diff --git a/bower_components/firebase/.bower.json b/bower_components/firebase/.bower.json new file mode 100644 index 0000000..223ba86 --- /dev/null +++ b/bower_components/firebase/.bower.json @@ -0,0 +1,35 @@ +{ + "name": "firebase", + "version": "2.4.1", + "homepage": "https://firebase.com", + "authors": [ + "Firebase " + ], + "description": "Firebase Web Client", + "main": "firebase.js", + "keywords": [ + "Firebase", + "synchronization", + "real-time", + "websocket" + ], + "license": "MIT", + "private": false, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "_release": "2.4.1", + "_resolution": { + "type": "version", + "tag": "v2.4.1", + "commit": "ab781011e8f1dc5cf7959fc7ea0b09b8d7ecc852" + }, + "_source": "git://github.com/firebase/firebase-bower.git", + "_target": "^2.4.1", + "_originalSource": "firebase", + "_direct": true +} \ No newline at end of file diff --git a/bower_components/firebase/README.md b/bower_components/firebase/README.md new file mode 100644 index 0000000..3c88c2a --- /dev/null +++ b/bower_components/firebase/README.md @@ -0,0 +1,10 @@ +firebase-bower +============== + +To use firebase via bower, do: + + bower install firebase + +NOTE: This repo is automatically generated and is not monitored for issues / pull requests. Please contact support@firebase.com for any bugs/suggestions on Firebase or the bower module. + +LICENSE - Refer to: https://www.firebase.com/terms/terms-of-service.html diff --git a/bower_components/firebase/bower.json b/bower_components/firebase/bower.json new file mode 100644 index 0000000..c880894 --- /dev/null +++ b/bower_components/firebase/bower.json @@ -0,0 +1,25 @@ +{ + "name": "firebase", + "version": "2.4.1", + "homepage": "https://firebase.com", + "authors": [ + "Firebase " + ], + "description": "Firebase Web Client", + "main": "firebase.js", + "keywords": [ + "Firebase", + "synchronization", + "real-time", + "websocket" + ], + "license": "MIT", + "private": false, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} \ No newline at end of file diff --git a/bower_components/firebase/firebase-debug.js b/bower_components/firebase/firebase-debug.js new file mode 100644 index 0000000..8869bf9 --- /dev/null +++ b/bower_components/firebase/firebase-debug.js @@ -0,0 +1,13980 @@ +/*! @license Firebase v2.4.1 + License: https://www.firebase.com/terms/terms-of-service.html */ +(function(ns) { + ns.wrapper = function(goog, fb) { + // Prevents closure from trying (and failing) to retrieve a deps.js file. + var CLOSURE_NO_DEPS = true; + + // Sets CLIENT_VERSION manually, since we can't use a closure --define with WHITESPACE_ONLY compilation. + var CLIENT_VERSION = '2.4.1'; + var COMPILED = false; +var goog = goog || {}; +goog.global = this; +goog.global.CLOSURE_UNCOMPILED_DEFINES; +goog.global.CLOSURE_DEFINES; +goog.isDef = function(val) { + return val !== void 0; +}; +goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) { + var parts = name.split("."); + var cur = opt_objectToExportTo || goog.global; + if (!(parts[0] in cur) && cur.execScript) { + cur.execScript("var " + parts[0]); + } + for (var part;parts.length && (part = parts.shift());) { + if (!parts.length && goog.isDef(opt_object)) { + cur[part] = opt_object; + } else { + if (cur[part]) { + cur = cur[part]; + } else { + cur = cur[part] = {}; + } + } + } +}; +goog.define = function(name, defaultValue) { + var value = defaultValue; + if (!COMPILED) { + if (goog.global.CLOSURE_UNCOMPILED_DEFINES && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_UNCOMPILED_DEFINES, name)) { + value = goog.global.CLOSURE_UNCOMPILED_DEFINES[name]; + } else { + if (goog.global.CLOSURE_DEFINES && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES, name)) { + value = goog.global.CLOSURE_DEFINES[name]; + } + } + } + goog.exportPath_(name, value); +}; +goog.define("goog.DEBUG", true); +goog.define("goog.LOCALE", "en"); +goog.define("goog.TRUSTED_SITE", true); +goog.define("goog.STRICT_MODE_COMPATIBLE", false); +goog.define("goog.DISALLOW_TEST_ONLY_CODE", COMPILED && !goog.DEBUG); +goog.provide = function(name) { + if (!COMPILED) { + if (goog.isProvided_(name)) { + throw Error('Namespace "' + name + '" already declared.'); + } + } + goog.constructNamespace_(name); +}; +goog.constructNamespace_ = function(name, opt_obj) { + if (!COMPILED) { + delete goog.implicitNamespaces_[name]; + var namespace = name; + while (namespace = namespace.substring(0, namespace.lastIndexOf("."))) { + if (goog.getObjectByName(namespace)) { + break; + } + goog.implicitNamespaces_[namespace] = true; + } + } + goog.exportPath_(name, opt_obj); +}; +goog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/; +goog.module = function(name) { + if (!goog.isString(name) || !name || name.search(goog.VALID_MODULE_RE_) == -1) { + throw Error("Invalid module identifier"); + } + if (!goog.isInModuleLoader_()) { + throw Error("Module " + name + " has been loaded incorrectly."); + } + if (goog.moduleLoaderState_.moduleName) { + throw Error("goog.module may only be called once per module."); + } + goog.moduleLoaderState_.moduleName = name; + if (!COMPILED) { + if (goog.isProvided_(name)) { + throw Error('Namespace "' + name + '" already declared.'); + } + delete goog.implicitNamespaces_[name]; + } +}; +goog.module.get = function(name) { + return goog.module.getInternal_(name); +}; +goog.module.getInternal_ = function(name) { + if (!COMPILED) { + if (goog.isProvided_(name)) { + return name in goog.loadedModules_ ? goog.loadedModules_[name] : goog.getObjectByName(name); + } else { + return null; + } + } +}; +goog.moduleLoaderState_ = null; +goog.isInModuleLoader_ = function() { + return goog.moduleLoaderState_ != null; +}; +goog.module.declareTestMethods = function() { + if (!goog.isInModuleLoader_()) { + throw new Error("goog.module.declareTestMethods must be called from " + "within a goog.module"); + } + goog.moduleLoaderState_.declareTestMethods = true; +}; +goog.module.declareLegacyNamespace = function() { + if (!COMPILED && !goog.isInModuleLoader_()) { + throw new Error("goog.module.declareLegacyNamespace must be called from " + "within a goog.module"); + } + if (!COMPILED && !goog.moduleLoaderState_.moduleName) { + throw Error("goog.module must be called prior to " + "goog.module.declareLegacyNamespace."); + } + goog.moduleLoaderState_.declareLegacyNamespace = true; +}; +goog.setTestOnly = function(opt_message) { + if (goog.DISALLOW_TEST_ONLY_CODE) { + opt_message = opt_message || ""; + throw Error("Importing test-only code into non-debug environment" + (opt_message ? ": " + opt_message : ".")); + } +}; +goog.forwardDeclare = function(name) { +}; +if (!COMPILED) { + goog.isProvided_ = function(name) { + return name in goog.loadedModules_ || !goog.implicitNamespaces_[name] && goog.isDefAndNotNull(goog.getObjectByName(name)); + }; + goog.implicitNamespaces_ = {"goog.module":true}; +} +goog.getObjectByName = function(name, opt_obj) { + var parts = name.split("."); + var cur = opt_obj || goog.global; + for (var part;part = parts.shift();) { + if (goog.isDefAndNotNull(cur[part])) { + cur = cur[part]; + } else { + return null; + } + } + return cur; +}; +goog.globalize = function(obj, opt_global) { + var global = opt_global || goog.global; + for (var x in obj) { + global[x] = obj[x]; + } +}; +goog.addDependency = function(relPath, provides, requires, opt_isModule) { + if (goog.DEPENDENCIES_ENABLED) { + var provide, require; + var path = relPath.replace(/\\/g, "/"); + var deps = goog.dependencies_; + for (var i = 0;provide = provides[i];i++) { + deps.nameToPath[provide] = path; + deps.pathIsModule[path] = !!opt_isModule; + } + for (var j = 0;require = requires[j];j++) { + if (!(path in deps.requires)) { + deps.requires[path] = {}; + } + deps.requires[path][require] = true; + } + } +}; +goog.define("goog.ENABLE_DEBUG_LOADER", true); +goog.logToConsole_ = function(msg) { + if (goog.global.console) { + goog.global.console["error"](msg); + } +}; +goog.require = function(name) { + if (!COMPILED) { + if (goog.ENABLE_DEBUG_LOADER && goog.IS_OLD_IE_) { + goog.maybeProcessDeferredDep_(name); + } + if (goog.isProvided_(name)) { + if (goog.isInModuleLoader_()) { + return goog.module.getInternal_(name); + } else { + return null; + } + } + if (goog.ENABLE_DEBUG_LOADER) { + var path = goog.getPathFromDeps_(name); + if (path) { + goog.included_[path] = true; + goog.writeScripts_(); + return null; + } + } + var errorMessage = "goog.require could not find: " + name; + goog.logToConsole_(errorMessage); + throw Error(errorMessage); + } +}; +goog.basePath = ""; +goog.global.CLOSURE_BASE_PATH; +goog.global.CLOSURE_NO_DEPS; +goog.global.CLOSURE_IMPORT_SCRIPT; +goog.nullFunction = function() { +}; +goog.identityFunction = function(opt_returnValue, var_args) { + return opt_returnValue; +}; +goog.abstractMethod = function() { + throw Error("unimplemented abstract method"); +}; +goog.addSingletonGetter = function(ctor) { + ctor.getInstance = function() { + if (ctor.instance_) { + return ctor.instance_; + } + if (goog.DEBUG) { + goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor; + } + return ctor.instance_ = new ctor; + }; +}; +goog.instantiatedSingletons_ = []; +goog.define("goog.LOAD_MODULE_USING_EVAL", true); +goog.define("goog.SEAL_MODULE_EXPORTS", goog.DEBUG); +goog.loadedModules_ = {}; +goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER; +if (goog.DEPENDENCIES_ENABLED) { + goog.included_ = {}; + goog.dependencies_ = {pathIsModule:{}, nameToPath:{}, requires:{}, visited:{}, written:{}, deferred:{}}; + goog.inHtmlDocument_ = function() { + var doc = goog.global.document; + return typeof doc != "undefined" && "write" in doc; + }; + goog.findBasePath_ = function() { + if (goog.global.CLOSURE_BASE_PATH) { + goog.basePath = goog.global.CLOSURE_BASE_PATH; + return; + } else { + if (!goog.inHtmlDocument_()) { + return; + } + } + var doc = goog.global.document; + var scripts = doc.getElementsByTagName("script"); + for (var i = scripts.length - 1;i >= 0;--i) { + var script = (scripts[i]); + var src = script.src; + var qmark = src.lastIndexOf("?"); + var l = qmark == -1 ? src.length : qmark; + if (src.substr(l - 7, 7) == "base.js") { + goog.basePath = src.substr(0, l - 7); + return; + } + } + }; + goog.importScript_ = function(src, opt_sourceText) { + var importScript = goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_; + if (importScript(src, opt_sourceText)) { + goog.dependencies_.written[src] = true; + } + }; + goog.IS_OLD_IE_ = !goog.global.atob && goog.global.document && goog.global.document.all; + goog.importModule_ = function(src) { + var bootstrap = 'goog.retrieveAndExecModule_("' + src + '");'; + if (goog.importScript_("", bootstrap)) { + goog.dependencies_.written[src] = true; + } + }; + goog.queuedModules_ = []; + goog.wrapModule_ = function(srcUrl, scriptText) { + if (!goog.LOAD_MODULE_USING_EVAL || !goog.isDef(goog.global.JSON)) { + return "" + "goog.loadModule(function(exports) {" + '"use strict";' + scriptText + "\n" + ";return exports" + "});" + "\n//# sourceURL=" + srcUrl + "\n"; + } else { + return "" + "goog.loadModule(" + goog.global.JSON.stringify(scriptText + "\n//# sourceURL=" + srcUrl + "\n") + ");"; + } + }; + goog.loadQueuedModules_ = function() { + var count = goog.queuedModules_.length; + if (count > 0) { + var queue = goog.queuedModules_; + goog.queuedModules_ = []; + for (var i = 0;i < count;i++) { + var path = queue[i]; + goog.maybeProcessDeferredPath_(path); + } + } + }; + goog.maybeProcessDeferredDep_ = function(name) { + if (goog.isDeferredModule_(name) && goog.allDepsAreAvailable_(name)) { + var path = goog.getPathFromDeps_(name); + goog.maybeProcessDeferredPath_(goog.basePath + path); + } + }; + goog.isDeferredModule_ = function(name) { + var path = goog.getPathFromDeps_(name); + if (path && goog.dependencies_.pathIsModule[path]) { + var abspath = goog.basePath + path; + return abspath in goog.dependencies_.deferred; + } + return false; + }; + goog.allDepsAreAvailable_ = function(name) { + var path = goog.getPathFromDeps_(name); + if (path && path in goog.dependencies_.requires) { + for (var requireName in goog.dependencies_.requires[path]) { + if (!goog.isProvided_(requireName) && !goog.isDeferredModule_(requireName)) { + return false; + } + } + } + return true; + }; + goog.maybeProcessDeferredPath_ = function(abspath) { + if (abspath in goog.dependencies_.deferred) { + var src = goog.dependencies_.deferred[abspath]; + delete goog.dependencies_.deferred[abspath]; + goog.globalEval(src); + } + }; + goog.loadModule = function(moduleDef) { + var previousState = goog.moduleLoaderState_; + try { + goog.moduleLoaderState_ = {moduleName:undefined, declareTestMethods:false}; + var exports; + if (goog.isFunction(moduleDef)) { + exports = moduleDef.call(goog.global, {}); + } else { + if (goog.isString(moduleDef)) { + exports = goog.loadModuleFromSource_.call(goog.global, moduleDef); + } else { + throw Error("Invalid module definition"); + } + } + var moduleName = goog.moduleLoaderState_.moduleName; + if (!goog.isString(moduleName) || !moduleName) { + throw Error('Invalid module name "' + moduleName + '"'); + } + if (goog.moduleLoaderState_.declareLegacyNamespace) { + goog.constructNamespace_(moduleName, exports); + } else { + if (goog.SEAL_MODULE_EXPORTS && Object.seal) { + Object.seal(exports); + } + } + goog.loadedModules_[moduleName] = exports; + if (goog.moduleLoaderState_.declareTestMethods) { + for (var entry in exports) { + if (entry.indexOf("test", 0) === 0 || entry == "tearDown" || entry == "setUp" || entry == "setUpPage" || entry == "tearDownPage") { + goog.global[entry] = exports[entry]; + } + } + } + } finally { + goog.moduleLoaderState_ = previousState; + } + }; + goog.loadModuleFromSource_ = function(source) { + var exports = {}; + eval(arguments[0]); + return exports; + }; + goog.writeScriptTag_ = function(src, opt_sourceText) { + if (goog.inHtmlDocument_()) { + var doc = goog.global.document; + if (doc.readyState == "complete") { + var isDeps = /\bdeps.js$/.test(src); + if (isDeps) { + return false; + } else { + throw Error('Cannot write "' + src + '" after document load'); + } + } + var isOldIE = goog.IS_OLD_IE_; + if (opt_sourceText === undefined) { + if (!isOldIE) { + doc.write(' + + Cordova tests + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
Log
+
+
+ + diff --git a/platforms/android/assets/www/cdvtests/jasmine-2.2.0/boot.js b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/boot.js new file mode 100755 index 0000000..e8ddd55 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/boot.js @@ -0,0 +1,121 @@ +/** + Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project. + + If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms. + + The location of `boot.js` can be specified and/or overridden in `jasmine.yml`. + + [jasmine-gem]: http://github.com/pivotal/jasmine-gem + */ + +(function() { + + /** + * ## Require & Instantiate + * + * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference. + */ + window.jasmine = jasmineRequire.core(jasmineRequire); + + /** + * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference. + */ + jasmineRequire.html(jasmine); + + /** + * Create the Jasmine environment. This is used to run all specs in a project. + */ + var env = jasmine.getEnv(); + + /** + * ## The Global Interface + * + * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged. + */ + var jasmineInterface = jasmineRequire.interface(jasmine, env); + + /** + * Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`. + */ + if (typeof window == "undefined" && typeof exports == "object") { + extend(exports, jasmineInterface); + } else { + extend(window, jasmineInterface); + } + + /** + * ## Runner Parameters + * + * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface. + */ + + var queryString = new jasmine.QueryString({ + getWindowLocation: function() { return window.location; } + }); + + var catchingExceptions = queryString.getParam("catch"); + env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions); + + /** + * ## Reporters + * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any). + */ + var htmlReporter = new jasmine.HtmlReporter({ + env: env, + onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); }, + addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); }, + getContainer: function() { return document.body; }, + createElement: function() { return document.createElement.apply(document, arguments); }, + createTextNode: function() { return document.createTextNode.apply(document, arguments); }, + timer: new jasmine.Timer() + }); + + /** + * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript. + */ + env.addReporter(jasmineInterface.jsApiReporter); + env.addReporter(htmlReporter); + + /** + * Filter which specs will be run by matching the start of the full name against the `spec` query param. + */ + var specFilter = new jasmine.HtmlSpecFilter({ + filterString: function() { return queryString.getParam("spec"); } + }); + + env.specFilter = function(spec) { + return specFilter.matches(spec.getFullName()); + }; + + /** + * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack. + */ + window.setTimeout = window.setTimeout; + window.setInterval = window.setInterval; + window.clearTimeout = window.clearTimeout; + window.clearInterval = window.clearInterval; + + /** + * ## Execution + * + * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded. + */ + var currentWindowOnload = window.onload; + + window.onload = function() { + if (currentWindowOnload) { + currentWindowOnload(); + } + htmlReporter.initialize(); + env.execute(); + }; + + /** + * Helper function for readability above. + */ + function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; + } + +}()); diff --git a/platforms/android/assets/www/cdvtests/jasmine-2.2.0/console.js b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/console.js new file mode 100755 index 0000000..e154806 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/console.js @@ -0,0 +1,190 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +function getJasmineRequireObj() { + if (typeof module !== 'undefined' && module.exports) { + return exports; + } else { + window.jasmineRequire = window.jasmineRequire || {}; + return window.jasmineRequire; + } +} + +getJasmineRequireObj().console = function(jRequire, j$) { + j$.ConsoleReporter = jRequire.ConsoleReporter(); +}; + +getJasmineRequireObj().ConsoleReporter = function() { + + var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } + }; + + function ConsoleReporter(options) { + var print = options.print, + showColors = options.showColors || false, + onComplete = options.onComplete || function() {}, + timer = options.timer || noopTimer, + specCount, + failureCount, + failedSpecs = [], + pendingCount, + ansi = { + green: '\x1B[32m', + red: '\x1B[31m', + yellow: '\x1B[33m', + none: '\x1B[0m' + }, + failedSuites = []; + + print('ConsoleReporter is deprecated and will be removed in a future version.'); + + this.jasmineStarted = function() { + specCount = 0; + failureCount = 0; + pendingCount = 0; + print('Started'); + printNewline(); + timer.start(); + }; + + this.jasmineDone = function() { + printNewline(); + for (var i = 0; i < failedSpecs.length; i++) { + specFailureDetails(failedSpecs[i]); + } + + if(specCount > 0) { + printNewline(); + + var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' + + failureCount + ' ' + plural('failure', failureCount); + + if (pendingCount) { + specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount); + } + + print(specCounts); + } else { + print('No specs found'); + } + + printNewline(); + var seconds = timer.elapsed() / 1000; + print('Finished in ' + seconds + ' ' + plural('second', seconds)); + printNewline(); + + for(i = 0; i < failedSuites.length; i++) { + suiteFailureDetails(failedSuites[i]); + } + + onComplete(failureCount === 0); + }; + + this.specDone = function(result) { + specCount++; + + if (result.status == 'pending') { + pendingCount++; + print(colored('yellow', '*')); + return; + } + + if (result.status == 'passed') { + print(colored('green', '.')); + return; + } + + if (result.status == 'failed') { + failureCount++; + failedSpecs.push(result); + print(colored('red', 'F')); + } + }; + + this.suiteDone = function(result) { + if (result.failedExpectations && result.failedExpectations.length > 0) { + failureCount++; + failedSuites.push(result); + } + }; + + return this; + + function printNewline() { + print('\n'); + } + + function colored(color, str) { + return showColors ? (ansi[color] + str + ansi.none) : str; + } + + function plural(str, count) { + return count == 1 ? str : str + 's'; + } + + function repeat(thing, times) { + var arr = []; + for (var i = 0; i < times; i++) { + arr.push(thing); + } + return arr; + } + + function indent(str, spaces) { + var lines = (str || '').split('\n'); + var newArr = []; + for (var i = 0; i < lines.length; i++) { + newArr.push(repeat(' ', spaces).join('') + lines[i]); + } + return newArr.join('\n'); + } + + function specFailureDetails(result) { + printNewline(); + print(result.fullName); + + for (var i = 0; i < result.failedExpectations.length; i++) { + var failedExpectation = result.failedExpectations[i]; + printNewline(); + print(indent(failedExpectation.message, 2)); + print(indent(failedExpectation.stack, 2)); + } + + printNewline(); + } + + function suiteFailureDetails(result) { + for (var i = 0; i < result.failedExpectations.length; i++) { + printNewline(); + print(colored('red', 'An error was thrown in an afterAll')); + printNewline(); + print(colored('red', 'AfterAll ' + result.failedExpectations[i].message)); + + } + printNewline(); + } + } + + return ConsoleReporter; +}; diff --git a/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine-html.js b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine-html.js new file mode 100755 index 0000000..bee5a04 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine-html.js @@ -0,0 +1,416 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +jasmineRequire.html = function(j$) { + j$.ResultsNode = jasmineRequire.ResultsNode(); + j$.HtmlReporter = jasmineRequire.HtmlReporter(j$); + j$.QueryString = jasmineRequire.QueryString(); + j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter(); +}; + +jasmineRequire.HtmlReporter = function(j$) { + + var noopTimer = { + start: function() {}, + elapsed: function() { return 0; } + }; + + function HtmlReporter(options) { + var env = options.env || {}, + getContainer = options.getContainer, + createElement = options.createElement, + createTextNode = options.createTextNode, + onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {}, + addToExistingQueryString = options.addToExistingQueryString || defaultQueryString, + timer = options.timer || noopTimer, + results = [], + specsExecuted = 0, + failureCount = 0, + pendingSpecCount = 0, + htmlReporterMain, + symbols, + failedSuites = []; + + this.initialize = function() { + clearPrior(); + htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'}, + createDom('div', {className: 'banner'}, + createDom('a', {className: 'title', href: 'http://jasmine.github.io/', target: '_blank'}), + createDom('span', {className: 'version'}, j$.version) + ), + createDom('ul', {className: 'symbol-summary'}), + createDom('div', {className: 'alert'}), + createDom('div', {className: 'results'}, + createDom('div', {className: 'failures'}) + ) + ); + getContainer().appendChild(htmlReporterMain); + + symbols = find('.symbol-summary'); + }; + + var totalSpecsDefined; + this.jasmineStarted = function(options) { + totalSpecsDefined = options.totalSpecsDefined || 0; + timer.start(); + }; + + var summary = createDom('div', {className: 'summary'}); + + var topResults = new j$.ResultsNode({}, '', null), + currentParent = topResults; + + this.suiteStarted = function(result) { + currentParent.addChild(result, 'suite'); + currentParent = currentParent.last(); + }; + + this.suiteDone = function(result) { + if (result.status == 'failed') { + failedSuites.push(result); + } + + if (currentParent == topResults) { + return; + } + + currentParent = currentParent.parent; + }; + + this.specStarted = function(result) { + currentParent.addChild(result, 'spec'); + }; + + var failures = []; + this.specDone = function(result) { + if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') { + console.error('Spec \'' + result.fullName + '\' has no expectations.'); + } + + if (result.status != 'disabled') { + specsExecuted++; + } + + symbols.appendChild(createDom('li', { + className: noExpectations(result) ? 'empty' : result.status, + id: 'spec_' + result.id, + title: result.fullName + } + )); + + if (result.status == 'failed') { + failureCount++; + + var failure = + createDom('div', {className: 'spec-detail failed'}, + createDom('div', {className: 'description'}, + createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName) + ), + createDom('div', {className: 'messages'}) + ); + var messages = failure.childNodes[1]; + + for (var i = 0; i < result.failedExpectations.length; i++) { + var expectation = result.failedExpectations[i]; + messages.appendChild(createDom('div', {className: 'result-message'}, expectation.message)); + messages.appendChild(createDom('div', {className: 'stack-trace'}, expectation.stack)); + } + + failures.push(failure); + } + + if (result.status == 'pending') { + pendingSpecCount++; + } + }; + + this.jasmineDone = function() { + var banner = find('.banner'); + banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's')); + + var alert = find('.alert'); + + alert.appendChild(createDom('span', { className: 'exceptions' }, + createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions'), + createDom('input', { + className: 'raise', + id: 'raise-exceptions', + type: 'checkbox' + }) + )); + var checkbox = find('#raise-exceptions'); + + checkbox.checked = !env.catchingExceptions(); + checkbox.onclick = onRaiseExceptionsClick; + + if (specsExecuted < totalSpecsDefined) { + var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all'; + alert.appendChild( + createDom('span', {className: 'bar skipped'}, + createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage) + ) + ); + } + var statusBarMessage = ''; + var statusBarClassName = 'bar '; + + if (totalSpecsDefined > 0) { + statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount); + if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); } + statusBarClassName += (failureCount > 0) ? 'failed' : 'passed'; + } else { + statusBarClassName += 'skipped'; + statusBarMessage += 'No specs found'; + } + + alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage)); + + for(i = 0; i < failedSuites.length; i++) { + var failedSuite = failedSuites[i]; + for(var j = 0; j < failedSuite.failedExpectations.length; j++) { + var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message; + var errorBarClassName = 'bar errored'; + alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage)); + } + } + + var results = find('.results'); + results.appendChild(summary); + + summaryList(topResults, summary); + + function summaryList(resultsTree, domParent) { + var specListNode; + for (var i = 0; i < resultsTree.children.length; i++) { + var resultNode = resultsTree.children[i]; + if (resultNode.type == 'suite') { + var suiteListNode = createDom('ul', {className: 'suite', id: 'suite-' + resultNode.result.id}, + createDom('li', {className: 'suite-detail'}, + createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description) + ) + ); + + summaryList(resultNode, suiteListNode); + domParent.appendChild(suiteListNode); + } + if (resultNode.type == 'spec') { + if (domParent.getAttribute('class') != 'specs') { + specListNode = createDom('ul', {className: 'specs'}); + domParent.appendChild(specListNode); + } + var specDescription = resultNode.result.description; + if(noExpectations(resultNode.result)) { + specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription; + } + if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') { + specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason; + } + specListNode.appendChild( + createDom('li', { + className: resultNode.result.status, + id: 'spec-' + resultNode.result.id + }, + createDom('a', {href: specHref(resultNode.result)}, specDescription) + ) + ); + } + } + } + + if (failures.length) { + alert.appendChild( + createDom('span', {className: 'menu bar spec-list'}, + createDom('span', {}, 'Spec List | '), + createDom('a', {className: 'failures-menu', href: '#'}, 'Failures'))); + alert.appendChild( + createDom('span', {className: 'menu bar failure-list'}, + createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'), + createDom('span', {}, ' | Failures '))); + + find('.failures-menu').onclick = function() { + setMenuModeTo('failure-list'); + }; + find('.spec-list-menu').onclick = function() { + setMenuModeTo('spec-list'); + }; + + setMenuModeTo('failure-list'); + + var failureNode = find('.failures'); + for (var i = 0; i < failures.length; i++) { + failureNode.appendChild(failures[i]); + } + } + }; + + return this; + + function find(selector) { + return getContainer().querySelector('.jasmine_html-reporter ' + selector); + } + + function clearPrior() { + // return the reporter + var oldReporter = find(''); + + if(oldReporter) { + getContainer().removeChild(oldReporter); + } + } + + function createDom(type, attrs, childrenVarArgs) { + var el = createElement(type); + + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i]; + + if (typeof child === 'string') { + el.appendChild(createTextNode(child)); + } else { + if (child) { + el.appendChild(child); + } + } + } + + for (var attr in attrs) { + if (attr == 'className') { + el[attr] = attrs[attr]; + } else { + el.setAttribute(attr, attrs[attr]); + } + } + + return el; + } + + function pluralize(singular, count) { + var word = (count == 1 ? singular : singular + 's'); + + return '' + count + ' ' + word; + } + + function specHref(result) { + return addToExistingQueryString('spec', result.fullName); + } + + function defaultQueryString(key, value) { + return '?' + key + '=' + value; + } + + function setMenuModeTo(mode) { + htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode); + } + + function noExpectations(result) { + return (result.failedExpectations.length + result.passedExpectations.length) === 0 && + result.status === 'passed'; + } + } + + return HtmlReporter; +}; + +jasmineRequire.HtmlSpecFilter = function() { + function HtmlSpecFilter(options) { + var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + var filterPattern = new RegExp(filterString); + + this.matches = function(specName) { + return filterPattern.test(specName); + }; + } + + return HtmlSpecFilter; +}; + +jasmineRequire.ResultsNode = function() { + function ResultsNode(result, type, parent) { + this.result = result; + this.type = type; + this.parent = parent; + + this.children = []; + + this.addChild = function(result, type) { + this.children.push(new ResultsNode(result, type, this)); + }; + + this.last = function() { + return this.children[this.children.length - 1]; + }; + } + + return ResultsNode; +}; + +jasmineRequire.QueryString = function() { + function QueryString(options) { + + this.navigateWithNewParam = function(key, value) { + options.getWindowLocation().search = this.fullStringWithNewParam(key, value); + }; + + this.fullStringWithNewParam = function(key, value) { + var paramMap = queryStringToParamMap(); + paramMap[key] = value; + return toQueryString(paramMap); + }; + + this.getParam = function(key) { + return queryStringToParamMap()[key]; + }; + + return this; + + function toQueryString(paramMap) { + var qStrPairs = []; + for (var prop in paramMap) { + qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop])); + } + return '?' + qStrPairs.join('&'); + } + + function queryStringToParamMap() { + var paramStr = options.getWindowLocation().search.substring(1), + params = [], + paramMap = {}; + + if (paramStr.length > 0) { + params = paramStr.split('&'); + for (var i = 0; i < params.length; i++) { + var p = params[i].split('='); + var value = decodeURIComponent(p[1]); + if (value === 'true' || value === 'false') { + value = JSON.parse(value); + } + paramMap[decodeURIComponent(p[0])] = value; + } + } + + return paramMap; + } + + } + + return QueryString; +}; diff --git a/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine.css b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine.css new file mode 100755 index 0000000..ecc5f5e --- /dev/null +++ b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine.css @@ -0,0 +1,62 @@ +body { overflow-y: scroll; } + +.jasmine_html-reporter { background-color: #eee; padding: 5px; margin: -8px; font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333; } +.jasmine_html-reporter a { text-decoration: none; } +.jasmine_html-reporter a:hover { text-decoration: underline; } +.jasmine_html-reporter p, .jasmine_html-reporter h1, .jasmine_html-reporter h2, .jasmine_html-reporter h3, .jasmine_html-reporter h4, .jasmine_html-reporter h5, .jasmine_html-reporter h6 { margin: 0; line-height: 14px; } +.jasmine_html-reporter .banner, .jasmine_html-reporter .symbol-summary, .jasmine_html-reporter .summary, .jasmine_html-reporter .result-message, .jasmine_html-reporter .spec .description, .jasmine_html-reporter .spec-detail .description, .jasmine_html-reporter .alert .bar, .jasmine_html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; } +.jasmine_html-reporter .banner { position: relative; } +.jasmine_html-reporter .banner .title { background: url('data:image/png;base64,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') no-repeat; background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICB3aWR0aD0iNjgxLjk2MjUyIgogICBoZWlnaHQ9IjE4Ny41IgogICBpZD0ic3ZnMiIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhOCI+PHJkZjpSREY+PGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMKICAgICBpZD0iZGVmczYiPjxjbGlwUGF0aAogICAgICAgaWQ9ImNsaXBQYXRoMTgiPjxwYXRoCiAgICAgICAgIGQ9Ik0gMCwxNTAwIDAsMCBsIDU0NTUuNzQsMCAwLDE1MDAgTCAwLDE1MDAgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgyMCIgLz48L2NsaXBQYXRoPjwvZGVmcz48ZwogICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMjUsMCwwLC0xLjI1LDAsMTg3LjUpIgogICAgIGlkPSJnMTAiPjxnCiAgICAgICB0cmFuc2Zvcm09InNjYWxlKDAuMSwwLjEpIgogICAgICAgaWQ9ImcxMiI+PGcKICAgICAgICAgaWQ9ImcxNCI+PGcKICAgICAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGgxOCkiCiAgICAgICAgICAgaWQ9ImcxNiI+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTU0NCw1OTkuNDM0IGMgMC45MiwtNDAuMzUyIDI1LjY4LC04MS42MDIgNzEuNTMsLTgxLjYwMiAyNy41MSwwIDQ3LjY4LDEyLjgzMiA2MS40NCwzNS43NTQgMTIuODMsMjIuOTMgMTIuODMsNTYuODUyIDEyLjgzLDgyLjUyNyBsIDAsMzI5LjE4NCAtNzEuNTIsMCAwLDEwNC41NDMgMjY2LjgzLDAgMCwtMTA0LjU0MyAtNzAuNiwwIDAsLTM0NC43NyBjIDAsLTU4LjY5MSAtMy42OCwtMTA0LjUzMSAtNDQuOTMsLTE1Mi4yMTggLTM2LjY4LC00Mi4xOCAtOTYuMjgsLTY2LjAyIC0xNTMuMTQsLTY2LjAyIC0xMTcuMzcsMCAtMjA3LjI0LDc3Ljk0MSAtMjAyLjY0LDE5Ny4xNDUgbCAxMzAuMiwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMjIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDIzMDEuNCw2NjIuNjk1IGMgMCw4MC43MDMgLTY2Ljk0LDE0NS44MTMgLTE0Ny42MywxNDUuODEzIC04My40NCwwIC0xNDcuNjMsLTY4Ljc4MSAtMTQ3LjYzLC0xNTEuMzAxIDAsLTc5Ljc4NSA2Ni45NCwtMTQ1LjgwMSAxNDUuOCwtMTQ1LjgwMSA4NC4zNSwwIDE0OS40Niw2Ny44NTIgMTQ5LjQ2LDE1MS4yODkgeiBtIC0xLjgzLC0xODEuNTQ3IGMgLTM1Ljc3LC01NC4wOTcgLTkzLjUzLC03OC44NTkgLTE1Ny43MiwtNzguODU5IC0xNDAuMywwIC0yNTEuMjQsMTE2LjQ0OSAtMjUxLjI0LDI1NC45MTggMCwxNDIuMTI5IDExMy43LDI2MC40MSAyNTYuNzQsMjYwLjQxIDYzLjI3LDAgMTE4LjI5LC0yOS4zMzYgMTUyLjIyLC04Mi41MjMgbCAwLDY5LjY4NyAxNzUuMTQsMCAwLC0xMDQuNTI3IC02MS40NCwwIDAsLTI4MC41OTggNjEuNDQsMCAwLC0xMDQuNTI3IC0xNzUuMTQsMCAwLDY2LjAxOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAyNjIyLjMzLDU1Ny4yNTggYyAzLjY3LC00NC4wMTYgMzMuMDEsLTczLjM0OCA3OC44NiwtNzMuMzQ4IDMzLjkzLDAgNjYuOTMsMjMuODI0IDY2LjkzLDYwLjUwNCAwLDQ4LjYwNiAtNDUuODQsNTYuODU2IC04My40NCw2Ni45NDEgLTg1LjI4LDIyLjAwNCAtMTc4LjgxLDQ4LjYwNiAtMTc4LjgxLDE1NS44NzkgMCw5My41MzYgNzguODYsMTQ3LjYzMyAxNjUuOTgsMTQ3LjYzMyA0NCwwIDgzLjQzLC05LjE3NiAxMTAuOTQsLTQ0LjAwOCBsIDAsMzMuOTIyIDgyLjUzLDAgMCwtMTMyLjk2NSAtMTA4LjIxLDAgYyAtMS44MywzNC44NTYgLTI4LjQyLDU3Ljc3NCAtNjMuMjYsNTcuNzc0IC0zMC4yNiwwIC02Mi4zNSwtMTcuNDIyIC02Mi4zNSwtNTEuMzQ4IDAsLTQ1Ljg0NyA0NC45MywtNTUuOTMgODAuNjksLTY0LjE4IDg4LjAyLC0yMC4xNzUgMTgyLjQ3LC00Ny42OTUgMTgyLjQ3LC0xNTcuNzM0IDAsLTk5LjAyNyAtODMuNDQsLTE1NC4wMzkgLTE3NS4xMywtMTU0LjAzOSAtNDkuNTMsMCAtOTQuNDYsMTUuNTgyIC0xMjYuNTUsNTMuMTggbCAwLC00MC4zNCAtODUuMjcsMCAwLDE0Mi4xMjkgMTE0LjYyLDAiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGgyNiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMjk4OC4xOCw4MDAuMjU0IC02My4yNiwwIDAsMTA0LjUyNyAxNjUuMDUsMCAwLC03My4zNTUgYyAzMS4xOCw1MS4zNDcgNzguODYsODUuMjc3IDE0MS4yMSw4NS4yNzcgNjcuODUsMCAxMjQuNzEsLTQxLjI1OCAxNTIuMjEsLTEwMi42OTkgMjYuNiw2Mi4zNTEgOTIuNjIsMTAyLjY5OSAxNjAuNDcsMTAyLjY5OSA1My4xOSwwIDEwNS40NiwtMjIgMTQxLjIxLC02Mi4zNTEgMzguNTIsLTQ0LjkzOCAzOC41MiwtOTMuNTMyIDM4LjUyLC0xNDkuNDU3IGwgMCwtMTg1LjIzOSA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40MiwwIDAsMTA0LjUyNyA2My4yOCwwIDAsMTU3LjcxNSBjIDAsMzIuMTAyIDAsNjAuNTI3IC0xNC42Nyw4OC45NTcgLTE4LjM0LDI2LjU4MiAtNDguNjEsNDAuMzQ0IC03OS43Nyw0MC4zNDQgLTMwLjI2LDAgLTYzLjI4LC0xMi44NDQgLTgyLjUzLC0zNi42NzIgLTIyLjkzLC0yOS4zNTUgLTIyLjkzLC01Ni44NjMgLTIyLjkzLC05Mi42MjkgbCAwLC0xNTcuNzE1IDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM4LjQxLDAgMCwxMDQuNTI3IDYzLjI4LDAgMCwxNTAuMzgzIGMgMCwyOS4zNDggMCw2Ni4wMjMgLTE0LjY3LDkxLjY5OSAtMTUuNTksMjkuMzM2IC00Ny42OSw0NC45MzQgLTgwLjcsNDQuOTM0IC0zMS4xOCwwIC01Ny43NywtMTEuMDA4IC03Ny45NCwtMzUuNzc0IC0yNC43NywtMzAuMjUzIC0yNi42LC02Mi4zNDMgLTI2LjYsLTk5Ljk0MSBsIDAsLTE1MS4zMDEgNjMuMjcsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNiwwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAzOTk4LjY2LDk1MS41NDcgLTExMS44NywwIDAsMTE4LjI5MyAxMTEuODcsMCAwLC0xMTguMjkzIHogbSAwLC00MzEuODkxIDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM5LjMzLDAgMCwxMDQuNTI3IDY0LjE5LDAgMCwyODAuNTk4IC02My4yNywwIDAsMTA0LjUyNyAxNzUuMTQsMCAwLC0zODUuMTI1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzAiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDQxNTkuMTIsODAwLjI1NCAtNjMuMjcsMCAwLDEwNC41MjcgMTc1LjE0LDAgMCwtNjkuNjg3IGMgMjkuMzUsNTQuMTAxIDg0LjM2LDgwLjY5OSAxNDQuODcsODAuNjk5IDUzLjE5LDAgMTA1LjQ1LC0yMi4wMTYgMTQxLjIyLC02MC41MjcgNDAuMzQsLTQ0LjkzNCA0MS4yNiwtODguMDMyIDQxLjI2LC0xNDMuOTU3IGwgMCwtMTkxLjY1MyA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40LDAgMCwxMDQuNTI3IDYzLjI2LDAgMCwxNTguNjM3IGMgMCwzMC4yNjIgMCw2MS40MzQgLTE5LjI2LDg4LjAzNSAtMjAuMTcsMjYuNTgyIC01My4xOCwzOS40MTQgLTg2LjE5LDM5LjQxNCAtMzMuOTMsMCAtNjguNzcsLTEzLjc1IC04OC45NCwtNDEuMjUgLTIxLjA5LC0yNy41IC0yMS4wOSwtNjkuNjg3IC0yMS4wOSwtMTAyLjcwNyBsIDAsLTE0Mi4xMjkgNjMuMjYsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNywwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDMyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA1MDgyLjQ4LDcwMy45NjUgYyAtMTkuMjQsNzAuNjA1IC04MS42LDExNS41NDcgLTE1NC4wNCwxMTUuNTQ3IC02Ni4wNCwwIC0xMjkuMywtNTEuMzQ4IC0xNDMuMDUsLTExNS41NDcgbCAyOTcuMDksMCB6IG0gODUuMjcsLTE0NC44ODMgYyAtMzguNTEsLTkzLjUyMyAtMTI5LjI3LC0xNTYuNzkzIC0yMzEuMDUsLTE1Ni43OTMgLTE0My4wNywwIC0yNTcuNjgsMTExLjg3MSAtMjU3LjY4LDI1NS44MzYgMCwxNDQuODgzIDEwOS4xMiwyNjEuMzI4IDI1NC45MSwyNjEuMzI4IDY3Ljg3LDAgMTM1LjcyLC0zMC4yNTggMTgzLjM5LC03OC44NjMgNDguNjIsLTUxLjM0NCA2OC43OSwtMTEzLjY5NSA2OC43OSwtMTgzLjM4MyBsIC0zLjY3LC0zOS40MzQgLTM5Ni4xMywwIGMgMTQuNjcsLTY3Ljg2MyA3Ny4wMywtMTE3LjM2MyAxNDYuNzIsLTExNy4zNjMgNDguNTksMCA5MC43NiwxOC4zMjggMTE4LjI4LDU4LjY3MiBsIDExNi40NCwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDY5MC44OTUsODUwLjcwMyA5MC43NSwwIDIyLjU0MywzMS4wMzUgMCwyNDMuMTIyIC0xMzUuODI5LDAgMCwtMjQzLjE0MSAyMi41MzYsLTMxLjAxNiIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDM2IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA2MzIuMzk1LDc0Mi4yNTggMjguMDM5LDg2LjMwNCAtMjIuNTUxLDMxLjA0IC0yMzEuMjIzLDc1LjEyOCAtNDEuOTc2LC0xMjkuMTgzIDIzMS4yNTcsLTc1LjEzNyAzNi40NTQsMTEuODQ4IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzgiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDcxNy40NDksNjUzLjEwNSAtNzMuNDEsNTMuMzYgLTM2LjQ4OCwtMTEuODc1IC0xNDIuOTAzLC0xOTYuNjkyIDEwOS44ODMsLTc5LjgyOCAxNDIuOTE4LDE5Ni43MDMgMCwzOC4zMzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0MCIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gODI4LjUyLDcwNi40NjUgLTczLjQyNiwtNTMuMzQgMC4wMTEsLTM4LjM1OSBMIDg5OC4wMDQsNDE4LjA3IDEwMDcuOSw0OTcuODk4IDg2NC45NzMsNjk0LjYwOSA4MjguNTIsNzA2LjQ2NSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA4MTIuMDg2LDgyOC41ODYgMjguMDU1LC04Ni4zMiAzNi40ODQsLTExLjgzNiAyMzEuMjI1LDc1LjExNyAtNDEuOTcsMTI5LjE4MyAtMjMxLjIzOSwtNzUuMTQgLTIyLjU1NSwtMzEuMDA0IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNDQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDczNi4zMDEsMTMzNS44OCBjIC0zMjMuMDQ3LDAgLTU4NS44NzUsLTI2Mi43OCAtNTg1Ljg3NSwtNTg1Ljc4MiAwLC0zMjMuMTE4IDI2Mi44MjgsLTU4NS45NzcgNTg1Ljg3NSwtNTg1Ljk3NyAzMjMuMDE5LDAgNTg1LjgwOSwyNjIuODU5IDU4NS44MDksNTg1Ljk3NyAwLDMyMy4wMDIgLTI2Mi43OSw1ODUuNzgyIC01ODUuODA5LDU4NS43ODIgbCAwLDAgeiBtIDAsLTExOC42MSBjIDI1Ny45NzIsMCA0NjcuMTg5LC0yMDkuMTMgNDY3LjE4OSwtNDY3LjE3MiAwLC0yNTguMTI5IC0yMDkuMjE3LC00NjcuMzQ4IC00NjcuMTg5LC00NjcuMzQ4IC0yNTguMDc0LDAgLTQ2Ny4yNTQsMjA5LjIxOSAtNDY3LjI1NCw0NjcuMzQ4IDAsMjU4LjA0MiAyMDkuMTgsNDY3LjE3MiA0NjcuMjU0LDQ2Ny4xNzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0NiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTA5MS4xMyw2MTkuODgzIC0xNzUuNzcxLDU3LjEyMSAxMS42MjksMzUuODA4IDE3NS43NjIsLTU3LjEyMSAtMTEuNjIsLTM1LjgwOCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQ4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA4NjYuOTU3LDkwMi4wNzQgODM2LjUsOTI0LjE5OSA5NDUuMTIxLDEwNzMuNzMgOTc1LjU4NiwxMDUxLjYxIDg2Ni45NTcsOTAyLjA3NCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDUwIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA2MDcuNDY1LDkwMy40NDUgNDk4Ljg1NSwxMDUyLjk3IDUyOS4zMiwxMDc1LjEgNjM3LjkzLDkyNS41NjYgNjA3LjQ2NSw5MDMuNDQ1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDM4MC42ODgsNjIyLjEyOSAtMTEuNjI2LDM1LjgwMSAxNzUuNzU4LDU3LjA5IDExLjYyMSwtMzUuODAxIC0xNzUuNzUzLC01Ny4wOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDU0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA3MTYuMjg5LDM3Ni41OSAzNy42NDA2LDAgMCwxODQuODE2IC0zNy42NDA2LDAgMCwtMTg0LjgxNiB6IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTYiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4=') no-repeat, none; -moz-background-size: 100%; -o-background-size: 100%; -webkit-background-size: 100%; background-size: 100%; display: block; float: left; width: 90px; height: 25px; } +.jasmine_html-reporter .banner .version { margin-left: 14px; position: relative; top: 6px; } +.jasmine_html-reporter .banner .duration { position: absolute; right: 14px; top: 6px; } +.jasmine_html-reporter #jasmine_content { position: fixed; right: 100%; } +.jasmine_html-reporter .version { color: #aaa; } +.jasmine_html-reporter .banner { margin-top: 14px; } +.jasmine_html-reporter .duration { color: #aaa; float: right; } +.jasmine_html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; } +.jasmine_html-reporter .symbol-summary li { display: inline-block; height: 8px; width: 14px; font-size: 16px; } +.jasmine_html-reporter .symbol-summary li.passed { font-size: 14px; } +.jasmine_html-reporter .symbol-summary li.passed:before { color: #007069; content: "\02022"; } +.jasmine_html-reporter .symbol-summary li.failed { line-height: 9px; } +.jasmine_html-reporter .symbol-summary li.failed:before { color: #ca3a11; content: "\d7"; font-weight: bold; margin-left: -1px; } +.jasmine_html-reporter .symbol-summary li.disabled { font-size: 14px; } +.jasmine_html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; } +.jasmine_html-reporter .symbol-summary li.pending { line-height: 17px; } +.jasmine_html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; } +.jasmine_html-reporter .symbol-summary li.empty { font-size: 14px; } +.jasmine_html-reporter .symbol-summary li.empty:before { color: #ba9d37; content: "\02022"; } +.jasmine_html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; } +.jasmine_html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } +.jasmine_html-reporter .bar.failed { background-color: #ca3a11; } +.jasmine_html-reporter .bar.passed { background-color: #007069; } +.jasmine_html-reporter .bar.skipped { background-color: #bababa; } +.jasmine_html-reporter .bar.errored { background-color: #ca3a11; } +.jasmine_html-reporter .bar.menu { background-color: #fff; color: #aaa; } +.jasmine_html-reporter .bar.menu a { color: #333; } +.jasmine_html-reporter .bar a { color: white; } +.jasmine_html-reporter.spec-list .bar.menu.failure-list, .jasmine_html-reporter.spec-list .results .failures { display: none; } +.jasmine_html-reporter.failure-list .bar.menu.spec-list, .jasmine_html-reporter.failure-list .summary { display: none; } +.jasmine_html-reporter .running-alert { background-color: #666; } +.jasmine_html-reporter .results { margin-top: 14px; } +.jasmine_html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; } +.jasmine_html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; } +.jasmine_html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; } +.jasmine_html-reporter.showDetails .summary { display: none; } +.jasmine_html-reporter.showDetails #details { display: block; } +.jasmine_html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; } +.jasmine_html-reporter .summary { margin-top: 14px; } +.jasmine_html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; } +.jasmine_html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; } +.jasmine_html-reporter .summary li.passed a { color: #007069; } +.jasmine_html-reporter .summary li.failed a { color: #ca3a11; } +.jasmine_html-reporter .summary li.empty a { color: #ba9d37; } +.jasmine_html-reporter .summary li.pending a { color: #ba9d37; } +.jasmine_html-reporter .description + .suite { margin-top: 0; } +.jasmine_html-reporter .suite { margin-top: 14px; } +.jasmine_html-reporter .suite a { color: #333; } +.jasmine_html-reporter .failures .spec-detail { margin-bottom: 28px; } +.jasmine_html-reporter .failures .spec-detail .description { background-color: #ca3a11; } +.jasmine_html-reporter .failures .spec-detail .description a { color: white; } +.jasmine_html-reporter .result-message { padding-top: 14px; color: #333; white-space: pre; } +.jasmine_html-reporter .result-message span.result { display: block; } +.jasmine_html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666; border: 1px solid #ddd; background: white; white-space: pre; } diff --git a/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine.js b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine.js new file mode 100755 index 0000000..6bf3f02 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine.js @@ -0,0 +1,3048 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +var getJasmineRequireObj = (function (jasmineGlobal) { + var jasmineRequire; + + if (typeof module !== 'undefined' && module.exports) { + jasmineGlobal = global; + jasmineRequire = exports; + } else { + if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') { + jasmineGlobal = window; + } + jasmineRequire = jasmineGlobal.jasmineRequire = jasmineGlobal.jasmineRequire || {}; + } + + function getJasmineRequire() { + return jasmineRequire; + } + + getJasmineRequire().core = function(jRequire) { + var j$ = {}; + + jRequire.base(j$, jasmineGlobal); + j$.util = jRequire.util(); + j$.Any = jRequire.Any(); + j$.Anything = jRequire.Anything(j$); + j$.CallTracker = jRequire.CallTracker(); + j$.MockDate = jRequire.MockDate(); + j$.Clock = jRequire.Clock(); + j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(); + j$.Env = jRequire.Env(j$); + j$.ExceptionFormatter = jRequire.ExceptionFormatter(); + j$.Expectation = jRequire.Expectation(); + j$.buildExpectationResult = jRequire.buildExpectationResult(); + j$.JsApiReporter = jRequire.JsApiReporter(); + j$.matchersUtil = jRequire.matchersUtil(j$); + j$.ObjectContaining = jRequire.ObjectContaining(j$); + j$.ArrayContaining = jRequire.ArrayContaining(j$); + j$.pp = jRequire.pp(j$); + j$.QueueRunner = jRequire.QueueRunner(j$); + j$.ReportDispatcher = jRequire.ReportDispatcher(); + j$.Spec = jRequire.Spec(j$); + j$.SpyRegistry = jRequire.SpyRegistry(j$); + j$.SpyStrategy = jRequire.SpyStrategy(); + j$.StringMatching = jRequire.StringMatching(j$); + j$.Suite = jRequire.Suite(); + j$.Timer = jRequire.Timer(); + j$.version = jRequire.version(); + + j$.matchers = jRequire.requireMatchers(jRequire, j$); + + return j$; + }; + + return getJasmineRequire; +})(this); + +getJasmineRequireObj().requireMatchers = function(jRequire, j$) { + var availableMatchers = [ + 'toBe', + 'toBeCloseTo', + 'toBeDefined', + 'toBeFalsy', + 'toBeGreaterThan', + 'toBeLessThan', + 'toBeNaN', + 'toBeNull', + 'toBeTruthy', + 'toBeUndefined', + 'toContain', + 'toEqual', + 'toHaveBeenCalled', + 'toHaveBeenCalledWith', + 'toMatch', + 'toThrow', + 'toThrowError' + ], + matchers = {}; + + for (var i = 0; i < availableMatchers.length; i++) { + var name = availableMatchers[i]; + matchers[name] = jRequire[name](j$); + } + + return matchers; +}; + +getJasmineRequireObj().base = function(j$, jasmineGlobal) { + j$.unimplementedMethod_ = function() { + throw new Error('unimplemented method'); + }; + + j$.MAX_PRETTY_PRINT_DEPTH = 40; + j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 100; + j$.DEFAULT_TIMEOUT_INTERVAL = 5000; + + j$.getGlobal = function() { + return jasmineGlobal; + }; + + j$.getEnv = function(options) { + var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options); + //jasmine. singletons in here (setTimeout blah blah). + return env; + }; + + j$.isArray_ = function(value) { + return j$.isA_('Array', value); + }; + + j$.isString_ = function(value) { + return j$.isA_('String', value); + }; + + j$.isNumber_ = function(value) { + return j$.isA_('Number', value); + }; + + j$.isA_ = function(typeName, value) { + return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; + }; + + j$.isDomNode = function(obj) { + return obj.nodeType > 0; + }; + + j$.fnNameFor = function(func) { + return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1]; + }; + + j$.any = function(clazz) { + return new j$.Any(clazz); + }; + + j$.anything = function() { + return new j$.Anything(); + }; + + j$.objectContaining = function(sample) { + return new j$.ObjectContaining(sample); + }; + + j$.stringMatching = function(expected) { + return new j$.StringMatching(expected); + }; + + j$.arrayContaining = function(sample) { + return new j$.ArrayContaining(sample); + }; + + j$.createSpy = function(name, originalFn) { + + var spyStrategy = new j$.SpyStrategy({ + name: name, + fn: originalFn, + getSpy: function() { return spy; } + }), + callTracker = new j$.CallTracker(), + spy = function() { + var callData = { + object: this, + args: Array.prototype.slice.apply(arguments) + }; + + callTracker.track(callData); + var returnValue = spyStrategy.exec.apply(this, arguments); + callData.returnValue = returnValue; + + return returnValue; + }; + + for (var prop in originalFn) { + if (prop === 'and' || prop === 'calls') { + throw new Error('Jasmine spies would overwrite the \'and\' and \'calls\' properties on the object being spied upon'); + } + + spy[prop] = originalFn[prop]; + } + + spy.and = spyStrategy; + spy.calls = callTracker; + + return spy; + }; + + j$.isSpy = function(putativeSpy) { + if (!putativeSpy) { + return false; + } + return putativeSpy.and instanceof j$.SpyStrategy && + putativeSpy.calls instanceof j$.CallTracker; + }; + + j$.createSpyObj = function(baseName, methodNames) { + if (j$.isArray_(baseName) && j$.util.isUndefined(methodNames)) { + methodNames = baseName; + baseName = 'unknown'; + } + + if (!j$.isArray_(methodNames) || methodNames.length === 0) { + throw 'createSpyObj requires a non-empty array of method names to create spies for'; + } + var obj = {}; + for (var i = 0; i < methodNames.length; i++) { + obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]); + } + return obj; + }; +}; + +getJasmineRequireObj().util = function() { + + var util = {}; + + util.inherit = function(childClass, parentClass) { + var Subclass = function() { + }; + Subclass.prototype = parentClass.prototype; + childClass.prototype = new Subclass(); + }; + + util.htmlEscape = function(str) { + if (!str) { + return str; + } + return str.replace(/&/g, '&') + .replace(//g, '>'); + }; + + util.argsToArray = function(args) { + var arrayOfArgs = []; + for (var i = 0; i < args.length; i++) { + arrayOfArgs.push(args[i]); + } + return arrayOfArgs; + }; + + util.isUndefined = function(obj) { + return obj === void 0; + }; + + util.arrayContains = function(array, search) { + var i = array.length; + while (i--) { + if (array[i] === search) { + return true; + } + } + return false; + }; + + util.clone = function(obj) { + if (Object.prototype.toString.apply(obj) === '[object Array]') { + return obj.slice(); + } + + var cloned = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + cloned[prop] = obj[prop]; + } + } + + return cloned; + }; + + return util; +}; + +getJasmineRequireObj().Spec = function(j$) { + function Spec(attrs) { + this.expectationFactory = attrs.expectationFactory; + this.resultCallback = attrs.resultCallback || function() {}; + this.id = attrs.id; + this.description = attrs.description || ''; + this.queueableFn = attrs.queueableFn; + this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; }; + this.userContext = attrs.userContext || function() { return {}; }; + this.onStart = attrs.onStart || function() {}; + this.getSpecName = attrs.getSpecName || function() { return ''; }; + this.expectationResultFactory = attrs.expectationResultFactory || function() { }; + this.queueRunnerFactory = attrs.queueRunnerFactory || function() {}; + this.catchingExceptions = attrs.catchingExceptions || function() { return true; }; + + if (!this.queueableFn.fn) { + this.pend(); + } + + this.result = { + id: this.id, + description: this.description, + fullName: this.getFullName(), + failedExpectations: [], + passedExpectations: [], + pendingReason: '' + }; + } + + Spec.prototype.addExpectationResult = function(passed, data) { + var expectationResult = this.expectationResultFactory(data); + if (passed) { + this.result.passedExpectations.push(expectationResult); + } else { + this.result.failedExpectations.push(expectationResult); + } + }; + + Spec.prototype.expect = function(actual) { + return this.expectationFactory(actual, this); + }; + + Spec.prototype.execute = function(onComplete) { + var self = this; + + this.onStart(this); + + if (this.markedPending || this.disabled) { + complete(); + return; + } + + var fns = this.beforeAndAfterFns(); + var allFns = fns.befores.concat(this.queueableFn).concat(fns.afters); + + this.queueRunnerFactory({ + queueableFns: allFns, + onException: function() { self.onException.apply(self, arguments); }, + onComplete: complete, + userContext: this.userContext() + }); + + function complete() { + self.result.status = self.status(); + self.resultCallback(self.result); + + if (onComplete) { + onComplete(); + } + } + }; + + Spec.prototype.onException = function onException(e) { + if (Spec.isPendingSpecException(e)) { + this.pend(extractCustomPendingMessage(e)); + return; + } + + this.addExpectationResult(false, { + matcherName: '', + passed: false, + expected: '', + actual: '', + error: e + }); + }; + + Spec.prototype.disable = function() { + this.disabled = true; + }; + + Spec.prototype.pend = function(message) { + this.markedPending = true; + if (message) { + this.result.pendingReason = message; + } + }; + + Spec.prototype.status = function() { + if (this.disabled) { + return 'disabled'; + } + + if (this.markedPending) { + return 'pending'; + } + + if (this.result.failedExpectations.length > 0) { + return 'failed'; + } else { + return 'passed'; + } + }; + + Spec.prototype.isExecutable = function() { + return !this.disabled && !this.markedPending; + }; + + Spec.prototype.getFullName = function() { + return this.getSpecName(this); + }; + + var extractCustomPendingMessage = function(e) { + var fullMessage = e.toString(), + boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage), + boilerplateEnd = boilerplateStart + Spec.pendingSpecExceptionMessage.length; + + return fullMessage.substr(boilerplateEnd); + }; + + Spec.pendingSpecExceptionMessage = '=> marked Pending'; + + Spec.isPendingSpecException = function(e) { + return !!(e && e.toString && e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1); + }; + + return Spec; +}; + +if (typeof window == void 0 && typeof exports == 'object') { + exports.Spec = jasmineRequire.Spec; +} + +getJasmineRequireObj().Env = function(j$) { + function Env(options) { + options = options || {}; + + var self = this; + var global = options.global || j$.getGlobal(); + + var totalSpecsDefined = 0; + + var catchExceptions = true; + + var realSetTimeout = j$.getGlobal().setTimeout; + var realClearTimeout = j$.getGlobal().clearTimeout; + this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler(), new j$.MockDate(global)); + + var runnableLookupTable = {}; + var runnableResources = {}; + + var currentSpec = null; + var currentlyExecutingSuites = []; + var currentDeclarationSuite = null; + + var currentSuite = function() { + return currentlyExecutingSuites[currentlyExecutingSuites.length - 1]; + }; + + var currentRunnable = function() { + return currentSpec || currentSuite(); + }; + + var reporter = new j$.ReportDispatcher([ + 'jasmineStarted', + 'jasmineDone', + 'suiteStarted', + 'suiteDone', + 'specStarted', + 'specDone' + ]); + + this.specFilter = function() { + return true; + }; + + this.addCustomEqualityTester = function(tester) { + if(!currentRunnable()) { + throw new Error('Custom Equalities must be added in a before function or a spec'); + } + runnableResources[currentRunnable().id].customEqualityTesters.push(tester); + }; + + this.addMatchers = function(matchersToAdd) { + if(!currentRunnable()) { + throw new Error('Matchers must be added in a before function or a spec'); + } + var customMatchers = runnableResources[currentRunnable().id].customMatchers; + for (var matcherName in matchersToAdd) { + customMatchers[matcherName] = matchersToAdd[matcherName]; + } + }; + + j$.Expectation.addCoreMatchers(j$.matchers); + + var nextSpecId = 0; + var getNextSpecId = function() { + return 'spec' + nextSpecId++; + }; + + var nextSuiteId = 0; + var getNextSuiteId = function() { + return 'suite' + nextSuiteId++; + }; + + var expectationFactory = function(actual, spec) { + return j$.Expectation.Factory({ + util: j$.matchersUtil, + customEqualityTesters: runnableResources[spec.id].customEqualityTesters, + customMatchers: runnableResources[spec.id].customMatchers, + actual: actual, + addExpectationResult: addExpectationResult + }); + + function addExpectationResult(passed, result) { + return spec.addExpectationResult(passed, result); + } + }; + + var defaultResourcesForRunnable = function(id, parentRunnableId) { + var resources = {spies: [], customEqualityTesters: [], customMatchers: {}}; + + if(runnableResources[parentRunnableId]){ + resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters); + resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers); + } + + runnableResources[id] = resources; + }; + + var clearResourcesForRunnable = function(id) { + spyRegistry.clearSpies(); + delete runnableResources[id]; + }; + + var beforeAndAfterFns = function(suite, runnablesExplictlySet) { + return function() { + var befores = [], + afters = [], + beforeAlls = [], + afterAlls = []; + + while(suite) { + befores = befores.concat(suite.beforeFns); + afters = afters.concat(suite.afterFns); + + if (runnablesExplictlySet()) { + beforeAlls = beforeAlls.concat(suite.beforeAllFns); + afterAlls = afterAlls.concat(suite.afterAllFns); + } + + suite = suite.parentSuite; + } + return { + befores: beforeAlls.reverse().concat(befores.reverse()), + afters: afters.concat(afterAlls) + }; + }; + }; + + var getSpecName = function(spec, suite) { + return suite.getFullName() + ' ' + spec.description; + }; + + // TODO: we may just be able to pass in the fn instead of wrapping here + var buildExpectationResult = j$.buildExpectationResult, + exceptionFormatter = new j$.ExceptionFormatter(), + expectationResultFactory = function(attrs) { + attrs.messageFormatter = exceptionFormatter.message; + attrs.stackFormatter = exceptionFormatter.stack; + + return buildExpectationResult(attrs); + }; + + // TODO: fix this naming, and here's where the value comes in + this.catchExceptions = function(value) { + catchExceptions = !!value; + return catchExceptions; + }; + + this.catchingExceptions = function() { + return catchExceptions; + }; + + var maximumSpecCallbackDepth = 20; + var currentSpecCallbackDepth = 0; + + function clearStack(fn) { + currentSpecCallbackDepth++; + if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) { + currentSpecCallbackDepth = 0; + realSetTimeout(fn, 0); + } else { + fn(); + } + } + + var catchException = function(e) { + return j$.Spec.isPendingSpecException(e) || catchExceptions; + }; + + var queueRunnerFactory = function(options) { + options.catchException = catchException; + options.clearStack = options.clearStack || clearStack; + options.timer = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}; + options.fail = self.fail; + + new j$.QueueRunner(options).execute(); + }; + + var topSuite = new j$.Suite({ + env: this, + id: getNextSuiteId(), + description: 'Jasmine__TopLevel__Suite', + queueRunner: queueRunnerFactory + }); + runnableLookupTable[topSuite.id] = topSuite; + defaultResourcesForRunnable(topSuite.id); + currentDeclarationSuite = topSuite; + + this.topSuite = function() { + return topSuite; + }; + + this.execute = function(runnablesToRun) { + if(runnablesToRun) { + runnablesExplictlySet = true; + } else if (focusedRunnables.length) { + runnablesExplictlySet = true; + runnablesToRun = focusedRunnables; + } else { + runnablesToRun = [topSuite.id]; + } + + var allFns = []; + for(var i = 0; i < runnablesToRun.length; i++) { + var runnable = runnableLookupTable[runnablesToRun[i]]; + allFns.push((function(runnable) { return { fn: function(done) { runnable.execute(done); } }; })(runnable)); + } + + reporter.jasmineStarted({ + totalSpecsDefined: totalSpecsDefined + }); + + queueRunnerFactory({queueableFns: allFns, onComplete: reporter.jasmineDone}); + }; + + this.addReporter = function(reporterToAdd) { + reporter.addReporter(reporterToAdd); + }; + + var spyRegistry = new j$.SpyRegistry({currentSpies: function() { + if(!currentRunnable()) { + throw new Error('Spies must be created in a before function or a spec'); + } + return runnableResources[currentRunnable().id].spies; + }}); + + this.spyOn = function() { + return spyRegistry.spyOn.apply(spyRegistry, arguments); + }; + + var suiteFactory = function(description) { + var suite = new j$.Suite({ + env: self, + id: getNextSuiteId(), + description: description, + parentSuite: currentDeclarationSuite, + queueRunner: queueRunnerFactory, + onStart: suiteStarted, + expectationFactory: expectationFactory, + expectationResultFactory: expectationResultFactory, + runnablesExplictlySetGetter: runnablesExplictlySetGetter, + resultCallback: function(attrs) { + if (!suite.disabled) { + clearResourcesForRunnable(suite.id); + } + currentlyExecutingSuites.pop(); + reporter.suiteDone(attrs); + } + }); + + runnableLookupTable[suite.id] = suite; + return suite; + + function suiteStarted(suite) { + currentlyExecutingSuites.push(suite); + defaultResourcesForRunnable(suite.id, suite.parentSuite.id); + reporter.suiteStarted(suite.result); + } + }; + + this.describe = function(description, specDefinitions) { + var suite = suiteFactory(description); + addSpecsToSuite(suite, specDefinitions); + return suite; + }; + + this.xdescribe = function(description, specDefinitions) { + var suite = this.describe(description, specDefinitions); + suite.disable(); + return suite; + }; + + var focusedRunnables = []; + + this.fdescribe = function(description, specDefinitions) { + var suite = suiteFactory(description); + suite.isFocused = true; + + focusedRunnables.push(suite.id); + unfocusAncestor(); + addSpecsToSuite(suite, specDefinitions); + + return suite; + }; + + function addSpecsToSuite(suite, specDefinitions) { + var parentSuite = currentDeclarationSuite; + parentSuite.addChild(suite); + currentDeclarationSuite = suite; + + var declarationError = null; + try { + specDefinitions.call(suite); + } catch (e) { + declarationError = e; + } + + if (declarationError) { + self.it('encountered a declaration exception', function() { + throw declarationError; + }); + } + + currentDeclarationSuite = parentSuite; + } + + function findFocusedAncestor(suite) { + while (suite) { + if (suite.isFocused) { + return suite.id; + } + suite = suite.parentSuite; + } + + return null; + } + + function unfocusAncestor() { + var focusedAncestor = findFocusedAncestor(currentDeclarationSuite); + if (focusedAncestor) { + for (var i = 0; i < focusedRunnables.length; i++) { + if (focusedRunnables[i] === focusedAncestor) { + focusedRunnables.splice(i, 1); + break; + } + } + } + } + + var runnablesExplictlySet = false; + + var runnablesExplictlySetGetter = function(){ + return runnablesExplictlySet; + }; + + var specFactory = function(description, fn, suite, timeout) { + totalSpecsDefined++; + var spec = new j$.Spec({ + id: getNextSpecId(), + beforeAndAfterFns: beforeAndAfterFns(suite, runnablesExplictlySetGetter), + expectationFactory: expectationFactory, + resultCallback: specResultCallback, + getSpecName: function(spec) { + return getSpecName(spec, suite); + }, + onStart: specStarted, + description: description, + expectationResultFactory: expectationResultFactory, + queueRunnerFactory: queueRunnerFactory, + userContext: function() { return suite.clonedSharedUserContext(); }, + queueableFn: { + fn: fn, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + } + }); + + runnableLookupTable[spec.id] = spec; + + if (!self.specFilter(spec)) { + spec.disable(); + } + + return spec; + + function specResultCallback(result) { + clearResourcesForRunnable(spec.id); + currentSpec = null; + reporter.specDone(result); + } + + function specStarted(spec) { + currentSpec = spec; + defaultResourcesForRunnable(spec.id, suite.id); + reporter.specStarted(spec.result); + } + }; + + this.it = function(description, fn, timeout) { + var spec = specFactory(description, fn, currentDeclarationSuite, timeout); + currentDeclarationSuite.addChild(spec); + return spec; + }; + + this.xit = function() { + var spec = this.it.apply(this, arguments); + spec.pend(); + return spec; + }; + + this.fit = function(){ + var spec = this.it.apply(this, arguments); + + focusedRunnables.push(spec.id); + unfocusAncestor(); + return spec; + }; + + this.expect = function(actual) { + if (!currentRunnable()) { + throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out'); + } + + return currentRunnable().expect(actual); + }; + + this.beforeEach = function(beforeEachFunction, timeout) { + currentDeclarationSuite.beforeEach({ + fn: beforeEachFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.beforeAll = function(beforeAllFunction, timeout) { + currentDeclarationSuite.beforeAll({ + fn: beforeAllFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.afterEach = function(afterEachFunction, timeout) { + currentDeclarationSuite.afterEach({ + fn: afterEachFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.afterAll = function(afterAllFunction, timeout) { + currentDeclarationSuite.afterAll({ + fn: afterAllFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.pending = function(message) { + var fullMessage = j$.Spec.pendingSpecExceptionMessage; + if(message) { + fullMessage += message; + } + throw fullMessage; + }; + + this.fail = function(error) { + var message = 'Failed'; + if (error) { + message += ': '; + message += error.message || error; + } + + currentRunnable().addExpectationResult(false, { + matcherName: '', + passed: false, + expected: '', + actual: '', + message: message, + error: error && error.message ? error : null + }); + }; + } + + return Env; +}; + +getJasmineRequireObj().JsApiReporter = function() { + + var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } + }; + + function JsApiReporter(options) { + var timer = options.timer || noopTimer, + status = 'loaded'; + + this.started = false; + this.finished = false; + + this.jasmineStarted = function() { + this.started = true; + status = 'started'; + timer.start(); + }; + + var executionTime; + + this.jasmineDone = function() { + this.finished = true; + executionTime = timer.elapsed(); + status = 'done'; + }; + + this.status = function() { + return status; + }; + + var suites = [], + suites_hash = {}; + + this.suiteStarted = function(result) { + suites_hash[result.id] = result; + }; + + this.suiteDone = function(result) { + storeSuite(result); + }; + + this.suiteResults = function(index, length) { + return suites.slice(index, index + length); + }; + + function storeSuite(result) { + suites.push(result); + suites_hash[result.id] = result; + } + + this.suites = function() { + return suites_hash; + }; + + var specs = []; + + this.specDone = function(result) { + specs.push(result); + }; + + this.specResults = function(index, length) { + return specs.slice(index, index + length); + }; + + this.specs = function() { + return specs; + }; + + this.executionTime = function() { + return executionTime; + }; + + } + + return JsApiReporter; +}; + +getJasmineRequireObj().CallTracker = function() { + + function CallTracker() { + var calls = []; + + this.track = function(context) { + calls.push(context); + }; + + this.any = function() { + return !!calls.length; + }; + + this.count = function() { + return calls.length; + }; + + this.argsFor = function(index) { + var call = calls[index]; + return call ? call.args : []; + }; + + this.all = function() { + return calls; + }; + + this.allArgs = function() { + var callArgs = []; + for(var i = 0; i < calls.length; i++){ + callArgs.push(calls[i].args); + } + + return callArgs; + }; + + this.first = function() { + return calls[0]; + }; + + this.mostRecent = function() { + return calls[calls.length - 1]; + }; + + this.reset = function() { + calls = []; + }; + } + + return CallTracker; +}; + +getJasmineRequireObj().Clock = function() { + function Clock(global, delayedFunctionScheduler, mockDate) { + var self = this, + realTimingFunctions = { + setTimeout: global.setTimeout, + clearTimeout: global.clearTimeout, + setInterval: global.setInterval, + clearInterval: global.clearInterval + }, + fakeTimingFunctions = { + setTimeout: setTimeout, + clearTimeout: clearTimeout, + setInterval: setInterval, + clearInterval: clearInterval + }, + installed = false, + timer; + + + self.install = function() { + replace(global, fakeTimingFunctions); + timer = fakeTimingFunctions; + installed = true; + + return self; + }; + + self.uninstall = function() { + delayedFunctionScheduler.reset(); + mockDate.uninstall(); + replace(global, realTimingFunctions); + + timer = realTimingFunctions; + installed = false; + }; + + self.mockDate = function(initialDate) { + mockDate.install(initialDate); + }; + + self.setTimeout = function(fn, delay, params) { + if (legacyIE()) { + if (arguments.length > 2) { + throw new Error('IE < 9 cannot support extra params to setTimeout without a polyfill'); + } + return timer.setTimeout(fn, delay); + } + return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]); + }; + + self.setInterval = function(fn, delay, params) { + if (legacyIE()) { + if (arguments.length > 2) { + throw new Error('IE < 9 cannot support extra params to setInterval without a polyfill'); + } + return timer.setInterval(fn, delay); + } + return Function.prototype.apply.apply(timer.setInterval, [global, arguments]); + }; + + self.clearTimeout = function(id) { + return Function.prototype.call.apply(timer.clearTimeout, [global, id]); + }; + + self.clearInterval = function(id) { + return Function.prototype.call.apply(timer.clearInterval, [global, id]); + }; + + self.tick = function(millis) { + if (installed) { + mockDate.tick(millis); + delayedFunctionScheduler.tick(millis); + } else { + throw new Error('Mock clock is not installed, use jasmine.clock().install()'); + } + }; + + return self; + + function legacyIE() { + //if these methods are polyfilled, apply will be present + return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply; + } + + function replace(dest, source) { + for (var prop in source) { + dest[prop] = source[prop]; + } + } + + function setTimeout(fn, delay) { + return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2)); + } + + function clearTimeout(id) { + return delayedFunctionScheduler.removeFunctionWithId(id); + } + + function setInterval(fn, interval) { + return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true); + } + + function clearInterval(id) { + return delayedFunctionScheduler.removeFunctionWithId(id); + } + + function argSlice(argsObj, n) { + return Array.prototype.slice.call(argsObj, n); + } + } + + return Clock; +}; + +getJasmineRequireObj().DelayedFunctionScheduler = function() { + function DelayedFunctionScheduler() { + var self = this; + var scheduledLookup = []; + var scheduledFunctions = {}; + var currentTime = 0; + var delayedFnCount = 0; + + self.tick = function(millis) { + millis = millis || 0; + var endTime = currentTime + millis; + + runScheduledFunctions(endTime); + currentTime = endTime; + }; + + self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) { + var f; + if (typeof(funcToCall) === 'string') { + /* jshint evil: true */ + f = function() { return eval(funcToCall); }; + /* jshint evil: false */ + } else { + f = funcToCall; + } + + millis = millis || 0; + timeoutKey = timeoutKey || ++delayedFnCount; + runAtMillis = runAtMillis || (currentTime + millis); + + var funcToSchedule = { + runAtMillis: runAtMillis, + funcToCall: f, + recurring: recurring, + params: params, + timeoutKey: timeoutKey, + millis: millis + }; + + if (runAtMillis in scheduledFunctions) { + scheduledFunctions[runAtMillis].push(funcToSchedule); + } else { + scheduledFunctions[runAtMillis] = [funcToSchedule]; + scheduledLookup.push(runAtMillis); + scheduledLookup.sort(function (a, b) { + return a - b; + }); + } + + return timeoutKey; + }; + + self.removeFunctionWithId = function(timeoutKey) { + for (var runAtMillis in scheduledFunctions) { + var funcs = scheduledFunctions[runAtMillis]; + var i = indexOfFirstToPass(funcs, function (func) { + return func.timeoutKey === timeoutKey; + }); + + if (i > -1) { + if (funcs.length === 1) { + delete scheduledFunctions[runAtMillis]; + deleteFromLookup(runAtMillis); + } else { + funcs.splice(i, 1); + } + + // intervals get rescheduled when executed, so there's never more + // than a single scheduled function with a given timeoutKey + break; + } + } + }; + + self.reset = function() { + currentTime = 0; + scheduledLookup = []; + scheduledFunctions = {}; + delayedFnCount = 0; + }; + + return self; + + function indexOfFirstToPass(array, testFn) { + var index = -1; + + for (var i = 0; i < array.length; ++i) { + if (testFn(array[i])) { + index = i; + break; + } + } + + return index; + } + + function deleteFromLookup(key) { + var value = Number(key); + var i = indexOfFirstToPass(scheduledLookup, function (millis) { + return millis === value; + }); + + if (i > -1) { + scheduledLookup.splice(i, 1); + } + } + + function reschedule(scheduledFn) { + self.scheduleFunction(scheduledFn.funcToCall, + scheduledFn.millis, + scheduledFn.params, + true, + scheduledFn.timeoutKey, + scheduledFn.runAtMillis + scheduledFn.millis); + } + + function forEachFunction(funcsToRun, callback) { + for (var i = 0; i < funcsToRun.length; ++i) { + callback(funcsToRun[i]); + } + } + + function runScheduledFunctions(endTime) { + if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) { + return; + } + + do { + currentTime = scheduledLookup.shift(); + + var funcsToRun = scheduledFunctions[currentTime]; + delete scheduledFunctions[currentTime]; + + forEachFunction(funcsToRun, function(funcToRun) { + if (funcToRun.recurring) { + reschedule(funcToRun); + } + }); + + forEachFunction(funcsToRun, function(funcToRun) { + funcToRun.funcToCall.apply(null, funcToRun.params || []); + }); + } while (scheduledLookup.length > 0 && + // checking first if we're out of time prevents setTimeout(0) + // scheduled in a funcToRun from forcing an extra iteration + currentTime !== endTime && + scheduledLookup[0] <= endTime); + } + } + + return DelayedFunctionScheduler; +}; + +getJasmineRequireObj().ExceptionFormatter = function() { + function ExceptionFormatter() { + this.message = function(error) { + var message = ''; + + if (error.name && error.message) { + message += error.name + ': ' + error.message; + } else { + message += error.toString() + ' thrown'; + } + + if (error.fileName || error.sourceURL) { + message += ' in ' + (error.fileName || error.sourceURL); + } + + if (error.line || error.lineNumber) { + message += ' (line ' + (error.line || error.lineNumber) + ')'; + } + + return message; + }; + + this.stack = function(error) { + return error ? error.stack : null; + }; + } + + return ExceptionFormatter; +}; + +getJasmineRequireObj().Expectation = function() { + + function Expectation(options) { + this.util = options.util || { buildFailureMessage: function() {} }; + this.customEqualityTesters = options.customEqualityTesters || []; + this.actual = options.actual; + this.addExpectationResult = options.addExpectationResult || function(){}; + this.isNot = options.isNot; + + var customMatchers = options.customMatchers || {}; + for (var matcherName in customMatchers) { + this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]); + } + } + + Expectation.prototype.wrapCompare = function(name, matcherFactory) { + return function() { + var args = Array.prototype.slice.call(arguments, 0), + expected = args.slice(0), + message = ''; + + args.unshift(this.actual); + + var matcher = matcherFactory(this.util, this.customEqualityTesters), + matcherCompare = matcher.compare; + + function defaultNegativeCompare() { + var result = matcher.compare.apply(null, args); + result.pass = !result.pass; + return result; + } + + if (this.isNot) { + matcherCompare = matcher.negativeCompare || defaultNegativeCompare; + } + + var result = matcherCompare.apply(null, args); + + if (!result.pass) { + if (!result.message) { + args.unshift(this.isNot); + args.unshift(name); + message = this.util.buildFailureMessage.apply(null, args); + } else { + if (Object.prototype.toString.apply(result.message) === '[object Function]') { + message = result.message(); + } else { + message = result.message; + } + } + } + + if (expected.length == 1) { + expected = expected[0]; + } + + // TODO: how many of these params are needed? + this.addExpectationResult( + result.pass, + { + matcherName: name, + passed: result.pass, + message: message, + actual: this.actual, + expected: expected // TODO: this may need to be arrayified/sliced + } + ); + }; + }; + + Expectation.addCoreMatchers = function(matchers) { + var prototype = Expectation.prototype; + for (var matcherName in matchers) { + var matcher = matchers[matcherName]; + prototype[matcherName] = prototype.wrapCompare(matcherName, matcher); + } + }; + + Expectation.Factory = function(options) { + options = options || {}; + + var expect = new Expectation(options); + + // TODO: this would be nice as its own Object - NegativeExpectation + // TODO: copy instead of mutate options + options.isNot = true; + expect.not = new Expectation(options); + + return expect; + }; + + return Expectation; +}; + +//TODO: expectation result may make more sense as a presentation of an expectation. +getJasmineRequireObj().buildExpectationResult = function() { + function buildExpectationResult(options) { + var messageFormatter = options.messageFormatter || function() {}, + stackFormatter = options.stackFormatter || function() {}; + + var result = { + matcherName: options.matcherName, + message: message(), + stack: stack(), + passed: options.passed + }; + + if(!result.passed) { + result.expected = options.expected; + result.actual = options.actual; + } + + return result; + + function message() { + if (options.passed) { + return 'Passed.'; + } else if (options.message) { + return options.message; + } else if (options.error) { + return messageFormatter(options.error); + } + return ''; + } + + function stack() { + if (options.passed) { + return ''; + } + + var error = options.error; + if (!error) { + try { + throw new Error(message()); + } catch (e) { + error = e; + } + } + return stackFormatter(error); + } + } + + return buildExpectationResult; +}; + +getJasmineRequireObj().MockDate = function() { + function MockDate(global) { + var self = this; + var currentTime = 0; + + if (!global || !global.Date) { + self.install = function() {}; + self.tick = function() {}; + self.uninstall = function() {}; + return self; + } + + var GlobalDate = global.Date; + + self.install = function(mockDate) { + if (mockDate instanceof GlobalDate) { + currentTime = mockDate.getTime(); + } else { + currentTime = new GlobalDate().getTime(); + } + + global.Date = FakeDate; + }; + + self.tick = function(millis) { + millis = millis || 0; + currentTime = currentTime + millis; + }; + + self.uninstall = function() { + currentTime = 0; + global.Date = GlobalDate; + }; + + createDateProperties(); + + return self; + + function FakeDate() { + switch(arguments.length) { + case 0: + return new GlobalDate(currentTime); + case 1: + return new GlobalDate(arguments[0]); + case 2: + return new GlobalDate(arguments[0], arguments[1]); + case 3: + return new GlobalDate(arguments[0], arguments[1], arguments[2]); + case 4: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3]); + case 5: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4]); + case 6: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4], arguments[5]); + default: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4], arguments[5], arguments[6]); + } + } + + function createDateProperties() { + FakeDate.prototype = GlobalDate.prototype; + + FakeDate.now = function() { + if (GlobalDate.now) { + return currentTime; + } else { + throw new Error('Browser does not support Date.now()'); + } + }; + + FakeDate.toSource = GlobalDate.toSource; + FakeDate.toString = GlobalDate.toString; + FakeDate.parse = GlobalDate.parse; + FakeDate.UTC = GlobalDate.UTC; + } + } + + return MockDate; +}; + +getJasmineRequireObj().pp = function(j$) { + + function PrettyPrinter() { + this.ppNestLevel_ = 0; + this.seen = []; + } + + PrettyPrinter.prototype.format = function(value) { + this.ppNestLevel_++; + try { + if (j$.util.isUndefined(value)) { + this.emitScalar('undefined'); + } else if (value === null) { + this.emitScalar('null'); + } else if (value === 0 && 1/value === -Infinity) { + this.emitScalar('-0'); + } else if (value === j$.getGlobal()) { + this.emitScalar(''); + } else if (value.jasmineToString) { + this.emitScalar(value.jasmineToString()); + } else if (typeof value === 'string') { + this.emitString(value); + } else if (j$.isSpy(value)) { + this.emitScalar('spy on ' + value.and.identity()); + } else if (value instanceof RegExp) { + this.emitScalar(value.toString()); + } else if (typeof value === 'function') { + this.emitScalar('Function'); + } else if (typeof value.nodeType === 'number') { + this.emitScalar('HTMLNode'); + } else if (value instanceof Date) { + this.emitScalar('Date(' + value + ')'); + } else if (j$.util.arrayContains(this.seen, value)) { + this.emitScalar(''); + } else if (j$.isArray_(value) || j$.isA_('Object', value)) { + this.seen.push(value); + if (j$.isArray_(value)) { + this.emitArray(value); + } else { + this.emitObject(value); + } + this.seen.pop(); + } else { + this.emitScalar(value.toString()); + } + } finally { + this.ppNestLevel_--; + } + }; + + PrettyPrinter.prototype.iterateObject = function(obj, fn) { + for (var property in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, property)) { continue; } + fn(property, obj.__lookupGetter__ ? (!j$.util.isUndefined(obj.__lookupGetter__(property)) && + obj.__lookupGetter__(property) !== null) : false); + } + }; + + PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitString = j$.unimplementedMethod_; + + function StringPrettyPrinter() { + PrettyPrinter.call(this); + + this.string = ''; + } + + j$.util.inherit(StringPrettyPrinter, PrettyPrinter); + + StringPrettyPrinter.prototype.emitScalar = function(value) { + this.append(value); + }; + + StringPrettyPrinter.prototype.emitString = function(value) { + this.append('\'' + value + '\''); + }; + + StringPrettyPrinter.prototype.emitArray = function(array) { + if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { + this.append('Array'); + return; + } + var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH); + this.append('[ '); + for (var i = 0; i < length; i++) { + if (i > 0) { + this.append(', '); + } + this.format(array[i]); + } + if(array.length > length){ + this.append(', ...'); + } + this.append(' ]'); + }; + + StringPrettyPrinter.prototype.emitObject = function(obj) { + var constructorName = obj.constructor ? j$.fnNameFor(obj.constructor) : 'null'; + this.append(constructorName); + + if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { + return; + } + + var self = this; + this.append('({ '); + var first = true; + + this.iterateObject(obj, function(property, isGetter) { + if (first) { + first = false; + } else { + self.append(', '); + } + + self.append(property); + self.append(': '); + if (isGetter) { + self.append(''); + } else { + self.format(obj[property]); + } + }); + + this.append(' })'); + }; + + StringPrettyPrinter.prototype.append = function(value) { + this.string += value; + }; + + return function(value) { + var stringPrettyPrinter = new StringPrettyPrinter(); + stringPrettyPrinter.format(value); + return stringPrettyPrinter.string; + }; +}; + +getJasmineRequireObj().QueueRunner = function(j$) { + + function once(fn) { + var called = false; + return function() { + if (!called) { + called = true; + fn(); + } + }; + } + + function QueueRunner(attrs) { + this.queueableFns = attrs.queueableFns || []; + this.onComplete = attrs.onComplete || function() {}; + this.clearStack = attrs.clearStack || function(fn) {fn();}; + this.onException = attrs.onException || function() {}; + this.catchException = attrs.catchException || function() { return true; }; + this.userContext = attrs.userContext || {}; + this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout}; + this.fail = attrs.fail || function() {}; + } + + QueueRunner.prototype.execute = function() { + this.run(this.queueableFns, 0); + }; + + QueueRunner.prototype.run = function(queueableFns, recursiveIndex) { + var length = queueableFns.length, + self = this, + iterativeIndex; + + + for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) { + var queueableFn = queueableFns[iterativeIndex]; + if (queueableFn.fn.length > 0) { + attemptAsync(queueableFn); + return; + } else { + attemptSync(queueableFn); + } + } + + var runnerDone = iterativeIndex >= length; + + if (runnerDone) { + this.clearStack(this.onComplete); + } + + function attemptSync(queueableFn) { + try { + queueableFn.fn.call(self.userContext); + } catch (e) { + handleException(e, queueableFn); + } + } + + function attemptAsync(queueableFn) { + var clearTimeout = function () { + Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeoutId]]); + }, + next = once(function () { + clearTimeout(timeoutId); + self.run(queueableFns, iterativeIndex + 1); + }), + timeoutId; + + next.fail = function() { + self.fail.apply(null, arguments); + next(); + }; + + if (queueableFn.timeout) { + timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() { + var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'); + onException(error, queueableFn); + next(); + }, queueableFn.timeout()]]); + } + + try { + queueableFn.fn.call(self.userContext, next); + } catch (e) { + handleException(e, queueableFn); + next(); + } + } + + function onException(e, queueableFn) { + self.onException(e); + } + + function handleException(e, queueableFn) { + onException(e, queueableFn); + if (!self.catchException(e)) { + //TODO: set a var when we catch an exception and + //use a finally block to close the loop in a nice way.. + throw e; + } + } + }; + + return QueueRunner; +}; + +getJasmineRequireObj().ReportDispatcher = function() { + function ReportDispatcher(methods) { + + var dispatchedMethods = methods || []; + + for (var i = 0; i < dispatchedMethods.length; i++) { + var method = dispatchedMethods[i]; + this[method] = (function(m) { + return function() { + dispatch(m, arguments); + }; + }(method)); + } + + var reporters = []; + + this.addReporter = function(reporter) { + reporters.push(reporter); + }; + + return this; + + function dispatch(method, args) { + for (var i = 0; i < reporters.length; i++) { + var reporter = reporters[i]; + if (reporter[method]) { + reporter[method].apply(reporter, args); + } + } + } + } + + return ReportDispatcher; +}; + + +getJasmineRequireObj().SpyRegistry = function(j$) { + + function SpyRegistry(options) { + options = options || {}; + var currentSpies = options.currentSpies || function() { return []; }; + + this.spyOn = function(obj, methodName) { + if (j$.util.isUndefined(obj)) { + throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()'); + } + + if (j$.util.isUndefined(methodName)) { + throw new Error('No method name supplied'); + } + + if (j$.util.isUndefined(obj[methodName])) { + throw new Error(methodName + '() method does not exist'); + } + + if (obj[methodName] && j$.isSpy(obj[methodName])) { + //TODO?: should this return the current spy? Downside: may cause user confusion about spy state + throw new Error(methodName + ' has already been spied upon'); + } + + var spy = j$.createSpy(methodName, obj[methodName]); + + currentSpies().push({ + spy: spy, + baseObj: obj, + methodName: methodName, + originalValue: obj[methodName] + }); + + obj[methodName] = spy; + + return spy; + }; + + this.clearSpies = function() { + var spies = currentSpies(); + for (var i = 0; i < spies.length; i++) { + var spyEntry = spies[i]; + spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue; + } + }; + } + + return SpyRegistry; +}; + +getJasmineRequireObj().SpyStrategy = function() { + + function SpyStrategy(options) { + options = options || {}; + + var identity = options.name || 'unknown', + originalFn = options.fn || function() {}, + getSpy = options.getSpy || function() {}, + plan = function() {}; + + this.identity = function() { + return identity; + }; + + this.exec = function() { + return plan.apply(this, arguments); + }; + + this.callThrough = function() { + plan = originalFn; + return getSpy(); + }; + + this.returnValue = function(value) { + plan = function() { + return value; + }; + return getSpy(); + }; + + this.returnValues = function() { + var values = Array.prototype.slice.call(arguments); + plan = function () { + return values.shift(); + }; + return getSpy(); + }; + + this.throwError = function(something) { + var error = (something instanceof Error) ? something : new Error(something); + plan = function() { + throw error; + }; + return getSpy(); + }; + + this.callFake = function(fn) { + plan = fn; + return getSpy(); + }; + + this.stub = function(fn) { + plan = function() {}; + return getSpy(); + }; + } + + return SpyStrategy; +}; + +getJasmineRequireObj().Suite = function() { + function Suite(attrs) { + this.env = attrs.env; + this.id = attrs.id; + this.parentSuite = attrs.parentSuite; + this.description = attrs.description; + this.onStart = attrs.onStart || function() {}; + this.resultCallback = attrs.resultCallback || function() {}; + this.clearStack = attrs.clearStack || function(fn) {fn();}; + this.expectationFactory = attrs.expectationFactory; + this.expectationResultFactory = attrs.expectationResultFactory; + this.runnablesExplictlySetGetter = attrs.runnablesExplictlySetGetter || function() {}; + + this.beforeFns = []; + this.afterFns = []; + this.beforeAllFns = []; + this.afterAllFns = []; + this.queueRunner = attrs.queueRunner || function() {}; + this.disabled = false; + + this.children = []; + + this.result = { + id: this.id, + description: this.description, + fullName: this.getFullName(), + failedExpectations: [] + }; + } + + Suite.prototype.expect = function(actual) { + return this.expectationFactory(actual, this); + }; + + Suite.prototype.getFullName = function() { + var fullName = this.description; + for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { + if (parentSuite.parentSuite) { + fullName = parentSuite.description + ' ' + fullName; + } + } + return fullName; + }; + + Suite.prototype.disable = function() { + this.disabled = true; + }; + + Suite.prototype.beforeEach = function(fn) { + this.beforeFns.unshift(fn); + }; + + Suite.prototype.beforeAll = function(fn) { + this.beforeAllFns.push(fn); + }; + + Suite.prototype.afterEach = function(fn) { + this.afterFns.unshift(fn); + }; + + Suite.prototype.afterAll = function(fn) { + this.afterAllFns.push(fn); + }; + + Suite.prototype.addChild = function(child) { + this.children.push(child); + }; + + Suite.prototype.status = function() { + if (this.disabled) { + return 'disabled'; + } + + if (this.result.failedExpectations.length > 0) { + return 'failed'; + } else { + return 'finished'; + } + }; + + Suite.prototype.execute = function(onComplete) { + var self = this; + + this.onStart(this); + + if (this.disabled) { + complete(); + return; + } + + var allFns = []; + + for (var i = 0; i < this.children.length; i++) { + allFns.push(wrapChildAsAsync(this.children[i])); + } + + if (this.isExecutable()) { + allFns = this.beforeAllFns.concat(allFns); + allFns = allFns.concat(this.afterAllFns); + } + + this.queueRunner({ + queueableFns: allFns, + onComplete: complete, + userContext: this.sharedUserContext(), + onException: function() { self.onException.apply(self, arguments); } + }); + + function complete() { + self.result.status = self.status(); + self.resultCallback(self.result); + + if (onComplete) { + onComplete(); + } + } + + function wrapChildAsAsync(child) { + return { fn: function(done) { child.execute(done); } }; + } + }; + + Suite.prototype.isExecutable = function() { + var runnablesExplicitlySet = this.runnablesExplictlySetGetter(); + return !runnablesExplicitlySet && hasExecutableChild(this.children); + }; + + Suite.prototype.sharedUserContext = function() { + if (!this.sharedContext) { + this.sharedContext = this.parentSuite ? clone(this.parentSuite.sharedUserContext()) : {}; + } + + return this.sharedContext; + }; + + Suite.prototype.clonedSharedUserContext = function() { + return clone(this.sharedUserContext()); + }; + + Suite.prototype.onException = function() { + if(isAfterAll(this.children)) { + var data = { + matcherName: '', + passed: false, + expected: '', + actual: '', + error: arguments[0] + }; + this.result.failedExpectations.push(this.expectationResultFactory(data)); + } else { + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + child.onException.apply(child, arguments); + } + } + }; + + Suite.prototype.addExpectationResult = function () { + if(isAfterAll(this.children) && isFailure(arguments)){ + var data = arguments[1]; + this.result.failedExpectations.push(this.expectationResultFactory(data)); + } else { + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + child.addExpectationResult.apply(child, arguments); + } + } + }; + + function isAfterAll(children) { + return children && children[0].result.status; + } + + function isFailure(args) { + return !args[0]; + } + + function hasExecutableChild(children) { + var foundActive = false; + for (var i = 0; i < children.length; i++) { + if (children[i].isExecutable()) { + foundActive = true; + break; + } + } + return foundActive; + } + + function clone(obj) { + var clonedObj = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + clonedObj[prop] = obj[prop]; + } + } + + return clonedObj; + } + + return Suite; +}; + +if (typeof window == void 0 && typeof exports == 'object') { + exports.Suite = jasmineRequire.Suite; +} + +getJasmineRequireObj().Timer = function() { + var defaultNow = (function(Date) { + return function() { return new Date().getTime(); }; + })(Date); + + function Timer(options) { + options = options || {}; + + var now = options.now || defaultNow, + startTime; + + this.start = function() { + startTime = now(); + }; + + this.elapsed = function() { + return now() - startTime; + }; + } + + return Timer; +}; + +getJasmineRequireObj().Any = function() { + + function Any(expectedObject) { + this.expectedObject = expectedObject; + } + + Any.prototype.asymmetricMatch = function(other) { + if (this.expectedObject == String) { + return typeof other == 'string' || other instanceof String; + } + + if (this.expectedObject == Number) { + return typeof other == 'number' || other instanceof Number; + } + + if (this.expectedObject == Function) { + return typeof other == 'function' || other instanceof Function; + } + + if (this.expectedObject == Object) { + return typeof other == 'object'; + } + + if (this.expectedObject == Boolean) { + return typeof other == 'boolean'; + } + + return other instanceof this.expectedObject; + }; + + Any.prototype.jasmineToString = function() { + return ''; + }; + + return Any; +}; + +getJasmineRequireObj().Anything = function(j$) { + + function Anything() {} + + Anything.prototype.asymmetricMatch = function(other) { + return !j$.util.isUndefined(other) && other !== null; + }; + + Anything.prototype.jasmineToString = function() { + return ''; + }; + + return Anything; +}; + +getJasmineRequireObj().ArrayContaining = function(j$) { + function ArrayContaining(sample) { + this.sample = sample; + } + + ArrayContaining.prototype.asymmetricMatch = function(other) { + var className = Object.prototype.toString.call(this.sample); + if (className !== '[object Array]') { throw new Error('You must provide an array to arrayContaining, not \'' + this.sample + '\'.'); } + + for (var i = 0; i < this.sample.length; i++) { + var item = this.sample[i]; + if (!j$.matchersUtil.contains(other, item)) { + return false; + } + } + + return true; + }; + + ArrayContaining.prototype.jasmineToString = function () { + return ''; + }; + + return ArrayContaining; +}; + +getJasmineRequireObj().ObjectContaining = function(j$) { + + function ObjectContaining(sample) { + this.sample = sample; + } + + ObjectContaining.prototype.asymmetricMatch = function(other) { + if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); } + + for (var property in this.sample) { + if (!Object.prototype.hasOwnProperty.call(other, property) || + !j$.matchersUtil.equals(this.sample[property], other[property])) { + return false; + } + } + + return true; + }; + + ObjectContaining.prototype.jasmineToString = function() { + return ''; + }; + + return ObjectContaining; +}; + +getJasmineRequireObj().StringMatching = function(j$) { + + function StringMatching(expected) { + if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { + throw new Error('Expected is not a String or a RegExp'); + } + + this.regexp = new RegExp(expected); + } + + StringMatching.prototype.asymmetricMatch = function(other) { + return this.regexp.test(other); + }; + + StringMatching.prototype.jasmineToString = function() { + return ''; + }; + + return StringMatching; +}; + +getJasmineRequireObj().matchersUtil = function(j$) { + // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter? + + return { + equals: function(a, b, customTesters) { + customTesters = customTesters || []; + + return eq(a, b, [], [], customTesters); + }, + + contains: function(haystack, needle, customTesters) { + customTesters = customTesters || []; + + if ((Object.prototype.toString.apply(haystack) === '[object Array]') || + (!!haystack && !haystack.indexOf)) + { + for (var i = 0; i < haystack.length; i++) { + if (eq(haystack[i], needle, [], [], customTesters)) { + return true; + } + } + return false; + } + + return !!haystack && haystack.indexOf(needle) >= 0; + }, + + buildFailureMessage: function() { + var args = Array.prototype.slice.call(arguments, 0), + matcherName = args[0], + isNot = args[1], + actual = args[2], + expected = args.slice(3), + englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); + + var message = 'Expected ' + + j$.pp(actual) + + (isNot ? ' not ' : ' ') + + englishyPredicate; + + if (expected.length > 0) { + for (var i = 0; i < expected.length; i++) { + if (i > 0) { + message += ','; + } + message += ' ' + j$.pp(expected[i]); + } + } + + return message + '.'; + } + }; + + function isAsymmetric(obj) { + return obj && j$.isA_('Function', obj.asymmetricMatch); + } + + function asymmetricMatch(a, b) { + var asymmetricA = isAsymmetric(a), + asymmetricB = isAsymmetric(b); + + if (asymmetricA && asymmetricB) { + return undefined; + } + + if (asymmetricA) { + return a.asymmetricMatch(b); + } + + if (asymmetricB) { + return b.asymmetricMatch(a); + } + } + + // Equality function lovingly adapted from isEqual in + // [Underscore](http://underscorejs.org) + function eq(a, b, aStack, bStack, customTesters) { + var result = true; + + var asymmetricResult = asymmetricMatch(a, b); + if (!j$.util.isUndefined(asymmetricResult)) { + return asymmetricResult; + } + + for (var i = 0; i < customTesters.length; i++) { + var customTesterResult = customTesters[i](a, b); + if (!j$.util.isUndefined(customTesterResult)) { + return customTesterResult; + } + } + + if (a instanceof Error && b instanceof Error) { + return a.message == b.message; + } + + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) { return a !== 0 || 1 / a == 1 / b; } + // A strict comparison is necessary because `null == undefined`. + if (a === null || b === null) { return a === b; } + var className = Object.prototype.toString.call(a); + if (className != Object.prototype.toString.call(b)) { return false; } + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') { return false; } + + var aIsDomNode = j$.isDomNode(a); + var bIsDomNode = j$.isDomNode(b); + if (aIsDomNode && bIsDomNode) { + // At first try to use DOM3 method isEqualNode + if (a.isEqualNode) { + return a.isEqualNode(b); + } + // IE8 doesn't support isEqualNode, try to use outerHTML && innerText + var aIsElement = a instanceof Element; + var bIsElement = b instanceof Element; + if (aIsElement && bIsElement) { + return a.outerHTML == b.outerHTML; + } + if (aIsElement || bIsElement) { + return false; + } + return a.innerText == b.innerText && a.textContent == b.textContent; + } + if (aIsDomNode || bIsDomNode) { + return false; + } + + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] == a) { return bStack[length] == b; } + } + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + var size = 0; + // Recursively compare objects and arrays. + // Compare array lengths to determine if a deep comparison is necessary. + if (className == '[object Array]' && a.length !== b.length) { + result = false; + } + + if (result) { + // Objects with different constructors are not equivalent, but `Object`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(isFunction(aCtor) && (aCtor instanceof aCtor) && + isFunction(bCtor) && (bCtor instanceof bCtor))) { + return false; + } + // Deep compare objects. + for (var key in a) { + if (has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) { break; } + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (has(b, key) && !(size--)) { break; } + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + + return result; + + function has(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); + } + + function isFunction(obj) { + return typeof obj === 'function'; + } + } +}; + +getJasmineRequireObj().toBe = function() { + function toBe() { + return { + compare: function(actual, expected) { + return { + pass: actual === expected + }; + } + }; + } + + return toBe; +}; + +getJasmineRequireObj().toBeCloseTo = function() { + + function toBeCloseTo() { + return { + compare: function(actual, expected, precision) { + if (precision !== 0) { + precision = precision || 2; + } + + return { + pass: Math.abs(expected - actual) < (Math.pow(10, -precision) / 2) + }; + } + }; + } + + return toBeCloseTo; +}; + +getJasmineRequireObj().toBeDefined = function() { + function toBeDefined() { + return { + compare: function(actual) { + return { + pass: (void 0 !== actual) + }; + } + }; + } + + return toBeDefined; +}; + +getJasmineRequireObj().toBeFalsy = function() { + function toBeFalsy() { + return { + compare: function(actual) { + return { + pass: !!!actual + }; + } + }; + } + + return toBeFalsy; +}; + +getJasmineRequireObj().toBeGreaterThan = function() { + + function toBeGreaterThan() { + return { + compare: function(actual, expected) { + return { + pass: actual > expected + }; + } + }; + } + + return toBeGreaterThan; +}; + + +getJasmineRequireObj().toBeLessThan = function() { + function toBeLessThan() { + return { + + compare: function(actual, expected) { + return { + pass: actual < expected + }; + } + }; + } + + return toBeLessThan; +}; +getJasmineRequireObj().toBeNaN = function(j$) { + + function toBeNaN() { + return { + compare: function(actual) { + var result = { + pass: (actual !== actual) + }; + + if (result.pass) { + result.message = 'Expected actual not to be NaN.'; + } else { + result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be NaN.'; }; + } + + return result; + } + }; + } + + return toBeNaN; +}; + +getJasmineRequireObj().toBeNull = function() { + + function toBeNull() { + return { + compare: function(actual) { + return { + pass: actual === null + }; + } + }; + } + + return toBeNull; +}; + +getJasmineRequireObj().toBeTruthy = function() { + + function toBeTruthy() { + return { + compare: function(actual) { + return { + pass: !!actual + }; + } + }; + } + + return toBeTruthy; +}; + +getJasmineRequireObj().toBeUndefined = function() { + + function toBeUndefined() { + return { + compare: function(actual) { + return { + pass: void 0 === actual + }; + } + }; + } + + return toBeUndefined; +}; + +getJasmineRequireObj().toContain = function() { + function toContain(util, customEqualityTesters) { + customEqualityTesters = customEqualityTesters || []; + + return { + compare: function(actual, expected) { + + return { + pass: util.contains(actual, expected, customEqualityTesters) + }; + } + }; + } + + return toContain; +}; + +getJasmineRequireObj().toEqual = function() { + + function toEqual(util, customEqualityTesters) { + customEqualityTesters = customEqualityTesters || []; + + return { + compare: function(actual, expected) { + var result = { + pass: false + }; + + result.pass = util.equals(actual, expected, customEqualityTesters); + + return result; + } + }; + } + + return toEqual; +}; + +getJasmineRequireObj().toHaveBeenCalled = function(j$) { + + function toHaveBeenCalled() { + return { + compare: function(actual) { + var result = {}; + + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + if (arguments.length > 1) { + throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); + } + + result.pass = actual.calls.any(); + + result.message = result.pass ? + 'Expected spy ' + actual.and.identity() + ' not to have been called.' : + 'Expected spy ' + actual.and.identity() + ' to have been called.'; + + return result; + } + }; + } + + return toHaveBeenCalled; +}; + +getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { + + function toHaveBeenCalledWith(util, customEqualityTesters) { + return { + compare: function() { + var args = Array.prototype.slice.call(arguments, 0), + actual = args[0], + expectedArgs = args.slice(1), + result = { pass: false }; + + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + if (!actual.calls.any()) { + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but it was never called.'; }; + return result; + } + + if (util.contains(actual.calls.allArgs(), expectedArgs, customEqualityTesters)) { + result.pass = true; + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' not to have been called with ' + j$.pp(expectedArgs) + ' but it was.'; }; + } else { + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but actual calls were ' + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + '.'; }; + } + + return result; + } + }; + } + + return toHaveBeenCalledWith; +}; + +getJasmineRequireObj().toMatch = function(j$) { + + function toMatch() { + return { + compare: function(actual, expected) { + if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { + throw new Error('Expected is not a String or a RegExp'); + } + + var regexp = new RegExp(expected); + + return { + pass: regexp.test(actual) + }; + } + }; + } + + return toMatch; +}; + +getJasmineRequireObj().toThrow = function(j$) { + + function toThrow(util) { + return { + compare: function(actual, expected) { + var result = { pass: false }, + threw = false, + thrown; + + if (typeof actual != 'function') { + throw new Error('Actual is not a Function'); + } + + try { + actual(); + } catch (e) { + threw = true; + thrown = e; + } + + if (!threw) { + result.message = 'Expected function to throw an exception.'; + return result; + } + + if (arguments.length == 1) { + result.pass = true; + result.message = function() { return 'Expected function not to throw, but it threw ' + j$.pp(thrown) + '.'; }; + + return result; + } + + if (util.equals(thrown, expected)) { + result.pass = true; + result.message = function() { return 'Expected function not to throw ' + j$.pp(expected) + '.'; }; + } else { + result.message = function() { return 'Expected function to throw ' + j$.pp(expected) + ', but it threw ' + j$.pp(thrown) + '.'; }; + } + + return result; + } + }; + } + + return toThrow; +}; + +getJasmineRequireObj().toThrowError = function(j$) { + function toThrowError (util) { + return { + compare: function(actual) { + var threw = false, + pass = {pass: true}, + fail = {pass: false}, + thrown; + + if (typeof actual != 'function') { + throw new Error('Actual is not a Function'); + } + + var errorMatcher = getMatcher.apply(null, arguments); + + try { + actual(); + } catch (e) { + threw = true; + thrown = e; + } + + if (!threw) { + fail.message = 'Expected function to throw an Error.'; + return fail; + } + + if (!(thrown instanceof Error)) { + fail.message = function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; }; + return fail; + } + + if (errorMatcher.hasNoSpecifics()) { + pass.message = 'Expected function not to throw an Error, but it threw ' + j$.fnNameFor(thrown) + '.'; + return pass; + } + + if (errorMatcher.matches(thrown)) { + pass.message = function() { + return 'Expected function not to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + '.'; + }; + return pass; + } else { + fail.message = function() { + return 'Expected function to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + + ', but it threw ' + errorMatcher.thrownDescription(thrown) + '.'; + }; + return fail; + } + } + }; + + function getMatcher() { + var expected = null, + errorType = null; + + if (arguments.length == 2) { + expected = arguments[1]; + if (isAnErrorType(expected)) { + errorType = expected; + expected = null; + } + } else if (arguments.length > 2) { + errorType = arguments[1]; + expected = arguments[2]; + if (!isAnErrorType(errorType)) { + throw new Error('Expected error type is not an Error.'); + } + } + + if (expected && !isStringOrRegExp(expected)) { + if (errorType) { + throw new Error('Expected error message is not a string or RegExp.'); + } else { + throw new Error('Expected is not an Error, string, or RegExp.'); + } + } + + function messageMatch(message) { + if (typeof expected == 'string') { + return expected == message; + } else { + return expected.test(message); + } + } + + return { + errorTypeDescription: errorType ? j$.fnNameFor(errorType) : 'an exception', + thrownDescription: function(thrown) { + var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception', + thrownMessage = ''; + + if (expected) { + thrownMessage = ' with message ' + j$.pp(thrown.message); + } + + return thrownName + thrownMessage; + }, + messageDescription: function() { + if (expected === null) { + return ''; + } else if (expected instanceof RegExp) { + return ' with a message matching ' + j$.pp(expected); + } else { + return ' with message ' + j$.pp(expected); + } + }, + hasNoSpecifics: function() { + return expected === null && errorType === null; + }, + matches: function(error) { + return (errorType === null || error.constructor === errorType) && + (expected === null || messageMatch(error.message)); + } + }; + } + + function isStringOrRegExp(potential) { + return potential instanceof RegExp || (typeof potential == 'string'); + } + + function isAnErrorType(type) { + if (typeof type !== 'function') { + return false; + } + + var Surrogate = function() {}; + Surrogate.prototype = type.prototype; + return (new Surrogate()) instanceof Error; + } + } + + return toThrowError; +}; + +getJasmineRequireObj().interface = function(jasmine, env) { + var jasmineInterface = { + describe: function(description, specDefinitions) { + return env.describe(description, specDefinitions); + }, + + xdescribe: function(description, specDefinitions) { + return env.xdescribe(description, specDefinitions); + }, + + fdescribe: function(description, specDefinitions) { + return env.fdescribe(description, specDefinitions); + }, + + it: function() { + return env.it.apply(env, arguments); + }, + + xit: function() { + return env.xit.apply(env, arguments); + }, + + fit: function() { + return env.fit.apply(env, arguments); + }, + + beforeEach: function() { + return env.beforeEach.apply(env, arguments); + }, + + afterEach: function() { + return env.afterEach.apply(env, arguments); + }, + + beforeAll: function() { + return env.beforeAll.apply(env, arguments); + }, + + afterAll: function() { + return env.afterAll.apply(env, arguments); + }, + + expect: function(actual) { + return env.expect(actual); + }, + + pending: function() { + return env.pending.apply(env, arguments); + }, + + fail: function() { + return env.fail.apply(env, arguments); + }, + + spyOn: function(obj, methodName) { + return env.spyOn(obj, methodName); + }, + + jsApiReporter: new jasmine.JsApiReporter({ + timer: new jasmine.Timer() + }), + + jasmine: jasmine + }; + + jasmine.addCustomEqualityTester = function(tester) { + env.addCustomEqualityTester(tester); + }; + + jasmine.addMatchers = function(matchers) { + return env.addMatchers(matchers); + }; + + jasmine.clock = function() { + return env.clock; + }; + + return jasmineInterface; +}; + +getJasmineRequireObj().version = function() { + return '2.2.0'; +}; diff --git a/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine_favicon.png b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine_favicon.png new file mode 100755 index 0000000..3b84583 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/jasmine-2.2.0/jasmine_favicon.png differ diff --git a/platforms/android/assets/www/cdvtests/jasmine-medic.js b/platforms/android/assets/www/cdvtests/jasmine-medic.js new file mode 100644 index 0000000..4194f3a --- /dev/null +++ b/platforms/android/assets/www/cdvtests/jasmine-medic.js @@ -0,0 +1,123 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* global device */ + +jasmineRequire.medic = function(j$) { + j$.MedicReporter = jasmineRequire.MedicReporter(j$); +}; + +jasmineRequire.MedicReporter = function(j$) { + var noopTimer = { + start: function() {}, + elapsed: function() { return 0; } + }; + + var platformMap = { + 'ipod touch':'ios', + 'iphone':'ios' + }; + + function MedicReporter(options) { + var logoptions = options.log || { logurl: 'http://127.0.0.1:5984/' }, // TODO: http://localhost:6800 + timer = options.timer || noopTimer, + results = [], + specsExecuted = 0, + failureCount = 0, + pendingSpecCount = 0; + + + var serverurl = logoptions.logurl; + + this.initialize = function() { + }; + + var totalSpecsDefined; + this.jasmineStarted = function(options) { + totalSpecsDefined = options.totalSpecsDefined || 0; + timer.start(); + }; + + this.suiteStarted = function(result) { + }; + + this.suiteDone = function(result) { + + }; + + this.specStarted = function(result) { + // Start timing this spec + }; + + this.specDone = function(result) { + if (result.status != "disabled") { + specsExecuted++; + } + if (result.status == "failed") { + failureCount++; + results.push(result); + } + if (result.status == "pending") { + pendingSpecCount++; + } + }; + + var buildResults = function(){ + var json ={specs:specsExecuted, failures:failureCount, results: results}; + return json; + }; + + this.jasmineDone = function() { + var p = 'Desktop'; + var devmodel='none'; + var version = cordova.version; + if(typeof device != 'undefined') { + p = device.platform.toLowerCase(); + devmodel=device.model || device.name; + version = device.version.toLowerCase(); + } + + this.postTests({ + mobilespec:buildResults(), + platform:(platformMap.hasOwnProperty(p) ? platformMap[p] : p), + version:version, + sha: options.sha, + timestamp:Math.round(Math.floor((new Date()).getTime() / 1000)), + model:devmodel + }); + + }; + + this.postTests = function(json) { + console.log('posting tests'); + + var xhr = new XMLHttpRequest(); + var doc_id = [options.sha, json.version, json.model].map(encodeURIComponent).join('__'); + var doc_url = serverurl + '/mobilespec_results/' + doc_id; + xhr.open("PUT", doc_url, true); + xhr.setRequestHeader("Content-Type","application/json"); + xhr.send(JSON.stringify(json)); + }; + return this; + } + + return MedicReporter; +}; diff --git a/platforms/android/assets/www/cdvtests/main-bootstrap.js b/platforms/android/assets/www/cdvtests/main-bootstrap.js new file mode 100644 index 0000000..58624b7 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/main-bootstrap.js @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +document.addEventListener("deviceready", function() { + 'use strict'; + + cordova.require('cordova-plugin-test-framework.main').init(); +}); diff --git a/platforms/android/assets/www/cdvtests/main.css b/platforms/android/assets/www/cdvtests/main.css new file mode 100644 index 0000000..9223dbd --- /dev/null +++ b/platforms/android/assets/www/cdvtests/main.css @@ -0,0 +1,148 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +*, *:before, *:after { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +html, body { + height: 100%; + width: 100%; + margin: 0; + padding: 0; +} + +#title { + position: fixed; + height: 30px; + width: 100%; + top: 0; + z-index: 1000; + + background-color: #75B2F0; + font-size: 25px; + text-align: center; + font-weight: bold; + white-space: nowrap; +} + +#middle { + position: absolute; + top: 30px; + bottom: 20px; + padding-bottom: 40%; + width: 100%; + overflow-y: auto; + overflow-x: auto; +} + +#log { + position: fixed; + height: 20px; + width: 100%; + bottom: 0; + z-index: 1000; + border-top: 2px solid #777; + transition: 0.25s ease; +} + +body.expanded-log #middle { + margin-bottom: 40%; +} + +body.expanded-log #log { + height: 40%; +} + +#log--title { + position: absolute; + top: 0; + height: 20px; + width: 100%; + background-color: #93AAC2; +} + +#log--content { + position: absolute; + top: 20px; + bottom: 0; + width: 100%; + overflow-x: none; + overflow-y: auto; + background-color: white; +} + +.log--content--line { + border-bottom: 1px solid #ccc; + white-space: pre; +} + +.log--content--line--log { + background-color: white; +} + +.log--content--line--warn { + background-color: #FCFFA6; +} + +.log--content--line--error { + background-color: #FFA6A6; +} + +#info{ + background:#ffa; + border: 1px solid #ffd324; + -webkit-border-radius: 5px; + border-radius: 5px; + clear:both; + margin:15px 6px 0; + min-width:295px; + max-width:97%; + padding:4px 0px 2px 10px; + word-wrap:break-word; + margin-bottom:10px; + display:inline-block; + min-height: 160px; + max-height: 300px; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +#test-enablers-container { + margin: 10px 5px; +} + +#test-expander { + text-decoration: underline; +} + +#test-list { + display: none; +} + +#test-list.expanded { + display: inherit; +} + +#test-list label { + display: block; +} diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/.gitignore b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/.gitignore new file mode 100755 index 0000000..f678651 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/.gitignore @@ -0,0 +1,6 @@ +node_modules +npm-debug.log +tmp +.DS_Store +src/ +.tern-port diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/Gruntfile.js b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/Gruntfile.js new file mode 100755 index 0000000..1952688 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/Gruntfile.js @@ -0,0 +1,277 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/*global module:false, require:false, process:false*/ + +var path = require('path'), + os = require('os'), + chromiumSrc = process.env.CHROMIUM_SRC || ""; + + +module.exports = function(grunt) { + 'use strict'; + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + + stylus: { + options: { + paths: grunt.file.expand(__dirname + '/node_modules/topcoat-*/src/') + /* FIXME: Utils is the last needing to be moved out of mixins + * folder + */ + .concat(grunt.file.expand(__dirname + '/node_modules/topcoat-utils/src/mixins/')), + compress: false + }, + + mobilelight: { + options: { + import: ['theme-topcoat-mobile-light', 'utils'] + }, + + files: [{ + src: 'node_modules/topcoat-*/src/**/*.styl', + dest: 'css/topcoat-mobile-light.css' + }] + }, + + mobiledark: { + options: { + import: ['theme-topcoat-mobile-dark', 'utils'] + }, + + files: [{ + src: 'node_modules/topcoat-*/src/**/*.styl', + dest: 'css/topcoat-mobile-dark.css' + }] + }, + + desktoplight: { + options: { + import: ['theme-topcoat-desktop-light', 'utils'] + }, + files: [{ + src: [ + 'node_modules/topcoat-*/src/**/*.styl', + '!node_modules/topcoat-navigation-bar/src/*.styl', + '!node_modules/topcoat-list/src/*.styl' + ], + dest: 'css/topcoat-desktop-light.css' + }] + }, + + desktopdark: { + options: { + import: ['theme-topcoat-desktop-dark', 'utils'] + }, + + files: [{ + src: [ + 'node_modules/topcoat-*/src/**/*.styl', + '!node_modules/topcoat-navigation-bar/src/*.styl', + '!node_modules/topcoat-list/src/*.styl' + ], + dest: 'css/topcoat-desktop-dark.css' + }] + } + }, + + topdoc: { + usageguides: { + options: { + source: 'css', + destination: 'demo', + template: 'node_modules/topdoc-theme/', + templateData: { + "title": "Topcoat", + "subtitle": "CSS for clean and fast web apps", + "download": { + "url": "https://github.com/topcoat/topcoat/archive/v0.7.0.zip", + "label": "Download" + }, + "homeURL": "http://topcoat.io", + "siteNav": [ + { + "url": "http://topcoat.io/topcoat", + "text": "Demo" + }, + { + "url": "http://bench.topcoat.io/", + "text": "Benchmarks" + }, + { + "url": "http://topcoat.io/blog", + "text": "Blog" + } + ] + } + } + } + }, + + autoprefixer: { + dist: { + options: { + /* + * Add target browsers here + * https://github.com/ai/autoprefixer#browsers + * browsers: ['android 4'] + */ + }, + files: [{ + src: 'css/topcoat-desktop-dark.css', + dest: 'css/topcoat-desktop-dark.css' + }, + { + src: 'css/topcoat-desktop-light.css', + dest: 'css/topcoat-desktop-light.css' + }, + { + src: 'css/topcoat-mobile-dark.css', + dest: 'css/topcoat-mobile-dark.css' + }, + { + src: 'css/topcoat-mobile-light.css', + dest: 'css/topcoat-mobile-light.css' + }] + } + + }, + + cssmin: { + minify: { + expand: true, + cwd: 'css', + src: ['*.css', '!*.min.css'], + dest: 'css', + ext: '.min.css' + } + }, + + htmlmin: { + telemetry: { + options: { + removeComments: true, + collapseWhitespace: true + }, + files: [{ + expand: true, + src: ['dev/test/**/topcoat/*.html'], + dest: '', + ext: '.test.html', + }], + }, + }, + + clean: { + release: ['css'] + }, + + copy: { + release: { + files: [{ + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/font/**', + dest: 'font' + }, { + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/img/*', + dest: 'img' + }] + }, + + telemetry: { + files: [{ + expand: true, + cwd: 'dev/test/perf/telemetry/perf/', + src: ['**'], + dest: path.join(chromiumSrc, 'tools/perf/') + }, { + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/font/**', + dest: path.join(chromiumSrc, 'tools/perf/page_sets/topcoat/release/font') + }, { + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/img/*', + dest: path.join(chromiumSrc, 'tools/perf/page_sets/topcoat/release/img') + }, { + src: ['css/**'], + dest: path.join(chromiumSrc, 'tools/perf/page_sets/topcoat/release/') + }] + } + }, + + jshint: { + options: { + curly: true, + eqeqeq: true, + immed: true, + latedef: true, + newcap: true, + noarg: true, + sub: true, + undef: true, + unused: true, + boss: true, + eqnull: true, + browser: true, + globals: { + jQuery: true + } + }, + gruntfile: { + src: 'Gruntfile.js' + }, + lib_test: { + src: ['dev/lib/**/*.js', 'dev/test/**/*.js'] + } + }, + + watch: { + files: ['src/**/*.styl'], + tasks: ['compile'] + } + + }); + + // These plugins provide necessary tasks. + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-contrib-jade'); + grunt.loadNpmTasks('grunt-contrib-stylus'); + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-exec'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-topdoc'); + grunt.loadNpmTasks('grunt-contrib-cssmin'); + grunt.loadNpmTasks('grunt-contrib-htmlmin'); + grunt.loadNpmTasks('grunt-autoprefixer'); + + //Load local tasks + grunt.loadTasks('dev/tasks'); + + // Default task. + grunt.registerTask('default', ['clean', 'stylus', 'autoprefixer', 'cssmin', 'topdoc', 'copy:release']); + grunt.registerTask('release', ['default', 'clean:src']); + grunt.registerTask('compile', ['topcoat:compile', 'topdoc', 'copy:release']); + + grunt.registerTask('telemetry', '', function(platform, theme) { + if (chromiumSrc === "") grunt.fail.warn("Set CHROMIUM_SRC to point to the correct location\n"); + grunt.task.run('check_chromium_src', 'perf:'.concat(platform || 'mobile').concat(':').concat(theme || 'light'), 'htmlmin:telemetry', 'copy:telemetry'); + }); +}; diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/LICENSE b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/LICENSE new file mode 100755 index 0000000..242fd8a --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/LICENSE @@ -0,0 +1,203 @@ +Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/NOTICE b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/NOTICE new file mode 100755 index 0000000..3c8ddfa --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/NOTICE @@ -0,0 +1,193 @@ +Topcoat is licensed under the Apache license version 2.0, January 2004 (see LICENSE file). + +Topcoat uses the following third party libraries that may have licenses +differing from that of Topcoat itself. You can find the libraries and their +respective licenses below. + + - Source Code Pro ./src/font/SourceCodePro + + https://github.com/adobe/source-code-pro + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + This Font Software is licensed under the SIL Open Font License, Version 1.1. + This license is available with a FAQ at: http://scripts.sil.org/OFL + +- Source Sans Pro ./src/font/SourceSansPro + + https://github.com/adobe/source-sans-pro + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + This Font Software is licensed under the SIL Open Font License, Version 1.1. + This license is available with a FAQ at: http://scripts.sil.org/OFL + +The following frameworks and libraries are provided just for testing and benchmarking and, as provided, should not be included as part of Topcoat output. + + - Bootstrap - ./test/third-party/bootstrap + + https://github.com/twitter/bootstrap + + Copyright 2012 Twitter, Inc + Licensed under the Apache License v2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + - jQuery - ./test/third-party/jquery-1.8.2.js + + https://github.com/jquery/jquery + + Copyright 2011, John Resig + Dual licensed under the MIT or GPL Version 2 licenses. + http://jquery.org/license + + Includes Sizzle.js + http://sizzlejs.com/ + Copyright 2011, The Dojo Foundation + Released under the MIT, BSD, and GPL Licenses. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + - Modernizr - ./test/third-party/modernizr + + https://github.com/Modernizr/Modernizr + + Modernizr is available under the MIT license + + Copyright (c) 2009–2011 + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + - Benchmark.js - ./test/third-party/benchmarkjs + + https://github.com/alexanderbeletsky/benchmark-js + + Copyright 2010-2012 Mathias Bynens + Based on JSLitmus.js, copyright Robert Kieffer + Modified by John-David Dalton + Available under MIT license + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - normalize.css - ./test/third-party/normalize + + Copyright (c) Nicolas Gallagher and Jonathan Neal + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - Foundation - ./test/third-party/foundation + + Copyright (c) 2012 Mark Hayes + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - ua-parser ./test/third-party/ua-parser + + https://github.com/faisalman/ua-parser-js + + Copyright © 2012 Faisalman + Dual licensed under GPLv2 & MIT + Copyright © 2012 Faisalman + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + - HTML5 boilerplate + + https://github.com/h5bp/html5-boilerplate + + Copyright (c) HTML5 Boilerplate + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - classList - ./test/third-party/classlist + + http://purl.eligrey.com/github/classList.js/blob/master/classList.js + + This software is dedicated to the public domain. No warranty is expressed or implied. + Use this software at your own risk. + + - fastclick - ./test/third-party/fastclick + + https://github.com/ftlabs/fastclick + + Copyright (C) 2012 The Financial Times Ltd. + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/README.md b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/README.md new file mode 100755 index 0000000..a89dad2 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/README.md @@ -0,0 +1,89 @@ +# Topcoat + +CSS for clean and fast web apps + +--- + +## Usage + +* [Download Topcoat](https://github.com/topcoat/topcoat/archive/0.7.0.zip) + +* Open index.html to view the usage guides. +* Copy your desired theme CSS from the `css/` folder into your project +* Copy the `img/` and `font/` folders into your project ( Feel free to only + copy the images and font weights you intend to use ) +* Link the CSS into your page + +```css + +``` + +_*Alternatively incorporate the css into your build process if you are so +inclined._ + +--- + +## Contributing + +Start by checking out our [Backlog](http://huboard.com/topcoat/topcoat/backlog). (Pls file issues against this repo.) + +* [Fill out the CLA here](http://topcoat.io/dev/topcoat-cla.html) +* [fork](https://help.github.com/articles/fork-a-repo) the repo +* Create a branch + + git checkout -b my_branch + +* Add your changes following the [coding guidelines](https://github.com/topcoat/topcoat/wiki/Coding-Guidelines) +* Commit your changes + + git commit -am "Added some awesome stuff" + +* Push your branch + + git push origin my_branch + +* make a [pull request](https://help.github.com/articles/using-pull-requests) + +For the details see our [Engineering Practices](https://github.com/topcoat/topcoat/wiki/Engineering-Practices). + +### Testing + +For performance tests, see [dev/test/perf/telemetry/](https://github.com/topcoat/topcoat/tree/master/dev/test/perf/telemetry). + +### Building + +Topcoat uses [Grunt](http://gruntjs.com/) to build + +* Open the terminal from the topcoat directory + + cd topcoat + +* Install [npm](http://nodejs.org/download/) +_*comes packaged with node._ +* Install its command line interface (CLI) globally + + npm install -g grunt-cli + +* Install dependencies with npm + + npm install + + +_*Topcoat uses Grunt 0.4.0. You might want to [read](http://gruntjs.com/getting-started) more on their website if you haven't upgraded since a lot has changed._ + +* Type `grunt` in the command line to build the css. +* The results will be built into the release folder. +* Alternatively type `grunt watch` to have the build run automatically when you make changes to +source files. + +--- + +## Release notes +See [Release Notes](https://github.com/topcoat/topcoat/releases/). + +--- + +## License + +[Apache license](https://raw.github.com/topcoat/topcoat/master/LICENSE) + diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/contributors.txt b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/contributors.txt new file mode 100755 index 0000000..e4cd8b7 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/contributors.txt @@ -0,0 +1,7 @@ +# Github accounts of the people who signed the TopCoat CLA (http://topcoat.io/dev/topcoat-cla.html). +# CLA needs to be signed before accepting pull requests. +@yourpalsonja +@noformnocontent +@jrowny +@aparticulate +@jlembeck diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.css new file mode 100755 index 0000000..e590e11 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.css @@ -0,0 +1,3450 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
+
+ +
+
+ +
+
+ +
+
+ examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
+
+ +
+
+ +
+
+ +
+
+ tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
+
+ + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 1rem; +} + +input[type="checkbox"] { + height: 1rem; + width: 1rem; + margin-top: 0; + margin-right: -1rem; + margin-bottom: -1rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 1rem; +} + +.topcoat-checkbox__checkmark:before { + width: 1rem; + height: 1rem; + background: #595b5b; + border: 1px solid #303233; + border-radius: 3px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-checkbox__checkmark { + width: 1rem; + height: 1rem; +} + +.topcoat-checkbox__checkmark:after { + top: 2px; + left: 1px; + opacity: 0; + width: 14px; + height: 4px; + background: transparent; + border: 7px solid #fff; + border-width: 3px; + border-top: none; + border-right: none; + border-radius: 1px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.25rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: baseline; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 4px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-icon-button:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 1.688rem; + height: 1.688rem; + line-height: 1.688rem; +} + +.topcoat-icon-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 0.81406rem; + height: 0.81406rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 1.06344rem; + height: 1.06344rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
+
+ + +
+
+ + +
+
+ + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.063rem; + width: 1.063rem; + margin-top: 0; + margin-right: -1.063rem; + margin-bottom: -1.063rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #c6c8c8; + line-height: 1.063rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.063rem; + height: 1.063rem; + background: #595b5b; + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.063rem; + height: 1.063rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.313rem; + height: 0.313rem; + background: #fff; + border: 1px solid rgba(255,255,255,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 0.313rem; + left: 0.313rem; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 4px; + border: 1px solid #303233; + background-color: #424546; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-moz-range-track { + border-radius: 4px; + border: 1px solid #303233; + background-color: #424546; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 4px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range::-moz-range-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 4px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 1.313rem; + font-size: 12px; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + padding: 0 0 0 1.3rem; + border-radius: 15px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 12px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 1.688rem; + font-size: 0.875rem; + font-weight: 400; + padding: 0 0 0 1.8rem; + border-radius: 25px; + background-position: 1.2em center; + background-size: 0.875rem; +} + +.topcoat-search-input--large:disabled { + color: #fff; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
+
+ +
+
+ + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 12px; + padding: 0 0.563rem; + border-radius: 4px; + border: 1px solid #303233; + overflow: hidden; + width: 3.5rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 2.6rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #5dc1ff; + background-color: #404141; + right: 0.8rem; + padding-left: 0.75rem; +} + +.topcoat-switch__toggle { + line-height: 1.313rem; + height: 1.313rem; + width: 1rem; + border-radius: 4px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #595b5b; + border: 1px solid #303233; + margin-left: -0.6rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #727373; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #404141; + left: 0.8rem; + padding-left: 0.6rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 1.85rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
+ + + +
+ examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 0.563rem; + height: 1.313rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border-top: 1px solid #303233; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #5dc1ff; + background-color: #404141; + box-shadow: inset 0 0 2px #313231; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
+
+ +
+
+ + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 1.313rem; + font-size: 12px; + letter-spacing: 0; + padding: 0 0.563rem; + border: 1px solid #303233; + border-radius: 4px; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
+
+ +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 1.688rem; + font-size: 0.875rem; +} + +.topcoat-text-input--large:disabled { + color: #fff; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 1rem; + font-size: 1rem; + font-weight: 400; + border-radius: 4px; + line-height: 1.313rem; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + letter-spacing: 0; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 1.3rem; + line-height: 1.688rem; +} + +.topcoat-textarea--large:disabled { + color: #fff; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #fff; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #4b4d4e; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_light.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.min.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.min.css new file mode 100755 index 0000000..1623395 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:4px;border-bottom-left-radius:4px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:4px;border-bottom-right-radius:4px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:1rem}input[type=checkbox]{height:1rem;width:1rem;margin-top:0;margin-right:-1rem;margin-bottom:-1rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:1rem}.topcoat-checkbox__checkmark:before{width:1rem;height:1rem;background:#595b5b;border:1px solid #303233;border-radius:3px;box-shadow:inset 0 1px #727373}.topcoat-checkbox__checkmark{width:1rem;height:1rem}.topcoat-checkbox__checkmark:after{top:2px;left:1px;opacity:0;width:14px;height:4px;background:transparent;border:7px solid #fff;border-width:3px;border-top:0;border-right:0;border-radius:1px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .25rem;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:baseline;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:4px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#646666}.topcoat-icon-button:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:1.688rem;height:1.688rem;line-height:1.688rem}.topcoat-icon-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:.81406rem;height:.81406rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:1.06344rem;height:1.06344rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.063rem;width:1.063rem;margin-top:0;margin-right:-1.063rem;margin-bottom:-1.063rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#c6c8c8;line-height:1.063rem}.topcoat-radio-button__checkmark:before{width:1.063rem;height:1.063rem;background:#595b5b;border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-radio-button__checkmark{position:relative;width:1.063rem;height:1.063rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.313rem;height:.313rem;background:#fff;border:1px solid rgba(255,255,255,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:.313rem;left:.313rem}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:4px;border:1px solid #303233;background-color:#424546;height:.5rem;border-radius:15px}.topcoat-range::-moz-range-track{border-radius:4px;border:1px solid #303233;background-color:#424546;height:.5rem;border-radius:15px}.topcoat-range::-webkit-slider-thumb{height:1.313rem;width:.75rem;background-color:#595b5b;border:1px solid #303233;border-radius:4px;box-shadow:inset 0 1px #727373}.topcoat-range::-moz-range-thumb{height:1.313rem;width:.75rem;background-color:#595b5b;border:1px solid #303233;border-radius:4px;box-shadow:inset 0 1px #727373}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:1.313rem;font-size:12px;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;padding:0 0 0 1.3rem;border-radius:15px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:12px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input:disabled::-moz-placeholder{color:#fff}.topcoat-search-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-search-input--large{line-height:1.688rem;font-size:.875rem;font-weight:400;padding:0 0 0 1.8rem;border-radius:25px;background-position:1.2em center;background-size:.875rem}.topcoat-search-input--large:disabled{color:#fff}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#fff}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:12px;padding:0 .563rem;border-radius:4px;border:1px solid #303233;overflow:hidden;width:3.5rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:2.6rem}.topcoat-switch__toggle:before{content:'ON';color:#5dc1ff;background-color:#404141;right:.8rem;padding-left:.75rem}.topcoat-switch__toggle{line-height:1.313rem;height:1.313rem;width:1rem;border-radius:4px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#595b5b;border:1px solid #303233;margin-left:-.6rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #727373;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#404141;left:.8rem;padding-left:.6rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:1.85rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 .563rem;height:1.313rem;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border-top:1px solid #303233}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#5dc1ff;background-color:#404141;box-shadow:inset 0 0 2px #313231}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:1.313rem;font-size:12px;letter-spacing:0;padding:0 .563rem;border:1px solid #303233;border-radius:4px;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input:disabled::-moz-placeholder{color:#fff}.topcoat-text-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:1.688rem;font-size:.875rem}.topcoat-text-input--large:disabled{color:#fff}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:1rem;font-size:1rem;font-weight:400;border-radius:4px;line-height:1.313rem;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;letter-spacing:0}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea:disabled::-moz-placeholder{color:#fff}.topcoat-textarea:disabled:-ms-input-placeholder{color:#fff}.topcoat-textarea--large{font-size:1.3rem;line-height:1.688rem}.topcoat-textarea--large:disabled{color:#fff}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea--large:disabled::-moz-placeholder{color:#fff}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#fff}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#4b4d4e;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_light.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.css new file mode 100755 index 0000000..0da42ea --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.css @@ -0,0 +1,3450 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
+
+ +
+
+ +
+
+ +
+
+ examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
+
+ +
+
+ +
+
+ +
+
+ tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
+
+ + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 1rem; +} + +input[type="checkbox"] { + height: 1rem; + width: 1rem; + margin-top: 0; + margin-right: -1rem; + margin-bottom: -1rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 1rem; +} + +.topcoat-checkbox__checkmark:before { + width: 1rem; + height: 1rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 3px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-checkbox__checkmark { + width: 1rem; + height: 1rem; +} + +.topcoat-checkbox__checkmark:after { + top: 2px; + left: 1px; + opacity: 0; + width: 14px; + height: 4px; + background: transparent; + border: 7px solid #666; + border-width: 3px; + border-top: none; + border-right: none; + border-radius: 1px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.25rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: baseline; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 4px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-icon-button:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 1.688rem; + height: 1.688rem; + line-height: 1.688rem; +} + +.topcoat-icon-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 0.81406rem; + height: 0.81406rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 1.06344rem; + height: 1.06344rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
+
+ + +
+
+ + +
+
+ + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.063rem; + width: 1.063rem; + margin-top: 0; + margin-right: -1.063rem; + margin-bottom: -1.063rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #454545; + line-height: 1.063rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.063rem; + height: 1.063rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.063rem; + height: 1.063rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.313rem; + height: 0.313rem; + background: #666; + border: 1px solid rgba(0,0,0,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 0.313rem; + left: 0.313rem; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 4px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-moz-range-track { + border-radius: 4px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 4px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range::-moz-range-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 4px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 1.313rem; + font-size: 12px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + padding: 0 0 0 1.3rem; + border-radius: 15px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 12px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 1.688rem; + font-size: 0.875rem; + font-weight: 400; + padding: 0 0 0 1.8rem; + border-radius: 25px; + background-position: 1.2em center; + background-size: 0.875rem; +} + +.topcoat-search-input--large:disabled { + color: #000; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
+
+ +
+
+ + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 12px; + padding: 0 0.563rem; + border-radius: 4px; + border: 1px solid #a5a8a8; + overflow: hidden; + width: 3.5rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 2.6rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #0083e8; + background-color: #e0f0fa; + right: 0.8rem; + padding-left: 0.75rem; +} + +.topcoat-switch__toggle { + line-height: 1.313rem; + height: 1.313rem; + width: 1rem; + border-radius: 4px; + color: #454545; + text-shadow: 0 1px #fff; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + margin-left: -0.6rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #fff; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #d3d7d7; + left: 0.8rem; + padding-left: 0.6rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 1.85rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
+ + + +
+ examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 0.563rem; + height: 1.313rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border-top: 1px solid #a5a8a8; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #0083e8; + background-color: #e0f0fa; + box-shadow: inset 0 0 2px #c0ced8; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
+
+ +
+
+ + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 1.313rem; + font-size: 12px; + letter-spacing: 0; + padding: 0 0.563rem; + border: 1px solid #a5a8a8; + border-radius: 4px; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
+
+ +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 1.688rem; + font-size: 0.875rem; +} + +.topcoat-text-input--large:disabled { + color: #000; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 1rem; + font-size: 1rem; + font-weight: 400; + border-radius: 4px; + line-height: 1.313rem; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + letter-spacing: 0; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 1.3rem; + line-height: 1.688rem; +} + +.topcoat-textarea--large:disabled { + color: #000; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #000; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #dfe2e2; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_dark.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.min.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.min.css new file mode 100755 index 0000000..e682662 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:4px;border-bottom-left-radius:4px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:4px;border-bottom-right-radius:4px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:1rem}input[type=checkbox]{height:1rem;width:1rem;margin-top:0;margin-right:-1rem;margin-bottom:-1rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:1rem}.topcoat-checkbox__checkmark:before{width:1rem;height:1rem;background:#e5e9e8;border:1px solid #a5a8a8;border-radius:3px;box-shadow:inset 0 1px #fff}.topcoat-checkbox__checkmark{width:1rem;height:1rem}.topcoat-checkbox__checkmark:after{top:2px;left:1px;opacity:0;width:14px;height:4px;background:transparent;border:7px solid #666;border-width:3px;border-top:0;border-right:0;border-radius:1px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .25rem;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:baseline;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:4px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#edf1f1}.topcoat-icon-button:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:1.688rem;height:1.688rem;line-height:1.688rem}.topcoat-icon-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:.81406rem;height:.81406rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:1.06344rem;height:1.06344rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.063rem;width:1.063rem;margin-top:0;margin-right:-1.063rem;margin-bottom:-1.063rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#454545;line-height:1.063rem}.topcoat-radio-button__checkmark:before{width:1.063rem;height:1.063rem;background:#e5e9e8;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-radio-button__checkmark{position:relative;width:1.063rem;height:1.063rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.313rem;height:.313rem;background:#666;border:1px solid rgba(0,0,0,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:.313rem;left:.313rem}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:4px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:.5rem;border-radius:15px}.topcoat-range::-moz-range-track{border-radius:4px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:.5rem;border-radius:15px}.topcoat-range::-webkit-slider-thumb{height:1.313rem;width:.75rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:4px;box-shadow:inset 0 1px #fff}.topcoat-range::-moz-range-thumb{height:1.313rem;width:.75rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:4px;box-shadow:inset 0 1px #fff}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:1.313rem;font-size:12px;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;padding:0 0 0 1.3rem;border-radius:15px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:12px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input:disabled::-moz-placeholder{color:#000}.topcoat-search-input:disabled:-ms-input-placeholder{color:#000}.topcoat-search-input--large{line-height:1.688rem;font-size:.875rem;font-weight:400;padding:0 0 0 1.8rem;border-radius:25px;background-position:1.2em center;background-size:.875rem}.topcoat-search-input--large:disabled{color:#000}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input--large:disabled::-moz-placeholder{color:#000}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#000}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:12px;padding:0 .563rem;border-radius:4px;border:1px solid #a5a8a8;overflow:hidden;width:3.5rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:2.6rem}.topcoat-switch__toggle:before{content:'ON';color:#0083e8;background-color:#e0f0fa;right:.8rem;padding-left:.75rem}.topcoat-switch__toggle{line-height:1.313rem;height:1.313rem;width:1rem;border-radius:4px;color:#454545;text-shadow:0 1px #fff;background-color:#e5e9e8;border:1px solid #a5a8a8;margin-left:-.6rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #fff;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#d3d7d7;left:.8rem;padding-left:.6rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:1.85rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 .563rem;height:1.313rem;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border-top:1px solid #a5a8a8}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#0083e8;background-color:#e0f0fa;box-shadow:inset 0 0 2px #c0ced8}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:1.313rem;font-size:12px;letter-spacing:0;padding:0 .563rem;border:1px solid #a5a8a8;border-radius:4px;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input:disabled::-moz-placeholder{color:#000}.topcoat-text-input:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:1.688rem;font-size:.875rem}.topcoat-text-input--large:disabled{color:#000}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input--large:disabled::-moz-placeholder{color:#000}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:1rem;font-size:1rem;font-weight:400;border-radius:4px;line-height:1.313rem;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;letter-spacing:0}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea:disabled::-moz-placeholder{color:#000}.topcoat-textarea:disabled:-ms-input-placeholder{color:#000}.topcoat-textarea--large{font-size:1.3rem;line-height:1.688rem}.topcoat-textarea--large:disabled{color:#000}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea--large:disabled::-moz-placeholder{color:#000}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#000}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#dfe2e2;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_dark.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.css new file mode 100755 index 0000000..0d3aa5f --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.css @@ -0,0 +1,3700 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
+
+ +
+
+ +
+
+ +
+
+ examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
+
+ +
+
+ +
+
+ +
+
+ tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
+
+ + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 2rem; +} + +input[type="checkbox"] { + height: 2rem; + width: 2rem; + margin-top: 0; + margin-right: -2rem; + margin-bottom: -2rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 2rem; +} + +.topcoat-checkbox__checkmark:before { + width: 2rem; + height: 2rem; + background: #595b5b; + border: 1px solid #303233; + border-radius: 3px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-checkbox__checkmark { + width: 2rem; + height: 2rem; +} + +.topcoat-checkbox__checkmark:after { + top: 1px; + left: 2px; + opacity: 0; + width: 28px; + height: 11px; + background: transparent; + border: 7px solid #fff; + border-width: 7px; + border-top: none; + border-right: none; + border-radius: 2px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.75rem; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: baseline; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 6px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-icon-button:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 4.375rem; + height: 4.375rem; + line-height: 4.375rem; +} + +.topcoat-icon-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 1.62rem; + height: 1.62rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 2.499999998125rem; + height: 2.499999998125rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list, +.topcoat-list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header, +.topcoat-list__header { + margin: 0; +} + +.list__container, +.topcoat-list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item, +.topcoat-list__item { + margin: 0; + padding: 0; +} + +/* topdoc + name: List + description: Topcoat default list skin + markup: +
+

Category

+
    +
  • + Item +
  • +
  • + Item +
  • +
  • + Item +
  • +
+
+ tags: + - mobile + - list +*/ + +.topcoat-list { + border-top: 1px solid #2f3234; + border-bottom: 1px solid #5e6061; + background-color: #444849; +} + +.topcoat-list__header { + padding: 4px 20px; + font-size: 0.9em; + font-weight: 400; + background-color: #3b3e40; + color: #868888; + text-shadow: 0 -1px 0 rgba(0,0,0,0.3); + border-top: solid 1px rgba(255,255,255,0.1); + border-bottom: solid 1px rgba(255,255,255,0.05); +} + +.topcoat-list__container { + border-top: 1px solid #2f3234; + color: #c6c8c8; +} + +.topcoat-list__item { + padding: 1.25rem; + border-top: 1px solid #5e6061; + border-bottom: 1px solid #2f3234; +} + +.topcoat-list__item:first-child { + border-top: 1px solid rgba(0,0,0,0.05); +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar, +.topcoat-navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item, +.topcoat-navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title, +.topcoat-navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* topdoc + name: Navigation Bar + description: A place where navigation goes to drink + markup: +
+
+

Header

+
+
+ tags: + - desktop + - light + - mobile + - navigation + - bar +*/ + +.topcoat-navigation-bar { + height: 4.375rem; + padding-left: 1rem; + padding-right: 1rem; + background: #595b5b; + color: #fff; + box-shadow: inset 0 -1px #333434, 0 1px rgba(0,0,0,0.15); +} + +.topcoat-navigation-bar__item { + margin: 0; + line-height: 4.375rem; + vertical-align: top; +} + +.topcoat-navigation-bar__title { + font-size: 1.3rem; + font-weight: 400; + color: #fff; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
+
+ + +
+
+ + +
+
+ + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.875rem; + width: 1.875rem; + margin-top: 0; + margin-right: -1.875rem; + margin-bottom: -1.875rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #c6c8c8; + line-height: 1.875rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.875rem; + height: 1.875rem; + background: #595b5b; + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.875rem; + height: 1.875rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.875rem; + height: 0.875rem; + background: #fff; + border: 1px solid rgba(255,255,255,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 7px; + left: 7px; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 6px; + border: 1px solid #303233; + background-color: #424546; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-moz-range-track { + border-radius: 6px; + border: 1px solid #303233; + background-color: #424546; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 3rem; + width: 2rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 6px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range::-moz-range-thumb { + height: 3rem; + width: 2rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 6px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 3rem; + font-size: 16px; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + padding: 0 0 0 2rem; + border-radius: 30px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 16px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 4.375rem; + font-size: 1.3rem; + font-weight: 200; + padding: 0 0 0 2.9rem; + border-radius: 40px; + background-position: 1.2em center; + background-size: 1.3rem; +} + +.topcoat-search-input--large:disabled { + color: #fff; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
+
+ +
+
+ + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 16px; + padding: 0 1.25rem; + border-radius: 6px; + border: 1px solid #303233; + overflow: hidden; + width: 6rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 5rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #5dc1ff; + background-color: #404141; + right: 1rem; + padding-left: 1.5rem; +} + +.topcoat-switch__toggle { + line-height: 3rem; + height: 3rem; + width: 2rem; + border-radius: 6px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #595b5b; + border: 1px solid #303233; + margin-left: -1.3rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #727373; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #404141; + left: 1rem; + padding-left: 2rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 2.7rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
+ + + +
+ examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 1.25rem; + height: 3rem; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border-top: 1px solid #303233; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #5dc1ff; + background-color: #404141; + box-shadow: inset 0 0 2px #313231; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
+
+ +
+
+ + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 3rem; + font-size: 16px; + letter-spacing: 1px; + padding: 0 1.25rem; + border: 1px solid #303233; + border-radius: 6px; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
+
+ +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 4.375rem; + font-size: 1.3rem; +} + +.topcoat-text-input--large:disabled { + color: #fff; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 2rem; + font-size: 2.5rem; + font-weight: 200; + border-radius: 6px; + line-height: 3rem; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + letter-spacing: 1px; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 3rem; + line-height: 4.375rem; +} + +.topcoat-textarea--large:disabled { + color: #fff; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #fff; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #4b4d4e; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_light.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.min.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.min.css new file mode 100755 index 0000000..2ce6f11 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:6px;border-bottom-left-radius:6px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:6px;border-bottom-right-radius:6px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:2rem}input[type=checkbox]{height:2rem;width:2rem;margin-top:0;margin-right:-2rem;margin-bottom:-2rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:2rem}.topcoat-checkbox__checkmark:before{width:2rem;height:2rem;background:#595b5b;border:1px solid #303233;border-radius:3px;box-shadow:inset 0 1px #727373}.topcoat-checkbox__checkmark{width:2rem;height:2rem}.topcoat-checkbox__checkmark:after{top:1px;left:2px;opacity:0;width:28px;height:11px;background:transparent;border:7px solid #fff;border-width:7px;border-top:0;border-right:0;border-radius:2px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .75rem;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:baseline;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:6px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#646666}.topcoat-icon-button:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:4.375rem;height:4.375rem;line-height:4.375rem}.topcoat-icon-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:1.62rem;height:1.62rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:2.499999998125rem;height:2.499999998125rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.list,.topcoat-list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header,.topcoat-list__header{margin:0}.list__container,.topcoat-list__container{padding:0;margin:0;list-style-type:none}.list__item,.topcoat-list__item{margin:0;padding:0}.topcoat-list{border-top:1px solid #2f3234;border-bottom:1px solid #5e6061;background-color:#444849}.topcoat-list__header{padding:4px 20px;font-size:.9em;font-weight:400;background-color:#3b3e40;color:#868888;text-shadow:0 -1px 0 rgba(0,0,0,.3);border-top:solid 1px rgba(255,255,255,.1);border-bottom:solid 1px rgba(255,255,255,.05)}.topcoat-list__container{border-top:1px solid #2f3234;color:#c6c8c8}.topcoat-list__item{padding:1.25rem;border-top:1px solid #5e6061;border-bottom:1px solid #2f3234}.topcoat-list__item:first-child{border-top:1px solid rgba(0,0,0,.05)}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.navigation-bar,.topcoat-navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item,.topcoat-navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title,.topcoat-navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.topcoat-navigation-bar{height:4.375rem;padding-left:1rem;padding-right:1rem;background:#595b5b;color:#fff;box-shadow:inset 0 -1px #333434,0 1px rgba(0,0,0,.15)}.topcoat-navigation-bar__item{margin:0;line-height:4.375rem;vertical-align:top}.topcoat-navigation-bar__title{font-size:1.3rem;font-weight:400;color:#fff}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.875rem;width:1.875rem;margin-top:0;margin-right:-1.875rem;margin-bottom:-1.875rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#c6c8c8;line-height:1.875rem}.topcoat-radio-button__checkmark:before{width:1.875rem;height:1.875rem;background:#595b5b;border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-radio-button__checkmark{position:relative;width:1.875rem;height:1.875rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.875rem;height:.875rem;background:#fff;border:1px solid rgba(255,255,255,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:7px;left:7px}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:6px;border:1px solid #303233;background-color:#424546;height:1rem;border-radius:30px}.topcoat-range::-moz-range-track{border-radius:6px;border:1px solid #303233;background-color:#424546;height:1rem;border-radius:30px}.topcoat-range::-webkit-slider-thumb{height:3rem;width:2rem;background-color:#595b5b;border:1px solid #303233;border-radius:6px;box-shadow:inset 0 1px #727373}.topcoat-range::-moz-range-thumb{height:3rem;width:2rem;background-color:#595b5b;border:1px solid #303233;border-radius:6px;box-shadow:inset 0 1px #727373}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:3rem;font-size:16px;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;padding:0 0 0 2rem;border-radius:30px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:16px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input:disabled::-moz-placeholder{color:#fff}.topcoat-search-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-search-input--large{line-height:4.375rem;font-size:1.3rem;font-weight:200;padding:0 0 0 2.9rem;border-radius:40px;background-position:1.2em center;background-size:1.3rem}.topcoat-search-input--large:disabled{color:#fff}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#fff}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:16px;padding:0 1.25rem;border-radius:6px;border:1px solid #303233;overflow:hidden;width:6rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:5rem}.topcoat-switch__toggle:before{content:'ON';color:#5dc1ff;background-color:#404141;right:1rem;padding-left:1.5rem}.topcoat-switch__toggle{line-height:3rem;height:3rem;width:2rem;border-radius:6px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#595b5b;border:1px solid #303233;margin-left:-1.3rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #727373;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#404141;left:1rem;padding-left:2rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:2.7rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 1.25rem;height:3rem;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border-top:1px solid #303233}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#5dc1ff;background-color:#404141;box-shadow:inset 0 0 2px #313231}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:3rem;font-size:16px;letter-spacing:1px;padding:0 1.25rem;border:1px solid #303233;border-radius:6px;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input:disabled::-moz-placeholder{color:#fff}.topcoat-text-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:4.375rem;font-size:1.3rem}.topcoat-text-input--large:disabled{color:#fff}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:2rem;font-size:2.5rem;font-weight:200;border-radius:6px;line-height:3rem;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;letter-spacing:1px}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea:disabled::-moz-placeholder{color:#fff}.topcoat-textarea:disabled:-ms-input-placeholder{color:#fff}.topcoat-textarea--large{font-size:3rem;line-height:4.375rem}.topcoat-textarea--large:disabled{color:#fff}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea--large:disabled::-moz-placeholder{color:#fff}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#fff}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#4b4d4e;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_light.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.css new file mode 100755 index 0000000..6735055 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.css @@ -0,0 +1,3700 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
+
+ +
+
+ +
+
+ +
+
+ examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
+
+ +
+
+ +
+
+ +
+
+ tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
+
+ + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 2rem; +} + +input[type="checkbox"] { + height: 2rem; + width: 2rem; + margin-top: 0; + margin-right: -2rem; + margin-bottom: -2rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 2rem; +} + +.topcoat-checkbox__checkmark:before { + width: 2rem; + height: 2rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 3px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-checkbox__checkmark { + width: 2rem; + height: 2rem; +} + +.topcoat-checkbox__checkmark:after { + top: 1px; + left: 2px; + opacity: 0; + width: 28px; + height: 11px; + background: transparent; + border: 7px solid #666; + border-width: 7px; + border-top: none; + border-right: none; + border-radius: 2px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.75rem; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: baseline; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 6px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-icon-button:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 4.375rem; + height: 4.375rem; + line-height: 4.375rem; +} + +.topcoat-icon-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 1.62rem; + height: 1.62rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 2.499999998125rem; + height: 2.499999998125rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list, +.topcoat-list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header, +.topcoat-list__header { + margin: 0; +} + +.list__container, +.topcoat-list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item, +.topcoat-list__item { + margin: 0; + padding: 0; +} + +/* topdoc + name: List + description: Topcoat default list skin + markup: +
+

Category

+
    +
  • + Item +
  • +
  • + Item +
  • +
  • + Item +
  • +
+
+ tags: + - mobile + - list +*/ + +.topcoat-list { + border-top: 1px solid #bcbfbf; + border-bottom: 1px solid #eff1f1; + background-color: #dfe2e2; +} + +.topcoat-list__header { + padding: 4px 20px; + font-size: 0.9em; + font-weight: 400; + background-color: #cccfcf; + color: #656565; + text-shadow: 0 1px 0 rgba(255,255,255,0.5); + border-top: 1px solid rgba(255,255,255,0.5); + border-bottom: 1px solid rgba(255,255,255,0.23); +} + +.topcoat-list__container { + border-top: 1px solid #bcbfbf; + color: #454545; +} + +.topcoat-list__item { + padding: 1.25rem; + border-top: 1px solid #eff1f1; + border-bottom: 1px solid #bcbfbf; +} + +.topcoat-list__item:first-child { + border-top: 1px solid rgba(0,0,0,0.05); +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar, +.topcoat-navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item, +.topcoat-navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title, +.topcoat-navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* topdoc + name: Navigation Bar + description: A place where navigation goes to drink + markup: +
+
+

Header

+
+
+ tags: + - desktop + - light + - mobile + - navigation + - bar +*/ + +.topcoat-navigation-bar { + height: 4.375rem; + padding-left: 1rem; + padding-right: 1rem; + background: #e5e9e8; + color: #000; + box-shadow: inset 0 -1px #b9bcbc, 0 1px #d4d6d6; +} + +.topcoat-navigation-bar__item { + margin: 0; + line-height: 4.375rem; + vertical-align: top; +} + +.topcoat-navigation-bar__title { + font-size: 1.3rem; + font-weight: 400; + color: #000; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
+
+ + +
+
+ + +
+
+ + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.875rem; + width: 1.875rem; + margin-top: 0; + margin-right: -1.875rem; + margin-bottom: -1.875rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #454545; + line-height: 1.875rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.875rem; + height: 1.875rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.875rem; + height: 1.875rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.875rem; + height: 0.875rem; + background: #666; + border: 1px solid rgba(0,0,0,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 7px; + left: 7px; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 6px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-moz-range-track { + border-radius: 6px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 3rem; + width: 2rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 6px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range::-moz-range-thumb { + height: 3rem; + width: 2rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 6px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 3rem; + font-size: 16px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + padding: 0 0 0 2rem; + border-radius: 30px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 16px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 4.375rem; + font-size: 1.3rem; + font-weight: 200; + padding: 0 0 0 2.9rem; + border-radius: 40px; + background-position: 1.2em center; + background-size: 1.3rem; +} + +.topcoat-search-input--large:disabled { + color: #000; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
+
+ +
+
+ + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 16px; + padding: 0 1.25rem; + border-radius: 6px; + border: 1px solid #a5a8a8; + overflow: hidden; + width: 6rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 5rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #0083e8; + background-color: #e0f0fa; + right: 1rem; + padding-left: 1.5rem; +} + +.topcoat-switch__toggle { + line-height: 3rem; + height: 3rem; + width: 2rem; + border-radius: 6px; + color: #454545; + text-shadow: 0 1px #fff; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + margin-left: -1.3rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #fff; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #d3d7d7; + left: 1rem; + padding-left: 2rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 2.7rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
+ + + +
+ examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 1.25rem; + height: 3rem; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border-top: 1px solid #a5a8a8; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #0083e8; + background-color: #e0f0fa; + box-shadow: inset 0 0 2px #c0ced8; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
+
+ +
+
+ + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 3rem; + font-size: 16px; + letter-spacing: 1px; + padding: 0 1.25rem; + border: 1px solid #a5a8a8; + border-radius: 6px; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
+
+ +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 4.375rem; + font-size: 1.3rem; +} + +.topcoat-text-input--large:disabled { + color: #000; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 2rem; + font-size: 2.5rem; + font-weight: 200; + border-radius: 6px; + line-height: 3rem; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + letter-spacing: 1px; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
+
+ + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 3rem; + line-height: 4.375rem; +} + +.topcoat-textarea--large:disabled { + color: #000; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #000; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #dfe2e2; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_dark.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.min.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.min.css new file mode 100755 index 0000000..7692377 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:6px;border-bottom-left-radius:6px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:6px;border-bottom-right-radius:6px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:2rem}input[type=checkbox]{height:2rem;width:2rem;margin-top:0;margin-right:-2rem;margin-bottom:-2rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:2rem}.topcoat-checkbox__checkmark:before{width:2rem;height:2rem;background:#e5e9e8;border:1px solid #a5a8a8;border-radius:3px;box-shadow:inset 0 1px #fff}.topcoat-checkbox__checkmark{width:2rem;height:2rem}.topcoat-checkbox__checkmark:after{top:1px;left:2px;opacity:0;width:28px;height:11px;background:transparent;border:7px solid #666;border-width:7px;border-top:0;border-right:0;border-radius:2px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .75rem;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:baseline;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:6px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#edf1f1}.topcoat-icon-button:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:4.375rem;height:4.375rem;line-height:4.375rem}.topcoat-icon-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:1.62rem;height:1.62rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:2.499999998125rem;height:2.499999998125rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.list,.topcoat-list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header,.topcoat-list__header{margin:0}.list__container,.topcoat-list__container{padding:0;margin:0;list-style-type:none}.list__item,.topcoat-list__item{margin:0;padding:0}.topcoat-list{border-top:1px solid #bcbfbf;border-bottom:1px solid #eff1f1;background-color:#dfe2e2}.topcoat-list__header{padding:4px 20px;font-size:.9em;font-weight:400;background-color:#cccfcf;color:#656565;text-shadow:0 1px 0 rgba(255,255,255,.5);border-top:1px solid rgba(255,255,255,.5);border-bottom:1px solid rgba(255,255,255,.23)}.topcoat-list__container{border-top:1px solid #bcbfbf;color:#454545}.topcoat-list__item{padding:1.25rem;border-top:1px solid #eff1f1;border-bottom:1px solid #bcbfbf}.topcoat-list__item:first-child{border-top:1px solid rgba(0,0,0,.05)}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.navigation-bar,.topcoat-navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item,.topcoat-navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title,.topcoat-navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.topcoat-navigation-bar{height:4.375rem;padding-left:1rem;padding-right:1rem;background:#e5e9e8;color:#000;box-shadow:inset 0 -1px #b9bcbc,0 1px #d4d6d6}.topcoat-navigation-bar__item{margin:0;line-height:4.375rem;vertical-align:top}.topcoat-navigation-bar__title{font-size:1.3rem;font-weight:400;color:#000}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.875rem;width:1.875rem;margin-top:0;margin-right:-1.875rem;margin-bottom:-1.875rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#454545;line-height:1.875rem}.topcoat-radio-button__checkmark:before{width:1.875rem;height:1.875rem;background:#e5e9e8;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-radio-button__checkmark{position:relative;width:1.875rem;height:1.875rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.875rem;height:.875rem;background:#666;border:1px solid rgba(0,0,0,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:7px;left:7px}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:6px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:1rem;border-radius:30px}.topcoat-range::-moz-range-track{border-radius:6px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:1rem;border-radius:30px}.topcoat-range::-webkit-slider-thumb{height:3rem;width:2rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:6px;box-shadow:inset 0 1px #fff}.topcoat-range::-moz-range-thumb{height:3rem;width:2rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:6px;box-shadow:inset 0 1px #fff}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:3rem;font-size:16px;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;padding:0 0 0 2rem;border-radius:30px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:16px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input:disabled::-moz-placeholder{color:#000}.topcoat-search-input:disabled:-ms-input-placeholder{color:#000}.topcoat-search-input--large{line-height:4.375rem;font-size:1.3rem;font-weight:200;padding:0 0 0 2.9rem;border-radius:40px;background-position:1.2em center;background-size:1.3rem}.topcoat-search-input--large:disabled{color:#000}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input--large:disabled::-moz-placeholder{color:#000}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#000}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:16px;padding:0 1.25rem;border-radius:6px;border:1px solid #a5a8a8;overflow:hidden;width:6rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:5rem}.topcoat-switch__toggle:before{content:'ON';color:#0083e8;background-color:#e0f0fa;right:1rem;padding-left:1.5rem}.topcoat-switch__toggle{line-height:3rem;height:3rem;width:2rem;border-radius:6px;color:#454545;text-shadow:0 1px #fff;background-color:#e5e9e8;border:1px solid #a5a8a8;margin-left:-1.3rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #fff;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#d3d7d7;left:1rem;padding-left:2rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:2.7rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 1.25rem;height:3rem;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border-top:1px solid #a5a8a8}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#0083e8;background-color:#e0f0fa;box-shadow:inset 0 0 2px #c0ced8}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:3rem;font-size:16px;letter-spacing:1px;padding:0 1.25rem;border:1px solid #a5a8a8;border-radius:6px;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input:disabled::-moz-placeholder{color:#000}.topcoat-text-input:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:4.375rem;font-size:1.3rem}.topcoat-text-input--large:disabled{color:#000}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input--large:disabled::-moz-placeholder{color:#000}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:2rem;font-size:2.5rem;font-weight:200;border-radius:6px;line-height:3rem;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;letter-spacing:1px}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea:disabled::-moz-placeholder{color:#000}.topcoat-textarea:disabled:-ms-input-placeholder{color:#000}.topcoat-textarea--large{font-size:3rem;line-height:4.375rem}.topcoat-textarea--large:disabled{color:#000}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea--large:disabled::-moz-placeholder{color:#000}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#000}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#dfe2e2;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_dark.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/css/brackets.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/css/brackets.css new file mode 100755 index 0000000..8e32479 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/css/brackets.css @@ -0,0 +1,69 @@ +/** + * Brackets theme + * + * @author Garth Braithwaite + * @version 0.0.1 + */ +pre { + word-wrap: break-word; + padding: 6px 10px; + line-height: 19px; + margin-bottom: 20px; +} + +pre, code { + font-family: source-code-pro, 'Source Code Pro', Courier, monospace; + color: #535353; +} + +pre, pre code { + font-size: 13px; +} + +pre .comment { + color: #A2A2A2; +} + +pre .support { + color: #0086B3; +} + +pre .tag, pre .tag-name { + color: #446FBD; +} + +pre .css-property { + color: #8757AD; +} + +pre .css-value, pre .support.namespace { + color: #F18900; +} +pre .vendor-prefix { + color: #535353; +} +pre .constant.numeric, pre .keyword.unit { + color: #738D00; +} +pre .hex-color { + color: #F18900; +} +pre .entity.class { + color: #5585C4; +} + +pre .entity.id, pre .entity.function { + color: #900; +} + +pre .attribute, pre .variable { + color: #738D00; +} + +pre .string, pre .support.value { + color: #8757AD; +} + +pre .regexp { + color: #535353; +} \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/css/main.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/css/main.css new file mode 100755 index 0000000..2d0bda3 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/css/main.css @@ -0,0 +1,508 @@ +html,body{ + margin:0; + padding:0; + height: 100%; +} +body { + font-family: source-sans-pro, sans-serif; + position: relative; + -webkit-font-smoothing: antialiased; +} +body.light { + background: #F4F4F4; +} +body.dark { + color: #F0F1F1; + background: #4A4D4E; +} +body.light { + color: #181919; +} + +h1 { + font-weight: 600; +} +#wrapper { + width: 100%; + overflow-x: hidden; + background: inherit; + position: relative; +} +#site { + width: 100%; + position: relative; + z-index: 10; + background: inherit; + left: 0; + transition: all 0.2s ease-out; + -webkit-transition: all 0.2s ease-out; + transform: translate3d(0, 0, 0); + -webkit-transform: translate3d(0, 0, 0); +} +#site:before{ + position: absolute; + content: ''; + left: -4px; + height: 100%; + width: 4px; + background: #3B3E3E; +} +#site.open { + transform: translate3d(250px, 0, 0); + -webkit-transform: translate3d(250px, 0, 0); +} +pre { + font-family: source-code-pro, sans-serif; + font-size: 12px; +} +/* Main Header */ +#main-header { + color: #373435; + background: #fff; + height: 98px; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 10px 20px; + position: relative; +} +#main-header hgroup { + text-align: center; +} +#main-header hgroup h1 { + font-size: 40px; + margin: 5px 0 0; + letter-spacing: -.065em; + line-height: 1.1em; +} +#main-header hgroup a { + color: #464646; + text-decoration: none; +} +#main-header hgroup a:hover { + color: #000; +} +#main-header hgroup p { + font-size: 13px; + color: #999; + margin: 0; +} +#main-header nav { + display: none; +} +#slide-menu-button { + position: absolute; + top: 20px; + left: 20px; + display: inline-block; + vertical-align: top; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-background-clip: padding; + -moz-background-clip: padding; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + padding: 0 0.5rem; + line-height: 2rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: baseline; + -webkit-box-shadow: inset 0 1px #fff; + box-shadow: inset 0 1px #fff; + -webkit-border-radius: 3px; + border-radius: 3px; + width: 2.6rem; + height: 2.6rem; + line-height: 2.6rem; + border: 1px solid transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +#slide-menu:disabled, +#slide-menu.is-disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} +#slide-menu-button:active, +#slide-menu-button.is-active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + -webkit-box-shadow: inset 0 1px rgba(0,0,0,0.12); + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} +#slide-menu-button span { + background-repeat: no-repeat; + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCIgWw0KCTwhRU5USVRZIG5zX2V4dGVuZCAiaHR0cDovL25zLmFkb2JlLmNvbS9FeHRlbnNpYmlsaXR5LzEuMC8iPg0KCTwhRU5USVRZIG5zX2FpICJodHRwOi8vbnMuYWRvYmUuY29tL0Fkb2JlSWxsdXN0cmF0b3IvMTAuMC8iPg0KCTwhRU5USVRZIG5zX2dyYXBocyAiaHR0cDovL25zLmFkb2JlLmNvbS9HcmFwaHMvMS4wLyI+DQoJPCFFTlRJVFkgbnNfdmFycyAiaHR0cDovL25zLmFkb2JlLmNvbS9WYXJpYWJsZXMvMS4wLyI+DQoJPCFFTlRJVFkgbnNfaW1yZXAgImh0dHA6Ly9ucy5hZG9iZS5jb20vSW1hZ2VSZXBsYWNlbWVudC8xLjAvIj4NCgk8IUVOVElUWSBuc19zZncgImh0dHA6Ly9ucy5hZG9iZS5jb20vU2F2ZUZvcldlYi8xLjAvIj4NCgk8IUVOVElUWSBuc19jdXN0b20gImh0dHA6Ly9ucy5hZG9iZS5jb20vR2VuZXJpY0N1c3RvbU5hbWVzcGFjZS8xLjAvIj4NCgk8IUVOVElUWSBuc19hZG9iZV94cGF0aCAiaHR0cDovL25zLmFkb2JlLmNvbS9YUGF0aC8xLjAvIj4NCl0+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOng9IiZuc19leHRlbmQ7IiB4bWxuczppPSImbnNfYWk7IiB4bWxuczpncmFwaD0iJm5zX2dyYXBoczsiDQoJIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDBweCIgaGVpZ2h0PSI0MHB4Ig0KCSB2aWV3Qm94PSIwIDAgNDAgNDAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQwIDQwIiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxzd2l0Y2g+DQoJPGZvcmVpZ25PYmplY3QgcmVxdWlyZWRFeHRlbnNpb25zPSImbnNfYWk7IiB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIj4NCgkJPGk6cGdmUmVmICB4bGluazpocmVmPSIjYWRvYmVfaWxsdXN0cmF0b3JfcGdmIj4NCgkJPC9pOnBnZlJlZj4NCgk8L2ZvcmVpZ25PYmplY3Q+DQoJPGcgaTpleHRyYW5lb3VzPSJzZWxmIj4NCgkJPGcgb3BhY2l0eT0iMC43Ij4NCgkJCTxnIG9wYWNpdHk9IjAuNzUiPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkZGRkZGIiBkPSJNMzksMTF2LTFjMC0xLjQ3LTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MQ0KCQkJCQljMCwxLjU1LDAuNTIsMiwyLDJoMzRDMzguNSwxMywzOSwxMi41MiwzOSwxMXoiLz4NCgkJCTwvZz4NCgkJCTxnPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzksMTBWOWMwLTEuNDctMC40OC0yLTItMkgzQzEuNDcsNywxLDcuNTIsMSw5djFjMCwxLjU1LDAuNTIsMiwyLDJoMzQNCgkJCQkJQzM4LjUsMTIsMzksMTEuNTIsMzksMTB6Ii8+DQoJCQk8L2c+DQoJCTwvZz4NCgkJPGcgb3BhY2l0eT0iMC43Ij4NCgkJCTxnIG9wYWNpdHk9IjAuNzUiPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkZGRkZGIiBkPSJNMzksMjJ2LTFjMC0xLjQ3LTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MQ0KCQkJCQljMCwxLjU1LDAuNTIsMiwyLDJoMzRDMzguNSwyNCwzOSwyMy41MiwzOSwyMnoiLz4NCgkJCTwvZz4NCgkJCTxnPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzksMjF2LTFjMC0xLjQ3LTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MWMwLDEuNTUsMC41MiwyLDIsMmgzNA0KCQkJCQlDMzguNSwyMywzOSwyMi41MiwzOSwyMXoiLz4NCgkJCTwvZz4NCgkJPC9nPg0KCQk8ZyBvcGFjaXR5PSIwLjciPg0KCQkJPGcgb3BhY2l0eT0iMC43NSI+DQoJCQkJPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGw9IiNGRkZGRkYiIGQ9Ik0zOSwzM3YtMWMwLTEuNDcxLTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MQ0KCQkJCQljMCwxLjU1LDAuNTIsMiwyLDJoMzRDMzguNSwzNSwzOSwzNC41MiwzOSwzM3oiLz4NCgkJCTwvZz4NCgkJCTxnPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzksMzJ2LTFjMC0xLjQ3MS0wLjQ4LTItMi0ySDNjLTEuNTMsMC0yLDAuNTItMiwydjFjMCwxLjU1LDAuNTIsMiwyLDJoMzQNCgkJCQkJQzM4LjUsMzQsMzksMzMuNTIsMzksMzJ6Ii8+DQoJCQk8L2c+DQoJCTwvZz4NCgk8L2c+DQo8L3N3aXRjaD4NCjxpOnBnZiAgaWQ9ImFkb2JlX2lsbHVzdHJhdG9yX3BnZiI+DQoJPCFbQ0RBVEFbDQoJZUp6c3ZlbVNKTG1SSnZnRTlnNitQMXFFSEprS0dnQ0RBY1lkV1pId09IbzRRM2FYa094anBXV2tKSmtWVGVaMEhpVlpXZVJ5bjM3MQorMVFWZ0xsN1pFVWVSVksySzFDVkVhNE9nNW5oVU9qeHFlTHYvbzh2Zi9QRjlkZHZmdmZ3UmJxYUQ5UGYvZDNOMjRkbjc5NjgvZm1CCjFNTXZYcjc4N3R0M2IwSDZ5YTkvZWdqcjFTeVZybjlSdjdLSy8venc5dHNYYjE3L25GOWRKZm55SGxmLzVCZmZQdnZkdzh1WEQ0ZGYKUG52OTlicy9QSHY1OFBhbmg1LzhWTDcvN1l0M0x4K2t4aCtldmZyZGQyOS8vL0QyNnRzLy92Nm5mbXRwNi9iWk8vbCsrVm44V1VpSAorUE01SHI3OEZiNSs5dnFQejc3OTlzWC8rNENicFlwN0hkOTg5L3JyRjY5L2Yzenovd2p4OEVYS2g3UWR2aWp5MVg5LzhldUhiOS96Ci9lMmI1OSs5ZW5qOTdzdTNiNTQvZlB2dHpadVhiOTUrKy9QRHpaK2Z2VDc4NnRudjVadG5oLzliM3VETm53N0hsOCtlLzhja2I1Mi8KdW4veDhrRmU4Tld6ZDRjUTBSZlh2d2p4cStOM0wxNSsvUS9mdmZyZGc3ejZ1cEdjdm1LVC8vU3R0Q1hONG0rUXkxZS9lQ1dVM3p5OApleWZQSlRkRWYvNzY3NC9qWXdpUjVTZi85dXVIMzc5ZzkwdTMvSytmV3JOdjMzeno2dG5iLzhDMWh5K1crU0QvMlIxLysvRHFtNWZTCmUzemRPRi9sd3hmOHQvOXA5ZVF0V09lTHVGYnBsYkllMGx3UEtWZjl2dmZOd3g5ZlBQenA1NGQvZVBQNlFUdmcrdTI3MytnUUxNczgKNjcvNnphKy9rekgrcDljdjNzbURyU0J0MmdPL2V2UDF3MHVwMzY2L2YvbU1MODRTK3I5YTRiZlBaRTY4azdGNzgvSzdkNXhaMWU4ZwpQZnpMWjM5K3dEQUZ2Y0UvZnZQdytyZHYvcG5QK0VVTTBrN2NyclpEWE9TTlF0eVdRNmhzUCtKUnQ3bmRNL1IvdFdrMGhHYThmY3lRCkwyV2Mvdkh0aTkrL2VQM3pMMUtWdms1eDFpSDgrN2N2dnU0akdBN1YvcGZHcitydy8rYi82OVBLaTc5NzkvRGFubDdtemMydmhua3cKWC8zcU4zTFh1OWRmMzd4NWhkNy9GaE5jSnNCcm1Sc3YzL3hldjJ0Lzh4dTUvTHR2OUEzNCtTc1pxQy9mdm5pTk5xZC80RGYxcXk5ZgpmaWRmL2YzYk45OTk4NHZYLy81bStva3U3WDkrZUM3clY4Ynk2OE0vL3U1L3l3ZFpuNXliaDkrK2ZmWmNHcERQcmM3VnN4ZmYvUFM5Cnpjbkx2WDA0NkpkeUpULzY3KysvK3ZiaDMyVlY5Y3VWZXZmNmp3OHYzM3d6Tk5zb3dsVU8vL0xzN1RmZjMvU1hMNSs5ZnZiMlFIcHIKK1pjdi9pamZQSk9lNm0xMzJoTWFsVm55alhRT0wyR1ZreHU4cDhMdzFSTnU5T3pkSDRRQlBieisrdHZXdG43Y1A3alN2cis5M3p6SApISHg3T0w3OTd0cy9ISDc3NXMzTDF1eitxOWE2a1VsRi9iK05lM3pKQzE3LzQydnRvUE03V1lYVE93bi8rWnU3aTlSKy9BN3k1ZDl5CjZ6ZlBYcjU4OGZ1M3o3NzV3NHZubDI1dzRmdDJKLzN1UXliV24xLzk3czNMRjkrKzZ2TnBvSHo1N08yN0Y4OWZQdnptejkrK2UzajEKNU1FOTNIMzlRcGpjSTh2NHZYVis4NmRuNzU3LzRaY3ZmdmYyMmRzWEQrOWRmUmlBZjMveCttdVorNy81N3NXN2g5NUJiMTU5QXlubAo4SnMvUFB2bWdhL3g3Zy8zclBtYjFtRCtTbGoveU55LytPSTlYRCtzaCtQcjRmdS9mL3ZzNnhleW9ZalE5ZmR2WG43OThQcndhN0QzCmFmZEp0cTl5T0g0OS9kczBXd2tzeStIdnZqcStuZjdiTkovK2hKTVNoNUtzTEZZeS8vZXk0djlKZm8ybHRGTG5iVmV1aDNLVWNtUGwKZGloMzgvMDAzM3ZaUGRqNEU0ZVNockxzU3RZeThWY0pxNVRDMzNVbzI2NWNoMk1yTjYwY3c2MFUvM1E3eVljN2ttN0QvVmpHcnVQRAorVThheWpLVUhGZVVTWC9GTXBRYU55bjY3L1ZRamxxbS8rdlNXRDQybW1rM25zc3dxbjFzcFV4dGVKZGhrSFZVeDlHdFV2QWJvMXAzCjQ3c05JeXovVGpiVVB0akhOc3o2RzZOOE40NjIvS3MvODhXeGp0TnVvSk9NSzM1alpESEdLMHZsS0plVEViNjJzaDliR1V2OHVtTzUKUFJsRnYybmlHUFl4UTlGQjhpSGJiTEJrZ0NZYkk0elZqWlZibGpzcjl5aStzdkF5NDFnR2p0SmlIVi9ab1VjdWtudjJUZVRMcjN5OQpqYTl5eXljTzlvUXJwNHc4d3NUNzRqNHhwYlNrTlJWUnRyWjBsSEtiN21XMHc1S1daY2xMV2VxeUxkZkxjYmxkN3BaNzZjaVlVMTd5Cm1rdmU4blUrNXB0OGwrOG5lYUFnczNSWjg3cXVkZDNXNi9XNDNxeTM2NzNNaFNEZHNKUmMxbExMVm83bHB0eVdlNWtub2NhNjFGelgKV3VwV3IrdXgzdGE3ZWkvekpVNWIycFpOMnRucXRtM0g3V2E3Mis1bDBvVHJkTDFjNSt2MXVsNXYxOWZYUnlrMzE3ZlhkNXhKVVY1ZwpPZVpqT2RiakpsOGRqemZIdStPOXpLNHdzYmZUelhLVGIrUUJicmFiNjV2anpjM043YzI5VExiQVVWaHU4KzE2S3c5M1cyKzMyK1B0CnplM2Q3ZjNkTE9PUzdwYTc5YTdjMWJ2dFR1NTFkM04zTzkzZDNkMWpSdHhMaDkzbmUzblRlM24yKzJzcGNzdDd1ZkwrNUVmR2NwYlIKYkovdmhuSTdsSnVoSEhmbGVpaWJsMG4rcVVNcFExbDNKUTlsR1VvYWlrekE2VDYyTXJLd3puem44ZEh2eHAvYlhiblJNdkhYY1NqWApROWwycFE2bERHVWRTcDd1Y2l2THJxU2h4S0dFb2N4ajBTNmZyTy9IcHg5L2JvWnkxTUtWdVJ2SC9lanR4OHhIYXo5RSsyR1JvWmlHCjBkZ1B3YjdqOTkxdDNYelN0K3pQcVhYcHZpUDN2YmZ2c1pOKzJuZk5kTklqMmh2WFZqYVdhcVZZV1ZteWxZVWxXWWtUMTU1dG1jcjYKMi9UM045TjcrYytSNWRyS3hsS3R5TnFlNUovVlNyYXlzQ1FyeW5xZDBRc0g5Ykc4NC9nZE9WNlY0NU01SUJpRW1kMSt5MjYrWnE4Vwo5dVBDZmd2c3B6dDJ6SkVkVVNlK2VlYTc0Z1ZudnRBdFgrQ2FqMXo0aEF1ZlNKNURac3VkZE9hTjhLMXI0VjlWK05ncTNHd1JyaGFGCm04K1RUS1E3NmVVYllYclh3djdxZFJGR21JVWhKdGxSZ3V5dzl6TGl0OUlkeCsxYTJHYmRpakRRTEl3MHlSWVVaRCsrbDRsd0s5MTAKRkc2NzFUb0o0MTJGQVM4MUNTc09zbkhmeXd5NWxUNDhsbXRoMWJVVVlkcFptSGNTRmg1a283K1h1WE1ySFhzVUJyOEpveS9DN3JPdwovU1RNUDZ6ekpOUDRUc2I0UmphR2E5a2dxbXdUYTg2eVlTVFpPSUxJRHZjeTNXNWxMSTZ5cVd5eXVaUmxsVzFta2UwbXlxWXp5N3kvCmsxbHhJeHZSdFd4SWRaS2RhVTFaOXFna2UxVVFXZVZlWnVpdERCOTJVV3lyMkdpemJHN1lpRU9jQTdoc0UyaXRGdXA1TGRhVEJhV2IKT3VRMzdQd2JKUU9WRkVSMjRIeDQ1SFpzaGczNDVmMWlpQjJ4TTRiN2dkVXJTOWhrVW1XWlVFRW0wNldwRkcyUDRPNkRIOTJCQXRjbApkcUhNMWVzN2tlMUYySXBrdHhFaGdQZkdmdGMydTFWbVdiMnczYVcyM1dHenU4WU5lWEdUR0pMSm9NV2xCZ29OZHhRYmdna091WWtPCjEyTzNveGNncDgzMzJxUjhvREIzeTQ5WUxicFdmRU5zdXlpLzU1dnpyWFVZcmltVjNLWGR5RklrREUzb1VRbFBCUitWNUc0b2lOOUoKMDhHRWJIMGRsNXBOU3FaYXdhYThvZDRNRzJGdjZNVVhlMElmZVJ3b0hhU2RzRUJKSWNuSUY1a0JSODZGRStuQXV5TGJCdUFjWitRNQpmYXAwdmpOeUh2SWU3ZUlMN0dqUGpiNlBGMm5YbjZ6R1QxNk14eWIrZXVtS1ROMnBPTVhVSGkxNXB4bVp0alRaSC82akF2bE9SOTJyCllMN0hOQVd0U2Zvc3gybW4yTjFRZ25hbEFMKzNrMUpQU2xjaTlhOTFjald6bGVXc3BMTVNMeFQ3bVhhYTdwbENoeFUzQ21udDkrM0YKSW54aWFwcjJqU2xqUjlYT0xwYnQwVkpkNzVzR0pWL0wrc1RTVmNvOGxtbi9zUmtiK3QvbkpUMVNPQ21tT1Q2eFhPcmdDMlY2WXNVbgovMXpTM1QvcDU3TTE2UHRpYUQycU1xcUwyYmRXVk1KeW80UWJLYXJwd203RXNKVSttZHJzeTl2TkluMzZuNjVtbDFCOTlZNEw5cWpyCjJGWDY4OVZhbWdsZ3RaS2JnYURiaHRLNFFLZnZYNW55VnpOTGRQUFV5WEwwQlhrN0RVYXQwY2gxdkxnY2p6dlQyUG1DTkdQSzZmcXMKT3l0YnQ4NjRoZWJTRW0yZnA3T1ZlYm9JenhmbGU4dDBaakM4dEZMZnQzNVBsdWMwMkNBL2VRMi9ieDMvOVpmZFoyL3drb2c2YWovbgorby9LSStmNmowc2hNM1RvTzBvYm0ybCtxOGtic1drLzk0UEVVWFlTUnh3MG9CdlJnYWdCVGFJQ1FRbFNGUWhLMEV3TlNIV2dHeHAvClZBK3FUUTlLcGdkQkU3b1JMZWhJUGFqU2xMUk1WSVVDRjhjOXRlSmIzRUd1cjZJSnFTNEViU2lxTmtSOTZOYjBvU1Axb1VwOUNCb1IKT0ZlWVRDbTZwNFlMdFVnVkk2aEdsYW9SbEtPRnlsSGdVcnFuaG5SRERRazZFclNrSW5kRlZWR0VKbEdVRXRsaG9Hbm1qdXJTcmFoTApVSmlnTWtGcGd0cFVsa3pGQ2FwVElxZWFxVDdkbTJKOTFES0ozQWJKRGJKYm9meTJvbjdDVDZEODFMazRaRm9kaXk2bHFXUldxVUNoCkxGUGoxR2RTMXlCanVTVlZmNDhNZUJTUktBOU5neEMwWTZwbmpITW51ZXg0NUk0alRqdVpCT1dFdDExa2ErK1JJTTRsaHFleGlVZloKeCtkY3g2WXRhaG5OVk9QUDNpdzNtQnIzdGpEZlZ5ZjdJKzVLMnBXOTJTMmZsSFZYeXJRejVaV2RrYTlTVWRxWDY1TnlQQzFUczNsNQp1VDByNXovMzU4WG4yRFR1MVBmaFFva1hTN3BZekpKM1h2SWpaWDIwTkZ2dXREUHNGcHFiMzFlMjd5blgwODZjZkxrY24xakkzS2VkCjVmcDk1ZlpwWmJwQXZEU0lUeTdUbzE5OTVNLzVKdnF4RFpuaFptN3FaelNQaFpiRmlwb3ozYnhackxqMWM3Tml0dEhKVEtYKzQ3eWgKTHhzZkQrZXNyaUs3Sk85V1dyWFpMaE9OUmxyV1Z0ek1XMXZackZ5M2NyekFvK1JuT21OUWwxaFROOTFmNWtZREg1b2VZVUtQY1ovSAp1TTdBYVk2MDRUek9hOTdEWTNaTXhSakw5RjZlY29HVGZCOExtZDdQTjU3QU1rNVl3elJ5aVk5bURjTjZmNHd4UEpFTm5LLzh4OWZ4Cis4dGZhQjEva0ExMVowVVZrZTFHaloxMHdrTE9Tc3N5aWFTM0RyN1lvM0FDOWNmTzVwR0ZUemJUSzF0Rm9IVFA3QzE4czdLNXFITTIKVVJTRmc3Wk1sRS9kU3dzLzdSMDl0ZXFyVFpBdTZhL0ZEM3kyMXhTQTRiZkZBbExmTGJ5M0VDenB3WjNveEsyUXRPbklQUW8zdW0zdQozRm5FUDBpUzhPa3U4bmlRa0F2RjhrMUU5R3Y2ZDIrRVg5eVpsM2UrRHBQSThaSHlQTnk5Y1BpdTE0V1Mvalk0ZnVuNmxZTHBDRUV3CjBNQ1k2QWFHSXhnQ2VhRTd1RTdIalQ1aDlRcmZrQmRoYWQvVFB6dzNsdXZNMXRtc3M5Zk9WbzJqVG8yVmRoYnFyTE16emM0ck80L3MKdkhIa2lMZFQ0NE1qLyt0OGI4L3JSaFkzc3JXQm1VMERIOXV6cmhObWRVSHlPZWRIZzB4eldXNTVqTXVjaUIxam1kN0hOYjZYVFR4eApnLy9ZZFd5RzYzK2JSbEJ4T0VUNWF6M1UrV3FSNVhJbzZVb1dTRVRWMzB4Lzk5VlRxaDYvUFcveEtrdkZQQjlxdUJJOWNIMjB1ZE42CmFPc3FyR1ZiZ253Wm9OMUdSeW5uV3VNaWY1UWM3ZXNZOHJvZFVFRWJpVmRwemt1NzJTYzN4S2VaUlRQTnE5U2FaWkd2dUU2VWExRysKMmRhMjVIa2pkbHFZNHBMbGo0amZZV2dyWGMzQ1Z2cERmYWIyOU5uV1dSZ3Eyc3Boem9YWFZXSEUycGFvaUZYYmo4SlIwWmFNVzk1MgpiZVY1M29abit6enRmZndveG5KVlU5clFVczFsKzhTaFBHM3R3a3kxSjkrMksrSG5qMDNUZlNWcDVYamJJSTZPVkx3TVh2ekh0OC8vCjhPTHJuMDcrQjREOURiSjR0YTVCOWttTVk0cWxyQVF3eXVKaTkrSnJqUHh1MmRvVkI3OUM0eERzaW9OZFljdFVIbGlVOWVHVlB1SmkKN2JDblhvaHVXdGFybERDOVArTEcrK3MvcEp0Lzh4OS9sajdHdjNMaG9oMzgzM3ovdWJkZEo5cCtrODJmV1d4M3ViWU41WFowUE50bQpzUmdXU25ZRFNrS3lGd1REZVMwVUVZRDBPbEkwdUtkVlNFV0NsY0xBTmNXQU8rNFNBSHBoMzljOS81cld2dHRUWUtPQ0dOMGpwUFp0Ck5aTmpMNTROQUtvdVhVZHcwaXZjUUhINU1hemtwWi9IMGJDajhUcWJVWVpXUWtWT0VEdlIwQk9uaHNKaUtBckZVUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJR0pLQ3BzSTdBMVBjWkhYcnZoOGVNcUJEbm9RTkdYMnpUUkFLQmgwWXdRTWRQbkNqMHM0QUlWaWFkTE01ak9CV3h3bGlyQ0VKSWIxVwpSeEZTWmxVTVlhV2NDdmtVMG1tV2ZvQkllaU9UYmFZWW1nMHdlRnZVUDQ1dU5keEZSMTdzZ0J0bU81eWIxL09HMWtFMUJ4WXoreTNtCk1RaG1DSDh5WU9aSmFCa0ZCSFR6dHpyY28yS2JETk4wMjNCTTE0WmVjbk40TnBpU3dwTm1Da1YzT3kvNkFCUnRVRkUxbjZvL1BEV3QKSWxPeldLbGRGR29ZbGRiZ2Erb1pSeG9XYmllS2xmZFVPTHJLb2VoUGpKdnFIYXA1ZE4yRDJvZmhRUlVSQ3YwREdzZzZVUW1wVkVKYwpEYm5kcVNJbnlvanBJaGg2UjQxU0gzR05aRHBSU1RBbk5nT1MzbENxdm10dzBraUZ4RUdsbzBaeVE0M2tEZ0xwWkFwSkdoU1NZc3JJCmtjcklMWlVSQlp4MlBXUVo5QkRvSUUwTG1Xamo2R3JJdVNLU1RSR2hLdEwwa0NOMUVXb2l5b2NNY0dmNDV3R2tTRS9oK2Q5MzdlODkKMWF6bWs4R281WVA1SXUrNlY5TC9Hbjgza1BVSXFsZUR2RUdzUTdQUXA0YXc3Ny9UN3ZkaTdOZmgyTG5oN3RYNEwxeHgyaUh2SFg5Zgo3Ri8xR3VpLzZzenQvMTd2ZkF5M0J0VTIvRDJCUDNBVUQxanRqdFJPNXNKWURhdTltaTlhUFIwZFZFOC95RFRncy91UzYwc3RFUkJ6CnVzdzRZd2lja2RYLy9qMW05QkdjK2dzZTh5Nll0M0owTVlUbWxoZ2RGT2NPMFhPZjZ1SmVqbE5IN1BtbjhmZnAzeU10ZThSQUR3MVoKSHNWdVBJN3NTTHUvMHpSOFdFNWNOcU1qNTdMUHVuL2ZQTmpUbWE5SCs2NjdsSHV2OWg3dWc5QTlNRHRrNnZFQ01yVVlLTFhEVVIySQphaEJVNWZUYzRXV1BuOGdicnJuUjYxWmZhTXpJNUNmSnRuemQ5UGN1MGV2bUVpMWtWdVlXblNnRmROL29MUjlPdHozZCtIenJhNXRmCjIvNThBeVJtbEp1Z2JJT1Q3WVBqVGpqdWhTTjJkSThlM2VOSEc0SjBVc0hIUEtTbkdOTEhVS1R2d1pGT0EzVHRvOEJyUWJueU9WcDgKS044UEdPK1diN09GVHcwbmZZNlVMczJvdmtkTEQzaHBLd05jZWpwRFROL3VFTk9QejhwcS9vTjFQemVuQVMwOVlxWG5ObEh2emE2awpiNmJ0SDl1YzFWbTdjYS9qM0oxcytxN2NDdnNrVGdZSlZGNnVybHlmMEhmV1hUZURyMThudDVUSlpuaXhXYjVTV2FDSW9xeVhIRnczCkN2VUw2N1MvNDlUbjVGY014Q1VuM1dsSXhHbTU3QW1NcDhiOXM2Q0ppOEVUZXp6L1dTREZkQjVOY1FMM3Z4eFVjUjVZWVhFQTA4WG8KaW5MaXNWMVAvTG1QQjFtazZkRTRpL0NlbGZQWXVwR1ZNMTFjUE1mQm1kVFh6N2lHaHBXMHM5NWRiU0prcGt6RkdlSTdyQjdDS0NwMAo2amtJczhxMGpZZ1dYVmVvMTNtTElaZWRHVU5xZHhQZjUycVBWcCs2cmx1Z2RyK0pJRnpOa0NJZm02VkdMVnpkWnJSZWlmeFUrOU44CmRBdThmMW1Tc0Q3WXBsSVIxbS9YaGxCRTdzY2I0aSs4YWwyRVp3NHZrVmU1TkhSRDVTYzNwRGF3T3FmRWZzeHBxelQ2eVQ1YlUwKzcKVUhBOWpHdmF1OWJNZHBYelBCcFJQcjJsRHpLbmZQZnExY05iV0ZUMER4ckJ6R28xU0g0dWtJMVMxUmhHV1Jwa3o3Rit4eFlFZStlaQp1NEtBSWRHNmVKMmJERjJhcE53akdUMFVkUlNGZTlncDFiMXBpRnFzRGFYWkEwb1YwYW40enNkMXpreXRrNEx3TkVqQ3FuSnVnMFI4CnRLM3N6alZQMFQySlhqSUFLTnVoOW9rTm5YcmlSTUJUSWZ4SkZWRlhSbysrUHhwdmNnK0ZDbnZSY05lbURHZHJOZWVKMmlxaFhMUkQKVkZOWnRkZ3U1Y0ZEdVczR3piUHNJS0tHSVowYVdEMjFrbHZwUDZXVjJzcDFLOGRlcHZWbUtOM2J2bmU1akRET3NDdHBLT3k3cVN5dAo1RjA1LzZrblpidFFycWR5ZlZadUhpbTM3eW5OYlRSZDlsbFR1Zi9Rd29rODFmZzV5bmtNYm8vQ0xTME85OWhYYWRqSGsxUXV5bU9QCkpzWlNuRXdkM2NXa2NKbmREL3BsZHcxdkZnZHpPMWhxRmw4ZnNNOU10aVp1NkIyY1c3QnV0bkRkU25QYnRVM25POXBpTUlFVHpZN1oKNWlZc01VZk94RnZNUUhjTFI4Nmo3aEsrcGt2WXhvOVl5VUJ0SU5FKzVyYVhTbU12YkM4UU9HaDNtYzN1a21sMVVSZncxaHpBdDJiOQpCUU9NRk9LNjFRWGkzdGJzTHZUOVR0L2ovdTBPNEcyd3Vkd3dLaGdHenp2REVUYmY3M1RpL0YwcEczZUVqVHVCVmVMdFVKb09vZW5nCkdZN1ZkT0lFWG5kUW1lME1LTE56Q0EvSW1JYUpVVzFrRDRKeHNld1U2M0tPY1RuSDA5MU1GMUF0RjlFc285eDZqbXJwWmJvZ0dWOUUKeUQwQklMZGNSdEk5aHFKN2I2R21Ic2FZWFkvVzlTaGRqOC90c2JuK0RGM3FONUYrRU5vcG91K2piM3NjczB2V1hZcnVnYlpOUUI0RQo0bHNGUmUwRGE3dVlleDVPMjFYREU3VncxQWVuQytyZ1pSUEZtU3A0b2dlYUpqaGRVQVgzeXVCZUhkd3JoTlZNb2FWdGRubHFhbUZYCkRWMDVqQzN0eGp5b2lQZURvbmpYRklNV0ZUejVqYS83ejlaS2JhWHZYWDBienEwc3ZVeW1WM2J0TWc0NlpoaDF6VUhqN0dYVXhEaWUKMDZERDNPeks4YXhjbjVSTFAzVWlPOTJYaXpzM1RUMlBseVlHVGYzUGs3SjhjT0VPTm0zcGM1UVBqOVorZjd3MlF5U25reGpKODVqdApmYVRrUG01N2pOdzI1OXpVREhhanNlN09wbWszMU8zTWRPcXJhOTQ2OTlkZCsvZ1dHeC90MEhnU3kzRFRQRlhiU1VSRDZyWTZzOWJkCmxkdUpLLzdJNmIrWkE2dFFPSFhYcFJydXV2Tnk3Nzdza1E2RnNtMmVMTnhCdlpoeEYvSndSMzYxRDN6WUtKU1VadURMSnA2M0dJZ0oKMWo3YSsrNXRrN3VsM2UvR09NVVlFcUZCRVNvT2VXaUVCa2VvV2tFM3hOU2lKTzVOLzFEdXFVenVTR3ZodFZrTVBYQmlESjFZVFpNdwpKU1dsaWJxUGg2U0dDN0Z4ajBYSGVaekZQaUoybTB6OTJnWUI5TEdnMkY2V1N3R3lIaVo3L25NZXgvWlkrTlFGSVB4MFJycjdtUEkrCmhCWEJLSFVIaXJqOHZRRXU4bHhGdVNQbVJnVGF6UUFUR2JhSDBLMFF6ZVp3Z3ZQNGlLcy94RHJ3VDY5ZlAzdjE4UFhoOTBZNmhKOU8KbDRnZDYzSWg0MDl1dXNhUTlTYzhIcmV1NGUvM0hyMCtHUXoxRklLNkQrTGZnMC9WQjZ6KzMrc2Q1bFRVaXFrQlRyZTllNnViT0pZegpKY2tmM0lQdSsrT2Z2c0J4MGpjd284VlRzeEc4QjBrNzlmZDUrZ01mN1lGN2pvQ3h0M2Y5UFZtSGg5M2pqcHJkWThrVExnTi8wOVM3CnZ5Y08ra0VTbEh5bTlDVFg5MU5QVC9LRFpsVDU4WUgxZ1FjYmQxcEtucEdJTmhhMU9rTVhMelREWHFuaDZjSWZGeG5pWjJoS3VLT20KM3lXbE5iMmpmUm9IbmVlTFBGVEkwblRlY2RGbzREQ3M1eHZDR3hLeEJ4dlhMVGhNSWhaZ282WHpUaGFvbWwwcWw2UkNtRFFWMnZYVQpFRXlSN0svUVZuZzdKRDl6QkpNRDZudnFzMkl3ZW9Mb0hhMHlOYmpLSHFwaVFKVWRjRDZieldRUG5COHRKM2ZiL2RUTUp3cGNpYWF2CkxHWkljU2o5YWtxUHEwRmR0L0FmVTU4bXM3VW8xdjdXZ0M1ajZRRWh1NUQxbml0eFg2YW0xZldTTHBibGtaTDNaVG9ockU4cTVmRXkKUGZwVi9iZ3lmVURsQzhyZmVabWVWdTNwNWNjR0wxUm9Vb0pMWVd2aklpcDdSVW9DWlpkck1SSmRWTGpwcXpHM0MxazFYVStheTZqSgpWOWpleCt5S2lRYmIxZUJ6RnNQVFFITWRNTmRDZDZhR2xmUEluWDNjVG1NNUFNbWRSZTRvVUc1dHhscmhQNVBOeEJ0enFONVpFTWRzCmNUekIxQk9IenVVV3orUEZiUS82Y3owWlovRis3WFlPdDM1MHcwaVBFdW1HbEhCYXBqRi8wTTRxazNiYzdyemtzMEplT0EyMm45TnkKd2NmeFNPazJwVHFOSDU1VXppdzgreko5WDRVUExVOXQ4TWsvMDlPci9xZHA4REVPQXAzaXp1RHBtVnJFdGZxR1dxNngxWlFHVDlJSwovbUVxMmdTaGhCN1QyREswUWplN2I3anF2TXZPcXE0ZWg5eU9icDZMSE1SNWlFTnRMMFQvWGVRaXprY0tzZ29xTTduZWNSSTFpSi95CmtzNVBvcGxjT2xmSlpvOHMwOEJZL0tmUDBUMWYyU0ZEVGdFd3ptR21NeWJ6R0xPSmo1UVRqak05a1FGOUh6dHFaWHJmbHg5UjNzdmoKUHFyODJPQmZvTUVQaVU1NThzLzdHdHpqaHRPWldhVHM3RGhtdzVtYVZXU1hPWEVNczZIZFJzMGdMaFc1ZTNzMTB4TUJJU29ZVFJaNwpVTGxPWUhlNmI5TFJRbHZ4Nk1xK3AzU1VMSUtra0dsQXhpZGFRckVRRTUzWGluUUFLNEhkVzEya3dBb2t1cTJ6Z1IzQVp0UWpCdGVwCnNxclVmTlpaZWRGa2JPakdRcGJnVzUzTmJhM0ZGN21QcGZNcmQwdDFNQnVWcDRrYVZOZVRSa1ZvMUc3MkNzbXAwRHI4S0lMNDlrSTUKejZhaW51RDV2U1ZPTi9ISlpYbEttWjVXN1daOWFwbWVYdlUvVFlOdTFybzlTejU3bERsYjdySXNPbVJqdmJYRVhTc1RkczFNMVhXawpqV3FsZlNwWWFxNmp6REs2dG1DVWdra0s5aWc0cytESVVpZVdnc3h2bVg1TG9lWFo4MjdSVTlYU0Q5ZmkwVlJUQTVFL0pmWHdhZkxoCmxuNjRZOGNuOHpLNWg4bTlTOGtnNUtFNWxXNEhJUG4xa0YycnU1SG9RcHJNZytUdW83M3J5QjFIM1duVVhVYWp3eWgxYjlFME9vdDIKanFKVE45R3BrK2dSLzlCMDRpQjZ6RDIwY3c2OXp6TTBQZVlZdXVRVWVvSWZpTEU1VHkwM1R5blQwNm85WW9tNlVLYW5WLzFQMCtDUApIT1JIRHZJakIvbmJYWjkvK3czK3lFRis1Q0EvY3BDLzNmWDV0OTlnOTNWZlBMbnU2VVM0eWt0Y2F0am91bDYyd29RcVdlWVlLS1ZrCmRYMkhHZEZURi83Z24rc0ZyL2xuYmRVYzZNZ3NFOUloaDZ0WmVOam9Sai81eHV2TFBlV0xOVndoYnYrUWxxczE5UHhPNzZteHY3NUkKcXptdU9GTTR4YTFjdVA2MFJydStsQXMrLzVIOGlXNy9lTm50SCtIMlQrNzJiOW5FN2s2Z3liY25FT1ZIQzNlczY5dXpjdk5oUlpzNQpoU0hqNTMwK2x6UHZrRVloZDZESmJIRHgyNFlUUHo5NnFaN0gyYmd4Y1R4R3JneWdzdkhreGZIVXhaUHlOOWRNVDJKejB6TDdkVHVYCnpRVWRpdjM0N01aV0sxeENRaGdXd3ZPNnRPTnk3SlNhZGk2UHAvRG9TV2Zxa0c3R2s4MThhb1dSa2FXMUtxY3BLZU1ZYk9FOTg4SmMKYVhVSmlYblI1cnhzYzd6d3gyWHN6K2RyVXFOTDh4d0RXeE5aU1p1Rml4eFF5em1zaTZFNkRjK1poSWZXaXV2NzQzemM5WHJ2ei9JcQpuNzF2UHBFRlhtU0E4Y094bzNlR1o3eHc0bEhEalJxTWNYTFk1ZmZoSnNzWmJ2SVMyUE1FcmFwN1AwN2JmRS9ybDkvaU1vaDA5ejZUCnY5TEhRQ2kvRjk0blBOWGpCVDUzVEFMdk1IbEV3dnRhL3dCNDRyNzlGdkd3NXlwMWdPbnRlTVBwRno4NHlpOWRtdXRwTjljTlp4WlAKTXI2T1NaWjBTN2hyYVY1N2t0YzhISSttR2M2T0U3TmtNNlJ2Q09mcnFWelhsc0wxMnVMMGRON1NQYVh4eHBFcVhxYTZWd3pLczlGWgpkYlJnNGp0enlYZFlUeHJpaE9IQXF0T3F3Y0F3NFNQbTk4N2llNVBoQ1RNZFdXTWNwbWRJd3l4djJWMU84N3VNR1Y0aW5lOHpYZktlCjVXWE04eklFa0V5UFJaQzBzekU4Z0tSNkFNbm5ndE5lWG0xUGg5T2V6TzBQelpXd1h3QWZjelgzSXJsdW5wSDlJSVdRbU5CUnJ4UnUKdGRaMXpKazUzTzVETHZxMGRWWXZMclM2U3c3Wk1xQjVEclF4RzdQRFJVMnE0dUNmWlg1MitHb0hjalFJcTE1dzExQ3Y4d0FONlpmNgp4ZkxEQzNaNUJHL01FNXk0Z0k3bSswMjJVdlFPajV4RGVUbDcwRi9pZ2k2Nm9oL0cyTWpUYkRtWDh1V0VDL2x5TEZmTzFBTE1YS1B3CkVFY1BhOVFkYTFmbEF4THFXRURqN1k3VENLK1o3TGdkanpMMFdMWFlZOVgwdnYwZStlS2Q0bnRTOTdTN2RjNDJuY1RGUlp0QWMyTncKT2o2MEpFWmhEWGM4WkdqajZVTHBHS1FQYjVrM2M1V25pSEpQbkI2MDBXeVlwSWs3Sm4vTXdnSm4yZ2MzbVZSWkpsZVllUFRQVVdaYwpFZmFkWkduZU04cnRta2Y2WURMb0FaR1hKYXNubks3NS9jRWhsaFArTkNQODhwL3d2bTA1RGFrY1cxNzVob3QzL05aajdHelAwQWg0Cm4zWnBCanEyZllTdmorRDBFV1BlY04zSzVOSU9kSHNoWC81NytPWXA1MFFXcTQ3OUg0RC9sNkgvYTN2VnNvT2RLZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJVUhISW5abDNHUno2OHozR29FOVpkTVA5NmhDTVdMd091K3Z3dXZNUWhRN05aU2JaUElLRVRuTEtFaDMweUU2UXovWUNRSC91Sm1KKwpNckUrTjhUNEpPSjZBT2U1STRSbklXQUhJQjFnY2hKeE54dmhOSURKQU4raVR6YWVmZnhwUngvclVhdlRwNXkxNmljUy8vaGtIL1ZrCmc1aTR5dFNQVlBERHZGSEJYK2Q1Z2NSM0pjc2paUVpIYVI2cjh6OTZucThxa3R1UXkvOHpONnVDNVRKSDVnVFBhd2pNUUNiZEoxMUwKcWJHbzhTUWgxWHU4OEVkcmNvMVhtNmpRdzVOKzFtYlZIUE5wOW5Gdk1seGg4LzFzWnZlVFpyVlBaeVFleFRzTFYrR0w1VENuamFNegpyMVZmbnNuOUwveHhVWkQvVEExK2twQy9YSkx4bDUzZG5HbVRrTDJuV3BMMmV5Wm9kK2FJOU96M2xwZ0g3Rm1USU9zZWVXZWJZaklsCkhOdmVOcG4rZmR2MDczRGpCNU12N1hnVnp5L2VEbFlaejFVWkRxV1NoVHp0VDZNNk9ZaHFmd2pWaUFQZkgwQTFIRVUxcGhwOC81bDUKVHl2MzA0Y2RhZlQ5NWEvZm9OcmxOQlh2UHY0Sk5qZFkydlNjZEpYeVhNSTd0a1JXaVZuaENwTWkzOWdHem1oczNjRWh6MW5TcXBaUApmTEhzYkc0NHVlRXVjVzlJMzBpVHlkTFNxUkh2T3pWemlhWkFtaTF0VmFUQkJJNXdUN3hXTGNkWmoxanFnTnJCWFhLU2pPejByRy9tCnU3cGM4c1d5VEhXNVdOYVBMZFBIWC9xWkd0U3AwYk91ZVNvNlQ3V3Y1MjE2WXNOaS8yOEQzVk0xdzhDYlBNdHpwTHRqVE1vOC9vdmYKWTVMcmVVaDNQUUxabjRSMy82aWZIeHQ4d2dWMkNNWXNxL0ZHQkhtY2hvdHpjR2VlZm52a3FiY1E5Q0tGUEloNEVQQWczaTA4em5ibQpRYmFRN0VhNWpvaVZ4OFM2UWJCcm90MnRJUyt1TFl1OG56M3J4MFdrYVRqRTIxUGo5NHo2NHltejQ0bmIyOW1VYnhraDkrZlZ2LzlVCitpY2RXdjE5eDh2LzhHUDUyUnRVVTh5Tm5RT2RhWklad1YzVjBoNW8wb09XOGVEOWg1cE03UUNQZFc5MDJsbTRqME9DSkxkd2U1S2sKMGNnZDZqeVpwZnZlOHVuZG1yMzd4bXpleHhiNzZSdEpUNWpaZjRhTW45TkozczNscktSSFNyeGNwa2UrQ0I5YnBvKy85RE0xcUZpSAo3aE1ZdlFMdUZ3aG5DQWpIUDR3SGovZmNlQ0kzeGwxYXZKNGsvU2taOGZZNThaajV5ME5YVWl0ajlNc2UrWFVTU0hQeHNNeTc2YkdvCm5EUHN5dFBLemZUOUlKY1BLMy85QmtjRDMxOWRLdjRoR255dmJqRTk4c1hsUXdmT3M2ZVBXZFNwRlUwWGp5Qll6N0pMN2pOTWhyT0YKNU12b09Oa2EybXp0ck9hTlczYkhHZGtCRnhkUzNJUVRiczhrLzJEM2lSYjVld1B6cWswK3lXNStMNDk5SkNkZmhYZkhxdnZLWDEwcQovcFFHTDZzSXl5TTZoV2tjMDVrS2NxYXNuR1JVSG1GaFhmdHBHdEhVMGtENzNxVlpwSFYzVVhsSGM4M2VHQmo2U0Myc1dDTEFoYUplCnBLQUZoTUx0UktudnhwTCtGUU5DTThXZlpmYURpVStCenpEd3didzNFOTE4STFxanluOXExVlBoN3pnMXVZOFNuOGw1a084ZzFVR00KZy9CMlRWMERjbGo2aTBmUy90amcyYzllUDdOQTQ2bDk4TE4zNG9uQ3QxY0VIUlNVMmxFK2UwMXptd1pWczU2b21tV25wRm94VmVVVApPK2JzNXkvUzRQdFZnOGVPSzdReVhUd1M2dlJNcDFHZGFWck9XUzlTSzVvTXVUa2VYbkF6NERidkcyQXJ0R1I2eVE0Rlc0ZVVlcFlEClVKUHF1UmR4OUNPK3o1TjRudEN3cHpQa1FRSmI4eHJ0ODNqZE1OTk9wR1VKU2ZsNURxR2VZdm5YbG9vL3BjRkhkSWRIaW1rYzA1a0sKY3E2czdKV1pRYys1ZEpEQTFNOE5zSEswckNMOWVJQzdJYi9JM0hLTXZDZkx5R1BlMDlGMzZtZU5iK1l4N1FmN1JUdGNYQS8wdTU1MgpwdXhvaHV4S3Y5OE43ZGVCbnI4c0R3eDd0VUpLL3VwUzhRL1I0SHQxaSttUkx4NVhZTzR1NlR4ZEk1cUdMUHk5akFwVlY3TThKMERYCnhWWnpJNVNlcG44eUphNGYxMzQwUmU4OFkvOTRZbnNIK2EzbVNqRG53ZVJZdjdQemNmVWs5blYzTnU3TjNlMEo2cXdJUndJK1ROZ1cKVHU1dHVERjM4VUhEejlsY1BhVmU0YURmUTFtdVFpNkRVKzdUbXFGcks4OXhJNDU2RG5IbGNUekNNMFBXM0k1TDJtSWdtaG40NnRHWApGOUpoS1ZmQ2x2dkRmSEpMZXZyUkI3MVNMWWU0WEpYZGMzeDBDNS9rVE11WG5HbDVoMHk5aUhzNTNhK2VuQXgyV1U0Uk1LY1ltRENjCnc0cjhUME9XV3o4bzBrOGc4bi83QVlmNzR5RzdpSlZPUDA4NzBXQTgyZkZVU0lEQUpjSldPN2ZYTVp3ZkR1RTBkZkVrSCtwMDNCOTUKM0pPcFAyWWZKQ0oxUEwvaGZqaG83ZndBaDIwNEpHMS9oTVBTam5DSTA2T25PSFFOL0hvd1QwSFlEUHU4clpFbmlNMnhsdUtuWnEyegpMS0RJdUFJZUdCOGV6ZFQ2NFJmck9WdXlKT2gybGpteHhHSlhWbzlaMkJUSGVobVcraEhYZnRwYXV3Z0R6ei9pd0gvRWdmK0lBLytzCk9QQjF1N1RTaEhvV1hSU2VFRjMwZUc1NjArZytzMG1tN1RSUG5HMVBTT0h0azdjZkYzUnI1Nno2a1VIOTBLRGFEZzFhaDhPTCtvR2gKT0JucGhQZC9NQ2ZkemNLUHVsclBTemc3UzJFMzRSNzcvcFBtVnJrb01wWDh2c2kxUjZPKzNuUHl3UTUzZkRta3JNc3U2NldwT3pUdgpGb3E4QzFoN05FNnROMWhQWXRST1R3NDRlOXJMNFdtUFQ5N0htZVZ1Q2ovT2ZaL0tmOSt6S3A3RzBwK1VKLy8weE5ZZ214SzFDNW16CkVOWkJtZGR0c3lsdWJMYk45ZE16UlUvV3lTZTM5YmtqM2Y3bER5L2VQZnpYdy9IbHMrZi9JY3RpOS9FdmNRckl1ZG5zSTg4Qm1jNFMKem5xNmFrODNPNmFhdlczSENlNXpWWHVPMlJ1Z3J1NHN2V3djOE9oN3JQemo2ZkhINVBqSGpvLy9GUGovelpEeG52ai82ZU1EQUt5MApGSkNlcVBIVTdISmlOZmtoejFjNXM2eCs5QWtyazZxcGo4d1V6OTJaN1NoS25TdzlQN0dMd0QxSHNZaStHME1BWFBpOXN3TlBuNURuCi9DUS9zVmtOMzJjeGZGcTh4ZmxoQ3g4YmNiRlBMZEFQV3poTklYRjdJVW5CazZiQ1I1eGNNMyt1czJ1bUN4TmhGNnBELzk4NEVjWXoKU1gwYURNbXEzemNWdmk5aDlUNWR0Wm1ScC9wcEFTNm5rK0oyK3ZnUWwyR0tEQk5sZXVSWWpuMDZpczhuUFpzTS9aZHI4SkpuNnRMQgoyR1hQM2FZTHpPMkNmbkV4OC9BKzc3QUZGRTJmR0ZGVU5LYW9oeFJOSHg5VFpKNkZveG9mYUhaSXQ4c2thMk9mZHVUdVF1S1JIK3JvCm9vOHgxVjA4dkdqNkVHTmR3L0k1a3M4VHQ5MzIxRzJUbVNXWXZhMGxiN3Q5VXZxMmZmSTJpMGFhUGkwY1NhTjZEYlhLZUtUcDR3T1MKaUZnRm5tRTFwQ3BBcXJLYzdrL1N3NVFMR1dSK25Bby9Ub1VmcDhLUFUrR3h0RkVma0ZUcExEL1VoMS83UTVtY2hQRFZQN3g1L2VYYgpGNi9mdlhqOSt5KytHSFR0OFl2cEg3N0JOMG0vK2ZMWnUzY1BiMStMRW43OThzL2ZmdnRNMUcvNzQ3QnRWOXVhRm5oT2wzVk5oN2dzClY3S055eDlodlpLNXRQSkpyL252di81SmZuM0hQOTNuK0s5LzVzZi9JWC8rYnlIK1NWNys4S3ZEdi8yditmQzFYdkpyK2VYMzhDWVAKcjRSNGRxUERMMGVxUDg4dmgrc3YwWFpYdjViL2YzYjk5dDN0aStmdlhyeDUvZXp0bnc4L3A4bmlaOGMzYjE3SzIvL0NldUtydTY5Zgp2SHZ6OXF2anMrZi9JYjMxMVc5ZnZIejQ2dGNQejkvOTlQQmY1WUwvVS82M1YvMHYzN0dCVzc3TlAzSTZSQndWcURiSUVETW54aUlUCm9sclNQenRBdGZwWmdjdFc1N1FkL3ZVWkc5cDFYQXJoYWs2cmpIdTlTaUxaYThmSXEwVVJ1QTU1dTFwRnBEcklpcitTcHZJaEZ4elcKS3U5Y3BYcU42WkR6VlpDMWRYaU95MnEra3NWYkR6bGVyUWdCRmNuL2FwRlZkVmkyS3hINmNYYnNlaFZrQVI2V2RDVnJMZHBsMjlVcwpYT0dRNU12Q3hvdmVMZGFySEdIUXIvTlYzamFab3VVcXdmakt5OHB5SlNxSTFGb1JtQ3QzVytVdTg3SWVVdFJuQWlIbHVoMlN2SVpJCnQzcVpFRU9vNVNERFhJT00vVnF1SUcvQ1A3NGhTbFMwSUJuT1hFQ0lxZHFycmZNVmxKTERzbDdoN0o5RGxLNEpzaFlQUzdoS290OGMKV28yVXJ4YS9LRnlKb0xxMng0NXJScTQwVFptRzVHVHJlcldFYlRtRUxFTXFnNkJYclZkYlNPc0JOd2gxNHdOSmk5SldYWEFlYms1WAp4Z1NFeWZoRjhqYnNzaS9DbGJBb2RIV3FWM091NGJCSUh3cjdFNEk4QmVaRElEdkplcDMwT1NDZWgxRHNOUlpoS1J1ZVdVWWNuU3VmCkY0VERZcnczRzdDRW1TLzlLYS9LMFVRclhCWnl6N3pLZTZaRngydkpWL0trTmw0cFhNbmZNb2RXNmRjZzd5V1hWMUVuRHVzaTQ1YmwKbGt1VW0waTdxOXhNaGxZdmt5a1hwT01PWlVXMGRtVW5DbmRlY0puc1NFS1FSWmx5a0haV21XV2h0RWtscTJSRlc0ajZQYVJaWG1pVApjYStMakxNTWsweDh6bUNaa3NMdmRjVGtzYTdXV2ZwY1ppQ2NUREtWY0RONXN5cFhaNWxUU1dZYnAzU0pPdXQ0bVF5d0tEYVJrZGRGCk9pQ2g5K1JlOHV4elR2Rnd0c3B3MWI5elFkOXl5Q3RUMmFFKzE4bXJrU2dUQy9rSU9WczJCRjNMdE1JYlJIYkEzRDdyNUpISGtxMjYKMTVHVkkwcmQwSWdSL0ZZK3U1VW9jM2RiVWN1YWtibkdGMnYzY2tLYnFYaWdYc3ZmbzdWejhtTCszaW1nSTJSWVNwSTFML1BxMVk2NAo2THhLTWl0bFA5NUFrTzFWT0lTdzJpeWoyQWc2YURMTGdxeU1YbXZSdS9aMm5HQjMwOHVjR0s5RVk1VkJhKzJFcTBWR2Y3aWJFZlF5CmY2Wld5NSs2dFhQeWJ2N1MvK1dmNUo5L2V2SUc4WXR2di9yVk05bFRiOTU4OCtldjN2dzdONHkvZi92bXUyOTBoN2g4eGE4ZnZubDQKOXU3aDY2L2tGcnVkWkR2ODVLZUhmLzJYQzN1S1RJeTh6c1FVQ1YvWjZQR2NTNUdld1c0aXJLakVQTzRtUmMvbDF0MWtxVmRseTdJeApZc0VzT25NN0Via0o0Q3FWQ1NKNnYweGxtU2hWZUt6MHN0WkFRbHdSOXRoRlFkaEtCRkVtaTE0bXF4RlJCNGVTdGZGRzJLd0dMM05pCm1EZTdMbUtYbHAwNWhOVW93dnZXdUEwVVhybllEdDdyeWNUVmVuUFZCMnVVcmVvbXp3dWRLRXlHODd5OWNRWEQydzVuM2JKZjcyRkIKZndnVHFWRzZWYmpLcXgxUjVBOXdyQ0RzY0JHaDF6bFd3RllqbzJJZjlRMlF2M2p0VmRDRlNYYWwxa1lqMkoxYVI1TVlaREFyN3VUTgp6THBNMjYzbXZtejc0N1JLL3NDdG1aUFgyazM4M1pSTGFhNExrR3F6N0E5MERzMjVoTlV5SGMvTTZWblZ6eTUvYkl2czJEcmhvdXlkCjdORzh3QUdibFZWaTVRSjBsNE9JRmNKdjR5emY1aXdNR1ZNSzIvVXNlNDNzQjNqV09SaXZuSVU3cjdLU3VWV0FXd1ZoMzlqc3RrVzIKMWlxYm42emtUVGFmd3lhN2dFZ1NlaGwyQUhtNVRaaURNUDREOXpYWmZUWVJla1M3a00vQ0I0S0lNYktIYkZ1MDdVaUlKVmZkUjRUcgpIQ0prRzlHWTBKc2l6SUVnMWF1SUc4STE1clRZWlVKYzVJME9zdWZCOXNtYnJWVkVCOWxFNndLSjZMUS9UbllXTEE3c3JYTGZQTXY5ClgrMkllRi9zeFBLZWVVbWNScGcxVVhoY1FKZmI1K2ZleDZYR1hrZjJlT1FvNlkwNHdXNmxWemxSUmxpMHYwTnJwcUJybDdYZnl3bDYKbVQxUXIrV1AzTm81ZWJIZFhBdUg2MjgrbWJVRlNJK3laVUx3a0wxZkYya2paaGtsR1Z4NThxdFFaYTdJc0ZYTVlQQVNVVlJySXlpUApFc2xZNXNCUVMzcHhGY21vdCtNRXU1dGU1c1J5QlFYODBOc1JrVG5MOFBlN0dVRXY4MmRxdGZ5cFd6c243OVo2VDNVcjl0NG5yOVVnClV5VkQzc1dVRWE3SURvU09nRTEzbGJFUmVUTUlLeGZobFk4V1NzUktGVFlqUTRTbHUyRmg2SHlRU1FaR0s0dzNZNWFMNUhzVnNaNWsKK3ErekxJeFE0VUplWXlPd0l5RHJ6MnV2Skt1R2ZEc2w1L2RHRUkxbDRPNUdGT0ZsWFdYMUJ3aVc1T2FMWFNiU1VDM1lGSVR0T25zUAowQnVLek5sQVhzUFdSWW9xM0hXeUNyU2RFbVg2TG41bG80cEVEQ01JZDUwTjR3S1dDbmZJQWExdklsWjJDcStVSFhhck12eTluanhqCnljdkNMWS9xeTBBUmpXRUwyYTUwS2htSWFGL29yTVRueDVyTkFUckJDaTgrbmovb0lQRktXWEdKYzFqMnlCWHlqUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJak8xVldyRGJ5R3ljWlorUVVmVjlOSlRlUTNHV01STEd5dWxIaFV3K3lBVTFzRjdCcXA2dEorYXRiNXdjZll4am1JRytBcGg0aGxKUQpPQUJsa1hVZFpIdEcyQnk0Y0oyRExSLzVzS3p5Z0tLOUpqQi8yYVNrdTRUamI3UGUvM1NHbm16VDBCMDRTUU51VTB5NjZWU0loL0xXCkt6aFlVVjVBMWgyRVhTTUhTNmY0QkZuQTRZZDZVVjUvRFVOVGpXQjMxQXNiVlRvaUNUOFltaElwZEpWbE05elNLSHBsZTdSV3J6MTkKYSt2MExiMFhSRFBWM3NHTW5uTlVLUjFqV3pPWWlGTkZEeGJCZXdaRnhuL0xPMHBSTFV2SG8xR3hzbW8rREczSmVnZ1lrWDVQbytpVgo2U29LS3gvcnlTNEwrTlhRVnFQczd0bW83ZGxhVyszNVQ5K3o5WUNzRXZhTktMTFVURi90aUVEVVo2eXdwTDI4VkZYQ2crZ0dDYlBRCkNjNk1rSFdtMTFxckRtdHJweEhzYnM5dHVpa3h5UlNCbU52YWlmWkM3VzVHMFBYdHo5UnErVk43TzZmdjlyaTA5aW5tSnVpSXM1QkgKK3hMWUd4UXROeTlCSGNpQVdMcDVLU3dpZ1ltV3RUTXZRU2lWdlc5cjVpVlZHSVFMdUhrSkl1bzhMOHZPdklTMk5naHNibDRDcitUZAozTHdVYUw0UVBqR2FsOGd0d2ZQY3ZDUnZmZ1h6ZFRNdmdSRGozcm9VNHFKU25GbVh3RjFsZXcvTnVrVFdKMHJIenJwRXZpbkNZN011ClljT1FUbHVhZGFuVjZOWWxzTXhscWYycFF4UlJhS3RyTXkrRktITi8yeG1YUUNwVk9MUWJsNW9rNE9ZbHJMQ2E2cll6TDRIeDVpUjgKdXBtWFpCRnRFVlkwc3k1aFVjbnVzVE11eWRMTE0zck9iRXV5L0dYZVJqY3R5Y2UwMENqWVRVdmdCd2tIcEpobFNacElhZDNjc0NSOApXd2FxN094S0ltWXpNNTZibFRaS3lLVlpsV1Jud0p3ZGJVcmtmVnNKemFhRXJvTVE2U1lsdWZjVlhBQTdrMUtRdTNKSnVVa3B5SFROCkFDSzc5aVhjbHJOMk5Da0ZLSytsVzVTd2ZjNTFYWnBGS2RTb3MzaTBLR0dub2xqckZpVzVyMnpLOHNodVVqcGJXQ2Q3RitOdHdySXoKS1RXaVc0TXdIV29XR2RqTVJTRXk5V0FlVFVyWXJTS0VPNjhUWUxTRXVjMGJjY0pvNU9sRU13VzFadHhZMU80MW1wVGFBL1ZhL2g3ZQp6dW1MamJ4YTVLRmxaMUxxUkRNRmdTK21MVGRia2NpY0NKdmFkaFlsY0ZTRSt3eTFacjFwYjhZSmc0Mm5FODBTMU5zeFcxRy8yMkJSCmFvL1VLdmt6dDJaTzN1eHYzYUQwOGRxOUxQQll5WVhNT1BkcXBNcFNwb0d1dVJGazR3YW9WQWhCcHd2WVVNNW1PWVpLc1VScTVtbWIKNFQyUWpoWkpFWmZsWk9aSmJzVlNRN1lOZHhDWS9SL0duU3lNcEpueFJjWGdXaFIySWs4ZFF5T29CUjRDZXVtVllGa3ZJc0xYYW40RgpKMnlidHQvczd5QmlOY3dySGxJMk0rRTRHMVVFQ2lNd3hzWjFJT2pMVmRFMnVJUzlXdXU3WUNicTg5NDhNUTZVV2UyYjJBUkVDRkk3ClZLY0tVeFFaZmxFckxqMEhNWnB6QUh4eHphRlR0T2ZnaEVqcldDK3FwMkJveXlsK1R6ZGJHN1dZUzY2MUJkMkpvOWZ1NlJTOTBwK3QKMWV0djVXMmR2ZWNQSXVvMEl6L2szSFhkbHIwdkRTb0tPWGR6cHFHZWFQT2xlOU1nbSthOHVsL00zR215VTRzSWlDdmRueWJhdmV6RAo5TERaU3NDMkl2SjkzbnZVS09NbDNxRzQwTG5xM0cwK05XZ09JaGI1bWpHbkdsVGN0V0FTdVZjTjNJM1AxdHhxMkpPNmhjdjlhdGk2CkFxWjA4NnlKdkNDRG4zSjNyY0VLSUpQZGg5QThaOURHUkJ3czNia202MEJ1empYb2RXQkJXVXk0Ynl1enZZTjcyS2d5eWExR0YxdFMKMTg3T3gwYkpNeSt4T2RuZzJscmt6czNMRmloNkxIc3ZHNVZycUNITnl3YlJVM2FqT0xqWkZuU0lTUUhkenliN21MNlJPOW9DOWxFWgpyZVpxbzdraEIzZlFtYThOTDY0K0ZYZTJRVDNmSXVhM3U5dlFnZlBpN00vOWJWUnZOcnlqTzl6aW5DQmVidDNqSmt4VUpCL2JrSnJMCkxkSkZVa1AzdWZGS3ZHOXp1c0d5Mm1hUE85M1FYQzF4N1Y0MzJDbXBwRFMvbTJ4dElxaVpnYWM1M21LRVJpZzdaUE84UlhER1FLZWEKODdVdzY5emMrZDVnRXFLWTZjNDNLSmVMOVBmaGZHRSs0bjdEOTF4V3IvYlVLaHR6M0xvRERvWU12a3h6aXpYS3pnazMxRE1IMjlCVwpvOWc5ZDQ0NE1JS2E2ZnkxdHFESTBzRGI3dGtvTzEvY1VLODlmMnZyOUQzUDNIRlJ1aXBMcCszOWNUREFjTzQxNTFjTXN0R1cwRjFrClR0ZzU1SG90MjMrR2hockZicmh6eVdHRU00VGszaFRVa2hDSEd4cGg1NVBydGRxVHQ0Wk8zL0QvdDBKVVNFSE5sU0hCS0dqVEdic2gKOVRwOExkb2hkdFlaUmpxbzM5S24wR1JwYnlaRnVCOHBybWlxZzIxRnZBNGxFV0hvQzJ3dXdpbDBMc3F0MU9EbkZOV1lrbnIwZWoyNAozQ2pHZzZQa0RRelJlRmJJWUwxK3BXZzFkcVZzU0x5blhEa25tRzFnSk1WK2RQYWFKeHBRZ2o0RkcxbWUrM1k4VUlOdU5tZ0hGbWxZClliZEE1ZzRmQTh5VVRsSE5SQlpQbXRlaG5uQ2VDald2TjlVcGMyYzBuU3F2b050M2Eyc1JkaERETXR6VEtjOXRKUGxvdlpvL2ZXdnEKN0MwZmwyMCtoNThYL2h2T2daMmpGM1pjSFYvMzlNS01QOE9EMDF5OVFRUWgyQXIydmw1YWlubWx1M0hCTkhTV05Vckt3NXhxMU1YbgpsTHQ3WTNiTzZPN2VSdG01ZTNzOTkrTkdyb0EwVWxMcGs2cFRNWlI1ZFBCaUY1dXpqZEcraHg3eCtVYUl3c2pwLzJwUGhROGdydDNyCjIzWk1kOFkyd3M3ejI2dTVWN2MzMVNsMnk1MzNseHNyRmZqV0Z1UmpXdGI4bGs3WU9ZQ0hhdTNwVzFPbmIva0QrSURCcjRRdjFMMlcKMktpdUpUWnJvR3VKbUJZMHFveGFJcmlIaVBxeGFZbFFxRUlWSnVoYUlpd090QmVPV21LejQ3bVcyTXh4cmdEQ0RGM1dXSFphSW5TLwplVkFsWVNKYlpESzdrdWlmUngzUmFVMUZoSmw2aFgrdjZYNzArS1Z0M2V1SXNHS1ZCYy9XNnJXZWN4M3h2QzlQN1VpcldpeDJPbUtuCnVsNUhzd3htVmRQOThNZWFjdG5yaUxUNnBDVU85VUpWbTE5dnExRkdmVzJnbWw3WDIzTGRyOTl6MUJIN3MvVjY3YTFhVzZmdmVkbWgKL0NtbThDVWJMQVdHWnpoOVgrMnB4WlNlWlhFbjRhb2FCRmJWREptbFVkd2VUZ3ZuVUE4N09seHp2YTFHc1hzNjh6RHFabGFFMXBacwpSTUxGMXVHZVRuRmp1cmtxVzczMi9LMnQwL2Y4UWJ6TEVldVU3bG5aQ0NqZVUyb1h0V0VyaEJoRkZSeGlvaVc3ME15ZmtDb0pYTHdVCkd2NEIzZGdjMXlHVGc3NG9HTlJqVUxhcElvZDBzR2hKa1dDRkxVWjlXZHJtSE9RUTRYekVacXkyR01JZXNPQ2djbUVxUURMVkxvZkcKMkd4TndLbHNVUkU0OHJLSnV2NmFpbDVadG5XaGQ1V0dYdlNyZEpiTmFhajRDVzhsKzc3cTNmQjBWVkxnaUlZT3Z4VzFHMEtJRXYzUQp0RHRSNFdUVENIUitLNEIycHZ6SHpVOEJ1Q0ttdzl3T0tTeTRnaEhBVm1HdkZxV2JMNENkcDlMbHVHSVJWY1Y5cmh0VTJES3JmcXhhCnN6UnJHbXlBd2hjelR5YUhaNHNXY05qVFJPcE1ORHFrNUpwdnB1MS80V05WSGNsRk1RSVVDbFdIUEowREo1cGRYQlUvZ2l1V3NoaTgKdVZQZGJJQlpRME92OUVrQnNKN2FxYnJpamFKekpDa2VaNmdubTJLb2VXeXJVZXllZW1XakpvTy85cmFpYnBYRFBXUGZQSWRuYS9YYQo4N2UyVHQvekI1RUNZM1pBd0Z5NkZOaW84S3BUR1Y2Q3dlTjhDV0tZU01oWGN6UVhCeVpVWFdGbmhTMWxVUnk5eW9Telh3ZDFrZjVBClVkcWFOQVpoczFEN2dDaW81Z2JYUHFDR3VHNGNYVG5vRWlCOEw1aW92VjdaSENxNDZSMDRLeFc2c0kwU1lEbWhnaE5xWDhpc1ZIbTEKVVdUWk5BbXdVMHR5R1pPK00vaWRrVnNtY3RvckRyR09Jbkl4R0FxTWZmcXdxeitzL0tHM3JMTzlwbE9jTjVRZFZlMkYyQ0ZnTHd5MAp3SGxiMjZBOWdmdndZU0crNjJ0dU5paUFYT2lnekI0RElHd2orVDA1ditlbHFqMUlybEsrcXlKK3RQVUxOcHBpcG9tUUJrMi9VdGxJCkVjMGNGclE1V25lczJhMHIyYlhCMlBWUzJxd1dDQVR3OE5MRUhseHJCRHVsUVFES3JzNkQ4V0VYUXdOU2g2UTFyczNzYUZQMGZLNmYKc0JaTVNRRFo4REkwbmIzYVUyVnJxWXVhUE5hbDZsZ3RzRGxpYzlDdWQ0b3VCK25vQXQ3WjZ4WDFwUTV0TlVvYXpIV2RtbkhVVlRnTQpiY0VxQkl4OHY2ZFI5TXIyYksxZWUvN1cxdWw3Tm9lYlRGdDZ0ekRmdVZXOTJsTTNOV01DckVLM0dPd0htWjZNRldoSTRsMk1va2lICm9OaWRvWjZzMTVoM2JUV0szZE92TkdveEMxZHJDLzVTbURyN1BaMmlWL3F6OVhydCtWdGJwKy9aZWtBR1pzdllja1g1SXl6eDFZNksKcmJuUVhEKzd2UVFqeWIyd0VnSFJDTDdpWjdyL2U3VUZ5ZWJTMEZTaitDMzF5a2FGK0VPZm9iY0ZLRVVKL1k3MldSbUZQNWRYNmkvawo3Wnk5b3I4ODdLMlZxQytndXBNNVhBZnFBdWxYb1hvaVRLcWpnWkkxektLeHB0SXB5bnRnMG9DSjNLa0VkZkd4dksyQll2ZlVLeHMxCm1tRFgyNElmQUs2SGZrK2pQTGVudFdkcjlkcnpXMXZuNzlsNklNRzlHeFhQSklxTCtjOGFGZlkxQ09IZ2hETm1uaXczaW1vQS82WjUKQzUzeTNNUVN1dmlIZW9CQndEdlltbW9VdjZXTENFWTFxMFZ2UzFnbjBKVDlsa1pRRjRFOW1GZnFMK1R0bkwzaUQ2RFBOd3d6ZGdwNgp2SGFnYm14VkszT0pPcW9iVzlDYTRTaHlXRGRNRXFtNi9kMkIzUkQwMWF2Z3lHN2dzRFBzYkEzYUhVVVV5RnNOYlFnQUZZS2tDZG5JCnNkM29LSFZvT3JnYk5WTjJINDJCdTJrR1dkYWxvN3NwNUFCMjB1RGQ0S2RwTzRGMzQ4MElXR3I0YnRqRjdFYW5uWE82RHhrUUduOVEKLzlwQnZLSERKRlZkREZMTm5Sclkwb2E4YnBUbjN1M2c5ME05dzNBUGJUbkY3K2xxa0ZHcjltSnJTdTVFSDJpL3BWTmNFdFJINi9YYQpTM2xUcDI5NVdUMy9ISGh2ZXIyaW96MDdWVkVhRFZ5Tk9TV1RaK3NZN0VaUmM0VkJ0WWQ2aHVidVRUV0MzVkV2YkZUWnhWZkNhbHRUCnhlekEvWlpsTUJmM1IydjEydE8zdGs3ZnNuRXptRzdoN0lQYUxwekNzQmVOS2dKVW5nTWlBa1hJS21ycEMrWkRuR2NQL3dpMnNjSm0KVzVaMUhlcWwyWUNhcmFWRzhUczZVMUlxVEd4QWVmVzJNS0dXYmJ5blUxU3MweWRydGRxenQ1Yk8zdkVITVUwMFdESFdFS0hVSS9TZApzaGhOaG81OXgwTEppVjR1QTc5RHgra2hrSTUrcHljUExLREIzeUhuYkNYR2puOXZGQlZ2RkFEZnF6bTJIY0syMmNDZHNvVlIzekVxCmVTbms0UWFDcDlDbzZvaWg0TUZDbTJ6ZFlQQndscXNLNGZCMjlENGx5RTVaWVdEd0t4dFZwSms1MHFkaE1IamdlK2ltYnpENFJsSHgKeDJEd3ZaN0QyMk14cEVHbnVObkJCU2VqaGl1Q2doMEZIK25tQVVUQVVmQkE1cXp0WVIwRkR6ZUUyc2tjQlEvM1FpcHI3aWg0NkJKZAorWEFVUE56c2hFODBGRHgxamhSVHg4R2o5YVo4TkJ3OFVBZTB0emdNSGlOQXZ0cHc4TmhJa0RqSEJDUUR3a01SWCtzQWhNZEd4V2M0Cm43SW5kbUJIaVdNUUE0SXBYdTJwb29MaDZPS0dPT2M3YndNVzNnaytTWWhmNzdVTTRqNDAxQ2gyUTcyd1VWMnhhMDBCT0JWSDlIMmoKNkpYK1lMMWVlL2pXMXVsTE5rbmZJZUtBZVMzQkF4MGR2dDZvRGVLTzJVOW55VURKUThoSHA4SndCY2RmYnd1Q05tRS83WjVHMFNzTgp2ajdVTTRqNzBGYWo3TzdacU8zWldsdnQrVS9mcy9XQXc4VXhkOHJpMXV0T0ZSWkdJSXdEejBXQXZab0pyM1o4ZXFNNGF5S012ZGR6CnBIdHZxMVBzbnMrbkFSRlAzWVNHbE43V2JHL1c3MmtVWGUzdDJWcTk5dnplMXRsN1BpN3hmZzVjL0E0czVzRDRoaFZyeVBpR0ZXdlEKK0IxV3JHSGpHMWFzZ2VNYlZxejV3M1pZc1FhUGIxaXhobzl2V0xFR2tOOWh4UnBDdm1IRkdrUytZY1VjSTcrRGlqV1FmSU9LTlpoOApnNG8xLzlvT0t0Wmc4QTBxMXBEeURTclc2NHhRc2VhZWE2L1E0UElOSzlidzhnTlNyQUhtRzFLc0krWWRLOVlnOHlOV3JFSG1HMWJNCklmTU5LdFl3OHlOU3JJSG1IU2ptcVBtR0UzUGMvQTRuNXNENUJoTno1SHhEaVRsMmZnY1NjL0I4dzRnNWVyNUJ4QT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJREQ2L0E0ZzEvSHdEaURtQXZ1SERHb0oreEljMUJIM0RoelVJZlhkak80aCtodzl6RkgyRGh6VVlmWU9ITlJ6OURoN1dnUFFOSHRhUQo5QTBmZHI0V1QzMmdCam5mNGNNR3FtRzZHbmk5NGI0YXhuMkhEMnRRK0Y3UDBmSzlyVTRac0ZvRDFUQmRyYTJHKzJyMzNPSEQyck1OCjlkcnplMXRuN3preWYzcVNkdml3Z1dxd0xvZXlPL0NyNGQxSGVGaER4ZmRhaHBzZjJtbVVBYTAxVUEzVjFac3k0RmUvNFFBUGEwL1YKS3JYbmJ1MmN2dDhsOWJKN0VtRnVFeFpoOXA1R2hTV2hxSlNWeVZBS29qZk0rbElEVjZOUlZQMTNMdC9yQ1pkS1N4amJhaFM3WnpNYwpLRlZXRkZqNTBKWnQrY005QnlGZ2VEYXYxNS9mMnpwN3o3WWVQa1hCUGtuWlJLMHVMV3FjS1ZqeHIvYlVvRkUyc01VVUlDWXhXSE5TCllaZTdmYU80RWNhVXFWWXZHTkNsTjlVb2Rzdm5ackF6YXRKZzFhR3RqTDA5ai9jMGlsN3BqOWFxdGFkdlRaMitaZS9MajljdjRRbWMKaStvY0lqT2FOTnFwc0cweGVRV1E1dGloQVRDbjRKOW5VeVdkb3BxWEorcG85UmhTbDllaHJVNnhleXBIZCtvMksvUzN0eVdVc29IUgp0SHM2UmUvcHo5YnIrZlAzdGs3ZnN6R2twWnFrZ1kwSEMrWFZub3JlTmZUWmxyT2xEZ0dDT2VnNVNGdW42SHNBRDFQaldFOTJHaHBNCmUxdU5ZdmYwUGExUjYwb0luN2NGQzFvZDdxaWY5U3AvTHE4enZJKzFjdnFHbjJVUmh0TkZLQktZK3RDU2dvdGU3YWtBUlVIZGh0MlUKbnRNbFdPS0poSEF3V0NxZDB0YlNHdU5ZVHg0Z09pQkQyMm9VdTZlYmZScFZrMlMxcGhiR3Z3eDNWSUl2ZTNzd3J6VzhrYlp6K29xOQpJejlCZ0QvaFpxcStNUXJUUWhkZjdhbUFuQ1dOYjlaWWRCbldBbTgrbFhNSzRFNVJaVzFXQ0VhclZoMy8ycHJxRkx1bE8zK05LbnBWCm9KempUY0hNYWlLQTNkRW96MDNGdFNkcjlkclR0NlpPMy9JSG1aU3drTUJQTEtJL3NqS2FZOG1KaSs1UzhQSFVMWVVEbElpcU9oTTUKclgzV2R4SlpyOGo5V3AxVlhUaTlFU2ZZclZ3NVY2SXM1SVZPY0crbWFMaEV2MWNaSXJYYkF4VVBxdkJIdG5iT1hxeTdVcVBxd0JzQwpXdHlQMklqU1cvT3F6czhVNVRFMlROaWtEbFdxc1U1UXhycXBBdHRxQVk1UVZRUFFkaHJCN3FhWE9SR1RBeXlwdFlQMXMyM0QzWXpnCnJsZDlwbGJMbjlyYk9YMjNIMkw1Y1p1RnlBSjFnMTZqVjNzcTVMdlZRbVVpSEVGUVZPYW8wb1JtUm5PSzg3RTFwVFRXdzl0dmVXeXIKVWV5ZXpzZU1XaFRTUGJSVlRhem85Nnc5c2Nid2JLMWVlLzdXMXVsN2ZnNXg0cVF2WTFZak5PVnRHRWRmN2Fnd3RzQWpEQVZ0aWJPYQp6U2hmUnpldkdFRUZUcmpRbG0yb05hdTNiR2pJS1g1RHZiQlJJOS9rMEp1aUhTZlY0WTVPMFN2OXdYcTk5a3F0cmRPWC9DRmtYRERPCjFSTEdCTWVJZEdJMFVBT2N0VVFMdG5nMm9GRFcxQW1xd3FVclpPa2ZxMkdOTWF0SGE2cFI3STZ1L0JrVnJoRmlIRnRiU0Y0YTZuQkwKSStpRjdjbGFOWC80MXRMSkszNytDVWtiekd6eDFMSkFISVBjcURBMlpaVzNwQTIxQjJyd0hqeVdXMW83UmQrSytYTzNzZDVNODhYUQpsQlBzam43ZDdCTnlKZ3JVR3hLS2FORExjRU9uZVAvcmcvVjY3ZUZiVzZjditYbTJWaUI3a29hK01pengxWTVZUFNuQmF1WkR4dm9zCmFzOUZzdjVPVWVGaThVeDhyWjVJV1VncU5MVFZLSFpMdDhNb1ZmcU11ZFI2VzNIV3dKOStUNmM4dDRmVlordjE3UEY3VXljdjZWMzMKMmNLNkhnL1grbHcrUTBBamsxbDhHNW9ad0s4RnE4N0J6UEtpY3dIT3g3SE1BR1Zsc0xvUnlsd1JlMUZ6UnpJWEdyaFNCeklYakViYQp3NWhsN29zUUVEdUtHZWtiS3h3TURtSmVrWU9CcU9ZQnc0eXdyUlhENHhCbUdFcm5VanVDR1U2SVV0SWV3QXl6OCt6SUp1YmpKVVF4CmRmaHlKZ0I5RDE2V204MGNhY2N1TXp3eXJoMjd2QUl3UU4yM1k1Y0xBVnhMaHk2WFRkWXRzY3lHWEthSVRPUGdBRnlHQ1hjcnk5cVIKeTRHUVF6cFV6WWxJcE15NmJYdnNNdEF5RWJab2h5NURGbHRTQnk2ZmpmYmU0bGhoZEFZYkdtSExuV2dXYk9SZDVDZzZHQmtoM2FtRQpQV2E1d0Erd2JwMVk1TmtxRkZadnB4TUc4SEFuR3NhNHQyTXc1SDYzQWEzY244bHJ0YWUyZHM3ZTdYSC95aWVoT2VJZXBReUNBNVFoCnpqZHdjczA3V0hKaHJFaHFxR1RoejhpQzB6REp6Q01UOTRoaytEK0M1ZGtqSUJtaWN3Y1pZMmFqaVJHS0xPdDNnOTI3RVJOU3hBMzQKWWdRZG5XQ1EwMGlaTy9CNDNpT081dzQxQmc2NFlzY3lwSEdFL25HQ000WUMzVEhHMFI3RGtjTkltclN1ZTN6eHdpeDFuWWFFNmRHdwpwUVFYTDliSUNDMDJkQU0vWiszVEJpa0daSUJaT3djM09lWmZ5VXZIRTFkN0VrY1RZeDdOS2V6QnhLWGF3allzTWZwbFJCSXozK3k2Cnh4RUxDOGtobEE0amhqRjRYVHVJdUJZYnYrSHhBZ1BiNGJweUNERm5uS09IZDlOdnY3YkJjaFp6ZmpYY2NDY2ExSmM1aG9BUmNqUXcKbVBFcFpoaHpjNmtEc1FBSEgwSnZwaE1HOEc0bkdzYTN0Mk13NEhhekFTemNuOGlJL1ptdG1iTTM4eGVIQlMzbnZBY0tkNkpqZTJtWgpIdEMvQU9LWEU0eXdDSnNsYkNORVdIYlJkV3lsRVhZQVlTYzZwdGZiYWJCZnU5a09IR3dQNUxUK3hOYksyWHY1Q3lkRy9BNGczVmNqCjBiRzhXRnRrR3c3M1RjamFXOVk5S2hoV3IxQ0hTdGloNktiMFpwd3dJblE3MFlDODNvd2hmZHV0Qmpod2V4NnYwOTdDMnpoOUxYOWYKNUdJSzg3YUhBbmVpb1hmUmoyR0UvV2JHSGc2SVgyN3h3UHBUWC9SYWNFMVNxL1IyR21FQTVIYWk0WFo3T3didDdYY2JFTUQ5bWJ4VwplMnB2NS9UZC9LVmg1c25NOXptZ2Z4dlJFYnV5T0xiRVBEWUc2b1hwcWRCelBXQi9oWmt0c1F4RXVEZDVpbmhyeHdrakVMY1REYS9iCjJqRkViN3ZaZ1BwdFQrUjEybnQ0STZjdmRza1pCcWQzWk9ENUNCZnNWQWY1SWE0MExCNGFEQ0NnN0w0NHIydVBGNFRmT1pUWWlSWHAKbGJjQmQ5Z0lJM1N2RVIzaDE5cHhFR0M3MjRnVTdBL2wxUDdnM3RMNUMzNTJyZUtqazBVODhnVEw0V2UvZVAzdXdpRWorUFhzZHk4Zgo5RUYrK2ViNVYvL3o0Yy9hZHA0UFAvdjF3N05MUjVQY3ZuajExWmNQYjU4L3ZINDMxSC9zSGwrK2ZmamppNGMvZmZYck4zLzYxbDR2Cndac2t1dTFqTitDWkovLzk0Y1h2Ly9EdTBRN3hxbSsrK1VvNjh2N3RtOWZmVy9lWEQvLys3c21WOFpMU0t5OGV2djJBZDd4NTg5TGYKVWNPNzF2ZS80Nys4K1ByZEh5Nk81WjJla1hQMyttdTc3dUtaT2YvanhSOGZmanJwTCtwWHE4N1BsVEhmVURLMnFxanBXRU9hTHA2WApvd2pwRHpzMngyN2xEVGVNMHU1MlBQZW1VZHRqL2JKZmY0bTJ1L292Y1dvT1RjbXlJOHc0ZGpndU9HVUtta1VOY2RZemlhT2ZTYnpzCmtxbGt6ZFdMVklDTFp3RUhFZUlsc25jamxTVUlBUUVKY0tHck9nNEwvMXlWNEJpa2hmaHMwR0tsSlhXMnRpdHlWS2s5Q2tkYmdkZEIKcGJtWjFNQWVxZHdGUUJJWHVoY1RzamdWWkdHQVVpL2Jjb0g1SElMdzRyWXFwTUFBbEF6RXpZNUFJQ1JMQ01haGhZQWRUd2hFQ3JYTApBSHhFcHJHY0ZiMVVlQUJLTW0wUFFnQ1F5U1NrMk41TTA3d25XSzREUmFRUTRERkJSbFB1blRRZndpa2dleXBmVFBiakxVY2lsVGErClBXQ1kwSjQycGtaTlNtREdOeWhmaXdNZ1IrcXlCcjB3TFp0U01zY2pCOHVSTmRQZzFxL01sWHRTbE02aER1ckNPK3BsQzhqU2pOSm8KZlZsdDVKQWZIRkVIT1BNcGE1Z3dqVjNJTmJGcURpOHEvOGh4c2phaEUvRVFWQVNRMVduVkJLR3NGdVlrMG1wV1ZQVUt4QzhzQ3lVNQprSDlkN2ZRSmhycXV3YXlyVEdFd3cvR21ZZGg2bGdid0RzSFRicTRPZ0E2dW5hL29DcWJXZzN1bExrWlpsQUl2Uzd0eW9TMDA0RkN4CnhZelB6QlNNL0ZrODFCNzNaR1FXS05HTkhaQ1VWdGVKbzQwMkE5QkpLQ3JMemV5S3dQTVhITThUVEVhUVd5NDBCcFZWVlM1MHh4S3AKeUsyVy8ydzJXeGpuRGhDTUplbjRwbG8xbzF4ZE1LUXp6RVVLSzAzSmp2TGdZS3N4RWI2NVJlT25Tb1FVeE1Tc20wbzdoY3V5MnRJaApaZldIQlZUT3JzdXNvMWthMFhyT0NtNWxQQVVvbEVuMEtoaUNZRUxDaUZkRE9Hb3l3aG51T0xpenEybTBHeXpwVXZmR0wxeEVLOTJZCktGNFJlbWxHbnBJTmpuVUZqeEUxaUNqL1pmV0FOc2o5U0hFQ3d4YVJkck9HMUFCd1hLTTZKWm44aExoQ2d4V1F5T1M1Z0JSR2JSdlQKa29BNGpkaWJvZUx4OCtJdWF2aUFnV09Vc1Nyb1NuajRrSWR1WTlwVVRWT29pVHZ4aFkwZHN3MGtwQkNHUGNwRGxMQzRLck56V0xCSwpLcFZLc1Bja2lVaGJCUU5mWkVqUXFtSVpMRExNSXh5Z3BraUhnckNHSHM1RUhBS0lTTElubnd1ODUyaUd3RU1RbHFSWmZaMVRhSEJNCkptZE9jektJUGhLelZXWVZEblFKVjdQa2dRUG9teVZDRUtEK3pveFhxMW9IVm9scUFMUWxiVkN2UXpJWEMybEFrWlpaRnhrSU5HTEQKdkxJQmpENzdVVlpDV0wwN1pvVFV5N2NnSnJ0TWRJRmx1S3hxaGc1ditMbDF2bXpWdEFnSERDUkdkczB5VVdEZUsxa0JDclRzbDAyVgpQWDJ6b0hjcmlGaUpodXFFcmdCblJad1YwWmxnZlFNY2YvYjhqQ0RTbWdHZ0g4NGdtMjN2RW9Md1REWDVzQjBRaHF1WXZYS0ZsMVF0ClFGUkRVQ2RWaS9xck9HNEx1NDIvR0x6TWtYMnJRTmd0Z2FGdVBHbGkwZkJsT3VIaGNGa2RoRlJ3N2dOdUJUZ09RL0ZocXlzOENhdFoKaUFQU0M4SlEyeGdYaUZIbTRySnFYOU9PSFBWNE9OSFJpMEduTnhKd2NHWmo2d1ZyRVVUYVZ0ZFY4MG5pc2hLTXdMdXRnRXZIeGw4MwpwTENVM3l1Vk9SaXB6Wklyb29vNllXS0JwU3JUa0VZR2doRkdzdUNLclhkVHY2MXM5eHpZVEIvQ3V1cThLZ3c2eXJZckY1czE0WXBKCmgyREh0ZVdoVytZaTAzTUxIRUx1MHJyL2J6QVlaUjBpeS9QRzhFV01ZU0U4QjViN2xXTVdRdW9DRWF6dm9JR0Q4Zk9zSXkyclQwRlEKekdzaGhGUWNrdDJhUWk3MHF2anBLdXVObVVyMWtUZlIrZkFLb3RzdCtsN1Nvem8vbUNtNDBMcTNJR0VpWEhMWUVDRENWYVo4WHRlVwpBMTYyTFRoYVlSU2UxYVBCWEZFRjdHSFZKQzA3NlhCdjZxTUVBTVJUZ0tYYmo0OVlORFl2RW1uS25UMXVBQTBIWktQWHdHbHVHWkg1Cm9HT1RKVFFrV0hnbHVEWUpnTVVqYVJLRkpSQVlFeHZBbFQxVUFpbytUWExZREt0NktXWWVMb1VVNWJySmg1bmF1QktlbXpDZnNNQmEKTGFUY1o1TE5ESjViTlVFZ2pLNUpYanpZbHNVMWcyaXRUUmMzd2QwTWg4VldZNEg5QkxkRktFMk82Vjh0a3hBeXFabllNVmZHUHJYUApnY0Y3aTVxblhGclJTRkhJUlVWcmFXd3F6MmhSdVNjdWpHMFJucHNkZExocUFpZ0UvWWFzdWhORlJ6cXY0dkFaWndPRTNDUlZTRm9MCnBNdW81ajZjTTR2TS95SzRhbFRhd25QL3pLeWdqNWhvZ29hbExVZXpWaUVWS2dpMFdVQk13bGpncXRsVDB5UEFEU2RVTWRlTkdibDQKWHVFQ3pxblpGTWo4MHFMN29MNVhWYjh5WmpuTldSbHhYWW5aNFkyelJIV2VZaDNYMGlXM2pkdXNlbVR3RVNPQlBLRTBsNjRRZXlzMwpTM29yL0NJKzlycjVlMFFlZW9iUGVWVmNRMFpPTFJEbUpuc1huVkxJeDB1K2duRVNNUVpwK210U3ZxSkhCVmExVHQrWXhCN1FaNWxLCmtPSlhaMGhQMENMSnhCYUQ3Qyt5V2tTRHM4dG1qZFNqWXBBTVRJbUZpOUN3T0d0V1gxMzlRZTJnejkxZWdhZ0VFQXR0VDFWRGQwSEkKbVBZSlRrcnNscGl6S2JUTFpvQlRzZlhRYmdZQ1lPV0tWOWU0a0FCeHRjejZic3JHZ3ZYMnFqckVzbWlpWlRoVTY2cm52N0dMc1BpMgo1SHpNd1ByY0hDT2RRTVVlVWZSTnkxYVhjZnFnRVhndldjZ2JRazViTGNTWFluOGk5d0dEb0swUHZwbEJMT1FwUE1KSVpXaTRPTUFPCnNKMHYyYlk5NW9TS1BPMGl1V1FDWW9GUEdjU0VaR3VJZ2VlYVFseGtVQUpqN3hHSFZ1YlNMbU5LdkdXeGtRVUIxZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJSS9aTDBDUjNqRGNGb1hvd1FWQ1pLek4zY3FZQmxUb0ZHUVJkM0ZGUHZnRXZoaExHWGhUWkVaN0ZqRk9HWm0yNkFNbTlVTnRWbTU5TQpQdDNRRzF1TWxmY0NqVXNST1JXd1BFQ29ub2t5ckhtL2ZZT0ljUVlNZUU3WmFnVVNSSWpRM0d3SURNYm42cjJJL0FMZ1o1aTUwQ2d4CnJzd2dMWE9hOGtzbklDallkOVJHcktiK01TNEFtK1ZNK1JkQld5cUI2V2Vkd0NZcXRUcW1vbENKWnk0eUovRG9Fdy8vTWlMc0VWQkkKTkZ1cE5MMUFyV01DZVp1S0N5QldwUjlic2lFMWh4RFZheWdxWVZseFVDM0VIR0JMSVRhRHdhQS9NQmp1VVpkbkJFMGtaOVhxOUlqWgpZajZZdWRxeE9BVWRWOXBWaEFtZ3FaeFVYU051QW9NUnF4RVFOdzM1cmpFcjVHaUFNQXVuN0x3YXdoWkhDU1RxUlNvSmtETXdwV1N5CldSWEJ1bVprdmI2YWJWWWg3MnMwaVJ6TGlWeUlsaGUvRjlZWTVBRllYbGEzUkZma1NDNG1nczZXa0JLWGJRNjhuemROWEFoaXBHSzYKRWIrRjlPTWJkRzljQlFzTXdzLzZhZ25ndGppMDFLM2kwSldnVFNKbjM2cjRMazFzdG5ZNUhrTk5TRklzTHBjRmxRcHhIRTNRcEtYYwpiSG5hVURJdWpEZzNhS3pZYklzbHVTTjZPTklVcFI3eEJkQU9rVm0yWlppTkdrT0VPSExXNFZnQUNMMmdWM0VSeEdHaytVN05ONTRVClRFQXBLbW5lTHoweU9xaWV4MG5PZk9LQnpFeFo4T3laQ01BanpGdkc5TzhJbWl1YTlhYXN1clBQalhzNEVkbGc2NktJLzFVVHB0dVEKTVJ5VG92b1ZqcXR2REorVENLR0lxMlZaMWJ5TnhUZ2xDSHFBbEdwVmZobWxmYzJkWWZsZ0dlcGZiTVBGM3Nma1RnV1NrMGNZVURLRApxVUoySnd0ZzVBR1ZjR3U2U0w0aStBOWhqMUQ5Zk92VWVBK2tmY3FLdEZGZEI5YkNUZkc4ekE3dkJGZHRhTG5zdFRZMWRjR1dvaDViCkl5REdLM3RZWHlQQ0pKbzFsYURzTUh4SW5Xa25JblJ6S1NOeGt5YUJTenJsTkdlN0IzU0ZsVllnaEpQektFL0MweXBQbHkvS0FaajYKczZxeXhEQjdIa3dRZzJLZWtCRlk4NmtqNHBEWitiT2RneEJydC9HQnV1YWdySDlGZjRHU0dZUWR3YkVRaDRSOG1Nd2tBTXJzUnhvdQo4RSt1eS81S1pyelhPMVM5TXVwSlRnZ0x0QVhDTy9CSUw3cXE3Q3dCUm90aDkxdXh4d0J6VEhRcldBNzJBYjVscWhhbmk0U1ZtNTQ0ClFPY2k0S0FsSVdtOGNJdEZVMWxYYllsM0JGT2gyNXh2d0JnT2c4ZVFzZ1E5OTRDSEl1SEN6WlBKQU9hQ0JVNXE1b0VKWEZuUmtvTW0KUFJkbFcycngzYlBmVWZHbXEvSjNWRXVjR1h4V0tGQUlNVTEyZWhQdEszcGxVS2xKeFlYTUNMcUVjRnV5NDhRVEJUSmtSWVY5eHR6eQpmeVl6aTJJOVlESUNSOHk4M1VoM2ptNUdWbFVhYTVGUDE4MmZpTFBUb3luQTloZkdzbTRhNlFJS2hWdUF3dFh5ek9UcmF3OTVVWE1xCnFNdHFvVEUwcGVJdDhxYXdjMEtLUUtHVzdsZFM2Z00xYjhndmlyWjRZQkl6Q0ZXTjR1UE1URHlDd1pQdDRRQ2pXVE9KeHh3dDFRNE4KM3B4anErWUYwc0FCSlBpTTdmelh0cEt3c2RCSUNHc1dQS1VCRTV6V0hNQUtvU0dGVmYwZ3o4MHNwc2Jhc0JydUI1b1JKVU9leWFmUgp4bnhXbVBCcTdOY3RtclNYWmk5V1VuQU5USFl4V3Q1SENxSlpWNExiajNSNEdZU0hidVZwa3BzeUM0TFlFSi9IblFkTFlZVWdvR2F1Cll1dUJ4d3hpR1NDUkdLTVlFTEZjR1NNY2JNV2owZGt0OXJCd01tYUduY0lnTmlna1NUZG0zWkZ4RENWRHUyYUc1dmVVaXlLQmE3MUkKT1hjek9ZcGJlc2xHNFJTR2xMNzU3Z1UvQ1RHNGNGVkE5NGw2Z2JvekNINkFrVlFHZDZWem40NXh2aWZlUGxmMVE2UjUxaXMxSC9ScwpFZzRNYXJTM1NnL1E2dGFzYkJYbmJtNDAxOEV1eUx4WUc3UFJHcUVtaG8xdnZwWm5TejZEb0JreVpiUkNDekJCWjVadGN0Rmc4N1ZOCkd6Z0YwRkpXNlFHcG9MZ1NObU13V01iVU16azJhN1ozUXdwb0pueVpaelVQWVQ0anBuSGpPWWNhU0VwbVR5U1pzemo0UWhpbEg1SHgKSzJzVXVaMGVSZTJMQkdSVVFZUitzY3d6SkJKM2dGMk5TWnV3NUMzK2ZsMDBsY3MybDZLRTBCZFR6WHBvZEt5enZoeWNGWnM1NXhqWQpnRFd6QWF4aEJoWXMxWFhORFBkUksyeWNkUVV5RGFqMUNHWmhTU3FINkpMUHFxUUJGTWk4WG9oSUxmb1p6ampHMU1OMXdwaGpQNWdLCldXZXBNU1owdzhxRVo0VFpBVHFjRnczRnA0a0JhUmFhV1RyaTNFTkNVK2VDOTRMRUNJNVF6VlRDWUppWktkZ0p1dE1oc3h6cU1GOFcKTytXYSt4a01uQ25idG9RRnpIdTUwd0tpTHhRUUVHZWVqRlBVRmtCME16OFdlRHJ3ZlV6OUlnb1loYWNNYUtML1RXWWpDTzFlUE4rQgpXWWg4ejRXcEI2dWVWbVJNdmtVejZXd01EeEk1QS9ZaWZCS0oxMC9ScVhyTVljSkprSmxWbUU4RWVTQUNSRlVRa0xkemcwSElNOUNSCldQVm9NOWdoMlF6Q2pYQW9PUUdSdUJVaXZkVWg1RGZEdDVHckpSWm02ZHJVMUVaemZxSTh3M3hBVzlJS0t2WlVOWDhqeWV2TXpNeVIKbS9oV1RRb2lSSGlqMHltN21RVEVpc1RNSUdZNFI3SmxLTjQyOVJZUkMwQm5hSEY5bGpTNCsrRkI1VjZCcHBtdWVtYWMya2JLdXRveAp2OElJL2MyQ0JaWWhXVUtraFErdVVtRjNZRG96N2dmTk1XN21pRElIR2tTNnlMQmlSSEJ4azBIZVhjbzJ6TGNFRlFQb2NUOStkcXZ0CktKM0lYQlB3U2dwdnJLeEdHQU44cjdCQWtzQXdrVUFvUVd6WDJlbWRzeHBwMlJLVFo0S1hzV3R3UjBaSGc5THVDT3VGWmpPQmZvYVYKdmJqQVFIeDUxTnphVEpXMVZiVkNxa1NYZFlyakphbkI2Q0ZTTVpxbVd6V0ZsQjBTQUVPcU0yVjR0UFVvY0lUSll2WEFaSWpnT3owRgpCZ3VJWnMyc0NTbGxoZmZ6OGJLZSs0aHpXS3VlbmFWcHYxblBLRVhUelVXRWZiUUw5UnlVZ0FRb21GNmdLT2dxS1pEdFhLeHZBais0Cjl1SUtyMldnaUE3ZkFpQVJNUWNnTU1RZ204aUdjNC9odlZnUndPazhPNmg0QnNPYmN2WkF2Q01QbUxPTHVCMkJrTmJVcmlLMEY4UmcKMndnTXMyZ2FXamsvMDAyMWRsV0ZxUWZnUTRlUkppZjFDV3E0dzZLeUZSMXdVanZ4R0dNVFEyaC9wZWtuV01UaEJ1NjN3cDVnc29XNgpyWXhBY1FENVQ4eHJxcldRdlFGOXNVTEsxZUFqQnZjai9mcnN4a3NRMGExNVZyQXJuRUdZaW5sV095M2NJMjVnODlQc1M5U3RFYUgrCk5PaVZxT1l6cTBTM0dseE5hTFRCQkpDSkRkb0hnSm0wK0RMN3JOcW9hWFpDVkN6MkN2dXNNbzZkZU9kMW1PY0dNTTFnRVMxT2dGcm4KUGRGb21QQ1dVSUI3c09nUUZGUGdyS2NPNndUdHdFUTdkcThFWVVmZUlnRmNEeE9URTNCMFc5NWFyeXNOTzNyUndDa0NTUUgyaVlxcwpwLzF4MlpxSEV6U3VidEN5T2NxWjBCUnVNNGJLZ0lBdXhqay84M0RaU2xWOE01c1Aya0ZjTmpZakluZVJ2MkhUeTdxaHVTN3FoUWVSCmJqYmtDZ3c4djdxc2tBMEw3Qmx3Y0ppcmdvWUFnSklnSVM5dUNnR2hiZ3pVS2ZRNEZRckF0TEtYNHNlcEZNcS9CejBpYzJVbDJveHoKTk1CeHNmTVFRU2d0Z2Q5bWJ0ZG8vc095cVdPTkcxTFFaeVFPQkpmTjN2bEZoWWtGY0I0SWdpMkR5YXFpSHQ2VVo5WnVDbjI1c1htNApZRElnQkZMdk5Xc3dRSXFLU0NOaFU0UDE3R0FIbU80aFZnTHZ0M3JVSVNBUnpEdFFOR2ROVXV0MDNQcEY5TXZDOGgxV0RTK2krNTFKCnZQU2pNR28yMm4xMnF5WVRTY21zUy9CSkUrbXp3UE5UdEU4NXl0QlQzZnNHNkF6U1E5RTl0Rm82R2pBcytvOFd2WnM4S1M3YjZPL3gKUjZSZ0E4OW1XdFc1UE5QS0xmMnRjQ0VMa3NRRWIyZHhnd2cyZ2ZTSmpBb0FBYUtvaHNJc1l6dVp5cUhlemR5WWNQSGxUYk4yMGVzego5K1UvR3dCbVZpdEh2dEtWeDM3RDZXK0VhU0VuTURkcEkraTZCNTlrRWtlcnRSWFZ3WkRES2xkTm9FbVZTWGFaa2p5b2tVSTNUS2ZxCkdlTm54TWtqdjFvRkQ5elV4OEF0MXAzUVc5S3NJTEJPWmp1NmsyWitaREtqcTJxemc5WVQ1WDduWnpBMzg2MW1ndmRVOHcwOGtKdUcKNUVhQXM2WDBJenVVdGhsUWtEcFE1Und1SmVpT1VQUkFTZ1dBNno2Q2ljMHNpNHI0aHBiSGhSNGRmb0dVdlp2R1E5RGE1OG9KMVF3egprT0d6bmtRQ1FZS1cyRVY5bExocWJrbEtrUU5uMDZZb3NEQXpHNjhpdStmbnhPUndNbnRyVDIzS1BRQkdGRFVxV040eDV2VW94VUJGCkdXZjZJWjR2dHplclNMR0pFS2pWY3FwU2g0SG1VSG5HQzRGbTdLRE5UNXhnSmhYVVRyb0I4cEFxb0tXaTZVdUVJa0UxNUJIcUxvSEMKOXFnbitITFdzQlk1SWV3akJDeEZneHZDWlQwbnZ4dmkxakxqTThpY296bWRSR2FqL2ZCTW9ybVpIazJ0TFdNYXFpWkt3RkhwczhhVAp0ampTTmNMSndUT2xrRFBCUXRGbE05N25TQ2dha2djWDMyeEhncE5JcitOcUdDWGE4UUpycmVDOHRNL1Y5dEcxUENKMEFJTmNGOHQ4CnpLWVRBNGMwYThKR1R5RVd1cW12UWRWK2VHY1g1cXd5SFJQUldKVFFreDI1dFl5R1Vod3FzNUMyQXFqQnBFdXpFc3lBYU9rSGw5RisKdUtpVkJpbUI0ZDlrMC9EWmd4QldKWkEza0ZDN0RaQmdNTFJOTUZiUTdIVTB6VUs4aHBjSmJoK1lwOXQ3bWN3Sk9TRkZtM3FLalNESQpBRE9CZkFsNnJyUENrWWo5Z3A5aGVPZnhZOFh5SlBESTVFMFhsRisxQXRVVHpTb1RtZTBOWjdwdUNvUWdBYndDUnNoNWRURjBNOXhECjBPVkExQnNNamN4RVVUVGRGblVvV1hmQjhRR3doOUUyU0tzbHN3QXVXZ3ZaekxkcVdTaVlNSFV3aUFLL1JkZExNcUVjK3RhcURodGQKQ0xObWN5SjJaZW5tSG1ZbjRacGNOTHRYMVJNN2RlR3pCdmhRNUVSZisyV0V6OHdHaXd4bVZFWDNMWXZkRFh3WWhPUWFGeTJDUERwRwp6WDlNdU16emUwSFE3QjF4b2ZCOTFYWUtzSjJDUXl2QkpyRHhRdEtrS29xd1NhSk9ZR1RpUTIvcXpPUldodWhpV00wd0pMQlRBUVBLCnpJTVJjRXZJSjBoblNWQlE2c1kyRU1uazBJOUVCZ0Y4dUhLR3lZNjhhZ2o5eWxSdnlPYmJRL1RwZjRocW1XQ1lQVStjVFlvSUpTRXgKcmJaMnRGOUZOekVHRml1YWFUY1pseG9Ndm9JRFkyQW5nU2RzZFZrS2x3VXlhd1VJSTgwbkRJdUlOaU40cDVobEQrdHh6aDExTjhOTQp4VVc2YXBZRldnMnh0TG1kTVN0Q1prUWNoWmwyR2JZemdLNW1WVlVJU2t6R1pFQ2dGNUlFOTB6aEZIakloUERZRWhCUVljZVR3Uk8rCkpsdUdKVU1HeW1IV2RjWVg0em5TOEYxbU5RTEJMMWF4Z3VEdGhyY2RmakVDeW9CVkMzNVVLb2haRVczcTBZUDNEQ1lwd2lJWHZZeG0KQ2RTQWdPeVhFUkVBWXJXazNCVG0xbVIrTVJBZzZSTTQ2VEpwUmhiQVRLNUxwQmloWS9BWE1TYzFVLzh0RGFIQVphN3ZWdFVwQXcyRgorb0NpNnhaRzNCUGdCSWdQdkMvQWUzZWNWcVRXc0FZREpPUHp4cytLZWxrdERuY05LcmZxUlVsZEpraEFIaFlGUFJGK1BGNG1mQ3BxCnV3M3l1REo0WDFURmpNZDJRVDlIUTNtVW9odHVKdGR5alNYb3ZmSmlBYjFBWmNKQUNLOGdnN2JYVE1WNnJicDhuOXRJYzVVQkVNeGcKLzlWMkpRQ0NpWFdEUUw0cVRxbzduUEdFVldHUnE5YWhWN0hCSkVFb0NsZk9jenZTYVRZVmZjWnkzNmpWVUVLam5ZMEtTOVUwRG5sVAoyNFFLamFwVHJXWmQxRlBqWU1OY0ZWeEpOQzRVUXpDSTFOd25XWkdyWUNQMG9PRVVKZHdkekFiVEJRUTZKRUJ3dSs4TVVLVThMMmcwCktNMW1aVWN6MVE1ald2MW1henRVYmxNUElUQmZ0TmE3alI5Mkp0ZURHVFlNRnp2ZVhUa2o1bVdnOXI0UjFLMnVESTQwYlZYY1REQ3IKOHRhZDFKRDJkTTY0M1h2Vy9HUU5JUnd0WG9OQnk5bWxscWl1eDlVUVp0anRaK0JUMXVyaUgxWlg1bHhZSGNjSElrTjVRT1ErRkZOTApCWUJRSVNVczJyRGJJSHBUT0hpQlFnQU1Ld2liNWltaUZqNEZvd21PdG9lblZVM2hhNXNoS2cvVGtWczVJU0xOVGdtcG9BTEJPWTNKClVXaURHd0pFTnA1cys4cW12WjhKZjI1WHV4QjI5Wk12bURGUFJ2Mm5oNS85NXQzYkY2OS9mL2pKOFhqOS9QbDNydz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJZnYzbTNUUFUzY1ZiMlVra2tCWUllb0JWRkZhTVYwYXRqTU1Jczh0UXhiTHVoRmxSZlJRUW1DNGFsbE1INzlCVVJyd0VxSFZSUVlJWQpWNDE1TVZ3K3BWVkd0NFFXenJBcXVnOVd4SVcyZHQ2VFVUQlFDVGN6OHFuUDBTZ3FUbmhpNGw1djArbk8zQitxTkxrakNzZVpGUmNDClZ5Z2U2b3dqMjZEYVJCYzVUbFlGcTFmRDQ2Ymh1bXVLcm00Rm5jdzhNSFpXVVl5cFRFZ0lSaUVPK2VUQ1dYZE5VSW1uSVNXdmFqVzIKSUltZ2dSdWcwQVRodXBxR00xVUZEK1BwS1h6Q0dZbFo1NThCTEFkRGNUbDNnYU8rRW8ra1dYNEpxWUZITE5zNEZzWjdsS3VtOHVyWgowSlZFNHZoQXdHRGpjN0JSWllRU3JscVczSzVLd0RreTlkNmlWeEVSQUoxK0NScmZRQTY3R1hwRzN3eWFYT0JKZzBYZkxLblJvN2pOCkdad0tIQmJiVllOeEVITTFjM0VTNk1wYTVEQlJ6WG9rSUpaanRmUWxUWXJFazRPb1V4dlltc0IyVmtyamlIeUVZUXMxZkhlanNzcTkKSVN2N0FpUU9DdVpxU1VIMHNFaDFaTkVaZStQYTYycEpYbmdjdEdYVDhCaHY5WWNHNXZsTFFLZjdWVXhVd3hRUm1MMVVjVFl5cG9WRwpBUUNqd0dIV2ViQjJKME1acjdPeFJvaDlNSUtnRmtlUi9vaUV6M1gydE1TZ3dWS0YvVzJlRnp1eE0zUDdoeVdOclVBU1hvTyttRjQxClcxOW4wMFdpaFNvV0lBTWhwRU9hWm1ZT1FJeXJPWGlBVjREd3lTMTRVNTZucHVwTndmaVJhRTdZRExlT3pzZXBHNGdQYVpXd3E2NkIKNlN6VWd3dUJCT2R6QU9UdmNremtzQXZEZ1pFOTgraU9XZ3FubWU2dHlCa1BPWmZ4WmY1aUFNbERuYTIrR2lHb2NWa1ZjMFh6UEpxTgpNZml4SFYrRlREbFlSVEJTY3c4RUFSQUJuSlNRWjIxSDB3aXRxZ2k0NTVBcDlwSDlpV1lLcE1TQTFGUm1sV3pnRXl4b0J5bldaN01SCndla21NaGJXaDd5NWVzbVdxbExDRE9nYXozRkJoRUJkMUJYTm15MUpaVWpLRWxpTndDWHprUllGbkpNQWl3ekVoSWF4V2VpcUpWSGgKUUt5MU1WRUJUZHBzZU5FMENUUXQ2R1ZaK1JyVGVLSzdnV1dEL1I2eVBGMDRUaERCa0NZWnZjeUp5WFQreFVJcmNEb0U0SStSR0d6RgpSYmY0RXNDa0tKUzFXbjcrZkNHNHRnNEVoSHU2U3VuRW10VmtIK2ttbUl1NjZ6SDdmVDdDSGJINXdiQUF3aU9lRmhZOFFyRFdXZk9pClFSUmtaQmQwQnh5NFNjM09XUSs4Y0VrSFFKY3huSENyaW1VMHI5R1ZWakxIcmNXUmNMYmpmSGEweFNxeUNEaldhOVMxUU13Z3hxeHgKSzZ6d2pUN2l4VmVWMm5CbjErY2hrbURoYmJScTM5aEFpd1FWV0FuR2pJelpGUFVpWFRGTVdhamU3NmJSZ01pejl1QVM1enNnTVhwbQpSS0ZLdW93bmluUnJ0N2pxU0tXb3Npa0Nxa2xBQWhxNHlNbTlHV0hFQ2t0Ykwram5va2V0WStMQlEwZlFsdXp6Q3Y4Q0VqMVZUWlRSCjlBVU1zd0lEWjZRaldUVVRNcVZQSE15UXNwNTB4VTBYUm1wSURNcXVOc1hjYk5WV05RQmQ2bzVHREF0Nk5qSGVWTStUYUZJUXJFb0kKQnlSVnA2TzZCK21maHA1REF1RjVjRkM3dnNiVzZxcjFvb0w3cW1xK3BQQVZrMFd5a05JQmREUnlNSW5acHNjTnAyQnlEUFlWUFpJdQpyN3FqTzRZak9kRElJQnJFblFDS3p1Zms0Q1ZHRFN2ODBJSGRQS2lJMHltbzQ0UUU5YjliaEF1dkk5QW5MRDNtbkZRT0QrelZ5NnlaCjdEY2U2QUNLOXVpc0hJK1Via1FyYW9RUGxCWTJUV1ZLVHNIOEs2b0tSUFhJV1F4RWJydXBScHJEeXNaM0FxYU51RHVBQXkwcFBUTWoKTzZHWnhHZ2M5MXF6UVJZQ0FYbkxTSUZlc05VZTFtalUxZUpWTWUwQVR3bDZXSUxLdG51NSszUEs5Z1RhODBDWnFwTlprNmtGRGZXQwpqTXM0ZHFDTUNUSkk1ZzNER1M4RXppMmFhWW5xbnNaaVlZMXB2QWlQaDZGMkE5Mnk2a25yM1BxVjBmdlpGYXNleUtLeGhKckdrSjZ1Cm1ldUdXUTJoZjJuK2c5UXUybGE2ZXZ5aW9zbi92R2tsekhUaE5FbVE5Nkx6STNxbXhhQ3dMOEFlNlE5ajRDQW5qZHJQK0dhQW0xY2UKT3FOdWMvZ2hwTW1LQ1UrRXB3Rytrcmw1ZUM4R3oyMTh4Sll4a2VkSEppN3NhSGtsNExnbTB0c0RMN0s1bzhMTUdEYW1qcU1yS3FxNwpHNFNBN2tnOWFCTDNTbkR6SlpvS1VZY29wLzZFMVZLWHpXb0U0bFhZd25oRU5mUnBUWkdta2YwZVA0ZlFGM2o2Z2JOb0VTOHczK01rCmxzMWlDb0RPd01sQ1FLZlJUb1Z6WUdnMnBybkNyMW9zRlJkcy83TW12YXpBSzh5UWl2RmVPRmNjeG0rbVUyaEJiSXRCTElEbFYzOGQKOFBBdzdzSWgyK0lWT0lteFFIcHdQcWpvU2JoQWFmZml3ZVdhRjJUbFpnZEtRUmcrOG5ndUxRUU9salBJNEYvTVYzcHVBUzN1UG84UQpSQ2kzRmNHTEFwT241ZllWZ2xES3RaaVJqY2NzV1pDYWhxVERSdGloMTNva0djOEVObE1Zb3ZXWXNpSXIrb2FFaGNjTnEvSFVMeXRRCmFLRHB1Uk9abHVxd2VpNkhhcGtuTEtWb000WnhPSXZucDRqcU1RUjhudmxBc3UxUmhlZ0d0U2N1bk9zeFdrNUxxRnF3aFFFTHFPYnUKMlk1aGpZUGRyUUp3eVVOVHpUY09WSUllbGFyUVp4S2dMc2N4WWdBZS9aWEhBeUcyU0kvOFlob1JNT3hpWjN0eGprYW1wZWdISkcvMAowRzBlSG1vcFBia3QyM0ZMeUNyaS9Qakd4b3dSTEF6aENob2hTV1JKTXNNb3Zkd3crS2JZTlY3NjFBSGVCSkZCUnZTOEp6cFg2RlpVCllNQkt3emxOQ00wNldJVUpwcWpCaFMzT083bGR0bGpLQnh4cDBHZElVR050V2kzWFY0dk5UYW90YVl3a3BEQ3pwdlBkbGszUmRqeG0KZ2FHd0NMeExCTWtraTZnbHM4WmhnL1BjczRRd3BDdDU2RGxNeE5pK2s2bG1yQUhzSmhDVHBaMzNaeG1yMDZaNFl6Yk9sSEtiNWU5QQovSzRzdUxScERvaG0zNGFFbExBRlIzMHp5a0xKWEg4TUJhL3FBaUNhU2tjdHFzZVlpejdZSWR0WWFkbGkyZ0VneE5URGtxeXpNNE5WCk5UamtqV1hBeXJJcUxDUWpoUWVHWXpHdkRXcmtHdHRsQkd1RHFORTVGbFdmMVVYR3p6QkE1S0lHQ0wwS1JneGhUSm53WVEzK1ZKQ0YKNTZGWkxDOERRbEFoaXV1WVlXWEJDYUV4S2F5RXZZbEdWdXhOYWRIbG1zdGdnNGViaFdrM2k2cThJTkJRQUFMRG5rQ0F1d1VFTjRXQgpTRUVEYlRFYUdDSElzSHVDNEhkVDdGaFJDT0Z6MndtcExpNUluVkUxU2JuT3E4cmNJZ1FjZ2w4bHk3bkFxd0x6a1NzeEdWSWYxamxtCkc5cXFmUTZNblN2TmF3VWlJaFU4b0k0RVFyYUtoNFBDMVErSFZORVZySmNWVFJDQVkrMnE1ZDZtWVk1WldSbkl1ZXFaS3d3VG5vM1AKUWNUVm1MZk1OSmR4dHMwNWVWenJxdkJyQUluY2trTEJEUlp0T0ZZM2srU1NmbGF2RlQ1elVnZDF2ZmxWUEVNQ2dYcmNITkJNcGY5MgowVTlFSXlVTGlsUFJKU2lhQ0lwRlpBeFBOZ1JRdEN4QzBjS3QzQmZtUWhuVHBqQkVwMnFjVE1vODlWcGRuMFRIenJRbURqc01zQ1E0Cnd5SzZQMmkyQS9nWWx4Y3RpTUk4dW5rZXdoMXBGV1dnbGFzMW1OUHcrMVlMV1NLU0tKb2R3OStOOHBOSVlSdDBEb3BsZElRdjVxVmgKYUhaUzNnZ0Frb3BscTA3czZObU0wV0hnc1J4TGlubFp3MW9vMExmREFqYzlhaHRTTGIxL09MR1pSNlFWZW9jMVZ4Q3owUTdDRWd5ZApWVkU2QkJ4VGRNYk90aWx1aHArWjc2anF1dk9yRnJxQUZVWFB6endCemxNL25RcmduMVc2QngvR0lvZnFuS0tmUWltekN4T0pKMkN1CjZzWGtIbHV5SjdLYURZQ2FOVXVCTXZsWjVUWFk4UmloRERNZ0pPVjEwWEJvcG5MQS9zVjBVS1duckdJWUY0aVc3NEdHWHJTZG5VRGYKV3U3cURkcW1teDhlNTNtMkF3L2dMV0F1ZUNJR2c2WnhBa1RmTVNqME5xNmFGbzN2eStNR3dURmhUNG5aY3VtcXM0MmYxUUUzTjErdgpWdHFLZFlnR2srclJMN2g1VUF1ZHUrMVV4QTYybzZBV0pqRXNkRkFHQVpCSEZCZk9FbTVTQUVEMGxnRlVzNi9EKzBlRG5OVWlBUndGCnpUaWdBWjQwS2lERjlFU2U4d2VyUkxIVUtjemJpeTJtakxsVVNsV0JwdFhDOVhDU0VaaUhTZXlFdW95WEdaRjUwNkVQVk4yK2dZZGcKNHZOcTV3TTVRV1czcXRieFZtdWIxVHlNb0J0R1NEZkMzR0ZialZnOWl5OE1vd0Q4MUdUeVZiVk1HalVPSHRxYWxFTlVwcU93dE1SYQphU21ySGxUQWNPMjZFMHVUeHRIVmFNSDUxU0JCZ0NDU3JlRm1SUzlyTm13OEVyTVhnQWhJSE1PL0VFbk1rNVpYd3djQ3hGM05EY0xwCmlDUkZLMDEwbWs5bVM1cVNOVjJwYXNjUXBVcERZNE84a0lqRmh5R2lvQXdDWE5nNEFwVU1HeW4xNEJsaW5udGZubHN5ci9GR1l4OVIKamZBSTRqTnpGbTVKc1N0b3BxVlZNakVFUGg4bVRFVzJzVVJ2VmJaZGI3UDFTdHVKSS9Rd0gydFdJNUpIaWpIcUNKTzNNR0ZVVUdOVQpOU2VYM2k2bzFhWGFoczdMQU9tQUNSMTZLd2dVQWFzRlVmdGw5QzJEQ0E4c0E4cG05blZtWEdMVUdCSm1kc3ZkU1JoaDUwSW1MNDB2ClhEU1BCM1pYWmxSZ3gvSTR2RmhVbGRWWHN4UmlvS3FDczdseUJRb01qUm9ZaDBRc01GVTRPRm9mcTI1bXdLanFKbWNlQVZJcW55SXEKREpaV2phMjV3Nkx1eVNGcUh2VkV6VkVEVXV2WVRGRTNzWTY0TzFBQlFiVGM2ZlFyY1JzMElKSzZZbzJnN3hmY0JMSnE0QUFXSVBnNQp3SEFVWWJET21DSFBLY29VaWlWbWJQWGdRb0ZLUjlHSitLQ3FhaGllc3dYY0VPeTlXREN4YXRCMDlDd2FKY3lNRTd6U0k0azd2cnIyCllHSlZJOERQNkV5RnlrWWhDTW5YR0dRYjY0QzRRYlJYc0hlazEwdlY2RTJQMEtINjNTbGhpQzNveEtnNTBvdW0rWUdEbFc5RTRITDIKQ0J4WU45aXA4R1VsbW8xTlZZRXUyUklQcWdpVExYNk5kczVTTzhySHdyMFh5eEFCdlVnVE9FS3kzelRUa3NvbnRJWDYwYzY1YUZCKwpDRXUvZzZXUnROUXJyTVB6NVlDcHlFMm5ORUFGckxtYUxtdmROTW9aa1ovY2xRbWpZdUtOZVFUWEI0WDdZL2xEaitPekJxdW1xZmVECkpqWmtoN1hEeDRMQ3BCaWFSZUVhYVU0V0U3V29wREV6Z1JvUHErTGg5RXBtZFYySC9rZDRTMUdQdDY3aWJFQksrdE5kd09ZWkJId3UKYzBVeWZSVlkzYlphMU1pcGJIVHpHUVd2Ly9KSUN1Y1BidWl2bjR6NkpOdnV4K1haUFQzUGJkWFR2OGVzdTFpcG9kU1dkRGZ5U0tyVQpjdTdDNEl0RHJzYVV1MmxUOTZLbjNNV2hvNWovbm5GMzVUa2k2NWh3RjdvMFpyRG4yNFZHS3ZkdDZYYWhRMVU5VXJCbDI0Mk1hVmxhCnNsMTh4cU42cmwxOFhqUkRiMHUxeTJ0Q2JwbDIwVzRwVzB1MEd4bXp2a3V6QzRTaXBmU2pReEYyVmxqUE5jbHVOdVRXa0dNWG1HbUsKd0paaUY0R1NNS2g0aHQzRkVGRzdCTHNqa2ZsMWwyVEpXejI5N3BMVWZMdkxycnNrUmZLMzVMckk1UDcvc2ZkdXU3NGt5WG5mRS9RNwo3QnNEdG9HaEtzK1psMUpiaG1XM1pFR3daQW1HUWRETmxrU0RQU05RbEFtL3ZkZDNpTXlzdFhvb0Nkd0NmS0VMY25yRnJxcC9IVE1qCkk3NzRCUmRSd2RhdHpuNi8wTHBNc3VVUlpOMXFoWS9CdXMzVDZNM1ZoYVJTN0ZkamRZTjF0cW02aU5qb2c3K2d1b2hhNURJT1U1ZTkKZWVZNlNGMG00MHQ1RTNXYmkwTTJVTGNWYWUwMlQ1ZUczdDQ0M1ZiTVdRaWFMbzZUNTJIcE5vdklYaWhkdE1RUnVVQWtYZWdmQzFONApCdWxpWlNhVXdzWFJaZnF6OUlQUlpjSFFPQkRkUGtQQ2RERjA0ZkVYQzVZNGQ0NGh6V2tRZERFSGkrQi9BWFE1VmZkNitMbXMzQXBVCk1UNnhxTzk2MFhPallzbjRYQlNKemNQTzVaOHV6TjNSZVhpM3ludWFuSXVPTUpwQkRjNGRsU0dpRzVzN0hLa0lhaTU2SFdDbURHZ3UKa3V3b3lMcVp1Y3VOTlFLWnV4SXpKUUhNeForY0JTNHdHblpaTldpNUsybCtNU3dYN2hOV0p6Y3JkM2JsSVFPVml5OFlxODRnNWVLOApxL2Jkb0Z5SXN4QlBDVTR1UzJMeHFRUW5sek1jSVc0M2NaalRYaDJiazh0Wno4UmJjbkl0SWlzdlRpNDFaUGpJemNtbGdpeEpDcW4xCkpBelVMODRiWHRXMU5nMU9MdTc3WTIzb293dzQ4OHNYSlhlNXkwNVFjdlVacXcwVksxQTRJeU80ZFdOeVpaeHIwdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJYkdHZ0dyeHZ1dGFqd2UzRzVQSmRvZHphbUZ4Nkt4UmtYYnN4OG5oamNwZnB6a0hKQmJzaDZaT2dDQlg2L2FZRjEyYmtycXhmQ2tTdQpGMEFCeUYzVCtxbUxqd3NiUHFiQTR5S3FnTnJ0b09QaU5GcTUyYmpJdUROV0lqUXVYdjFIQjZYdUZXSTVDbG9QR0hlaHFxMmx6Y1hsCnkxT0Rpb3U1RWl1K2k0a0xQcW5iK3pBODI1WWNyQ0RpdGtObjJ5TlFzKzR2ZUxoZ0Z1QkhBNGZicFBpN1liaE5ZYTlBNGFLK0Y3OFMKSkZ6OHpWKzVTSHBJVUVBc0hCemNIazJPbkl1QXMxREdEY0h0YnRRVEROenV4R0FnY0JIdnhpdHpFM0JaUzl0SEFIQ2hSL0pycjFrdApLWTEzNDIrclMzbUNmZ3ZPR2ZWOWh0K0tmMWRlN050cXZFaXdiNnVyVkFKOWk3K0Jjcm5KdC9zNEJ0OHl3UUhaczhDM3Rhb1kvdWJlCkZnK09nYjFGRkxxV0h0UmIrRkR0NlMvcUxWZEVxd1QwTm5jOTkyRGVmbmJOSWh3cEVUQW01MW5leUZzVVJTQTBaZUl0YUJGTmZGc0MKYjV1N0M5NjhXOElobnJseHQ4M2xTa0c3eFQ2Wkl0dFRPSXVWaHRwRGluV0wzK25zNUM2SWJjdGFGMXlnVzZJUkxocHVOUjAzTUxmSQpVeVB5ZEZGdVVXZGVSdDJRVzFSc00zNXN4bTEwRnJzUnR3QjQ0cFV5MGJhNVdldjVrMEs1bTI4TGhIRTVkTnVXbmIwMDNCWi9zNFQ1Cll0dFc1NWNEYmN2dkUwWGRJdHZ1UHkrd2JaMUt3Z1hZOW1PaHBNSlh3MXFhS3dodXJDMXkyNkI3QnRhMnVZWWdxTGJ3UW5IWGI2Z3QKM0poZU45SVdJd21URjBiYTRwK2JPTGliYUl0VElVL09RRnNreWxBQUhEemJWaG5MdTJtMk1QR0xNczRXZitPdUI4MFd3d2ZrSGpmTQpGZzRYNGFCbTJVS01oekJMc0d5QlZXbUNxdS9KQVRsSERySWkyVUtiaU1CRWdHeEp2eXoxeGJHbGt1SGpKZ1hHdGpvWUVCUmJnR2N4Ck9OOFFXeUFWTDRSdGRVNDVDTFlnVWZKRHZnQzJoZjFFOHViWEVqejU4WG9FdmhaL3AxVmU5TnE4eEc4TGVHMVc4Qy9RdFpuUThCZTQKdHJoMXNMbTFoZW1ydkxHMWhjclEvS0xXSW1XV1ZmVEVpbUpRbUhWZVV2MTB3TUxYQzFtTEZFUStGRnNvTXJpcUMyQXRKQVZFZXI2QQp0Ui92S3g2MWdiV1k0L1NFUE5XakdyKythYlVvTFdqandHcmgrai9qc0dvZnljOWZxRnFnMXNZNHBGcmNuSXRUKzNDWXV5bTFtSmhRCml4bVVXa2dlaTlvUnFpYU43ZWhmaUZxZ1pqRXZiRVF0MGhLaXlJcFF1NFFWZWdGcWtUbDd4Z2JVb2l6bTBHbXpaWGozbElvVVpoTDkKbElJQ2JsUHlRZE11ZFVCOW9XbVJOVVloVDVCcFVkSFcxZ0hUeHQ4M2x6WnNnYVZkV3N1Yk9BditKOWJZRjVRV0ZaVm9wQnhiMFBtdgpHMG03Lzc2SXRHRUxJQzNxZlhEVXphUDFhM2JqYUJmTHhldW0wYUo4SGk1S3dHZ2ZMb0VGeTlpYXhhMHJDaG90NUIyRVdRU045cUZXCnJMeHB0UGc2S1JJSkd1M3ZtRmJDV2pSd3RBOHJac1VDM2dNT3lqOTd1V2kwOEtyd2Q2RGF1ajd6bTBVTHNpRkFRa2JSZnJ3c0hBTTMKaXBZcXgvSW0wV0tXZnRJRzBRSm5NeEcvREJBdFJnaUdRRzRRTGJ1bnozbEF0QS9vejRqTUI0a1dxMklNakRlSVZoU3RkRGkwai9seApnYUZGa0tYTUY0VVdJV05FbFFKQ0M1bk0wMG93YURIdVBDTy9FTFNZVVRycVNrMmdCVlNBWlVOUk1JTlFVU2t2L214dUd2ck5uMlZsCnM0cVhtV25IMzFQYy9aMXF3bUZLR3hzK2k1eXlRRUxXYkRhRmRpNzBMUHl3cmlKY2NwdllkMm5XRFo2RnlCQkJtSnM3RzdiQXprSWEKTW1mYTFGbmVFS0kzams0Y0FpTzhLOEdjaFJRQVkyQWdaL0h2N0E1eEVXZGhtK3k5STBsTGNSMTM4R2FSWWMvdFJadEZucDFNV2NObQp5ekxjMUt4Wk1HeGR1YnlyK0twMUlVR2F4Y2pHUllRUnNxMG9WWDl6WnVHd0kxNFhOc1R2eUtBelpUYit2aUd6MjJiR0xKcnpQa3ppCjZqMzY3TEtHUTR1QXNLbGNGMkpXRFRGRzM0alpWRjFNdFJHemtDSUloM1VJczZrNGk3c0pzOWhLdUZHTGVmQzlNT0J4QTJacFRSY2wKRmdiaFJvTXZtMWdSMk1hYkx3dnBBMHV4cnoyN2FQNmJMMHZMek9YTmw4WHhLRi9jZkZuQlFsYzVmRmxwWWNvbndDemg0c1VKREdhNApTM1plSWdDelJLZU9OTitBV1ZxRkhEVmdGdi9Cbk9ZR3pQSS9tRjY2Q2JNQ3k1WjVDTE84T2tSbk5tR1cvNVNNNU4wUXF6eGRQUmVFCldXYWYrR0lFWVphUGhwQzBtekNMQkpGU1VTYk00ajQ5ZFpaRG1OV1RaK0xySXN3eUw4WklZUkJteVRaRlZYa2daZ21pWitqeVJzemkKQjFEMnNnbXpPQi9seDRJd3kwTXkvSG9UWmlsc1lwUXhDTFBFNFdmM0xaYk1NcHY0OVNMTVNoTFZEMkNXQm5ZT0NjQXNMT0lTM1lSWgp3bG1adnd6Q0xHS1ZpdnNHWVphQlAyVVlMOElzTTJQNmtFeVlaWXhuK1Q2eGVtMDFRWFplZ0Zrd0Y2UkJGbDhXREVRQ3N3TXZpMFpWCmFwVjI0V1ZYaStwUzgyVzUxVGgwV1J4bU9lMjU0YklJMmZEQkJsdVdnU2tWVlpndGkrdWdFdW5GbGwzTFgwS2daVmNTejIrVFpaRWMKU1BYTmxVV2NVTzNEakpXZFJiaXhUWldGQWV2TkYxUjI1bWlhWnFZc0RLSUNHaW1yN0VWNUUyVlJvcTN5VVFObEdUNUQxbjREWlpuUApiMk84Z2JLODVQejBBNVRsbytOWEdFQlpjREFSbDd4NXNzdTFpTWJKSWxiRjRMOXBzdmk3OXBzbEN3dGxKVWJKNGdDUG9tc2t5UksyCitmRTkzU0RaeEt4N1Nwc2txemk1a3d3c0lNRHNKNHppUlpMbElFWVljNUJrZWRPclhoVnhHbkNqTUtyZktGa0cxSWNhR3hJbFN3T2kKYllHU3BjRUUybzJTVlE2bTVZMlNWWnBram8yU1ZmNWx6UmRLRnFkTWVWaWdaRmx1dy9yYWFQU0ljbE44SHpkTGxpME9vQ0VJbGl5RwpkbjVyWnNueW5yQlc3bUxKMG9qNHVWbXl6SXdqQWgwc1dSaVlSTGhac2pBR2daWXNXUm9RVndtV0xBMXNTM2F4WkNsNXBLYkdNRmwyCkJNSFhIekJaREI5VUhOdzBXY2tnODl3MFdXNkYyU3Rvc2lrN1ozSFRaR0ZrZWlGb3Nsc3NLWnBzSXJ4bnRCZE5Ga2I2RWtHVHBRRmgKdktESjBzRG1NQmRORnFNMktibUd5WXJvdjFMUVpObmFHd1BXelpPRmtXV3lBWlJOcElhV3VZR3lOTENLK3dMS3lvaGtoWUd5UEE0TApEZzJVaFlFczl4c295MDRJeUxZSFVGYkZFbmtGVUpaOVFQa09YMEJaMWNZQXpXcWdMTnJWY05JT29peVV6eFMyM2tSWnlxR05rU1pSCk5sV2pmVTJVNWQ5OHB5K2tMSTJRQ0FSU1ZxcnFyQXdST1Z6OE5XcVRicVNzWk5UNnJpblFZT09mcFZwQUVtVzNRdm9teXRLdGExbUQKbkFTZUlQSFRtUW1pTEVUMFQvb0VsSVV4c1JneWlMS3dlSXA2b2dkOFBYbkdqWlJOcDMyQmtiSThGbnRHQkZJV29uaXFMRjlJV1Z5agovS3hBeW5JK1ZvTFdoRGE0TitNVFVaWktKNWFYQlZFVys2bWdMWWl5dUJFaUc5eEVXVWpZVFhVM1VSWXZGaitLQU1xbTVvNlJMNkFzCnkyV29DQW1nTEx0d0tUVnJvQ3g5Y1FDU2JxQnNpb3ozQnNyS2NuQ3lYMTM0N2R4akxIMmtGTjg0V1VFUzhxYkpZbXlsTk5vMFdUMzQKbFY0NFdScmhpd1ZPRm9lbWdEbDRzakJ3VnJwNXNreVR6N0Z4c3Z3YnMxVHdaR1hvNjhXVHhZOGhqUnc0V1g0UEFralNqOExNWUJUWgpscXNodjRZU2xjREpNaStaK3ViRVloU2FiYjVnc2hqUG5GbWtyVWRyVGFGa093YVlaNzVJc3JBOVpyNU9iVUpNaVRpeVVPZk9GMFdXCm5lZytibHRBWkx0ckE3MEovc1NRY0NOa3UxdTZCa0VXMktoSFFXSEVpTkFxRnRQRHhZOGxqSFhWTUxIWGErdWJIaHQvWC9EWWJUSTcKZG5yT0RTb3NXS2tzMHJuSXNhTXBhcnkzS1FLRUJEZzIvcjY0c2R0a2JPekh1VlBuYUdyc2ZBU3R1cUN4UWNzTlp1eDhOTFFGTW5ZKwpiaGgxRVdPeGo4bXZqTTFNQzBpQ0Z6c2Z2Ym8zTG5hNEJVN1FZcGtiVTRpS3RGalFCTWpOdTJDeGhJaVd1Vm14QVJVTlZDd0MwQjhECndRMktoUW1mVW9CaThUZHlvY0dKSFNLMzNwVFlZYWxYUUdLSHU1Y0VJNVpCNnR4ZmlOaHVEeUVRc2ZqY0prdkU1Y0dONkJad0VXSUQKR3hXQVdEUzhRVFl6K0xBOUszbC80V0ZwS25uVFliRUxrWVNHd3dMNnd3em9nY09DaUZYR1JzTWltWW1Vczhpd2dHR3hIMWw5NWJkWQo3Qk5jV0NSbUtWY3hGblo0VFhoVFlkbk9sQldtZ3NKMnJYRUNDZHNOL2J1SnNEeVJ1bm13YkROOWFMQ2RZYS82Z3NHeXVBdHZvbG13CjNjVE9RTUh1UXh3UWJIZCtMeml3dzBtVFozL0Vvc0NDU29GUUJDQ3dHSlBTaFh5ZDBTYmpRc0JDeDhYVlNXeXp0RndLQUN4SlYwUzcKSHY0cmlSV29JVk1xQ1g5MjNpUFJYNmYxQ2pmOWRSbzBHL0JYcU4xWnZXVDJLMUMyS05PN3lLK0xvZDJ5d2E5WWJiTEJnd3VDNCs4TAorN3BOcHI2QzY5SkY5aHRXam5HZGNUTmZsNkV3Z1h6Rk9veWZheUJmaVRkb2FoYTFrYTh3U2xHc2lCVjFIUXdlalNoZDZacktMK0lyCmdVaEQ4VWI1RTVCYlVVdHE1Q3Uzb056MFFyNWlDdU9vSGNoWE9KUmw4MTVuMFJPL2NhOVlKcUhTUDJpdlBKdEhHNm5pRjM3Q05LSjEKMXczQVZjQ1ZCdTVWYm9JZ3VXclRsZHdwOXNhOTJsVW9HL2NLQTBlendMM1N3UExsQy9kS1A0c25idHdyOFFrWWVvTDMrc1hsK1BHSAovNks4VjRiUXdQQzVlYTgwSXNvWXZGZUYxVXJlZ0ZkR3kwaDN2NGl2RElwQWVCTEVWMkllZUhBUlgxZlZ1M0FEWDNIQlhKMEg4SFV2CkJBUDRpckFYKzN2ZXdGZTFQcFREUXVJckRUam51Z042WFk1QXZlTjVvbFFFOEZVUnRkNDI4SlUxZlNTMVg4QlhCcFllSjdNa0srb1MKa0FmeGxmRUxacXN2NU90MkRJMTg1ZnRub1lEcTR1bktJa04vSVY5dkkyUHV5Ukh3UUw0UzZkQ1VwdG5JVndyTklXSUo1R3NpYkRmbgpqWHcxdEtLOGtLOVVDRklQWU9Tcm1HQ3RiT1FySGlFWE9UZnlGZVVaV0VJRzhSVmxSVVFtcTVwMXVhbkd6WHVGSnNsUWFYck44RWt4CkNnVHVsYkdqcWk1L0cvZkthRWRYUTJQeEJ4NzM2UXpjS3cxTmxYbW45b1hHMmpmdWxjZEJoRE53ci95MVBGKzBWOGJvMkJ2WnRGY3UKQnl2ckwxalB4d2dUYVlNSDlvb3dqUHMwc3pvSXpDYXNFUVAxeXRLSlhGK2tWeFFORVJwcjBPdVk0cllGNTNXNFNPdkd2TUpXVkpGSQpWZnR3dldoQVhvZS9oaHZ5Q2wzYU10TVZRa2pSTW9Qd09yb2lPVGZnZFRSWDI1dnZPb2FLVUUxM1JZaUZyUElMN29wK0RSaFRBKzdhCmw3dGJtdTNhSFd1NzBhNWdEaUZvRkdUWHJnaGVjRjNKS0JydGhYVmw4eEJrcGtSMXhSSHdoZ1hVbGYyUXgzZ3hYYnVyTDZPTUZUMHMKc2lyWFdiT0dNOGQ2K3lhNnN2OXdMUnZveWtMcm5EZlBGYXdvT0hrM3poVXViOVk1TVZtR0xvRkZsMEdZYTNVVjRNMXl4ZHJSemV2cApZTmE1QWJBTStlTnZ1T0EzeUpVTnpVZmVIRmYyeXNsbFkxd0JJSVZ5NWFhNG92NlJMcmNocnExcG0yQzRRdG1DdGZHTmNJVU5ybndnClhLR0lhVUt2Y2pVSnhZeHBiYnQ2dkZVbEpBTGcycXJrc05jK3JDQzY4YTJvQjJmSnU1a1Y0WVFIdmhXMUpKZy9iM29yUUJQNG5ZQzMKdHJsNzBuTE1SeFVNeWJvWHV4VTJmRHFCYm0yZVhvTGNpdk1vSnNSRnJoWXljSVRhREc1RlFuRWNkUitJQUVYaTJZMXB3WlV1MXdvQQpYSXJGRGN2cHpXeWRiaVIvSTF1WFZ6ZUJiRjN1MHhQRVZtaDZpWGk3Z0swUWpMS0kwYnhXbHRDc3RYR3QwQ2NqQUhmUldpVmozcXpXCjVUQjJvRnJ4ZC94S2tGb1ptSWVySGFUV0NLRUhxQlYxUGVBZzNKeFcxT2h4N1dsTTZ6TEdMeWl0eS9IY0c5S0tuSURlakFnb3UySTcKeEtxaU9lWHhnclRTU0t5dzVWT0pHTTFjTjZTVjRXejRxamVrbFEydUVmb0xTQ3NtZHNNQnlXaE4wWjdnWXJTZUk1blJDZ01STk1GbwpwWG9mUVltYjBRb3ZKbDRJcGFuZ2dMTjN0aG10VHMydUY2T1ZuaGRiUDVqUnlnd2tacDFndEg1eDJDSlk5ZjBZcmNzdFcxNklWa1JkCktmUVBRaXVpcmxHOHdQVU1wdlJrWXV1V3N5eFN5Z3h0eFhBQmd3cEJUV2ZGYmt5ZzNIQldGaVhLcXlhYWRRVmZOUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJaUtzS2wxMm9WcjIyOFAxWWNoaWJvV3ZUOU5xRWhmRW5yM09CV2VtR00xOGZZRll1ZHBoYURqQXJRM2l1NGR0NFZZYnhXQnRwTGl2UApDN1hTbTh0S0I1ZmtyYzg3OWlxZHZkb2NzeUptam04Ynkwb0xPN0hlV0ZidXdGb1lZMWw1MFpoTWpHWGRmOTlZVm9aeldhMXZMS3NxCmMyZmRXRmJtcjFoZGNHRlpHZnhtZzdnUnNyVkh5czdnc3RMenpRS3NucHBDZUU0NWJTd3JZdThzT2pLVmxmOWVoSURkVkZhZUVlNWMKVUZsVDlCRUlLaXZGK3hoRWJ5b3JqZnlvVFdXbGdVT0txYXdjekZBN2NGTlo2ZTNodklQS0NnT3JZNFBLQ2dQVjVqZVZsWXRLanYyaQpzbExac0JReTBxOWpkSmhLQ0cwcUt4ZVp1R3VCWmNWN0RkRitVRm1WV3l6MVJXVWxUd0pJZzZDeUtzR2QrcWF5SWpiUE1lV21zaExvCjBRUmQxVmdJeHQ0OFVGWkY5RFZlYlNvclZRd0lGQVdWbFlZaUNpc0NXTnlyS25Cekt0cWhpZUs5TnBXVlhMcWtZTjRRNGkzcEJ0MVUKVmdnZUVPb0xLQ3R6YmZNd1dhR0RZZERpWnJLQ3A4WDA5TjRLbmdPQkM0YXlJdTNCOStPR3NzTEk1cXlDc2dJR1JIY2dvS3hJenpCQwpkRU5aeVI3RGtqT2dyRERRWXdzb0t3MlFTdDlRVmdKNldNOXZLS3VJUFI5M002Q3MzSTIxTGhlVU5UVzdhUUZsUlYwcmx4VUJaVlh6CmJqQ0VENVNWYVN2V214akt5cE91OGdVSVpRVytqYUNBaThrS20zN0xUTlpFVWsydG04bEtBK0ltTjVNVlJtTEhnc25LclhqOVpyTHkKd0VtYytNMWtSZjVQbkFveldmRmtpYThLSnVzMjNFeldZelNURlFkblFDSm9xNG42NGp4ZlRGWmtUT2wwN2EyeUZqQ0JaTjEvWDBUVwpzQVdRTlJIU0JTbUNnYXo3WmJ5QnJNeDhvaTQ3Z0t3c0ZVWnlPb0NzVEdPWmdIKzZ1OE80NUo3cEMwWVNDNnVTQUxJeUdhVy9kNTBEClgvU3FtOTlVZ3Z5SUIwRkVBLzRWNjhlYngwcThWWk1QcWV4eENkWmJBRmtad3BrM2o1Vkl3Q2RMVWpQMGFhZ3FQbmlzL0ppY1BMNDYKVEZTNUJ1YXg0dStPQkY3d1dHR2dwM1B6V0dGa29ENTRyRFM0R1NsNXJEUThPazQ5MzBwV210UkVWbVpYS1hJS0lpdjBhaXlKZXhGWgo4Wmk3T2VzRVlyS0NmNmdmS0lHc2xHOFJHSElCV2FrVHlJS2c2NHZHK2xuWlhBTlo4ZGF4ODlPTHlBb3IrY0NieUVvTEhzbEdzdEpDClFkdU5aT1h4Mk9vOGtLeFV6TEVxTlpDc3NEQnVkU0ZaNldBeSsya2tLd2xXZytxaklJY2treUl2SnV1MmJTWXJKeVBxTW9QSnluczEKeXljb0s2eDZwUXhsaFlHTC9RMWw1U2JVek54UVZscjVoQUxLS3Z6WE1LWlZ1TTZzRWU4RlphV0k3akZycVd2bTdCb3FOcFNWakFLbAo4eThvS3dPMnJFOE9LQ3RySUtsVk0yNlZiejJ2KzRLeWN0R1NqbTFGTDdSQUFHN0RUV1E5Um9OMjBNSkMxQkR6V0wvNDJOL1ZqZis0CkUxV1lpWU5qVlZWNTJqUldlT3RjWVFXTUZaSGNYdDhzVmdTSldGNXJGR3VYdW5xVFdLZEsyRjhnMWcvYklERFZTRlhJSmhBc0RCQXIKVnMxbzBITnpXTEdPNi9jdUErckVEV0cxM3ZQRllFVXRJSW9FakdCRmV3MXhTRVJnUmJ5eXBmb0NzRUp5alFwNzgxY1Ira0xOYk5CTgpnWldGL09QR3I4STJpV1FWZlJWQnVtZHU5aXBVOVNpV3VkR3JVR2Vqd0NMUXEvaDdJY1J2OGlyK1JubnZUVjRsdlBialF3anlLclRuClVERHNVNFBJbHF1Umd4SmpNZ1J1c2JDclVGY1hmTzB1N1FLVmJ1RUdYZEJWS0crSWw5YUFXcGJHOTBDdWxzNlcyQmR2RlI1RXhuTEIKdUZYMlhudktwcTJDYWxlZitZYXRsaUk5d0dhdFFndmVpR1IxU1FRTUtDQjZrVlpoaEdRMFFLdUZoUHQ4T0tzRkViVlMzcGpWc3FRawpKV1VWbVZBeU5mMmlJTlhNRmdrWFk3V2FMUmVJVmNiQTF0aUVWU3pZdWE2OUFLdUlUcERuRXJHcXg5UUM0MVc3UlZZM1hSVTI2b3dNClY4VStTNWxKUlVvZjh3Y3V0R3F6eENuSXFzM3Q1d0tzMm1LcU9XQlZxRTRZU0RkWUZaSUl2S2ZHcXNJNUhPa0ZWVVVnbEFrdU0xV0gKRVRPQlZCMHM5SHNCVlpFQXo2S2xrcWM2alBZSm5DcDJBWUxncHFsQzZjTDhsMkdxbU0zQlh6WkxGVElzMWlsY0tGVmNIaWJwSUtuaQo4cGxCZFhnUzRVT0VXbStPS2dKdjBDMEdScFhaYXBFVG1hM3JLdFMvR2FyZFBQOUFxRWFKY0JCVXUrdi9iNEFxR3g2VXRmbXB1K2pUCitOVEMwdVQwb3FkV002OENuZ3JJSjlKalpxZTJzdkdSRzUxS2tFU3VtNXphM0ZZb3dLbk5Lc1dibXdwYkVRQ1ZxbHBTSlhyZTFOUlcKQkpxL3FhblZBdnVBcHNLTFl0YzBKODlRL2NTZWZoY3lsYUtEVVRZeEZhUU9mRGdHcHVJT1FFbDU4MUpoZTFiZnVGVGdGNmZFTjZTbApGcVkrMGd1V0dpaVZZS1VXbGwvblFLWGl6NHlydWtpcHVCdVBoRU1FcFJhOGVpS1pNTUZmV0psZlhwaFVWUDJ3N2t1RkZTVnIrZ2hJCkttcUt5SFc5R0ttc0FjaHRJMUpGdmxxYmtJbzhaUjh2UG1ydUtySU1QQ3IrQmpRazZLajQrNm5yQlVmTnlJTTg3YkJSUVJaU2grbkIKcHJDVkgvcE5SaVVnM1RhQVVTSGdRSTR2d0toNFdiTUFwNXVMMm9BMmVnNFdGWE1qbk1LZ29pSSs5SWlsdXFHb2l6WGo2VEJSS3lzdQpEeElWNDVaZW8wTkViY0xkYkNKcThwUnBJQ3BlaFpwZU9GUzhRWEEzZ29ZSzNTVFNGMEZEeGF6SXk3MWdxS0FrUVA4UUxGUUVFSldpCnhFU0RMSHNlbjBpb1VNKzBBMExGbWwwL1F2SUxXMitXL01hZ2ZyeFlnRTFzQ3FvRm94dUNDbDF2TFc4R0tzSVBwUjRFS3FhT2NnQ28KeUhDbS91YWZJdnE4NXNHZjRsVmwyd0RUVHo4bS9xcUt5QU0vTFhKZWduMmFQVE1IK3BSbHZYaUxMdklweEJWOWJPNHBGaEFrNFFYMgpGS1ZBVC9wRVBRVUF2bTdvS1JKbGoxd3FESjFjdWxBdGV6RlBKVlZnWTNaSlloRkRkS3RsS1VjZWxycktvZHpRVTBUVFJZczI5UlFHCm9lRU41L25pNTM1UEp4ckQ1dkQ2TktDblVBVkFjUlhNMDBBbkJmSVV1YXNwU3VrbW5tSWxEaGxrQUU5UjhneWhTUEJPU1J5bzY0VTcKeFNnRVg4RzAwMlpTWThCTzhmZVlMOVJwYzRZN1NLZklEaUx1SHFCVDBrTWc0NzA0cDYySk5oS0JZaUNTNEcwRXdCVEFEK2VuTnVWMApwcDBCcFEyTFpkNEJWUzBDVFlQVitJMDRoUTAzTWdpbnk1aDlBMDVCaHRTL2Jyd3BJdG1ZOVlKdWlpb1lCcmE4RFJKbnlDemRiTk01CjFkWXowS1lCOWd4bTZaaEtWOXhnVTRUWDRGK0VyVThKUVFOckduL2ZWTk93QmRSMGVIWU5YT25vV2tUZVRGTW9MSXZrVzdUTnBOQnEKRUUzMzN4ZlFOR3pCTXlXRGRkV05NeDFHS053MFUwaE1TVEl4ekJSQU13UjZBMlpLd0ZrZUw1YnBjQy9hUUprT2ExMENYSXBYdStUeApBcGtDQm1yOEtZVmUwelR2d0poQzZSYlV6cUNZSXI1V0ZDOWtMSUovbDBNeFpSd3h2UmltMDVDWlFKaE90OW9KZ3FrYjI5NzhVc1lzCld3MThLWE9jSWlkeHJsTU90Tjd3MHFEMkJMdDBUamVEQ1hUcDlNZjNJcGRPWmlPbDMzSlJFa3RjQWx5S3Y3UEN4WnRiU2x1YUcxc0sKMWl0RUMwRXRSWDBLZkxBYldycE94ekJXZGhFRk8xSXdTMW5sa1YvRVV1Q0JFQVVLWUNuZU9lbm16U3VOMXI4dlhPa01BR1BRU2xlcwpWZ0pXeXJLck50K3NVcE5vTjZrVTU3UDY0WlNpNklTVmVEZW1GR0ZCb3Fvejc1UEtFZ0pTdW85d0lVcG41QkJOS0oxT3NRU1BORDd0Cm0wOEsyYVBvcDhLVHpxUWJ0N0dqbzVwQWR0TkplNkJDdzRoTUMvR2JacE5TUFR6ckcwMDYzSlI2azBuSnhlamxnRW5IYytwUFE5bzcKbmxPQktyVGE0ODRlUVNYOU1LZ3U4NGFTZGtkN041TzBQMUU0NmJMYmJiaUlwTWNtSUdrM29HVURNVWRXZWMrTFIwckpTdjIyYWFRbwpLd21NRzUySzZ1cW5GNHUwcnFnTU5vcVUrdlFlSFpla0xJOFdUenRuaU94T0tvb0E2dGd6eUh1bWFsUW52bDhRMG1hOXdHYVFJcW5WCjJpYVFqcURnM2dCUzVBOGhJdy8rS0ZkRDNnaTFvU1FnbW9vV0tncVVBeFdEN2xoZVc3TlVUSnM5V3JONldyelFveFdMNndDWjRrYkQKb0pwb2swZXI1WHczZUJRTjczVFdUclpGcmlld281K2RreCsvbytQelg2bWpmeXQxbFAyWEtETEFTUG94eGtveVc1cTcwNUpxMTVQYgpNaTF0eDFjVUt3bkd5MmtJU1RDMFdYTzZ1enNodWs4Y2YycDFCYXl1RUwycmEwbW90VWh5ZVJqY2hxYldJOUs2Y3c3RDRJMzFYc1kvCnNhajBPYlFBZ1psQm84TnlDQlpxdk1TeWZvUUxVS3VxUlYrem5UMGZKR3lKQ2NmS2hDdEtrOHZUbUxJSTU3d2M1SXVyYkducVRDWlkKT3FRTVkvV1IrRTVqVklFT2lyd3UxT0xDSjlUeTBXMEZNZ3RiY1JjSUJ4NXErNnppelpiazZLQ1Q3V2x5ZjZ4WmdaelVYRUlKQyt2ZgptV2tsTkF1V2tzNmVoTWpSMnJwSXcrNWJnVFVwTGhnV3lqZ1JnWjRCNW0vdUtjMG1yMWoyc20zNzR0bGlQYzlBKzZOUmt3MWxJLy9lCnEvS3BiQTNIeW5rV01pVjEwUDJZaXh2YmhaUEppSDV5VWJ6RUh1T2RDMGpNSXl4cnFPSTNveXN4V2FQc3YwUGxPMUErc1ZCU201NXEKNjNCL0hTWmRZRUhva245WC9WMERza2pqVkVQdHhsWTUzYzIxWU9rdEd2NGdza3hMTDZjNXZBQnRrTkJTUzRWSHJqWk1qemlncVR1dgpyajBqSjhibFJkSjJEenRoUUJHYjJTRWJqZGZaamFvcjE0NlhvRTVEcGRCemdEQlVQaWFFcnRGMVFDZzFURC9FRjB5WGpPRVc4bkVyCndXQXhLRytzV2xRTlIwb1JqK1czT3YwcDBaTGliT0gxZVQ5a1B2QTNpMUo0ZkZiL3c0SUJIcFlVMkFCOHQ2eW14aFAzOGJzS3kvQlcKRkR3QlVOV25wTXpqa29wdzlRUDFORHNRNC9OU25XNm1wUzUyVkhaZktIdzJZM3F5aHBXQ0RWcEI5S05sOEJjNmtWVTB3S25PcktqWQpUUWNmbFVMRFNnaFRWaEcvRHNXd1gzN2M0MUtXcVBSZUx2Q0VWZG80RWsxTjExZUpPQzRJdXEwc1dZN2pGVS9Jb0hFODlZOUVySVF0CkJ6QXFaM1dsWm5OME1OMzNyYVVWekZGWSticnd2V0dPRGt2bXhaYmRybC9rTm8rakVHeUR6VzZPUTJFb2JpZTBQMzRoOFkxcmtqNm0KTWM4b3dnN09LSDVtM3djR0RPazdJRjZCcDFNNStBM0RWVUFMd09pZzZ5ekV1ckg3QW1vM3NLTTJtNGJBOGJIeU8xZ3FRTkV6V2RKdwpKUzU0a2p0U2t4Y0R6WVArbHRBTmY2ZTRPNCsxdG9tUVhlOG56RW5zNTZyNmZlU2YvVHdvZXVBM2hlZTdXMEhnUk9uM0xFdUQwMXpDCkxPa0NrMzhReTFzeW5BQ0hXQVF6c25URmJ4RllFSURuODV1UG4rUlhpUVp5S3o5Ky96anRRU2YySkwzZ090YkFnT09xV0xiWEpFb0kKVnVUOThKdHFQem1ZeVM2MHlNZWs1bXpGbnRuNERDaXgyR05zRllQNndheGxiNjVaQWl5WmxLelV1T1V1SEhqSmxLeGpzZDNRUUZjUQprTU00cithZ3JWOGpIcXhVUERaeXUvRzN6Z0h6Q2ZrbzNkSmZXa3BNMGFoZDVMcUdWaVRadXh1NzhVZ01FWEllaVY4c2dXM29XY215ClJKK1pYNFpieTdFbkMxWW1pQlFoVm9XM2xZaGlEajZqUzYzTzdpWHNGMENRYnRORC96alM0ay9xdlVQTUFQSVR6ZTNEYnhVNTZ1d0UKRVBYbncwTXhCRnNmbzZnZkwyWjcrUk5ZZWFCYWFEaU1DOHZIeUsvVEp6dUZmZDlXMThNa1FTSThrVFdUbnpuK0E0YkhiOEhIRGEyeQpKTDdzaGVITi9aTStISlE5dVBIVnhCMkFxNXZQbnFWaWliRXRYeVFFK1hwN2t1RWIxV0p3M2d6a1ErZ3Jza2RORlNMNTUzQXB1U3lCCmxYVXNzS1FzSi9OaitIQXowSmN6R2lGUVNYbnBWbVMxdENMRDcxY2JwUlNCZGVJbEl6QXhhMG1kcUdQdDdvS2QyRmYzOGxMVWh4ZFcKUWdwZ1lXMHNjQlYweG1DaDMxc0VkZk9lVFJoNnJaeVRlakdKRmZTeHRsNjl5STl3NXhOYjVGS0Jvekx6dFIxQ3FIeC9TelhkS3JvWgpraS9RUnJpT3pRMW9VWUgxdUxWRkk1bWNQYit5bTFSQmRRUkYyZWhSM2djVkpGOU02TXo0aEhxZ2FtNExrV0RhTStadzBocTdGR29mCkE1dXVxaWg4Z2ZOZmNyTVlxOFQ1TS8vMXN4M2RRc3dUeVBsdG1IREFxYWVaNDNsWnB0Qnc0U0lUVllHUGgxck5GZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJSFp1eFpxNXNwVmhVMVVIV3hneVZXSGRiRWpUaVh1eWloZi9BODRXRlZLL3Vya25jTWI0aDF0dXcvV0ZSTW9lV0lzUGlDOWRkK3FlTwpyZEVqcXdWMmkzMDBLT0lNTGo4Ri9sa3RUeGRIMHVHYzZoNmROS25YakdFQmYydENRc3FTelRxenlXV0RKSys2OTlQNWt4eis2UGg5Ckx2ZDhtZXJYU1lrcUxXMnZBWVpmT3haT1BSS29VUkNNampVMVY0MU42cW5kbldENjBhc0hpa2YxYmxVMUYyR3hPQnVwY0R4a3Q4MGwKcWVmVGg1MVZKREFmdDA1YkpEaHgzWlRWSldlaHowSmliaTFwTXVvdEpJTE12dUpMUnNkVVlpaVE3R1MzbnlPMURDb1RaTWhyQzlXbQpwVW1UMGZDa0pyL1R6VllaYU9HZUxESkdKSHQvSkRYRkkraGUyWkJ1eW04RDhWZXNRR3YyUGVzSVBBVUFwamkwdzVtNDlQaVFOVVl5CkJ3VjlGVlhNMjZMc1UxWHEvbXlIVlJWblFjQjA2cU1JbHQ2ZmZybXJGb045M08vbFR3bFJKRG9TVkZlU0cwVGRwK2dzOFRrajFjUkEKR1FBcUkzaHUxVEFXSnY5SUhFcTVCM2FsN0QybHZpTzBoUUhrYWRZMFhxUktQQXZZY0VzV092emEwOTRmbENqNWNRa29heS9BTzhpcwpIWEVkSkY0THJoWjVYeW5oS21yRFU1S09UMEtBVy84bzJNZ3laYm9IZTRoRldESjhobWF3SHFzRDZEUGszSUtLMXo3NURGUnFWSGtwCm81cTdwMGdqa2J2VGJaZndqVFRyb3JSajk2QklLY0RrODFZamVNclVlUTdiZ2dhZU1mUWM2L1NpRlZGWGptS0E4M1BhaGw1U0hxRXQKZXRIRFp6dmJlWFZGcHdsNTY4dENXWWwzREdOcm9oWVRpOGNmd0tmT0JlOStYVUVxZ1JPaEo0bGdQRTZXZlhTYk9EdWRrdGhzaU5GagpVajd2Vjl2bDd5eHMwejJMZU92eTN4UjFQY1JJVGxucXhzWGdzVlU5Sk5KZWhlTnBlclJVRmRCU3U1Mi9QZHFCOUVWbm14TDJxU29CCjl3VmJwb0VpZmxVTVRFbzFlcmdoRjA2cUc5UmsrckttdXBnVUxoMVlJc0VoREVUYkhXTEI5MGdmaEtGTkJsWWgrb1lRbUJiditlRVYKNlFkempjYXNXSnB3dUs2VVpJcWpCRkFMREE4bGNOaVJzU1d5UnZaM0JjZ1JoZkpKcEdrMk1lMTJyTkxqdVA2Z3l3dE1TeXc2S0NrZQpmai9zSWliN3FSRDBONDU5MlpNNkFrTWw2dHNRTnFha0dwMXZOUElqUU0zN0NrYm5sRitnR0RGSkJWdk1qcWlQUExLVzdJcm9FZUh0Cm0wa3V5KzdVbGtmb2dHRWQxVDRmVy9JV3Z6MTBBaC81TUlyYXdZSm5wdkg4OFRCRDRWT1ZBSnoxRFA0RUN1ZWowZTFIOUQzd2JDdXAKQlJTUkluYlFteitWNWp0V0l0VXpJc2dDZ2c3Zk1sZ2Z0MWNYdTRvNnlhVEhwU1VUOGZreHZ0WUlmN0p1R29NY0FXbGRGczNzTEpzZwpNZlRxOGNOWG5EY0dEenMxa2NONm9lb1lpd2l2SGZwangza0ZOQTdOeFpScUFacHRhSGgwbjU4cUxTbm11WjNzb0NWV1pidkptcmZiCnFaUEJzUE5sZ1pSdjlmQW50eFh4WVhvK3cwZ1hWQUx5WmZ6czVNY2FJS05PdXFJNkhzSTh2Sk5xa1lYTUUzdXhkd1hBY2hERU1xWUgKek50WjMrRGlOcHlpdVd5dnhybmxZaGxJeGdjMmliMW9lazAvdmdINUFMbk1IZDJFc1l1T2dmRUluUkdnT0N2a2xLaldFb2FLQkJBTgoxWmNQSzdYb3J4M0pRT1B4ay83T1ZLM0FiUWs5TFE3UDhuYktEeEZPd051OUdETEtVZ0hqSXVCOEkwekttWVNYQ0NqVzRHYndhSGxCCkpnaGxLcGJ3azhVdHgza0sxUnBKV0lWZzRBVWdwZ0ZHTHRzWUY0UHRZRUVyRlJwMmp5K29wL0NPOFhEb1ZseTYwcENaZmhmQ3FMQ2cKSm9BWDJhd1M0Uzh5WUY2YXBnVnN4KzVVT2xmOGI1WG1FQmZMd0pGMmRHa2JubmRMRkc3QzI2WHFjMEJOakFmZkFqR3dSSXptbmtSUgo4NUtTWHNlY3ExQUtrQXFpYzFCV0tsY1h1V08vZkxORUkxaEtSZkRKTEQ3QlIrNTBSajBFdys0WUk2dFQrckFxbGd3ckF0eXdLSTZNClBpc1FLTUhBakFBSGo1WDJqblFxYzNWREVCNEtDMGRZV0hqSW4wekxCc3V2TWpXcE9NV2FsTFptSkozQmZyNWtET1VPVlVqalRyTUIKV29UODlvYzBFTDVRbkE3Z2FDTERHWjBxVWl6RE1sWWc5b3ZEMUNpN2U1Z3VLQ0xsY1RNK3kwZmR6bUhvdWU3OUdHWnZpdVp4RzRiRgpRYUJRWUsxWWgwc21SV0RTbncyUUtPcFRvRGp4MGxpeEVFNWlGSnJ2SlI3eHNKd1BjZWNlMlFVQ1J0bHFHR0UwaEZSYlJwd0kzYTE0CnFvUWVSOStCSkJJampSQkZzdjB0c1VPd2NPS0dHSWowSXZqS0pWakswQU5CazVIcGU3UGRzUjB3V056cElQa0ZoaCsvRzBJUlJjSkcKNGxuTHJDeTI3VkNxcUxEeGVKY0tLTWRJek12RXhSTXNBdnhQemRwVGl1WEhEaEVicWo1WnFSM0dEM2UwY0E3RlRCbDlWSjlYcDRBNgovSEgxb3NXckNjOXVmOCt3RHNic3B3cGxlU3dGdkRGZ1JKUGFvUjF6dkR4cys3QVl2YVNQd2J0U0krZUVjWVl2Q0hsRmVFYVBWUjg1CkcyekdwQk5DV3JnSEJLNDgwSWJ4WVQwZThnRlZXVEhXb1lzZEk5K1BPYlE1dVZVUis4NFc3VWdTR2U5U01rT0tWbkxVY1dXTG1aUEgKc0xYSFJMYk1ibmhqMkpMUHA4VysyTHhMT1MzblYzUU9VMW1yWXNUTkE1R0UyenZoNVJKSEdpVmovQ1NReldJT2ZpNlA4Ymc5YkNSSwp2bkowNHNXSGx0ek5PV01TOUxjb0MyV1UvRjRyazBOUTBVVjdBSkMxdEU1MUVVT204cmRvTzdZZjRUYU1mS0I3NHc3RlEwQU90M2hGCmJ4VW9ZUmlhVzQ3bFlPanRqOFlETmliUW80U3NudTJ5bThCUm1WRHU0ZWd0SjdyaS9CVi9jU2R5aWpHcUNtRmpkQ3pSWWhZV3FBZGgKVVIzWExLZTZFMVo1SWxQcW1FeXR0cnRvNzU4a0NZUXRzM3ZNemhCc2N4VktPU0xlVC9oYlU0K2NpNGlNU0ZIbU5VSStxOTNRTFlkOQprNk1iSnZnZk5YdllhM2hMWVdtUHR1bWhrSmQxNnBheDB3RVBOYm9zSE9Qd2U2M29GOWY1eFNyQkp4SlRLK0c5UmNpSEl4UUtDZVVmCmRIVld4TGx6RzdsS1U1Ri9waFRnem1RU0NKMEVvdTlFTnNqU2dKSWlrZ1ByTEYzakRRdW1ZRm5QZEhLUGVUVnNzNW9ubDNoekNJU0IKLzRFRkYyY2FOc2h5VnJCandRWkw3MDVQVTZtc1BhMnZoSlZkVzNCTkpIbHh4S3FrbUdVVjR5dHA1N3dqSEVLaG5xQ201aVNGT0FsOQpJNHdreUdaa1JIN2EwR1RROCs0ZkJrMmlqV3JNeXZTK3BscjJ4WUNoTVUrN2JnMCtlcElOcGFRWmdlYVJHcWVwUjRzNC9tS21LMEk0CmdYK3hHZnlBbkNHckUra1NLczN2WmltWkRhbTZoMWVFVXVVVEdzeUNTWUVMSTdvc0hLblo1NGJ1TWpsYStNVU5mczRoNDhYQVZCQUwKd1Z1MkhuaEx1U2pmblJtWXhidU04aHZYdE1EWUpoNFRmRlZVUFdRR1psSFh3ODFzR1J3R0VBc3FWb2RsYWlpeXRtdDh5MGhnbXJKOApMQi8xays5VndWNHZZTEN2ZTJuOThTcHp2WUFxcCtxVzB1d1pCd3R4VTRqcXkrbER6cDFwbTY2S1FBM1p5UTA5Ui9lY2tGaU5oTDlaCmJBMERwek51TWNiYSt6MXdZbWh0bm9XV3MvNE1CTkNnMUYwL2F4N3NTQ0VDdzkycktYR3FoQVdiZURGZC9RaThVVjJiSXFkbVNuYkkKc0hwU0lwcjEzVWpjVVVjSkIyT244ZzUrSExKWlpadGp1MUhqM3FDTkR1SWh3eFF6Q2o5cXhGMWg1YjFHSVZqMmR1SVFFeVR6eU5JaQpGTGpkZmxnNTFhb0JkeDZSQkx1Mll5NkxHYmorNkVscXoyYWlDTVRuakdBSE1CYmhOQVhGZ0tYa2ZCTVdPVkpGenMvWmJqV0RUcUQrCjREUGNGc0JyVXNEWWp2VnhGNW5sK1ozMTVUeHQ4Qks0YUE2TDdtMVJvUDVzbHQzWG9FWnQ0N1l3Y2g3NGdHT3RiSStjU1BqMW1RMDIKdVovVEFkUTJUNHBZZVU1S2pOdzZBQloyRzJDZVFpazZrdzhSU1Q0Um9obmRjeEZmN3Q2T2ZSZGhZYU1mNXU1WERrdEUwV2Mxb2FZdApkZXBoQmh3dUFLb0IwYXdJZVFuQzh4Q0VacDZHMFFpa1FoZzJhaEdjZ1dYNlpGbUx4WHcrRXpWcVUrNjNZT2xieFlOREp6am1MeGtLCmgyd0hFMUhhL1hsUkN4Zk9XMkliWHpjOVY5SVZWQSttSDBuMktqcFhkWlhBc1dwQWxJWmNGbWFveVBKbkRoVWhwdExsYU9LcStZbVQKZStncmJGSklJeUNWOVh1UGtCL01QZkEvWUZGb0ZHOUxqay9rTWJFWERHd0lFN2dkRmR1YW9CUXVwcm9WaG5MdHFBdzNyQWdOa1ZMYwpSRkNmVlBQQXdrWXg2RDEwOHB2ZGpaQnJjUWlNRFphVFV4bFVIdTBHeCtnTGtnTzlQY3dwaGRYYmVSRkh5MHdLWkdmSmx3RjlDR0pPCkVKUnBaVFlOb1cwT0dMQ3dtcnN2QTRvU0tRMDdxTFJFUEsvUzd0QlNvc0tmYit0OXFIUnViQ1NBNGJhanlEZU55SUhSeVVqM0NCSVcKWGlhVFRtN1RrclNka1JrQ2ZDSWNpV29TRGlWaDBRaGlrTzdaYmczWHhaS3loYk9BVW1adFlsVGJnNVp4K1VXWlJGckVUY0IvUE5Jcwo2Q285dGNlT1JCR0pFYy9sWlltZU10bEphTWoxT2Rkd214aXowTUtBeXdFK2twRzlhbWRmbWNubC9qR0FEQnNkeEMvcnN1cVRqVWZtCmNKaTNhQW9hRWI5OXVtdlNNS0dKTklFUTNHaGVvSEs4S0tHSVNSdGIwQlc1akNXVk8rdzR5QWVMRVFodTRBcUxVcjNZcGg1TkZEbHAKUEJ3ZEoxaThIeWNXR2pneVpKRE12TnR1UHpRaU9sTEVVbVAwSE9velNjRndBMW1DNnA1UnVFWTFla0orSHplYnkwSGVhTWFCNGRiawpwSzRLdUYzRmJidHA1SVd6VXIzSys2UGdqUllzOWFnaG8wNUxFZmF5OTFTdGRkRWJSUU5IVjhUVEtUWExGbzlTRTFCYi9PVGpma1QxCmlRNXZ6c3NoVlBsSXpQZDJzMzc4NGI4bzVKZUJTREtYMlk3VVFBaGFsYTN0RnBVeFBKbVM1VHJGb2NoNS9vNGxxb1JVa0o0K1hkRVYKSHg5cTRhYm9sZDRRc0YreXV5YlRzU3RURXRnUEIxM0JMUzJVZTlieU9STXgwT1dMblRod1VhMFAwNFdMN0laSU5iY2RJNjEyYnRvcgpSbG9WaXFMV2lKMEI4UU1VUjZBSUZ4bTNYS0xNSHBiK25GQ25SSDJzVGs1eWUxa2pnVkwyeG9XbytsTlRackgyUllaenpNNjVqQm9rCnIvM0JKK0Nna04wTU9yR3dPODM5NXRnNk5TWFJ3b3dERkN5c0w4K1A5WFRVdEpTeDkxUVpSSEVraXVKY050b2dmWGhLbktzUmhzWGwKTTF6bUZhcVRwTStHWWtZQytWRGhrSmZjZHE3OXNNME1SVVptdlFKY1pFWnJzY0lOWUJ0MTRrd3NQTTMxTW5nTU94WU1KWjRTVXRrTApDcXlKdXhOWittUWVGUTFLVnRSUDFJbWpONHlOTDk3ajdHbnhhTUZ0T0lJUnNUMVBoTXo5eGg2cllaT2p5a3dXeithZjVJQU95NGhWCkk4T2lReWZDSUNoamFvZzAwdEladVJyR1EzRFBHTkNoeWw4Nk5SWVN3eFBtb2hvM1EwS2cxYUpkbW52YWNLWkVhU0hiaDVYb05JTlcKOGl6UEttNktxMm9CU3JqeUNUMG1Ncnk2MnFwMXlyaEk5U3lhQ3RnN01ybHFqb2FZMVhkTldISDRoUUt6NnNZdWxBVW5JYXYwMEhqegpZMDhsMzFrYVFORklFNm8zTVc5U05hdUxqZ0VKa1NWTDB5MXdhckppSENwY3d1U1JuS1dxZkRqVWlhK0dLdGhZL0R5TTFMRkxBcGVPCmpxWENvbmx5Wkl0WE1Wdms4TkJnNVR6SkZ1aGVjRW1GV21zNE01SEVoV1VuRE1ld3M0ck1ZYlpJbGUxUmtPZXM1RkNoOW5GWUV2VEUKazRUb2pUbEsvQ1JYQlZnRThYTnJydnpuZjhpVHpScFYrSk93TnNzVWxRVkZxcEZCT2NwaG5kSlg3emxZU25RSWc0YURRd2JGaTltNgpUenFZbE14YU5LQzFDU1d6b2N2R2VnTWNVNnllS2ZtakNEQS8xZ3F3S0dIVUVJYVlES1Bybkc1MmlQVVYxekRxU0Y4NXJnOXEwaURFCklwWnBwR3YxMDQzeEJMS051blVZbGd4U0krRmtPSGlpQmlESGUwYytMQVRSc0xZbW9acmFzOTE3c2hlV0RyNWxydUpnSjViQWNZWHYKdFFrenQxU05ERS9yNmxrUnk2M2tYNlMra1F0M3R3Q2hINDRwaU9FUUNzU0dQdm1mL1JMb282UmNIT2ZUWTlLalhCejVhYXdldXZWdApKNVBmdTVvTkRvY3FPRkZUemJIVnNiQU02OXBUdUNCY0xpZ3FnVEd0NkxmbEpFSjIzTGplbXBEdVJkNDVIRjh2RFlmRHJoalNKYmFZClRhcGFDclc1MG9XR1BUekp4MDNnWWVUS25Ma0luZ0paV0k4VTNzenR5TEw5M21qUGhPWUFqSzA5VGxWd08rWWdPQT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJaS9nblNRQ0trWm41Vmk2UG1mYUliRWxpU0xDcUVtck5KdWtPYjRRRzJPNENVc2hCV1F6d1JNUExuaFMvNHh6RjE2N1BMUUNBMDZrMwpxdS9FQVVJd0krVEVEc2VwUWVXWW11eC9kcVpGbGFYRFNrRzRGK3dRejZjclB4UzA3NmFIbFVPakNhdXF4c1owTVFDaWlhd0x4Uyt3CnBUQmhEejc2anJ4Y3gydnFlc3hRNGRQMERaSW5oZWsvSzNLMEpPQlNNaUZxS0dDbG84NWMrWlIrZlRJa3g0YXl5ZUtwWGZNQUQ1S2kKV0dqTStRc2xKc2Z1TU1WWGJ6VGlqOThQWVV6bnBEQU12UlMzK2RYV3FVS2ZGUjdjMFBLWWxsNGRuaWYvQ0h1R3NvcHhSS2EzOHVOVwp6K3h4dVJ4MmJxN3VvUGZNNnFtMjYyUzY5SnA2NE15a0RSY3FaZDVDaDBHYmt6MjB5R2xCZVZ2dTkzYkdJTE1BVEF1N25lbERBN0FWCkxpaW9aYzJPZVNGOHBJcDZ4WlVnNWdvRlo1M3lZOGY3SGJKOXVnTGIxTFR6M0FhOTN4SEIyT1NHQmU4OUg2YzBrM1ZOdExCUkJYTGwKcXJsSnJnZEs3RHU4RjVNdW1SdFNrUE5mMVduaFVRaDFXMWcrYUxVc2RoUW9FWmt4cmwrU2RVMU1reTQvemFFNm9xSElVenhOTHExWgpSRld6OGh4ODZEQTBQMTZWd21ISDJkUGVrVDNuYUUxT2tFaUQ4UURqclY5VXc1M0graVZkWkRGSEVDNmZMckk0cERNalVvOEJqU015CnhwSlF6bEFWOThqWWxYSmRNYTBSM0NVRGk0Tmd5UDNzS0lBaUFzMTYxNWNiRWNMQ0pRRUNOTjErejU0aHViVFduRkk5eXFXaDlrYUkKVmVra01KSlFlamJkSy96SFdHMTNWYVFtcHMyeU93MGhXakpSVTZKRXRGVURDeVVNc2FNSzVORUJpYm1yN0s2dmlUUjhOcW9vSG9JUQp1TnU1Z2hJNmMxZzVqRUpVejVET2VQeHdtZFZSZEt6V1VFN0F5UEFjNWtoOEVEQU1COUVZU2VTUjZJaWpvSCsvNk9XSisxKzlQc3BSClBndFZNbUtMMU16d2hxRVU5ekZNRktJUVJXTTU1Q2NOamc3d0w1VnZJSk9rR0U5WWxFbWlTUExhREZtZG5wUjNVQjRkM2s1MmRmSDIKa3pLWjE1alJrYjVBK0JLSG1tUG9UZFJVM1F5WlNHd2VFSmVKa2dxdXcxZDh2V0NnNlNNY0ZnZWdydysxMEtzckhCdDdLcUtOK25wTwpwckFRcW9HMmdpdnJXSHBuWVhsbS9DYjhTTlpYWWQyTEgxaEtjc0hocHUrRS9LdjRIS01yOWNRN3kzS0NLVjM0aDB1c1BLUmFxUU5jCkFibGh4dUtiMVNYd0swWUVNMUN3RUlWcVRCRkRuSzR6cXlwSW9JV2hKcm9mTWRQVklqb3RyRXlNY2pQZWpLb1VBSSt0QWFvcVVLSWQKbXhzb1l5d2puQS95UTZZL1FOMUFubXdiNWxDb1NUdHVhM2Jnb2thUkRuZzdVTFRtbW81QWZwY3VRYlVrNzI5dlYyS1ZOc25CcUxjRgpWY214L04zVzFaVHR5T3hQU0tIQlVpWDNmbVdaV2lzdDB0RlZIV1NoMTVCc3JyT3V2bk84VnBWaHAzYXE2Z2FGSnBUWnorSkhvaytmCkxXSHNBRDdhYjR5bVI3bUxrL2hOektFbndnZ3pMS3MydVp5WlVoeFlxUDJFOTdwSFBCUnEwTGZ0SVVjWUNuTXpZOG1BQk55ZHpNeXcKOHdBLytpVmdFeG5OcGtsU3lnZThIR1pFK1huaEV3eEp3bDVzd1RxclZSeXFSbFRzTE1sQ1Z4dExuNUZETXJhSnBIRHJwby9IckRJcwphMGtHd1NrZEJvNzRWUm54dUVncGg1YVZtc3hvNE1HZzhEWDdFMUY5TGFLK3NZQ2h1cEFlRERJQjFJcEIvcG5zNVM5MGc4ZWd5SmtkCmJ3VTlFdzE0SzdvekRZOEVKVGtKRHdJK2xVbUlXSFVKQWVwMnQ0b2JrTUhhOU1JcVF5dTlRSkc2a0hrSENRYnkyRHRLVFFSL1RtTE4KcWFVNi9UbGVaWEYxRkxlSnB1SDBjQkd2MFdSSHQwdk53bkRaTExhaitKRktNYm9OTWZac2E3S3FocnFoVW4xcWZKTFV5OHAxM3lMLwpUTG51SEphYWNzSnhPcHdoVm82NXJMNmpMckFlbWdLdGZFNVE1bUdsZ1B1L0VDR0NSWW92Uk1Rb21zdFhUU0Yxbml4K0p5ODM2Wjg1CnFtQU9ubHFIWk9VOEtZekZpamltYUxFVEVQYmlSWDA0WlZ6MElVZzhxVXVCakl3WEhwWWQ3bnZXWmFWU1JrclhJa0xCc2VTcE1LMzIKM05idVNtdW9idEtRZGtIdjRoZFAvM3V1SmxoNUlWalIxSHZOQWtwMnFXbWlRQXZOQUI1ZW94bzlPNzBJdlRZVkN0Z214ZEl6dTRFdApXeUJBOUlVNkM5VVdwQmFsTnQzdVJQSUV3YVU1RWNGdWQ2ejZWb3JhMVVVT21nVW1ZN2dLVERmdEF4a1prcy9QZmtNOUNQYnhaWG5VClcyNkhodm1MU2c4bExiQVJucVdtajcxcmxndFpsMG9TR0JQa05TSS93bXc3TmYyUGFralY0M2tvQ293SUtNVjg2dFFjTld6VkJjZzgKLzZ5S0U0SjYxQlN2RkVOVmtCS09wcy9hc3ptSmw1MkZMaTBTZUJ0bzB0aTFtVmM0UWxpS1gyUmxGbjZIMjBpc2RzNXpXb21DTC9uWgo4UC9IM2gxRU5ta3FYRWlPQldwVVZidFp1d1VZSU1qdmVxbEtNa3ZsOFZSd2dsWmdoV3ozSnY0azJ6Z3dLZ2xXMHpnMUMwcVVwV1J5CkFDcEx1ak94OU1rWlMyVVNJQkFpMmpNME1iRFdvUWlyUXRycFVkeVEyL0F0aHdBc25mSSsrYVpJSnpMU2loOWdIQVlXNGxOcU1sME0KSzRtZHNBWFNwamdsckZRdnlwMVMzUDdxWHQybVJJM2pqU2wxNDg4SVNGT0hEY203YWk2SlJMY21jYkxhVWQremZKUytlbzY0WHArbQp6TU5DTVFjc1BOdmNGQ21PUFlXeHg5SWtNdmNLMU9jV1BKTXA4Z3E3b0tRUWZTQ3lwMmM4Z3RDU25YbEZVUm9CT1UzVEd6OVdKQXNVCkw2MzZIdkE5alNnOVoyQVB5U21GL0I5LzdoRGE3MWdpcWp1VnZFeVNKMEFyUXRvT0cvQlpQTUo2eUhKWGtVQmNRYmtMa2FwWnRaM3EKVXg5d1hPN0pkN2d3U2hSUmMrUXF1bXFvWGIxYzFPazRFYnY3cUNxWkRXVlNET2MvK2xtcTlBa2ZrZGdIMFJ1cE9nUk1rUUhEM0RXZgo1Ym5pcWN5UFp1VmNwSDl3VG9vcFdnazF1akxIZFgvUXNMSWJBR0ZjVmIrZ01xRWFnZWhoRGdvdDUvMUpEazhEQ0V6Nndha3B6MXJECnFXZ1hqN2s0cjhEclpHMGZia045RkdaalF3d21TRkg2bjF3cnJtRWY5YnoxNXU4OEtxb2lYZ0dTR1FaOHExZU4zSVFhWHNwSm84ME0KNDlKREdqWnEwM2w4MW53QlVrQU5DYXJPVzdGaGR3Vng0UXFzS1ZWZEpCMHRmclBETmMwZlRremxqYUJpVGc4ek95M1Bpc2NpL3BFKwp6QjdzQm9oRytYSjJGTkh0WWFSN2RZbTZwY1NuM3kzaVlTVlQxWDFTZmd0N3JxRGdicDRWcktyd0NvcEVkNEtSRmtaUitsQVVSWHVpCjBSVGpsNCs3QWxSM0lHVC9FR3BJYXBCS1VOU0VsWUFlWnJTd2FLNW40bmFjOHhCVWRxa3lQL0Urcm53RThwdGNKOEU2dTc5a0JqcHcKcnF5bTQ3ZHRsa2VMS0IrczlHaG9aU0Y3cVk3dm9yR1JmdEZLd1NFWjZjK2VaYldjSlVUajhXeWsxMjVhMVlONEdBZThhdndJOTBRcwpTdFdSdy9LaXBNb1MzamQxVlFzMVNuVThMSFpVdjVLbzVKUkFxY25pV21WMENtUWViK2lyMTU3RFlBeUlwZkhDUXNiS1lRcXZ4Mk92CjU0bFhuYUpkK1V2bFQ2TE1NaTIycFhyc0FOUVM1ZGZkMm4xa3B5TXV4TTRiak9qRFNnUUNZcVkyS05tWDNER1k4OXF6TDdJTGo4OXAKa3RlR1EwMlZGeks3UXpsSFNyWkVxVWxPbG9XaEtHbWs0dm1rdWdpZVpLNGN4WHlSU0F5ZlVOd2gxbjh0MVcwWHVrY3M0OUtFSzJFOQoxazk3NXNJMERKNnJLa0xiOE1UOERGZUUxaHBUdGNrZTdhcStWUk1FTGt5bXBtcTkrRmhKa0QzMWhDUk1hNHQ5bFhMYzBKRWk1ZUk1CmJBbkdvV1FXT1FORkEreDBmWUtBRzdpYlpKVDdGQWZIYXFpWmhCRnRxcDVpWm4zUHNxd3p5aUtIS0lrS09WZHpmeWRtNEZrdnpkcGgKT0tiYlQwT1lkM28ycGpxZDdueFhHVHpkRlJvbzI0Tmw2NzlDMThIeXVFZFYya3FINTRDc2ZWa1lmTmRsaCtTYVh1TVAxVzB5Q2NzMwpEUEkwbmtTdzhaQ2RNelR1Q1pWeUZabERFOFpqWHhFaHk4ZlNZWUZYMlJ1cnFPSmQweUlzbXlzQlZBbGRJVmdEZTZMMk9qaldNdjdOCldjbDZWbUQ0QlFrc0VNT3EwaHlyMUJmdG9vY3p1cUtub1VWaWlJU1l0dTNHRTlLalE5TXpqcmpvcWRmRnI0Z3NaUW9QQjRGanBkRzkKMFJweGIxemp6SUFWNVpmcjBmb2lVcDV5K3RmaitRbmI4UjFIRkxKVTdTazhCU3piMlVCVFNrN1hLNkRvU0o4cTZPanRhT0V3aEtPSApxSVIzZ0N1azZYVXRybFY1eEdua1VHS0hPRU9YRG9TSUdPalNydTNZQ3BwbFBzdFNoRzFCZE96czJhTjg3VEg3Y01wRlVHSTJLOGVyCjVYdFk1RHRPcFEzT2RnenZONlZaV3IzL2ZvNzBibHQ1dFp6WUlQT21RZ3VpUy9wMU0rZ3lLMTk1NzJCMzAxcGNkdFM5V1lLb2h3WlMKQjliTFBTNEdBeUhhM2IyZFJGd3JtV0tBbnh6ZWN3ZjFpV2dicmtBVTRTb1pwWWI0TVZFbWtJQ3lKR0E1YWNTM2xVUm1SU0pGWkFvbQo4c29TZ1BJMTVtaEZWbnBNM3l2SVlKT05WZjIyTTdxN05PYXZBRS9QSlEvOVovK2VFL0pMSVUzZVRLWlRZVEdHUzZvaTdIZ2dadUh2CnJDa0NFSzVESEQ2MndjMjZTVXBtc1ZsQmFIVVF4bThLak8xNlJsYkJzVVFwa2RXV3JJZFpUaExxSjVQRjg4ditBdmVrdm1aUjhVK0QKL00vbCt2L1lVV2w3WkJyR1Vya2dWUnRzWnV4aUs5WXM4ZGl0bjJRcis2TWdLdVNDMkNxOERVSklwSWlJY1RxSDFZNUdBbE9jMVZqUApPN3dDVzE0RnNteU9wVW1zNDJTWlVOOXFlcDBab3YxczY3SWtReUFuZzV1VlIrTWJGZEU1bWpURm5wemxZYVZPbWhaaUlkR0phWmVZCnhyRm0zTmkwSWh0ZEg1TjNsdk54TEdTbTd4Zmp4N2JvTXBOaU9pelg1bmI0VEI4RkR1VW56ZDNjeHhZTkg4TXcxYjBkWmhnRytPR0oKMGhtbjlyOHJ3NzhydlZnandIQXJWTCtQNElTUE1tNkRrQlh1cHdMNGNVdng1Nm1DMTVvR2d4K1QwMlFXV2ZxaDJuQnVFd3Nyb0lBWQpEQzJ1S3RMS24vWGJMdjQvbG53WHF4eHJrcENWV256bnczbEoxTEczWGZyVjVsWUhFUzdEcERRNVRUMGZXS2o4b3VheVNrWnQwenFxCks1TUtxa0VvV0tXSnVsclZ3OFA0bnVWNGIwOTdUMElsYUkxZkVQazFtMFRFYmRRZXFxZ0xXY3pOaXQrbllpUWRrRUVzejRjbnhWbWQKRXJlbTJxdGRrSkdNUkNXSUUyTklNemcrcy9uaEVQNUVLRklFZGtMbXcyVWpyeDMza1k0OHdGY3FCL2Rxa1hpTlFuWEFrSHBSZXo3cQpFM21lUUh2TWJSaitvcHMxc1pRb3hJREhsVjVjZ0laK1pnbUhhekpaRC9EWnovcnhPenB4LzVXai9iZHl0S1BDNElYUlJwUXNEU1d4CkdXRkVUSnZSR0VPMEVjMW14T05tYUpmbHpHc3d0RUdGWDEzbFd5eW1nTHRMdXZ4TjBFWjVKc3VlRE5DT3psT2JuNDNsR3Z2djNQanMKdkpRdzNmUnNNbU00ODBjZCt2SVljN096dVZ0U3BRcmpjamo0c0Y5Qi9FaGVLbGE3dWRuMUNiU21zZG1JRERGYkVOVHNadjNjQzVvZApmV2syTTV0RWUyYzRxYkdwMXFPOWlObkhhR0IyZGRQTXpjc0dtcEF3aVJ1WERiUlJMV0pqY3lxdVJTdTJEY3V1Vmc2OFdObE1ObVpWCkozT2dxS0dvQ2xKMmkvbjJBbVZEQml1ZXM0UGNBUkRjbUd5V0NGUVJmcU1ndncxWFl3Y2tHOFhTSEZHRGtVMHBReWx2UkhaekFkRW0KWktPM1dyWXdINTIvaXVvV2J6NDIyNitab1UwaE13NlM1NEZqTjh2M1hteHNBdUJhT1doc3hKL1VVczlrYkt6K2hrOXdZMktaQ3k3OQpjTEZaZEtiY0hCT0lmWVppN0lKaW85OU5zVHlNTXl2b3RNOVF0US9qYXBpaXlkdStpZGljeUxzdzJRUmlzeDdRNkhIaTY2SnM4SVhECmpxcTN6Y01tWlBqYmhtSHp6NlZuczRITnFDcFRBdGdvYkpHVlJZY2dDWHRVMFZCdUR2WndtR1Jqc0Q5V05FeCtiUXIyY20rL0Z3UWIKcXdWMlJBd0c5bExUd0NCZ3I2UWw0Z3VBVFVHTjlxRjdoU1B6dFF2NjlYSS80UmY4ZW5ablpZTjlEVUJFSjU3YjZPdXh4Tng2a2EvWApWRS9qRGI1bTFWbkpxaUZnZ0pjTkpVUkN2Sm5pYkROUkpTSVdKeDBKVStHckRiNkdSZG1ORzN5ZDZFS25FSld5MDBWMGlRbndOUzBTCmxNNmI3ZGE5REE3d05kYlBUMmlHa2IzQ29vY3B5QnQ3dmFyVGFvRzlSajhPYlJiWWF6YkVZT3p0NWw3TE9sWHZxZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJaE0yVExQWWZodEE5cm5pOHVkZXdEaW5vemIxbW01RHVza2J2cDFqcHpiMWU1cmx2N0hVMEVRcnFOZW8xbXRkeUczcU4rV0o1WmMrQQpzOWRWbTNpOVpnalhMdUExakV5QkJ1OGFjWTJSODdlTnU4YlpOS24vZGlVekdqd3JiR1BXOVJvbWk0Wk9lUTBuSDI3U05kYTZUTzBFCjZIbzIxY2dHNWhwbHU0Wnlic2gxZDV1bXpiaHVTeDdiUmx5M2kzRzRoNjVtWmFZQjF3Qnk4S2VEYjkya3lIelJyWnZqY3NHMmJ0TjAKMFVCYnc3Qi9LYkt1U01kUTdoMWc2Mmo0R1Z4cjZoejFLVzJxTlhNVDFDa2FhdDBqYXhwTTZ6YjhTdDFJYXlTREZLTnlWZ1Fhc1AyRgpjSEpNVG5IZVBPc2FsVitCczY1UGFEQ2R0VWM1WkhNUng0WlpWME4zTnN5NlJnMVRzS3hoR0cxOGU2R3N6N0ZNc21iK2QraXJvdXFYCkpUS3NuRDhnYXl6cXBzVm1YRFFnbDZoaUlXT3M0YXlSZzMxanJITS9CVVNrV0dkT1pQTHhwS3Y1N0FsR0tGVmFic3o0NGl4ZkRHdlUKeDNEdEdBaHJRRkthZWRVa1dHT0daMlRoQmxpVGlQSW9qazU2U0l0aXQ4Qlh0K1k4NEUydnhpcUhTTm1BVitQWG1FOE5Kalc3K0tVMwp1WnBRa0J0d1hZTjRIZHpxNkNMN3dsWWo1YUtVcnFuVmRVVlkzTkJxSk9NWTY3eVoxWUJpODgwTFFEVk9xUm5uR0FicEdHOWdOWkRsClJZZGltU0QranBwVzVudGhVQkgrQmF1dWthY1BWald1bFpORm9LcVA0U0pWc3lLeXBrT3FidEhIUGtEVkxRcEpiazUxaTI1VndhbHUKVVVvU21Pcm1ibmczcFpvbEh6SXhFbzdWbjlJMlpsUmpBK1ZmTDBRMXpvaDNMUWpWSUV1d1NqMEExYTBxRm5uanFXSFRoMmcrTlF5YQpONHlueGlCRWljMU5weWFVaEJoZnc2a2htbVRvT2VEVUFCQ3BxdWxpVXlORnE3SGJhT3JhTEdJTk1qVSthR2JxYmpBMUZTT1BzcUtzCmRhZ09XbXdzZFlscDlxWlNJd2wvTTZsclpPY0RTVjJDVG40VHFVdG9Td0pJalFha0tsMDBqNW9kU1MwODJEanFqREtVcE4xRWNGR3IKdnMyaXprc3hvNXRFWFpqUWxEeWQza1JoWms5MU9nemVsbUp5NzRXaFJybThJdWltVU9kZFhCbHdhY0JzMHZyMllsQjM1NzNDOW5DRgptWVZ0OEpvWUdVMTNQVGdFYWk3UDJpRlE5eWpqRTMvNmNjTHVoWjkyYmVxaFR6OU9TRzM0Tk1iM21qK3hweDh4L1E1Nit2bVROM2dhCmZsVjZZNmN4QjZKbjhNWk9WelpsbFk1ZVZZOVZ1ZHViT1QwWmhHN2ZEblA2RVJicklLZVgweW92NHZSeUVqQ0kwMXkvSE53MC9od3oKdmVmeGJBMzRoazF6cTVJdjFqUzZSeHBIZlZqVGp0TnQxSFJYQ2ZraFRXL0REWnJleHVCTUw0Y21BaC9ORUdFYXg4QnpiQTYvN3EzcwpHRy9HOURFY3hQUzJCV0U2NzZyUEFFekhxM2p6cFZFTTBFZ2pGbDRhU3lXMkZ3cTY5TU5ZWktwdnVqU09rTnVZZ1pjV3BxRG1nNWZHCkI4MHV5aSs4OUVOSVl5a0hMLzA3SnQxcVQ0Y3ZEVkxCbU9aOTd4RUx6a2RuSGovdzBnWkhiTHAwRG1MMURaZkdLcHVwaW1CTEwvcXEKN1Z1d3BURVN6Zkx0alphR1o4Q0tkcE9sSC81a3Rab0JEaW5LeHovT3p6c0dXUnBlVVowenVBd2ZreUdHTHZiaTNHaHBPUVhTQW0yeQpOSW9sQVVFOFlHbmNxbVM1NHFPUGdHcnpGMVk2bTBpd3FkSm9TUDgwZ1NKSU1NQ3dKVVhSeFpTR1lLUzcxNEpHYllqcmpOVlE1Vld6ClJ1Y0dTcE0vMmkzR2xQNWJsV3liSncwRDVTQTNUaHJIS2sxdUZJVHp5TkYzcCs4bHlXMk9ZOTBzYWJpRzNiMHhpRlZoZWZqVXRiSUsKa05EWGtiKzlRTkxiR0J4cEtDSllUeHdZYWQ2aVZOOFVhV0pPeWpnUTZlS2lwTTJReGhZTStONElhUmo1VUlJZ0RTSENNK1lCU09QcwpyVTNaSlk2NEFBNU5RWTh1UzRqaURZK211bzArNVdGSDE5RG1CRG9hUlJOYy9nUVJHalFoeWlGdWNEVFdHTkVWazhiK0dCb1pzTkp0CnVLblJ4MmhvZEZ0V1h3UXorb3RUSFQ0M2hpQmo4aTVtdFByeWpINlkwZFRKc1d3dm1ORlVDRkltZnlHajhhRXlGckNSMGRoTUJPRlEKV0FGanpGalBSWXltTVYzY1o3M2NlVzFnZEdJQmFodHZZRFRlTDNJRXJoMjcrb0lZR00yL3AvbkV6OEd0RCtsUk56QWFNa2psRWdNWQpMVEZTK1VTTUp2U0JSYVZCaktha2tzSEZJRVlUNnNNYytrMk1wbFVNWVJPaitYaEdiNGNZVGVrSzgyNDNNcHBxbFZibVJrWlRxY0p3ClZDQ2p1VWt5WVB1dzR5Q3ZaN2c0a05GVXFqNnRibVEwVkRpaUZ0N0lhT3JhQlFNMk1qcVI3Y3NDQXlPajhVNktmSHNqb3lsc1pwQTAKa05Hd0VJS3dtZEZpSTVtVWZmb0ZKdlZYMnNob3FJK1VPUXhrTkhYQ2pEM2Z5R2lxeXhoaURXUTBHMll3dm1wa05BMTh6VzlrdEdScAovUkNqYWNDU2JST2pZV0hkNEFzWmpVc1MxRG1RMFJCcUsrWWR5R2pLa1pSN3ZaRFJiSzRiM3hGcnJSbTdVa2JReUdqRUpab3h0YUdXClIrQ01NZHdBUnE4bW9ldm1SYVBObnBvK0hsNzBhbEhHYkdBME54b0hGNDJqRU9oNTA2TFhqT2RxV0RRRGJvejhCaXdhbDBIUjF3c1cKaldLZ2lMS1RGWTFPN3VSckJpcWF2RjJWNGdRb0doRlJkVUUwSjNvVzRmdzJKcHJhbDZ3dzg2WkVvMCszMmo4YUVnMkRHSjFtUkdPMwphb3owUmtRallxY2laUk9pR1JTa3VpRUkwV3p5emJ6aFRZam1GZWRIU1EzbHBCNzNpTnFFYUZTOTlqcSt2UURSeTVXdG13L04xdHJPCmV4QjB5Szdmb2pkdk9EUnN4UlhOWkVQak1Bb0pDdzNOWHVDUGtKZEJoazRVSnlUakdOU0VKaWlvZ1liV1RPS09pQnNOTFE1Y2NUOVMKZGpzamIySHBXQUtMZ0pyQXNmMW1ROFBxQW1pem9XbEJzNWRnUTlNUVVPbk5ocWFWdFVuQmh1WVAxQmtrYUhqalRHaXQrZTNGaGtiQQptV0s4ellabWFZTUt1cU1BQkZYTi9HQnVPRFRMS2FoaURqZzBLaFNFN3dvNE5HK1FxaXd2T0hSUzhmdjZ0dUhRN0xmTkFIekFvVm5iCjhKZ09zK0hRckM3WldHbkFvV2xoSENqZzBMU29zK0lGaDZZU1ZTb2wwNkhaVTZpNXBsS3lEUEFpdXNzSU54NWE2bFNTMDQySDVuYmsKRXdVZUd0T1IybnZmZUdoNk5XcDFhRHowVWJFR0hocVdHcFRualllR1ZVNkg4ZEEwTURvWmVHaGExSHpxd2tNekZzZXFVTk9oMWRuRApNaUNoZXhCbTR1QjJBNks1T0tKQUpBalJpZEJmWS9ERmlXbHVoZjRpUk12S1Q5ZUVhQjVMOWFzaVJNT2diZzQzSVpvdFVpaGFDRUswCkZnRm1SbXNwWE1aaHFHOUN0SXFubW5SMVV5VTl4WE45SUtLNVlKa3UrdCtJYU1xMHhaTTNJcHBLYm4wV1JrVFRvZy9nWWtUVFN0RkYKTUtJbGxjOW1BVlF2d0V3MHVCalJFc2JyY0ZwTnd4OVpKdEVURWIwVjd5OUVOTDFDOW04T1JEUnVtUVNGZ1loV05PTVRJWm9SRGRYVwpHaEhOY0FhbnVHQkVLOERSamU4SVJuUTY3VXpNaUhaMFpCNUdOQ01xTS9BZCt6Yy9ybEorV2pDaTZRVXF1UjByVnN5dm54SFJXQXhJClNCSWNTVmJhcUFpVWlHaVMyWko3S1c5RU5BTy82dkpnUkRSZU13SW9naENkV3JUTHZRalJMSitpeWlZSTBXd05LSTJRQ2RIMDVIT3EKYjBKMDJvS0JJRVRMY3ZqUVgxY0FlMjJBMGZjSnVYL3dvWkVFWk5vdThOQ0o1SXRIb0NQNWQ4QUJrdmgyODZGcHBUVFlmR2djWDVMegpBRVRESWxuNkRZaUdWWEptODZGcFVGclFnR2habVBDNkFOSDRSYmFtQ2o0MEVwUE1Cd1FlR3BtOGdQZHRQRFR6a0N4VENqNzA2dFk3CkJ2WVpRMXdrd1RZZGVwVEl5TnJZbzhOd3NLRTdxc1Vka3Qxb2FCZ2ZzNXM1czhBZzFJN0IwSkJTVDBXd3RtdlBkcHJVV1pzSzNhUFUKTkxicTFSbXNtd25kM2Z0Nkk2Rkhjc0lxU00vb3E4MHA1Z1pDazZpODZqR3lOM2FUUHB3NDZHMjRhZERIYUJqMDlIeStJYytBT2FtQwo2MEpCaithdytONnFDSHV6U2REYmNJT2dqMUVjNk5HdFBnME1OS2dTQkx2ZEZPaU54QTRJTkVMUFRBa0ZBeG9HTmErN0VORFlMVGpPCkRCN04wTzRFQUhvK2Z0MXYvdk9JRmx1QmZ3YkVSWDBEalg4R3RVUjB5b3YrVFBTdkEzU01wMndXY0xDZlJ4SlM4U0kvdzdRc2V5TUUKQ0lZYURlSXh2UXhEbUcvczgzZ2luV3ZxODNCRHBBMTlob0Yxb1RmenVkc1AyY3huQkVCWm94SEk1eEVmN1VFK2I2UmFFSjhCWldOYQpPSURQNElSdUZuWmdpV2tzTWpJaGo5M0VBalh0K2NNZ1R1Rk5lKzVKZVYrem5oR1FaVm8vVU0rNllCbnVYS0Rxd1FMMGpIUzMrbkdaCjh6eThTbjFobnRuM2VkVkRlZTVhZVczR2N3L0k1bzE0NWluVkEzakdEV1lGalBITytMdll1MjFuSDJGK0F1N2NBNmtiYk9mcktKdnMKM0NNekdtRG5FU21rb0RqdmNlREdPZ09ZcURKZVU1MHg1cVViNFR5alYrTE5kSjdkWXZTOTFUS3lQWWpPa1BJMWs1b0Q2RXk4NWF5SAo1d3hEOTAwa3pubUdoT1RHT2MvZ1J3Zk5HWFVPVE00RnpCbkVhdmJqdkZET2k1SHNja2pPV0NvejcyV1E4Lzc3NWpnZm96SE9RTHBFCmYyRldiczFpWXQ4TmNWN0JTUXFHTTlhUyt1cUQ0WnlvYlhjenU4MXdobFVMbUlpNlVYMURrdWJPcTJONVpEanpidUVMYVJPQlZJRncKaG1Xd2ppQVl6dHlHSC9waE9HTUcxZlFRREdjMGVIZXBMdEw4V05Qd2hiajV6UitYUjY3SXhqZnpsSGgzQTkvTWd2NFp2T1ZkUkFLbgprUmNkL0daVzlFOURzTlZaTUVYWDdadmZ6R2ZKUWduem0vbEtOQU9pSlY1T1ZqTysrTTFzRXhsWG9GQTNQRDBPWlFZNGYvV0RmdnpoCnZ5akFtWEZCVXE1dWdET3RsRGdFd0ZuUndwSVBzSmxoUURXTHVCRE9ERmRSSHhRSVp6eFgvNElSenVBeDhnVzVDYzY0Y2hVWUJzSDUKckdhRDRLeHZlbW9DUFlGWmRueTFENlhNV283Nnk3WmpsdDNPU0h2RkxNVmgyUVJuR0tRYUNJSXppMGZWOGVFaU9PTXFwVTRMZ2pOZQpPMEdiQXVFTTEwNkNzcHZoZkR6WVlEano5UXlwaGdnUFpGSU1wYkEydy9teW11SE03cjBNL1FmREdSYkp3MjZHTTNFUFZCd0Z3emtSCnErMEtldlVTaDZDV3c4dk5jTVliYXpXR0djN1U1YW42MVF4blBGK1ZJOThNWjFTbmtlZ1ZDR2VVYWdtWDdnTHI1UVkvTDRBejFHWEIKbDZmSER6ZWFRMGZ3bS9HZWNIMXk4NXNaNE9Gd0hmeG1CbmpFSmZCb1FVdHpEZWlwbHFMVnJYMnA0K1N4V0NRZC9HYitaSlp3WitPYgpHYWlNWnZRcU9Yc2VSUUUzdm5uTllHd2ZlalBLYVlSWE5yeDVEcTEyTjd1WjVUVTg4d3Zkakc0d0FrR2IzQXpwSkN2MUE5dzhvdkx2CjVqYVA3dUV4c00wamlwZUQyanppNDdtb3pWallMQ09hR1JRWkp0c0dzaG5rUE03N043RjV0Q0JJR05nOGhzdWlqV3NHSW94Qm1rTnIKUnRzWURzMUJhNmFzZ2lYL2hqVjNCeDlmckdaUXVoZzNDMVJ6TDI2OVkxQXpzVjVENWRDYjA4eE9SNDl3enJ3c0hJYXZZRkNhMlgxKwpLSm04MDNJOUtvQ2p0SnBpUDBNWVdCZUpxNmlQR0FrYjBjd3U3MVdmTlFOUVNOVHhXd3BBTTZocjlFQnZQak95ZHdRakI1NFpFQUhHCnhJTE9YS1A4OUlZelF6WTFTcWp4SVBNTHJ6RFF6TVF3ckZCM1dqUU12UTlMNHdQTXpGWmZ1Und1TS9qQlZCZmRXR1pVNEdxTllDcHoKYTk0cW9NeFlGN0hFOEdZeXc4Z0ZTRENaSVYxcTVpaHoxUXh4azBpSkY1SVowd1RCOUVGa2J0V0Z0ZGR1cW1pOWVjeGNpaEhnWUc3TApYamNFanhuS0VzN1NONDRaVjhCZkN4cHptNmU3TnljVDFGV0pvSDNCbU52d2x4WXM1aGF6VjZDWWNUN0ZqTWFkQk1lc3dnS1RJREZqCktocVhxTE5OZDd1NE1jeHczclg4TjRVWnB5WkloQ0hNRURuTnRGNE01aFdMdEdBd3J4YTk5NHhnWHQycDQ0dkFEQzJ4Q21rTllGN2QKUHg3OFpVRWJ3ekMzVGxqTm5BeGZYczRGYlBZeURQRmJHNzNNUkFmWEJvRmVqbVRFSmk5RDVFWHF4dzFlbmlNNktwaTd2QUt3R2RqbApGWUh3aTdxTVJJdmVtNzRqOHNFY0NEVXoxeitVdzkvVVpWcEZFN2NNTHBHRGE4V2R2Y2RxanNsTlhZWjFzZUEvcU10a1JQbTlrQ0JpCk4wRzVvY3ZYNFF4ZGhrWG9wb0F1cCtSQ3R4ZDBXU3VmdFE1MG1mbG15azREdWl5UWdaVmxoMDhQUDVEQ3pvQXVNdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJemNzNUxhRExYejNJQ09wOVAranljck9wRjNONUxRRVdObklaVmZPc2p3bmlNcHlIWkFUejFob2hIY09VVWZDV1lWQnBzbkhMMkkwSgpxcHUyek1MWWVsakxLNERKZ1ZCV1FQRmlMK3Q5aGtpVEphK3hHYmlQNUFZSGFmbEtuRjJrWlM0TnFJc0kwaklYWkV6aEIybVpZVTZYCmtHNWNNa09kQWs4YnRNd3pVNWU4Y2FLYVJ0dDkyck1ieXF2KzhUQ282R2RFaVVkMjZjbkZXV1k5aCtxdHpGbm1aUS9XVjVtenZDMDMKWnhrN2ltd1NuR1Y4a2FUN2I4NHl2S3FxcXBXTHN3eXIydmtHWnhrV1NuazNhSmtPT0IvUkRWcW1sNWExR1JPRW9EU296RTJZWlc3QQpSM1pqbG5saWpDUUhaam50bmlTQldXWXBDQWZkQzdOTVkzVVhCdEhVWU5Gc0pjd3lCejBXbzl5WVpUcVkyVUw5b2hWRlVzbjJ4aXpECm9qS0ZHN1BNSmJEbURHT1dFd3ZoaW5TOU9nbU1IU3hkdURITFhCUlREeDJjWmF4a1dRTVNtR1VsZFV0OVk1WVpOeUdwSXpETFhDS3AKVzRReHkyU2pWY3MrVDhROWgxWTZNTXRrbzAxdnhrZWJnd0oyWTVhcEptRjB6SmhsR29xaHlnemdjVWVobmkvTU1qS1d2di9HTEVNTwpvczVOZ1ZuR05ycGhOMmFaYU1VZVF6eFRuY3ZoOGhWc3B1VVl6QTFaSmsyTGxUVjd1OVlzdEEvS010YU5lbmx1eWpMankyUTlCbVVaClBxWWNqYUFzSTNhZ09OaE5XUmJYYUk1RFdhYjJUNStnS2N1MFVFcC9VNWFscE96elVKYkZ1Q0pNeEpSbDdxa3lxNHV5ekJCNXdMWVgKcGU3SnE1MmdMSE1oS1hqNFJWbVdmSExOUTFubTZVZlJLaW5MQ0dBSmYzRkJsbUgwTHdxeXpEQ1hUc3lRWlZvWUVMb2h5N0NLOVdmSQpNamZUdlRCa21jZE9iaXV4SWN0YzNZak5Fb3pMc295R00yVDVHRzdJOG1VMVpCay9vQ2hMd0pNWkxsSUMvNElzWTZrbzcyNXZsNzIwCkNzYnlNVnlJNVcwTXdqTFhjOHJWbTdDODM5Y1hZWm1wWnhJR2dyRE1rbmVxQm9Ld3pPUmh0TTdZZWtsYWwzMUJmZlhJSG5LMUpNSXkKYzREeFp4VFBTS251cDJHdVkzT1dMUURMM0lZcjNodXdMRUh5VElldzdDREhQSVJsUnFybUo4QXlzWjFQam5ZRnlYa2hJaDhDc015dgpMekw2VnplYmFzY2pBTXV3OUdKMWdFaW9yY3FkZWdHV0dSc2ljU0FBeTdSb0hoTmdtUVlKRFM3Q01tOC9NOWFCV0dhcW00SzFRQ3dqCkVLQkt6aHV4VExTVnV6T1FhZ3VWV1ZlM1FCT1dNZGFwdmRsTldLYXVJMGZ6Qkk0Q2NIMlVYVGRobVRHVGt2SWJzUXdybWVBYnNVd0wKSDFJd2xtbWhRUEZtTFBONFZPVUVZNW1SRTVWWHI3aE1GL2E4R010MGFMTjdTVGc0WnU3T2hpd3prZEJHOUdhSW9XZGJBN0xNR1c3MQplaURMdkdmc0xYOVRsbUhWaXhhVVpWaWtsQXJLTXJlaEJPcW1MTlBLUnhXVVpSSDJSaitVWmNvSTFjdmpLbm1qTkpMMTFFRlpobktICnc4cW1MRE03UTRmMnBpd3phczJLKzZBc3M0Q1hDc1NnSjhPZFlJdXpGMldaSzZkMEdWZW9NUUxLdVEwM1l2a1lUYUpDYnh6eGNneFkKL3VMVmY5ZUZBMi8zMHc1R0RXdUd3cHVidm0yOE1wNXdtWHJFb2l0M2R4dDd3Wlc3bWF1YnJkd2RNTjVvNVdsVXc0dXNQQjBaM0lCawoxNmtmc3ZLTWQrNEdLMDlHNHU2OXhNVGRWT1hwOHBJWFZCbEZZMVErbWFuTU42VGxRQ3BETmNKSTlVMVVEdER0QmlwRHU4VWhMVURGCjJmV3ZOMDhadG1uR3Nwb3VkUEYzQXFiTVBOSXFiNVp5ZHVYTVppbkR3SFphZ1ZLbXB0NGg4UTFESTUwYXF4aWhsTkVSWTZ4MG5lQ0sKdGU4RlVrYmhBc0d3d1ZFT1BOTEdLSmRvOUh4VGxDR2NZb2c0SU1yVUI5ZDVHTXJBSjYwWFFMbTBjQ0xOVHk3UmxEZnd5VXd3T1FHNgo2Y2xJUXlzN1pYZ3lLZ0thR2NzTTZ4WFRPbTUwTW15azhRVTV1WVRRTDhESnlFa2htdkxpSnFNVUp2cm1jbnBGcWtFWlI3OUJLRG9SCklmdUNKdGRnT1FZem1WRzlOUTR5R1hvUFpvbHZZaklTT1BTNkE1Z01DVXEzSTA5SlViZDI3b1ZMN2srUUVFMUx4bTZNakFjc0dRZG0KYU81bUpUZEwxallxdVVYUHpTQWxOODlTTDFJeVd0eEZZb0drWkdoWW1Pb3pKeG41NTZGLzM3TXBWMW1QdmlHc2ZvZEpUTUZJUmxmMQpyckQ0cnBqQXNpK0hiQXNmeXpBRmEvT1JzUmY3b2R4NFpBUmNsRUUwSFJtT0FSbnNBVWVHdms0bExSY2JHZGZhWFF0QlNDb0ZLazBCCmRRYXFJRDFnZ1BrR0k2dGlySDdiWEdScUJwem1ZZWF6QzF6eGdpTDNhQWtTVE9SZC9oNUk1RzRveG91SXpBWXFQSmFCeUtkWTJUemsKNGdMWUZ3NjVCaDR5YU1nZzlETFZHRERrVmc3b05WaklCSzF3eGFLSy9CWk56NEtFM0VLdGVvT1FZU3pFR1p1RFRQWUsxeS9HSU9PMwoySmJpeGlCWEYyTnNDaks4TkhXR2RDS1N1ZXVscGRkbUlDT0x3Ynh3SUpCQnRlRjNGZ1RrRW0zWGJ3QnkyYzM3ekQ5R2hZWkltc1lmCmsyWm1odkdtSDI4WVVjQ1B5NGlwejZrNUdBaHF2ZEhIZk8wc0RlTzhBclljNWRzQlB0Njg3NXQ3akpveTFSdTZLS2RrVDB1aUhtY2sKcEl4c3Zwb0xPVTRWekdQa1padTNVaSsvTGhibkRUek9YYXIrelR1R2dSQjk0WTV6Tk1hOGFjY2YwenlyQ3cvc3VKb01HYXpqeGdGVgpOWDRiZGN6V0NtSEVYSWo1Z1VXdVFUckdPNTJOSzk2ZzQ0Wkt0NmVlc2tJTW00T2ZrREhIaUM0OTVpTnZ5dkZpTWpSOTI1RGo2azdlCm0zRThWQUw2Umh4L1RKakxnamNoanBPbjVTQWNXMmY2NGh0UExxTnN4TFFsR1o0b3lNeVNUWUo5bmJTTGRURmdJbWxKVVUyNDhmUkMKTHVER0VTZC9vNDJsK3pwazR4R3RDZ3cyenRIaTlzVTE3cXF5T0ZoakN4TTMxWmhKQUpVcEhxZ3hreDVSbFlqRnI2R2ptMmlNdHlJWgo5TENCeGlnSlcrWTZrR2VNOTlrTEVYMGxIUHUwcHRrMDQyS3ZLV0RHT1h5QVlCbXpSdDBqYnFDTVVlL1dWVzFKVHdtTEdyNlNtMk9NCmdqT2psQytNc1NYZFFURnVEQktrQXpIbXFvcGxxamZFV0FxU1VRN0VHQkhVajNWYVB4Ump5am1mc0lUc2lWclIySTQxQkxEVTZuSXgKUHJpdi92ZjM5TzR4K281WVNKdGlYS2NiVGdiRU9GaGxtMkhjY2tocEw0UXhBZ2pGMUVsNjFjQmRVTTBUQUdNU09Lb05JWlVIOGtKTgpndXRtWUFpcUd2VGlscDNKdTlqRkxiUUZSaGNqM1VxOVo1Q0xrYU9VQnZ3Q0Y3ZG1mSTlqNTFDTDBzTXhrUmo5aHlPeEY5amltU0s1CkxCc1JzWFVjYVBGS0NpQzhtTVV3c21vaWtNVXIrbmNFc1JnZ1YyK3dYZlNWUEtjR3JoakZXQXJlZVN2OEE5TnhONng0VHJkRURsYngKcHZNR2doaG9DcnFYTjZsNFBQWm93Z2loTUhOeHdTbmVoaHRUSE1aTktSNmV3VGQ5R0NKZXJuNXZTREhFdHdyazJEaVQ0YVJDRko4LwpMMEp4R0RlZ21IRGxWUStmZUFSVzVNWVRRNHdzTXBEcHhLTTVZeDEwWWhpbWVickhLNDFlMzhFbUhxRk9DaER4YU01aDNtUmljS2NDCmFZelhld2IyUDdqRStHdzJlamV3eExQWm1RNHNNUTNsd2hJemZwM2VVT0laSkNjemlhZmJnUVdTT0ZxSDMwQmljQmlWblRhUEdKcE0KSmhxTkk0YjZrdmZ3cGhGdllGYkFpSWxjWkRyTUxPTHBEL1dGSWthcFVqSWhORXJuMU1RMFNNUXdaRWZQTjRpWVJzeEV3U0VHMDRrSwpFbU9JVjdFRGVGT0kxOTBXRVI0TFVjOGpIUWd4Uys3eUcwRU1QQmREWEVFZ1J2cGVsUm9HRUVlejlSZC9lQVpITmZERHk4dXFUUjltCmxTQnh4QWMrYk5iMFJnL2poRlkvNE9GVkpObDljWWZ4dWJGWUxyRERLMHBoZ2pwOEhXWXpoMmNrWkFNNVBKMmEybnpoR0FaZXdHR28KWFVVME5tOFk1TEErTG83d3FCNUxiOXh3RC9adkdKRzFacXc3WU1QVW5NLzZaZzBqZ2ZTNDZUQkNIZmc3R1VnOEpjQncyZlFGR2taaQpLa3FuUlVOOGxIVFltR0drdUpwNzFXMHRUM2VnZTBPR2V4U1dCV040RzI3RThER2FNTndOTjlwOFd5eHBrMm0yR3pBTUtEN3h1VjZRCm9LQXAwSXYwVktxTDhsNXdZWkNqVk5SdXRqQldQQUpXR2kyTXRWQk9iN0F3VmxPcDlNTVZ4cG9yOE1QOHlxckZCQytxY0xNb1kwT0YKZ1JscTdTQ0ZSOUN0RDFFWWdpWWlKUU1vekxXWlM5dFkxa3h5YVpsdm5EQzlzZFFPVFZncjJYNWd3bHpyanZ4bUNXTlZ2SXdtNXEyRwpRUVg5UmdsWEt6TmZKR0VBcE9LOCtYMUVIbXh6aEQ4N09qOStSeWZxLzM4WTRTOTQ0RDl5NVBydDcvMmozLy8xZldBYzZBOS94Zi81CnMvL3JMMy9SRC96MGg1Ly85SC81NWYvVnNkdno3ZS85czEvKzdDOS9ZNi8vNFM5Ky9kTi8rc3RmL2Z6TDcvLzYydjZQL2NZLy9hdGYKL3ArLytPVnYvdlNmL2VGdi9yM3B4MUczOE1kKzRILzdpNDlUK3A5KytZdC84Mi8vK28veWttUFRQL3k3UC8yNFFmL2pYLzNoOS8vUgpiWC82NVYvLzlYL3l4cmpJajd2eUY3LzgrLytNYS96eEQzKzVyeEZWM1IvRDR0OTZqZi83WC96NVgvL2IzM3lXLy9DSC8rYnYvNlB5CnAvL3c5My91L2ZCM3c5OS8ray8rOFB0Lyt2R1MvZlhIZS9hNzM4bjhEMzc1TngvWGRmM0RELy9rMytGZnB2N2xIL3pWZi9qMy96YU8KODkvK2sxLys1cHYvK0piK3V4K2ViMy8vNC8vKzVkLzg4QjkrZUlHaG4yLy84OGQvL044ZnByLzVWci85NDIvL3gvLzVmUHR6YlBuUApmdmpkQktPUS8rL1gvUWZxZ3JDUS93a1cvRUZ4N2g4emYrenkwMzJjbjM3NC9jZXgvOWNmNEZ3endmVkFmNWIxSDFoK1Fwby9vTndGCkRPaGp5ZmV4OHNKL2ZJekRuUmJHNXY3bG4rR1lrTkpYMUgweGlKVSt4aG1lSmNaM2xHb2ZNNHhWMkt1SkFNTEhEOVpQeHE1MmNELy8KOERZREZmSHhDKytqb3BqbFkreDVuNEdOT3NDUU9QNjlyWU5QNzZNZTQrc01qdms2MjNQVTY3cSszSU9mZi9qWFB3Q3N0T0JrZ2lySwpmQmpVUFFWVEsybmhINjcyUkluRXgvSVhtWEFVSUMwVWNYN2MxL1I4KzhmN0VjS1BUY1FuUDM0Rk9EdTAyd3dqWk1YUUlLcHIyY2RNCjlEWW1wVDk0YVpmNUVTWGlkZFNQNldqaEpYaWRRUmgvL3UwVCs4dVBLNDUvWVAwVEpybE1rRTRjdTl4bW53V1dySk5GRkwyblQwYnIKaC9ZWjIweVFWLy8yT21yRGVxR1ViNjh6Q09QUHYzMWlQdVAvK2dMLzhSZTR6cHBOU3B1TXBIeXN1NEd3UVRGQnhidjdNUTRRQnRpZgpnZGc2NFFFWUxEUTJBSE9ITFA2blcwdEJSV3J2VTRBb2dVdWkrMlF2NDMxaGwvbmNoT3VvNTNaZFozRGYydWpmOE41MmtxdjI2YWpICitEcURZNzdPOWh6MXVxNHY5K0R2T0RiOGpxY3lRTHo3ZEY5eDJ0QnJ2SDRmRjRnby9ldE1MK045VlpmNTNJSHJxT2RlWFdkdzMxZjgKQkZ6bjk3YkladVpQcit4bGZKM0JNVjluZTQ1NlhkZVhlL0JkWGxsMjlYcmE1L0VMZ3c0cTFsN2pWMlBZcXJ6SHI4dDRqMStYK1l4Zgo1NmpYK0hYTzREVis5U3hGOW50YmxuWitQdW94M21kd21jL1pucU5lMS9YMUh2eXNvUkp6Q0pRK24yNE81cENuZkRvSXBvdktMK1FlCjNJL3hOYmdmODdtTWM5VHJnczhadkc0T1pyeUJRT0pyVy9MKzE2ZWpIdVByOFJ6ejlTajNVZStIL3VVZStPWmN6KzJlcTY5bmZPYnEKOHpaY2MvVmx2T2ZxeTN6bTZuUFVhNjQrWi9DYXE4OHp2cmZkYjhOOTFHTzh6K0F5bjdPOTNzZHpYVi92d1pjMzUzVnpybWQ4T1RMNwpiYmdkbVdOOE9UTEhmQzdqSFBXNjRITUdyNXR6bnZHOTdYNGI3cU1lNCt2eEhQUDFLTS83ZUQzMEwvZmc1ODhlU0dNZmkvYlpBd256Cnk2dG9UTEYvY2tzdzIwaVA4VFpia1BjK0trdVgxbnYrRCtNbkQrVGVkbnNWOTFHUDhYVUd4M3lkN1RucWRWMWY3c0hmZlpvOFUrL3IKdmg1SDRmcjk0MUpjWjNvWjc2dTZ6T2NPWEVjOTkrbzZnL3UrSGtmaDNuYTdGUGRSai9GMUJzZDhuZTA1Nm5WZFgrN0JkNWtteit6Nwp1clhIVjdoTzRYZ1YxOGxleHZ2Q0x2TzVDZGRSeisyNnp1Qyt0Y2RYdUxmZFhzVjkxR044bmNFeFgyZDdqbnBkMTVkNzhIZC9aYzluCmdFOW5sQzlEUVpoZm4zZEhxWW85Z21Qc2dvRjhHZ3B3cVBxTTkxREFaaGFwdmovRU1INGFDdTV0OStkOUgvVVlYdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJWjNETTE5bWVvMTdYOWVVZWZPZkZ5T3ZXbnUvMk9vWHpoVjhuZXhudkM3dk01eVpjUnoyMzZ6cUQrOWFlNy9iZWRuL2g5MUdQOFhVRwp4M3lkN1RucWRWMWY3c0gzWEl5ODd1djVhSy9mUDUvM2RhYVg4YjZxeTN6dXdIWFVjNit1TTdqdjYvbG83MjMzNTMwZjlSaGZaM0RNCjE5bWVvMTdYOWVVZWVHb0hXUWdKbkU5K3p4QSsvNVB6WklYNzI4MDZ4cGRMZHN6SFF6bEh2WHlaY3dZdnYrZnJpVGtjTXI2NDl6eHMKK2JUMjRRbG8yMnMxY1l5dmxjY3hIMGY4SFBWeTJjY1h6LzUxT2pqRmY2NVE2ei84L1orL0FxMy9LZkhYOG5lTHYvcU9mUXJDbmxncgozckEvWW94OWYvcHl0Qk9LL1RzSEMvSHVkcTNlcVh3cForN0lqUFdGMmZNQmlKVmVaNmYyeVlnMWVXMW43ckFaNi9kUnY3MlAycFQrCmY1K0JqWHZ1V0dOODJuWkk2ZjArNmpHK3p1Q1lyN005UjcydTY4czkrRzV6Qi83OTA2MmxOMUUrblFMOURyN1kxOGxleHZ2Q0x2TzUKQ2RkUnorMjZ6dUMrdGMwNjIvZTJVMEsxOTFHUDhYVUd4M3lkN1RucWRWMWY3c0YzbVR0WXRmSHB2dkswODZkWGxoZFlQcjJ5bC9HKwpxc3Q4N3NCMTFIT3Zyak80N3l0K292YithZHRwS2NQcnFNZjRPb05qdnM3MkhQVzZyaS8zNExzRnNsQVo1ZEd6ckJPT1lJdkFiZjZkClJ0dzhhZ3ptWlh3eW1oYTh3eEUyUHlvWWVSMlZnM2VhMzE1bkVNWWRqb0JvOGIxdGtScjJmZFJqdk0vZ01wK3pQVWU5cnV2clBiakMKRVUyZTczMXpPSmUyVHdmaHROblQrK2N1NDMxcWwvbGN4am5xZGNIbkRGNDNCelAvbk92VHRrVWxZZStqSHVQcjhSeno5U2ozVWUrSAovdVVlZkljVjkzNDVJbHQ1V1R6aHYxOUN1d2J2aDJYanA5ZmwzbmEvQXZkUmp6RjlmbGZIU1ZEdFJ4U25lRm5Pd2E1WDRmenNkY3Z1ClU3eHU3N1h0ZmhEM1VZOHhmWDVqZklyZjhjT1BYL3YwNFlmNWRZTjREYXQrTXZwNlA5M011RGV2bzM2S1Erb012c1FoOVNRL3hTSDEKME82akh1TjlCcGY1bk8wMW5KenIrbm9Qdm56NHI1dHpmYUxuSU9mUlhEOTNHZTlUdTh6bk1zNVJQOFVoZFFaZjRwQjZoejdGSWV2bgptM01aWDQvbm1LOUhlWWFUNjZGL3VRZmZZU0pQMGkxK3VxL1YzVHZmOTlYZDY5NzM5UmhmOS9XWXp4MDRSLzJVcU5ZWmZFbFV2MC9zClNsU1B2bGNYTVFYZzJDbmZacDlGbiszVEZIQ01yeW5nbU05Z2ZZNTZEZXZuREY1VHdOY1QrejdEd3ZhTXcrWDd0RG9JODh2anB5Zm8KNU1BeDJoUDh0RHFRMzdxRHpENnFQZHozR2RqNGFYVndiN3M5L3Z1b3gvZzZnMk8renZZYzlicXVML2ZnK3dTWjVSYS83dXR4NHEvZgpQKzcrZGFhWDhiNnF5M3p1d0hYVWM2K3VNN2p2NjNIaTcyMjN1MzhmOVJoZlozRE0xOW1lbzE3WDllVWVmSzhnc3ozajE2MDlmdngxCkNzZmp2MDcyTXQ0WGRwblBUYmlPZW03WGRRYjNyVDErL0wzdDl2anZveDdqNnd5TytUcmJjOVRydXI3Y2crOFRaTzRSaFpzajljOUQKUVpoZm56ZGpZUG5UVU1CNFdadWZod0ljQ28yRTNrZEZGTzc5R2NyMGFSZzQyKzBQK3o3ZU1iNSsrNWl2OHp6SHZLN295OVYvNXhEQgo2NmFlTC9ZNmhmTnRYeWQ3R2U4THU4em5KbHhIalp0MS9mNjVxZWRyUGR2dHIvbyszakcrZnZ1WXIvTTh4N3l1Nk12VmY4L2d3T3VPCm5nLzErdjN6U1Y5bmVobnZxN3JNNXc1Y1I0MDdkZjMrdWFQbkl6M2I3WS81UHQ0eHZuNzdtSy96UE1lOHJ1akwxZi84bngvOS9PZS8KLy8yZi9mckxuMzhicjhqbmYwYnNzK1lGYVMyazV2Z1BNR2wraFJXNE45U3pIL05Qbjh6dFk5SFRxOHpuR0w5dDNZZjRQYy90ZXdoVApYK2N5MUlKN256bmNRSnJseThrNGJIdjZyTGExNTJOaFFXTjZxRytYbWJXR05MTkYrK2NyOTYvOUJEK3pFdVVHTGdCNmxINmNlcDgrCkRkUzNmTHpxTkpQQUxDUDlRUDBrcWdwa0pMSkJQemhMbk1kZ1AwQnQybVAzanlGcCtkSlFSaVBqeHdyVXY4OWF2OWo5K2ZnUS9mc2YKYjVvdmVlMkRLdEl2bzI4TldSQnhGOWpTeDNjc04yL0ptbTM5UHFveGZMOHdubXJMUkxxbHpPUWk2cmJnZWZxazBKRlZScFRmK2FxZQpNSDQ0OXVmeTBSalo1Lzh4SHNlbWJYai9jd00rUFlBZjlXVHl3dzVpdEdmMGF2N1ZWcmFTcHJVcGxDL3JTUDQ1ZmVNeXJoWGI1dDYvCi9kWlI0OWZtbjlUMCtCK2VqNFdCZjI3dTE3R3JlNnFOV1FjQjdHcHVtMTREZzBGL2pQM0hpQzJmN0UzWnhVZkhaSmp4dDM0L1Rnek4KWVBTRTBXYWtGcDhZY0p5NnVLWWlVaHRSKzJmamFtRjhZc1BGK3h1YkxwOXY3M3QzRkJqS0JvVDJiLzcrZit6NXNORUt6ZXhuRUErSQp3RlZ2WGVOWlZML1BiTGd3LzdZSDlBQTNuUDJkZmJ4YU1kS2gyVW4zUzQxMXFXMTdhR0R2WEJqQjBXditKTmd5N01mWVArVnNNMG9DCjQ2RHhwZGFoczMzWURPTExkNzZFRHRQdkkxTm8yOXpuMVBmdTcvUDNoU1hVdHlYZmRiYUEvelhNVCt1WCtTZWJpYXlSK1dNMStzM0cKN2tmTTFoTzJvUkJkeGhUajQ5ZGY4MEFJTGdES1RmVVBZTjM5YW5NQ25rU0h3WXRnWTA3K0tqaDgyUWpJc0o3YzhnY0FhNHJ4TFkweAp2T25UWTNRaGM4REc5SGgwWUdvNURoQVBzK3RSeDdZamJnNGV4bTlld1hsMXh0TThtTEtUWGJ3NnJGV1Z1UTNQZXl6STJXYmdER3ljCmNjVWx4dU12eDQxSE9sV0FyWnUya3VlMlpCcTB6TlgzY3FvUzA4K3B0REEyRHpDRFk4RW40OHc5NzcxekdOdGEzMzd6NTMxZTZBUFMKdTZiMDUxRk14ZGJxTDRQUm1EQjZXbGdqNVczci9nUldxejR2ZHV2TVBmYlhKNlFXbmkxKzY5ci8rdms0cmUxcGdEQ2FQQVV2QUJwawpiQ3ZHRVJobjgzTm9WWGVMeHNldkNFSDhYNHhsZVdiODhsdCsvUWtnS2I1bkJYbWlYOFA4ekI3bXdXdWpjYVRmTU9ZUnhuai9VWFpaCnVzZlpqS1lETm83d3VQQ3AvT1lKK082d0VWb002dXlTK0t2Tk9SZWZCRWtZTXNhOGp6ZXNaaHViUHhaOGJUNHhTYTFHekVJbE52MVkKVmVUM3JQTDFCTTUzeFQ0akdoTFgzSjhWdTk3RWlOajhxYkFOaDQwbHZwK1AxN1Nlc1ROR1ZLNUlQWHBxZW53SVMyMnhxZWJjTDc5Lwo3dGo3Z24vOURXdjlqVnZ6TVhyOXE3amxvNGNaczhwUFlVWnJKcG5yRTNlSHpXTmtMSG4ra1Z1dXQyeXFiU2x2SlNlUlg4T2N3azFnCnRiMk1wTHZLT0hRZldQd2JiZ1lCS2ovK0VPWmNZdHVSWXR2Wi9HTk43OExYRTRneks1TEllSnpQZnBqczlWNUx2RkRObjJFQmd6S0YKZVNUOVhoRml6a2FOUlYrUDZ4OUV4ZmFZNjlyNlY1dkRKMmppSmRyWTloQ3A3K1hEMXNyK3RSYnpHOHg1blRQcnNTMGJHK2drMGd4agppZy9XbzZSL0MyT2dqeHUvVld1TGcyclErWHIrY1dHZ2J6emorckZmd3h4dUdLdWlaUHVZWDFaTTVuT0ZjV3lmc1V3UFhEQzNlQklzCkU3Y3hMbUZsVGE2d1BUR1FrTXo3NDIrZmxrZStpYTQyc1lDaDkvQ3J6ZWxKSHRXSEozNFlTN0ZuUmVLSmpSNDB3TGZ0OXF5bWNVSTYKYnRJUzRzTlllNDhmKzFqU2Yvdk5NN2g5dnZnNStORXh3SEM5ZHp3NUcvTzR2TFBmSGg5c0JZN0wxaGJ6ZTdncDJIL0ZvUE5IUEw0eAp0eU9adHNjNFJoaWY0NGUrVHYrOCtuUXFOUkd1dUs1b2R5TnppMitOMkM5TjhaT1VjZG02YjRHUDhKdUg5ZStoajBiekJYOThnZlpHCjBPOWlMMGNuOENRL2hmbXA0M29ZUHNLb05ZeHkrTDRjTmk0dmlZYjErZkt5ZUFOeUV6U0N3N2E5WjFJeFpVdzlKaEIrS3ZFQ2svUW0KTXhhQk5xNjhEMURpQVBtSjUwNmN3WSsvZlY3bkN5QSswUzl3S2VjTHVONXJyV0cvdnV6LzZtL2Y5blhjZi9IeGcvLzlmNkFmZ2llNAovQVRwcVB4cU0yTWtOc3Y1WEJoK2l1OStEQk5zNFJhL09CNnZ1OUVldWxhL2NzUjdhZE0wVXR5a3NjSklKaFYvS2NXeWNMSi9RYnlECm5uUUFYdW5KSHdJYlBNaEl1SitNTlc3eVhBcXY2SzE0dFBZaG1pVU93RmZGUm9TRS9aanJPWVB6SlgxNGFIRW5XdzczWWE0bkJxUDgKSkwrcDlrdDgxejErRHF2SlpRelBGWlRPMzN3NnNUdFYxL3FTUGFiU3VIek1qdzh0NzkvM2htbFB4YS9CN0ZrZU40ZldhdlFIZ0JtUwpMVUlzUThRLzdUKzBMS3M3cm1WanhNU2VHbGZQNXVNeWdtd1J1N01wbDNZSE52QW5tL3Z4bjNLT084QndudzVCTWY0bkk1c094WEZqCm1UTGtUc3Y0NGR2NldwTlgzOU5YbzZPMnZUdkRVSDRBK3ZweFVpc21BNzVNY2N6WVhjVE4rUGxZVVFONEdWZkZodHArVzNNY2dDdEMKais5eFRoOXJtSFZ0R0VjbHprbmZ3SGoyK2RkNFYrWlNGQVN0SWVIdzdjRkwrL2Y3dFh6OHJOSERjUHBPalRTbmphM0h3MmE4VUFkbwplOGdmNnM0dTQxbysxK0xRR1VoSkk4V1lXTUpabWVnc0VZZGx1RURHUEZNOGdPR0p0d3FPcnhONHdpdEF4OXhTWXJUSGZLd2JXLytrCjFVOURMWmxLeGMrZ3lBa0NRNzV1WDMrVnVDOVZuZjg4TmloSUFVNVRibkd1Y0VYOFF5M09kWnpIRFZ6TW5INWVYZE14anByaWpXOTEKeGxrOS9VbVhNUTdBVm1lK3J1bTVsQTJSNHoyeUl6ZEpieDZmWHMxOFhRR2ZzUTZicnhlK1o0M0UwKzNpUER3cUxEdXprTXIrcFlqcgpUaEQvWW5BaWNROUdFRnppVko4d3hWZUlTZDhmNFRDNU4zd3l4NFRHQ2Z1TlAzRlllcHlBaGRsUDNyRHVlU0E4eXc5ckhmc3I4ZzM0Clk4ZTBaem5VV0dIdlgrTXI2SzBYYjNzQzdsdzRlTXZWWTJJdXBlOERuQmhjckRySFdSTVp6Z3NqSnJWOUExTHlYUjJhQVgydTAyTWUKZXNpbEo4SVZjdnJIRUxIVkg1eEdZclNUV1BHdytabnBxSWlzeDB6UWNuRjhpQTN0NG8wamtSTkd0SnlJRXl0ZVlZeXFySnVudmVvNQorc05jZWpoTzRTdU84aWZka2VLNWwrTURYWGhqd3h4ZjEyQy90ZmhtS0xxaGtSQXgvNWFtVGRLQlp6eFpMRWgxZ0x5RDgwQnZhdHdICjRLbUhCeDNCWDlBQjkvRFFQbFk1K3dEaE8yQ0k3RzI3amdNZ2MyMDk4dHhtemlQMjBWSTlqdVp2KzUrRXV2ckYwZlNOUTZTMXg0N1MKdy9qRTlORkxPQkFmWmc3bEh2ODFKckt0eTlxdjR6ckdKKzc1TTN3QXRFR2Y4ZWFSOHZhVHpXY0VqVFV2eElNbEZnUGtVOGxJRXBzbgpDM1lvMEFIR2RpSStwb2djQjlnZmVzU1MwTW5RVXdpQXFSRkx3Z0hLZnFFMXJtUFRGZ3VYK002Nm1VSWVKMHJlKzNPNXBQMzdpbTE1CjZSNFVGRHpyVTExdy9JQ3pYeHkwTTZ3eFVueDhXbjd1NkNMZFl1RkNud3JHRGE5U0FGQm4yMVZsWm1PTUlLd3pDLzl3UFRNTzhPekoKVllNcWRpOWxSNEdxWGE3dUZKWEgyaWNlR0ZDdjhTTEVZTjNWZTZxRzEremR0eDlaKzdQMlVjTzUwT3BSTmhMci9FdDZCL0E3MitGYwpaZXpkQ1dDTGp6L3ZreW85bmxlTXk5MWtQRCtESEtmRmhoYTZWNGlBN3VQbUZ0UEZxaHdYZTFPSGFXN0xrVUxHbUxCdnB3Zm0wajIzCnNsdk5UemFIM3oyMVhJQVJoT1BoUmNLSHQ5bHRqRWtmdzBmeE5BSnozdDlvejluYlB2dkQ1UkFJSXpwaHJIQXh0VkNWdWZad01MencKak5LaTk1c0JldWJhazN0NHpwMkl1bmkyOWpyWStpL2M2VjZWaWUxWjVWa2U4Q00yakFPTVdJM0dSQTR1K2Q1MkpFM1BhTnkraC91NQo5MDg3YkFqZlh1NEZhKzduL2tBMW52VUh6YzlqS0NnUk1rRnZ6QkYrVjNPMjhjTTQrZ2x0K0t4Y1Z1YlpjZFo5Z0RialN5Z2Erc2oyCm0vdWo4YkJ4d216K05tSi9FcmM5dHpXUHlSQkE5cGdnbVdpRkVWVGZ4eTlNVEdQTmlRRVA2dUc0d0h4bVFyeTBQOWxjOGhPclZTeW0Kdy96c1lFN3ZXbTAxbjd3TzhXZ04yWEE2TVVhc0h1Tko2MmoyR1c2cElyMTlSMzA4cFA1T1lkcDZ1NmtSR1g5bThvWHBVb3VwOFR3aAp1K21rd2JjZUgwek16czNOVlR6NE55OVZBSUhmdHpEbVp4anovc0sxMUFTMTd3blhONVY5QjgrSE1HUFhlV0ljTTg3ejJkUHlUSEZHCllHK2YyNmxmZVhaQXg3RHREeU1BaWc1cFd2TEJlUXN3YzZUQlpQYmNTU1IrZklQaDhLQzliTjNSdlNlOGVZTEY0dz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJdUI5UElRSmJRK2hoMzM0Tnh1RHg1NUNkSkh0WDdEVVdRL0ZVYnNUbXNTTlFqZ3JVZHNVUGxpTjUwU1hBeHNqT1YxTmcrV001NnliVwphZ1MwN3pUL3J2dWlZbndIZUQ5dkI5ZnBPR3hiOTFRdzlhSVEwYi9kNjVUMi9vOUZMZmh0amZuc2JyeUhNRHdnR2JzanNYWU45VmkyCmN6alZhTnViOXIwcFdtVDVvRSs0T1FsQnB4OWoveDNWSVJCWXhxZEZzREdWRmNZMFkrVkdUeTBDY3ZQWmQzcHB2QVdyY2p2TlZCajgKN285SDlNRDhDbGVQcTBjWlc4cWZyd3NBOXUwNjdWaEpQUU91b3hhL1U3eDA3a1dHbzEwSTltK1p3RmxuSW80YVg4WU95ajlxa1BpYQpjcGlXeU8vWXFzeHhZZWQrbDdVWGxIWnliSXdCM3owVFphMGVnYVlXdDc5amp1WjhSVHdWR2J0ajJjQzlacDhBRUxKN2Vvc29QUkcrCjRmNVovRU1lYkd6WVl1SEVCdUF4T2JHM3ZIZmZBWXltbTFxc0x2TFB4MHFpM0Q3U2JCcEdQb3lNWHR1ZlV2UUFMZE42eExDSUs5Y0IKMEY0Z1hoZjY4RExXczU1VHhoOHQ5cmJNNm1PSkdQdlhLOXdWVThXSE1hMklBRVdTb1h5ODdqdHNUKzlZQjhCWHRGZHpVdzU4S1hJVgpkQUpacnhBeVdjOStnMklZNFA1N1JWb2o1MFVKNXZGSGJhekhHMjFuOTdiMnp6OG52M2FrV21VcXFTaVNmOGpnMm9yRHhzM3VFRDJzCmZkd1B6Mk03RFR2RmZQei94eTR0K3JLUGU2RWZhZXUrWXNBY3JVU0t1NjBZYjJPaHo3NkFFUkk1TDFaV2FrWFdPRmY0WXR2cDhPQlMKM0wzTXYxL1BBYzRhYWorWExOMmMzeXl0Zk5GUDU0bnh1WTRucmlEZEFTK0hrR0RjOFI5R0VuVFU0Mk1PYUpQaUFCeldYODRZT3Y3RQp1cWdVWi80VGN2ZzdZcHpxM2o4UyttN3I0VzFQeWp2dVMySkhLTnYydC9WZ3RvbmZ6d3BWb012ZEUyL1JJMmVTc3ExSXp1UWMzbWhlClhDTyt2b3g4Ui9LTDE3QXc3dFg4Y1lQUW4zUkZSS0dYV00xL21NdStMWFhya3ZLU1BNN20wTVNGbnN5OU9XUnNPdzFFYlVVSTVVYUoKUVkvaHRKOXNQbTRPeTNYQ2ZBSkp1WjF0VnppRFQ1UFVBai9uaSt0YXkzakwwbXc4amxLZWV3SEJsbFo4T3pJKzRkQWZ6YWw1SHUweQpaZ3dRSi9aUDg3ak5YNDBmRC9wZmVOc1dHWUZsalJyYlVLVklFL1FTUnJiVDFaYW9Zb3ZmWWxkVVhTM2NJQmtqYnNvK05TTU9zRU9CClIvbVd4M1pBaG54akdQc1ZzaXJkZWtkMG00Nmg4NFFqY3Q5KzRjbFU1SHVlS1UrSm81WTlTN2tkZ013blpzWEE0MDgyaC9CaDdLZzgKRy9SVW41anl6dG1kOVh5dU1TV3dCWEI0S3pVcFVZNmZ5aUUxWkVCRFc0WUdjbHdyYkpqM29pSWxUUjh3bnNCaGt5NkFYWU4zc21WRgpoamkzVzhNY0F0R0szNDJiK1AreDk3WHRiZHpHb3VmemZSNzlCL2EyYnB3bXBCZFlBTHNiSjIwc3lYYWR5ckZyNWNVOWJhcERrU3ViCk1VV3FKT1hFK2VQMzQ3a3pBd3dBdmk5bFN5SnA5c1VpaDhBQU13QUdnNW5Cd01WNFNHVTl5QTVyeGlRb0gzV0Vvc2N4VVpIRjJpSlYKTHJaVDJjY2xuWkR6ODFCRlpqc241L0VWbVpTM2VwbzVDTVJuQWgzS2hBV2ZsRDZPSTdNTzlDTUh6aFJIcUJvWDZDTFJsTWhIZWVVOApCUkpQeDF3L1k3c2NQdDBvZUxwUUxua0g5R0plT1pNVUFuM2tBRVhGV2dUQ1Iwc0V3eDRBcFdMaklybkI2amJhMUZ0SWhYZnR5Y1JtClhROHM1TmhVSmJKSm9aaFlvNVVGdXBnVGZDYlFtemhTTHpkRWlCak03TE1rRmtpaGFCWm9NZ2JxbkoxcjVOZndrWDNldWNaR1BIcUUKbEtNTEtiV01CZEliaTJGcVdRU1pmZi9hclRwN0doUE9VZWZZYVBWSWtVVnVZM3AxeVllRmVzcG9OK05vMHl6M3prempnaE9OalZOMAprOVk2cU9oVnk4eUoxQ0xqdVlSbGplRTRlcmRoUmpHc3h2dVRoWWtGZFNwQ3ZHcnVLQXVCNUZTV3lSWE95dzFBZXFMWmtoQWp3QVhCCnM5bnVnOEk5VGVFa2o0Y1Y3T0tqc0d5dW4yamVyNVQwbldXL0c0WWhXaE9EMFA3NGpJOWY4ekZKdUhnZnl4bkZiZ1NCd29mRk9zY2sKNFpPZ0diTUx4S2gwd05SSkRtZm9aTHpCSFVablprYkE0ZFBzVEVKZzdqY2dIMWlySXc5VllzKysrTTZKYngvV3RXMGZYN3VRdkZ1aQo4ZExXVjk1UmpmY1NiQndOdm5YcHdob1FhQmdyekh3NXhWazhmZk5oTjVXK01jRGx4WnppMEdDWVVTS2FuWXlBM2x0eGE1OE45ZlNHCnJRL1F3ZGRlR0J5V1E2cFVBUE0raWo1ZTYyY1NvSDhIRjZxd1J6aDhwOTQ1YS9FeFNNb0U0c29heGt1dk5GcWdOOEJ6aUQvQ0ZKK3IKM1B1d0RxMzNnN0NqUzZUV05PdGtuWnNJcWUyTGxmWVo3MWY4T3E5VFNtMVJhZk5jV1ozT0JVMUxlc1dROTBXT0twWTJ1TkFpZFpHVgpJdlp6K2ttUFQwejZRemdmb1FWS2NGYUoyWDJLUlROdnN5eHNGQWdDdGRjdGZFQzZqRHdvaVJ0dllSVm0yL3ZNS2tjaXNZNWNOMTBFCno2SWtzck56L0NXKzVaSDdaWkM0VzBTRnRSdTZrZVoxUVBIZU9WOUFLUXpIYzhFMFk2VUw5NXAvY0ZtdlNyRjVKSEZQUjduZFJuSnMKS3MxZVMxWWMyK29Wamx6N0tGaS9nMUVRVWQyRnJ1WFI1bUdyNTlZNzRCYUg1S0tzeDZIV2FsV2JKSThGdHpZQkFia2luRERVcmlnSgpDamQ5N0RZeDc3WkVjQUNoZmRuZHhNcDlzQ3Z1OTRhdlc4Z3NrTW9HYWdRTDlyOUk3YTltQkpkZnFxeHFnbGk5QjEvNWUwWDRzQXlqCjlYSDRXYlFoc2M2WlpKR3pqTjdIc1FqUXBzUENyQWozdzlDMHg5SFFIUEdReE1ZVjRaejFpRUJ5VUIvczNLbnZtSDErMHdzZDExdk4KeDAwaG1kM1NCR1U2Qy9YcHdVWGJBY054TzhSRzZUYWF0SmczdUc3R1NDOXlaS3FpS1ZNNEJCUXp5SmNjS0FHY2JjNmY0bkFxdTdPMAo4YzRLQkdxdmlBamg1N2V6c2hucmplRUpydDB4MEZnaDY0QStSTm80cDN0UzJIZDRDYWo4aFNrRU8rK1VzU1kzQjVRY2o4MHEvYXpiCkYyN2xLaVpCUzA5WFhyRDZIMkV0Y3U0QjN3L0RrcWxoWU02bkxSUW9obnRBandOWklNY2FHL3NNa0FVYWQydzJWZ2d4QXZLbldMRE8KM1BnS3diWmhaNG16UlRsWXlkaGJVN1lnV3hxTjlSc2V1UHJrc1NRd1Nnekd5dTV5ekNpWm1nRE8rWGpKZDUwQVNJRzh5dCtUc0VDVApGVzQ1cE9IeUVOcFU4b3g1YXhnQmgwWVpLK0FkMXN6ZnMvRDNFbEhZRytZWTM2MmhmWWxQMkh4RXArZkFEZk9yQ0pzVis4S01EY2x3Cm14VnJuc3JaTUxGNjdxZDk2alYxTkhaeCsvVE1tZHMvL1UwSXIzU2hHNGVCdEJueFhpdWRwZzdkY3Q1QWZBZzdaeDAxMVlwM2NPbWMKMGlZNmc1QmlrUHZCTFZnem9CeWxLcjZMc2VBK2xPU3JqdVF2dFVBT2hhRFhibGx0eTNtdzBpd29YWEFBWVFLODBtWVM3aE41c3B6YQphdGdZa3JENFJLZ3pXMmovbG8xVmtpVVB0MDBrTTZaUUc3c1pXS0RSR2ZkS2E1NFlicGJZTGpnN01LcjV6a0dFWGNnWnFFSVBOQjhPCjUxK1hZeFhSK0VBeVBGTW8xc2hGNms5TGlXZGhjT2NKcDdNcmUwdWdZSUtENHpHNmhrZE9UT2F0YyttSTNGOVE5QmM3SFRnVGZuNHIKUHB3RmtlWk1PaUlmVy9nY3VJZmdqT1ZrbGl0dWl3M2Z4bDdENUpiNGdpNnBraTFHSUpnSlh1L0w3ZHV3YnJkd0N6eW5KeE1kVWhOMQp3Ri9zby90S1J3NmNKaXdvS1pDVzBYcUpsdVRjRm5zRWpGV2dHRy9xVDR3eTk1ZmtWRmhoeXQ5OVU4YmZ2UEZlZUJHMGllaHlZdTZ0CmxzWjdzTEZiWHFnSDh3MGlVTXhGVnNnQWFEU1BMYXVwTSs3Wk9iQ0xJRGIybnR0NFdXTXRQUmFZdXhCb1krMmNiRThRZmd2aElEV1IKMitnY08rT1Vab09FczZXNjYxNWNuM0wvaDBWcWdieFRPS3NWQS8ya1Q5bXZobWFLY0QrVGRlcWk0YStHRmU3YUJGbytKTjhPTFRnQwpHODBrTEdRVGR6aEdJNHZNK2FxS2xteGtrZjQybnZSSENnQUxMN3pEdVE3QlJlYVhqTC9qelRKU0ZuYXJSSmdMUXpPUmpZVEFPZ2JQCkxEdXpaRUF3VnBhN2xlWGFuNW10OUpUQ3FpUmpITVRIRlhsSGtKcERWUW1hOHc2ZVNHOXRDOWZpNmJLZ0JXWUpLMTFTMm10ZUFHUjMKWVh6UlVlSWpodHdhNytzU1BibWVYenBueTZCSWVhTVEzak9HQnNQQzMrZDFZWWI0ckxTL3V3NHJLbk5BY3R3NEVyd0RJWTF1YUJYdQpEQXZBUEdmMWpQWTNMcGt3MEhzWHNhenhWNTU0enFUK1pJWjNZKzNxd2pjaEN6WWVKWkVabEk0amRzbzd1NTd5c1VQYTV6REFoOXo1CmJsYnVUNVpvbk0zODN1RUhCaDl5bHJ3dnBnVmpEVWZMeE4zNGxtamY4SHNFcmhoR1MrWWVaVy9lZXdlSzltdE9Xd1d4VG1icklLUlQKTGRqdWJkd2xMTHlSbndack9vVkcyT1lTdzZaNzZXK0lzZjBOamZ4K0VFTkFnRVM3VzhSRU8yUFE3dWN2ZithR2ZTSjhZMWpiZ0NQMgpLR2gvWTVFamdoQm9XSFJ6akw3RVFBYkRVd05uTHlNb25LVnFyQWVGUDVOd3BBbTZhaFJQWkZXd2xvM2VIczFya1I0VnQ4QndTWTdOCnhua3NqaEsyYVdHNkJwMTZpWjV3MlZUd0ZVYStaVGMvM3dNN1lMUS9SOHFjNzVGcGVvaVR5MFdUMEZmV25IK0JacjUzZGlVOGpUT1YKTWxIc2V0QStRUWMveG03SHhYdUt3bG5lWlhCWVVKK0RET0tjQWVqYmN6R3FtQmRDYzFxSmNNL1NuVzNucHBvd3prS2tmV0FnT2gxegpuNGNnRVp4cmdyWEFlRlR3eFhxdGZWOVRMbHV3R2t3M2QyMUJ0dnk1WkFOY1h4dSsvbGs0YXhRaVZTb2VBd3MwN2s2UXRpZEdSaEN1ClZYTllUaHFPYWJyaHRBU3NML2dlTG1rc3ZyN3pxbWtNOEdGWE1Qa1ZDT2p1VXdDTVVrTW92aGp1UGNrcDAwOWI0SkVEODdrY0pZYkgKQ2dzZ1k2QU51MFd2dGVadVNSMDg1TnJuUzZBWUFVYkxKMVh0cjFjQ01OTktNVEJMUGRCMWxwUis3emYzYzlCcFA0alRlQWE0S1l3RgppMEt4ZU9mcGl1NTQ3Zk1jT0w1STlwQWJObFZqTUlGa2ZZVGN6Tjd0SCs0UDI3V0tSWFBKbmRlS2d4RVNrekhReHlSUjNBSFhWKzVHCklyK2RiSUZ1TDhVK0dXWnFHdWFLOUs0RjkrcTdBL29iek01RU8rdkN2d1ZuT1NlWFlUOGhCa240MVdhY1RvdWhIMTZJMHJwbEJPR0kKeHZHaStFQzE1T1dldW1nMURCTGg1VXAzcmpoMGhHOWphT3NyY3ZVRmI4VSt6aWIxT29xMmxsTkdRRWNIVzFaN0JHSFQ0bHRWc3k2SAp1N0x1YUlHN1F5NTlVQXp0ZHVOTEhpK2Q4eW1DWFVHcGlzNWNwTUZidk1ydlpYaGU1ZXFxOE9mRGxIRVdMbjdIYnZ4Y20wM3k3c0JqCmdXem8xdmFoYVF1a3kyQ09yTUo0QlBSeXRwT0RCUmVWL3BLL3RwNC9Lc2pYd3BYM3BXRUlWUkRaN2hvZ0FqUFd3S1h6cGFYYVBtZHUKRVlTSUZPMVZsMmdRdFhYbVdtQWlHQ3NsUkhWck1OU1hJZWNRWDhKREJCbXJqMlM4WUREYjhJTktoQmdNVDI0T2NNQVlNSmM0UnR0bgp0VDI1eWllb2NOWTFCRW8rekxMMmhWajVXT0FOSGRnK0wwUDdxcUhqQ3lkd1VPNE1oZUZxR2VzTU1tSHRGY0ZlOGFFSXB5TUgxczYxCnJuMHdiR3E4ZVJFWngwRjRmUCtCUm9NSEVTM1VmbTVrZkZjaGpTTS82R2FGQmRKdEtHWk02b0JCZmZSbkU0UTZodzJnVFZ3Z0lzYWcKZXNXQnc5am1aNUF3UEk4eTNqZlFzczl5RC9iRm5JRWVRZUhQN1FET0ZmY3JrM3hvU3d0TzU2VHhxR2haVTNoUGJUamlBekQzaHp2cAo0eHNMNnd0MlN6SHpzWlFoSFFOTEtEeUsrbk9CaUNJc3M1eVhRdWJTZmlBQ3IvMFo1N0ZBWU1vSDdOeTc1MVRpVFZzaHA1WUtsNjl4Cjl0aHBPRCtoaE00SzFuVmRwRFpkNEdmYm1NZzFJK0RBRTJObERTTmdLV21zRk9leTNxeUVscVIvN00xRVVhY3cyVVR6dEpmT2VJSFoKQmdyMjFKS0gzRFltZkxTejl2ZTM4VUs5NWdPZU1vYXYzcy9NVTVGRzlza2s4U0hNS3RWZXNiZUdLWXhMVnB6anp0OXhSS2czbExCYgptNHI2ODRKTFVVVEpwN080Sll0QVJjbFVjdWxqb0lPeldtYzJya21GNkJzVEJSQUJtT05NUXNZcHhPb1RRSkd0eUFMWmRVdG5tOXdqClVJblhvS1JrQkR6bmpMMEtVS2U0ZE9sOHN0cWFnQzBDN1NOd3RZM0lPM0pndmlha3ZmVmJhVGEyaEF4ekNvZFordz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJNHhYTGI0VlRUZmw5eVlTeVh0U2prdktESzZ1OGM0UXNqWFVic1MrOGNRK2RJeGFvbkhLTWRtYjI5S25NTG0wM2E1VXJLbjNNQXp2MwpWZWFqeTdTMW8zUDlZUEpMM0kxMVJPQ042aXBKR0t2eGxramFqUmxCSmpsVlZPb1ViT1hDOGxWc25sUzV2MTZnYmRBQ0krRHJnZHE2ClhQamFBbnNGM1pIZG91Q0R1clkzV3kxUTVrSFdpM0FkUXBvZ2tyU3pJNm5jK3lhMERWRjNRTzltNDZ0MUNtV3FGd2dwWDFoVGhRMkEKY3R4MUlUeXFpSncrSnMwWmcwNjl3eUcxOFFrS1hWK1M5UnMrZkdDNmRpbjk2WmNka3pxSlVzQzVHenA0K0dHaG1EclJBY0RDRzFISQpZWHZncW1mZXI1bmtWaUFBa0ROQ09JbGlnZXdZMWRhV3p3aGtFYlpYd2JkYWd0NlRPWE1nQUhQRG94RHVmbUJacGtvSEFncldPL24rCmxvNlBkR1RwNStxNW5reG9xTVBWVTdyOTUyQWg4eUdwYXJhKzhMbWtjQnUyR3o0bDNPY3pyY3VWQjdEUWZlMTduM3FzMmtaWUlWRFoKNkRNcmQ0eFBjY1hDSDg5amZNa1Y4eGFiekNzY2ZCMHF6RmN0RmRlWFB1eFArS3RxbUF0TDhtQlRrSjhGY3U4TjV5UFRYbUNReW00cgpHNS8yUmR0SW1pTUhscEkzVUhkdXdJeG1pYzlJNXBSK0JFcldwRlVZVXVQRnNmYVplYlNKNW85MFNoQ1d6SVNiS0ltUG0wU3dZSjFQCjV0WUJnNWZKQkV2TjFLVzEwb1p2MHVNNVBhclBWKzIwdlczQWROSDFHTmJqY29laEVJWjc0QzZwWWJDTVR5eVhzLzFDWjlGSlVSVCsKVnA3TGoySkw4NDI0M01iMnVMS09Cem1lRi9pa21QTjFYZ1Jyemh2SmpuMmQrN0IzWktLMUZ1RmR2OEx2YU40d28xR1J5L2lvNkt6QgpKdkZpeU9XZnNzQ2N4U09wZ1ZRZmJ6RjZrVWNYNzQ4Y09KdytpUGQxdWtmSjdsRE52akVqdkJQTW5WMHNXc0hCTTdyaEwzRUdzNHd6CkpDUE03NGJLYjVKR2VGMUgrL1JRQmswbG5HK1M4MndZNFNNWXRKVjhqQ0FzVGZLSFc2S2t0ZXJhS2VPc05VYmF5NWRPNHRpNVpWTHIKV2JZTU5LeVpFWmpYcHQwT1Rlb3ZQbXViamF4dXI5eEtOa0dDdXNCTUNUZHh0UlVUUnc2Y3kzeGl2aGh0WTAwY1pRbGZVaGFLWjJ4MApxZHhFcDMxSzcxdW51OXVaNEFYcW9ueE1jTmRwdTh4cy9aQmhGMXZWWERRWEV4WUV2SlB1VFJBVXNzRDFNejhHOW9pRVY5cUQzOWdkCkdoQ1lDWC91WVhNTFhYL1A0elhBbC8yRkMyclEzdmxoQ3NwUzZHYTc0TGJZZGE5dHVnbEdtOHZDSDZCenpubVFSRVorVHErRWFSTzAKOFhZTmUwYktaSlNKa1NKV0NDK21idkNtUUZZK01NMkRadXNTQjR3QU1DUWJwY1hMQ0RJdlkwbFMySTZsTmlUYmtwRVduRlBDeXowWApRNWNwbTREYnpUaGVjVkNTZzI1MGRLY2NTa3QvK0JMYUpTRlJVVXBrWjU3S1VPVk8vVEdQRTNBb20rVEVpZFBDVGRtTVpLUGt5V1ZOCjE1bTJkeGpkZ05uOUtBUFJ6WjJsK0J5TEZrOEFpdXVuVms5Qm9HWlhxbklPL2N3RUJuZ0RYMmFpaEsycDA2S3pMSElyQ1plMUtzdDgKWWhSdGc0SXNnaXlLWUVoZHh0Y3M5eWx4dFUzMFo0RjhGZFVkWlN5Q1BOcm5OQWV5Wm5sa05jdGRMQkVCL2VHVGsySHdpYVZRSWJFTQpweFF4L3VvTUF2M0IxU2U4eU5tSGlTY0xsazFRTkZpR09JWXlLNkpvQk1xelpJRmFlMCtadit5RW1XRWttMmdwbTJMSWJPTXo1cnA0ClF3UjZ0ZHhaY3pPMEh2aTAwNFl2MldJYW5jemJocHdYRllBcVJMYTRTNXM1SHQ1OWVzU1FyeWZ4dVV1MFRlVmhnWm5rSUNCUldQRUUKd09DbUNxb09ndjJ4anpYdFBMSFhhQzFXbDNNRGdWNWtCTmJtd2tjZEI4TU1wUkZpTGtwM1ZzaEZISnRUOERrSXdkNmFXTGd6VXg0dQp3bW1iaHF4T09Zc1NyK21RRXNBSVFrTEozSXJZWFBpNFJEdzE1dHlCTkFuV3ZUeDBJSUJaelVDa0tXc1UybDNkeFpKZUxaTSt2UStWCjVXVkFKMnZYMmNJYmxKMUZHMU14OGRLa2JkcldsLzd5cnJaSE9nZFVYckYwbHhrcGxSTjNsT09yRVNpOVBvRm5sU01IOXJ1QmRyZHMKRWViRkk0c21BSEllRWxSKzJOMmFvNEJXdnF6aHNsbkJDNG50d1FBTWpwSW9KWnVNWEIwc3MvTTAwcjRveFlNRmh2eWxSSXRGZ0ZZWgp2Nk1uWEoram9aMVRZYksrRDdSQmFPWXpWNGVXQk0vQjNOMGZBeUEvRWVEeVhuTjk2YlUvc2gwNm9KOXFMdmxkNnFORVlpbElZSi8xCm5KTUtwdDR2UEk3QXUyOXlIMHVjcHo0bFJGUldScm82WjNqQkFmREdWUm5OaThLa1hrK3pkNWNRcVRmc2NUSXRHaFJtUU1oN2hYd3gKcktjSVRocVorbXhpSVNJRmdHeUlOWGJ6WXdSaEsrS1luRnpGeHFQY09wc3dvWnBQOTA5UG4xc0V5c2R6NHc1bHpRdDViR1ppZDIrTwpoaWpXVVh6TUFlYXY4MWRUcEJKY256SWhxZGh5ZzhBUURPR2pWQkJCTURlNnpSVGJ5dmtjeXlsdXFBTitaQVdibVhMalUxR0YzUUN6CjdSVXNYM25ud3J4OFJ2aStzcEtSWjFIb1lwSTVkcG1RY05pTFRBeVU5bFlpbnlZb056NWJGRTZ1akRQTm9VR2VsUlFPZE1mc3R6NWsKcitBc21GRjRoTC9YbnhmK0htWXdNQ05RcC83TW5qQ0M2QkVGdzJweFFVK3orRGxyVjBjaHJBRkVXVXVaMVFhS2NLNElrUmhGR3FsRAp1Wk10Q0N5OFI4YWR3UUNZaDRBL3pWWllCQWMzaFkvSExKVDN1cU9OS01rOU9OTWNXc1ZpRHpVcDd6TFVMdmtReldudkFHTDloZVFYCnN5c2NibmkxT1EzRVlxVm9LTGJSR0VlRThkZXFYVVNvUld2c25VWVZXOU9KZGN4d3VzeHFnU0Q0T1RiTU82SEkyR3ppWWJUOXdtd0sKYkh0M3I5RlljT0N2ZFBtSDZQcUVkOHk0b05JaTg5ZjF0RFZXSHpnRVJaWk02QXFZbmNjYnJsMk9Uc3cySVRsckFCMUxiWDJYQmNXcApGVzUrNUQ2aGl1R2NRcHlWMFZJbzJDZzNMMlYvbW5LR0JYNkxoakxyV0lxZEU2L0lRbUt1M0R1ajZVNlJ6OE9ZUlp4U0lSY1FaMHFtCnkwS2M1SVB5aEFlMityektxWTAvUVF3NVh3dmttdzUwcWNXbjB4UjhjNVd2cDlteTdzMkJ6TDg0RStYa3hRdGdmSW1kOWdhZUJibFAKMmVXenlaTVE0T1JIV1NKNElvSVU1cWJjL1JZc3FUZ1RRT0ZqMFFzWFFPNEl0eFlGUkJDeVdXWitkcHB3b1paVFY1QVAxRi93VnpuWApWNFZQNE9RT3VXVHQ5d2thL2MwcG1qdDhiNGZNZUE3b2N6VFFWUW9MVEhOT29oVTg0cVErZXdRdUJvYzJBbjRveFVzdTdZTXMzWXpnCmRhLzlGWEM2cE9qa2hyK09xMTAwZlRILzdRcWZTNXoxMkVJMWZBSlpUaElCc0pBQ2k2NHJIRGpCVldTY0Y0WHZpaGNxem1mcER2UUkKZEJsZzNMTnRYazRhbndEVk9TUlFKQ3UrVWxpd25FWWxKRXhPUGg4Z1dETUZWZ2tycEw5eEdsSVRJVEF0L0pwaEpiSUlJYVdaVjhJSwoxRmo1cWgyY0U1UURxcHdUUmxORU9TTlF2RzdKdEdoaDRRWS8rNDBMWVUrbGJwbjVJUlRldmg1eXJTQ0N6TThCdTMvVDVzWEpta1RtCkpRU0FDNTlvMWFXcktVU2M1MVZuRFBUWk5LbFRYRDljZGN5ZERST0JCVjlMejl6UkZZRDhva2h1azEwd2duQi96eWtnQUl1U1VMa1kKcWdJOXJueTFOZHlKS1pJb01RM2QySEJsQmFmbzVFd1NtQWZjTUsvOVUxdEZlT1lxOTJrWXB0T0wvMlB2YkUvVURwM2lHaVN5d2czeQpmQWJZOElrbUJ1YXpnRjZaazlFTmJBNnZHTXVPUzIrcTFlT3prOHZnM09MNm5yNm9xQXJKS3p6T0NRSmM2bms2S2ZLVllweEdqakswCjFQSUZaT1VQb0J4NWt6VmNBalE4RmFjc0pCUnJBWFNBOWhja25VaWtvdjd1c2JzMGhEaDk3bXE2VWVZUkpEeWJwZFBsaEErMnhUdVAKR2RlZjZEN1RsZHBKUUFLTFRLTThZa1hCYm5GMmVDQlFlL3UxTXczSXlENUhPZEVQcHVwek5wbzg5UmZldFQzTjF2bXM1RjB6bkFpVwp3TjVqVlBnekdDZlFEdFpqQXZJWmxqYWpDSUdjYnN5N2dVUkFPczRCWk0yZnZ0OUwzSnllT21PZU05aUg2ZWFhVWFYQk51dkNSeENvCnh1SnkvQkV0dkdsUzhCbVhuN0h6MFQ3elQzalN2NmpHbmg4NjR2cUQ2N0lqcWpUZUlzT3pKQ1FlZENlT21mU0haOW9tN2xnc2VVY3YKOWZmSTNEVVpCRXAyNFpJZVVGOTh5V0xtSFltUWZvVURCOGFCbkpwbnhwV1FNMmU0RHVsZ0tkWGp1UWZQU0VVc295ZllDbmF4VCtNNAo4bSt3VGVTTzREZlkwb0szWE9tQ3BNZHlSMUNpZFFmVUxLYkkyblhBQ0xSUDJzSzN0RXg0R3BMdllNeEtYc0hQc2sya1B1Qm4yYlJYCk1WS2ZVQlBBSVJrWDU2ZENvRTlBUkM2S21YaTV3ZFRlR0ozWUhCRHNjM2R4Vm5vQyt1eE1ibnJPVDNNUVV2aWxMbUNjRVBpVUFESFEKNXpOZ1BXRzZYMGZoNWFLeHZHejhjQkZmR1VhdzVyeHVRWkhtQ0V6MG9mbnNWeG1JbUphckh4SW9zQjBvRFJkZFFyNy9HWG5oN01LYgp5dnQwN3NEK1lqMWZMcE9adjdxUk5WekVrc3lpYS9uQlhJSFZNMVpPcFl0N3dLYUt4QVBkdmFDcDlxUG5aOXlwT0xjaHMrSGxKZW5CCkNiK2NGTXJ5YXhiemt5R3l1eVAzQVpzSWpFdldaNzlUTTdOYlIvNXB6cEE2bFk3Ri9EUW5CemI0WFZWbTNpU1grU3VuOHpsWkdNNlYKeFR1NHpDUEZrNU41VEhlQTN5Y2lOWXdQc2tiNHQyUHp3ajgyNHRPZ0U5Z1hkdStTRUpCbk5SK0ZreXpLZEJFZUg1aHFMVHhoTzFIYwpkOE1uMTZVem5lK0dUMnFnWE5aT0JHWWgzWWd4ODdyQkRZYUUxM1NUYUVtRG1UOHArL2VXTXA5NHlyOEdONFUxdkFMRjkwZHc1WXZ3CjhpZm5PblZKc3Z6empab2xxUmFDVTM4WTVWOEZkamxCcC9HeUNFeHNXaVA3QTZwKzV3NmNwUDZwME55L1laZjdqSytjMUIweGUxSkMKdXRMNVBRN1puL2o1QXhFbmx1ZUhnS1k3eGoyV0RjbUdaSm53VzZ4Q2VEZVQyN2c1RFVBUkxJWjgzUnZUc0hDZ1dlS3lEU0lDeFc4bwpKb2tJdC9qVGNJT04zL1FVM2lRVll2dW0raFUyR1JPaXgvaE5XN3h6WDdEN2g1MXRWSlNOLzduMk1CL1BRUWxOZUl2SWZEUWxSNTRnCnNQQldlbmNVbTJxZlpYWnExN2RpNitJNVF3VjcwQ2djNzhpQjB4RGVKMU8rM3loOVVBajNkd290TjZkdDFLamQ2WXgvMnhkVHhiR0cKRVI2ZVFMRGdrNzcwcjM5TUkyRzVhYUlRQXUySk1UNjd0YlladFRucG5uZXhrU0ovTkJQRmtYL2pMbWliZEgyQW4vZ0tGOWpDeFExTQovNXNHejdUZ21HS0tjN2VvMDR5QkUzaDV6eXA4dm1wbjVqOTM0RlJ6bUFiN25URzRVZm43SjRYbTRFWmp2SldlRFZCWU5IaDkrYlhBCndsc0JkY2hyUE5VQjFrdVR5TjFDRjRiT0hUZzhSb3ZCcHh6L0VSNEpwY2pnbzlrNGp1Z3grYUoyOTlQYXl4L0hQczE3WUY0ajhPVGIKZnUvNW9OTWJkWHF2Nm5VTHBuZm40eC8ydnIzQVgwUmlmenIrNGZHalRoZlE3TjN6SDJ0ZjdOMTcrZlRvMjM2N3hJK0huZGFvMCs4MQpCKzhXL1hDL2R2Zlg4MjRQZnFwRHR3YWQwOHRST2Z5MDl2bmV2UWVEUVhPaVJPdDFwOXNlbEQzOFhkYnVQZW1Od20vNHoramRSWW0vCjNRVk41TTZudFh2Zjl6b3RBQjhEM3Q2cjhhSnZtOTFMVy9hWFRudjBlbkhoWHZPY3lrSlhYT25QMTVtaTEyWG4xZXRSWlpLNCtJM1QKMUQvOXVXeU45dnVYdlRiMGI3Ly9hMVVDejJpK1FkSFJzREtWWTNWdW5OUUhUMDRlZEM5ZU4wOUVWUm83YlNpNWhDWXNjK09rVkorSAo3eW9QenJ1MXBtUEp2SXpvK0pYL0x1N3V1b2pKMGVYZzlMSmI5bHBsVlZiWXFoVzV3ZTNjOU1EQ0VhOHFQYWZOWWZsb1VQN25FcGhRCmZicE8xTHB4Q21WVjhucVg1ODlhbytiYnNycWNqS3ZjT0dHOS92R29NMm90Mlk0RGZVTXEvVjJudXdLQlkzVnVuRUpjY2xXcEc1VEQKeTI3MWZaeUxWNUZBYzdvdUZuUjk5bTRVYmNybGR4WEZTZWp6QXZhdjhiaDBla3NXWUx4Rlk5a2JuMldkWGxWYStoZmxvRG5xRHlvVApGQ3JjT0ZYSC9jdEJxM3c4YUY2ODdyU3FEOVlLWTNXTGkrZWdmMzdSSDNaR0s2eWQ2K2dIYWNsVnUzRHZzRHlyM2Q4ZEFkZVBvdDBSCmNBYVZhM0lFVkxzajRBeENka2ZBV3hHVFo0TW1hUHZkYi91ZDRaWWRBaXRiV2piekRGaFppdXpPZ0xzejRPNE11QT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJT3dQdXpvQzdNK0RIZGdaVVczY0dYSUdpVFRrRHdzRm92M3hiZG85Zk45djlYN2JBUTFhWDIzSkFXb1dTclQwaVZkYTBoNlAyWWZtMgowOFFPcmFDS3hwVnVmSVJQdTVkTFJQMEgwRVZ2UlVjZ1k4dTJhUWlQbTVmRFlhZloyMTg2Yk91b1lGZGVTZTNxWXJHOTFvZnZkbldwCjJQNzFGZ2pwbjUwTnk5SHkyYlI1UW1BVndiWXBxLzhaamRibXJmc3VhcFlZWGRqcWQvdURMMzU1dmZTSUUyK3E3N3JWclkydTlJM1AKdHNvQko4UEx3Vm16VlI2M21xdFFOVmJweG9rYlhwU3RaNWRMNXQxT1FveEppQnYzRFZhZWdEQ1lsOTNtNE9HdkYvMWUyYXMrVHRNVgpiNTdLVllrODZQZUdvK1lWaUF3Vk4rbWtBc2MxK0U5Vkp2MVdtU3UvM2NiUlU2eEN5NW9mby9VS3BIendjL1MxcUNMUCs1M2U2R2dWCkE5UDEyQ3JMWTdkaWo1eU9zWG5hMFpXT3F6dnZ3MjE0SDdaVUUxcVJyRTA1TGwzQm5iSXVNcUh5YnZGbWlVNFVqUVVXdmZrNGpNcUUKTExHcHhJU29kZFk5MzZUVkNVblhtcERxZTh5YjI5aGlWcFphNjc1bk5nZWQwZXZ6Y2xUZHNiMUplMmUzTTNyZTdDdzdpMjNlNXJtTApTS2k0aFc3T09YcDFxL2ltak9mVGN2Q3FSRTV1bmtxMHF2elk0aUc1dm43c0FvOCtqSTRsZG9GSDZ4OTQ5SEZkUGpubzk3djdnN0w4CnJiTHJiWDBEckZhWWpPdHVHYTVNeU5iR1Y3VTczV1oxZi9BbUhYa3EyM00zNjZ4enZaRlY2enBHSkEwckVuSWJRbEUwS3FlRkdEVGIKbmN2cVd4Y1h2ejBWdVQrNGVOM3Y5bDlWRnVicmMyelpYdWwyL1hlWTFsWVVyTGxNcTM2TGFTZlRkakx0S3ZyM3RnVHlubGIyaG15SwpFRnZoQnVPYUM3SFZMZ0t0SXNWdWFjbHZhdmp1OXVZSXFMeTdiR2FPZ01wUnlic2NBZE1FM202T2dOUHFpcyttYkV6VjVmbTY3MHlWCngyWlRkcVpOenRxd0pOd21FZ0tyM2JtNHBjc1dLMHl1dFE5b09hMDhOanNodHI1anMrNUdnZ2VWWFVFSHI1dTlYdGs5THJ0bGF4VWoKMjNURkd5ZnlSV1UzMFZXSm5LNTRhOXZSWVdkNDBXMjJ5dk95TjNyYXZOaThQZW04Q2FncXU1TTM0cXhVNC8vV3BqNktzWTlWcWFaUAoxZFZ4TG43emdyS3lzV3RqTnJIcW9uL2RON0hWY21sdWdDWitnRGVrbjFZUUgrc285cXJmejl6RVRDbVZyU2tiSXdlcXI1NTFsd09WCngrWWE1TUM2ckw2emxZSzd6anJkN2lyQmE5M2JVRHFXcUFlUmZSWWZwYXB1bDdXbGIvN0dTbVd4RnlqenpYOUwvYTlJNFVTdFd6RFEKOWlyUHhHYXJkWGwrdVR4S0lpWXZxbkx6VnZYS3M3SmRQVW1UTFh2anRBeEtPbWhWSHFwMnV6UHF2RjFob0h5RjliM25kamJvbjFlWApoRlI0ZlQwNW8zNzFrMlQvRmdocGRuOXB2cXU4Z0VBMUdqVUhLNmxTdHZ3dDNHN3JsYzNLMTRWYXpXN3JhYi82bFkrb3dpMmRUSnE5Cnp2a0tFdnFhN3Foc2R2cTdlcjR0WVRPdFhkak11aDZGcWcvTnBwaEVkbUV6OHpidzJ3cWIyZmIzRmF0blU5c0Z6c3l5MDkxbTRFeHIKNndKblZwRG82NzQzN1FKbjFtaC9xcXlOYmtiZ3pBcVRhKzBEWjFwYkZ6aXpSVUpzRnppekM1elpCYzdzQW1ldUdEZ2pQcGJBbWRiVwpCYzZzSVByWGZSUGJCYzZzazlqYjZzQ1oxdFlGenF5d2V0WmREdHhtNE13bXVJZzJKL3huaGFGY2RWTGUwbEJ1Y0xMQ0ZRTFNkb094CnVYazlObWNzcnE4ZnQ5dUhyVWtaK2VESnlTR2xDanBaemI2MFpVR3MyNXN1NldieVJLL3I1ZHVQSVQzUFRyNVZrbTltSjk5MjhtMUQKNUZ2bHVicVRienY1OW5BQWdJOWJmU3VSQlR2cHRpSFNiYWU5N2FUYml0THRvMWJlZHRKdGs2VGJUbmZiU2JmSzBpMTJHNTJzNWh6ZgpNaUZYbWZnUDRvdmVLQy9oYmhHdHNJaXlqM2tSVlNaK3Q0aDJpeWkrNTUzVWRPVkFRRXYyaXhWaUFhTWFONjZPZlZ5dmJUM3YvRnAyCm4zZWI3MDVXdTQrNVpYSndVSjczbDZXTDJPV2t3WTdjVms2YWlrSmtsNUJtTVhtM21aQkdWSitUdTR3MHQ1aVJabHR6bnd3dk1QdEoKVmJyZUsvZkpEVlBXNmJYTHMwNXY2ZnZYOGFoZGxNM1I0UXJMTEtweDg1S2pKdTdMcENZMC9KdlU0UC8zNFRQOHZROC8xSzc5UHNxdApIRnRXVG1TekxxclV6UjRwYnpwZWRvVzMxamZsbHNBV1BwYTV5akI5cEJjR05zTnpzKzRYNEpjdGhNMTBzN1g2NXhmOUlXZ1R6eTZYCnlLL05rM1lyaVlZTmliTS80UEhhUExsUTJZajRab2w5S2hvTExIcno5cGJLaEN4eFhNV0VxTnZRdFNzVHNpUXNKeVlrWFd0Q3F1OHkKYjI1ams3bVNncmJ1TzJkejBCbTlQaTlIMWJXQlRkMUJ0eTRINVZYVWc0OXhLOTBjOThlVnB1dW1ET251RnVMTy83enpQeThpZEMzOAp6NnZsWE56NW4zZis1NTMvK2NPVHVmTS9VOUdkLzNubmYvN2dkTjNnMnhzNy8vT0hWemZSQXkyVCt5dXBuanVmODg3bi9MN0U3WHpPClZ6TTNyUEV3N1h6T2ErVUFhSGZPemk2SDVVRy9CNnBCci9yeW1hcDM0NVB1WGRudDluK3BTbWUzOCtyMUNINnZ0ekFKYVdVeUo2dmQKL1BaYldieGZEczVBS1Q1ZTdTR0FzVXJyNjZheXdubzEyc2JxM0RocGJuMXMyK1oxclNFRTZ6MUVXL3dzOGM0RXQrNG11RlcycjUwZApibzN0Y0x1WGlYZDJ1SjBkYm1lSHUrSng1LzZyUVZuMjdvTWFWdDRIaWp1dit2ZmZkdnJkY25SL1VMYnY5d2ZOM2pJLys4NUFkOU01CmJpcGJUTXN1ZkZuSlBCZlZ1UG10TEs5TVdQTzN6dm5sYU1tTGxySGc1L0szWnYwNTdKQlo0d2pWcmx1T25UbTB4NVFqcHdGdTNnSUEKeWJUdFZocXgxV2FhNFVYWkFvVjVzTHNTc2RiMmpCVW1vUnZRaDc5ZXdGbHJCYXZ2ZE1WYmlHUllsY3FWYmR2VEZYZkduSjB4WjJmTQoyUmx6ZHNhY25URm5aOHpaR1hNK0FIMW91ckhHSEdmWkladk96cGl6M21mWm5USG5mWXc1dDZGbmJWdGMwaHBacG83ZE9XbHpUVk5iCmViMTRPeE56YkxFUjZncWtiY29GMUExT3oxRTloOEl1UGNlNkViTG02VG1xRTdMbTZUbFdEYUZiKzcxenUxTnpkRHVqNTgzT01rdjQKNW0yZ04vTTJ6bTRMdlQ0NXQ5dEMxMDJwV2ZNdGRHc3lYRjFKK2Q5dG8rdXdqVzVkZHF0VjlZT1BjUXZkbkVDQWxhZnBwZ3puTHF2Vgo5bVcxK3JoU1B4Mi9icmI3djN6Yzd3NVZUbnExUzF5d0h0ckJUU1F1dUtVZFpiTXYrMWQrRHJSZCtUVmFLbnJqTTZ3NklVdTJoNWlRClgyK0JrUDdaMmJBYzRXd2FsTzJWVnN5bUNJTnR6Q1gvakVidG96b2pYSDJpYnNxZ1h1R3dzQzZEczlWbTdkMGhidnNPY1VJbGQ2ck8KMDE4NjdSV0N5RnpwbXpjenA5VXBlbDJ1RXBQbGk5Kzhjdkl4SHJXdkljWHlEZE5TRjdyeVZLeXU1OStHbXI4S0pkVVYvVjgzeS94aApkdWFQelRyeDdNd2YvZlZVay9OdE1YOVVKMlJuL3RpWlAzYm1qNTM1WTJmKytJakdaV2YrV0hQengwZDJzQjQxVjRqdjJrWVA5dG1nCjJSbzF1OS8yTzlWRDRHM2xpbVBNTGQxMHRHdWpjaWFaMCthd2ZEUW8vM05aOWxyVnRldUpXamR2MWFzY3o5dTdQSDhHWS94MmhhdlYKY1pVYnA2elhQeDUxUnEwbGh0WFl1SUNsdit0MFZ5QndyTTZOVTlpcWJNbmJsTE5FNi9vQzlOWjJiSGJKdERjby85SUtRbjZYcm1neAplYmVacm1pWHJXaUZnYnE5YkVVcmFGOW5nLzU1ZGVGQmhXK0JuTW92VkkzNjFUWGovaTJRc3NzalJadjhMby9VL0R4U3QySk5Xam1iCjByVllrcjY3SEp4ZWRrRkYyRmhUNHk0UHpBWmN2bHZoakxFaHB1QXIzRTdibVdFWFduZTJMZ3B0QllwMlVXZ3pxTHgxWTNuWUhFK1cKWEt6ZmdFaTA2cE54dmVQUXF0T3h0VkZvbzRwSzI2WTVNSkl0OTJCVURoWGFPVENtQ2J4ZEJ3WXV1V3QzWWR5U0tyczdBKzdPZ0d1MgpoSGFud0pYNnNUc0Y3azZCTjBqVFIzc0tyS3lmN2s2QmEwUEgxcDRDdHplUXJYSkdpYzA4QmxZbWIzY00zQjBEZDhmQTNURndLUzI3ClkrRHVHTGhWeDBDOWRjZkFGU2phSFFOblVIbnJ4OEFmKy8zMnEwR3p1bEJlMnpOZ1hXekxLWEFWU3JiMkhGajVPTEhMU2JFZVYwZHUKNW9yc0dnL1VwcnphdDlrWk5uWUpSaGNSc3N1d2NldFNZTTBsV3I5Q1pvM05rMmtmTEYvSVRWdTd1NkIvMTF2OWJuL3d4V20zMlhwegp2MlpCL1l0bXF6TjY5OFVLWnVQaDZGMjN1aG5jbGI3NW1HbWtkZHNFeEVwRWJjcWFlb1FUY2ZPVzFQdmswZG5aVG0vRGRycjlDc1JxCjhtSE5OWWdoWlRFOTJFYVJ0OEh2RzFaTzNPRGVTVDNvOStqeDl1cG5pOGw2Tno3eGZubTl3dVhKcm5zSXZsNWg3VVZVVGxhN2NTSXIKQitNTUx3ZG56Vlo1M0dxdW92V05WYnA1ZjhGcWduMDEyc2JxM0RocEt6NC92Q2s3MXpZZGZWZDlJWHA3ODhLWXlrbW55aTU4V2NtMApIdFc0ZWZtU1ZoYWZ6ZDg2NTVjcnVGaDkrUnNuaXJhazI4eG1kQzJxMW1HSDFJaWpWWnpDMTVRdDROREtoU08zOVcrZTdyZFRqRFpkCk1ickN5OHM3RGVJVzlwZksreVlQNk1OZkwvcTljb1ZqMW5URjlkWFN1YThybnlXbksrNjBwNTMyZEgzYTAwNTV1amJsNmRndDVjM1YKbm5aUjFodmpLZGhpTmVrS3BHMXhIUG02eUliS3F0Q2JKU1dqc2NDaU4zLzlyREloUytJTllrTFVXaE95SkxsUlRFaTYxb1JVMzJ2ZQozTVpXczZwWmRlMzN6dWFnTTNwOVhxN3dvc1FtN2FIZHp1aDVzN1Bzc0xaNUcraFdQOUd6d1Z0b2RUbTMyMExYVGFsWjh5MjBPaUZyCnZvVmVTZm5mYmFPN2JmVDI2Zm9ZZDlETk1WWHZIcFZjWTgxb1c1ZmFocjRudVM3VFlsc3pJRzE5SXR6ZFUzNmJtd0twYXBxZ3pWUG8KcnVUZTJveU5acE56TzUwM0FWWGwzQ0tiSU45RkxYSC9uZlhKUTZxU1RKK3Fpdzh1ZnVOa1A0YXF3K1d4WnBzbk9GWVhpWnNpTitqdQowdE1LQzNBZEJjZFdKMGJaNWt1QVc3d1JiM1pLa1hybGM4bTY1eFNwYjAxU2tXZGJmeWQ0bTQxeW01cU80K3F6YnYzZE1kc1pFWWhtCmZSeXY3MjRpaGZHNm55dzJSVHhzY0RTRHFQNGk5aWJxMy9GeXFuemxjRlBXMDFWa3hhWXNxYzNXd0hGa1hwNlZnMGVkd2RhWlVkWkIKaXEvTE9JK2FwOVg1c0FrMlQxbXI3UE1oMm45WXphZzVWdWYyRW9GZDlsb3ZOaytvYk4xa2EyUzFwUFp4VExmSHUrbDIrOU5OZkN6QwpiZitXQTFYb1BJU1h2YjhiTkh2RHMrcXZYYXpQN0w5aTlQM09hSEpiUmhNN1lOdW9jRi9sTUxFcHg3d050cHhRTk42RGJ2ZmFwOXZtCkhJZXV0ZzQzWmE1dWFCam9kZlRoS2s5WTNYbndSQ1FuRDN0dC81UVZnalJDVHI3dDk1NERDc3JIVkxmZy9mSlZweGYvc1BmdEJlRlEKOXFmamQrZW4vZTdlM1FmdGR1MVI4MjEvZ0VKa0w2azlnUCsvL0dYdkV2NmIxSjd0SlExVFpIQ3FiUWlWcTh6RzdEU0VTYkpjd1FlVApKVHJQNFVPZUc1bnAyc3ZtWG9qeGVma092bndESDM0RzBDODFrZFNlMXY3NVUxSnJZd3N2OXVwSlF5a2o4NkltUlNQWFN0Zk85K3JDCk5FU1JLQ2pjRUZxb1dsMnFoaTdTdklhbHBjaWhqYnJVV0RHdDFZdUdFYmt3dFlPOUFCT3lZZklrcXgzdFlkVk1GMUJWSm8wa1VRVjkKa0Zyamg3U1I1QWJRaTZ5Ukdwa1NKRFdGcUxXb0R6cHpNSWRVTjNKcHBJVkFWd2tpbE5JQmd2V1NScEZMRlpVcUdsS1pCTnVURFNscQpkVUNUNU5pK3lCdENxQlI3N3JsUUY2SUJ6UnJvdW1vVXd1aFE3R2d2YjZTSTBPS0JocElpU1VORFFnRmRjY3V0UFFBVktiYnB5MmdZCnJWd0dxb0JNWlFvWmt5NEsrSVRNWnY3QTM5eGtXV0FoRG9kT1plRHp3WjRIOFhBY0VVZ1ZORUxhQ0MycFdxb05BUklGTXdZQkVzZW0KZ000ZzB3aFBrZVRZVmlOTnRDRThSYU1vbElsQktjNjFGRkRqNE9aWlVVdEZJODBLb0QwRHBoaVRJNEQ3azBvcHNZc2VCTDB1OGxSWgpQREI1TGNzSWhHeVJCQ2pzTU1EVUVCb0hENHFtS1l3YThBZG1weWdNZ1ZRS0k0VFRRSnZNQXNaR2dnR3RQZWhYWWxJZFFDbndRbVRZClVvYWpxbXZSSElBQk5pS2xpYUdnUHlyblVraGZrU1JwRWZDRVNSZ2F3OGxMREk1S1FRZUV5RUtuY1ZvbE1Lc2l3Zz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJY0sya1F1cEFmUjE1WnFRT0RLcW5NcXd4Z2tBblBZeVpEZXNPYWhwZ2dXakl4Q1FXZ1lHeFF0NklBbm5qeWVVK3d1QkRZYTJ6bXN5aApycW1waGxFNVRDQnBZTVVBd3cwc0NLVjFEWlo1a2lvSkZUd0VhRWhTYkJmNkM0c2lqU0N3SGtWUlNJbWdYQUE2WFA0UzBjS2NTZU9PCnNBUTYyRHZiKzM2UGhGZDd6OVR1ZmxwNytlUGVuWk5ab2dxZ1Z4UldVSE9HdUVMbzFRU1c3Y2xWUkJiV3ZJclFpamtTaWEwN0o5T0MKNjg3SnlxTHJ6c21WaEJkVXU0cjR1bk15UTRCWjRNb2lqS3BOQ2pFQVRvdXhPeWRYRW1SUWJWcVVFYTdWaFJudzZ5cmk3TTdKRlFVYQpUSm9yaVRRN3ZhOGcxT3lLdW9wWWc1b3pCQnRDcnlEYVlQeFhGVzUzVHFiRkd3elhsSUM3YzNJVkVYZm5wQWZhNjkwSHZYNnZWa2hECk1zNHBlMUM5S05JQ1dDMThzRGJvZElRTW1BYnp4ZVFGU2orR3dKQVdLcVhWRDNJQVZwU1lCZUo2UjZST3dtUkpaNEZ3a1Jja05MamUKTklSNGxwRnU0SG93RFFtMWFCQnhlS1lnb2ZsSjJvNW1id0hUTEFpd2lHSVlwV2syQkdCb0JJZHVpaFVSTUhRNTFKNEZDK1NIL3N5Qwp4WFduMlJKZ2NXZW1XUk5OSGVMTDl3Q0JRK05vN0d4TWdnWFdURkZUTU9FTlNFT2xZZlZSZTFKSmU0aTQ5NkpzZG0zSU5WUUFsRTlFCitoeE9vK1dnVnh4M096YnpLcHhhSGc4NjdiK1ZGRHQ1NTBTN00xZFUrQVdjWllhakFjVkhmT2VPWDhERzJyMzlmcjg3VnZKaEQrM0wKank4N2JYdllCZnFtMFdHV3pjRW9JSUpqMThsZXdiUEFuOERzMlduR2FXci9jalRxOTA3NmIrRjRGeCttL25RSmZEdDBpMnpPQVVtTgpuNCtTMnFzOWtCaEpJbkNQeFRXWDB3YzgyZmhQSUdhay9iMXVkd3FaNUxnbjRaZk1LbWcxcTVUSkd2MkkyR3dsM1BrTGxOQXdNQUpWCk1QcDd4RzNTWnl3SnV3Wjg1dnE2UmhoQnA2WVdqdmE0MlFKT2g2NDRkaWZxT1NwVkNSQ2ZDcWg0am45Z1dtall6VUVvRzQyYmVjTEYKNFpQdFNPTElkQit3WUlZOWdCNG5FcVU0NFRDNDZSQmFwRlRZRHRFSC9GWExyT2FyZ3FKVHMzeHpUZFFKdGU5bVlvOGIxQi84eGtpdwpDWXY1d0JKd3RMZC9pbXZnK3g2ZTBOdTFWNE5tdTFQQ05Fby9wVUd0RnpqQUlycnRJbXI3ci9DY2wrQi9VS21CM2hnOE5CTUFtc3NGClNQTmNBRWRlbm84VjFETUxTdEJiOWxzVk1lNVh3UWpuZWNTSXc3Uy92L2VuNzJIR3czYWl3elNOMkhRZU04OTlxTS84RkhOK2JFeVkKbjNYSDBMSGhuQnByT3dzT3duU1kvc3R6cDdzWFRha3d6OXdNNFFrU0QyMDg1QkdSclhtRExDc1BNaFFDVFcrTTB6a09pWmdjNUhSbQpRZFRlSmdaNVBzYjlLaGlGRWRFZ3o1SGNxZ1pUUVlEdWVRTkNXdHlXa0Q0WWxPM09xSGJRSExUbkN1bHJNM3RKUStzVlJzeDlza3RGCkZuVHdrMVowQ3diUUYrTUVPUjYxVWxMNTdUZjRBcnFhKzBybkZ2cmdrYmtQaUJUYWtxaFoycjhrNnZpM3FJcEZZMlY3d0Q3V3N1dVEKKzhCWW92NDdxbGpvZ3hZQXhjL3Bid1pyRGRRTjZmNktBZ3ZEdndmRUMvaUFyQWcvMXFNNmRZc0hTeFp4MzZhK1VkL09YREhiNlhQMwp6VmhXMCtIQkllVVAxSnFodjhTak9uVW0vam11NTdBZDdFV05ISTAxaVYwQU1UcFhQUUxOcUFhYXZCRGJyQXNkTmtmbG8wN1piVStyClEzYUphV0VVTFRLVkNnWDZaZlFoeWJRQzdSYktKSEJDbmZXQjFoeXN3R3FyTGlQVm8yN3NmZ01EakpNaDR6OFpEUmdneTNScWNJRnIKYVpUMmQxVkJNMDV4bjB3YVdacEpQYjNlNFF5SDJMTWFUYkhNYmpPRy85Z1pDZHJkSHU2K3RodlVNUDVGclZyN1AyYStlcUVYN2p6dwpBKzVjdWhhMkFSRDRDcVIrbHVHR2srQjVSTTh1a2NQQkVuZUdoVGoyRitPQTAwYllXNGllYzA4ZS9sV1dQaFdvdlpJV3RhQ0xaaW1aCnlWSXl6Vkl5ZFVUbUpWR0dtbmtkTFJKSUthcWpqbUwrSytiVGFvcEFySnBKYkk1VEF2K0tMTVhtbFNNU1ZhcjRoMXc1eXFZcjdNK3MKWU9MeGdsK2twVUphSWhMYmQvZEhMcWFnanROblpTSWlmVVdrRThSa2k0aFpVSEdTS0cySjBwWW9OeUR1ejRJcFNFU2w3MGVTR1M5UQpKRlZKTW90SVN0MTBFMjY2Q1RmTjB2RDNRMDIzSko1dTJUZzhGOVBVSlBGc215Zy9TWVMwTkVoTFFtSjc3djU4d01tV3pGc3h5WndWCms4eGJNYk9Jc081S083bEV6YkhmL2ZsZ2t5dFp0bDZTT2VzbFdiWmVwa2hLN055U2RncEpPNk1TLytjRHpTdVR4WU9pSnVENUZDRmMKZm45VytZbitTK28rYWJjMG14TDM3NGViVXVPOXo4YmhNMWJGZU8remhiMG5xeXJOSEZtelBMZi9mcWk1Tk43M2FIYmJ6azh2aC9ITwpUMVlZNnozSm4vTTlKMzYwLzBNV1Yvdm5ROHdkTllmN2FnNzMxUnp1cStuKzQ5elJORk0welpyVS9mc0I1NDZhTS9QVm5KbXY1c3o4CkdiM1gxSHVyUTFxZTIzOC8yTnk1TnM1Lzd3OFUvdkNkTkFvcGhmQXVDUFNzQ0kxbmNGQzdCVVdPS0s5MnhTdkZxMkRDcXZPQWpYYVoKYzk1WGVKY1IvRWZ5UVUzVUhseFEwNnJtbFhvOFFyaElsWXoxKzFpeGQrcitIUDVtaS9YMUNha3NzbkZkTTdWellsS3BJTFYwUnRGQwpXZFcyR3RaSmpXTWVWcU9YMjR0U3FDd1MvaWR0V0p2aHRoNW9CLzJMZHYrWEdlWjlzaDBsT0lsV3NQSUx0dktUcVZPamQwaVRsL3A4CkNuTGtJWFhUVVBRaEF1WGt0VlZrN3RRWnVhaVZxKzVLTU9CZ0Q3M0xOcmFnOElpOE5kVERNQ3dBaXVtQU8wQk13TVd3ME0xRklJK0sKbXl0Y0dkOG5CbEI0QnpWU2VEUk1IRU9ZZXNZNnlUSTBRTTJjc25kUmFHZEpWcGhQUTV6ZS92NkRWdXZ5L0VWLzVHL2FRdVc0WnUzZQp0LzNSaTdMVkg3UmhuZHQ1U0hvNC9ERXBuS0ZOYW5BUnBVVmlwaGJBd1lNbmo1MWsrTzZzUHpqblhFTTBDMkdPdHZ1bjVjbURKOFVKCmRQZDQ5SzVibm9TbW83bUtMYjVzbzhpUlZ6ZzZ3eXBtZnliSlJ1WjY3cWNkam5haUMrTkJNQ0ZzbWF4aDZBY1BDR3oyb0docUJoaFcKcENHM2lPR0RtMkYrSHVaK1Bwa3dvUmtSMXBOMkhpbzMzQVhYUjhUNTVMSTQyTXVuMWc1RG1BaEd5bFFhUDVVOFRaTzhxV2F2V0RBagpyTlFYTkV1RHFQVWZKSm5walNBUFJDNjBYWWkwQVdDRUM0Yk16S3VVQWxraXlhTmF1Qk9zMnRKK2haWnlNZDZJMnhwMnEyek9LdnZUCm5FMXp4NXNmcHp5TWs2djJmRzlxYVllRjdCZi9oSENZRWlEeGZoZUV5a3pZdElTYWxHRlRjbTZKN0l1MndBVWdMMW1uWk8ra0RKb3AKbGlabFZ4Q1pESm1XZnBNYlpSVmY1M0xSbHMwVE9GYWpsRTdnbUNRU2JXS3V3S0ZLS21IUnhyVkl0SzNZMG42Rmx2Smt2SkdQVXJRdApkbTZQTGQ5d2JrTlBxY3JSaTJOU2dUNVJBNmMxc3AzclBEVUNmd2ovbjNhVTBuR09GNUZ3aStoOEwrV1ZMUHk2U3ZCNFFlVzZNNm9jCnpWZjMzRkFueTBhTE9EVFBMOTdJc3d6RC9OeWZCUDFCN3M4V2U4b2ZkYnJuRXdjZGY5aFpjTWFaOUw3aElVZWtHUHdLekVNbGcxekMKY0VadHlCeGozUnpvS0lEd0EwWERIdm1LTTBDaDRoa2R2RENFTXlseVVsT2xrZVR5WXhDS1BTV290bWprR0VJOURlRnFjN1U5NVZhSQptcmxDWk43QStBQ01PaFUyK01nMHNqU25HQ1ZvQUlPSDRRQU8vUkVKbXRBSzNBSmtnWkpRWVNjeFVEblZqVlFxT2JPcVRGRFlwN0tXClM0bEIxWVpzZGhnSW5hTXpYamVVelBTY1ZnM00zRUpyYkRWdEpLbWt3S0Nza1JsUjBPYWxSWnJrczZ2cUhCRkxNalRqRm9JMUsvVlgKYUJBR1Jsc1BZMUlBZjZHN2ozeU1VUkFoYzliY3ZhZk40UnY2NUUvOFQzcHc4aDZWN1FsRHdFRzNjM0hSd2JkbXg4Q0huU0d1RVZmNgo1VmZ3enlYOG42NUh3Y3d1ditBdk5PZGZOSWQwcCtvRU9nVlM4akhKNy9KdGgyNHh2NnU5L0JZQS8vVERYU2U3Ty8zekU4Wk5wR2h6CmZ2bDZmaGtFMlhMMmYzazBmMVNON0U3WW5UdlVsOFBtcVBrRkxDT1o3YjE4OG4vKzY3My84Ly8rZCs1Ly9oLytQdi9uLy8zZm0vbDkKVHNkM3YrOSsvNjkxbUorTGYxKzJ2dDd2UHlnV1lKdEdvWUJ5N0s4c3RnRG1oZGEzYzBLTmd1WlExQjVkL3ZiYnV4cEsxVWdidUhPQwo0dGZyQkNjdlA3TUt6R0Ewb1hzY2RYcHZXSmJlSjRRbkU2aXNNSk1vUFpmcEEyUFI5ZDlQYWhJVHNmY290UDkwU1gxNWNFRUMvaG45Cit3cEJVMm9GM2hlWlVpd2lZS1JIaE9vemdYSDFNMEl4cFY1RXdLQk8yT2o4Y1JVandJS1NjZWNFMUF5a2FsVkZBM1M5SzZzYW9NdGUKWGRuQWl5bFhWamZ3NXRCVkZZNkt2WjZwY3R3NWVVVFRoYzV6WkpPWnAzRHc5WGZRQVI0OHFUMjRIUFZyZG9GMWZpdkQ2V0hxelBYcwpkRmdPM3BidEU5RHNUMnloWWJRc3dsMmJ3dDIxQ2U2Q3hNZWJKbW1HQnhyNElIV1NtK2dEZXNRVWhrSlAvbDNwdHJYQUF4cmVUSU1QClVoWTJmQ0dDSlJnRENYL3p4RTd3WE9VVUZ5M3NMd3c0c0JwMWtxb0FPeUtZRkVyRkZXVURCaWVQY0VjQTZvQkY1V0N5SVhEZ2pzWmgKYVVhdUIwWU9IN1RLTEM3YkJZWWdMdUhiSVpEMVBGaHlRa1ZQc1VjZVFhZ0xCek40WlE4WXpyMVR6ekJPMGFoUTVYd2NaaEhqM0JVNgpianhyNUhRWkxlbzBMT1BDNVBsWXIzR3RtandtdDJpSUxNdlNDSGtNNFY0SG1PLzFHTXlObzBQdUI4cDNJUnBpN21rMHdwNGNYekdRCjdIREhBQjdoS1Y1UmRLNkMzNVVSWXh5TVlaWklCZUpYNlRSaWhFSjVvTEl4RnVxR3pvdVlYVWQ3ZEdjMXlTSzJBcVRJa25qY0l3QXoKMElNQy95SVFrZWdSZXk3NDVpUDIrVzVHL1BQRStKcUJZSWM4QmpEL3BqaEYvTU9wanZjT1kvN0ZNRGUxR3lMbmxlU21QM1FpVitQcgpCcGNiYkl4ai9KTjRqem1McGlwQU1ySlBCZXd4aERrWVlJR0ZNWXpJOU1nOUozd1hZaW5EWFkybERCTVVwSXdubXFWTUJQQlNacEpiCnlFTVpNY2V4TUFZUmpiaC81anBpZy9CM29UMy9RTVRBYmpRdWVOQnNtWTd4RkdPSVpacEhTM2dNNHZnWHdUei94bUJJWWtET1hBaGQKQ1B6elBRM3M4OVF3S05Cck1jZmZIZSttdUlTc2d3MjRNT09zaTBGRW5nWU1PdWFVaGlhVUdaTitDamE5UkdZeDUxSWdKVWtqeHFVTgpvMENGQ29oamdHTmJBSG11eFNBa3plTmwybjNiZ1dXK2g0RmxuZ29HQlRvdDN2aTdZOWtVZDVCbE9VZ0VxY2UyakJoRWxPV1JxQ1RhCmMwQXBUQjZ6TEd2SU5FdGpqbVdnSjJUeFZtZ2FPV2hyT3VDTkFZNWpBZVE1Rm9PUU1vK1hTZWVtQThOOC93TERQQTBNQ2xSYXRQRjMKeDdBcDN0QnVLK3psNkloaE1ZZ0lFeUpzM1haNUN0QWM4N0h0UWVENlVXTWN3NWJUV0FoaTEraEN1MGNjQVJ6SEFzaHpMQVloYVI0dgowKzdianBZbDl6Q3d6RlBocTNrNkhkN291MlBaRkhmc3J1RFVGc3BIa1dleGhsZUF5cGc3UFlCVW9xSUJla0VlRkR6K0h1bDNESXJVCnUxRExLV2tCcndOdzI1RnlSd2NrazhXNm5aQjg3SEtJNGEvSzNJWkRqVE1nS0hZTWlmUzZVSXNwOTNnRGdObyttT1lPc1l6Vms0aGwKRFBLa3NlYmppWGZhVWNReTFxRWlsckdpNVd1eEt1YnhNaUJpbVFjRmxrVWdTeG9qOXNSejR4SExYQThqbGpFUnZwYW5uUEZHQUdiWgpKSGZHZExlSVpRenlwTEd5NDRsbmpTamlHU3RPRWM5WXUvTFZuUHJsOGJydkVjY1lFaGdXSUpZdVJ1b3A1NFlqZm5IM0lvWXhDYjZhCnA1c1JSd0JtMkNSdnhwUzFlRms2VUZnK2JwOE5DOHlwUHhIRFdFdUtHTWFxbEsvR3lwWkh6SUNJWlI0VWVCYUJMRzJNMkZQUGpjZnIKMG5VeFhwaU9qTEF3bVhhL01BUEFMOHdKL3NUYVdlQ1o5Qnl5bExFMnc2U3p3aE1ZNXRXaXdEQ3ZPekhJYTFlTTFnTUN3d0xJTXl3RwpFVjBlTVZQdUd3OE00eDRHZmpFTkRKR0JmWVExK3U2WU5jbVhXQjBMdkdJSUU4VnFERlBObWs3Z0ZhdERnVldzTVRHRU5Tckd5ZDhECm56ekVzeW1DRUQyTWsrbmxWZ09QdUdlQlI5eDNobmhxSGM3b3UrUFJKRDlpL1N2d2lDRk1UKzdGdnFXWGxadkFJdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJcHdBRkZyR0t4QkJXb1JnbGZ3OHM4aERQb2doQzVEQk9KdGMxR2pqRS9Rb2N5b1BnSm9pbjFhR012anNPVFhJalZyZ0NoeGpDNUxDaQo0bGVjMDJVQ2gxamhDU3hpbmNqWGNUcVR4K20rQnhaNWlHZFJCTEZtV1llVDZlVldvNVhtZWhaNHhIMzNkWmhheGhtK094NU44bVB4CmxkN3I4bFVtMXVMOXdWeVdwa2IvL0lSM21OTmt0c3ZTbDBHUUxXZi9yZUN5aERGOVg0K2w4NnJ3Ly80M2ZIL2ZILzlyL0gvOGFmZWYKM1gvOGYyYk1vZi82TUxOdi9vOVgvYy9IN2hja24rQXN4OFlFdExKcnczbnpKcHdiRm5vRjk0YXRPT25nbUlDdTRPTEFtbE5PRGt2cgpWZHdjczNoblUzemh2c00rcTl3eDIvbGUwUUVDRldlNFFDYWcxWjBnVUhHR0d3U2dWM1NFVU0wcFY4Z0V0TG96aE9pYWRJY1E4Q29PCmtWbThtOC8wV1k2U0NlZ0tyaEtvT2NOWlF0QXJ1RXVvM3FURFpCeFkzV1ZDUkUwNVRRaDZGYmZKTE00dDRQSU1kOG9FZEFXSENxYWQKbkhhcEVQUktUaFdxT2VWV21ZQldkNndRWVZPdUZZSmV4Ymt5aTN2ek9UM0Q2VElPck94MndWU0owNDRYU3FCNEpkY0wxcHgydmt4QQpxN3RmTUZ2bmxBTUdTVjNkQlRPRGEvTVpQTU0xTXc2czdKekJtT2NwOXd4ZStMeUNnd2FyVGJsb3hvRlZuVFJJelpTYkJvR3JPMnBtCmNHcytZMmM0Y01hQmxWMDRHQVl6NmNTaHBMcXJ1M0V3SEdmS2tUTU9yT2pLUVZxbW5Ea0lYTjJkTTROWEM3U0thVGZQT0xDeW93ZXEKVGJ0NkNMaTZzNGVxVGJwN3hvRlZIVDVFemFUTGg0QXJPMzFtY0d2Um5qYmxESXFBSzdpRElwMDRtSFVpbFhnVmwxQ2srZ2J6emppdwpzbHNvS01QQnloUHB3bUlGMTlBTWJpMWc3TFRMS0FLdTREU0sxTjR4eGw3RmNSUXB0Mk9NdllyektPaTdZNHk5aWdOcEJyY3E2THBqCmpMMktheW5TYzhjNHU3cDdLYWl6WTJ5OWdvc3BVbkRIMkhvVk45TU1YbFZRYnNjRndSVWNVSkZpTzhiV3F6aWhJdlYxakxOWGNVUkYKR3UyNEtMaUNNMm9HdjVacnN6Rm5WM2RUUlpwc3pOWXJ1YW9pZlRWbTY1WGNWVUdGamJtNnVzdHFtay9MMWRlWW82czdzNExxR2pOMApkWWRXMEZCalpxN3UxQW82YTh6SjFSMWIwL3hacnEvR25GemQ1ZVYxMVppUnE3dTlna29hTTNKbDExZFFVbU0rcnU3K211Yk9jZ1UxCjV1UHFqckdnbk1hTVhOMDVGblRRbUpHck84aUNWaHB6Y25VbjJUUi81bk55WGphRWE0KzZ6eGRkTWx6MVJ1eGYrK2ZsWk5Mb2lVaisKNjhvY25hcEdsdEtEUEtrb0tLK3hCTW1hNGhzeTlHQ09wcEFDQnVIN01pckZyTWdpblEvQ1YwRVNROG14NkpxMHZXRUJ3RFNsZ0E3YgpKdG4vVWlta0RRNHVHaExJcUZFcG0zOWFnc0lqcmRhUW9HSVN3d2diWG9FaFFKRlBBNmhXUXBlNENYZUVlWkptaWcxSmJEVjg1b0xZCndLa1VIT0JvTCtSVzhEM01YVHI1R1NCZnJVNlk4M1FHQkJXdVJORTFkTThtQVdlM3JLQkUwYTVIb2RSRUg1ZmtnOFkzblVBYWFWcFgKb3FheVJxWXhzWUxHNTVTS2JVNnA5YnpaSzdzbkI5MytzTFJQWnp5YlRxMjE2dXNaUHErV29hRkNrd1pNRWpUVTEyeEszc0lGeE5rbgpzd3I2SDM2bGQ0SHdkaEtGNHRsa3pwU2d3LzdDTmFnRUphbXEyUXdjdGhVYmpHdkxnblpTQzU4UlgyR1RPMGN0UlMxR0hlVzg2VG1sCm5NdWhsS0JEQS81Vm1NMEQ0RG4yRC84UUdReXZoOEwxbk5xMEdmbU82Qy8rSk8yYlM3YUMvYkdlRXgzMW5EcnZmNGtxNUpZZithSmsKZDVXZnZoQTJSL3hZcWpsS1lacE12b29nWmhhVWlaak1jemNmNDM0VmpBS0UzOVRURjFtWVlzUWJtOHQ2ak45MVluaGdxMk5UM2ZJcAovUEZERWczVTJBakcvNFl5b2FJZFNvdlBqV2ZVYnRRZE41anYrM0FGWmlDV3lUaWZNSnRLVmt5bUl5eG1GeXp5eVNHYWozRy9Fa2FUCnpzd1lhWk0ydm5mNkVkbkk2VjRveUc1VUpGMDhxNUpvQytYZktFUXlsNFdvMmQvb2VRRCtCTCtrTUZZVXp6ZU9hbUZTa2l6WHNCRlYKU2twU1o0VGN3TGx2YWtaL1p2UTZGSnBDdGFDUEV1OTlpa0s5WCtJVWpmZG8zVC9xZlJKRWl0dmR6YTZmd0EzWXJ2c1gzMThzZU9OcQoxUlNZUGp0TVN0bW8wRVpEMlg5c1RsSlNwTkx3VWZxUDlhaEVQYzBibVgxcHFxNHdDMm5kUDNSbHY5ckliUHhJc2M3MEtUeVVSWlhwCi9TeEVTYzlWOGFjajN5MzdCWXJpQTFqd1pReUhRMzJ3eDgwZDdVWDlRSVhYVmNRdXhvVHlYbzhNcUtjRllUbDNuOXhUVnZReFBKeUUKeVM3OWswcVdCZlNjbFhRZkhaUHNBMHlXak1TeGlDcFNQY1Nacy9MaG1zV3UrQjc0RXZoMkV1WFh0QThxTVRNU3o2T0VSeWg4c3QzdwpuVHVLaGpheFRCVCtqUzFQSFhhRnlUN2dqbnlZbDdaeS80d0Q3dEpDNWcwOTc2MnRtVVZudjdZMUYrdjBlMXV6aTg1NmNTdFNPMkttCm5jZmNqSGdjR0I4R0l4cWp3R3RtTlE4cEQzbVlhQk1qRVk5UjFKSDNWeTd3RGF1SkhWNFdsblZqNzJKaCtubDZoR05tWWRqaHAvSWQKTDhTOFh4WHorQnRaWVltZDcwMnN2WWwxNmFkdTNjL2R5WFVXcjBBM1hBZlJhbzJXY0QwYTdqa01GKy94REpreU14Z3U3TXVvY3dwTApkSjR1ZjQ0c1lONnZpbm1jNGUrbHpOSENxbU82YnpmQU9LK0ZuYjBTbjRiTEdYcm04MzA3bnVGLzNYdENNa0tvL09qUFhIWDBlL2hrCmZ6NExJMG12cFBwcVlteWtKOGY4Ykg2QzdTSlRwZ2FuRkdDSTJ1WmNjODlCd3h3dFZpaXV6N1NHWXFHUmFIeWMrWHpQcGpjeEF0OHQKQnJtUUpvSk9YRm1DRDdQaTYyRDhtUjZ0TnlZTGtDTVBRYU1wZWxnaUNLcmVNSWt4elM2KzMwdHZkS09keDAwVFkrM2RCenh0UUd2SQpETnFPOGtaU2FHdVhLMHhtRFc1VVpBckFPSTVzTXQreFZ1cVQvYWhQZHZWZ3J6NU5UejBtMkZyL3hobFNqOWxWanpuWnN1L1V3VWxECjB4RVluNWZUalRSVHRYL1lsK3B5KzNxeXg0bFpPaWtLenZESEEwZVorOHFFQnNKbmZmV0ZBeDZ5TE1adFJNMkhidG1YNzdpL01TbHYKbmFvR0RNNDB4Zk9BY3BlYWxDNFNKWXBpcVJ6a3lFTmtabTNqUjlQVjdMMHRYNHg2Zis0aE5JejJjbkRtaHpYNkhnM0hIQURqUEpwcQpoY1FmbGduTjFzZStNdzZCV1U2RmIzVGlhNHdPSCs4enhFQW44dHczTnh3WlZuU200MW5mZmVsNlFFUmZHbHFsQlVQcWFCZEdneWk5CktwNkZJYU12RFMyVkVpamxKNzlvN2txb1BvRTV0SHBRNGRrK0JZUnJZWkhsNlZZYloxOGNINC9KWTdkclhxY2d4cWZYWUwyUllhdEkKYzVjWXhvSmd1U3JjQzBIWVpLa21QMWxPUGdtMGhoV0NYTGtXMEtJbkRaUXdvVWpodkxRZUNRTzRvZGFlQndGKysvYTdRNElkeUlVSQo3VENndGVmNzRzdHdiejJTU1lwYTh3d3U5MTQrUGZyK3lXSHRpOXJkVm1mUTZwWW42Y21uTmJwU0FTTUY1ZUhIc1ZzVk1Cb2duM0pCCkxsMlRxWlRlT2trYUtlaGdxZkV3OHUwb1NiSXV3NmZvRTNLNXFBUjFWMHpVSlZFR3B6Q1k2RnBPYVZBVjBvYS9KWGgrZ0xKSjZ2aU0KVDVvRE9sRW9HMUZvTlA2VTRQclJRdHBMN0JhR3dqTXp4anFEb0M4aUo0dGFnWkVHTmZ5YlpXZzhNN1E3VFJKeU1FVWFTcG9DSDduUApaVVF1TEZ3WVVCMlZBbGxwaWdRblltNW90T3FZYWR3R1JzTnZtVWtwRHNvb2RKalZjZUVMbmJ0K1d4ak9BMGtaMmdRSVQ1UFM5TWs0CjZNRHVuZkJMU205aWozZm9ZS3FMQzNRN2dWbU8wNXFDM1N0REk1MUFucEFocVNoMHZzMlM1YmhzRGxxdloyUVd2bWJwQWxzWExuRmsKc1JJdWJWSU9lMnRCenZGQ3A0YjBMbkxpWVF3aUJUckQ1cXFFOVg0TG9hMXdFVW9sR09xY0ZETExNQ0YxQnZNWW94QndvdU1Mc0RDeApDcE1VQ0xDMkg5eHpNUGNkckMvWVJrbEd3VWNCNnhMVDFtTzRHS0tCNnRBTGxFcEt1dldTcFFtNkFWeVRXS2xBeHoyY1ptQm1rcElGClBjMEtQUFJubU9HUXVvUEpEclY5UHpkTGhNMXZXR1JBSHI1aGF5alNHeVBQSkFHQUl4YlBCSGU2TkhXbkxtVVYwZldzR1prYTdiWFYKWnphRWFiV0J4T2lycVJGQzRPcGpSTkdWazZOa3d4aFhIU2VvTlQxU0ZLdTIrbGpaWU5lSjBYTEpLVmNkcnhuY1FseTR1M3hQWTBDRApjK2NrRE05N0RBdVFBRUlON1FDWjhqR3ZlTUFRTlR3OUZOcGZja20xZFV6WmtFaE92V25TcEVDTkc1UlI1WURqS09mQnp1aE15aFI4Ckg4VjFaQzZiNHArdVcyem9oaUJIUDdJYlJqcWxiVWZyUkVZZzBBcFRlaVZDWU41TWVybElGclIxNEFOYm9JL2lsWEk4aVNsN0FOTVkKZlFSSGtqU2g0MVZTb09NZmtHRXdCbXhZV2ttVjJ5clN3SGFwOE9WcEc3Mk9FeW1qd0FDODFRQVRML3ArUUdrYmNNOWxpR3lBcGx2ZwplQmlhaXJCdlpUaFkwRzBwaFV1aGd0RStDdHJBeFVXdlp4VGFuaGxncWtsQmk4THUwaGd1ckFHUHpYVUNyQ1NER0V4VmpWT1VJdGNUCmlzQjNYSm5pM01IZUl6ck9oeDlTRzJ0OERuc3Q5TThFQ0xRTzJBci8rRGllZHh2S0dEcDZHbVZjdmhVWVdMcGtadDhBQjRnUXVhSGEKN2hZVExIK0Z2OEFjVURtdUlFbzVVdVM0VXVHb29QSFpYL2lScWtsWTlpUllwRlBXOEoyQnRDQ25BTXdscmRHM2x5clkrdUd2SUFFQwo2cDBRTXZWRHdkOVJFMGh5bUJRZWdyUGFHQnlTSkpYb2RFZ3hISWVDWnV4N1dERGNDblVRTkpuaDZjbytOYUFLVkZkTlErblVwclFGClFXUjFVNHBNZ1Vya3A3T3gvTnFHaTlrNjJHQkNsemFBOVlJZWhiT0JYSmdCUW9CaTdKTGgyZ0FnSENHaExNaFlZWWVDUm9RUm1ScTAKZytseFhCenBnbjVQR0NpQm1WQXIrQlFWdmNBM3NmM01WcVZBM1VhdEMwNW5hUUVEcXpCRVc5dUR2ZFJiL2N6NjhlcytKWlNvSFRRSApNK3huMTI0NkV3MGJZb2ltWG1kTFNJUjlqaTJSYkUxSVJIVHNsNWtOS2hObzFrM0l0WVlkS3hCaXp4VVlJb1lQU0tLYlBLRkllb1RrClpBUWpPenJPZXcvQ2JjWG1yQUZJUnRFRzBCYU12aXpjZDl4UFFCZUhobE9xZ1FDWDdNeDJqaUZIRWNUWVorc2NTRkNXNVFJUEJOYlkKVTJocGJkdnVxbVhhOE1adXJJYStBR0tOaDZCbEg1WldqZ1kxaG1FMlk0bnhHNEM1U0FraEEraVZHMUkzUFFoNmhBSWtvRUhEczBWagptK0x2MXBKbnlWQytkUWRDUzQ3N2FxOGVLYjZPQ3BLSk5obURCNUdVcUVTYWFFc3JMTWN6elYrQjNhNGJEdUM2Q1VzT3pqM0dmMDJwCjBkWWVmNGZXOFFhS3IyeG56dGcwT3JBWm9BcVprdHhPckNxQlVUaHdFc1ZBMWdiTVYyM0R1U3lFaGlpbnQzKzUzalRFWTBJaFpkeFoKbHN1ZG8vRE44a0pFTlFNRTFNczhzV2tTWFRWNm1naDBuUmptSzZKTnJHSHZiSUo4VmJpM0EvN2NZWU50TmNzb0t0Q0RRbWU1M2pTRQpNWEd1UDlxR1F2YzlDSmNWWUkzbXNxUWd4bmd4QnZSVG1Kd0VyK2R1ZFpJR3lrK3AyQVl5WnpmVytQaE9EVlpiWm1pL2NkOFZMU1U4ClVEaEF6aTA0QkRUN1NkR3dUYmp2WkhMSU1EYzZGeENvL0dLSXBzZkFnTkFHUTdnWERnVjNjb0lNdEw1QTVVeEhoRUhWSWsxOEZWU3EKWVhRWUlYL2xGdm03NnhKWGRsMTJ1RDFGNkhWQ3M2a0RwSUthNE1yOGxYSHpkOWMwVjNZZEcrOTNhNEZoQVVwSVVKZzBLRUVaR3FkZwpiOWNKMlN3em5jaHQzZzIvYTU3dU53ZjFVZk4wT2tCbGxhQVVjdDJqaS9MY2ZpU1hPR21sS1lXQm9rbEkyMWdBL0VCT0c1TFg5SlY4CmU3Ujc4RmVzcFhQN0ZjYlJGbVdrSG1Bc0t2Y1ZWcVlUM1ZMUGcxQ1Y2R3R1TjB4RUtXM01DWWFpK043UXQ2aXo5QjMzQWhsOWhxckMKZlNYdkQrT2tMN2FMZFN1NS9jNmlKNzY1YnMxeFgrdnFFUnpDZFZ3N0FvTWJQd2RsMVQwc2k5bis5V1JBQnowUmxpK3BLUk5ONjNMQwp0NzFDcS90WGFIWEdTM01UOFI5ak0rSjhiM3JHak0ybmVLNU56VVEvUjYxVE1KNjhZL05haDdFZG0yalRrMUdOVGIzM0QxRmdacWN6CldLWThzNVBwSVNaK1prdHF3aUZtMWhDdjBPcitGVnFkTWNRdVhoVWxzQ0NsdXpCMHJRKzBiMG1SeVVXQ2xpazNCdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJYkRoQ1VrelBDUjZKOHhuckxyeVh6S1duSWFIR21XMGpuVzZEYTUxUFlNVnYrUlRHYVVpb3NTQ3lBWFJ6MnB2b0w5bys4RFU5dWZXUAo2bjFYL2pwNk1DaWJKMmY5MXVWd1lvY2lEOXNMUEsvbHhnZzZwT1Y0b2NhZTJDZzBCclFiUlRjMmM1bnF0UGJ5d2V4TkRlWlRJVktRCkVWTjdXNFlPWEtYdDVoYStITGt2ZGZkdCtvdjdQS1JwWTBLVEtDNXptTHEvN0dVWVpLUGN2aG0rSExrdmRmZHQrb3Y3UEp5cjBxRHIKRmhRWWN1SFdDano2SlpRWUprOXV3Z2Q3WTVPRnNyZWRmTnZ2VVRnTTlMZGUzd3NKSCtNZjlyNjl3Rjl5Kzh2ejdpWDgrK3owNTdJMQoyck8zNUdyN2c4dmg2OXJUWnEvNXFoelVuZzNhcUE4dC9LMW1menhvZHJzZGtPUVhyenN0Vi9JN29QNWVMYTFkakJxMUYvM0xYdnZlCmRObFBhL1c5dStNVlJMS3d4bmhoWGJzZ0ZGRGhVYmM1NHZJd0daNzFnSjJ2eHdvZnZHNE9XdjFtdDFhdlBTOTdyVTZYaXhPS3RpMDYKVnFFNSttUUluM3V2TGtzdTZ3WnBFajJod0Nya2hoM2UrN1RXc0t5R3NSbGo5QWNlc0tsZXc1REUzWWF2bUhrVDl5VDcveFQzRHp3MwpZeEJNN2NHVGsvMEJUTjV1U1JpT09xZXdlazRPanFHa09VR09uaEJoei9zWWFIVkRKTTBaYktBa25ocjRGZWNLL2MvK1B5Z015YUsrClhxbnBkS0psT0lpTnRadGNVN3VhMnNXUm9HYmhnRVlORmZTL0NvMSt5SUdadGFwd3VrMHVLNENCV0t1eGZwZmRxL0YvY1h6dTFWejQKWk5pQ2hQK1VvQko0TTlUTVdjaEVrVjNFam81dnkxKzRjRTJNZjAybnZ1Si9jWm1wRkZRU1dqdTQzalI4a1JnRUFkcGhXa2pMZzJRdQpEejdzaUJiMkYzN21lYmgzNzIrOS9pODkrZ0liNWQwSDNYZkRZZlBrOGZHbnRYdmZ3b2pCcG5QdkFleWtiMHN1Y3UrZ2YzNkJVLzlSCnB3dUVZaVVZOUU2dlpndFlxRlhlNzdraW40UHVldStIenJBRCt4MGluTVp3UEdxMjNxeUFZYjg1N0xUaTZvUCttN0o2ZlVrL2RKOE4KWEVYQXVPaXA3WHUybU9OQXJiSnQyL2tlN2gyV1o3WDd0YjNhM1FnUGJ1ZjNhOVJzN2Y1ZTdkN3o1bUEwZzdLRGZxOTkyUmxWSVdvQgpGaVIyQmU0dTVBWGlDcHg0eGxQbTArbUpXL3VuUUR1VS9ZRSttU1RQUWVYQ3hGVmE2NElTTnZ4VXUxamxKV2d4emxIZkcrU250eHA5ClB5d2Z2aTE3ejlydGlteStUZ2JoTnB2a2lzTFg0Y1JXME9QeE9oUDJhVDZqOGVZdWFPTndqcVpuKy9KQ0NWQlJWL0doZkNpdUxHRFEKZnJmc3RUOFVod2paeXFzcGtCZnF6eVZrNzk3RFg4dldKZmFCZnFDNlU4S3VoKzdDZFpaejc5K0hpWEcwMjUwVGU4L096b2JsNkZNYQpnRG4xWFlVbjNlNGxuV3I2ZzBiekF0VHNlM1lud3B6eWpuMTN4NURXam9DVnRZZG5aN0JSUWVudk9xT3JDTjY3enk1SFF6Z2ZSZDdlCnc4N3dvdHQ4Wjc5K2VvM0MyUzhiQzdka1Blblo3bFFTS3B1MlpqNzBKdlRCSisrMVNta3llS1JGbmtlYTJHMEk0YTJaUlZ0RVUrWGQKcEphYWRMMTNsSjNtdkRhYTgwcTIvQThpaGNTSFVBV3RSbkE0NkYvVWpsODMyLzFmRmlzUVdOQ1dhelE3c3pXSE1WeGVWMWpJVEUvSgpSYk16Y0tTaEJiZDJGMS9OK1hTT2hQZG5GUEYrVEIyMnV0Um9sbkNyN2ViZ2paUHpGdkM2UC9pTkFHaGZjN0QrUmJNMU5neVh3L0w1CjhkRis5M0l3VnZjMEFNZ2UzQm9PV3ZIMzAyNlB4ZzJPRU01Z1RFTml0YTNhdzE4dm1pQmQ5OHV6L3FDcy9WQU9oaTRxN3BZM216RUgKNVMySTVrS2E5UmJOTzJWL3ArenZsUDJiMlhtdks1eDFkd3JZblFMYzVaTHIyMnBtaW5seVI5VU8rb01lN1BnZlNzeFBJSzJvbXpVRQpCclk2WlFZRGVpNkg4NmI1N2tDek5RZWFxM0ppWjZ4ZVJiRGs2NjNEN2xiam1xeEdWSEtTTk1NZ092Z2dkVUxPSmY2QUZnYUY5MnNtCi82NloyOG51VlBFRGs0djJOU3BuanlGemJRMlB5dWJvTmZLNTJsNkdVWmc2NTczc3hjSzk3Q09TUXNWT0N1MmswRWJwQkdzZ1NYSzgKZUx1VEpFNlM3SGN2eTlxMzVicDc0RzlabEdBb2R5b1QrOGFPeUdSV3VHajdFTWVkYVludnlZVElrWW1BYmdIREtpaWcyK2pwWUc3eAova0xvTm5paUU1TmhtSDlEWmpJM05pKzdTQXFLNWNicjY4TG1mNlRJTzJSTldraGg1ckpHYkJOcmpESDRTZ2ZNRzYwemtidnBrZ0pMCk1sUUJOWnU1c2dJL3plVUpKcGZjRnBaa3VhRzUwVkNTbmg1eEJqKzZBWUVzUVhzZnpxSE1vTVZ2TGtzd3ljclc4Q1RQMGpRWEZJK2EKRkJuZkV3SVd1WUEwV0Y1UzY3bThVQitHRVIvY0dIWXJLeTQxT3FWd2VwM1NnNzU0d2NzSzZrWnFweFJtRkRBcUl6R05VYjl5TG1PdgpaNFpkcjJNdnVnRjJEUTZLclpnajJxUjVnZk1nVFZKTWp1MFdtOTJYTUJtQXdGdHNxQ1NtbU1ocDN1d3dHemc3cE41TmoyWFRRNms4Cnh3MUs0bzBBT3pjMDc5Z0dVeVBpMU5EV1JETm5hbVNiT0RXdWRXYnNEc3M3QTNvNGNCNjhIdlRobVBuWHpxdlhYZmovYUtQT25ldmkKbFY5OFJXMmhUY1ZXb3RKWWVLNWRaUnI1MVdOSzdqMStkdnJ6QzVnTlg5VGkyM08xWlhUY2l5OWFZUTVkMTQ4UWcvV2c5NnBidmlnQgpHOHljNy9yNGs0L3pPdXdBS2NUWmlmS0g1UVhNNWVHejNsaTRGemxaZStXUXpFR0ZCMU9Oc1lJRSthRTU2UGhFWjJORTNmdSsxMm4xCjIyWDE2SmtYMVdNUTU5NFNUNlFTQmEzZzFmYWVaSkpiWTRReDJ6eHZsckJ1Wm1YR1BGYjMxdmM4bDVyM2hqYTkyOUYxdFV6b3VKMFYKQlQwWHJXQ1dpWlFDYnREbWdQcU9zOHhNZnBnLzBUQXIxZXJUN0VZT25WYWF1R0E0dkVMNm9lSXZ4bEJXc3pNclhodm4zYzQ1Y2dCegpKbUtxYmc1Q1BSdFNmQ3duRy9pNU43cW91QzUyd24rKzhKZWJLUHpkTW5NUjBYTlhYbXBrYm5ZaXZwcUlsMlNBM3F3VDcvV2RhUlprClRKc1RUckIvQ210cFJqNm9KRm1ZRVlwU0pHMVEyS1c4cG5qNGozMld1TGZrdG1lUzZCdU4vdDZBTVU3ejZ4L2lqODAyTW40RGEzUE0KSXJ2SW50dGF6dXRqckZ6UCs0alo4dnVJTjNIOWsyOHE2cW1iaXRsNzNGVFVremNWeGNSTlJiSFJOeFZ2VFF4L0ErSjJsM3RwSjRJcgo1MTdDQ1RNejh4Sm1YTUkzTStuZnBKYnFOR3VrR0JZa2lpSTFqVlFrK2lOSXZBUlN0S0JRcUtTUU5rU2pLQXkrdTBCME4zSmpNQlA2CjdlVDUrTmhrMjdOTDdQcmpidjhYVE5TNVdkNjNuWXpicVpuT3h1OW44WHRybVRHcWFrcm03YXFRNzZNZnlwMCtlQldaK1UrQU5pKzcKbzU4aWFYbmNPYi9vZW1rNUo3SEorenQyWnhFbzNOUjREdUo0RlBXYThvbys3TFZEVnRHbHFVbWZON3ZsYUZSUzM1K2ZWdTd0M1gvRworYlYvK3BTb2Z2bmIzaVI4NzNscm1pMTNmM3pkR1pYMnQrb0xCd1lUOWc3R09ETkgyTjBYai9kckw4cTJRNTBZZXNHVlNoc3RWTzdWCk15NzdqN0tMeTk0V056SXo1REFJdGl3dTkzaFFsajFYVEl1c3NJbnRHMExxMUlhNmU5S3c5TUc3SmhmTzg5UlFPR0ZtQ21HaWhMcSsKTUY2L2NJV2xLZXdWUUh6WjBtWHpGMk9GbnpaZmxiMVIwNVVIcFFvb1JPcXl2TWhJcTVLWnBMc0lpY21VdTVSZ2NncUZGWHc3UWRqNApWMEw1bFNqUzJ1T3YwcUsyLzVYU3pMWUVxaHFiZDE1SlJmaFRTYzhGSjBsU1VBTE5BcEZSNG9ZRVgrQWpoekpGeVZtMEVoajArQ3VaCkE5clUrQ0hMb0doS0kydnl6TjZIVEJKaHg1cWpuVlBmelRGOEFIcjhWWkZFK0xBdThKYWl4aE44bHhtUTVOcG9kNmx5S3RwWEVOMGUKSC9aUHdMK0FNQWtJcFZBVW9vOVBEdUk0WkNLMVVlcUFXNlgwbzRGcFdSaUtFQlFwTU4waDFOaEI3UEQrVjdwZ2hFcUwxUFVuRlhtdQpIQ1lYN1Y2aytCK2FSc1JNeGlTUmRTbnhMdVdSeGljSmM4dXdsS0pYWVdLbk5yQTU1OFNsR1haeENwMmdrWUJoak5CcHZLSWg3RjJOCjFFNmNJa2x6TzZtMXU0ZWFNZWVBV1lrdWVNS29CQWt0c0h1RzhXWEtDR3NlQjBRWlRRZDhTUU1qS0J2U3h0SGlBM0J1cGtqTFFZdFAKMDBEa0F0QmxpaGVOU2ZGVk1KeXFHcTlJVUU5VElOamVLdEdaMURSN3BNMFBZaEZSdHhUeTN6RC9nUTVhSG1tcThCVTVaQnFsd1lXRgpsaGh0eHhYRElCUnlRTnE4cnhHeUJIbW1lVlZrc05TMDdRRE0zU3kzekJjOGhwNDZPNUV0bWxSNTRvVHdpSEtsNko1TWtlVFVLNlV6ClRjRVpPQUV6MnkxL3FjaE1kY3ZnWWhVNlk2bTFXZ0lWd0tMc1ZNVmVTY21yS2M5MFNyelIwaWp2Nm9qQ1F2Z2FRdWlJU0xFamVjN2MKTG1DeDJOV3RGVFdmcEtwUU5neWZIaXJ4bWJZVGZNbE42Q3dNcHV1WkFieUs2Rk8yWXlTdVlieGdmZEdhVTFvU1JzRTNSUktlOWFuRgo2R1k5VFhvVUYraXU1RW1xSlhVQ3hJUndpNm13VTFWS2l2bFZRVHBpN0l5OWdtSm5mWUtMRWdZRWU4WURxUXF0cVE5QWVVRkJOYmlhCkVrdXd2UU1WaVIrV2ErN2FENittak1XdlVMeWFRUHdnT2lJcWt3bE5BNEZ2cU52NDlNSWtGTGhFRDZZblBEWHc3ZlBIWHlIRmhSY2EKQW1hYVphQXFwSDNmSnM4a3pZZlVyZnZBUHRzL0ZocVMrVmNrWWNmTjZPR2NCRjlXNWFVUTlnRXJYakhDQ0tkUHZBMmtOQTVTOEM0bgpjMXg3c0hxVkpQbU43OXJhWFRyajZXRndwMEQrZWZLQW16aHBjNXI3bmxNZ2xSVXRPc0NaMnRrTGROQzhNTG05YVc4c2xBU0d3a25qCmVhOXg2eE9wb3RXWmVkR1kyb0VERHRIR0RkeTJLd3prV0VGeTIyOVZMTWpUZUt2Q1o2dGhxOEloelQzU1RKTWlBc2lVSUtUQS9aeHcKd1Fhc0NKbVhhVzVBcE9ZOEFJQTB4NjdTaWpYYXM5RmtWcnJsOUZJcTNYNnhHbFFpQkYwbzhoTGNYMnBRTWhvZEZPTEFBRzFvbWJEUQpUSVV1eUVLakNwRmJ3WjNDN2tYVHA4Z0xDaWZqWE5uS2loWHNQYUR4VzRUQlpTeG95OGtsb3pVeXRmTS9Vd21oelZVQ24ybUhNSUlHCm0zZWVsUGRhdDNmRU93OXRQRjc0cGZaeFpMeGdLQkppQXJBVEh4Q25TM2ZFQkRmbXVPMjRPU1hHaHd1bktPM2JYck9BTWJJM3NnQzMKWlMxTWZhdFhBVlB3eFdkY21idzd1Z1VKU3ltd3RrQU9XTVl5WDFXV1dXR1l3VzVrN0NMTUJDMUxBMnViMkNpNXI0S1hWZUtDOFFncgo4VFVscVdzWGszWE1ramI5ZWMycXg1R3VQY3NoTzE0NDREaCs4MjVwVlN3VGFqd2J0RjUzMmtzcnVXS3VIcXUvKzYrcDBjdnpjejRlCkxtclhGcHVKNG5HLzJ5NTd0UmNVVzdVRVQxd1drYzAzMmtZSTBEaHJDMUtWUlRuMkp5cTVvbllYdS90NDBIeEgyYUNldjFycDBHUDMKV3BTZ2ZoK1QyaTVtZkMrVGtHallmbWk5dzduQkJuZWlnaVZtZkhCaUdlZVJ4Tm5wdDM5VEtDdWdVbnRmRjlZekxYa041eGVhaU9ILwpUbTlESlVLalJOSXMySTFPTTlwVU5DajZ0S0hDSGtwQnBpQ1liTWRTN3Mva0I0czBvN1dJU25ubVJTY0lYMUltdEVCaGdCK1NMQ05rCkVyWmIyczJVLzMrOFcrTy9LTmhZQXNHbXIwaVFvM0FwZFB3aHliVGI5TGxia3g4Y1lra1NrODQxOEMrdmJBbVNsOGhVV1c3Rklld2UKMm02NFJVNXFqdkgvSDl0OGREcStuOEd4alFTcmhIT1hzUW9QakxVOU4yVGNwY2tQRG1ObWQwalNKVEtXT3JDOUdPcWJRQTBzb3c4NgpkY2ZYM1AvZnpZdEUwYmFQZ2h2KzVWTk1yblJoSDAwUUtjMHpVSjR6NDg0MTNKZkpENndBSkhTWXdma3J3MEhyU3VsdzZOaEdlb25DCmdZVi9lVzM5V0o3V0R2cmQvZ0RPNmYzTEM3L0szR1FHQ2EzNDZoc2ZaaUlOdTRnVk1wTjZGVnQ2UlE4a2ZwS3hHWUhXQmVrNWJxUE8KV0EyUUZpTlBGYXRDMFo2ZGVSMEt5RXhwL3dBZW1kUVpHK1lkVXJXZU9xVGFQdGlSTEhCRXBVTWg4REViMGhUakE0aEZJWkdjTkhRQwpGbU5tdlRHcHpQQm1tOVVSN1ROMGZNMXRyQStTNW1uR1MwbkNTdGMwcTJTR3pNTG1UV2FjRXNmWDVTSkYwL0VrTDhMOEVoYlo4MzF2Cm8ySlQxQ3J2NWh4MWhxUFlQRGNlTXpEdDdJalRYY3k0aVJROHYvRUxQRk4yTldyMUtxLytpQ1IrUWhEUi9CZjA2QT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJY2pUcTk5d3p0OU1QMzA2OU0zajNlZi9pKzR2eFdrZzFVT3kvUDIvMnl1N0pRYmMvTEczQlo2NWNjMVErNnBUZE5oZDgxT21ldzU4WAp4MGp5Y2RtRTdSb1pNeWpiblJHK1JJOFBhMDI4VEgvM3I4QTBlb0N1WFh2VWZOc2ZrREh2THBINjZlUmJlSmJHK2J4eTQza0lwSjJYCnZSSDByNGtQQi9MMzJoZjBMYklSMjBlSnJWVjd2MXVXN2FQeWJQUkRFNjFvdGNrWC9wTGFXUmRmZ2VyQkhMZ1lsTU55OExhc0llRVgKMklmaDRncXRidWVpMXVxamtmZlgyZ0E2MmUrNUdsbjAzR0JjWTlBY3dteXJ2eTFiSTVCRnA4MXVzOWR5dmJyN3o2ZkEwY3Z6Mm90eQoyTzllT3FPcHo2OExpRVROMDN4Y2ppNHZLSnpjNG4yT1hSL1YwUERzdWh5aVNJQ0R0YWZsOEhYdEJUWGUrWTBNcjFFenRrYWFqTldBClpYRnhPVnBTSndsVVRuWHVxTmw3ZGRsOFZkWmdMbDVlMlBMZTJRRExEWWgvVVY1Y2RvY3h0bWpRWHVCeWkwWnQvTmZ2K2hmUmIvZGUKUGozNnR0OHVaODZGKzdXN3Y1NTNlL0J6SGRnMTZKekNnbmZEZE8vQkFKUXVXK3VhVVh3QS9GRXAwSmk3N1VIcEdNY3VHLzRWL3huNQpkeWp2L3JFM1BIbmJIQXp2UjlNcEx2bzJNSkxnd3pubGVuNTJ1WjRNeDc1dEtIZDYvVjVaZ1RIZGZ1dE4yYTdDR1M3NWdTYm1WZWs2CjdmVGEwRkZSZ1RhWUhMQm1yZkJZVGw5YytnTU4vM3R5UWl6a1JDWDZPL2pBYTVXSnYzUlVOMm1oZi9HMjhsTEhvcmM4bzVFOFVHOUcKL2ZQYmxXVFhOdysvR0RaUm1VQVZCNVpZMWVsNDdldmlHQjhqV0p1dWJNTXFIWjc5c3NhNzhTMHZneUcrNGIzaG8xeUhjN014ckxMTwpvL1NYVHB0dUN5OGRYMWZ3ZGdWd05acGVseTVqeDFLaXVPVHRVaVhSNDdHTXFIZFY2SGwzMjZUa3VwRExLUG0xa2ppNWJVcjhpWHNlCkdhZjlFZWdCZUxCL051aTg2dlNxVURWZFp3MzJmQkoyeC8zTFFhdmN4MERZVzkvMFlXdTY3UzZjbDZObUczU2c5KzFIOFo3OStIM2IKbVRTcXpLNm84T2V6dHFLeHVYUmNkdi9hSEIzMlcwZjlWck9MWjZraC9UNXIzdm15UUVzNWVISVlsNHgvL2c3MUkyelY5VjZvUnRKSQpvcTYvZWZEazBXVzN5M1lhRjdRSnY5b0t5bHRubnNNdkZ5V0ZlajhlZE5vbnVHUWVOVnVsejNTQVEreGVjWHZlNy9SR3lNMnBXc2RBCldiRGQwRUJNRnZtKzEzRzkxWGt5cjNVeUJEMzhkZVJadTZBczlqUXVxblNPd24xbTQ0KzYvZjdBaHUxUldkemRza1ZsOS8zTVdGcjAKQlJzQUZwVWt3cUlPNkxsa0VjNW5GODFXWi9SdU1VY0paK2lvTkJpdk5yc284aXB1UFM5eXNhQm9RS3JtOC8rSFR2a0x6TFhEem5BVQpMSnRHNjNRQllzK3JISk1UVVVES3NwazFJbk1rRlZqR09oTDNFNXhieEdUMzlCck44YmtMNHFEc2RnOUFXcnVDNlZ5Y1dQQzQ4eHVQCnh2eHUvclUvNlB6VzcvMDFVb21RYlhyUk1Idkd5VG1sdnZPeWJuN0RoR21TUWQ3YWJTTGJkYk0zNnRTYTNVNXpPRjB1dG5IM0wwZmQKVHErc2pjcGZlUlY2TTNIQk5tc1VTSCsvQkd5amQ3V2o4bTNaSGQ4NUFLVThPYjdvajhocDk3VGZYbUs2NXphSGRLdGl1RXlnRWRFVApFaTJwMVRXYndPZFBQYzRrUTVQbGgyYXZNM3dOcEVRemtWeCtlU3JNVWt6WWgrZmRacS9FU1JJTHJZVnJtMnBRY0h3SG1ZZExvWXlXClQxWXNYejRCejNmOWk3anJWZGRmUUxCUEtsV013MlNBQXhGVndUR0xnVm1ocXpFUVYvWnEvTHZzbGdPcitqM3B0Y3Rmajh0V3Y5ZGUKcmM2anptQzRwQm1hR3ZPSGFWNDFUODc3RGE1SGM4V3g5ZlduaGpiTFJMV2h0ZTYyNlpGbHlnOEcvUXYwVnRyTFpOT21pUW5OS1JjMApwYktwZHFPeEdXL0FKVlI2NnE1UGd5NzBZREE2N1RjSDdacVlUcjhVT2MyOHZIand3b2tRa0FvcUZncXcvci9ydjdDTld1TDd3NDdmCmpDVDNvM29WTVNIWW5neTVyODVqL2UyMHRzc2xZcFZ4Z21tcFA2ZGZOTnZ0Q1lGOVRvOXFqSUdHSUdzblFDQ2MyWnZKRzB6N290TVkKRittdGZuZmdWZEVIVDJvUExrZDk3elFzSnpDU201RFY1TnFiWHIvMUJnUjM3WlVOeVZoUXREUHNnOWd0YTZkNFdjY2x5Um9yWE5RdQptaGV3RHd3NzU1ZmRabkJReW1qbkdRMmF2ZUZGRTA0SHJYZlFacWNOcGJtTFdpcVpSMldiUEY5YUZEUWlvZVhJZXp5bldFVlVyeUtkCmExblpBVy94c1RJd282U0lPcmkwYU5TQnBXVjlCNFJKODlTWDVEUEVRYlAzdGprTUdvNFlHNy9uN0ZESCtJVGF3M1puMUxTQ2JVSVQKSTQrdWxUZVJVL2MrL3V3dmVrMU04Y2w3WUJNZWJ5RnJNQmtmY3g0YXZLcG1YZUNMbk42MjBoSHFFYkRDcUJKMWZMTFNlRXVpOXZENQo4Y3BOMlZyTDIxclZ3ODZ6OC9pSHg0LzZ2VkhRQU5Qd0F3eExxelBtZG5jUDZ2N3dHUHZ3ckdkekdFNys5ckk1dVVpcHd2bEYxKzlTCkU2M2o0VFppVzFUdCthdXpjZm9BZHZqZDRYUkJsQ2QvS3djVHl4bCtlTmdER2U1RlFkVHd3L1BUc20wbDBMaW9ndDhvTk9lN2FTdlQKMUFHak4wWHJWSkhYL1YvKzJtbFBFSDRFN2JKMGZ1TElXUjdZUWZOdVFUREh1RWFPVWhaVjhRZW9pc2NjOEdVSTN3RUdweHk0NEpRWApjWERLVk5GblRucytqclhuWkY2cDc3eGVIMGU1VUJITDlucy8yUENXL1RpOFJVd1VmVFlSWTFNbC9BV1hUR1UyWWVFbGZMSVlxekhLCmxsM0txZkZpczFsbHkxVGpsY00zUHlDcHFQWDZJV0NwMXVsUlFCSnFHS3haTFJHYnJxMTd3Zmg1NytmK2FZUFFOYnRkM2hHR2swYXoKcVFvZ2lXQ0hmVFZCd3p5OGkwc04zM1F1VG9FamI4YWx4R1N4QVp3Y0I4TVNxUmtzTGduN1dSQlRkNmVWd01ueVRIWkUwWDIvcXlHagp2K21mUHVtZDlXdkI0TGFFMGZONmR0b1puVGN4OUd4Uzd0dTlJaTUrOGVyOFRlTVVOOHYrMlZuRG1yUGRQajYzK0Rrb3djUEo0clBZClBvNzhjbGpDYmtNYnMxK2dUaUd0L1ZpZTN2c0JSRi8vM3RNKzdPZmxUNHZaaWF3dmlUTmptdlpVQjRhamJxTnRtNkJKd2tPNlpMU3cKbWlzZjdMRlY2bHkweitIbmJxOXlweTdhbFpIYk1BVmZZOWJZWDF3TVhMRUZZd0psWE90dW5JV2NPZEpRTG5JUlpzWGNVckhQVGVUegpTblhPWVRFM3VuQ09xMVp5MU9jQXYwSXRMamtJeldkNmJpOXQyWGpHM29YSkJ4SzFYVHQ5VnpzY2RON1NZMzRMQmdHeDlPS2RZYnFoCjFnVFg1aGVLbWJZQVZUK3lIUzVBTmxGc2F0Q3BGQjFXRm91MGRqbnN2T3JOT096TUZMbW56cm0wQ0NNVjdKOTFKczMyczJYNDBFcXUKeWlKMWJEaW1xZTRPR3VmZXpqZXZSS3Zmd3lSdGVGcGRRQXVXOUZ2aXFiMzBaTSt4TTBzUDJvMytBSlgzNXJUZVBWbndESlFGenNKRwo4YXd6UzEyNEUvNml1VUN0dm1vc25IeXVqQXU5RXNuY1VrUDB0VEN1cGVYZUxxWngyTHJvdHQ3TmwwcTJUS3MzYVFpYkxET0NzMTUwClZwOURINHhUdDNteG5BK3UzSUsrMHc1Vzl0QU50a2p1WXFraEoveFlPbk9wdUpYVFlXRlVxUU5UZm9TWllseFA4R21sZVhzMGlIaFUKRjhkbDBZSU5la21aMXFCL3NhUUlLbXNkVUYrV0ZCdEVtVHFXTllvR2c5UG1ZTGhnSE1kVmpMQzlWQ2c4aWtoYVZqYmFZeXJvUmFFYgpGUXI3YmxRb0czVmoxaW82NjQwYTdlNWlrV2ZMWEF6TytyMUY4ZzZMRFM5UGVUMm1zOFpvQ0lSNk44dk1VUnlDS29ySzY4SWl2ZkpWCk0xaHQ1eFRDRXdnb3RNUEZzd2JMd1hiVFc0eXJLeEJiMDN2YVpvLy9zREY4M1lSRFFMbUFTMWlvSEtIUGlIUDRSeGJmaVlManBiSloKY3Y3WGk4YlkvUTNxMnF4U2cwbmRudXhIczBxK21uRUttRlhPN1lMQndUWnJmb1Z5MWltMnVHUzNzMEJrUUFGMC9qWEhEdEp6Q3ZZdgpXZ3VrQ2hVWUxoaHhLdEMrWEdnVFdDQjVvZnBpTlFOT2RNUGxld1NWT3J2c3RSYk1FbHZHV1NONHBpelpHS2hPczlkalcvdnMwelNWClduWTBhSjFINnRMZDd4dkhqWnE5NUFpbjNIYnRYM2VQZjN6Mi9GK2YxdDdLSlllemM5RG1JcFZ2bGc0SlpmQjQ1ZjA0YzdyRDE2ZGEKNSs4V0hOdWpnbjM3SnZmMDJmb0JGNDlPMTdFdFJnZEw2UFBPcjJYM2VUbkFwR1JUMXBqajV0dnlLWnlkT2hmZDhzRzRIZU1LaC9WTwo3MDEzT0lKRjVmMyszT3NudlRjMXZNVTIzbDF2Vko4dzIxN2d4VHMzYmphbjJ2UERSODZhaFZwRC8ySmtUVkRqSnNKditxZTFaL2FuCnlPYVZaZU5HdUxoVU1NdmYyKzh3cFErT0Q1NDh5ZlZoaVRNQ2YxUi9lZmJIZjM3MjVZOWZmWEsvK2ZMemI5SS9QcXZ2ZnoxNGZQNzYKaTFlOTMzM3o2SGVmMy8za29OTnNEUDlndnYvclEvUDdMNzcrL3ZHZm42cS9mSEgwcjArZWZqMjRiR1dQSHNxbitSMmgxTytUWkhqNAo4K0dyejVNL2ZIMy8zNDAvZmYzbDV4ZkRyNGQvay9mMjdueDkvK2gzQXk3MHpXai8xVi8vZnZUMWw2bzhQdWg4OWVmV1lhUHh5YXVwCnBvN2EvNEQyc3NOSGQ3N0kvdnZ4NlBEbm4vYlZmOWMvZjNEZVB4ckM0STVlZi9abjgvdkxSNGZxRHovdS85ejk1TWU5TzRkbnlUZW4KTTVIOUlTdk9zaC8rL3M5L1BmanVvUEhEL0ViamNsLzg5UFdYYng3OTlQVVh3OGI1WjRlZjM3bDhkUGR4KzJ6dkRqSHIwZitjUExzOApQUHZweDJ5LyszWDM1UmRuKzY5SEI2K3oveFpqN1BpZlB4NjJ4TkYvdnY3eUw1LzhhUEZBbDRjSC8zNzE3ejU4K3VOL0RwKzBuL3h1CnY1Ny8vSWNIeC9YZjkyd2ZYamJibDN0M2lwL3ZmdFo2Mk5KL3YzdndXcDNjLy9MQm5mU1BuKzEvKy9uL2ZQYjF3U2ZmUHpvb0wvLzAKNXgrKytmM3IrNjFXOHcxKzZuejI4T3pvdFcxWkpQZWEyYUR6aC8vNW92UHZiOXI3M1R0LythUSsrT3hmbHcrT2p2LzRIK3ovcDEvZgovK1oxdW5mSDNQL2hwNjhmOUZxZm5ILzIxZFA3OTdMemYzM1Z5Yko3dzdQMHdhRDFSSHoyNWd2aE1iWU92eG4rQUd6TFBpbXpIOU9rCi9VWG40RjRUeGxjOC9lcHUvZk55djVzOVA3Y1UvT1BvenRjSFQ3NzgvWThQUHkvMEVNYmx5VC9ONy8rY0hmVC8vZG1YUDdULytZVTgKL2YxUGhQYlB2VHRBMEovTm4zNlBRL0pQODZQNWV3LzU5T2Y5TjUrYXVwdWFQN1NQRXZIVDc1OGUzbXQrK2NkSHYvdnN2d2ZZaXNFZgovazFZcU1qZW5lVDAvejVSOVBtelB6LzYwbjM2OHNlSGY3UEZEejUvK0Q4V21meUhmQUpUOTJYeTJaLy8vUEJ6ZWZpWFYxODVQRDkrCjllWDk5cy9mL3B0RzBuY1k4RDNiMTY0VktMVC9qZS9BVDZFRDR1NVhMN0JRcVFpbWY3ZC9lRUtzUGl5SGYxSG12ODNQclFmZkhmNzgKMmVIWnZiLzk1Mkd6K2NrZjlzM3A5Mzh2bnQ5NStmMkRad2Y3encvUGpqdi8rZm8vUDMzeGF1L08vMi92eTdmVFozSUZuNEIzQ1BzTwp0dG1Yc0dNZ1FCSUlFQ0FKTzRFRXdrNzM5UHh4bjMycXlydnhDbngzenAwejV6djlhNEtOVktXU1ZKSktLdVdDdmRhUUltWS9QT3NYCmg3aTdrd3Qyc3k5azRmZDltUC81RGZzVDMzL1dCWm4vZHVHQWdLbFJKTktjYlRsODBiZjlYelg3VW5OVnlZSnpWcVZvd3hDYTRuMncKK3FlZHIrRk9kOFo3YWtLcGNIU2NTYlJPcG16cjZYUytuSnFJc2p3Nk1BdlJQUmdaVUc5QWNsN3lKNE8xMko5WkY4UW9tUzVnNUdjbQpnRmdnT1VxU0JjQWRMbzg3dDQwTnhHc2xwQ3gvWVptRm9EZ252VHllRVpYQVhQaDBlcXFWc3NNbkhIRk0wcjFMakVqSGQ5V1h4Wkt0ClB1RzBESkxVUUlUa0NKK2JzVG5wc08yYytXVzR1U3E2YXo2UzQxUWdBTDB0MURCdnhSbmswQXdRcWo4Ym1KclptVjhzaThkSVl0cHUKWmlOOTRsMjhCcS9sZFVjQTIxUXFlajJUbU5TU3hGYnphdDVnemJicU16ZlFNS2xZSVZmcnJhUkdpOTdrdlZmcVJiNkIwQlFKakNnRgo2NWVjYzNvbG5hL3JCRmtJOVFsM3FqVHlHcXpjdk1Dc3B0OWtzUkNLNU1MZWx3NVNPRDY4M1BFZ3BBWC9hT2ZLL1o1bWY3bjFwclBOCnRwWmRDd0JSZGJNQWRrWFA5cGtnYmQ3SVI3YjV2YlNEbjMzWmNtRjNiVWxwUzJmaDIxNE9nOUZ1bDVRV0xIYTZaUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJUm9VREJOV3ZWb0RNTEI2N1VNR1BDcFBnOGozYnRrNlB3dmRzMldicll4MzlYWHVUU0tOeEd3SEF3ajNmUG1ISjNNcXgreUdUSmR6QgowKzM5cG12TXB3bllTM2pLR3NjbTU2TGpjZi9PN1RTaXA0Q1RIYWZJQWd4di9uYnhQRHB5SnlySGI2Q3hwK1pRRGordlA3SnZvNmM4Ci9UU1dIV1dTNWJ3UHZETHFBQzFRcytYdy9ubVlmVHUzZ3R4VDlETFFZK0NMdjh4aEdyZFJxOFdYVDM4dm1YN0pieUxONzRVRG53emEKMllETmFDbENuczdqcFh3dEF6K2xzS2NTL29qTkovRTA3bkhrMCt4M0tlNFhCaXYzSnZvVy9wbURxakNQZm9qK0RML1ZpQVo4K2tqOQpta0dRaDkvbEtHRFpwSmVNaEx5RkpqSHM3NHJ3bFNSNkdmNVpNRmpaNGVYZ1M4OGNIQW9MeENjRWtXRUhuMkova1VDdndORzhvaUd4CjA4MmlnUmlzYUpyVWhPR2dJcS9sZWd0K2wwREFPQ3dJaEpoRXpKREZTTkdmTEx3M0dndjdhL1NiQkh5T3BwSG1TSWxlUjhPanFMaFoKSkJvc0NkNFFQVmtzU2RIU2dkVVhMcFRFMGw2eEVLSmxvTEZRdjRIRTRtQ2phU0E2Q2NueGlHYkYvWW1Bc1poTEVtUElTTTRscGI0awoxSkRSSnhZaWhWVDRKOFVXUVBQTE1ZWXNXOENYYSt5c09GYVJKQlo2QURqNWtsaVAxRnlSNUREa2VPVG1ERjkra1NLcVNGSlpBajVTCkZCTk5FOUVrTGdTUkZvNG16MkttZUZxRUZMM01TUjNnWkc2MUJLdWE0cmdXdlE0cGtaVVFsUVE3d2xkV2VWQk1paDdRc28vQTZpZTEKTXI4Z2tpTXFJc2cwajBrcFFEUTFWalQxc1NHMUpLd01VZG9TamJFWmp1TE9GL1NKSWorY0JobzgvS2N2TlAxYzJWYW51aUV6OW5rTApXUHJmQkgvRGlHVTNZSzljMU1oUnZSY25qUzRmMk1YZ3ZLTE1idSsxQU11bHNNcThtOXVML005Z21DbE9WM3NidFpYeHpJblE2VlhlCm5lR2JIZTUzNU00QVgwem8wS0NCRmhaZVo1b3kvVjRyems5dWp4TjRXNWc1MDdFN1l2bmx1ZGt2Vkt2N0hIOUN1ZUU4Mjl3VVhqSnYKZzhNRVdMRHJ6Qjh1eE9KR3ZrUDhHVnNQazk0UnVSVS85WnVjSDhBSjdleUtVMC9Mbnd0N0NDL1BiOFJ6azBWaDdpcVdPZHNLV2twUAo1eGhIR05vSys0eSs4RnczdmhFQlhGUG8yOGJXNVBhYk1zOHVBSFNENEdmZXJiL2UvTXpDY1FGTENWanJvZjR0em9rRzF3UmFTamM2Ckp4cGNFOXJxWXpuVUM2ZEd1Y3dDMzNldzRqeVU2TnAzS05OcjBMYXVhUHVvKzVSRFppeEhKdzdVLzF1ZUJYS2tHWCtxL0ZtbzVzSjIKZ01BNXlUVXlINjVjdy9wMVF1WXdWQlVSQ1RyeGZSSEU5cWx3MVZlby9FYkdITm1BWndFSlI1TS91eWxIT3V0YUsvdlNyZ0oyQjlKSgpNU2MzRURtbmdxSm5LaHgyc1FKUXlxM0RpdzlrL1J1c25QMS9PZEQ1UzZHMHNzNkJlRFdTTUtneEJaODhwOUxPTkluRjNJbmdzeEJzClRjWkpTZG9wRFZQS3ZxMHpidkRyeFI2Zk50TXZSS1p0ak5HZWFzczFCOFJhQlZXY2ZxSy9NdWVYbjhZNEdQQnd5S3orbHc5TTF3ZGsKUDdlcXU0RWo4dm9kWkFVa0RoMkRRVzVGUEJxNUJ5eXpZL0haM3hxRHkvUWs4SkhET1RKWi9QU3hVQ0xrNE10bEpvdWJNNUJLd2hyNwppMUtjNWJINFA2S1JhZTBwMTNqTmdOMmk5L2RNRC9UY3MyWWJ6MjhkNkdzekQ5NS9BelNOdHpZc3NqcFBYckhhenJjdUhWL21CeEZtCldpcEZ1TytOMldCbFdaTE1IQTdMZGpCZWYwOGpCQWtzblJoQjd5NlBmY2Z5RlI3c2wxMnVuQXVlY3hqdWFSK05nalg0R0dSamlhcVgKZmRBSzduMC9XZVNMRlQyWmcrbXBUTHFjbmlCUVYrL0F2L0hNTm1CM2FwTGswR2xjd3BrR01zbkpZSk41YjdodDhhWDc3UWRzZnJGZgp4T2M4N1h3UndDaDdDMDhIMTRqaXNVdU9NUlpUMUp1cy9BcUFhWk5lSXB5MW9SMFF4bUhVNURmQUJSMlZwWmMzRUNpOXdCWGNmdWQvCmpqOWhHRlh3ZmpTeHArSStMNEtvd2N2bmdXMFl3YzdOU0c4QW1DL1ZOWG9samtlTndPWW5uYjNYVTdiYXcyZlVNajVXbjJlRjJWL00Kd3pDZnd3VDg5RFJXeUpmTjFHYmszUnBUUGlvUVFFWFAzaDlEOGZuSU5xZnBWSDcxNTlhK0pnNkF2bTJRMldHd1VoaWYyOUd2NG5CZwovUUNEWHhneis5ekF3ZTVZUzVidmdOWU5XNnlBRXJFSzNITVd4WW0vL3lPMFlaREcva0MrTzcxZjF4YkFVb3E4MTNkdndyMmJlak9TCkRCVG54Y0hMWkFoc2t3UlVPTi9PNHRTTmZXYURqbGdEcUwvM0tHVUwwT2dENWt3eTNiWVZLbjgvSDdsUXArdkxObHl2aTJ5ejVRYWUKUmNsYStvcmtWdmpzd0RkVnFBM2wwVitvZk5SYzBOaG9vbGVBZGs2K1NRMCsyckpaM3NpaDJkWXJmQU42NWRaUmk2Znc1SEE2a0hIRAp5ajZ5SkJiV0ZlQ0ptQ254YlhsYlNpQU5nazIwZVN5NlhlRnYvdllHMTJvM3pBMHlIY3ZweEdLdWdTVmVHTU9uR3RrRW5CeHErYnlDClIzWWpWdmtvSldrUTdQNktJclQxMysvditJKzlVUWNtblNkTEZucGxsOVRVQk8rRjNBWnI0bXY3OGFuMFVzY1ZlWjRtWGtTdkpPWUQKNXdyRjBlTFBpOFJQMGJQdDQwQXpodkRzVzRqOEt2MmRYSGI0M2krallTNjR5SHdFZTBsOVNSa3k2WEMzbEgvT2Q5SWkzcUJQTHc3RwpEMkEyNzV0Z2tUTjdublZJZzhKOGdMenZPNE1WSFlCSXJJRVB5R2MxSEg0azkrVmtZVjBMY1VZd3ZZZ0RzN0h3L1RiYTVuOU1saEJnCjdPQkxkcE9xYktWNENLNExaTHFYN1hRWHEzLzc4ZXhMdkZqTkpISTd2dVZOanl6cHlCeThzVFBVeVpsczVHdjJYUGlPamZ6Ri92eGsKRTlFejludXd0OEMrUCtobHQ4c1hGNkNZa0ZsWWN3bjkrY2tOSGd3cVhlRnhTZW94SEpCaWtOZ3FXMnhsSTdFbU1odUhoZS9HRWV6SQpsS3FnUjFzMmsvbnMxNExNWnhiTnN1VVJyMlJqL2xWVytwV3M2emZUYVZYR1pMSnc0bzBHYUdLektSTi9ueTh5MGQxaGlPS1NsMWlBClErZENhd1c0NkhXcGRhYVVtU2VFa2l5dDYzL3VWS1JVQnZ2THZwL29zUXNWQUlxeWVJUmgrZ2Jnamw5YnB2UGRPdk5ncDhKUDU0S3YKT2ZObTRzKy9LNTV4RHY1cGhVM2tKazhmdmJEaXVzOUM3elgzQjNZL0FmbnRhLzl5UGhneHBKNEgrZVFvdjV3TDVjSHhXUEJNeUdMUwphYkcyQVMvMjlybS9sMVRva2w4YUpyQjlyZnJRVWtyZ0RxRG5nbFpncXJYOGhlL1dBVGg3MlBjZlR3SXJ4NjlSeVVvYXE1bURlWEFxCmZHOFBQZ21HallGZGMrR0VaenRkTXYrZERuRGlRL3N2MERpSXdFQXNaV0tSbHU3dkQwYUVWc3RDS1dXZEF4TWpGcVppc05OTy84aUMKVFpDT3l1d2RPcGVmVUVkMEMvUGtBTG9LWnpmbkFES25QQUdYd3hrTkhSTHZ3Q29xL1daZjhGd0F1Tm5wVlNhWjJwbjVzc2lZUWVEVAp6TStqSW5iMDlNT3BkckNZRFhtckRhZ284RXNzNkNVMDBBRkp0Q1QzSkJOWjJ4U25vUTNBN1BVNUpZaGx6MGJlNmlSWWc5NXJkcHY5CmRraGpBWlN2UnVWQU9JRDFoQzNpZFhjQTdLUXRtMUdUcEFyWW5sb1hPY1puZysvWUNRaHhhNVBGaURUWkFFdzF3b3JUM2lGVXlKUjMKZStabHp4WWFkR0dLa1VxOXpCb2RITkxXaGZ2eHFmL0VvdzdZZGI1eTYwakdnbHdKK2lBekRBOFhJcTR6MUJmTnVQYzdlV0JueWc5QgoxTXRPTExkZTcwWWlCNTdqTWQ2MlBTbE9zS1NkYjhIVEVNUFVnK3g2UEllbkVtWjRXSU5sbTl2YXFlQjUyYzhZUzJsMVprZk4zMThRCkZsdHhhZ3AvQVUvR2VDQ0wwV1paYkd6c3k4MGFjcFFUMzM4MkczRGJmOE9jTFNSaEFkU0J4aTc2MEdJRExBbzJSZUs5Nkg2eHV3RUIKQjE2bDkxSjFJSVpWQzhCTStxUXdHNndzN3ZkTWNrMDYrVGE0R05pYnZOeEJFZDdubjR1eEVkcFEzS2xqUDhZcFI2QXQ0WlFlSFExbgpEM29vei80ZmN6eEpHN1RNUytSdzdROERIUmxlWnlMZFJURWJMUjFQOE9qYlN6cWV2SjA4M3Y0N0p1WngyeCtZYzlQSng1emEveUVyCkV1cms5SFF1MUpibmJIU3lXL0MyQktSdys0MXhHZGg2V3l6eGZaNGZ4S3AzNnlyNGViOWdENFlSMHhpczRUMGVld1AyOWh0SlpoYUEKeWQvT3JaazYvNGFSMDR2b0FQMkFPbUNmZHdMWUk4bDY5czJUQWV1eWNHMzRXQkJ6RnFkbjB6QWI5ZnBNMENBTWk5Z0xiRWViZVM2NAptczNDbmZaWEp4cEo1OHY1NWNmTUJEMHNVeWJaQ0F3SzFXclN4QjRXaTM4RzdERnliQ3RtRWw5dFlIWkdHbTZNOE95blFNdjNWMkRQCi9kNWxtK3ZRdTBBSmo3dVpvN05yS2xTZkFvRHR6Ym1kbEVKbFR1MWYrNUhXOEx3eFdNR2IrY2ZDSWhRMkpUM256NTl3YXU4cUFpL0kKdFNlVDVKVG1SbFkvc2FxSjBVbTBIanZTVHNXcnpmMllpWmdLS0hjQURPUXJIM21iYlpQQUd0OVpCbDR1dUJtZnphYXRPREYydmViVwpYcnhWNnZhN0c3QXVweHdYemFOZWVSNU16dVRvNjd5RTJSWjI1QnQ1TjU1V0VDMEVmN0V4ZUxNMHRScmZmdTg3V1BpMkk3dVpMSTZzCmJoTkFIQkIvYUEvazVWZ0l3SGFBOFRvNEF3TDJyRUN0TmM3Y1U0ckgzck90ZHFURjBTNjJ5dnpXd016LzNnVWhTMGpsMFR2WW9uYlkKTVlzbG4zZThtQ2dpVnM2ZWJCVmNQLzVwMHRPcjVySlJUd1hDcy8yQXVTQlpaUTBpT2NvemkwTmJlRVZnVE9XbTJaZHFHUjZYTG5xUQpEb1JnU0EwVDJCem1ING54Ky9ZWGVLLys0cStWTE1hMlA4VkJkOWtHQ3NmYmszaDlGRzYvZlB6U0dxWkdmc3JDSnAybnhMWTREVHRECnViclQrUlBaVkJwdTZJbUxvOUVOc08vWFNUdGdaMHUvNk8xRkY3bmdlOERMVy8yZmdXZVJiUldPcnZDK09rNC9BdC9ZQVp5ckpDN0UKeDBKeFBRSjVtY1JYajRXdm41Nlp4MmdzSE9UV2d6M25UdzVFb0pGZlptYmVRbVdkZnhkdCtSalIrRFNUam1vdUN0Ymx0ZS9aOHVZdgppSU9IV2Mzd0EvM1BVSEhTS29ZNHpTakEzSWVHUTNtR0F0Wk1oS1FmUXpFVjZDTUhzSmt3NWhJdmprZS9udXdtYlh3bFI0NHZBZ3JEClorSEorSTF4dzJOZ0R3ZUp5a3U1R1k1MzJ4TXdsemxKbTRpQTFXaHQ4WVF0d09vRE04OEpFSHp5WS9YaHVQbExVMnBSS0RaMEYrdnUKR0pBNnR3ZklVT3RZbktiS0FGVGJ0clBFMnNVUFMyenhEbnhrTUxJeWpNdjdCdG5XY25xQ1kveXZGSnVDSjh4N0s2Q3J3elJrK1RrKwpLdXYxR1NXNGJ3OFB2QWFlT3F2WlpMS1NOVitqTHAwUURGTUxYd3ZrRUYyQlU5aitlME5kRGl2K3NXUnlzdlpyNTZXU09Sbk1UUDArCmowcXdpQi9RSkQvZVVhWDhQL09qSWh5Q2dvTXlUQ3ViS1lDRExyNVkveWdWbUdpNTNFY3lBWjhaT0hXTEUzblkvbVVQcDM5dkQ2dWMKU3ZFajgwUFlneWZQWmEvVE54VEpaN015djJzZGZ2N2dkU01LNmVjc1VjZUxlWVZmZWlFL0RlYW1lNjJ2OG1lcE5JVG1mTUVickJJOQpHRm9BTW1vZFJKTXJlM0MwbG9DQkhzYUgrY05wT1grZ0t4a2Z3TkpBSGpvKy9IczUzendjeC8rQ1FqYmVQUENGRWZMTHcvZ0l2K1p5ClpKbjdRSHdQN1NNQ0NmNFZBdnZQOXZ5d0E5ejlBS1JzVHJFcVFrMkJXOERlNUQ4Q1JKNEhnSXo5NlFhTS8rRzBoU0NtODRjZlZFNDkKZmxpUC93T3ZLUm52ZG9CdEtRaytucWRMT0x6S3BvQ3E4RGd3RkxZTklORVpqRzc3emFIL09UNmNOeXZZTk5pbnJHSVlzUUdncDRlZgpuWEk1QUVON0VvajQrM3dDTDJCVFgxYXFLOFlQVTE2dDlDcGJlcTQrQktTb2N2d1NJRm1OMERvQWFySlhpMGkvR0VRMG9JdVF0WEpmCmphdFpWVUQvZGhwdlpyQnppVUxsQmdPMnZ0MXNwNmdMakx3T1ZzSkY3UURnTVdCY1doSENuVU9ERGhUbzRPejBzSjJNVDdYeGYrWU0KZ1lPYVJzMVRaOVVmNXJvcmdwRFpOVmd0eUUyMkFvdHhzNVB0dnpUc0dJZ0Y1QlNvUHBYTjF5UGE1SVdpZEg2N21hSGl5OG9NVVB6bgorNGVwTWRDdzA4ZzNkRkhlb29VRUUzTkhXQWZCdUNYU1gvekNxZ0wyaWoycXFFQ3lLNHpZVU5IUUlVWjE0VGtTY05NSUtoSU9zcWs4CnA4a1ZUWXAzM2ZmNXJieWlMc1pBR1lQZGhMNTNraE5kamVoNHYzN1dla2tCODF1NlhmcC91Qi9xRXlSdEtwRm1SQT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJV0RBbU50RVVyUm5xNWdXNEN0eTlPakkvVUxwTVVrbEdSRVlaeDF1S2xoeEVNejdOVzh2ejMyUXovbGxyTU0xb3dXbnhMZ3BUMzhxQQpLWUtJME9KVk94TWh0Zm1BdCtlOGE3TVVkNkMzOHdTdTZIWnpha0lPMG1iRlNzbWlWR0VvMzlJRDBFWDNjMmsxemJsU1JPV3BJeTRUCnpWM24zc3ZUa0hwRS9XSUQxcklSaXJTYVdEL3BrMFBXa0FjK0szaUIwczE1MXAwVVZhL0J1NitnNFl2dWh0Nk54ZTRhZmNNV3hSb24KbHZFU2wwNXVndTFOSit5Z0JzZEpkVmFEdHhReHp3eG8vUHh2Skl2RzNLblFLT0pPZHlaK3pPK3VlOTNwNVNrQVB4SEJaQ01lWUI4MAoyRS9vUVNLUWJwMXloZTlZYVZVMk54L0g4T3dxeFQ0bDNJL044TkxvREpRZmpWNi92V213R3QycFZkTG9mTzdIako3bEQzZzArdllaCjNlZjRtOUZUN3hhTVhxeE9ZUDdIbmdPaER4bnp6a2J3U0J6cllIQ0ZWVEQ5TWtvRmN0RkFOTndQLy9WUjRnWUtpSEJQc2ZKd25qZFkKRDRmVTR5VHIyVDAvWmFxeFl5cGFUcjc3eUcwLzJDa2VQdnRZb1UvMld1Umo5bkdLdTdLUkRZMGxZR200ODE1WEUrQ3JoZVdtUzAzSQpGNmpGTElCaUZ5L1Zqb2RENHRnQ1NEd1Z6Qjk4bzZiQmpld1lKVThkWXJCZDJiQ1pEVWVZWHppd2h5L3NtQVN3bzJkM3FtUzBvWW1qCmRTbXNmUDVqdEJTTTdoTy80TS9TR3Z5NlZ4QWkvVHg4MVQ4YjBraExrVUVvWGhuNEpKRU9MTTgxZzFXRWxrTWEvcW1Xck5KSWswYkgKNFloYkQ5SklYL0hQb0ltSXV6aWtCaXVIOW1qMzFMMHlTRU5MeDlqZUswb2pEVG8vM1VsaUlUMVRFemtJR3F6bTltNWRrNW9yUnVhcQpHUm1rWWJObGMzQSt5aUR0RFREeSsvbU5RNHFLTEZtMEpXUFNoajhOVzVKSVMyV2lKVXRlb3A5cWpSQlN3SXVUb25CTjN3RW5mNTVUCk5ZaldlYm1xamw3Z1k0MDdBZExnOW9LVmFsaU9SdnBxdDR1UWhrSi93eDJIbE9Oa0N1M3c4TFhjdEdTUVpzYmhDR25CSlpFTzBxT20KSE5LeXdXb0pPQktmMG5OTkdyK081dVc4S1kyMGtYZW05cGEvbWhSU2QySWRUM0ZJd2JvSVdjbVY3bWRlcEpFR2V6Mk1qR0hQa2toTgo1Q0ppYWY0UkwxSklEVmFNL1BvaVplWWFObHRYbTNwZUR1a1lLM2xHSFdta0pTeHJuenNpUFlUVVlCVVQrR1QycEdta1BhOURST0QwCmMvQ1JKbS94YzBVS2tQYVRXQzNpeFNGU2x3aXB3WG8wbGVmYmNIUHNKUURheUU3TXY3V1AvbGdHYWRnY1djM0lnUnpTQWxaM2ZjVVEKVXNoam9ybFc5dkhNNytHNUtZbjBMV0VQeUNLdHp0OENtQlJTcVBtREgxN3NiZWcwU2MzMWFLcVc1ODhmZmFkREVtbkh2bG5JSW4xYgpOa1lUaE5SZ3ZaenJSd25yVkhkSmFhUzFnTFZOWnBLUDBraDNUeVlwcEVBblE3U2RZY2wwa2lId3h3djJucTRXcEpIV1U4WGhvUEgxCkpZbjA2MlZWUVVqaC9uSTUxOTllYUViS0lQMk1ZbC9IdFZjYTZmUHY3dThsRmcySWtNSlVBb2gyV1BGdVpBbDhzTDY1alRKSWUyMnMKK1BQM0pJazArdXcxR1ROZlhxREhBTnI0WGl3MDUyRmtTQ09kQkp3aW9YSDJhMk1YUWtyWVU0NnljS1kxYk9TS1p5RlNENGNVWUlGbwpBZGpmUGFQMEh3OWlwTWV0N1pGR2VrcTdSVE0xZm80L25CVFNYQSt2Q0JXaDUzQnNwNHdBQzBEcnU5UktGUythSzBDYVAxMm93cklwClRDRk40MVd2U0JGNmRzRm5hcWNKV09MNUtrSUtzZEJvTFlmRGVMS0JTREVSMHNNaE85OHkvUHRrRkNFOWhuN2o5RTZUampkOEl2S2EKdHZOUnkwRGJEL1B4TUN3Y1ZMbHRHMnpqc2s5N0RmeXZJL2QwaVpWSDFqUDM5RUx6QTlWYnNNbjhHcXlCeloxbnh2VTdqNGllaHFQNApzRVUvUGE2aUYxSVozaXhOWGFubmxGSjhyY1EvWlo5R0NWZHpKUDkwT1I3WVdZcGRQczhTdHY1VTltbk52VWtUOGs4bkw5OEo3cW1JClltSHppMms2S2N2OE9scTJsWlB0SS9YMDI3NlBpWDdiZHY4d3h1azNib3BmVUt3OWVYcmJTRDJudEZ6QnZUcklQbjIzVHZ4RythZWYKaGZnalF6R0o1eVBySUdLUmZmcDdldDJWWlordU9rU3V3VDI5b05qZmlrd041SDROaHRSSWhHU2ZQaEhCVkZlZVl0YnBadkpXay91MQp6V2lyZkxwa254YXo5Y2xjOXVrVGtUYmg4aFRMR2dtTE15N3pORlRHaW84dVpzNXhSMEwwMU4xcUhOUDAwN3d2S1piS2NtdFVjbVc1CjU4RmowTk1VZW1CNWJHYi95TlA2WjJSZHc2YzcyaDBsaHlGSzllUzJ4MmZxazBDUEVTY0w5RER6UnU5VHJBYzh6TjhXL01jSHZ5T04KbmtJekQvOTVSLzRiNjcxUk9vTEdOMjdtR00xM01CSDJ4MWN2cmMrQm55T3d4MUxtZ0IzODhPa1B5UWIwZEhnUzRhOUhOM2JneDNiUApRTFdhYkFEZmQ1TEZaL2IvUEU2Y1FEdVppb2Z6eU9jVnFOdUR5V0RsMENKUFJ3WnAyQXo5bkE5cHBNRmVYeFlwMkVSK2NaRTl4cDhyCjhuUmtrY0l0YnlxSGRNWkhHbndEUGpJUGJmUTU5OFpET3JQWnpCeFNaUDJ6U0FNaThrTHJuNTFwYVMxQTZ1d2g3NVdQVmtEZ1IwSVcKS2JMK1paQUNmeEJZL3dNT0taaUxZSzVmc2tnQmdZOUJlYVRRK3BkRmFyQkMrMzhwUGRlazBhZUV0R2FYUllwc0NnNHBsSDBCV21oVAp0QVNyT284eDZORW5laUdjK2Y3c1Q4dDdnL1BmaGkvN01tK0d6ZnRCc2Z1aStsNW9TZk1kclMxeVlNNmZXVnBiWG9qdXlQRUhxZFBrCkJXaFM1UGxBS3hmYlcwWWs4VEMxMGNQOWs5bzVaaTNhV1ljNmlmTDNVenRuY3NkQ2RDQVFxVmpaOG90R2tZcVZQZ3BBY1kyTEVIT0EKVTAwMCtsVFJTdi9qcVc5cEJNZ0VaaEN3dGlVWUQ1amM0NDU2U1JSOUFtb3Y1MS9PQzFiMm55YmZZcVpqWmkvc3l3V0lwY1NmN3VncApUY2VVd0pEYnIrQUxHelJvenk2R09wVGRUcXRqM2d4ZWJVSUNzaEUzTUdEc0tXUzFvbjhnUTc0THZTU3BRYTFpRmRHZytFTWFudTJBCmRlc2V3cDdHZUhFMFVUZ1FrUnhveTY5enJxcEdkUGdQUFhqS21aZVluOTBvT3orRGxac2gra2QyQlpuMWV6T3ByNStablorTDVqR3AKR1VManRhMUFMTzNydDBYOFNYa1dHb21sQUF4MzVYNUpXVkFHTGV6T0VDdmgxY1ZaSEY4SmRtU0tzMHFmZS8yVWw2UTdNRzc2TkNmZgpUSGtpMTQ4OUtkUGRJRThzb2VweFhxcWVRVkdvZWdLeXFzZWd4cnJGejhxQlQwQjJ5QUlDMmlqVkkwMjdBYnlLaGlHd3pIZzhSUS8xCkQwMDdmQ05OdTU3WEtLdTI1YVFTeGVNa3A5WXo2WjhhZnhkRGt3dWtPNjI2R3FsTFZSdDltaUE1a0lKYk5DditMc2FiMWZ6Vlo2TlgKLzBLTkZnR1d6bGJYaEtRMERPQWQ0TTUxZWJSbHhaRFA1eU9uRFF5dVc1QlpKczhPSDF2c1pUUUdLczUvSldFdytWMTZ1WFUvTXB6RAo0MlFVMUpFR2htc0ZKZ1VLMFoxM3l1TzZsTHN4cVZYdWxLVU83SlZqVS9lc3VKWm0zTlBHUGZDZkR6ZnZrT0tDTFlCbWRCU3JVc3NKCktNWmZVUGdQV0ZBdUVIM0pHMkIrckJhODVJMlhCanNrM3JqUVhFNGx5WkdsU3BPajNDUXoyUHpVOWw5WVlaZEx3bmw4ZGZmbGtzeEsKYWxhWVZ0V3ppaDROVnRtTlNZUE55TDBNckptUGsreTJaTERxV2Q4U3BFbFp2L1VrSmZ1emtsQlBTeENydnVVMlhvVWhuZEpQc252bApTNU1lanhhVERneEozcUJqbHM1ZzFiYUN3TXRYTkN6VWJIN0JDbTZzaW9hRmp2VXJ2ZjV4b0NoT3ZnSFkyMGJEdU9CVloxcUFDVGNVCnZlTmlUbmhwWUQxbEowYlBKUGxXM2MwVUd4N3VTREdoUnRNNXJwMHdEak9LSEM0YzExUHFlS1YxTERoL0FlTXBTem1EY2dhdDVBWk4KNUxwTG80b2U0eG5ZMGxKNVNwdnVKcFc1N3Q2aXoxR216bU12VnJJTWoweHFIRzJnSjY2Zk9qMlRUYXZ6d2RxV1l1cWtqdXkyckJwRwprRFlNeXlLbElDa3Y2c3VVT2lxN2VLS0IwSng4T1JRVkxhQnBJQ0xiOGpxYXFJZzlieUNVait5VzJhSVdaUmk2L3REaGsxT0hrc0lrCkl6YTNoL2c2VG55OGdEYjRWSUU4WDlTQlFDYW9BU3hCbzRJTkk2aytaQVNrb214MkdLeDZCbVcrVWdFSXRTVVV1YStUVlhsYjFxb0EKS3B3QzBPcnZ5OC9Qcm9Ia0JtMUVGOWdLNnZFTXNTWFB4ZnArSy9CUTcvMGVURlU0NGNXdlk0blRESUpjT0VuSFI4WW5CN3kvREdqbApUL3JFU29sWTJrVmMxdTFCWGhJZ2xrNFJGeENMRlhIMGk0QWx0dklMQmZ3SnprVW80cEpldDNwMENYQ3RTVnVFUkNtVzhDUU95WXBICm94U1NGVVZJL3A2RUZyeU1VNndla2dWVDR3a1N2ZnE2d3lSUE1DK2hyalc4d1hwSjRxRThuWVhiOGhYaERjQUhld0pOQ0dXcVhLeVcKOXJVUzdha3ljUitEVlNsSzkvY0VEM2Q3TjhWOUlGblVZMzBpVlNBVHI0SFVDV3ZpWko3ZUZFUWFkZ0pUT25NV205S0FEK1NEaWJSTwoxbUJNUXlwWHhhYTBIdHBSOWhnYWoxVjVQRnJqQzRGME8ySVhjUVRQRjlPMUVWWkZsdkIxOGhKdk9KV25wczduVlc3elkvZVhLNkxSCnU2cDQzNU9ia01HcXdPbUFkNFNiM2pVS0lOMjJoZ3dxYTY2Tk1FT1ZJTDFCdE5YSjJiS0FPcUtOVG0wZjR0dXkxRng0V3gwOHJMTHoKOHpmZ3JNQjNXcGhCVnVwNG5Kd0g0L0hwaTNsZnpybjdKclhiQ1U5Rk5SOUJBbUJ5OFZhcGFDdmxXY2pGV3lFd0hjSW43UzhCb1RGWQpiejZrUUt1bXZPVVpOTU1ST3BMNlJrT2ZpVk53YnBWQUNncnJUWEpRR0oyc0I0NytmWS8xOXlXQUNVNEk5VzJpd3ZOQk83SXVQQTZoCnhabEhhYXAzT1dISW8rUlRnMVZkRERWc054QVk0ZE45eGlkalJNQmNUcGNtVXZMTXovaGVzSXVKTmRweDVielFhTWVWK0FCUGcwYVQKakpEa0FXRXkrMXMxV3B2VGFJejNxc2VDRndOVDEyZ0dqU2RJRU5qMUdvMlZ5bEpuZXdlTkJsWk5TcVBwbG4wQVI3OUd1NGhkVUhCdQoxMmdReXUxbnJ3aU93bW1RSitkZ1QzSDhCcXVVTlNEWWhEcGJKUSthZjNRb2JhTUVQVTFodmlYd2VTNWk0L0M3V3c5Z21mM2wyNzZYClYwTWFMYk04a1BPWGs1UXdVeEY0ZldvV0FPc1lkU2xaZzFWV3pWNlovU0FVNWc3eXBRV2UrRFVHQ2xnMVVWS1RuSVpSaDZQTnRKZUYKZ3VJd0FNN3RLUkFJaW94RExUcDVWNGNqUEhUWEdGNldPRTFBd080UnE2YjJRakEvTjdRdWhMc2grTlo3aTMzUFk5S3hxWG04MmVQcgp2bXVOWnZGaUY3Szc0YnN1KzE0NUJndUIzVzdmZis2bDlrSzl1eGhjTmYwaHJjdGRETUs1eGI3blFXSDN3dXQzTVFSSHdyNlhnc0o2CnJ6Snd0TzZHeW5zaDBqQ2YrNXQzUThGZU9CU2ZFeU1zNE51N3BDTkIvU09aaDBYdmxZTGtLUzROUTlZV0dCNFVsb1JQU28rRzA3ZHUKOTVaWXRTak9ENERkS3QyOGNVbkl0bkt1dFFMRk5KbTd6RXBDTEhJZUVWaExueVk1VnpnOXpRTjZkdndLa1NzTjZYU2lJY2x5Qk1ydApVUlV2OGNhVTkza3Z0cVc4ejYvSnI5U3dNUkc1N2t3MlBVOCtjMDNHM3djakk3U1JVb053VFk3M3k3WUZ3R1RQYnRob2o5YUVlZ0FzCllFbFVhL2VJa0FDS1JmU1pHREk1aUhBbGh6NU5NVmdLbUl5dzl4U1RieW1PTUREeGUwMkQwc2dSRjhKRjc4aVU2SEw3V1NwVTMwaDYKRnZRYW9HcTU0OExvM1RTR1JrOW5VRFI2czRFQnJKc3JTbFhRVVRlMzNGNUR4OS9GTGl2b1JCVkRWOWZRS1ZmUUlaMThoeG82V2FTbwpnazYyV2xCbkRaMXlCUjIvV3ZDV0dqcmxDanFCMVhkRERaMXlCWjJnV3ZDR0dqcmxDanFGYWtGZE5YVEtGWFNvV3ZBT05YVEs3OUcxCjFUZlgwRjBJcnFDQ2p2VXNicXloVTY2Z1EvYVllZzJkSUNGWm9jTHMxVTVLV2R2eU9mRHlsVUNpWkJjTlE1S005QmJVRTdkZDJ1cWwKU0pHUGZIVXliRUZzL1VvRUI3UkdlajhLd3QxZTM5THh6dmdLNG9TTnErbVVjQW5ZVlZncnl1N3hEaTNGWVBQZmVVY3RpQ0k4NDFNQwpwcHlIcFcxK0tOYW5Wam1uZVg2aXlOV2x2R2dudWwvL2tHUXFIMVVpVjBwRGtpcVpnM1BSVlRTblNkY1VSYWtnWEc2UHZnS3FrNjVVCkVDcC9URElaUkgvWVdDNW9qRzRHdXpsZTFmT2FsYWRtMEZqc0pzeUUxQnNZUkp3TTF2eldpREZWN0NaM2JDUDBrZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJMUlyZDVQMVQ1UU1IbnJZc0tpYURDRnhUTlRla0tLcG1FRlFLYXdNbVRNSENMMDlzSnNSZXJmSlJtODRhazdxY1hpU1ZjbTd2SkNDZgpRcW1yeEJUVnZ0VTFWaDJxKy9hQVdGSm4yYXc5ZGhrNlV3c2NycUk3VVpnRS9MWXRtVFI3eFlsVlNkYnNrcTBDNDFsSzRqb3dWYk5MCmN4M2ZXUzBIWGtjZDMwU3Qvc1VzQ0ZySmw2YkpGOEVvbTlLWE9mRDJ4NlZaYmxBWnFSSk4rZlZUellIWG5FVXdLd2tqbUpMcnA3V08KTDNwUXE0bFJZZ1poZGpvRWRyY0swUU4zOGlGWG1hSUhtRHJIYTZlWU1NQjZJOFZVeTBTMVQ1TFRhRmRSVEJqNEpYTGRubGVZNkZRVwpKZFpMVkhKcHMyVXZZcjZYYmhZcjZrM3B1S1Z5dlp3SWhBeUFsVW00STB1QUdCRURIUDR6VXBUdXNnWm5qL1g0Vkp5OVJWbXpzeWNIClFKeWplQVVJdGF0UndEcXp0MnBvSzVXN2FvV0dtUHIrd3BnMDBtSUJTOXpVZ3d3R3haQTByRXFUY2VJdTJGNnBSczZnVXVhczRjZ1QKVFVqNXloUERoWHVsWUVmR2p4ZXAvSTdDU1FQSmVTY2pjcHo4VzlFWDNwRndsU2hMU2FWQTdrTHJ5RmRFblNSMzh5dnNzWXBXaWVmawpYZFllKzYzb0MrL0lsOW1KTTRpdXB0TlNKZEpnRUxrUzhpeWdNeUlqR0pLZ0hoa01pdEFUL2xBWWtsQ1kxWGN4QlRvRnRRNUpPVHRkCnZTaE9hVWppdXp0OG92Z3ZWWkowajRqTUU0ckkzSmlsQml4aGk0YUlESDNHcDFLZVk0bjdiTGRFWkhqKy90UHRFUmtBd0tHUTNhR2oKRE8yYWlNeEZ0ZUR0RVJsWWhpYUt5TWhWcEtyVjV3VjFSV1FrNC94UEdzcHp0Qlhud0JJOUlIRHFuS3d0ZlErMjZzQ0V4bktWTTVibAo4OGExR011QmROdHQxc0FNeWpXSnUrcDlNaG5ndXNRYjl2c0VkY0RVNGc2Vm5GNHRaV2hYSnJEejl4ZFlRQ1lmWGRKUlBuYVJ1aUJaCkxhaFdWNmM3YWZZeVF4WFYxV25NMTFPc3ErT1ZqaXBVQ3FzSFFhdUtsMVR4cEpkbld5cW02cjFlM2tVS3Y5TzQwVEUxNzNLSlNmZXAKaDROWTdwRlRwMXdQcC8vK3NXdnE0YVN5b0YvLzdsMFBkME9kaFk1Nk9LVU0xZnZWdzhHbzlZMFNxS0VlVHVKR1VOa2lydXZyNFFUWgpVTXh2N1BldWh4UGZPMHBWeE4yN0hrNzFsb0M3MU1NSlRxdzBwRnBlVnc4bjlzWGtqblZnSmR2dGxmVndnN3RiVGlRQUpjeUpsTE10CnRlUkVkcmFhY2lMVlpQKzRDdHhxQnVSUmdzVHQxZWdJamtkdDlUWEMwVkpISWd1RnNzY1FuRHRVY2wxa01pamt3S3RyTkZoY0p4OFEKdTh4MzV2V3lrY2w0dHU5ZEZ4blA5cjNLUW9pRVVEYmEwKzNjSW9aYzhSRXZxbkNyR0FKZ2l0ZktTT2t4V1RIczdiU0tvWUkxRHVtdAp6MStVWkxUNzNBYU00T2dUSDVsNlpBRG5Mb1dRQmIrMlhVd1ZqdnlWd0RLM2FjbWxXVjllQ2F4Nkc1b3dLaTI2cmRIcHVZeGh3ZUl6CjVZdWRWQjFxdGlJVk4xMmJJTUticzl6RndsZFZwSTVOUXcxRnBCb3JVc2VtaVphUWdVcXAzMTBxVWovMzk2bEloWER1VVpFSzY4VnUKcjBpRlVPNVJrUXJoYUxzR1d1UVNTK1gxSVFHUnZ6UlZkNUtSMDB1dnZsQU11emVMb2FnVVRscVAzYnNVRHVYeksyYjAzS01VVG5KZAo3bDRLZDMzY1VrZ3haZDlkaDE5NVF5a2MvdzRpVkF6M2o1VENTVVFWL29GU09PbjRtRWIvcktka0dQSlZBZi8rWktYQ3A2VnNycXFXCkcrR0Y5bGplcCtJV2FVMzBncUJDbWlLS0dnTElFSmo4elhZNmJaaUxTNGIxSGk3d3F0RjdHbzl3bEc3bkJhcGNhc3Zqc0tnWE40dnIKNmo1bHI4TVJidzVNZEZSaWUrRGtGM2FOODBqaG85Y0F0YmhNdlN4TDY4NTRXRERQemtVeVpza015RmJxdFpqeG4reEE4NU90ZEtTSAoyb1lYK3NWREpsc090NTd5T2Q4MG44LzVxN0FKd2R1TzJZNnNhK0dRNllpVHNCWkxxdW9NZWtsMGpkS0hmTjFadEJGLzViT1hzTmd0Ck1YMnA4NFBQUEtTaHBjdWFORzdsS3V5Q3ZhNVNzZHZNTDRzVUkxczVwUW83Njh0UGZTeUhkS1NBdE9TTjhaQ0thN0hpN2lNdkNpY3UKZGd0Mmx6VzJNNkdvQk16a1VDcDJ3MzBpcE1KK2ZJay91UXE3c05tOEQ1OC81WXJkUHBTcXp2NlVLK3kyclpZc1VsdHR2cHpKSVowcgo5K05yZE9XUkZwOC9TckxrdFd3Q2lhRWMwb2F3d2c2dEtoQllldGJvRTgzbmNZM3ZKYVRlbzZJS2dqZURuelZORUlQT1YrbzlldXVzCmhTVU0wV2ZHUzBxUjU3VjRRMVdLSFd0SXVSVmFzTzROTlJmQkdkR3JiWHVmMGg3MURGVngxRVMrajlWZXc1QjQ1MklLZzFKTFRsWEwKODZDODEzdDJrcE5xT3lKeHA0cUc2SkpTSnpsZFViaVBndVlVU1pWcVNIUW5wSTY4UHJVbWNvcDVmZHI1U2FXSm5PejhwUHErcVRVYgowVG8vOVY0RG1vbXUxbWRFZEpmYURmM2p0TXRMYVM3ZmlFZzIzVlZyQXpybFNPODExWFRYeFdIMFZ0TkorUUZNTDg3N1ZkTnB2Qi9tCnhtbzZxWmlnV0Y1dXI2YVRxcVc3dHZKUnZwcE9LaFl2bldsL1N6V2RnQ3kwekVyZVAzWlROWjBVS0pVYlFxNm9wcnR5UjlaWlRTZDEKVHNQdWxYZXJwcE9xcGVQNysvZXBwcE9xcGRPWTI2T2ptazRxMXM1MFlMOWZOWjNVNnFKSTcxMnI2YVNNRzM3dTZIMnE2YVJxNldSdQptNytobXU1eVNFdXp2S1YwYlRXZGxIRnFzTjY3bWs1cS9TU3lvVzZzcGhPRFV1MHBmRlUxblp4dGVkOXFPdTBVdTZXYVRnUktmQ1orCnAycTZxeWltdTVwT3NjYnFidFYwMHJYVjk2Nm1rd0lBc055NW1rN3F0RVNVQTMrSGFqb3A5U0QwWHU5UlRhZHlNbktuYWpyMS9lVWUKMVhSU3hPQ3M4WHRWMDZsVmN0Mm5tazZxbGs2Mkg5L3REcUNYY3dBRi9jVjBYZDBrMzhYcnNrbWx1RGVIeHNLbnZZcXdDNGdmM01yMQpzcm0rWDkzRmtFN3dsT2ZlL2Vya3JRdHRkRHE1N2Jyb3hGRkprQWtKYXpKVkRRdU5MQ0FvVUpDcGVwWWJsR2hJV2xXQmh1NXl3b09wCnE0WUVLUVlHcGF2dHN0S1FwQk1wWkRXTUFwMFUyaTdMcUV5NGl3azlvalQrZEJSNVJBRkxiS2ZTMkZ3NU1zZDJ5MUpxZEhkem16dmUKUFZjYVRmSnIydHpKZHBlcmFxcFYwdGptVHE2U1Mxc2huYVlFQ2VYOFpLN1IzVzFyVmVydHRIU1pVWXhTYVdwenB4cFJoSVM1dWMwZApiY01vTjdxN3VjMGRWZnVtMHVoTzIrSFJybnFIZTY0QzZUYXV2SWphNnl5cWQwdFIybFU1ay92cVdoNHd0VWVuVnY2VVBlV0JEZXBVCmN3L1YrQk9XMFVIbldURUNyNm1RVGt0R3MwRzl3bEEraVVOemZTSEFvcEIycUNPSkRGSkhOdlFuNUdSdEhiWUFack5kWEU4RUwwMlYKbmJQVTNWQnk1ejJsMTc4ckM3c0UyVkNBcVZUeXdUVm5Rd0ZRcXZsam1yT2hBREJ0R2QzS2ljMUk5OTJsOHZIMm94RFlVVkRoT25CNgo5VFhDMGRUYlZRb0tMN1ByN1I0U2lLQmNWTEpMVmdxcjE3SWpZSm9LYStWNlFJZ0xhOTgybDRXMWI1djczUW9JZ2QybGtUSGlNVEJhCkxjcU12M2ZKa3JJbFJVclZmcTlLT2RTdXl5TmRXSWwzbVVHdDZJbkw1VkRQajZ1N1ZLYXdOeC9ydHlRdVFkWE85K3BnQ0I2OHloOFIKYTViOXRxNUcxWEtuYjdEeDJzM21CQVZGS2F0VEI1dzczQkpBd2JtMVd6VUZoUkZDcVJzTzllV3F0alVVTXVnNjRYVzZKY1N3bzZHUQpRVk1FL3VZT2QweDlwVnlQdXl2RVVDSzU0dHErMWZvNjNDbFZQdDRnaGd5ajBSM3U3dElwVDdXZVNGdW52RnZyaWRoT2ViZUxvVUtICk8yRmRrcGI2a0dzNjNDbjFlNFU5N3ZSM3VOTjZxem1zZnJxOXNQWnp6NWs1Y3Q2cjVzSmFBRXpkekRGb01YU28zblRYRmRhS0t4OUQKdDhhUFlIMWhYYkljV3Q4OVZ3ak9GWHJ6NG80SUNPY3U5WngxVEpzdnBncEh2aFpXVk1Sa1VMdG1BclhMMDFQZkxsWEV4RDhWaFFyQwpjeUdHY1lmS1FtaUlhekY5M3pTV01Xa3BZckkvRHNTZUtHOFgwMUxHSkp5a1N1eVVBOFd1aTJ3WlU5eWhxVUpkMFcxbnBUTHUwQ0tWCldvcVk3SThic2ZGOXJWL1oxVlhFSkpkQkJIc25LdXkwK2d6RExsM0RlOE90L0NMRFVPS3l4RzZQNmdGeGp4clh2RS8rVmpIb3YranQKU0tlcjNTTWlwYnc5MXJ2ZjFWUTlkUHAycHhyWG51elZWUHB0bU1sUlY3dEhsVTU1L2l0clhIbnl5YVpoYUtoNlZxOXhCVVBTWFBXcwpWT05LUjREZ1F0UWkwdmdZMHc5V3ZKVWZXNFVWbnMvNW45NEw1dm5UbThGYVNMdmZXby9ia1RzTVBwVmVVWFVmMmYwa1o0UTlaU3BRCkd3OEs3ZkppeC9RblFSSGVjN3JKUnlxb2h6TllqK1pPNzVVZnFoTDJZWXZuUDNveTlYQk8rU0s4dzNrVXg0VTZXVlNHaDdua2F2L0MKWmt1azZmeVNLOEw3bEVVSzVtSWlkd0hadVdJbGM3OHRpOVJlbWZnV2NuM1luQnhTdHBLTEkvQnJpT0FoRlphbUhlMFJHOWRITUNDcQpjblE2MGg5ckthUUdLeVN3dU9lY29BeHZMSzc5NDVPM21ueVZRUm8yVzRQUGhSRVhneFZYeEEwVmtKWXNZWG1rcFlhNUw0VVU5WDJMCmxnV2xsV0trVGFVK2d0V09QTkppc1UwS01yc0FXZ3Q4N21FLzBVV1laOWVqWDdqNk11OEY4cGpzZS96NlNtemtpbWMxUUhUSHQ2Y2kKdDAyQ09mZUNZcU9UUGF5aG96M0N6VE92RUNkbU56cU5hWk9BcUNFbk9nMFNkREZUVDV6VXNEY0QySS9pd2liVkNJbDhTZEpsYXBYcwprQ0FueXc4cXI2VzBTYjJ3Nlhpdnppd29vS3ZTbVVWckpLbWduRm9sdTNRWG5Wa0FnamM5S1doS1ZYZWlteWR2cUVwVHlkQ2txR1RRCnhrK2lReSs5ODJPajFyRHVUbmVYUlpraFhXUnBpZVZGTTlGMVpXa1pyRXFEa284VDZ4c1MwSmJ5ZVZyMGVDNXlZMFhxcXZpWmNna1AKcjR1WFBWT3VjeVVBN0lxR3E2OVZZckNENHIwdWIreDVqZHB1T05SUWphUVlYdFo2eWpNbzNuSVRMVmVUZUhGbDNGWEZidEpIMXJydQp0UjRVcjR3c0MyL1JoRldBdDE1Q0szVlhuR3k5bUpyWGNubFhuSUlESkIwZkV5YU5TQnl4amtsZC9RN2tOUXg1Tng5NVRJbzF6TFduCjNsVEJuWndjb3hNcjlmWjFncEdKNC96cUlUdlVqMDgycWhMY1h5UVFyS0lIL2ZhSVRPOG4rMk5YL25CUVh5SFpSVCtMRzlxeUtWY3kKNmFxeGl1bTY1NEEzSkZIOXk2eWtGRHRXdGNZRlErS2w2dE9uMVR5cDFWa0t1TEpvS09YazMzT2xVQXFvMXRKWVpmMjRrL2RaU2IxUQpSek16aVBvYVMzYVowUUZNcll1T1hWeGRxd0JNdEt2Y1JqSFZXaDd0a3hTZVhONUlNZFYrT3Jvb1ZndCt5Z0M3S0JlV3NnNXBpbDFaCkJhaTFCbER6UFNSeUJXS2FhZ0FWc3RNMVZBRnFyUUc4akNmcnFRTFVXZ1BJditGUWZ4V2cxaHBBRkxXK3VncFF3Q29LSHFZNEQxWmYKRmFEV0drQklzZXVyQURsNkt1c05ZWTJWM2lwQXJUV0FySTk4VlJXZ3pKQXVhZ0Q1NTVYVWVDNW5kWHRUUHUwZDJXNXB5c2VieXovWQpsTzhpcXZDUE5PVlQ2OGgybjZaOFZNMklzb0Z5ZTFNK2cxWENLcng3VTc3TC9zai9SRk0rK2Y3STkyektwNmwvNVMxTitmaFJCVGlvCnNPeWdhQktwbFFiTGQvVzcvVzZvcDN2Y0RhV3hyNSttdTZGdTd1dkhtOW9kN29hUzYrdW5MMC9wMnI1K3lsMzlycm9iU3FLdm4zSlUKU05vVDE5L1hUNXI1Rk8rR3VxS3Zuem9uMzZPdm4zSm1DQnU1dXJHdm4xb2wxNTBDdW9wZC9ReFdYUUZkMmI1K3lsTVR4UzZ1N3VzbgpHTWhGVjc4ck9vQkk5dlZUbnBCVWh1bzFmZjBreXhHVmJqWFhUaGpObGJLU2QwRmYwZGRQK2VZdjlrejh4cjUraWh0ZEh1MWlkK2pyCnB4d1cxblVEbFVKZlAyVlhWeklMK29xK2ZsSmxrcHpvM2RhUDd3NDE3N3I2K2lsRGdYSCtlL1QxVXo1UU1XaUdjMHZodTdnaTlkcSsKZmhLbUpxK3JINzg3QTNaRFh6K1JHR0xDcm42Q083dDBsNmRnYkY4LzFiclh1L1QxVSs3cXgzTHlqWDM5bEJPdWVSV3BOL1gxNCtxMwpwSGhSZE0vVjFYMzlsQW1JTE5nNzlQVlRrTFhqS25DbmZud3VaU2lhKy9HcHRKUFQzSS92cHI1K0xCUko4ZEZielhIUjEwK2g3a0UxCjIzYXV0Nitmc2lVUGJ6eTRSMTgvdVQyOGMzbVNlRjM5bGdaem5qbEpWQk5EdGI1K3l1Zk53aXlDNi92NkNha3Q5Zz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJRnEvdHg2Y3ZTVU8rSDk4ZHhJZnQ2bmQ3UHo0dFJVeHF0emRjNW1yb2E4VW5ya2k5cmErZklMQjkwZFdQcWhpNnZhOGZXeXFsMUZmMAo1cjUreW1hT0RJL3A3dXVuM05YdjVsdWI2TDUrTjhiNk5QYjEwMUQzZW9lK2ZzcGQvWFQzNDd1cUNsZWtMUy83K2wxZkRNL3I2c2ZECmNsTmZ2OHRRTXIrcm45d3RaM3I3K2ltbmQ0bDJzYXY3K2lrbk9vbGlTbGYzOVpOWUYxNVhQK1Y3NGJUMzlicytiaW1rbVA2YUp4bS8KOG9hK2ZwemlrdXJxZDNYMm9LaXZueUpIOERxQTNOYlhUOWt3cEx6WDIvdjZLUmZFMGp2eXpYMzloSk1VZC9XN3NNYzAzMlFsN09zbgpid1JSTm96S1RWWWErL3Bwc21GdTd1dkhYOG5MQXh5RjZsb1orWlR1NjZlOE9TaFdjZDZ0SUpiYTkvMFMyME5meVVaN2FVdG5mSWp2CmxWcFNOeXFLOWtyd3JYeG9Wem54WGxTMktPQW1oc2U0MDV2VTQ0NWZCMC9GcG1oVURzRU82ZHR5aE1IOEwvTXdTODluZ1NkYU84TGEKTitLNE5JSnQ1Y25vL25pMllQN3VLa0s5Qk91cGpKWjZxdUxESEJ1amYvcXhDd1lPeXljeXRmNktOZG91aC9mUGFjL3RjMWg1OFp3MQo3OCs1c1BGelBBdUFUNk9NTlJSTmxHMzFsMzB6dEYvMVBneldTTWdYbkViclpOZFg5UjJNb1ZvcE9NbzFWKzMwN0swZWZsKzI1cytoCmZjY3gvN2E4WjUzQndxK3AxYXl1NHV0a2R6dFBPemI3WVdSdlBXUTI0V2ZqKzNQYWJnazRTbUhyOTBlbDRqd3Z6Ui9CN2VjOFRzcysKcXUxTXRWdHZIYVBQUGNnWWljVys0MDRHN0JtTXpGVnpHUGs5ZmNKS1lWdnpjQmpGSElkajlMMXlOQS9DazJObzh2SEtWbHEyM0k5Kwo3N3N2VUl1Wm1MSzNYLy9oK0xtRnplWmlacXEyK2xLSENPcExFLzNhTUphZE5uYlFvV1piUU1KK2t1Y1JiblZsTTdVbktXSWhZb0RwCm5teHdYUUlXbyt4Y1VVV2pZMnlmdjVvNy9WYktzam40U1JzUlhKek42NWx4Qml0Sm41amlVT1Bac3dzK3czeTErZ2JWSkJxelpLdGwKeFN6ekdmTDNYN2RDazMwbkVoOHd0ZGM4cjJpT2k3ZnlwZ2JVbWhRZFVtRnIvbXl3RnZya3ZJc2FhT2EvU3MxdStEay9NMlg4cCtSVAp4bitjSmNpWWVmVmFmTThFQm9Cc20xUnAzZWwrWnN0aDR3VEE2ZXdac0ZUN1RBZnVYa1ZnS1dOdmtFblVqQWMwcSt6ZkZuSnl0dnIrClBuUVhPOTB5L0FRbS9McjJ3YUpkRCtYV3AwSzlBL0tjTVAvSkFiTVJoaWRLRS90RFBqdnpDWGVnMkRHZ1NHUUQvb3k0VU5VdlVEaVYKSGZqejBZTTBqTmtPZHJHUEEvZ2k3Mk4rU1BySklsR1BBckJsekYzd1dNK2tvMXlwNEI3NzhxODRYZTFqbUQ4VmNhS0J3c0Y5NGE0OApuc2ovalAwNGVQRG81ajBZVy9LUEJpdnpLTy9sSGhHNWZqdk5QS2l3K0twOGZGNUxaY2tRNXRrSlZNWjJoWmRxcGpIN25adDcyV0RGClN3UGZsSDNrNWNFcDdlSVkvTTVQMjBlaFp3eFdHZjNoNVhDTmdIOFNGT3pKd01yQ2JyaXBWeVk3SEZyb0RTOHZCbXNoN0NrSFRMZHEKK0tpWHB1RThoTlBBWUhMWUFaK1dYOUNmTk5ocC93T24xNnBIdXYzMXQxVUFQRzE1MEZQQ0dZN1BHS1F0SDRNRmMxcWlHTEYrc3hZOQpNU2ZnRHF4ajRmdjdJd2Q5TEVjeHcwWDhpQTc1QUloK2l0a2w0QW56eHJWRHhIZ1FjYi81bUhTM0U0ZHdxaDE4emthK1pnNG9kVG5DCjJYOHpJbGFCRk90OUVPekNqd0tXWkhKRURwMGZWY0o1bnEyWXFiOTd1QVVqQ3VWSHlOUHZQb3BFaFg0Rmh4dTVoU2hNWDBMMHAzV2IKb0QrZFB3YTBiVWtVbmVNaC9ZbFloQ0NJRUFWaTJNOUFpSDBmck5mWUVzTjFEYU4rUFR3M2FkZ2paNWZsdGo3Qkc4MG9NZnRGRHhERgora0ZXS2llOHVZemVqWG00MHlSZ21rSXp0L1l0WE5uWDZYZXRVSzBZM3poRndoN201Tm5nZ0kwWGMrQk9Fbk1CNjdreVo4Yno1VWZUCkNOaUlkaENOTm1CTGZJVG9UNFh4RC90ZWdINnY4NWNWaitZbDMvb2lDMnZUTk50c2Zkb04xdUxFbTNtSG0zVVM1YlBSc24vYWhTbFoKRkpvT3drTmdtMEJ2c21ydFVtOHl1eGpVbkNLOUdmOTYyVHFLNzduNlU4NjVQc0JMQ3NMbFhCSHp0UzcxcHJqdHNCMU5IS2kxS0xxaQoxc21lOFFIMVQwK2p1M0pUcTVyckRvNllmMlh5K1g5TXI3YUFKZlozd2pDSDcwanJNYUF0VVNJNGlyZUNQNE5PVk9hTUZ6OHo4TSs0Ckd3YzdSd29xUXVnak13di9DWDdUZ1NxbDdFTjJIVXk5OGFGSUJGUkNNTkpROXN2RWxNcVl4T3JEQjFVSHpIM2R3em9MYkROaUZyVHEKb25TSUoyK2RzTjk1Nk8vYU9PVHBLdUNOU0tlY0g2MnlNNEZXcldGWWFGS0ZDMUhGK2Rvd3R3OGpPM254QW5VZlFORGJvcTBGVHYwegpDNy9ER2ZPc0ZxRXBVU0s5NkJYZ3lUWDM0TSthbjRFTmRTa2NEZENsbkxLbU5CK1lDMUNwWHMyc1JGbDRGeWNNZEhSRjNLQVdOYlIrCjlQL1NjWDdFYU5qY0ZQSnpaaVg2RHQ1YTBNQm0xazBCdkg1dzg4MGNCQ0taZnVNQnFIeDZmRUlBeTFSNzZLTHkrcG9uYUdDMkJSZEoKMUk3d096UDRMbnFtckV4Ym4zamltZHFVMlpWOEtiSUFHcGNBemhRQU1CY0tSTmxXNWx1OWdPZmQ4RVlFdEFiQUVIOG1ZSGtyMkpnOApaVGY4NUdPLzg3UGZnWFh4dk8yaGZYQ2dtQjJ3ZlorM2k5azQyd3YyekI0eEp0WWp3VmhYd0NpYldKcWZ3R0FJbHNROW8ra05BMDZJCnVtNGladVI2UjhOZTVFYnFKb29lc2pQcHZ0M3I5alBmQndGYko3MHVPV2ZWemR4dFVmN3ltWDdiWUFadUVpRDFlWkZZWDE1NlFWZjQKTWhRTFJGNVd0TlZMbkhITzRFWE53cUhiWUdKR3c3c0R4TVVqd2NjaE1PRmRRY0tTd0pudnp3YW93ZzRSd2VjVkVBRVYxMUZFR1BDSgpRQ3dhaUFqd1FaOVBBbEhyY2lEeEhBbTRmdUpDSW95VHp4d1JBaDlyUE1wclp2VjFuUGo0U0duRC8wdVdCT0srMVQ2Tys3dkdyYjlJCkVlR1E2MzFvNHdOME5UOWk3TE9SSTRIQmFnd2VQMndzRWJvS2ZBQXZMR1dvK0NuRlNySUF1RHlsM2s2Wkc5VjRFVWFKNWNZQTVVWEwKTklhSEs2ZkJSRWhRT09LMmFTd2xWNE5iQzBvcWxhYngrcm03amFkZmgzdFdXNHBBYUtNRUFERS9LazhEQUhCWkVDY3pJTkw1L1ZZQQpZbXRVSDRPaWRqcVlFQUJFc2Q0ZkJ3SXIxM3RUL3B1OVQ1Wi9lN3lGeDhpdnNqRG04dnAzTTQraDY4QnY0N0g1NlJZUUFNRGFlRE9QCmRUWTM4bGh2Szhkam1rRk1EdW9NMGhmdzJNVTBsamVTOG5WMTVuanNPaEM5b1FaeDdUTFJIbWtRRTNuZHAyME1jeDRwS1lycFhZM2UKVWwzaStXTUFjN2tZeGVyRzFlaHR6aUpTTWhUVFBvMkRpbXhJalVGUW01RHFuVTIzTVhiZmJGYmZrWW5qSndmQ2FPOHMzL2dnSnBOcgo5d0IyUjU3TTkycVVVQm5EVWtZK3dSaDQybEtKRXBQVjhWWnRPZG1jTk94RUN2dlFaSDlXSG9PNnRweWNqZncvcDJhVDRFK2JtWWwwCmxpa2ZFaDdMeFhoaGI4ZUhLd2hXM3pPY2RZMmUvYTVtOU5TN0w1UVJDSDdEUmNxNjBPTUw4MXd6bEU4eFAyV2l5QzVsWXpnRG5qYzUKdHZ4OVVoRVErMk12Uk5XOVFxOTc2SUcraXBlSlZuNGU0WjlzQUs1c1p6ODVLTWR1Zmx4QmE3eE0rYnZ3NE4rRHZHNzZ6N3pQUjduYgpURTR2OUxCWmR6eVE3dXh5ak5zYmRMREJSQ2MvZUJrN3NjRzlxcHYvb09abXc0WlZyeUNpNkJsRTJCQk1sY1AzRmJBa0Zsa0czd3ZPCkVZWU9VWlFlWGR4My9PaG9LZS9oUFJCRVIwc1ZId3dPdVFEdFB0MlVyLzExL0FXOFUycmk2TTlBdW0wRWY3NW1PTmhET216eFNpSnEKdTRDL01NOGh0d0NlMDBBdm9SWUZWdnZMQWNyTDY0c2Z4alk4QU1IZUF2NXNJN0F1S2lUaWYvMElzSkZKdHp0bFRwcmhVemRBNEFORwpTNi9HaFc1SERKWVJvSEc0N3kzNHgwbGJmTEd4dHcxV01sa00vdkxDNjFUd3ZkUnQ4SS9mbVRONDlyUW9Cc2E0eVV0QmxJSkg1U21wClFHUnV1a1FRblUvUlJpeGFJalAyZWF0UW1UMGFhYSs2MThVWlZtbnhBMzdPOVJEc2xYU0VxRGNPc2xNZkF5eW5HTDFna3hjVUV2SFEKNGZWSjIwOEhlU2RkREovVUtrN3c2UU9uNDFHVEFaR0tWUWl3VnBOeGdQazBDMUlSZUErOXRLc21ndWhGUitUZ3p5NFRsRnQ5WU15bgpBY2R0RThLZXJxWG8wYXhtQWQ2RGdURXdwT09TOWIyVm5jdnFMNHk4dGtBdUdvZ201Z1BuZDM0WkpsOXk2Nmc1S2hWcG9TYkUvVU5sCmJIT2htbFBYeHlLZG9vdzd5Q3luQVlhWDhJd0RmQnJqektjWkZ3S2Uwa0drMDIvd1lqU2hVNGQwT1ZPSlNNZHJxcE9qdWpWR0JVTnQKdzJNRWV5cTVRMGoydjhLMExIWXhNM0pTbGVPRCtxT0RMTVYweEFmMVJ3ZWw3dXRUaXcvcWp3NUNpdW1ORCtxUERsS2NyQzgreUk4TwpadjhyWllqaUVmd0IvZU52bnRmenc4dmhaL0d6ZWZBWUVnWi90b0xqN2Mxc1N4N204OWI4ZjUwSzIrbjViNzQ1UGNRZi9ObTNmS1VTCkRSWG0wKzFzL29DU21VS2pDS3MydkRTMzB2ek5QOUlXaEJoUnNEeFgrSTZWVm1WejgzRmMrTVo2S1o1WVVGYktyclUzZXBhL1piQ2gKdXFjK3RLdCtHRDBFK1daMGxJOGUrR2VQMnVVcElra2VyQ0t0NURJWDVvZmN1ZWl1MTk1RnB3UW9HQk1idFVwZ2V5aSs1K2JOalArNApTUHJMMlg2MTBDYzdieG4vQ2RzeUFVRjRuaW5JSHVDZGVrc2NrZ05ENW1Rek9wUFBRYVBYYisvQXcvSUNtSXVsRVBVYlBjNU1Cbjc3ClpIUTNUTTl3ZnMvd1Fkcm96UVptMEdvb0cxMTdNekRMeHZzb1gxWFlDRGN0Y3R4V1J3Nkh6SEsvYnBHYU5WRG54N2huc1VpaFl3TmEKWDBMeFF5Y1pqUGo1MFo4d3BkRkJmL3FkSStQQVNWc0Q5ajFzSVZOMjAzL0dIVjdLa0tHQ3p2Q0dHQnJFZHp0K1lpUzVnbkduajN3OQpydU1va3p2SU5GaGxqeks1QnplYkNkUXg4SUNQK3g4d0UxQmFIbTBvL0hObWdzR3F2SzNmeDB5Z1F0dWFJVjVwSmdCRGh6VVUvamt6CkFSbzZqS0h3ejVrSllDNnNvZkRQbVFrOGVabitjMmFDd2NvWkNtSXpRVGtqaE01Q3JNWGxOZ2RhL2J1K3lETjBwWmEvd0pYcURJcEEKS2I1M2pjN252b1BXbStmNEsxU3BaYUJMMHkyajgyZWRNbm8zalUrb1MyTndYN0NJM1N0cXdSNTdsS29EUXBOMUlJSGpEalhmZHZSTAo0NzJYU2Z3SU9yakVEelpYdzA1NWYwQmJ1bWx0Q1U5WWVOcVMzc3J0aEQxai9FTExEclZsM3VkQnQwOFRYK2RreGYvVFBma293K1BICkUzZWp0QzJneDRwUFVrWG53Tzk2cm9wV0h6NW9BeXlSQTZkYUtUMzJSWXVBU0sraWJCU2dVdUhJSFBBNFk1VmJtemFrMFBuQ09CdUcKNyt5VjRrN0lHM1ZrakNBRE5FcWQ1dU9sdGlQS1dqRzBTVlJhQkNIRm5uMjBSV0xKK0F0UHlTMEc0THhnbFBMa2FleFNtMEFMQWY1eAo4NnA2MkRSVzdpUVNLSE51OTBXTWVGR2d3WjcvaTFxcVVtbHB4VUZJZERqSXBlVlI1NHRlL3ZuaU5Gb1ZuUzhhalNjSEd6ODd2bDZjCkx3WmRKVit3bkdXTzJ4NjNUT3Ntd1VHb3Q4NGRCUkdPV0M4Z09BZ05tNDNXbktYQWdKamFMazVTYzM0ZUFKenNsbkIwNEVzbk5OQmkKRHpnZG1leituMVM3aUl3RHlHZ3B4T2ZNZDUwOTgxM3Y0UDk1MmJpNVJBdkVjZ0p6bnc2dENNT09Xa04rU0lYQkNkSG5udlQxK3E3TQp1MnZNSEVFaU81bytmVE5ZeFllUTZGYjA2NDhnblZLbmJ6QWtwUG44RGI4NVZMZUs3aGdpWkFJOElxQlRZWm9JUVQ5SEJEaWFGZThJCkV0MmtKMGNDSm9TYWpxODJEQkZjb2lOSTc0MUgwWThuN25oZWU5aVZ4d2ZwK090SncxRTBuV0lvZFJoTkZ4WlRWRVRueDFLc3BIQ2EKVFpkRUFnQmc5VFZ5NHdVSTFOUk4yeGlvMUp4TEVLZ2gxUzNUUUFuOGpFanhqclIxVEtNZDkrdEtETGlVU2svczVMcUZwNkZMN1JZQgpvQ21tbFJMUUEvZXFUZVB5YUo5ZkpJTjdkbmxNY2hvYVNRbFRLSEVFNEdncWxYTnV0cFdId1FvVEh2YThONEhiNzZUZkpIOXh0MFRUCkQ1clB4MFA3alR3R0RCVEhiVHhXQy9vNEFMSThwZ2hpa01GdTVUSDcwbkViajJFYnB3eVBhUVpSYzN0VUdZUVBBQT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJVFVMSVk0T0k3NWJWQVA3OG8xOEtBT0F4clNCS05aTzZ1RW9Eb05OWW9jR25XZmRKajJIZ2t5WWxIQU82bEZ4MU5ZQ0JxU3J4U21PQQpTY3k3K0cyckFhMWFaVktpL1VWcEdtVXZxVTgyTHNZUXJ1SFFHcjlCTnNycEpxRXloa1BLai9OMjVITHc1R3NuZVNBbUErdHRlOEJrCjRYWXpPN0xpS0JUR3NNUGxtVW8wQmxyMnhhT1lXaUxlbXpoaTZuMzAzWlprQmhQY0pVVmNkZ3lzdGtRSm55SGNnWXhFcnY4WVFoLzEKR3FmQlF0bzk3QmJPNDFJdC8vVVVNOU1oZzFDR2lTUlJJZjZuUDJHZU9sVTZZYkJLRlUvY3UzUUNZcmtzbnRCZE9zR0dRNldQSmRHNgphRHFZRkI5TDhoN3M4Z3YyZ1NpbUR3T296ekNxd1B1MjdXQ1BEWjQ5L0FlTElGdVRBTDFsNENWQnZVS2x6RVAxQURrWm5RTnNrYVRDClB4c3V3ZEVwa0IxSTJ3YnRlZ01tanRQZWhxZU96c2R6a0M4aEt6WDhkQkZGdWdMSjFxREJUaHR0QkRiQWl6S1dod2Y2Z05ucERWTFcKZU12TFA3aExaeEs2ay9BdkRtRllMNTV3bHNrazVTWGREV0tqOXNpZE5ZUk9yNVo1NmFzZlhSaXMyYmV6NWFmWW43M0NrNk1XenZFdgo4WFVlWk9pWVJHOFFZRU9SUVg3QlJEckNzc3E3bDY2YWFPU2hYbm4zTTJ6L2pxR0VoaS9vY3I3alRIVHBIWjBTd05PRTl3RDdLVWlCCktDYit3dURQUGcxeE9FVUwzMmVQOGZzWSt3bm5yejY4VTV5dFNlZ0grTFVVaFpXRmlUTCtocGk1OU1PeVZTcHV1Um9WQTMzQkNWZXYKd3E5UytmSnhTQU0yNXdzazZoZjRwL2NPb3c5Zk9QdUo0TDlYWHdUaGQwRnVORUQybWZFMHlGR25seSs0bzA2U0xOWTdVU2E0K1JmQwo1cE40R0hLb2o0MVQ5S2txeVA4ZjYvc2ZHK3ZiL2xmS2tBQ1RxZUQ0c0xpWjhjOGNEVllyK09adGZqcnY0QXVoWVc2KytOblV4ditaCkh3ejRBL1VmQnY2RC8wWmlEemdSZlNCQ0lmQkhDSDVibXhnYzZOMEgzUGxRQTd2TDBKODluQW8vMDlQUGRqTSsvT2NoRHIvcTFtdnQKU3VFaC9rQzlPd1R2Smg0Y1lEVFlFTHdOSGpuaFFlY1FqSEJvd0I2eTRIL2RmeHZPNEQvczRjV0FQV0QwQU9CLzNiRUJvMGNFM3ZvUAorT01KZlBnRlgvMzdBY2NlNmc4Zlg5akRESXk4MnpRRVlnOWVISC80b3o1Z0QydjBJZW9MRVRFd2t3RDRnTWRDNEl1SFFBVCtPelVFCjRQK3REYmd2R01FSUhQNkJVKzlqR0FFL0FoaFRBNDZBcnRIL0U3NVFNQWJlb2wveDRvR0hBUG9Yd0lxZ0R3QW5BRUE5aVZHL0lCN28KZ1UwTjM0WTJuSjh2QWdrS1VhQVpnYUdqMmMwTTRRZUg4Nkg3emxBQ3ZBZkhoZm5Da1ZnNEdrQWZNSUlnd0ljWWhvZURERmxFTk9LSQpnZEhFaU5HMGlJaHBFVUcwaUZDMGlQQnBFWUVFaUhDMGlOR2t3R2hTNEdKU0VJZ1VCRU1LZ2lNRlF3Q1dGQmhOaWhnOTNiWTBIOUg4CkFjakFYLzlMYWxtSDdHU3BqM0M2MUNlRkNZTVhxQ2xiaDRxVEJvL3BhVk9mRkNZT1FESlRCeDhWSm04ZHlvbE85bkFZVXgrQnZEeGsKejZmdFEzTjhQTTBQUC85Nzduend2NTBPUDVzRkpUMUFvbWJieVh5WXJjU0dMNVBqL1BDditXeFluZjluU0wxMDVBa1pEdDdkYkRjUApnWENBNWk4dHNzYnlFZUE0aW84SW5HWWtQQVlKRytYb2lzY1FZZkVZeFVwNGpNOUw0QytjL2czOFFPQVVMeEVFeFV0RVFFUlNJZ2hKCkN2NmxlQWw4WUhnSlBvbFJ2NEJvNmNIOXR3c1d3V2daZ3RFeWVGUk1FRXJONExTZXdRV0tCa2VhQnYwR0VZVFdNd1N0WndpeG5pR1EKbmlFWVBVTndlb1lJMEVUZ0VRVC9KOFFMVFpuK2lMSHlwVGh0SkdGbzRqd1JrNW82RWl3MGVlcVR3dlFwRVVNRVlFUk1qZ1QvdzRRcwpFS0I1S2tEUVBCWEFJSEVESEhFREdDSnVBS040S29EeGVTb0F3YUxmd0hkeEJBZHhWU0JBY1ZVZ0tDSnJJQVRKQ3Y2bHVBcDhZTGdxClFKRVIvb0loYVNEdzN5OW1BVWJ2QkJpOVE4UkVKQ0VvdlVQUWVvY1E2QjBDNlIzNEc0WWt0T1lKMEpvbklOWThBYVI1QW96bUNYQ2EKSnhDa3ljQWpDZkZQQ0JxYU5QMFJad1ZOY2VKSTBJaVlVTkNrSjQ4RUxFQXdvcVpFQUVyVUVBa1lVWk1qd3Y5dFVhdmxLRnNXV0xiSQo0dlFDLzlyNk9sN01XNGZ4enhwWXRvdmorRi96aC9GbXN6Mk5UL01kZVBLd09NeVBwKzFoL25CY2J2OE52d0UvWVY0SE52SUxhZmcvCndrbmVyZz09DQoJXV0+DQo8L2k6cGdmPg0KPC9zdmc+DQo=); + -webkit-background-size: cover; + -moz-background-size: cover; + background-size: cover; + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + vertical-align: middle; + width: 1.3rem; + height: 1.3rem; +} +#download-btn { + display: none; +} +/* Content */ +#content { + width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 20px; +} +/* Code */ +#content section.code { + display: none; + background: #FFF; + border: 1px solid #E0E0E0; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 15px; + font-size: 12px; + -moz-border-radius: 1px; + -webkit-border-radius: 1px; + border-radius: 1px; + font-weight: 400; +} +article.component { + padding: 0 0 10px; +} +#content section.code h3 { + margin: 0; + font-size: 12px; + color: #000; + font-weight: 400; +} +#content header h2 { + font-weight: 300; + margin: 10px 0 25px; + font-size: 20px; + position: relative; + display: inline-block; + padding-right: 10px; +} +body.light #content header h2 { + background: #F4F4F4; +} +body.dark #content header h2 { + background: #4A4D4E; +} +#content header{ + position: relative; +} +#content header:before { + content: ''; + width: 100%; + display: block; + position: absolute; + left: 0; + top: 23px; +} +body.light #content header:before { + border-bottom: 1px solid #E0E0E0; +} +body.dark #content header:before { + border-bottom: 1px solid #58595A; +} +#content pre { + padding: 0; + margin: 2px 0 10px; +} +.showcode { + margin: 10px 0; +} +.showcode a, section.examples a { + color: #288edf; + text-decoration: none; +} +.showcode a:hover, section.examples a:hover { + text-decoration: underline; +} +section.examples ul { + margin: 0 0 20px; + padding: 0 0 0 20px; +} +section.examples h4 { + margin-bottom: 5px; +} +section.examples li { + color: #58595A; +} +/* Side Nav */ +#sideNav { + background: #4A4D4E; + position: absolute; + width: 100%; + z-index: 1; + height: 100%; + left: 0; +} +#sideNav ul { + list-style: none; + margin: 0; + padding: 0; +} +#sideNav li a { + color: #F0F1F1; + display: block; + height: 46px; + font-size: 16px; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 12px 0 0 20px; + text-decoration: none; +} +#sideNav nav.site, #sideNav .combo { + border-bottom: 1px solid #58595A; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 10px; + display: block; +} +#pageNav li { + border-bottom: 1px solid #58595A; +} + +select.docNav { + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + background: #595B5B; + background-image: none; + box-shadow: 0 0 0 1px #303233; + border: none; + border-top: 2px solid #666767; + color: #FFF; + text-shadow: 0 -1px 0 #000; + overflow: hidden; + font-size: 14px; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 20px; + -webkit-appearance: none; + -moz-appearance: button; +} +@media screen and (min-width: 650px) { + #site.open { + transform: translate3d(0, 0, 0); + -webkit-transform: translate3d(0, 0, 0); + } + #main-header nav { + display: inline-block; + position: absolute; + right: 0; + top: 40px; + } + #main-header ul { + list-style: none; + } + #main-header nav li { + display: inline-block; + margin: 0 18px; + } + #main-header nav li#download-btn { + display: none; + } + #main-header nav li a { + text-decoration: none; + font-size: 20px; + color: #7F7F7F; + } + #main-header nav li.selected a { + color: #373435; + } + #slide-menu-button{ + display: none; + } + #main-header hgroup { + text-align: left; + position: absolute; + display: inline-block; + top: 24px; + } + #main-header hgroup h1 { + font-size: 60px; + } + #main-header hgroup p { + font-size: 15px; + } + #main-header { + color: #373435; + background: #fff; + height: 148px; + } + #content { + padding-left: 240px; + } + /* Side Nav */ + #sideNav { + background: transparent; + width: 220px; + z-index: 20; + left: 10px; + top: 150px; + height: auto; + } + #sideNav nav.site { + display: none; + } + #sideNav .combo { + border-bottom: none; + padding: 36px 0; + } + #sideNav li a { + padding: 12px 0 0 10px; + } + body.light #sideNav li a { + color: #797B7B; + } + body.light #pageNav li { + border-bottom: 1px solid #E0E0E0; + } + select.docNav { + background: #595B5B; + box-shadow: 0 0 0 1px #303233; + border: none; + border-top: 2px solid #666767; + color: #FFF; + text-shadow: 0 -1px 0 #000; + padding: 3px 20px 4px 8px; + -webkit-appearance: none; + } + body.light select.docNav { + box-shadow: 0 0 0 1px #949696; + background: #DDE1E1; + border-top: 1px solid #FFF; + color: #454545; + text-shadow: 0 -1px 0 #FFF; + width: 192px; + } +} +@media screen and (min-width: 880px) { + #content { + padding-left: 300px; + } + #sideNav li a { + display: block; + height: 60px; + padding: 22px 0 0 10px; + text-decoration: none; + } + #content header h2 { + font-size: 28px; + } + #content header:before { + top: 30px; + } + section.code div { + display: inline-block; + width: 48%; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + section.code div:first-child { + padding-right: 5px; + } + section.code div:last-child { + padding-left: 5px; + } + .max-width { + max-width: 1180px; + position: relative; + margin: 0 auto; + } + header#main-header .max-width { + top: -10px; + } + #main-header nav li a { + font-size: 22px; + } + #main-header nav { + display: inline-block; + } + + #main-header nav li { + margin: 0 25px; + } + #main-header nav li:last-child { + margin-right: 0; + } +} +@media screen and (min-width: 940px) { + #main-header nav li#download-btn { + display: inline-block; + } + #main-header nav li a#download-btn{ + position:relative; + top: -15px; + display:inline-block; + box-sizing:border-box; + -moz-box-sizing:border-box; + background-clip:padding-box; + font:inherit; + background:transparent; + -webkit-user-select:none; + -moz-user-select:none; + user-select:none; + text-overflow:ellipsis; + white-space:nowrap; + overflow:hidden; + font-size:16px; + line-height:3rem; + letter-spacing:1px; + color:#454545; + text-shadow:0 1px #fff; + vertical-align:top; + background-color:#e5e9e8; + box-shadow:inset 0 1px #fff; + border:1px solid #a5a8a8; + border-radius:6px; + margin:0; + padding:0 1.25rem; + } + #main-header nav li a#download-btn, #main-header nav li a#download-btn:hover { + border:1px solid #143250; + background-color:#288edf; + box-shadow:inset 0 1px rgba(255,255,255,0.36); + color:#fff; + font-weight:500; + text-shadow:0 -1px rgba(0,0,0,0.36); + } + #main-header nav li a#download-btn:hover { + background-color:#2f9cf3; + } + #main-header nav li a#download-btn:active, #main-header nav li a#download-btn.is-active { + background-color:#0380e8; + box-shadow:inset 0 1px rgba(0,0,0,0.12); + } + #main-header nav li a#download-btn:disabled, #main-header nav li a#download-btn.is-disabled { + opacity:.3; + cursor:default; + pointer-events:none; + } +} + + + diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/css/theme.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/css/theme.css new file mode 100755 index 0000000..7f1ec6c --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/css/theme.css @@ -0,0 +1,28 @@ +pre { + padding: 0; + font-family: 'Monaco', 'Source Code Pro', monospace; + font-size: 1em; +} +.rainbow { + border-spacing: 0; + border-collapse: collapse; +} +.rainbow .line:hover { + background-color: #171b1c; +} +.rainbow .line:hover .line-number { + background-color: #101313; +} +.rainbow .line .line-number { + text-align: right; + background-color: #1b2022; + padding-left: 0.8em; + padding-right: 0.8em; +} +.rainbow .line .line-number:before { + content: attr(data-line-number); +} +.rainbow .line .line-code { + padding-left: 1em; + width: 100%; +} diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.eot b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.eot new file mode 100755 index 0000000..9e9e4de Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.eot differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.svg new file mode 100755 index 0000000..f4a1739 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.ttf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.ttf new file mode 100755 index 0000000..6eb48e7 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.ttf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.woff b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.woff new file mode 100755 index 0000000..2383f47 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.woff differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.eot b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.eot new file mode 100755 index 0000000..bda2005 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.eot differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.svg new file mode 100755 index 0000000..e031390 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.ttf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.ttf new file mode 100755 index 0000000..0959ece Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.ttf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.woff b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.woff new file mode 100755 index 0000000..522d5ab Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.woff differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.eot b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.eot new file mode 100755 index 0000000..2b75abb Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.eot differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.svg new file mode 100755 index 0000000..581a849 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.ttf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.ttf new file mode 100755 index 0000000..e166286 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.ttf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.woff b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.woff new file mode 100755 index 0000000..315c98a Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.woff differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.eot b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.eot new file mode 100755 index 0000000..ddf5d11 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.eot differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.svg new file mode 100755 index 0000000..317e536 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.ttf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.ttf new file mode 100755 index 0000000..6d97e7b Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.ttf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.woff b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.woff new file mode 100755 index 0000000..d844315 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.woff differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/stylesheet.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/stylesheet.css new file mode 100755 index 0000000..2d66502 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/fonts/stylesheet.css @@ -0,0 +1,57 @@ + +@font-face { + font-family: 'source-sans-pro'; + src: url('sourcesanspro-light-webfont.eot'); + src: url('sourcesanspro-light-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcesanspro-light-webfont.woff') format('woff'), + url('sourcesanspro-light-webfont.ttf') format('truetype'), + url('sourcesanspro-light-webfont.svg#source_sans_prolight') format('svg'); + font-weight: 300; + font-style: normal; + +} + + + + +@font-face { + font-family: 'source-sans-pro'; + src: url('sourcesanspro-regular-webfont.eot'); + src: url('sourcesanspro-regular-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcesanspro-regular-webfont.woff') format('woff'), + url('sourcesanspro-regular-webfont.ttf') format('truetype'), + url('sourcesanspro-regular-webfont.svg#source_sans_proregular') format('svg'); + font-weight: 400; + font-style: normal; + +} + + + + +@font-face { + font-family: 'source-sans-pro'; + src: url('sourcesanspro-semibold-webfont.eot'); + src: url('sourcesanspro-semibold-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcesanspro-semibold-webfont.woff') format('woff'), + url('sourcesanspro-semibold-webfont.ttf') format('truetype'), + url('sourcesanspro-semibold-webfont.svg#source_sans_prosemibold') format('svg'); + font-weight: 600; + font-style: normal; + +} + + + + +@font-face { + font-family: 'source-code-pro'; + src: url('sourcecodepro-regular-webfont.eot'); + src: url('sourcecodepro-regular-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcecodepro-regular-webfont.woff') format('woff'), + url('sourcecodepro-regular-webfont.ttf') format('truetype'), + url('sourcecodepro-regular-webfont.svg#source_code_proregular') format('svg'); + font-weight: normal; + font-style: normal; + +} \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/index.html b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/index.html new file mode 100755 index 0000000..00cf38a --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/index.html @@ -0,0 +1,3167 @@ + + + + + + Topcoat + + + + + + + +
+ +
+
+
+
+

Topcoat

+

CSS for clean and fast web apps

+
+ +
+
+
+
+
+

Button Bar

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<div class="topcoat-button-bar">
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">One</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">Two</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">Three</button>
  </div>
</div>
+
+
+

CSS

+

+.topcoat-button-bar > .topcoat-button-bar__item:first-child {
+  border-top-left-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+
+.topcoat-button-bar > .topcoat-button-bar__item:last-child {
+  border-top-right-radius: 4px;
+  border-bottom-right-radius: 4px;
+}
+
+.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
+.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
+  border-right: none;
+}
+
+.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
+.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
+  border-left: none;
+}
+
+.topcoat-button-bar__button {
+  border-radius: inherit;
+}
+
+.topcoat-button-bar__button:focus,
+.topcoat-button-bar__button--large:focus {
+  z-index: 1;
+}
+
+
+
+
+
+
+
+

Large Button Bar

+
+
+
+ +
+
+

HTML

+
<div class="topcoat-button-bar">
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">One</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">Two</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">Three</button>
  </div>
</div>
+
+
+

CSS

+

+.topcoat-button-bar__button--large {
+  border-radius: inherit;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-button,
+.topcoat-button--quiet,
+.topcoat-button--large,
+.topcoat-button--large--quiet,
+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-button:disabled,
+.topcoat-button--quiet:disabled,
+.topcoat-button--large:disabled,
+.topcoat-button--large--quiet:disabled,
+.topcoat-button--cta:disabled,
+.topcoat-button--large--cta:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Button

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<button class="topcoat-button">Button</button>
<button class="topcoat-button" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button,
+.topcoat-button--quiet,
+.topcoat-button--large,
+.topcoat-button--large--quiet,
+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  padding: 0 0.563rem;
+  font-size: 12px;
+  line-height: 1.313rem;
+  letter-spacing: 0;
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  vertical-align: top;
+  background-color: #595b5b;
+  box-shadow: inset 0 1px #727373;
+  border: 1px solid #303233;
+  border-radius: 4px;
+}
+
+.topcoat-button:hover,
+.topcoat-button--quiet:hover,
+.topcoat-button--large:hover,
+.topcoat-button--large--quiet:hover {
+  background-color: #646666;
+}
+
+.topcoat-button:active,
+.topcoat-button--large:active {
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+}
+
+.topcoat-button:focus,
+.topcoat-button--quiet:focus,
+.topcoat-button--large:focus,
+.topcoat-button--large--quiet:focus,
+.topcoat-button--cta:focus,
+.topcoat-button--large--cta:focus {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+  outline: 0;
+}
+
+
+
+
+
+
+
+

Quiet Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--quiet">Button</button>
<button class="topcoat-button--quiet" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-button--quiet:hover,
+.topcoat-button--large--quiet:hover {
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  border: 1px solid #303233;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-button--quiet:active,
+.topcoat-button--large--quiet:active {
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  background-color: #404141;
+  border: 1px solid #303233;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+}
+
+
+
+
+
+
+
+

Large Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large" >Button</button>
<button class="topcoat-button--large" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large,
+.topcoat-button--large--quiet {
+  font-size: 0.875rem;
+  font-weight: 600;
+  line-height: 1.688rem;
+  padding: 0 0.875rem;
+}
+
+
+
+
+
+
+
+

Large Quiet Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large--quiet" >Button</button>
<button class="topcoat-button--large--quiet" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+
+
+
+
+
+
+

Call To Action Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--cta" >Button</button>
<button class="topcoat-button--cta" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  border: 1px solid #143250;
+  background-color: #288edf;
+  box-shadow: inset 0 1px rgba(255,255,255,0.36);
+  color: #fff;
+  font-weight: 500;
+  text-shadow: 0 -1px rgba(0,0,0,0.36);
+}
+
+.topcoat-button--cta:hover,
+.topcoat-button--large--cta:hover {
+  background-color: #509bef;
+}
+
+.topcoat-button--cta:active,
+.topcoat-button--large--cta:active {
+  background-color: #1976c3;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+
+
+
+
+
+
+

Large Call To Action Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large--cta" >Button</button>
<button class="topcoat-button--large--cta" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large--cta {
+  font-size: 0.875rem;
+  font-weight: 600;
+  line-height: 1.688rem;
+  padding: 0 0.875rem;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="checkbox"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.checkbox {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox__label {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.checkbox:before,
+.checkbox:after {
+  content: '';
+  position: absolute;
+}
+
+.checkbox:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="checkbox"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.checkbox,
+.topcoat-checkbox__checkmark {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox__label,
+.topcoat-checkbox {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox--disabled,
+input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.checkbox:before,
+.checkbox:after,
+.topcoat-checkbox__checkmark:before,
+.topcoat-checkbox__checkmark:after {
+  content: '';
+  position: absolute;
+}
+
+.checkbox:before,
+.topcoat-checkbox__checkmark:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+
+
+
+
+
+
+

Checkbox

+
+


+
+

Examples

+ +
+
+ +
+
+

HTML

+
<label class="topcoat-checkbox">
  <input type="checkbox">
  <div class="topcoat-checkbox__checkmark"></div>
  Default
</label>
<br>
<br>
<label class="topcoat-checkbox">
  <input type="checkbox" disabled>
  <div class="topcoat-checkbox__checkmark"></div>
  Disabled
</label>
+
+
+

CSS

+

+.topcoat-checkbox__checkmark {
+  height: 1rem;
+}
+
+input[type="checkbox"] {
+  height: 1rem;
+  width: 1rem;
+  margin-top: 0;
+  margin-right: -1rem;
+  margin-bottom: -1rem;
+  margin-left: 0;
+}
+
+input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
+  opacity: 1;
+}
+
+.topcoat-checkbox {
+  line-height: 1rem;
+}
+
+.topcoat-checkbox__checkmark:before {
+  width: 1rem;
+  height: 1rem;
+  background: #595b5b;
+  border: 1px solid #303233;
+  border-radius: 3px;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-checkbox__checkmark {
+  width: 1rem;
+  height: 1rem;
+}
+
+.topcoat-checkbox__checkmark:after {
+  top: 2px;
+  left: 1px;
+  opacity: 0;
+  width: 14px;
+  height: 4px;
+  background: transparent;
+  border: 7px solid #fff;
+  border-width: 3px;
+  border-top: none;
+  border-right: none;
+  border-radius: 1px;
+  -webkit-transform: rotate(-50deg);
+  -ms-transform: rotate(-50deg);
+  transform: rotate(-50deg);
+}
+
+input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-icon-button,
+.topcoat-icon-button--quiet,
+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-icon-button:disabled,
+.topcoat-icon-button--quiet:disabled,
+.topcoat-icon-button--large:disabled,
+.topcoat-icon-button--large--quiet:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button">
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button" disabled>
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button,
+.topcoat-icon-button--quiet,
+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  padding: 0 0.25rem;
+  line-height: 1.313rem;
+  letter-spacing: 0;
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  vertical-align: baseline;
+  background-color: #595b5b;
+  box-shadow: inset 0 1px #727373;
+  border: 1px solid #303233;
+  border-radius: 4px;
+}
+
+.topcoat-icon-button:hover,
+.topcoat-icon-button--quiet:hover,
+.topcoat-icon-button--large:hover,
+.topcoat-icon-button--large--quiet:hover {
+  background-color: #646666;
+}
+
+.topcoat-icon-button:active {
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+}
+
+.topcoat-icon-button:focus,
+.topcoat-icon-button--quiet:focus,
+.topcoat-icon-button--quiet:hover:focus,
+.topcoat-icon-button--large:focus,
+.topcoat-icon-button--large--quiet:focus,
+.topcoat-icon-button--large--quiet:hover:focus {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+  outline: 0;
+}
+
+
+
+
+
+
+
+

Quiet Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--quiet">
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--quiet" disabled>
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-icon-button--quiet:hover,
+.topcoat-icon-button--large--quiet:hover {
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  border: 1px solid #303233;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-icon-button--quiet:active,
+.topcoat-icon-button--large--quiet:active {
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  background-color: #404141;
+  border: 1px solid #303233;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+}
+
+
+
+
+
+
+
+

Large Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--large">
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--large" disabled>
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  width: 1.688rem;
+  height: 1.688rem;
+  line-height: 1.688rem;
+}
+
+.topcoat-icon-button--large:active {
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+}
+
+
+
+
+
+
+
+

Large Quiet Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--large--quiet">
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--large--quiet" disabled>
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--large--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-icon,
+.topcoat-icon--large {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  overflow: hidden;
+  width: 0.81406rem;
+  height: 0.81406rem;
+  vertical-align: middle;
+  top: -1px;
+}
+
+.topcoat-icon--large {
+  width: 1.06344rem;
+  height: 1.06344rem;
+  top: -2px;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.input {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+}
+
+.input:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.list {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  overflow: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+.list__header {
+  margin: 0;
+}
+
+.list__container {
+  padding: 0;
+  margin: 0;
+  list-style-type: none;
+}
+
+.list__item {
+  margin: 0;
+  padding: 0;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.navigation-bar {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  white-space: nowrap;
+  overflow: hidden;
+  word-spacing: 0;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.navigation-bar__item {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+}
+
+.navigation-bar__title {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.notification {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.notification,
+.topcoat-notification {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+
+
+
+
+
+
+

Notification

+
+
1
+
+ +
+
+

HTML

+
<span class="topcoat-notification">1</span>
+
+
+

CSS

+

+.topcoat-notification {
+  padding: 0.15em 0.5em 0.2em;
+  border-radius: 2px;
+  background-color: #ec514e;
+  color: #fff;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="radio"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.radio-button {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button__label {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button:before,
+.radio-button:after {
+  content: '';
+  position: absolute;
+  border-radius: 100%;
+}
+
+.radio-button:after {
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+}
+
+.radio-button:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.radio-button--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="radio"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.radio-button,
+.topcoat-radio-button__checkmark {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button__label,
+.topcoat-radio-button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button:before,
+.radio-button:after,
+.topcoat-radio-button__checkmark:before,
+.topcoat-radio-button__checkmark:after {
+  content: '';
+  position: absolute;
+  border-radius: 100%;
+}
+
+.radio-button:after,
+.topcoat-radio-button__checkmark:after {
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+}
+
+.radio-button:before,
+.topcoat-radio-button__checkmark:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.radio-button--disabled,
+input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Radio Button

+
+






+
+

Examples

+ +
+
+ +
+
+

HTML

+
<!-- NO LABEL -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
</label>
<br>
<br>
<!-- LEFT LABEL -->
<label class="topcoat-radio-button">
  Left label
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
</label>
<br>
<br>
<!-- RIGHT LABEL -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
  Right label
</label>
<br>
<br>
<!-- DISABLED -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat" Disabled>
  <div class="topcoat-radio-button__checkmark"></div>
  Disabled
</label>
+
+
+

CSS

+

+input[type="radio"] {
+  height: 1.063rem;
+  width: 1.063rem;
+  margin-top: 0;
+  margin-right: -1.063rem;
+  margin-bottom: -1.063rem;
+  margin-left: 0;
+}
+
+input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
+  opacity: 1;
+}
+
+.topcoat-radio-button {
+  color: #c6c8c8;
+  line-height: 1.063rem;
+}
+
+.topcoat-radio-button__checkmark:before {
+  width: 1.063rem;
+  height: 1.063rem;
+  background: #595b5b;
+  border: 1px solid #303233;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-radio-button__checkmark {
+  position: relative;
+  width: 1.063rem;
+  height: 1.063rem;
+}
+
+.topcoat-radio-button__checkmark:after {
+  opacity: 0;
+  width: 0.313rem;
+  height: 0.313rem;
+  background: #fff;
+  border: 1px solid rgba(255,255,255,0.1);
+  box-shadow: 0 1px rgba(255,255,255,0.5);
+  -webkit-transform: none;
+  -ms-transform: none;
+  transform: none;
+  top: 0.313rem;
+  left: 0.313rem;
+}
+
+input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.range {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+.range__thumb {
+  cursor: pointer;
+}
+
+.range__thumb--webkit {
+  cursor: pointer;
+  -webkit-appearance: none;
+}
+
+.range:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.range,
+.topcoat-range {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+.range__thumb,
+.topcoat-range::-moz-range-thumb {
+  cursor: pointer;
+}
+
+.range__thumb--webkit,
+.topcoat-range::-webkit-slider-thumb {
+  cursor: pointer;
+  -webkit-appearance: none;
+}
+
+.range:disabled,
+.topcoat-range:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Range

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<input type="range" class="topcoat-range">
<input type="range" class="topcoat-range" disabled>
+
+
+

CSS

+

+.topcoat-range {
+  border-radius: 4px;
+  border: 1px solid #303233;
+  background-color: #424546;
+  height: 0.5rem;
+  border-radius: 15px;
+}
+
+.topcoat-range::-moz-range-track {
+  border-radius: 4px;
+  border: 1px solid #303233;
+  background-color: #424546;
+  height: 0.5rem;
+  border-radius: 15px;
+}
+
+.topcoat-range::-webkit-slider-thumb {
+  height: 1.313rem;
+  width: 0.75rem;
+  background-color: #595b5b;
+  border: 1px solid #303233;
+  border-radius: 4px;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-range::-moz-range-thumb {
+  height: 1.313rem;
+  width: 0.75rem;
+  background-color: #595b5b;
+  border: 1px solid #303233;
+  border-radius: 4px;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-range:focus::-webkit-slider-thumb {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-range:focus::-moz-range-thumb {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.search-input {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+}
+
+.search-input:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.search-input,
+.topcoat-search-input,
+.topcoat-search-input--large {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+}
+
+.search-input:disabled,
+.topcoat-search-input:disabled,
+.topcoat-search-input--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Search Input

+
+
+
+ +
+
+

HTML

+
<input type="search" value="" placeholder="search" class="topcoat-search-input">
<input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
+
+
+

CSS

+

+.topcoat-search-input,
+.topcoat-search-input--large {
+  line-height: 1.313rem;
+  font-size: 12px;
+  border: 1px solid #303233;
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+  color: #c6c8c8;
+  padding: 0 0 0 1.3rem;
+  border-radius: 15px;
+  background-image: url("../img/search.svg");
+  background-position: 1em center;
+  background-repeat: no-repeat;
+  background-size: 12px;
+}
+
+.topcoat-search-input:focus,
+.topcoat-search-input--large:focus {
+  background-image: url("../img/search_dark.svg");
+  background-color: #646666;
+  color: #fff;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-search-input::-webkit-search-cancel-button,
+.topcoat-search-input::-webkit-search-decoration,
+.topcoat-search-input--large::-webkit-search-cancel-button,
+.topcoat-search-input--large::-webkit-search-decoration {
+  margin-right: 5px;
+}
+
+.topcoat-search-input:focus::-webkit-input-placeholder,
+.topcoat-search-input:focus::-webkit-input-placeholder {
+  color: #c6c8c8;
+}
+
+.topcoat-search-input:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-search-input:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-search-input:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+
+
+
+
+
+
+

Large Search Input

+
+
+
+ +
+
+

HTML

+
<input type="search" value="" placeholder="search" class="topcoat-search-input--large">
<input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
+
+
+

CSS

+

+.topcoat-search-input--large {
+  line-height: 1.688rem;
+  font-size: 0.875rem;
+  font-weight: 400;
+  padding: 0 0 0 1.8rem;
+  border-radius: 25px;
+  background-position: 1.2em center;
+  background-size: 0.875rem;
+}
+
+.topcoat-search-input--large:disabled {
+  color: #fff;
+}
+
+.topcoat-search-input--large:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-search-input--large:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-search-input--large:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.switch {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch__input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.switch__toggle {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.switch__toggle:before,
+.switch__toggle:after {
+  content: '';
+  position: absolute;
+  z-index: -1;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.switch,
+.topcoat-switch {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch__input,
+.topcoat-switch__input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.switch__toggle,
+.topcoat-switch__toggle {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.switch__toggle:before,
+.switch__toggle:after,
+.topcoat-switch__toggle:before,
+.topcoat-switch__toggle:after {
+  content: '';
+  position: absolute;
+  z-index: -1;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch--disabled,
+.topcoat-switch__input:disabled + .topcoat-switch__toggle {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Switch

+
+




+
+

Examples

+ +
+
+ +
+
+

HTML

+
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input">
  <div class="topcoat-switch__toggle"></div>
</label>
<br>
<br>
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input" checked>
  <div class="topcoat-switch__toggle"></div>
</label>
<br>
<br>
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input" disabled>
  <div class="topcoat-switch__toggle"></div>
</label>
+
+
+

CSS

+

+.topcoat-switch {
+  font-size: 12px;
+  padding: 0 0.563rem;
+  border-radius: 4px;
+  border: 1px solid #303233;
+  overflow: hidden;
+  width: 3.5rem;
+}
+
+.topcoat-switch__toggle:before,
+.topcoat-switch__toggle:after {
+  top: -1px;
+  width: 2.6rem;
+}
+
+.topcoat-switch__toggle:before {
+  content: 'ON';
+  color: #5dc1ff;
+  background-color: #404141;
+  right: 0.8rem;
+  padding-left: 0.75rem;
+}
+
+.topcoat-switch__toggle {
+  line-height: 1.313rem;
+  height: 1.313rem;
+  width: 1rem;
+  border-radius: 4px;
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  background-color: #595b5b;
+  border: 1px solid #303233;
+  margin-left: -0.6rem;
+  margin-bottom: -1px;
+  margin-top: -1px;
+  box-shadow: inset 0 1px #727373;
+  -webkit-transition: margin-left 0.05s ease-in-out;
+  transition: margin-left 0.05s ease-in-out;
+}
+
+.topcoat-switch__toggle:after {
+  content: 'OFF';
+  background-color: #404141;
+  left: 0.8rem;
+  padding-left: 0.6rem;
+}
+
+.topcoat-switch__input:checked + .topcoat-switch__toggle {
+  margin-left: 1.85rem;
+}
+
+.topcoat-switch__input:focus + .topcoat-switch__toggle {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
+.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
+  background: transparent;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-tab-bar__button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-tab-bar__button:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.button-bar,
+.topcoat-tab-bar {
+  display: table;
+  table-layout: fixed;
+  white-space: nowrap;
+  margin: 0;
+  padding: 0;
+}
+
+.button-bar__item,
+.topcoat-tab-bar__item {
+  display: table-cell;
+  width: auto;
+  border-radius: 0;
+}
+
+.button-bar__item > input,
+.topcoat-tab-bar__item > input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.button-bar__button {
+  border-radius: inherit;
+}
+
+.button-bar__item:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Tab Bar

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<div class="topcoat-tab-bar">
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">One</button>
  </label>
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">Two</button>
  </label>
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">Three</button>
  </label>
</div>
+
+
+

CSS

+

+.topcoat-tab-bar__button {
+  padding: 0 0.563rem;
+  height: 1.313rem;
+  line-height: 1.313rem;
+  letter-spacing: 0;
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  vertical-align: top;
+  background-color: #595b5b;
+  box-shadow: inset 0 1px #727373;
+  border-top: 1px solid #303233;
+}
+
+.topcoat-tab-bar__button:active,
+.topcoat-tab-bar__button--large:active,
+:checked + .topcoat-tab-bar__button {
+  color: #5dc1ff;
+  background-color: #404141;
+  box-shadow: inset 0 0 2px #313231;
+}
+
+.topcoat-tab-bar__button:focus,
+.topcoat-tab-bar__button--large:focus {
+  z-index: 1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.input,
+.topcoat-text-input,
+.topcoat-text-input--large {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+}
+
+.input:disabled,
+.topcoat-text-input:disabled,
+.topcoat-text-input--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Text input

+
+




+
+ +
+
+

HTML

+
<input type="text" class="topcoat-text-input" placeholder="text" value="">
<br>
<br>
<input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
<br>
<br>
<input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
+
+
+

CSS

+

+.topcoat-text-input,
+.topcoat-text-input--large {
+  line-height: 1.313rem;
+  font-size: 12px;
+  letter-spacing: 0;
+  padding: 0 0.563rem;
+  border: 1px solid #303233;
+  border-radius: 4px;
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+  color: #c6c8c8;
+  vertical-align: top;
+}
+
+.topcoat-text-input:focus,
+.topcoat-text-input--large:focus {
+  background-color: #646666;
+  color: #fff;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-text-input:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input:invalid {
+  border: 1px solid #d83b75;
+}
+
+
+
+
+
+
+
+

Large Text Input

+
+




+
+ +
+
+

HTML

+
<input type="text" class="topcoat-text-input--large" value="" placeholder="text">
<br>
<br>
<input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
<br>
<br>
<input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
+
+
+

CSS

+

+.topcoat-text-input--large {
+  line-height: 1.688rem;
+  font-size: 0.875rem;
+}
+
+.topcoat-text-input--large:disabled {
+  color: #fff;
+}
+
+.topcoat-text-input--large:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input--large:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input--large:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input--large:invalid {
+  border: 1px solid #d83b75;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.textarea {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  vertical-align: top;
+  resize: none;
+  outline: none;
+}
+
+.textarea:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.textarea,
+.topcoat-textarea,
+.topcoat-textarea--large {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  vertical-align: top;
+  resize: none;
+  outline: none;
+}
+
+.textarea:disabled,
+.topcoat-textarea:disabled,
+.topcoat-textarea--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Textarea

+
+


+
+ +
+
+

HTML

+
<textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
<br>
<br>
<textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
+
+
+

CSS

+

+.topcoat-textarea,
+.topcoat-textarea--large {
+  padding: 1rem;
+  font-size: 1rem;
+  font-weight: 400;
+  border-radius: 4px;
+  line-height: 1.313rem;
+  border: 1px solid #303233;
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+  color: #c6c8c8;
+  letter-spacing: 0;
+}
+
+.topcoat-textarea:focus,
+.topcoat-textarea--large:focus {
+  background-color: #646666;
+  color: #fff;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-textarea:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-textarea:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-textarea:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+
+
+
+
+
+
+

Large Textarea

+
+


+
+ +
+
+

HTML

+
<textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
<br>
<br>
<textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
+
+
+

CSS

+

+.topcoat-textarea--large {
+  font-size: 1.3rem;
+  line-height: 1.688rem;
+}
+
+.topcoat-textarea--large:disabled {
+  color: #fff;
+}
+
+.topcoat-textarea--large:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-textarea--large:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-textarea--large:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Regular.otf");
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Light.otf");
+  font-weight: 200;
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Semibold.otf");
+  font-weight: 600;
+}
+
+body {
+  margin: 0;
+  padding: 0;
+  background: #4b4d4e;
+  color: #000;
+  font: 16px "Source Sans", helvetica, arial, sans-serif;
+  font-weight: 200;
+}
+
+:focus {
+  outline-color: transparent;
+  outline-style: none;
+}
+
+.topcoat-icon--menu-stack {
+  background: url("../img/hamburger_light.svg") no-repeat;
+  background-size: cover;
+}
+
+.quarter {
+  width: 25%;
+}
+
+.half {
+  width: 50%;
+}
+
+.three-quarters {
+  width: 75%;
+}
+
+.third {
+  width: 33.333%;
+}
+
+.two-thirds {
+  width: 66.666%;
+}
+
+.full {
+  width: 100%;
+}
+
+.left {
+  text-align: left;
+}
+
+.center {
+  text-align: center;
+}
+
+.right {
+  text-align: right;
+}
+
+.reset-ui {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+}
+
+/* This file should include color and image variables corresponding to the dark theme */
+
+/* Call To Action */
+
+/* Icons */
+
+/* Navigation Bar */
+
+/* Text Input */
+
+/* Search Input */
+
+/* List */
+
+/* Checkbox */
+
+/* Overlay */
+
+/* Progress bar */
+
+/* Checkbox */
+
+/* Radio Button */
+
+/* Tab bar */
+
+/* Switch */
+
+/* Icon Button */
+
+/* Navigation bar */
+
+/* List */
+
+/* Search Input */
+
+/* Textarea */
+
+/* Checkbox */
+
+/* Radio */
+
+/* Range input */
+
+/* Search Input */
+
+/* Switch */
+
+/* This file should include color and image variables corresponding to the light theme */
+
+/* Call To Action */
+
+/* Icons */
+
+/* Navigation Bar */
+
+/* Text Input */
+
+/* List */
+
+/* Overlay */
+
+/* Progress bar */
+
+/* Checkbox */
+
+/* Range input */
+
+/* Radio Button */
+
+/* Tab bar */
+
+/* Switch */
+
+/* Containers */
+
+/* Icon Button */
+
+/* Navigation bar */
+
+/* List */
+
+/* Search Input */
+
+/* Text Area */
+
+/* Checkbox */
+
+/* Radio */
+
+/* Range input */
+
+/* Search Input */
+
+/* Switch */
+
+/* Text Input */
+
+/* Radio input */
+
+/* Overlay */
+
+/* Textarea */
+
+/* Progress bar container */
+
+/* Progress bar progress */
+
+/* Search input */
+
+/* Switch */
+
+/* Notification */
+
+
+
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/js/main.js b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/js/main.js new file mode 100755 index 0000000..6dcdbd8 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/js/main.js @@ -0,0 +1,44 @@ +window.onload = function(){ + var showCodeDivs = document.getElementsByClassName('showcode'); + for (var i = showCodeDivs.length - 1; i >= 0; i--) { + showCodeDivs[i].firstChild.onclick = function(e) { + var element = e.target.parentNode.nextSibling.nextSibling; + var style = window.getComputedStyle(element); + if(style.getPropertyValue('display') == 'none'){ + e.target.innerHTML = 'Hide code snippets'; + element.style.display = 'block'; + } else { + e.target.innerHTML = 'Show code snippets'; + element.style.display = 'none'; + } + return false; + }; + }; + var slideMenuButton = document.getElementById('slide-menu-button'); + slideMenuButton.onclick = function(e) { + var site = document.getElementById('site'); + var cl = site.classList; + if (cl.contains('open')) { + cl.remove('open'); + } else { + cl.add('open'); + } + }; + var docNavs = document.getElementsByClassName('docNav'); + for (var j = docNavs.length - 1; j >= 0; j--) { + docNavs[j].onchange = function(e){ + window.location.href = e.target[e.target.selectedIndex].value; + }; + }; + var pageNav = document.getElementById('pageNav'); + var pageLinks = pageNav.getElementsByTagName('a'); + for (var k = pageLinks.length - 1; k >= 0; k--) { + pageLinks[k].onclick = function(e) { + var site = document.getElementById('site'); + var cl = site.classList; + if (cl.contains('open')) { + cl.remove('open'); + } + }; + }; +} \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/js/rainbow-custom.min.js b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/js/rainbow-custom.min.js new file mode 100755 index 0000000..a25e178 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/js/rainbow-custom.min.js @@ -0,0 +1,11 @@ +/* Rainbow v1.2 rainbowco.de | included languages: html, css */ +window.Rainbow=function(){function q(a){var b,c=a.getAttribute&&a.getAttribute("data-language")||0;if(!c){a=a.attributes;for(b=0;b=f[d][c])delete f[d][c],delete j[d][c];if(a>=c&&ac&&b'+b+""}function s(a,b,c,i){var e=a.exec(c);if(e){++t;!b.name&&"string"==typeof b.matches[0]&&(b.name=b.matches[0],delete b.matches[0]);var k=e[0],g=e.index,u=e[0].length+g,h=function(){function e(){s(a,b,c,i)}t%100>0?e():setTimeout(e,0)};if(C(g,u))h();else{var m=v(b.matches),l=function(a,c,i){if(a>=c.length)i(k);else{var d=e[c[a]];if(d){var g=b.matches[c[a]],f=g.language,h=g.name&&g.matches? +g.matches:g,j=function(b,d,g){var f;f=0;var h;for(h=1;h/g,">").replace(/&(?![\w\#]+;)/g, +"&"),b,c)}function o(a,b,c){if(b + + + + + Topcoat + + + + + + + +
+ +
+
+
+
+

Topcoat

+

CSS for clean and fast web apps

+
+ +
+
+
+
+
+

Button Bar

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<div class="topcoat-button-bar">
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">One</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">Two</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">Three</button>
  </div>
</div>
+
+
+

CSS

+

+.topcoat-button-bar > .topcoat-button-bar__item:first-child {
+  border-top-left-radius: 4px;
+  border-bottom-left-radius: 4px;
+}
+
+.topcoat-button-bar > .topcoat-button-bar__item:last-child {
+  border-top-right-radius: 4px;
+  border-bottom-right-radius: 4px;
+}
+
+.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
+.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
+  border-right: none;
+}
+
+.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
+.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
+  border-left: none;
+}
+
+.topcoat-button-bar__button {
+  border-radius: inherit;
+}
+
+.topcoat-button-bar__button:focus,
+.topcoat-button-bar__button--large:focus {
+  z-index: 1;
+}
+
+
+
+
+
+
+
+

Large Button Bar

+
+
+
+ +
+
+

HTML

+
<div class="topcoat-button-bar">
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">One</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">Two</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">Three</button>
  </div>
</div>
+
+
+

CSS

+

+.topcoat-button-bar__button--large {
+  border-radius: inherit;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-button,
+.topcoat-button--quiet,
+.topcoat-button--large,
+.topcoat-button--large--quiet,
+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-button:disabled,
+.topcoat-button--quiet:disabled,
+.topcoat-button--large:disabled,
+.topcoat-button--large--quiet:disabled,
+.topcoat-button--cta:disabled,
+.topcoat-button--large--cta:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Button

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<button class="topcoat-button">Button</button>
<button class="topcoat-button" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button,
+.topcoat-button--quiet,
+.topcoat-button--large,
+.topcoat-button--large--quiet,
+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  padding: 0 0.563rem;
+  font-size: 12px;
+  line-height: 1.313rem;
+  letter-spacing: 0;
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  vertical-align: top;
+  background-color: #e5e9e8;
+  box-shadow: inset 0 1px #fff;
+  border: 1px solid #a5a8a8;
+  border-radius: 4px;
+}
+
+.topcoat-button:hover,
+.topcoat-button--quiet:hover,
+.topcoat-button--large:hover,
+.topcoat-button--large--quiet:hover {
+  background-color: #edf1f1;
+}
+
+.topcoat-button:active,
+.topcoat-button--large:active {
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+.topcoat-button:focus,
+.topcoat-button--quiet:focus,
+.topcoat-button--large:focus,
+.topcoat-button--large--quiet:focus,
+.topcoat-button--cta:focus,
+.topcoat-button--large--cta:focus {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+  outline: 0;
+}
+
+
+
+
+
+
+
+

Quiet Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--quiet">Button</button>
<button class="topcoat-button--quiet" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-button--quiet:hover,
+.topcoat-button--large--quiet:hover {
+  text-shadow: 0 1px #fff;
+  border: 1px solid #a5a8a8;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-button--quiet:active,
+.topcoat-button--large--quiet:active {
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  background-color: #d3d7d7;
+  border: 1px solid #a5a8a8;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+
+
+
+
+
+
+

Large Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large" >Button</button>
<button class="topcoat-button--large" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large,
+.topcoat-button--large--quiet {
+  font-size: 0.875rem;
+  font-weight: 600;
+  line-height: 1.688rem;
+  padding: 0 0.875rem;
+}
+
+
+
+
+
+
+
+

Large Quiet Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large--quiet" >Button</button>
<button class="topcoat-button--large--quiet" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+
+
+
+
+
+
+

Call To Action Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--cta" >Button</button>
<button class="topcoat-button--cta" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  border: 1px solid #143250;
+  background-color: #288edf;
+  box-shadow: inset 0 1px rgba(255,255,255,0.36);
+  color: #fff;
+  font-weight: 500;
+  text-shadow: 0 -1px rgba(0,0,0,0.36);
+}
+
+.topcoat-button--cta:hover,
+.topcoat-button--large--cta:hover {
+  background-color: #509bef;
+}
+
+.topcoat-button--cta:active,
+.topcoat-button--large--cta:active {
+  background-color: #0380e8;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+
+
+
+
+
+
+

Large Call To Action Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large--cta" >Button</button>
<button class="topcoat-button--large--cta" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large--cta {
+  font-size: 0.875rem;
+  font-weight: 600;
+  line-height: 1.688rem;
+  padding: 0 0.875rem;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="checkbox"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.checkbox {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox__label {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.checkbox:before,
+.checkbox:after {
+  content: '';
+  position: absolute;
+}
+
+.checkbox:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="checkbox"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.checkbox,
+.topcoat-checkbox__checkmark {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox__label,
+.topcoat-checkbox {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox--disabled,
+input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.checkbox:before,
+.checkbox:after,
+.topcoat-checkbox__checkmark:before,
+.topcoat-checkbox__checkmark:after {
+  content: '';
+  position: absolute;
+}
+
+.checkbox:before,
+.topcoat-checkbox__checkmark:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+
+
+
+
+
+
+

Checkbox

+
+


+
+

Examples

+ +
+
+ +
+
+

HTML

+
<label class="topcoat-checkbox">
  <input type="checkbox">
  <div class="topcoat-checkbox__checkmark"></div>
  Default
</label>
<br>
<br>
<label class="topcoat-checkbox">
  <input type="checkbox" disabled>
  <div class="topcoat-checkbox__checkmark"></div>
  Disabled
</label>
+
+
+

CSS

+

+.topcoat-checkbox__checkmark {
+  height: 1rem;
+}
+
+input[type="checkbox"] {
+  height: 1rem;
+  width: 1rem;
+  margin-top: 0;
+  margin-right: -1rem;
+  margin-bottom: -1rem;
+  margin-left: 0;
+}
+
+input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
+  opacity: 1;
+}
+
+.topcoat-checkbox {
+  line-height: 1rem;
+}
+
+.topcoat-checkbox__checkmark:before {
+  width: 1rem;
+  height: 1rem;
+  background: #e5e9e8;
+  border: 1px solid #a5a8a8;
+  border-radius: 3px;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-checkbox__checkmark {
+  width: 1rem;
+  height: 1rem;
+}
+
+.topcoat-checkbox__checkmark:after {
+  top: 2px;
+  left: 1px;
+  opacity: 0;
+  width: 14px;
+  height: 4px;
+  background: transparent;
+  border: 7px solid #666;
+  border-width: 3px;
+  border-top: none;
+  border-right: none;
+  border-radius: 1px;
+  -webkit-transform: rotate(-50deg);
+  -ms-transform: rotate(-50deg);
+  transform: rotate(-50deg);
+}
+
+input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-icon-button,
+.topcoat-icon-button--quiet,
+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-icon-button:disabled,
+.topcoat-icon-button--quiet:disabled,
+.topcoat-icon-button--large:disabled,
+.topcoat-icon-button--large--quiet:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button">
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button" disabled>
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button,
+.topcoat-icon-button--quiet,
+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  padding: 0 0.25rem;
+  line-height: 1.313rem;
+  letter-spacing: 0;
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  vertical-align: baseline;
+  background-color: #e5e9e8;
+  box-shadow: inset 0 1px #fff;
+  border: 1px solid #a5a8a8;
+  border-radius: 4px;
+}
+
+.topcoat-icon-button:hover,
+.topcoat-icon-button--quiet:hover,
+.topcoat-icon-button--large:hover,
+.topcoat-icon-button--large--quiet:hover {
+  background-color: #edf1f1;
+}
+
+.topcoat-icon-button:active {
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+.topcoat-icon-button:focus,
+.topcoat-icon-button--quiet:focus,
+.topcoat-icon-button--quiet:hover:focus,
+.topcoat-icon-button--large:focus,
+.topcoat-icon-button--large--quiet:focus,
+.topcoat-icon-button--large--quiet:hover:focus {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+  outline: 0;
+}
+
+
+
+
+
+
+
+

Quiet Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--quiet">
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--quiet" disabled>
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-icon-button--quiet:hover,
+.topcoat-icon-button--large--quiet:hover {
+  text-shadow: 0 1px #fff;
+  border: 1px solid #a5a8a8;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-icon-button--quiet:active,
+.topcoat-icon-button--large--quiet:active {
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  background-color: #d3d7d7;
+  border: 1px solid #a5a8a8;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+
+
+
+
+
+
+

Large Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--large">
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--large" disabled>
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  width: 1.688rem;
+  height: 1.688rem;
+  line-height: 1.688rem;
+}
+
+.topcoat-icon-button--large:active {
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+
+
+
+
+
+
+

Large Quiet Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--large--quiet">
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--large--quiet" disabled>
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--large--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-icon,
+.topcoat-icon--large {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  overflow: hidden;
+  width: 0.81406rem;
+  height: 0.81406rem;
+  vertical-align: middle;
+  top: -1px;
+}
+
+.topcoat-icon--large {
+  width: 1.06344rem;
+  height: 1.06344rem;
+  top: -2px;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.input {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+}
+
+.input:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.list {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  overflow: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+.list__header {
+  margin: 0;
+}
+
+.list__container {
+  padding: 0;
+  margin: 0;
+  list-style-type: none;
+}
+
+.list__item {
+  margin: 0;
+  padding: 0;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.navigation-bar {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  white-space: nowrap;
+  overflow: hidden;
+  word-spacing: 0;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.navigation-bar__item {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+}
+
+.navigation-bar__title {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.notification {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.notification,
+.topcoat-notification {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+
+
+
+
+
+
+

Notification

+
+
1
+
+ +
+
+

HTML

+
<span class="topcoat-notification">1</span>
+
+
+

CSS

+

+.topcoat-notification {
+  padding: 0.15em 0.5em 0.2em;
+  border-radius: 2px;
+  background-color: #ec514e;
+  color: #fff;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="radio"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.radio-button {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button__label {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button:before,
+.radio-button:after {
+  content: '';
+  position: absolute;
+  border-radius: 100%;
+}
+
+.radio-button:after {
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+}
+
+.radio-button:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.radio-button--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="radio"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.radio-button,
+.topcoat-radio-button__checkmark {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button__label,
+.topcoat-radio-button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button:before,
+.radio-button:after,
+.topcoat-radio-button__checkmark:before,
+.topcoat-radio-button__checkmark:after {
+  content: '';
+  position: absolute;
+  border-radius: 100%;
+}
+
+.radio-button:after,
+.topcoat-radio-button__checkmark:after {
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+}
+
+.radio-button:before,
+.topcoat-radio-button__checkmark:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.radio-button--disabled,
+input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Radio Button

+
+






+
+

Examples

+ +
+
+ +
+
+

HTML

+
<!-- NO LABEL -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
</label>
<br>
<br>
<!-- LEFT LABEL -->
<label class="topcoat-radio-button">
  Left label
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
</label>
<br>
<br>
<!-- RIGHT LABEL -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
  Right label
</label>
<br>
<br>
<!-- DISABLED -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat" Disabled>
  <div class="topcoat-radio-button__checkmark"></div>
  Disabled
</label>
+
+
+

CSS

+

+input[type="radio"] {
+  height: 1.063rem;
+  width: 1.063rem;
+  margin-top: 0;
+  margin-right: -1.063rem;
+  margin-bottom: -1.063rem;
+  margin-left: 0;
+}
+
+input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
+  opacity: 1;
+}
+
+.topcoat-radio-button {
+  color: #454545;
+  line-height: 1.063rem;
+}
+
+.topcoat-radio-button__checkmark:before {
+  width: 1.063rem;
+  height: 1.063rem;
+  background: #e5e9e8;
+  border: 1px solid #a5a8a8;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-radio-button__checkmark {
+  position: relative;
+  width: 1.063rem;
+  height: 1.063rem;
+}
+
+.topcoat-radio-button__checkmark:after {
+  opacity: 0;
+  width: 0.313rem;
+  height: 0.313rem;
+  background: #666;
+  border: 1px solid rgba(0,0,0,0.1);
+  box-shadow: 0 1px rgba(255,255,255,0.5);
+  -webkit-transform: none;
+  -ms-transform: none;
+  transform: none;
+  top: 0.313rem;
+  left: 0.313rem;
+}
+
+input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.range {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+.range__thumb {
+  cursor: pointer;
+}
+
+.range__thumb--webkit {
+  cursor: pointer;
+  -webkit-appearance: none;
+}
+
+.range:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.range,
+.topcoat-range {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+.range__thumb,
+.topcoat-range::-moz-range-thumb {
+  cursor: pointer;
+}
+
+.range__thumb--webkit,
+.topcoat-range::-webkit-slider-thumb {
+  cursor: pointer;
+  -webkit-appearance: none;
+}
+
+.range:disabled,
+.topcoat-range:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Range

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<input type="range" class="topcoat-range">
<input type="range" class="topcoat-range" disabled>
+
+
+

CSS

+

+.topcoat-range {
+  border-radius: 4px;
+  border: 1px solid #a5a8a8;
+  background-color: #d3d7d7;
+  height: 0.5rem;
+  border-radius: 15px;
+}
+
+.topcoat-range::-moz-range-track {
+  border-radius: 4px;
+  border: 1px solid #a5a8a8;
+  background-color: #d3d7d7;
+  height: 0.5rem;
+  border-radius: 15px;
+}
+
+.topcoat-range::-webkit-slider-thumb {
+  height: 1.313rem;
+  width: 0.75rem;
+  background-color: #e5e9e8;
+  border: 1px solid #a5a8a8;
+  border-radius: 4px;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-range::-moz-range-thumb {
+  height: 1.313rem;
+  width: 0.75rem;
+  background-color: #e5e9e8;
+  border: 1px solid #a5a8a8;
+  border-radius: 4px;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-range:focus::-webkit-slider-thumb {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-range:focus::-moz-range-thumb {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.search-input {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+}
+
+.search-input:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.search-input,
+.topcoat-search-input,
+.topcoat-search-input--large {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+}
+
+.search-input:disabled,
+.topcoat-search-input:disabled,
+.topcoat-search-input--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Search Input

+
+
+
+ +
+
+

HTML

+
<input type="search" value="" placeholder="search" class="topcoat-search-input">
<input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
+
+
+

CSS

+

+.topcoat-search-input,
+.topcoat-search-input--large {
+  line-height: 1.313rem;
+  font-size: 12px;
+  border: 1px solid #a5a8a8;
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+  color: #454545;
+  padding: 0 0 0 1.3rem;
+  border-radius: 15px;
+  background-image: url("../img/search.svg");
+  background-position: 1em center;
+  background-repeat: no-repeat;
+  background-size: 12px;
+}
+
+.topcoat-search-input:focus,
+.topcoat-search-input--large:focus {
+  background-image: url("../img/search_dark.svg");
+  background-color: #edf1f1;
+  color: #000;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-search-input::-webkit-search-cancel-button,
+.topcoat-search-input::-webkit-search-decoration,
+.topcoat-search-input--large::-webkit-search-cancel-button,
+.topcoat-search-input--large::-webkit-search-decoration {
+  margin-right: 5px;
+}
+
+.topcoat-search-input:focus::-webkit-input-placeholder,
+.topcoat-search-input:focus::-webkit-input-placeholder {
+  color: #c6c8c8;
+}
+
+.topcoat-search-input:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-search-input:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-search-input:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+
+
+
+
+
+
+

Large Search Input

+
+
+
+ +
+
+

HTML

+
<input type="search" value="" placeholder="search" class="topcoat-search-input--large">
<input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
+
+
+

CSS

+

+.topcoat-search-input--large {
+  line-height: 1.688rem;
+  font-size: 0.875rem;
+  font-weight: 400;
+  padding: 0 0 0 1.8rem;
+  border-radius: 25px;
+  background-position: 1.2em center;
+  background-size: 0.875rem;
+}
+
+.topcoat-search-input--large:disabled {
+  color: #000;
+}
+
+.topcoat-search-input--large:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-search-input--large:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-search-input--large:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.switch {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch__input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.switch__toggle {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.switch__toggle:before,
+.switch__toggle:after {
+  content: '';
+  position: absolute;
+  z-index: -1;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.switch,
+.topcoat-switch {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch__input,
+.topcoat-switch__input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.switch__toggle,
+.topcoat-switch__toggle {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.switch__toggle:before,
+.switch__toggle:after,
+.topcoat-switch__toggle:before,
+.topcoat-switch__toggle:after {
+  content: '';
+  position: absolute;
+  z-index: -1;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch--disabled,
+.topcoat-switch__input:disabled + .topcoat-switch__toggle {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Switch

+
+




+
+

Examples

+ +
+
+ +
+
+

HTML

+
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input">
  <div class="topcoat-switch__toggle"></div>
</label>
<br>
<br>
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input" checked>
  <div class="topcoat-switch__toggle"></div>
</label>
<br>
<br>
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input" disabled>
  <div class="topcoat-switch__toggle"></div>
</label>
+
+
+

CSS

+

+.topcoat-switch {
+  font-size: 12px;
+  padding: 0 0.563rem;
+  border-radius: 4px;
+  border: 1px solid #a5a8a8;
+  overflow: hidden;
+  width: 3.5rem;
+}
+
+.topcoat-switch__toggle:before,
+.topcoat-switch__toggle:after {
+  top: -1px;
+  width: 2.6rem;
+}
+
+.topcoat-switch__toggle:before {
+  content: 'ON';
+  color: #0083e8;
+  background-color: #e0f0fa;
+  right: 0.8rem;
+  padding-left: 0.75rem;
+}
+
+.topcoat-switch__toggle {
+  line-height: 1.313rem;
+  height: 1.313rem;
+  width: 1rem;
+  border-radius: 4px;
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  background-color: #e5e9e8;
+  border: 1px solid #a5a8a8;
+  margin-left: -0.6rem;
+  margin-bottom: -1px;
+  margin-top: -1px;
+  box-shadow: inset 0 1px #fff;
+  -webkit-transition: margin-left 0.05s ease-in-out;
+  transition: margin-left 0.05s ease-in-out;
+}
+
+.topcoat-switch__toggle:after {
+  content: 'OFF';
+  background-color: #d3d7d7;
+  left: 0.8rem;
+  padding-left: 0.6rem;
+}
+
+.topcoat-switch__input:checked + .topcoat-switch__toggle {
+  margin-left: 1.85rem;
+}
+
+.topcoat-switch__input:focus + .topcoat-switch__toggle {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
+.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
+  background: transparent;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-tab-bar__button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-tab-bar__button:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.button-bar,
+.topcoat-tab-bar {
+  display: table;
+  table-layout: fixed;
+  white-space: nowrap;
+  margin: 0;
+  padding: 0;
+}
+
+.button-bar__item,
+.topcoat-tab-bar__item {
+  display: table-cell;
+  width: auto;
+  border-radius: 0;
+}
+
+.button-bar__item > input,
+.topcoat-tab-bar__item > input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.button-bar__button {
+  border-radius: inherit;
+}
+
+.button-bar__item:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Tab Bar

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<div class="topcoat-tab-bar">
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">One</button>
  </label>
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">Two</button>
  </label>
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">Three</button>
  </label>
</div>
+
+
+

CSS

+

+.topcoat-tab-bar__button {
+  padding: 0 0.563rem;
+  height: 1.313rem;
+  line-height: 1.313rem;
+  letter-spacing: 0;
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  vertical-align: top;
+  background-color: #e5e9e8;
+  box-shadow: inset 0 1px #fff;
+  border-top: 1px solid #a5a8a8;
+}
+
+.topcoat-tab-bar__button:active,
+.topcoat-tab-bar__button--large:active,
+:checked + .topcoat-tab-bar__button {
+  color: #0083e8;
+  background-color: #e0f0fa;
+  box-shadow: inset 0 0 2px #c0ced8;
+}
+
+.topcoat-tab-bar__button:focus,
+.topcoat-tab-bar__button--large:focus {
+  z-index: 1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.input,
+.topcoat-text-input,
+.topcoat-text-input--large {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+}
+
+.input:disabled,
+.topcoat-text-input:disabled,
+.topcoat-text-input--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Text input

+
+




+
+ +
+
+

HTML

+
<input type="text" class="topcoat-text-input" placeholder="text" value="">
<br>
<br>
<input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
<br>
<br>
<input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
+
+
+

CSS

+

+.topcoat-text-input,
+.topcoat-text-input--large {
+  line-height: 1.313rem;
+  font-size: 12px;
+  letter-spacing: 0;
+  padding: 0 0.563rem;
+  border: 1px solid #a5a8a8;
+  border-radius: 4px;
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+  color: #454545;
+  vertical-align: top;
+}
+
+.topcoat-text-input:focus,
+.topcoat-text-input--large:focus {
+  background-color: #edf1f1;
+  color: #000;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-text-input:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input:invalid {
+  border: 1px solid #d83b75;
+}
+
+
+
+
+
+
+
+

Large Text Input

+
+




+
+ +
+
+

HTML

+
<input type="text" class="topcoat-text-input--large" value="" placeholder="text">
<br>
<br>
<input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
<br>
<br>
<input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
+
+
+

CSS

+

+.topcoat-text-input--large {
+  line-height: 1.688rem;
+  font-size: 0.875rem;
+}
+
+.topcoat-text-input--large:disabled {
+  color: #000;
+}
+
+.topcoat-text-input--large:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input--large:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input--large:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input--large:invalid {
+  border: 1px solid #d83b75;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.textarea {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  vertical-align: top;
+  resize: none;
+  outline: none;
+}
+
+.textarea:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.textarea,
+.topcoat-textarea,
+.topcoat-textarea--large {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  vertical-align: top;
+  resize: none;
+  outline: none;
+}
+
+.textarea:disabled,
+.topcoat-textarea:disabled,
+.topcoat-textarea--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Textarea

+
+


+
+ +
+
+

HTML

+
<textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
<br>
<br>
<textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
+
+
+

CSS

+

+.topcoat-textarea,
+.topcoat-textarea--large {
+  padding: 1rem;
+  font-size: 1rem;
+  font-weight: 400;
+  border-radius: 4px;
+  line-height: 1.313rem;
+  border: 1px solid #a5a8a8;
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+  color: #454545;
+  letter-spacing: 0;
+}
+
+.topcoat-textarea:focus,
+.topcoat-textarea--large:focus {
+  background-color: #edf1f1;
+  color: #000;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-textarea:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-textarea:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-textarea:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+
+
+
+
+
+
+

Large Textarea

+
+


+
+ +
+
+

HTML

+
<textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
<br>
<br>
<textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
+
+
+

CSS

+

+.topcoat-textarea--large {
+  font-size: 1.3rem;
+  line-height: 1.688rem;
+}
+
+.topcoat-textarea--large:disabled {
+  color: #000;
+}
+
+.topcoat-textarea--large:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-textarea--large:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-textarea--large:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Regular.otf");
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Light.otf");
+  font-weight: 200;
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Semibold.otf");
+  font-weight: 600;
+}
+
+body {
+  margin: 0;
+  padding: 0;
+  background: #dfe2e2;
+  color: #000;
+  font: 16px "Source Sans", helvetica, arial, sans-serif;
+  font-weight: 200;
+}
+
+:focus {
+  outline-color: transparent;
+  outline-style: none;
+}
+
+.topcoat-icon--menu-stack {
+  background: url("../img/hamburger_dark.svg") no-repeat;
+  background-size: cover;
+}
+
+.quarter {
+  width: 25%;
+}
+
+.half {
+  width: 50%;
+}
+
+.three-quarters {
+  width: 75%;
+}
+
+.third {
+  width: 33.333%;
+}
+
+.two-thirds {
+  width: 66.666%;
+}
+
+.full {
+  width: 100%;
+}
+
+.left {
+  text-align: left;
+}
+
+.center {
+  text-align: center;
+}
+
+.right {
+  text-align: right;
+}
+
+.reset-ui {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+}
+
+/* This file should include color and image variables corresponding to the dark theme */
+
+/* Call To Action */
+
+/* Icons */
+
+/* Navigation Bar */
+
+/* Text Input */
+
+/* Search Input */
+
+/* List */
+
+/* Checkbox */
+
+/* Overlay */
+
+/* Progress bar */
+
+/* Checkbox */
+
+/* Radio Button */
+
+/* Tab bar */
+
+/* Switch */
+
+/* Icon Button */
+
+/* Navigation bar */
+
+/* List */
+
+/* Search Input */
+
+/* Textarea */
+
+/* Checkbox */
+
+/* Radio */
+
+/* Range input */
+
+/* Search Input */
+
+/* Switch */
+
+/* This file should include color and image variables corresponding to the light theme */
+
+/* Call To Action */
+
+/* Icons */
+
+/* Navigation Bar */
+
+/* Text Input */
+
+/* List */
+
+/* Overlay */
+
+/* Progress bar */
+
+/* Checkbox */
+
+/* Range input */
+
+/* Radio Button */
+
+/* Tab bar */
+
+/* Switch */
+
+/* Containers */
+
+/* Icon Button */
+
+/* Navigation bar */
+
+/* List */
+
+/* Search Input */
+
+/* Text Area */
+
+/* Checkbox */
+
+/* Radio */
+
+/* Range input */
+
+/* Search Input */
+
+/* Switch */
+
+/* Text Input */
+
+/* Radio input */
+
+/* Overlay */
+
+/* Textarea */
+
+/* Progress bar container */
+
+/* Progress bar progress */
+
+/* Search input */
+
+/* Switch */
+
+/* Notification */
+
+
+
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-dark.html b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-dark.html new file mode 100755 index 0000000..327aeae --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-dark.html @@ -0,0 +1,3417 @@ + + + + + + Topcoat + + + + + + + +
+ +
+
+
+
+

Topcoat

+

CSS for clean and fast web apps

+
+ +
+
+
+
+
+

Button Bar

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<div class="topcoat-button-bar">
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">One</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">Two</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">Three</button>
  </div>
</div>
+
+
+

CSS

+

+.topcoat-button-bar > .topcoat-button-bar__item:first-child {
+  border-top-left-radius: 6px;
+  border-bottom-left-radius: 6px;
+}
+
+.topcoat-button-bar > .topcoat-button-bar__item:last-child {
+  border-top-right-radius: 6px;
+  border-bottom-right-radius: 6px;
+}
+
+.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
+.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
+  border-right: none;
+}
+
+.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
+.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
+  border-left: none;
+}
+
+.topcoat-button-bar__button {
+  border-radius: inherit;
+}
+
+.topcoat-button-bar__button:focus,
+.topcoat-button-bar__button--large:focus {
+  z-index: 1;
+}
+
+
+
+
+
+
+
+

Large Button Bar

+
+
+
+ +
+
+

HTML

+
<div class="topcoat-button-bar">
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">One</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">Two</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">Three</button>
  </div>
</div>
+
+
+

CSS

+

+.topcoat-button-bar__button--large {
+  border-radius: inherit;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-button,
+.topcoat-button--quiet,
+.topcoat-button--large,
+.topcoat-button--large--quiet,
+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-button:disabled,
+.topcoat-button--quiet:disabled,
+.topcoat-button--large:disabled,
+.topcoat-button--large--quiet:disabled,
+.topcoat-button--cta:disabled,
+.topcoat-button--large--cta:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Button

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<button class="topcoat-button">Button</button>
<button class="topcoat-button" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button,
+.topcoat-button--quiet,
+.topcoat-button--large,
+.topcoat-button--large--quiet,
+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  padding: 0 1.25rem;
+  font-size: 16px;
+  line-height: 3rem;
+  letter-spacing: 1px;
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  vertical-align: top;
+  background-color: #595b5b;
+  box-shadow: inset 0 1px #727373;
+  border: 1px solid #303233;
+  border-radius: 6px;
+}
+
+.topcoat-button:hover,
+.topcoat-button--quiet:hover,
+.topcoat-button--large:hover,
+.topcoat-button--large--quiet:hover {
+  background-color: #646666;
+}
+
+.topcoat-button:active,
+.topcoat-button--large:active {
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+}
+
+.topcoat-button:focus,
+.topcoat-button--quiet:focus,
+.topcoat-button--large:focus,
+.topcoat-button--large--quiet:focus,
+.topcoat-button--cta:focus,
+.topcoat-button--large--cta:focus {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+  outline: 0;
+}
+
+
+
+
+
+
+
+

Quiet Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--quiet">Button</button>
<button class="topcoat-button--quiet" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-button--quiet:hover,
+.topcoat-button--large--quiet:hover {
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  border: 1px solid #303233;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-button--quiet:active,
+.topcoat-button--large--quiet:active {
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  background-color: #404141;
+  border: 1px solid #303233;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+}
+
+
+
+
+
+
+
+

Large Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large" >Button</button>
<button class="topcoat-button--large" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large,
+.topcoat-button--large--quiet {
+  font-size: 1.3rem;
+  font-weight: 400;
+  line-height: 4.375rem;
+  padding: 0 1.25rem;
+}
+
+
+
+
+
+
+
+

Large Quiet Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large--quiet" >Button</button>
<button class="topcoat-button--large--quiet" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+
+
+
+
+
+
+

Call To Action Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--cta" >Button</button>
<button class="topcoat-button--cta" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  border: 1px solid #143250;
+  background-color: #288edf;
+  box-shadow: inset 0 1px rgba(255,255,255,0.36);
+  color: #fff;
+  font-weight: 500;
+  text-shadow: 0 -1px rgba(0,0,0,0.36);
+}
+
+.topcoat-button--cta:hover,
+.topcoat-button--large--cta:hover {
+  background-color: #509bef;
+}
+
+.topcoat-button--cta:active,
+.topcoat-button--large--cta:active {
+  background-color: #1976c3;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+
+
+
+
+
+
+

Large Call To Action Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large--cta" >Button</button>
<button class="topcoat-button--large--cta" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large--cta {
+  font-size: 1.3rem;
+  font-weight: 400;
+  line-height: 4.375rem;
+  padding: 0 1.25rem;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="checkbox"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.checkbox {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox__label {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.checkbox:before,
+.checkbox:after {
+  content: '';
+  position: absolute;
+}
+
+.checkbox:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="checkbox"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.checkbox,
+.topcoat-checkbox__checkmark {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox__label,
+.topcoat-checkbox {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox--disabled,
+input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.checkbox:before,
+.checkbox:after,
+.topcoat-checkbox__checkmark:before,
+.topcoat-checkbox__checkmark:after {
+  content: '';
+  position: absolute;
+}
+
+.checkbox:before,
+.topcoat-checkbox__checkmark:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+
+
+
+
+
+
+

Checkbox

+
+


+
+

Examples

+ +
+
+ +
+
+

HTML

+
<label class="topcoat-checkbox">
  <input type="checkbox">
  <div class="topcoat-checkbox__checkmark"></div>
  Default
</label>
<br>
<br>
<label class="topcoat-checkbox">
  <input type="checkbox" disabled>
  <div class="topcoat-checkbox__checkmark"></div>
  Disabled
</label>
+
+
+

CSS

+

+.topcoat-checkbox__checkmark {
+  height: 2rem;
+}
+
+input[type="checkbox"] {
+  height: 2rem;
+  width: 2rem;
+  margin-top: 0;
+  margin-right: -2rem;
+  margin-bottom: -2rem;
+  margin-left: 0;
+}
+
+input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
+  opacity: 1;
+}
+
+.topcoat-checkbox {
+  line-height: 2rem;
+}
+
+.topcoat-checkbox__checkmark:before {
+  width: 2rem;
+  height: 2rem;
+  background: #595b5b;
+  border: 1px solid #303233;
+  border-radius: 3px;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-checkbox__checkmark {
+  width: 2rem;
+  height: 2rem;
+}
+
+.topcoat-checkbox__checkmark:after {
+  top: 1px;
+  left: 2px;
+  opacity: 0;
+  width: 28px;
+  height: 11px;
+  background: transparent;
+  border: 7px solid #fff;
+  border-width: 7px;
+  border-top: none;
+  border-right: none;
+  border-radius: 2px;
+  -webkit-transform: rotate(-50deg);
+  -ms-transform: rotate(-50deg);
+  transform: rotate(-50deg);
+}
+
+input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-icon-button,
+.topcoat-icon-button--quiet,
+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-icon-button:disabled,
+.topcoat-icon-button--quiet:disabled,
+.topcoat-icon-button--large:disabled,
+.topcoat-icon-button--large--quiet:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button">
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button" disabled>
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button,
+.topcoat-icon-button--quiet,
+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  padding: 0 0.75rem;
+  line-height: 3rem;
+  letter-spacing: 1px;
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  vertical-align: baseline;
+  background-color: #595b5b;
+  box-shadow: inset 0 1px #727373;
+  border: 1px solid #303233;
+  border-radius: 6px;
+}
+
+.topcoat-icon-button:hover,
+.topcoat-icon-button--quiet:hover,
+.topcoat-icon-button--large:hover,
+.topcoat-icon-button--large--quiet:hover {
+  background-color: #646666;
+}
+
+.topcoat-icon-button:active {
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+}
+
+.topcoat-icon-button:focus,
+.topcoat-icon-button--quiet:focus,
+.topcoat-icon-button--quiet:hover:focus,
+.topcoat-icon-button--large:focus,
+.topcoat-icon-button--large--quiet:focus,
+.topcoat-icon-button--large--quiet:hover:focus {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+  outline: 0;
+}
+
+
+
+
+
+
+
+

Quiet Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--quiet">
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--quiet" disabled>
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-icon-button--quiet:hover,
+.topcoat-icon-button--large--quiet:hover {
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  border: 1px solid #303233;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-icon-button--quiet:active,
+.topcoat-icon-button--large--quiet:active {
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  background-color: #404141;
+  border: 1px solid #303233;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+}
+
+
+
+
+
+
+
+

Large Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--large">
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--large" disabled>
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  width: 4.375rem;
+  height: 4.375rem;
+  line-height: 4.375rem;
+}
+
+.topcoat-icon-button--large:active {
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+}
+
+
+
+
+
+
+
+

Large Quiet Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--large--quiet">
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--large--quiet" disabled>
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--large--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-icon,
+.topcoat-icon--large {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  overflow: hidden;
+  width: 1.62rem;
+  height: 1.62rem;
+  vertical-align: middle;
+  top: -1px;
+}
+
+.topcoat-icon--large {
+  width: 2.499999998125rem;
+  height: 2.499999998125rem;
+  top: -2px;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.input {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+}
+
+.input:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.list {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  overflow: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+.list__header {
+  margin: 0;
+}
+
+.list__container {
+  padding: 0;
+  margin: 0;
+  list-style-type: none;
+}
+
+.list__item {
+  margin: 0;
+  padding: 0;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.list,
+.topcoat-list {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  overflow: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+.list__header,
+.topcoat-list__header {
+  margin: 0;
+}
+
+.list__container,
+.topcoat-list__container {
+  padding: 0;
+  margin: 0;
+  list-style-type: none;
+}
+
+.list__item,
+.topcoat-list__item {
+  margin: 0;
+  padding: 0;
+}
+
+
+
+
+
+
+
+

List

+
+

Category

  • Item
  • Item
  • Item
+
+ +
+
+

HTML

+
<div class="topcoat-list">
  <h3 class="topcoat-list__header">Category</h3>
  <ul class="topcoat-list__container">
    <li class="topcoat-list__item">
      Item
    </li>
    <li class="topcoat-list__item">
      Item
    </li>
    <li class="topcoat-list__item">
      Item
    </li>
  </ul>
</div>
+
+
+

CSS

+

+.topcoat-list {
+  border-top: 1px solid #2f3234;
+  border-bottom: 1px solid #5e6061;
+  background-color: #444849;
+}
+
+.topcoat-list__header {
+  padding: 4px 20px;
+  font-size: 0.9em;
+  font-weight: 400;
+  background-color: #3b3e40;
+  color: #868888;
+  text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
+  border-top: solid 1px rgba(255,255,255,0.1);
+  border-bottom: solid 1px rgba(255,255,255,0.05);
+}
+
+.topcoat-list__container {
+  border-top: 1px solid #2f3234;
+  color: #c6c8c8;
+}
+
+.topcoat-list__item {
+  padding: 1.25rem;
+  border-top: 1px solid #5e6061;
+  border-bottom: 1px solid #2f3234;
+}
+
+.topcoat-list__item:first-child {
+  border-top: 1px solid rgba(0,0,0,0.05);
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.navigation-bar {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  white-space: nowrap;
+  overflow: hidden;
+  word-spacing: 0;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.navigation-bar__item {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+}
+
+.navigation-bar__title {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.navigation-bar,
+.topcoat-navigation-bar {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  white-space: nowrap;
+  overflow: hidden;
+  word-spacing: 0;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.navigation-bar__item,
+.topcoat-navigation-bar__item {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+}
+
+.navigation-bar__title,
+.topcoat-navigation-bar__title {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+}
+
+
+
+
+
+ +
+
+

Notification

+
+
1
+
+ +
+
+

HTML

+
<span class="topcoat-notification">1</span>
+
+
+

CSS

+

+.topcoat-notification {
+  padding: 0.15em 0.5em 0.2em;
+  border-radius: 2px;
+  background-color: #ec514e;
+  color: #fff;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="radio"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.radio-button {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button__label {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button:before,
+.radio-button:after {
+  content: '';
+  position: absolute;
+  border-radius: 100%;
+}
+
+.radio-button:after {
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+}
+
+.radio-button:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.radio-button--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="radio"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.radio-button,
+.topcoat-radio-button__checkmark {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button__label,
+.topcoat-radio-button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button:before,
+.radio-button:after,
+.topcoat-radio-button__checkmark:before,
+.topcoat-radio-button__checkmark:after {
+  content: '';
+  position: absolute;
+  border-radius: 100%;
+}
+
+.radio-button:after,
+.topcoat-radio-button__checkmark:after {
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+}
+
+.radio-button:before,
+.topcoat-radio-button__checkmark:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.radio-button--disabled,
+input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Radio Button

+
+






+
+

Examples

+ +
+
+ +
+
+

HTML

+
<!-- NO LABEL -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
</label>
<br>
<br>
<!-- LEFT LABEL -->
<label class="topcoat-radio-button">
  Left label
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
</label>
<br>
<br>
<!-- RIGHT LABEL -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
  Right label
</label>
<br>
<br>
<!-- DISABLED -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat" Disabled>
  <div class="topcoat-radio-button__checkmark"></div>
  Disabled
</label>
+
+
+

CSS

+

+input[type="radio"] {
+  height: 1.875rem;
+  width: 1.875rem;
+  margin-top: 0;
+  margin-right: -1.875rem;
+  margin-bottom: -1.875rem;
+  margin-left: 0;
+}
+
+input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
+  opacity: 1;
+}
+
+.topcoat-radio-button {
+  color: #c6c8c8;
+  line-height: 1.875rem;
+}
+
+.topcoat-radio-button__checkmark:before {
+  width: 1.875rem;
+  height: 1.875rem;
+  background: #595b5b;
+  border: 1px solid #303233;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-radio-button__checkmark {
+  position: relative;
+  width: 1.875rem;
+  height: 1.875rem;
+}
+
+.topcoat-radio-button__checkmark:after {
+  opacity: 0;
+  width: 0.875rem;
+  height: 0.875rem;
+  background: #fff;
+  border: 1px solid rgba(255,255,255,0.1);
+  box-shadow: 0 1px rgba(255,255,255,0.5);
+  -webkit-transform: none;
+  -ms-transform: none;
+  transform: none;
+  top: 7px;
+  left: 7px;
+}
+
+input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.range {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+.range__thumb {
+  cursor: pointer;
+}
+
+.range__thumb--webkit {
+  cursor: pointer;
+  -webkit-appearance: none;
+}
+
+.range:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.range,
+.topcoat-range {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+.range__thumb,
+.topcoat-range::-moz-range-thumb {
+  cursor: pointer;
+}
+
+.range__thumb--webkit,
+.topcoat-range::-webkit-slider-thumb {
+  cursor: pointer;
+  -webkit-appearance: none;
+}
+
+.range:disabled,
+.topcoat-range:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Range

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<input type="range" class="topcoat-range">
<input type="range" class="topcoat-range" disabled>
+
+
+

CSS

+

+.topcoat-range {
+  border-radius: 6px;
+  border: 1px solid #303233;
+  background-color: #424546;
+  height: 1rem;
+  border-radius: 30px;
+}
+
+.topcoat-range::-moz-range-track {
+  border-radius: 6px;
+  border: 1px solid #303233;
+  background-color: #424546;
+  height: 1rem;
+  border-radius: 30px;
+}
+
+.topcoat-range::-webkit-slider-thumb {
+  height: 3rem;
+  width: 2rem;
+  background-color: #595b5b;
+  border: 1px solid #303233;
+  border-radius: 6px;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-range::-moz-range-thumb {
+  height: 3rem;
+  width: 2rem;
+  background-color: #595b5b;
+  border: 1px solid #303233;
+  border-radius: 6px;
+  box-shadow: inset 0 1px #727373;
+}
+
+.topcoat-range:focus::-webkit-slider-thumb {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-range:focus::-moz-range-thumb {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.search-input {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+}
+
+.search-input:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.search-input,
+.topcoat-search-input,
+.topcoat-search-input--large {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+}
+
+.search-input:disabled,
+.topcoat-search-input:disabled,
+.topcoat-search-input--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Search Input

+
+
+
+ +
+
+

HTML

+
<input type="search" value="" placeholder="search" class="topcoat-search-input">
<input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
+
+
+

CSS

+

+.topcoat-search-input,
+.topcoat-search-input--large {
+  line-height: 3rem;
+  font-size: 16px;
+  border: 1px solid #303233;
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+  color: #c6c8c8;
+  padding: 0 0 0 2rem;
+  border-radius: 30px;
+  background-image: url("../img/search.svg");
+  background-position: 1em center;
+  background-repeat: no-repeat;
+  background-size: 16px;
+}
+
+.topcoat-search-input:focus,
+.topcoat-search-input--large:focus {
+  background-image: url("../img/search_dark.svg");
+  background-color: #646666;
+  color: #fff;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-search-input::-webkit-search-cancel-button,
+.topcoat-search-input::-webkit-search-decoration,
+.topcoat-search-input--large::-webkit-search-cancel-button,
+.topcoat-search-input--large::-webkit-search-decoration {
+  margin-right: 5px;
+}
+
+.topcoat-search-input:focus::-webkit-input-placeholder,
+.topcoat-search-input:focus::-webkit-input-placeholder {
+  color: #c6c8c8;
+}
+
+.topcoat-search-input:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-search-input:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-search-input:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+
+
+
+
+
+
+

Large Search Input

+
+
+
+ +
+
+

HTML

+
<input type="search" value="" placeholder="search" class="topcoat-search-input--large">
<input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
+
+
+

CSS

+

+.topcoat-search-input--large {
+  line-height: 4.375rem;
+  font-size: 1.3rem;
+  font-weight: 200;
+  padding: 0 0 0 2.9rem;
+  border-radius: 40px;
+  background-position: 1.2em center;
+  background-size: 1.3rem;
+}
+
+.topcoat-search-input--large:disabled {
+  color: #fff;
+}
+
+.topcoat-search-input--large:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-search-input--large:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-search-input--large:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.switch {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch__input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.switch__toggle {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.switch__toggle:before,
+.switch__toggle:after {
+  content: '';
+  position: absolute;
+  z-index: -1;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.switch,
+.topcoat-switch {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch__input,
+.topcoat-switch__input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.switch__toggle,
+.topcoat-switch__toggle {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.switch__toggle:before,
+.switch__toggle:after,
+.topcoat-switch__toggle:before,
+.topcoat-switch__toggle:after {
+  content: '';
+  position: absolute;
+  z-index: -1;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch--disabled,
+.topcoat-switch__input:disabled + .topcoat-switch__toggle {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Switch

+
+




+
+

Examples

+ +
+
+ +
+
+

HTML

+
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input">
  <div class="topcoat-switch__toggle"></div>
</label>
<br>
<br>
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input" checked>
  <div class="topcoat-switch__toggle"></div>
</label>
<br>
<br>
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input" disabled>
  <div class="topcoat-switch__toggle"></div>
</label>
+
+
+

CSS

+

+.topcoat-switch {
+  font-size: 16px;
+  padding: 0 1.25rem;
+  border-radius: 6px;
+  border: 1px solid #303233;
+  overflow: hidden;
+  width: 6rem;
+}
+
+.topcoat-switch__toggle:before,
+.topcoat-switch__toggle:after {
+  top: -1px;
+  width: 5rem;
+}
+
+.topcoat-switch__toggle:before {
+  content: 'ON';
+  color: #5dc1ff;
+  background-color: #404141;
+  right: 1rem;
+  padding-left: 1.5rem;
+}
+
+.topcoat-switch__toggle {
+  line-height: 3rem;
+  height: 3rem;
+  width: 2rem;
+  border-radius: 6px;
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  background-color: #595b5b;
+  border: 1px solid #303233;
+  margin-left: -1.3rem;
+  margin-bottom: -1px;
+  margin-top: -1px;
+  box-shadow: inset 0 1px #727373;
+  -webkit-transition: margin-left 0.05s ease-in-out;
+  transition: margin-left 0.05s ease-in-out;
+}
+
+.topcoat-switch__toggle:after {
+  content: 'OFF';
+  background-color: #404141;
+  left: 1rem;
+  padding-left: 2rem;
+}
+
+.topcoat-switch__input:checked + .topcoat-switch__toggle {
+  margin-left: 2.7rem;
+}
+
+.topcoat-switch__input:focus + .topcoat-switch__toggle {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
+.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
+  background: transparent;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-tab-bar__button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-tab-bar__button:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.button-bar,
+.topcoat-tab-bar {
+  display: table;
+  table-layout: fixed;
+  white-space: nowrap;
+  margin: 0;
+  padding: 0;
+}
+
+.button-bar__item,
+.topcoat-tab-bar__item {
+  display: table-cell;
+  width: auto;
+  border-radius: 0;
+}
+
+.button-bar__item > input,
+.topcoat-tab-bar__item > input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.button-bar__button {
+  border-radius: inherit;
+}
+
+.button-bar__item:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Tab Bar

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<div class="topcoat-tab-bar">
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">One</button>
  </label>
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">Two</button>
  </label>
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">Three</button>
  </label>
</div>
+
+
+

CSS

+

+.topcoat-tab-bar__button {
+  padding: 0 1.25rem;
+  height: 3rem;
+  line-height: 3rem;
+  letter-spacing: 1px;
+  color: #c6c8c8;
+  text-shadow: 0 -1px rgba(0,0,0,0.69);
+  vertical-align: top;
+  background-color: #595b5b;
+  box-shadow: inset 0 1px #727373;
+  border-top: 1px solid #303233;
+}
+
+.topcoat-tab-bar__button:active,
+.topcoat-tab-bar__button--large:active,
+:checked + .topcoat-tab-bar__button {
+  color: #5dc1ff;
+  background-color: #404141;
+  box-shadow: inset 0 0 2px #313231;
+}
+
+.topcoat-tab-bar__button:focus,
+.topcoat-tab-bar__button--large:focus {
+  z-index: 1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.input,
+.topcoat-text-input,
+.topcoat-text-input--large {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+}
+
+.input:disabled,
+.topcoat-text-input:disabled,
+.topcoat-text-input--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Text input

+
+




+
+ +
+
+

HTML

+
<input type="text" class="topcoat-text-input" placeholder="text" value="">
<br>
<br>
<input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
<br>
<br>
<input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
+
+
+

CSS

+

+.topcoat-text-input,
+.topcoat-text-input--large {
+  line-height: 3rem;
+  font-size: 16px;
+  letter-spacing: 1px;
+  padding: 0 1.25rem;
+  border: 1px solid #303233;
+  border-radius: 6px;
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+  color: #c6c8c8;
+  vertical-align: top;
+}
+
+.topcoat-text-input:focus,
+.topcoat-text-input--large:focus {
+  background-color: #646666;
+  color: #fff;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-text-input:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input:invalid {
+  border: 1px solid #d83b75;
+}
+
+
+
+
+
+
+
+

Large Text Input

+
+




+
+ +
+
+

HTML

+
<input type="text" class="topcoat-text-input--large" value="" placeholder="text">
<br>
<br>
<input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
<br>
<br>
<input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
+
+
+

CSS

+

+.topcoat-text-input--large {
+  line-height: 4.375rem;
+  font-size: 1.3rem;
+}
+
+.topcoat-text-input--large:disabled {
+  color: #fff;
+}
+
+.topcoat-text-input--large:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input--large:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input--large:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-text-input--large:invalid {
+  border: 1px solid #d83b75;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.textarea {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  vertical-align: top;
+  resize: none;
+  outline: none;
+}
+
+.textarea:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.textarea,
+.topcoat-textarea,
+.topcoat-textarea--large {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  vertical-align: top;
+  resize: none;
+  outline: none;
+}
+
+.textarea:disabled,
+.topcoat-textarea:disabled,
+.topcoat-textarea--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Textarea

+
+


+
+ +
+
+

HTML

+
<textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
<br>
<br>
<textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
+
+
+

CSS

+

+.topcoat-textarea,
+.topcoat-textarea--large {
+  padding: 2rem;
+  font-size: 2.5rem;
+  font-weight: 200;
+  border-radius: 6px;
+  line-height: 3rem;
+  border: 1px solid #303233;
+  background-color: #404141;
+  box-shadow: inset 0 1px rgba(0,0,0,0.18);
+  color: #c6c8c8;
+  letter-spacing: 1px;
+}
+
+.topcoat-textarea:focus,
+.topcoat-textarea--large:focus {
+  background-color: #646666;
+  color: #fff;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-textarea:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-textarea:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-textarea:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+
+
+
+
+
+
+

Large Textarea

+
+


+
+ +
+
+

HTML

+
<textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
<br>
<br>
<textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
+
+
+

CSS

+

+.topcoat-textarea--large {
+  font-size: 3rem;
+  line-height: 4.375rem;
+}
+
+.topcoat-textarea--large:disabled {
+  color: #fff;
+}
+
+.topcoat-textarea--large:disabled::-webkit-input-placeholder {
+  color: #fff;
+}
+
+.topcoat-textarea--large:disabled::-moz-placeholder {
+  color: #fff;
+}
+
+.topcoat-textarea--large:disabled:-ms-input-placeholder {
+  color: #fff;
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Regular.otf");
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Light.otf");
+  font-weight: 200;
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Semibold.otf");
+  font-weight: 600;
+}
+
+body {
+  margin: 0;
+  padding: 0;
+  background: #4b4d4e;
+  color: #000;
+  font: 16px "Source Sans", helvetica, arial, sans-serif;
+  font-weight: 200;
+}
+
+:focus {
+  outline-color: transparent;
+  outline-style: none;
+}
+
+.topcoat-icon--menu-stack {
+  background: url("../img/hamburger_light.svg") no-repeat;
+  background-size: cover;
+}
+
+.quarter {
+  width: 25%;
+}
+
+.half {
+  width: 50%;
+}
+
+.three-quarters {
+  width: 75%;
+}
+
+.third {
+  width: 33.333%;
+}
+
+.two-thirds {
+  width: 66.666%;
+}
+
+.full {
+  width: 100%;
+}
+
+.left {
+  text-align: left;
+}
+
+.center {
+  text-align: center;
+}
+
+.right {
+  text-align: right;
+}
+
+.reset-ui {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+}
+
+/* This file should include color and image variables corresponding to the dark theme */
+
+/* Call To Action */
+
+/* Icons */
+
+/* Navigation Bar */
+
+/* Text Input */
+
+/* Search Input */
+
+/* List */
+
+/* Checkbox */
+
+/* Overlay */
+
+/* Progress bar */
+
+/* Checkbox */
+
+/* Radio Button */
+
+/* Tab bar */
+
+/* Switch */
+
+/* Icon Button */
+
+/* Navigation bar */
+
+/* List */
+
+/* Search Input */
+
+/* Textarea */
+
+/* Checkbox */
+
+/* Radio */
+
+/* Range input */
+
+/* Search Input */
+
+/* Switch */
+
+/* This file should include color and image variables corresponding to the light theme */
+
+/* Call To Action */
+
+/* Icons */
+
+/* Navigation Bar */
+
+/* Text Input */
+
+/* List */
+
+/* Overlay */
+
+/* Progress bar */
+
+/* Checkbox */
+
+/* Range input */
+
+/* Radio Button */
+
+/* Tab bar */
+
+/* Switch */
+
+/* Containers */
+
+/* Icon Button */
+
+/* Navigation bar */
+
+/* List */
+
+/* Search Input */
+
+/* Text Area */
+
+/* Checkbox */
+
+/* Radio */
+
+/* Range input */
+
+/* Search Input */
+
+/* Switch */
+
+/* Text Input */
+
+/* Radio input */
+
+/* Overlay */
+
+/* Textarea */
+
+/* Progress bar container */
+
+/* Progress bar progress */
+
+/* Search input */
+
+/* Switch */
+
+/* Notification */
+
+
+
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-light.html b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-light.html new file mode 100755 index 0000000..f67a519 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-light.html @@ -0,0 +1,3417 @@ + + + + + + Topcoat + + + + + + + +
+ +
+
+
+
+

Topcoat

+

CSS for clean and fast web apps

+
+ +
+
+
+
+
+

Button Bar

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<div class="topcoat-button-bar">
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">One</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">Two</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button">Three</button>
  </div>
</div>
+
+
+

CSS

+

+.topcoat-button-bar > .topcoat-button-bar__item:first-child {
+  border-top-left-radius: 6px;
+  border-bottom-left-radius: 6px;
+}
+
+.topcoat-button-bar > .topcoat-button-bar__item:last-child {
+  border-top-right-radius: 6px;
+  border-bottom-right-radius: 6px;
+}
+
+.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
+.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
+  border-right: none;
+}
+
+.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
+.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
+  border-left: none;
+}
+
+.topcoat-button-bar__button {
+  border-radius: inherit;
+}
+
+.topcoat-button-bar__button:focus,
+.topcoat-button-bar__button--large:focus {
+  z-index: 1;
+}
+
+
+
+
+
+
+
+

Large Button Bar

+
+
+
+ +
+
+

HTML

+
<div class="topcoat-button-bar">
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">One</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">Two</button>
  </div>
  <div class="topcoat-button-bar__item">
    <button class="topcoat-button-bar__button--large">Three</button>
  </div>
</div>
+
+
+

CSS

+

+.topcoat-button-bar__button--large {
+  border-radius: inherit;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-button,
+.topcoat-button--quiet,
+.topcoat-button--large,
+.topcoat-button--large--quiet,
+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-button:disabled,
+.topcoat-button--quiet:disabled,
+.topcoat-button--large:disabled,
+.topcoat-button--large--quiet:disabled,
+.topcoat-button--cta:disabled,
+.topcoat-button--large--cta:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Button

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<button class="topcoat-button">Button</button>
<button class="topcoat-button" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button,
+.topcoat-button--quiet,
+.topcoat-button--large,
+.topcoat-button--large--quiet,
+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  padding: 0 1.25rem;
+  font-size: 16px;
+  line-height: 3rem;
+  letter-spacing: 1px;
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  vertical-align: top;
+  background-color: #e5e9e8;
+  box-shadow: inset 0 1px #fff;
+  border: 1px solid #a5a8a8;
+  border-radius: 6px;
+}
+
+.topcoat-button:hover,
+.topcoat-button--quiet:hover,
+.topcoat-button--large:hover,
+.topcoat-button--large--quiet:hover {
+  background-color: #edf1f1;
+}
+
+.topcoat-button:active,
+.topcoat-button--large:active {
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+.topcoat-button:focus,
+.topcoat-button--quiet:focus,
+.topcoat-button--large:focus,
+.topcoat-button--large--quiet:focus,
+.topcoat-button--cta:focus,
+.topcoat-button--large--cta:focus {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+  outline: 0;
+}
+
+
+
+
+
+
+
+

Quiet Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--quiet">Button</button>
<button class="topcoat-button--quiet" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-button--quiet:hover,
+.topcoat-button--large--quiet:hover {
+  text-shadow: 0 1px #fff;
+  border: 1px solid #a5a8a8;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-button--quiet:active,
+.topcoat-button--large--quiet:active {
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  background-color: #d3d7d7;
+  border: 1px solid #a5a8a8;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+
+
+
+
+
+
+

Large Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large" >Button</button>
<button class="topcoat-button--large" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large,
+.topcoat-button--large--quiet {
+  font-size: 1.3rem;
+  font-weight: 400;
+  line-height: 4.375rem;
+  padding: 0 1.25rem;
+}
+
+
+
+
+
+
+
+

Large Quiet Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large--quiet" >Button</button>
<button class="topcoat-button--large--quiet" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+
+
+
+
+
+
+

Call To Action Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--cta" >Button</button>
<button class="topcoat-button--cta" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--cta,
+.topcoat-button--large--cta {
+  border: 1px solid #143250;
+  background-color: #288edf;
+  box-shadow: inset 0 1px rgba(255,255,255,0.36);
+  color: #fff;
+  font-weight: 500;
+  text-shadow: 0 -1px rgba(0,0,0,0.36);
+}
+
+.topcoat-button--cta:hover,
+.topcoat-button--large--cta:hover {
+  background-color: #509bef;
+}
+
+.topcoat-button--cta:active,
+.topcoat-button--large--cta:active {
+  background-color: #0380e8;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+
+
+
+
+
+
+

Large Call To Action Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-button--large--cta" >Button</button>
<button class="topcoat-button--large--cta" disabled>Button</button>
+
+
+

CSS

+

+.topcoat-button--large--cta {
+  font-size: 1.3rem;
+  font-weight: 400;
+  line-height: 4.375rem;
+  padding: 0 1.25rem;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="checkbox"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.checkbox {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox__label {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.checkbox:before,
+.checkbox:after {
+  content: '';
+  position: absolute;
+}
+
+.checkbox:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="checkbox"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.checkbox,
+.topcoat-checkbox__checkmark {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox__label,
+.topcoat-checkbox {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.checkbox--disabled,
+input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.checkbox:before,
+.checkbox:after,
+.topcoat-checkbox__checkmark:before,
+.topcoat-checkbox__checkmark:after {
+  content: '';
+  position: absolute;
+}
+
+.checkbox:before,
+.topcoat-checkbox__checkmark:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+
+
+
+
+
+
+

Checkbox

+
+


+
+

Examples

+ +
+
+ +
+
+

HTML

+
<label class="topcoat-checkbox">
  <input type="checkbox">
  <div class="topcoat-checkbox__checkmark"></div>
  Default
</label>
<br>
<br>
<label class="topcoat-checkbox">
  <input type="checkbox" disabled>
  <div class="topcoat-checkbox__checkmark"></div>
  Disabled
</label>
+
+
+

CSS

+

+.topcoat-checkbox__checkmark {
+  height: 2rem;
+}
+
+input[type="checkbox"] {
+  height: 2rem;
+  width: 2rem;
+  margin-top: 0;
+  margin-right: -2rem;
+  margin-bottom: -2rem;
+  margin-left: 0;
+}
+
+input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
+  opacity: 1;
+}
+
+.topcoat-checkbox {
+  line-height: 2rem;
+}
+
+.topcoat-checkbox__checkmark:before {
+  width: 2rem;
+  height: 2rem;
+  background: #e5e9e8;
+  border: 1px solid #a5a8a8;
+  border-radius: 3px;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-checkbox__checkmark {
+  width: 2rem;
+  height: 2rem;
+}
+
+.topcoat-checkbox__checkmark:after {
+  top: 1px;
+  left: 2px;
+  opacity: 0;
+  width: 28px;
+  height: 11px;
+  background: transparent;
+  border: 7px solid #666;
+  border-width: 7px;
+  border-top: none;
+  border-right: none;
+  border-radius: 2px;
+  -webkit-transform: rotate(-50deg);
+  -ms-transform: rotate(-50deg);
+  transform: rotate(-50deg);
+}
+
+input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-icon-button,
+.topcoat-icon-button--quiet,
+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-icon-button:disabled,
+.topcoat-icon-button--quiet:disabled,
+.topcoat-icon-button--large:disabled,
+.topcoat-icon-button--large--quiet:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button">
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button" disabled>
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button,
+.topcoat-icon-button--quiet,
+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  padding: 0 0.75rem;
+  line-height: 3rem;
+  letter-spacing: 1px;
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  vertical-align: baseline;
+  background-color: #e5e9e8;
+  box-shadow: inset 0 1px #fff;
+  border: 1px solid #a5a8a8;
+  border-radius: 6px;
+}
+
+.topcoat-icon-button:hover,
+.topcoat-icon-button--quiet:hover,
+.topcoat-icon-button--large:hover,
+.topcoat-icon-button--large--quiet:hover {
+  background-color: #edf1f1;
+}
+
+.topcoat-icon-button:active {
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+.topcoat-icon-button:focus,
+.topcoat-icon-button--quiet:focus,
+.topcoat-icon-button--quiet:hover:focus,
+.topcoat-icon-button--large:focus,
+.topcoat-icon-button--large--quiet:focus,
+.topcoat-icon-button--large--quiet:hover:focus {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+  outline: 0;
+}
+
+
+
+
+
+
+
+

Quiet Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--quiet">
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--quiet" disabled>
  <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-icon-button--quiet:hover,
+.topcoat-icon-button--large--quiet:hover {
+  text-shadow: 0 1px #fff;
+  border: 1px solid #a5a8a8;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-icon-button--quiet:active,
+.topcoat-icon-button--large--quiet:active {
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  background-color: #d3d7d7;
+  border: 1px solid #a5a8a8;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+
+
+
+
+
+
+

Large Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--large">
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--large" disabled>
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--large,
+.topcoat-icon-button--large--quiet {
+  width: 4.375rem;
+  height: 4.375rem;
+  line-height: 4.375rem;
+}
+
+.topcoat-icon-button--large:active {
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+}
+
+
+
+
+
+
+
+

Large Quiet Icon Button

+
+
+
+ +
+
+

HTML

+
<button class="topcoat-icon-button--large--quiet">
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
<button class="topcoat-icon-button--large--quiet" disabled>
  <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
</button>
+
+
+

CSS

+

+.topcoat-icon-button--large--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.topcoat-icon,
+.topcoat-icon--large {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  overflow: hidden;
+  width: 1.62rem;
+  height: 1.62rem;
+  vertical-align: middle;
+  top: -1px;
+}
+
+.topcoat-icon--large {
+  width: 2.499999998125rem;
+  height: 2.499999998125rem;
+  top: -2px;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.input {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+}
+
+.input:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.list {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  overflow: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+.list__header {
+  margin: 0;
+}
+
+.list__container {
+  padding: 0;
+  margin: 0;
+  list-style-type: none;
+}
+
+.list__item {
+  margin: 0;
+  padding: 0;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.list,
+.topcoat-list {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  overflow: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+.list__header,
+.topcoat-list__header {
+  margin: 0;
+}
+
+.list__container,
+.topcoat-list__container {
+  padding: 0;
+  margin: 0;
+  list-style-type: none;
+}
+
+.list__item,
+.topcoat-list__item {
+  margin: 0;
+  padding: 0;
+}
+
+
+
+
+
+
+
+

List

+
+

Category

  • Item
  • Item
  • Item
+
+ +
+
+

HTML

+
<div class="topcoat-list">
  <h3 class="topcoat-list__header">Category</h3>
  <ul class="topcoat-list__container">
    <li class="topcoat-list__item">
      Item
    </li>
    <li class="topcoat-list__item">
      Item
    </li>
    <li class="topcoat-list__item">
      Item
    </li>
  </ul>
</div>
+
+
+

CSS

+

+.topcoat-list {
+  border-top: 1px solid #bcbfbf;
+  border-bottom: 1px solid #eff1f1;
+  background-color: #dfe2e2;
+}
+
+.topcoat-list__header {
+  padding: 4px 20px;
+  font-size: 0.9em;
+  font-weight: 400;
+  background-color: #cccfcf;
+  color: #656565;
+  text-shadow: 0 1px 0 rgba(255,255,255,0.5);
+  border-top: 1px solid rgba(255,255,255,0.5);
+  border-bottom: 1px solid rgba(255,255,255,0.23);
+}
+
+.topcoat-list__container {
+  border-top: 1px solid #bcbfbf;
+  color: #454545;
+}
+
+.topcoat-list__item {
+  padding: 1.25rem;
+  border-top: 1px solid #eff1f1;
+  border-bottom: 1px solid #bcbfbf;
+}
+
+.topcoat-list__item:first-child {
+  border-top: 1px solid rgba(0,0,0,0.05);
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.navigation-bar {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  white-space: nowrap;
+  overflow: hidden;
+  word-spacing: 0;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.navigation-bar__item {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+}
+
+.navigation-bar__title {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.navigation-bar,
+.topcoat-navigation-bar {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  white-space: nowrap;
+  overflow: hidden;
+  word-spacing: 0;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.navigation-bar__item,
+.topcoat-navigation-bar__item {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+}
+
+.navigation-bar__title,
+.topcoat-navigation-bar__title {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+}
+
+
+
+
+
+ +
+
+

Notification

+
+
1
+
+ +
+
+

HTML

+
<span class="topcoat-notification">1</span>
+
+
+

CSS

+

+.topcoat-notification {
+  padding: 0.15em 0.5em 0.2em;
+  border-radius: 2px;
+  background-color: #ec514e;
+  color: #fff;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="radio"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.radio-button {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button__label {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button:before,
+.radio-button:after {
+  content: '';
+  position: absolute;
+  border-radius: 100%;
+}
+
+.radio-button:after {
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+}
+
+.radio-button:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.radio-button--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+input[type="radio"] {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.radio-button,
+.topcoat-radio-button__checkmark {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button__label,
+.topcoat-radio-button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.radio-button:before,
+.radio-button:after,
+.topcoat-radio-button__checkmark:before,
+.topcoat-radio-button__checkmark:after {
+  content: '';
+  position: absolute;
+  border-radius: 100%;
+}
+
+.radio-button:after,
+.topcoat-radio-button__checkmark:after {
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+}
+
+.radio-button:before,
+.topcoat-radio-button__checkmark:before {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.radio-button--disabled,
+input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Radio Button

+
+






+
+

Examples

+ +
+
+ +
+
+

HTML

+
<!-- NO LABEL -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
</label>
<br>
<br>
<!-- LEFT LABEL -->
<label class="topcoat-radio-button">
  Left label
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
</label>
<br>
<br>
<!-- RIGHT LABEL -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat">
  <div class="topcoat-radio-button__checkmark"></div>
  Right label
</label>
<br>
<br>
<!-- DISABLED -->
<label class="topcoat-radio-button">
  <input type="radio" name="topcoat" Disabled>
  <div class="topcoat-radio-button__checkmark"></div>
  Disabled
</label>
+
+
+

CSS

+

+input[type="radio"] {
+  height: 1.875rem;
+  width: 1.875rem;
+  margin-top: 0;
+  margin-right: -1.875rem;
+  margin-bottom: -1.875rem;
+  margin-left: 0;
+}
+
+input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
+  opacity: 1;
+}
+
+.topcoat-radio-button {
+  color: #454545;
+  line-height: 1.875rem;
+}
+
+.topcoat-radio-button__checkmark:before {
+  width: 1.875rem;
+  height: 1.875rem;
+  background: #e5e9e8;
+  border: 1px solid #a5a8a8;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-radio-button__checkmark {
+  position: relative;
+  width: 1.875rem;
+  height: 1.875rem;
+}
+
+.topcoat-radio-button__checkmark:after {
+  opacity: 0;
+  width: 0.875rem;
+  height: 0.875rem;
+  background: #666;
+  border: 1px solid rgba(0,0,0,0.1);
+  box-shadow: 0 1px rgba(255,255,255,0.5);
+  -webkit-transform: none;
+  -ms-transform: none;
+  transform: none;
+  top: 7px;
+  left: 7px;
+}
+
+input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.range {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+.range__thumb {
+  cursor: pointer;
+}
+
+.range__thumb--webkit {
+  cursor: pointer;
+  -webkit-appearance: none;
+}
+
+.range:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+Copyright 2012 Adobe Systems Inc.;
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.range,
+.topcoat-range {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+.range__thumb,
+.topcoat-range::-moz-range-thumb {
+  cursor: pointer;
+}
+
+.range__thumb--webkit,
+.topcoat-range::-webkit-slider-thumb {
+  cursor: pointer;
+  -webkit-appearance: none;
+}
+
+.range:disabled,
+.topcoat-range:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Range

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<input type="range" class="topcoat-range">
<input type="range" class="topcoat-range" disabled>
+
+
+

CSS

+

+.topcoat-range {
+  border-radius: 6px;
+  border: 1px solid #a5a8a8;
+  background-color: #d3d7d7;
+  height: 1rem;
+  border-radius: 30px;
+}
+
+.topcoat-range::-moz-range-track {
+  border-radius: 6px;
+  border: 1px solid #a5a8a8;
+  background-color: #d3d7d7;
+  height: 1rem;
+  border-radius: 30px;
+}
+
+.topcoat-range::-webkit-slider-thumb {
+  height: 3rem;
+  width: 2rem;
+  background-color: #e5e9e8;
+  border: 1px solid #a5a8a8;
+  border-radius: 6px;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-range::-moz-range-thumb {
+  height: 3rem;
+  width: 2rem;
+  background-color: #e5e9e8;
+  border: 1px solid #a5a8a8;
+  border-radius: 6px;
+  box-shadow: inset 0 1px #fff;
+}
+
+.topcoat-range:focus::-webkit-slider-thumb {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-range:focus::-moz-range-thumb {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.search-input {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+}
+
+.search-input:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.search-input,
+.topcoat-search-input,
+.topcoat-search-input--large {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+  -webkit-appearance: none;
+}
+
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+}
+
+.search-input:disabled,
+.topcoat-search-input:disabled,
+.topcoat-search-input--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Search Input

+
+
+
+ +
+
+

HTML

+
<input type="search" value="" placeholder="search" class="topcoat-search-input">
<input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
+
+
+

CSS

+

+.topcoat-search-input,
+.topcoat-search-input--large {
+  line-height: 3rem;
+  font-size: 16px;
+  border: 1px solid #a5a8a8;
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+  color: #454545;
+  padding: 0 0 0 2rem;
+  border-radius: 30px;
+  background-image: url("../img/search.svg");
+  background-position: 1em center;
+  background-repeat: no-repeat;
+  background-size: 16px;
+}
+
+.topcoat-search-input:focus,
+.topcoat-search-input--large:focus {
+  background-image: url("../img/search_dark.svg");
+  background-color: #edf1f1;
+  color: #000;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-search-input::-webkit-search-cancel-button,
+.topcoat-search-input::-webkit-search-decoration,
+.topcoat-search-input--large::-webkit-search-cancel-button,
+.topcoat-search-input--large::-webkit-search-decoration {
+  margin-right: 5px;
+}
+
+.topcoat-search-input:focus::-webkit-input-placeholder,
+.topcoat-search-input:focus::-webkit-input-placeholder {
+  color: #c6c8c8;
+}
+
+.topcoat-search-input:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-search-input:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-search-input:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+
+
+
+
+
+
+

Large Search Input

+
+
+
+ +
+
+

HTML

+
<input type="search" value="" placeholder="search" class="topcoat-search-input--large">
<input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
+
+
+

CSS

+

+.topcoat-search-input--large {
+  line-height: 4.375rem;
+  font-size: 1.3rem;
+  font-weight: 200;
+  padding: 0 0 0 2.9rem;
+  border-radius: 40px;
+  background-position: 1.2em center;
+  background-size: 1.3rem;
+}
+
+.topcoat-search-input--large:disabled {
+  color: #000;
+}
+
+.topcoat-search-input--large:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-search-input--large:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-search-input--large:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.switch {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch__input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.switch__toggle {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.switch__toggle:before,
+.switch__toggle:after {
+  content: '';
+  position: absolute;
+  z-index: -1;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch--disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.switch,
+.topcoat-switch {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch__input,
+.topcoat-switch__input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.switch__toggle,
+.topcoat-switch__toggle {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+.switch__toggle:before,
+.switch__toggle:after,
+.topcoat-switch__toggle:before,
+.topcoat-switch__toggle:after {
+  content: '';
+  position: absolute;
+  z-index: -1;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+}
+
+.switch--disabled,
+.topcoat-switch__input:disabled + .topcoat-switch__toggle {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Switch

+
+




+
+

Examples

+ +
+
+ +
+
+

HTML

+
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input">
  <div class="topcoat-switch__toggle"></div>
</label>
<br>
<br>
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input" checked>
  <div class="topcoat-switch__toggle"></div>
</label>
<br>
<br>
<label class="topcoat-switch">
  <input type="checkbox" class="topcoat-switch__input" disabled>
  <div class="topcoat-switch__toggle"></div>
</label>
+
+
+

CSS

+

+.topcoat-switch {
+  font-size: 16px;
+  padding: 0 1.25rem;
+  border-radius: 6px;
+  border: 1px solid #a5a8a8;
+  overflow: hidden;
+  width: 6rem;
+}
+
+.topcoat-switch__toggle:before,
+.topcoat-switch__toggle:after {
+  top: -1px;
+  width: 5rem;
+}
+
+.topcoat-switch__toggle:before {
+  content: 'ON';
+  color: #0083e8;
+  background-color: #e0f0fa;
+  right: 1rem;
+  padding-left: 1.5rem;
+}
+
+.topcoat-switch__toggle {
+  line-height: 3rem;
+  height: 3rem;
+  width: 2rem;
+  border-radius: 6px;
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  background-color: #e5e9e8;
+  border: 1px solid #a5a8a8;
+  margin-left: -1.3rem;
+  margin-bottom: -1px;
+  margin-top: -1px;
+  box-shadow: inset 0 1px #fff;
+  -webkit-transition: margin-left 0.05s ease-in-out;
+  transition: margin-left 0.05s ease-in-out;
+}
+
+.topcoat-switch__toggle:after {
+  content: 'OFF';
+  background-color: #d3d7d7;
+  left: 1rem;
+  padding-left: 2rem;
+}
+
+.topcoat-switch__input:checked + .topcoat-switch__toggle {
+  margin-left: 2.7rem;
+}
+
+.topcoat-switch__input:focus + .topcoat-switch__toggle {
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
+.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
+  background: transparent;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.button,
+.topcoat-tab-bar__button {
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  text-decoration: none;
+}
+
+.button--quiet {
+  background: transparent;
+  border: 1px solid transparent;
+  box-shadow: none;
+}
+
+.button--disabled,
+.topcoat-tab-bar__button:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+.button-bar,
+.topcoat-tab-bar {
+  display: table;
+  table-layout: fixed;
+  white-space: nowrap;
+  margin: 0;
+  padding: 0;
+}
+
+.button-bar__item,
+.topcoat-tab-bar__item {
+  display: table-cell;
+  width: auto;
+  border-radius: 0;
+}
+
+.button-bar__item > input,
+.topcoat-tab-bar__item > input {
+  position: absolute;
+  overflow: hidden;
+  padding: 0;
+  border: 0;
+  opacity: 0.001;
+  z-index: 1;
+  vertical-align: top;
+  outline: none;
+}
+
+.button-bar__button {
+  border-radius: inherit;
+}
+
+.button-bar__item:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Tab Bar

+
+
+
+

Examples

+ +
+
+ +
+
+

HTML

+
<div class="topcoat-tab-bar">
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">One</button>
  </label>
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">Two</button>
  </label>
  <label class="topcoat-tab-bar__item">
    <input type="radio" name="tab-bar">
    <button class="topcoat-tab-bar__button">Three</button>
  </label>
</div>
+
+
+

CSS

+

+.topcoat-tab-bar__button {
+  padding: 0 1.25rem;
+  height: 3rem;
+  line-height: 3rem;
+  letter-spacing: 1px;
+  color: #454545;
+  text-shadow: 0 1px #fff;
+  vertical-align: top;
+  background-color: #e5e9e8;
+  box-shadow: inset 0 1px #fff;
+  border-top: 1px solid #a5a8a8;
+}
+
+.topcoat-tab-bar__button:active,
+.topcoat-tab-bar__button--large:active,
+:checked + .topcoat-tab-bar__button {
+  color: #0083e8;
+  background-color: #e0f0fa;
+  box-shadow: inset 0 0 2px #c0ced8;
+}
+
+.topcoat-tab-bar__button:focus,
+.topcoat-tab-bar__button--large:focus {
+  z-index: 1;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.input,
+.topcoat-text-input,
+.topcoat-text-input--large {
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  vertical-align: top;
+  outline: none;
+}
+
+.input:disabled,
+.topcoat-text-input:disabled,
+.topcoat-text-input--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Text input

+
+




+
+ +
+
+

HTML

+
<input type="text" class="topcoat-text-input" placeholder="text" value="">
<br>
<br>
<input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
<br>
<br>
<input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
+
+
+

CSS

+

+.topcoat-text-input,
+.topcoat-text-input--large {
+  line-height: 3rem;
+  font-size: 16px;
+  letter-spacing: 1px;
+  padding: 0 1.25rem;
+  border: 1px solid #a5a8a8;
+  border-radius: 6px;
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+  color: #454545;
+  vertical-align: top;
+}
+
+.topcoat-text-input:focus,
+.topcoat-text-input--large:focus {
+  background-color: #edf1f1;
+  color: #000;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-text-input:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input:invalid {
+  border: 1px solid #d83b75;
+}
+
+
+
+
+
+
+
+

Large Text Input

+
+




+
+ +
+
+

HTML

+
<input type="text" class="topcoat-text-input--large" value="" placeholder="text">
<br>
<br>
<input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
<br>
<br>
<input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
+
+
+

CSS

+

+.topcoat-text-input--large {
+  line-height: 4.375rem;
+  font-size: 1.3rem;
+}
+
+.topcoat-text-input--large:disabled {
+  color: #000;
+}
+
+.topcoat-text-input--large:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input--large:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input--large:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+.topcoat-text-input--large:invalid {
+  border: 1px solid #d83b75;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.textarea {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  vertical-align: top;
+  resize: none;
+  outline: none;
+}
+
+.textarea:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+/**
+*
+* Copyright 2012 Adobe Systems Inc.;
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+.textarea,
+.topcoat-textarea,
+.topcoat-textarea--large {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  vertical-align: top;
+  resize: none;
+  outline: none;
+}
+
+.textarea:disabled,
+.topcoat-textarea:disabled,
+.topcoat-textarea--large:disabled {
+  opacity: 0.3;
+  cursor: default;
+  pointer-events: none;
+}
+
+
+
+
+
+
+
+

Textarea

+
+


+
+ +
+
+

HTML

+
<textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
<br>
<br>
<textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
+
+
+

CSS

+

+.topcoat-textarea,
+.topcoat-textarea--large {
+  padding: 2rem;
+  font-size: 2.5rem;
+  font-weight: 200;
+  border-radius: 6px;
+  line-height: 3rem;
+  border: 1px solid #a5a8a8;
+  background-color: #d3d7d7;
+  box-shadow: inset 0 1px rgba(0,0,0,0.12);
+  color: #454545;
+  letter-spacing: 1px;
+}
+
+.topcoat-textarea:focus,
+.topcoat-textarea--large:focus {
+  background-color: #edf1f1;
+  color: #000;
+  border: 1px solid #0940fd;
+  box-shadow: 0 0 0 2px #6fb5f1;
+}
+
+.topcoat-textarea:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-textarea:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-textarea:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+
+
+
+
+
+
+

Large Textarea

+
+


+
+ +
+
+

HTML

+
<textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
<br>
<br>
<textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
+
+
+

CSS

+

+.topcoat-textarea--large {
+  font-size: 3rem;
+  line-height: 4.375rem;
+}
+
+.topcoat-textarea--large:disabled {
+  color: #000;
+}
+
+.topcoat-textarea--large:disabled::-webkit-input-placeholder {
+  color: #000;
+}
+
+.topcoat-textarea--large:disabled::-moz-placeholder {
+  color: #000;
+}
+
+.topcoat-textarea--large:disabled:-ms-input-placeholder {
+  color: #000;
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Regular.otf");
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Light.otf");
+  font-weight: 200;
+}
+
+@font-face {
+  font-family: "Source Sans";
+  src: url("../font/SourceSansPro-Semibold.otf");
+  font-weight: 600;
+}
+
+body {
+  margin: 0;
+  padding: 0;
+  background: #dfe2e2;
+  color: #000;
+  font: 16px "Source Sans", helvetica, arial, sans-serif;
+  font-weight: 200;
+}
+
+:focus {
+  outline-color: transparent;
+  outline-style: none;
+}
+
+.topcoat-icon--menu-stack {
+  background: url("../img/hamburger_dark.svg") no-repeat;
+  background-size: cover;
+}
+
+.quarter {
+  width: 25%;
+}
+
+.half {
+  width: 50%;
+}
+
+.three-quarters {
+  width: 75%;
+}
+
+.third {
+  width: 33.333%;
+}
+
+.two-thirds {
+  width: 66.666%;
+}
+
+.full {
+  width: 100%;
+}
+
+.left {
+  text-align: left;
+}
+
+.center {
+  text-align: center;
+}
+
+.right {
+  text-align: right;
+}
+
+.reset-ui {
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  background-clip: padding-box;
+  position: relative;
+  display: inline-block;
+  vertical-align: top;
+  padding: 0;
+  margin: 0;
+  font: inherit;
+  color: inherit;
+  background: transparent;
+  border: none;
+  cursor: default;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+}
+
+/* This file should include color and image variables corresponding to the dark theme */
+
+/* Call To Action */
+
+/* Icons */
+
+/* Navigation Bar */
+
+/* Text Input */
+
+/* Search Input */
+
+/* List */
+
+/* Checkbox */
+
+/* Overlay */
+
+/* Progress bar */
+
+/* Checkbox */
+
+/* Radio Button */
+
+/* Tab bar */
+
+/* Switch */
+
+/* Icon Button */
+
+/* Navigation bar */
+
+/* List */
+
+/* Search Input */
+
+/* Textarea */
+
+/* Checkbox */
+
+/* Radio */
+
+/* Range input */
+
+/* Search Input */
+
+/* Switch */
+
+/* This file should include color and image variables corresponding to the light theme */
+
+/* Call To Action */
+
+/* Icons */
+
+/* Navigation Bar */
+
+/* Text Input */
+
+/* List */
+
+/* Overlay */
+
+/* Progress bar */
+
+/* Checkbox */
+
+/* Range input */
+
+/* Radio Button */
+
+/* Tab bar */
+
+/* Switch */
+
+/* Containers */
+
+/* Icon Button */
+
+/* Navigation bar */
+
+/* List */
+
+/* Search Input */
+
+/* Text Area */
+
+/* Checkbox */
+
+/* Radio */
+
+/* Range input */
+
+/* Search Input */
+
+/* Switch */
+
+/* Text Input */
+
+/* Radio input */
+
+/* Overlay */
+
+/* Textarea */
+
+/* Progress bar container */
+
+/* Progress bar progress */
+
+/* Search input */
+
+/* Switch */
+
+/* Notification */
+
+
+
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/build/styleguide.css b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/build/styleguide.css new file mode 100755 index 0000000..bcbf2a8 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/build/styleguide.css @@ -0,0 +1,495 @@ +/*! +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +/* Styleguide CSS here pls ------------------------------------------------------------------------------- */ + +html { + height: 100%; + width: 100%; + position: absolute; +} + +body { + color: #444; + font: 14px "source-sans-pro", "source", helvetica, arial, sans-serif; + line-height: 21px; + margin: 0; + padding: 0; + -webkit-font-smoothing: subpixel-antialiased; +} + +.guides { +/* border: 1px solid red;*/ +} + +.space { + height: 90px; +} + +#container { + min-width: 600px; +} + +#test-container { + padding: 0 120px 30px 30px ; +} + +h1,h2,h3,h4,h5,h6 { + color: #000; + font-family: "source-l", helvetica, arial, sans-serif; + font-weight: normal; + margin: 0; +} + +h4 { + border-bottom: 1px solid #d7d7d7; + font-size: 30px; + margin: 20px 0; +} + +h5 { + font-size: 21px; +} + +h4 span { + background: #fff; + padding: 0 7px 0 0; + position: relative; + bottom: -10px; +} + +.tabular { + border: 1px solid rgba(0,0,0,0.09); + border-spacing: 0; + margin: 14px 0; +} + +th, td, .tabular td.var { + border-bottom: 1px solid #eee; + font-size: 15px; + font-weight: normal; + padding: 5px 10px; + text-align: left; +} + +th { + white-space: nowrap; +} + +.tabular tr:last-child td { + border: none; +} + +.tabular td { + font-size: 12px; + padding: 10px; +} + +.images { + width: 100% !important; +} + +.images td, +.images th { + border-right: 1px solid #eee !important; + padding: 18px; + text-align: center; + vertical-align: top; +} + +.images th { + padding: 9px; +} + +.images tr:last-child td, +.images tr th:last-child { + border-right: none !important; +} + +.images img { + width: 300px; +} + +header { + background: #3a3f42 url("../img/bg_dark.png") repeat-x; + bottom: 0; + cursor: default; + left: 0; + overflow-y: scroll; + padding: 0 0 30px 0; + position: absolute; + top: 0; + width: 220px; +} + +#main { + bottom: 0; + left: 220px; + margin: 0; + overflow-y: scroll; + padding: 0 100px 60px 40px; + position: absolute; + right: 0; + top: 0; +} + +header hgroup { + padding: 15px; +} + +header hgroup { + border-bottom: 1px solid rgba(0,0,0,0.36); + box-shadow: 0px 1px 0px rgba(255,255,255,0.11); +} + +header h1 { + color: #fff; + font-size: 18px; + text-shadow: 0 -1px 0 #000; +} + +header h2 { + color: #c7c7c7; + font-size: 12px; + text-shadow: 0 -1px 0 #000; +} + +header h3 { + color: #A4B4B7; + font-size: 14px; + text-shadow: 0 -1px 0 #000; + margin: 15px 0 5px 15px; +} + +header ul { + list-style: none; + margin: 0; + padding: 0; + width: 100%; +} + +header a { + box-sizing: border-box; + border-top: 1px solid rgba(0,0,0,0); + border-bottom: 1px solid rgba(0,0,0,0); + color: #bbb; + display: block; + font-size: 14px; + height: 24px; + line-height: 24px; + padding: 0 15px 0 30px; + text-shadow: 0 1px 0 #000; +} + +header a:link, +header a:visited { + color: #c7c7c7; + text-decoration: none; +} + +header .selected { + background: rgba(112,112,112,0.24); + border-top: 1px solid rgba(0,0,0,0); + border-bottom: 1px solid rgba(0,0,0,0); + color: #fff !important; +} + + +header a:hover { + background: rgba(112,112,112,0.24); + border-top: 1px solid rgba(0,0,0,0); + border-bottom: 1px solid rgba(0,0,0,0); + color: #fff !important; +} + +header a:focus { + border: 1px solid #0940fd; + -webkit-box-shadow: 0 0 4px #0088ff; + box-shadow: 0 0 4px #0088ff; + outline: none; + margin-left: 4px; + margin-right: 4px; + padding: 0 10px 0 25px; + background: rgba(112,112,112,0.24); + color: #fff !important; +} + +header a:active { + background: rgba(0,0,0,0.24); + border-top: 1px solid rgba(0,0,0,0.2); + border-bottom: 1px solid rgba(255,255,255,0.15); + color: #fff; +} + +h4:target span { + -webkit-animation: highlight 5s ease; + -moz-animation: highlight 5s ease; +} + + @-webkit-keyframes highlight { + 0% { color: #0083E8; text-shadow: 0 0 4px rgba(0,136,255,.69); } + 100% { color: #000; text-shadow: none; } + } + +.preview { + border-spacing: 0; + width: auto; +} + +.preview td { + padding: 15px 30px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.bg-light { + background: #f8f8f8; + border: 1px solid rgba(0,0,0,0.09); + font-size: 12px; +} + +.fonts.tabular { + width: 100%; +} + +.fonts.tabular th.bg-white { + border-bottom: 1px solid rgba(0,0,0,0.09); +} + +.fonts.tabular th.bg-lightgray { + border-bottom: 1px solid #bdbdbd; +} + +.fonts.tabular th.bg-slategray { + border-bottom: 1px solid #5c6061; +} + +.fonts.tabular td { + vertical-align: top; + width: 33%; +} + + +/* Selection ------------------------------------------------------------------------------- */ + +::selection { + background: #e0f0fa; + color: #000; +} + +header { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +/* Scrollbars ------------------------------------------------------------------------------- */ + +::-webkit-scrollbar { + height: 8px; + width: 8px; +} + +::-webkit-scrollbar-track { + background: rgba(0,0,0,0.1); + box-shadow: inset 0 0 6px rgba(0,0,0,0); + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0); + border-radius: 4px; + -webkit-border-radius: 4px; +} + +::-webkit-scrollbar-thumb { + border-radius: 4px; + -webkit-border-radius: 4px; + border: 1px solid rgba(255,255,255,0.15); + background: rgba(0,0,0,0.3); + box-shadow: inset 0 0 6px rgba(0,0,0,0); + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0); +} + +::-webkit-scrollbar-thumb:window-inactive { + background: rgba(0,0,0,0.1); +} + + +/* Scrollbars ------------------------------------------------------------------------------- */ + + +/* Container */ +.modal { + /* Overlay page content */ + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0,0,0,0.6); + z-index: 10000; + + /* Transition opacity on open */ + -webkit-transition: opacity 200ms ease-in; + transition: opacity 200ms ease-in; + + /* Hide for now */ + opacity: 0; + pointer-events: none; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +/* Show modal */ +.modal:target { + opacity: 1; + pointer-events: auto; +} + +/* Hide modal */ +.modal:active { + opacity: 0; +} + +/* Content */ +.modal > div { + width: 65%; + background: #fff; + position: relative; + margin: 10% auto; + + /* Default minimise animation */ + -webkit-animation: minimise 500ms linear; + + /* Prettify */ + padding: 12px 15px; + border-radius: 4px; + box-shadow: 0 15px 36px rgba(0,0,0,0.6); + background: #fff; + text-shadow: 0 1px 0 #fff; +} + +/* Override animation on modal open */ +.modal:target > div { + -webkit-animation-name: bounce; + -moz-animation-name: bounce; +} + +.modal h1 { + font-size: 24px; + padding: 0 0 10px; +} + +@-webkit-keyframes bounce { + 0% { + -webkit-transform: scale3d(1,1,1); + } + 55% { + -webkit-transform: scale3d(1,1,1); + } + 100% { + -webkit-transform: scale3d(1,1,1); + } +/* 0% { + -webkit-transform: scale3d(0.1,0.1,1); + box-shadow: 0 3px 20px rgba(0,0,0,0.9); + } + 55% { + -webkit-transform: scale3d(1,1,1); + box-shadow: 0 10px 20px rgba(0,0,0,0); + } + 75% { + -webkit-transform: scale3d(0.95,0.95,1); + box-shadow: 0 0 20px rgba(0,0,0,0.9); + } + 100% { + -webkit-transform: scale3d(1,1,1); + box-shadow: 0 3px 20px rgba(0,0,0,0.9); + } +*/ +} + +@-webkit-keyframes minimise { + 0% { + -webkit-transform: scale3d(1,1,1); + } + 100% { + -webkit-transform: scale3d(0.1,0.1,1); + } +} + +/* Modal close link */ +.modal a[href="#close"] { + position: absolute; + right: 0; + top: 0; + color: transparent; +} + +/* Reset native styles */ + .modal a[href="#close"]:focus { + outline: none; +} + +/* Create close button */ +.modal a[href="#close"]:after { + content: url("../img/close_modal.png"); + display: block; + + /* Position */ + position: absolute; + right: 15px; + top: 15px; + + /* Style */ + font-size: 12px; + text-decoration: none; + text-shadow: none; + text-align: center; + font-weight: bold; + background: #fff; +} + +.modal a[href="#close"]:focus:after, +.modal a[href="#close"]:hover:after { + +} + +.modal a[href="#close"]:focus:after { + outline: 1px solid #000; +} + +.modal a[href="#close"] { + text-shadow: none !important; +} + +/* Open modal */ +a.openmodal { + display: block; + text-align: center; +} + +a.openmodal:hover, +a.openmodal:focus { + +} \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/build/styleguide.js b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/build/styleguide.js new file mode 100755 index 0000000..67f89bf --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/build/styleguide.js @@ -0,0 +1,10 @@ +if (!document.querySelector('override')) { + var head = document.querySelector('head'); + var link = document.createElement('link'); + link.id = 'override'; + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = '../../release/css/' + location.href.split('/').pop().split('.')[0] + '.css'; + link.media = 'all'; + head.appendChild(link); +} \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/tasks/checkchromiumsrc.js b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/tasks/checkchromiumsrc.js new file mode 100755 index 0000000..6c472dd --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/tasks/checkchromiumsrc.js @@ -0,0 +1,13 @@ +var chromiumSrc = process.env.CHROMIUM_SRC; + +module.exports = function(grunt) { + + grunt.registerTask('check_chromium_src', "Internal task to store CHROMIUM_SRC env var into chromiumSrc", function() { + if (!chromiumSrc) { + grunt.fail.warn("Please set the CHROMIUM_SRC env var to the root of your chromium sources(ends in /src)"); + } else { + grunt.log.writeln("CHROMIUM_SRC points to " + chromiumSrc.cyan); + } + }); + +} diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrygentest.js b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrygentest.js new file mode 100755 index 0000000..2b0bb0c --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrygentest.js @@ -0,0 +1,98 @@ +var fs = require("fs"), + jade = require("jade"), + path = require("path"); + +module.exports = function (grunt) { + + var TELEMETRY_DIR = 'dev/test/perf/telemetry/perf/page_sets/', + MASTER_JADE = 'topcoat_telemetry.jade'; + + grunt.registerTask('perf', 'Generates performance test', function (platform, theme) { + + var perfJades = findAllPerfJadeFileInSrc(); + + var targetPlatform = platform || 'mobile', + targetTheme = theme || 'light'; + + var targetCSS = prepareCSS(targetPlatform, targetTheme); + + var jadeCompileData = {}; + + grunt.util._.forEach(perfJades, function (jadePath) { + + var jadeFileName = path.basename(jadePath).split('.')[0]; + + prepareJadeCompileData(jadeCompileData, jadePath, + jadeFileName, targetPlatform, targetTheme, targetCSS); + + createTelemetryJSON(jadeFileName); + }); + batchCompileJade(jadeCompileData); + }); + + var findAllPerfJadeFileInSrc = function () { + + var jades = grunt.file.expand('node_modules/topcoat-*/test/perf/topcoat_*.jade') + .concat('node_modules/topcoat-checkbox/test/perf/checkbox-test.jade'); + + if (jades.length === 0){ + throw new Error("ERROR: No jade file is found in src/../test/perf/"); + } + + return jades; + }; + + var prepareCSS = function(platform, theme) { + + return "release/css/topcoat-" + platform + "-" + theme + ".min.css"; + }; + + var prepareJadeCompileData = function (jadeCompileData, jadePath, + caseName, platform, theme, css) { + + var jadeContent = fs.readFileSync(jadePath, "utf8"), + getHtml = jade.compile(jadeContent); + + jadeCompileData[caseName] = { + options: { + data: { + platform: platform, + theme: theme, + css: css, + name: caseName, + componentHTML: getHtml() + } + }, + src: TELEMETRY_DIR + "topcoat/" + MASTER_JADE, + dest: TELEMETRY_DIR + "topcoat/" + caseName + ".test.html" + }; + }; + + var createTelemetryJSON = function (caseName) { + + var jsonContent = { + "description": "Test", + "archive_data_file": "../data/topcoat_buttons.json", + "pages": [ + { + "url": "file:///topcoat/" + caseName + ".test.html", + "smoothness": { + "action": "scrolling_action" + } + } + ] + }; + + var jsonFilePATH = TELEMETRY_DIR + caseName + '.test.json'; + + fs.writeFileSync( + jsonFilePATH, + JSON.stringify(jsonContent, null, 4), + 'utf8'); + }; + + var batchCompileJade = function(data){ + grunt.config('jade', data); + grunt.task.run('jade'); + }; +}; diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrysubmit.js b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrysubmit.js new file mode 100755 index 0000000..f9f6fb2 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrysubmit.js @@ -0,0 +1,101 @@ +module.exports = function(grunt) { + + grunt.registerTask('telemetry-submit', 'Submit telemetry test results', function(gitCWD) { + + var exec = require("child_process").exec, + commandToBeExecuted = 'git log --pretty=format:"%H %ci" | head -n 1', + done = this.async(); + + var part1 = { + properties: { + path: { + message: 'Path to telemetry output file', + required: true + }, + device: { + message: 'Device on which the test ran', + required: true + } + } + }; + + var part2 = { + properties: { + test: { + message: 'What is the name of the test?', + required: true, + default: '' + }, + type: { + message: 'Is it a test (nightly) ?', + required: true, + default: 'Yes' + } + } + }; + + exec(commandToBeExecuted, { cwd: gitCWD }, function(error, stdout, stderr) { + if (error) { + grunt.log.error('Error'); + console.log(error); + done(); + } else { + + var path = grunt.option('path') + , device = grunt.option('device') + , test = grunt.option('test') + // use env variables to overwrite the location + // where the test results end up, for CI example + , host = process.env.TOPCOAT_BENCHMARK_SERVER + , port = process.env.TOPCOAT_BENCHMARK_PORT + , type = grunt.option('type') + , date = grunt.option('date') + , snapshot + , submitData = require('../test/perf/telemetry/lib/submitData') + , fileName = require('../test/perf/telemetry/lib/extractFileName') + , prompt = require('prompt') + ; + + if (!path || !test || !device) { + // Dummy test to see if it was called without arguments + // in this case we request the user for data + + prompt.start(); + prompt.get(part1, function (err, result) { + var options = result; + + part2.properties.test.default = fileName(result.path); + + prompt.get(part2, function (err, result) { + for (var i in result) + options[i] = result[i]; + + if (options.type.match(/y/gi)) + options.date = 'snapshot ' + new Date().toISOString(); + else + options.date = stdout; + + submitData(options.date, options.path, { + device: options.device, + test: options.test + }, { + host : host, + port : port + }); + }); + }); + } else { + // This is in case for automated tasks that submits the data + submitData(stdout, path, { + device: device, + test: test + }, { + host : host, + port : port + }); + } + } + }); + + }); +}; \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/README.md b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/README.md new file mode 100755 index 0000000..0fc795e --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/README.md @@ -0,0 +1,79 @@ +Performance tests based on chromium telemetry (see https://github.com/topcoat/topcoat/wiki/Measuring-performance for details) + +# Preparing to run the tests +A few steps are required before you can run the telemetry tests. + +First of all, you need to download chromium source code locally, as described on http://www.chromium.org/developers/how-tos/get-the-code. No need to compile, just download it. +Then export the location for the 'src' folder in the CHROMIUM_SRC environment variable, like in +``` +export CHROMIUM_SRC = /Users/cataling/work/chromium/home/src_tarball/tarball/chromium/src/ +``` + +Then you need to manually patch a little bit two of the benchmark files (the patches are just one liners, it they get bigger we'll just duplicate the benchmarks in topcoat). Locate the files named `loading_benchmark.py` and `smoothness_benchmark.py` in `$CHROMIUM_SRC/tools/perf/perf_tools`. Inside, look for the method `MeasurePage`, and find an appropriate place to paste `results.Add("UserAgent", "", tab.EvaluateJavaScript("navigator.userAgent"));`. This makes the benchmarks include the user agent string as part of their output, and we need this info to submit the results to the server. + +NOTE: we should make a patch for these modifications + +Next you can prepare the telemetry tests: +``` +grunt telemetry +``` +This does few things: +* it generates html snippets based on grunt template from test/perf/topcoat-*.test.jade of each of Topcoat component. So make sure you build Topcoat first, by ```grunt default```, so that Topcoat components are downloaded into the src folder; +* then it uses that html snippet to generate the actual test file from topcoat/test/perf /telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade; +* last, it copies those test files to the right location in chromium telemetry tests. + +# Running performance tests locally +You can run a telemetry test with: +``` +cd $CHROMIUM_SRC/tools/perf +./run_multipage_benchmarks --browser=system loading_benchmark page_sets/topcoat_buttons-base.test.json -o /tmp/loading_benchmark_topcoat_buttons-base.txt +./run_multipage_benchmarks --browser=system smoothness_benchmark page_sets/topcoat_buttons-base.test.json -o /tmp/smoothness_benchmark_topcoat_buttons-base.txt +``` +We store the benchmark output in a file - the next script will take this output and push it to the server + +For steps of running performance tests on Android: +https://github.com/topcoat/topcoat/wiki/Running-TopCoat-Performance-Test-on-Android + +# Pushing benchmark results to the server + +There is a grunt task that automates the process `$ grunt telemetry-submit --path=test_results.txt --type=sha|snapshot [--device] [--test]` + +Device is an optional parameter and sets the device on which the test ran. +For `type snapshot` you have to send in a date param as well. You have to use: `date -u +"%Y-%m-%dT%H:%M:%SZ"` + +Type is either `sha` or `snapshot`. + + * `sha` is for running the tests on a stable version (in black) + * `snapshot` is for running custom nightly builds of topcoat (in red) + * ![x axis perf view](http://i.imgur.com/DrKxFlI.png) + +Test is an optional parameter and it overrides the default test name ( which is the name of the file from path ). + +There is a `settings.js` file located under `/test/perf/telemetry/lib/` where you can change the address where to submit. It is currently set for http://bench.topcoat.io/v2/benchmark + +If you set an `TOPCOAT_BENCHMARK_SERVER` and `TOPCOAT_BENCHMARK_PORT` env variables you can override the default settings. + +You can view the results at http://bench.topcoat.io + +# Running all tests +There's also a handy script to run all the performance tests and push the results on the server. +It's located at `https://github.com/topcoat/topcoat/blob/master/test/perf/telemetry/bin/runAll.py`. +Check out the script for details on how to run it. + +# Adding a new performance test +Before adding new tests, you should make yourself comfortable with the chromium telemetry framework and running telemetry tests in chrome. + +Topcoat performance tests are located in `test/perf/telemetry/perf/page_sets` (the folder convention matches the one from chromium telemetry tests). When building telemetry with `grunt telemetry` this folder is copied over `page_sets` in chromium src. There is one .json file that describes each test, its structure is as required by chromium telemetry framework. You will need to add a new json file to describe your test - just start from an existing ones. + +The files for the tests are located under the `topcoat` folder. You can either add html file directly, or use jade. Jade files are converted to html when you run `grunt telemetry`. The html files will be generated under `page_sets` in chromium src. Currently, if you're adding a jade file you need to manually add it to `Gruntfile.js` (just look up where topcoat_buttons.jade is added). If future we'll get rid of this. + +Inside the test files (html or jade) you can reference the topcoat assets (css, fonts, images) under "./release/". The whole `./release` folder under topcoat root and all the components are copied there by `grunt telemetry`. + +In the json file you can reference the test file to load using `file:///topcoat/` URLs. Use .html here even if you use .jade for tests - you want to reference the generated html file, not the jade template. When running the tests, telemetry will instantiate a local HTTP server and rewrite the URLs, they will not be loaded with the file protocol. + +From telemetry we're currently using loading and smoothness benchmarks. The runAll.sh script currently runs these two benchmarks on all the .json tests under page_sets. + +Note 1: runAll.py uses CEF ([chromium embedding framework](https://code.google.com/p/chromiumembedded/)) to run the tests on desktop (Win and Mac) by default. This is because the target for TopCoat are web applications, not web sites, and CEF is the preferred way to develop web applications on desktop. +We're currently using a custom CEF build because telemetry does not work in CEF by default. A patch has been submitted to CEF upstream (https://code.google.com/p/chromiumembedded/issues/detail?id=917&sort=-id) to fix this. + +Note 2: part of this will probably change when we switch to the new components/themes architecture. diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.py b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.py new file mode 100755 index 0000000..3dd8aba --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.py @@ -0,0 +1,200 @@ +# Copyright 2012 Adobe Systems Inc.; +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Runs all the telemetry tests and pushes results to the server +# +# Make sure to run in from its folder! +# +# Env vars used: +# - TestHelper.CHROMIUM_SRC: path to chromium src +# - DEVICE_NAME: a label to identify the machine running the tests when submitting results +# - CEF_HOME: path to CEF binaries (needed only if USE_CEF is set to True) +# - USE_CEF: if run with CEF, set this to 'True' +# + +import os +import sys +import shutil +import subprocess +import glob +import platform +import shutil + + +class TestHelper(): + GRUNT = "grunt" + RESULTS_DIR = "/tmp/topcoat-telemetry" + BROWSER = "system" + BROWSER_EXEC = None + SUBMIT_TYPE = "SHA" + + CHROMIUM_SRC = os.environ.get("CHROMIUM_SRC") + DEVICE_NAME = os.environ.get("DEVICE_NAME") + CEF_HOME = os.environ.get("CEF_HOME") + USE_CEF = os.environ.get("USE_CEF") + + @staticmethod + def init(targetPlatform, targetTheme): + TestHelper._checkEnvVars() + TestHelper._prepareProperties() + TestHelper._prepareResultsDir() + TestHelper._cleanTelemetryTests() + TestHelper._prepareTelemetryTests(targetPlatform, targetTheme) + + @staticmethod + def _getPlatform(): + p = platform.platform().lower() + if p.find('windows') != -1: return "Win" + if p.find('darwin') != -1: return "Mac" + if p.find('linux') != -1: return "Lin" + + @staticmethod + def _checkEnvVars(): + if not TestHelper.DEVICE_NAME: + raise RuntimeError("Please set DEVICE_NAME env var (no spaces allowed yet)") + + if not TestHelper.CHROMIUM_SRC: + raise RuntimeError("Please set CHROMIUM_SRC env var.") + + if not TestHelper.USE_CEF: + raise RuntimeError("Please set USE_CEF env var.") + + if (TestHelper.USE_CEF == 'True') and (not TestHelper.CEF_HOME): + raise RuntimeError("Please set CEF_HOME if you set USE_CEF to True") + + @staticmethod + def _prepareProperties(): + p = TestHelper._getPlatform() + + if p == "Win": + TestHelper.GRUNT = "grunt.cmd" + TestHelper.RESULTS_DIR = "C:\\tmp\\topcoat-telemetry" + TestHelper.BROWSER = "exact" + TestHelper.BROWSER_EXEC = "%s\\app\\cefclient.exe" % TestHelper.CEF_HOME + + if p == "Mac": + if TestHelper.USE_CEF: + TestHelper.BROWSER = "exact" + TestHelper.BROWSER_EXEC = "%s/app/cefclient.app/Contents/MacOS/cefclient" % TestHelper.CEF_HOME + + if p == "Lin": + TestHelper.BROWSER = "android-chrome-beta" + + @staticmethod + def _prepareResultsDir(): + print "runAll.py: Preparing results dir %s" % TestHelper.RESULTS_DIR + if os.path.isdir(TestHelper.RESULTS_DIR): + shutil.rmtree(TestHelper.RESULTS_DIR) + os.makedirs(TestHelper.RESULTS_DIR) + + @staticmethod + def _prepareTelemetryTests(targetPlatform, targetTheme): + print "runAll.py: Preparing telemetry tests" + subprocess.check_call([TestHelper.GRUNT, 'telemetry:'+targetPlatform+':'+targetTheme]) + + @staticmethod + def _cleanTelemetryTests(): + print "runAll.py: clean up CHROMIUM_SRC/tools/perf/page_sets/topcoat" + path = TestHelper.CHROMIUM_SRC + "tools/perf/page_sets/topcoat" + if os.path.exists(path): + shutil.rmtree(path) + + @staticmethod + def runTests(user_defined_test_list, how_many_rounds_to_run_the_test): + print "runAll.py: Running telemetry tests, results in %s" % TestHelper.RESULTS_DIR + + telemetry_tests = ["loading_benchmark", "smoothness_benchmark"] + + if user_defined_test_list and len(user_defined_test_list) != 0: + topcoat_test_files = user_defined_test_list + else: + topcoat_test_files = glob.glob(os.getcwd() + "/../perf/page_sets/*.json") + + def genCmd(): + cmd = [ + "python", + TestHelper.CHROMIUM_SRC + "/tools/perf/run_multipage_benchmarks", + "--browser=" + TestHelper.BROWSER, + telemetry_test, + TestHelper.CHROMIUM_SRC + "tools/perf/page_sets/%s" % topcoat_test_file, + "-o", TestHelper.RESULTS_DIR + "/%s_%s-%s.txt" % (telemetry_test, topcoat_test_name, test_round) + ] + if TestHelper.BROWSER_EXEC: + cmd.insert(3, "--browser-executable=" + TestHelper.BROWSER_EXEC) + return cmd + + for tf in topcoat_test_files: + topcoat_test_file = tf.split(os.sep)[-1] + topcoat_test_name = topcoat_test_file.split(".")[0] + print "runAll.py: Running tests for %s" % topcoat_test_name + + for telemetry_test in telemetry_tests: + for test_round in range(how_many_rounds_to_run_the_test): + cmd = genCmd() + subprocess.check_call(cmd) + + @staticmethod + def submitResults(git_cwd): + print "runAll.py: Pushing telemetry data to the server" + result_files = glob.glob(TestHelper.RESULTS_DIR + "/*.txt") + for rf in result_files: + subprocess.check_call([ + TestHelper.GRUNT, + "telemetry-submit:" + git_cwd, + "--path=" + rf, + "--device=" + TestHelper.DEVICE_NAME, + "--test=" + rf.split(os.sep)[-1][:-6], + "--type=" + TestHelper.SUBMIT_TYPE + ]) + + +if __name__ == "__main__": + + # Usage: + # ./python runAll.py --platform=VALUE --theme=VALUE [--gitCWD=VALUE] [--test=VALUE] [--round=VALUE] + # --platform= desktop or mobile + # --theme= light or dark + # [optional] --gitCWD=PATH_WHERE_YOU_WANT_TO_RUN_GIT_LOG, e.g. src/skins/button + # [optional] --test=ONE_OR_MORE_TESTS_YOU_WANT_TO_RUN, e.g. topcoat_button.test.json + # [optional] --test=HOW_MANY_ROUNDS_TO_RUN_THE_TEST, default is 1. + + platfrm = theme = git_cwd = test_list = None + test_round = 1 + + args = sys.argv[1:] + + for arg in args: + arg_key, arg_val = arg.split('=') + if arg_key == '--platform': + platfrm = arg_val + elif arg_key == '--theme': + theme = arg_val + elif arg_key == '--gitCWD': + git_cwd = arg_val + elif arg_key == '--test': + test_list = arg_val.split(',') + elif arg_key == '--round': + test_round = int(arg_val) + else: + print "%s is not recognized." + + if not platform or not theme: + raise RuntimeError("ERROR: --platform and --theme must be set.") + + if not git_cwd: + git_cwd = '' + + TestHelper.init(platfrm, theme) + TestHelper.runTests(test_list, test_round) + TestHelper.submitResults(git_cwd) \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.sh b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.sh new file mode 100755 index 0000000..aa088c0 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.sh @@ -0,0 +1,105 @@ +#!/bin/sh +# Copyright 2012 Adobe Systems Inc.; +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Runs all the telemetry tests and pushes results to the server +# +# Make sure to run in from its folder! +# +# Env vars used: +# - CHROMIUM_SRC: path to chromium src +# - DEVICE_NAME: a label to identify the machine running the tests when submitting results +# - CEF_HOME: path to CEF binaries (needed only if USE_CEF is set to True) +# + +RESULTS_DIR=/tmp/topcoat-telemetry +USE_CEF=true + +function checkEnvVars() { + if [ -z "$DEVICE_NAME" ] + then + echo "Please set DEVICE_NAME env var (no spaces allowed yet)" + exit 1 + fi + + if [ -z "$CHROMIUM_SRC" ] + then + echo "Please set CHROMIUM_SRC env var" + exit 1 + fi + + if ($USE_CEF) + then + if [ -z "$CEF_HOME" ] + then + echo "You need to set CEF_HOME if yout set USE_CEF to True" + exit 1 + fi + fi +} + +function prepareResultsDir() { + echo "runAll.sh: Preparing results dir $RESULTS_DIR" + rm -rf $RESULTS_DIR + mkdir $RESULTS_DIR +} + +function prepareTelemetryTests() { + echo "runAll.sh: Preparing telemetry tests" + grunt telemetry +} + +function runTests() { + echo "runAll.sh: Running telemetry tests, resuls in $RESULTS_DIR" + + if ($USE_CEF) + then + browserParams="--browser=exact --browser-executable=$CEF_HOME/app/cefclient.app/Contents/MacOS/cefclient" + else + browserParams="--browser=system" + fi + + testFiles=$(ls ../perf/page_sets/*.json); + + currentDir=`pwd` + cd $CHROMIUM_SRC/tools/perf + + for test in $testFiles + do + testFileBaseName=$(basename $test) #ends with .json + testName=$(echo $testFileBaseName | cut -d '.' -f 1) + echo "runAll.sh: Running tests for $testName" + ./run_multipage_benchmarks $browserParams loading_benchmark page_sets/$testFileBaseName -o $RESULTS_DIR/loading_benchmark_$testName.txt + ./run_multipage_benchmarks $browserParams smoothness_benchmark page_sets/$testFileBaseName -o $RESULTS_DIR/smoothness_benchmark_$testName.txt + done + + cd $currentDir +} + +function submitResults() { + echo "runAll.sh: Pushing telemetry data to the server" + + for resultFile in $RESULTS_DIR/* + do + grunt telemetry-submit --path=$resultFile --device $DEVICE_NAME + done +} + + +checkEnvVars +prepareResultsDir +prepareTelemetryTests +runTests +submitResults + diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/csvToJSON.js b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/csvToJSON.js new file mode 100755 index 0000000..b5d0594 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/csvToJSON.js @@ -0,0 +1,56 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +"use strict"; + +var parseCSV = function(file, cb) { + + var fs = require('fs') + , filename = file + , csv = require('csv') + ; + + var header = []; + var values = []; + var json = {}; + + csv() + .from.stream(fs.createReadStream(file)) + .transform(function(row, index){ + //in case there are blank lines in between key & value on Win7 + if (row[0] == ""){ + return null; + }else{ + return row; + } + }) + .on('record', function(row,index){ + if (index === 0) + header.push(row); + else + values.push(row); + }) + .on('end', function(count){ + header[0].forEach(function (h, idx) { + json[h] = values[0][idx]; + }); + cb(json); + }) + .on('error', function(error){ + console.log(error.message); + }); +}; + +module.exports = parseCSV; \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/extractFileName.js b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/extractFileName.js new file mode 100755 index 0000000..f3446e5 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/extractFileName.js @@ -0,0 +1,12 @@ +var extractFileName = function (path) { + if (path.split('/').length > 1) { + sep = '/'; + } else if (path.split('\\').length > 1) { + sep = '\\'; + } else { + throw new Error('ERROR: the separator in test result file path is neither "/" nor "\\".'); + } + return path.split(sep).pop().split('.')[0]; +}; + +module.exports = extractFileName; \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/settings.js b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/settings.js new file mode 100755 index 0000000..b701064 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/settings.js @@ -0,0 +1,31 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +function settings (contentLength) { + var post_options = { + host: 'localhost', + port: '3000', + path: '/v2/benchmark', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': contentLength + } + }; + + return post_options; +} + +module.exports = settings; diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/submitData.js b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/submitData.js new file mode 100755 index 0000000..d3f732d --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/submitData.js @@ -0,0 +1,61 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +var submitData = function (stdout, path, args, destination) { + var querystring = require('querystring'); + var http = require('http'); + var fs = require('fs'); + var parse = require('./csvToJSON'); + var postOptions = require('./settings'); + var fileName = require('./extractFileName.js'); + + var post_data = {}; + console.log(path); + parse(path, function (j) { + post_data = { + resultName : j + }; + + var version = stdout.split(' '); + + post_data.commit = version.shift(); + post_data.date = version.join(' '); + post_data.test = args.test || fileName(path); + post_data.device = args.device || 'device?'; + post_data = querystring.stringify({data : JSON.stringify(post_data)}); + post_options = postOptions(post_data.length); + if (destination.host && destination.port) { + var location = destination.host.split('/'); + + post_options.host = location.shift(); + post_options.port = destination.port; + } + // Set up the request + var post_req = http.request(post_options, function(res) { + res.setEncoding('utf8'); + res.on('data', function(chunk) { + console.log(chunk); + }); + }); + + // post the data + post_req.write(post_data); + post_req.end(); + + }); + +}; + +module.exports = submitData; \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade new file mode 100755 index 0000000..c38b00f --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade @@ -0,0 +1,17 @@ +repeats = 200 + +doctype 5 +html + head + meta(charset="utf-8") + meta(name="format-detection", content="telephone=no") + meta(name="viewport", content="user-scalable=no, initial-scale=1, maximum-scale=1, width=device-width, height=device-width, target-densitydpi=device-dpi") + + title #{name} test + | + + body + -while (repeats > 0) + -var repeats = repeats - 1 + p + | !{componentHTML} diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/LICENSE.txt b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/LICENSE.txt new file mode 100755 index 0000000..d154618 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Black.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Black.otf new file mode 100755 index 0000000..ba47f3d Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Black.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Bold.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Bold.otf new file mode 100755 index 0000000..b8a2f57 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Bold.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-ExtraLight.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-ExtraLight.otf new file mode 100755 index 0000000..5cb8e5f Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-ExtraLight.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Light.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Light.otf new file mode 100755 index 0000000..e3c0a74 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Light.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Regular.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Regular.otf new file mode 100755 index 0000000..40208be Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Regular.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Semibold.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Semibold.otf new file mode 100755 index 0000000..65b82d1 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Semibold.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Black.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Black.otf new file mode 100755 index 0000000..13338c2 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Black.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BlackIt.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BlackIt.otf new file mode 100755 index 0000000..f5a7490 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BlackIt.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Bold.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Bold.otf new file mode 100755 index 0000000..8998f3d Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Bold.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BoldIt.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BoldIt.otf new file mode 100755 index 0000000..071d0c3 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BoldIt.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLight.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLight.otf new file mode 100755 index 0000000..43e0c69 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLight.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLightIt.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLightIt.otf new file mode 100755 index 0000000..01ac876 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLightIt.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-It.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-It.otf new file mode 100755 index 0000000..51577d6 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-It.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Light.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Light.otf new file mode 100755 index 0000000..9d8fb28 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Light.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-LightIt.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-LightIt.otf new file mode 100755 index 0000000..e03c41c Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-LightIt.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Regular.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Regular.otf new file mode 100755 index 0000000..7b6fa55 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Regular.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Semibold.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Semibold.otf new file mode 100755 index 0000000..6b39aa4 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Semibold.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-SemiboldIt.otf b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-SemiboldIt.otf new file mode 100755 index 0000000..8a668e4 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/font/SourceSansPro-SemiboldIt.otf differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/avatar.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/avatar.png new file mode 100755 index 0000000..c3a1306 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/avatar.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/bg_dark.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/bg_dark.png new file mode 100755 index 0000000..e44a7c4 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/bg_dark.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/breadcrumb.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/breadcrumb.png new file mode 100755 index 0000000..b2cf4f3 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/breadcrumb.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_checked.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_checked.png new file mode 100755 index 0000000..daaa1a8 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_checked.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_checked_dark.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_checked_dark.png new file mode 100755 index 0000000..777ddcf Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_checked_dark.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked.png new file mode 100755 index 0000000..4ef08dd Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked_dark.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked_dark.png new file mode 100755 index 0000000..3f5e6c9 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked_dark.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkmark_bw.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkmark_bw.svg new file mode 100755 index 0000000..f737096 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/checkmark_bw.svg @@ -0,0 +1,15 @@ + + + + + + +]> + + + diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg.png new file mode 100755 index 0000000..9a4e92d Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg2x.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg2x.png new file mode 100755 index 0000000..7ab0c5a Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg2x.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-grips.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-grips.png new file mode 100755 index 0000000..c52325d Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-grips.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-sprites2x.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-sprites2x.png new file mode 100755 index 0000000..f9a875b Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dark-sprites2x.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dialog-zone-bg.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dialog-zone-bg.png new file mode 100755 index 0000000..6dd0ff8 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/dialog-zone-bg.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/drop-down-triangle-dark.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/drop-down-triangle-dark.png new file mode 100755 index 0000000..9af2042 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/drop-down-triangle-dark.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/drop-down-triangle.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/drop-down-triangle.png new file mode 100755 index 0000000..cb1c968 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/drop-down-triangle.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/hamburger_bw.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/hamburger_bw.svg new file mode 100755 index 0000000..c08ff01 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/hamburger_bw.svg @@ -0,0 +1,1912 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + eJzsvemOJMmRJvgE9g6+PxogB1NBU1PTw7iDBcLj6OEM2V0g2ceiMSgks6LJnM6jkJVFLvfpV75P +RFTV3D2yIo8iie0KrcoIF1dTM9NDVI5PRP/u//jyN19cf/3mdw9fxKv5MP3d3928fXj27s3bnx9I +Pfzi5cvvvn33FqSf/Pqnh5CvZql0/Yv6lVX854e337548/rn/Ooqypf3uPonv/j22e8eXr58OPzy +2euv3/3h2cuHtz89/OSn8v1vX7x7+SA1/vDs1e++e/v7h7dX3/7x9z/1W0tbt8/eyffrz5afhXhY +fj7Hw5e/wtfPXv/x2bffvvh/H3CzWHGv45vvXn/94vXvj2/+HyEevojrIW6HL4p89d9f/Prh2/d8 +f/vm+XevHl6/+/Ltm+cP33578+blm7ff/vxw8+dnrw+/evZ7+ebZ4f+WN3jzp8Px5bPn/zHJW6ev +7l+8fJAXfPXs3SEs6IvrX4Tlq+N3L15+/Q/fvfrdg7x63kiOX7HJf/pW2pJm8TfI5atfvBLKbx7e +vZPnkhuiP3/998fxMYTI8pN/+/XD71+w+6Vb/tdPrdm3b7559eztf+DawxfrfJD/7I6/fXj1zUvp +Pb7uMl+lwxf8t/9p9eQtWOeLJVfplZIPca6HmKp+3/vm4Y8vHv7088M/vHn9oB1w/fbdb3QI1nWe +9V/95tffyRj/0+sX7+TBMkib9sCv3nz98FLqt+vvXz7ji7OE/q9W+O0zmRPvZOzevPzuHWdW9TtI +D//y2Z8fMExBb/CP3zy8/u2bf+YzfrEEaWfZrrbDssobhWVbD6Gy/QWPus3tnqH/q02jITTj7WOG +fCnj9I9vX/z+xeuffxGr9HVcZh3Cv3/74us+guFQ7X9p/KoO/2/+vz6tvPi7dw+v7ell3tz8apgH +89WvfiN3vXv99c2bV+j9bzHBZQK8lrnx8s3v9bv2N7+Ry7/7Rt+An7+Sgfry7YvXaHP6B35Tv/ry +5Xfy1d+/ffPdN794/e9vpp/o0v7nh+eyfmUsvz784+/+t3yQ9cm5efjt22fPpQH53OpcPXvxzU/f +25y83NuHg34pV/Kj//7+q28f/l1WVb9cqXev//jw8s03Q7ONIlzl8C/P3n7z/U1/+fLZ62dvD6S3 +ln/54o/yzTPpqd52pz2hUZkl30jn8BJWObnBeyoMXz3hRs/e/UEY0MPrr79tbevH/YMr7fvb+81z +zMG3h+Pb7779w+G3b968bM3uv2qtG5lU1P/buMeXvOD1P77WDjq/k1U4vZPwn7+5u0jtx+8gX/4t +t37z7OXLF79/++ybP7x4fukGF75vd9LvPmRi/fnV7968fPHtqz6fBsqXz96+e/H85cNv/vztu4dX +Tx7cw93XL4TJPbKM31vnN3969u75H3754ndvn7198fDe1YcB+PcXr7+Wuf+b7168e+gd9ObVN5BS +Dr/5w7NvHvga7/5wz5q/aQ2mr4T1j8z9iy/ew/VDPhxfD9///dtnX7+QDUWErr9/8/Lrh9eHX4O9 +T7tPsn2Vw/Hr6d+m2UpgWQ9/99Xx7fTfpvn0J5yUZSjRymol8X8vGf9P8msspZU6b7tyPZSjlBsr +t0O5m++n+d7L7sHGn2UocSjrriQtE3+VkKUU/q5D2XblOhxbuWnlGG6l+KfbST7ckXQb7scydh0f +zn/iUNahpCWjTPprKUOpyyZF/70eylHL9H9dGsvHRjPuxnMdRrWPrZSpDe86DLKO6ji6VQp+Y1Tr +bny3YYTl38mG2gf72IZZf2OU78bRln/1Z7441su0G+go44rfGFmMcWapHOVyMsLXVvZjK2OJX3cs +tyej6DeNHMM+Zig6SD5kmw2WDNBkY4SxurFyy3Jn5R7FVxZeZhzLwFFareMrO/TIRXLPvln48pmv +t/FVbvnEwZ4wc8rII0y8L+6zxBjXmGMRZWuLRym38V5GO6xxXde0lrWu23q9Htfb9W69l45cUkxr +yqmkLV2nY7pJd+l+kgcKMkvXnHLONW/5Oh/zTb7N9zIXgnTDWlLJpZatHMtNuS33Mk9CXepaU821 +1K1e12O9rXf1XubLMm1xWzdpZ6vbth23m+1uu5dJE67j9XqdrvN1vd6ur6+PUm6ub6/vOJMWeYH1 +mI7lWI+bfHU83hzvjvcyu8LE3o436026kQe42W6ub443Nze3N/cy2QJHYb1Nt/lWHu623m63x9ub +27vb+7tZxiXerXf5rtzVu+1O7nV3c3c73d3d3WNG3EuH3ad7edN7efb7aylyy3u58v7kR8ZyltFs +n++GcjuUm6Ecd+V6KJuXSf6pQylDybuShrIOJQ5FJuB0v7QysrDOfOfx0e/Gn9tdudEy8ddxKNdD +2XalDqUMJQ8lTXeplXVX4lCWoYShzGPRLp+s78enH39uhnLUwpW5G8f96O3HzEdrP0T7YZGhmIbR +2A/BvuP33W3dfNK37M+pdem+I/e9t++xk37ad8100iPaG9dWNpZqpVjJLMnKyhKtLBPXnm2Zyvrb +9Pc303v5z5Hl2srGUq3I2p7kn2wlWVlZohVlvc7ohYP6WN5x/I4cr8rxSRwQDMLMbr9lN1+zVwv7 +cWW/BfbTHTvmyI6oE9888V3xgjNf6JYvcM1HLnzClU8kzyGz5U4680b41rXwryp8LAs3W4WrLcLN +50km0p308o0wvWthf/W6CCNMwhCj7ChBdth7GfFb6Y7jdi1ss25FGGgSRhplCwqyH9/LRLiVbjoK +t91qnYTxZmHAa43CioNs3PcyQ26lD4/lWlh1LUWYdhLmHYWFB9no72Xu3ErHHoXBb8Loi7D7JGw/ +CvMPeZ5kGt/JGN/IxnAtG0SVbSKnJBtGlI0jiOxwL9PtVsbiKJvKJptLWbNsM6tsN4tsOrPM+zuZ +FTeyEV3LhlQn2ZlyTLJHRdmrgsgq9zJDb2X4sItiW8VGm2Rzw0YcljmAyzaB1mqhntdiPVlQuqlD +fsPOv1EyUElBZAfOh0dux2bYgF/eL4bYsXTGcD+wemUJm0yqJBMqyGS6NJUW2yO4++BHd6DAdYld +KHH1+k5kexG2ItltRAjgvbHftc0uyyyrF7a72LY7bHbXuCEvbhJDNBm0uNRAoeGOYkMwwSE10eF6 +7Hb0AuS0+V6blA8U5m75EatF14pviG0X5fd8c761DsM1pZK7uBtZioShCT0q4ango5LcDQXxO2k6 +mJCtr+NSs0nJVCvYlDfUm2Ej7A29+GJP6COPA6WDtBMWKClEGfkiM+DIuXAiHXhXJNsAnOOMPKdP +lc53Rs5D3qNdfIEd7bnR9/Ei7fqT1fjJi/HYxF8vXZGpOxWnmNqjJe00I9OWJvvDf1Qg3+moexXM +95imoDVJn+U47RS7G0rQrhTg93ZS6knpSqT+lSdXM1tZz0o8K8uFYj/TTtM9U+iw4kYhrf2+vViE +T0xN074xZeyo2tnFsj1aqut906Dka8lPLF2lTGOZ9h+bsaH/fV7iI4WTYpqXJ5ZLHXyhTE+s+OSf +S7r7J/18tgZ9XwytR1VGdTH71opKWG6UcCNFNV3YjRi20idTm315u1mkT//T1ewSqq/eccEedR27 +Sn++WkszAWQrqRkIum0ojgt0+v6VKX81s0Q3T50sR1+Qt9Ng1BqNXMeLy/G4M42dL0gzppyuz7qz +snXrjFtoLi3R9nk6W5mni/B8Ub63TGcGw0sr9X3r92R5ToMN8pPX8PvW8V9/2X32Bi+JqKP2c67/ +qDxyrv+4FDJDh76jtLGZ5pdN3lia9nM/SBxlJ3EsgwZ0IzoQNaBJVCAoQaoCQQmaqQGpDnRD44/q +QbXpQdH0IGhCN6IFHakHVZqS1omqUODiuKdWfIs7yPVVNCHVhaANLaoNUR+6NX3oSH2oUh+CRgTO +FSZTiu6p4UItUsUIqlGlagTlaKVyFLiU7qkh3VBDgo4ELanIXVFVFKFJFKVIdhhomrmjunQr6hIU +JqhMUJqgNpU1UXGC6hTJqWaqT/emWB+1TCK3QXKD7FYov2XUj/gJlJ86F4dMq2PRpTSVzCoVKJR1 +apz6TOoaZCy3pOrvkQGPIhLloWkQgnZM9Yxx7iSXHY/cccRpJ5OgnPC2i2ztPRLEucTwNDbxKPv4 +nOvYtEUto5lq/Nmb5QZT494W5vvqZH8suxJ3ZW92Sycl70qZdqa8sjPyVSpK+3J9Uo6nZWo2Ly+3 +Z+X85/68+Bybxp36Plwoy8USLxaz5J2X9EjJj5Zmy512ht1Cc/P7yvY95XramZMvl+MTC5n7tLNc +v6/cPq1MF4iXBvHJZXr0q4/8Od9EP7YhM9zMTf1czGOhZbWi5kw3bxYrbv3crJhtdDJTqf84b+jL +xsfDOauryC7Ju5VWbbbrRKORltyKm3lrK5uV61aOF3iU/ExnDOoSa+qm+8vcaOBD0yNM6DHu8xjX +GTjNkTacx3nNe3jMjqkYY5ney1MucJLvYyHT+/nGE1jGCWuYRi7x0axhWO+PMYYnsoHzlf/4On5/ ++Qut4w+yoe6sqCKy3aixk05YyFlxXSeR9PLgiz0KJ1B/7GweWfhkE72yVQRK98zewjcrm4s6ZyNF +UThoy0T51L208NPe0VOrvtoI6ZL+WvzAZ3tNARh+Wywg9d3CewvBkh7ciU7cCkmbjtyjcKPb5s6d +RfyDJAmf7iqPBwm5UCzfRES/pn/3RvjFnXl55+swiRy/UJ6HuxcO33xdKOlvg+OXrl8pmI4QBAMN +jJFuYDiCIZAXuoPrdNzoE1av8A15EZb2Pf3Dc2O5zmydzTp77WzVOOrUWGlnoc46O9PsvLLzyM4b +R454OzU+OPK/zvf2vG5kcSNbG5jZNPCxPes6YVYXJJ9zfjTINJfllse4zInYMZbpfVzje9nEEzf4 +j13HZrj+t2kEFYfDIn/lQ52vVlkuhxKvZIEsqPqb6e++ekrV47fnLV4lqZjmQw1XogfmR5s7rYe2 +rkIu2xrkywDtdnGUcqp1WeWPkhb7egkpbwdU0EaWqzintd3skxvi08yimaYstWZZ5BnXiXItyjfb +2tY0b8ROC1Nck/yx4HcY2opXs7CV/lCfqT19tjwLQ0VbKcyp8LoqjFjbEhWxavuLcFS0JeOWtl1b +aZ634dk+T3sfP4pLuaoxbmipprJ94lCetnZhptqTb9uV8PPHpum+krRyvG0QR0cqXgYv/uPb5394 +8fVPJ/8DwP4GWbzKOcg+iXGMSymZAEZZXOxefI2R3y1bu+LgV2gcgl1xsCtsmcoDi7I+vNJHXKwd +9tQL0U1rvooR0/sjbry//kO6+Tf/8WfpY/wrF67awf/N959723UW22+S+TOL7S7XtqHcjo5n2yxW +w0LJbkBJSPaCYDivlSICkF5Higb3tAqpSJApDFxTDLjjLgGgF/Z93fOvae27PQU2KojRPUJq31Yz +Ofbi2QCg6tJ1BCe9wg0Ulx7DSl76eRwNOxqvkxllaCVU5ASxEw09cWooLIaiUByFIQ== + + + KWgqvDMwxU1St+774SEDOuRJ2JDRN9sEoWDQgRE80OEDNyrtDBCCtUk3m8MIbnWcIMYakhDSa3UU +IWVWxRBWyqmQTyGdJukHiKQ3MtlmiqHJAIO3Rf3j6FbDXXTkxQ64YbbDuXk9b2gdVHNgMbPfah6D +YIbwJwNmnoSWUUBAN3+rw31RbJNhmm4bjuna0EtuDk8GU1J40kyh6G7nRR+Aog0qquZT9YfHplUk +ahaZ2kWhhlFpDb6mnnGkYeF2olh5T4WjqxyK/sS4qd6hmkfXPah9GB5UEaHQP6CB5IlKSKUS4mrI +7U4VOVFGTBfB0DtqlPqIayTTiUqCObEZkPSGUvVdg5MuVEgcVDpqJDfUSO4gkE6mkMRBISmmjByp +jNxSGVHAaddD1kEPgQ7StJCJNo6uhpwrIskUEaoiTQ85UhehJqJ8yAB3hn8eQIr0FJ7/fdf+3lPN +aj4ZjFo+mC/yrnsl/a/xdwNZj6B6NcgbxDo0C31sCPv+O+5+r8Z+HY6dGu5ejf/CFacd8t7x98X+ +Va+B/qvO3P7v9c7HcGtQbcPfE/gDR/GA1e5I7WgujGxY7Wy+aPV0dFA9/SDTgM/uS64vtUhAzOky +44whcEZW//v3mNFHcOoveMy7YN7K0cUQmltidFCcO0TPfaqrezlOHbHnn8bfp3+PtOQRAz00ZH0U +u/E4siPu/o7T8GE9cdmMjpzLPuv+ffNgT2e+Hu277lLuvdp7uA9C98DskKnHC8jUYqDUDkd1IKpB +UJXTc4eXPX4ib7jmRq9bfaExI5GfRNvyddPfu0Svm0u0kFmZW3SiFNB9o7d8ON32dOPzra9tfm37 +8w2QmFFugrINTrYPjjvhuBeO2NE9enSPH20I0kkFH/OQnmJIH0ORvgdHOg3QtY8CrwXlyudo8aF8 +P2C8W77NFj41nPQ5Uro0o/oeLT3gpa0McOnpDDF9u0NMPz4rq/kP8n5uTgNaesRKz22i3ptdSd9M +2z+2OauzduNex7k72fTN3Ar7JI4GCVRerq5cn9B31l03g69fJ7eUyWZ4sVmeqSxQRFHWSw6uG4X6 +hXXa33Hqc/IrBuKSk+40JOK0XPYELqfG/bOgiYvBE3s8/1kgxXQeTXEC978cVHEeWGFxANPF6Ipy +4rHNJ/7cx4Ms4vRonEV4z8p5bN3IypkuLp7j4Ezq62dcQ8NK2lnvrjYRMmOi4gzxHVYPYRQVOvUc +hFkl2kZEi64Z6nXalpDKzowhtbuJ73O1R6tPzXkL1O43EYSrGVLkY7PUqIWr24zylchPtT/NR7fA ++5c1CuuDbSoWYf12bQhF5H68If7Cq9ZVeObwEinLpaEbKj+5IbWB1TlG9mOKW6XRT/bZGnvahYLr +YVzT3rVmtquU5tGI8uktfZA55btXrx7ewqKif9AIZlarQfJzgWyUqsYwytIge471O7Yg2DsX3RUE +DInWxevUZOjSJOUeyeihqKMo3MNOqe5NQ9RibSjNHlCqiE7Fdz6ucyZqnRSEp0ESVpVzGyTio21l +d655iu5J9JIBQNkOtU9s6NQTJwKeCuFPqoi6Mnr0/dF4k3soVNhbDHdtynCyVlOaqK0SykU7RDWV +VYvtUh48lNpm3DzLDiJqGNKpgdVjK6mV/lNaqa1ct3LsZco3Q+ne9r3LZYRxhl2JQ2HfTWVtJe3K ++U89KduFcj2V67Ny80i5fU9pbqPpss+ayv2HFk7kqS6fo5zH4PYo3NLicI99lYZ9PEnlojz2aGIs +xcnU0V1MCpfZ/aBfdtfwZnEwt4OlZvX1AfvMZGviht7BuQXrJgvXrTS3Xdt0vqMtBhM40uyYbG7C +EnPkTLzFDHS38MJ51F3C13QJ2/gRKxmoDUTax9z2Umnshe0FAgftLrPZXRKtLuoC3poD+Nasv2CA +C4W4bnWBuLc1uwt9v9P3uH+7A3gbbC43jAqGwfPOcITN9zudOH8zZeOOsHEnsEq8HUrTITQdPMOx +mk6cwHkHldnOgDI7h/CAjGmYGNVG9iAYF8tOsS7nGJdzPN3NdAHVchHNMsqt56iWXqYLkvFFhNwT +AHLrZSTdYyi69xZq6mGM2fVoXY/S9fjcHpvrz9ClfhPpB6GdIvo++rbHMbtk3aXoHmjbBORBIL5V +UNQ+sLaLuefhtF01PFELR31wuqAOXjZRnKmCJ3qgaYLTBVVwrwzu1cG9QljNFFraZpemphZ21dCV +w6Wl3ZgHFfF+UBTvmmLQooInv/F1/9laqa30vatvw6mVtZfJ9MquXS6DjhlGXXPQOHsZNTGO5zTo +MDe7cjwr1yfl0k+dyE735eLOTVPP46WJQVP/86SsH1y4g01b/Bzlw6O13x+vzRDJ6SRG8jxmex8p +uY/bHiO3zTk3NYPdaKy7s2naDXU7M5366pq3zv111z6+xcZHO3Q5iWW4aZ6q7SSiIXZbnVnr7srt +xBV/5PTfzIFVKJy661INd915uXdf9kiHQtk2TRbuoF7MZRfycEd+tQ982CiUlGbgSyaetxiICdY+ +2vvubZO7pd3vxjjFGBKhQREqDnlohAZHqFpBN8TUoiTuTf9Q7qlM7khr4bVZDD1wYgydyKZJmJIS +40Tdx0NSw4XYuMei4zzOYh8Ru02mfm2DAPpYUGwv66UAWQ+TPf85j2N7LHzqAhB+OiPdfUx5H8KK +YJS6A0Vc/t4AF2muotwRcyMC7WaAiQTbQ+hWiGZzOMF5fMTVH2Id+KfXr5+9evj68HsjHcJPp0vE +jnW5kPEnNV1jyPoTHo9b1/D3e49enwyGegpB3Qfx78Gn6gNW/+/1DnMqasXUAKfb3r3VTRzrmZLk +D+5B9/3xT1/gOOkbmNHiqdkI3oOknfr7PP2Bj/bAPUfA2Nu7/p6sw8PucUfN7rHkCZeBv3Hq3d8T +B/0gCUo+U3qS6/uppyf5QTOq/PjA+sCDjTuuJc1IRLsUtTpDFy80w16p4enCHxcZ4mdoSrijpt8l +pTW9o30aB53nizxUyNJ02nHRxcBhWM83hDdEYg82rltwmEgswEZL550sUDW7VC5JhTBpKrTrqSGY +FrK/Qlvh7ZD8zBFMDqjvqc+KwegJone0ytTgKnuoigFVdsD5ZDaTPXB+tJzcbfdTM58ocGUxfWU1 +Q4pD6bMpPa4Gdd3Cf0x9mszWolj7WwO6jKUHhOxC1nuuxH2ZmlbXS7xY1kdK2pfphJCfVMrjZXr0 +q/pxZfqAyheUv/MyPa3a08uPDV6o0KQEl8Jy4yIqey2UBMou1+JCdFHhpq/G3C5k1Xg9aS6jJl9h +ex+zK0YabLPB5yyGp4HmOmCuhe5MDSvnkTv7uJ3GcgCSO4vcUaBcbsZa4T+TzcQbc6jeWRDHbHE8 +wdQTh86lFs/jxW0P+nM9GWfxfu12Drd+dMNIjxLphpRwWqYxf9DOKhN33O68pLNCXjgNtp/TcsHH +8UjpNqU6jR+eVM4sPPsyfV+FDy1PbfDJP9PTq/6nafAxDgKd4s7g6YlaxLX6hlqusWxKgydpBf8w +FW2CUEKP6dIytEI3u2+46rTLzqquHofcjm6eixzEeYhDbS9E/13kIs5HCrIKKjO53nESNYif8pLO +TxYzuXSuksweWaaBsfhPn6N7vrJDhpwCYJzDTGdM5jFmszxSTjjO9EQG9H3sqJXpfV9+RHkvj/uo +8mODf4EGPyQ65ck/72twjxuOZ2aRsrPjmA1nalaRXebEMcyGdhs1g7hU5O7tbKYnAkJUMJos9qBy +ncDudN+ko5W24tGVfU/pKFoESSHTgIxPtIRiISY6rxXpAFYCu7e6SIEViHRbJwM7gM2oRwyuU2VV +sfmsk/KiydjQjYUswbc6m9taiy9yH0vnV+6W6mA2Kk8TNaiuJ42K0Kjd7BWSU6F1+FEE8e2Fcp5N +RT3B83vLMt0sTy7rU8r0tGo3+allenrV/zQNulnr9iz57FHmbLlLsuiQjfXWEndlJuyamarrSBtV +pn0qWGquo8wyurZglIJJCvYoOLPgyFInloLMb5l+S6HlyfNu0VPV0g/X4tFUUwORPyX18Gny4ZZ+ +uGPHJ/MyuYfJvUvRIOShOZVuByD59ZBdq7uR6EKazIPk7qO968gdR91p1F1Go8Modm/RNDqLdo6i +UzfRqZPoEf/QdOIgesw9tHMOvc8zND3mGLrkFHqCH4ixOU8tN08p09OqPWKJulCmp1f9T9Pgjxzk +Rw7yIwf5212ff/sN/shBfuQgP3KQv931+bffYPd1Xzy57ulEuMrLstaw0XW9boUJVZLMMVBKSer6 +DjOipy78wT/zBa/5Z23VHOjILBPiIYWrWXjY6EY/+cbryz3lixyuELd/iOtVDj2/03tq7K8v0mpa +Ms4UjstWLlx/WqNdX8oFn/9I/kS3/3LZ7b/A7R/d7d+yid2dQJNvTyDKjxbuWNe3Z+Xmw4o2cwpD +xs/7fC5n3iGNQu5Ak9ng4rcNJ35+9FI9j7NxY+J4jFwZQGXjyYvjqYsn5W+umZ7E5qZl9ut2LpsL +OhT78dmNrVa4hIQwLITndWnH5dgpNe1cHk/h0ZPO1CHdjCeb+dQKIyOLuSqnKTHhGGzhPfPKXGl1 +DZF50ea0bvNy4Y/L2J/P16RGl6Z5CWxNZCVtFi5yQC3nkFdDdRqeMwoPrRXX98f5uOv13p/lVT57 +33wiC7zIAJcPx47eGZ7xwolHDTdqMMbJYZffh5ssZ7jJS2DPE7Sq7v04bfM9rV9+i8sg0t37TP5K +HwOh/F54n/BUjxf43DEJvMPkEQnva/0D4In79lvEw56r1AGmt+MNp1/84Ci/eGmux91cN5zZcpLx +dUyypFvCXUvz2pO8puF4NM1wdpyYJZshfUM4X0/lmlsK12uL09N5S/eUxhsvVPES1b1iUJ6Nzqqj +BRPfmUu+w3riECcMB1adsgYDw4SPmN87i++NhidMdGSNcZieIQ2zvGV3Oc3vMmZ4Weh8n+mS9ywv +Y56XIYBkeiyCpJ2N4QEk1QNIPhec9vJqezqc9mRuf2iuhP0C+JiruRfJdfOM7AcxhMiEjnqlcKtc +85gzc7jdh1z0aeusXlxodZccsmVA8xxoYzZmh4uaVMXBP8v87PDVDuRoEFa94K6hXucBGtIv9Yvl +hxfs8gjemCc4cgEdzfcbbaXoHR45h/Jy9qC/xAVddEU/jLGRp9lyLuXLCRfy5ViunKkFmLlG4SGO +HtaoO9auygck1LGAxtsdpxFeM9lxOx5l6LFqS49V0/v2e6SLd1rek7qn3a1ztukkLm6xCTQ3Bqfj +Q0viIqzhjocMbTxdKB6D9OEt82ZmeYpF7onTgzaaDaM0ccfkj0lY4Ez74CaTKsnkChOP/jnKjCvC +vqMszXtGuV3zSB9MBj0g8rJk9YTTNb8/OMRywp9mhF//E963LachlWPLK99w8Y7feoyd7RkaAe/T +Ls1Ax7aP8PURnD5izBuuW5lc3IFuL+TLfw/fPOWcyGLVsf8D8P8y9D+3Vy072KkCFQ== + + + h9yZaZfBoT/fYwz6lEU33K8OwYjF67C7Dq87D1Ho0Fxmkk0jSOgkpyzRQY/sBOlsLwD0524i5icR +63NDjE8krgdwnjtCeFYCdgDSASYnEnezEU4DmAzwLfpk49nHn3b0sR61On3KWat+IvGPT/ZRTzaI +iVmm/kIFP8wbFfw8zyskvitZHjExOErzWJ3/0fN8VZHchlz+n7lZFSzXeWFO8JRDYAYy6T7pWkqN +RY0nEanelwt/tCbzcrWJCj086WdtVs0xn2Yf9ybDFTbfz2Z2P2lW+3RG4lG8s3AVvlgKc9w4OnOu ++vJM7n/hj4uC/Gdq8JOE/PWSjL/u7OZMm4TsPdWStN8zQbszR6Rnv7fEPGDPmgRZ98g72xSjKeHY +9rbJ9O/bpn+HGz+YfG3Hq3h+8XawyniuynAolSzkaX8a1clBVPtDqEYc+P4AquEoqjHV4PvPzHta +uZ8+7Eij7y9//QbVLqepePfxT7C5wdKm56SrlOcS3rElsorMCleYFPnGNnBGY+sODnnOkla1fOKr +ZWdzw8kNd4l7Q/ouNJmsLZ0a8b5TM5doCqTZ0lYtNJjAEe6J16rlOOsRSx1QO7hLTpKRnZ71zXxX +l0u6WNaprhdL/tgyffyln6lBnRo965qnovNU+3repic2LPb/NtA9VTMMvNGzPC90d4xJmcd/8XtM +cj0P6a5HIPuT8O4f9fNjg0+4wA7BmGU13oggj9NwcQ7uzNNvjzz1FoLeQiEPIh4EPIh3K4+znXmQ +LSS7Ua4jYuUxsW4Q7Jpod2vIi2vLIu9nz/pxEXEaDvH21Pg9o/54yux44vZ2NuVbRsj9efXvP5X+ +SYdWf9/x8j/8WH72BtUUc2PnQCeaZEZwV7W0B5r0oGU8eP+hJlM7wCPvjU47C/dxSJDkFm5PkjQa +uUOdJ7N031s+vVuzd9+YzfvYYj99I+kJM/vPkPFzOsm7uZ6V+EhZLpfpkS/Cx5bp4y/9TA0q1qH7 +BEavgPsFwhkCwvEP48HjPTeeyI3LLi1eT5L+lIx4+5x4zPzloSuxlTH6ZY/8OgmkuXhY5t30WFTO +GXblaeVm+n6Qy4eVv36Do4Hvry4V/xANvle3mB754vKhA+fZ08cs6tSKpotHEOSz7JL7DJPhbCH5 +MjpOtoY2WzvZvHHr7jgjO+DiQoqbcMLtmeQf7D7SIn9vYF61yUfZze/lsY/k5Fl491J1X/mrS8Wf +0uBlFWF9RKcwjWM6U0HOlJWTjMojLKxrP00jmloaaN+7NIu07i4q72iu2RsDQx+phRVLBLhS1Fso +aAGhcDtR6ruxpH/FgNBM8WeZ/WDiU+AzDHww781EN9+I1qjyn1r1VPg7Tk3uo8Rnch7kO0h1EOMg +vF1T14AcFv/ikbQ/Nnj2s9fPLNB4ah/87J3lROHbK4IOCortKJ+9prlNg6pZT1TNslNSrZiq8okd +c/bzF2nw/arBY8cVWpkuHgl1eqbTqM40LeesF6kVTYbcHA8vuBlwm/cNsBVaMr1oh4LlIaWe5QDU +pHruRRz9iO/zJJ4nNOzpDHmQwNa8Rvs8XjfMtLPQsoSk/DyHUE+x/GtLxZ/S4CO6wyPFNI7pTAU5 +V1b2ysyg51w6SGDq5wZYOVpWkX48wN2QX2RuOUbek2XkMe/p6Dv1s8Y385j2g/0WO1xcD/S7nnam +7MUM2ZV+vxvarwM9f0keGPZqhZT81aXiH6LB9+oW0yNfPK7A3F3SebpGNA1Z+HsZFaquZnlOgK6L +ZXMjlJ6mfzIlrh/XfjRF7zxj/3hiewf5ZXMlmPNgcqzf2fm4ehJ73p2Ne3N3e4I6K8KRgA8TtoWT +extuzF180PBTMldPqVc46PdQ1quQyuCU+7Rm6NpK87IRRz2HJfM4HuGZIWluxzVuSyCaGfjq0ZcX +4mEtV8KW+8N8ckt6+tEHvVIth2W9Krvn+OgWPsmZli4509IOmXoR93K6Xz05Gey6niJgTjEwYTiH +Ffmfhiy3flCkn0Dk//YDDvfHQ3YRK55+nnaiwXiy46mQAIFLhK12bq9jOD8cwmnq4kk+1Om4P/K4 +J1N/zD5IROp4fsP9cNDa+QEO23BI2v4Ih7Ud4bBMj57i0DXw68E8BWEz7PO2LjxBbF5qKX5qVp5l +AS2MK+CB8eHRTK0ffrGesyVLgm5nmRPrUuzK6jELm+JYL8NSP+LaT1trF2Hg6Ucc+I848B9x4J8V +B563SytNqGfRReEJ0UWP56Y3je4zm2TaTvPE2faEFN4+eftxQbd2zqofGdQPDart0KA8HF7UDwzF +yUgnvP+DOeluFn7U1XpewtlZCrsJ99j3nzS3ykWRqaT3Ra49GvX1npMPdrjjyyFlXXbJl6bu0Lxb +KNIuYO3ROLXeYD2JUTs9OeDsaS+Hpz0+eR9nlrsp/Dj3fSr/fc+qeBpLf1Ke/NMTW4NsStQuZM5C +WAdlzttmU9zYbJvrp2eKnqyTT27rc0e6/csfXrx7+K+H48tnz/9DlsXu41/iFJBzs9lHngMynSWc +9XTVnm52TDV7244T3Oeq9hyzN0Bd3Vl62WXAo++x8o+nxx+T4x87Pv5T4P83Q8Z74v+njw8AsNJS +QHqixlOzy4nV5Ic8X+XMsvrRJ6xMqqY+MlM8d2eyoyh1svT8xC4C9xzFIvpuDAFw4ffODjx9Qp7z +k/zEZjV8n8XwafEW54ctfGzExT61QD9s4TSFxO2FJAVPmgofcXLN/LnOrpkuTIRdqA79f+NEGM8k +9WkwJKt+31T4voTV+3TVZkae6qcFuJxOitvp40NchikyTJTpkWM59ukoPp/0bDL0X67BS56pSwdj +lz13my4wtwv6xcXMw/u8wxZQNH1iRFHRmKIeUjR9fEyReRaOanyg2SHerpOsjX3akbsLiUd+qKOL +PsZUd/HwoulDjHUNy+dIPk/cdttTt01mlmD2tpa87fZJ6dv2ydssGmn6tHAkjeo11CrjkaaPD0gi +YhV4hmxIVYBUZTndn6SHKRcyyPw4FX6cCj9OhR+nwmNpoz4gqdJZfqgPv/aHMjkJ4at/ePP6y7cv +Xr978fr3X3wx6NrjF9M/fINvon7z5bN37x7evhYl/Prln7/99pmo3/bHYduuthxXeE7XnONhWdcr +2cblj5CvZC5lPuk1//3XP8mv7/in+xz/9c/8+D/kz/8txD/Jyx9+dfi3/zUfvtZLfi2//B7e5OGV +EM9udPjlSPXn+eVw/SXa7urX8v/Prt++u33x/N2LN6+fvf3z4ec0Wfzs+ObNS3n7X1hPfHX39Yt3 +b95+dXz2/D+kt7767YuXD1/9+uH5u58e/qtc8H/K//aq/+U7NnDLt/lHTocFRwWqDTIsiRNjlQlR +LemfHaBa/azAdatz3A7/+owN7TouhnA1xyzjXq+iSPbaMfJqiwhch7RdZRGpDrLir6SpdEgFh7XK +O1epXpd4SOkqyNo6PMdlNV3J4q2HtFxlhICK5H+1yqo6rNuVCP04OzZfBVmAhzVeyVpb7LLtahau +cIjyZWHjRe+21Ku0wKBf56u0bTJFy1WE8ZWXlfVKVBCplRGYK3fLcpd5zYe46DOBEFPdDlFeQ6Rb +vUyIIdRykGGuQcY+lyvIm/CPb4gSFS1IhjMVEJZY7dXyfAWl5LDmK5z9c1ika4KsxcMarqLoN4dW +I6ar1S8KVyKo5vbYS07IlaYp05CcLOerNWzrISQZUhkEvSpfbSHmA24Q6sYHkhalrbriPNwUr4wJ +CJPxi+Rt2GVfhCthUejqWK/mVMNhlT4U9icEeQrMh0B2kvQ66XNAPA+h2GuswlI2PLOMODpXPq8I +h8V4bzZgETNf+lNelaOJVrgs5J4py3vGVcdrTVfypDZeMVzJ3zKHsvRrkPeSy6uoE4e8yrglueW6 +yE2k3Sw3k6HVy2TKBem4Q8mI1q7sROHOKy6THUkIsihjCtJOllkWSptUskoy2kLU7yHO8kKbjHtd +ZZxlmGTicwbLlBR+ryMmj3WVZ+lzmYFwMslUws3kzapcnWRORZltnNJl0VnHy2SARbFZGHldpAMi +ek/uJc8+p7gczlYZrvp3LuhbDnllKjvU5zp5NRJlYiEfIWfLhqBrmVZ4g4UdMLfPOnnksWSr7nVk +5YhSNzRiBL+Vz24lytzdMmpZMzLX+GLtXk5oMxUP1Gv5e7R2Tl7M3zsGdIQMS4my5mVevdoRV51X +UWal7McbCLK9CocQVptkFBtBB01mWZCV0WutetfejhPsbnqZE5cr0Vhl0Fo74WqV0R/uZgS9zJ+p +1fKnbu2cvJu/9H/5J/nnn568Qfzi269+9Uz21Js33/z5qzf/zg3j79+++e4b3SEuX/Hrh28enr17 ++PorucVuJ9kOP/np4V//5cKeIhMj5ZmYIuErGz2ecynSM9hNhBWVJY27SdFzuXU3WetV2ZJsjFgw +q87cTkRuArhKZYKI3i9TWSZKFR4rvaw1kBBXhD12URC2soAok0Uvk9WIqINDSdp4I2xWg5c5Mcyb +Xbdgl5adOYRsFOF9edkGCq9cbQfv9WTiar256oM1ylZ1k+eFThQmw3ne3riC4W2Hs27Zr/ewoj+E +idRFulW4yqsdUeQPcKwg7HAVodc5VsBWI6NiH/UNkL849yrowii7UmujEexOraNJDDKYFXfyZmZd +pu1Wc1+2/XFaJX/g1szJa+0m/m7KxTjXFUi1WfYHOofmVEK2TMczc3pW9bPLH9sqO7ZOuEX2TvZo +WuGATcoqsXIBuktBxArht8ss36YkDBlTCtv1LHuN7Ad41jkYr5yFO2dZydwqwK2CsG9sdtsqW2uV +zU9W8iabz2GTXUAkCb0MO4C83CbMQRj/gfua7D6bCD2iXchn4QNBxBjZQ7Ztse1IiCVV3UeE6xwW +yDaiMaE3RZgDQapXETeEa8xxtcuEuMobHWTPg+2TN8tVRAfZROsKiei0P052FiwO7K1y3zTL/V/t +iHhf7MTynmmNnEaYNYvwuIAut8/PvY9LXXod2eORo6Q34gS7lV7lRBlh0f4OrZmCrl1zv5cT9DJ7 +oF7LH7m1c/Jiu7kWDtfffDJrC5AeZcuE4CF7vy7SRkwySjK48uRXocpckWGrmMHgJaKo1kZQHiWS +scyBoZb0YhbJqLfjBLubXubEcgUF/NDbEZE5yfD3uxlBL/NnarX8qVs7J+/Wek91K/beJ6/VIFMl +Qd7FlBGuyA6EjoBNN8vYiLwZhJWL8MpHC2XBShU2I0OEpbthYeh8kEkGRiuMN2GWi+R7tWA9yfTP +syyMUOFCzksjsCMg68+5V5JVQ74do/N7I4jGMnB3I4rwkrOs/gDBktx8tctEGqoFm4KwXWfvAXpD +kTkbyGvYukhRhbtOUoG2UxaZvqtf2agiEcMIwl1nw7iApcIdckDrm4iVncIrZYfdqgx/ryfPWNK6 +csuj+jJQRGPYQrIrnUoGItoXOivy+bFmU4BOkOHFx/MHHSReKSsucg7LHpkh38jYXg== + + + xRW7jczGWfYJGVXfR0PpPbTMMkbCWDn9qJDJB7mgBtYrWNWz9cS89Y2To49xDDPQVwATz1AKCgeg +rLKug2zPCJsDF65zsOUjH9YsDyjaawTzl01Kuks4/jbr/U9n6Mk2Dd2BkzTgNsWkm06FeChvncHB +ivICsu4g7Bo5WDrFJ8gKDj/UW+T1cxiaagS7o17YqNIRUfjB0JRIoVmWzXBLo+iV7dFavfb0ra3T +t/ReEM1Uewczek6LSukY25rARJwqerAI3jMoMv5b2lGKalk6Ho2KlVXTYWhL1kPAiPR7GkWvjFeL +sPKxnuyygF8NbTXK7p6N2p6ttdWe//Q9Ww/IKmHfiCJLzfTVjghEfcIKi9rLa1UlPIhuEDELneDM +CFlneq1cdVhbO41gd3tu002JUaYIxNzWzmIv1O5mBF3f/kytlj+1t3P6bo9La59iboKOOAt5tC+B +vUHRcvMS1IEEiKWbl8IqEphoWTvzEoRS2fu2Zl5ShUG4gJuXIKLO87ruzEtoa4PA5uYl8Erezc1L +geYL4ROjeYncEjzPzUvy5lcwXzfzEgjLsrcuhWVVKc6sS+Cusr2HZl0i6xOlY2ddIt8U4bFZl7Bh +SKetzbrUanTrEljmutb+1GERUWiruZmXwiJzf9sZl0AqVTi0G5eaJODmJaywGuu2My+B8aYofLqZ +l2QRbQusaGZdwqKS3WNnXJKll2b0nNmWZPnLvF3ctCQf40qjYDctgR9EHJBiliVpIsa8uWFJ+LYM +VNnZlUTMZmY8NyttlJBLsyrJzoA5O9qUyPu2EppNCV0HIdJNSnLvK7gAdialIHflknKTUpDpmgBE +du1LuC1n7WhSClBeS7coYfuca16bRSnURWfxaFHCTkWx1i1Kcl/ZlOWR3aR0trBO9i7G24R1Z1Jq +RLcGYTrUJDKwmYvCwtSDaTQpYbdaINx5nQCjJcxt3ogTRiNPJ5opqDXjxqJ2r9Gk1B6o1/L38HZO +X2zk1SIPrTuTUieaKQh8MW6p2YpE5kTY1LazKIGjItxnqDXrTXszThhsPJ1olqDejtmK+t0Gi1J7 +pFbJn7k1c/Jmf+sGpY/X7mWBL5VcyIxzr0aqLGUa6JobQTZugEqFEHS6gA2lZJZjqBTrQs08bjO8 +B9LRIinishTNPMmtWGrItuEOArP/w7iThJE0M76oGFyLwk7kqZfQCGqBh4BeeiVY1ouI8LWaX8EJ +26btN/s7iFgNc8ZDymYmHGejikBhBMbYJQ8Efbkq2gaXsFdrfRfMRH3emyfGgTKrfRObgAhBaofq +VGGKIsOvasWl52BZzDkAvphT6BTtOTghYh7rLeopGNpyit/TzdZGLeaSa21Bd+LotXs6Ra/0Z2v1 ++lt5W2fv+YOIOs3IDzk3523d+9KgopBzN2ca6ok2X7o3DbJpStn9YuZOk51aREBc6f400e5lH6aH +zVYCthWR79Peo0YZL/IOxYXOrHO3+dSgOYhY5GvGnGpQcXPBJHKvGrgbn6251bAndQuX+9WwdQVM +6eZZE3lBBj+m7lqDFUAmuw+hec6gjYk4WLpzTdaB3Jxr0OvAgrKacN9WZnsH97BRZZJbjS62qK6d +nY+Nkmdal+Zkg2trlTs3L1ug6LHuvWxUrqGGNC8bRE/ZjZbBzbaiQ0wK6H422cf0jdzRFrCPymg1 +VxvNDSm4g858bXhx9am4sw3q+bZgfru7DR04r87+3N9G9WbDO7rDbZkjxMute9yEiYrkYxtSc7kt +dJHU0H1uvBLv25xusKy22eNONzRXy5K71w12Siopze8mW5sIambgaY63ZYFGKDtk87wt4IyBTjXn +a2HWubnzvcEkRDHTnW9QLlfp78P5wnzE/Ybvuaxe7alVNuZl6w44GDL4Ms0t1ig7J9xQzxxsQ1uN +YvfcOeLACGqi89fagiJLA2+7Z6PsfHFDvfb8ra3T9zxzxy3SVUk6be+PgwGGc685v5YgG20J3UXm +hJ1Drtey/WdoqFHshjuXHEY4QUjuTUEtCctwQyPsfHK9Vnvy1tDpG/7/VogKMai5MkQYBW06Yzek +XoevRTvEzjrDSAf1W/oUmiztzaQI9yPFFU11sGXE61ASEYa+wuYinELnotxKDX5OUY0pqkev14PL +jWI8OErawBCNZ4UE1utXilZjV8qGxHvKlXOE2QZGUuxHZ695ogFF6FOwkaW5b8cDNehmg3ZgkYYV +dgtk7vAxwEzpFNVMZPHEOQ/1hPNUqHm9qU6ZO6PpVHkF3b5bW6uwgyWswz2d8txGko/Wq/nTt6bO +3vJx2eZz+Hnhv+Ec2Dl6YcfV8XVPL8z4Mzw4zdUbRBCCrWDv66WlmFe6GxdMQ2dZo8Q0zKlGXX1O +ubt3Sc4Z3d3bKDt3b6/nftyFKyCOlFj6pOpUDGUaHbzYxeZkY7TvoUd8vgtEYeT0f7Wnwgew5O71 +bTumO2MbYef57dXcq9ub6hS75c77y42VCnxrC/IxLWt+SyfsHMBDtfb0ranTt/wBfMDgV8IX6l5L +bFTXEps10LVETAsaVUYtEdxDRP2laYlQqEIVJuhaIiwOtBeOWmKz47mW2MxxrgDCDF3yUnZaInS/ +eVAlYSJbZTK7kuifRx3RaU1FhJk6w7/XdD96/OKW9zoirFhlxbO1eq3nXEc878tTO1JWi8VOR+xU +1+tolsGsarof/sgxlb2OSKtPXJehXqhq8+ttNcqorw1U0+t6W6779XuOOmJ/tl6vvVVr6/Q9LzuU +P8UUviaDpcDwDKfvqz21mNKzru4kzKpBYFXNkFkaxe3htHAO9bCjwzXX22oUu6czD6NuZkVobclG +JFwsD/d0ihvTzVXZ6rXnb22dvucP4l1esE7pnpWNgOI9pXZRG7ZCiNGigsMSackuNPNHpEoCFy+F +hn9ANzbHdcjkoC8KBvUlKNtUkUM6WLSkhWCFbVn0ZWmbc5DDAucjNmO1xRD2gAUHlQtTAZKpdjk0 +xmZrAk5lWxSBIy8bqevnWPTKsuWV3lUaetGv0lk2p6HiR7yV7Puqd8PTVUmBIxo6/FbUbgghSvRD +0+5EhZNNI9D5rQDamfIfNz8F4IqYDnM7pLDgCkYAW4W9WpRuvgB2nkqXY8Yiqor7zBtU2DKrfqxa +szRrGmyAwrcknkwOzxYt4LCnidQZaXSI0TXfRNv/yseqOpKrYgQoFKoOeToHTjS7JSt+BFesZTV4 +c6e62QCzhoZe6ZMCYD21U3XFG0XnSFQ8zlBPNsVQ09hWo9g99cpGjQZ/7W0tulUO91z65jk8W6vX +nr+1dfqeP4gUuCQHBMylS4GNCq86leE1GDzOlyCGiYR0NS/m4sCEqhl2VthSVsXRq0w4+3VQF+kP +FKWtSWMQNgu1D4iCam5w7QNqiOvGiysHXQKE7wUTtdcrm0MFN70DZ6VCF7ZRAiwnVHBC7QuZlSqv +NoosmyYBdmqJLmPSdwa/M3LLLJz2ikOso4hcDIYCY58+bPaHlT/0lnW213SK84ayo6q9EDsE7IWB +Fjhvaxu0J3AfPizEd33NzQYFkAsdlNljAIRtRL8n5/e8VrUHyVXKd1XEX2z9go3GJdFESIOmX6ls +pIhmDgvavFh35OTWleTa4NL1UtqsVggE8PDSxB5cawQ7pUEAyq7Og/FhV0MDUoekNa7N7MWm6Plc +P2EtmJIAsuFlaDp7tafK1lJXNXnktepYrbA5YnPQrneKLgfp6ALe2esV9aUObTVKHMx1nZpw1FU4 +DG3BKgSMfL+nUfTK9mytXnv+1tbpezaHm0xbercw37lVvdpTNzVjAqxCtxjsB4mejAw0JPEuRlGk +Q1DszlBP1uuSdm01it3TrzRqMQtXawv+Upg6+z2dolf6s/V67flbW6fv2XpABmZL2HJF+SMs8dWO +iq250Fw/u70EI8m9sBIB0Qi+4me6/3u1Fcnm4tBUo/gt9cpGhfhDn6G3BShFCf2O9lkZhT+XV+ov +5O2cvaK/POytlagvoLqjOVwH6grpV6F6Ikyqo4GSNcyiS42lU5T3wKQBE7lTCeriY3lbA8XuqVc2 +6mKCXW8LfgC4Hvo9jfLcntaerdVrz29tnb9n64EI9+6ieCZRXMx/1qiwr0EIByecMfNkuVFUA/g3 +zlvolOcmltDFP9QDDALewdZUo/gtXUQwqlktelvCOoGm7Lc0groI7MG8Un8hb+fsFX8Afb5hmLFT +0OO1A3Vjq8rMJeqobmxBOcFR5LBumCRidfu7A7sh6KtXwZHdwGEn2NkatHsRUSBtNbQhAFQIkiZk +I8d2o6PUoengbtSMyX00Bu6mGWTNa0d3U8gB7KTBu8FP43YC78abEbDU8N2wi9mNTjvndB8yIDT+ +oP61g3hDh4mquhikmjs1sKUNed0oz73bwe+HeobhHtpyit/T1SCjVu3F1pTciT7QfkunuCSoj9br +tZfypk7f8rJ6/jnw3vR6LY727FRFaTRwNeaUTJ6tY7AbRc0VBtUe6hmauzfVCHZHvbBRZRfPhNW2 +porZgfsty2Au7o/W6rWnb22dvmXjZjDdwtkHtV04hWEvGlUEqDQHRASKkFXU0hfMhzjPHv4RbGOF +zbasOQ/14mxAzdZSo/gdnSkpFSY2oLx6W5hQ6zbe0ykq1umTtVrt2VtLZ+/4g5gmGqwYa4hQ6hH6 +TlmMJkPHvmOhpEgvl4HfoeP0EEhHv9OTBxbQ4O+Qc7ayLB3/3igq3igAvldzbDuEbbOBO2ULo75j +VPJSyMMNBE+hUdURQ8GDhTbZusHg4SxXFcLh7eh9SpCdkmFg8CsbVaSZeaFPw2DwwPfQTd9g8I2i +4o/B4Hs9h7cvxZAGneJmBxecjBquCAp2FPxCNw8gAo6CBzInt4d1FDzcEGoncxQ83Aux5NRR8NAl +uvLhKHi42QmfaCh46hxxiR0Hj9ab8tFw8EAd0N7iMHiMAPlqw8FjI0HiHBOQDAgPRTzXAQiPjYrP +cD5lT+zAjhLHIAYEU7zaU0UFw9HFDXHOd94GLLwTfJIQv95rGcR9aKhR7IZ6YaO6YteaAnBqGdH3 +jaJX+oP1eu3hW1unL9kkfYeIA+a1Bg90dPh6ozaIO2Y/nSUDJQ0hH50KwxUcf70tCNqE/bR7GkWv +NPj6UM8g7kNbjbK7Z6O2Z2tttec/fc/WAw4Xx9wpq1uvO1VYGIEwDjwXAfZqJrza8emN4qyJMPZe +z5Huva1OsXs+nwZEPHUTGlJ6W7O9Wb+nUXS1t2dr9drze1tn7/m4xPs5cPE7sJgD4xtWrCHjG1as +QeN3WLGGjW9YsQaOb1ix5g/bYcUaPL5hxRo+vmHFGkB+hxVrCPmGFWsQ+YYVc4z8DirWQPINKtZg +8g0q1vxrO6hYg8E3qFhDyjeoWK8zQsWae669QoPLN6xYw8sPSLEGmG9IsY6Yd6xYg8yPWLEGmW9Y +MYfMN6hYw8yPSLEGmnegmKPmG07McfM7nJgD5xtMzJHzDSXm2PkdSMzB8w0j5uj5Bg== + + + ETP4/A4g1vDzDSDmAPqGD2sI+hEf1hD0DR/WIPTdje0g+h0+zFH0DR7WYPQNHtZw9Dt4WAPSN3hY +Q9I3fNj5Wjz1gRrkfIcPG6iG6Wrg9Yb7ahj3HT6sQeF7PUfL97Y6ZcBqDVTDdLW2Gu6r3XOHD2vP +NtRrz+9tnb3nyPzpSdrhwwaqwbocyu7Ar4Z3H+FhDRXfaxlufminUQa01kA1VFdvyoBf/YYDPKw9 +VavUnru1c/p+l9TL7kmEuU1YhNl7GhWWhKJSViJDKYjeMOtLDVyNRlH137l8rydcKq5hbKtR7J7N +cKBUWVFg5UNbtuUP9xyEgOHZvF5/fm/r7D3bevgUBfskZRO1uriqcaZgxb/aU4NG2cAWU4CYxGDN +UYVd7vaN4kYYU6ZavWBAl95Uo9gtn5vBzqhRg1WHthL29jTe0yh6pT9aq9aevjV1+pa9Lz9ev4Qn +cC6qc4jMaNJop8K2xeQVQJpjhwbAnIJ/mk2VdIpqXp6oo9VjSF3KQ1udYvdUju7UbVbob29LKGUD +o2n3dIre05+t1/Pn722dvmdjSGs1SQMbDxbKqz0VvWvosy0lSx0CBHPQc5C2TtH3AB6mLmM92Wlo +MO1tNYrd0/e0Rq2ZED5vCxa0OtxRP+tV/lxeZ3gfa+X0DT/LIgyni1AkMPWhRQUXvdpTAYqCug27 +KT2na7DEExHhYLBUOqWtpbwsYz15gMUBGdpWo9g93ezTqJokqzW1Mv5luKMSfNnbg3mt4Y20ndNX +7B35CQL8CTdT9Y1RmBa6+GpPBeQsanyzxqLLsBZ486mcUwB3iiprs0IwWrXq+NfWVKfYLd35a1TR +qwLlHG8KZlYTAeyORnluKq49WavXnr41dfqWP8ikhIUEfmIR/ZGV0RxLTlx1l4KPp24xHKBEVNWZ +yGnts76TyHpF7tfqZHXh9EacYLdy5VyJspBXOsG9maLhEv1eZYjUbg9UPKjCH9naOXux7kpdVAfe +ENDifsRGlN6aszo/4yKPsWHCRnWoUo11gjLWTRXYVgtwhKoagLbTCHY3vcyJmBxgSa0drJ9tG+5m +BHe96jO1Wv7U3s7pu/0Qy4/bLEQWqBv0Gr3aUyHfZQuVWeAIgqIyLypNaGY0pzgfyzHGsR7efktj +W41i93Q+ZtSikO6hrWpiRb9n7Yk1hmdr9drzt7ZO3/NziBMnfbkkNUJT3oZx9NWOCmMLPMJQ0NZl +VrMZ5evFzStGUIETLrR1G2rN6i0bGnKK31AvbNSFb3LoTdGOE+twR6folf5gvV57pdbW6Uv+EDIu +GGe2hDHBMSKduBioAc5aogVbPBtQKDl2gqpw8QpZ+sdqWGPM6tGaahS7oyt/RoVrhBjH1haSl4Y6 +3NIIemF7slbNH761dPKKn39C0gYzWzy1LBDHIDcqjE1J5S1pQ+2BGrwHj+UWc6foWzF/7jbWm2m+ +GJpygt3Rr5t9Qs5EgXpDQhENeh1u6BTvf32wXq89fGvr9CU/z9YKZE/U0FeGJb7aEasnJchmPmSs +z6r2XCTr7xQVLlbPxNfqiZSFpEJDW41it3Q7jFKlz5hLrbe1zBr40+/plOf2sPpsvZ49fm/q5CW9 +6z5bWNfj4Vqfy2cIaGQ0i29DMwP4tWLVOZhZXnQuwPk4lhmgrARWN0KZK2IvaupI5kIDV+xA5oLR +iHsYs8x9EQKWjmJG+sYKB4ODmDNyMBDVPGCYEbaVMTwOYYahdC61I5jhhCgl7gHMMDvPjmxiPl5C +FGOHLycC0PfgZbnZzJF27DLDI5fcscsZgAHqvh27XAjgWjt0uWyybollNuQyRWQaBwfgMky4W1lz +Ry4HQg7pUDUnIpEyedv22GWgZRbYoh26DFlsjR24fDbae4tjhdEZbGiELXeiWbCRd5Gj6GBkhHTH +EvaY5QI/QN46scizVSis3k4nDODhTjSMcW/HYMj9bgNauT+T12pPbe2cvdvj/pVPQnMse5QyCA5Q +hjjfwMk17WDJhbEisaGShT8jC07DJDOPzLJHJMP/ESzPHgHJEJ07yBgzG02MUGRZvxvs3o0YkSJu +wBcj6OgEgxxHytyBx/MecTx3qDFwwBU7liGNF+gfJzhjKNAdY7zYYzhyGEmTct7ji1dmqes0JExf +DFtKcPFqjYzQYkM38HPSPm2QYkAGmLVzcJNj/pW0djxxtSdxNDHm0RzDHkxcqi1swxKjX0YkMfPN +5j2OWFhICqF0GDGMwTl3EHEtNn7D4wUGtsN15RBizjhHD++m335tg+Ws5vxquOFONKgvcwwBI+Ro +YDDjU8ww5uZaB2IBDj6E3kwnDODdTjSMb2/HYMDtZgNYuD+REfszWzNnb+YvDgtaSmkPFO5Ex/bS +Mj2gfwHELycYYRE2S9hGiLDsonlspRF2AGEnOqbX22mwX7vZDhxsD+S0/sTWytl7+QtHRvwOIN1X +I9GxvFhbZBsO943I2lvyHhUMq1eoQyXsUHRTejNOGBG6nWhAXm/GkL7tVgMcuD2P12lv4W2cvpa/ +L3IxhXnbQ4E70dC76Mcwwn4TYw8HxC+3eGD9qS96LbgmqVV6O40wAHI70XC7vR2D9va7DQjg/kxe +qz21t3P6bv7SMPMk5vsc0L+N6IhdWRxbZB4bA/XC9FTouR6wv8LM1qUMRLg3eYp4a8cJIxC3Ew2v +29oxRG+72YD6bU/kddp7eCOnL3bJGQan98LA8xEu2KkO8kNcaVg9NBhAQNl9cV7XHi8Iv3MoSydW +pFfeBtxhI4zQvUZ0hF9rx0GA7W4jUrA/lFP7g3tL5y/42bWKj04W8cgTrIef/eL1uwuHjODXs9+9 +fNAH+eWb51/9z4c/a9tpPvzs1w/PLh1Ncvvi1VdfPrx9/vD63VD/sXt8+fbhjy8e/vTVr9/86Vt7 +vQhvkui2j92AZ57894cXv//Du0c7xKu++eYr6cj7t29ef2/dXz78+7snV8ZLSq+8ePj2A97x5s1L +f0cN78rvf8d/efH1uz9cHMs7PSPn7vXXdt3FM3P+x4s/Pvx00l/Ur7LOz8yYbygZW1XU9FJDnC6e +l6MI6Q87Nsdu5Q03jNLudjz3plHbY/2yX3+Jtrv6L3FqDk3JsiPMOHZ4WXHKFDSLGpZZzyRe/Ezi +dZdMJWmuXqQCXD0LOIgQL5G9G6ksQQgISIALXdVxWPjnqgTHIK3EZ4O2VFpSZ2u7IkeV2qNwtBV4 +HVSam0kN7AuVuwBI4kr3YkQWp4IsDFDqZVsuMJ9DEF7dVoUUGICSgbjZEQiEZAnBOLQQsOMJgUih +dhmAj8g0lpKilwoPQImm7UEIADKZhLi0N9M07xGW60ARKQR4TJDRlHsnzYdwCsieyheT/XhLC5FK +G98eMExoTxtTo0YlMOMblK/VAZAjdc1BL4zrppTE8UjBcmTNNLj1K1PlnrRI51AHdeEd9ZIFZGlG +abS+Zhs55AdH1AHOfEoaJkxjF3JNZM3hReUfOU5yEzoRD0FFAFmdsiYIZbUwR5FWk6KqMxC/sCyU +6ED+nO30CYa65mDWVaYwmOF40zBsPUsDeIfgaTezA6CDa+cZXcHUenCv1NUoq1LgZWlXrrSFBhwq +tprxmZmCkT+Lh9rjnozMAmVxYwckpew68WKjzQB0EorKcjO7IvD8BcfzBJMR5JYrjUElq8qF7lgX +KnLZ8p/NZgvj3AGCsUQd31irZpSrK4Z0hrlIYaUx2lEeHGw1JsI3t2r8VFkgBTEx66bSTuGyrLZ0 +SMn+sIDK2XWJdTRLI1pPScGtjKcAhTKJXgVDEExIGPFqCEdNRjjDHQd3djWNdoMlXere+IWraKUb +E8UrQi/OyFOywbGu4DGiBhHlv2YPaIPcjxQnMGwRaTdrSA0Ax3VRpySTnxBXaLACEpk8F5DCRdvG +tCQgTiP2Zqh4/Ly6ixo+YOAYZawKuhIePuSh25g2VdMUauJOfGFjx2wDESmEYY/yECUsrsrsHBas +EkulEuw9SSLSVsHAtzAkKKtYBosM8wgHqCnSoSDk0MOZiEMAEUn25HOB9xzNEHgIwho1q69zCg2O +SeTMcY4G0UditsqswoEu4WqWPHAAfbNICALU35nxalXrwCpRDYC2xg3qdYjmYiENKNIy6yIDgUZs +mFc2gNFnP8pKCNm7Y0ZIvXwLYrTLRBdYh8uqZujwhp9b58tWTYtwwEBiZHOSiQLzXkkKUKBlv2yq +7OmbBb1bQcTKYqhO6ApwViyzIjojrG+A48+enxFEWjMA9MMZZLPtXUIQnqkmH7YDwnAVs1dmeEnV +AkQ1BHVitai/iuO2sNv4i8HLvLBvFQi7RTDUjSdNrBq+TCc8HC7ZQUgF5z7gVoDjMBQftrrCk7Ca +hTggvSAMtY1xgbjIXFyz9jXtyIseDyc6ejHo9EYCDs5sbL1gLYJI22rOmk8Sl5VgBN4tAy69NP66 +IYWl/M5U5mCkNkuuiCrqhFkKLFWJhjQyEIwwkgVXbL2b+m1lu+fAJvoQctZ5VRh0lGxXLjZrwhWT +DsGOa8tDt8xVpucWOITcpXX/32AwSjpElueN4YsYw0J4Diz3mWMWQuwCEazvoIGD8fOsIy2rT0FQ +zGshhFgckt2aQi70qvjpKuuNmUr1kTfR+fAKotut+l7Sozo/mCm40Lq3ImEiXHLYECDCVaZ8zrnl +gJdtC45WGIVn9WgwV1QBe8iapGUnHe5NfZQAgHgKsHT78RGrxuYtRJpyZ182gIYDstFr4DS3jIX5 +oJcmS2hIsPBKcG0SAItH0iQKSyAwJjaAK3uoBFR8muSwGVb1Usw8XAopynWTDzO1cSU8N2E+YoG1 +Wki5zySbCTy3aoJAGF2jvHiwLYtrBtFamy5ugrsZDoutxgL7CW5boDQ5pj9bJiFkUjOxY66MfWqf +A4P3VjVPubSikaKQi4rW0thUntGics+yMrZFeG5y0GHWBFAI+g1JdSeKjnReLcNnnA0QUpNUIWmt +kC4XNffhnFlk/hfBVaPSVp77Z2YFfcRIEzQsbWkxaxVSoYJAmwXEJIwFrpo9NT0C3HBCFXPdmJGL +5xWu4JyaTYHML666D+p7VfUrY5bTnJUQ1xWZHd44y6LOU6zjWrrktnGbVY8MPmIkkCeU5tIMsbdy +s6S3wi/iY+fN32PhoWf4nLLiGhJyaoEwN9m76JRCPl7yFYyTiDFI01+j8hU9KrCqdfrGJPaAPktU +ghS/OkN6ghZJJrYaZH+V1SIanF02a6QeFYNoYEosXISGLbNm9dXVH9QO+tztFYhKALHQ9lQ1dBeE +hGkf4aTEbok5G0O7bAY4FVsP7WYgAFaueHWNCwkQV8us76ZsLFhvZ9Uh1lUTLcOhWrOe/8YuwuLb +ovMxA+tzc1zoBCr2iKJvWra6hNMHjcB7yULeEHLaaiG+FPsTuQ8YBG198M0MYiFP4RFGKkPDxQF2 +gO18TbbtMSfUwtMuoksmIBb4lEGMSLaGGHiuKcRFBiUw9h5xaGUu7TKmxFtXG1kQYA== + + + PWK/BE1yx3hTEKoHEwSVuRJzJycaUKlTkEHQxb3oyTfgxVDC2IsiO8KzmHDK0KxNFyC5V2q7avOT +yacbemOLS+W9QONSRE4FLA8QqmeiDDntt28QMc6AAc8xWa1AgggRmpsNgcH4XL0XkV8A/AwzFxol +xpUZpGVOU37pBAQF+47aiNXUP8YFYLOcKf8iaEslMP2sE9hEpVbHVBQq8cxF5gQefeLhX0aEPQIK +iWYrlaZXqHVMIG9TcQXEqvRjSzak5hCieg1FJSwZB9VCzAG2FGIzGAz6A4PhHnV5RtBEclatTo+Y +LeaDmasdi1PQcaVdRZgAmkpR1TXiJjAYSzUC4qYh3zVmhRwNEGbhlJ2zIWxxlECkXqSSADkDU0pG +m1ULWNeMrNdXs80q5H1dTCLHciIXouXF74U1BnkAlpfsluiKHMnFRNDZElLiss2B9/OmiQtBXKiY +bsRvIf34Bt0bV8ECg/CzvloCuC0OLXWrOHQlaJPI2ZcV36WJzXKX4zHUhCQtxeWyoFIhjqMJmrSU +my1PG4rGhRHnBo0Vm22xJHdEDy80RalHfAW0Q2SWbR1mo8YQIY6cdTgWAEKv6FVcBHEYab5j841H +BRNQioqa90uPjA6q53GSM594IDNTFjx7JgLwCPOWMf07guaKZr0pWXf2uXEPJyIbbF0V8Z81YboN +GcMxKapf4bj6xvA5iRCKmC3LquZtLMYpQdADpFSr8sso7WvuDMsHy1D/Yhsu9j4mdyqQnDzCgJIZ +TBWyO1kAIw+ohFvTRfKM4D+EPUL1861T4z2Q9ikp0kZ1HVgLN8XzMju8E1y1oeWy19rU1AVbinps +jYAYr+RhfY0Ik2jSVIKyw/AhdaadiNDNpYzETZoELuqU05ztHtAVMq1ACCfnUZ6Ep1WeLl+UAzD1 +Z1VliWH2PJhgCYp5QkZgzaeOiENm5092DsJSu40P1JyCsv6M/gIlMQh7AcdCHBLyYTKTACizH2m4 +wj+Z1/2VzHivd6h65aInOSEs0BYI78AjveiqsrMEGC2G3S9jjwHmmOhWsBzsA3zLWC1OFwkrNz1x +gM5FwEFLRNJ44RarprKu2hLvCKZCtznfgDEcBo8hZQ167gEPRcKFmyeTAcwFC5zUxAMTuLIWSw4a +9VyUba3Fd89+R8WbZuXvqBY5M/isUKAQYhrt9CbaV/TKoFKTiguJEXQR4bZkx5EnCiTIigr7XFLL +/xnNLIr1gMkIHDHzdiPdOboZWVVprEU+XTd/Is5Oj6YA218Zy7pppAsoFG4BClfLM5Ov5x7youZU +UNdsoTE0peIt0qawc0KKQKGW7ldS6gM1bcgvirZ4YBIzCFWN4uPMjDyCwZPt4QCjWTOJL2mxVDs0 +eHOOZc0LpIEDSPC5tPNf20rCxkIjIaxZ8JQGTHBacwArhIYUsvpBnptZTI21IRvuB5oRJUOeyafR +xnxWmPDq0q9bNWkvzV6spOAamOyWxfI+UhBNuhLcfqTDyyA8dCtPk9yUWRDEhvg87jxYChmCgJq5 +iq0HHjOIZYBEYoxiQMRyZYxwsBWPRme32MPCyZgZdgqD2KCQRN2YdUfGMZQM7ZoZmt9TLooErvUW +yrmbyVHc0ksyCqcwpPTNdy/4SYjBhasCus+iF6g7g+AHGEllcDOd+3SM8z3x9qmqHyLOs16p+aBn +k3BgUKO9VXqAVrdmZas4d3OjuQ52QebF2piN1gg1Mmx887U8W/IZBM2QKaMVWoAJOrNsk6sGm+c2 +beAUQEtJpQekguJK2IzBYBlTz+TY5GTvhhTQTPgyz2oewnxGTOPGcw41kJTMnkgyZ3HwhTBKf0HG +r6RR5HZ6FLUvEpBRBRH6xTLPkEjcAXY1Jm3Ckrf4+7xqKpdtLkUJoS+mmvTQ6KXO+nJwVmzmnGNg +A9bMBrCGGViwVHNODPdRK+wy6wpkGlDrEczCElUO0SWfVEkDKJB5vRCRWvQznHGMqYfrhDHHfjAV +ss5SY4zohsyEZ4TZATqcVg3Fp4kBaRaaWXrBuYeEps4F7wWJERyhmqmEwTAzU7ATdKdDZjnUYb4s +dso19zMYOGOybQkLmPdypwVEXyggIM48GaeoLYDoZn4s8HTg+yX2iyhgFJ4yoIn+N5mNILR78XwH +ZiHyPRemHqx6WpEx+VbNpLMxPEjkDNiL8EkkXj9Fp+oxhxEnQSZWYT4R5IEIEFVBQN7ODQYhz0BH +YtWjzWCHZDMIN8Kh5ARE4laI9FaHkN8M3y5cLUthlq5NTW0050fKM8wHtEWtoGJPVfM3krzOzMy8 +cBPfqklBhAhvdDolN5OAWJGYGcQE50iyDMXbpt4iYgHoDC2uz5IGdz88qNwr0DTTVc+MU9tIydmO ++RVG6G8WLLAMyRIWWvjgKhV2B6Yz437QHJfNHFHmQINItzCsGBFc3GSQd5eyDfMtQcUAetyPn91q +O0pnYa4JeCWFN1ZWI4wBvldYIElgmEgglGBp19npnbMaadkSk2eCl7FrcEdGR4PS7gjrhWYzgX6G +lb26wEB8+aK5tZkqa6tqhVSJLukUx0tSg9FDpJbFNN2qKaTskAAYUp0pw6OtR4EjTBarByZDBN/p +KTBYQDRrJk1IKSu8n4+X9NxHnMNa9ewsTfvNekYpmm5uQdhHu1DPQQlIgILpBYqCrqIC2c7F+ibw +g2uvrvBaBorF4VsAJCLmAASGGCQT2XDuMbwXGQGczrODimcwvClnD8Q78oA5u4jbEQgxx3YVob0g +BttGYJhF09DK+ZluqtxVFaYegA8dRpoU1Seo4Q6rylZ0wEntyGOMTQyh/ZWmn2ARhxu4X4Y9wWQL +dVsZgeIA8p+Y11RrIXsD+iJDytXgIwb3I/367MZLENGtaVawK5xBmIppVjst3CNuYPPT7MuiWyNC +/WnQK4uaz6wS3WpwNaHRBhNAJjZoHwBm0uLL7LNqo6bZCVGx2Cvss8o4duKd12GeG8A0g0W0OAFq +nfdEo2HCW0IB7sGiQ1BMgbOeOqwTtAMj7di9EoQdeYsIcD1MTE7A0W1pa72uNOzoRQOnCCQF2GdR +ZD3tj+vWPJygcXWDlsxRzoSmcJsxVAYEdDHO+ZmHyzJV8c1sPmgHcdnYjIjcRf6GTS/rhua6qhce +RLrZkCsw8PzqkiEbFtgz4OAwVwUNAQAlQUJe3RQCQt0YqFPocSoUgGllL8WPUymUfw96RGZmJdqM +02KA42LnIYJQWgK/zdyui/kPy6aONW5IQZ+ROBBcNnvnFxUmVsB5IAi2DCZZRT28Kc+s3RT6cmPz +cMVkQAik3mvWYIC4KCKNhE0N1rODHWC6h1gJvF/2qENAIph3oGjOmqjW6WXrF9EvC8t3yBpeRPc7 +k3jpR2HUbLT77LImE4nRrEvwSRPps8LzU7RPOcrQU937BugM0kPRPZQtHQ0YFv1Hq95NnhSXbfT3 ++CNSsIFnM2Z1Ls+0ckt/K1zIgiQxwdtZ3CCCTSB9IqMCQIAoqqEw69hOonKodzM3Jlx8adOsXfT6 +zH35zwaAmdXKka505bHfcPobYVrICcxN2gi67sEnmcTRam1FdTDksEpVE2hSZZJdpkQPaqTQDdOp +esb4GXHyyK9WwQM39TFwi3Un9BY1Kwisk8mO7qSZH5nM6Kra7KD1SLnf+RnMzXyrmeA91XwDD+Sm +IbkR4Gwp/cgOpW0GFKQOVDmHSwm6IxQ9kFIB4LqPYGIzy6IivqHlcaEvDr9Ayt5N4yFo7XPlhGqG +GcjwWU8igSBBS+yqPkpcNbckpciBs2lTFFiYmY1Xkd3zc2RyOJm9tac25R4AI4oaFSzvGPN6lGKg +ooQz/RDPl9qbVaTYRAhUtpyq1GGgOVSe8UKgGTto8xMnmEkFtaNugDykCmipxfQlQpGgGvIIdZdA +YXvUE3w5a1iLnBD2EQKWFoMbwmU9R78b4tYS4zPInBdzOonMRvvhmURzMz2aWlvGNFRNlICj0meN +J21xpHmBk4NnSiFngoWiy2a8z5FQNCQPLr7ZjgQnkV7HbBgl2vECa2VwXtrnavvoWh4ROoBB5tUy +H7PpyMAhzZqw0VOIhW7qa1C1H97ZlTmrTMdENBYl9GhHbq2joRSHyqykZQA1mHRpVoIZEC394Dra +D1e10iAlMPybbBo+exBCVgJ5Awm12wAJBkPbBGMFzV5H0yzEa3iZ4PaBebq9l8mckBPiYlNPsREE +GWAmkC9Bz3VWOBKxX/AzDO88fqxYngQembzpgvKrMlA9i1llFmZ7w5mumwIhSACvgBFyzi6GboZ7 +CLociHqDoZGZKIqm26IOJesuOD4A9jDaBmm1ZBbAVWshm/lWLQsFE6YOBlHgt+h6iSaUQ9/K6rDR +hTBrNidiV9Zu7mF2Eq7JVbN7VT2xUxc+a4APLZzouV9G+MxssMhgRlV037ra3cCHQYiucdEiyKNj +1PzHhMs8vxcEzd6xrBS+r9pOAbZTcGgl2AQ2XkiaVEURNknUCYxMfOhNnZncyhBdDKsZhgR2KmBA +mXlwAdwS8gnSWRIUFLuxDUQyOfQjkUEAH2bOMNmRs4bQZ6Z6QzbfHqJP/8OilgmG2fPE2aiIUBIi +02prR/tVdBNjYLGimXaTcanB4Cs4MAZ2EnjCsstSuCyQWStAGGk+YVhEtBnBO8Use1iPc+qouxlm +Ki7SrFkWaDXE0uZ2xqwIiRFxFGbaZdjOALqaVVUhKDEakwGBXkgS3DOFU+AhE8JjS0BAhR1PBk/4 +mmwZlgwZKIdZ1xlfjOdIw3eZ1AgEv1jFCoK3G952+MUIKANWLfhRqSAmRbSpRw/eM5ikCItc9TKa +JVADArJfRkQAiNWSclOYy9H8YiBA0idw0mXShCyAiVyXSDFCx+AvYk5qpv5bG0KBy1zfrapTBhoK +9QFF162MuCfACRAfeF+A9+44rYVaQw4GSMbnjZ8V9ZItDjcHlVv1oqguEyQgD6uCngg/Hi8TPrVo +uw3ymBm8L6piwmO7oJ8WQ3mUohtuItdyjSXovdJqAb1AZcJACK8gg7ZzomKdqy7f5zbSXGUABDPY +P9uuBEAwsW4QyLPipLrDGU9YFRaZtQ69ig0mCUJRuHKa25FOs6noM5b7Rq2GEhrtbFRYqqZxSJva +JlRoVJ0qm3VRT42DDTMruJJoXCiGYBCxuU+SIlfBRuhBwylKuDuYDaYLCHRIgOB23xmgSnle0GhQ +ms3KjmaqHcaU/Wa5HSq3qYcQmC9a693GDzuT68EMG4aLHe+unBHzMlB73wjqVlcGR5q2Km4mmFVp +605qSHs6Z9zuPWt+soYQXixeg0HLyaWWRV2P2RBm2O1n4FNydfEPqytxLmTH8YHIUB4QuQ8tsaUC +QKiQElZt2G0QvSkcvEAhAIYVhE3zFFELn4LRBEfbw9OqpvDcZojKw3TkVk6IhWaniFRQgeCcxuQo +tMENASIbj7Z9JdPez4Q/t6tdCLv6yRfMmCej/tPDz37z7u2L178//OR4vH7+/LtXvw== + + + fvPuGeru4q3sJBJICwQ9wCoKK8Yro1bGYYTZZahiWXfCrKg+CghMFw3LqYN3aCojXgLUuqogQYyr +xrwYLp/SKqNbQgtnyIrugxVxpa2d92QUDFTCzYx86nM0iooTnpi419t0ujP3hypN7ojCcWbFhcAM +xUOdcWQbVJvoIsfJqmD1anjcNFw3x8XVraCTmQfGziqKMZUJCcEoxCGfXDjrrgkq8TSkpKxWYwuS +CBq4AQpNEK6raThTVfAwnp7CJ5yRmHX+GcByMBSXc1c46ivxSJrll5AaeMSSjWNhvEe5aiqvng1d +SSSODwQMNj4HG1VGKOGqdU3tqgicI1PvrXoVEQHQ6deg8Q3ksJuhZ/TNoMkFnjRY9M2iGj2K25zB +qcBhsV01GAcxVzMXJ4GurEUOs6hZjwTEcmRLX9KkSDw5iDq1ga0JbCdTGkfkIwxbqOG7G5VV7g1J +2RcgcVAwsyUF0cMi1ZFFZ+yNa6/ZkrzwOGjLpuEx3uoPDczzF4FO96uYqIYpIjB7qeJsZEwrjQIA +RoHD5HmwdkdDGefZWCPEPhhBUIujSH9ExOc6e1pi0GCpwv42z6ud2Jm4/cOSxlYgCeegL6ZXzdbX +yXSRxUIVC5CBENIhTTMzByDG1Rw8wCtA+OQWvCnPU1P1pmD8hWhO2Ay3js7HqRuID2mVsKvmwHQW +6sGFQILzOQDydzlm4bALw4GRPfHojloKp5nurcgZDzmX8WX+YgDJQ52tvhohqHFZFXNF8zyajTH4 +Szu+CplysIpgpOYeCAIgAjgpIc3ajqYRyqoIuOeQKfaR/YlmCqTEgNRUZpVs4BMsaAcp1mezEcHp +JjIW1oe8uXrJ1qpSwgzoGs9xQYRAXdUVzZutUWVIyhJYjcAl85FWBZyTAIsMxISGsVnpqiVR4UCs +tTFRAU3abHjVNAk0LehlSfka03iiu4Flg/0esjxdOE4QwZAmGb3MidF0/tVCK3A6BOCPCzHYiotu +8SWASVEoa7X8/PlCcG0dCAj3dJXSiTWpyX6hm2Au6q7H7Pf5CHfE5gfDAgiPeFpY8AjByrPmRYMo +yMgu6A44cJOanbMeeOGiDoAuYzjhsoplNK/RlVYSx63FkXC243x2tMUqsgg41nnRtUDMIMascSus +8I0+4tVXldpwZ9fnIZJg4W20at/YQIsEFVgJxoyE2bToRbpimLJQvd9NowGRZ+3BJc53QGL0xIhC +lXQZT7TQrd3iqhcqRZVNEVBNAhLQwEVO7s0II1ZY23pBPxc9ah0TDx46grZkn1f4F5DosWqijKYv +YJgVGDgjHUnWTMiUPnEwQ0x60hU3XRipITEou9oUc7NVW9UAdKk7GjEs6NnIeFM9T6JJQbAqIRyQ +VJ2O6h6kfxp6DgmE58FB7foaW6tZ6y0K7quq+ZLCV4wWyUJKB9DRyMEkZpseNxyDyTHYV/RIupR1 +R3cMR3SgkUE0iDsBFJ3PycGLjBpW+KEDu3lQEadTUMcJCep/twgXXkegT1h7zDmpHB7Yq9dZM9lv +PNABFO3RWTkeKd2IVtQIHygtbJrKlJyC+VdUFVjUI2cxEKntphppDisb3wmYNuLuAA60pPTMjOyE +ZhKjcdxrzQZZCATkrSMFesFWe1ijUbPFq2LaAZ4S9LAElW33cvfnlO0JtOeBMlUnsyZTCxrqBRmX +cexAGRNkEM0bhjNeCJxbNdMS1T2NxcIa03gRHg9D7Qa6ZdWT1rn1K6P3syuyHsiisYSaxpCerpnr +hlkNoX9p/oPYLtoyXT1+UdHkf960Ema6cJokyHvR+bF4psWgsC/AHukPY+AgJ43az/hmgJtXHjqj +bnP4IaTJiglPhKcBvqK5eXgvBs9tfMSWMZHnR0Yu7MXySsBxTaS3B14kc0eFmTFsTB1HV9Si7m4Q +Aroj9qBJ3CvCzRdpKkQdopz6E1ZLXTarEYhXYQvjEdXQpzVFmkb2e/wcQl/g6QfOokW8wHyPk1g2 +iykAOgMnCwGdRjsVzoGh2ZjmCr9qtVRcsP3PmvSyAq8wQyrGe+FccRi/mU6hBbGtBrEAll/9dcDD +w7gLh2yLV+AkxgLpwfmgoifhAqXdiweXa16QzM0OlIIwfOTxXFsIHCxnkMG/mK/03AJa3H0eIYhQ +biuCFwUmT8vtKwShlLmYkY3HLFmQmoakw0bYodd6JBnPBDZTGKL1mLIiKfqGhJXHDavx1C8rUGig +6bkTmZbqkD2XQ7XME5ZStBnDOJzF81Ms6jEEfJ75QJLtUYXoBrUnrpzry2I5LaFqwRYGLKCau2c7 +hnUZ7G4VgEsemmq+caAS9KhUhT6TAHV5GSMG4NHPPB4IsUV65BfTiIBhFzvbi3N0YVqKfkDyRg/d +5uGhltKT27Idt4SsIs6Pb2zMGMHCEK6gEZJElkQzjNLLDYNvXLrGS586wJsgMsiInvdI5wrdigoM +yDSc04TQrINVmGBcNLiwxXlHt8sWS/mAIw36DAlqrI3Zcn212Nyo2pLGSEIKM2s6323dFG3HYxYY +CovAu0iQTLSIWjJrHDY4zz1LCEO6ooeew0SM7TuaasYawG4CMVnaeX+WsTpuijdm40wpt1n+DsTv +yoKLm+aAaPZtSEgRW/Cib0ZZKJrrj6HgVV0ARFPpqC3qMeaiD3bINlZasph2AAgx9bAk6+zMIKsG +h7yxDFhZs8JCElJ4YDhW89qgRqpLu4xgbRA1Osei6pO6yPgZBohU1AChV8GIIYwpET6swZ8KsvA8 +NKvlZUAIKkRxHTOsLDghNCaFlbA30ciKvSmuulxTGWzwcLMw7WZRlRcEGgpAYNgTCHC3gOCmMBAp +aKAtRgMjBBl2TxD8boodKwohfG47IdXFFakzqiYp13lVmVuEgEPwq2g5F3hVYD5yJUZD6sM6x2xD +W7XPgbFzpXmtQESkggfUkUDIVvFwULj64ZAquoL1sqIJAnCsXbXc2zTMMSsrAzmznrnCMOHZ+BxE +XI15S0xzucy2OUePa80KvwaQyC0pFNxg0YZjdTNJLupn9VrhMyd1UNebX8UzJBCox80BzVT6b1f9 +RDRStKA4FV2CoomgWCyM4UmGAFosi9Bi4VbuC3OhjGlTGKJTNU4mJp56ra5PomNnWhOHHQZYEpxh +sbg/aLYD+BiXt1gQhXl00zyEO9IqykArV2swp+H3rRayRCTRYnYMfzfKTyKFbdA5KJbREb6al4ah +2VF5IwBIKpZlndiLZzNGh4HHciwp5iUNa6FA3w4L3PSobUi19P7hxGYekVboHdZcQcxGOwhLMHRW +RekQcEzRGTvbprgZfma+o6rrzq9a6QJWFD0/8wQ4T/10KoB/VukefBiLHKpzXPwUSpldmEg8ATOr +F5N7bEmeyGo2AGrSLAXK5GeV12DHY4QyzICQlPOq4dBM5YD9i+mgSk9ZxTAuEC3fAw29aDs5gb61 +1NUbtE03PzzO82wHHsBbwFzwRAwGTeMEiL5jUOhtzJoWje/L4wbBMWFPWZLl0lVnGz+rA25uvl6t +tBXrEA0m1aNfcPOgFjp326mIHWxHQS1MYljooAwCII8oLpwl3KQAgOgtA6hmX4f3jwY5q0UCOAqa +cUADPGlUQIrpiTznD1aJYqlTmLcXW0wZc6mUqgJNq4Xr4SQjMA+T2Al1HS8zIvOmQx+oun0DD8HE +59XOB3KCym5VreOt1jareRhBN4yQboS5w7YasXoWXxhGAfip0eSrapk06jJ4aGtUDlGZjsLSEmul +tWQ9qIDh2nUnlkaNo6uLBedXgwQBgki2hpsVvazZsPFIzF4AIiBxDP9CJDFPWs6GDwSIu5obhNMR +SYoyTXSaT2aLmpI1XqlqxxClSkNjg7yQiMWHIaKgDAJc2DgClQwbKfXgGWKee1+eWzSv8UZjH1GN +8AjiM3MWblGxK2impVUyMQQ+HyZMRbaxSG9Vsl1vs/VK24kj9DAfa1IjkkeKMeoIk7cwYVRQY1Q1 +J5feLqjVpdqGzssA6YAJHXorCBQBqwVR+2X0LYMIDywDymb2dWJc4qIxJMzslrqTcIGdC5m8NL5w +1Twe2F2ZUYEdy+PwlqKqrL6apRADVRWczZUrUGBo1MA4JGKBqcLB0fpYdTMDRlU3OfMIkFL5FIvC +YGnV2Jo7bNE9OSyaRz1Sc9SA1Do2U9RNrCPuDlRAEC13Ov1K3AYNiKSuWCPo+wU3gWQNHMACBD8H +GI4iDNYZM+Q5RZlCscSMrR5cKFDpKDoRH1RVDcNztoAbgr1XCyZWDZqOnlWjhJlxgld6JHHHV9ce +TKxqBPgZnalQ2SgEIfkag2yXOiBuEO0V7B3p9VI1etMjdKh+d0oYYgs6cdEc6UXT/MDByjcicDl5 +BA6sG+xU+LIizcamqkCXbIkHVYRJFr9GO2epHeVj4d6rZYiAXqQJHCHZb5ppSeUT2kL9aOdUNCg/ +hLXfwdJIWuoV1uH5csBUpKZTGqAC1lxNl5U3jXJG5Cd3ZcKomHhjHsH1QeH+WP7Q4/iswapp6v2g +iQ3ZYe3wsaAwKYZmUbhGmpPVRC0qacxMoMbDqng4vZJZXfPQ/whvKerx1lWcDEhJf7oL2DyDgM9l +rkimrwKr27JFjZzKRjefUfD6L4+kcP7ghv76yahPsu1+XJ7d0/Pcsp7+PWbdxUoNpbakuwuPpIot +5y4Mvjjkaky5Gzd1L3rKXRw6ivnvGXczzxHJY8Jd6NKYwZ5vFxqp3Lel24UOVfVIwZZtd2FMy9qS +7eIzHtVz7eLzqhl6W6pdXhNSy7SLdkvZWqLdhTHruzS7QChaSj86FGFnhfVck+wmQ24NOXaBmaYI +bCl2ESgJg4pn2F0NEbVLsDsSmV93jZa81dPrrlHNt7vsumtUJH9LrotM7v8fe++260uSnPc9Qb/D +vjFgGxiq8px5KbVlWHZLFgRLlmAYBN1sSTTYMwJFmfDbe32HyMxaq4eSwC3AF7ogp1fsqvrXMTMy +4otfcBEVbN3q7PcLrcskWx5B1q1W+Bis2zyN3lxdSCrFfjVWN1hnm6qLiI0++Auqi6hFLuMwddmb +Z66D1GUyvpQ3Ube5OGQDdVuR1m7zdGno7Y3TbcWchaDp4jh5HpZus4jshdJFSxyRC0TShf6xMIVn +kC5WZkIpXBxdpj9LPxhdFgyNA9HtMyRMF0MXHn+xYIlz5xjSnAZBF3OwCP4XQJdTda+Hn8vKrUAV +4xOL+q4XPTcqlozPRZHYPOxc/unC3B2dh3ervKfJuegIoxnU4NxRGSK6sbnDkYqg5qLXAWbKgOYi +yY6CrJuZu9xYI5C5KzFTEsBc/MlZ4AKjYZdVg5a7kuYXw3LhPmF1crNyZ1ceMlC5+IKx6gxSLs67 +at8NyoU4C/GU4OSyJBafSnByOcMR4nYThznt1bE5uZz1TLwlJ9cisvLi5FJDho/cnFwqyJKkkFpP +wkD94rzhVV1r0+Dk4r4/1oY+yoAzv3xRcpe77AQlV5+x2lCxAoUzMoJbNyZXxrk2zQ== + + + Fgaqwfumaz0a3G5MLt8Vyq2NyaW3QkHWtRsjjzcmd5nuHJRcsBuSPgmKUKHfb1pwbUbuyvqlQOR6 +ARSA3DWtn7r4uLDhYwo8LqIKqN0OOi5Oo5WbjYuMO2MlQuPi1X90UOpeIZajoPWAcReq2lraXFy+ +PDWouJgrseK7mLjgk7q9D8OzbcnBCiJuO3S2PQI16/6ChwtmAX40cLhNir8bhtsU9goULup78StB +wsXf/JWLpIcEBcTCwcHt0eTIuQg4C2XcENzuRj3BwO1ODAYCF/FuvDI3AZe1tH0EABd6JL/2mtWS +0ng3/ra6lCfot+CcUd9n+K34d+XFvq3GiwT7trpKJdC3+Bsol5t8u49j8C0THJA9C3xbq4rhb+5t +8eAY2FtEoWvpQb2FD9We/qLeckW0SkBvc9dzD+btZ9cswpESAWNynuWNvEVRBEJTJt6CFtHEtyXw +trm74M27JRzimRt321yuFLRb7JMpsj2Fs1hpqD2kWLf4nc5O7oLYtqx1wQW6JRrhouFW03EDc4s8 +NSJPF+UWdeZl1A25RcU248dm3EZnsRtxC4AnXikTbZubtZ4/KZS7+bZAGJdDt23Z2UvDbfE3S5gv +tm11fjnQtvw+UdQtsu3+8wLb1qkkXIBtPxZKKnw1rKW5guDG2iK3DbpnYG2bawiCagsvFHf9htrC +jel1I20xkjB5YaQt/rmJg7uJtjgV8uQMtEWiDAXAwbNtlbG8m2YLE78o42zxN+560GwxfEDuccNs +4XARDmqWLcR4CLMEyxZYlSao+p4ckHPkICuSLbSJCEwEyJb0y1JfHFsqGT5uUmBsq4MBQbEFeBaD +8w2xBVLxQthW55SDYAsSJT/kC2Bb2E8kb34twZMfr0fga/F3WuVFr81L/LaA12YF/wJdmwkNf4Fr +i1sHm1tbmL7KG1tbqAzNL2otUmZZRU+sKAaFWecl1U8HLHy9kLVIQeRDsYUig6u6ANZCUkCk5wtY ++/G+4lEbWIs5Tk/IUz2q8eubVovSgjYOrBau/zMOq/aR/PyFqgVqbYxDqsXNuTi1D4e5m1KLiQm1 +mEGpheSxqB2hatLYjv6FqAVqFvPCRtQiLSGKrAi1S1ihF6AWmbNnbEAtymIOnTZbhndPqUhhJtFP +KSjgNiUfNO1SB9QXmhZZYxTyBJkWFW1tHTBt/H1zacMWWNqltbyJs+B/Yo19QWlRUYlGyrEFnf+6 +kbT774tIG7YA0qLeB0fdPFq/ZjeOdrFcvG4aLcrn4aIEjPbhEliwjK1Z3LqioNFC3kGYRdBoH2rF +yptGi6+TIpGg0f6OaSWsRQNH+7BiVizgPeCg/LOXi0YLrwp/B6qt6zO/WbQgGwIkZBTtx8vCMXCj +aKlyLG8SLWbpJ20QLXA2E/HLANFihGAI5AbRsnv6nAdE+4D+jMh8kGixKsbAeINoRdFKh0P7mB8X +GFoEWcp8UWgRMkZUKSC0kMk8rQSDFuPOM/ILQYsZpaOu1ARaQAVYNhQFMwgVlfLiz+amod/8WVY2 +q3iZmXb8PcXd36kmHKa0seGzyCkLJGTNZlNo50LPwg/rKsIlt4l9l2bd4FmIDBGEubmzYQvsLKQh +c6ZNneUNIXrj6MQhMMK7EsxZSAEwBgZyFv/O7hAXcRa2yd47krQU13EHbxYZ9txetFnk2cmUNWy2 +LMNNzZoFw9aVy7uKr1oXEqRZjGxcRBgh24pS9TdnFg474nVhQ/yODDpTZuPvGzK7bWbMojnvwySu +3qPPLms4tAgIm8p1IWbVEGP0jZhN1cVUGzELKYJwWIcwm4qzuJswi62EG7WYB98LAx43YJbWdFFi +YRBuNPiyiRWBbbz5spA+sBT72rOL5r/5srTMXN58WRyP8sXNlxUsdJXDl5UWpnwCzBIuXpzAYIa7 +ZOclAjBLdOpI8w2YpVXIUQNm8R/MaW7ALP+D6aWbMCuwbJmHMMurQ3RmE2b5T8lI3g2xytPVc0GY +ZfaJL0YQZvloCEm7CbNIECkVZcIs7tNTZzmEWT15Jr4uwizzYowUBmGWbFNUlQdiliB6hi5vxCx+ +AGUvmzCL81F+LAizPCTDrzdhlsImRhmDMEscfnbfYskss4lfL8KsJFH9AGZpYOeQAMzCIi7RTZgl +nJX5yyDMIlapuG8QZhn4U4bxIswyM6YPyYRZxniW7xOr11YTZOcFmAVzQRpk8WXBQCQwO/CyaFSl +VmkXXna1qC41X5ZbjUOXxWGW054bLouQDR9ssGUZmFJRhdmyuA4qkV5s2bX8JQRadiXx/DZZFsmB +VN9cWcQJ1T7MWNlZhBvbVFkYsN58QWVnjqZpZsrCICqgkbLKXpQ3URYl2iofNVCW4TNk7TdQlvn8 +NsYbKMtLzk8/QFk+On6FAZQFBxNxyZsnu1yLaJwsYlUM/psmi79rv1mysFBWYpQsDvAoukaSLGGb +H9/TDZJNzLqntEmyipM7ycACAsx+wiheJFkOYoQxB0mWN73qVRGnATcKo/qNkmVAfaixIVGyNCDa +FihZGkyg3ShZ5WBa3ihZpUnm2ChZ5V/WfKFkccqUhwVKluU2rK+NRo8oN8X3cbNk2eIAGoJgyWJo +57dmlizvCWvlLpYsjYifmyXLzDgi0MGShYFJhJslC2MQaMmSpQFxlWDJ0sC2ZBdLlpJHamoMk2VH +EHz9AZPF8EHFwU2TlQwyz02T5VaYvYImm7JzFjdNFkamF4Imu8WSoskmwntGe9FkYaQvETRZGhDG +C5osDWwOc9FkMWqTkmuYrIj+KwVNlq29MWDdPFkYWSYbQNlEamiZGyhLA6u4L6CsjEhWGCjL47Dg +0EBZGMhyv4Gy7ISAbHsAZVUskVcAZdkHlO/wBZRVbQzQrAbKol0NJ+0gykL5TGHrTZSlHNoYaRJl +UzXa10RZ/s13+kLK0giJQCBlparOyhCRw8VfozbpRspKRq3vmgINNv5ZqgUkUXYrpG+iLN26ljXI +SeAJEj+dmSDKQkT/pE9AWRgTiyGDKAuLp6gnesDXk2fcSNl02hcYKctjsWdEIGUhiqfK8oWUxTXK +zwqkLOdjJWhNaIN7Mz4RZal0YnlZEGWxnwragiiLGyGywU2UhYTdVHcTZfFi8aMIoGxq7hj5Asqy +XIaKkADKsguXUrMGytIXByDpBsqmyHhvoKwsByf71YXfzj3G0kdK8Y2TFSQhb5osxlZKo02T1YNf +6YWTpRG+WOBkcWgKmIMnCwNnpZsnyzT5HBsny78xSwVPVoa+XjxZ/BjSyIGT5fcggCT9KMwMRpFt +uRryayhRCZws85Kpb04sRqHZ5gsmi/HMmUXaerTWFEq2Y4B55oskC9tj5uvUJsSUiCMLde58UWTZ +ie7jtgVEtrs20JvgTwwJN0K2u6VrEGSBjXoUFEaMCK1iMT1c/FjCWFcNE3u9tr7psfH3BY/dJrNj +p+fcoMKClcoinYscO5qixnubIkBIgGPj74sbu03Gxn6cO3WOpsbOR9CqCxobtNxgxs5HQ1sgY+fj +hlEXMRb7mPzK2My0gCR4sfPRq3vjYodb4AQtlrkxhahIiwVNgNy8CxZLiGiZmxUbUNFAxSIA/TEQ +3KBYmPApBSgWfyMXGpzYIXLrTYkdlnoFJHa4e0kwYhmkzv2FiO32EAIRi89tskRcHtyIbgEXITaw +UQGIRcMbZDODD9uzkvcXHpamkjcdFrsQSWg4LKA/zIAeOCyIWGVsNCySmUg5iwwLGBb7kdVXfovF +PsGFRWKWchVjYYfXhDcVlu1MWWEqKGzXGieQsN3Qv5sIyxOpmwfLNtOHBtsZ9qovGCyLu/AmmgXb +TewMFOw+xAHBduf3ggM7nDR59kcsCiyoFAhFAAKLMSldyNcZbTIuBCx0XFydxDZLy6UAwJJ0RbTr +4b+SWIEaMqWS8GfnPRL9dVqvcNNfp0GzAX+F2p3VS2a/AmWLMr2L/LoY2i0b/IrVJhs8uCA4/r6w +r9tk6iu4Ll1kv2HlGNcZN/N1GQoTyFesw/i5BvKVeIOmZlEb+QqjFMWKWFHXweDRiNKVrqn8Ir4S +iDQUb5Q/AbkVtaRGvnILyk0v5CumMI7agXyFQ1k273UWPfEb94plEir9g/bKs3m0kSp+4SdMI1p3 +3QBcBVxp4F7lJgiSqzZdyZ1ib9yrXYWyca8wcDQL3CsNLF++cK/0s3jixr0Sn4ChJ3ivX1yOH3/4 +L8p7ZQgNDJ+b90ojoozBe1VYreQNeGW0jHT3i/jKoAiEJ0F8JeaBBxfxdVW9CzfwFRfM1XkAX/dC +MICvCHuxv+cNfFXrQzksJL7SgHOuO6DX5QjUO54nSkUAXxVR620DX1nTR1L7BXxlYOlxMkuyoi4B +eRBfGb9gtvpCvm7H0MhXvn8WCqgunq4sMvQX8vU2MuaeHAEP5CuRDk1pmo18pdAcIpZAvibCdnPe +yFdDK8oL+UqFIPUARr6KCdbKRr7iEXKRcyNfUZ6BJWQQX1FWRGSyqlmXm2rcvFdokgyVptcMnxSj +QOBeGTuq6vK3ca+MdnQ1NBZ/4HGfzsC90tBUmXdqX2isfeNeeRxEOAP3yl/L80V7ZYyOvZFNe+Vy +sLL+gvV8jDCRNnhgrwjDuE8zq4PAbMIaMVCvLJ3I9UV6RdEQobEGvY4pbltwXoeLtG7MK2xFFYlU +tQ/XiwbkdfhruCGv0KUtM10hhBQtMwivoyuScwNeR3O1vfmuY6gI1XRXhFjIKr/grujXgDE14K59 +ubul2a7dsbYb7QrmEIJGQXbtiuAF15WMotFeWFc2D0FmSlRXHAFvWEBd2Q95jBfTtbv6MspY0cMi +q3KdNWs4c6y3b6Ir+w/XsoGuLLTOefNcwYqCk3fjXOHyZp0Tk2XoElh0GYS5VlcB3ixXrB3dvJ4O +Zp0bAMuQP/6GC36DXNnQfOTNcWWvnFw2xhUAUihXboor6h/pchvi2pq2CYYrlC1YG98IV9jgygfC +FYqYJvQqV5NQzJjWtqvHW1VCIgCurUoOe+3DCqIb34p6cJa8m1kRTnjgW1FLgvnzprcCNIHfCXhr +m7snLcd8VMGQrHuxW2HDpxPo1ubpJcitOI9iQlzkaiEDR6jN4FYkFMdR94EIUCSe3ZgWXOlyrQDA +pVjcsJzezNbpRvI3snV5dRPI1uU+PUFshaaXiLcL2ArBKIsYzWtlCc1aG9cKfTICcBetVTLmzWpd +DmMHqhV/x68EqZWBebjaQWqNEHqAWlHXAw7CzWlFjR7Xnsa0LmP8gtK6HM+9Ia3ICejNiICyK7ZD +rCqaUx4vSCuNxApbPpWI0cx1Q1oZzoavekNa2eAaob+AtGJiNxyQjNYU7QkuRus5khmtMBBBE4xW +qvcRlLgZrfBi4oVQmgoOOHtnm9Hq1Ox6MVrpebH1gxmtzEBi1glG6xeHLYJV34/Rutyy5YVoRdSV +Qv8gtCLqGsULXM9gSk8mtm45yyKlzNBWDBcwqBDUdFbsxgTKDWdlUaK8aqJZV/BVgw== + + + uKpw2YVq1WsL348lh7EZujZNr01YGH/yOheYlW448/UBZuVih6nlALMyhOcavo1XZRiPtZHmsvK8 +UCu9uax0cEne+rxjr9LZq80xK2Lm+LaxrLSwE+uNZeUOrIUxlpUXjcnEWNb9941lZTiX1frGsqoy +d9aNZWX+itUFF5aVwW82iBshW3uk7AwuKz3fLMDqqSmE55TTxrIi9s6iI1NZ+e9FCNhNZeUZ4c4F +lTVFH4GgslK8j0H0prLSyI/aVFYaOKSYysrBDLUDN5WV3h7OO6isMLA6NqisMFBtflNZuajk2C8q +K5UNSyEj/TpGh6mE0KaycpGJuxZYVrzXEO0HlVW5xVJfVFbyJIA0CCqrEtypbyorYvMcU24qK4Ee +TdBVjYVg7M0DZVVEX+PVprJSxYBAUVBZaSiisCKAxb2qAjenoh2aKN5rU1nJpUsK5g0h3pJu0E1l +heABob6AsjLXNg+TFToYBi1uJit4WkxP763gORC4YCgr0h58P24oK4xsziooK2BAdAcCyor0DCNE +N5SV7DEsOQPKCgM9toCy0gCp9A1lJaCH9fyGsorY83E3A8rK3VjrckFZU7ObFlBW1LVyWRFQVjXv +BkP4QFmZtmK9iaGsPOkqX4BQVuDbCAq4mKyw6bfMZE0k1dS6maw0IG5yM1lhJHYsmKzcitdvJisP +nMSJ30xW5P/EqTCTFU+W+Kpgsm7DzWQ9RjNZcXAGJIK2mqgvzvPFZEXGlE7X3iprARNI1v33RWQN +WwBZEyFdkCIYyLpfxhvIyswn6rIDyMpSYSSnA8jKNJYJ+Ke7O4xL7pm+YCSxsCoJICuTUfp71znw +Ra+6+U0lyI94EEQ04F+xfrx5rMRbNfmQyh6XYL0FkJUhnHnzWIkEfLIkNUOfhqrig8fKj8nJ46vD +RJVrYB4r/u5I4AWPFQZ6OjePFUYG6oPHSoObkZLHSsOj49TzrWSlSU1kZXaVIqcgskKvxpK4F5EV +j7mbs04gJiv4h/qBEshK+RaBIReQlTqBLAi6vmisn5XNNZAVbx07P72IrLCSD7yJrLTgkWwkKy0U +tN1IVh6Prc4DyUrFHKtSA8kKC+NWF5KVDiazn0aykmA1qD4KckgyKfJism7bZrJyMqIuM5isvFez +fIKywqpXylBWGLjY31BWbkLNzA1lpZVPKKCswn8NY1qF68wa8V5QVoroHrOWumbOrqFiQ1nJKFA6 +/4KyMmDL+uSAsrIGklo141b51vO6LygrFy3p2Fb0QgsE4DbcRNZjNGgHLSxEDTGP9YuP/V3d+I87 +UYWZODhWVZWnTWOFt84VVsBYEcnt9c1iRZCI5bVGsXapqzeJdaqE/QVi/bANAlONVIVsAsHCALFi +1YwGPTeHFeu4fu8yoE7cEFbrPV8MVtQCokjACFa01xCHRARWxCtbqi8AKyTXqLA3fxWhL9TMBt0U +WFnIP278KmyTSFbRVxGke+Zmr0JVj2KZG70KdTYKLAK9ir8XQvwmr+JvlPfe5FXCaz8+hCCvQnsO +BcM+NYhsuRo5KDEmQ+AWC7sKdXXB1+7SLlDpFm7QBV2F8oZ4aQ2oZWl8D+Rq6WyJffFW4UFkLBeM +W2Xvtads2iqodvWZb9hqKdIDbNYqtOCNSFaXRMCAAqIXaRVGSEYDtFpIuM+Hs1oQUSvljVktS0pS +UlaRCSVT0y8KUs1skXAxVqvZcoFYZQxsjU1YxYKd69oLsIroBHkuEat6TC0wXrVbZHXTVWGjzshw +VeyzlJlUpPQxf+BCqzZLnIKs2tx+LsCqLaaaA1aF6oSBdINVIYnAe2qsKpzDkV5QVQRCmeAyU3UY +MRNI1cFCvxdQFQnwLFoqearDaJ/AqWIXIAhumiqULsx/GaaK2Rz8ZbNUIcNincKFUsXlYZIOkiou +nxlUhycRPkSo9eaoIvAG3WJgVJmtFjmR2bquQv2bodrN8w+EapQIB0G1u/7/Bqiy4UFZm5+6iz6N +Ty0sTU4vemo18yrgqYB8Ij1mdmorGx+50akESeS6yanNbYUCnNqsUry5qbAVAVCpqiVVoudNTW1F +oPmbmlotsA9oKrwodk1z8gzVT+zpdyFTKToYZRNTQerAh2NgKu4AlJQ3LxW2Z/WNSwV+cUp8Q1pq +YeojvWCpgVIJVmph+XUOVCr+zLiqi5SKu/FIOERQasGrJ5IJE/yFlfnlhUlF1Q/rvlRYUbKmj4Ck +oqaIXNeLkcoagNw2IlXkq7UJqchT9vHio+auIsvAo+JvQEOCjoq/n7pecNSMPMjTDhsVZCF1mB5s +Clv5od9kVALSbQMYFQIO5PgCjIqXNQtwurmoDWij52BRMTfCKQwqKuJDj1iqG4q6WDOeDhO1suLy +IFExbuk1OkTUJtzNJqImT5kGouJVqOmFQ8UbBHcjaKjQTSJ9ETRUzIq83AuGCkoC9A/BQkUAUSlK +TDTIsufxiYQK9Uw7IFSs2fUjJL+w9WbJbwzqx4sF2MSmoFowuiGo0PXW8magIvxQ6kGgYuooB4CK +DGfqb/4pos9rHvwpXlW2DTD99GPir6qIPPDTIucl2KfZM3OgT1nWi7foIp9CXNHH5p5iAUESXmBP +UQr0pE/UUwDg64aeIlH2yKXC0MmlC9WyF/NUUgU2ZpckFjFEt1qWcuRhqascyg09RTRdtGhTT2EQ +Gt5wni9+7vd0ojFsDq9PA3oKVQAUV8E8DXRSIE+Ru5qilG7iKVbikEEG8BQlzxCKBO+UxIG6XrhT +jELwFUw7bSY1BuwUf4/5Qp02Z7iDdIrsIOLuATolPQQy3otz2ppoIxEoBiIJ3kYATAH8cH5qU05n +2hlQ2rBY5h1Q1SLQNFiN34hT2HAjg3C6jNk34BRkSP3rxpsiko1ZL+imqIJhYMvbIHGGzNLNNp1T +bT0DbRpgz2CWjql0xQ02RXgN/kXY+pQQNLCm8fdNNQ1bQE2HZ9fAlY6uReTNNIXCski+RdtMCq0G +0XT/fQFNwxY8UzJYV90402GEwk0zhcSUJBPDTAE0Q6A3YKYEnOXxYpkO96INlOmw1iXApXi1Sx4v +kClgoMafUug1TfMOjCmUbkHtDIop4mtF8ULGIvh3ORRTxhHTi2E6DZkJhOl0q50gmLqx7c0vZcyy +1cCXMscpchLnOuVA6w0vDWpPsEvndDOYQJdOf3wvculkNlL6LRclscQlwKX4OytcvLmltKW5saVg +vUK0ENRS1KfAB7uhpet0DGNlF1GwIwWzlFUe+UUsBR4IUaAAluKdk27evNJo/fvClc4AMAatdMVq +JWClLLtq880qNYl2k0pxPqsfTimKTliJd2NKERYkqjrzPqksISCl+wgXonRGDtGE0ukUS/BI49O+ ++aSQPYp+KjzpTLpxGzs6qglkN520Byo0jMi0EL9pNinVw7O+0aTDTak3mZRcjF4OmHQ8p/40pL3j +ORWoQqs97uwRVNIPg+oybyhpd7R3M0n7E4WTLrvdhotIemwCknYDWjYQc2SV97x4pJSs1G+bRoqy +ksC40amorn56sUjrispgo0ipT+/RcUnK8mjxtHOGyO6kogigjj2DvGeqRnXi+wUhbdYLbAYpklqt +bQLpCAruDSBF/hAy8uCPcjXkjVAbSgKiqWihokA5UDHojuW1NUvFtNmjNaunxQs9WrG4DpApbjQM +qok2ebRazneDR9HwTmftZFvkegI7+tk5+fE7Oj7/lTr6t1JH2X+JIgOMpB9jrCSzpbk7Lal2Pbkt +09J2fEWxkmC8nIaQBEObNae7uxOi+8Txp1ZXwOoK0bu6loRaiySXh8FtaGo9Iq075zAM3ljvZfwT +i0qfQwsQmBk0OiyHYKHGSyzrR7gAtapa9DXb2fNBwpaYcKxMuKI0uTyNKYtwzstBvrjKlqbOZIKl +Q8owVh+J7zRGFeigyOtCLS58Qi0f3VYgs7AVd4Fw4KG2zyrebEmODjrZnib3x5oVyEnNJZSwsP6d +mVZCs2Ap6exJiBytrYs07L4VWJPigmGhjBMR6Blg/uae0mzyimUv27Yvni3W8wy0Pxo12VA28u+9 +Kp/K1nCsnGchU1IH3Y+5uLFdOJmM6CcXxUvsMd65gMQ8wrKGKn4zuhKTNcr+O1S+A+UTCyW16am2 +DvfXYdIFFoQu+XfV3zUgizRONdRubJXT3VwLlt6i4Q8iy7T0cprDC9AGCS21VHjkasP0iAOauvPq +2jNyYlxeJG33sBMGFLGZHbLReJ3dqLpy7XgJ6jRUCj0HCEPlY0LoGl0HhFLD9EN8wXTJGG4hH7cS +DBaD8saqRdVwpBTxWH6r058SLSnOFl6f90PmA3+zKIXHZ/U/LBjgYUmBDcB3y2pqPHEfv6uwDG9F +wRMAVX1KyjwuqQhXP1BPswMxPi/V6WZa6mJHZfeFwmczpidrWCnYoBVEP1oGf6ETWUUDnOrMiord +dPBRKTSshDBlFfHrUAz75cc9LmWJSu/lAk9YpY0j0dR0fZWI44Kg28qS5The8YQMGsdT/0jESthy +AKNyVldqNkcH033fWlrBHIWVrwvfG+bosGRebNnt+kVu8zgKwTbY7OY4FIbidkL74xcS37gm6WMa +84wi7OCM4mf2fWDAkL4D4hV4OpWD3zBcBbQAjA66zkKsG7svoHYDO2qzaQgcHyu/g6UCFD2TJQ1X +4oInuSM1eTHQPOhvCd3wd4q781hrmwjZ9X7CnMR+rqrfR/7Zz4OiB35TeL67FQROlH7PsjQ4zSXM +ki4w+QexvCXDCXCIRTAjS1f8FoEFAXg+v/n4SX6VaCC38uP3j9MedGJP0guuYw0MOK6KZXtNooRg +Rd4Pv6n2k4OZ7EKLfExqzlbsmY3PgBKLPcZWMagfzFr25polwJJJyUqNW+7CgZdMyToW2w0NdAUB +OYzzag7a+jXiwUrFYyO3G3/rHDCfkI/SLf2lpcQUjdpFrmtoRZK9u7Ebj8QQIeeR+MUS2IaelSxL +9Jn5Zbi1HHuyYGWCSBFiVXhbiSjm4DO61OrsXsJ+AQTpNj30jyMt/qTeO8QMID/R3D78VpGjzk4A +UX8+PBRDsPUxivrxYraXP4GVB6qFhsO4sHyM/Dp9slPY9211PUwSJMITWTP5meM/YHj8Fnzc0CpL +4steGN7cP+nDQdmDG19N3AG4uvnsWSqWGNvyRUKQr7cnGb5RLQbnzUA+hL4ie9RUIZJ/DpeSyxJY +WccCS8pyMj+GDzcDfTmjEQKVlJduRVZLKzL8frVRShFYJ14yAhOzltSJOtbuLtiJfXUvL0V9eGEl +pAAW1sYCV0FnDBb6vUVQN+/ZhKHXyjmpF5NYQR9r69WL/Ah3PrFFLhU4KjNf2yGEyve3VNOtopsh ++QJthOvY3IAWFViPW1s0ksnZ8yu7SRVUR1CUjR7lfVBB8sWEzoxPqAeq5rYQCaY9Yw4nrbFLofYx +sOmqisIXOP8lN4uxSpw/818/29EtxDyBnN+GCQecepo5npdlCg0XLjJRFfh4qNVs0Q== + + + sRlr5spWikVVHWRtzFCJdbclQSPuxS5a+A88X1hI9erumsQd4xtivQ3bHxYlc2gpMiy+cN2lf+rY +Gj2yWmC32EeDIs7g8lPgn9XydHEkHc6p7tFJk3rNGBbwtyYkpCzZrDObXDZI8qp7P50/yeGPjt/n +cs+XqX6dlKjS0vYaYPi1Y+HUI4EaBcHoWFNz1dikntrdCaYfvXqgeFTvVlVzERaLs5EKx0N221yS +ej592FlFAvNx67RFghPXTVldchb6LCTm1pImo95CIsjsK75kdEwlhgLJTnb7OVLLoDJBhry2UG1a +mjQZDU9q8jvdbJWBFu7JImNEsvdHUlM8gu6VDemm/DYQf8UKtGbfs47AUwBgikM7nIlLjw9ZYyRz +UNBXUcW8Lco+VaXuz3ZYVXEWBEynPopg6f3pl7tqMdjH/V7+lBBFoiNBdSW5QdR9is4SnzNSTQyU +AaAygudWDWNh8o/EoZR7YFfK3lPqO0JbGECeZk3jRarEs4ANt2Shw6897f1BiZIfl4Cy9gK8g8za +EddB4rXgapH3lRKuojY8Jen4JAS49Y+CjSxTpnuwh1iEJcNnaAbrsTqAPkPOLah47ZPPQKVGlZcy +qrl7ijQSuTvddgnfSLMuSjt2D4qUAkw+bzWCp0yd57AtaOAZQ8+xTi9aEXXlKAY4P6dt6CXlEdqi +Fz18trOdV1d0mpC3viyUlXjHMLYmajGxePwBfOpc8O7XFaQSOBF6kgjG42TZR7eJs9Mpic2GGD0m +5fN+tV3+zsI23bOIty7/TVHXQ4zklKVuXAweW9VDIu1VOJ6mR0tVAS212/nbox1IX3S2KWGfqhJw +X7BlGijiV8XApFSjhxty4aS6QU2mL2uqi0nh0oElEhzCQLTdIRZ8j/RBGNpkYBWibwiBafGeH16R +fjDXaMyKpQmH60pJpjhKALXA8FAChx0ZWyJrZH9XgBxRKJ9EmmYT027HKj2O6w+6vMC0xKKDkuLh +98MuYrKfCkF/49iXPakjMFSivg1hY0qq0flGIz8C1LyvYHRO+QWKEZNUsMXsiPrII2vJrogeEd6+ +meSy7E5teYQOGNZR7fOxJW/x20Mn8JEPo6gdLHhmGs8fDzMUPlUJwFnP4E+gcD4a3X5E3wPPtpJa +QBEpYge9+VNpvmMlUj0jgiwg6PAtg/Vxe3Wxq6iTTHpcWjIRnx/ja43wJ+umMcgRkNZl0czOsgkS +Q68eP3zFeWPwsFMTOawXqo6xiPDaoT92nFdA49BcTKkWoNmGhkf3+anSkmKe28kOWmJVtpusebud +OhkMO18WSPlWD39yWxEfpuczjHRBJSBfxs9OfqwBMuqkK6rjIczDO6kWWcg8sRd7VwAsB0EsY3rA +vJ31DS5uwymay/ZqnFsuloFkfGCT2Ium1/TjG5APkMvc0U0Yu+gYGI/QGQGKs0JOiWotYahIANFQ +ffmwUov+2pEMNB4/6e9M1QrcltDT4vAsb6f8EOEEvN2LIaMsFTAuAs43wqScSXiJgGINbgaPlhdk +glCmYgk/WdxynKdQrZGEVQgGXgBiGmDkso1xMdgOFrRSoWH3+IJ6Cu8YD4duxaUrDZnpdyGMCgtq +AniRzSoR/iID5qVpWsB27E6lc8X/VmkOcbEMHGlHl7bhebdE4Sa8Xao+B9TEePAtEANLxGjuSRQ1 +Lynpdcy5CqUAqSA6B2WlcnWRO/bLN0s0gqVUBJ/M4hN85E5n1EMw7I4xsjqlD6tiybAiwA2L4sjo +swKBEgzMCHDwWGnvSKcyVzcE4aGwcISFhYf8ybRssPwqU5OKU6xJaWtG0hns50vGUO5QhTTuNBug +Rchvf0gD4QvF6QCOJjKc0akixTIsYwVivzhMjbK7h+mCIlIeN+OzfNTtHIae696PYfamaB63YVgc +BAoF1op1uGRSBCb92QCJoj4FihMvjRUL4SRGofle4hEPy/kQd+6RXSBglK2GEUZDSLVlxInQ3Yqn +Suhx9B1IIjHSCFEk298SOwQLJ26IgUgvgq9cgqUMPRA0GZm+N9sd2wGDxZ0Okl9g+PG7IRRRJGwk +nrXMymLbDqWKChuPd6mAcozEvExcPMEiwP/UrD2lWH7sELGh6pOV2mH8cEcL51DMlNFH9Xl1CqjD +H1cvWrya8Oz29wzrYMx+qlCWx1LAGwNGNKkd2jHHy8O2D4vRS/oYvCs1ck4YZ/iCkFeEZ/RY9ZGz +wWZMOiGkhXtA4MoDbRgf1uMhH1CVFWMdutgx8v2YQ5uTWxWx72zRjiSR8S4lM6RoJUcdV7aYOXkM +W3tMZMvshjeGLfl8WuyLzbuU03J+RecwlbUqRtw8EEm4vRNeLnGkUTLGTwLZLObg5/IYj9vDRqLk +K0cnXnxoyd2cMyZBf4uyUEbJ77UyOQQVXbQHAFlL61QXMWQqf4u2Y/sRbsPIB7o37lA8BORwi1f0 +VoEShqG55VgOht7+aDxgYwI9Ssjq2S67CRyVCeUejt5yoivOX/EXdyKnGKOqEDZGxxItZmGBehAW +1XHNcqo7YZUnMqWOydRqu4v2/kmSQNgyu8fsDME2V6GUI+L9hL819ci5iMiIFGVeI+Sz2g3dctg3 +Obphgv9Rs4e9hrcUlvZomx4KeVmnbhk7HfBQo8vCMQ6/14p+cZ1frBJ8IjG1Et5bhHw4QqGQUP5B +V2dFnDu3kas0FflnSgHuTCaB0Ekg+k5kgywNKCkiObDO0jXesGAKlvVMJ/eYV8M2q3lyiTeHQBj4 +H1hwcaZhgyxnBTsWbLD07vQ0lcra0/pKWNm1BddEkhdHrEqKWVYxvpJ2zjvCIRTqCWpqTlKIk9A3 +wkiCbEZG5KcNTQY97/5h0CTaqMasTO9rqmVfDBga87Tr1uCjJ9lQSpoRaB6pcZp6tIjjL2a6IoQT ++BebwQ/IGbI6kS6h0vxulpLZkKp7eEUoVT6hwSyYFLgwosvCkZp9buguk6OFX9zg5xwyXgxMBbEQ +vGXrgbeUi/LdmYFZvMsov3FNC4xt4jHBV0XVQ2ZgFnU93MyWwWEAsaBidVimhiJru8a3jASmKcvH +8lE/+V4V7PUCBvu6l9YfrzLXC6hyqm4pzZ5xsBA3hai+nD7k3Jm26aoI1JCd3NBzdM8JidVI+JvF +1jBwOuMWY6y93wMnhtbmWWg5689AAA1K3fWz5sGOFCIw3L2aEqdKWLCJF9PVj8Ab1bUpcmqmZIcM +qyclolnfjcQddZRwMHYq7+DHIZtVtjm2GzXuDdroIB4yTDGj8KNG3BVW3msUgmVvJw4xQTKPLC1C +gdvth5VTrRpw5xFJsGs75rKYgeuPnqT2bCaKQHzOCHYAYxFOU1AMWErON2GRI1Xk/JztVjPoBOoP +PsNtAbwmBYztWB93kVme31lfztMGL4GL5rDo3hYF6s9m2X0NatQ2bgsj54EPONbK9siJhF+f2WCT ++zkdQG3zpIiV56TEyK0DYGG3AeYplKIz+RCR5BMhmtE9F/Hl7u3YdxEWNvph7n7lsEQUfVYTatpS +px5mwOECoBoQzYqQlyA8D0Fo5mkYjUAqhGGjFsEZWKZPlrVYzOczUaM25X4Llr5VPDh0gmP+kqFw +yHYwEaXdnxe1cOG8JbbxddNzJV1B9WD6kWSvonNVVwkcqwZEachlYYaKLH/mUBFiKl2OJq6anzi5 +h77CJoU0AlJZv/cI+cHcA/8DFoVG8bbk+EQeE3vBwIYwgdtRsa0JSuFiqlthKNeOynDDitAQKcVN +BPVJNQ8sbBSD3kMnv9ndCLkWh8DYYDk5lUHl0W5wjL4gOdDbw5xSWL2dF3G0zKRAdpZ8GdCHIOYE +QZlWZtMQ2uaAAQurufsyoCiR0rCDSkvE8yrtDi0lKvz5tt6HSufGRgIYbjuKfNOIHBidjHSPIGHh +ZTLp5DYtSdsZmSHAJ8KRqCbhUBIWjSAG6Z7t1nBdLClbOAsoZdYmRrU9aBmXX5RJpEXcBPzHI82C +rtJTe+xIFJEY8Vxelugpk52Ehlyfcw23iTELLQy4HOAjGdmrdvaVmVzuHwPIsNFB/LIuqz7ZeGQO +h3mLpqAR8dunuyYNE5pIEwjBjeYFKseLEoqYtLEFXZHLWFK5w46DfLAYgeAGrrAo1Ytt6tFEkZPG +w9FxgsX7cWKhgSNDBsnMu+32QyOiI0UsNUbPoT6TFAw3kCWo7hmFa1SjJ+T3cbO5HOSNZhwYbk1O +6qqA21XctptGXjgr1au8PwreaMFSjxoy6rQUYS97T9VaF71RNHB0RTydUrNs8Sg1AbXFTz7uR1Sf +6PDmvBxClY/EfG8368cf/otCfhmIJHOZ7UgNhKBV2dpuURnDkylZrlMcipzn71iiSkgF6enTFV3x +8aEWbope6Q0B+yW7azIduzIlgf1w0BXc0kK5Zy2fMxEDXb7YiQMX1fowXbjIbohUc9sx0mrnpr1i +pFWhKGqN2BkQP0BxBIpwkXHLJcrsYenPCXVK1Mfq5CS3lzUSKGVvXIiqPzVlFmtfZDjH7JzLqEHy +2h98Ag4K2c2gEwu709xvjq1TUxItzDhAwcL68vxYT0dNSxl7T5VBFEeiKM5low3Sh6fEuRphWFw+ +w2VeoTpJ+mwoZiSQDxUOeclt59oP28xQZGTWK8BFZrQWK9wAtlEnzsTC01wvg8ewY8FQ4ikhlb2g +wJq4O5GlT+ZR0aBkRf1EnTh6w9j44j3OnhaPFtyGIxgR2/NEyNxv7LEaNjmqzGTxbP5JDuiwjFg1 +Miw6dCIMgjKmhkgjLZ2Rq2E8BPeMAR2q/KVTYyExPGEuqnEzJARaLdqluacNZ0qUFrJ9WIlOM2gl +z/Ks4qa4qhaghCuf0GMiw6urrVqnjItUz6KpgL0jk6vmaIhZfdeEFYdfKDCrbuxCWXASskoPjTc/ +9lTynaUBFI00oXoT8yZVs7roGJAQWbI03QKnJivGocIlTB7JWarKh0Od+Gqogo3Fz8NIHbskcOno +WCosmidHtngVs0UODw1WzpNsge4Fl1SotYYzE0lcWHbCcAw7q8gcZotU2R4Fec5KDhVqH4clQU88 +SYjemKPET3JVgEUQP7fmyn/+hzzZrFGFPwlrs0xRWVCkGhmUoxzWKX31noOlRIcwaDg4ZFC8mK37 +pINJyaxFA1qbUDIbumysN8AxxeqZkj+KAPNjrQCLEkYNYYjJMLrO6WaHWF9xDaOO9JXj+qAmDUIs +YplGulY/3RhPINuoW4dhySA1Ek6GgydqAHK8d+TDQhANa2sSqqk9270ne2Hp4FvmKg52YgkcV/he +mzBzS9XI8LSunhWx3Er+ReobuXB3CxD64ZiCGA6hQGzok//ZL4E+SsrFcT49Jj3KxZGfxuqhW992 +Mvm9q9ngcKiCEzXVHFsdC8uwrj2FC8LlgqISGNOKfltOImTHjeutCele5J3D8fXScDjsiiFdYovZ +pKqlUJsrXWjYw5N83AQeRq7MmYvgKZCF9UjhzdyOLNvvjfZMaA7A2NrjVAW3Yw6Csw== + + + iH+SBKAYmZlv5fKYaY/IliSGBKsqodZsku7wRmiA7S4ghRyUxQBPNLzsSfE7zlF87frcAgA4nXqj ++k4cIAQzQk7scJwaVI6pyf5nZ1pUWTqsFIR7wQ7xfLryQ0H7bnpYOTSasKpqbEwXAyCayLpQ/AJb +ChP24KPvyMt1vKauxwwVPk3fIHlSmP6zIkdLAi4lE6KGAlY66syVT+nXJ0NybCibLJ7aNQ/wICmK +hcacv1BicuwOU3z1RiP++P0QxnROCsPQS3GbX22dKvRZ4cENLY9p6dXhefKPsGcoqxhHZHorP271 +zB6Xy2Hn5uoOes+snmq7TqZLr6kHzkzacKFS5i10GLQ52UOLnBaUt+V+b2cMMgvAtLDbmT40AFvh +goJa1uyYF8JHqqhXXAlirlBw1ik/drzfIdunK7BNTTvPbdD7HRGMTW5Y8N7zcUozWddECxtVIFeu +mpvkeqDEvsN7MemSuSEFOf9VnRYehVC3heWDVstiR4ESkRnj+iVZ18Q06fLTHKojGoo8xdPk0ppF +VDUrz8GHDkPz41UpHHacPe0d2XOO1uQEiTQYDzDe+kU13HmsX9JFFnME4fLpIotDOjMi9RjQOCJj +LAnlDFVxj4xdKdcV0xrBXTKwOAiG3M+OAigi0Kx3fbkRISxcEiBA0+337BmSS2vNKdWjXBpqb4RY +lU4CIwmlZ9O9wn+M1XZXRWpi2iy70xCiJRM1JUpEWzWwUMIQO6pAHh2QmLvK7vqaSMNno4riIQiB +u50rKKEzh5XDKET1DOmMxw+XWR1Fx2oN5QSMDM9hjsQHAcNwEI2RRB6JjjgK+veLXp64/9Xroxzl +s1AlI7ZIzQxvGEpxH8NEIQpRNJZDftLg6AD/UvkGMkmK8YRFmSSKJK/NkNXpSXkH5dHh7WRXF28/ +KZN5jRkd6QuEL3GoOYbeRE3VzZCJxOYBcZkoqeA6fMXXCwaaPsJhcQD6+lALvbrCsbGnItqor+dk +CguhGmgruLKOpXcWlmfGb8KPZH0V1r34gaUkFxxu+k7Iv4rPMbpST7yzLCeY0oV/uMTKQ6qVOsAV +kBtmLL5ZXQK/YkQwAwULUajGFDHE6TqzqoIEWhhqovsRM10totPCysQoN+PNqEoB8NgaoKoCJdqx +uYEyxjLC+SA/ZPoD1A3kybZhDoWatOO2ZgcuahTpgLcDRWuu6Qjkd+kSVEvy/vZ2JVZpkxyMeltQ +lRzL321dTdmOzP6EFBosVXLvV5aptdIiHV3VQRZ6DcnmOuvqO8drVRl2aqeqblBoQpn9LH4k+vTZ +EsYO4KP9xmh6lLs4id/EHHoijDDDsmqTy5kpxYGF2k94r3vEQ6EGfdsecoShMDczlgxIwN3JzAw7 +D/CjXwI2kdFsmiSlfMDLYUaUnxc+wZAk7MUWrLNaxaFqRMXOkix0tbH0GTkkY5tICrdu+njMKsOy +lmQQnNJh4IhflRGPi5RyaFmpyYwGHgwKX7M/EdXXIuobCxiqC+nBIBNArRjkn8le/kI3eAyKnNnx +VtAz0YC3ojvT8EhQkpPwIOBTmYSIVZcQoG53q7gBGaxNL6wytNILFKkLmXeQYCCPvaPURPDnJNac +WqrTn+NVFldHcZtoGk4PF/EaTXZ0u9QsDJfNYjuKH6kUo9sQY8+2JqtqqBsq1afGJ0m9rFz3LfLP +lOvOYakpJxynwxli5ZjL6jvqAuuhKdDK5wRlHlYKuP8LESJYpPhCRIyiuXzVFFLnyeJ38nKT/pmj +CubgqXVIVs6TwlisiGOKFjsBYS9e1IdTxkUfgsSTuhTIyHjhYdnhvmddViplpHQtIhQcS54K02rP +be2utIbqJg1pF/QufvH0v+dqgpUXghVNvdcsoGSXmiYKtNAM4OE1qtGz04vQa1OhgG1SLD2zG9iy +BQJEX6izUG1BalFq0+1OJE8QXJoTEex2x6pvpahdXeSgWWAyhqvAdNM+kJEh+fzsN9SDYB9flke9 +5XZomL+o9FDSAhvhWWr62LtmuZB1qSSBMUFeI/IjzLZT0/+ohlQ9noeiwIiAUsynTs1Rw1ZdgMzz +z6o4IahHTfFKMVQFKeFo+qw9m5N42Vno0iKBt4EmjV2beYUjhKX4RVZm4Xe4jcRq5zynlSj4kp8N +/3/s3UFkk6bCheRYoEZVtZu1W4ABgvyul6oks1QeTwUnaAVWyHZv4k+yjQOjkmA1jVOzoERZSiYH +oLKkOxNLn5yxVCYBAiGiPUMTA2sdirAqpJ0exQ25Dd9yCMDSKe+Tb4p0IiOt+AHGYWAhPqUm08Ww +ktgJWyBtilPCSvWi3CnF7a/u1W1K1DjemFI3/oyANHXYkLyr5pJIdGsSJ6sd9T3LR+mr54jr9WnK +PCwUc8DCs81NkeLYUxh7LE0ic69AfW7BM5kir7ALSgrRByJ7esYjCC3ZmVcUpRGQ0zS98WNFskDx +0qrvAd/TiNJzBvaQnFLI//HnDqH9jiWiulPJyyR5ArQipO2wAZ/FI6yHLHcVCcQVlLsQqZpV26k+ +9QHH5Z58hwujRBE1R66iq4ba1ctFnY4TsbuPqpLZUCbFcP6jn6VKn/ARiX0QvZGqQ8AUGTDMXfNZ +niueyvxoVs5F+gfnpJiilVCjK3Nc9wcNK7sBEMZV9QsqE6oRiB7moNBy3p/k8DSAwKQfnJryrDWc +inbxmIvzCrxO1vbhNtRHYTY2xGCCFKX/ybXiGvZRz1tv/s6joiriFSCZYcC3etXITajhpZw02sww +Lj2kYaM2ncdnzRcgBdSQoOq8FRt2VxAXrsCaUtVF0tHiNztc0/zhxFTeCCrm9DCz0/KseCziH+nD +7MFugGiUL2dHEd0eRrpXl6hbSnz63SIeVjJV3Sflt7DnCgru5lnBqgqvoEh0JxhpYRSlD0VRtCca +TTF++bgrQHUHQvYPoYakBqkERU1YCehhRguL5nombsc5D0FllyrzE+/jykcgv8l1Eqyz+0tmoAPn +ymo6fttmebSI8sFKj4ZWFrKX6vguGhvpF60UHJKR/uxZVstZQjQez0Z67aZVPYiHccCrxo9wT8Si +VB05LC9KqizhfVNXtVCjVMfDYkf1K4lKTgmUmiyuVUanQObxhr567TkMxoBYGi8sZKwcpvB6PPZ6 +nnjVKdqVv1T+JMos02JbqscOQC1Rft2t3Ud2OuJC7LzBiD6sRCAgZmqDkn3JHYM5rz37Irvw+Jwm +eW041FR5IbM7lHOkZEuUmuRkWRiKkkYqnk+qi+BJ5spRzBeJxPAJxR1i/ddS3Xahe8QyLk24EtZj +/bRnLkzD4LmqIrQNT8zPcEVorTFVm+zRrupbNUHgwmRqqtaLj5UE2VNPSMK0tthXKccNHSlSLp7D +lmAcSmaRM1A0wE7XJwi4gbtJRrlPcXCshppJGNGm6ilm1vcsyzqjLHKIkqiQczX3d2IGnvXSrB2G +Y7r9NIR5p2djqtPpzneVwdNdoYGyPVi2/it0HSyPe1SlrXR4Dsjal4XBd112SK7pNf5Q3SaTsHzD +IE/jSQQbD9k5Q+OeUClXkTk0YTz2FRGyfCwdFniVvbGKKt41LcKyuRJAldAVgjWwJ2qvg2Mt49+c +laxnBYZfkMACMawqzbFKfdEuejijK3oaWiSGSIhp2248IT06ND3jiIueel38ishSpvBwEDhWGt0b +rRH3xjXODFhRfrkerS8i5Smnfz2en7Ad33FEIUvVnsJTwLKdDTSl5HS9AoqO9KmCjt6OFg5DOHqI +SngHuEKaXtfiWpVHnEYOJXaIM3TpQIiIgS7t2o6toFnmsyxF2BZEx86ePcrXHrMPp1wEJWazcrxa +vodFvuNU2uBsx/B+U5ql1fvv50jvtpVXy4kNMm8qtCC6pF83gy6z8pX3DnY3rcVlR92bJYh6aCB1 +YL3c42IwEKLd3dtJxLWSKQb4yeE9d1CfiLbhCkQRrpJRaogfE2UCCShLApaTRnxbSWRWJFJEpmAi +rywBKF9jjlZkpcf0vYIMNtlY1W87o7tLY/4K8PRc8tB/9u85Ib8U0uTNZDoVFmO4pCrCjgdiFv7O +miIA4TrE4WMb3KybpGQWmxWEVgdh/KbA2K5nZBUcS5QSWW3JepjlJKF+Mlk8v+wvcE/qaxYV/zTI +/1yu/48dlbZHpmEslQtStcFmxi62Ys0Sj936SbayPwqiQi6IrcLbIIREiogYp3NY7WgkMMVZjfW8 +wyuw5VUgy+ZYmsQ6TpYJ9a2m15kh2s+2LksyBHIyuFl5NL5REZ2jSVPsyVkeVuqkaSEWEp2Ydolp +HGvGjU0rstH1MXlnOR/HQmb6fjF+bIsuMymmw3JtbofP9FHgUH7S3M19bNHwMQxT3dthhmGAH54o +nXFq/7sy/LvSizUCDLdC9fsITvgo4zYIWeF+KoAftxR/nip4rWkw+DE5TWaRpR+qDec2sbACCojB +0OKqIq38Wb/t4v9jyXexyrEmCVmpxXc+nJdEHXvbpV9tbnUQ4TJMSpPT1POBhcovai6rZNQ2raO6 +MqmgGoSCVZqoq1U9PIzvWY739rT3JFSC1vgFkV+zSUTcRu2hirqQxdys+H0qRtIBGcTyfHhSnNUp +cWuqvdoFGclIVII4MYY0g+Mzmx8O4U+EIkVgJ2Q+XDby2nEf6cgDfKVycK8WidcoVAcMqRe156M+ +kecJtMfchuEvulkTS4lCDHhc6cUFaOhnlnC4JpP1AJ/9rB+/oxP3XznafytHOyoMXhhtRMnSUBKb +EUbEtBmNMUQb0WxGPG6GdlnOvAZDG1T41VW+xWIKuLuky98EbZRnsuzJAO3oPLX52Viusf/Ojc/O +SwnTTc8mM4Yzf9ShL48xNzubuyVVqjAuh4MP+xXEj+SlYrWbm12fQGsam43IELMFQc1u1s+9oNnR +l2Yzs0m0d4aTGptqPdqLmH2MBmZXN83cvGygCQmTuHHZQBvVIjY2p+JatGLbsOxq5cCLlc1kY1Z1 +MgeKGoqqIGW3mG8vUDZksOI5O8gdAMGNyWaJQBXhNwry23A1dkCyUSzNETUY2ZQylPJGZDcXEG1C +NnqrZQvz0fmrqG7x5mOz/ZoZ2hQy4yB5Hjh2s3zvxcYmAK6Vg8ZG/Ekt9UzGxupv+AQ3Jpa54NIP +F5tFZ8rNMYHYZyjGLig2+t0Uy8M4s4JO+wxV+zCuhimavO2biM2JvAuTTSA26wGNHie+LsoGXzjs +qHrbPGxChr9tGDb/XHo2G9iMqjIlgI3CFllZdAiSsEcVDeXmYA+HSTYG+2NFw+TXpmAv9/Z7QbCx +WmBHxGBgLzUNDAL2SloivgDYFNRoH7pXODJfu6BfL/cTfsGvZ3dWNtjXAER04rmNvh5LzK0X+XpN +9TTe4GtWnZWsGgIGeNlQQiTEmynONhNVImJx0pEwFb7a4GtYlN24wdeJLnQKUSk7XUSXmABf0yJB +6bzZbt3L4ABfY/38hGYY2SssepiCvLHXqzqtFthr9OPQZoG9ZkMMxt5u7rWsU/WuSg== + + + 2DzJYv9hCN3jisebew3rkILe3Gu2Cekua/R+ipXe3OtlnvvGXkcToaBeo16jeS23odeYL5ZX9gw4 +e121iddrhnDtAl7DyBRo8K4R1xg5f9u4a5xNk/pvVzKjwbPCNmZdr2GyaOiU13Dy4SZdY63L1E6A +rmdTjWxgrlG2ayjnhlx3t2najOu25LFtxHW7GId76GpWZhpwDSAHfzr41k2KzBfdujkuF2zrNk0X +DbQ1DPuXIuuKdAzl3gG2joafwbWmzlGf0qZaMzdBnaKh1j2ypsG0bsOv1I20RjJIMSpnRaAB218I +J8fkFOfNs65R+RU46/qEBtNZe5RDNhdxbJh1NXRnw6xr1DAFyxqG0ca3F8r6HMska+Z/h74qqn5Z +IsPK+QOyxqJuWmzGRQNyiSoWMsYazho52DfGOvdTQESKdeZEJh9PuprPnmCEUqXlxowvzvLFsEZ9 +DNeOgbAGJKWZV02CNWZ4RhZugDWJKI/i6KSHtCh2C3x1a84D3vRqrHKIlA14NX6N+dRgUrOLX3qT +qwkFuQHXNYjXwa2OLrIvbDVSLkrpmlpdV4TFDa1GMo6xzptZDSg237wAVOOUmnGOYZCO8QZWA1le +dCiWCeLvqGllvhcGFeFfsOoaefpgVeNaOVkEqvoYLlI1KyJrOqTqFn3sA1TdopDk5lS36FYVnOoW +pSSBqW7uhndTqlnyIRMj4Vj9KW1jRjU2UP71QlTjjHjXglANsgSr1ANQ3apikTeeGjZ9iOZTw6B5 +w3hqDEKU2Nx0akJJiPE1nBqiSYaeA04NAJGqmi42NVK0GruNpq7NItYgU+ODZqbuBlNTMfIoK8pa +h+qgxcZSl5hmbyo1kvA3k7pGdj6Q1CXo5DeRuoS2JIDUaECq0kXzqNmR1MKDjaPOKENJ2k0EF7Xq +2yzqvBQzuknUhQlNydPpTRRm9lSnw+BtKSb3XhhqlMsrgm4Kdd7FlQGXBswmrW8vBnV33itsD1eY +WdgGr4mR0XTXg0Og5vKsHQJ1jzI+8acfJ+xe+GnXph769OOE1IZPY3yv+RN7+hHT76Cnnz95g6fh +V6U3dhpzIHoGb+x0ZVNW6ehV9ViVu72Z05NB6PbtMKcfYbEOcno5rfIiTi8nAYM4zfXLwU3jzzHT +ex7P1oBv2DS3KvliTaN7pHHUhzXtON1GTXeVkB/S9DbcoOltDM70cmgi8NEMEaZxDDzH5vDr3sqO +8WZMH8NBTG9bEKbzrvoMwHS8ijdfGsUAjTRi4aWxVGJ7oaBLP4xFpvqmS+MIuY0ZeGlhCmo+eGl8 +0Oyi/MJLP4Q0lnLw0r9j0q32dPjSIBWMad73HrHgfHTm8QMvbXDEpkvnIFbfcGmsspmqCLb0oq/a +vgVbGiPRLN/eaGl4BqxoN1n64U9WqxngkKJ8/OP8vGOQpeEV1TmDy/AxGWLoYi/OjZaWUyAt0CZL +o1gSEMQDlsatSpYrPvoIqDZ/YaWziQSbKo2G9E8TKIIEAwxbUhRdTGkIRrp7LWjUhrjOWA1VXjVr +dG6gNPmj3WJM6b9VybZ50jBQDnLjpHGs0uRGQTiPHH13+l6S3OY41s2ShmvY3RuDWBWWh09dK6sA +CX0d+dsLJL2NwZGGIoL1xIGR5i1K9U2RJuakjAORLi5K2gxpbMGA742QhpEPJQjSECI8Yx6ANM7e +2pRd4ogL4NAU9OiyhCje8Giq2+hTHnZ0DW1OoKNRNMHlTxChQROiHOIGR2ONEV0xaeyPoZEBK92G +mxp9jIZGt2X1RTCjvzjV4XNjCDIm72JGqy/P6IcZTZ0cy/aCGU2FIGXyFzIaHypjARsZjc1EEA6F +FTDGjPVcxGga08V91sud1wZGJxagtvEGRuP9Ikfg2rGrL4iB0fx7mk/8HNz6kB51A6Mhg1QuMYDR +EiOVT8RoQh9YVBrEaEoqGVwMYjShPsyh38RoWsUQNjGaj2f0dojRlK4w73Yjo6lWaWVuZDSVKgxH +BTKamyQDtg87DvJ6hosDGU2l6tPqRkZDhSNq4Y2Mpq5dMGAjoxPZviwwMDIa76TItzcymsJmBkkD +GQ0LIQibGS02kknZp19gUn+ljYyG+kiZw0BGUyfM2PONjKa6jCHWQEazYQbjq0ZG08DX/EZGS5bW +DzGaBizZNjEaFtYNvpDRuCRBnQMZDaG2Yt6BjKYcSbnXCxnN5rrxHbHWmrErZQSNjEZcohlTG2p5 +BM4Yww1g9GoSum5eNNrsqenj4UWvFmXMBkZzo3Fw0TgKgZ43LXrNeK6GRTPgxshvwKJxGRR9vWDR +KAaKKDtZ0ejkTr5moKLJ21UpToCiERFVF0RzomcRzm9joql9yQozb0o0+nSr/aMh0TCI0WlGNHar +xkhvRDQidipSNiGaQUGqG4IQzSbfzBvehGhecX6U1FBO6nGPqE2IRtVrr+PbCxC9XNm6+dBsre28 +B0GH7PotevOGQ8NWXNFMNjQOo5Cw0NDsBf4IeRlk6ERxQjKOQU1ogoIaaGjNJO6IuNHQ4sAV9yNl +tzPyFpaOJbAIqAkc2282NKwugDYbmhY0ewk2NA0Bld5saFpZmxRsaP5AnUGChjfOhNaa315saASc +KcbbbGiWNqigOwpAUNXMD+aGQ7OcgirmgEOjQkH4roBD8wapyvKCQycVv69vGw7NftsMwAccmrUN +j+kwGw7N6pKNlQYcmhbGgQIOTYs6K15waCpRpVIyHZo9hZprKiXLAC+iu4xw46GlTiU53Xhobkc+ +UeChMR2pvfeNh6ZXo1aHxkMfFWvgoWGpQXneeGhY5XQYD00Do5OBh6ZFzacuPDRjcawKNR1anT0s +AxK6B2EmDm43IJqLIwpEghCdCP01Bl+cmOZW6C9CtKz8dE2I5rFUvypCNAzq5nATotkihaKFIERr +EWBmtJbCZRyG+iZEq3iqSVc3VdJTPNcHIpoLlumi/42IpkxbPHkjoqnk1mdhRDQt+gAuRjStFF0E +I1pS+WwWQPUCzESDixEtYbwOp9U0/JFlEj0R0Vvx/kJE0ytk/+ZAROOWSVAYiGhFMz4RohnRUG2t +EdEMZ3CKC0a0Ahzd+I5gRKfTzsSMaEdH5mFEM6IyA9+xf/PjKuWnBSOaXqCS27Fixfz6GRGNxYCE +JMGRZKWNikCJiCaZLbmX8kZEM/CrLg9GROM1I4AiCNGpRbvcixDN8imqbIIQzdaA0giZEE1PPqf6 +JkSnLRgIQrQshw/9dQWw1wYYfZ+Q+wcfGklApu0CD51IvngEOpJ/BxwgiW83H5pWSoPNh8bxJTkP +QDQskqXfgGhYJWc2H5oGpQUNiJaFCa8LEI1fZGuq4EMjMcl8QOChkckLeN/GQzMPyTKl4EOvbr1j +YJ8xxEUSbNOhR4mMrI09OgwHG7qjWtwh2Y2GhvExu5kzCwxC7RgMDSn1VARru/Zsp0mdtanQPUpN +Y6tencG6mdDdva83EnokJ6yC9Iy+2pxibiA0icqrHiN7Yzfpw4mD3oabBn2MhkFPz+cb8gyYkyq4 +LhT0aA6L762KsDebBL0NNwj6GMWBHt3q08BAgypBsNtNgd5I7IBAI/TMlFAwoGFQ87oLAY3dguPM +4NEM7U4AoOfj1/3mP49osRX4Z0Bc1DfQ+GdQS0SnvOjPRP86QMd4ymYBB/t5JCEVL/IzTMuyN0KA +YKjRIB7TyzCE+cY+jyfSuaY+DzdE2tBnGFgXejOfu/2QzXxGAJQ1GoF8HvHRHuTzRqoF8RlQNqaF +A/gMTuhmYQeWmMYiIxPy2E0sUNOePwziFN60556U9zXrGQFZpvUD9awLluHOBaoeLEDPSHerH5c5 +z8Or1BfmmX2fVz2U566V12Y894Bs3ohnnlI9gGfcYFbAGO+Mv4u923b2EeYn4M49kLrBdr6OssnO +PTKjAXYekUIKivMeB26sM4CJKuM11RljXroRzjN6Jd5M59ktRt9bLSPbg+gMKV8zqTmAzsRbznp4 +zjB030TinGdISG6c8wx+dNCcUefA5FzAnEGsZj/OC+W8GMkuh+SMpTLzXgY5779vjvMxGuMMpEv0 +F2bl1iwm9t0Q5xWcpGA4Yy2prz4Yzonadjez2wxnWLWAiagb1Tckae68OpZHhjPvFr6QNhFIFQhn +WAbrCILhzG34oR+GM2ZQTQ/BcEaDd5fqIs2PNQ1fiJvf/HF55IpsfDNPiXc38M0s6J/BW95FJHAa +edHBb2ZF/zQEW50FU3TdvvnNfJYslDC/ma9EMyBa4uVkNeOL38w2kXEFCnXD0+NQZoDzVz/oxx/+ +iwKcGRck5eoGONNKiUMAnBUtLPkAmxkGVLOIC+HMcBX1QYFwxnP1LxjhDB4jX5Cb4IwrV4FhEJzP +ajYIzvqmpybQE5hlx1f7UMqs5ai/bDtm2e2MtFfMUhyWTXCGQaqBIDizeFQdHy6CM65S6rQgOOO1 +E7QpEM5w7SQouxnOx4MNhjNfz5BqiPBAJsVQCmsznC+rGc7s3svQfzCcYZE87GY4E/dAxVEwnBOx +2q6gVy9xCGo5vNwMZ7yxVmOY4UxdnqpfzXDG81U58s1wRnUaiV6BcEaplnDpLrBebvDzAjhDXRZ8 +eXr8cKM5dAS/Ge8J1yc3v5kBHg7XwW9mgEdcAo8WtDTXgJ5qKVrd2pc6Th6LRdLBb+ZPZgl3Nr6Z +gcpoRq+Ss+dRFHDjm9cMxvahN6OcRnhlw5vn0Gp3s5tZXsMzv9DN6AYjELTJzZBOslI/wM0jKv9u +bvPoHh4D2zyieDmozSM+novajIXNMqKZQZFhsm0gm0HO47x/E5tHC4KEgc1juCzauGYgwhikObRm +tI3h0By0ZsoqWPJvWHN38PHFagali3GzQDX34tY7BjUT6zVUDr05zex09AjnzMvCYfgKBqWZ3eeH +ksk7LdejAjhKqyn2M4SBdZG4ivqIkbARzezyXvVZMwCFRB2/pQA0g7pGD/TmMyN7RzBy4JkBEWBM +LOjMNcpPbzgzZFOjhBoPMr/wCgPNTAzDCnWnRcPQ+7A0PsDMbPWVy+Eygx9MddGNZUYFrtYIpjK3 +5q0Cyox1EUsMbyYzjFyABJMZ0qVmjjJXzRA3iZR4IZkxTRBMH0TmVl1Ye+2mitabx8ylGAEO5rbs +dUPwmKEs4Sx945hxBfy1oDG3ebp7czJBXZUI2heMuQ1/acFibjF7BYoZ51PMaNxJcMwqLDAJEjOm +onGJOtt0t4sbwwznXct/U5hxaoJEGMIMkdNM68VgXrFICwbzatF7zwjm1Z06vgjM0BKrkNYA5tX9 +48FfFrQxDHPrhNXMyfDl5VzAZi/DEL+10ctMdHBtEOjlSEZs8jJEXqR+3ODlOaKjgrnLKwCbgV1e +EQi/qMtItOi96TsiH8yBUDNz/UM5/E1dplU0ccvgEjm4VtzZe6zmmNzUZVgXC/6DukxGlN8LCSJ2 +E5QbunwdztBlWIRuCuhySi50e0GXtfJZ60CXmW+m7DSgywIZWFl2+PTwAynsDOgy0w== + + + vJzTArr81YOMoN73gy4vN5t6MZfXEmBhI5dRNc/6mCAuw3lIRjBvrRHSMUwZBW8ZBpUmG7eM3Zig +umnLLIyth7W8ApgcCGUFFC/2st5niDRZ8hqbgftIbnCQlq/E2UVa5tKAuoggLXNBxhR+kJYZ5nQJ +6cYlM9Qp8LRByzwzdckbJ6pptN2nPbuhvOofD4OKfkaUeGSXnlycZdZzqN7KnGVe9mB9lTnL23Jz +lrGjyCbBWcYXSbr/5izDq6qqWrk4y7CqnW9wlmGhlHeDlumA8xHdoGV6aVmbMUEISoPK3IRZ5gZ8 +ZDdmmSfGSHJgltPuSRKYZZaCcNC9MMs0VndhEE0NFs1Wwixz0GMxyo1ZpoOZLdQvWlEklWxvzDIs +KlO4MctcAmvOMGY5sRCuSNerk8DYwdKFG7PMRTH10MFZxkqWNSCBWVZSt9Q3ZplxE5I6ArPMJZK6 +RRizTDZatezzRNxzaKUDs0w22vRmfLQ5KGA3ZplqEkbHjFmmoRiqzAAedxTq+cIsI2Pp+2/MMuQg +6twUmGVsoxt2Y5aJVuwxxDPVuRwuX8FmWo7B3JBl0rRYWbO3a81C+6AsY92ol+emLDO+TNZjUJbh +Y8rRCMoyYgeKg92UZXGN5jiUZWr/9AmaskwLpfQ3ZVlKyj4PZVmMK8JETFnmniqzuijLDJEHbHtR +6p682gnKMheSgodflGXJJ9c8lGWefhStkrKMAJbwFxdkGUb/oiDLDHPpxAxZpoUBoRuyDKtYf4Ys +czPdC0OWeezkthIbsszVjdgswbgsy2g4Q5aP4YYsX1ZDlvEDirIEPJnhIiXwL8gylory7vZ22Uur +YCwfw4VY3sYgLHM9p1y9Ccv7fX0Rlpl6JmEgCMsseadqIAjLTB5G64ytl6R12RfUV4/sIVdLIiwz +Bxh/RvGMlOp+GuY6NmfZArDMbbjivQHLEiTPdAjLDnLMQ1hmpGp+AiwT2/nkaFeQnBci8iEAy/z6 +IqN/dbOpdjwCsAxLL1YHiITaqtypF2CZsSESBwKwTIvmMQGWaZDQ4CIs8/YzYx2IZaa6KVgLxDIC +AarkvBHLRFu5OwOptlCZdXULNGEZY53am92EZeo6cjRP4CgA10fZdROWGTMpKb8Ry7CSCb4Ry7Tw +IQVjmRYKFG/GMo9HVU4wlhk5UXn1ist0Yc+LsUyHNruXhINj5u5syDITCW1Eb4YYerY1IMuc4Vav +B7LMe8be8jdlGVa9aEFZhkVKqaAscxtKoG7KMq18VEFZFmFv9ENZpoxQvTyukjdKI1lPHZRlKHc4 +rGzKMrMzdGhvyjKj1qy4D8oyC3ipQAx6MtwJtjh7UZa5ckqXcYUaI6Cc23Ajlo/RJCr0xhEvx4Dl +L179d1048HY/7WDUsGYovLnp28Yr4wmXqUcsunJ3t7EXXLmbubrZyt0B441WnkY1vMjK05HBDUh2 +nfohK894526w8mQk7t5LTNxNVZ4uL3lBlVE0RuWTmcp8Q1oOpDJUI4xU30TlAN1uoDK0WxzSAlSc +Xf9685Rhm2Ysq+lCF38nYMrMI63yZilnV85sljIMbKcVKGVq6h0S3zA00qmxihFKGR0xxkrXCa5Y ++14gZRQuEAwbHOXAI22McolGzzdFGcIphogDokx9cJ2HoQx80noBlEsLJ9L85BJNeQOfzASTE6Cb +now0tLJThiejIqCZscywXjGt40Ynw0YaX5CTSwj9ApyMnBSiKS9uMkphom8up1ekGpRx9BuEohMR +si9ocg2WYzCTGdVb4yCTofdglvgmJiOBQ687gMmQoHQ78pQUdWvnXrjk/gQJ0bRk7MbIeMCScWCG +5m5WcrNkbaOSW/TcDFJy8yz1IiWjxV0kFkhKhoaFqT5zkpF/Hvr3PZtylfXoG8Lqd5jEFIxkdFXv +Covvigks+3LItvCxDFOwNh8Ze7Efyo1HRsBFGUTTkeEYkMEecGTo61TScrGRca3dtRCEpFKg0hRQ +Z6AK0gMGmG8wsirG6rfNRaZmwGkeZj67wBUvKHKPliDBRN7l74FE7oZivIjIbKDCYxmIfIqVzUMu +LoB94ZBr4CGDhgxCL1ONAUNu5YBeg4VM0ApXLKrIb9H0LEjILdSqNwgZxkKcsTnIZK9w/WIMMn6L +bSluDHJ1McamIMNLU2dIJyKZu15aem0GMrIYzAsHAhlUG35nQUAu0Xb9BiCX3bzP/GNUaIikafwx +aWZmGG/68YYRBfy4jJj6nJqDgaDWG33M187SMM4rYMtRvh3g4837vrnHqClTvaGLckr2tCTqcUZC +ysjmq7mQ41TBPEZetnkr9fLrYnHewOPcperfvGMYCNEX7jhHY8ybdvwxzbO68MCOq8mQwTpuHFBV +47dRx2ytEEbMhZgfWOQapGO809m44g06bqh0e+opK8SwOfgJGXOM6NJjPvKmHC8mQ9O3DTmu7uS9 +GcdDJaBvxPHHhLkseBPiOHlaDsKxdaYvvvHkMspGTFuS4YmCzCzZJNjXSbtYFwMmkpYU1YQbTy/k +Am4ccfI32li6r0M2HtGqwGDjHC1uX1zjriqLgzW2MHFTjZkEUJnigRoz6RFViVj8Gjq6icZ4K5JB +DxtojJKwZa4DecZ4n70Q0VfCsU9rmk0zLvaaAmacwwcIljFr1D3iBsoY9W5d1Zb0lLCo4Su5OcYo +ODNK+cIYW9IdFOPGIEE6EGOuqlimekOMpSAZ5UCMEUH9WKf1QzGmnPMJS8ieqBWN7VhDAEutLhfj +g/vqf39P7x6j74iFtCnGdbrhZECMg1W2GcYth5T2QhgjgFBMnaRXDdwF1TwBMCaBo9oQUnkgL9Qk +uG4GhqCqQS9u2Zm8i13cQltgdDHSrdR7BrkYOUppwC9wcWvG9zh2DrUoPRwTidF/OBJ7gS2eKZLL +shERW8eBFq+kAMKLWQwjqyYCWbyif0cQiwFy9QbbRV/Jc2rgilGMpeCdt8I/MB13w4rndEvkYBVv +Om8giIGmoHt5k4rHY48mjBAKMxcXnOJtuDHFYdyU4uEZfNOHIeLl6veGFEN8q0COjTMZTipE8fnz +IhSHcQOKCVde9fCJR2BFbjwxxMgiA5lOPJoz1kEnhmGap3u80uj1HWziEeqkABGP5hzmTSYGdyqQ +xni9Z2D/g0uMz2ajdwNLPJud6cAS01AuLDHj1+kNJZ5BcjKTeLodWCCJo3X4DSQGh1HZafOIoclk +otE4YqgveQ9vGvEGZgWMmMhFpsPMIp7+UF8oYpQqJRNCo3ROTUyDRAxDdvR8g4hpxEwUHGIwnagg +MYZ4FTuAN4V43W0R4bEQ9TzSgRCz5C6/EcTAczHEFQRipO9VqWEAcTRbf/GHZ3BUAz+8vKza9GFW +CRJHfODDZk1v9DBOaPUDHl5Fkt0XdxifG4vlAju8ohQmqMPXYTZzeEZCNpDD06mpzReOYeAFHIba +VURj84ZBDuvj4giP6rH0xg33YP+GEVlrxroDNkzN+axv1jASSI+bDiPUgb+TgcRTAgyXTV+gYSSm +onRaNMRHSYeNGUaKq7lX3dbydAe6N2S4R2FZMIa34UYMH6MJw91wo823xZI2mWa7AcOA4hOf6wUJ +CpoCvUhPpboo7wUXBjlKRe1mC2PFI2Cl0cJYC+X0BgtjNZVKP1xhrLkCP8yvrFpM8KIKN4syNlQY +mKHWDlJ4BN36EIUhaCJSMoDCXJu5tI1lzSSXlvnGCdMbS+3QhLWS7QcmzLXuyG+WMFbFy2hi3moY +VNBvlHC1MvNFEgZAKs6b30fkwTZH+LOj8+N3dKL+/4cR/oIH/iNHrt/+3j/6/V/fB8aB/vBX/J8/ ++7/+8hf9wE9/+PlP/5df/l8duz3f/t4/++XP/vI39vof/uLXP/2nv/zVz7/8/q+v7f/Yb/zTv/rl +//mLX/7mT//ZH/7m35t+HHULf+wH/re/+Dil/+mXv/g3//av/ygvOTb9w7/7048b9D/+1R9+/x/d +9qdf/vVf/ydvjIv8uCt/8cu//8+4xh//8Jf7GlHV/TEs/q3X+L//xZ//9b/9zWf5D3/4b/7+Pyp/ ++g9//+feD383/P2n/+QPv/+nHy/ZX3+8Z7/7ncz/4Jd/83Fd1z/88E/+Hf5l6l/+wV/9h3//b+M4 +/+0/+eVvvvmPb+m/++H59vc//u9f/s0P/+GHFxj6+fY/f/zH//1h+ptv9ds//vZ//J/Ptz/Hlv/s +h99NMAr5/37df6AuCAv5n2DBHxTn/jHzxy4/3cf56Yfffxz7f/0BzjUTXA/0Z1n/geUnpPkDyl3A +gD6WfB8rL/zHxzjcaWFs7l/+GY4JKX1F3ReDWOljnOFZYnxHqfYxw1iFvZoIIHz8YP1k7GoH9/MP +bzNQER+/8D4qilk+xp73GdioAwyJ49/bOvj0Puoxvs7gmK+zPUe9ruvLPfj5h3/9A8BKC04mqKLM +h0HdUzC1khb+4WpPlEh8LH+RCUcB0kIR58d9Tc+3f7wfIfzYRHzy41eAs0O7zTBCVgwNorqWfcxE +b2NS+oOXdpkfUSJeR/2YjhZegtcZhPHn3z6xv/y44vgH1j9hkssE6cSxy232WWDJOllE0Xv6ZLR+ +aJ+xzQR59W+vozasF0r59jqDMP782yfmM/6vL/Aff4HrrNmktMlIyse6GwgbFBNUvLsf4wBhgP0Z +iK0THoDBQmMDMHfI4n+6tRRUpPY+BYgSuCS6T/Yy3hd2mc9NuI56btd1Bvetjf4N720nuWqfjnqM +rzM45utsz1Gv6/pyD/6OY8PveCoDxLtP9xWnDb3G6/dxgYjSv870Mt5XdZnPHbiOeu7VdQb3fcVP +wHV+b4tsZv70yl7G1xkc83W256jXdX25B9/llWVXr6d9Hr8w6KBi7TV+NYatynv8uoz3+HWZz/h1 +jnqNX+cMXuNXz1Jkv7dlaefnox7jfQaX+ZztOep1XV/vwc8aKjGHQOnz6eZgDnnKp4Nguqj8Qu7B +/Rhfg/sxn8s4R70u+JzB6+ZgxhsIJL62Je9/fTrqMb4ezzFfj3If9X7oX+6Bb8713O65+nrGZ64+ +b8M1V1/Ge66+zGeuPke95upzBq+5+jzje9v9NtxHPcb7DC7zOdvrfTzX9fUefHlzXjfnesaXI7Pf +htuROcaXI3PM5zLOUa8LPmfwujnnGd/b7rfhPuoxvh7PMV+P8ryP10P/cg9+/uyBNPaxaJ89kDC/ +vIrGFPsntwSzjfQYb7MFee+jsnRpvef/MH7yQO5tt1dxH/UYX2dwzNfZnqNe1/XlHvzdp8kz9b7u +63EUrt8/LsV1ppfxvqrLfO7AddRzr64zuO/rcRTubbdLcR/1GF9ncMzX2Z6jXtf15R58l2nyzL6v +W3t8hesUjldxnexlvC/sMp+bcB313K7rDO5be3yFe9vtVdxHPcbXGRzzdbbnqNd1fbkHf/dX9nwG ++HRG+TIUhPn1eXeUqtgjOMYuGMinoQCHqs94DwVsZpHq+0MM46eh4N52f973UY/xdQ== + + + Bsd8ne056nVdX+7Bd16MvG7t+W6vUzhf+HWyl/G+sMt8bsJ11HO7rjO4b+35bu9t9xd+H/UYX2dw +zNfZnqNe1/XlHnzPxcjrvp6P9vr983lfZ3oZ76u6zOcOXEc99+o6g/u+no/23nZ/3vdRj/F1Bsd8 +ne056nVdX+6Bp3aQhZDA+eT3DOHzPzlPVri/3axjfLlkx3w8lHPUy5c5Z/Dye76emMMh44t7z8OW +T2sfnoC2vVYTx/haeRzzccTPUS+XfXzx7F+ng1P85wq1/sPf//kr0PqfEn8tf7f4q+/YpyDsibXi +Dfsjxtj3py9HO6HYv3OwEO9u1+qdypdy5o7MWF+YPR+AWOl1dmqfjFiT13bmDpuxfh/12/uoTen/ +9xnYuOeONcanbYeU3u+jHuPrDI75Ottz1Ou6vtyD7zZ34N8/3Vp6E+XTKdDv4It9nexlvC/sMp+b +cB313K7rDO5b26yzfW87JVR7H/UYX2dwzNfZnqNe1/XlHnyXuYNVG5/uK087f3pleYHl0yt7Ge+r +usznDlxHPffqOoP7vuInau+ftp2WMryOeoyvMzjm62zPUa/r+nIPvlsgC5VRHj3LOuEItgjc5t9p +xM2jxmBexiejacE7HGHzo4KR11E5eKf57XUGYdzhCIgW39sWqWHfRz3G+wwu8znbc9Trur7egysc +0eT53jeHc2n7dBBOmz29f+4y3qd2mc9lnKNeF3zO4HVzMPPPuT5tW1QS9j7qMb4ezzFfj3If9X7o +X+7Bd1hx75cjspWXxRP++yW0a/B+WDZ+el3ubfcrcB/1GNPnd3WcBNV+RHGKl+Uc7HoVzs9et+w+ +xev2XtvuB3Ef9RjT5zfGp/gdP/z4tU8ffphfN4jXsOono6/3082Me/M66qc4pM7gSxxST/JTHFIP +7T7qMd5ncJnP2V7Dybmur/fgy4f/ujnXJ3oOch7N9XOX8T61y3wu4xz1UxxSZ/AlDql36FMcsn6+ +OZfx9XiO+XqUZzi5HvqXe/AdJvIk3eKn+1rdvfN9X9297n1fj/F1X4/53IFz1E+Jap3Bl0T1+8Su +RPXoe3URUwCOnfJt9ln02T5NAcf4mgKO+QzW56jXsH7O4DUFfD2x7zMsbM84XL5Pq4Mwvzx+eoJO +DhyjPcFPqwP5rTvI7KPaw32fgY2fVgf3ttvjv496jK8zOObrbM9Rr+v6cg++T5BZbvHrvh4n/vr9 +4+5fZ3oZ76u6zOcOXEc99+o6g/u+Hif+3na7+/dRj/F1Bsd8ne056nVdX+7B9woy2zN+3drjx1+n +cDz+62Qv431hl/nchOuo53ZdZ3Df2uPH39tuj/8+6jG+zuCYr7M9R72u68s9+D5B5h5RuDlS/zwU +hPn1eTMGlj8NBYyXtfl5KMCh0EjofVRE4d6foUyfhoGz3f6w7+Md4+u3j/k6z3PM64q+XP13DhG8 +bur5Yq9TON/2dbKX8b6wy3xuwnXUuFnX75+ber7Ws93+qu/jHePrt4/5Os9zzOuKvlz99wwOvO7o ++VCv3z+f9HWml/G+qst87sB11LhT1++fO3o+0rPd/pjv4x3j67eP+TrPc8zrir5c/c//+dHPf/77 +3//Zr7/8+bfxinz+Z8Q+a16Q1kJqjv8Ak+ZXWIF7Qz37Mf/0ydw+Fj29ynyO8dvWfYjf89y+hzD1 +dS5DLbj3mcMNpFm+nIzDtqfPalt7PhYWNKaH+naZWWtIM1u0f75y/9pP8DMrUW7gAqBH6cep9+nT +QH3Lx6tOMwnMMtIP1E+iqkBGIhv0g7PEeQz2A9SmPXb/GJKWLw1lNDJ+rED9+6z1i92fjw/Rv//x +pvmS1z6oIv0y+taQBRF3gS19fMdy85as2dbvoxrD9wvjqbZMpFvKTC6ibguep08KHVllRPmdr+oJ +44djfy4fjZF9/h/jcWzahvc/N+DTA/hRTyY/7CBGe0av5l9tZStpWptC+bKO5J/TNy7jWrFt7v3b +bx01fm3+SU2P/+H5WBj45+Z+Hbu6p9qYdRDArua26TUwGPTH2H+M2PLJ3pRdfHRMhhl/6/fjxNAM +Rk8YbUZq8YkBx6mLayoitRG1fzauFsYnNly8v7Hp8vn2vndHgaFsQGj/5u//x54PG63QzH4G8YAI +XPXWNZ5F9fvMhgvzb3tAD3DD2d/Zx6sVIx2anXS/1FiX2raHBvbOhREcveZPgi3Dfoz9U842oyQw +Dhpfah0624fNIL5850voMP0+MoW2zX1Ofe/+Pn9fWEJ9W/JdZwv4X8P8tH6Zf7KZyBqZP1aj32zs +fsRsPWEbCtFlTDE+fv01D4TgAqDcVP8A1t2vNifgSXQYvAg25uSvgsOXjYAM68ktfwCwphjf0hjD +mz49RhcyB2xMj0cHppbjAPEwux51bDvi5uBh/OYVnFdnPM2DKTvZxavDWlWZ2/C8x4KcbQbOwMYZ +V1xiPP5y3HikUwXYumkreW5LpkHLXH0vpyox/ZxKC2PzADM4Fnwyztzz3juHsa317Td/3ueFPiC9 +a0p/HsVUbK3+MhiNCaOnhTVS3rbuT2C16vNit87cY399Qmrh2eK3rv2vn4/T2p4GCKPJU/ACoEHG +tmIcgXE2P4dWdbdofPyKEMT/xViWZ8Yvv+XXnwCS4ntWkCf6NczP7GEevDYaR/oNYx5hjPcfZZel +e5zNaDpg4wiPC5/Kb56A7w4bocWgzi6Jv9qcc/FJkIQhY8z7eMNqtrH5Y8HX5hOT1GrELFRi049V +RX7PKl9P4HxX7DOiIXHN/Vmx602MiM2fCttw2Fji+/l4TesZO2NE5YrUo6emx4ew1Babas798vvn +jr0v+NffsNbfuDUfo9e/ils+epgxq/wUZrRmkrk+cXfYPEbGkucfueV6y6balvJWchL5Ncwp3ARW +28tIuquMQ/eBxb/hZhCg8uMPYc4lth0ptp3NP9b0Lnw9gTizIomMx/nsh8le77XEC9X8GRYwKFOY +R9LvFSHmbNRY9PW4/kFUbI+5rq1/tTl8giZeoo1tD5H6Xj5srexfazG/wZzXObMe27KxgU4izTCm ++GA9Svq3MAb6uPFbtbY4qAadr+cfFwb6xjOuH/s1zOGGsSpKto/5ZcVkPlcYx/YZy/TABXOLJ8Ey +cRvjElbW5ArbEwMJybw//vZpeeSb6GoTCxh6D7/anJ7kUX144oexFHtWJJ7Y6EEDfNtuz2oaJ6Tj +Ji0hPoy19/ixjyX9t988g9vni5+DHx0DDNd7x5OzMY/LO/vt8cFW4LhsbTG/h5uC/VcMOn/E4xtz +O5Jpe4xjhPE5fujr9M+rT6dSE+GK64p2NzK3+NaI/dIUP0kZl637FvgIv3lY/x76aDRf8McXaG8E +/S72cnQCT/JTmJ86rofhI4xawyiH78th4/KSaFifLy+LNyA3QSM4bNt7JhVTxtRjAuGnEi8wSW8y +YxFo48r7ACUOkJ947sQZ/Pjb53W+AOIT/QKXcr6A673WGvbry/6v/vZtX8f9Fx8/+N//B/oheILL +T5COyq82M0Zis5zPheGn+O7HMMEWbvGL4/G6G+2ha/UrR7yXNk0jxU0aK4xkUvGXUiwLJ/sXxDvo +SQfglZ78IbDBg4yE+8lY4ybPpfCK3opHax+iWeIAfFVsREjYj7meMzhf0oeHFney5XAf5npiMMpP +8ptqv8R33ePnsJpcxvBcQen8zacTu1N1rS/ZYyqNy8f8+NDy/n1vmPZU/BrMnuVxc2itRn8AmCHZ +IsQyRPzT/kPLsrrjWjZGTOypcfVsPi4jyBaxO5tyaXdgA3+yuR//Kee4Awz36RAU438ysulQHDeW +KUPutIwfvq2vNXn1PX01OmrbuzMM5Qegrx8ntWIy4MsUx4zdRdyMn48VNYCXcVVsqO23NccBuCL0 ++B7n9LGGWdeGcVTinPQNjGeff413ZS5FQdAaEg7fHry0f79fy8fPGj0Mp+/USHPa2Ho8bMYLdYC2 +h/yh7uwyruVzLQ6dgZQ0UoyJJZyVic4ScViGC2TMM8UDGJ54q+D4OoEnvAJ0zC0lRnvMx7qx9U9a +/TTUkqlU/AyKnCAw5Ov29VeJ+1LV+c9jg4IU4DTlFucKV8Q/1OJcx3ncwMXM6efVNR3jqCne+FZn +nNXTn3QZ4wBsdebrmp5L2RA53iM7cpP05vHp1czXFfAZ67D5euF71kg83S7Ow6PCsjMLqexfirju +BPEvBicS92AEwSVO9QlTfIWY9P0RDpN7wydzTGicsN/4E4elxwlYmP3kDeueB8Kz/LDWsb8i34A/ +dkx7lkONFfb+Nb6C3nrxtifgzoWDt1w9JuZS+j7AicHFqnOcNZHhvDBiUts3ICXf1aEZ0Oc6Peah +h1x6Ilwhp38MEVv9wWkkRjuJFQ+bn5mOish6zAQtF8eH2NAu3jgSOWFEy4k4seIVxqjKunnaq56j +P8ylh+MUvuIof9IdKZ57OT7QhTc2zPF1DfZbi2+GohsaCRHzb2naJB14xpPFglQHyDs4D/Smxn0A +nnp40BH8BR1wDw/tY5WzDxC+A4bI3rbrOAAy19Yjz23mPGIfLdXjaP62/0moq18cTd84RFp77Cg9 +jE9MH72EA/Fh5lDu8V9jItu6rP06rmN84p4/wwdAG/QZbx4pbz/ZfEbQWPNCPFhiMUA+lYwksXmy +YIcCHWBsJ+JjishxgP2hRywJnQw9hQCYGrEkHKDsF1rjOjZtsXCJ76ybKeRxouS9P5dL2r+v2JaX +7kFBwbM+1QXHDzj7xUE7wxojxcen5eeOLtItFi70qWDc8CoFAHW2XVVmNsYIwjqz8A/XM+MAz55c +Nahi91J2FKja5epOUXmsfeKBAfUaL0IM1l29p2p4zd59+5G1P2sfNZwLrR5lI7HOv6R3AL+zHc5V +xt6dALb4+PM+qdLjecW43E3G8zPIcVpsaKF7hQjoPm5uMV2synGxN3WY5rYcKWSMCft2emAu3XMr +u9X8ZHP43VPLBRhBOB5eJHx4m93GmPQxfBRPIzDn/Y32nL3tsz9cDoEwohPGChdTC1WZaw8HwwvP +KC16vxmgZ649uYfn3Imoi2drr4Ot/8Kd7lWZ2J5VnuUBP2LDOMCI1WhM5OCS721H0vSMxu17uJ97 +/7TDhvDt5V6w5n7uD1TjWX/Q/DyGghIhE/TGHOF3NWcbP4yjn9CGz8plZZ4dZ90HaDO+hKKhj2y/ +uT8aDxsnzOZvI/YncdtzW/OYDAFkjwmSiVYYQfV9/MLENNacGPCgHo4LzGcmxEv7k80lP7FaxWI6 +zM8O5vSu1VbzyesQj9aQDacTY8TqMZ60jmaf4ZYq0tt31MdD6u8Upq23mxqR8WcmX5gutZgazxOy +m04afOvxwcTs3NxcxYN/81IFEPh9C2N+hjHvL1xLTVD7nnB9U9l38HwIM3adJ8Yx4zyfPS3PFGcE +9va5nfqVZwd0DNv+MAKg6JCmJR+ctwAzRxpMZs+dROLHNxgOD9rL1h3de8KbJ1g8jg== + + + +/EUIrA1hB727ddgDB5/DtlJsnfFXmMxFE/lRmweOwLlqEBtV/xgOZIXXQJsjOx8NQWWP5azbmKt +RkD7TvPvui8qxneA9/N2cJ2Ow7Z1TwVTLwoR/du9Tmnv/1jUgt/WmM/uxnsIwwOSsTsSa9dQj2U7 +h1ONtr1p35uiRZYP+oSbkxB0+jH231EdAoFlfFoEG1NZYUwzVm701CIgN599p5fGW7Aqt9NMhcHv +/nhED8yvcPW4epSxpfz5ugBg367TjpXUM+A6avE7xUvnXmQ42oVg/5YJnHUm4qjxZeyg/KMGia8p +h2mJ/I6tyhwXdu53WXtBaSfHxhjw3TNR1uoRaGpx+zvmaM5XxFORsTuWDdxr9gkAIbunt4jSE+Eb +7p/FP+TBxoYtFk5sAB6TE3vLe/cdwGi6qcXqIv98rCTK7SPNpmHkw8jotf0pRQ/QMq1HDIu4ch0A +7QXidaEPL2M96zll/NFib8usPpaIsX+9wl0xVXwY04oIUCQZysfrvsP29I51AHxFezU35cCXIldB +J5D1CiGT9ew3KIYB7r9XpDVyXpRgHn/Uxnq80XZ2b2v//HPya0eqVaaSiiL5hwyurThs3OwO0cPa +x/3wPLbTsFPMx/9/7NKiL/u4F/qRtu4rBszRSqS424rxNhb67AsYIZHzYmWlVmSNc4Uvtp0ODy7F +3cv8+/Uc4Kyh9nPJ0s35zdLKF/10nhif63jiCtId8HIICcYd/2EkQUc9PuaANikOwGH95Yyh40+s +i0px5j8hh78jxqnu/SOh77Ye3vakvOO+JHaEsm1/Ww9mm/j9rFAFutw98RY9ciYp24rkTM7hjebF +NeLry8h3JL94DQvjXs0fNwj9SVdEFHqJ1fyHuezbUrcuKS/J42wOTVzoydybQ8a200DUVoRQbpQY +9BhO+8nm4+awXCfMJ5CU29l2hTP4NEkt8HO+uK61jLcszcbjKOW5FxBsacW3I+MTDv3RnJrn0S5j +xgBxYv80j9v81fjxoP+Ft22REVjWqLENVYo0QS9hZDtdbYkqtvgtdkXV1cINkjHipuxTM+IAOxR4 +lG95bAdkyDeGsV8hq9Ktd0S36Rg6Tzgi9+0XnkxFvueZ8pQ4atmzlNsByHxiVgw8/mRzCB/Gjsqz +QU/1iSnvnN1Zz+caUwJbAIe3UpMS5fipHFJDBjS0ZWggx7XChnkvKlLS9AHjCRw26QLYNXgnW1Zk +iHO7NcwhEK343biJ/x97X9vexm0sej7f59F/YG/rxmlCeoEFsLtx0saSbNepHLtWXtzTpjoUubIZ +U6RKUk6cP34/njszwADg+1K2JJJmXyxyCAwwA2AwmBkMXIyHVNaD7LBmTILyUUcoehwTFVmsLVLl +YjuVfVzSCTk/D1VktnNyHl+RSXmrp5mDQHwm0KFMWPBJ6eM4MutAP3LgTHGEqnGBLhJNiXyUV85T +IPF0zPUztsvh042CpwvlkndAL+aVM0kh0EcOUFSsRSB8tEQw7AFQKjYukhusbqNNvYVUeNeeTGzW +9cBCjk1VIpsUiok1WlmgiznBZwK9iSP1ckOEiMHMPktigRSKZoEmY6DO2blGfg0f2eeda2zEo0dI +ObqQUstYIL2xGKaWRZDZ96/dqrOnMeEcdY6NVo8UWeQ2pleXfFiop4x2M442zXLvzDQuONHYOEU3 +aa2Dil61zJxILTKeS1jWGI6jdxtmFMNqvD9ZmFhQpyLEq+aOshBITmWZXOG83ACkJ5otCTECXBA8 +m+0+KNzTFE7yeFjBLj4Ky+b6ieb9SknfWfa7YRiiNTEI7Y/P+Pg1H5OEi/exnFHsRhAofFisc0wS +PgmaMbtAjEoHTJ3kcIZOxhvcYXRmZgQcPs3OJATmfgPygbU68lAl9uyL75z49mFd2/bxtQvJuyUa +L2195R3VeC/BxtHgW5curAGBhrHCzJdTnMXTNx92U+kbA1xezCkODYYZJaLZyQjovRW39tlQT2/Y ++gAdfO2FwWE5pEoFMO+j6OO1fiYB+ndwoQp7hMN36p2zFh+DpEwgrqxhvPRKowV6AzyH+CNM8bnK +vQ/r0Ho/CDu6RGpNs07WuYmQ2r5YaZ/xfsWv8zql1BaVNs+V1elc0LSkVwx5X+SoYmmDCy1SF1kp +Yj+nn/T4xKQ/hPMRWqAEZ5WY3adYNPM2y8JGgSBQe93CB6TLyIOSuPEWVmG2vc+sciQS68h100Xw +LEoiOzvHX+JbHrlfBom7RVRYu6EbaV4HFO+d8wWUwnA8F0wzVrpwr/kHl/WqFJtHEvd0lNttJMem +0uy1ZMWxrV7hyLWPgvU7GAUR1V3oWh5tHrZ6br0DbnFILsp6HGqtVrVJ8lhwaxMQkCvCCUPtipKg +cNPHbhPzbksEBxDal91NrNwHu+J+b/i6hcwCqWygRrBg/4vU/mpGcPmlyqomiNV78JW/V4QPyzBa +H4efRRsS65xJFjnL6H0ciwBtOizMinA/DE17HA3NEQ9JbFwRzlmPCCQH9cHOnfqO2ec3vdBxvdV8 +3BSS2S1NUKazUJ8eXLQdMBy3Q2yUbqNJi3mD62aM9CJHpiqaMoVDQDGDfMmBEsDZ5vwpDqeyO0sb +76xAoPaKiBB+fjsrm7HeGJ7g2h0DjRWyDuhDpI1zuieFfYeXgMpfmEKw804Za3JzQMnx2KzSz7p9 +4VauYhK09HTlBav/EdYi5x7w/TAsmRoG5nzaQoFiuAf0OJAFcqyxsc8AWaBxx2ZjhRAjIH+KBevM +ja8QbBt2ljhblIOVjL01ZQuypdFYv+GBq08eSwKjxGCs7C7HjJKpCeCcj5d81wmAFMir/D0JCzRZ +4ZZDGi4PoU0lz5i3hhFwaJSxAt5hzfw9C38vEYW9YY7x3Rral/iEzUd0eg7cML+KsFmxL8zYkAy3 +WbHmqZwNE6vnftqnXlNHYxe3T8+cuf3T34TwShe6cRhImxHvtdJp6tAt5w3Eh7Bz1lFTrXgHl84p +baIzCCkGuR/cgjUDylGq4rsYC+5DSb7qSP5SC+RQCHrtltW2nAcrzYLSBQcQJsArbSbhPpEny6mt +ho0hCYtPhDqzhfZv2VglWfJw20QyYwq1sZuBBRqdca+05onhZontgrMDo5rvHETYhZyBKvRA8+Fw +/nU5VhGNDyTDM4VijVyk/rSUeBYGd55wOruytwQKJjg4HqNreOTEZN46l47I/QVFf7HTgTPh57fi +w1kQac6kI/Kxhc+BewjOWE5mueK22PBt7DVMbokv6JIq2WIEgpng9b7cvg3rdgu3wHN6MtEhNVEH +/MU+uq905MBpwoKSAmkZrZdoSc5tsUfAWAWK8ab+xChzf0lOhRWm/N03ZfzNG++FF0GbiC4n5t5q +abwHG7vlhXow3yACxVxkhQyARvPYspo6456dA7sIYmPvuY2XNdbSY4G5C4E21s7J9gThtxAOUhO5 +jc6xM05pNkg4W6q77sX1Kfd/WKQWyDuFs1ox0E/6lP1qaKYI9zNZpy4a/mpY4a5NoOVD8u3QgiOw +0UzCQjZxh2M0ssicr6poyUYW6W/jSX+kALDwwjuc6xBcZH7J+DveLCNlYbdKhLkwNBPZSAisY/DM +sjNLBgRjZblbWa79mdlKTymsSjLGQXxckXcEqTlUlaA57+CJ9Na2cC2eLgtaYJaw0iWlveYFQHYX +xhcdJT5iyK3xvi7Rk+v5pXO2DIqUNwrhPWNoMCz8fV4XZojPSvu767CiMgckx40jwTsQ0uiGVuHO +sADMc1bPaH/jkgkDvXcRyxp/5YnnTOpPZng31q4ufBOyYONREplB6Thip7yz6ykfO6R9DgN8yJ3v +ZuX+ZInG2czvHX5g8CFnyftiWjDWcLRM3I1vifYNv0fgimG0ZO5R9ua9d6Bov+a0VRDrZLYOQjrV +gu3exl3Cwhv5abCmU2iEbS4xbLqX/oYY29/QyO8HMQQESLS7RUy0Mwbtfv7yZ27YJ8I3hrUNOGKP +gvY3FjkiCIGGRTfH6EsMZDA8NXD2MoLCWarGelD4MwlHmqCrRvFEVgVr2ejt0bwW6VFxCwyX5Nhs +nMfiKGGbFqZr0KmX6AmXTQVfYeRbdvPzPbADRvtzpMz5Hpmmhzi5XDQJfWXN+Rdo5ntnV8LTOFMp +E8WuB+0TdPBj7HZcvKconOVdBocF9TnIIM4ZgL49F6OKeSE0p5UI9yzd2XZuqgnjLETaBwai0zH3 +eQgSwbkmWAuMRwVfrNfa9zXlsgWrwXRz1xZky59LNsD1teHrn4WzRiFSpeIxsEDj7gRpe2JkBOFa +NYflpOGYphtOS8D6gu/hksbi6zuvmsYAH3YFk1+BgO4+BcAoNYTii+Hek5wy/bQFHjkwn8tRYnis +sAAyBtqwW/Raa+6W1MFDrn2+BIoRYLR8UtX+eiUAM60UA7PUA11nSen3fnM/B532gziNZ4Cbwliw +KBSLd56u6I7XPs+B44tkD7lhUzUGE0jWR8jN7N3+4f6wXatYNJfcea04GCExGQN9TBLFHXB95W4k +8tvJFuj2UuyTYaamYa5I71pwr747oL/B7Ey0sy78W3CWc3IZ9hNikIRfbcbptBj64YUorVtGEI5o +HC+KD1RLXu6pi1bDIBFernTnikNH+DaGtr4iV1/wVuzjbFKvo2hrOWUEdHSwZbVHEDYtvlU163K4 +K+uOFrg75NIHxdBuN77k8dI5nyLYFZSq6MxFGrzFq/xehudVrq4Kfz5MGWfh4nfsxs+12STvDjwW +yIZubR+atkC6DObIKoxHQC9nOzlYcFHpL/lr6/mjgnwtXHlfGoZQBZHtrgEiMGMNXDpfWqrtc+YW +QYhI0V51iQZRW2euBSaCsVJCVLcGQ30Zcg7xJTxEkLH6SMYLBrMNP6hEiMHw5OYAB4wBc4ljtH1W +25OrfIIKZ11DoOTDLGtfiJWPBd7Qge3zMrSvGjq+cAIH5c5QGK6Wsc4gE9ZeEewVH4pwOnJg7Vzr +2gfDpsabF5FxHITH9x9oNHgQ0ULt50bGdxXSOPKDblZYIN2GYsakDhjUR382Qahz2ADaxAUiYgyq +Vxw4jG1+BgnD8yjjfQMt+yz3YF/MGegRFP7cDuBccb8yyYe2tOB0ThqPipY1hffUhiM+AHN/uJM+ +vrGwvmC3FDMfSxnSMbCEwqOoPxeIKMIyy3kpZC7tByLw2p9xHgsEpnzAzr17TiXetBVyaqlw+Rpn +j52G8xNK6KxgXddFatMFfraNiVwzAg48MVbWMAKWksZKcS7rzUpoSfrH3kwUdQqTTTRPe+mMF5ht +oGBPLXnIbWPCRztrf38bL9RrPuApY/jq/cw8FWlkn0wSH8KsUu0Ve2uYwrhkxTnu/B1HhHpDCbu1 +qag/L7gURZR8OotbsghUlEwllz4GOjirdWbjmlSIvjFRABGAOc4kZJxCrD4BFNmKLJBdt3S2yT0C +lXgNSkpGwHPO2KsAdYpLl84nq60J2CLQPgJX24i8Iwfma0LaW7+VZmNLyDCncJi1Pw== + + + XrH8VjjVlN+XTCjrRT0qKT+4sso7R8jSWLcR+8Ib99A5YoHKKcdoZ2ZPn8rs0nazVrmi0sc8sHNf +ZT66TFs7OtcPJr/E3VhHBN6orpKEsRpviaTdmBFkklNFpU7BVi4sX8XmSZX76wXaBi0wAr4eqK3L +ha8tsFfQHdktCj6oa3uz1QJlHmS9CNchpAkiSTs7ksq9b0LbEHUH9G42vlqnUKZ6gZDyhTVV2AAo +x10XwqOKyOlj0pwx6NQ7HFIbn6DQ9SVZv+HDB6Zrl9KfftkxqZMoBZy7oYOHHxaKqRMdACy8EYUc +tgeueub9mkluBQIAOSOEkygWyI5RbW35jEAWYXsVfKsl6D2ZMwcCMDc8CuHuB5ZlqnQgoGC9k+9v +6fhIR5Z+rp7ryYSGOlw9pdt/DhYyH5KqZusLn0sKt2G74VPCfT7Tulx5AAvd1773qceqbYQVApWN +PrNyx/gUVyz88TzGl1wxb7HJvMLB16HCfNVScX3pw/6Ev6qGubAkDzYF+Vkg995wPjLtBQap7Lay +8WlftI2kOXJgKXkDdecGzGiW+IxkTulHoGRNWoUhNV4ca5+ZR5to/kinBGHJTLiJkvi4SQQL1vlk +bh0weJlMsNRMXVorbfgmPZ7To/p81U7b2wZMF12PYT0udxgKYbgH7pIaBsv4xHI52y90Fp0UReFv +5bn8KLY034jLbWyPK+t4kON5gU+KOV/nRbDmvJHs2Ne5D3tHJlprEd71K/yO5g0zGhW5jI+Kzhps +Ei+GXP4pC8xZPJIaSPXxFqMXeXTx/siBw+mDeF+ne5TsDtXsGzPCO8Hc2cWiFRw8oxv+EmcwyzhD +MsL8bqj8JmmE13W0Tw9l0FTC+SY5z4YRPoJBW8nHCMLSJH+4JUpaq66dMs5aY6S9fOkkjp1bJrWe +ZctAw5oZgXlt2u3QpP7is7bZyOr2yq1kEySoC8yUcBNXWzFx5MC5zCfmi9E21sRRlvAlZaF4xkaX +yk102qf0vnW6u50JXqAuyscEd522y8zWDxl2sVXNRXMxYUHAO+neBEEhC1w/82Ngj0h4pT34jd2h +AYGZ8OceNrfQ9fc8XgN82V+4oAbtnR+moCyFbrYLbotd99qmm2C0uSz8ATrnnAdJZOTn9EqYNkEb +b9ewZ6RMRpkYKWKF8GLqBm8KZOUD0zxoti5xwAgAQ7JRWryMIPMyliSF7VhqQ7ItGWnBOSW83HMx +dJmyCbjdjOMVByU56EZHd8qhtPSHL6FdEhIVpUR25qkMVe7UH/M4AYeySU6cOC3clM1INkqeXNZ0 +nWl7h9ENmN2PMhDd3FmKz7Fo8QSguH5q9RQEanalKufQz0xggDfwZSZK2Jo6LTrLIreScFmrsswn +RtE2KMgiyKIIhtRlfM1ynxJX20R/FshXUd1RxiLIo31OcyBrlkdWs9zFEhHQHz45GQafWAoVEstw +ShHjr84g0B9cfcKLnH2YeLJg2QRFg2WIYyizIopGoDxLFqi195T5y06YGUayiZayKYbMNj5jros3 +RKBXy501N0PrgU87bfiSLabRybxtyHlRAahCZIu7tJnj4d2nRwz5ehKfu0TbVB4WmEkOAhKFFU8A +DG6qoOog2B/7WNPOE3uN1mJ1OTcQ6EVGYG0ufNRxMMxQGiHmonRnhVzEsTkFn4MQ7K2JhTsz5eEi +nLZpyOqUsyjxmg4pAYwgJJTMrYjNhY9LxFNjzh1Ik2Ddy0MHApjVDESaskah3dVdLOnVMunT+1BZ +XgZ0snadLbxB2Vm0MRUTL03apm196S/vanukc0DlFUt3mZFSOXFHOb4agdLrE3hWOXJgvxtod8sW +YV48smgCIOchQeWH3a05CmjlyxoumxW8kNgeDMDgKIlSssnI1cEyO08j7YtSPFhgyF9KtFgEaJXx +O3rC9Tka2jkVJuv7QBuEZj5zdWhJ8BzM3f0xAPITAS7vNdeXXvsj26ED+qnmkt+lPkokloIE9lnP +Oalg6v3C4wi8+yb3scR56lNCRGVlpKtzhhccAG9cldG8KEzq9TR7dwmResMeJ9OiQWEGhLxXyBfD +eorgpJGpzyYWIlIAyIZYYzc/RhC2Io7JyVVsPMqtswkTqvl0//T0uUWgfDw37lDWvJDHZiZ29+Zo +iGIdxcccYP46fzVFKsH1KROSii03CAzBED5KBREEc6PbTLGtnM+xnOKGOuBHVrCZKTc+FVXYDTDb +XsHylXcuzMtnhO8rKxl5FoUuJpljlwkJh73IxEBpbyXyaYJy47NF4eTKONMcGuRZSeFAd8x+60P2 +Cs6CGYVH+Hv9eeHvYQYDMwJ16s/sCSOIHlEwrBYX9DSLn7N2dRTCGkCUtZRZbaAI54oQiVGkkTqU +O9mCwMJ7ZNwZDIB5CPjTbIVFcHBT+HjMQnmvO9qIktyDM82hVSz2UJPyLkPtkg/RnPYOINZfSH4x +u8Lhhleb00AsVoqGYhuNcUQYf63aRYRatMbeaVSxNZ1Yxwyny6wWCIKfY8O8E4qMzSYeRtsvzKbA +tnf3Go0FB/5Kl3+Irk94x4wLKi0yf11PW2P1gUNQZMmEroDZebzh2uXoxGwTkrMG0LHU1ndZUJxa +4eZH7hOqGM4pxFkZLYWCjXLzUvanKWdY4LdoKLOOpdg58YosJObKvTOa7hT5PIxZxCkVcgFxpmS6 +LMRJPihPeGCrz6uc2vgTxJDztUC+6UCXWnw6TcE3V/l6mi3r3hzI/IszUU5evADGl9hpb+BZkPuU +XT6bPAkBTn6UJYInIkhhbsrdb8GSijMBFD4WvXAB5I5wa1FABCGbZeZnpwkXajl1BflA/QV/lXN9 +VfgETu6QS9Z+n6DR35yiucP3dsiM54A+RwNdpbDANOckWsEjTuqzR+BicGgj4IdSvOTSPsjSzQhe +99pfAadLik5u+Ou42kXTF/PfrvC5xFmPLVTDJ5DlJBEACymw6LrCgRNcRcZ5UfiueKHifJbuQI9A +lwHGPdvm5aTxCVCdQwJFsuIrhQXLaVRCwuTk8wGCNVNglbBC+hunITURAtPCrxlWIosQUpp5JaxA +jZWv2sE5QTmgyjlhNEWUMwLF65ZMixYWbvCz37gQ9lTqlpkfQuHt6yHXCiLI/Byw+zdtXpysSWRe +QgC48IlWXbqaQsR5XnXGQJ9NkzrF9cNVx9zZMBFY8LX0zB1dAcgviuQ22QUjCPf3nAICsCgJlYuh +KtDjyldbw52YIokS09CNDVdWcIpOziSBecAN89o/tVWEZ65yn4ZhOr34P/bO9kTt0CmuQSIr3CDP +Z4ANn2hiYD4L6JU5Gd3A5vCKsey49KZaPT47uQzOLa7v6YuKqpC8wuOcIMClnqeTIl8pxmnkKENL +LV9AVv4AypE3WcMlQMNTccpCQrEWQAdof0HSiUQq6u8eu0tDiNPnrqYbZR5BwrNZOl1O+GBbvPOY +cf2J7jNdqZ0EJLDINMojVhTsFmeHBwK1t18704CM7HOUE/1gqj5no8lTf+Fd29Nsnc9K3jXDiWAJ +7D1GhT+DcQLtYD0mIJ9haTOKEMjpxrwbSASk4xxA1vzp+73EzempM+Y5g32Ybq4ZVRpssy58BIFq +LC7HH9HCmyYFn3H5GTsf7TP/hCf9i2rs+aEjrj+4LjuiSuMtMjxLQuJBd+KYSX94pm3ijsWSd/RS +f4/MXZNBoGQXLukB9cWXLGbekQjpVzhwYBzIqXlmXAk5c4brkA6WUj2ee/CMVMQyeoKtYBf7NI4j +/wbbRO4IfoMtLXjLlS5Ieix3BCVad0DNYoqsXQeMQPukLXxLy4SnIfkOxqzkFfws20TqA36WTXsV +I/UJNQEcknFxfioE+gRE5KKYiZcbTO2N0YnNAcE+dxdnpSegz87kpuf8NAchhV/qAsYJgU8JEAN9 +PgPWE6b7dRReLhrLy8YPF/GVYQRrzusWFGmOwEQfms9+lYGIabn6IYEC24HScNEl5PufkRfOLryp +vE/nDuwv1vPlMpn5qxtZw0UsySy6lh/MFVg9Y+VUurgHbKpIPNDdC5pqP3p+xp2KcxsyG15ekh6c +8MtJoSy/ZjE/GSK7O3IfsInAuGR99js1M7t15J/mDKlT6VjMT3NyYIPfVWXmTXKZv3I6n5OF4VxZ +vIPLPFI8OZnHdAf4fSJSw/gga4R/OzYv/GMjPg06gX1h9y4JAXlW81E4yaJMF+HxganWwhO2E8V9 +N3xyXTrT+W74pAbKZe1EYBbSjRgzrxvcYEh4TTeJljSY+ZOyf28p84mn/GtwU1jDK1B8fwRXvggv +f3KuU5ckyz/fqFmSaiE49YdR/lVglxN0Gi+LwMSmNbI/oOp37sBJ6p8Kzf0bdrnP+MpJ3RGzJyWk +K53f45D9iZ8/EHFieX4IaLpj3GPZkGxIlgm/xSqEdzO5jZvTABTBYsjXvTENCweaJS7bICJQ/IZi +kohwiz8NN9j4TU/hTVIhtm+qX2GTMSF6jN+0xTv3Bbt/2NlGRdn4n2sP8/EclNCEt4jMR1Ny5AkC +C2+ld0exqfZZZqd2fSu2Lp4zVLAHjcLxjhw4DeF9MuX7jdIHhXB/p9Byc9pGjdqdzvi3fTFVHGsY +4eEJBAs+6Uv/+sc0EpabJgoh0J4Y47Nba5tRm5PueRcbKfJHM1Ec+TfugrZJ1wf4ia9wgS1c3MD0 +v2nwTAuOKaY4d4s6zRg4gZf3rMLnq3Zm/nMHTjWHabDfGYMblb9/UmgObjTGW+nZAIVFg9eXXwss +vBVQh7zGUx1gvTSJ3C10YejcgcNjtBh8yvEf4ZFQigw+mo3jiB6TL2p3P629/HHs07wH5jUCT77t +954POr1Rp/eqXrdgenc+/mHv2wv8RST2p+MfHj/qdAHN3j3/sfbF3r2XT4++7bdL/HjYaY06/V5z +8G7RD/drd3897/bgpzp0a9A5vRyVw09rn+/dezAYNCdKtF53uu1B2cPfZe3ek94o/Ib/jN5dlPjb +XdBE7nxau/d9r9MC8DHg7b0aL/q22b20ZX/ptEevFxfuNc+pLHTFlf58nSl6XXZevR5VJomL3zhN +/dOfy9Zov3/Za0P/9vu/ViXwjOYbFB0NK1M5VufGSX3w5ORB9+J180RUpbHThpJLaMIyN05K9Xn4 +rvLgvFtrOpbMy4iOX/nv4u6ui5gcXQ5OL7tlr1VWZYWtWpEb3M5NDywc8arSc9oclo8G5X8ugQnV +p+tErRunUFYlr3d5/qw1ar4tq8vJuMqNE9brH486o9aS7TjQN6TS33W6KxA4VufGKcQlV5W6QTm8 +7Fbfx7l4FQk0p+tiQddn70bRplx+V1GchD4vYP8aj0unt2QBxls0lr3xWdbpVaWlf1EOmqP+oDJB +ocKNU3Xcvxy0yseD5sXrTqv6YK0wVre4eA765xf9YWe0wtq5jn6Qlly1C/cOy7Pa/d0RcP0o2h0B +Z1C5JkdAtTsCziBkdwS8FTF5NmiCtt/9tt8ZbtkhsLKlZTPPgJWlyO4MuDsD7s6Auw== + + + M+DuDLg7A35sZ0C1dWfAFSjalDMgHIz2y7dl9/h1s93/ZQs8ZHW5LQekVSjZ2iNSZU17OGoflm87 +TezQCqpoXOnGR/i0e7lE1H8AXfRWdAQytmybhvC4eTkcdpq9/aXDto4KduWV1K4uFttrffhuV5eK +7V9vgZD+2dmwHC2fTZsnBFYRbJuy+p/RaG3euu+iZonRha1+tz/44pfXS4848ab6rlvd2uhK3/hs +qxxwMrwcnDVb5XGruQpVY5VunLjhRdl6drlk3u0kxJiEuHHfYOUJCIN52W0OHv560e+VverjNF3x +5qlclciDfm84al6ByFBxk04qcFyD/1Rl0m+VufLbbRw9xSq0rPkxWq9Aygc/R1+LKvK83+mNjlYx +MF2PrbI8div2yOkYm6cdXem4uvM+3Ib3YUs1oRXJ2pTj0hXcKesiEyrvFm+W6ETRWGDRm4/DqEzI +EptKTIhaZ93zTVqdkHStCam+x7y5jS1mZam17ntmc9AZvT4vR9Ud25u0d3Y7o+fNzrKz2OZtnruI +hIpb6Oaco1e3im/KeD4tB69K5OTmqUSryo8tHpLr68cu8OjD6FhiF3i0/oFHH9flk4N+v7s/KMvf +Krve1jfAaoXJuO6W4cqEbG18VbvTbVb3B2/SkaeyPXezzjrXG1m1rmNE0rAiIbchFEWjclqIQbPd +uay+dXHx21OR+4OL1/1u/1VlYb4+x5btlW7Xf4dpbUXBmsu06reYdjJtJ9Ouon9vSyDvaWVvyKYI +sRVuMK65EFvtItAqUuyWlvymhu9ub46AyrvLZuYIqByVvMsRME3g7eYIOK2u+GzKxlRdnq/7zlR5 +bDZlZ9rkrA1Lwm0iIbDanYtbumyxwuRa+4CW08pjsxNi6zs2624keFDZFXTwutnrld3jslu2VjGy +TVe8cSJfVHYTXZXI6Yq3th0ddoYX3WarPC97o6fNi83bk86bgKqyO3kjzko1/m9t6qMY+1iVavpU +XR3n4jcvKCsbuzZmE6su+td9E1stl+YGaOIHeEP6aQXxsY5ir/r9zE3MlFLZmrIxcqD66ll3OVB5 +bK5BDqzL6jtbKbjrrNPtrhK81r0NpWOJehDZZ/FRqup2WVv65m+sVBZ7gTLf/LfU/4oUTtS6BQNt +r/JMbLZal+eXy6MkYvKiKjdvVa88K9vVkzTZsjdOy6Ckg1bloWq3O6PO2xUGyldY33tuZ4P+eXVJ +SIXX15Mz6lc/SfZvgZBm95fmu8oLCFSjUXOwkiply9/C7bZe2ax8XajV7Lae9qtf+Ygq3NLJpNnr +nK8goa/pjspmp7+r59sSNtPahc2s61Go+tBsiklkFzYzbwO/rbCZbX9fsXo2tV3gzCw73W0GzrS2 +LnBmBYm+7nvTLnBmjfanytroZgTOrDC51j5wprV1gTNbJMR2gTO7wJld4MwucOaKgTPiYwmcaW1d +4MwKon/dN7Fd4Mw6ib2tDpxpbV3gzAqrZ93lwG0GzmyCi2hzwn9WGMpVJ+UtDeUGJytcISBtNxib +m9djc8bi+vpxu33YmpSRD56cHFKqoJPV7EtbFsS6vemSbiZP9Lpevv0Y0vPs5Fsl+WZ28m0n3zZE +vlWeqzv5tpNvDwcA+LjVtxJZsJNuGyLddtrbTrqtKN0+auVtJ902SbrtdLeddKss3WK30clqzvEt +E3KVif8gvuiN8hLuFtEKiyj7mBdRZeJ3i2i3iOJ73klNVw4EtGS/WCEWMKpx4+rYx/Xa1vPOr2X3 +ebf57mS1+5hbJgcH5Xl/WbqIXU4a7Mht5aSpKER2CWkWk3ebCWlE9Tm5y0hzixlptjX3yfACs59U +peu9cp/cMGWdXrs86/SWvn8dj9pF2RwdrrDMoho3Lzlq4r5MakLDv0kN/n8fPsPf+/BD7drvo9zK +sWXlRDbrokrd7JHypuNlV3hrfVNuCWzhY5mrDNNHemFgMzw3634BftlC2Ew3W6t/ftEfgjbx7HKJ +/No8abeSaNiQOPsDHq/NkwuVjYhvltinorHAojdvb6lMyBLHVUyIug1duzIhS8JyYkLStSak+i7z +5jY2mSspaOu+czYHndHr83JUXRvY1B1063JQXkU9+Bi30s1xf1xpum7KkO5uIe78zzv/8yJC18L/ +vFrOxZ3/eed/3vmfPzyZO/8zFd35n3f+5w9O1w2+vbHzP394dRM90DK5v5LqufM573zO70vczud8 +NXPDGg/Tzue8Vg6Adufs7HJYHvR7oBr0qi+fqXo3Puneld1u/5eqdHY7r16P4Pd6C5OQViZzstrN +b7+Vxfvl4AyU4uPVHgIYq7S+biorrFejbazOjZPm1se2bV7XGkKw3kO0xc8S70xw626CW2X72tnh +1tgOt3uZeGeH29nhdna4Kx537r8alGXvPqhh5X2guPOqf/9tp98tR/cHZft+f9DsLfOz7wx0N53j +prLFtOzCl5XMc1GNm9/K8sqENX/rnF+OlrxoGQt+Ln9r1p/DDpk1jlDtuuXYmUN7TDlyGuDmLQCQ +TNtupRFbbaYZXpQtUJgHuysRa23PWGESugF9+OsFnLVWsPpOV7yFSIZVqVzZtj1dcWfM2Rlzdsac +nTFnZ8zZGXN2xpydMecD0IemG2vMcZYdsunsjDnrfZbdGXPex5hzG3rWtsUlrZFl6tidkzbXNLWV +14u3MzHHFhuhrkDaplxA3eD0HNVzKOzSc6wbIWuenqM6IWuenmPVELq13zu3OzVHtzN63uwss4Rv +3gZ6M2/j7LbQ65Nzuy103ZSaNd9CtybD1ZWU/902ug7b6NZlt1pVP/gYt9DNCQRYeZpuynDuslpt +X1arjyv10/HrZrv/y8f97lDlpFe7xAXroR3cROKCW9pRNvuyf+XnQNuVX6Olojc+w6oTsmR7iAn5 +9RYI6Z+dDcsRzqZB2V5pxWyKMNjGXPLPaNQ+qjPC1SfqpgzqFQ4L6zI4W23W3h3itu8QJ1Ryp+o8 +/aXTXiGIzJW+eTNzWp2i1+UqMVm++M0rJx/jUfsaUizfMC11oStPxep6/m2o+atQUl3R/3WzzB9m +Z/7YrBPPzvzRX081Od8W80d1Qnbmj535Y2f+2Jk/duaPj2hcduaPNTd/fGQH61FzhfiubfRgnw2a +rVGz+22/Uz0E3lauOMbc0k1HuzYqZ5I5bQ7LR4PyP5dlr1Vdu56odfNWvcrxvL3L82cwxm9XuFod +V7lxynr941Fn1FpiWI2NC1j6u053BQLH6tw4ha3KlrxNOUu0ri9Ab23HZpdMe4PyL60g5HfpihaT +d5vpinbZilYYqNvLVrSC9nU26J9XFx5U+BbIqfxC1ahfXTPu3wIpuzxStMnv8kjNzyN1K9aklbMp +XYsl6bvLwellF1SEjTU17vLAbMDluxXOGBtiCr7C7bSdGXahdWfrotBWoGgXhTaDyls3lofN8WTJ +xfoNiESrPhnXOw6tOh1bG4U2qqi0bZoDI9lyD0blUKGdA2OawNt1YOCSu3YXxi2psrsz4O4MuGZL +aHcKXKkfu1Pg7hR4gzR9tKfAyvrp7hS4NnRs7SlwewPZKmeU2MxjYGXydsfA3TFwdwzcHQOX0rI7 +Bu6OgVt1DNRbdwxcgaLdMXAGlbd+DPyx32+/GjSrC+W1PQPWxbacAlehZGvPgZWPE7ucFOtxdeRm +rsiu8UBtyqt9m51hY5dgdBEhuwwbty4F1lyi9Stk1tg8mfbB8oXctLW7C/p3vdXv9gdfnHabrTf3 +axbUv2i2OqN3X6xgNh6O3nWrm8Fd6ZuPmUZat01ArETUpqypRzgRN29JvU8enZ3t9DZsp9uvQKwm +H9ZcgxhSFtODbRR5G/y+YeXEDe6d1IN+jx5vr362mKx34xPvl9crXJ7suofg6xXWXkTlZLUbJ7Jy +MM7wcnDWbJXHreYqWt9YpZv3F6wm2FejbazOjZO24vPDm7JzbdPRd9UXorc3L4ypnHSq7MKXlUzr +UY2bly9pZfHZ/K1zfrmCi9WXv3GiaEu6zWxG16JqHXZIjThaxSl8TdkCDq1cOHJb/+bpfjvFaNMV +oyu8vLzTIG5hf6m8b/KAPvz1ot8rVzhmTVdcXy2d+7ryWXK64k572mlP16c97ZSna1Oejt1S3lzt +aRdlvTGegi1Wk65A2hbHka+LbKisCr1ZUjIaCyx689fPKhOyJN4gJkStNSFLkhvFhKRrTUj1vebN +bWw1q5pV137vbA46o9fn5QovSmzSHtrtjJ43O8sOa5u3gW71Ez0bvIVWl3O7LXTdlJo130KrE7Lm +W+iVlP/dNrrbRm+fro9xB90cU/XuUck11oy2dalt6HuS6zIttjUD0tYnwt095be5KZCqpgnaPIXu +Su6tzdhoNjm303kTUFXOLbIJ8l3UEvffWZ88pCrJ9Km6+ODiN072Y6g6XB5rtnmCY3WRuClyg+4u +Pa2wANdRcGx1YpRtvgS4xRvxZqcUqVc+l6x7TpH61iQVebb1d4K32Si3qek4rj7r1t8ds50RgWjW +x/H67iZSGK/7yWJTxMMGRzOI6i9ib6L+HS+nylcON2U9XUVWbMqS2mwNHEfm5Vk5eNQZbJ0ZZR2k ++LqM86h5Wp0Pm2DzlLXKPh+i/YfVjJpjdW4vEdhlr/Vi84TK1k22RlZLah/HdHu8m263P93ExyLc +9m85UIXOQ3jZ+7tBszc8q/7axfrM/itG3++MJrdlNLEDto0K91UOE5tyzNtgywlF4z3odq99um3O +cehq63BT5uqGhoFeRx+u8oTVnQdPRHLysNf2T1khSCPk5Nt+7zmgoHxMdQveL191evEPe99eEA5l +fzp+d37a7+7dfdBu1x413/YHKET2ktoD+P/LX/Yu4b9J7dle0jBFBqfahlC5ymzMTkOYJMsVfDBZ +ovMcPuS5kZmuvWzuhRifl+/gyzfw4WcA/VITSe1p7Z8/JbU2tvBir540lDIyL2pSNHKtdO18ry5M +QxSJgsINoYWq1aVq6CLNa1haihzaqEuNFdNavWgYkQtTO9gLMCEbJk+y2tEeVs10AVVl0kgSVdAH +qTV+SBtJbgC9yBqpkSlBUlOIWov6oDMHc0h1I5dGWgh0lSBCKR0gWC9pFLlUUamiIZVJsD3ZkKJW +BzRJju2LvCGESrHnngt1IRrQrIGuq0YhjA7FjvbyRooILR5oKCmSNDQkFNAVt9zaA1CRYpu+jIbR +ymWgCshUppAx6aKAT8hs5g/8zU2WBRbicOhUBj4f7HkQD8cRgVRBI6SN0JKqpdoQIFEwYxAgcWwK +6AwyjfAUSY5tNdJEG8JTNIpCmRiU4lxLATUObp4VtVQ00qwA2jNgijE5Arg/qZQSu+hB0OsiT5XF +A5PXsoxAyBZJgMIOA0wNoXHwoGiawqgBf2B2isIQSKUwQjgNtMksYGwkGNDag34lJtUBlAIvRIYt +ZTiquhbNARhgI1KaGAr6o3IuhfQVSZIWAU+YhKExnLzE4KgUdECILHQap1UCsyoiDA== + + + 10oqpA7U15FnRurAoHoqwxojCHTSw5jZsO6gpgEWiIZMTGIRGBgr5I0okDeeXO4jDD4U1jqryRzq +mppqGJXDBJIGVgww3MCCUFrXYJknqZJQwUOAhiTFdqG/sCjSCALrURSFlAjKBaDD5S8RLcyZNO4I +S6CDvbO97/dIeLX3TO3up7WXP+7dOZklqgB6RWEFNWeIK4ReTWDZnlxFZGHNqwitmCOR2LpzMi24 +7pysLLrunFxJeEG1q4ivOyczBJgFrizCqNqkEAPgtBi7c3IlQQbVpkUZ4VpdmAG/riLO7pxcUaDB +pLmSSLPT+wpCza6oq4g1qDlDsCH0CqINxn9V4XbnZFq8wXBNCbg7J1cRcXdOeqC93n3Q6/dqhTQk +45yyB9WLIi2A1cIHa4NOR8iAaTBfTF6g9GMIDGmhUlr9IAdgRYlZIK53ROokTJZ0FggXeUFCg+tN +Q4hnGekGrgfTkFCLBhGHZwoSmp+k7Wj2FjDNggCLKIZRmmZDAIZGcOimWBEBQ5dD7VmwQH7ozyxY +XHeaLQEWd2aaNdHUIb58DxA4NI7GzsYkWGDNFDUFE96ANFQaVh+1J5W0h4h7L8pm14ZcQwVA+USk +z+E0Wg56xXG3YzOvwqnl8aDT/ltJsZN3TrQ7c0WFX8BZZjgaUHzEd+74BWys3dvv97tjJR/20L78 ++LLTtoddoG8aHWbZHIwCIjh2newVPAv8CcyenWacpvYvR6N+76T/Fo538WHqT5fAt0O3yOYckNT4 ++SipvdoDiZEkAvdYXHM5fcCTjf8EYkba3+t2p5BJjnsSfsmsglazSpms0Y+IzVbCnb9ACQ0DI1AF +o79H3CZ9xpKwa8Bnrq9rhBF0amrhaI+bLeB06Ipjd6Keo1KVAPGpgIrn+AemhYbdHISy0biZJ1wc +PtmOJI5M9wELZtgD6HEiUYoTDoObDqFFSoXtEH3AX7XMar4qKDo1yzfXRJ1Q+24m9rhB/cFvjASb +sJgPLAFHe/unuAa+7+EJvV17NWi2OyVMo/RTGtR6gQMsotsuorb/Cs95Cf4HlRrojcFDMwGguVyA +NM8FcOTl+VhBPbOgBL1lv1UR434VjHCeR4w4TPv7e3/6HmY8bCc6TNOITecx89yH+sxPMefHxoT5 +WXcMHRvOqbG2s+AgTIfpvzx3unvRlArzzM0QniDx0MZDHhHZmjfIsvIgQyHQ9MY4neOQiMlBTmcW +RO1tYpDnY9yvglEYEQ3yHMmtajAVBOieNyCkxW0J6YNB2e6MagfNQXuukL42s5c0tF5hxNwnu1Rk +QQc/aUW3YAB9MU6Q41ErJZXffoMvoKu5r3RuoQ8emfuASKEtiZql/Uuijn+Lqlg0VrYH7GMtuw65 +D4wl6r+jioU+aAFQ/Jz+ZrDWQN2Q7q8osDD8e0C8gA/IivBjPapTt3iwZBH3beob9e3MFbOdPnff +jGU1HR4cUv5ArRn6SzyqU2fin+N6DtvBXtTI0ViT2AUQo3PVI9CMaqDJC7HNutBhc1Q+6pTd9rQ6 +ZJeYFkbRIlOpUKBfRh+STCvQbqFMAifUWR9ozcEKrLbqMlI96sbuNzDAOBky/pPRgAGyTKcGF7iW +Rml/VxU04xT3yaSRpZnU0+sdznCIPavRFMvsNmP4j52RoN3t4e5ru0EN41/UqrX/Y+arF3rhzgM/ +4M6la2EbAIGvQOpnGW44CZ5H9OwSORwscWdYiGN/MQ44bYS9heg59+ThX2XpU4HaK2lRC7polpKZ +LCXTLCVTR2ReEmWomdfRIoGUojrqKOa/Yj6tpgjEqpnE5jgl8K/IUmxeOSJRpYp/yJWjbLrC/swK +Jh4v+EVaKqQlIrF9d3/kYgrqOH1WJiLSV0Q6QUy2iJgFFSeJ0pYobYlyA+L+LJiCRFT6fiSZ8QJF +UpUks4ik1E034aabcNMsDX8/1HRL4umWjcNzMU1NEs+2ifKTREhLg7QkJLbn7s8HnGzJvBWTzFkx +ybwVM4sI6660k0vUHPvdnw82uZJl6yWZs16SZetliqTEzi1pp5C0Myrxfz7QvDJZPChqAp5PEcLl +92eVn+i/pO6TdkuzKXH/frgpNd77bBw+Y1WM9z5b2HuyqtLMkTXLc/vvh5pL432PZrft/PRyGO/8 +ZIWx3pP8Od9z4kf7P2RxtX8+xNxRc7iv5nBfzeG+mu4/zh1NM0XTrEndvx9w7qg5M1/Nmflqzsyf +0XtNvbc6pOW5/feDzZ1r4/z3/kDhD99Jo5BSCO+CQM+K0HgGB7VbUOSI8mpXvFK8CiasOg/YaJc5 +532FdxnBfyQf1ETtwQU1rWpeqccjhItUyVi/jxV7p+7P4W+2WF+fkMoiG9c1UzsnJpUKUktnFC2U +VW2rYZ3UOOZhNXq5vSiFyiLhf9KGtRlu64F20L9o93+ZYd4n21GCk2gFK79gKz+ZOjV6hzR5qc+n +IEceUjcNRR8iUE5eW0XmTp2Ri1q56q4EAw720LtsYwsKj8hbQz0MwwKgmA64A8QEXAwL3VwE8qi4 +ucKV8X1iAIV3UCOFR8PEMYSpZ6yTLEMD1MwpexeFdpZkhfk0xOnt7z9otS7PX/RH/qYtVI5r1u59 +2x+9KFv9QRvWuZ2HpIfDH5PCGdqkBhdRWiRmagEcPHjy2EmG7876g3PONUSzEOZou39anjx4UpxA +d49H77rlSWg6mqvY4ss2ihx5haMzrGL2Z5JsZK7nftrhaCe6MB4EE8KWyRqGfvCAwGYPiqZmgGFF +GnKLGD64GebnYe7nkwkTmhFhPWnnoXLDXXB9RJxPLouDvXxq7TCEiWCkTKXxU8nTNMmbavaKBTPC +Sn1BszSIWv9BkpneCPJA5ELbhUgbAEa4YMjMvEopkCWSPKqFO8GqLe1XaCkX4424rWG3yuassj/N +2TR3vPlxysM4uWrP96aWdljIfvFPCIcpARLvd0GozIRNS6hJGTYl55bIvmgLXADyknVK9k7KoJli +aVJ2BZHJkGnpN7lRVvF1Lhdt2TyBYzVK6QSOSSLRJuYKHKqkEhZtXItE24ot7VdoKU/GG/koRdti +5/bY8g3nNvSUqhy9OCYV6BM1cFoj27nOUyPwh/D/aUcpHed4EQm3iM73Ul7Jwq+rBI8XVK47o8rR +fHXPDXWybLSIQ/P84o08yzDMz/1J0B/k/myxp/xRp3s+cdDxh50FZ5xJ7xseckSKwa/APFQyyCUM +Z9SGzDHWzYGOAgg/UDTska84AxQqntHBC0M4kyInNVUaSS4/BqHYU4Jqi0aOIdTTEK42V9tTboWo +mStE5g2MD8CoU2GDj0wjS3OKUYIGMHgYDuDQH5GgCa3ALUAWKAkVdhIDlVPdSKWSM6vKBIV9Kmu5 +lBhUbchmh4HQOTrjdUPJTM9p1cDMLbTGVtNGkkoKDMoamREFbV5apEk+u6rOEbEkQzNuIVizUn+F +BmFgtPUwJgXwF7r7yMcYBREyZ83de9ocvqFP/sT/pAcn71HZnjAEHHQ7FxcdfGt2DHzYGeIacaVf +fgX/XML/6XoUzOzyC/5Cc/5Fc0h3qk6gUyAlH5P8Lt926Bbzu9rLbwHwTz/cdbK70z8/YdxEijbn +l6/nl0GQLWf/l0fzR9XI7oTduUN9OWyOml/AMpLZ3ssn/+e/3vs//+9/5/7n/+Hv83/+3/+9md/n +dHz3++73/1qH+bn492Xr6/3+g2IBtmkUCijH/spiC2BeaH07J9QoaA5F7dHlb7+9q6FUjbSBOyco +fr1OcPLyM6vADEYTusdRp/eGZel9QngygcoKM4nSc5k+MBZd//2kJjERe49C+0+X1JcHFyTgn9G/ +rxA0pVbgfZEpxSICRnpEqD4TGFc/IxRT6kUEDOqEjc4fVzECLCgZd05AzUCqVlU0QNe7sqoBuuzV +lQ28mHJldQNvDl1V4ajY65kqx52TRzRd6DxHNpl5Cgdffwcd4MGT2oPLUb9mF1jntzKcHqbOXM9O +h+Xgbdk+Ac3+xBYaRssi3LUp3F2b4C5IfLxpkmZ4oIEPUie5iT6gR0xhKPTk35VuWws8oOHNNPgg +ZWHDFyJYgjGQ8DdP7ATPVU5x0cL+woADq1EnqQqwI4JJoVRcUTZgcPIIdwSgDlhUDiYbAgfuaByW +ZuR6YOTwQavM4rJdYAjiEr4dAlnPgyUnVPQUe+QRhLpwMINX9oDh3Dv1DOMUjQpVzsdhFjHOXaHj +xrNGTpfRok7DMi5Mno/1GteqyWNyi4bIsiyNkMcQ7nWA+V6Pwdw4OuR+oHwXoiHmnkYj7MnxFQPJ +DncM4BGe4hVF5yr4XRkxxsEYZolUIH6VTiNGKJQHKhtjoW7ovIjZdbRHd1aTLGIrQIosicc9AjAD +PSjwLwIRiR6x54JvPmKf72bEP0+MrxkIdshjAPNvilPEP5zqeO8w5l8Mc1O7IXJeSW76QydyNb5u +cLnBxjjGP4n3mLNoqgIkI/tUwB5DmIMBFlgYw4hMj9xzwnchljLc1VjKMEFByniiWcpEAC9lJrmF +PJQRcxwLYxDRiPtnriM2CH8X2vMPRAzsRuOCB82W6RhPMYZYpnm0hMcgjn8RzPNvDIYkBuTMhdCF +wD/f08A+Tw2DAr0Wc/zd8W6KS8g62IALM866GETkacCgY05paEKZMemnYNNLZBZzLgVSkjRiXNow +ClSogDgGOLYFkOdaDELSPF6m3bcdWOZ7GFjmqWBQoNPijb87lk1xB1mWg0SQemzLiEFEWR6JSqI9 +B5TC5DHLsoZMszTmWAZ6QhZvhaaRg7amA94Y4DgWQJ5jMQgp83iZdG46MMz3LzDM08CgQKVFG393 +DJviDe22wl6OjhgWg4gwIcLWbZenAM0xH9seBK4fNcYxbDmNhSB2jS60e8QRwHEsgDzHYhCS5vEy +7b7taFlyDwPLPBW+mqfT4Y2+O5ZNccfuCk5toXwUeRZreAWojLnTA0glKhqgF+RBwePvkX7HoEi9 +C7WckhbwOgC3HSl3dEAyWazbCcnHLocY/qrMbTjUOAOCYseQSK8LtZhyjzcAqO2Dae4Qy1g9iVjG +IE8aaz6eeKcdRSxjHSpiGStavharYh4vAyKWeVBgWQSypDFiTzw3HrHM9TBiGRPha3nKGW8EYJZN +cmdMd4tYxiBPGis7nnjWiCKeseIU8Yy1K1/NqV8er/secYwhgWEBYulipJ5ybjjiF3cvYhiT4Kt5 +uhlxBGCGTfJmTFmLl6UDheXj9tmwwJz6EzGMtaSIYaxK+WqsbHnEDIhY5kGBZxHI0saIPfXceLwu +XRfjhenICAuTafcLMwD8wpzgT6ydBZ5JzyFLGWszTDorPIFhXi0KDPO6E4O8dsVoPSAwLIA8w2IQ +0eURM+W+8cAw7mHgF9PAEBnYR1ij745Zk3yJ1bHAK4YwUazGMNWs6QResToUWMUaE0NYo2Kc/D3w +yUM8myII0cM4mV5uNfCIexZ4xH1niKfW4Yy+Ox5N8iPWvwKPGML05F7sW3pZuQk8cg== + + + ClBgEatIDGEVilHy98AiD/EsiiBEDuNkcl2jgUPcr8ChPAhugnhaHcrou+PQJDdihStwiCFMDisq +fsU5XSZwiBWewCLWiXwdpzN5nO57YJGHeBZFEGuWdTiZXm41WmmuZ4FH3Hdfh6llnOG749EkPxZf +6b0uX2ViLd4fzGVpavTPT3iHOU1muyx9GQTZcvbfCi5LGNP39Vg6rwr/73/D9/f98b/G/8efdv/Z +/cf/Z8Yc+q8PM/vm/3jV/3zsfkHyCc5ybExAK7s2nDdvwrlhoVdwb9iKkw6OCegKLg6sOeXksLRe +xc0xi3c2xRfuO+yzyh2zne8VHSBQcYYLZAJa3QkCFWe4QQB6RUcI1ZxyhUxAqztDiK5JdwgBr+IQ +mcW7+Uyf5SiZgK7gKoGaM5wlBL2Cu4TqTTpMxoHVXSZE1JTThKBXcZvM4twCLs9wp0xAV3CoYNrJ +aZcKQa/kVKGaU26VCWh1xwoRNuVaIehVnCuzuDef0zOcLuPAym4XTJU47XihBIpXcr1gzWnnywS0 +uvsFs3VOOWCQ1NVdMDO4Np/BM1wz48DKzhmMeZ5yz+CFzys4aLDalItmHFjVSYPUTLlpELi6o2YG +t+YzdoYDZxxY2YWDYTCTThxKqru6GwfDcaYcOePAiq4cpGXKmYPA1d05M3i1QKuYdvOMAys7eqDa +tKuHgKs7e6japLtnHFjV4UPUTLp8CLiy02cGtxbtaVPOoAi4gjso0omDWSdSiVdxCUWqbzDvjAMr +u4WCMhysPJEuLFZwDc3g1gLGTruMIuAKTqNI7R1j7FUcR5FyO8bYqziPgr47xtirOJBmcKuCrjvG +2Ku4liI9d4yzq7uXgjo7xtYruJgiBXeMrVdxM83gVQXldlwQXMEBFSm2Y2y9ihMqUl/HOHsVR1Sk +0Y6Lgis4o2bwa7k2G3N2dTdVpMnGbL2SqyrSV2O2XsldFVTYmKuru6ym+bRcfY05urozK6iuMUNX +d2gFDTVm5upOraCzxpxc3bE1zZ/l+mrMydVdXl5XjRm5utsrqKQxI1d2fQUlNebj6u6vae4sV1Bj +Pq7uGAvKaczI1Z1jQQeNGbm6gyxopTEnV3eSTfNnPifnZUO49qj7fNElw1VvxP61f15OJo2eiOS/ +rszRqWpkKT3Ik4qC8hpLkKwpviFDD+ZoCilgEL4vo1LMiizS+SB8FSQxlByLrknbGxYATFMK6LBt +kv0vlULa4OCiIYGMGpWy+aclKDzSag0JKiYxjLDhFRgCFPk0gGoldImbcEeYJ2mm2JDEVsNnLogN +nErBAY72Qm4F38PcpZOfAfLV6oQ5T2dAUOFKFF1D92wScHbLCkoU7XoUSk30cUk+aHzTCaSRpnUl +aiprZBoTK2h8TqnY5pRaz5u9snty0O0PS/t0xrPp1Fqrvp7h82oZGio0acAkQUN9zabkLVxAnH0y +q6D/4Vd6FwhvJ1Eonk3mTAk67C9cg0pQkqqazcBhW7HBuLYsaCe18BnxFTa5c9RS1GLUUc6bnlPK +uRxKCTo04F+F2TwAnmP/8A+RwfB6KFzPqU2bke+I/uJP0r65ZCvYH+s50VHPqfP+l6hCbvmRL0p2 +V/npC2FzxI+lmqMUpsnkqwhiZkGZiMk8d/Mx7lfBKED4TT19kYUpRryxuazH+F0nhge2OjbVLZ/C +Hz8k0UCNjWD8bygTKtqhtPjceEbtRt1xg/m+D1dgBmKZjPMJs6lkxWQ6wmJ2wSKfHKL5GPcrYTTp +zIyRNmnje6cfkY2c7oWC7EZF0sWzKom2UP6NQiRzWYia/Y2eB+BP8EsKY0XxfOOoFiYlyXING1Gl +pCR1RsgNnPumZvRnRq9DoSlUC/oo8d6nKNT7JU7ReI/W/aPeJ0GkuN3d7PoJ3IDtun/x/cWCN65W +TYHps8OklI0KbTSU/cfmJCVFKg0fpf9Yj0rU07yR2Zem6gqzkNb9Q1f2q43Mxo8U60yfwkNZVJne +z0KU9FwVfzry3bJfoCg+gAVfxnA41Ad73NzRXtQPVHhdRexiTCjv9ciAeloQlnP3yT1lRR/Dw0mY +7NI/qWRZQM9ZSffRMck+wGTJSByLqCLVQ5w5Kx+uWeyK74EvgW8nUX5N+6ASMyPxPEp4hMIn2w3f +uaNoaBPLROHf2PLUYVeY7APuyId5aSv3zzjgLi1k3tDz3tqaWXT2a1tzsU6/tzW76KwXtyK1I2ba +eczNiMeB8WEwojEKvGZW85DykIeJNjES8RhFHXl/5QLfsJrY4WVhWTf2Lhamn6dHOGYWhh1+Kt/x +Qsz7VTGPv5EVltj53sTam1iXfurW/dydXGfxCnTDdRCt1mgJ16PhnsNw8R7PkCkzg+HCvow6p7BE +5+ny58gC5v2qmMcZ/l7KHC2sOqb7dgOM81rY2SvxabicoWc+37fjGf7XvSckI4TKj/7MVUe/h0/2 +57MwkvRKqq8mxkZ6cszP5ifYLjJlanBKAYaobc419xw0zNFiheL6TGsoFhqJxseZz/dsehMj8N1i +kAtpIujElSX4MCu+Dsaf6dF6Y7IAOfIQNJqihyWCoOoNkxjT7OL7vfRGN9p53DQx1t59wNMGtIbM +oO0obySFtna5wmTW4EZFpgCM48gm8x1rpT7Zj/pkVw/26tP01GOCrfVvnCH1mF31mJMt+04dnDQ0 +HYHxeTndSDNV+4d9qS63ryd7nJilk6LgDH88cJS5r0xoIHzWV1844CHLYtxG1Hzoln35jvsbk/LW +qWrA4ExTPA8od6lJ6SJRoiiWykGOPERm1jZ+NF3N3tvyxaj35x5Cw2gvB2d+WKPv0XDMATDOo6lW +SPxhmdBsfew74xCY5VT4Rie+xujw8T5DDHQiz31zw5FhRWc6nvXdl64HRPSloVVaMKSOdmE0iNKr +4lkYMvrS0FIpgVJ+8ovmroTqE5hDqwcVnu1TQLgWFlmebrVx9sXx8Zg8drvmdQpifHoN1hsZtoo0 +d4lhLAiWq8K9EIRNlmryk+Xkk0BrWCHIlWsBLXrSQAkTihTOS+uRMIAbau15EOC3b787JNiBXIjQ +DgNae74vvgz31iOZpKg1z+By7+XTo++fHNa+qN1tdQatbnmSnnxaoysVMFJQHn4cu1UBowHyKRfk +0jWZSumtk6SRgg6WGg8j346SJOsyfIo+IZeLSlB3xURdEmVwCoOJruWUBlUhbfhbgucHKJukjs/4 +pDmgE4WyEYVG408Jrh8tpL3EbmEoPDNjrDMI+iJysqgVGGlQw79ZhsYzQ7vTJCEHU6ShpCnwkftc +RuTCwoUB1VEpkJWmSHAi5oZGq46Zxm1gNPyWmZTioIxCh1kdF77Queu3heE8kJShTYDwNClNn4yD +DuzeCb+k9Cb2eIcOprq4QLcTmOU4rSnYvTI00gnkCRmSikLn2yxZjsvmoPV6Rmbha5YusHXhEkcW +K+HSJuWwtxbkHC90akjvIicexiBSoDNsrkpY77cQ2goXoVSCoc5JIbMME1JnMI8xCgEnOr4ACxOr +MEmBAGv7wT0Hc9/B+oJtlGQUfBSwLjFtPYaLIRqoDr1AqaSkWy9ZmqAbwDWJlQp03MNpBmYmKVnQ +06zAQ3+GGQ6pO5jsUNv3c7NE2PyGRQbk4Ru2hiK9MfJMEgA4YvFMcKdLU3fqUlYRXc+akanRXlt9 +ZkOYVhtIjL6aGiEErj5GFF05OUo2jHHVcYJa0yNFsWqrj5UNdp0YLZecctXxmsEtxIW7y/c0BjQ4 +d07C8LzHsAAJINTQDpApH/OKBwxRw9NDof0ll1Rbx5QNieTUmyZNCtS4QRlVDjiOch7sjM6kTMH3 +UVxH5rIp/um6xYZuCHL0I7thpFPadrROZAQCrTClVyIE5s2kl4tkQVsHPrAF+iheKceTmLIHMI3R +R3AkSRM6XiUFOv4BGQZjwIallVS5rSINbJcKX5620es4kTIKDMBbDTDxou8HlLYB91yGyAZougWO +h6GpCPtWhoMF3ZZSuBQqGO2joA1cXPR6RqHtmQGmmhS0KOwujeHCGvDYXCfASjKIwVTVOEUpcj2h +CHzHlSnOHew9ouN8+CG1scbnsNdC/0yAQOuArfCPj+N5t6GMoaOnUcblW4GBpUtm9g1wgAiRG6rt +bjHB8lf4C8wBleMKopQjRY4rFY4KGp/9hR+pmoRlT4JFOmUN3xlIC3IKwFzSGn17qYKtH/4KEiCg +3gkhUz8U/B01gSSHSeEhOKuNwSFJUolOhxTDcShoxr6HBcOtUAdBkxmeruxTA6pAddU0lE5tSlsQ +RFY3pcgUqER+OhvLr224mK2DDSZ0aQNYL+hROBvIhRkgBCjGLhmuDQDCERLKgowVdihoRBiRqUE7 +mB7HxZEu6PeEgRKYCbWCT1HRC3wT289sVQrUbdS64HSWFjCwCkO0tT3YS73Vz6wfv+5TQonaQXMw +w3527aYz0bAhhmjqdbaERNjn2BLJ1oRERMd+mdmgMoFm3YRca9ixAiH2XIEhYviAJLrJE4qkR0hO +RjCyo+O89yDcVmzOGoBkFG0AbcHoy8J9x/0EdHFoOKUaCHDJzmznGHIUQYx9ts6BBGVZLvBAYI09 +hZbWtu2uWqYNb+zGaugLINZ4CFr2YWnlaFBjGGYzlhi/AZiLlBAygF65IXXTg6BHKEACGjQ8WzS2 +Kf5uLXmWDOVbdyC05Liv9uqR4uuoIJlokzF4EEmJSqSJtrTCcjzT/BXY7brhAK6bsOTg3GP815Qa +be3xd2gdb6D4ynbmjE2jA5sBqpApye3EqhIYhQMnUQxkbcB81Tacy0JoiHJ6+5frTUM8JhRSxp1l +udw5Ct8sL0RUM0BAvcwTmybRVaOniUDXiWG+ItrEGvbOJshXhXs74M8dNthWs4yiAj0odJbrTUMY +E+f6o20odN+DcFkB1mguSwpijBdjQD+FyUnweu5WJ2mg/JSKbSBzdmONj+/UYLVlhvYb913RUsID +hQPk3IJDQLOfFA3bhPtOJocMc6NzAYHKL4ZoegwMCG0whHvhUHAnJ8hA6wtUznREGFQt0sRXQaUa +RocR8ldukb+7LnFl12WH21OEXic0mzpAKqgJrsxfGTd/d01zZdex8X63FhgWoIQEhUmDEpShcQr2 +dp2QzTLTidzm3fC75ul+c1AfNU+nA1RWCUoh1z26KM/tR3KJk1aaUhgomoS0jQXAD+S0IXlNX8m3 +R7sHf8VaOrdfYRxtUUbqAcaicl9hZTrRLfU8CFWJvuZ2w0SU0sacYCiK7w19izpL33EvkNFnqCrc +V/L+ME76YrtYt5Lb7yx64pvr1hz3ta4ewSFcx7UjMLjxc1BW3cOymO1fTwZ00BNh+ZKaMtG0Lid8 +2yu0un+FVme8NDcR/zE2I873pmfM2HyK59rUTPRz1DoF48k7Nq91GNuxiTY9GdXY1Hv/EAVmdjqD +ZcozO5keYuJntqQmHGJmDfEKre5fodUZQ+ziVVECC1K6C0PX+kD7lhSZXCRomXJzwA== + + + hiMkxfSc4JE4n7HuwnvJXHoaEmqc2TbS6Ta41vkEVvyWT2GchoQaCyIbQDenvYn+ou0DX9OTW/+o +3nflr6MHg7J5ctZvXQ4ndijysL3A81pujKBDWo4XauyJjUJjQLtRdGMzl6lOay8fzN7UYD4VIgUZ +MbW3ZejAVdpubuHLkftSd9+mv7jPQ5o2JjSJ4jKHqfvLXoZBNsrtm+HLkftSd9+mv7jPw7kqDbpu +QYEhF26twKNfQolh8uQmfLA3Nlkoe9vJt/0ehcNAf+v1vZDwMf5h79sL/CW3vzzvXsK/z05/Lluj +PXtLrrY/uBy+rj1t9pqvykHt2aCN+tDC32r2x4Nmt9sBSX7xutNyJb8D6u/V0trFqFF70b/ste9N +l/20Vt+7O15BJAtrjBfWtQtCARUedZsjLg+T4VkP2Pl6rPDB6+ag1W92a/Xa87LX6nS5OKFo26Jj +FZqjT4bwuffqsuSybpAm0RMKrEJu2OG9T2sNy2oYmzFGf+ABm+o1DEncbfiKmTdxT7L/T3H/wHMz +BsHUHjw52R/A5O2WhOGocwqr5+TgGEqaE+ToCRH2vI+BVjdE0pzBBkriqYFfca7Q/+z/g8KQLOrr +lZpOJ1qGg9hYu8k1taupXRwJahYOaNRQQf+r0OiHHJhZqwqn2+SyAhiItRrrd9m9Gv8Xx+dezYVP +hi1I+E8JKoE3Q82chUwU2UXs6Pi2/IUL18T413TqK/4Xl5lKQSWhtYPrTcMXiUEQoB2mhbQ8SOby +4MOOaGF/4Weeh3v3/tbr/9KjL7BR3n3QfTccNk8eH39au/ctjBhsOvcewE76tuQi9w765xc49R91 +ukAoVoJB7/RqtoCFWuX9nivyOeiu937oDDuw3yHCaQzHo2brzQoY9pvDTiuuPui/KavXl/RD99nA +VQSMi57avmeLOQ7UKtu2ne/h3mF5Vrtf26vdjfDgdn6/Rs3W7u/V7j1vDkYzKDvo99qXnVEVohZg +QWJX4O5CXiCuwIlnPGU+nZ64tX8KtEPZH+iTSfIcVC5MXKW1Lihhw0+1i1VeghbjHPW9QX56q9H3 +w/Lh27L3rN2uyObrZBBus0muKHwdTmwFPR6vM2Gf5jMab+6CNg7naHq2Ly+UABV1FR/Kh+LKAgbt +d8te+0NxiJCtvJoCeaH+XEL27j38tWxdYh/oB6o7Jex66C5cZzn3/n2YGEe73Tmx9+zsbFiOPqUB +mFPfVXjS7V7SqaY/aDQvQM2+Z3cizCnv2Hd3DGntCFhZe3h2BhsVlP6uM7qK4L377HI0hPNR5O09 +7Awvus139uun1yic/bKxcEvWk57tTiWhsmlr5kNvQh988l6rlCaDR1rkeaSJ3YYQ3ppZtEU0Vd5N +aiot1ntH2WnOa6M5r2TL/yBSSHwIVdBqBIeD/kXt+HWz3f9lUoFIxhQILGjLNZqd2ZrDGC6vKyxk +pqfkotkZONLQglu7i6/mfDpHwvszing/pg5bXWo0S7jVdnPwxsl5C3jdH/xGALSvOVj/otkaG4bL +Yfn8+Gi/ezkYq3saAGQPbg0Hrfj7abdH4wZHCGcwpiGx2lbt4a8XTZCu++VZf1DWfigHQxcVt4Wb +TXXBXEiz3oJ5p+rvVP2dqn8z++51BbPuzgC7M4C7WnJ9W81MMU/OqNpBf9CD/f5DifkJpBU1s4bA +sFanymA4z+Vw3jTfHWe25jhzVU7sTNWrCJZ8vXXY3Wpck9WISk6SZhhCBx+kTsi1xB/QvqDwds3k +3zVzOtmdKn5ectG+RuXsMWSupeFR2Ry9Rj5X28swBlPnvJe9WLiXfURSaGfi3EmhzdIJ1kCS5Hjt +didJnCTZ716WtW/Ldfe/37IowUDuVCb2hR2RyaxwsfYhijvTEl+TCXEjE+HcAoZVUDi30dOh3OL9 +hdBt8EQnJsMg/4bMZG5sVnaRFBTJjZfXhc3+SHF3yJq0kMLMZY3YJtYYY/CNDpg3Wmcid9MlBZZk +qAJqNnNlBX6ayxNMLbktLMlyQ3OjoSQ9POIMfnT/AVmC9j6cQ5lBi99clmCKla3hSZ6laS4oGjUp +Mr4lBCxy4WiwvKTWc3mhPgwjPrgx7FZWXGp0SsH0OqXnfPF6lxXUjdROKcwnYFRGYhpjfuVcxl7P +DLtOFQKIvAYlYsvmiDZpXuA8SJMUU2O7xWb3JUwFIPAOGyqJKaZxmjc7zAbODql302PZ9FAqz3GD +kngfwM4NzTu2wcSIODW0NdHMmRrZJk6Na50Zu8PyzoAeDpwHrwd9OGb+tfPqdRf+P9qoc+e6eOUX +X1BbaFOxlag0Fp5rV5lGfvWYknuPn53+/AJmwxe1+O5cbRkd9+JrVphB1/UjRGA96L3qli9KwAYz +57s+/uSjvA47QApxdqL8YXkBc3n4rDcW7EVO1l45JHNQ4cFUY6wgQX5oDjo+zdkYUfe+73Va/XZZ +PXrmRfUIxLl3xBOpREEreLW9J5nk1hhhzDbPmyWsm1mZMY/VvfU9zyXmvaFN73Z0XS0TOm5nRUGP +RSuYZSKlgBu0OaC+4ywzkx/mTzTMSbX6NLuRQ6eVJi4YDi+Qfqj4izGU1ezMitfGebdzjhzAjImY +qJtDUM+GFB3LqQZ+7o0uKq6LnfCfL/zlJgp/t8xcPPTclZcamZudiK8m4iUZoDfrxHt9Z5oF+dLm +hBPsn8JampENKkkW5oOiBEkbFHYpx9N17WbJB5ol7iW57Zkk+kajvzdgjNP8+of4Y7ONjN+/2hyz +yC6y57aW8/oYK5feRhw/idzQbcRs+W3Em7j8yfcU9dQ9xew97inqyXuKYuKeotjdU7yKGP4GxO0u +89JOBFfOvIQTZmbeJcy3hC9m0r9JLdVp1kgxLEgURWoaqUj0R5B2CaRoQaFQSSFtiEZRGHx1gehu +5MZgHvTbyfLxscm2Z5fY9cfd/i+YpnOzvG87GbdTM52N38/i99YyY1TVlMzbVSHfRz+UO33wKjLz +nwBtXnZHP0XS8rhzftH10nJOWpP3d+zOIlC4qfEcxPEo6jVlFX3Ya4ecoksTkz5vdsvRqKS+Pz+t +3Nu7/4yza//0KVH98re9Sfje89Y0W+7++LozKu1v1RcODCbsHYxxZoawuy8e79delG2HOjH0fiuV +Nlqo3KtnXPYfZReXvS1uZGbIYRBsWVzu8aAse66YFllh09o3hNSpDXX3pGHpg3dNLpznqaFwwswU +wkTpdH1hvH7hCktT2CuA+K6ly+Uvxgo/bb4qe6OmKw9KFVCI1GV5kZFWJTNJdxESkyl3KcHkFAor ++HaCsPGvhPIrUaS1x1+lRW3/K6WZbQlUNTbrvJKK8KeSHgtOkqSg9JkFIqPEDQm+v0cOZYqSs2gl +MOjxVzIHtKnxQ5ZB0ZRG1uSZvQ+ZJMKONUc7p76bY/gA9PirIonwYV3gLUWNJ/gqMyDJtdHuUuVU +tK8guj0+7J+AfwFhEhBKoShEHx8cxHHIRGqj1AG3SulHA9OyMBQhKFJgukOosYPY4f2vdMEIlRap +608q8lw5TC7avUjxPzSNiJmMSSLrUuJdyiONDxLmlmEpRa/CxE5tYHPOaUsz7OIUOkEjAcMYodN4 +RUPYuxqpnThFkuZ2Umt3DzVjzgGzEl3whFEJElpg9wzjy5QR1jwOiDKaDviOBkZQNqSNo8Xn39xM +kZaDFp+mgcgFoMsULxqT4ptgOFU1XpGgnqZAsL1VojOpafZImx/EIqJuKeS/Yf4DHbQ80lThG3LI +NEqCCwstMdqOK4ZBKOSAtFlfI2QJ8kzzqshgqWnbAZi7WW6ZL3gMPXV2Ils0qfLECeER5UrRPZki +yalXSmeagjNwAma2W/5SkZnqlsHFKnTGUmu1BCqARdmpir2SkldTnumUeKOlUd7VEYWF8DWE0BGR +YkfynLldwGKxq1sraj5JVaFsGD49U+LzbCf4jpvQWRhM1zMDeBXRp2zHSFzDeMH6ojWntCSMgm+K +JDzrU4vRzXqa9Cgu0F3Jk1RL6gSICeEWU2GnqpQU86uCdMTYGXsFxc76BBclDAj2jAdSFVpTH4Dy +goJqcDUllmB7ByoSPyzX3LUfXk0Zi1+heDWB+EF0RFQmE5oGAl9Qt/HphUkocImeS094auDL54+/ +QooLLzQEzDTLQFVI+7pNnkmaD6lb94F9tn8sNCTzr0jCjpvRszkJvqvKSyHsA1a8YoQRTp94G0hp +HKTgXU7muPZg9SpJ8htftbW7dMbTw+BOgfzz5AE3cdLmNPc9p0AqK1p0gDO1sxfooHlhcnvT3lgo +CQyFk8bzXuPWJ1JFqzPzojG1Awccoo0buG1XGMixguS236pYkKfxVoWPVsNWhUOae6SZJkUEkClB +SIH7OeGCDVgRMi/T3IBIzXkAAGmOXaUVa7Rno8msdMvpnVS6/WI1qEQIulDkJbi/1KBkNDooxIEB +2tAyYaGZCl2QhUYVIreCO4Xdi6ZPkRcUTsaZspUVK9h7QOO3CIPLWNCWk0tGa2Rq53+mEkKbqwQ+ +0w5hBA027zwp77Vu74h3Htp4vPBL7dPIeMFQJMQEYCc+H06X7ogJbsxx23FzSowPF05R2re9ZgFj +ZG9kAW7LWpj6Vq8CpuB7z7gyeXd0CxKWUmBtgRywjGW+qiyzwjCD3cjYRZgJWpYG1jaxUXJfBS+r +xAXjEVbia0pS1y4m65glbfrzmlWPI117lkN2vHDAcfzm3dKqWCbUeDZove60l1ZyxVw9Vn/3X1Oj +l+fnfDxc1K4tNhPF4363XfZqLyi2agmeuCwim2+0jRCgcdYWpCqLMuxPVHJF7S529/Gg+Y6yQT1/ +tdKhx+61KEH9Pia1Xcz4WiYh0bD90HqHc4MN7kQFS8z44MQyziOJs9Nv/6ZQVkCl9r4urGda8hrO +LzQRw/+d3oZKhEaJpFmwG51mtKloUPRpQ4U9lIJMQTDZjqXcn8kPFmlGaxGV8syLThC+pExogcIA +PyRZRsgkbLe0myn//3i3xn9RsLEEgk1fkSBH4VLo+EOSabfpc7cmPzjEkiQmnWvgX17ZEiQvkamy +3IpD2D203XCLnNQc4/8/tvnodHw/g2MbCVYJ5y5jFR4Ya3tuyLhLkx8cxszukKRLZCx1YHsx1DeB +GlhGH3Tqjq+5/7+bF4mibR8FN/zLp5hc6cI+mSBSmmegPGfGnWu4L5MfWAFI6DCD81eGg9aV0uHQ +sY30EoUDC//y2vqxPK0d9Lv9AZzT+5cXfpW5yQwSWvHVNz7MRBp2EStkJvUqtvSKHkj8JGMzAq0L +0nPcRp2xGiAtRp4qVoWiPTvzOhSQmdL+ATwyqTM2zDukaj11SLV9sCNZ4IhKh0LgUzakKcYHEItC +Ijlp6AQsxsx6Y1KZ4c02qyPaR+j4mttYHyTN04yXkoSVrmlWyQyZhc2bzDgljq/LRYqm40lehPkl +LLLn+95GxaaoVV7NOeoMR7F5bjxmYNrZEae7mHETKXh+4/d3puxq1OpV3vwRSfyAIA== + + + ovkv6NHlaNTvuUdup5+9nXpl8O7z/sX3F+O1kGqg2H9/3uyV3ZODbn9Y2oLPXLnmqHzUKbttLvio +0z2HPy+OkeTjsgnbNTJmULY7I3yHHp/VmniX/u5fgWn0/Fy79qj5tj8gY95dIvXTyZfwLI3zeeXG +8xBIOy97I+hfE58N5O+1L+hbZCO2TxJbq/Z+tyzbR+XZ6IcmWtFqk+/7JbWzLr4B1YM5cDEoh+Xg +bVlDwi+wD8PFFVrdzkWt1Ucj76+1AXSy33M1suixwbjGoDmE2VZ/W7ZGIItOm91mr+V6dfefT4Gj +l+e1F+Ww3710RlOfXxcQiZqn+bgcXV5QOLnF+xy7Pqqh4dl1OUSRAAdrT8vh69oLarzzGxleo2Zs +jTQZqwHL4uJytKROEqic6txRs/fqsvmqrMFcvLyw5b2zAZYbEP+ivLjsDmNs0aC9wOUWjdr4r9/1 +L6Lf7r18evRtv13OnAv3a3d/Pe/24Oc6sGvQOYUF74bp3oMBKF221jWj+AD4o1KgMXfbg9Ixjl02 +/Cv+M/KvUN79Y2948rY5GN6PplNc9G1gJMGHc8r1/OxyPRmOfdtQ7vT6vbICY7r91puyXYUzXPID +Tcyr0nXa6bWho6ICbTA5YM1a4bGcvrj0Bxr+9+SEWMiJSvR38HnXKhN/6ahu0kL/4m3lpY5Fb3lG +I3mg3oz657crya5vHn4xbKIygSoOLLGq0/Ha18UxPkawNl3ZhlU6PPtljXfjW14GQ3zBe8NHuQ7n +ZmNYZZ1H6S+dNt0WXjq+ruDtCuBqNL0uXcaOpURxydulSqLHYxlR76rQ8+62Scl1IZdR8mslcXLb +lPgT9zwyTvsj0APwYP9s0HnV6VWharrOGuz5JOyO+5eDVrmPgbC3vunD1nTbXTgvR8026EDv24/i +Pfvx+7YzaVSZXVHhz2dtRWNz6bjs/rU5Ouy3jvqtZhfPUkP6fda882WBlnLw5DAuGf/8HepH2Krr +vVCNpJFEXX/z4Mmjy26X7TQuaBN+tRWUt848h18uSgr1fjzotE9wyTxqtkqf6QCH2L3h9rzf6Y2Q +m1O1joGyYLuhgZgs8n2v43qr82Re62QIevjryLN2QVnsaVxU6RyF+8zGH3X7/YEN26OyuLtli8ru ++5mxtOgLNgAsKkmERR3Qc8kinM8umq3O6N1ijhLO0FFpMF5tdlHkVdx6XuRiQdGAVM3n/w+d8heY +a4ed4ShYNo3W6QLEnlc5JieigJRlM2tE5kgqsIx1JO4nOLeIye7pNZrjcxfEQdntHoC0dgXTuTix +4HHnNx6N+d38a3/Q+a3f+2ukEiHb9KJh9oyTc0p952Xd/IYJ0ySDvLXbRLbrZm/UqTW7neZwulxs +4+5fjrqdXlkblb/yKvRm4oJt1iiQ/n4J2Ebvakfl27I7vnMASnlyfNEfkdPuab+9xHTPbQ7pVsVw +mUAjoickWlKrazaBz596nEmGJssPzV5n+BpIiWYiufzyVJilmLAPz7vNXomTJBZaC9c21aDg+A4y +D5dCGS2frFi+fAKe7/oXcderrr+AYJ9UqhiHyQAHIqqCYxYDs0JXYyCu7NX4d9ktB1b1e9Jrl78e +l61+r71anUedwXBJMzQ15g/TvGqenPcbXI/mimPr608NbZaJakNr3W3TI8uUHwz6F+ittJfJpk0T +E5pTLmhKZVPtRmMz3oBLqPTUXZ8GXejBYHTabw7aNTGdfilymnl58eCFEyEgFVQsFGD9f9d/YRu1 +xPeHHb8ZSe5H9SpiQrA9GXJfncf622ltl0vEKuME01J/Tr9ottsTAvucHtUYAw1B1k6AQDizN5M3 +mPZFpzEu0lv97sCrog+e1B5cjvreaVhOYCQ3IavJtTe9fusNCO7aKxuSsaBoZ9gHsVvWTvGyjkuS +NVa4qF00L2AfGHbOL7vN4KCU0c4zGjR7w4smnA5a76DNThtKcxe1VDKPyjZ5vrQoaERCy5H3eE6x +iqheRTrXsrID3uJjZWBGSRF1cGnRqANLy/oOCJPmqS/JZ4iDZu9tcxg0HDE2fs/ZoY7xCbWH7c6o +aQXbhCZGHl0rbyKn7n382V/0mpjik/fAJjzeQtZgMj7mPDR4Vc26wBc5vW2lI9QjYIVRJer4ZKXx +lkTt4fPjlZuytZa3taqHnWfn8Q+PH/V7o6ABpuEHGJZWZ8zt7h7U/eEx9uFZz+YwnPztZXNykVKF +84uu36UmWsfDbcS2qNrzV2fj9AHs8LvD6YIoT/5WDiaWM/zwsAcy3IuCqOGH56dl20qgcVEFv1Fo +znfTVqapA0ZvitapIq/7v/y1054g/AjaZen8xJGzPLCD5t2CYI5xjRylLKriD1AVjzngyxC+AwxO +OXDBKS/i4JSpos+c9nwca8/JvFLfeb0+jnKhIpbt936w4S37cXiLmCj6bCLGpkr4Cy6ZymzCwkv4 +ZDFWY5Qtu5RT48Vms8qWqcYrh29+QFJR6/VDwFKt06OAJNQwWLNaIjZdW/eC8fPez/3TBqFrdru8 +IwwnjWZTFUASwQ77aoKGeXgXlxq+6VycAkfejEuJyWIDODkOhiVSM1hcEvazIKbuTiuBk+WZ7Iii ++35XQ0Z/0z990jvr14LBbQmj5/XstDM6b2Lo2aTct3tFXPzi1fmbxilulv2zs4Y1Z7t9fG7xc1CC +h5PFZ7F9HPnlsITdhjZmv0CdQlr7sTy99wOIvv69p33Yz8ufFrMTWV8SZ8Y07akODEfdRts2QZOE +h3TJaGE1Vz7YY6vUuWifw8/dXuVOXbQrI7dhCr7GrLG/uBi4YgvGBMq41t04CzlzpKFc5CLMirml +Yp+byOeV6pzDYm504RxXreSozwF+hVpcchCaz/TcXtqy8Yy9C5MPJGq7dvqudjjovKXH/BYMAmLp +xTvDdEOtCa7NLxQzbQGqfmQ7XIBsotjUoFMpOqwsFmntcth51Ztx2Jkpck+dc2kRRirYP+tMmu1n +y/ChlVyVRerYcExT3R00zr2db16JVr+HSdrwtLqAFizpt8RTe+nJnmNnlh60G/0BKu/Nab17suAZ +KAuchY3iWWeWunAn/EVzgVp91Vg4+VwZF3olkrmlhuhrYVxLy71dTOOwddFtvZsvlWyZVm/SEDZZ +ZgRnveisPoc+GKdu82I5H1y5BX2nHazsoRtskdzFUkNO+LF05lJxK6fDwqhSB6b8CDPFuJ7g00rz +9mgQ8agujsuiBRv0kjKtQf9iSRFU1jqgviwpNogydSxrFA0Gp83BcME4jqsYYXupUHgUkbSsbLTH +VNCLQjcqFPbdqFA26sasVXTWGzXa3cUiz5a5GJz1e4vkHRYbXp7yekxnjdEQCPVulpmjOARVFJXX +hUV65atmsNrOKYQnEFBoh4tnDZaD7aa3GFdXILam97TNHv9hY/i6CYeAcgGXsFA5Qp8R5/CPLL4T +BcdLZbPk/K8XjbH7G9S1WaUGk7o92Y9mlXw14xQwq5zbBYODbdb8CuWsU2xxyW5ngciAAuj8a44d +pOcU7F+0FkgVKjBcMOJUoH250CawQPJC9cVqBpzohsv3CCp1dtlrLZgltoyzRvBMWbIxUJ1mr8e2 +9tmnaSq17GjQOo/UpbvfN44bNXvJEU657dq/7h7/+Oz5vz6tvZVLDmfnoM1FKt8sHRLK4PHK+3Hm +dIevT7XO3y04tkcF+/ZN7umz9QMuHp2uY1uMDpbQ551fy+7zcoBJyaasMcfNt+VTODt1Lrrlg3E7 +xhUO653em+5wBIvK+/251096b2p4i228u96oPmG2vcCLd27cbE6154ePnDULtYb+xciaoMZNhN/0 +T2vP7E+RzSvLxo1wcalglr+332FKHxwfPHmS68MSZwT+qP7y7I///OzLH7/65H7z5effpH98Vt// +evD4/PUXr3q/++bR7z6/+8lBp9kY/sF8/9eH5vdffP394z8/VX/54uhfnzz9enDZyh49lE/zO0Kp +3yfJ8PDnw1efJ3/4+v6/G3/6+svPL4ZfD/8m7+3d+fr+0e8GXOib0f6rv/796OsvVXl80Pnqz63D +RuOTV1NNHbX/Ae1lh4/ufJH99+PR4c8/7av/rn/+4Lx/NITBHb3+7M/m95ePDtUfftz/ufvJj3t3 +Ds+Sb05nIvtDVpxlP/z9n/968N1B44f5jcblvvjp6y/fPPrp6y+GjfPPDj+/c/no7uP22d4dYtaj +/zl5dnl49tOP2X736+7LL872X48OXmf/LcbY8T9/PGyJo/98/eVfPvnR4oEuDw/+/erfffj0x/8c +Pmk/+d1+Pf/5Dw+O67/v2T68bLYv9+4UP9/9rPWwpf9+9+C1Orn/5YM76R8/2//28//57OuDT75/ +dFBe/unPP3zz+9f3W63mG/zU+ezh2dFr27JI7jWzQecP//NF59/ftPe7d/7ySX3w2b8uHxwd//E/ +2P9Pv77/zet07465/8NPXz/otT45/+yrp/fvZef/+qqTZfeGZ+mDQeuJ+OzNF8JjbB1+M/wB2JZ9 +UmY/pkn7i87BvSaMr3j61d365+V+N3t+bin4x9Gdrw+efPn7Hx9+XughjMuTf5rf/zk76P/7sy9/ +aP/zC3n6+58I7Z97d4CgP5s//R6H5J/mR/P3HvLpz/tvPjV1NzV/aB8l4qffPz281/zyj49+99l/ +D7AVgz/8m7BQkb07yen/faLo82d/fvSl+/Tljw//ZosffP7wfywy+Q/5BKbuy+SzP//54efy8C+v +vnJ4fvzqy/vtn7/9N42k7zDge7avXStQaP8b34GfQgfE3a9eYKFSEUz/bv/whFh9WA7/osx/m59b +D747/Pmzw7N7f/vPw2bzkz/sm9Pv/148v/Py+wfPDvafH54dd/7z9X9++uL/t/fdy+nsyp9PwDuY +nGHI0WQGMGAbDBiwTcZgg8ncu+ef37OvpMnDaAJwtmq3tm7d78HMoJZarVZ3qz/qhc6cC/ZaQ4qZ +/fCsXxz6nJ1csJt9IQu/78P8z2/Ym/j+My/I/LfDBxiYGkUizdmWoxd92/9Vsy81R5Us2GdVijcM +oynZB7N/2nkaznRnvKcGlApHx5lE62TItp5O58uhiTjL4wMzEd2DnmnqDaycl/xJZy72Z+aFf5RM +FwjyMxNAIpAcJckCkA6Hy5nbxgbiuRJylj+xzERQkpNeHs+IS2AsfD491UrZ4ZMPSUzSuUuMSNt3 +1ZMlkq2+324aJKmOCNkRPjdjc9Jm2dnzy3BzVXTWPCQnqWAB9LZQw7wVZ1BCM2BR/VnA0Iz2/GJZ +PEYS03YzG+n738Vz8FpedwRtG0pFt2sSk5qS2GpezevM2VZ95gQaJhUr5Gq9lVRv0Zu890q9yDdY +NEU/4S8F65eSc3ol7a/rBFkI9f3OVGnk1pm5cYFRTb/JYiEUyYXdLx2kcDy+cseFiBa8o50j93ua +/eXWm84221p2TaCJqpNtYFd0bZ/9pMUd+cg2v5dW8LMvSy7srC0pbWkvfFvLYdDb7Q== + + + ktKCxU63zKhwQKD61QqQmcVjFyr4UWESXL5n2+bpUfieJdtsfayjv2t3Emk0biMAVLjn2ycimVvZ +dj9ksuSz8XR7v+kY83kC9hKesvYRk3PR9rh/53Ya0VMgybZTZAG6N3+7eB4dOROV4zfQ2FNjKOc7 +rz+yb6OnPP00lh1lkuW8B7wy6gAtULPkfP3zMPt2bgW5p+hloMfAF3+ZwzRuoWaLvz69vWT6Jb+J +NL8XNt9k0M4GLHpTEcp03lfK1zLwU4p4Kvkeifkknva5bPk0+12K+4XOzL2JvoV/5qAqzKMfoj/D +bzV/Az59pH7NEMjD73JUY9mkm4yE3IWmf9jfFeErSfQy/LOgM7Pdy8GXnrl2KCqQnrCJDNv5FPuL +BHoF9uYVdYkdbhZ1RGdGw6QGDDsVeS3XW/C7BGqMo4KaELOI6bKYKPqTbe+NpsL+Gv0mAZ+jYaQ5 +VqLXUfcoLm4WiQbLgjfET5ZKUjR1YPaFEyUxtVdMhGgaaCrUbyCzuLbRMBCfhOx4RKPi/kSNsZRL +En3ISI4lpTwlVJfRJ7ZFiqjwT0osgObHCQZWLODLNXZUnKhIMgs9AJJ8yaxHaqxo5TDseOTGDF9+ +kWKqaKWyDHykOCYaJuJJXNhEWtibPEuZkmkRUfQyt+qAJHOzJZjVFCe16HXIiazEUkmwPXxllQcl +pOgBvfZRs9pZLS8viOWIi6hlWsakFCAaGrs0tYkhNSXsGqK0JepjMxz12V/QJ4r9cBio8/CfvtD0 +c2RbneqGzFjnLWDpf/v5G0YsuwF75aJGjuq9OKl3eMAuBscVZXZ7twlYLoVV5t3YXuR/BsNMcbra +W6itjGdOhE6veHeGb3Y435E7A3wxoUODOlpYuO1pyvR7rdg/uT1O4G0RxkzHaovll+dmv1Ct7nP8 +AeWG82xzU3jJvA0OE2DBrjN/PiEVJ/Id4s/Eeph0j8it+KnXYP8ATmhnV5y6Wt5c2OV38/xGX26y +KMwdxTJnW0FL6ekc4xhDW2Gf0Ree68Y3IoBrCn3b2JrcflPm2UUD3SD4mXvrrTc/s7BfwFIC1nqo +f4tzosI1gZbSjc6JCteEtvpYCXXDoVEus8D3Haw4DyW69hzK9By0zSvaPuo+5ZAZy/GJa+r/Lc8C +OdKMP1X+LFRzYSsgYJ/kGpkPR65h/johcxiqiogEn/i+CBL7VLjqKVR+I2OObcCzgIyj2Z/dlCOd +da2VfWlXgbiD1UkJJ9cRnFNB8TMVDjvYBVDKrcOLD2T968yc/X/Z0flLobQyz8HyaiRhUGMKPrlO +pZ1hEos5E8FnYbM1jJOStFIappR9W2ec4NeLvW/aTL/4M219jPZUW445YNYqqOD0+/srY375qY+D +Dg+HzOx/ecBwPWDt51Z1J3BEXr+D7AKJQ8dgkFv5H/XcA1bYifjsb03AaXoS+MjhHJksfnrYViLk +4MthJIubM1iVfnPsL0pJlsvk/YhGprWnXOM1A3aL3t8z3dFzz5xtPL91oK/NPHj/DdA83lqIyOo8 +eSVqO8+6dHyZH0SU6VUpon1vyjozK5Jk5nBYtoPx+nsaEUgQ6cQIend54juWr/DaftnlyrngOUf4 +XO2jXjAHH4NsLFF1sw9awb3nJ4t8saIrczA8lUmH3RUE6uod+Deu2QbsTk2SHNr1SzjSQCY5GWwy +7w2nJb50vv2AzS/2i+Scp50vAhhld+Hp4BhRMnYpMfpiinqTXb+CxtStXn84a0E7IIzDKK3fABd0 +lF+9vI7A1Qtcwe13/uf4E4ZRBfdHk3gq7vOiFlV4+bxmG3qwczOrNwDMl+oavRL3RfXA5iftvddT +ttrzzahpfKw+zwqzv5iLET6bAfjpaaKQLxupzci91ac8VCCAip69P4bi85FlTvOp/OrNrT1NH2j0 +bYPMDp2Zovjcjn4VhwPzB+j8Qp/Z5wY2dsdasnIHtG7YZAaciFXgnrMoTrz9H6ENgzT2B/Ld6f26 +tgCWUuS9vnsT7t3Um5FkoDgvDl4mQ2CbJKDC+bYXp07iMxu0xRpA/b1HKVuAJh8wZpLptqVQ+fv5 +yIU6XU+24XhdZJstJ/AsSubSVyS38s0OfFOF2lAevYXKR80BjY0megVo5+SbVOejLYvpjRwaLb3C +N+BXbh01uQpPNrsNGTfs2keWxMK8AjIRMyS+TW9LCaJBsIk2j0WnI/zN397gXO2GuUGmYzqdWMo1 +MMULffhUI5tAkkMtj1vwyKonKh+lJN0Eu7+iCG399/s7/mNt1IFJ58qShV7ZITU0wXshp86c+Np+ +fMq91HFEnqeJF9ErifnAvkJxtPjzIvFTdG37PqAZQ77sW4j8Kv2dHFb43i+jYS6kyHgEe0l9SRky +6XC3lH/Od9Ii2aBPLw76D2A275tgkjN7nnVIN0V4AHvfdzozOgCRmAMPWJ/VcPiR3JeThXUtxBnB +9CQOjPrC99tom/8xmEJAsIMv2U2qspWSITgvUOhettNdrP7t9WVf4sVqJpHb8S1vumdJW+bgjp2h +Ts5kI1+z58J3bOQt9ucni4ifsd+DtQX2/UEvu12+OADHhMLCmkvoz0+u86BT6QpPSlKP4YCUgMRW +2WIrG4k1kdk4LHw3jmBHplQF3duykcxnvxZkPrNolk2Pvko25l1lpV/JOn4znVZlTCYLJ15vgCY2 +GjLx9/kiE90dhigueUkFOHQONFdAil6XakdKmXnCVpKldf3PmYqUymB/2fcTPXaiAkBRFo8wTN8A +0vFryXS+W2de26nw07ngac7cmfjz74pnnIN/WmEDucnTRy/sct1nofea+wO7n4D91rV3OR+MGFbP +g3x2lF/OhfLgeCy4JmQxaTeZ20AWe/vc30sqdCkvDQPYvlZ9aCklfDag54JmYKq1vIXv1gE4e8T3 +H28FVo5fo5KZ1FczB+PgVPjeHjwSAhsDu+bCDs92umT+Ox3glg/tv0DjIAIDsZSJRZq6vz+EP7Ra +Fkop8xyYGLEwFYOddvpHttkEaavM3qFz+Ql1RLcwTw6gq3B2cg4gc8oTcNjs0dAh8Q6sotJv9sWX +CwA3O73KJFM7I38tMmYQ+DTz8rhIHF39cKodLGZD7moDKgrfJRX0EurogPS3JPckA1nbFKehDaDs +9tglmGXNRt7qJJiD3mt2m/22SVMBnK9GcU3YgPVELOJ1ZwDspC2LXtVKFYg9NS84wWeD78QJLOLW +Jkv402QDCNWIKE57h1AhU97tmZddW2jQhSlBKvUya3RwSFsXzsen/hOPO2DX+cqtIxkTciXog8ww +PFyIOM5QXzTj7u/kgR0pPwRRL9uJ3Hq9G4kceE7GeNv2pDghkla+BU+3GKYeZNfjOTyVMMLDGiLb +3NZOBdfLfsZYSqsz22v+/oKoWIpTQ/gLeDL6A1mMNstiY2NfbtaQo5z4/rNYgNv+G+ZsIQkLoA40 +dtGDJhtQkbEpEu9F54vVCRg4cMu9l6qDZVg1AcqkR4qyzszSfs8k16Sdb4OLG3vDrzu4hPf552Js +hDYUZ+rYj3HKEWhLOKRHW8Pegx7Ks/fHGE/SBi3zEjlce8NAR4bXmUh3UcxGS8cTPPp2k7Yndyfv +a/8dE/O45Q+MuWnnU07t/5AVCXVyejoXastzNjrZLXhbAlK4/ca4DGy9LZH4Ps8PYtW7dRS8vF+w +B8NIaHTm8N4XewP29htJZhZAyN/OrZmy/IaR04v4AP2AOhCfdz+wR5L17JsrA+Zl4djwqSDhLE7P +hmE26vYYoEEYFokX2I4281xwNZuFO+2vTjSSzpfzy4+ZAXpYhkyyERgUqtWkgT0sFv8M2GPk2FLM +JL7awOyMNJyE37WfAi3fX4E993uXba5D7wIlPO5mjvauoVB9CgCxN+Z2UgqVObV/7Udaw/NGZwZv +5h8Li1DYkHSdP3/Cqb2jCLwgx55MklNaGln9xKomRifReuxIOxWvFudjJmIooNwB0JGvfORttk0C +a3xnGri54GZ8Npu24v6x4zW3dvtapW6/uwHzcspx0TzqlefB5EyOvs5LmG1hRb6Re+NqBdFE8Ceb +gDdLU7Px7XW/g4lv27KbyeLI6jZBiwP/H9oDeTkWgmY7wHgdnAEDe2ag1hpn7iklY+/ZVjvS4ngX +W2V+a2Dkf++CkCXk8ugdbFE74pglks87XkwUMStnTbYKjh/vNOnqVXPZqKsC27P8gLGgtcoaRDjO +M5NDW3hFYEzlptmXahkely56kA9+QZcaBrA5zD8S4/ftL/BevcVfM1mMbX+Kg+6yDRSOuyfx+ijc +fvn4pTVMjfzEtk3aT4ltcRq2h3J1u/0nsqk0nNATF0ejG2Dfr5NWIM6mftHdiy5ywfeAmzf7PwPX +ItsqHB3hfXWcfgS+sQ04V0mfkB7biuMRrJdJfPVY+PrpGXmCxraD3Hqw5/zhmgg08svMzF2orPPv +oi2f8Dc+jaStmouCeXntu7a88Qvi4GFWM/xA/zNUnLSKIU4zCij3oeFQnqGANRMh6cdQTAX6yAFi +Joy5xIvj0a8ru0nrX8mR7csPF8Nn4Un/TXDdY9oeDhKVl3IzHO+2J2Asc5I2EYGo0driiViA2Qdm +nh0Q+OTH6sNx45eq1KJQbOgs1p0xsOqcLrCGWsfiNFUGTbUtO1OsXfwwxRbvwEcGPSvDuLxnkG0t +pyfYx/9JsSl4wry3Aro6TEWWn+2jsl6fUYL79vDAK+CpEc2GyUpWfY26dEIwTC18LZBDdAVOYfvf +DXU5rPjHksnJ6q+dl0rmZCgz+H0elyCIH/AkP95RUP6f+VG2HT/VDsowrWymoB108cX6Rw5gouZy +H8kEfKbj1C1O5GH7lz2c/rs9rHIK4Efmh7AGT57LXqdvKMJnszK/ax1+/uB1IzLp5yxTx4t5hQ+9 +wA+Duele7av8Ucp1oTlf8Dorxw+GF4CNajvR5GAPttYSCNDD+DB/OC3nDzSS8QFMDZSh48N/l/PN +w3H8H7jIxpsH/mKE8vIwPsKvuRxZ5j4Qz0P7iJoE/wob+2d7ftgB6X4Aq2xOiSoiTTW3gLXJfwSE +XA+AGPvTDej/w2kLm5jOH34QnHr8sB7/A68pGe92QGypFXw8T5ewe5VNAaHwuGYoahvAojPo3fab +I/9zfDhvVrBosEdexTDLBjQ9Pfzs5OEADO9JsMTf5xN4AZvytFJVMX4YeLXcqyz0XLkLSFHl+BAg +rEZoHQA32atFpF8MIh7QIGS10lfjMKsy5N9O480MVi6RQW4wzda3m+0UVYHB62A5WtQOAB4DwaUV +Idw5VOhAgQ7OTg/byfhUG/8zZxgcVNVrnjqr/jDXXfn9mF2D1YLcYCsQjJudbP+jYsdAIoBToNpU +Nl+PqFsvFKfz280MgS8rM8Dxn+8fBmOgYqfBF3SR36KFDBNLR1gDw7gp0g5+YVUBe8UeBSqQrAoj +NlRUVIhRnHiOBdwwgrKMg2KKlzQcaFK8677Pb5UV5WUMlDHYTeh7J7mlq5Ic79fPag== + + + LylgfkuXS/+H+6G2haROJdKCCAFjYhNN1pqhbl6As8Ddq4P5gdxlknJrRGSUcbIla8lBMuPTvLU8 +/00245+1CtOMXjgt3kVhylsZMEUQE1o8tLM/pDQe8Pacd22W7A70dp7AGd1uTk0oQeqsWKm1KAUM +5Vt6oHXR/VxqTXMOiig/dCRlorFr3Ht5GlLLUr/YgNVshCKtJtZP2tYha8gDnxW8QOnmPOtOitBr +8O4raPiiu6F3Y7G7Rt+wRYnGiRW8xKWTm2Br0wkrqMF+UpXV4C1FzDMd6j//G0nQmDMVGkWc6c7E +S3iddbczvTwF4Cd/MNmIB9gHDfYTepAIpFunXOE7VlqVjc3HMTy7SrFP/c7HZniptwfKj3q319rU +mfXO1Cqptz/3Y3rX8gc8Gn179M5z/E3vqncLejdR9xPex54NkQ/p8/ZG8Og/1kHnCqtg+mWUCuSi +gWi4H/7ro8QNFBDhnhLl4TyvMx8OqcdJ1rV7fspUY8dUtJx895DbfrBTPHz2iUKf7LXIx+zj1OfI +RjY0lYCp4cy7HU1ArxbGDZcakCdQi5kAxy5eqh0Ph8SxBYi4KoQ3+EYNg+vZMUqeOv7BdmUhZhYf +ovzCNXv4Io5J0Hb07EyV9BY0cDQvhZXHe4yWgtF94hf8WVqDX/cKQqKfh6/6Z0OaaCkyCMUrA48k +0YHpuaYzi8hyRMM/1ZJZmmhSbzscfeaDNNFX32fQ4I87OKI6M0f2aHXV3RiioaVtbO0VpYkG7Z/O +pH8hPVIDOQjqzMb2bl2TGitB5qoZDNGw0bQ52B8xRHsDgvx+fuOIIpAlS7akT1p8T8OWJNFS2d/C +stffT7VGiCiQxUlROKfvQJI/z6kaJGu/nFVbL/Cx9tkB0eD2QpRqRI4m+mq1ioiGQn/DHUeUk2SK +7PDwtdy0MEQz43CENPkkiQ7SoyaOaFlnNgVsiU/psSb1X0fjct6UJtrI21N7019NiqgzsY6nOKJg +XoSi5Ej3My/SRIO9HkHGiGdJogZyETE1//wvUkR1ZoL8+iIxYw0bzatNPY8jOiZKrlFHmmiJyFrn +tkgPEdWZxQw+GV1pmmjPbRMxOP0cfKTZW/xckQKi/SRRi7h9kKhDRFRnPhrK8224OXb7AdnITiy/ +tY/+GEM0bIysZuQAR7RA1B1fMUQUyphorJV9PPN7eG5KEn1LWANYotX5W4CQIgo1f/DDTbwN7Qap +sR4N1fL8+aNvt0kS7Vg3CyzRt2VjNEFEdebLsX6UiE51l5QmWguY22Qm+ShNdPdkkCIKdDIk2xmW +DCcMgz9eiPd0tSBNtJ4qDgeNry9Jol8vqwoiCveXy7H+9kIzEkP0M0p8HdduaaLPv7u/l1g0ICIK +Uwkg2WHFvcEy+GB+c+oxRHttovjz9yRJNPrsNugzX26gxwDZ+F68aM7DyJAmOgnYRYvG3q+NHYio +35qylYUjrREjRzwLibo4ooAKJAua/d0zSv/xICZ63FoeaaKntFM0Uv3n+MNOEc31fBWhInQdju2U +HlABZD2XWqniRmMFRPOnC1VYNoQpomlf1S1ShK5d8JnaaQKmeL6KiEIqNFnT4TCebCBRQkT0cMjO +t4z8PulFRI+h3zi906TjDY+IvYbtfNTS0fbDfDwMCztVblsG2zj2aa/h++vgni6J8sh85p5eaH6g +egsWzK/BHFiceaZfv/OI6Gk46hu26KfHVfRiVYY3S0NX6jmlFF8r8U/s06jf0Rzhny7HAyvLscvn +Wb+lP8U+rTk3aT/+6eTlO8E9FXEsbHwxTCdlzK+jZUs52T5ST7+t+5jot23nD2OcfvsM8QuOtSdP +bxup55SWKzhXB+zTd/PEq8c//SzEHxmOSTwfmQcRE/bp7+l1V8Y+XXX8uQb39IJjfysyNcD9GnSp +kQhhnz75g6kunmPm6WbyVsP92qK3VD4d2KfFbH0yxz598qcNPjzHsnq/yR7HPA2VieKjgxlz3JYQ +PXW2Gsc0/TTvSYpXZbk1Kjmy3PPgMehqCj2wPDGzfuRp/TMyr+HTHe2OksMQpXpy2+Mz9Umgx/wn +E/Qw83r3U6wHPMzfFvzHA78j9a5CMw//eUf+G+u9UTqCpjdu5hjNdzD4rY+vblqfAz9HYI+ljAEr ++OHTH1ob0NPhrQhvPbqxAj+2ewaq1WAB9L6TLD2j9+dxYgfayVA8nEcet0DdHgw6M0cWeToYomEj +9HM+pIkGe30sUbCJ/PpE9hh/rMjTwRKFW94UR3TGJxp8Az4yj2z0OffGIzqzWIwcUWT9s0QDIvZC +658daWktIGrvIe+VT1bA4Ec/liiy/jFEgT8IrP8BRxSMRTDWLyxRwOBjEE8UWv9YojoztP+X0mNN +6j1yRGtWLFFkU3BE4doXkIU2RUswq/MYQx59oifCnu/P/tS8Nzj/bfhrH/Nm2LgfFLsviu+FlrTc +0doiB8b8maW15cXSHdn+IHeavABNijwfaOViecuIVjxMbXRx/6R2tlmLdtahTqL8/dTOntyxLdpQ +E6lY2fSLepGKlT4KQHGNi5BygFNNNPlU0Uz/46pvaQLIBGYIsLYl6A8Y3OOOekkUfQJqL+ddzgtm +9p8m32KmY2Yv7MsFSKXEH+7oKU3HlECX26/gCws0aM8OhjuU3U6rY94IXi1CBrIRN9Bh4ilkNqN/ +oEC+C70kqU6tYhVRp/hdGp6tQHTrLr81TfDiaKJwIGI50JZf51xVienwH7rzlDMvMT6rHjs+nZkb +IfoHO4PM/L0ZlOfPyI7PQcuY1Aih8dqWYZb6+dsi+aQ8C5XMkmnM58j9ktimdGrEnWFWwq1Jsji5 +EuzIlGSVPvfaOS/Jd2Dc9GlJvpnz/lw/9iTPdx2eWULVY79UPYOiUPUEsKpHpyS6xc/Kgc9AtssC +Bloo1SPNuwG8ioZhMKY/rqKL+ofmnW8jzbueW49V27hVieJxkkPrGbQPjb+LocEF0p1WXYnVpaqF +Pk2Q7EjBKRoVfxfjjWr+6rHQs3+hRouASmeraUBSGgbIDnDnujzessuQL+cjuwV0rlvATJNr5xub +rGXUByrOfyVjCPwuvdw6HxnJ4UkyCupIN+ZT25hUU4jvvFMex+W6G5Nq1538qgN75djQPcvOpdHn +avtc8J8PJ++Q4kIsgGa0FatS0wk4xp9Q+A+YUC4QfSkbYHysFryUjZcG2yVev9BYTiXJnqVKkyNu +kBlifmp7L6ywyynhPL6683JKZiUlK0yt6llFjzozdmNSYTNyLwNr5uOE3ZZ0Zi3zW4I8KWu3nqTW +/qwk1NMSzKpvuY1Xpkun9BN2r3xp0v1RY9KBLuENOmbqdGZ1Mwi8fFnDQsnmF8zgxixrWGiYv9Lr +H9cUJck3NPa2UdEveNWZmsaEG4rWfjEnvHRjPXknRssg+VbdzRwbHu7IMaFG09ivnTAOM4ocLhzX +U+p4pXUsOH8B/SlLOYM4g1Zyg/bnuku9gh7jGdjSq/KUNtxtVea6e5M2R5k6j72YyTI8MqlxvIGe +uHbu9AwWtc4Ha1uKuZM6stuyYhhB2jAsi5SC5HpRnqbUUd7FE3WEluTLrihoAVUdEdmW1/FEYdnz +OkL5yE7MFrUow9D1hwafnDqUFCYZsbk9/q/jxMMLaINPFSjzRQ0EMEENYAnqZWwYSfWBWSAVebND +Z9bSKeOVCkCoLeGS+zqZ5bdltQqgwikAtf4+fnxWFSzXqWO6wFZQjmeILXku1vdbgYd67/cQqsLJ +V/w6ljjNIMiFk3R8MD45kP1lQK180idWcsxSv8Sxbg/ykgCzNC5xAbPYJY5+ETDFVl7hAn+CYxEu +cUmvWzm6BKTWoC5CIhdLeBKHZMW9kQvJiiIkf09CCx7jFCuHZMHQeAuJnn3NYZInmJdQVxveYL0k +cVeezsJt+YrwBpCDvR8NCGWqXMyW+rkS7amYuI/OLBel+3uCh7u9m+I+kC3KsT6RKsDEayB3wqok +mac3BZGGncCUzpzFpjSQA3wwkdbJKoxpyOWq2JTWwjvKHkP9Mcv3R218IZBuR6wiieD5Ypo2wqrI +Er5uvcQbdvmhKct5ldv82P3limj0rire93AD0pllJB3IjnDTu0YBpNvmkE5hztUxZqgQpNeJtjqc +LQu4I9rolPYhvi1LjYW31cHDKis/fwOOCnynRhiwq44nyXnQH4+2mPflmLtvUrud8FRU9REkaAwX +b5WKtlKeBS7eChvTsPik/SWwaHTmmw8p0KzJb3k61e0IHUltvaHPxKl2bl2BVCusN8m1wuhkLe1o +3/dYf1+iMcEJobZNVHg+aEXWhcsmtDjzKE31LicMeZR8qjMrL0MV2w1szO/RfMaHMSJgLqdDFSt5 +5md8L9jFxBrtuLJfaLTjSnyAp0KjSUZI8oAxmf2tGq3NaTTGe9ViwYsbU9ZoOpUnSLCx6zUauypL +ne0dNBqYNSmNpnntg3a0a7SL2AXVzu0aDbZy+9krakfmNMiVs7GnOF6dWcoaEGxCna2cB80/OpS2 +UYKupjDfEvg8F7Fx+N2tB7DM/vJt3ePVkErLLA/W+ctJajFTEXhtahY01tFrUrI6M1bNXpn9IFzM +HeRLCzzxawwUMGuipCachlFuR51pj20FxWFAO7enQKBWMA616ORduR3hobvK8LLEaQJq7B6xamov +BONzQutCuBuCb9232Pc8IR0bmsebPb7uu9poFi92gd0N3zXZ9/IxWNjY7fb9515qL9S6i8FZ0x7S +utzFYDu32Pe8Vti98PpdDLUjYd9LtcJ6r5h21O6G8nsh0jCf+5t3Q8FeOBSfEyMq4Nu7pCNB/SOZ +h0XvlYLkKS4NA2sLDA8yU8JnpUvF6Vu3e0usWhTnB43durp5/ZJY2/K51jIcU2XuMjMJqeA8IjCX +HlXrXOb0NA/42fHKRK5UpNOJuoSVCJTbo7i8xBtT3uO+2JbyHq8qv1LFxuTPdWfY9Dx85hrG3wc9 +86tjpYrFNTneL9sWNIY9u2GjPWoT6kFjAVOiWrtHhARwLKLNxMDkIMKZHHpUxWCpxjCLvSebfEtJ +hI6J36vqlEqJuFhc9I5MLV1uP0uF6htJz4KeA4SWOy707k1jqHd1BkW9OxsYQNxcUQpBR93ccjuG +jr+LXSLoRIihqzF08gg6pJPvgKHDEkUIOixaUCOGTh5Bx0cL3oKhk0fQCay+GzB08gg6AVrwBgyd +PIJOBi2oCUMnj6BDaME7YOjk36Ox1Tdj6C4WrgBBx3oWN2Lo5BF0yB5TxtAJEpJlEGavVlLK2sbn +wOORQKJkFxVdkoz0FpQTtx3q8FKkyEe+Ohm2ILZ+JYIDaiO9HwXhbq9t6nhnfAVxwsbVfEo4BOIq +xIqye7xNDRhs/jvvKAVRhGd8co3J52GpGx+K9Skh51SPTxS5ulwv6pnu1d4lDPJRIXIl1yUpyBwc +iybQnCpdUxSlgnC5PdoAVCdNqSBU/phkMoj2sDEuaIxuBrs5XtVzG+WHplMJdhNmQg== + + + ag0MIkkGc35rxJgCu+GObYRekhLYDe+fyh848LRlUTYZROCaKrkhRRGaQYAUVteYMAXLd3liM/Hv +lZCP6nTWmNTk9KJViXN7JwF8CqUmiCnCvtVVog6VfXvALKmzbNYeuwydKQUOV9GdKEwCftuWTJq9 +4sSqhDW7sCgwnqUkxoEpml2qcXxnpRx4DTi+iRL+xSgIWuGhaXgQjLwpfZkDb31cGnGdykhBNPHz +p5gDrzqLYFYSRjAl508tji96UMLEyAmDMDsdNnY3hOiBO/nAIVO0NKYs8eo5Jgyw3sgxRZio+kFy +Gu0qjgkDv/5ct+cWJjqVRYn1EkgudbbsRcz30s1il3pTOm4pj5cTNYFpYGUQ7sgSTYz8Ax/8ZyS7 +ussqnD3W41Nw9hZl1c4ergFxjuIVTShdjQLmmb1VQx1U7qoZGhLK+wtj0kgvCwhxUw4y6GRD0hCV +hnHiLsReDiOnU4A5qzjyRAOSv/JEd+FeydiR8eNFKr+tcFLBct7JCE6SfyvawjsSrhJlKSkA5C60 +Dh4RdZLcza+wxypqVzy33rH22G9FW3gHD7MTZxBdzaelQqRBJ3Il8CKgMSIj6JIAjww65dcS/pDp +knAxK+9iMnwKqu2SfHa6MihOrkviuzs8ovgvBUm6R0TmCUVkbsxSA5awSUVEhj7jU4DnmOIeyy0R +GZ6//3R7RAY0YJPJ7tAAQ7smInOBFrw9IgNhaKKIDA6RqoTPC2qKyEjG+Z9UwHPUgXMgRA8sOGVJ +Vpe+B0t1EEJjucoZy/i8cTXGciDddhpVCIM8JnFXvU8mA5yXeMN6n6AOGFrcppDTqwaGdmUCO39/ +gQAyfHRJA3zsInVBEi2ohKvTnDR7maGKcHUq8/VkcXU86KgMUlg5CFqVvaSKt3p5tqVsqt7r5V2k +8DuVGx2DecclJt0HDwep3COnTh4Pp/3+sWvwcFJZ0K9/98bD3YCz0ICHk8tQvR8eDkatb1yBKvBw +EjeCYkFc1+PhBNlQzG+s98bDie8dpRBx98bDKd4ScBc8nODESkWq5XV4OLEvhjvWgUi225H1cIO7 +W04kaEqYE4mzLdXkRHa2qnIildb+cRW41QzIowSJ29HoqB2X0uyrbEcNjgTbCmWPoXbugOS6yGSQ +yYFX1mgQXIcPiF3mO/Nq2WAynq17x0XGs3WvMBGiRYiN9nQ7tyxDDnzEiyrcugxBY7LXykjpMewy +7O3ULkMZaxzyW5u/KClo97kNGLWjbflg8MignbsAIQtedbuYYjv4K4Ext2nh0qwvrwRWvA1NGJUW +3dZod13GsCD4TP5iJ0WHmkWk+gzXJojwxoy7WPgqROrYMFQBIlWJSB0bJmpCBgpQv7sgUj/390Gk +wnbugUiFeLHbEamwlXsgUmE76q6BFrnEUnl9aIHgL03VnGRkd9OzL1yG3ZuXoQgKJ63H7g2FQ/n8 +shk994DCSc7L3aFw18cthRyT9901+JU3QOH4dxAhMNy/AoWTiCr8C1A46fiYSv+sJ2cY8lUB//5k +OeDTEpurquZGeKE9lvcouEVqE71gUyFVEUUVAWTYGP5mO402zMUlw1oPF3ho9J7KIxy523mBKpfa +8jgqyuBmMa7uE3sdjnhzYKKjEtsDt35h1TiXFD16DlCJy9TLsrTujIcF4+xcJGOmzIBspV6LGe/J +CjQ/2UpHeqhseKFfPGSy5XDrKZ/zTPP5nLcKixC87ZjtyLwWdpmOOAmxWFKoM+gl0RilDzzuLNqI +v/LFSwh2S0xf6vzgM49oaOkwJ/VbHMIu2OvKgd1mXixRgmzl5BB25pef+hhHdCRDtOSO8YiKsVhx +55EXhROD3YLdZY2tTCiCgBlscmA3n0dEVFiPL/GHQ9iFjcZ9+PyJA7t9yKHO/uQRdttWC0vUUpsv +Zziic/l6fI0unmjx+aOEZa9pE0gMcUQbQoQdmlWwYOlRo0+0nMdVvpeQeo+KKgjeDH7WVLUYtL9S +79FbZy0sYYg+M15SijyvxRuqXOxYRcqt0IJ1bqixCM6IXi3b+0B7lDNUxVETfB2rvYou8c7FZDql +lJyqlOdBea/3rCQnVXZE4k4VFdEluUpymqJwHwXVKZIKaEh0J6SGvD6lInKyeX3q5UmhiBx2fFJ1 +35SKjagdn3KtAdVMV6ozIrpL7Yb6cerXS2mOL0SETXdVW4BOPtJ7DZruujiMVjSdlB/A1OK8H5pO +5f0wN6LppGKC4vVyO5pOCkt3LfIRj6aTisVLZ9rfgqYTsIVes5L3j92EppNqSuGGkCvQdFfuyBrR +dFLnNOxeeTc0nRSWju/v3wdNJ4WlU5nbowFNJxVrZyqw3w9NJzW7KNJ7VzSdlHHDzx29D5pOCkuH +uW3+BjTdZZeWRryldC2aTso41ZnvjaaTmj+JbKgb0XTiphRrCl+FpsPZlvdF06nn2C1oOlFT4jPx +O6HpruKYZjSdLMbqbmg6aWz1vdF0Ug0AKndG00mdlohy4O+AppNSD0Lv9R5oOoWTkTuh6ZT3l3ug +6aSYwVnj90LTKSG57oOmk8LSYevx3e4AujkHUFBfTNPVTfgqXpdFKsW1OVQCn/YKi13A/OAWV8vm ++np1F106wVOee9erw1sX6vh0clo18YnjkiATEmIyFQ0LlSIgAChgUM+4Tom6pFYVqKguJzyYuqpL +kGOgU5rKLst1STqRAqthZPgkU3YZozLhLib0iNK+p6PIIwqYYjuFwubykTm2WpZcobuby9zx7rlS +aZJfU+YOW12uqgqrpLLMHQ7JpQ5IpypBQj4/mSt0d9tclXo7NVVmZKNUqsrcKUYUIWNuLnNH2zDy +he5uLnNHYd8UCt2pOzzaVe9wz1Ug3fbJT6J6nEX1bilKuypncl+N5QFDe7SrlU/sKQ8sUKeYe6gk +nxBGB51n2Qi8KiCdmoxmnTLCEJ/EoRpfCKjIpB1qSCKD3MGG/oSSrK7CFqBstIrxRPDSVOyYpe6G +wp33lF7/rgR2CbKhgFAp5IOrzoYCTSnmj6nOhgKNqcvolk9sRrrvLsjH249CYEVBmevA6dlX2Y6q +2q5SrfAyu97usQJRKxdIdkmksDKWHTWmCliLqwEhBta+bS6BtW+b+90KCBu7SyFjJGOgt2qUGX/v +wrKyJcVKxXqvcjnUjssjXYjEu8yglvXEcTnU8+PqLsgU9uZj7ZbEZVO1870qGIIHr/gjYtVrv62p +UDXu9A0WXrvZnKBakcvq1NDOHW4JoNq5tVo11QqzCKVuONSWq9pWAWTQdMJrd0osw44KIIOqCPzN +Fe4YfCWuxt0Vy1AiueLautXaKtzJIR9vWIaMoNEV7u5SKU8RT6SuUt6teCK2Ut7ty1Cmwp0Ql6QG +H3JNhTu5eq+wxp32CndqbzWH6KfbgbWfe87MwXmvqoG1oDFlM0enxtChatNdB6wVIx9Dt8aPIL6w +LgmH1nbPFWrnCr15cUcEbOcueM46oc4XU2wHj4UVgZh0StdMoHJ5WvDtUiAm/qkoVBCui2UYtylM +hIq4FlP3TSWMSQ2Iyfo4EHuivF1MDYxJOEiF2CnXFDsvWBhT3KYKoS7rtrOrMm5TsyrVgJisjxux +8X2tX9nVBGLCZRDB2okyO602w7BLY3hvuJVfZBhKXJbY7VE1IO6Bcc178LeKQf9Fa0U6TeUeESvx +9ljvfldT9dDp250wrj3s1VTabZjJUVO5R4VKed4rMa689cmmYahAPStjXEGXVKOe5TCudAQITkQt +Ik2PMf0g4q382CqsfPmc9+m9YJw/venMhbTzrfW4HTnD4FPpFaH7yO4nOfNbU4YCtfGg0C4vdkx/ +EoDwntNNPlEBHk5nPho7vVd+qEpYhy2e/+hh8HB2PAjvcB7FfUKdLILhEQ4c9i9sNEWa9i8cCO8T +SxSMxUDuAtixEiVjv40laq1MPAtcHTY7R5RFcnEMfg35eUSF0LSjNWLh6ggGRChHuy39sZYiqjND +BotrzglgeGMx9o/P3mryFUM0bDQHnwsjLgYrRsQNZYiWTGE80VLD2Jciiuq+RcsCaKWYaFOujmC1 +gydaLLZJQWYXIGuCz13sJxqEeXY8eoWzj3kvkCew7/HxlcTIEc+qaNEZ356K3DYJxtwLio1O9rCG +jvYIN8+8TJyY3ehUpk0Cpobs6DRIUMVMOXFSxd4M2n4UA5sUIyR4SNJlahW2S1CS8Z3Kq4E2KQOb +jveqzIICugqVWdRGkgryqVXYqbuozAIIvGlJQZND3YlunrwBlaaQoUlxSadOnkSHXlrHx0atIe5O +c5VFTJcusrTE60U10zVlaenMcp3Cx4m1dQloS3yeFt2fi9xYkboqfqYcwsPr4mXNlOtcCdB2RcXV +1wox2EHxXpc39tx6dTccqkAjyYaX1Z7yDIq33ETLYRIvroy7CuwmfWSt6V7rQfHKyLLwFk2IArz1 +Elqpu+KweDElr+XyrjgZB0g6PiZMGpE4Yh2Tmuod4DUMeTcfeUyKNcy1p94U4A63jtGJlXL5OkHP +xHF+5ZAdqseHjaoE9xcJBKvoQbs9gqn9ZH3s4g8HtQHJLupZ3FCWTR7JpAljFdN0zwGvSyL8y6wk +FztWtMYFXeKl6tOn1bxVqxEKuDKpgHLy77mSgQIqlTRWmD/u5H1WUgbqqBYGUV1jySozGhpTqqJj +FaNrZRoT7Sq3cUwRy6N+kMKTyxs5plhPRxPHasFPTGMXcGEp65Dm2JUoQLUYQNX3kOAAYqowgDLZ +6SpQgGoxgJfxZC0oQLUYQP4Nh9pRgGoxgChqfTUKUCAqMh6mOA9WGwpQLQYQcux6FCDHT3m9IcRY +aUUBqsUAsj7yVShATJcuMID880qqP5ejur0on/qKbLcU5eON5V8syncRVfhXivIpVWS7T1E+CjMi +b6DcXpRPZ5awCu9elO+yPvK/UZQPXx/5nkX5VNWvvKUoHz+qADsVxnaKZpESNBhf1e/2u6Ge7nE3 +lMq6fqruhrq5rh9vaHe4GwpX109bntK1df3kq/pddTeURF0/+aiQtCeuva6ftPDJ3g11RV0/ZUm+ +R10/+cwQNnJ1Y10/JSTXnQK6slX9dGZNAV1sXT/5oYliF1fX9RN05KKq3xUVQCTr+skPSCpD9Zq6 +fpJwRLlbzdUzRjVSVvIu6Cvq+snf/MWeid9Y1092o8ujXewOdf3kw8KabqCSqesn7+pKZkFfUddP +CibJLb3b6vHdAfOuqa6ffCswzn+Pun7yByo61e3cAnwXI1KvresnYWryqvrxqzMQN9T1Ey1DQljV +T3Bnl2Z4CsHW9VPEvd6lrp98VT9Wkm+s6yefcM1DpN5U14/Db0nJouieq6vr+skzEFmwd6jrJ7PW +jqvAnerxOeRbUV2PT6GcnOp6fDfV9WNbkVw+WtEcF3X9ZHAPitm2c611/eQteXjjwT3q+uH28M7l +SeJ1+C0V5jxzkqi0DJXq+smfNwuzCK6v6yfktthbvLYen7YkDXw9vjssH7aq3+31+A== + + + 1ICYlG5vuMzV0FaKT4xIva2unyCwfVHVj0IM3V7Xj4VKydUVvbmun7yZg5ExzXX95Kv63XxrE13X +78ZYn8q6fipwr3eo6ydf1U9zPb6rULgibXlZ1+96MDyvqh+Pyk11/S5DyfyqfrhbzrTW9ZNP7xLt +YlfX9ZNPdBLFlK6u6ycxL7yqfvL3wqmv63d93FLIMe2YJ4xfeUNdP05xSVX1uzp7UFTXT1YieBVA +bqvrJ28YUt7r7XX95AGx9I58c10/4SDFVf0u7DHVN1kJ6/rhjSDKhlG4yUplXT9VNszNdf34M3l5 +gCODrsWsT+m6fvKbgyyK826AWGrf90psD305G+2lLZ3xIb5XakndqCjaK8G3+NCufOK9CLYokCZG +xrjTm9Tjjo+Dp2JTNCmbYIf0bDnGEN6XeZjl57PAE60dIfbNf1zqwbbypHd+PJsIb3cVoV6CeCq9 +qZ6qeAjbRu+dfuyCgcPyiUytv2KNtsPm/rNbc/scUV48Z437cy6s/xzPAuDTKGMORRNlS/1l3wzt +V70PnTkS8gSn0TrZ9VQ9B32oVgqOcs1VOz17q4ffl635c2jfsc2/Te9Ze7Dwa2g1q6v4OtndztO2 +zX4Y2ZsPmU34Wf/+nLaaArZS2Pz9UanYz0vjR3D7OY/Tax9hO1Pt1ltH73EOMnr/Yt9xJgPWDEHm +qjmC/J4+EaWwpXk4jGK2wzH6XjkaB+HJMTT5eGWRli3no9f97gnUYgYG9vbrPRw/t7DYXMxIYasv +dYgAX5ro14ax7LSxgw41WwIS1pM8j3xmRzZTe5JiFmIGGO7JAuclYNJjx4oQjbaxdf5q7PRbKdPm +4CUt/uDibFzP9DOIJH1iwKH6s2sXfIb5avUNwiTqs2SrZSZM8xny91+3QpN9J1o+YGiveR5ojou3 +8oYG1JoUH1Jhc/6sMxf65LyLCmjmv0rNbvg5PzNkvKfkU8Z7nCXImHH1WnzPBAaAbZtUad3pfmbL +Yf0EtNPZM81S5TNtPucqAqGMvUEmUdMf0Kiyf1soydnq+/vQWex0y/ATGPDr2gNBuy7KrU+Fegfk +ORHekw1mIwxPlCb2hjxW5pPPhmLHgCORDfgz4kCoX6BwKjvw56MLaRijFexiHwfwRd7D/JD0kkV/ +PQqaLRPOgst8Jm3lSsXnsi7/itPVPkZ4UxE76ijs3JfPkfcl8j9jrw88eHTyHoxN+UedmXmUd3OP +/Ll+O808qLD0qnx6blNlyTDm2Q5UxnblK9UMY/Y7J/eyzuwrDTxT9pGb105pFyfgd17aPgo9ExBl +9Ocrh2t++KefansyMLNtN5zUK5OdD1roDTcvBmvyW1M2mG7V8FAvTcN52E6DgMlhB9+0/IL+pJud +9j989Fz1SKe3/rYKgKctF3rqt4fjM4Zoy8NQIeymKOFfv5mLrpgdSAfRMfH9/ZGNPpajhOEifkSH +fECLXkrYJdoT5o2rb5HgtejzGo9JZztxCKfaweds5Gtmg6su57f33/RIVCDHeh9+duJHAVMyOSKH +9o+q336erZihv7u4CfMXyo9Qpt89FIsK/YoPbuQmf2H6EqI/rdt++tP5Y0Dblv6ifTykP/kXIdhE +iGpi2M/AFvseiNfY+ofrGkH9enhu0m2P7F1W2vp+Xm9GidkveoA41g+yq3LCG8voXZ+HO00Cpik0 +c2vPwpF9nX7XCtWK/o1TJOxhTp4NDlh4MQfuJDEXMJ8rc6Y/X140jIDF3w6i3gYsiY8Q/akw/mHf +C9Dvdf6y4t685FtfZGFtmGabrU+rzlycuDPvcLNOonw2eu2fdmFqLQpNB+EhsEWgN1m1dqk3mV0M +ak6R3ox/vWxtxfdc/SlnXx/gJQXhcq5IeFqXelNcdtiKBg7UWhRdUWtnz/iA+qeH0V05qVnNdQdH +wrsyeLw/hldLwBT7OxGEzXOk9RjQligRHMVbwZ9BO4I5+4qfGfhn3OkDO0cKKkLoIzMT/wl+04Eq +pexBdh1MvfGgSARUQjDSUPZiYkplQmL24YOqDea+7iHOgtiMmAmtOigd4sqbJ+x3Lvq7tg/KdBXI +RqRTzo9W2ZlAq9YIIjSpwomo+vjaMLcPIzt58QJ1HyDQ26KtBQ79Mwu/8zHmWS1Cc6JEutErwJNr +7sGfNS/TNtSlsDdAl3LKmtJ8YCxApbpVixJl4V2cMNDRFXGBWlTQ+tH7S8f5kaARc0PIy5mV6Dt4 +a0GDmJk3BfD6wck3c1ATyfQbr4HKp8sjbGCZag8dVF5f8wQNzLbgIonaEX5nBN9Fz5SVaen7n3im +NmV2JV+KbAONywbOVANgLFQTZUuZb/UCmXfCGxHQHABD/NkP4a1gY3KVnfCTh/3Oy34H5sX1tof2 +wYESdiD2fd4uZuFsL1gze8SYWI9+xroCRtnE1PwEBkOwJK4ZTW8YcEDUdRMxPVc7GtYi11M3UfSQ +nUnX7V63n/k+CNg66XnJ2atO5m6L8pfH8NsGI3CSgKjHjZb15aUXNMKX4Vgg8rKirV7/2ccZvKhY +OHQbDExveHeAOHgs+DgEJrwrSFgW2PP92QAh7BATPG4BExC4jmLCgM8E/6KBmAAf9PksEJUuByue +YwFXT1zIhHHymWNC4GPti/KKWX0dJx4+Udrw/8KyQFy32sNJf1e/9RYpJhxyvQ91coCu5keCfdZz +LNCZ9cHjh4VlQldGDuCFpQwXP6VECdsAl6fU28lLo5Iswigxrg9wvagZxvBw5TCYCAkKR9w2jKXk +bHBzQa1KuWG8fu5uk+nX4Z7VlqIm1HECNDE/yg8DNOAwIUlmmkjn91tBE1u9ch9ktdPBgBpAHOv9 +cU0Q5Xpvyn+z98nKb4838QT5VRbGXF7/bpYxdB34bTI2P93SBGhgrb9ZxjqbG2Wst8XJmOomJgdl +AekLZOxiGMsbWfm6OnMydl0TvaGK5dploj3STUzwuk9dH+Y8VlIc0zobvaXyiuf3AYzloherG2ej +tzmLWMlwTP0wDgprQ6oPAmxCqnc23CbYfaNReUf2Hz+5JvTWzvKN38Rkcu0ewO7Ik/leiRMKfVhi +1ifoA09bynFisjreqi0nm5OKnUhmH5rsz/J9UNaWk7Oe/+fUaBD8aTEykc4y5UPCY7kYL+xt+3AE +wey7hrOu3rXf1fSueveFMgLBb7hIWRd6fGGea4byKeanTBTZpWwMZ8DzJsemv08qAmJ97IUo3Cv0 +uocu6Ku4mWjl5xH+yQbgylb2k41y7ObHFbTGy5S/Cw/+Xcjrpv/MezyUu83k9EIPm3XHA+nOLse4 +vUEbG0y084OXsRMb3Ks6+Q9qTjZsWHULIoquQYQNwVQ5el8BU2KRZei9+DjG0CGK0qOD+44fHS3l +XbwHguhoqeKBwSEH4N2nk/K1v46/QHZKTR/6M5Bu68Gfrxmu7SEdtnglEbcdwF+Y55BbAM9poJdQ +iwKr/eUA18vrixfGNlyAwN4E/myjZh1USMT7+hFgI5NOZ8qYNMKnTkDAA4yWXo0L3Y4YKiPA43Df +XfCOk5b4YmNt68xkshj85YXXqeB7qdvgH78zZ/DsaVEM9HGTl2pRqj0qT0mhReamS9Si/SnaiEVL +ZMY6bxUqs0c97VX3uj5GVFr8gJ99PQR7JR0h6o2D7NDHgMopRk/Y5AWFRFx0eH3S9tJB3kmX8E1q +FTv49OGj41GTgT8Vq/jBXE3GAebTLEhF4F301K6aqEU3OiIHf3aZoNzqg2A+DThpm/it6VqK7s1q +FuA9GOgDQzouWd+b2bGs/sLIawvkooFoYj6wf+eXYfIlt44ao1KRFmpA3D9UxjYXqjl1PSzRKcq4 +g8JyGhC+ki9jA5/GPubTjAsBT+kg0uk3eNGb0KlDOuypRKTjNtTJUd0co4KhluExQjyVnCG09r/C +9FrsEkbkpMrHB7VHB1mOaYgPao8OSt3XpxQf1B4dhBzTGh/UHh2kJFlbfJAfHcz+T0oX9UV8D+gf +b/O8nh9eDj+Ln82DS5fQebMVn6+9mW3Jw3zemv+vU2E7Pf/NN6eH+IM3+5avVKKhwny6nc0fUDJT +aBRh1YabllZavvlH2oIQIwqW5wrfsdKqbGw+jgvfRC/FWxaUlbJr7fWu5W8ZbKjOqQftqh96l598 +09vKRxf8s0ft8hSTJA9WkVZyGAvzQ+5cdNZr76JTAhSMiY1aJbA9FN9z82bGe1wkveVsv1rok523 +jPdEbJmAIDzPFGQP8E69JQ7JgSFzsujtyeeg3u21duBheQGMxVSIevUueyYDv33SOxuGZzi+Z/gg +rXdnAzNoNZT1jr0RmGXjfZSvKix+J73kuK2OHA6Z6X7dIjWro86Pfa7FIoWODWh9CZcfOslglp8X +/QlTGm30p985Mg7stDVg3cMSMmUn/Wfc5qYMGSroDG+IoZv4bsdPzEquENzpI1+PazjK5A4ydWbs +USb34GYzgToGHvBp/wtmAkrLow2Ff89M0Jnlt/X7mAlUaFt1i1eaCcDQYQ2Ff89MgIYOYyj8e2YC +GAtrKPx7ZgJvvUz/PTNBZ+YMBbGZIJ8RQmch1uK4zYFW/44v8gxdqeUvcKU6gyJQiu9dvf25b6P1 +5jn+ClVqGejSdEtv/1mn9O5N4xPq0hjcF0xi94qasMceperAosna0ILjDjXfdvRL472bSfwI2rjE +DzZXw0p5f0BbOmltCU9YeNqS3sqtfmtG/4WmHWrLvMeFbp/2f52TFe9P9+ShDI8fV9yJ0raAHis+ +SYHOgd/1XBXNPnzQBlQiB061Unrsi14CIr2KslGASoU9s8HjjFVubdiQQueL4GwYvrNXituhbNSR +MYIM0Ch1mu8rtW1R1oqhTaLSIgg59uyhLRJTxlt4Sm4J0M4LQSlPnsYutf1oIsA/Th6qh01j5U4i +gTLndl8kiBcADfb8X1RSlUpLKw5CosNBLi2POl90888Xp9Gq6HxRrz/Z2PjZ8fXifDHoKHmC5Sxz +3Pa4ZUo3CQ5C3XXuKMhvi/UCgoPQsFFvzpkKTBNTy8VJas7La8BHdks+dOBLJzTQyx5IOjLZvT+p +dhEZB1DQUkjOme86e+a73sH787JxcokWSOQE5j4dWhGGHdWG/JAKgwOizz3p6/UdmXfHmDmCRHY0 +ffqmM4sPIdGt6NcfQdqlTt9gSEj1+Zvv5lDdKrpjmJAJ8JiAToVpJgS9HBNgb1a8I0h0kx6OBUwI +NR1fbRgmOERHkO4bj6IfT9zxvPqwK08O0vHXk4qjaDrFUOowmgYWU1xE58dSoiRzmk1DIkEDYPZV +SuNFE6iom7o+UKk5l02gglS3DAMl8DNLinekrWEY7bhXU2LA5ap0xU6OW2QautROUQM0x9RyAnrg +bqVhXB7t80EyPtcuT0gOQyUrYQqlDzVwNJTKOSdbykNnhgkPe96bwO2302+Svz6nRNEPWs7HQ+uN +MgYMFNttMlYLergGsDIm28QgQ9wqY9al7TYZIzZ2jIypbqLmdCkKCL8BNAihjA0ing== + + + W2YD+POPXqkGgIypbaJUMygvV+kG6DRWaPCp1n3SfRh4pFkJ+4AuJVecDWBgKq54uT7AJOZd/LbZ +gFatPCvR/iI3jLKb1LY2LvoQrvmgNX7D2iinm36FPhxSXh9vRy4HT552ktfEZGC+bQ+YLJxOZkeW +7YVMH3Y+vFCJ+kCvfXEvpqaI+yaJmLofPbclmcEEd8klju0Dqy1RwmfIZ0NGIld/DJGPuvXTYCHt +HHYL53Gplv96ihnpkEEow0SSqBD/058wT52CTujMUuCJe0MnIJVL8IRm6AQbDpU+lkTzoupgUnws +yXuwyy/YB6KYPgygPsOoAu/bto09Nnh28R8sgiwmAXrLwEuCeoVKmYfqAUoyOgfYopUK/2w4BEen +YO1A3jZo1xsIcZz2Nlx1dD6eg3IJRanhpUEU6QpkW4Nudtpoo2YDvChjeXigD5jt7iBljbfc/IO7 +dCahOQn/4hCG9eL99jKZpLyku7XYqD1yZw2h06tpXvrqRxc6c/btbPop9mev8OSo5ePk1/91HmTo +mERvEGBDkUE+YCIdYUXl3U2jJhp5qFfevYzYvxMooeELupzvPia69I5OCeBpwnuA/RSkmigm/sLg +zz7d4nCKJr7PHuP3CfaTjz/78E5xFpPQD/CxFIWViYky/oaYsfTDWJSKE4dR0dEXnHB4FT5K5cvD +EQ1Y7C+QqV/gn947jD58+dhPfv579UUQfhfkegPWPtOfBjnq9PIFZ9ROksV6J8oEN/9CxHwSD0MJ +9bBxij6Fgvz/sb7/a2N92/9J6RJgMBWfb1jczPhnjjqzGXzzNj+dd/CF0DA3X/xsauN/5ged74H6 +HwH+B/+NxB58/uiDPxQCf4Tgt7WJzobeffDZH2pgdxl6s4dT4Wd6+tluxod/HuLwq2691q4UHuIP +1LtD8G7iwQZ6QwzB2+CRHR50DkEPhzriIQv+3/2v7gz+86IjPJEQ4QfEPeFILBwNoA+E3+8HH2KE +LxxEnQM/GOsIuqfgj3/AH0/gwy/46r8PPuKh/vDxRTzMwIi6TV0g9uAG3/2hD7GHNfpvxBPyx8AA +A1FPyBcLgS8eAhH471QXgP9Z63yeYAR2Bfzho94nCD/8GAPv+FCTa/RfnycUjEUffPQbbp//IYD+ +BU1F0AdAEpChnsSoX9CfCPDSt64tzUiaQWAIaJQzXfjBZn/ovoOv2TFRH+GoqE8y4wIvUCMzD2XH +Bh7To6M+yYwPNMmMEHyUGaN5iBEWNEYfkI7NdvMQDMTQ+DTLAjvP4HVqnv0EPdG+KORIlGOIL4o4 +Av6Dphr8lzfX4C8f/Rv4wU9Qcw0eobn2+0W88AcgL8C/1FyDD8xcwycx6heQLN2562cbjYz+SLDT +LTs6NOFofLwZlxohmmc0RuqTzCipGUfjZGYcN9L/U3Me8NNzHvDRc+6PQa4EOK74Y4gr/hg15/4Y +f87BXz7qN/BdH2oHzXrAT816ICDiRyAI+QH+pWYdfGBmHT6JUb9geBHw3zDraGz0Rx8767LjQ7Pu +jwlnXXqMaLYDfmbe5cZJzTsaKTPvuLFqm/dajtqHwK6Edgs3sI3Nr+PFvHUY/6zBrrQ4jv8zfxhv +NtvT+DTfgScPi8P8eNoe5g/H5fa/8BvwE+Z1sL+9kLr/DTBb8Rk= + + + diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/hamburger_dark.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/hamburger_dark.svg new file mode 100755 index 0000000..e698e19 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/hamburger_dark.svg @@ -0,0 +1,1935 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + eJzsvemSJLmRJvgE9g6+P1qEHJkKGgCDAcYdWZHwOHo4Q3aXkOxjpWWkJJkVTeZ0HiVZWeRyn371 ++1QVgLl7ZEUeRVK2K1CVEa4Og5nhUOjxqeLv/o8vf/PF9ddvfvfwRbqaD9Pf/d3N24dn7968/fmB +1MMvXr787tt3b0H6ya9/egjr1SyVrn9Rv7KK//zw9tsXb17/nF9dJfnyHlf/5BffPvvdw8uXD4df +Pnv99bs/PHv58Panh5/8VL7/7Yt3Lx+kxh+evfrdd29///D26ts//v6nfmtp6/bZO/l++Vn8WUiH ++PM5Hr78Fb5+9vqPz7799sX/+4CbpYp7Hd989/rrF69/f3zz/wjx8EXKh7Qdvijy1X9/8euHb9/z +/e2b59+9enj97su3b54/fPvtzZuXb95++/PDzZ+fvT786tnv5Ztnh/9b3uDNnw7Hl8+e/8ckb52/ +un/x8kFe8NWzd4cQ0RfXvwjxq+N3L15+/Q/fvfrdg7z6upGcvmKT//SttCXN4m+Qy1e/eCWU3zy8 +eyfPJTdEf/7674/jYwiR5Sf/9uuH379g90u3/K+fWrNv33zz6tnb/8C1hy+W+SD/2R1/+/Dqm5fS +e3zdOF/lwxf8t/9p9eQtWOeLuFbplbIe0lwPKVf9vvfNwx9fPPzp54d/ePP6QTvg+u273+gQLMs8 +67/6za+/kzH+p9cv3smDrSBt2gO/evP1w0up366/f/mML84S+r9a4bfPZE68k7F78/K7d5xZ1e8g +PfzLZ39+wDAFvcE/fvPw+rdv/pnP+EUM0k7crrZDXOSNQtyWQ6hsP+JRt7ndM/R/tWk0hGa8fcyQ +L2Wc/vHti9+/eP3zL1KVvk5x1iH8+7cvvu4jGA7V/pfGr+rw/+b/69PKi7979/Danl7mzc2vhnkw +X/3qN3LXu9df37x5hd7/FhNcJsBrmRsv3/xev2t/8xu5/Ltv9A34+SsZqC/fvniNNqd/4Df1qy9f +fidf/f3bN99984vX//5m+oku7X9+eC7rV8by68M//u5/ywdZn5ybh9++ffZcGpDPrc7Vsxff/PS9 +zcnLvX046JdyJT/67++/+vbh32VV9cuVevf6jw8v33wzNNsowlUO//Ls7Tff3/SXL5+9fvb2QHpr ++Zcv/ijfPJOe6m132hMalVnyjXQOL2GVkxu8p8Lw1RNu9OzdH4QBPbz++tvWtn7cP7jSvr+93zzH +HHx7OL797ts/HH775s3L1uz+q9a6kUlF/b+Ne3zJC17/42vtoPM7WYXTOwn/+Zu7i9R+/A7y5d9y +6zfPXr588fu3z775w4vnl25w4ft2J/3uQybWn1/97s3LF9++6vNpoHz57O27F89fPvzmz9++e3j1 +5ME93H39QpjcI8v4vXV+86dn757/4Zcvfvf22dsXD+9dfRiAf3/x+muZ+7/57sW7h95Bb159Aynl +8Js/PPvmga/x7g/3rPmb1mD+Slj/yNy/+OI9XD+sh+Pr4fu/f/vs6xeyoYjQ9fdvXn798Prwa7D3 +afdJtq9yOH49/ds0Wwksy+Hvvjq+nf7bNJ/+hJMSh5KsLFYy//ey4v9Jfo2ltFLnbVeuh3KUcmPl +dih38/0033vZPdj4E4eShrLsStYy8VcJq5TC33Uo265ch2MrN60cw60U/3Q7yYc7km7D/VjGruPD ++U8ayjKUHFeUSX/FMpQaNyn67/VQjlqm/+vSWD42mmk3nsswqn1spUxteJdhkHVUx9GtUvAbo1p3 +47sNIyz/TjbUPtjHNsz6G6N8N462/Ks/88WxjtNuoJOMK35jZDHGK0vlKJeTEb62sh9bGUv8umO5 +PRlFv2niGPYxQ9FB8iHbbLBkgCYbI4zVjZVbljsr9yi+svAy41gGjtJiHV/ZoUcuknv2TeTLr3y9 +ja9yyycO9oQrp4w8wsT74j4xpbSkNRVRtrZ0lHKb7mW0w5KWZclLWeqyLdfLcbld7pZ76ciYU17y +mkve8nU+5pt8l+8neaAgs3RZ87qudd3W6/W43qy3673MhSDdsJRc1lLLVo7lptyWe5knoca61FzX +WupWr+ux3ta7ei/zJU5b2pZN2tnqtm3H7Wa72+5l0oTrdL1c5+v1ul5v19fXRyk317fXd5xJUV5g +OeZjOdbjJl8djzfHu+O9zK4wsbfTzXKTb+QBbrab65vjzc3N7c29TLbAUVhu8+16Kw93W2+32+Pt +ze3d7f3dLOOS7pa79a7c1bvtTu51d3N3O93d3d1jRtxLh93ne3nTe3n2+2spcst7ufL+5EfGcpbR +bJ/vhnI7lJuhHHfleiibl0n+qUMpQ1l3JQ9lGUoaikzA6T62MrKwznzn8dHvxp/bXbnRMvHXcSjX +Q9l2pQ6lDGUdSp7ucivLrqShxKGEocxj0S6frO/Hpx9/boZy1MKVuRvH/ejtx8xHaz9E+2GRoZiG +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 +5+8WHNujgn37Jvf02foBF49O17EtRgdL6PPOr2X3eTnApGRT1pjj5tvyKZydOhfd8sG4HeMKh/VO +7013OIJF5f3+3OsnvTc1vMU23l1vVJ8w217gxTs3bjan2vPDR86ahVpD/2JkTVDjJsJv+qe1Z/an +yOaVZeNGuLhUMMvf2+8wpQ+OD548yfVhiTMCf1R/efbHf3725Y9ffXK/+fLzb9I/Pqvvfz14fP76 +i1e9333z6Hef3/3koNNsDP9gvv/rQ/P7L77+/vGfn6q/fHH0r0+efj24bGWPHsqn+R2h1O+TZHj4 +8+Grz5M/fH3/340/ff3l5xfDr4d/k/f27nx9/+h3Ay70zWj/1V//fvT1l6o8Puh89efWYaPxyaup +po7a/4D2ssNHd77I/vvx6PDnn/bVf9c/f3DePxrC4I5ef/Zn8/vLR4fqDz/u/9z95Me9O4dnyTen +M5H9ISvOsh/+/s9/PfjuoPHD/Ebjcl/89PWXbx799PUXw8b5Z4ef37l8dPdx+2zvDjHr0f+cPLs8 +PPvpx2y/+3X35Rdn+69HB6+z/xZj7PifPx62xNF/vv7yL5/8aPFAl4cH/3717z58+uN/Dp+0n/xu +v57//IcHx/Xf92wfXjbbl3t3ip/vftZ62NJ/v3vwWp3c//LBnfSPn+1/+/n/fPb1wSffPzooL//0 +5x+++f3r+61W8w1+6nz28OzotW1ZJPea2aDzh//5ovPvb9r73Tt/+aQ++Oxflw+Ojv/4H+z/p1/f +/+Z1unfH3P/hp68f9FqfnH/21dP797Lzf33VybJ7w7P0waD1RHz25gvhMbYOvxn+AGzLPimzH9Ok +/UXn4F4Txlc8/epu/fNyv5s9P7cU/OPoztcHT778/Y8PPy/0EMblyT/N7/+cHfT//dmXP7T/+YU8 +/f1PhPbPvTtA0J/Nn36PQ/JP86P5ew/59Of9N5+aupuaP7SPEvHT758e3mt++cdHv/vsvwfYisEf +/k1YqMjeneT0/z5R9PmzPz/60n368seHf7PFDz5/+D8WmfyHfAJT92Xy2Z///PBzefiXV185PD9+ +9eX99s/f/ptG0ncY8D3b164VKLT/je/AT6ED4u5XL7BQqQimf7d/eEKsPiyHf1Hmv83PrQffHf78 +2eHZvb/952Gz+ckf9s3p938vnt95+f2DZwf7zw/Pjjv/+fo/P33xau/O/2/vy7fTZ3IFn4B3CPsO +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 +wknerg== + + + diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/hamburger_light.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/hamburger_light.svg new file mode 100755 index 0000000..27a1290 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/hamburger_light.svg @@ -0,0 +1,1936 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + eJzsvemOJMmRJvgE9g6+PxogB1NBU1PTw7iDBcLj6OEs2V1gsad70RgUklnRZG7nUcjKai736Ve+ +T0RU1dw9siKPIontCq3KCBdXUzPTQ1SOT0T/7n/78qsvrr958/uHL+LVfJj+7u9u3j48e/fm7S8P +pB5+9fLl99+9ewvSz37780PIV7NUuv5V/doq/s+Ht9+9ePP6l/zqKsqX97j6Z7/67tnvH16+fDj8 ++tnrb9798dnLh7c/P/zs5/L97168e/kgNf747NXvv3/7h4e3X7988Yc/vrt69uLnfn9p8PbZO6m0 +/mL5RYiH5ZfzevjyN/j62ev/ePbddy/+3wfcMVbc8Pjm+9ffvHj9h+Ob/0eIhy9iOsTt8EWRr/77 +i98+fPee72/fPP/+1cPrd1++ffP84bvvbt68fPP2u18ebv787PXhN8/+IN88O/xf8hpv/nQ4vnz2 +/N8nefX09f2Llw/ylq+evTuEBR1y/auwfH38/sXLb/7h+1e/f5D3zxvJ8Ws2+U/fSVvSLP4GuXz9 +q1dC+erh3Tt5LrkhOvW3f38cH0OILD/7198+/OEFx0C65X/93Jp9++bbV8/e/juuPXyxzgf5z+74 +u4dX376U3uPrLvNVOnzBf/ufVk/egnW+WHKVXin5EOd6iKnq971vHv7jxcOffnn4hzevH7QDrt++ ++0qHYF3nWf/Vb377vQz0P71+8U4eLIO0aQ/85s03Dy+lfrv+/uUzvjhL6P9qhd89k4nxTsbuzcvv +33F6Vb+D9PCvn/35AcMU9Ab/+O3D69+9+Z98xi+WIO0s29V2WFZ5o7Bs6yFUtr/gUbe53TP0f7Vp +NIRmvH3MkC9lnP7x7Ys/vHj9yy9ilb6Oy6xD+PdvX3zTRzAcqv0vjV/V4f/N/9enlRd/9+7htT29 +zJub3wzzYL76zVdy17vX39y8eYXe/w4TXCbAa5kbL9/8Qb9rf/Mbufz7b/UN+PlrGagv3754jTan +f+A39esvX34vX/392zfff/ur1//2ZvqZru//+fBcFrGM5TeHf/z9/y0fZJFybh5+9/bZc2lAPrc6 +skS//fl7m5OXe/tw0C/lSn703z989e3Dv8mq6pcr9e71fzy8fPPt0GyjCGs5/POzt9/+cNNfvnz2 ++tnbA+mt5V+/+A/55pn0VG+7057QqMySb6VzeAmrnNzgPRWGr55wo2fv/igM6OH1N9+1tvXj/sGV +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 +8xm/zlGv8eucwWv86lmK7Pe2LO38fNRjvM/gMp+zPUe9ruvrPfhZQyXmECh9Pt0czCFP+XQQTBeV +X8g9uB/ja3A/5nMZ56jXBZ8zeN0czHgDgcTXtuT9r09HPcbX4znm61Huo94P/cs98M25nts9V1/P ++MzV52245urLeM/Vl/nM1eeo11x9zuA1V59nfG+734b7qMd4n8FlPmd7vY/nur7egy9vzuvmXM/4 +cmT223A7Msf4cmSO+VzGOep1wecMXjfnPON72/023Ec9xtfjOebrUZ738XroX+7Bz589kMY+Fu2z +BxLml1fRmGL/5JZgtpEe4222IO99VJYurff8H8ZPHsi97fYq7qMe4+sMjvk623PU67q+3IO/+zR5 +pt7XfT2OwvX7x6W4zvQy3ld1mc8duI567tV1Bvd9PY7Cve12Ke6jHuPrDI75Ottz1Ou6vtyD7zJN +ntn3dWuPr3CdwvEqrpO9jPeFXeZzE66jntt1ncF9a4+vcG+7vYr7qMf4OoNjvs72HPW6ri/34O/+ +yp7PAJ/OKF+GgjC/Pu+OUhV7BMfYBQP5NBTgUPUZ76GAzSxSfX+IYfw0FNzb7s/7Pg== + + + 6jG+zuCYr7M9R72u68s9+M6LkdetPd/tdQrnC79O9jLeF3aZz024jnpu13UG96093+297f7C76Me +4+sMjvk623PU67q+3IPvuRh53dfz0V6/fz7v60wv431Vl/ncgeuo515dZ3Df1/PR3tvuz/s+6jG+ +zuCYr7M9R72u68s98NQOshASOJ/8niF8/ifnyQr3t5t1jC+X7JiPh3KOevky5wxefs/XE3M4ZHxx +73nY8mntwxPQttdq4hhfK49jPo74Oerlso8vnv3rdHCK/1yh1n/4+z9/BVr/U+Kv5e8Wf/Ud+xSE +PbFWvGF/xBj7/vTlaCcU+3cOFuLd7Vq9U/lSztyRGesLs+cDECu9zk7tkxFr8trO3GEz1u+jfnsf +tSn9/z4DG/fcscb4tO2Q0vt91GN8ncExX2d7jnpd15d78N3mDvz7p1tLb6J8OgX6HXyxr5O9jPeF +XeZzE66jntt1ncF9a5t1tu9tp4Rq76Me4+sMjvk623PU67q+3IPvMnewauPTfeVp50+vLC+wfHpl +L+N9VZf53IHrqOdeXWdw31f8RO3907bTUobXUY/xdQbHfJ3tOep1XV/uwXcLZKEyyqNnWSccwRaB +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 +3x/Wu/nN/nv9H/gN+An3OrCRH2jT/wGF4u/k + + + diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg.png new file mode 100755 index 0000000..f619677 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg2x.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg2x.png new file mode 100755 index 0000000..57663ca Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg2x.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-grips.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-grips.png new file mode 100755 index 0000000..1692347 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-grips.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-sprites2x.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-sprites2x.png new file mode 100755 index 0000000..a70f5dc Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/light-sprites2x.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/pop-up-triangle-dark.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/pop-up-triangle-dark.png new file mode 100755 index 0000000..53e79bc Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/pop-up-triangle-dark.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/pop-up-triangle.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/pop-up-triangle.png new file mode 100755 index 0000000..0467cc5 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/pop-up-triangle.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search-bg.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search-bg.png new file mode 100755 index 0000000..54181ee Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search-bg.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search-bg2x.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search-bg2x.png new file mode 100755 index 0000000..f886480 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search-bg2x.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search.svg new file mode 100755 index 0000000..d18a4fa --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search.svg @@ -0,0 +1,11 @@ + + + Slice 1 + Created with Sketch (http://www.bohemiancoding.com/sketch) + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search_bw.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search_bw.svg new file mode 100755 index 0000000..9ab9e71 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search_bw.svg @@ -0,0 +1,16 @@ + + + + + + +]> + + + diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search_dark.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search_dark.svg new file mode 100755 index 0000000..9ab9e71 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search_dark.svg @@ -0,0 +1,16 @@ + + + + + + +]> + + + diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search_light.svg b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search_light.svg new file mode 100755 index 0000000..0c0dff6 --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/search_light.svg @@ -0,0 +1,11 @@ + + + Slice 1 + Created with Sketch (http://www.bohemiancoding.com/sketch) + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/spinner.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/spinner.png new file mode 100755 index 0000000..ae457fa Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/spinner.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/spinner2x.png b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/spinner2x.png new file mode 100755 index 0000000..3b77ee6 Binary files /dev/null and b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/img/spinner2x.png differ diff --git a/platforms/android/assets/www/cdvtests/topcoat-0.7.5/package.json b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/package.json new file mode 100755 index 0000000..03c64ef --- /dev/null +++ b/platforms/android/assets/www/cdvtests/topcoat-0.7.5/package.json @@ -0,0 +1,85 @@ +{ + "name": "topcoat", + "version": "0.7.5", + "description": "CSS for clean and fast web apps", + "main": "Gruntfile.js", + "directories": { + "doc": "doc", + "test": "test" + }, + "dependencies": { + "topcoat-utils": "~0.1.3", + "topcoat-radio-button-base": "~0.1.1", + "topcoat-button-base": "~0.6.0", + "topcoat-radio-button": "~0.1.2", + "topcoat-navigation-bar-base": "~0.4.0", + "topcoat-navigation-bar": "~0.4.2", + "topcoat-input-base": "~0.4.1", + "topcoat-list-base": "~0.4.1", + "topcoat-list": "~0.5.0", + "topcoat-search-input": "~0.3.0", + "topcoat-search-input-base": "~0.1.2", + "topcoat-checkbox": "~0.4.0", + "topcoat-checkbox-base": "~0.1.3", + "topcoat-button": "~0.5.3", + "topcoat-icon-button": "~0.3.3", + "topcoat-button-bar-base": "~0.1.1", + "topcoat-button-bar": "~0.1.0", + "topcoat-textarea": "~0.3.0", + "topcoat-theme": "~0.5.24", + "topcoat-text-input": "~0.3.4", + "topcoat-textarea-base": "~0.3.2", + "topcoat-notification": "~0.1.1", + "topcoat-notification-base": "0.0.1", + "topcoat-tab-bar": "~0.1.0", + "topcoat-switch": "~0.1.3", + "topcoat-switch-base": "~0.1.0", + "topcoat-range-base": "0.0.3", + "topcoat-range": "~0.1.0" + }, + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-copy": "~0.4.1", + "grunt-contrib-jade": "~0.4.0", + "grunt-contrib-watch": "~0.1.4", + "grunt-contrib-clean": "~0.4.1", + "grunt-exec": "~0.4.2", + "grunt-contrib-cssmin": "~0.5.0", + "jade": "~0.28.2", + "grunt-contrib-stylus": "~0.6.0", + "grunt-contrib-htmlmin": "~0.1.3", + "prompt": "*", + "csv": "*", + "topdoc-theme": "~0.2.7", + "grunt-topdoc": "~0.1.3", + "grunt-autoprefixer": "~0.2.20130806" + }, + "scripts": { + "test": "grunt test", + "prepublish": "grunt" + }, + "repository": { + "type": "git", + "url": "git://github.com/topcoat/topcoat.git" + }, + "bugs": { + "url": "https://github.com/topcoat/topcoat/issues" + }, + "license": { + "type": "Apache", + "url": "https://github.com/topcoat/topcoat/blob/master/LICENSE" + }, + "keywords": [ + "css", + "ui", + "ux", + "pattern", + "library", + "mobile", + "desktop", + "native", + "application", + "web", + "standards" + ] +} diff --git a/platforms/android/assets/www/cordova-js-src/platform.js b/platforms/android/assets/www/cordova-js-src/platform.js index bffc675..2bfd024 100644 --- a/platforms/android/assets/www/cordova-js-src/platform.js +++ b/platforms/android/assets/www/cordova-js-src/platform.js @@ -19,6 +19,9 @@ * */ +// The last resume event that was received that had the result of a plugin call. +var lastResumeEvent = null; + module.exports = { id: 'android', bootstrap: function() { @@ -58,6 +61,19 @@ module.exports = { bindButtonChannel('volumeup'); bindButtonChannel('volumedown'); + // The resume event is not "sticky", but it is possible that the event + // will contain the result of a plugin call. We need to ensure that the + // plugin result is delivered even after the event is fired (CB-10498) + var cordovaAddEventListener = document.addEventListener; + + document.addEventListener = function(evt, handler, capture) { + cordovaAddEventListener(evt, handler, capture); + + if (evt === 'resume' && lastResumeEvent) { + handler(lastResumeEvent); + } + }; + // Let native code know we are all done on the JS side. // Native code will then un-hide the WebView. channel.onCordovaReady.subscribe(function() { @@ -79,12 +95,30 @@ function onMessageFromNative(msg) { case 'searchbutton': // App life cycle events case 'pause': - case 'resume': // Volume events case 'volumedownbutton': case 'volumeupbutton': cordova.fireDocumentEvent(action); break; + case 'resume': + if(arguments.length > 1 && msg.pendingResult) { + if(arguments.length === 2) { + msg.pendingResult.result = arguments[1]; + } else { + // The plugin returned a multipart message + var res = []; + for(var i = 1; i < arguments.length; i++) { + res.push(arguments[i]); + } + msg.pendingResult.result = res; + } + + // Save the plugin result so that it can be delivered to the js + // even if they miss the initial firing of the event + lastResumeEvent = msg; + } + cordova.fireDocumentEvent(action, msg); + break; default: throw new Error('Unknown event action ' + action); } diff --git a/platforms/android/assets/www/cordova.js b/platforms/android/assets/www/cordova.js index 23f6e47..e94e0f7 100644 --- a/platforms/android/assets/www/cordova.js +++ b/platforms/android/assets/www/cordova.js @@ -1,5 +1,5 @@ // Platform: android -// 2c29e187e4206a6a77fba940ef6f77aef5c7eb8c +// c517ca811b4948b630e0b74dbae6c9637939da24 /* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file @@ -19,7 +19,7 @@ under the License. */ ;(function() { -var PLATFORM_VERSION_BUILD_LABEL = '4.1.1'; +var PLATFORM_VERSION_BUILD_LABEL = '5.1.1'; // file: src/scripts/require.js /*jshint -W079 */ @@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") { // file: src/cordova.js define("cordova", function(require, exports, module) { -if(window.cordova){ +// Workaround for Windows 10 in hosted environment case +// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object +if (window.cordova && !(window.cordova instanceof HTMLElement)) { throw new Error("cordova already defined"); } @@ -1291,10 +1293,12 @@ define("cordova/init_b", function(require, exports, module) { var channel = require('cordova/channel'); var cordova = require('cordova'); +var modulemapper = require('cordova/modulemapper'); var platform = require('cordova/platform'); +var pluginloader = require('cordova/pluginloader'); var utils = require('cordova/utils'); -var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady]; +var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady]; // setting exec cordova.exec = require('cordova/exec'); @@ -1379,10 +1383,19 @@ if (window._nativeReady) { // Call the platform-specific initialization. platform.bootstrap && platform.bootstrap(); +// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js. +// The delay allows the attached modules to be defined before the plugin loader looks for them. +setTimeout(function() { + pluginloader.load(function() { + channel.onPluginsReady.fire(); + }); +}, 0); + /** * Create all cordova objects once native side is ready. */ channel.join(function() { + modulemapper.mapModules(window); platform.initialize && platform.initialize(); @@ -1499,11 +1512,111 @@ exports.getOriginalSymbol = function(context, symbolPath) { exports.reset(); +}); + +// file: src/common/modulemapper_b.js +define("cordova/modulemapper_b", function(require, exports, module) { + +var builder = require('cordova/builder'), + symbolList = [], + deprecationMap; + +exports.reset = function() { + symbolList = []; + deprecationMap = {}; +}; + +function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) { + symbolList.push(strategy, moduleName, symbolPath); + if (opt_deprecationMessage) { + deprecationMap[symbolPath] = opt_deprecationMessage; + } +} + +// Note: Android 2.3 does have Function.bind(). +exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) { + addEntry('c', moduleName, symbolPath, opt_deprecationMessage); +}; + +exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) { + addEntry('m', moduleName, symbolPath, opt_deprecationMessage); +}; + +exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) { + addEntry('d', moduleName, symbolPath, opt_deprecationMessage); +}; + +exports.runs = function(moduleName) { + addEntry('r', moduleName, null); +}; + +function prepareNamespace(symbolPath, context) { + if (!symbolPath) { + return context; + } + var parts = symbolPath.split('.'); + var cur = context; + for (var i = 0, part; part = parts[i]; ++i) { + cur = cur[part] = cur[part] || {}; + } + return cur; +} + +exports.mapModules = function(context) { + var origSymbols = {}; + context.CDV_origSymbols = origSymbols; + for (var i = 0, len = symbolList.length; i < len; i += 3) { + var strategy = symbolList[i]; + var moduleName = symbolList[i + 1]; + var module = require(moduleName); + // + if (strategy == 'r') { + continue; + } + var symbolPath = symbolList[i + 2]; + var lastDot = symbolPath.lastIndexOf('.'); + var namespace = symbolPath.substr(0, lastDot); + var lastName = symbolPath.substr(lastDot + 1); + + var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null; + var parentObj = prepareNamespace(namespace, context); + var target = parentObj[lastName]; + + if (strategy == 'm' && target) { + builder.recursiveMerge(target, module); + } else if ((strategy == 'd' && !target) || (strategy != 'd')) { + if (!(symbolPath in origSymbols)) { + origSymbols[symbolPath] = target; + } + builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg); + } + } +}; + +exports.getOriginalSymbol = function(context, symbolPath) { + var origSymbols = context.CDV_origSymbols; + if (origSymbols && (symbolPath in origSymbols)) { + return origSymbols[symbolPath]; + } + var parts = symbolPath.split('.'); + var obj = context; + for (var i = 0; i < parts.length; ++i) { + obj = obj && obj[parts[i]]; + } + return obj; +}; + +exports.reset(); + + }); // file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/platform.js define("cordova/platform", function(require, exports, module) { +// The last resume event that was received that had the result of a plugin call. +var lastResumeEvent = null; + module.exports = { id: 'android', bootstrap: function() { @@ -1543,6 +1656,19 @@ module.exports = { bindButtonChannel('volumeup'); bindButtonChannel('volumedown'); + // The resume event is not "sticky", but it is possible that the event + // will contain the result of a plugin call. We need to ensure that the + // plugin result is delivered even after the event is fired (CB-10498) + var cordovaAddEventListener = document.addEventListener; + + document.addEventListener = function(evt, handler, capture) { + cordovaAddEventListener(evt, handler, capture); + + if (evt === 'resume' && lastResumeEvent) { + handler(lastResumeEvent); + } + }; + // Let native code know we are all done on the JS side. // Native code will then un-hide the WebView. channel.onCordovaReady.subscribe(function() { @@ -1564,12 +1690,30 @@ function onMessageFromNative(msg) { case 'searchbutton': // App life cycle events case 'pause': - case 'resume': // Volume events case 'volumedownbutton': case 'volumeupbutton': cordova.fireDocumentEvent(action); break; + case 'resume': + if(arguments.length > 1 && msg.pendingResult) { + if(arguments.length === 2) { + msg.pendingResult.result = arguments[1]; + } else { + // The plugin returned a multipart message + var res = []; + for(var i = 1; i < arguments.length; i++) { + res.push(arguments[i]); + } + msg.pendingResult.result = res; + } + + // Save the plugin result so that it can be delivered to the js + // even if they miss the initial firing of the event + lastResumeEvent = msg; + } + cordova.fireDocumentEvent(action, msg); + break; default: throw new Error('Unknown event action ' + action); } @@ -1673,10 +1817,6 @@ module.exports = { // file: src/common/pluginloader.js define("cordova/pluginloader", function(require, exports, module) { -/* - NOTE: this file is NOT used when we use the browserify workflow -*/ - var modulemapper = require('cordova/modulemapper'); var urlutil = require('cordova/urlutil'); @@ -1784,6 +1924,54 @@ exports.load = function(callback) { }; +}); + +// file: src/common/pluginloader_b.js +define("cordova/pluginloader_b", function(require, exports, module) { + +var modulemapper = require('cordova/modulemapper'); + +// Handler for the cordova_plugins.js content. +// See plugman's plugin_loader.js for the details of this object. +function handlePluginsObject(moduleList) { + // if moduleList is not defined or empty, we've nothing to do + if (!moduleList || !moduleList.length) { + return; + } + + // Loop through all the modules and then through their clobbers and merges. + for (var i = 0, module; module = moduleList[i]; i++) { + if (module.clobbers && module.clobbers.length) { + for (var j = 0; j < module.clobbers.length; j++) { + modulemapper.clobbers(module.id, module.clobbers[j]); + } + } + + if (module.merges && module.merges.length) { + for (var k = 0; k < module.merges.length; k++) { + modulemapper.merges(module.id, module.merges[k]); + } + } + + // Finally, if runs is truthy we want to simply require() the module. + if (module.runs) { + modulemapper.runs(module.id); + } + } +} + +// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle +// but the method accepts callback to be compatible with non-browserify flow. +// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are +// no plugins to load, or they are all done. +exports.load = function(callback) { + var moduleList = require("cordova/plugin_list"); + handlePluginsObject(moduleList); + + callback(); +}; + + }); // file: src/common/urlutil.js diff --git a/platforms/android/assets/www/cordova_plugins.js b/platforms/android/assets/www/cordova_plugins.js index 3d13c71..25c72bb 100644 --- a/platforms/android/assets/www/cordova_plugins.js +++ b/platforms/android/assets/www/cordova_plugins.js @@ -1,25 +1,37 @@ cordova.define('cordova/plugin_list', function(require, exports, module) { module.exports = [ + { + "file": "plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js", + "id": "at.gofg.sportscomputer.powermanagement.device", + "clobbers": [ + "window.powerManagement" + ] + }, { "file": "plugins/com.lampa.startapp/www/startApp.js", "id": "com.lampa.startapp.startapp", - "pluginId": "com.lampa.startapp", "merges": [ "navigator.startApp" ] }, { - "file": "plugins/com.shukriadams.micVolume/www/micVolume.js", - "id": "com.shukriadams.micVolume.MicVolume", - "pluginId": "com.shukriadams.micVolume", + "file": "plugins/cordova-plugin-device/www/device.js", + "id": "cordova-plugin-device.device", "clobbers": [ - "window.micVolume" + "device" + ] + }, + { + "file": "plugins/cordova-plugin-background-mode/www/background-mode.js", + "id": "cordova-plugin-background-mode.BackgroundMode", + "clobbers": [ + "cordova.plugins.backgroundMode", + "plugin.backgroundMode" ] }, { "file": "plugins/cordova-plugin-device-motion/www/Acceleration.js", "id": "cordova-plugin-device-motion.Acceleration", - "pluginId": "cordova-plugin-device-motion", "clobbers": [ "Acceleration" ] @@ -27,21 +39,13 @@ module.exports = [ { "file": "plugins/cordova-plugin-device-motion/www/accelerometer.js", "id": "cordova-plugin-device-motion.accelerometer", - "pluginId": "cordova-plugin-device-motion", "clobbers": [ "navigator.accelerometer" ] }, - { - "file": "plugins/cordova-plugin-whitelist/whitelist.js", - "id": "cordova-plugin-whitelist.whitelist", - "pluginId": "cordova-plugin-whitelist", - "runs": true - }, { "file": "plugins/cordova-plugin-dialogs/www/notification.js", "id": "cordova-plugin-dialogs.notification", - "pluginId": "cordova-plugin-dialogs", "merges": [ "navigator.notification" ] @@ -49,48 +53,87 @@ module.exports = [ { "file": "plugins/cordova-plugin-dialogs/www/android/notification.js", "id": "cordova-plugin-dialogs.notification_android", - "pluginId": "cordova-plugin-dialogs", "merges": [ "navigator.notification" ] }, { - "file": "plugins/cordova-plugin-device/www/device.js", - "id": "cordova-plugin-device.device", - "pluginId": "cordova-plugin-device", + "file": "plugins/cordova-plugin-whitelist/whitelist.js", + "id": "cordova-plugin-whitelist.whitelist", + "runs": true + }, + { + "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js", + "id": "de.appplant.cordova.plugin.local-notification.LocalNotification", "clobbers": [ - "device" + "cordova.plugins.notification.local", + "plugin.notification.local" ] }, { - "file": "plugins/cordova-plugin-background-mode/www/background-mode.js", - "id": "cordova-plugin-background-mode.BackgroundMode", - "pluginId": "cordova-plugin-background-mode", + "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js", + "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core", "clobbers": [ - "cordova.plugins.backgroundMode", - "plugin.backgroundMode" + "cordova.plugins.notification.local.core", + "plugin.notification.local.core" ] }, { - "file": "plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js", - "id": "at.gofg.sportscomputer.powermanagement.device", - "pluginId": "at.gofg.sportscomputer.powermanagement", + "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js", + "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util", + "merges": [ + "cordova.plugins.notification.local.core", + "plugin.notification.local.core" + ] + }, + { + "file": "plugins/cordova-plugin-device-tests/tests.js", + "id": "cordova-plugin-device-tests.tests" + }, + { + "file": "plugins/cordova-plugin-device-motion-tests/tests.js", + "id": "cordova-plugin-device-motion-tests.tests" + }, + { + "file": "plugins/cordova-plugin-test-framework/www/tests.js", + "id": "cordova-plugin-test-framework.cdvtests" + }, + { + "file": "plugins/cordova-plugin-test-framework/www/jasmine_helpers.js", + "id": "cordova-plugin-test-framework.jasmine_helpers" + }, + { + "file": "plugins/cordova-plugin-test-framework/www/medic.js", + "id": "cordova-plugin-test-framework.medic" + }, + { + "file": "plugins/cordova-plugin-test-framework/www/main.js", + "id": "cordova-plugin-test-framework.main" + }, + { + "file": "plugins/com.shukriadams.micVolume/www/micVolume.js", + "id": "com.shukriadams.micVolume.MicVolume", "clobbers": [ - "window.powerManagement" + "window.micVolume" ] } ]; module.exports.metadata = // TOP OF METADATA { + "at.gofg.sportscomputer.powermanagement": "1.1.0", "com.lampa.startapp": "0.0.5", - "com.shukriadams.micVolume": "0.1.0", - "cordova-plugin-device-motion": "1.2.0", - "cordova-plugin-whitelist": "1.2.1", - "cordova-plugin-dialogs": "1.2.0", + "cordova-plugin-app-event": "1.2.0", "cordova-plugin-device": "1.1.1", "cordova-plugin-background-mode": "0.6.5", - "at.gofg.sportscomputer.powermanagement": "1.1.0" -} + "cordova-plugin-device-motion": "1.2.0", + "cordova-plugin-dialogs": "1.2.0", + "cordova-plugin-whitelist": "1.2.1", + "de.appplant.cordova.plugin.local-notification": "0.8.4", + "cordova-plugin-device-tests": "1.1.2-dev", + "cordova-plugin-device-motion-tests": "1.2.1-dev", + "cordova-plugin-test-framework": "1.1.2-dev", + "com.shukriadams.micVolume": "0.1.0" +}; // BOTTOM OF METADATA }); \ No newline at end of file diff --git a/platforms/android/assets/www/help.html b/platforms/android/assets/www/help.html new file mode 100644 index 0000000..1e4191f --- /dev/null +++ b/platforms/android/assets/www/help.html @@ -0,0 +1,189 @@ + + + + + + Help + + + + + + + + + + + +
+
+
+
+
+
+
+
Help
+
+ + + + +
+ +
+

User Evaluation Participants

+ For the next week I ask that whenever you sit down to study, you open the app and press the start switch to inform it that you are beginning a session. At the end of your studying session, simply open the app again and press the stop switch. At the end of the session, I ask that you fill in the “Post-Study Session†online questionnaire. A link to is available within the menu of the app. Alternatively you can use the link I’ve sent you via email to fill it out on a computer/laptop. +
+
+

Menu

+ The menu for the app can be accessed by selecting the 3 white horizontal lines in the top left corner of the screen. This gives access to all pages within the app. It can be closed by selecting the horizonal lines a second time. +
+

Study Time

+ Study Time is the default page. It is where you will be starting, pausing and finishing your study sessions. +
+ start: +
    +
  1. press the switch while it is in it’s ‘off state’ (grey coloured).
  2. +
+
+ pause:
+
    +
  1. press the switch while it is in it’s ‘on state’ (blue coloured).
  2. +
  3. select “take a short break†when the “confirmation†window pops up.
  4. +
+
+ resume:
+
    +
  1. select “ok†or tap anywhere off of the “monitoring paused†message.
  2. +
+
+ stop:
+
    +
  1. + press the switch while it is in it’s ‘on state’ (blue coloured). +
  2. +
  3. select “yes†when the “confirmation†window pops up.
  4. +
  5. enter any notes you wish to save regarding the session and click “okâ€. It is fine to leave the input field blank and just click “ok†if you have no notes to save.
  6. +
  7. Upon stopping, your session will be saved.
  8. +
+
+ Whilst a session is in progress you cannot travel to other StudyWell pages. To do so you must first end the session. +
+
+ +

Schedule

+ This page is a placeholder. The feature is still a work-in-progress. For now there is only a button allowing you to open Google Calendar - something which can allow you to plan study sessions. +
+
+ +

Reports

+ This section is where you can view the reports on all your previous study sessions. Reports will be ordered by time and date, from earliest to latest. As of just now, to review your reports you must be connected to the internet. +
+
+ + +

Settings

+ In this section of the app you can change the app’s default settings to your own custom ones. +
+
+ current user ID:
+
    +
  1. directly under “Current User ID†you will find what your ID is currently set to.
  2. +
+
+ new user ID:
+
    +
  1. tap the input box below “New User ID†- your device's keyboard should appear.
  2. +
  3. enter your user ID.
  4. +
  5. tap the “Submit†button below the input box.
  6. +
+
+ + enable break reminder: +
    +
  1. in the “break reminder†section, select the “on†radio button.
  2. +
  3. there should be a dark dot in the circle next to the “on†text.
  4. +
  5. there should be no dark dot in the circle next to the “off†text.
  6. +
+ +
+ disable break reminder:
+
    +
  1. in the “break reminder†section, select the “off†radio button.
  2. +
  3. there should be a dark dot in the circle next to the “off†text.
  4. +
  5. there should be no dark dot in the circle next to the “on†text.
  6. +
+ +
+ set study duration between break reminders:
+
    +
  1. enable break reminder (see above)
  2. +
  3. tap the rectangle stating “X Minutes†with a small arrow pointing down - X being either “20, 30, 40, 50 or 60â€.
  4. +
  5. a pop up should appear.
  6. +
  7. select the duration you want to study for between breaks.
  8. +
+ +
+ enable distraction reminder:
+
    +
  1. in the “distraction reminder†section, select the “on†radio button.
  2. +
  3. there should be a dark dot in the circle next to the “on†text.
  4. +
  5. there should be no dark dot in the circle next to the “off†text.
  6. +
+
+ + disable distraction reminder:
+
    +
  1. in the “distraction reminder†section, select the “off†radio button.
  2. +
  3. there should be a dark dot in the circle next to the “off†text.
  4. +
  5. there should be no dark dot in the circle next to the “on†text.
  6. +
+
+ + custom noise threshold level: +
    +
  1. in the “surrounding noise level†section.
  2. +
  3. tap the “record noise level†button.
  4. +
  5. tap “ok†on the pop up that appears.
  6. +
  7. wait 10 seconds.
  8. +
  9. tap ok on the pop up that appears.
  10. +
+ +
+ default noise threshold level:
+
    +
  1. in the “surrounding noise level†section.
  2. +
  3. tap the “default value†button.
  4. +
  5. tap “ok†on the pop up that appears.
  6. +
+
+
+ +

Help

+ In this section you can read the user guide and find instructions on how to complete the user evaluation. +
+
+ + +

Post-Session Questionnaire

+ This button will open up a questionnaire in your browser. This questionnaire is for filling in after a study session. It is not necessary to fill one in if your study session only lasted a few minutes. Information such as “session ID†that the questionnaire asks for can be found in the “Reports†section of the app. Ensure you are looking at the correct report when you take note of the session ID. +
+ +
+
+ + + + + + + diff --git a/platforms/android/assets/www/index.html b/platforms/android/assets/www/index.html index a95cb47..e029c01 100644 --- a/platforms/android/assets/www/index.html +++ b/platforms/android/assets/www/index.html @@ -6,12 +6,11 @@ StudyWell Home - + - @@ -36,7 +35,7 @@ - +
@@ -49,11 +48,11 @@ @@ -72,7 +71,9 @@

-

+
+

+


@@ -93,5 +94,27 @@

+ // Test the navigation bar by clicking on the 'REVIEW' link and checking the URL changes to '/review' + it('Has a working nav', function(done) { + var currentURL = this.driver.getCurrentUrl(); + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + setTimeout(restTest, 2000); + var currentURL = this.driver.getCurrentUrl(); + + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + diff --git a/platforms/android/assets/www/node_modules/.bin/jasmine b/platforms/android/assets/www/node_modules/.bin/jasmine new file mode 120000 index 0000000..d2c1bff --- /dev/null +++ b/platforms/android/assets/www/node_modules/.bin/jasmine @@ -0,0 +1 @@ +../jasmine/bin/jasmine.js \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/.bin/rimraf b/platforms/android/assets/www/node_modules/.bin/rimraf new file mode 120000 index 0000000..4cd49a4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/.bin/rimraf @@ -0,0 +1 @@ +../rimraf/bin.js \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/adm-zip/.idea/scopes/scope_settings.xml b/platforms/android/assets/www/node_modules/adm-zip/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000..0d5175c --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/adm-zip/MIT-LICENSE.txt b/platforms/android/assets/www/node_modules/adm-zip/MIT-LICENSE.txt new file mode 100644 index 0000000..14c3ee5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/MIT-LICENSE.txt @@ -0,0 +1,21 @@ +Copyright (c) 2012 Another-D-Mention Software and other contributors, +http://www.another-d-mention.ro/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/adm-zip/README.md b/platforms/android/assets/www/node_modules/adm-zip/README.md new file mode 100644 index 0000000..030fab8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/README.md @@ -0,0 +1,64 @@ +# ADM-ZIP for NodeJS + +ADM-ZIP is a pure JavaScript implementation for zip data compression for [NodeJS](http://nodejs.org/). + +# Installation + +With [npm](http://npmjs.org) do: + + $ npm install adm-zip + +## What is it good for? +The library allows you to: + +* decompress zip files directly to disk or in memory buffers +* compress files and store them to disk in .zip format or in compressed buffers +* update content of/add new/delete files from an existing .zip + +# Dependencies +There are no other nodeJS libraries that ADM-ZIP is dependent of + +# Examples + +## Basic usage +```javascript + + var AdmZip = require('adm-zip'); + + // reading archives + var zip = new AdmZip("./my_file.zip"); + var zipEntries = zip.getEntries(); // an array of ZipEntry records + + zipEntries.forEach(function(zipEntry) { + console.log(zipEntry.toString()); // outputs zip entries information + if (zipEntry.entryName == "my_file.txt") { + console.log(zipEntry.data.toString('utf8')); + } + }); + // outputs the content of some_folder/my_file.txt + console.log(zip.readAsText("some_folder/my_file.txt")); + // extracts the specified file to the specified location + zip.extractEntryTo(/*entry name*/"some_folder/my_file.txt", /*target path*/"/home/me/tempfolder", /*maintainEntryPath*/false, /*overwrite*/true); + // extracts everything + zip.extractAllTo(/*target path*/"/home/me/zipcontent/", /*overwrite*/true); + + + // creating archives + var zip = new AdmZip(); + + // add file directly + zip.addFile("test.txt", new Buffer("inner content of the file"), "entry comment goes here"); + // add local file + zip.addLocalFile("/home/me/some_picture.png"); + // get everything as a buffer + var willSendthis = zip.toBuffer(); + // or write everything to disk + zip.writeZip(/*target file name*/"/home/me/files.zip"); + + + // ... more examples in the wiki +``` + +For more detailed information please check out the [wiki](https://github.com/cthackers/adm-zip/wiki). + +[![build status](https://secure.travis-ci.org/cthackers/adm-zip.png)](http://travis-ci.org/cthackers/adm-zip) diff --git a/platforms/android/assets/www/node_modules/adm-zip/adm-zip.js b/platforms/android/assets/www/node_modules/adm-zip/adm-zip.js new file mode 100644 index 0000000..46595fc --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/adm-zip.js @@ -0,0 +1,404 @@ +var fs = require("fs"), + pth = require("path"); + +fs.existsSync = fs.existsSync || pth.existsSync; + +var ZipEntry = require("./zipEntry"), + ZipFile = require("./zipFile"), + Utils = require("./util"); + +module.exports = function(/*String*/input) { + var _zip = undefined, + _filename = ""; + + if (input && typeof input === "string") { // load zip file + if (fs.existsSync(input)) { + _filename = input; + _zip = new ZipFile(input, Utils.Constants.FILE); + } else { + throw Utils.Errors.INVALID_FILENAME; + } + } else if(input && Buffer.isBuffer(input)) { // load buffer + _zip = new ZipFile(input, Utils.Constants.BUFFER); + } else { // create new zip file + _zip = new ZipFile(null, Utils.Constants.NONE); + } + + function getEntry(/*Object*/entry) { + if (entry && _zip) { + var item; + // If entry was given as a file name + if (typeof entry === "string") + item = _zip.getEntry(entry); + // if entry was given as a ZipEntry object + if (typeof entry === "object" && entry.entryName != undefined && entry.header != undefined) + item = _zip.getEntry(entry.entryName); + + if (item) { + return item; + } + } + return null; + } + + return { + /** + * Extracts the given entry from the archive and returns the content as a Buffer object + * @param entry ZipEntry object or String with the full path of the entry + * + * @return Buffer or Null in case of error + */ + readFile : function(/*Object*/entry) { + var item = getEntry(entry); + return item && item.getData() || null; + }, + + /** + * Asynchronous readFile + * @param entry ZipEntry object or String with the full path of the entry + * @param callback + * + * @return Buffer or Null in case of error + */ + readFileAsync : function(/*Object*/entry, /*Function*/callback) { + var item = getEntry(entry); + if (item) { + item.getDataAsync(callback); + } else { + callback(null,"getEntry failed for:" + entry) + } + }, + + /** + * Extracts the given entry from the archive and returns the content as plain text in the given encoding + * @param entry ZipEntry object or String with the full path of the entry + * @param encoding Optional. If no encoding is specified utf8 is used + * + * @return String + */ + readAsText : function(/*Object*/entry, /*String - Optional*/encoding) { + var item = getEntry(entry); + if (item) { + var data = item.getData(); + if (data && data.length) { + return data.toString(encoding || "utf8"); + } + } + return ""; + }, + + /** + * Asynchronous readAsText + * @param entry ZipEntry object or String with the full path of the entry + * @param callback + * @param encoding Optional. If no encoding is specified utf8 is used + * + * @return String + */ + readAsTextAsync : function(/*Object*/entry, /*Function*/callback, /*String - Optional*/encoding) { + var item = getEntry(entry); + if (item) { + item.getDataAsync(function(data) { + if (data && data.length) { + callback(data.toString(encoding || "utf8")); + } else { + callback(""); + } + }) + } else { + callback(""); + } + }, + + /** + * Remove the entry from the file or the entry and all it's nested directories and files if the given entry is a directory + * + * @param entry + */ + deleteFile : function(/*Object*/entry) { // @TODO: test deleteFile + var item = getEntry(entry); + if (item) { + _zip.deleteEntry(item.entryName); + } + }, + + /** + * Adds a comment to the zip. The zip must be rewritten after adding the comment. + * + * @param comment + */ + addZipComment : function(/*String*/comment) { // @TODO: test addZipComment + _zip.comment = comment; + }, + + /** + * Returns the zip comment + * + * @return String + */ + getZipComment : function() { + return _zip.comment || ''; + }, + + /** + * Adds a comment to a specified zipEntry. The zip must be rewritten after adding the comment + * The comment cannot exceed 65535 characters in length + * + * @param entry + * @param comment + */ + addZipEntryComment : function(/*Object*/entry,/*String*/comment) { + var item = getEntry(entry); + if (item) { + item.comment = comment; + } + }, + + /** + * Returns the comment of the specified entry + * + * @param entry + * @return String + */ + getZipEntryComment : function(/*Object*/entry) { + var item = getEntry(entry); + if (item) { + return item.comment || ''; + } + return '' + }, + + /** + * Updates the content of an existing entry inside the archive. The zip must be rewritten after updating the content + * + * @param entry + * @param content + */ + updateFile : function(/*Object*/entry, /*Buffer*/content) { + var item = getEntry(entry); + if (item) { + item.setData(content); + } + }, + + /** + * Adds a file from the disk to the archive + * + * @param localPath + */ + addLocalFile : function(/*String*/localPath, /*String*/zipPath) { + if (fs.existsSync(localPath)) { + if(zipPath){ + zipPath=zipPath.split("\\").join("/"); + if(zipPath.charAt(zipPath.length - 1) != "/"){ + zipPath += "/"; + } + }else{ + zipPath=""; + } + var p = localPath.split("\\").join("/").split("/").pop(); + + this.addFile(zipPath+p, fs.readFileSync(localPath), "", 0) + } else { + throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath); + } + }, + + /** + * Adds a local directory and all its nested files and directories to the archive + * + * @param localPath + */ + addLocalFolder : function(/*String*/localPath, /*String*/zipPath) { + if(zipPath){ + zipPath=zipPath.split("\\").join("/"); + if(zipPath.charAt(zipPath.length - 1) != "/"){ + zipPath += "/"; + } + }else{ + zipPath=""; + } + localPath = localPath.split("\\").join("/"); //windows fix + if (localPath.charAt(localPath.length - 1) != "/") + localPath += "/"; + + if (fs.existsSync(localPath)) { + + var items = Utils.findFiles(localPath), + self = this; + + if (items.length) { + items.forEach(function(path) { + var p = path.split("\\").join("/").replace(localPath, ""); //windows fix + if (p.charAt(p.length - 1) !== "/") { + self.addFile(zipPath+p, fs.readFileSync(path), "", 0) + } else { + self.addFile(zipPath+p, new Buffer(0), "", 0) + } + }); + } + } else { + throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath); + } + }, + + /** + * Allows you to create a entry (file or directory) in the zip file. + * If you want to create a directory the entryName must end in / and a null buffer should be provided. + * Comment and attributes are optional + * + * @param entryName + * @param content + * @param comment + * @param attr + */ + addFile : function(/*String*/entryName, /*Buffer*/content, /*String*/comment, /*Number*/attr) { + var entry = new ZipEntry(); + entry.entryName = entryName; + entry.comment = comment || ""; + entry.attr = attr || 438; //0666; + if (entry.isDirectory && content.length) { + // throw Utils.Errors.DIRECTORY_CONTENT_ERROR; + } + entry.setData(content); + _zip.setEntry(entry); + }, + + /** + * Returns an array of ZipEntry objects representing the files and folders inside the archive + * + * @return Array + */ + getEntries : function() { + if (_zip) { + return _zip.entries; + } else { + return []; + } + }, + + /** + * Returns a ZipEntry object representing the file or folder specified by ``name``. + * + * @param name + * @return ZipEntry + */ + getEntry : function(/*String*/name) { + return getEntry(name); + }, + + /** + * Extracts the given entry to the given targetPath + * If the entry is a directory inside the archive, the entire directory and it's subdirectories will be extracted + * + * @param entry ZipEntry object or String with the full path of the entry + * @param targetPath Target folder where to write the file + * @param maintainEntryPath If maintainEntryPath is true and the entry is inside a folder, the entry folder + * will be created in targetPath as well. Default is TRUE + * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true. + * Default is FALSE + * + * @return Boolean + */ + extractEntryTo : function(/*Object*/entry, /*String*/targetPath, /*Boolean*/maintainEntryPath, /*Boolean*/overwrite) { + overwrite = overwrite || false; + maintainEntryPath = typeof maintainEntryPath == "undefined" ? true : maintainEntryPath; + + var item = getEntry(entry); + if (!item) { + throw Utils.Errors.NO_ENTRY; + } + + var target = pth.resolve(targetPath, maintainEntryPath ? item.entryName : pth.basename(item.entryName)); + + if (item.isDirectory) { + target = pth.resolve(target, ".."); + var children = _zip.getEntryChildren(item); + children.forEach(function(child) { + if (child.isDirectory) return; + var content = child.getData(); + if (!content) { + throw Utils.Errors.CANT_EXTRACT_FILE; + } + Utils.writeFileTo(pth.resolve(targetPath, maintainEntryPath ? child.entryName : child.entryName.substr(item.entryName.length)), content, overwrite); + }); + return true; + } + + var content = item.getData(); + if (!content) throw Utils.Errors.CANT_EXTRACT_FILE; + + if (fs.existsSync(targetPath) && !overwrite) { + throw Utils.Errors.CANT_OVERRIDE; + } + Utils.writeFileTo(target, content, overwrite); + + return true; + }, + + /** + * Extracts the entire archive to the given location + * + * @param targetPath Target location + * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true. + * Default is FALSE + */ + extractAllTo : function(/*String*/targetPath, /*Boolean*/overwrite) { + overwrite = overwrite || false; + if (!_zip) { + throw Utils.Errors.NO_ZIP; + } + + _zip.entries.forEach(function(entry) { + if (entry.isDirectory) { + Utils.makeDir(pth.resolve(targetPath, entry.entryName.toString())); + return; + } + var content = entry.getData(); + if (!content) { + throw Utils.Errors.CANT_EXTRACT_FILE + "2"; + } + Utils.writeFileTo(pth.resolve(targetPath, entry.entryName.toString()), content, overwrite); + }) + }, + + /** + * Writes the newly created zip file to disk at the specified location or if a zip was opened and no ``targetFileName`` is provided, it will overwrite the opened zip + * + * @param targetFileName + * @param callback + */ + writeZip : function(/*String*/targetFileName, /*Function*/callback) { + if (arguments.length == 1) { + if (typeof targetFileName == "function") { + callback = targetFileName; + targetFileName = ""; + } + } + + if (!targetFileName && _filename) { + targetFileName = _filename; + } + if (!targetFileName) return; + + var zipData = _zip.compressToBuffer(); + if (zipData) { + Utils.writeFileTo(targetFileName, zipData, true); + } + }, + + /** + * Returns the content of the entire zip file as a Buffer object + * + * @return Buffer + */ + toBuffer : function(/*Function*/onSuccess,/*Function*/onFail,/*Function*/onItemStart,/*Function*/onItemEnd) { + this.valueOf = 2; + if (typeof onSuccess == "function") { + _zip.toAsyncBuffer(onSuccess,onFail,onItemStart,onItemEnd); + return null; + } + return _zip.compressToBuffer() + } + } +}; diff --git a/platforms/android/assets/www/node_modules/adm-zip/headers/entryHeader.js b/platforms/android/assets/www/node_modules/adm-zip/headers/entryHeader.js new file mode 100644 index 0000000..a29c70f --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/headers/entryHeader.js @@ -0,0 +1,261 @@ +var Utils = require("../util"), + Constants = Utils.Constants; + +/* The central directory file header */ +module.exports = function () { + var _verMade = 0x0A, + _version = 0x0A, + _flags = 0, + _method = 0, + _time = 0, + _crc = 0, + _compressedSize = 0, + _size = 0, + _fnameLen = 0, + _extraLen = 0, + + _comLen = 0, + _diskStart = 0, + _inattr = 0, + _attr = 0, + _offset = 0; + + var _dataHeader = {}; + + function setTime(val) { + var val = new Date(val); + _time = (val.getFullYear() - 1980 & 0x7f) << 25 // b09-16 years from 1980 + | (val.getMonth() + 1) << 21 // b05-08 month + | val.getDay() << 16 // b00-04 hour + + // 2 bytes time + | val.getHours() << 11 // b11-15 hour + | val.getMinutes() << 5 // b05-10 minute + | val.getSeconds() >> 1; // b00-04 seconds divided by 2 + } + + setTime(+new Date()); + + return { + get made () { return _verMade; }, + set made (val) { _verMade = val; }, + + get version () { return _version; }, + set version (val) { _version = val }, + + get flags () { return _flags }, + set flags (val) { _flags = val; }, + + get method () { return _method; }, + set method (val) { _method = val; }, + + get time () { return new Date( + ((_time >> 25) & 0x7f) + 1980, + ((_time >> 21) & 0x0f) - 1, + (_time >> 16) & 0x1f, + (_time >> 11) & 0x1f, + (_time >> 5) & 0x3f, + (_time & 0x1f) << 1 + ); + }, + set time (val) { + setTime(val); + }, + + get crc () { return _crc; }, + set crc (val) { _crc = val; }, + + get compressedSize () { return _compressedSize; }, + set compressedSize (val) { _compressedSize = val; }, + + get size () { return _size; }, + set size (val) { _size = val; }, + + get fileNameLength () { return _fnameLen; }, + set fileNameLength (val) { _fnameLen = val; }, + + get extraLength () { return _extraLen }, + set extraLength (val) { _extraLen = val; }, + + get commentLength () { return _comLen }, + set commentLength (val) { _comLen = val }, + + get diskNumStart () { return _diskStart }, + set diskNumStart (val) { _diskStart = val }, + + get inAttr () { return _inattr }, + set inAttr (val) { _inattr = val }, + + get attr () { return _attr }, + set attr (val) { _attr = val }, + + get offset () { return _offset }, + set offset (val) { _offset = val }, + + get encripted () { return (_flags & 1) == 1 }, + + get entryHeaderSize () { + return Constants.CENHDR + _fnameLen + _extraLen + _comLen; + }, + + get realDataOffset () { + return _offset + Constants.LOCHDR + _dataHeader.fnameLen + _dataHeader.extraLen; + }, + + get dataHeader () { + return _dataHeader; + }, + + loadDataHeaderFromBinary : function(/*Buffer*/input) { + var data = input.slice(_offset, _offset + Constants.LOCHDR); + // 30 bytes and should start with "PK\003\004" + if (data.readUInt32LE(0) != Constants.LOCSIG) { + throw Utils.Errors.INVALID_LOC; + } + _dataHeader = { + // version needed to extract + version : data.readUInt16LE(Constants.LOCVER), + // general purpose bit flag + flags : data.readUInt16LE(Constants.LOCFLG), + // compression method + method : data.readUInt16LE(Constants.LOCHOW), + // modification time (2 bytes time, 2 bytes date) + time : data.readUInt32LE(Constants.LOCTIM), + // uncompressed file crc-32 value + crc : data.readUInt32LE(Constants.LOCCRC), + // compressed size + compressedSize : data.readUInt32LE(Constants.LOCSIZ), + // uncompressed size + size : data.readUInt32LE(Constants.LOCLEN), + // filename length + fnameLen : data.readUInt16LE(Constants.LOCNAM), + // extra field length + extraLen : data.readUInt16LE(Constants.LOCEXT) + } + }, + + loadFromBinary : function(/*Buffer*/data) { + // data should be 46 bytes and start with "PK 01 02" + if (data.length != Constants.CENHDR || data.readUInt32LE(0) != Constants.CENSIG) { + throw Utils.Errors.INVALID_CEN; + } + // version made by + _verMade = data.readUInt16LE(Constants.CENVEM); + // version needed to extract + _version = data.readUInt16LE(Constants.CENVER); + // encrypt, decrypt flags + _flags = data.readUInt16LE(Constants.CENFLG); + // compression method + _method = data.readUInt16LE(Constants.CENHOW); + // modification time (2 bytes time, 2 bytes date) + _time = data.readUInt32LE(Constants.CENTIM); + // uncompressed file crc-32 value + _crc = data.readUInt32LE(Constants.CENCRC); + // compressed size + _compressedSize = data.readUInt32LE(Constants.CENSIZ); + // uncompressed size + _size = data.readUInt32LE(Constants.CENLEN); + // filename length + _fnameLen = data.readUInt16LE(Constants.CENNAM); + // extra field length + _extraLen = data.readUInt16LE(Constants.CENEXT); + // file comment length + _comLen = data.readUInt16LE(Constants.CENCOM); + // volume number start + _diskStart = data.readUInt16LE(Constants.CENDSK); + // internal file attributes + _inattr = data.readUInt16LE(Constants.CENATT); + // external file attributes + _attr = data.readUInt32LE(Constants.CENATX); + // LOC header offset + _offset = data.readUInt32LE(Constants.CENOFF); + }, + + dataHeaderToBinary : function() { + // LOC header size (30 bytes) + var data = new Buffer(Constants.LOCHDR); + // "PK\003\004" + data.writeUInt32LE(Constants.LOCSIG, 0); + // version needed to extract + data.writeUInt16LE(_version, Constants.LOCVER); + // general purpose bit flag + data.writeUInt16LE(_flags, Constants.LOCFLG); + // compression method + data.writeUInt16LE(_method, Constants.LOCHOW); + // modification time (2 bytes time, 2 bytes date) + data.writeUInt32LE(_time, Constants.LOCTIM); + // uncompressed file crc-32 value + data.writeUInt32LE(_crc, Constants.LOCCRC); + // compressed size + data.writeUInt32LE(_compressedSize, Constants.LOCSIZ); + // uncompressed size + data.writeUInt32LE(_size, Constants.LOCLEN); + // filename length + data.writeUInt16LE(_fnameLen, Constants.LOCNAM); + // extra field length + data.writeUInt16LE(_extraLen, Constants.LOCEXT); + return data; + }, + + entryHeaderToBinary : function() { + // CEN header size (46 bytes) + var data = new Buffer(Constants.CENHDR + _fnameLen + _extraLen + _comLen); + // "PK\001\002" + data.writeUInt32LE(Constants.CENSIG, 0); + // version made by + data.writeUInt16LE(_verMade, Constants.CENVEM); + // version needed to extract + data.writeUInt16LE(_version, Constants.CENVER); + // encrypt, decrypt flags + data.writeUInt16LE(_flags, Constants.CENFLG); + // compression method + data.writeUInt16LE(_method, Constants.CENHOW); + // modification time (2 bytes time, 2 bytes date) + data.writeUInt32LE(_time, Constants.CENTIM); + // uncompressed file crc-32 value + data.writeInt32LE(_crc, Constants.CENCRC, true); + // compressed size + data.writeUInt32LE(_compressedSize, Constants.CENSIZ); + // uncompressed size + data.writeUInt32LE(_size, Constants.CENLEN); + // filename length + data.writeUInt16LE(_fnameLen, Constants.CENNAM); + // extra field length + data.writeUInt16LE(_extraLen, Constants.CENEXT); + // file comment length + data.writeUInt16LE(_comLen, Constants.CENCOM); + // volume number start + data.writeUInt16LE(_diskStart, Constants.CENDSK); + // internal file attributes + data.writeUInt16LE(_inattr, Constants.CENATT); + // external file attributes + data.writeUInt32LE(_attr, Constants.CENATX); + // LOC header offset + data.writeUInt32LE(_offset, Constants.CENOFF); + // fill all with + data.fill(0x00, Constants.CENHDR); + return data; + }, + + toString : function() { + return '{\n' + + '\t"made" : ' + _verMade + ",\n" + + '\t"version" : ' + _version + ",\n" + + '\t"flags" : ' + _flags + ",\n" + + '\t"method" : ' + Utils.methodToString(_method) + ",\n" + + '\t"time" : ' + _time + ",\n" + + '\t"crc" : 0x' + _crc.toString(16).toUpperCase() + ",\n" + + '\t"compressedSize" : ' + _compressedSize + " bytes,\n" + + '\t"size" : ' + _size + " bytes,\n" + + '\t"fileNameLength" : ' + _fnameLen + ",\n" + + '\t"extraLength" : ' + _extraLen + " bytes,\n" + + '\t"commentLength" : ' + _comLen + " bytes,\n" + + '\t"diskNumStart" : ' + _diskStart + ",\n" + + '\t"inAttr" : ' + _inattr + ",\n" + + '\t"attr" : ' + _attr + ",\n" + + '\t"offset" : ' + _offset + ",\n" + + '\t"entryHeaderSize" : ' + (Constants.CENHDR + _fnameLen + _extraLen + _comLen) + " bytes\n" + + '}'; + } + } +}; diff --git a/platforms/android/assets/www/node_modules/adm-zip/headers/index.js b/platforms/android/assets/www/node_modules/adm-zip/headers/index.js new file mode 100644 index 0000000..b8c67b9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/headers/index.js @@ -0,0 +1,2 @@ +exports.EntryHeader = require("./entryHeader"); +exports.MainHeader = require("./mainHeader"); diff --git a/platforms/android/assets/www/node_modules/adm-zip/headers/mainHeader.js b/platforms/android/assets/www/node_modules/adm-zip/headers/mainHeader.js new file mode 100644 index 0000000..002bc8a --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/headers/mainHeader.js @@ -0,0 +1,80 @@ +var Utils = require("../util"), + Constants = Utils.Constants; + +/* The entries in the end of central directory */ +module.exports = function () { + var _volumeEntries = 0, + _totalEntries = 0, + _size = 0, + _offset = 0, + _commentLength = 0; + + return { + get diskEntries () { return _volumeEntries }, + set diskEntries (/*Number*/val) { _volumeEntries = _totalEntries = val; }, + + get totalEntries () { return _totalEntries }, + set totalEntries (/*Number*/val) { _totalEntries = _volumeEntries = val; }, + + get size () { return _size }, + set size (/*Number*/val) { _size = val; }, + + get offset () { return _offset }, + set offset (/*Number*/val) { _offset = val; }, + + get commentLength () { return _commentLength }, + set commentLength (/*Number*/val) { _commentLength = val; }, + + get mainHeaderSize () { + return Constants.ENDHDR + _commentLength; + }, + + loadFromBinary : function(/*Buffer*/data) { + // data should be 22 bytes and start with "PK 05 06" + if (data.length != Constants.ENDHDR || data.readUInt32LE(0) != Constants.ENDSIG) + throw Utils.Errors.INVALID_END; + + // number of entries on this volume + _volumeEntries = data.readUInt16LE(Constants.ENDSUB); + // total number of entries + _totalEntries = data.readUInt16LE(Constants.ENDTOT); + // central directory size in bytes + _size = data.readUInt32LE(Constants.ENDSIZ); + // offset of first CEN header + _offset = data.readUInt32LE(Constants.ENDOFF); + // zip file comment length + _commentLength = data.readUInt16LE(Constants.ENDCOM); + }, + + toBinary : function() { + var b = new Buffer(Constants.ENDHDR + _commentLength); + // "PK 05 06" signature + b.writeUInt32LE(Constants.ENDSIG, 0); + b.writeUInt32LE(0, 4); + // number of entries on this volume + b.writeUInt16LE(_volumeEntries, Constants.ENDSUB); + // total number of entries + b.writeUInt16LE(_totalEntries, Constants.ENDTOT); + // central directory size in bytes + b.writeUInt32LE(_size, Constants.ENDSIZ); + // offset of first CEN header + b.writeUInt32LE(_offset, Constants.ENDOFF); + // zip file comment length + b.writeUInt16LE(_commentLength, Constants.ENDCOM); + // fill comment memory with spaces so no garbage is left there + b.fill(" ", Constants.ENDHDR); + + return b; + }, + + toString : function() { + return '{\n' + + '\t"diskEntries" : ' + _volumeEntries + ",\n" + + '\t"totalEntries" : ' + _totalEntries + ",\n" + + '\t"size" : ' + _size + " bytes,\n" + + '\t"offset" : 0x' + _offset.toString(16).toUpperCase() + ",\n" + + '\t"commentLength" : 0x' + _commentLength + "\n" + + '}'; + } + } +}; \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/adm-zip/methods/deflater.js b/platforms/android/assets/www/node_modules/adm-zip/methods/deflater.js new file mode 100644 index 0000000..3267943 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/methods/deflater.js @@ -0,0 +1,1578 @@ +/* + * $Id: rawdeflate.js,v 0.5 2013/04/09 14:25:38 dankogai Exp dankogai $ + * + * GNU General Public License, version 2 (GPL-2.0) + * http://opensource.org/licenses/GPL-2.0 + * Original: + * http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt + */ +function JSDeflater(/*inbuff*/inbuf) { + + /* Copyright (C) 1999 Masanao Izumo + * Version: 1.0.1 + * LastModified: Dec 25 1999 + */ + + var WSIZE = 32768, // Sliding Window size + zip_STORED_BLOCK = 0, + zip_STATIC_TREES = 1, + zip_DYN_TREES = 2, + zip_DEFAULT_LEVEL = 6, + zip_FULL_SEARCH = true, + zip_INBUFSIZ = 32768, // Input buffer size + zip_INBUF_EXTRA = 64, // Extra buffer + zip_OUTBUFSIZ = 1024 * 8, + zip_window_size = 2 * WSIZE, + MIN_MATCH = 3, + MAX_MATCH = 258, + zip_BITS = 16, + LIT_BUFSIZE = 0x2000, + zip_HASH_BITS = 13, + zip_DIST_BUFSIZE = LIT_BUFSIZE, + zip_HASH_SIZE = 1 << zip_HASH_BITS, + zip_HASH_MASK = zip_HASH_SIZE - 1, + zip_WMASK = WSIZE - 1, + zip_NIL = 0, // Tail of hash chains + zip_TOO_FAR = 4096, + zip_MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1, + zip_MAX_DIST = WSIZE - zip_MIN_LOOKAHEAD, + zip_SMALLEST = 1, + zip_MAX_BITS = 15, + zip_MAX_BL_BITS = 7, + zip_LENGTH_CODES = 29, + zip_LITERALS = 256, + zip_END_BLOCK = 256, + zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES, + zip_D_CODES = 30, + zip_BL_CODES = 19, + zip_REP_3_6 = 16, + zip_REPZ_3_10 = 17, + zip_REPZ_11_138 = 18, + zip_HEAP_SIZE = 2 * zip_L_CODES + 1, + zip_H_SHIFT = parseInt((zip_HASH_BITS + MIN_MATCH - 1) / MIN_MATCH); + + var zip_free_queue, zip_qhead, zip_qtail, zip_initflag, zip_outbuf = null, zip_outcnt, zip_outoff, zip_complete, + zip_window, zip_d_buf, zip_l_buf, zip_prev, zip_bi_buf, zip_bi_valid, zip_block_start, zip_ins_h, zip_hash_head, + zip_prev_match, zip_match_available, zip_match_length, zip_prev_length, zip_strstart, zip_match_start, zip_eofile, + zip_lookahead, zip_max_chain_length, zip_max_lazy_match, zip_compr_level, zip_good_match, zip_nice_match, + zip_dyn_ltree, zip_dyn_dtree, zip_static_ltree, zip_static_dtree, zip_bl_tree, zip_l_desc, zip_d_desc, zip_bl_desc, + zip_bl_count, zip_heap, zip_heap_len, zip_heap_max, zip_depth, zip_length_code, zip_dist_code, zip_base_length, + zip_base_dist, zip_flag_buf, zip_last_lit, zip_last_dist, zip_last_flags, zip_flags, zip_flag_bit, zip_opt_len, + zip_static_len, zip_deflate_data, zip_deflate_pos; + + var zip_DeflateCT = function () { + this.fc = 0; // frequency count or bit string + this.dl = 0; // father node in Huffman tree or length of bit string + }; + + var zip_DeflateTreeDesc = function () { + this.dyn_tree = null; // the dynamic tree + this.static_tree = null; // corresponding static tree or NULL + this.extra_bits = null; // extra bits for each code or NULL + this.extra_base = 0; // base index for extra_bits + this.elems = 0; // max number of elements in the tree + this.max_length = 0; // max bit length for the codes + this.max_code = 0; // largest code with non zero frequency + }; + + /* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ + var zip_DeflateConfiguration = function (a, b, c, d) { + this.good_length = a; // reduce lazy search above this match length + this.max_lazy = b; // do not perform lazy search above this match length + this.nice_length = c; // quit search above this match length + this.max_chain = d; + }; + + var zip_DeflateBuffer = function () { + this.next = null; + this.len = 0; + this.ptr = new Array(zip_OUTBUFSIZ); + this.off = 0; + }; + + /* constant tables */ + var zip_extra_lbits = new Array( + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0); + var zip_extra_dbits = new Array( + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13); + var zip_extra_blbits = new Array( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7); + var zip_bl_order = new Array( + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15); + var zip_configuration_table = new Array( + new zip_DeflateConfiguration(0, 0, 0, 0), + new zip_DeflateConfiguration(4, 4, 8, 4), + new zip_DeflateConfiguration(4, 5, 16, 8), + new zip_DeflateConfiguration(4, 6, 32, 32), + new zip_DeflateConfiguration(4, 4, 16, 16), + new zip_DeflateConfiguration(8, 16, 32, 32), + new zip_DeflateConfiguration(8, 16, 128, 128), + new zip_DeflateConfiguration(8, 32, 128, 256), + new zip_DeflateConfiguration(32, 128, 258, 1024), + new zip_DeflateConfiguration(32, 258, 258, 4096)); + + + /* routines (deflate) */ + + var zip_deflate_start = function (level) { + var i; + + if (!level) + level = zip_DEFAULT_LEVEL; + else if (level < 1) + level = 1; + else if (level > 9) + level = 9; + + zip_compr_level = level; + zip_initflag = false; + zip_eofile = false; + if (zip_outbuf != null) + return; + + zip_free_queue = zip_qhead = zip_qtail = null; + zip_outbuf = new Array(zip_OUTBUFSIZ); + zip_window = new Array(zip_window_size); + zip_d_buf = new Array(zip_DIST_BUFSIZE); + zip_l_buf = new Array(zip_INBUFSIZ + zip_INBUF_EXTRA); + zip_prev = new Array(1 << zip_BITS); + zip_dyn_ltree = new Array(zip_HEAP_SIZE); + for (i = 0; i < zip_HEAP_SIZE; i++) zip_dyn_ltree[i] = new zip_DeflateCT(); + zip_dyn_dtree = new Array(2 * zip_D_CODES + 1); + for (i = 0; i < 2 * zip_D_CODES + 1; i++) zip_dyn_dtree[i] = new zip_DeflateCT(); + zip_static_ltree = new Array(zip_L_CODES + 2); + for (i = 0; i < zip_L_CODES + 2; i++) zip_static_ltree[i] = new zip_DeflateCT(); + zip_static_dtree = new Array(zip_D_CODES); + for (i = 0; i < zip_D_CODES; i++) zip_static_dtree[i] = new zip_DeflateCT(); + zip_bl_tree = new Array(2 * zip_BL_CODES + 1); + for (i = 0; i < 2 * zip_BL_CODES + 1; i++) zip_bl_tree[i] = new zip_DeflateCT(); + zip_l_desc = new zip_DeflateTreeDesc(); + zip_d_desc = new zip_DeflateTreeDesc(); + zip_bl_desc = new zip_DeflateTreeDesc(); + zip_bl_count = new Array(zip_MAX_BITS + 1); + zip_heap = new Array(2 * zip_L_CODES + 1); + zip_depth = new Array(2 * zip_L_CODES + 1); + zip_length_code = new Array(MAX_MATCH - MIN_MATCH + 1); + zip_dist_code = new Array(512); + zip_base_length = new Array(zip_LENGTH_CODES); + zip_base_dist = new Array(zip_D_CODES); + zip_flag_buf = new Array(parseInt(LIT_BUFSIZE / 8)); + }; + + var zip_deflate_end = function () { + zip_free_queue = zip_qhead = zip_qtail = null; + zip_outbuf = null; + zip_window = null; + zip_d_buf = null; + zip_l_buf = null; + zip_prev = null; + zip_dyn_ltree = null; + zip_dyn_dtree = null; + zip_static_ltree = null; + zip_static_dtree = null; + zip_bl_tree = null; + zip_l_desc = null; + zip_d_desc = null; + zip_bl_desc = null; + zip_bl_count = null; + zip_heap = null; + zip_depth = null; + zip_length_code = null; + zip_dist_code = null; + zip_base_length = null; + zip_base_dist = null; + zip_flag_buf = null; + }; + + var zip_reuse_queue = function (p) { + p.next = zip_free_queue; + zip_free_queue = p; + }; + + var zip_new_queue = function () { + var p; + + if (zip_free_queue != null) { + p = zip_free_queue; + zip_free_queue = zip_free_queue.next; + } + else + p = new zip_DeflateBuffer(); + p.next = null; + p.len = p.off = 0; + + return p; + }; + + var zip_head1 = function (i) { + return zip_prev[WSIZE + i]; + }; + + var zip_head2 = function (i, val) { + return zip_prev[WSIZE + i] = val; + }; + + /* put_byte is used for the compressed output, put_ubyte for the + * uncompressed output. However unlzw() uses window for its + * suffix table instead of its output buffer, so it does not use put_ubyte + * (to be cleaned up). + */ + var zip_put_byte = function (c) { + zip_outbuf[zip_outoff + zip_outcnt++] = c; + if (zip_outoff + zip_outcnt == zip_OUTBUFSIZ) + zip_qoutbuf(); + }; + + /* Output a 16 bit value, lsb first */ + var zip_put_short = function (w) { + w &= 0xffff; + if (zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) { + zip_outbuf[zip_outoff + zip_outcnt++] = (w & 0xff); + zip_outbuf[zip_outoff + zip_outcnt++] = (w >>> 8); + } else { + zip_put_byte(w & 0xff); + zip_put_byte(w >>> 8); + } + }; + + /* ========================================================================== + * Insert string s in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of s are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ + var zip_INSERT_STRING = function () { + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) + ^ (zip_window[zip_strstart + MIN_MATCH - 1] & 0xff)) + & zip_HASH_MASK; + zip_hash_head = zip_head1(zip_ins_h); + zip_prev[zip_strstart & zip_WMASK] = zip_hash_head; + zip_head2(zip_ins_h, zip_strstart); + }; + + /* Send a code of the given tree. c and tree must not have side effects */ + var zip_SEND_CODE = function (c, tree) { + zip_send_bits(tree[c].fc, tree[c].dl); + }; + + /* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. dist_code[256] and dist_code[257] are never + * used. + */ + var zip_D_CODE = function (dist) { + return (dist < 256 ? zip_dist_code[dist] + : zip_dist_code[256 + (dist >> 7)]) & 0xff; + }; + + /* ========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ + var zip_SMALLER = function (tree, n, m) { + return tree[n].fc < tree[m].fc || + (tree[n].fc == tree[m].fc && zip_depth[n] <= zip_depth[m]); + }; + + /* ========================================================================== + * read string data + */ + var zip_read_buff = function (buff, offset, n) { + var i; + for (i = 0; i < n && zip_deflate_pos < zip_deflate_data.length; i++) + buff[offset + i] = + zip_deflate_data[zip_deflate_pos++] & 0xff; + return i; + }; + + /* ========================================================================== + * Initialize the "longest match" routines for a new file + */ + var zip_lm_init = function () { + var j; + + /* Initialize the hash table. */ + for (j = 0; j < zip_HASH_SIZE; j++) + zip_prev[WSIZE + j] = 0; + zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy; + zip_good_match = zip_configuration_table[zip_compr_level].good_length; + if (!zip_FULL_SEARCH) + zip_nice_match = zip_configuration_table[zip_compr_level].nice_length; + zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain; + + zip_strstart = 0; + zip_block_start = 0; + + zip_lookahead = zip_read_buff(zip_window, 0, 2 * WSIZE); + if (zip_lookahead <= 0) { + zip_eofile = true; + zip_lookahead = 0; + return; + } + zip_eofile = false; + /* Make sure that we always have enough lookahead. This is important + * if input comes from a device such as a tty. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + + /* If lookahead < MIN_MATCH, ins_h is garbage, but this is + * not important since only literal bytes will be emitted. + */ + zip_ins_h = 0; + for (j = 0; j < MIN_MATCH - 1; j++) { + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[j] & 0xff)) & zip_HASH_MASK; + } + }; + + /* ========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + */ + var zip_longest_match = function (cur_match) { + var chain_length = zip_max_chain_length; // max hash chain length + var scanp = zip_strstart; // current string + var matchp; // matched string + var len; // length of current match + var best_len = zip_prev_length; // best match length so far + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + var limit = (zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL); + + var strendp = zip_strstart + MAX_MATCH; + var scan_end1 = zip_window[scanp + best_len - 1]; + var scan_end = zip_window[scanp + best_len]; + + /* Do not waste too much time if we already have a good match: */ + if (zip_prev_length >= zip_good_match) + chain_length >>= 2; + + do { + matchp = cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ + if (zip_window[matchp + best_len] != scan_end || + zip_window[matchp + best_len - 1] != scan_end1 || + zip_window[matchp] != zip_window[scanp] || + zip_window[++matchp] != zip_window[scanp + 1]) { + continue; + } + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scanp += 2; + matchp++; + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + scanp < strendp); + + len = MAX_MATCH - (strendp - scanp); + scanp = strendp - MAX_MATCH; + + if (len > best_len) { + zip_match_start = cur_match; + best_len = len; + if (zip_FULL_SEARCH) { + if (len >= MAX_MATCH) break; + } else { + if (len >= zip_nice_match) break; + } + + scan_end1 = zip_window[scanp + best_len - 1]; + scan_end = zip_window[scanp + best_len]; + } + } while ((cur_match = zip_prev[cur_match & zip_WMASK]) > limit + && --chain_length != 0); + + return best_len; + }; + + /* ========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead, and sets eofile if end of input file. + * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 + * OUT assertions: at least one byte has been read, or eofile is set; + * file reads are performed for at least two bytes (required for the + * translate_eol option). + */ + var zip_fill_window = function () { + var n, m; + + // Amount of free space at the end of the window. + var more = zip_window_size - zip_lookahead - zip_strstart; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (more == -1) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + } else if (zip_strstart >= WSIZE + zip_MAX_DIST) { + /* By the IN assertion, the window is not empty so we can't confuse + * more == 0 with more == 64K on a 16 bit machine. + */ + for (n = 0; n < WSIZE; n++) + zip_window[n] = zip_window[n + WSIZE]; + + zip_match_start -= WSIZE; + zip_strstart -= WSIZE; + /* we now have strstart >= MAX_DIST: */ + zip_block_start -= WSIZE; + + for (n = 0; n < zip_HASH_SIZE; n++) { + m = zip_head1(n); + zip_head2(n, m >= WSIZE ? m - WSIZE : zip_NIL); + } + for (n = 0; n < WSIZE; n++) { + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + m = zip_prev[n]; + zip_prev[n] = (m >= WSIZE ? m - WSIZE : zip_NIL); + } + more += WSIZE; + } + // At this point, more >= 2 + if (!zip_eofile) { + n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more); + if (n <= 0) + zip_eofile = true; + else + zip_lookahead += n; + } + }; + + /* ========================================================================== + * Processes a new input file and return its compressed length. This + * function does not perform lazy evaluationof matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ + var zip_deflate_fast = function () { + while (zip_lookahead != 0 && zip_qhead == null) { + var flush; // set if current block must be flushed + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + zip_INSERT_STRING(); + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (zip_hash_head != zip_NIL && + zip_strstart - zip_hash_head <= zip_MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + zip_match_length = zip_longest_match(zip_hash_head); + /* longest_match() sets match_start */ + if (zip_match_length > zip_lookahead) + zip_match_length = zip_lookahead; + } + if (zip_match_length >= MIN_MATCH) { + flush = zip_ct_tally(zip_strstart - zip_match_start, + zip_match_length - MIN_MATCH); + zip_lookahead -= zip_match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (zip_match_length <= zip_max_lazy_match) { + zip_match_length--; // string at strstart already in hash table + do { + zip_strstart++; + zip_INSERT_STRING(); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since + * the next lookahead bytes will be emitted as literals. + */ + } while (--zip_match_length != 0); + zip_strstart++; + } else { + zip_strstart += zip_match_length; + zip_match_length = 0; + zip_ins_h = zip_window[zip_strstart] & 0xff; + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[zip_strstart + 1] & 0xff)) & zip_HASH_MASK; + } + } else { + /* No match, output a literal byte */ + flush = zip_ct_tally(0, zip_window[zip_strstart] & 0xff); + zip_lookahead--; + zip_strstart++; + } + if (flush) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + } + }; + + var zip_deflate_better = function () { + /* Process the input block. */ + while (zip_lookahead != 0 && zip_qhead == null) { + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + zip_INSERT_STRING(); + + /* Find the longest match, discarding those <= prev_length. + */ + zip_prev_length = zip_match_length; + zip_prev_match = zip_match_start; + zip_match_length = MIN_MATCH - 1; + + if (zip_hash_head != zip_NIL && + zip_prev_length < zip_max_lazy_match && + zip_strstart - zip_hash_head <= zip_MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + zip_match_length = zip_longest_match(zip_hash_head); + /* longest_match() sets match_start */ + if (zip_match_length > zip_lookahead) + zip_match_length = zip_lookahead; + + /* Ignore a length 3 match if it is too distant: */ + if (zip_match_length == MIN_MATCH && + zip_strstart - zip_match_start > zip_TOO_FAR) { + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + zip_match_length--; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (zip_prev_length >= MIN_MATCH && + zip_match_length <= zip_prev_length) { + var flush; // set if current block must be flushed + flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match, + zip_prev_length - MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. + */ + zip_lookahead -= zip_prev_length - 1; + zip_prev_length -= 2; + do { + zip_strstart++; + zip_INSERT_STRING(); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since the + * next lookahead bytes will always be emitted as literals. + */ + } while (--zip_prev_length != 0); + zip_match_available = 0; + zip_match_length = MIN_MATCH - 1; + zip_strstart++; + if (flush) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + } else if (zip_match_available != 0) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + if (zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff)) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + zip_strstart++; + zip_lookahead--; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + zip_match_available = 1; + zip_strstart++; + zip_lookahead--; + } + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + } + }; + + var zip_init_deflate = function () { + if (zip_eofile) + return; + zip_bi_buf = 0; + zip_bi_valid = 0; + zip_ct_init(); + zip_lm_init(); + + zip_qhead = null; + zip_outcnt = 0; + zip_outoff = 0; + zip_match_available = 0; + + if (zip_compr_level <= 3) { + zip_prev_length = MIN_MATCH - 1; + zip_match_length = 0; + } + else { + zip_match_length = MIN_MATCH - 1; + zip_match_available = 0; + zip_match_available = 0; + } + + zip_complete = false; + }; + + /* ========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ + var zip_deflate_internal = function (buff, off, buff_size) { + var n; + + if (!zip_initflag) { + zip_init_deflate(); + zip_initflag = true; + if (zip_lookahead == 0) { // empty + zip_complete = true; + return 0; + } + } + + if ((n = zip_qcopy(buff, off, buff_size)) == buff_size) + return buff_size; + + if (zip_complete) + return n; + + if (zip_compr_level <= 3) // optimized for speed + zip_deflate_fast(); + else + zip_deflate_better(); + if (zip_lookahead == 0) { + if (zip_match_available != 0) + zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff); + zip_flush_block(1); + zip_complete = true; + } + return n + zip_qcopy(buff, n + off, buff_size - n); + }; + + var zip_qcopy = function (buff, off, buff_size) { + var n, i, j; + + n = 0; + while (zip_qhead != null && n < buff_size) { + i = buff_size - n; + if (i > zip_qhead.len) + i = zip_qhead.len; + for (j = 0; j < i; j++) + buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j]; + + zip_qhead.off += i; + zip_qhead.len -= i; + n += i; + if (zip_qhead.len == 0) { + var p; + p = zip_qhead; + zip_qhead = zip_qhead.next; + zip_reuse_queue(p); + } + } + + if (n == buff_size) + return n; + + if (zip_outoff < zip_outcnt) { + i = buff_size - n; + if (i > zip_outcnt - zip_outoff) + i = zip_outcnt - zip_outoff; + // System.arraycopy(outbuf, outoff, buff, off + n, i); + for (j = 0; j < i; j++) + buff[off + n + j] = zip_outbuf[zip_outoff + j]; + zip_outoff += i; + n += i; + if (zip_outcnt == zip_outoff) + zip_outcnt = zip_outoff = 0; + } + return n; + }; + + /* ========================================================================== + * Allocate the match buffer, initialize the various tables and save the + * location of the internal file attribute (ascii/binary) and method + * (DEFLATE/STORE). + */ + var zip_ct_init = function () { + var n; // iterates over tree elements + var bits; // bit counter + var length; // length value + var code; // code value + var dist; // distance index + + if (zip_static_dtree[0].dl != 0) return; // ct_init already called + + zip_l_desc.dyn_tree = zip_dyn_ltree; + zip_l_desc.static_tree = zip_static_ltree; + zip_l_desc.extra_bits = zip_extra_lbits; + zip_l_desc.extra_base = zip_LITERALS + 1; + zip_l_desc.elems = zip_L_CODES; + zip_l_desc.max_length = zip_MAX_BITS; + zip_l_desc.max_code = 0; + + zip_d_desc.dyn_tree = zip_dyn_dtree; + zip_d_desc.static_tree = zip_static_dtree; + zip_d_desc.extra_bits = zip_extra_dbits; + zip_d_desc.extra_base = 0; + zip_d_desc.elems = zip_D_CODES; + zip_d_desc.max_length = zip_MAX_BITS; + zip_d_desc.max_code = 0; + + zip_bl_desc.dyn_tree = zip_bl_tree; + zip_bl_desc.static_tree = null; + zip_bl_desc.extra_bits = zip_extra_blbits; + zip_bl_desc.extra_base = 0; + zip_bl_desc.elems = zip_BL_CODES; + zip_bl_desc.max_length = zip_MAX_BL_BITS; + zip_bl_desc.max_code = 0; + + // Initialize the mapping length (0..255) -> length code (0..28) + length = 0; + for (code = 0; code < zip_LENGTH_CODES - 1; code++) { + zip_base_length[code] = length; + for (n = 0; n < (1 << zip_extra_lbits[code]); n++) + zip_length_code[length++] = code; + } + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + zip_length_code[length - 1] = code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + zip_base_dist[code] = dist; + for (n = 0; n < (1 << zip_extra_dbits[code]); n++) { + zip_dist_code[dist++] = code; + } + } + dist >>= 7; // from now on, all distances are divided by 128 + for (; code < zip_D_CODES; code++) { + zip_base_dist[code] = dist << 7; + for (n = 0; n < (1 << (zip_extra_dbits[code] - 7)); n++) + zip_dist_code[256 + dist++] = code; + } + // Construct the codes of the static literal tree + for (bits = 0; bits <= zip_MAX_BITS; bits++) + zip_bl_count[bits] = 0; + n = 0; + while (n <= 143) { + zip_static_ltree[n++].dl = 8; + zip_bl_count[8]++; + } + while (n <= 255) { + zip_static_ltree[n++].dl = 9; + zip_bl_count[9]++; + } + while (n <= 279) { + zip_static_ltree[n++].dl = 7; + zip_bl_count[7]++; + } + while (n <= 287) { + zip_static_ltree[n++].dl = 8; + zip_bl_count[8]++; + } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + zip_gen_codes(zip_static_ltree, zip_L_CODES + 1); + + /* The static distance tree is trivial: */ + for (n = 0; n < zip_D_CODES; n++) { + zip_static_dtree[n].dl = 5; + zip_static_dtree[n].fc = zip_bi_reverse(n, 5); + } + + // Initialize the first block of the first file: + zip_init_block(); + }; + + /* ========================================================================== + * Initialize a new block. + */ + var zip_init_block = function () { + var n; // iterates over tree elements + + // Initialize the trees. + for (n = 0; n < zip_L_CODES; n++) zip_dyn_ltree[n].fc = 0; + for (n = 0; n < zip_D_CODES; n++) zip_dyn_dtree[n].fc = 0; + for (n = 0; n < zip_BL_CODES; n++) zip_bl_tree[n].fc = 0; + + zip_dyn_ltree[zip_END_BLOCK].fc = 1; + zip_opt_len = zip_static_len = 0; + zip_last_lit = zip_last_dist = zip_last_flags = 0; + zip_flags = 0; + zip_flag_bit = 1; + }; + + /* ========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ + var zip_pqdownheap = function (tree, // the tree to restore + k) { // node to move down + var v = zip_heap[k]; + var j = k << 1; // left son of k + + while (j <= zip_heap_len) { + // Set j to the smallest of the two sons: + if (j < zip_heap_len && + zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j])) + j++; + + // Exit if v is smaller than both sons + if (zip_SMALLER(tree, v, zip_heap[j])) + break; + + // Exchange v with the smallest son + zip_heap[k] = zip_heap[j]; + k = j; + + // And continue down the tree, setting j to the left son of k + j <<= 1; + } + zip_heap[k] = v; + }; + + /* ========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ + var zip_gen_bitlen = function (desc) { // the tree descriptor + var tree = desc.dyn_tree; + var extra = desc.extra_bits; + var base = desc.extra_base; + var max_code = desc.max_code; + var max_length = desc.max_length; + var stree = desc.static_tree; + var h; // heap index + var n, m; // iterate over the tree elements + var bits; // bit length + var xbits; // extra bits + var f; // frequency + var overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= zip_MAX_BITS; bits++) + zip_bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[zip_heap[zip_heap_max]].dl = 0; // root of the heap + + for (h = zip_heap_max + 1; h < zip_HEAP_SIZE; h++) { + n = zip_heap[h]; + bits = tree[tree[n].dl].dl + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n].dl = bits; + // We overwrite tree[n].dl which is no longer needed + + if (n > max_code) + continue; // not a leaf node + + zip_bl_count[bits]++; + xbits = 0; + if (n >= base) + xbits = extra[n - base]; + f = tree[n].fc; + zip_opt_len += f * (bits + xbits); + if (stree != null) + zip_static_len += f * (stree[n].dl + xbits); + } + if (overflow == 0) + return; + + // This happens for example on obj2 and pic of the Calgary corpus + + // Find the first bit length which could increase: + do { + bits = max_length - 1; + while (zip_bl_count[bits] == 0) + bits--; + zip_bl_count[bits]--; // move one leaf down the tree + zip_bl_count[bits + 1] += 2; // move one overflow item as its brother + zip_bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = zip_bl_count[bits]; + while (n != 0) { + m = zip_heap[--h]; + if (m > max_code) + continue; + if (tree[m].dl != bits) { + zip_opt_len += (bits - tree[m].dl) * tree[m].fc; + tree[m].fc = bits; + } + n--; + } + } + }; + + /* ========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ + var zip_gen_codes = function (tree, // the tree to decorate + max_code) { // largest code with non zero frequency + var next_code = new Array(zip_MAX_BITS + 1); // next code value for each bit length + var code = 0; // running code value + var bits; // bit index + var n; // code index + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= zip_MAX_BITS; bits++) { + code = ((code + zip_bl_count[bits - 1]) << 1); + next_code[bits] = code; + } + + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + for (n = 0; n <= max_code; n++) { + var len = tree[n].dl; + if (len == 0) + continue; + // Now reverse the bits + tree[n].fc = zip_bi_reverse(next_code[len]++, len); + } + }; + + /* ========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ + var zip_build_tree = function (desc) { // the tree descriptor + var tree = desc.dyn_tree; + var stree = desc.static_tree; + var elems = desc.elems; + var n, m; // iterate over heap elements + var max_code = -1; // largest code with non zero frequency + var node = elems; // next internal node of the tree + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + zip_heap_len = 0; + zip_heap_max = zip_HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].fc != 0) { + zip_heap[++zip_heap_len] = max_code = n; + zip_depth[n] = 0; + } else + tree[n].dl = 0; + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (zip_heap_len < 2) { + var xnew = zip_heap[++zip_heap_len] = (max_code < 2 ? ++max_code : 0); + tree[xnew].fc = 1; + zip_depth[xnew] = 0; + zip_opt_len--; + if (stree != null) + zip_static_len -= stree[xnew].dl; + // new is 0 or 1 so it does not have extra bits + } + desc.max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = zip_heap_len >> 1; n >= 1; n--) + zip_pqdownheap(tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + do { + n = zip_heap[zip_SMALLEST]; + zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--]; + zip_pqdownheap(tree, zip_SMALLEST); + + m = zip_heap[zip_SMALLEST]; // m = node of next least frequency + + // keep the nodes sorted by frequency + zip_heap[--zip_heap_max] = n; + zip_heap[--zip_heap_max] = m; + + // Create a new node father of n and m + tree[node].fc = tree[n].fc + tree[m].fc; + if (zip_depth[n] > zip_depth[m] + 1) + zip_depth[node] = zip_depth[n]; + else + zip_depth[node] = zip_depth[m] + 1; + tree[n].dl = tree[m].dl = node; + + // and insert the new node in the heap + zip_heap[zip_SMALLEST] = node++; + zip_pqdownheap(tree, zip_SMALLEST); + + } while (zip_heap_len >= 2); + + zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + zip_gen_bitlen(desc); + + // The field len is now set, we can generate the bit codes + zip_gen_codes(tree, max_code); + }; + + /* ========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. Updates opt_len to take into account the repeat + * counts. (The contribution of the bit length codes will be added later + * during the construction of bl_tree.) + */ + var zip_scan_tree = function (tree,// the tree to be scanned + max_code) { // and its largest code of non zero frequency + var n; // iterates over all tree elements + var prevlen = -1; // last emitted length + var curlen; // length of current code + var nextlen = tree[0].dl; // length of next code + var count = 0; // repeat count of the current code + var max_count = 7; // max repeat count + var min_count = 4; // min repeat count + + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } + tree[max_code + 1].dl = 0xffff; // guard + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n + 1].dl; + if (++count < max_count && curlen == nextlen) + continue; + else if (count < min_count) + zip_bl_tree[curlen].fc += count; + else if (curlen != 0) { + if (curlen != prevlen) + zip_bl_tree[curlen].fc++; + zip_bl_tree[zip_REP_3_6].fc++; + } else if (count <= 10) + zip_bl_tree[zip_REPZ_3_10].fc++; + else + zip_bl_tree[zip_REPZ_11_138].fc++; + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } else if (curlen == nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + }; + + /* ========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ + var zip_send_tree = function (tree, // the tree to be scanned + max_code) { // and its largest code of non zero frequency + var n; // iterates over all tree elements + var prevlen = -1; // last emitted length + var curlen; // length of current code + var nextlen = tree[0].dl; // length of next code + var count = 0; // repeat count of the current code + var max_count = 7; // max repeat count + var min_count = 4; // min repeat count + + /* tree[max_code+1].dl = -1; */ + /* guard already set */ + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n + 1].dl; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { + zip_SEND_CODE(curlen, zip_bl_tree); + } while (--count != 0); + } else if (curlen != 0) { + if (curlen != prevlen) { + zip_SEND_CODE(curlen, zip_bl_tree); + count--; + } + // Assert(count >= 3 && count <= 6, " 3_6?"); + zip_SEND_CODE(zip_REP_3_6, zip_bl_tree); + zip_send_bits(count - 3, 2); + } else if (count <= 10) { + zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree); + zip_send_bits(count - 3, 3); + } else { + zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree); + zip_send_bits(count - 11, 7); + } + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } else if (curlen == nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + }; + + /* ========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ + var zip_build_bl_tree = function () { + var max_blindex; // index of last bit length code of non zero freq + + // Determine the bit length frequencies for literal and distance trees + zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code); + zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code); + + // Build the bit length tree: + zip_build_tree(zip_bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = zip_BL_CODES - 1; max_blindex >= 3; max_blindex--) { + if (zip_bl_tree[zip_bl_order[max_blindex]].dl != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + zip_opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + return max_blindex; + }; + + /* ========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ + var zip_send_all_trees = function (lcodes, dcodes, blcodes) { // number of codes for each tree + var rank; // index in bl_order + zip_send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt + zip_send_bits(dcodes - 1, 5); + zip_send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) { + zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3); + } + + // send the literal tree + zip_send_tree(zip_dyn_ltree, lcodes - 1); + + // send the distance tree + zip_send_tree(zip_dyn_dtree, dcodes - 1); + }; + + /* ========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ + var zip_flush_block = function (eof) { // true if this is the last block for a file + var opt_lenb, static_lenb; // opt_len and static_len in bytes + var max_blindex; // index of last bit length code of non zero freq + var stored_len; // length of input block + + stored_len = zip_strstart - zip_block_start; + zip_flag_buf[zip_last_flags] = zip_flags; // Save the flags for the last 8 items + + // Construct the literal and distance trees + zip_build_tree(zip_l_desc); + zip_build_tree(zip_d_desc); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = zip_build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb = (zip_opt_len + 3 + 7) >> 3; + static_lenb = (zip_static_len + 3 + 7) >> 3; + if (static_lenb <= opt_lenb) + opt_lenb = static_lenb; + if (stored_len + 4 <= opt_lenb // 4: two words for the lengths + && zip_block_start >= 0) { + var i; + + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + zip_send_bits((zip_STORED_BLOCK << 1) + eof, 3); + /* send block type */ + zip_bi_windup(); + /* align on byte boundary */ + zip_put_short(stored_len); + zip_put_short(~stored_len); + + // copy block + for (i = 0; i < stored_len; i++) + zip_put_byte(zip_window[zip_block_start + i]); + + } else if (static_lenb == opt_lenb) { + zip_send_bits((zip_STATIC_TREES << 1) + eof, 3); + zip_compress_block(zip_static_ltree, zip_static_dtree); + } else { + zip_send_bits((zip_DYN_TREES << 1) + eof, 3); + zip_send_all_trees(zip_l_desc.max_code + 1, + zip_d_desc.max_code + 1, + max_blindex + 1); + zip_compress_block(zip_dyn_ltree, zip_dyn_dtree); + } + + zip_init_block(); + + if (eof != 0) + zip_bi_windup(); + }; + + /* ========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ + var zip_ct_tally = function (dist, // distance of matched string + lc) { // match length-MIN_MATCH or unmatched char (if dist==0) + zip_l_buf[zip_last_lit++] = lc; + if (dist == 0) { + // lc is the unmatched char + zip_dyn_ltree[lc].fc++; + } else { + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + zip_dyn_ltree[zip_length_code[lc] + zip_LITERALS + 1].fc++; + zip_dyn_dtree[zip_D_CODE(dist)].fc++; + + zip_d_buf[zip_last_dist++] = dist; + zip_flags |= zip_flag_bit; + } + zip_flag_bit <<= 1; + + // Output the flags if they fill a byte + if ((zip_last_lit & 7) == 0) { + zip_flag_buf[zip_last_flags++] = zip_flags; + zip_flags = 0; + zip_flag_bit = 1; + } + // Try to guess if it is profitable to stop the current block here + if (zip_compr_level > 2 && (zip_last_lit & 0xfff) == 0) { + // Compute an upper bound for the compressed length + var out_length = zip_last_lit * 8; + var in_length = zip_strstart - zip_block_start; + var dcode; + + for (dcode = 0; dcode < zip_D_CODES; dcode++) { + out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]); + } + out_length >>= 3; + if (zip_last_dist < parseInt(zip_last_lit / 2) && + out_length < parseInt(in_length / 2)) + return true; + } + return (zip_last_lit == LIT_BUFSIZE - 1 || + zip_last_dist == zip_DIST_BUFSIZE); + /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + }; + + /* ========================================================================== + * Send the block data compressed using the given Huffman trees + */ + var zip_compress_block = function (ltree, // literal tree + dtree) { // distance tree + var dist; // distance of matched string + var lc; // match length or unmatched char (if dist == 0) + var lx = 0; // running index in l_buf + var dx = 0; // running index in d_buf + var fx = 0; // running index in flag_buf + var flag = 0; // current flags + var code; // the code to send + var extra; // number of extra bits to send + + if (zip_last_lit != 0) do { + if ((lx & 7) == 0) + flag = zip_flag_buf[fx++]; + lc = zip_l_buf[lx++] & 0xff; + if ((flag & 1) == 0) { + zip_SEND_CODE(lc, ltree); + /* send a literal byte */ + } else { + // Here, lc is the match length - MIN_MATCH + code = zip_length_code[lc]; + zip_SEND_CODE(code + zip_LITERALS + 1, ltree); // send the length code + extra = zip_extra_lbits[code]; + if (extra != 0) { + lc -= zip_base_length[code]; + zip_send_bits(lc, extra); // send the extra length bits + } + dist = zip_d_buf[dx++]; + // Here, dist is the match distance - 1 + code = zip_D_CODE(dist); + zip_SEND_CODE(code, dtree); // send the distance code + extra = zip_extra_dbits[code]; + if (extra != 0) { + dist -= zip_base_dist[code]; + zip_send_bits(dist, extra); // send the extra distance bits + } + } // literal or match pair ? + flag >>= 1; + } while (lx < zip_last_lit); + + zip_SEND_CODE(zip_END_BLOCK, ltree); + }; + + /* ========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ + var zip_Buf_size = 16; // bit size of bi_buf + var zip_send_bits = function (value, // value to send + length) { // number of bits + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (zip_bi_valid > zip_Buf_size - length) { + zip_bi_buf |= (value << zip_bi_valid); + zip_put_short(zip_bi_buf); + zip_bi_buf = (value >> (zip_Buf_size - zip_bi_valid)); + zip_bi_valid += length - zip_Buf_size; + } else { + zip_bi_buf |= value << zip_bi_valid; + zip_bi_valid += length; + } + }; + + /* ========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ + var zip_bi_reverse = function (code, // the value to invert + len) { // its bit length + var res = 0; + do { + res |= code & 1; + code >>= 1; + res <<= 1; + } while (--len > 0); + return res >> 1; + }; + + /* ========================================================================== + * Write out any remaining bits in an incomplete byte. + */ + var zip_bi_windup = function () { + if (zip_bi_valid > 8) { + zip_put_short(zip_bi_buf); + } else if (zip_bi_valid > 0) { + zip_put_byte(zip_bi_buf); + } + zip_bi_buf = 0; + zip_bi_valid = 0; + }; + + var zip_qoutbuf = function () { + if (zip_outcnt != 0) { + var q, i; + q = zip_new_queue(); + if (zip_qhead == null) + zip_qhead = zip_qtail = q; + else + zip_qtail = zip_qtail.next = q; + q.len = zip_outcnt - zip_outoff; + for (i = 0; i < q.len; i++) + q.ptr[i] = zip_outbuf[zip_outoff + i]; + zip_outcnt = zip_outoff = 0; + } + }; + + function deflate(buffData, level) { + zip_deflate_data = buffData; + zip_deflate_pos = 0; + zip_deflate_start(level); + + var buff = new Array(1024), + pages = [], + totalSize = 0, + i; + + for (i = 0; i < 1024; i++) buff[i] = 0; + while ((i = zip_deflate_internal(buff, 0, buff.length)) > 0) { + var buf = new Buffer(buff.slice(0, i)); + pages.push(buf); + totalSize += buf.length; + } + + if (pages.length == 1) { + return pages[0]; + } + + var result = new Buffer(totalSize), + index = 0; + + for (i = 0; i < pages.length; i++) { + pages[i].copy(result, index); + index = index + pages[i].length + } + + return result; + } + + return { + deflate: function () { + return deflate(inbuf, 8); + } + } +} + +module.exports = function (/*Buffer*/inbuf) { + + var zlib = require("zlib"); + + return { + deflate: function () { + return new JSDeflater(inbuf).deflate(); + }, + + deflateAsync: function (/*Function*/callback) { + var tmp = zlib.createDeflateRaw({chunkSize:(parseInt(inbuf.length / 1024) + 1)*1024}), + parts = [], total = 0; + tmp.on('data', function(data) { + parts.push(data); + total += data.length; + }); + tmp.on('end', function() { + var buf = new Buffer(total), written = 0; + buf.fill(0); + + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + part.copy(buf, written); + written += part.length; + } + callback && callback(buf); + }); + tmp.end(inbuf); + } + } +}; diff --git a/platforms/android/assets/www/node_modules/adm-zip/methods/index.js b/platforms/android/assets/www/node_modules/adm-zip/methods/index.js new file mode 100644 index 0000000..ddcbba6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/methods/index.js @@ -0,0 +1,2 @@ +exports.Deflater = require("./deflater"); +exports.Inflater = require("./inflater"); \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/adm-zip/methods/inflater.js b/platforms/android/assets/www/node_modules/adm-zip/methods/inflater.js new file mode 100644 index 0000000..59536c9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/methods/inflater.js @@ -0,0 +1,448 @@ +var Buffer = require("buffer").Buffer; + +function JSInflater(/*Buffer*/input) { + + var WSIZE = 0x8000, + slide = new Buffer(0x10000), + windowPos = 0, + fixedTableList = null, + fixedTableDist, + fixedLookup, + bitBuf = 0, + bitLen = 0, + method = -1, + eof = false, + copyLen = 0, + copyDist = 0, + tblList, tblDist, bitList, bitdist, + + inputPosition = 0, + + MASK_BITS = [0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff], + LENS = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0], + LEXT = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99], + DISTS = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577], + DEXT = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13], + BITORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; + + function HuffTable(clen, cnum, cval, blist, elist, lookupm) { + + this.status = 0; + this.root = null; + this.maxbit = 0; + + var el, f, tail, + offsets = [], + countTbl = [], + sTbl = [], + values = [], + tentry = {extra: 0, bitcnt: 0, lbase: 0, next: null}; + + tail = this.root = null; + for(var i = 0; i < 0x11; i++) { countTbl[i] = 0; sTbl[i] = 0; offsets[i] = 0; } + for(i = 0; i < 0x120; i++) values[i] = 0; + + el = cnum > 256 ? clen[256] : 16; + + var pidx = -1; + while (++pidx < cnum) countTbl[clen[pidx]]++; + + if(countTbl[0] == cnum) return; + + for(var j = 1; j <= 16; j++) if(countTbl[j] != 0) break; + var bitLen = j; + for(i = 16; i != 0; i--) if(countTbl[i] != 0) break; + var maxLen = i; + + lookupm < j && (lookupm = j); + + var dCodes = 1 << j; + for(; j < i; j++, dCodes <<= 1) + if((dCodes -= countTbl[j]) < 0) { + this.status = 2; + this.maxbit = lookupm; + return; + } + + if((dCodes -= countTbl[i]) < 0) { + this.status = 2; + this.maxbit = lookupm; + return; + } + + countTbl[i] += dCodes; + offsets[1] = j = 0; + pidx = 1; + var xp = 2; + while(--i > 0) offsets[xp++] = (j += countTbl[pidx++]); + pidx = 0; + i = 0; + do { + (j = clen[pidx++]) && (values[offsets[j]++] = i); + } while(++i < cnum); + cnum = offsets[maxLen]; + offsets[0] = i = 0; + pidx = 0; + + var level = -1, + w = sTbl[0] = 0, + cnode = null, + tblCnt = 0, + tblStack = []; + + for(; bitLen <= maxLen; bitLen++) { + var kccnt = countTbl[bitLen]; + while(kccnt-- > 0) { + while(bitLen > w + sTbl[1 + level]) { + w += sTbl[1 + level]; + level++; + tblCnt = (tblCnt = maxLen - w) > lookupm ? lookupm : tblCnt; + if((f = 1 << (j = bitLen - w)) > kccnt + 1) { + f -= kccnt + 1; + xp = bitLen; + while(++j < tblCnt) { + if((f <<= 1) <= countTbl[++xp]) break; + f -= countTbl[xp]; + } + } + if(w + j > el && w < el) j = el - w; + tblCnt = 1 << j; + sTbl[1 + level] = j; + cnode = []; + while (cnode.length < tblCnt) cnode.push({extra: 0, bitcnt: 0, lbase: 0, next: null}); + if (tail == null) { + tail = this.root = {next:null, list:null}; + } else { + tail = tail.next = {next:null, list:null} + } + tail.next = null; + tail.list = cnode; + + tblStack[level] = cnode; + + if(level > 0) { + offsets[level] = i; + tentry.bitcnt = sTbl[level]; + tentry.extra = 16 + j; + tentry.next = cnode; + j = (i & ((1 << w) - 1)) >> (w - sTbl[level]); + + tblStack[level-1][j].extra = tentry.extra; + tblStack[level-1][j].bitcnt = tentry.bitcnt; + tblStack[level-1][j].lbase = tentry.lbase; + tblStack[level-1][j].next = tentry.next; + } + } + tentry.bitcnt = bitLen - w; + if(pidx >= cnum) + tentry.extra = 99; + else if(values[pidx] < cval) { + tentry.extra = (values[pidx] < 256 ? 16 : 15); + tentry.lbase = values[pidx++]; + } else { + tentry.extra = elist[values[pidx] - cval]; + tentry.lbase = blist[values[pidx++] - cval]; + } + + f = 1 << (bitLen - w); + for(j = i >> w; j < tblCnt; j += f) { + cnode[j].extra = tentry.extra; + cnode[j].bitcnt = tentry.bitcnt; + cnode[j].lbase = tentry.lbase; + cnode[j].next = tentry.next; + } + for(j = 1 << (bitLen - 1); (i & j) != 0; j >>= 1) + i ^= j; + i ^= j; + while((i & ((1 << w) - 1)) != offsets[level]) { + w -= sTbl[level]; + level--; + } + } + } + + this.maxbit = sTbl[1]; + this.status = ((dCodes != 0 && maxLen != 1) ? 1 : 0); + } + + function addBits(n) { + while(bitLen < n) { + bitBuf |= input[inputPosition++] << bitLen; + bitLen += 8; + } + return bitBuf; + } + + function cutBits(n) { + bitLen -= n; + return bitBuf >>= n; + } + + function maskBits(n) { + while(bitLen < n) { + bitBuf |= input[inputPosition++] << bitLen; + bitLen += 8; + } + var res = bitBuf & MASK_BITS[n]; + bitBuf >>= n; + bitLen -= n; + return res; + } + + function codes(buff, off, size) { + var e, t; + if(size == 0) return 0; + + var n = 0; + for(;;) { + t = tblList.list[addBits(bitList) & MASK_BITS[bitList]]; + e = t.extra; + while(e > 16) { + if(e == 99) return -1; + cutBits(t.bitcnt); + e -= 16; + t = t.next[addBits(e) & MASK_BITS[e]]; + e = t.extra; + } + cutBits(t.bitcnt); + if(e == 16) { + windowPos &= WSIZE - 1; + buff[off + n++] = slide[windowPos++] = t.lbase; + if(n == size) return size; + continue; + } + if(e == 15) break; + + copyLen = t.lbase + maskBits(e); + t = tblDist.list[addBits(bitdist) & MASK_BITS[bitdist]]; + e = t.extra; + + while(e > 16) { + if(e == 99) return -1; + cutBits(t.bitcnt); + e -= 16; + t = t.next[addBits(e) & MASK_BITS[e]]; + e = t.extra + } + cutBits(t.bitcnt); + copyDist = windowPos - t.lbase - maskBits(e); + + while(copyLen > 0 && n < size) { + copyLen--; + copyDist &= WSIZE - 1; + windowPos &= WSIZE - 1; + buff[off + n++] = slide[windowPos++] = slide[copyDist++]; + } + + if(n == size) return size; + } + + method = -1; // done + return n; + } + + function stored(buff, off, size) { + cutBits(bitLen & 7); + var n = maskBits(0x10); + if(n != ((~maskBits(0x10)) & 0xffff)) return -1; + copyLen = n; + + n = 0; + while(copyLen > 0 && n < size) { + copyLen--; + windowPos &= WSIZE - 1; + buff[off + n++] = slide[windowPos++] = maskBits(8); + } + + if(copyLen == 0) method = -1; + return n; + } + + function fixed(buff, off, size) { + var fixed_bd = 0; + if(fixedTableList == null) { + var lengths = []; + + for(var symbol = 0; symbol < 144; symbol++) lengths[symbol] = 8; + for(; symbol < 256; symbol++) lengths[symbol] = 9; + for(; symbol < 280; symbol++) lengths[symbol] = 7; + for(; symbol < 288; symbol++) lengths[symbol] = 8; + + fixedLookup = 7; + + var htbl = new HuffTable(lengths, 288, 257, LENS, LEXT, fixedLookup); + + if(htbl.status != 0) return -1; + + fixedTableList = htbl.root; + fixedLookup = htbl.maxbit; + + for(symbol = 0; symbol < 30; symbol++) lengths[symbol] = 5; + fixed_bd = 5; + + htbl = new HuffTable(lengths, 30, 0, DISTS, DEXT, fixed_bd); + if(htbl.status > 1) { + fixedTableList = null; + return -1; + } + fixedTableDist = htbl.root; + fixed_bd = htbl.maxbit; + } + + tblList = fixedTableList; + tblDist = fixedTableDist; + bitList = fixedLookup; + bitdist = fixed_bd; + return codes(buff, off, size); + } + + function dynamic(buff, off, size) { + var ll = new Array(0x023C); + + for (var m = 0; m < 0x023C; m++) ll[m] = 0; + + var llencnt = 257 + maskBits(5), + dcodescnt = 1 + maskBits(5), + bitlencnt = 4 + maskBits(4); + + if(llencnt > 286 || dcodescnt > 30) return -1; + + for(var j = 0; j < bitlencnt; j++) ll[BITORDER[j]] = maskBits(3); + for(; j < 19; j++) ll[BITORDER[j]] = 0; + + // build decoding table for trees--single level, 7 bit lookup + bitList = 7; + var hufTable = new HuffTable(ll, 19, 19, null, null, bitList); + if(hufTable.status != 0) + return -1; // incomplete code set + + tblList = hufTable.root; + bitList = hufTable.maxbit; + var lencnt = llencnt + dcodescnt, + i = 0, + lastLen = 0; + while(i < lencnt) { + var hufLcode = tblList.list[addBits(bitList) & MASK_BITS[bitList]]; + j = hufLcode.bitcnt; + cutBits(j); + j = hufLcode.lbase; + if(j < 16) + ll[i++] = lastLen = j; + else if(j == 16) { + j = 3 + maskBits(2); + if(i + j > lencnt) return -1; + while(j-- > 0) ll[i++] = lastLen; + } else if(j == 17) { + j = 3 + maskBits(3); + if(i + j > lencnt) return -1; + while(j-- > 0) ll[i++] = 0; + lastLen = 0; + } else { + j = 11 + maskBits(7); + if(i + j > lencnt) return -1; + while(j-- > 0) ll[i++] = 0; + lastLen = 0; + } + } + bitList = 9; + hufTable = new HuffTable(ll, llencnt, 257, LENS, LEXT, bitList); + bitList == 0 && (hufTable.status = 1); + + if (hufTable.status != 0) return -1; + + tblList = hufTable.root; + bitList = hufTable.maxbit; + + for(i = 0; i < dcodescnt; i++) ll[i] = ll[i + llencnt]; + bitdist = 6; + hufTable = new HuffTable(ll, dcodescnt, 0, DISTS, DEXT, bitdist); + tblDist = hufTable.root; + bitdist = hufTable.maxbit; + + if((bitdist == 0 && llencnt > 257) || hufTable.status != 0) return -1; + + return codes(buff, off, size); + } + + return { + inflate : function(/*Buffer*/outputBuffer) { + tblList = null; + + var size = outputBuffer.length, + offset = 0, i; + + while(offset < size) { + if(eof && method == -1) return; + if(copyLen > 0) { + if(method != 0) { + while(copyLen > 0 && offset < size) { + copyLen--; + copyDist &= WSIZE - 1; + windowPos &= WSIZE - 1; + outputBuffer[offset++] = (slide[windowPos++] = slide[copyDist++]); + } + } else { + while(copyLen > 0 && offset < size) { + copyLen--; + windowPos &= WSIZE - 1; + outputBuffer[offset++] = (slide[windowPos++] = maskBits(8)); + } + copyLen == 0 && (method = -1); // done + } + if (offset == size) return; + } + + if(method == -1) { + if(eof) break; + eof = maskBits(1) != 0; + method = maskBits(2); + tblList = null; + copyLen = 0; + } + switch(method) { + case 0: i = stored(outputBuffer, offset, size - offset); break; + case 1: i = tblList != null ? codes(outputBuffer, offset, size - offset) : fixed(outputBuffer, offset, size - offset); break; + case 2: i = tblList != null ? codes(outputBuffer, offset, size - offset) : dynamic(outputBuffer, offset, size - offset); break; + default: i = -1; break; + } + + if(i == -1) return; + offset += i; + } + } + }; +} + +module.exports = function(/*Buffer*/inbuf) { + var zlib = require("zlib"); + return { + inflateAsync : function(/*Function*/callback) { + var tmp = zlib.createInflateRaw(), + parts = [], total = 0; + tmp.on('data', function(data) { + parts.push(data); + total += data.length; + }); + tmp.on('end', function() { + var buf = new Buffer(total), written = 0; + buf.fill(0); + + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + part.copy(buf, written); + written += part.length; + } + callback && callback(buf); + }); + tmp.end(inbuf) + }, + + inflate : function(/*Buffer*/outputBuffer) { + var x = { + x: new JSInflater(inbuf) + }; + x.x.inflate(outputBuffer); + delete(x.x); + } + } +}; diff --git a/platforms/android/assets/www/node_modules/adm-zip/package.json b/platforms/android/assets/www/node_modules/adm-zip/package.json new file mode 100644 index 0000000..d1f56d4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/package.json @@ -0,0 +1,83 @@ +{ + "_args": [ + [ + "adm-zip@0.4.4", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver" + ] + ], + "_from": "adm-zip@0.4.4", + "_id": "adm-zip@0.4.4", + "_inCache": true, + "_installable": true, + "_location": "/adm-zip", + "_npmUser": { + "email": "iacob.campia@gmail.com", + "name": "cthackers" + }, + "_npmVersion": "1.3.24", + "_phantomChildren": {}, + "_requested": { + "name": "adm-zip", + "raw": "adm-zip@0.4.4", + "rawSpec": "0.4.4", + "scope": null, + "spec": "0.4.4", + "type": "version" + }, + "_requiredBy": [ + "/selenium-webdriver" + ], + "_resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz", + "_shasum": "a61ed5ae6905c3aea58b3a657d25033091052736", + "_shrinkwrap": null, + "_spec": "adm-zip@0.4.4", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver", + "author": { + "email": "sy@another-d-mention.ro", + "name": "Nasca Iacob", + "url": "https://github.com/cthackers" + }, + "bugs": { + "email": "sy@another-d-mention.ro", + "url": "https://github.com/cthackers/adm-zip/issues" + }, + "dependencies": {}, + "description": "A Javascript implementation of zip for nodejs. Allows user to create or extract zip files both in memory or to/from disk", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "a61ed5ae6905c3aea58b3a657d25033091052736", + "tarball": "http://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz" + }, + "engines": { + "node": ">=0.3.0" + }, + "homepage": "http://github.com/cthackers/adm-zip", + "keywords": [ + "zip", + "methods", + "archive", + "unzip" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://raw.github.com/cthackers/adm-zip/master/MIT-LICENSE.txt" + } + ], + "main": "adm-zip.js", + "maintainers": [ + { + "email": "iacob.campia@gmail.com", + "name": "cthackers" + } + ], + "name": "adm-zip", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/cthackers/adm-zip.git" + }, + "version": "0.4.4" +} diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test.zip b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test.zip new file mode 100644 index 0000000..d57bfc0 Binary files /dev/null and b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test.zip differ diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden.txt b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden.txt new file mode 100644 index 0000000..3c3ca55 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden.txt @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden_readonly.txt b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden_readonly.txt new file mode 100644 index 0000000..3c3ca55 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden_readonly.txt @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/readonly.txt b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/readonly.txt new file mode 100644 index 0000000..3c3ca55 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/readonly.txt @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/somefile.txt b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/somefile.txt new file mode 100644 index 0000000..3c3ca55 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/New folder/somefile.txt @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/asd/New Text Document.txt b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/asd/New Text Document.txt new file mode 100644 index 0000000..e69de29 diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/blank file.txt b/platforms/android/assets/www/node_modules/adm-zip/test/assets/attributes_test/blank file.txt new file mode 100644 index 0000000..e69de29 diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/fast.zip b/platforms/android/assets/www/node_modules/adm-zip/test/assets/fast.zip new file mode 100644 index 0000000..f4ed17b Binary files /dev/null and b/platforms/android/assets/www/node_modules/adm-zip/test/assets/fast.zip differ diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/fastest.zip b/platforms/android/assets/www/node_modules/adm-zip/test/assets/fastest.zip new file mode 100644 index 0000000..f4ed17b Binary files /dev/null and b/platforms/android/assets/www/node_modules/adm-zip/test/assets/fastest.zip differ diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/linux_arc.zip b/platforms/android/assets/www/node_modules/adm-zip/test/assets/linux_arc.zip new file mode 100644 index 0000000..188eccb Binary files /dev/null and b/platforms/android/assets/www/node_modules/adm-zip/test/assets/linux_arc.zip differ diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/maximum.zip b/platforms/android/assets/www/node_modules/adm-zip/test/assets/maximum.zip new file mode 100644 index 0000000..86a8ec7 Binary files /dev/null and b/platforms/android/assets/www/node_modules/adm-zip/test/assets/maximum.zip differ diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/normal.zip b/platforms/android/assets/www/node_modules/adm-zip/test/assets/normal.zip new file mode 100644 index 0000000..b4602c9 Binary files /dev/null and b/platforms/android/assets/www/node_modules/adm-zip/test/assets/normal.zip differ diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/store.zip b/platforms/android/assets/www/node_modules/adm-zip/test/assets/store.zip new file mode 100644 index 0000000..e2add30 Binary files /dev/null and b/platforms/android/assets/www/node_modules/adm-zip/test/assets/store.zip differ diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/assets/ultra.zip b/platforms/android/assets/www/node_modules/adm-zip/test/assets/ultra.zip new file mode 100644 index 0000000..86a8ec7 Binary files /dev/null and b/platforms/android/assets/www/node_modules/adm-zip/test/assets/ultra.zip differ diff --git a/platforms/android/assets/www/node_modules/adm-zip/test/index.js b/platforms/android/assets/www/node_modules/adm-zip/test/index.js new file mode 100644 index 0000000..70acb51 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/test/index.js @@ -0,0 +1,5 @@ +var Attr = require("../util").FileAttr, + Zip = require("../adm-zip"), + fs = require("fs"); + +//zip.addLocalFile("./test/readonly.txt"); diff --git a/platforms/android/assets/www/node_modules/adm-zip/util/constants.js b/platforms/android/assets/www/node_modules/adm-zip/util/constants.js new file mode 100644 index 0000000..0548054 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/util/constants.js @@ -0,0 +1,84 @@ +module.exports = { + /* The local file header */ + LOCHDR : 30, // LOC header size + LOCSIG : 0x04034b50, // "PK\003\004" + LOCVER : 4, // version needed to extract + LOCFLG : 6, // general purpose bit flag + LOCHOW : 8, // compression method + LOCTIM : 10, // modification time (2 bytes time, 2 bytes date) + LOCCRC : 14, // uncompressed file crc-32 value + LOCSIZ : 18, // compressed size + LOCLEN : 22, // uncompressed size + LOCNAM : 26, // filename length + LOCEXT : 28, // extra field length + + /* The Data descriptor */ + EXTSIG : 0x08074b50, // "PK\007\008" + EXTHDR : 16, // EXT header size + EXTCRC : 4, // uncompressed file crc-32 value + EXTSIZ : 8, // compressed size + EXTLEN : 12, // uncompressed size + + /* The central directory file header */ + CENHDR : 46, // CEN header size + CENSIG : 0x02014b50, // "PK\001\002" + CENVEM : 4, // version made by + CENVER : 6, // version needed to extract + CENFLG : 8, // encrypt, decrypt flags + CENHOW : 10, // compression method + CENTIM : 12, // modification time (2 bytes time, 2 bytes date) + CENCRC : 16, // uncompressed file crc-32 value + CENSIZ : 20, // compressed size + CENLEN : 24, // uncompressed size + CENNAM : 28, // filename length + CENEXT : 30, // extra field length + CENCOM : 32, // file comment length + CENDSK : 34, // volume number start + CENATT : 36, // internal file attributes + CENATX : 38, // external file attributes (host system dependent) + CENOFF : 42, // LOC header offset + + /* The entries in the end of central directory */ + ENDHDR : 22, // END header size + ENDSIG : 0x06054b50, // "PK\005\006" + ENDSUB : 8, // number of entries on this disk + ENDTOT : 10, // total number of entries + ENDSIZ : 12, // central directory size in bytes + ENDOFF : 16, // offset of first CEN header + ENDCOM : 20, // zip file comment length + + /* Compression methods */ + STORED : 0, // no compression + SHRUNK : 1, // shrunk + REDUCED1 : 2, // reduced with compression factor 1 + REDUCED2 : 3, // reduced with compression factor 2 + REDUCED3 : 4, // reduced with compression factor 3 + REDUCED4 : 5, // reduced with compression factor 4 + IMPLODED : 6, // imploded + // 7 reserved + DEFLATED : 8, // deflated + ENHANCED_DEFLATED: 9, // enhanced deflated + PKWARE : 10,// PKWare DCL imploded + // 11 reserved + BZIP2 : 12, // compressed using BZIP2 + // 13 reserved + LZMA : 14, // LZMA + // 15-17 reserved + IBM_TERSE : 18, // compressed using IBM TERSE + IBM_LZ77 : 19, //IBM LZ77 z + + /* General purpose bit flag */ + FLG_ENC : 0, // encripted file + FLG_COMP1 : 1, // compression option + FLG_COMP2 : 2, // compression option + FLG_DESC : 4, // data descriptor + FLG_ENH : 8, // enhanced deflation + FLG_STR : 16, // strong encryption + FLG_LNG : 1024, // language encoding + FLG_MSK : 4096, // mask header values + + /* Load type */ + FILE : 0, + BUFFER : 1, + NONE : 2 +}; diff --git a/platforms/android/assets/www/node_modules/adm-zip/util/errors.js b/platforms/android/assets/www/node_modules/adm-zip/util/errors.js new file mode 100644 index 0000000..db5d69e --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/util/errors.js @@ -0,0 +1,35 @@ +module.exports = { + /* Header error messages */ + "INVALID_LOC" : "Invalid LOC header (bad signature)", + "INVALID_CEN" : "Invalid CEN header (bad signature)", + "INVALID_END" : "Invalid END header (bad signature)", + + /* ZipEntry error messages*/ + "NO_DATA" : "Nothing to decompress", + "BAD_CRC" : "CRC32 checksum failed", + "FILE_IN_THE_WAY" : "There is a file in the way: %s", + "UNKNOWN_METHOD" : "Invalid/unsupported compression method", + + /* Inflater error messages */ + "AVAIL_DATA" : "inflate::Available inflate data did not terminate", + "INVALID_DISTANCE" : "inflate::Invalid literal/length or distance code in fixed or dynamic block", + "TO_MANY_CODES" : "inflate::Dynamic block code description: too many length or distance codes", + "INVALID_REPEAT_LEN" : "inflate::Dynamic block code description: repeat more than specified lengths", + "INVALID_REPEAT_FIRST" : "inflate::Dynamic block code description: repeat lengths with no first length", + "INCOMPLETE_CODES" : "inflate::Dynamic block code description: code lengths codes incomplete", + "INVALID_DYN_DISTANCE": "inflate::Dynamic block code description: invalid distance code lengths", + "INVALID_CODES_LEN": "inflate::Dynamic block code description: invalid literal/length code lengths", + "INVALID_STORE_BLOCK" : "inflate::Stored block length did not match one's complement", + "INVALID_BLOCK_TYPE" : "inflate::Invalid block type (type == 3)", + + /* ADM-ZIP error messages */ + "CANT_EXTRACT_FILE" : "Could not extract the file", + "CANT_OVERRIDE" : "Target file already exists", + "NO_ZIP" : "No zip file was loaded", + "NO_ENTRY" : "Entry doesn't exist", + "DIRECTORY_CONTENT_ERROR" : "A directory cannot have content", + "FILE_NOT_FOUND" : "File not found: %s", + "NOT_IMPLEMENTED" : "Not implemented", + "INVALID_FILENAME" : "Invalid filename", + "INVALID_FORMAT" : "Invalid or unsupported zip format. No END header found" +}; \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/adm-zip/util/fattr.js b/platforms/android/assets/www/node_modules/adm-zip/util/fattr.js new file mode 100644 index 0000000..2191ec1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/util/fattr.js @@ -0,0 +1,84 @@ +var fs = require("fs"), + pth = require("path"); + +fs.existsSync = fs.existsSync || pth.existsSync; + +module.exports = function(/*String*/path) { + + var _path = path || "", + _permissions = 0, + _obj = newAttr(), + _stat = null; + + function newAttr() { + return { + directory : false, + readonly : false, + hidden : false, + executable : false, + mtime : 0, + atime : 0 + } + } + + if (_path && fs.existsSync(_path)) { + _stat = fs.statSync(_path); + _obj.directory = _stat.isDirectory(); + _obj.mtime = _stat.mtime; + _obj.atime = _stat.atime; + _obj.executable = !!(1 & parseInt ((_stat.mode & parseInt ("777", 8)).toString (8)[0])); + _obj.readonly = !!(2 & parseInt ((_stat.mode & parseInt ("777", 8)).toString (8)[0])); + _obj.hidden = pth.basename(_path)[0] === "."; + } else { + console.warn("Invalid path: " + _path) + } + + return { + + get directory () { + return _obj.directory; + }, + + get readOnly () { + return _obj.readonly; + }, + + get hidden () { + return _obj.hidden; + }, + + get mtime () { + return _obj.mtime; + }, + + get atime () { + return _obj.atime; + }, + + + get executable () { + return _obj.executable; + }, + + decodeAttributes : function(val) { + + }, + + encodeAttributes : function (val) { + + }, + + toString : function() { + return '{\n' + + '\t"path" : "' + _path + ",\n" + + '\t"isDirectory" : ' + _obj.directory + ",\n" + + '\t"isReadOnly" : ' + _obj.readonly + ",\n" + + '\t"isHidden" : ' + _obj.hidden + ",\n" + + '\t"isExecutable" : ' + _obj.executable + ",\n" + + '\t"mTime" : ' + _obj.mtime + "\n" + + '\t"aTime" : ' + _obj.atime + "\n" + + '}'; + } + } + +}; diff --git a/platforms/android/assets/www/node_modules/adm-zip/util/index.js b/platforms/android/assets/www/node_modules/adm-zip/util/index.js new file mode 100644 index 0000000..935fc1a --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/util/index.js @@ -0,0 +1,4 @@ +module.exports = require("./utils"); +module.exports.Constants = require("./constants"); +module.exports.Errors = require("./errors"); +module.exports.FileAttr = require("./fattr"); \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/adm-zip/util/utils.js b/platforms/android/assets/www/node_modules/adm-zip/util/utils.js new file mode 100644 index 0000000..b14db8c --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/util/utils.js @@ -0,0 +1,145 @@ +var fs = require("fs"), + pth = require('path'); + +fs.existsSync = fs.existsSync || pth.existsSync; + +module.exports = (function() { + + var crcTable = [], + Constants = require('./constants'), + Errors = require('./errors'), + + PATH_SEPARATOR = pth.normalize("/"); + + + function mkdirSync(/*String*/path) { + var resolvedPath = path.split(PATH_SEPARATOR)[0]; + path.split(PATH_SEPARATOR).forEach(function(name) { + if (!name || name.substr(-1,1) == ":") return; + resolvedPath += PATH_SEPARATOR + name; + var stat; + try { + stat = fs.statSync(resolvedPath); + } catch (e) { + fs.mkdirSync(resolvedPath); + } + if (stat && stat.isFile()) + throw Errors.FILE_IN_THE_WAY.replace("%s", resolvedPath); + }); + } + + function findSync(/*String*/root, /*RegExp*/pattern, /*Boolean*/recoursive) { + if (typeof pattern === 'boolean') { + recoursive = pattern; + pattern = undefined; + } + var files = []; + fs.readdirSync(root).forEach(function(file) { + var path = pth.join(root, file); + + if (fs.statSync(path).isDirectory() && recoursive) + files = files.concat(findSync(path, pattern, recoursive)); + + if (!pattern || pattern.test(path)) { + files.push(pth.normalize(path) + (fs.statSync(path).isDirectory() ? PATH_SEPARATOR : "")); + } + + }); + return files; + } + + return { + makeDir : function(/*String*/path) { + mkdirSync(path); + }, + + crc32 : function(buf) { + var b = new Buffer(4); + if (!crcTable.length) { + for (var n = 0; n < 256; n++) { + var c = n; + for (var k = 8; --k >= 0;) // + if ((c & 1) != 0) { c = 0xedb88320 ^ (c >>> 1); } else { c = c >>> 1; } + if (c < 0) { + b.writeInt32LE(c, 0); + c = b.readUInt32LE(0); + } + crcTable[n] = c; + } + } + var crc = 0, off = 0, len = buf.length, c1 = ~crc; + while(--len >= 0) c1 = crcTable[(c1 ^ buf[off++]) & 0xff] ^ (c1 >>> 8); + crc = ~c1; + b.writeInt32LE(crc & 0xffffffff, 0); + return b.readUInt32LE(0); + }, + + methodToString : function(/*Number*/method) { + switch (method) { + case Constants.STORED: + return 'STORED (' + method + ')'; + case Constants.DEFLATED: + return 'DEFLATED (' + method + ')'; + default: + return 'UNSUPPORTED (' + method + ')' + } + + }, + + writeFileTo : function(/*String*/path, /*Buffer*/content, /*Boolean*/overwrite, /*Number*/attr) { + if (fs.existsSync(path)) { + if (!overwrite) + return false; // cannot overwite + + var stat = fs.statSync(path); + if (stat.isDirectory()) { + return false; + } + } + var folder = pth.dirname(path); + if (!fs.existsSync(folder)) { + mkdirSync(folder); + } + + var fd; + try { + fd = fs.openSync(path, 'w', 438); // 0666 + } catch(e) { + fs.chmodSync(path, 438); + fd = fs.openSync(path, 'w', 438); + } + if (fd) { + fs.writeSync(fd, content, 0, content.length, 0); + fs.closeSync(fd); + } + fs.chmodSync(path, attr || 438); + return true; + }, + + findFiles : function(/*String*/path) { + return findSync(path, true); + }, + + getAttributes : function(/*String*/path) { + + }, + + setAttributes : function(/*String*/path) { + + }, + + toBuffer : function(input) { + if (Buffer.isBuffer(input)) { + return input; + } else { + if (input.length == 0) { + return new Buffer(0) + } + return new Buffer(input, 'utf8'); + } + }, + + Constants : Constants, + Errors : Errors + } +})(); diff --git a/platforms/android/assets/www/node_modules/adm-zip/zipEntry.js b/platforms/android/assets/www/node_modules/adm-zip/zipEntry.js new file mode 100644 index 0000000..02c3172 --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/zipEntry.js @@ -0,0 +1,224 @@ +var Utils = require("./util"), + Headers = require("./headers"), + Constants = Utils.Constants, + Methods = require("./methods"); + +module.exports = function (/*Buffer*/input) { + + var _entryHeader = new Headers.EntryHeader(), + _entryName = new Buffer(0), + _comment = new Buffer(0), + _isDirectory = false, + uncompressedData = null, + _extra = new Buffer(0); + + function getCompressedDataFromZip() { + if (!input || !Buffer.isBuffer(input)) { + return new Buffer(0); + } + _entryHeader.loadDataHeaderFromBinary(input); + return input.slice(_entryHeader.realDataOffset, _entryHeader.realDataOffset + _entryHeader.compressedSize) + } + + function crc32OK(data) { + // if bit 3 (0x08) of the general-purpose flags field is set, then the CRC-32 and file sizes are not known when the header is written + if (_entryHeader.flags & 0x8 != 0x8) { + if (Utils.crc32(data) != _entryHeader.crc) { + return false; + } + } else { + // @TODO: load and check data descriptor header + // The fields in the local header are filled with zero, and the CRC-32 and size are appended in a 12-byte structure + // (optionally preceded by a 4-byte signature) immediately after the compressed data: + } + return true; + } + + function decompress(/*Boolean*/async, /*Function*/callback) { + if (_isDirectory) { + if (async && callback) { + callback(new Buffer(0), Utils.Errors.DIRECTORY_CONTENT_ERROR); //si added error. + } + return new Buffer(0); + } + + var compressedData = getCompressedDataFromZip(); + if (compressedData.length == 0) { + if (async && callback) callback(compressedData, Utils.Errors.NO_DATA);//si added error. + return compressedData; + } + + var data = new Buffer(_entryHeader.size); + data.fill(0); + + switch (_entryHeader.method) { + case Utils.Constants.STORED: + compressedData.copy(data); + if (!crc32OK(data)) { + if (async && callback) callback(data, Utils.Errors.BAD_CRC);//si added error + return Utils.Errors.BAD_CRC; + } else {//si added otherwise did not seem to return data. + if (async && callback) callback(data); + return data; + } + break; + case Utils.Constants.DEFLATED: + var inflater = new Methods.Inflater(compressedData); + if (!async) { + inflater.inflate(data); + if (!crc32OK(data)) { + console.warn(Utils.Errors.BAD_CRC + " " + _entryName.toString()) + } + return data; + } else { + inflater.inflateAsync(function(result) { + result.copy(data, 0); + if (crc32OK(data)) { + if (callback) callback(data, Utils.Errors.BAD_CRC); //si added error + } else { //si added otherwise did not seem to return data. + if (callback) callback(data); + } + }) + } + break; + default: + if (async && callback) callback(new Buffer(0), Utils.Errors.UNKNOWN_METHOD); + return Utils.Errors.UNKNOWN_METHOD; + } + } + + function compress(/*Boolean*/async, /*Function*/callback) { + if ((!uncompressedData || !uncompressedData.length) && Buffer.isBuffer(input)) { + // no data set or the data wasn't changed to require recompression + if (async && callback) callback(getCompressedDataFromZip()); + return getCompressedDataFromZip(); + } + + if (uncompressedData.length && !_isDirectory) { + var compressedData; + // Local file header + switch (_entryHeader.method) { + case Utils.Constants.STORED: + _entryHeader.compressedSize = _entryHeader.size; + + compressedData = new Buffer(uncompressedData.length); + uncompressedData.copy(compressedData); + + if (async && callback) callback(compressedData); + return compressedData; + + break; + default: + case Utils.Constants.DEFLATED: + + var deflater = new Methods.Deflater(uncompressedData); + if (!async) { + var deflated = deflater.deflate(); + _entryHeader.compressedSize = deflated.length; + return deflated; + } else { + deflater.deflateAsync(function(data) { + compressedData = new Buffer(data.length); + _entryHeader.compressedSize = data.length; + data.copy(compressedData); + callback && callback(compressedData); + }) + } + deflater = null; + break; + } + } else { + if (async && callback) { + callback(new Buffer(0)); + } else { + return new Buffer(0); + } + } + } + + return { + get entryName () { return _entryName.toString(); }, + get rawEntryName() { return _entryName; }, + set entryName (val) { + _entryName = Utils.toBuffer(val); + var lastChar = _entryName[_entryName.length - 1]; + _isDirectory = (lastChar == 47) || (lastChar == 92); + _entryHeader.fileNameLength = _entryName.length; + }, + + get extra () { return _extra; }, + set extra (val) { + _extra = val; + _entryHeader.extraLength = val.length; + }, + + get comment () { return _comment.toString(); }, + set comment (val) { + _comment = Utils.toBuffer(val); + _entryHeader.commentLength = _comment.length; + }, + + get name () { var n = _entryName.toString(); return _isDirectory ? n.substr(n.length - 1).split("/").pop() : n.split("/").pop(); }, + get isDirectory () { return _isDirectory }, + + getCompressedData : function() { + return compress(false, null) + }, + + getCompressedDataAsync : function(/*Function*/callback) { + compress(true, callback) + }, + + setData : function(value) { + uncompressedData = Utils.toBuffer(value); + if (!_isDirectory && uncompressedData.length) { + _entryHeader.size = uncompressedData.length; + _entryHeader.method = Utils.Constants.DEFLATED; + _entryHeader.crc = Utils.crc32(value); + } else { // folders and blank files should be stored + _entryHeader.method = Utils.Constants.STORED; + } + }, + + getData : function() { + return decompress(false, null); + }, + + getDataAsync : function(/*Function*/callback) { + decompress(true, callback) + }, + + set header(/*Buffer*/data) { + _entryHeader.loadFromBinary(data); + }, + + get header() { + return _entryHeader; + }, + + packHeader : function() { + var header = _entryHeader.entryHeaderToBinary(); + // add + _entryName.copy(header, Utils.Constants.CENHDR); + if (_entryHeader.extraLength) { + _extra.copy(header, Utils.Constants.CENHDR + _entryName.length) + } + if (_entryHeader.commentLength) { + _comment.copy(header, Utils.Constants.CENHDR + _entryName.length + _entryHeader.extraLength, _comment.length); + } + return header; + }, + + toString : function() { + return '{\n' + + '\t"entryName" : "' + _entryName.toString() + "\",\n" + + '\t"name" : "' + _entryName.toString().split("/").pop() + "\",\n" + + '\t"comment" : "' + _comment.toString() + "\",\n" + + '\t"isDirectory" : ' + _isDirectory + ",\n" + + '\t"header" : ' + _entryHeader.toString().replace(/\t/mg, "\t\t") + ",\n" + + '\t"compressedData" : <' + (input && input.length + " bytes buffer" || "null") + ">\n" + + '\t"data" : <' + (uncompressedData && uncompressedData.length + " bytes buffer" || "null") + ">\n" + + '}'; + } + } +}; diff --git a/platforms/android/assets/www/node_modules/adm-zip/zipFile.js b/platforms/android/assets/www/node_modules/adm-zip/zipFile.js new file mode 100644 index 0000000..f066d7e --- /dev/null +++ b/platforms/android/assets/www/node_modules/adm-zip/zipFile.js @@ -0,0 +1,311 @@ +var ZipEntry = require("./zipEntry"), + Headers = require("./headers"), + Utils = require("./util"); + +module.exports = function(/*String|Buffer*/input, /*Number*/inputType) { + var entryList = [], + entryTable = {}, + _comment = new Buffer(0), + filename = "", + fs = require("fs"), + inBuffer = null, + mainHeader = new Headers.MainHeader(); + + if (inputType == Utils.Constants.FILE) { + // is a filename + filename = input; + inBuffer = fs.readFileSync(filename); + readMainHeader(); + } else if (inputType == Utils.Constants.BUFFER) { + // is a memory buffer + inBuffer = input; + readMainHeader(); + } else { + // none. is a new file + } + + function readEntries() { + entryTable = {}; + entryList = new Array(mainHeader.diskEntries); // total number of entries + var index = mainHeader.offset; // offset of first CEN header + for(var i = 0; i < entryList.length; i++) { + + var tmp = index, + entry = new ZipEntry(inBuffer); + entry.header = inBuffer.slice(tmp, tmp += Utils.Constants.CENHDR); + + entry.entryName = inBuffer.slice(tmp, tmp += entry.header.fileNameLength); + + if (entry.header.extraLength) { + entry.extra = inBuffer.slice(tmp, tmp += entry.header.extraLength); + } + + if (entry.header.commentLength) + entry.comment = inBuffer.slice(tmp, tmp + entry.header.commentLength); + + index += entry.header.entryHeaderSize; + + entryList[i] = entry; + entryTable[entry.entryName] = entry; + } + } + + function readMainHeader() { + var i = inBuffer.length - Utils.Constants.ENDHDR, // END header size + n = Math.max(0, i - 0xFFFF), // 0xFFFF is the max zip file comment length + endOffset = 0; // Start offset of the END header + + for (i; i >= n; i--) { + if (inBuffer[i] != 0x50) continue; // quick check that the byte is 'P' + if (inBuffer.readUInt32LE(i) == Utils.Constants.ENDSIG) { // "PK\005\006" + endOffset = i; + break; + } + } + if (!endOffset) + throw Utils.Errors.INVALID_FORMAT; + + mainHeader.loadFromBinary(inBuffer.slice(endOffset, endOffset + Utils.Constants.ENDHDR)); + if (mainHeader.commentLength) { + _comment = inBuffer.slice(endOffset + Utils.Constants.ENDHDR); + } + readEntries(); + } + + return { + /** + * Returns an array of ZipEntry objects existent in the current opened archive + * @return Array + */ + get entries () { + return entryList; + }, + + /** + * Archive comment + * @return {String} + */ + get comment () { return _comment.toString(); }, + set comment(val) { + mainHeader.commentLength = val.length; + _comment = val; + }, + + /** + * Returns a reference to the entry with the given name or null if entry is inexistent + * + * @param entryName + * @return ZipEntry + */ + getEntry : function(/*String*/entryName) { + return entryTable[entryName] || null; + }, + + /** + * Adds the given entry to the entry list + * + * @param entry + */ + setEntry : function(/*ZipEntry*/entry) { + entryList.push(entry); + entryTable[entry.entryName] = entry; + mainHeader.totalEntries = entryList.length; + }, + + /** + * Removes the entry with the given name from the entry list. + * + * If the entry is a directory, then all nested files and directories will be removed + * @param entryName + */ + deleteEntry : function(/*String*/entryName) { + var entry = entryTable[entryName]; + if (entry && entry.isDirectory) { + var _self = this; + this.getEntryChildren(entry).forEach(function(child) { + if (child.entryName != entryName) { + _self.deleteEntry(child.entryName) + } + }) + } + entryList.splice(entryList.indexOf(entry), 1); + delete(entryTable[entryName]); + mainHeader.totalEntries = entryList.length; + }, + + /** + * Iterates and returns all nested files and directories of the given entry + * + * @param entry + * @return Array + */ + getEntryChildren : function(/*ZipEntry*/entry) { + if (entry.isDirectory) { + var list = [], + name = entry.entryName, + len = name.length; + + entryList.forEach(function(zipEntry) { + if (zipEntry.entryName.substr(0, len) == name) { + list.push(zipEntry); + } + }); + return list; + } + return [] + }, + + /** + * Returns the zip file + * + * @return Buffer + */ + compressToBuffer : function() { + if (entryList.length > 1) { + entryList.sort(function(a, b) { + var nameA = a.entryName.toLowerCase(); + var nameB = b.entryName.toLowerCase(); + if (nameA < nameB) {return -1} + if (nameA > nameB) {return 1} + return 0; + }); + } + + var totalSize = 0, + dataBlock = [], + entryHeaders = [], + dindex = 0; + + mainHeader.size = 0; + mainHeader.offset = 0; + + entryList.forEach(function(entry) { + entry.header.offset = dindex; + + // compress data and set local and entry header accordingly. Reason why is called first + var compressedData = entry.getCompressedData(); + // data header + var dataHeader = entry.header.dataHeaderToBinary(); + var postHeader = new Buffer(entry.entryName + entry.extra.toString()); + var dataLength = dataHeader.length + postHeader.length + compressedData.length; + + dindex += dataLength; + + dataBlock.push(dataHeader); + dataBlock.push(postHeader); + dataBlock.push(compressedData); + + var entryHeader = entry.packHeader(); + entryHeaders.push(entryHeader); + mainHeader.size += entryHeader.length; + totalSize += (dataLength + entryHeader.length); + }); + + totalSize += mainHeader.mainHeaderSize; // also includes zip file comment length + // point to end of data and begining of central directory first record + mainHeader.offset = dindex; + + dindex = 0; + var outBuffer = new Buffer(totalSize); + dataBlock.forEach(function(content) { + content.copy(outBuffer, dindex); // write data blocks + dindex += content.length; + }); + entryHeaders.forEach(function(content) { + content.copy(outBuffer, dindex); // write central directory entries + dindex += content.length; + }); + + var mh = mainHeader.toBinary(); + if (_comment) { + _comment.copy(mh, Utils.Constants.ENDHDR); // add zip file comment + } + + mh.copy(outBuffer, dindex); // write main header + + return outBuffer + }, + + toAsyncBuffer : function(/*Function*/onSuccess,/*Function*/onFail,/*Function*/onItemStart,/*Function*/onItemEnd) { + if (entryList.length > 1) { + entryList.sort(function(a, b) { + var nameA = a.entryName.toLowerCase(); + var nameB = b.entryName.toLowerCase(); + if (nameA > nameB) {return -1} + if (nameA < nameB) {return 1} + return 0; + }); + } + + var totalSize = 0, + dataBlock = [], + entryHeaders = [], + dindex = 0; + + mainHeader.size = 0; + mainHeader.offset = 0; + + var compress=function(entryList){ + var self=arguments.callee; + var entry; + if(entryList.length){ + var entry=entryList.pop(); + var name=entry.entryName + entry.extra.toString(); + if(onItemStart)onItemStart(name); + entry.getCompressedDataAsync(function(compressedData){ + if(onItemEnd)onItemEnd(name); + + entry.header.offset = dindex; + // data header + var dataHeader = entry.header.dataHeaderToBinary(); + var postHeader = new Buffer(name); + var dataLength = dataHeader.length + postHeader.length + compressedData.length; + + dindex += dataLength; + + dataBlock.push(dataHeader); + dataBlock.push(postHeader); + dataBlock.push(compressedData); + + var entryHeader = entry.packHeader(); + entryHeaders.push(entryHeader); + mainHeader.size += entryHeader.length; + totalSize += (dataLength + entryHeader.length); + + if(entryList.length){ + self(entryList); + }else{ + + + totalSize += mainHeader.mainHeaderSize; // also includes zip file comment length + // point to end of data and begining of central directory first record + mainHeader.offset = dindex; + + dindex = 0; + var outBuffer = new Buffer(totalSize); + dataBlock.forEach(function(content) { + content.copy(outBuffer, dindex); // write data blocks + dindex += content.length; + }); + entryHeaders.forEach(function(content) { + content.copy(outBuffer, dindex); // write central directory entries + dindex += content.length; + }); + + var mh = mainHeader.toBinary(); + if (_comment) { + _comment.copy(mh, Utils.Constants.ENDHDR); // add zip file comment + } + + mh.copy(outBuffer, dindex); // write main header + + onSuccess(outBuffer); + } + }); + } + }; + + compress(entryList); + } + } +}; diff --git a/platforms/android/assets/www/node_modules/balanced-match/.npmignore b/platforms/android/assets/www/node_modules/balanced-match/.npmignore new file mode 100644 index 0000000..fd4f2b0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/balanced-match/.npmignore @@ -0,0 +1,2 @@ +node_modules +.DS_Store diff --git a/platforms/android/assets/www/node_modules/balanced-match/.travis.yml b/platforms/android/assets/www/node_modules/balanced-match/.travis.yml new file mode 100644 index 0000000..6e5919d --- /dev/null +++ b/platforms/android/assets/www/node_modules/balanced-match/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" diff --git a/platforms/android/assets/www/node_modules/balanced-match/LICENSE.md b/platforms/android/assets/www/node_modules/balanced-match/LICENSE.md new file mode 100644 index 0000000..2cdc8e4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/balanced-match/LICENSE.md @@ -0,0 +1,21 @@ +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/balanced-match/Makefile b/platforms/android/assets/www/node_modules/balanced-match/Makefile new file mode 100644 index 0000000..fa5da71 --- /dev/null +++ b/platforms/android/assets/www/node_modules/balanced-match/Makefile @@ -0,0 +1,6 @@ + +test: + @node_modules/.bin/tape test/*.js + +.PHONY: test + diff --git a/platforms/android/assets/www/node_modules/balanced-match/README.md b/platforms/android/assets/www/node_modules/balanced-match/README.md new file mode 100644 index 0000000..421f3aa --- /dev/null +++ b/platforms/android/assets/www/node_modules/balanced-match/README.md @@ -0,0 +1,89 @@ +# balanced-match + +Match balanced string pairs, like `{` and `}` or `` and ``. + +[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) +[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) + +[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) + +## Example + +Get the first matching pair of braces: + +```js +var balanced = require('balanced-match'); + +console.log(balanced('{', '}', 'pre{in{nested}}post')); +console.log(balanced('{', '}', 'pre{first}between{second}post')); +``` + +The matches are: + +```bash +$ node example.js +{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } +{ start: 3, + end: 9, + pre: 'pre', + body: 'first', + post: 'between{second}post' } +``` + +## API + +### var m = balanced(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +object with those keys: + +* **start** the index of the first match of `a` +* **end** the index of the matching `b` +* **pre** the preamble, `a` and `b` not included +* **body** the match, `a` and `b` not included +* **post** the postscript, `a` and `b` not included + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']`. + +### var r = balanced.range(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +array with indexes: `[ , ]`. + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]`. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install balanced-match +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/balanced-match/example.js b/platforms/android/assets/www/node_modules/balanced-match/example.js new file mode 100644 index 0000000..c02ad34 --- /dev/null +++ b/platforms/android/assets/www/node_modules/balanced-match/example.js @@ -0,0 +1,5 @@ +var balanced = require('./'); + +console.log(balanced('{', '}', 'pre{in{nested}}post')); +console.log(balanced('{', '}', 'pre{first}between{second}post')); + diff --git a/platforms/android/assets/www/node_modules/balanced-match/index.js b/platforms/android/assets/www/node_modules/balanced-match/index.js new file mode 100644 index 0000000..75f3d71 --- /dev/null +++ b/platforms/android/assets/www/node_modules/balanced-match/index.js @@ -0,0 +1,50 @@ +module.exports = balanced; +function balanced(a, b, str) { + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i < str.length && i >= 0 && ! result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} diff --git a/platforms/android/assets/www/node_modules/balanced-match/package.json b/platforms/android/assets/www/node_modules/balanced-match/package.json new file mode 100644 index 0000000..6ae13e8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/balanced-match/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + "balanced-match@^0.3.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/brace-expansion" + ] + ], + "_from": "balanced-match@>=0.3.0 <0.4.0", + "_id": "balanced-match@0.3.0", + "_inCache": true, + "_installable": true, + "_location": "/balanced-match", + "_nodeVersion": "4.2.1", + "_npmUser": { + "email": "julian@juliangruber.com", + "name": "juliangruber" + }, + "_npmVersion": "2.14.7", + "_phantomChildren": {}, + "_requested": { + "name": "balanced-match", + "raw": "balanced-match@^0.3.0", + "rawSpec": "^0.3.0", + "scope": null, + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/brace-expansion" + ], + "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.3.0.tgz", + "_shasum": "a91cdd1ebef1a86659e70ff4def01625fc2d6756", + "_shrinkwrap": null, + "_spec": "balanced-match@^0.3.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/brace-expansion", + "author": { + "email": "mail@juliangruber.com", + "name": "Julian Gruber", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/balanced-match/issues" + }, + "dependencies": {}, + "description": "Match balanced character pairs, like \"{\" and \"}\"", + "devDependencies": { + "tape": "~4.2.2" + }, + "directories": {}, + "dist": { + "shasum": "a91cdd1ebef1a86659e70ff4def01625fc2d6756", + "tarball": "http://registry.npmjs.org/balanced-match/-/balanced-match-0.3.0.tgz" + }, + "gitHead": "a7114b0986554787e90b7ac595a043ca75ea77e5", + "homepage": "https://github.com/juliangruber/balanced-match", + "keywords": [ + "match", + "regexp", + "test", + "balanced", + "parse" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "email": "julian@juliangruber.com", + "name": "juliangruber" + } + ], + "name": "balanced-match", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/balanced-match.git" + }, + "scripts": { + "test": "make test" + }, + "testling": { + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ], + "files": "test/*.js" + }, + "version": "0.3.0" +} diff --git a/platforms/android/assets/www/node_modules/balanced-match/test/balanced.js b/platforms/android/assets/www/node_modules/balanced-match/test/balanced.js new file mode 100644 index 0000000..f5e98e3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/balanced-match/test/balanced.js @@ -0,0 +1,84 @@ +var test = require('tape'); +var balanced = require('..'); + +test('balanced', function(t) { + t.deepEqual(balanced('{', '}', 'pre{in{nest}}post'), { + start: 3, + end: 12, + pre: 'pre', + body: 'in{nest}', + post: 'post' + }); + t.deepEqual(balanced('{', '}', '{{{{{{{{{in}post'), { + start: 8, + end: 11, + pre: '{{{{{{{{', + body: 'in', + post: 'post' + }); + t.deepEqual(balanced('{', '}', 'pre{body{in}post'), { + start: 8, + end: 11, + pre: 'pre{body', + body: 'in', + post: 'post' + }); + t.deepEqual(balanced('{', '}', 'pre}{in{nest}}post'), { + start: 4, + end: 13, + pre: 'pre}', + body: 'in{nest}', + post: 'post' + }); + t.deepEqual(balanced('{', '}', 'pre{body}between{body2}post'), { + start: 3, + end: 8, + pre: 'pre', + body: 'body', + post: 'between{body2}post' + }); + t.notOk(balanced('{', '}', 'nope'), 'should be notOk'); + t.deepEqual(balanced('', '', 'preinnestpost'), { + start: 3, + end: 19, + pre: 'pre', + body: 'innest', + post: 'post' + }); + t.deepEqual(balanced('', '', 'preinnestpost'), { + start: 7, + end: 23, + pre: 'pre', + body: 'innest', + post: 'post' + }); + t.deepEqual(balanced('{{', '}}', 'pre{{{in}}}post'), { + start: 3, + end: 9, + pre: 'pre', + body: '{in}', + post: 'post' + }); + t.deepEqual(balanced('{{{', '}}', 'pre{{{in}}}post'), { + start: 3, + end: 8, + pre: 'pre', + body: 'in', + post: '}post' + }); + t.deepEqual(balanced('{', '}', 'pre{{first}in{second}post'), { + start: 4, + end: 10, + pre: 'pre{', + body: 'first', + post: 'in{second}post' + }); + t.deepEqual(balanced('', 'prepost'), { + start: 3, + end: 4, + pre: 'pre', + body: '', + post: 'post' + }); + t.end(); +}); diff --git a/platforms/android/assets/www/node_modules/brace-expansion/.npmignore b/platforms/android/assets/www/node_modules/brace-expansion/.npmignore new file mode 100644 index 0000000..353546a --- /dev/null +++ b/platforms/android/assets/www/node_modules/brace-expansion/.npmignore @@ -0,0 +1,3 @@ +test +.gitignore +.travis.yml diff --git a/platforms/android/assets/www/node_modules/brace-expansion/README.md b/platforms/android/assets/www/node_modules/brace-expansion/README.md new file mode 100644 index 0000000..1793929 --- /dev/null +++ b/platforms/android/assets/www/node_modules/brace-expansion/README.md @@ -0,0 +1,122 @@ +# brace-expansion + +[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), +as known from sh/bash, in JavaScript. + +[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) +[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) + +[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) + +## Example + +```js +var expand = require('brace-expansion'); + +expand('file-{a,b,c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('-v{,,}') +// => ['-v', '-v', '-v'] + +expand('file{0..2}.jpg') +// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] + +expand('file-{a..c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('file{2..0}.jpg') +// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] + +expand('file{0..4..2}.jpg') +// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] + +expand('file-{a..e..2}.jpg') +// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] + +expand('file{00..10..5}.jpg') +// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] + +expand('{{A..C},{a..c}}') +// => ['A', 'B', 'C', 'a', 'b', 'c'] + +expand('ppp{,config,oe{,conf}}') +// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] +``` + +## API + +```js +var expand = require('brace-expansion'); +``` + +### var expanded = expand(str) + +Return an array of all possible and valid expansions of `str`. If none are +found, `[str]` is returned. + +Valid expansions are: + +```js +/^(.*,)+(.+)?$/ +// {a,b,...} +``` + +A comma seperated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +A numeric sequence from `x` to `y` inclusive, with optional increment. +If `x` or `y` start with a leading `0`, all the numbers will be padded +to have equal length. Negative numbers and backwards iteration work too. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +An alphabetic sequence from `x` to `y` inclusive, with optional increment. +`x` and `y` must be exactly one character, and if given, `incr` must be a +number. + +For compatibility reasons, the string `${` is not eligible for brace expansion. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install brace-expansion +``` + +## Contributors + +- [Julian Gruber](https://github.com/juliangruber) +- [Isaac Z. Schlueter](https://github.com/isaacs) + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/brace-expansion/example.js b/platforms/android/assets/www/node_modules/brace-expansion/example.js new file mode 100644 index 0000000..60ecfc7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/brace-expansion/example.js @@ -0,0 +1,8 @@ +var expand = require('./'); + +console.log(expand('http://any.org/archive{1996..1999}/vol{1..4}/part{a,b,c}.html')); +console.log(expand('http://www.numericals.com/file{1..100..10}.txt')); +console.log(expand('http://www.letters.com/file{a..z..2}.txt')); +console.log(expand('mkdir /usr/local/src/bash/{old,new,dist,bugs}')); +console.log(expand('chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}')); + diff --git a/platforms/android/assets/www/node_modules/brace-expansion/index.js b/platforms/android/assets/www/node_modules/brace-expansion/index.js new file mode 100644 index 0000000..932718f --- /dev/null +++ b/platforms/android/assets/www/node_modules/brace-expansion/index.js @@ -0,0 +1,191 @@ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = /^(.*,)+(.+)?$/.test(m.body); + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + diff --git a/platforms/android/assets/www/node_modules/brace-expansion/package.json b/platforms/android/assets/www/node_modules/brace-expansion/package.json new file mode 100644 index 0000000..034c59e --- /dev/null +++ b/platforms/android/assets/www/node_modules/brace-expansion/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + "brace-expansion@^1.0.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/minimatch" + ] + ], + "_from": "brace-expansion@>=1.0.0 <2.0.0", + "_id": "brace-expansion@1.1.3", + "_inCache": true, + "_installable": true, + "_location": "/brace-expansion", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-6-west.internal.npmjs.com", + "tmp": "tmp/brace-expansion-1.1.3.tgz_1455216688668_0.948847763473168" + }, + "_npmUser": { + "email": "julian@juliangruber.com", + "name": "juliangruber" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "name": "brace-expansion", + "raw": "brace-expansion@^1.0.0", + "rawSpec": "^1.0.0", + "scope": null, + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/minimatch" + ], + "_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.3.tgz", + "_shasum": "46bff50115d47fc9ab89854abb87d98078a10991", + "_shrinkwrap": null, + "_spec": "brace-expansion@^1.0.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/minimatch", + "author": { + "email": "mail@juliangruber.com", + "name": "Julian Gruber", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/brace-expansion/issues" + }, + "dependencies": { + "balanced-match": "^0.3.0", + "concat-map": "0.0.1" + }, + "description": "Brace expansion as known from sh/bash", + "devDependencies": { + "tape": "4.4.0" + }, + "directories": {}, + "dist": { + "shasum": "46bff50115d47fc9ab89854abb87d98078a10991", + "tarball": "http://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.3.tgz" + }, + "gitHead": "f0da1bb668e655f67b6b2d660c6e1c19e2a6f231", + "homepage": "https://github.com/juliangruber/brace-expansion", + "keywords": [], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "email": "julian@juliangruber.com", + "name": "juliangruber" + }, + { + "email": "isaacs@npmjs.com", + "name": "isaacs" + } + ], + "name": "brace-expansion", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + }, + "scripts": { + "gentest": "bash test/generate.sh", + "test": "tape test/*.js" + }, + "testling": { + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ], + "files": "test/*.js" + }, + "version": "1.1.3" +} diff --git a/platforms/android/assets/www/node_modules/concat-map/.travis.yml b/platforms/android/assets/www/node_modules/concat-map/.travis.yml new file mode 100644 index 0000000..f1d0f13 --- /dev/null +++ b/platforms/android/assets/www/node_modules/concat-map/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.4 + - 0.6 diff --git a/platforms/android/assets/www/node_modules/concat-map/LICENSE b/platforms/android/assets/www/node_modules/concat-map/LICENSE new file mode 100644 index 0000000..ee27ba4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/concat-map/LICENSE @@ -0,0 +1,18 @@ +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/concat-map/README.markdown b/platforms/android/assets/www/node_modules/concat-map/README.markdown new file mode 100644 index 0000000..408f70a --- /dev/null +++ b/platforms/android/assets/www/node_modules/concat-map/README.markdown @@ -0,0 +1,62 @@ +concat-map +========== + +Concatenative mapdashery. + +[![browser support](http://ci.testling.com/substack/node-concat-map.png)](http://ci.testling.com/substack/node-concat-map) + +[![build status](https://secure.travis-ci.org/substack/node-concat-map.png)](http://travis-ci.org/substack/node-concat-map) + +example +======= + +``` js +var concatMap = require('concat-map'); +var xs = [ 1, 2, 3, 4, 5, 6 ]; +var ys = concatMap(xs, function (x) { + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; +}); +console.dir(ys); +``` + +*** + +``` +[ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ] +``` + +methods +======= + +``` js +var concatMap = require('concat-map') +``` + +concatMap(xs, fn) +----------------- + +Return an array of concatenated elements by calling `fn(x, i)` for each element +`x` and each index `i` in the array `xs`. + +When `fn(x, i)` returns an array, its result will be concatenated with the +result array. If `fn(x, i)` returns anything else, that value will be pushed +onto the end of the result array. + +install +======= + +With [npm](http://npmjs.org) do: + +``` +npm install concat-map +``` + +license +======= + +MIT + +notes +===== + +This module was written while sitting high above the ground in a tree. diff --git a/platforms/android/assets/www/node_modules/concat-map/example/map.js b/platforms/android/assets/www/node_modules/concat-map/example/map.js new file mode 100644 index 0000000..3365621 --- /dev/null +++ b/platforms/android/assets/www/node_modules/concat-map/example/map.js @@ -0,0 +1,6 @@ +var concatMap = require('../'); +var xs = [ 1, 2, 3, 4, 5, 6 ]; +var ys = concatMap(xs, function (x) { + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; +}); +console.dir(ys); diff --git a/platforms/android/assets/www/node_modules/concat-map/index.js b/platforms/android/assets/www/node_modules/concat-map/index.js new file mode 100644 index 0000000..b29a781 --- /dev/null +++ b/platforms/android/assets/www/node_modules/concat-map/index.js @@ -0,0 +1,13 @@ +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; diff --git a/platforms/android/assets/www/node_modules/concat-map/package.json b/platforms/android/assets/www/node_modules/concat-map/package.json new file mode 100644 index 0000000..a9ec9a4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/concat-map/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + "concat-map@0.0.1", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/brace-expansion" + ] + ], + "_from": "concat-map@0.0.1", + "_id": "concat-map@0.0.1", + "_inCache": true, + "_installable": true, + "_location": "/concat-map", + "_npmUser": { + "email": "mail@substack.net", + "name": "substack" + }, + "_npmVersion": "1.3.21", + "_phantomChildren": {}, + "_requested": { + "name": "concat-map", + "raw": "concat-map@0.0.1", + "rawSpec": "0.0.1", + "scope": null, + "spec": "0.0.1", + "type": "version" + }, + "_requiredBy": [ + "/brace-expansion" + ], + "_resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "_shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b", + "_shrinkwrap": null, + "_spec": "concat-map@0.0.1", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/brace-expansion", + "author": { + "email": "mail@substack.net", + "name": "James Halliday", + "url": "http://substack.net" + }, + "bugs": { + "url": "https://github.com/substack/node-concat-map/issues" + }, + "dependencies": {}, + "description": "concatenative mapdashery", + "devDependencies": { + "tape": "~2.4.0" + }, + "directories": { + "example": "example", + "test": "test" + }, + "dist": { + "shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b", + "tarball": "http://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + }, + "homepage": "https://github.com/substack/node-concat-map", + "keywords": [ + "concat", + "concatMap", + "map", + "functional", + "higher-order" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "email": "mail@substack.net", + "name": "substack" + } + ], + "name": "concat-map", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/substack/node-concat-map.git" + }, + "scripts": { + "test": "tape test/*.js" + }, + "testling": { + "browsers": { + "chrome": [ + 10, + 22 + ], + "ff": [ + 3.5, + 10, + 15 + ], + "ie": [ + 6, + 7, + 8, + 9 + ], + "opera": [ + 12 + ], + "safari": [ + 5.1 + ] + }, + "files": "test/*.js" + }, + "version": "0.0.1" +} diff --git a/platforms/android/assets/www/node_modules/concat-map/test/map.js b/platforms/android/assets/www/node_modules/concat-map/test/map.js new file mode 100644 index 0000000..fdbd702 --- /dev/null +++ b/platforms/android/assets/www/node_modules/concat-map/test/map.js @@ -0,0 +1,39 @@ +var concatMap = require('../'); +var test = require('tape'); + +test('empty or not', function (t) { + var xs = [ 1, 2, 3, 4, 5, 6 ]; + var ixes = []; + var ys = concatMap(xs, function (x, ix) { + ixes.push(ix); + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; + }); + t.same(ys, [ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]); + t.same(ixes, [ 0, 1, 2, 3, 4, 5 ]); + t.end(); +}); + +test('always something', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function (x) { + return x === 'b' ? [ 'B', 'B', 'B' ] : [ x ]; + }); + t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); + t.end(); +}); + +test('scalars', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function (x) { + return x === 'b' ? [ 'B', 'B', 'B' ] : x; + }); + t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); + t.end(); +}); + +test('undefs', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function () {}); + t.same(ys, [ undefined, undefined, undefined, undefined ]); + t.end(); +}); diff --git a/platforms/android/assets/www/node_modules/exit/.jshintrc b/platforms/android/assets/www/node_modules/exit/.jshintrc new file mode 100644 index 0000000..2b7e39b --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/.jshintrc @@ -0,0 +1,14 @@ +{ + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": "nofunc", + "newcap": true, + "noarg": true, + "sub": true, + "undef": true, + "unused": true, + "boss": true, + "eqnull": true, + "node": true +} diff --git a/platforms/android/assets/www/node_modules/exit/.npmignore b/platforms/android/assets/www/node_modules/exit/.npmignore new file mode 100644 index 0000000..e69de29 diff --git a/platforms/android/assets/www/node_modules/exit/.travis.yml b/platforms/android/assets/www/node_modules/exit/.travis.yml new file mode 100644 index 0000000..42d4302 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - 0.8 + - '0.10' +before_script: + - npm install -g grunt-cli diff --git a/platforms/android/assets/www/node_modules/exit/Gruntfile.js b/platforms/android/assets/www/node_modules/exit/Gruntfile.js new file mode 100644 index 0000000..ff37751 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/Gruntfile.js @@ -0,0 +1,48 @@ +'use strict'; + +module.exports = function(grunt) { + + // Project configuration. + grunt.initConfig({ + nodeunit: { + files: ['test/**/*_test.js'], + }, + jshint: { + options: { + jshintrc: '.jshintrc' + }, + gruntfile: { + src: 'Gruntfile.js' + }, + lib: { + src: ['lib/**/*.js'] + }, + test: { + src: ['test/**/*.js'] + }, + }, + watch: { + gruntfile: { + files: '<%= jshint.gruntfile.src %>', + tasks: ['jshint:gruntfile'] + }, + lib: { + files: '<%= jshint.lib.src %>', + tasks: ['jshint:lib', 'nodeunit'] + }, + test: { + files: '<%= jshint.test.src %>', + tasks: ['jshint:test', 'nodeunit'] + }, + }, + }); + + // These plugins provide necessary tasks. + grunt.loadNpmTasks('grunt-contrib-nodeunit'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-watch'); + + // Default task. + grunt.registerTask('default', ['jshint', 'nodeunit']); + +}; diff --git a/platforms/android/assets/www/node_modules/exit/LICENSE-MIT b/platforms/android/assets/www/node_modules/exit/LICENSE-MIT new file mode 100644 index 0000000..bb2aad6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2013 "Cowboy" Ben Alman + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/exit/README.md b/platforms/android/assets/www/node_modules/exit/README.md new file mode 100644 index 0000000..20c364e --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/README.md @@ -0,0 +1,75 @@ +# exit [![Build Status](https://secure.travis-ci.org/cowboy/node-exit.png?branch=master)](http://travis-ci.org/cowboy/node-exit) + +A replacement for process.exit that ensures stdio are fully drained before exiting. + +To make a long story short, if `process.exit` is called on Windows, script output is often truncated when pipe-redirecting `stdout` or `stderr`. This module attempts to work around this issue by waiting until those streams have been completely drained before actually calling `process.exit`. + +See [Node.js issue #3584](https://github.com/joyent/node/issues/3584) for further reference. + +Tested in OS X 10.8, Windows 7 on Node.js 0.8.25 and 0.10.18. + +Based on some code by [@vladikoff](https://github.com/vladikoff). + +## Getting Started +Install the module with: `npm install exit` + +```javascript +var exit = require('exit'); + +// These lines should appear in the output, EVEN ON WINDOWS. +console.log("omg"); +console.error("yay"); + +// process.exit(5); +exit(5); + +// These lines shouldn't appear in the output. +console.log("wtf"); +console.error("bro"); +``` + +## Don't believe me? Try it for yourself. + +In Windows, clone the repo and cd to the `test\fixtures` directory. The only difference between [log.js](test/fixtures/log.js) and [log-broken.js](test/fixtures/log-broken.js) is that the former uses `exit` while the latter calls `process.exit` directly. + +This test was done using cmd.exe, but you can see the same results using `| grep "std"` in either PowerShell or git-bash. + +``` +C:\node-exit\test\fixtures>node log.js 0 10 stdout stderr 2>&1 | find "std" +stdout 0 +stderr 0 +stdout 1 +stderr 1 +stdout 2 +stderr 2 +stdout 3 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 + +C:\node-exit\test\fixtures>node log-broken.js 0 10 stdout stderr 2>&1 | find "std" + +C:\node-exit\test\fixtures> +``` + +## Contributing +In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/). + +## Release History +2013-11-26 - v0.1.2 - Fixed a bug with hanging processes. +2013-09-26 - v0.1.1 - Fixed some bugs. It seems to actually work now! +2013-09-20 - v0.1.0 - Initial release. + +## License +Copyright (c) 2013 "Cowboy" Ben Alman +Licensed under the MIT license. diff --git a/platforms/android/assets/www/node_modules/exit/lib/exit.js b/platforms/android/assets/www/node_modules/exit/lib/exit.js new file mode 100644 index 0000000..2883e05 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/lib/exit.js @@ -0,0 +1,41 @@ +/* + * exit + * https://github.com/cowboy/node-exit + * + * Copyright (c) 2013 "Cowboy" Ben Alman + * Licensed under the MIT license. + */ + +'use strict'; + +module.exports = function exit(exitCode, streams) { + if (!streams) { streams = [process.stdout, process.stderr]; } + var drainCount = 0; + // Actually exit if all streams are drained. + function tryToExit() { + if (drainCount === streams.length) { + process.exit(exitCode); + } + } + streams.forEach(function(stream) { + // Count drained streams now, but monitor non-drained streams. + if (stream.bufferSize === 0) { + drainCount++; + } else { + stream.write('', 'utf-8', function() { + drainCount++; + tryToExit(); + }); + } + // Prevent further writing. + stream.write = function() {}; + }); + // If all streams were already drained, exit now. + tryToExit(); + // In Windows, when run as a Node.js child process, a script utilizing + // this library might just exit with a 0 exit code, regardless. This code, + // despite the fact that it looks a bit crazy, appears to fix that. + process.on('exit', function() { + process.exit(exitCode); + }); +}; diff --git a/platforms/android/assets/www/node_modules/exit/package.json b/platforms/android/assets/www/node_modules/exit/package.json new file mode 100644 index 0000000..ea2795d --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/package.json @@ -0,0 +1,95 @@ +{ + "_args": [ + [ + "exit@^0.1.2", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine" + ] + ], + "_from": "exit@>=0.1.2 <0.2.0", + "_id": "exit@0.1.2", + "_inCache": true, + "_installable": true, + "_location": "/exit", + "_npmUser": { + "email": "cowboy@rj3.net", + "name": "cowboy" + }, + "_npmVersion": "1.3.11", + "_phantomChildren": {}, + "_requested": { + "name": "exit", + "raw": "exit@^0.1.2", + "rawSpec": "^0.1.2", + "scope": null, + "spec": ">=0.1.2 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine" + ], + "_resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "_shasum": "0632638f8d877cc82107d30a0fff1a17cba1cd0c", + "_shrinkwrap": null, + "_spec": "exit@^0.1.2", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine", + "author": { + "name": "\"Cowboy\" Ben Alman", + "url": "http://benalman.com/" + }, + "bugs": { + "url": "https://github.com/cowboy/node-exit/issues" + }, + "dependencies": {}, + "description": "A replacement for process.exit that ensures stdio are fully drained before exiting.", + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-jshint": "~0.6.4", + "grunt-contrib-nodeunit": "~0.2.0", + "grunt-contrib-watch": "~0.5.3", + "which": "~1.0.5" + }, + "directories": {}, + "dist": { + "shasum": "0632638f8d877cc82107d30a0fff1a17cba1cd0c", + "tarball": "http://registry.npmjs.org/exit/-/exit-0.1.2.tgz" + }, + "engines": { + "node": ">= 0.8.0" + }, + "homepage": "https://github.com/cowboy/node-exit", + "keywords": [ + "exit", + "process", + "stdio", + "stdout", + "stderr", + "drain", + "flush", + "3584" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/cowboy/node-exit/blob/master/LICENSE-MIT" + } + ], + "main": "lib/exit", + "maintainers": [ + { + "email": "cowboy@rj3.net", + "name": "cowboy" + } + ], + "name": "exit", + "optionalDependencies": {}, + "readme": "# exit [![Build Status](https://secure.travis-ci.org/cowboy/node-exit.png?branch=master)](http://travis-ci.org/cowboy/node-exit)\n\nA replacement for process.exit that ensures stdio are fully drained before exiting.\n\nTo make a long story short, if `process.exit` is called on Windows, script output is often truncated when pipe-redirecting `stdout` or `stderr`. This module attempts to work around this issue by waiting until those streams have been completely drained before actually calling `process.exit`.\n\nSee [Node.js issue #3584](https://github.com/joyent/node/issues/3584) for further reference.\n\nTested in OS X 10.8, Windows 7 on Node.js 0.8.25 and 0.10.18.\n\nBased on some code by [@vladikoff](https://github.com/vladikoff).\n\n## Getting Started\nInstall the module with: `npm install exit`\n\n```javascript\nvar exit = require('exit');\n\n// These lines should appear in the output, EVEN ON WINDOWS.\nconsole.log(\"omg\");\nconsole.error(\"yay\");\n\n// process.exit(5);\nexit(5);\n\n// These lines shouldn't appear in the output.\nconsole.log(\"wtf\");\nconsole.error(\"bro\");\n```\n\n## Don't believe me? Try it for yourself.\n\nIn Windows, clone the repo and cd to the `test\\fixtures` directory. The only difference between [log.js](test/fixtures/log.js) and [log-broken.js](test/fixtures/log-broken.js) is that the former uses `exit` while the latter calls `process.exit` directly.\n\nThis test was done using cmd.exe, but you can see the same results using `| grep \"std\"` in either PowerShell or git-bash.\n\n```\nC:\\node-exit\\test\\fixtures>node log.js 0 10 stdout stderr 2>&1 | find \"std\"\nstdout 0\nstderr 0\nstdout 1\nstderr 1\nstdout 2\nstderr 2\nstdout 3\nstderr 3\nstdout 4\nstderr 4\nstdout 5\nstderr 5\nstdout 6\nstderr 6\nstdout 7\nstderr 7\nstdout 8\nstderr 8\nstdout 9\nstderr 9\n\nC:\\node-exit\\test\\fixtures>node log-broken.js 0 10 stdout stderr 2>&1 | find \"std\"\n\nC:\\node-exit\\test\\fixtures>\n```\n\n## Contributing\nIn lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).\n\n## Release History\n2013-11-26 - v0.1.2 - Fixed a bug with hanging processes. \n2013-09-26 - v0.1.1 - Fixed some bugs. It seems to actually work now! \n2013-09-20 - v0.1.0 - Initial release.\n\n## License\nCopyright (c) 2013 \"Cowboy\" Ben Alman \nLicensed under the MIT license.\n", + "readmeFilename": "README.md", + "repository": { + "type": "git", + "url": "git://github.com/cowboy/node-exit.git" + }, + "scripts": { + "test": "grunt nodeunit" + }, + "version": "0.1.2" +} diff --git a/platforms/android/assets/www/node_modules/exit/test/exit_test.js b/platforms/android/assets/www/node_modules/exit/test/exit_test.js new file mode 100644 index 0000000..a91afb9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/exit_test.js @@ -0,0 +1,121 @@ +'use strict'; + +/* + ======== A Handy Little Nodeunit Reference ======== + https://github.com/caolan/nodeunit + + Test methods: + test.expect(numAssertions) + test.done() + Test assertions: + test.ok(value, [message]) + test.equal(actual, expected, [message]) + test.notEqual(actual, expected, [message]) + test.deepEqual(actual, expected, [message]) + test.notDeepEqual(actual, expected, [message]) + test.strictEqual(actual, expected, [message]) + test.notStrictEqual(actual, expected, [message]) + test.throws(block, [error], [message]) + test.doesNotThrow(block, [error], [message]) + test.ifError(value) +*/ + +var fs = require('fs'); +var exec = require('child_process').exec; + +var _which = require('which').sync; +function which(command) { + try { + _which(command); + return command; + } catch (err) { + return false; + } +} + +// Look for grep first (any OS). If not found (but on Windows) look for find, +// which is Windows' horribly crippled grep alternative. +var grep = which('grep') || process.platform === 'win32' && which('find'); + +exports['exit'] = { + setUp: function(done) { + this.origCwd = process.cwd(); + process.chdir('test/fixtures'); + done(); + }, + tearDown: function(done) { + process.chdir(this.origCwd); + done(); + }, + 'grep': function(test) { + test.expect(1); + // Many unit tests depend on this. + test.ok(grep, 'A suitable "grep" or "find" program was not found in the PATH.'); + test.done(); + }, + // The rest of the tests are built dynamically, to keep things sane. +}; + +// A few helper functions. +function normalizeLineEndings(s) { + return s.replace(/\r?\n/g, '\n'); +} + +// Capture command output, normalizing captured stdout to unix file endings. +function run(command, callback) { + exec(command, function(error, stdout) { + callback(error ? error.code : 0, normalizeLineEndings(stdout)); + }); +} + +// Read a fixture file, normalizing file contents to unix file endings. +function fixture(filename) { + return normalizeLineEndings(String(fs.readFileSync(filename))); +} + +function buildTests() { + // Build individual unit tests for command output. + var counts = [10, 100, 1000]; + var outputs = [' stdout stderr', ' stdout', ' stderr']; + var pipes = ['', ' | ' + grep + ' "std"']; + counts.forEach(function(count) { + outputs.forEach(function(output) { + pipes.forEach(function(pipe) { + var command = 'node log.js 0 ' + count + output + ' 2>&1' + pipe; + exports['exit']['output (' + command + ')'] = function(test) { + test.expect(2); + run(command, function(code, actual) { + var expected = fixture(count + output.replace(/ /g, '-') + '.txt'); + // Sometimes, the actual file lines are out of order on Windows. + // But since the point of this lib is to drain the buffer and not + // guarantee output order, we only test the length. + test.equal(actual.length, expected.length, 'should be the same length.'); + // The "fail" lines in log.js should NOT be output! + test.ok(actual.indexOf('fail') === -1, 'should not output after exit is called.'); + test.done(); + }); + }; + }); + }); + }); + + // Build individual unit tests for exit codes. + var codes = [0, 1, 123]; + codes.forEach(function(code) { + var command = 'node log.js ' + code + ' 10 stdout stderr'; + exports['exit']['exit code (' + command + ')'] = function(test) { + test.expect(1); + run(command, function(actual) { + // The specified exit code should be passed through. + test.equal(actual, code, 'should exit with ' + code + ' error code.'); + test.done(); + }); + }; + }); +} + +// Don't bother building tests if grep wasn't found, otherwise everything will +// fail and the error will get lost. +if (grep) { + buildTests(); +} diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/10-stderr.txt b/platforms/android/assets/www/node_modules/exit/test/fixtures/10-stderr.txt new file mode 100644 index 0000000..2859200 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/10-stderr.txt @@ -0,0 +1,10 @@ +stderr 0 +stderr 1 +stderr 2 +stderr 3 +stderr 4 +stderr 5 +stderr 6 +stderr 7 +stderr 8 +stderr 9 diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/10-stdout-stderr.txt b/platforms/android/assets/www/node_modules/exit/test/fixtures/10-stdout-stderr.txt new file mode 100644 index 0000000..9de8616 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/10-stdout-stderr.txt @@ -0,0 +1,20 @@ +stdout 0 +stderr 0 +stdout 1 +stdout 2 +stderr 1 +stdout 3 +stderr 2 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/10-stdout.txt b/platforms/android/assets/www/node_modules/exit/test/fixtures/10-stdout.txt new file mode 100644 index 0000000..1ce90dc --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/10-stdout.txt @@ -0,0 +1,10 @@ +stdout 0 +stdout 1 +stdout 2 +stdout 3 +stdout 4 +stdout 5 +stdout 6 +stdout 7 +stdout 8 +stdout 9 diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/100-stderr.txt b/platforms/android/assets/www/node_modules/exit/test/fixtures/100-stderr.txt new file mode 100644 index 0000000..3a78c85 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/100-stderr.txt @@ -0,0 +1,100 @@ +stderr 0 +stderr 1 +stderr 2 +stderr 3 +stderr 4 +stderr 5 +stderr 6 +stderr 7 +stderr 8 +stderr 9 +stderr 10 +stderr 11 +stderr 12 +stderr 13 +stderr 14 +stderr 15 +stderr 16 +stderr 17 +stderr 18 +stderr 19 +stderr 20 +stderr 21 +stderr 22 +stderr 23 +stderr 24 +stderr 25 +stderr 26 +stderr 27 +stderr 28 +stderr 29 +stderr 30 +stderr 31 +stderr 32 +stderr 33 +stderr 34 +stderr 35 +stderr 36 +stderr 37 +stderr 38 +stderr 39 +stderr 40 +stderr 41 +stderr 42 +stderr 43 +stderr 44 +stderr 45 +stderr 46 +stderr 47 +stderr 48 +stderr 49 +stderr 50 +stderr 51 +stderr 52 +stderr 53 +stderr 54 +stderr 55 +stderr 56 +stderr 57 +stderr 58 +stderr 59 +stderr 60 +stderr 61 +stderr 62 +stderr 63 +stderr 64 +stderr 65 +stderr 66 +stderr 67 +stderr 68 +stderr 69 +stderr 70 +stderr 71 +stderr 72 +stderr 73 +stderr 74 +stderr 75 +stderr 76 +stderr 77 +stderr 78 +stderr 79 +stderr 80 +stderr 81 +stderr 82 +stderr 83 +stderr 84 +stderr 85 +stderr 86 +stderr 87 +stderr 88 +stderr 89 +stderr 90 +stderr 91 +stderr 92 +stderr 93 +stderr 94 +stderr 95 +stderr 96 +stderr 97 +stderr 98 +stderr 99 diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/100-stdout-stderr.txt b/platforms/android/assets/www/node_modules/exit/test/fixtures/100-stdout-stderr.txt new file mode 100644 index 0000000..65f35f4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/100-stdout-stderr.txt @@ -0,0 +1,200 @@ +stdout 0 +stderr 0 +stdout 1 +stderr 1 +stdout 2 +stderr 2 +stdout 3 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 +stdout 10 +stderr 10 +stdout 11 +stderr 11 +stdout 12 +stderr 12 +stdout 13 +stderr 13 +stdout 14 +stderr 14 +stdout 15 +stderr 15 +stdout 16 +stderr 16 +stdout 17 +stderr 17 +stdout 18 +stderr 18 +stdout 19 +stderr 19 +stdout 20 +stderr 20 +stdout 21 +stderr 21 +stdout 22 +stderr 22 +stdout 23 +stderr 23 +stdout 24 +stderr 24 +stdout 25 +stderr 25 +stdout 26 +stderr 26 +stdout 27 +stderr 27 +stdout 28 +stderr 28 +stdout 29 +stderr 29 +stdout 30 +stderr 30 +stdout 31 +stderr 31 +stdout 32 +stderr 32 +stdout 33 +stderr 33 +stdout 34 +stderr 34 +stdout 35 +stderr 35 +stdout 36 +stderr 36 +stdout 37 +stderr 37 +stdout 38 +stderr 38 +stdout 39 +stderr 39 +stdout 40 +stderr 40 +stdout 41 +stderr 41 +stdout 42 +stderr 42 +stdout 43 +stderr 43 +stdout 44 +stderr 44 +stdout 45 +stderr 45 +stdout 46 +stderr 46 +stdout 47 +stderr 47 +stdout 48 +stderr 48 +stdout 49 +stderr 49 +stdout 50 +stderr 50 +stdout 51 +stderr 51 +stdout 52 +stderr 52 +stdout 53 +stderr 53 +stdout 54 +stderr 54 +stdout 55 +stderr 55 +stdout 56 +stderr 56 +stdout 57 +stderr 57 +stdout 58 +stderr 58 +stdout 59 +stderr 59 +stdout 60 +stderr 60 +stdout 61 +stderr 61 +stdout 62 +stderr 62 +stdout 63 +stderr 63 +stdout 64 +stderr 64 +stdout 65 +stderr 65 +stdout 66 +stderr 66 +stdout 67 +stderr 67 +stdout 68 +stderr 68 +stdout 69 +stderr 69 +stdout 70 +stderr 70 +stdout 71 +stderr 71 +stdout 72 +stderr 72 +stdout 73 +stderr 73 +stdout 74 +stderr 74 +stdout 75 +stderr 75 +stdout 76 +stderr 76 +stdout 77 +stderr 77 +stdout 78 +stderr 78 +stdout 79 +stderr 79 +stdout 80 +stderr 80 +stdout 81 +stderr 81 +stdout 82 +stderr 82 +stdout 83 +stderr 83 +stdout 84 +stderr 84 +stdout 85 +stderr 85 +stdout 86 +stderr 86 +stdout 87 +stderr 87 +stdout 88 +stderr 88 +stdout 89 +stderr 89 +stdout 90 +stderr 90 +stdout 91 +stderr 91 +stdout 92 +stderr 92 +stdout 93 +stderr 93 +stdout 94 +stderr 94 +stdout 95 +stderr 95 +stdout 96 +stderr 96 +stdout 97 +stderr 97 +stdout 98 +stderr 98 +stdout 99 +stderr 99 diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/100-stdout.txt b/platforms/android/assets/www/node_modules/exit/test/fixtures/100-stdout.txt new file mode 100644 index 0000000..5d9cac2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/100-stdout.txt @@ -0,0 +1,100 @@ +stdout 0 +stdout 1 +stdout 2 +stdout 3 +stdout 4 +stdout 5 +stdout 6 +stdout 7 +stdout 8 +stdout 9 +stdout 10 +stdout 11 +stdout 12 +stdout 13 +stdout 14 +stdout 15 +stdout 16 +stdout 17 +stdout 18 +stdout 19 +stdout 20 +stdout 21 +stdout 22 +stdout 23 +stdout 24 +stdout 25 +stdout 26 +stdout 27 +stdout 28 +stdout 29 +stdout 30 +stdout 31 +stdout 32 +stdout 33 +stdout 34 +stdout 35 +stdout 36 +stdout 37 +stdout 38 +stdout 39 +stdout 40 +stdout 41 +stdout 42 +stdout 43 +stdout 44 +stdout 45 +stdout 46 +stdout 47 +stdout 48 +stdout 49 +stdout 50 +stdout 51 +stdout 52 +stdout 53 +stdout 54 +stdout 55 +stdout 56 +stdout 57 +stdout 58 +stdout 59 +stdout 60 +stdout 61 +stdout 62 +stdout 63 +stdout 64 +stdout 65 +stdout 66 +stdout 67 +stdout 68 +stdout 69 +stdout 70 +stdout 71 +stdout 72 +stdout 73 +stdout 74 +stdout 75 +stdout 76 +stdout 77 +stdout 78 +stdout 79 +stdout 80 +stdout 81 +stdout 82 +stdout 83 +stdout 84 +stdout 85 +stdout 86 +stdout 87 +stdout 88 +stdout 89 +stdout 90 +stdout 91 +stdout 92 +stdout 93 +stdout 94 +stdout 95 +stdout 96 +stdout 97 +stdout 98 +stdout 99 diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/1000-stderr.txt b/platforms/android/assets/www/node_modules/exit/test/fixtures/1000-stderr.txt new file mode 100644 index 0000000..d637510 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/1000-stderr.txt @@ -0,0 +1,1000 @@ +stderr 0 +stderr 1 +stderr 2 +stderr 3 +stderr 4 +stderr 5 +stderr 6 +stderr 7 +stderr 8 +stderr 9 +stderr 10 +stderr 11 +stderr 12 +stderr 13 +stderr 14 +stderr 15 +stderr 16 +stderr 17 +stderr 18 +stderr 19 +stderr 20 +stderr 21 +stderr 22 +stderr 23 +stderr 24 +stderr 25 +stderr 26 +stderr 27 +stderr 28 +stderr 29 +stderr 30 +stderr 31 +stderr 32 +stderr 33 +stderr 34 +stderr 35 +stderr 36 +stderr 37 +stderr 38 +stderr 39 +stderr 40 +stderr 41 +stderr 42 +stderr 43 +stderr 44 +stderr 45 +stderr 46 +stderr 47 +stderr 48 +stderr 49 +stderr 50 +stderr 51 +stderr 52 +stderr 53 +stderr 54 +stderr 55 +stderr 56 +stderr 57 +stderr 58 +stderr 59 +stderr 60 +stderr 61 +stderr 62 +stderr 63 +stderr 64 +stderr 65 +stderr 66 +stderr 67 +stderr 68 +stderr 69 +stderr 70 +stderr 71 +stderr 72 +stderr 73 +stderr 74 +stderr 75 +stderr 76 +stderr 77 +stderr 78 +stderr 79 +stderr 80 +stderr 81 +stderr 82 +stderr 83 +stderr 84 +stderr 85 +stderr 86 +stderr 87 +stderr 88 +stderr 89 +stderr 90 +stderr 91 +stderr 92 +stderr 93 +stderr 94 +stderr 95 +stderr 96 +stderr 97 +stderr 98 +stderr 99 +stderr 100 +stderr 101 +stderr 102 +stderr 103 +stderr 104 +stderr 105 +stderr 106 +stderr 107 +stderr 108 +stderr 109 +stderr 110 +stderr 111 +stderr 112 +stderr 113 +stderr 114 +stderr 115 +stderr 116 +stderr 117 +stderr 118 +stderr 119 +stderr 120 +stderr 121 +stderr 122 +stderr 123 +stderr 124 +stderr 125 +stderr 126 +stderr 127 +stderr 128 +stderr 129 +stderr 130 +stderr 131 +stderr 132 +stderr 133 +stderr 134 +stderr 135 +stderr 136 +stderr 137 +stderr 138 +stderr 139 +stderr 140 +stderr 141 +stderr 142 +stderr 143 +stderr 144 +stderr 145 +stderr 146 +stderr 147 +stderr 148 +stderr 149 +stderr 150 +stderr 151 +stderr 152 +stderr 153 +stderr 154 +stderr 155 +stderr 156 +stderr 157 +stderr 158 +stderr 159 +stderr 160 +stderr 161 +stderr 162 +stderr 163 +stderr 164 +stderr 165 +stderr 166 +stderr 167 +stderr 168 +stderr 169 +stderr 170 +stderr 171 +stderr 172 +stderr 173 +stderr 174 +stderr 175 +stderr 176 +stderr 177 +stderr 178 +stderr 179 +stderr 180 +stderr 181 +stderr 182 +stderr 183 +stderr 184 +stderr 185 +stderr 186 +stderr 187 +stderr 188 +stderr 189 +stderr 190 +stderr 191 +stderr 192 +stderr 193 +stderr 194 +stderr 195 +stderr 196 +stderr 197 +stderr 198 +stderr 199 +stderr 200 +stderr 201 +stderr 202 +stderr 203 +stderr 204 +stderr 205 +stderr 206 +stderr 207 +stderr 208 +stderr 209 +stderr 210 +stderr 211 +stderr 212 +stderr 213 +stderr 214 +stderr 215 +stderr 216 +stderr 217 +stderr 218 +stderr 219 +stderr 220 +stderr 221 +stderr 222 +stderr 223 +stderr 224 +stderr 225 +stderr 226 +stderr 227 +stderr 228 +stderr 229 +stderr 230 +stderr 231 +stderr 232 +stderr 233 +stderr 234 +stderr 235 +stderr 236 +stderr 237 +stderr 238 +stderr 239 +stderr 240 +stderr 241 +stderr 242 +stderr 243 +stderr 244 +stderr 245 +stderr 246 +stderr 247 +stderr 248 +stderr 249 +stderr 250 +stderr 251 +stderr 252 +stderr 253 +stderr 254 +stderr 255 +stderr 256 +stderr 257 +stderr 258 +stderr 259 +stderr 260 +stderr 261 +stderr 262 +stderr 263 +stderr 264 +stderr 265 +stderr 266 +stderr 267 +stderr 268 +stderr 269 +stderr 270 +stderr 271 +stderr 272 +stderr 273 +stderr 274 +stderr 275 +stderr 276 +stderr 277 +stderr 278 +stderr 279 +stderr 280 +stderr 281 +stderr 282 +stderr 283 +stderr 284 +stderr 285 +stderr 286 +stderr 287 +stderr 288 +stderr 289 +stderr 290 +stderr 291 +stderr 292 +stderr 293 +stderr 294 +stderr 295 +stderr 296 +stderr 297 +stderr 298 +stderr 299 +stderr 300 +stderr 301 +stderr 302 +stderr 303 +stderr 304 +stderr 305 +stderr 306 +stderr 307 +stderr 308 +stderr 309 +stderr 310 +stderr 311 +stderr 312 +stderr 313 +stderr 314 +stderr 315 +stderr 316 +stderr 317 +stderr 318 +stderr 319 +stderr 320 +stderr 321 +stderr 322 +stderr 323 +stderr 324 +stderr 325 +stderr 326 +stderr 327 +stderr 328 +stderr 329 +stderr 330 +stderr 331 +stderr 332 +stderr 333 +stderr 334 +stderr 335 +stderr 336 +stderr 337 +stderr 338 +stderr 339 +stderr 340 +stderr 341 +stderr 342 +stderr 343 +stderr 344 +stderr 345 +stderr 346 +stderr 347 +stderr 348 +stderr 349 +stderr 350 +stderr 351 +stderr 352 +stderr 353 +stderr 354 +stderr 355 +stderr 356 +stderr 357 +stderr 358 +stderr 359 +stderr 360 +stderr 361 +stderr 362 +stderr 363 +stderr 364 +stderr 365 +stderr 366 +stderr 367 +stderr 368 +stderr 369 +stderr 370 +stderr 371 +stderr 372 +stderr 373 +stderr 374 +stderr 375 +stderr 376 +stderr 377 +stderr 378 +stderr 379 +stderr 380 +stderr 381 +stderr 382 +stderr 383 +stderr 384 +stderr 385 +stderr 386 +stderr 387 +stderr 388 +stderr 389 +stderr 390 +stderr 391 +stderr 392 +stderr 393 +stderr 394 +stderr 395 +stderr 396 +stderr 397 +stderr 398 +stderr 399 +stderr 400 +stderr 401 +stderr 402 +stderr 403 +stderr 404 +stderr 405 +stderr 406 +stderr 407 +stderr 408 +stderr 409 +stderr 410 +stderr 411 +stderr 412 +stderr 413 +stderr 414 +stderr 415 +stderr 416 +stderr 417 +stderr 418 +stderr 419 +stderr 420 +stderr 421 +stderr 422 +stderr 423 +stderr 424 +stderr 425 +stderr 426 +stderr 427 +stderr 428 +stderr 429 +stderr 430 +stderr 431 +stderr 432 +stderr 433 +stderr 434 +stderr 435 +stderr 436 +stderr 437 +stderr 438 +stderr 439 +stderr 440 +stderr 441 +stderr 442 +stderr 443 +stderr 444 +stderr 445 +stderr 446 +stderr 447 +stderr 448 +stderr 449 +stderr 450 +stderr 451 +stderr 452 +stderr 453 +stderr 454 +stderr 455 +stderr 456 +stderr 457 +stderr 458 +stderr 459 +stderr 460 +stderr 461 +stderr 462 +stderr 463 +stderr 464 +stderr 465 +stderr 466 +stderr 467 +stderr 468 +stderr 469 +stderr 470 +stderr 471 +stderr 472 +stderr 473 +stderr 474 +stderr 475 +stderr 476 +stderr 477 +stderr 478 +stderr 479 +stderr 480 +stderr 481 +stderr 482 +stderr 483 +stderr 484 +stderr 485 +stderr 486 +stderr 487 +stderr 488 +stderr 489 +stderr 490 +stderr 491 +stderr 492 +stderr 493 +stderr 494 +stderr 495 +stderr 496 +stderr 497 +stderr 498 +stderr 499 +stderr 500 +stderr 501 +stderr 502 +stderr 503 +stderr 504 +stderr 505 +stderr 506 +stderr 507 +stderr 508 +stderr 509 +stderr 510 +stderr 511 +stderr 512 +stderr 513 +stderr 514 +stderr 515 +stderr 516 +stderr 517 +stderr 518 +stderr 519 +stderr 520 +stderr 521 +stderr 522 +stderr 523 +stderr 524 +stderr 525 +stderr 526 +stderr 527 +stderr 528 +stderr 529 +stderr 530 +stderr 531 +stderr 532 +stderr 533 +stderr 534 +stderr 535 +stderr 536 +stderr 537 +stderr 538 +stderr 539 +stderr 540 +stderr 541 +stderr 542 +stderr 543 +stderr 544 +stderr 545 +stderr 546 +stderr 547 +stderr 548 +stderr 549 +stderr 550 +stderr 551 +stderr 552 +stderr 553 +stderr 554 +stderr 555 +stderr 556 +stderr 557 +stderr 558 +stderr 559 +stderr 560 +stderr 561 +stderr 562 +stderr 563 +stderr 564 +stderr 565 +stderr 566 +stderr 567 +stderr 568 +stderr 569 +stderr 570 +stderr 571 +stderr 572 +stderr 573 +stderr 574 +stderr 575 +stderr 576 +stderr 577 +stderr 578 +stderr 579 +stderr 580 +stderr 581 +stderr 582 +stderr 583 +stderr 584 +stderr 585 +stderr 586 +stderr 587 +stderr 588 +stderr 589 +stderr 590 +stderr 591 +stderr 592 +stderr 593 +stderr 594 +stderr 595 +stderr 596 +stderr 597 +stderr 598 +stderr 599 +stderr 600 +stderr 601 +stderr 602 +stderr 603 +stderr 604 +stderr 605 +stderr 606 +stderr 607 +stderr 608 +stderr 609 +stderr 610 +stderr 611 +stderr 612 +stderr 613 +stderr 614 +stderr 615 +stderr 616 +stderr 617 +stderr 618 +stderr 619 +stderr 620 +stderr 621 +stderr 622 +stderr 623 +stderr 624 +stderr 625 +stderr 626 +stderr 627 +stderr 628 +stderr 629 +stderr 630 +stderr 631 +stderr 632 +stderr 633 +stderr 634 +stderr 635 +stderr 636 +stderr 637 +stderr 638 +stderr 639 +stderr 640 +stderr 641 +stderr 642 +stderr 643 +stderr 644 +stderr 645 +stderr 646 +stderr 647 +stderr 648 +stderr 649 +stderr 650 +stderr 651 +stderr 652 +stderr 653 +stderr 654 +stderr 655 +stderr 656 +stderr 657 +stderr 658 +stderr 659 +stderr 660 +stderr 661 +stderr 662 +stderr 663 +stderr 664 +stderr 665 +stderr 666 +stderr 667 +stderr 668 +stderr 669 +stderr 670 +stderr 671 +stderr 672 +stderr 673 +stderr 674 +stderr 675 +stderr 676 +stderr 677 +stderr 678 +stderr 679 +stderr 680 +stderr 681 +stderr 682 +stderr 683 +stderr 684 +stderr 685 +stderr 686 +stderr 687 +stderr 688 +stderr 689 +stderr 690 +stderr 691 +stderr 692 +stderr 693 +stderr 694 +stderr 695 +stderr 696 +stderr 697 +stderr 698 +stderr 699 +stderr 700 +stderr 701 +stderr 702 +stderr 703 +stderr 704 +stderr 705 +stderr 706 +stderr 707 +stderr 708 +stderr 709 +stderr 710 +stderr 711 +stderr 712 +stderr 713 +stderr 714 +stderr 715 +stderr 716 +stderr 717 +stderr 718 +stderr 719 +stderr 720 +stderr 721 +stderr 722 +stderr 723 +stderr 724 +stderr 725 +stderr 726 +stderr 727 +stderr 728 +stderr 729 +stderr 730 +stderr 731 +stderr 732 +stderr 733 +stderr 734 +stderr 735 +stderr 736 +stderr 737 +stderr 738 +stderr 739 +stderr 740 +stderr 741 +stderr 742 +stderr 743 +stderr 744 +stderr 745 +stderr 746 +stderr 747 +stderr 748 +stderr 749 +stderr 750 +stderr 751 +stderr 752 +stderr 753 +stderr 754 +stderr 755 +stderr 756 +stderr 757 +stderr 758 +stderr 759 +stderr 760 +stderr 761 +stderr 762 +stderr 763 +stderr 764 +stderr 765 +stderr 766 +stderr 767 +stderr 768 +stderr 769 +stderr 770 +stderr 771 +stderr 772 +stderr 773 +stderr 774 +stderr 775 +stderr 776 +stderr 777 +stderr 778 +stderr 779 +stderr 780 +stderr 781 +stderr 782 +stderr 783 +stderr 784 +stderr 785 +stderr 786 +stderr 787 +stderr 788 +stderr 789 +stderr 790 +stderr 791 +stderr 792 +stderr 793 +stderr 794 +stderr 795 +stderr 796 +stderr 797 +stderr 798 +stderr 799 +stderr 800 +stderr 801 +stderr 802 +stderr 803 +stderr 804 +stderr 805 +stderr 806 +stderr 807 +stderr 808 +stderr 809 +stderr 810 +stderr 811 +stderr 812 +stderr 813 +stderr 814 +stderr 815 +stderr 816 +stderr 817 +stderr 818 +stderr 819 +stderr 820 +stderr 821 +stderr 822 +stderr 823 +stderr 824 +stderr 825 +stderr 826 +stderr 827 +stderr 828 +stderr 829 +stderr 830 +stderr 831 +stderr 832 +stderr 833 +stderr 834 +stderr 835 +stderr 836 +stderr 837 +stderr 838 +stderr 839 +stderr 840 +stderr 841 +stderr 842 +stderr 843 +stderr 844 +stderr 845 +stderr 846 +stderr 847 +stderr 848 +stderr 849 +stderr 850 +stderr 851 +stderr 852 +stderr 853 +stderr 854 +stderr 855 +stderr 856 +stderr 857 +stderr 858 +stderr 859 +stderr 860 +stderr 861 +stderr 862 +stderr 863 +stderr 864 +stderr 865 +stderr 866 +stderr 867 +stderr 868 +stderr 869 +stderr 870 +stderr 871 +stderr 872 +stderr 873 +stderr 874 +stderr 875 +stderr 876 +stderr 877 +stderr 878 +stderr 879 +stderr 880 +stderr 881 +stderr 882 +stderr 883 +stderr 884 +stderr 885 +stderr 886 +stderr 887 +stderr 888 +stderr 889 +stderr 890 +stderr 891 +stderr 892 +stderr 893 +stderr 894 +stderr 895 +stderr 896 +stderr 897 +stderr 898 +stderr 899 +stderr 900 +stderr 901 +stderr 902 +stderr 903 +stderr 904 +stderr 905 +stderr 906 +stderr 907 +stderr 908 +stderr 909 +stderr 910 +stderr 911 +stderr 912 +stderr 913 +stderr 914 +stderr 915 +stderr 916 +stderr 917 +stderr 918 +stderr 919 +stderr 920 +stderr 921 +stderr 922 +stderr 923 +stderr 924 +stderr 925 +stderr 926 +stderr 927 +stderr 928 +stderr 929 +stderr 930 +stderr 931 +stderr 932 +stderr 933 +stderr 934 +stderr 935 +stderr 936 +stderr 937 +stderr 938 +stderr 939 +stderr 940 +stderr 941 +stderr 942 +stderr 943 +stderr 944 +stderr 945 +stderr 946 +stderr 947 +stderr 948 +stderr 949 +stderr 950 +stderr 951 +stderr 952 +stderr 953 +stderr 954 +stderr 955 +stderr 956 +stderr 957 +stderr 958 +stderr 959 +stderr 960 +stderr 961 +stderr 962 +stderr 963 +stderr 964 +stderr 965 +stderr 966 +stderr 967 +stderr 968 +stderr 969 +stderr 970 +stderr 971 +stderr 972 +stderr 973 +stderr 974 +stderr 975 +stderr 976 +stderr 977 +stderr 978 +stderr 979 +stderr 980 +stderr 981 +stderr 982 +stderr 983 +stderr 984 +stderr 985 +stderr 986 +stderr 987 +stderr 988 +stderr 989 +stderr 990 +stderr 991 +stderr 992 +stderr 993 +stderr 994 +stderr 995 +stderr 996 +stderr 997 +stderr 998 +stderr 999 diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/1000-stdout-stderr.txt b/platforms/android/assets/www/node_modules/exit/test/fixtures/1000-stdout-stderr.txt new file mode 100644 index 0000000..4fde2b4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/1000-stdout-stderr.txt @@ -0,0 +1,2000 @@ +stdout 0 +stderr 0 +stdout 1 +stderr 1 +stdout 2 +stderr 2 +stdout 3 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 +stdout 10 +stderr 10 +stdout 11 +stderr 11 +stdout 12 +stderr 12 +stdout 13 +stderr 13 +stdout 14 +stderr 14 +stdout 15 +stderr 15 +stdout 16 +stderr 16 +stdout 17 +stderr 17 +stdout 18 +stderr 18 +stdout 19 +stderr 19 +stdout 20 +stderr 20 +stdout 21 +stderr 21 +stdout 22 +stderr 22 +stdout 23 +stderr 23 +stdout 24 +stderr 24 +stdout 25 +stderr 25 +stdout 26 +stderr 26 +stdout 27 +stderr 27 +stdout 28 +stderr 28 +stdout 29 +stderr 29 +stdout 30 +stderr 30 +stdout 31 +stderr 31 +stdout 32 +stderr 32 +stdout 33 +stderr 33 +stdout 34 +stderr 34 +stdout 35 +stderr 35 +stdout 36 +stderr 36 +stdout 37 +stderr 37 +stdout 38 +stderr 38 +stdout 39 +stderr 39 +stdout 40 +stderr 40 +stdout 41 +stderr 41 +stdout 42 +stderr 42 +stdout 43 +stderr 43 +stdout 44 +stderr 44 +stdout 45 +stderr 45 +stdout 46 +stderr 46 +stdout 47 +stderr 47 +stdout 48 +stderr 48 +stdout 49 +stderr 49 +stdout 50 +stderr 50 +stdout 51 +stderr 51 +stdout 52 +stderr 52 +stdout 53 +stderr 53 +stdout 54 +stderr 54 +stdout 55 +stderr 55 +stdout 56 +stderr 56 +stdout 57 +stderr 57 +stdout 58 +stderr 58 +stdout 59 +stderr 59 +stdout 60 +stderr 60 +stdout 61 +stderr 61 +stdout 62 +stderr 62 +stdout 63 +stderr 63 +stdout 64 +stderr 64 +stdout 65 +stderr 65 +stdout 66 +stderr 66 +stdout 67 +stderr 67 +stdout 68 +stderr 68 +stdout 69 +stderr 69 +stdout 70 +stderr 70 +stdout 71 +stderr 71 +stdout 72 +stderr 72 +stdout 73 +stderr 73 +stdout 74 +stderr 74 +stdout 75 +stderr 75 +stdout 76 +stderr 76 +stdout 77 +stderr 77 +stdout 78 +stderr 78 +stdout 79 +stderr 79 +stdout 80 +stderr 80 +stdout 81 +stderr 81 +stdout 82 +stderr 82 +stdout 83 +stderr 83 +stdout 84 +stderr 84 +stdout 85 +stderr 85 +stdout 86 +stderr 86 +stdout 87 +stderr 87 +stdout 88 +stderr 88 +stdout 89 +stderr 89 +stdout 90 +stderr 90 +stdout 91 +stderr 91 +stdout 92 +stderr 92 +stdout 93 +stderr 93 +stdout 94 +stderr 94 +stdout 95 +stderr 95 +stdout 96 +stderr 96 +stdout 97 +stderr 97 +stdout 98 +stderr 98 +stdout 99 +stderr 99 +stdout 100 +stderr 100 +stdout 101 +stderr 101 +stdout 102 +stderr 102 +stdout 103 +stderr 103 +stdout 104 +stderr 104 +stdout 105 +stderr 105 +stdout 106 +stderr 106 +stdout 107 +stderr 107 +stdout 108 +stderr 108 +stdout 109 +stderr 109 +stdout 110 +stderr 110 +stdout 111 +stderr 111 +stdout 112 +stderr 112 +stdout 113 +stderr 113 +stdout 114 +stderr 114 +stdout 115 +stderr 115 +stdout 116 +stderr 116 +stdout 117 +stderr 117 +stdout 118 +stderr 118 +stdout 119 +stderr 119 +stdout 120 +stderr 120 +stdout 121 +stderr 121 +stdout 122 +stderr 122 +stdout 123 +stderr 123 +stdout 124 +stderr 124 +stdout 125 +stderr 125 +stdout 126 +stderr 126 +stdout 127 +stderr 127 +stdout 128 +stderr 128 +stdout 129 +stderr 129 +stdout 130 +stderr 130 +stdout 131 +stderr 131 +stdout 132 +stderr 132 +stdout 133 +stderr 133 +stdout 134 +stderr 134 +stdout 135 +stderr 135 +stdout 136 +stderr 136 +stdout 137 +stderr 137 +stdout 138 +stderr 138 +stdout 139 +stderr 139 +stdout 140 +stderr 140 +stdout 141 +stderr 141 +stdout 142 +stderr 142 +stdout 143 +stderr 143 +stdout 144 +stderr 144 +stdout 145 +stderr 145 +stdout 146 +stderr 146 +stdout 147 +stderr 147 +stdout 148 +stderr 148 +stdout 149 +stderr 149 +stdout 150 +stderr 150 +stdout 151 +stderr 151 +stdout 152 +stderr 152 +stdout 153 +stderr 153 +stdout 154 +stderr 154 +stdout 155 +stderr 155 +stdout 156 +stderr 156 +stdout 157 +stderr 157 +stdout 158 +stderr 158 +stdout 159 +stderr 159 +stdout 160 +stderr 160 +stdout 161 +stderr 161 +stdout 162 +stderr 162 +stdout 163 +stderr 163 +stdout 164 +stderr 164 +stdout 165 +stderr 165 +stdout 166 +stderr 166 +stdout 167 +stderr 167 +stdout 168 +stderr 168 +stdout 169 +stderr 169 +stdout 170 +stderr 170 +stdout 171 +stderr 171 +stdout 172 +stderr 172 +stdout 173 +stderr 173 +stdout 174 +stderr 174 +stdout 175 +stderr 175 +stdout 176 +stderr 176 +stdout 177 +stderr 177 +stdout 178 +stderr 178 +stdout 179 +stderr 179 +stdout 180 +stderr 180 +stdout 181 +stderr 181 +stdout 182 +stderr 182 +stdout 183 +stderr 183 +stdout 184 +stderr 184 +stdout 185 +stderr 185 +stdout 186 +stderr 186 +stdout 187 +stderr 187 +stdout 188 +stderr 188 +stdout 189 +stderr 189 +stdout 190 +stderr 190 +stdout 191 +stderr 191 +stdout 192 +stderr 192 +stdout 193 +stderr 193 +stdout 194 +stderr 194 +stdout 195 +stderr 195 +stdout 196 +stderr 196 +stdout 197 +stderr 197 +stdout 198 +stderr 198 +stdout 199 +stderr 199 +stdout 200 +stderr 200 +stdout 201 +stderr 201 +stdout 202 +stderr 202 +stdout 203 +stderr 203 +stdout 204 +stderr 204 +stdout 205 +stderr 205 +stdout 206 +stderr 206 +stdout 207 +stderr 207 +stdout 208 +stderr 208 +stdout 209 +stderr 209 +stdout 210 +stderr 210 +stdout 211 +stderr 211 +stdout 212 +stderr 212 +stdout 213 +stderr 213 +stdout 214 +stderr 214 +stdout 215 +stderr 215 +stdout 216 +stderr 216 +stdout 217 +stderr 217 +stdout 218 +stderr 218 +stdout 219 +stderr 219 +stdout 220 +stderr 220 +stdout 221 +stderr 221 +stdout 222 +stderr 222 +stdout 223 +stderr 223 +stdout 224 +stderr 224 +stdout 225 +stderr 225 +stdout 226 +stderr 226 +stdout 227 +stderr 227 +stdout 228 +stderr 228 +stdout 229 +stderr 229 +stdout 230 +stderr 230 +stdout 231 +stderr 231 +stdout 232 +stderr 232 +stdout 233 +stderr 233 +stdout 234 +stderr 234 +stdout 235 +stderr 235 +stdout 236 +stderr 236 +stdout 237 +stderr 237 +stdout 238 +stderr 238 +stdout 239 +stderr 239 +stdout 240 +stderr 240 +stdout 241 +stderr 241 +stdout 242 +stderr 242 +stdout 243 +stderr 243 +stdout 244 +stderr 244 +stdout 245 +stderr 245 +stdout 246 +stderr 246 +stdout 247 +stderr 247 +stdout 248 +stderr 248 +stdout 249 +stderr 249 +stdout 250 +stderr 250 +stdout 251 +stderr 251 +stdout 252 +stderr 252 +stdout 253 +stderr 253 +stdout 254 +stderr 254 +stdout 255 +stderr 255 +stdout 256 +stderr 256 +stdout 257 +stderr 257 +stdout 258 +stderr 258 +stdout 259 +stderr 259 +stdout 260 +stderr 260 +stdout 261 +stderr 261 +stdout 262 +stderr 262 +stdout 263 +stderr 263 +stdout 264 +stderr 264 +stdout 265 +stderr 265 +stdout 266 +stderr 266 +stdout 267 +stderr 267 +stdout 268 +stderr 268 +stdout 269 +stderr 269 +stdout 270 +stderr 270 +stdout 271 +stderr 271 +stdout 272 +stderr 272 +stdout 273 +stderr 273 +stdout 274 +stderr 274 +stdout 275 +stderr 275 +stdout 276 +stderr 276 +stdout 277 +stderr 277 +stdout 278 +stderr 278 +stdout 279 +stderr 279 +stdout 280 +stderr 280 +stdout 281 +stderr 281 +stdout 282 +stderr 282 +stdout 283 +stderr 283 +stdout 284 +stderr 284 +stdout 285 +stderr 285 +stdout 286 +stderr 286 +stdout 287 +stderr 287 +stdout 288 +stderr 288 +stdout 289 +stderr 289 +stdout 290 +stderr 290 +stdout 291 +stderr 291 +stdout 292 +stderr 292 +stdout 293 +stderr 293 +stdout 294 +stderr 294 +stdout 295 +stderr 295 +stdout 296 +stderr 296 +stdout 297 +stderr 297 +stdout 298 +stderr 298 +stdout 299 +stderr 299 +stdout 300 +stderr 300 +stdout 301 +stderr 301 +stdout 302 +stderr 302 +stdout 303 +stderr 303 +stdout 304 +stderr 304 +stdout 305 +stderr 305 +stdout 306 +stderr 306 +stdout 307 +stderr 307 +stdout 308 +stderr 308 +stdout 309 +stderr 309 +stdout 310 +stderr 310 +stdout 311 +stderr 311 +stdout 312 +stderr 312 +stdout 313 +stderr 313 +stdout 314 +stderr 314 +stdout 315 +stderr 315 +stdout 316 +stderr 316 +stdout 317 +stderr 317 +stdout 318 +stderr 318 +stdout 319 +stderr 319 +stdout 320 +stderr 320 +stdout 321 +stderr 321 +stdout 322 +stderr 322 +stdout 323 +stderr 323 +stdout 324 +stderr 324 +stdout 325 +stderr 325 +stdout 326 +stderr 326 +stdout 327 +stderr 327 +stdout 328 +stderr 328 +stdout 329 +stderr 329 +stdout 330 +stderr 330 +stdout 331 +stderr 331 +stdout 332 +stderr 332 +stdout 333 +stderr 333 +stdout 334 +stderr 334 +stdout 335 +stderr 335 +stdout 336 +stderr 336 +stdout 337 +stderr 337 +stdout 338 +stderr 338 +stdout 339 +stderr 339 +stdout 340 +stderr 340 +stdout 341 +stderr 341 +stdout 342 +stderr 342 +stdout 343 +stderr 343 +stdout 344 +stderr 344 +stdout 345 +stderr 345 +stdout 346 +stderr 346 +stdout 347 +stderr 347 +stdout 348 +stderr 348 +stdout 349 +stderr 349 +stdout 350 +stderr 350 +stdout 351 +stderr 351 +stdout 352 +stderr 352 +stdout 353 +stderr 353 +stdout 354 +stderr 354 +stdout 355 +stderr 355 +stdout 356 +stderr 356 +stdout 357 +stderr 357 +stdout 358 +stderr 358 +stdout 359 +stderr 359 +stdout 360 +stderr 360 +stdout 361 +stderr 361 +stdout 362 +stderr 362 +stdout 363 +stderr 363 +stdout 364 +stderr 364 +stdout 365 +stderr 365 +stdout 366 +stderr 366 +stdout 367 +stderr 367 +stdout 368 +stderr 368 +stdout 369 +stderr 369 +stdout 370 +stderr 370 +stdout 371 +stderr 371 +stdout 372 +stderr 372 +stdout 373 +stderr 373 +stdout 374 +stderr 374 +stdout 375 +stderr 375 +stdout 376 +stderr 376 +stdout 377 +stderr 377 +stdout 378 +stderr 378 +stdout 379 +stderr 379 +stdout 380 +stderr 380 +stdout 381 +stderr 381 +stdout 382 +stderr 382 +stdout 383 +stderr 383 +stdout 384 +stderr 384 +stdout 385 +stderr 385 +stdout 386 +stderr 386 +stdout 387 +stderr 387 +stdout 388 +stderr 388 +stdout 389 +stderr 389 +stdout 390 +stderr 390 +stdout 391 +stderr 391 +stdout 392 +stderr 392 +stdout 393 +stderr 393 +stdout 394 +stderr 394 +stdout 395 +stderr 395 +stdout 396 +stderr 396 +stdout 397 +stderr 397 +stdout 398 +stderr 398 +stdout 399 +stderr 399 +stdout 400 +stderr 400 +stdout 401 +stderr 401 +stdout 402 +stderr 402 +stdout 403 +stderr 403 +stdout 404 +stderr 404 +stdout 405 +stderr 405 +stdout 406 +stderr 406 +stdout 407 +stderr 407 +stdout 408 +stderr 408 +stdout 409 +stderr 409 +stdout 410 +stderr 410 +stdout 411 +stderr 411 +stdout 412 +stderr 412 +stdout 413 +stderr 413 +stdout 414 +stderr 414 +stdout 415 +stderr 415 +stdout 416 +stderr 416 +stdout 417 +stderr 417 +stdout 418 +stderr 418 +stdout 419 +stderr 419 +stdout 420 +stderr 420 +stdout 421 +stderr 421 +stdout 422 +stderr 422 +stdout 423 +stderr 423 +stdout 424 +stderr 424 +stdout 425 +stderr 425 +stdout 426 +stderr 426 +stdout 427 +stderr 427 +stdout 428 +stderr 428 +stdout 429 +stderr 429 +stdout 430 +stderr 430 +stdout 431 +stderr 431 +stdout 432 +stderr 432 +stdout 433 +stderr 433 +stdout 434 +stderr 434 +stdout 435 +stderr 435 +stdout 436 +stderr 436 +stdout 437 +stderr 437 +stdout 438 +stderr 438 +stdout 439 +stderr 439 +stdout 440 +stderr 440 +stdout 441 +stderr 441 +stdout 442 +stderr 442 +stdout 443 +stderr 443 +stdout 444 +stderr 444 +stdout 445 +stderr 445 +stdout 446 +stderr 446 +stdout 447 +stderr 447 +stdout 448 +stderr 448 +stdout 449 +stderr 449 +stdout 450 +stderr 450 +stdout 451 +stderr 451 +stdout 452 +stderr 452 +stdout 453 +stderr 453 +stdout 454 +stderr 454 +stdout 455 +stderr 455 +stdout 456 +stderr 456 +stdout 457 +stderr 457 +stdout 458 +stderr 458 +stdout 459 +stderr 459 +stdout 460 +stderr 460 +stdout 461 +stderr 461 +stdout 462 +stderr 462 +stdout 463 +stderr 463 +stdout 464 +stderr 464 +stdout 465 +stderr 465 +stdout 466 +stderr 466 +stdout 467 +stderr 467 +stdout 468 +stderr 468 +stdout 469 +stderr 469 +stdout 470 +stderr 470 +stdout 471 +stderr 471 +stdout 472 +stderr 472 +stdout 473 +stderr 473 +stdout 474 +stderr 474 +stdout 475 +stderr 475 +stdout 476 +stderr 476 +stdout 477 +stderr 477 +stdout 478 +stderr 478 +stdout 479 +stderr 479 +stdout 480 +stderr 480 +stdout 481 +stderr 481 +stdout 482 +stderr 482 +stdout 483 +stderr 483 +stdout 484 +stderr 484 +stdout 485 +stderr 485 +stdout 486 +stderr 486 +stdout 487 +stderr 487 +stdout 488 +stderr 488 +stdout 489 +stderr 489 +stdout 490 +stderr 490 +stdout 491 +stderr 491 +stdout 492 +stderr 492 +stdout 493 +stderr 493 +stdout 494 +stderr 494 +stdout 495 +stderr 495 +stdout 496 +stderr 496 +stdout 497 +stderr 497 +stdout 498 +stderr 498 +stdout 499 +stderr 499 +stdout 500 +stderr 500 +stdout 501 +stderr 501 +stdout 502 +stderr 502 +stdout 503 +stderr 503 +stdout 504 +stderr 504 +stdout 505 +stderr 505 +stdout 506 +stderr 506 +stdout 507 +stderr 507 +stdout 508 +stderr 508 +stdout 509 +stderr 509 +stdout 510 +stderr 510 +stdout 511 +stderr 511 +stdout 512 +stderr 512 +stdout 513 +stderr 513 +stdout 514 +stderr 514 +stdout 515 +stderr 515 +stdout 516 +stderr 516 +stdout 517 +stderr 517 +stdout 518 +stderr 518 +stdout 519 +stderr 519 +stdout 520 +stderr 520 +stdout 521 +stderr 521 +stdout 522 +stderr 522 +stdout 523 +stderr 523 +stdout 524 +stderr 524 +stdout 525 +stderr 525 +stdout 526 +stderr 526 +stdout 527 +stderr 527 +stdout 528 +stderr 528 +stdout 529 +stderr 529 +stdout 530 +stderr 530 +stdout 531 +stderr 531 +stdout 532 +stderr 532 +stdout 533 +stderr 533 +stdout 534 +stderr 534 +stdout 535 +stderr 535 +stdout 536 +stderr 536 +stdout 537 +stderr 537 +stdout 538 +stderr 538 +stdout 539 +stderr 539 +stdout 540 +stderr 540 +stdout 541 +stderr 541 +stdout 542 +stderr 542 +stdout 543 +stderr 543 +stdout 544 +stderr 544 +stdout 545 +stderr 545 +stdout 546 +stderr 546 +stdout 547 +stderr 547 +stdout 548 +stderr 548 +stdout 549 +stderr 549 +stdout 550 +stderr 550 +stdout 551 +stderr 551 +stdout 552 +stderr 552 +stdout 553 +stderr 553 +stdout 554 +stderr 554 +stdout 555 +stderr 555 +stdout 556 +stderr 556 +stdout 557 +stderr 557 +stdout 558 +stderr 558 +stdout 559 +stderr 559 +stdout 560 +stderr 560 +stdout 561 +stderr 561 +stdout 562 +stderr 562 +stdout 563 +stderr 563 +stdout 564 +stderr 564 +stdout 565 +stderr 565 +stdout 566 +stderr 566 +stdout 567 +stderr 567 +stdout 568 +stderr 568 +stdout 569 +stderr 569 +stdout 570 +stderr 570 +stdout 571 +stderr 571 +stdout 572 +stderr 572 +stdout 573 +stderr 573 +stdout 574 +stderr 574 +stdout 575 +stderr 575 +stdout 576 +stderr 576 +stdout 577 +stderr 577 +stdout 578 +stderr 578 +stdout 579 +stderr 579 +stdout 580 +stderr 580 +stdout 581 +stderr 581 +stdout 582 +stderr 582 +stdout 583 +stderr 583 +stdout 584 +stderr 584 +stdout 585 +stderr 585 +stdout 586 +stderr 586 +stdout 587 +stderr 587 +stdout 588 +stderr 588 +stdout 589 +stderr 589 +stdout 590 +stderr 590 +stdout 591 +stderr 591 +stdout 592 +stderr 592 +stdout 593 +stderr 593 +stdout 594 +stderr 594 +stdout 595 +stderr 595 +stdout 596 +stderr 596 +stdout 597 +stderr 597 +stdout 598 +stderr 598 +stdout 599 +stderr 599 +stdout 600 +stderr 600 +stdout 601 +stderr 601 +stdout 602 +stderr 602 +stdout 603 +stderr 603 +stdout 604 +stderr 604 +stdout 605 +stderr 605 +stdout 606 +stderr 606 +stdout 607 +stderr 607 +stdout 608 +stderr 608 +stdout 609 +stderr 609 +stdout 610 +stderr 610 +stdout 611 +stderr 611 +stdout 612 +stderr 612 +stdout 613 +stderr 613 +stdout 614 +stderr 614 +stdout 615 +stderr 615 +stdout 616 +stderr 616 +stdout 617 +stderr 617 +stdout 618 +stderr 618 +stdout 619 +stderr 619 +stdout 620 +stderr 620 +stdout 621 +stderr 621 +stdout 622 +stderr 622 +stdout 623 +stderr 623 +stdout 624 +stderr 624 +stdout 625 +stderr 625 +stdout 626 +stderr 626 +stdout 627 +stderr 627 +stdout 628 +stderr 628 +stdout 629 +stderr 629 +stdout 630 +stderr 630 +stdout 631 +stderr 631 +stdout 632 +stderr 632 +stdout 633 +stderr 633 +stdout 634 +stderr 634 +stdout 635 +stderr 635 +stdout 636 +stderr 636 +stdout 637 +stderr 637 +stdout 638 +stderr 638 +stdout 639 +stderr 639 +stdout 640 +stderr 640 +stdout 641 +stderr 641 +stdout 642 +stderr 642 +stdout 643 +stderr 643 +stdout 644 +stderr 644 +stdout 645 +stderr 645 +stdout 646 +stderr 646 +stdout 647 +stderr 647 +stdout 648 +stderr 648 +stdout 649 +stderr 649 +stdout 650 +stderr 650 +stdout 651 +stderr 651 +stdout 652 +stderr 652 +stdout 653 +stderr 653 +stdout 654 +stderr 654 +stdout 655 +stderr 655 +stdout 656 +stderr 656 +stdout 657 +stderr 657 +stdout 658 +stderr 658 +stdout 659 +stderr 659 +stdout 660 +stderr 660 +stdout 661 +stderr 661 +stdout 662 +stderr 662 +stdout 663 +stderr 663 +stdout 664 +stderr 664 +stdout 665 +stderr 665 +stdout 666 +stderr 666 +stdout 667 +stderr 667 +stdout 668 +stderr 668 +stdout 669 +stderr 669 +stdout 670 +stderr 670 +stdout 671 +stderr 671 +stdout 672 +stderr 672 +stdout 673 +stderr 673 +stdout 674 +stderr 674 +stdout 675 +stderr 675 +stdout 676 +stderr 676 +stdout 677 +stderr 677 +stdout 678 +stderr 678 +stdout 679 +stderr 679 +stdout 680 +stderr 680 +stdout 681 +stderr 681 +stdout 682 +stderr 682 +stdout 683 +stderr 683 +stdout 684 +stderr 684 +stdout 685 +stderr 685 +stdout 686 +stderr 686 +stdout 687 +stderr 687 +stdout 688 +stderr 688 +stdout 689 +stderr 689 +stdout 690 +stderr 690 +stdout 691 +stderr 691 +stdout 692 +stderr 692 +stdout 693 +stderr 693 +stdout 694 +stderr 694 +stdout 695 +stderr 695 +stdout 696 +stderr 696 +stdout 697 +stderr 697 +stdout 698 +stderr 698 +stdout 699 +stderr 699 +stdout 700 +stderr 700 +stdout 701 +stderr 701 +stdout 702 +stderr 702 +stdout 703 +stderr 703 +stdout 704 +stderr 704 +stdout 705 +stderr 705 +stdout 706 +stderr 706 +stdout 707 +stderr 707 +stdout 708 +stderr 708 +stdout 709 +stderr 709 +stdout 710 +stderr 710 +stdout 711 +stderr 711 +stdout 712 +stderr 712 +stdout 713 +stderr 713 +stdout 714 +stderr 714 +stdout 715 +stderr 715 +stdout 716 +stderr 716 +stdout 717 +stderr 717 +stdout 718 +stderr 718 +stdout 719 +stderr 719 +stdout 720 +stderr 720 +stdout 721 +stderr 721 +stdout 722 +stderr 722 +stdout 723 +stderr 723 +stdout 724 +stderr 724 +stdout 725 +stderr 725 +stdout 726 +stderr 726 +stdout 727 +stderr 727 +stdout 728 +stderr 728 +stdout 729 +stderr 729 +stdout 730 +stderr 730 +stdout 731 +stderr 731 +stdout 732 +stderr 732 +stdout 733 +stderr 733 +stdout 734 +stderr 734 +stdout 735 +stderr 735 +stdout 736 +stderr 736 +stdout 737 +stderr 737 +stdout 738 +stderr 738 +stdout 739 +stderr 739 +stdout 740 +stderr 740 +stdout 741 +stderr 741 +stdout 742 +stderr 742 +stdout 743 +stderr 743 +stdout 744 +stderr 744 +stdout 745 +stderr 745 +stdout 746 +stderr 746 +stdout 747 +stderr 747 +stdout 748 +stderr 748 +stdout 749 +stderr 749 +stdout 750 +stderr 750 +stdout 751 +stderr 751 +stdout 752 +stderr 752 +stdout 753 +stderr 753 +stdout 754 +stderr 754 +stdout 755 +stderr 755 +stdout 756 +stderr 756 +stdout 757 +stderr 757 +stdout 758 +stderr 758 +stdout 759 +stderr 759 +stdout 760 +stderr 760 +stdout 761 +stderr 761 +stdout 762 +stderr 762 +stdout 763 +stderr 763 +stdout 764 +stderr 764 +stdout 765 +stderr 765 +stdout 766 +stderr 766 +stdout 767 +stderr 767 +stdout 768 +stderr 768 +stdout 769 +stderr 769 +stdout 770 +stderr 770 +stdout 771 +stderr 771 +stdout 772 +stderr 772 +stdout 773 +stderr 773 +stdout 774 +stderr 774 +stdout 775 +stderr 775 +stdout 776 +stderr 776 +stdout 777 +stderr 777 +stdout 778 +stderr 778 +stdout 779 +stderr 779 +stdout 780 +stderr 780 +stdout 781 +stderr 781 +stdout 782 +stderr 782 +stdout 783 +stderr 783 +stdout 784 +stderr 784 +stdout 785 +stderr 785 +stdout 786 +stderr 786 +stdout 787 +stderr 787 +stdout 788 +stderr 788 +stdout 789 +stderr 789 +stdout 790 +stderr 790 +stdout 791 +stderr 791 +stdout 792 +stderr 792 +stdout 793 +stderr 793 +stdout 794 +stderr 794 +stdout 795 +stderr 795 +stdout 796 +stderr 796 +stdout 797 +stderr 797 +stdout 798 +stderr 798 +stdout 799 +stderr 799 +stdout 800 +stderr 800 +stdout 801 +stderr 801 +stdout 802 +stderr 802 +stdout 803 +stderr 803 +stdout 804 +stderr 804 +stdout 805 +stderr 805 +stdout 806 +stderr 806 +stdout 807 +stderr 807 +stdout 808 +stderr 808 +stdout 809 +stderr 809 +stdout 810 +stderr 810 +stdout 811 +stderr 811 +stdout 812 +stderr 812 +stdout 813 +stderr 813 +stdout 814 +stderr 814 +stdout 815 +stderr 815 +stdout 816 +stderr 816 +stdout 817 +stderr 817 +stdout 818 +stderr 818 +stdout 819 +stderr 819 +stdout 820 +stderr 820 +stdout 821 +stderr 821 +stdout 822 +stderr 822 +stdout 823 +stderr 823 +stdout 824 +stderr 824 +stdout 825 +stderr 825 +stdout 826 +stderr 826 +stdout 827 +stderr 827 +stdout 828 +stderr 828 +stdout 829 +stderr 829 +stdout 830 +stderr 830 +stdout 831 +stderr 831 +stdout 832 +stderr 832 +stdout 833 +stderr 833 +stdout 834 +stderr 834 +stdout 835 +stderr 835 +stdout 836 +stderr 836 +stdout 837 +stderr 837 +stdout 838 +stderr 838 +stdout 839 +stderr 839 +stdout 840 +stderr 840 +stdout 841 +stderr 841 +stdout 842 +stderr 842 +stdout 843 +stderr 843 +stdout 844 +stderr 844 +stdout 845 +stderr 845 +stdout 846 +stderr 846 +stdout 847 +stderr 847 +stdout 848 +stderr 848 +stdout 849 +stderr 849 +stdout 850 +stderr 850 +stdout 851 +stderr 851 +stdout 852 +stderr 852 +stdout 853 +stderr 853 +stdout 854 +stderr 854 +stdout 855 +stderr 855 +stdout 856 +stderr 856 +stdout 857 +stderr 857 +stdout 858 +stderr 858 +stdout 859 +stderr 859 +stdout 860 +stderr 860 +stdout 861 +stderr 861 +stdout 862 +stderr 862 +stdout 863 +stderr 863 +stdout 864 +stderr 864 +stdout 865 +stderr 865 +stdout 866 +stderr 866 +stdout 867 +stderr 867 +stdout 868 +stderr 868 +stdout 869 +stderr 869 +stdout 870 +stderr 870 +stdout 871 +stderr 871 +stdout 872 +stderr 872 +stdout 873 +stderr 873 +stdout 874 +stderr 874 +stdout 875 +stderr 875 +stdout 876 +stderr 876 +stdout 877 +stderr 877 +stdout 878 +stderr 878 +stdout 879 +stderr 879 +stdout 880 +stderr 880 +stdout 881 +stderr 881 +stdout 882 +stderr 882 +stdout 883 +stderr 883 +stdout 884 +stderr 884 +stdout 885 +stderr 885 +stdout 886 +stderr 886 +stdout 887 +stderr 887 +stdout 888 +stderr 888 +stdout 889 +stderr 889 +stdout 890 +stderr 890 +stdout 891 +stderr 891 +stdout 892 +stderr 892 +stdout 893 +stderr 893 +stdout 894 +stderr 894 +stdout 895 +stderr 895 +stdout 896 +stderr 896 +stdout 897 +stderr 897 +stdout 898 +stderr 898 +stdout 899 +stderr 899 +stdout 900 +stderr 900 +stdout 901 +stderr 901 +stdout 902 +stderr 902 +stdout 903 +stderr 903 +stdout 904 +stderr 904 +stdout 905 +stderr 905 +stdout 906 +stderr 906 +stdout 907 +stderr 907 +stdout 908 +stderr 908 +stdout 909 +stderr 909 +stdout 910 +stderr 910 +stdout 911 +stderr 911 +stdout 912 +stderr 912 +stdout 913 +stderr 913 +stdout 914 +stderr 914 +stdout 915 +stderr 915 +stdout 916 +stderr 916 +stdout 917 +stderr 917 +stdout 918 +stderr 918 +stdout 919 +stderr 919 +stdout 920 +stderr 920 +stdout 921 +stderr 921 +stdout 922 +stderr 922 +stdout 923 +stderr 923 +stdout 924 +stderr 924 +stdout 925 +stderr 925 +stdout 926 +stderr 926 +stdout 927 +stderr 927 +stdout 928 +stderr 928 +stdout 929 +stderr 929 +stdout 930 +stderr 930 +stdout 931 +stderr 931 +stdout 932 +stderr 932 +stdout 933 +stderr 933 +stdout 934 +stderr 934 +stdout 935 +stderr 935 +stdout 936 +stderr 936 +stdout 937 +stderr 937 +stdout 938 +stderr 938 +stdout 939 +stderr 939 +stdout 940 +stderr 940 +stdout 941 +stderr 941 +stdout 942 +stderr 942 +stdout 943 +stderr 943 +stdout 944 +stderr 944 +stdout 945 +stderr 945 +stdout 946 +stderr 946 +stdout 947 +stderr 947 +stdout 948 +stderr 948 +stdout 949 +stderr 949 +stdout 950 +stderr 950 +stdout 951 +stderr 951 +stdout 952 +stderr 952 +stdout 953 +stderr 953 +stdout 954 +stderr 954 +stdout 955 +stderr 955 +stdout 956 +stderr 956 +stdout 957 +stderr 957 +stdout 958 +stderr 958 +stdout 959 +stderr 959 +stdout 960 +stderr 960 +stdout 961 +stderr 961 +stdout 962 +stderr 962 +stdout 963 +stderr 963 +stdout 964 +stderr 964 +stdout 965 +stderr 965 +stdout 966 +stderr 966 +stdout 967 +stderr 967 +stdout 968 +stderr 968 +stdout 969 +stderr 969 +stdout 970 +stderr 970 +stdout 971 +stderr 971 +stdout 972 +stderr 972 +stdout 973 +stderr 973 +stdout 974 +stderr 974 +stdout 975 +stderr 975 +stdout 976 +stderr 976 +stdout 977 +stderr 977 +stdout 978 +stderr 978 +stdout 979 +stderr 979 +stdout 980 +stderr 980 +stdout 981 +stderr 981 +stdout 982 +stderr 982 +stdout 983 +stderr 983 +stdout 984 +stderr 984 +stdout 985 +stderr 985 +stdout 986 +stderr 986 +stdout 987 +stderr 987 +stdout 988 +stderr 988 +stdout 989 +stderr 989 +stdout 990 +stderr 990 +stdout 991 +stderr 991 +stdout 992 +stderr 992 +stdout 993 +stderr 993 +stdout 994 +stderr 994 +stdout 995 +stderr 995 +stdout 996 +stderr 996 +stdout 997 +stderr 997 +stdout 998 +stderr 998 +stdout 999 +stderr 999 diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/1000-stdout.txt b/platforms/android/assets/www/node_modules/exit/test/fixtures/1000-stdout.txt new file mode 100644 index 0000000..d3649d0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/1000-stdout.txt @@ -0,0 +1,1000 @@ +stdout 0 +stdout 1 +stdout 2 +stdout 3 +stdout 4 +stdout 5 +stdout 6 +stdout 7 +stdout 8 +stdout 9 +stdout 10 +stdout 11 +stdout 12 +stdout 13 +stdout 14 +stdout 15 +stdout 16 +stdout 17 +stdout 18 +stdout 19 +stdout 20 +stdout 21 +stdout 22 +stdout 23 +stdout 24 +stdout 25 +stdout 26 +stdout 27 +stdout 28 +stdout 29 +stdout 30 +stdout 31 +stdout 32 +stdout 33 +stdout 34 +stdout 35 +stdout 36 +stdout 37 +stdout 38 +stdout 39 +stdout 40 +stdout 41 +stdout 42 +stdout 43 +stdout 44 +stdout 45 +stdout 46 +stdout 47 +stdout 48 +stdout 49 +stdout 50 +stdout 51 +stdout 52 +stdout 53 +stdout 54 +stdout 55 +stdout 56 +stdout 57 +stdout 58 +stdout 59 +stdout 60 +stdout 61 +stdout 62 +stdout 63 +stdout 64 +stdout 65 +stdout 66 +stdout 67 +stdout 68 +stdout 69 +stdout 70 +stdout 71 +stdout 72 +stdout 73 +stdout 74 +stdout 75 +stdout 76 +stdout 77 +stdout 78 +stdout 79 +stdout 80 +stdout 81 +stdout 82 +stdout 83 +stdout 84 +stdout 85 +stdout 86 +stdout 87 +stdout 88 +stdout 89 +stdout 90 +stdout 91 +stdout 92 +stdout 93 +stdout 94 +stdout 95 +stdout 96 +stdout 97 +stdout 98 +stdout 99 +stdout 100 +stdout 101 +stdout 102 +stdout 103 +stdout 104 +stdout 105 +stdout 106 +stdout 107 +stdout 108 +stdout 109 +stdout 110 +stdout 111 +stdout 112 +stdout 113 +stdout 114 +stdout 115 +stdout 116 +stdout 117 +stdout 118 +stdout 119 +stdout 120 +stdout 121 +stdout 122 +stdout 123 +stdout 124 +stdout 125 +stdout 126 +stdout 127 +stdout 128 +stdout 129 +stdout 130 +stdout 131 +stdout 132 +stdout 133 +stdout 134 +stdout 135 +stdout 136 +stdout 137 +stdout 138 +stdout 139 +stdout 140 +stdout 141 +stdout 142 +stdout 143 +stdout 144 +stdout 145 +stdout 146 +stdout 147 +stdout 148 +stdout 149 +stdout 150 +stdout 151 +stdout 152 +stdout 153 +stdout 154 +stdout 155 +stdout 156 +stdout 157 +stdout 158 +stdout 159 +stdout 160 +stdout 161 +stdout 162 +stdout 163 +stdout 164 +stdout 165 +stdout 166 +stdout 167 +stdout 168 +stdout 169 +stdout 170 +stdout 171 +stdout 172 +stdout 173 +stdout 174 +stdout 175 +stdout 176 +stdout 177 +stdout 178 +stdout 179 +stdout 180 +stdout 181 +stdout 182 +stdout 183 +stdout 184 +stdout 185 +stdout 186 +stdout 187 +stdout 188 +stdout 189 +stdout 190 +stdout 191 +stdout 192 +stdout 193 +stdout 194 +stdout 195 +stdout 196 +stdout 197 +stdout 198 +stdout 199 +stdout 200 +stdout 201 +stdout 202 +stdout 203 +stdout 204 +stdout 205 +stdout 206 +stdout 207 +stdout 208 +stdout 209 +stdout 210 +stdout 211 +stdout 212 +stdout 213 +stdout 214 +stdout 215 +stdout 216 +stdout 217 +stdout 218 +stdout 219 +stdout 220 +stdout 221 +stdout 222 +stdout 223 +stdout 224 +stdout 225 +stdout 226 +stdout 227 +stdout 228 +stdout 229 +stdout 230 +stdout 231 +stdout 232 +stdout 233 +stdout 234 +stdout 235 +stdout 236 +stdout 237 +stdout 238 +stdout 239 +stdout 240 +stdout 241 +stdout 242 +stdout 243 +stdout 244 +stdout 245 +stdout 246 +stdout 247 +stdout 248 +stdout 249 +stdout 250 +stdout 251 +stdout 252 +stdout 253 +stdout 254 +stdout 255 +stdout 256 +stdout 257 +stdout 258 +stdout 259 +stdout 260 +stdout 261 +stdout 262 +stdout 263 +stdout 264 +stdout 265 +stdout 266 +stdout 267 +stdout 268 +stdout 269 +stdout 270 +stdout 271 +stdout 272 +stdout 273 +stdout 274 +stdout 275 +stdout 276 +stdout 277 +stdout 278 +stdout 279 +stdout 280 +stdout 281 +stdout 282 +stdout 283 +stdout 284 +stdout 285 +stdout 286 +stdout 287 +stdout 288 +stdout 289 +stdout 290 +stdout 291 +stdout 292 +stdout 293 +stdout 294 +stdout 295 +stdout 296 +stdout 297 +stdout 298 +stdout 299 +stdout 300 +stdout 301 +stdout 302 +stdout 303 +stdout 304 +stdout 305 +stdout 306 +stdout 307 +stdout 308 +stdout 309 +stdout 310 +stdout 311 +stdout 312 +stdout 313 +stdout 314 +stdout 315 +stdout 316 +stdout 317 +stdout 318 +stdout 319 +stdout 320 +stdout 321 +stdout 322 +stdout 323 +stdout 324 +stdout 325 +stdout 326 +stdout 327 +stdout 328 +stdout 329 +stdout 330 +stdout 331 +stdout 332 +stdout 333 +stdout 334 +stdout 335 +stdout 336 +stdout 337 +stdout 338 +stdout 339 +stdout 340 +stdout 341 +stdout 342 +stdout 343 +stdout 344 +stdout 345 +stdout 346 +stdout 347 +stdout 348 +stdout 349 +stdout 350 +stdout 351 +stdout 352 +stdout 353 +stdout 354 +stdout 355 +stdout 356 +stdout 357 +stdout 358 +stdout 359 +stdout 360 +stdout 361 +stdout 362 +stdout 363 +stdout 364 +stdout 365 +stdout 366 +stdout 367 +stdout 368 +stdout 369 +stdout 370 +stdout 371 +stdout 372 +stdout 373 +stdout 374 +stdout 375 +stdout 376 +stdout 377 +stdout 378 +stdout 379 +stdout 380 +stdout 381 +stdout 382 +stdout 383 +stdout 384 +stdout 385 +stdout 386 +stdout 387 +stdout 388 +stdout 389 +stdout 390 +stdout 391 +stdout 392 +stdout 393 +stdout 394 +stdout 395 +stdout 396 +stdout 397 +stdout 398 +stdout 399 +stdout 400 +stdout 401 +stdout 402 +stdout 403 +stdout 404 +stdout 405 +stdout 406 +stdout 407 +stdout 408 +stdout 409 +stdout 410 +stdout 411 +stdout 412 +stdout 413 +stdout 414 +stdout 415 +stdout 416 +stdout 417 +stdout 418 +stdout 419 +stdout 420 +stdout 421 +stdout 422 +stdout 423 +stdout 424 +stdout 425 +stdout 426 +stdout 427 +stdout 428 +stdout 429 +stdout 430 +stdout 431 +stdout 432 +stdout 433 +stdout 434 +stdout 435 +stdout 436 +stdout 437 +stdout 438 +stdout 439 +stdout 440 +stdout 441 +stdout 442 +stdout 443 +stdout 444 +stdout 445 +stdout 446 +stdout 447 +stdout 448 +stdout 449 +stdout 450 +stdout 451 +stdout 452 +stdout 453 +stdout 454 +stdout 455 +stdout 456 +stdout 457 +stdout 458 +stdout 459 +stdout 460 +stdout 461 +stdout 462 +stdout 463 +stdout 464 +stdout 465 +stdout 466 +stdout 467 +stdout 468 +stdout 469 +stdout 470 +stdout 471 +stdout 472 +stdout 473 +stdout 474 +stdout 475 +stdout 476 +stdout 477 +stdout 478 +stdout 479 +stdout 480 +stdout 481 +stdout 482 +stdout 483 +stdout 484 +stdout 485 +stdout 486 +stdout 487 +stdout 488 +stdout 489 +stdout 490 +stdout 491 +stdout 492 +stdout 493 +stdout 494 +stdout 495 +stdout 496 +stdout 497 +stdout 498 +stdout 499 +stdout 500 +stdout 501 +stdout 502 +stdout 503 +stdout 504 +stdout 505 +stdout 506 +stdout 507 +stdout 508 +stdout 509 +stdout 510 +stdout 511 +stdout 512 +stdout 513 +stdout 514 +stdout 515 +stdout 516 +stdout 517 +stdout 518 +stdout 519 +stdout 520 +stdout 521 +stdout 522 +stdout 523 +stdout 524 +stdout 525 +stdout 526 +stdout 527 +stdout 528 +stdout 529 +stdout 530 +stdout 531 +stdout 532 +stdout 533 +stdout 534 +stdout 535 +stdout 536 +stdout 537 +stdout 538 +stdout 539 +stdout 540 +stdout 541 +stdout 542 +stdout 543 +stdout 544 +stdout 545 +stdout 546 +stdout 547 +stdout 548 +stdout 549 +stdout 550 +stdout 551 +stdout 552 +stdout 553 +stdout 554 +stdout 555 +stdout 556 +stdout 557 +stdout 558 +stdout 559 +stdout 560 +stdout 561 +stdout 562 +stdout 563 +stdout 564 +stdout 565 +stdout 566 +stdout 567 +stdout 568 +stdout 569 +stdout 570 +stdout 571 +stdout 572 +stdout 573 +stdout 574 +stdout 575 +stdout 576 +stdout 577 +stdout 578 +stdout 579 +stdout 580 +stdout 581 +stdout 582 +stdout 583 +stdout 584 +stdout 585 +stdout 586 +stdout 587 +stdout 588 +stdout 589 +stdout 590 +stdout 591 +stdout 592 +stdout 593 +stdout 594 +stdout 595 +stdout 596 +stdout 597 +stdout 598 +stdout 599 +stdout 600 +stdout 601 +stdout 602 +stdout 603 +stdout 604 +stdout 605 +stdout 606 +stdout 607 +stdout 608 +stdout 609 +stdout 610 +stdout 611 +stdout 612 +stdout 613 +stdout 614 +stdout 615 +stdout 616 +stdout 617 +stdout 618 +stdout 619 +stdout 620 +stdout 621 +stdout 622 +stdout 623 +stdout 624 +stdout 625 +stdout 626 +stdout 627 +stdout 628 +stdout 629 +stdout 630 +stdout 631 +stdout 632 +stdout 633 +stdout 634 +stdout 635 +stdout 636 +stdout 637 +stdout 638 +stdout 639 +stdout 640 +stdout 641 +stdout 642 +stdout 643 +stdout 644 +stdout 645 +stdout 646 +stdout 647 +stdout 648 +stdout 649 +stdout 650 +stdout 651 +stdout 652 +stdout 653 +stdout 654 +stdout 655 +stdout 656 +stdout 657 +stdout 658 +stdout 659 +stdout 660 +stdout 661 +stdout 662 +stdout 663 +stdout 664 +stdout 665 +stdout 666 +stdout 667 +stdout 668 +stdout 669 +stdout 670 +stdout 671 +stdout 672 +stdout 673 +stdout 674 +stdout 675 +stdout 676 +stdout 677 +stdout 678 +stdout 679 +stdout 680 +stdout 681 +stdout 682 +stdout 683 +stdout 684 +stdout 685 +stdout 686 +stdout 687 +stdout 688 +stdout 689 +stdout 690 +stdout 691 +stdout 692 +stdout 693 +stdout 694 +stdout 695 +stdout 696 +stdout 697 +stdout 698 +stdout 699 +stdout 700 +stdout 701 +stdout 702 +stdout 703 +stdout 704 +stdout 705 +stdout 706 +stdout 707 +stdout 708 +stdout 709 +stdout 710 +stdout 711 +stdout 712 +stdout 713 +stdout 714 +stdout 715 +stdout 716 +stdout 717 +stdout 718 +stdout 719 +stdout 720 +stdout 721 +stdout 722 +stdout 723 +stdout 724 +stdout 725 +stdout 726 +stdout 727 +stdout 728 +stdout 729 +stdout 730 +stdout 731 +stdout 732 +stdout 733 +stdout 734 +stdout 735 +stdout 736 +stdout 737 +stdout 738 +stdout 739 +stdout 740 +stdout 741 +stdout 742 +stdout 743 +stdout 744 +stdout 745 +stdout 746 +stdout 747 +stdout 748 +stdout 749 +stdout 750 +stdout 751 +stdout 752 +stdout 753 +stdout 754 +stdout 755 +stdout 756 +stdout 757 +stdout 758 +stdout 759 +stdout 760 +stdout 761 +stdout 762 +stdout 763 +stdout 764 +stdout 765 +stdout 766 +stdout 767 +stdout 768 +stdout 769 +stdout 770 +stdout 771 +stdout 772 +stdout 773 +stdout 774 +stdout 775 +stdout 776 +stdout 777 +stdout 778 +stdout 779 +stdout 780 +stdout 781 +stdout 782 +stdout 783 +stdout 784 +stdout 785 +stdout 786 +stdout 787 +stdout 788 +stdout 789 +stdout 790 +stdout 791 +stdout 792 +stdout 793 +stdout 794 +stdout 795 +stdout 796 +stdout 797 +stdout 798 +stdout 799 +stdout 800 +stdout 801 +stdout 802 +stdout 803 +stdout 804 +stdout 805 +stdout 806 +stdout 807 +stdout 808 +stdout 809 +stdout 810 +stdout 811 +stdout 812 +stdout 813 +stdout 814 +stdout 815 +stdout 816 +stdout 817 +stdout 818 +stdout 819 +stdout 820 +stdout 821 +stdout 822 +stdout 823 +stdout 824 +stdout 825 +stdout 826 +stdout 827 +stdout 828 +stdout 829 +stdout 830 +stdout 831 +stdout 832 +stdout 833 +stdout 834 +stdout 835 +stdout 836 +stdout 837 +stdout 838 +stdout 839 +stdout 840 +stdout 841 +stdout 842 +stdout 843 +stdout 844 +stdout 845 +stdout 846 +stdout 847 +stdout 848 +stdout 849 +stdout 850 +stdout 851 +stdout 852 +stdout 853 +stdout 854 +stdout 855 +stdout 856 +stdout 857 +stdout 858 +stdout 859 +stdout 860 +stdout 861 +stdout 862 +stdout 863 +stdout 864 +stdout 865 +stdout 866 +stdout 867 +stdout 868 +stdout 869 +stdout 870 +stdout 871 +stdout 872 +stdout 873 +stdout 874 +stdout 875 +stdout 876 +stdout 877 +stdout 878 +stdout 879 +stdout 880 +stdout 881 +stdout 882 +stdout 883 +stdout 884 +stdout 885 +stdout 886 +stdout 887 +stdout 888 +stdout 889 +stdout 890 +stdout 891 +stdout 892 +stdout 893 +stdout 894 +stdout 895 +stdout 896 +stdout 897 +stdout 898 +stdout 899 +stdout 900 +stdout 901 +stdout 902 +stdout 903 +stdout 904 +stdout 905 +stdout 906 +stdout 907 +stdout 908 +stdout 909 +stdout 910 +stdout 911 +stdout 912 +stdout 913 +stdout 914 +stdout 915 +stdout 916 +stdout 917 +stdout 918 +stdout 919 +stdout 920 +stdout 921 +stdout 922 +stdout 923 +stdout 924 +stdout 925 +stdout 926 +stdout 927 +stdout 928 +stdout 929 +stdout 930 +stdout 931 +stdout 932 +stdout 933 +stdout 934 +stdout 935 +stdout 936 +stdout 937 +stdout 938 +stdout 939 +stdout 940 +stdout 941 +stdout 942 +stdout 943 +stdout 944 +stdout 945 +stdout 946 +stdout 947 +stdout 948 +stdout 949 +stdout 950 +stdout 951 +stdout 952 +stdout 953 +stdout 954 +stdout 955 +stdout 956 +stdout 957 +stdout 958 +stdout 959 +stdout 960 +stdout 961 +stdout 962 +stdout 963 +stdout 964 +stdout 965 +stdout 966 +stdout 967 +stdout 968 +stdout 969 +stdout 970 +stdout 971 +stdout 972 +stdout 973 +stdout 974 +stdout 975 +stdout 976 +stdout 977 +stdout 978 +stdout 979 +stdout 980 +stdout 981 +stdout 982 +stdout 983 +stdout 984 +stdout 985 +stdout 986 +stdout 987 +stdout 988 +stdout 989 +stdout 990 +stdout 991 +stdout 992 +stdout 993 +stdout 994 +stdout 995 +stdout 996 +stdout 997 +stdout 998 +stdout 999 diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/create-files.sh b/platforms/android/assets/www/node_modules/exit/test/fixtures/create-files.sh new file mode 100755 index 0000000..6a526de --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/create-files.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +rm 10*.txt +for n in 10 100 1000; do + node log.js 0 $n stdout stderr &> $n-stdout-stderr.txt + node log.js 0 $n stdout &> $n-stdout.txt + node log.js 0 $n stderr &> $n-stderr.txt +done diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/log-broken.js b/platforms/android/assets/www/node_modules/exit/test/fixtures/log-broken.js new file mode 100644 index 0000000..74c8f12 --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/log-broken.js @@ -0,0 +1,23 @@ +var errorCode = process.argv[2]; +var max = process.argv[3]; +var modes = process.argv.slice(4); + +function stdout(message) { + if (modes.indexOf('stdout') === -1) { return; } + process.stdout.write('stdout ' + message + '\n'); +} + +function stderr(message) { + if (modes.indexOf('stderr') === -1) { return; } + process.stderr.write('stderr ' + message + '\n'); +} + +for (var i = 0; i < max; i++) { + stdout(i); + stderr(i); +} + +process.exit(errorCode); + +stdout('fail'); +stderr('fail'); diff --git a/platforms/android/assets/www/node_modules/exit/test/fixtures/log.js b/platforms/android/assets/www/node_modules/exit/test/fixtures/log.js new file mode 100644 index 0000000..8a9ed9a --- /dev/null +++ b/platforms/android/assets/www/node_modules/exit/test/fixtures/log.js @@ -0,0 +1,25 @@ +var exit = require('../../lib/exit'); + +var errorCode = process.argv[2]; +var max = process.argv[3]; +var modes = process.argv.slice(4); + +function stdout(message) { + if (modes.indexOf('stdout') === -1) { return; } + process.stdout.write('stdout ' + message + '\n'); +} + +function stderr(message) { + if (modes.indexOf('stderr') === -1) { return; } + process.stderr.write('stderr ' + message + '\n'); +} + +for (var i = 0; i < max; i++) { + stdout(i); + stderr(i); +} + +exit(errorCode); + +stdout('fail'); +stderr('fail'); diff --git a/platforms/android/assets/www/node_modules/glob/LICENSE b/platforms/android/assets/www/node_modules/glob/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/glob/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/glob/README.md b/platforms/android/assets/www/node_modules/glob/README.md new file mode 100644 index 0000000..9dd9384 --- /dev/null +++ b/platforms/android/assets/www/node_modules/glob/README.md @@ -0,0 +1,365 @@ +# Glob + +Match files using the patterns the shell uses, like stars and stuff. + +[![Build Status](https://travis-ci.org/isaacs/node-glob.svg?branch=master)](https://travis-ci.org/isaacs/node-glob/) [![Build Status](https://ci.appveyor.com/api/projects/status/kd7f3yftf7unxlsx?svg=true)](https://ci.appveyor.com/project/isaacs/node-glob) [![Coverage Status](https://coveralls.io/repos/isaacs/node-glob/badge.svg?branch=master&service=github)](https://coveralls.io/github/isaacs/node-glob?branch=master) + +This is a glob implementation in JavaScript. It uses the `minimatch` +library to do its matching. + +![](oh-my-glob.gif) + +## Usage + +Install with npm + +``` +npm i glob +``` + +```javascript +var glob = require("glob") + +// options is optional +glob("**/*.js", options, function (er, files) { + // files is an array of filenames. + // If the `nonull` option is set, and nothing + // was found, then files is ["**/*.js"] + // er is an error object or null. +}) +``` + +## Glob Primer + +"Globs" are the patterns you type when you do stuff like `ls *.js` on +the command line, or put `build/*` in a `.gitignore` file. + +Before parsing the path part patterns, braced sections are expanded +into a set. Braced sections start with `{` and end with `}`, with any +number of comma-delimited sections within. Braced sections may contain +slash characters, so `a{/b/c,bcd}` would expand into `a/b/c` and `abcd`. + +The following characters have special magic meaning when used in a +path portion: + +* `*` Matches 0 or more characters in a single path portion +* `?` Matches 1 character +* `[...]` Matches a range of characters, similar to a RegExp range. + If the first character of the range is `!` or `^` then it matches + any character not in the range. +* `!(pattern|pattern|pattern)` Matches anything that does not match + any of the patterns provided. +* `?(pattern|pattern|pattern)` Matches zero or one occurrence of the + patterns provided. +* `+(pattern|pattern|pattern)` Matches one or more occurrences of the + patterns provided. +* `*(a|b|c)` Matches zero or more occurrences of the patterns provided +* `@(pattern|pat*|pat?erN)` Matches exactly one of the patterns + provided +* `**` If a "globstar" is alone in a path portion, then it matches + zero or more directories and subdirectories searching for matches. + It does not crawl symlinked directories. + +### Dots + +If a file or directory path portion has a `.` as the first character, +then it will not match any glob pattern unless that pattern's +corresponding path part also has a `.` as its first character. + +For example, the pattern `a/.*/c` would match the file at `a/.b/c`. +However the pattern `a/*/c` would not, because `*` does not start with +a dot character. + +You can make glob treat dots as normal characters by setting +`dot:true` in the options. + +### Basename Matching + +If you set `matchBase:true` in the options, and the pattern has no +slashes in it, then it will seek for any file anywhere in the tree +with a matching basename. For example, `*.js` would match +`test/simple/basic.js`. + +### Empty Sets + +If no matching files are found, then an empty array is returned. This +differs from the shell, where the pattern itself is returned. For +example: + + $ echo a*s*d*f + a*s*d*f + +To get the bash-style behavior, set the `nonull:true` in the options. + +### See Also: + +* `man sh` +* `man bash` (Search for "Pattern Matching") +* `man 3 fnmatch` +* `man 5 gitignore` +* [minimatch documentation](https://github.com/isaacs/minimatch) + +## glob.hasMagic(pattern, [options]) + +Returns `true` if there are any special characters in the pattern, and +`false` otherwise. + +Note that the options affect the results. If `noext:true` is set in +the options object, then `+(a|b)` will not be considered a magic +pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}` +then that is considered magical, unless `nobrace:true` is set in the +options. + +## glob(pattern, [options], cb) + +* `pattern` `{String}` Pattern to be matched +* `options` `{Object}` +* `cb` `{Function}` + * `err` `{Error | null}` + * `matches` `{Array}` filenames found matching the pattern + +Perform an asynchronous glob search. + +## glob.sync(pattern, [options]) + +* `pattern` `{String}` Pattern to be matched +* `options` `{Object}` +* return: `{Array}` filenames found matching the pattern + +Perform a synchronous glob search. + +## Class: glob.Glob + +Create a Glob object by instantiating the `glob.Glob` class. + +```javascript +var Glob = require("glob").Glob +var mg = new Glob(pattern, options, cb) +``` + +It's an EventEmitter, and starts walking the filesystem to find matches +immediately. + +### new glob.Glob(pattern, [options], [cb]) + +* `pattern` `{String}` pattern to search for +* `options` `{Object}` +* `cb` `{Function}` Called when an error occurs, or matches are found + * `err` `{Error | null}` + * `matches` `{Array}` filenames found matching the pattern + +Note that if the `sync` flag is set in the options, then matches will +be immediately available on the `g.found` member. + +### Properties + +* `minimatch` The minimatch object that the glob uses. +* `options` The options object passed in. +* `aborted` Boolean which is set to true when calling `abort()`. There + is no way at this time to continue a glob search after aborting, but + you can re-use the statCache to avoid having to duplicate syscalls. +* `cache` Convenience object. Each field has the following possible + values: + * `false` - Path does not exist + * `true` - Path exists + * `'FILE'` - Path exists, and is not a directory + * `'DIR'` - Path exists, and is a directory + * `[file, entries, ...]` - Path exists, is a directory, and the + array value is the results of `fs.readdir` +* `statCache` Cache of `fs.stat` results, to prevent statting the same + path multiple times. +* `symlinks` A record of which paths are symbolic links, which is + relevant in resolving `**` patterns. +* `realpathCache` An optional object which is passed to `fs.realpath` + to minimize unnecessary syscalls. It is stored on the instantiated + Glob object, and may be re-used. + +### Events + +* `end` When the matching is finished, this is emitted with all the + matches found. If the `nonull` option is set, and no match was found, + then the `matches` list contains the original pattern. The matches + are sorted, unless the `nosort` flag is set. +* `match` Every time a match is found, this is emitted with the specific + thing that matched. It is not deduplicated or resolved to a realpath. +* `error` Emitted when an unexpected error is encountered, or whenever + any fs error occurs if `options.strict` is set. +* `abort` When `abort()` is called, this event is raised. + +### Methods + +* `pause` Temporarily stop the search +* `resume` Resume the search +* `abort` Stop the search forever + +### Options + +All the options that can be passed to Minimatch can also be passed to +Glob to change pattern matching behavior. Also, some have been added, +or have glob-specific ramifications. + +All options are false by default, unless otherwise noted. + +All options are added to the Glob object, as well. + +If you are running many `glob` operations, you can pass a Glob object +as the `options` argument to a subsequent operation to shortcut some +`stat` and `readdir` calls. At the very least, you may pass in shared +`symlinks`, `statCache`, `realpathCache`, and `cache` options, so that +parallel glob operations will be sped up by sharing information about +the filesystem. + +* `cwd` The current working directory in which to search. Defaults + to `process.cwd()`. +* `root` The place where patterns starting with `/` will be mounted + onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix + systems, and `C:\` or some such on Windows.) +* `dot` Include `.dot` files in normal matches and `globstar` matches. + Note that an explicit dot in a portion of the pattern will always + match dot files. +* `nomount` By default, a pattern starting with a forward-slash will be + "mounted" onto the root setting, so that a valid filesystem path is + returned. Set this flag to disable that behavior. +* `mark` Add a `/` character to directory matches. Note that this + requires additional stat calls. +* `nosort` Don't sort the results. +* `stat` Set to true to stat *all* results. This reduces performance + somewhat, and is completely unnecessary, unless `readdir` is presumed + to be an untrustworthy indicator of file existence. +* `silent` When an unusual error is encountered when attempting to + read a directory, a warning will be printed to stderr. Set the + `silent` option to true to suppress these warnings. +* `strict` When an unusual error is encountered when attempting to + read a directory, the process will just continue on in search of + other matches. Set the `strict` option to raise an error in these + cases. +* `cache` See `cache` property above. Pass in a previously generated + cache object to save some fs calls. +* `statCache` A cache of results of filesystem information, to prevent + unnecessary stat calls. While it should not normally be necessary + to set this, you may pass the statCache from one glob() call to the + options object of another, if you know that the filesystem will not + change between calls. (See "Race Conditions" below.) +* `symlinks` A cache of known symbolic links. You may pass in a + previously generated `symlinks` object to save `lstat` calls when + resolving `**` matches. +* `sync` DEPRECATED: use `glob.sync(pattern, opts)` instead. +* `nounique` In some cases, brace-expanded patterns can result in the + same file showing up multiple times in the result set. By default, + this implementation prevents duplicates in the result set. Set this + flag to disable that behavior. +* `nonull` Set to never return an empty set, instead returning a set + containing the pattern itself. This is the default in glob(3). +* `debug` Set to enable debug logging in minimatch and glob. +* `nobrace` Do not expand `{a,b}` and `{1..3}` brace sets. +* `noglobstar` Do not match `**` against multiple filenames. (Ie, + treat it as a normal `*` instead.) +* `noext` Do not match `+(a|b)` "extglob" patterns. +* `nocase` Perform a case-insensitive match. Note: on + case-insensitive filesystems, non-magic patterns will match by + default, since `stat` and `readdir` will not raise errors. +* `matchBase` Perform a basename-only match if the pattern does not + contain any slash characters. That is, `*.js` would be treated as + equivalent to `**/*.js`, matching all js files in all directories. +* `nodir` Do not match directories, only files. (Note: to match + *only* directories, simply put a `/` at the end of the pattern.) +* `ignore` Add a pattern or an array of glob patterns to exclude matches. + Note: `ignore` patterns are *always* in `dot:true` mode, regardless + of any other settings. +* `follow` Follow symlinked directories when expanding `**` patterns. + Note that this can result in a lot of duplicate references in the + presence of cyclic links. +* `realpath` Set to true to call `fs.realpath` on all of the results. + In the case of a symlink that cannot be resolved, the full absolute + path to the matched entry is returned (though it will usually be a + broken symlink) + +## Comparisons to other fnmatch/glob implementations + +While strict compliance with the existing standards is a worthwhile +goal, some discrepancies exist between node-glob and other +implementations, and are intentional. + +The double-star character `**` is supported by default, unless the +`noglobstar` flag is set. This is supported in the manner of bsdglob +and bash 4.3, where `**` only has special significance if it is the only +thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but +`a/**b` will not. + +Note that symlinked directories are not crawled as part of a `**`, +though their contents may match against subsequent portions of the +pattern. This prevents infinite loops and duplicates and the like. + +If an escaped pattern has no matches, and the `nonull` flag is set, +then glob returns the pattern as-provided, rather than +interpreting the character escapes. For example, +`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than +`"*a?"`. This is akin to setting the `nullglob` option in bash, except +that it does not resolve escaped pattern characters. + +If brace expansion is not disabled, then it is performed before any +other interpretation of the glob pattern. Thus, a pattern like +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are +checked for validity. Since those two are valid, matching proceeds. + +### Comments and Negation + +Previously, this module let you mark a pattern as a "comment" if it +started with a `#` character, or a "negated" pattern if it started +with a `!` character. + +These options were deprecated in version 5, and removed in version 6. + +To specify things that should not match, use the `ignore` option. + +## Windows + +**Please only use forward-slashes in glob expressions.** + +Though windows uses either `/` or `\` as its path separator, only `/` +characters are used by this glob implementation. You must use +forward-slashes **only** in glob expressions. Back-slashes will always +be interpreted as escape characters, not path separators. + +Results from absolute patterns such as `/foo/*` are mounted onto the +root setting using `path.join`. On windows, this will by default result +in `/foo/*` matching `C:\foo\bar.txt`. + +## Race Conditions + +Glob searching, by its very nature, is susceptible to race conditions, +since it relies on directory walking and such. + +As a result, it is possible that a file that exists when glob looks for +it may have been deleted or modified by the time it returns the result. + +As part of its internal implementation, this program caches all stat +and readdir calls that it makes, in order to cut down on system +overhead. However, this also makes it even more susceptible to races, +especially if the cache or statCache objects are reused between glob +calls. + +Users are thus advised not to use a glob result as a guarantee of +filesystem state in the face of rapid changes. For the vast majority +of operations, this is never a problem. + +## Contributing + +Any change to behavior (including bugfixes) must come with a test. + +Patches that fail tests or reduce performance will be rejected. + +``` +# to run tests +npm test + +# to re-generate test fixtures +npm run test-regen + +# to benchmark against bash/zsh +npm run bench + +# to profile javascript +npm run prof +``` diff --git a/platforms/android/assets/www/node_modules/glob/changelog.md b/platforms/android/assets/www/node_modules/glob/changelog.md new file mode 100644 index 0000000..4163677 --- /dev/null +++ b/platforms/android/assets/www/node_modules/glob/changelog.md @@ -0,0 +1,67 @@ +## 7.0 + +- Raise error if `options.cwd` is specified, and not a directory + +## 6.0 + +- Remove comment and negation pattern support +- Ignore patterns are always in `dot:true` mode + +## 5.0 + +- Deprecate comment and negation patterns +- Fix regression in `mark` and `nodir` options from making all cache + keys absolute path. +- Abort if `fs.readdir` returns an error that's unexpected +- Don't emit `match` events for ignored items +- Treat ENOTSUP like ENOTDIR in readdir + +## 4.5 + +- Add `options.follow` to always follow directory symlinks in globstar +- Add `options.realpath` to call `fs.realpath` on all results +- Always cache based on absolute path + +## 4.4 + +- Add `options.ignore` +- Fix handling of broken symlinks + +## 4.3 + +- Bump minimatch to 2.x +- Pass all tests on Windows + +## 4.2 + +- Add `glob.hasMagic` function +- Add `options.nodir` flag + +## 4.1 + +- Refactor sync and async implementations for performance +- Throw if callback provided to sync glob function +- Treat symbolic links in globstar results the same as Bash 4.3 + +## 4.0 + +- Use `^` for dependency versions (bumped major because this breaks + older npm versions) +- Ensure callbacks are only ever called once +- switch to ISC license + +## 3.x + +- Rewrite in JavaScript +- Add support for setting root, cwd, and windows support +- Cache many fs calls +- Add globstar support +- emit match events + +## 2.x + +- Use `glob.h` and `fnmatch.h` from NetBSD + +## 1.x + +- `glob.h` static binding. diff --git a/platforms/android/assets/www/node_modules/glob/common.js b/platforms/android/assets/www/node_modules/glob/common.js new file mode 100644 index 0000000..58dc41e --- /dev/null +++ b/platforms/android/assets/www/node_modules/glob/common.js @@ -0,0 +1,235 @@ +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } + + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = path.resolve(options.cwd) + self.changedCwd = self.cwd !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + self.cwdAbs = makeAbs(self, self.cwd) + self.nomount = !!options.nomount + + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + var notDir = !(/\/$/.test(e)) + var c = self.cache[e] || self.cache[makeAbs(self, e)] + if (notDir && c) + notDir = c !== 'DIR' && !Array.isArray(c) + return notDir + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + + if (process.platform === 'win32') + abs = abs.replace(/\\/g, '/') + + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} diff --git a/platforms/android/assets/www/node_modules/glob/glob.js b/platforms/android/assets/www/node_modules/glob/glob.js new file mode 100644 index 0000000..4dba04a --- /dev/null +++ b/platforms/android/assets/www/node_modules/glob/glob.js @@ -0,0 +1,782 @@ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin + } + + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin +} + +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + var n = this.minimatch.set.length + this._processing = 0 + this.matches = new Array(n) + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + var sync = true + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + sync = false + + function done () { + --self._processing + if (self._processing <= 0) { + if (sync) { + process.nextTick(function () { + self._finish() + }) + } else { + self._finish() + } + } + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + fs.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (this.matches[index][e]) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = this._makeAbs(e) + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + if (this.mark) + e = this._mark(e) + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er) + return cb() + + var isSym = lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + this.emit('error', error) + this.abort() + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && !stat.isDirectory()) + return cb(null, false, stat) + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return cb() + + return cb(null, c, stat) +} diff --git a/platforms/android/assets/www/node_modules/glob/package.json b/platforms/android/assets/www/node_modules/glob/package.json new file mode 100644 index 0000000..3638792 --- /dev/null +++ b/platforms/android/assets/www/node_modules/glob/package.json @@ -0,0 +1,102 @@ +{ + "_args": [ + [ + "glob@^7.0.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/rimraf" + ] + ], + "_from": "glob@>=7.0.0 <8.0.0", + "_id": "glob@7.0.3", + "_inCache": true, + "_installable": true, + "_location": "/glob", + "_nodeVersion": "5.6.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/glob-7.0.3.tgz_1457166529288_0.7840580905321985" + }, + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "3.7.3", + "_phantomChildren": {}, + "_requested": { + "name": "glob", + "raw": "glob@^7.0.0", + "rawSpec": "^7.0.0", + "scope": null, + "spec": ">=7.0.0 <8.0.0", + "type": "range" + }, + "_requiredBy": [ + "/rimraf" + ], + "_resolved": "https://registry.npmjs.org/glob/-/glob-7.0.3.tgz", + "_shasum": "0aa235931a4a96ac13d60ffac2fb877bd6ed4f58", + "_shrinkwrap": null, + "_spec": "glob@^7.0.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/rimraf", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/node-glob/issues" + }, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "description": "a little globber", + "devDependencies": { + "mkdirp": "0", + "rimraf": "^2.2.8", + "tap": "^5.7.0", + "tick": "0.0.6" + }, + "directories": {}, + "dist": { + "shasum": "0aa235931a4a96ac13d60ffac2fb877bd6ed4f58", + "tarball": "http://registry.npmjs.org/glob/-/glob-7.0.3.tgz" + }, + "engines": { + "node": "*" + }, + "files": [ + "glob.js", + "sync.js", + "common.js" + ], + "gitHead": "2fc2278ab857c7df117213a2fb431de090be6353", + "homepage": "https://github.com/isaacs/node-glob#readme", + "license": "ISC", + "main": "glob.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "glob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "scripts": { + "bench": "bash benchmark.sh", + "benchclean": "node benchclean.js", + "prepublish": "npm run benchclean", + "prof": "bash prof.sh && cat profile.txt", + "profclean": "rm -f v8.log profile.txt", + "test": "tap test/*.js --cov", + "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js" + }, + "version": "7.0.3" +} diff --git a/platforms/android/assets/www/node_modules/glob/sync.js b/platforms/android/assets/www/node_modules/glob/sync.js new file mode 100644 index 0000000..301577a --- /dev/null +++ b/platforms/android/assets/www/node_modules/glob/sync.js @@ -0,0 +1,467 @@ +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = fs.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this.matches[index][e] = true + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + var abs = this._makeAbs(e) + if (this.mark) + e = this._mark(e) + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[this._makeAbs(e)] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + // lstat failed, doesn't exist + return null + } + + var isSym = lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + throw error + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this.matches[index][prefix] = true +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + return false + } + + if (lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} diff --git a/platforms/android/assets/www/node_modules/inflight/.eslintrc b/platforms/android/assets/www/node_modules/inflight/.eslintrc new file mode 100644 index 0000000..b7a1550 --- /dev/null +++ b/platforms/android/assets/www/node_modules/inflight/.eslintrc @@ -0,0 +1,17 @@ +{ + "env" : { + "node" : true + }, + "rules" : { + "semi": [2, "never"], + "strict": 0, + "quotes": [1, "single", "avoid-escape"], + "no-use-before-define": 0, + "curly": 0, + "no-underscore-dangle": 0, + "no-lonely-if": 1, + "no-unused-vars": [2, {"vars" : "all", "args" : "after-used"}], + "no-mixed-requires": 0, + "space-infix-ops": 0 + } +} diff --git a/platforms/android/assets/www/node_modules/inflight/LICENSE b/platforms/android/assets/www/node_modules/inflight/LICENSE new file mode 100644 index 0000000..05eeeb8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/inflight/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/inflight/README.md b/platforms/android/assets/www/node_modules/inflight/README.md new file mode 100644 index 0000000..6dc8929 --- /dev/null +++ b/platforms/android/assets/www/node_modules/inflight/README.md @@ -0,0 +1,37 @@ +# inflight + +Add callbacks to requests in flight to avoid async duplication + +## USAGE + +```javascript +var inflight = require('inflight') + +// some request that does some stuff +function req(key, callback) { + // key is any random string. like a url or filename or whatever. + // + // will return either a falsey value, indicating that the + // request for this key is already in flight, or a new callback + // which when called will call all callbacks passed to inflightk + // with the same key + callback = inflight(key, callback) + + // If we got a falsey value back, then there's already a req going + if (!callback) return + + // this is where you'd fetch the url or whatever + // callback is also once()-ified, so it can safely be assigned + // to multiple events etc. First call wins. + setTimeout(function() { + callback(null, key) + }, 100) +} + +// only assigns a single setTimeout +// when it dings, all cbs get called +req('foo', cb1) +req('foo', cb2) +req('foo', cb3) +req('foo', cb4) +``` diff --git a/platforms/android/assets/www/node_modules/inflight/inflight.js b/platforms/android/assets/www/node_modules/inflight/inflight.js new file mode 100644 index 0000000..8bc96cb --- /dev/null +++ b/platforms/android/assets/www/node_modules/inflight/inflight.js @@ -0,0 +1,44 @@ +var wrappy = require('wrappy') +var reqs = Object.create(null) +var once = require('once') + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} diff --git a/platforms/android/assets/www/node_modules/inflight/package.json b/platforms/android/assets/www/node_modules/inflight/package.json new file mode 100644 index 0000000..90db3b2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/inflight/package.json @@ -0,0 +1,86 @@ +{ + "_args": [ + [ + "inflight@^1.0.4", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/glob" + ] + ], + "_from": "inflight@>=1.0.4 <2.0.0", + "_id": "inflight@1.0.4", + "_inCache": true, + "_installable": true, + "_location": "/inflight", + "_nodeVersion": "0.10.32", + "_npmUser": { + "email": "ogd@aoaioxxysz.net", + "name": "othiym23" + }, + "_npmVersion": "2.1.3", + "_phantomChildren": {}, + "_requested": { + "name": "inflight", + "raw": "inflight@^1.0.4", + "rawSpec": "^1.0.4", + "scope": null, + "spec": ">=1.0.4 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob" + ], + "_resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", + "_shasum": "6cbb4521ebd51ce0ec0a936bfd7657ef7e9b172a", + "_shrinkwrap": null, + "_spec": "inflight@^1.0.4", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/glob", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/inflight/issues" + }, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + }, + "description": "Add callbacks to requests in flight to avoid async duplication", + "devDependencies": { + "tap": "^0.4.10" + }, + "directories": {}, + "dist": { + "shasum": "6cbb4521ebd51ce0ec0a936bfd7657ef7e9b172a", + "tarball": "http://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz" + }, + "gitHead": "c7b5531d572a867064d4a1da9e013e8910b7d1ba", + "homepage": "https://github.com/isaacs/inflight", + "license": "ISC", + "main": "inflight.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + }, + { + "email": "ogd@aoaioxxysz.net", + "name": "othiym23" + }, + { + "email": "me@re-becca.org", + "name": "iarna" + } + ], + "name": "inflight", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/inflight.git" + }, + "scripts": { + "test": "tap test.js" + }, + "version": "1.0.4" +} diff --git a/platforms/android/assets/www/node_modules/inflight/test.js b/platforms/android/assets/www/node_modules/inflight/test.js new file mode 100644 index 0000000..2bb75b3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/inflight/test.js @@ -0,0 +1,97 @@ +var test = require('tap').test +var inf = require('./inflight.js') + + +function req (key, cb) { + cb = inf(key, cb) + if (cb) setTimeout(function () { + cb(key) + cb(key) + }) + return cb +} + +test('basic', function (t) { + var calleda = false + var a = req('key', function (k) { + t.notOk(calleda) + calleda = true + t.equal(k, 'key') + if (calledb) t.end() + }) + t.ok(a, 'first returned cb function') + + var calledb = false + var b = req('key', function (k) { + t.notOk(calledb) + calledb = true + t.equal(k, 'key') + if (calleda) t.end() + }) + + t.notOk(b, 'second should get falsey inflight response') +}) + +test('timing', function (t) { + var expect = [ + 'method one', + 'start one', + 'end one', + 'two', + 'tick', + 'three' + ] + var i = 0 + + function log (m) { + t.equal(m, expect[i], m + ' === ' + expect[i]) + ++i + if (i === expect.length) + t.end() + } + + function method (name, cb) { + log('method ' + name) + process.nextTick(cb) + } + + var one = inf('foo', function () { + log('start one') + var three = inf('foo', function () { + log('three') + }) + if (three) method('three', three) + log('end one') + }) + + method('one', one) + + var two = inf('foo', function () { + log('two') + }) + if (two) method('one', two) + + process.nextTick(log.bind(null, 'tick')) +}) + +test('parameters', function (t) { + t.plan(8) + + var a = inf('key', function (first, second, third) { + t.equal(first, 1) + t.equal(second, 2) + t.equal(third, 3) + }) + t.ok(a, 'first returned cb function') + + var b = inf('key', function (first, second, third) { + t.equal(first, 1) + t.equal(second, 2) + t.equal(third, 3) + }) + t.notOk(b, 'second should get falsey inflight response') + + setTimeout(function () { + a(1, 2, 3) + }) +}) diff --git a/platforms/android/assets/www/node_modules/inherits/LICENSE b/platforms/android/assets/www/node_modules/inherits/LICENSE new file mode 100644 index 0000000..dea3013 --- /dev/null +++ b/platforms/android/assets/www/node_modules/inherits/LICENSE @@ -0,0 +1,16 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/platforms/android/assets/www/node_modules/inherits/README.md b/platforms/android/assets/www/node_modules/inherits/README.md new file mode 100644 index 0000000..b1c5665 --- /dev/null +++ b/platforms/android/assets/www/node_modules/inherits/README.md @@ -0,0 +1,42 @@ +Browser-friendly inheritance fully compatible with standard node.js +[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). + +This package exports standard `inherits` from node.js `util` module in +node environment, but also provides alternative browser-friendly +implementation through [browser +field](https://gist.github.com/shtylman/4339901). Alternative +implementation is a literal copy of standard one located in standalone +module to avoid requiring of `util`. It also has a shim for old +browsers with no `Object.create` support. + +While keeping you sure you are using standard `inherits` +implementation in node.js environment, it allows bundlers such as +[browserify](https://github.com/substack/node-browserify) to not +include full `util` package to your client code if all you need is +just `inherits` function. It worth, because browser shim for `util` +package is large and `inherits` is often the single function you need +from it. + +It's recommended to use this package instead of +`require('util').inherits` for any code that has chances to be used +not only in node.js but in browser too. + +## usage + +```js +var inherits = require('inherits'); +// then use exactly as the standard one +``` + +## note on version ~1.0 + +Version ~1.0 had completely different motivation and is not compatible +neither with 2.0 nor with standard node.js `inherits`. + +If you are using version ~1.0 and planning to switch to ~2.0, be +careful: + +* new version uses `super_` instead of `super` for referencing + superclass +* new version overwrites current prototype while old one preserves any + existing fields on it diff --git a/platforms/android/assets/www/node_modules/inherits/inherits.js b/platforms/android/assets/www/node_modules/inherits/inherits.js new file mode 100644 index 0000000..29f5e24 --- /dev/null +++ b/platforms/android/assets/www/node_modules/inherits/inherits.js @@ -0,0 +1 @@ +module.exports = require('util').inherits diff --git a/platforms/android/assets/www/node_modules/inherits/inherits_browser.js b/platforms/android/assets/www/node_modules/inherits/inherits_browser.js new file mode 100644 index 0000000..c1e78a7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/inherits/inherits_browser.js @@ -0,0 +1,23 @@ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} diff --git a/platforms/android/assets/www/node_modules/inherits/package.json b/platforms/android/assets/www/node_modules/inherits/package.json new file mode 100644 index 0000000..722bcd1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/inherits/package.json @@ -0,0 +1,77 @@ +{ + "_args": [ + [ + "inherits@2", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/glob" + ] + ], + "_from": "inherits@>=2.0.0 <3.0.0", + "_id": "inherits@2.0.1", + "_inCache": true, + "_installable": true, + "_location": "/inherits", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "1.3.8", + "_phantomChildren": {}, + "_requested": { + "name": "inherits", + "raw": "inherits@2", + "rawSpec": "2", + "scope": null, + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob" + ], + "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", + "_shrinkwrap": null, + "_spec": "inherits@2", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/glob", + "browser": "./inherits_browser.js", + "bugs": { + "url": "https://github.com/isaacs/inherits/issues" + }, + "dependencies": {}, + "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", + "tarball": "http://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "homepage": "https://github.com/isaacs/inherits#readme", + "keywords": [ + "inheritance", + "class", + "klass", + "oop", + "object-oriented", + "inherits", + "browser", + "browserify" + ], + "license": "ISC", + "main": "./inherits.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "inherits", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/inherits.git" + }, + "scripts": { + "test": "node test" + }, + "version": "2.0.1" +} diff --git a/platforms/android/assets/www/node_modules/inherits/test.js b/platforms/android/assets/www/node_modules/inherits/test.js new file mode 100644 index 0000000..fc53012 --- /dev/null +++ b/platforms/android/assets/www/node_modules/inherits/test.js @@ -0,0 +1,25 @@ +var inherits = require('./inherits.js') +var assert = require('assert') + +function test(c) { + assert(c.constructor === Child) + assert(c.constructor.super_ === Parent) + assert(Object.getPrototypeOf(c) === Child.prototype) + assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype) + assert(c instanceof Child) + assert(c instanceof Parent) +} + +function Child() { + Parent.call(this) + test(this) +} + +function Parent() {} + +inherits(Child, Parent) + +var c = new Child +test(c) + +console.log('ok') diff --git a/platforms/android/assets/www/node_modules/jasmine-core/.npmignore b/platforms/android/assets/www/node_modules/jasmine-core/.npmignore new file mode 100644 index 0000000..82d86f3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/.npmignore @@ -0,0 +1,28 @@ +dist/ +grunt/ +node_modules +pkg/ +release_notes/ +spec/ +src/ +Gemfile +Gemfile.lock +Rakefile +jasmine-core.gemspec +.bundle/ +.gitignore +.gitmodules +.idea +.jshintrc +.rspec +.sass-cache/ +.travis.yml +*.sh +*.py +Gruntfile.js +lib/jasmine-core.rb +lib/jasmine-core/boot/ +lib/jasmine-core/spec +lib/jasmine-core/version.rb +lib/jasmine-core/*.py +sauce_connect.log diff --git a/platforms/android/assets/www/node_modules/jasmine-core/CONTRIBUTING.md b/platforms/android/assets/www/node_modules/jasmine-core/CONTRIBUTING.md new file mode 100644 index 0000000..8d990ff --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/CONTRIBUTING.md @@ -0,0 +1,130 @@ +# Developing for Jasmine Core + +We welcome your contributions! Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists before starting work. What you're looking for may already have been done. If it hasn't, the community can help make your contribution better. If you want to contribute but don't know what to work on, [issues tagged ready for work](https://github.com/jasmine/jasmine/labels/ready%20for%20work) should have enough detail to get started. + +## Links + +- [Jasmine Google Group](http://groups.google.com/group/jasmine-js) +- [Jasmine-dev Google Group](http://groups.google.com/group/jasmine-js-dev) +- [Jasmine on PivotalTracker](https://www.pivotaltracker.com/n/projects/10606) + +## General Workflow + +Please submit pull requests via feature branches using the semi-standard workflow of: + +```bash +git clone git@github.com:yourUserName/jasmine.git # Clone your fork +cd jasmine # Change directory +git remote add upstream https://github.com/jasmine/jasmine.git # Assign original repository to a remote named 'upstream' +git fetch upstream # Pull in changes not present in your local repository +git checkout -b my-new-feature # Create your feature branch +git commit -am 'Add some feature' # Commit your changes +git push origin my-new-feature # Push to the branch +``` + +Once you've pushed a feature branch to your forked repo, you're ready to open a pull request. We favor pull requests with very small, single commits with a single purpose. + +## Background + +### Directory Structure + +* `/src` contains all of the source files + * `/src/console` - Node.js-specific files + * `/src/core` - generic source files + * `/src/html` - browser-specific files +* `/spec` contains all of the tests + * mirrors the source directory + * there are some additional files +* `/dist` contains the standalone distributions as zip files +* `/lib` contains the generated files for distribution as the Jasmine Rubygem and the Python package + +### Self-testing + +Note that Jasmine tests itself. The files in `lib` are loaded first, defining the reference `jasmine`. Then the files in `src` are loaded, defining the reference `j$`. So there are two copies of the code loaded under test. + +The tests should always use `j$` to refer to the objects and functions that are being tested. But the tests can use functions on `jasmine` as needed. _Be careful how you structure any new test code_. Copy the patterns you see in the existing code - this ensures that the code you're testing is not leaking into the `jasmine` reference and vice-versa. + +### `boot.js` + +__This is new for Jasmine 2.0.__ + +This file does all of the setup necessary for Jasmine to work. It loads all of the code, creates an `Env`, attaches the global functions, and builds the reporter. It also sets up the execution of the `Env` - for browsers this is in `window.onload`. While the default in `lib` is appropriate for browsers, projects may wish to customize this file. + +For example, for Jasmine development there is a different `dev_boot.js` for Jasmine development that does more work. + +### Compatibility + +* Browser Minimum + * IE8 + * Firefox 3.x + * Chrome ?? + * Safari 5 + +## Development + +All source code belongs in `src/`. The `core/` directory contains the bulk of Jasmine's functionality. This code should remain browser- and environment-agnostic. If your feature or fix cannot be, as mentioned above, please degrade gracefully. Any code that should only be in a non-browser environment should live in `src/console/`. Any code that depends on a browser (specifically, it expects `window` to be the global or `document` is present) should live in `src/html/`. + +### Install Dependencies + +Jasmine Core relies on Ruby and Node.js. + +To install the Ruby dependencies, you will need Ruby, Rubygems, and Bundler available. Then: + + $ bundle + +...will install all of the Ruby dependencies. If the ffi gem fails to build its native extensions, you may need to manually install some system dependencies. On Ubuntu: + + $ apt-get install gcc ruby ruby-dev libxml2 libxml2-dev libxslt1-dev + +...should get you to the point that `bundle` can install everything. + +To install the Node dependencies, you will need Node.js, Npm, and [Grunt](http://gruntjs.com/), the [grunt-cli](https://github.com/gruntjs/grunt-cli) and ensure that `grunt` is on your path. + + $ npm install --local + +...will install all of the node modules locally. Now run + + $ grunt + +...if you see that JSHint runs, your system is ready. + +### How to write new Jasmine code + +Or, How to make a successful pull request + +* _Do not change the public interface_. Lots of projects depend on Jasmine and if you aren't careful you'll break them +* _Be environment agnostic_ - server-side developers are just as important as browser developers +* _Be browser agnostic_ - if you must rely on browser-specific functionality, please write it in a way that degrades gracefully +* _Write specs_ - Jasmine's a testing framework; don't add functionality without test-driving it +* _Write code in the style of the rest of the repo_ - Jasmine should look like a cohesive whole +* _Ensure the *entire* test suite is green_ in all the big browsers, Node, and JSHint - your contribution shouldn't break Jasmine for other users + +Follow these tips and your pull request, patch, or suggestion is much more likely to be integrated. + +### Running Specs + +Jasmine uses the [Jasmine Ruby gem](http://github.com/jasmine/jasmine-gem) to test itself in browser. + + $ bundle exec rake jasmine + +...and then visit `http://localhost:8888` to run specs. + +Jasmine uses the [Jasmine NPM package](http://github.com/jasmine/jasmine-npm) to test itself in a Node.js/npm environment. + + $ grunt execSpecsInNode + +...and then the results will print to the console. All specs run except those that expect a browser (the specs in `spec/html` are ignored). + +## Before Committing or Submitting a Pull Request + +1. Ensure all specs are green in browser *and* node +1. Ensure JSHint is green with `grunt jshint` +1. Build `jasmine.js` with `grunt buildDistribution` and run all specs again - this ensures that your changes self-test well + +## Submitting a Pull Request +1. Revert your changes to `jasmine.js` and `jasmine-html.js` + * We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches +1. When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master + +Note that we use Travis for Continuous Integration. We only accept green pull requests. + diff --git a/platforms/android/assets/www/node_modules/jasmine-core/MANIFEST.in b/platforms/android/assets/www/node_modules/jasmine-core/MANIFEST.in new file mode 100644 index 0000000..4d58eed --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/MANIFEST.in @@ -0,0 +1,5 @@ +recursive-include . *.py +include lib/jasmine-core/*.js +include lib/jasmine-core/*.css +include images/*.png +include package.json diff --git a/platforms/android/assets/www/node_modules/jasmine-core/MIT.LICENSE b/platforms/android/assets/www/node_modules/jasmine-core/MIT.LICENSE new file mode 100644 index 0000000..aff8ed4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/MIT.LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008-2014 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/jasmine-core/README.md b/platforms/android/assets/www/node_modules/jasmine-core/README.md new file mode 100644 index 0000000..74d90d4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/README.md @@ -0,0 +1,76 @@ +[](http://jasmine.github.io) + +[![Build Status](https://travis-ci.org/jasmine/jasmine.svg?branch=master)](https://travis-ci.org/jasmine/jasmine) +[![Code Climate](https://codeclimate.com/github/pivotal/jasmine.svg)](https://codeclimate.com/github/pivotal/jasmine) + +======= + +**A JavaScript Testing Framework** + +Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, [Node.js](http://nodejs.org) projects, or anywhere that JavaScript can run. + +Documentation & guides live here: [http://jasmine.github.io](http://jasmine.github.io/) +For a quick start guide of Jasmine 2.0, see the beginning of [http://jasmine.github.io/2.0/introduction.html](http://jasmine.github.io/2.0/introduction.html) + +Upgrading from Jasmine 1.x? Check out the [2.0 release notes](https://github.com/jasmine/jasmine/blob/v2.0.0/release_notes/20.md) for a list of what's new (including breaking interface changes). You can also read the [upgrade guide](http://jasmine.github.io/2.0/upgrading.html). + +## Contributing + +Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/master/CONTRIBUTING.md) + +## Installation + +For the Jasmine NPM module:
+[https://github.com/jasmine/jasmine-npm](https://github.com/jasmine/jasmine-npm) + +For the Jasmine Ruby Gem:
+[https://github.com/jasmine/jasmine-gem](https://github.com/jasmine/jasmine-gem) + +For the Jasmine Python Egg:
+[https://github.com/jasmine/jasmine-py](https://github.com/jasmine/jasmine-py) + +To install Jasmine standalone on your local box: + +* Download the standalone distribution for your desired release from the [releases page](https://github.com/jasmine/jasmine/releases) +* Create a Jasmine directory in your project - `mkdir my-project/jasmine` +* Move the dist to your project directory - `mv jasmine/dist/jasmine-standalone-2.0.0.zip my-project/jasmine` +* Change directory - `cd my-project/jasmine` +* Unzip the dist - `unzip jasmine-standalone-2.0.0.zip` + +Add the following to your HTML file: + +```html + + + + + + +``` + +## Supported environments + +Jasmine tests itself across many browsers (Safari, Chrome, Firefox, PhantomJS, and new Internet Explorer) as well as node. To see the exact version tests are run against look at our [.travis.yml](https://github.com/jasmine/jasmine/blob/master/.travis.yml) + + +## Support + +* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js) +* Send an email to the list: [jasmine-js@googlegroups.com](mailto:jasmine-js@googlegroups.com) +* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606) +* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD) + +## Maintainers + +* [Davis W. Frank](mailto:dwfrank@pivotal.io), Pivotal Labs +* [Rajan Agaskar](mailto:rajan@pivotal.io), Pivotal Labs +* [Gregg Van Hove](mailto:gvanhove@pivotal.io), Pivotal Labs +* [Greg Cobb](mailto:gcobb@pivotal.io), Pivotal Labs +* [Chris Amavisca](mailto:camavisca@pivotal.io), Pivotal Labs + +### Maintainers Emeritus + +* [Christian Williams](mailto:antixian666@gmail.com), Cloud Foundry +* Sheel Choksi + +Copyright (c) 2008-2015 Pivotal Labs. This software is licensed under the MIT License. diff --git a/platforms/android/assets/www/node_modules/jasmine-core/RELEASE.md b/platforms/android/assets/www/node_modules/jasmine-core/RELEASE.md new file mode 100644 index 0000000..e5273b0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/RELEASE.md @@ -0,0 +1,73 @@ +# How to work on a Jasmine Release + +## Development +___Jasmine Core Maintainers Only___ + +Follow the instructions in `CONTRIBUTING.md` during development. + +### Git Rules + +Please work on feature branches. + +Please attempt to keep commits to `master` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits or small work), please squash them when merging back to `master`. + +### Version + +We attempt to stick to [Semantic Versioning](http://semver.org/). Most of the time, development should be against a new minor version - fixing bugs and adding new features that are backwards compatible. + +The current version lives in the file `/package.json`. This version will be the version number that is currently released. When releasing a new version, update `package.json` with the new version and `grunt build:copyVersionToGem` to update the gem version number. + +This version is used by both `jasmine.js` and the `jasmine-core` Ruby gem. + +Note that Jasmine should only use the "patch" version number in the following cases: + +* Changes related to packaging for a specific platform (npm, gem, or pip). +* Fixes for regressions. + +When jasmine-core revs its major or minor version, the binding libraries should also rev to that version. + +## Release + +When ready to release - specs are all green and the stories are done: + +1. Update the release notes in `release_notes` - use the Anchorman gem to generate the markdown file and edit accordingly +1. Update the version in `package.json` to a release candidate +1. Update any links or top-level landing page for the Github Pages + +### Build standalone distribution + +1. Build the standalone distribution with `grunt buildStandaloneDist` + +### Release the Python egg + +1. `python setup.py register sdist upload` You will need pypi credentials to upload the egg. + +### Release the Ruby gem + +1. Copy version to the Ruby gem with `grunt build:copyVersionToGem` +1. __NOTE__: You will likely need to point to a local jasmine gem in order to run tests locally. _Do not_ push this version of the Gemfile. +1. __NOTE__: You will likely need to push a new jasmine gem with a dependent version right after this release. +1. Push these changes to GitHub and verify that this SHA is green +1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org. In order to release you will have to ensure you have rubygems creds locally. + +### Release the NPM + +1. `npm adduser` to save your credentials locally +1. `npm publish .` to publish what's in `package.json` + +### Release the docs + +Probably only need to do this when releasing a minor version, and not a patch version. + +1. `cp -R edge ${version}` to copy the current edge docs to the new version +1. Add a link to the new version in `index.html` + +### Finally + +1. Visit the [Releases page for Jasmine](https://github.com/jasmine/jasmine/releases), find the tag just pushed. + 1. Paste in a link to the correct release notes for this release. The link should reference the blob and tag correctly, and the markdown file for the notes. + 1. If it is a pre-release, mark it as such. + 1. Attach the standalone zipfile + + +There should be a post to Pivotal Labs blog and a tweet to that link. diff --git a/platforms/android/assets/www/node_modules/jasmine-core/bower.json b/platforms/android/assets/www/node_modules/jasmine-core/bower.json new file mode 100644 index 0000000..c69673f --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/bower.json @@ -0,0 +1,40 @@ +{ + "name": "jasmine-core", + "homepage": "http://jasmine.github.io", + "authors": [ + "slackersoft " + ], + "description": "Official packaging of Jasmine's core files", + "keywords": [ + "test", + "jasmine", + "tdd", + "bdd" + ], + "license": "MIT", + "moduleType": "globals", + "main": "lib/jasmine-core/jasmine.js", + "ignore": [ + "**/.*", + "dist", + "grunt", + "node_modules", + "pkg", + "release_notes", + "spec", + "src", + "Gemfile", + "Gemfile.lock", + "Rakefile", + "jasmine-core.gemspec", + "*.sh", + "*.py", + "Gruntfile.js", + "lib/jasmine-core.rb", + "lib/jasmine-core/boot/", + "lib/jasmine-core/spec", + "lib/jasmine-core/version.rb", + "lib/jasmine-core/*.py", + "sauce_connect.log" + ] +} diff --git a/platforms/android/assets/www/node_modules/jasmine-core/images/jasmine-horizontal.png b/platforms/android/assets/www/node_modules/jasmine-core/images/jasmine-horizontal.png new file mode 100644 index 0000000..ca287ff Binary files /dev/null and b/platforms/android/assets/www/node_modules/jasmine-core/images/jasmine-horizontal.png differ diff --git a/platforms/android/assets/www/node_modules/jasmine-core/images/jasmine-horizontal.svg b/platforms/android/assets/www/node_modules/jasmine-core/images/jasmine-horizontal.svg new file mode 100644 index 0000000..ba8990e --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/images/jasmine-horizontal.svg @@ -0,0 +1,102 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/jasmine-core/images/jasmine_favicon.png b/platforms/android/assets/www/node_modules/jasmine-core/images/jasmine_favicon.png new file mode 100644 index 0000000..3b84583 Binary files /dev/null and b/platforms/android/assets/www/node_modules/jasmine-core/images/jasmine_favicon.png differ diff --git a/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/PKG-INFO b/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/PKG-INFO new file mode 100644 index 0000000..fe5901a --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/PKG-INFO @@ -0,0 +1,30 @@ +Metadata-Version: 1.1 +Name: jasmine-core +Version: 2.2.1 +Summary: Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, Node.js (http://nodejs.org) projects, or anywhere that JavaScript can run. +Home-page: http://jasmine.github.io +Author: Pivotal Labs +Author-email: jasmine-js@googlegroups.com +License: MIT +Description: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Environment :: Web Environment +Classifier: Framework :: Django +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Build Tools +Classifier: Topic :: Software Development :: Quality Assurance +Classifier: Topic :: Software Development :: Testing diff --git a/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/SOURCES.txt b/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/SOURCES.txt new file mode 100644 index 0000000..cf3dcc8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/SOURCES.txt @@ -0,0 +1,18 @@ +MANIFEST.in +package.json +images/__init__.py +images/jasmine-horizontal.png +images/jasmine_favicon.png +jasmine_core.egg-info/PKG-INFO +jasmine_core.egg-info/SOURCES.txt +jasmine_core.egg-info/dependency_links.txt +jasmine_core.egg-info/requires.txt +jasmine_core.egg-info/top_level.txt +lib/jasmine-core/__init__.py +lib/jasmine-core/boot.js +lib/jasmine-core/core.py +lib/jasmine-core/jasmine-html.js +lib/jasmine-core/jasmine.css +lib/jasmine-core/jasmine.js +lib/jasmine-core/json2.js +lib/jasmine-core/node_boot.js \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/dependency_links.txt b/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/requires.txt b/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/requires.txt new file mode 100644 index 0000000..119bcbe --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/requires.txt @@ -0,0 +1,2 @@ +glob2>=0.4.1 +ordereddict==1.1 diff --git a/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/top_level.txt b/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/top_level.txt new file mode 100644 index 0000000..fb7d8b2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/jasmine_core.egg-info/top_level.txt @@ -0,0 +1 @@ +jasmine_core diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/console/console.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/console/console.js new file mode 100644 index 0000000..e154806 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/console/console.js @@ -0,0 +1,190 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +function getJasmineRequireObj() { + if (typeof module !== 'undefined' && module.exports) { + return exports; + } else { + window.jasmineRequire = window.jasmineRequire || {}; + return window.jasmineRequire; + } +} + +getJasmineRequireObj().console = function(jRequire, j$) { + j$.ConsoleReporter = jRequire.ConsoleReporter(); +}; + +getJasmineRequireObj().ConsoleReporter = function() { + + var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } + }; + + function ConsoleReporter(options) { + var print = options.print, + showColors = options.showColors || false, + onComplete = options.onComplete || function() {}, + timer = options.timer || noopTimer, + specCount, + failureCount, + failedSpecs = [], + pendingCount, + ansi = { + green: '\x1B[32m', + red: '\x1B[31m', + yellow: '\x1B[33m', + none: '\x1B[0m' + }, + failedSuites = []; + + print('ConsoleReporter is deprecated and will be removed in a future version.'); + + this.jasmineStarted = function() { + specCount = 0; + failureCount = 0; + pendingCount = 0; + print('Started'); + printNewline(); + timer.start(); + }; + + this.jasmineDone = function() { + printNewline(); + for (var i = 0; i < failedSpecs.length; i++) { + specFailureDetails(failedSpecs[i]); + } + + if(specCount > 0) { + printNewline(); + + var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' + + failureCount + ' ' + plural('failure', failureCount); + + if (pendingCount) { + specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount); + } + + print(specCounts); + } else { + print('No specs found'); + } + + printNewline(); + var seconds = timer.elapsed() / 1000; + print('Finished in ' + seconds + ' ' + plural('second', seconds)); + printNewline(); + + for(i = 0; i < failedSuites.length; i++) { + suiteFailureDetails(failedSuites[i]); + } + + onComplete(failureCount === 0); + }; + + this.specDone = function(result) { + specCount++; + + if (result.status == 'pending') { + pendingCount++; + print(colored('yellow', '*')); + return; + } + + if (result.status == 'passed') { + print(colored('green', '.')); + return; + } + + if (result.status == 'failed') { + failureCount++; + failedSpecs.push(result); + print(colored('red', 'F')); + } + }; + + this.suiteDone = function(result) { + if (result.failedExpectations && result.failedExpectations.length > 0) { + failureCount++; + failedSuites.push(result); + } + }; + + return this; + + function printNewline() { + print('\n'); + } + + function colored(color, str) { + return showColors ? (ansi[color] + str + ansi.none) : str; + } + + function plural(str, count) { + return count == 1 ? str : str + 's'; + } + + function repeat(thing, times) { + var arr = []; + for (var i = 0; i < times; i++) { + arr.push(thing); + } + return arr; + } + + function indent(str, spaces) { + var lines = (str || '').split('\n'); + var newArr = []; + for (var i = 0; i < lines.length; i++) { + newArr.push(repeat(' ', spaces).join('') + lines[i]); + } + return newArr.join('\n'); + } + + function specFailureDetails(result) { + printNewline(); + print(result.fullName); + + for (var i = 0; i < result.failedExpectations.length; i++) { + var failedExpectation = result.failedExpectations[i]; + printNewline(); + print(indent(failedExpectation.message, 2)); + print(indent(failedExpectation.stack, 2)); + } + + printNewline(); + } + + function suiteFailureDetails(result) { + for (var i = 0; i < result.failedExpectations.length; i++) { + printNewline(); + print(colored('red', 'An error was thrown in an afterAll')); + printNewline(); + print(colored('red', 'AfterAll ' + result.failedExpectations[i].message)); + + } + printNewline(); + } + } + + return ConsoleReporter; +}; diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core.js new file mode 100644 index 0000000..fe0ecd8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core.js @@ -0,0 +1,37 @@ +module.exports = require("./jasmine-core/jasmine.js"); +module.exports.boot = require('./jasmine-core/node_boot.js'); + +var path = require('path'), + fs = require('fs'); + +var rootPath = path.join(__dirname, "jasmine-core"), + bootFiles = ['boot.js'], + nodeBootFiles = ['node_boot.js'], + cssFiles = [], + jsFiles = [], + jsFilesToSkip = ['jasmine.js'].concat(bootFiles, nodeBootFiles); + +fs.readdirSync(rootPath).forEach(function(file) { + if(fs.statSync(path.join(rootPath, file)).isFile()) { + switch(path.extname(file)) { + case '.css': + cssFiles.push(file); + break; + case '.js': + if (jsFilesToSkip.indexOf(file) < 0) { + jsFiles.push(file); + } + break; + } + } +}); + +module.exports.files = { + path: rootPath, + bootDir: rootPath, + bootFiles: bootFiles, + nodeBootFiles: nodeBootFiles, + cssFiles: cssFiles, + jsFiles: ['jasmine.js'].concat(jsFiles), + imagesDir: path.join(__dirname, '../images') +}; diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/boot.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/boot.js new file mode 100644 index 0000000..a1002de --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/boot.js @@ -0,0 +1,152 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +/** + Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project. + + If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms. + + The location of `boot.js` can be specified and/or overridden in `jasmine.yml`. + + [jasmine-gem]: http://github.com/pivotal/jasmine-gem + */ + +(function() { + + /** + * ## Require & Instantiate + * + * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference. + */ + window.jasmine = jasmineRequire.core(jasmineRequire); + + /** + * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference. + */ + jasmineRequire.html(jasmine); + + /** + * Create the Jasmine environment. This is used to run all specs in a project. + */ + var env = jasmine.getEnv(); + + /** + * ## The Global Interface + * + * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged. + */ + var jasmineInterface = jasmineRequire.interface(jasmine, env); + + /** + * Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`. + */ + extend(window, jasmineInterface); + + /** + * ## Runner Parameters + * + * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface. + */ + + var queryString = new jasmine.QueryString({ + getWindowLocation: function() { return window.location; } + }); + + var catchingExceptions = queryString.getParam("catch"); + env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions); + + var throwingExpectationFailures = queryString.getParam("throwFailures"); + env.throwOnExpectationFailure(throwingExpectationFailures); + + var random = queryString.getParam("random"); + env.randomizeTests(random); + + var seed = queryString.getParam("seed"); + if (seed) { + env.seed(seed); + } + + /** + * ## Reporters + * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any). + */ + var htmlReporter = new jasmine.HtmlReporter({ + env: env, + onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); }, + onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); }, + onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); }, + addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); }, + getContainer: function() { return document.body; }, + createElement: function() { return document.createElement.apply(document, arguments); }, + createTextNode: function() { return document.createTextNode.apply(document, arguments); }, + timer: new jasmine.Timer() + }); + + /** + * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript. + */ + env.addReporter(jasmineInterface.jsApiReporter); + env.addReporter(htmlReporter); + + /** + * Filter which specs will be run by matching the start of the full name against the `spec` query param. + */ + var specFilter = new jasmine.HtmlSpecFilter({ + filterString: function() { return queryString.getParam("spec"); } + }); + + env.specFilter = function(spec) { + return specFilter.matches(spec.getFullName()); + }; + + /** + * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack. + */ + window.setTimeout = window.setTimeout; + window.setInterval = window.setInterval; + window.clearTimeout = window.clearTimeout; + window.clearInterval = window.clearInterval; + + /** + * ## Execution + * + * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded. + */ + var currentWindowOnload = window.onload; + + window.onload = function() { + if (currentWindowOnload) { + currentWindowOnload(); + } + htmlReporter.initialize(); + env.execute(); + }; + + /** + * Helper function for readability above. + */ + function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; + } + +}()); diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Player.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Player.js new file mode 100644 index 0000000..fe95f89 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Player.js @@ -0,0 +1,24 @@ +function Player() { +} +Player.prototype.play = function(song) { + this.currentlyPlayingSong = song; + this.isPlaying = true; +}; + +Player.prototype.pause = function() { + this.isPlaying = false; +}; + +Player.prototype.resume = function() { + if (this.isPlaying) { + throw new Error("song is already playing"); + } + + this.isPlaying = true; +}; + +Player.prototype.makeFavorite = function() { + this.currentlyPlayingSong.persistFavoriteStatus(true); +}; + +module.exports = Player; diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Song.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Song.js new file mode 100644 index 0000000..3415bb8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Song.js @@ -0,0 +1,9 @@ +function Song() { +} + +Song.prototype.persistFavoriteStatus = function(value) { + // something complicated + throw new Error("not yet implemented"); +}; + +module.exports = Song; diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/helpers/jasmine_examples/SpecHelper.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/helpers/jasmine_examples/SpecHelper.js new file mode 100644 index 0000000..578b3e8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/helpers/jasmine_examples/SpecHelper.js @@ -0,0 +1,15 @@ +beforeEach(function () { + jasmine.addMatchers({ + toBePlaying: function () { + return { + compare: function (actual, expected) { + var player = actual; + + return { + pass: player.currentlyPlayingSong === expected && player.isPlaying + } + } + }; + } + }); +}); diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/jasmine_examples/PlayerSpec.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/jasmine_examples/PlayerSpec.js new file mode 100644 index 0000000..80f149e --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/jasmine_examples/PlayerSpec.js @@ -0,0 +1,60 @@ +describe("Player", function() { + var Player = require('../../lib/jasmine_examples/Player'); + var Song = require('../../lib/jasmine_examples/Song'); + var player; + var song; + + beforeEach(function() { + player = new Player(); + song = new Song(); + }); + + it("should be able to play a Song", function() { + player.play(song); + expect(player.currentlyPlayingSong).toEqual(song); + + //demonstrates use of custom matcher + expect(player).toBePlaying(song); + }); + + describe("when song has been paused", function() { + beforeEach(function() { + player.play(song); + player.pause(); + }); + + it("should indicate that the song is currently paused", function() { + expect(player.isPlaying).toBeFalsy(); + + // demonstrates use of 'not' with a custom matcher + expect(player).not.toBePlaying(song); + }); + + it("should be possible to resume", function() { + player.resume(); + expect(player.isPlaying).toBeTruthy(); + expect(player.currentlyPlayingSong).toEqual(song); + }); + }); + + // demonstrates use of spies to intercept and test method calls + it("tells the current song if the user has made it a favorite", function() { + spyOn(song, 'persistFavoriteStatus'); + + player.play(song); + player.makeFavorite(); + + expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true); + }); + + //demonstrates use of expected exceptions + describe("#resume", function() { + it("should throw an exception if song is already playing", function() { + player.play(song); + + expect(function() { + player.resume(); + }).toThrowError("song is already playing"); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/PlayerSpec.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/PlayerSpec.js new file mode 100644 index 0000000..f17521f --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/PlayerSpec.js @@ -0,0 +1,58 @@ +describe("Player", function() { + var player; + var song; + + beforeEach(function() { + player = new Player(); + song = new Song(); + }); + + it("should be able to play a Song", function() { + player.play(song); + expect(player.currentlyPlayingSong).toEqual(song); + + //demonstrates use of custom matcher + expect(player).toBePlaying(song); + }); + + describe("when song has been paused", function() { + beforeEach(function() { + player.play(song); + player.pause(); + }); + + it("should indicate that the song is currently paused", function() { + expect(player.isPlaying).toBeFalsy(); + + // demonstrates use of 'not' with a custom matcher + expect(player).not.toBePlaying(song); + }); + + it("should be possible to resume", function() { + player.resume(); + expect(player.isPlaying).toBeTruthy(); + expect(player.currentlyPlayingSong).toEqual(song); + }); + }); + + // demonstrates use of spies to intercept and test method calls + it("tells the current song if the user has made it a favorite", function() { + spyOn(song, 'persistFavoriteStatus'); + + player.play(song); + player.makeFavorite(); + + expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true); + }); + + //demonstrates use of expected exceptions + describe("#resume", function() { + it("should throw an exception if song is already playing", function() { + player.play(song); + + expect(function() { + player.resume(); + }).toThrowError("song is already playing"); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/SpecHelper.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/SpecHelper.js new file mode 100644 index 0000000..126752d --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/SpecHelper.js @@ -0,0 +1,15 @@ +beforeEach(function () { + jasmine.addMatchers({ + toBePlaying: function () { + return { + compare: function (actual, expected) { + var player = actual; + + return { + pass: player.currentlyPlayingSong === expected && player.isPlaying + }; + } + }; + } + }); +}); diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Player.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Player.js new file mode 100644 index 0000000..fcce826 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Player.js @@ -0,0 +1,22 @@ +function Player() { +} +Player.prototype.play = function(song) { + this.currentlyPlayingSong = song; + this.isPlaying = true; +}; + +Player.prototype.pause = function() { + this.isPlaying = false; +}; + +Player.prototype.resume = function() { + if (this.isPlaying) { + throw new Error("song is already playing"); + } + + this.isPlaying = true; +}; + +Player.prototype.makeFavorite = function() { + this.currentlyPlayingSong.persistFavoriteStatus(true); +}; \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Song.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Song.js new file mode 100644 index 0000000..a8a3f2d --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Song.js @@ -0,0 +1,7 @@ +function Song() { +} + +Song.prototype.persistFavoriteStatus = function(value) { + // something complicated + throw new Error("not yet implemented"); +}; \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js new file mode 100644 index 0000000..da23532 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js @@ -0,0 +1,473 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +jasmineRequire.html = function(j$) { + j$.ResultsNode = jasmineRequire.ResultsNode(); + j$.HtmlReporter = jasmineRequire.HtmlReporter(j$); + j$.QueryString = jasmineRequire.QueryString(); + j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter(); +}; + +jasmineRequire.HtmlReporter = function(j$) { + + var noopTimer = { + start: function() {}, + elapsed: function() { return 0; } + }; + + function HtmlReporter(options) { + var env = options.env || {}, + getContainer = options.getContainer, + createElement = options.createElement, + createTextNode = options.createTextNode, + onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {}, + onThrowExpectationsClick = options.onThrowExpectationsClick || function() {}, + onRandomClick = options.onRandomClick || function() {}, + addToExistingQueryString = options.addToExistingQueryString || defaultQueryString, + timer = options.timer || noopTimer, + results = [], + specsExecuted = 0, + failureCount = 0, + pendingSpecCount = 0, + htmlReporterMain, + symbols, + failedSuites = []; + + this.initialize = function() { + clearPrior(); + htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'}, + createDom('div', {className: 'jasmine-banner'}, + createDom('a', {className: 'jasmine-title', href: 'http://jasmine.github.io/', target: '_blank'}), + createDom('span', {className: 'jasmine-version'}, j$.version) + ), + createDom('ul', {className: 'jasmine-symbol-summary'}), + createDom('div', {className: 'jasmine-alert'}), + createDom('div', {className: 'jasmine-results'}, + createDom('div', {className: 'jasmine-failures'}) + ) + ); + getContainer().appendChild(htmlReporterMain); + }; + + var totalSpecsDefined; + this.jasmineStarted = function(options) { + totalSpecsDefined = options.totalSpecsDefined || 0; + timer.start(); + }; + + var summary = createDom('div', {className: 'jasmine-summary'}); + + var topResults = new j$.ResultsNode({}, '', null), + currentParent = topResults; + + this.suiteStarted = function(result) { + currentParent.addChild(result, 'suite'); + currentParent = currentParent.last(); + }; + + this.suiteDone = function(result) { + if (result.status == 'failed') { + failedSuites.push(result); + } + + if (currentParent == topResults) { + return; + } + + currentParent = currentParent.parent; + }; + + this.specStarted = function(result) { + currentParent.addChild(result, 'spec'); + }; + + var failures = []; + this.specDone = function(result) { + if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') { + console.error('Spec \'' + result.fullName + '\' has no expectations.'); + } + + if (result.status != 'disabled') { + specsExecuted++; + } + + if (!symbols){ + symbols = find('.jasmine-symbol-summary'); + } + + symbols.appendChild(createDom('li', { + className: noExpectations(result) ? 'jasmine-empty' : 'jasmine-' + result.status, + id: 'spec_' + result.id, + title: result.fullName + } + )); + + if (result.status == 'failed') { + failureCount++; + + var failure = + createDom('div', {className: 'jasmine-spec-detail jasmine-failed'}, + createDom('div', {className: 'jasmine-description'}, + createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName) + ), + createDom('div', {className: 'jasmine-messages'}) + ); + var messages = failure.childNodes[1]; + + for (var i = 0; i < result.failedExpectations.length; i++) { + var expectation = result.failedExpectations[i]; + messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message)); + messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, expectation.stack)); + } + + failures.push(failure); + } + + if (result.status == 'pending') { + pendingSpecCount++; + } + }; + + this.jasmineDone = function(doneResult) { + var banner = find('.jasmine-banner'); + var alert = find('.jasmine-alert'); + var order = doneResult && doneResult.order; + alert.appendChild(createDom('span', {className: 'jasmine-duration'}, 'finished in ' + timer.elapsed() / 1000 + 's')); + + banner.appendChild( + createDom('div', { className: 'jasmine-run-options' }, + createDom('span', { className: 'jasmine-trigger' }, 'Options'), + createDom('div', { className: 'jasmine-payload' }, + createDom('div', { className: 'jasmine-exceptions' }, + createDom('input', { + className: 'jasmine-raise', + id: 'jasmine-raise-exceptions', + type: 'checkbox' + }), + createDom('label', { className: 'jasmine-label', 'for': 'jasmine-raise-exceptions' }, 'raise exceptions')), + createDom('div', { className: 'jasmine-throw-failures' }, + createDom('input', { + className: 'jasmine-throw', + id: 'jasmine-throw-failures', + type: 'checkbox' + }), + createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')), + createDom('div', { className: 'jasmine-random-order' }, + createDom('input', { + className: 'jasmine-random', + id: 'jasmine-random-order', + type: 'checkbox' + }), + createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order')) + ) + )); + + var raiseCheckbox = find('#jasmine-raise-exceptions'); + + raiseCheckbox.checked = !env.catchingExceptions(); + raiseCheckbox.onclick = onRaiseExceptionsClick; + + var throwCheckbox = find('#jasmine-throw-failures'); + throwCheckbox.checked = env.throwingExpectationFailures(); + throwCheckbox.onclick = onThrowExpectationsClick; + + var randomCheckbox = find('#jasmine-random-order'); + randomCheckbox.checked = env.randomTests(); + randomCheckbox.onclick = onRandomClick; + + var optionsMenu = find('.jasmine-run-options'), + optionsTrigger = optionsMenu.querySelector('.jasmine-trigger'), + optionsPayload = optionsMenu.querySelector('.jasmine-payload'), + isOpen = /\bjasmine-open\b/; + + optionsTrigger.onclick = function() { + if (isOpen.test(optionsPayload.className)) { + optionsPayload.className = optionsPayload.className.replace(isOpen, ''); + } else { + optionsPayload.className += ' jasmine-open'; + } + }; + + if (specsExecuted < totalSpecsDefined) { + var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all'; + alert.appendChild( + createDom('span', {className: 'jasmine-bar jasmine-skipped'}, + createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage) + ) + ); + } + var statusBarMessage = ''; + var statusBarClassName = 'jasmine-bar '; + + if (totalSpecsDefined > 0) { + statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount); + if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); } + statusBarClassName += (failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed'; + } else { + statusBarClassName += 'jasmine-skipped'; + statusBarMessage += 'No specs found'; + } + + var seedBar; + if (order && order.random) { + seedBar = createDom('span', {className: 'jasmine-seed-bar'}, + ', randomized with seed ', + createDom('a', {title: 'randomized with seed ' + order.seed, href: seedHref(order.seed)}, order.seed) + ); + } + + alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar)); + + for(i = 0; i < failedSuites.length; i++) { + var failedSuite = failedSuites[i]; + for(var j = 0; j < failedSuite.failedExpectations.length; j++) { + var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message; + var errorBarClassName = 'jasmine-bar jasmine-errored'; + alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage)); + } + } + + var results = find('.jasmine-results'); + results.appendChild(summary); + + summaryList(topResults, summary); + + function summaryList(resultsTree, domParent) { + var specListNode; + for (var i = 0; i < resultsTree.children.length; i++) { + var resultNode = resultsTree.children[i]; + if (resultNode.type == 'suite') { + var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id}, + createDom('li', {className: 'jasmine-suite-detail'}, + createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description) + ) + ); + + summaryList(resultNode, suiteListNode); + domParent.appendChild(suiteListNode); + } + if (resultNode.type == 'spec') { + if (domParent.getAttribute('class') != 'jasmine-specs') { + specListNode = createDom('ul', {className: 'jasmine-specs'}); + domParent.appendChild(specListNode); + } + var specDescription = resultNode.result.description; + if(noExpectations(resultNode.result)) { + specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription; + } + if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') { + specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason; + } + specListNode.appendChild( + createDom('li', { + className: 'jasmine-' + resultNode.result.status, + id: 'spec-' + resultNode.result.id + }, + createDom('a', {href: specHref(resultNode.result)}, specDescription) + ) + ); + } + } + } + + if (failures.length) { + alert.appendChild( + createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-spec-list'}, + createDom('span', {}, 'Spec List | '), + createDom('a', {className: 'jasmine-failures-menu', href: '#'}, 'Failures'))); + alert.appendChild( + createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-failure-list'}, + createDom('a', {className: 'jasmine-spec-list-menu', href: '#'}, 'Spec List'), + createDom('span', {}, ' | Failures '))); + + find('.jasmine-failures-menu').onclick = function() { + setMenuModeTo('jasmine-failure-list'); + }; + find('.jasmine-spec-list-menu').onclick = function() { + setMenuModeTo('jasmine-spec-list'); + }; + + setMenuModeTo('jasmine-failure-list'); + + var failureNode = find('.jasmine-failures'); + for (var i = 0; i < failures.length; i++) { + failureNode.appendChild(failures[i]); + } + } + }; + + return this; + + function find(selector) { + return getContainer().querySelector('.jasmine_html-reporter ' + selector); + } + + function clearPrior() { + // return the reporter + var oldReporter = find(''); + + if(oldReporter) { + getContainer().removeChild(oldReporter); + } + } + + function createDom(type, attrs, childrenVarArgs) { + var el = createElement(type); + + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i]; + + if (typeof child === 'string') { + el.appendChild(createTextNode(child)); + } else { + if (child) { + el.appendChild(child); + } + } + } + + for (var attr in attrs) { + if (attr == 'className') { + el[attr] = attrs[attr]; + } else { + el.setAttribute(attr, attrs[attr]); + } + } + + return el; + } + + function pluralize(singular, count) { + var word = (count == 1 ? singular : singular + 's'); + + return '' + count + ' ' + word; + } + + function specHref(result) { + return addToExistingQueryString('spec', result.fullName); + } + + function seedHref(seed) { + return addToExistingQueryString('seed', seed); + } + + function defaultQueryString(key, value) { + return '?' + key + '=' + value; + } + + function setMenuModeTo(mode) { + htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode); + } + + function noExpectations(result) { + return (result.failedExpectations.length + result.passedExpectations.length) === 0 && + result.status === 'passed'; + } + } + + return HtmlReporter; +}; + +jasmineRequire.HtmlSpecFilter = function() { + function HtmlSpecFilter(options) { + var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + var filterPattern = new RegExp(filterString); + + this.matches = function(specName) { + return filterPattern.test(specName); + }; + } + + return HtmlSpecFilter; +}; + +jasmineRequire.ResultsNode = function() { + function ResultsNode(result, type, parent) { + this.result = result; + this.type = type; + this.parent = parent; + + this.children = []; + + this.addChild = function(result, type) { + this.children.push(new ResultsNode(result, type, this)); + }; + + this.last = function() { + return this.children[this.children.length - 1]; + }; + } + + return ResultsNode; +}; + +jasmineRequire.QueryString = function() { + function QueryString(options) { + + this.navigateWithNewParam = function(key, value) { + options.getWindowLocation().search = this.fullStringWithNewParam(key, value); + }; + + this.fullStringWithNewParam = function(key, value) { + var paramMap = queryStringToParamMap(); + paramMap[key] = value; + return toQueryString(paramMap); + }; + + this.getParam = function(key) { + return queryStringToParamMap()[key]; + }; + + return this; + + function toQueryString(paramMap) { + var qStrPairs = []; + for (var prop in paramMap) { + qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop])); + } + return '?' + qStrPairs.join('&'); + } + + function queryStringToParamMap() { + var paramStr = options.getWindowLocation().search.substring(1), + params = [], + paramMap = {}; + + if (paramStr.length > 0) { + params = paramStr.split('&'); + for (var i = 0; i < params.length; i++) { + var p = params[i].split('='); + var value = decodeURIComponent(p[1]); + if (value === 'true' || value === 'false') { + value = JSON.parse(value); + } + paramMap[decodeURIComponent(p[0])] = value; + } + } + + return paramMap; + } + + } + + return QueryString; +}; diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.css b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.css new file mode 100644 index 0000000..6319982 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.css @@ -0,0 +1,58 @@ +body { overflow-y: scroll; } + +.jasmine_html-reporter { background-color: #eee; padding: 5px; margin: -8px; font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333; } +.jasmine_html-reporter a { text-decoration: none; } +.jasmine_html-reporter a:hover { text-decoration: underline; } +.jasmine_html-reporter p, .jasmine_html-reporter h1, .jasmine_html-reporter h2, .jasmine_html-reporter h3, .jasmine_html-reporter h4, .jasmine_html-reporter h5, .jasmine_html-reporter h6 { margin: 0; line-height: 14px; } +.jasmine_html-reporter .jasmine-banner, .jasmine_html-reporter .jasmine-symbol-summary, .jasmine_html-reporter .jasmine-summary, .jasmine_html-reporter .jasmine-result-message, .jasmine_html-reporter .jasmine-spec .jasmine-description, .jasmine_html-reporter .jasmine-spec-detail .jasmine-description, .jasmine_html-reporter .jasmine-alert .jasmine-bar, .jasmine_html-reporter .jasmine-stack-trace { padding-left: 9px; padding-right: 9px; } +.jasmine_html-reporter .jasmine-banner { position: relative; } +.jasmine_html-reporter .jasmine-banner .jasmine-title { background: url('data:image/png;base64,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') no-repeat; background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICB3aWR0aD0iNjgxLjk2MjUyIgogICBoZWlnaHQ9IjE4Ny41IgogICBpZD0ic3ZnMiIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhOCI+PHJkZjpSREY+PGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMKICAgICBpZD0iZGVmczYiPjxjbGlwUGF0aAogICAgICAgaWQ9ImNsaXBQYXRoMTgiPjxwYXRoCiAgICAgICAgIGQ9Ik0gMCwxNTAwIDAsMCBsIDU0NTUuNzQsMCAwLDE1MDAgTCAwLDE1MDAgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgyMCIgLz48L2NsaXBQYXRoPjwvZGVmcz48ZwogICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMjUsMCwwLC0xLjI1LDAsMTg3LjUpIgogICAgIGlkPSJnMTAiPjxnCiAgICAgICB0cmFuc2Zvcm09InNjYWxlKDAuMSwwLjEpIgogICAgICAgaWQ9ImcxMiI+PGcKICAgICAgICAgaWQ9ImcxNCI+PGcKICAgICAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGgxOCkiCiAgICAgICAgICAgaWQ9ImcxNiI+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTU0NCw1OTkuNDM0IGMgMC45MiwtNDAuMzUyIDI1LjY4LC04MS42MDIgNzEuNTMsLTgxLjYwMiAyNy41MSwwIDQ3LjY4LDEyLjgzMiA2MS40NCwzNS43NTQgMTIuODMsMjIuOTMgMTIuODMsNTYuODUyIDEyLjgzLDgyLjUyNyBsIDAsMzI5LjE4NCAtNzEuNTIsMCAwLDEwNC41NDMgMjY2LjgzLDAgMCwtMTA0LjU0MyAtNzAuNiwwIDAsLTM0NC43NyBjIDAsLTU4LjY5MSAtMy42OCwtMTA0LjUzMSAtNDQuOTMsLTE1Mi4yMTggLTM2LjY4LC00Mi4xOCAtOTYuMjgsLTY2LjAyIC0xNTMuMTQsLTY2LjAyIC0xMTcuMzcsMCAtMjA3LjI0LDc3Ljk0MSAtMjAyLjY0LDE5Ny4xNDUgbCAxMzAuMiwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMjIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDIzMDEuNCw2NjIuNjk1IGMgMCw4MC43MDMgLTY2Ljk0LDE0NS44MTMgLTE0Ny42MywxNDUuODEzIC04My40NCwwIC0xNDcuNjMsLTY4Ljc4MSAtMTQ3LjYzLC0xNTEuMzAxIDAsLTc5Ljc4NSA2Ni45NCwtMTQ1LjgwMSAxNDUuOCwtMTQ1LjgwMSA4NC4zNSwwIDE0OS40Niw2Ny44NTIgMTQ5LjQ2LDE1MS4yODkgeiBtIC0xLjgzLC0xODEuNTQ3IGMgLTM1Ljc3LC01NC4wOTcgLTkzLjUzLC03OC44NTkgLTE1Ny43MiwtNzguODU5IC0xNDAuMywwIC0yNTEuMjQsMTE2LjQ0OSAtMjUxLjI0LDI1NC45MTggMCwxNDIuMTI5IDExMy43LDI2MC40MSAyNTYuNzQsMjYwLjQxIDYzLjI3LDAgMTE4LjI5LC0yOS4zMzYgMTUyLjIyLC04Mi41MjMgbCAwLDY5LjY4NyAxNzUuMTQsMCAwLC0xMDQuNTI3IC02MS40NCwwIDAsLTI4MC41OTggNjEuNDQsMCAwLC0xMDQuNTI3IC0xNzUuMTQsMCAwLDY2LjAxOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAyNjIyLjMzLDU1Ny4yNTggYyAzLjY3LC00NC4wMTYgMzMuMDEsLTczLjM0OCA3OC44NiwtNzMuMzQ4IDMzLjkzLDAgNjYuOTMsMjMuODI0IDY2LjkzLDYwLjUwNCAwLDQ4LjYwNiAtNDUuODQsNTYuODU2IC04My40NCw2Ni45NDEgLTg1LjI4LDIyLjAwNCAtMTc4LjgxLDQ4LjYwNiAtMTc4LjgxLDE1NS44NzkgMCw5My41MzYgNzguODYsMTQ3LjYzMyAxNjUuOTgsMTQ3LjYzMyA0NCwwIDgzLjQzLC05LjE3NiAxMTAuOTQsLTQ0LjAwOCBsIDAsMzMuOTIyIDgyLjUzLDAgMCwtMTMyLjk2NSAtMTA4LjIxLDAgYyAtMS44MywzNC44NTYgLTI4LjQyLDU3Ljc3NCAtNjMuMjYsNTcuNzc0IC0zMC4yNiwwIC02Mi4zNSwtMTcuNDIyIC02Mi4zNSwtNTEuMzQ4IDAsLTQ1Ljg0NyA0NC45MywtNTUuOTMgODAuNjksLTY0LjE4IDg4LjAyLC0yMC4xNzUgMTgyLjQ3LC00Ny42OTUgMTgyLjQ3LC0xNTcuNzM0IDAsLTk5LjAyNyAtODMuNDQsLTE1NC4wMzkgLTE3NS4xMywtMTU0LjAzOSAtNDkuNTMsMCAtOTQuNDYsMTUuNTgyIC0xMjYuNTUsNTMuMTggbCAwLC00MC4zNCAtODUuMjcsMCAwLDE0Mi4xMjkgMTE0LjYyLDAiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGgyNiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMjk4OC4xOCw4MDAuMjU0IC02My4yNiwwIDAsMTA0LjUyNyAxNjUuMDUsMCAwLC03My4zNTUgYyAzMS4xOCw1MS4zNDcgNzguODYsODUuMjc3IDE0MS4yMSw4NS4yNzcgNjcuODUsMCAxMjQuNzEsLTQxLjI1OCAxNTIuMjEsLTEwMi42OTkgMjYuNiw2Mi4zNTEgOTIuNjIsMTAyLjY5OSAxNjAuNDcsMTAyLjY5OSA1My4xOSwwIDEwNS40NiwtMjIgMTQxLjIxLC02Mi4zNTEgMzguNTIsLTQ0LjkzOCAzOC41MiwtOTMuNTMyIDM4LjUyLC0xNDkuNDU3IGwgMCwtMTg1LjIzOSA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40MiwwIDAsMTA0LjUyNyA2My4yOCwwIDAsMTU3LjcxNSBjIDAsMzIuMTAyIDAsNjAuNTI3IC0xNC42Nyw4OC45NTcgLTE4LjM0LDI2LjU4MiAtNDguNjEsNDAuMzQ0IC03OS43Nyw0MC4zNDQgLTMwLjI2LDAgLTYzLjI4LC0xMi44NDQgLTgyLjUzLC0zNi42NzIgLTIyLjkzLC0yOS4zNTUgLTIyLjkzLC01Ni44NjMgLTIyLjkzLC05Mi42MjkgbCAwLC0xNTcuNzE1IDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM4LjQxLDAgMCwxMDQuNTI3IDYzLjI4LDAgMCwxNTAuMzgzIGMgMCwyOS4zNDggMCw2Ni4wMjMgLTE0LjY3LDkxLjY5OSAtMTUuNTksMjkuMzM2IC00Ny42OSw0NC45MzQgLTgwLjcsNDQuOTM0IC0zMS4xOCwwIC01Ny43NywtMTEuMDA4IC03Ny45NCwtMzUuNzc0IC0yNC43NywtMzAuMjUzIC0yNi42LC02Mi4zNDMgLTI2LjYsLTk5Ljk0MSBsIDAsLTE1MS4zMDEgNjMuMjcsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNiwwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAzOTk4LjY2LDk1MS41NDcgLTExMS44NywwIDAsMTE4LjI5MyAxMTEuODcsMCAwLC0xMTguMjkzIHogbSAwLC00MzEuODkxIDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM5LjMzLDAgMCwxMDQuNTI3IDY0LjE5LDAgMCwyODAuNTk4IC02My4yNywwIDAsMTA0LjUyNyAxNzUuMTQsMCAwLC0zODUuMTI1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzAiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDQxNTkuMTIsODAwLjI1NCAtNjMuMjcsMCAwLDEwNC41MjcgMTc1LjE0LDAgMCwtNjkuNjg3IGMgMjkuMzUsNTQuMTAxIDg0LjM2LDgwLjY5OSAxNDQuODcsODAuNjk5IDUzLjE5LDAgMTA1LjQ1LC0yMi4wMTYgMTQxLjIyLC02MC41MjcgNDAuMzQsLTQ0LjkzNCA0MS4yNiwtODguMDMyIDQxLjI2LC0xNDMuOTU3IGwgMCwtMTkxLjY1MyA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40LDAgMCwxMDQuNTI3IDYzLjI2LDAgMCwxNTguNjM3IGMgMCwzMC4yNjIgMCw2MS40MzQgLTE5LjI2LDg4LjAzNSAtMjAuMTcsMjYuNTgyIC01My4xOCwzOS40MTQgLTg2LjE5LDM5LjQxNCAtMzMuOTMsMCAtNjguNzcsLTEzLjc1IC04OC45NCwtNDEuMjUgLTIxLjA5LC0yNy41IC0yMS4wOSwtNjkuNjg3IC0yMS4wOSwtMTAyLjcwNyBsIDAsLTE0Mi4xMjkgNjMuMjYsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNywwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDMyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA1MDgyLjQ4LDcwMy45NjUgYyAtMTkuMjQsNzAuNjA1IC04MS42LDExNS41NDcgLTE1NC4wNCwxMTUuNTQ3IC02Ni4wNCwwIC0xMjkuMywtNTEuMzQ4IC0xNDMuMDUsLTExNS41NDcgbCAyOTcuMDksMCB6IG0gODUuMjcsLTE0NC44ODMgYyAtMzguNTEsLTkzLjUyMyAtMTI5LjI3LC0xNTYuNzkzIC0yMzEuMDUsLTE1Ni43OTMgLTE0My4wNywwIC0yNTcuNjgsMTExLjg3MSAtMjU3LjY4LDI1NS44MzYgMCwxNDQuODgzIDEwOS4xMiwyNjEuMzI4IDI1NC45MSwyNjEuMzI4IDY3Ljg3LDAgMTM1LjcyLC0zMC4yNTggMTgzLjM5LC03OC44NjMgNDguNjIsLTUxLjM0NCA2OC43OSwtMTEzLjY5NSA2OC43OSwtMTgzLjM4MyBsIC0zLjY3LC0zOS40MzQgLTM5Ni4xMywwIGMgMTQuNjcsLTY3Ljg2MyA3Ny4wMywtMTE3LjM2MyAxNDYuNzIsLTExNy4zNjMgNDguNTksMCA5MC43NiwxOC4zMjggMTE4LjI4LDU4LjY3MiBsIDExNi40NCwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDY5MC44OTUsODUwLjcwMyA5MC43NSwwIDIyLjU0MywzMS4wMzUgMCwyNDMuMTIyIC0xMzUuODI5LDAgMCwtMjQzLjE0MSAyMi41MzYsLTMxLjAxNiIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDM2IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA2MzIuMzk1LDc0Mi4yNTggMjguMDM5LDg2LjMwNCAtMjIuNTUxLDMxLjA0IC0yMzEuMjIzLDc1LjEyOCAtNDEuOTc2LC0xMjkuMTgzIDIzMS4yNTcsLTc1LjEzNyAzNi40NTQsMTEuODQ4IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzgiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDcxNy40NDksNjUzLjEwNSAtNzMuNDEsNTMuMzYgLTM2LjQ4OCwtMTEuODc1IC0xNDIuOTAzLC0xOTYuNjkyIDEwOS44ODMsLTc5LjgyOCAxNDIuOTE4LDE5Ni43MDMgMCwzOC4zMzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0MCIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gODI4LjUyLDcwNi40NjUgLTczLjQyNiwtNTMuMzQgMC4wMTEsLTM4LjM1OSBMIDg5OC4wMDQsNDE4LjA3IDEwMDcuOSw0OTcuODk4IDg2NC45NzMsNjk0LjYwOSA4MjguNTIsNzA2LjQ2NSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA4MTIuMDg2LDgyOC41ODYgMjguMDU1LC04Ni4zMiAzNi40ODQsLTExLjgzNiAyMzEuMjI1LDc1LjExNyAtNDEuOTcsMTI5LjE4MyAtMjMxLjIzOSwtNzUuMTQgLTIyLjU1NSwtMzEuMDA0IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNDQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDczNi4zMDEsMTMzNS44OCBjIC0zMjMuMDQ3LDAgLTU4NS44NzUsLTI2Mi43OCAtNTg1Ljg3NSwtNTg1Ljc4MiAwLC0zMjMuMTE4IDI2Mi44MjgsLTU4NS45NzcgNTg1Ljg3NSwtNTg1Ljk3NyAzMjMuMDE5LDAgNTg1LjgwOSwyNjIuODU5IDU4NS44MDksNTg1Ljk3NyAwLDMyMy4wMDIgLTI2Mi43OSw1ODUuNzgyIC01ODUuODA5LDU4NS43ODIgbCAwLDAgeiBtIDAsLTExOC42MSBjIDI1Ny45NzIsMCA0NjcuMTg5LC0yMDkuMTMgNDY3LjE4OSwtNDY3LjE3MiAwLC0yNTguMTI5IC0yMDkuMjE3LC00NjcuMzQ4IC00NjcuMTg5LC00NjcuMzQ4IC0yNTguMDc0LDAgLTQ2Ny4yNTQsMjA5LjIxOSAtNDY3LjI1NCw0NjcuMzQ4IDAsMjU4LjA0MiAyMDkuMTgsNDY3LjE3MiA0NjcuMjU0LDQ2Ny4xNzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0NiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTA5MS4xMyw2MTkuODgzIC0xNzUuNzcxLDU3LjEyMSAxMS42MjksMzUuODA4IDE3NS43NjIsLTU3LjEyMSAtMTEuNjIsLTM1LjgwOCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQ4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA4NjYuOTU3LDkwMi4wNzQgODM2LjUsOTI0LjE5OSA5NDUuMTIxLDEwNzMuNzMgOTc1LjU4NiwxMDUxLjYxIDg2Ni45NTcsOTAyLjA3NCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDUwIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA2MDcuNDY1LDkwMy40NDUgNDk4Ljg1NSwxMDUyLjk3IDUyOS4zMiwxMDc1LjEgNjM3LjkzLDkyNS41NjYgNjA3LjQ2NSw5MDMuNDQ1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDM4MC42ODgsNjIyLjEyOSAtMTEuNjI2LDM1LjgwMSAxNzUuNzU4LDU3LjA5IDExLjYyMSwtMzUuODAxIC0xNzUuNzUzLC01Ny4wOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDU0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA3MTYuMjg5LDM3Ni41OSAzNy42NDA2LDAgMCwxODQuODE2IC0zNy42NDA2LDAgMCwtMTg0LjgxNiB6IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTYiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4=') no-repeat, none; -moz-background-size: 100%; -o-background-size: 100%; -webkit-background-size: 100%; background-size: 100%; display: block; float: left; width: 90px; height: 25px; } +.jasmine_html-reporter .jasmine-banner .jasmine-version { margin-left: 14px; position: relative; top: 6px; } +.jasmine_html-reporter #jasmine_content { position: fixed; right: 100%; } +.jasmine_html-reporter .jasmine-version { color: #aaa; } +.jasmine_html-reporter .jasmine-banner { margin-top: 14px; } +.jasmine_html-reporter .jasmine-duration { color: #fff; float: right; line-height: 28px; padding-right: 9px; } +.jasmine_html-reporter .jasmine-symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; } +.jasmine_html-reporter .jasmine-symbol-summary li { display: inline-block; height: 10px; width: 14px; font-size: 16px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-passed { font-size: 14px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-passed:before { color: #007069; content: "\02022"; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-failed { line-height: 9px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-failed:before { color: #ca3a11; content: "\d7"; font-weight: bold; margin-left: -1px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-disabled { font-size: 14px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-disabled:before { color: #bababa; content: "\02022"; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-pending { line-height: 17px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-pending:before { color: #ba9d37; content: "*"; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-empty { font-size: 14px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-empty:before { color: #ba9d37; content: "\02022"; } +.jasmine_html-reporter .jasmine-run-options { float: right; margin-right: 5px; border: 1px solid #8a4182; color: #8a4182; position: relative; line-height: 20px; } +.jasmine_html-reporter .jasmine-run-options .jasmine-trigger { cursor: pointer; padding: 8px 16px; } +.jasmine_html-reporter .jasmine-run-options .jasmine-payload { position: absolute; display: none; right: -1px; border: 1px solid #8a4182; background-color: #eee; white-space: nowrap; padding: 4px 8px; } +.jasmine_html-reporter .jasmine-run-options .jasmine-payload.jasmine-open { display: block; } +.jasmine_html-reporter .jasmine-bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } +.jasmine_html-reporter .jasmine-bar.jasmine-failed { background-color: #ca3a11; } +.jasmine_html-reporter .jasmine-bar.jasmine-passed { background-color: #007069; } +.jasmine_html-reporter .jasmine-bar.jasmine-skipped { background-color: #bababa; } +.jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; } +.jasmine_html-reporter .jasmine-bar.jasmine-menu { background-color: #fff; color: #aaa; } +.jasmine_html-reporter .jasmine-bar.jasmine-menu a { color: #333; } +.jasmine_html-reporter .jasmine-bar a { color: white; } +.jasmine_html-reporter.jasmine-spec-list .jasmine-bar.jasmine-menu.jasmine-failure-list, .jasmine_html-reporter.jasmine-spec-list .jasmine-results .jasmine-failures { display: none; } +.jasmine_html-reporter.jasmine-failure-list .jasmine-bar.jasmine-menu.jasmine-spec-list, .jasmine_html-reporter.jasmine-failure-list .jasmine-summary { display: none; } +.jasmine_html-reporter .jasmine-results { margin-top: 14px; } +.jasmine_html-reporter .jasmine-summary { margin-top: 14px; } +.jasmine_html-reporter .jasmine-summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; } +.jasmine_html-reporter .jasmine-summary ul.jasmine-suite { margin-top: 7px; margin-bottom: 7px; } +.jasmine_html-reporter .jasmine-summary li.jasmine-passed a { color: #007069; } +.jasmine_html-reporter .jasmine-summary li.jasmine-failed a { color: #ca3a11; } +.jasmine_html-reporter .jasmine-summary li.jasmine-empty a { color: #ba9d37; } +.jasmine_html-reporter .jasmine-summary li.jasmine-pending a { color: #ba9d37; } +.jasmine_html-reporter .jasmine-summary li.jasmine-disabled a { color: #bababa; } +.jasmine_html-reporter .jasmine-description + .jasmine-suite { margin-top: 0; } +.jasmine_html-reporter .jasmine-suite { margin-top: 14px; } +.jasmine_html-reporter .jasmine-suite a { color: #333; } +.jasmine_html-reporter .jasmine-failures .jasmine-spec-detail { margin-bottom: 28px; } +.jasmine_html-reporter .jasmine-failures .jasmine-spec-detail .jasmine-description { background-color: #ca3a11; } +.jasmine_html-reporter .jasmine-failures .jasmine-spec-detail .jasmine-description a { color: white; } +.jasmine_html-reporter .jasmine-result-message { padding-top: 14px; color: #333; white-space: pre; } +.jasmine_html-reporter .jasmine-result-message span.jasmine-result { display: block; } +.jasmine_html-reporter .jasmine-stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666; border: 1px solid #ddd; background: white; white-space: pre; } diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.js new file mode 100644 index 0000000..bea469d --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.js @@ -0,0 +1,3454 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +var getJasmineRequireObj = (function (jasmineGlobal) { + var jasmineRequire; + + if (typeof module !== 'undefined' && module.exports) { + if (typeof global !== 'undefined') { + jasmineGlobal = global; + } else { + jasmineGlobal = {}; + } + jasmineRequire = exports; + } else { + if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') { + jasmineGlobal = window; + } + jasmineRequire = jasmineGlobal.jasmineRequire = jasmineGlobal.jasmineRequire || {}; + } + + function getJasmineRequire() { + return jasmineRequire; + } + + getJasmineRequire().core = function(jRequire) { + var j$ = {}; + + jRequire.base(j$, jasmineGlobal); + j$.util = jRequire.util(); + j$.errors = jRequire.errors(); + j$.Any = jRequire.Any(j$); + j$.Anything = jRequire.Anything(j$); + j$.CallTracker = jRequire.CallTracker(); + j$.MockDate = jRequire.MockDate(); + j$.Clock = jRequire.Clock(); + j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(); + j$.Env = jRequire.Env(j$); + j$.ExceptionFormatter = jRequire.ExceptionFormatter(); + j$.Expectation = jRequire.Expectation(); + j$.buildExpectationResult = jRequire.buildExpectationResult(); + j$.JsApiReporter = jRequire.JsApiReporter(); + j$.matchersUtil = jRequire.matchersUtil(j$); + j$.ObjectContaining = jRequire.ObjectContaining(j$); + j$.ArrayContaining = jRequire.ArrayContaining(j$); + j$.pp = jRequire.pp(j$); + j$.QueueRunner = jRequire.QueueRunner(j$); + j$.ReportDispatcher = jRequire.ReportDispatcher(); + j$.Spec = jRequire.Spec(j$); + j$.SpyRegistry = jRequire.SpyRegistry(j$); + j$.SpyStrategy = jRequire.SpyStrategy(); + j$.StringMatching = jRequire.StringMatching(j$); + j$.Suite = jRequire.Suite(j$); + j$.Timer = jRequire.Timer(); + j$.TreeProcessor = jRequire.TreeProcessor(); + j$.version = jRequire.version(); + j$.Order = jRequire.Order(); + + j$.matchers = jRequire.requireMatchers(jRequire, j$); + + return j$; + }; + + return getJasmineRequire; +})(this); + +getJasmineRequireObj().requireMatchers = function(jRequire, j$) { + var availableMatchers = [ + 'toBe', + 'toBeCloseTo', + 'toBeDefined', + 'toBeFalsy', + 'toBeGreaterThan', + 'toBeLessThan', + 'toBeNaN', + 'toBeNull', + 'toBeTruthy', + 'toBeUndefined', + 'toContain', + 'toEqual', + 'toHaveBeenCalled', + 'toHaveBeenCalledWith', + 'toHaveBeenCalledTimes', + 'toMatch', + 'toThrow', + 'toThrowError' + ], + matchers = {}; + + for (var i = 0; i < availableMatchers.length; i++) { + var name = availableMatchers[i]; + matchers[name] = jRequire[name](j$); + } + + return matchers; +}; + +getJasmineRequireObj().base = function(j$, jasmineGlobal) { + j$.unimplementedMethod_ = function() { + throw new Error('unimplemented method'); + }; + + j$.MAX_PRETTY_PRINT_DEPTH = 40; + j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 100; + j$.DEFAULT_TIMEOUT_INTERVAL = 5000; + + j$.getGlobal = function() { + return jasmineGlobal; + }; + + j$.getEnv = function(options) { + var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options); + //jasmine. singletons in here (setTimeout blah blah). + return env; + }; + + j$.isArray_ = function(value) { + return j$.isA_('Array', value); + }; + + j$.isString_ = function(value) { + return j$.isA_('String', value); + }; + + j$.isNumber_ = function(value) { + return j$.isA_('Number', value); + }; + + j$.isA_ = function(typeName, value) { + return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; + }; + + j$.isDomNode = function(obj) { + return obj.nodeType > 0; + }; + + j$.fnNameFor = function(func) { + return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1]; + }; + + j$.any = function(clazz) { + return new j$.Any(clazz); + }; + + j$.anything = function() { + return new j$.Anything(); + }; + + j$.objectContaining = function(sample) { + return new j$.ObjectContaining(sample); + }; + + j$.stringMatching = function(expected) { + return new j$.StringMatching(expected); + }; + + j$.arrayContaining = function(sample) { + return new j$.ArrayContaining(sample); + }; + + j$.createSpy = function(name, originalFn) { + + var spyStrategy = new j$.SpyStrategy({ + name: name, + fn: originalFn, + getSpy: function() { return spy; } + }), + callTracker = new j$.CallTracker(), + spy = function() { + var callData = { + object: this, + args: Array.prototype.slice.apply(arguments) + }; + + callTracker.track(callData); + var returnValue = spyStrategy.exec.apply(this, arguments); + callData.returnValue = returnValue; + + return returnValue; + }; + + for (var prop in originalFn) { + if (prop === 'and' || prop === 'calls') { + throw new Error('Jasmine spies would overwrite the \'and\' and \'calls\' properties on the object being spied upon'); + } + + spy[prop] = originalFn[prop]; + } + + spy.and = spyStrategy; + spy.calls = callTracker; + + return spy; + }; + + j$.isSpy = function(putativeSpy) { + if (!putativeSpy) { + return false; + } + return putativeSpy.and instanceof j$.SpyStrategy && + putativeSpy.calls instanceof j$.CallTracker; + }; + + j$.createSpyObj = function(baseName, methodNames) { + if (j$.isArray_(baseName) && j$.util.isUndefined(methodNames)) { + methodNames = baseName; + baseName = 'unknown'; + } + + if (!j$.isArray_(methodNames) || methodNames.length === 0) { + throw 'createSpyObj requires a non-empty array of method names to create spies for'; + } + var obj = {}; + for (var i = 0; i < methodNames.length; i++) { + obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]); + } + return obj; + }; +}; + +getJasmineRequireObj().util = function() { + + var util = {}; + + util.inherit = function(childClass, parentClass) { + var Subclass = function() { + }; + Subclass.prototype = parentClass.prototype; + childClass.prototype = new Subclass(); + }; + + util.htmlEscape = function(str) { + if (!str) { + return str; + } + return str.replace(/&/g, '&') + .replace(//g, '>'); + }; + + util.argsToArray = function(args) { + var arrayOfArgs = []; + for (var i = 0; i < args.length; i++) { + arrayOfArgs.push(args[i]); + } + return arrayOfArgs; + }; + + util.isUndefined = function(obj) { + return obj === void 0; + }; + + util.arrayContains = function(array, search) { + var i = array.length; + while (i--) { + if (array[i] === search) { + return true; + } + } + return false; + }; + + util.clone = function(obj) { + if (Object.prototype.toString.apply(obj) === '[object Array]') { + return obj.slice(); + } + + var cloned = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + cloned[prop] = obj[prop]; + } + } + + return cloned; + }; + + return util; +}; + +getJasmineRequireObj().Spec = function(j$) { + function Spec(attrs) { + this.expectationFactory = attrs.expectationFactory; + this.resultCallback = attrs.resultCallback || function() {}; + this.id = attrs.id; + this.description = attrs.description || ''; + this.queueableFn = attrs.queueableFn; + this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; }; + this.userContext = attrs.userContext || function() { return {}; }; + this.onStart = attrs.onStart || function() {}; + this.getSpecName = attrs.getSpecName || function() { return ''; }; + this.expectationResultFactory = attrs.expectationResultFactory || function() { }; + this.queueRunnerFactory = attrs.queueRunnerFactory || function() {}; + this.catchingExceptions = attrs.catchingExceptions || function() { return true; }; + this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure; + + if (!this.queueableFn.fn) { + this.pend(); + } + + this.result = { + id: this.id, + description: this.description, + fullName: this.getFullName(), + failedExpectations: [], + passedExpectations: [], + pendingReason: '' + }; + } + + Spec.prototype.addExpectationResult = function(passed, data, isError) { + var expectationResult = this.expectationResultFactory(data); + if (passed) { + this.result.passedExpectations.push(expectationResult); + } else { + this.result.failedExpectations.push(expectationResult); + + if (this.throwOnExpectationFailure && !isError) { + throw new j$.errors.ExpectationFailed(); + } + } + }; + + Spec.prototype.expect = function(actual) { + return this.expectationFactory(actual, this); + }; + + Spec.prototype.execute = function(onComplete, enabled) { + var self = this; + + this.onStart(this); + + if (!this.isExecutable() || this.markedPending || enabled === false) { + complete(enabled); + return; + } + + var fns = this.beforeAndAfterFns(); + var allFns = fns.befores.concat(this.queueableFn).concat(fns.afters); + + this.queueRunnerFactory({ + queueableFns: allFns, + onException: function() { self.onException.apply(self, arguments); }, + onComplete: complete, + userContext: this.userContext() + }); + + function complete(enabledAgain) { + self.result.status = self.status(enabledAgain); + self.resultCallback(self.result); + + if (onComplete) { + onComplete(); + } + } + }; + + Spec.prototype.onException = function onException(e) { + if (Spec.isPendingSpecException(e)) { + this.pend(extractCustomPendingMessage(e)); + return; + } + + if (e instanceof j$.errors.ExpectationFailed) { + return; + } + + this.addExpectationResult(false, { + matcherName: '', + passed: false, + expected: '', + actual: '', + error: e + }, true); + }; + + Spec.prototype.disable = function() { + this.disabled = true; + }; + + Spec.prototype.pend = function(message) { + this.markedPending = true; + if (message) { + this.result.pendingReason = message; + } + }; + + Spec.prototype.getResult = function() { + this.result.status = this.status(); + return this.result; + }; + + Spec.prototype.status = function(enabled) { + if (this.disabled || enabled === false) { + return 'disabled'; + } + + if (this.markedPending) { + return 'pending'; + } + + if (this.result.failedExpectations.length > 0) { + return 'failed'; + } else { + return 'passed'; + } + }; + + Spec.prototype.isExecutable = function() { + return !this.disabled; + }; + + Spec.prototype.getFullName = function() { + return this.getSpecName(this); + }; + + var extractCustomPendingMessage = function(e) { + var fullMessage = e.toString(), + boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage), + boilerplateEnd = boilerplateStart + Spec.pendingSpecExceptionMessage.length; + + return fullMessage.substr(boilerplateEnd); + }; + + Spec.pendingSpecExceptionMessage = '=> marked Pending'; + + Spec.isPendingSpecException = function(e) { + return !!(e && e.toString && e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1); + }; + + return Spec; +}; + +if (typeof window == void 0 && typeof exports == 'object') { + exports.Spec = jasmineRequire.Spec; +} + +/*jshint bitwise: false*/ + +getJasmineRequireObj().Order = function() { + function Order(options) { + this.random = 'random' in options ? options.random : true; + var seed = this.seed = options.seed || generateSeed(); + this.sort = this.random ? randomOrder : naturalOrder; + + function naturalOrder(items) { + return items; + } + + function randomOrder(items) { + var copy = items.slice(); + copy.sort(function(a, b) { + return jenkinsHash(seed + a.id) - jenkinsHash(seed + b.id); + }); + return copy; + } + + function generateSeed() { + return String(Math.random()).slice(-5); + } + + // Bob Jenkins One-at-a-Time Hash algorithm is a non-cryptographic hash function + // used to get a different output when the key changes slighly. + // We use your return to sort the children randomly in a consistent way when + // used in conjunction with a seed + + function jenkinsHash(key) { + var hash, i; + for(hash = i = 0; i < key.length; ++i) { + hash += key.charCodeAt(i); + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return hash; + } + + } + + return Order; +}; + +getJasmineRequireObj().Env = function(j$) { + function Env(options) { + options = options || {}; + + var self = this; + var global = options.global || j$.getGlobal(); + + var totalSpecsDefined = 0; + + var catchExceptions = true; + + var realSetTimeout = j$.getGlobal().setTimeout; + var realClearTimeout = j$.getGlobal().clearTimeout; + this.clock = new j$.Clock(global, function () { return new j$.DelayedFunctionScheduler(); }, new j$.MockDate(global)); + + var runnableLookupTable = {}; + var runnableResources = {}; + + var currentSpec = null; + var currentlyExecutingSuites = []; + var currentDeclarationSuite = null; + var throwOnExpectationFailure = false; + var random = false; + var seed = null; + + var currentSuite = function() { + return currentlyExecutingSuites[currentlyExecutingSuites.length - 1]; + }; + + var currentRunnable = function() { + return currentSpec || currentSuite(); + }; + + var reporter = new j$.ReportDispatcher([ + 'jasmineStarted', + 'jasmineDone', + 'suiteStarted', + 'suiteDone', + 'specStarted', + 'specDone' + ]); + + this.specFilter = function() { + return true; + }; + + this.addCustomEqualityTester = function(tester) { + if(!currentRunnable()) { + throw new Error('Custom Equalities must be added in a before function or a spec'); + } + runnableResources[currentRunnable().id].customEqualityTesters.push(tester); + }; + + this.addMatchers = function(matchersToAdd) { + if(!currentRunnable()) { + throw new Error('Matchers must be added in a before function or a spec'); + } + var customMatchers = runnableResources[currentRunnable().id].customMatchers; + for (var matcherName in matchersToAdd) { + customMatchers[matcherName] = matchersToAdd[matcherName]; + } + }; + + j$.Expectation.addCoreMatchers(j$.matchers); + + var nextSpecId = 0; + var getNextSpecId = function() { + return 'spec' + nextSpecId++; + }; + + var nextSuiteId = 0; + var getNextSuiteId = function() { + return 'suite' + nextSuiteId++; + }; + + var expectationFactory = function(actual, spec) { + return j$.Expectation.Factory({ + util: j$.matchersUtil, + customEqualityTesters: runnableResources[spec.id].customEqualityTesters, + customMatchers: runnableResources[spec.id].customMatchers, + actual: actual, + addExpectationResult: addExpectationResult + }); + + function addExpectationResult(passed, result) { + return spec.addExpectationResult(passed, result); + } + }; + + var defaultResourcesForRunnable = function(id, parentRunnableId) { + var resources = {spies: [], customEqualityTesters: [], customMatchers: {}}; + + if(runnableResources[parentRunnableId]){ + resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters); + resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers); + } + + runnableResources[id] = resources; + }; + + var clearResourcesForRunnable = function(id) { + spyRegistry.clearSpies(); + delete runnableResources[id]; + }; + + var beforeAndAfterFns = function(suite) { + return function() { + var befores = [], + afters = []; + + while(suite) { + befores = befores.concat(suite.beforeFns); + afters = afters.concat(suite.afterFns); + + suite = suite.parentSuite; + } + + return { + befores: befores.reverse(), + afters: afters + }; + }; + }; + + var getSpecName = function(spec, suite) { + return suite.getFullName() + ' ' + spec.description; + }; + + // TODO: we may just be able to pass in the fn instead of wrapping here + var buildExpectationResult = j$.buildExpectationResult, + exceptionFormatter = new j$.ExceptionFormatter(), + expectationResultFactory = function(attrs) { + attrs.messageFormatter = exceptionFormatter.message; + attrs.stackFormatter = exceptionFormatter.stack; + + return buildExpectationResult(attrs); + }; + + // TODO: fix this naming, and here's where the value comes in + this.catchExceptions = function(value) { + catchExceptions = !!value; + return catchExceptions; + }; + + this.catchingExceptions = function() { + return catchExceptions; + }; + + var maximumSpecCallbackDepth = 20; + var currentSpecCallbackDepth = 0; + + function clearStack(fn) { + currentSpecCallbackDepth++; + if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) { + currentSpecCallbackDepth = 0; + realSetTimeout(fn, 0); + } else { + fn(); + } + } + + var catchException = function(e) { + return j$.Spec.isPendingSpecException(e) || catchExceptions; + }; + + this.throwOnExpectationFailure = function(value) { + throwOnExpectationFailure = !!value; + }; + + this.throwingExpectationFailures = function() { + return throwOnExpectationFailure; + }; + + this.randomizeTests = function(value) { + random = !!value; + }; + + this.randomTests = function() { + return random; + }; + + this.seed = function(value) { + if (value) { + seed = value; + } + return seed; + }; + + var queueRunnerFactory = function(options) { + options.catchException = catchException; + options.clearStack = options.clearStack || clearStack; + options.timeout = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}; + options.fail = self.fail; + + new j$.QueueRunner(options).execute(); + }; + + var topSuite = new j$.Suite({ + env: this, + id: getNextSuiteId(), + description: 'Jasmine__TopLevel__Suite', + queueRunner: queueRunnerFactory + }); + runnableLookupTable[topSuite.id] = topSuite; + defaultResourcesForRunnable(topSuite.id); + currentDeclarationSuite = topSuite; + + this.topSuite = function() { + return topSuite; + }; + + this.execute = function(runnablesToRun) { + if(!runnablesToRun) { + if (focusedRunnables.length) { + runnablesToRun = focusedRunnables; + } else { + runnablesToRun = [topSuite.id]; + } + } + + var order = new j$.Order({ + random: random, + seed: seed + }); + + var processor = new j$.TreeProcessor({ + tree: topSuite, + runnableIds: runnablesToRun, + queueRunnerFactory: queueRunnerFactory, + nodeStart: function(suite) { + currentlyExecutingSuites.push(suite); + defaultResourcesForRunnable(suite.id, suite.parentSuite.id); + reporter.suiteStarted(suite.result); + }, + nodeComplete: function(suite, result) { + if (!suite.disabled) { + clearResourcesForRunnable(suite.id); + } + currentlyExecutingSuites.pop(); + reporter.suiteDone(result); + }, + orderChildren: function(node) { + return order.sort(node.children); + } + }); + + if(!processor.processTree().valid) { + throw new Error('Invalid order: would cause a beforeAll or afterAll to be run multiple times'); + } + + reporter.jasmineStarted({ + totalSpecsDefined: totalSpecsDefined + }); + + processor.execute(function() { + reporter.jasmineDone({ + order: order + }); + }); + }; + + this.addReporter = function(reporterToAdd) { + reporter.addReporter(reporterToAdd); + }; + + var spyRegistry = new j$.SpyRegistry({currentSpies: function() { + if(!currentRunnable()) { + throw new Error('Spies must be created in a before function or a spec'); + } + return runnableResources[currentRunnable().id].spies; + }}); + + this.spyOn = function() { + return spyRegistry.spyOn.apply(spyRegistry, arguments); + }; + + var suiteFactory = function(description) { + var suite = new j$.Suite({ + env: self, + id: getNextSuiteId(), + description: description, + parentSuite: currentDeclarationSuite, + expectationFactory: expectationFactory, + expectationResultFactory: expectationResultFactory, + throwOnExpectationFailure: throwOnExpectationFailure + }); + + runnableLookupTable[suite.id] = suite; + return suite; + }; + + this.describe = function(description, specDefinitions) { + var suite = suiteFactory(description); + if (specDefinitions.length > 0) { + throw new Error('describe does not expect a done parameter'); + } + if (currentDeclarationSuite.markedPending) { + suite.pend(); + } + addSpecsToSuite(suite, specDefinitions); + return suite; + }; + + this.xdescribe = function(description, specDefinitions) { + var suite = suiteFactory(description); + suite.pend(); + addSpecsToSuite(suite, specDefinitions); + return suite; + }; + + var focusedRunnables = []; + + this.fdescribe = function(description, specDefinitions) { + var suite = suiteFactory(description); + suite.isFocused = true; + + focusedRunnables.push(suite.id); + unfocusAncestor(); + addSpecsToSuite(suite, specDefinitions); + + return suite; + }; + + function addSpecsToSuite(suite, specDefinitions) { + var parentSuite = currentDeclarationSuite; + parentSuite.addChild(suite); + currentDeclarationSuite = suite; + + var declarationError = null; + try { + specDefinitions.call(suite); + } catch (e) { + declarationError = e; + } + + if (declarationError) { + self.it('encountered a declaration exception', function() { + throw declarationError; + }); + } + + currentDeclarationSuite = parentSuite; + } + + function findFocusedAncestor(suite) { + while (suite) { + if (suite.isFocused) { + return suite.id; + } + suite = suite.parentSuite; + } + + return null; + } + + function unfocusAncestor() { + var focusedAncestor = findFocusedAncestor(currentDeclarationSuite); + if (focusedAncestor) { + for (var i = 0; i < focusedRunnables.length; i++) { + if (focusedRunnables[i] === focusedAncestor) { + focusedRunnables.splice(i, 1); + break; + } + } + } + } + + var specFactory = function(description, fn, suite, timeout) { + totalSpecsDefined++; + var spec = new j$.Spec({ + id: getNextSpecId(), + beforeAndAfterFns: beforeAndAfterFns(suite), + expectationFactory: expectationFactory, + resultCallback: specResultCallback, + getSpecName: function(spec) { + return getSpecName(spec, suite); + }, + onStart: specStarted, + description: description, + expectationResultFactory: expectationResultFactory, + queueRunnerFactory: queueRunnerFactory, + userContext: function() { return suite.clonedSharedUserContext(); }, + queueableFn: { + fn: fn, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }, + throwOnExpectationFailure: throwOnExpectationFailure + }); + + runnableLookupTable[spec.id] = spec; + + if (!self.specFilter(spec)) { + spec.disable(); + } + + return spec; + + function specResultCallback(result) { + clearResourcesForRunnable(spec.id); + currentSpec = null; + reporter.specDone(result); + } + + function specStarted(spec) { + currentSpec = spec; + defaultResourcesForRunnable(spec.id, suite.id); + reporter.specStarted(spec.result); + } + }; + + this.it = function(description, fn, timeout) { + var spec = specFactory(description, fn, currentDeclarationSuite, timeout); + if (currentDeclarationSuite.markedPending) { + spec.pend(); + } + currentDeclarationSuite.addChild(spec); + return spec; + }; + + this.xit = function() { + var spec = this.it.apply(this, arguments); + spec.pend('Temporarily disabled with xit'); + return spec; + }; + + this.fit = function(description, fn, timeout){ + var spec = specFactory(description, fn, currentDeclarationSuite, timeout); + currentDeclarationSuite.addChild(spec); + focusedRunnables.push(spec.id); + unfocusAncestor(); + return spec; + }; + + this.expect = function(actual) { + if (!currentRunnable()) { + throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out'); + } + + return currentRunnable().expect(actual); + }; + + this.beforeEach = function(beforeEachFunction, timeout) { + currentDeclarationSuite.beforeEach({ + fn: beforeEachFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.beforeAll = function(beforeAllFunction, timeout) { + currentDeclarationSuite.beforeAll({ + fn: beforeAllFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.afterEach = function(afterEachFunction, timeout) { + currentDeclarationSuite.afterEach({ + fn: afterEachFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.afterAll = function(afterAllFunction, timeout) { + currentDeclarationSuite.afterAll({ + fn: afterAllFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.pending = function(message) { + var fullMessage = j$.Spec.pendingSpecExceptionMessage; + if(message) { + fullMessage += message; + } + throw fullMessage; + }; + + this.fail = function(error) { + var message = 'Failed'; + if (error) { + message += ': '; + message += error.message || error; + } + + currentRunnable().addExpectationResult(false, { + matcherName: '', + passed: false, + expected: '', + actual: '', + message: message, + error: error && error.message ? error : null + }); + }; + } + + return Env; +}; + +getJasmineRequireObj().JsApiReporter = function() { + + var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } + }; + + function JsApiReporter(options) { + var timer = options.timer || noopTimer, + status = 'loaded'; + + this.started = false; + this.finished = false; + this.runDetails = {}; + + this.jasmineStarted = function() { + this.started = true; + status = 'started'; + timer.start(); + }; + + var executionTime; + + this.jasmineDone = function(runDetails) { + this.finished = true; + this.runDetails = runDetails; + executionTime = timer.elapsed(); + status = 'done'; + }; + + this.status = function() { + return status; + }; + + var suites = [], + suites_hash = {}; + + this.suiteStarted = function(result) { + suites_hash[result.id] = result; + }; + + this.suiteDone = function(result) { + storeSuite(result); + }; + + this.suiteResults = function(index, length) { + return suites.slice(index, index + length); + }; + + function storeSuite(result) { + suites.push(result); + suites_hash[result.id] = result; + } + + this.suites = function() { + return suites_hash; + }; + + var specs = []; + + this.specDone = function(result) { + specs.push(result); + }; + + this.specResults = function(index, length) { + return specs.slice(index, index + length); + }; + + this.specs = function() { + return specs; + }; + + this.executionTime = function() { + return executionTime; + }; + + } + + return JsApiReporter; +}; + +getJasmineRequireObj().CallTracker = function() { + + function CallTracker() { + var calls = []; + + this.track = function(context) { + calls.push(context); + }; + + this.any = function() { + return !!calls.length; + }; + + this.count = function() { + return calls.length; + }; + + this.argsFor = function(index) { + var call = calls[index]; + return call ? call.args : []; + }; + + this.all = function() { + return calls; + }; + + this.allArgs = function() { + var callArgs = []; + for(var i = 0; i < calls.length; i++){ + callArgs.push(calls[i].args); + } + + return callArgs; + }; + + this.first = function() { + return calls[0]; + }; + + this.mostRecent = function() { + return calls[calls.length - 1]; + }; + + this.reset = function() { + calls = []; + }; + } + + return CallTracker; +}; + +getJasmineRequireObj().Clock = function() { + function Clock(global, delayedFunctionSchedulerFactory, mockDate) { + var self = this, + realTimingFunctions = { + setTimeout: global.setTimeout, + clearTimeout: global.clearTimeout, + setInterval: global.setInterval, + clearInterval: global.clearInterval + }, + fakeTimingFunctions = { + setTimeout: setTimeout, + clearTimeout: clearTimeout, + setInterval: setInterval, + clearInterval: clearInterval + }, + installed = false, + delayedFunctionScheduler, + timer; + + + self.install = function() { + if(!originalTimingFunctionsIntact()) { + throw new Error('Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?'); + } + replace(global, fakeTimingFunctions); + timer = fakeTimingFunctions; + delayedFunctionScheduler = delayedFunctionSchedulerFactory(); + installed = true; + + return self; + }; + + self.uninstall = function() { + delayedFunctionScheduler = null; + mockDate.uninstall(); + replace(global, realTimingFunctions); + + timer = realTimingFunctions; + installed = false; + }; + + self.withMock = function(closure) { + this.install(); + try { + closure(); + } finally { + this.uninstall(); + } + }; + + self.mockDate = function(initialDate) { + mockDate.install(initialDate); + }; + + self.setTimeout = function(fn, delay, params) { + if (legacyIE()) { + if (arguments.length > 2) { + throw new Error('IE < 9 cannot support extra params to setTimeout without a polyfill'); + } + return timer.setTimeout(fn, delay); + } + return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]); + }; + + self.setInterval = function(fn, delay, params) { + if (legacyIE()) { + if (arguments.length > 2) { + throw new Error('IE < 9 cannot support extra params to setInterval without a polyfill'); + } + return timer.setInterval(fn, delay); + } + return Function.prototype.apply.apply(timer.setInterval, [global, arguments]); + }; + + self.clearTimeout = function(id) { + return Function.prototype.call.apply(timer.clearTimeout, [global, id]); + }; + + self.clearInterval = function(id) { + return Function.prototype.call.apply(timer.clearInterval, [global, id]); + }; + + self.tick = function(millis) { + if (installed) { + mockDate.tick(millis); + delayedFunctionScheduler.tick(millis); + } else { + throw new Error('Mock clock is not installed, use jasmine.clock().install()'); + } + }; + + return self; + + function originalTimingFunctionsIntact() { + return global.setTimeout === realTimingFunctions.setTimeout && + global.clearTimeout === realTimingFunctions.clearTimeout && + global.setInterval === realTimingFunctions.setInterval && + global.clearInterval === realTimingFunctions.clearInterval; + } + + function legacyIE() { + //if these methods are polyfilled, apply will be present + return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply; + } + + function replace(dest, source) { + for (var prop in source) { + dest[prop] = source[prop]; + } + } + + function setTimeout(fn, delay) { + return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2)); + } + + function clearTimeout(id) { + return delayedFunctionScheduler.removeFunctionWithId(id); + } + + function setInterval(fn, interval) { + return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true); + } + + function clearInterval(id) { + return delayedFunctionScheduler.removeFunctionWithId(id); + } + + function argSlice(argsObj, n) { + return Array.prototype.slice.call(argsObj, n); + } + } + + return Clock; +}; + +getJasmineRequireObj().DelayedFunctionScheduler = function() { + function DelayedFunctionScheduler() { + var self = this; + var scheduledLookup = []; + var scheduledFunctions = {}; + var currentTime = 0; + var delayedFnCount = 0; + + self.tick = function(millis) { + millis = millis || 0; + var endTime = currentTime + millis; + + runScheduledFunctions(endTime); + currentTime = endTime; + }; + + self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) { + var f; + if (typeof(funcToCall) === 'string') { + /* jshint evil: true */ + f = function() { return eval(funcToCall); }; + /* jshint evil: false */ + } else { + f = funcToCall; + } + + millis = millis || 0; + timeoutKey = timeoutKey || ++delayedFnCount; + runAtMillis = runAtMillis || (currentTime + millis); + + var funcToSchedule = { + runAtMillis: runAtMillis, + funcToCall: f, + recurring: recurring, + params: params, + timeoutKey: timeoutKey, + millis: millis + }; + + if (runAtMillis in scheduledFunctions) { + scheduledFunctions[runAtMillis].push(funcToSchedule); + } else { + scheduledFunctions[runAtMillis] = [funcToSchedule]; + scheduledLookup.push(runAtMillis); + scheduledLookup.sort(function (a, b) { + return a - b; + }); + } + + return timeoutKey; + }; + + self.removeFunctionWithId = function(timeoutKey) { + for (var runAtMillis in scheduledFunctions) { + var funcs = scheduledFunctions[runAtMillis]; + var i = indexOfFirstToPass(funcs, function (func) { + return func.timeoutKey === timeoutKey; + }); + + if (i > -1) { + if (funcs.length === 1) { + delete scheduledFunctions[runAtMillis]; + deleteFromLookup(runAtMillis); + } else { + funcs.splice(i, 1); + } + + // intervals get rescheduled when executed, so there's never more + // than a single scheduled function with a given timeoutKey + break; + } + } + }; + + return self; + + function indexOfFirstToPass(array, testFn) { + var index = -1; + + for (var i = 0; i < array.length; ++i) { + if (testFn(array[i])) { + index = i; + break; + } + } + + return index; + } + + function deleteFromLookup(key) { + var value = Number(key); + var i = indexOfFirstToPass(scheduledLookup, function (millis) { + return millis === value; + }); + + if (i > -1) { + scheduledLookup.splice(i, 1); + } + } + + function reschedule(scheduledFn) { + self.scheduleFunction(scheduledFn.funcToCall, + scheduledFn.millis, + scheduledFn.params, + true, + scheduledFn.timeoutKey, + scheduledFn.runAtMillis + scheduledFn.millis); + } + + function forEachFunction(funcsToRun, callback) { + for (var i = 0; i < funcsToRun.length; ++i) { + callback(funcsToRun[i]); + } + } + + function runScheduledFunctions(endTime) { + if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) { + return; + } + + do { + currentTime = scheduledLookup.shift(); + + var funcsToRun = scheduledFunctions[currentTime]; + delete scheduledFunctions[currentTime]; + + forEachFunction(funcsToRun, function(funcToRun) { + if (funcToRun.recurring) { + reschedule(funcToRun); + } + }); + + forEachFunction(funcsToRun, function(funcToRun) { + funcToRun.funcToCall.apply(null, funcToRun.params || []); + }); + } while (scheduledLookup.length > 0 && + // checking first if we're out of time prevents setTimeout(0) + // scheduled in a funcToRun from forcing an extra iteration + currentTime !== endTime && + scheduledLookup[0] <= endTime); + } + } + + return DelayedFunctionScheduler; +}; + +getJasmineRequireObj().ExceptionFormatter = function() { + function ExceptionFormatter() { + this.message = function(error) { + var message = ''; + + if (error.name && error.message) { + message += error.name + ': ' + error.message; + } else { + message += error.toString() + ' thrown'; + } + + if (error.fileName || error.sourceURL) { + message += ' in ' + (error.fileName || error.sourceURL); + } + + if (error.line || error.lineNumber) { + message += ' (line ' + (error.line || error.lineNumber) + ')'; + } + + return message; + }; + + this.stack = function(error) { + return error ? error.stack : null; + }; + } + + return ExceptionFormatter; +}; + +getJasmineRequireObj().Expectation = function() { + + function Expectation(options) { + this.util = options.util || { buildFailureMessage: function() {} }; + this.customEqualityTesters = options.customEqualityTesters || []; + this.actual = options.actual; + this.addExpectationResult = options.addExpectationResult || function(){}; + this.isNot = options.isNot; + + var customMatchers = options.customMatchers || {}; + for (var matcherName in customMatchers) { + this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]); + } + } + + Expectation.prototype.wrapCompare = function(name, matcherFactory) { + return function() { + var args = Array.prototype.slice.call(arguments, 0), + expected = args.slice(0), + message = ''; + + args.unshift(this.actual); + + var matcher = matcherFactory(this.util, this.customEqualityTesters), + matcherCompare = matcher.compare; + + function defaultNegativeCompare() { + var result = matcher.compare.apply(null, args); + result.pass = !result.pass; + return result; + } + + if (this.isNot) { + matcherCompare = matcher.negativeCompare || defaultNegativeCompare; + } + + var result = matcherCompare.apply(null, args); + + if (!result.pass) { + if (!result.message) { + args.unshift(this.isNot); + args.unshift(name); + message = this.util.buildFailureMessage.apply(null, args); + } else { + if (Object.prototype.toString.apply(result.message) === '[object Function]') { + message = result.message(); + } else { + message = result.message; + } + } + } + + if (expected.length == 1) { + expected = expected[0]; + } + + // TODO: how many of these params are needed? + this.addExpectationResult( + result.pass, + { + matcherName: name, + passed: result.pass, + message: message, + actual: this.actual, + expected: expected // TODO: this may need to be arrayified/sliced + } + ); + }; + }; + + Expectation.addCoreMatchers = function(matchers) { + var prototype = Expectation.prototype; + for (var matcherName in matchers) { + var matcher = matchers[matcherName]; + prototype[matcherName] = prototype.wrapCompare(matcherName, matcher); + } + }; + + Expectation.Factory = function(options) { + options = options || {}; + + var expect = new Expectation(options); + + // TODO: this would be nice as its own Object - NegativeExpectation + // TODO: copy instead of mutate options + options.isNot = true; + expect.not = new Expectation(options); + + return expect; + }; + + return Expectation; +}; + +//TODO: expectation result may make more sense as a presentation of an expectation. +getJasmineRequireObj().buildExpectationResult = function() { + function buildExpectationResult(options) { + var messageFormatter = options.messageFormatter || function() {}, + stackFormatter = options.stackFormatter || function() {}; + + var result = { + matcherName: options.matcherName, + message: message(), + stack: stack(), + passed: options.passed + }; + + if(!result.passed) { + result.expected = options.expected; + result.actual = options.actual; + } + + return result; + + function message() { + if (options.passed) { + return 'Passed.'; + } else if (options.message) { + return options.message; + } else if (options.error) { + return messageFormatter(options.error); + } + return ''; + } + + function stack() { + if (options.passed) { + return ''; + } + + var error = options.error; + if (!error) { + try { + throw new Error(message()); + } catch (e) { + error = e; + } + } + return stackFormatter(error); + } + } + + return buildExpectationResult; +}; + +getJasmineRequireObj().MockDate = function() { + function MockDate(global) { + var self = this; + var currentTime = 0; + + if (!global || !global.Date) { + self.install = function() {}; + self.tick = function() {}; + self.uninstall = function() {}; + return self; + } + + var GlobalDate = global.Date; + + self.install = function(mockDate) { + if (mockDate instanceof GlobalDate) { + currentTime = mockDate.getTime(); + } else { + currentTime = new GlobalDate().getTime(); + } + + global.Date = FakeDate; + }; + + self.tick = function(millis) { + millis = millis || 0; + currentTime = currentTime + millis; + }; + + self.uninstall = function() { + currentTime = 0; + global.Date = GlobalDate; + }; + + createDateProperties(); + + return self; + + function FakeDate() { + switch(arguments.length) { + case 0: + return new GlobalDate(currentTime); + case 1: + return new GlobalDate(arguments[0]); + case 2: + return new GlobalDate(arguments[0], arguments[1]); + case 3: + return new GlobalDate(arguments[0], arguments[1], arguments[2]); + case 4: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3]); + case 5: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4]); + case 6: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4], arguments[5]); + default: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4], arguments[5], arguments[6]); + } + } + + function createDateProperties() { + FakeDate.prototype = GlobalDate.prototype; + + FakeDate.now = function() { + if (GlobalDate.now) { + return currentTime; + } else { + throw new Error('Browser does not support Date.now()'); + } + }; + + FakeDate.toSource = GlobalDate.toSource; + FakeDate.toString = GlobalDate.toString; + FakeDate.parse = GlobalDate.parse; + FakeDate.UTC = GlobalDate.UTC; + } + } + + return MockDate; +}; + +getJasmineRequireObj().pp = function(j$) { + + function PrettyPrinter() { + this.ppNestLevel_ = 0; + this.seen = []; + } + + PrettyPrinter.prototype.format = function(value) { + this.ppNestLevel_++; + try { + if (j$.util.isUndefined(value)) { + this.emitScalar('undefined'); + } else if (value === null) { + this.emitScalar('null'); + } else if (value === 0 && 1/value === -Infinity) { + this.emitScalar('-0'); + } else if (value === j$.getGlobal()) { + this.emitScalar(''); + } else if (value.jasmineToString) { + this.emitScalar(value.jasmineToString()); + } else if (typeof value === 'string') { + this.emitString(value); + } else if (j$.isSpy(value)) { + this.emitScalar('spy on ' + value.and.identity()); + } else if (value instanceof RegExp) { + this.emitScalar(value.toString()); + } else if (typeof value === 'function') { + this.emitScalar('Function'); + } else if (typeof value.nodeType === 'number') { + this.emitScalar('HTMLNode'); + } else if (value instanceof Date) { + this.emitScalar('Date(' + value + ')'); + } else if (value.toString && typeof value === 'object' && !(value instanceof Array) && value.toString !== Object.prototype.toString) { + this.emitScalar(value.toString()); + } else if (j$.util.arrayContains(this.seen, value)) { + this.emitScalar(''); + } else if (j$.isArray_(value) || j$.isA_('Object', value)) { + this.seen.push(value); + if (j$.isArray_(value)) { + this.emitArray(value); + } else { + this.emitObject(value); + } + this.seen.pop(); + } else { + this.emitScalar(value.toString()); + } + } finally { + this.ppNestLevel_--; + } + }; + + PrettyPrinter.prototype.iterateObject = function(obj, fn) { + for (var property in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, property)) { continue; } + fn(property, obj.__lookupGetter__ ? (!j$.util.isUndefined(obj.__lookupGetter__(property)) && + obj.__lookupGetter__(property) !== null) : false); + } + }; + + PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitString = j$.unimplementedMethod_; + + function StringPrettyPrinter() { + PrettyPrinter.call(this); + + this.string = ''; + } + + j$.util.inherit(StringPrettyPrinter, PrettyPrinter); + + StringPrettyPrinter.prototype.emitScalar = function(value) { + this.append(value); + }; + + StringPrettyPrinter.prototype.emitString = function(value) { + this.append('\'' + value + '\''); + }; + + StringPrettyPrinter.prototype.emitArray = function(array) { + if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { + this.append('Array'); + return; + } + var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH); + this.append('[ '); + for (var i = 0; i < length; i++) { + if (i > 0) { + this.append(', '); + } + this.format(array[i]); + } + if(array.length > length){ + this.append(', ...'); + } + + var self = this; + var first = array.length === 0; + this.iterateObject(array, function(property, isGetter) { + if (property.match(/^\d+$/)) { + return; + } + + if (first) { + first = false; + } else { + self.append(', '); + } + + self.formatProperty(array, property, isGetter); + }); + + this.append(' ]'); + }; + + StringPrettyPrinter.prototype.emitObject = function(obj) { + var constructorName = obj.constructor ? j$.fnNameFor(obj.constructor) : 'null'; + this.append(constructorName); + + if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { + return; + } + + var self = this; + this.append('({ '); + var first = true; + + this.iterateObject(obj, function(property, isGetter) { + if (first) { + first = false; + } else { + self.append(', '); + } + + self.formatProperty(obj, property, isGetter); + }); + + this.append(' })'); + }; + + StringPrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) { + this.append(property); + this.append(': '); + if (isGetter) { + this.append(''); + } else { + this.format(obj[property]); + } + }; + + StringPrettyPrinter.prototype.append = function(value) { + this.string += value; + }; + + return function(value) { + var stringPrettyPrinter = new StringPrettyPrinter(); + stringPrettyPrinter.format(value); + return stringPrettyPrinter.string; + }; +}; + +getJasmineRequireObj().QueueRunner = function(j$) { + + function once(fn) { + var called = false; + return function() { + if (!called) { + called = true; + fn(); + } + }; + } + + function QueueRunner(attrs) { + this.queueableFns = attrs.queueableFns || []; + this.onComplete = attrs.onComplete || function() {}; + this.clearStack = attrs.clearStack || function(fn) {fn();}; + this.onException = attrs.onException || function() {}; + this.catchException = attrs.catchException || function() { return true; }; + this.userContext = attrs.userContext || {}; + this.timeout = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout}; + this.fail = attrs.fail || function() {}; + } + + QueueRunner.prototype.execute = function() { + this.run(this.queueableFns, 0); + }; + + QueueRunner.prototype.run = function(queueableFns, recursiveIndex) { + var length = queueableFns.length, + self = this, + iterativeIndex; + + + for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) { + var queueableFn = queueableFns[iterativeIndex]; + if (queueableFn.fn.length > 0) { + attemptAsync(queueableFn); + return; + } else { + attemptSync(queueableFn); + } + } + + var runnerDone = iterativeIndex >= length; + + if (runnerDone) { + this.clearStack(this.onComplete); + } + + function attemptSync(queueableFn) { + try { + queueableFn.fn.call(self.userContext); + } catch (e) { + handleException(e, queueableFn); + } + } + + function attemptAsync(queueableFn) { + var clearTimeout = function () { + Function.prototype.apply.apply(self.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]); + }, + next = once(function () { + clearTimeout(timeoutId); + self.run(queueableFns, iterativeIndex + 1); + }), + timeoutId; + + next.fail = function() { + self.fail.apply(null, arguments); + next(); + }; + + if (queueableFn.timeout) { + timeoutId = Function.prototype.apply.apply(self.timeout.setTimeout, [j$.getGlobal(), [function() { + var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'); + onException(error); + next(); + }, queueableFn.timeout()]]); + } + + try { + queueableFn.fn.call(self.userContext, next); + } catch (e) { + handleException(e, queueableFn); + next(); + } + } + + function onException(e) { + self.onException(e); + } + + function handleException(e, queueableFn) { + onException(e); + if (!self.catchException(e)) { + //TODO: set a var when we catch an exception and + //use a finally block to close the loop in a nice way.. + throw e; + } + } + }; + + return QueueRunner; +}; + +getJasmineRequireObj().ReportDispatcher = function() { + function ReportDispatcher(methods) { + + var dispatchedMethods = methods || []; + + for (var i = 0; i < dispatchedMethods.length; i++) { + var method = dispatchedMethods[i]; + this[method] = (function(m) { + return function() { + dispatch(m, arguments); + }; + }(method)); + } + + var reporters = []; + + this.addReporter = function(reporter) { + reporters.push(reporter); + }; + + return this; + + function dispatch(method, args) { + for (var i = 0; i < reporters.length; i++) { + var reporter = reporters[i]; + if (reporter[method]) { + reporter[method].apply(reporter, args); + } + } + } + } + + return ReportDispatcher; +}; + + +getJasmineRequireObj().SpyRegistry = function(j$) { + + function SpyRegistry(options) { + options = options || {}; + var currentSpies = options.currentSpies || function() { return []; }; + + this.spyOn = function(obj, methodName) { + if (j$.util.isUndefined(obj)) { + throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()'); + } + + if (j$.util.isUndefined(methodName)) { + throw new Error('No method name supplied'); + } + + if (j$.util.isUndefined(obj[methodName])) { + throw new Error(methodName + '() method does not exist'); + } + + if (obj[methodName] && j$.isSpy(obj[methodName])) { + //TODO?: should this return the current spy? Downside: may cause user confusion about spy state + throw new Error(methodName + ' has already been spied upon'); + } + + var descriptor; + try { + descriptor = Object.getOwnPropertyDescriptor(obj, methodName); + } catch(e) { + // IE 8 doesn't support `definePropery` on non-DOM nodes + } + + if (descriptor && !(descriptor.writable || descriptor.set)) { + throw new Error(methodName + ' is not declared writable or has no setter'); + } + + var spy = j$.createSpy(methodName, obj[methodName]); + + currentSpies().push({ + spy: spy, + baseObj: obj, + methodName: methodName, + originalValue: obj[methodName] + }); + + obj[methodName] = spy; + + return spy; + }; + + this.clearSpies = function() { + var spies = currentSpies(); + for (var i = 0; i < spies.length; i++) { + var spyEntry = spies[i]; + spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue; + } + }; + } + + return SpyRegistry; +}; + +getJasmineRequireObj().SpyStrategy = function() { + + function SpyStrategy(options) { + options = options || {}; + + var identity = options.name || 'unknown', + originalFn = options.fn || function() {}, + getSpy = options.getSpy || function() {}, + plan = function() {}; + + this.identity = function() { + return identity; + }; + + this.exec = function() { + return plan.apply(this, arguments); + }; + + this.callThrough = function() { + plan = originalFn; + return getSpy(); + }; + + this.returnValue = function(value) { + plan = function() { + return value; + }; + return getSpy(); + }; + + this.returnValues = function() { + var values = Array.prototype.slice.call(arguments); + plan = function () { + return values.shift(); + }; + return getSpy(); + }; + + this.throwError = function(something) { + var error = (something instanceof Error) ? something : new Error(something); + plan = function() { + throw error; + }; + return getSpy(); + }; + + this.callFake = function(fn) { + plan = fn; + return getSpy(); + }; + + this.stub = function(fn) { + plan = function() {}; + return getSpy(); + }; + } + + return SpyStrategy; +}; + +getJasmineRequireObj().Suite = function(j$) { + function Suite(attrs) { + this.env = attrs.env; + this.id = attrs.id; + this.parentSuite = attrs.parentSuite; + this.description = attrs.description; + this.expectationFactory = attrs.expectationFactory; + this.expectationResultFactory = attrs.expectationResultFactory; + this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure; + + this.beforeFns = []; + this.afterFns = []; + this.beforeAllFns = []; + this.afterAllFns = []; + this.disabled = false; + + this.children = []; + + this.result = { + id: this.id, + description: this.description, + fullName: this.getFullName(), + failedExpectations: [] + }; + } + + Suite.prototype.expect = function(actual) { + return this.expectationFactory(actual, this); + }; + + Suite.prototype.getFullName = function() { + var fullName = this.description; + for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { + if (parentSuite.parentSuite) { + fullName = parentSuite.description + ' ' + fullName; + } + } + return fullName; + }; + + Suite.prototype.disable = function() { + this.disabled = true; + }; + + Suite.prototype.pend = function(message) { + this.markedPending = true; + }; + + Suite.prototype.beforeEach = function(fn) { + this.beforeFns.unshift(fn); + }; + + Suite.prototype.beforeAll = function(fn) { + this.beforeAllFns.push(fn); + }; + + Suite.prototype.afterEach = function(fn) { + this.afterFns.unshift(fn); + }; + + Suite.prototype.afterAll = function(fn) { + this.afterAllFns.push(fn); + }; + + Suite.prototype.addChild = function(child) { + this.children.push(child); + }; + + Suite.prototype.status = function() { + if (this.disabled) { + return 'disabled'; + } + + if (this.markedPending) { + return 'pending'; + } + + if (this.result.failedExpectations.length > 0) { + return 'failed'; + } else { + return 'finished'; + } + }; + + Suite.prototype.isExecutable = function() { + return !this.disabled; + }; + + Suite.prototype.canBeReentered = function() { + return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0; + }; + + Suite.prototype.getResult = function() { + this.result.status = this.status(); + return this.result; + }; + + Suite.prototype.sharedUserContext = function() { + if (!this.sharedContext) { + this.sharedContext = this.parentSuite ? clone(this.parentSuite.sharedUserContext()) : {}; + } + + return this.sharedContext; + }; + + Suite.prototype.clonedSharedUserContext = function() { + return clone(this.sharedUserContext()); + }; + + Suite.prototype.onException = function() { + if (arguments[0] instanceof j$.errors.ExpectationFailed) { + return; + } + + if(isAfterAll(this.children)) { + var data = { + matcherName: '', + passed: false, + expected: '', + actual: '', + error: arguments[0] + }; + this.result.failedExpectations.push(this.expectationResultFactory(data)); + } else { + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + child.onException.apply(child, arguments); + } + } + }; + + Suite.prototype.addExpectationResult = function () { + if(isAfterAll(this.children) && isFailure(arguments)){ + var data = arguments[1]; + this.result.failedExpectations.push(this.expectationResultFactory(data)); + if(this.throwOnExpectationFailure) { + throw new j$.errors.ExpectationFailed(); + } + } else { + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + try { + child.addExpectationResult.apply(child, arguments); + } catch(e) { + // keep going + } + } + } + }; + + function isAfterAll(children) { + return children && children[0].result.status; + } + + function isFailure(args) { + return !args[0]; + } + + function clone(obj) { + var clonedObj = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + clonedObj[prop] = obj[prop]; + } + } + + return clonedObj; + } + + return Suite; +}; + +if (typeof window == void 0 && typeof exports == 'object') { + exports.Suite = jasmineRequire.Suite; +} + +getJasmineRequireObj().Timer = function() { + var defaultNow = (function(Date) { + return function() { return new Date().getTime(); }; + })(Date); + + function Timer(options) { + options = options || {}; + + var now = options.now || defaultNow, + startTime; + + this.start = function() { + startTime = now(); + }; + + this.elapsed = function() { + return now() - startTime; + }; + } + + return Timer; +}; + +getJasmineRequireObj().TreeProcessor = function() { + function TreeProcessor(attrs) { + var tree = attrs.tree, + runnableIds = attrs.runnableIds, + queueRunnerFactory = attrs.queueRunnerFactory, + nodeStart = attrs.nodeStart || function() {}, + nodeComplete = attrs.nodeComplete || function() {}, + orderChildren = attrs.orderChildren || function(node) { return node.children; }, + stats = { valid: true }, + processed = false, + defaultMin = Infinity, + defaultMax = 1 - Infinity; + + this.processTree = function() { + processNode(tree, false); + processed = true; + return stats; + }; + + this.execute = function(done) { + if (!processed) { + this.processTree(); + } + + if (!stats.valid) { + throw 'invalid order'; + } + + var childFns = wrapChildren(tree, 0); + + queueRunnerFactory({ + queueableFns: childFns, + userContext: tree.sharedUserContext(), + onException: function() { + tree.onException.apply(tree, arguments); + }, + onComplete: done + }); + }; + + function runnableIndex(id) { + for (var i = 0; i < runnableIds.length; i++) { + if (runnableIds[i] === id) { + return i; + } + } + } + + function processNode(node, parentEnabled) { + var executableIndex = runnableIndex(node.id); + + if (executableIndex !== undefined) { + parentEnabled = true; + } + + parentEnabled = parentEnabled && node.isExecutable(); + + if (!node.children) { + stats[node.id] = { + executable: parentEnabled && node.isExecutable(), + segments: [{ + index: 0, + owner: node, + nodes: [node], + min: startingMin(executableIndex), + max: startingMax(executableIndex) + }] + }; + } else { + var hasExecutableChild = false; + + var orderedChildren = orderChildren(node); + + for (var i = 0; i < orderedChildren.length; i++) { + var child = orderedChildren[i]; + + processNode(child, parentEnabled); + + if (!stats.valid) { + return; + } + + var childStats = stats[child.id]; + + hasExecutableChild = hasExecutableChild || childStats.executable; + } + + stats[node.id] = { + executable: hasExecutableChild + }; + + segmentChildren(node, orderedChildren, stats[node.id], executableIndex); + + if (!node.canBeReentered() && stats[node.id].segments.length > 1) { + stats = { valid: false }; + } + } + } + + function startingMin(executableIndex) { + return executableIndex === undefined ? defaultMin : executableIndex; + } + + function startingMax(executableIndex) { + return executableIndex === undefined ? defaultMax : executableIndex; + } + + function segmentChildren(node, orderedChildren, nodeStats, executableIndex) { + var currentSegment = { index: 0, owner: node, nodes: [], min: startingMin(executableIndex), max: startingMax(executableIndex) }, + result = [currentSegment], + lastMax = defaultMax, + orderedChildSegments = orderChildSegments(orderedChildren); + + function isSegmentBoundary(minIndex) { + return lastMax !== defaultMax && minIndex !== defaultMin && lastMax < minIndex - 1; + } + + for (var i = 0; i < orderedChildSegments.length; i++) { + var childSegment = orderedChildSegments[i], + maxIndex = childSegment.max, + minIndex = childSegment.min; + + if (isSegmentBoundary(minIndex)) { + currentSegment = {index: result.length, owner: node, nodes: [], min: defaultMin, max: defaultMax}; + result.push(currentSegment); + } + + currentSegment.nodes.push(childSegment); + currentSegment.min = Math.min(currentSegment.min, minIndex); + currentSegment.max = Math.max(currentSegment.max, maxIndex); + lastMax = maxIndex; + } + + nodeStats.segments = result; + } + + function orderChildSegments(children) { + var specifiedOrder = [], + unspecifiedOrder = []; + + for (var i = 0; i < children.length; i++) { + var child = children[i], + segments = stats[child.id].segments; + + for (var j = 0; j < segments.length; j++) { + var seg = segments[j]; + + if (seg.min === defaultMin) { + unspecifiedOrder.push(seg); + } else { + specifiedOrder.push(seg); + } + } + } + + specifiedOrder.sort(function(a, b) { + return a.min - b.min; + }); + + return specifiedOrder.concat(unspecifiedOrder); + } + + function executeNode(node, segmentNumber) { + if (node.children) { + return { + fn: function(done) { + nodeStart(node); + + queueRunnerFactory({ + onComplete: function() { + nodeComplete(node, node.getResult()); + done(); + }, + queueableFns: wrapChildren(node, segmentNumber), + userContext: node.sharedUserContext(), + onException: function() { + node.onException.apply(node, arguments); + } + }); + } + }; + } else { + return { + fn: function(done) { node.execute(done, stats[node.id].executable); } + }; + } + } + + function wrapChildren(node, segmentNumber) { + var result = [], + segmentChildren = stats[node.id].segments[segmentNumber].nodes; + + for (var i = 0; i < segmentChildren.length; i++) { + result.push(executeNode(segmentChildren[i].owner, segmentChildren[i].index)); + } + + if (!stats[node.id].executable) { + return result; + } + + return node.beforeAllFns.concat(result).concat(node.afterAllFns); + } + } + + return TreeProcessor; +}; + +getJasmineRequireObj().Any = function(j$) { + + function Any(expectedObject) { + if (typeof expectedObject === 'undefined') { + throw new TypeError( + 'jasmine.any() expects to be passed a constructor function. ' + + 'Please pass one or use jasmine.anything() to match any object.' + ); + } + this.expectedObject = expectedObject; + } + + Any.prototype.asymmetricMatch = function(other) { + if (this.expectedObject == String) { + return typeof other == 'string' || other instanceof String; + } + + if (this.expectedObject == Number) { + return typeof other == 'number' || other instanceof Number; + } + + if (this.expectedObject == Function) { + return typeof other == 'function' || other instanceof Function; + } + + if (this.expectedObject == Object) { + return typeof other == 'object'; + } + + if (this.expectedObject == Boolean) { + return typeof other == 'boolean'; + } + + return other instanceof this.expectedObject; + }; + + Any.prototype.jasmineToString = function() { + return ''; + }; + + return Any; +}; + +getJasmineRequireObj().Anything = function(j$) { + + function Anything() {} + + Anything.prototype.asymmetricMatch = function(other) { + return !j$.util.isUndefined(other) && other !== null; + }; + + Anything.prototype.jasmineToString = function() { + return ''; + }; + + return Anything; +}; + +getJasmineRequireObj().ArrayContaining = function(j$) { + function ArrayContaining(sample) { + this.sample = sample; + } + + ArrayContaining.prototype.asymmetricMatch = function(other) { + var className = Object.prototype.toString.call(this.sample); + if (className !== '[object Array]') { throw new Error('You must provide an array to arrayContaining, not \'' + this.sample + '\'.'); } + + for (var i = 0; i < this.sample.length; i++) { + var item = this.sample[i]; + if (!j$.matchersUtil.contains(other, item)) { + return false; + } + } + + return true; + }; + + ArrayContaining.prototype.jasmineToString = function () { + return ''; + }; + + return ArrayContaining; +}; + +getJasmineRequireObj().ObjectContaining = function(j$) { + + function ObjectContaining(sample) { + this.sample = sample; + } + + function getPrototype(obj) { + if (Object.getPrototypeOf) { + return Object.getPrototypeOf(obj); + } + + if (obj.constructor.prototype == obj) { + return null; + } + + return obj.constructor.prototype; + } + + function hasProperty(obj, property) { + if (!obj) { + return false; + } + + if (Object.prototype.hasOwnProperty.call(obj, property)) { + return true; + } + + return hasProperty(getPrototype(obj), property); + } + + ObjectContaining.prototype.asymmetricMatch = function(other) { + if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); } + + for (var property in this.sample) { + if (!hasProperty(other, property) || + !j$.matchersUtil.equals(this.sample[property], other[property])) { + return false; + } + } + + return true; + }; + + ObjectContaining.prototype.jasmineToString = function() { + return ''; + }; + + return ObjectContaining; +}; + +getJasmineRequireObj().StringMatching = function(j$) { + + function StringMatching(expected) { + if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { + throw new Error('Expected is not a String or a RegExp'); + } + + this.regexp = new RegExp(expected); + } + + StringMatching.prototype.asymmetricMatch = function(other) { + return this.regexp.test(other); + }; + + StringMatching.prototype.jasmineToString = function() { + return ''; + }; + + return StringMatching; +}; + +getJasmineRequireObj().errors = function() { + function ExpectationFailed() {} + + ExpectationFailed.prototype = new Error(); + ExpectationFailed.prototype.constructor = ExpectationFailed; + + return { + ExpectationFailed: ExpectationFailed + }; +}; +getJasmineRequireObj().matchersUtil = function(j$) { + // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter? + + return { + equals: function(a, b, customTesters) { + customTesters = customTesters || []; + + return eq(a, b, [], [], customTesters); + }, + + contains: function(haystack, needle, customTesters) { + customTesters = customTesters || []; + + if ((Object.prototype.toString.apply(haystack) === '[object Array]') || + (!!haystack && !haystack.indexOf)) + { + for (var i = 0; i < haystack.length; i++) { + if (eq(haystack[i], needle, [], [], customTesters)) { + return true; + } + } + return false; + } + + return !!haystack && haystack.indexOf(needle) >= 0; + }, + + buildFailureMessage: function() { + var args = Array.prototype.slice.call(arguments, 0), + matcherName = args[0], + isNot = args[1], + actual = args[2], + expected = args.slice(3), + englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); + + var message = 'Expected ' + + j$.pp(actual) + + (isNot ? ' not ' : ' ') + + englishyPredicate; + + if (expected.length > 0) { + for (var i = 0; i < expected.length; i++) { + if (i > 0) { + message += ','; + } + message += ' ' + j$.pp(expected[i]); + } + } + + return message + '.'; + } + }; + + function isAsymmetric(obj) { + return obj && j$.isA_('Function', obj.asymmetricMatch); + } + + function asymmetricMatch(a, b) { + var asymmetricA = isAsymmetric(a), + asymmetricB = isAsymmetric(b); + + if (asymmetricA && asymmetricB) { + return undefined; + } + + if (asymmetricA) { + return a.asymmetricMatch(b); + } + + if (asymmetricB) { + return b.asymmetricMatch(a); + } + } + + // Equality function lovingly adapted from isEqual in + // [Underscore](http://underscorejs.org) + function eq(a, b, aStack, bStack, customTesters) { + var result = true; + + var asymmetricResult = asymmetricMatch(a, b); + if (!j$.util.isUndefined(asymmetricResult)) { + return asymmetricResult; + } + + for (var i = 0; i < customTesters.length; i++) { + var customTesterResult = customTesters[i](a, b); + if (!j$.util.isUndefined(customTesterResult)) { + return customTesterResult; + } + } + + if (a instanceof Error && b instanceof Error) { + return a.message == b.message; + } + + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) { return a !== 0 || 1 / a == 1 / b; } + // A strict comparison is necessary because `null == undefined`. + if (a === null || b === null) { return a === b; } + var className = Object.prototype.toString.call(a); + if (className != Object.prototype.toString.call(b)) { return false; } + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') { return false; } + + var aIsDomNode = j$.isDomNode(a); + var bIsDomNode = j$.isDomNode(b); + if (aIsDomNode && bIsDomNode) { + // At first try to use DOM3 method isEqualNode + if (a.isEqualNode) { + return a.isEqualNode(b); + } + // IE8 doesn't support isEqualNode, try to use outerHTML && innerText + var aIsElement = a instanceof Element; + var bIsElement = b instanceof Element; + if (aIsElement && bIsElement) { + return a.outerHTML == b.outerHTML; + } + if (aIsElement || bIsElement) { + return false; + } + return a.innerText == b.innerText && a.textContent == b.textContent; + } + if (aIsDomNode || bIsDomNode) { + return false; + } + + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] == a) { return bStack[length] == b; } + } + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + var size = 0; + // Recursively compare objects and arrays. + // Compare array lengths to determine if a deep comparison is necessary. + if (className == '[object Array]' && a.length !== b.length) { + result = false; + } + + if (result) { + // Objects with different constructors are not equivalent, but `Object`s + // or `Array`s from different frames are. + if (className !== '[object Array]') { + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(isFunction(aCtor) && aCtor instanceof aCtor && + isFunction(bCtor) && bCtor instanceof bCtor)) { + return false; + } + } + // Deep compare objects. + for (var key in a) { + if (has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) { break; } + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (has(b, key) && !(size--)) { break; } + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + + return result; + + function has(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); + } + + function isFunction(obj) { + return typeof obj === 'function'; + } + } +}; + +getJasmineRequireObj().toBe = function() { + function toBe() { + return { + compare: function(actual, expected) { + return { + pass: actual === expected + }; + } + }; + } + + return toBe; +}; + +getJasmineRequireObj().toBeCloseTo = function() { + + function toBeCloseTo() { + return { + compare: function(actual, expected, precision) { + if (precision !== 0) { + precision = precision || 2; + } + + return { + pass: Math.abs(expected - actual) < (Math.pow(10, -precision) / 2) + }; + } + }; + } + + return toBeCloseTo; +}; + +getJasmineRequireObj().toBeDefined = function() { + function toBeDefined() { + return { + compare: function(actual) { + return { + pass: (void 0 !== actual) + }; + } + }; + } + + return toBeDefined; +}; + +getJasmineRequireObj().toBeFalsy = function() { + function toBeFalsy() { + return { + compare: function(actual) { + return { + pass: !!!actual + }; + } + }; + } + + return toBeFalsy; +}; + +getJasmineRequireObj().toBeGreaterThan = function() { + + function toBeGreaterThan() { + return { + compare: function(actual, expected) { + return { + pass: actual > expected + }; + } + }; + } + + return toBeGreaterThan; +}; + + +getJasmineRequireObj().toBeLessThan = function() { + function toBeLessThan() { + return { + + compare: function(actual, expected) { + return { + pass: actual < expected + }; + } + }; + } + + return toBeLessThan; +}; +getJasmineRequireObj().toBeNaN = function(j$) { + + function toBeNaN() { + return { + compare: function(actual) { + var result = { + pass: (actual !== actual) + }; + + if (result.pass) { + result.message = 'Expected actual not to be NaN.'; + } else { + result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be NaN.'; }; + } + + return result; + } + }; + } + + return toBeNaN; +}; + +getJasmineRequireObj().toBeNull = function() { + + function toBeNull() { + return { + compare: function(actual) { + return { + pass: actual === null + }; + } + }; + } + + return toBeNull; +}; + +getJasmineRequireObj().toBeTruthy = function() { + + function toBeTruthy() { + return { + compare: function(actual) { + return { + pass: !!actual + }; + } + }; + } + + return toBeTruthy; +}; + +getJasmineRequireObj().toBeUndefined = function() { + + function toBeUndefined() { + return { + compare: function(actual) { + return { + pass: void 0 === actual + }; + } + }; + } + + return toBeUndefined; +}; + +getJasmineRequireObj().toContain = function() { + function toContain(util, customEqualityTesters) { + customEqualityTesters = customEqualityTesters || []; + + return { + compare: function(actual, expected) { + + return { + pass: util.contains(actual, expected, customEqualityTesters) + }; + } + }; + } + + return toContain; +}; + +getJasmineRequireObj().toEqual = function() { + + function toEqual(util, customEqualityTesters) { + customEqualityTesters = customEqualityTesters || []; + + return { + compare: function(actual, expected) { + var result = { + pass: false + }; + + result.pass = util.equals(actual, expected, customEqualityTesters); + + return result; + } + }; + } + + return toEqual; +}; + +getJasmineRequireObj().toHaveBeenCalled = function(j$) { + + function toHaveBeenCalled() { + return { + compare: function(actual) { + var result = {}; + + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + if (arguments.length > 1) { + throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); + } + + result.pass = actual.calls.any(); + + result.message = result.pass ? + 'Expected spy ' + actual.and.identity() + ' not to have been called.' : + 'Expected spy ' + actual.and.identity() + ' to have been called.'; + + return result; + } + }; + } + + return toHaveBeenCalled; +}; + +getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) { + + function toHaveBeenCalledTimes() { + return { + compare: function(actual, expected) { + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + var args = Array.prototype.slice.call(arguments, 0), + result = { pass: false }; + + if(!expected){ + throw new Error('Expected times failed is required as an argument.'); + } + + actual = args[0]; + var calls = actual.calls.count(); + var timesMessage = expected === 1 ? 'once' : expected + ' times'; + result.pass = calls === expected; + result.message = result.pass ? + 'Expected spy ' + actual.and.identity() + ' not to have been called ' + timesMessage + '. It was called ' + calls + ' times.' : + 'Expected spy ' + actual.and.identity() + ' to have been called ' + timesMessage + '. It was called ' + calls + ' times.'; + return result; + } + }; + } + + return toHaveBeenCalledTimes; +}; + +getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { + + function toHaveBeenCalledWith(util, customEqualityTesters) { + return { + compare: function() { + var args = Array.prototype.slice.call(arguments, 0), + actual = args[0], + expectedArgs = args.slice(1), + result = { pass: false }; + + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + if (!actual.calls.any()) { + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but it was never called.'; }; + return result; + } + + if (util.contains(actual.calls.allArgs(), expectedArgs, customEqualityTesters)) { + result.pass = true; + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' not to have been called with ' + j$.pp(expectedArgs) + ' but it was.'; }; + } else { + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but actual calls were ' + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + '.'; }; + } + + return result; + } + }; + } + + return toHaveBeenCalledWith; +}; + +getJasmineRequireObj().toMatch = function(j$) { + + function toMatch() { + return { + compare: function(actual, expected) { + if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { + throw new Error('Expected is not a String or a RegExp'); + } + + var regexp = new RegExp(expected); + + return { + pass: regexp.test(actual) + }; + } + }; + } + + return toMatch; +}; + +getJasmineRequireObj().toThrow = function(j$) { + + function toThrow(util) { + return { + compare: function(actual, expected) { + var result = { pass: false }, + threw = false, + thrown; + + if (typeof actual != 'function') { + throw new Error('Actual is not a Function'); + } + + try { + actual(); + } catch (e) { + threw = true; + thrown = e; + } + + if (!threw) { + result.message = 'Expected function to throw an exception.'; + return result; + } + + if (arguments.length == 1) { + result.pass = true; + result.message = function() { return 'Expected function not to throw, but it threw ' + j$.pp(thrown) + '.'; }; + + return result; + } + + if (util.equals(thrown, expected)) { + result.pass = true; + result.message = function() { return 'Expected function not to throw ' + j$.pp(expected) + '.'; }; + } else { + result.message = function() { return 'Expected function to throw ' + j$.pp(expected) + ', but it threw ' + j$.pp(thrown) + '.'; }; + } + + return result; + } + }; + } + + return toThrow; +}; + +getJasmineRequireObj().toThrowError = function(j$) { + function toThrowError () { + return { + compare: function(actual) { + var threw = false, + pass = {pass: true}, + fail = {pass: false}, + thrown; + + if (typeof actual != 'function') { + throw new Error('Actual is not a Function'); + } + + var errorMatcher = getMatcher.apply(null, arguments); + + try { + actual(); + } catch (e) { + threw = true; + thrown = e; + } + + if (!threw) { + fail.message = 'Expected function to throw an Error.'; + return fail; + } + + if (!(thrown instanceof Error)) { + fail.message = function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; }; + return fail; + } + + if (errorMatcher.hasNoSpecifics()) { + pass.message = 'Expected function not to throw an Error, but it threw ' + j$.fnNameFor(thrown) + '.'; + return pass; + } + + if (errorMatcher.matches(thrown)) { + pass.message = function() { + return 'Expected function not to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + '.'; + }; + return pass; + } else { + fail.message = function() { + return 'Expected function to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + + ', but it threw ' + errorMatcher.thrownDescription(thrown) + '.'; + }; + return fail; + } + } + }; + + function getMatcher() { + var expected = null, + errorType = null; + + if (arguments.length == 2) { + expected = arguments[1]; + if (isAnErrorType(expected)) { + errorType = expected; + expected = null; + } + } else if (arguments.length > 2) { + errorType = arguments[1]; + expected = arguments[2]; + if (!isAnErrorType(errorType)) { + throw new Error('Expected error type is not an Error.'); + } + } + + if (expected && !isStringOrRegExp(expected)) { + if (errorType) { + throw new Error('Expected error message is not a string or RegExp.'); + } else { + throw new Error('Expected is not an Error, string, or RegExp.'); + } + } + + function messageMatch(message) { + if (typeof expected == 'string') { + return expected == message; + } else { + return expected.test(message); + } + } + + return { + errorTypeDescription: errorType ? j$.fnNameFor(errorType) : 'an exception', + thrownDescription: function(thrown) { + var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception', + thrownMessage = ''; + + if (expected) { + thrownMessage = ' with message ' + j$.pp(thrown.message); + } + + return thrownName + thrownMessage; + }, + messageDescription: function() { + if (expected === null) { + return ''; + } else if (expected instanceof RegExp) { + return ' with a message matching ' + j$.pp(expected); + } else { + return ' with message ' + j$.pp(expected); + } + }, + hasNoSpecifics: function() { + return expected === null && errorType === null; + }, + matches: function(error) { + return (errorType === null || error instanceof errorType) && + (expected === null || messageMatch(error.message)); + } + }; + } + + function isStringOrRegExp(potential) { + return potential instanceof RegExp || (typeof potential == 'string'); + } + + function isAnErrorType(type) { + if (typeof type !== 'function') { + return false; + } + + var Surrogate = function() {}; + Surrogate.prototype = type.prototype; + return (new Surrogate()) instanceof Error; + } + } + + return toThrowError; +}; + +getJasmineRequireObj().interface = function(jasmine, env) { + var jasmineInterface = { + describe: function(description, specDefinitions) { + return env.describe(description, specDefinitions); + }, + + xdescribe: function(description, specDefinitions) { + return env.xdescribe(description, specDefinitions); + }, + + fdescribe: function(description, specDefinitions) { + return env.fdescribe(description, specDefinitions); + }, + + it: function() { + return env.it.apply(env, arguments); + }, + + xit: function() { + return env.xit.apply(env, arguments); + }, + + fit: function() { + return env.fit.apply(env, arguments); + }, + + beforeEach: function() { + return env.beforeEach.apply(env, arguments); + }, + + afterEach: function() { + return env.afterEach.apply(env, arguments); + }, + + beforeAll: function() { + return env.beforeAll.apply(env, arguments); + }, + + afterAll: function() { + return env.afterAll.apply(env, arguments); + }, + + expect: function(actual) { + return env.expect(actual); + }, + + pending: function() { + return env.pending.apply(env, arguments); + }, + + fail: function() { + return env.fail.apply(env, arguments); + }, + + spyOn: function(obj, methodName) { + return env.spyOn(obj, methodName); + }, + + jsApiReporter: new jasmine.JsApiReporter({ + timer: new jasmine.Timer() + }), + + jasmine: jasmine + }; + + jasmine.addCustomEqualityTester = function(tester) { + env.addCustomEqualityTester(tester); + }; + + jasmine.addMatchers = function(matchers) { + return env.addMatchers(matchers); + }; + + jasmine.clock = function() { + return env.clock; + }; + + return jasmineInterface; +}; + +getJasmineRequireObj().version = function() { + return '2.4.1'; +}; diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/json2.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/json2.js new file mode 100644 index 0000000..deb88ec --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/json2.js @@ -0,0 +1,489 @@ +/* + json2.js + 2014-02-04 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function () { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function () { + return this.valueOf(); + }; + } + + var cx, + escapable, + gap, + indent, + meta, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }; + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); diff --git a/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/node_boot.js b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/node_boot.js new file mode 100644 index 0000000..a0fc4a2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/lib/jasmine-core/node_boot.js @@ -0,0 +1,41 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +module.exports = function(jasmineRequire) { + var jasmine = jasmineRequire.core(jasmineRequire); + + var consoleFns = require('../console/console.js'); + consoleFns.console(consoleFns, jasmine); + + var env = jasmine.getEnv(); + + var jasmineInterface = jasmineRequire.interface(jasmine, env); + + extend(global, jasmineInterface); + + function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; + } + + return jasmine; +}; diff --git a/platforms/android/assets/www/node_modules/jasmine-core/package.json b/platforms/android/assets/www/node_modules/jasmine-core/package.json new file mode 100644 index 0000000..5ca02ee --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/package.json @@ -0,0 +1,90 @@ +{ + "_args": [ + [ + "jasmine-core@~2.4.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine" + ] + ], + "_from": "jasmine-core@>=2.4.0 <2.5.0", + "_id": "jasmine-core@2.4.1", + "_inCache": true, + "_installable": true, + "_location": "/jasmine-core", + "_nodeVersion": "0.12.7", + "_npmUser": { + "email": "gregg@slackersoft.net", + "name": "slackersoft" + }, + "_npmVersion": "2.12.1", + "_phantomChildren": {}, + "_requested": { + "name": "jasmine-core", + "raw": "jasmine-core@~2.4.0", + "rawSpec": "~2.4.0", + "scope": null, + "spec": ">=2.4.0 <2.5.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine" + ], + "_resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.4.1.tgz", + "_shasum": "6f83ab3a0f16951722ce07d206c773d57cc838be", + "_shrinkwrap": null, + "_spec": "jasmine-core@~2.4.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine", + "bugs": { + "url": "https://github.com/jasmine/jasmine/issues" + }, + "dependencies": {}, + "description": "Official packaging of Jasmine's core files for use by Node.js projects.", + "devDependencies": { + "glob": "~5.0.13", + "grunt": "~0.4.1", + "grunt-cli": "^0.1.13", + "grunt-contrib-compass": "~0.6.0", + "grunt-contrib-compress": "~0.5.2", + "grunt-contrib-concat": "~0.3.0", + "grunt-contrib-jshint": "~0.7.0", + "jasmine": "git://github.com/jasmine/jasmine-npm.git", + "load-grunt-tasks": "^0.4.0", + "shelljs": "~0.1.4", + "temp": "~0.8.1" + }, + "directories": {}, + "dist": { + "shasum": "6f83ab3a0f16951722ce07d206c773d57cc838be", + "tarball": "http://registry.npmjs.org/jasmine-core/-/jasmine-core-2.4.1.tgz" + }, + "gitHead": "a95c2cfe3f80921ec6bc061d5fcc0b2368586666", + "homepage": "http://jasmine.github.io", + "keywords": [ + "test", + "jasmine", + "tdd", + "bdd" + ], + "license": "MIT", + "main": "./lib/jasmine-core.js", + "maintainers": [ + { + "email": "dwfrank@pivotallabs.com", + "name": "dwfrank" + }, + { + "email": "gregg@slackersoft.net", + "name": "slackersoft" + } + ], + "name": "jasmine-core", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jasmine/jasmine.git" + }, + "scripts": { + "test": "grunt jshint execSpecsInNode" + }, + "version": "2.4.1" +} diff --git a/platforms/android/assets/www/node_modules/jasmine-core/requirements.txt b/platforms/android/assets/www/node_modules/jasmine-core/requirements.txt new file mode 100644 index 0000000..591279c --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine-core/requirements.txt @@ -0,0 +1 @@ +ordereddict==1.1 diff --git a/platforms/android/assets/www/node_modules/jasmine/.travis.yml b/platforms/android/assets/www/node_modules/jasmine/.travis.yml new file mode 100644 index 0000000..ba260f3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/.travis.yml @@ -0,0 +1,5 @@ +--- +language: node_js +sudo: false +before_script: + - npm install git+https://github.com/jasmine/jasmine.git diff --git a/platforms/android/assets/www/node_modules/jasmine/Gruntfile.js b/platforms/android/assets/www/node_modules/jasmine/Gruntfile.js new file mode 100644 index 0000000..f5af99e --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/Gruntfile.js @@ -0,0 +1,44 @@ +module.exports = function(grunt) { + var pkg = require("./package.json"); + global.jasmineVersion = pkg.version; + var versionString = 'v' + pkg.version; + + grunt.initConfig({ + pkg: pkg, + jshint: {all: ['lib/**/*.js', 'spec/**/*.js']} + }); + + var shell = require('shelljs'); + function runCommands(commands, done) { + var command = commands.shift(); + + if (command) { + shell.exec(command, function(exitCode) { + if (exitCode !== 0) { + grunt.fail.fatal("Command `" + command + "` failed", exitCode); + done(); + } else { + runCommands(commands, done); + } + }); + } else { + done(); + } + } + + // depend on jshint:all, specs? + grunt.registerTask('release', + 'Create tag ' + versionString + ' and push jasmine-' + pkg.version + ' to NPM', + function() { + var done = this.async(), + commands = ['git tag ' + versionString, 'git push origin master --tags', 'npm publish']; + + runCommands(commands, done); + }); + + grunt.loadNpmTasks('grunt-contrib-jshint'); + + grunt.loadTasks('tasks'); + + grunt.registerTask('default', ['jshint:all', 'specs']); +}; diff --git a/platforms/android/assets/www/node_modules/jasmine/README.md b/platforms/android/assets/www/node_modules/jasmine/README.md new file mode 100644 index 0000000..26a517a --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/README.md @@ -0,0 +1,48 @@ +[![Build Status](https://travis-ci.org/jasmine/jasmine-npm.png?branch=master)](https://travis-ci.org/jasmine/jasmine-npm) + +# The Jasmine Module + +The [Jasmine](https://github.com/jasmine/jasmine) module is a package of helper code for developing Jasmine projects for Node.js. + +## Contents + +This module allows you to run Jasmine specs for your Node.js code. The output will be displayed in your terminal. + +## Installation + +`npm install -g jasmine` + +## Initializing + +To initialize a project for Jasmine + +`jasmine init` + +To seed your project with some examples + +`jasmine examples` + +## Usage + +To run your test suite + +`jasmine` + +## Configuration + +Customize `spec/support/jasmine.json` to enumerate the source and spec files you would like the Jasmine runner to include. +You may use dir glob strings. +More information on the format of `jasmine.json` can be found in [the documentation](http://jasmine.github.io/2.3/node.html#section-Configuration) + +Alternatively, you may specify the path to your `jasmine.json` by setting an environment variable: + +`jasmine JASMINE_CONFIG_PATH=relative/path/to/your/jasmine.json` + +## Support + +Jasmine Mailing list: [jasmine-js@googlegroups.com](mailto:jasmine-js@googlegroups.com) +Twitter: [@jasminebdd](http://twitter.com/jasminebdd) + +Please file issues here at Github + +Copyright (c) 2008-2013 Pivotal Labs. This software is licensed under the MIT License. diff --git a/platforms/android/assets/www/node_modules/jasmine/bin/jasmine.js b/platforms/android/assets/www/node_modules/jasmine/bin/jasmine.js new file mode 100755 index 0000000..5b514ea --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/bin/jasmine.js @@ -0,0 +1,11 @@ +#!/usr/bin/env node + +var path = require('path'), + Command = require('../lib/command.js'), + Jasmine = require('../lib/jasmine.js'); + +var jasmine = new Jasmine({ projectBaseDir: path.resolve() }); +var examplesDir = path.join(__dirname, '..', 'node_modules', 'jasmine-core', 'lib', 'jasmine-core', 'example', 'node_example'); +var command = new Command(path.resolve(), examplesDir, console.log); + +command.run(jasmine, process.argv.slice(2)); \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/jasmine/lib/command.js b/platforms/android/assets/www/node_modules/jasmine/lib/command.js new file mode 100644 index 0000000..700a2f9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/lib/command.js @@ -0,0 +1,220 @@ +var path = require('path'), + fs = require('fs'); + +exports = module.exports = Command; + +var subCommands = { + init: { + description: 'initialize jasmine', + action: initJasmine + }, + examples: { + description: 'install examples', + action: installExamples + }, + help: { + description: 'show help', + action: help, + alias: '-h' + }, + version: { + description: 'show jasmine and jasmine-core versions', + action: version, + alias: '-v' + } +}; + +function Command(projectBaseDir, examplesDir, print) { + this.projectBaseDir = projectBaseDir; + this.specDir = path.join(projectBaseDir, 'spec'); + + var command = this; + + this.run = function(jasmine, commands) { + setEnvironmentVariables(commands); + + var commandToRun; + Object.keys(subCommands).forEach(function(cmd) { + var commandObject = subCommands[cmd]; + if (commands.indexOf(cmd) >= 0) { + commandToRun = commandObject; + } else if(commandObject.alias && commands.indexOf(commandObject.alias) >= 0) { + commandToRun = commandObject; + } + }); + + if (commandToRun) { + commandToRun.action({projectBaseDir: command.projectBaseDir, specDir: command.specDir, examplesDir: examplesDir, print: print}); + } else { + runJasmine(jasmine, parseOptions(commands)); + } + }; +} + +function isFileArg(arg) { + return arg.indexOf('--') !== 0 && !isEnvironmentVariable(arg); +} + +function parseOptions(argv) { + var files = [], + color = process.stdout.isTTY || false, + filter, + stopOnFailure, + random = false, + seed; + + argv.forEach(function(arg) { + if (arg === '--no-color') { + color = false; + } else if (arg.match("^--filter=")) { + filter = arg.match("^--filter=(.*)")[1]; + } else if (arg.match("^--stop-on-failure=")) { + stopOnFailure = arg.match("^--stop-on-failure=(.*)")[1] === 'true'; + } else if (arg.match("^--random=")) { + random = arg.match("^--random=(.*)")[1] === 'true'; + } else if (arg.match("^--seed=")) { + seed = arg.match("^--seed=(.*)")[1]; + } else if (isFileArg(arg)) { + files.push(arg); + } + }); + return { + color: color, + filter: filter, + stopOnFailure: stopOnFailure, + files: files, + random: random, + seed: seed + }; +} + +function runJasmine(jasmine, env) { + jasmine.loadConfigFile(process.env.JASMINE_CONFIG_PATH); + if (env.stopOnFailure !== undefined) { + jasmine.stopSpecOnExpectationFailure(env.stopOnFailure); + } + if (env.seed !== undefined) { + jasmine.seed(env.seed); + } + + jasmine.randomizeTests(env.random); + jasmine.showColors(env.color); + jasmine.execute(env.files, env.filter); +} + +function initJasmine(options) { + var print = options.print; + var specDir = options.specDir; + makeDirStructure(path.join(specDir, 'support/')); + if(!fs.existsSync(path.join(specDir, 'support/jasmine.json'))) { + fs.writeFileSync(path.join(specDir, 'support/jasmine.json'), fs.readFileSync(path.join(__dirname, '../lib/examples/jasmine.json'), 'utf-8')); + } + else { + print('spec/support/jasmine.json already exists in your project.'); + } +} + +function installExamples(options) { + var specDir = options.specDir; + var projectBaseDir = options.projectBaseDir; + var examplesDir = options.examplesDir; + + makeDirStructure(path.join(specDir, 'support')); + makeDirStructure(path.join(specDir, 'jasmine_examples')); + makeDirStructure(path.join(specDir, 'helpers', 'jasmine_examples')); + makeDirStructure(path.join(projectBaseDir, 'lib', 'jasmine_examples')); + + copyFiles( + path.join(examplesDir, 'spec', 'helpers', 'jasmine_examples'), + path.join(specDir, 'helpers', 'jasmine_examples'), + new RegExp(/[Hh]elper\.js/) + ); + + copyFiles( + path.join(examplesDir, 'lib', 'jasmine_examples'), + path.join(projectBaseDir, 'lib', 'jasmine_examples'), + new RegExp(/\.js/) + ); + + copyFiles( + path.join(examplesDir, 'spec', 'jasmine_examples'), + path.join(specDir, 'jasmine_examples'), + new RegExp(/[Ss]pec.js/) + ); +} + +function help(options) { + var print = options.print; + print('Usage: jasmine [command] [options] [files]'); + print(''); + print('Commands:'); + Object.keys(subCommands).forEach(function(cmd) { + var commandNameText = cmd; + if(subCommands[cmd].alias) { + commandNameText = commandNameText + ',' + subCommands[cmd].alias; + } + print('%s\t%s', lPad(commandNameText, 10), subCommands[cmd].description); + }); + print(''); + print('If no command is given, jasmine specs will be run'); + print(''); + print(''); + + print('Options:'); + print('%s\tturn off color in spec output', lPad('--no-color', 18)); + print('%s\tfilter specs to run only those that match the given string', lPad('--filter=', 18)); + print('%s\t[true|false] stop spec execution on expectation failure. This takes precedence over the stopSpecOnExpectationFailure option in jasmine.json', lPad('--stop-on-failure=', 18)); + print(''); + print('The path to your jasmine.json can be configured by setting the JASMINE_CONFIG_PATH environment variable'); +} + +function version(options) { + var print = options.print; + print('jasmine v' + require('../package.json').version); + print('jasmine-core v' + require('../node_modules/jasmine-core/package.json').version); +} + +function lPad(str, length) { + if (str.length >= length) { + return str; + } else { + return lPad(' ' + str, length); + } +} + +function copyFiles(srcDir, destDir, pattern) { + var srcDirFiles = fs.readdirSync(srcDir); + srcDirFiles.forEach(function(file) { + if (file.search(pattern) !== -1) { + fs.writeFileSync(path.join(destDir, file), fs.readFileSync(path.join(srcDir, file))); + } + }); +} + +function makeDirStructure(absolutePath) { + var splitPath = absolutePath.split(path.sep); + splitPath.forEach(function(dir, index) { + if(index > 1) { + var fullPath = path.join(splitPath.slice(0, index).join('/'), dir); + if (!fs.existsSync(fullPath)) { + fs.mkdirSync(fullPath); + } + } + }); +} + +function isEnvironmentVariable(command) { + var envRegExp = /(.*)=(.*)/; + return command.match(envRegExp); +} + +function setEnvironmentVariables(commands) { + commands.forEach(function (command) { + var regExpMatch = isEnvironmentVariable(command); + if(regExpMatch) { + var key = regExpMatch[1]; + var value = regExpMatch[2]; + process.env[key] = value; + } + }); +} diff --git a/platforms/android/assets/www/node_modules/jasmine/lib/examples/jasmine.json b/platforms/android/assets/www/node_modules/jasmine/lib/examples/jasmine.json new file mode 100644 index 0000000..3ea3166 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/lib/examples/jasmine.json @@ -0,0 +1,11 @@ +{ + "spec_dir": "spec", + "spec_files": [ + "**/*[sS]pec.js" + ], + "helpers": [ + "helpers/**/*.js" + ], + "stopSpecOnExpectationFailure": false, + "random": false +} diff --git a/platforms/android/assets/www/node_modules/jasmine/lib/exit.js b/platforms/android/assets/www/node_modules/jasmine/lib/exit.js new file mode 100644 index 0000000..d2a6de6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/lib/exit.js @@ -0,0 +1,17 @@ +module.exports = function(exitCode, platform, nodeVersion, exit, nodeExit) { + if(isWindows(platform) && olderThan12(nodeVersion)) { + nodeExit(exitCode); + } + else { + exit(exitCode); + } +}; + +function isWindows(platform) { + return /^win/.test(platform); +} + +function olderThan12(nodeVersion) { + var version = nodeVersion.split('.'); + return parseInt(version[0].substr(1), 10) <= 0 && parseInt(version[1], 10) < 12; +} \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/jasmine/lib/filters/console_spec_filter.js b/platforms/android/assets/www/node_modules/jasmine/lib/filters/console_spec_filter.js new file mode 100644 index 0000000..e3cf6bd --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/lib/filters/console_spec_filter.js @@ -0,0 +1,10 @@ +module.exports = exports = ConsoleSpecFilter; + +function ConsoleSpecFilter(options) { + var filterString = options && options.filterString && options.filterString.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + var filterPattern = new RegExp(filterString); + + this.matches = function(specName) { + return filterPattern.test(specName); + }; +} \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/jasmine/lib/jasmine.js b/platforms/android/assets/www/node_modules/jasmine/lib/jasmine.js new file mode 100644 index 0000000..67ffeb3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/lib/jasmine.js @@ -0,0 +1,170 @@ +var path = require('path'), + util = require('util'), + glob = require('glob'), + exit = require('./exit'), + ExitCodeReporter = require('./reporters/exit_code_reporter'), + ConsoleSpecFilter = require('./filters/console_spec_filter'); + +module.exports = Jasmine; +module.exports.ConsoleReporter = require('./reporters/console_reporter'); + +function Jasmine(options) { + options = options || {}; + var jasmineCore = options.jasmineCore || require('jasmine-core'); + this.jasmineCorePath = path.join(jasmineCore.files.path, 'jasmine.js'); + this.jasmine = jasmineCore.boot(jasmineCore); + this.projectBaseDir = options.projectBaseDir || path.resolve(); + this.printDeprecation = options.printDeprecation || require('./printDeprecation'); + this.specFiles = []; + this.helperFiles = []; + this.env = this.jasmine.getEnv(); + this.reportersCount = 0; + this.exitCodeReporter = new ExitCodeReporter(); + this.onCompleteCallbackAdded = false; + this.exit = exit; + this.showingColors = true; +} + +Jasmine.prototype.randomizeTests = function(value) { + this.env.randomizeTests(value); +}; + +Jasmine.prototype.seed = function(value) { + this.env.seed(value); +}; + +Jasmine.prototype.showColors = function(value) { + this.showingColors = value; +}; + +Jasmine.prototype.addSpecFile = function(filePath) { + this.specFiles.push(filePath); +}; + +Jasmine.prototype.addReporter = function(reporter) { + this.env.addReporter(reporter); + this.reportersCount++; +}; + +Jasmine.prototype.configureDefaultReporter = function(options) { + options.timer = options.timer || new this.jasmine.Timer(); + options.print = options.print || function() { + process.stdout.write(util.format.apply(this, arguments)); + }; + options.showColors = options.hasOwnProperty('showColors') ? options.showColors : true; + options.jasmineCorePath = options.jasmineCorePath || this.jasmineCorePath; + + if(options.onComplete) { + this.printDeprecation('Passing in an onComplete function to configureDefaultReporter is deprecated.'); + } + var consoleReporter = new module.exports.ConsoleReporter(options); + this.addReporter(consoleReporter); + this.defaultReporterAdded = true; +}; + +Jasmine.prototype.addMatchers = function(matchers) { + this.jasmine.Expectation.addMatchers(matchers); +}; + +Jasmine.prototype.loadSpecs = function() { + this.specFiles.forEach(function(file) { + require(file); + }); +}; + +Jasmine.prototype.loadHelpers = function() { + this.helperFiles.forEach(function(file) { + require(file); + }); +}; + +Jasmine.prototype.loadConfigFile = function(configFilePath) { + var absoluteConfigFilePath = path.resolve(this.projectBaseDir, configFilePath || 'spec/support/jasmine.json'); + var config = require(absoluteConfigFilePath); + this.loadConfig(config); +}; + +Jasmine.prototype.loadConfig = function(config) { + var jasmineRunner = this; + jasmineRunner.specDir = config.spec_dir; + + if(config.helpers) { + config.helpers.forEach(function(helperFile) { + var filePaths = glob.sync(path.join(jasmineRunner.projectBaseDir, jasmineRunner.specDir, helperFile)); + filePaths.forEach(function(filePath) { + if(jasmineRunner.helperFiles.indexOf(filePath) === -1) { + jasmineRunner.helperFiles.push(filePath); + } + }); + }); + } + + this.env.throwOnExpectationFailure(config.stopSpecOnExpectationFailure); + this.env.randomizeTests(config.random); + + if(config.spec_files) { + jasmineRunner.addSpecFiles(config.spec_files); + } +}; + +Jasmine.prototype.addSpecFiles = function(files) { + var jasmineRunner = this; + + files.forEach(function(specFile) { + var filePaths = glob.sync(path.join(jasmineRunner.projectBaseDir, jasmineRunner.specDir, specFile)); + filePaths.forEach(function(filePath) { + if(jasmineRunner.specFiles.indexOf(filePath) === -1) { + jasmineRunner.specFiles.push(filePath); + } + }); + }); +}; + +Jasmine.prototype.onComplete = function(onCompleteCallback) { + this.exitCodeReporter.onComplete(onCompleteCallback); + this.onCompleteCallbackAdded = true; +}; + +Jasmine.prototype.stopSpecOnExpectationFailure = function(value) { + this.env.throwOnExpectationFailure(value); +}; + +Jasmine.prototype.execute = function(files, filterString) { + this.loadHelpers(); + + if(this.reportersCount === 0) { + this.configureDefaultReporter({ showColors: this.showingColors }); + } + + if(filterString) { + var specFilter = new ConsoleSpecFilter({ + filterString: filterString + }); + this.env.specFilter = function(spec) { + return specFilter.matches(spec.getFullName()); + }; + } + + if (files && files.length > 0) { + this.specDir = ''; + this.specFiles = []; + this.addSpecFiles(files); + } + + this.loadSpecs(); + + if(!this.onCompleteCallbackAdded && this.defaultReporterAdded) { + var jasmineRunner = this; + this.exitCodeReporter.onComplete(function(passed) { + if(passed) { + jasmineRunner.exit(0, process.platform, process.version, process.exit, require('exit')); + } + else { + jasmineRunner.exit(1, process.platform, process.version, process.exit, require('exit')); + } + }); + } + + this.addReporter(this.exitCodeReporter); + this.env.execute(); +}; diff --git a/platforms/android/assets/www/node_modules/jasmine/lib/printDeprecation.js b/platforms/android/assets/www/node_modules/jasmine/lib/printDeprecation.js new file mode 100644 index 0000000..0755b2e --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/lib/printDeprecation.js @@ -0,0 +1,3 @@ +module.exports = function(message) { + console.warn('Deprecation warning: ' + message); +}; \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/jasmine/lib/reporters/console_reporter.js b/platforms/android/assets/www/node_modules/jasmine/lib/reporters/console_reporter.js new file mode 100644 index 0000000..f1ac0c6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/lib/reporters/console_reporter.js @@ -0,0 +1,208 @@ +module.exports = exports = ConsoleReporter; + +var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } +}; + +function ConsoleReporter(options) { + var print = options.print, + showColors = options.showColors || false, + timer = options.timer || noopTimer, + jasmineCorePath = options.jasmineCorePath, + printDeprecation = options.printDeprecation || require('../printDeprecation'), + specCount, + executableSpecCount, + failureCount, + failedSpecs = [], + pendingSpecs = [], + ansi = { + green: '\x1B[32m', + red: '\x1B[31m', + yellow: '\x1B[33m', + none: '\x1B[0m' + }, + failedSuites = [], + stackFilter = options.stackFilter || defaultStackFilter; + + if(options.onComplete) { + printDeprecation('Passing in an onComplete function to the ConsoleReporter is deprecated.'); + } + var onComplete = options.onComplete || function() {}; + + this.jasmineStarted = function() { + specCount = 0; + executableSpecCount = 0; + failureCount = 0; + print('Started'); + printNewline(); + timer.start(); + }; + + this.jasmineDone = function(result) { + printNewline(); + printNewline(); + if(failedSpecs.length > 0) { + print('Failures:'); + } + for (var i = 0; i < failedSpecs.length; i++) { + specFailureDetails(failedSpecs[i], i + 1); + } + + if (pendingSpecs.length > 0) { + print("Pending:"); + } + for(i = 0; i < pendingSpecs.length; i++) { + pendingSpecDetails(pendingSpecs[i], i + 1); + } + + if(specCount > 0) { + printNewline(); + + if(executableSpecCount !== specCount) { + print('Ran ' + executableSpecCount + ' of ' + specCount + plural(' spec', specCount)); + printNewline(); + } + var specCounts = executableSpecCount + ' ' + plural('spec', executableSpecCount) + ', ' + + failureCount + ' ' + plural('failure', failureCount); + + if (pendingSpecs.length) { + specCounts += ', ' + pendingSpecs.length + ' pending ' + plural('spec', pendingSpecs.length); + } + + print(specCounts); + } else { + print('No specs found'); + } + + printNewline(); + var seconds = timer.elapsed() / 1000; + print('Finished in ' + seconds + ' ' + plural('second', seconds)); + printNewline(); + + for(i = 0; i < failedSuites.length; i++) { + suiteFailureDetails(failedSuites[i]); + } + + if (result && result.order && result.order.random) { + print('Randomized with seed ' + result.order.seed); + printNewline(); + } + + onComplete(failureCount === 0); + }; + + this.specDone = function(result) { + specCount++; + + if (result.status == 'pending') { + pendingSpecs.push(result); + executableSpecCount++; + print(colored('yellow', '*')); + return; + } + + if (result.status == 'passed') { + executableSpecCount++; + print(colored('green', '.')); + return; + } + + if (result.status == 'failed') { + failureCount++; + failedSpecs.push(result); + executableSpecCount++; + print(colored('red', 'F')); + } + }; + + this.suiteDone = function(result) { + if (result.failedExpectations && result.failedExpectations.length > 0) { + failureCount++; + failedSuites.push(result); + } + }; + + return this; + + function printNewline() { + print('\n'); + } + + function colored(color, str) { + return showColors ? (ansi[color] + str + ansi.none) : str; + } + + function plural(str, count) { + return count == 1 ? str : str + 's'; + } + + function repeat(thing, times) { + var arr = []; + for (var i = 0; i < times; i++) { + arr.push(thing); + } + return arr; + } + + function indent(str, spaces) { + var lines = (str || '').split('\n'); + var newArr = []; + for (var i = 0; i < lines.length; i++) { + newArr.push(repeat(' ', spaces).join('') + lines[i]); + } + return newArr.join('\n'); + } + + function defaultStackFilter(stack) { + var filteredStack = stack.split('\n').filter(function(stackLine) { + return stackLine.indexOf(jasmineCorePath) === -1; + }).join('\n'); + return filteredStack; + } + + function specFailureDetails(result, failedSpecNumber) { + printNewline(); + print(failedSpecNumber + ') '); + print(result.fullName); + + for (var i = 0; i < result.failedExpectations.length; i++) { + var failedExpectation = result.failedExpectations[i]; + printNewline(); + print(indent('Message:', 2)); + printNewline(); + print(colored('red', indent(failedExpectation.message, 4))); + printNewline(); + print(indent('Stack:', 2)); + printNewline(); + print(indent(stackFilter(failedExpectation.stack), 4)); + } + + printNewline(); + } + + function suiteFailureDetails(result) { + for (var i = 0; i < result.failedExpectations.length; i++) { + printNewline(); + print(colored('red', 'An error was thrown in an afterAll')); + printNewline(); + print(colored('red', 'AfterAll ' + result.failedExpectations[i].message)); + + } + printNewline(); + } + + function pendingSpecDetails(result, pendingSpecNumber) { + printNewline(); + printNewline(); + print(pendingSpecNumber + ') '); + print(result.fullName); + printNewline(); + var pendingReason = "No reason given"; + if (result.pendingReason && result.pendingReason !== '') { + pendingReason = result.pendingReason; + } + print(indent(colored('yellow', pendingReason), 2)); + printNewline(); + } +} diff --git a/platforms/android/assets/www/node_modules/jasmine/lib/reporters/exit_code_reporter.js b/platforms/android/assets/www/node_modules/jasmine/lib/reporters/exit_code_reporter.js new file mode 100644 index 0000000..354a83e --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/lib/reporters/exit_code_reporter.js @@ -0,0 +1,24 @@ +module.exports = function() { + var results = true; + var onCompleteCallback = function() {}; + + this.onComplete = function(callback) { + onCompleteCallback = callback; + }; + + this.jasmineDone = function() { + onCompleteCallback(results); + }; + + this.specDone = function(result) { + if(result.status === 'failed') { + results = false; + } + }; + + this.suiteDone = function(result) { + if (result.failedExpectations && result.failedExpectations.length > 0) { + results = false; + } + }; +}; \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/.npmignore b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/.npmignore new file mode 100644 index 0000000..2af4b71 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/.npmignore @@ -0,0 +1,2 @@ +.*.swp +test/a/ diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/.travis.yml b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/.travis.yml new file mode 100644 index 0000000..baa0031 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - 0.8 diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/LICENSE b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/LICENSE new file mode 100644 index 0000000..0c44ae7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) Isaac Z. Schlueter ("Author") +All rights reserved. + +The BSD License + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/README.md b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/README.md new file mode 100644 index 0000000..cc69164 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/README.md @@ -0,0 +1,250 @@ +# Glob + +Match files using the patterns the shell uses, like stars and stuff. + +This is a glob implementation in JavaScript. It uses the `minimatch` +library to do its matching. + +## Attention: node-glob users! + +The API has changed dramatically between 2.x and 3.x. This library is +now 100% JavaScript, and the integer flags have been replaced with an +options object. + +Also, there's an event emitter class, proper tests, and all the other +things you've come to expect from node modules. + +And best of all, no compilation! + +## Usage + +```javascript +var glob = require("glob") + +// options is optional +glob("**/*.js", options, function (er, files) { + // files is an array of filenames. + // If the `nonull` option is set, and nothing + // was found, then files is ["**/*.js"] + // er is an error object or null. +}) +``` + +## Features + +Please see the [minimatch +documentation](https://github.com/isaacs/minimatch) for more details. + +Supports these glob features: + +* Brace Expansion +* Extended glob matching +* "Globstar" `**` matching + +See: + +* `man sh` +* `man bash` +* `man 3 fnmatch` +* `man 5 gitignore` +* [minimatch documentation](https://github.com/isaacs/minimatch) + +## glob(pattern, [options], cb) + +* `pattern` {String} Pattern to be matched +* `options` {Object} +* `cb` {Function} + * `err` {Error | null} + * `matches` {Array} filenames found matching the pattern + +Perform an asynchronous glob search. + +## glob.sync(pattern, [options]) + +* `pattern` {String} Pattern to be matched +* `options` {Object} +* return: {Array} filenames found matching the pattern + +Perform a synchronous glob search. + +## Class: glob.Glob + +Create a Glob object by instanting the `glob.Glob` class. + +```javascript +var Glob = require("glob").Glob +var mg = new Glob(pattern, options, cb) +``` + +It's an EventEmitter, and starts walking the filesystem to find matches +immediately. + +### new glob.Glob(pattern, [options], [cb]) + +* `pattern` {String} pattern to search for +* `options` {Object} +* `cb` {Function} Called when an error occurs, or matches are found + * `err` {Error | null} + * `matches` {Array} filenames found matching the pattern + +Note that if the `sync` flag is set in the options, then matches will +be immediately available on the `g.found` member. + +### Properties + +* `minimatch` The minimatch object that the glob uses. +* `options` The options object passed in. +* `error` The error encountered. When an error is encountered, the + glob object is in an undefined state, and should be discarded. +* `aborted` Boolean which is set to true when calling `abort()`. There + is no way at this time to continue a glob search after aborting, but + you can re-use the statCache to avoid having to duplicate syscalls. +* `statCache` Collection of all the stat results the glob search + performed. +* `cache` Convenience object. Each field has the following possible + values: + * `false` - Path does not exist + * `true` - Path exists + * `1` - Path exists, and is not a directory + * `2` - Path exists, and is a directory + * `[file, entries, ...]` - Path exists, is a directory, and the + array value is the results of `fs.readdir` + +### Events + +* `end` When the matching is finished, this is emitted with all the + matches found. If the `nonull` option is set, and no match was found, + then the `matches` list contains the original pattern. The matches + are sorted, unless the `nosort` flag is set. +* `match` Every time a match is found, this is emitted with the matched. +* `error` Emitted when an unexpected error is encountered, or whenever + any fs error occurs if `options.strict` is set. +* `abort` When `abort()` is called, this event is raised. + +### Methods + +* `abort` Stop the search. + +### Options + +All the options that can be passed to Minimatch can also be passed to +Glob to change pattern matching behavior. Also, some have been added, +or have glob-specific ramifications. + +All options are false by default, unless otherwise noted. + +All options are added to the glob object, as well. + +* `cwd` The current working directory in which to search. Defaults + to `process.cwd()`. +* `root` The place where patterns starting with `/` will be mounted + onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix + systems, and `C:\` or some such on Windows.) +* `dot` Include `.dot` files in normal matches and `globstar` matches. + Note that an explicit dot in a portion of the pattern will always + match dot files. +* `nomount` By default, a pattern starting with a forward-slash will be + "mounted" onto the root setting, so that a valid filesystem path is + returned. Set this flag to disable that behavior. +* `mark` Add a `/` character to directory matches. Note that this + requires additional stat calls. +* `nosort` Don't sort the results. +* `stat` Set to true to stat *all* results. This reduces performance + somewhat, and is completely unnecessary, unless `readdir` is presumed + to be an untrustworthy indicator of file existence. It will cause + ELOOP to be triggered one level sooner in the case of cyclical + symbolic links. +* `silent` When an unusual error is encountered + when attempting to read a directory, a warning will be printed to + stderr. Set the `silent` option to true to suppress these warnings. +* `strict` When an unusual error is encountered + when attempting to read a directory, the process will just continue on + in search of other matches. Set the `strict` option to raise an error + in these cases. +* `cache` See `cache` property above. Pass in a previously generated + cache object to save some fs calls. +* `statCache` A cache of results of filesystem information, to prevent + unnecessary stat calls. While it should not normally be necessary to + set this, you may pass the statCache from one glob() call to the + options object of another, if you know that the filesystem will not + change between calls. (See "Race Conditions" below.) +* `sync` Perform a synchronous glob search. +* `nounique` In some cases, brace-expanded patterns can result in the + same file showing up multiple times in the result set. By default, + this implementation prevents duplicates in the result set. + Set this flag to disable that behavior. +* `nonull` Set to never return an empty set, instead returning a set + containing the pattern itself. This is the default in glob(3). +* `nocase` Perform a case-insensitive match. Note that case-insensitive + filesystems will sometimes result in glob returning results that are + case-insensitively matched anyway, since readdir and stat will not + raise an error. +* `debug` Set to enable debug logging in minimatch and glob. +* `globDebug` Set to enable debug logging in glob, but not minimatch. + +## Comparisons to other fnmatch/glob implementations + +While strict compliance with the existing standards is a worthwhile +goal, some discrepancies exist between node-glob and other +implementations, and are intentional. + +If the pattern starts with a `!` character, then it is negated. Set the +`nonegate` flag to suppress this behavior, and treat leading `!` +characters normally. This is perhaps relevant if you wish to start the +pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` +characters at the start of a pattern will negate the pattern multiple +times. + +If a pattern starts with `#`, then it is treated as a comment, and +will not match anything. Use `\#` to match a literal `#` at the +start of a line, or set the `nocomment` flag to suppress this behavior. + +The double-star character `**` is supported by default, unless the +`noglobstar` flag is set. This is supported in the manner of bsdglob +and bash 4.1, where `**` only has special significance if it is the only +thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but +`a/**b` will not. + +If an escaped pattern has no matches, and the `nonull` flag is set, +then glob returns the pattern as-provided, rather than +interpreting the character escapes. For example, +`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than +`"*a?"`. This is akin to setting the `nullglob` option in bash, except +that it does not resolve escaped pattern characters. + +If brace expansion is not disabled, then it is performed before any +other interpretation of the glob pattern. Thus, a pattern like +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are +checked for validity. Since those two are valid, matching proceeds. + +## Windows + +**Please only use forward-slashes in glob expressions.** + +Though windows uses either `/` or `\` as its path separator, only `/` +characters are used by this glob implementation. You must use +forward-slashes **only** in glob expressions. Back-slashes will always +be interpreted as escape characters, not path separators. + +Results from absolute patterns such as `/foo/*` are mounted onto the +root setting using `path.join`. On windows, this will by default result +in `/foo/*` matching `C:\foo\bar.txt`. + +## Race Conditions + +Glob searching, by its very nature, is susceptible to race conditions, +since it relies on directory walking and such. + +As a result, it is possible that a file that exists when glob looks for +it may have been deleted or modified by the time it returns the result. + +As part of its internal implementation, this program caches all stat +and readdir calls that it makes, in order to cut down on system +overhead. However, this also makes it even more susceptible to races, +especially if the cache or statCache objects are reused between glob +calls. + +Users are thus advised not to use a glob result as a guarantee of +filesystem state in the face of rapid changes. For the vast majority +of operations, this is never a problem. diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/examples/g.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/examples/g.js new file mode 100644 index 0000000..be122df --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/examples/g.js @@ -0,0 +1,9 @@ +var Glob = require("../").Glob + +var pattern = "test/a/**/[cg]/../[cg]" +console.log(pattern) + +var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) { + console.log("matches", matches) +}) +console.log("after") diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/examples/usr-local.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/examples/usr-local.js new file mode 100644 index 0000000..327a425 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/examples/usr-local.js @@ -0,0 +1,9 @@ +var Glob = require("../").Glob + +var pattern = "{./*/*,/*,/usr/local/*}" +console.log(pattern) + +var mg = new Glob(pattern, {mark: true}, function (er, matches) { + console.log("matches", matches) +}) +console.log("after") diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/glob.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/glob.js new file mode 100644 index 0000000..f646c44 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/glob.js @@ -0,0 +1,728 @@ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// readdir(PREFIX) as ENTRIES +// If fails, END +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $]) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $]) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + + + +module.exports = glob + +var fs = require("fs") +, minimatch = require("minimatch") +, Minimatch = minimatch.Minimatch +, inherits = require("inherits") +, EE = require("events").EventEmitter +, path = require("path") +, isDir = {} +, assert = require("assert").ok + +function glob (pattern, options, cb) { + if (typeof options === "function") cb = options, options = {} + if (!options) options = {} + + if (typeof options === "number") { + deprecated() + return + } + + var g = new Glob(pattern, options, cb) + return g.sync ? g.found : g +} + +glob.fnmatch = deprecated + +function deprecated () { + throw new Error("glob's interface has changed. Please see the docs.") +} + +glob.sync = globSync +function globSync (pattern, options) { + if (typeof options === "number") { + deprecated() + return + } + + options = options || {} + options.sync = true + return glob(pattern, options) +} + +this._processingEmitQueue = false + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (!(this instanceof Glob)) { + return new Glob(pattern, options, cb) + } + + if (typeof options === "function") { + cb = options + options = null + } + + if (typeof cb === "function") { + this.on("error", cb) + this.on("end", function (matches) { + cb(null, matches) + }) + } + + options = options || {} + + this._endEmitted = false + this.EOF = {} + this._emitQueue = [] + + this.paused = false + this._processingEmitQueue = false + + this.maxDepth = options.maxDepth || 1000 + this.maxLength = options.maxLength || Infinity + this.cache = options.cache || {} + this.statCache = options.statCache || {} + + this.changedCwd = false + var cwd = process.cwd() + if (!options.hasOwnProperty("cwd")) this.cwd = cwd + else { + this.cwd = options.cwd + this.changedCwd = path.resolve(options.cwd) !== cwd + } + + this.root = options.root || path.resolve(this.cwd, "/") + this.root = path.resolve(this.root) + if (process.platform === "win32") + this.root = this.root.replace(/\\/g, "/") + + this.nomount = !!options.nomount + + if (!pattern) { + throw new Error("must provide pattern") + } + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + this.strict = options.strict !== false + this.dot = !!options.dot + this.mark = !!options.mark + this.sync = !!options.sync + this.nounique = !!options.nounique + this.nonull = !!options.nonull + this.nosort = !!options.nosort + this.nocase = !!options.nocase + this.stat = !!options.stat + + this.debug = !!options.debug || !!options.globDebug + if (this.debug) + this.log = console.error + + this.silent = !!options.silent + + var mm = this.minimatch = new Minimatch(pattern, options) + this.options = mm.options + pattern = this.pattern = mm.pattern + + this.error = null + this.aborted = false + + // list of all the patterns that ** has resolved do, so + // we can avoid visiting multiple times. + this._globstars = {} + + EE.call(this) + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + this.minimatch.set.forEach(iterator.bind(this)) + function iterator (pattern, i, set) { + this._process(pattern, 0, i, function (er) { + if (er) this.emit("error", er) + if (-- n <= 0) this._finish() + }) + } +} + +Glob.prototype.log = function () {} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + + var nou = this.nounique + , all = nou ? [] : {} + + for (var i = 0, l = this.matches.length; i < l; i ++) { + var matches = this.matches[i] + this.log("matches[%d] =", i, matches) + // do like the shell, and spit out the literal glob + if (!matches) { + if (this.nonull) { + var literal = this.minimatch.globSet[i] + if (nou) all.push(literal) + else all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) all.push.apply(all, m) + else m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) all = Object.keys(all) + + if (!this.nosort) { + all = all.sort(this.nocase ? alphasorti : alphasort) + } + + if (this.mark) { + // at *some* point we statted all of these + all = all.map(this._mark, this) + } + + this.log("emitting end", all) + + this.EOF = this.found = all + this.emitMatch(this.EOF) +} + +function alphasorti (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return alphasort(a, b) +} + +function alphasort (a, b) { + return a > b ? 1 : a < b ? -1 : 0 +} + +Glob.prototype._mark = function (p) { + var c = this.cache[p] + var m = p + if (c) { + var isDir = c === 2 || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + this.statCache[m] = this.statCache[p] + this.cache[m] = this.cache[p] + } + } + + return m +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit("abort") +} + +Glob.prototype.pause = function () { + if (this.paused) return + if (this.sync) + this.emit("error", new Error("Can't pause/resume sync glob")) + this.paused = true + this.emit("pause") +} + +Glob.prototype.resume = function () { + if (!this.paused) return + if (this.sync) + this.emit("error", new Error("Can't pause/resume sync glob")) + this.paused = false + this.emit("resume") + this._processEmitQueue() + //process.nextTick(this.emit.bind(this, "resume")) +} + +Glob.prototype.emitMatch = function (m) { + this.log('emitMatch', m) + this._emitQueue.push(m) + this._processEmitQueue() +} + +Glob.prototype._processEmitQueue = function (m) { + this.log("pEQ paused=%j processing=%j m=%j", this.paused, + this._processingEmitQueue, m) + var done = false + while (!this._processingEmitQueue && + !this.paused) { + this._processingEmitQueue = true + var m = this._emitQueue.shift() + this.log(">processEmitQueue", m === this.EOF ? ":EOF:" : m) + if (!m) { + this.log(">processEmitQueue, falsey m") + this._processingEmitQueue = false + break + } + + if (m === this.EOF || !(this.mark && !this.stat)) { + this.log("peq: unmarked, or eof") + next.call(this, 0, false) + } else if (this.statCache[m]) { + var sc = this.statCache[m] + var exists + if (sc) + exists = sc.isDirectory() ? 2 : 1 + this.log("peq: stat cached") + next.call(this, exists, exists === 2) + } else { + this.log("peq: _stat, then next") + this._stat(m, next) + } + + function next(exists, isDir) { + this.log("next", m, exists, isDir) + var ev = m === this.EOF ? "end" : "match" + + // "end" can only happen once. + assert(!this._endEmitted) + if (ev === "end") + this._endEmitted = true + + if (exists) { + // Doesn't mean it necessarily doesn't exist, it's possible + // we just didn't check because we don't care that much, or + // this is EOF anyway. + if (isDir && !m.match(/\/$/)) { + m = m + "/" + } else if (!isDir && m.match(/\/$/)) { + m = m.replace(/\/+$/, "") + } + } + this.log("emit", ev, m) + this.emit(ev, m) + this._processingEmitQueue = false + if (done && m !== this.EOF && !this.paused) + this._processEmitQueue() + } + } + done = true +} + +Glob.prototype._process = function (pattern, depth, index, cb_) { + assert(this instanceof Glob) + + var cb = function cb (er, res) { + assert(this instanceof Glob) + if (this.paused) { + if (!this._processQueue) { + this._processQueue = [] + this.once("resume", function () { + var q = this._processQueue + this._processQueue = null + q.forEach(function (cb) { cb() }) + }) + } + this._processQueue.push(cb_.bind(this, er, res)) + } else { + cb_.call(this, er, res) + } + }.bind(this) + + if (this.aborted) return cb() + + if (depth > this.maxDepth) return cb() + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === "string") { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + prefix = pattern.join("/") + this._stat(prefix, function (exists, isDir) { + // either it's there, or it isn't. + // nothing more to do, either way. + if (exists) { + if (prefix && isAbsolute(prefix) && !this.nomount) { + if (prefix.charAt(0) === "/") { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + } + } + + if (process.platform === "win32") + prefix = prefix.replace(/\\/g, "/") + + this.matches[index] = this.matches[index] || {} + this.matches[index][prefix] = true + this.emitMatch(prefix) + } + return cb() + }) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's "absolute" like /foo/bar, + // or "relative" like "../baz" + prefix = pattern.slice(0, n) + prefix = prefix.join("/") + break + } + + // get the list of entries. + var read + if (prefix === null) read = "." + else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) { + if (!prefix || !isAbsolute(prefix)) { + prefix = path.join("/", prefix) + } + read = prefix = path.resolve(prefix) + + // if (process.platform === "win32") + // read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/") + + this.log('absolute: ', prefix, this.root, pattern, read) + } else { + read = prefix + } + + this.log('readdir(%j)', read, this.cwd, this.root) + + return this._readdir(read, function (er, entries) { + if (er) { + // not a directory! + // this means that, whatever else comes after this, it can never match + return cb() + } + + // globstar is special + if (pattern[n] === minimatch.GLOBSTAR) { + // test without the globstar, and with every child both below + // and replacing the globstar. + var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ] + entries.forEach(function (e) { + if (e.charAt(0) === "." && !this.dot) return + // instead of the globstar + s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))) + // below the globstar + s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n))) + }, this) + + s = s.filter(function (pattern) { + var key = gsKey(pattern) + var seen = !this._globstars[key] + this._globstars[key] = true + return seen + }, this) + + if (!s.length) + return cb() + + // now asyncForEach over this + var l = s.length + , errState = null + s.forEach(function (gsPattern) { + this._process(gsPattern, depth + 1, index, function (er) { + if (errState) return + if (er) return cb(errState = er) + if (--l <= 0) return cb() + }) + }, this) + + return + } + + // not a globstar + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = pattern[n] + var rawGlob = pattern[n]._glob + , dotOk = this.dot || rawGlob.charAt(0) === "." + + entries = entries.filter(function (e) { + return (e.charAt(0) !== "." || dotOk) && + e.match(pattern[n]) + }) + + // If n === pattern.length - 1, then there's no need for the extra stat + // *unless* the user has specified "mark" or "stat" explicitly. + // We know that they exist, since the readdir returned them. + if (n === pattern.length - 1 && + !this.mark && + !this.stat) { + entries.forEach(function (e) { + if (prefix) { + if (prefix !== "/") e = prefix + "/" + e + else e = prefix + e + } + if (e.charAt(0) === "/" && !this.nomount) { + e = path.join(this.root, e) + } + + if (process.platform === "win32") + e = e.replace(/\\/g, "/") + + this.matches[index] = this.matches[index] || {} + this.matches[index][e] = true + this.emitMatch(e) + }, this) + return cb.call(this) + } + + + // now test all the remaining entries as stand-ins for that part + // of the pattern. + var l = entries.length + , errState = null + if (l === 0) return cb() // no matches possible + entries.forEach(function (e) { + var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)) + this._process(p, depth + 1, index, function (er) { + if (errState) return + if (er) return cb(errState = er) + if (--l === 0) return cb.call(this) + }) + }, this) + }) + +} + +function gsKey (pattern) { + return '**' + pattern.map(function (p) { + return (p === minimatch.GLOBSTAR) ? '**' : (''+p) + }).join('/') +} + +Glob.prototype._stat = function (f, cb) { + assert(this instanceof Glob) + var abs = f + if (f.charAt(0) === "/") { + abs = path.join(this.root, f) + } else if (this.changedCwd) { + abs = path.resolve(this.cwd, f) + } + + if (f.length > this.maxLength) { + var er = new Error("Path name too long") + er.code = "ENAMETOOLONG" + er.path = f + return this._afterStat(f, abs, cb, er) + } + + this.log('stat', [this.cwd, f, '=', abs]) + + if (!this.stat && this.cache.hasOwnProperty(f)) { + var exists = this.cache[f] + , isDir = exists && (Array.isArray(exists) || exists === 2) + if (this.sync) return cb.call(this, !!exists, isDir) + return process.nextTick(cb.bind(this, !!exists, isDir)) + } + + var stat = this.statCache[abs] + if (this.sync || stat) { + var er + try { + stat = fs.statSync(abs) + } catch (e) { + er = e + } + this._afterStat(f, abs, cb, er, stat) + } else { + fs.stat(abs, this._afterStat.bind(this, f, abs, cb)) + } +} + +Glob.prototype._afterStat = function (f, abs, cb, er, stat) { + var exists + assert(this instanceof Glob) + + if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) { + this.log("should be ENOTDIR, fake it") + + er = new Error("ENOTDIR, not a directory '" + abs + "'") + er.path = abs + er.code = "ENOTDIR" + stat = null + } + + var emit = !this.statCache[abs] + this.statCache[abs] = stat + + if (er || !stat) { + exists = false + } else { + exists = stat.isDirectory() ? 2 : 1 + if (emit) + this.emit('stat', f, stat) + } + this.cache[f] = this.cache[f] || exists + cb.call(this, !!exists, exists === 2) +} + +Glob.prototype._readdir = function (f, cb) { + assert(this instanceof Glob) + var abs = f + if (f.charAt(0) === "/") { + abs = path.join(this.root, f) + } else if (isAbsolute(f)) { + abs = f + } else if (this.changedCwd) { + abs = path.resolve(this.cwd, f) + } + + if (f.length > this.maxLength) { + var er = new Error("Path name too long") + er.code = "ENAMETOOLONG" + er.path = f + return this._afterReaddir(f, abs, cb, er) + } + + this.log('readdir', [this.cwd, f, abs]) + if (this.cache.hasOwnProperty(f)) { + var c = this.cache[f] + if (Array.isArray(c)) { + if (this.sync) return cb.call(this, null, c) + return process.nextTick(cb.bind(this, null, c)) + } + + if (!c || c === 1) { + // either ENOENT or ENOTDIR + var code = c ? "ENOTDIR" : "ENOENT" + , er = new Error((c ? "Not a directory" : "Not found") + ": " + f) + er.path = f + er.code = code + this.log(f, er) + if (this.sync) return cb.call(this, er) + return process.nextTick(cb.bind(this, er)) + } + + // at this point, c === 2, meaning it's a dir, but we haven't + // had to read it yet, or c === true, meaning it's *something* + // but we don't have any idea what. Need to read it, either way. + } + + if (this.sync) { + var er, entries + try { + entries = fs.readdirSync(abs) + } catch (e) { + er = e + } + return this._afterReaddir(f, abs, cb, er, entries) + } + + fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb)) +} + +Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) { + assert(this instanceof Glob) + if (entries && !er) { + this.cache[f] = entries + // if we haven't asked to stat everything for suresies, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. This also gets us one step + // further into ELOOP territory. + if (!this.mark && !this.stat) { + entries.forEach(function (e) { + if (f === "/") e = f + e + else e = f + "/" + e + this.cache[e] = true + }, this) + } + + return cb.call(this, er, entries) + } + + // now handle errors, and cache the information + if (er) switch (er.code) { + case "ENOTDIR": // totally normal. means it *does* exist. + this.cache[f] = 1 + return cb.call(this, er) + case "ENOENT": // not terribly unusual + case "ELOOP": + case "ENAMETOOLONG": + case "UNKNOWN": + this.cache[f] = false + return cb.call(this, er) + default: // some unusual error. Treat as failure. + this.cache[f] = false + if (this.strict) this.emit("error", er) + if (!this.silent) console.error("glob error", er) + return cb.call(this, er) + } +} + +var isAbsolute = process.platform === "win32" ? absWin : absUnix + +function absWin (p) { + if (absUnix(p)) return true + // pull off the device/UNC bit from a windows path. + // from node's lib/path.js + var splitDeviceRe = + /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/ + , result = splitDeviceRe.exec(p) + , device = result[1] || '' + , isUnc = device && device.charAt(1) !== ':' + , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute + + return isAbsolute +} + +function absUnix (p) { + return p.charAt(0) === "/" || p === "" +} diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/package.json b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/package.json new file mode 100644 index 0000000..93bb56a --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/package.json @@ -0,0 +1,83 @@ +{ + "_args": [ + [ + "glob@^3.2.11", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine" + ] + ], + "_from": "glob@>=3.2.11 <4.0.0", + "_id": "glob@3.2.11", + "_inCache": true, + "_installable": true, + "_location": "/jasmine/glob", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "1.4.10", + "_phantomChildren": {}, + "_requested": { + "name": "glob", + "raw": "glob@^3.2.11", + "rawSpec": "^3.2.11", + "scope": null, + "spec": ">=3.2.11 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine" + ], + "_resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "_shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", + "_shrinkwrap": null, + "_spec": "glob@^3.2.11", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/node-glob/issues" + }, + "dependencies": { + "inherits": "2", + "minimatch": "0.3" + }, + "description": "a little globber", + "devDependencies": { + "mkdirp": "0", + "rimraf": "1", + "tap": "~0.4.0" + }, + "directories": {}, + "dist": { + "shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", + "tarball": "http://registry.npmjs.org/glob/-/glob-3.2.11.tgz" + }, + "engines": { + "node": "*" + }, + "gitHead": "73f57e99510582b2024b762305970ebcf9b70aa2", + "homepage": "https://github.com/isaacs/node-glob", + "license": "BSD", + "main": "glob.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "glob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "scripts": { + "test": "tap test/*.js", + "test-regen": "TEST_REGEN=1 node test/00-setup.js" + }, + "version": "3.2.11" +} diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/00-setup.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/00-setup.js new file mode 100644 index 0000000..245afaf --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/00-setup.js @@ -0,0 +1,176 @@ +// just a little pre-run script to set up the fixtures. +// zz-finish cleans it up + +var mkdirp = require("mkdirp") +var path = require("path") +var i = 0 +var tap = require("tap") +var fs = require("fs") +var rimraf = require("rimraf") + +var files = +[ "a/.abcdef/x/y/z/a" +, "a/abcdef/g/h" +, "a/abcfed/g/h" +, "a/b/c/d" +, "a/bc/e/f" +, "a/c/d/c/b" +, "a/cb/e/f" +] + +var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c") +var symlinkFrom = "../.." + +files = files.map(function (f) { + return path.resolve(__dirname, f) +}) + +tap.test("remove fixtures", function (t) { + rimraf(path.resolve(__dirname, "a"), function (er) { + t.ifError(er, "remove fixtures") + t.end() + }) +}) + +files.forEach(function (f) { + tap.test(f, function (t) { + var d = path.dirname(f) + mkdirp(d, 0755, function (er) { + if (er) { + t.fail(er) + return t.bailout() + } + fs.writeFile(f, "i like tests", function (er) { + t.ifError(er, "make file") + t.end() + }) + }) + }) +}) + +if (process.platform !== "win32") { + tap.test("symlinky", function (t) { + var d = path.dirname(symlinkTo) + console.error("mkdirp", d) + mkdirp(d, 0755, function (er) { + t.ifError(er) + fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) { + t.ifError(er, "make symlink") + t.end() + }) + }) + }) +} + +;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) { + w = "/tmp/glob-test/" + w + tap.test("create " + w, function (t) { + mkdirp(w, function (er) { + if (er) + throw er + t.pass(w) + t.end() + }) + }) +}) + + +// generate the bash pattern test-fixtures if possible +if (process.platform === "win32" || !process.env.TEST_REGEN) { + console.error("Windows, or TEST_REGEN unset. Using cached fixtures.") + return +} + +var spawn = require("child_process").spawn; +var globs = + // put more patterns here. + // anything that would be directly in / should be in /tmp/glob-test + ["test/a/*/+(c|g)/./d" + ,"test/a/**/[cg]/../[cg]" + ,"test/a/{b,c,d,e,f}/**/g" + ,"test/a/b/**" + ,"test/**/g" + ,"test/a/abc{fed,def}/g/h" + ,"test/a/abc{fed/g,def}/**/" + ,"test/a/abc{fed/g,def}/**///**/" + ,"test/**/a/**/" + ,"test/+(a|b|c)/a{/,bc*}/**" + ,"test/*/*/*/f" + ,"test/**/f" + ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**" + ,"{./*/*,/tmp/glob-test/*}" + ,"{/tmp/glob-test/*,*}" // evil owl face! how you taunt me! + ,"test/a/!(symlink)/**" + ] +var bashOutput = {} +var fs = require("fs") + +globs.forEach(function (pattern) { + tap.test("generate fixture " + pattern, function (t) { + var cmd = "shopt -s globstar && " + + "shopt -s extglob && " + + "shopt -s nullglob && " + + // "shopt >&2; " + + "eval \'for i in " + pattern + "; do echo $i; done\'" + var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) }) + var out = [] + cp.stdout.on("data", function (c) { + out.push(c) + }) + cp.stderr.pipe(process.stderr) + cp.on("close", function (code) { + out = flatten(out) + if (!out) + out = [] + else + out = cleanResults(out.split(/\r*\n/)) + + bashOutput[pattern] = out + t.notOk(code, "bash test should finish nicely") + t.end() + }) + }) +}) + +tap.test("save fixtures", function (t) { + var fname = path.resolve(__dirname, "bash-results.json") + var data = JSON.stringify(bashOutput, null, 2) + "\n" + fs.writeFile(fname, data, function (er) { + t.ifError(er) + t.end() + }) +}) + +function cleanResults (m) { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m.map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort).map(function (f) { + // de-windows + return (process.platform !== 'win32') ? f + : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') + }) +} + +function flatten (chunks) { + var s = 0 + chunks.forEach(function (c) { s += c.length }) + var out = new Buffer(s) + s = 0 + chunks.forEach(function (c) { + c.copy(out, s) + s += c.length + }) + + return out.toString().trim() +} + +function alphasort (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 +} diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/bash-comparison.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/bash-comparison.js new file mode 100644 index 0000000..239ed1a --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/bash-comparison.js @@ -0,0 +1,63 @@ +// basic test +// show that it does the same thing by default as the shell. +var tap = require("tap") +, child_process = require("child_process") +, bashResults = require("./bash-results.json") +, globs = Object.keys(bashResults) +, glob = require("../") +, path = require("path") + +// run from the root of the project +// this is usually where you're at anyway, but be sure. +process.chdir(path.resolve(__dirname, "..")) + +function alphasort (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 +} + +globs.forEach(function (pattern) { + var expect = bashResults[pattern] + // anything regarding the symlink thing will fail on windows, so just skip it + if (process.platform === "win32" && + expect.some(function (m) { + return /\/symlink\//.test(m) + })) + return + + tap.test(pattern, function (t) { + glob(pattern, function (er, matches) { + if (er) + throw er + + // sort and unmark, just to match the shell results + matches = cleanResults(matches) + + t.deepEqual(matches, expect, pattern) + t.end() + }) + }) + + tap.test(pattern + " sync", function (t) { + var matches = cleanResults(glob.sync(pattern)) + + t.deepEqual(matches, expect, "should match shell") + t.end() + }) +}) + +function cleanResults (m) { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m.map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort).map(function (f) { + // de-windows + return (process.platform !== 'win32') ? f + : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/') + }) +} diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/bash-results.json b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/bash-results.json new file mode 100644 index 0000000..8051c72 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/bash-results.json @@ -0,0 +1,351 @@ +{ + "test/a/*/+(c|g)/./d": [ + "test/a/b/c/./d" + ], + "test/a/**/[cg]/../[cg]": [ + "test/a/abcdef/g/../g", + "test/a/abcfed/g/../g", + "test/a/b/c/../c", + "test/a/c/../c", + "test/a/c/d/c/../c", + "test/a/symlink/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c" + ], + "test/a/{b,c,d,e,f}/**/g": [], + "test/a/b/**": [ + "test/a/b", + "test/a/b/c", + "test/a/b/c/d" + ], + "test/**/g": [ + "test/a/abcdef/g", + "test/a/abcfed/g" + ], + "test/a/abc{fed,def}/g/h": [ + "test/a/abcdef/g/h", + "test/a/abcfed/g/h" + ], + "test/a/abc{fed/g,def}/**/": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcfed/g" + ], + "test/a/abc{fed/g,def}/**///**/": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcfed/g" + ], + "test/**/a/**/": [ + "test/a", + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcfed", + "test/a/abcfed/g", + "test/a/b", + "test/a/b/c", + "test/a/bc", + "test/a/bc/e", + "test/a/c", + "test/a/c/d", + "test/a/c/d/c", + "test/a/cb", + "test/a/cb/e", + "test/a/symlink", + "test/a/symlink/a", + "test/a/symlink/a/b", + "test/a/symlink/a/b/c", + "test/a/symlink/a/b/c/a", + "test/a/symlink/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b" + ], + "test/+(a|b|c)/a{/,bc*}/**": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcdef/g/h", + "test/a/abcfed", + "test/a/abcfed/g", + "test/a/abcfed/g/h" + ], + "test/*/*/*/f": [ + "test/a/bc/e/f", + "test/a/cb/e/f" + ], + "test/**/f": [ + "test/a/bc/e/f", + "test/a/cb/e/f" + ], + "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [ + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c" + ], + "{./*/*,/tmp/glob-test/*}": [ + "./examples/g.js", + "./examples/usr-local.js", + "./node_modules/inherits", + "./node_modules/minimatch", + "./node_modules/mkdirp", + "./node_modules/rimraf", + "./node_modules/tap", + "./test/00-setup.js", + "./test/a", + "./test/bash-comparison.js", + "./test/bash-results.json", + "./test/cwd-test.js", + "./test/globstar-match.js", + "./test/mark.js", + "./test/new-glob-optional-options.js", + "./test/nocase-nomagic.js", + "./test/pause-resume.js", + "./test/readme-issue.js", + "./test/root-nomount.js", + "./test/root.js", + "./test/stat.js", + "./test/zz-cleanup.js", + "/tmp/glob-test/asdf", + "/tmp/glob-test/bar", + "/tmp/glob-test/baz", + "/tmp/glob-test/foo", + "/tmp/glob-test/quux", + "/tmp/glob-test/qwer", + "/tmp/glob-test/rewq" + ], + "{/tmp/glob-test/*,*}": [ + "/tmp/glob-test/asdf", + "/tmp/glob-test/bar", + "/tmp/glob-test/baz", + "/tmp/glob-test/foo", + "/tmp/glob-test/quux", + "/tmp/glob-test/qwer", + "/tmp/glob-test/rewq", + "examples", + "glob.js", + "LICENSE", + "node_modules", + "package.json", + "README.md", + "test" + ], + "test/a/!(symlink)/**": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcdef/g/h", + "test/a/abcfed", + "test/a/abcfed/g", + "test/a/abcfed/g/h", + "test/a/b", + "test/a/b/c", + "test/a/b/c/d", + "test/a/bc", + "test/a/bc/e", + "test/a/bc/e/f", + "test/a/c", + "test/a/c/d", + "test/a/c/d/c", + "test/a/c/d/c/b", + "test/a/cb", + "test/a/cb/e", + "test/a/cb/e/f" + ] +} diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/cwd-test.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/cwd-test.js new file mode 100644 index 0000000..352c27e --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/cwd-test.js @@ -0,0 +1,55 @@ +var tap = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +tap.test("changing cwd and searching for **/d", function (t) { + var glob = require('../') + var path = require('path') + t.test('.', function (t) { + glob('**/d', function (er, matches) { + t.ifError(er) + t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) + t.end() + }) + }) + + t.test('a', function (t) { + glob('**/d', {cwd:path.resolve('a')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'b/c/d', 'c/d' ]) + t.end() + }) + }) + + t.test('a/b', function (t) { + glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'c/d' ]) + t.end() + }) + }) + + t.test('a/b/', function (t) { + glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'c/d' ]) + t.end() + }) + }) + + t.test('.', function (t) { + glob('**/d', {cwd: process.cwd()}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) + t.end() + }) + }) + + t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() + }) + + t.end() +}) diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/globstar-match.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/globstar-match.js new file mode 100644 index 0000000..9b234fa --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/globstar-match.js @@ -0,0 +1,19 @@ +var Glob = require("../glob.js").Glob +var test = require('tap').test + +test('globstar should not have dupe matches', function(t) { + var pattern = 'a/**/[gh]' + var g = new Glob(pattern, { cwd: __dirname }) + var matches = [] + g.on('match', function(m) { + console.error('match %j', m) + matches.push(m) + }) + g.on('end', function(set) { + console.error('set', set) + matches = matches.sort() + set = set.sort() + t.same(matches, set, 'should have same set of matches') + t.end() + }) +}) diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/mark.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/mark.js new file mode 100644 index 0000000..bf411c0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/mark.js @@ -0,0 +1,118 @@ +var test = require("tap").test +var glob = require('../') +process.chdir(__dirname) + +// expose timing issues +var lag = 5 +glob.Glob.prototype._stat = function(o) { return function(f, cb) { + var args = arguments + setTimeout(function() { + o.call(this, f, cb) + }.bind(this), lag += 5) +}}(glob.Glob.prototype._stat) + + +test("mark, with **", function (t) { + glob("a/*b*/**", {mark: true}, function (er, results) { + if (er) + throw er + var expect = + [ 'a/abcdef/', + 'a/abcdef/g/', + 'a/abcdef/g/h', + 'a/abcfed/', + 'a/abcfed/g/', + 'a/abcfed/g/h', + 'a/b/', + 'a/b/c/', + 'a/b/c/d', + 'a/bc/', + 'a/bc/e/', + 'a/bc/e/f', + 'a/cb/', + 'a/cb/e/', + 'a/cb/e/f' ] + + t.same(results, expect) + t.end() + }) +}) + +test("mark, no / on pattern", function (t) { + glob("a/*", {mark: true}, function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/' ] + + if (process.platform !== "win32") + expect.push('a/symlink/') + + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /\/$/) + }) +}) + +test("mark=false, no / on pattern", function (t) { + glob("a/*", function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef', + 'a/abcfed', + 'a/b', + 'a/bc', + 'a/c', + 'a/cb' ] + + if (process.platform !== "win32") + expect.push('a/symlink') + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /[^\/]$/) + }) +}) + +test("mark=true, / on pattern", function (t) { + glob("a/*/", {mark: true}, function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/' ] + if (process.platform !== "win32") + expect.push('a/symlink/') + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /\/$/) + }) +}) + +test("mark=false, / on pattern", function (t) { + glob("a/*/", function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/' ] + if (process.platform !== "win32") + expect.push('a/symlink/') + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /\/$/) + }) +}) diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/new-glob-optional-options.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/new-glob-optional-options.js new file mode 100644 index 0000000..3e7dc5a --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/new-glob-optional-options.js @@ -0,0 +1,10 @@ +var Glob = require('../glob.js').Glob; +var test = require('tap').test; + +test('new glob, with cb, and no options', function (t) { + new Glob(__filename, function(er, results) { + if (er) throw er; + t.same(results, [__filename]); + t.end(); + }); +}); diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/nocase-nomagic.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/nocase-nomagic.js new file mode 100644 index 0000000..2503f23 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/nocase-nomagic.js @@ -0,0 +1,113 @@ +var fs = require('fs'); +var test = require('tap').test; +var glob = require('../'); + +test('mock fs', function(t) { + var stat = fs.stat + var statSync = fs.statSync + var readdir = fs.readdir + var readdirSync = fs.readdirSync + + function fakeStat(path) { + var ret + switch (path.toLowerCase()) { + case '/tmp': case '/tmp/': + ret = { isDirectory: function() { return true } } + break + case '/tmp/a': + ret = { isDirectory: function() { return false } } + break + } + return ret + } + + fs.stat = function(path, cb) { + var f = fakeStat(path); + if (f) { + process.nextTick(function() { + cb(null, f) + }) + } else { + stat.call(fs, path, cb) + } + } + + fs.statSync = function(path) { + return fakeStat(path) || statSync.call(fs, path) + } + + function fakeReaddir(path) { + var ret + switch (path.toLowerCase()) { + case '/tmp': case '/tmp/': + ret = [ 'a', 'A' ] + break + case '/': + ret = ['tmp', 'tMp', 'tMP', 'TMP'] + } + return ret + } + + fs.readdir = function(path, cb) { + var f = fakeReaddir(path) + if (f) + process.nextTick(function() { + cb(null, f) + }) + else + readdir.call(fs, path, cb) + } + + fs.readdirSync = function(path) { + return fakeReaddir(path) || readdirSync.call(fs, path) + } + + t.pass('mocked') + t.end() +}) + +test('nocase, nomagic', function(t) { + var n = 2 + var want = [ '/TMP/A', + '/TMP/a', + '/tMP/A', + '/tMP/a', + '/tMp/A', + '/tMp/a', + '/tmp/A', + '/tmp/a' ] + glob('/tmp/a', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + if (--n === 0) t.end() + }) + glob('/tmp/A', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + if (--n === 0) t.end() + }) +}) + +test('nocase, with some magic', function(t) { + t.plan(2) + var want = [ '/TMP/A', + '/TMP/a', + '/tMP/A', + '/tMP/a', + '/tMp/A', + '/tMp/a', + '/tmp/A', + '/tmp/a' ] + glob('/tmp/*', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + }) + glob('/tmp/*', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + }) +}) diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/pause-resume.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/pause-resume.js new file mode 100644 index 0000000..e1ffbab --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/pause-resume.js @@ -0,0 +1,73 @@ +// show that no match events happen while paused. +var tap = require("tap") +, child_process = require("child_process") +// just some gnarly pattern with lots of matches +, pattern = "test/a/!(symlink)/**" +, bashResults = require("./bash-results.json") +, patterns = Object.keys(bashResults) +, glob = require("../") +, Glob = glob.Glob +, path = require("path") + +// run from the root of the project +// this is usually where you're at anyway, but be sure. +process.chdir(path.resolve(__dirname, "..")) + +function alphasort (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 +} + +function cleanResults (m) { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m.map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort).map(function (f) { + // de-windows + return (process.platform !== 'win32') ? f + : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') + }) +} + +var globResults = [] +tap.test("use a Glob object, and pause/resume it", function (t) { + var g = new Glob(pattern) + , paused = false + , res = [] + , expect = bashResults[pattern] + + g.on("pause", function () { + console.error("pause") + }) + + g.on("resume", function () { + console.error("resume") + }) + + g.on("match", function (m) { + t.notOk(g.paused, "must not be paused") + globResults.push(m) + g.pause() + t.ok(g.paused, "must be paused") + setTimeout(g.resume.bind(g), 10) + }) + + g.on("end", function (matches) { + t.pass("reached glob end") + globResults = cleanResults(globResults) + matches = cleanResults(matches) + t.deepEqual(matches, globResults, + "end event matches should be the same as match events") + + t.deepEqual(matches, expect, + "glob matches should be the same as bash results") + + t.end() + }) +}) + diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/readme-issue.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/readme-issue.js new file mode 100644 index 0000000..0b4e0be --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/readme-issue.js @@ -0,0 +1,36 @@ +var test = require("tap").test +var glob = require("../") + +var mkdirp = require("mkdirp") +var fs = require("fs") +var rimraf = require("rimraf") +var dir = __dirname + "/package" + +test("setup", function (t) { + mkdirp.sync(dir) + fs.writeFileSync(dir + "/package.json", "{}", "ascii") + fs.writeFileSync(dir + "/README", "x", "ascii") + t.pass("setup done") + t.end() +}) + +test("glob", function (t) { + var opt = { + cwd: dir, + nocase: true, + mark: true + } + + glob("README?(.*)", opt, function (er, files) { + if (er) + throw er + t.same(files, ["README"]) + t.end() + }) +}) + +test("cleanup", function (t) { + rimraf.sync(dir) + t.pass("clean") + t.end() +}) diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/root-nomount.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/root-nomount.js new file mode 100644 index 0000000..3ac5979 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/root-nomount.js @@ -0,0 +1,39 @@ +var tap = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +tap.test("changing root and searching for /b*/**", function (t) { + var glob = require('../') + var path = require('path') + t.test('.', function (t) { + glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, []) + t.end() + }) + }) + + t.test('a', function (t) { + glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) + t.end() + }) + }) + + t.test('root=a, cwd=a/b', function (t) { + glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) + t.end() + }) + }) + + t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() + }) + + t.end() +}) diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/root.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/root.js new file mode 100644 index 0000000..95c23f9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/root.js @@ -0,0 +1,46 @@ +var t = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +var glob = require('../') +var path = require('path') + +t.test('.', function (t) { + glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) { + t.ifError(er) + t.like(matches, []) + t.end() + }) +}) + + +t.test('a', function (t) { + console.error("root=" + path.resolve('a')) + glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) { + t.ifError(er) + var wanted = [ + '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' + ].map(function (m) { + return path.join(path.resolve('a'), m).replace(/\\/g, '/') + }) + + t.like(matches, wanted) + t.end() + }) +}) + +t.test('root=a, cwd=a/b', function (t) { + glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { + return path.join(path.resolve('a'), m).replace(/\\/g, '/') + })) + t.end() + }) +}) + +t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() +}) diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/stat.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/stat.js new file mode 100644 index 0000000..6291711 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/stat.js @@ -0,0 +1,32 @@ +var glob = require('../') +var test = require('tap').test +var path = require('path') + +test('stat all the things', function(t) { + var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: __dirname }) + var matches = [] + g.on('match', function(m) { + matches.push(m) + }) + var stats = [] + g.on('stat', function(m) { + stats.push(m) + }) + g.on('end', function(eof) { + stats = stats.sort() + matches = matches.sort() + eof = eof.sort() + t.same(stats, matches) + t.same(eof, matches) + var cache = Object.keys(this.statCache) + t.same(cache.map(function (f) { + return path.relative(__dirname, f) + }).sort(), matches) + + cache.forEach(function(c) { + t.equal(typeof this.statCache[c], 'object') + }, this) + + t.end() + }) +}) diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/zz-cleanup.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/zz-cleanup.js new file mode 100644 index 0000000..e085f0f --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/glob/test/zz-cleanup.js @@ -0,0 +1,11 @@ +// remove the fixtures +var tap = require("tap") +, rimraf = require("rimraf") +, path = require("path") + +tap.test("cleanup fixtures", function (t) { + rimraf(path.resolve(__dirname, "a"), function (er) { + t.ifError(er, "removed") + t.end() + }) +}) diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/.npmignore b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/platforms/android/cordova/node_modules/nopt/node_modules/abbrev/LICENSE b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/LICENSE similarity index 100% rename from platforms/android/cordova/node_modules/nopt/node_modules/abbrev/LICENSE rename to platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/LICENSE diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/README.md b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/README.md new file mode 100644 index 0000000..5b3967e --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/README.md @@ -0,0 +1,218 @@ +# minimatch + +A minimal matching utility. + +[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch) + + +This is the matching library used internally by npm. + +Eventually, it will replace the C binding in node-glob. + +It works by converting glob expressions into JavaScript `RegExp` +objects. + +## Usage + +```javascript +var minimatch = require("minimatch") + +minimatch("bar.foo", "*.foo") // true! +minimatch("bar.foo", "*.bar") // false! +minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy! +``` + +## Features + +Supports these glob features: + +* Brace Expansion +* Extended glob matching +* "Globstar" `**` matching + +See: + +* `man sh` +* `man bash` +* `man 3 fnmatch` +* `man 5 gitignore` + +## Minimatch Class + +Create a minimatch object by instanting the `minimatch.Minimatch` class. + +```javascript +var Minimatch = require("minimatch").Minimatch +var mm = new Minimatch(pattern, options) +``` + +### Properties + +* `pattern` The original pattern the minimatch object represents. +* `options` The options supplied to the constructor. +* `set` A 2-dimensional array of regexp or string expressions. + Each row in the + array corresponds to a brace-expanded pattern. Each item in the row + corresponds to a single path-part. For example, the pattern + `{a,b/c}/d` would expand to a set of patterns like: + + [ [ a, d ] + , [ b, c, d ] ] + + If a portion of the pattern doesn't have any "magic" in it + (that is, it's something like `"foo"` rather than `fo*o?`), then it + will be left as a string rather than converted to a regular + expression. + +* `regexp` Created by the `makeRe` method. A single regular expression + expressing the entire pattern. This is useful in cases where you wish + to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled. +* `negate` True if the pattern is negated. +* `comment` True if the pattern is a comment. +* `empty` True if the pattern is `""`. + +### Methods + +* `makeRe` Generate the `regexp` member if necessary, and return it. + Will return `false` if the pattern is invalid. +* `match(fname)` Return true if the filename matches the pattern, or + false otherwise. +* `matchOne(fileArray, patternArray, partial)` Take a `/`-split + filename, and match it against a single row in the `regExpSet`. This + method is mainly for internal use, but is exposed so that it can be + used by a glob-walker that needs to avoid excessive filesystem calls. + +All other methods are internal, and will be called as necessary. + +## Functions + +The top-level exported function has a `cache` property, which is an LRU +cache set to store 100 items. So, calling these methods repeatedly +with the same pattern and options will use the same Minimatch object, +saving the cost of parsing it multiple times. + +### minimatch(path, pattern, options) + +Main export. Tests a path against the pattern using the options. + +```javascript +var isJS = minimatch(file, "*.js", { matchBase: true }) +``` + +### minimatch.filter(pattern, options) + +Returns a function that tests its +supplied argument, suitable for use with `Array.filter`. Example: + +```javascript +var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true})) +``` + +### minimatch.match(list, pattern, options) + +Match against the list of +files, in the style of fnmatch or glob. If nothing is matched, and +options.nonull is set, then return a list containing the pattern itself. + +```javascript +var javascripts = minimatch.match(fileList, "*.js", {matchBase: true})) +``` + +### minimatch.makeRe(pattern, options) + +Make a regular expression object from the pattern. + +## Options + +All options are `false` by default. + +### debug + +Dump a ton of stuff to stderr. + +### nobrace + +Do not expand `{a,b}` and `{1..3}` brace sets. + +### noglobstar + +Disable `**` matching against multiple folder names. + +### dot + +Allow patterns to match filenames starting with a period, even if +the pattern does not explicitly have a period in that spot. + +Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot` +is set. + +### noext + +Disable "extglob" style patterns like `+(a|b)`. + +### nocase + +Perform a case-insensitive match. + +### nonull + +When a match is not found by `minimatch.match`, return a list containing +the pattern itself if this option is set. When not set, an empty list +is returned if there are no matches. + +### matchBase + +If set, then patterns without slashes will be matched +against the basename of the path if it contains slashes. For example, +`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. + +### nocomment + +Suppress the behavior of treating `#` at the start of a pattern as a +comment. + +### nonegate + +Suppress the behavior of treating a leading `!` character as negation. + +### flipNegate + +Returns from negate expressions the same as if they were not negated. +(Ie, true on a hit, false on a miss.) + + +## Comparisons to other fnmatch/glob implementations + +While strict compliance with the existing standards is a worthwhile +goal, some discrepancies exist between minimatch and other +implementations, and are intentional. + +If the pattern starts with a `!` character, then it is negated. Set the +`nonegate` flag to suppress this behavior, and treat leading `!` +characters normally. This is perhaps relevant if you wish to start the +pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` +characters at the start of a pattern will negate the pattern multiple +times. + +If a pattern starts with `#`, then it is treated as a comment, and +will not match anything. Use `\#` to match a literal `#` at the +start of a line, or set the `nocomment` flag to suppress this behavior. + +The double-star character `**` is supported by default, unless the +`noglobstar` flag is set. This is supported in the manner of bsdglob +and bash 4.1, where `**` only has special significance if it is the only +thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but +`a/**b` will not. + +If an escaped pattern has no matches, and the `nonull` flag is set, +then minimatch.match returns the pattern as-provided, rather than +interpreting the character escapes. For example, +`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than +`"*a?"`. This is akin to setting the `nullglob` option in bash, except +that it does not resolve escaped pattern characters. + +If brace expansion is not disabled, then it is performed before any +other interpretation of the glob pattern. Thus, a pattern like +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are +checked for validity. Since those two are valid, matching proceeds. diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/minimatch.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/minimatch.js new file mode 100644 index 0000000..4539678 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/minimatch.js @@ -0,0 +1,1061 @@ +;(function (require, exports, module, platform) { + +if (module) module.exports = minimatch +else exports.minimatch = minimatch + +if (!require) { + require = function (id) { + switch (id) { + case "sigmund": return function sigmund (obj) { + return JSON.stringify(obj) + } + case "path": return { basename: function (f) { + f = f.split(/[\/\\]/) + var e = f.pop() + if (!e) e = f.pop() + return e + }} + case "lru-cache": return function LRUCache () { + // not quite an LRU, but still space-limited. + var cache = {} + var cnt = 0 + this.set = function (k, v) { + cnt ++ + if (cnt >= 100) cache = {} + cache[k] = v + } + this.get = function (k) { return cache[k] } + } + } + } +} + +minimatch.Minimatch = Minimatch + +var LRU = require("lru-cache") + , cache = minimatch.cache = new LRU({max: 100}) + , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} + , sigmund = require("sigmund") + +var path = require("path") + // any single thing other than / + // don't need to escape / when using new RegExp() + , qmark = "[^/]" + + // * => any number of characters + , star = qmark + "*?" + + // ** when dots are allowed. Anything goes, except .. and . + // not (^ or / followed by one or two dots followed by $ or /), + // followed by anything, any number of times. + , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?" + + // not a ^ or / followed by a dot, + // followed by anything, any number of times. + , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?" + + // characters that need to be escaped in RegExp. + , reSpecials = charSet("().*{}+?[]^$\\!") + +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split("").reduce(function (set, c) { + set[c] = true + return set + }, {}) +} + +// normalizes slashes. +var slashSplit = /\/+/ + +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} + +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t +} + +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch + + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) + } + + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } + + return m +} + +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} + + +function minimatch (p, pattern, options) { + if (typeof pattern !== "string") { + throw new TypeError("glob pattern string required") + } + + if (!options) options = {} + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === "#") { + return false + } + + // "" only matches "" + if (pattern.trim() === "") return p === "" + + return new Minimatch(pattern, options).match(p) +} + +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options, cache) + } + + if (typeof pattern !== "string") { + throw new TypeError("glob pattern string required") + } + + if (!options) options = {} + pattern = pattern.trim() + + // windows: need to use /, not \ + // On other platforms, \ is a valid (albeit bad) filename char. + if (platform === "win32") { + pattern = pattern.split("\\").join("/") + } + + // lru storage. + // these things aren't particularly big, but walking down the string + // and turning it into a regexp can get pretty costly. + var cacheKey = pattern + "\n" + sigmund(options) + var cached = minimatch.cache.get(cacheKey) + if (cached) return cached + minimatch.cache.set(cacheKey, this) + + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false + + // make the set of regexps etc. + this.make() +} + +Minimatch.prototype.debug = function() {} + +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return + + var pattern = this.pattern + var options = this.options + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === "#") { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } + + // step 1: figure out negation, etc. + this.parseNegate() + + // step 2: expand braces + var set = this.globSet = this.braceExpand() + + if (options.debug) this.debug = console.error + + this.debug(this.pattern, set) + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) + + this.debug(this.pattern, set) + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) + + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return -1 === s.indexOf(false) + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + , negate = false + , options = this.options + , negateOffset = 0 + + if (options.nonegate) return + + for ( var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === "!" + ; i ++) { + negate = !negate + negateOffset ++ + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} + +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return new Minimatch(pattern, options).braceExpand() +} + +Minimatch.prototype.braceExpand = braceExpand +function braceExpand (pattern, options) { + options = options || this.options + pattern = typeof pattern === "undefined" + ? this.pattern : pattern + + if (typeof pattern === "undefined") { + throw new Error("undefined pattern") + } + + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] + } + + var escaping = false + + // examples and comments refer to this crazy pattern: + // a{b,c{d,e},{f,g}h}x{y,z} + // expected: + // abxy + // abxz + // acdxy + // acdxz + // acexy + // acexz + // afhxy + // afhxz + // aghxy + // aghxz + + // everything before the first \{ is just a prefix. + // So, we pluck that off, and work with the rest, + // and then prepend it to everything we find. + if (pattern.charAt(0) !== "{") { + this.debug(pattern) + var prefix = null + for (var i = 0, l = pattern.length; i < l; i ++) { + var c = pattern.charAt(i) + this.debug(i, c) + if (c === "\\") { + escaping = !escaping + } else if (c === "{" && !escaping) { + prefix = pattern.substr(0, i) + break + } + } + + // actually no sets, all { were escaped. + if (prefix === null) { + this.debug("no sets") + return [pattern] + } + + var tail = braceExpand.call(this, pattern.substr(i), options) + return tail.map(function (t) { + return prefix + t + }) + } + + // now we have something like: + // {b,c{d,e},{f,g}h}x{y,z} + // walk through the set, expanding each part, until + // the set ends. then, we'll expand the suffix. + // If the set only has a single member, then'll put the {} back + + // first, handle numeric sets, since they're easier + var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/) + if (numset) { + this.debug("numset", numset[1], numset[2]) + var suf = braceExpand.call(this, pattern.substr(numset[0].length), options) + , start = +numset[1] + , end = +numset[2] + , inc = start > end ? -1 : 1 + , set = [] + for (var i = start; i != (end + inc); i += inc) { + // append all the suffixes + for (var ii = 0, ll = suf.length; ii < ll; ii ++) { + set.push(i + suf[ii]) + } + } + return set + } + + // ok, walk through the set + // We hope, somewhat optimistically, that there + // will be a } at the end. + // If the closing brace isn't found, then the pattern is + // interpreted as braceExpand("\\" + pattern) so that + // the leading \{ will be interpreted literally. + var i = 1 // skip the \{ + , depth = 1 + , set = [] + , member = "" + , sawEnd = false + , escaping = false + + function addMember () { + set.push(member) + member = "" + } + + this.debug("Entering for") + FOR: for (i = 1, l = pattern.length; i < l; i ++) { + var c = pattern.charAt(i) + this.debug("", i, c) + + if (escaping) { + escaping = false + member += "\\" + c + } else { + switch (c) { + case "\\": + escaping = true + continue + + case "{": + depth ++ + member += "{" + continue + + case "}": + depth -- + // if this closes the actual set, then we're done + if (depth === 0) { + addMember() + // pluck off the close-brace + i ++ + break FOR + } else { + member += c + continue + } + + case ",": + if (depth === 1) { + addMember() + } else { + member += c + } + continue + + default: + member += c + continue + } // switch + } // else + } // for + + // now we've either finished the set, and the suffix is + // pattern.substr(i), or we have *not* closed the set, + // and need to escape the leading brace + if (depth !== 0) { + this.debug("didn't close", pattern) + return braceExpand.call(this, "\\" + pattern, options) + } + + // x{y,z} -> ["xy", "xz"] + this.debug("set", set) + this.debug("suffix", pattern.substr(i)) + var suf = braceExpand.call(this, pattern.substr(i), options) + // ["b", "c{d,e}","{f,g}h"] -> + // [["b"], ["cd", "ce"], ["fh", "gh"]] + var addBraces = set.length === 1 + this.debug("set pre-expanded", set) + set = set.map(function (p) { + return braceExpand.call(this, p, options) + }, this) + this.debug("set expanded", set) + + + // [["b"], ["cd", "ce"], ["fh", "gh"]] -> + // ["b", "cd", "ce", "fh", "gh"] + set = set.reduce(function (l, r) { + return l.concat(r) + }) + + if (addBraces) { + set = set.map(function (s) { + return "{" + s + "}" + }) + } + + // now attach the suffixes. + var ret = [] + for (var i = 0, l = set.length; i < l; i ++) { + for (var ii = 0, ll = suf.length; ii < ll; ii ++) { + ret.push(set[i] + suf[ii]) + } + } + return ret +} + +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + var options = this.options + + // shortcuts + if (!options.noglobstar && pattern === "**") return GLOBSTAR + if (pattern === "") return "" + + var re = "" + , hasMagic = !!options.nocase + , escaping = false + // ? => one single character + , patternListStack = [] + , plType + , stateChar + , inClass = false + , reClassStart = -1 + , classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + , patternStart = pattern.charAt(0) === "." ? "" // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))" + : "(?!\\.)" + , self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case "*": + re += star + hasMagic = true + break + case "?": + re += qmark + hasMagic = true + break + default: + re += "\\"+stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } + + for ( var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i ++ ) { + + this.debug("%s\t%s %s %j", pattern, i, re, c) + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += "\\" + c + escaping = false + continue + } + + SWITCH: switch (c) { + case "/": + // completely not allowed, even escaped. + // Should already be path-split by now. + return false + + case "\\": + clearStateChar() + escaping = true + continue + + // the various stateChar values + // for the "extglob" stuff. + case "?": + case "*": + case "+": + case "@": + case "!": + this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c) + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === "!" && i === classStart + 1) c = "^" + re += c + continue + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + + case "(": + if (inClass) { + re += "(" + continue + } + + if (!stateChar) { + re += "\\(" + continue + } + + plType = stateChar + patternListStack.push({ type: plType + , start: i - 1 + , reStart: re.length }) + // negation is (?:(?!js)[^/]*) + re += stateChar === "!" ? "(?:(?!" : "(?:" + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + + case ")": + if (inClass || !patternListStack.length) { + re += "\\)" + continue + } + + clearStateChar() + hasMagic = true + re += ")" + plType = patternListStack.pop().type + // negation is (?:(?!js)[^/]*) + // The others are (?:) + switch (plType) { + case "!": + re += "[^/]*?)" + break + case "?": + case "+": + case "*": re += plType + case "@": break // the default anyway + } + continue + + case "|": + if (inClass || !patternListStack.length || escaping) { + re += "\\|" + escaping = false + continue + } + + clearStateChar() + re += "|" + continue + + // these are mostly the same in regexp and glob + case "[": + // swallow any state-tracking char before the [ + clearStateChar() + + if (inClass) { + re += "\\" + c + continue + } + + inClass = true + classStart = i + reClassStart = re.length + re += c + continue + + case "]": + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += "\\" + c + escaping = false + continue + } + + // finish up the class. + hasMagic = true + inClass = false + re += c + continue + + default: + // swallow any state char that wasn't consumed + clearStateChar() + + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === "^" && inClass)) { + re += "\\" + } + + re += c + + } // switch + } // for + + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + var cs = pattern.substr(classStart + 1) + , sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + "\\[" + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + var pl + while (pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + 3) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = "\\" + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + "|" + }) + + this.debug("tail=%j\n %s", tail, tail) + var t = pl.type === "*" ? star + : pl.type === "?" ? qmark + : "\\" + pl.type + + hasMagic = true + re = re.slice(0, pl.reStart) + + t + "\\(" + + tail + } + + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += "\\\\" + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case ".": + case "[": + case "(": addPatternStart = true + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== "" && hasMagic) re = "(?=.)" + re + + if (addPatternStart) re = patternStart + re + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [ re, hasMagic ] + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } + + var flags = options.nocase ? "i" : "" + , regExp = new RegExp("^" + re + "$", flags) + + regExp._glob = pattern + regExp._src = re + + return regExp +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} + +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) return this.regexp = false + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + , flags = options.nocase ? "i" : "" + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === "string") ? regExpEscape(p) + : p._src + }).join("\\\/") + }).join("|") + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = "^(?:" + re + ")$" + + // can match anything, as long as it's not this. + if (this.negate) re = "^(?!" + re + ").*$" + + try { + return this.regexp = new RegExp(re, flags) + } catch (ex) { + return this.regexp = false + } +} + +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} + +Minimatch.prototype.match = match +function match (f, partial) { + this.debug("match", f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === "" + + if (f === "/" && partial) return true + + var options = this.options + + // windows: need to use /, not \ + // On other platforms, \ is a valid (albeit bad) filename char. + if (platform === "win32") { + f = f.split("\\").join("/") + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, "split", f) + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set + this.debug(this.pattern, "set", set) + + // Find the basename of the path by looking for the last non-empty segment + var filename; + for (var i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (var i = 0, l = set.length; i < l; i ++) { + var pattern = set[i], file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} + +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + + this.debug("matchOne", + { "this": this + , file: file + , pattern: pattern }) + + this.debug("matchOne", file.length, pattern.length) + + for ( var fi = 0 + , pi = 0 + , fl = file.length + , pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi ++, pi ++ ) { + + this.debug("matchOne loop") + var p = pattern[pi] + , f = file[fi] + + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + , pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for ( ; fi < fl; fi ++) { + if (file[fi] === "." || file[fi] === ".." || + (!options.dot && file[fi].charAt(0) === ".")) return false + } + return true + } + + // ok, let's see if we can swallow whatever we can. + WHILE: while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', + file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === "." || swallowee === ".." || + (!options.dot && swallowee.charAt(0) === ".")) { + this.debug("dot detected!", file, fr, pattern, pr) + break WHILE + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr ++ + } + } + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug("\n>>> no match, partial?", file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === "string") { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug("string match", p, f, hit) + } else { + hit = f.match(p) + this.debug("pattern match", p, f, hit) + } + + if (!hit) return false + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === "") + return emptyFileEnd + } + + // should be unreachable. + throw new Error("wtf?") +} + + +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, "$1") +} + + +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") +} + +})( typeof require === "function" ? require : null, + this, + typeof module === "object" ? module : null, + typeof process === "object" ? process.platform : "win32" + ) diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/package.json b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/package.json new file mode 100644 index 0000000..ac23beb --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/package.json @@ -0,0 +1,82 @@ +{ + "_args": [ + [ + "minimatch@0.3", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine/node_modules/glob" + ] + ], + "_from": "minimatch@>=0.3.0 <0.4.0", + "_id": "minimatch@0.3.0", + "_inCache": true, + "_installable": true, + "_location": "/jasmine/minimatch", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "1.4.10", + "_phantomChildren": {}, + "_requested": { + "name": "minimatch", + "raw": "minimatch@0.3", + "rawSpec": "0.3", + "scope": null, + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine/glob" + ], + "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "_shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", + "_shrinkwrap": null, + "_spec": "minimatch@0.3", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine/node_modules/glob", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me" + }, + "bugs": { + "url": "https://github.com/isaacs/minimatch/issues" + }, + "dependencies": { + "lru-cache": "2", + "sigmund": "~1.0.0" + }, + "description": "a glob matcher in javascript", + "devDependencies": { + "tap": "" + }, + "directories": {}, + "dist": { + "shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", + "tarball": "http://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/isaacs/minimatch", + "license": { + "type": "MIT", + "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE" + }, + "main": "minimatch.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "minimatch", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/minimatch.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "0.3.0" +} diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/basic.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/basic.js new file mode 100644 index 0000000..ae7ac73 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/basic.js @@ -0,0 +1,399 @@ +// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test +// +// TODO: Some of these tests do very bad things with backslashes, and will +// most likely fail badly on windows. They should probably be skipped. + +var tap = require("tap") + , globalBefore = Object.keys(global) + , mm = require("../") + , files = [ "a", "b", "c", "d", "abc" + , "abd", "abe", "bb", "bcd" + , "ca", "cb", "dd", "de" + , "bdir/", "bdir/cfile"] + , next = files.concat([ "a-b", "aXb" + , ".x", ".y" ]) + + +var patterns = + [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test" + , ["a*", ["a", "abc", "abd", "abe"]] + , ["X*", ["X*"], {nonull: true}] + + // allow null glob expansion + , ["X*", []] + + // isaacs: Slightly different than bash/sh/ksh + // \\* is not un-escaped to literal "*" in a failed match, + // but it does make it get treated as a literal star + , ["\\*", ["\\*"], {nonull: true}] + , ["\\**", ["\\**"], {nonull: true}] + , ["\\*\\*", ["\\*\\*"], {nonull: true}] + + , ["b*/", ["bdir/"]] + , ["c*", ["c", "ca", "cb"]] + , ["**", files] + + , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] + , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] + + , "legendary larry crashes bashes" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] + + , "character classes" + , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] + , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", + "bdir/", "ca", "cb", "dd", "de"]] + , ["a*[^c]", ["abd", "abe"]] + , function () { files.push("a-b", "aXb") } + , ["a[X-]b", ["a-b", "aXb"]] + , function () { files.push(".x", ".y") } + , ["[^a-c]*", ["d", "dd", "de"]] + , function () { files.push("a*b/", "a*b/ooo") } + , ["a\\*b/*", ["a*b/ooo"]] + , ["a\\*?/*", ["a*b/ooo"]] + , ["*\\\\!*", [], {null: true}, ["echo !7"]] + , ["*\\!*", ["echo !7"], null, ["echo !7"]] + , ["*.\\*", ["r.*"], null, ["r.*"]] + , ["a[b]c", ["abc"]] + , ["a[\\b]c", ["abc"]] + , ["a?c", ["abc"]] + , ["a\\*c", [], {null: true}, ["abc"]] + , ["", [""], { null: true }, [""]] + + , "http://www.opensource.apple.com/source/bash/bash-23/" + + "bash/tests/glob-test" + , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } + , ["*/man*/bash.*", ["man/man1/bash.1"]] + , ["man/man1/bash.1", ["man/man1/bash.1"]] + , ["a***c", ["abc"], null, ["abc"]] + , ["a*****?c", ["abc"], null, ["abc"]] + , ["?*****??", ["abc"], null, ["abc"]] + , ["*****??", ["abc"], null, ["abc"]] + , ["?*****?c", ["abc"], null, ["abc"]] + , ["?***?****c", ["abc"], null, ["abc"]] + , ["?***?****?", ["abc"], null, ["abc"]] + , ["?***?****", ["abc"], null, ["abc"]] + , ["*******c", ["abc"], null, ["abc"]] + , ["*******?", ["abc"], null, ["abc"]] + , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["[-abc]", ["-"], null, ["-"]] + , ["[abc-]", ["-"], null, ["-"]] + , ["\\", ["\\"], null, ["\\"]] + , ["[\\\\]", ["\\"], null, ["\\"]] + , ["[[]", ["["], null, ["["]] + , ["[", ["["], null, ["["]] + , ["[*", ["[abc"], null, ["[abc"]] + , "a right bracket shall lose its special meaning and\n" + + "represent itself in a bracket expression if it occurs\n" + + "first in the list. -- POSIX.2 2.8.3.2" + , ["[]]", ["]"], null, ["]"]] + , ["[]-]", ["]"], null, ["]"]] + , ["[a-\z]", ["p"], null, ["p"]] + , ["??**********?****?", [], { null: true }, ["abc"]] + , ["??**********?****c", [], { null: true }, ["abc"]] + , ["?************c****?****", [], { null: true }, ["abc"]] + , ["*c*?**", [], { null: true }, ["abc"]] + , ["a*****c*?**", [], { null: true }, ["abc"]] + , ["a********???*******", [], { null: true }, ["abc"]] + , ["[]", [], { null: true }, ["a"]] + , ["[abc", [], { null: true }, ["["]] + + , "nocase tests" + , ["XYZ", ["xYz"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["ab*", ["ABC"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + + // [ pattern, [matches], MM opts, files, TAP opts] + , "onestar/twostar" + , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] + , ["{/?,*}", ["/a", "bb"], {null: true} + , ["/a", "/b/b", "/a/b/c", "bb"]] + + , "dots should not match unless requested" + , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] + + // .. and . can only match patterns starting with ., + // even when options.dot is set. + , function () { + files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] + } + , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] + , ["a/*/b", ["a/c/b"], {dot:false}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] + + + // this also tests that changing the options needs + // to change the cache key, even if the pattern is + // the same! + , ["**", ["a/b","a/.d",".a/.d"], { dot: true } + , [ ".a/.d", "a/.d", "a/b"]] + + , "paren sets cannot contain slashes" + , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] + + // brace sets trump all else. + // + // invalid glob pattern. fails on bash4 and bsdglob. + // however, in this implementation, it's easier just + // to do the intuitive thing, and let brace-expansion + // actually come before parsing any extglob patterns, + // like the documentation seems to say. + // + // XXX: if anyone complains about this, either fix it + // or tell them to grow up and stop complaining. + // + // bash/bsdglob says this: + // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] + // but we do this instead: + , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] + + // test partial parsing in the presence of comment/negation chars + , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] + , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] + + // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. + , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] + , {} + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] + + + // crazy nested {,,} and *(||) tests. + , function () { + files = [ "a", "b", "c", "d" + , "ab", "ac", "ad" + , "bc", "cb" + , "bc,d", "c,db", "c,d" + , "d)", "(b|c", "*(b|c" + , "b|c", "b|cc", "cb|c" + , "x(a|b|c)", "x(a|c)" + , "(a|b|c)", "(a|c)"] + } + , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] + , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] + // a + // *(b|c) + // *(b|d) + , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] + , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] + + + // test various flag settings. + , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] + , { noext: true } ] + , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} + , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] + , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] + + + // begin channelling Boole and deMorgan... + , "negation tests" + , function () { + files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] + } + + // anything that is NOT a* matches. + , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] + + // anything that IS !a* matches. + , ["!a*", ["!ab", "!abc"], {nonegate: true}] + + // anything that IS a* matches + , ["!!a*", ["a!b"]] + + // anything that is NOT !a* matches + , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] + + // negation nestled within a pattern + , function () { + files = [ "foo.js" + , "foo.bar" + // can't match this one without negative lookbehind. + , "foo.js.js" + , "blar.js" + , "foo." + , "boo.js.boo" ] + } + , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] + + // https://github.com/isaacs/minimatch/issues/5 + , function () { + files = [ 'a/b/.x/c' + , 'a/b/.x/c/d' + , 'a/b/.x/c/d/e' + , 'a/b/.x' + , 'a/b/.x/' + , 'a/.x/b' + , '.x' + , '.x/' + , '.x/a' + , '.x/a/b' + , 'a/.x/b/.x/c' + , '.x/.x' ] + } + , ["**/.x/**", [ '.x/' + , '.x/a' + , '.x/a/b' + , 'a/.x/b' + , 'a/b/.x/' + , 'a/b/.x/c' + , 'a/b/.x/c/d' + , 'a/b/.x/c/d/e' ] ] + + ] + +var regexps = + [ '/^(?:(?=.)a[^/]*?)$/', + '/^(?:(?=.)X[^/]*?)$/', + '/^(?:(?=.)X[^/]*?)$/', + '/^(?:\\*)$/', + '/^(?:(?=.)\\*[^/]*?)$/', + '/^(?:\\*\\*)$/', + '/^(?:(?=.)b[^/]*?\\/)$/', + '/^(?:(?=.)c[^/]*?)$/', + '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/', + '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/', + '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/', + '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/', + '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/', + '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/', + '/^(?:(?=.)a[^/]*?[^c])$/', + '/^(?:(?=.)a[X-]b)$/', + '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/', + '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/', + '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/', + '/^(?:(?=.)a[b]c)$/', + '/^(?:(?=.)a[b]c)$/', + '/^(?:(?=.)a[^/]c)$/', + '/^(?:a\\*c)$/', + 'false', + '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/', + '/^(?:man\\/man1\\/bash\\.1)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/', + '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/', + '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', + '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[-abc])$/', + '/^(?:(?!\\.)(?=.)[abc-])$/', + '/^(?:\\\\)$/', + '/^(?:(?!\\.)(?=.)[\\\\])$/', + '/^(?:(?!\\.)(?=.)[\\[])$/', + '/^(?:\\[)$/', + '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[\\]])$/', + '/^(?:(?!\\.)(?=.)[\\]-])$/', + '/^(?:(?!\\.)(?=.)[a-z])$/', + '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', + '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/', + '/^(?:\\[\\])$/', + '/^(?:\\[abc)$/', + '/^(?:(?=.)XYZ)$/i', + '/^(?:(?=.)ab[^/]*?)$/i', + '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i', + '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/', + '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/', + '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/', + '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/', + '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/', + '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/', + '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/', + '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/', + '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/', + '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/', + '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/', + '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/', + '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/', + '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/', + '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/', + '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/', + '/^(?:(?=.)a[^/]b)$/', + '/^(?:(?=.)#[^/]*?)$/', + '/^(?!^(?:(?=.)a[^/]*?)$).*$/', + '/^(?:(?=.)\\!a[^/]*?)$/', + '/^(?:(?=.)a[^/]*?)$/', + '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/', + '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ] +var re = 0; + +tap.test("basic tests", function (t) { + var start = Date.now() + + // [ pattern, [matches], MM opts, files, TAP opts] + patterns.forEach(function (c) { + if (typeof c === "function") return c() + if (typeof c === "string") return t.comment(c) + + var pattern = c[0] + , expect = c[1].sort(alpha) + , options = c[2] || {} + , f = c[3] || files + , tapOpts = c[4] || {} + + // options.debug = true + var m = new mm.Minimatch(pattern, options) + var r = m.makeRe() + var expectRe = regexps[re++] + tapOpts.re = String(r) || JSON.stringify(r) + tapOpts.files = JSON.stringify(f) + tapOpts.pattern = pattern + tapOpts.set = m.set + tapOpts.negated = m.negate + + var actual = mm.match(f, pattern, options) + actual.sort(alpha) + + t.equivalent( actual, expect + , JSON.stringify(pattern) + " " + JSON.stringify(expect) + , tapOpts ) + + t.equal(tapOpts.re, expectRe, tapOpts) + }) + + t.comment("time=" + (Date.now() - start) + "ms") + t.end() +}) + +tap.test("global leak test", function (t) { + var globalAfter = Object.keys(global) + t.equivalent(globalAfter, globalBefore, "no new globals, please") + t.end() +}) + +function alpha (a, b) { + return a > b ? 1 : -1 +} diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/brace-expand.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/brace-expand.js new file mode 100644 index 0000000..7ee278a --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/brace-expand.js @@ -0,0 +1,33 @@ +var tap = require("tap") + , minimatch = require("../") + +tap.test("brace expansion", function (t) { + // [ pattern, [expanded] ] + ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}" + , [ "abxy" + , "abxz" + , "acdxy" + , "acdxz" + , "acexy" + , "acexz" + , "afhxy" + , "afhxz" + , "aghxy" + , "aghxz" ] ] + , [ "a{1..5}b" + , [ "a1b" + , "a2b" + , "a3b" + , "a4b" + , "a5b" ] ] + , [ "a{b}c", ["a{b}c"] ] + ].forEach(function (tc) { + var p = tc[0] + , expect = tc[1] + t.equivalent(minimatch.braceExpand(p), expect, p) + }) + console.error("ending") + t.end() +}) + + diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/caching.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/caching.js new file mode 100644 index 0000000..0fec4b0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/caching.js @@ -0,0 +1,14 @@ +var Minimatch = require("../minimatch.js").Minimatch +var tap = require("tap") +tap.test("cache test", function (t) { + var mm1 = new Minimatch("a?b") + var mm2 = new Minimatch("a?b") + t.equal(mm1, mm2, "should get the same object") + // the lru should drop it after 100 entries + for (var i = 0; i < 100; i ++) { + new Minimatch("a"+i) + } + mm2 = new Minimatch("a?b") + t.notEqual(mm1, mm2, "cache should have dropped") + t.end() +}) diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/defaults.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/defaults.js new file mode 100644 index 0000000..75e0571 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/defaults.js @@ -0,0 +1,274 @@ +// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test +// +// TODO: Some of these tests do very bad things with backslashes, and will +// most likely fail badly on windows. They should probably be skipped. + +var tap = require("tap") + , globalBefore = Object.keys(global) + , mm = require("../") + , files = [ "a", "b", "c", "d", "abc" + , "abd", "abe", "bb", "bcd" + , "ca", "cb", "dd", "de" + , "bdir/", "bdir/cfile"] + , next = files.concat([ "a-b", "aXb" + , ".x", ".y" ]) + +tap.test("basic tests", function (t) { + var start = Date.now() + + // [ pattern, [matches], MM opts, files, TAP opts] + ; [ "http://www.bashcookbook.com/bashinfo" + + "/source/bash-1.14.7/tests/glob-test" + , ["a*", ["a", "abc", "abd", "abe"]] + , ["X*", ["X*"], {nonull: true}] + + // allow null glob expansion + , ["X*", []] + + // isaacs: Slightly different than bash/sh/ksh + // \\* is not un-escaped to literal "*" in a failed match, + // but it does make it get treated as a literal star + , ["\\*", ["\\*"], {nonull: true}] + , ["\\**", ["\\**"], {nonull: true}] + , ["\\*\\*", ["\\*\\*"], {nonull: true}] + + , ["b*/", ["bdir/"]] + , ["c*", ["c", "ca", "cb"]] + , ["**", files] + + , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] + , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] + + , "legendary larry crashes bashes" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] + + , "character classes" + , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] + , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", + "bdir/", "ca", "cb", "dd", "de"]] + , ["a*[^c]", ["abd", "abe"]] + , function () { files.push("a-b", "aXb") } + , ["a[X-]b", ["a-b", "aXb"]] + , function () { files.push(".x", ".y") } + , ["[^a-c]*", ["d", "dd", "de"]] + , function () { files.push("a*b/", "a*b/ooo") } + , ["a\\*b/*", ["a*b/ooo"]] + , ["a\\*?/*", ["a*b/ooo"]] + , ["*\\\\!*", [], {null: true}, ["echo !7"]] + , ["*\\!*", ["echo !7"], null, ["echo !7"]] + , ["*.\\*", ["r.*"], null, ["r.*"]] + , ["a[b]c", ["abc"]] + , ["a[\\b]c", ["abc"]] + , ["a?c", ["abc"]] + , ["a\\*c", [], {null: true}, ["abc"]] + , ["", [""], { null: true }, [""]] + + , "http://www.opensource.apple.com/source/bash/bash-23/" + + "bash/tests/glob-test" + , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } + , ["*/man*/bash.*", ["man/man1/bash.1"]] + , ["man/man1/bash.1", ["man/man1/bash.1"]] + , ["a***c", ["abc"], null, ["abc"]] + , ["a*****?c", ["abc"], null, ["abc"]] + , ["?*****??", ["abc"], null, ["abc"]] + , ["*****??", ["abc"], null, ["abc"]] + , ["?*****?c", ["abc"], null, ["abc"]] + , ["?***?****c", ["abc"], null, ["abc"]] + , ["?***?****?", ["abc"], null, ["abc"]] + , ["?***?****", ["abc"], null, ["abc"]] + , ["*******c", ["abc"], null, ["abc"]] + , ["*******?", ["abc"], null, ["abc"]] + , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["[-abc]", ["-"], null, ["-"]] + , ["[abc-]", ["-"], null, ["-"]] + , ["\\", ["\\"], null, ["\\"]] + , ["[\\\\]", ["\\"], null, ["\\"]] + , ["[[]", ["["], null, ["["]] + , ["[", ["["], null, ["["]] + , ["[*", ["[abc"], null, ["[abc"]] + , "a right bracket shall lose its special meaning and\n" + + "represent itself in a bracket expression if it occurs\n" + + "first in the list. -- POSIX.2 2.8.3.2" + , ["[]]", ["]"], null, ["]"]] + , ["[]-]", ["]"], null, ["]"]] + , ["[a-\z]", ["p"], null, ["p"]] + , ["??**********?****?", [], { null: true }, ["abc"]] + , ["??**********?****c", [], { null: true }, ["abc"]] + , ["?************c****?****", [], { null: true }, ["abc"]] + , ["*c*?**", [], { null: true }, ["abc"]] + , ["a*****c*?**", [], { null: true }, ["abc"]] + , ["a********???*******", [], { null: true }, ["abc"]] + , ["[]", [], { null: true }, ["a"]] + , ["[abc", [], { null: true }, ["["]] + + , "nocase tests" + , ["XYZ", ["xYz"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["ab*", ["ABC"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + + // [ pattern, [matches], MM opts, files, TAP opts] + , "onestar/twostar" + , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] + , ["{/?,*}", ["/a", "bb"], {null: true} + , ["/a", "/b/b", "/a/b/c", "bb"]] + + , "dots should not match unless requested" + , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] + + // .. and . can only match patterns starting with ., + // even when options.dot is set. + , function () { + files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] + } + , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] + , ["a/*/b", ["a/c/b"], {dot:false}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] + + + // this also tests that changing the options needs + // to change the cache key, even if the pattern is + // the same! + , ["**", ["a/b","a/.d",".a/.d"], { dot: true } + , [ ".a/.d", "a/.d", "a/b"]] + + , "paren sets cannot contain slashes" + , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] + + // brace sets trump all else. + // + // invalid glob pattern. fails on bash4 and bsdglob. + // however, in this implementation, it's easier just + // to do the intuitive thing, and let brace-expansion + // actually come before parsing any extglob patterns, + // like the documentation seems to say. + // + // XXX: if anyone complains about this, either fix it + // or tell them to grow up and stop complaining. + // + // bash/bsdglob says this: + // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] + // but we do this instead: + , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] + + // test partial parsing in the presence of comment/negation chars + , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] + , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] + + // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. + , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] + , {} + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] + + + // crazy nested {,,} and *(||) tests. + , function () { + files = [ "a", "b", "c", "d" + , "ab", "ac", "ad" + , "bc", "cb" + , "bc,d", "c,db", "c,d" + , "d)", "(b|c", "*(b|c" + , "b|c", "b|cc", "cb|c" + , "x(a|b|c)", "x(a|c)" + , "(a|b|c)", "(a|c)"] + } + , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] + , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] + // a + // *(b|c) + // *(b|d) + , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] + , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] + + + // test various flag settings. + , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] + , { noext: true } ] + , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} + , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] + , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] + + + // begin channelling Boole and deMorgan... + , "negation tests" + , function () { + files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] + } + + // anything that is NOT a* matches. + , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] + + // anything that IS !a* matches. + , ["!a*", ["!ab", "!abc"], {nonegate: true}] + + // anything that IS a* matches + , ["!!a*", ["a!b"]] + + // anything that is NOT !a* matches + , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] + + // negation nestled within a pattern + , function () { + files = [ "foo.js" + , "foo.bar" + // can't match this one without negative lookbehind. + , "foo.js.js" + , "blar.js" + , "foo." + , "boo.js.boo" ] + } + , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] + + ].forEach(function (c) { + if (typeof c === "function") return c() + if (typeof c === "string") return t.comment(c) + + var pattern = c[0] + , expect = c[1].sort(alpha) + , options = c[2] + , f = c[3] || files + , tapOpts = c[4] || {} + + // options.debug = true + var Class = mm.defaults(options).Minimatch + var m = new Class(pattern, {}) + var r = m.makeRe() + tapOpts.re = String(r) || JSON.stringify(r) + tapOpts.files = JSON.stringify(f) + tapOpts.pattern = pattern + tapOpts.set = m.set + tapOpts.negated = m.negate + + var actual = mm.match(f, pattern, options) + actual.sort(alpha) + + t.equivalent( actual, expect + , JSON.stringify(pattern) + " " + JSON.stringify(expect) + , tapOpts ) + }) + + t.comment("time=" + (Date.now() - start) + "ms") + t.end() +}) + +tap.test("global leak test", function (t) { + var globalAfter = Object.keys(global) + t.equivalent(globalAfter, globalBefore, "no new globals, please") + t.end() +}) + +function alpha (a, b) { + return a > b ? 1 : -1 +} diff --git a/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/extglob-ending-with-state-char.js b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/extglob-ending-with-state-char.js new file mode 100644 index 0000000..6676e26 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/node_modules/minimatch/test/extglob-ending-with-state-char.js @@ -0,0 +1,8 @@ +var test = require('tap').test +var minimatch = require('../') + +test('extglob ending with statechar', function(t) { + t.notOk(minimatch('ax', 'a?(b*)')) + t.ok(minimatch('ax', '?(a*|b)')) + t.end() +}) diff --git a/platforms/android/assets/www/node_modules/jasmine/package.json b/platforms/android/assets/www/node_modules/jasmine/package.json new file mode 100644 index 0000000..5b20c3a --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + "jasmine", + "/Users/adamdon/Desktop/studywell/studywell/sw/www" + ] + ], + "_from": "jasmine@latest", + "_id": "jasmine@2.4.1", + "_inCache": true, + "_installable": true, + "_location": "/jasmine", + "_nodeVersion": "0.12.7", + "_npmUser": { + "email": "gregg@slackersoft.net", + "name": "slackersoft" + }, + "_npmVersion": "2.12.1", + "_phantomChildren": { + "inherits": "2.0.1", + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + }, + "_requested": { + "name": "jasmine", + "raw": "jasmine", + "rawSpec": "", + "scope": null, + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.4.1.tgz", + "_shasum": "9016dda453213d27ac6d43dc4ea97315a189085e", + "_shrinkwrap": null, + "_spec": "jasmine", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www", + "bin": { + "jasmine": "./bin/jasmine.js" + }, + "bugs": { + "url": "https://github.com/jasmine/jasmine-npm/issues" + }, + "dependencies": { + "exit": "^0.1.2", + "glob": "^3.2.11", + "jasmine-core": "~2.4.0" + }, + "description": "Command line jasmine", + "devDependencies": { + "grunt": "^0.4.2", + "grunt-cli": "^0.1.13", + "grunt-contrib-jshint": "^0.11.0", + "shelljs": "^0.3.0" + }, + "directories": {}, + "dist": { + "shasum": "9016dda453213d27ac6d43dc4ea97315a189085e", + "tarball": "http://registry.npmjs.org/jasmine/-/jasmine-2.4.1.tgz" + }, + "gitHead": "17344da242f81c61e4d19a895960bf9414fae07d", + "homepage": "http://jasmine.github.io/", + "keywords": [ + "test", + "jasmine", + "tdd", + "bdd" + ], + "license": "MIT", + "main": "./lib/jasmine.js", + "maintainers": [ + { + "email": "gregg@slackersoft.net", + "name": "slackersoft" + }, + { + "email": "dwfrank@pivotallabs.com", + "name": "dwfrank" + }, + { + "email": "chris.amavisca@gmail.com", + "name": "amavisca" + } + ], + "name": "jasmine", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jasmine/jasmine-npm.git" + }, + "scripts": { + "test": "grunt && ./bin/jasmine.js" + }, + "version": "2.4.1" +} diff --git a/platforms/android/assets/www/node_modules/jasmine/tasks/jasmine.js b/platforms/android/assets/www/node_modules/jasmine/tasks/jasmine.js new file mode 100644 index 0000000..b137c18 --- /dev/null +++ b/platforms/android/assets/www/node_modules/jasmine/tasks/jasmine.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = function(grunt) { + var Jasmine = require('../lib/jasmine'); + + grunt.registerTask('specs', function() { + var jasmine = new Jasmine(); + var done = this.async(); + + jasmine.loadConfigFile(process.env.JASMINE_CONFIG_PATH || './spec/support/jasmine.json'); + jasmine.onComplete(done); + jasmine.execute(); + }); +}; diff --git a/platforms/android/assets/www/node_modules/lodash/LICENSE b/platforms/android/assets/www/node_modules/lodash/LICENSE new file mode 100644 index 0000000..bcbe13d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright 2012-2016 The Dojo Foundation +Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/lodash/README.md b/platforms/android/assets/www/node_modules/lodash/README.md new file mode 100644 index 0000000..56a419b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/README.md @@ -0,0 +1,40 @@ +# lodash v4.6.1 + +The [lodash](https://lodash.com/) library exported as [Node.js](https://nodejs.org/) modules. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash +``` + +In Node.js: +```js +// Load the full build. +var _ = require('lodash'); +// Load the core build. +var _ = require('lodash/core'); +// Load the fp build for immutable auto-curried iteratee-first data-last methods. +var _ = require('lodash/fp'); + +// Load a method category. +var array = require('lodash/array'); +var object = require('lodash/fp/object'); + +// Load a single method for smaller builds with browserify/rollup/webpack. +var chunk = require('lodash/chunk'); +var extend = require('lodash/fp/extend'); +``` + +See the [package source](https://github.com/lodash/lodash/tree/4.6.1-npm) for more details. + +**Note:**
+Don’t assign values to the [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL.
+Install [n_](https://www.npmjs.com/package/n_) for a REPL that includes lodash by default. + +## Support + +Tested in Chrome 47-48, Firefox 43-44, IE 9-11, Edge 13, Safari 8-9, Node.js 0.10, 0.12, 4, & 5, & PhantomJS 1.9.8.
+Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available. diff --git a/platforms/android/assets/www/node_modules/lodash/_Hash.js b/platforms/android/assets/www/node_modules/lodash/_Hash.js new file mode 100644 index 0000000..8647d16 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_Hash.js @@ -0,0 +1,18 @@ +var nativeCreate = require('./_nativeCreate'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Creates an hash object. + * + * @private + * @constructor + * @returns {Object} Returns the new hash object. + */ +function Hash() {} + +// Avoid inheriting from `Object.prototype` when possible. +Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto; + +module.exports = Hash; diff --git a/platforms/android/assets/www/node_modules/lodash/_LazyWrapper.js b/platforms/android/assets/www/node_modules/lodash/_LazyWrapper.js new file mode 100644 index 0000000..ad01ef8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_LazyWrapper.js @@ -0,0 +1,27 @@ +var baseCreate = require('./_baseCreate'), + baseLodash = require('./_baseLodash'); + +/** Used as references for the maximum length and index of an array. */ +var MAX_ARRAY_LENGTH = 4294967295; + +/** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @constructor + * @param {*} value The value to wrap. + */ +function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = MAX_ARRAY_LENGTH; + this.__views__ = []; +} + +LazyWrapper.prototype = baseCreate(baseLodash.prototype); +LazyWrapper.prototype.constructor = LazyWrapper; + +module.exports = LazyWrapper; diff --git a/platforms/android/assets/www/node_modules/lodash/_LodashWrapper.js b/platforms/android/assets/www/node_modules/lodash/_LodashWrapper.js new file mode 100644 index 0000000..7c255b2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_LodashWrapper.js @@ -0,0 +1,22 @@ +var baseCreate = require('./_baseCreate'), + baseLodash = require('./_baseLodash'); + +/** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + */ +function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined; +} + +LodashWrapper.prototype = baseCreate(baseLodash.prototype); +LodashWrapper.prototype.constructor = LodashWrapper; + +module.exports = LodashWrapper; diff --git a/platforms/android/assets/www/node_modules/lodash/_Map.js b/platforms/android/assets/www/node_modules/lodash/_Map.js new file mode 100644 index 0000000..b73f29a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_Map.js @@ -0,0 +1,7 @@ +var getNative = require('./_getNative'), + root = require('./_root'); + +/* Built-in method references that are verified to be native. */ +var Map = getNative(root, 'Map'); + +module.exports = Map; diff --git a/platforms/android/assets/www/node_modules/lodash/_MapCache.js b/platforms/android/assets/www/node_modules/lodash/_MapCache.js new file mode 100644 index 0000000..2652843 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_MapCache.js @@ -0,0 +1,32 @@ +var mapClear = require('./_mapClear'), + mapDelete = require('./_mapDelete'), + mapGet = require('./_mapGet'), + mapHas = require('./_mapHas'), + mapSet = require('./_mapSet'); + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function MapCache(values) { + var index = -1, + length = values ? values.length : 0; + + this.clear(); + while (++index < length) { + var entry = values[index]; + this.set(entry[0], entry[1]); + } +} + +// Add functions to the `MapCache`. +MapCache.prototype.clear = mapClear; +MapCache.prototype['delete'] = mapDelete; +MapCache.prototype.get = mapGet; +MapCache.prototype.has = mapHas; +MapCache.prototype.set = mapSet; + +module.exports = MapCache; diff --git a/platforms/android/assets/www/node_modules/lodash/_Reflect.js b/platforms/android/assets/www/node_modules/lodash/_Reflect.js new file mode 100644 index 0000000..1de7475 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_Reflect.js @@ -0,0 +1,6 @@ +var root = require('./_root'); + +/** Built-in value references. */ +var Reflect = root.Reflect; + +module.exports = Reflect; diff --git a/platforms/android/assets/www/node_modules/lodash/_Set.js b/platforms/android/assets/www/node_modules/lodash/_Set.js new file mode 100644 index 0000000..b3c8dcb --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_Set.js @@ -0,0 +1,7 @@ +var getNative = require('./_getNative'), + root = require('./_root'); + +/* Built-in method references that are verified to be native. */ +var Set = getNative(root, 'Set'); + +module.exports = Set; diff --git a/platforms/android/assets/www/node_modules/lodash/_SetCache.js b/platforms/android/assets/www/node_modules/lodash/_SetCache.js new file mode 100644 index 0000000..5d9d620 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_SetCache.js @@ -0,0 +1,25 @@ +var MapCache = require('./_MapCache'), + cachePush = require('./_cachePush'); + +/** + * + * Creates a set cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values ? values.length : 0; + + this.__data__ = new MapCache; + while (++index < length) { + this.push(values[index]); + } +} + +// Add functions to the `SetCache`. +SetCache.prototype.push = cachePush; + +module.exports = SetCache; diff --git a/platforms/android/assets/www/node_modules/lodash/_Stack.js b/platforms/android/assets/www/node_modules/lodash/_Stack.js new file mode 100644 index 0000000..345577e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_Stack.js @@ -0,0 +1,32 @@ +var stackClear = require('./_stackClear'), + stackDelete = require('./_stackDelete'), + stackGet = require('./_stackGet'), + stackHas = require('./_stackHas'), + stackSet = require('./_stackSet'); + +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function Stack(values) { + var index = -1, + length = values ? values.length : 0; + + this.clear(); + while (++index < length) { + var entry = values[index]; + this.set(entry[0], entry[1]); + } +} + +// Add functions to the `Stack` cache. +Stack.prototype.clear = stackClear; +Stack.prototype['delete'] = stackDelete; +Stack.prototype.get = stackGet; +Stack.prototype.has = stackHas; +Stack.prototype.set = stackSet; + +module.exports = Stack; diff --git a/platforms/android/assets/www/node_modules/lodash/_Symbol.js b/platforms/android/assets/www/node_modules/lodash/_Symbol.js new file mode 100644 index 0000000..a013f7c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_Symbol.js @@ -0,0 +1,6 @@ +var root = require('./_root'); + +/** Built-in value references. */ +var Symbol = root.Symbol; + +module.exports = Symbol; diff --git a/platforms/android/assets/www/node_modules/lodash/_Uint8Array.js b/platforms/android/assets/www/node_modules/lodash/_Uint8Array.js new file mode 100644 index 0000000..2fb30e1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_Uint8Array.js @@ -0,0 +1,6 @@ +var root = require('./_root'); + +/** Built-in value references. */ +var Uint8Array = root.Uint8Array; + +module.exports = Uint8Array; diff --git a/platforms/android/assets/www/node_modules/lodash/_WeakMap.js b/platforms/android/assets/www/node_modules/lodash/_WeakMap.js new file mode 100644 index 0000000..567f86c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_WeakMap.js @@ -0,0 +1,7 @@ +var getNative = require('./_getNative'), + root = require('./_root'); + +/* Built-in method references that are verified to be native. */ +var WeakMap = getNative(root, 'WeakMap'); + +module.exports = WeakMap; diff --git a/platforms/android/assets/www/node_modules/lodash/_addMapEntry.js b/platforms/android/assets/www/node_modules/lodash/_addMapEntry.js new file mode 100644 index 0000000..0112ef7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_addMapEntry.js @@ -0,0 +1,15 @@ +/** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ +function addMapEntry(map, pair) { + // Don't return `Map#set` because it doesn't return the map instance in IE 11. + map.set(pair[0], pair[1]); + return map; +} + +module.exports = addMapEntry; diff --git a/platforms/android/assets/www/node_modules/lodash/_addSetEntry.js b/platforms/android/assets/www/node_modules/lodash/_addSetEntry.js new file mode 100644 index 0000000..7b75c13 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_addSetEntry.js @@ -0,0 +1,14 @@ +/** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ +function addSetEntry(set, value) { + set.add(value); + return set; +} + +module.exports = addSetEntry; diff --git a/platforms/android/assets/www/node_modules/lodash/_apply.js b/platforms/android/assets/www/node_modules/lodash/_apply.js new file mode 100644 index 0000000..22d4f8a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_apply.js @@ -0,0 +1,22 @@ +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + var length = args.length; + switch (length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); +} + +module.exports = apply; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayAggregator.js b/platforms/android/assets/www/node_modules/lodash/_arrayAggregator.js new file mode 100644 index 0000000..562eeb3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayAggregator.js @@ -0,0 +1,22 @@ +/** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ +function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); + } + return accumulator; +} + +module.exports = arrayAggregator; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayConcat.js b/platforms/android/assets/www/node_modules/lodash/_arrayConcat.js new file mode 100644 index 0000000..96e7741 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayConcat.js @@ -0,0 +1,25 @@ +/** + * Creates a new array concatenating `array` with `other`. + * + * @private + * @param {Array} array The first array to concatenate. + * @param {Array} other The second array to concatenate. + * @returns {Array} Returns the new concatenated array. + */ +function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; +} + +module.exports = arrayConcat; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayEach.js b/platforms/android/assets/www/node_modules/lodash/_arrayEach.js new file mode 100644 index 0000000..c302e63 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayEach.js @@ -0,0 +1,22 @@ +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +module.exports = arrayEach; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayEachRight.js b/platforms/android/assets/www/node_modules/lodash/_arrayEachRight.js new file mode 100644 index 0000000..5318585 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayEachRight.js @@ -0,0 +1,21 @@ +/** + * A specialized version of `_.forEachRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; +} + +module.exports = arrayEachRight; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayEvery.js b/platforms/android/assets/www/node_modules/lodash/_arrayEvery.js new file mode 100644 index 0000000..d3ba018 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayEvery.js @@ -0,0 +1,22 @@ +/** + * A specialized version of `_.every` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. + */ +function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; +} + +module.exports = arrayEvery; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayFilter.js b/platforms/android/assets/www/node_modules/lodash/_arrayFilter.js new file mode 100644 index 0000000..7b61ba6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayFilter.js @@ -0,0 +1,25 @@ +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +module.exports = arrayFilter; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayIncludes.js b/platforms/android/assets/www/node_modules/lodash/_arrayIncludes.js new file mode 100644 index 0000000..9574f5d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayIncludes.js @@ -0,0 +1,16 @@ +var baseIndexOf = require('./_baseIndexOf'); + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} array The array to search. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + return !!array.length && baseIndexOf(array, value, 0) > -1; +} + +module.exports = arrayIncludes; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayIncludesWith.js b/platforms/android/assets/www/node_modules/lodash/_arrayIncludesWith.js new file mode 100644 index 0000000..88ea237 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayIncludesWith.js @@ -0,0 +1,22 @@ +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to search. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +module.exports = arrayIncludesWith; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayMap.js b/platforms/android/assets/www/node_modules/lodash/_arrayMap.js new file mode 100644 index 0000000..73b29cf --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayMap.js @@ -0,0 +1,21 @@ +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +module.exports = arrayMap; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayPush.js b/platforms/android/assets/www/node_modules/lodash/_arrayPush.js new file mode 100644 index 0000000..7d742b3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayPush.js @@ -0,0 +1,20 @@ +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +module.exports = arrayPush; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayReduce.js b/platforms/android/assets/www/node_modules/lodash/_arrayReduce.js new file mode 100644 index 0000000..6a355bc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayReduce.js @@ -0,0 +1,25 @@ +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +module.exports = arrayReduce; diff --git a/platforms/android/assets/www/node_modules/lodash/_arrayReduceRight.js b/platforms/android/assets/www/node_modules/lodash/_arrayReduceRight.js new file mode 100644 index 0000000..b33a2d0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arrayReduceRight.js @@ -0,0 +1,23 @@ +/** + * A specialized version of `_.reduceRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduceRight(array, iteratee, accumulator, initAccum) { + var length = array.length; + if (initAccum && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; +} + +module.exports = arrayReduceRight; diff --git a/platforms/android/assets/www/node_modules/lodash/_arraySome.js b/platforms/android/assets/www/node_modules/lodash/_arraySome.js new file mode 100644 index 0000000..b93d531 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_arraySome.js @@ -0,0 +1,22 @@ +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +module.exports = arraySome; diff --git a/platforms/android/assets/www/node_modules/lodash/_assignInDefaults.js b/platforms/android/assets/www/node_modules/lodash/_assignInDefaults.js new file mode 100644 index 0000000..ea6b0e3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_assignInDefaults.js @@ -0,0 +1,27 @@ +var eq = require('./eq'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used by `_.defaults` to customize its `_.assignIn` use. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. + */ +function assignInDefaults(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; +} + +module.exports = assignInDefaults; diff --git a/platforms/android/assets/www/node_modules/lodash/_assignMergeValue.js b/platforms/android/assets/www/node_modules/lodash/_assignMergeValue.js new file mode 100644 index 0000000..61dd583 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_assignMergeValue.js @@ -0,0 +1,19 @@ +var eq = require('./eq'); + +/** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (typeof key == 'number' && value === undefined && !(key in object))) { + object[key] = value; + } +} + +module.exports = assignMergeValue; diff --git a/platforms/android/assets/www/node_modules/lodash/_assignValue.js b/platforms/android/assets/www/node_modules/lodash/_assignValue.js new file mode 100644 index 0000000..35d49f0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_assignValue.js @@ -0,0 +1,27 @@ +var eq = require('./eq'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } +} + +module.exports = assignValue; diff --git a/platforms/android/assets/www/node_modules/lodash/_assocDelete.js b/platforms/android/assets/www/node_modules/lodash/_assocDelete.js new file mode 100644 index 0000000..709a04a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_assocDelete.js @@ -0,0 +1,31 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * Removes `key` and its value from the associative array. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function assocDelete(array, key) { + var index = assocIndexOf(array, key); + if (index < 0) { + return false; + } + var lastIndex = array.length - 1; + if (index == lastIndex) { + array.pop(); + } else { + splice.call(array, index, 1); + } + return true; +} + +module.exports = assocDelete; diff --git a/platforms/android/assets/www/node_modules/lodash/_assocGet.js b/platforms/android/assets/www/node_modules/lodash/_assocGet.js new file mode 100644 index 0000000..e53d332 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_assocGet.js @@ -0,0 +1,16 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** + * Gets the associative array value for `key`. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function assocGet(array, key) { + var index = assocIndexOf(array, key); + return index < 0 ? undefined : array[index][1]; +} + +module.exports = assocGet; diff --git a/platforms/android/assets/www/node_modules/lodash/_assocHas.js b/platforms/android/assets/www/node_modules/lodash/_assocHas.js new file mode 100644 index 0000000..a74bd39 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_assocHas.js @@ -0,0 +1,15 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** + * Checks if an associative array value for `key` exists. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function assocHas(array, key) { + return assocIndexOf(array, key) > -1; +} + +module.exports = assocHas; diff --git a/platforms/android/assets/www/node_modules/lodash/_assocIndexOf.js b/platforms/android/assets/www/node_modules/lodash/_assocIndexOf.js new file mode 100644 index 0000000..958c8d8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_assocIndexOf.js @@ -0,0 +1,22 @@ +var eq = require('./eq'); + +/** + * Gets the index at which the first occurrence of `key` is found in `array` + * of key-value pairs. + * + * @private + * @param {Array} array The array to search. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +module.exports = assocIndexOf; diff --git a/platforms/android/assets/www/node_modules/lodash/_assocSet.js b/platforms/android/assets/www/node_modules/lodash/_assocSet.js new file mode 100644 index 0000000..524f341 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_assocSet.js @@ -0,0 +1,20 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** + * Sets the associative array `key` to `value`. + * + * @private + * @param {Array} array The array to modify. + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + */ +function assocSet(array, key, value) { + var index = assocIndexOf(array, key); + if (index < 0) { + array.push([key, value]); + } else { + array[index][1] = value; + } +} + +module.exports = assocSet; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseAggregator.js b/platforms/android/assets/www/node_modules/lodash/_baseAggregator.js new file mode 100644 index 0000000..4bc9e91 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseAggregator.js @@ -0,0 +1,21 @@ +var baseEach = require('./_baseEach'); + +/** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ +function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function(value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; +} + +module.exports = baseAggregator; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseAssign.js b/platforms/android/assets/www/node_modules/lodash/_baseAssign.js new file mode 100644 index 0000000..e5c4a1a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseAssign.js @@ -0,0 +1,17 @@ +var copyObject = require('./_copyObject'), + keys = require('./keys'); + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); +} + +module.exports = baseAssign; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseAt.js b/platforms/android/assets/www/node_modules/lodash/_baseAt.js new file mode 100644 index 0000000..a077cb9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseAt.js @@ -0,0 +1,23 @@ +var get = require('./get'); + +/** + * The base implementation of `_.at` without support for individual paths. + * + * @private + * @param {Object} object The object to iterate over. + * @param {string[]} paths The property paths of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ +function baseAt(object, paths) { + var index = -1, + isNil = object == null, + length = paths.length, + result = Array(length); + + while (++index < length) { + result[index] = isNil ? undefined : get(object, paths[index]); + } + return result; +} + +module.exports = baseAt; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseCastArrayLikeObject.js b/platforms/android/assets/www/node_modules/lodash/_baseCastArrayLikeObject.js new file mode 100644 index 0000000..17c0c86 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseCastArrayLikeObject.js @@ -0,0 +1,14 @@ +var isArrayLikeObject = require('./isArrayLikeObject'); + +/** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ +function baseCastArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; +} + +module.exports = baseCastArrayLikeObject; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseCastFunction.js b/platforms/android/assets/www/node_modules/lodash/_baseCastFunction.js new file mode 100644 index 0000000..b3d0f72 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseCastFunction.js @@ -0,0 +1,14 @@ +var identity = require('./identity'); + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ +function baseCastFunction(value) { + return typeof value == 'function' ? value : identity; +} + +module.exports = baseCastFunction; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseCastPath.js b/platforms/android/assets/www/node_modules/lodash/_baseCastPath.js new file mode 100644 index 0000000..7634e5b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseCastPath.js @@ -0,0 +1,15 @@ +var isArray = require('./isArray'), + stringToPath = require('./_stringToPath'); + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast property path array. + */ +function baseCastPath(value) { + return isArray(value) ? value : stringToPath(value); +} + +module.exports = baseCastPath; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseClamp.js b/platforms/android/assets/www/node_modules/lodash/_baseClamp.js new file mode 100644 index 0000000..ceadeef --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseClamp.js @@ -0,0 +1,22 @@ +/** + * The base implementation of `_.clamp` which doesn't coerce arguments to numbers. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ +function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined) { + number = number <= upper ? number : upper; + } + if (lower !== undefined) { + number = number >= lower ? number : lower; + } + } + return number; +} + +module.exports = baseClamp; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseClone.js b/platforms/android/assets/www/node_modules/lodash/_baseClone.js new file mode 100644 index 0000000..b3f106e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseClone.js @@ -0,0 +1,131 @@ +var Stack = require('./_Stack'), + arrayEach = require('./_arrayEach'), + assignValue = require('./_assignValue'), + baseAssign = require('./_baseAssign'), + baseForOwn = require('./_baseForOwn'), + cloneBuffer = require('./_cloneBuffer'), + copyArray = require('./_copyArray'), + copySymbols = require('./_copySymbols'), + getTag = require('./_getTag'), + initCloneArray = require('./_initCloneArray'), + initCloneByTag = require('./_initCloneByTag'), + initCloneObject = require('./_initCloneObject'), + isArray = require('./isArray'), + isBuffer = require('./isBuffer'), + isHostObject = require('./_isHostObject'), + isObject = require('./isObject'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = +cloneableTags[dateTag] = cloneableTags[float32Tag] = +cloneableTags[float64Tag] = cloneableTags[int8Tag] = +cloneableTags[int16Tag] = cloneableTags[int32Tag] = +cloneableTags[mapTag] = cloneableTags[numberTag] = +cloneableTags[objectTag] = cloneableTags[regexpTag] = +cloneableTags[setTag] = cloneableTags[stringTag] = +cloneableTags[symbolTag] = cloneableTags[uint8Tag] = +cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = +cloneableTags[uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + result = baseAssign(result, value); + return isFull ? copySymbols(value, result) : result; + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return (isFull && !isArr) ? copySymbols(value, result) : result; +} + +module.exports = baseClone; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseConforms.js b/platforms/android/assets/www/node_modules/lodash/_baseConforms.js new file mode 100644 index 0000000..888434d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseConforms.js @@ -0,0 +1,32 @@ +var keys = require('./keys'); + +/** + * The base implementation of `_.conforms` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new function. + */ +function baseConforms(source) { + var props = keys(source), + length = props.length; + + return function(object) { + if (object == null) { + return !length; + } + var index = length; + while (index--) { + var key = props[index], + predicate = source[key], + value = object[key]; + + if ((value === undefined && !(key in Object(object))) || !predicate(value)) { + return false; + } + } + return true; + }; +} + +module.exports = baseConforms; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseCreate.js b/platforms/android/assets/www/node_modules/lodash/_baseCreate.js new file mode 100644 index 0000000..4372cad --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseCreate.js @@ -0,0 +1,18 @@ +var isObject = require('./isObject'); + +/** Built-in value references. */ +var objectCreate = Object.create; + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ +function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; +} + +module.exports = baseCreate; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseDelay.js b/platforms/android/assets/www/node_modules/lodash/_baseDelay.js new file mode 100644 index 0000000..c397562 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseDelay.js @@ -0,0 +1,21 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * The base implementation of `_.delay` and `_.defer` which accepts an array + * of `func` arguments. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments to provide to `func`. + * @returns {number} Returns the timer id. + */ +function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); +} + +module.exports = baseDelay; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseDifference.js b/platforms/android/assets/www/node_modules/lodash/_baseDifference.js new file mode 100644 index 0000000..b266d7e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseDifference.js @@ -0,0 +1,66 @@ +var SetCache = require('./_SetCache'), + arrayIncludes = require('./_arrayIncludes'), + arrayIncludesWith = require('./_arrayIncludesWith'), + arrayMap = require('./_arrayMap'), + baseUnary = require('./_baseUnary'), + cacheHas = require('./_cacheHas'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of methods like `_.difference` without support for + * excluding multiple arrays or iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + */ +function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; + + if (!length) { + return result; + } + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } + else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; + isCommon = false; + values = new SetCache(values); + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (isCommon && computed === computed) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === computed) { + continue outer; + } + } + result.push(value); + } + else if (!includes(values, computed, comparator)) { + result.push(value); + } + } + return result; +} + +module.exports = baseDifference; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseEach.js b/platforms/android/assets/www/node_modules/lodash/_baseEach.js new file mode 100644 index 0000000..512c067 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseEach.js @@ -0,0 +1,14 @@ +var baseForOwn = require('./_baseForOwn'), + createBaseEach = require('./_createBaseEach'); + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = createBaseEach(baseForOwn); + +module.exports = baseEach; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseEachRight.js b/platforms/android/assets/www/node_modules/lodash/_baseEachRight.js new file mode 100644 index 0000000..0a8feec --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseEachRight.js @@ -0,0 +1,14 @@ +var baseForOwnRight = require('./_baseForOwnRight'), + createBaseEach = require('./_createBaseEach'); + +/** + * The base implementation of `_.forEachRight` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEachRight = createBaseEach(baseForOwnRight, true); + +module.exports = baseEachRight; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseEvery.js b/platforms/android/assets/www/node_modules/lodash/_baseEvery.js new file mode 100644 index 0000000..aafa00d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseEvery.js @@ -0,0 +1,20 @@ +var baseEach = require('./_baseEach'); + +/** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false` + */ +function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; +} + +module.exports = baseEvery; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseExtremum.js b/platforms/android/assets/www/node_modules/lodash/_baseExtremum.js new file mode 100644 index 0000000..c6cb804 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseExtremum.js @@ -0,0 +1,30 @@ +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? current === current + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +module.exports = baseExtremum; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseFill.js b/platforms/android/assets/www/node_modules/lodash/_baseFill.js new file mode 100644 index 0000000..46ef9c7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseFill.js @@ -0,0 +1,32 @@ +var toInteger = require('./toInteger'), + toLength = require('./toLength'); + +/** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ +function baseFill(array, value, start, end) { + var length = array.length; + + start = toInteger(start); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : toInteger(end); + if (end < 0) { + end += length; + } + end = start > end ? 0 : toLength(end); + while (start < end) { + array[start++] = value; + } + return array; +} + +module.exports = baseFill; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseFilter.js b/platforms/android/assets/www/node_modules/lodash/_baseFilter.js new file mode 100644 index 0000000..4678477 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseFilter.js @@ -0,0 +1,21 @@ +var baseEach = require('./_baseEach'); + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +module.exports = baseFilter; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseFind.js b/platforms/android/assets/www/node_modules/lodash/_baseFind.js new file mode 100644 index 0000000..535f7f3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseFind.js @@ -0,0 +1,24 @@ +/** + * The base implementation of methods like `_.find` and `_.findKey`, without + * support for iteratee shorthands, which iterates over `collection` using + * `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ +function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; +} + +module.exports = baseFind; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseFindIndex.js b/platforms/android/assets/www/node_modules/lodash/_baseFindIndex.js new file mode 100644 index 0000000..61428f6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseFindIndex.js @@ -0,0 +1,23 @@ +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +module.exports = baseFindIndex; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseFlatten.js b/platforms/android/assets/www/node_modules/lodash/_baseFlatten.js new file mode 100644 index 0000000..7d024dd --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseFlatten.js @@ -0,0 +1,39 @@ +var arrayPush = require('./_arrayPush'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isArrayLikeObject = require('./isArrayLikeObject'); + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, isStrict, result) { + result || (result = []); + + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + if (depth > 0 && isArrayLikeObject(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +module.exports = baseFlatten; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseFor.js b/platforms/android/assets/www/node_modules/lodash/_baseFor.js new file mode 100644 index 0000000..97b70c9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseFor.js @@ -0,0 +1,17 @@ +var createBaseFor = require('./_createBaseFor'); + +/** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ +var baseFor = createBaseFor(); + +module.exports = baseFor; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseForIn.js b/platforms/android/assets/www/node_modules/lodash/_baseForIn.js new file mode 100644 index 0000000..4dcfdaf --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseForIn.js @@ -0,0 +1,16 @@ +var baseFor = require('./_baseFor'), + keysIn = require('./keysIn'); + +/** + * The base implementation of `_.forIn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForIn(object, iteratee) { + return object == null ? object : baseFor(object, iteratee, keysIn); +} + +module.exports = baseForIn; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseForOwn.js b/platforms/android/assets/www/node_modules/lodash/_baseForOwn.js new file mode 100644 index 0000000..503d523 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseForOwn.js @@ -0,0 +1,16 @@ +var baseFor = require('./_baseFor'), + keys = require('./keys'); + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); +} + +module.exports = baseForOwn; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseForOwnRight.js b/platforms/android/assets/www/node_modules/lodash/_baseForOwnRight.js new file mode 100644 index 0000000..a4b10e6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseForOwnRight.js @@ -0,0 +1,16 @@ +var baseForRight = require('./_baseForRight'), + keys = require('./keys'); + +/** + * The base implementation of `_.forOwnRight` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwnRight(object, iteratee) { + return object && baseForRight(object, iteratee, keys); +} + +module.exports = baseForOwnRight; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseForRight.js b/platforms/android/assets/www/node_modules/lodash/_baseForRight.js new file mode 100644 index 0000000..32842cd --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseForRight.js @@ -0,0 +1,15 @@ +var createBaseFor = require('./_createBaseFor'); + +/** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ +var baseForRight = createBaseFor(true); + +module.exports = baseForRight; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseFunctions.js b/platforms/android/assets/www/node_modules/lodash/_baseFunctions.js new file mode 100644 index 0000000..6e1090f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseFunctions.js @@ -0,0 +1,19 @@ +var arrayFilter = require('./_arrayFilter'), + isFunction = require('./isFunction'); + +/** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ +function baseFunctions(object, props) { + return arrayFilter(props, function(key) { + return isFunction(object[key]); + }); +} + +module.exports = baseFunctions; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseGet.js b/platforms/android/assets/www/node_modules/lodash/_baseGet.js new file mode 100644 index 0000000..ef9623a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseGet.js @@ -0,0 +1,24 @@ +var baseCastPath = require('./_baseCastPath'), + isKey = require('./_isKey'); + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[path[index++]]; + } + return (index && index == length) ? object : undefined; +} + +module.exports = baseGet; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseHas.js b/platforms/android/assets/www/node_modules/lodash/_baseHas.js new file mode 100644 index 0000000..b393206 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseHas.js @@ -0,0 +1,26 @@ +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Built-in value references. */ +var getPrototypeOf = Object.getPrototypeOf; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`, + // that are composed entirely of index properties, return `false` for + // `hasOwnProperty` checks of them. + return hasOwnProperty.call(object, key) || + (typeof object == 'object' && key in object && getPrototypeOf(object) === null); +} + +module.exports = baseHas; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseHasIn.js b/platforms/android/assets/www/node_modules/lodash/_baseHasIn.js new file mode 100644 index 0000000..4a36558 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseHasIn.js @@ -0,0 +1,13 @@ +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return key in Object(object); +} + +module.exports = baseHasIn; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseInRange.js b/platforms/android/assets/www/node_modules/lodash/_baseInRange.js new file mode 100644 index 0000000..16d53f2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseInRange.js @@ -0,0 +1,18 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * The base implementation of `_.inRange` which doesn't coerce arguments to numbers. + * + * @private + * @param {number} number The number to check. + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + */ +function baseInRange(number, start, end) { + return number >= nativeMin(start, end) && number < nativeMax(start, end); +} + +module.exports = baseInRange; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseIndexOf.js b/platforms/android/assets/www/node_modules/lodash/_baseIndexOf.js new file mode 100644 index 0000000..6cda802 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseIndexOf.js @@ -0,0 +1,27 @@ +var indexOfNaN = require('./_indexOfNaN'); + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); + } + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +module.exports = baseIndexOf; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseIndexOfWith.js b/platforms/android/assets/www/node_modules/lodash/_baseIndexOfWith.js new file mode 100644 index 0000000..8be568a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseIndexOfWith.js @@ -0,0 +1,23 @@ +/** + * This function is like `baseIndexOf` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @param {Function} comparator The comparator invoked per element. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOfWith(array, value, fromIndex, comparator) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (comparator(array[index], value)) { + return index; + } + } + return -1; +} + +module.exports = baseIndexOfWith; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseIntersection.js b/platforms/android/assets/www/node_modules/lodash/_baseIntersection.js new file mode 100644 index 0000000..7d12926 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseIntersection.js @@ -0,0 +1,73 @@ +var SetCache = require('./_SetCache'), + arrayIncludes = require('./_arrayIncludes'), + arrayIncludesWith = require('./_arrayIncludesWith'), + arrayMap = require('./_arrayMap'), + baseUnary = require('./_baseUnary'), + cacheHas = require('./_cacheHas'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ +function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + maxLength = Infinity, + result = []; + + while (othIndex--) { + var array = arrays[othIndex]; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) + ? new SetCache(othIndex && array) + : undefined; + } + array = arrays[0]; + + var index = -1, + seen = caches[0]; + + outer: + while (++index < length && result.length < maxLength) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { + othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { + continue outer; + } + } + if (seen) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +module.exports = baseIntersection; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseInverter.js b/platforms/android/assets/www/node_modules/lodash/_baseInverter.js new file mode 100644 index 0000000..fbc337f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseInverter.js @@ -0,0 +1,21 @@ +var baseForOwn = require('./_baseForOwn'); + +/** + * The base implementation of `_.invert` and `_.invertBy` which inverts + * `object` with values transformed by `iteratee` and set by `setter`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform values. + * @param {Object} accumulator The initial inverted object. + * @returns {Function} Returns `accumulator`. + */ +function baseInverter(object, setter, iteratee, accumulator) { + baseForOwn(object, function(value, key, object) { + setter(accumulator, iteratee(value), key, object); + }); + return accumulator; +} + +module.exports = baseInverter; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseInvoke.js b/platforms/android/assets/www/node_modules/lodash/_baseInvoke.js new file mode 100644 index 0000000..7a94a3f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseInvoke.js @@ -0,0 +1,27 @@ +var apply = require('./_apply'), + baseCastPath = require('./_baseCastPath'), + isKey = require('./_isKey'), + last = require('./last'), + parent = require('./_parent'); + +/** + * The base implementation of `_.invoke` without support for individual + * method arguments. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ +function baseInvoke(object, path, args) { + if (!isKey(path, object)) { + path = baseCastPath(path); + object = parent(object, path); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : apply(func, object, args); +} + +module.exports = baseInvoke; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseIsEqual.js b/platforms/android/assets/www/node_modules/lodash/_baseIsEqual.js new file mode 100644 index 0000000..3772dab --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseIsEqual.js @@ -0,0 +1,30 @@ +var baseIsEqualDeep = require('./_baseIsEqualDeep'), + isObject = require('./isObject'), + isObjectLike = require('./isObjectLike'); + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @param {boolean} [bitmask] The bitmask of comparison flags. + * The bitmask may be composed of the following flags: + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, customizer, bitmask, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack); +} + +module.exports = baseIsEqual; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseIsEqualDeep.js b/platforms/android/assets/www/node_modules/lodash/_baseIsEqualDeep.js new file mode 100644 index 0000000..50bb411 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseIsEqualDeep.js @@ -0,0 +1,78 @@ +var Stack = require('./_Stack'), + equalArrays = require('./_equalArrays'), + equalByTag = require('./_equalByTag'), + equalObjects = require('./_equalObjects'), + getTag = require('./_getTag'), + isArray = require('./isArray'), + isHostObject = require('./_isHostObject'), + isTypedArray = require('./isTypedArray'); + +/** Used to compose bitmasks for comparison styles. */ +var PARTIAL_COMPARE_FLAG = 2; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparisons. + * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = getTag(object); + objTag = objTag == argsTag ? objectTag : objTag; + } + if (!othIsArr) { + othTag = getTag(other); + othTag = othTag == argsTag ? objectTag : othTag; + } + var objIsObj = objTag == objectTag && !isHostObject(object), + othIsObj = othTag == objectTag && !isHostObject(other), + isSameTag = objTag == othTag; + + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, equalFunc, customizer, bitmask, stack) + : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack); + } + if (!(bitmask & PARTIAL_COMPARE_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + stack || (stack = new Stack); + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, equalFunc, customizer, bitmask, stack); +} + +module.exports = baseIsEqualDeep; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseIsMatch.js b/platforms/android/assets/www/node_modules/lodash/_baseIsMatch.js new file mode 100644 index 0000000..c1dcafc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseIsMatch.js @@ -0,0 +1,61 @@ +var Stack = require('./_Stack'), + baseIsEqual = require('./_baseIsEqual'); + +/** Used to compose bitmasks for comparison styles. */ +var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack, + result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined; + + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) + : result + )) { + return false; + } + } + } + return true; +} + +module.exports = baseIsMatch; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseIteratee.js b/platforms/android/assets/www/node_modules/lodash/_baseIteratee.js new file mode 100644 index 0000000..19531af --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseIteratee.js @@ -0,0 +1,30 @@ +var baseMatches = require('./_baseMatches'), + baseMatchesProperty = require('./_baseMatchesProperty'), + identity = require('./identity'), + isArray = require('./isArray'), + property = require('./property'); + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + var type = typeof value; + if (type == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (type == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); +} + +module.exports = baseIteratee; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseKeys.js b/platforms/android/assets/www/node_modules/lodash/_baseKeys.js new file mode 100644 index 0000000..2c8ccb9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseKeys.js @@ -0,0 +1,16 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeKeys = Object.keys; + +/** + * The base implementation of `_.keys` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + return nativeKeys(Object(object)); +} + +module.exports = baseKeys; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseKeysIn.js b/platforms/android/assets/www/node_modules/lodash/_baseKeysIn.js new file mode 100644 index 0000000..7455fd8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseKeysIn.js @@ -0,0 +1,36 @@ +var Reflect = require('./_Reflect'), + iteratorToArray = require('./_iteratorToArray'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var enumerate = Reflect ? Reflect.enumerate : undefined, + propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** + * The base implementation of `_.keysIn` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeysIn(object) { + object = object == null ? object : Object(object); + + var result = []; + for (var key in object) { + result.push(key); + } + return result; +} + +// Fallback for IE < 9 with es6-shim. +if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) { + baseKeysIn = function(object) { + return iteratorToArray(enumerate(object)); + }; +} + +module.exports = baseKeysIn; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseLodash.js b/platforms/android/assets/www/node_modules/lodash/_baseLodash.js new file mode 100644 index 0000000..15b79d3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseLodash.js @@ -0,0 +1,10 @@ +/** + * The function whose prototype all chaining wrappers inherit from. + * + * @private + */ +function baseLodash() { + // No operation performed. +} + +module.exports = baseLodash; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseMap.js b/platforms/android/assets/www/node_modules/lodash/_baseMap.js new file mode 100644 index 0000000..0bf5cea --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseMap.js @@ -0,0 +1,22 @@ +var baseEach = require('./_baseEach'), + isArrayLike = require('./isArrayLike'); + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +module.exports = baseMap; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseMatches.js b/platforms/android/assets/www/node_modules/lodash/_baseMatches.js new file mode 100644 index 0000000..56c72e6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseMatches.js @@ -0,0 +1,30 @@ +var baseIsMatch = require('./_baseIsMatch'), + getMatchData = require('./_getMatchData'); + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ +function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; + + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && + (value !== undefined || (key in Object(object))); + }; + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; +} + +module.exports = baseMatches; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseMatchesProperty.js b/platforms/android/assets/www/node_modules/lodash/_baseMatchesProperty.js new file mode 100644 index 0000000..256ad65 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseMatchesProperty.js @@ -0,0 +1,26 @@ +var baseIsEqual = require('./_baseIsEqual'), + get = require('./get'), + hasIn = require('./hasIn'); + +/** Used to compose bitmasks for comparison styles. */ +var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new function. + */ +function baseMatchesProperty(path, srcValue) { + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG); + }; +} + +module.exports = baseMatchesProperty; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseMerge.js b/platforms/android/assets/www/node_modules/lodash/_baseMerge.js new file mode 100644 index 0000000..04cda58 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseMerge.js @@ -0,0 +1,50 @@ +var Stack = require('./_Stack'), + arrayEach = require('./_arrayEach'), + assignMergeValue = require('./_assignMergeValue'), + baseMergeDeep = require('./_baseMergeDeep'), + isArray = require('./isArray'), + isObject = require('./isObject'), + isTypedArray = require('./isTypedArray'), + keysIn = require('./keysIn'); + +/** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + */ +function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + var props = (isArray(source) || isTypedArray(source)) + ? undefined + : keysIn(source); + + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; + } + if (isObject(srcValue)) { + stack || (stack = new Stack); + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(object[key], srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }); +} + +module.exports = baseMerge; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseMergeDeep.js b/platforms/android/assets/www/node_modules/lodash/_baseMergeDeep.js new file mode 100644 index 0000000..1b8130a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseMergeDeep.js @@ -0,0 +1,82 @@ +var assignMergeValue = require('./_assignMergeValue'), + baseClone = require('./_baseClone'), + copyArray = require('./_copyArray'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isArrayLikeObject = require('./isArrayLikeObject'), + isFunction = require('./isFunction'), + isObject = require('./isObject'), + isPlainObject = require('./isPlainObject'), + isTypedArray = require('./isTypedArray'), + toPlainObject = require('./toPlainObject'); + +/** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + */ +function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = object[key], + srcValue = source[key], + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + newValue = srcValue; + if (isArray(srcValue) || isTypedArray(srcValue)) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else { + isCommon = false; + newValue = baseClone(srcValue, !customizer); + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { + isCommon = false; + newValue = baseClone(srcValue, !customizer); + } + else { + newValue = objValue; + } + } + else { + isCommon = false; + } + } + stack.set(srcValue, newValue); + + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + } + stack['delete'](srcValue); + assignMergeValue(object, key, newValue); +} + +module.exports = baseMergeDeep; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseOrderBy.js b/platforms/android/assets/www/node_modules/lodash/_baseOrderBy.js new file mode 100644 index 0000000..4dcbe38 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseOrderBy.js @@ -0,0 +1,32 @@ +var arrayMap = require('./_arrayMap'), + baseIteratee = require('./_baseIteratee'), + baseMap = require('./_baseMap'), + baseSortBy = require('./_baseSortBy'), + compareMultiple = require('./_compareMultiple'); + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + var index = -1; + iteratees = arrayMap(iteratees.length ? iteratees : Array(1), baseIteratee); + + var result = baseMap(collection, function(value, key, collection) { + var criteria = arrayMap(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); +} + +module.exports = baseOrderBy; diff --git a/platforms/android/assets/www/node_modules/lodash/_basePick.js b/platforms/android/assets/www/node_modules/lodash/_basePick.js new file mode 100644 index 0000000..e2ce722 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_basePick.js @@ -0,0 +1,22 @@ +var arrayReduce = require('./_arrayReduce'); + +/** + * The base implementation of `_.pick` without support for individual + * property names. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, props) { + object = Object(object); + return arrayReduce(props, function(result, key) { + if (key in object) { + result[key] = object[key]; + } + return result; + }, {}); +} + +module.exports = basePick; diff --git a/platforms/android/assets/www/node_modules/lodash/_basePickBy.js b/platforms/android/assets/www/node_modules/lodash/_basePickBy.js new file mode 100644 index 0000000..37c4943 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_basePickBy.js @@ -0,0 +1,21 @@ +var baseForIn = require('./_baseForIn'); + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, predicate) { + var result = {}; + baseForIn(object, function(value, key) { + if (predicate(value, key)) { + result[key] = value; + } + }); + return result; +} + +module.exports = basePickBy; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseProperty.js b/platforms/android/assets/www/node_modules/lodash/_baseProperty.js new file mode 100644 index 0000000..e515941 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseProperty.js @@ -0,0 +1,14 @@ +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +module.exports = baseProperty; diff --git a/platforms/android/assets/www/node_modules/lodash/_basePropertyDeep.js b/platforms/android/assets/www/node_modules/lodash/_basePropertyDeep.js new file mode 100644 index 0000000..acc2009 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_basePropertyDeep.js @@ -0,0 +1,16 @@ +var baseGet = require('./_baseGet'); + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ +function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; +} + +module.exports = basePropertyDeep; diff --git a/platforms/android/assets/www/node_modules/lodash/_basePullAll.js b/platforms/android/assets/www/node_modules/lodash/_basePullAll.js new file mode 100644 index 0000000..3c07c99 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_basePullAll.js @@ -0,0 +1,47 @@ +var arrayMap = require('./_arrayMap'), + baseIndexOf = require('./_baseIndexOf'), + baseIndexOfWith = require('./_baseIndexOfWith'), + baseUnary = require('./_baseUnary'); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * The base implementation of `_.pullAllBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + */ +function basePullAll(array, values, iteratee, comparator) { + var indexOf = comparator ? baseIndexOfWith : baseIndexOf, + index = -1, + length = values.length, + seen = array; + + if (iteratee) { + seen = arrayMap(array, baseUnary(iteratee)); + } + while (++index < length) { + var fromIndex = 0, + value = values[index], + computed = iteratee ? iteratee(value) : value; + + while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { + if (seen !== array) { + splice.call(seen, fromIndex, 1); + } + splice.call(array, fromIndex, 1); + } + } + return array; +} + +module.exports = basePullAll; diff --git a/platforms/android/assets/www/node_modules/lodash/_basePullAt.js b/platforms/android/assets/www/node_modules/lodash/_basePullAt.js new file mode 100644 index 0000000..eb9ed21 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_basePullAt.js @@ -0,0 +1,49 @@ +var baseCastPath = require('./_baseCastPath'), + isIndex = require('./_isIndex'), + isKey = require('./_isKey'), + last = require('./last'), + parent = require('./_parent'); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * The base implementation of `_.pullAt` without support for individual + * indexes or capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ +function basePullAt(array, indexes) { + var length = array ? indexes.length : 0, + lastIndex = length - 1; + + while (length--) { + var index = indexes[length]; + if (lastIndex == length || index != previous) { + var previous = index; + if (isIndex(index)) { + splice.call(array, index, 1); + } + else if (!isKey(index, array)) { + var path = baseCastPath(index), + object = parent(array, path); + + if (object != null) { + delete object[last(path)]; + } + } + else { + delete array[index]; + } + } + } + return array; +} + +module.exports = basePullAt; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseRandom.js b/platforms/android/assets/www/node_modules/lodash/_baseRandom.js new file mode 100644 index 0000000..94f76a7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseRandom.js @@ -0,0 +1,18 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeFloor = Math.floor, + nativeRandom = Math.random; + +/** + * The base implementation of `_.random` without support for returning + * floating-point numbers. + * + * @private + * @param {number} lower The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the random number. + */ +function baseRandom(lower, upper) { + return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); +} + +module.exports = baseRandom; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseRange.js b/platforms/android/assets/www/node_modules/lodash/_baseRange.js new file mode 100644 index 0000000..2b39dd4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseRange.js @@ -0,0 +1,28 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments to numbers. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the new array of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +module.exports = baseRange; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseReduce.js b/platforms/android/assets/www/node_modules/lodash/_baseReduce.js new file mode 100644 index 0000000..6ec5442 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseReduce.js @@ -0,0 +1,22 @@ +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +module.exports = baseReduce; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseSet.js b/platforms/android/assets/www/node_modules/lodash/_baseSet.js new file mode 100644 index 0000000..0596d89 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseSet.js @@ -0,0 +1,45 @@ +var assignValue = require('./_assignValue'), + baseCastPath = require('./_baseCastPath'), + isIndex = require('./_isIndex'), + isKey = require('./_isKey'), + isObject = require('./isObject'); + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + var newValue = value; + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = objValue == null + ? (isIndex(path[index + 1]) ? [] : {}) + : objValue; + } + } + assignValue(nested, key, newValue); + } + nested = nested[key]; + } + return object; +} + +module.exports = baseSet; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseSetData.js b/platforms/android/assets/www/node_modules/lodash/_baseSetData.js new file mode 100644 index 0000000..e689df2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseSetData.js @@ -0,0 +1,17 @@ +var identity = require('./identity'), + metaMap = require('./_metaMap'); + +/** + * The base implementation of `setData` without support for hot loop detection. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ +var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; +}; + +module.exports = baseSetData; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseSlice.js b/platforms/android/assets/www/node_modules/lodash/_baseSlice.js new file mode 100644 index 0000000..786f6c9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseSlice.js @@ -0,0 +1,31 @@ +/** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; +} + +module.exports = baseSlice; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseSome.js b/platforms/android/assets/www/node_modules/lodash/_baseSome.js new file mode 100644 index 0000000..8b6aa0a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseSome.js @@ -0,0 +1,21 @@ +var baseEach = require('./_baseEach'); + +/** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + */ +function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; +} + +module.exports = baseSome; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseSortBy.js b/platforms/android/assets/www/node_modules/lodash/_baseSortBy.js new file mode 100644 index 0000000..a25c92e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseSortBy.js @@ -0,0 +1,21 @@ +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +module.exports = baseSortBy; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseSortedIndex.js b/platforms/android/assets/www/node_modules/lodash/_baseSortedIndex.js new file mode 100644 index 0000000..3961063 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseSortedIndex.js @@ -0,0 +1,40 @@ +var baseSortedIndexBy = require('./_baseSortedIndexBy'), + identity = require('./identity'); + +/** Used as references for the maximum length and index of an array. */ +var MAX_ARRAY_LENGTH = 4294967295, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + +/** + * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which + * performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ +function baseSortedIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return baseSortedIndexBy(array, value, identity, retHighest); +} + +module.exports = baseSortedIndex; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseSortedIndexBy.js b/platforms/android/assets/www/node_modules/lodash/_baseSortedIndexBy.js new file mode 100644 index 0000000..6e295f9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseSortedIndexBy.js @@ -0,0 +1,56 @@ +/** Used as references for the maximum length and index of an array. */ +var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeFloor = Math.floor, + nativeMin = Math.min; + +/** + * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` + * which invokes `iteratee` for `value` and each element of `array` to compute + * their sort ranking. The iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The iteratee invoked per element. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + */ +function baseSortedIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); + + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsNull = value === null, + valIsUndef = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + isDef = computed !== undefined, + isReflexive = computed === computed; + + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); +} + +module.exports = baseSortedIndexBy; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseSortedUniq.js b/platforms/android/assets/www/node_modules/lodash/_baseSortedUniq.js new file mode 100644 index 0000000..bf1eb2e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseSortedUniq.js @@ -0,0 +1,14 @@ +var baseSortedUniqBy = require('./_baseSortedUniqBy'); + +/** + * The base implementation of `_.sortedUniq`. + * + * @private + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + */ +function baseSortedUniq(array) { + return baseSortedUniqBy(array); +} + +module.exports = baseSortedUniq; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseSortedUniqBy.js b/platforms/android/assets/www/node_modules/lodash/_baseSortedUniqBy.js new file mode 100644 index 0000000..81e7ae1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseSortedUniqBy.js @@ -0,0 +1,33 @@ +var eq = require('./eq'); + +/** + * The base implementation of `_.sortedUniqBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseSortedUniqBy(array, iteratee) { + var index = 0, + length = array.length, + value = array[0], + computed = iteratee ? iteratee(value) : value, + seen = computed, + resIndex = 1, + result = [value]; + + while (++index < length) { + value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!eq(computed, seen)) { + seen = computed; + result[resIndex++] = value; + } + } + return result; +} + +module.exports = baseSortedUniqBy; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseSum.js b/platforms/android/assets/www/node_modules/lodash/_baseSum.js new file mode 100644 index 0000000..348b5e8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseSum.js @@ -0,0 +1,23 @@ +/** + * The base implementation of `_.sum` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ +function baseSum(array, iteratee) { + var result, + index = -1, + length = array.length; + + while (++index < length) { + var current = iteratee(array[index]); + if (current !== undefined) { + result = result === undefined ? current : (result + current); + } + } + return result; +} + +module.exports = baseSum; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseTimes.js b/platforms/android/assets/www/node_modules/lodash/_baseTimes.js new file mode 100644 index 0000000..0603fc3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseTimes.js @@ -0,0 +1,20 @@ +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +module.exports = baseTimes; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseToPairs.js b/platforms/android/assets/www/node_modules/lodash/_baseToPairs.js new file mode 100644 index 0000000..d80b402 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseToPairs.js @@ -0,0 +1,18 @@ +var arrayMap = require('./_arrayMap'); + +/** + * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array + * of key-value pairs for `object` corresponding to the property names of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the new array of key-value pairs. + */ +function baseToPairs(object, props) { + return arrayMap(props, function(key) { + return [key, object[key]]; + }); +} + +module.exports = baseToPairs; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseUnary.js b/platforms/android/assets/www/node_modules/lodash/_baseUnary.js new file mode 100644 index 0000000..e584a99 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseUnary.js @@ -0,0 +1,14 @@ +/** + * The base implementation of `_.unary` without support for storing wrapper metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new function. + */ +function baseUnary(func) { + return function(value) { + return func(value); + }; +} + +module.exports = baseUnary; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseUniq.js b/platforms/android/assets/www/node_modules/lodash/_baseUniq.js new file mode 100644 index 0000000..ecb6fe4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseUniq.js @@ -0,0 +1,71 @@ +var SetCache = require('./_SetCache'), + arrayIncludes = require('./_arrayIncludes'), + arrayIncludesWith = require('./_arrayIncludesWith'), + cacheHas = require('./_cacheHas'), + createSet = require('./_createSet'), + setToArray = require('./_setToArray'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +module.exports = baseUniq; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseUnset.js b/platforms/android/assets/www/node_modules/lodash/_baseUnset.js new file mode 100644 index 0000000..02b5640 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseUnset.js @@ -0,0 +1,22 @@ +var baseCastPath = require('./_baseCastPath'), + has = require('./has'), + isKey = require('./_isKey'), + last = require('./last'), + parent = require('./_parent'); + +/** + * The base implementation of `_.unset`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + */ +function baseUnset(object, path) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + object = parent(object, path); + var key = last(path); + return (object != null && has(object, key)) ? delete object[key] : true; +} + +module.exports = baseUnset; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseUpdate.js b/platforms/android/assets/www/node_modules/lodash/_baseUpdate.js new file mode 100644 index 0000000..ec1b338 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseUpdate.js @@ -0,0 +1,18 @@ +var baseGet = require('./_baseGet'), + baseSet = require('./_baseSet'); + +/** + * The base implementation of `_.update`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to update. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseUpdate(object, path, updater, customizer) { + return baseSet(object, path, updater(baseGet(object, path)), customizer); +} + +module.exports = baseUpdate; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseValues.js b/platforms/android/assets/www/node_modules/lodash/_baseValues.js new file mode 100644 index 0000000..b95faad --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseValues.js @@ -0,0 +1,19 @@ +var arrayMap = require('./_arrayMap'); + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); +} + +module.exports = baseValues; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseWhile.js b/platforms/android/assets/www/node_modules/lodash/_baseWhile.js new file mode 100644 index 0000000..07eac61 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseWhile.js @@ -0,0 +1,26 @@ +var baseSlice = require('./_baseSlice'); + +/** + * The base implementation of methods like `_.dropWhile` and `_.takeWhile` + * without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ +function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && + predicate(array[index], index, array)) {} + + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); +} + +module.exports = baseWhile; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseWrapperValue.js b/platforms/android/assets/www/node_modules/lodash/_baseWrapperValue.js new file mode 100644 index 0000000..443e0df --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseWrapperValue.js @@ -0,0 +1,25 @@ +var LazyWrapper = require('./_LazyWrapper'), + arrayPush = require('./_arrayPush'), + arrayReduce = require('./_arrayReduce'); + +/** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ +function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + return arrayReduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); +} + +module.exports = baseWrapperValue; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseXor.js b/platforms/android/assets/www/node_modules/lodash/_baseXor.js new file mode 100644 index 0000000..7e62d1b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseXor.js @@ -0,0 +1,30 @@ +var arrayPush = require('./_arrayPush'), + baseDifference = require('./_baseDifference'), + baseUniq = require('./_baseUniq'); + +/** + * The base implementation of methods like `_.xor`, without support for + * iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + */ +function baseXor(arrays, iteratee, comparator) { + var index = -1, + length = arrays.length; + + while (++index < length) { + var result = result + ? arrayPush( + baseDifference(result, arrays[index], iteratee, comparator), + baseDifference(arrays[index], result, iteratee, comparator) + ) + : arrays[index]; + } + return (result && result.length) ? baseUniq(result, iteratee, comparator) : []; +} + +module.exports = baseXor; diff --git a/platforms/android/assets/www/node_modules/lodash/_baseZipObject.js b/platforms/android/assets/www/node_modules/lodash/_baseZipObject.js new file mode 100644 index 0000000..c8a3e83 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_baseZipObject.js @@ -0,0 +1,22 @@ +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property names. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + assignFunc(result, props[index], index < valsLength ? values[index] : undefined); + } + return result; +} + +module.exports = baseZipObject; diff --git a/platforms/android/assets/www/node_modules/lodash/_cacheHas.js b/platforms/android/assets/www/node_modules/lodash/_cacheHas.js new file mode 100644 index 0000000..7f2ac48 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_cacheHas.js @@ -0,0 +1,25 @@ +var isKeyable = require('./_isKeyable'); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Checks if `value` is in `cache`. + * + * @private + * @param {Object} cache The set cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function cacheHas(cache, value) { + var map = cache.__data__; + if (isKeyable(value)) { + var data = map.__data__, + hash = typeof value == 'string' ? data.string : data.hash; + + return hash[value] === HASH_UNDEFINED; + } + return map.has(value); +} + +module.exports = cacheHas; diff --git a/platforms/android/assets/www/node_modules/lodash/_cachePush.js b/platforms/android/assets/www/node_modules/lodash/_cachePush.js new file mode 100644 index 0000000..638383b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_cachePush.js @@ -0,0 +1,27 @@ +var isKeyable = require('./_isKeyable'); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the set cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ +function cachePush(value) { + var map = this.__data__; + if (isKeyable(value)) { + var data = map.__data__, + hash = typeof value == 'string' ? data.string : data.hash; + + hash[value] = HASH_UNDEFINED; + } + else { + map.set(value, HASH_UNDEFINED); + } +} + +module.exports = cachePush; diff --git a/platforms/android/assets/www/node_modules/lodash/_charsEndIndex.js b/platforms/android/assets/www/node_modules/lodash/_charsEndIndex.js new file mode 100644 index 0000000..07908ff --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_charsEndIndex.js @@ -0,0 +1,19 @@ +var baseIndexOf = require('./_baseIndexOf'); + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ +function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; +} + +module.exports = charsEndIndex; diff --git a/platforms/android/assets/www/node_modules/lodash/_charsStartIndex.js b/platforms/android/assets/www/node_modules/lodash/_charsStartIndex.js new file mode 100644 index 0000000..b17afd2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_charsStartIndex.js @@ -0,0 +1,20 @@ +var baseIndexOf = require('./_baseIndexOf'); + +/** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ +function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; +} + +module.exports = charsStartIndex; diff --git a/platforms/android/assets/www/node_modules/lodash/_checkGlobal.js b/platforms/android/assets/www/node_modules/lodash/_checkGlobal.js new file mode 100644 index 0000000..b0ea47e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_checkGlobal.js @@ -0,0 +1,12 @@ +/** + * Checks if `value` is a global object. + * + * @private + * @param {*} value The value to check. + * @returns {null|Object} Returns `value` if it's a global object, else `null`. + */ +function checkGlobal(value) { + return (value && value.Object === Object) ? value : null; +} + +module.exports = checkGlobal; diff --git a/platforms/android/assets/www/node_modules/lodash/_cloneArrayBuffer.js b/platforms/android/assets/www/node_modules/lodash/_cloneArrayBuffer.js new file mode 100644 index 0000000..c3d8f6e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_cloneArrayBuffer.js @@ -0,0 +1,16 @@ +var Uint8Array = require('./_Uint8Array'); + +/** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ +function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; +} + +module.exports = cloneArrayBuffer; diff --git a/platforms/android/assets/www/node_modules/lodash/_cloneBuffer.js b/platforms/android/assets/www/node_modules/lodash/_cloneBuffer.js new file mode 100644 index 0000000..247d410 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_cloneBuffer.js @@ -0,0 +1,18 @@ +/** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ +function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; +} + +module.exports = cloneBuffer; diff --git a/platforms/android/assets/www/node_modules/lodash/_cloneMap.js b/platforms/android/assets/www/node_modules/lodash/_cloneMap.js new file mode 100644 index 0000000..a42cbf3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_cloneMap.js @@ -0,0 +1,16 @@ +var addMapEntry = require('./_addMapEntry'), + arrayReduce = require('./_arrayReduce'), + mapToArray = require('./_mapToArray'); + +/** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @returns {Object} Returns the cloned map. + */ +function cloneMap(map) { + return arrayReduce(mapToArray(map), addMapEntry, new map.constructor); +} + +module.exports = cloneMap; diff --git a/platforms/android/assets/www/node_modules/lodash/_cloneRegExp.js b/platforms/android/assets/www/node_modules/lodash/_cloneRegExp.js new file mode 100644 index 0000000..64a30df --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_cloneRegExp.js @@ -0,0 +1,17 @@ +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +module.exports = cloneRegExp; diff --git a/platforms/android/assets/www/node_modules/lodash/_cloneSet.js b/platforms/android/assets/www/node_modules/lodash/_cloneSet.js new file mode 100644 index 0000000..0575c0a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_cloneSet.js @@ -0,0 +1,16 @@ +var addSetEntry = require('./_addSetEntry'), + arrayReduce = require('./_arrayReduce'), + setToArray = require('./_setToArray'); + +/** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @returns {Object} Returns the cloned set. + */ +function cloneSet(set) { + return arrayReduce(setToArray(set), addSetEntry, new set.constructor); +} + +module.exports = cloneSet; diff --git a/platforms/android/assets/www/node_modules/lodash/_cloneSymbol.js b/platforms/android/assets/www/node_modules/lodash/_cloneSymbol.js new file mode 100644 index 0000000..bede39f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_cloneSymbol.js @@ -0,0 +1,18 @@ +var Symbol = require('./_Symbol'); + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +module.exports = cloneSymbol; diff --git a/platforms/android/assets/www/node_modules/lodash/_cloneTypedArray.js b/platforms/android/assets/www/node_modules/lodash/_cloneTypedArray.js new file mode 100644 index 0000000..7aad84d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_cloneTypedArray.js @@ -0,0 +1,16 @@ +var cloneArrayBuffer = require('./_cloneArrayBuffer'); + +/** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ +function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); +} + +module.exports = cloneTypedArray; diff --git a/platforms/android/assets/www/node_modules/lodash/_compareAscending.js b/platforms/android/assets/www/node_modules/lodash/_compareAscending.js new file mode 100644 index 0000000..532866c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_compareAscending.js @@ -0,0 +1,33 @@ +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; +} + +module.exports = compareAscending; diff --git a/platforms/android/assets/www/node_modules/lodash/_compareMultiple.js b/platforms/android/assets/www/node_modules/lodash/_compareMultiple.js new file mode 100644 index 0000000..a3f2d8b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_compareMultiple.js @@ -0,0 +1,44 @@ +var compareAscending = require('./_compareAscending'); + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +module.exports = compareMultiple; diff --git a/platforms/android/assets/www/node_modules/lodash/_composeArgs.js b/platforms/android/assets/www/node_modules/lodash/_composeArgs.js new file mode 100644 index 0000000..07398e7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_composeArgs.js @@ -0,0 +1,39 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ +function composeArgs(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersLength = holders.length, + leftIndex = -1, + leftLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(leftLength + rangeLength), + isUncurried = !isCurried; + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + } + while (rangeLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; +} + +module.exports = composeArgs; diff --git a/platforms/android/assets/www/node_modules/lodash/_composeArgsRight.js b/platforms/android/assets/www/node_modules/lodash/_composeArgsRight.js new file mode 100644 index 0000000..18cfae0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_composeArgsRight.js @@ -0,0 +1,41 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ +function composeArgsRight(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersIndex = -1, + holdersLength = holders.length, + rightIndex = -1, + rightLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(rangeLength + rightLength), + isUncurried = !isCurried; + + while (++argsIndex < rangeLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + } + return result; +} + +module.exports = composeArgsRight; diff --git a/platforms/android/assets/www/node_modules/lodash/_copyArray.js b/platforms/android/assets/www/node_modules/lodash/_copyArray.js new file mode 100644 index 0000000..cd94d5d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_copyArray.js @@ -0,0 +1,20 @@ +/** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ +function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; +} + +module.exports = copyArray; diff --git a/platforms/android/assets/www/node_modules/lodash/_copyObject.js b/platforms/android/assets/www/node_modules/lodash/_copyObject.js new file mode 100644 index 0000000..f8406b6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_copyObject.js @@ -0,0 +1,16 @@ +var copyObjectWith = require('./_copyObjectWith'); + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object) { + return copyObjectWith(source, props, object); +} + +module.exports = copyObject; diff --git a/platforms/android/assets/www/node_modules/lodash/_copyObjectWith.js b/platforms/android/assets/www/node_modules/lodash/_copyObjectWith.js new file mode 100644 index 0000000..c4c1f45 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_copyObjectWith.js @@ -0,0 +1,32 @@ +var assignValue = require('./_assignValue'); + +/** + * This function is like `copyObject` except that it accepts a function to + * customize copied values. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObjectWith(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : source[key]; + + assignValue(object, key, newValue); + } + return object; +} + +module.exports = copyObjectWith; diff --git a/platforms/android/assets/www/node_modules/lodash/_copySymbols.js b/platforms/android/assets/www/node_modules/lodash/_copySymbols.js new file mode 100644 index 0000000..1fac3c8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_copySymbols.js @@ -0,0 +1,16 @@ +var copyObject = require('./_copyObject'), + getSymbols = require('./_getSymbols'); + +/** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); +} + +module.exports = copySymbols; diff --git a/platforms/android/assets/www/node_modules/lodash/_countHolders.js b/platforms/android/assets/www/node_modules/lodash/_countHolders.js new file mode 100644 index 0000000..8cc95e6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_countHolders.js @@ -0,0 +1,21 @@ +/** + * Gets the number of `placeholder` occurrences in `array`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} placeholder The placeholder to search for. + * @returns {number} Returns the placeholder count. + */ +function countHolders(array, placeholder) { + var length = array.length, + result = 0; + + while (length--) { + if (array[length] === placeholder) { + result++; + } + } + return result; +} + +module.exports = countHolders; diff --git a/platforms/android/assets/www/node_modules/lodash/_createAggregator.js b/platforms/android/assets/www/node_modules/lodash/_createAggregator.js new file mode 100644 index 0000000..7f7afd2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createAggregator.js @@ -0,0 +1,23 @@ +var arrayAggregator = require('./_arrayAggregator'), + baseAggregator = require('./_baseAggregator'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'); + +/** + * Creates a function like `_.groupBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ +function createAggregator(setter, initializer) { + return function(collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; + + return func(collection, setter, baseIteratee(iteratee), accumulator); + }; +} + +module.exports = createAggregator; diff --git a/platforms/android/assets/www/node_modules/lodash/_createAssigner.js b/platforms/android/assets/www/node_modules/lodash/_createAssigner.js new file mode 100644 index 0000000..1e81db9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createAssigner.js @@ -0,0 +1,37 @@ +var isIterateeCall = require('./_isIterateeCall'), + rest = require('./rest'); + +/** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return rest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = typeof customizer == 'function' + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); +} + +module.exports = createAssigner; diff --git a/platforms/android/assets/www/node_modules/lodash/_createBaseEach.js b/platforms/android/assets/www/node_modules/lodash/_createBaseEach.js new file mode 100644 index 0000000..d24fdd1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createBaseEach.js @@ -0,0 +1,32 @@ +var isArrayLike = require('./isArrayLike'); + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +module.exports = createBaseEach; diff --git a/platforms/android/assets/www/node_modules/lodash/_createBaseFor.js b/platforms/android/assets/www/node_modules/lodash/_createBaseFor.js new file mode 100644 index 0000000..bc84c03 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createBaseFor.js @@ -0,0 +1,25 @@ +/** + * Creates a base function for methods like `_.forIn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; +} + +module.exports = createBaseFor; diff --git a/platforms/android/assets/www/node_modules/lodash/_createBaseWrapper.js b/platforms/android/assets/www/node_modules/lodash/_createBaseWrapper.js new file mode 100644 index 0000000..fd3bb9a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createBaseWrapper.js @@ -0,0 +1,28 @@ +var createCtorWrapper = require('./_createCtorWrapper'), + root = require('./_root'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1; + +/** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createBaseWrapper(func, bitmask, thisArg) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, arguments); + } + return wrapper; +} + +module.exports = createBaseWrapper; diff --git a/platforms/android/assets/www/node_modules/lodash/_createCaseFirst.js b/platforms/android/assets/www/node_modules/lodash/_createCaseFirst.js new file mode 100644 index 0000000..a6f7054 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createCaseFirst.js @@ -0,0 +1,38 @@ +var stringToArray = require('./_stringToArray'), + toString = require('./toString'); + +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); + +/** + * Creates a function like `_.lowerFirst`. + * + * @private + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new function. + */ +function createCaseFirst(methodName) { + return function(string) { + string = toString(string); + + var strSymbols = reHasComplexSymbol.test(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols ? strSymbols[0] : string.charAt(0), + trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1); + + return chr[methodName]() + trailing; + }; +} + +module.exports = createCaseFirst; diff --git a/platforms/android/assets/www/node_modules/lodash/_createCompounder.js b/platforms/android/assets/www/node_modules/lodash/_createCompounder.js new file mode 100644 index 0000000..bfa4ee5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createCompounder.js @@ -0,0 +1,18 @@ +var arrayReduce = require('./_arrayReduce'), + deburr = require('./deburr'), + words = require('./words'); + +/** + * Creates a function like `_.camelCase`. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ +function createCompounder(callback) { + return function(string) { + return arrayReduce(words(deburr(string)), callback, ''); + }; +} + +module.exports = createCompounder; diff --git a/platforms/android/assets/www/node_modules/lodash/_createCtorWrapper.js b/platforms/android/assets/www/node_modules/lodash/_createCtorWrapper.js new file mode 100644 index 0000000..a0a7f83 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createCtorWrapper.js @@ -0,0 +1,37 @@ +var baseCreate = require('./_baseCreate'), + isObject = require('./isObject'); + +/** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ +function createCtorWrapper(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; +} + +module.exports = createCtorWrapper; diff --git a/platforms/android/assets/www/node_modules/lodash/_createCurryWrapper.js b/platforms/android/assets/www/node_modules/lodash/_createCurryWrapper.js new file mode 100644 index 0000000..af6f320 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createCurryWrapper.js @@ -0,0 +1,46 @@ +var apply = require('./_apply'), + createCtorWrapper = require('./_createCtorWrapper'), + createHybridWrapper = require('./_createHybridWrapper'), + createRecurryWrapper = require('./_createRecurryWrapper'), + getPlaceholder = require('./_getPlaceholder'), + replaceHolders = require('./_replaceHolders'), + root = require('./_root'); + +/** + * Creates a function that wraps `func` to enable currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {number} arity The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createCurryWrapper(func, bitmask, arity) { + var Ctor = createCtorWrapper(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length, + placeholder = getPlaceholder(wrapper); + + while (index--) { + args[index] = arguments[index]; + } + var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) + ? [] + : replaceHolders(args, placeholder); + + length -= holders.length; + if (length < arity) { + return createRecurryWrapper( + func, bitmask, createHybridWrapper, wrapper.placeholder, undefined, + args, holders, undefined, undefined, arity - length); + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return apply(fn, this, args); + } + return wrapper; +} + +module.exports = createCurryWrapper; diff --git a/platforms/android/assets/www/node_modules/lodash/_createFlow.js b/platforms/android/assets/www/node_modules/lodash/_createFlow.js new file mode 100644 index 0000000..8a5e60d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createFlow.js @@ -0,0 +1,83 @@ +var LodashWrapper = require('./_LodashWrapper'), + baseFlatten = require('./_baseFlatten'), + getData = require('./_getData'), + getFuncName = require('./_getFuncName'), + isArray = require('./isArray'), + isLaziable = require('./_isLaziable'), + rest = require('./rest'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** Used to compose bitmasks for wrapper metadata. */ +var CURRY_FLAG = 8, + PARTIAL_FLAG = 32, + ARY_FLAG = 128, + REARG_FLAG = 256; + +/** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ +function createFlow(fromRight) { + return rest(function(funcs) { + funcs = baseFlatten(funcs, 1); + + var length = funcs.length, + index = length, + prereq = LodashWrapper.prototype.thru; + + if (fromRight) { + funcs.reverse(); + } + while (index--) { + var func = funcs[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (prereq && !wrapper && getFuncName(func) == 'wrapper') { + var wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? index : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && + data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && + isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }); +} + +module.exports = createFlow; diff --git a/platforms/android/assets/www/node_modules/lodash/_createHybridWrapper.js b/platforms/android/assets/www/node_modules/lodash/_createHybridWrapper.js new file mode 100644 index 0000000..eaf8c81 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createHybridWrapper.js @@ -0,0 +1,90 @@ +var composeArgs = require('./_composeArgs'), + composeArgsRight = require('./_composeArgsRight'), + countHolders = require('./_countHolders'), + createCtorWrapper = require('./_createCtorWrapper'), + createRecurryWrapper = require('./_createRecurryWrapper'), + getPlaceholder = require('./_getPlaceholder'), + reorder = require('./_reorder'), + replaceHolders = require('./_replaceHolders'), + root = require('./_root'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + ARY_FLAG = 128, + FLIP_FLAG = 512; + +/** + * Creates a function that wraps `func` to invoke it with optional `this` + * binding of `thisArg`, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG), + isFlip = bitmask & FLIP_FLAG, + Ctor = isBindKey ? undefined : createCtorWrapper(func); + + function wrapper() { + var length = arguments.length, + index = length, + args = Array(length); + + while (index--) { + args[index] = arguments[index]; + } + if (isCurried) { + var placeholder = getPlaceholder(wrapper), + holdersCount = countHolders(args, placeholder); + } + if (partials) { + args = composeArgs(args, partials, holders, isCurried); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight, isCurried); + } + length -= holdersCount; + if (isCurried && length < arity) { + var newHolders = replaceHolders(args, placeholder); + return createRecurryWrapper( + func, bitmask, createHybridWrapper, wrapper.placeholder, thisArg, + args, newHolders, argPos, ary, arity - length + ); + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + length = args.length; + if (argPos) { + args = reorder(args, argPos); + } else if (isFlip && length > 1) { + args.reverse(); + } + if (isAry && ary < length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtorWrapper(fn); + } + return fn.apply(thisBinding, args); + } + return wrapper; +} + +module.exports = createHybridWrapper; diff --git a/platforms/android/assets/www/node_modules/lodash/_createInverter.js b/platforms/android/assets/www/node_modules/lodash/_createInverter.js new file mode 100644 index 0000000..6c0c562 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createInverter.js @@ -0,0 +1,17 @@ +var baseInverter = require('./_baseInverter'); + +/** + * Creates a function like `_.invertBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} toIteratee The function to resolve iteratees. + * @returns {Function} Returns the new inverter function. + */ +function createInverter(setter, toIteratee) { + return function(object, iteratee) { + return baseInverter(object, setter, toIteratee(iteratee), {}); + }; +} + +module.exports = createInverter; diff --git a/platforms/android/assets/www/node_modules/lodash/_createOver.js b/platforms/android/assets/www/node_modules/lodash/_createOver.js new file mode 100644 index 0000000..f0a99c3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createOver.js @@ -0,0 +1,26 @@ +var apply = require('./_apply'), + arrayMap = require('./_arrayMap'), + baseFlatten = require('./_baseFlatten'), + baseIteratee = require('./_baseIteratee'), + rest = require('./rest'); + +/** + * Creates a function like `_.over`. + * + * @private + * @param {Function} arrayFunc The function to iterate over iteratees. + * @returns {Function} Returns the new invoker function. + */ +function createOver(arrayFunc) { + return rest(function(iteratees) { + iteratees = arrayMap(baseFlatten(iteratees, 1), baseIteratee); + return rest(function(args) { + var thisArg = this; + return arrayFunc(iteratees, function(iteratee) { + return apply(iteratee, thisArg, args); + }); + }); + }); +} + +module.exports = createOver; diff --git a/platforms/android/assets/www/node_modules/lodash/_createPadding.js b/platforms/android/assets/www/node_modules/lodash/_createPadding.js new file mode 100644 index 0000000..e59cc52 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createPadding.js @@ -0,0 +1,47 @@ +var repeat = require('./repeat'), + stringSize = require('./_stringSize'), + stringToArray = require('./_stringToArray'), + toInteger = require('./toInteger'); + +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil; + +/** + * Creates the padding for `string` based on `length`. The `chars` string + * is truncated if the number of characters exceeds `length`. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padding for `string`. + */ +function createPadding(string, length, chars) { + length = toInteger(length); + + var strLength = stringSize(string); + if (!length || strLength >= length) { + return ''; + } + var padLength = length - strLength; + chars = chars === undefined ? ' ' : (chars + ''); + + var result = repeat(chars, nativeCeil(padLength / stringSize(chars))); + return reHasComplexSymbol.test(chars) + ? stringToArray(result).slice(0, padLength).join('') + : result.slice(0, padLength); +} + +module.exports = createPadding; diff --git a/platforms/android/assets/www/node_modules/lodash/_createPartialWrapper.js b/platforms/android/assets/www/node_modules/lodash/_createPartialWrapper.js new file mode 100644 index 0000000..1fc3a9b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createPartialWrapper.js @@ -0,0 +1,43 @@ +var apply = require('./_apply'), + createCtorWrapper = require('./_createCtorWrapper'), + root = require('./_root'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1; + +/** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new wrapped function. + */ +function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return apply(fn, isBind ? thisArg : this, args); + } + return wrapper; +} + +module.exports = createPartialWrapper; diff --git a/platforms/android/assets/www/node_modules/lodash/_createRange.js b/platforms/android/assets/www/node_modules/lodash/_createRange.js new file mode 100644 index 0000000..9728563 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createRange.js @@ -0,0 +1,31 @@ +var baseRange = require('./_baseRange'), + isIterateeCall = require('./_isIterateeCall'), + toNumber = require('./toNumber'); + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = toNumber(start); + start = start === start ? start : 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = toNumber(end) || 0; + } + step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0); + return baseRange(start, end, step, fromRight); + }; +} + +module.exports = createRange; diff --git a/platforms/android/assets/www/node_modules/lodash/_createRecurryWrapper.js b/platforms/android/assets/www/node_modules/lodash/_createRecurryWrapper.js new file mode 100644 index 0000000..027424e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createRecurryWrapper.js @@ -0,0 +1,56 @@ +var copyArray = require('./_copyArray'), + isLaziable = require('./_isLaziable'), + setData = require('./_setData'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64; + +/** + * Creates a function that wraps `func` to continue currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {Function} wrapFunc The function to create the `func` wrapper. + * @param {*} placeholder The placeholder value. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { + var isCurry = bitmask & CURRY_FLAG, + newArgPos = argPos ? copyArray(argPos) : undefined, + newHolders = isCurry ? holders : undefined, + newHoldersRight = isCurry ? undefined : holders, + newPartials = isCurry ? partials : undefined, + newPartialsRight = isCurry ? undefined : partials; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!(bitmask & CURRY_BOUND_FLAG)) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [ + func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, + newHoldersRight, newArgPos, ary, arity + ]; + + var result = wrapFunc.apply(undefined, newData); + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; +} + +module.exports = createRecurryWrapper; diff --git a/platforms/android/assets/www/node_modules/lodash/_createRound.js b/platforms/android/assets/www/node_modules/lodash/_createRound.js new file mode 100644 index 0000000..cb42ba2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createRound.js @@ -0,0 +1,30 @@ +var toInteger = require('./toInteger'), + toNumber = require('./toNumber'), + toString = require('./toString'); + +/** + * Creates a function like `_.round`. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ +function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + number = toNumber(number); + precision = toInteger(precision); + if (precision) { + // Shift with exponential notation to avoid floating-point issues. + // See [MDN](https://mdn.io/round#Examples) for more details. + var pair = (toString(number) + 'e').split('e'), + value = func(pair[0] + 'e' + (+pair[1] + precision)); + + pair = (toString(value) + 'e').split('e'); + return +(pair[0] + 'e' + (+pair[1] - precision)); + } + return func(number); + }; +} + +module.exports = createRound; diff --git a/platforms/android/assets/www/node_modules/lodash/_createSet.js b/platforms/android/assets/www/node_modules/lodash/_createSet.js new file mode 100644 index 0000000..c67128f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createSet.js @@ -0,0 +1,15 @@ +var Set = require('./_Set'), + noop = require('./noop'); + +/** + * Creates a set of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) { + return new Set(values); +}; + +module.exports = createSet; diff --git a/platforms/android/assets/www/node_modules/lodash/_createWrapper.js b/platforms/android/assets/www/node_modules/lodash/_createWrapper.js new file mode 100644 index 0000000..7b573b2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_createWrapper.js @@ -0,0 +1,105 @@ +var baseSetData = require('./_baseSetData'), + createBaseWrapper = require('./_createBaseWrapper'), + createCurryWrapper = require('./_createCurryWrapper'), + createHybridWrapper = require('./_createHybridWrapper'), + createPartialWrapper = require('./_createPartialWrapper'), + getData = require('./_getData'), + mergeData = require('./_mergeData'), + setData = require('./_setData'), + toInteger = require('./toInteger'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask of wrapper flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); + arity = arity === undefined ? arity : toInteger(arity); + length -= holders ? holders.length : 0; + + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; + + if (data) { + mergeData(newData, data); + } + func = newData[0]; + bitmask = newData[1]; + thisArg = newData[2]; + partials = newData[3]; + holders = newData[4]; + arity = newData[9] = newData[9] == null + ? (isBindKey ? 0 : func.length) + : nativeMax(newData[9] - length, 0); + + if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) { + bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG); + } + if (!bitmask || bitmask == BIND_FLAG) { + var result = createBaseWrapper(func, bitmask, thisArg); + } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) { + result = createCurryWrapper(func, bitmask, arity); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) { + result = createPartialWrapper(func, bitmask, thisArg, partials); + } else { + result = createHybridWrapper.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); +} + +module.exports = createWrapper; diff --git a/platforms/android/assets/www/node_modules/lodash/_deburrLetter.js b/platforms/android/assets/www/node_modules/lodash/_deburrLetter.js new file mode 100644 index 0000000..e559dbe --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_deburrLetter.js @@ -0,0 +1,33 @@ +/** Used to map latin-1 supplementary letters to basic latin letters. */ +var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' +}; + +/** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ +function deburrLetter(letter) { + return deburredLetters[letter]; +} + +module.exports = deburrLetter; diff --git a/platforms/android/assets/www/node_modules/lodash/_equalArrays.js b/platforms/android/assets/www/node_modules/lodash/_equalArrays.js new file mode 100644 index 0000000..eb39015 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_equalArrays.js @@ -0,0 +1,72 @@ +var arraySome = require('./_arraySome'); + +/** Used to compose bitmasks for comparison styles. */ +var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { + var index = -1, + isPartial = bitmask & PARTIAL_COMPARE_FLAG, + isUnordered = bitmask & UNORDERED_COMPARE_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked) { + return stacked == other; + } + var result = true; + stack.set(array, other); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isUnordered) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack); + })) { + result = false; + break; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { + result = false; + break; + } + } + stack['delete'](array); + return result; +} + +module.exports = equalArrays; diff --git a/platforms/android/assets/www/node_modules/lodash/_equalByTag.js b/platforms/android/assets/www/node_modules/lodash/_equalByTag.js new file mode 100644 index 0000000..15b3860 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_equalByTag.js @@ -0,0 +1,99 @@ +var Symbol = require('./_Symbol'), + Uint8Array = require('./_Uint8Array'), + equalArrays = require('./_equalArrays'), + mapToArray = require('./_mapToArray'), + setToArray = require('./_setToArray'); + +/** Used to compose bitmasks for comparison styles. */ +var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) { + switch (tag) { + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) ? other != +other : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & PARTIAL_COMPARE_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + // Recursively compare objects (susceptible to call stack limits). + return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask | UNORDERED_COMPARE_FLAG, stack.set(object, other)); + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +module.exports = equalByTag; diff --git a/platforms/android/assets/www/node_modules/lodash/_equalObjects.js b/platforms/android/assets/www/node_modules/lodash/_equalObjects.js new file mode 100644 index 0000000..103f435 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_equalObjects.js @@ -0,0 +1,82 @@ +var baseHas = require('./_baseHas'), + keys = require('./keys'); + +/** Used to compose bitmasks for comparison styles. */ +var PARTIAL_COMPARE_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { + var isPartial = bitmask & PARTIAL_COMPARE_FLAG, + objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : baseHas(other, key))) { + return false; + } + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + var result = true; + stack.set(object, other); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + return result; +} + +module.exports = equalObjects; diff --git a/platforms/android/assets/www/node_modules/lodash/_escapeHtmlChar.js b/platforms/android/assets/www/node_modules/lodash/_escapeHtmlChar.js new file mode 100644 index 0000000..b21e452 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_escapeHtmlChar.js @@ -0,0 +1,22 @@ +/** Used to map characters to HTML entities. */ +var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' +}; + +/** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ +function escapeHtmlChar(chr) { + return htmlEscapes[chr]; +} + +module.exports = escapeHtmlChar; diff --git a/platforms/android/assets/www/node_modules/lodash/_escapeStringChar.js b/platforms/android/assets/www/node_modules/lodash/_escapeStringChar.js new file mode 100644 index 0000000..44eca96 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_escapeStringChar.js @@ -0,0 +1,22 @@ +/** Used to escape characters for inclusion in compiled string literals. */ +var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' +}; + +/** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ +function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; +} + +module.exports = escapeStringChar; diff --git a/platforms/android/assets/www/node_modules/lodash/_getData.js b/platforms/android/assets/www/node_modules/lodash/_getData.js new file mode 100644 index 0000000..a1fe7b7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_getData.js @@ -0,0 +1,15 @@ +var metaMap = require('./_metaMap'), + noop = require('./noop'); + +/** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ +var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); +}; + +module.exports = getData; diff --git a/platforms/android/assets/www/node_modules/lodash/_getFuncName.js b/platforms/android/assets/www/node_modules/lodash/_getFuncName.js new file mode 100644 index 0000000..21e15b3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_getFuncName.js @@ -0,0 +1,31 @@ +var realNames = require('./_realNames'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ +function getFuncName(func) { + var result = (func.name + ''), + array = realNames[result], + length = hasOwnProperty.call(realNames, result) ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; +} + +module.exports = getFuncName; diff --git a/platforms/android/assets/www/node_modules/lodash/_getLength.js b/platforms/android/assets/www/node_modules/lodash/_getLength.js new file mode 100644 index 0000000..1848d49 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_getLength.js @@ -0,0 +1,15 @@ +var baseProperty = require('./_baseProperty'); + +/** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ +var getLength = baseProperty('length'); + +module.exports = getLength; diff --git a/platforms/android/assets/www/node_modules/lodash/_getMatchData.js b/platforms/android/assets/www/node_modules/lodash/_getMatchData.js new file mode 100644 index 0000000..a1456d2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_getMatchData.js @@ -0,0 +1,21 @@ +var isStrictComparable = require('./_isStrictComparable'), + toPairs = require('./toPairs'); + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = toPairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; +} + +module.exports = getMatchData; diff --git a/platforms/android/assets/www/node_modules/lodash/_getNative.js b/platforms/android/assets/www/node_modules/lodash/_getNative.js new file mode 100644 index 0000000..f6ff7f1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_getNative.js @@ -0,0 +1,16 @@ +var isNative = require('./isNative'); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = object[key]; + return isNative(value) ? value : undefined; +} + +module.exports = getNative; diff --git a/platforms/android/assets/www/node_modules/lodash/_getPlaceholder.js b/platforms/android/assets/www/node_modules/lodash/_getPlaceholder.js new file mode 100644 index 0000000..4bbcda2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_getPlaceholder.js @@ -0,0 +1,13 @@ +/** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ +function getPlaceholder(func) { + var object = func; + return object.placeholder; +} + +module.exports = getPlaceholder; diff --git a/platforms/android/assets/www/node_modules/lodash/_getSymbols.js b/platforms/android/assets/www/node_modules/lodash/_getSymbols.js new file mode 100644 index 0000000..266906a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_getSymbols.js @@ -0,0 +1,15 @@ +/** Built-in value references. */ +var getOwnPropertySymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = getOwnPropertySymbols || function() { + return []; +}; + +module.exports = getSymbols; diff --git a/platforms/android/assets/www/node_modules/lodash/_getTag.js b/platforms/android/assets/www/node_modules/lodash/_getTag.js new file mode 100644 index 0000000..1516eca --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_getTag.js @@ -0,0 +1,59 @@ +var Map = require('./_Map'), + Set = require('./_Set'), + WeakMap = require('./_WeakMap'); + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + objectTag = '[object Object]', + setTag = '[object Set]', + weakMapTag = '[object WeakMap]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = Function.prototype.toString; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Used to detect maps, sets, and weakmaps. */ +var mapCtorString = Map ? funcToString.call(Map) : '', + setCtorString = Set ? funcToString.call(Set) : '', + weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : ''; + +/** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function getTag(value) { + return objectToString.call(value); +} + +// Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps. +if ((Map && getTag(new Map) != mapTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : null, + ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case mapCtorString: return mapTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; +} + +module.exports = getTag; diff --git a/platforms/android/assets/www/node_modules/lodash/_getView.js b/platforms/android/assets/www/node_modules/lodash/_getView.js new file mode 100644 index 0000000..df1e5d4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_getView.js @@ -0,0 +1,33 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ +function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; +} + +module.exports = getView; diff --git a/platforms/android/assets/www/node_modules/lodash/_hasPath.js b/platforms/android/assets/www/node_modules/lodash/_hasPath.js new file mode 100644 index 0000000..ed4f1a1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_hasPath.js @@ -0,0 +1,40 @@ +var baseCastPath = require('./_baseCastPath'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isIndex = require('./_isIndex'), + isKey = require('./_isKey'), + isLength = require('./isLength'), + isString = require('./isString'), + last = require('./last'), + parent = require('./_parent'); + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + if (object == null) { + return false; + } + var result = hasFunc(object, path); + if (!result && !isKey(path)) { + path = baseCastPath(path); + object = parent(object, path); + if (object != null) { + path = last(path); + result = hasFunc(object, path); + } + } + var length = object ? object.length : undefined; + return result || ( + !!length && isLength(length) && isIndex(path, length) && + (isArray(object) || isString(object) || isArguments(object)) + ); +} + +module.exports = hasPath; diff --git a/platforms/android/assets/www/node_modules/lodash/_hashDelete.js b/platforms/android/assets/www/node_modules/lodash/_hashDelete.js new file mode 100644 index 0000000..b562317 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_hashDelete.js @@ -0,0 +1,15 @@ +var hashHas = require('./_hashHas'); + +/** + * Removes `key` and its value from the hash. + * + * @private + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(hash, key) { + return hashHas(hash, key) && delete hash[key]; +} + +module.exports = hashDelete; diff --git a/platforms/android/assets/www/node_modules/lodash/_hashGet.js b/platforms/android/assets/www/node_modules/lodash/_hashGet.js new file mode 100644 index 0000000..ba509b6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_hashGet.js @@ -0,0 +1,28 @@ +var nativeCreate = require('./_nativeCreate'); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Gets the hash value for `key`. + * + * @private + * @param {Object} hash The hash to query. + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(hash, key) { + if (nativeCreate) { + var result = hash[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(hash, key) ? hash[key] : undefined; +} + +module.exports = hashGet; diff --git a/platforms/android/assets/www/node_modules/lodash/_hashHas.js b/platforms/android/assets/www/node_modules/lodash/_hashHas.js new file mode 100644 index 0000000..3bbff48 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_hashHas.js @@ -0,0 +1,21 @@ +var nativeCreate = require('./_nativeCreate'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @param {Object} hash The hash to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(hash, key) { + return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key); +} + +module.exports = hashHas; diff --git a/platforms/android/assets/www/node_modules/lodash/_hashSet.js b/platforms/android/assets/www/node_modules/lodash/_hashSet.js new file mode 100644 index 0000000..f7c3307 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_hashSet.js @@ -0,0 +1,18 @@ +var nativeCreate = require('./_nativeCreate'); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Sets the hash `key` to `value`. + * + * @private + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + */ +function hashSet(hash, key, value) { + hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; +} + +module.exports = hashSet; diff --git a/platforms/android/assets/www/node_modules/lodash/_indexKeys.js b/platforms/android/assets/www/node_modules/lodash/_indexKeys.js new file mode 100644 index 0000000..0e2fc10 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_indexKeys.js @@ -0,0 +1,24 @@ +var baseTimes = require('./_baseTimes'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isLength = require('./isLength'), + isString = require('./isString'); + +/** + * Creates an array of index keys for `object` values of arrays, + * `arguments` objects, and strings, otherwise `null` is returned. + * + * @private + * @param {Object} object The object to query. + * @returns {Array|null} Returns index keys, else `null`. + */ +function indexKeys(object) { + var length = object ? object.length : undefined; + if (isLength(length) && + (isArray(object) || isString(object) || isArguments(object))) { + return baseTimes(length, String); + } + return null; +} + +module.exports = indexKeys; diff --git a/platforms/android/assets/www/node_modules/lodash/_indexOfNaN.js b/platforms/android/assets/www/node_modules/lodash/_indexOfNaN.js new file mode 100644 index 0000000..05b8207 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_indexOfNaN.js @@ -0,0 +1,23 @@ +/** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * + * @private + * @param {Array} array The array to search. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched `NaN`, else `-1`. + */ +function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 0 : -1); + + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; + } + } + return -1; +} + +module.exports = indexOfNaN; diff --git a/platforms/android/assets/www/node_modules/lodash/_initCloneArray.js b/platforms/android/assets/www/node_modules/lodash/_initCloneArray.js new file mode 100644 index 0000000..aef0212 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_initCloneArray.js @@ -0,0 +1,26 @@ +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +module.exports = initCloneArray; diff --git a/platforms/android/assets/www/node_modules/lodash/_initCloneByTag.js b/platforms/android/assets/www/node_modules/lodash/_initCloneByTag.js new file mode 100644 index 0000000..5d21cda --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_initCloneByTag.js @@ -0,0 +1,74 @@ +var cloneArrayBuffer = require('./_cloneArrayBuffer'), + cloneMap = require('./_cloneMap'), + cloneRegExp = require('./_cloneRegExp'), + cloneSet = require('./_cloneSet'), + cloneSymbol = require('./_cloneSymbol'), + cloneTypedArray = require('./_cloneTypedArray'); + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object); + + case symbolTag: + return cloneSymbol(object); + } +} + +module.exports = initCloneByTag; diff --git a/platforms/android/assets/www/node_modules/lodash/_initCloneObject.js b/platforms/android/assets/www/node_modules/lodash/_initCloneObject.js new file mode 100644 index 0000000..14d2dc4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_initCloneObject.js @@ -0,0 +1,20 @@ +var baseCreate = require('./_baseCreate'), + isPrototype = require('./_isPrototype'); + +/** Built-in value references. */ +var getPrototypeOf = Object.getPrototypeOf; + +/** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototypeOf(object)) + : {}; +} + +module.exports = initCloneObject; diff --git a/platforms/android/assets/www/node_modules/lodash/_isHostObject.js b/platforms/android/assets/www/node_modules/lodash/_isHostObject.js new file mode 100644 index 0000000..e598c10 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_isHostObject.js @@ -0,0 +1,20 @@ +/** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ +function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; +} + +module.exports = isHostObject; diff --git a/platforms/android/assets/www/node_modules/lodash/_isIndex.js b/platforms/android/assets/www/node_modules/lodash/_isIndex.js new file mode 100644 index 0000000..c7ff607 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_isIndex.js @@ -0,0 +1,21 @@ +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; +} + +module.exports = isIndex; diff --git a/platforms/android/assets/www/node_modules/lodash/_isIterateeCall.js b/platforms/android/assets/www/node_modules/lodash/_isIterateeCall.js new file mode 100644 index 0000000..b422b48 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_isIterateeCall.js @@ -0,0 +1,28 @@ +var eq = require('./eq'), + isArrayLike = require('./isArrayLike'), + isIndex = require('./_isIndex'), + isObject = require('./isObject'); + +/** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + return eq(object[index], value); + } + return false; +} + +module.exports = isIterateeCall; diff --git a/platforms/android/assets/www/node_modules/lodash/_isKey.js b/platforms/android/assets/www/node_modules/lodash/_isKey.js new file mode 100644 index 0000000..0e34576 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_isKey.js @@ -0,0 +1,24 @@ +var isArray = require('./isArray'); + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if (typeof value == 'number') { + return true; + } + return !isArray(value) && + (reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object))); +} + +module.exports = isKey; diff --git a/platforms/android/assets/www/node_modules/lodash/_isKeyable.js b/platforms/android/assets/www/node_modules/lodash/_isKeyable.js new file mode 100644 index 0000000..5df83c0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_isKeyable.js @@ -0,0 +1,14 @@ +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return type == 'number' || type == 'boolean' || + (type == 'string' && value != '__proto__') || value == null; +} + +module.exports = isKeyable; diff --git a/platforms/android/assets/www/node_modules/lodash/_isLaziable.js b/platforms/android/assets/www/node_modules/lodash/_isLaziable.js new file mode 100644 index 0000000..faa17b9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_isLaziable.js @@ -0,0 +1,27 @@ +var LazyWrapper = require('./_LazyWrapper'), + getData = require('./_getData'), + getFuncName = require('./_getFuncName'), + lodash = require('./wrapperLodash'); + +/** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + */ +function isLaziable(func) { + var funcName = getFuncName(func), + other = lodash[funcName]; + + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { + return false; + } + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; +} + +module.exports = isLaziable; diff --git a/platforms/android/assets/www/node_modules/lodash/_isPrototype.js b/platforms/android/assets/www/node_modules/lodash/_isPrototype.js new file mode 100644 index 0000000..0f29498 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_isPrototype.js @@ -0,0 +1,18 @@ +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +module.exports = isPrototype; diff --git a/platforms/android/assets/www/node_modules/lodash/_isStrictComparable.js b/platforms/android/assets/www/node_modules/lodash/_isStrictComparable.js new file mode 100644 index 0000000..b59f40b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_isStrictComparable.js @@ -0,0 +1,15 @@ +var isObject = require('./isObject'); + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !isObject(value); +} + +module.exports = isStrictComparable; diff --git a/platforms/android/assets/www/node_modules/lodash/_iteratorToArray.js b/platforms/android/assets/www/node_modules/lodash/_iteratorToArray.js new file mode 100644 index 0000000..4768566 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_iteratorToArray.js @@ -0,0 +1,18 @@ +/** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ +function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; +} + +module.exports = iteratorToArray; diff --git a/platforms/android/assets/www/node_modules/lodash/_lazyClone.js b/platforms/android/assets/www/node_modules/lodash/_lazyClone.js new file mode 100644 index 0000000..d8a51f8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_lazyClone.js @@ -0,0 +1,23 @@ +var LazyWrapper = require('./_LazyWrapper'), + copyArray = require('./_copyArray'); + +/** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ +function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = copyArray(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = copyArray(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = copyArray(this.__views__); + return result; +} + +module.exports = lazyClone; diff --git a/platforms/android/assets/www/node_modules/lodash/_lazyReverse.js b/platforms/android/assets/www/node_modules/lodash/_lazyReverse.js new file mode 100644 index 0000000..c5b5219 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_lazyReverse.js @@ -0,0 +1,23 @@ +var LazyWrapper = require('./_LazyWrapper'); + +/** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ +function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; +} + +module.exports = lazyReverse; diff --git a/platforms/android/assets/www/node_modules/lodash/_lazyValue.js b/platforms/android/assets/www/node_modules/lodash/_lazyValue.js new file mode 100644 index 0000000..09bf14b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_lazyValue.js @@ -0,0 +1,73 @@ +var baseWrapperValue = require('./_baseWrapperValue'), + getView = require('./_getView'), + isArray = require('./isArray'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** Used to indicate the type of lazy iteratees. */ +var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ +function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || + (arrLength == length && takeCount == length)) { + return baseWrapperValue(array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; +} + +module.exports = lazyValue; diff --git a/platforms/android/assets/www/node_modules/lodash/_mapClear.js b/platforms/android/assets/www/node_modules/lodash/_mapClear.js new file mode 100644 index 0000000..296f417 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_mapClear.js @@ -0,0 +1,19 @@ +var Hash = require('./_Hash'), + Map = require('./_Map'); + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapClear() { + this.__data__ = { + 'hash': new Hash, + 'map': Map ? new Map : [], + 'string': new Hash + }; +} + +module.exports = mapClear; diff --git a/platforms/android/assets/www/node_modules/lodash/_mapDelete.js b/platforms/android/assets/www/node_modules/lodash/_mapDelete.js new file mode 100644 index 0000000..640eb0a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_mapDelete.js @@ -0,0 +1,23 @@ +var Map = require('./_Map'), + assocDelete = require('./_assocDelete'), + hashDelete = require('./_hashDelete'), + isKeyable = require('./_isKeyable'); + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapDelete(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashDelete(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map['delete'](key) : assocDelete(data.map, key); +} + +module.exports = mapDelete; diff --git a/platforms/android/assets/www/node_modules/lodash/_mapGet.js b/platforms/android/assets/www/node_modules/lodash/_mapGet.js new file mode 100644 index 0000000..8f33854 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_mapGet.js @@ -0,0 +1,23 @@ +var Map = require('./_Map'), + assocGet = require('./_assocGet'), + hashGet = require('./_hashGet'), + isKeyable = require('./_isKeyable'); + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapGet(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashGet(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map.get(key) : assocGet(data.map, key); +} + +module.exports = mapGet; diff --git a/platforms/android/assets/www/node_modules/lodash/_mapHas.js b/platforms/android/assets/www/node_modules/lodash/_mapHas.js new file mode 100644 index 0000000..9225537 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_mapHas.js @@ -0,0 +1,23 @@ +var Map = require('./_Map'), + assocHas = require('./_assocHas'), + hashHas = require('./_hashHas'), + isKeyable = require('./_isKeyable'); + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapHas(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashHas(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map.has(key) : assocHas(data.map, key); +} + +module.exports = mapHas; diff --git a/platforms/android/assets/www/node_modules/lodash/_mapSet.js b/platforms/android/assets/www/node_modules/lodash/_mapSet.js new file mode 100644 index 0000000..7a58786 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_mapSet.js @@ -0,0 +1,28 @@ +var Map = require('./_Map'), + assocSet = require('./_assocSet'), + hashSet = require('./_hashSet'), + isKeyable = require('./_isKeyable'); + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache object. + */ +function mapSet(key, value) { + var data = this.__data__; + if (isKeyable(key)) { + hashSet(typeof key == 'string' ? data.string : data.hash, key, value); + } else if (Map) { + data.map.set(key, value); + } else { + assocSet(data.map, key, value); + } + return this; +} + +module.exports = mapSet; diff --git a/platforms/android/assets/www/node_modules/lodash/_mapToArray.js b/platforms/android/assets/www/node_modules/lodash/_mapToArray.js new file mode 100644 index 0000000..e2e8a24 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_mapToArray.js @@ -0,0 +1,18 @@ +/** + * Converts `map` to an array. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the converted array. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +module.exports = mapToArray; diff --git a/platforms/android/assets/www/node_modules/lodash/_mergeData.js b/platforms/android/assets/www/node_modules/lodash/_mergeData.js new file mode 100644 index 0000000..ac6fa4c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_mergeData.js @@ -0,0 +1,90 @@ +var composeArgs = require('./_composeArgs'), + composeArgsRight = require('./_composeArgsRight'), + copyArray = require('./_copyArray'), + replaceHolders = require('./_replaceHolders'); + +/** Used as the internal argument placeholder. */ +var PLACEHOLDER = '__lodash_placeholder__'; + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + ARY_FLAG = 128, + REARG_FLAG = 256; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers used to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` + * modify function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * combined case where curried functions have `_.ary` and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ +function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG); + + var isCombo = + ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) || + ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) || + ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG)); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = copyArray(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; +} + +module.exports = mergeData; diff --git a/platforms/android/assets/www/node_modules/lodash/_mergeDefaults.js b/platforms/android/assets/www/node_modules/lodash/_mergeDefaults.js new file mode 100644 index 0000000..263836b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_mergeDefaults.js @@ -0,0 +1,23 @@ +var baseMerge = require('./_baseMerge'), + isObject = require('./isObject'); + +/** + * Used by `_.defaultsDeep` to customize its `_.merge` use. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to merge. + * @param {Object} object The parent object of `objValue`. + * @param {Object} source The parent object of `srcValue`. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + * @returns {*} Returns the value to assign. + */ +function mergeDefaults(objValue, srcValue, key, object, source, stack) { + if (isObject(objValue) && isObject(srcValue)) { + baseMerge(objValue, srcValue, undefined, mergeDefaults, stack.set(srcValue, objValue)); + } + return objValue; +} + +module.exports = mergeDefaults; diff --git a/platforms/android/assets/www/node_modules/lodash/_metaMap.js b/platforms/android/assets/www/node_modules/lodash/_metaMap.js new file mode 100644 index 0000000..0157a0b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_metaMap.js @@ -0,0 +1,6 @@ +var WeakMap = require('./_WeakMap'); + +/** Used to store function metadata. */ +var metaMap = WeakMap && new WeakMap; + +module.exports = metaMap; diff --git a/platforms/android/assets/www/node_modules/lodash/_nativeCreate.js b/platforms/android/assets/www/node_modules/lodash/_nativeCreate.js new file mode 100644 index 0000000..c7aede8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_nativeCreate.js @@ -0,0 +1,6 @@ +var getNative = require('./_getNative'); + +/* Built-in method references that are verified to be native. */ +var nativeCreate = getNative(Object, 'create'); + +module.exports = nativeCreate; diff --git a/platforms/android/assets/www/node_modules/lodash/_parent.js b/platforms/android/assets/www/node_modules/lodash/_parent.js new file mode 100644 index 0000000..e04ff6e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_parent.js @@ -0,0 +1,16 @@ +var baseSlice = require('./_baseSlice'), + get = require('./get'); + +/** + * Gets the parent value at `path` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. + */ +function parent(object, path) { + return path.length == 1 ? object : get(object, baseSlice(path, 0, -1)); +} + +module.exports = parent; diff --git a/platforms/android/assets/www/node_modules/lodash/_reEscape.js b/platforms/android/assets/www/node_modules/lodash/_reEscape.js new file mode 100644 index 0000000..7f47eda --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_reEscape.js @@ -0,0 +1,4 @@ +/** Used to match template delimiters. */ +var reEscape = /<%-([\s\S]+?)%>/g; + +module.exports = reEscape; diff --git a/platforms/android/assets/www/node_modules/lodash/_reEvaluate.js b/platforms/android/assets/www/node_modules/lodash/_reEvaluate.js new file mode 100644 index 0000000..6adfc31 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_reEvaluate.js @@ -0,0 +1,4 @@ +/** Used to match template delimiters. */ +var reEvaluate = /<%([\s\S]+?)%>/g; + +module.exports = reEvaluate; diff --git a/platforms/android/assets/www/node_modules/lodash/_reInterpolate.js b/platforms/android/assets/www/node_modules/lodash/_reInterpolate.js new file mode 100644 index 0000000..d02ff0b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_reInterpolate.js @@ -0,0 +1,4 @@ +/** Used to match template delimiters. */ +var reInterpolate = /<%=([\s\S]+?)%>/g; + +module.exports = reInterpolate; diff --git a/platforms/android/assets/www/node_modules/lodash/_realNames.js b/platforms/android/assets/www/node_modules/lodash/_realNames.js new file mode 100644 index 0000000..aa0d529 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_realNames.js @@ -0,0 +1,4 @@ +/** Used to lookup unminified function names. */ +var realNames = {}; + +module.exports = realNames; diff --git a/platforms/android/assets/www/node_modules/lodash/_reorder.js b/platforms/android/assets/www/node_modules/lodash/_reorder.js new file mode 100644 index 0000000..a3502b0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_reorder.js @@ -0,0 +1,29 @@ +var copyArray = require('./_copyArray'), + isIndex = require('./_isIndex'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ +function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = copyArray(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; +} + +module.exports = reorder; diff --git a/platforms/android/assets/www/node_modules/lodash/_replaceHolders.js b/platforms/android/assets/www/node_modules/lodash/_replaceHolders.js new file mode 100644 index 0000000..74360ec --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_replaceHolders.js @@ -0,0 +1,29 @@ +/** Used as the internal argument placeholder. */ +var PLACEHOLDER = '__lodash_placeholder__'; + +/** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ +function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value === placeholder || value === PLACEHOLDER) { + array[index] = PLACEHOLDER; + result[resIndex++] = index; + } + } + return result; +} + +module.exports = replaceHolders; diff --git a/platforms/android/assets/www/node_modules/lodash/_root.js b/platforms/android/assets/www/node_modules/lodash/_root.js new file mode 100644 index 0000000..d2cfd31 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_root.js @@ -0,0 +1,41 @@ +var checkGlobal = require('./_checkGlobal'); + +/** Used to determine if values are of the language type `Object`. */ +var objectTypes = { + 'function': true, + 'object': true +}; + +/** Detect free variable `exports`. */ +var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; + +/** Detect free variable `module`. */ +var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); + +/** Detect free variable `self`. */ +var freeSelf = checkGlobal(objectTypes[typeof self] && self); + +/** Detect free variable `window`. */ +var freeWindow = checkGlobal(objectTypes[typeof window] && window); + +/** Detect `this` as the global object. */ +var thisGlobal = checkGlobal(objectTypes[typeof this] && this); + +/** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ +var root = freeGlobal || + ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || + freeSelf || thisGlobal || Function('return this')(); + +module.exports = root; diff --git a/platforms/android/assets/www/node_modules/lodash/_setData.js b/platforms/android/assets/www/node_modules/lodash/_setData.js new file mode 100644 index 0000000..8b2efca --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_setData.js @@ -0,0 +1,41 @@ +var baseSetData = require('./_baseSetData'), + now = require('./now'); + +/** Used to detect hot functions by number of calls within a span of milliseconds. */ +var HOT_COUNT = 150, + HOT_SPAN = 16; + +/** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity function + * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ +var setData = (function() { + var count = 0, + lastCalled = 0; + + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; + } + return baseSetData(key, value); + }; +}()); + +module.exports = setData; diff --git a/platforms/android/assets/www/node_modules/lodash/_setToArray.js b/platforms/android/assets/www/node_modules/lodash/_setToArray.js new file mode 100644 index 0000000..6b24f30 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_setToArray.js @@ -0,0 +1,18 @@ +/** + * Converts `set` to an array. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the converted array. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +module.exports = setToArray; diff --git a/platforms/android/assets/www/node_modules/lodash/_stackClear.js b/platforms/android/assets/www/node_modules/lodash/_stackClear.js new file mode 100644 index 0000000..8255536 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_stackClear.js @@ -0,0 +1,12 @@ +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ +function stackClear() { + this.__data__ = { 'array': [], 'map': null }; +} + +module.exports = stackClear; diff --git a/platforms/android/assets/www/node_modules/lodash/_stackDelete.js b/platforms/android/assets/www/node_modules/lodash/_stackDelete.js new file mode 100644 index 0000000..7e38a13 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_stackDelete.js @@ -0,0 +1,19 @@ +var assocDelete = require('./_assocDelete'); + +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + var data = this.__data__, + array = data.array; + + return array ? assocDelete(array, key) : data.map['delete'](key); +} + +module.exports = stackDelete; diff --git a/platforms/android/assets/www/node_modules/lodash/_stackGet.js b/platforms/android/assets/www/node_modules/lodash/_stackGet.js new file mode 100644 index 0000000..20b9d9a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_stackGet.js @@ -0,0 +1,19 @@ +var assocGet = require('./_assocGet'); + +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + var data = this.__data__, + array = data.array; + + return array ? assocGet(array, key) : data.map.get(key); +} + +module.exports = stackGet; diff --git a/platforms/android/assets/www/node_modules/lodash/_stackHas.js b/platforms/android/assets/www/node_modules/lodash/_stackHas.js new file mode 100644 index 0000000..7a3b0b9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_stackHas.js @@ -0,0 +1,19 @@ +var assocHas = require('./_assocHas'); + +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + var data = this.__data__, + array = data.array; + + return array ? assocHas(array, key) : data.map.has(key); +} + +module.exports = stackHas; diff --git a/platforms/android/assets/www/node_modules/lodash/_stackSet.js b/platforms/android/assets/www/node_modules/lodash/_stackSet.js new file mode 100644 index 0000000..0194d10 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_stackSet.js @@ -0,0 +1,36 @@ +var MapCache = require('./_MapCache'), + assocSet = require('./_assocSet'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache object. + */ +function stackSet(key, value) { + var data = this.__data__, + array = data.array; + + if (array) { + if (array.length < (LARGE_ARRAY_SIZE - 1)) { + assocSet(array, key, value); + } else { + data.array = null; + data.map = new MapCache(array); + } + } + var map = data.map; + if (map) { + map.set(key, value); + } + return this; +} + +module.exports = stackSet; diff --git a/platforms/android/assets/www/node_modules/lodash/_stringSize.js b/platforms/android/assets/www/node_modules/lodash/_stringSize.js new file mode 100644 index 0000000..7aa9f41 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_stringSize.js @@ -0,0 +1,48 @@ +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + rsAstralRange + ']', + rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + if (!(string && reHasComplexSymbol.test(string))) { + return string.length; + } + var result = reComplexSymbol.lastIndex = 0; + while (reComplexSymbol.test(string)) { + result++; + } + return result; +} + +module.exports = stringSize; diff --git a/platforms/android/assets/www/node_modules/lodash/_stringToArray.js b/platforms/android/assets/www/node_modules/lodash/_stringToArray.js new file mode 100644 index 0000000..90986f0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_stringToArray.js @@ -0,0 +1,38 @@ +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + rsAstralRange + ']', + rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function stringToArray(string) { + return string.match(reComplexSymbol); +} + +module.exports = stringToArray; diff --git a/platforms/android/assets/www/node_modules/lodash/_stringToPath.js b/platforms/android/assets/www/node_modules/lodash/_stringToPath.js new file mode 100644 index 0000000..a8fd82a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_stringToPath.js @@ -0,0 +1,24 @@ +var toString = require('./toString'); + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +function stringToPath(string) { + var result = []; + toString(string).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +} + +module.exports = stringToPath; diff --git a/platforms/android/assets/www/node_modules/lodash/_unescapeHtmlChar.js b/platforms/android/assets/www/node_modules/lodash/_unescapeHtmlChar.js new file mode 100644 index 0000000..28b3454 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_unescapeHtmlChar.js @@ -0,0 +1,22 @@ +/** Used to map HTML entities to characters. */ +var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' +}; + +/** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ +function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; +} + +module.exports = unescapeHtmlChar; diff --git a/platforms/android/assets/www/node_modules/lodash/_wrapperClone.js b/platforms/android/assets/www/node_modules/lodash/_wrapperClone.js new file mode 100644 index 0000000..7bb58a2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/_wrapperClone.js @@ -0,0 +1,23 @@ +var LazyWrapper = require('./_LazyWrapper'), + LodashWrapper = require('./_LodashWrapper'), + copyArray = require('./_copyArray'); + +/** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ +function wrapperClone(wrapper) { + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; +} + +module.exports = wrapperClone; diff --git a/platforms/android/assets/www/node_modules/lodash/add.js b/platforms/android/assets/www/node_modules/lodash/add.js new file mode 100644 index 0000000..d097850 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/add.js @@ -0,0 +1,29 @@ +/** + * Adds two numbers. + * + * @static + * @memberOf _ + * @category Math + * @param {number} augend The first number in an addition. + * @param {number} addend The second number in an addition. + * @returns {number} Returns the total. + * @example + * + * _.add(6, 4); + * // => 10 + */ +function add(augend, addend) { + var result; + if (augend === undefined && addend === undefined) { + return 0; + } + if (augend !== undefined) { + result = augend; + } + if (addend !== undefined) { + result = result === undefined ? addend : (result + addend); + } + return result; +} + +module.exports = add; diff --git a/platforms/android/assets/www/node_modules/lodash/after.js b/platforms/android/assets/www/node_modules/lodash/after.js new file mode 100644 index 0000000..41b0146 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/after.js @@ -0,0 +1,41 @@ +var toInteger = require('./toInteger'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ +function after(n, func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; +} + +module.exports = after; diff --git a/platforms/android/assets/www/node_modules/lodash/array.js b/platforms/android/assets/www/node_modules/lodash/array.js new file mode 100644 index 0000000..bfded5c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/array.js @@ -0,0 +1,65 @@ +module.exports = { + 'chunk': require('./chunk'), + 'compact': require('./compact'), + 'concat': require('./concat'), + 'difference': require('./difference'), + 'differenceBy': require('./differenceBy'), + 'differenceWith': require('./differenceWith'), + 'drop': require('./drop'), + 'dropRight': require('./dropRight'), + 'dropRightWhile': require('./dropRightWhile'), + 'dropWhile': require('./dropWhile'), + 'fill': require('./fill'), + 'findIndex': require('./findIndex'), + 'findLastIndex': require('./findLastIndex'), + 'flatten': require('./flatten'), + 'flattenDeep': require('./flattenDeep'), + 'flattenDepth': require('./flattenDepth'), + 'fromPairs': require('./fromPairs'), + 'head': require('./head'), + 'indexOf': require('./indexOf'), + 'initial': require('./initial'), + 'intersection': require('./intersection'), + 'intersectionBy': require('./intersectionBy'), + 'intersectionWith': require('./intersectionWith'), + 'join': require('./join'), + 'last': require('./last'), + 'lastIndexOf': require('./lastIndexOf'), + 'pull': require('./pull'), + 'pullAll': require('./pullAll'), + 'pullAllBy': require('./pullAllBy'), + 'pullAllWith': require('./pullAllWith'), + 'pullAt': require('./pullAt'), + 'remove': require('./remove'), + 'reverse': require('./reverse'), + 'slice': require('./slice'), + 'sortedIndex': require('./sortedIndex'), + 'sortedIndexBy': require('./sortedIndexBy'), + 'sortedIndexOf': require('./sortedIndexOf'), + 'sortedLastIndex': require('./sortedLastIndex'), + 'sortedLastIndexBy': require('./sortedLastIndexBy'), + 'sortedLastIndexOf': require('./sortedLastIndexOf'), + 'sortedUniq': require('./sortedUniq'), + 'sortedUniqBy': require('./sortedUniqBy'), + 'tail': require('./tail'), + 'take': require('./take'), + 'takeRight': require('./takeRight'), + 'takeRightWhile': require('./takeRightWhile'), + 'takeWhile': require('./takeWhile'), + 'union': require('./union'), + 'unionBy': require('./unionBy'), + 'unionWith': require('./unionWith'), + 'uniq': require('./uniq'), + 'uniqBy': require('./uniqBy'), + 'uniqWith': require('./uniqWith'), + 'unzip': require('./unzip'), + 'unzipWith': require('./unzipWith'), + 'without': require('./without'), + 'xor': require('./xor'), + 'xorBy': require('./xorBy'), + 'xorWith': require('./xorWith'), + 'zip': require('./zip'), + 'zipObject': require('./zipObject'), + 'zipObjectDeep': require('./zipObjectDeep'), + 'zipWith': require('./zipWith') +}; diff --git a/platforms/android/assets/www/node_modules/lodash/ary.js b/platforms/android/assets/www/node_modules/lodash/ary.js new file mode 100644 index 0000000..b3906ac --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/ary.js @@ -0,0 +1,28 @@ +var createWrapper = require('./_createWrapper'); + +/** Used to compose bitmasks for wrapper metadata. */ +var ARY_FLAG = 128; + +/** + * Creates a function that accepts up to `n` arguments, ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ +function ary(func, n, guard) { + n = guard ? undefined : n; + n = (func && n == null) ? func.length : n; + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); +} + +module.exports = ary; diff --git a/platforms/android/assets/www/node_modules/lodash/assign.js b/platforms/android/assets/www/node_modules/lodash/assign.js new file mode 100644 index 0000000..123ff49 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/assign.js @@ -0,0 +1,62 @@ +var assignValue = require('./_assignValue'), + copyObject = require('./_copyObject'), + createAssigner = require('./_createAssigner'), + isArrayLike = require('./isArrayLike'), + isPrototype = require('./_isPrototype'), + keys = require('./keys'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ +var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); + +/** + * Assigns own enumerable properties of source objects to the destination + * object. Source objects are applied from left to right. Subsequent sources + * overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.c = 3; + * } + * + * function Bar() { + * this.e = 5; + * } + * + * Foo.prototype.d = 4; + * Bar.prototype.f = 6; + * + * _.assign({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3, 'e': 5 } + */ +var assign = createAssigner(function(object, source) { + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } +}); + +module.exports = assign; diff --git a/platforms/android/assets/www/node_modules/lodash/assignIn.js b/platforms/android/assets/www/node_modules/lodash/assignIn.js new file mode 100644 index 0000000..0315ffe --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/assignIn.js @@ -0,0 +1,56 @@ +var assignValue = require('./_assignValue'), + copyObject = require('./_copyObject'), + createAssigner = require('./_createAssigner'), + isArrayLike = require('./isArrayLike'), + isPrototype = require('./_isPrototype'), + keysIn = require('./keysIn'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ +var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); + +/** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * function Bar() { + * this.d = 4; + * } + * + * Foo.prototype.c = 3; + * Bar.prototype.e = 5; + * + * _.assignIn({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 } + */ +var assignIn = createAssigner(function(object, source) { + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keysIn(source), object); + return; + } + for (var key in source) { + assignValue(object, key, source[key]); + } +}); + +module.exports = assignIn; diff --git a/platforms/android/assets/www/node_modules/lodash/assignInWith.js b/platforms/android/assets/www/node_modules/lodash/assignInWith.js new file mode 100644 index 0000000..da73ef7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/assignInWith.js @@ -0,0 +1,36 @@ +var copyObjectWith = require('./_copyObjectWith'), + createAssigner = require('./_createAssigner'), + keysIn = require('./keysIn'); + +/** + * This method is like `_.assignIn` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keysIn(source), object, customizer); +}); + +module.exports = assignInWith; diff --git a/platforms/android/assets/www/node_modules/lodash/assignWith.js b/platforms/android/assets/www/node_modules/lodash/assignWith.js new file mode 100644 index 0000000..eb7915b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/assignWith.js @@ -0,0 +1,35 @@ +var copyObjectWith = require('./_copyObjectWith'), + createAssigner = require('./_createAssigner'), + keys = require('./keys'); + +/** + * This method is like `_.assign` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keys(source), object, customizer); +}); + +module.exports = assignWith; diff --git a/platforms/android/assets/www/node_modules/lodash/at.js b/platforms/android/assets/www/node_modules/lodash/at.js new file mode 100644 index 0000000..cb35a54 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/at.js @@ -0,0 +1,29 @@ +var baseAt = require('./_baseAt'), + baseFlatten = require('./_baseFlatten'), + rest = require('./rest'); + +/** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths of elements to pick, + * specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + * + * _.at(['a', 'b', 'c'], 0, 2); + * // => ['a', 'c'] + */ +var at = rest(function(object, paths) { + return baseAt(object, baseFlatten(paths, 1)); +}); + +module.exports = at; diff --git a/platforms/android/assets/www/node_modules/lodash/attempt.js b/platforms/android/assets/www/node_modules/lodash/attempt.js new file mode 100644 index 0000000..52bc3e3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/attempt.js @@ -0,0 +1,33 @@ +var apply = require('./_apply'), + isError = require('./isError'), + rest = require('./rest'); + +/** + * Attempts to invoke `func`, returning either the result or the caught error + * object. Any additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Util + * @param {Function} func The function to attempt. + * @returns {*} Returns the `func` result or error object. + * @example + * + * // Avoid throwing errors for invalid selectors. + * var elements = _.attempt(function(selector) { + * return document.querySelectorAll(selector); + * }, '>_>'); + * + * if (_.isError(elements)) { + * elements = []; + * } + */ +var attempt = rest(function(func, args) { + try { + return apply(func, undefined, args); + } catch (e) { + return isError(e) ? e : new Error(e); + } +}); + +module.exports = attempt; diff --git a/platforms/android/assets/www/node_modules/lodash/before.js b/platforms/android/assets/www/node_modules/lodash/before.js new file mode 100644 index 0000000..47148b1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/before.js @@ -0,0 +1,39 @@ +var toInteger = require('./toInteger'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ +function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; +} + +module.exports = before; diff --git a/platforms/android/assets/www/node_modules/lodash/bind.js b/platforms/android/assets/www/node_modules/lodash/bind.js new file mode 100644 index 0000000..a594063 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/bind.js @@ -0,0 +1,57 @@ +var createWrapper = require('./_createWrapper'), + getPlaceholder = require('./_getPlaceholder'), + replaceHolders = require('./_replaceHolders'), + rest = require('./rest'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ +var bind = rest(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getPlaceholder(bind)); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); +}); + +// Assign default placeholders. +bind.placeholder = {}; + +module.exports = bind; diff --git a/platforms/android/assets/www/node_modules/lodash/bindAll.js b/platforms/android/assets/www/node_modules/lodash/bindAll.js new file mode 100644 index 0000000..ddbc2ff --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/bindAll.js @@ -0,0 +1,39 @@ +var arrayEach = require('./_arrayEach'), + baseFlatten = require('./_baseFlatten'), + bind = require('./bind'), + rest = require('./rest'); + +/** + * Binds methods of an object to the object itself, overwriting the existing + * method. + * + * **Note:** This method doesn't set the "length" property of bound functions. + * + * @static + * @memberOf _ + * @category Util + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} methodNames The object method names to bind, + * specified individually or in arrays. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view, 'onClick'); + * jQuery(element).on('click', view.onClick); + * // => logs 'clicked docs' when clicked + */ +var bindAll = rest(function(object, methodNames) { + arrayEach(baseFlatten(methodNames, 1), function(key) { + object[key] = bind(object[key], object); + }); + return object; +}); + +module.exports = bindAll; diff --git a/platforms/android/assets/www/node_modules/lodash/bindKey.js b/platforms/android/assets/www/node_modules/lodash/bindKey.js new file mode 100644 index 0000000..5f5c982 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/bindKey.js @@ -0,0 +1,67 @@ +var createWrapper = require('./_createWrapper'), + getPlaceholder = require('./_getPlaceholder'), + replaceHolders = require('./_replaceHolders'), + rest = require('./rest'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to invoke the method on. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // Bound with placeholders. + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ +var bindKey = rest(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getPlaceholder(bindKey)); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); +}); + +// Assign default placeholders. +bindKey.placeholder = {}; + +module.exports = bindKey; diff --git a/platforms/android/assets/www/node_modules/lodash/camelCase.js b/platforms/android/assets/www/node_modules/lodash/camelCase.js new file mode 100644 index 0000000..00239e3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/camelCase.js @@ -0,0 +1,28 @@ +var capitalize = require('./capitalize'), + createCompounder = require('./_createCompounder'); + +/** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar'); + * // => 'fooBar' + * + * _.camelCase('__foo_bar__'); + * // => 'fooBar' + */ +var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); +}); + +module.exports = camelCase; diff --git a/platforms/android/assets/www/node_modules/lodash/capitalize.js b/platforms/android/assets/www/node_modules/lodash/capitalize.js new file mode 100644 index 0000000..4daec03 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/capitalize.js @@ -0,0 +1,22 @@ +var toString = require('./toString'), + upperFirst = require('./upperFirst'); + +/** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ +function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); +} + +module.exports = capitalize; diff --git a/platforms/android/assets/www/node_modules/lodash/castArray.js b/platforms/android/assets/www/node_modules/lodash/castArray.js new file mode 100644 index 0000000..4ea96fc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/castArray.js @@ -0,0 +1,43 @@ +var isArray = require('./isArray'); + +/** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ +function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; +} + +module.exports = castArray; diff --git a/platforms/android/assets/www/node_modules/lodash/ceil.js b/platforms/android/assets/www/node_modules/lodash/ceil.js new file mode 100644 index 0000000..ecf2f12 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/ceil.js @@ -0,0 +1,25 @@ +var createRound = require('./_createRound'); + +/** + * Computes `number` rounded up to `precision`. + * + * @static + * @memberOf _ + * @category Math + * @param {number} number The number to round up. + * @param {number} [precision=0] The precision to round up to. + * @returns {number} Returns the rounded up number. + * @example + * + * _.ceil(4.006); + * // => 5 + * + * _.ceil(6.004, 2); + * // => 6.01 + * + * _.ceil(6040, -2); + * // => 6100 + */ +var ceil = createRound('ceil'); + +module.exports = ceil; diff --git a/platforms/android/assets/www/node_modules/lodash/chain.js b/platforms/android/assets/www/node_modules/lodash/chain.js new file mode 100644 index 0000000..3300933 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/chain.js @@ -0,0 +1,36 @@ +var lodash = require('./wrapperLodash'); + +/** + * Creates a `lodash` object that wraps `value` with explicit method chaining enabled. + * The result of such method chaining must be unwrapped with `_#value`. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ +function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; +} + +module.exports = chain; diff --git a/platforms/android/assets/www/node_modules/lodash/chunk.js b/platforms/android/assets/www/node_modules/lodash/chunk.js new file mode 100644 index 0000000..429a371 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/chunk.js @@ -0,0 +1,44 @@ +var baseSlice = require('./_baseSlice'), + toInteger = require('./toInteger'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * Creates an array of elements split into groups the length of `size`. + * If `array` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=0] The length of each chunk. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ +function chunk(array, size) { + size = nativeMax(toInteger(size), 0); + + var length = array ? array.length : 0; + if (!length || size < 1) { + return []; + } + var index = 0, + resIndex = 0, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[resIndex++] = baseSlice(array, index, (index += size)); + } + return result; +} + +module.exports = chunk; diff --git a/platforms/android/assets/www/node_modules/lodash/clamp.js b/platforms/android/assets/www/node_modules/lodash/clamp.js new file mode 100644 index 0000000..9e186d8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/clamp.js @@ -0,0 +1,38 @@ +var baseClamp = require('./_baseClamp'), + toNumber = require('./toNumber'); + +/** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ +function clamp(number, lower, upper) { + if (upper === undefined) { + upper = lower; + lower = undefined; + } + if (upper !== undefined) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); +} + +module.exports = clamp; diff --git a/platforms/android/assets/www/node_modules/lodash/clone.js b/platforms/android/assets/www/node_modules/lodash/clone.js new file mode 100644 index 0000000..fb83952 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/clone.js @@ -0,0 +1,31 @@ +var baseClone = require('./_baseClone'); + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return baseClone(value, false, true); +} + +module.exports = clone; diff --git a/platforms/android/assets/www/node_modules/lodash/cloneDeep.js b/platforms/android/assets/www/node_modules/lodash/cloneDeep.js new file mode 100644 index 0000000..b8e95d3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/cloneDeep.js @@ -0,0 +1,23 @@ +var baseClone = require('./_baseClone'); + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return baseClone(value, true, true); +} + +module.exports = cloneDeep; diff --git a/platforms/android/assets/www/node_modules/lodash/cloneDeepWith.js b/platforms/android/assets/www/node_modules/lodash/cloneDeepWith.js new file mode 100644 index 0000000..4d04b22 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/cloneDeepWith.js @@ -0,0 +1,33 @@ +var baseClone = require('./_baseClone'); + +/** + * This method is like `_.cloneWith` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * } + * + * var el = _.cloneDeepWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 20 + */ +function cloneDeepWith(value, customizer) { + return baseClone(value, true, true, customizer); +} + +module.exports = cloneDeepWith; diff --git a/platforms/android/assets/www/node_modules/lodash/cloneWith.js b/platforms/android/assets/www/node_modules/lodash/cloneWith.js new file mode 100644 index 0000000..e689231 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/cloneWith.js @@ -0,0 +1,36 @@ +var baseClone = require('./_baseClone'); + +/** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * } + * + * var el = _.cloneWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 0 + */ +function cloneWith(value, customizer) { + return baseClone(value, false, true, customizer); +} + +module.exports = cloneWith; diff --git a/platforms/android/assets/www/node_modules/lodash/collection.js b/platforms/android/assets/www/node_modules/lodash/collection.js new file mode 100644 index 0000000..6d37b3f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/collection.js @@ -0,0 +1,29 @@ +module.exports = { + 'at': require('./at'), + 'countBy': require('./countBy'), + 'each': require('./each'), + 'eachRight': require('./eachRight'), + 'every': require('./every'), + 'filter': require('./filter'), + 'find': require('./find'), + 'findLast': require('./findLast'), + 'flatMap': require('./flatMap'), + 'forEach': require('./forEach'), + 'forEachRight': require('./forEachRight'), + 'groupBy': require('./groupBy'), + 'includes': require('./includes'), + 'invokeMap': require('./invokeMap'), + 'keyBy': require('./keyBy'), + 'map': require('./map'), + 'orderBy': require('./orderBy'), + 'partition': require('./partition'), + 'reduce': require('./reduce'), + 'reduceRight': require('./reduceRight'), + 'reject': require('./reject'), + 'sample': require('./sample'), + 'sampleSize': require('./sampleSize'), + 'shuffle': require('./shuffle'), + 'size': require('./size'), + 'some': require('./some'), + 'sortBy': require('./sortBy') +}; diff --git a/platforms/android/assets/www/node_modules/lodash/commit.js b/platforms/android/assets/www/node_modules/lodash/commit.js new file mode 100644 index 0000000..1f87f50 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/commit.js @@ -0,0 +1,32 @@ +var LodashWrapper = require('./_LodashWrapper'); + +/** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ +function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); +} + +module.exports = wrapperCommit; diff --git a/platforms/android/assets/www/node_modules/lodash/compact.js b/platforms/android/assets/www/node_modules/lodash/compact.js new file mode 100644 index 0000000..e872c20 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/compact.js @@ -0,0 +1,30 @@ +/** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ +function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[resIndex++] = value; + } + } + return result; +} + +module.exports = compact; diff --git a/platforms/android/assets/www/node_modules/lodash/concat.js b/platforms/android/assets/www/node_modules/lodash/concat.js new file mode 100644 index 0000000..1d2b846 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/concat.js @@ -0,0 +1,35 @@ +var arrayConcat = require('./_arrayConcat'), + baseFlatten = require('./_baseFlatten'), + isArray = require('./isArray'), + rest = require('./rest'); + +/** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ +var concat = rest(function(array, values) { + if (!isArray(array)) { + array = array == null ? [] : [Object(array)]; + } + values = baseFlatten(values, 1); + return arrayConcat(array, values); +}); + +module.exports = concat; diff --git a/platforms/android/assets/www/node_modules/lodash/cond.js b/platforms/android/assets/www/node_modules/lodash/cond.js new file mode 100644 index 0000000..593ac9e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/cond.js @@ -0,0 +1,58 @@ +var apply = require('./_apply'), + arrayMap = require('./_arrayMap'), + baseIteratee = require('./_baseIteratee'), + rest = require('./rest'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that iterates over `pairs` invoking the corresponding + * function of the first predicate to return truthy. The predicate-function + * pairs are invoked with the `this` binding and arguments of the created + * function. + * + * @static + * @memberOf _ + * @category Util + * @param {Array} pairs The predicate-function pairs. + * @returns {Function} Returns the new function. + * @example + * + * var func = _.cond([ + * [_.matches({ 'a': 1 }), _.constant('matches A')], + * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')], + * [_.constant(true), _.constant('no match')] + * ]); + * + * func({ 'a': 1, 'b': 2 }); + * // => 'matches A' + * + * func({ 'a': 0, 'b': 1 }); + * // => 'matches B' + * + * func({ 'a': '1', 'b': '2' }); + * // => 'no match' + */ +function cond(pairs) { + var length = pairs ? pairs.length : 0; + + pairs = !length ? [] : arrayMap(pairs, function(pair) { + if (typeof pair[1] != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return [baseIteratee(pair[0]), pair[1]]; + }); + + return rest(function(args) { + var index = -1; + while (++index < length) { + var pair = pairs[index]; + if (apply(pair[0], this, args)) { + return apply(pair[1], this, args); + } + } + }); +} + +module.exports = cond; diff --git a/platforms/android/assets/www/node_modules/lodash/conforms.js b/platforms/android/assets/www/node_modules/lodash/conforms.js new file mode 100644 index 0000000..2bfeca2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/conforms.js @@ -0,0 +1,28 @@ +var baseClone = require('./_baseClone'), + baseConforms = require('./_baseConforms'); + +/** + * Creates a function that invokes the predicate properties of `source` with + * the corresponding property values of a given object, returning `true` if + * all predicates return truthy, else `false`. + * + * @static + * @memberOf _ + * @category Util + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new function. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) })); + * // => [{ 'user': 'fred', 'age': 40 }] + */ +function conforms(source) { + return baseConforms(baseClone(source, true)); +} + +module.exports = conforms; diff --git a/platforms/android/assets/www/node_modules/lodash/constant.js b/platforms/android/assets/www/node_modules/lodash/constant.js new file mode 100644 index 0000000..5844804 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/constant.js @@ -0,0 +1,23 @@ +/** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @category Util + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new function. + * @example + * + * var object = { 'user': 'fred' }; + * var getter = _.constant(object); + * + * getter() === object; + * // => true + */ +function constant(value) { + return function() { + return value; + }; +} + +module.exports = constant; diff --git a/platforms/android/assets/www/node_modules/lodash/core.js b/platforms/android/assets/www/node_modules/lodash/core.js new file mode 100644 index 0000000..d8ba4fd --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/core.js @@ -0,0 +1,3826 @@ +/** + * @license + * lodash 4.6.1 (Custom Build) + * Build: `lodash core -o ./dist/lodash.core.js` + * Copyright 2012-2016 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '4.6.1'; + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + PARTIAL_FLAG = 32; + + /** Used to compose bitmasks for comparison styles. */ + var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + stringTag = '[object String]'; + + /** Used to match HTML entities and HTML characters. */ + var reUnescapedHtml = /[&<>"'`]/g, + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Detect free variable `exports`. */ + var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; + + /** Detect free variable `module`. */ + var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = (freeModule && freeModule.exports === freeExports) + ? freeExports + : undefined; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); + + /** Detect free variable `self`. */ + var freeSelf = checkGlobal(objectTypes[typeof self] && self); + + /** Detect free variable `window`. */ + var freeWindow = checkGlobal(objectTypes[typeof window] && window); + + /** Detect `this` as the global object. */ + var thisGlobal = checkGlobal(objectTypes[typeof this] && this); + + /** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || + ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || + freeSelf || thisGlobal || Function('return this')(); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a new array concatenating `array` with `other`. + * + * @private + * @param {Array} array The first array to concatenate. + * @param {Array} other The second array to concatenate. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + return arrayPush(copyArray(array), values); + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? current === current + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; + } + + /** + * The base implementation of methods like `_.find` and `_.findKey`, without + * support for iteratee shorthands, which iterates over `collection` using + * `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + return baseMap(props, function(key) { + return object[key]; + }); + } + + /** + * Checks if `value` is a global object. + * + * @private + * @param {*} value The value to check. + * @returns {null|Object} Returns `value` if it's a global object, else `null`. + */ + function checkGlobal(value) { + return (value && value.Object === Object) ? value : null; + } + + /** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function compareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; + } + + /** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ + function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Built-in value references. */ + var Reflect = root.Reflect, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + enumerate = Reflect ? Reflect.enumerate : undefined, + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeIsFinite = root.isFinite, + nativeKeys = Object.keys, + nativeMax = Math.max; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit method + * chaining. Methods that operate on and return arrays, collections, and + * functions can be chained together. Methods that retrieve a single value or + * may return a primitive value will automatically end the chain sequence and + * return the unwrapped value. Otherwise, the value must be unwrapped with + * `_#value`. + * + * Explicit chaining, which must be unwrapped with `_#value` in all cases, + * may be enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization to merge iteratee calls; this avoids the creation + * of intermediate arrays and can greatly reduce the number of iteratee executions. + * Sections of a chain sequence qualify for shortcut fusion if the section is + * applied to an array of at least two hundred elements and any iteratees + * accept only one argument. The heuristic for whether a section qualifies + * for shortcut fusion is subject to change. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatten`, `flattenDeep`, `flattenDepth`, `flip`, `flow`, `flowRight`, + * `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`, `intersection`, + * `intersectionBy`, `intersectionWith`, `invert`, `invertBy`, `invokeMap`, + * `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, + * `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`, + * `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, + * `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`, + * `partition`, `pick`, `pickBy`, `plant`, `property`, `propertyOf`, `pull`, + * `pullAll`, `pullAllBy`, `pullAllWith`, `pullAt`, `push`, `range`, + * `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`, + * `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, + * `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, + * `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, + * `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `update`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, + * `zipObjectDeep`, and `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `each`, `eachRight`, + * `endsWith`, `eq`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `first`, `floor`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`, `includes`, + * `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`, `isArrayBuffer`, + * `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`, `isDate`, + * `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`, `isFinite`, + * `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`, `isMatchWith`, + * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`, + * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isSet`, `isString`, + * `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, + * `maxBy`, `mean`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toInteger`, `toJSON`, `toLength`, `toLower`, + * `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, `trimEnd`, + * `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, `upperFirst`, + * `value`, and `words` + * + * @name _ + * @constructor + * @category Seq + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2, 3]); + * + * // Returns an unwrapped value. + * wrapped.reduce(_.add); + * // => 6 + * + * // Returns a wrapped value. + * var squares = wrapped.map(square); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + */ + function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + } + + /*------------------------------------------------------------------------*/ + + /** + * Used by `_.defaults` to customize its `_.assignIn` use. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. + */ + function assignInDefaults(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastFunction(value) { + return typeof value == 'function' ? value : identity; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `_.delay` and `_.defer` which accepts an array + * of `func` arguments. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments to provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, depth, isStrict, result) { + result || (result = []); + + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + if (depth > 0 && isArrayLikeObject(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ + function baseFunctions(object, props) { + return baseFilter(props, function(key) { + return isFunction(object[key]); + }); + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @param {boolean} [bitmask] The bitmask of comparison flags. + * The bitmask may be composed of the following flags: + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, customizer, bitmask, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparisons. + * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objectToString.call(object); + objTag = objTag == argsTag ? objectTag : objTag; + } + if (!othIsArr) { + othTag = objectToString.call(other); + othTag = othTag == argsTag ? objectTag : othTag; + } + var objIsObj = objTag == objectTag && !isHostObject(object), + othIsObj = othTag == objectTag && !isHostObject(other), + isSameTag = objTag == othTag; + + stack || (stack = []); + var stacked = find(stack, function(entry) { + return entry[0] === object; + }); + if (stacked && stacked[1]) { + return stacked[1] == other; + } + stack.push([object, other]); + if (isSameTag && !objIsObj) { + var result = (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, equalFunc, customizer, bitmask, stack) + : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack); + stack.pop(); + return result; + } + if (!(bitmask & PARTIAL_COMPARE_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var result = equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack); + stack.pop(); + return result; + } + } + if (!isSameTag) { + return false; + } + var result = equalObjects(object, other, equalFunc, customizer, bitmask, stack); + stack.pop(); + return result; + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(func) { + var type = typeof func; + if (type == 'function') { + return func; + } + return func == null + ? identity + : (type == 'object' ? baseMatches : baseProperty)(func); + } + + /** + * The base implementation of `_.keys` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + return nativeKeys(Object(object)); + } + + /** + * The base implementation of `_.keysIn` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + object = object == null ? object : Object(object); + + var result = []; + for (var key in object) { + result.push(key); + } + return result; + } + + // Fallback for IE < 9 with es6-shim. + if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) { + baseKeysIn = function(object) { + return iteratorToArray(enumerate(object)); + }; + } + + /** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var props = keys(source); + return function(object) { + var length = props.length; + if (object == null) { + return !length; + } + object = Object(object); + while (length--) { + var key = props[length]; + if (!(key in object && + baseIsEqual(source[key], object[key], undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG) + )) { + return false; + } + } + return true; + }; + } + + /** + * The base implementation of `_.pick` without support for individual + * property names. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function basePick(object, props) { + object = Object(object); + return reduce(props, function(result, key) { + if (key in object) { + result[key] = object[key]; + } + return result; + }, {}); + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source) { + return baseSlice(source, 0, source.length); + } + + /** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + return reduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + var copyObject = copyObjectWith; + + /** + * This function is like `copyObject` except that it accepts a function to + * customize copied values. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObjectWith(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : source[key]; + + assignValue(object, key, newValue); + } + return object; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return rest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined; + + customizer = typeof customizer == 'function' + ? (length--, customizer) + : undefined; + + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for methods like `_.forIn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtorWrapper(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new wrapped function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return fn.apply(isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { + var index = -1, + isPartial = bitmask & PARTIAL_COMPARE_FLAG, + isUnordered = bitmask & UNORDERED_COMPARE_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + var result = true; + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + var compared; + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isUnordered) { + if (!baseSome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack); + })) { + result = false; + break; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { + result = false; + break; + } + } + return result; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) { + switch (tag) { + + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) ? other != +other : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { + var isPartial = bitmask & PARTIAL_COMPARE_FLAG, + objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + var result = true; + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + var compared; + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + return result; + } + + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Creates an array of index keys for `object` values of arrays, + * `arguments` objects, and strings, otherwise `null` is returned. + * + * @private + * @param {Object} object The object to query. + * @returns {Array|null} Returns index keys, else `null`. + */ + function indexKeys(object) { + var length = object ? object.length : undefined; + if (isLength(length) && + (isArray(object) || isString(object) || isArguments(object))) { + return baseTimes(length, String); + } + return null; + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + return baseFilter(array, Boolean); + } + + /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var concat = rest(function(array, values) { + if (!isArray(array)) { + array = array == null ? [] : [Object(array)]; + } + values = baseFlatten(values, 1); + return arrayConcat(array, values); + }); + + /** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ + function flatten(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, 1) : []; + } + + /** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, INFINITY) : []; + } + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ + function head(array) { + return array ? array[0] : undefined; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else { + fromIndex = 0; + } + var index = (fromIndex || 0) - 1, + isReflexive = value === value; + + while (++index < length) { + var other = array[index]; + if ((isReflexive ? other === value : other !== other)) { + return index; + } + } + return -1; + } + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice) + * to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array ? array.length : 0; + start = start == null ? 0 : +start; + end = end === undefined ? length : +end; + return length ? baseSlice(array, start, end) : []; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps `value` with explicit method chaining enabled. + * The result of such method chaining must be unwrapped with `_#value`. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor + * is invoked with one argument; (value). The purpose of this method is to + * "tap into" a method chain in order to modify intermediate results. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * // Mutate input array. + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * The purpose of this method is to "pass thru" values replacing intermediate + * results in a method chain. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor) { + return interceptor(value); + } + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // A sequence without explicit chaining. + * _(users).head(); + * // => { 'user': 'barney', 'age': 36 } + * + * // A sequence with explicit chaining. + * _(users) + * .chain() + * .head() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias toJSON, valueOf + * @category Seq + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, guard) { + predicate = guard ? undefined : predicate; + return baseEvery(collection, baseIteratee(predicate)); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + */ + function filter(collection, predicate) { + return baseFilter(collection, baseIteratee(predicate)); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ + function find(collection, predicate) { + return baseFind(collection, baseIteratee(predicate), baseEach); + } + + /** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn` + * for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(value) { + * console.log(value); + * }); + * // => logs `1` then `2` + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' then 'b' (iteration order is not guaranteed) + */ + function forEach(collection, iteratee) { + return baseEach(collection, baseCastFunction(iteratee)); + } + + /** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`, + * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`, + * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`, + * and `words` + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee) { + return baseMap(collection, baseIteratee(iteratee)); + } + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ + function reduce(collection, iteratee, accumulator) { + return baseReduce(collection, baseIteratee(iteratee), accumulator, arguments.length < 3, baseEach); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + if (collection == null) { + return 0; + } + collection = isArrayLike(collection) ? collection : keys(collection); + return collection.length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.some(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, guard) { + predicate = guard ? undefined : predicate; + return baseSome(collection, baseIteratee(predicate)); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]] + * The iteratees to sort by, specified individually or in arrays. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, function(o) { return o.user; }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.sortBy(users, 'user', function(o) { + * return Math.floor(o.age / 10); + * }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + function sortBy(collection, iteratee) { + var index = 0; + iteratee = baseIteratee(iteratee); + + return baseMap(baseMap(collection, function(value, key, collection) { + return { 'value': value, 'index': index++, 'criteria': iteratee(value, key, collection) }; + }).sort(function(object, other) { + return compareAscending(object.criteria, other.criteria) || (object.index - other.index); + }), baseProperty('value')); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = rest(function(func, thisArg, partials) { + return createPartialWrapper(func, BIND_FLAG | PARTIAL_FLAG, thisArg, partials); + }); + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => logs 'deferred' after one or more milliseconds + */ + var defer = rest(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ + var delay = rest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); + }); + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.rest(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function rest(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = array; + return func.apply(this, otherArgs); + }; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone(value) { + if (!isObject(value)) { + return value; + } + return isArray(value) ? copyArray(value) : copyObject(value, keys(value)); + } + + /** + * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + function gt(value, other) { + return value > other; + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @type {Function} + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && objectToString.call(value) == boolTag); + } + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + function isDate(value) { + return isObjectLike(value) && objectToString.call(value) == dateTag; + } + + /** + * Checks if `value` is an empty collection or object. A value is considered + * empty if it's an `arguments` object, array, string, or jQuery-like collection + * with a length of `0` or has no own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (isArrayLike(value) && + (isArray(value) || isString(value) || + isFunction(value.splice) || isArguments(value))) { + return !value.length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are **not** supported. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MAX_VALUE); + * // => true + * + * _.isFinite(3.14); + * // => true + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8 which returns 'object' for typed array and weak map constructors, + // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && objectToString.call(value) == numberTag); + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + function isRegExp(value) { + return isObject(value) && objectToString.call(value) == regexpTag; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + function lt(value, other) { + return value < other; + } + + /** + * Converts `value` to an array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!isArrayLike(value)) { + return values(value); + } + return value.length ? copyArray(value) : []; + } + + /** + * Converts `value` to an integer. + * + * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3'); + * // => 3 + */ + var toInteger = Number; + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3); + * // => 3 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3'); + * // => 3 + */ + var toNumber = Number; + + /** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to process. + * @returns {string} Returns the string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + if (typeof value == 'string') { + return value; + } + return value == null ? '' : (value + ''); + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source objects to the destination + * object. Source objects are applied from left to right. Subsequent sources + * overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.c = 3; + * } + * + * function Bar() { + * this.e = 5; + * } + * + * Foo.prototype.d = 4; + * Bar.prototype.f = 6; + * + * _.assign({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3, 'e': 5 } + */ + var assign = createAssigner(function(object, source) { + copyObject(source, keys(source), object); + }); + + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * function Bar() { + * this.d = 4; + * } + * + * Foo.prototype.c = 3; + * Bar.prototype.e = 5; + * + * _.assignIn({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 } + */ + var assignIn = createAssigner(function(object, source) { + copyObject(source, keysIn(source), object); + }); + + /** + * This method is like `_.assignIn` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keysIn(source), object, customizer); + }); + + /** + * Creates an object that inherits from the `prototype` object. If a `properties` + * object is given its own enumerable properties are assigned to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? assign(result, properties) : result; + } + + /** + * Assigns own and inherited enumerable properties of source objects to the + * destination object for all destination properties that resolve to `undefined`. + * Source objects are applied from left to right. Once a property is set, + * additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var defaults = rest(function(args) { + args.push(undefined, assignInDefaults); + return assignInWith.apply(undefined, args); + }); + + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + function has(object, path) { + return object != null && hasOwnProperty.call(object, path); + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + var isProto = isPrototype(object); + if (!(isProto || isArrayLike(object))) { + return baseKeys(object); + } + var indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + for (var key in object) { + if (hasOwnProperty.call(object, key) && + !(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(isProto && key == 'constructor')) { + result.push(key); + } + } + return result; + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + var index = -1, + isProto = isPrototype(object), + props = baseKeysIn(object), + propsLength = props.length, + indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + while (++index < propsLength) { + var key = props[index]; + if (!(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [props] The property names to pick, specified + * individually or in arrays. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + var pick = rest(function(object, props) { + return object == null ? {} : basePick(object, baseFlatten(props, 1)); + }); + + /** + * This method is like `_.get` except that if the resolved value is a function + * it's invoked with the `this` binding of its parent object and its result + * is returned. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + var value = object == null ? undefined : object[path]; + if (value === undefined) { + value = defaultValue; + } + return isFunction(value) ? value.call(object) : value; + } + + /** + * Creates an array of the own enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object ? baseValues(object, keys(object)) : []; + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in IE < 9, they can break out of + * attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /*------------------------------------------------------------------------*/ + + /** + * This method returns the first argument given to it. + * + * @static + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'user': 'fred' }; + * + * _.identity(object) === object; + * // => true + */ + function identity(value) { + return value; + } + + /** + * Creates a function that invokes `func` with the arguments of the created + * function. If `func` is a property name the created callback returns the + * property value for a given element. If `func` is an object the created + * callback returns `true` for elements that contain the equivalent object + * properties, otherwise it returns `false`. + * + * @static + * @memberOf _ + * @category Util + * @param {*} [func=_.identity] The value to convert to a callback. + * @returns {Function} Returns the callback. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // Create custom iteratee shorthands. + * _.iteratee = _.wrap(_.iteratee, function(callback, func) { + * var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func); + * return !p ? callback(func) : function(object) { + * return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]); + * }; + * }); + * + * _.filter(users, 'age > 36'); + * // => [{ 'user': 'fred', 'age': 40 }] + */ + var iteratee = baseIteratee; + + /** + * Creates a function that performs a partial deep comparison between a given + * object and `source`, returning `true` if the given object has equivalent + * property values, else `false`. The created function is equivalent to + * `_.isMatch` with a `source` partially applied. + * + * **Note:** This method supports comparing the same values as `_.isEqual`. + * + * @static + * @memberOf _ + * @category Util + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, _.matches({ 'age': 40, 'active': false })); + * // => [{ 'user': 'fred', 'age': 40, 'active': false }] + */ + function matches(source) { + return baseMatches(assign({}, source)); + } + + /** + * Adds all own enumerable function properties of a source object to the + * destination object. If `object` is a function then methods are added to + * its prototype as well. + * + * **Note:** Use `_.runInContext` to create a pristine `lodash` function to + * avoid conflicts caused by modifying the original. + * + * @static + * @memberOf _ + * @category Util + * @param {Function|Object} [object=lodash] The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options] The options object. + * @param {boolean} [options.chain=true] Specify whether the functions added + * are chainable. + * @returns {Function|Object} Returns `object`. + * @example + * + * function vowels(string) { + * return _.filter(string, function(v) { + * return /[aeiou]/i.test(v); + * }); + * } + * + * _.mixin({ 'vowels': vowels }); + * _.vowels('fred'); + * // => ['e'] + * + * _('fred').vowels().value(); + * // => ['e'] + * + * _.mixin({ 'vowels': vowels }, { 'chain': false }); + * _('fred').vowels(); + * // => ['e'] + */ + function mixin(object, source, options) { + var props = keys(source), + methodNames = baseFunctions(source, props); + + if (options == null && + !(isObject(source) && (methodNames.length || !props.length))) { + options = source; + source = object; + object = this; + methodNames = baseFunctions(source, keys(source)); + } + var chain = (isObject(options) && 'chain' in options) ? options.chain : true, + isFunc = isFunction(object); + + baseEach(methodNames, function(methodName) { + var func = source[methodName]; + object[methodName] = func; + if (isFunc) { + object.prototype[methodName] = function() { + var chainAll = this.__chain__; + if (chain || chainAll) { + var result = object(this.__wrapped__), + actions = result.__actions__ = copyArray(this.__actions__); + + actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); + result.__chain__ = chainAll; + return result; + } + return func.apply(object, arrayPush([this.value()], arguments)); + }; + } + }); + + return object; + } + + /** + * Reverts the `_` variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Util + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + if (root._ === this) { + root._ = oldDash; + } + return this; + } + + /** + * A no-operation function that returns `undefined` regardless of the + * arguments it receives. + * + * @static + * @memberOf _ + * @category Util + * @example + * + * var object = { 'user': 'fred' }; + * + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // No operation performed. + } + + /** + * Generates a unique ID. If `prefix` is given the ID is appended to it. + * + * @static + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ + function uniqueId(prefix) { + var id = ++idCounter; + return toString(prefix) + id; + } + + /*------------------------------------------------------------------------*/ + + /** + * Computes the maximum value of `array`. If `array` is empty or falsey + * `undefined` is returned. + * + * @static + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ + function max(array) { + return (array && array.length) + ? baseExtremum(array, identity, gt) + : undefined; + } + + /** + * Computes the minimum value of `array`. If `array` is empty or falsey + * `undefined` is returned. + * + * @static + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ + function min(array) { + return (array && array.length) + ? baseExtremum(array, identity, lt) + : undefined; + } + + /*------------------------------------------------------------------------*/ + + LodashWrapper.prototype = baseCreate(lodash.prototype); + LodashWrapper.prototype.constructor = LodashWrapper; + + // Add functions that return wrapped values when chaining. + lodash.assignIn = assignIn; + lodash.before = before; + lodash.bind = bind; + lodash.chain = chain; + lodash.compact = compact; + lodash.concat = concat; + lodash.create = create; + lodash.defaults = defaults; + lodash.defer = defer; + lodash.delay = delay; + lodash.filter = filter; + lodash.flatten = flatten; + lodash.flattenDeep = flattenDeep; + lodash.iteratee = iteratee; + lodash.keys = keys; + lodash.map = map; + lodash.matches = matches; + lodash.mixin = mixin; + lodash.negate = negate; + lodash.once = once; + lodash.pick = pick; + lodash.slice = slice; + lodash.sortBy = sortBy; + lodash.tap = tap; + lodash.thru = thru; + lodash.toArray = toArray; + lodash.values = values; + + // Add aliases. + lodash.extend = assignIn; + + // Add functions to `lodash.prototype`. + mixin(lodash, lodash); + + /*------------------------------------------------------------------------*/ + + // Add functions that return unwrapped values when chaining. + lodash.clone = clone; + lodash.escape = escape; + lodash.every = every; + lodash.find = find; + lodash.forEach = forEach; + lodash.has = has; + lodash.head = head; + lodash.identity = identity; + lodash.indexOf = indexOf; + lodash.isArguments = isArguments; + lodash.isArray = isArray; + lodash.isBoolean = isBoolean; + lodash.isDate = isDate; + lodash.isEmpty = isEmpty; + lodash.isEqual = isEqual; + lodash.isFinite = isFinite; + lodash.isFunction = isFunction; + lodash.isNaN = isNaN; + lodash.isNull = isNull; + lodash.isNumber = isNumber; + lodash.isObject = isObject; + lodash.isRegExp = isRegExp; + lodash.isString = isString; + lodash.isUndefined = isUndefined; + lodash.last = last; + lodash.max = max; + lodash.min = min; + lodash.noConflict = noConflict; + lodash.noop = noop; + lodash.reduce = reduce; + lodash.result = result; + lodash.size = size; + lodash.some = some; + lodash.uniqueId = uniqueId; + + // Add aliases. + lodash.each = forEach; + lodash.first = head; + + mixin(lodash, (function() { + var source = {}; + baseForOwn(lodash, function(func, methodName) { + if (!hasOwnProperty.call(lodash.prototype, methodName)) { + source[methodName] = func; + } + }); + return source; + }()), { 'chain': false }); + + /*------------------------------------------------------------------------*/ + + /** + * The semantic version number. + * + * @static + * @memberOf _ + * @type {string} + */ + lodash.VERSION = VERSION; + + // Add `Array` and `String` methods to `lodash.prototype`. + baseEach(['pop', 'join', 'replace', 'reverse', 'split', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { + var func = (/^(?:replace|split)$/.test(methodName) ? String.prototype : arrayProto)[methodName], + chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', + retUnwrapped = /^(?:pop|join|replace|shift)$/.test(methodName); + + lodash.prototype[methodName] = function() { + var args = arguments; + if (retUnwrapped && !this.__chain__) { + return func.apply(this.value(), args); + } + return this[chainName](function(value) { + return func.apply(value, args); + }); + }; + }); + + // Add chaining functions to the `lodash` wrapper. + lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue; + + /*--------------------------------------------------------------------------*/ + + // Expose lodash on the free variable `window` or `self` when available. This + // prevents errors in cases where lodash is loaded by a script tag in the presence + // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details. + (freeWindow || freeSelf || {})._ = lodash; + + // Some AMD build optimizers like r.js check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Define as an anonymous module so, through path mapping, it can be + // referenced as the "underscore" module. + define(function() { + return lodash; + }); + } + // Check for `exports` after `define` in case a build optimizer adds an `exports` object. + else if (freeExports && freeModule) { + // Export for Node.js. + if (moduleExports) { + (freeModule.exports = lodash)._ = lodash; + } + // Export for CommonJS support. + freeExports._ = lodash; + } + else { + // Export to the global object. + root._ = lodash; + } +}.call(this)); diff --git a/platforms/android/assets/www/node_modules/lodash/core.min.js b/platforms/android/assets/www/node_modules/lodash/core.min.js new file mode 100644 index 0000000..d6a4405 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/core.min.js @@ -0,0 +1,29 @@ +/** + * @license + * lodash 4.6.1 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + * Build: `lodash core -o ./dist/lodash.core.js` + */ +;(function(){function n(n,t){for(var r=-1,e=t.length,u=n.length;++r-1&&0==n%1&&(null==t?9007199254740991:t)>n}function a(n){if(Y(n)&&!Pn(n)){if(n instanceof l)return n;if(An.call(n,"__wrapped__")){var t=new l(n.__wrapped__,n.__chain__);return t.__actions__=N(n.__actions__),t}}return new l(n)}function l(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t}function p(n,t,r,e){var u;return(u=n===an)||(u=xn[r], +u=(n===u||n!==n&&u!==u)&&!An.call(e,r)),u?t:n}function s(n){return X(n)?Fn(n):{}}function h(n,t,r){if(typeof n!="function")throw new TypeError("Expected a function");return setTimeout(function(){n.apply(an,r)},t)}function v(n,t){var r=true;return $n(n,function(n,e,u){return r=!!t(n,e,u)}),r}function y(n,t){var r=[];return $n(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function _(t,r,e,u){u||(u=[]);for(var o=-1,i=t.length;++o0&&Y(c)&&L(c)&&(e||Pn(c)||K(c))?r>1?_(c,r-1,e,u):n(u,c):e||(u[u.length]=c); +}return u}function b(n,t){return n&&qn(n,t,en)}function g(n,t){return y(t,function(t){return Q(n[t])})}function j(n,t,r,e,u){return n===t?true:null==n||null==t||!X(n)&&!Y(t)?n!==n&&t!==t:d(n,t,j,r,e,u)}function d(n,t,r,e,u,o){var i=Pn(n),f=Pn(t),a="[object Array]",l="[object Array]";i||(a=kn.call(n),a="[object Arguments]"==a?"[object Object]":a),f||(l=kn.call(t),l="[object Arguments]"==l?"[object Object]":l);var p="[object Object]"==a&&!c(n),f="[object Object]"==l&&!c(t),l=a==l;o||(o=[]);var s=J(o,function(t){ +return t[0]===n});return s&&s[1]?s[1]==t:(o.push([n,t]),l&&!p?(t=i||isTypedArray(n)?I(n,t,r,e,u,o):$(n,t,a),o.pop(),t):2&u||(i=p&&An.call(n,"__wrapped__"),a=f&&An.call(t,"__wrapped__"),!i&&!a)?l?(t=q(n,t,r,e,u,o),o.pop(),t):false:(t=r(i?n.value():n,a?t.value():t,e,u,o),o.pop(),t))}function m(n){var t=typeof n;return"function"==t?n:null==n?cn:("object"==t?x:E)(n)}function w(n){n=null==n?n:Object(n);var t,r=[];for(t in n)r.push(t);return r}function O(n,t){var r=-1,e=L(n)?Array(n.length):[];return $n(n,function(n,u,o){ +e[++r]=t(n,u,o)}),e}function x(n){var t=en(n);return function(r){var e=t.length;if(null==r)return!e;for(r=Object(r);e--;){var u=t[e];if(!(u in r&&j(n[u],r[u],an,3)))return false}return true}}function A(n,t){return n=Object(n),P(t,function(t,r){return r in n&&(t[r]=n[r]),t},{})}function E(n){return function(t){return null==t?an:t[n]}}function k(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Array(u);++e1?r[u-1]:an,o=typeof o=="function"?(u--,o):an;for(t=Object(t);++ef))return false;for(a=true;++iarguments.length,$n)}function U(n,t){var r;if(typeof t!="function")throw new TypeError("Expected a function");return n=Un(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=an),r}}function V(n){var t;if(typeof n!="function")throw new TypeError("Expected a function"); +return t=In(t===an?n.length-1:Un(t),0),function(){for(var r=arguments,e=-1,u=In(r.length-t,0),o=Array(u);++et}function K(n){return Y(n)&&L(n)&&An.call(n,"callee")&&(!Rn.call(n,"callee")||"[object Arguments]"==kn.call(n))}function L(n){return null!=n&&W(zn(n))&&!Q(n)}function Q(n){return n=X(n)?kn.call(n):"","[object Function]"==n||"[object GeneratorFunction]"==n}function W(n){return typeof n=="number"&&n>-1&&0==n%1&&9007199254740991>=n; +}function X(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function Y(n){return!!n&&typeof n=="object"}function Z(n){return typeof n=="number"||Y(n)&&"[object Number]"==kn.call(n)}function nn(n){return typeof n=="string"||!Pn(n)&&Y(n)&&"[object String]"==kn.call(n)}function tn(n,t){return t>n}function rn(n){return typeof n=="string"?n:null==n?"":n+""}function en(n){var t=C(n);if(!t&&!L(n))return Dn(Object(n));var r,e=z(n),u=!!e,e=e||[],o=e.length;for(r in n)!An.call(n,r)||u&&("length"==r||f(r,o))||t&&"constructor"==r||e.push(r); +return e}function un(n){for(var t=-1,r=C(n),e=w(n),u=e.length,o=z(n),i=!!o,o=o||[],c=o.length;++t"'`]/g,sn=RegExp(pn.source),hn=/^(?:0|[1-9]\d*)$/,vn={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},yn={"function":true,object:true},_n=yn[typeof exports]&&exports&&!exports.nodeType?exports:an,bn=yn[typeof module]&&module&&!module.nodeType?module:an,gn=bn&&bn.exports===_n?_n:an,jn=o(yn[typeof self]&&self),dn=o(yn[typeof window]&&window),mn=o(yn[typeof this]&&this),wn=o(_n&&bn&&typeof global=="object"&&global)||dn!==(mn&&mn.window)&&dn||jn||mn||Function("return this")(),On=Array.prototype,xn=Object.prototype,An=xn.hasOwnProperty,En=0,kn=xn.toString,Nn=wn._,Sn=wn.Reflect,Tn=Sn?Sn.f:an,Fn=Object.create,Rn=xn.propertyIsEnumerable,Bn=wn.isFinite,Dn=Object.keys,In=Math.max,$n=function(n,t){ +return function(r,e){if(null==r)return r;if(!L(r))return n(r,e);for(var u=r.length,o=t?u:-1,i=Object(r);(t?o--:++oe&&!c||!i||u&&!f&&a||o&&a){r=1;break n}if(e>r&&!u||!a||c&&!o&&i||f&&i){r=-1;break n}}r=0}return r||n.b-t.b; +}),E("c"))},a.tap=function(n,t){return t(n),n},a.thru=function(n,t){return t(n)},a.toArray=function(n){return L(n)?n.length?N(n):[]:on(n)},a.values=on,a.extend=Kn,fn(a,a),a.clone=function(n){return X(n)?Pn(n)?N(n):F(n,en(n)):n},a.escape=function(n){return(n=rn(n))&&sn.test(n)?n.replace(pn,i):n},a.every=function(n,t,r){return t=r?an:t,v(n,m(t))},a.find=J,a.forEach=M,a.has=function(n,t){return null!=n&&An.call(n,t)},a.head=G,a.identity=cn,a.indexOf=function(n,t,r){var e=n?n.length:0;r=typeof r=="number"?0>r?In(e+r,0):r:0, +r=(r||0)-1;for(var u=t===t;++r { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ +var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); +}); + +module.exports = countBy; diff --git a/platforms/android/assets/www/node_modules/lodash/create.js b/platforms/android/assets/www/node_modules/lodash/create.js new file mode 100644 index 0000000..dddbd29 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/create.js @@ -0,0 +1,41 @@ +var baseAssign = require('./_baseAssign'), + baseCreate = require('./_baseCreate'); + +/** + * Creates an object that inherits from the `prototype` object. If a `properties` + * object is given its own enumerable properties are assigned to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ +function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? baseAssign(result, properties) : result; +} + +module.exports = create; diff --git a/platforms/android/assets/www/node_modules/lodash/curry.js b/platforms/android/assets/www/node_modules/lodash/curry.js new file mode 100644 index 0000000..1c5e8a5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/curry.js @@ -0,0 +1,56 @@ +var createWrapper = require('./_createWrapper'); + +/** Used to compose bitmasks for wrapper metadata. */ +var CURRY_FLAG = 8; + +/** + * Creates a function that accepts arguments of `func` and either invokes + * `func` returning its result, if at least `arity` number of arguments have + * been provided, or returns a function that accepts the remaining `func` + * arguments, and so on. The arity of `func` may be specified if `func.length` + * is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ +function curry(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curry.placeholder; + return result; +} + +// Assign default placeholders. +curry.placeholder = {}; + +module.exports = curry; diff --git a/platforms/android/assets/www/node_modules/lodash/curryRight.js b/platforms/android/assets/www/node_modules/lodash/curryRight.js new file mode 100644 index 0000000..8521fdc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/curryRight.js @@ -0,0 +1,53 @@ +var createWrapper = require('./_createWrapper'); + +/** Used to compose bitmasks for wrapper metadata. */ +var CURRY_RIGHT_FLAG = 16; + +/** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ +function curryRight(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryRight.placeholder; + return result; +} + +// Assign default placeholders. +curryRight.placeholder = {}; + +module.exports = curryRight; diff --git a/platforms/android/assets/www/node_modules/lodash/date.js b/platforms/android/assets/www/node_modules/lodash/date.js new file mode 100644 index 0000000..cbf5b41 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/date.js @@ -0,0 +1,3 @@ +module.exports = { + 'now': require('./now') +}; diff --git a/platforms/android/assets/www/node_modules/lodash/debounce.js b/platforms/android/assets/www/node_modules/lodash/debounce.js new file mode 100644 index 0000000..45f52ce --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/debounce.js @@ -0,0 +1,177 @@ +var isObject = require('./isObject'), + now = require('./now'), + toNumber = require('./toNumber'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide an options object to indicate whether `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent calls + * to the debounced function return the result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it's invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ +function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + leading = false, + maxWait = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait); + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + lastCalled = 0; + args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined; + } + + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function flush() { + if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) { + result = func.apply(thisArg, args); + } + cancel(); + return result; + } + + function maxDelayed() { + complete(trailing, timeoutId); + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!lastCalled && !maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled); + + var isCalled = (remaining <= 0 || remaining > maxWait) && + (leading || maxTimeoutId); + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; +} + +module.exports = debounce; diff --git a/platforms/android/assets/www/node_modules/lodash/deburr.js b/platforms/android/assets/www/node_modules/lodash/deburr.js new file mode 100644 index 0000000..7e75034 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/deburr.js @@ -0,0 +1,39 @@ +var deburrLetter = require('./_deburrLetter'), + toString = require('./toString'); + +/** Used to match latin-1 supplementary letters (excluding mathematical operators). */ +var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + +/** Used to compose unicode character classes. */ +var rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0'; + +/** Used to compose unicode capture groups. */ +var rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']'; + +/** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ +var reComboMark = RegExp(rsCombo, 'g'); + +/** + * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ +function deburr(string) { + string = toString(string); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); +} + +module.exports = deburr; diff --git a/platforms/android/assets/www/node_modules/lodash/defaults.js b/platforms/android/assets/www/node_modules/lodash/defaults.js new file mode 100644 index 0000000..eded284 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/defaults.js @@ -0,0 +1,30 @@ +var apply = require('./_apply'), + assignInDefaults = require('./_assignInDefaults'), + assignInWith = require('./assignInWith'), + rest = require('./rest'); + +/** + * Assigns own and inherited enumerable properties of source objects to the + * destination object for all destination properties that resolve to `undefined`. + * Source objects are applied from left to right. Once a property is set, + * additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ +var defaults = rest(function(args) { + args.push(undefined, assignInDefaults); + return apply(assignInWith, undefined, args); +}); + +module.exports = defaults; diff --git a/platforms/android/assets/www/node_modules/lodash/defaultsDeep.js b/platforms/android/assets/www/node_modules/lodash/defaultsDeep.js new file mode 100644 index 0000000..c495aee --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/defaultsDeep.js @@ -0,0 +1,29 @@ +var apply = require('./_apply'), + mergeDefaults = require('./_mergeDefaults'), + mergeWith = require('./mergeWith'), + rest = require('./rest'); + +/** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } + * + */ +var defaultsDeep = rest(function(args) { + args.push(undefined, mergeDefaults); + return apply(mergeWith, undefined, args); +}); + +module.exports = defaultsDeep; diff --git a/platforms/android/assets/www/node_modules/lodash/defer.js b/platforms/android/assets/www/node_modules/lodash/defer.js new file mode 100644 index 0000000..f492b3d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/defer.js @@ -0,0 +1,25 @@ +var baseDelay = require('./_baseDelay'), + rest = require('./rest'); + +/** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => logs 'deferred' after one or more milliseconds + */ +var defer = rest(function(func, args) { + return baseDelay(func, 1, args); +}); + +module.exports = defer; diff --git a/platforms/android/assets/www/node_modules/lodash/delay.js b/platforms/android/assets/www/node_modules/lodash/delay.js new file mode 100644 index 0000000..28d070c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/delay.js @@ -0,0 +1,27 @@ +var baseDelay = require('./_baseDelay'), + rest = require('./rest'), + toNumber = require('./toNumber'); + +/** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ +var delay = rest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); +}); + +module.exports = delay; diff --git a/platforms/android/assets/www/node_modules/lodash/difference.js b/platforms/android/assets/www/node_modules/lodash/difference.js new file mode 100644 index 0000000..34c26e8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/difference.js @@ -0,0 +1,29 @@ +var baseDifference = require('./_baseDifference'), + baseFlatten = require('./_baseFlatten'), + isArrayLikeObject = require('./isArrayLikeObject'), + rest = require('./rest'); + +/** + * Creates an array of unique `array` values not included in the other + * given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. The order of result values is determined by the + * order they occur in the first array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([3, 2, 1], [4, 2]); + * // => [3, 1] + */ +var difference = rest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true)) + : []; +}); + +module.exports = difference; diff --git a/platforms/android/assets/www/node_modules/lodash/differenceBy.js b/platforms/android/assets/www/node_modules/lodash/differenceBy.js new file mode 100644 index 0000000..8c5831e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/differenceBy.js @@ -0,0 +1,40 @@ +var baseDifference = require('./_baseDifference'), + baseFlatten = require('./_baseFlatten'), + baseIteratee = require('./_baseIteratee'), + isArrayLikeObject = require('./isArrayLikeObject'), + last = require('./last'), + rest = require('./rest'); + +/** + * This method is like `_.difference` except that it accepts `iteratee` which + * is invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. Result values are chosen from the first array. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor); + * // => [3.1, 1.3] + * + * // The `_.property` iteratee shorthand. + * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ +var differenceBy = rest(function(array, values) { + var iteratee = last(values); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true), baseIteratee(iteratee)) + : []; +}); + +module.exports = differenceBy; diff --git a/platforms/android/assets/www/node_modules/lodash/differenceWith.js b/platforms/android/assets/www/node_modules/lodash/differenceWith.js new file mode 100644 index 0000000..88a4a0b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/differenceWith.js @@ -0,0 +1,37 @@ +var baseDifference = require('./_baseDifference'), + baseFlatten = require('./_baseFlatten'), + isArrayLikeObject = require('./isArrayLikeObject'), + last = require('./last'), + rest = require('./rest'); + +/** + * This method is like `_.difference` except that it accepts `comparator` + * which is invoked to compare elements of `array` to `values`. Result values + * are chosen from the first array. The comparator is invoked with two arguments: + * (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * + * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); + * // => [{ 'x': 2, 'y': 1 }] + */ +var differenceWith = rest(function(array, values) { + var comparator = last(values); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true), undefined, comparator) + : []; +}); + +module.exports = differenceWith; diff --git a/platforms/android/assets/www/node_modules/lodash/drop.js b/platforms/android/assets/www/node_modules/lodash/drop.js new file mode 100644 index 0000000..3094995 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/drop.js @@ -0,0 +1,37 @@ +var baseSlice = require('./_baseSlice'), + toInteger = require('./toInteger'); + +/** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ +function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, n < 0 ? 0 : n, length); +} + +module.exports = drop; diff --git a/platforms/android/assets/www/node_modules/lodash/dropRight.js b/platforms/android/assets/www/node_modules/lodash/dropRight.js new file mode 100644 index 0000000..61e1268 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/dropRight.js @@ -0,0 +1,38 @@ +var baseSlice = require('./_baseSlice'), + toInteger = require('./toInteger'); + +/** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ +function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, 0, n < 0 ? 0 : n); +} + +module.exports = dropRight; diff --git a/platforms/android/assets/www/node_modules/lodash/dropRightWhile.js b/platforms/android/assets/www/node_modules/lodash/dropRightWhile.js new file mode 100644 index 0000000..0c04ed2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/dropRightWhile.js @@ -0,0 +1,44 @@ +var baseIteratee = require('./_baseIteratee'), + baseWhile = require('./_baseWhile'); + +/** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.dropRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney'] + * + * // The `_.matches` iteratee shorthand. + * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropRightWhile(users, ['active', false]); + * // => objects for ['barney'] + * + * // The `_.property` iteratee shorthand. + * _.dropRightWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ +function dropRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, baseIteratee(predicate, 3), true, true) + : []; +} + +module.exports = dropRightWhile; diff --git a/platforms/android/assets/www/node_modules/lodash/dropWhile.js b/platforms/android/assets/www/node_modules/lodash/dropWhile.js new file mode 100644 index 0000000..72f9448 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/dropWhile.js @@ -0,0 +1,44 @@ +var baseIteratee = require('./_baseIteratee'), + baseWhile = require('./_baseWhile'); + +/** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.dropWhile(users, function(o) { return !o.active; }); + * // => objects for ['pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.dropWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropWhile(users, ['active', false]); + * // => objects for ['pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.dropWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ +function dropWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, baseIteratee(predicate, 3), true) + : []; +} + +module.exports = dropWhile; diff --git a/platforms/android/assets/www/node_modules/lodash/each.js b/platforms/android/assets/www/node_modules/lodash/each.js new file mode 100644 index 0000000..8800f42 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/each.js @@ -0,0 +1 @@ +module.exports = require('./forEach'); diff --git a/platforms/android/assets/www/node_modules/lodash/eachRight.js b/platforms/android/assets/www/node_modules/lodash/eachRight.js new file mode 100644 index 0000000..3252b2a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/eachRight.js @@ -0,0 +1 @@ +module.exports = require('./forEachRight'); diff --git a/platforms/android/assets/www/node_modules/lodash/endsWith.js b/platforms/android/assets/www/node_modules/lodash/endsWith.js new file mode 100644 index 0000000..5da6b5e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/endsWith.js @@ -0,0 +1,39 @@ +var baseClamp = require('./_baseClamp'), + toInteger = require('./toInteger'), + toString = require('./toString'); + +/** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search from. + * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ +function endsWith(string, target, position) { + string = toString(string); + target = typeof target == 'string' ? target : (target + ''); + + var length = string.length; + position = position === undefined + ? length + : baseClamp(toInteger(position), 0, length); + + position -= target.length; + return position >= 0 && string.indexOf(target, position) == position; +} + +module.exports = endsWith; diff --git a/platforms/android/assets/www/node_modules/lodash/eq.js b/platforms/android/assets/www/node_modules/lodash/eq.js new file mode 100644 index 0000000..5df222d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/eq.js @@ -0,0 +1,35 @@ +/** + * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +module.exports = eq; diff --git a/platforms/android/assets/www/node_modules/lodash/escape.js b/platforms/android/assets/www/node_modules/lodash/escape.js new file mode 100644 index 0000000..62857ed --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/escape.js @@ -0,0 +1,47 @@ +var escapeHtmlChar = require('./_escapeHtmlChar'), + toString = require('./toString'); + +/** Used to match HTML entities and HTML characters. */ +var reUnescapedHtml = /[&<>"'`]/g, + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + +/** + * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in IE < 9, they can break out of + * attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ +function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; +} + +module.exports = escape; diff --git a/platforms/android/assets/www/node_modules/lodash/escapeRegExp.js b/platforms/android/assets/www/node_modules/lodash/escapeRegExp.js new file mode 100644 index 0000000..52878c1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/escapeRegExp.js @@ -0,0 +1,28 @@ +var toString = require('./toString'); + +/** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, + reHasRegExpChar = RegExp(reRegExpChar.source); + +/** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ +function escapeRegExp(string) { + string = toString(string); + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string; +} + +module.exports = escapeRegExp; diff --git a/platforms/android/assets/www/node_modules/lodash/every.js b/platforms/android/assets/www/node_modules/lodash/every.js new file mode 100644 index 0000000..d100d0d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/every.js @@ -0,0 +1,49 @@ +var arrayEvery = require('./_arrayEvery'), + baseEvery = require('./_baseEvery'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'), + isIterateeCall = require('./_isIterateeCall'); + +/** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ +function every(collection, predicate, guard) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, baseIteratee(predicate, 3)); +} + +module.exports = every; diff --git a/platforms/android/assets/www/node_modules/lodash/extend.js b/platforms/android/assets/www/node_modules/lodash/extend.js new file mode 100644 index 0000000..e00166c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/extend.js @@ -0,0 +1 @@ +module.exports = require('./assignIn'); diff --git a/platforms/android/assets/www/node_modules/lodash/extendWith.js b/platforms/android/assets/www/node_modules/lodash/extendWith.js new file mode 100644 index 0000000..dbdcb3b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/extendWith.js @@ -0,0 +1 @@ +module.exports = require('./assignInWith'); diff --git a/platforms/android/assets/www/node_modules/lodash/fill.js b/platforms/android/assets/www/node_modules/lodash/fill.js new file mode 100644 index 0000000..4c0119f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fill.js @@ -0,0 +1,44 @@ +var baseFill = require('./_baseFill'), + isIterateeCall = require('./_isIterateeCall'); + +/** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8, 10], '*', 1, 3); + * // => [4, '*', '*', 10] + */ +function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); +} + +module.exports = fill; diff --git a/platforms/android/assets/www/node_modules/lodash/filter.js b/platforms/android/assets/www/node_modules/lodash/filter.js new file mode 100644 index 0000000..1df81c4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/filter.js @@ -0,0 +1,44 @@ +var arrayFilter = require('./_arrayFilter'), + baseFilter = require('./_baseFilter'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'); + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + */ +function filter(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, baseIteratee(predicate, 3)); +} + +module.exports = filter; diff --git a/platforms/android/assets/www/node_modules/lodash/find.js b/platforms/android/assets/www/node_modules/lodash/find.js new file mode 100644 index 0000000..c2ba356 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/find.js @@ -0,0 +1,50 @@ +var baseEach = require('./_baseEach'), + baseFind = require('./_baseFind'), + baseFindIndex = require('./_baseFindIndex'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'); + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +function find(collection, predicate) { + predicate = baseIteratee(predicate, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, baseEach); +} + +module.exports = find; diff --git a/platforms/android/assets/www/node_modules/lodash/findIndex.js b/platforms/android/assets/www/node_modules/lodash/findIndex.js new file mode 100644 index 0000000..5343fd1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/findIndex.js @@ -0,0 +1,43 @@ +var baseFindIndex = require('./_baseFindIndex'), + baseIteratee = require('./_baseIteratee'); + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate) { + return (array && array.length) + ? baseFindIndex(array, baseIteratee(predicate, 3)) + : -1; +} + +module.exports = findIndex; diff --git a/platforms/android/assets/www/node_modules/lodash/findKey.js b/platforms/android/assets/www/node_modules/lodash/findKey.js new file mode 100644 index 0000000..95d01f3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/findKey.js @@ -0,0 +1,42 @@ +var baseFind = require('./_baseFind'), + baseForOwn = require('./_baseForOwn'), + baseIteratee = require('./_baseIteratee'); + +/** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ +function findKey(object, predicate) { + return baseFind(object, baseIteratee(predicate, 3), baseForOwn, true); +} + +module.exports = findKey; diff --git a/platforms/android/assets/www/node_modules/lodash/findLast.js b/platforms/android/assets/www/node_modules/lodash/findLast.js new file mode 100644 index 0000000..0e5d593 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/findLast.js @@ -0,0 +1,33 @@ +var baseEachRight = require('./_baseEachRight'), + baseFind = require('./_baseFind'), + baseFindIndex = require('./_baseFindIndex'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'); + +/** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ +function findLast(collection, predicate) { + predicate = baseIteratee(predicate, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, true); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, baseEachRight); +} + +module.exports = findLast; diff --git a/platforms/android/assets/www/node_modules/lodash/findLastIndex.js b/platforms/android/assets/www/node_modules/lodash/findLastIndex.js new file mode 100644 index 0000000..2e62b36 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/findLastIndex.js @@ -0,0 +1,43 @@ +var baseFindIndex = require('./_baseFindIndex'), + baseIteratee = require('./_baseIteratee'); + +/** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); + * // => 2 + * + * // The `_.matches` iteratee shorthand. + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastIndex(users, ['active', false]); + * // => 2 + * + * // The `_.property` iteratee shorthand. + * _.findLastIndex(users, 'active'); + * // => 0 + */ +function findLastIndex(array, predicate) { + return (array && array.length) + ? baseFindIndex(array, baseIteratee(predicate, 3), true) + : -1; +} + +module.exports = findLastIndex; diff --git a/platforms/android/assets/www/node_modules/lodash/findLastKey.js b/platforms/android/assets/www/node_modules/lodash/findLastKey.js new file mode 100644 index 0000000..0380b07 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/findLastKey.js @@ -0,0 +1,42 @@ +var baseFind = require('./_baseFind'), + baseForOwnRight = require('./_baseForOwnRight'), + baseIteratee = require('./_baseIteratee'); + +/** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ +function findLastKey(object, predicate) { + return baseFind(object, baseIteratee(predicate, 3), baseForOwnRight, true); +} + +module.exports = findLastKey; diff --git a/platforms/android/assets/www/node_modules/lodash/flatMap.js b/platforms/android/assets/www/node_modules/lodash/flatMap.js new file mode 100644 index 0000000..0117bb4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/flatMap.js @@ -0,0 +1,28 @@ +var baseFlatten = require('./_baseFlatten'), + map = require('./map'); + +/** + * Creates an array of flattened values by running each element in `collection` + * through `iteratee` and concating its result to the other mapped values. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [n, n]; + * } + * + * _.flatMap([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ +function flatMap(collection, iteratee) { + return baseFlatten(map(collection, iteratee), 1); +} + +module.exports = flatMap; diff --git a/platforms/android/assets/www/node_modules/lodash/flatten.js b/platforms/android/assets/www/node_modules/lodash/flatten.js new file mode 100644 index 0000000..b8f701d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/flatten.js @@ -0,0 +1,21 @@ +var baseFlatten = require('./_baseFlatten'); + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, 1) : []; +} + +module.exports = flatten; diff --git a/platforms/android/assets/www/node_modules/lodash/flattenDeep.js b/platforms/android/assets/www/node_modules/lodash/flattenDeep.js new file mode 100644 index 0000000..b96cd56 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/flattenDeep.js @@ -0,0 +1,24 @@ +var baseFlatten = require('./_baseFlatten'); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ +function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, INFINITY) : []; +} + +module.exports = flattenDeep; diff --git a/platforms/android/assets/www/node_modules/lodash/flattenDepth.js b/platforms/android/assets/www/node_modules/lodash/flattenDepth.js new file mode 100644 index 0000000..e045711 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/flattenDepth.js @@ -0,0 +1,32 @@ +var baseFlatten = require('./_baseFlatten'), + toInteger = require('./toInteger'); + +/** + * Recursively flatten `array` up to `depth` times. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * var array = [1, [2, [3, [4]], 5]]; + * + * _.flattenDepth(array, 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth(array, 2); + * // => [1, 2, 3, [4], 5] + */ +function flattenDepth(array, depth) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(array, depth); +} + +module.exports = flattenDepth; diff --git a/platforms/android/assets/www/node_modules/lodash/flip.js b/platforms/android/assets/www/node_modules/lodash/flip.js new file mode 100644 index 0000000..6e14896 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/flip.js @@ -0,0 +1,27 @@ +var createWrapper = require('./_createWrapper'); + +/** Used to compose bitmasks for wrapper metadata. */ +var FLIP_FLAG = 512; + +/** + * Creates a function that invokes `func` with arguments reversed. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to flip arguments for. + * @returns {Function} Returns the new function. + * @example + * + * var flipped = _.flip(function() { + * return _.toArray(arguments); + * }); + * + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] + */ +function flip(func) { + return createWrapper(func, FLIP_FLAG); +} + +module.exports = flip; diff --git a/platforms/android/assets/www/node_modules/lodash/floor.js b/platforms/android/assets/www/node_modules/lodash/floor.js new file mode 100644 index 0000000..9bbf097 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/floor.js @@ -0,0 +1,25 @@ +var createRound = require('./_createRound'); + +/** + * Computes `number` rounded down to `precision`. + * + * @static + * @memberOf _ + * @category Math + * @param {number} number The number to round down. + * @param {number} [precision=0] The precision to round down to. + * @returns {number} Returns the rounded down number. + * @example + * + * _.floor(4.006); + * // => 4 + * + * _.floor(0.046, 2); + * // => 0.04 + * + * _.floor(4060, -2); + * // => 4000 + */ +var floor = createRound('floor'); + +module.exports = floor; diff --git a/platforms/android/assets/www/node_modules/lodash/flow.js b/platforms/android/assets/www/node_modules/lodash/flow.js new file mode 100644 index 0000000..b773405 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/flow.js @@ -0,0 +1,25 @@ +var createFlow = require('./_createFlow'); + +/** + * Creates a function that returns the result of invoking the given functions + * with the `this` binding of the created function, where each successive + * invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @category Util + * @param {...(Function|Function[])} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 + */ +var flow = createFlow(); + +module.exports = flow; diff --git a/platforms/android/assets/www/node_modules/lodash/flowRight.js b/platforms/android/assets/www/node_modules/lodash/flowRight.js new file mode 100644 index 0000000..e844822 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/flowRight.js @@ -0,0 +1,24 @@ +var createFlow = require('./_createFlow'); + +/** + * This method is like `_.flow` except that it creates a function that + * invokes the given functions from right to left. + * + * @static + * @memberOf _ + * @category Util + * @param {...(Function|Function[])} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 + */ +var flowRight = createFlow(true); + +module.exports = flowRight; diff --git a/platforms/android/assets/www/node_modules/lodash/forEach.js b/platforms/android/assets/www/node_modules/lodash/forEach.js new file mode 100644 index 0000000..a11eb22 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/forEach.js @@ -0,0 +1,40 @@ +var arrayEach = require('./_arrayEach'), + baseCastFunction = require('./_baseCastFunction'), + baseEach = require('./_baseEach'), + isArray = require('./isArray'); + +/** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn` + * for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(value) { + * console.log(value); + * }); + * // => logs `1` then `2` + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' then 'b' (iteration order is not guaranteed) + */ +function forEach(collection, iteratee) { + return (typeof iteratee == 'function' && isArray(collection)) + ? arrayEach(collection, iteratee) + : baseEach(collection, baseCastFunction(iteratee)); +} + +module.exports = forEach; diff --git a/platforms/android/assets/www/node_modules/lodash/forEachRight.js b/platforms/android/assets/www/node_modules/lodash/forEachRight.js new file mode 100644 index 0000000..ea58e7c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/forEachRight.js @@ -0,0 +1,30 @@ +var arrayEachRight = require('./_arrayEachRight'), + baseCastFunction = require('./_baseCastFunction'), + baseEachRight = require('./_baseEachRight'), + isArray = require('./isArray'); + +/** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @example + * + * _.forEachRight([1, 2], function(value) { + * console.log(value); + * }); + * // => logs `2` then `1` + */ +function forEachRight(collection, iteratee) { + return (typeof iteratee == 'function' && isArray(collection)) + ? arrayEachRight(collection, iteratee) + : baseEachRight(collection, baseCastFunction(iteratee)); +} + +module.exports = forEachRight; diff --git a/platforms/android/assets/www/node_modules/lodash/forIn.js b/platforms/android/assets/www/node_modules/lodash/forIn.js new file mode 100644 index 0000000..747175f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/forIn.js @@ -0,0 +1,37 @@ +var baseCastFunction = require('./_baseCastFunction'), + baseFor = require('./_baseFor'), + keysIn = require('./keysIn'); + +/** + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The iteratee is invoked with three arguments: + * (value, key, object). Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed) + */ +function forIn(object, iteratee) { + return object == null + ? object + : baseFor(object, baseCastFunction(iteratee), keysIn); +} + +module.exports = forIn; diff --git a/platforms/android/assets/www/node_modules/lodash/forInRight.js b/platforms/android/assets/www/node_modules/lodash/forInRight.js new file mode 100644 index 0000000..fa74e9e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/forInRight.js @@ -0,0 +1,35 @@ +var baseCastFunction = require('./_baseCastFunction'), + baseForRight = require('./_baseForRight'), + keysIn = require('./keysIn'); + +/** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c' + */ +function forInRight(object, iteratee) { + return object == null + ? object + : baseForRight(object, baseCastFunction(iteratee), keysIn); +} + +module.exports = forInRight; diff --git a/platforms/android/assets/www/node_modules/lodash/forOwn.js b/platforms/android/assets/www/node_modules/lodash/forOwn.js new file mode 100644 index 0000000..ac5ddc6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/forOwn.js @@ -0,0 +1,34 @@ +var baseCastFunction = require('./_baseCastFunction'), + baseForOwn = require('./_baseForOwn'); + +/** + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The iteratee is invoked with three arguments: + * (value, key, object). Iteratee functions may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' then 'b' (iteration order is not guaranteed) + */ +function forOwn(object, iteratee) { + return object && baseForOwn(object, baseCastFunction(iteratee)); +} + +module.exports = forOwn; diff --git a/platforms/android/assets/www/node_modules/lodash/forOwnRight.js b/platforms/android/assets/www/node_modules/lodash/forOwnRight.js new file mode 100644 index 0000000..7bda5de --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/forOwnRight.js @@ -0,0 +1,32 @@ +var baseCastFunction = require('./_baseCastFunction'), + baseForOwnRight = require('./_baseForOwnRight'); + +/** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b' + */ +function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, baseCastFunction(iteratee)); +} + +module.exports = forOwnRight; diff --git a/platforms/android/assets/www/node_modules/lodash/fp.js b/platforms/android/assets/www/node_modules/lodash/fp.js new file mode 100644 index 0000000..e372dbb --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp.js @@ -0,0 +1,2 @@ +var _ = require('./lodash.min').runInContext(); +module.exports = require('./fp/_baseConvert')(_, _); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/_baseConvert.js b/platforms/android/assets/www/node_modules/lodash/fp/_baseConvert.js new file mode 100644 index 0000000..b074100 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/_baseConvert.js @@ -0,0 +1,319 @@ +var mapping = require('./_mapping'), + mutateMap = mapping.mutate, + fallbackHolder = {}; + +/** + * The base implementation of `convert` which accepts a `util` object of methods + * required to perform conversions. + * + * @param {Object} util The util object. + * @param {string} name The name of the function to wrap. + * @param {Function} func The function to wrap. + * @param {Object} [options] The options object. + * @param {boolean} [options.cap=true] Specify capping iteratee arguments. + * @param {boolean} [options.curry=true] Specify currying. + * @param {boolean} [options.fixed=true] Specify fixed arity. + * @param {boolean} [options.immutable=true] Specify immutable operations. + * @param {boolean} [options.rearg=true] Specify rearranging arguments. + * @returns {Function|Object} Returns the converted function or object. + */ +function baseConvert(util, name, func, options) { + var setPlaceholder, + isLib = typeof name == 'function', + isObj = name === Object(name); + + if (isObj) { + options = func; + func = name; + name = undefined; + } + if (func == null) { + throw new TypeError; + } + options || (options = {}); + + var config = { + 'cap': 'cap' in options ? options.cap : true, + 'curry': 'curry' in options ? options.curry : true, + 'fixed': 'fixed' in options ? options.fixed : true, + 'immutable': 'immutable' in options ? options.immutable : true, + 'rearg': 'rearg' in options ? options.rearg : true + }; + + var forceRearg = ('rearg' in options) && options.rearg, + placeholder = isLib ? func : fallbackHolder; + + var helpers = isLib ? func : { + 'ary': util.ary, + 'clone': util.clone, + 'curry': util.curry, + 'forEach': util.forEach, + 'isArray': util.isArray, + 'isFunction': util.isFunction, + 'iteratee': util.iteratee, + 'keys': util.keys, + 'rearg': util.rearg, + 'spread': util.spread, + 'toPath': util.toPath + }; + + var ary = helpers.ary, + clone = helpers.clone, + curry = helpers.curry, + each = helpers.forEach, + isArray = helpers.isArray, + isFunction = helpers.isFunction, + keys = helpers.keys, + rearg = helpers.rearg, + spread = helpers.spread, + toPath = helpers.toPath; + + var aryMethodKeys = keys(mapping.aryMethod); + + var baseArity = function(func, n) { + return n == 2 + ? function(a, b) { return func.apply(undefined, arguments); } + : function(a) { return func.apply(undefined, arguments); }; + }; + + var baseAry = function(func, n) { + return n == 2 + ? function(a, b) { return func(a, b); } + : function(a) { return func(a); }; + }; + + var cloneArray = function(array) { + var length = array ? array.length : 0, + result = Array(length); + + while (length--) { + result[length] = array[length]; + } + return result; + }; + + var cloneByPath = function(object, path) { + path = toPath(path); + + var index = -1, + length = path.length, + result = clone(Object(object)), + nested = result; + + while (nested != null && ++index < length) { + var key = path[index], + value = nested[key]; + + if (value != null) { + nested[key] = clone(Object(value)); + } + nested = nested[key]; + } + return result; + }; + + var createCloner = function(func) { + return function(object) { + return func({}, object); + }; + }; + + var immutWrap = function(func, cloner) { + return function() { + var length = arguments.length; + if (!length) { + return result; + } + var args = Array(length); + while (length--) { + args[length] = arguments[length]; + } + var result = args[0] = cloner.apply(undefined, args); + func.apply(undefined, args); + return result; + }; + }; + + var iterateeAry = function(func, n) { + return overArg(func, function(func) { + return typeof func == 'function' ? baseAry(func, n) : func; + }); + }; + + var iterateeRearg = function(func, indexes) { + return overArg(func, function(func) { + var n = indexes.length; + return baseArity(rearg(baseAry(func, n), indexes), n); + }); + }; + + var overArg = function(func, iteratee, retArg) { + return function() { + var length = arguments.length; + if (!length) { + return func(); + } + var args = Array(length); + while (length--) { + args[length] = arguments[length]; + } + var index = config.rearg ? 0 : (length - 1); + args[index] = iteratee(args[index]); + return func.apply(undefined, args); + }; + }; + + var wrappers = { + 'castArray': function(castArray) { + return function() { + var value = arguments[0]; + return isArray(value) + ? castArray(cloneArray(value)) + : castArray.apply(undefined, arguments); + }; + }, + 'iteratee': function(iteratee) { + return function() { + var func = arguments[0], + arity = arguments[1], + result = iteratee(func, arity), + length = result.length; + + if (config.cap && typeof arity == 'number') { + arity = arity > 2 ? (arity - 2) : 1; + return (length && length <= arity) ? result : baseAry(result, arity); + } + return result; + }; + }, + 'mixin': function(mixin) { + return function(source) { + var func = this; + if (!isFunction(func)) { + return mixin(func, Object(source)); + } + var methods = [], + methodNames = []; + + each(keys(source), function(key) { + var value = source[key]; + if (isFunction(value)) { + methodNames.push(key); + methods.push(func.prototype[key]); + } + }); + + mixin(func, Object(source)); + + each(methodNames, function(methodName, index) { + var method = methods[index]; + if (isFunction(method)) { + func.prototype[methodName] = method; + } else { + delete func.prototype[methodName]; + } + }); + return func; + }; + }, + 'runInContext': function(runInContext) { + return function(context) { + return baseConvert(util, runInContext(context), options); + }; + } + }; + + var wrap = function(name, func) { + name = mapping.aliasToReal[name] || name; + var wrapper = wrappers[name]; + if (wrapper) { + return wrapper(func); + } + var wrapped = func; + if (config.immutable) { + if (mutateMap.array[name]) { + wrapped = immutWrap(func, cloneArray); + } + else if (mutateMap.object[name]) { + wrapped = immutWrap(func, createCloner(func)); + } + else if (mutateMap.set[name]) { + wrapped = immutWrap(func, cloneByPath); + } + } + var result; + each(aryMethodKeys, function(aryKey) { + each(mapping.aryMethod[aryKey], function(otherName) { + if (name == otherName) { + var aryN = !isLib && mapping.iterateeAry[name], + reargIndexes = mapping.iterateeRearg[name], + spreadStart = mapping.methodSpread[name]; + + result = wrapped; + if (config.fixed) { + result = spreadStart === undefined + ? ary(result, aryKey) + : spread(result, spreadStart); + } + if (config.rearg && aryKey > 1 && (forceRearg || !mapping.skipRearg[name])) { + result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[aryKey]); + } + if (config.cap) { + if (reargIndexes) { + result = iterateeRearg(result, reargIndexes); + } else if (aryN) { + result = iterateeAry(result, aryN); + } + } + if (config.curry && aryKey > 1) { + result = curry(result, aryKey); + } + return false; + } + }); + return !result; + }); + + result || (result = wrapped); + if (mapping.placeholder[name]) { + setPlaceholder = true; + func.placeholder = result.placeholder = placeholder; + } + return result; + }; + + if (!isObj) { + return wrap(name, func); + } + var _ = func; + + // Iterate over methods for the current ary cap. + var pairs = []; + each(aryMethodKeys, function(aryKey) { + each(mapping.aryMethod[aryKey], function(key) { + var func = _[mapping.remap[key] || key]; + if (func) { + pairs.push([key, wrap(key, func)]); + } + }); + }); + + // Assign to `_` leaving `_.prototype` unchanged to allow chaining. + each(pairs, function(pair) { + _[pair[0]] = pair[1]; + }); + + if (setPlaceholder) { + _.placeholder = placeholder; + } + // Wrap the lodash method and its aliases. + each(keys(_), function(key) { + each(mapping.realToAlias[key] || [], function(alias) { + _[alias] = _[key]; + }); + }); + + return _; +} + +module.exports = baseConvert; diff --git a/platforms/android/assets/www/node_modules/lodash/fp/_convertBrowser.js b/platforms/android/assets/www/node_modules/lodash/fp/_convertBrowser.js new file mode 100644 index 0000000..fbd2174 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/_convertBrowser.js @@ -0,0 +1,17 @@ +var baseConvert = require('./_baseConvert'); + +/** + * Converts `lodash` to an immutable auto-curried iteratee-first data-last version. + * + * @param {Function} lodash The lodash function. + * @param {Object} [options] The options object. See `baseConvert` for more details. + * @returns {Function} Returns the converted `lodash`. + */ +function browserConvert(lodash, options) { + return baseConvert(lodash, lodash, options); +} + +if (typeof _ == 'function') { + _ = browserConvert(_.runInContext()); +} +module.exports = browserConvert; diff --git a/platforms/android/assets/www/node_modules/lodash/fp/_mapping.js b/platforms/android/assets/www/node_modules/lodash/fp/_mapping.js new file mode 100644 index 0000000..1d33d4b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/_mapping.js @@ -0,0 +1,243 @@ +/** Used to map aliases to their real names. */ +exports.aliasToReal = { + '__': 'placeholder', + 'all': 'some', + 'allPass': 'overEvery', + 'apply': 'spread', + 'assoc': 'set', + 'assocPath': 'set', + 'compose': 'flowRight', + 'contains': 'includes', + 'dissoc': 'unset', + 'dissocPath': 'unset', + 'each': 'forEach', + 'eachRight': 'forEachRight', + 'equals': 'isEqual', + 'extend': 'assignIn', + 'extendWith': 'assignInWith', + 'first': 'head', + 'init': 'initial', + 'mapObj': 'mapValues', + 'omitAll': 'omit', + 'nAry': 'ary', + 'path': 'get', + 'pathEq': 'matchesProperty', + 'pathOr': 'getOr', + 'pickAll': 'pick', + 'pipe': 'flow', + 'prop': 'get', + 'propOf': 'propertyOf', + 'propOr': 'getOr', + 'somePass': 'overSome', + 'unapply': 'rest', + 'unnest': 'flatten', + 'useWith': 'overArgs', + 'whereEq': 'filter', + 'zipObj': 'zipObject' +}; + +/** Used to map ary to method names. */ +exports.aryMethod = { + '1': [ + 'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor', + 'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', + 'over', 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext', + 'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words' + ], + '2': [ + 'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey', + 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN', + 'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference', + 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every', + 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', + 'findLastKey', 'flatMap', 'flattenDepth', 'forEach', 'forEachRight', 'forIn', + 'forInRight', 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has', + 'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap', + 'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', + 'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit', + 'omitBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', 'partial', + 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll', 'pullAt', + 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove', 'repeat', 'result', + 'sampleSize', 'some', 'sortBy', 'sortedIndex', 'sortedIndexOf', 'sortedLastIndex', + 'sortedLastIndexOf', 'sortedUniqBy', 'split', 'startsWith', 'subtract', 'sumBy', + 'take', 'takeRight', 'takeRightWhile', 'takeWhile', 'tap', 'throttle', 'thru', + 'times', 'trimChars', 'trimCharsEnd', 'trimCharsStart', 'truncate', 'union', + 'uniqBy', 'uniqWith', 'unset', 'unzipWith', 'without', 'wrap', 'xor', 'zip', + 'zipObject', 'zipObjectDeep' + ], + '3': [ + 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith', + 'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith', + 'isMatchWith', 'mergeWith', 'orderBy', 'pullAllBy', 'pullAllWith', 'reduce', + 'reduceRight', 'replace', 'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', + 'transform', 'unionBy', 'unionWith', 'update', 'xorBy', 'xorWith', 'zipWith' + ], + '4': [ + 'fill', 'setWith', 'updateWith' + ] +}; + +/** Used to map ary to rearg configs. */ +exports.aryRearg = { + '2': [1, 0], + '3': [2, 0, 1], + '4': [3, 2, 0, 1] +}; + +/** Used to map method names to their iteratee ary. */ +exports.iterateeAry = { + 'assignWith': 2, + 'assignInWith': 2, + 'cloneDeepWith': 1, + 'cloneWith': 1, + 'dropRightWhile': 1, + 'dropWhile': 1, + 'every': 1, + 'filter': 1, + 'find': 1, + 'findIndex': 1, + 'findKey': 1, + 'findLast': 1, + 'findLastIndex': 1, + 'findLastKey': 1, + 'flatMap': 1, + 'forEach': 1, + 'forEachRight': 1, + 'forIn': 1, + 'forInRight': 1, + 'forOwn': 1, + 'forOwnRight': 1, + 'isEqualWith': 2, + 'isMatchWith': 2, + 'map': 1, + 'mapKeys': 1, + 'mapValues': 1, + 'partition': 1, + 'reduce': 2, + 'reduceRight': 2, + 'reject': 1, + 'remove': 1, + 'some': 1, + 'takeRightWhile': 1, + 'takeWhile': 1, + 'times': 1, + 'transform': 2 +}; + +/** Used to map method names to iteratee rearg configs. */ +exports.iterateeRearg = { + 'mapKeys': [1] +}; + +/** Used to map method names to rearg configs. */ +exports.methodRearg = { + 'assignInWith': [1, 2, 0], + 'assignWith': [1, 2, 0], + 'getOr': [2, 1, 0], + 'isMatchWith': [2, 1, 0], + 'mergeWith': [1, 2, 0], + 'pullAllBy': [2, 1, 0], + 'pullAllWith': [2, 1, 0], + 'setWith': [3, 1, 2, 0], + 'sortedIndexBy': [2, 1, 0], + 'sortedLastIndexBy': [2, 1, 0], + 'updateWith': [3, 1, 2, 0], + 'zipWith': [1, 2, 0] +}; + +/** Used to map method names to spread configs. */ +exports.methodSpread = { + 'partial': 1, + 'partialRight': 1 +}; + +/** Used to identify methods which mutate arrays or objects. */ +exports.mutate = { + 'array': { + 'fill': true, + 'pull': true, + 'pullAll': true, + 'pullAllBy': true, + 'pullAllWith': true, + 'pullAt': true, + 'remove': true, + 'reverse': true + }, + 'object': { + 'assign': true, + 'assignIn': true, + 'assignInWith': true, + 'assignWith': true, + 'defaults': true, + 'defaultsDeep': true, + 'merge': true, + 'mergeWith': true + }, + 'set': { + 'set': true, + 'setWith': true, + 'unset': true, + 'update': true, + 'updateWith': true + } +}; + +/** Used to track methods with placeholder support */ +exports.placeholder = { + 'bind': true, + 'bindKey': true, + 'curry': true, + 'curryRight': true, + 'partial': true, + 'partialRight': true +}; + +/** Used to map real names to their aliases. */ +exports.realToAlias = (function() { + var hasOwnProperty = Object.prototype.hasOwnProperty, + object = exports.aliasToReal, + result = {}; + + for (var key in object) { + var value = object[key]; + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + } + return result; +}()); + +/** Used to map method names to other names. */ +exports.remap = { + 'curryN': 'curry', + 'curryRightN': 'curryRight', + 'getOr': 'get', + 'trimChars': 'trim', + 'trimCharsEnd': 'trimEnd', + 'trimCharsStart': 'trimStart' +}; + +/** Used to track methods that skip `_.rearg`. */ +exports.skipRearg = { + 'add': true, + 'assign': true, + 'assignIn': true, + 'concat': true, + 'difference': true, + 'gt': true, + 'gte': true, + 'lt': true, + 'lte': true, + 'matchesProperty': true, + 'merge': true, + 'partial': true, + 'partialRight': true, + 'random': true, + 'range': true, + 'rangeRight': true, + 'subtract': true, + 'zip': true, + 'zipObject': true +}; diff --git a/platforms/android/assets/www/node_modules/lodash/fp/_util.js b/platforms/android/assets/www/node_modules/lodash/fp/_util.js new file mode 100644 index 0000000..afa811b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/_util.js @@ -0,0 +1,13 @@ +module.exports = { + 'ary': require('../ary'), + 'clone': require('../clone'), + 'curry': require('../curry'), + 'forEach': require('../_arrayEach'), + 'isArray': require('../isArray'), + 'isFunction': require('../isFunction'), + 'iteratee': require('../iteratee'), + 'keys': require('../_baseKeys'), + 'rearg': require('../rearg'), + 'spread': require('../spread'), + 'toPath': require('../toPath') +}; diff --git a/platforms/android/assets/www/node_modules/lodash/fp/add.js b/platforms/android/assets/www/node_modules/lodash/fp/add.js new file mode 100644 index 0000000..c51b8fa --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/add.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('add', require('../add')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/after.js b/platforms/android/assets/www/node_modules/lodash/fp/after.js new file mode 100644 index 0000000..83691b7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/after.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('after', require('../after')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/all.js b/platforms/android/assets/www/node_modules/lodash/fp/all.js new file mode 100644 index 0000000..900ac25 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/all.js @@ -0,0 +1 @@ +module.exports = require('./some'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/allPass.js b/platforms/android/assets/www/node_modules/lodash/fp/allPass.js new file mode 100644 index 0000000..79b73ef --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/allPass.js @@ -0,0 +1 @@ +module.exports = require('./overEvery'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/apply.js b/platforms/android/assets/www/node_modules/lodash/fp/apply.js new file mode 100644 index 0000000..2b75712 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/apply.js @@ -0,0 +1 @@ +module.exports = require('./spread'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/array.js b/platforms/android/assets/www/node_modules/lodash/fp/array.js new file mode 100644 index 0000000..fe939c2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/array.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../array')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/ary.js b/platforms/android/assets/www/node_modules/lodash/fp/ary.js new file mode 100644 index 0000000..0f75d18 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/ary.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('ary', require('../ary')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/assign.js b/platforms/android/assets/www/node_modules/lodash/fp/assign.js new file mode 100644 index 0000000..ad02bcb --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/assign.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('assign', require('../assign')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/assignIn.js b/platforms/android/assets/www/node_modules/lodash/fp/assignIn.js new file mode 100644 index 0000000..1ed4f0d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/assignIn.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('assignIn', require('../assignIn')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/assignInWith.js b/platforms/android/assets/www/node_modules/lodash/fp/assignInWith.js new file mode 100644 index 0000000..882145d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/assignInWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('assignInWith', require('../assignInWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/assignWith.js b/platforms/android/assets/www/node_modules/lodash/fp/assignWith.js new file mode 100644 index 0000000..1ff0527 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/assignWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('assignWith', require('../assignWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/assoc.js b/platforms/android/assets/www/node_modules/lodash/fp/assoc.js new file mode 100644 index 0000000..7648820 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/assoc.js @@ -0,0 +1 @@ +module.exports = require('./set'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/assocPath.js b/platforms/android/assets/www/node_modules/lodash/fp/assocPath.js new file mode 100644 index 0000000..7648820 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/assocPath.js @@ -0,0 +1 @@ +module.exports = require('./set'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/at.js b/platforms/android/assets/www/node_modules/lodash/fp/at.js new file mode 100644 index 0000000..5da3525 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/at.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('at', require('../at')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/attempt.js b/platforms/android/assets/www/node_modules/lodash/fp/attempt.js new file mode 100644 index 0000000..d8a3be5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/attempt.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('attempt', require('../attempt')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/before.js b/platforms/android/assets/www/node_modules/lodash/fp/before.js new file mode 100644 index 0000000..f2954a6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/before.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('before', require('../before')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/bind.js b/platforms/android/assets/www/node_modules/lodash/fp/bind.js new file mode 100644 index 0000000..e054a48 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/bind.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('bind', require('../bind')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/bindAll.js b/platforms/android/assets/www/node_modules/lodash/fp/bindAll.js new file mode 100644 index 0000000..495b75c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/bindAll.js @@ -0,0 +1 @@ +module.exports = require('../bindAll'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/bindKey.js b/platforms/android/assets/www/node_modules/lodash/fp/bindKey.js new file mode 100644 index 0000000..0b588c7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/bindKey.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('bindKey', require('../bindKey')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/camelCase.js b/platforms/android/assets/www/node_modules/lodash/fp/camelCase.js new file mode 100644 index 0000000..328041e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/camelCase.js @@ -0,0 +1 @@ +module.exports = require('../camelCase'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/capitalize.js b/platforms/android/assets/www/node_modules/lodash/fp/capitalize.js new file mode 100644 index 0000000..186e6d9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/capitalize.js @@ -0,0 +1 @@ +module.exports = require('../capitalize'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/castArray.js b/platforms/android/assets/www/node_modules/lodash/fp/castArray.js new file mode 100644 index 0000000..2a75bb9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/castArray.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('castArray', require('../castArray')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/ceil.js b/platforms/android/assets/www/node_modules/lodash/fp/ceil.js new file mode 100644 index 0000000..7c3774b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/ceil.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('ceil', require('../ceil')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/chain.js b/platforms/android/assets/www/node_modules/lodash/fp/chain.js new file mode 100644 index 0000000..2f139cc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/chain.js @@ -0,0 +1 @@ +module.exports = require('../chain'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/chunk.js b/platforms/android/assets/www/node_modules/lodash/fp/chunk.js new file mode 100644 index 0000000..9d32b8a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/chunk.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('chunk', require('../chunk')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/clamp.js b/platforms/android/assets/www/node_modules/lodash/fp/clamp.js new file mode 100644 index 0000000..8ec3d9d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/clamp.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('clamp', require('../clamp')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/clone.js b/platforms/android/assets/www/node_modules/lodash/fp/clone.js new file mode 100644 index 0000000..afd2c15 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/clone.js @@ -0,0 +1 @@ +module.exports = require('../clone'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/cloneDeep.js b/platforms/android/assets/www/node_modules/lodash/fp/cloneDeep.js new file mode 100644 index 0000000..a17a6f8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/cloneDeep.js @@ -0,0 +1 @@ +module.exports = require('../cloneDeep'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/cloneDeepWith.js b/platforms/android/assets/www/node_modules/lodash/fp/cloneDeepWith.js new file mode 100644 index 0000000..01c7fef --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/cloneDeepWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('cloneDeepWith', require('../cloneDeepWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/cloneWith.js b/platforms/android/assets/www/node_modules/lodash/fp/cloneWith.js new file mode 100644 index 0000000..9e9d783 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/cloneWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('cloneWith', require('../cloneWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/collection.js b/platforms/android/assets/www/node_modules/lodash/fp/collection.js new file mode 100644 index 0000000..fc8b328 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/collection.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../collection')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/commit.js b/platforms/android/assets/www/node_modules/lodash/fp/commit.js new file mode 100644 index 0000000..04e9eb9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/commit.js @@ -0,0 +1 @@ +module.exports = require('../commit'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/compact.js b/platforms/android/assets/www/node_modules/lodash/fp/compact.js new file mode 100644 index 0000000..b2ed9c7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/compact.js @@ -0,0 +1 @@ +module.exports = require('../compact'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/compose.js b/platforms/android/assets/www/node_modules/lodash/fp/compose.js new file mode 100644 index 0000000..1954e94 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/compose.js @@ -0,0 +1 @@ +module.exports = require('./flowRight'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/concat.js b/platforms/android/assets/www/node_modules/lodash/fp/concat.js new file mode 100644 index 0000000..c13a92a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/concat.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('concat', require('../concat')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/cond.js b/platforms/android/assets/www/node_modules/lodash/fp/cond.js new file mode 100644 index 0000000..a150a89 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/cond.js @@ -0,0 +1 @@ +module.exports = require('../cond'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/conforms.js b/platforms/android/assets/www/node_modules/lodash/fp/conforms.js new file mode 100644 index 0000000..387dde1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/conforms.js @@ -0,0 +1 @@ +module.exports = require('../conforms'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/constant.js b/platforms/android/assets/www/node_modules/lodash/fp/constant.js new file mode 100644 index 0000000..3bcd276 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/constant.js @@ -0,0 +1 @@ +module.exports = require('../constant'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/contains.js b/platforms/android/assets/www/node_modules/lodash/fp/contains.js new file mode 100644 index 0000000..594722a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/contains.js @@ -0,0 +1 @@ +module.exports = require('./includes'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/convert.js b/platforms/android/assets/www/node_modules/lodash/fp/convert.js new file mode 100644 index 0000000..a1d266f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/convert.js @@ -0,0 +1,17 @@ +var baseConvert = require('./_baseConvert'), + util = require('./_util'); + +/** + * Converts `func` of `name` to an immutable auto-curried iteratee-first data-last + * version. If `name` is an object its methods will be converted. + * + * @param {string} name The name of the function to wrap. + * @param {Function} [func] The function to wrap. + * @param {Object} [options] The options object. See `baseConvert` for more details. + * @returns {Function|Object} Returns the converted function or object. + */ +function convert(name, func, options) { + return baseConvert(util, name, func, options); +} + +module.exports = convert; diff --git a/platforms/android/assets/www/node_modules/lodash/fp/countBy.js b/platforms/android/assets/www/node_modules/lodash/fp/countBy.js new file mode 100644 index 0000000..ee4b942 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/countBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('countBy', require('../countBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/create.js b/platforms/android/assets/www/node_modules/lodash/fp/create.js new file mode 100644 index 0000000..bdad771 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/create.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('create', require('../create')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/curry.js b/platforms/android/assets/www/node_modules/lodash/fp/curry.js new file mode 100644 index 0000000..d64722c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/curry.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('curry', require('../curry')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/curryN.js b/platforms/android/assets/www/node_modules/lodash/fp/curryN.js new file mode 100644 index 0000000..f33f7fc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/curryN.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('curryN', require('../curry')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/curryRight.js b/platforms/android/assets/www/node_modules/lodash/fp/curryRight.js new file mode 100644 index 0000000..2e04709 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/curryRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('curryRight', require('../curryRight')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/curryRightN.js b/platforms/android/assets/www/node_modules/lodash/fp/curryRightN.js new file mode 100644 index 0000000..510e4e4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/curryRightN.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('curryRightN', require('../curryRight')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/date.js b/platforms/android/assets/www/node_modules/lodash/fp/date.js new file mode 100644 index 0000000..82cb952 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/date.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../date')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/debounce.js b/platforms/android/assets/www/node_modules/lodash/fp/debounce.js new file mode 100644 index 0000000..a6b0407 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/debounce.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('debounce', require('../debounce')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/deburr.js b/platforms/android/assets/www/node_modules/lodash/fp/deburr.js new file mode 100644 index 0000000..f8e1a49 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/deburr.js @@ -0,0 +1 @@ +module.exports = require('../deburr'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/defaults.js b/platforms/android/assets/www/node_modules/lodash/fp/defaults.js new file mode 100644 index 0000000..7c3b3ab --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/defaults.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('defaults', require('../defaults')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/defaultsDeep.js b/platforms/android/assets/www/node_modules/lodash/fp/defaultsDeep.js new file mode 100644 index 0000000..c7480e2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/defaultsDeep.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('defaultsDeep', require('../defaultsDeep')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/defer.js b/platforms/android/assets/www/node_modules/lodash/fp/defer.js new file mode 100644 index 0000000..4126727 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/defer.js @@ -0,0 +1 @@ +module.exports = require('../defer'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/delay.js b/platforms/android/assets/www/node_modules/lodash/fp/delay.js new file mode 100644 index 0000000..cd3b1c3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/delay.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('delay', require('../delay')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/difference.js b/platforms/android/assets/www/node_modules/lodash/fp/difference.js new file mode 100644 index 0000000..aea9ab8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/difference.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('difference', require('../difference')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/differenceBy.js b/platforms/android/assets/www/node_modules/lodash/fp/differenceBy.js new file mode 100644 index 0000000..ab65554 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/differenceBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('differenceBy', require('../differenceBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/differenceWith.js b/platforms/android/assets/www/node_modules/lodash/fp/differenceWith.js new file mode 100644 index 0000000..f932a2e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/differenceWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('differenceWith', require('../differenceWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/dissoc.js b/platforms/android/assets/www/node_modules/lodash/fp/dissoc.js new file mode 100644 index 0000000..7ec7be1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/dissoc.js @@ -0,0 +1 @@ +module.exports = require('./unset'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/dissocPath.js b/platforms/android/assets/www/node_modules/lodash/fp/dissocPath.js new file mode 100644 index 0000000..7ec7be1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/dissocPath.js @@ -0,0 +1 @@ +module.exports = require('./unset'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/drop.js b/platforms/android/assets/www/node_modules/lodash/fp/drop.js new file mode 100644 index 0000000..ccca2d0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/drop.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('drop', require('../drop')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/dropRight.js b/platforms/android/assets/www/node_modules/lodash/fp/dropRight.js new file mode 100644 index 0000000..bd9a2bd --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/dropRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('dropRight', require('../dropRight')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/dropRightWhile.js b/platforms/android/assets/www/node_modules/lodash/fp/dropRightWhile.js new file mode 100644 index 0000000..2dbb2a3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/dropRightWhile.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('dropRightWhile', require('../dropRightWhile')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/dropWhile.js b/platforms/android/assets/www/node_modules/lodash/fp/dropWhile.js new file mode 100644 index 0000000..17e46ff --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/dropWhile.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('dropWhile', require('../dropWhile')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/each.js b/platforms/android/assets/www/node_modules/lodash/fp/each.js new file mode 100644 index 0000000..8800f42 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/each.js @@ -0,0 +1 @@ +module.exports = require('./forEach'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/eachRight.js b/platforms/android/assets/www/node_modules/lodash/fp/eachRight.js new file mode 100644 index 0000000..3252b2a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/eachRight.js @@ -0,0 +1 @@ +module.exports = require('./forEachRight'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/endsWith.js b/platforms/android/assets/www/node_modules/lodash/fp/endsWith.js new file mode 100644 index 0000000..cbe8f8c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/endsWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('endsWith', require('../endsWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/eq.js b/platforms/android/assets/www/node_modules/lodash/fp/eq.js new file mode 100644 index 0000000..518a54d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/eq.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('eq', require('../eq')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/equals.js b/platforms/android/assets/www/node_modules/lodash/fp/equals.js new file mode 100644 index 0000000..e6a5ce0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/equals.js @@ -0,0 +1 @@ +module.exports = require('./isEqual'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/escape.js b/platforms/android/assets/www/node_modules/lodash/fp/escape.js new file mode 100644 index 0000000..e5de9f2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/escape.js @@ -0,0 +1 @@ +module.exports = require('../escape'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/escapeRegExp.js b/platforms/android/assets/www/node_modules/lodash/fp/escapeRegExp.js new file mode 100644 index 0000000..ab18963 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/escapeRegExp.js @@ -0,0 +1 @@ +module.exports = require('../escapeRegExp'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/every.js b/platforms/android/assets/www/node_modules/lodash/fp/every.js new file mode 100644 index 0000000..965f889 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/every.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('every', require('../every')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/extend.js b/platforms/android/assets/www/node_modules/lodash/fp/extend.js new file mode 100644 index 0000000..e00166c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/extend.js @@ -0,0 +1 @@ +module.exports = require('./assignIn'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/extendWith.js b/platforms/android/assets/www/node_modules/lodash/fp/extendWith.js new file mode 100644 index 0000000..dbdcb3b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/extendWith.js @@ -0,0 +1 @@ +module.exports = require('./assignInWith'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/fill.js b/platforms/android/assets/www/node_modules/lodash/fp/fill.js new file mode 100644 index 0000000..e16f8bf --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/fill.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('fill', require('../fill')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/filter.js b/platforms/android/assets/www/node_modules/lodash/fp/filter.js new file mode 100644 index 0000000..7191a82 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/filter.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('filter', require('../filter')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/find.js b/platforms/android/assets/www/node_modules/lodash/fp/find.js new file mode 100644 index 0000000..5915bbd --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/find.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('find', require('../find')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/findIndex.js b/platforms/android/assets/www/node_modules/lodash/fp/findIndex.js new file mode 100644 index 0000000..6bf435c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/findIndex.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('findIndex', require('../findIndex')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/findKey.js b/platforms/android/assets/www/node_modules/lodash/fp/findKey.js new file mode 100644 index 0000000..3ff9844 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/findKey.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('findKey', require('../findKey')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/findLast.js b/platforms/android/assets/www/node_modules/lodash/fp/findLast.js new file mode 100644 index 0000000..31e169b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/findLast.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('findLast', require('../findLast')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/findLastIndex.js b/platforms/android/assets/www/node_modules/lodash/fp/findLastIndex.js new file mode 100644 index 0000000..db41e88 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/findLastIndex.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('findLastIndex', require('../findLastIndex')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/findLastKey.js b/platforms/android/assets/www/node_modules/lodash/fp/findLastKey.js new file mode 100644 index 0000000..ffe9e2a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/findLastKey.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('findLastKey', require('../findLastKey')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/first.js b/platforms/android/assets/www/node_modules/lodash/fp/first.js new file mode 100644 index 0000000..53f4ad1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/first.js @@ -0,0 +1 @@ +module.exports = require('./head'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/flatMap.js b/platforms/android/assets/www/node_modules/lodash/fp/flatMap.js new file mode 100644 index 0000000..da249a8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/flatMap.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('flatMap', require('../flatMap')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/flatten.js b/platforms/android/assets/www/node_modules/lodash/fp/flatten.js new file mode 100644 index 0000000..f1c1a62 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/flatten.js @@ -0,0 +1 @@ +module.exports = require('../flatten'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/flattenDeep.js b/platforms/android/assets/www/node_modules/lodash/fp/flattenDeep.js new file mode 100644 index 0000000..c2ff987 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/flattenDeep.js @@ -0,0 +1 @@ +module.exports = require('../flattenDeep'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/flattenDepth.js b/platforms/android/assets/www/node_modules/lodash/fp/flattenDepth.js new file mode 100644 index 0000000..731e27a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/flattenDepth.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('flattenDepth', require('../flattenDepth')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/flip.js b/platforms/android/assets/www/node_modules/lodash/fp/flip.js new file mode 100644 index 0000000..730bbd1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/flip.js @@ -0,0 +1 @@ +module.exports = require('../flip'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/floor.js b/platforms/android/assets/www/node_modules/lodash/fp/floor.js new file mode 100644 index 0000000..f130f8b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/floor.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('floor', require('../floor')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/flow.js b/platforms/android/assets/www/node_modules/lodash/fp/flow.js new file mode 100644 index 0000000..d9943c6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/flow.js @@ -0,0 +1 @@ +module.exports = require('../flow'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/flowRight.js b/platforms/android/assets/www/node_modules/lodash/fp/flowRight.js new file mode 100644 index 0000000..556dc37 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/flowRight.js @@ -0,0 +1 @@ +module.exports = require('../flowRight'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/forEach.js b/platforms/android/assets/www/node_modules/lodash/fp/forEach.js new file mode 100644 index 0000000..d715ea6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/forEach.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forEach', require('../forEach')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/forEachRight.js b/platforms/android/assets/www/node_modules/lodash/fp/forEachRight.js new file mode 100644 index 0000000..90dd8dd --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/forEachRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forEachRight', require('../forEachRight')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/forIn.js b/platforms/android/assets/www/node_modules/lodash/fp/forIn.js new file mode 100644 index 0000000..90a8f07 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/forIn.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forIn', require('../forIn')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/forInRight.js b/platforms/android/assets/www/node_modules/lodash/fp/forInRight.js new file mode 100644 index 0000000..505258f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/forInRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forInRight', require('../forInRight')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/forOwn.js b/platforms/android/assets/www/node_modules/lodash/fp/forOwn.js new file mode 100644 index 0000000..6fef1e3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/forOwn.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forOwn', require('../forOwn')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/forOwnRight.js b/platforms/android/assets/www/node_modules/lodash/fp/forOwnRight.js new file mode 100644 index 0000000..11ff1fd --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/forOwnRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forOwnRight', require('../forOwnRight')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/fromPairs.js b/platforms/android/assets/www/node_modules/lodash/fp/fromPairs.js new file mode 100644 index 0000000..f5c3cb8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/fromPairs.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('fromPairs', require('../fromPairs')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/function.js b/platforms/android/assets/www/node_modules/lodash/fp/function.js new file mode 100644 index 0000000..dfe69b1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/function.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../function')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/functions.js b/platforms/android/assets/www/node_modules/lodash/fp/functions.js new file mode 100644 index 0000000..bb1cb93 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/functions.js @@ -0,0 +1 @@ +module.exports = require('../functions'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/functionsIn.js b/platforms/android/assets/www/node_modules/lodash/fp/functionsIn.js new file mode 100644 index 0000000..d375213 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/functionsIn.js @@ -0,0 +1 @@ +module.exports = require('../functionsIn'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/get.js b/platforms/android/assets/www/node_modules/lodash/fp/get.js new file mode 100644 index 0000000..a054c9d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/get.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('get', require('../get')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/getOr.js b/platforms/android/assets/www/node_modules/lodash/fp/getOr.js new file mode 100644 index 0000000..c46f2e9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/getOr.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('getOr', require('../get')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/groupBy.js b/platforms/android/assets/www/node_modules/lodash/fp/groupBy.js new file mode 100644 index 0000000..6588856 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/groupBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('groupBy', require('../groupBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/gt.js b/platforms/android/assets/www/node_modules/lodash/fp/gt.js new file mode 100644 index 0000000..5b92de9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/gt.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('gt', require('../gt')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/gte.js b/platforms/android/assets/www/node_modules/lodash/fp/gte.js new file mode 100644 index 0000000..3a40250 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/gte.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('gte', require('../gte')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/has.js b/platforms/android/assets/www/node_modules/lodash/fp/has.js new file mode 100644 index 0000000..e37db9a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/has.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('has', require('../has')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/hasIn.js b/platforms/android/assets/www/node_modules/lodash/fp/hasIn.js new file mode 100644 index 0000000..84d7815 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/hasIn.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('hasIn', require('../hasIn')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/head.js b/platforms/android/assets/www/node_modules/lodash/fp/head.js new file mode 100644 index 0000000..bd97a7b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/head.js @@ -0,0 +1 @@ +module.exports = require('../head'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/identity.js b/platforms/android/assets/www/node_modules/lodash/fp/identity.js new file mode 100644 index 0000000..6d007dc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/identity.js @@ -0,0 +1 @@ +module.exports = require('../identity'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/inRange.js b/platforms/android/assets/www/node_modules/lodash/fp/inRange.js new file mode 100644 index 0000000..fc55e1c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/inRange.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('inRange', require('../inRange')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/includes.js b/platforms/android/assets/www/node_modules/lodash/fp/includes.js new file mode 100644 index 0000000..91f1eec --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/includes.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('includes', require('../includes')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/indexOf.js b/platforms/android/assets/www/node_modules/lodash/fp/indexOf.js new file mode 100644 index 0000000..65345ce --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/indexOf.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('indexOf', require('../indexOf')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/init.js b/platforms/android/assets/www/node_modules/lodash/fp/init.js new file mode 100644 index 0000000..2f88d8b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/init.js @@ -0,0 +1 @@ +module.exports = require('./initial'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/initial.js b/platforms/android/assets/www/node_modules/lodash/fp/initial.js new file mode 100644 index 0000000..9fc94e0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/initial.js @@ -0,0 +1 @@ +module.exports = require('../initial'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/intersection.js b/platforms/android/assets/www/node_modules/lodash/fp/intersection.js new file mode 100644 index 0000000..784f4d1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/intersection.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('intersection', require('../intersection')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/intersectionBy.js b/platforms/android/assets/www/node_modules/lodash/fp/intersectionBy.js new file mode 100644 index 0000000..4aa93b6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/intersectionBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('intersectionBy', require('../intersectionBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/intersectionWith.js b/platforms/android/assets/www/node_modules/lodash/fp/intersectionWith.js new file mode 100644 index 0000000..879fe9d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/intersectionWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('intersectionWith', require('../intersectionWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/invert.js b/platforms/android/assets/www/node_modules/lodash/fp/invert.js new file mode 100644 index 0000000..231d5ca --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/invert.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('invert', require('../invert')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/invertBy.js b/platforms/android/assets/www/node_modules/lodash/fp/invertBy.js new file mode 100644 index 0000000..90820e6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/invertBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('invertBy', require('../invertBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/invoke.js b/platforms/android/assets/www/node_modules/lodash/fp/invoke.js new file mode 100644 index 0000000..a8635e8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/invoke.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('invoke', require('../invoke')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/invokeMap.js b/platforms/android/assets/www/node_modules/lodash/fp/invokeMap.js new file mode 100644 index 0000000..2691ae3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/invokeMap.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('invokeMap', require('../invokeMap')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isArguments.js b/platforms/android/assets/www/node_modules/lodash/fp/isArguments.js new file mode 100644 index 0000000..093aa35 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isArguments.js @@ -0,0 +1 @@ +module.exports = require('../isArguments'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isArray.js b/platforms/android/assets/www/node_modules/lodash/fp/isArray.js new file mode 100644 index 0000000..ec7fad3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isArray.js @@ -0,0 +1 @@ +module.exports = require('../isArray'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isArrayBuffer.js b/platforms/android/assets/www/node_modules/lodash/fp/isArrayBuffer.js new file mode 100644 index 0000000..655e85b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isArrayBuffer.js @@ -0,0 +1 @@ +module.exports = require('../isArrayBuffer'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isArrayLike.js b/platforms/android/assets/www/node_modules/lodash/fp/isArrayLike.js new file mode 100644 index 0000000..1595b2f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isArrayLike.js @@ -0,0 +1 @@ +module.exports = require('../isArrayLike'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isArrayLikeObject.js b/platforms/android/assets/www/node_modules/lodash/fp/isArrayLikeObject.js new file mode 100644 index 0000000..4d1d202 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isArrayLikeObject.js @@ -0,0 +1 @@ +module.exports = require('../isArrayLikeObject'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isBoolean.js b/platforms/android/assets/www/node_modules/lodash/fp/isBoolean.js new file mode 100644 index 0000000..30d4a4a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isBoolean.js @@ -0,0 +1 @@ +module.exports = require('../isBoolean'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isBuffer.js b/platforms/android/assets/www/node_modules/lodash/fp/isBuffer.js new file mode 100644 index 0000000..15af9b6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isBuffer.js @@ -0,0 +1 @@ +module.exports = require('../isBuffer'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isDate.js b/platforms/android/assets/www/node_modules/lodash/fp/isDate.js new file mode 100644 index 0000000..ac002f4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isDate.js @@ -0,0 +1 @@ +module.exports = require('../isDate'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isElement.js b/platforms/android/assets/www/node_modules/lodash/fp/isElement.js new file mode 100644 index 0000000..458a348 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isElement.js @@ -0,0 +1 @@ +module.exports = require('../isElement'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isEmpty.js b/platforms/android/assets/www/node_modules/lodash/fp/isEmpty.js new file mode 100644 index 0000000..b1a04cd --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isEmpty.js @@ -0,0 +1 @@ +module.exports = require('../isEmpty'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isEqual.js b/platforms/android/assets/www/node_modules/lodash/fp/isEqual.js new file mode 100644 index 0000000..91b7d66 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isEqual.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('isEqual', require('../isEqual')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isEqualWith.js b/platforms/android/assets/www/node_modules/lodash/fp/isEqualWith.js new file mode 100644 index 0000000..37a6e35 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isEqualWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('isEqualWith', require('../isEqualWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isError.js b/platforms/android/assets/www/node_modules/lodash/fp/isError.js new file mode 100644 index 0000000..da2710c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isError.js @@ -0,0 +1 @@ +module.exports = require('../isError'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isFinite.js b/platforms/android/assets/www/node_modules/lodash/fp/isFinite.js new file mode 100644 index 0000000..a71e53d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isFinite.js @@ -0,0 +1 @@ +module.exports = require('../isFinite'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isFunction.js b/platforms/android/assets/www/node_modules/lodash/fp/isFunction.js new file mode 100644 index 0000000..1fc73f6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isFunction.js @@ -0,0 +1 @@ +module.exports = require('../isFunction'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isInteger.js b/platforms/android/assets/www/node_modules/lodash/fp/isInteger.js new file mode 100644 index 0000000..f990b01 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isInteger.js @@ -0,0 +1 @@ +module.exports = require('../isInteger'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isLength.js b/platforms/android/assets/www/node_modules/lodash/fp/isLength.js new file mode 100644 index 0000000..f40c362 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isLength.js @@ -0,0 +1 @@ +module.exports = require('../isLength'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isMap.js b/platforms/android/assets/www/node_modules/lodash/fp/isMap.js new file mode 100644 index 0000000..51fb7e2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isMap.js @@ -0,0 +1 @@ +module.exports = require('../isMap'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isMatch.js b/platforms/android/assets/www/node_modules/lodash/fp/isMatch.js new file mode 100644 index 0000000..749c903 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isMatch.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('isMatch', require('../isMatch')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isMatchWith.js b/platforms/android/assets/www/node_modules/lodash/fp/isMatchWith.js new file mode 100644 index 0000000..b1311fc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isMatchWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('isMatchWith', require('../isMatchWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isNaN.js b/platforms/android/assets/www/node_modules/lodash/fp/isNaN.js new file mode 100644 index 0000000..74daf0a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isNaN.js @@ -0,0 +1 @@ +module.exports = require('../isNaN'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isNative.js b/platforms/android/assets/www/node_modules/lodash/fp/isNative.js new file mode 100644 index 0000000..9eeded4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isNative.js @@ -0,0 +1 @@ +module.exports = require('../isNative'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isNil.js b/platforms/android/assets/www/node_modules/lodash/fp/isNil.js new file mode 100644 index 0000000..beace9d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isNil.js @@ -0,0 +1 @@ +module.exports = require('../isNil'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isNull.js b/platforms/android/assets/www/node_modules/lodash/fp/isNull.js new file mode 100644 index 0000000..44689a7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isNull.js @@ -0,0 +1 @@ +module.exports = require('../isNull'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isNumber.js b/platforms/android/assets/www/node_modules/lodash/fp/isNumber.js new file mode 100644 index 0000000..d7e8615 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isNumber.js @@ -0,0 +1 @@ +module.exports = require('../isNumber'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isObject.js b/platforms/android/assets/www/node_modules/lodash/fp/isObject.js new file mode 100644 index 0000000..bb48630 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isObject.js @@ -0,0 +1 @@ +module.exports = require('../isObject'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isObjectLike.js b/platforms/android/assets/www/node_modules/lodash/fp/isObjectLike.js new file mode 100644 index 0000000..5ef6f62 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isObjectLike.js @@ -0,0 +1 @@ +module.exports = require('../isObjectLike'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isPlainObject.js b/platforms/android/assets/www/node_modules/lodash/fp/isPlainObject.js new file mode 100644 index 0000000..2d34d86 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isPlainObject.js @@ -0,0 +1 @@ +module.exports = require('../isPlainObject'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isRegExp.js b/platforms/android/assets/www/node_modules/lodash/fp/isRegExp.js new file mode 100644 index 0000000..4d0727b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isRegExp.js @@ -0,0 +1 @@ +module.exports = require('../isRegExp'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isSafeInteger.js b/platforms/android/assets/www/node_modules/lodash/fp/isSafeInteger.js new file mode 100644 index 0000000..ed08cab --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isSafeInteger.js @@ -0,0 +1 @@ +module.exports = require('../isSafeInteger'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isSet.js b/platforms/android/assets/www/node_modules/lodash/fp/isSet.js new file mode 100644 index 0000000..f8a0a49 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isSet.js @@ -0,0 +1 @@ +module.exports = require('../isSet'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isString.js b/platforms/android/assets/www/node_modules/lodash/fp/isString.js new file mode 100644 index 0000000..2f22d0e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isString.js @@ -0,0 +1 @@ +module.exports = require('../isString'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isSymbol.js b/platforms/android/assets/www/node_modules/lodash/fp/isSymbol.js new file mode 100644 index 0000000..9ce6731 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isSymbol.js @@ -0,0 +1 @@ +module.exports = require('../isSymbol'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isTypedArray.js b/platforms/android/assets/www/node_modules/lodash/fp/isTypedArray.js new file mode 100644 index 0000000..72349c5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isTypedArray.js @@ -0,0 +1 @@ +module.exports = require('../isTypedArray'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isUndefined.js b/platforms/android/assets/www/node_modules/lodash/fp/isUndefined.js new file mode 100644 index 0000000..a65c5be --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isUndefined.js @@ -0,0 +1 @@ +module.exports = require('../isUndefined'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isWeakMap.js b/platforms/android/assets/www/node_modules/lodash/fp/isWeakMap.js new file mode 100644 index 0000000..dc62201 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isWeakMap.js @@ -0,0 +1 @@ +module.exports = require('../isWeakMap'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/isWeakSet.js b/platforms/android/assets/www/node_modules/lodash/fp/isWeakSet.js new file mode 100644 index 0000000..7646ca8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/isWeakSet.js @@ -0,0 +1 @@ +module.exports = require('../isWeakSet'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/iteratee.js b/platforms/android/assets/www/node_modules/lodash/fp/iteratee.js new file mode 100644 index 0000000..2884465 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/iteratee.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('iteratee', require('../iteratee')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/join.js b/platforms/android/assets/www/node_modules/lodash/fp/join.js new file mode 100644 index 0000000..fdaa488 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/join.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('join', require('../join')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/kebabCase.js b/platforms/android/assets/www/node_modules/lodash/fp/kebabCase.js new file mode 100644 index 0000000..f251a4d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/kebabCase.js @@ -0,0 +1 @@ +module.exports = require('../kebabCase'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/keyBy.js b/platforms/android/assets/www/node_modules/lodash/fp/keyBy.js new file mode 100644 index 0000000..ad9abac --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/keyBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('keyBy', require('../keyBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/keys.js b/platforms/android/assets/www/node_modules/lodash/fp/keys.js new file mode 100644 index 0000000..23dc6b7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/keys.js @@ -0,0 +1 @@ +module.exports = require('../keys'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/keysIn.js b/platforms/android/assets/www/node_modules/lodash/fp/keysIn.js new file mode 100644 index 0000000..2b738b9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/keysIn.js @@ -0,0 +1 @@ +module.exports = require('../keysIn'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/lang.js b/platforms/android/assets/www/node_modules/lodash/fp/lang.js new file mode 100644 index 0000000..08cc9c1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/lang.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../lang')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/last.js b/platforms/android/assets/www/node_modules/lodash/fp/last.js new file mode 100644 index 0000000..222be23 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/last.js @@ -0,0 +1 @@ +module.exports = require('../last'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/lastIndexOf.js b/platforms/android/assets/www/node_modules/lodash/fp/lastIndexOf.js new file mode 100644 index 0000000..e27480e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/lastIndexOf.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('lastIndexOf', require('../lastIndexOf')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/lowerCase.js b/platforms/android/assets/www/node_modules/lodash/fp/lowerCase.js new file mode 100644 index 0000000..4da15ce --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/lowerCase.js @@ -0,0 +1 @@ +module.exports = require('../lowerCase'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/lowerFirst.js b/platforms/android/assets/www/node_modules/lodash/fp/lowerFirst.js new file mode 100644 index 0000000..afd1ba5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/lowerFirst.js @@ -0,0 +1 @@ +module.exports = require('../lowerFirst'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/lt.js b/platforms/android/assets/www/node_modules/lodash/fp/lt.js new file mode 100644 index 0000000..dd4cba0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/lt.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('lt', require('../lt')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/lte.js b/platforms/android/assets/www/node_modules/lodash/fp/lte.js new file mode 100644 index 0000000..f9bf725 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/lte.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('lte', require('../lte')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/map.js b/platforms/android/assets/www/node_modules/lodash/fp/map.js new file mode 100644 index 0000000..b74c1a1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/map.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('map', require('../map')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/mapKeys.js b/platforms/android/assets/www/node_modules/lodash/fp/mapKeys.js new file mode 100644 index 0000000..a8156c1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/mapKeys.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('mapKeys', require('../mapKeys')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/mapObj.js b/platforms/android/assets/www/node_modules/lodash/fp/mapObj.js new file mode 100644 index 0000000..9f1872d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/mapObj.js @@ -0,0 +1 @@ +module.exports = require('./mapValues'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/mapValues.js b/platforms/android/assets/www/node_modules/lodash/fp/mapValues.js new file mode 100644 index 0000000..9375d73 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/mapValues.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('mapValues', require('../mapValues')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/matches.js b/platforms/android/assets/www/node_modules/lodash/fp/matches.js new file mode 100644 index 0000000..eea5916 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/matches.js @@ -0,0 +1 @@ +module.exports = require('../matches'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/matchesProperty.js b/platforms/android/assets/www/node_modules/lodash/fp/matchesProperty.js new file mode 100644 index 0000000..c4343a1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/matchesProperty.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('matchesProperty', require('../matchesProperty')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/math.js b/platforms/android/assets/www/node_modules/lodash/fp/math.js new file mode 100644 index 0000000..e8f50f7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/math.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../math')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/max.js b/platforms/android/assets/www/node_modules/lodash/fp/max.js new file mode 100644 index 0000000..f7258c6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/max.js @@ -0,0 +1 @@ +module.exports = require('../max'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/maxBy.js b/platforms/android/assets/www/node_modules/lodash/fp/maxBy.js new file mode 100644 index 0000000..b81243f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/maxBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('maxBy', require('../maxBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/mean.js b/platforms/android/assets/www/node_modules/lodash/fp/mean.js new file mode 100644 index 0000000..b78e427 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/mean.js @@ -0,0 +1 @@ +module.exports = require('../mean'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/memoize.js b/platforms/android/assets/www/node_modules/lodash/fp/memoize.js new file mode 100644 index 0000000..1a45e09 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/memoize.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('memoize', require('../memoize')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/merge.js b/platforms/android/assets/www/node_modules/lodash/fp/merge.js new file mode 100644 index 0000000..3dca641 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/merge.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('merge', require('../merge')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/mergeWith.js b/platforms/android/assets/www/node_modules/lodash/fp/mergeWith.js new file mode 100644 index 0000000..ba45644 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/mergeWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('mergeWith', require('../mergeWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/method.js b/platforms/android/assets/www/node_modules/lodash/fp/method.js new file mode 100644 index 0000000..c2f95c3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/method.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('method', require('../method')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/methodOf.js b/platforms/android/assets/www/node_modules/lodash/fp/methodOf.js new file mode 100644 index 0000000..223f651 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/methodOf.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('methodOf', require('../methodOf')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/min.js b/platforms/android/assets/www/node_modules/lodash/fp/min.js new file mode 100644 index 0000000..10db02c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/min.js @@ -0,0 +1 @@ +module.exports = require('../min'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/minBy.js b/platforms/android/assets/www/node_modules/lodash/fp/minBy.js new file mode 100644 index 0000000..10edfd4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/minBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('minBy', require('../minBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/mixin.js b/platforms/android/assets/www/node_modules/lodash/fp/mixin.js new file mode 100644 index 0000000..965f180 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/mixin.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('mixin', require('../mixin')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/nAry.js b/platforms/android/assets/www/node_modules/lodash/fp/nAry.js new file mode 100644 index 0000000..f262a76 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/nAry.js @@ -0,0 +1 @@ +module.exports = require('./ary'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/negate.js b/platforms/android/assets/www/node_modules/lodash/fp/negate.js new file mode 100644 index 0000000..345b425 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/negate.js @@ -0,0 +1 @@ +module.exports = require('../negate'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/next.js b/platforms/android/assets/www/node_modules/lodash/fp/next.js new file mode 100644 index 0000000..5cad70e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/next.js @@ -0,0 +1 @@ +module.exports = require('../next'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/noop.js b/platforms/android/assets/www/node_modules/lodash/fp/noop.js new file mode 100644 index 0000000..ca10050 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/noop.js @@ -0,0 +1 @@ +module.exports = require('../noop'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/now.js b/platforms/android/assets/www/node_modules/lodash/fp/now.js new file mode 100644 index 0000000..aa5ed67 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/now.js @@ -0,0 +1 @@ +module.exports = require('../now'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/nthArg.js b/platforms/android/assets/www/node_modules/lodash/fp/nthArg.js new file mode 100644 index 0000000..dd47ac6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/nthArg.js @@ -0,0 +1 @@ +module.exports = require('../nthArg'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/number.js b/platforms/android/assets/www/node_modules/lodash/fp/number.js new file mode 100644 index 0000000..5c10b88 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/number.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../number')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/object.js b/platforms/android/assets/www/node_modules/lodash/fp/object.js new file mode 100644 index 0000000..ae39a13 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/object.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../object')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/omit.js b/platforms/android/assets/www/node_modules/lodash/fp/omit.js new file mode 100644 index 0000000..404b551 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/omit.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('omit', require('../omit')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/omitAll.js b/platforms/android/assets/www/node_modules/lodash/fp/omitAll.js new file mode 100644 index 0000000..144cf4b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/omitAll.js @@ -0,0 +1 @@ +module.exports = require('./omit'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/omitBy.js b/platforms/android/assets/www/node_modules/lodash/fp/omitBy.js new file mode 100644 index 0000000..745efa5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/omitBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('omitBy', require('../omitBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/once.js b/platforms/android/assets/www/node_modules/lodash/fp/once.js new file mode 100644 index 0000000..6bd0beb --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/once.js @@ -0,0 +1 @@ +module.exports = require('../once'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/orderBy.js b/platforms/android/assets/www/node_modules/lodash/fp/orderBy.js new file mode 100644 index 0000000..b32244f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/orderBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('orderBy', require('../orderBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/over.js b/platforms/android/assets/www/node_modules/lodash/fp/over.js new file mode 100644 index 0000000..0a5a797 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/over.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('over', require('../over')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/overArgs.js b/platforms/android/assets/www/node_modules/lodash/fp/overArgs.js new file mode 100644 index 0000000..8188387 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/overArgs.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('overArgs', require('../overArgs')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/overEvery.js b/platforms/android/assets/www/node_modules/lodash/fp/overEvery.js new file mode 100644 index 0000000..36dc552 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/overEvery.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('overEvery', require('../overEvery')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/overSome.js b/platforms/android/assets/www/node_modules/lodash/fp/overSome.js new file mode 100644 index 0000000..b02d464 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/overSome.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('overSome', require('../overSome')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pad.js b/platforms/android/assets/www/node_modules/lodash/fp/pad.js new file mode 100644 index 0000000..e59cfc9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pad.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pad', require('../pad')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/padEnd.js b/platforms/android/assets/www/node_modules/lodash/fp/padEnd.js new file mode 100644 index 0000000..0b6dbb7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/padEnd.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('padEnd', require('../padEnd')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/padStart.js b/platforms/android/assets/www/node_modules/lodash/fp/padStart.js new file mode 100644 index 0000000..c97f098 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/padStart.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('padStart', require('../padStart')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/parseInt.js b/platforms/android/assets/www/node_modules/lodash/fp/parseInt.js new file mode 100644 index 0000000..35be713 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/parseInt.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('parseInt', require('../parseInt')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/partial.js b/platforms/android/assets/www/node_modules/lodash/fp/partial.js new file mode 100644 index 0000000..a687d0c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/partial.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('partial', require('../partial')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/partialRight.js b/platforms/android/assets/www/node_modules/lodash/fp/partialRight.js new file mode 100644 index 0000000..28428c0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/partialRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('partialRight', require('../partialRight')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/partition.js b/platforms/android/assets/www/node_modules/lodash/fp/partition.js new file mode 100644 index 0000000..b1495e6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/partition.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('partition', require('../partition')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/path.js b/platforms/android/assets/www/node_modules/lodash/fp/path.js new file mode 100644 index 0000000..b29cfb2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/path.js @@ -0,0 +1 @@ +module.exports = require('./get'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pathEq.js b/platforms/android/assets/www/node_modules/lodash/fp/pathEq.js new file mode 100644 index 0000000..36c027a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pathEq.js @@ -0,0 +1 @@ +module.exports = require('./matchesProperty'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pathOr.js b/platforms/android/assets/www/node_modules/lodash/fp/pathOr.js new file mode 100644 index 0000000..4ab5820 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pathOr.js @@ -0,0 +1 @@ +module.exports = require('./getOr'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pick.js b/platforms/android/assets/www/node_modules/lodash/fp/pick.js new file mode 100644 index 0000000..e84b366 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pick.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pick', require('../pick')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pickAll.js b/platforms/android/assets/www/node_modules/lodash/fp/pickAll.js new file mode 100644 index 0000000..a8ecd46 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pickAll.js @@ -0,0 +1 @@ +module.exports = require('./pick'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pickBy.js b/platforms/android/assets/www/node_modules/lodash/fp/pickBy.js new file mode 100644 index 0000000..4d14a0b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pickBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pickBy', require('../pickBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pipe.js b/platforms/android/assets/www/node_modules/lodash/fp/pipe.js new file mode 100644 index 0000000..b2e1e2c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pipe.js @@ -0,0 +1 @@ +module.exports = require('./flow'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/plant.js b/platforms/android/assets/www/node_modules/lodash/fp/plant.js new file mode 100644 index 0000000..c85596a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/plant.js @@ -0,0 +1 @@ +module.exports = require('../plant'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/prop.js b/platforms/android/assets/www/node_modules/lodash/fp/prop.js new file mode 100644 index 0000000..b29cfb2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/prop.js @@ -0,0 +1 @@ +module.exports = require('./get'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/propOf.js b/platforms/android/assets/www/node_modules/lodash/fp/propOf.js new file mode 100644 index 0000000..cf0d197 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/propOf.js @@ -0,0 +1 @@ +module.exports = require('./propertyOf'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/propOr.js b/platforms/android/assets/www/node_modules/lodash/fp/propOr.js new file mode 100644 index 0000000..4ab5820 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/propOr.js @@ -0,0 +1 @@ +module.exports = require('./getOr'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/property.js b/platforms/android/assets/www/node_modules/lodash/fp/property.js new file mode 100644 index 0000000..fab6f23 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/property.js @@ -0,0 +1 @@ +module.exports = require('../property'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/propertyOf.js b/platforms/android/assets/www/node_modules/lodash/fp/propertyOf.js new file mode 100644 index 0000000..d941cdb --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/propertyOf.js @@ -0,0 +1 @@ +module.exports = require('../propertyOf'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pull.js b/platforms/android/assets/www/node_modules/lodash/fp/pull.js new file mode 100644 index 0000000..47f49ae --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pull.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pull', require('../pull')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pullAll.js b/platforms/android/assets/www/node_modules/lodash/fp/pullAll.js new file mode 100644 index 0000000..ffb663b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pullAll.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pullAll', require('../pullAll')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pullAllBy.js b/platforms/android/assets/www/node_modules/lodash/fp/pullAllBy.js new file mode 100644 index 0000000..23b11b7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pullAllBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pullAllBy', require('../pullAllBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pullAllWith.js b/platforms/android/assets/www/node_modules/lodash/fp/pullAllWith.js new file mode 100644 index 0000000..495d574 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pullAllWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pullAllWith', require('../pullAllWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/pullAt.js b/platforms/android/assets/www/node_modules/lodash/fp/pullAt.js new file mode 100644 index 0000000..5836d2d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/pullAt.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pullAt', require('../pullAt')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/random.js b/platforms/android/assets/www/node_modules/lodash/fp/random.js new file mode 100644 index 0000000..607d63a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/random.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('random', require('../random')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/range.js b/platforms/android/assets/www/node_modules/lodash/fp/range.js new file mode 100644 index 0000000..1142304 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/range.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('range', require('../range')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/rangeRight.js b/platforms/android/assets/www/node_modules/lodash/fp/rangeRight.js new file mode 100644 index 0000000..2248287 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/rangeRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('rangeRight', require('../rangeRight')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/rearg.js b/platforms/android/assets/www/node_modules/lodash/fp/rearg.js new file mode 100644 index 0000000..b2753e9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/rearg.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('rearg', require('../rearg')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/reduce.js b/platforms/android/assets/www/node_modules/lodash/fp/reduce.js new file mode 100644 index 0000000..2f1b425 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/reduce.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('reduce', require('../reduce')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/reduceRight.js b/platforms/android/assets/www/node_modules/lodash/fp/reduceRight.js new file mode 100644 index 0000000..b110e9e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/reduceRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('reduceRight', require('../reduceRight')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/reject.js b/platforms/android/assets/www/node_modules/lodash/fp/reject.js new file mode 100644 index 0000000..30bd3bc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/reject.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('reject', require('../reject')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/remove.js b/platforms/android/assets/www/node_modules/lodash/fp/remove.js new file mode 100644 index 0000000..4b67a94 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/remove.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('remove', require('../remove')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/repeat.js b/platforms/android/assets/www/node_modules/lodash/fp/repeat.js new file mode 100644 index 0000000..bc0704b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/repeat.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('repeat', require('../repeat')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/replace.js b/platforms/android/assets/www/node_modules/lodash/fp/replace.js new file mode 100644 index 0000000..a4462e7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/replace.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('replace', require('../replace')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/rest.js b/platforms/android/assets/www/node_modules/lodash/fp/rest.js new file mode 100644 index 0000000..69dfc18 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/rest.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('rest', require('../rest')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/result.js b/platforms/android/assets/www/node_modules/lodash/fp/result.js new file mode 100644 index 0000000..1d3fb58 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/result.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('result', require('../result')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/reverse.js b/platforms/android/assets/www/node_modules/lodash/fp/reverse.js new file mode 100644 index 0000000..a6d960d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/reverse.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('reverse', require('../reverse')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/round.js b/platforms/android/assets/www/node_modules/lodash/fp/round.js new file mode 100644 index 0000000..9eb69b1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/round.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('round', require('../round')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sample.js b/platforms/android/assets/www/node_modules/lodash/fp/sample.js new file mode 100644 index 0000000..008cb06 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sample.js @@ -0,0 +1 @@ +module.exports = require('../sample'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sampleSize.js b/platforms/android/assets/www/node_modules/lodash/fp/sampleSize.js new file mode 100644 index 0000000..920c075 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sampleSize.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sampleSize', require('../sampleSize')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/seq.js b/platforms/android/assets/www/node_modules/lodash/fp/seq.js new file mode 100644 index 0000000..d8f42b0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/seq.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../seq')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/set.js b/platforms/android/assets/www/node_modules/lodash/fp/set.js new file mode 100644 index 0000000..fc2a75b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/set.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('set', require('../set')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/setWith.js b/platforms/android/assets/www/node_modules/lodash/fp/setWith.js new file mode 100644 index 0000000..fd836ea --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/setWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('setWith', require('../setWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/shuffle.js b/platforms/android/assets/www/node_modules/lodash/fp/shuffle.js new file mode 100644 index 0000000..85d5699 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/shuffle.js @@ -0,0 +1 @@ +module.exports = require('../shuffle'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/size.js b/platforms/android/assets/www/node_modules/lodash/fp/size.js new file mode 100644 index 0000000..efba2ca --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/size.js @@ -0,0 +1 @@ +module.exports = require('../size'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/slice.js b/platforms/android/assets/www/node_modules/lodash/fp/slice.js new file mode 100644 index 0000000..6fb1898 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/slice.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('slice', require('../slice')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/snakeCase.js b/platforms/android/assets/www/node_modules/lodash/fp/snakeCase.js new file mode 100644 index 0000000..2893f7b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/snakeCase.js @@ -0,0 +1 @@ +module.exports = require('../snakeCase'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/some.js b/platforms/android/assets/www/node_modules/lodash/fp/some.js new file mode 100644 index 0000000..64727fe --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/some.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('some', require('../some')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/somePass.js b/platforms/android/assets/www/node_modules/lodash/fp/somePass.js new file mode 100644 index 0000000..2774ab3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/somePass.js @@ -0,0 +1 @@ +module.exports = require('./overSome'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sortBy.js b/platforms/android/assets/www/node_modules/lodash/fp/sortBy.js new file mode 100644 index 0000000..80fe4dd --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sortBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortBy', require('../sortBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sortedIndex.js b/platforms/android/assets/www/node_modules/lodash/fp/sortedIndex.js new file mode 100644 index 0000000..509dcb8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sortedIndex.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedIndex', require('../sortedIndex')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sortedIndexBy.js b/platforms/android/assets/www/node_modules/lodash/fp/sortedIndexBy.js new file mode 100644 index 0000000..aa2d219 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sortedIndexBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedIndexBy', require('../sortedIndexBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sortedIndexOf.js b/platforms/android/assets/www/node_modules/lodash/fp/sortedIndexOf.js new file mode 100644 index 0000000..c127420 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sortedIndexOf.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedIndexOf', require('../sortedIndexOf')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sortedLastIndex.js b/platforms/android/assets/www/node_modules/lodash/fp/sortedLastIndex.js new file mode 100644 index 0000000..7ec9e33 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sortedLastIndex.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedLastIndex', require('../sortedLastIndex')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sortedLastIndexBy.js b/platforms/android/assets/www/node_modules/lodash/fp/sortedLastIndexBy.js new file mode 100644 index 0000000..e03f185 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sortedLastIndexBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedLastIndexBy', require('../sortedLastIndexBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sortedLastIndexOf.js b/platforms/android/assets/www/node_modules/lodash/fp/sortedLastIndexOf.js new file mode 100644 index 0000000..0130801 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sortedLastIndexOf.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedLastIndexOf', require('../sortedLastIndexOf')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sortedUniq.js b/platforms/android/assets/www/node_modules/lodash/fp/sortedUniq.js new file mode 100644 index 0000000..c0df750 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sortedUniq.js @@ -0,0 +1 @@ +module.exports = require('../sortedUniq'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sortedUniqBy.js b/platforms/android/assets/www/node_modules/lodash/fp/sortedUniqBy.js new file mode 100644 index 0000000..f5c65ad --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sortedUniqBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedUniqBy', require('../sortedUniqBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/split.js b/platforms/android/assets/www/node_modules/lodash/fp/split.js new file mode 100644 index 0000000..79f2693 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/split.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('split', require('../split')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/spread.js b/platforms/android/assets/www/node_modules/lodash/fp/spread.js new file mode 100644 index 0000000..0348df2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/spread.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('spread', require('../spread')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/startCase.js b/platforms/android/assets/www/node_modules/lodash/fp/startCase.js new file mode 100644 index 0000000..2a6a66e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/startCase.js @@ -0,0 +1 @@ +module.exports = require('../startCase'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/startsWith.js b/platforms/android/assets/www/node_modules/lodash/fp/startsWith.js new file mode 100644 index 0000000..730a141 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/startsWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('startsWith', require('../startsWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/string.js b/platforms/android/assets/www/node_modules/lodash/fp/string.js new file mode 100644 index 0000000..773b037 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/string.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../string')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/subtract.js b/platforms/android/assets/www/node_modules/lodash/fp/subtract.js new file mode 100644 index 0000000..46b83db --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/subtract.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('subtract', require('../subtract')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sum.js b/platforms/android/assets/www/node_modules/lodash/fp/sum.js new file mode 100644 index 0000000..e8a59c5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sum.js @@ -0,0 +1 @@ +module.exports = require('../sum'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/sumBy.js b/platforms/android/assets/www/node_modules/lodash/fp/sumBy.js new file mode 100644 index 0000000..2692dc1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/sumBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sumBy', require('../sumBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/tail.js b/platforms/android/assets/www/node_modules/lodash/fp/tail.js new file mode 100644 index 0000000..36c6494 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/tail.js @@ -0,0 +1 @@ +module.exports = require('../tail'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/take.js b/platforms/android/assets/www/node_modules/lodash/fp/take.js new file mode 100644 index 0000000..e0984a4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/take.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('take', require('../take')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/takeRight.js b/platforms/android/assets/www/node_modules/lodash/fp/takeRight.js new file mode 100644 index 0000000..7b7c3ce --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/takeRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('takeRight', require('../takeRight')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/takeRightWhile.js b/platforms/android/assets/www/node_modules/lodash/fp/takeRightWhile.js new file mode 100644 index 0000000..305b254 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/takeRightWhile.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('takeRightWhile', require('../takeRightWhile')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/takeWhile.js b/platforms/android/assets/www/node_modules/lodash/fp/takeWhile.js new file mode 100644 index 0000000..a90126d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/takeWhile.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('takeWhile', require('../takeWhile')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/tap.js b/platforms/android/assets/www/node_modules/lodash/fp/tap.js new file mode 100644 index 0000000..3bec2bd --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/tap.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('tap', require('../tap')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/template.js b/platforms/android/assets/www/node_modules/lodash/fp/template.js new file mode 100644 index 0000000..0130d14 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/template.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('template', require('../template')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/templateSettings.js b/platforms/android/assets/www/node_modules/lodash/fp/templateSettings.js new file mode 100644 index 0000000..ddbbb58 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/templateSettings.js @@ -0,0 +1 @@ +module.exports = require('../templateSettings'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/throttle.js b/platforms/android/assets/www/node_modules/lodash/fp/throttle.js new file mode 100644 index 0000000..36f76d6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/throttle.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('throttle', require('../throttle')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/thru.js b/platforms/android/assets/www/node_modules/lodash/fp/thru.js new file mode 100644 index 0000000..05ddaef --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/thru.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('thru', require('../thru')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/times.js b/platforms/android/assets/www/node_modules/lodash/fp/times.js new file mode 100644 index 0000000..02fd3b7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/times.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('times', require('../times')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toArray.js b/platforms/android/assets/www/node_modules/lodash/fp/toArray.js new file mode 100644 index 0000000..1ea0b52 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toArray.js @@ -0,0 +1 @@ +module.exports = require('../toArray'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toInteger.js b/platforms/android/assets/www/node_modules/lodash/fp/toInteger.js new file mode 100644 index 0000000..17e59a3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toInteger.js @@ -0,0 +1 @@ +module.exports = require('../toInteger'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toIterator.js b/platforms/android/assets/www/node_modules/lodash/fp/toIterator.js new file mode 100644 index 0000000..13bf21c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toIterator.js @@ -0,0 +1 @@ +module.exports = require('../toIterator'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toJSON.js b/platforms/android/assets/www/node_modules/lodash/fp/toJSON.js new file mode 100644 index 0000000..5f6cb92 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toJSON.js @@ -0,0 +1 @@ +module.exports = require('../toJSON'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toLength.js b/platforms/android/assets/www/node_modules/lodash/fp/toLength.js new file mode 100644 index 0000000..38529fb --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toLength.js @@ -0,0 +1 @@ +module.exports = require('../toLength'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toLower.js b/platforms/android/assets/www/node_modules/lodash/fp/toLower.js new file mode 100644 index 0000000..01d3432 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toLower.js @@ -0,0 +1 @@ +module.exports = require('../toLower'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toNumber.js b/platforms/android/assets/www/node_modules/lodash/fp/toNumber.js new file mode 100644 index 0000000..071e320 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toNumber.js @@ -0,0 +1 @@ +module.exports = require('../toNumber'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toPairs.js b/platforms/android/assets/www/node_modules/lodash/fp/toPairs.js new file mode 100644 index 0000000..4b4dcb7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toPairs.js @@ -0,0 +1 @@ +module.exports = require('../toPairs'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toPairsIn.js b/platforms/android/assets/www/node_modules/lodash/fp/toPairsIn.js new file mode 100644 index 0000000..53076cc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toPairsIn.js @@ -0,0 +1 @@ +module.exports = require('../toPairsIn'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toPath.js b/platforms/android/assets/www/node_modules/lodash/fp/toPath.js new file mode 100644 index 0000000..62762ec --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toPath.js @@ -0,0 +1 @@ +module.exports = require('../toPath'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toPlainObject.js b/platforms/android/assets/www/node_modules/lodash/fp/toPlainObject.js new file mode 100644 index 0000000..6a6aebd --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toPlainObject.js @@ -0,0 +1 @@ +module.exports = require('../toPlainObject'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toSafeInteger.js b/platforms/android/assets/www/node_modules/lodash/fp/toSafeInteger.js new file mode 100644 index 0000000..3f5b817 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toSafeInteger.js @@ -0,0 +1 @@ +module.exports = require('../toSafeInteger'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toString.js b/platforms/android/assets/www/node_modules/lodash/fp/toString.js new file mode 100644 index 0000000..c309058 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toString.js @@ -0,0 +1 @@ +module.exports = require('../[object Object]'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/toUpper.js b/platforms/android/assets/www/node_modules/lodash/fp/toUpper.js new file mode 100644 index 0000000..428eb33 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/toUpper.js @@ -0,0 +1 @@ +module.exports = require('../toUpper'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/transform.js b/platforms/android/assets/www/node_modules/lodash/fp/transform.js new file mode 100644 index 0000000..30bed49 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/transform.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('transform', require('../transform')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/trim.js b/platforms/android/assets/www/node_modules/lodash/fp/trim.js new file mode 100644 index 0000000..b7cafe9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/trim.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trim', require('../trim')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/trimChars.js b/platforms/android/assets/www/node_modules/lodash/fp/trimChars.js new file mode 100644 index 0000000..051ea1e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/trimChars.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trimChars', require('../trim')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/trimCharsEnd.js b/platforms/android/assets/www/node_modules/lodash/fp/trimCharsEnd.js new file mode 100644 index 0000000..54c5cff --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/trimCharsEnd.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trimCharsEnd', require('../trimEnd')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/trimCharsStart.js b/platforms/android/assets/www/node_modules/lodash/fp/trimCharsStart.js new file mode 100644 index 0000000..44f9866 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/trimCharsStart.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trimCharsStart', require('../trimStart')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/trimEnd.js b/platforms/android/assets/www/node_modules/lodash/fp/trimEnd.js new file mode 100644 index 0000000..1666596 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/trimEnd.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trimEnd', require('../trimEnd')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/trimStart.js b/platforms/android/assets/www/node_modules/lodash/fp/trimStart.js new file mode 100644 index 0000000..4921b03 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/trimStart.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trimStart', require('../trimStart')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/truncate.js b/platforms/android/assets/www/node_modules/lodash/fp/truncate.js new file mode 100644 index 0000000..0c4d158 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/truncate.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('truncate', require('../truncate')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/unapply.js b/platforms/android/assets/www/node_modules/lodash/fp/unapply.js new file mode 100644 index 0000000..c5dfe77 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/unapply.js @@ -0,0 +1 @@ +module.exports = require('./rest'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/unary.js b/platforms/android/assets/www/node_modules/lodash/fp/unary.js new file mode 100644 index 0000000..3bc6483 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/unary.js @@ -0,0 +1 @@ +module.exports = require('../unary'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/unescape.js b/platforms/android/assets/www/node_modules/lodash/fp/unescape.js new file mode 100644 index 0000000..4233b15 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/unescape.js @@ -0,0 +1 @@ +module.exports = require('../unescape'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/union.js b/platforms/android/assets/www/node_modules/lodash/fp/union.js new file mode 100644 index 0000000..9deef12 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/union.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('union', require('../union')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/unionBy.js b/platforms/android/assets/www/node_modules/lodash/fp/unionBy.js new file mode 100644 index 0000000..029b359 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/unionBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('unionBy', require('../unionBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/unionWith.js b/platforms/android/assets/www/node_modules/lodash/fp/unionWith.js new file mode 100644 index 0000000..631eda0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/unionWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('unionWith', require('../unionWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/uniq.js b/platforms/android/assets/www/node_modules/lodash/fp/uniq.js new file mode 100644 index 0000000..c64510f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/uniq.js @@ -0,0 +1 @@ +module.exports = require('../uniq'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/uniqBy.js b/platforms/android/assets/www/node_modules/lodash/fp/uniqBy.js new file mode 100644 index 0000000..1b6c03f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/uniqBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('uniqBy', require('../uniqBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/uniqWith.js b/platforms/android/assets/www/node_modules/lodash/fp/uniqWith.js new file mode 100644 index 0000000..be4c48d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/uniqWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('uniqWith', require('../uniqWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/uniqueId.js b/platforms/android/assets/www/node_modules/lodash/fp/uniqueId.js new file mode 100644 index 0000000..daa41cb --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/uniqueId.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('uniqueId', require('../uniqueId')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/unnest.js b/platforms/android/assets/www/node_modules/lodash/fp/unnest.js new file mode 100644 index 0000000..5d34060 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/unnest.js @@ -0,0 +1 @@ +module.exports = require('./flatten'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/unset.js b/platforms/android/assets/www/node_modules/lodash/fp/unset.js new file mode 100644 index 0000000..0c4c1a6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/unset.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('unset', require('../unset')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/unzip.js b/platforms/android/assets/www/node_modules/lodash/fp/unzip.js new file mode 100644 index 0000000..e0ac2db --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/unzip.js @@ -0,0 +1 @@ +module.exports = require('../unzip'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/unzipWith.js b/platforms/android/assets/www/node_modules/lodash/fp/unzipWith.js new file mode 100644 index 0000000..de25cf7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/unzipWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('unzipWith', require('../unzipWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/update.js b/platforms/android/assets/www/node_modules/lodash/fp/update.js new file mode 100644 index 0000000..93e0d57 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/update.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('update', require('../update')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/updateWith.js b/platforms/android/assets/www/node_modules/lodash/fp/updateWith.js new file mode 100644 index 0000000..a6ed49e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/updateWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('updateWith', require('../updateWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/upperCase.js b/platforms/android/assets/www/node_modules/lodash/fp/upperCase.js new file mode 100644 index 0000000..ddcb369 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/upperCase.js @@ -0,0 +1 @@ +module.exports = require('../upperCase'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/upperFirst.js b/platforms/android/assets/www/node_modules/lodash/fp/upperFirst.js new file mode 100644 index 0000000..34f1e20 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/upperFirst.js @@ -0,0 +1 @@ +module.exports = require('../upperFirst'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/useWith.js b/platforms/android/assets/www/node_modules/lodash/fp/useWith.js new file mode 100644 index 0000000..d8b3df5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/useWith.js @@ -0,0 +1 @@ +module.exports = require('./overArgs'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/util.js b/platforms/android/assets/www/node_modules/lodash/fp/util.js new file mode 100644 index 0000000..18c00ba --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/util.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../util')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/value.js b/platforms/android/assets/www/node_modules/lodash/fp/value.js new file mode 100644 index 0000000..4dc0e7e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/value.js @@ -0,0 +1 @@ +module.exports = require('../value'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/valueOf.js b/platforms/android/assets/www/node_modules/lodash/fp/valueOf.js new file mode 100644 index 0000000..c309058 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/valueOf.js @@ -0,0 +1 @@ +module.exports = require('../[object Object]'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/values.js b/platforms/android/assets/www/node_modules/lodash/fp/values.js new file mode 100644 index 0000000..3843170 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/values.js @@ -0,0 +1 @@ +module.exports = require('../values'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/valuesIn.js b/platforms/android/assets/www/node_modules/lodash/fp/valuesIn.js new file mode 100644 index 0000000..f81c171 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/valuesIn.js @@ -0,0 +1 @@ +module.exports = require('../valuesIn'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/whereEq.js b/platforms/android/assets/www/node_modules/lodash/fp/whereEq.js new file mode 100644 index 0000000..ade80f6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/whereEq.js @@ -0,0 +1 @@ +module.exports = require('./filter'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/without.js b/platforms/android/assets/www/node_modules/lodash/fp/without.js new file mode 100644 index 0000000..5238e94 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/without.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('without', require('../without')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/words.js b/platforms/android/assets/www/node_modules/lodash/fp/words.js new file mode 100644 index 0000000..b58a485 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/words.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('words', require('../words')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/wrap.js b/platforms/android/assets/www/node_modules/lodash/fp/wrap.js new file mode 100644 index 0000000..56465a2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/wrap.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('wrap', require('../wrap')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/wrapperAt.js b/platforms/android/assets/www/node_modules/lodash/fp/wrapperAt.js new file mode 100644 index 0000000..f8d37a1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/wrapperAt.js @@ -0,0 +1 @@ +module.exports = require('../wrapperAt'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/wrapperChain.js b/platforms/android/assets/www/node_modules/lodash/fp/wrapperChain.js new file mode 100644 index 0000000..964a846 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/wrapperChain.js @@ -0,0 +1 @@ +module.exports = require('../wrapperChain'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/wrapperFlatMap.js b/platforms/android/assets/www/node_modules/lodash/fp/wrapperFlatMap.js new file mode 100644 index 0000000..fa030c0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/wrapperFlatMap.js @@ -0,0 +1 @@ +module.exports = require('../wrapperFlatMap'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/wrapperLodash.js b/platforms/android/assets/www/node_modules/lodash/fp/wrapperLodash.js new file mode 100644 index 0000000..d62a996 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/wrapperLodash.js @@ -0,0 +1 @@ +module.exports = require('../wrapperLodash'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/wrapperReverse.js b/platforms/android/assets/www/node_modules/lodash/fp/wrapperReverse.js new file mode 100644 index 0000000..cf70388 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/wrapperReverse.js @@ -0,0 +1 @@ +module.exports = require('../wrapperReverse'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/wrapperValue.js b/platforms/android/assets/www/node_modules/lodash/fp/wrapperValue.js new file mode 100644 index 0000000..494dfb1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/wrapperValue.js @@ -0,0 +1 @@ +module.exports = require('../wrapperValue'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/xor.js b/platforms/android/assets/www/node_modules/lodash/fp/xor.js new file mode 100644 index 0000000..0f3e025 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/xor.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('xor', require('../xor')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/xorBy.js b/platforms/android/assets/www/node_modules/lodash/fp/xorBy.js new file mode 100644 index 0000000..e48fc41 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/xorBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('xorBy', require('../xorBy')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/xorWith.js b/platforms/android/assets/www/node_modules/lodash/fp/xorWith.js new file mode 100644 index 0000000..5c2eebe --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/xorWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('xorWith', require('../xorWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/zip.js b/platforms/android/assets/www/node_modules/lodash/fp/zip.js new file mode 100644 index 0000000..0cae73b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/zip.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('zip', require('../zip')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/zipObj.js b/platforms/android/assets/www/node_modules/lodash/fp/zipObj.js new file mode 100644 index 0000000..f4a3453 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/zipObj.js @@ -0,0 +1 @@ +module.exports = require('./zipObject'); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/zipObject.js b/platforms/android/assets/www/node_modules/lodash/fp/zipObject.js new file mode 100644 index 0000000..8c2ff3b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/zipObject.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('zipObject', require('../zipObject')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/zipObjectDeep.js b/platforms/android/assets/www/node_modules/lodash/fp/zipObjectDeep.js new file mode 100644 index 0000000..a0ee4e3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/zipObjectDeep.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('zipObjectDeep', require('../zipObjectDeep')); diff --git a/platforms/android/assets/www/node_modules/lodash/fp/zipWith.js b/platforms/android/assets/www/node_modules/lodash/fp/zipWith.js new file mode 100644 index 0000000..da75f3d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fp/zipWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('zipWith', require('../zipWith')); diff --git a/platforms/android/assets/www/node_modules/lodash/fromPairs.js b/platforms/android/assets/www/node_modules/lodash/fromPairs.js new file mode 100644 index 0000000..c18c1e3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/fromPairs.js @@ -0,0 +1,27 @@ +/** + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. + * @example + * + * _.fromPairs([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + */ +function fromPairs(pairs) { + var index = -1, + length = pairs ? pairs.length : 0, + result = {}; + + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } + return result; +} + +module.exports = fromPairs; diff --git a/platforms/android/assets/www/node_modules/lodash/function.js b/platforms/android/assets/www/node_modules/lodash/function.js new file mode 100644 index 0000000..b0fc6d9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/function.js @@ -0,0 +1,25 @@ +module.exports = { + 'after': require('./after'), + 'ary': require('./ary'), + 'before': require('./before'), + 'bind': require('./bind'), + 'bindKey': require('./bindKey'), + 'curry': require('./curry'), + 'curryRight': require('./curryRight'), + 'debounce': require('./debounce'), + 'defer': require('./defer'), + 'delay': require('./delay'), + 'flip': require('./flip'), + 'memoize': require('./memoize'), + 'negate': require('./negate'), + 'once': require('./once'), + 'overArgs': require('./overArgs'), + 'partial': require('./partial'), + 'partialRight': require('./partialRight'), + 'rearg': require('./rearg'), + 'rest': require('./rest'), + 'spread': require('./spread'), + 'throttle': require('./throttle'), + 'unary': require('./unary'), + 'wrap': require('./wrap') +}; diff --git a/platforms/android/assets/www/node_modules/lodash/functions.js b/platforms/android/assets/www/node_modules/lodash/functions.js new file mode 100644 index 0000000..b50a197 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/functions.js @@ -0,0 +1,29 @@ +var baseFunctions = require('./_baseFunctions'), + keys = require('./keys'); + +/** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ +function functions(object) { + return object == null ? [] : baseFunctions(object, keys(object)); +} + +module.exports = functions; diff --git a/platforms/android/assets/www/node_modules/lodash/functionsIn.js b/platforms/android/assets/www/node_modules/lodash/functionsIn.js new file mode 100644 index 0000000..b48e5a6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/functionsIn.js @@ -0,0 +1,29 @@ +var baseFunctions = require('./_baseFunctions'), + keysIn = require('./keysIn'); + +/** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ +function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); +} + +module.exports = functionsIn; diff --git a/platforms/android/assets/www/node_modules/lodash/get.js b/platforms/android/assets/www/node_modules/lodash/get.js new file mode 100644 index 0000000..755fa05 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/get.js @@ -0,0 +1,32 @@ +var baseGet = require('./_baseGet'); + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; +} + +module.exports = get; diff --git a/platforms/android/assets/www/node_modules/lodash/groupBy.js b/platforms/android/assets/www/node_modules/lodash/groupBy.js new file mode 100644 index 0000000..728a6da --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/groupBy.js @@ -0,0 +1,38 @@ +var createAggregator = require('./_createAggregator'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of elements responsible for generating the key. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } + * + * // The `_.property` iteratee shorthand. + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ +var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } +}); + +module.exports = groupBy; diff --git a/platforms/android/assets/www/node_modules/lodash/gt.js b/platforms/android/assets/www/node_modules/lodash/gt.js new file mode 100644 index 0000000..ddaf5ea --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/gt.js @@ -0,0 +1,25 @@ +/** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ +function gt(value, other) { + return value > other; +} + +module.exports = gt; diff --git a/platforms/android/assets/www/node_modules/lodash/gte.js b/platforms/android/assets/www/node_modules/lodash/gte.js new file mode 100644 index 0000000..4a5ffb5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/gte.js @@ -0,0 +1,25 @@ +/** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ +function gte(value, other) { + return value >= other; +} + +module.exports = gte; diff --git a/platforms/android/assets/www/node_modules/lodash/has.js b/platforms/android/assets/www/node_modules/lodash/has.js new file mode 100644 index 0000000..d66d2de --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/has.js @@ -0,0 +1,34 @@ +var baseHas = require('./_baseHas'), + hasPath = require('./_hasPath'); + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return hasPath(object, path, baseHas); +} + +module.exports = has; diff --git a/platforms/android/assets/www/node_modules/lodash/hasIn.js b/platforms/android/assets/www/node_modules/lodash/hasIn.js new file mode 100644 index 0000000..7da6b7d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/hasIn.js @@ -0,0 +1,33 @@ +var baseHasIn = require('./_baseHasIn'), + hasPath = require('./_hasPath'); + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b.c'); + * // => true + * + * _.hasIn(object, ['a', 'b', 'c']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return hasPath(object, path, baseHasIn); +} + +module.exports = hasIn; diff --git a/platforms/android/assets/www/node_modules/lodash/head.js b/platforms/android/assets/www/node_modules/lodash/head.js new file mode 100644 index 0000000..30b47b0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/head.js @@ -0,0 +1,22 @@ +/** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ +function head(array) { + return array ? array[0] : undefined; +} + +module.exports = head; diff --git a/platforms/android/assets/www/node_modules/lodash/identity.js b/platforms/android/assets/www/node_modules/lodash/identity.js new file mode 100644 index 0000000..da7dea1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/identity.js @@ -0,0 +1,20 @@ +/** + * This method returns the first argument given to it. + * + * @static + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'user': 'fred' }; + * + * _.identity(object) === object; + * // => true + */ +function identity(value) { + return value; +} + +module.exports = identity; diff --git a/platforms/android/assets/www/node_modules/lodash/inRange.js b/platforms/android/assets/www/node_modules/lodash/inRange.js new file mode 100644 index 0000000..69c6110 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/inRange.js @@ -0,0 +1,52 @@ +var baseInRange = require('./_baseInRange'), + toNumber = require('./toNumber'); + +/** + * Checks if `n` is between `start` and up to but not including, `end`. If + * `end` is not specified it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. + * + * @static + * @memberOf _ + * @category Number + * @param {number} number The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + * + * _.inRange(-3, -2, -6); + * // => true + */ +function inRange(number, start, end) { + start = toNumber(start) || 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = toNumber(end) || 0; + } + number = toNumber(number); + return baseInRange(number, start, end); +} + +module.exports = inRange; diff --git a/platforms/android/assets/www/node_modules/lodash/includes.js b/platforms/android/assets/www/node_modules/lodash/includes.js new file mode 100644 index 0000000..01d6844 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/includes.js @@ -0,0 +1,51 @@ +var baseIndexOf = require('./_baseIndexOf'), + isArrayLike = require('./isArrayLike'), + isString = require('./isString'), + toInteger = require('./toInteger'), + values = require('./values'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Checks if `value` is in `collection`. If `collection` is a string it's checked + * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ +function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return isString(collection) + ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) + : (!!length && baseIndexOf(collection, value, fromIndex) > -1); +} + +module.exports = includes; diff --git a/platforms/android/assets/www/node_modules/lodash/index.js b/platforms/android/assets/www/node_modules/lodash/index.js new file mode 100644 index 0000000..5d063e2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/index.js @@ -0,0 +1 @@ +module.exports = require('./lodash'); \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/lodash/indexOf.js b/platforms/android/assets/www/node_modules/lodash/indexOf.js new file mode 100644 index 0000000..4474d0c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/indexOf.js @@ -0,0 +1,41 @@ +var baseIndexOf = require('./_baseIndexOf'), + toInteger = require('./toInteger'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ +function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + fromIndex = toInteger(fromIndex); + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return baseIndexOf(array, value, fromIndex); +} + +module.exports = indexOf; diff --git a/platforms/android/assets/www/node_modules/lodash/initial.js b/platforms/android/assets/www/node_modules/lodash/initial.js new file mode 100644 index 0000000..59b7a7d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/initial.js @@ -0,0 +1,20 @@ +var dropRight = require('./dropRight'); + +/** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ +function initial(array) { + return dropRight(array, 1); +} + +module.exports = initial; diff --git a/platforms/android/assets/www/node_modules/lodash/intersection.js b/platforms/android/assets/www/node_modules/lodash/intersection.js new file mode 100644 index 0000000..25495fe --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/intersection.js @@ -0,0 +1,29 @@ +var arrayMap = require('./_arrayMap'), + baseCastArrayLikeObject = require('./_baseCastArrayLikeObject'), + baseIntersection = require('./_baseIntersection'), + rest = require('./rest'); + +/** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. The order of result values is determined by the + * order they occur in the first array. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersection([2, 1], [4, 2], [1, 2]); + * // => [2] + */ +var intersection = rest(function(arrays) { + var mapped = arrayMap(arrays, baseCastArrayLikeObject); + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped) + : []; +}); + +module.exports = intersection; diff --git a/platforms/android/assets/www/node_modules/lodash/intersectionBy.js b/platforms/android/assets/www/node_modules/lodash/intersectionBy.js new file mode 100644 index 0000000..41bcec5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/intersectionBy.js @@ -0,0 +1,43 @@ +var arrayMap = require('./_arrayMap'), + baseCastArrayLikeObject = require('./_baseCastArrayLikeObject'), + baseIntersection = require('./_baseIntersection'), + baseIteratee = require('./_baseIteratee'), + last = require('./last'), + rest = require('./rest'); + +/** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which they're compared. Result values are chosen from the first array. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [2.1] + * + * // The `_.property` iteratee shorthand. + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ +var intersectionBy = rest(function(arrays) { + var iteratee = last(arrays), + mapped = arrayMap(arrays, baseCastArrayLikeObject); + + if (iteratee === last(mapped)) { + iteratee = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, baseIteratee(iteratee)) + : []; +}); + +module.exports = intersectionBy; diff --git a/platforms/android/assets/www/node_modules/lodash/intersectionWith.js b/platforms/android/assets/www/node_modules/lodash/intersectionWith.js new file mode 100644 index 0000000..c24c25a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/intersectionWith.js @@ -0,0 +1,41 @@ +var arrayMap = require('./_arrayMap'), + baseCastArrayLikeObject = require('./_baseCastArrayLikeObject'), + baseIntersection = require('./_baseIntersection'), + last = require('./last'), + rest = require('./rest'); + +/** + * This method is like `_.intersection` except that it accepts `comparator` + * which is invoked to compare elements of `arrays`. Result values are chosen + * from the first array. The comparator is invoked with two arguments: + * (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.intersectionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }] + */ +var intersectionWith = rest(function(arrays) { + var comparator = last(arrays), + mapped = arrayMap(arrays, baseCastArrayLikeObject); + + if (comparator === last(mapped)) { + comparator = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, undefined, comparator) + : []; +}); + +module.exports = intersectionWith; diff --git a/platforms/android/assets/www/node_modules/lodash/invert.js b/platforms/android/assets/www/node_modules/lodash/invert.js new file mode 100644 index 0000000..11628b1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/invert.js @@ -0,0 +1,26 @@ +var constant = require('./constant'), + createInverter = require('./_createInverter'), + identity = require('./identity'); + +/** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite property + * assignments of previous values. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ +var invert = createInverter(function(result, value, key) { + result[value] = key; +}, constant(identity)); + +module.exports = invert; diff --git a/platforms/android/assets/www/node_modules/lodash/invertBy.js b/platforms/android/assets/www/node_modules/lodash/invertBy.js new file mode 100644 index 0000000..513f62b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/invertBy.js @@ -0,0 +1,43 @@ +var baseIteratee = require('./_baseIteratee'), + createInverter = require('./_createInverter'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` through `iteratee`. + * The corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ +var invertBy = createInverter(function(result, value, key) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } +}, baseIteratee); + +module.exports = invertBy; diff --git a/platforms/android/assets/www/node_modules/lodash/invoke.js b/platforms/android/assets/www/node_modules/lodash/invoke.js new file mode 100644 index 0000000..f090a72 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/invoke.js @@ -0,0 +1,23 @@ +var baseInvoke = require('./_baseInvoke'), + rest = require('./rest'); + +/** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ +var invoke = rest(baseInvoke); + +module.exports = invoke; diff --git a/platforms/android/assets/www/node_modules/lodash/invokeMap.js b/platforms/android/assets/www/node_modules/lodash/invokeMap.js new file mode 100644 index 0000000..42c8fbe --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/invokeMap.js @@ -0,0 +1,43 @@ +var apply = require('./_apply'), + baseEach = require('./_baseEach'), + baseInvoke = require('./_baseInvoke'), + isArrayLike = require('./isArrayLike'), + isKey = require('./_isKey'), + rest = require('./rest'); + +/** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it's + * invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke each method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invokeMap([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ +var invokeMap = rest(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args); + }); + return result; +}); + +module.exports = invokeMap; diff --git a/platforms/android/assets/www/node_modules/lodash/isArguments.js b/platforms/android/assets/www/node_modules/lodash/isArguments.js new file mode 100644 index 0000000..73fbafe --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isArguments.js @@ -0,0 +1,43 @@ +var isArrayLikeObject = require('./isArrayLikeObject'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +module.exports = isArguments; diff --git a/platforms/android/assets/www/node_modules/lodash/isArray.js b/platforms/android/assets/www/node_modules/lodash/isArray.js new file mode 100644 index 0000000..fa9b055 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isArray.js @@ -0,0 +1,26 @@ +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @type {Function} + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +module.exports = isArray; diff --git a/platforms/android/assets/www/node_modules/lodash/isArrayBuffer.js b/platforms/android/assets/www/node_modules/lodash/isArrayBuffer.js new file mode 100644 index 0000000..a22a9ee --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isArrayBuffer.js @@ -0,0 +1,34 @@ +var isObjectLike = require('./isObjectLike'); + +var arrayBufferTag = '[object ArrayBuffer]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ +function isArrayBuffer(value) { + return isObjectLike(value) && objectToString.call(value) == arrayBufferTag; +} + +module.exports = isArrayBuffer; diff --git a/platforms/android/assets/www/node_modules/lodash/isArrayLike.js b/platforms/android/assets/www/node_modules/lodash/isArrayLike.js new file mode 100644 index 0000000..3e809f4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isArrayLike.js @@ -0,0 +1,33 @@ +var getLength = require('./_getLength'), + isFunction = require('./isFunction'), + isLength = require('./isLength'); + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(getLength(value)) && !isFunction(value); +} + +module.exports = isArrayLike; diff --git a/platforms/android/assets/www/node_modules/lodash/isArrayLikeObject.js b/platforms/android/assets/www/node_modules/lodash/isArrayLikeObject.js new file mode 100644 index 0000000..0b8b2ca --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isArrayLikeObject.js @@ -0,0 +1,31 @@ +var isArrayLike = require('./isArrayLike'), + isObjectLike = require('./isObjectLike'); + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +module.exports = isArrayLikeObject; diff --git a/platforms/android/assets/www/node_modules/lodash/isBoolean.js b/platforms/android/assets/www/node_modules/lodash/isBoolean.js new file mode 100644 index 0000000..53ec5d6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isBoolean.js @@ -0,0 +1,36 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ +function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && objectToString.call(value) == boolTag); +} + +module.exports = isBoolean; diff --git a/platforms/android/assets/www/node_modules/lodash/isBuffer.js b/platforms/android/assets/www/node_modules/lodash/isBuffer.js new file mode 100644 index 0000000..cee6b22 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isBuffer.js @@ -0,0 +1,48 @@ +var constant = require('./constant'), + root = require('./_root'); + +/** Used to determine if values are of the language type `Object`. */ +var objectTypes = { + 'function': true, + 'object': true +}; + +/** Detect free variable `exports`. */ +var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; + +/** Detect free variable `module`. */ +var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = (freeModule && freeModule.exports === freeExports) + ? freeExports + : undefined; + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined; + +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = !Buffer ? constant(false) : function(value) { + return value instanceof Buffer; +}; + +module.exports = isBuffer; diff --git a/platforms/android/assets/www/node_modules/lodash/isDate.js b/platforms/android/assets/www/node_modules/lodash/isDate.js new file mode 100644 index 0000000..6e3611a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isDate.js @@ -0,0 +1,35 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var dateTag = '[object Date]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ +function isDate(value) { + return isObjectLike(value) && objectToString.call(value) == dateTag; +} + +module.exports = isDate; diff --git a/platforms/android/assets/www/node_modules/lodash/isElement.js b/platforms/android/assets/www/node_modules/lodash/isElement.js new file mode 100644 index 0000000..447d6bc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isElement.js @@ -0,0 +1,24 @@ +var isObjectLike = require('./isObjectLike'), + isPlainObject = require('./isPlainObject'); + +/** + * Checks if `value` is likely a DOM element. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ +function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); +} + +module.exports = isElement; diff --git a/platforms/android/assets/www/node_modules/lodash/isEmpty.js b/platforms/android/assets/www/node_modules/lodash/isEmpty.js new file mode 100644 index 0000000..f81838d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isEmpty.js @@ -0,0 +1,54 @@ +var isArguments = require('./isArguments'), + isArray = require('./isArray'), + isArrayLike = require('./isArrayLike'), + isFunction = require('./isFunction'), + isString = require('./isString'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Checks if `value` is an empty collection or object. A value is considered + * empty if it's an `arguments` object, array, string, or jQuery-like collection + * with a length of `0` or has no own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ +function isEmpty(value) { + if (isArrayLike(value) && + (isArray(value) || isString(value) || + isFunction(value.splice) || isArguments(value))) { + return !value.length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; +} + +module.exports = isEmpty; diff --git a/platforms/android/assets/www/node_modules/lodash/isEqual.js b/platforms/android/assets/www/node_modules/lodash/isEqual.js new file mode 100644 index 0000000..43a3a2b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isEqual.js @@ -0,0 +1,34 @@ +var baseIsEqual = require('./_baseIsEqual'); + +/** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are **not** supported. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ +function isEqual(value, other) { + return baseIsEqual(value, other); +} + +module.exports = isEqual; diff --git a/platforms/android/assets/www/node_modules/lodash/isEqualWith.js b/platforms/android/assets/www/node_modules/lodash/isEqualWith.js new file mode 100644 index 0000000..4643a35 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isEqualWith.js @@ -0,0 +1,40 @@ +var baseIsEqual = require('./_baseIsEqual'); + +/** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ +function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; +} + +module.exports = isEqualWith; diff --git a/platforms/android/assets/www/node_modules/lodash/isError.js b/platforms/android/assets/www/node_modules/lodash/isError.js new file mode 100644 index 0000000..6065453 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isError.js @@ -0,0 +1,40 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var errorTag = '[object Error]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ +function isError(value) { + if (!isObjectLike(value)) { + return false; + } + return (objectToString.call(value) == errorTag) || + (typeof value.message == 'string' && typeof value.name == 'string'); +} + +module.exports = isError; diff --git a/platforms/android/assets/www/node_modules/lodash/isFinite.js b/platforms/android/assets/www/node_modules/lodash/isFinite.js new file mode 100644 index 0000000..44be4bc --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isFinite.js @@ -0,0 +1,34 @@ +var root = require('./_root'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeIsFinite = root.isFinite; + +/** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MAX_VALUE); + * // => true + * + * _.isFinite(3.14); + * // => true + * + * _.isFinite(Infinity); + * // => false + */ +function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); +} + +module.exports = isFinite; diff --git a/platforms/android/assets/www/node_modules/lodash/isFunction.js b/platforms/android/assets/www/node_modules/lodash/isFunction.js new file mode 100644 index 0000000..fd8c4ad --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isFunction.js @@ -0,0 +1,40 @@ +var isObject = require('./isObject'); + +/** `Object#toString` result references. */ +var funcTag = '[object Function]', + genTag = '[object GeneratorFunction]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8 which returns 'object' for typed array and weak map constructors, + // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +module.exports = isFunction; diff --git a/platforms/android/assets/www/node_modules/lodash/isInteger.js b/platforms/android/assets/www/node_modules/lodash/isInteger.js new file mode 100644 index 0000000..1bfcc65 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isInteger.js @@ -0,0 +1,31 @@ +var toInteger = require('./toInteger'); + +/** + * Checks if `value` is an integer. + * + * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ +function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); +} + +module.exports = isInteger; diff --git a/platforms/android/assets/www/node_modules/lodash/isLength.js b/platforms/android/assets/www/node_modules/lodash/isLength.js new file mode 100644 index 0000000..b095123 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isLength.js @@ -0,0 +1,33 @@ +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +module.exports = isLength; diff --git a/platforms/android/assets/www/node_modules/lodash/isMap.js b/platforms/android/assets/www/node_modules/lodash/isMap.js new file mode 100644 index 0000000..bc92def --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isMap.js @@ -0,0 +1,27 @@ +var getTag = require('./_getTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var mapTag = '[object Map]'; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +function isMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; +} + +module.exports = isMap; diff --git a/platforms/android/assets/www/node_modules/lodash/isMatch.js b/platforms/android/assets/www/node_modules/lodash/isMatch.js new file mode 100644 index 0000000..faf0898 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isMatch.js @@ -0,0 +1,31 @@ +var baseIsMatch = require('./_baseIsMatch'), + getMatchData = require('./_getMatchData'); + +/** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. This method is + * equivalent to a `_.matches` function when `source` is partially applied. + * + * **Note:** This method supports comparing the same values as `_.isEqual`. + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + */ +function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); +} + +module.exports = isMatch; diff --git a/platforms/android/assets/www/node_modules/lodash/isMatchWith.js b/platforms/android/assets/www/node_modules/lodash/isMatchWith.js new file mode 100644 index 0000000..2460eb3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isMatchWith.js @@ -0,0 +1,40 @@ +var baseIsMatch = require('./_baseIsMatch'), + getMatchData = require('./_getMatchData'); + +/** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ +function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseIsMatch(object, source, getMatchData(source), customizer); +} + +module.exports = isMatchWith; diff --git a/platforms/android/assets/www/node_modules/lodash/isNaN.js b/platforms/android/assets/www/node_modules/lodash/isNaN.js new file mode 100644 index 0000000..5b757b1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isNaN.js @@ -0,0 +1,34 @@ +var isNumber = require('./isNumber'); + +/** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ +function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE. + return isNumber(value) && value != +value; +} + +module.exports = isNaN; diff --git a/platforms/android/assets/www/node_modules/lodash/isNative.js b/platforms/android/assets/www/node_modules/lodash/isNative.js new file mode 100644 index 0000000..616a832 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isNative.js @@ -0,0 +1,53 @@ +var isFunction = require('./isFunction'), + isHostObject = require('./_isHostObject'), + isObjectLike = require('./isObjectLike'); + +/** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to detect host constructors (Safari > 5). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = Function.prototype.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ +function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(funcToString.call(value)); + } + return isObjectLike(value) && + (isHostObject(value) ? reIsNative : reIsHostCtor).test(value); +} + +module.exports = isNative; diff --git a/platforms/android/assets/www/node_modules/lodash/isNil.js b/platforms/android/assets/www/node_modules/lodash/isNil.js new file mode 100644 index 0000000..c4197fb --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isNil.js @@ -0,0 +1,24 @@ +/** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ +function isNil(value) { + return value == null; +} + +module.exports = isNil; diff --git a/platforms/android/assets/www/node_modules/lodash/isNull.js b/platforms/android/assets/www/node_modules/lodash/isNull.js new file mode 100644 index 0000000..ec66c4d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isNull.js @@ -0,0 +1,21 @@ +/** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ +function isNull(value) { + return value === null; +} + +module.exports = isNull; diff --git a/platforms/android/assets/www/node_modules/lodash/isNumber.js b/platforms/android/assets/www/node_modules/lodash/isNumber.js new file mode 100644 index 0000000..0c8fb9a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isNumber.js @@ -0,0 +1,45 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var numberTag = '[object Number]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ +function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && objectToString.call(value) == numberTag); +} + +module.exports = isNumber; diff --git a/platforms/android/assets/www/node_modules/lodash/isObject.js b/platforms/android/assets/www/node_modules/lodash/isObject.js new file mode 100644 index 0000000..41993db --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isObject.js @@ -0,0 +1,29 @@ +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +module.exports = isObject; diff --git a/platforms/android/assets/www/node_modules/lodash/isObjectLike.js b/platforms/android/assets/www/node_modules/lodash/isObjectLike.js new file mode 100644 index 0000000..240167a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isObjectLike.js @@ -0,0 +1,28 @@ +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +module.exports = isObjectLike; diff --git a/platforms/android/assets/www/node_modules/lodash/isPlainObject.js b/platforms/android/assets/www/node_modules/lodash/isPlainObject.js new file mode 100644 index 0000000..5491848 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isPlainObject.js @@ -0,0 +1,66 @@ +var isHostObject = require('./_isHostObject'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = Function.prototype.toString; + +/** Used to infer the `Object` constructor. */ +var objectCtorString = funcToString.call(Object); + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var getPrototypeOf = Object.getPrototypeOf; + +/** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ +function isPlainObject(value) { + if (!isObjectLike(value) || + objectToString.call(value) != objectTag || isHostObject(value)) { + return false; + } + var proto = getPrototypeOf(value); + if (proto === null) { + return true; + } + var Ctor = proto.constructor; + return (typeof Ctor == 'function' && + Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); +} + +module.exports = isPlainObject; diff --git a/platforms/android/assets/www/node_modules/lodash/isRegExp.js b/platforms/android/assets/www/node_modules/lodash/isRegExp.js new file mode 100644 index 0000000..e127e5a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isRegExp.js @@ -0,0 +1,35 @@ +var isObject = require('./isObject'); + +/** `Object#toString` result references. */ +var regexpTag = '[object RegExp]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ +function isRegExp(value) { + return isObject(value) && objectToString.call(value) == regexpTag; +} + +module.exports = isRegExp; diff --git a/platforms/android/assets/www/node_modules/lodash/isSafeInteger.js b/platforms/android/assets/www/node_modules/lodash/isSafeInteger.js new file mode 100644 index 0000000..f601243 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isSafeInteger.js @@ -0,0 +1,35 @@ +var isInteger = require('./isInteger'); + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ +function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; +} + +module.exports = isSafeInteger; diff --git a/platforms/android/assets/www/node_modules/lodash/isSet.js b/platforms/android/assets/www/node_modules/lodash/isSet.js new file mode 100644 index 0000000..e1d50be --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isSet.js @@ -0,0 +1,27 @@ +var getTag = require('./_getTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var setTag = '[object Set]'; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +function isSet(value) { + return isObjectLike(value) && getTag(value) == setTag; +} + +module.exports = isSet; diff --git a/platforms/android/assets/www/node_modules/lodash/isString.js b/platforms/android/assets/www/node_modules/lodash/isString.js new file mode 100644 index 0000000..5ed392e --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isString.js @@ -0,0 +1,37 @@ +var isArray = require('./isArray'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); +} + +module.exports = isString; diff --git a/platforms/android/assets/www/node_modules/lodash/isSymbol.js b/platforms/android/assets/www/node_modules/lodash/isSymbol.js new file mode 100644 index 0000000..5e11a00 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isSymbol.js @@ -0,0 +1,36 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +module.exports = isSymbol; diff --git a/platforms/android/assets/www/node_modules/lodash/isTypedArray.js b/platforms/android/assets/www/node_modules/lodash/isTypedArray.js new file mode 100644 index 0000000..1283322 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isTypedArray.js @@ -0,0 +1,75 @@ +var isLength = require('./isLength'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dateTag] = typedArrayTags[errorTag] = +typedArrayTags[funcTag] = typedArrayTags[mapTag] = +typedArrayTags[numberTag] = typedArrayTags[objectTag] = +typedArrayTags[regexpTag] = typedArrayTags[setTag] = +typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ +function isTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; +} + +module.exports = isTypedArray; diff --git a/platforms/android/assets/www/node_modules/lodash/isUndefined.js b/platforms/android/assets/www/node_modules/lodash/isUndefined.js new file mode 100644 index 0000000..d64e560 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isUndefined.js @@ -0,0 +1,21 @@ +/** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +module.exports = isUndefined; diff --git a/platforms/android/assets/www/node_modules/lodash/isWeakMap.js b/platforms/android/assets/www/node_modules/lodash/isWeakMap.js new file mode 100644 index 0000000..d934a9f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isWeakMap.js @@ -0,0 +1,27 @@ +var getTag = require('./_getTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var weakMapTag = '[object WeakMap]'; + +/** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ +function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; +} + +module.exports = isWeakMap; diff --git a/platforms/android/assets/www/node_modules/lodash/isWeakSet.js b/platforms/android/assets/www/node_modules/lodash/isWeakSet.js new file mode 100644 index 0000000..40674f4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/isWeakSet.js @@ -0,0 +1,35 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var weakSetTag = '[object WeakSet]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ +function isWeakSet(value) { + return isObjectLike(value) && objectToString.call(value) == weakSetTag; +} + +module.exports = isWeakSet; diff --git a/platforms/android/assets/www/node_modules/lodash/iteratee.js b/platforms/android/assets/www/node_modules/lodash/iteratee.js new file mode 100644 index 0000000..e9d2f8a --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/iteratee.js @@ -0,0 +1,38 @@ +var baseClone = require('./_baseClone'), + baseIteratee = require('./_baseIteratee'); + +/** + * Creates a function that invokes `func` with the arguments of the created + * function. If `func` is a property name the created callback returns the + * property value for a given element. If `func` is an object the created + * callback returns `true` for elements that contain the equivalent object + * properties, otherwise it returns `false`. + * + * @static + * @memberOf _ + * @category Util + * @param {*} [func=_.identity] The value to convert to a callback. + * @returns {Function} Returns the callback. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // Create custom iteratee shorthands. + * _.iteratee = _.wrap(_.iteratee, function(callback, func) { + * var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func); + * return !p ? callback(func) : function(object) { + * return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]); + * }; + * }); + * + * _.filter(users, 'age > 36'); + * // => [{ 'user': 'fred', 'age': 40 }] + */ +function iteratee(func) { + return baseIteratee(typeof func == 'function' ? func : baseClone(func, true)); +} + +module.exports = iteratee; diff --git a/platforms/android/assets/www/node_modules/lodash/join.js b/platforms/android/assets/www/node_modules/lodash/join.js new file mode 100644 index 0000000..79d308d --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/join.js @@ -0,0 +1,25 @@ +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeJoin = arrayProto.join; + +/** + * Converts all elements in `array` into a string separated by `separator`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to convert. + * @param {string} [separator=','] The element separator. + * @returns {string} Returns the joined string. + * @example + * + * _.join(['a', 'b', 'c'], '~'); + * // => 'a~b~c' + */ +function join(array, separator) { + return array ? nativeJoin.call(array, separator) : ''; +} + +module.exports = join; diff --git a/platforms/android/assets/www/node_modules/lodash/kebabCase.js b/platforms/android/assets/www/node_modules/lodash/kebabCase.js new file mode 100644 index 0000000..f29124f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/kebabCase.js @@ -0,0 +1,26 @@ +var createCompounder = require('./_createCompounder'); + +/** + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' + */ +var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); +}); + +module.exports = kebabCase; diff --git a/platforms/android/assets/www/node_modules/lodash/keyBy.js b/platforms/android/assets/www/node_modules/lodash/keyBy.js new file mode 100644 index 0000000..febc86b --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/keyBy.js @@ -0,0 +1,34 @@ +var createAggregator = require('./_createAggregator'); + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var array = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.keyBy(array, function(o) { + * return String.fromCharCode(o.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.keyBy(array, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + */ +var keyBy = createAggregator(function(result, value, key) { + result[key] = value; +}); + +module.exports = keyBy; diff --git a/platforms/android/assets/www/node_modules/lodash/keys.js b/platforms/android/assets/www/node_modules/lodash/keys.js new file mode 100644 index 0000000..eac239f --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/keys.js @@ -0,0 +1,55 @@ +var baseHas = require('./_baseHas'), + baseKeys = require('./_baseKeys'), + indexKeys = require('./_indexKeys'), + isArrayLike = require('./isArrayLike'), + isIndex = require('./_isIndex'), + isPrototype = require('./_isPrototype'); + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + var isProto = isPrototype(object); + if (!(isProto || isArrayLike(object))) { + return baseKeys(object); + } + var indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + for (var key in object) { + if (baseHas(object, key) && + !(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(isProto && key == 'constructor')) { + result.push(key); + } + } + return result; +} + +module.exports = keys; diff --git a/platforms/android/assets/www/node_modules/lodash/keysIn.js b/platforms/android/assets/www/node_modules/lodash/keysIn.js new file mode 100644 index 0000000..e327b87 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/keysIn.js @@ -0,0 +1,54 @@ +var baseKeysIn = require('./_baseKeysIn'), + indexKeys = require('./_indexKeys'), + isIndex = require('./_isIndex'), + isPrototype = require('./_isPrototype'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + var index = -1, + isProto = isPrototype(object), + props = baseKeysIn(object), + propsLength = props.length, + indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + while (++index < propsLength) { + var key = props[index]; + if (!(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} + +module.exports = keysIn; diff --git a/platforms/android/assets/www/node_modules/lodash/lang.js b/platforms/android/assets/www/node_modules/lodash/lang.js new file mode 100644 index 0000000..665f5c6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/lang.js @@ -0,0 +1,56 @@ +module.exports = { + 'castArray': require('./castArray'), + 'clone': require('./clone'), + 'cloneDeep': require('./cloneDeep'), + 'cloneDeepWith': require('./cloneDeepWith'), + 'cloneWith': require('./cloneWith'), + 'eq': require('./eq'), + 'gt': require('./gt'), + 'gte': require('./gte'), + 'isArguments': require('./isArguments'), + 'isArray': require('./isArray'), + 'isArrayBuffer': require('./isArrayBuffer'), + 'isArrayLike': require('./isArrayLike'), + 'isArrayLikeObject': require('./isArrayLikeObject'), + 'isBoolean': require('./isBoolean'), + 'isBuffer': require('./isBuffer'), + 'isDate': require('./isDate'), + 'isElement': require('./isElement'), + 'isEmpty': require('./isEmpty'), + 'isEqual': require('./isEqual'), + 'isEqualWith': require('./isEqualWith'), + 'isError': require('./isError'), + 'isFinite': require('./isFinite'), + 'isFunction': require('./isFunction'), + 'isInteger': require('./isInteger'), + 'isLength': require('./isLength'), + 'isMap': require('./isMap'), + 'isMatch': require('./isMatch'), + 'isMatchWith': require('./isMatchWith'), + 'isNaN': require('./isNaN'), + 'isNative': require('./isNative'), + 'isNil': require('./isNil'), + 'isNull': require('./isNull'), + 'isNumber': require('./isNumber'), + 'isObject': require('./isObject'), + 'isObjectLike': require('./isObjectLike'), + 'isPlainObject': require('./isPlainObject'), + 'isRegExp': require('./isRegExp'), + 'isSafeInteger': require('./isSafeInteger'), + 'isSet': require('./isSet'), + 'isString': require('./isString'), + 'isSymbol': require('./isSymbol'), + 'isTypedArray': require('./isTypedArray'), + 'isUndefined': require('./isUndefined'), + 'isWeakMap': require('./isWeakMap'), + 'isWeakSet': require('./isWeakSet'), + 'lt': require('./lt'), + 'lte': require('./lte'), + 'toArray': require('./toArray'), + 'toInteger': require('./toInteger'), + 'toLength': require('./toLength'), + 'toNumber': require('./toNumber'), + 'toPlainObject': require('./toPlainObject'), + 'toSafeInteger': require('./toSafeInteger'), + 'toString': require('./toString') +}; diff --git a/platforms/android/assets/www/node_modules/lodash/last.js b/platforms/android/assets/www/node_modules/lodash/last.js new file mode 100644 index 0000000..299af31 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/last.js @@ -0,0 +1,19 @@ +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; +} + +module.exports = last; diff --git a/platforms/android/assets/www/node_modules/lodash/lastIndexOf.js b/platforms/android/assets/www/node_modules/lodash/lastIndexOf.js new file mode 100644 index 0000000..1eb2f28 --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/lastIndexOf.js @@ -0,0 +1,49 @@ +var indexOfNaN = require('./_indexOfNaN'), + toInteger = require('./toInteger'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // Search from the `fromIndex`. + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + */ +function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +module.exports = lastIndexOf; diff --git a/platforms/android/assets/www/node_modules/lodash/lodash.js b/platforms/android/assets/www/node_modules/lodash/lodash.js new file mode 100644 index 0000000..0fc4b1c --- /dev/null +++ b/platforms/android/assets/www/node_modules/lodash/lodash.js @@ -0,0 +1,15073 @@ +/** + * @license + * lodash 4.6.1 (Custom Build) + * Build: `lodash -d -o ./foo/lodash.js` + * Copyright 2012-2016 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '4.6.1'; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64, + ARY_FLAG = 128, + REARG_FLAG = 256, + FLIP_FLAG = 512; + + /** Used to compose bitmasks for comparison styles. */ + var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + + /** Used as default options for `_.truncate`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect hot functions by number of calls within a span of milliseconds. */ + var HOT_COUNT = 150, + HOT_SPAN = 16; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2, + LAZY_WHILE_FLAG = 3; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]', + weakSetTag = '[object WeakSet]'; + + var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, + reUnescapedHtml = /[&<>"'`]/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g; + + /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, + reHasRegExpChar = RegExp(reRegExpChar.source); + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g, + reTrimStart = /^\s+/, + reTrimEnd = /\s+$/; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect hexadecimal string values. */ + var reHasHexPrefix = /^0x/i; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; + + /** Used to detect host constructors (Safari > 5). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect octal string values. */ + var reIsOctal = /^0o[0-7]+$/i; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ + var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; + + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsDingbatRange = '\\u2700-\\u27bf', + rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', + rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', + rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', + rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d', + rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', + rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', + rsVarRange = '\\ufe0e\\ufe0f', + rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange; + + /** Used to compose unicode capture groups. */ + var rsAstral = '[' + rsAstralRange + ']', + rsBreak = '[' + rsBreakRange + ']', + rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', + rsDigits = '\\d+', + rsDingbat = '[' + rsDingbatRange + ']', + rsLower = '[' + rsLowerRange + ']', + rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsUpper = '[' + rsUpperRange + ']', + rsZWJ = '\\u200d'; + + /** Used to compose unicode regexes. */ + var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')', + rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')', + reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ + var reComboMark = RegExp(rsCombo, 'g'); + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); + + /** Used to match non-compound words composed of alphanumeric characters. */ + var reBasicWord = /[a-zA-Z0-9]+/g; + + /** Used to match complex or compound words. */ + var reComplexWord = RegExp([ + rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', + rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')', + rsUpper + '?' + rsLowerMisc + '+', + rsUpper + '+', + rsDigits, + rsEmoji + ].join('|'), 'g'); + + /** Used to detect strings that need a more robust regexp to match words. */ + var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; + + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'Buffer', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', + 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_', + 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' + ]; + + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dateTag] = typedArrayTags[errorTag] = + typedArrayTags[funcTag] = typedArrayTags[mapTag] = + typedArrayTags[numberTag] = typedArrayTags[objectTag] = + typedArrayTags[regexpTag] = typedArrayTags[setTag] = + typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = + cloneableTags[dateTag] = cloneableTags[float32Tag] = + cloneableTags[float64Tag] = cloneableTags[int8Tag] = + cloneableTags[int16Tag] = cloneableTags[int32Tag] = + cloneableTags[mapTag] = cloneableTags[numberTag] = + cloneableTags[objectTag] = cloneableTags[regexpTag] = + cloneableTags[setTag] = cloneableTags[stringTag] = + cloneableTags[symbolTag] = cloneableTags[uint8Tag] = + cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = + cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Used to map latin-1 supplementary letters to basic latin letters. */ + var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' + }; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' + }; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Built-in method references without a dependency on `root`. */ + var freeParseFloat = parseFloat, + freeParseInt = parseInt; + + /** Detect free variable `exports`. */ + var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; + + /** Detect free variable `module`. */ + var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = (freeModule && freeModule.exports === freeExports) + ? freeExports + : undefined; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); + + /** Detect free variable `self`. */ + var freeSelf = checkGlobal(objectTypes[typeof self] && self); + + /** Detect free variable `window`. */ + var freeWindow = checkGlobal(objectTypes[typeof window] && window); + + /** Detect `this` as the global object. */ + var thisGlobal = checkGlobal(objectTypes[typeof this] && this); + + /** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || + ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || + freeSelf || thisGlobal || Function('return this')(); + + /*--------------------------------------------------------------------------*/ + + /** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ + function addMapEntry(map, pair) { + // Don't return `Map#set` because it doesn't return the map instance in IE 11. + map.set(pair[0], pair[1]); + return map; + } + + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + set.add(value); + return set; + } + + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + var length = args.length; + switch (length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); + } + return accumulator; + } + + /** + * Creates a new array concatenating `array` with `other`. + * + * @private + * @param {Array} array The first array to concatenate. + * @param {Array} other The second array to concatenate. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} array The array to search. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludes(array, value) { + return !!array.length && baseIndexOf(array, value, 0) > -1; + } + + /** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to search. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initAccum) { + var length = array.length; + if (initAccum && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? current === current + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; + } + + /** + * The base implementation of methods like `_.find` and `_.findKey`, without + * support for iteratee shorthands, which iterates over `collection` using + * `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); + } + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * This function is like `baseIndexOf` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @param {Function} comparator The comparator invoked per element. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOfWith(array, value, fromIndex, comparator) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (comparator(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * The base implementation of `_.sum` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(array, iteratee) { + var result, + index = -1, + length = array.length; + + while (++index < length) { + var current = iteratee(array[index]); + if (current !== undefined) { + result = result === undefined ? current : (result + current); + } + } + return result; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array + * of key-value pairs for `object` corresponding to the property names of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the new array of key-value pairs. + */ + function baseToPairs(object, props) { + return arrayMap(props, function(key) { + return [key, object[key]]; + }); + } + + /** + * The base implementation of `_.unary` without support for storing wrapper metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new function. + */ + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); + } + + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Checks if `value` is a global object. + * + * @private + * @param {*} value The value to check. + * @returns {null|Object} Returns `value` if it's a global object, else `null`. + */ + function checkGlobal(value) { + return (value && value.Object === Object) ? value : null; + } + + /** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function compareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; + } + + /** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Gets the number of `placeholder` occurrences in `array`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} placeholder The placeholder to search for. + * @returns {number} Returns the placeholder count. + */ + function countHolders(array, placeholder) { + var length = array.length, + result = 0; + + while (length--) { + if (array[length] === placeholder) { + result++; + } + } + return result; + } + + /** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + function deburrLetter(letter) { + return deburredLetters[letter]; + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * + * @private + * @param {Array} array The array to search. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched `NaN`, else `-1`. + */ + function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 0 : -1); + + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; + } + } + return -1; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; + } + + /** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ + function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; + } + + /** + * Converts `map` to an array. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the converted array. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value === placeholder || value === PLACEHOLDER) { + array[index] = PLACEHOLDER; + result[resIndex++] = index; + } + } + return result; + } + + /** + * Converts `set` to an array. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the converted array. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ + function stringSize(string) { + if (!(string && reHasComplexSymbol.test(string))) { + return string.length; + } + var result = reComplexSymbol.lastIndex = 0; + while (reComplexSymbol.test(string)) { + result++; + } + return result; + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return string.match(reComplexSymbol); + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new pristine `lodash` function using the `context` object. + * + * @static + * @memberOf _ + * @category Util + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // Use `context` to mock `Date#getTime` use in `_.now`. + * var mock = _.runInContext({ + * 'Date': function() { + * return { 'getTime': getTimeMock }; + * } + * }); + * + * // Create a suped-up `defer` in Node.js. + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + function runInContext(context) { + context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root; + + /** Built-in constructor references. */ + var Date = context.Date, + Error = context.Error, + Math = context.Math, + RegExp = context.RegExp, + TypeError = context.TypeError; + + /** Used for built-in method references. */ + var arrayProto = context.Array.prototype, + objectProto = context.Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = context.Function.prototype.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + + /** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? context.Buffer : undefined, + Reflect = context.Reflect, + Symbol = context.Symbol, + Uint8Array = context.Uint8Array, + clearTimeout = context.clearTimeout, + enumerate = Reflect ? Reflect.enumerate : undefined, + getPrototypeOf = Object.getPrototypeOf, + getOwnPropertySymbols = Object.getOwnPropertySymbols, + iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined, + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + setTimeout = context.setTimeout, + splice = arrayProto.splice; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeFloor = Math.floor, + nativeIsFinite = context.isFinite, + nativeJoin = arrayProto.join, + nativeKeys = Object.keys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeParseInt = context.parseInt, + nativeRandom = Math.random, + nativeReverse = arrayProto.reverse; + + /* Built-in method references that are verified to be native. */ + var Map = getNative(context, 'Map'), + Set = getNative(context, 'Set'), + WeakMap = getNative(context, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ + var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /** Used to detect maps, sets, and weakmaps. */ + var mapCtorString = Map ? funcToString.call(Map) : '', + setCtorString = Set ? funcToString.call(Set) : '', + weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : ''; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit method + * chaining. Methods that operate on and return arrays, collections, and + * functions can be chained together. Methods that retrieve a single value or + * may return a primitive value will automatically end the chain sequence and + * return the unwrapped value. Otherwise, the value must be unwrapped with + * `_#value`. + * + * Explicit chaining, which must be unwrapped with `_#value` in all cases, + * may be enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization to merge iteratee calls; this avoids the creation + * of intermediate arrays and can greatly reduce the number of iteratee executions. + * Sections of a chain sequence qualify for shortcut fusion if the section is + * applied to an array of at least two hundred elements and any iteratees + * accept only one argument. The heuristic for whether a section qualifies + * for shortcut fusion is subject to change. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatten`, `flattenDeep`, `flattenDepth`, `flip`, `flow`, `flowRight`, + * `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`, `intersection`, + * `intersectionBy`, `intersectionWith`, `invert`, `invertBy`, `invokeMap`, + * `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, + * `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`, + * `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, + * `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`, + * `partition`, `pick`, `pickBy`, `plant`, `property`, `propertyOf`, `pull`, + * `pullAll`, `pullAllBy`, `pullAllWith`, `pullAt`, `push`, `range`, + * `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`, + * `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, + * `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, + * `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, + * `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `update`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, + * `zipObjectDeep`, and `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `each`, `eachRight`, + * `endsWith`, `eq`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `first`, `floor`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`, `includes`, + * `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`, `isArrayBuffer`, + * `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`, `isDate`, + * `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`, `isFinite`, + * `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`, `isMatchWith`, + * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`, + * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isSet`, `isString`, + * `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, + * `maxBy`, `mean`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toInteger`, `toJSON`, `toLength`, `toLower`, + * `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, `trimEnd`, + * `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, `upperFirst`, + * `value`, and `words` + * + * @name _ + * @constructor + * @category Seq + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2, 3]); + * + * // Returns an unwrapped value. + * wrapped.reduce(_.add); + * // => 6 + * + * // Returns a wrapped value. + * var squares = wrapped.map(square); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The function whose prototype all chaining wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + */ + function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined; + } + + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB). Change the following template settings to use + * alternative delimiters. + * + * @static + * @memberOf _ + * @type {Object} + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type {string} + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type {Object} + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type {Function} + */ + '_': lodash + } + }; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @constructor + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = MAX_ARRAY_LENGTH; + this.__views__ = []; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = copyArray(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = copyArray(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = copyArray(this.__views__); + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || + (arrLength == length && takeCount == length)) { + return baseWrapperValue(array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an hash object. + * + * @private + * @constructor + * @returns {Object} Returns the new hash object. + */ + function Hash() {} + + /** + * Removes `key` and its value from the hash. + * + * @private + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(hash, key) { + return hashHas(hash, key) && delete hash[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @param {Object} hash The hash to query. + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(hash, key) { + if (nativeCreate) { + var result = hash[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(hash, key) ? hash[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @param {Object} hash The hash to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(hash, key) { + return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + */ + function hashSet(hash, key, value) { + hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function MapCache(values) { + var index = -1, + length = values ? values.length : 0; + + this.clear(); + while (++index < length) { + var entry = values[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapClear() { + this.__data__ = { + 'hash': new Hash, + 'map': Map ? new Map : [], + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapDelete(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashDelete(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map['delete'](key) : assocDelete(data.map, key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapGet(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashGet(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map.get(key) : assocGet(data.map, key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapHas(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashHas(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map.has(key) : assocHas(data.map, key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache object. + */ + function mapSet(key, value) { + var data = this.__data__; + if (isKeyable(key)) { + hashSet(typeof key == 'string' ? data.string : data.hash, key, value); + } else if (Map) { + data.map.set(key, value); + } else { + assocSet(data.map, key, value); + } + return this; + } + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates a set cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var index = -1, + length = values ? values.length : 0; + + this.__data__ = new MapCache; + while (++index < length) { + this.push(values[index]); + } + } + + /** + * Checks if `value` is in `cache`. + * + * @private + * @param {Object} cache The set cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ + function cacheHas(cache, value) { + var map = cache.__data__; + if (isKeyable(value)) { + var data = map.__data__, + hash = typeof value == 'string' ? data.string : data.hash; + + return hash[value] === HASH_UNDEFINED; + } + return map.has(value); + } + + /** + * Adds `value` to the set cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ + function cachePush(value) { + var map = this.__data__; + if (isKeyable(value)) { + var data = map.__data__, + hash = typeof value == 'string' ? data.string : data.hash; + + hash[value] = HASH_UNDEFINED; + } + else { + map.set(value, HASH_UNDEFINED); + } + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function Stack(values) { + var index = -1, + length = values ? values.length : 0; + + this.clear(); + while (++index < length) { + var entry = values[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = { 'array': [], 'map': null }; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + var data = this.__data__, + array = data.array; + + return array ? assocDelete(array, key) : data.map['delete'](key); + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + var data = this.__data__, + array = data.array; + + return array ? assocGet(array, key) : data.map.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + var data = this.__data__, + array = data.array; + + return array ? assocHas(array, key) : data.map.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache object. + */ + function stackSet(key, value) { + var data = this.__data__, + array = data.array; + + if (array) { + if (array.length < (LARGE_ARRAY_SIZE - 1)) { + assocSet(array, key, value); + } else { + data.array = null; + data.map = new MapCache(array); + } + } + var map = data.map; + if (map) { + map.set(key, value); + } + return this; + } + + /*------------------------------------------------------------------------*/ + + /** + * Removes `key` and its value from the associative array. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function assocDelete(array, key) { + var index = assocIndexOf(array, key); + if (index < 0) { + return false; + } + var lastIndex = array.length - 1; + if (index == lastIndex) { + array.pop(); + } else { + splice.call(array, index, 1); + } + return true; + } + + /** + * Gets the associative array value for `key`. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function assocGet(array, key) { + var index = assocIndexOf(array, key); + return index < 0 ? undefined : array[index][1]; + } + + /** + * Checks if an associative array value for `key` exists. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function assocHas(array, key) { + return assocIndexOf(array, key) > -1; + } + + /** + * Gets the index at which the first occurrence of `key` is found in `array` + * of key-value pairs. + * + * @private + * @param {Array} array The array to search. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * Sets the associative array `key` to `value`. + * + * @private + * @param {Array} array The array to modify. + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + */ + function assocSet(array, key, value) { + var index = assocIndexOf(array, key); + if (index < 0) { + array.push([key, value]); + } else { + array[index][1] = value; + } + } + + /*------------------------------------------------------------------------*/ + + /** + * Used by `_.defaults` to customize its `_.assignIn` use. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. + */ + function assignInDefaults(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; + } + + /** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (typeof key == 'number' && value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function(value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.at` without support for individual paths. + * + * @private + * @param {Object} object The object to iterate over. + * @param {string[]} paths The property paths of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ + function baseAt(object, paths) { + var index = -1, + isNil = object == null, + length = paths.length, + result = Array(length); + + while (++index < length) { + result[index] = isNil ? undefined : get(object, paths[index]); + } + return result; + } + + /** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; + } + + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastFunction(value) { + return typeof value == 'function' ? value : identity; + } + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast property path array. + */ + function baseCastPath(value) { + return isArray(value) ? value : stringToPath(value); + } + + /** + * The base implementation of `_.clamp` which doesn't coerce arguments to numbers. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ + function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined) { + number = number <= upper ? number : upper; + } + if (lower !== undefined) { + number = number >= lower ? number : lower; + } + } + return number; + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + result = baseAssign(result, value); + return isFull ? copySymbols(value, result) : result; + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return (isFull && !isArr) ? copySymbols(value, result) : result; + } + + /** + * The base implementation of `_.conforms` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new function. + */ + function baseConforms(source) { + var props = keys(source), + length = props.length; + + return function(object) { + if (object == null) { + return !length; + } + var index = length; + while (index--) { + var key = props[index], + predicate = source[key], + value = object[key]; + + if ((value === undefined && !(key in Object(object))) || !predicate(value)) { + return false; + } + } + return true; + }; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `_.delay` and `_.defer` which accepts an array + * of `func` arguments. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments to provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of methods like `_.difference` without support for + * excluding multiple arrays or iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; + + if (!length) { + return result; + } + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } + else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; + isCommon = false; + values = new SetCache(values); + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (isCommon && computed === computed) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === computed) { + continue outer; + } + } + result.push(value); + } + else if (!includes(values, computed, comparator)) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.forEachRight` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); + + /** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ + function baseFill(array, value, start, end) { + var length = array.length; + + start = toInteger(start); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : toInteger(end); + if (end < 0) { + end += length; + } + end = start > end ? 0 : toLength(end); + while (start < end) { + array[start++] = value; + } + return array; + } + + /** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, depth, isStrict, result) { + result || (result = []); + + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + if (depth > 0 && isArrayLikeObject(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); + + /** + * The base implementation of `_.forIn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForIn(object, iteratee) { + return object == null ? object : baseFor(object, iteratee, keysIn); + } + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return object && baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ + function baseFunctions(object, props) { + return arrayFilter(props, function(key) { + return isFunction(object[key]); + }); + } + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[path[index++]]; + } + return (index && index == length) ? object : undefined; + } + + /** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHas(object, key) { + // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`, + // that are composed entirely of index properties, return `false` for + // `hasOwnProperty` checks of them. + return hasOwnProperty.call(object, key) || + (typeof object == 'object' && key in object && getPrototypeOf(object) === null); + } + + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHasIn(object, key) { + return key in Object(object); + } + + /** + * The base implementation of `_.inRange` which doesn't coerce arguments to numbers. + * + * @private + * @param {number} number The number to check. + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + */ + function baseInRange(number, start, end) { + return number >= nativeMin(start, end) && number < nativeMax(start, end); + } + + /** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ + function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + maxLength = Infinity, + result = []; + + while (othIndex--) { + var array = arrays[othIndex]; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) + ? new SetCache(othIndex && array) + : undefined; + } + array = arrays[0]; + + var index = -1, + seen = caches[0]; + + outer: + while (++index < length && result.length < maxLength) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { + othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { + continue outer; + } + } + if (seen) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.invert` and `_.invertBy` which inverts + * `object` with values transformed by `iteratee` and set by `setter`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform values. + * @param {Object} accumulator The initial inverted object. + * @returns {Function} Returns `accumulator`. + */ + function baseInverter(object, setter, iteratee, accumulator) { + baseForOwn(object, function(value, key, object) { + setter(accumulator, iteratee(value), key, object); + }); + return accumulator; + } + + /** + * The base implementation of `_.invoke` without support for individual + * method arguments. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function baseInvoke(object, path, args) { + if (!isKey(path, object)) { + path = baseCastPath(path); + object = parent(object, path); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : apply(func, object, args); + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @param {boolean} [bitmask] The bitmask of comparison flags. + * The bitmask may be composed of the following flags: + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, customizer, bitmask, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparisons. + * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = getTag(object); + objTag = objTag == argsTag ? objectTag : objTag; + } + if (!othIsArr) { + othTag = getTag(other); + othTag = othTag == argsTag ? objectTag : othTag; + } + var objIsObj = objTag == objectTag && !isHostObject(object), + othIsObj = othTag == objectTag && !isHostObject(other), + isSameTag = objTag == othTag; + + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, equalFunc, customizer, bitmask, stack) + : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack); + } + if (!(bitmask & PARTIAL_COMPARE_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + stack || (stack = new Stack); + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, equalFunc, customizer, bitmask, stack); + } + + /** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack, + result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined; + + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) + : result + )) { + return false; + } + } + } + return true; + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(value) { + var type = typeof value; + if (type == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (type == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); + } + + /** + * The base implementation of `_.keys` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + return nativeKeys(Object(object)); + } + + /** + * The base implementation of `_.keysIn` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + object = object == null ? object : Object(object); + + var result = []; + for (var key in object) { + result.push(key); + } + return result; + } + + // Fallback for IE < 9 with es6-shim. + if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) { + baseKeysIn = function(object) { + return iteratorToArray(enumerate(object)); + }; + } + + /** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; + + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && + (value !== undefined || (key in Object(object))); + }; + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; + } + + /** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new function. + */ + function baseMatchesProperty(path, srcValue) { + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG); + }; + } + + /** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + */ + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + var props = (isArray(source) || isTypedArray(source)) + ? undefined + : keysIn(source); + + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; + } + if (isObject(srcValue)) { + stack || (stack = new Stack); + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(object[key], srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }); + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + */ + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = object[key], + srcValue = source[key], + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + newValue = srcValue; + if (isArray(srcValue) || isTypedArray(srcValue)) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else { + isCommon = false; + newValue = baseClone(srcValue, !customizer); + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { + isCommon = false; + newValue = baseClone(srcValue, !customizer); + } + else { + newValue = objValue; + } + } + else { + isCommon = false; + } + } + stack.set(srcValue, newValue); + + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + } + stack['delete'](srcValue); + assignMergeValue(object, key, newValue); + } + + /** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseOrderBy(collection, iteratees, orders) { + var index = -1; + iteratees = arrayMap(iteratees.length ? iteratees : Array(1), getIteratee()); + + var result = baseMap(collection, function(value, key, collection) { + var criteria = arrayMap(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.pick` without support for individual + * property names. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function basePick(object, props) { + object = Object(object); + return arrayReduce(props, function(result, key) { + if (key in object) { + result[key] = object[key]; + } + return result; + }, {}); + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, predicate) { + var result = {}; + baseForIn(object, function(value, key) { + if (predicate(value, key)) { + result[key] = value; + } + }); + return result; + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ + function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; + } + + /** + * The base implementation of `_.pullAllBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + */ + function basePullAll(array, values, iteratee, comparator) { + var indexOf = comparator ? baseIndexOfWith : baseIndexOf, + index = -1, + length = values.length, + seen = array; + + if (iteratee) { + seen = arrayMap(array, baseUnary(iteratee)); + } + while (++index < length) { + var fromIndex = 0, + value = values[index], + computed = iteratee ? iteratee(value) : value; + + while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { + if (seen !== array) { + splice.call(seen, fromIndex, 1); + } + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * indexes or capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0, + lastIndex = length - 1; + + while (length--) { + var index = indexes[length]; + if (lastIndex == length || index != previous) { + var previous = index; + if (isIndex(index)) { + splice.call(array, index, 1); + } + else if (!isKey(index, array)) { + var path = baseCastPath(index), + object = parent(array, path); + + if (object != null) { + delete object[last(path)]; + } + } + else { + delete array[index]; + } + } + } + return array; + } + + /** + * The base implementation of `_.random` without support for returning + * floating-point numbers. + * + * @private + * @param {number} lower The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the random number. + */ + function baseRandom(lower, upper) { + return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); + } + + /** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments to numbers. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the new array of numbers. + */ + function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; + } + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + var newValue = value; + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = objValue == null + ? (isIndex(path[index + 1]) ? [] : {}) + : objValue; + } + } + assignValue(nested, key, newValue); + } + nested = nested[key]; + } + return object; + } + + /** + * The base implementation of `setData` without support for hot loop detection. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which + * performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function baseSortedIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return baseSortedIndexBy(array, value, identity, retHighest); + } + + /** + * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` + * which invokes `iteratee` for `value` and each element of `array` to compute + * their sort ranking. The iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The iteratee invoked per element. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + */ + function baseSortedIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); + + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsNull = value === null, + valIsUndef = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + isDef = computed !== undefined, + isReflexive = computed === computed; + + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } + + /** + * The base implementation of `_.sortedUniq`. + * + * @private + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + */ + function baseSortedUniq(array) { + return baseSortedUniqBy(array); + } + + /** + * The base implementation of `_.sortedUniqBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseSortedUniqBy(array, iteratee) { + var index = 0, + length = array.length, + value = array[0], + computed = iteratee ? iteratee(value) : value, + seen = computed, + resIndex = 1, + result = [value]; + + while (++index < length) { + value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!eq(computed, seen)) { + seen = computed; + result[resIndex++] = value; + } + } + return result; + } + + /** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.unset`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + */ + function baseUnset(object, path) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + object = parent(object, path); + var key = last(path); + return (object != null && has(object, key)) ? delete object[key] : true; + } + + /** + * The base implementation of `_.update`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to update. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseUpdate(object, path, updater, customizer) { + return baseSet(object, path, updater(baseGet(object, path)), customizer); + } + + /** + * The base implementation of methods like `_.dropWhile` and `_.takeWhile` + * without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && + predicate(array[index], index, array)) {} + + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + return arrayReduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); + } + + /** + * The base implementation of methods like `_.xor`, without support for + * iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + */ + function baseXor(arrays, iteratee, comparator) { + var index = -1, + length = arrays.length; + + while (++index < length) { + var result = result + ? arrayPush( + baseDifference(result, arrays[index], iteratee, comparator), + baseDifference(arrays[index], result, iteratee, comparator) + ) + : arrays[index]; + } + return (result && result.length) ? baseUniq(result, iteratee, comparator) : []; + } + + /** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property names. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ + function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + assignFunc(result, props[index], index < valsLength ? values[index] : undefined); + } + return result; + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @returns {Object} Returns the cloned map. + */ + function cloneMap(map) { + return arrayReduce(mapToArray(map), addMapEntry, new map.constructor); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set) { + return arrayReduce(setToArray(set), addSetEntry, new set.constructor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersLength = holders.length, + leftIndex = -1, + leftLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(leftLength + rangeLength), + isUncurried = !isCurried; + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + } + while (rangeLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersIndex = -1, + holdersLength = holders.length, + rightIndex = -1, + rightLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(rangeLength + rightLength), + isUncurried = !isCurried; + + while (++argsIndex < rangeLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object) { + return copyObjectWith(source, props, object); + } + + /** + * This function is like `copyObject` except that it accepts a function to + * customize copied values. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObjectWith(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : source[key]; + + assignValue(object, key, newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates a function like `_.groupBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; + + return func(collection, setter, getIteratee(iteratee), accumulator); + }; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return rest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = typeof customizer == 'function' + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for methods like `_.forIn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createBaseWrapper(func, bitmask, thisArg) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, arguments); + } + return wrapper; + } + + /** + * Creates a function like `_.lowerFirst`. + * + * @private + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new function. + */ + function createCaseFirst(methodName) { + return function(string) { + string = toString(string); + + var strSymbols = reHasComplexSymbol.test(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols ? strSymbols[0] : string.charAt(0), + trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1); + + return chr[methodName]() + trailing; + }; + } + + /** + * Creates a function like `_.camelCase`. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + return arrayReduce(words(deburr(string)), callback, ''); + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtorWrapper(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a function that wraps `func` to enable currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {number} arity The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createCurryWrapper(func, bitmask, arity) { + var Ctor = createCtorWrapper(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length, + placeholder = getPlaceholder(wrapper); + + while (index--) { + args[index] = arguments[index]; + } + var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) + ? [] + : replaceHolders(args, placeholder); + + length -= holders.length; + if (length < arity) { + return createRecurryWrapper( + func, bitmask, createHybridWrapper, wrapper.placeholder, undefined, + args, holders, undefined, undefined, arity - length); + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return apply(fn, this, args); + } + return wrapper; + } + + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return rest(function(funcs) { + funcs = baseFlatten(funcs, 1); + + var length = funcs.length, + index = length, + prereq = LodashWrapper.prototype.thru; + + if (fromRight) { + funcs.reverse(); + } + while (index--) { + var func = funcs[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (prereq && !wrapper && getFuncName(func) == 'wrapper') { + var wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? index : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && + data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && + isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }); + } + + /** + * Creates a function that wraps `func` to invoke it with optional `this` + * binding of `thisArg`, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG), + isFlip = bitmask & FLIP_FLAG, + Ctor = isBindKey ? undefined : createCtorWrapper(func); + + function wrapper() { + var length = arguments.length, + index = length, + args = Array(length); + + while (index--) { + args[index] = arguments[index]; + } + if (isCurried) { + var placeholder = getPlaceholder(wrapper), + holdersCount = countHolders(args, placeholder); + } + if (partials) { + args = composeArgs(args, partials, holders, isCurried); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight, isCurried); + } + length -= holdersCount; + if (isCurried && length < arity) { + var newHolders = replaceHolders(args, placeholder); + return createRecurryWrapper( + func, bitmask, createHybridWrapper, wrapper.placeholder, thisArg, + args, newHolders, argPos, ary, arity - length + ); + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + length = args.length; + if (argPos) { + args = reorder(args, argPos); + } else if (isFlip && length > 1) { + args.reverse(); + } + if (isAry && ary < length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtorWrapper(fn); + } + return fn.apply(thisBinding, args); + } + return wrapper; + } + + /** + * Creates a function like `_.invertBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} toIteratee The function to resolve iteratees. + * @returns {Function} Returns the new inverter function. + */ + function createInverter(setter, toIteratee) { + return function(object, iteratee) { + return baseInverter(object, setter, toIteratee(iteratee), {}); + }; + } + + /** + * Creates a function like `_.over`. + * + * @private + * @param {Function} arrayFunc The function to iterate over iteratees. + * @returns {Function} Returns the new invoker function. + */ + function createOver(arrayFunc) { + return rest(function(iteratees) { + iteratees = arrayMap(baseFlatten(iteratees, 1), getIteratee()); + return rest(function(args) { + var thisArg = this; + return arrayFunc(iteratees, function(iteratee) { + return apply(iteratee, thisArg, args); + }); + }); + }); + } + + /** + * Creates the padding for `string` based on `length`. The `chars` string + * is truncated if the number of characters exceeds `length`. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padding for `string`. + */ + function createPadding(string, length, chars) { + length = toInteger(length); + + var strLength = stringSize(string); + if (!length || strLength >= length) { + return ''; + } + var padLength = length - strLength; + chars = chars === undefined ? ' ' : (chars + ''); + + var result = repeat(chars, nativeCeil(padLength / stringSize(chars))); + return reHasComplexSymbol.test(chars) + ? stringToArray(result).slice(0, padLength).join('') + : result.slice(0, padLength); + } + + /** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new wrapped function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return apply(fn, isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ + function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = toNumber(start); + start = start === start ? start : 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = toNumber(end) || 0; + } + step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0); + return baseRange(start, end, step, fromRight); + }; + } + + /** + * Creates a function that wraps `func` to continue currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {Function} wrapFunc The function to create the `func` wrapper. + * @param {*} placeholder The placeholder value. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { + var isCurry = bitmask & CURRY_FLAG, + newArgPos = argPos ? copyArray(argPos) : undefined, + newHolders = isCurry ? holders : undefined, + newHoldersRight = isCurry ? undefined : holders, + newPartials = isCurry ? partials : undefined, + newPartialsRight = isCurry ? undefined : partials; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!(bitmask & CURRY_BOUND_FLAG)) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [ + func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, + newHoldersRight, newArgPos, ary, arity + ]; + + var result = wrapFunc.apply(undefined, newData); + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; + } + + /** + * Creates a function like `_.round`. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + number = toNumber(number); + precision = toInteger(precision); + if (precision) { + // Shift with exponential notation to avoid floating-point issues. + // See [MDN](https://mdn.io/round#Examples) for more details. + var pair = (toString(number) + 'e').split('e'), + value = func(pair[0] + 'e' + (+pair[1] + precision)); + + pair = (toString(value) + 'e').split('e'); + return +(pair[0] + 'e' + (+pair[1] - precision)); + } + return func(number); + }; + } + + /** + * Creates a set of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ + var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) { + return new Set(values); + }; + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask of wrapper flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); + arity = arity === undefined ? arity : toInteger(arity); + length -= holders ? holders.length : 0; + + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; + + if (data) { + mergeData(newData, data); + } + func = newData[0]; + bitmask = newData[1]; + thisArg = newData[2]; + partials = newData[3]; + holders = newData[4]; + arity = newData[9] = newData[9] == null + ? (isBindKey ? 0 : func.length) + : nativeMax(newData[9] - length, 0); + + if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) { + bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG); + } + if (!bitmask || bitmask == BIND_FLAG) { + var result = createBaseWrapper(func, bitmask, thisArg); + } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) { + result = createCurryWrapper(func, bitmask, arity); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) { + result = createPartialWrapper(func, bitmask, thisArg, partials); + } else { + result = createHybridWrapper.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { + var index = -1, + isPartial = bitmask & PARTIAL_COMPARE_FLAG, + isUnordered = bitmask & UNORDERED_COMPARE_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked) { + return stacked == other; + } + var result = true; + stack.set(array, other); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isUnordered) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack); + })) { + result = false; + break; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { + result = false; + break; + } + } + stack['delete'](array); + return result; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) { + switch (tag) { + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) ? other != +other : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & PARTIAL_COMPARE_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + // Recursively compare objects (susceptible to call stack limits). + return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask | UNORDERED_COMPARE_FLAG, stack.set(object, other)); + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { + var isPartial = bitmask & PARTIAL_COMPARE_FLAG, + objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : baseHas(other, key))) { + return false; + } + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + var result = true; + stack.set(object, other); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + return result; + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; + + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = (func.name + ''), + array = realNames[result], + length = hasOwnProperty.call(realNames, result) ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } + + /** + * Gets the appropriate "iteratee" function. If the `_.iteratee` method is + * customized this function returns the custom method, otherwise it returns + * `baseIteratee`. If arguments are provided the chosen function is invoked + * with them and its result is returned. + * + * @private + * @param {*} [value] The value to convert to an iteratee. + * @param {number} [arity] The arity of the created iteratee. + * @returns {Function} Returns the chosen function or its result. + */ + function getIteratee() { + var result = lodash.iteratee || iteratee; + result = result === iteratee ? baseIteratee : result; + return arguments.length ? result(arguments[0], arguments[1]) : result; + } + + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = toPairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = object[key]; + return isNative(value) ? value : undefined; + } + + /** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ + function getPlaceholder(func) { + var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; + return object.placeholder; + } + + /** + * Creates an array of the own symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = getOwnPropertySymbols || function() { + return []; + }; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function getTag(value) { + return objectToString.call(value); + } + + // Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps. + if ((Map && getTag(new Map) != mapTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : null, + ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case mapCtorString: return mapTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ + function hasPath(object, path, hasFunc) { + if (object == null) { + return false; + } + var result = hasFunc(object, path); + if (!result && !isKey(path)) { + path = baseCastPath(path); + object = parent(object, path); + if (object != null) { + path = last(path); + result = hasFunc(object, path); + } + } + var length = object ? object.length : undefined; + return result || ( + !!length && isLength(length) && isIndex(path, length) && + (isArray(object) || isString(object) || isArguments(object)) + ); + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototypeOf(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object); + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Creates an array of index keys for `object` values of arrays, + * `arguments` objects, and strings, otherwise `null` is returned. + * + * @private + * @param {Object} object The object to query. + * @returns {Array|null} Returns index keys, else `null`. + */ + function indexKeys(object) { + var length = object ? object.length : undefined; + if (isLength(length) && + (isArray(object) || isString(object) || isArguments(object))) { + return baseTimes(length, String); + } + return null; + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + return eq(object[index], value); + } + return false; + } + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (typeof value == 'number') { + return true; + } + return !isArray(value) && + (reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object))); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return type == 'number' || type == 'boolean' || + (type == 'string' && value != '__proto__') || value == null; + } + + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func), + other = lodash[funcName]; + + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { + return false; + } + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers used to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` + * modify function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * combined case where curried functions have `_.ary` and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG); + + var isCombo = + ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) || + ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) || + ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG)); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = copyArray(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to merge. + * @param {Object} object The parent object of `objValue`. + * @param {Object} source The parent object of `srcValue`. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + * @returns {*} Returns the value to assign. + */ + function mergeDefaults(objValue, srcValue, key, object, source, stack) { + if (isObject(objValue) && isObject(srcValue)) { + baseMerge(objValue, srcValue, undefined, mergeDefaults, stack.set(srcValue, objValue)); + } + return objValue; + } + + /** + * Gets the parent value at `path` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. + */ + function parent(object, path) { + return path.length == 1 ? object : get(object, baseSlice(path, 0, -1)); + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = copyArray(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity function + * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = (function() { + var count = 0, + lastCalled = 0; + + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; + } + return baseSetData(key, value); + }; + }()); + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + function stringToPath(string) { + var result = []; + toString(string).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `array` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=0] The length of each chunk. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size) { + size = nativeMax(toInteger(size), 0); + + var length = array ? array.length : 0; + if (!length || size < 1) { + return []; + } + var index = 0, + resIndex = 0, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[resIndex++] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var concat = rest(function(array, values) { + if (!isArray(array)) { + array = array == null ? [] : [Object(array)]; + } + values = baseFlatten(values, 1); + return arrayConcat(array, values); + }); + + /** + * Creates an array of unique `array` values not included in the other + * given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. The order of result values is determined by the + * order they occur in the first array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([3, 2, 1], [4, 2]); + * // => [3, 1] + */ + var difference = rest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `iteratee` which + * is invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. Result values are chosen from the first array. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor); + * // => [3.1, 1.3] + * + * // The `_.property` iteratee shorthand. + * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var differenceBy = rest(function(array, values) { + var iteratee = last(values); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true), getIteratee(iteratee)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `comparator` + * which is invoked to compare elements of `array` to `values`. Result values + * are chosen from the first array. The comparator is invoked with two arguments: + * (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * + * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); + * // => [{ 'x': 2, 'y': 1 }] + */ + var differenceWith = rest(function(array, values) { + var comparator = last(values); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true), undefined, comparator) + : []; + }); + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.dropRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney'] + * + * // The `_.matches` iteratee shorthand. + * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropRightWhile(users, ['active', false]); + * // => objects for ['barney'] + * + * // The `_.property` iteratee shorthand. + * _.dropRightWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ + function dropRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), true, true) + : []; + } + + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.dropWhile(users, function(o) { return !o.active; }); + * // => objects for ['pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.dropWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropWhile(users, ['active', false]); + * // => objects for ['pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.dropWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ + function dropWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), true) + : []; + } + + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8, 10], '*', 1, 3); + * // => [4, '*', '*', 10] + */ + function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ + function findIndex(array, predicate) { + return (array && array.length) + ? baseFindIndex(array, getIteratee(predicate, 3)) + : -1; + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); + * // => 2 + * + * // The `_.matches` iteratee shorthand. + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastIndex(users, ['active', false]); + * // => 2 + * + * // The `_.property` iteratee shorthand. + * _.findLastIndex(users, 'active'); + * // => 0 + */ + function findLastIndex(array, predicate) { + return (array && array.length) + ? baseFindIndex(array, getIteratee(predicate, 3), true) + : -1; + } + + /** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ + function flatten(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, 1) : []; + } + + /** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, INFINITY) : []; + } + + /** + * Recursively flatten `array` up to `depth` times. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * var array = [1, [2, [3, [4]], 5]]; + * + * _.flattenDepth(array, 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth(array, 2); + * // => [1, 2, 3, [4], 5] + */ + function flattenDepth(array, depth) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(array, depth); + } + + /** + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. + * @example + * + * _.fromPairs([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + */ + function fromPairs(pairs) { + var index = -1, + length = pairs ? pairs.length : 0, + result = {}; + + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } + return result; + } + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ + function head(array) { + return array ? array[0] : undefined; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + fromIndex = toInteger(fromIndex); + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + return dropRight(array, 1); + } + + /** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. The order of result values is determined by the + * order they occur in the first array. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersection([2, 1], [4, 2], [1, 2]); + * // => [2] + */ + var intersection = rest(function(arrays) { + var mapped = arrayMap(arrays, baseCastArrayLikeObject); + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped) + : []; + }); + + /** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which they're compared. Result values are chosen from the first array. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [2.1] + * + * // The `_.property` iteratee shorthand. + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ + var intersectionBy = rest(function(arrays) { + var iteratee = last(arrays), + mapped = arrayMap(arrays, baseCastArrayLikeObject); + + if (iteratee === last(mapped)) { + iteratee = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, getIteratee(iteratee)) + : []; + }); + + /** + * This method is like `_.intersection` except that it accepts `comparator` + * which is invoked to compare elements of `arrays`. Result values are chosen + * from the first array. The comparator is invoked with two arguments: + * (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.intersectionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }] + */ + var intersectionWith = rest(function(arrays) { + var comparator = last(arrays), + mapped = arrayMap(arrays, baseCastArrayLikeObject); + + if (comparator === last(mapped)) { + comparator = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, undefined, comparator) + : []; + }); + + /** + * Converts all elements in `array` into a string separated by `separator`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to convert. + * @param {string} [separator=','] The element separator. + * @returns {string} Returns the joined string. + * @example + * + * _.join(['a', 'b', 'c'], '~'); + * // => 'a~b~c' + */ + function join(array, separator) { + return array ? nativeJoin.call(array, separator) : ''; + } + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } + + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // Search from the `fromIndex`. + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all given values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` + * to remove elements from an array by predicate. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + var pull = rest(pullAll); + + /** + * This method is like `_.pull` except that it accepts an array of values to remove. + * + * **Note:** Unlike `_.difference`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pullAll(array, [2, 3]); + * console.log(array); + * // => [1, 1] + */ + function pullAll(array, values) { + return (array && array.length && values && values.length) + ? basePullAll(array, values) + : array; + } + + /** + * This method is like `_.pullAll` except that it accepts `iteratee` which is + * invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. The iteratee is invoked with one argument: (value). + * + * **Note:** Unlike `_.differenceBy`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; + * + * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); + * console.log(array); + * // => [{ 'x': 2 }] + */ + function pullAllBy(array, values, iteratee) { + return (array && array.length && values && values.length) + ? basePullAll(array, values, getIteratee(iteratee)) + : array; + } + + /** + * This method is like `_.pullAll` except that it accepts `comparator` which + * is invoked to compare elements of `array` to `values`. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.differenceWith`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; + * + * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); + * console.log(array); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] + */ + function pullAllWith(array, values, comparator) { + return (array && array.length && values && values.length) + ? basePullAll(array, values, undefined, comparator) + : array; + } + + /** + * Removes elements from `array` corresponding to `indexes` and returns an + * array of removed elements. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified individually or in arrays. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, 1, 3); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] + */ + var pullAt = rest(function(array, indexes) { + indexes = arrayMap(baseFlatten(indexes, 1), String); + + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(compareAscending)); + return result; + }); + + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is invoked + * with three arguments: (value, index, array). + * + * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` + * to pull elements from an array by value. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = getIteratee(predicate, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; + } + + /** + * Reverses `array` so that the first element becomes the last, the second + * element becomes the second to last, and so on. + * + * **Note:** This method mutates `array` and is based on + * [`Array#reverse`](https://mdn.io/Array/reverse). + * + * @static + * @memberOf _ + * @category Array + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.reverse(array); + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function reverse(array) { + return array ? nativeReverse.call(array) : array; + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice) + * to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + else { + start = start == null ? 0 : toInteger(start); + end = end === undefined ? length : toInteger(end); + } + return baseSlice(array, start, end); + } + + /** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 5], 4); + * // => 0 + */ + function sortedIndex(array, value) { + return baseSortedIndex(array, value); + } + + /** + * This method is like `_.sortedIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + * @example + * + * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 }; + * + * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict)); + * // => 1 + * + * // The `_.property` iteratee shorthand. + * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); + * // => 0 + */ + function sortedIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee)); + } + + /** + * This method is like `_.indexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedIndexOf([1, 1, 2, 2], 2); + * // => 2 + */ + function sortedIndexOf(array, value) { + var length = array ? array.length : 0; + if (length) { + var index = baseSortedIndex(array, value); + if (index < length && eq(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + * @example + * + * _.sortedLastIndex([4, 5], 4); + * // => 1 + */ + function sortedLastIndex(array, value) { + return baseSortedIndex(array, value, true); + } + + /** + * This method is like `_.sortedLastIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + * @example + * + * // The `_.property` iteratee shorthand. + * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); + * // => 1 + */ + function sortedLastIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee), true); + } + + /** + * This method is like `_.lastIndexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedLastIndexOf([1, 1, 2, 2], 2); + * // => 3 + */ + function sortedLastIndexOf(array, value) { + var length = array ? array.length : 0; + if (length) { + var index = baseSortedIndex(array, value, true) - 1; + if (eq(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.uniq` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniq([1, 1, 2]); + * // => [1, 2] + */ + function sortedUniq(array) { + return (array && array.length) + ? baseSortedUniq(array) + : []; + } + + /** + * This method is like `_.uniqBy` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); + * // => [1.1, 2.3] + */ + function sortedUniqBy(array, iteratee) { + return (array && array.length) + ? baseSortedUniqBy(array, getIteratee(iteratee)) + : []; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.tail([1, 2, 3]); + * // => [2, 3] + */ + function tail(array) { + return drop(array, 1); + } + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + if (!(array && array.length)) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is invoked with three + * arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.takeRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeRightWhile(users, ['active', false]); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.takeRightWhile(users, 'active'); + * // => [] + */ + function takeRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), false, true) + : []; + } + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.takeWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matches` iteratee shorthand. + * _.takeWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeWhile(users, ['active', false]); + * // => objects for ['barney', 'fred'] + * + * // The `_.property` iteratee shorthand. + * _.takeWhile(users, 'active'); + * // => [] + */ + function takeWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3)) + : []; + } + + /** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2, 1], [4, 2], [1, 2]); + * // => [2, 1, 4] + */ + var union = rest(function(arrays) { + return baseUniq(baseFlatten(arrays, 1, true)); + }); + + /** + * This method is like `_.union` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by which + * uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [2.1, 1.2, 4.3] + * + * // The `_.property` iteratee shorthand. + * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + var unionBy = rest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return baseUniq(baseFlatten(arrays, 1, true), getIteratee(iteratee)); + }); + + /** + * This method is like `_.union` except that it accepts `comparator` which + * is invoked to compare elements of `arrays`. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.unionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var unionWith = rest(function(arrays) { + var comparator = last(arrays); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return baseUniq(baseFlatten(arrays, 1, true), undefined, comparator); + }); + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + */ + function uniq(array) { + return (array && array.length) + ? baseUniq(array) + : []; + } + + /** + * This method is like `_.uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniqBy([2.1, 1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniqBy(array, iteratee) { + return (array && array.length) + ? baseUniq(array, getIteratee(iteratee)) + : []; + } + + /** + * This method is like `_.uniq` except that it accepts `comparator` which + * is invoked to compare elements of `array`. The comparator is invoked with + * two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.uniqWith(objects, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] + */ + function uniqWith(array, comparator) { + return (array && array.length) + ? baseUniq(array, undefined, comparator) + : []; + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ + function unzip(array) { + if (!(array && array.length)) { + return []; + } + var length = 0; + array = arrayFilter(array, function(group) { + if (isArrayLikeObject(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + return baseTimes(length, function(index) { + return arrayMap(array, baseProperty(index)); + }); + } + + /** + * This method is like `_.unzip` except that it accepts `iteratee` to specify + * how regrouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee=_.identity] The function to combine regrouped values. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ + function unzipWith(array, iteratee) { + if (!(array && array.length)) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + return arrayMap(result, function(group) { + return apply(iteratee, undefined, group); + }); + } + + /** + * Creates an array excluding all given values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 3], 1, 2); + * // => [3] + */ + var without = rest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, values) + : []; + }); + + /** + * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the given arrays. The order of result values is determined by the order + * they occur in the arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([2, 1], [4, 2]); + * // => [1, 4] + */ + var xor = rest(function(arrays) { + return baseXor(arrayFilter(arrays, isArrayLikeObject)); + }); + + /** + * This method is like `_.xor` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by which + * by which they're compared. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [1.2, 4.3] + * + * // The `_.property` iteratee shorthand. + * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var xorBy = rest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee)); + }); + + /** + * This method is like `_.xor` except that it accepts `comparator` which is + * invoked to compare elements of `arrays`. The comparator is invoked with + * two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.xorWith(objects, others, _.isEqual); + * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var xorWith = rest(function(arrays) { + var comparator = last(arrays); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); + }); + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second elements + * of the given arrays, and so on. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + var zip = rest(unzip); + + /** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property names and one of corresponding values. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} [props=[]] The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ + function zipObject(props, values) { + return baseZipObject(props || [], values || [], assignValue); + } + + /** + * This method is like `_.zipObject` except that it supports property paths. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} [props=[]] The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); + * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } + */ + function zipObjectDeep(props, values) { + return baseZipObject(props || [], values || [], baseSet); + } + + /** + * This method is like `_.zip` except that it accepts `iteratee` to specify + * how grouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee=_.identity] The function to combine grouped values. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { + * return a + b + c; + * }); + * // => [111, 222] + */ + var zipWith = rest(function(arrays) { + var length = arrays.length, + iteratee = length > 1 ? arrays[length - 1] : undefined; + + iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; + return unzipWith(arrays, iteratee); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps `value` with explicit method chaining enabled. + * The result of such method chaining must be unwrapped with `_#value`. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor + * is invoked with one argument; (value). The purpose of this method is to + * "tap into" a method chain in order to modify intermediate results. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * // Mutate input array. + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * The purpose of this method is to "pass thru" values replacing intermediate + * results in a method chain. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor) { + return interceptor(value); + } + + /** + * This method is the wrapper version of `_.at`. + * + * @name at + * @memberOf _ + * @category Seq + * @param {...(string|string[])} [paths] The property paths of elements to pick, + * specified individually or in arrays. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _(object).at(['a[0].b.c', 'a[1]']).value(); + * // => [3, 4] + * + * _(['a', 'b', 'c']).at(0, 2).value(); + * // => ['a', 'c'] + */ + var wrapperAt = rest(function(paths) { + paths = baseFlatten(paths, 1); + var length = paths.length, + start = length ? paths[0] : 0, + value = this.__wrapped__, + interceptor = function(object) { return baseAt(object, paths); }; + + if (length > 1 || this.__actions__.length || + !(value instanceof LazyWrapper) || !isIndex(start)) { + return this.thru(interceptor); + } + value = value.slice(start, +start + (length ? 1 : 0)); + value.__actions__.push({ + 'func': thru, + 'args': [interceptor], + 'thisArg': undefined + }); + return new LodashWrapper(value, this.__chain__).thru(function(array) { + if (length && !array.length) { + array.push(undefined); + } + return array; + }); + }); + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // A sequence without explicit chaining. + * _(users).head(); + * // => { 'user': 'barney', 'age': 36 } + * + * // A sequence with explicit chaining. + * _(users) + * .chain() + * .head() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } + + /** + * This method is the wrapper version of `_.flatMap`. + * + * @name flatMap + * @memberOf _ + * @category Seq + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function duplicate(n) { + * return [n, n]; + * } + * + * _([1, 2]).flatMap(duplicate).value(); + * // => [1, 1, 2, 2] + */ + function wrapperFlatMap(iteratee) { + return this.map(iteratee).flatten(); + } + + /** + * Gets the next value on a wrapped object following the + * [iterator protocol](https://mdn.io/iteration_protocols#iterator). + * + * @name next + * @memberOf _ + * @category Seq + * @returns {Object} Returns the next iterator value. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped.next(); + * // => { 'done': false, 'value': 1 } + * + * wrapped.next(); + * // => { 'done': false, 'value': 2 } + * + * wrapped.next(); + * // => { 'done': true, 'value': undefined } + */ + function wrapperNext() { + if (this.__values__ === undefined) { + this.__values__ = toArray(this.value()); + } + var done = this.__index__ >= this.__values__.length, + value = done ? undefined : this.__values__[this.__index__++]; + + return { 'done': done, 'value': value }; + } + + /** + * Enables the wrapper to be iterable. + * + * @name Symbol.iterator + * @memberOf _ + * @category Seq + * @returns {Object} Returns the wrapper object. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped[Symbol.iterator]() === wrapped; + * // => true + * + * Array.from(wrapped); + * // => [1, 2] + */ + function wrapperToIterator() { + return this; + } + + /** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Seq + * @param {*} value The value to plant. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2]).map(square); + * var other = wrapped.plant([3, 4]); + * + * other.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + clone.__index__ = 0; + clone.__values__ = undefined; + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } + + /** + * This method is the wrapper version of `_.reverse`. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ + 'func': thru, + 'args': [reverse], + 'thisArg': undefined + }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(reverse); + } + + /** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias toJSON, valueOf + * @category Seq + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, guard) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + */ + function filter(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ + function find(collection, predicate) { + predicate = getIteratee(predicate, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, baseEach); + } + + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ + function findLast(collection, predicate) { + predicate = getIteratee(predicate, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, true); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, baseEachRight); + } + + /** + * Creates an array of flattened values by running each element in `collection` + * through `iteratee` and concating its result to the other mapped values. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [n, n]; + * } + * + * _.flatMap([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ + function flatMap(collection, iteratee) { + return baseFlatten(map(collection, iteratee), 1); + } + + /** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn` + * for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(value) { + * console.log(value); + * }); + * // => logs `1` then `2` + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' then 'b' (iteration order is not guaranteed) + */ + function forEach(collection, iteratee) { + return (typeof iteratee == 'function' && isArray(collection)) + ? arrayEach(collection, iteratee) + : baseEach(collection, baseCastFunction(iteratee)); + } + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @example + * + * _.forEachRight([1, 2], function(value) { + * console.log(value); + * }); + * // => logs `2` then `1` + */ + function forEachRight(collection, iteratee) { + return (typeof iteratee == 'function' && isArray(collection)) + ? arrayEachRight(collection, iteratee) + : baseEachRight(collection, baseCastFunction(iteratee)); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of elements responsible for generating the key. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } + * + * // The `_.property` iteratee shorthand. + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } + }); + + /** + * Checks if `value` is in `collection`. If `collection` is a string it's checked + * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ + function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return isString(collection) + ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) + : (!!length && baseIndexOf(collection, value, fromIndex) > -1); + } + + /** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it's + * invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke each method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invokeMap([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + var invokeMap = rest(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args); + }); + return result; + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var array = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.keyBy(array, function(o) { + * return String.fromCharCode(o.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.keyBy(array, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + */ + var keyBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`, + * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`, + * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`, + * and `words` + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee) { + var func = isArray(collection) ? arrayMap : baseMap; + return func(collection, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.sortBy` except that it allows specifying the sort + * orders of the iteratees to sort by. If `orders` is unspecified, all values + * are sorted in ascending order. Otherwise, specify an order of "desc" for + * descending or "asc" for ascending sort order of corresponding values. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by. + * @param {string[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // Sort by `user` in ascending order and by `age` in descending order. + * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + function orderBy(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + orders = guard ? undefined : orders; + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseOrderBy(collection, iteratees, orders); + } + + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, the second of which + * contains elements `predicate` returns falsey for. The predicate is + * invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * _.partition(users, function(o) { return o.active; }); + * // => objects for [['fred'], ['barney', 'pebbles']] + * + * // The `_.matches` iteratee shorthand. + * _.partition(users, { 'age': 1, 'active': false }); + * // => objects for [['pebbles'], ['barney', 'fred']] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.partition(users, ['active', false]); + * // => objects for [['barney', 'pebbles'], ['fred']] + * + * // The `_.property` iteratee shorthand. + * _.partition(users, 'active'); + * // => objects for [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ + function reduce(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduce : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); + } + + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduceRight : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); + } + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * _.reject(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.reject(users, { 'age': 40, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.reject(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.reject(users, 'active'); + * // => objects for ['barney'] + */ + function reject(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getIteratee(predicate, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); + } + + /** + * Gets a random element from `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + */ + function sample(collection) { + var array = isArrayLike(collection) ? collection : values(collection), + length = array.length; + + return length > 0 ? array[baseRandom(0, length - 1)] : undefined; + } + + /** + * Gets `n` random elements at unique keys from `collection` up to the + * size of `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @param {number} [n=0] The number of elements to sample. + * @returns {Array} Returns the random elements. + * @example + * + * _.sampleSize([1, 2, 3], 2); + * // => [3, 1] + * + * _.sampleSize([1, 2, 3], 4); + * // => [2, 3, 1] + */ + function sampleSize(collection, n) { + var index = -1, + result = toArray(collection), + length = result.length, + lastIndex = length - 1; + + n = baseClamp(toInteger(n), 0, length); + while (++index < n) { + var rand = baseRandom(index, lastIndex), + value = result[rand]; + + result[rand] = result[index]; + result[index] = value; + } + result.length = n; + return result; + } + + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + return sampleSize(collection, MAX_ARRAY_LENGTH); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + if (collection == null) { + return 0; + } + if (isArrayLike(collection)) { + var result = collection.length; + return (result && isString(collection)) ? stringSize(collection) : result; + } + return keys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.some(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, guard) { + var func = isArray(collection) ? arraySome : baseSome; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]] + * The iteratees to sort by, specified individually or in arrays. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, function(o) { return o.user; }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.sortBy(users, 'user', function(o) { + * return Math.floor(o.age / 10); + * }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + var sortBy = rest(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { + iteratees.length = 1; + } + return baseOrderBy(collection, baseFlatten(iteratees, 1), []); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @type {Function} + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked + */ + var now = Date.now; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ + function after(n, func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that accepts up to `n` arguments, ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ + function ary(func, n, guard) { + n = guard ? undefined : n; + n = (func && n == null) ? func.length : n; + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = rest(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getPlaceholder(bind)); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); + }); + + /** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to invoke the method on. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // Bound with placeholders. + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + var bindKey = rest(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getPlaceholder(bindKey)); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); + }); + + /** + * Creates a function that accepts arguments of `func` and either invokes + * `func` returning its result, if at least `arity` number of arguments have + * been provided, or returns a function that accepts the remaining `func` + * arguments, and so on. The arity of `func` may be specified if `func.length` + * is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + function curry(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curry.placeholder; + return result; + } + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ + function curryRight(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryRight.placeholder; + return result; + } + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide an options object to indicate whether `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent calls + * to the debounced function return the result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it's invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + leading = false, + maxWait = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait); + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + lastCalled = 0; + args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined; + } + + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function flush() { + if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) { + result = func.apply(thisArg, args); + } + cancel(); + return result; + } + + function maxDelayed() { + complete(trailing, timeoutId); + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!lastCalled && !maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled); + + var isCalled = (remaining <= 0 || remaining > maxWait) && + (leading || maxTimeoutId); + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => logs 'deferred' after one or more milliseconds + */ + var defer = rest(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ + var delay = rest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); + }); + + /** + * Creates a function that invokes `func` with arguments reversed. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to flip arguments for. + * @returns {Function} Returns the new function. + * @example + * + * var flipped = _.flip(function() { + * return _.toArray(arguments); + * }); + * + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] + */ + function flip(func) { + return createWrapper(func, FLIP_FLAG); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) + * method interface of `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; + } + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with arguments transformed by + * corresponding `transforms`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified individually or in arrays. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var func = _.overArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * func(9, 3); + * // => [81, 6] + * + * func(10, 5); + * // => [100, 10] + */ + var overArgs = rest(function(func, transforms) { + transforms = arrayMap(baseFlatten(transforms, 1), getIteratee()); + + var funcsLength = transforms.length; + return rest(function(args) { + var index = -1, + length = nativeMin(args.length, funcsLength); + + while (++index < length) { + args[index] = transforms[index].call(this, args[index]); + } + return apply(func, this, args); + }); + }); + + /** + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. This method is like `_.bind` except + * it does **not** alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // Partially applied with placeholders. + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ + var partial = rest(function(func, partials) { + var holders = replaceHolders(partials, getPlaceholder(partial)); + return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders); + }); + + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // Partially applied with placeholders. + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ + var partialRight = rest(function(func, partials) { + var holders = replaceHolders(partials, getPlaceholder(partialRight)); + return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders); + }); + + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified indexes where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, + * specified individually or in arrays. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + */ + var rearg = rest(function(func, indexes) { + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1)); + }); + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.rest(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function rest(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, array); + case 1: return func.call(this, args[0], array); + case 2: return func.call(this, args[0], args[1], array); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = array; + return apply(func, this, otherArgs); + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). + * + * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to spread arguments over. + * @param {number} [start=0] The start position of the spread. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ + function spread(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = start === undefined ? 0 : nativeMax(toInteger(start), 0); + return rest(function(args) { + var array = args[start], + otherArgs = args.slice(0, start); + + if (array) { + arrayPush(otherArgs, array); + } + return apply(func, this, otherArgs); + }); + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide an options object to indicate whether + * `func` should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the throttled function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify invoking on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); + } + + /** + * Creates a function that accepts up to one argument, ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.unary(parseInt)); + * // => [6, 8, 10] + */ + function unary(func) { + return ary(func, 1); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {*} value The value to wrap. + * @param {Function} [wrapper=identity] The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

fred, barney, & pebbles

' + */ + function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return partial(wrapper, value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone(value) { + return baseClone(value, false, true); + } + + /** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * } + * + * var el = _.cloneWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 0 + */ + function cloneWith(value, customizer) { + return baseClone(value, false, true, customizer); + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, true, true); + } + + /** + * This method is like `_.cloneWith` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * } + * + * var el = _.cloneDeepWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 20 + */ + function cloneDeepWith(value, customizer) { + return baseClone(value, true, true, customizer); + } + + /** + * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + function gt(value, other) { + return value > other; + } + + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ + function gte(value, other) { + return value >= other; + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @type {Function} + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ + function isArrayBuffer(value) { + return isObjectLike(value) && objectToString.call(value) == arrayBufferTag; + } + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && objectToString.call(value) == boolTag); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = !Buffer ? constant(false) : function(value) { + return value instanceof Buffer; + }; + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + function isDate(value) { + return isObjectLike(value) && objectToString.call(value) == dateTag; + } + + /** + * Checks if `value` is likely a DOM element. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); + } + + /** + * Checks if `value` is an empty collection or object. A value is considered + * empty if it's an `arguments` object, array, string, or jQuery-like collection + * with a length of `0` or has no own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (isArrayLike(value) && + (isArray(value) || isString(value) || + isFunction(value.splice) || isArguments(value))) { + return !value.length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are **not** supported. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ + function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + if (!isObjectLike(value)) { + return false; + } + return (objectToString.call(value) == errorTag) || + (typeof value.message == 'string' && typeof value.name == 'string'); + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MAX_VALUE); + * // => true + * + * _.isFinite(3.14); + * // => true + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8 which returns 'object' for typed array and weak map constructors, + // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is an integer. + * + * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ + function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ + function isMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; + } + + /** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. This method is + * equivalent to a `_.matches` function when `source` is partially applied. + * + * **Note:** This method supports comparing the same values as `_.isEqual`. + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + */ + function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); + } + + /** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ + function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseIsMatch(object, source, getMatchData(source), customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(funcToString.call(value)); + } + return isObjectLike(value) && + (isHostObject(value) ? reIsNative : reIsHostCtor).test(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ + function isNil(value) { + return value == null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && objectToString.call(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || + objectToString.call(value) != objectTag || isHostObject(value)) { + return false; + } + var proto = getPrototypeOf(value); + if (proto === null) { + return true; + } + var Ctor = proto.constructor; + return (typeof Ctor == 'function' && + Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + function isRegExp(value) { + return isObject(value) && objectToString.call(value) == regexpTag; + } + + /** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ + function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ + function isSet(value) { + return isObjectLike(value) && getTag(value) == setTag; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + function isTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ + function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; + } + + /** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ + function isWeakSet(value) { + return isObjectLike(value) && objectToString.call(value) == weakSetTag; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + function lt(value, other) { + return value < other; + } + + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ + function lte(value, other) { + return value <= other; + } + + /** + * Converts `value` to an array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!value) { + return []; + } + if (isArrayLike(value)) { + return isString(value) ? stringToArray(value) : copyArray(value); + } + if (iteratorSymbol && value[iteratorSymbol]) { + return iteratorToArray(value[iteratorSymbol]()); + } + var tag = getTag(value), + func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); + + return func(value); + } + + /** + * Converts `value` to an integer. + * + * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3'); + * // => 3 + */ + function toInteger(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + var remainder = value % 1; + return value === value ? (remainder ? value - remainder : value) : 0; + } + + /** + * Converts `value` to an integer suitable for use as the length of an + * array-like object. + * + * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toLength(3); + * // => 3 + * + * _.toLength(Number.MIN_VALUE); + * // => 0 + * + * _.toLength(Infinity); + * // => 4294967295 + * + * _.toLength('3'); + * // => 3 + */ + function toLength(value) { + return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3); + * // => 3 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3'); + * // => 3 + */ + function toNumber(value) { + if (isObject(value)) { + var other = isFunction(value.valueOf) ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable + * properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * Converts `value` to a safe integer. A safe integer can be compared and + * represented correctly. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toSafeInteger(3); + * // => 3 + * + * _.toSafeInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toSafeInteger(Infinity); + * // => 9007199254740991 + * + * _.toSafeInteger('3'); + * // => 3 + */ + function toSafeInteger(value) { + return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER); + } + + /** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to process. + * @returns {string} Returns the string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (value == null) { + return ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source objects to the destination + * object. Source objects are applied from left to right. Subsequent sources + * overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.c = 3; + * } + * + * function Bar() { + * this.e = 5; + * } + * + * Foo.prototype.d = 4; + * Bar.prototype.f = 6; + * + * _.assign({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3, 'e': 5 } + */ + var assign = createAssigner(function(object, source) { + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } + }); + + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * function Bar() { + * this.d = 4; + * } + * + * Foo.prototype.c = 3; + * Bar.prototype.e = 5; + * + * _.assignIn({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 } + */ + var assignIn = createAssigner(function(object, source) { + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keysIn(source), object); + return; + } + for (var key in source) { + assignValue(object, key, source[key]); + } + }); + + /** + * This method is like `_.assignIn` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keysIn(source), object, customizer); + }); + + /** + * This method is like `_.assign` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keys(source), object, customizer); + }); + + /** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths of elements to pick, + * specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + * + * _.at(['a', 'b', 'c'], 0, 2); + * // => ['a', 'c'] + */ + var at = rest(function(object, paths) { + return baseAt(object, baseFlatten(paths, 1)); + }); + + /** + * Creates an object that inherits from the `prototype` object. If a `properties` + * object is given its own enumerable properties are assigned to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? baseAssign(result, properties) : result; + } + + /** + * Assigns own and inherited enumerable properties of source objects to the + * destination object for all destination properties that resolve to `undefined`. + * Source objects are applied from left to right. Once a property is set, + * additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var defaults = rest(function(args) { + args.push(undefined, assignInDefaults); + return apply(assignInWith, undefined, args); + }); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } + * + */ + var defaultsDeep = rest(function(args) { + args.push(undefined, mergeDefaults); + return apply(mergeWith, undefined, args); + }); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFind(object, getIteratee(predicate, 3), baseForOwn, true); + } + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + function findLastKey(object, predicate) { + return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true); + } + + /** + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The iteratee is invoked with three arguments: + * (value, key, object). Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed) + */ + function forIn(object, iteratee) { + return object == null + ? object + : baseFor(object, baseCastFunction(iteratee), keysIn); + } + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c' + */ + function forInRight(object, iteratee) { + return object == null + ? object + : baseForRight(object, baseCastFunction(iteratee), keysIn); + } + + /** + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The iteratee is invoked with three arguments: + * (value, key, object). Iteratee functions may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' then 'b' (iteration order is not guaranteed) + */ + function forOwn(object, iteratee) { + return object && baseForOwn(object, baseCastFunction(iteratee)); + } + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b' + */ + function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, baseCastFunction(iteratee)); + } + + /** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ + function functions(object) { + return object == null ? [] : baseFunctions(object, keys(object)); + } + + /** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ + function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + function has(object, path) { + return hasPath(object, path, baseHas); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b.c'); + * // => true + * + * _.hasIn(object, ['a', 'b', 'c']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return hasPath(object, path, baseHasIn); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite property + * assignments of previous values. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ + var invert = createInverter(function(result, value, key) { + result[value] = key; + }, constant(identity)); + + /** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` through `iteratee`. + * The corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ + var invertBy = createInverter(function(result, value, key) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + }, getIteratee); + + /** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ + var invoke = rest(baseInvoke); + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + var isProto = isPrototype(object); + if (!(isProto || isArrayLike(object))) { + return baseKeys(object); + } + var indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + for (var key in object) { + if (baseHas(object, key) && + !(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(isProto && key == 'constructor')) { + result.push(key); + } + } + return result; + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + var index = -1, + isProto = isPrototype(object), + props = baseKeysIn(object), + propsLength = props.length, + indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + while (++index < propsLength) { + var key = props[index]; + if (!(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * property of `object` through `iteratee`. The iteratee is invoked with + * three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + function mapKeys(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + result[iteratee(value, key, object)] = value; + }); + return result; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through `iteratee`. The + * iteratee is invoked with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + result[key] = iteratee(value, key, object); + }); + return result; + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable properties of source objects into the destination + * object. Source properties that resolve to `undefined` are skipped if a + * destination value exists. Array and plain object properties are merged + * recursively.Other objects and value types are overridden by assignment. + * Source objects are applied from left to right. Subsequent sources + * overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined` merging is handled by the + * method instead. The `customizer` is invoked with seven arguments: + * (objValue, srcValue, key, object, source, stack). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.mergeWith(object, other, customizer); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { + baseMerge(object, source, srcIndex, customizer); + }); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [props] The property names to omit, specified + * individually or in arrays. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } + */ + var omit = rest(function(object, props) { + if (object == null) { + return {}; + } + props = arrayMap(baseFlatten(props, 1), String); + return basePick(object, baseDifference(keysIn(object), props)); + }); + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable properties of `object` that `predicate` + * doesn't return truthy for. The predicate is invoked with two arguments: + * (value, key). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + predicate = getIteratee(predicate); + return basePickBy(object, function(value, key) { + return !predicate(value, key); + }); + } + + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [props] The property names to pick, specified + * individually or in arrays. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + var pick = rest(function(object, props) { + return object == null ? {} : basePick(object, baseFlatten(props, 1)); + }); + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + return object == null ? {} : basePickBy(object, getIteratee(predicate)); + } + + /** + * This method is like `_.get` except that if the resolved value is a function + * it's invoked with the `this` binding of its parent object and its result + * is returned. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + if (!isKey(path, object)) { + path = baseCastPath(path); + var result = get(object, path); + object = parent(object, path); + } else { + result = object == null ? undefined : object[path]; + } + if (result === undefined) { + result = defaultValue; + } + return isFunction(result) ? result.call(object) : result; + } + + /** + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, 'x[0].y.z', 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + return object == null ? object : baseSet(object, path, value); + } + + /** + * This method is like `_.set` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.setWith(object, '[0][1]', 'a', Object); + * // => { '0': { '1': 'a' } } + */ + function setWith(object, path, value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseSet(object, path, value, customizer); + } + + /** + * Creates an array of own enumerable key-value pairs for `object` which + * can be consumed by `_.fromPairs`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairs(new Foo); + * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) + */ + function toPairs(object) { + return baseToPairs(object, keys(object)); + } + + /** + * Creates an array of own and inherited enumerable key-value pairs for + * `object` which can be consumed by `_.fromPairs`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairsIn(new Foo); + * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed) + */ + function toPairsIn(object) { + return baseToPairs(object, keysIn(object)); + } + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own enumerable + * properties through `iteratee`, with each invocation potentially mutating + * the `accumulator` object. The iteratee is invoked with four arguments: + * (accumulator, value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Array|Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }, []); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function transform(object, iteratee, accumulator) { + var isArr = isArray(object) || isTypedArray(object); + iteratee = getIteratee(iteratee, 4); + + if (accumulator == null) { + if (isArr || isObject(object)) { + var Ctor = object.constructor; + if (isArr) { + accumulator = isArray(object) ? new Ctor : []; + } else { + accumulator = isFunction(Ctor) ? baseCreate(getPrototypeOf(object)) : {}; + } + } else { + accumulator = {}; + } + } + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Removes the property at `path` of `object`. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 7 } }] }; + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + * + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + */ + function unset(object, path) { + return object == null ? true : baseUnset(object, path); + } + + /** + * This method is like `_.set` except that accepts `updater` to produce the + * value to set. Use `_.updateWith` to customize `path` creation. The `updater` + * is invoked with one argument: (value). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.update(object, 'a[0].b.c', function(n) { return n * n; }); + * console.log(object.a[0].b.c); + * // => 9 + * + * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); + * console.log(object.x[0].y.z); + * // => 0 + */ + function update(object, path, updater) { + return object == null ? object : baseUpdate(object, path, baseCastFunction(updater)); + } + + /** + * This method is like `_.update` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.updateWith(object, '[0][1]', _.constant('a'), Object); + * // => { '0': { '1': 'a' } } + */ + function updateWith(object, path, updater, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseUpdate(object, path, baseCastFunction(updater), customizer); + } + + /** + * Creates an array of the own enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object ? baseValues(object, keys(object)) : []; + } + + /** + * Creates an array of the own and inherited enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return object == null ? [] : baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ + function clamp(number, lower, upper) { + if (upper === undefined) { + upper = lower; + lower = undefined; + } + if (upper !== undefined) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); + } + + /** + * Checks if `n` is between `start` and up to but not including, `end`. If + * `end` is not specified it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. + * + * @static + * @memberOf _ + * @category Number + * @param {number} number The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + * + * _.inRange(-3, -2, -6); + * // => true + */ + function inRange(number, start, end) { + start = toNumber(start) || 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = toNumber(end) || 0; + } + number = toNumber(number); + return baseInRange(number, start, end); + } + + /** + * Produces a random number between the inclusive `lower` and `upper` bounds. + * If only one argument is provided a number between `0` and the given number + * is returned. If `floating` is `true`, or either `lower` or `upper` are floats, + * a floating-point number is returned instead of an integer. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @memberOf _ + * @category Number + * @param {number} [lower=0] The lower bound. + * @param {number} [upper=1] The upper bound. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(lower, upper, floating) { + if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { + upper = floating = undefined; + } + if (floating === undefined) { + if (typeof upper == 'boolean') { + floating = upper; + upper = undefined; + } + else if (typeof lower == 'boolean') { + floating = lower; + lower = undefined; + } + } + if (lower === undefined && upper === undefined) { + lower = 0; + upper = 1; + } + else { + lower = toNumber(lower) || 0; + if (upper === undefined) { + upper = lower; + lower = 0; + } else { + upper = toNumber(upper) || 0; + } + } + if (lower > upper) { + var temp = lower; + lower = upper; + upper = temp; + } + if (floating || lower % 1 || upper % 1) { + var rand = nativeRandom(); + return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); + } + return baseRandom(lower, upper); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar'); + * // => 'fooBar' + * + * _.camelCase('__foo_bar__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); + }); + + /** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ + function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); + } + + /** + * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = toString(string); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search from. + * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = toString(string); + target = typeof target == 'string' ? target : (target + ''); + + var length = string.length; + position = position === undefined + ? length + : baseClamp(toInteger(position), 0, length); + + position -= target.length; + return position >= 0 && string.indexOf(target, position) == position; + } + + /** + * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in IE < 9, they can break out of + * attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ + function escapeRegExp(string) { + string = toString(string); + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string; + } + + /** + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Converts `string`, as space separated words, to lower case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the lower cased string. + * @example + * + * _.lowerCase('--Foo-Bar'); + * // => 'foo bar' + * + * _.lowerCase('fooBar'); + * // => 'foo bar' + * + * _.lowerCase('__FOO_BAR__'); + * // => 'foo bar' + */ + var lowerCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + word.toLowerCase(); + }); + + /** + * Converts the first character of `string` to lower case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.lowerFirst('Fred'); + * // => 'fred' + * + * _.lowerFirst('FRED'); + * // => 'fRED' + */ + var lowerFirst = createCaseFirst('toLowerCase'); + + /** + * Converts the first character of `string` to upper case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.upperFirst('fred'); + * // => 'Fred' + * + * _.upperFirst('FRED'); + * // => 'FRED' + */ + var upperFirst = createCaseFirst('toUpperCase'); + + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = stringSize(string); + if (!length || strLength >= length) { + return string; + } + var mid = (length - strLength) / 2, + leftLength = nativeFloor(mid), + rightLength = nativeCeil(mid); + + return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars); + } + + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padEnd('abc', 6); + * // => 'abc ' + * + * _.padEnd('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padEnd('abc', 3); + * // => 'abc' + */ + function padEnd(string, length, chars) { + string = toString(string); + return string + createPadding(string, length, chars); + } + + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padStart('abc', 6); + * // => ' abc' + * + * _.padStart('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padStart('abc', 3); + * // => 'abc' + */ + function padStart(string, length, chars) { + string = toString(string); + return createPadding(string, length, chars) + string; + } + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, + * in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2) + * of `parseInt`. + * + * @static + * @memberOf _ + * @category String + * @param {string} string The string to convert. + * @param {number} [radix=10] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + // Chrome fails to trim leading whitespace characters. + // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. + if (guard || radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + string = toString(string).replace(reTrim, ''); + return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=0] The number of times to repeat the string. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n) { + string = toString(string); + n = toInteger(n); + + var result = ''; + if (!string || n < 1 || n > MAX_SAFE_INTEGER) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + string += string; + } while (n); + + return result; + } + + /** + * Replaces matches for `pattern` in `string` with `replacement`. + * + * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to modify. + * @param {RegExp|string} pattern The pattern to replace. + * @param {Function|string} replacement The match replacement. + * @returns {string} Returns the modified string. + * @example + * + * _.replace('Hi Fred', 'Fred', 'Barney'); + * // => 'Hi Barney' + */ + function replace() { + var args = arguments, + string = toString(args[0]); + + return args.length < 3 ? string : string.replace(args[1], args[2]); + } + + /** + * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--foo-bar'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Splits `string` by `separator`. + * + * **Note:** This method is based on [`String#split`](https://mdn.io/String/split). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to split. + * @param {RegExp|string} separator The separator pattern to split by. + * @param {number} [limit] The length to truncate results to. + * @returns {Array} Returns the new array of string segments. + * @example + * + * _.split('a-b-c', '-', 2); + * // => ['a', 'b'] + */ + function split(string, separator, limit) { + return toString(string).split(separator, limit); + } + + /** + * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + capitalize(word); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = toString(string); + position = baseClamp(toInteger(position), 0, string.length); + return string.lastIndexOf(target, position) == position; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is given it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as free variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. + * @param {string} [options.variable] The data object variable name. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the compiled template function. + * @example + * + * // Use the "interpolate" delimiter to create a compiled template. + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // Use the HTML "escape" delimiter to escape data property values. + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': ' +
diff --git a/platforms/android/assets/www/node_modules/sax/README.md b/platforms/android/assets/www/node_modules/sax/README.md new file mode 100644 index 0000000..c965242 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/README.md @@ -0,0 +1,216 @@ +# sax js + +A sax-style parser for XML and HTML. + +Designed with [node](http://nodejs.org/) in mind, but should work fine in +the browser or other CommonJS implementations. + +## What This Is + +* A very simple tool to parse through an XML string. +* A stepping stone to a streaming HTML parser. +* A handy way to deal with RSS and other mostly-ok-but-kinda-broken XML + docs. + +## What This Is (probably) Not + +* An HTML Parser - That's a fine goal, but this isn't it. It's just + XML. +* A DOM Builder - You can use it to build an object model out of XML, + but it doesn't do that out of the box. +* XSLT - No DOM = no querying. +* 100% Compliant with (some other SAX implementation) - Most SAX + implementations are in Java and do a lot more than this does. +* An XML Validator - It does a little validation when in strict mode, but + not much. +* A Schema-Aware XSD Thing - Schemas are an exercise in fetishistic + masochism. +* A DTD-aware Thing - Fetching DTDs is a much bigger job. + +## Regarding `Hello, world!').close(); + + // stream usage + // takes the same options as the parser + var saxStream = require("sax").createStream(strict, options) + saxStream.on("error", function (e) { + // unhandled errors will throw, since this is a proper node + // event emitter. + console.error("error!", e) + // clear the error + this._parser.error = null + this._parser.resume() + }) + saxStream.on("opentag", function (node) { + // same object as above + }) + // pipe is supported, and it's readable/writable + // same chunks coming in also go out. + fs.createReadStream("file.xml") + .pipe(saxStream) + .pipe(fs.createWriteStream("file-copy.xml")) + + + +## Arguments + +Pass the following arguments to the parser function. All are optional. + +`strict` - Boolean. Whether or not to be a jerk. Default: `false`. + +`opt` - Object bag of settings regarding string formatting. All default to `false`. + +Settings supported: + +* `trim` - Boolean. Whether or not to trim text and comment nodes. +* `normalize` - Boolean. If true, then turn any whitespace into a single + space. +* `lowercase` - Boolean. If true, then lowercase tag names and attribute names + in loose mode, rather than uppercasing them. +* `xmlns` - Boolean. If true, then namespaces are supported. +* `position` - Boolean. If false, then don't track line/col/position. + +## Methods + +`write` - Write bytes onto the stream. You don't have to do this all at +once. You can keep writing as much as you want. + +`close` - Close the stream. Once closed, no more data may be written until +it is done processing the buffer, which is signaled by the `end` event. + +`resume` - To gracefully handle errors, assign a listener to the `error` +event. Then, when the error is taken care of, you can call `resume` to +continue parsing. Otherwise, the parser will not continue while in an error +state. + +## Members + +At all times, the parser object will have the following members: + +`line`, `column`, `position` - Indications of the position in the XML +document where the parser currently is looking. + +`startTagPosition` - Indicates the position where the current tag starts. + +`closed` - Boolean indicating whether or not the parser can be written to. +If it's `true`, then wait for the `ready` event to write again. + +`strict` - Boolean indicating whether or not the parser is a jerk. + +`opt` - Any options passed into the constructor. + +`tag` - The current tag being dealt with. + +And a bunch of other stuff that you probably shouldn't touch. + +## Events + +All events emit with a single argument. To listen to an event, assign a +function to `on`. Functions get executed in the this-context of +the parser object. The list of supported events are also in the exported +`EVENTS` array. + +When using the stream interface, assign handlers using the EventEmitter +`on` function in the normal fashion. + +`error` - Indication that something bad happened. The error will be hanging +out on `parser.error`, and must be deleted before parsing can continue. By +listening to this event, you can keep an eye on that kind of stuff. Note: +this happens *much* more in strict mode. Argument: instance of `Error`. + +`text` - Text node. Argument: string of text. + +`doctype` - The ``. Argument: +object with `name` and `body` members. Attributes are not parsed, as +processing instructions have implementation dependent semantics. + +`sgmldeclaration` - Random SGML declarations. Stuff like `` +would trigger this kind of event. This is a weird thing to support, so it +might go away at some point. SAX isn't intended to be used to parse SGML, +after all. + +`opentag` - An opening tag. Argument: object with `name` and `attributes`. +In non-strict mode, tag names are uppercased, unless the `lowercase` +option is set. If the `xmlns` option is set, then it will contain +namespace binding information on the `ns` member, and will have a +`local`, `prefix`, and `uri` member. + +`closetag` - A closing tag. In loose mode, tags are auto-closed if their +parent closes. In strict mode, well-formedness is enforced. Note that +self-closing tags will have `closeTag` emitted immediately after `openTag`. +Argument: tag name. + +`attribute` - An attribute node. Argument: object with `name` and `value`. +In non-strict mode, attribute names are uppercased, unless the `lowercase` +option is set. If the `xmlns` option is set, it will also contains namespace +information. + +`comment` - A comment node. Argument: the string of the comment. + +`opencdata` - The opening tag of a ``) of a `` tags trigger a `"script"` +event, and their contents are not checked for special xml characters. +If you pass `noscript: true`, then this behavior is suppressed. + +## Reporting Problems + +It's best to write a failing test if you find an issue. I will always +accept pull requests with failing tests if they demonstrate intended +behavior, but it is very hard to figure out what issue you're describing +without a test. Writing a test is also the best way for you yourself +to figure out if you really understand the issue you think you have with +sax-js. diff --git a/platforms/android/assets/www/node_modules/sax/examples/big-not-pretty.xml b/platforms/android/assets/www/node_modules/sax/examples/big-not-pretty.xml new file mode 100644 index 0000000..fb5265d --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/examples/big-not-pretty.xml @@ -0,0 +1,8002 @@ + + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + diff --git a/platforms/android/assets/www/node_modules/sax/examples/example.js b/platforms/android/assets/www/node_modules/sax/examples/example.js new file mode 100644 index 0000000..7b0246e --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/examples/example.js @@ -0,0 +1,29 @@ + +var fs = require("fs"), + util = require("util"), + path = require("path"), + xml = fs.readFileSync(path.join(__dirname, "test.xml"), "utf8"), + sax = require("../lib/sax"), + strict = sax.parser(true), + loose = sax.parser(false, {trim:true}), + inspector = function (ev) { return function (data) { + console.error("%s %s %j", this.line+":"+this.column, ev, data); + }}; + +sax.EVENTS.forEach(function (ev) { + loose["on"+ev] = inspector(ev); +}); +loose.onend = function () { + console.error("end"); + console.error(loose); +}; + +// do this in random bits at a time to verify that it works. +(function () { + if (xml) { + var c = Math.ceil(Math.random() * 1000) + loose.write(xml.substr(0,c)); + xml = xml.substr(c); + process.nextTick(arguments.callee); + } else loose.close(); +})(); diff --git a/platforms/android/assets/www/node_modules/sax/examples/get-products.js b/platforms/android/assets/www/node_modules/sax/examples/get-products.js new file mode 100644 index 0000000..9e8d74a --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/examples/get-products.js @@ -0,0 +1,58 @@ +// pull out /GeneralSearchResponse/categories/category/items/product tags +// the rest we don't care about. + +var sax = require("../lib/sax.js") +var fs = require("fs") +var path = require("path") +var xmlFile = path.resolve(__dirname, "shopping.xml") +var util = require("util") +var http = require("http") + +fs.readFile(xmlFile, function (er, d) { + http.createServer(function (req, res) { + if (er) throw er + var xmlstr = d.toString("utf8") + + var parser = sax.parser(true) + var products = [] + var product = null + var currentTag = null + + parser.onclosetag = function (tagName) { + if (tagName === "product") { + products.push(product) + currentTag = product = null + return + } + if (currentTag && currentTag.parent) { + var p = currentTag.parent + delete currentTag.parent + currentTag = p + } + } + + parser.onopentag = function (tag) { + if (tag.name !== "product" && !product) return + if (tag.name === "product") { + product = tag + } + tag.parent = currentTag + tag.children = [] + tag.parent && tag.parent.children.push(tag) + currentTag = tag + } + + parser.ontext = function (text) { + if (currentTag) currentTag.children.push(text) + } + + parser.onend = function () { + var out = util.inspect(products, false, 3, true) + res.writeHead(200, {"content-type":"application/json"}) + res.end("{\"ok\":true}") + // res.end(JSON.stringify(products)) + } + + parser.write(xmlstr).end() + }).listen(1337) +}) diff --git a/platforms/android/assets/www/node_modules/sax/examples/hello-world.js b/platforms/android/assets/www/node_modules/sax/examples/hello-world.js new file mode 100644 index 0000000..cbfa518 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/examples/hello-world.js @@ -0,0 +1,4 @@ +require("http").createServer(function (req, res) { + res.writeHead(200, {"content-type":"application/json"}) + res.end(JSON.stringify({ok: true})) +}).listen(1337) diff --git a/platforms/android/assets/www/node_modules/sax/examples/not-pretty.xml b/platforms/android/assets/www/node_modules/sax/examples/not-pretty.xml new file mode 100644 index 0000000..9592852 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/examples/not-pretty.xml @@ -0,0 +1,8 @@ + + something blerm a bit down here diff --git a/platforms/android/assets/www/node_modules/sax/examples/pretty-print.js b/platforms/android/assets/www/node_modules/sax/examples/pretty-print.js new file mode 100644 index 0000000..cd6aca9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/examples/pretty-print.js @@ -0,0 +1,74 @@ +var sax = require("../lib/sax") + , printer = sax.createStream(false, {lowercasetags:true, trim:true}) + , fs = require("fs") + +function entity (str) { + return str.replace('"', '"') +} + +printer.tabstop = 2 +printer.level = 0 +printer.indent = function () { + print("\n") + for (var i = this.level; i > 0; i --) { + for (var j = this.tabstop; j > 0; j --) { + print(" ") + } + } +} +printer.on("opentag", function (tag) { + this.indent() + this.level ++ + print("<"+tag.name) + for (var i in tag.attributes) { + print(" "+i+"=\""+entity(tag.attributes[i])+"\"") + } + print(">") +}) + +printer.on("text", ontext) +printer.on("doctype", ontext) +function ontext (text) { + this.indent() + print(text) +} + +printer.on("closetag", function (tag) { + this.level -- + this.indent() + print("") +}) + +printer.on("cdata", function (data) { + this.indent() + print("") +}) + +printer.on("comment", function (comment) { + this.indent() + print("") +}) + +printer.on("error", function (error) { + console.error(error) + throw error +}) + +if (!process.argv[2]) { + throw new Error("Please provide an xml file to prettify\n"+ + "TODO: read from stdin or take a file") +} +var xmlfile = require("path").join(process.cwd(), process.argv[2]) +var fstr = fs.createReadStream(xmlfile, { encoding: "utf8" }) + +function print (c) { + if (!process.stdout.write(c)) { + fstr.pause() + } +} + +process.stdout.on("drain", function () { + fstr.resume() +}) + +fstr.pipe(printer) diff --git a/platforms/android/assets/www/node_modules/sax/examples/shopping.xml b/platforms/android/assets/www/node_modules/sax/examples/shopping.xml new file mode 100644 index 0000000..223c6c6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/examples/shopping.xml @@ -0,0 +1,2 @@ + +sandbox3.1 r31.Kadu4DC.phase357782011.10.06 15:37:23 PSTp2.a121bc2aaf029435dce62011-10-21T18:38:45.982-04:00P0Y0M0DT0H0M0.169S1112You are currently using the SDC API sandbox environment! No clicks to merchant URLs from this response will be paid. Please change the host of your API requests to 'publisher.api.shopping.com' when you have finished development and testinghttp://statTest.dealtime.com/pixel/noscript?PV_EvnTyp=APPV&APPV_APITSP=10%2F21%2F11_06%3A38%3A45_PM&APPV_DSPRQSID=p2.a121bc2aaf029435dce6&APPV_IMGURL=http://img.shopping.com/sc/glb/sdc_logo_106x19.gif&APPV_LI_LNKINID=7000610&APPV_LI_SBMKYW=nikon&APPV_MTCTYP=1000&APPV_PRTID=2002&APPV_BrnID=14804http://www.shopping.com/digital-cameras/productsDigital CamerasDigital CamerasElectronicshttp://www.shopping.com/xCH-electronics-nikon~linkin_id-7000610?oq=nikonCameras and Photographyhttp://www.shopping.com/xCH-cameras_and_photography-nikon~linkin_id-7000610?oq=nikonDigital Camerashttp://www.shopping.com/digital-cameras/nikon/products?oq=nikon&linkin_id=7000610nikonnikonDigital Camerashttp://www.shopping.com/digital-cameras/nikon/products?oq=nikon&linkin_id=7000610Nikon D3100 Digital Camera14.2 Megapixel, SLR Camera, 3 in. LCD Screen, With High Definition Video, Weight: 1 lb.The Nikon D3100 digital SLR camera speaks to the growing ranks of enthusiastic D-SLR users and aspiring photographers by providing an easy-to-use and affordable entrance to the world of Nikon D-SLR’s. The 14.2-megapixel D3100 has powerful features, such as the enhanced Guide Mode that makes it easy to unleash creative potential and capture memories with still images and full HD video. Like having a personal photo tutor at your fingertips, this unique feature provides a simple graphical interface on the camera’s LCD that guides users by suggesting and/or adjusting camera settings to achieve the desired end result images. The D3100 is also the world’s first D-SLR to introduce full time auto focus (AF) in Live View and D-Movie mode to effortlessly achieve the critical focus needed when shooting Full HD 1080p video.http://di1.shopping.com/images/pi/93/bc/04/101677489-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-606x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=194.56http://img.shopping.com/sc/pr/sdc_stars_sm_4.5.gifhttp://www.shopping.com/Nikon-D3100/reviews~linkin_id-7000610429.001360.00http://www.shopping.com/Nikon-D3100/prices~linkin_id-7000610http://www.shopping.com/Nikon-D3100/info~linkin_id-7000610Nikon D3100 Digital SLR Camera with 18-55mm NIKKOR VR LensThe Nikon D3100 Digital SLR Camera is an affordable compact and lightweight photographic power-house. It features the all-purpose 18-55mm VR lens a high-resolution 14.2 MP CMOS sensor along with a feature set that's comprehensive yet easy to navigate - the intuitive onboard learn-as-you grow guide mode allows the photographer to understand what the 3100 can do quickly and easily. Capture beautiful pictures and amazing Full HD 1080p movies with sound and full-time autofocus. Availabilty: In Stock!7185Nikonhttp://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-350x350-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stockFree Shipping with Any Purchase!529.000.00799.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=647&BEFID=7185&aon=%5E1&MerchantID=475674&crawler_id=475674&dealId=-ZW6BMZqz6fbS-aULwga_g%3D%3D&url=http%3A%2F%2Fwww.fumfie.com%2Fproduct%2F343.5%2Fshopping-com%3F&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D3100+Digital+SLR+Camera+with+18-55mm+NIKKOR+VR+Lens&dlprc=529.0&crn=&istrsmrc=1&isathrsl=0&AR=1&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=1&cid=&semid1=&semid2=&IsLps=0&CC=1&SL=1&FS=1&code=&acode=658&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=FumFiehttp://img.shopping.com/cctool/merch_logos/475674.gif866 666 91985604.27http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_fumfie~MRD-475674~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSF343C5Nikon Nikon D3100 14.2MP Digital SLR Camera with 18-55mm f/3.5-5.6 AF-S DX VR, CamerasNikon D3100 14.2MP Digital SLR Camera with 18-55mm f/3.5-5.6 AF-S DX VR7185Nikonhttp://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-385x352-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stock549.000.00549.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=779&BEFID=7185&aon=%5E1&MerchantID=305814&crawler_id=305814&dealId=md1e9lD8vdOu4FHQfJqKng%3D%3D&url=http%3A%2F%2Fwww.electronics-expo.com%2Findex.php%3Fpage%3Ditem%26id%3DNIKD3100%26source%3DSideCar%26scpid%3D8%26scid%3Dscsho318727%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+Nikon+D3100+14.2MP+Digital+SLR+Camera+with+18-55mm+f%2F3.5-5.6+AF-S+DX+VR%2C+Cameras&dlprc=549.0&crn=&istrsmrc=1&isathrsl=0&AR=9&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=9&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=771&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Electronics Expohttp://img.shopping.com/cctool/merch_logos/305814.gif1-888-707-EXPO3713.90http://img.shopping.com/sc/mr/sdc_checks_4.gifhttp://www.shopping.com/xMR-store_electronics_expo~MRD-305814~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSNIKD3100Nikon D3100 14.2-Megapixel Digital SLR Camera With 18-55mm Zoom-Nikkor Lens, BlackSplit-second shutter response captures shots other cameras may have missed Helps eliminate the frustration of shutter delay! 14.2-megapixels for enlargements worth framing and hanging. Takes breathtaking 1080p HD movies. ISO sensitivity from 100-1600 for bright or dimly lit settings. 3.0in. color LCD for beautiful, wide-angle framing and viewing. In-camera image editing lets you retouch with no PC. Automatic scene modes include Child, Sports, Night Portrait and more. Accepts SDHC memory cards. Nikon D3100 14.2-Megapixel Digital SLR Camera With 18-55mm Zoom-Nikkor Lens, Black is one of many Digital SLR Cameras available through Office Depot. Made by Nikon.7185Nikonhttp://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-250x250-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stock549.990.00699.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=698&BEFID=7185&aon=%5E1&MerchantID=467671&crawler_id=467671&dealId=yYuaXnDFtCY7rDUjkY2aaw%3D%3D&url=http%3A%2F%2Flink.mercent.com%2Fredirect.ashx%3Fmr%3AmerchantID%3DOfficeDepot%26mr%3AtrackingCode%3DCEC9669E-6ABC-E011-9F24-0019B9C043EB%26mr%3AtargetUrl%3Dhttp%3A%2F%2Fwww.officedepot.com%2Fa%2Fproducts%2F486292%2FNikon-D3100-142-Megapixel-Digital-SLR%2F%253fcm_mmc%253dMercent-_-Shopping-_-Cameras_and_Camcorders-_-486292&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D3100+14.2-Megapixel+Digital+SLR+Camera+With+18-55mm+Zoom-Nikkor+Lens%2C+Black&dlprc=549.99&crn=&istrsmrc=1&isathrsl=0&AR=10&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=10&cid=&semid1=&semid2=&IsLps=0&CC=1&SL=1&FS=1&code=&acode=690&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Office Depothttp://img.shopping.com/cctool/merch_logos/467671.gif1-800-GO-DEPOT1352.37http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_office_depot_4158555~MRD-467671~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS486292Nikon® D3100™ 14.2MP Digital SLR with 18-55mm LensThe Nikon D3100 DSLR will surprise you with its simplicity and impress you with superb results.7185Nikonhttp://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stock549.996.05549.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=Rl56U7CuiTYsH4MGZ02lxQ%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D903483107%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C2%AE+D3100%E2%84%A2+14.2MP+Digital+SLR+with+18-55mm+Lens&dlprc=549.99&crn=&istrsmrc=0&isathrsl=0&AR=11&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=11&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=496&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS9614867Nikon D3100 SLR w/Nikon 18-55mm VR & 55-200mm VR Lenses14.2 Megapixels3" LCDLive ViewHD 1080p Video w/ Sound & Autofocus11-point Autofocus3 Frames per Second ShootingISO 100 to 3200 (Expand to 12800-Hi2)Self Cleaning SensorEXPEED 2, Image Processing EngineScene Recognition System7185Nikonhttp://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-345x345-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stock695.000.00695.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&BEFID=7185&aon=%5E1&MerchantID=487342&crawler_id=487342&dealId=huS6xZKDKaKMTMP71eI6DA%3D%3D&url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D32983%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D3100+SLR+w%2FNikon+18-55mm+VR+%26+55-200mm+VR+Lenses&dlprc=695.0&crn=&istrsmrc=0&isathrsl=0&AR=15&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=15&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=379&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RytherCamera.comhttp://img.shopping.com/cctool/merch_logos/487342.gif1-877-644-75930http://img.shopping.com/sc/glb/flag/US.gifUS32983Nikon COOLPIX S203 Digital Camera10 Megapixel, Ultra-Compact Camera, 2.5 in. LCD Screen, 3x Optical Zoom, With Video Capability, Weight: 0.23 lb.With 10.34 mega pixel, electronic VR vibration reduction, 5-level brightness adjustment, 3x optical zoom, and TFT LCD, Nikon Coolpix s203 fulfills all the demands of any photographer. The digital camera has an inbuilt memory of 44MB and an external memory slot made for all kinds of SD (Secure Digital) cards.http://di1.shopping.com/images/pi/c4/ef/1b/95397883-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-500x499-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=20139.00139.00http://www.shopping.com/Nikon-Coolpix-S203/prices~linkin_id-7000610http://www.shopping.com/Nikon-Coolpix-S203/info~linkin_id-7000610Nikon Coolpix S203 Digital Camera (Red)With 10.34 mega pixel, electronic VR vibration reduction, 5-level brightness adjustment, 3x optical zoom, and TFT LCD, Nikon Coolpix s203 fulfills all the demands of any photographer. The digital camera has an inbuilt memory of 44MB and an external memory slot made for all kinds of SD (Secure Digital) cards.7185Nikonhttp://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stockFantastic prices with ease & comfort of Amazon.com!139.009.50139.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=566&BEFID=7185&aon=%5E1&MerchantID=301531&crawler_id=1903313&dealId=sBd2JnIEPM-A_lBAM1RZgQ%3D%3D&url=http%3A%2F%2Fwww.amazon.com%2Fdp%2FB002T964IM%2Fref%3Dasc_df_B002T964IM1751618%3Fsmid%3DA22UHVNXG98FAT%26tag%3Ddealtime-ce-mp01feed-20%26linkCode%3Dasn%26creative%3D395105%26creativeASIN%3DB002T964IM&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+Coolpix+S203+Digital+Camera+%28Red%29&dlprc=139.0&crn=&istrsmrc=0&isathrsl=0&AR=63&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=95397883&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=63&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=518&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Amazon Marketplacehttp://img.shopping.com/cctool/merch_logos/301531.gif2132.73http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_amazon_marketplace_9689~MRD-301531~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSB002T964IMNikon S3100 Digital Camera14.5 Megapixel, Compact Camera, 2.7 in. LCD Screen, 5x Optical Zoom, With High Definition Video, Weight: 0.23 lb.This digital camera features a wide-angle optical Zoom-NIKKOR glass lens that allows you to capture anything from landscapes to portraits to action shots. The high-definition movie mode with one-touch recording makes it easy to capture video clips.http://di1.shopping.com/images/pi/66/2d/33/106834268-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-507x387-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=312.00http://img.shopping.com/sc/pr/sdc_stars_sm_2.gifhttp://www.shopping.com/nikon-s3100/reviews~linkin_id-700061099.95134.95http://www.shopping.com/nikon-s3100/prices~linkin_id-7000610http://www.shopping.com/nikon-s3100/info~linkin_id-7000610CoolPix S3100 14 Megapixel Compact Digital Camera- RedNikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - red7185Nikonhttp://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stockGet 30 days FREE SHIPPING w/ ShipVantage119.956.95139.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=UUyGoqV8r0-xrkn-rnGNbg%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJ3Yx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmDAJeU1oyGG0GcBdhGwUGCAVqYF9SO0xSN1sZdmA7dmMdBQAJB24qX1NbQxI6AjA2ME5dVFULPDsGPFcQTTdaLTA6SR0OFlQvPAwMDxYcYlxIVkcoLTcCDA%3D%3D%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=CoolPix+S3100+14+Megapixel+Compact+Digital+Camera-+Red&dlprc=119.95&crn=&istrsmrc=1&isathrsl=0&AR=28&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=28&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=0&code=&acode=583&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00337013000COOLPIX S3100 PinkNikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - pink7185Nikonhttp://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stockGet 30 days FREE SHIPPING w/ ShipVantage119.956.95139.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=X87AwXlW1dXoMXk4QQDToQ%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJxYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcUFxDEGsPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=COOLPIX+S3100+Pink&dlprc=119.95&crn=&istrsmrc=1&isathrsl=0&AR=31&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=31&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=0&code=&acode=583&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00337015000Nikon Coolpix S3100 14.0 MP Digital Camera - SilverNikon Coolpix S3100 14.0 MP Digital Camera - Silver7185Nikonhttp://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-270x270-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stock109.970.00109.97http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=803&BEFID=7185&aon=%5E&MerchantID=475774&crawler_id=475774&dealId=nvFwnpfA4rlA1Dbksdsa0w%3D%3D&url=http%3A%2F%2Fwww.thewiz.com%2Fcatalog%2Fproduct.jsp%3FmodelNo%3DS3100SILVER%26gdftrk%3DgdfV2677_a_7c996_a_7c4049_a_7c26262&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+Coolpix+S3100+14.0+MP+Digital+Camera+-+Silver&dlprc=109.97&crn=&istrsmrc=0&isathrsl=0&AR=33&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=33&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=797&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=TheWiz.comhttp://img.shopping.com/cctool/merch_logos/475774.gif877-542-69880http://img.shopping.com/sc/glb/flag/US.gifUS26262Nikon� COOLPIX� S3100 14MP Digital Camera (Silver)The Nikon COOLPIX S3100 is the easy way to share your life and stay connected.7185Nikonhttp://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stock119.996.05119.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=5GtaN2NeryKwps-Se2l-4g%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D848064082%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C3%AF%C2%BF%C2%BD+COOLPIX%C3%AF%C2%BF%C2%BD+S3100+14MP+Digital+Camera+%28Silver%29&dlprc=119.99&crn=&istrsmrc=0&isathrsl=0&AR=37&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=37&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=509&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS10101095COOLPIX S3100 YellowNikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - yellow7185Nikonhttp://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stockGet 30 days FREE SHIPPING w/ ShipVantage119.956.95139.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=a43m0RXulX38zCnQjU59jw%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJwYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcUFxDEGoPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=COOLPIX+S3100+Yellow&dlprc=119.95&crn=&istrsmrc=1&isathrsl=0&AR=38&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=38&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=0&code=&acode=583&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00337014000Nikon D90 Digital Camera12.3 Megapixel, Point and Shoot Camera, 3 in. LCD Screen, With Video Capability, Weight: 1.36 lb.Untitled Document Nikon D90 SLR Digital Camera With 28-80mm 75-300mm Lens Kit The Nikon D90 SLR Digital Camera, with its 12.3-megapixel DX-format CMOS, 3" High resolution LCD display, Scene Recognition System, Picture Control, Active D-Lighting, and one-button Live View, provides photo enthusiasts with the image quality and performance they need to pursue their own vision while still being intuitive enough for use as an everyday camera.http://di1.shopping.com/images/pi/52/fb/d3/99671132-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-499x255-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=475.00http://img.shopping.com/sc/pr/sdc_stars_sm_5.gifhttp://www.shopping.com/Nikon-D90-with-18-270mm-Lens/reviews~linkin_id-7000610689.002299.00http://www.shopping.com/Nikon-D90-with-18-270mm-Lens/prices~linkin_id-7000610http://www.shopping.com/Nikon-D90-with-18-270mm-Lens/info~linkin_id-7000610Nikon® D90 12.3MP Digital SLR Camera (Body Only)The Nikon D90 will make you rethink what a digital SLR camera can achieve.7185Nikonhttp://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stock1015.996.051015.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=GU5JJkpUAxe5HujB7fkwAA%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D851830266%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C2%AE+D90+12.3MP+Digital+SLR+Camera+%28Body+Only%29&dlprc=1015.99&crn=&istrsmrc=0&isathrsl=0&AR=14&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=14&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=496&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS10148659Nikon D90 SLR Digital Camera (Camera Body)The Nikon D90 SLR Digital Camera with its 12.3-megapixel DX-format CCD 3" High resolution LCD display Scene Recognition System Picture Control Active D-Lighting and one-button Live View provides photo enthusiasts with the image quality and performance they need to pursue their own vision while still being intuitive enough for use as an everyday camera. In addition the D90 introduces the D-Movie mode allowing for the first time an interchangeable lens SLR camera that is capable of recording 720p HD movie clips. Availabilty: In Stock7185Nikonhttp://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-350x350-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stockFree Shipping with Any Purchase!689.000.00900.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=647&BEFID=7185&aon=%5E1&MerchantID=475674&crawler_id=475674&dealId=XhURuSC-spBbTIDfo4qfzQ%3D%3D&url=http%3A%2F%2Fwww.fumfie.com%2Fproduct%2F169.5%2Fshopping-com%3F&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+SLR+Digital+Camera+%28Camera+Body%29&dlprc=689.0&crn=&istrsmrc=1&isathrsl=0&AR=16&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=16&cid=&semid1=&semid2=&IsLps=0&CC=1&SL=1&FS=1&code=&acode=658&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=FumFiehttp://img.shopping.com/cctool/merch_logos/475674.gif866 666 91985604.27http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_fumfie~MRD-475674~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSF169C5Nikon D90 SLR w/Nikon 18-105mm VR & 55-200mm VR Lenses12.3 MegapixelDX Format CMOS Sensor3" VGA LCD DisplayLive ViewSelf Cleaning SensorD-Movie ModeHigh Sensitivity (ISO 3200)4.5 fps BurstIn-Camera Image Editing7185Nikonhttp://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stock1189.000.001189.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&BEFID=7185&aon=%5E1&MerchantID=487342&crawler_id=487342&dealId=o0Px_XLWDbrxAYRy3rCmyQ%3D%3D&url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D30619%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+SLR+w%2FNikon+18-105mm+VR+%26+55-200mm+VR+Lenses&dlprc=1189.0&crn=&istrsmrc=0&isathrsl=0&AR=20&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=20&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=379&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RytherCamera.comhttp://img.shopping.com/cctool/merch_logos/487342.gif1-877-644-75930http://img.shopping.com/sc/glb/flag/US.gifUS30619Nikon D90 12.3 Megapixel Digital SLR Camera (Body Only)Fusing 12.3 megapixel image quality and a cinematic 24fps D-Movie Mode, the Nikon D90 exceeds the demands of passionate photographers. Coupled with Nikon's EXPEED image processing technologies and NIKKOR optics, breathtaking image fidelity is assured. Combined with fast 0.15ms power-up and split-second 65ms shooting lag, dramatic action and decisive moments are captured easily. Effective 4-frequency, ultrasonic sensor cleaning frees image degrading dust particles from the sensor's optical low pass filter.7185Nikonhttp://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stockFREE FEDEX 2-3 DAY DELIVERY899.950.00899.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=269&BEFID=7185&aon=%5E&MerchantID=9296&crawler_id=811558&dealId=4HgbWJSJ8ssgIf8B0MXIwA%3D%3D&url=http%3A%2F%2Fwww.pcnation.com%2Foptics-gallery%2Fdetails.asp%3Faffid%3D305%26item%3D2N145P&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+12.3+Megapixel+Digital+SLR+Camera+%28Body+Only%29&dlprc=899.95&crn=&istrsmrc=1&isathrsl=0&AR=21&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=21&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=257&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=PCNationhttp://img.shopping.com/cctool/merch_logos/9296.gif800-470-707916224.43http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_pcnation_9689~MRD-9296~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS2N145PNikon D90 12.3MP Digital SLR Camera (Body Only)Fusing 12.3-megapixel image quality inherited from the award-winning D300 with groundbreaking features, the D90's breathtaking, low-noise image quality is further advanced with EXPEED image processing. Split-second shutter response and continuous shooting at up to 4.5 frames-per-second provide the power to capture fast action and precise moments perfectly, while Nikon's exclusive Scene Recognition System contributes to faster 11-area autofocus performance, finer white balance detection and more. The D90 delivers the control passionate photographers demand, utilizing comprehensive exposure functions and the intelligence of 3D Color Matrix Metering II. Stunning results come to life on a 3-inch 920,000-dot color LCD monitor, providing accurate image review, Live View composition and brilliant playback of the D90's cinematic-quality 24-fps HD D-Movie mode.7185Nikonhttp://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stockFantastic prices with ease & comfort of Amazon.com!780.000.00780.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=566&BEFID=7185&aon=%5E1&MerchantID=301531&crawler_id=1903313&dealId=UNDa3uMDZXOnvD_7sTILYg%3D%3D&url=http%3A%2F%2Fwww.amazon.com%2Fdp%2FB001ET5U92%2Fref%3Dasc_df_B001ET5U921751618%3Fsmid%3DAHF4SYKP09WBH%26tag%3Ddealtime-ce-mp01feed-20%26linkCode%3Dasn%26creative%3D395105%26creativeASIN%3DB001ET5U92&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+12.3MP+Digital+SLR+Camera+%28Body+Only%29&dlprc=780.0&crn=&istrsmrc=0&isathrsl=0&AR=29&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=29&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=520&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Amazon Marketplacehttp://img.shopping.com/cctool/merch_logos/301531.gif2132.73http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_amazon_marketplace_9689~MRD-301531~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSB001ET5U92Nikon D90 Digital Camera with 18-105mm lens12.9 Megapixel, SLR Camera, 3 in. LCD Screen, 5.8x Optical Zoom, With Video Capability, Weight: 2.3 lb.Its 12.3 megapixel DX-format CMOS image sensor and EXPEED image processing system offer outstanding image quality across a wide ISO light sensitivity range. Live View mode lets you compose and shoot via the high-resolution 3-inch LCD monitor, and an advanced Scene Recognition System and autofocus performance help capture images with astounding accuracy. Movies can be shot in Motion JPEG format using the D-Movie function. The camera’s large image sensor ensures exceptional movie image quality and you can create dramatic effects by shooting with a wide range of interchangeable NIKKOR lenses, from wide-angle to macro to fisheye, or by adjusting the lens aperture and experimenting with depth-of-field. The D90 – designed to fuel your passion for photography.http://di1.shopping.com/images/pi/57/6a/4f/70621646-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-490x489-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5324.81http://img.shopping.com/sc/pr/sdc_stars_sm_5.gifhttp://www.shopping.com/Nikon-D90-with-18-105mm-lens/reviews~linkin_id-7000610849.951599.95http://www.shopping.com/Nikon-D90-with-18-105mm-lens/prices~linkin_id-7000610http://www.shopping.com/Nikon-D90-with-18-105mm-lens/info~linkin_id-7000610Nikon D90 18-105mm VR LensThe Nikon D90 SLR Digital Camera with its 12.3-megapixel DX-format CMOS 3" High resolution LCD display Scene Recognition System Picture Control Active D-Lighting and one-button Live View prov7185Nikonhttp://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-260x260-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stock849.950.00849.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=419&BEFID=7185&aon=%5E1&MerchantID=9390&crawler_id=1905054&dealId=3o5e1VghgJPfhLvT1JFKTA%3D%3D&url=http%3A%2F%2Fwww.ajrichard.com%2FNikon-D90-18-105mm-VR-Lens%2Fp-292%3Frefid%3DShopping%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+18-105mm+VR+Lens&dlprc=849.95&crn=&istrsmrc=0&isathrsl=0&AR=2&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=2&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=425&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=AJRichardhttp://img.shopping.com/cctool/merch_logos/9390.gif1-888-871-125631244.48http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_ajrichard~MRD-9390~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS292Nikon D90 SLR w/Nikon 18-105mm VR Lens12.3 MegapixelDX Format CMOS Sensor3" VGA LCD DisplayLive ViewSelf Cleaning SensorD-Movie ModeHigh Sensitivity (ISO 3200)4.5 fps BurstIn-Camera Image Editing7185Nikonhttp://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stock909.000.00909.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&BEFID=7185&aon=%5E1&MerchantID=487342&crawler_id=487342&dealId=_lYWj_jbwfsSkfcwUcDuww%3D%3D&url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D30971%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+SLR+w%2FNikon+18-105mm+VR+Lens&dlprc=909.0&crn=&istrsmrc=0&isathrsl=0&AR=3&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=3&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=379&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RytherCamera.comhttp://img.shopping.com/cctool/merch_logos/487342.gif1-877-644-75930http://img.shopping.com/sc/glb/flag/US.gifUS3097125448/D90 12.3 Megapixel Digital Camera 18-105mm Zoom Lens w/ 3" Screen - BlackNikon D90 - Digital camera - SLR - 12.3 Mpix - Nikon AF-S DX 18-105mm lens - optical zoom: 5.8 x - supported memory: SD, SDHC7185Nikonhttp://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stockGet 30 days FREE SHIPPING w/ ShipVantage1199.008.201199.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=1KCclCGuWvty2XKU9skadg%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBRtFXpzYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcVlhCGGkPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=25448%2FD90+12.3+Megapixel+Digital+Camera+18-105mm+Zoom+Lens+w%2F+3%22+Screen+-+Black&dlprc=1199.0&crn=&istrsmrc=1&isathrsl=0&AR=4&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=4&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=586&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00353197000Nikon® D90 12.3MP Digital SLR with 18-105mm LensThe Nikon D90 will make you rethink what a digital SLR camera can achieve.7185Nikonhttp://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stock1350.996.051350.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=3-VOSfVV5Jo7HlA4kJtanA%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D982673361%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C2%AE+D90+12.3MP+Digital+SLR+with+18-105mm+Lens&dlprc=1350.99&crn=&istrsmrc=0&isathrsl=0&AR=5&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=5&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=496&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS11148905Nikon D90 Kit 12.3-megapixel Digital SLR with 18-105mm VR LensPhotographers, take your passion further!Now is the time for new creativity, and to rethink what a digital SLR camera can achieve. It's time for the D90, a camera with everything you would expect from Nikon's next-generation D-SLRs, and some unexpected surprises, as well. The stunning image quality is inherited from the D300, Nikon's DX-format flagship. The D90 also has Nikon's unmatched ergonomics and high performance, and now takes high-quality movies with beautifully cinematic results. The world of photography has changed, and with the D90 in your hands, it's time to make your own rules.AF-S DX NIKKOR 18-105mm f/3.5-5.6G ED VR LensWide-ratio 5.8x zoom Compact, versatile and ideal for a broad range of shooting situations, ranging from interiors and landscapes to beautiful portraits� a perfect everyday zoom. Nikon VR (Vibration Reduction) image stabilization Vibration Reduction is engineered specifically for each VR NIKKOR lens and enables handheld shooting at up to 3 shutter speeds slower than would7185Nikonhttp://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-300x232-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stockShipping Included!1050.000.001199.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=135&BEFID=7185&aon=%5E1&MerchantID=313162&crawler_id=313162&dealId=kQnB6rS4AjN5dx5h2_631g%3D%3D&url=http%3A%2F%2Fonecall.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1pZSxNoWHFwLx8GTAICa2ZeH1sPXTZLNzRpAh1HR0BxPQEGCBJNMhFHUElsFCFCVkVTTHAcBggEHQ4aHXNpGERGH3RQODsbAgdechJtbBt8fx8JAwhtZFAzJj1oGgIWCxRlNyFOUV9UUGIxBgo0T0IyTSYqJ0RWHw4QPCIBAAQXRGMDICg6TllZVBhh%26nAID%3D13736960&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+Kit+12.3-megapixel+Digital+SLR+with+18-105mm+VR+Lens&dlprc=1050.0&crn=&istrsmrc=1&isathrsl=0&AR=6&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=6&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=1&code=&acode=143&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=OneCallhttp://img.shopping.com/cctool/merch_logos/313162.gif1.800.398.07661804.44http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_onecall_9689~MRD-313162~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS92826Price rangehttp://www.shopping.com/digital-cameras/nikon/products?oq=nikon&linkin_id=7000610$24 - $4012http://www.shopping.com/digital-cameras/nikon/products?minPrice=24&maxPrice=4012&linkin_id=7000610$4012 - $7999http://www.shopping.com/digital-cameras/nikon/products?minPrice=4012&maxPrice=7999&linkin_id=7000610Brandhttp://www.shopping.com/digital-cameras/nikon/products~all-9688-brand~MS-1?oq=nikon&linkin_id=7000610Nikonhttp://www.shopping.com/digital-cameras/nikon+brand-nikon/products~linkin_id-7000610Cranehttp://www.shopping.com/digital-cameras/nikon+9688-brand-crane/products~linkin_id-7000610Ikelitehttp://www.shopping.com/digital-cameras/nikon+ikelite/products~linkin_id-7000610Bowerhttp://www.shopping.com/digital-cameras/nikon+bower/products~linkin_id-7000610FUJIFILMhttp://www.shopping.com/digital-cameras/nikon+brand-fuji/products~linkin_id-7000610Storehttp://www.shopping.com/digital-cameras/nikon/products~all-store~MS-1?oq=nikon&linkin_id=7000610Amazon Marketplacehttp://www.shopping.com/digital-cameras/nikon+store-amazon-marketplace-9689/products~linkin_id-7000610Amazonhttp://www.shopping.com/digital-cameras/nikon+store-amazon/products~linkin_id-7000610Adoramahttp://www.shopping.com/digital-cameras/nikon+store-adorama/products~linkin_id-7000610J&R Music and Computer Worldhttp://www.shopping.com/digital-cameras/nikon+store-j-r-music-and-computer-world/products~linkin_id-7000610RytherCamera.comhttp://www.shopping.com/digital-cameras/nikon+store-rythercamera-com/products~linkin_id-7000610Resolutionhttp://www.shopping.com/digital-cameras/nikon/products~all-21885-resolution~MS-1?oq=nikon&linkin_id=7000610Under 4 Megapixelhttp://www.shopping.com/digital-cameras/nikon+under-4-megapixel/products~linkin_id-7000610At least 5 Megapixelhttp://www.shopping.com/digital-cameras/nikon+5-megapixel-digital-cameras/products~linkin_id-7000610At least 6 Megapixelhttp://www.shopping.com/digital-cameras/nikon+6-megapixel-digital-cameras/products~linkin_id-7000610At least 7 Megapixelhttp://www.shopping.com/digital-cameras/nikon+7-megapixel-digital-cameras/products~linkin_id-7000610At least 8 Megapixelhttp://www.shopping.com/digital-cameras/nikon+8-megapixel-digital-cameras/products~linkin_id-7000610Featureshttp://www.shopping.com/digital-cameras/nikon/products~all-32804-features~MS-1?oq=nikon&linkin_id=7000610Shockproofhttp://www.shopping.com/digital-cameras/nikon+32804-features-shockproof/products~linkin_id-7000610Waterproofhttp://www.shopping.com/digital-cameras/nikon+32804-features-waterproof/products~linkin_id-7000610Freezeproofhttp://www.shopping.com/digital-cameras/nikon+32804-features-freezeproof/products~linkin_id-7000610Dust proofhttp://www.shopping.com/digital-cameras/nikon+32804-features-dust-proof/products~linkin_id-7000610Image Stabilizationhttp://www.shopping.com/digital-cameras/nikon+32804-features-image-stabilization/products~linkin_id-7000610hybriddigital camerag1sonycameracanonnikonkodak digital camerakodaksony cybershotkodak easyshare digital cameranikon coolpixolympuspink digital cameracanon powershot \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/sax/examples/strict.dtd b/platforms/android/assets/www/node_modules/sax/examples/strict.dtd new file mode 100644 index 0000000..b274559 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/examples/strict.dtd @@ -0,0 +1,870 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platforms/android/assets/www/node_modules/sax/examples/test.html b/platforms/android/assets/www/node_modules/sax/examples/test.html new file mode 100644 index 0000000..61f8f1a --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/examples/test.html @@ -0,0 +1,15 @@ + + + + + testing the parser + + + +

hello + + + + diff --git a/platforms/android/assets/www/node_modules/sax/examples/test.xml b/platforms/android/assets/www/node_modules/sax/examples/test.xml new file mode 100644 index 0000000..801292d --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/examples/test.xml @@ -0,0 +1,1254 @@ + + +]> + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/sax/lib/sax.js b/platforms/android/assets/www/node_modules/sax/lib/sax.js new file mode 100644 index 0000000..410a507 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/lib/sax.js @@ -0,0 +1,1410 @@ +// wrapper for non-node envs +;(function (sax) { + +sax.parser = function (strict, opt) { return new SAXParser(strict, opt) } +sax.SAXParser = SAXParser +sax.SAXStream = SAXStream +sax.createStream = createStream + +// When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns. +// When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)), +// since that's the earliest that a buffer overrun could occur. This way, checks are +// as rare as required, but as often as necessary to ensure never crossing this bound. +// Furthermore, buffers are only tested at most once per write(), so passing a very +// large string into write() might have undesirable effects, but this is manageable by +// the caller, so it is assumed to be safe. Thus, a call to write() may, in the extreme +// edge case, result in creating at most one complete copy of the string passed in. +// Set to Infinity to have unlimited buffers. +sax.MAX_BUFFER_LENGTH = 64 * 1024 + +var buffers = [ + "comment", "sgmlDecl", "textNode", "tagName", "doctype", + "procInstName", "procInstBody", "entity", "attribName", + "attribValue", "cdata", "script" +] + +sax.EVENTS = // for discoverability. + [ "text" + , "processinginstruction" + , "sgmldeclaration" + , "doctype" + , "comment" + , "attribute" + , "opentag" + , "closetag" + , "opencdata" + , "cdata" + , "closecdata" + , "error" + , "end" + , "ready" + , "script" + , "opennamespace" + , "closenamespace" + ] + +function SAXParser (strict, opt) { + if (!(this instanceof SAXParser)) return new SAXParser(strict, opt) + + var parser = this + clearBuffers(parser) + parser.q = parser.c = "" + parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH + parser.opt = opt || {} + parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags + parser.looseCase = parser.opt.lowercase ? "toLowerCase" : "toUpperCase" + parser.tags = [] + parser.closed = parser.closedRoot = parser.sawRoot = false + parser.tag = parser.error = null + parser.strict = !!strict + parser.noscript = !!(strict || parser.opt.noscript) + parser.state = S.BEGIN + parser.ENTITIES = Object.create(sax.ENTITIES) + parser.attribList = [] + + // namespaces form a prototype chain. + // it always points at the current tag, + // which protos to its parent tag. + if (parser.opt.xmlns) parser.ns = Object.create(rootNS) + + // mostly just for error reporting + parser.trackPosition = parser.opt.position !== false + if (parser.trackPosition) { + parser.position = parser.line = parser.column = 0 + } + emit(parser, "onready") +} + +if (!Object.create) Object.create = function (o) { + function f () { this.__proto__ = o } + f.prototype = o + return new f +} + +if (!Object.getPrototypeOf) Object.getPrototypeOf = function (o) { + return o.__proto__ +} + +if (!Object.keys) Object.keys = function (o) { + var a = [] + for (var i in o) if (o.hasOwnProperty(i)) a.push(i) + return a +} + +function checkBufferLength (parser) { + var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10) + , maxActual = 0 + for (var i = 0, l = buffers.length; i < l; i ++) { + var len = parser[buffers[i]].length + if (len > maxAllowed) { + // Text/cdata nodes can get big, and since they're buffered, + // we can get here under normal conditions. + // Avoid issues by emitting the text node now, + // so at least it won't get any bigger. + switch (buffers[i]) { + case "textNode": + closeText(parser) + break + + case "cdata": + emitNode(parser, "oncdata", parser.cdata) + parser.cdata = "" + break + + case "script": + emitNode(parser, "onscript", parser.script) + parser.script = "" + break + + default: + error(parser, "Max buffer length exceeded: "+buffers[i]) + } + } + maxActual = Math.max(maxActual, len) + } + // schedule the next check for the earliest possible buffer overrun. + parser.bufferCheckPosition = (sax.MAX_BUFFER_LENGTH - maxActual) + + parser.position +} + +function clearBuffers (parser) { + for (var i = 0, l = buffers.length; i < l; i ++) { + parser[buffers[i]] = "" + } +} + +function flushBuffers (parser) { + closeText(parser) + if (parser.cdata !== "") { + emitNode(parser, "oncdata", parser.cdata) + parser.cdata = "" + } + if (parser.script !== "") { + emitNode(parser, "onscript", parser.script) + parser.script = "" + } +} + +SAXParser.prototype = + { end: function () { end(this) } + , write: write + , resume: function () { this.error = null; return this } + , close: function () { return this.write(null) } + , flush: function () { flushBuffers(this) } + } + +try { + var Stream = require("stream").Stream +} catch (ex) { + var Stream = function () {} +} + + +var streamWraps = sax.EVENTS.filter(function (ev) { + return ev !== "error" && ev !== "end" +}) + +function createStream (strict, opt) { + return new SAXStream(strict, opt) +} + +function SAXStream (strict, opt) { + if (!(this instanceof SAXStream)) return new SAXStream(strict, opt) + + Stream.apply(this) + + this._parser = new SAXParser(strict, opt) + this.writable = true + this.readable = true + + + var me = this + + this._parser.onend = function () { + me.emit("end") + } + + this._parser.onerror = function (er) { + me.emit("error", er) + + // if didn't throw, then means error was handled. + // go ahead and clear error, so we can write again. + me._parser.error = null + } + + this._decoder = null; + + streamWraps.forEach(function (ev) { + Object.defineProperty(me, "on" + ev, { + get: function () { return me._parser["on" + ev] }, + set: function (h) { + if (!h) { + me.removeAllListeners(ev) + return me._parser["on"+ev] = h + } + me.on(ev, h) + }, + enumerable: true, + configurable: false + }) + }) +} + +SAXStream.prototype = Object.create(Stream.prototype, + { constructor: { value: SAXStream } }) + +SAXStream.prototype.write = function (data) { + if (typeof Buffer === 'function' && + typeof Buffer.isBuffer === 'function' && + Buffer.isBuffer(data)) { + if (!this._decoder) { + var SD = require('string_decoder').StringDecoder + this._decoder = new SD('utf8') + } + data = this._decoder.write(data); + } + + this._parser.write(data.toString()) + this.emit("data", data) + return true +} + +SAXStream.prototype.end = function (chunk) { + if (chunk && chunk.length) this.write(chunk) + this._parser.end() + return true +} + +SAXStream.prototype.on = function (ev, handler) { + var me = this + if (!me._parser["on"+ev] && streamWraps.indexOf(ev) !== -1) { + me._parser["on"+ev] = function () { + var args = arguments.length === 1 ? [arguments[0]] + : Array.apply(null, arguments) + args.splice(0, 0, ev) + me.emit.apply(me, args) + } + } + + return Stream.prototype.on.call(me, ev, handler) +} + + + +// character classes and tokens +var whitespace = "\r\n\t " + // this really needs to be replaced with character classes. + // XML allows all manner of ridiculous numbers and digits. + , number = "0124356789" + , letter = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + // (Letter | "_" | ":") + , quote = "'\"" + , entity = number+letter+"#" + , attribEnd = whitespace + ">" + , CDATA = "[CDATA[" + , DOCTYPE = "DOCTYPE" + , XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace" + , XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/" + , rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE } + +// turn all the string character sets into character class objects. +whitespace = charClass(whitespace) +number = charClass(number) +letter = charClass(letter) + +// http://www.w3.org/TR/REC-xml/#NT-NameStartChar +// This implementation works on strings, a single character at a time +// as such, it cannot ever support astral-plane characters (10000-EFFFF) +// without a significant breaking change to either this parser, or the +// JavaScript language. Implementation of an emoji-capable xml parser +// is left as an exercise for the reader. +var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/ + +var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040\.\d-]/ + +quote = charClass(quote) +entity = charClass(entity) +attribEnd = charClass(attribEnd) + +function charClass (str) { + return str.split("").reduce(function (s, c) { + s[c] = true + return s + }, {}) +} + +function isRegExp (c) { + return Object.prototype.toString.call(c) === '[object RegExp]' +} + +function is (charclass, c) { + return isRegExp(charclass) ? !!c.match(charclass) : charclass[c] +} + +function not (charclass, c) { + return !is(charclass, c) +} + +var S = 0 +sax.STATE = +{ BEGIN : S++ +, TEXT : S++ // general stuff +, TEXT_ENTITY : S++ // & and such. +, OPEN_WAKA : S++ // < +, SGML_DECL : S++ // +, SCRIPT : S++ // " + , expect : + [ [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ] + , [ "opentag", { name: "script", attributes: {}, isSelfClosing: false } ] + , [ "text", "hello world" ] + , [ "closetag", "script" ] + , [ "closetag", "xml" ] + ] + , strict : false + , opt : { lowercasetags: true, noscript: true } + } + ) + +require(__dirname).test + ( { xml : "" + , expect : + [ [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ] + , [ "opentag", { name: "script", attributes: {}, isSelfClosing: false } ] + , [ "opencdata", undefined ] + , [ "cdata", "hello world" ] + , [ "closecdata", undefined ] + , [ "closetag", "script" ] + , [ "closetag", "xml" ] + ] + , strict : false + , opt : { lowercasetags: true, noscript: true } + } + ) + diff --git a/platforms/android/assets/www/node_modules/sax/test/issue-84.js b/platforms/android/assets/www/node_modules/sax/test/issue-84.js new file mode 100644 index 0000000..0e7ee69 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/issue-84.js @@ -0,0 +1,13 @@ +// https://github.com/isaacs/sax-js/issues/49 +require(__dirname).test + ( { xml : "body" + , expect : + [ [ "processinginstruction", { name: "has", body: "unbalanced \"quotes" } ], + [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ] + , [ "text", "body" ] + , [ "closetag", "xml" ] + ] + , strict : false + , opt : { lowercasetags: true, noscript: true } + } + ) diff --git a/platforms/android/assets/www/node_modules/sax/test/parser-position.js b/platforms/android/assets/www/node_modules/sax/test/parser-position.js new file mode 100644 index 0000000..e4a68b1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/parser-position.js @@ -0,0 +1,28 @@ +var sax = require("../lib/sax"), + assert = require("assert") + +function testPosition(chunks, expectedEvents) { + var parser = sax.parser(); + expectedEvents.forEach(function(expectation) { + parser['on' + expectation[0]] = function() { + for (var prop in expectation[1]) { + assert.equal(parser[prop], expectation[1][prop]); + } + } + }); + chunks.forEach(function(chunk) { + parser.write(chunk); + }); +}; + +testPosition(['

abcdefgh
'], + [ ['opentag', { position: 5, startTagPosition: 1 }] + , ['text', { position: 19, startTagPosition: 14 }] + , ['closetag', { position: 19, startTagPosition: 14 }] + ]); + +testPosition(['
abcde','fgh
'], + [ ['opentag', { position: 5, startTagPosition: 1 }] + , ['text', { position: 19, startTagPosition: 14 }] + , ['closetag', { position: 19, startTagPosition: 14 }] + ]); diff --git a/platforms/android/assets/www/node_modules/sax/test/script-close-better.js b/platforms/android/assets/www/node_modules/sax/test/script-close-better.js new file mode 100644 index 0000000..f4887b9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/script-close-better.js @@ -0,0 +1,12 @@ +require(__dirname).test({ + xml : "", + expect : [ + ["opentag", {"name": "HTML","attributes": {}, isSelfClosing: false}], + ["opentag", {"name": "HEAD","attributes": {}, isSelfClosing: false}], + ["opentag", {"name": "SCRIPT","attributes": {}, isSelfClosing: false}], + ["script", "'
foo
", + expect : [ + ["opentag", {"name": "HTML","attributes": {}, "isSelfClosing": false}], + ["opentag", {"name": "HEAD","attributes": {}, "isSelfClosing": false}], + ["opentag", {"name": "SCRIPT","attributes": {}, "isSelfClosing": false}], + ["script", "if (1 < 0) { console.log('elo there'); }"], + ["closetag", "SCRIPT"], + ["closetag", "HEAD"], + ["closetag", "HTML"] + ] +}); diff --git a/platforms/android/assets/www/node_modules/sax/test/self-closing-child-strict.js b/platforms/android/assets/www/node_modules/sax/test/self-closing-child-strict.js new file mode 100644 index 0000000..3d6e985 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/self-closing-child-strict.js @@ -0,0 +1,44 @@ + +require(__dirname).test({ + xml : + ""+ + "" + + "" + + "" + + "" + + "=(|)" + + "" + + "", + expect : [ + ["opentag", { + "name": "root", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "child", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "haha", + "attributes": {}, + "isSelfClosing": true + }], + ["closetag", "haha"], + ["closetag", "child"], + ["opentag", { + "name": "monkey", + "attributes": {}, + "isSelfClosing": false + }], + ["text", "=(|)"], + ["closetag", "monkey"], + ["closetag", "root"], + ["end"], + ["ready"] + ], + strict : true, + opt : {} +}); + diff --git a/platforms/android/assets/www/node_modules/sax/test/self-closing-child.js b/platforms/android/assets/www/node_modules/sax/test/self-closing-child.js new file mode 100644 index 0000000..f31c366 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/self-closing-child.js @@ -0,0 +1,44 @@ + +require(__dirname).test({ + xml : + ""+ + "" + + "" + + "" + + "" + + "=(|)" + + "" + + "", + expect : [ + ["opentag", { + "name": "ROOT", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "CHILD", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "HAHA", + "attributes": {}, + "isSelfClosing": true + }], + ["closetag", "HAHA"], + ["closetag", "CHILD"], + ["opentag", { + "name": "MONKEY", + "attributes": {}, + "isSelfClosing": false + }], + ["text", "=(|)"], + ["closetag", "MONKEY"], + ["closetag", "ROOT"], + ["end"], + ["ready"] + ], + strict : false, + opt : {} +}); + diff --git a/platforms/android/assets/www/node_modules/sax/test/self-closing-tag.js b/platforms/android/assets/www/node_modules/sax/test/self-closing-tag.js new file mode 100644 index 0000000..d1d8b7c --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/self-closing-tag.js @@ -0,0 +1,25 @@ + +require(__dirname).test({ + xml : + " "+ + " "+ + " "+ + " "+ + "=(|) "+ + ""+ + " ", + expect : [ + ["opentag", {name:"ROOT", attributes:{}, isSelfClosing: false}], + ["opentag", {name:"HAHA", attributes:{}, isSelfClosing: true}], + ["closetag", "HAHA"], + ["opentag", {name:"HAHA", attributes:{}, isSelfClosing: true}], + ["closetag", "HAHA"], + // ["opentag", {name:"HAHA", attributes:{}}], + // ["closetag", "HAHA"], + ["opentag", {name:"MONKEY", attributes:{}, isSelfClosing: false}], + ["text", "=(|)"], + ["closetag", "MONKEY"], + ["closetag", "ROOT"] + ], + opt : { trim : true } +}); \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/sax/test/stray-ending.js b/platforms/android/assets/www/node_modules/sax/test/stray-ending.js new file mode 100644 index 0000000..bec467b --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/stray-ending.js @@ -0,0 +1,17 @@ +// stray ending tags should just be ignored in non-strict mode. +// https://github.com/isaacs/sax-js/issues/32 +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "opentag", { name: "A", attributes: {}, isSelfClosing: false } ] + , [ "opentag", { name: "B", attributes: {}, isSelfClosing: false } ] + , [ "text", "" ] + , [ "closetag", "B" ] + , [ "closetag", "A" ] + ] + , strict : false + , opt : {} + } + ) + diff --git a/platforms/android/assets/www/node_modules/sax/test/trailing-attribute-no-value.js b/platforms/android/assets/www/node_modules/sax/test/trailing-attribute-no-value.js new file mode 100644 index 0000000..222837f --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/trailing-attribute-no-value.js @@ -0,0 +1,10 @@ + +require(__dirname).test({ + xml : + "", + expect : [ + ["attribute", {name:"ATTRIB", value:"attrib"}], + ["opentag", {name:"ROOT", attributes:{"ATTRIB":"attrib"}, isSelfClosing: false}] + ], + opt : { trim : true } +}); diff --git a/platforms/android/assets/www/node_modules/sax/test/trailing-non-whitespace.js b/platforms/android/assets/www/node_modules/sax/test/trailing-non-whitespace.js new file mode 100644 index 0000000..619578b --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/trailing-non-whitespace.js @@ -0,0 +1,18 @@ + +require(__dirname).test({ + xml : "Welcome, to monkey land", + expect : [ + ["opentag", { + "name": "SPAN", + "attributes": {}, + isSelfClosing: false + }], + ["text", "Welcome,"], + ["closetag", "SPAN"], + ["text", " to monkey land"], + ["end"], + ["ready"] + ], + strict : false, + opt : {} +}); diff --git a/platforms/android/assets/www/node_modules/sax/test/unclosed-root.js b/platforms/android/assets/www/node_modules/sax/test/unclosed-root.js new file mode 100644 index 0000000..f4eeac6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/unclosed-root.js @@ -0,0 +1,11 @@ +require(__dirname).test + ( { xml : "" + + , expect : + [ [ "opentag", { name: "root", attributes: {}, isSelfClosing: false } ] + , [ "error", "Unclosed root tag\nLine: 0\nColumn: 6\nChar: " ] + ] + , strict : true + , opt : {} + } + ) diff --git a/platforms/android/assets/www/node_modules/sax/test/unquoted.js b/platforms/android/assets/www/node_modules/sax/test/unquoted.js new file mode 100644 index 0000000..b3a9a81 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/unquoted.js @@ -0,0 +1,18 @@ +// unquoted attributes should be ok in non-strict mode +// https://github.com/isaacs/sax-js/issues/31 +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "attribute", { name: "CLASS", value: "test" } ] + , [ "attribute", { name: "HELLO", value: "world" } ] + , [ "opentag", { name: "SPAN", + attributes: { CLASS: "test", HELLO: "world" }, + isSelfClosing: false } ] + , [ "closetag", "SPAN" ] + ] + , strict : false + , opt : {} + } + ) + diff --git a/platforms/android/assets/www/node_modules/sax/test/utf8-split.js b/platforms/android/assets/www/node_modules/sax/test/utf8-split.js new file mode 100644 index 0000000..e22bc10 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/utf8-split.js @@ -0,0 +1,32 @@ +var assert = require('assert') +var saxStream = require('../lib/sax').createStream() + +var b = new Buffer('误') + +saxStream.on('text', function(text) { + assert.equal(text, b.toString()) +}) + +saxStream.write(new Buffer('')) +saxStream.write(b.slice(0, 1)) +saxStream.write(b.slice(1)) +saxStream.write(new Buffer('')) +saxStream.write(b.slice(0, 2)) +saxStream.write(b.slice(2)) +saxStream.write(new Buffer('')) +saxStream.write(b) +saxStream.write(new Buffer('')) +saxStream.write(Buffer.concat([new Buffer(''), b.slice(0, 1)])) +saxStream.end(Buffer.concat([b.slice(1), new Buffer('')])) + +var saxStream2 = require('../lib/sax').createStream() + +saxStream2.on('text', function(text) { + assert.equal(text, '�') +}); + +saxStream2.write(new Buffer('')); +saxStream2.write(new Buffer([0xC0])); +saxStream2.write(new Buffer('')); +saxStream2.write(Buffer.concat([new Buffer(''), b.slice(0,1)])); +saxStream2.end(); diff --git a/platforms/android/assets/www/node_modules/sax/test/xmlns-as-tag-name.js b/platforms/android/assets/www/node_modules/sax/test/xmlns-as-tag-name.js new file mode 100644 index 0000000..99142ca --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/xmlns-as-tag-name.js @@ -0,0 +1,15 @@ + +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "opentag", { name: "xmlns", uri: "", prefix: "", local: "xmlns", + attributes: {}, ns: {}, + isSelfClosing: true} + ], + ["closetag", "xmlns"] + ] + , strict : true + , opt : { xmlns: true } + } + ); diff --git a/platforms/android/assets/www/node_modules/sax/test/xmlns-issue-41.js b/platforms/android/assets/www/node_modules/sax/test/xmlns-issue-41.js new file mode 100644 index 0000000..17ab45a --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/xmlns-issue-41.js @@ -0,0 +1,68 @@ +var t = require(__dirname) + + , xmls = // should be the same both ways. + [ "" + , "" ] + + , ex1 = + [ [ "opennamespace" + , { prefix: "a" + , uri: "http://ATTRIBUTE" + } + ] + , [ "attribute" + , { name: "xmlns:a" + , value: "http://ATTRIBUTE" + , prefix: "xmlns" + , local: "a" + , uri: "http://www.w3.org/2000/xmlns/" + } + ] + , [ "attribute" + , { name: "a:attr" + , local: "attr" + , prefix: "a" + , uri: "http://ATTRIBUTE" + , value: "value" + } + ] + , [ "opentag" + , { name: "parent" + , uri: "" + , prefix: "" + , local: "parent" + , attributes: + { "a:attr": + { name: "a:attr" + , local: "attr" + , prefix: "a" + , uri: "http://ATTRIBUTE" + , value: "value" + } + , "xmlns:a": + { name: "xmlns:a" + , local: "a" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "http://ATTRIBUTE" + } + } + , ns: {"a": "http://ATTRIBUTE"} + , isSelfClosing: true + } + ] + , ["closetag", "parent"] + , ["closenamespace", { prefix: "a", uri: "http://ATTRIBUTE" }] + ] + + // swap the order of elements 2 and 1 + , ex2 = [ex1[0], ex1[2], ex1[1]].concat(ex1.slice(3)) + , expected = [ex1, ex2] + +xmls.forEach(function (x, i) { + t.test({ xml: x + , expect: expected[i] + , strict: true + , opt: { xmlns: true } + }) +}) diff --git a/platforms/android/assets/www/node_modules/sax/test/xmlns-rebinding.js b/platforms/android/assets/www/node_modules/sax/test/xmlns-rebinding.js new file mode 100644 index 0000000..07e0425 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/xmlns-rebinding.js @@ -0,0 +1,63 @@ + +require(__dirname).test + ( { xml : + ""+ + ""+ + ""+ + ""+ + ""+ + "" + + , expect : + [ [ "opennamespace", { prefix: "x", uri: "x1" } ] + , [ "opennamespace", { prefix: "y", uri: "y1" } ] + , [ "attribute", { name: "xmlns:x", value: "x1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } ] + , [ "attribute", { name: "xmlns:y", value: "y1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "y" } ] + , [ "attribute", { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "root", uri: "", prefix: "", local: "root", + attributes: { "xmlns:x": { name: "xmlns:x", value: "x1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } + , "xmlns:y": { name: "xmlns:y", value: "y1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "y" } + , "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x1', y: 'y1' }, + isSelfClosing: false } ] + + , [ "opennamespace", { prefix: "x", uri: "x2" } ] + , [ "attribute", { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } ] + , [ "opentag", { name: "rebind", uri: "", prefix: "", local: "rebind", + attributes: { "xmlns:x": { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } }, + ns: { x: 'x2' }, + isSelfClosing: false } ] + + , [ "attribute", { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "check", uri: "", prefix: "", local: "check", + attributes: { "x:a": { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x2' }, + isSelfClosing: true } ] + + , [ "closetag", "check" ] + + , [ "closetag", "rebind" ] + , [ "closenamespace", { prefix: "x", uri: "x2" } ] + + , [ "attribute", { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "check", uri: "", prefix: "", local: "check", + attributes: { "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x1', y: 'y1' }, + isSelfClosing: true } ] + , [ "closetag", "check" ] + + , [ "closetag", "root" ] + , [ "closenamespace", { prefix: "x", uri: "x1" } ] + , [ "closenamespace", { prefix: "y", uri: "y1" } ] + ] + , strict : true + , opt : { xmlns: true } + } + ) + diff --git a/platforms/android/assets/www/node_modules/sax/test/xmlns-strict.js b/platforms/android/assets/www/node_modules/sax/test/xmlns-strict.js new file mode 100644 index 0000000..b5e3e51 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/xmlns-strict.js @@ -0,0 +1,74 @@ + +require(__dirname).test + ( { xml : + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + "" + + , expect : + [ [ "opentag", { name: "root", prefix: "", local: "root", uri: "", + attributes: {}, ns: {}, isSelfClosing: false } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "", + attributes: { "attr": { name: "attr", value: "normal", uri: "", prefix: "", local: "attr", uri: "" } }, + ns: {}, isSelfClosing: true } ] + , [ "closetag", "plain" ] + + , [ "opennamespace", { prefix: "", uri: "uri:default" } ] + + , [ "attribute", { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } ] + , [ "opentag", { name: "ns1", prefix: "", local: "ns1", uri: "uri:default", + attributes: { "xmlns": { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } }, + ns: { "": "uri:default" }, isSelfClosing: false } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "uri:default", ns: { '': 'uri:default' }, + attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } }, + isSelfClosing: true } ] + , [ "closetag", "plain" ] + + , [ "closetag", "ns1" ] + + , [ "closenamespace", { prefix: "", uri: "uri:default" } ] + + , [ "opennamespace", { prefix: "a", uri: "uri:nsa" } ] + + , [ "attribute", { name: "xmlns:a", value: "uri:nsa", prefix: "xmlns", local: "a", uri: "http://www.w3.org/2000/xmlns/" } ] + + , [ "opentag", { name: "ns2", prefix: "", local: "ns2", uri: "", + attributes: { "xmlns:a": { name: "xmlns:a", value: "uri:nsa", prefix: "xmlns", local: "a", uri: "http://www.w3.org/2000/xmlns/" } }, + ns: { a: "uri:nsa" }, isSelfClosing: false } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "", + attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } }, + ns: { a: 'uri:nsa' }, + isSelfClosing: true } ] + , [ "closetag", "plain" ] + + , [ "attribute", { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } ] + , [ "opentag", { name: "a:ns", prefix: "a", local: "ns", uri: "uri:nsa", + attributes: { "a:attr": { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } }, + ns: { a: 'uri:nsa' }, + isSelfClosing: true } ] + , [ "closetag", "a:ns" ] + + , [ "closetag", "ns2" ] + + , [ "closenamespace", { prefix: "a", uri: "uri:nsa" } ] + + , [ "closetag", "root" ] + ] + , strict : true + , opt : { xmlns: true } + } + ) + diff --git a/platforms/android/assets/www/node_modules/sax/test/xmlns-unbound-element.js b/platforms/android/assets/www/node_modules/sax/test/xmlns-unbound-element.js new file mode 100644 index 0000000..9d031a2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/xmlns-unbound-element.js @@ -0,0 +1,33 @@ +require(__dirname).test( + { strict : true + , opt : { xmlns: true } + , expect : + [ [ "error", "Unbound namespace prefix: \"unbound:root\"\nLine: 0\nColumn: 15\nChar: >"] + , [ "opentag", { name: "unbound:root", uri: "unbound", prefix: "unbound", local: "root" + , attributes: {}, ns: {}, isSelfClosing: true } ] + , [ "closetag", "unbound:root" ] + ] + } +).write(""); + +require(__dirname).test( + { strict : true + , opt : { xmlns: true } + , expect : + [ [ "opennamespace", { prefix: "unbound", uri: "someuri" } ] + , [ "attribute", { name: 'xmlns:unbound', value: 'someuri' + , prefix: 'xmlns', local: 'unbound' + , uri: 'http://www.w3.org/2000/xmlns/' } ] + , [ "opentag", { name: "unbound:root", uri: "someuri", prefix: "unbound", local: "root" + , attributes: { 'xmlns:unbound': { + name: 'xmlns:unbound' + , value: 'someuri' + , prefix: 'xmlns' + , local: 'unbound' + , uri: 'http://www.w3.org/2000/xmlns/' } } + , ns: { "unbound": "someuri" }, isSelfClosing: true } ] + , [ "closetag", "unbound:root" ] + , [ "closenamespace", { prefix: 'unbound', uri: 'someuri' }] + ] + } +).write(""); diff --git a/platforms/android/assets/www/node_modules/sax/test/xmlns-unbound.js b/platforms/android/assets/www/node_modules/sax/test/xmlns-unbound.js new file mode 100644 index 0000000..b740e26 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/xmlns-unbound.js @@ -0,0 +1,15 @@ + +require(__dirname).test( + { strict : true + , opt : { xmlns: true } + , expect : + [ ["error", "Unbound namespace prefix: \"unbound\"\nLine: 0\nColumn: 28\nChar: >"] + + , [ "attribute", { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } ] + , [ "opentag", { name: "root", uri: "", prefix: "", local: "root", + attributes: { "unbound:attr": { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } }, + ns: {}, isSelfClosing: true } ] + , [ "closetag", "root" ] + ] + } +).write("") diff --git a/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-ns.js b/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-ns.js new file mode 100644 index 0000000..b1984d2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-ns.js @@ -0,0 +1,31 @@ +var xmlns_attr = +{ + name: "xmlns", value: "http://foo", prefix: "xmlns", + local: "", uri : "http://www.w3.org/2000/xmlns/" +}; + +var attr_attr = +{ + name: "attr", value: "bar", prefix: "", + local : "attr", uri : "" +}; + + +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "opennamespace", { prefix: "", uri: "http://foo" } ] + , [ "attribute", xmlns_attr ] + , [ "attribute", attr_attr ] + , [ "opentag", { name: "elm", prefix: "", local: "elm", uri : "http://foo", + ns : { "" : "http://foo" }, + attributes: { xmlns: xmlns_attr, attr: attr_attr }, + isSelfClosing: true } ] + , [ "closetag", "elm" ] + , [ "closenamespace", { prefix: "", uri: "http://foo"} ] + ] + , strict : true + , opt : {xmlns: true} + } + ) diff --git a/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js b/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js new file mode 100644 index 0000000..e41f218 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js @@ -0,0 +1,36 @@ +require(__dirname).test( + { xml : "" + , expect : + [ [ "attribute" + , { name: "xml:lang" + , local: "lang" + , prefix: "xml" + , uri: "http://www.w3.org/XML/1998/namespace" + , value: "en" + } + ] + , [ "opentag" + , { name: "root" + , uri: "" + , prefix: "" + , local: "root" + , attributes: + { "xml:lang": + { name: "xml:lang" + , local: "lang" + , prefix: "xml" + , uri: "http://www.w3.org/XML/1998/namespace" + , value: "en" + } + } + , ns: {} + , isSelfClosing: true + } + ] + , ["closetag", "root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-prefix.js b/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-prefix.js new file mode 100644 index 0000000..a85b478 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-prefix.js @@ -0,0 +1,21 @@ +require(__dirname).test( + { xml : "" + , expect : + [ + [ "opentag" + , { name: "xml:root" + , uri: "http://www.w3.org/XML/1998/namespace" + , prefix: "xml" + , local: "root" + , attributes: {} + , ns: {} + , isSelfClosing: true + } + ] + , ["closetag", "xml:root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-redefine.js b/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-redefine.js new file mode 100644 index 0000000..d35d5a0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sax/test/xmlns-xml-default-redefine.js @@ -0,0 +1,41 @@ +require(__dirname).test( + { xml : "" + , expect : + [ ["error" + , "xml: prefix must be bound to http://www.w3.org/XML/1998/namespace\n" + + "Actual: ERROR\n" + + "Line: 0\nColumn: 27\nChar: '" + ] + , [ "attribute" + , { name: "xmlns:xml" + , local: "xml" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "ERROR" + } + ] + , [ "opentag" + , { name: "xml:root" + , uri: "http://www.w3.org/XML/1998/namespace" + , prefix: "xml" + , local: "root" + , attributes: + { "xmlns:xml": + { name: "xmlns:xml" + , local: "xml" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "ERROR" + } + } + , ns: {} + , isSelfClosing: true + } + ] + , ["closetag", "xml:root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/.npmignore b/platforms/android/assets/www/node_modules/selenium-webdriver/.npmignore new file mode 100644 index 0000000..d570088 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/.npmignore @@ -0,0 +1,2 @@ +node_modules/ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/CHANGES.md b/platforms/android/assets/www/node_modules/selenium-webdriver/CHANGES.md new file mode 100644 index 0000000..5d40b1b --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/CHANGES.md @@ -0,0 +1,490 @@ +## v2.52.0 + +### Notice + +Starting with v2.52.0, each release of selenium-webdriver will support the +latest _minor_ LTS and stable Node releases. All releases between the LTS and +stable release will have best effort support. Further details are available in +the selenium-webdriver package README. + +### Change Summary + +* Add support for Microsoft's Edge web browser +* Added `webdriver.Builder#buildAsync()`, which returns a promise that will be + fulfilled with the newly created WebDriver instance once the associated + browser has been full initialized. This is purely a convenient alternative + to the existing build() method as the WebDriver class will always defer + commands until it has a fully created browser. +* Added `firefox.Profile#setHost()` which may be used to set the host that + the FirefoxDriver's server listens for commands on. The server uses + "localhost" by default. +* Added `promise.Promise#catch()` for API compatibility with native Promises. + `promise.Promise#thenCatch()` is not yet deprecated, but it simply + delegates to `catch`. +* Changed some `io` operations to use native promises. +* Changed `command.Executor#execute()` and `HttpClient#send()` to return + promises instead of using callback passing. +* Replaced the `Serializable` class with an internal, Symbol-defined method. +* Changed the `Capabilities` class to extend the native `Map` type. +* Changed the `Capabilities.has(key)` to only test if a capability has been set + (Map semantics). To check whether the value is true, use `get(key)`. +* Deprecated `executors.DeferredExecutor` in favor of + `lib/command.DeferredExecutor`. +* API documentation is no longer distributed with the npm package, but remains + available at +* Rewrote the `error` module to export an Error subtype for each type of error + defined in the [W3C WebDriver spec](https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors). +* Changed the `http.Request` and `http.Response` classes to store headers in + maps instead of object literals. +* Updated `ws` dependency to version `1.0.1`. +* Removed fluent predicates "is" and "not" from the experimental + `testing/assert` module. +* Wait conditions that locate an element, or that wait on an element's state, + will return a WebElementPromise. +* Lots of internal clean-up to break selenium-webdriver's long standing + dependency on Google's Closure library. + +### Changes for W3C WebDriver Spec Compliance + +* Updated the `By` locators that are not in the W3C spec to delegated to using + CSS selectors: `By.className`, `By.id`, `By.name`, and `By.tagName`. + + +## v2.49-51 + +* _Releases skipped to stay in sync with the rest of the Selenium project_ + + +## v2.48.2 + +* Added `WebElement#takeScreenshot()`. +* More adjustments to promise callback tracking. + +## v2.48.1 + +* FIXED: Adjusted how the control flow tracks promise callbacks to avoid a + potential deadlock. + +## v2.48.0 + +* Node v0.12.x users must run with --harmony. _This is the last release that + will support v0.12.x_ +* FIXED: (Promise/A+ compliance) When a promise is rejected with a thenable, + the promise adopts the thenable as its rejection reason instead of waiting + for it to settle. The previous (incorrect) behavior was hidden by bugs in + the `promises-aplus-tests` compliance test suite that were fixed in version + `2.1.1`. +* FIXED: the `webdriver.promise.ControlFlow` now has a consistent execution + order for tasks/callbacks scheduled in different turns of the JS event loop. + Refer to the `webdriver.promise` documentation for more details. +* FIXED: do not drop user auth from the WebDriver server URL. +* FIXED: a single `firefox.Binary` instance may be used to configure and + launch multiple FirefoxDriver sessions. + + var binary = new firefox.Binary(); + var options = new firefox.Options().setBinary(binary); + var builder = new Builder().setFirefoxOptions(options); + + var driver1 = builder.build(); + var driver2 = builder.build(); + +* FIXED: zip files created for transfer to a remote WebDriver server are no + longer compressed. If the zip contained a file that was already compressed, + the server would return an "invalid code lengths set" error. +* FIXED: Surfaced the `loopback` option to `remote/SeleniumServer`. When set, + the server will be accessed using the current host's loopback address. + +## v2.47.0 + +### Notice + +This is the last release for `selenium-webdriver` that will support ES5. +Subsequent releases will depend on ES6 features that are enabled by +[default](https://nodejs.org/en/docs/es6/) in Node v4.0.0. Node v0.12.x will +continue to be supported, but will require setting the `--harmony` flag. + +### Change Summary + +* Add support for [Node v4.0.0](https://nodejs.org/en/blog/release/v4.0.0/) + * Updated `ws` dependency from `0.7.1` to `0.8.0` +* Bumped the minimum supported version of Node from `0.10.x` to `0.12.x`. This + is in accordance with the Node support policy established in `v2.45.0`. + +## v2.46.1 + +* Fixed internal module loading on Windows. +* Fixed error message format on timeouts for `until.elementLocated()` + and `until.elementsLocated()`. + +## v2.46.0 + +* Exposed a new logging API via the `webdriver.logging` module. For usage, see + `example/logging.js`. +* Added support for using a proxy server for WebDriver commands. + See `Builder#usingWebDriverProxy()` for more info. +* Removed deprecated functions: + * Capabilities#toJSON() + * UnhandledAlertError#getAlert() + * chrome.createDriver() + * phantomjs.createDriver() + * promise.ControlFlow#annotateError() + * promise.ControlFlow#await() + * promise.ControlFlow#clearHistory() + * promise.ControlFlow#getHistory() +* Removed deprecated enum values: `ErrorCode.NO_MODAL_DIALOG_OPEN` and + `ErrorCode.MODAL_DIALOG_OPENED`. Use `ErrorCode.NO_SUCH_ALERT` and + `ErrorCode.UNEXPECTED_ALERT_OPEN`, respectively. +* FIXED: The `promise.ControlFlow` will maintain state for promise chains + generated in a loop. +* FIXED: Correct serialize target elements used in an action sequence. +* FIXED: `promise.ControlFlow#wait()` now has consistent semantics for an + omitted or 0-timeout: it will wait indefinitely. +* FIXED: `remote.DriverService#start()` will now fail if the child process dies + while waiting for the server to start accepting requests. Previously, start + would continue to poll the server address until the timeout expired. +* FIXED: Skip launching Firefox with the `-silent` flag to preheat the profile. + Starting with Firefox 38, this would cause the browser to crash. This step, + which was first introduced for Selenium's java client back with Firefox 2, + no longer appears to be required. +* FIXED: 8564: `firefox.Driver#quit()` will wait for the Firefox process to + terminate before deleting the temporary webdriver profile. This eliminates a + race condition where Firefox would write profile data during shutdown, + causing the `rm -rf` operation on the profile directory to fail. + +## v2.45.1 + +* FIXED: 8548: Task callbacks are once again dropped if the task was cancelled + due to a previously uncaught error within the frame. +* FIXED: 8496: Extended the `chrome.Options` API to cover all configuration + options (e.g. mobile emulation and performance logging) documented on the + ChromeDriver [project site](https://sites.google.com/a/chromium.org/chromedriver/capabilities). + +## v2.45.0 + +### Important Policy Change + +Starting with the 2.45.0 release, selenium-webdriver will support the last +two stable minor releases for Node. For 2.45.0, this means Selenium will +support Node 0.10.x and 0.12.x. Support for the intermediate, un-stable release +(0.11.x) is "best-effort". This policy will be re-evaluated once Node has a +major version release (i.e. 1.0.0). + +### Change Summary + +* Added native browser support for Internet Explorer, Opera 26+, and Safari +* With the release of [Node 0.12.0](http://blog.nodejs.org/2015/02/06/node-v0-12-0-stable/) + (finally!), the minimum supported version of Node is now `0.10.x`. +* The `promise` module is now [Promises/A+](https://promisesaplus.com/) + compliant. The biggest compliance change is that promise callbacks are now + invoked in a future turn of the JS event loop. For example: + + var promise = require('selenium-webdriver').promise; + console.log('start'); + promise.fulfilled().then(function() { + console.log('middle'); + }); + console.log('end'); + + // Output in selenium-webdriver@2.44.0 + // start + // middle + // end + // + // Output in selenium-webdriver@2.45.0 + // start + // end + // middle + + The `promise.ControlFlow` class has been updated to track the asynchronous + breaks required by Promises/A+, so there are no changes to task execution + order. +* Updated how errors are annotated on failures. When a task fails, the + stacktrace from when that task was scheduled is appended to the rejection + reason with a `From: ` prefix (if it is an Error object). For example: + + var driver = new webdriver.Builder().forBrowser('chrome').build(); + driver.get('http://www.google.com/ncr'); + driver.call(function() { + driver.wait(function() { + return driver.isElementPresent(webdriver.By.id('not-there')); + }, 2000, 'element not found'); + }); + + This code will fail an error like: + + Error: element not found + Wait timed out after 2002ms + at + From: Task: element not found + at + From: Task: WebDriver.call(function) + at + +* Changed the format of strings returned by `promise.ControlFlow#getSchedule`. + This function now accepts a boolean to control whether the returned string + should include the stacktraces for when each task was scheduled. +* Deprecating `promise.ControlFlow#getHistory`, + `promise.ControlFlow#clearHistory`, and `promise.ControlFlow#annotateError`. + These functions were all intended for internal use and are no longer + necessary, so they have been made no-ops. +* `WebDriver.wait()` may now be used to wait for a promise to resolve, with + an optional timeout. Refer to the API documentation for more information. +* Added support for copying files to a remote Selenium via `sendKeys` to test + file uploads. Refer to the API documentation for more information. Sample + usage included in `test/upload_test.js` +* Expanded the interactions API to include touch actions. + See `WebDriver.touchActions()`. +* FIXED: 8380: `firefox.Driver` will delete its temporary profile on `quit`. +* FIXED: 8306: Stack overflow in promise callbacks eliminated. +* FIXED: 8221: Added support for defining custom command mappings. Includes + support for PhantomJS's `executePhantomJS` (requires PhantomJS 1.9.7 or + GhostDriver 1.1.0). +* FIXED: 8128: When the FirefoxDriver marshals an object to the page for + `executeScript`, it defines additional properties (required by the driver's + implementation). These properties will no longer be enumerable and should + be omitted (i.e. they won't show up in JSON.stringify output). +* FIXED: 8094: The control flow will no longer deadlock when a task returns + a promise that depends on the completion of sub-tasks. + +## v2.44.0 + +* Added the `until` module, which defines common explicit wait conditions. + Sample usage: + + var firefox = require('selenium-webdriver/firefox'), + until = require('selenium-webdriver/until'); + + var driver = new firefox.Driver(); + driver.get('http://www.google.com/ncr'); + driver.wait(until.titleIs('Google Search'), 1000); + +* FIXED: 8000: `Builder.forBrowser()` now accepts an empty string since some + WebDriver implementations ignore the value. A value must still be specified, + however, since it is a required field in WebDriver's wire protocol. +* FIXED: 7994: The `stacktrace` module will not modify stack traces if the + initial parse fails (e.g. the user defined `Error.prepareStackTrace`) +* FIXED: 5855: Added a module (`until`) that defines several common conditions + for use with explicit waits. See updated examples for usage. + +## v2.43.5 + +* FIXED: 7905: `Builder.usingServer(url)` once again returns `this` for + chaining. + +## v2.43.2-4 + +* No changes; version bumps while attempting to work around an issue with + publishing to npm (a version string may only be used once). + +## v2.43.1 + +* Fixed an issue with flakiness when setting up the Firefox profile that could + prevent the driver from initializing properly. + +## v2.43.0 + +* Added native support for Firefox - the Java Selenium server is no longer + required. +* Added support for generator functions to `ControlFlow#execute` and + `ControlFlow#wait`. For more information, see documentation on + `webdriver.promise.consume`. Requires harmony support (run with + `node --harmony-generators` in `v0.11.x`). +* Various improvements to the `Builder` API. Notably, the `build()` function + will no longer default to attempting to use a server at + `http://localhost:4444/wd/hub` if it cannot start a browser directly - + you must specify the WebDriver server with `usingServer(url)`. You can + also set the target browser and WebDriver server through a pair of + environment variables. See the documentation on the `Builder` constructor + for more information. +* For consistency with the other language bindings, added browser specific + classes that can be used to start a browser without the builder. + + var webdriver = require('selenium-webdriver') + chrome = require('selenium-webdriver/chrome'); + + // The following are equivalent. + var driver1 = new webdriver.Builder().forBrowser('chrome').build(); + var driver2 = new chrome.Driver(); + +* Promise A+ compliance: a promise may no longer resolve to itself. +* For consistency with other language bindings, deprecated + `UnhandledAlertError#getAlert` and added `#getAlertText`. + `getAlert` will be removed in `2.45.0`. +* FIXED: 7641: Deprecated `ErrorCode.NO_MODAL_DIALOG_OPEN` and + `ErrorCode.MODAL_DIALOG_OPENED` in favor of the new + `ErrorCode.NO_SUCH_ALERT` and `ErrorCode.UNEXPECTED_ALERT_OPEN`, + respectively. +* FIXED: 7563: Mocha integration no longer disables timeouts. Default Mocha + timeouts apply (2000 ms) and may be changed using `this.timeout(ms)`. +* FIXED: 7470: Make it easier to create WebDriver instances in custom flows for + parallel execution. + +## v2.42.1 + +* FIXED: 7465: Fixed `net.getLoopbackAddress` on Windows +* FIXED: 7277: Support `done` callback in Mocha's BDD interface +* FIXED: 7156: `Promise#thenFinally` should not suppress original error + +## v2.42.0 + +* Removed deprecated functions `Promise#addCallback()`, + `Promise#addCallbacks()`, `Promise#addErrback()`, and `Promise#addBoth()`. +* Fail with a more descriptive error if the server returns a malformed redirect +* FIXED: 7300: Connect to ChromeDriver using the loopback address since + ChromeDriver 2.10.267517 binds to localhost by default. +* FIXED: 7339: Preserve wrapped test function's string representation for + Mocha's BDD interface. + +## v2.41.0 + +* FIXED: 7138: export logging API from webdriver module. +* FIXED: 7105: beforeEach/it/afterEach properly bind `this` for Mocha tests. + +## v2.40.0 + +* API documentation is now included in the docs directory. +* Added utility functions for working with an array of promises: + `promise.all`, `promise.map`, and `promise.filter` +* Introduced `Promise#thenCatch()` and `Promise#thenFinally()`. +* Deprecated `Promise#addCallback()`, `Promise#addCallbacks()`, + `Promise#addErrback()`, and `Promise#addBoth()`. +* Removed deprecated function `webdriver.WebDriver#getCapability`. +* FIXED: 6826: Added support for custom locators. + +## v2.39.0 + +* Version bump to stay in sync with the Selenium project. + +## v2.38.1 + +* FIXED: 6686: Changed `webdriver.promise.Deferred#cancel()` to silently no-op + if the deferred has already been resolved. + +## v2.38.0 + +* When a promise is rejected, always annotate the stacktrace with the parent + flow state so users can identify the source of an error. +* Updated tests to reflect features not working correctly in the SafariDriver + (cookie management and proxy support; see issues 5051, 5212, and 5503) +* FIXED: 6284: For mouse moves, correctly omit the x/y offsets if not + specified as a function argument (instead of passing (0,0)). +* FIXED: 6471: Updated documentation on `webdriver.WebElement#getAttribute` +* FIXED: 6612: On Unix, use the default IANA ephemeral port range if unable to + retrieve the current system's port range. +* FIXED: 6617: Avoid triggering the node debugger when initializing the + stacktrace module. +* FIXED: 6627: Safely rebuild chrome.Options from a partial JSON spec. + +## v2.37.0 + +* FIXED: 6346: The remote.SeleniumServer class now accepts JVM arguments using + the `jvmArgs` option. + +## v2.36.0 + +* _Release skipped to stay in sync with main Selenium project._ + +## v2.35.2 + +* FIXED: 6200: Pass arguments to the Selenium server instead of to the JVM. + +## v2.35.1 + +* FIXED: 6090: Changed example scripts to use chromedriver. + +## v2.35.0 + +* Version bump to stay in sync with the Selenium project. + +## v2.34.1 + +* FIXED: 6079: The parent process should not wait for spawn driver service + processes (chromedriver, phantomjs, etc.) + +## v2.34.0 + +* Added the `selenium-webdriver/testing/assert` module. This module + simplifies writing assertions against promised values (see + example in module documentation). +* Added the `webdriver.Capabilities` class. +* Added native support for the ChromeDriver. When using the `Builder`, + requesting chrome without specifying a remote server URL will default to + the native ChromeDriver implementation. The + [ChromeDriver server](https://code.google.com/p/chromedriver/downloads/list) + must be downloaded separately. + + // Will start ChromeDriver locally. + var driver = new webdriver.Builder(). + withCapabilities(webdriver.Capabilities.chrome()). + build(); + + // Will start ChromeDriver using the remote server. + var driver = new webdriver.Builder(). + withCapabilities(webdriver.Capabilities.chrome()). + usingServer('http://server:1234/wd/hub'). + build(); + +* Added support for configuring proxies through the builder. For examples, see + `selenium-webdriver/test/proxy_test`. +* Added native support for PhantomJS. +* Changed signature of `SeleniumServer` to `SeleniumServer(jar, options)`. +* Tests are now included in the npm published package. See `README.md` for + execution instructions +* Removed the deprecated `webdriver.Deferred#resolve` and + `webdriver.promise.resolved` functions. +* Removed the ability to connect to an existing session from the Builder. This + feature is intended for use with the browser-based client. + +## v2.33.0 + +* Added support for WebDriver's logging API +* FIXED: 5511: Added webdriver.manage().timeouts().pageLoadTimeout(ms) + +## v2.32.1 + +* FIXED: 5541: Added missing return statement for windows in + `portprober.findFreePort()` + +## v2.32.0 + +* Added the `selenium-webdriver/testing` package, which provides a basic + framework for writing tests using Mocha. See + `selenium-webdriver/example/google_search_test.js` for usage. +* For Promises/A+ compatibility, backing out the change in 2.30.0 that ensured + rejections were always Error objects. Rejection reasons are now left as is. +* Removed deprecated functions originally scheduled for removal in 2.31.0 + * promise.Application.getInstance() + * promise.ControlFlow#schedule() + * promise.ControlFlow#scheduleTimeout() + * promise.ControlFlow#scheduleWait() +* Renamed some functions for consistency with Promises/A+ terminology. The + original functions have been deprecated and will be removed in 2.34.0: + * promise.resolved() -> promise.fulfilled() + * promise.Deferred#resolve() -> promise.Deferred#fulfill() +* FIXED: remote.SeleniumServer#stop now shuts down within the active control + flow, allowing scripts to finish. Use #kill to shutdown immediately. +* FIXED: 5321: cookie deletion commands + +## v2.31.0 + +* Added an example script. +* Added a class for controlling the standalone Selenium server (server +available separately) +* Added a portprober for finding free ports +* FIXED: WebElements now belong to the same flow as their parent driver. + +## v2.30.0 + +* Ensures promise rejections are always Error values. +* Version bump to keep in sync with the Selenium project. + +## v2.29.1 + +* Fixed a bug that could lead to an infinite loop. +* Added a README.md + +## v2.29.0 + +* Initial release for npm: + + npm install selenium-webdriver diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/LICENSE b/platforms/android/assets/www/node_modules/selenium-webdriver/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/NOTICE b/platforms/android/assets/www/node_modules/selenium-webdriver/NOTICE new file mode 100644 index 0000000..2744503 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/NOTICE @@ -0,0 +1,2 @@ +Copyright 2011-2016 Software Freedom Conservancy +Copyright 2004-2011 Selenium committers diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/README.md b/platforms/android/assets/www/node_modules/selenium-webdriver/README.md new file mode 100644 index 0000000..0b446ba --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/README.md @@ -0,0 +1,226 @@ +# selenium-webdriver + +Selenium is a browser automation library. Most often used for testing +web-applications, Selenium may be used for any task that requires automating +interaction with the browser. + +## Installation + +Selenium may be installed via npm with + + npm install selenium-webdriver + +Out of the box, Selenium includes everything you need to work with Firefox. You +will need to download additional components to work with the other major +browsers. The drivers for Chrome, PhantomJS, Opera, and Microsoft's IE and Edge +web browsers are all standalone executables that should be available on your +[PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). The SafariDriver +browser extension should be installed in your browser before using Selenium; we +recommend disabling the extension when using the browser without Selenium or +installing the extension in a profile only used for testing. + +| Browser | Component | +| ----------------- | ---------------------------------- | +| Chrome | [chromedriver(.exe)][chrome] | +| Internet Explorer | [IEDriverServer.exe][release] | +| Edge | [MicrosoftWebDriver.msi][edge] | +| PhantomJS | [phantomjs(.exe)][phantomjs] | +| Opera | [operadriver(.exe)][opera] | +| Safari | [SafariDriver.safariextz][release] | + +## Usage + +The sample below and others are included in the `example` directory. You may +also find the tests for selenium-webdriver informative. + + var webdriver = require('selenium-webdriver'), + By = require('selenium-webdriver').By, + until = require('selenium-webdriver').until; + + var driver = new webdriver.Builder() + .forBrowser('firefox') + .build(); + + driver.get('http://www.google.com/ncr'); + driver.findElement(By.name('q')).sendKeys('webdriver'); + driver.findElement(By.name('btnG')).click(); + driver.wait(until.titleIs('webdriver - Google Search'), 1000); + driver.quit(); + +### Using the Builder API + +The `Builder` class is your one-stop shop for configuring new WebDriver +instances. Rather than clutter your code with branches for the various browsers, +the builder lets you set all options in one flow. When you call +`Builder#build()`, all options irrelevant to the selected browser are dropped: + + var webdriver = require('selenium-webdriver'), + chrome = require('selenium-webdriver/chrome'), + firefox = require('selenium-webdriver/firefox'); + + var driver = new webdriver.Builder() + .forBrowser('firefox') + .setChromeOptions(/* ... */) + .setFirefoxOptions(/* ... */) + .build(); + +Why would you want to configure options irrelevant to the target browser? The +`Builder`'s API defines your _default_ configuration. You can change the target +browser at runtime through the `SELENIUM_BROWSER` environment variable. For +example, the `example/google_search.js` script is configured to run against +Firefox. You can run the example against other browsers just by changing the +runtime environment + + # cd node_modules/selenium-webdriver + node example/google_search + SELENIUM_BROWSER=chrome node example/google_search + SELENIUM_BROWSER=safari node example/google_search + +### The Standalone Selenium Server + +The standalone Selenium Server acts as a proxy between your script and the +browser-specific drivers. The server may be used when running locally, but it's +not recommend as it introduces an extra hop for each request and will slow +things down. The server is required, however, to use a browser on a remote host +(most browser drivers, like the IEDriverServer, do not accept remote +connections). + +To use the Selenium Server, you will need to install the +[JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html) and +download the latest server from [Selenium][release]. Once downloaded, run the +server with + + java -jar selenium-server-standalone-2.45.0.jar + +You may configure your tests to run against a remote server through the Builder +API: + + var driver = new webdriver.Builder() + .forBrowser('firefox') + .usingServer('http://localhost:4444/wd/hub') + .build(); + +Or change the Builder's configuration at runtime with the `SELENIUM_REMOTE_URL` +environment variable: + + SELENIUM_REMOTE_URL="http://localhost:4444/wd/hub" node script.js + +You can experiment with these options using the `example/google_search.js` +script provided with `selenium-webdriver`. + +## Documentation + +API documentation is available online from the [Selenium project][api]. +Addition resources include + +- the #selenium channel on freenode IRC +- the [selenium-users@googlegroups.com][users] list +- [SeleniumHQ](http://www.seleniumhq.org/docs/) documentation + +## Contributing + +Contributions are accepted either through [GitHub][gh] pull requests or patches +via the [Selenium issue tracker][issues]. You must sign our +[Contributor License Agreement][cla] before your changes will be accepted. + +## Node Support Policy + +Each version of selenium-webdriver will support the latest _semver-minor_ +version of the [LTS] and stable Node releases. All _semver-major_ & +_semver-minor_ versions between the LTS and stable release will have "best +effort" support. Following a Selenium release, any _semver-minor_ Node releases +will also have "best effort" support. Releases older than the latest LTS, +_semver-major_ releases, and all unstable release branches (e.g. "v.Next") +are considered strictly unsupported. + +For example, suppose the current LTS and stable releases are v4.2.4 and v5.4.1, +respectively. Then a Selenium release would have the following support levels: + +| Version | Support | +| ------- | ------------- | +| <= 4.1 | _unsupported_ | +| 4.2 | supported | +| 5.0-3 | best effort | +| 5.4 | supported | +| >= 5.5 | best effort | +| v.Next | _unsupported_ | + +### Support Level Definitions + +- _supported:_ A selenium-webdriver release will be API compatible with the + platform API, without the use of runtime flags. + +- _best effort:_ Bugs will be investigated as time permits. API compatibility is + only guaranteed where required by a _supported_ release. This effectively + means the adoption of new JS features, such as ES2015 modules, will depend + on what is supported in Node's LTS. + +- _unsupported:_ Bug submissions will be closed as will-not-fix and API + compatibility is not guaranteed. + +### Projected Support Schedule + +If Node releases a new [LTS] each October and a new major version every 6 +months, the support window for selenium-webdriver will be roughly: + +| Date | LTS | Stable | +| --------- | ---: | -----: | +| (current) | 4.2 | 5.0 | +| 2016-04 | 4.2 | 6.0 | +| 2016-10 | 6.0 | 7.0 | +| 2017-04 | 6.0 | 8.0 | +| 2017-10 | 8.0 | 9.0 | + +## Issues + +Please report any issues using the [Selenium issue tracker][issues]. When using +the issue tracker + +- __Do__ include a detailed description of the problem. +- __Do__ include a link to a [gist](http://gist.github.com/) with any + interesting stack traces/logs (you may also attach these directly to the bug + report). +- __Do__ include a [reduced test case][reduction]. Reporting "unable to find + element on the page" is _not_ a valid report - there's nothing for us to + look into. Expect your bug report to be closed if you do not provide enough + information for us to investigate. +- __Do not__ use the issue tracker to submit basic help requests. All help + inquiries should be directed to the [user forum][users] or #selenium IRC + channel. +- __Do not__ post empty "I see this too" or "Any updates?" comments. These + provide no additional information and clutter the log. +- __Do not__ report regressions on closed bugs as they are not actively + monitored for upates (especially bugs that are >6 months old). Please open a + new issue and reference the original bug in your report. + +## License + +Licensed to the Software Freedom Conservancy (SFC) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The SFC licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. + +[LTS]: https://github.com/nodejs/LTS +[api]: http://seleniumhq.github.io/selenium/docs/api/javascript/ +[cla]: http://goo.gl/qC50R +[chrome]: http://chromedriver.storage.googleapis.com/index.html +[gh]: https://github.com/SeleniumHQ/selenium/ +[issues]: https://github.com/SeleniumHQ/selenium/issues +[opera]: https://github.com/operasoftware/operachromiumdriver/releases +[phantomjs]: http://phantomjs.org/ +[edge]: http://go.microsoft.com/fwlink/?LinkId=619687 +[reduction]: http://www.webkit.org/quality/reduction.html +[release]: http://selenium-release.storage.googleapis.com/index.html +[users]: https://groups.google.com/forum/#!forum/selenium-users diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/builder.js b/platforms/android/assets/www/node_modules/selenium-webdriver/builder.js new file mode 100644 index 0000000..64968e1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/builder.js @@ -0,0 +1,513 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const chrome = require('./chrome'); +const edge = require('./edge'); +const executors = require('./executors'); +const firefox = require('./firefox'); +const ie = require('./ie'); +const capabilities = require('./lib/capabilities'); +const webdriver = require('./lib/webdriver'); +const promise = require('./lib/promise'); +const opera = require('./opera'); +const phantomjs = require('./phantomjs'); +const safari = require('./safari'); + +const Browser = capabilities.Browser; +const Capabilities = capabilities.Capabilities; +const Capability = capabilities.Capability; +const WebDriver = webdriver.WebDriver; + + + +var seleniumServer; + +/** + * Starts an instance of the Selenium server if not yet running. + * @param {string} jar Path to the server jar to use. + * @return {!promise.Promise} A promise for the server's + * addrss once started. + */ +function startSeleniumServer(jar) { + if (!seleniumServer) { + // Requiring 'chrome' above would create a cycle: + // index -> builder -> chrome -> index + var remote = require('./remote'); + seleniumServer = new remote.SeleniumServer(jar); + } + return seleniumServer.start(); +} + + +/** + * Creates new {@link webdriver.WebDriver WebDriver} instances. The environment + * variables listed below may be used to override a builder's configuration, + * allowing quick runtime changes. + * + * - {@code SELENIUM_BROWSER}: defines the target browser in the form + * {@code browser[:version][:platform]}. + * + * - {@code SELENIUM_REMOTE_URL}: defines the remote URL for all builder + * instances. This environment variable should be set to a fully qualified + * URL for a WebDriver server (e.g. http://localhost:4444/wd/hub). This + * option always takes precedence over {@code SELENIUM_SERVER_JAR}. + * + * - {@code SELENIUM_SERVER_JAR}: defines the path to the + * + * standalone Selenium server jar to use. The server will be started the + * first time a WebDriver instance and be killed when the process exits. + * + * Suppose you had mytest.js that created WebDriver with + * + * var driver = new webdriver.Builder() + * .forBrowser('chrome') + * .build(); + * + * This test could be made to use Firefox on the local machine by running with + * `SELENIUM_BROWSER=firefox node mytest.js`. Rather than change the code to + * target Google Chrome on a remote machine, you can simply set the + * `SELENIUM_BROWSER` and `SELENIUM_REMOTE_URL` environment variables: + * + * SELENIUM_BROWSER=chrome:36:LINUX \ + * SELENIUM_REMOTE_URL=http://www.example.com:4444/wd/hub \ + * node mytest.js + * + * You could also use a local copy of the standalone Selenium server: + * + * SELENIUM_BROWSER=chrome:36:LINUX \ + * SELENIUM_SERVER_JAR=/path/to/selenium-server-standalone.jar \ + * node mytest.js + */ +class Builder { + constructor() { + /** @private {promise.ControlFlow} */ + this.flow_ = null; + + /** @private {string} */ + this.url_ = ''; + + /** @private {?string} */ + this.proxy_ = null; + + /** @private {!Capabilities} */ + this.capabilities_ = new Capabilities(); + + /** @private {chrome.Options} */ + this.chromeOptions_ = null; + + /** @private {firefox.Options} */ + this.firefoxOptions_ = null; + + /** @private {opera.Options} */ + this.operaOptions_ = null; + + /** @private {ie.Options} */ + this.ieOptions_ = null; + + /** @private {safari.Options} */ + this.safariOptions_ = null; + + /** @private {edge.Options} */ + this.edgeOptions_ = null; + + /** @private {boolean} */ + this.ignoreEnv_ = false; + } + + /** + * Configures this builder to ignore any environment variable overrides and to + * only use the configuration specified through this instance's API. + * + * @return {!Builder} A self reference. + */ + disableEnvironmentOverrides() { + this.ignoreEnv_ = true; + return this; + } + + /** + * Sets the URL of a remote WebDriver server to use. Once a remote URL has + * been specified, the builder direct all new clients to that server. If this + * method is never called, the Builder will attempt to create all clients + * locally. + * + * As an alternative to this method, you may also set the + * `SELENIUM_REMOTE_URL` environment variable. + * + * @param {string} url The URL of a remote server to use. + * @return {!Builder} A self reference. + */ + usingServer(url) { + this.url_ = url; + return this; + } + + /** + * @return {string} The URL of the WebDriver server this instance is + * configured to use. + */ + getServerUrl() { + return this.url_; + } + + /** + * Sets the URL of the proxy to use for the WebDriver's HTTP connections. + * If this method is never called, the Builder will create a connection + * without a proxy. + * + * @param {string} proxy The URL of a proxy to use. + * @return {!Builder} A self reference. + */ + usingWebDriverProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * @return {?string} The URL of the proxy server to use for the WebDriver's + * HTTP connections, or `null` if not set. + */ + getWebDriverProxy() { + return this.proxy_; + } + + /** + * Sets the desired capabilities when requesting a new session. This will + * overwrite any previously set capabilities. + * @param {!(Object|Capabilities)} capabilities The desired capabilities for + * a new session. + * @return {!Builder} A self reference. + */ + withCapabilities(capabilities) { + this.capabilities_ = new Capabilities(capabilities); + return this; + } + + /** + * Returns the base set of capabilities this instance is currently configured + * to use. + * @return {!Capabilities} The current capabilities for this builder. + */ + getCapabilities() { + return this.capabilities_; + } + + /** + * Configures the target browser for clients created by this instance. + * Any calls to {@link #withCapabilities} after this function will + * overwrite these settings. + * + * You may also define the target browser using the {@code SELENIUM_BROWSER} + * environment variable. If set, this environment variable should be of the + * form `browser[:[version][:platform]]`. + * + * @param {(string|Browser)} name The name of the target browser; + * common defaults are available on the {@link webdriver.Browser} enum. + * @param {string=} opt_version A desired version; may be omitted if any + * version should be used. + * @param {string=} opt_platform The desired platform; may be omitted if any + * version may be used. + * @return {!Builder} A self reference. + */ + forBrowser(name, opt_version, opt_platform) { + this.capabilities_.set(Capability.BROWSER_NAME, name); + this.capabilities_.set(Capability.VERSION, opt_version || null); + this.capabilities_.set(Capability.PLATFORM, opt_platform || null); + return this; + } + + /** + * Sets the proxy configuration to use for WebDriver clients created by this + * builder. Any calls to {@link #withCapabilities} after this function will + * overwrite these settings. + * @param {!capabilities.ProxyConfig} config The configuration to use. + * @return {!Builder} A self reference. + */ + setProxy(config) { + this.capabilities_.setProxy(config); + return this; + } + + /** + * Sets the logging preferences for the created session. Preferences may be + * changed by repeated calls, or by calling {@link #withCapabilities}. + * @param {!(./lib/logging.Preferences|Object)} prefs The + * desired logging preferences. + * @return {!Builder} A self reference. + */ + setLoggingPrefs(prefs) { + this.capabilities_.setLoggingPrefs(prefs); + return this; + } + + /** + * Sets whether native events should be used. + * @param {boolean} enabled Whether to enable native events. + * @return {!Builder} A self reference. + */ + setEnableNativeEvents(enabled) { + this.capabilities_.setEnableNativeEvents(enabled); + return this; + } + + /** + * Sets how elements should be scrolled into view for interaction. + * @param {number} behavior The desired scroll behavior: either 0 to align + * with the top of the viewport or 1 to align with the bottom. + * @return {!Builder} A self reference. + */ + setScrollBehavior(behavior) { + this.capabilities_.setScrollBehavior(behavior); + return this; + } + + /** + * Sets the default action to take with an unexpected alert before returning + * an error. + * @param {string} behavior The desired behavior; should be "accept", + * "dismiss", or "ignore". Defaults to "dismiss". + * @return {!Builder} A self reference. + */ + setAlertBehavior(behavior) { + this.capabilities_.setAlertBehavior(behavior); + return this; + } + + /** + * Sets Chrome specific {@linkplain chrome.Options options} for drivers + * created by this builder. Any logging or proxy settings defined on the given + * options will take precedence over those set through + * {@link #setLoggingPrefs} and {@link #setProxy}, respectively. + * + * @param {!chrome.Options} options The ChromeDriver options to use. + * @return {!Builder} A self reference. + */ + setChromeOptions(options) { + this.chromeOptions_ = options; + return this; + } + + /** + * Sets Firefox specific {@linkplain firefox.Options options} for drivers + * created by this builder. Any logging or proxy settings defined on the given + * options will take precedence over those set through + * {@link #setLoggingPrefs} and {@link #setProxy}, respectively. + * + * @param {!firefox.Options} options The FirefoxDriver options to use. + * @return {!Builder} A self reference. + */ + setFirefoxOptions(options) { + this.firefoxOptions_ = options; + return this; + } + + /** + * Sets Opera specific {@linkplain opera.Options options} for drivers created + * by this builder. Any logging or proxy settings defined on the given options + * will take precedence over those set through {@link #setLoggingPrefs} and + * {@link #setProxy}, respectively. + * + * @param {!opera.Options} options The OperaDriver options to use. + * @return {!Builder} A self reference. + */ + setOperaOptions(options) { + this.operaOptions_ = options; + return this; + } + + /** + * Set Internet Explorer specific {@linkplain ie.Options options} for drivers + * created by this builder. Any proxy settings defined on the given options + * will take precedence over those set through {@link #setProxy}. + * + * @param {!ie.Options} options The IEDriver options to use. + * @return {!Builder} A self reference. + */ + setIeOptions(options) { + this.ieOptions_ = options; + return this; + } + + /** + * Set {@linkplain edge.Options options} specific to Microsoft's Edge browser + * for drivers created by this builder. Any proxy settings defined on the + * given options will take precedence over those set through + * {@link #setProxy}. + * + * @param {!edge.Options} options The MicrosoftEdgeDriver options to use. + * @return {!Builder} A self reference. + */ + setEdgeOptions(options) { + this.edgeOptions_ = options; + return this; + } + + /** + * Sets Safari specific {@linkplain safari.Options options} for drivers + * created by this builder. Any logging settings defined on the given options + * will take precedence over those set through {@link #setLoggingPrefs}. + * + * @param {!safari.Options} options The Safari options to use. + * @return {!Builder} A self reference. + */ + setSafariOptions(options) { + this.safariOptions_ = options; + return this; + } + + /** + * Sets the control flow that created drivers should execute actions in. If + * the flow is never set, or is set to {@code null}, it will use the active + * flow at the time {@link #build()} is called. + * @param {promise.ControlFlow} flow The control flow to use, or + * {@code null} to + * @return {!Builder} A self reference. + */ + setControlFlow(flow) { + this.flow_ = flow; + return this; + } + + /** + * Creates a new WebDriver client based on this builder's current + * configuration. + * + * While this method will immediately return a new WebDriver instance, any + * commands issued against it will be deferred until the associated browser + * has been fully initialized. Users may call {@link #buildAsync()} to obtain + * a promise that will not be fulfilled until the browser has been created + * (the difference is purely in style). + * + * @return {!webdriver.WebDriver} A new WebDriver instance. + * @throws {Error} If the current configuration is invalid. + * @see #buildAsync() + */ + build() { + // Create a copy for any changes we may need to make based on the current + // environment. + var capabilities = new Capabilities(this.capabilities_); + + var browser; + if (!this.ignoreEnv_ && process.env.SELENIUM_BROWSER) { + browser = process.env.SELENIUM_BROWSER.split(/:/, 3); + capabilities.set(Capability.BROWSER_NAME, browser[0]); + capabilities.set(Capability.VERSION, browser[1] || null); + capabilities.set(Capability.PLATFORM, browser[2] || null); + } + + browser = capabilities.get(Capability.BROWSER_NAME); + + if (typeof browser !== 'string') { + throw TypeError( + `Target browser must be a string, but is <${typeof browser}>;` + + ' did you forget to call forBrowser()?'); + } + + if (browser === 'ie') { + browser = Browser.INTERNET_EXPLORER; + } + + // Apply browser specific overrides. + if (browser === Browser.CHROME && this.chromeOptions_) { + capabilities.merge(this.chromeOptions_.toCapabilities()); + + } else if (browser === Browser.FIREFOX && this.firefoxOptions_) { + capabilities.merge(this.firefoxOptions_.toCapabilities()); + + } else if (browser === Browser.INTERNET_EXPLORER && this.ieOptions_) { + capabilities.merge(this.ieOptions_.toCapabilities()); + + } else if (browser === Browser.OPERA && this.operaOptions_) { + capabilities.merge(this.operaOptions_.toCapabilities()); + + } else if (browser === Browser.SAFARI && this.safariOptions_) { + capabilities.merge(this.safariOptions_.toCapabilities()); + + } else if (browser === Browser.EDGE && this.edgeOptions_) { + capabilities.merge(this.edgeOptions_.toCapabilities()); + } + + // Check for a remote browser. + var url = this.url_; + if (!this.ignoreEnv_) { + if (process.env.SELENIUM_REMOTE_URL) { + url = process.env.SELENIUM_REMOTE_URL; + } else if (process.env.SELENIUM_SERVER_JAR) { + url = startSeleniumServer(process.env.SELENIUM_SERVER_JAR); + } + } + + if (url) { + var executor = executors.createExecutor(url, this.proxy_); + return WebDriver.createSession(executor, capabilities, this.flow_); + } + + // Check for a native browser. + switch (browser) { + case Browser.CHROME: + return new chrome.Driver(capabilities, null, this.flow_); + + case Browser.FIREFOX: + return new firefox.Driver(capabilities, this.flow_); + + case Browser.INTERNET_EXPLORER: + return new ie.Driver(capabilities, this.flow_); + + case Browser.EDGE: + return new edge.Driver(capabilities, null, this.flow_); + + case Browser.OPERA: + return new opera.Driver(capabilities, null, this.flow_); + + case Browser.PHANTOM_JS: + return new phantomjs.Driver(capabilities, this.flow_); + + case Browser.SAFARI: + return new safari.Driver(capabilities, this.flow_); + + default: + throw new Error('Do not know how to build driver: ' + browser + + '; did you forget to call usingServer(url)?'); + } + } + + /** + * Creates a new WebDriver client based on this builder's current + * configuration. This method returns a promise that will not be fulfilled + * until the new browser session has been fully initialized. + * + * __Note:__ this method is purely a convenience wrapper around + * {@link #build()}. + * + * @return {!promise.Promise} A promise that will be + * fulfilled with the newly created WebDriver instance once the browser + * has been fully initialized. + * @see #build() + */ + buildAsync() { + let driver = this.build(); + return driver.getSession().then(() => driver); + } +} + + +// PUBLIC API + + +exports.Builder = Builder; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/chrome.js b/platforms/android/assets/www/node_modules/selenium-webdriver/chrome.js new file mode 100644 index 0000000..2731d90 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/chrome.js @@ -0,0 +1,811 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a {@linkplain Driver WebDriver} client for the Chrome + * web browser. Before using this module, you must download the latest + * [ChromeDriver release] and ensure it can be found on your system [PATH]. + * + * There are three primary classes exported by this module: + * + * 1. {@linkplain ServiceBuilder}: configures the + * {@link selenium-webdriver/remote.DriverService remote.DriverService} + * that manages the [ChromeDriver] child process. + * + * 2. {@linkplain Options}: defines configuration options for each new Chrome + * session, such as which {@linkplain Options#setProxy proxy} to use, + * what {@linkplain Options#addExtensions extensions} to install, or + * what {@linkplain Options#addArguments command-line switches} to use when + * starting the browser. + * + * 3. {@linkplain Driver}: the WebDriver client; each new instance will control + * a unique browser session with a clean user profile (unless otherwise + * configured through the {@link Options} class). + * + * __Customizing the ChromeDriver Server__ + * + * By default, every Chrome session will use a single driver service, which is + * started the first time a {@link Driver} instance is created and terminated + * when this process exits. The default service will inherit its environment + * from the current process and direct all output to /dev/null. You may obtain + * a handle to this default service using + * {@link #getDefaultService getDefaultService()} and change its configuration + * with {@link #setDefaultService setDefaultService()}. + * + * You may also create a {@link Driver} with its own driver service. This is + * useful if you need to capture the server's log output for a specific session: + * + * let chrome = require('selenium-webdriver/chrome'); + * + * let service = new chrome.ServiceBuilder() + * .loggingTo('/my/log/file.txt') + * .enableVerboseLogging() + * .build(); + * + * let options = new chrome.Options(); + * // configure browser options ... + * + * let driver = new chrome.Driver(options, service); + * + * Users should only instantiate the {@link Driver} class directly when they + * need a custom driver service configuration (as shown above). For normal + * operation, users should start Chrome using the + * {@link selenium-webdriver.Builder}. + * + * __Working with Android__ + * + * The [ChromeDriver][android] supports running tests on the Chrome browser as + * well as [WebView apps][webview] starting in Android 4.4 (KitKat). In order to + * work with Android, you must first start the adb + * + * adb start-server + * + * By default, adb will start on port 5037. You may change this port, but this + * will require configuring a [custom server](#custom-server) that will connect + * to adb on the {@linkplain ServiceBuilder#setAdbPort correct port}: + * + * let service = new chrome.ServiceBuilder() + * .setAdbPort(1234) + * build(); + * // etc. + * + * The ChromeDriver may be configured to launch Chrome on Android using + * {@link Options#androidChrome()}: + * + * let driver = new Builder() + * .forBrowser('chrome') + * .setChromeOptions(new chrome.Options().androidChrome()) + * .build(); + * + * Alternatively, you can configure the ChromeDriver to launch an app with a + * Chrome-WebView by setting the {@linkplain Options#androidActivity + * androidActivity} option: + * + * let driver = new Builder() + * .forBrowser('chrome') + * .setChromeOptions(new chrome.Options() + * .androidPackage('com.example') + * .androidActivity('com.example.Activity')) + * .build(); + * + * [Refer to the ChromeDriver site] for more information on using the + * [ChromeDriver with Android][android]. + * + * [ChromeDriver]: https://sites.google.com/a/chromium.org/chromedriver/ + * [ChromeDriver release]: http://chromedriver.storage.googleapis.com/index.html + * [PATH]: http://en.wikipedia.org/wiki/PATH_%28variable%29 + * [android]: https://sites.google.com/a/chromium.org/chromedriver/getting-started/getting-started---android + * [webview]: https://developer.chrome.com/multidevice/webview/overview + */ + +'use strict'; + +const fs = require('fs'), + util = require('util'); + +const executors = require('./executors'), + http = require('./http'), + io = require('./io'), + Capabilities = require('./lib/capabilities').Capabilities, + Capability = require('./lib/capabilities').Capability, + command = require('./lib/command'), + logging = require('./lib/logging'), + promise = require('./lib/promise'), + Symbols = require('./lib/symbols'), + webdriver = require('./lib/webdriver'), + portprober = require('./net/portprober'), + remote = require('./remote'); + + +/** + * Name of the ChromeDriver executable. + * @type {string} + * @const + */ +const CHROMEDRIVER_EXE = + process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver'; + + +/** + * Custom command names supported by ChromeDriver. + * @enum {string} + */ +const Command = { + LAUNCH_APP: 'launchApp' +}; + + +/** + * Creates a command executor with support for ChromeDriver's custom commands. + * @param {!promise.Promise} url The server's URL. + * @return {!command.Executor} The new command executor. + */ +function createExecutor(url) { + return new executors.DeferredExecutor(url.then(function(url) { + let client = new http.HttpClient(url); + let executor = new http.Executor(client); + executor.defineCommand( + Command.LAUNCH_APP, + 'POST', '/session/:sessionId/chromium/launch_app'); + return executor; + })); +} + + +/** + * Creates {@link selenium-webdriver/remote.DriverService} instances that manage + * a [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/) + * server in a child process. + */ +class ServiceBuilder { + /** + * @param {string=} opt_exe Path to the server executable to use. If omitted, + * the builder will attempt to locate the chromedriver on the current + * PATH. + * @throws {Error} If provided executable does not exist, or the chromedriver + * cannot be found on the PATH. + */ + constructor(opt_exe) { + let exe = opt_exe || io.findInPath(CHROMEDRIVER_EXE, true); + if (!exe) { + throw Error( + 'The ChromeDriver could not be found on the current PATH. Please ' + + 'download the latest version of the ChromeDriver from ' + + 'http://chromedriver.storage.googleapis.com/index.html and ensure ' + + 'it can be found on your PATH.'); + } + + if (!fs.existsSync(exe)) { + throw Error('File does not exist: ' + exe); + } + /** @private {string} */ + this.exe_ = exe; + + /** @private {!Array} */ + this.args_ = []; + + /** + * @private {(string|!Array)} + */ + this.stdio_ = 'ignore'; + + /** @private {?string} */ + this.path_ = null; + + /** @private {number} */ + this.port_ = 0; + + /** @private {Object} */ + this.env_ = null; + } + + /** + * Sets the port to start the ChromeDriver on. + * @param {number} port The port to use, or 0 for any free port. + * @return {!ServiceBuilder} A self reference. + * @throws {Error} If the port is invalid. + */ + usingPort(port) { + if (port < 0) { + throw Error('port must be >= 0: ' + port); + } + this.port_ = port; + return this; + } + + /** + * Sets which port adb is listening to. _The ChromeDriver will connect to adb + * if an {@linkplain Options#androidPackage Android session} is requested, but + * adb **must** be started beforehand._ + * + * @param {number} port Which port adb is running on. + * @return {!ServiceBuilder} A self reference. + */ + setAdbPort(port) { + this.args_.push('--adb-port=' + port); + return this; + } + + /** + * Sets the path of the log file the driver should log to. If a log file is + * not specified, the driver will log to stderr. + * @param {string} path Path of the log file to use. + * @return {!ServiceBuilder} A self reference. + */ + loggingTo(path) { + this.args_.push('--log-path=' + path); + return this; + } + + /** + * Enables verbose logging. + * @return {!ServiceBuilder} A self reference. + */ + enableVerboseLogging() { + this.args_.push('--verbose'); + return this; + } + + /** + * Sets the number of threads the driver should use to manage HTTP requests. + * By default, the driver will use 4 threads. + * @param {number} n The number of threads to use. + * @return {!ServiceBuilder} A self reference. + */ + setNumHttpThreads(n) { + this.args_.push('--http-threads=' + n); + return this; + } + + /** + * Sets the base path for WebDriver REST commands (e.g. "/wd/hub"). + * By default, the driver will accept commands relative to "/". + * @param {string} path The base path to use. + * @return {!ServiceBuilder} A self reference. + */ + setUrlBasePath(path) { + this.args_.push('--url-base=' + path); + this.path_ = path; + return this; + } + + /** + * Defines the stdio configuration for the driver service. See + * {@code child_process.spawn} for more information. + * @param {(string|!Array)} + * config The configuration to use. + * @return {!ServiceBuilder} A self reference. + */ + setStdio(config) { + this.stdio_ = config; + return this; + } + + /** + * Defines the environment to start the server under. This settings will be + * inherited by every browser session started by the server. + * @param {!Object} env The environment to use. + * @return {!ServiceBuilder} A self reference. + */ + withEnvironment(env) { + this.env_ = env; + return this; + } + + /** + * Creates a new DriverService using this instance's current configuration. + * @return {!remote.DriverService} A new driver service using this instance's + * current configuration. + * @throws {Error} If the driver exectuable was not specified and a default + * could not be found on the current PATH. + */ + build() { + let port = this.port_ || portprober.findFreePort(); + let args = this.args_.concat(); // Defensive copy. + + return new remote.DriverService(this.exe_, { + loopback: true, + path: this.path_, + port: port, + args: promise.when(port, function(port) { + return args.concat('--port=' + port); + }), + env: this.env_, + stdio: this.stdio_ + }); + } +} + + + +/** @type {remote.DriverService} */ +let defaultService = null; + + +/** + * Sets the default service to use for new ChromeDriver instances. + * @param {!remote.DriverService} service The service to use. + * @throws {Error} If the default service is currently running. + */ +function setDefaultService(service) { + if (defaultService && defaultService.isRunning()) { + throw Error( + 'The previously configured ChromeDriver service is still running. ' + + 'You must shut it down before you may adjust its configuration.'); + } + defaultService = service; +} + + +/** + * Returns the default ChromeDriver service. If such a service has not been + * configured, one will be constructed using the default configuration for + * a ChromeDriver executable found on the system PATH. + * @return {!remote.DriverService} The default ChromeDriver service. + */ +function getDefaultService() { + if (!defaultService) { + defaultService = new ServiceBuilder().build(); + } + return defaultService; +} + + +/** + * @type {string} + * @const + */ +let OPTIONS_CAPABILITY_KEY = 'chromeOptions'; + + +/** + * Class for managing ChromeDriver specific options. + */ +class Options { + constructor() { + /** @private {!Object} */ + this.options_ = {}; + + /** @private {!Array<(string|!Buffer)>} */ + this.extensions_ = []; + + /** @private {?logging.Preferences} */ + this.logPrefs_ = null; + + /** @private {?./lib/capabilities.ProxyConfig} */ + this.proxy_ = null; + } + + /** + * Extracts the ChromeDriver specific options from the given capabilities + * object. + * @param {!Capabilities} caps The capabilities object. + * @return {!Options} The ChromeDriver options. + */ + static fromCapabilities(caps) { + let options = new Options(); + + let o = caps.get(OPTIONS_CAPABILITY_KEY); + if (o instanceof Options) { + options = o; + } else if (o) { + options. + addArguments(o.args || []). + addExtensions(o.extensions || []). + detachDriver(o.detach). + excludeSwitches(o.excludeSwitches || []). + setChromeBinaryPath(o.binary). + setChromeLogFile(o.logPath). + setChromeMinidumpPath(o.minidumpPath). + setLocalState(o.localState). + setMobileEmulation(o.mobileEmulation). + setUserPreferences(o.prefs). + setPerfLoggingPrefs(o.perfLoggingPrefs); + } + + if (caps.has(Capability.PROXY)) { + options.setProxy(caps.get(Capability.PROXY)); + } + + if (caps.has(Capability.LOGGING_PREFS)) { + options.setLoggingPrefs( + caps.get(Capability.LOGGING_PREFS)); + } + + return options; + } + + /** + * Add additional command line arguments to use when launching the Chrome + * browser. Each argument may be specified with or without the "--" prefix + * (e.g. "--foo" and "foo"). Arguments with an associated value should be + * delimited by an "=": "foo=bar". + * @param {...(string|!Array)} var_args The arguments to add. + * @return {!Options} A self reference. + */ + addArguments(var_args) { + let args = this.options_.args || []; + args = args.concat.apply(args, arguments); + if (args.length) { + this.options_.args = args; + } + return this; + } + + /** + * List of Chrome command line switches to exclude that ChromeDriver by default + * passes when starting Chrome. Do not prefix switches with "--". + * + * @param {...(string|!Array)} var_args The switches to exclude. + * @return {!Options} A self reference. + */ + excludeSwitches(var_args) { + let switches = this.options_.excludeSwitches || []; + switches = switches.concat.apply(switches, arguments); + if (switches.length) { + this.options_.excludeSwitches = switches; + } + return this; + } + + /** + * Add additional extensions to install when launching Chrome. Each extension + * should be specified as the path to the packed CRX file, or a Buffer for an + * extension. + * @param {...(string|!Buffer|!Array<(string|!Buffer)>)} var_args The + * extensions to add. + * @return {!Options} A self reference. + */ + addExtensions(var_args) { + this.extensions_ = + this.extensions_.concat.apply(this.extensions_, arguments); + return this; + } + + /** + * Sets the path to the Chrome binary to use. On Mac OS X, this path should + * reference the actual Chrome executable, not just the application binary + * (e.g. "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"). + * + * The binary path be absolute or relative to the chromedriver server + * executable, but it must exist on the machine that will launch Chrome. + * + * @param {string} path The path to the Chrome binary to use. + * @return {!Options} A self reference. + */ + setChromeBinaryPath(path) { + this.options_.binary = path; + return this; + } + + /** + * Sets whether to leave the started Chrome browser running if the controlling + * ChromeDriver service is killed before {@link webdriver.WebDriver#quit()} is + * called. + * @param {boolean} detach Whether to leave the browser running if the + * chromedriver service is killed before the session. + * @return {!Options} A self reference. + */ + detachDriver(detach) { + this.options_.detach = detach; + return this; + } + + /** + * Sets the user preferences for Chrome's user profile. See the "Preferences" + * file in Chrome's user data directory for examples. + * @param {!Object} prefs Dictionary of user preferences to use. + * @return {!Options} A self reference. + */ + setUserPreferences(prefs) { + this.options_.prefs = prefs; + return this; + } + + /** + * Sets the logging preferences for the new session. + * @param {!logging.Preferences} prefs The logging preferences. + * @return {!Options} A self reference. + */ + setLoggingPrefs(prefs) { + this.logPrefs_ = prefs; + return this; + } + + /** + * Sets the performance logging preferences. Options include: + * + * - `enableNetwork`: Whether or not to collect events from Network domain. + * - `enablePage`: Whether or not to collect events from Page domain. + * - `enableTimeline`: Whether or not to collect events from Timeline domain. + * Note: when tracing is enabled, Timeline domain is implicitly disabled, + * unless `enableTimeline` is explicitly set to true. + * - `tracingCategories`: A comma-separated string of Chrome tracing + * categories for which trace events should be collected. An unspecified + * or empty string disables tracing. + * - `bufferUsageReportingInterval`: The requested number of milliseconds + * between DevTools trace buffer usage events. For example, if 1000, then + * once per second, DevTools will report how full the trace buffer is. If + * a report indicates the buffer usage is 100%, a warning will be issued. + * + * @param {{enableNetwork: boolean, + * enablePage: boolean, + * enableTimeline: boolean, + * tracingCategories: string, + * bufferUsageReportingInterval: number}} prefs The performance + * logging preferences. + * @return {!Options} A self reference. + */ + setPerfLoggingPrefs(prefs) { + this.options_.perfLoggingPrefs = prefs; + return this; + } + + /** + * Sets preferences for the "Local State" file in Chrome's user data + * directory. + * @param {!Object} state Dictionary of local state preferences. + * @return {!Options} A self reference. + */ + setLocalState(state) { + this.options_.localState = state; + return this; + } + + /** + * Sets the name of the activity hosting a Chrome-based Android WebView. This + * option must be set to connect to an [Android WebView]( + * https://sites.google.com/a/chromium.org/chromedriver/getting-started/getting-started---android) + * + * @param {string} name The activity name. + * @return {!Options} A self reference. + */ + androidActivity(name) { + this.options_.androidActivity = name; + return this; + } + + /** + * Sets the device serial number to connect to via ADB. If not specified, the + * ChromeDriver will select an unused device at random. An error will be + * returned if all devices already have active sessions. + * + * @param {string} serial The device serial number to connect to. + * @return {!Options} A self reference. + */ + androidDeviceSerial(serial) { + this.options_.androidDeviceSerial = serial; + return this; + } + + /** + * Configures the ChromeDriver to launch Chrome on Android via adb. This + * function is shorthand for + * {@link #androidPackage options.androidPackage('com.android.chrome')}. + * @return {!Options} A self reference. + */ + androidChrome() { + return this.androidPackage('com.android.chrome'); + } + + /** + * Sets the package name of the Chrome or WebView app. + * + * @param {?string} pkg The package to connect to, or `null` to disable Android + * and switch back to using desktop Chrome. + * @return {!Options} A self reference. + */ + androidPackage(pkg) { + this.options_.androidPackage = pkg; + return this; + } + + /** + * Sets the process name of the Activity hosting the WebView (as given by + * `ps`). If not specified, the process name is assumed to be the same as + * {@link #androidPackage}. + * + * @param {string} processName The main activity name. + * @return {!Options} A self reference. + */ + androidProcess(processName) { + this.options_.androidProcess = processName; + return this; + } + + /** + * Sets whether to connect to an already-running instead of the specified + * {@linkplain #androidProcess app} instead of launching the app with a clean + * data directory. + * + * @param {boolean} useRunning Whether to connect to a running instance. + * @return {!Options} A self reference. + */ + androidUseRunningApp(useRunning) { + this.options_.androidUseRunningApp = useRunning; + return this; + } + + /** + * Sets the path to Chrome's log file. This path should exist on the machine + * that will launch Chrome. + * @param {string} path Path to the log file to use. + * @return {!Options} A self reference. + */ + setChromeLogFile(path) { + this.options_.logPath = path; + return this; + } + + /** + * Sets the directory to store Chrome minidumps in. This option is only + * supported when ChromeDriver is running on Linux. + * @param {string} path The directory path. + * @return {!Options} A self reference. + */ + setChromeMinidumpPath(path) { + this.options_.minidumpPath = path; + return this; + } + + /** + * Configures Chrome to emulate a mobile device. For more information, refer + * to the ChromeDriver project page on [mobile emulation][em]. Configuration + * options include: + * + * - `deviceName`: The name of a pre-configured [emulated device][devem] + * - `width`: screen width, in pixels + * - `height`: screen height, in pixels + * - `pixelRatio`: screen pixel ratio + * + * __Example 1: Using a Pre-configured Device__ + * + * let options = new chrome.Options().setMobileEmulation( + * {deviceName: 'Google Nexus 5'}); + * + * let driver = new chrome.Driver(options); + * + * __Example 2: Using Custom Screen Configuration__ + * + * let options = new chrome.Options().setMobileEmulation({ + * width: 360, + * height: 640, + * pixelRatio: 3.0 + * }); + * + * let driver = new chrome.Driver(options); + * + * + * [em]: https://sites.google.com/a/chromium.org/chromedriver/mobile-emulation + * [devem]: https://developer.chrome.com/devtools/docs/device-mode + * + * @param {?({deviceName: string}| + * {width: number, height: number, pixelRatio: number})} config The + * mobile emulation configuration, or `null` to disable emulation. + * @return {!Options} A self reference. + */ + setMobileEmulation(config) { + this.options_.mobileEmulation = config; + return this; + } + + /** + * Sets the proxy settings for the new session. + * @param {./lib/capabilities.ProxyConfig} proxy The proxy configuration to + * use. + * @return {!Options} A self reference. + */ + setProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * Converts this options instance to a {@link Capabilities} object. + * @param {Capabilities=} opt_capabilities The capabilities to merge + * these options into, if any. + * @return {!Capabilities} The capabilities. + */ + toCapabilities(opt_capabilities) { + let caps = opt_capabilities || Capabilities.chrome(); + caps. + set(Capability.PROXY, this.proxy_). + set(Capability.LOGGING_PREFS, this.logPrefs_). + set(OPTIONS_CAPABILITY_KEY, this); + return caps; + } + + /** + * Converts this instance to its JSON wire protocol representation. Note this + * function is an implementation not intended for general use. + * @return {!Object} The JSON wire protocol representation of this instance. + */ + [Symbols.serialize]() { + let json = {}; + for (let key in this.options_) { + if (this.options_[key] != null) { + json[key] = this.options_[key]; + } + } + if (this.extensions_.length) { + json.extensions = this.extensions_.map(function(extension) { + if (Buffer.isBuffer(extension)) { + return extension.toString('base64'); + } + return promise.checkedNodeCall( + fs.readFile, extension, 'base64'); + }); + } + return json; + } +} + + +/** + * Creates a new WebDriver client for Chrome. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(Capabilities|Options)=} opt_config The configuration + * options. + * @param {remote.DriverService=} opt_service The session to use; will use + * the {@linkplain #getDefaultService default service} by default. + * @param {promise.ControlFlow=} opt_flow The control flow to use, + * or {@code null} to use the currently active flow. + */ + constructor(opt_config, opt_service, opt_flow) { + let service = opt_service || getDefaultService(); + let executor = createExecutor(service.start()); + + let caps = + opt_config instanceof Options ? opt_config.toCapabilities() : + (opt_config || Capabilities.chrome()); + + let driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + + super(driver.getSession(), executor, driver.controlFlow()); + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() {} + + /** + * Schedules a command to launch Chrome App with given ID. + * @param {string} id ID of the App to launch. + * @return {!promise.Promise} A promise that will be resolved + * when app is launched. + */ + launchApp(id) { + return this.schedule( + new command.Command(Command.LAUNCH_APP).setParameter('id', id), + 'Driver.launchApp()'); + } +} + + +// PUBLIC API + + +exports.Driver = Driver; +exports.Options = Options; +exports.ServiceBuilder = ServiceBuilder; +exports.getDefaultService = getDefaultService; +exports.setDefaultService = setDefaultService; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/edge.js b/platforms/android/assets/www/node_modules/selenium-webdriver/edge.js new file mode 100644 index 0000000..676637a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/edge.js @@ -0,0 +1,378 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a {@linkplain Driver WebDriver} client for + * Microsoft's Edge web browser. Before using this module, + * you must download and install the latest + * [MicrosoftEdgeDriver](http://go.microsoft.com/fwlink/?LinkId=619687) server. + * Ensure that the MicrosoftEdgeDriver is on your + * [PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). + * + * There are three primary classes exported by this module: + * + * 1. {@linkplain ServiceBuilder}: configures the + * {@link ./remote.DriverService remote.DriverService} + * that manages the [MicrosoftEdgeDriver] child process. + * + * 2. {@linkplain Options}: defines configuration options for each new + * MicrosoftEdgeDriver session, such as which + * {@linkplain Options#setProxy proxy} to use when starting the browser. + * + * 3. {@linkplain Driver}: the WebDriver client; each new instance will control + * a unique browser session. + * + * __Customizing the MicrosoftEdgeDriver Server__ + * + * By default, every MicrosoftEdge session will use a single driver service, + * which is started the first time a {@link Driver} instance is created and + * terminated when this process exits. The default service will inherit its + * environment from the current process. + * You may obtain a handle to this default service using + * {@link #getDefaultService getDefaultService()} and change its configuration + * with {@link #setDefaultService setDefaultService()}. + * + * You may also create a {@link Driver} with its own driver service. This is + * useful if you need to capture the server's log output for a specific session: + * + * var edge = require('selenium-webdriver/edge'); + * + * var service = new edge.ServiceBuilder() + * .usingPort(55555) + * .build(); + * + * var options = new edge.Options(); + * // configure browser options ... + * + * var driver = new edge.Driver(options, service); + * + * Users should only instantiate the {@link Driver} class directly when they + * need a custom driver service configuration (as shown above). For normal + * operation, users should start MicrosoftEdge using the + * {@link ./builder.Builder selenium-webdriver.Builder}. + * + * [MicrosoftEdgeDriver]: https://msdn.microsoft.com/en-us/library/mt188085(v=vs.85).aspx + */ + +'use strict'; + +const fs = require('fs'), + util = require('util'); + +const executors = require('./executors'), + io = require('./io'), + capabilities = require('./lib/capabilities'), + promise = require('./lib/promise'), + Symbols = require('./lib/symbols'), + webdriver = require('./lib/webdriver'), + portprober = require('./net/portprober'), + remote = require('./remote'); + +const EDGEDRIVER_EXE = 'MicrosoftWebDriver.exe'; + + +/** + * Option keys. + * @enum {string} + */ +const CAPABILITY_KEY = { + PAGE_LOAD_STRATEGY: 'pageLoadStrategy' +}; + + +/** + * Class for managing MicrosoftEdgeDriver specific options. + */ +class Options { + constructor() { + /** @private {!Object} */ + this.options_ = {}; + + /** @private {?capabilities.ProxyConfig} */ + this.proxy_ = null; + } + + /** + * Extracts the MicrosoftEdgeDriver specific options from the given + * capabilities object. + * @param {!capabilities.Capabilities} caps The capabilities object. + * @return {!Options} The MicrosoftEdgeDriver options. + */ + static fromCapabilities(caps) { + var options = new Options(); + var map = options.options_; + + Object.keys(CAPABILITY_KEY).forEach(function(key) { + key = CAPABILITY_KEY[key]; + if (caps.has(key)) { + map[key] = caps.get(key); + } + }); + + if (caps.has(capabilities.Capability.PROXY)) { + options.setProxy(caps.get(capabilities.Capability.PROXY)); + } + + return options; + } + + /** + * Sets the proxy settings for the new session. + * @param {capabilities.ProxyConfig} proxy The proxy configuration to use. + * @return {!Options} A self reference. + */ + setProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * Sets the page load strategy for Edge. + * Supported values are "normal", "eager", and "none"; + * + * @param {string} pageLoadStrategy The page load strategy to use. + * @return {!Options} A self reference. + */ + setPageLoadStrategy(pageLoadStrategy) { + this.options_[CAPABILITY_KEY.PAGE_LOAD_STRATEGY] = + pageLoadStrategy.toLowerCase(); + return this; + } + + /** + * Converts this options instance to a {@link capabilities.Capabilities} + * object. + * @param {capabilities.Capabilities=} opt_capabilities The capabilities to + * merge these options into, if any. + * @return {!capabilities.Capabilities} The capabilities. + */ + toCapabilities(opt_capabilities) { + var caps = opt_capabilities || capabilities.Capabilities.edge(); + if (this.proxy_) { + caps.set(capabilities.Capability.PROXY, this.proxy_); + } + Object.keys(this.options_).forEach(function(key) { + caps.set(key, this.options_[key]); + }, this); + return caps; + } + + /** + * Converts this instance to its JSON wire protocol representation. Note this + * function is an implementation not intended for general use. + * @return {{pageLoadStrategy: (string|undefined)}} + * The JSON wire protocol representation of this instance. + */ + [Symbols.serialize]() { + var json = {}; + for (var key in this.options_) { + if (this.options_[key] != null) { + json[key] = this.options_[key]; + } + } + return json; + } +} + + +/** + * Creates {@link remote.DriverService} instances that manage a + * MicrosoftEdgeDriver server in a child process. + */ +class ServiceBuilder { + /** + * @param {string=} opt_exe Path to the server executable to use. If omitted, + * the builder will attempt to locate the MicrosoftEdgeDriver on the current + * PATH. + * @throws {Error} If provided executable does not exist, or the + * MicrosoftEdgeDriver cannot be found on the PATH. + */ + constructor(opt_exe) { + let exe = opt_exe || io.findInPath(EDGEDRIVER_EXE, true); + if (!exe) { + throw Error( + 'The ' + EDGEDRIVER_EXE + ' could not be found on the current PATH. ' + + 'Please download the latest version of the MicrosoftEdgeDriver from ' + + 'https://www.microsoft.com/en-us/download/details.aspx?id=48212 and ' + + 'ensure it can be found on your PATH.'); + } else if (!fs.existsSync(exe)) { + throw Error('File does not exist: ' + exe); + } + + /** @private {string} */ + this.exe_ = /** @type {string} */(exe); + + /** @private {!Array.} */ + this.args_ = []; + + /** @private {number} */ + this.port_ = 0; + + /** + * @private {(string|!Array.)} + */ + this.stdio_ = 'ignore'; + + /** @private {Object.} */ + this.env_ = null; + } + + /** + * Defines the stdio configuration for the driver service. See + * {@code child_process.spawn} for more information. + * @param {(string|!Array.)} + * config The configuration to use. + * @return {!ServiceBuilder} A self reference. + */ + setStdio(config) { + this.stdio_ = config; + return this; + } + + /** + * Sets the port to start the MicrosoftEdgeDriver on. + * @param {number} port The port to use, or 0 for any free port. + * @return {!ServiceBuilder} A self reference. + * @throws {Error} If the port is invalid. + */ + usingPort(port) { + if (port < 0) { + throw Error('port must be >= 0: ' + port); + } + this.port_ = port; + return this; + } + + /** + * Defines the environment to start the server under. This settings will be + * inherited by every browser session started by the server. + * @param {!Object.} env The environment to use. + * @return {!ServiceBuilder} A self reference. + */ + withEnvironment(env) { + this.env_ = env; + return this; + } + + /** + * Creates a new DriverService using this instance's current configuration. + * @return {!remote.DriverService} A new driver service using this instance's + * current configuration. + * @throws {Error} If the driver exectuable was not specified and a default + * could not be found on the current PATH. + */ + build() { + var port = this.port_ || portprober.findFreePort(); + var args = this.args_.concat(); // Defensive copy. + + return new remote.DriverService(this.exe_, { + // Binding to the loopback address will fail if not running with + // administrator privileges. Since we cannot test for that in script + // (or can we?), force the DriverService to use "localhost". + hostname: 'localhost', + port: port, + args: promise.fulfilled(port).then(function(port) { + return args.concat('--port=' + port); + }), + env: this.env_, + stdio: this.stdio_ + }); + } +} + + +/** @type {remote.DriverService} */ +var defaultService = null; + + +/** + * Sets the default service to use for new MicrosoftEdgeDriver instances. + * @param {!remote.DriverService} service The service to use. + * @throws {Error} If the default service is currently running. + */ +function setDefaultService(service) { + if (defaultService && defaultService.isRunning()) { + throw Error( + 'The previously configured EdgeDriver service is still running. ' + + 'You must shut it down before you may adjust its configuration.'); + } + defaultService = service; +} + + +/** + * Returns the default MicrosoftEdgeDriver service. If such a service has + * not been configured, one will be constructed using the default configuration + * for an MicrosoftEdgeDriver executable found on the system PATH. + * @return {!remote.DriverService} The default MicrosoftEdgeDriver service. + */ +function getDefaultService() { + if (!defaultService) { + defaultService = new ServiceBuilder().build(); + } + return defaultService; +} + + +/** + * Creates a new WebDriver client for Microsoft's Edge. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(capabilities.Capabilities|Options)=} opt_config The configuration + * options. + * @param {remote.DriverService=} opt_service The session to use; will use + * the {@linkplain #getDefaultService default service} by default. + * @param {promise.ControlFlow=} opt_flow The control flow to use, or + * {@code null} to use the currently active flow. + */ + constructor(opt_config, opt_service, opt_flow) { + var service = opt_service || getDefaultService(); + var executor = executors.createExecutor(service.start()); + + var caps = + opt_config instanceof Options ? opt_config.toCapabilities() : + (opt_config || capabilities.Capabilities.edge()); + + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + super(driver.getSession(), executor, driver.controlFlow()); + + var boundQuit = this.quit.bind(this); + + /** @override */ + this.quit = function() { + return boundQuit().thenFinally(service.kill.bind(service)); + }; + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() {} +} + + +// PUBLIC API + + +exports.Driver = Driver; +exports.Options = Options; +exports.ServiceBuilder = ServiceBuilder; +exports.getDefaultService = getDefaultService; +exports.setDefaultService = setDefaultService; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/error.js b/platforms/android/assets/www/node_modules/selenium-webdriver/error.js new file mode 100644 index 0000000..32af633 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/error.js @@ -0,0 +1,619 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * The base WebDriver error type. This error type is only used directly when a + * more appropriate category is not defined for the offending error. + */ +class WebDriverError extends Error { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + + /** @override */ + this.name = this.constructor.name; + } + + /** + * @return {number} the legacy numeric code for this class of error. + * @deprecated + */ + static get code() { + return ErrorCode.UNKNOWN_ERROR; + } + + /** + * @return {number} the legacy numeric code for this class of error. + * @deprecated + */ + get code() { + return this.constructor.code; + } +} + + +/** + * An attempt was made to select an element that cannot be selected. + */ +class ElementNotSelectableError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.ELEMENT_NOT_SELECTABLE; + } +} + + +/** + * An element command could not be completed because the element is not visible + * on the page. + */ +class ElementNotVisibleError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.ELEMENT_NOT_VISIBLE; + } +} + + +/** + * The arguments passed to a command are either invalid or malformed. + */ +class InvalidArgumentError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } +} + + +/** + * An illegal attempt was made to set a cookie under a different domain than + * the current page. + */ +class InvalidCookieDomainError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.INVALID_COOKIE_DOMAIN; + } +} + + +/** + * The coordinates provided to an interactions operation are invalid. + */ +class InvalidElementCoordinatesError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.INVALID_ELEMENT_COORDINATES; + } +} + + +/** + * An element command could not be completed because the element is in an + * invalid state, e.g. attempting to click an element that is no longer attached + * to the document. + */ +class InvalidElementStateError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.INVALID_ELEMENT_STATE; + } +} + + +/** + * Argument was an invalid selector. + */ +class InvalidSelectorError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.INVALID_SELECTOR_ERROR; + } +} + + +/** + * Occurs if the given session id is not in the list of active sessions, meaning + * the session either does not exist or that it’s not active. + */ +class InvalidSessionIdError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } +} + + +/** + * An error occurred while executing JavaScript supplied by the user. + */ +class JavascriptError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.JAVASCRIPT_ERROR; + } +} + + +/** + * The target for mouse interaction is not in the browser’s viewport and cannot + * be brought into that viewport. + */ +class MoveTargetOutOfBoundsError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS; + } +} + + +/** + * An attempt was made to operate on a modal dialog when one was not open. + */ +class NoSuchAlertError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.NO_SUCH_ALERT; + } +} + + +/** + * An element could not be located on the page using the given search + * parameters. + */ +class NoSuchElementError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.NO_SUCH_ELEMENT; + } +} + + +/** + * A request to switch to a frame could not be satisfied because the frame + * could not be found. + */ +class NoSuchFrameError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.NO_SUCH_FRAME; + } +} + + +/** + * A request to switch to a window could not be satisfied because the window + * could not be found. + */ +class NoSuchWindowError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.NO_SUCH_WINDOW; + } +} + + +/** + * A script did not complete before its timeout expired. + */ +class ScriptTimeoutError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.SCRIPT_TIMEOUT; + } +} + + +/** + * A new session could not be created. + */ +class SessionNotCreatedError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.SESSION_NOT_CREATED; + } +} + + + +/** + * An element command failed because the referenced element is no longer + * attached to the DOM. + */ +class StaleElementReferenceError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.STALE_ELEMENT_REFERENCE; + } +} + + +/** + * An operation did not complete before its timeout expired. + */ +class TimeoutError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.TIMEOUT; + } +} + + +/** + * A request to set a cookie’s value could not be satisfied. + */ +class UnableToSetCookieError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.UNABLE_TO_SET_COOKIE; + } +} + + +/** + * A screen capture operation was not possible. + */ +class UnableToCaptureScreenError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } +} + + +/** + * A modal dialog was open, blocking this operation. + */ +class UnexpectedAlertOpenError extends WebDriverError { + /** + * @param {string=} opt_error the error message, if any. + * @param {string=} opt_text the text of the open dialog, if available. + */ + constructor(opt_error, opt_text) { + super(opt_error); + + /** @private {(string|undefined)} */ + this.text_ = opt_text; + } + + /** @override */ + static get code() { + return ErrorCode.UNEXPECTED_ALERT_OPEN; + } + + /** + * @return {(string|undefined)} The text displayed with the unhandled alert, + * if available. + */ + getAlertText() { + return this.text_; + } +} + + +/** + * A command could not be executed because the remote end is not aware of it. + */ +class UnknownCommandError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.UNSUPPORTED_OPERATION; + } +} + + +/** + * The requested command matched a known URL but did not match an method for + * that URL. + */ +class UnknownMethodError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.UNSUPPORTED_OPERATION; + } +} + + +/** + * Reports an unsupport operation. + */ +class UnsupportedOperationError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.UNSUPPORTED_OPERATION; + } +} + +// TODO(jleyba): Define UnknownError as an alias of WebDriverError? + + +/** + * Enum of legacy error codes. + * TODO: remove this when all code paths have been switched to the new error + * types. + * @deprecated + * @enum {number} + */ +const ErrorCode = { + SUCCESS: 0, + NO_SUCH_ELEMENT: 7, + NO_SUCH_FRAME: 8, + UNKNOWN_COMMAND: 9, + UNSUPPORTED_OPERATION: 9, + STALE_ELEMENT_REFERENCE: 10, + ELEMENT_NOT_VISIBLE: 11, + INVALID_ELEMENT_STATE: 12, + UNKNOWN_ERROR: 13, + ELEMENT_NOT_SELECTABLE: 15, + JAVASCRIPT_ERROR: 17, + XPATH_LOOKUP_ERROR: 19, + TIMEOUT: 21, + NO_SUCH_WINDOW: 23, + INVALID_COOKIE_DOMAIN: 24, + UNABLE_TO_SET_COOKIE: 25, + UNEXPECTED_ALERT_OPEN: 26, + NO_SUCH_ALERT: 27, + SCRIPT_TIMEOUT: 28, + INVALID_ELEMENT_COORDINATES: 29, + IME_NOT_AVAILABLE: 30, + IME_ENGINE_ACTIVATION_FAILED: 31, + INVALID_SELECTOR_ERROR: 32, + SESSION_NOT_CREATED: 33, + MOVE_TARGET_OUT_OF_BOUNDS: 34, + SQL_DATABASE_ERROR: 35, + INVALID_XPATH_SELECTOR: 51, + INVALID_XPATH_SELECTOR_RETURN_TYPE: 52, + METHOD_NOT_ALLOWED: 405 +}; + + +const LEGACY_ERROR_CODE_TO_TYPE = new Map([ + [ErrorCode.NO_SUCH_ELEMENT, NoSuchElementError], + [ErrorCode.NO_SUCH_FRAME, NoSuchFrameError], + [ErrorCode.UNSUPPORTED_OPERATION, UnsupportedOperationError], + [ErrorCode.STALE_ELEMENT_REFERENCE, StaleElementReferenceError], + [ErrorCode.ELEMENT_NOT_VISIBLE, ElementNotVisibleError], + [ErrorCode.INVALID_ELEMENT_STATE, InvalidElementStateError], + [ErrorCode.UNKNOWN_ERROR, WebDriverError], + [ErrorCode.ELEMENT_NOT_SELECTABLE, ElementNotSelectableError], + [ErrorCode.JAVASCRIPT_ERROR, JavascriptError], + [ErrorCode.XPATH_LOOKUP_ERROR, InvalidSelectorError], + [ErrorCode.TIMEOUT, TimeoutError], + [ErrorCode.NO_SUCH_WINDOW, NoSuchWindowError], + [ErrorCode.INVALID_COOKIE_DOMAIN, InvalidCookieDomainError], + [ErrorCode.UNABLE_TO_SET_COOKIE, UnableToSetCookieError], + [ErrorCode.UNEXPECTED_ALERT_OPEN, UnexpectedAlertOpenError], + [ErrorCode.NO_SUCH_ALERT, NoSuchAlertError], + [ErrorCode.SCRIPT_TIMEOUT, ScriptTimeoutError], + [ErrorCode.INVALID_ELEMENT_COORDINATES, InvalidElementCoordinatesError], + [ErrorCode.INVALID_SELECTOR_ERROR, InvalidSelectorError], + [ErrorCode.SESSION_NOT_CREATED, SessionNotCreatedError], + [ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS, MoveTargetOutOfBoundsError], + [ErrorCode.INVALID_XPATH_SELECTOR, InvalidSelectorError], + [ErrorCode.INVALID_XPATH_SELECTOR_RETURN_TYPE, InvalidSelectorError], + [ErrorCode.METHOD_NOT_ALLOWED, UnsupportedOperationError]]); + + +const ERROR_CODE_TO_TYPE = new Map([ + ['unknown error', WebDriverError], + ['element not selectable', ElementNotSelectableError], + ['element not visible', ElementNotVisibleError], + ['invalid argument', InvalidArgumentError], + ['invalid cookie domain', InvalidCookieDomainError], + ['invalid element coordinates', InvalidElementCoordinatesError], + ['invalid element state', InvalidElementStateError], + ['invalid selector', InvalidSelectorError], + ['invalid session id', InvalidSessionIdError], + ['javascript error', JavascriptError], + ['move target out of bounds', MoveTargetOutOfBoundsError], + ['no such alert', NoSuchAlertError], + ['no such element', NoSuchElementError], + ['no such frame', NoSuchFrameError], + ['no such window', NoSuchWindowError], + ['script timeout', ScriptTimeoutError], + ['session not created', SessionNotCreatedError], + ['stale element reference', StaleElementReferenceError], + ['timeout', TimeoutError], + ['unable to set cookie', UnableToSetCookieError], + ['unable to capture screen', UnableToCaptureScreenError], + ['unexpected alert open', UnexpectedAlertOpenError], + ['unknown command', UnknownCommandError], + ['unknown method', UnknownMethodError], + ['unsupported operation', UnsupportedOperationError]]); + + +/** + * Checks a response object from a server that adheres to the W3C WebDriver + * protocol. + * @param {*} data The response data to check. + * @return {*} The response data if it was not an encoded error. + * @throws {WebDriverError} the decoded error, if present in the data object. + * @see https://w3c.github.io/webdriver/webdriver-spec.html#protocol + */ +function checkResponse(data) { + if (data && typeof data.error === 'string') { + let ctor = ERROR_CODE_TO_TYPE.get(data.error) || WebDriverError; + throw new ctor(data.message); + } + return data; +} + + +/** + * Checks a legacy response from the Selenium 2.0 wire protocol for an error. + * @param {*} responseObj the response object to check. + * @return {*} responseObj the original response if it does not define an error. + * @throws {WebDriverError} if the response object defines an error. + */ +function checkLegacyResponse(responseObj) { + // Handle the legacy Selenium error response format. + if (responseObj + && typeof responseObj === 'object' + && typeof responseObj['status'] === 'number' + && responseObj['status'] !== 0) { + let status = responseObj['status']; + let ctor = LEGACY_ERROR_CODE_TO_TYPE.get(status) || WebDriverError; + + let value = responseObj['value']; + + if (!value || typeof value !== 'object') { + throw new ctor(value + ''); + } else { + throw new ctor(value['message'] + ''); + } + } + return responseObj; +} + + +// PUBLIC API + + +exports.ErrorCode = ErrorCode; + +exports.WebDriverError = WebDriverError; +exports.ElementNotSelectableError = ElementNotSelectableError; +exports.ElementNotVisibleError = ElementNotVisibleError; +exports.InvalidArgumentError = InvalidArgumentError; +exports.InvalidCookieDomainError = InvalidCookieDomainError; +exports.InvalidElementCoordinatesError = InvalidElementCoordinatesError; +exports.InvalidElementStateError = InvalidElementStateError; +exports.InvalidSelectorError = InvalidSelectorError; +exports.InvalidSessionIdError = InvalidSessionIdError; +exports.JavascriptError = JavascriptError; +exports.MoveTargetOutOfBoundsError = MoveTargetOutOfBoundsError; +exports.NoSuchAlertError = NoSuchAlertError; +exports.NoSuchElementError = NoSuchElementError; +exports.NoSuchFrameError = NoSuchFrameError; +exports.NoSuchWindowError = NoSuchWindowError; +exports.ScriptTimeoutError = ScriptTimeoutError; +exports.SessionNotCreatedError = SessionNotCreatedError; +exports.StaleElementReferenceError = StaleElementReferenceError; +exports.TimeoutError = TimeoutError; +exports.UnableToSetCookieError = UnableToSetCookieError; +exports.UnableToCaptureScreenError = UnableToCaptureScreenError; +exports.UnexpectedAlertOpenError = UnexpectedAlertOpenError; +exports.UnknownCommandError = UnknownCommandError; +exports.UnknownMethodError = UnknownMethodError; +exports.UnsupportedOperationError = UnsupportedOperationError; + +exports.checkResponse = checkResponse; +exports.checkLegacyResponse = checkLegacyResponse; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/example/chrome_android.js b/platforms/android/assets/www/node_modules/selenium-webdriver/example/chrome_android.js new file mode 100644 index 0000000..990a4c4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/example/chrome_android.js @@ -0,0 +1,38 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview A basic example of working with Chrome on Android. Before + * running this example, you must start adb and connect a device (or start an + * AVD). + */ + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until, + chrome = require('../chrome'); + +var driver = new webdriver.Builder() + .forBrowser('chrome') + .setChromeOptions(new chrome.Options().androidChrome()) + .build(); + +driver.get('http://www.google.com/ncr'); +driver.findElement(By.name('q')).sendKeys('webdriver'); +driver.findElement(By.name('btnG')).click(); +driver.wait(until.titleIs('webdriver - Google Search'), 1000); +driver.quit(); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/example/chrome_mobile_emulation.js b/platforms/android/assets/www/node_modules/selenium-webdriver/example/chrome_mobile_emulation.js new file mode 100644 index 0000000..d308112 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/example/chrome_mobile_emulation.js @@ -0,0 +1,39 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview This is an example of emulating a mobile device using the + * ChromeDriver. + */ + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until, + chrome = require('../chrome'); + + +var driver = new webdriver.Builder() + .forBrowser('chrome') + .setChromeOptions(new chrome.Options() + .setMobileEmulation({deviceName: 'Google Nexus 5'})) + .build(); + +driver.get('http://www.google.com/ncr'); +driver.findElement(By.name('q')).sendKeys('webdriver'); +driver.findElement(By.name('btnG')).click(); +driver.wait(until.titleIs('webdriver - Google Search'), 1000); +driver.quit(); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/example/google_search.js b/platforms/android/assets/www/node_modules/selenium-webdriver/example/google_search.js new file mode 100644 index 0000000..c624fa2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/example/google_search.js @@ -0,0 +1,50 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview An example WebDriver script. This requires the chromedriver + * to be present on the system PATH. + * + * Usage: + * // Default behavior + * node selenium-webdriver/example/google_search.js + * + * // Target Chrome locally; the chromedriver must be on your PATH + * SELENIUM_BROWSER=chrome node selenium-webdriver/example/google_search.js + * + * // Use a local copy of the standalone Selenium server + * SELENIUM_SERVER_JAR=/path/to/selenium-server-standalone.jar \ + * node selenium-webdriver/example/google_search.js + * + * // Target a remove Selenium server + * SELENIUM_REMOTE_URL=http://www.example.com:4444/wd/hub \ + * node selenium-webdriver/example/google_search.js + */ + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until; + +var driver = new webdriver.Builder() + .forBrowser('firefox') + .build(); + +driver.get('http://www.google.com/ncr'); +driver.findElement(By.name('q')).sendKeys('webdriver'); +driver.findElement(By.name('btnG')).click(); +driver.wait(until.titleIs('webdriver - Google Search'), 1000); +driver.quit(); \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/example/google_search_generator.js b/platforms/android/assets/www/node_modules/selenium-webdriver/example/google_search_generator.js new file mode 100644 index 0000000..983c8d8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/example/google_search_generator.js @@ -0,0 +1,45 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview An example WebDriver script using generator functions. + * + * Usage: node selenium-webdriver/example/google_search_generator.js + */ + +var webdriver = require('..'), + By = webdriver.By; + +var driver = new webdriver.Builder() + .forBrowser('firefox') + .build(); + +driver.get('http://www.google.com/ncr'); +driver.call(function* () { + var query = yield driver.findElement(By.name('q')); + query.sendKeys('webdriver'); + + var submit = yield driver.findElement(By.name('btnG')); + submit.click(); +}); + +driver.wait(function* () { + var title = yield driver.getTitle(); + return 'webdriver - Google Search' === title; +}, 1000); + +driver.quit(); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/example/google_search_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/example/google_search_test.js new file mode 100644 index 0000000..823e2c5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/example/google_search_test.js @@ -0,0 +1,47 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview An example test that may be run using Mocha. + * Usage: mocha -t 10000 selenium-webdriver/example/google_search_test.js + */ + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until, + test = require('../testing'); + +test.describe('Google Search', function() { + var driver; + + test.before(function() { + driver = new webdriver.Builder() + .forBrowser('firefox') + .build(); + }); + + test.it('should append query to title', function() { + driver.get('http://www.google.com'); + driver.findElement(By.name('q')).sendKeys('webdriver'); + driver.findElement(By.name('btnG')).click(); + driver.wait(until.titleIs('webdriver - Google Search'), 1000); + }); + + test.after(function() { + driver.quit(); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/example/logging.js b/platforms/android/assets/www/node_modules/selenium-webdriver/example/logging.js new file mode 100644 index 0000000..ae1d4cc --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/example/logging.js @@ -0,0 +1,43 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Demonstrates how to use WebDriver's logging sysem. + */ + +'use strict'; + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until; + +webdriver.logging.installConsoleHandler(); +webdriver.logging.getLogger('webdriver.http') + .setLevel(webdriver.logging.Level.ALL); + +var driver = new webdriver.Builder() + .forBrowser('firefox') + .build(); + +driver.get('http://www.google.com/ncr'); + +var searchBox = driver.wait(until.elementLocated(By.name('q')), 3000); +searchBox.sendKeys('webdriver'); + +driver.findElement(By.name('btnG')).click(); +driver.wait(until.titleIs('webdriver - Google Search'), 1000); +driver.quit(); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/example/parallel_flows.js b/platforms/android/assets/www/node_modules/selenium-webdriver/example/parallel_flows.js new file mode 100644 index 0000000..f416922 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/example/parallel_flows.js @@ -0,0 +1,51 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview An example of starting multiple WebDriver clients that run + * in parallel in separate control flows. + */ + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until; + +for (var i = 0; i < 3; i++) { + (function(n) { + var flow = new webdriver.promise.ControlFlow() + .on('uncaughtException', function(e) { + console.log('uncaughtException in flow %d: %s', n, e); + }); + + var driver = new webdriver.Builder(). + forBrowser('firefox'). + setControlFlow(flow). // Comment out this line to see the difference. + build(); + + // Position and resize window so it's easy to see them running together. + driver.manage().window().setSize(600, 400); + driver.manage().window().setPosition(300 * i, 400 * i); + + driver.get('http://www.google.com'); + driver.findElement(By.name('q')).sendKeys('webdriver'); + driver.findElement(By.name('btnG')).click(); + driver.wait(until.titleIs('webdriver - Google Search'), 1000); + + driver.quit(); + })(i); +} + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/executors.js b/platforms/android/assets/www/node_modules/selenium-webdriver/executors.js new file mode 100644 index 0000000..17f222a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/executors.js @@ -0,0 +1,50 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Various utilities for working with {@link ./command.Executor} + * implementations. + */ + + 'use strict'; + +const HttpClient = require('./http').HttpClient, + HttpExecutor = require('./http').Executor, + DeferredExecutor = require('./lib/command').DeferredExecutor, + promise = require('./lib/promise'); + + +// PUBLIC API + + +/** @deprecated Use {@link ./lib/command.DeferredExecutor} instead. */ +exports.DeferredExecutor = DeferredExecutor; + +/** + * Creates a command executor that uses WebDriver's JSON wire protocol. + * @param {(string|!promise.Promise)} url The server's URL, + * or a promise that will resolve to that URL. + * @param {?string=} opt_proxy (optional) The URL of the HTTP proxy for the + * client to use. + * @returns {!./lib/command.Executor} The new command executor. + */ +exports.createExecutor = function(url, opt_proxy) { + return new DeferredExecutor(promise.when(url, function(url) { + var client = new HttpClient(url, null, opt_proxy); + return new HttpExecutor(client); + })); +}; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/binary.js b/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/binary.js new file mode 100644 index 0000000..48a4a0b --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/binary.js @@ -0,0 +1,221 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Manages Firefox binaries. This module is considered internal; + * users should use {@link ./firefox selenium-webdriver/firefox}. + */ + +'use strict'; + +const child = require('child_process'), + fs = require('fs'), + path = require('path'), + util = require('util'); + +const isDevMode = require('../lib/devmode'), + promise = require('../lib/promise'), + Symbols = require('../lib/symbols'), + io = require('../io'), + exec = require('../io/exec'); + + + +/** @const */ +const NO_FOCUS_LIB_X86 = isDevMode ? + path.join(__dirname, '../../../../cpp/prebuilt/i386/libnoblur.so') : + path.join(__dirname, '../lib/firefox/i386/libnoblur.so') ; + +/** @const */ +const NO_FOCUS_LIB_AMD64 = isDevMode ? + path.join(__dirname, '../../../../cpp/prebuilt/amd64/libnoblur64.so') : + path.join(__dirname, '../lib/firefox/amd64/libnoblur64.so') ; + +const X_IGNORE_NO_FOCUS_LIB = 'x_ignore_nofocus.so'; + +var foundBinary = null; + + +/** + * Checks the default Windows Firefox locations in Program Files. + * @return {!Promise} A promise for the located executable. + * The promise will resolve to {@code null} if Firefox was not found. + */ +function defaultWindowsLocation() { + var files = [ + process.env['PROGRAMFILES'] || 'C:\\Program Files', + process.env['PROGRAMFILES(X86)'] || 'C:\\Program Files (x86)' + ].map(function(prefix) { + return path.join(prefix, 'Mozilla Firefox\\firefox.exe'); + }); + return io.exists(files[0]).then(function(exists) { + return exists ? files[0] : io.exists(files[1]).then(function(exists) { + return exists ? files[1] : null; + }); + }); +} + + +/** + * Locates the Firefox binary for the current system. + * @return {!promise.Promise.} A promise for the located binary. The + * promise will be rejected if Firefox cannot be located. + */ +function findFirefox() { + if (foundBinary) { + return foundBinary; + } + + if (process.platform === 'darwin') { + var osxExe = '/Applications/Firefox.app/Contents/MacOS/firefox-bin'; + foundBinary = io.exists(osxExe).then(function(exists) { + return exists ? osxExe : null; + }); + } else if (process.platform === 'win32') { + foundBinary = defaultWindowsLocation(); + } else { + foundBinary = promise.fulfilled(io.findInPath('firefox')); + } + + return foundBinary = foundBinary.then(function(found) { + if (found) { + return found; + } + throw Error('Could not locate Firefox on the current system'); + }); +} + + +/** + * Copies the no focus libs into the given profile directory. + * @param {string} profileDir Path to the profile directory to install into. + * @return {!promise.Promise.} The LD_LIBRARY_PATH prefix string to use + * for the installed libs. + */ +function installNoFocusLibs(profileDir) { + var x86 = path.join(profileDir, 'x86'); + var amd64 = path.join(profileDir, 'amd64'); + + return mkdir(x86) + .then(copyLib.bind(null, NO_FOCUS_LIB_X86, x86)) + .then(mkdir.bind(null, amd64)) + .then(copyLib.bind(null, NO_FOCUS_LIB_AMD64, amd64)) + .then(function() { + return x86 + ':' + amd64; + }); + + function mkdir(dir) { + return io.exists(dir).then(function(exists) { + if (!exists) { + return promise.checkedNodeCall(fs.mkdir, dir); + } + }); + } + + function copyLib(src, dir) { + return io.copy(src, path.join(dir, X_IGNORE_NO_FOCUS_LIB)); + } +} + + +/** + * Provides a mechanism to configure and launch Firefox in a subprocess for + * use with WebDriver. + * + * @final + */ +class Binary { + /** + * @param {string=} opt_exe Path to the Firefox binary to use. If not + * specified, will attempt to locate Firefox on the current system. + */ + constructor(opt_exe) { + /** @private {(string|undefined)} */ + this.exe_ = opt_exe; + + /** @private {!Array.} */ + this.args_ = []; + + /** @private {!Object} */ + this.env_ = {}; + Object.assign(this.env_, process.env, { + MOZ_CRASHREPORTER_DISABLE: '1', + MOZ_NO_REMOTE: '1', + NO_EM_RESTART: '1' + }); + } + + /** + * Add arguments to the command line used to start Firefox. + * @param {...(string|!Array.)} var_args Either the arguments to add + * as varargs, or the arguments as an array. + */ + addArguments(var_args) { + for (var i = 0; i < arguments.length; i++) { + if (Array.isArray(arguments[i])) { + this.args_ = this.args_.concat(arguments[i]); + } else { + this.args_.push(arguments[i]); + } + } + } + + /** + * Launches Firefox and returns a promise that will be fulfilled when the + * process terminates. + * @param {string} profile Path to the profile directory to use. + * @return {!promise.Promise} A promise for the handle to the + * started subprocess. + */ + launch(profile) { + let env = {}; + Object.assign(env, this.env_, {XRE_PROFILE_PATH: profile}); + + let args = ['-foreground'].concat(this.args_); + + return promise.when(this.exe_ || findFirefox(), function(firefox) { + if (process.platform === 'win32' || process.platform === 'darwin') { + return exec(firefox, {args: args, env: env}); + } + return installNoFocusLibs(profile).then(function(ldLibraryPath) { + env['LD_LIBRARY_PATH'] = ldLibraryPath + ':' + env['LD_LIBRARY_PATH']; + env['LD_PRELOAD'] = X_IGNORE_NO_FOCUS_LIB; + return exec(firefox, {args: args, env: env}); + }); + }); + } + + /** + * Returns a promise for the wire representation of this binary. Note: the + * FirefoxDriver only supports passing the path to the binary executable over + * the wire; all command line arguments and environment variables will be + * discarded. + * + * @return {!promise.Promise} A promise for this binary's wire + * representation. + */ + [Symbols.serialize]() { + return promise.fulfilled(this.exe_ || findFirefox()); + } +} + + +// PUBLIC API + + +exports.Binary = Binary; + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/extension.js b/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/extension.js new file mode 100644 index 0000000..990481c --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/extension.js @@ -0,0 +1,177 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** @fileoverview Utilities for working with Firefox extensions. */ + +'use strict'; + +const AdmZip = require('adm-zip'), + fs = require('fs'), + path = require('path'), + xml = require('xml2js'); + +const promise = require('../lib/promise'), + checkedCall = promise.checkedNodeCall, + io = require('../io'); + + +/** + * Thrown when there an add-on is malformed. + */ +class AddonFormatError extends Error { + /** @param {string} msg The error message. */ + constructor(msg) { + super(msg); + /** @override */ + this.name = this.constructor.name; + } +} + + + +/** + * Installs an extension to the given directory. + * @param {string} extension Path to the extension to install, as either a xpi + * file or a directory. + * @param {string} dir Path to the directory to install the extension in. + * @return {!promise.Promise.} A promise for the add-on ID once + * installed. + */ +function install(extension, dir) { + return getDetails(extension).then(function(details) { + function returnId() { return details.id; } + + var dst = path.join(dir, details.id); + if (extension.slice(-4) === '.xpi') { + if (!details.unpack) { + return io.copy(extension, dst + '.xpi').then(returnId); + } else { + return checkedCall(fs.readFile, extension).then(function(buff) { + // TODO: find an async library for inflating a zip archive. + new AdmZip(buff).extractAllTo(dst, true); + }).then(returnId); + } + } else { + return io.copyDir(extension, dst).then(returnId); + } + }); +} + + +/** + * Describes a Firefox add-on. + * @typedef {{id: string, name: string, version: string, unpack: boolean}} + */ +var AddonDetails; + + +/** + * Extracts the details needed to install an add-on. + * @param {string} addonPath Path to the extension directory. + * @return {!promise.Promise.} A promise for the add-on details. + */ +function getDetails(addonPath) { + return readManifest(addonPath).then(function(doc) { + var em = getNamespaceId(doc, 'http://www.mozilla.org/2004/em-rdf#'); + var rdf = getNamespaceId( + doc, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); + + var description = doc[rdf + 'RDF'][rdf + 'Description'][0]; + var details = { + id: getNodeText(description, em + 'id'), + name: getNodeText(description, em + 'name'), + version: getNodeText(description, em + 'version'), + unpack: getNodeText(description, em + 'unpack') || false + }; + + if (typeof details.unpack === 'string') { + details.unpack = details.unpack.toLowerCase() === 'true'; + } + + if (!details.id) { + throw new AddonFormatError('Could not find add-on ID for ' + addonPath); + } + + return details; + }); + + function getNodeText(node, name) { + return node[name] && node[name][0] || ''; + } + + function getNamespaceId(doc, url) { + var keys = Object.keys(doc); + if (keys.length !== 1) { + throw new AddonFormatError('Malformed manifest for add-on ' + addonPath); + } + + var namespaces = doc[keys[0]].$; + var id = ''; + Object.keys(namespaces).some(function(ns) { + if (namespaces[ns] !== url) { + return false; + } + + if (ns.indexOf(':') != -1) { + id = ns.split(':')[1] + ':'; + } + return true; + }); + return id; + } +} + + +/** + * Reads the manifest for a Firefox add-on. + * @param {string} addonPath Path to a Firefox add-on as a xpi or an extension. + * @return {!promise.Promise} A promise for the parsed manifest. + */ +function readManifest(addonPath) { + var manifest; + + if (addonPath.slice(-4) === '.xpi') { + manifest = checkedCall(fs.readFile, addonPath).then(function(buff) { + var zip = new AdmZip(buff); + if (!zip.getEntry('install.rdf')) { + throw new AddonFormatError( + 'Could not find install.rdf in ' + addonPath); + } + var done = promise.defer(); + zip.readAsTextAsync('install.rdf', done.fulfill); + return done.promise; + }); + } else { + manifest = checkedCall(fs.stat, addonPath).then(function(stats) { + if (!stats.isDirectory()) { + throw Error( + 'Add-on path is niether a xpi nor a directory: ' + addonPath); + } + return checkedCall(fs.readFile, path.join(addonPath, 'install.rdf')); + }); + } + + return manifest.then(function(content) { + return checkedCall(xml.parseString, content); + }); +} + + +// PUBLIC API + + +exports.install = install; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/index.js b/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/index.js new file mode 100644 index 0000000..8d726ee --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/index.js @@ -0,0 +1,320 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines the {@linkplain Driver WebDriver} client for Firefox. + * Each FirefoxDriver instance will be created with an anonymous profile, + * ensuring browser historys do not share session data (cookies, history, cache, + * offline storage, etc.) + * + * __Customizing the Firefox Profile__ + * + * The {@link Profile} class may be used to configure the browser profile used + * with WebDriver, with functions to install additional + * {@linkplain Profile#addExtension extensions}, configure browser + * {@linkplain Profile#setPreference preferences}, and more. For example, you + * may wish to include Firebug: + * + * var firefox = require('selenium-webdriver/firefox'); + * + * var profile = new firefox.Profile(); + * profile.addExtension('/path/to/firebug.xpi'); + * profile.setPreference('extensions.firebug.showChromeErrors', true); + * + * var options = new firefox.Options().setProfile(profile); + * var driver = new firefox.Driver(options); + * + * The {@link Profile} class may also be used to configure WebDriver based on a + * pre-existing browser profile: + * + * var profile = new firefox.Profile( + * '/usr/local/home/bob/.mozilla/firefox/3fgog75h.testing'); + * var options = new firefox.Options().setProfile(profile); + * var driver = new firefox.Driver(options); + * + * The FirefoxDriver will _never_ modify a pre-existing profile; instead it will + * create a copy for it to modify. By extension, there are certain browser + * preferences that are required for WebDriver to function properly and they + * will always be overwritten. + * + * __Using a Custom Firefox Binary__ + * + * On Windows and OSX, the FirefoxDriver will search for Firefox in its + * default installation location: + * + * * Windows: C:\Program Files and C:\Program Files (x86). + * * Mac OS X: /Applications/Firefox.app + * + * For Linux, Firefox will be located on the PATH: `$(where firefox)`. + * + * You can configure WebDriver to start use a custom Firefox installation with + * the {@link Binary} class: + * + * var firefox = require('selenium-webdriver/firefox'); + * var binary = new firefox.Binary('/my/firefox/install/dir/firefox-bin'); + * var options = new firefox.Options().setBinary(binary); + * var driver = new firefox.Driver(options); + * + * __Remote Testing__ + * + * You may customize the Firefox binary and profile when running against a + * remote Selenium server. Your custom profile will be packaged as a zip and + * transfered to the remote host for use. The profile will be transferred + * _once for each new session_. The performance impact should be minimal if + * you've only configured a few extra browser preferences. If you have a large + * profile with several extensions, you should consider installing it on the + * remote host and defining its path via the {@link Options} class. Custom + * binaries are never copied to remote machines and must be referenced by + * installation path. + * + * var options = new firefox.Options() + * .setProfile('/profile/path/on/remote/host') + * .setBinary('/install/dir/on/remote/host/firefox-bin'); + * + * var driver = new (require('selenium-webdriver')).Builder() + * .forBrowser('firefox') + * .usingServer('http://127.0.0.1:4444/wd/hub') + * .setFirefoxOptions(options) + * .build(); + */ + +'use strict'; + +const url = require('url'); + +const Binary = require('./binary').Binary, + Profile = require('./profile').Profile, + decodeProfile = require('./profile').decode, + executors = require('../executors'), + httpUtil = require('../http/util'), + io = require('../io'), + capabilities = require('../lib/capabilities'), + logging = require('../lib/logging'), + promise = require('../lib/promise'), + webdriver = require('../lib/webdriver'), + net = require('../net'), + portprober = require('../net/portprober'); + + +/** + * Configuration options for the FirefoxDriver. + */ +class Options { + constructor() { + /** @private {Profile} */ + this.profile_ = null; + + /** @private {Binary} */ + this.binary_ = null; + + /** @private {logging.Preferences} */ + this.logPrefs_ = null; + + /** @private {?capabilities.ProxyConfig} */ + this.proxy_ = null; + } + + /** + * Sets the profile to use. The profile may be specified as a + * {@link Profile} object or as the path to an existing Firefox profile to use + * as a template. + * + * @param {(string|!Profile)} profile The profile to use. + * @return {!Options} A self reference. + */ + setProfile(profile) { + if (typeof profile === 'string') { + profile = new Profile(profile); + } + this.profile_ = profile; + return this; + } + + /** + * Sets the binary to use. The binary may be specified as the path to a Firefox + * executable, or as a {@link Binary} object. + * + * @param {(string|!Binary)} binary The binary to use. + * @return {!Options} A self reference. + */ + setBinary(binary) { + if (typeof binary === 'string') { + binary = new Binary(binary); + } + this.binary_ = binary; + return this; + } + + /** + * Sets the logging preferences for the new session. + * @param {logging.Preferences} prefs The logging preferences. + * @return {!Options} A self reference. + */ + setLoggingPreferences(prefs) { + this.logPrefs_ = prefs; + return this; + } + + /** + * Sets the proxy to use. + * + * @param {capabilities.ProxyConfig} proxy The proxy configuration to use. + * @return {!Options} A self reference. + */ + setProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * Converts these options to a {@link capabilities.Capabilities} instance. + * + * @return {!capabilities.Capabilities} A new capabilities object. + */ + toCapabilities() { + var caps = capabilities.Capabilities.firefox(); + if (this.logPrefs_) { + caps.set(capabilities.Capability.LOGGING_PREFS, this.logPrefs_); + } + if (this.proxy_) { + caps.set(capabilities.Capability.PROXY, this.proxy_); + } + if (this.binary_) { + caps.set('firefox_binary', this.binary_); + } + if (this.profile_) { + caps.set('firefox_profile', this.profile_); + } + return caps; + } +} + + +/** + * A WebDriver client for Firefox. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(Options|capabilities.Capabilities|Object)=} opt_config The + * configuration options for this driver, specified as either an + * {@link Options} or {@link capabilities.Capabilities}, or as a raw hash + * object. + * @param {promise.ControlFlow=} opt_flow The flow to + * schedule commands through. Defaults to the active flow object. + */ + constructor(opt_config, opt_flow) { + let caps; + if (opt_config instanceof Options) { + caps = opt_config.toCapabilities(); + } else { + caps = new capabilities.Capabilities(opt_config); + } + + let binary = caps.get('firefox_binary') || new Binary(); + if (typeof binary === 'string') { + binary = new Binary(binary); + } + + let profile = caps.get('firefox_profile') || new Profile(); + + caps.set('firefox_binary', null); + caps.set('firefox_profile', null); + + let self; // Cannot assign to 'this' until after we call super. + let freePort = portprober.findFreePort(); + let command = freePort.then(function(port) { + if (typeof profile === 'string') { + return decodeProfile(profile).then(function(dir) { + var profile = new Profile(dir); + profile.setPreference('webdriver_firefox_port', port); + return profile.writeToDisk(); + }); + } else { + profile.setPreference('webdriver_firefox_port', port); + return profile.writeToDisk(); + } + }).then(function(profileDir) { + self.profilePath_ = profileDir; + return binary.launch(profileDir); + }); + + let serverUrl = command + .then(function() { return freePort; }) + .then(function(/** number */port) { + var serverUrl = url.format({ + protocol: 'http', + hostname: net.getLoopbackAddress(), + port: port + '', + pathname: '/hub' + }); + + return httpUtil.waitForServer(serverUrl, 45 * 1000).then(function() { + return serverUrl; + }); + }); + + var executor = executors.createExecutor(serverUrl); + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + + super(driver.getSession(), executor, opt_flow); + self = this; + + /** @private {?string} */ + this.profilePath_ = null; + + /** @private */ + this.command_ = command; + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() { + } + + /** @override */ + quit() { + // TODO: use super.quit when closure compiler knows how to transpile it. + // let superQuit = super.quit; + return this.call(function() { + let self = this; + return webdriver.WebDriver.prototype.quit.call(this) + .thenFinally(function() { + return self.command_.then(function(command) { + command.kill(); + return command.result(); + }); + }) + .thenFinally(function() { + if (self.profilePath_) { + return io.rmDir(self.profilePath_); + } + }); + }, this); + } +} + + +// PUBLIC API + + +exports.Binary = Binary; +exports.Driver = Driver; +exports.Options = Options; +exports.Profile = Profile; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/profile.js b/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/profile.js new file mode 100644 index 0000000..13f1250 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/firefox/profile.js @@ -0,0 +1,413 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Profile management module. This module is considered internal; + * users should use {@link selenium-webdriver/firefox}. + */ + +'use strict'; + +const AdmZip = require('adm-zip'), + AdmConstants = require('adm-zip/util/constants'), + fs = require('fs'), + path = require('path'), + vm = require('vm'); + +const isDevMode = require('../lib/devmode'), + promise = require('../lib/promise'), + Symbols = require('../lib/symbols'), + io = require('../io'), + extension = require('./extension'); + + +/** @const */ +const WEBDRIVER_PREFERENCES_PATH = isDevMode + ? path.join(__dirname, '../../../firefox-driver/webdriver.json') + : path.join(__dirname, '../lib/firefox/webdriver.json'); + +/** @const */ +const WEBDRIVER_EXTENSION_PATH = isDevMode + ? path.join(__dirname, + '../../../../build/javascript/firefox-driver/webdriver.xpi') + : path.join(__dirname, '../lib/firefox/webdriver.xpi'); + +/** @const */ +const WEBDRIVER_EXTENSION_NAME = 'fxdriver@googlecode.com'; + + + +/** @type {Object} */ +var defaultPreferences = null; + +/** + * Synchronously loads the default preferences used for the FirefoxDriver. + * @return {!Object} The default preferences JSON object. + */ +function getDefaultPreferences() { + if (!defaultPreferences) { + var contents = /** @type {string} */( + fs.readFileSync(WEBDRIVER_PREFERENCES_PATH, 'utf8')); + defaultPreferences = /** @type {!Object} */(JSON.parse(contents)); + } + return defaultPreferences; +} + + +/** + * Parses a user.js file in a Firefox profile directory. + * @param {string} f Path to the file to parse. + * @return {!promise.Promise} A promise for the parsed preferences as + * a JSON object. If the file does not exist, an empty object will be + * returned. + */ +function loadUserPrefs(f) { + var done = promise.defer(); + fs.readFile(f, function(err, contents) { + if (err && err.code === 'ENOENT') { + done.fulfill({}); + return; + } + + if (err) { + done.reject(err); + return; + } + + var prefs = {}; + var context = vm.createContext({ + 'user_pref': function(key, value) { + prefs[key] = value; + } + }); + + vm.runInContext(/** @type {string} */(contents), context, f); + done.fulfill(prefs); + }); + return done.promise; +} + + + +/** + * @param {!Object} prefs The default preferences to write. Will be + * overridden by user.js preferences in the template directory and the + * frozen preferences required by WebDriver. + * @param {string} dir Path to the directory write the file to. + * @return {!promise.Promise} A promise for the profile directory, + * to be fulfilled when user preferences have been written. + */ +function writeUserPrefs(prefs, dir) { + var userPrefs = path.join(dir, 'user.js'); + return loadUserPrefs(userPrefs).then(function(overrides) { + Object.assign(prefs, overrides); + Object.assign(prefs, getDefaultPreferences()['frozen']); + + var contents = Object.keys(prefs).map(function(key) { + return 'user_pref(' + JSON.stringify(key) + ', ' + + JSON.stringify(prefs[key]) + ');'; + }).join('\n'); + + var done = promise.defer(); + fs.writeFile(userPrefs, contents, function(err) { + err && done.reject(err) || done.fulfill(dir); + }); + return done.promise; + }); +}; + + +/** + * Installs a group of extensions in the given profile directory. If the + * WebDriver extension is not included in this set, the default version + * bundled with this package will be installed. + * @param {!Array.} extensions The extensions to install, as a + * path to an unpacked extension directory or a path to a xpi file. + * @param {string} dir The profile directory to install to. + * @param {boolean=} opt_excludeWebDriverExt Whether to skip installation of + * the default WebDriver extension. + * @return {!Promise} A promise for the main profile directory + * once all extensions have been installed. + */ +function installExtensions(extensions, dir, opt_excludeWebDriverExt) { + var hasWebDriver = !!opt_excludeWebDriverExt; + var next = 0; + var extensionDir = path.join(dir, 'extensions'); + + return new Promise(function(fulfill, reject) { + io.exists(extensionDir).then(function(exists) { + if (!exists) { + return promise.checkedNodeCall(fs.mkdir, extensionDir); + } + }).then(installNext); + + function installNext() { + if (next >= extensions.length) { + if (hasWebDriver) { + fulfill(dir); + } else { + install(WEBDRIVER_EXTENSION_PATH); + } + } else { + install(extensions[next++]); + } + } + + function install(ext) { + extension.install(ext, extensionDir).then(function(id) { + hasWebDriver = hasWebDriver || (id === WEBDRIVER_EXTENSION_NAME); + installNext(); + }, reject); + } + }); +} + + +/** + * Decodes a base64 encoded profile. + * @param {string} data The base64 encoded string. + * @return {!Promise} A promise for the path to the decoded profile + * directory. + */ +function decode(data) { + return io.tmpFile().then(function(file) { + var buf = new Buffer(data, 'base64'); + return promise.checkedNodeCall(fs.writeFile, file, buf).then(function() { + return io.tmpDir(); + }).then(function(dir) { + var zip = new AdmZip(file); + zip.extractAllTo(dir); // Sync only? Why?? :-( + return dir; + }); + }); +} + + + +/** + * Models a Firefox proifle directory for use with the FirefoxDriver. The + * {@code Proifle} directory uses an in-memory model until {@link #writeToDisk} + * is called. + */ +class Profile { + /** + * @param {string=} opt_dir Path to an existing Firefox profile directory to + * use a template for this profile. If not specified, a blank profile will + * be used. + */ + constructor(opt_dir) { + /** @private {!Object} */ + this.preferences_ = {}; + + Object.assign(this.preferences_, getDefaultPreferences()['mutable']); + Object.assign(this.preferences_, getDefaultPreferences()['frozen']); + + /** @private {boolean} */ + this.nativeEventsEnabled_ = true; + + /** @private {(string|undefined)} */ + this.template_ = opt_dir; + + /** @private {number} */ + this.port_ = 0; + + /** @private {!Array} */ + this.extensions_ = []; + } + + /** + * Registers an extension to be included with this profile. + * @param {string} extension Path to the extension to include, as either an + * unpacked extension directory or the path to a xpi file. + */ + addExtension(extension) { + this.extensions_.push(extension); + } + + /** + * Sets a desired preference for this profile. + * @param {string} key The preference key. + * @param {(string|number|boolean)} value The preference value. + * @throws {Error} If attempting to set a frozen preference. + */ + setPreference(key, value) { + var frozen = getDefaultPreferences()['frozen']; + if (frozen.hasOwnProperty(key) && frozen[key] !== value) { + throw Error('You may not set ' + key + '=' + JSON.stringify(value) + + '; value is frozen for proper WebDriver functionality (' + + key + '=' + JSON.stringify(frozen[key]) + ')'); + } + this.preferences_[key] = value; + } + + /** + * Returns the currently configured value of a profile preference. This does + * not include any defaults defined in the profile's template directory user.js + * file (if a template were specified on construction). + * @param {string} key The desired preference. + * @return {(string|number|boolean|undefined)} The current value of the + * requested preference. + */ + getPreference(key) { + return this.preferences_[key]; + } + + /** + * Specifies which host the driver should listen for commands on. If not + * specified, the driver will default to "localhost". This option should be + * specified when "localhost" is not mapped to the loopback address + * (127.0.0.1) in `/etc/hosts`. + * + * @param {string} host the host the driver should listen for commands on + */ + setHost(host) { + this.preferences_['webdriver_firefox_allowed_hosts'] = host; + } + + /** + * @return {number} The port this profile is currently configured to use, or + * 0 if the port will be selected at random when the profile is written + * to disk. + */ + getPort() { + return this.port_; + } + + /** + * Sets the port to use for the WebDriver extension loaded by this profile. + * @param {number} port The desired port, or 0 to use any free port. + */ + setPort(port) { + this.port_ = port; + } + + /** + * @return {boolean} Whether the FirefoxDriver is configured to automatically + * accept untrusted SSL certificates. + */ + acceptUntrustedCerts() { + return !!this.preferences_['webdriver_accept_untrusted_certs']; + } + + /** + * Sets whether the FirefoxDriver should automatically accept untrusted SSL + * certificates. + * @param {boolean} value . + */ + setAcceptUntrustedCerts(value) { + this.preferences_['webdriver_accept_untrusted_certs'] = !!value; + } + + /** + * Sets whether to assume untrusted certificates come from untrusted issuers. + * @param {boolean} value . + */ + setAssumeUntrustedCertIssuer(value) { + this.preferences_['webdriver_assume_untrusted_issuer'] = !!value; + } + + /** + * @return {boolean} Whether to assume untrusted certs come from untrusted + * issuers. + */ + assumeUntrustedCertIssuer() { + return !!this.preferences_['webdriver_assume_untrusted_issuer']; + } + + /** + * Sets whether to use native events with this profile. + * @param {boolean} enabled . + */ + setNativeEventsEnabled(enabled) { + this.nativeEventsEnabled_ = enabled; + } + + /** + * Returns whether native events are enabled in this profile. + * @return {boolean} . + */ + nativeEventsEnabled() { + return this.nativeEventsEnabled_; + } + + /** + * Writes this profile to disk. + * @param {boolean=} opt_excludeWebDriverExt Whether to exclude the WebDriver + * extension from the generated profile. Used to reduce the size of an + * {@link #encode() encoded profile} since the server will always install + * the extension itself. + * @return {!Promise} A promise for the path to the new profile + * directory. + */ + writeToDisk(opt_excludeWebDriverExt) { + var profileDir = io.tmpDir(); + if (this.template_) { + profileDir = profileDir.then(function(dir) { + return io.copyDir( + /** @type {string} */(this.template_), + dir, /(parent\.lock|lock|\.parentlock)/); + }.bind(this)); + } + + // Freeze preferences for async operations. + var prefs = {}; + Object.assign(prefs, this.preferences_); + + // Freeze extensions for async operations. + var extensions = this.extensions_.concat(); + + return profileDir.then(function(dir) { + return writeUserPrefs(prefs, dir); + }).then(function(dir) { + return installExtensions(extensions, dir, !!opt_excludeWebDriverExt); + }); + } + + /** + * Encodes this profile as a zipped, base64 encoded directory. + * @return {!Promise} A promise for the encoded profile. + */ + encode() { + return this.writeToDisk(true).then(function(dir) { + var zip = new AdmZip(); + zip.addLocalFolder(dir, ''); + zip.getEntries()[0].header.method = AdmConstants.STORED; + return io.tmpFile().then(function(file) { + zip.writeZip(file); // Sync! Why oh why :-( + return promise.checkedNodeCall(fs.readFile, file); + }); + }).then(function(data) { + return new Buffer(data).toString('base64'); + }); + } + + /** + * Encodes this profile as a zipped, base64 encoded directory. + * @return {!Promise} A promise for the encoded profile. + */ + [Symbols.serialize]() { + return this.encode(); + } +} + + +// PUBLIC API + + +exports.Profile = Profile; +exports.decode = decode; +exports.loadUserPrefs = loadUserPrefs; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/http/index.js b/platforms/android/assets/www/node_modules/selenium-webdriver/http/index.js new file mode 100644 index 0000000..2ffbfb9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/http/index.js @@ -0,0 +1,514 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines an {@linkplain cmd.Executor command executor} that + * communicates with a remote end using HTTP + JSON. + */ + +'use strict'; + +const http = require('http'); +const url = require('url'); + +const error = require('../error'); +const cmd = require('../lib/command'); +const logging = require('../lib/logging'); +const promise = require('../lib/promise'); + + + +/** + * Converts a headers map to a HTTP header block string. + * @param {!Map} headers The map to convert. + * @return {string} The headers as a string. + */ +function headersToString(headers) { + let ret = []; + headers.forEach(function(value, name) { + ret.push(`${name.toLowerCase()}: ${value}`); + }); + return ret.join('\n'); +} + + +/** + * Represents a HTTP request message. This class is a "partial" request and only + * defines the path on the server to send a request to. It is each client's + * responsibility to build the full URL for the final request. + * @final + */ +class HttpRequest { + /** + * @param {string} method The HTTP method to use for the request. + * @param {string} path The path on the server to send the request to. + * @param {Object=} opt_data This request's non-serialized JSON payload data. + */ + constructor(method, path, opt_data) { + this.method = /** string */method; + this.path = /** string */path; + this.data = /** Object */opt_data; + this.headers = /** !Map */new Map( + [['Accept', 'application/json; charset=utf-8']]); + } + + /** @override */ + toString() { + let ret = `${this.method} ${this.path} HTTP/1.1\n`; + ret += headersToString(this.headers) + '\n\n'; + if (this.data) { + ret += JSON.stringify(this.data); + } + return ret; + } +} + + +/** + * Represents a HTTP response message. + * @final + */ +class HttpResponse { + /** + * @param {number} status The response code. + * @param {!Object} headers The response headers. All header names + * will be converted to lowercase strings for consistent lookups. + * @param {string} body The response body. + */ + constructor(status, headers, body) { + this.status = /** number */status; + this.body = /** string */body; + this.headers = /** !Map*/new Map; + for (let header in headers) { + this.headers.set(header.toLowerCase(), headers[header]); + } + } + + /** @override */ + toString() { + let ret = `HTTP/1.1 ${this.status}\n${headersToString(this.headers)}\n\n`; + if (this.body) { + ret += this.body; + } + return ret; + } +} + + +function post(path) { return resource('POST', path); } +function del(path) { return resource('DELETE', path); } +function get(path) { return resource('GET', path); } +function resource(method, path) { return {method: method, path: path}; } + + +/** @const {!Map} */ +const COMMAND_MAP = new Map([ + [cmd.Name.GET_SERVER_STATUS, get('/status')], + [cmd.Name.NEW_SESSION, post('/session')], + [cmd.Name.GET_SESSIONS, get('/sessions')], + [cmd.Name.DESCRIBE_SESSION, get('/session/:sessionId')], + [cmd.Name.QUIT, del('/session/:sessionId')], + [cmd.Name.CLOSE, del('/session/:sessionId/window')], + [cmd.Name.GET_CURRENT_WINDOW_HANDLE, get('/session/:sessionId/window_handle')], + [cmd.Name.GET_WINDOW_HANDLES, get('/session/:sessionId/window_handles')], + [cmd.Name.GET_CURRENT_URL, get('/session/:sessionId/url')], + [cmd.Name.GET, post('/session/:sessionId/url')], + [cmd.Name.GO_BACK, post('/session/:sessionId/back')], + [cmd.Name.GO_FORWARD, post('/session/:sessionId/forward')], + [cmd.Name.REFRESH, post('/session/:sessionId/refresh')], + [cmd.Name.ADD_COOKIE, post('/session/:sessionId/cookie')], + [cmd.Name.GET_ALL_COOKIES, get('/session/:sessionId/cookie')], + [cmd.Name.DELETE_ALL_COOKIES, del('/session/:sessionId/cookie')], + [cmd.Name.DELETE_COOKIE, del('/session/:sessionId/cookie/:name')], + [cmd.Name.FIND_ELEMENT, post('/session/:sessionId/element')], + [cmd.Name.FIND_ELEMENTS, post('/session/:sessionId/elements')], + [cmd.Name.GET_ACTIVE_ELEMENT, post('/session/:sessionId/element/active')], + [cmd.Name.FIND_CHILD_ELEMENT, post('/session/:sessionId/element/:id/element')], + [cmd.Name.FIND_CHILD_ELEMENTS, post('/session/:sessionId/element/:id/elements')], + [cmd.Name.CLEAR_ELEMENT, post('/session/:sessionId/element/:id/clear')], + [cmd.Name.CLICK_ELEMENT, post('/session/:sessionId/element/:id/click')], + [cmd.Name.SEND_KEYS_TO_ELEMENT, post('/session/:sessionId/element/:id/value')], + [cmd.Name.SUBMIT_ELEMENT, post('/session/:sessionId/element/:id/submit')], + [cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')], + [cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')], + [cmd.Name.IS_ELEMENT_SELECTED, get('/session/:sessionId/element/:id/selected')], + [cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')], + [cmd.Name.IS_ELEMENT_DISPLAYED, get('/session/:sessionId/element/:id/displayed')], + [cmd.Name.GET_ELEMENT_LOCATION, get('/session/:sessionId/element/:id/location')], + [cmd.Name.GET_ELEMENT_SIZE, get('/session/:sessionId/element/:id/size')], + [cmd.Name.GET_ELEMENT_ATTRIBUTE, get('/session/:sessionId/element/:id/attribute/:name')], + [cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY, get('/session/:sessionId/element/:id/css/:propertyName')], + [cmd.Name.ELEMENT_EQUALS, get('/session/:sessionId/element/:id/equals/:other')], + [cmd.Name.TAKE_ELEMENT_SCREENSHOT, get('/session/:sessionId/element/:id/screenshot')], + [cmd.Name.SWITCH_TO_WINDOW, post('/session/:sessionId/window')], + [cmd.Name.MAXIMIZE_WINDOW, post('/session/:sessionId/window/:windowHandle/maximize')], + [cmd.Name.GET_WINDOW_POSITION, get('/session/:sessionId/window/:windowHandle/position')], + [cmd.Name.SET_WINDOW_POSITION, post('/session/:sessionId/window/:windowHandle/position')], + [cmd.Name.GET_WINDOW_SIZE, get('/session/:sessionId/window/:windowHandle/size')], + [cmd.Name.SET_WINDOW_SIZE, post('/session/:sessionId/window/:windowHandle/size')], + [cmd.Name.SWITCH_TO_FRAME, post('/session/:sessionId/frame')], + [cmd.Name.GET_PAGE_SOURCE, get('/session/:sessionId/source')], + [cmd.Name.GET_TITLE, get('/session/:sessionId/title')], + [cmd.Name.EXECUTE_SCRIPT, post('/session/:sessionId/execute')], + [cmd.Name.EXECUTE_ASYNC_SCRIPT, post('/session/:sessionId/execute_async')], + [cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')], + [cmd.Name.SET_TIMEOUT, post('/session/:sessionId/timeouts')], + [cmd.Name.SET_SCRIPT_TIMEOUT, post('/session/:sessionId/timeouts/async_script')], + [cmd.Name.IMPLICITLY_WAIT, post('/session/:sessionId/timeouts/implicit_wait')], + [cmd.Name.MOVE_TO, post('/session/:sessionId/moveto')], + [cmd.Name.CLICK, post('/session/:sessionId/click')], + [cmd.Name.DOUBLE_CLICK, post('/session/:sessionId/doubleclick')], + [cmd.Name.MOUSE_DOWN, post('/session/:sessionId/buttondown')], + [cmd.Name.MOUSE_UP, post('/session/:sessionId/buttonup')], + [cmd.Name.MOVE_TO, post('/session/:sessionId/moveto')], + [cmd.Name.SEND_KEYS_TO_ACTIVE_ELEMENT, post('/session/:sessionId/keys')], + [cmd.Name.TOUCH_SINGLE_TAP, post('/session/:sessionId/touch/click')], + [cmd.Name.TOUCH_DOUBLE_TAP, post('/session/:sessionId/touch/doubleclick')], + [cmd.Name.TOUCH_DOWN, post('/session/:sessionId/touch/down')], + [cmd.Name.TOUCH_UP, post('/session/:sessionId/touch/up')], + [cmd.Name.TOUCH_MOVE, post('/session/:sessionId/touch/move')], + [cmd.Name.TOUCH_SCROLL, post('/session/:sessionId/touch/scroll')], + [cmd.Name.TOUCH_LONG_PRESS, post('/session/:sessionId/touch/longclick')], + [cmd.Name.TOUCH_FLICK, post('/session/:sessionId/touch/flick')], + [cmd.Name.ACCEPT_ALERT, post('/session/:sessionId/accept_alert')], + [cmd.Name.DISMISS_ALERT, post('/session/:sessionId/dismiss_alert')], + [cmd.Name.GET_ALERT_TEXT, get('/session/:sessionId/alert_text')], + [cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert_text')], + [cmd.Name.GET_LOG, post('/session/:sessionId/log')], + [cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/log/types')], + [cmd.Name.GET_SESSION_LOGS, post('/logs')], + [cmd.Name.UPLOAD_FILE, post('/session/:sessionId/file')], +]); + + +/** + * A basic HTTP client used to send messages to a remote end. + */ +class HttpClient { + /** + * @param {string} serverUrl URL for the WebDriver server to send commands to. + * @param {http.Agent=} opt_agent The agent to use for each request. + * Defaults to `http.globalAgent`. + * @param {?string=} opt_proxy The proxy to use for the connection to the + * server. Default is to use no proxy. + */ + constructor(serverUrl, opt_agent, opt_proxy) { + let parsedUrl = url.parse(serverUrl); + if (!parsedUrl.hostname) { + throw new Error('Invalid server URL: ' + serverUrl); + } + + /** @private {http.Agent} */ + this.agent_ = opt_agent || null; + + /** @private {?string} */ + this.proxy_ = opt_proxy || null; + + /** + * Base options for each request. + * @private {{auth: (?string|undefined), + * host: string, + * path: (?string|undefined), + * port: (?string|undefined)}} + */ + this.options_ = { + auth: parsedUrl.auth, + host: parsedUrl.hostname, + path: parsedUrl.pathname, + port: parsedUrl.port + }; + } + + /** + * Sends a request to the server. The client will automatically follow any + * redirects returned by the server, fulfilling the returned promise with the + * final response. + * + * @param {!HttpRequest} httpRequest The request to send. + * @return {!promise.Promise} A promise that will be fulfilled + * with the server's response. + */ + send(httpRequest) { + var data; + + let headers = {}; + httpRequest.headers.forEach(function(value, name) { + headers[name] = value; + }); + + headers['Content-Length'] = 0; + if (httpRequest.method == 'POST' || httpRequest.method == 'PUT') { + data = JSON.stringify(httpRequest.data); + headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); + headers['Content-Type'] = 'application/json;charset=UTF-8'; + } + + var path = this.options_.path; + if (path[path.length - 1] === '/' && httpRequest.path[0] === '/') { + path += httpRequest.path.substring(1); + } else { + path += httpRequest.path; + } + + var options = { + method: httpRequest.method, + auth: this.options_.auth, + host: this.options_.host, + port: this.options_.port, + path: path, + headers: headers + }; + + if (this.agent_) { + options.agent = this.agent_; + } + + var proxy = this.proxy_; + return new promise.Promise(function(fulfill, reject) { + sendRequest(options, fulfill, reject, data, proxy); + }); + } +} + + +/** + * Sends a single HTTP request. + * @param {!Object} options The request options. + * @param {function(!HttpResponse)} onOk The function to call if the + * request succeeds. + * @param {function(!Error)} onError The function to call if the request fails. + * @param {?string=} opt_data The data to send with the request. + * @param {?string=} opt_proxy The proxy server to use for the request. + */ +function sendRequest(options, onOk, onError, opt_data, opt_proxy) { + var host = options.host; + var port = options.port; + + if (opt_proxy) { + var proxy = url.parse(opt_proxy); + + options.headers['Host'] = options.host; + options.host = proxy.hostname; + options.port = proxy.port; + + if (proxy.auth) { + options.headers['Proxy-Authorization'] = + 'Basic ' + new Buffer(proxy.auth).toString('base64'); + } + } + + var request = http.request(options, function(response) { + if (response.statusCode == 302 || response.statusCode == 303) { + try { + var location = url.parse(response.headers['location']); + } catch (ex) { + onError(Error( + 'Failed to parse "Location" header for server redirect: ' + + ex.message + '\nResponse was: \n' + + new HttpResponse(response.statusCode, response.headers, ''))); + return; + } + + if (!location.hostname) { + location.hostname = host; + location.port = port; + } + + request.abort(); + sendRequest({ + method: 'GET', + host: location.hostname, + path: location.pathname + (location.search || ''), + port: location.port, + headers: { + 'Accept': 'application/json; charset=utf-8' + } + }, onOk, onError, undefined, opt_proxy); + return; + } + + var body = []; + response.on('data', body.push.bind(body)); + response.on('end', function() { + var resp = new HttpResponse( + /** @type {number} */(response.statusCode), + /** @type {!Object} */(response.headers), + body.join('').replace(/\0/g, '')); + onOk(resp); + }); + }); + + request.on('error', function(e) { + if (e.code === 'ECONNRESET') { + setTimeout(function() { + sendRequest(options, onOk, onError, opt_data, opt_proxy); + }, 15); + } else { + var message = e.message; + if (e.code) { + message = e.code + ' ' + message; + } + onError(new Error(message)); + } + }); + + if (opt_data) { + request.write(opt_data); + } + + request.end(); +} + + +/** + * A command executor that communicates with the server using HTTP + JSON. + * @implements {cmd.Executor} + */ +class Executor { + /** + * @param {!HttpClient} client The client to use for sending requests to the + * server. + */ + constructor(client) { + /** @private {!HttpClient} */ + this.client_ = client; + + /** @private {Map} */ + this.customCommands_ = null; + + /** @private {!logging.Logger} */ + this.log_ = logging.getLogger('webdriver.http.Executor'); + } + + /** + * Defines a new command for use with this executor. When a command is sent, + * the {@code path} will be preprocessed using the command's parameters; any + * path segments prefixed with ":" will be replaced by the parameter of the + * same name. For example, given "/person/:name" and the parameters + * "{name: 'Bob'}", the final command path will be "/person/Bob". + * + * @param {string} name The command name. + * @param {string} method The HTTP method to use when sending this command. + * @param {string} path The path to send the command to, relative to + * the WebDriver server's command root and of the form + * "/path/:variable/segment". + */ + defineCommand(name, method, path) { + if (!this.customCommands_) { + this.customCommands_ = new Map; + } + this.customCommands_.set(name, {method, path}); + } + + /** @override */ + execute(command) { + let resource = + (this.customCommands_ && this.customCommands_.get(command.getName())) + || COMMAND_MAP.get(command.getName()); + if (!resource) { + throw new error.UnknownCommandError( + 'Unrecognized command: ' + command.getName()); + } + + let parameters = command.getParameters(); + let path = buildPath(resource.path, parameters); + let request = new HttpRequest(resource.method, path, parameters); + + let log = this.log_; + log.finer(() => '>>>\n' + request); + return this.client_.send(request).then(function(response) { + log.finer(() => '<<<\n' + response); + return parseHttpResponse(/** @type {!HttpResponse} */ (response)); + }); + } +} + + +/** + * Callback used to parse {@link HttpResponse} objects from a + * {@link HttpClient}. + * @param {!HttpResponse} httpResponse The HTTP response to parse. + * @return {!Object} The parsed response. + */ +function parseHttpResponse(httpResponse) { + try { + return /** @type {!Object} */ (JSON.parse(httpResponse.body)); + } catch (ignored) { + // Whoops, looks like the server sent us a malformed response. We'll need + // to manually build a response object based on the response code. + } + + let response = { + 'status': error.ErrorCode.SUCCESS, + 'value': httpResponse.body.replace(/\r\n/g, '\n') + }; + + if (httpResponse.status >= 400) { + // 404 represents an unknown command; anything else is a generic unknown + // error. + response['status'] = httpResponse.status == 404 ? + error.ErrorCode.UNKNOWN_COMMAND : + error.ErrorCode.UNKNOWN_ERROR; + } + + return response; +} + + +/** + * Builds a fully qualified path using the given set of command parameters. Each + * path segment prefixed with ':' will be replaced by the value of the + * corresponding parameter. All parameters spliced into the path will be + * removed from the parameter map. + * @param {string} path The original resource path. + * @param {!Object<*>} parameters The parameters object to splice into the path. + * @return {string} The modified path. + */ +function buildPath(path, parameters) { + let pathParameters = path.match(/\/:(\w+)\b/g); + if (pathParameters) { + for (let i = 0; i < pathParameters.length; ++i) { + let key = pathParameters[i].substring(2); // Trim the /: + if (key in parameters) { + let value = parameters[key]; + // TODO: move webdriver.WebElement.ELEMENT definition to a + // common file so we can reference it here without pulling in all of + // webdriver.WebElement's dependencies. + if (value && value['ELEMENT']) { + // When inserting a WebElement into the URL, only use its ID value, + // not the full JSON. + value = value['ELEMENT']; + } + path = path.replace(pathParameters[i], '/' + value); + delete parameters[key]; + } else { + throw new error.InvalidArgumentError( + 'Missing required parameter: ' + key); + } + } + } + return path; +} + + +// PUBLIC API + +exports.Executor = Executor; +exports.HttpClient = HttpClient; +exports.Request = HttpRequest; +exports.Response = HttpResponse; +exports.buildPath = buildPath; // Exported for testing. diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/http/util.js b/platforms/android/assets/www/node_modules/selenium-webdriver/http/util.js new file mode 100644 index 0000000..88a06d6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/http/util.js @@ -0,0 +1,135 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Various HTTP utilities. + */ + +'use strict'; + +const error = require('../error'), + Executor = require('./index').Executor, + HttpClient = require('./index').HttpClient, + HttpRequest = require('./index').Request, + Command = require('../lib/command').Command, + CommandName = require('../lib/command').Name, + promise = require('../lib/promise'); + + + +/** + * Queries a WebDriver server for its current status. + * @param {string} url Base URL of the server to query. + * @return {!promise.Promise.} A promise that resolves with + * a hash of the server status. + */ +function getStatus(url) { + var client = new HttpClient(url); + var executor = new Executor(client); + var command = new Command(CommandName.GET_SERVER_STATUS); + return executor.execute(command).then(function(responseObj) { + error.checkLegacyResponse(responseObj); + return responseObj['value']; + }); +} + + +// PUBLIC API + + +/** + * Queries a WebDriver server for its current status. + * @param {string} url Base URL of the server to query. + * @return {!promise.Promise.} A promise that resolves with + * a hash of the server status. + */ +exports.getStatus = getStatus; + + +/** + * Waits for a WebDriver server to be healthy and accepting requests. + * @param {string} url Base URL of the server to query. + * @param {number} timeout How long to wait for the server. + * @return {!promise.Promise} A promise that will resolve when the + * server is ready. + */ +exports.waitForServer = function(url, timeout) { + var ready = promise.defer(), + start = Date.now(); + checkServerStatus(); + return ready.promise; + + function checkServerStatus() { + return getStatus(url).then(ready.fulfill, onError); + } + + function onError() { + if (Date.now() - start > timeout) { + ready.reject( + Error('Timed out waiting for the WebDriver server at ' + url)); + } else { + setTimeout(function() { + if (ready.isPending()) { + checkServerStatus(); + } + }, 50); + } + } +}; + + +/** + * Polls a URL with GET requests until it returns a 2xx response or the + * timeout expires. + * @param {string} url The URL to poll. + * @param {number} timeout How long to wait, in milliseconds. + * @return {!promise.Promise} A promise that will resolve when the + * URL responds with 2xx. + */ +exports.waitForUrl = function(url, timeout) { + var client = new HttpClient(url), + request = new HttpRequest('GET', ''), + ready = promise.defer(), + start = Date.now(); + testUrl(); + return ready.promise; + + function testUrl() { + client.send(request).then(onResponse, onError); + } + + function onError() { + if (Date.now() - start > timeout) { + ready.reject(Error( + 'Timed out waiting for the URL to return 2xx: ' + url)); + } else { + setTimeout(function() { + if (ready.isPending()) { + testUrl(); + } + }, 50); + } + } + + function onResponse(response) { + if (!ready.isPending()) return; + if (response.status > 199 && response.status < 300) { + return ready.fulfill(); + } + onError(); + } +}; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/ie.js b/platforms/android/assets/www/node_modules/selenium-webdriver/ie.js new file mode 100644 index 0000000..a892094 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/ie.js @@ -0,0 +1,444 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a {@linkplain Driver WebDriver} client for Microsoft's + * Internet Explorer. Before using the IEDriver, you must download the latest + * [IEDriverServer](http://selenium-release.storage.googleapis.com/index.html) + * and place it on your + * [PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). You must also apply + * the system configuration outlined on the Selenium project + * [wiki](https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver) + */ + +'use strict'; + +const fs = require('fs'), + util = require('util'); + +const executors = require('./executors'), + io = require('./io'), + capabilities = require('./lib/capabilities'), + promise = require('./lib/promise'), + webdriver = require('./lib/webdriver'), + portprober = require('./net/portprober'), + remote = require('./remote'); + + +const IEDRIVER_EXE = 'IEDriverServer.exe'; + + + +/** + * IEDriverServer logging levels. + * @enum {string} + */ +const Level = { + FATAL: 'FATAL', + ERROR: 'ERROR', + WARN: 'WARN', + INFO: 'INFO', + DEBUG: 'DEBUG', + TRACE: 'TRACE' +}; + + + +/** + * Option keys: + * https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities#ie-specific + * @enum {string} + */ +const Key = { + IGNORE_PROTECTED_MODE_SETTINGS: 'ignoreProtectedModeSettings', + IGNORE_ZOOM_SETTING: 'ignoreZoomSetting', + INITIAL_BROWSER_URL: 'initialBrowserUrl', + ENABLE_PERSISTENT_HOVER: 'enablePersistentHover', + ENABLE_ELEMENT_CACHE_CLEANUP: 'enableElementCacheCleanup', + REQUIRE_WINDOW_FOCUS: 'requireWindowFocus', + BROWSER_ATTACH_TIMEOUT: 'browserAttachTimeout', + FORCE_CREATE_PROCESS: 'ie.forceCreateProcessApi', + BROWSER_COMMAND_LINE_SWITCHES: 'ie.browserCommandLineSwitches', + USE_PER_PROCESS_PROXY: 'ie.usePerProcessProxy', + ENSURE_CLEAN_SESSION: 'ie.ensureCleanSession', + LOG_FILE: 'logFile', + LOG_LEVEL: 'logLevel', + HOST: 'host', + EXTRACT_PATH: 'extractPath', + SILENT: 'silent' +}; + + +/** + * Class for managing IEDriver specific options. + */ +class Options { + constructor() { + /** @private {!Object<(boolean|number|string|!Array)>} */ + this.options_ = {}; + + /** @private {(capabilities.ProxyConfig|null)} */ + this.proxy_ = null; + } + + /** + * Extracts the IEDriver specific options from the given capabilities + * object. + * @param {!capabilities.Capabilities} caps The capabilities object. + * @return {!Options} The IEDriver options. + */ + static fromCapabilities(caps) { + var options = new Options(); + var map = options.options_; + + Object.keys(Key).forEach(function(key) { + key = Key[key]; + if (caps.has(key)) { + map[key] = caps.get(key); + } + }); + + if (caps.has(capabilities.Capability.PROXY)) { + options.setProxy(caps.get(capabilities.Capability.PROXY)); + } + + return options; + } + + /** + * Whether to disable the protected mode settings check when the session is + * created. Disbling this setting may lead to significant instability as the + * browser may become unresponsive/hang. Only "best effort" support is provided + * when using this capability. + * + * For more information, refer to the IEDriver's + * [required system configuration](http://goo.gl/eH0Yi3). + * + * @param {boolean} ignoreSettings Whether to ignore protected mode settings. + * @return {!Options} A self reference. + */ + introduceFlakinessByIgnoringProtectedModeSettings(ignoreSettings) { + this.options_[Key.IGNORE_PROTECTED_MODE_SETTINGS] = !!ignoreSettings; + return this; + } + + /** + * Indicates whether to skip the check that the browser's zoom level is set to + * 100%. + * + * @param {boolean} ignore Whether to ignore the browser's zoom level settings. + * @return {!Options} A self reference. + */ + ignoreZoomSetting(ignore) { + this.options_[Key.IGNORE_ZOOM_SETTING] = !!ignore; + return this; + } + + /** + * Sets the initial URL loaded when IE starts. This is intended to be used with + * {@link #ignoreProtectedModeSettings} to allow the user to initialize IE in + * the proper Protected Mode zone. Setting this option may cause browser + * instability or flaky and unresponsive code. Only "best effort" support is + * provided when using this option. + * + * @param {string} url The initial browser URL. + * @return {!Options} A self reference. + */ + initialBrowserUrl(url) { + this.options_[Key.INITIAL_BROWSER_URL] = url; + return this; + } + + /** + * Configures whether to enable persistent mouse hovering (true by default). + * Persistent hovering is achieved by continuously firing mouse over events at + * the last location the mouse cursor has been moved to. + * + * @param {boolean} enable Whether to enable persistent hovering. + * @return {!Options} A self reference. + */ + enablePersistentHover(enable) { + this.options_[Key.ENABLE_PERSISTENT_HOVER] = !!enable; + return this; + } + + /** + * Configures whether the driver should attempt to remove obsolete + * {@linkplain webdriver.WebElement WebElements} from its internal cache on + * page navigation (true by default). Disabling this option will cause the + * driver to run with a larger memory footprint. + * + * @param {boolean} enable Whether to enable element reference cleanup. + * @return {!Options} A self reference. + */ + enableElementCacheCleanup(enable) { + this.options_[Key.ENABLE_ELEMENT_CACHE_CLEANUP] = !!enable; + return this; + } + + /** + * Configures whether to require the IE window to have input focus before + * performing any user interactions (i.e. mouse or keyboard events). This + * option is disabled by default, but delivers much more accurate interaction + * events when enabled. + * + * @param {boolean} require Whether to require window focus. + * @return {!Options} A self reference. + */ + requireWindowFocus(require) { + this.options_[Key.REQUIRE_WINDOW_FOCUS] = !!require; + return this; + } + + /** + * Configures the timeout, in milliseconds, that the driver will attempt to + * located and attach to a newly opened instance of Internet Explorer. The + * default is zero, which indicates waiting indefinitely. + * + * @param {number} timeout How long to wait for IE. + * @return {!Options} A self reference. + */ + browserAttachTimeout(timeout) { + this.options_[Key.BROWSER_ATTACH_TIMEOUT] = Math.max(timeout, 0); + return this; + } + + /** + * Configures whether to launch Internet Explorer using the CreateProcess API. + * If this option is not specified, IE is launched using IELaunchURL, if + * available. For IE 8 and above, this option requires the TabProcGrowth + * registry value to be set to 0. + * + * @param {boolean} force Whether to use the CreateProcess API. + * @return {!Options} A self reference. + */ + forceCreateProcessApi(force) { + this.options_[Key.FORCE_CREATE_PROCESS] = !!force; + return this; + } + + /** + * Specifies command-line switches to use when launching Internet Explorer. + * This is only valid when used with {@link #forceCreateProcessApi}. + * + * @param {...(string|!Array.)} var_args The arguments to add. + * @return {!Options} A self reference. + */ + addArguments(var_args) { + var args = this.options_[Key.BROWSER_COMMAND_LINE_SWITCHES] || []; + args = args.concat.apply(args, arguments); + this.options_[Key.BROWSER_COMMAND_LINE_SWITCHES] = args; + return this; + } + + /** + * Configures whether proxies should be configured on a per-process basis. If + * not set, setting a {@linkplain #setProxy proxy} will configure the system + * proxy. The default behavior is to use the system proxy. + * + * @param {boolean} enable Whether to enable per-process proxy settings. + * @return {!Options} A self reference. + */ + usePerProcessProxy(enable) { + this.options_[Key.USE_PER_PROCESS_PROXY] = !!enable; + return this; + } + + /** + * Configures whether to clear the cache, cookies, history, and saved form data + * before starting the browser. _Using this capability will clear session data + * for all running instances of Internet Explorer, including those started + * manually._ + * + * @param {boolean} cleanSession Whether to clear all session data on startup. + * @return {!Options} A self reference. + */ + ensureCleanSession(cleanSession) { + this.options_[Key.ENSURE_CLEAN_SESSION] = !!cleanSession; + return this; + } + + /** + * Sets the path to the log file the driver should log to. + * @param {string} file The log file path. + * @return {!Options} A self reference. + */ + setLogFile(file) { + this.options_[Key.LOG_FILE] = file; + return this; + } + + /** + * Sets the IEDriverServer's logging {@linkplain Level level}. + * @param {Level} level The logging level. + * @return {!Options} A self reference. + */ + setLogLevel(level) { + this.options_[Key.LOG_LEVEL] = level; + return this; + } + + /** + * Sets the IP address of the driver's host adapter. + * @param {string} host The IP address to use. + * @return {!Options} A self reference. + */ + setHost(host) { + this.options_[Key.HOST] = host; + return this; + } + + /** + * Sets the path of the temporary data directory to use. + * @param {string} path The log file path. + * @return {!Options} A self reference. + */ + setExtractPath(path) { + this.options_[Key.EXTRACT_PATH] = path; + return this; + } + + /** + * Sets whether the driver should start in silent mode. + * @param {boolean} silent Whether to run in silent mode. + * @return {!Options} A self reference. + */ + silent(silent) { + this.options_[Key.SILENT] = silent; + return this; + } + + /** + * Sets the proxy settings for the new session. + * @param {capabilities.ProxyConfig} proxy The proxy configuration to use. + * @return {!Options} A self reference. + */ + setProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * Converts this options instance to a {@link capabilities.Capabilities} + * object. + * @param {capabilities.Capabilities=} opt_capabilities The capabilities to + * merge these options into, if any. + * @return {!capabilities.Capabilities} The capabilities. + */ + toCapabilities(opt_capabilities) { + var caps = opt_capabilities || capabilities.Capabilities.ie(); + if (this.proxy_) { + caps.set(capabilities.Capability.PROXY, this.proxy_); + } + Object.keys(this.options_).forEach(function(key) { + caps.set(key, this.options_[key]); + }, this); + return caps; + } +} + + +function createServiceFromCapabilities(capabilities) { + if (process.platform !== 'win32') { + throw Error( + 'The IEDriver may only be used on Windows, but you appear to be on ' + + process.platform + '. Did you mean to run against a remote ' + + 'WebDriver server?'); + } + + let exe = io.findInPath(IEDRIVER_EXE, true); + if (!exe || !fs.existsSync(exe)) { + throw Error( + `${IEDRIVER_EXE} could not be found on the current PATH. Please ` + + `download the latest version of ${IEDRIVER_EXE} from ` + + 'http://selenium-release.storage.googleapis.com/index.html and ' + + 'ensure it can be found on your system PATH.'); + } + + var args = []; + if (capabilities.has(Key.HOST)) { + args.push('--host=' + capabilities.get(Key.HOST)); + } + if (capabilities.has(Key.LOG_FILE)) { + args.push('--log-file=' + capabilities.get(Key.LOG_FILE)); + } + if (capabilities.has(Key.LOG_LEVEL)) { + args.push('--log-level=' + capabilities.get(Key.LOG_LEVEL)); + } + if (capabilities.has(Key.EXTRACT_PATH)) { + args.push('--extract-path=' + capabilities.get(Key.EXTRACT_PATH)); + } + if (capabilities.get(Key.SILENT)) { + args.push('--silent'); + } + + var port = portprober.findFreePort(); + return new remote.DriverService(exe, { + loopback: true, + port: port, + args: port.then(function(port) { + return args.concat('--port=' + port); + }), + stdio: 'ignore' + }); +} + + +/** + * A WebDriver client for Microsoft's Internet Explorer. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(capabilities.Capabilities|Options)=} opt_config The configuration + * options. + * @param {promise.ControlFlow=} opt_flow The control flow to use, + * or {@code null} to use the currently active flow. + */ + constructor(opt_config, opt_flow) { + var caps = opt_config instanceof Options ? + opt_config.toCapabilities() : + (opt_config || capabilities.Capabilities.ie()); + + var service = createServiceFromCapabilities(caps); + var executor = executors.createExecutor(service.start()); + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + + super(driver.getSession(), executor, driver.controlFlow()); + + let boundQuit = this.quit.bind(this); + + /** @override */ + this.quit = function() { + return boundQuit().thenFinally(service.kill.bind(service)); + }; + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() {} +} + + +// PUBLIC API + + +exports.Driver = Driver; +exports.Options = Options; +exports.Level = Level; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/index.js b/platforms/android/assets/www/node_modules/selenium-webdriver/index.js new file mode 100644 index 0000000..38dfa6f --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/index.js @@ -0,0 +1,57 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview The main user facing module. Exports WebDriver's primary + * public API and provides convenience assessors to certain sub-modules. + */ + +'use strict'; + +const builder = require('./builder'); +const error = require('./error'); +const actions = require('./lib/actions'); +const by = require('./lib/by'); +const capabilities = require('./lib/capabilities'); +const command = require('./lib/command'); +const events = require('./lib/events'); +const input = require('./lib/input'); +const logging = require('./lib/logging'); +const promise = require('./lib/promise'); +const session = require('./lib/session'); +const until = require('./lib/until'); +const webdriver = require('./lib/webdriver'); + + +exports.ActionSequence = actions.ActionSequence; +exports.Browser = capabilities.Browser; +exports.Builder = builder.Builder; +exports.Button = input.Button; +exports.By = by.By; +exports.Capabilities = capabilities.Capabilities; +exports.Capability = capabilities.Capability; +exports.EventEmitter = events.EventEmitter; +exports.FileDetector = input.FileDetector; +exports.Key = input.Key; +exports.Session = session.Session; +exports.WebDriver = webdriver.WebDriver; +exports.WebElement = webdriver.WebElement; +exports.WebElementPromise = webdriver.WebElementPromise; +exports.error = error; +exports.logging = logging; +exports.promise = promise; +exports.until = until; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/io/exec.js b/platforms/android/assets/www/node_modules/selenium-webdriver/io/exec.js new file mode 100644 index 0000000..90d4232 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/io/exec.js @@ -0,0 +1,159 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const childProcess = require('child_process'); +const promise = require('../lib/promise'); + + +/** + * A hash with configuration options for an executed command. + * + * - `args` - Command line arguments. + * - `env` - Command environment; will inherit from the current process if + * missing. + * - `stdio` - IO configuration for the spawned server process. For more + * information, refer to the documentation of `child_process.spawn`. + * + * @typedef {{ + * args: (!Array|undefined), + * env: (!Object|undefined), + * stdio: (string|!Array| + * undefined) + * }} + */ +var Options; + + +/** + * Describes a command's termination conditions. + */ +class Result { + /** + * @param {?number} code The exit code, or {@code null} if the command did not + * exit normally. + * @param {?string} signal The signal used to kill the command, or + * {@code null}. + */ + constructor(code, signal) { + /** @type {?number} */ + this.code = code; + + /** @type {?string} */ + this.signal = signal; + } + + /** @override */ + toString() { + return `Result(code=${this.code}, signal=${this.signal})`; + } +} + + +const COMMAND_RESULT = + /** !WeakMap> */new WeakMap; +const KILL_HOOK = /** !WeakMap */new WeakMap; + +/** + * Represents a command running in a sub-process. + */ +class Command { + /** + * @param {!promise.Promise} result The command result. + * @param {function(string)} onKill The function to call when {@link #kill()} + * is called. + */ + constructor(result, onKill) { + COMMAND_RESULT.set(this, result); + KILL_HOOK.set(this, onKill); + } + + /** @return {boolean} Whether this command is still running. */ + isRunning() { + return COMMAND_RESULT.get(this).isPending(); + } + + /** + * @return {!promise.Promise} A promise for the result of this + * command. + */ + result() { + return /** @type {!promise.Promise} */(COMMAND_RESULT.get(this)); + } + + /** + * Sends a signal to the underlying process. + * @param {string=} opt_signal The signal to send; defaults to `SIGTERM`. + */ + kill(opt_signal) { + KILL_HOOK.get(this)(opt_signal || 'SIGTERM'); + } +} + + +// PUBLIC API + + +/** + * Spawns a child process. The returned {@link Command} may be used to wait + * for the process result or to send signals to the process. + * + * @param {string} command The executable to spawn. + * @param {Options=} opt_options The command options. + * @return {!Command} The launched command. + */ +module.exports = function exec(command, opt_options) { + var options = opt_options || {}; + + var proc = childProcess.spawn(command, options.args || [], { + env: options.env || process.env, + stdio: options.stdio || 'ignore' + }).once('exit', onExit); + + // This process should not wait on the spawned child, however, we do + // want to ensure the child is killed when this process exits. + proc.unref(); + process.once('exit', killCommand); + + var result = promise.defer(); + var cmd = new Command(result.promise, function(signal) { + if (!result.isPending() || !proc) { + return; // No longer running. + } + proc.kill(signal); + }); + return cmd; + + function onExit(code, signal) { + proc = null; + process.removeListener('exit', killCommand); + result.fulfill(new Result(code, signal)); + } + + function killCommand() { + process.removeListener('exit', killCommand); + proc && proc.kill('SIGTERM'); + } +}; + +// Exported to improve generated API documentation. + +module.exports.Command = Command; +/** @typedef {!Options} */ +module.exports.Options = Options; +module.exports.Result = Result; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/io/index.js b/platforms/android/assets/www/node_modules/selenium-webdriver/io/index.js new file mode 100644 index 0000000..2da0670 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/io/index.js @@ -0,0 +1,227 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fs = require('fs'), + path = require('path'), + rimraf = require('rimraf'), + tmp = require('tmp'); + + + +// PUBLIC API + + + +/** + * Recursively removes a directory and all of its contents. This is equivalent + * to {@code rm -rf} on a POSIX system. + * @param {string} dirPath Path to the directory to remove. + * @return {!Promise} A promise to be resolved when the operation has + * completed. + */ +exports.rmDir = function(dirPath) { + return new Promise(function(fulfill, reject) { + var numAttempts = 0; + attemptRm(); + function attemptRm() { + numAttempts += 1; + rimraf(dirPath, function(err) { + if (err) { + if (err.code === 'ENOTEMPTY' && numAttempts < 2) { + attemptRm(); + return; + } + reject(err); + } else { + fulfill(); + } + }); + } + }); +}; + + +/** + * Copies one file to another. + * @param {string} src The source file. + * @param {string} dst The destination file. + * @return {!Promise} A promise for the copied file's path. + */ +exports.copy = function(src, dst) { + return new Promise(function(fulfill, reject) { + var rs = fs.createReadStream(src); + rs.on('error', reject); + rs.on('end', () => fulfill(dst)); + + var ws = fs.createWriteStream(dst); + ws.on('error', reject); + + rs.pipe(ws); + }); +}; + + +/** + * Recursively copies the contents of one directory to another. + * @param {string} src The source directory to copy. + * @param {string} dst The directory to copy into. + * @param {(RegExp|function(string): boolean)=} opt_exclude An exclusion filter + * as either a regex or predicate function. All files matching this filter + * will not be copied. + * @return {!Promise} A promise for the destination + * directory's path once all files have been copied. + */ +exports.copyDir = function(src, dst, opt_exclude) { + var predicate = opt_exclude; + if (opt_exclude && typeof opt_exclude !== 'function') { + predicate = function(p) { + return !opt_exclude.test(p); + }; + } + + // TODO(jleyba): Make this function completely async. + if (!fs.existsSync(dst)) { + fs.mkdirSync(dst); + } + + var files = fs.readdirSync(src); + files = files.map(function(file) { + return path.join(src, file); + }); + + if (predicate) { + files = files.filter(/** @type {function(string): boolean} */(predicate)); + } + + var results = []; + files.forEach(function(file) { + var stats = fs.statSync(file); + var target = path.join(dst, path.basename(file)); + + if (stats.isDirectory()) { + if (!fs.existsSync(target)) { + fs.mkdirSync(target, stats.mode); + } + results.push(exports.copyDir(file, target, predicate)); + } else { + results.push(exports.copy(file, target)); + } + }); + + return Promise.all(results).then(() => dst); +}; + + +/** + * Tests if a file path exists. + * @param {string} aPath The path to test. + * @return {!Promise} A promise for whether the file exists. + */ +exports.exists = function(aPath) { + return new Promise(function(fulfill) { + fs.exists(aPath, fulfill); + }); +}; + + +/** + * Deletes a name from the filesystem and possibly the file it refers to. Has + * no effect if the file does not exist. + * @param {string} aPath The path to remove. + * @return {!Promise} A promise for when the file has been removed. + */ +exports.unlink = function(aPath) { + return new Promise(function(fulfill, reject) { + fs.exists(aPath, function(exists) { + if (exists) { + fs.unlink(aPath, function(err) { + err && reject(err) || fulfill(); + }); + } else { + fulfill(); + } + }); + }); +}; + + +/** + * @return {!Promise} A promise for the path to a temporary directory. + * @see https://www.npmjs.org/package/tmp + */ +exports.tmpDir = function() { + return new Promise(function(fulfill, reject) { + tmp.dir(function(error, value) { + error ? reject(error) : fulfill(value); + }); + }); +}; + + +/** + * @param {{postfix: string}=} opt_options Temporary file options. + * @return {!Promise} A promise for the path to a temporary file. + * @see https://www.npmjs.org/package/tmp + */ +exports.tmpFile = function(opt_options) { + return new Promise(function(fulfill, reject) { + let callback = function( + /** Error */err, + /** (string|undefined) */value) { + err ? reject(err) : fulfill(value); + }; + + // |tmp.file| checks arguments length to detect options rather than doing a + // truthy check, so we must only pass options if there are some to pass. + if (opt_options) { + tmp.file(opt_options, callback); + } else { + tmp.file(callback); + } + }); +}; + + +/** + * Searches the {@code PATH} environment variable for the given file. + * @param {string} file The file to locate on the PATH. + * @param {boolean=} opt_checkCwd Whether to always start with the search with + * the current working directory, regardless of whether it is explicitly + * listed on the PATH. + * @return {?string} Path to the located file, or {@code null} if it could + * not be found. + */ +exports.findInPath = function(file, opt_checkCwd) { + if (opt_checkCwd) { + var tmp = path.join(process.cwd(), file); + if (fs.existsSync(tmp)) { + return tmp; + } + } + + var dirs = process.env['PATH'].split(path.delimiter); + var found = null; + dirs.forEach(function(dir) { + var tmp = path.join(dir, file); + if (!found && fs.existsSync(tmp)) { + found = tmp; + } + }); + return found; +}; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/README b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/README new file mode 100644 index 0000000..bdf25b0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/README @@ -0,0 +1,2 @@ +This directory contains modules internal to selenium-webdriver that are not +intended for general consumption. They may change at any time. diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/actions.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/actions.js new file mode 100644 index 0000000..bb94c5e --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/actions.js @@ -0,0 +1,594 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const command = require('./command'); +const input = require('./input'); +const error = require('../error'); + + +/** + * @param {!IArrayLike} args . + * @return {!Array} . + */ +function flatten(args) { + let result = []; + for (let i = 0; i < args.length; i++) { + let element = args[i]; + if (Array.isArray(element)) { + result.push.apply(result, flatten(element)); + } else { + result.push(element); + } + } + return result; +} + + +const MODIFIER_KEYS = new Set([ + input.Key.ALT, + input.Key.CONTROL, + input.Key.SHIFT, + input.Key.COMMAND +]); + + +/** + * Checks that a key is a modifier key. + * @param {!input.Key} key The key to check. + * @throws {error.InvalidArgumentError} If the key is not a modifier key. + * @private + */ +function checkModifierKey(key) { + if (!MODIFIER_KEYS.has(key)) { + throw new error.InvalidArgumentError('Not a modifier key'); + } +} + + +/** + * Class for defining sequences of complex user interactions. Each sequence + * will not be executed until {@link #perform} is called. + * + * Example: + * + * new ActionSequence(driver). + * keyDown(Key.SHIFT). + * click(element1). + * click(element2). + * dragAndDrop(element3, element4). + * keyUp(Key.SHIFT). + * perform(); + * + */ +class ActionSequence { + /** + * @param {!./webdriver.WebDriver} driver The driver that should be used to + * perform this action sequence. + */ + constructor(driver) { + /** @private {!./webdriver.WebDriver} */ + this.driver_ = driver; + + /** @private {!Array<{description: string, command: !command.Command}>} */ + this.actions_ = []; + } + + /** + * Schedules an action to be executed each time {@link #perform} is called on + * this instance. + * + * @param {string} description A description of the command. + * @param {!command.Command} command The command. + * @private + */ + schedule_(description, command) { + this.actions_.push({ + description: description, + command: command + }); + } + + /** + * Executes this action sequence. + * + * @return {!./promise.Promise} A promise that will be resolved once + * this sequence has completed. + */ + perform() { + // Make a protected copy of the scheduled actions. This will protect against + // users defining additional commands before this sequence is actually + // executed. + let actions = this.actions_.concat(); + let driver = this.driver_; + return driver.controlFlow().execute(function() { + actions.forEach(function(action) { + driver.schedule(action.command, action.description); + }); + }, 'ActionSequence.perform'); + } + + /** + * Moves the mouse. The location to move to may be specified in terms of the + * mouse's current location, an offset relative to the top-left corner of an + * element, or an element (in which case the middle of the element is used). + * + * @param {(!./webdriver.WebElement|{x: number, y: number})} location The + * location to drag to, as either another WebElement or an offset in + * pixels. + * @param {{x: number, y: number}=} opt_offset If the target {@code location} + * is defined as a {@link ./webdriver.WebElement}, this parameter defines + * an offset within that element. The offset should be specified in pixels + * relative to the top-left corner of the element's bounding box. If + * omitted, the element's center will be used as the target offset. + * @return {!ActionSequence} A self reference. + */ + mouseMove(location, opt_offset) { + let cmd = new command.Command(command.Name.MOVE_TO); + + if (typeof location.x === 'number') { + setOffset(/** @type {{x: number, y: number}} */(location)); + } else { + cmd.setParameter('element', location.getRawId()); + if (opt_offset) { + setOffset(opt_offset); + } + } + + this.schedule_('mouseMove', cmd); + return this; + + /** @param {{x: number, y: number}} offset The offset to use. */ + function setOffset(offset) { + cmd.setParameter('xoffset', offset.x || 0); + cmd.setParameter('yoffset', offset.y || 0); + } + } + + /** + * Schedules a mouse action. + * @param {string} description A simple descriptive label for the scheduled + * action. + * @param {!command.Name} commandName The name of the command. + * @param {(./webdriver.WebElement|input.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link input.Button.LEFT} if neither an element nor + * button is specified. + * @param {input.Button=} opt_button The button to use. Defaults to + * {@link input.Button.LEFT}. Ignored if the previous argument is + * provided as a button. + * @return {!ActionSequence} A self reference. + * @private + */ + scheduleMouseAction_( + description, commandName, opt_elementOrButton, opt_button) { + let button; + if (typeof opt_elementOrButton === 'number') { + button = opt_elementOrButton; + } else { + if (opt_elementOrButton) { + this.mouseMove( + /** @type {!./webdriver.WebElement} */ (opt_elementOrButton)); + } + button = opt_button !== void(0) ? opt_button : input.Button.LEFT; + } + + let cmd = new command.Command(commandName). + setParameter('button', button); + this.schedule_(description, cmd); + return this; + } + + /** + * Presses a mouse button. The mouse button will not be released until + * {@link #mouseUp} is called, regardless of whether that call is made in this + * sequence or another. The behavior for out-of-order events (e.g. mouseDown, + * click) is undefined. + * + * If an element is provided, the mouse will first be moved to the center + * of that element. This is equivalent to: + * + * sequence.mouseMove(element).mouseDown() + * + * Warning: this method currently only supports the left mouse button. See + * [issue 4047](http://code.google.com/p/selenium/issues/detail?id=4047). + * + * @param {(./webdriver.WebElement|input.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link input.Button.LEFT} if neither an element nor + * button is specified. + * @param {input.Button=} opt_button The button to use. Defaults to + * {@link input.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!ActionSequence} A self reference. + */ + mouseDown(opt_elementOrButton, opt_button) { + return this.scheduleMouseAction_('mouseDown', + command.Name.MOUSE_DOWN, opt_elementOrButton, opt_button); + } + + /** + * Releases a mouse button. Behavior is undefined for calling this function + * without a previous call to {@link #mouseDown}. + * + * If an element is provided, the mouse will first be moved to the center + * of that element. This is equivalent to: + * + * sequence.mouseMove(element).mouseUp() + * + * Warning: this method currently only supports the left mouse button. See + * [issue 4047](http://code.google.com/p/selenium/issues/detail?id=4047). + * + * @param {(./webdriver.WebElement|input.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link input.Button.LEFT} if neither an element nor + * button is specified. + * @param {input.Button=} opt_button The button to use. Defaults to + * {@link input.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!ActionSequence} A self reference. + */ + mouseUp(opt_elementOrButton, opt_button) { + return this.scheduleMouseAction_('mouseUp', + command.Name.MOUSE_UP, opt_elementOrButton, opt_button); + } + + /** + * Convenience function for performing a "drag and drop" manuever. The target + * element may be moved to the location of another element, or by an offset (in + * pixels). + * + * @param {!./webdriver.WebElement} element The element to drag. + * @param {(!./webdriver.WebElement|{x: number, y: number})} location The + * location to drag to, either as another WebElement or an offset in + * pixels. + * @return {!ActionSequence} A self reference. + */ + dragAndDrop(element, location) { + return this.mouseDown(element).mouseMove(location).mouseUp(); + } + + /** + * Clicks a mouse button. + * + * If an element is provided, the mouse will first be moved to the center + * of that element. This is equivalent to: + * + * sequence.mouseMove(element).click() + * + * @param {(./webdriver.WebElement|input.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link input.Button.LEFT} if neither an element nor + * button is specified. + * @param {input.Button=} opt_button The button to use. Defaults to + * {@link input.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!ActionSequence} A self reference. + */ + click(opt_elementOrButton, opt_button) { + return this.scheduleMouseAction_('click', + command.Name.CLICK, opt_elementOrButton, opt_button); + } + + /** + * Double-clicks a mouse button. + * + * If an element is provided, the mouse will first be moved to the center of + * that element. This is equivalent to: + * + * sequence.mouseMove(element).doubleClick() + * + * Warning: this method currently only supports the left mouse button. See + * [issue 4047](http://code.google.com/p/selenium/issues/detail?id=4047). + * + * @param {(./webdriver.WebElement|input.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link input.Button.LEFT} if neither an element nor + * button is specified. + * @param {input.Button=} opt_button The button to use. Defaults to + * {@link input.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!ActionSequence} A self reference. + */ + doubleClick(opt_elementOrButton, opt_button) { + return this.scheduleMouseAction_('doubleClick', + command.Name.DOUBLE_CLICK, opt_elementOrButton, opt_button); + } + + /** + * Schedules a keyboard action. + * + * @param {string} description A simple descriptive label for the scheduled + * action. + * @param {!Array<(string|!input.Key)>} keys The keys to send. + * @return {!ActionSequence} A self reference. + * @private + */ + scheduleKeyboardAction_(description, keys) { + let cmd = new command.Command(command.Name.SEND_KEYS_TO_ACTIVE_ELEMENT) + .setParameter('value', keys); + this.schedule_(description, cmd); + return this; + } + + /** + * Performs a modifier key press. The modifier key is not released + * until {@link #keyUp} or {@link #sendKeys} is called. The key press will be + * targetted at the currently focused element. + * + * @param {!input.Key} key The modifier key to push. Must be one of + * {ALT, CONTROL, SHIFT, COMMAND, META}. + * @return {!ActionSequence} A self reference. + * @throws {error.InvalidArgumentError} If the key is not a valid modifier + * key. + */ + keyDown(key) { + checkModifierKey(key); + return this.scheduleKeyboardAction_('keyDown', [key]); + } + + /** + * Performs a modifier key release. The release is targetted at the currently + * focused element. + * @param {!input.Key} key The modifier key to release. Must be one of + * {ALT, CONTROL, SHIFT, COMMAND, META}. + * @return {!ActionSequence} A self reference. + * @throws {error.InvalidArgumentError} If the key is not a valid modifier + * key. + */ + keyUp(key) { + checkModifierKey(key); + return this.scheduleKeyboardAction_('keyUp', [key]); + } + + /** + * Simulates typing multiple keys. Each modifier key encountered in the + * sequence will not be released until it is encountered again. All key events + * will be targetted at the currently focused element. + * + * @param {...(string|!input.Key|!Array<(string|!input.Key)>)} var_args + * The keys to type. + * @return {!ActionSequence} A self reference. + * @throws {Error} If the key is not a valid modifier key. + */ + sendKeys(var_args) { + let keys = flatten(arguments); + return this.scheduleKeyboardAction_('sendKeys', keys); + } +} + + +/** + * Class for defining sequences of user touch interactions. Each sequence + * will not be executed until {@link #perform} is called. + * + * Example: + * + * new TouchSequence(driver). + * tapAndHold({x: 0, y: 0}). + * move({x: 3, y: 4}). + * release({x: 10, y: 10}). + * perform(); + * + */ +class TouchSequence { + /** + * @param {!./webdriver.WebDriver} driver The driver that should be used to + * perform this action sequence. + */ + constructor(driver) { + /** @private {!./webdriver.WebDriver} */ + this.driver_ = driver; + + /** @private {!Array<{description: string, command: !command.Command}>} */ + this.actions_ = []; + } + + /** + * Schedules an action to be executed each time {@link #perform} is called on + * this instance. + * @param {string} description A description of the command. + * @param {!command.Command} command The command. + * @private + */ + schedule_(description, command) { + this.actions_.push({ + description: description, + command: command + }); + } + + /** + * Executes this action sequence. + * @return {!./promise.Promise} A promise that will be resolved once + * this sequence has completed. + */ + perform() { + // Make a protected copy of the scheduled actions. This will protect against + // users defining additional commands before this sequence is actually + // executed. + let actions = this.actions_.concat(); + let driver = this.driver_; + return driver.controlFlow().execute(function() { + actions.forEach(function(action) { + driver.schedule(action.command, action.description); + }); + }, 'TouchSequence.perform'); + } + + /** + * Taps an element. + * + * @param {!./webdriver.WebElement} elem The element to tap. + * @return {!TouchSequence} A self reference. + */ + tap(elem) { + let cmd = new command.Command(command.Name.TOUCH_SINGLE_TAP). + setParameter('element', elem.getId()); + + this.schedule_('tap', cmd); + return this; + } + + /** + * Double taps an element. + * + * @param {!./webdriver.WebElement} elem The element to double tap. + * @return {!TouchSequence} A self reference. + */ + doubleTap(elem) { + let cmd = new command.Command(command.Name.TOUCH_DOUBLE_TAP). + setParameter('element', elem.getId()); + + this.schedule_('doubleTap', cmd); + return this; + } + + /** + * Long press on an element. + * + * @param {!./webdriver.WebElement} elem The element to long press. + * @return {!TouchSequence} A self reference. + */ + longPress(elem) { + let cmd = new command.Command(command.Name.TOUCH_LONG_PRESS). + setParameter('element', elem.getId()); + + this.schedule_('longPress', cmd); + return this; + } + + /** + * Touch down at the given location. + * + * @param {{x: number, y: number}} location The location to touch down at. + * @return {!TouchSequence} A self reference. + */ + tapAndHold(location) { + let cmd = new command.Command(command.Name.TOUCH_DOWN). + setParameter('x', location.x). + setParameter('y', location.y); + + this.schedule_('tapAndHold', cmd); + return this; + } + + /** + * Move a held {@linkplain #tapAndHold touch} to the specified location. + * + * @param {{x: number, y: number}} location The location to move to. + * @return {!TouchSequence} A self reference. + */ + move(location) { + let cmd = new command.Command(command.Name.TOUCH_MOVE). + setParameter('x', location.x). + setParameter('y', location.y); + + this.schedule_('move', cmd); + return this; + } + + /** + * Release a held {@linkplain #tapAndHold touch} at the specified location. + * + * @param {{x: number, y: number}} location The location to release at. + * @return {!TouchSequence} A self reference. + */ + release(location) { + let cmd = new command.Command(command.Name.TOUCH_UP). + setParameter('x', location.x). + setParameter('y', location.y); + + this.schedule_('release', cmd); + return this; + } + + /** + * Scrolls the touch screen by the given offset. + * + * @param {{x: number, y: number}} offset The offset to scroll to. + * @return {!TouchSequence} A self reference. + */ + scroll(offset) { + let cmd = new command.Command(command.Name.TOUCH_SCROLL). + setParameter('xoffset', offset.x). + setParameter('yoffset', offset.y); + + this.schedule_('scroll', cmd); + return this; + } + + /** + * Scrolls the touch screen, starting on `elem` and moving by the specified + * offset. + * + * @param {!./webdriver.WebElement} elem The element where scroll starts. + * @param {{x: number, y: number}} offset The offset to scroll to. + * @return {!TouchSequence} A self reference. + */ + scrollFromElement(elem, offset) { + let cmd = new command.Command(command.Name.TOUCH_SCROLL). + setParameter('element', elem.getId()). + setParameter('xoffset', offset.x). + setParameter('yoffset', offset.y); + + this.schedule_('scrollFromElement', cmd); + return this; + } + + /** + * Flick, starting anywhere on the screen, at speed xspeed and yspeed. + * + * @param {{xspeed: number, yspeed: number}} speed The speed to flick in each + direction, in pixels per second. + * @return {!TouchSequence} A self reference. + */ + flick(speed) { + let cmd = new command.Command(command.Name.TOUCH_FLICK). + setParameter('xspeed', speed.xspeed). + setParameter('yspeed', speed.yspeed); + + this.schedule_('flick', cmd); + return this; + } + + /** + * Flick starting at elem and moving by x and y at specified speed. + * + * @param {!./webdriver.WebElement} elem The element where flick starts. + * @param {{x: number, y: number}} offset The offset to flick to. + * @param {number} speed The speed to flick at in pixels per second. + * @return {!TouchSequence} A self reference. + */ + flickElement(elem, offset, speed) { + let cmd = new command.Command(command.Name.TOUCH_FLICK). + setParameter('element', elem.getId()). + setParameter('xoffset', offset.x). + setParameter('yoffset', offset.y). + setParameter('speed', speed); + + this.schedule_('flickElement', cmd); + return this; + } +} + + +// PUBLIC API + +exports.ActionSequence = ActionSequence; +exports.TouchSequence = TouchSequence; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/by.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/by.js new file mode 100644 index 0000000..4d77b99 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/by.js @@ -0,0 +1,276 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * @fileoverview Factory methods for the supported locator strategies. + */ + +/** + * Short-hand expressions for the primary element locator strategies. + * For example the following two statements are equivalent: + * + * var e1 = driver.findElement(By.id('foo')); + * var e2 = driver.findElement({id: 'foo'}); + * + * Care should be taken when using JavaScript minifiers (such as the + * Closure compiler), as locator hashes will always be parsed using + * the un-obfuscated properties listed. + * + * @typedef {( + * {className: string}| + * {css: string}| + * {id: string}| + * {js: string}| + * {linkText: string}| + * {name: string}| + * {partialLinkText: string}| + * {tagName: string}| + * {xpath: string})} + */ +var ByHash; + + +/** + * Error thrown if an invalid character is encountered while escaping a CSS + * identifier. + * @see https://drafts.csswg.org/cssom/#serialize-an-identifier + */ +class InvalidCharacterError extends Error { + constructor() { + super(); + this.name = this.constructor.name; + } +} + + +/** + * Escapes a CSS string. + * @param {string} css the string to escape. + * @return {string} the escaped string. + * @throws {TypeError} if the input value is not a string. + * @throws {InvalidCharacterError} if the string contains an invalid character. + * @see https://drafts.csswg.org/cssom/#serialize-an-identifier + */ +function escapeCss(css) { + if (typeof css !== 'string') { + throw new TypeError('input must be a string'); + } + let ret = ''; + const n = css.length; + for (let i = 0; i < n; i++) { + const c = css.charCodeAt(i); + if (c == 0x0) { + throw new InvalidCharacterError(); + } + + if ((c >= 0x0001 && c <= 0x001F) + || c == 0x007F + || (i == 0 && c >= 0x0030 && c <= 0x0039) + || (i == 1 && c >= 0x0030 && c <= 0x0039 + && css.charCodeAt(0) == 0x002D)) { + ret += '\\' + c.toString(16); + continue; + } + + if (i == 0 && c == 0x002D && n == 1) { + ret += '\\' + css.charAt(i); + continue; + } + + if (c >= 0x0080 + || c == 0x002D // - + || c == 0x005F // _ + || (c >= 0x0030 && c <= 0x0039) // [0-9] + || (c >= 0x0041 && c <= 0x005A) // [A-Z] + || (c >= 0x0061 && c <= 0x007A)) { // [a-z] + ret += css.charAt(i); + continue; + } + + ret += '\\' + css.charAt(i); + } + return ret; +} + + +/** + * Describes a mechanism for locating an element on the page. + * @final + */ +class By { + /** + * @param {string} using the name of the location strategy to use. + * @param {string} value the value to search for. + */ + constructor(using, value) { + /** @type {string} */ + this.using = using; + + /** @type {string} */ + this.value = value; + } + + /** + * Locates elements that have a specific class name. + * + * @param {string} name The class name to search for. + * @return {!By} The new locator. + * @see http://www.w3.org/TR/2011/WD-html5-20110525/elements.html#classes + * @see http://www.w3.org/TR/CSS2/selector.html#class-html + */ + static className(name) { + let names = name.split(/\s+/g) + .filter(s => s.length > 0) + .map(s => escapeCss(s)); + return By.css('.' + names.join('.')); + } + + /** + * Locates elements using a CSS selector. + * + * @param {string} selector The CSS selector to use. + * @return {!By} The new locator. + * @see http://www.w3.org/TR/CSS2/selector.html + */ + static css(selector) { + return new By('css selector', selector); + } + + /** + * Locates eleemnts by the ID attribute. This locator uses the CSS selector + * `*[id="$ID"]`, _not_ `document.getElementById`. + * + * @param {string} id The ID to search for. + * @return {!By} The new locator. + */ + static id(id) { + return By.css('*[id="' + escapeCss(id) + '"]'); + } + + /** + * Locates link elements whose + * {@linkplain webdriver.WebElement#getText visible text} matches the given + * string. + * + * @param {string} text The link text to search for. + * @return {!By} The new locator. + */ + static linkText(text) { + return new By('link text', text); + } + + /** + * Locates an elements by evaluating a + * {@linkplain webdriver.WebDriver#executeScript JavaScript expression}. + * The result of this expression must be an element or list of elements. + * + * @param {!(string|Function)} script The script to execute. + * @param {...*} var_args The arguments to pass to the script. + * @return {function(!./webdriver.WebDriver): !./promise.Promise} + * A new JavaScript-based locator function. + */ + static js(script, var_args) { + let args = Array.prototype.slice.call(arguments, 0); + return function(driver) { + return driver.executeScript.apply(driver, args); + }; + } + + /** + * Locates elements whose `name` attribute has the given value. + * + * @param {string} name The name attribute to search for. + * @return {!By} The new locator. + */ + static name(name) { + return By.css('*[name="' + escapeCss(name) + '"]'); + } + + /** + * Locates link elements whose + * {@linkplain webdriver.WebElement#getText visible text} contains the given + * substring. + * + * @param {string} text The substring to check for in a link's visible text. + * @return {!By} The new locator. + */ + static partialLinkText(text) { + return new By('partial link text', text); + } + + /** + * Locates elements with a given tag name. + * + * @param {string} name The tag name to search for. + * @return {!By} The new locator. + * @deprecated Use {@link By.css() By.css(tagName)} instead. + */ + static tagName(name) { + return By.css(name); + } + + /** + * Locates elements matching a XPath selector. Care should be taken when + * using an XPath selector with a {@link webdriver.WebElement} as WebDriver + * will respect the context in the specified in the selector. For example, + * given the selector `//div`, WebDriver will search from the document root + * regardless of whether the locator was used with a WebElement. + * + * @param {string} xpath The XPath selector to use. + * @return {!By} The new locator. + * @see http://www.w3.org/TR/xpath/ + */ + static xpath(xpath) { + return new By('xpath', xpath); + } + + /** @override */ + toString() { + // The static By.name() overrides this.constructor.name. Shame... + return `By(${this.using}, ${this.value})`; + } +} + + +/** + * Checks if a value is a valid locator. + * @param {!(By|Function|ByHash)} locator The value to check. + * @return {!(By|Function)} The valid locator. + * @throws {TypeError} If the given value does not define a valid locator + * strategy. + */ +function check(locator) { + if (locator instanceof By || typeof locator === 'function') { + return locator; + } + for (let key in locator) { + if (locator.hasOwnProperty(key) && By.hasOwnProperty(key)) { + return By[key](locator[key]); + } + } + throw new TypeError('Invalid locator'); +} + + + +// PUBLIC API + + +exports.By = By; +exports.checkedLocator = check; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/capabilities.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/capabilities.js new file mode 100644 index 0000000..d5333fe --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/capabilities.js @@ -0,0 +1,404 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * @fileoverview Defines types related to describing the capabilities of a + * WebDriver session. + */ + +const Symbols = require('./symbols'); + + +/** + * Recognized browser names. + * @enum {string} + */ +const Browser = { + ANDROID: 'android', + CHROME: 'chrome', + EDGE: 'MicrosoftEdge', + FIREFOX: 'firefox', + IE: 'internet explorer', + INTERNET_EXPLORER: 'internet explorer', + IPAD: 'iPad', + IPHONE: 'iPhone', + OPERA: 'opera', + PHANTOM_JS: 'phantomjs', + SAFARI: 'safari', + HTMLUNIT: 'htmlunit' +}; + + +/** + * Common Capability keys. + * @enum {string} + */ +const Capability = { + + /** + * Indicates whether a driver should accept all SSL certs by default. This + * capability only applies when requesting a new session. To query whether + * a driver can handle insecure SSL certs, see {@link #SECURE_SSL}. + */ + ACCEPT_SSL_CERTS: 'acceptSslCerts', + + + /** + * The browser name. Common browser names are defined in the {@link Browser} + * enum. + */ + BROWSER_NAME: 'browserName', + + /** + * Defines how elements should be scrolled into the viewport for interaction. + * This capability will be set to zero (0) if elements are aligned with the + * top of the viewport, or one (1) if aligned with the bottom. The default + * behavior is to align with the top of the viewport. + */ + ELEMENT_SCROLL_BEHAVIOR: 'elementScrollBehavior', + + /** + * Whether the driver is capable of handling modal alerts (e.g. alert, + * confirm, prompt). To define how a driver should handle alerts, + * use {@link #UNEXPECTED_ALERT_BEHAVIOR}. + */ + HANDLES_ALERTS: 'handlesAlerts', + + /** + * Key for the logging driver logging preferences. + */ + LOGGING_PREFS: 'loggingPrefs', + + /** + * Whether this session generates native events when simulating user input. + */ + NATIVE_EVENTS: 'nativeEvents', + + /** + * Describes the platform the browser is running on. Will be one of + * ANDROID, IOS, LINUX, MAC, UNIX, or WINDOWS. When requesting a + * session, ANY may be used to indicate no platform preference (this is + * semantically equivalent to omitting the platform capability). + */ + PLATFORM: 'platform', + + /** + * Describes the proxy configuration to use for a new WebDriver session. + */ + PROXY: 'proxy', + + /** Whether the driver supports changing the brower's orientation. */ + ROTATABLE: 'rotatable', + + /** + * Whether a driver is only capable of handling secure SSL certs. To request + * that a driver accept insecure SSL certs by default, use + * {@link #ACCEPT_SSL_CERTS}. + */ + SECURE_SSL: 'secureSsl', + + /** Whether the driver supports manipulating the app cache. */ + SUPPORTS_APPLICATION_CACHE: 'applicationCacheEnabled', + + /** Whether the driver supports locating elements with CSS selectors. */ + SUPPORTS_CSS_SELECTORS: 'cssSelectorsEnabled', + + /** Whether the browser supports JavaScript. */ + SUPPORTS_JAVASCRIPT: 'javascriptEnabled', + + /** Whether the driver supports controlling the browser's location info. */ + SUPPORTS_LOCATION_CONTEXT: 'locationContextEnabled', + + /** Whether the driver supports taking screenshots. */ + TAKES_SCREENSHOT: 'takesScreenshot', + + /** + * Defines how the driver should handle unexpected alerts. The value should + * be one of "accept", "dismiss", or "ignore. + */ + UNEXPECTED_ALERT_BEHAVIOR: 'unexpectedAlertBehavior', + + /** Defines the browser version. */ + VERSION: 'version' +}; + + +/** + * Describes how a proxy should be configured for a WebDriver session. + * Proxy configuration object, as defined by the WebDriver wire protocol. + * @typedef {( + * {proxyType: string}| + * {proxyType: string, + * proxyAutoconfigUrl: string}| + * {proxyType: string, + * ftpProxy: string, + * httpProxy: string, + * sslProxy: string, + * noProxy: string})} + */ +var ProxyConfig; + + +/** + * Converts a generic hash object to a map. + * @param {!Object} hash The hash object. + * @return {!Map} The converted map. + */ +function toMap(hash) { + let m = new Map; + for (let key in hash) { + if (hash.hasOwnProperty(key)) { + m.set(key, hash[key]); + } + } + return m; +} + + +/** + * Describes a set of capabilities for a WebDriver session. + */ +class Capabilities extends Map { + /** + * @param {(Capabilities|Map|Object)=} opt_other Another set of + * capabilities to initialize this instance from. + */ + constructor(opt_other) { + if (opt_other && !(opt_other instanceof Map)) { + opt_other = toMap(opt_other); + } + super(opt_other); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Android. + */ + static android() { + return new Capabilities() + .set(Capability.BROWSER_NAME, Browser.ANDROID) + .set(Capability.PLATFORM, 'ANDROID'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Chrome. + */ + static chrome() { + return new Capabilities().set(Capability.BROWSER_NAME, Browser.CHROME); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Microsoft Edge. + */ + static edge() { + return new Capabilities() + .set(Capability.BROWSER_NAME, Browser.EDGE) + .set(Capability.PLATFORM, 'WINDOWS'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Firefox. + */ + static firefox() { + return new Capabilities().set(Capability.BROWSER_NAME, Browser.FIREFOX); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Internet Explorer. + */ + static ie() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.INTERNET_EXPLORER). + set(Capability.PLATFORM, 'WINDOWS'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for iPad. + */ + static ipad() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.IPAD). + set(Capability.PLATFORM, 'MAC'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for iPhone. + */ + static iphone() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.IPHONE). + set(Capability.PLATFORM, 'MAC'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Opera. + */ + static opera() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.OPERA); + } + + /** + * @return {!Capabilities} A basic set of capabilities for PhantomJS. + */ + static phantomjs() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.PHANTOM_JS); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Safari. + */ + static safari() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.SAFARI). + set(Capability.PLATFORM, 'MAC'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for HTMLUnit. + */ + static htmlunit() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.HTMLUNIT); + } + + /** + * @return {!Capabilities} A basic set of capabilities for HTMLUnit + * with enabled Javascript. + */ + static htmlunitwithjs() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.HTMLUNIT). + set(Capability.SUPPORTS_JAVASCRIPT, true); + } + + /** + * @return {!Object} The JSON representation of this instance. + * Note, the returned object may contain nested promised values. + */ + [Symbols.serialize]() { + let ret = {}; + for (let key of this.keys()) { + let cap = this.get(key); + if (cap) { + ret[key] = cap; + } + } + return ret; + } + + /** + * Merges another set of capabilities into this instance. + * @param {!(Capabilities|Map|Object)} other The other + * set of capabilities to merge. + * @return {!Capabilities} A self reference. + */ + merge(other) { + if (!other) { + throw new TypeError('no capabilities provided for merge'); + } + + if (!(other instanceof Map)) { + other = toMap(other); + } + + for (let key of other.keys()) { + this.set(key, other.get(key)); + } + + return this; + } + + /** + * @param {string} key The capability key. + * @param {*} value The capability value. + * @return {!Capabilities} A self reference. + * @throws {TypeError} If the `key` is not a string. + * @override + */ + set(key, value) { + if (typeof key !== 'string') { + throw new TypeError('Capability keys must be strings: ' + typeof key); + } + super.set(key, value); + return this; + } + + /** + * Sets the logging preferences. Preferences may be specified as a + * {@link ./logging.Preferences} instance, or a as a map of log-type to + * log-level. + * @param {!(./logging.Preferences|Object)} prefs The logging + * preferences. + * @return {!Capabilities} A self reference. + */ + setLoggingPrefs(prefs) { + return this.set(Capability.LOGGING_PREFS, prefs); + } + + /** + * Sets the proxy configuration for this instance. + * @param {ProxyConfig} proxy The desired proxy configuration. + * @return {!Capabilities} A self reference. + */ + setProxy(proxy) { + return this.set(Capability.PROXY, proxy); + } + + /** + * Sets whether native events should be used. + * @param {boolean} enabled Whether to enable native events. + * @return {!Capabilities} A self reference. + */ + setEnableNativeEvents(enabled) { + return this.set(Capability.NATIVE_EVENTS, enabled); + } + + /** + * Sets how elements should be scrolled into view for interaction. + * @param {number} behavior The desired scroll behavior: either 0 to align + * with the top of the viewport or 1 to align with the bottom. + * @return {!Capabilities} A self reference. + */ + setScrollBehavior(behavior) { + return this.set(Capability.ELEMENT_SCROLL_BEHAVIOR, behavior); + } + + /** + * Sets the default action to take with an unexpected alert before returning + * an error. + * @param {string} behavior The desired behavior; should be "accept", + * "dismiss", or "ignore". Defaults to "dismiss". + * @return {!Capabilities} A self reference. + */ + setAlertBehavior(behavior) { + return this.set(Capability.UNEXPECTED_ALERT_BEHAVIOR, behavior); + } +} + + +// PUBLIC API + + +exports.Browser = Browser; +exports.Capabilities = Capabilities; +exports.Capability = Capability; + +/** @typedef {ProxyConfig} */ +exports.ProxyConfig = ProxyConfig; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/command.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/command.js new file mode 100644 index 0000000..188167f --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/command.js @@ -0,0 +1,263 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Contains several classes for handling commands. + */ + +'use strict'; + +const promise = require('./promise'); + + +/** + * Describes a command to execute. + * @final + */ +class Command { + /** @param {string} name The name of this command. */ + constructor(name) { + /** @private {string} */ + this.name_ = name; + + /** @private {!Object<*>} */ + this.parameters_ = {}; + } + + /** @return {string} This command's name. */ + getName() { + return this.name_; + } + + /** + * Sets a parameter to send with this command. + * @param {string} name The parameter name. + * @param {*} value The parameter value. + * @return {!Command} A self reference. + */ + setParameter(name, value) { + this.parameters_[name] = value; + return this; + } + + /** + * Sets the parameters for this command. + * @param {!Object<*>} parameters The command parameters. + * @return {!Command} A self reference. + */ + setParameters(parameters) { + this.parameters_ = parameters; + return this; + } + + /** + * Returns a named command parameter. + * @param {string} key The parameter key to look up. + * @return {*} The parameter value, or undefined if it has not been set. + */ + getParameter(key) { + return this.parameters_[key]; + } + + /** + * @return {!Object<*>} The parameters to send with this command. + */ + getParameters() { + return this.parameters_; + } +} + + +/** + * Enumeration of predefined names command names that all command processors + * will support. + * @enum {string} + */ +// TODO: Delete obsolete command names. +const Name = { + GET_SERVER_STATUS: 'getStatus', + + NEW_SESSION: 'newSession', + GET_SESSIONS: 'getSessions', + DESCRIBE_SESSION: 'getSessionCapabilities', + + CLOSE: 'close', + QUIT: 'quit', + + GET_CURRENT_URL: 'getCurrentUrl', + GET: 'get', + GO_BACK: 'goBack', + GO_FORWARD: 'goForward', + REFRESH: 'refresh', + + ADD_COOKIE: 'addCookie', + GET_COOKIE: 'getCookie', + GET_ALL_COOKIES: 'getCookies', + DELETE_COOKIE: 'deleteCookie', + DELETE_ALL_COOKIES: 'deleteAllCookies', + + GET_ACTIVE_ELEMENT: 'getActiveElement', + FIND_ELEMENT: 'findElement', + FIND_ELEMENTS: 'findElements', + FIND_CHILD_ELEMENT: 'findChildElement', + FIND_CHILD_ELEMENTS: 'findChildElements', + + CLEAR_ELEMENT: 'clearElement', + CLICK_ELEMENT: 'clickElement', + SEND_KEYS_TO_ELEMENT: 'sendKeysToElement', + SUBMIT_ELEMENT: 'submitElement', + + GET_CURRENT_WINDOW_HANDLE: 'getCurrentWindowHandle', + GET_WINDOW_HANDLES: 'getWindowHandles', + GET_WINDOW_POSITION: 'getWindowPosition', + SET_WINDOW_POSITION: 'setWindowPosition', + GET_WINDOW_SIZE: 'getWindowSize', + SET_WINDOW_SIZE: 'setWindowSize', + MAXIMIZE_WINDOW: 'maximizeWindow', + + SWITCH_TO_WINDOW: 'switchToWindow', + SWITCH_TO_FRAME: 'switchToFrame', + GET_PAGE_SOURCE: 'getPageSource', + GET_TITLE: 'getTitle', + + EXECUTE_SCRIPT: 'executeScript', + EXECUTE_ASYNC_SCRIPT: 'executeAsyncScript', + + GET_ELEMENT_TEXT: 'getElementText', + GET_ELEMENT_TAG_NAME: 'getElementTagName', + IS_ELEMENT_SELECTED: 'isElementSelected', + IS_ELEMENT_ENABLED: 'isElementEnabled', + IS_ELEMENT_DISPLAYED: 'isElementDisplayed', + GET_ELEMENT_LOCATION: 'getElementLocation', + GET_ELEMENT_LOCATION_IN_VIEW: 'getElementLocationOnceScrolledIntoView', + GET_ELEMENT_SIZE: 'getElementSize', + GET_ELEMENT_ATTRIBUTE: 'getElementAttribute', + GET_ELEMENT_VALUE_OF_CSS_PROPERTY: 'getElementValueOfCssProperty', + ELEMENT_EQUALS: 'elementEquals', + + SCREENSHOT: 'screenshot', + TAKE_ELEMENT_SCREENSHOT: 'takeElementScreenshot', + IMPLICITLY_WAIT: 'implicitlyWait', + SET_SCRIPT_TIMEOUT: 'setScriptTimeout', + SET_TIMEOUT: 'setTimeout', + + ACCEPT_ALERT: 'acceptAlert', + DISMISS_ALERT: 'dismissAlert', + GET_ALERT_TEXT: 'getAlertText', + SET_ALERT_TEXT: 'setAlertValue', + + EXECUTE_SQL: 'executeSQL', + GET_LOCATION: 'getLocation', + SET_LOCATION: 'setLocation', + GET_APP_CACHE: 'getAppCache', + GET_APP_CACHE_STATUS: 'getStatus', + CLEAR_APP_CACHE: 'clearAppCache', + IS_BROWSER_ONLINE: 'isBrowserOnline', + SET_BROWSER_ONLINE: 'setBrowserOnline', + + GET_LOCAL_STORAGE_ITEM: 'getLocalStorageItem', + GET_LOCAL_STORAGE_KEYS: 'getLocalStorageKeys', + SET_LOCAL_STORAGE_ITEM: 'setLocalStorageItem', + REMOVE_LOCAL_STORAGE_ITEM: 'removeLocalStorageItem', + CLEAR_LOCAL_STORAGE: 'clearLocalStorage', + GET_LOCAL_STORAGE_SIZE: 'getLocalStorageSize', + + GET_SESSION_STORAGE_ITEM: 'getSessionStorageItem', + GET_SESSION_STORAGE_KEYS: 'getSessionStorageKey', + SET_SESSION_STORAGE_ITEM: 'setSessionStorageItem', + REMOVE_SESSION_STORAGE_ITEM: 'removeSessionStorageItem', + CLEAR_SESSION_STORAGE: 'clearSessionStorage', + GET_SESSION_STORAGE_SIZE: 'getSessionStorageSize', + + SET_SCREEN_ORIENTATION: 'setScreenOrientation', + GET_SCREEN_ORIENTATION: 'getScreenOrientation', + + // These belong to the Advanced user interactions - an element is + // optional for these commands. + CLICK: 'mouseClick', + DOUBLE_CLICK: 'mouseDoubleClick', + MOUSE_DOWN: 'mouseButtonDown', + MOUSE_UP: 'mouseButtonUp', + MOVE_TO: 'mouseMoveTo', + SEND_KEYS_TO_ACTIVE_ELEMENT: 'sendKeysToActiveElement', + + // These belong to the Advanced Touch API + TOUCH_SINGLE_TAP: 'touchSingleTap', + TOUCH_DOWN: 'touchDown', + TOUCH_UP: 'touchUp', + TOUCH_MOVE: 'touchMove', + TOUCH_SCROLL: 'touchScroll', + TOUCH_DOUBLE_TAP: 'touchDoubleTap', + TOUCH_LONG_PRESS: 'touchLongPress', + TOUCH_FLICK: 'touchFlick', + + GET_AVAILABLE_LOG_TYPES: 'getAvailableLogTypes', + GET_LOG: 'getLog', + GET_SESSION_LOGS: 'getSessionLogs', + + // Non-standard commands used by the standalone Selenium server. + UPLOAD_FILE: 'uploadFile' +}; + + + +/** + * Handles the execution of WebDriver {@link Command commands}. + * @interface + */ +class Executor { + /** + * Executes the given {@code command}. If there is an error executing the + * command, the provided callback will be invoked with the offending error. + * Otherwise, the callback will be invoked with a null Error and non-null + * response object. + * + * @param {!Command} command The command to execute. + * @return {!promise.Promise} A promise that will be fulfilled with + * the command result. + */ + execute(command) {} +} + + +/** + * Wraps a promised {@link Executor}, ensuring no commands are executed until + * the wrapped executor has been fully resolved. + * @implements {Executor} + */ +class DeferredExecutor { + /** + * @param {!promise.Promise} delegate The promised delegate, which + * may be provided by any promise-like thenable object. + */ + constructor(delegate) { + /** @override */ + this.execute = function(command) { + return delegate.then(executor => executor.execute(command)); + }; + } +} + + + +// PUBLIC API + + +exports.Command = Command; +exports.Name = Name; +exports.Executor = Executor; +exports.DeferredExecutor = DeferredExecutor; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/devmode.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/devmode.js new file mode 100644 index 0000000..4862c6a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/devmode.js @@ -0,0 +1,34 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Module used to detect if scripts are loaded from the Selenium + * project repo instead of from a deployed package. + */ + +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +/** + * @const {boolean} + */ +module.exports = (function() { + let buildDescFile = path.join(__dirname, '..', '..', 'build.desc'); + return fs.existsSync(buildDescFile); +})(); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/events.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/events.js new file mode 100644 index 0000000..fc5cfa6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/events.js @@ -0,0 +1,210 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * Describes an event listener registered on an {@linkplain EventEmitter}. + */ +class Listener { + /** + * @param {!Function} fn The acutal listener function. + * @param {(Object|undefined)} scope The object in whose scope to invoke the + * listener. + * @param {boolean} oneshot Whether this listener should only be used once. + */ + constructor(fn, scope, oneshot) { + Object.defineProperties(this, { + fn: {value: fn}, + scope: {value: scope}, + oneshot: {value: oneshot} + }); + } +} + + +/** @type {!WeakMap>>} */ +const EVENTS = new WeakMap; + + +/** + * Object that can emit events for others to listen for. + */ +class EventEmitter { + /** + * Fires an event and calls all listeners. + * @param {string} type The type of event to emit. + * @param {...*} var_args Any arguments to pass to each listener. + */ + emit(type, var_args) { + let events = EVENTS.get(this); + if (!events) { + return; + } + + let args = Array.prototype.slice.call(arguments, 1); + + let listeners = events.get(type); + if (listeners) { + for (let listener of listeners) { + listener.fn.apply(listener.scope, args); + if (listener.oneshot) { + listeners.delete(listener); + } + } + } + } + + /** + * Returns a mutable list of listeners for a specific type of event. + * @param {string} type The type of event to retrieve the listeners for. + * @return {!Set} The registered listeners for the given event + * type. + */ + listeners(type) { + let events = EVENTS.get(this); + if (!events) { + events = new Map; + EVENTS.set(this, events); + } + + let listeners = events.get(type); + if (!listeners) { + listeners = new Set; + events.set(type, listeners); + } + return listeners; + } + + /** + * Registers a listener. + * @param {string} type The type of event to listen for. + * @param {!Function} fn The function to invoke when the event is fired. + * @param {Object=} opt_self The object in whose scope to invoke the listener. + * @param {boolean=} opt_oneshot Whether the listener should b (e removed after + * the first event is fired. + * @return {!EventEmitter} A self reference. + * @private + */ + addListener_(type, fn, opt_self, opt_oneshot) { + let listeners = this.listeners(type); + for (let listener of listeners) { + if (listener.fn === fn) { + return this; + } + } + listeners.add(new Listener(fn, opt_self || undefined, !!opt_oneshot)); + return this; + } + + /** + * Registers a listener. + * @param {string} type The type of event to listen for. + * @param {!Function} fn The function to invoke when the event is fired. + * @param {Object=} opt_self The object in whose scope to invoke the listener. + * @return {!EventEmitter} A self reference. + */ + addListener(type, fn, opt_self) { + return this.addListener_(type, fn, opt_self, false); + } + + /** + * Registers a one-time listener which will be called only the first time an + * event is emitted, after which it will be removed. + * @param {string} type The type of event to listen for. + * @param {!Function} fn The function to invoke when the event is fired. + * @param {Object=} opt_self The object in whose scope to invoke the listener. + * @return {!EventEmitter} A self reference. + */ + once(type, fn, opt_self) { + return this.addListener_(type, fn, opt_self, true); + } + + /** + * An alias for {@link #addListener() addListener()}. + * @param {string} type The type of event to listen for. + * @param {!Function} fn The function to invoke when the event is fired. + * @param {Object=} opt_self The object in whose scope to invoke the listener. + * @return {!EventEmitter} A self reference. + */ + on(type, fn, opt_self) { + return this.addListener(type, fn, opt_self); + } + + /** + * Removes a previously registered event listener. + * @param {string} type The type of event to unregister. + * @param {!Function} listenerFn The handler function to remove. + * @return {!EventEmitter} A self reference. + */ + removeListener(type, listenerFn) { + if (typeof type !== 'string' || typeof listenerFn !== 'function') { + throw TypeError('invalid args: expected (string, function), got (' + + (typeof type) + ', ' + (typeof listenerFn) + ')'); + } + + let events = EVENTS.get(this); + if (!events) { + return this; + } + + let listeners = events.get(type); + if (!listeners) { + return this; + } + + let match; + for (let listener of listeners) { + if (listener.fn === listenerFn) { + match = listener; + break; + } + } + if (match) { + listeners.delete(match); + if (!listeners.size) { + events.delete(type); + } + } + return this; + } + + /** + * Removes all listeners for a specific type of event. If no event is + * specified, all listeners across all types will be removed. + * @param {string=} opt_type The type of event to remove listeners from. + * @return {!EventEmitter} A self reference. + */ + removeAllListeners(opt_type) { + let events = EVENTS.get(this); + if (events) { + if (typeof opt_type === 'string') { + events.delete(opt_type); + } else { + EVENTS.delete(this); + } + } + return this; + } +} + + +// PUBLIC API + + +exports.EventEmitter = EventEmitter; +exports.Listener = Listener; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/amd64/libnoblur64.so b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/amd64/libnoblur64.so new file mode 100644 index 0000000..916e530 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/amd64/libnoblur64.so differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/i386/libnoblur.so b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/i386/libnoblur.so new file mode 100644 index 0000000..8e7db8d Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/i386/libnoblur.so differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/webdriver.json b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/webdriver.json new file mode 100644 index 0000000..4a30492 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/webdriver.json @@ -0,0 +1,78 @@ +{ + "frozen": { + "app.update.auto": false, + "app.update.enabled": false, + "browser.displayedE10SNotice": 4, + "browser.download.manager.showWhenStarting": false, + "browser.EULA.override": true, + "browser.EULA.3.accepted": true, + "browser.link.open_external": 2, + "browser.link.open_newwindow": 2, + "browser.offline": false, + "browser.reader.detectedFirstArticle": true, + "browser.safebrowsing.enabled": false, + "browser.safebrowsing.malware.enabled": false, + "browser.search.update": false, + "browser.selfsupport.url" : "", + "browser.sessionstore.resume_from_crash": false, + "browser.shell.checkDefaultBrowser": false, + "browser.tabs.warnOnClose": false, + "browser.tabs.warnOnOpen": false, + "datareporting.healthreport.service.enabled": false, + "datareporting.healthreport.uploadEnabled": false, + "datareporting.healthreport.service.firstRun": false, + "datareporting.healthreport.logging.consoleEnabled": false, + "datareporting.policy.dataSubmissionEnabled": false, + "datareporting.policy.dataSubmissionPolicyAccepted": false, + "devtools.errorconsole.enabled": true, + "dom.disable_open_during_load": false, + "extensions.autoDisableScopes": 10, + "extensions.blocklist.enabled": false, + "extensions.checkCompatibility.nightly": false, + "extensions.logging.enabled": true, + "extensions.update.enabled": false, + "extensions.update.notifyUser": false, + "javascript.enabled": true, + "network.manage-offline-status": false, + "network.http.phishy-userpass-length": 255, + "offline-apps.allow_by_default": true, + "prompts.tab_modal.enabled": false, + "security.csp.enable": false, + "security.fileuri.origin_policy": 3, + "security.fileuri.strict_origin_policy": false, + "security.warn_entering_secure": false, + "security.warn_entering_secure.show_once": false, + "security.warn_entering_weak": false, + "security.warn_entering_weak.show_once": false, + "security.warn_leaving_secure": false, + "security.warn_leaving_secure.show_once": false, + "security.warn_submit_insecure": false, + "security.warn_viewing_mixed": false, + "security.warn_viewing_mixed.show_once": false, + "signon.rememberSignons": false, + "toolkit.networkmanager.disable": true, + "toolkit.telemetry.prompted": 2, + "toolkit.telemetry.enabled": false, + "toolkit.telemetry.rejected": true, + "xpinstall.signatures.required": false, + "xpinstall.whitelist.required": false + }, + "mutable": { + "browser.dom.window.dump.enabled": true, + "browser.laterrun.enabled": false, + "browser.newtab.url": "about:blank", + "browser.newtabpage.enabled": false, + "browser.startup.page": 0, + "browser.startup.homepage": "about:blank", + "browser.usedOnWindows10.introURL": "about:blank", + "dom.max_chrome_script_run_time": 30, + "dom.max_script_run_time": 30, + "dom.report_all_js_exceptions": true, + "javascript.options.showInConsole": true, + "network.http.max-connections-per-server": 10, + "startup.homepage_welcome_url": "about:blank", + "startup.homepage_welcome_url.additional": "about:blank", + "webdriver_accept_untrusted_certs": true, + "webdriver_assume_untrusted_issuer": true + } +} diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi new file mode 100644 index 0000000..74182e9 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/input.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/input.js new file mode 100644 index 0000000..e6f598c --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/input.js @@ -0,0 +1,172 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * @fileoverview Defines types related to user input with the WebDriver API. + */ + +const promise = require('./promise'); + + +/** + * Enumeration of the buttons used in the advanced interactions API. + * @enum {number} + */ +const Button = { + LEFT: 0, + MIDDLE: 1, + RIGHT: 2 +}; + + + +/** + * Representations of pressable keys that aren't text. These are stored in + * the Unicode PUA (Private Use Area) code points, 0xE000-0xF8FF. Refer to + * http://www.google.com.au/search?&q=unicode+pua&btnG=Search + * + * @enum {string} + */ +const Key = { + NULL: '\uE000', + CANCEL: '\uE001', // ^break + HELP: '\uE002', + BACK_SPACE: '\uE003', + TAB: '\uE004', + CLEAR: '\uE005', + RETURN: '\uE006', + ENTER: '\uE007', + SHIFT: '\uE008', + CONTROL: '\uE009', + ALT: '\uE00A', + PAUSE: '\uE00B', + ESCAPE: '\uE00C', + SPACE: '\uE00D', + PAGE_UP: '\uE00E', + PAGE_DOWN: '\uE00F', + END: '\uE010', + HOME: '\uE011', + ARROW_LEFT: '\uE012', + LEFT: '\uE012', + ARROW_UP: '\uE013', + UP: '\uE013', + ARROW_RIGHT: '\uE014', + RIGHT: '\uE014', + ARROW_DOWN: '\uE015', + DOWN: '\uE015', + INSERT: '\uE016', + DELETE: '\uE017', + SEMICOLON: '\uE018', + EQUALS: '\uE019', + + NUMPAD0: '\uE01A', // number pad keys + NUMPAD1: '\uE01B', + NUMPAD2: '\uE01C', + NUMPAD3: '\uE01D', + NUMPAD4: '\uE01E', + NUMPAD5: '\uE01F', + NUMPAD6: '\uE020', + NUMPAD7: '\uE021', + NUMPAD8: '\uE022', + NUMPAD9: '\uE023', + MULTIPLY: '\uE024', + ADD: '\uE025', + SEPARATOR: '\uE026', + SUBTRACT: '\uE027', + DECIMAL: '\uE028', + DIVIDE: '\uE029', + + F1: '\uE031', // function keys + F2: '\uE032', + F3: '\uE033', + F4: '\uE034', + F5: '\uE035', + F6: '\uE036', + F7: '\uE037', + F8: '\uE038', + F9: '\uE039', + F10: '\uE03A', + F11: '\uE03B', + F12: '\uE03C', + + COMMAND: '\uE03D', // Apple command key + META: '\uE03D' // alias for Windows key +}; + + +/** + * Simulate pressing many keys at once in a "chord". Takes a sequence of + * {@linkplain Key keys} or strings, appends each of the values to a string, + * adds the chord termination key ({@link Key.NULL}) and returns the resulting + * string. + * + * Note: when the low-level webdriver key handlers see Keys.NULL, active + * modifier keys (CTRL/ALT/SHIFT/etc) release via a keyup event. + * + * @param {...string} var_args The key sequence to concatenate. + * @return {string} The null-terminated key sequence. + */ +Key.chord = function(var_args) { + return Array.prototype.slice.call(arguments, 0).join('') + Key.NULL; +}; + + +/** + * Used with {@link ./webelement.WebElement#sendKeys WebElement#sendKeys} on + * file input elements (``) to detect when the entered key + * sequence defines the path to a file. + * + * By default, {@linkplain ./webelement.WebElement WebElement's} will enter all + * key sequences exactly as entered. You may set a + * {@linkplain ./webdriver.WebDriver#setFileDetector file detector} on the + * parent WebDriver instance to define custom behavior for handling file + * elements. Of particular note is the + * {@link selenium-webdriver/remote.FileDetector}, which should be used when + * running against a remote + * [Selenium Server](http://docs.seleniumhq.org/download/). + */ +class FileDetector { + + /** + * Handles the file specified by the given path, preparing it for use with + * the current browser. If the path does not refer to a valid file, it will + * be returned unchanged, otherwisee a path suitable for use with the current + * browser will be returned. + * + * This default implementation is a no-op. Subtypes may override this function + * for custom tailored file handling. + * + * @param {!./webdriver.WebDriver} driver The driver for the current browser. + * @param {string} path The path to process. + * @return {!./promise.Promise} A promise for the processed file + * path. + * @package + */ + handleFile(driver, path) { + return promise.fulfilled(path); + } +} + + +// PUBLIC API + + +exports.Button = Button; +exports.Key = Key; +exports.FileDetector = FileDetector; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/logging.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/logging.js new file mode 100644 index 0000000..6bdee3e --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/logging.js @@ -0,0 +1,668 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * @fileoverview Defines WebDriver's logging system. The logging system is + * broken into major components: local and remote logging. + * + * The local logging API, which is anchored by the {@linkplain Logger} class is + * similar to Java's logging API. Loggers, retrieved by + * {@linkplain #getLogger getLogger(name)}, use hierarchical, dot-delimited + * namespaces (e.g. "" > "webdriver" > "webdriver.logging"). Recorded log + * messages are represented by the {@linkplain Entry} class. You can capture log + * records by {@linkplain Logger#addHandler attaching} a handler function to the + * desired logger. For convenience, you can quickly enable logging to the + * console by simply calling {@linkplain #installConsoleHandler + * installConsoleHandler}. + * + * The [remote logging API](https://github.com/SeleniumHQ/selenium/wiki/Logging) + * allows you to retrieve logs from a remote WebDriver server. This API uses the + * {@link Preferences} class to define desired log levels prior to creating + * a WebDriver session: + * + * var prefs = new logging.Preferences(); + * prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG); + * + * var caps = Capabilities.chrome(); + * caps.setLoggingPrefs(prefs); + * // ... + * + * Remote log entries, also represented by the {@link Entry} class, may be + * retrieved via {@link webdriver.WebDriver.Logs}: + * + * driver.manage().logs().get(logging.Type.BROWSER) + * .then(function(entries) { + * entries.forEach(function(entry) { + * console.log('[%s] %s', entry.level.name, entry.message); + * }); + * }); + * + * **NOTE:** Only a few browsers support the remote logging API (notably + * Firefox and Chrome). Firefox supports basic logging functionality, while + * Chrome exposes robust + * [performance logging](https://sites.google.com/a/chromium.org/chromedriver/logging) + * options. Remote logging is still considered a non-standard feature, and the + * APIs exposed by this module for it are non-frozen. This module will be + * updated, possibly breaking backwards-compatibility, once logging is + * officially defined by the + * [W3C WebDriver spec](http://www.w3.org/TR/webdriver/). + */ + +/** + * Defines a message level that may be used to control logging output. + * + * @final + */ +class Level { + /** + * @param {string} name the level's name. + * @param {number} level the level's numeric value. + */ + constructor(name, level) { + if (level < 0) { + throw new TypeError('Level must be >= 0'); + } + + /** @private {string} */ + this.name_ = name; + + /** @private {number} */ + this.value_ = level; + } + + /** This logger's name. */ + get name() { + return this.name_; + } + + /** The numeric log level. */ + get value() { + return this.value_; + } + + /** @override */ + toString() { + return this.name; + } +} + +/** + * Indicates no log messages should be recorded. + * @const + */ +Level.OFF = new Level('OFF', Infinity); + + +/** + * Log messages with a level of `1000` or higher. + * @const + */ +Level.SEVERE = new Level('SEVERE', 1000); + + +/** + * Log messages with a level of `900` or higher. + * @const + */ +Level.WARNING = new Level('WARNING', 900); + + +/** + * Log messages with a level of `800` or higher. + * @const + */ +Level.INFO = new Level('INFO', 800); + + +/** + * Log messages with a level of `700` or higher. + * @const + */ +Level.DEBUG = new Level('DEBUG', 700); + + +/** + * Log messages with a level of `500` or higher. + * @const + */ +Level.FINE = new Level('FINE', 500); + + +/** + * Log messages with a level of `400` or higher. + * @const + */ +Level.FINER = new Level('FINER', 400); + + +/** + * Log messages with a level of `300` or higher. + * @const + */ +Level.FINEST = new Level('FINEST', 300); + + +/** + * Indicates all log messages should be recorded. + * @const + */ +Level.ALL = new Level('ALL', 0); + + +const ALL_LEVELS = /** !Set */new Set([ + Level.OFF, + Level.SEVERE, + Level.WARNING, + Level.INFO, + Level.DEBUG, + Level.FINE, + Level.FINER, + Level.FINEST, + Level.ALL +]); + + +const LEVELS_BY_NAME = /** !Map */ new Map([ + [Level.OFF.name, Level.OFF], + [Level.SEVERE.name, Level.SEVERE], + [Level.WARNING.name, Level.WARNING], + [Level.INFO.name, Level.INFO], + [Level.DEBUG.name, Level.DEBUG], + [Level.FINE.name, Level.FINE], + [Level.FINER.name, Level.FINER], + [Level.FINEST.name, Level.FINEST], + [Level.ALL.name, Level.ALL] +]); + + +/** + * Converts a level name or value to a {@link Level} value. If the name/value + * is not recognized, {@link Level.ALL} will be returned. + * + * @param {(number|string)} nameOrValue The log level name, or value, to + * convert. + * @return {!Level} The converted level. + */ +function getLevel(nameOrValue) { + if (typeof nameOrValue === 'string') { + return LEVELS_BY_NAME.get(nameOrValue) || Level.ALL; + } + if (typeof nameOrValue !== 'number') { + throw new TypeError('not a string or number'); + } + for (let level of ALL_LEVELS) { + if (nameOrValue >= level.value) { + return level; + } + } + return Level.ALL; +} + + +/** + * Describes a single log entry. + * + * @final + */ +class Entry { + /** + * @param {(!Level|string|number)} level The entry level. + * @param {string} message The log message. + * @param {number=} opt_timestamp The time this entry was generated, in + * milliseconds since 0:00:00, January 1, 1970 UTC. If omitted, the + * current time will be used. + * @param {string=} opt_type The log type, if known. + */ + constructor(level, message, opt_timestamp, opt_type) { + this.level = level instanceof Level ? level : getLevel(level); + this.message = message; + this.timestamp = + typeof opt_timestamp === 'number' ? opt_timestamp : Date.now(); + this.type = opt_type || ''; + } + + /** + * @return {{level: string, message: string, timestamp: number, + * type: string}} The JSON representation of this entry. + */ + toJSON() { + return { + 'level': this.level.name, + 'message': this.message, + 'timestamp': this.timestamp, + 'type': this.type + }; + } +} + + +/** @typedef {(string|function(): string)} */ +let Loggable; + + +/** + * An object used to log debugging messages. Loggers use a hierarchical, + * dot-separated naming scheme. For instance, "foo" is considered the parent of + * the "foo.bar" and an ancestor of "foo.bar.baz". + * + * Each logger may be assigned a {@linkplain #setLevel log level}, which + * controls which level of messages will be reported to the + * {@linkplain #addHandler handlers} attached to this instance. If a log level + * is not explicitly set on a logger, it will inherit its parent. + * + * This class should never be directly instantiated. Instead, users should + * obtain logger references using the {@linkplain ./logging.getLogger() + * getLogger()} function. + * + * @final + */ +class Logger { + /** + * @param {string} name the name of this logger. + * @param {Level=} opt_level the initial level for this logger. + */ + constructor(name, opt_level) { + /** @private {string} */ + this.name_ = name; + + /** @private {Level} */ + this.level_ = opt_level || null; + + /** @private {Logger} */ + this.parent_ = null; + + /** @private {Set} */ + this.handlers_ = null; + } + + /** @return {string} the name of this logger. */ + getName() { + return this.name_; + } + + /** + * @param {Level} level the new level for this logger, or `null` if the logger + * should inherit its level from its parent logger. + */ + setLevel(level) { + this.level_ = level; + } + + /** @return {Level} the log level for this logger. */ + getLevel() { + return this.level_; + } + + /** + * @return {!Level} the effective level for this logger. + */ + getEffectiveLevel() { + let logger = this; + let level; + do { + level = logger.level_; + logger = logger.parent_; + } while (logger && !level); + return level || Level.OFF; + } + + /** + * @param {!Level} level the level to check. + * @return {boolean} whether messages recorded at the given level are loggable + * by this instance. + */ + isLoggable(level) { + return level.value !== Level.OFF.value + && level.value >= this.getEffectiveLevel().value; + } + + /** + * Adds a handler to this logger. The handler will be invoked for each message + * logged with this instance, or any of its descendants. + * + * @param {function(!Entry)} handler the handler to add. + */ + addHandler(handler) { + if (!this.handlers_) { + this.handlers_ = new Set; + } + this.handlers_.add(handler); + } + + /** + * Removes a handler from this logger. + * + * @param {function(!Entry)} handler the handler to remove. + * @return {boolean} whether a handler was successfully removed. + */ + removeHandler(handler) { + if (!this.handlers_) { + return false; + } + return this.handlers_.delete(handler); + } + + /** + * Logs a message at the given level. The message may be defined as a string + * or as a function that will return the message. If a function is provided, + * it will only be invoked if this logger's + * {@linkplain #getEffectiveLevel() effective log level} includes the given + * `level`. + * + * @param {!Level} level the level at which to log the message. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + log(level, loggable) { + if (!this.isLoggable(level)) { + return; + } + let message = '[' + this.name_ + '] ' + + (typeof loggable === 'function' ? loggable() : loggable); + let entry = new Entry(level, message, Date.now()); + for (let logger = this; !!logger; logger = logger.parent_) { + if (logger.handlers_) { + for (let handler of logger.handlers_) { + handler(entry); + } + } + } + } + + /** + * Logs a message at the {@link Level.SEVERE} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + severe(loggable) { + this.log(Level.SEVERE, loggable); + } + + /** + * Logs a message at the {@link Level.WARNING} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + warning(loggable) { + this.log(Level.WARNING, loggable); + } + + /** + * Logs a message at the {@link Level.INFO} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + info(loggable) { + this.log(Level.INFO, loggable); + } + + /** + * Logs a message at the {@link Level.DEBUG} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + debug(loggable) { + this.log(Level.DEBUG, loggable); + } + + /** + * Logs a message at the {@link Level.FINE} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + fine(loggable) { + this.log(Level.FINE, loggable); + } + + /** + * Logs a message at the {@link Level.FINER} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + finer(loggable) { + this.log(Level.FINER, loggable); + } + + /** + * Logs a message at the {@link Level.FINEST} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + finest(loggable) { + this.log(Level.FINEST, loggable); + } +} + + +/** + * Maintains a collection of loggers. + * + * @final + */ +class LogManager { + constructor() { + /** @private {!Map} */ + this.loggers_ = new Map; + this.root_ = new Logger('', Level.OFF); + } + + /** + * Retrieves a named logger, creating it in the process. This function will + * implicitly create the requested logger, and any of its parents, if they + * do not yet exist. + * + * @param {string} name the logger's name. + * @return {!Logger} the requested logger. + */ + getLogger(name) { + if (!name) { + return this.root_; + } + let parent = this.root_; + for (let i = name.indexOf('.'); i != -1; i = name.indexOf('.', i + 1)) { + let parentName = name.substr(0, i); + parent = this.createLogger_(parentName, parent); + } + return this.createLogger_(name, parent); + } + + /** + * Creates a new logger. + * + * @param {string} name the logger's name. + * @param {!Logger} parent the logger's parent. + * @return {!Logger} the new logger. + * @private + */ + createLogger_(name, parent) { + if (this.loggers_.has(name)) { + return /** @type {!Logger} */(this.loggers_.get(name)); + } + let logger = new Logger(name, null); + logger.parent_ = parent; + this.loggers_.set(name, logger); + return logger; + } +} + + +const logManager = new LogManager; + + +/** + * Retrieves a named logger, creating it in the process. This function will + * implicitly create the requested logger, and any of its parents, if they + * do not yet exist. + * + * The log level will be unspecified for newly created loggers. Use + * {@link Logger#setLevel(level)} to explicitly set a level. + * + * @param {string} name the logger's name. + * @return {!Logger} the requested logger. + */ +function getLogger(name) { + return logManager.getLogger(name); +} + + +function pad(n) { + if (n > 10) { + return '' + n; + } else { + return '0' + n; + } +} + + +/** + * Logs all messages to the Console API. + * @param {!Entry} entry the entry to log. + */ +function consoleHandler(entry) { + if (typeof console === 'undefined' || !console) { + return; + } + + var timestamp = new Date(entry.timestamp); + var msg = + '[' + timestamp.getUTCFullYear() + '-' + + pad(timestamp.getUTCMonth() + 1) + '-' + + pad(timestamp.getUTCDate()) + 'T' + + pad(timestamp.getUTCHours()) + ':' + + pad(timestamp.getUTCMinutes()) + ':' + + pad(timestamp.getUTCSeconds()) + 'Z] ' + + '[' + entry.level.name + '] ' + + entry.message; + + var level = entry.level.value; + if (level >= Level.SEVERE.value) { + console.error(msg); + } else if (level >= Level.WARNING.value) { + console.warn(msg); + } else { + console.log(msg); + } +} + + +/** + * Adds the console handler to the given logger. The console handler will log + * all messages using the JavaScript Console API. + * + * @param {Logger=} opt_logger The logger to add the handler to; defaults + * to the root logger. + */ +function addConsoleHandler(opt_logger) { + let logger = opt_logger || logManager.root_; + logger.addHandler(consoleHandler); +} + + +/** + * Removes the console log handler from the given logger. + * + * @param {Logger=} opt_logger The logger to remove the handler from; defaults + * to the root logger. + * @see exports.addConsoleHandler + */ +function removeConsoleHandler(opt_logger) { + let logger = opt_logger || logManager.root_; + logger.removeHandler(consoleHandler); +} + + +/** + * Installs the console log handler on the root logger. + */ +function installConsoleHandler() { + addConsoleHandler(logManager.root_); +} + + +/** + * Common log types. + * @enum {string} + */ +const Type = { + /** Logs originating from the browser. */ + BROWSER: 'browser', + /** Logs from a WebDriver client. */ + CLIENT: 'client', + /** Logs from a WebDriver implementation. */ + DRIVER: 'driver', + /** Logs related to performance. */ + PERFORMANCE: 'performance', + /** Logs from the remote server. */ + SERVER: 'server' +}; + + +/** + * Describes the log preferences for a WebDriver session. + * + * @final + */ +class Preferences { + constructor() { + /** @private {!Map} */ + this.prefs_ = new Map; + } + + /** + * Sets the desired logging level for a particular log type. + * @param {(string|Type)} type The log type. + * @param {(!Level|string|number)} level The desired log level. + * @throws {TypeError} if `type` is not a `string`. + */ + setLevel(type, level) { + if (typeof type !== 'string') { + throw TypeError('specified log type is not a string: ' + typeof type); + } + this.prefs_.set(type, level instanceof Level ? level : getLevel(level)); + } + + /** + * Converts this instance to its JSON representation. + * @return {!Object} The JSON representation of this set of + * preferences. + */ + toJSON() { + let json = {}; + for (let key of this.prefs_.keys()) { + json[key] = this.prefs_.get(key).name; + } + return json; + } +} + + +// PUBLIC API + + +exports.Entry = Entry; +exports.Level = Level; +exports.LogManager = LogManager; +exports.Logger = Logger; +exports.Preferences = Preferences; +exports.Type = Type; +exports.addConsoleHandler = addConsoleHandler; +exports.getLevel = getLevel; +exports.getLogger = getLogger; +exports.installConsoleHandler = installConsoleHandler; +exports.removeConsoleHandler = removeConsoleHandler; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/promise.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/promise.js new file mode 100644 index 0000000..905ec50 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/promise.js @@ -0,0 +1,3093 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview + * The promise module is centered around the {@linkplain ControlFlow}, a class + * that coordinates the execution of asynchronous tasks. The ControlFlow allows + * users to focus on the imperative commands for their script without worrying + * about chaining together every single asynchronous action, which can be + * tedious and verbose. APIs may be layered on top of the control flow to read + * as if they were synchronous. For instance, the core + * {@linkplain ./webdriver.WebDriver WebDriver} API is built on top of the + * control flow, allowing users to write + * + * driver.get('http://www.google.com/ncr'); + * driver.findElement({name: 'q'}).sendKeys('webdriver'); + * driver.findElement({name: 'btnGn'}).click(); + * + * instead of + * + * driver.get('http://www.google.com/ncr') + * .then(function() { + * return driver.findElement({name: 'q'}); + * }) + * .then(function(q) { + * return q.sendKeys('webdriver'); + * }) + * .then(function() { + * return driver.findElement({name: 'btnG'}); + * }) + * .then(function(btnG) { + * return btnG.click(); + * }); + * + * ## Tasks and Task Queues + * + * The control flow is based on the concept of tasks and task queues. Tasks are + * functions that define the basic unit of work for the control flow to execute. + * Each task is scheduled via {@link ControlFlow#execute()}, which will return + * a {@link ManagedPromise ManagedPromise} that will be resolved with the task's + * result. + * + * A task queue contains all of the tasks scheduled within a single turn of the + * [JavaScript event loop][JSEL]. The control flow will create a new task queue + * the first time a task is scheduled within an event loop. + * + * var flow = promise.controlFlow(); + * flow.execute(foo); // Creates a new task queue and inserts foo. + * flow.execute(bar); // Inserts bar into the same queue as foo. + * setTimeout(function() { + * flow.execute(baz); // Creates a new task queue and inserts baz. + * }, 0); + * + * Whenever the control flow creates a new task queue, it will automatically + * begin executing tasks in the next available turn of the event loop. This + * execution is scheduled using a "micro-task" timer, such as a (native) + * `ManagedPromise.then()` callback. + * + * setTimeout(() => console.log('a')); + * ManagedPromise.resolve().then(() => console.log('b')); // A native promise. + * flow.execute(() => console.log('c')); + * ManagedPromise.resolve().then(() => console.log('d')); + * setTimeout(() => console.log('fin')); + * // b + * // c + * // d + * // a + * // fin + * + * In the example above, b/c/d is logged before a/fin because native promises + * and this module use "micro-task" timers, which have a higher priority than + * "macro-tasks" like `setTimeout`. + * + * ## Task Execution + * + * Upon creating a task queue, and whenever an exisiting queue completes a task, + * the control flow will schedule a micro-task timer to process any scheduled + * tasks. This ensures no task is ever started within the same turn of the + * JavaScript event loop in which it was scheduled, nor is a task ever started + * within the same turn that another finishes. + * + * When the execution timer fires, a single task will be dequeued and executed. + * There are several important events that may occur while executing a task + * function: + * + * 1. A new task queue is created by a call to {@link ControlFlow#execute()}. + * Any tasks scheduled within this task queue are considered subtasks of the + * current task. + * 2. The task function throws an error. Any scheduled tasks are immediately + * discarded and the task's promised result (previously returned by + * {@link ControlFlow#execute()}) is immediately rejected with the thrown + * error. + * 3. The task function returns sucessfully. + * + * If a task function created a new task queue, the control flow will wait for + * that queue to complete before processing the task result. If the queue + * completes without error, the flow will settle the task's promise with the + * value originaly returned by the task function. On the other hand, if the task + * queue termintes with an error, the task's promise will be rejected with that + * error. + * + * flow.execute(function() { + * flow.execute(() => console.log('a')); + * flow.execute(() => console.log('b')); + * }); + * flow.execute(() => console.log('c')); + * // a + * // b + * // c + * + * ## ManagedPromise Integration + * + * In addition to the {@link ControlFlow} class, the promise module also exports + * a [ManagedPromise/A+] {@linkplain ManagedPromise implementation} that is deeply + * integrated with the ControlFlow. First and foremost, each promise + * {@linkplain ManagedPromise#then() callback} is scheduled with the + * control flow as a task. As a result, each callback is invoked in its own turn + * of the JavaScript event loop with its own task queue. If any tasks are + * scheduled within a callback, the callback's promised result will not be + * settled until the task queue has completed. + * + * promise.fulfilled().then(function() { + * flow.execute(function() { + * console.log('b'); + * }); + * }).then(() => console.log('a')); + * // b + * // a + * + * ### Scheduling ManagedPromise Callbacks + * + * How callbacks are scheduled in the control flow depends on when they are + * attached to the promise. Callbacks attached to a _previously_ resolved + * promise are immediately enqueued as subtasks of the currently running task. + * + * var p = promise.fulfilled(); + * flow.execute(function() { + * flow.execute(() => console.log('A')); + * p.then( () => console.log('B')); + * flow.execute(() => console.log('C')); + * p.then( () => console.log('D')); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // B + * // C + * // D + * // fin + * + * When a promise is resolved while a task function is on the call stack, any + * callbacks also registered in that stack frame are scheduled as if the promise + * were already resolved: + * + * var d = promise.defer(); + * flow.execute(function() { + * flow.execute( () => console.log('A')); + * d.promise.then(() => console.log('B')); + * flow.execute( () => console.log('C')); + * d.promise.then(() => console.log('D')); + * + * d.fulfill(); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // B + * // C + * // D + * // fin + * + * Callbacks attached to an _unresolved_ promise within a task function are + * only weakly scheduled as subtasks and will be dropped if they reach the + * front of the queue before the promise is resolved. In the example below, the + * callbacks for `B` & `D` are dropped as sub-tasks since they are attached to + * an unresolved promise when they reach the front of the task queue. + * + * var d = promise.defer(); + * flow.execute(function() { + * flow.execute( () => console.log('A')); + * d.promise.then(() => console.log('B')); + * flow.execute( () => console.log('C')); + * d.promise.then(() => console.log('D')); + * + * setTimeout(d.fulfill, 20); + * }).then(function() { + * console.log('fin') + * }); + * // A + * // C + * // fin + * // B + * // D + * + * If a promise is resolved while a task function is on the call stack, any + * previously registered and unqueued callbacks (i.e. either attached while no + * task was on the call stack, or previously dropped as described above) act as + * _interrupts_ and are inserted at the front of the task queue. If multiple + * promises are fulfilled, their interrupts are enqueued in the order the + * promises are resolved. + * + * var d1 = promise.defer(); + * d1.promise.then(() => console.log('A')); + * + * var d2 = promise.defer(); + * d2.promise.then(() => console.log('B')); + * + * flow.execute(function() { + * d1.promise.then(() => console.log('C')); + * flow.execute(() => console.log('D')); + * }); + * flow.execute(function() { + * flow.execute(() => console.log('E')); + * flow.execute(() => console.log('F')); + * d1.fulfill(); + * d2.fulfill(); + * }).then(function() { + * console.log('fin'); + * }); + * // D + * // A + * // C + * // B + * // E + * // F + * // fin + * + * Within a task function (or callback), each step of a promise chain acts as + * an interrupt on the task queue: + * + * var d = promise.defer(); + * flow.execute(function() { + * d.promise. + * then(() => console.log('A')). + * then(() => console.log('B')). + * then(() => console.log('C')). + * then(() => console.log('D')); + * + * flow.execute(() => console.log('E')); + * d.fulfill(); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // B + * // C + * // D + * // E + * // fin + * + * If there are multiple promise chains derived from a single promise, they are + * processed in the order created: + * + * var d = promise.defer(); + * flow.execute(function() { + * var chain = d.promise.then(() => console.log('A')); + * + * chain.then(() => console.log('B')). + * then(() => console.log('C')); + * + * chain.then(() => console.log('D')). + * then(() => console.log('E')); + * + * flow.execute(() => console.log('F')); + * + * d.fulfill(); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // B + * // C + * // D + * // E + * // F + * // fin + * + * Even though a subtask's promised result will never resolve while the task + * function is on the stack, it will be treated as a promise resolved within the + * task. In all other scenarios, a task's promise behaves just like a normal + * promise. In the sample below, `C/D` is loggged before `B` because the + * resolution of `subtask1` interrupts the flow of the enclosing task. Within + * the final subtask, `E/F` is logged in order because `subtask1` is a resolved + * promise when that task runs. + * + * flow.execute(function() { + * var subtask1 = flow.execute(() => console.log('A')); + * var subtask2 = flow.execute(() => console.log('B')); + * + * subtask1.then(() => console.log('C')); + * subtask1.then(() => console.log('D')); + * + * flow.execute(function() { + * flow.execute(() => console.log('E')); + * subtask1.then(() => console.log('F')); + * }); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // C + * // D + * // B + * // E + * // F + * // fin + * + * Finally, consider the following: + * + * var d = promise.defer(); + * d.promise.then(() => console.log('A')); + * d.promise.then(() => console.log('B')); + * + * flow.execute(function() { + * flow.execute( () => console.log('C')); + * d.promise.then(() => console.log('D')); + * + * flow.execute( () => console.log('E')); + * d.promise.then(() => console.log('F')); + * + * d.fulfill(); + * + * flow.execute( () => console.log('G')); + * d.promise.then(() => console.log('H')); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // B + * // C + * // D + * // E + * // F + * // G + * // H + * // fin + * + * In this example, callbacks are registered on `d.promise` both before and + * during the invocation of the task function. When `d.fulfill()` is called, + * the callbacks registered before the task (`A` & `B`) are registered as + * interrupts. The remaining callbacks were all attached within the task and + * are scheduled in the flow as standard tasks. + * + * ## Generator Support + * + * [Generators][GF] may be scheduled as tasks within a control flow or attached + * as callbacks to a promise. Each time the generator yields a promise, the + * control flow will wait for that promise to settle before executing the next + * iteration of the generator. The yielded promise's fulfilled value will be + * passed back into the generator: + * + * flow.execute(function* () { + * var d = promise.defer(); + * + * setTimeout(() => console.log('...waiting...'), 25); + * setTimeout(() => d.fulfill(123), 50); + * + * console.log('start: ' + Date.now()); + * + * var value = yield d.promise; + * console.log('mid: %d; value = %d', Date.now(), value); + * + * yield promise.delayed(10); + * console.log('end: ' + Date.now()); + * }).then(function() { + * console.log('fin'); + * }); + * // start: 0 + * // ...waiting... + * // mid: 50; value = 123 + * // end: 60 + * // fin + * + * Yielding the result of a promise chain will wait for the entire chain to + * complete: + * + * promise.fulfilled().then(function* () { + * console.log('start: ' + Date.now()); + * + * var value = yield flow. + * execute(() => console.log('A')). + * then( () => console.log('B')). + * then( () => 123); + * + * console.log('mid: %s; value = %d', Date.now(), value); + * + * yield flow.execute(() => console.log('C')); + * }).then(function() { + * console.log('fin'); + * }); + * // start: 0 + * // A + * // B + * // mid: 2; value = 123 + * // C + * // fin + * + * Yielding a _rejected_ promise will cause the rejected value to be thrown + * within the generator function: + * + * flow.execute(function* () { + * console.log('start: ' + Date.now()); + * try { + * yield promise.delayed(10).then(function() { + * throw Error('boom'); + * }); + * } catch (ex) { + * console.log('caught time: ' + Date.now()); + * console.log(ex.message); + * } + * }); + * // start: 0 + * // caught time: 10 + * // boom + * + * # Error Handling + * + * ES6 promises do not require users to handle a promise rejections. This can + * result in subtle bugs as the rejections are silently "swallowed" by the + * ManagedPromise class. + * + * ManagedPromise.reject(Error('boom')); + * // ... *crickets* ... + * + * Selenium's promise module, on the other hand, requires that every rejection + * be explicitly handled. When a {@linkplain ManagedPromise ManagedPromise} is + * rejected and no callbacks are defined on that promise, it is considered an + * _unhandled rejection_ and reproted to the active task queue. If the rejection + * remains unhandled after a single turn of the [event loop][JSEL] (scheduled + * with a micro-task), it will propagate up the stack. + * + * ## Error Propagation + * + * If an unhandled rejection occurs within a task function, that task's promised + * result is rejected and all remaining subtasks are discarded: + * + * flow.execute(function() { + * // No callbacks registered on promise -> unhandled rejection + * promise.rejected(Error('boom')); + * flow.execute(function() { console.log('this will never run'); }); + * }).catch(function(e) { + * console.log(e.message); + * }); + * // boom + * + * The promised results for discarded tasks are silently rejected with a + * cancellation error and existing callback chains will never fire. + * + * flow.execute(function() { + * promise.rejected(Error('boom')); + * flow.execute(function() { console.log('a'); }). + * then(function() { console.log('b'); }); + * }).catch(function(e) { + * console.log(e.message); + * }); + * // boom + * + * An unhandled rejection takes precedence over a task function's returned + * result, even if that value is another promise: + * + * flow.execute(function() { + * promise.rejected(Error('boom')); + * return flow.execute(someOtherTask); + * }).catch(function(e) { + * console.log(e.message); + * }); + * // boom + * + * If there are multiple unhandled rejections within a task, they are packaged + * in a {@link MultipleUnhandledRejectionError}, which has an `errors` property + * that is a `Set` of the recorded unhandled rejections: + * + * flow.execute(function() { + * promise.rejected(Error('boom1')); + * promise.rejected(Error('boom2')); + * }).catch(function(ex) { + * console.log(ex instanceof MultipleUnhandledRejectionError); + * for (var e of ex.errors) { + * console.log(e.message); + * } + * }); + * // boom1 + * // boom2 + * + * When a subtask is discarded due to an unreported rejection in its parent + * frame, the existing callbacks on that task will never settle and the + * callbacks will not be invoked. If a new callback is attached ot the subtask + * _after_ it has been discarded, it is handled the same as adding a callback + * to a cancelled promise: the error-callback path is invoked. This behavior is + * intended to handle cases where the user saves a reference to a task promise, + * as illustrated below. + * + * var subTask; + * flow.execute(function() { + * promise.rejected(Error('boom')); + * subTask = flow.execute(function() {}); + * }).catch(function(e) { + * console.log(e.message); + * }).then(function() { + * return subTask.then( + * () => console.log('subtask success!'), + * (e) => console.log('subtask failed:\n' + e)); + * }); + * // boom + * // subtask failed: + * // DiscardedTaskError: Task was discarded due to a previous failure: boom + * + * When a subtask fails, its promised result is treated the same as any other + * promise: it must be handled within one turn of the rejection or the unhandled + * rejection is propagated to the parent task. This means users can catch errors + * from complex flows from the top level task: + * + * flow.execute(function() { + * flow.execute(function() { + * flow.execute(function() { + * throw Error('fail!'); + * }); + * }); + * }).catch(function(e) { + * console.log(e.message); + * }); + * // fail! + * + * ## Unhandled Rejection Events + * + * When an unhandled rejection propagates to the root of the control flow, the + * flow will emit an __uncaughtException__ event. If no listeners are registered + * on the flow, the error will be rethrown to the global error handler: an + * __uncaughtException__ event from the + * [`process`](https://nodejs.org/api/process.html) object in node, or + * `window.onerror` when running in a browser. + * + * Bottom line: you __*must*__ handle rejected promises. + * + * # ManagedPromise/A+ Compatibility + * + * This `promise` module is compliant with the [ManagedPromise/A+][] specification + * except for sections `2.2.6.1` and `2.2.6.2`: + * + * > + * > - `then` may be called multiple times on the same promise. + * > - If/when `promise` is fulfilled, all respective `onFulfilled` callbacks + * > must execute in the order of their originating calls to `then`. + * > - If/when `promise` is rejected, all respective `onRejected` callbacks + * > must execute in the order of their originating calls to `then`. + * > + * + * Specifically, the conformance tests contains the following scenario (for + * brevity, only the fulfillment version is shown): + * + * var p1 = ManagedPromise.resolve(); + * p1.then(function() { + * console.log('A'); + * p1.then(() => console.log('B')); + * }); + * p1.then(() => console.log('C')); + * // A + * // C + * // B + * + * Since the [ControlFlow](#scheduling_callbacks) executes promise callbacks as + * tasks, with this module, the result would be + * + * var p2 = promise.fulfilled(); + * p2.then(function() { + * console.log('A'); + * p2.then(() => console.log('B'); + * }); + * p2.then(() => console.log('C')); + * // A + * // B + * // C + * + * [JSEL]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop + * [GF]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function* + * [ManagedPromise/A+]: https://promisesaplus.com/ + */ + +'use strict'; + +const events = require('./events'); +const logging = require('./logging'); + + +/** + * Alias to help with readability and differentiate types. + * @const + */ +const NativePromise = Promise; + + +/** + * Whether to append traces of `then` to rejection errors. + * @type {boolean} + */ +exports.LONG_STACK_TRACES = false; // TODO: this should not be CONSTANT_CASE + + +/** @const */ +const LOG = logging.getLogger('promise'); + + +const UNIQUE_IDS = new WeakMap; +let nextId = 1; + + +function getUid(obj) { + let id = UNIQUE_IDS.get(obj); + if (!id) { + id = nextId; + nextId += 1; + UNIQUE_IDS.set(obj, id); + } + return id; +} + + +/** + * Runs the given function after a micro-task yield. + * @param {function()} fn The function to run. + */ +function asyncRun(fn) { + NativePromise.resolve().then(function() { + try { + fn(); + } catch (ignored) { + // Do nothing. + } + }); +} + + +/** + * Throws an error asynchronously so it is reported to the global error handler. + * + * @param {!Error} error The error to throw. + */ +function asyncThrow(error) { + setTimeout(function() { + throw error; + }, 0); +} + + +/** + * @param {number} level What level of verbosity to log with. + * @param {(string|function(this: T): string)} loggable The message to log. + * @param {T=} opt_self The object in whose context to run the loggable + * function. + * @template T + */ +function vlog(level, loggable, opt_self) { + var logLevel = logging.Level.FINE; + if (level > 1) { + logLevel = logging.Level.FINEST; + } else if (level > 0) { + logLevel = logging.Level.FINER; + } + + if (typeof loggable === 'function') { + loggable = loggable.bind(opt_self); + } + + LOG.log(logLevel, loggable); +} + + +/** + * Generates an error to capture the current stack trace. + * @param {string} name Error name for this stack trace. + * @param {string} msg Message to record. + * @param {Function=} opt_topFn The function that should appear at the top of + * the stack; only applicable in V8. + * @return {!Error} The generated error. + */ +function captureStackTrace(name, msg, opt_topFn) { + var e = Error(msg); + e.name = name; + if (Error.captureStackTrace) { + Error.captureStackTrace(e, opt_topFn); + } else { + var stack = Error().stack; + if (stack) { + e.stack = e.toString(); + e.stack += '\n' + stack; + } + } + return e; +} + + +/** + * Error used when the computation of a promise is cancelled. + */ +class CancellationError extends Error { + /** + * @param {string=} opt_msg The cancellation message. + */ + constructor(opt_msg) { + super(opt_msg); + + /** @override */ + this.name = this.constructor.name; + + /** @private {boolean} */ + this.silent_ = false; + } + + /** + * Wraps the given error in a CancellationError. + * + * @param {*} error The error to wrap. + * @param {string=} opt_msg The prefix message to use. + * @return {!CancellationError} A cancellation error. + */ + static wrap(error, opt_msg) { + var message; + if (error instanceof CancellationError) { + return new CancellationError( + opt_msg ? (opt_msg + ': ' + error.message) : error.message); + } else if (opt_msg) { + message = opt_msg; + if (error) { + message += ': ' + error; + } + return new CancellationError(message); + } + if (error) { + message = error + ''; + } + return new CancellationError(message); + } +} + + +/** + * Error used to cancel tasks when a control flow is reset. + * @final + */ +class FlowResetError extends CancellationError { + constructor() { + super('ControlFlow was reset'); + this.silent_ = true; + } +} + + +/** + * Error used to cancel tasks that have been discarded due to an uncaught error + * reported earlier in the control flow. + * @final + */ +class DiscardedTaskError extends CancellationError { + /** @param {*} error The original error. */ + constructor(error) { + if (error instanceof DiscardedTaskError) { + return /** @type {!DiscardedTaskError} */(error); + } + + var msg = ''; + if (error) { + msg = ': ' + ( + typeof error.message === 'string' ? error.message : error); + } + + super('Task was discarded due to a previous failure' + msg); + this.silent_ = true; + } +} + + +/** + * Error used when there are multiple unhandled promise rejections detected + * within a task or callback. + * + * @final + */ +class MultipleUnhandledRejectionError extends Error { + /** + * @param {!(Set<*>)} errors The errors to report. + */ + constructor(errors) { + super('Multiple unhandled promise rejections reported'); + + /** @override */ + this.name = this.constructor.name; + + /** @type {!Set<*>} */ + this.errors = errors; + } +} + + +/** + * Property used to flag constructor's as implementing the Thenable interface + * for runtime type checking. + * @const + */ +const IMPLEMENTED_BY_SYMBOL = Symbol('promise.Thenable'); + + +/** + * Thenable is a promise-like object with a {@code then} method which may be + * used to schedule callbacks on a promised value. + * + * @interface + * @extends {IThenable} + * @template T + */ +class Thenable { + /** + * Adds a property to a class prototype to allow runtime checks of whether + * instances of that class implement the Thenable interface. This function + * will also ensure the prototype's {@code then} function is exported from + * compiled code. + * @param {function(new: Thenable, ...?)} ctor The + * constructor whose prototype to modify. + */ + static addImplementation(ctor) { + ctor.prototype['then'] = ctor.prototype.then; + try { + ctor.prototype[IMPLEMENTED_BY_SYMBOL] = true; + } catch (ignored) { + // Property access denied? + } + } + + /** + * Checks if an object has been tagged for implementing the Thenable + * interface as defined by {@link Thenable.addImplementation}. + * @param {*} object The object to test. + * @return {boolean} Whether the object is an implementation of the Thenable + * interface. + */ + static isImplementation(object) { + if (!object) { + return false; + } + try { + return !!object[IMPLEMENTED_BY_SYMBOL]; + } catch (e) { + return false; // Property access seems to be forbidden. + } + } + + /** + * Cancels the computation of this promise's value, rejecting the promise in + * the process. This method is a no-op if the promise has already been + * resolved. + * + * @param {(string|Error)=} opt_reason The reason this promise is being + * cancelled. This value will be wrapped in a {@link CancellationError}. + */ + cancel(opt_reason) {} + + /** @return {boolean} Whether this promise's value is still being computed. */ + isPending() {} + + /** + * Registers listeners for when this instance is resolved. + * + * @param {?(function(T): (R|IThenable))=} opt_callback The + * function to call if this promise is successfully resolved. The function + * should expect a single argument: the promise's resolved value. + * @param {?(function(*): (R|IThenable))=} opt_errback + * The function to call if this promise is rejected. The function should + * expect a single argument: the rejection reason. + * @return {!ManagedPromise} A new promise which will be + * resolved with the result of the invoked callback. + * @template R + */ + then(opt_callback, opt_errback) {} + + /** + * Registers a listener for when this promise is rejected. This is synonymous + * with the {@code catch} clause in a synchronous API: + * + * // Synchronous API: + * try { + * doSynchronousWork(); + * } catch (ex) { + * console.error(ex); + * } + * + * // Asynchronous promise API: + * doAsynchronousWork().catch(function(ex) { + * console.error(ex); + * }); + * + * @param {function(*): (R|IThenable)} errback The + * function to call if this promise is rejected. The function should + * expect a single argument: the rejection reason. + * @return {!ManagedPromise} A new promise which will be + * resolved with the result of the invoked callback. + * @template R + */ + catch(errback) {} + + /** + * An alias for {@link #catch()} + * + * @param {function(*): (R|IThenable)} errback The + * function to call if this promise is rejected. The function should + * expect a single argument: the rejection reason. + * @return {!ManagedPromise} A new promise which will be + * resolved wdith the result of the invoked callback. + * @template R + */ + thenCatch(errback) {} + + /** + * Registers a listener to invoke when this promise is resolved, regardless + * of whether the promise's value was successfully computed. This function + * is synonymous with the {@code finally} clause in a synchronous API: + * + * // Synchronous API: + * try { + * doSynchronousWork(); + * } finally { + * cleanUp(); + * } + * + * // Asynchronous promise API: + * doAsynchronousWork().thenFinally(cleanUp); + * + * __Note:__ similar to the {@code finally} clause, if the registered + * callback returns a rejected promise or throws an error, it will silently + * replace the rejection error (if any) from this promise: + * + * try { + * throw Error('one'); + * } finally { + * throw Error('two'); // Hides Error: one + * } + * + * promise.rejected(Error('one')) + * .thenFinally(function() { + * throw Error('two'); // Hides Error: one + * }); + * + * @param {function(): (R|IThenable)} callback The function + * to call when this promise is resolved. + * @return {!ManagedPromise} A promise that will be fulfilled + * with the callback result. + * @template R + */ + thenFinally(callback) {} +} + + +/** + * @enum {string} + */ +const PromiseState = { + PENDING: 'pending', + BLOCKED: 'blocked', + REJECTED: 'rejected', + FULFILLED: 'fulfilled' +}; + + +/** + * Internal symbol used to store a cancellation handler for + * {@link ManagedPromise} objects. This is an internal implementation detail + * used by the {@link TaskQueue} class to monitor for when a promise is + * cancelled without generating an extra promise via then(). + */ +const CANCEL_HANDLER_SYMBOL = Symbol('on cancel'); + + +/** + * Represents the eventual value of a completed operation. Each promise may be + * in one of three states: pending, fulfilled, or rejected. Each promise starts + * in the pending state and may make a single transition to either a + * fulfilled or rejected state, at which point the promise is considered + * resolved. + * + * @implements {Thenable} + * @unrestricted + * @template T + * @see http://promises-aplus.github.io/promises-spec/ + */ +const ManagedPromise = class Promise { + /** + * @param {function( + * function((T|IThenable|Thenable)=), + * function(*=))} resolver + * Function that is invoked immediately to begin computation of this + * promise's value. The function should accept a pair of callback + * functions, one for fulfilling the promise and another for rejecting it. + * @param {ControlFlow=} opt_flow The control flow + * this instance was created under. Defaults to the currently active flow. + */ + constructor(resolver, opt_flow) { + getUid(this); + + /** @private {!ControlFlow} */ + this.flow_ = opt_flow || controlFlow(); + + /** @private {Error} */ + this.stack_ = null; + if (exports.LONG_STACK_TRACES) { + this.stack_ = captureStackTrace('Promise', 'new', this.constructor); + } + + /** @private {ManagedPromise} */ + this.parent_ = null; + + /** @private {Array} */ + this.callbacks_ = null; + + /** @private {PromiseState} */ + this.state_ = PromiseState.PENDING; + + /** @private {boolean} */ + this.handled_ = false; + + /** @private {*} */ + this.value_ = undefined; + + /** @private {TaskQueue} */ + this.queue_ = null; + + /** @private {(function(CancellationError)|null)} */ + this[CANCEL_HANDLER_SYMBOL] = null; + + try { + var self = this; + resolver(function(value) { + self.resolve_(PromiseState.FULFILLED, value); + }, function(reason) { + self.resolve_(PromiseState.REJECTED, reason); + }); + } catch (ex) { + this.resolve_(PromiseState.REJECTED, ex); + } + } + + /** @override */ + toString() { + return 'ManagedPromise::' + getUid(this) + + ' {[[PromiseStatus]]: "' + this.state_ + '"}'; + } + + /** + * Resolves this promise. If the new value is itself a promise, this function + * will wait for it to be resolved before notifying the registered listeners. + * @param {PromiseState} newState The promise's new state. + * @param {*} newValue The promise's new value. + * @throws {TypeError} If {@code newValue === this}. + * @private + */ + resolve_(newState, newValue) { + if (PromiseState.PENDING !== this.state_) { + return; + } + + if (newValue === this) { + // See promise a+, 2.3.1 + // http://promises-aplus.github.io/promises-spec/#point-48 + newValue = new TypeError('A promise may not resolve to itself'); + newState = PromiseState.REJECTED; + } + + this.parent_ = null; + this.state_ = PromiseState.BLOCKED; + + if (newState !== PromiseState.REJECTED) { + if (Thenable.isImplementation(newValue)) { + // 2.3.2 + newValue = /** @type {!Thenable} */(newValue); + newValue.then( + this.unblockAndResolve_.bind(this, PromiseState.FULFILLED), + this.unblockAndResolve_.bind(this, PromiseState.REJECTED)); + return; + + } else if (newValue + && (typeof newValue === 'object' || typeof newValue === 'function')) { + // 2.3.3 + + try { + // 2.3.3.1 + var then = newValue['then']; + } catch (e) { + // 2.3.3.2 + this.state_ = PromiseState.REJECTED; + this.value_ = e; + this.scheduleNotifications_(); + return; + } + + if (typeof then === 'function') { + // 2.3.3.3 + this.invokeThen_(/** @type {!Object} */(newValue), then); + return; + } + } + } + + if (newState === PromiseState.REJECTED && + isError(newValue) && newValue.stack && this.stack_) { + newValue.stack += '\nFrom: ' + (this.stack_.stack || this.stack_); + } + + // 2.3.3.4 and 2.3.4 + this.state_ = newState; + this.value_ = newValue; + this.scheduleNotifications_(); + } + + /** + * Invokes a thenable's "then" method according to 2.3.3.3 of the promise + * A+ spec. + * @param {!Object} x The thenable object. + * @param {!Function} then The "then" function to invoke. + * @private + */ + invokeThen_(x, then) { + var called = false; + var self = this; + + var resolvePromise = function(value) { + if (!called) { // 2.3.3.3.3 + called = true; + // 2.3.3.3.1 + self.unblockAndResolve_(PromiseState.FULFILLED, value); + } + }; + + var rejectPromise = function(reason) { + if (!called) { // 2.3.3.3.3 + called = true; + // 2.3.3.3.2 + self.unblockAndResolve_(PromiseState.REJECTED, reason); + } + }; + + try { + // 2.3.3.3 + then.call(x, resolvePromise, rejectPromise); + } catch (e) { + // 2.3.3.3.4.2 + rejectPromise(e); + } + } + + /** + * @param {PromiseState} newState The promise's new state. + * @param {*} newValue The promise's new value. + * @private + */ + unblockAndResolve_(newState, newValue) { + if (this.state_ === PromiseState.BLOCKED) { + this.state_ = PromiseState.PENDING; + this.resolve_(newState, newValue); + } + } + + /** + * @private + */ + scheduleNotifications_() { + vlog(2, () => this + ' scheduling notifications', this); + + this[CANCEL_HANDLER_SYMBOL] = null; + if (this.value_ instanceof CancellationError + && this.value_.silent_) { + this.callbacks_ = null; + } + + if (!this.queue_) { + this.queue_ = this.flow_.getActiveQueue_(); + } + + if (!this.handled_ && + this.state_ === PromiseState.REJECTED && + !(this.value_ instanceof CancellationError)) { + this.queue_.addUnhandledRejection(this); + } + this.queue_.scheduleCallbacks(this); + } + + /** @override */ + cancel(opt_reason) { + if (!canCancel(this)) { + return; + } + + if (this.parent_ && canCancel(this.parent_)) { + this.parent_.cancel(opt_reason); + } else { + var reason = CancellationError.wrap(opt_reason); + if (this[CANCEL_HANDLER_SYMBOL]) { + this[CANCEL_HANDLER_SYMBOL](reason); + this[CANCEL_HANDLER_SYMBOL] = null; + } + + if (this.state_ === PromiseState.BLOCKED) { + this.unblockAndResolve_(PromiseState.REJECTED, reason); + } else { + this.resolve_(PromiseState.REJECTED, reason); + } + } + + function canCancel(promise) { + return promise.state_ === PromiseState.PENDING + || promise.state_ === PromiseState.BLOCKED; + } + } + + /** @override */ + isPending() { + return this.state_ === PromiseState.PENDING; + } + + /** @override */ + then(opt_callback, opt_errback) { + return this.addCallback_( + opt_callback, opt_errback, 'then', ManagedPromise.prototype.then); + } + + /** @override */ + catch(errback) { + return this.addCallback_( + null, errback, 'catch', ManagedPromise.prototype.catch); + } + + /** @override */ + thenCatch(errback) { + return this.catch(errback); + } + + /** @override */ + thenFinally(callback) { + var error; + var mustThrow = false; + return this.then(function() { + return callback(); + }, function(err) { + error = err; + mustThrow = true; + return callback(); + }).then(function() { + if (mustThrow) { + throw error; + } + }); + } + + /** + * Registers a new callback with this promise + * @param {(function(T): (R|IThenable)|null|undefined)} callback The + * fulfillment callback. + * @param {(function(*): (R|IThenable)|null|undefined)} errback The + * rejection callback. + * @param {string} name The callback name. + * @param {!Function} fn The function to use as the top of the stack when + * recording the callback's creation point. + * @return {!ManagedPromise} A new promise which will be resolved with the + * esult of the invoked callback. + * @template R + * @private + */ + addCallback_(callback, errback, name, fn) { + if (typeof callback !== 'function' && typeof errback !== 'function') { + return this; + } + + this.handled_ = true; + if (this.queue_) { + this.queue_.clearUnhandledRejection(this); + } + + var cb = new Task( + this.flow_, + this.invokeCallback_.bind(this, callback, errback), + name, + exports.LONG_STACK_TRACES ? {name: 'Promise', top: fn} : undefined); + cb.promise.parent_ = this; + + if (this.state_ !== PromiseState.PENDING && + this.state_ !== PromiseState.BLOCKED) { + this.flow_.getActiveQueue_().enqueue(cb); + } else { + if (!this.callbacks_) { + this.callbacks_ = []; + } + this.callbacks_.push(cb); + cb.blocked = true; + this.flow_.getActiveQueue_().enqueue(cb); + } + + return cb.promise; + } + + /** + * Invokes a callback function attached to this promise. + * @param {(function(T): (R|IThenable)|null|undefined)} callback The + * fulfillment callback. + * @param {(function(*): (R|IThenable)|null|undefined)} errback The + * rejection callback. + * @template R + * @private + */ + invokeCallback_(callback, errback) { + var callbackFn = callback; + if (this.state_ === PromiseState.REJECTED) { + callbackFn = errback; + } + + if (typeof callbackFn === 'function') { + if (isGenerator(callbackFn)) { + return consume(callbackFn, null, this.value_); + } + return callbackFn(this.value_); + } else if (this.state_ === PromiseState.REJECTED) { + throw this.value_; + } else { + return this.value_; + } + } +} +Thenable.addImplementation(ManagedPromise); + + +/** + * Represents a value that will be resolved at some point in the future. This + * class represents the protected "producer" half of a ManagedPromise - each Deferred + * has a {@code promise} property that may be returned to consumers for + * registering callbacks, reserving the ability to resolve the deferred to the + * producer. + * + * If this Deferred is rejected and there are no listeners registered before + * the next turn of the event loop, the rejection will be passed to the + * {@link ControlFlow} as an unhandled failure. + * + * @implements {Thenable} + * @template T + */ +class Deferred { + /** + * @param {ControlFlow=} opt_flow The control flow this instance was + * created under. This should only be provided during unit tests. + */ + constructor(opt_flow) { + var fulfill, reject; + + /** @type {!ManagedPromise} */ + this.promise = new ManagedPromise(function(f, r) { + fulfill = f; + reject = r; + }, opt_flow); + + var self = this; + var checkNotSelf = function(value) { + if (value === self) { + throw new TypeError('May not resolve a Deferred with itself'); + } + }; + + /** + * Resolves this deferred with the given value. It is safe to call this as a + * normal function (with no bound "this"). + * @param {(T|IThenable|Thenable)=} opt_value The fulfilled value. + */ + this.fulfill = function(opt_value) { + checkNotSelf(opt_value); + fulfill(opt_value); + }; + + /** + * Rejects this promise with the given reason. It is safe to call this as a + * normal function (with no bound "this"). + * @param {*=} opt_reason The rejection reason. + */ + this.reject = function(opt_reason) { + checkNotSelf(opt_reason); + reject(opt_reason); + }; + } + + /** @override */ + isPending() { + return this.promise.isPending(); + } + + /** @override */ + cancel(opt_reason) { + this.promise.cancel(opt_reason); + } + + /** + * @override + * @deprecated Use {@code then} from the promise property directly. + */ + then(opt_cb, opt_eb) { + return this.promise.then(opt_cb, opt_eb); + } + + /** + * @override + * @deprecated Use {@lcode catch} from the promise property directly. + */ + catch(opt_eb) { + return this.promise.catch(opt_eb); + } + + /** + * @override + * @deprecated Use {@code thenCatch} from the promise property directly. + */ + thenCatch(opt_eb) { + return this.promise.thenCatch(opt_eb); + } + + /** + * @override + * @deprecated Use {@code thenFinally} from the promise property directly. + */ + thenFinally(opt_cb) { + return this.promise.thenFinally(opt_cb); + } +} +Thenable.addImplementation(Deferred); + + +/** + * Tests if a value is an Error-like object. This is more than an straight + * instanceof check since the value may originate from another context. + * @param {*} value The value to test. + * @return {boolean} Whether the value is an error. + */ +function isError(value) { + return value instanceof Error || + (!!value && typeof value === 'object' + && typeof value.message === 'string'); +} + + +/** + * Determines whether a {@code value} should be treated as a promise. + * Any object whose "then" property is a function will be considered a promise. + * + * @param {?} value The value to test. + * @return {boolean} Whether the value is a promise. + */ +function isPromise(value) { + try { + // Use array notation so the Closure compiler does not obfuscate away our + // contract. + return value + && (typeof value === 'object' || typeof value === 'function') + && typeof value['then'] === 'function'; + } catch (ex) { + return false; + } +} + + +/** + * Creates a promise that will be resolved at a set time in the future. + * @param {number} ms The amount of time, in milliseconds, to wait before + * resolving the promise. + * @return {!ManagedPromise} The promise. + */ +function delayed(ms) { + var key; + return new ManagedPromise(function(fulfill) { + key = setTimeout(function() { + key = null; + fulfill(); + }, ms); + }).catch(function(e) { + clearTimeout(key); + key = null; + throw e; + }); +} + + +/** + * Creates a new deferred object. + * @return {!Deferred} The new deferred object. + * @template T + */ +function defer() { + return new Deferred(); +} + + +/** + * Creates a promise that has been resolved with the given value. + * @param {T=} opt_value The resolved value. + * @return {!ManagedPromise} The resolved promise. + * @template T + */ +function fulfilled(opt_value) { + if (opt_value instanceof ManagedPromise) { + return opt_value; + } + return new ManagedPromise(function(fulfill) { + fulfill(opt_value); + }); +} + + +/** + * Creates a promise that has been rejected with the given reason. + * @param {*=} opt_reason The rejection reason; may be any value, but is + * usually an Error or a string. + * @return {!ManagedPromise} The rejected promise. + * @template T + */ +function rejected(opt_reason) { + if (opt_reason instanceof ManagedPromise) { + return opt_reason; + } + return new ManagedPromise(function(_, reject) { + reject(opt_reason); + }); +} + + +/** + * Wraps a function that expects a node-style callback as its final + * argument. This callback expects two arguments: an error value (which will be + * null if the call succeeded), and the success value as the second argument. + * The callback will the resolve or reject the returned promise, based on its + * arguments. + * @param {!Function} fn The function to wrap. + * @param {...?} var_args The arguments to apply to the function, excluding the + * final callback. + * @return {!ManagedPromise} A promise that will be resolved with the + * result of the provided function's callback. + */ +function checkedNodeCall(fn, var_args) { + let args = Array.prototype.slice.call(arguments, 1); + return new ManagedPromise(function(fulfill, reject) { + try { + args.push(function(error, value) { + error ? reject(error) : fulfill(value); + }); + fn.apply(undefined, args); + } catch (ex) { + reject(ex); + } + }); +} + + +/** + * Registers an observer on a promised {@code value}, returning a new promise + * that will be resolved when the value is. If {@code value} is not a promise, + * then the return promise will be immediately resolved. + * @param {*} value The value to observe. + * @param {Function=} opt_callback The function to call when the value is + * resolved successfully. + * @param {Function=} opt_errback The function to call when the value is + * rejected. + * @return {!ManagedPromise} A new promise. + */ +function when(value, opt_callback, opt_errback) { + if (Thenable.isImplementation(value)) { + return value.then(opt_callback, opt_errback); + } + + return new ManagedPromise(function(fulfill) { + fulfill(value); + }).then(opt_callback, opt_errback); +} + + +/** + * Invokes the appropriate callback function as soon as a promised `value` is + * resolved. This function is similar to `when()`, except it does not return + * a new promise. + * @param {*} value The value to observe. + * @param {Function} callback The function to call when the value is + * resolved successfully. + * @param {Function=} opt_errback The function to call when the value is + * rejected. + */ +function asap(value, callback, opt_errback) { + if (isPromise(value)) { + value.then(callback, opt_errback); + + } else if (callback) { + callback(value); + } +} + + +/** + * Given an array of promises, will return a promise that will be fulfilled + * with the fulfillment values of the input array's values. If any of the + * input array's promises are rejected, the returned promise will be rejected + * with the same reason. + * + * @param {!Array<(T|!ManagedPromise)>} arr An array of + * promises to wait on. + * @return {!ManagedPromise>} A promise that is + * fulfilled with an array containing the fulfilled values of the + * input array, or rejected with the same reason as the first + * rejected value. + * @template T + */ +function all(arr) { + return new ManagedPromise(function(fulfill, reject) { + var n = arr.length; + var values = []; + + if (!n) { + fulfill(values); + return; + } + + var toFulfill = n; + var onFulfilled = function(index, value) { + values[index] = value; + toFulfill--; + if (toFulfill == 0) { + fulfill(values); + } + }; + + function processPromise(index) { + asap(arr[index], function(value) { + onFulfilled(index, value); + }, reject); + } + + for (var i = 0; i < n; ++i) { + processPromise(i); + } + }); +} + + +/** + * Calls a function for each element in an array and inserts the result into a + * new array, which is used as the fulfillment value of the promise returned + * by this function. + * + * If the return value of the mapping function is a promise, this function + * will wait for it to be fulfilled before inserting it into the new array. + * + * If the mapping function throws or returns a rejected promise, the + * promise returned by this function will be rejected with the same reason. + * Only the first failure will be reported; all subsequent errors will be + * silently ignored. + * + * @param {!(Array|ManagedPromise>)} arr The + * array to iterator over, or a promise that will resolve to said array. + * @param {function(this: SELF, TYPE, number, !Array): ?} fn The + * function to call for each element in the array. This function should + * expect three arguments (the element, the index, and the array itself. + * @param {SELF=} opt_self The object to be used as the value of 'this' within + * {@code fn}. + * @template TYPE, SELF + */ +function map(arr, fn, opt_self) { + return fulfilled(arr).then(function(v) { + if (!Array.isArray(v)) { + throw TypeError('not an array'); + } + var arr = /** @type {!Array} */(v); + return new ManagedPromise(function(fulfill, reject) { + var n = arr.length; + var values = new Array(n); + (function processNext(i) { + for (; i < n; i++) { + if (i in arr) { + break; + } + } + if (i >= n) { + fulfill(values); + return; + } + try { + asap( + fn.call(opt_self, arr[i], i, /** @type {!Array} */(arr)), + function(value) { + values[i] = value; + processNext(i + 1); + }, + reject); + } catch (ex) { + reject(ex); + } + })(0); + }); + }); +} + + +/** + * Calls a function for each element in an array, and if the function returns + * true adds the element to a new array. + * + * If the return value of the filter function is a promise, this function + * will wait for it to be fulfilled before determining whether to insert the + * element into the new array. + * + * If the filter function throws or returns a rejected promise, the promise + * returned by this function will be rejected with the same reason. Only the + * first failure will be reported; all subsequent errors will be silently + * ignored. + * + * @param {!(Array|ManagedPromise>)} arr The + * array to iterator over, or a promise that will resolve to said array. + * @param {function(this: SELF, TYPE, number, !Array): ( + * boolean|ManagedPromise)} fn The function + * to call for each element in the array. + * @param {SELF=} opt_self The object to be used as the value of 'this' within + * {@code fn}. + * @template TYPE, SELF + */ +function filter(arr, fn, opt_self) { + return fulfilled(arr).then(function(v) { + if (!Array.isArray(v)) { + throw TypeError('not an array'); + } + var arr = /** @type {!Array} */(v); + return new ManagedPromise(function(fulfill, reject) { + var n = arr.length; + var values = []; + var valuesLength = 0; + (function processNext(i) { + for (; i < n; i++) { + if (i in arr) { + break; + } + } + if (i >= n) { + fulfill(values); + return; + } + try { + var value = arr[i]; + var include = fn.call(opt_self, value, i, /** @type {!Array} */(arr)); + asap(include, function(include) { + if (include) { + values[valuesLength++] = value; + } + processNext(i + 1); + }, reject); + } catch (ex) { + reject(ex); + } + })(0); + }); + }); +} + + +/** + * Returns a promise that will be resolved with the input value in a + * fully-resolved state. If the value is an array, each element will be fully + * resolved. Likewise, if the value is an object, all keys will be fully + * resolved. In both cases, all nested arrays and objects will also be + * fully resolved. All fields are resolved in place; the returned promise will + * resolve on {@code value} and not a copy. + * + * Warning: This function makes no checks against objects that contain + * cyclical references: + * + * var value = {}; + * value['self'] = value; + * promise.fullyResolved(value); // Stack overflow. + * + * @param {*} value The value to fully resolve. + * @return {!ManagedPromise} A promise for a fully resolved version + * of the input value. + */ +function fullyResolved(value) { + if (isPromise(value)) { + return when(value, fullyResolveValue); + } + return fullyResolveValue(value); +} + + +/** + * @param {*} value The value to fully resolve. If a promise, assumed to + * already be resolved. + * @return {!ManagedPromise} A promise for a fully resolved version + * of the input value. + */ +function fullyResolveValue(value) { + if (Array.isArray(value)) { + return fullyResolveKeys(/** @type {!Array} */ (value)); + } + + if (isPromise(value)) { + if (isPromise(value)) { + // We get here when the original input value is a promise that + // resolves to itself. When the user provides us with such a promise, + // trust that it counts as a "fully resolved" value and return it. + // Of course, since it's already a promise, we can just return it + // to the user instead of wrapping it in another promise. + return /** @type {!ManagedPromise} */ (value); + } + } + + if (value && typeof value === 'object') { + return fullyResolveKeys(/** @type {!Object} */ (value)); + } + + if (typeof value === 'function') { + return fullyResolveKeys(/** @type {!Object} */ (value)); + } + + return fulfilled(value); +} + + +/** + * @param {!(Array|Object)} obj the object to resolve. + * @return {!ManagedPromise} A promise that will be resolved with the + * input object once all of its values have been fully resolved. + */ +function fullyResolveKeys(obj) { + var isArray = Array.isArray(obj); + var numKeys = isArray ? obj.length : (function() { + let n = 0; + for (let key in obj) { + n += 1; + } + return n; + })(); + if (!numKeys) { + return fulfilled(obj); + } + + function forEachProperty(obj, fn) { + for (let key in obj) { + fn.call(null, obj[key], key, obj); + } + } + + function forEachElement(arr, fn) { + arr.forEach(fn); + } + + var numResolved = 0; + return new ManagedPromise(function(fulfill, reject) { + var forEachKey = isArray ? forEachElement: forEachProperty; + + forEachKey(obj, function(partialValue, key) { + if (!Array.isArray(partialValue) + && (!partialValue || typeof partialValue !== 'object')) { + maybeResolveValue(); + return; + } + + fullyResolved(partialValue).then( + function(resolvedValue) { + obj[key] = resolvedValue; + maybeResolveValue(); + }, + reject); + }); + + function maybeResolveValue() { + if (++numResolved == numKeys) { + fulfill(obj); + } + } + }); +} + + +////////////////////////////////////////////////////////////////////////////// +// +// ControlFlow +// +////////////////////////////////////////////////////////////////////////////// + + + +/** + * Handles the execution of scheduled tasks, each of which may be an + * asynchronous operation. The control flow will ensure tasks are executed in + * the ordered scheduled, starting each task only once those before it have + * completed. + * + * Each task scheduled within this flow may return a {@link ManagedPromise} to + * indicate it is an asynchronous operation. The ControlFlow will wait for such + * promises to be resolved before marking the task as completed. + * + * Tasks and each callback registered on a {@link ManagedPromise} will be run + * in their own ControlFlow frame. Any tasks scheduled within a frame will take + * priority over previously scheduled tasks. Furthermore, if any of the tasks in + * the frame fail, the remainder of the tasks in that frame will be discarded + * and the failure will be propagated to the user through the callback/task's + * promised result. + * + * Each time a ControlFlow empties its task queue, it will fire an + * {@link ControlFlow.EventType.IDLE IDLE} event. Conversely, + * whenever the flow terminates due to an unhandled error, it will remove all + * remaining tasks in its queue and fire an + * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION UNCAUGHT_EXCEPTION} event. + * If there are no listeners registered with the flow, the error will be + * rethrown to the global error handler. + * + * Refer to the {@link ./promise} module documentation fora detailed + * explanation of how the ControlFlow coordinates task execution. + * + * @final + */ +class ControlFlow extends events.EventEmitter { + constructor() { + super(); + + /** @private {boolean} */ + this.propagateUnhandledRejections_ = true; + + /** @private {TaskQueue} */ + this.activeQueue_ = null; + + /** @private {Set} */ + this.taskQueues_ = null; + + /** + * Micro task that controls shutting down the control flow. Upon shut down, + * the flow will emit an + * {@link ControlFlow.EventType.IDLE} event. Idle events + * always follow a brief timeout in order to catch latent errors from the + * last completed task. If this task had a callback registered, but no + * errback, and the task fails, the unhandled failure would not be reported + * by the promise system until the next turn of the event loop: + * + * // Schedule 1 task that fails. + * var result = promise.controlFlow().schedule('example', + * function() { return promise.rejected('failed'); }); + * // Set a callback on the result. This delays reporting the unhandled + * // failure for 1 turn of the event loop. + * result.then(function() {}); + * + * @private {MicroTask} + */ + this.shutdownTask_ = null; + + /** + * ID for a long running interval used to keep a Node.js process running + * while a control flow's event loop is still working. This is a cheap hack + * required since JS events are only scheduled to run when there is + * _actually_ something to run. When a control flow is waiting on a task, + * there will be nothing in the JS event loop and the process would + * terminate without this. + * @private + */ + this.hold_ = null; + } + + /** + * Returns a string representation of this control flow, which is its current + * {@linkplain #getSchedule() schedule}, sans task stack traces. + * @return {string} The string representation of this contorl flow. + * @override + */ + toString() { + return this.getSchedule(); + } + + /** + * Sets whether any unhandled rejections should propagate up through the + * control flow stack and cause rejections within parent tasks. If error + * propagation is disabled, tasks will not be aborted when an unhandled + * promise rejection is detected, but the rejection _will_ trigger an + * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION} + * event. + * + * The default behavior is to propagate all unhandled rejections. _The use + * of this option is highly discouraged._ + * + * @param {boolean} propagate whether to propagate errors. + */ + setPropagateUnhandledRejections(propagate) { + this.propagateUnhandledRejections_ = propagate; + } + + /** + * @return {boolean} Whether this flow is currently idle. + */ + isIdle() { + return !this.shutdownTask_ && (!this.taskQueues_ || !this.taskQueues_.size); + } + + /** + * Resets this instance, clearing its queue and removing all event listeners. + */ + reset() { + this.cancelQueues_(new FlowResetError); + this.emit(ControlFlow.EventType.RESET); + this.removeAllListeners(); + this.cancelShutdown_(); + } + + /** + * Generates an annotated string describing the internal state of this control + * flow, including the currently executing as well as pending tasks. If + * {@code opt_includeStackTraces === true}, the string will include the + * stack trace from when each task was scheduled. + * @param {string=} opt_includeStackTraces Whether to include the stack traces + * from when each task was scheduled. Defaults to false. + * @return {string} String representation of this flow's internal state. + */ + getSchedule(opt_includeStackTraces) { + var ret = 'ControlFlow::' + getUid(this); + var activeQueue = this.activeQueue_; + if (!this.taskQueues_ || !this.taskQueues_.size) { + return ret; + } + var childIndent = '| '; + for (var q of this.taskQueues_) { + ret += '\n' + printQ(q, childIndent); + } + return ret; + + function printQ(q, indent) { + var ret = q.toString(); + if (q === activeQueue) { + ret = '(active) ' + ret; + } + var prefix = indent + childIndent; + if (q.pending_) { + if (q.pending_.q.state_ !== TaskQueueState.FINISHED) { + ret += '\n' + prefix + '(pending) ' + q.pending_.task; + ret += '\n' + printQ(q.pending_.q, prefix + childIndent); + } else { + ret += '\n' + prefix + '(blocked) ' + q.pending_.task; + } + } + if (q.interrupts_) { + q.interrupts_.forEach((task) => { + ret += '\n' + prefix + task; + }); + } + if (q.tasks_) { + q.tasks_.forEach((task) => ret += printTask(task, '\n' + prefix)); + } + return indent + ret; + } + + function printTask(task, prefix) { + var ret = prefix + task; + if (opt_includeStackTraces && task.promise.stack_) { + ret += prefix + childIndent + + (task.promise.stack_.stack || task.promise.stack_) + .replace(/\n/g, prefix); + } + return ret; + } + } + + /** + * Returns the currently actively task queue for this flow. If there is no + * active queue, one will be created. + * @return {!TaskQueue} the currently active task queue for this flow. + * @private + */ + getActiveQueue_() { + if (this.activeQueue_) { + return this.activeQueue_; + } + + this.activeQueue_ = new TaskQueue(this); + if (!this.taskQueues_) { + this.taskQueues_ = new Set(); + } + this.taskQueues_.add(this.activeQueue_); + this.activeQueue_ + .once('end', this.onQueueEnd_, this) + .once('error', this.onQueueError_, this); + + asyncRun(() => this.activeQueue_ = null); + this.activeQueue_.start(); + return this.activeQueue_; + } + + /** + * Schedules a task for execution. If there is nothing currently in the + * queue, the task will be executed in the next turn of the event loop. If + * the task function is a generator, the task will be executed using + * {@link ./promise.consume consume()}. + * + * @param {function(): (T|ManagedPromise)} fn The function to + * call to start the task. If the function returns a + * {@link ManagedPromise}, this instance will wait for it to be + * resolved before starting the next task. + * @param {string=} opt_description A description of the task. + * @return {!ManagedPromise} A promise that will be resolved + * with the result of the action. + * @template T + */ + execute(fn, opt_description) { + if (isGenerator(fn)) { + let original = fn; + fn = () => consume(original); + } + + if (!this.hold_) { + var holdIntervalMs = 2147483647; // 2^31-1; max timer length for Node.js + this.hold_ = setInterval(function() {}, holdIntervalMs); + } + + var task = new Task( + this, fn, opt_description || '', + {name: 'Task', top: ControlFlow.prototype.execute}); + + var q = this.getActiveQueue_(); + q.enqueue(task); + this.emit(ControlFlow.EventType.SCHEDULE_TASK, task.description); + return task.promise; + } + + /** + * Inserts a {@code setTimeout} into the command queue. This is equivalent to + * a thread sleep in a synchronous programming language. + * + * @param {number} ms The timeout delay, in milliseconds. + * @param {string=} opt_description A description to accompany the timeout. + * @return {!ManagedPromise} A promise that will be resolved with + * the result of the action. + */ + timeout(ms, opt_description) { + return this.execute(function() { + return delayed(ms); + }, opt_description); + } + + /** + * Schedules a task that shall wait for a condition to hold. Each condition + * function may return any value, but it will always be evaluated as a + * boolean. + * + * Condition functions may schedule sub-tasks with this instance, however, + * their execution time will be factored into whether a wait has timed out. + * + * In the event a condition returns a ManagedPromise, the polling loop will wait for + * it to be resolved before evaluating whether the condition has been + * satisfied. The resolution time for a promise is factored into whether a + * wait has timed out. + * + * If the condition function throws, or returns a rejected promise, the + * wait task will fail. + * + * If the condition is defined as a promise, the flow will wait for it to + * settle. If the timeout expires before the promise settles, the promise + * returned by this function will be rejected. + * + * If this function is invoked with `timeout === 0`, or the timeout is + * omitted, the flow will wait indefinitely for the condition to be satisfied. + * + * @param {(!ManagedPromise|function())} condition The condition to poll, + * or a promise to wait on. + * @param {number=} opt_timeout How long to wait, in milliseconds, for the + * condition to hold before timing out. If omitted, the flow will wait + * indefinitely. + * @param {string=} opt_message An optional error message to include if the + * wait times out; defaults to the empty string. + * @return {!ManagedPromise} A promise that will be fulfilled + * when the condition has been satisified. The promise shall be rejected + * if the wait times out waiting for the condition. + * @throws {TypeError} If condition is not a function or promise or if timeout + * is not a number >= 0. + * @template T + */ + wait(condition, opt_timeout, opt_message) { + var timeout = opt_timeout || 0; + if (typeof timeout !== 'number' || timeout < 0) { + throw TypeError('timeout must be a number >= 0: ' + timeout); + } + + if (isPromise(condition)) { + return this.execute(function() { + if (!timeout) { + return condition; + } + return new ManagedPromise(function(fulfill, reject) { + var start = Date.now(); + var timer = setTimeout(function() { + timer = null; + reject(Error((opt_message ? opt_message + '\n' : '') + + 'Timed out waiting for promise to resolve after ' + + (Date.now() - start) + 'ms')); + }, timeout); + + /** @type {Thenable} */(condition).then( + function(value) { + timer && clearTimeout(timer); + fulfill(value); + }, + function(error) { + timer && clearTimeout(timer); + reject(error); + }); + }); + }, opt_message || ''); + } + + if (typeof condition !== 'function') { + throw TypeError('Invalid condition; must be a function or promise: ' + + typeof condition); + } + + if (isGenerator(condition)) { + let original = condition; + condition = () => consume(original); + } + + var self = this; + return this.execute(function() { + var startTime = Date.now(); + return new ManagedPromise(function(fulfill, reject) { + pollCondition(); + + function pollCondition() { + var conditionFn = /** @type {function()} */(condition); + self.execute(conditionFn).then(function(value) { + var elapsed = Date.now() - startTime; + if (!!value) { + fulfill(value); + } else if (timeout && elapsed >= timeout) { + reject(new Error((opt_message ? opt_message + '\n' : '') + + 'Wait timed out after ' + elapsed + 'ms')); + } else { + // Do not use asyncRun here because we need a non-micro yield + // here so the UI thread is given a chance when running in a + // browser. + setTimeout(pollCondition, 0); + } + }, reject); + } + }); + }, opt_message || ''); + } + + /** + * Executes a function in the next available turn of the JavaScript event + * loop. This ensures the function runs with its own task queue and any + * scheduled tasks will run in "parallel" to those scheduled in the current + * function. + * + * flow.execute(() => console.log('a')); + * flow.execute(() => console.log('b')); + * flow.execute(() => console.log('c')); + * flow.async(() => { + * flow.execute(() => console.log('d')); + * flow.execute(() => console.log('e')); + * }); + * flow.async(() => { + * flow.execute(() => console.log('f')); + * flow.execute(() => console.log('g')); + * }); + * flow.once('idle', () => console.log('fin')); + * // a + * // d + * // f + * // b + * // e + * // g + * // c + * // fin + * + * If the function itself throws, the error will be treated the same as an + * unhandled rejection within the control flow. + * + * __NOTE__: This function is considered _unstable_. + * + * @param {!Function} fn The function to execute. + * @param {Object=} opt_self The object in whose context to run the function. + * @param {...*} var_args Any arguments to pass to the function. + */ + async(fn, opt_self, var_args) { + asyncRun(() => { + // Clear any lingering queues, forces getActiveQueue_ to create a new one. + this.activeQueue_ = null; + var q = this.getActiveQueue_(); + try { + q.execute_(fn.bind(opt_self, var_args)); + } catch (ex) { + var cancellationError = CancellationError.wrap(ex, + 'Function passed to ControlFlow.async() threw'); + cancellationError.silent_ = true; + q.abort_(cancellationError); + } finally { + this.activeQueue_ = null; + } + }); + } + + /** + * Event handler for when a task queue is exhausted. This starts the shutdown + * sequence for this instance if there are no remaining task queues: after + * one turn of the event loop, this object will emit the + * {@link ControlFlow.EventType.IDLE IDLE} event to signal + * listeners that it has completed. During this wait, if another task is + * scheduled, the shutdown will be aborted. + * + * @param {!TaskQueue} q the completed task queue. + * @private + */ + onQueueEnd_(q) { + if (!this.taskQueues_) { + return; + } + this.taskQueues_.delete(q); + + vlog(1, () => q + ' has finished'); + vlog(1, () => this.taskQueues_.size + ' queues remain\n' + this, this); + + if (!this.taskQueues_.size) { + if (this.shutdownTask_) { + throw Error('Already have a shutdown task??'); + } + vlog(1, () => 'Scheduling shutdown\n' + this); + this.shutdownTask_ = new MicroTask(() => this.shutdown_()); + } + } + + /** + * Event handler for when a task queue terminates with an error. This triggers + * the cancellation of all other task queues and a + * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION} event. + * If there are no error event listeners registered with this instance, the + * error will be rethrown to the global error handler. + * + * @param {*} error the error that caused the task queue to terminate. + * @param {!TaskQueue} q the task queue. + * @private + */ + onQueueError_(error, q) { + if (this.taskQueues_) { + this.taskQueues_.delete(q); + } + this.cancelQueues_(CancellationError.wrap( + error, 'There was an uncaught error in the control flow')); + this.cancelShutdown_(); + this.cancelHold_(); + + var listeners = this.listeners( + ControlFlow.EventType.UNCAUGHT_EXCEPTION); + if (!listeners.size) { + asyncThrow(/** @type {!Error} */(error)); + } else { + this.reportUncaughtException_(error); + } + } + + /** + * Cancels all remaining task queues. + * @param {!CancellationError} reason The cancellation reason. + * @private + */ + cancelQueues_(reason) { + reason.silent_ = true; + if (this.taskQueues_) { + for (var q of this.taskQueues_) { + q.removeAllListeners(); + q.abort_(reason); + } + this.taskQueues_.clear(); + this.taskQueues_ = null; + } + } + + /** + * Reports an uncaught exception using a + * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION} event. + * + * @param {*} e the error to report. + * @private + */ + reportUncaughtException_(e) { + this.emit(ControlFlow.EventType.UNCAUGHT_EXCEPTION, e); + } + + /** @private */ + cancelHold_() { + if (this.hold_) { + clearInterval(this.hold_); + this.hold_ = null; + } + } + + /** @private */ + shutdown_() { + vlog(1, () => 'Going idle: ' + this); + this.cancelHold_(); + this.shutdownTask_ = null; + this.emit(ControlFlow.EventType.IDLE); + } + + /** + * Cancels the shutdown sequence if it is currently scheduled. + * @private + */ + cancelShutdown_() { + if (this.shutdownTask_) { + this.shutdownTask_.cancel(); + this.shutdownTask_ = null; + } + } +} + + +/** + * Events that may be emitted by an {@link ControlFlow}. + * @enum {string} + */ +ControlFlow.EventType = { + + /** Emitted when all tasks have been successfully executed. */ + IDLE: 'idle', + + /** Emitted when a ControlFlow has been reset. */ + RESET: 'reset', + + /** Emitted whenever a new task has been scheduled. */ + SCHEDULE_TASK: 'scheduleTask', + + /** + * Emitted whenever a control flow aborts due to an unhandled promise + * rejection. This event will be emitted along with the offending rejection + * reason. Upon emitting this event, the control flow will empty its task + * queue and revert to its initial state. + */ + UNCAUGHT_EXCEPTION: 'uncaughtException' +}; + + +/** + * Wraps a function to execute as a cancellable micro task. + * @final + */ +class MicroTask { + /** + * @param {function()} fn The function to run as a micro task. + */ + constructor(fn) { + /** @private {boolean} */ + this.cancelled_ = false; + asyncRun(() => { + if (!this.cancelled_) { + fn(); + } + }); + } + + /** + * Runs the given function after a micro-task yield. + * @param {function()} fn The function to run. + */ + static run(fn) { + NativePromise.resolve().then(function() { + try { + fn(); + } catch (ignored) { + // Do nothing. + } + }); + } + + /** + * Cancels the execution of this task. Note: this will not prevent the task + * timer from firing, just the invocation of the wrapped function. + */ + cancel() { + this.cancelled_ = true; + } +} + + +/** + * A task to be executed by a {@link ControlFlow}. + * + * @template T + * @final + */ +class Task extends Deferred { + /** + * @param {!ControlFlow} flow The flow this instances belongs + * to. + * @param {function(): (T|!ManagedPromise)} fn The function to + * call when the task executes. If it returns a + * {@link ManagedPromise}, the flow will wait for it to be + * resolved before starting the next task. + * @param {string} description A description of the task for debugging. + * @param {{name: string, top: !Function}=} opt_stackOptions Options to use + * when capturing the stacktrace for when this task was created. + */ + constructor(flow, fn, description, opt_stackOptions) { + super(flow); + getUid(this); + + /** @type {function(): (T|!ManagedPromise)} */ + this.execute = fn; + + /** @type {string} */ + this.description = description; + + /** @type {TaskQueue} */ + this.queue = null; + + /** + * Whether this task is considered block. A blocked task may be registered + * in a task queue, but will be dropped if it is still blocked when it + * reaches the front of the queue. A dropped task may always be rescheduled. + * + * Blocked tasks are used when a callback is attached to an unsettled + * promise to reserve a spot in line (in a manner of speaking). If the + * promise is not settled before the callback reaches the front of the + * of the queue, it will be dropped. Once the promise is settled, the + * dropped task will be rescheduled as an interrupt on the currently task + * queue. + * + * @type {boolean} + */ + this.blocked = false; + + if (opt_stackOptions) { + this.promise.stack_ = captureStackTrace( + opt_stackOptions.name, this.description, opt_stackOptions.top); + } + } + + /** @override */ + toString() { + return 'Task::' + getUid(this) + '<' + this.description + '>'; + } +} + + +/** @enum {string} */ +const TaskQueueState = { + NEW: 'new', + STARTED: 'started', + FINISHED: 'finished' +}; + + +/** + * @final + */ +class TaskQueue extends events.EventEmitter { + /** @param {!ControlFlow} flow . */ + constructor(flow) { + super(); + + /** @private {string} */ + this.name_ = 'TaskQueue::' + getUid(this); + + /** @private {!ControlFlow} */ + this.flow_ = flow; + + /** @private {!Array} */ + this.tasks_ = []; + + /** @private {Array} */ + this.interrupts_ = null; + + /** @private {({task: !Task, q: !TaskQueue}|null)} */ + this.pending_ = null; + + /** @private {TaskQueueState} */ + this.state_ = TaskQueueState.NEW; + + /** @private {!Set} */ + this.unhandledRejections_ = new Set(); + } + + /** @override */ + toString() { + return 'TaskQueue::' + getUid(this); + } + + /** + * @param {!ManagedPromise} promise . + */ + addUnhandledRejection(promise) { + // TODO: node 4.0.0+ + vlog(2, () => this + ' registering unhandled rejection: ' + promise, this); + this.unhandledRejections_.add(promise); + } + + /** + * @param {!ManagedPromise} promise . + */ + clearUnhandledRejection(promise) { + var deleted = this.unhandledRejections_.delete(promise); + if (deleted) { + // TODO: node 4.0.0+ + vlog(2, () => this + ' clearing unhandled rejection: ' + promise, this); + } + } + + /** + * Enqueues a new task for execution. + * @param {!Task} task The task to enqueue. + * @throws {Error} If this instance has already started execution. + */ + enqueue(task) { + if (this.state_ !== TaskQueueState.NEW) { + throw Error('TaskQueue has started: ' + this); + } + + if (task.queue) { + throw Error('Task is already scheduled in another queue'); + } + + this.tasks_.push(task); + task.queue = this; + task.promise[CANCEL_HANDLER_SYMBOL] = + this.onTaskCancelled_.bind(this, task); + + vlog(1, () => this + '.enqueue(' + task + ')', this); + vlog(2, () => this.flow_.toString(), this); + } + + /** + * Schedules the callbacks registered on the given promise in this queue. + * + * @param {!ManagedPromise} promise the promise whose callbacks should be + * registered as interrupts in this task queue. + * @throws {Error} if this queue has already finished. + */ + scheduleCallbacks(promise) { + if (this.state_ === TaskQueueState.FINISHED) { + throw new Error('cannot interrupt a finished q(' + this + ')'); + } + + if (this.pending_ && this.pending_.task.promise === promise) { + this.pending_.task.promise.queue_ = null; + this.pending_ = null; + asyncRun(() => this.executeNext_()); + } + + if (!promise.callbacks_) { + return; + } + promise.callbacks_.forEach(function(cb) { + cb.blocked = false; + if (cb.queue) { + return; + } + + cb.promise[CANCEL_HANDLER_SYMBOL] = this.onTaskCancelled_.bind(this, cb); + + if (cb.queue === this && this.tasks_.indexOf(cb) !== -1) { + return; + } + + if (cb.queue) { + cb.queue.dropTask_(cb); + } + + cb.queue = this; + if (!this.interrupts_) { + this.interrupts_ = []; + } + this.interrupts_.push(cb); + }, this); + promise.callbacks_ = null; + vlog(2, () => this + ' interrupted\n' + this.flow_, this); + } + + /** + * Starts executing tasks in this queue. Once called, no further tasks may + * be {@linkplain #enqueue() enqueued} with this instance. + * + * @throws {Error} if this queue has already been started. + */ + start() { + if (this.state_ !== TaskQueueState.NEW) { + throw new Error('TaskQueue has already started'); + } + // Always asynchronously execute next, even if there doesn't look like + // there is anything in the queue. This will catch pending unhandled + // rejections that were registered before start was called. + asyncRun(() => this.executeNext_()); + } + + /** + * Aborts this task queue. If there are any scheduled tasks, they are silently + * cancelled and discarded (their callbacks will never fire). If this queue + * has a _pending_ task, the abortion error is used to cancel that task. + * Otherwise, this queue will emit an error event. + * + * @param {*} error The abortion reason. + * @private + */ + abort_(error) { + var cancellation; + + if (error instanceof FlowResetError) { + cancellation = error; + } else { + cancellation = new DiscardedTaskError(error); + } + + if (this.interrupts_ && this.interrupts_.length) { + this.interrupts_.forEach((t) => t.reject(cancellation)); + this.interrupts_ = []; + } + + if (this.tasks_ && this.tasks_.length) { + this.tasks_.forEach((t) => t.reject(cancellation)); + this.tasks_ = []; + } + + if (this.pending_) { + vlog(2, () => this + '.abort(); cancelling pending task', this); + this.pending_.task.cancel(/** @type {!CancellationError} */(error)); + + } else { + vlog(2, () => this + '.abort(); emitting error event', this); + this.emit('error', error, this); + } + } + + /** @private */ + executeNext_() { + if (this.state_ === TaskQueueState.FINISHED) { + return; + } + this.state_ = TaskQueueState.STARTED; + + if (this.pending_ != null || this.processUnhandledRejections_()) { + return; + } + + var task; + do { + task = this.getNextTask_(); + } while (task && !task.promise.isPending()); + + if (!task) { + this.state_ = TaskQueueState.FINISHED; + this.tasks_ = []; + this.interrupts_ = null; + vlog(2, () => this + '.emit(end)', this); + this.emit('end', this); + return; + } + + var self = this; + var subQ = new TaskQueue(this.flow_); + subQ.once('end', () => self.onTaskComplete_(result)) + .once('error', (e) => self.onTaskFailure_(result, e)); + vlog(2, () => self + ' created ' + subQ + ' for ' + task); + + var result = undefined; + try { + this.pending_ = {task: task, q: subQ}; + task.promise.queue_ = this; + result = subQ.execute_(task.execute); + subQ.start(); + } catch (ex) { + subQ.abort_(ex); + } + } + + /** + * @param {!Function} fn . + * @return {T} . + * @template T + * @private + */ + execute_(fn) { + try { + activeFlows.push(this.flow_); + this.flow_.activeQueue_ = this; + return fn(); + } finally { + this.flow_.activeQueue_ = null; + activeFlows.pop(); + } + } + + /** + * Process any unhandled rejections registered with this task queue. If there + * is a rejection, this queue will be aborted with the rejection error. If + * there are multiple rejections registered, this queue will be aborted with + * a {@link MultipleUnhandledRejectionError}. + * @return {boolean} whether there was an unhandled rejection. + * @private + */ + processUnhandledRejections_() { + if (!this.unhandledRejections_.size) { + return false; + } + + var errors = new Set(); + for (var rejection of this.unhandledRejections_) { + errors.add(rejection.value_); + } + this.unhandledRejections_.clear(); + + var errorToReport = errors.size === 1 + ? errors.values().next().value + : new MultipleUnhandledRejectionError(errors); + + vlog(1, () => this + ' aborting due to unhandled rejections', this); + if (this.flow_.propagateUnhandledRejections_) { + this.abort_(errorToReport); + return true; + } else { + vlog(1, 'error propagation disabled; reporting to control flow'); + this.flow_.reportUncaughtException_(errorToReport); + return false; + } + } + + /** + * @param {!Task} task The task to drop. + * @private + */ + dropTask_(task) { + var index; + if (this.interrupts_) { + index = this.interrupts_.indexOf(task); + if (index != -1) { + task.queue = null; + this.interrupts_.splice(index, 1); + return; + } + } + + index = this.tasks_.indexOf(task); + if (index != -1) { + task.queue = null; + this.tasks_.splice(index, 1); + } + } + + /** + * @param {!Task} task The task that was cancelled. + * @param {!CancellationError} reason The cancellation reason. + * @private + */ + onTaskCancelled_(task, reason) { + if (this.pending_ && this.pending_.task === task) { + this.pending_.q.abort_(reason); + } else { + this.dropTask_(task); + } + } + + /** + * @param {*} value the value originally returned by the task function. + * @private + */ + onTaskComplete_(value) { + if (this.pending_) { + this.pending_.task.fulfill(value); + } + } + + /** + * @param {*} taskFnResult the value originally returned by the task function. + * @param {*} error the error that caused the task function to terminate. + * @private + */ + onTaskFailure_(taskFnResult, error) { + if (Thenable.isImplementation(taskFnResult)) { + taskFnResult.cancel(CancellationError.wrap(error)); + } + this.pending_.task.reject(error); + } + + /** + * @return {(Task|undefined)} the next task scheduled within this queue, + * if any. + * @private + */ + getNextTask_() { + var task = undefined; + while (true) { + if (this.interrupts_) { + task = this.interrupts_.shift(); + } + if (!task && this.tasks_) { + task = this.tasks_.shift(); + } + if (task && task.blocked) { + vlog(2, () => this + ' skipping blocked task ' + task, this); + task.queue = null; + task = null; + // TODO: recurse when tail-call optimization is available in node. + } else { + break; + } + } + return task; + } +}; + + + +/** + * The default flow to use if no others are active. + * @type {!ControlFlow} + */ +var defaultFlow = new ControlFlow(); + + +/** + * A stack of active control flows, with the top of the stack used to schedule + * commands. When there are multiple flows on the stack, the flow at index N + * represents a callback triggered within a task owned by the flow at index + * N-1. + * @type {!Array} + */ +var activeFlows = []; + + +/** + * Changes the default flow to use when no others are active. + * @param {!ControlFlow} flow The new default flow. + * @throws {Error} If the default flow is not currently active. + */ +function setDefaultFlow(flow) { + if (activeFlows.length) { + throw Error('You may only change the default flow while it is active'); + } + defaultFlow = flow; +} + + +/** + * @return {!ControlFlow} The currently active control flow. + */ +function controlFlow() { + return /** @type {!ControlFlow} */ ( + activeFlows.length ? activeFlows[activeFlows.length - 1] : defaultFlow); +} + + +/** + * Creates a new control flow. The provided callback will be invoked as the + * first task within the new flow, with the flow as its sole argument. Returns + * a promise that resolves to the callback result. + * @param {function(!ControlFlow)} callback The entry point + * to the newly created flow. + * @return {!ManagedPromise} A promise that resolves to the callback + * result. + */ +function createFlow(callback) { + var flow = new ControlFlow; + return flow.execute(function() { + return callback(flow); + }); +} + + +/** + * Tests is a function is a generator. + * @param {!Function} fn The function to test. + * @return {boolean} Whether the function is a generator. + */ +function isGenerator(fn) { + return fn.constructor.name === 'GeneratorFunction'; +} + + +/** + * Consumes a {@code GeneratorFunction}. Each time the generator yields a + * promise, this function will wait for it to be fulfilled before feeding the + * fulfilled value back into {@code next}. Likewise, if a yielded promise is + * rejected, the rejection error will be passed to {@code throw}. + * + * __Example 1:__ the Fibonacci Sequence. + * + * promise.consume(function* fibonacci() { + * var n1 = 1, n2 = 1; + * for (var i = 0; i < 4; ++i) { + * var tmp = yield n1 + n2; + * n1 = n2; + * n2 = tmp; + * } + * return n1 + n2; + * }).then(function(result) { + * console.log(result); // 13 + * }); + * + * __Example 2:__ a generator that throws. + * + * promise.consume(function* () { + * yield promise.delayed(250).then(function() { + * throw Error('boom'); + * }); + * }).catch(function(e) { + * console.log(e.toString()); // Error: boom + * }); + * + * @param {!Function} generatorFn The generator function to execute. + * @param {Object=} opt_self The object to use as "this" when invoking the + * initial generator. + * @param {...*} var_args Any arguments to pass to the initial generator. + * @return {!ManagedPromise} A promise that will resolve to the + * generator's final result. + * @throws {TypeError} If the given function is not a generator. + */ +function consume(generatorFn, opt_self, var_args) { + if (!isGenerator(generatorFn)) { + throw new TypeError('Input is not a GeneratorFunction: ' + + generatorFn.constructor.name); + } + + var deferred = defer(); + var generator = generatorFn.apply( + opt_self, Array.prototype.slice.call(arguments, 2)); + callNext(); + return deferred.promise; + + /** @param {*=} opt_value . */ + function callNext(opt_value) { + pump(generator.next, opt_value); + } + + /** @param {*=} opt_error . */ + function callThrow(opt_error) { + // Dictionary lookup required because Closure compiler's built-in + // externs does not include GeneratorFunction.prototype.throw. + pump(generator['throw'], opt_error); + } + + function pump(fn, opt_arg) { + if (!deferred.isPending()) { + return; // Defererd was cancelled; silently abort. + } + + try { + var result = fn.call(generator, opt_arg); + } catch (ex) { + deferred.reject(ex); + return; + } + + if (result.done) { + deferred.fulfill(result.value); + return; + } + + asap(result.value, callNext, callThrow); + } +} + + +// PUBLIC API + + +exports.CancellationError = CancellationError; +exports.ControlFlow = ControlFlow; +exports.Deferred = Deferred; +exports.MultipleUnhandledRejectionError = MultipleUnhandledRejectionError; +exports.Thenable = Thenable; +exports.Promise = ManagedPromise; +exports.all = all; +exports.asap = asap; +exports.captureStackTrace = captureStackTrace; +exports.checkedNodeCall = checkedNodeCall; +exports.consume = consume; +exports.controlFlow = controlFlow; +exports.createFlow = createFlow; +exports.defer = defer; +exports.delayed = delayed; +exports.filter = filter; +exports.fulfilled = fulfilled; +exports.fullyResolved = fullyResolved; +exports.isGenerator = isGenerator; +exports.isPromise = isPromise; +exports.map = map; +exports.rejected = rejected; +exports.setDefaultFlow = setDefaultFlow; +exports.when = when; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/safari/client.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/safari/client.js new file mode 100644 index 0000000..b15dbd6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/safari/client.js @@ -0,0 +1,7203 @@ +'use strict';var COMPILED = !0, goog = goog || {}; +goog.global = this; +goog.isDef = function(a) { + return void 0 !== a; +}; +goog.exportPath_ = function(a, b, c) { + a = a.split("."); + c = c || goog.global; + a[0] in c || !c.execScript || c.execScript("var " + a[0]); + for (var d;a.length && (d = a.shift());) { + !a.length && goog.isDef(b) ? c[d] = b : c = c[d] ? c[d] : c[d] = {}; + } +}; +goog.define = function(a, b) { + var c = b; + COMPILED || (goog.global.CLOSURE_UNCOMPILED_DEFINES && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_UNCOMPILED_DEFINES, a) ? c = goog.global.CLOSURE_UNCOMPILED_DEFINES[a] : goog.global.CLOSURE_DEFINES && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES, a) && (c = goog.global.CLOSURE_DEFINES[a])); + goog.exportPath_(a, c); +}; +goog.DEBUG = !0; +goog.LOCALE = "en"; +goog.TRUSTED_SITE = !0; +goog.STRICT_MODE_COMPATIBLE = !1; +goog.DISALLOW_TEST_ONLY_CODE = COMPILED && !goog.DEBUG; +goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING = !1; +goog.provide = function(a) { + if (!COMPILED && goog.isProvided_(a)) { + throw Error('Namespace "' + a + '" already declared.'); + } + goog.constructNamespace_(a); +}; +goog.constructNamespace_ = function(a, b) { + if (!COMPILED) { + delete goog.implicitNamespaces_[a]; + for (var c = a;(c = c.substring(0, c.lastIndexOf("."))) && !goog.getObjectByName(c);) { + goog.implicitNamespaces_[c] = !0; + } + } + goog.exportPath_(a, b); +}; +goog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/; +goog.module = function(a) { + if (!goog.isString(a) || !a || -1 == a.search(goog.VALID_MODULE_RE_)) { + throw Error("Invalid module identifier"); + } + if (!goog.isInModuleLoader_()) { + throw Error("Module " + a + " has been loaded incorrectly."); + } + if (goog.moduleLoaderState_.moduleName) { + throw Error("goog.module may only be called once per module."); + } + goog.moduleLoaderState_.moduleName = a; + if (!COMPILED) { + if (goog.isProvided_(a)) { + throw Error('Namespace "' + a + '" already declared.'); + } + delete goog.implicitNamespaces_[a]; + } +}; +goog.module.get = function(a) { + return goog.module.getInternal_(a); +}; +goog.module.getInternal_ = function(a) { + if (!COMPILED) { + return goog.isProvided_(a) ? a in goog.loadedModules_ ? goog.loadedModules_[a] : goog.getObjectByName(a) : null; + } +}; +goog.moduleLoaderState_ = null; +goog.isInModuleLoader_ = function() { + return null != goog.moduleLoaderState_; +}; +goog.module.declareLegacyNamespace = function() { + if (!COMPILED && !goog.isInModuleLoader_()) { + throw Error("goog.module.declareLegacyNamespace must be called from within a goog.module"); + } + if (!COMPILED && !goog.moduleLoaderState_.moduleName) { + throw Error("goog.module must be called prior to goog.module.declareLegacyNamespace."); + } + goog.moduleLoaderState_.declareLegacyNamespace = !0; +}; +goog.setTestOnly = function(a) { + if (goog.DISALLOW_TEST_ONLY_CODE) { + throw a = a || "", Error("Importing test-only code into non-debug environment" + (a ? ": " + a : ".")); + } +}; +goog.forwardDeclare = function(a) { +}; +COMPILED || (goog.isProvided_ = function(a) { + return a in goog.loadedModules_ || !goog.implicitNamespaces_[a] && goog.isDefAndNotNull(goog.getObjectByName(a)); +}, goog.implicitNamespaces_ = {"goog.module":!0}); +goog.getObjectByName = function(a, b) { + for (var c = a.split("."), d = b || goog.global, e;e = c.shift();) { + if (goog.isDefAndNotNull(d[e])) { + d = d[e]; + } else { + return null; + } + } + return d; +}; +goog.globalize = function(a, b) { + var c = b || goog.global, d; + for (d in a) { + c[d] = a[d]; + } +}; +goog.addDependency = function(a, b, c, d) { + if (goog.DEPENDENCIES_ENABLED) { + var e; + a = a.replace(/\\/g, "/"); + for (var f = goog.dependencies_, g = 0;e = b[g];g++) { + f.nameToPath[e] = a, f.pathIsModule[a] = !!d; + } + for (d = 0;b = c[d];d++) { + a in f.requires || (f.requires[a] = {}), f.requires[a][b] = !0; + } + } +}; +goog.ENABLE_DEBUG_LOADER = !0; +goog.logToConsole_ = function(a) { + goog.global.console && goog.global.console.error(a); +}; +goog.require = function(a) { + if (!COMPILED) { + goog.ENABLE_DEBUG_LOADER && goog.IS_OLD_IE_ && goog.maybeProcessDeferredDep_(a); + if (goog.isProvided_(a)) { + return goog.isInModuleLoader_() ? goog.module.getInternal_(a) : null; + } + if (goog.ENABLE_DEBUG_LOADER) { + var b = goog.getPathFromDeps_(a); + if (b) { + return goog.writeScripts_(b), null; + } + } + a = "goog.require could not find: " + a; + goog.logToConsole_(a); + throw Error(a); + } +}; +goog.basePath = ""; +goog.nullFunction = function() { +}; +goog.abstractMethod = function() { + throw Error("unimplemented abstract method"); +}; +goog.addSingletonGetter = function(a) { + a.getInstance = function() { + if (a.instance_) { + return a.instance_; + } + goog.DEBUG && (goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = a); + return a.instance_ = new a; + }; +}; +goog.instantiatedSingletons_ = []; +goog.LOAD_MODULE_USING_EVAL = !0; +goog.SEAL_MODULE_EXPORTS = goog.DEBUG; +goog.loadedModules_ = {}; +goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER; +goog.DEPENDENCIES_ENABLED && (goog.dependencies_ = {pathIsModule:{}, nameToPath:{}, requires:{}, visited:{}, written:{}, deferred:{}}, goog.inHtmlDocument_ = function() { + var a = goog.global.document; + return null != a && "write" in a; +}, goog.findBasePath_ = function() { + if (goog.isDef(goog.global.CLOSURE_BASE_PATH)) { + goog.basePath = goog.global.CLOSURE_BASE_PATH; + } else { + if (goog.inHtmlDocument_()) { + for (var a = goog.global.document.getElementsByTagName("SCRIPT"), b = a.length - 1;0 <= b;--b) { + var c = a[b].src, d = c.lastIndexOf("?"), d = -1 == d ? c.length : d; + if ("base.js" == c.substr(d - 7, 7)) { + goog.basePath = c.substr(0, d - 7); + break; + } + } + } + } +}, goog.importScript_ = function(a, b) { + (goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_)(a, b) && (goog.dependencies_.written[a] = !0); +}, goog.IS_OLD_IE_ = !(goog.global.atob || !goog.global.document || !goog.global.document.all), goog.importModule_ = function(a) { + goog.importScript_("", 'goog.retrieveAndExecModule_("' + a + '");') && (goog.dependencies_.written[a] = !0); +}, goog.queuedModules_ = [], goog.wrapModule_ = function(a, b) { + return goog.LOAD_MODULE_USING_EVAL && goog.isDef(goog.global.JSON) ? "goog.loadModule(" + goog.global.JSON.stringify(b + "\n//# sourceURL=" + a + "\n") + ");" : 'goog.loadModule(function(exports) {"use strict";' + b + "\n;return exports});\n//# sourceURL=" + a + "\n"; +}, goog.loadQueuedModules_ = function() { + var a = goog.queuedModules_.length; + if (0 < a) { + var b = goog.queuedModules_; + goog.queuedModules_ = []; + for (var c = 0;c < a;c++) { + goog.maybeProcessDeferredPath_(b[c]); + } + } +}, goog.maybeProcessDeferredDep_ = function(a) { + goog.isDeferredModule_(a) && goog.allDepsAreAvailable_(a) && (a = goog.getPathFromDeps_(a), goog.maybeProcessDeferredPath_(goog.basePath + a)); +}, goog.isDeferredModule_ = function(a) { + return (a = goog.getPathFromDeps_(a)) && goog.dependencies_.pathIsModule[a] ? goog.basePath + a in goog.dependencies_.deferred : !1; +}, goog.allDepsAreAvailable_ = function(a) { + if ((a = goog.getPathFromDeps_(a)) && a in goog.dependencies_.requires) { + for (var b in goog.dependencies_.requires[a]) { + if (!goog.isProvided_(b) && !goog.isDeferredModule_(b)) { + return !1; + } + } + } + return !0; +}, goog.maybeProcessDeferredPath_ = function(a) { + if (a in goog.dependencies_.deferred) { + var b = goog.dependencies_.deferred[a]; + delete goog.dependencies_.deferred[a]; + goog.globalEval(b); + } +}, goog.loadModuleFromUrl = function(a) { + goog.retrieveAndExecModule_(a); +}, goog.loadModule = function(a) { + var b = goog.moduleLoaderState_; + try { + goog.moduleLoaderState_ = {moduleName:void 0, declareLegacyNamespace:!1}; + var c; + if (goog.isFunction(a)) { + c = a.call(goog.global, {}); + } else { + if (goog.isString(a)) { + c = goog.loadModuleFromSource_.call(goog.global, a); + } else { + throw Error("Invalid module definition"); + } + } + var d = goog.moduleLoaderState_.moduleName; + if (!goog.isString(d) || !d) { + throw Error('Invalid module name "' + d + '"'); + } + goog.moduleLoaderState_.declareLegacyNamespace ? goog.constructNamespace_(d, c) : goog.SEAL_MODULE_EXPORTS && Object.seal && Object.seal(c); + goog.loadedModules_[d] = c; + } finally { + goog.moduleLoaderState_ = b; + } +}, goog.loadModuleFromSource_ = function(a) { + eval(a); + return {}; +}, goog.writeScriptSrcNode_ = function(a) { + goog.global.document.write('")' + Response.Output.Write(""); + } +} diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx new file mode 100644 index 0000000..52d2e67 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx @@ -0,0 +1,11 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Redirect.aspx.cs" Inherits="Redirect" %> + + + + + + Untitled Page + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx.cs b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx.cs new file mode 100644 index 0000000..9e0650b --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx.cs @@ -0,0 +1,9 @@ +using System; + +public partial class Redirect : Page +{ + protected new void Page_Load(object sender, EventArgs e) + { + Response.Redirect("resultPage.html"); + } +} diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Settings.StyleCop b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Settings.StyleCop new file mode 100644 index 0000000..fc955f8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Settings.StyleCop @@ -0,0 +1,759 @@ + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Web.Config b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Web.Config new file mode 100644 index 0000000..68b648f --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/Web.Config @@ -0,0 +1,59 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/actualXhtmlPage.xhtml b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/actualXhtmlPage.xhtml new file mode 100644 index 0000000..a0f5470 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/actualXhtmlPage.xhtml @@ -0,0 +1,14 @@ + + + + + + Title + + + +

+ Foo +

+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/ajaxy_page.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/ajaxy_page.html new file mode 100644 index 0000000..4b34031 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/ajaxy_page.html @@ -0,0 +1,81 @@ + + + +
+ + +
+ + Red + Green +
+ +
+ + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/alerts.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/alerts.html new file mode 100644 index 0000000..1add0db --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/alerts.html @@ -0,0 +1,85 @@ + + + + + Testing Alerts + + + + + +

Testing Alerts and Stuff

+ +

This tests alerts: click me

+ +

This tests alerts: click me

+ +

Let's make the prompt happen

+ +

Let's make the prompt with default happen

+ +

Let's make TWO prompts happen

+ +

A SLOW alert

+ +

This is a test of a confirm: + test confirm

+ +

This is a test of showModalDialog: test dialog

+ +

This is a test of an alert in an iframe: + +

+ +

This is a test of an alert in a nested iframe: + +

+ +

This is a test of an alert open from onload event handler: open new page

+ +

This is a test of an alert open from onload event handler: open new window

+ +

This is a test of an alert open from onunload event handler: open new page

+ +

This is a test of an alert open from onclose event handler: open new window

+ +

This is a test of an alert open from onclose event handler: open new window

+ +
+
+
+ +

+

+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/banner.gif b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/banner.gif new file mode 100644 index 0000000..3f34354 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/banner.gif differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/beach.jpg b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/beach.jpg new file mode 100644 index 0000000..402237c Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/beach.jpg differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/blank.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/blank.html new file mode 100644 index 0000000..c3f376e --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/blank.html @@ -0,0 +1 @@ +blank diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/bodyTypingTest.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/bodyTypingTest.html new file mode 100644 index 0000000..f2b1939 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/bodyTypingTest.html @@ -0,0 +1,41 @@ + + + + Testing Typing into body + + + + +

Type Stuff

+ +
+   +
+ +
+   +
+ + + + +
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/booleanAttributes.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/booleanAttributes.html new file mode 100644 index 0000000..16fbbe9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/booleanAttributes.html @@ -0,0 +1,19 @@ + + + Elements with boolean attributes + + +
+ + + + + +
+ + +
+ +
Unwrappable text
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/child/childPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/child/childPage.html new file mode 100644 index 0000000..9192b54 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/child/childPage.html @@ -0,0 +1,8 @@ + + + Depth one child page + + +

I'm a page in a child directory

+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/child/grandchild/grandchildPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/child/grandchild/grandchildPage.html new file mode 100644 index 0000000..f52685e --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/child/grandchild/grandchildPage.html @@ -0,0 +1,8 @@ + + + Depth two child page + + +

I'm a page in a grandchild directory! How cute!

+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/clickEventPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/clickEventPage.html new file mode 100644 index 0000000..8e0355d --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/clickEventPage.html @@ -0,0 +1,26 @@ + + + + Testing click events + + + +
+ Click me to view my coordinates +
+ +
+

 

+
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_frames.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_frames.html new file mode 100644 index 0000000..bd055c7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_frames.html @@ -0,0 +1,10 @@ + + + click frames + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_jacker.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_jacker.html new file mode 100644 index 0000000..0ff3900 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_jacker.html @@ -0,0 +1,38 @@ + + + + click-jacking + + + +
+
Click jacked!
+
Click Me
+ +
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds.html new file mode 100644 index 0000000..8a51659 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds.html @@ -0,0 +1,23 @@ + + + + + + + + + + + +
+
+
+
+
+ +
+
+
+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds_overflow.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds_overflow.html new file mode 100644 index 0000000..15ac17f --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds_overflow.html @@ -0,0 +1,85 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
click me
+
+ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_rtl.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_rtl.html new file mode 100644 index 0000000..e84fffa --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_rtl.html @@ -0,0 +1,19 @@ + + +RTL test + + + +
+ +
Ù…ÙØªØ§Ø­ معايير الويب
+ +
פעילות הבינ×ו×
+ +
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_source.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_source.html new file mode 100644 index 0000000..22e9319 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_source.html @@ -0,0 +1,18 @@ + + + Click Source + + + I go to a target + + + + + + Click Source + + + I go to a target + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_iframe.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_iframe.html new file mode 100644 index 0000000..7b749bc --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_iframe.html @@ -0,0 +1,6 @@ + + + click iframe + +Click me + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_in_iframe.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_in_iframe.html new file mode 100644 index 0000000..60b1cca --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_in_iframe.html @@ -0,0 +1,8 @@ + + + click in iframe + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_frame.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_frame.html new file mode 100644 index 0000000..d6f4caf --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_frame.html @@ -0,0 +1 @@ +Continue \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_target.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_target.html new file mode 100644 index 0000000..cbc16e8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_target.html @@ -0,0 +1,10 @@ + + + + Target page for issue 5237 + + +

Test passed

+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/link_that_wraps.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/link_that_wraps.html new file mode 100644 index 0000000..0443436 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/link_that_wraps.html @@ -0,0 +1,11 @@ + + + + Link that continues on next line + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page1.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page1.html new file mode 100644 index 0000000..245f038 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page1.html @@ -0,0 +1,9 @@ + + + + Target Page 1 + + +
Target Page 1
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page2.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page2.html new file mode 100644 index 0000000..6f9636c --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page2.html @@ -0,0 +1,9 @@ + + + + Target Page 2 + + +
Target Page 2
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page3.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page3.html new file mode 100644 index 0000000..87a35f3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page3.html @@ -0,0 +1,9 @@ + + + + Target Page 3 + + +
Target Page 3
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/overlapping_elements.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/overlapping_elements.html new file mode 100644 index 0000000..6cfa56a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/overlapping_elements.html @@ -0,0 +1,70 @@ + + + + An element that disappears on click + + + +

Hello

+

Hello

+
+
+

Log:

+

+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/partially_overlapping_elements.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/partially_overlapping_elements.html new file mode 100644 index 0000000..2af6252 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/partially_overlapping_elements.html @@ -0,0 +1,124 @@ + + + + An element that disappears on click + + + +

Hello

+

Hello

+
+
+
+
+
+
+

Log:

+

+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/span_that_wraps.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/span_that_wraps.html new file mode 100644 index 0000000..77a9d6d --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/span_that_wraps.html @@ -0,0 +1,11 @@ + + + + Link that continues on next line + + +
+
placeholder
Span that continues on next line +
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/submitted_page.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/submitted_page.html new file mode 100644 index 0000000..0ed2cba --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/submitted_page.html @@ -0,0 +1,9 @@ + + + +Submitted Successfully! + + +

Submitted Successfully!

+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/wrapped_overlapping_elements.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/wrapped_overlapping_elements.html new file mode 100644 index 0000000..1c0c3d0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_tests/wrapped_overlapping_elements.html @@ -0,0 +1,13 @@ + + + + A wrapped element with overlapped first part + + +
+
placeholder
+
Over
+ Link that continues on next line +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_too_big.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_too_big.html new file mode 100644 index 0000000..568ee77 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_too_big.html @@ -0,0 +1,10 @@ + + + + +
+       +
+
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_too_big_in_frame.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_too_big_in_frame.html new file mode 100644 index 0000000..cda990e --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/click_too_big_in_frame.html @@ -0,0 +1,11 @@ + + + This page has iframes + + +

This is the heading

+ + + + +
+I'm a normal link +
+I go to an anchor +
+I open a window with javascript +
+Click me +
+ +
+I'm a green link +

looooooooooong short looooooooooong +

+ +333333 +

I have a span

And another span

+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/closeable_window.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/closeable_window.html new file mode 100644 index 0000000..e64c599 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/closeable_window.html @@ -0,0 +1,8 @@ + + +closeable window + + +This window can be closed by clicking on this. + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cn-test.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cn-test.html new file mode 100644 index 0000000..df846ad --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cn-test.html @@ -0,0 +1,156 @@ + + + + + + + + + + +
+
+ + +

Õ¹Íû2008ÊÀ½ç´óÊÆ£º·çÆðÔÆÓ¿ ¼¤µ´ÈËÐÄ


+
+ 8ÔÂ8ÈÕÍí£¬±±¾©2008Äê°ÂÔ˻ᵹ¼ÆÊ±Ò»ÖÜÄêÇì×£»î¶¯ÔÚÌì°²ÃŹ㳡¾ÙÐС£Í¼ÎªÇì×£»î¶¯ÖеÄÎÄÒÕÑݳö¡£ лªÉç¼ÇÕßÁõÎÀ±øÉã + + £²£°£°£¸ÄêÊÀ½ç·çÆðÔÆÓ¿£¬¼¤µ´ÈËÐÄ¡£µ«Òª×÷³öÒ»¸öÔ¤²â£¬Ê×ÏÈÒª¶Ô½ñÌìËù´¦µÄÊÀ½çÓÐÒ»¸ö»ù±¾¹²Ê¶¡£
+
+ÖйúÖ®Éù
+
+
+ +
+ +
+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/colorPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/colorPage.html new file mode 100644 index 0000000..0d1bfc0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/colorPage.html @@ -0,0 +1,20 @@ + + + + Color Page + + +
namedColor
+
rgb
+
rgbpct
+
hex
+
hex
+
hsl
+
rgba
+
rgba
+
hsla
+ + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cookies.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cookies.html new file mode 100644 index 0000000..7db5b49 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cookies.html @@ -0,0 +1,30 @@ + + + Testing cookies + + + + +

Cookie Mashing

+ .com Click
+ . Click
+ google.com Click
+ .google.com Click
+ 127.0.0.1 Click
+ localhost:3001 Click
+ .google:3001 Click
+ 172.16.12.225 Click
+ 172.16.12.225:port Click
+ Set on a different path + +
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_frame.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_frame.html new file mode 100644 index 0000000..7714a48 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_frame.html @@ -0,0 +1,9 @@ + + + + Welcome Page + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_nested_frame.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_nested_frame.html new file mode 100644 index 0000000..b3143b0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_nested_frame.html @@ -0,0 +1,9 @@ + + + + Welcome Page + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_element_out_of_view.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_element_out_of_view.html new file mode 100644 index 0000000..6f2bcd4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_element_out_of_view.html @@ -0,0 +1,11 @@ + + + + Page With Element Out Of View + + +
Placeholder
+
Red box
+
Tex after box
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_empty_element.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_empty_element.html new file mode 100644 index 0000000..b07972a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_empty_element.html @@ -0,0 +1,10 @@ + + + + Page With Empty Element + + +
+
Tex after box
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_fixed_element.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_fixed_element.html new file mode 100644 index 0000000..6cbb273 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_fixed_element.html @@ -0,0 +1,12 @@ + + + + Page With Fixed Element + + +
fixed red box
+
Placeholder
+
Element at the bottom
+
Tex after box
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_hidden_element.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_hidden_element.html new file mode 100644 index 0000000..286b04b --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_hidden_element.html @@ -0,0 +1,10 @@ + + + + Page With Hidden Element + + + +
Tex after box
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_invisible_element.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_invisible_element.html new file mode 100644 index 0000000..dc33c71 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_invisible_element.html @@ -0,0 +1,10 @@ + + + + Page With Invisible Element + + + +
Tex after box
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_transparent_element.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_transparent_element.html new file mode 100644 index 0000000..d0090d9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_transparent_element.html @@ -0,0 +1,10 @@ + + + + Page With Transparent Element + + +
Hidden box
+
Tex after box
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/simple_page.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/simple_page.html new file mode 100644 index 0000000..7b857b9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/simple_page.html @@ -0,0 +1,10 @@ + + + + Simple Page + + +
Red box
+
Tex after box
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png new file mode 100644 index 0000000..954e22d Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png new file mode 100644 index 0000000..64ece57 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png new file mode 100644 index 0000000..abdc010 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png new file mode 100644 index 0000000..9b383f4 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png new file mode 100644 index 0000000..a23baad Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 0000000..42ccba2 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png new file mode 100644 index 0000000..39d5824 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png new file mode 100644 index 0000000..f127367 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png new file mode 100644 index 0000000..359397a Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_222222_256x240.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000..b273ff1 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_222222_256x240.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_228ef1_256x240.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_228ef1_256x240.png new file mode 100644 index 0000000..a641a37 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_228ef1_256x240.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ef8c08_256x240.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ef8c08_256x240.png new file mode 100644 index 0000000..85e63e9 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ef8c08_256x240.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffd27a_256x240.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffd27a_256x240.png new file mode 100644 index 0000000..e117eff Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffd27a_256x240.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffffff_256x240.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffffff_256x240.png new file mode 100644 index 0000000..42f8f99 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffffff_256x240.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/jquery-ui-1.8.10.custom.css b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/jquery-ui-1.8.10.custom.css new file mode 100644 index 0000000..1706e22 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/jquery-ui-1.8.10.custom.css @@ -0,0 +1,573 @@ +/* + * jQuery UI CSS Framework 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; } +.ui-widget-content a { color: #333333; } +.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; } +.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); } +.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/* + * jQuery UI Resizable 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * jQuery UI Selectable 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * jQuery UI Accordion 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/* + * jQuery UI Autocomplete 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.10 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * jQuery UI Button 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Dialog 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* + * jQuery UI Slider 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * jQuery UI Tabs 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/* + * jQuery UI Datepicker 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* + * jQuery UI Progressbar 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cssTransform.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cssTransform.html new file mode 100644 index 0000000..c3b9964 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cssTransform.html @@ -0,0 +1,61 @@ + + +
+You shouldn't see anything other than this sentence on the page +
+
+ I have a hidden child +
+ I am a hidden child +
+
+
+ I have a hidden child +
+ I am a hidden child +
+
+
I am a hidden element
+
I am a hidden element
diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cssTransform2.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cssTransform2.html new file mode 100644 index 0000000..602924b --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/cssTransform2.html @@ -0,0 +1,20 @@ + + +
+
+
+
+
+
+
I am not a hidden element
diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/document_write_in_onload.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/document_write_in_onload.html new file mode 100644 index 0000000..a15fc47 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/document_write_in_onload.html @@ -0,0 +1,13 @@ + + + Document Write In Onload + + + +

hello world

+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropInsideScrolledDiv.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropInsideScrolledDiv.html new file mode 100644 index 0000000..0b2ee9a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropInsideScrolledDiv.html @@ -0,0 +1,67 @@ + + + + + + + +
+
+
+
+
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropTest.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropTest.html new file mode 100644 index 0000000..fdee16b --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropTest.html @@ -0,0 +1,102 @@ + + + + + + + + +
+
+"Hi there +
+
+
+
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dragDropOverflow.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dragDropOverflow.html new file mode 100644 index 0000000..ecb2562 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dragDropOverflow.html @@ -0,0 +1,104 @@ + + + + + + +
+
+
+
+
12am
+
1am
+
2am
+
3am
+
4am
+
5am
+
6am
+
7am
+
8am
+
9am
+
10am
+
11am
+
12pm
+
1pm
+
2pm
+
3pm
+
4pm
+
5pm
+
6pm
+
7pm
+
8pm
+
9pm
+
10pm
+
11pm
+
+
+
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/draggableLists.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/draggableLists.html new file mode 100644 index 0000000..f7e0dca --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/draggableLists.html @@ -0,0 +1,67 @@ + + + + + jQuery UI Sortable - Connect lists + + + + + + + + + +
+
    +
  • LeftItem 1
  • +
  • LeftItem 2
  • +
  • LeftItem 3
  • +
  • LeftItem 4
  • +
  • LeftItem 5
  • +
+ +
    +
  • RightItem 1
  • +
  • RightItem 2
  • +
  • RightItem 3
  • +
  • RightItem 4
  • +
  • RightItem 5
  • +
+ +
+ +
+
+

Nothing happened.

+
+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/droppableItems.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/droppableItems.html new file mode 100644 index 0000000..fc850ac --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/droppableItems.html @@ -0,0 +1,65 @@ + + + + + jQuery UI Droppable - Default Demo + + + + + + + +
+ +
+

Drag me to my target

+
+ +
+

Drop here

+
+ +
+

start

+
+ +
+ +
+ +

Taken from the JQuery demo.

+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dynamic.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dynamic.html new file mode 100644 index 0000000..b9e6067 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dynamic.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dynamicallyModifiedPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dynamicallyModifiedPage.html new file mode 100644 index 0000000..ed7c7ed --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/dynamicallyModifiedPage.html @@ -0,0 +1,42 @@ + + + + Delayed remove of an element + + + + + +
+ +
+

element

+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/errors.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/errors.html new file mode 100644 index 0000000..78fb902 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/errors.html @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/firefox/jetpack-sample.xpi b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/firefox/jetpack-sample.xpi new file mode 100644 index 0000000..84d6493 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/firefox/jetpack-sample.xpi differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/firefox/sample.xpi b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/firefox/sample.xpi new file mode 100644 index 0000000..062f9a1 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/firefox/sample.xpi differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScroll.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScroll.html new file mode 100644 index 0000000..ca65d1f --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScroll.html @@ -0,0 +1,13 @@ + + + + Fixed footer with no scrollbar + + +
+
+ Click me +
+
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScrollQuirksMode.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScrollQuirksMode.html new file mode 100644 index 0000000..2593bf3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScrollQuirksMode.html @@ -0,0 +1,12 @@ + + + Fixed footer with no scrollbar + + +
+
+ Click me +
+
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/formPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/formPage.html new file mode 100644 index 0000000..7bcfea0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/formPage.html @@ -0,0 +1,174 @@ + + + We Leave From Here + + + + +There should be a form here: + +
+ + + +
+ +
+ +
+ +
+ Here's a checkbox: + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + Cheese
+ Peas
+ Cheese and peas
+ Not a sausage
+ Not another sausage + + + +

I like cheese

+ + + Cumberland sausage +
+ +
+ + + + + + + + +
+ +
+ + + + + + + +
+ +
+ + + + + + + +
+ + +
+
+ +
+ +
+ + +
+

+ + + +

+
+ +
+ + + +
+

+ +

+
+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/formSelectionPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/formSelectionPage.html new file mode 100644 index 0000000..4890c08 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/formSelectionPage.html @@ -0,0 +1,46 @@ + + + + Testing Typing into body + + + + +

Type Stuff

+ +
+   +
+ +
+ +
+ + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/form_handling_js_submit.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/form_handling_js_submit.html new file mode 100644 index 0000000..3023143 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/form_handling_js_submit.html @@ -0,0 +1,30 @@ + + + + + + Form with JS action + + +
+ +
+ +

+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/framePage3.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/framePage3.html new file mode 100644 index 0000000..3e62e45 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/framePage3.html @@ -0,0 +1,7 @@ + + + inner + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameScrollChild.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameScrollChild.html new file mode 100644 index 0000000..3eb3bf4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameScrollChild.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

This is a scrolling frame test

+
+ + + + + + + + + + + + + +
First row
Second row
Third row
Fourth row
+
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameScrollPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameScrollPage.html new file mode 100644 index 0000000..b7fb8f2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameScrollPage.html @@ -0,0 +1,14 @@ + + + + Welcome Page + + +
+ +
+
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameScrollParent.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameScrollParent.html new file mode 100644 index 0000000..8fccb6d --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameScrollParent.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameWithAnimals.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameWithAnimals.html new file mode 100644 index 0000000..1e0dc87 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameWithAnimals.html @@ -0,0 +1,11 @@ + + + This page has iframes + + +

This is the heading

+ + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876_iframe.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876_iframe.html new file mode 100644 index 0000000..57d47d8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876_iframe.html @@ -0,0 +1,9 @@ + + + +
+ + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame.html new file mode 100644 index 0000000..9c27e04 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame.html @@ -0,0 +1,29 @@ + + + Deleting frame: main page + + + + +
+ + +
+
+ +
+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe.html new file mode 100644 index 0000000..e4b9723 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe.html @@ -0,0 +1,8 @@ + + + Deleting frame: iframe + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe2.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe2.html new file mode 100644 index 0000000..47764eb --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe2.html @@ -0,0 +1,7 @@ + + + Deleting frame: iframe 2 + + +
Added back
+ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameset.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameset.html new file mode 100644 index 0000000..039c5f2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/frameset.html @@ -0,0 +1,14 @@ + + + Unique title + + + + + + + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/framesetPage2.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/framesetPage2.html new file mode 100644 index 0000000..4ea35ff --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/framesetPage2.html @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/framesetPage3.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/framesetPage3.html new file mode 100644 index 0000000..42a9300 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/framesetPage3.html @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/globalscope.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/globalscope.html new file mode 100644 index 0000000..e4ca97a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/globalscope.html @@ -0,0 +1,15 @@ + + + + Global scope + + + +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/hidden.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/hidden.html new file mode 100644 index 0000000..0e8097e --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/hidden.html @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/blue.jpg b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/blue.jpg new file mode 100644 index 0000000..8ea27c4 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/blue.jpg differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/database.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/database.js new file mode 100644 index 0000000..c6333be --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/database.js @@ -0,0 +1,84 @@ +var database={}; +database.db={}; + +database.onError = function(tx, e) { + var log = document.createElement('div'); + log.setAttribute('name','error'); + log.setAttribute('style','background-color:red'); + log.innerText = e.message; + document.getElementById('logs').appendChild(log); +} + +database.onSuccess = function(tx, r) { + if (r.rows.length) { + var ol; + for (var i = 0; i < r.rows.length; i++) { + ol = document.createElement('ol'); + ol.innerHTML = r.rows.item(i).ID + ": " + r.rows.item(i).docname + " (" + r.rows.item(i).created + ")"; + document.getElementById('logs').appendChild(ol); + } + + } +} + +database.open=function(){ + database.db=openDatabase('HTML5', '1.0', 'Offline document storage', 100*1024); +} + +database.create=function(){ + database.db.transaction(function(tx) { + tx.executeSql("CREATE TABLE IF NOT EXISTS docs(ID INTEGER PRIMARY KEY ASC, docname TEXT, created TIMESTAMP DEFAULT CURRENT_TIMESTAMP)", + [], + database.onSuccess, + database.onError); + });} + +database.add = function(message) { + database.db.transaction(function(tx){ + tx.executeSql("INSERT INTO docs(docname) VALUES (?)", + [message], database.onSuccess, database.onError); + }); +} + +database.selectAll = function() { + database.db.transaction(function(tx) { + tx.executeSql("SELECT * FROM docs", [], database.onSuccess, + database.onError); + }); +} + +database.onDeleteAllSuccess = function(tx, r) { + var doc = document.documentElement; + var db_completed = document.createElement("div"); + db_completed.setAttribute("id", "db_completed"); + db_completed.innerText = "db operation completed"; + doc.appendChild(db_completed); +} + +database.deleteAll = function() { + database.db.transaction(function(tx) { + tx.executeSql("delete from docs", [], database.onDeleteAllSuccess, + database.onError); + }); +} + +var log = document.createElement('div'); +log.setAttribute('name','notice'); +log.setAttribute('style','background-color:yellow'); +log.innerText = typeof window.openDatabase == "function" ? "Web Database is supported." : "Web Database is not supported."; +document.getElementById('logs').appendChild(log); + +try { + database.open(); + database.create(); + database.add('Doc 1'); + database.add('Doc 2'); + database.selectAll(); + database.deleteAll(); +} catch(error) { + var log = document.createElement('div'); + log.setAttribute('name','critical'); + log.setAttribute('style','background-color:pink'); + log.innerText = error; + document.getElementById('logs').appendChild(log); +} diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/geolocation.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/geolocation.js new file mode 100644 index 0000000..f07af14 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/geolocation.js @@ -0,0 +1,18 @@ +function success(position) { + var message = document.getElementById("status"); + message.innerHTML =""; + message.innerHTML += "

Longitude: " + position.coords.longitude + "

"; + message.innerHTML += "

Latitude: " + position.coords.latitude + "

"; + message.innerHTML += "

Altitude: " + position.coords.altitude + "

"; +} + +function error(msg) { + var message = document.getElementById("status"); + message.innerHTML = "Failed to get geolocation."; +} + +if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(success, error); +} else { + error('Geolocation is not supported.'); +} \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/green.jpg b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/green.jpg new file mode 100644 index 0000000..6a0d3be Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/green.jpg differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/red.jpg b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/red.jpg new file mode 100644 index 0000000..f296e27 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/red.jpg differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/status.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/status.html new file mode 100644 index 0000000..394116a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/status.html @@ -0,0 +1 @@ +Online diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/test.appcache b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/test.appcache new file mode 100644 index 0000000..3bc4e00 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/test.appcache @@ -0,0 +1,11 @@ +CACHE MANIFEST + +CACHE: +# Additional items to cache. +yellow.jpg +red.jpg +blue.jpg +green.jpg + +FALLBACK: +status.html offline.html diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/yellow.jpg b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/yellow.jpg new file mode 100644 index 0000000..7c609b3 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5/yellow.jpg differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5Page.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5Page.html new file mode 100644 index 0000000..355ddc3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/html5Page.html @@ -0,0 +1,32 @@ + + +HTML5 + + + +

Geolocation Test

+
Location unknown
+ + +

Web SQL Database Test

+
+ + +

Application Cache Test

+
+

Current network status:

+ + + + + +
+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/icon.gif b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/icon.gif new file mode 100644 index 0000000..bb99461 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/icon.gif differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/iframeAtBottom.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/iframeAtBottom.html new file mode 100644 index 0000000..a686ba3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/iframeAtBottom.html @@ -0,0 +1,15 @@ + + + This page has iframes + + +

This is the heading

+ +
+ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/iframes.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/iframes.html new file mode 100644 index 0000000..e00b482 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/iframes.html @@ -0,0 +1,11 @@ + + + This page has iframes + + +

This is the heading

+ +':"");a._keyEvent=false;return I},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='
', +o="";if(h||!j)o+=''+i[b]+"";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='"}u||(k+=o+(h||!(j&& +l)?" ":""));a.yearshtml="";if(h||!l)k+=''+c+"";else{g=this._get(a,"yearRange").split(":");var r=(new Date).getFullYear();i=function(s){s=s.match(/c[+-].*/)?c+parseInt(s.substring(1),10):s.match(/[+-].*/)?r+parseInt(s,10):parseInt(s,10);return isNaN(s)?r:s};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='";if(d.browser.mozilla)k+='";else{k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="
";return k},_adjustInstDate:function(a,b,c){var e= +a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&ba?a:b},_notifyChange:function(a){var b=this._get(a, +"onChangeMonthYear");if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a); +c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a, +"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker= +function(a){if(!this.length)return this;if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker, +[this[0]].concat(b));return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new K;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.10";window["DP_jQuery_"+y]=d})(jQuery); +;/* + * jQuery UI Progressbar 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("
").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); +this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* +this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.10"})})(jQuery); +;/* + * jQuery UI Effects 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/ + */ +jQuery.effects||function(f,j){function n(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], +16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return o.transparent;return o[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return n(b)}function p(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle, +a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function q(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d= +a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function m(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor", +"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=n(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var o={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0, +0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211, +211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},r=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b, +d){if(f.isFunction(b)){d=b;b=null}return this.queue("fx",function(){var e=f(this),g=e.attr("style")||" ",h=q(p.call(this)),l,v=e.attr("className");f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});l=q(p.call(this));e.attr("className",v);e.animate(u(h,l),a,b,function(){f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments)});h=f.queue(this);l=h.splice(h.length-1,1)[0]; +h.splice(1,0,l);f.dequeue(this)})};f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c, +a):f.effects.animateClass.apply(this,[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.10",save:function(c,a){for(var b=0;b
").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent", +border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c); +return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});return d.call(this,b)},_show:f.fn.show,show:function(c){if(m(c))return this._show.apply(this,arguments); +else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(m(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(m(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c), +b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c, +a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c, +a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a== +e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h
").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ +e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); +;/* + * jQuery UI Effects Fade 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fade + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Fold 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fold + * + * Depends: + * jquery.effects.core.js + */ +(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1], +10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); +;/* + * jQuery UI Effects Highlight 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Highlight + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& +this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Pulsate 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Pulsate + * + * Depends: + * jquery.effects.core.js + */ +(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c
').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); +b.dequeue()})})}})(jQuery); +; \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.inline.min.css b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.inline.min.css new file mode 100644 index 0000000..9f194f6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.inline.min.css @@ -0,0 +1 @@ +.mce-object{border:1px dotted #3A3A3A;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0px}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp{background:#AAA}hr{cursor:default}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333} \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.min.css b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.min.css new file mode 100644 index 0000000..ea08c68 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.min.css @@ -0,0 +1 @@ +body{background-color:#FFFFFF;color:#000000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDDDDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px}.mce-object{border:1px dotted #3A3A3A;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0px}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp{background:#AAA}hr{cursor:default}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333} \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/readme.md b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/readme.md new file mode 100644 index 0000000..fa5d639 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/readme.md @@ -0,0 +1 @@ +Icons are generated and provided by the http://icomoon.io service. diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.dev.svg b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.dev.svg new file mode 100644 index 0000000..578b869 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.dev.svg @@ -0,0 +1,175 @@ + + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.eot b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.eot new file mode 100644 index 0000000..60e2d2e Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.eot differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.svg b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.svg new file mode 100644 index 0000000..930c48d --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.svg @@ -0,0 +1,62 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.ttf b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.ttf new file mode 100644 index 0000000..afc6ec4 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.ttf differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.woff b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.woff new file mode 100644 index 0000000..fa72c74 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.woff differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.dev.svg b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.dev.svg new file mode 100644 index 0000000..c87b8cd --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.dev.svg @@ -0,0 +1,153 @@ + + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.eot b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.eot new file mode 100644 index 0000000..c1085bf Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.eot differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.svg b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.svg new file mode 100644 index 0000000..feb9ba3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.svg @@ -0,0 +1,63 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.ttf b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.ttf new file mode 100644 index 0000000..58103c2 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.ttf differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.woff b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.woff new file mode 100644 index 0000000..ad1ae39 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.woff differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/anchor.gif b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/anchor.gif new file mode 100644 index 0000000..606348c Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/anchor.gif differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/loader.gif b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/loader.gif new file mode 100644 index 0000000..c69e937 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/loader.gif differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/object.gif b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/object.gif new file mode 100644 index 0000000..cccd7f0 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/object.gif differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/trans.gif b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/trans.gif new file mode 100644 index 0000000..3884865 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/trans.gif differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.ie7.min.css b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.ie7.min.css new file mode 100644 index 0000000..cd2bbdf --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.ie7.min.css @@ -0,0 +1 @@ +.mce-container,.mce-container *,.mce-widget,.mce-widget *,.mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:normal;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible !important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.mce-wordcount{position:absolute;top:0;right:0;padding:8px}div.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #9e9e9e;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:#d9d9d9}.mce-grid td div{border:1px solid #d6d6d6;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:focus{border-color:#a1a1a1}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover,.mce-grid a:focus{border-color:#a1a1a1}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#d6d6d6;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#a1a1a1;background:#c8def4}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-toolbar-grp{padding-bottom:2px}.mce-toolbar-grp .mce-flow-layout-item{margin-bottom:0}.mce-rtl .mce-wordcount{left:0;right:auto}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-panel{border:0 solid #9e9e9e;background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fdfdfd, #ddd);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fdfdfd), to(#ddd));background-image:-webkit-linear-gradient(top, #fdfdfd, #ddd);background-image:-o-linear-gradient(top, #fdfdfd, #ddd);background-image:linear-gradient(to bottom, #fdfdfd, #ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd', endColorstr='#ffdddddd', GradientType=0);zoom:1}.mce-floatpanel{position:absolute;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2)}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);top:0;left:0;background:#fff;border:1px solid #9e9e9e;border:1px solid rgba(0,0,0,0.25)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px;*margin-top:0}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#9e9e9e;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#fff;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#fff;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #c5c5c5;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#858585;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#adadad}.mce-window-head .mce-title{line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#fff;border-top:1px solid #c5c5c5;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-rtl .mce-window-head .mce-close{position:absolute;right:auto;left:15px}.mce-rtl .mce-window-head .mce-dragh{left:auto;right:0}.mce-rtl .mce-window-head .mce-title{direction:rtl;text-align:right}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000000;-moz-box-shadow:0 0 5px #000000;box-shadow:0 0 5px #000000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0px;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);position:relative;text-shadow:0 1px 1px rgba(255,255,255,0.75);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1}.mce-btn:hover,.mce-btn:focus{color:#333;background-color:#e3e3e3;background-image:-moz-linear-gradient(top, #f2f2f2, #ccc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#ccc));background-image:-webkit-linear-gradient(top, #f2f2f2, #ccc);background-image:-o-linear-gradient(top, #f2f2f2, #ccc);background-image:linear-gradient(to bottom, #f2f2f2, #ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffcccccc', GradientType=0);zoom:1}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn:not(.mce-disabled):active{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{min-width:50px;color:#fff;border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #08c, #04c);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));background-image:-webkit-linear-gradient(top, #08c, #04c);background-image:-o-linear-gradient(top, #08c, #04c);background-image:linear-gradient(to bottom, #08c, #04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);zoom:1}.mce-primary:hover,.mce-primary:focus{background-color:#005fb3;background-image:-moz-linear-gradient(top, #0077b3, #003cb3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0077b3), to(#003cb3));background-image:-webkit-linear-gradient(top, #0077b3, #003cb3);background-image:-o-linear-gradient(top, #0077b3, #003cb3);background-image:linear-gradient(to bottom, #0077b3, #003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3', endColorstr='#ff003cb3', GradientType=0);zoom:1}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{background-color:#005299;background-image:-moz-linear-gradient(top, #069, #039);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#069), to(#039));background-image:-webkit-linear-gradient(top, #069, #039);background-image:-o-linear-gradient(top, #069, #039);background-image:linear-gradient(to bottom, #069, #039);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff006699', endColorstr='#ff003399', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-primary button,.mce-primary button i{color:#fff;text-shadow:1px 1px #333}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:1px 5px;font-size:12px;*padding-bottom:2px}.mce-btn-small i{line-height:20px;vertical-align:top;*line-height:18px}.mce-btn .mce-caret{margin-top:8px;margin-left:0}.mce-btn-small .mce-caret{margin-top:8px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #333;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #333;border-top:0}.mce-rtl .mce-btn button{direction:rtl}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-first{border-left:1px solid #b1b1b1;border-left:1px solid rgba(0,0,0,0.25);-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #b1b1b1;border-right:1px solid rgba(0,0,0,0.1);-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#333;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#acacac}.mce-rtl .mce-checkbox{direction:rtl;text-align:right}.mce-rtl i.mce-i-checkbox{margin:0 0 0 3px}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-14px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-16px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;border-left:1px solid transparent;border-right:1px solid transparent}.mce-colorbutton:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-colorbutton.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-colorbutton{direction:rtl}.mce-rtl .mce-colorbutton .mce-preview{margin-left:0;padding-right:0;padding-left:4px;margin-right:-14px}.mce-rtl .mce-colorbutton.mce-btn-small .mce-preview{margin-left:0;padding-right:0;margin-right:-17px;padding-left:0}.mce-rtl .mce-colorbutton button{padding-right:10px;padding-left:10px}.mce-rtl .mce-colorbutton .mce-open{padding-left:4px;padding-right:4px}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);*height:32px}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#adadad}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#333}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:#666;color:#fff}.mce-path .mce-divider{display:inline}.mce-disabled .mce-path-item{color:#aaa}.mce-rtl .mce-path{direction:rtl}.mce-fieldset{border:0 solid #9E9E9E;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-rtl .mce-flow-layout{text-align:right;direction:rtl}.mce-rtl .mce-flow-layout-item{margin:2px 2px 2px 0}.mce-rtl .mce-flow-layout-item.mce-last{margin-left:2px}.mce-iframe{border:0 solid #9e9e9e;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label.mce-disabled{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-label.mce-error{color:#a00}.mce-rtl .mce-label{text-align:right;direction:rtl}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #c4c4c4}.mce-menubar .mce-menubtn button span{color:#333}.mce-menubar .mce-caret{border-top-color:#333}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:transparent;background:#e6e6e6;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-menubtn span{color:#333;margin-right:2px;line-height:20px;*line-height:16px}.mce-menubtn.mce-btn-small span{font-size:12px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-menubtn .mce-caret{*margin-top:6px}.mce-rtl .mce-menubtn button{direction:rtl;text-align:right}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-rtl .mce-listbox .mce-caret{right:auto;left:8px}.mce-rtl .mce-listbox button{padding-right:10px;padding-left:20px}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-ico,.mce-menu-item .mce-text{color:#333}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled .mce-ico{color:#adadad}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text,.mce-menu-item:focus .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:#fff}.mce-menu-item.mce-disabled:hover{background:#ccc}.mce-menu-shortcut{display:inline-block;color:#adadad}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 15px 0 20px}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item.mce-selected .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:#fff}.mce-menu-item .mce-caret{margin-top:4px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #333}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret,.mce-menu-item:hover .mce-caret{border-left-color:#fff}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item-normal.mce-active{background-color:#c8def4}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa}.mce-menu-item-normal.mce-active .mce-text{color:#333}.mce-menu-item-normal.mce-active:hover .mce-text,.mce-menu-item-normal.mce-active:hover .mce-ico{color:#fff}.mce-menu-item-normal.mce-active:focus .mce-text,.mce-menu-item-normal.mce-active:focus .mce-ico{color:#fff}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #08c, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);zoom:1}div.mce-menu .mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#cbcbcb;border-bottom:1px solid #fff;cursor:default;filter:none}.mce-menu.mce-rtl{direction:rtl}.mce-rtl .mce-menu-item{text-align:right;direction:rtl;padding:6px 12px 6px 15px}.mce-menu-align.mce-rtl .mce-menu-shortcut,.mce-menu-align.mce-rtl .mce-caret{right:auto;left:0}.mce-rtl .mce-menu-item .mce-caret{margin-left:6px;margin-right:0;border-right:4px solid #333;border-left:0}.mce-rtl .mce-menu-item.mce-selected .mce-caret,.mce-rtl .mce-menu-item:focus .mce-caret,.mce-rtl .mce-menu-item:hover .mce-caret{border-left-color:transparent;border-right-color:#fff}.mce-menu{position:absolute;left:0;top:0;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#fff;border:1px solid #989898;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#333}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-splitbtn.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-splitbtn{direction:rtl;text-align:right}.mce-rtl .mce-splitbtn button{padding-right:10px;padding-left:10px}.mce-rtl .mce-splitbtn .mce-open{padding-left:4px;padding-right:4px}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-rtl .mce-tabs{text-align:right;direction:rtl}.mce-rtl .mce-tab{border-width:0 0 0 1px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);display:inline-block;-webkit-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#333}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-textbox.mce-disabled{color:#adadad}.mce-rtl .mce-textbox{text-align:right;direction:rtl}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}.mce-throbber-inline{position:static;height:50px}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce';font-style:normal;font-weight:normal;font-size:16px;line-height:16px;vertical-align:text-top;-webkit-font-smoothing:antialiased;display:inline-block;background:transparent center center;width:16px;height:16px;color:#333;-ie7-icon:' '}.mce-btn-small .mce-ico{font-family:'tinymce-small'}.mce-ico,i.mce-i-checkbox{zoom:expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = this.currentStyle['-ie7-icon'].substr(1, 1) + ' ')}.mce-i-save{-ie7-icon:"\e000"}.mce-i-newdocument{-ie7-icon:"\e001"}.mce-i-fullpage{-ie7-icon:"\e002"}.mce-i-alignleft{-ie7-icon:"\e003"}.mce-i-aligncenter{-ie7-icon:"\e004"}.mce-i-alignright{-ie7-icon:"\e005"}.mce-i-alignjustify{-ie7-icon:"\e006"}.mce-i-cut{-ie7-icon:"\e007"}.mce-i-paste{-ie7-icon:"\e008"}.mce-i-searchreplace{-ie7-icon:"\e009"}.mce-i-bullist{-ie7-icon:"\e00a"}.mce-i-numlist{-ie7-icon:"\e00b"}.mce-i-indent{-ie7-icon:"\e00c"}.mce-i-outdent{-ie7-icon:"\e00d"}.mce-i-blockquote{-ie7-icon:"\e00e"}.mce-i-undo{-ie7-icon:"\e00f"}.mce-i-redo{-ie7-icon:"\e010"}.mce-i-link{-ie7-icon:"\e011"}.mce-i-unlink{-ie7-icon:"\e012"}.mce-i-anchor{-ie7-icon:"\e013"}.mce-i-image{-ie7-icon:"\e014"}.mce-i-media{-ie7-icon:"\e015"}.mce-i-help{-ie7-icon:"\e016"}.mce-i-code{-ie7-icon:"\e017"}.mce-i-insertdatetime{-ie7-icon:"\e018"}.mce-i-preview{-ie7-icon:"\e019"}.mce-i-forecolor{-ie7-icon:"\e01a"}.mce-i-backcolor{-ie7-icon:"\e01a"}.mce-i-table{-ie7-icon:"\e01b"}.mce-i-hr{-ie7-icon:"\e01c"}.mce-i-removeformat{-ie7-icon:"\e01d"}.mce-i-subscript{-ie7-icon:"\e01e"}.mce-i-superscript{-ie7-icon:"\e01f"}.mce-i-charmap{-ie7-icon:"\e020"}.mce-i-emoticons{-ie7-icon:"\e021"}.mce-i-print{-ie7-icon:"\e022"}.mce-i-fullscreen{-ie7-icon:"\e023"}.mce-i-spellchecker{-ie7-icon:"\e024"}.mce-i-nonbreaking{-ie7-icon:"\e025"}.mce-i-template{-ie7-icon:"\e026"}.mce-i-pagebreak{-ie7-icon:"\e027"}.mce-i-restoredraft{-ie7-icon:"\e028"}.mce-i-untitled{-ie7-icon:"\e029"}.mce-i-bold{-ie7-icon:"\e02a"}.mce-i-italic{-ie7-icon:"\e02b"}.mce-i-underline{-ie7-icon:"\e02c"}.mce-i-strikethrough{-ie7-icon:"\e02d"}.mce-i-visualchars{-ie7-icon:"\e02e"}.mce-i-ltr{-ie7-icon:"\e02f"}.mce-i-rtl{-ie7-icon:"\e030"}.mce-i-copy{-ie7-icon:"\e031"}.mce-i-resize{-ie7-icon:"\e032"}.mce-i-browse{-ie7-icon:"\e034"}.mce-i-pastetext{-ie7-icon:"\e035"}.mce-i-checkbox,.mce-i-selected{-ie7-icon:"\e033"}.mce-i-selected{visibility:hidden}.mce-i-backcolor{background:#BBB} \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.min.css b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.min.css new file mode 100644 index 0000000..284ac1d --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.min.css @@ -0,0 +1 @@ +.mce-container,.mce-container *,.mce-widget,.mce-widget *,.mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:normal;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible !important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.mce-wordcount{position:absolute;top:0;right:0;padding:8px}div.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #9e9e9e;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:#d9d9d9}.mce-grid td div{border:1px solid #d6d6d6;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:focus{border-color:#a1a1a1}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover,.mce-grid a:focus{border-color:#a1a1a1}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#d6d6d6;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#a1a1a1;background:#c8def4}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-toolbar-grp{padding-bottom:2px}.mce-toolbar-grp .mce-flow-layout-item{margin-bottom:0}.mce-rtl .mce-wordcount{left:0;right:auto}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-panel{border:0 solid #9e9e9e;background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fdfdfd, #ddd);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fdfdfd), to(#ddd));background-image:-webkit-linear-gradient(top, #fdfdfd, #ddd);background-image:-o-linear-gradient(top, #fdfdfd, #ddd);background-image:linear-gradient(to bottom, #fdfdfd, #ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd', endColorstr='#ffdddddd', GradientType=0);zoom:1}.mce-floatpanel{position:absolute;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2)}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);top:0;left:0;background:#fff;border:1px solid #9e9e9e;border:1px solid rgba(0,0,0,0.25)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px;*margin-top:0}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#9e9e9e;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#fff;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#fff;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #c5c5c5;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#858585;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#adadad}.mce-window-head .mce-title{line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#fff;border-top:1px solid #c5c5c5;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-rtl .mce-window-head .mce-close{position:absolute;right:auto;left:15px}.mce-rtl .mce-window-head .mce-dragh{left:auto;right:0}.mce-rtl .mce-window-head .mce-title{direction:rtl;text-align:right}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000000;-moz-box-shadow:0 0 5px #000000;box-shadow:0 0 5px #000000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0px;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);position:relative;text-shadow:0 1px 1px rgba(255,255,255,0.75);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1}.mce-btn:hover,.mce-btn:focus{color:#333;background-color:#e3e3e3;background-image:-moz-linear-gradient(top, #f2f2f2, #ccc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#ccc));background-image:-webkit-linear-gradient(top, #f2f2f2, #ccc);background-image:-o-linear-gradient(top, #f2f2f2, #ccc);background-image:linear-gradient(to bottom, #f2f2f2, #ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffcccccc', GradientType=0);zoom:1}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn:not(.mce-disabled):active{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{min-width:50px;color:#fff;border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #08c, #04c);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));background-image:-webkit-linear-gradient(top, #08c, #04c);background-image:-o-linear-gradient(top, #08c, #04c);background-image:linear-gradient(to bottom, #08c, #04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);zoom:1}.mce-primary:hover,.mce-primary:focus{background-color:#005fb3;background-image:-moz-linear-gradient(top, #0077b3, #003cb3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0077b3), to(#003cb3));background-image:-webkit-linear-gradient(top, #0077b3, #003cb3);background-image:-o-linear-gradient(top, #0077b3, #003cb3);background-image:linear-gradient(to bottom, #0077b3, #003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3', endColorstr='#ff003cb3', GradientType=0);zoom:1}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{background-color:#005299;background-image:-moz-linear-gradient(top, #069, #039);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#069), to(#039));background-image:-webkit-linear-gradient(top, #069, #039);background-image:-o-linear-gradient(top, #069, #039);background-image:linear-gradient(to bottom, #069, #039);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff006699', endColorstr='#ff003399', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-primary button,.mce-primary button i{color:#fff;text-shadow:1px 1px #333}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:1px 5px;font-size:12px;*padding-bottom:2px}.mce-btn-small i{line-height:20px;vertical-align:top;*line-height:18px}.mce-btn .mce-caret{margin-top:8px;margin-left:0}.mce-btn-small .mce-caret{margin-top:8px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #333;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #333;border-top:0}.mce-rtl .mce-btn button{direction:rtl}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-first{border-left:1px solid #b1b1b1;border-left:1px solid rgba(0,0,0,0.25);-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #b1b1b1;border-right:1px solid rgba(0,0,0,0.1);-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#333;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#acacac}.mce-rtl .mce-checkbox{direction:rtl;text-align:right}.mce-rtl i.mce-i-checkbox{margin:0 0 0 3px}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-14px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-16px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;border-left:1px solid transparent;border-right:1px solid transparent}.mce-colorbutton:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-colorbutton.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-colorbutton{direction:rtl}.mce-rtl .mce-colorbutton .mce-preview{margin-left:0;padding-right:0;padding-left:4px;margin-right:-14px}.mce-rtl .mce-colorbutton.mce-btn-small .mce-preview{margin-left:0;padding-right:0;margin-right:-17px;padding-left:0}.mce-rtl .mce-colorbutton button{padding-right:10px;padding-left:10px}.mce-rtl .mce-colorbutton .mce-open{padding-left:4px;padding-right:4px}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);*height:32px}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#adadad}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#333}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:#666;color:#fff}.mce-path .mce-divider{display:inline}.mce-disabled .mce-path-item{color:#aaa}.mce-rtl .mce-path{direction:rtl}.mce-fieldset{border:0 solid #9E9E9E;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-rtl .mce-flow-layout{text-align:right;direction:rtl}.mce-rtl .mce-flow-layout-item{margin:2px 2px 2px 0}.mce-rtl .mce-flow-layout-item.mce-last{margin-left:2px}.mce-iframe{border:0 solid #9e9e9e;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label.mce-disabled{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-label.mce-error{color:#a00}.mce-rtl .mce-label{text-align:right;direction:rtl}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #c4c4c4}.mce-menubar .mce-menubtn button span{color:#333}.mce-menubar .mce-caret{border-top-color:#333}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:transparent;background:#e6e6e6;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-menubtn span{color:#333;margin-right:2px;line-height:20px;*line-height:16px}.mce-menubtn.mce-btn-small span{font-size:12px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-menubtn .mce-caret{*margin-top:6px}.mce-rtl .mce-menubtn button{direction:rtl;text-align:right}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-rtl .mce-listbox .mce-caret{right:auto;left:8px}.mce-rtl .mce-listbox button{padding-right:10px;padding-left:20px}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-ico,.mce-menu-item .mce-text{color:#333}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled .mce-ico{color:#adadad}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text,.mce-menu-item:focus .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:#fff}.mce-menu-item.mce-disabled:hover{background:#ccc}.mce-menu-shortcut{display:inline-block;color:#adadad}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 15px 0 20px}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item.mce-selected .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:#fff}.mce-menu-item .mce-caret{margin-top:4px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #333}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret,.mce-menu-item:hover .mce-caret{border-left-color:#fff}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item-normal.mce-active{background-color:#c8def4}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa}.mce-menu-item-normal.mce-active .mce-text{color:#333}.mce-menu-item-normal.mce-active:hover .mce-text,.mce-menu-item-normal.mce-active:hover .mce-ico{color:#fff}.mce-menu-item-normal.mce-active:focus .mce-text,.mce-menu-item-normal.mce-active:focus .mce-ico{color:#fff}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #08c, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);zoom:1}div.mce-menu .mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#cbcbcb;border-bottom:1px solid #fff;cursor:default;filter:none}.mce-menu.mce-rtl{direction:rtl}.mce-rtl .mce-menu-item{text-align:right;direction:rtl;padding:6px 12px 6px 15px}.mce-menu-align.mce-rtl .mce-menu-shortcut,.mce-menu-align.mce-rtl .mce-caret{right:auto;left:0}.mce-rtl .mce-menu-item .mce-caret{margin-left:6px;margin-right:0;border-right:4px solid #333;border-left:0}.mce-rtl .mce-menu-item.mce-selected .mce-caret,.mce-rtl .mce-menu-item:focus .mce-caret,.mce-rtl .mce-menu-item:hover .mce-caret{border-left-color:transparent;border-right-color:#fff}.mce-menu{position:absolute;left:0;top:0;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#fff;border:1px solid #989898;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#333}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-splitbtn.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-splitbtn{direction:rtl;text-align:right}.mce-rtl .mce-splitbtn button{padding-right:10px;padding-left:10px}.mce-rtl .mce-splitbtn .mce-open{padding-left:4px;padding-right:4px}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-rtl .mce-tabs{text-align:right;direction:rtl}.mce-rtl .mce-tab{border-width:0 0 0 1px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);display:inline-block;-webkit-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#333}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-textbox.mce-disabled{color:#adadad}.mce-rtl .mce-textbox{text-align:right;direction:rtl}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}.mce-throbber-inline{position:static;height:50px}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce',Arial;font-style:normal;font-weight:normal;font-variant:normal;font-size:16px;line-height:16px;speak:none;vertical-align:text-top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;background:transparent center center;background-size:cover;width:16px;height:16px;color:#333}.mce-btn-small .mce-ico{font-family:'tinymce-small',Arial}.mce-i-save:before{content:"\e000"}.mce-i-newdocument:before{content:"\e001"}.mce-i-fullpage:before{content:"\e002"}.mce-i-alignleft:before{content:"\e003"}.mce-i-aligncenter:before{content:"\e004"}.mce-i-alignright:before{content:"\e005"}.mce-i-alignjustify:before{content:"\e006"}.mce-i-cut:before{content:"\e007"}.mce-i-paste:before{content:"\e008"}.mce-i-searchreplace:before{content:"\e009"}.mce-i-bullist:before{content:"\e00a"}.mce-i-numlist:before{content:"\e00b"}.mce-i-indent:before{content:"\e00c"}.mce-i-outdent:before{content:"\e00d"}.mce-i-blockquote:before{content:"\e00e"}.mce-i-undo:before{content:"\e00f"}.mce-i-redo:before{content:"\e010"}.mce-i-link:before{content:"\e011"}.mce-i-unlink:before{content:"\e012"}.mce-i-anchor:before{content:"\e013"}.mce-i-image:before{content:"\e014"}.mce-i-media:before{content:"\e015"}.mce-i-help:before{content:"\e016"}.mce-i-code:before{content:"\e017"}.mce-i-insertdatetime:before{content:"\e018"}.mce-i-preview:before{content:"\e019"}.mce-i-forecolor:before{content:"\e01a"}.mce-i-backcolor:before{content:"\e01a"}.mce-i-table:before{content:"\e01b"}.mce-i-hr:before{content:"\e01c"}.mce-i-removeformat:before{content:"\e01d"}.mce-i-subscript:before{content:"\e01e"}.mce-i-superscript:before{content:"\e01f"}.mce-i-charmap:before{content:"\e020"}.mce-i-emoticons:before{content:"\e021"}.mce-i-print:before{content:"\e022"}.mce-i-fullscreen:before{content:"\e023"}.mce-i-spellchecker:before{content:"\e024"}.mce-i-nonbreaking:before{content:"\e025"}.mce-i-template:before{content:"\e026"}.mce-i-pagebreak:before{content:"\e027"}.mce-i-restoredraft:before{content:"\e028"}.mce-i-untitled:before{content:"\e029"}.mce-i-bold:before{content:"\e02a"}.mce-i-italic:before{content:"\e02b"}.mce-i-underline:before{content:"\e02c"}.mce-i-strikethrough:before{content:"\e02d"}.mce-i-visualchars:before{content:"\e02e"}.mce-i-visualblocks:before{content:"\e02e"}.mce-i-ltr:before{content:"\e02f"}.mce-i-rtl:before{content:"\e030"}.mce-i-copy:before{content:"\e031"}.mce-i-resize:before{content:"\e032"}.mce-i-browse:before{content:"\e034"}.mce-i-pastetext:before{content:"\e035"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#bbb} \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/themes/modern/theme.min.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/themes/modern/theme.min.js new file mode 100644 index 0000000..e25849d --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/js/themes/modern/theme.min.js @@ -0,0 +1 @@ +tinymce.ThemeManager.add("modern",function(e){function t(){function t(t){var n,o=[];if(t)return d(t.split(/[ ,]/),function(t){function i(){var i=e.selection;"bullist"==r&&i.selectorChanged("ul > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"UL"==n)}),"numlist"==r&&i.selectorChanged("ol > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"OL"==n)}),t.settings.stateSelector&&i.selectorChanged(t.settings.stateSelector,function(e){t.active(e)},!0),t.settings.disabledStateSelector&&i.selectorChanged(t.settings.disabledStateSelector,function(e){t.disabled(e)})}var r;"|"==t?n=null:c.has(t)?(t={type:t},u.toolbar_items_size&&(t.size=u.toolbar_items_size),o.push(t),n=null):(n||(n={type:"buttongroup",items:[]},o.push(n)),e.buttons[t]&&(r=t,t=e.buttons[r],"function"==typeof t&&(t=t()),t.type=t.type||"button",u.toolbar_items_size&&(t.size=u.toolbar_items_size),t=c.create(t),n.items.push(t),e.initialized?i():e.on("init",i)))}),i.push({type:"toolbar",layout:"flow",items:o}),!0}var i=[];if(tinymce.isArray(u.toolbar)){if(0===u.toolbar.length)return;tinymce.each(u.toolbar,function(e,t){u["toolbar"+(t+1)]=e}),delete u.toolbar}for(var n=1;10>n&&t(u["toolbar"+n]);n++);return i.length||u.toolbar===!1||t(u.toolbar||f),i.length?{type:"panel",layout:"stack",classes:"toolbar-grp",ariaRoot:!0,ariaRemember:!0,items:i}:void 0}function i(){function t(t){var i;return"|"==t?{text:"|"}:i=e.menuItems[t]}function i(i){var n,o,r,a,s;if(s=tinymce.makeMap((u.removed_menuitems||"").split(/[ ,]/)),u.menu?(o=u.menu[i],a=!0):o=h[i],o){n={text:o.title},r=[],d((o.items||"").split(/[ ,]/),function(e){var i=t(e);i&&!s[e]&&r.push(t(e))}),a||d(e.menuItems,function(e){e.context==i&&("before"==e.separator&&r.push({text:"|"}),e.prependToContext?r.unshift(e):r.push(e),"after"==e.separator&&r.push({text:"|"}))});for(var l=0;lr;r++)if(o=n[r],o&&o.func.call(o.scope,e)===!1&&e.preventDefault(),e.isImmediatePropagationStopped())return}var a=this,s={},l,c,u,d,f;c=o+(+new Date).toString(32),d="onmouseenter"in document.documentElement,u="onfocusin"in document.documentElement,f={mouseenter:"mouseover",mouseleave:"mouseout"},l=1,a.domLoaded=!1,a.events=s,a.bind=function(t,o,p,h){function m(e){i(n(e||_.event),g)}var g,v,y,b,C,x,w,_=window;if(t&&3!==t.nodeType&&8!==t.nodeType){for(t[c]?g=t[c]:(g=l++,t[c]=g,s[g]={}),h=h||t,o=o.split(" "),y=o.length;y--;)b=o[y],x=m,C=w=!1,"DOMContentLoaded"===b&&(b="ready"),a.domLoaded&&"ready"===b&&"complete"==t.readyState?p.call(h,n({type:b})):(d||(C=f[b],C&&(x=function(e){var t,r;if(t=e.currentTarget,r=e.relatedTarget,r&&t.contains)r=t.contains(r);else for(;r&&r!==t;)r=r.parentNode;r||(e=n(e||_.event),e.type="mouseout"===e.type?"mouseleave":"mouseenter",e.target=t,i(e,g))})),u||"focusin"!==b&&"focusout"!==b||(w=!0,C="focusin"===b?"focus":"blur",x=function(e){e=n(e||_.event),e.type="focus"===e.type?"focusin":"focusout",i(e,g)}),v=s[g][b],v?"ready"===b&&a.domLoaded?p({type:b}):v.push({func:p,scope:h}):(s[g][b]=v=[{func:p,scope:h}],v.fakeName=C,v.capture=w,v.nativeHandler=x,"ready"===b?r(t,x,a):e(t,C||b,x,w)));return t=v=0,p}},a.unbind=function(e,n,r){var i,o,l,u,d,f;if(!e||3===e.nodeType||8===e.nodeType)return a;if(i=e[c]){if(f=s[i],n){for(n=n.split(" "),l=n.length;l--;)if(d=n[l],o=f[d]){if(r)for(u=o.length;u--;)if(o[u].func===r){var p=o.nativeHandler,h=o.fakeName,m=o.capture;o=o.slice(0,u).concat(o.slice(u+1)),o.nativeHandler=p,o.fakeName=h,o.capture=m,f[d]=o}r&&0!==o.length||(delete f[d],t(e,o.fakeName||d,o.nativeHandler,o.capture))}}else{for(d in f)o=f[d],t(e,o.fakeName||d,o.nativeHandler,o.capture);f={}}for(d in f)return a;delete s[i];try{delete e[c]}catch(g){e[c]=null}}return a},a.fire=function(e,t,r){var o;if(!e||3===e.nodeType||8===e.nodeType)return a;r=n(null,r),r.type=t,r.target=e;do o=e[c],o&&i(r,o),e=e.parentNode||e.ownerDocument||e.defaultView||e.parentWindow;while(e&&!r.isPropagationStopped());return a},a.clean=function(e){var t,n,r=a.unbind;if(!e||3===e.nodeType||8===e.nodeType)return a;if(e[c]&&r(e),e.getElementsByTagName||(e=e.document),e&&e.getElementsByTagName)for(r(e),n=e.getElementsByTagName("*"),t=n.length;t--;)e=n[t],e[c]&&r(e);return a},a.destroy=function(){s={}},a.cancel=function(e){return e&&(e.preventDefault(),e.stopImmediatePropagation()),!1}}var o="mce-data-",a=/^(?:mouse|contextmenu)|click/,s={keyLocation:1,layerX:1,layerY:1,returnValue:1};return i.Event=new i,i.Event.bind(window,"ready",function(){}),i}),r(c,[],function(){function e(e){return mt.test(e+"")}function n(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>_.cacheLength&&delete e[t.shift()],e[n]=r,r}}function r(e){return e[I]=!0,e}function i(e){var t=B.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t=null}}function o(e,t,n,r){var i,o,a,s,l,c,f,p,h,m;if((t?t.ownerDocument||t:F)!==B&&A(t),t=t||B,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(L&&!r){if(i=gt.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&O(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return Z.apply(n,t.getElementsByTagName(e)),n;if((a=i[3])&&z.getElementsByClassName&&t.getElementsByClassName)return Z.apply(n,t.getElementsByClassName(a)),n}if(z.qsa&&!M.test(e)){if(f=!0,p=I,h=t,m=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){for(c=u(e),(f=t.getAttribute("id"))?p=f.replace(bt,"\\$&"):t.setAttribute("id",p),p="[id='"+p+"'] ",l=c.length;l--;)c[l]=p+d(c[l]);h=ht.test(e)&&t.parentNode||t,m=c.join(",")}if(m)try{return Z.apply(n,h.querySelectorAll(m)),n}catch(g){}finally{f||t.removeAttribute("id")}}}return b(e.replace(lt,"$1"),t,n,r)}function a(e,t){var n=t&&e,r=n&&(~t.sourceIndex||Y)-(~e.sourceIndex||Y);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function l(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function c(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function u(e,t){var n,r,i,a,s,l,c,u=q[e+" "];if(u)return t?0:u.slice(0);for(s=e,l=[],c=_.preFilter;s;){(!n||(r=ct.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=ut.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(lt," ")}),s=s.slice(n.length));for(a in _.filter)!(r=pt[a].exec(s))||c[a]&&!(r=c[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?o.error(e):q(e,l).slice(0)}function d(e){for(var t=0,n=e.length,r="";n>t;t++)r+=e[t].value;return r}function f(e,t,n){var r=t.dir,i=n&&"parentNode"===r,o=V++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,l,c,u=W+" "+o;if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i)if(c=t[I]||(t[I]={}),(l=c[r])&&l[0]===u){if((s=l[1])===!0||s===w)return s===!0}else if(l=c[r]=[u],l[1]=e(t,n,a)||w,l[1]===!0)return!0}}function p(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function h(e,t,n,r,i){for(var o,a=[],s=0,l=e.length,c=null!=t;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),c&&t.push(s));return a}function m(e,t,n,i,o,a){return i&&!i[I]&&(i=m(i)),o&&!o[I]&&(o=m(o,a)),r(function(r,a,s,l){var c,u,d,f=[],p=[],m=a.length,g=r||y(t||"*",s.nodeType?[s]:s,[]),v=!e||!r&&t?g:h(g,f,e,s,l),b=n?o||(r?e:m||i)?[]:a:v;if(n&&n(v,b,s,l),i)for(c=h(b,p),i(c,[],s,l),u=c.length;u--;)(d=c[u])&&(b[p[u]]=!(v[p[u]]=d));if(r){if(o||e){if(o){for(c=[],u=b.length;u--;)(d=b[u])&&c.push(v[u]=d);o(null,b=[],c,l)}for(u=b.length;u--;)(d=b[u])&&(c=o?tt.call(r,d):f[u])>-1&&(r[c]=!(a[c]=d))}}else b=h(b===a?b.splice(m,b.length):b),o?o(null,a,b,l):Z.apply(a,b)})}function g(e){for(var t,n,r,i=e.length,o=_.relative[e[0].type],a=o||_.relative[" "],s=o?1:0,l=f(function(e){return e===t},a,!0),c=f(function(e){return tt.call(t,e)>-1},a,!0),u=[function(e,n,r){return!o&&(r||n!==k)||((t=n).nodeType?l(e,n,r):c(e,n,r))}];i>s;s++)if(n=_.relative[e[s].type])u=[f(p(u),n)];else{if(n=_.filter[e[s].type].apply(null,e[s].matches),n[I]){for(r=++s;i>r&&!_.relative[e[r].type];r++);return m(s>1&&p(u),s>1&&d(e.slice(0,s-1)).replace(lt,"$1"),n,r>s&&g(e.slice(s,r)),i>r&&g(e=e.slice(r)),i>r&&d(e))}u.push(n)}return p(u)}function v(e,t){var n=0,i=t.length>0,a=e.length>0,s=function(r,s,l,c,u){var d,f,p,m=[],g=0,v="0",y=r&&[],b=null!=u,C=k,x=r||a&&_.find.TAG("*",u&&s.parentNode||s),N=W+=null==C?1:Math.random()||.1;for(b&&(k=s!==B&&s,w=n);null!=(d=x[v]);v++){if(a&&d){for(f=0;p=e[f++];)if(p(d,s,l)){c.push(d);break}b&&(W=N,w=++n)}i&&((d=!p&&d)&&g--,r&&y.push(d))}if(g+=v,i&&v!==g){for(f=0;p=t[f++];)p(y,m,s,l);if(r){if(g>0)for(;v--;)y[v]||m[v]||(m[v]=J.call(c));m=h(m)}Z.apply(c,m),b&&!r&&m.length>0&&g+t.length>1&&o.uniqueSort(c)}return b&&(W=N,k=C),y};return i?r(s):s}function y(e,t,n){for(var r=0,i=t.length;i>r;r++)o(e,t[r],n);return n}function b(e,t,n,r){var i,o,a,s,l,c=u(e);if(!r&&1===c.length){if(o=c[0]=c[0].slice(0),o.length>2&&"ID"===(a=o[0]).type&&9===t.nodeType&&L&&_.relative[o[1].type]){if(t=(_.find.ID(a.matches[0].replace(xt,wt),t)||[])[0],!t)return n;e=e.slice(o.shift().value.length)}for(i=pt.needsContext.test(e)?0:o.length;i--&&(a=o[i],!_.relative[s=a.type]);)if((l=_.find[s])&&(r=l(a.matches[0].replace(xt,wt),ht.test(o[0].type)&&t.parentNode||t))){if(o.splice(i,1),e=r.length&&d(o),!e)return Z.apply(n,r),n;break}}return S(e,c)(r,t,!L,n,ht.test(e)),n}function C(){}var x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I="sizzle"+-new Date,F=window.document,z={},W=0,V=0,U=n(),q=n(),$=n(),j=!1,K=function(){return 0},G=typeof t,Y=1<<31,X=[],J=X.pop,Q=X.push,Z=X.push,et=X.slice,tt=X.indexOf||function(e){for(var t=0,n=this.length;n>t;t++)if(this[t]===e)return t;return-1},nt="[\\x20\\t\\r\\n\\f]",rt="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",it=rt.replace("w","w#"),ot="([*^$|!~]?=)",at="\\["+nt+"*("+rt+")"+nt+"*(?:"+ot+nt+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+it+")|)|)"+nt+"*\\]",st=":("+rt+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+at.replace(3,8)+")*)|.*)\\)|)",lt=new RegExp("^"+nt+"+|((?:^|[^\\\\])(?:\\\\.)*)"+nt+"+$","g"),ct=new RegExp("^"+nt+"*,"+nt+"*"),ut=new RegExp("^"+nt+"*([\\x20\\t\\r\\n\\f>+~])"+nt+"*"),dt=new RegExp(st),ft=new RegExp("^"+it+"$"),pt={ID:new RegExp("^#("+rt+")"),CLASS:new RegExp("^\\.("+rt+")"),NAME:new RegExp("^\\[name=['\"]?("+rt+")['\"]?\\]"),TAG:new RegExp("^("+rt.replace("w","w*")+")"),ATTR:new RegExp("^"+at),PSEUDO:new RegExp("^"+st),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+nt+"*(even|odd|(([+-]|)(\\d*)n|)"+nt+"*(?:([+-]|)"+nt+"*(\\d+)|))"+nt+"*\\)|)","i"),needsContext:new RegExp("^"+nt+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+nt+"*((?:-\\d)?\\d*)"+nt+"*\\)|)(?=[^-]|$)","i")},ht=/[\x20\t\r\n\f]*[+~]/,mt=/^[^{]+\{\s*\[native code/,gt=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,vt=/^(?:input|select|textarea|button)$/i,yt=/^h\d$/i,bt=/'|\\/g,Ct=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,xt=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,wt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320)};try{Z.apply(X=et.call(F.childNodes),F.childNodes),X[F.childNodes.length].nodeType}catch(_t){Z={apply:X.length?function(e,t){Q.apply(e,et.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}E=o.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},A=o.setDocument=function(n){var r=n?n.ownerDocument||n:F;return r!==B&&9===r.nodeType&&r.documentElement?(B=r,D=r.documentElement,L=!E(r),z.getElementsByTagName=i(function(e){return e.appendChild(r.createComment("")),!e.getElementsByTagName("*").length}),z.attributes=i(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),z.getElementsByClassName=i(function(e){return e.innerHTML="",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),z.getByName=i(function(e){e.id=I+0,e.appendChild(B.createElement("a")).setAttribute("name",I),e.appendChild(B.createElement("i")).setAttribute("name",I),D.appendChild(e);var t=r.getElementsByName&&r.getElementsByName(I).length===2+r.getElementsByName(I+0).length;return D.removeChild(e),t}),z.sortDetached=i(function(e){return e.compareDocumentPosition&&1&e.compareDocumentPosition(B.createElement("div"))}),_.attrHandle=i(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==G&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},z.getByName?(_.find.ID=function(e,t){if(typeof t.getElementById!==G&&L){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},_.filter.ID=function(e){var t=e.replace(xt,wt);return function(e){return e.getAttribute("id")===t}}):(_.find.ID=function(e,n){if(typeof n.getElementById!==G&&L){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==G&&r.getAttributeNode("id").value===e?[r]:t:[]}},_.filter.ID=function(e){var t=e.replace(xt,wt);return function(e){var n=typeof e.getAttributeNode!==G&&e.getAttributeNode("id");return n&&n.value===t}}),_.find.TAG=z.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==G?t.getElementsByTagName(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},_.find.NAME=z.getByName&&function(e,t){return typeof t.getElementsByName!==G?t.getElementsByName(name):void 0},_.find.CLASS=z.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==G&&L?t.getElementsByClassName(e):void 0},H=[],M=[":focus"],(z.qsa=e(r.querySelectorAll))&&(i(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||M.push("\\["+nt+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||M.push(":checked")}),i(function(e){e.innerHTML="",e.querySelectorAll("[i^='']").length&&M.push("[*^$]="+nt+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||M.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),M.push(",.*:")})),(z.matchesSelector=e(P=D.matchesSelector||D.mozMatchesSelector||D.webkitMatchesSelector||D.oMatchesSelector||D.msMatchesSelector))&&i(function(e){z.disconnectedMatch=P.call(e,"div"),P.call(e,"[s!='']:x"),H.push("!=",st)}),M=new RegExp(M.join("|")),H=H.length&&new RegExp(H.join("|")),O=e(D.contains)||D.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},K=D.compareDocumentPosition?function(e,t){if(e===t)return j=!0,0;var n=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return n?1&n||T&&t.compareDocumentPosition(e)===n?e===r||O(F,e)?-1:t===r||O(F,t)?1:R?tt.call(R,e)-tt.call(R,t):0:4&n?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var n,i=0,o=e.parentNode,s=t.parentNode,l=[e],c=[t];if(e===t)return j=!0,0;if(!o||!s)return e===r?-1:t===r?1:o?-1:s?1:0;if(o===s)return a(e,t);for(n=e;n=n.parentNode;)l.unshift(n);for(n=t;n=n.parentNode;)c.unshift(n);for(;l[i]===c[i];)i++;return i?a(l[i],c[i]):l[i]===F?-1:c[i]===F?1:0},B):B},o.matches=function(e,t){return o(e,null,null,t)},o.matchesSelector=function(e,t){if((e.ownerDocument||e)!==B&&A(e),t=t.replace(Ct,"='$1']"),z.matchesSelector&&L&&(!H||!H.test(t))&&!M.test(t))try{var n=P.call(e,t);if(n||z.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return o(t,B,null,[e]).length>0},o.contains=function(e,t){return(e.ownerDocument||e)!==B&&A(e),O(e,t)},o.attr=function(e,t){var n;return(e.ownerDocument||e)!==B&&A(e),L&&(t=t.toLowerCase()),(n=_.attrHandle[t])?n(e):!L||z.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},o.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},o.uniqueSort=function(e){var t,n=[],r=0,i=0;if(j=!z.detectDuplicates,T=!z.sortDetached,R=!z.sortStable&&e.slice(0),e.sort(K),j){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return e},N=o.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=N(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=N(t);return n},_=o.selectors={cacheLength:50,createPseudo:r,match:pt,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(xt,wt),e[3]=(e[4]||e[5]||"").replace(xt,wt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||o.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&o.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return pt.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&dt.test(n)&&(t=u(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(xt,wt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=U[e+" "];return t||(t=new RegExp("(^|"+nt+")"+e+"("+nt+"|$)"))&&U(e,function(e){return t.test(e.className||typeof e.getAttribute!==G&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=o.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var c,u,d,f,p,h,m=o!==a?"nextSibling":"previousSibling",g=t.parentNode,v=s&&t.nodeName.toLowerCase(),y=!l&&!s;if(g){if(o){for(;m;){for(d=t;d=d[m];)if(s?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;h=m="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?g.firstChild:g.lastChild],a&&y){for(u=g[I]||(g[I]={}),c=u[e]||[],p=c[0]===W&&c[1],f=c[0]===W&&c[2],d=p&&g.childNodes[p];d=++p&&d&&d[m]||(f=p=0)||h.pop();)if(1===d.nodeType&&++f&&d===t){u[e]=[W,p,f];break}}else if(y&&(c=(t[I]||(t[I]={}))[e])&&c[0]===W)f=c[1];else for(;(d=++p&&d&&d[m]||(f=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++f||(y&&((d[I]||(d[I]={}))[e]=[W,f]),d!==t)););return f-=i,f===r||f%r===0&&f/r>=0}}},PSEUDO:function(e,t){var n,i=_.pseudos[e]||_.setFilters[e.toLowerCase()]||o.error("unsupported pseudo: "+e);return i[I]?i(t):i.length>1?(n=[e,e,"",t],_.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,n){for(var r,o=i(e,t),a=o.length;a--;)r=tt.call(e,o[a]),e[r]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:r(function(e){var t=[],n=[],i=S(e.replace(lt,"$1"));return i[I]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),!n.pop()}}),has:r(function(e){return function(t){return o(e,t).length>0}}),contains:r(function(e){return function(t){return(t.textContent||t.innerText||N(t)).indexOf(e)>-1}}),lang:r(function(e){return ft.test(e||"")||o.error("unsupported lang: "+e),e=e.replace(xt,wt).toLowerCase(),function(t){var n;do if(n=L?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(e){var t=window.location&&window.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===D},focus:function(e){return e===B.activeElement&&(!B.hasFocus||B.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!_.pseudos.empty(e)},header:function(e){return yt.test(e.nodeName)},input:function(e){return vt.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:c(function(){return[0]}),last:c(function(e,t){return[t-1]}),eq:c(function(e,t,n){return[0>n?n+t:n]}),even:c(function(e,t){for(var n=0;t>n;n+=2)e.push(n);return e}),odd:c(function(e,t){for(var n=1;t>n;n+=2)e.push(n);return e}),lt:c(function(e,t,n){for(var r=0>n?n+t:n;--r>=0;)e.push(r);return e}),gt:c(function(e,t,n){for(var r=0>n?n+t:n;++rn;n++)t[n]=e[n];return t}function f(e,t){var n;if(t.indexOf)return t.indexOf(e);for(n=t.length;n--;)if(t[n]===e)return n;return-1}function p(e){return null===e||e===t?"":(""+e).replace(N,"")}function h(e,t){var n,r,i,o,a;if(e)if(n=e.length,n===o){for(r in e)if(e.hasOwnProperty(r)&&(a=e[r],t.call(a,a,r)===!1))break}else for(i=0;n>i&&(a=e[i],t.call(a,a,r)!==!1);i++);return e}function m(e,n,r){for(var i=[],o=e[n];o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!c(o).is(r));)1===o.nodeType&&i.push(o),o=o[n];return i}function g(e,t,n,r){for(var i=[];e;e=e[n])r&&e.nodeType!==r||e===t||i.push(e);return i}var v=document,y=Array.prototype.push,b=Array.prototype.slice,C=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,x=e.Event,w=l("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom"),_=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)},N=/^\s*|\s*$/g;return c.fn=c.prototype={constructor:c,selector:"",length:0,init:function(e,t){var n=this,r,a;if(!e)return n;if(e.nodeType)return n.context=n[0]=e,n.length=1,n;if(i(e)){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:C.exec(e),!r)return c(t||document).find(e);if(r[1])for(a=o(e).firstChild;a;)this.add(a),a=a.nextSibling;else{if(a=v.getElementById(r[2]),a.id!==r[2])return n.find(e);n.length=1,n[0]=a}}else this.add(e);return n},toArray:function(){return d(this)},add:function(e){var t=this;return _(e)?y.apply(t,e):e instanceof c?t.add(e.toArray()):y.call(t,e),t},attr:function(e,n){var i=this;if("object"==typeof e)h(e,function(e,t){i.attr(t,e)});else{if(!r(n))return i[0]&&1===i[0].nodeType?i[0].getAttribute(e):t;this.each(function(){1===this.nodeType&&this.setAttribute(e,n)})}return i},css:function(e,n){var i=this;if("object"==typeof e)h(e,function(e,t){i.css(t,e)});else{if(e=e.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),!r(n))return i[0]?i[0].style[e]:t;"number"!=typeof n||w[e]||(n+="px"),i.each(function(){var t=this.style;"opacity"===e&&this.runtimeStyle&&"undefined"==typeof this.runtimeStyle.opacity&&(t.filter=""===n?"":"alpha(opacity="+100*n+")");try{t[e]=n}catch(r){}})}return i},remove:function(){for(var e=this,t,n=this.length;n--;)t=e[n],x.clean(t),t.parentNode&&t.parentNode.removeChild(t);return this},empty:function(){for(var e=this,t,n=this.length;n--;)for(t=e[n];t.firstChild;)t.removeChild(t.firstChild);return this},html:function(e){var t=this,n;if(r(e)){for(n=t.length;n--;)t[n].innerHTML=e;return t}return t[0]?t[0].innerHTML:""},text:function(e){var t=this,n;if(r(e)){for(n=t.length;n--;)t[n].innerText=t[0].textContent=e;return t}return t[0]?t[0].innerText||t[0].textContent:""},append:function(){return a(this,arguments,function(e){1===this.nodeType&&this.appendChild(e)})},prepend:function(){return a(this,arguments,function(e){1===this.nodeType&&this.insertBefore(e,this.firstChild)})},before:function(){var e=this;return e[0]&&e[0].parentNode?a(e,arguments,function(e){this.parentNode.insertBefore(e,this.nextSibling)}):e},after:function(){var e=this;return e[0]&&e[0].parentNode?a(e,arguments,function(e){this.parentNode.insertBefore(e,this)}):e},appendTo:function(e){return c(e).append(this),this},addClass:function(e){return this.toggleClass(e,!0)},removeClass:function(e){return this.toggleClass(e,!1)},toggleClass:function(e,t){var n=this;return-1!==e.indexOf(" ")?h(e.split(" "),function(){n.toggleClass(this,t)}):n.each(function(n){var r;s(n,e)!==t&&(r=n.className,t?n.className+=r?" "+e:e:n.className=p((" "+r+" ").replace(" "+e+" "," ")))}),n},hasClass:function(e){return s(this[0],e)},each:function(e){return h(this,e)},on:function(e,t){return this.each(function(){x.bind(this,e,t)})},off:function(e,t){return this.each(function(){x.unbind(this,e,t)})},show:function(){return this.css("display","")},hide:function(){return this.css("display","none")},slice:function(){return new c(b.apply(this,arguments))},eq:function(e){return-1===e?this.slice(e):this.slice(e,+e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},replaceWith:function(e){var t=this;return t[0]&&t[0].parentNode.replaceChild(c(e)[0],t[0]),t},wrap:function(e){return e=c(e)[0],this.each(function(){var t=this,n=e.cloneNode(!1);t.parentNode.insertBefore(n,t),n.appendChild(t)})},unwrap:function(){return this.each(function(){for(var e=this,t=e.firstChild,n;t;)n=t,t=t.nextSibling,e.parentNode.insertBefore(n,e)})},clone:function(){var e=[];return this.each(function(){e.push(this.cloneNode(!0))}),c(e)},find:function(e){var t,n,r=[];for(t=0,n=this.length;n>t;t++)c.find(e,this[t],r);return c(r)},push:y,sort:[].sort,splice:[].splice},u(c,{extend:u,toArray:d,inArray:f,isArray:_,each:h,trim:p,makeMap:l,find:n,expr:n.selectors,unique:n.uniqueSort,text:n.getText,isXMLDoc:n.isXML,contains:n.contains,filter:function(e,t,n){return n&&(e=":not("+e+")"),t=1===t.length?c.find.matchesSelector(t[0],e)?[t[0]]:[]:c.find.matches(e,t)}}),h({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return m(e,"parentNode")},parentsUntil:function(e,t){return m(e,"parentNode",t)},next:function(e){return g(e,"nextSibling",1)},prev:function(e){return g(e,"previousSibling",1)},nextNodes:function(e){return g(e,"nextSibling")},prevNodes:function(e){return g(e,"previousSibling")},children:function(e){return g(e.firstChild,"nextSibling",1)},contents:function(e){return d(("iframe"===e.nodeName?e.contentDocument||e.contentWindow.document:e).childNodes)}},function(e,t){c.fn[e]=function(n){var r=this,i;if(r.length>1)throw new Error("DomQuery only supports traverse functions on a single node.");return r[0]&&(i=t(r[0],n)),i=c(i),n&&"parentsUntil"!==e?i.filter(n):i}}),c.fn.filter=function(e){return c.filter(e)},c.fn.is=function(e){return!!e&&this.filter(e).length>0},c.fn.init.prototype=c.fn,c}),r(d,[],function(){return function(e,t){function n(e,t,n,r){function i(e){return e=parseInt(e,10).toString(16),e.length>1?e:"0"+e +}return"#"+i(t)+i(n)+i(r)}var r=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,i=/(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,o=/\s*([^:]+):\s*([^;]+);?/g,a=/\s+$/,s,l,c={},u,d="\ufeff";for(e=e||{},u=("\\\" \\' \\; \\: ; : "+d).split(" "),l=0;l-1&&n||(m[e+t]=-1==l?s[0]:s.join(" "),delete m[e+"-top"+t],delete m[e+"-right"+t],delete m[e+"-bottom"+t],delete m[e+"-left"+t])}}function u(e){var t=m[e],n;if(t){for(t=t.split(" "),n=t.length;n--;)if(t[n]!==t[0])return!1;return m[e]=t[0],!0}}function d(e,t,n,r){u(t)&&u(n)&&u(r)&&(m[e]=m[t]+" "+m[n]+" "+m[r],delete m[t],delete m[n],delete m[r])}function f(e){return b=!0,c[e]}function p(e,t){return b&&(e=e.replace(/\uFEFF[0-9]/g,function(e){return c[e]})),t||(e=e.replace(/\\([\'\";:])/g,"$1")),e}function h(t,n,r,i,o,a){if(o=o||a)return o=p(o),"'"+o.replace(/\'/g,"\\'")+"'";if(n=p(n||r||i),!e.allow_script_urls){var s=n.replace(/[\s\r\n]+/,"");if(/(java|vb)script:/i.test(s))return"";if(!e.allow_svg_data_urls&&/^data:image\/svg/i.test(s))return""}return C&&(n=C.call(x,n,"style")),"url('"+n.replace(/\'/g,"\\'")+"')"}var m={},g,v,y,b,C=e.url_converter,x=e.url_converter_scope||this;if(t){for(t=t.replace(/[\u0000-\u001F]/g,""),t=t.replace(/\\[\"\';:\uFEFF]/g,f).replace(/\"[^\"]+\"|\'[^\']+\'/g,function(e){return e.replace(/[;:]/g,f)});g=o.exec(t);){if(v=g[1].replace(a,"").toLowerCase(),y=g[2].replace(a,""),y=y.replace(/\\[0-9a-f]+/g,function(e){return String.fromCharCode(parseInt(e.substr(1),16))}),v&&y.length>0){if(!e.allow_script_urls&&("behavior"==v||/expression\s*\(|\/\*|\*\//.test(y)))continue;"font-weight"===v&&"700"===y?y="bold":("color"===v||"background-color"===v)&&(y=y.toLowerCase()),y=y.replace(r,n),y=y.replace(i,h),m[v]=b?p(y,!0):y}o.lastIndex=g.index+g[0].length}s("border","",!0),s("border","-width"),s("border","-color"),s("border","-style"),s("padding",""),s("margin",""),d("border","border-width","border-style","border-color"),"medium none"===m.border&&delete m.border,"none"===m["border-image"]&&delete m["border-image"]}return m},serialize:function(e,n){function r(n){var r,o,a,l;if(r=t.styles[n])for(o=0,a=r.length;a>o;o++)n=r[o],l=e[n],l!==s&&l.length>0&&(i+=(i.length>0?" ":"")+n+": "+l+";")}var i="",o,a;if(n&&t&&t.styles)r("*"),r(n);else for(o in e)a=e[o],a!==s&&a.length>0&&(i+=(i.length>0?" ":"")+o+": "+a+";");return i}}}}),r(f,[],function(){return function(e,t){function n(e,n,r,i){var o,a;if(e){if(!i&&e[n])return e[n];if(e!=t){if(o=e[r])return o;for(a=e.parentNode;a&&a!=t;a=a.parentNode)if(o=a[r])return o}}}var r=e;this.current=function(){return r},this.next=function(e){return r=n(r,"firstChild","nextSibling",e)},this.prev=function(e){return r=n(r,"lastChild","previousSibling",e)}}}),r(p,[],function(){function e(e){return null===e||e===t?"":(""+e).replace(m,"")}function n(e,n){return n?"array"==n&&g(e)?!0:typeof e==n:e!==t}function r(e){var t=[],n,r;for(n=0,r=e.length;r>n;n++)t[n]=e[n];return t}function i(e,t,n){var r;for(e=e||[],t=t||",","string"==typeof e&&(e=e.split(t)),n=n||{},r=e.length;r--;)n[e[r]]={};return n}function o(e,n,r){var i,o;if(!e)return 0;if(r=r||e,e.length!==t){for(i=0,o=e.length;o>i;i++)if(n.call(r,e[i],i,e)===!1)return 0}else for(i in e)if(e.hasOwnProperty(i)&&n.call(r,e[i],i,e)===!1)return 0;return 1}function a(e,t){var n=[];return o(e,function(e){n.push(t(e))}),n}function s(e,t){var n=[];return o(e,function(e){(!t||t(e))&&n.push(e)}),n}function l(e,t,n){var r=this,i,o,a,s,l,c=0;if(e=/^((static) )?([\w.]+)(:([\w.]+))?/.exec(e),a=e[3].match(/(^|\.)(\w+)$/i)[2],o=r.createNS(e[3].replace(/\.\w+$/,""),n),!o[a]){if("static"==e[2])return o[a]=t,void(this.onCreate&&this.onCreate(e[2],e[3],o[a]));t[a]||(t[a]=function(){},c=1),o[a]=t[a],r.extend(o[a].prototype,t),e[5]&&(i=r.resolve(e[5]).prototype,s=e[5].match(/\.(\w+)$/i)[1],l=o[a],o[a]=c?function(){return i[s].apply(this,arguments)}:function(){return this.parent=i[s],l.apply(this,arguments)},o[a].prototype[a]=o[a],r.each(i,function(e,t){o[a].prototype[t]=i[t]}),r.each(t,function(e,t){i[t]?o[a].prototype[t]=function(){return this.parent=i[t],e.apply(this,arguments)}:t!=a&&(o[a].prototype[t]=e)})),r.each(t["static"],function(e,t){o[a][t]=e})}}function c(e,t){var n,r;if(e)for(n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}function u(e,n){var r,i,o,a=arguments,s;for(r=1,i=a.length;i>r;r++){n=a[r];for(o in n)n.hasOwnProperty(o)&&(s=n[o],s!==t&&(e[o]=s))}return e}function d(e,t,n,r){r=r||this,e&&(n&&(e=e[n]),o(e,function(e,i){return t.call(r,e,i,n)===!1?!1:void d(e,t,n,r)}))}function f(e,t){var n,r;for(t=t||window,e=e.split("."),n=0;nn&&(t=t[e[n]],t);n++);return t}function h(t,r){return!t||n(t,"array")?t:a(t.split(r||","),e)}var m=/^\s*|\s*$/g,g=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)};return{trim:e,isArray:g,is:n,toArray:r,makeMap:i,each:o,map:a,grep:s,inArray:c,extend:u,create:l,walk:d,createNS:f,resolve:p,explode:h}}),r(h,[p],function(e){function t(n){function r(){return H.createDocumentFragment()}function i(e,t){_(F,e,t)}function o(e,t){_(z,e,t)}function a(e){i(e.parentNode,j(e))}function s(e){i(e.parentNode,j(e)+1)}function l(e){o(e.parentNode,j(e))}function c(e){o(e.parentNode,j(e)+1)}function u(e){e?(M[U]=M[V],M[q]=M[W]):(M[V]=M[U],M[W]=M[q]),M.collapsed=F}function d(e){a(e),c(e)}function f(e){i(e,0),o(e,1===e.nodeType?e.childNodes.length:e.nodeValue.length)}function p(e,t){var n=M[V],r=M[W],i=M[U],o=M[q],a=t.startContainer,s=t.startOffset,l=t.endContainer,c=t.endOffset;return 0===e?w(n,r,a,s):1===e?w(i,o,a,s):2===e?w(i,o,l,c):3===e?w(n,r,l,c):void 0}function h(){N(I)}function m(){return N(P)}function g(){return N(O)}function v(e){var t=this[V],r=this[W],i,o;3!==t.nodeType&&4!==t.nodeType||!t.nodeValue?(t.childNodes.length>0&&(o=t.childNodes[r]),o?t.insertBefore(e,o):3==t.nodeType?n.insertAfter(e,t):t.appendChild(e)):r?r>=t.nodeValue.length?n.insertAfter(e,t):(i=t.splitText(r),t.parentNode.insertBefore(e,i)):t.parentNode.insertBefore(e,t)}function y(e){var t=M.extractContents();M.insertNode(e),e.appendChild(t),M.selectNode(e)}function b(){return $(new t(n),{startContainer:M[V],startOffset:M[W],endContainer:M[U],endOffset:M[q],collapsed:M.collapsed,commonAncestorContainer:M.commonAncestorContainer})}function C(e,t){var n;if(3==e.nodeType)return e;if(0>t)return e;for(n=e.firstChild;n&&t>0;)--t,n=n.nextSibling;return n?n:e}function x(){return M[V]==M[U]&&M[W]==M[q]}function w(e,t,r,i){var o,a,s,l,c,u;if(e==r)return t==i?0:i>t?-1:1;for(o=r;o&&o.parentNode!=e;)o=o.parentNode;if(o){for(a=0,s=e.firstChild;s!=o&&t>a;)a++,s=s.nextSibling;return a>=t?-1:1}for(o=e;o&&o.parentNode!=r;)o=o.parentNode;if(o){for(a=0,s=r.firstChild;s!=o&&i>a;)a++,s=s.nextSibling;return i>a?-1:1}for(l=n.findCommonAncestor(e,r),c=e;c&&c.parentNode!=l;)c=c.parentNode;for(c||(c=l),u=r;u&&u.parentNode!=l;)u=u.parentNode;if(u||(u=l),c==u)return 0;for(s=l.firstChild;s;){if(s==c)return-1;if(s==u)return 1;s=s.nextSibling}}function _(e,t,r){var i,o;for(e?(M[V]=t,M[W]=r):(M[U]=t,M[q]=r),i=M[U];i.parentNode;)i=i.parentNode;for(o=M[V];o.parentNode;)o=o.parentNode;o==i?w(M[V],M[W],M[U],M[q])>0&&M.collapse(e):M.collapse(e),M.collapsed=x(),M.commonAncestorContainer=n.findCommonAncestor(M[V],M[U])}function N(e){var t,n=0,r=0,i,o,a,s,l,c;if(M[V]==M[U])return E(e);for(t=M[U],i=t.parentNode;i;t=i,i=i.parentNode){if(i==M[V])return S(t,e);++n}for(t=M[V],i=t.parentNode;i;t=i,i=i.parentNode){if(i==M[U])return k(t,e);++r}for(o=r-n,a=M[V];o>0;)a=a.parentNode,o--;for(s=M[U];0>o;)s=s.parentNode,o++;for(l=a.parentNode,c=s.parentNode;l!=c;l=l.parentNode,c=c.parentNode)a=l,s=c;return T(a,s,e)}function E(e){var t,n,i,o,a,s,l,c,u;if(e!=I&&(t=r()),M[W]==M[q])return t;if(3==M[V].nodeType){if(n=M[V].nodeValue,i=n.substring(M[W],M[q]),e!=O&&(o=M[V],c=M[W],u=M[q]-M[W],0===c&&u>=o.nodeValue.length-1?o.parentNode.removeChild(o):o.deleteData(c,u),M.collapse(F)),e==I)return;return i.length>0&&t.appendChild(H.createTextNode(i)),t}for(o=C(M[V],M[W]),a=M[q]-M[W];o&&a>0;)s=o.nextSibling,l=D(o,e),t&&t.appendChild(l),--a,o=s;return e!=O&&M.collapse(F),t}function S(e,t){var n,i,o,a,s,l;if(t!=I&&(n=r()),i=R(e,t),n&&n.appendChild(i),o=j(e),a=o-M[W],0>=a)return t!=O&&(M.setEndBefore(e),M.collapse(z)),n;for(i=e.previousSibling;a>0;)s=i.previousSibling,l=D(i,t),n&&n.insertBefore(l,n.firstChild),--a,i=s;return t!=O&&(M.setEndBefore(e),M.collapse(z)),n}function k(e,t){var n,i,o,a,s,l;for(t!=I&&(n=r()),o=A(e,t),n&&n.appendChild(o),i=j(e),++i,a=M[q]-i,o=e.nextSibling;o&&a>0;)s=o.nextSibling,l=D(o,t),n&&n.appendChild(l),--a,o=s;return t!=O&&(M.setStartAfter(e),M.collapse(F)),n}function T(e,t,n){var i,o,a,s,l,c,u;for(n!=I&&(o=r()),i=A(e,n),o&&o.appendChild(i),a=j(e),s=j(t),++a,l=s-a,c=e.nextSibling;l>0;)u=c.nextSibling,i=D(c,n),o&&o.appendChild(i),c=u,--l;return i=R(t,n),o&&o.appendChild(i),n!=O&&(M.setStartAfter(e),M.collapse(F)),o}function R(e,t){var n=C(M[U],M[q]-1),r,i,o,a,s,l=n!=M[U];if(n==e)return B(n,l,z,t);for(r=n.parentNode,i=B(r,z,z,t);r;){for(;n;)o=n.previousSibling,a=B(n,l,z,t),t!=I&&i.insertBefore(a,i.firstChild),l=F,n=o;if(r==e)return i;n=r.previousSibling,r=r.parentNode,s=B(r,z,z,t),t!=I&&s.appendChild(i),i=s}}function A(e,t){var n=C(M[V],M[W]),r=n!=M[V],i,o,a,s,l;if(n==e)return B(n,r,F,t);for(i=n.parentNode,o=B(i,z,F,t);i;){for(;n;)a=n.nextSibling,s=B(n,r,F,t),t!=I&&o.appendChild(s),r=F,n=a;if(i==e)return o;n=i.nextSibling,i=i.parentNode,l=B(i,z,F,t),t!=I&&l.appendChild(o),o=l}}function B(e,t,r,i){var o,a,s,l,c;if(t)return D(e,i);if(3==e.nodeType){if(o=e.nodeValue,r?(l=M[W],a=o.substring(l),s=o.substring(0,l)):(l=M[q],a=o.substring(0,l),s=o.substring(l)),i!=O&&(e.nodeValue=s),i==I)return;return c=n.clone(e,z),c.nodeValue=a,c}if(i!=I)return n.clone(e,z)}function D(e,t){return t!=I?t==O?n.clone(e,F):e:void e.parentNode.removeChild(e)}function L(){return n.create("body",null,g()).outerText}var M=this,H=n.doc,P=0,O=1,I=2,F=!0,z=!1,W="startOffset",V="startContainer",U="endContainer",q="endOffset",$=e.extend,j=n.nodeIndex;return $(M,{startContainer:H,startOffset:0,endContainer:H,endOffset:0,collapsed:F,commonAncestorContainer:H,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:i,setEnd:o,setStartBefore:a,setStartAfter:s,setEndBefore:l,setEndAfter:c,collapse:u,selectNode:d,selectNodeContents:f,compareBoundaryPoints:p,deleteContents:h,extractContents:m,cloneContents:g,insertNode:v,surroundContents:y,cloneRange:b,toStringIE:L}),M}return t.prototype.toString=function(){return this.toStringIE()},t}),r(m,[p],function(e){function t(e){var t;return t=document.createElement("div"),t.innerHTML=e,t.textContent||t.innerText||e}function n(e,t){var n,r,i,a={};if(e){for(e=e.split(","),t=t||10,n=0;n\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,l=/[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,c=/[<>&\"\']/g,u=/&(#x|#)?([\w]+);/g,d={128:"\u20ac",130:"\u201a",131:"\u0192",132:"\u201e",133:"\u2026",134:"\u2020",135:"\u2021",136:"\u02c6",137:"\u2030",138:"\u0160",139:"\u2039",140:"\u0152",142:"\u017d",145:"\u2018",146:"\u2019",147:"\u201c",148:"\u201d",149:"\u2022",150:"\u2013",151:"\u2014",152:"\u02dc",153:"\u2122",154:"\u0161",155:"\u203a",156:"\u0153",158:"\u017e",159:"\u0178"};o={'"':""","'":"'","<":"<",">":">","&":"&","`":"`"},a={"<":"<",">":">","&":"&",""":'"',"'":"'"},i=n("50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro",32);var f={encodeRaw:function(e,t){return e.replace(t?s:l,function(e){return o[e]||e})},encodeAllRaw:function(e){return(""+e).replace(c,function(e){return o[e]||e})},encodeNumeric:function(e,t){return e.replace(t?s:l,function(e){return e.length>1?"&#"+(1024*(e.charCodeAt(0)-55296)+(e.charCodeAt(1)-56320)+65536)+";":o[e]||"&#"+e.charCodeAt(0)+";"})},encodeNamed:function(e,t,n){return n=n||i,e.replace(t?s:l,function(e){return o[e]||n[e]||e})},getEncodeFunc:function(e,t){function a(e,n){return e.replace(n?s:l,function(e){return o[e]||t[e]||"&#"+e.charCodeAt(0)+";"||e})}function c(e,n){return f.encodeNamed(e,n,t)}return t=n(t)||i,e=r(e.replace(/\+/g,",")),e.named&&e.numeric?a:e.named?t?c:f.encodeNamed:e.numeric?f.encodeNumeric:f.encodeRaw},decode:function(e){return e.replace(u,function(e,n,r){return n?(r=parseInt(r,2===n.length?16:10),r>65535?(r-=65536,String.fromCharCode(55296+(r>>10),56320+(1023&r))):d[r]||String.fromCharCode(r)):a[e]||i[e]||t(e)})}};return f}),r(g,[],function(){var e=navigator,t=e.userAgent,n,r,i,o,a,s,l;n=window.opera&&window.opera.buildNumber,r=/WebKit/.test(t),i=!r&&!n&&/MSIE/gi.test(t)&&/Explorer/gi.test(e.appName),i=i&&/MSIE (\w+)\./.exec(t)[1],o=-1==t.indexOf("Trident/")||-1==t.indexOf("rv:")&&-1==e.appName.indexOf("Netscape")?!1:11,i=i||o,a=!r&&!o&&/Gecko/.test(t),s=-1!=t.indexOf("Mac"),l=/(iPad|iPhone)/.test(t);var c=!l||t.match(/AppleWebKit\/(\d*)/)[1]>=534;return{opera:n,webkit:r,ie:i,gecko:a,mac:s,iOS:l,contentEditable:c,transparentSrc:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",caretAfter:8!=i,range:window.getSelection&&"Range"in window,documentMode:i?document.documentMode||7:10}}),r(v,[],function(){return function(e,t){function n(t){e.getElementsByTagName("head")[0].appendChild(t)}function r(t,r,s){function l(){for(var e=v.passed,t=e.length;t--;)e[t]();v.status=2,v.passed=[],v.failed=[]}function c(){for(var e=v.failed,t=e.length;t--;)e[t]();v.status=3,v.passed=[],v.failed=[]}function u(){var e=navigator.userAgent.match(/WebKit\/(\d*)/);return!!(e&&e[1]<536)}function d(e,t){e()||((new Date).getTime()-g0)return m=e.createElement("style"),m.textContent='@import "'+t+'"',p(),void n(m);f()}n(h),h.href=t}}var i=0,o={},a;t=t||{},a=t.maxLoadTime||5e3,this.load=r}}),r(y,[c,d,l,f,h,m,g,p,v],function(e,n,r,i,o,a,s,l,c){function u(e,t){var i=this,o;i.doc=e,i.win=window,i.files={},i.counter=0,i.stdMode=!v||e.documentMode>=8,i.boxModel=!v||"CSS1Compat"==e.compatMode||i.stdMode,i.hasOuterHTML="outerHTML"in e.createElement("a"),i.styleSheetLoader=new c(e),this.boundEvents=[],i.settings=t=m({keep_values:!1,hex_colors:1},t),i.schema=t.schema,i.styles=new n({url_converter:t.url_converter,url_converter_scope:t.url_converter_scope},t.schema),i.fixDoc(e),i.events=t.ownEvents?new r(t.proxy):r.Event,o=t.schema?t.schema.getBlockElements():{},i.isBlock=function(e){if(!e)return!1;var t=e.nodeType;return t?!(1!==t||!o[e.nodeName]):!!o[e]}}var d=l.each,f=l.is,p=l.grep,h=l.trim,m=l.extend,g=s.webkit,v=s.ie,y=/^([a-z0-9],?)+$/i,b=/^[ \t\r\n]*$/,C=l.makeMap("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom"," ");return u.prototype={root:null,props:{"for":"htmlFor","class":"className",className:"className",checked:"checked",disabled:"disabled",maxlength:"maxLength",readonly:"readOnly",selected:"selected",value:"value",id:"id",name:"name",type:"type"},fixDoc:function(e){var t=this.settings,n;if(v&&t.schema){"abbr article aside audio canvas details figcaption figure footer header hgroup mark menu meter nav output progress section summary time video".replace(/\w+/g,function(t){e.createElement(t)});for(n in t.schema.getCustomElements())e.createElement(n)}},clone:function(e,t){var n=this,r,i;return!v||1!==e.nodeType||t?e.cloneNode(t):(i=n.doc,t?r.firstChild:(r=i.createElement(e.nodeName),d(n.getAttribs(e),function(t){n.setAttrib(r,t.nodeName,n.getAttrib(e,t.nodeName))}),r))},getRoot:function(){var e=this;return e.get(e.settings.root_element)||e.doc.body},getViewPort:function(e){var t,n;return e=e?e:this.win,t=e.document,n=this.boxModel?t.documentElement:t.body,{x:e.pageXOffset||n.scrollLeft,y:e.pageYOffset||n.scrollTop,w:e.innerWidth||n.clientWidth,h:e.innerHeight||n.clientHeight}},getRect:function(e){var t=this,n,r;return e=t.get(e),n=t.getPos(e),r=t.getSize(e),{x:n.x,y:n.y,w:r.w,h:r.h}},getSize:function(e){var t=this,n,r;return e=t.get(e),n=t.getStyle(e,"width"),r=t.getStyle(e,"height"),-1===n.indexOf("px")&&(n=0),-1===r.indexOf("px")&&(r=0),{w:parseInt(n,10)||e.offsetWidth||e.clientWidth,h:parseInt(r,10)||e.offsetHeight||e.clientHeight}},getParent:function(e,t,n){return this.getParents(e,t,n,!1)},getParents:function(e,n,r,i){var o=this,a,s=[];for(e=o.get(e),i=i===t,r=r||("BODY"!=o.getRoot().nodeName?o.getRoot().parentNode:null),f(n,"string")&&(a=n,n="*"===n?function(e){return 1==e.nodeType}:function(e){return o.is(e,a)});e&&e!=r&&e.nodeType&&9!==e.nodeType;){if(!n||n(e)){if(!i)return e;s.push(e)}e=e.parentNode}return i?s:null},get:function(e){var t;return e&&this.doc&&"string"==typeof e&&(t=e,e=this.doc.getElementById(e),e&&e.id!==t)?this.doc.getElementsByName(t)[1]:e},getNext:function(e,t){return this._findSib(e,t,"nextSibling")},getPrev:function(e,t){return this._findSib(e,t,"previousSibling")},select:function(t,n){var r=this;return e(t,r.get(n)||r.get(r.settings.root_element)||r.doc,[])},is:function(n,r){var i;if(n.length===t){if("*"===r)return 1==n.nodeType;if(y.test(r)){for(r=r.toLowerCase().split(/,/),n=n.nodeName.toLowerCase(),i=r.length-1;i>=0;i--)if(r[i]==n)return!0;return!1}}if(n.nodeType&&1!=n.nodeType)return!1;var o=n.nodeType?[n]:n;return e(r,o[0].ownerDocument||o[0],null,o).length>0},add:function(e,t,n,r,i){var o=this;return this.run(e,function(e){var a;return a=f(t,"string")?o.doc.createElement(t):t,o.setAttribs(a,n),r&&(r.nodeType?a.appendChild(r):o.setHTML(a,r)),i?a:e.appendChild(a)})},create:function(e,t,n){return this.add(this.doc.createElement(e),e,t,n,1)},createHTML:function(e,t,n){var r="",i;r+="<"+e;for(i in t)t.hasOwnProperty(i)&&null!==t[i]&&(r+=" "+i+'="'+this.encode(t[i])+'"');return"undefined"!=typeof n?r+">"+n+"":r+" />"},createFragment:function(e){var t,n,r=this.doc,i;for(i=r.createElement("div"),t=r.createDocumentFragment(),e&&(i.innerHTML=e);n=i.firstChild;)t.appendChild(n);return t},remove:function(e,t){return this.run(e,function(e){var n,r=e.parentNode;if(!r)return null;if(t)for(;n=e.firstChild;)!v||3!==n.nodeType||n.nodeValue?r.insertBefore(n,e):e.removeChild(n);return r.removeChild(e)})},setStyle:function(e,t,n){return this.run(e,function(e){var r=this,i,o;if(t)if("string"==typeof t){i=e.style,t=t.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),"number"!=typeof n||C[t]||(n+="px"),"opacity"===t&&e.runtimeStyle&&"undefined"==typeof e.runtimeStyle.opacity&&(i.filter=""===n?"":"alpha(opacity="+100*n+")"),"float"==t&&(t="cssFloat"in e.style?"cssFloat":"styleFloat");try{i[t]=n}catch(a){}r.settings.update_styles&&e.removeAttribute("data-mce-style")}else for(o in t)r.setStyle(e,o,t[o])})},getStyle:function(e,n,r){if(e=this.get(e)){if(this.doc.defaultView&&r){n=n.replace(/[A-Z]/g,function(e){return"-"+e});try{return this.doc.defaultView.getComputedStyle(e,null).getPropertyValue(n)}catch(i){return null}}return n=n.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),"float"==n&&(n=v?"styleFloat":"cssFloat"),e.currentStyle&&r?e.currentStyle[n]:e.style?e.style[n]:t}},setStyles:function(e,t){this.setStyle(e,t)},css:function(e,t,n){this.setStyle(e,t,n)},removeAllAttribs:function(e){return this.run(e,function(e){var t,n=e.attributes;for(t=n.length-1;t>=0;t--)e.removeAttributeNode(n.item(t))})},setAttrib:function(e,t,n){var r=this;if(e&&t)return this.run(e,function(e){var i=r.settings,o=e.getAttribute(t);if(null!==n)switch(t){case"style":if(!f(n,"string"))return void d(n,function(t,n){r.setStyle(e,n,t)});i.keep_values&&(n?e.setAttribute("data-mce-style",n,2):e.removeAttribute("data-mce-style",2)),e.style.cssText=n;break;case"class":e.className=n||"";break;case"src":case"href":i.keep_values&&(i.url_converter&&(n=i.url_converter.call(i.url_converter_scope||r,n,t,e)),r.setAttrib(e,"data-mce-"+t,n,2));break;case"shape":e.setAttribute("data-mce-style",n)}f(n)&&null!==n&&0!==n.length?e.setAttribute(t,""+n,2):e.removeAttribute(t,2),o!=n&&i.onSetAttrib&&i.onSetAttrib({attrElm:e,attrName:t,attrValue:n})})},setAttribs:function(e,t){var n=this;return this.run(e,function(e){d(t,function(t,r){n.setAttrib(e,r,t)})})},getAttrib:function(e,t,n){var r,i=this,o;if(e=i.get(e),!e||1!==e.nodeType)return n===o?!1:n;if(f(n)||(n=""),/^(src|href|style|coords|shape)$/.test(t)&&(r=e.getAttribute("data-mce-"+t)))return r;if(v&&i.props[t]&&(r=e[i.props[t]],r=r&&r.nodeValue?r.nodeValue:r),r||(r=e.getAttribute(t,2)),/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(t))return e[i.props[t]]===!0&&""===r?t:r?t:"";if("FORM"===e.nodeName&&e.getAttributeNode(t))return e.getAttributeNode(t).nodeValue;if("style"===t&&(r=r||e.style.cssText,r&&(r=i.serializeStyle(i.parseStyle(r),e.nodeName),i.settings.keep_values&&e.setAttribute("data-mce-style",r))),g&&"class"===t&&r&&(r=r.replace(/(apple|webkit)\-[a-z\-]+/gi,"")),v)switch(t){case"rowspan":case"colspan":1===r&&(r="");break;case"size":("+0"===r||20===r||0===r)&&(r="");break;case"width":case"height":case"vspace":case"checked":case"disabled":case"readonly":0===r&&(r="");break;case"hspace":-1===r&&(r="");break;case"maxlength":case"tabindex":(32768===r||2147483647===r||"32768"===r)&&(r="");break;case"multiple":case"compact":case"noshade":case"nowrap":return 65535===r?t:n;case"shape":r=r.toLowerCase();break;default:0===t.indexOf("on")&&r&&(r=(""+r).replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/,"$1"))}return r!==o&&null!==r&&""!==r?""+r:n},getPos:function(e,t){var n=this,r=0,i=0,o,a=n.doc,s;if(e=n.get(e),t=t||a.body,e){if(t===a.body&&e.getBoundingClientRect)return s=e.getBoundingClientRect(),t=n.boxModel?a.documentElement:a.body,r=s.left+(a.documentElement.scrollLeft||a.body.scrollLeft)-t.clientLeft,i=s.top+(a.documentElement.scrollTop||a.body.scrollTop)-t.clientTop,{x:r,y:i};for(o=e;o&&o!=t&&o.nodeType;)r+=o.offsetLeft||0,i+=o.offsetTop||0,o=o.offsetParent;for(o=e.parentNode;o&&o!=t&&o.nodeType;)r-=o.scrollLeft||0,i-=o.scrollTop||0,o=o.parentNode}return{x:r,y:i}},parseStyle:function(e){return this.styles.parse(e)},serializeStyle:function(e,t){return this.styles.serialize(e,t)},addStyle:function(e){var t=this,n=t.doc,r,i;if(t!==u.DOM&&n===document){var o=u.DOM.addedStyles;if(o=o||[],o[e])return;o[e]=!0,u.DOM.addedStyles=o}i=n.getElementById("mceDefaultStyles"),i||(i=n.createElement("style"),i.id="mceDefaultStyles",i.type="text/css",r=n.getElementsByTagName("head")[0],r.firstChild?r.insertBefore(i,r.firstChild):r.appendChild(i)),i.styleSheet?i.styleSheet.cssText+=e:i.appendChild(n.createTextNode(e))},loadCSS:function(e){var t=this,n=t.doc,r;return t!==u.DOM&&n===document?void u.DOM.loadCSS(e):(e||(e=""),r=n.getElementsByTagName("head")[0],void d(e.split(","),function(e){var i;t.files[e]||(t.files[e]=!0,i=t.create("link",{rel:"stylesheet",href:e}),v&&n.documentMode&&n.recalc&&(i.onload=function(){n.recalc&&n.recalc(),i.onload=null}),r.appendChild(i))}))},addClass:function(e,t){return this.run(e,function(e){var n;return t?this.hasClass(e,t)?e.className:(n=this.removeClass(e,t),e.className=n=(""!==n?n+" ":"")+t,n):0})},removeClass:function(e,t){var n=this,r;return n.run(e,function(e){var i;return n.hasClass(e,t)?(r||(r=new RegExp("(^|\\s+)"+t+"(\\s+|$)","g")),i=e.className.replace(r," "),i=h(" "!=i?i:""),e.className=i,i||(e.removeAttribute("class"),e.removeAttribute("className")),i):e.className})},hasClass:function(e,t){return e=this.get(e),e&&t?-1!==(" "+e.className+" ").indexOf(" "+t+" "):!1},toggleClass:function(e,n,r){r=r===t?!this.hasClass(e,n):r,this.hasClass(e,n)!==r&&(r?this.addClass(e,n):this.removeClass(e,n))},show:function(e){return this.setStyle(e,"display","block")},hide:function(e){return this.setStyle(e,"display","none")},isHidden:function(e){return e=this.get(e),!e||"none"==e.style.display||"none"==this.getStyle(e,"display")},uniqueId:function(e){return(e?e:"mce_")+this.counter++},setHTML:function(e,t){var n=this;return n.run(e,function(e){if(v){for(;e.firstChild;)e.removeChild(e.firstChild);try{e.innerHTML="
"+t,e.removeChild(e.firstChild)}catch(r){var i=n.create("div");i.innerHTML="
"+t,d(p(i.childNodes),function(t,n){n&&e.canHaveHTML&&e.appendChild(t)})}}else e.innerHTML=t;return t})},getOuterHTML:function(e){var t,n=this;return(e=n.get(e))?1===e.nodeType&&n.hasOuterHTML?e.outerHTML:(t=(e.ownerDocument||n.doc).createElement("body"),t.appendChild(e.cloneNode(!0)),t.innerHTML):null},setOuterHTML:function(e,t,n){var r=this;return r.run(e,function(e){function i(){var i,o;for(o=n.createElement("body"),o.innerHTML=t,i=o.lastChild;i;)r.insertAfter(i.cloneNode(!0),e),i=i.previousSibling;r.remove(e)}if(1==e.nodeType)if(n=n||e.ownerDocument||r.doc,v)try{1==e.nodeType&&r.hasOuterHTML?e.outerHTML=t:i()}catch(o){i()}else i()})},decode:a.decode,encode:a.encodeAllRaw,insertAfter:function(e,t){return t=this.get(t),this.run(e,function(e){var n,r;return n=t.parentNode,r=t.nextSibling,r?n.insertBefore(e,r):n.appendChild(e),e})},replace:function(e,t,n){var r=this;return r.run(t,function(t){return f(t,"array")&&(e=e.cloneNode(!0)),n&&d(p(t.childNodes),function(t){e.appendChild(t)}),t.parentNode.replaceChild(e,t)})},rename:function(e,t){var n=this,r;return e.nodeName!=t.toUpperCase()&&(r=n.create(t),d(n.getAttribs(e),function(t){n.setAttrib(r,t.nodeName,n.getAttrib(e,t.nodeName))}),n.replace(r,e,1)),r||e},findCommonAncestor:function(e,t){for(var n=e,r;n;){for(r=t;r&&n!=r;)r=r.parentNode;if(n==r)break;n=n.parentNode}return!n&&e.ownerDocument?e.ownerDocument.documentElement:n},toHex:function(e){return this.styles.toHex(l.trim(e))},run:function(e,t,n){var r=this,i;return"string"==typeof e&&(e=r.get(e)),e?(n=n||this,e.nodeType||!e.length&&0!==e.length?t.call(n,e):(i=[],d(e,function(e,o){e&&("string"==typeof e&&(e=r.get(e)),i.push(t.call(n,e,o)))}),i)):!1},getAttribs:function(e){var t;if(e=this.get(e),!e)return[];if(v){if(t=[],"OBJECT"==e.nodeName)return e.attributes;"OPTION"===e.nodeName&&this.getAttrib(e,"selected")&&t.push({specified:1,nodeName:"selected"});var n=/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi;return e.cloneNode(!1).outerHTML.replace(n,"").replace(/[\w:\-]+/gi,function(e){t.push({specified:1,nodeName:e})}),t}return e.attributes},isEmpty:function(e,t){var n=this,r,o,a,s,l,c=0;if(e=e.firstChild){s=new i(e,e.parentNode),t=t||n.schema?n.schema.getNonEmptyElements():null;do{if(a=e.nodeType,1===a){if(e.getAttribute("data-mce-bogus"))continue;if(l=e.nodeName.toLowerCase(),t&&t[l]){if("br"===l){c++;continue}return!1}for(o=n.getAttribs(e),r=o.length;r--;)if(l=o[r].nodeName,"name"===l||"data-mce-bookmark"===l)return!1}if(8==a)return!1;if(3===a&&!b.test(e.nodeValue))return!1}while(e=s.next())}return 1>=c},createRng:function(){var e=this.doc;return e.createRange?e.createRange():new o(this)},nodeIndex:function(e,t){var n=0,r,i;if(e)for(r=e.nodeType,e=e.previousSibling;e;e=e.previousSibling)i=e.nodeType,(!t||3!=i||i!=r&&e.nodeValue.length)&&(n++,r=i);return n},split:function(e,t,n){function r(e){function t(e){var t=e.previousSibling&&"SPAN"==e.previousSibling.nodeName,n=e.nextSibling&&"SPAN"==e.nextSibling.nodeName;return t&&n}var n,o=e.childNodes,a=e.nodeType;if(1!=a||"bookmark"!=e.getAttribute("data-mce-type")){for(n=o.length-1;n>=0;n--)r(o[n]);if(9!=a){if(3==a&&e.nodeValue.length>0){var s=h(e.nodeValue).length;if(!i.isBlock(e.parentNode)||s>0||0===s&&t(e))return}else if(1==a&&(o=e.childNodes,1==o.length&&o[0]&&1==o[0].nodeType&&"bookmark"==o[0].getAttribute("data-mce-type")&&e.parentNode.insertBefore(o[0],e),o.length||/^(br|hr|input|img)$/i.test(e.nodeName)))return;i.remove(e)}return e}}var i=this,o=i.createRng(),a,s,l;return e&&t?(o.setStart(e.parentNode,i.nodeIndex(e)),o.setEnd(t.parentNode,i.nodeIndex(t)),a=o.extractContents(),o=i.createRng(),o.setStart(t.parentNode,i.nodeIndex(t)+1),o.setEnd(e.parentNode,i.nodeIndex(e)+1),s=o.extractContents(),l=e.parentNode,l.insertBefore(r(a),e),n?l.replaceChild(n,t):l.insertBefore(t,e),l.insertBefore(r(s),e),i.remove(e),n||t):void 0},bind:function(e,t,n,r){var i=this;if(l.isArray(e)){for(var o=e.length;o--;)e[o]=i.bind(e[o],t,n,r);return e}return!i.settings.collect||e!==i.doc&&e!==i.win||i.boundEvents.push([e,t,n,r]),i.events.bind(e,t,n,r||i)},unbind:function(e,t,n){var r=this,i;if(l.isArray(e)){for(i=e.length;i--;)e[i]=r.unbind(e[i],t,n);return e}if(r.boundEvents&&(e===r.doc||e===r.win))for(i=r.boundEvents.length;i--;){var o=r.boundEvents[i];e!=o[0]||t&&t!=o[1]||n&&n!=o[2]||this.events.unbind(o[0],o[1],o[2])}return this.events.unbind(e,t,n)},fire:function(e,t,n){return this.events.fire(e,t,n)},getContentEditable:function(e){var t;return e&&1==e.nodeType?(t=e.getAttribute("data-mce-contenteditable"),t&&"inherit"!==t?t:"inherit"!==e.contentEditable?e.contentEditable:null):null},getContentEditableParent:function(e){for(var t=this.getRoot(),n=null;e&&e!==t&&(n=this.getContentEditable(e),null===n);e=e.parentNode);return n},destroy:function(){var t=this;if(t.boundEvents){for(var n=t.boundEvents.length;n--;){var r=t.boundEvents[n]; +this.events.unbind(r[0],r[1],r[2])}t.boundEvents=null}e.setDocument&&e.setDocument(),t.win=t.doc=t.root=t.events=t.frag=null},isChildOf:function(e,t){for(;e;){if(t===e)return!0;e=e.parentNode}return!1},dumpRng:function(e){return"startContainer: "+e.startContainer.nodeName+", startOffset: "+e.startOffset+", endContainer: "+e.endContainer.nodeName+", endOffset: "+e.endOffset},_findSib:function(e,t,n){var r=this,i=t;if(e)for("string"==typeof i&&(i=function(e){return r.is(e,t)}),e=e[n];e;e=e[n])if(i(e))return e;return null}},u.DOM=new u(document),u}),r(b,[y,p],function(e,t){function n(){function e(e,t){function n(){o.remove(s),a&&(a.onreadystatechange=a.onload=a=null),t()}function i(){"undefined"!=typeof console&&console.log&&console.log("Failed to load: "+e)}var o=r,a,s;s=o.uniqueId(),a=document.createElement("script"),a.id=s,a.type="text/javascript",a.src=e,"onreadystatechange"in a?a.onreadystatechange=function(){/loaded|complete/.test(a.readyState)&&n()}:a.onload=n,a.onerror=i,(document.getElementsByTagName("head")[0]||document.body).appendChild(a)}var t=0,n=1,a=2,s={},l=[],c={},u=[],d=0,f;this.isDone=function(e){return s[e]==a},this.markDone=function(e){s[e]=a},this.add=this.load=function(e,n,r){var i=s[e];i==f&&(l.push(e),s[e]=t),n&&(c[e]||(c[e]=[]),c[e].push({func:n,scope:r||this}))},this.loadQueue=function(e,t){this.loadScripts(l,e,t)},this.loadScripts=function(t,r,l){function p(e){i(c[e],function(e){e.func.call(e.scope)}),c[e]=f}var h;u.push({func:r,scope:l||this}),(h=function(){var r=o(t);t.length=0,i(r,function(t){return s[t]==a?void p(t):void(s[t]!=n&&(s[t]=n,d++,e(t,function(){s[t]=a,d--,p(t),h()})))}),d||(i(u,function(e){e.func.call(e.scope)}),u.length=0)})()}}var r=e.DOM,i=t.each,o=t.grep;return n.ScriptLoader=new n,n}),r(C,[b,p],function(e,n){function r(){var e=this;e.items=[],e.urls={},e.lookup={}}var i=n.each;return r.prototype={get:function(e){return this.lookup[e]?this.lookup[e].instance:t},dependencies:function(e){var t;return this.lookup[e]&&(t=this.lookup[e].dependencies),t||[]},requireLangPack:function(t,n){var i=r.language;if(i&&r.languageLoad!==!1){if(n)if(n=","+n+",",-1!=n.indexOf(","+i.substr(0,2)+","))i=i.substr(0,2);else if(-1==n.indexOf(","+i+","))return;e.ScriptLoader.add(this.urls[t]+"/langs/"+i+".js")}},add:function(e,t,n){return this.items.push(t),this.lookup[e]={instance:t,dependencies:n},t},createUrl:function(e,t){return"object"==typeof t?t:{prefix:e.prefix,resource:t,suffix:e.suffix}},addComponents:function(t,n){var r=this.urls[t];i(n,function(t){e.ScriptLoader.add(r+"/"+t)})},load:function(n,o,a,s){function l(){var r=c.dependencies(n);i(r,function(e){var n=c.createUrl(o,e);c.load(n.resource,n,t,t)}),a&&a.call(s?s:e)}var c=this,u=o;c.urls[n]||("object"==typeof o&&(u=o.prefix+o.resource+o.suffix),0!==u.indexOf("/")&&-1==u.indexOf("://")&&(u=r.baseURL+"/"+u),c.urls[n]=u.substring(0,u.lastIndexOf("/")),c.lookup[n]?l():e.ScriptLoader.add(u,l,s))}},r.PluginManager=new r,r.ThemeManager=new r,r}),r(x,[],function(){function e(e,t,n){var r,i,o=n?"lastChild":"firstChild",a=n?"prev":"next";if(e[o])return e[o];if(e!==t){if(r=e[a])return r;for(i=e.parent;i&&i!==t;i=i.parent)if(r=i[a])return r}}function t(e,t){this.name=e,this.type=t,1===t&&(this.attributes=[],this.attributes.map={})}var n=/^[ \t\r\n]*$/,r={"#text":3,"#comment":8,"#cdata":4,"#pi":7,"#doctype":10,"#document-fragment":11};return t.prototype={replace:function(e){var t=this;return e.parent&&e.remove(),t.insert(e,t),t.remove(),t},attr:function(e,t){var n=this,r,i,o;if("string"!=typeof e){for(i in e)n.attr(i,e[i]);return n}if(r=n.attributes){if(t!==o){if(null===t){if(e in r.map)for(delete r.map[e],i=r.length;i--;)if(r[i].name===e)return r=r.splice(i,1),n;return n}if(e in r.map){for(i=r.length;i--;)if(r[i].name===e){r[i].value=t;break}}else r.push({name:e,value:t});return r.map[e]=t,n}return r.map[e]}},clone:function(){var e=this,n=new t(e.name,e.type),r,i,o,a,s;if(o=e.attributes){for(s=[],s.map={},r=0,i=o.length;i>r;r++)a=o[r],"id"!==a.name&&(s[s.length]={name:a.name,value:a.value},s.map[a.name]=a.value);n.attributes=s}return n.value=e.value,n.shortEnded=e.shortEnded,n},wrap:function(e){var t=this;return t.parent.insert(e,t),e.append(t),t},unwrap:function(){var e=this,t,n;for(t=e.firstChild;t;)n=t.next,e.insert(t,e,!0),t=n;e.remove()},remove:function(){var e=this,t=e.parent,n=e.next,r=e.prev;return t&&(t.firstChild===e?(t.firstChild=n,n&&(n.prev=null)):r.next=n,t.lastChild===e?(t.lastChild=r,r&&(r.next=null)):n.prev=r,e.parent=e.next=e.prev=null),e},append:function(e){var t=this,n;return e.parent&&e.remove(),n=t.lastChild,n?(n.next=e,e.prev=n,t.lastChild=e):t.lastChild=t.firstChild=e,e.parent=t,e},insert:function(e,t,n){var r;return e.parent&&e.remove(),r=t.parent||this,n?(t===r.firstChild?r.firstChild=e:t.prev.next=e,e.prev=t.prev,e.next=t,t.prev=e):(t===r.lastChild?r.lastChild=e:t.next.prev=e,e.next=t.next,e.prev=t,t.next=e),e.parent=r,e},getAll:function(t){var n=this,r,i=[];for(r=n.firstChild;r;r=e(r,n))r.name===t&&i.push(r);return i},empty:function(){var t=this,n,r,i;if(t.firstChild){for(n=[],i=t.firstChild;i;i=e(i,t))n.push(i);for(r=n.length;r--;)i=n[r],i.parent=i.firstChild=i.lastChild=i.next=i.prev=null}return t.firstChild=t.lastChild=null,t},isEmpty:function(t){var r=this,i=r.firstChild,o,a;if(i)do{if(1===i.type){if(i.attributes.map["data-mce-bogus"])continue;if(t[i.name])return!1;for(o=i.attributes.length;o--;)if(a=i.attributes[o].name,"name"===a||0===a.indexOf("data-mce-"))return!1}if(8===i.type)return!1;if(3===i.type&&!n.test(i.value))return!1}while(i=e(i,r));return!0},walk:function(t){return e(this,null,t)}},t.create=function(e,n){var i,o;if(i=new t(e,r[e]||1),n)for(o in n)i.attr(o,n[o]);return i},t}),r(w,[p],function(e){function t(e,t){return e?e.split(t||" "):[]}function n(e){function n(e,n,r){function i(e){var t={},n,r;for(n=0,r=e.length;r>n;n++)t[e[n]]={};return t}var o,l,c,u=arguments;for(r=r||[],n=n||"","string"==typeof r&&(r=t(r)),l=3;lo;o++)i.attributes[n[o]]={},i.attributesOrder.push(n[o])}var a={},s,l,c,u,d,f;return r[e]?r[e]:(s=t("id accesskey class dir lang style tabindex title"),l=t("address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul"),c=t("a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd label map noscript object q s samp script select small span strong sub sup textarea u var #text #comment"),"html4"!=e&&(s.push.apply(s,t("contenteditable contextmenu draggable dropzone hidden spellcheck translate")),l.push.apply(l,t("article aside details dialog figure header footer hgroup section nav")),c.push.apply(c,t("audio canvas command datalist mark meter output progress time wbr video ruby bdi keygen"))),"html5-strict"!=e&&(s.push("xml:lang"),f=t("acronym applet basefont big font strike tt"),c.push.apply(c,f),o(f,function(e){n(e,"",c)}),d=t("center dir isindex noframes"),l.push.apply(l,d),u=[].concat(l,c),o(d,function(e){n(e,"",u)})),u=u||[].concat(l,c),n("html","manifest","head body"),n("head","","base command link meta noscript script style title"),n("title hr noscript br"),n("base","href target"),n("link","href rel media hreflang type sizes hreflang"),n("meta","name http-equiv content charset"),n("style","media type scoped"),n("script","src async defer type charset"),n("body","onafterprint onbeforeprint onbeforeunload onblur onerror onfocus onhashchange onload onmessage onoffline ononline onpagehide onpageshow onpopstate onresize onscroll onstorage onunload",u),n("address dt dd div caption","",u),n("h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn","",c),n("blockquote","cite",u),n("ol","reversed start type","li"),n("ul","","li"),n("li","value",u),n("dl","","dt dd"),n("a","href target rel media hreflang type",c),n("q","cite",c),n("ins del","cite datetime",u),n("img","src alt usemap ismap width height"),n("iframe","src name width height",u),n("embed","src type width height"),n("object","data type typemustmatch name usemap form width height",u,"param"),n("param","name value"),n("map","name",u,"area"),n("area","alt coords shape href target rel media hreflang type"),n("table","border","caption colgroup thead tfoot tbody tr"+("html4"==e?" col":"")),n("colgroup","span","col"),n("col","span"),n("tbody thead tfoot","","tr"),n("tr","","td th"),n("td","colspan rowspan headers",u),n("th","colspan rowspan headers scope abbr",u),n("form","accept-charset action autocomplete enctype method name novalidate target",u),n("fieldset","disabled form name",u,"legend"),n("label","form for",c),n("input","accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate formtarget height list max maxlength min multiple name pattern readonly required size src step type value width"),n("button","disabled form formaction formenctype formmethod formnovalidate formtarget name type value","html4"==e?u:c),n("select","disabled form multiple name required size","option optgroup"),n("optgroup","disabled label","option"),n("option","disabled label selected value"),n("textarea","cols dirname disabled form maxlength name readonly required rows wrap"),n("menu","type label",u,"li"),n("noscript","",u),"html4"!=e&&(n("wbr"),n("ruby","",c,"rt rp"),n("figcaption","",u),n("mark rt rp summary bdi","",c),n("canvas","width height",u),n("video","src crossorigin poster preload autoplay mediagroup loop muted controls width height buffered",u,"track source"),n("audio","src crossorigin preload autoplay mediagroup loop muted controls buffered volume",u,"track source"),n("source","src type media"),n("track","kind src srclang label default"),n("datalist","",c,"option"),n("article section nav aside header footer","",u),n("hgroup","","h1 h2 h3 h4 h5 h6"),n("figure","",u,"figcaption"),n("time","datetime",c),n("dialog","open",u),n("command","type label icon disabled checked radiogroup command"),n("output","for form name",c),n("progress","value max",c),n("meter","value min max low high optimum",c),n("details","open",u,"summary"),n("keygen","autofocus challenge disabled form keytype name")),"html5-strict"!=e&&(i("script","language xml:space"),i("style","xml:space"),i("object","declare classid codebase codetype archive standby align border hspace vspace"),i("param","valuetype type"),i("a","charset name rev shape coords"),i("br","clear"),i("applet","codebase archive code object alt name width height align hspace vspace"),i("img","name longdesc align border hspace vspace"),i("iframe","longdesc frameborder marginwidth marginheight scrolling align"),i("font basefont","size color face"),i("input","usemap align"),i("select","onchange"),i("textarea"),i("h1 h2 h3 h4 h5 h6 div p legend caption","align"),i("ul","type compact"),i("li","type"),i("ol dl menu dir","compact"),i("pre","width xml:space"),i("hr","align noshade size width"),i("isindex","prompt"),i("table","summary width frame rules cellspacing cellpadding align bgcolor"),i("col","width align char charoff valign"),i("colgroup","width align char charoff valign"),i("thead","align char charoff valign"),i("tr","align char charoff valign bgcolor"),i("th","axis align char charoff valign nowrap bgcolor width height"),i("form","accept"),i("td","abbr axis scope align char charoff valign nowrap bgcolor width height"),i("tfoot","align char charoff valign"),i("tbody","align char charoff valign"),i("area","nohref"),i("body","background bgcolor text link vlink alink")),"html4"!=e&&(i("input button select textarea","autofocus"),i("input textarea","placeholder"),i("a","download"),i("link script img","crossorigin"),i("iframe","sandbox seamless allowfullscreen")),o(t("a form meter progress dfn"),function(e){a[e]&&delete a[e].children[e]}),delete a.caption.children.table,r[e]=a,a)}var r={},i=e.makeMap,o=e.each,a=e.extend,s=e.explode,l=e.inArray;return function(e){function c(t,n,o){var s=e[t];return s?s=i(s,/[, ]/,i(s.toUpperCase(),/[, ]/)):(s=r[t],s||(s=i(n," ",i(n.toUpperCase()," ")),s=a(s,o),r[t]=s)),s}function u(e){return new RegExp("^"+e.replace(/([?+*])/g,".$1")+"$")}function d(e){var n,r,o,a,s,c,d,f,p,h,m,g,y,C,x,w,_,N,E,S=/^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)\])?$/,k=/^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,T=/[*?+]/;if(e)for(e=t(e,","),v["@"]&&(w=v["@"].attributes,_=v["@"].attributesOrder),n=0,r=e.length;r>n;n++)if(s=S.exec(e[n])){if(C=s[1],p=s[2],x=s[3],f=s[5],g={},y=[],c={attributes:g,attributesOrder:y},"#"===C&&(c.paddEmpty=!0),"-"===C&&(c.removeEmpty=!0),"!"===s[4]&&(c.removeEmptyAttrs=!0),w){for(N in w)g[N]=w[N];y.push.apply(y,_)}if(f)for(f=t(f,"|"),o=0,a=f.length;a>o;o++)if(s=k.exec(f[o])){if(d={},m=s[1],h=s[2].replace(/::/g,":"),C=s[3],E=s[4],"!"===m&&(c.attributesRequired=c.attributesRequired||[],c.attributesRequired.push(h),d.required=!0),"-"===m){delete g[h],y.splice(l(y,h),1);continue}C&&("="===C&&(c.attributesDefault=c.attributesDefault||[],c.attributesDefault.push({name:h,value:E}),d.defaultValue=E),":"===C&&(c.attributesForced=c.attributesForced||[],c.attributesForced.push({name:h,value:E}),d.forcedValue=E),"<"===C&&(d.validValues=i(E,"?"))),T.test(h)?(c.attributePatterns=c.attributePatterns||[],d.pattern=u(h),c.attributePatterns.push(d)):(g[h]||y.push(h),g[h]=d)}w||"@"!=p||(w=g,_=y),x&&(c.outputName=p,v[x]=c),T.test(p)?(c.pattern=u(p),b.push(c)):v[p]=c}}function f(e){v={},b=[],d(e),o(x,function(e,t){y[t]=e.children})}function p(e){var n=/^(~)?(.+)$/;e&&(r.text_block_elements=r.block_elements=null,o(t(e,","),function(e){var t=n.exec(e),r="~"===t[1],i=r?"span":"div",s=t[2];if(y[s]=y[i],R[s]=i,r||(S[s.toUpperCase()]={},S[s]={}),!v[s]){var l=v[i];l=a({},l),delete l.removeEmptyAttrs,delete l.removeEmpty,v[s]=l}o(y,function(e,t){e[i]&&(y[t]=e=a({},y[t]),e[s]=e[i])})}))}function h(e){var n=/^([+\-]?)(\w+)\[([^\]]+)\]$/;e&&o(t(e,","),function(e){var r=n.exec(e),i,s;r&&(s=r[1],i=s?y[r[2]]:y[r[2]]={"#comment":{}},i=y[r[2]],o(t(r[3],"|"),function(e){"-"===s?(y[r[2]]=i=a({},y[r[2]]),delete i[e]):i[e]={}}))})}function m(e){var t=v[e],n;if(t)return t;for(n=b.length;n--;)if(t=b[n],t.pattern.test(e))return t}var g=this,v={},y={},b=[],C,x,w,_,N,E,S,k,T,R={},A={};e=e||{},x=n(e.schema),e.verify_html===!1&&(e.valid_elements="*[*]"),e.valid_styles&&(C={},o(e.valid_styles,function(e,t){C[t]=s(e)})),w=c("whitespace_elements","pre script noscript style textarea video audio iframe object"),_=c("self_closing_elements","colgroup dd dt li option p td tfoot th thead tr"),N=c("short_ended_elements","area base basefont br col frame hr img input isindex link meta param embed source wbr track"),E=c("boolean_attributes","checked compact declare defer disabled ismap multiple nohref noresize noshade nowrap readonly selected autoplay loop controls"),k=c("non_empty_elements","td th iframe video audio object script",N),T=c("text_block_elements","h1 h2 h3 h4 h5 h6 p div address pre form blockquote center dir fieldset header footer article section hgroup aside nav figure"),S=c("block_elements","hr table tbody thead tfoot th tr td li ol ul caption dl dt dd noscript menu isindex option datalist select optgroup",T),o((e.special||"script noscript style textarea").split(" "),function(e){A[e]=new RegExp("]*>","gi")}),e.valid_elements?f(e.valid_elements):(o(x,function(e,t){v[t]={attributes:e.attributes,attributesOrder:e.attributesOrder},y[t]=e.children}),"html5"!=e.schema&&o(t("strong/b em/i"),function(e){e=t(e,"/"),v[e[1]].outputName=e[0]}),v.img.attributesDefault=[{name:"alt",value:""}],o(t("ol ul sub sup blockquote span font a table tbody tr strong em b i"),function(e){v[e]&&(v[e].removeEmpty=!0)}),o(t("p h1 h2 h3 h4 h5 h6 th td pre div address caption"),function(e){v[e].paddEmpty=!0}),o(t("span"),function(e){v[e].removeEmptyAttrs=!0})),p(e.custom_elements),h(e.valid_children),d(e.extended_valid_elements),h("+ol[ul|ol],+ul[ul|ol]"),e.invalid_elements&&o(s(e.invalid_elements),function(e){v[e]&&delete v[e]}),m("span")||d("span[!data-mce-type|*]"),g.children=y,g.styles=C,g.getBoolAttrs=function(){return E},g.getBlockElements=function(){return S},g.getTextBlockElements=function(){return T},g.getShortEndedElements=function(){return N},g.getSelfClosingElements=function(){return _},g.getNonEmptyElements=function(){return k},g.getWhiteSpaceElements=function(){return w},g.getSpecialElements=function(){return A},g.isValidChild=function(e,t){var n=y[e];return!(!n||!n[t])},g.isValid=function(e,t){var n,r,i=m(e);if(i){if(!t)return!0;if(i.attributes[t])return!0;if(n=i.attributePatterns)for(r=n.length;r--;)if(n[r].pattern.test(e))return!0}return!1},g.getElementRule=m,g.getCustomElements=function(){return R},g.addValidElements=d,g.setValidElements=f,g.addCustomElements=p,g.addValidChildren=h,g.elements=v}}),r(_,[w,m,p],function(e,t,n){var r=n.each;return function(i,o){function a(){}var s=this;i=i||{},s.schema=o=o||new e,i.fix_self_closing!==!1&&(i.fix_self_closing=!0),r("comment cdata text start end pi doctype".split(" "),function(e){e&&(s[e]=i[e]||a)}),s.parse=function(e){function r(e){var t,n;for(t=f.length;t--&&f[t].name!==e;);if(t>=0){for(n=f.length-1;n>=t;n--)e=f[n],e.valid&&s.end(e.name);f.length=t}}function a(e,t,n,r,o){var a,s,l=/[\s\u0000-\u001F]+/g;if(t=t.toLowerCase(),n=t in C?t:F(n||r||o||""),w&&!v&&0!==t.indexOf("data-")){if(a=k[t],!a&&T){for(s=T.length;s--&&(a=T[s],!a.pattern.test(t)););-1===s&&(a=null)}if(!a)return;if(a.validValues&&!(n in a.validValues))return}if(W[t]&&!i.allow_script_urls){var c=n.replace(l,"");try{c=decodeURIComponent(c)}catch(u){c=unescape(c)}if(V.test(c))return;if(!i.allow_html_data_urls&&U.test(c)&&!/^data:image\//i.test(c))return}p.map[t]=n,p.push({name:t,value:n})}var s=this,l,c=0,u,d,f=[],p,h,m,g,v,y,b,C,x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I=0,F=t.decode,z,W=n.makeMap("src,href,data,background,formaction,poster"),V=/((java|vb)script|mhtml):/i,U=/^data:/i;for(M=new RegExp("<(?:(?:!--([\\w\\W]*?)-->)|(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|(?:!DOCTYPE([\\w\\W]*?)>)|(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|(?:\\/([^>]+)>)|(?:([A-Za-z0-9\\-\\:\\.]+)((?:\\s+[^\"'>]+(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>]*))*|\\/|\\s+)>))","g"),H=/([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g,b=o.getShortEndedElements(),L=i.self_closing_elements||o.getSelfClosingElements(),C=o.getBoolAttrs(),w=i.validate,y=i.remove_internals,z=i.fix_self_closing,P=o.getSpecialElements();l=M.exec(e);){if(c0&&f[f.length-1].name===u&&r(u),!w||(_=o.getElementRule(u))){if(N=!0,w&&(k=_.attributes,T=_.attributePatterns),(S=l[8])?(v=-1!==S.indexOf("data-mce-type"),v&&y&&(N=!1),p=[],p.map={},S.replace(H,a)):(p=[],p.map={}),w&&!v){if(R=_.attributesRequired,A=_.attributesDefault,B=_.attributesForced,D=_.removeEmptyAttrs,D&&!p.length&&(N=!1),B)for(h=B.length;h--;)E=B[h],g=E.name,O=E.value,"{$uid}"===O&&(O="mce_"+I++),p.map[g]=O,p.push({name:g,value:O});if(A)for(h=A.length;h--;)E=A[h],g=E.name,g in p.map||(O=E.value,"{$uid}"===O&&(O="mce_"+I++),p.map[g]=O,p.push({name:g,value:O}));if(R){for(h=R.length;h--&&!(R[h]in p.map););-1===h&&(N=!1)}p.map["data-mce-bogus"]&&(N=!1)}N&&s.start(u,p,x)}else N=!1;if(d=P[u]){d.lastIndex=c=l.index+l[0].length,(l=d.exec(e))?(N&&(m=e.substr(c,l.index-c)),c=l.index+l[0].length):(m=e.substr(c),c=e.length),N&&(m.length>0&&s.text(m,!0),s.end(u)),M.lastIndex=c;continue}x||(S&&S.indexOf("/")==S.length-1?N&&s.end(u):f.push({name:u,valid:N}))}else(u=l[1])?(">"===u.charAt(0)&&(u=" "+u),i.allow_conditional_comments||"[if"!==u.substr(0,3)||(u=" "+u),s.comment(u)):(u=l[2])?s.cdata(u):(u=l[3])?s.doctype(u):(u=l[4])&&s.pi(u,l[5]);c=l.index+l[0].length}for(c=0;h--)u=f[h],u.valid&&s.end(u.name)}}}),r(N,[x,w,_,p],function(e,t,n,r){var i=r.makeMap,o=r.each,a=r.explode,s=r.extend;return function(r,l){function c(t){var n,r,o,a,s,c,d,f,p,h,m,g,v,y;for(m=i("tr,td,th,tbody,thead,tfoot,table"),h=l.getNonEmptyElements(),g=l.getTextBlockElements(),n=0;n1){for(a.reverse(),s=c=u.filterNode(a[0].clone()),p=0;p0?(t.value=n,t=t.prev):(r=t.prev,t.remove(),t=r)}function g(e){var t,n={};for(t in e)"li"!==t&&"p"!=t&&(n[t]=e[t]);return n}var v,y,b,C,x,w,_,N,E,S,k,T,R,A=[],B,D,L,M,H,P,O,I;if(o=o||{},p={},h={},T=s(i("script,style,head,html,body,title,meta,param"),l.getBlockElements()),O=l.getNonEmptyElements(),P=l.children,k=r.validate,I="forced_root_block"in o?o.forced_root_block:r.forced_root_block,H=l.getWhiteSpaceElements(),R=/^[ \t\r\n]+/,D=/[ \t\r\n]+$/,L=/[ \t\r\n]+/g,M=/^[ \t\r\n]+$/,v=new n({validate:k,allow_script_urls:r.allow_script_urls,allow_conditional_comments:r.allow_conditional_comments,self_closing_elements:g(l.getSelfClosingElements()),cdata:function(e){b.append(u("#cdata",4)).value=e},text:function(e,t){var n;B||(e=e.replace(L," "),b.lastChild&&T[b.lastChild.name]&&(e=e.replace(R,""))),0!==e.length&&(n=u("#text",3),n.raw=!!t,b.append(n).value=e)},comment:function(e){b.append(u("#comment",8)).value=e},pi:function(e,t){b.append(u(e,7)).value=t,m(b)},doctype:function(e){var t;t=b.append(u("#doctype",10)),t.value=e,m(b)},start:function(e,t,n){var r,i,o,a,s;if(o=k?l.getElementRule(e):{}){for(r=u(o.outputName||e,1),r.attributes=t,r.shortEnded=n,b.append(r),s=P[b.name],s&&P[r.name]&&!s[r.name]&&A.push(r),i=f.length;i--;)a=f[i].name,a in t.map&&(E=h[a],E?E.push(r):h[a]=[r]);T[e]&&m(r),n||(b=r),!B&&H[e]&&(B=!0)}},end:function(t){var n,r,i,o,a;if(r=k?l.getElementRule(t):{}){if(T[t]&&!B){if(n=b.firstChild,n&&3===n.type)if(i=n.value.replace(R,""),i.length>0)n.value=i,n=n.next;else for(o=n.next,n.remove(),n=o;n&&3===n.type;)i=n.value,o=n.next,(0===i.length||M.test(i))&&(n.remove(),n=o),n=o;if(n=b.lastChild,n&&3===n.type)if(i=n.value.replace(D,""),i.length>0)n.value=i,n=n.prev;else for(o=n.prev,n.remove(),n=o;n&&3===n.type;)i=n.value,o=n.prev,(0===i.length||M.test(i))&&(n.remove(),n=o),n=o}if(B&&H[t]&&(B=!1),(r.removeEmpty||r.paddEmpty)&&b.isEmpty(O))if(r.paddEmpty)b.empty().append(new e("#text","3")).value="\xa0";else if(!b.attributes.map.name&&!b.attributes.map.id)return a=b.parent,b.empty().remove(),void(b=a);b=b.parent}}},l),y=b=new e(o.context||r.root_name,11),v.parse(t),k&&A.length&&(o.context?o.invalid=!0:c(A)),I&&("body"==y.name||o.isRootContent)&&a(),!o.invalid){for(S in p){for(E=d[S],C=p[S],_=C.length;_--;)C[_].parent||C.splice(_,1);for(x=0,w=E.length;w>x;x++)E[x](C,S,o)}for(x=0,w=f.length;w>x;x++)if(E=f[x],E.name in h){for(C=h[E.name],_=C.length;_--;)C[_].parent||C.splice(_,1);for(_=0,N=E.callbacks.length;N>_;_++)E.callbacks[_](C,E.name,o)}}return y},r.remove_trailing_brs&&u.addNodeFilter("br",function(t){var n,r=t.length,i,o=s({},l.getBlockElements()),a=l.getNonEmptyElements(),c,u,d,f,p,h;for(o.body=1,n=0;r>n;n++)if(i=t[n],c=i.parent,o[i.parent.name]&&i===c.lastChild){for(d=i.prev;d;){if(f=d.name,"span"!==f||"bookmark"!==d.attr("data-mce-type")){if("br"!==f)break;if("br"===f){i=null;break}}d=d.prev}i&&(i.remove(),c.isEmpty(a)&&(p=l.getElementRule(c.name),p&&(p.removeEmpty?c.remove():p.paddEmpty&&(c.empty().append(new e("#text",3)).value="\xa0"))))}else{for(u=i;c&&c.firstChild===u&&c.lastChild===u&&(u=c,!o[c.name]);)c=c.parent;u===c&&(h=new e("#text",3),h.value="\xa0",i.replace(h))}}),r.allow_html_in_named_anchor||u.addAttributeFilter("id,name",function(e){for(var t=e.length,n,r,i,o;t--;)if(o=e[t],"a"===o.name&&o.firstChild&&!o.attr("href")){i=o.parent,n=o.lastChild;do r=n.prev,i.insert(n,o),n=r;while(n)}})}}),r(E,[m,p],function(e,t){var n=t.makeMap;return function(t){var r=[],i,o,a,s,l;return t=t||{},i=t.indent,o=n(t.indent_before||""),a=n(t.indent_after||""),s=e.getEncodeFunc(t.entity_encoding||"raw",t.entities),l="html"==t.element_format,{start:function(e,t,n){var c,u,d,f;if(i&&o[e]&&r.length>0&&(f=r[r.length-1],f.length>0&&"\n"!==f&&r.push("\n")),r.push("<",e),t)for(c=0,u=t.length;u>c;c++)d=t[c],r.push(" ",d.name,'="',s(d.value,!0),'"');r[r.length]=!n||l?">":" />",n&&i&&a[e]&&r.length>0&&(f=r[r.length-1],f.length>0&&"\n"!==f&&r.push("\n"))},end:function(e){var t;r.push(""),i&&a[e]&&r.length>0&&(t=r[r.length-1],t.length>0&&"\n"!==t&&r.push("\n"))},text:function(e,t){e.length>0&&(r[r.length]=t?e:s(e))},cdata:function(e){r.push("")},comment:function(e){r.push("")},pi:function(e,t){t?r.push(""):r.push(""),i&&r.push("\n")},doctype:function(e){r.push("",i?"\n":"")},reset:function(){r.length=0},getContent:function(){return r.join("").replace(/\n$/,"")}}}}),r(S,[E,w],function(e,t){return function(n,r){var i=this,o=new e(n);n=n||{},n.validate="validate"in n?n.validate:!0,i.schema=r=r||new t,i.writer=o,i.serialize=function(e){function t(e){var n=i[e.type],s,l,c,u,d,f,p,h,m;if(n)n(e);else{if(s=e.name,l=e.shortEnded,c=e.attributes,a&&c&&c.length>1){for(f=[],f.map={},m=r.getElementRule(e.name),p=0,h=m.attributesOrder.length;h>p;p++)u=m.attributesOrder[p],u in c.map&&(d=c.map[u],f.map[u]=d,f.push({name:u,value:d}));for(p=0,h=c.length;h>p;p++)u=c[p].name,u in f.map||(d=c.map[u],f.map[u]=d,f.push({name:u,value:d}));c=f}if(o.start(e.name,c,l),!l){if(e=e.firstChild)do t(e);while(e=e.next);o.end(s)}}}var i,a;return a=n.validate,i={3:function(e){o.text(e.value,e.raw)},8:function(e){o.comment(e.value)},7:function(e){o.pi(e.name,e.value)},10:function(e){o.doctype(e.value)},4:function(e){o.cdata(e.value)},11:function(e){if(e=e.firstChild)do t(e);while(e=e.next)}},o.reset(),1!=e.type||n.inner?i[11](e):t(e),o.getContent()}}}),r(k,[y,N,m,S,x,w,g,p],function(e,t,n,r,i,o,a,s){var l=s.each,c=s.trim,u=e.DOM;return function(e,i){var s,d,f;return i&&(s=i.dom,d=i.schema),s=s||u,d=d||new o(e),e.entity_encoding=e.entity_encoding||"named",e.remove_trailing_brs="remove_trailing_brs"in e?e.remove_trailing_brs:!0,f=new t(e,d),f.addAttributeFilter("data-mce-tabindex",function(e,t){for(var n=e.length,r;n--;)r=e[n],r.attr("tabindex",r.attributes.map["data-mce-tabindex"]),r.attr(t,null)}),f.addAttributeFilter("src,href,style",function(t,n){for(var r=t.length,i,o,a="data-mce-"+n,l=e.url_converter,c=e.url_converter_scope,u;r--;)i=t[r],o=i.attributes.map[a],o!==u?(i.attr(n,o.length>0?o:null),i.attr(a,null)):(o=i.attributes.map[n],"style"===n?o=s.serializeStyle(s.parseStyle(o),i.name):l&&(o=l.call(c,o,n,i.name)),i.attr(n,o.length>0?o:null))}),f.addAttributeFilter("class",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.attr("class").replace(/(?:^|\s)mce-item-\w+(?!\S)/g,""),n.attr("class",r.length>0?r:null)}),f.addAttributeFilter("data-mce-type",function(e,t,n){for(var r=e.length,i;r--;)i=e[r],"bookmark"!==i.attributes.map["data-mce-type"]||n.cleanup||i.remove()}),f.addAttributeFilter("data-mce-expando",function(e,t){for(var n=e.length;n--;)e[n].attr(t,null)}),f.addNodeFilter("noscript",function(e){for(var t=e.length,r;t--;)r=e[t].firstChild,r&&(r.value=n.decode(r.value))}),f.addNodeFilter("script,style",function(e,t){function n(e){return e.replace(/()/g,"\n").replace(/^[\r\n]*|[\r\n]*$/g,"").replace(/^\s*(()?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g,"")}for(var r=e.length,i,o;r--;)if(i=e[r],o=i.firstChild?i.firstChild.value:"","script"===t){var a=(i.attr("type")||"text/javascript").replace(/^mce\-/,"");i.attr("type","text/javascript"===a?null:a),o.length>0&&(i.firstChild.value="// ")}else o.length>0&&(i.firstChild.value="")}),f.addNodeFilter("#comment",function(e){for(var t=e.length,n;t--;)n=e[t],0===n.value.indexOf("[CDATA[")?(n.name="#cdata",n.type=4,n.value=n.value.replace(/^\[CDATA\[|\]\]$/g,"")):0===n.value.indexOf("mce:protected ")&&(n.name="#text",n.type=3,n.raw=!0,n.value=unescape(n.value).substr(14))}),f.addNodeFilter("xml:namespace,input",function(e,t){for(var n=e.length,r;n--;)r=e[n],7===r.type?r.remove():1===r.type&&("input"!==t||"type"in r.attributes.map||r.attr("type","text"))}),e.fix_list_elements&&f.addNodeFilter("ul,ol",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.parent,("ul"===r.name||"ol"===r.name)&&n.prev&&"li"===n.prev.name&&n.prev.append(n)}),f.addAttributeFilter("data-mce-src,data-mce-href,data-mce-style,data-mce-selected",function(e,t){for(var n=e.length;n--;)e[n].attr(t,null)}),{schema:d,addNodeFilter:f.addNodeFilter,addAttributeFilter:f.addAttributeFilter,serialize:function(t,n){var i=this,o,u,p,h,m;return a.ie&&s.select("script,style,select,map").length>0?(m=t.innerHTML,t=t.cloneNode(!1),s.setHTML(t,m)):t=t.cloneNode(!0),o=t.ownerDocument.implementation,o.createHTMLDocument&&(u=o.createHTMLDocument(""),l("BODY"==t.nodeName?t.childNodes:[t],function(e){u.body.appendChild(u.importNode(e,!0))}),t="BODY"!=t.nodeName?u.body.firstChild:u.body,p=s.doc,s.doc=u),n=n||{},n.format=n.format||"html",n.selection&&(n.forced_root_block=""),n.no_events||(n.node=t,i.onPreProcess(n)),h=new r(e,d),n.content=h.serialize(f.parse(c(n.getInner?t.innerHTML:s.getOuterHTML(t)),n)),n.cleanup||(n.content=n.content.replace(/\uFEFF/g,"")),n.no_events||i.onPostProcess(n),p&&(s.doc=p),n.node=null,n.content},addRules:function(e){d.addValidElements(e)},setRules:function(e){d.setValidElements(e)},onPreProcess:function(e){i&&i.fire("PreProcess",e)},onPostProcess:function(e){i&&i.fire("PostProcess",e)}}}}),r(T,[],function(){function e(e){function t(t,n){var r,i=0,o,a,s,l,c,u,d=-1,f;if(r=t.duplicate(),r.collapse(n),f=r.parentElement(),f.ownerDocument===e.dom.doc){for(;"false"===f.contentEditable;)f=f.parentNode; +if(!f.hasChildNodes())return{node:f,inside:1};for(s=f.children,o=s.length-1;o>=i;)if(u=Math.floor((i+o)/2),l=s[u],r.moveToElementText(l),d=r.compareEndPoints(n?"StartToStart":"EndToEnd",t),d>0)o=u-1;else{if(!(0>d))return{node:l};i=u+1}if(0>d)for(l?r.collapse(!1):(r.moveToElementText(f),r.collapse(!0),l=f,a=!0),c=0;0!==r.compareEndPoints(n?"StartToStart":"StartToEnd",t)&&0!==r.move("character",1)&&f==r.parentElement();)c++;else for(r.collapse(!0),c=0;0!==r.compareEndPoints(n?"StartToStart":"StartToEnd",t)&&0!==r.move("character",-1)&&f==r.parentElement();)c++;return{node:l,position:d,offset:c,inside:a}}}function n(){function n(e){var n=t(o,e),r,i,s=0,l,c,u;if(r=n.node,i=n.offset,n.inside&&!r.hasChildNodes())return void a[e?"setStart":"setEnd"](r,0);if(i===c)return void a[e?"setStartBefore":"setEndAfter"](r);if(n.position<0){if(l=n.inside?r.firstChild:r.nextSibling,!l)return void a[e?"setStartAfter":"setEndAfter"](r);if(!i)return void(3==l.nodeType?a[e?"setStart":"setEnd"](l,0):a[e?"setStartBefore":"setEndBefore"](l));for(;l;){if(u=l.nodeValue,s+=u.length,s>=i){r=l,s-=i,s=u.length-s;break}l=l.nextSibling}}else{if(l=r.previousSibling,!l)return a[e?"setStartBefore":"setEndBefore"](r);if(!i)return void(3==r.nodeType?a[e?"setStart":"setEnd"](l,r.nodeValue.length):a[e?"setStartAfter":"setEndAfter"](l));for(;l;){if(s+=l.nodeValue.length,s>=i){r=l,s-=i;break}l=l.previousSibling}}a[e?"setStart":"setEnd"](r,s)}var o=e.getRng(),a=i.createRng(),s,l,c,u,d;if(s=o.item?o.item(0):o.parentElement(),s.ownerDocument!=i.doc)return a;if(l=e.isCollapsed(),o.item)return a.setStart(s.parentNode,i.nodeIndex(s)),a.setEnd(a.startContainer,a.startOffset+1),a;try{n(!0),l||n()}catch(f){if(-2147024809!=f.number)throw f;d=r.getBookmark(2),c=o.duplicate(),c.collapse(!0),s=c.parentElement(),l||(c=o.duplicate(),c.collapse(!1),u=c.parentElement(),u.innerHTML=u.innerHTML),s.innerHTML=s.innerHTML,r.moveToBookmark(d),o=e.getRng(),n(!0),l||n()}return a}var r=this,i=e.dom,o=!1;this.getBookmark=function(n){function r(e){var t,n,r,o,a=[];for(t=e.parentNode,n=i.getRoot().parentNode;t!=n&&9!==t.nodeType;){for(r=t.children,o=r.length;o--;)if(e===r[o]){a.push(o);break}e=t,t=t.parentNode}return a}function o(e){var n;return n=t(a,e),n?{position:n.position,offset:n.offset,indexes:r(n.node),inside:n.inside}:void 0}var a=e.getRng(),s={};return 2===n&&(a.item?s.start={ctrl:!0,indexes:r(a.item(0))}:(s.start=o(!0),e.isCollapsed()||(s.end=o()))),s},this.moveToBookmark=function(e){function t(e){var t,n,r,o;for(t=i.getRoot(),n=e.length-1;n>=0;n--)o=t.children,r=e[n],r<=o.length-1&&(t=o[r]);return t}function n(n){var i=e[n?"start":"end"],a,s,l,c;i&&(a=i.position>0,s=o.createTextRange(),s.moveToElementText(t(i.indexes)),c=i.offset,c!==l?(s.collapse(i.inside||a),s.moveStart("character",a?-c:c)):s.collapse(n),r.setEndPoint(n?"StartToStart":"EndToStart",s),n&&r.collapse(!0))}var r,o=i.doc.body;e.start&&(e.start.ctrl?(r=o.createControlRange(),r.addElement(t(e.start.indexes)),r.select()):(r=o.createTextRange(),n(!0),n(),r.select()))},this.addRange=function(t){function n(e){var t,n,a,d,h;a=i.create("a"),t=e?s:c,n=e?l:u,d=r.duplicate(),(t==f||t==f.documentElement)&&(t=p,n=0),3==t.nodeType?(t.parentNode.insertBefore(a,t),d.moveToElementText(a),d.moveStart("character",n),i.remove(a),r.setEndPoint(e?"StartToStart":"EndToEnd",d)):(h=t.childNodes,h.length?(n>=h.length?i.insertAfter(a,h[h.length-1]):t.insertBefore(a,h[n]),d.moveToElementText(a)):t.canHaveHTML&&(t.innerHTML="",a=t.firstChild,d.moveToElementText(a),d.collapse(o)),r.setEndPoint(e?"StartToStart":"EndToEnd",d),i.remove(a))}var r,a,s,l,c,u,d,f=e.dom.doc,p=f.body,h,m;if(s=t.startContainer,l=t.startOffset,c=t.endContainer,u=t.endOffset,r=p.createTextRange(),s==c&&1==s.nodeType){if(l==u&&!s.hasChildNodes()){if(s.canHaveHTML)return d=s.previousSibling,d&&!d.hasChildNodes()&&i.isBlock(d)?d.innerHTML="":d=null,s.innerHTML="",r.moveToElementText(s.lastChild),r.select(),i.doc.selection.clear(),s.innerHTML="",void(d&&(d.innerHTML=""));l=i.nodeIndex(s),s=s.parentNode}if(l==u-1)try{if(m=s.childNodes[l],a=p.createControlRange(),a.addElement(m),a.select(),h=e.getRng(),h.item&&m===h.item(0))return}catch(g){}}n(!0),n(),r.select()},this.getRangeAt=n}return e}),r(R,[g],function(e){return{BACKSPACE:8,DELETE:46,DOWN:40,ENTER:13,LEFT:37,RIGHT:39,SPACEBAR:32,TAB:9,UP:38,modifierPressed:function(e){return e.shiftKey||e.ctrlKey||e.altKey},metaKeyPressed:function(t){return(e.mac?t.metaKey:t.ctrlKey)&&!t.altKey}}}),r(A,[R,p,g],function(e,t,n){return function(r,i){function o(e){var t=i.settings.object_resizing;return t===!1||n.iOS?!1:("string"!=typeof t&&(t="table,img,div"),"false"===e.getAttribute("data-mce-resize")?!1:i.dom.is(e,t))}function a(t){var n,r;n=t.screenX-k,r=t.screenY-T,H=n*E[2]+B,P=r*E[3]+D,H=5>H?5:H,P=5>P?5:P,(e.modifierPressed(t)||"IMG"==w.nodeName&&E[2]*E[3]!==0)&&(H=Math.round(P/L),P=Math.round(H*L)),C.setStyles(_,{width:H,height:P}),E[2]<0&&_.clientWidth<=H&&C.setStyle(_,"left",R+(B-H)),E[3]<0&&_.clientHeight<=P&&C.setStyle(_,"top",A+(D-P)),M||(i.fire("ObjectResizeStart",{target:w,width:B,height:D}),M=!0)}function s(){function e(e,t){t&&(w.style[e]||!i.schema.isValid(w.nodeName.toLowerCase(),e)?C.setStyle(w,e,t):C.setAttrib(w,e,t))}M=!1,e("width",H),e("height",P),C.unbind(O,"mousemove",a),C.unbind(O,"mouseup",s),I!=O&&(C.unbind(I,"mousemove",a),C.unbind(I,"mouseup",s)),C.remove(_),F&&"TABLE"!=w.nodeName||l(w),i.fire("ObjectResized",{target:w,width:H,height:P}),i.nodeChanged()}function l(e,t,r){var l,u,d,f,p,h=i.getBody();g(),l=C.getPos(e,h),R=l.x,A=l.y,p=e.getBoundingClientRect(),u=p.width||p.right-p.left,d=p.height||p.bottom-p.top,w!=e&&(m(),w=e,H=P=0),f=i.fire("ObjectSelected",{target:e}),o(e)&&!f.isDefaultPrevented()?x(N,function(e,o){function l(t){k=t.screenX,T=t.screenY,B=w.clientWidth,D=w.clientHeight,L=D/B,E=e,_=w.cloneNode(!0),C.addClass(_,"mce-clonedresizable"),_.contentEditable=!1,_.unSelectabe=!0,C.setStyles(_,{left:R,top:A,margin:0}),_.removeAttribute("data-mce-selected"),i.getBody().appendChild(_),C.bind(O,"mousemove",a),C.bind(O,"mouseup",s),I!=O&&(C.bind(I,"mousemove",a),C.bind(I,"mouseup",s))}var c,f;return t?void(o==t&&l(r)):(c=C.get("mceResizeHandle"+o),c?C.show(c):(f=i.getBody(),c=C.add(f,"div",{id:"mceResizeHandle"+o,"data-mce-bogus":!0,"class":"mce-resizehandle",unselectable:!0,style:"cursor:"+o+"-resize; margin:0; padding:0"}),n.ie&&(c.contentEditable=!1)),e.elm||(C.bind(c,"mousedown",function(e){e.stopImmediatePropagation(),e.preventDefault(),l(e)}),e.elm=c),void C.setStyles(c,{left:u*e[0]+R-c.offsetWidth/2,top:d*e[1]+A-c.offsetHeight/2}))}):c(),w.setAttribute("data-mce-selected","1")}function c(){var e,t;g(),w&&w.removeAttribute("data-mce-selected");for(e in N)t=C.get("mceResizeHandle"+e),t&&(C.unbind(t),C.remove(t))}function u(e){function t(e,t){if(e)do if(e===t)return!0;while(e=e.parentNode)}var n;return x(C.select("img[data-mce-selected],hr[data-mce-selected]"),function(e){e.removeAttribute("data-mce-selected")}),n="mousedown"==e.type?e.target:r.getNode(),n=C.getParent(n,F?"table":"table,img,hr"),t(n,i.getBody())&&(v(),t(r.getStart(),n)&&t(r.getEnd(),n)&&(!F||n!=r.getStart()&&"IMG"!==r.getStart().nodeName))?void l(n):void c()}function d(e,t,n){e&&e.attachEvent&&e.attachEvent("on"+t,n)}function f(e,t,n){e&&e.detachEvent&&e.detachEvent("on"+t,n)}function p(e){var t=e.srcElement,n,r,o,a,s,c,u;n=t.getBoundingClientRect(),c=S.clientX-n.left,u=S.clientY-n.top;for(r in N)if(o=N[r],a=t.offsetWidth*o[0],s=t.offsetHeight*o[1],Math.abs(a-c)<8&&Math.abs(s-u)<8){E=o;break}M=!0,i.getDoc().selection.empty(),l(t,r,S)}function h(e){var t=e.srcElement;if(t!=w){if(m(),0===t.id.indexOf("mceResizeHandle"))return void(e.returnValue=!1);("IMG"==t.nodeName||"TABLE"==t.nodeName)&&(c(),w=t,d(t,"resizestart",p))}}function m(){f(w,"resizestart",p)}function g(){for(var e in N){var t=N[e];t.elm&&(C.unbind(t.elm),delete t.elm)}}function v(){try{i.getDoc().execCommand("enableObjectResizing",!1,!1)}catch(e){}}function y(e){var t;if(F){t=O.body.createControlRange();try{return t.addElement(e),t.select(),!0}catch(n){}}}function b(){w=_=null,F&&(m(),f(i.getBody(),"controlselect",h))}var C=i.dom,x=t.each,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O=i.getDoc(),I=document,F=n.ie&&n.ie<11;N={n:[.5,0,0,-1],e:[1,.5,1,0],s:[.5,1,0,1],w:[0,.5,-1,0],nw:[0,0,-1,-1],ne:[1,0,1,-1],se:[1,1,1,1],sw:[0,1,-1,1]};var z=".mce-content-body";return i.contentStyles.push(z+" div.mce-resizehandle {position: absolute;border: 1px solid black;background: #FFF;width: 5px;height: 5px;z-index: 10000}"+z+" .mce-resizehandle:hover {background: #000}"+z+" img[data-mce-selected], hr[data-mce-selected] {outline: 1px solid black;resize: none}"+z+" .mce-clonedresizable {position: absolute;"+(n.gecko?"":"outline: 1px dashed black;")+"opacity: .5;filter: alpha(opacity=50);z-index: 10000}"),i.on("init",function(){F?(i.on("ObjectResized",function(e){"TABLE"!=e.target.nodeName&&(c(),y(e.target))}),d(i.getBody(),"controlselect",h),i.on("mousedown",function(e){S=e})):(v(),n.ie>=11&&(i.on("mouseup",function(e){var t=e.target.nodeName;/^(TABLE|IMG|HR)$/.test(t)&&(i.selection.select(e.target,"TABLE"==t),i.nodeChanged())}),i.dom.bind(i.getBody(),"mscontrolselect",function(e){/^(TABLE|IMG|HR)$/.test(e.target.nodeName)&&(e.preventDefault(),"IMG"==e.target.tagName&&window.setTimeout(function(){i.selection.select(e.target)},0))}))),i.on("nodechange mousedown mouseup ResizeEditor",u),i.on("keydown keyup",function(e){w&&"TABLE"==w.nodeName&&u(e)}),i.on("hide",c)}),i.on("remove",g),{isResizable:o,showResizeRect:l,hideResizeRect:c,updateResizeRect:u,controlSelect:y,destroy:b}}}),r(B,[p,f],function(e,t){function n(e){this.walk=function(t,n){function i(e){var t;return t=e[0],3===t.nodeType&&t===l&&c>=t.nodeValue.length&&e.splice(0,1),t=e[e.length-1],0===d&&e.length>0&&t===u&&3===t.nodeType&&e.splice(e.length-1,1),e}function o(e,t,n){for(var r=[];e&&e!=n;e=e[t])r.push(e);return r}function a(e,t){do{if(e.parentNode==t)return e;e=e.parentNode}while(e)}function s(e,t,r){var a=r?"nextSibling":"previousSibling";for(m=e,g=m.parentNode;m&&m!=t;m=g)g=m.parentNode,v=o(m==e?m:m[a],a),v.length&&(r||v.reverse(),n(i(v)))}var l=t.startContainer,c=t.startOffset,u=t.endContainer,d=t.endOffset,f,p,h,m,g,v,y;if(y=e.select("td.mce-item-selected,th.mce-item-selected"),y.length>0)return void r(y,function(e){n([e])});if(1==l.nodeType&&l.hasChildNodes()&&(l=l.childNodes[c]),1==u.nodeType&&u.hasChildNodes()&&(u=u.childNodes[Math.min(d-1,u.childNodes.length-1)]),l==u)return n(i([l]));for(f=e.findCommonAncestor(l,u),m=l;m;m=m.parentNode){if(m===u)return s(l,f,!0);if(m===f)break}for(m=u;m;m=m.parentNode){if(m===l)return s(u,f);if(m===f)break}p=a(l,f)||l,h=a(u,f)||u,s(l,p,!0),v=o(p==l?p:p.nextSibling,"nextSibling",h==u?h.nextSibling:h),v.length&&n(i(v)),s(u,h)},this.split=function(e){function t(e,t){return e.splitText(t)}var n=e.startContainer,r=e.startOffset,i=e.endContainer,o=e.endOffset;return n==i&&3==n.nodeType?r>0&&rr?(o-=r,n=i=t(i,o).previousSibling,o=i.nodeValue.length,r=0):o=0):(3==n.nodeType&&r>0&&r0&&o0)return c=p,u=n?p.nodeValue.length:0,void(i=!0);if(e.isBlock(p)||h[p.nodeName.toLowerCase()])return;s=p}o&&s&&(c=s,i=!0,u=0)}var c,u,d,f=e.getRoot(),p,h,m,g;if(c=n[(r?"start":"end")+"Container"],u=n[(r?"start":"end")+"Offset"],g=1==c.nodeType&&u===c.childNodes.length,h=e.schema.getNonEmptyElements(),m=r,1==c.nodeType&&u>c.childNodes.length-1&&(m=!1),9===c.nodeType&&(c=e.getRoot(),u=0),c===f){if(m&&(p=c.childNodes[u>0?u-1:0],p&&(h[p.nodeName]||"TABLE"==p.nodeName)))return;if(c.hasChildNodes()&&(u=Math.min(!m&&u>0?u-1:u,c.childNodes.length-1),c=c.childNodes[u],u=0,c.hasChildNodes()&&!/TABLE/.test(c.nodeName))){p=c,d=new t(c,f);do{if(3===p.nodeType&&p.nodeValue.length>0){u=m?0:p.nodeValue.length,c=p,i=!0;break}if(h[p.nodeName.toLowerCase()]){u=e.nodeIndex(p),c=p.parentNode,"IMG"!=p.nodeName||m||u++,i=!0;break}}while(p=m?d.next():d.prev())}}o&&(3===c.nodeType&&0===u&&l(!0),1===c.nodeType&&(p=c.childNodes[u],p||(p=c.childNodes[u-1]),!p||"BR"!==p.nodeName||s(p,"A")||a(p)||a(p,!0)||l(!0,p))),m&&!o&&3===c.nodeType&&u===c.nodeValue.length&&l(!1),i&&n["set"+(r?"Start":"End")](c,u)}var i,o;return o=n.collapsed,r(!0),o||r(),i&&o&&n.collapse(!0),i}}var r=e.each;return n.compareRanges=function(e,t){if(e&&t){if(!e.item&&!e.duplicate)return e.startContainer==t.startContainer&&e.startOffset==t.startOffset;if(e.item&&t.item&&e.item(0)===t.item(0))return!0;if(e.isEqual&&t.isEqual&&t.isEqual(e))return!0}return!1},n}),r(D,[f,T,A,B,g,p],function(e,n,r,i,o,a){function s(e,t,i,o){var a=this;a.dom=e,a.win=t,a.serializer=i,a.editor=o,a.controlSelection=new r(a,o),a.win.getSelection||(a.tridentSel=new n(a))}var l=a.each,c=a.grep,u=a.trim,d=o.ie,f=o.opera;return s.prototype={setCursorLocation:function(e,t){var n=this,r=n.dom.createRng();e?(r.setStart(e,t),r.setEnd(e,t),n.setRng(r),n.collapse(!1)):(n._moveEndPoint(r,n.editor.getBody(),!0),n.setRng(r))},getContent:function(e){var n=this,r=n.getRng(),i=n.dom.create("body"),o=n.getSel(),a,s,l;return e=e||{},a=s="",e.get=!0,e.format=e.format||"html",e.selection=!0,n.editor.fire("BeforeGetContent",e),"text"==e.format?n.isCollapsed()?"":r.text||(o.toString?o.toString():""):(r.cloneContents?(l=r.cloneContents(),l&&i.appendChild(l)):r.item!==t||r.htmlText!==t?(i.innerHTML="
"+(r.item?r.item(0).outerHTML:r.htmlText),i.removeChild(i.firstChild)):i.innerHTML=r.toString(),/^\s/.test(i.innerHTML)&&(a=" "),/\s+$/.test(i.innerHTML)&&(s=" "),e.getInner=!0,e.content=n.isCollapsed()?"":a+n.serializer.serialize(i,e)+s,n.editor.fire("GetContent",e),e.content)},setContent:function(e,t){var n=this,r=n.getRng(),i,o=n.win.document,a,s;if(t=t||{format:"html"},t.set=!0,t.selection=!0,e=t.content=e,t.no_events||n.editor.fire("BeforeSetContent",t),e=t.content,r.insertNode){e+='_',r.startContainer==o&&r.endContainer==o?o.body.innerHTML=e:(r.deleteContents(),0===o.body.childNodes.length?o.body.innerHTML=e:r.createContextualFragment?r.insertNode(r.createContextualFragment(e)):(a=o.createDocumentFragment(),s=o.createElement("div"),a.appendChild(s),s.outerHTML=e,r.insertNode(a))),i=n.dom.get("__caret"),r=o.createRange(),r.setStartBefore(i),r.setEndBefore(i),n.setRng(r),n.dom.remove("__caret");try{n.setRng(r)}catch(l){}}else r.item&&(o.execCommand("Delete",!1,null),r=n.getRng()),/^\s+/.test(e)?(r.pasteHTML('_'+e),n.dom.remove("__mce_tmp")):r.pasteHTML(e);t.no_events||n.editor.fire("SetContent",t)},getStart:function(){var e=this,t=e.getRng(),n,r,i,o;if(t.duplicate||t.item){if(t.item)return t.item(0);for(i=t.duplicate(),i.collapse(1),n=i.parentElement(),n.ownerDocument!==e.dom.doc&&(n=e.dom.getRoot()),r=o=t.parentElement();o=o.parentNode;)if(o==n){n=r;break}return n}return n=t.startContainer,1==n.nodeType&&n.hasChildNodes()&&(n=n.childNodes[Math.min(n.childNodes.length-1,t.startOffset)]),n&&3==n.nodeType?n.parentNode:n},getEnd:function(){var e=this,t=e.getRng(),n,r;return t.duplicate||t.item?t.item?t.item(0):(t=t.duplicate(),t.collapse(0),n=t.parentElement(),n.ownerDocument!==e.dom.doc&&(n=e.dom.getRoot()),n&&"BODY"==n.nodeName?n.lastChild||n:n):(n=t.endContainer,r=t.endOffset,1==n.nodeType&&n.hasChildNodes()&&(n=n.childNodes[r>0?r-1:r]),n&&3==n.nodeType?n.parentNode:n)},getBookmark:function(e,t){function n(e,t){var n=0;return l(a.select(e),function(e,r){e==t&&(n=r)}),n}function r(e){function t(t){var n,r,i,o=t?"start":"end";n=e[o+"Container"],r=e[o+"Offset"],1==n.nodeType&&"TR"==n.nodeName&&(i=n.childNodes,n=i[Math.min(t?r:r-1,i.length-1)],n&&(r=t?0:n.childNodes.length,e["set"+(t?"Start":"End")](n,r)))}return t(!0),t(),e}function i(){function e(e,n){var i=e[n?"startContainer":"endContainer"],a=e[n?"startOffset":"endOffset"],s=[],l,c,u=0;if(3==i.nodeType){if(t)for(l=i.previousSibling;l&&3==l.nodeType;l=l.previousSibling)a+=l.nodeValue.length;s.push(a)}else c=i.childNodes,a>=c.length&&c.length&&(u=1,a=Math.max(0,c.length-1)),s.push(o.dom.nodeIndex(c[a],t)+u);for(;i&&i!=r;i=i.parentNode)s.push(o.dom.nodeIndex(i,t));return s}var n=o.getRng(!0),r=a.getRoot(),i={};return i.start=e(n,!0),o.isCollapsed()||(i.end=e(n)),i}var o=this,a=o.dom,s,c,u,d,f,p,h="",m;if(2==e)return p=o.getNode(),f=p?p.nodeName:null,"IMG"==f?{name:f,index:n(f,p)}:o.tridentSel?o.tridentSel.getBookmark(e):i();if(e)return{rng:o.getRng()};if(s=o.getRng(),u=a.uniqueId(),d=o.isCollapsed(),m="overflow:hidden;line-height:0px",s.duplicate||s.item){if(s.item)return p=s.item(0),f=p.nodeName,{name:f,index:n(f,p)};c=s.duplicate();try{s.collapse(),s.pasteHTML(''+h+""),d||(c.collapse(!1),s.moveToElementText(c.parentElement()),0===s.compareEndPoints("StartToEnd",c)&&c.move("character",-1),c.pasteHTML(''+h+""))}catch(g){return null}}else{if(p=o.getNode(),f=p.nodeName,"IMG"==f)return{name:f,index:n(f,p)};c=r(s.cloneRange()),d||(c.collapse(!1),c.insertNode(a.create("span",{"data-mce-type":"bookmark",id:u+"_end",style:m},h))),s=r(s),s.collapse(!0),s.insertNode(a.create("span",{"data-mce-type":"bookmark",id:u+"_start",style:m},h))}return o.moveToBookmark({id:u,keep:1}),{id:u}},moveToBookmark:function(e){function t(t){var n=e[t?"start":"end"],r,i,o,l;if(n){for(o=n[0],i=s,r=n.length-1;r>=1;r--){if(l=i.childNodes,n[r]>l.length-1)return;i=l[n[r]]}3===i.nodeType&&(o=Math.min(n[0],i.nodeValue.length)),1===i.nodeType&&(o=Math.min(n[0],i.childNodes.length)),t?a.setStart(i,o):a.setEnd(i,o)}return!0}function n(t){var n=o.get(e.id+"_"+t),r,i,a,s,d=e.keep;if(n&&(r=n.parentNode,"start"==t?(d?(r=n.firstChild,i=1):i=o.nodeIndex(n),u=p=r,h=m=i):(d?(r=n.firstChild,i=1):i=o.nodeIndex(n),p=r,m=i),!d)){for(s=n.previousSibling,a=n.nextSibling,l(c(n.childNodes),function(e){3==e.nodeType&&(e.nodeValue=e.nodeValue.replace(/\uFEFF/g,""))});n=o.get(e.id+"_"+t);)o.remove(n,1);s&&a&&s.nodeType==a.nodeType&&3==s.nodeType&&!f&&(i=s.nodeValue.length,s.appendData(a.nodeValue),o.remove(a),"start"==t?(u=p=s,h=m=i):(p=s,m=i))}}function r(e){return!o.isBlock(e)||e.innerHTML||d||(e.innerHTML='
'),e}var i=this,o=i.dom,a,s,u,p,h,m;if(e)if(e.start){if(a=o.createRng(),s=o.getRoot(),i.tridentSel)return i.tridentSel.moveToBookmark(e);t(!0)&&t()&&i.setRng(a)}else e.id?(n("start"),n("end"),u&&(a=o.createRng(),a.setStart(r(u),h),a.setEnd(r(p),m),i.setRng(a))):e.name?i.select(o.select(e.name)[e.index]):e.rng&&i.setRng(e.rng)},select:function(e,t){var n=this,r=n.dom,i=r.createRng(),o;if(n.lastFocusBookmark=null,e){if(!t&&n.controlSelection.controlSelect(e))return;o=r.nodeIndex(e),i.setStart(e.parentNode,o),i.setEnd(e.parentNode,o+1),t&&(n._moveEndPoint(i,e,!0),n._moveEndPoint(i,e)),n.setRng(i)}return e},isCollapsed:function(){var e=this,t=e.getRng(),n=e.getSel();return!t||t.item?!1:t.compareEndPoints?0===t.compareEndPoints("StartToEnd",t):!n||t.collapsed},collapse:function(e){var t=this,n=t.getRng(),r;n.item&&(r=n.item(0),n=t.win.document.body.createTextRange(),n.moveToElementText(r)),n.collapse(!!e),t.setRng(n)},getSel:function(){var e=this.win;return e.getSelection?e.getSelection():e.document.selection},getRng:function(e){function t(e,t,n){try{return t.compareBoundaryPoints(e,n)}catch(r){return-1}}var n=this,r,i,o,a=n.win.document,s;if(!e&&n.lastFocusBookmark){var l=n.lastFocusBookmark;return l.startContainer?(i=a.createRange(),i.setStart(l.startContainer,l.startOffset),i.setEnd(l.endContainer,l.endOffset)):i=l,i}if(e&&n.tridentSel)return n.tridentSel.getRangeAt(0);try{(r=n.getSel())&&(i=r.rangeCount>0?r.getRangeAt(0):r.createRange?r.createRange():a.createRange())}catch(c){}if(d&&i&&i.setStart&&a.selection){try{s=a.selection.createRange()}catch(c){}s&&s.item&&(o=s.item(0),i=a.createRange(),i.setStartBefore(o),i.setEndAfter(o))}return i||(i=a.createRange?a.createRange():a.body.createTextRange()),i.setStart&&9===i.startContainer.nodeType&&i.collapsed&&(o=n.dom.getRoot(),i.setStart(o,0),i.setEnd(o,0)),n.selectedRange&&n.explicitRange&&(0===t(i.START_TO_START,i,n.selectedRange)&&0===t(i.END_TO_END,i,n.selectedRange)?i=n.explicitRange:(n.selectedRange=null,n.explicitRange=null)),i},setRng:function(e,t){var n=this,r;if(e.select)try{e.select()}catch(i){}else if(n.tridentSel){if(e.cloneRange)try{return void n.tridentSel.addRange(e)}catch(i){}}else if(r=n.getSel()){n.explicitRange=e;try{r.removeAllRanges(),r.addRange(e)}catch(i){}t===!1&&r.extend&&(r.collapse(e.endContainer,e.endOffset),r.extend(e.startContainer,e.startOffset)),n.selectedRange=r.rangeCount>0?r.getRangeAt(0):null}},setNode:function(e){var t=this;return t.setContent(t.dom.getOuterHTML(e)),e},getNode:function(){function e(e,t){for(var n=e;e&&3===e.nodeType&&0===e.length;)e=t?e.nextSibling:e.previousSibling;return e||n}var t=this,n=t.getRng(),r,i=n.startContainer,o=n.endContainer,a=n.startOffset,s=n.endOffset,l=t.dom.getRoot();return n?n.setStart?(r=n.commonAncestorContainer,!n.collapsed&&(i==o&&2>s-a&&i.hasChildNodes()&&(r=i.childNodes[a]),3===i.nodeType&&3===o.nodeType&&(i=i.length===a?e(i.nextSibling,!0):i.parentNode,o=0===s?e(o.previousSibling,!1):o.parentNode,i&&i===o))?i:r&&3==r.nodeType?r.parentNode:r):(r=n.item?n.item(0):n.parentElement(),r.ownerDocument!==t.win.document&&(r=l),r):l},getSelectedBlocks:function(t,n){var r=this,i=r.dom,o,a,s=[];if(a=i.getRoot(),t=i.getParent(t||r.getStart(),i.isBlock),n=i.getParent(n||r.getEnd(),i.isBlock),t&&t!=a&&s.push(t),t&&n&&t!=n){o=t;for(var l=new e(t,a);(o=l.next())&&o!=n;)i.isBlock(o)&&s.push(o)}return n&&t!=n&&n!=a&&s.push(n),s},isForward:function(){var e=this.dom,t=this.getSel(),n,r;return t&&t.anchorNode&&t.focusNode?(n=e.createRng(),n.setStart(t.anchorNode,t.anchorOffset),n.collapse(!0),r=e.createRng(),r.setStart(t.focusNode,t.focusOffset),r.collapse(!0),n.compareBoundaryPoints(n.START_TO_START,r)<=0):!0},normalize:function(){var e=this,t=e.getRng();return!d&&new i(e.dom).normalize(t)&&e.setRng(t,e.isForward()),t},selectorChanged:function(e,t){var n=this,r;return n.selectorChangedData||(n.selectorChangedData={},r={},n.editor.on("NodeChange",function(e){var t=e.element,i=n.dom,o=i.getParents(t,null,i.getRoot()),a={};l(n.selectorChangedData,function(e,t){l(o,function(n){return i.is(n,t)?(r[t]||(l(e,function(e){e(!0,{node:n,selector:t,parents:o})}),r[t]=e),a[t]=e,!1):void 0})}),l(r,function(e,n){a[n]||(delete r[n],l(e,function(e){e(!1,{node:t,selector:n,parents:o})}))})})),n.selectorChangedData[e]||(n.selectorChangedData[e]=[]),n.selectorChangedData[e].push(t),n},getScrollContainer:function(){for(var e,t=this.dom.getRoot();t&&"BODY"!=t.nodeName;){if(t.scrollHeight>t.clientHeight){e=t;break}t=t.parentNode}return e},scrollIntoView:function(e){function t(e){for(var t=0,n=0,r=e;r&&r.nodeType;)t+=r.offsetLeft||0,n+=r.offsetTop||0,r=r.offsetParent;return{x:t,y:n}}var n,r,i=this,o=i.dom,a=o.getRoot(),s,l;if("BODY"!=a.nodeName){var c=i.getScrollContainer();if(c)return n=t(e).y-t(c).y,l=c.clientHeight,s=c.scrollTop,void((s>n||n+25>s+l)&&(c.scrollTop=s>n?n:n-l+25))}r=o.getViewPort(i.editor.getWin()),n=o.getPos(e).y,s=r.y,l=r.h,(ns+l)&&i.editor.getWin().scrollTo(0,s>n?n:n-l+25)},_moveEndPoint:function(t,n,r){var i=n,a=new e(n,i),s=this.dom.schema.getNonEmptyElements();do{if(3==n.nodeType&&0!==u(n.nodeValue).length)return void(r?t.setStart(n,0):t.setEnd(n,n.nodeValue.length));if(s[n.nodeName])return void(r?t.setStartBefore(n):"BR"==n.nodeName?t.setEndBefore(n):t.setEndAfter(n));if(o.ie&&o.ie<11&&this.dom.isBlock(n)&&this.dom.isEmpty(n))return void(r?t.setStart(n,0):t.setEnd(n,0))}while(n=r?a.next():a.prev());"BODY"==i.nodeName&&(r?t.setStart(i,0):t.setEnd(i,i.childNodes.length))},destroy:function(){this.win=null,this.controlSelection.destroy()}},s}),r(L,[p],function(e){function t(e,t){function r(e){return e.replace(/%(\w+)/g,"")}var i,o,a=e.dom,s="",l,c;if(c=e.settings.preview_styles,c===!1)return"";if(c||(c="font-family font-size font-weight font-style text-decoration text-transform color background-color border border-radius outline text-shadow"),"string"==typeof t){if(t=e.formatter.get(t),!t)return;t=t[0]}return i=t.block||t.inline||"span",o=a.create(i),n(t.styles,function(e,t){e=r(e),e&&a.setStyle(o,t,e)}),n(t.attributes,function(e,t){e=r(e),e&&a.setAttrib(o,t,e)}),n(t.classes,function(e){e=r(e),a.hasClass(o,e)||a.addClass(o,e)}),e.fire("PreviewFormats"),a.setStyles(o,{position:"absolute",left:-65535}),e.getBody().appendChild(o),l=a.getStyle(e.getBody(),"fontSize",!0),l=/px$/.test(l)?parseInt(l,10):0,n(c.split(" "),function(t){var n=a.getStyle(o,t,!0);if(!("background-color"==t&&/transparent|rgba\s*\([^)]+,\s*0\)/.test(n)&&(n=a.getStyle(e.getBody(),t,!0),"#ffffff"==a.toHex(n).toLowerCase())||"color"==t&&"#000000"==a.toHex(n).toLowerCase())){if("font-size"==t&&/em|%$/.test(n)){if(0===l)return;n=parseFloat(n,10)/(/%$/.test(n)?100:1),n=n*l+"px"}"border"==t&&n&&(s+="padding:0 2px;"),s+=t+":"+n+";"}}),e.fire("AfterPreviewFormats"),a.remove(o),s}var n=e.each;return{getCssText:t}}),r(M,[f,B,p,L],function(e,t,n,r){return function(i){function o(e){return e.nodeType&&(e=e.nodeName),!!i.schema.getTextBlockElements()[e.toLowerCase()]}function a(e,t){return z.getParents(e,t,z.getRoot())}function s(e){return 1===e.nodeType&&"_mce_caret"===e.id}function l(){d({valigntop:[{selector:"td,th",styles:{verticalAlign:"top"}}],valignmiddle:[{selector:"td,th",styles:{verticalAlign:"middle"}}],valignbottom:[{selector:"td,th",styles:{verticalAlign:"bottom"}}],alignleft:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"left"},defaultBlock:"div"},{selector:"img,table",collapsed:!1,styles:{"float":"left"}}],aligncenter:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"center"},defaultBlock:"div"},{selector:"img",collapsed:!1,styles:{display:"block",marginLeft:"auto",marginRight:"auto"}},{selector:"table",collapsed:!1,styles:{marginLeft:"auto",marginRight:"auto"}}],alignright:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"right"},defaultBlock:"div"},{selector:"img,table",collapsed:!1,styles:{"float":"right"}}],alignjustify:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"justify"},defaultBlock:"div"}],bold:[{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}},{inline:"b",remove:"all"}],italic:[{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}},{inline:"i",remove:"all"}],underline:[{inline:"span",styles:{textDecoration:"underline"},exact:!0},{inline:"u",remove:"all"}],strikethrough:[{inline:"span",styles:{textDecoration:"line-through"},exact:!0},{inline:"strike",remove:"all"}],forecolor:{inline:"span",styles:{color:"%value"},wrap_links:!1},hilitecolor:{inline:"span",styles:{backgroundColor:"%value"},wrap_links:!1},fontname:{inline:"span",styles:{fontFamily:"%value"}},fontsize:{inline:"span",styles:{fontSize:"%value"}},fontsize_class:{inline:"span",attributes:{"class":"%value"}},blockquote:{block:"blockquote",wrapper:1,remove:"all"},subscript:{inline:"sub"},superscript:{inline:"sup"},code:{inline:"code"},link:{inline:"a",selector:"a",remove:"all",split:!0,deep:!0,onmatch:function(){return!0},onformat:function(e,t,n){nt(n,function(t,n){z.setAttrib(e,n,t)})}},removeformat:[{selector:"b,strong,em,i,font,u,strike,sub,sup,dfn,code,samp,kbd,var,cite,mark,q",remove:"all",split:!0,expand:!1,block_expand:!0,deep:!0},{selector:"span",attributes:["style","class"],remove:"empty",split:!0,expand:!1,deep:!0},{selector:"*",attributes:["style","class"],split:!1,expand:!1,deep:!0}]}),nt("p h1 h2 h3 h4 h5 h6 div address pre div dt dd samp".split(/\s/),function(e){d(e,{block:e,remove:"all"})}),d(i.settings.formats)}function c(){i.addShortcut("ctrl+b","bold_desc","Bold"),i.addShortcut("ctrl+i","italic_desc","Italic"),i.addShortcut("ctrl+u","underline_desc","Underline");for(var e=1;6>=e;e++)i.addShortcut("ctrl+"+e,"",["FormatBlock",!1,"h"+e]);i.addShortcut("ctrl+7","",["FormatBlock",!1,"p"]),i.addShortcut("ctrl+8","",["FormatBlock",!1,"div"]),i.addShortcut("ctrl+9","",["FormatBlock",!1,"address"])}function u(e){return e?F[e]:F}function d(e,t){e&&("string"!=typeof e?nt(e,function(e,t){d(t,e)}):(t=t.length?t:[t],nt(t,function(e){e.deep===Q&&(e.deep=!e.selector),e.split===Q&&(e.split=!e.selector||e.inline),e.remove===Q&&e.selector&&!e.inline&&(e.remove="none"),e.selector&&e.inline&&(e.mixed=!0,e.block_expand=!0),"string"==typeof e.classes&&(e.classes=e.classes.split(/\s+/))}),F[e]=t))}function f(e){var t;return i.dom.getParent(e,function(e){return t=i.dom.getStyle(e,"text-decoration"),t&&"none"!==t}),t}function p(e){var t;1===e.nodeType&&e.parentNode&&1===e.parentNode.nodeType&&(t=f(e.parentNode),i.dom.getStyle(e,"color")&&t?i.dom.setStyle(e,"text-decoration",t):i.dom.getStyle(e,"textdecoration")===t&&i.dom.setStyle(e,"text-decoration",null))}function h(t,n,r){function a(e,t){if(t=t||m,e){if(t.onformat&&t.onformat(e,t,n,r),nt(t.styles,function(t,r){z.setStyle(e,r,k(t,n))}),t.styles){var i=z.getAttrib(e,"style");i&&e.setAttribute("data-mce-style",i)}nt(t.attributes,function(t,r){z.setAttrib(e,r,k(t,n))}),nt(t.classes,function(t){t=k(t,n),z.hasClass(e,t)||z.addClass(e,t)})}}function l(){function t(t,n){var i=new e(n);for(r=i.current();r;r=i.prev())if(r.childNodes.length>1||r==t||"BR"==r.tagName)return r}var n=i.selection.getRng(),o=n.startContainer,a=n.endContainer;if(o!=a&&0===n.endOffset){var s=t(o,a),l=3==s.nodeType?s.length:s.childNodes.length;n.setEnd(s,l)}return n}function c(e,t,n,r,i){var o=[],a=-1,s,l=-1,c=-1,u;return nt(e.childNodes,function(e,t){return"UL"===e.nodeName||"OL"===e.nodeName?(a=t,s=e,!1):void 0}),nt(e.childNodes,function(e,n){"SPAN"===e.nodeName&&"bookmark"==z.getAttrib(e,"data-mce-type")&&(e.id==t.id+"_start"?l=n:e.id==t.id+"_end"&&(c=n))}),0>=a||a>l&&c>a?(nt(rt(e.childNodes),i),0):(u=z.clone(n,Y),nt(rt(e.childNodes),function(e,t){(a>l&&a>t||l>a&&t>a)&&(o.push(e),e.parentNode.removeChild(e))}),a>l?e.insertBefore(u,s):l>a&&e.insertBefore(u,s.nextSibling),r.push(u),nt(o,function(e){u.appendChild(e)}),u)}function d(e,r,i){var l=[],u,d,p=!0;u=m.inline||m.block,d=z.create(u),a(d),V.walk(e,function(e){function h(e){var y,C,x,w,_;return _=p,y=e.nodeName.toLowerCase(),C=e.parentNode.nodeName.toLowerCase(),1===e.nodeType&&Z(e)&&(_=p,p="true"===Z(e),w=!0),N(y,"br")?(g=0,void(m.block&&z.remove(e))):m.wrapper&&v(e,t,n)?void(g=0):p&&!w&&m.block&&!m.wrapper&&o(y)&&U(C,u)?(e=z.rename(e,u),a(e),l.push(e),void(g=0)):m.selector&&(nt(f,function(t){"collapsed"in t&&t.collapsed!==b||z.is(e,t.selector)&&!s(e)&&(a(e,t),x=!0)}),!m.inline||x)?void(g=0):void(!p||w||!U(u,y)||!U(C,u)||!i&&3===e.nodeType&&1===e.nodeValue.length&&65279===e.nodeValue.charCodeAt(0)||s(e)||m.inline&&q(e)?"li"==y&&r?g=c(e,r,d,l,h):(g=0,nt(rt(e.childNodes),h),w&&(p=_),g=0):(g||(g=z.clone(d,Y),e.parentNode.insertBefore(g,e),l.push(g)),g.appendChild(e)))}var g;nt(e,h)}),m.wrap_links===!1&&nt(l,function(e){function t(e){var n,r,i;if("A"===e.nodeName){for(r=z.clone(d,Y),l.push(r),i=rt(e.childNodes),n=0;n1||!q(e))&&0===o)return void z.remove(e,1);if(m.inline||m.wrapper){if(m.exact||1!==o||(e=i(e)),nt(f,function(t){nt(z.select(t.inline,e),function(e){var r;if(!M(e)){if(t.wrap_links===!1){r=e.parentNode;do if("A"===r.nodeName)return;while(r=r.parentNode)}B(t,n,e,t.exact?e:null)}})}),v(e.parentNode,t,n))return z.remove(e,1),e=0,X;m.merge_with_parents&&z.getParent(e.parentNode,function(r){return v(r,t,n)?(z.remove(e,1),e=0,X):void 0}),e&&m.merge_siblings!==!1&&(e=H(L(e),e),e=H(e,L(e,X)))}})}var f=u(t),m=f[0],g,y,b=!r&&W.isCollapsed();if(m)if(r)r.nodeType?(y=z.createRng(),y.setStartBefore(r),y.setEndAfter(r),d(A(y,f),null,!0)):d(r,null,!0);else if(b&&m.inline&&!z.select("td.mce-item-selected,th.mce-item-selected").length)O("apply",t,n);else{var C=i.selection.getNode();$||!f[0].defaultBlock||z.getParent(C,z.isBlock)||h(f[0].defaultBlock),i.selection.setRng(l()),g=W.getBookmark(),d(A(W.getRng(X),f),g),m.styles&&(m.styles.color||m.styles.textDecoration)&&(it(C,p,"childNodes"),p(C)),W.moveToBookmark(g),I(W.getRng(X)),i.nodeChanged()}}function m(e,t,n){function r(e){var n,i,o,a,s;if(1===e.nodeType&&Z(e)&&(a=b,b="true"===Z(e),s=!0),n=rt(e.childNodes),b&&!s)for(i=0,o=p.length;o>i&&!B(p[i],t,e,e);i++);if(h.deep&&n.length){for(i=0,o=n.length;o>i;i++)r(n[i]);s&&(b=a)}}function o(n){var r;return nt(a(n.parentNode).reverse(),function(n){var i;r||"_start"==n.id||"_end"==n.id||(i=v(n,e,t),i&&i.split!==!1&&(r=n))}),r}function s(e,n,r,i){var o,a,s,l,c,u;if(e){for(u=e.parentNode,o=n.parentNode;o&&o!=u;o=o.parentNode){for(a=z.clone(o,Y),c=0;c=0;o--){if(s=t[o].selector,!s||t[o].defaultBlock)return X;for(i=r.length-1;i>=0;i--)if(z.is(r[i],s))return X}return Y}function x(e,t,n){var r;return J||(J={},r={},i.on("NodeChange",function(e){var t=a(e.element),n={};nt(J,function(e,i){nt(t,function(o){return v(o,i,{},e.similar)?(r[i]||(nt(e,function(e){e(!0,{node:o,format:i,parents:t})}),r[i]=e),n[i]=e,!1):void 0})}),nt(r,function(i,o){n[o]||(delete r[o],nt(i,function(n){n(!1,{node:e.element,format:o,parents:t})}))})})),nt(e.split(","),function(e){J[e]||(J[e]=[],J[e].similar=n),J[e].push(t)}),this}function w(e){return r.getCssText(i,e)}function _(e,t){return N(e,t.inline)?X:N(e,t.block)?X:t.selector?1==e.nodeType&&z.is(e,t.selector):void 0}function N(e,t){return e=e||"",t=t||"",e=""+(e.nodeName||e),t=""+(t.nodeName||t),e.toLowerCase()==t.toLowerCase()}function E(e,t){return S(z.getStyle(e,t),t)}function S(e,t){return("color"==t||"backgroundColor"==t)&&(e=z.toHex(e)),"fontWeight"==t&&700==e&&(e="bold"),"fontFamily"==t&&(e=e.replace(/[\'\"]/g,"").replace(/,\s+/g,",")),""+e}function k(e,t){return"string"!=typeof e?e=e(t):t&&(e=e.replace(/%(\w+)/g,function(e,n){return t[n]||e})),e}function T(e){return e&&3===e.nodeType&&/^([\t \r\n]+|)$/.test(e.nodeValue)}function R(e,t,n){var r=z.create(t,n);return e.parentNode.insertBefore(r,e),r.appendChild(e),r}function A(t,n,r){function s(e){function t(e){return"BR"==e.nodeName&&e.getAttribute("data-mce-bogus")&&!e.nextSibling}var r,i,o,a,s;if(r=i=e?g:y,a=e?"previousSibling":"nextSibling",s=z.getRoot(),3==r.nodeType&&!T(r)&&(e?v>0:bi?n:i,-1===n||r||n++):(n=a.indexOf(" ",t),i=a.indexOf("\xa0",t),n=-1!==n&&(-1===i||i>n)?n:i),n}var s,l,c,u;if(3===t.nodeType){if(c=a(t,n),-1!==c)return{container:t,offset:c};u=t}for(s=new e(t,z.getParent(t,q)||i.getBody());l=s[o?"prev":"next"]();)if(3===l.nodeType){if(u=l,c=a(l),-1!==c)return{container:l,offset:c}}else if(q(l))break;return u?(n=o?0:u.length,{container:u,offset:n}):void 0}function d(e,r){var i,o,s,l;for(3==e.nodeType&&0===e.nodeValue.length&&e[r]&&(e=e[r]),i=a(e),o=0;op?p:v],3==g.nodeType&&(v=0)),1==y.nodeType&&y.hasChildNodes()&&(p=y.childNodes.length-1,y=y.childNodes[b>p?p:b-1],3==y.nodeType&&(b=y.nodeValue.length)),g=c(g),y=c(y),(M(g.parentNode)||M(g))&&(g=M(g)?g:g.parentNode,g=g.nextSibling||g,3==g.nodeType&&(v=0)),(M(y.parentNode)||M(y))&&(y=M(y)?y:y.parentNode,y=y.previousSibling||y,3==y.nodeType&&(b=y.length)),n[0].inline&&(t.collapsed&&(m=u(g,v,!0),m&&(g=m.container,v=m.offset),m=u(y,b),m&&(y=m.container,b=m.offset)),h=l(y,b),h.node)){for(;h.node&&0===h.offset&&h.node.previousSibling;)h=l(h.node.previousSibling);h.node&&h.offset>0&&3===h.node.nodeType&&" "===h.node.nodeValue.charAt(h.offset-1)&&h.offset>1&&(y=h.node,y.splitText(h.offset-1))}return(n[0].inline||n[0].block_expand)&&(n[0].inline&&3==g.nodeType&&0!==v||(g=s(!0)),n[0].inline&&3==y.nodeType&&b!==y.nodeValue.length||(y=s())),n[0].selector&&n[0].expand!==Y&&!n[0].inline&&(g=d(g,"previousSibling"),y=d(y,"nextSibling")),(n[0].block||n[0].selector)&&(g=f(g,"previousSibling"),y=f(y,"nextSibling"),n[0].block&&(q(g)||(g=s(!0)),q(y)||(y=s()))),1==g.nodeType&&(v=j(g),g=g.parentNode),1==y.nodeType&&(b=j(y)+1,y=y.parentNode),{startContainer:g,startOffset:v,endContainer:y,endOffset:b}}function B(e,t,n,r){var i,o,a;if(!_(n,e))return Y;if("all"!=e.remove)for(nt(e.styles,function(e,i){e=S(k(e,t),i),"number"==typeof i&&(i=e,r=0),(!r||N(E(r,i),e))&&z.setStyle(n,i,""),a=1}),a&&""===z.getAttrib(n,"style")&&(n.removeAttribute("style"),n.removeAttribute("data-mce-style")),nt(e.attributes,function(e,i){var o;if(e=k(e,t),"number"==typeof i&&(i=e,r=0),!r||N(z.getAttrib(r,i),e)){if("class"==i&&(e=z.getAttrib(n,i),e&&(o="",nt(e.split(/\s+/),function(e){/mce\w+/.test(e)&&(o+=(o?" ":"")+e)}),o)))return void z.setAttrib(n,i,o);"class"==i&&n.removeAttribute("className"),G.test(i)&&n.removeAttribute("data-mce-"+i),n.removeAttribute(i)}}),nt(e.classes,function(e){e=k(e,t),(!r||z.hasClass(r,e))&&z.removeClass(n,e)}),o=z.getAttribs(n),i=0;ia?a:o]),3===r.nodeType&&n&&o>=r.nodeValue.length&&(r=new e(r,i.getBody()).next()||r),3!==r.nodeType||n||0!==o||(r=new e(r,i.getBody()).prev()||r),r}function O(t,n,r){function a(e){var t=z.create("span",{id:y,"data-mce-bogus":!0,style:b?"color:red":""});return e&&t.appendChild(i.getDoc().createTextNode(K)),t}function s(e,t){for(;e;){if(3===e.nodeType&&e.nodeValue!==K||e.childNodes.length>1)return!1;t&&1===e.nodeType&&t.push(e),e=e.firstChild}return!0}function l(e){for(;e;){if(e.id===y)return e;e=e.parentNode}}function c(t){var n;if(t)for(n=new e(t,t),t=n.current();t;t=n.next())if(3===t.nodeType)return t}function d(e,t){var n,r;if(e)r=W.getRng(!0),s(e)?(t!==!1&&(r.setStartBefore(e),r.setEndBefore(e)),z.remove(e)):(n=c(e),n.nodeValue.charAt(0)===K&&(n=n.deleteData(0,1)),z.remove(e,1)),W.setRng(r);else if(e=l(W.getStart()),!e)for(;e=z.get(y);)d(e,!1)}function f(){var e,t,i,o,s,d,f;e=W.getRng(!0),o=e.startOffset,d=e.startContainer,f=d.nodeValue,t=l(W.getStart()),t&&(i=c(t)),f&&o>0&&o=0;p--)c.appendChild(z.clone(f[p],!1)),c=c.firstChild;c.appendChild(z.doc.createTextNode(K)),c=c.firstChild;var g=z.getParent(d,o);g&&z.isEmpty(g)?d.parentNode.replaceChild(h,d):z.insertAfter(h,d),W.setCursorLocation(c,1),z.isEmpty(d)&&z.remove(d)}}function g(){var e;e=l(W.getStart()),e&&!z.isEmpty(e)&&it(e,function(e){1!=e.nodeType||e.id===y||z.isEmpty(e)||z.setAttrib(e,"data-mce-bogus",null)},"childNodes")}var y="_mce_caret",b=i.settings.caret_debug;i._hasCaretEvents||(tt=function(){var e=[],t;if(s(l(W.getStart()),e))for(t=e.length;t--;)z.setAttrib(e[t],"data-mce-bogus","1")},et=function(e){var t=e.keyCode;d(),(8==t||37==t||39==t)&&d(l(W.getStart())),g()},i.on("SetContent",function(e){e.selection&&g()}),i._hasCaretEvents=!0),"apply"==t?f():p()}function I(t){var n=t.startContainer,r=t.startOffset,i,o,a,s,l;if(3==n.nodeType&&r>=n.nodeValue.length&&(r=j(n),n=n.parentNode,i=!0),1==n.nodeType)for(s=n.childNodes,n=s[Math.min(r,s.length-1)],o=new e(n,z.getParent(n,z.isBlock)),(r>s.length-1||i)&&o.next(),a=o.current();a;a=o.next())if(3==a.nodeType&&!T(a))return l=z.create("a",null,K),a.parentNode.insertBefore(l,a),t.setStart(a,0),W.setRng(t),void z.remove(l)}var F={},z=i.dom,W=i.selection,V=new t(z),U=i.schema.isValidChild,q=z.isBlock,$=i.settings.forced_root_block,j=z.nodeIndex,K="\ufeff",G=/^(src|href|style)$/,Y=!1,X=!0,J,Q,Z=z.getContentEditable,et,tt,nt=n.each,rt=n.grep,it=n.walk,ot=n.extend;ot(this,{get:u,register:d,apply:h,remove:m,toggle:g,match:y,matchAll:b,matchNode:v,canApply:C,formatChanged:x,getCssText:w}),l(),c(),i.on("BeforeGetContent",function(){tt&&tt()}),i.on("mouseup keydown",function(e){et&&et(e)})}}),r(H,[g,p],function(e,t){var n=t.trim,r;return r=new RegExp(["]+data-mce-bogus[^>]+>[\u200b\ufeff]+<\\/span>","]+data-mce-bogus[^>]+><\\/div>",'\\s?data-mce-selected="[^"]+"'].join("|"),"gi"),function(t){function i(){return n(t.getContent({format:"raw",no_events:1}).replace(r,""))}function o(e){a.typing=!1,a.add({},e)}var a=this,s=0,l=[],c,u,d=0;return t.on("init",function(){a.add()}),t.on("BeforeExecCommand",function(e){var t=e.command;"Undo"!=t&&"Redo"!=t&&"mceRepaint"!=t&&a.beforeChange()}),t.on("ExecCommand",function(e){var t=e.command;"Undo"!=t&&"Redo"!=t&&"mceRepaint"!=t&&o(e)}),t.on("ObjectResizeStart",function(){a.beforeChange()}),t.on("SaveContent ObjectResized blur",o),t.on("DragEnd",o),t.on("KeyUp",function(n){var r=n.keyCode;(r>=33&&36>=r||r>=37&&40>=r||45==r||13==r||n.ctrlKey)&&(o(),t.nodeChanged()),(46==r||8==r||e.mac&&(91==r||93==r))&&t.nodeChanged(),u&&a.typing&&(t.isDirty()||(t.isNotDirty=!l[0]||i()==l[0].content,t.isNotDirty||t.fire("change",{level:l[0],lastLevel:null})),t.fire("TypingUndo"),u=!1,t.nodeChanged())}),t.on("KeyDown",function(e){var t=e.keyCode;return t>=33&&36>=t||t>=37&&40>=t||45==t?void(a.typing&&o(e)):void((16>t||t>20)&&224!=t&&91!=t&&!a.typing&&(a.beforeChange(),a.typing=!0,a.add({},e),u=!0))}),t.on("MouseDown",function(e){a.typing&&o(e)}),t.addShortcut("ctrl+z","","Undo"),t.addShortcut("ctrl+y,ctrl+shift+z","","Redo"),t.on("AddUndo Undo Redo ClearUndos MouseUp",function(e){e.isDefaultPrevented()||t.nodeChanged()}),a={data:l,typing:!1,beforeChange:function(){d||(c=t.selection.getBookmark(2,!0))},add:function(e,n){var r,o=t.settings,a;if(e=e||{},e.content=i(),d||t.removed)return null;if(a=l[s],t.fire("BeforeAddUndo",{level:e,lastLevel:a,originalEvent:n}).isDefaultPrevented())return null;if(a&&a.content==e.content)return null;if(l[s]&&(l[s].beforeBookmark=c),o.custom_undo_redo_levels&&l.length>o.custom_undo_redo_levels){for(r=0;r0&&(t.isNotDirty=!1,t.fire("change",u)),e},undo:function(){var e;return a.typing&&(a.add(),a.typing=!1),s>0&&(e=l[--s],0===s&&(t.isNotDirty=!0),t.setContent(e.content,{format:"raw"}),t.selection.moveToBookmark(e.beforeBookmark),t.fire("undo",{level:e})),e},redo:function(){var e;return s0||a.typing&&l[0]&&i()!=l[0].content},hasRedo:function(){return sD)&&(u=a.create("br"),t.parentNode.insertBefore(u,t)),l.setStartBefore(t),l.setEndBefore(t)):(l.setStartAfter(t),l.setEndAfter(t)):(l.setStart(t,0),l.setEnd(t,0));s.setRng(l),a.remove(u),s.scrollIntoView(t)}function g(e){var t=l.forced_root_block;t&&t.toLowerCase()===e.tagName.toLowerCase()&&a.setAttribs(e,l.forced_root_block_attrs)}function v(e){var t=R,n,i,o;if(e||"TABLE"==O?(n=a.create(e||F),g(n)):n=B.cloneNode(!1),o=n,l.keep_styles!==!1)do if(/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U|VAR|CITE|DFN|CODE|MARK|Q|SUP|SUB|SAMP)$/.test(t.nodeName)){if("_mce_caret"==t.id)continue;i=t.cloneNode(!1),a.setAttrib(i,"id",""),n.hasChildNodes()?(i.appendChild(n.firstChild),n.appendChild(i)):(o=i,n.appendChild(i))}while(t=t.parentNode);return r||(o.innerHTML='
'),n}function y(t){var n,r,i;if(3==R.nodeType&&(t?A>0:A0)return!0}function w(){var e,t,n;R&&3==R.nodeType&&A>=R.nodeValue.length&&(r||x()||(e=a.create("br"),S.insertNode(e),S.setStartAfter(e),S.setEndAfter(e),t=!0)),e=a.create("br"),S.insertNode(e),r&&"PRE"==O&&(!D||8>D)&&e.parentNode.insertBefore(a.doc.createTextNode("\r"),e),n=a.create("span",{}," "),e.parentNode.insertBefore(n,e),s.scrollIntoView(n),a.remove(n),t?(S.setStartBefore(e),S.setEndBefore(e)):(S.setStartAfter(e),S.setEndAfter(e)),s.setRng(S),c.add()}function _(e){do 3===e.nodeType&&(e.nodeValue=e.nodeValue.replace(/^[\r\n]+/,"")),e=e.firstChild;while(e)}function N(e){var t=a.getRoot(),n,r;for(n=e;n!==t&&"false"!==a.getContentEditable(n);)"true"===a.getContentEditable(n)&&(r=n),n=n.parentNode;return n!==t?r:t}function E(e){var t;r||(e.normalize(),t=e.lastChild,(!t||/^(left|right)$/gi.test(a.getStyle(t,"float",!0)))&&a.add(e,"br"))}var S,k,T,R,A,B,D,L,M,H,P,O,I,F,z;if(S=s.getRng(!0),!o.isDefaultPrevented()){if(!S.collapsed)return void i.execCommand("Delete");if(new t(a).normalize(S),R=S.startContainer,A=S.startOffset,F=(l.force_p_newlines?"p":"")||l.forced_root_block,F=F?F.toUpperCase():"",D=a.doc.documentMode,L=o.shiftKey,1==R.nodeType&&R.hasChildNodes()&&(z=A>R.childNodes.length-1,R=R.childNodes[Math.min(A,R.childNodes.length-1)]||R,A=z&&3==R.nodeType?R.nodeValue.length:0),T=N(R)){if(c.beforeChange(),!a.isBlock(T)&&T!=a.getRoot())return void((!F||L)&&w());if((F&&!L||!F&&L)&&(R=b(R,A)),B=a.getParent(R,a.isBlock),P=B?a.getParent(B.parentNode,a.isBlock):null,O=B?B.nodeName.toUpperCase():"",I=P?P.nodeName.toUpperCase():"","LI"!=I||o.ctrlKey||(B=P,O=I),"LI"==O){if(!F&&L)return void w();if(a.isEmpty(B))return void C()}if("PRE"==O&&l.br_in_pre!==!1){if(!L)return void w()}else if(!F&&!L&&"LI"!=O||F&&L)return void w();F&&B===i.getBody()||(F=F||"P",y()?(M=/^(H[1-6]|PRE|FIGURE)$/.test(O)&&"HGROUP"!=I?v(F):v(),l.end_container_on_empty_block&&f(P)&&a.isEmpty(B)?M=a.split(P,B):a.insertAfter(M,B),m(M)):y(!0)?(M=B.parentNode.insertBefore(v(),B),p(M),m(B)):(k=S.cloneRange(),k.setEndAfter(B),H=k.extractContents(),_(H),M=H.firstChild,a.insertAfter(H,B),h(M),E(B),m(M)),a.setAttrib(M,"id",""),i.fire("NewBlock",{newBlock:M}),c.add())}}}var a=i.dom,s=i.selection,l=i.settings,c=i.undoManager,u=i.schema,d=u.getNonEmptyElements();i.on("keydown",function(e){13==e.keyCode&&o(e)!==!1&&e.preventDefault()})}}),r(O,[],function(){return function(e){function t(){var t=i.getStart(),s=e.getBody(),l,c,u,d,f,p,h,m=-16777215,g,v,y,b,C;if(C=n.forced_root_block,t&&1===t.nodeType&&C){for(;t&&t!=s;){if(a[t.nodeName])return;t=t.parentNode}if(l=i.getRng(),l.setStart){c=l.startContainer,u=l.startOffset,d=l.endContainer,f=l.endOffset;try{v=e.getDoc().activeElement===s}catch(x){}}else l.item&&(t=l.item(0),l=e.getDoc().body.createTextRange(),l.moveToElementText(t)),v=l.parentElement().ownerDocument===e.getDoc(),y=l.duplicate(),y.collapse(!0),u=-1*y.move("character",m),y.collapsed||(y=l.duplicate(),y.collapse(!1),f=-1*y.move("character",m)-u);for(t=s.firstChild,b=s.nodeName.toLowerCase();t;)if((3===t.nodeType||1==t.nodeType&&!a[t.nodeName])&&o.isValidChild(b,C.toLowerCase())){if(3===t.nodeType&&0===t.nodeValue.length){h=t,t=t.nextSibling,r.remove(h);continue}p||(p=r.create(C,e.settings.forced_root_block_attrs),t.parentNode.insertBefore(p,t),g=!0),h=t,t=t.nextSibling,p.appendChild(h)}else p=null,t=t.nextSibling;if(g&&v){if(l.setStart)l.setStart(c,u),l.setEnd(d,f),i.setRng(l);else try{l=e.getDoc().body.createTextRange(),l.moveToElementText(s),l.collapse(!0),l.moveStart("character",u),f>0&&l.moveEnd("character",f),l.select()}catch(x){}e.nodeChanged()}}}var n=e.settings,r=e.dom,i=e.selection,o=e.schema,a=o.getBlockElements();n.forced_root_block&&e.on("NodeChange",t)}}),r(I,[S,g,p],function(e,n,r){var i=r.each,o=r.extend,a=r.map,s=r.inArray,l=r.explode,c=n.gecko,u=n.ie,d=!0,f=!1;return function(r){function p(e,t,n){var r;return e=e.toLowerCase(),(r=N.exec[e])?(r(e,t,n),d):f}function h(e){var t;return e=e.toLowerCase(),(t=N.state[e])?t(e):-1}function m(e){var t;return e=e.toLowerCase(),(t=N.value[e])?t(e):f}function g(e,t){t=t||"exec",i(e,function(e,n){i(n.toLowerCase().split(","),function(n){N[t][n]=e})})}function v(e,n,i){return n===t&&(n=f),i===t&&(i=null),r.getDoc().execCommand(e,n,i)}function y(e){return S.match(e)}function b(e,n){S.toggle(e,n?{value:n}:t),r.nodeChanged()}function C(e){k=_.getBookmark(e)}function x(){_.moveToBookmark(k)}var w=r.dom,_=r.selection,N={state:{},exec:{},value:{}},E=r.settings,S=r.formatter,k;o(this,{execCommand:p,queryCommandState:h,queryCommandValue:m,addCommands:g}),g({"mceResetDesignMode,mceBeginUndoLevel":function(){},"mceEndUndoLevel,mceAddUndoLevel":function(){r.undoManager.add()},"Cut,Copy,Paste":function(e){var t=r.getDoc(),i;try{v(e)}catch(o){i=d}if(i||!t.queryCommandSupported(e)){var a=r.translate("Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.");n.mac&&(a=a.replace(/Ctrl\+/g,"\u2318+")),r.windowManager.alert(a)}},unlink:function(){if(_.isCollapsed()){var e=_.getNode();return void("A"==e.tagName&&r.dom.remove(e,!0))}S.remove("link")},"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(e){var t=e.substring(7);"full"==t&&(t="justify"),i("left,center,right,justify".split(","),function(e){t!=e&&S.remove("align"+e)}),b("align"+t),p("mceRepaint")},"InsertUnorderedList,InsertOrderedList":function(e){var t,n;v(e),t=w.getParent(_.getNode(),"ol,ul"),t&&(n=t.parentNode,/^(H[1-6]|P|ADDRESS|PRE)$/.test(n.nodeName)&&(C(),w.split(n,t),x()))},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(e){b(e)},"ForeColor,HiliteColor,FontName":function(e,t,n){b(e,n)},FontSize:function(e,t,n){var r,i;n>=1&&7>=n&&(i=l(E.font_size_style_values),r=l(E.font_size_classes),n=r?r[n-1]||n:i[n-1]||n),b(e,n)},RemoveFormat:function(e){S.remove(e)},mceBlockQuote:function(){b("blockquote")},FormatBlock:function(e,t,n){return b(n||"p")},mceCleanup:function(){var e=_.getBookmark();r.setContent(r.getContent({cleanup:d}),{cleanup:d}),_.moveToBookmark(e)},mceRemoveNode:function(e,t,n){var i=n||_.getNode();i!=r.getBody()&&(C(),r.dom.remove(i,d),x())},mceSelectNodeDepth:function(e,t,n){var i=0;w.getParent(_.getNode(),function(e){return 1==e.nodeType&&i++==n?(_.select(e),f):void 0},r.getBody())},mceSelectNode:function(e,t,n){_.select(n)},mceInsertContent:function(t,n,i){function o(e){function t(e){return r[e]&&3==r[e].nodeType}var n,r,i;return n=_.getRng(!0),r=n.startContainer,i=n.startOffset,3==r.nodeType&&(i>0?e=e.replace(/^ /," "):t("previousSibling")||(e=e.replace(/^ /," ")),i|)$/," "):t("nextSibling")||(e=e.replace(/( | )(
|)$/," "))),e}var a,s,l,c,d,f,p,h,m,g,v;/^ | $/.test(i)&&(i=o(i)),a=r.parser,s=new e({},r.schema),v='ÈB;',f={content:i,format:"html",selection:!0},r.fire("BeforeSetContent",f),i=f.content,-1==i.indexOf("{$caret}")&&(i+="{$caret}"),i=i.replace(/\{\$caret\}/,v),h=_.getRng();var y=h.startContainer||(h.parentElement?h.parentElement():null),b=r.getBody();y===b&&_.isCollapsed()&&w.isBlock(b.firstChild)&&w.isEmpty(b.firstChild)&&(h=w.createRng(),h.setStart(b.firstChild,0),h.setEnd(b.firstChild,0),_.setRng(h)),_.isCollapsed()||r.getDoc().execCommand("Delete",!1,null),l=_.getNode();var C={context:l.nodeName.toLowerCase()};if(d=a.parse(i,C),m=d.lastChild,"mce_marker"==m.attr("id"))for(p=m,m=m.prev;m;m=m.walk(!0))if(3==m.type||!w.isBlock(m.name)){m.parent.insert(p,m,"br"===m.name);break}if(C.invalid){for(_.setContent(v),l=_.getNode(),c=r.getBody(),9==l.nodeType?l=m=c:m=l;m!==c;)l=m,m=m.parentNode;i=l==c?c.innerHTML:w.getOuterHTML(l),i=s.serialize(a.parse(i.replace(//i,function(){return s.serialize(d)}))),l==c?w.setHTML(c,i):w.setOuterHTML(l,i)}else i=s.serialize(d),m=l.firstChild,g=l.lastChild,!m||m===g&&"BR"===m.nodeName?w.setHTML(l,i):_.setContent(i);p=w.get("mce_marker"),_.scrollIntoView(p),h=w.createRng(),m=p.previousSibling,m&&3==m.nodeType?(h.setStart(m,m.nodeValue.length),u||(g=p.nextSibling,g&&3==g.nodeType&&(m.appendData(g.data),g.parentNode.removeChild(g)))):(h.setStartBefore(p),h.setEndBefore(p)),w.remove(p),_.setRng(h),r.fire("SetContent",f),r.addVisual()},mceInsertRawHTML:function(e,t,n){_.setContent("tiny_mce_marker"),r.setContent(r.getContent().replace(/tiny_mce_marker/g,function(){return n}))},mceToggleFormat:function(e,t,n){b(n)},mceSetContent:function(e,t,n){r.setContent(n)},"Indent,Outdent":function(e){var t,n,o;t=E.indentation,n=/[a-z%]+$/i.exec(t),t=parseInt(t,10),h("InsertUnorderedList")||h("InsertOrderedList")?v(e):(E.forced_root_block||w.getParent(_.getNode(),w.isBlock)||S.apply("div"),i(_.getSelectedBlocks(),function(i){if("LI"!=i.nodeName){var a=r.getParam("indent_use_margin",!1)?"margin":"padding";a+="rtl"==w.getStyle(i,"direction",!0)?"Right":"Left","outdent"==e?(o=Math.max(0,parseInt(i.style[a]||0,10)-t),w.setStyle(i,a,o?o+n:"")):(o=parseInt(i.style[a]||0,10)+t+n,w.setStyle(i,a,o))}}))},mceRepaint:function(){if(c)try{C(d),_.getSel()&&_.getSel().selectAllChildren(r.getBody()),_.collapse(d),x()}catch(e){}},InsertHorizontalRule:function(){r.execCommand("mceInsertContent",!1,"
")},mceToggleVisualAid:function(){r.hasVisual=!r.hasVisual,r.addVisual()},mceReplaceContent:function(e,t,n){r.execCommand("mceInsertContent",!1,n.replace(/\{\$selection\}/g,_.getContent({format:"text"})))},mceInsertLink:function(e,t,n){var r;"string"==typeof n&&(n={href:n}),r=w.getParent(_.getNode(),"a"),n.href=n.href.replace(" ","%20"),r&&n.href||S.remove("link"),n.href&&S.apply("link",n,r)},selectAll:function(){var e=w.getRoot(),t;_.getRng().setStart?(t=w.createRng(),t.setStart(e,0),t.setEnd(e,e.childNodes.length),_.setRng(t)):(t=_.getRng(),t.item||(t.moveToElementText(e),t.select()))},"delete":function(){v("Delete");var e=r.getBody();w.isEmpty(e)&&(r.setContent(""),e.firstChild&&w.isBlock(e.firstChild)?r.selection.setCursorLocation(e.firstChild,0):r.selection.setCursorLocation(e,0))},mceNewDocument:function(){r.setContent("")}}),g({"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(e){var t="align"+e.substring(7),n=_.isCollapsed()?[w.getParent(_.getNode(),w.isBlock)]:_.getSelectedBlocks(),r=a(n,function(e){return!!S.matchNode(e,t)});return-1!==s(r,d)},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(e){return y(e)},mceBlockQuote:function(){return y("blockquote")},Outdent:function(){var e;if(E.inline_styles){if((e=w.getParent(_.getStart(),w.isBlock))&&parseInt(e.style.paddingLeft,10)>0)return d;if((e=w.getParent(_.getEnd(),w.isBlock))&&parseInt(e.style.paddingLeft,10)>0)return d +}return h("InsertUnorderedList")||h("InsertOrderedList")||!E.inline_styles&&!!w.getParent(_.getNode(),"BLOCKQUOTE")},"InsertUnorderedList,InsertOrderedList":function(e){var t=w.getParent(_.getNode(),"ul,ol");return t&&("insertunorderedlist"===e&&"UL"===t.tagName||"insertorderedlist"===e&&"OL"===t.tagName)}},"state"),g({"FontSize,FontName":function(e){var t=0,n;return(n=w.getParent(_.getNode(),"span"))&&(t="fontsize"==e?n.style.fontSize:n.style.fontFamily.replace(/, /g,",").replace(/[\'\"]/g,"").toLowerCase()),t}},"value"),g({Undo:function(){r.undoManager.undo()},Redo:function(){r.undoManager.redo()}})}}),r(F,[p],function(e){function t(e,i){var o=this,a,s;if(e=r(e),i=o.settings=i||{},/^([\w\-]+):([^\/]{2})/i.test(e)||/^\s*#/.test(e))return void(o.source=e);var l=0===e.indexOf("//");0!==e.indexOf("/")||l||(e=(i.base_uri?i.base_uri.protocol||"http":"http")+"://mce_host"+e),/^[\w\-]*:?\/\//.test(e)||(s=i.base_uri?i.base_uri.path:new t(location.href).directory,e=""===i.base_uri.protocol?"//mce_host"+o.toAbsPath(s,e):(i.base_uri&&i.base_uri.protocol||"http")+"://mce_host"+o.toAbsPath(s,e)),e=e.replace(/@@/g,"(mce_at)"),e=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(e),n(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],function(t,n){var r=e[n];r&&(r=r.replace(/\(mce_at\)/g,"@@")),o[t]=r}),a=i.base_uri,a&&(o.protocol||(o.protocol=a.protocol),o.userInfo||(o.userInfo=a.userInfo),o.port||"mce_host"!==o.host||(o.port=a.port),o.host&&"mce_host"!==o.host||(o.host=a.host),o.source=""),l&&(o.protocol="")}var n=e.each,r=e.trim,i={ftp:21,http:80,https:443,mailto:25};return t.prototype={setPath:function(e){var t=this;e=/^(.*?)\/?(\w+)?$/.exec(e),t.path=e[0],t.directory=e[1],t.file=e[2],t.source="",t.getURI()},toRelative:function(e){var n=this,r;if("./"===e)return e;if(e=new t(e,{base_uri:n}),"mce_host"!=e.host&&n.host!=e.host&&e.host||n.port!=e.port||n.protocol!=e.protocol&&""!==e.protocol)return e.getURI();var i=n.getURI(),o=e.getURI();return i==o||"/"==i.charAt(i.length-1)&&i.substr(0,i.length-1)==o?i:(r=n.toRelPath(n.path,e.path),e.query&&(r+="?"+e.query),e.anchor&&(r+="#"+e.anchor),r)},toAbsolute:function(e,n){return e=new t(e,{base_uri:this}),e.getURI(n&&this.isSameOrigin(e))},isSameOrigin:function(e){if(this.host==e.host&&this.protocol==e.protocol){if(this.port==e.port)return!0;var t=i[this.protocol];if(t&&(this.port||t)==(e.port||t))return!0}return!1},toRelPath:function(e,t){var n,r=0,i="",o,a;if(e=e.substring(0,e.lastIndexOf("/")),e=e.split("/"),n=t.split("/"),e.length>=n.length)for(o=0,a=e.length;a>o;o++)if(o>=n.length||e[o]!=n[o]){r=o+1;break}if(e.lengtho;o++)if(o>=e.length||e[o]!=n[o]){r=o+1;break}if(1===r)return t;for(o=0,a=e.length-(r-1);a>o;o++)i+="../";for(o=r-1,a=n.length;a>o;o++)i+=o!=r-1?"/"+n[o]:n[o];return i},toAbsPath:function(e,t){var r,i=0,o=[],a,s;for(a=/\/$/.test(t)?"/":"",e=e.split("/"),t=t.split("/"),n(e,function(e){e&&o.push(e)}),e=o,r=t.length-1,o=[];r>=0;r--)0!==t[r].length&&"."!==t[r]&&(".."!==t[r]?i>0?i--:o.push(t[r]):i++);return r=e.length-i,s=0>=r?o.reverse().join("/"):e.slice(0,r).join("/")+"/"+o.reverse().join("/"),0!==s.indexOf("/")&&(s="/"+s),a&&s.lastIndexOf("/")!==s.length-1&&(s+=a),s},getURI:function(e){var t,n=this;return(!n.source||e)&&(t="",e||(t+=n.protocol?n.protocol+"://":"//",n.userInfo&&(t+=n.userInfo+"@"),n.host&&(t+=n.host),n.port&&(t+=":"+n.port)),n.path&&(t+=n.path),n.query&&(t+="?"+n.query),n.anchor&&(t+="#"+n.anchor),n.source=t),n.source}},t}),r(z,[p],function(e){function t(){}var n=e.each,r=e.extend,i,o;return t.extend=i=function(e){function t(){var e,t,n,r=this;if(!o&&(r.init&&r.init.apply(r,arguments),t=r.Mixins))for(e=t.length;e--;)n=t[e],n.init&&n.init.apply(r,arguments)}function a(){return this}function s(e,t){return function(){var n=this,r=n._super,i;return n._super=c[e],i=t.apply(n,arguments),n._super=r,i}}var l=this,c=l.prototype,u,d,f;o=!0,u=new l,o=!1,e.Mixins&&(n(e.Mixins,function(t){t=t;for(var n in t)"init"!==n&&(e[n]=t[n])}),c.Mixins&&(e.Mixins=c.Mixins.concat(e.Mixins))),e.Methods&&n(e.Methods.split(","),function(t){e[t]=a}),e.Properties&&n(e.Properties.split(","),function(t){var n="_"+t;e[t]=function(e){var t=this,r;return e!==r?(t[n]=e,t):t[n]}}),e.Statics&&n(e.Statics,function(e,n){t[n]=e}),e.Defaults&&c.Defaults&&(e.Defaults=r({},c.Defaults,e.Defaults));for(d in e)f=e[d],u[d]="function"==typeof f&&c[d]?s(d,f):f;return t.prototype=u,t.constructor=t,t.extend=i,t},t}),r(W,[p],function(e){function t(e){function t(){return!1}function n(){return!0}function r(r,i){var o,a,s,u;if(r=r.toLowerCase(),i=i||{},i.type=r,i.target||(i.target=l),i.preventDefault||(i.preventDefault=function(){i.isDefaultPrevented=n},i.stopPropagation=function(){i.isPropagationStopped=n},i.stopImmediatePropagation=function(){i.isImmediatePropagationStopped=n},i.isDefaultPrevented=t,i.isPropagationStopped=t,i.isImmediatePropagationStopped=t),e.beforeFire&&e.beforeFire(i),o=c[r])for(a=0,s=o.length;s>a;a++){if(o[a]=u=o[a],i.isImmediatePropagationStopped())return i.stopPropagation(),i;if(u.call(l,i)===!1)return i.preventDefault(),i}return i}function i(e,n,r){var i,o,a;if(n===!1&&(n=t),n)for(o=e.toLowerCase().split(" "),a=o.length;a--;)e=o[a],i=c[e],i||(i=c[e]=[],u(e,!0)),r?i.unshift(n):i.push(n);return s}function o(e,t){var n,r,i,o,a;if(e)for(o=e.toLowerCase().split(" "),n=o.length;n--;){if(e=o[n],r=c[e],!e){for(i in c)u(i,!1),delete c[i];return s}if(r){if(t)for(a=r.length;a--;)r[a]===t&&r.splice(a,1);else r.length=0;r.length||(u(e,!1),delete c[e])}}else{for(e in c)u(e,!1);c={}}return s}function a(e){return e=e.toLowerCase(),!(!c[e]||0===c[e].length)}var s=this,l,c={},u;e=e||{},l=e.scope||s,u=e.toggleEvent||t,s.fire=r,s.on=i,s.off=o,s.has=a}var n=e.makeMap("focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange mouseout mouseenter mouseleave wheel keydown keypress keyup input contextmenu dragstart dragend dragover draggesture dragdrop drop drag submit"," ");return t.isNative=function(e){return!!n[e.toLowerCase()]},t}),r(V,[z],function(e){function t(e){for(var t=[],n=e.length,r;n--;)r=e[n],r.__checked||(t.push(r),r.__checked=1);for(n=t.length;n--;)delete t[n].__checked;return t}var n=/^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i,r=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,i=/^\s*|\s*$/g,o,a=e.extend({init:function(e){function t(e){return e?(e=e.toLowerCase(),function(t){return"*"===e||t.type===e}):void 0}function o(e){return e?function(t){return t._name===e}:void 0}function a(e){return e?(e=e.split("."),function(t){for(var n=e.length;n--;)if(!t.hasClass(e[n]))return!1;return!0}):void 0}function s(e,t,n){return e?function(r){var i=r[e]?r[e]():"";return t?"="===t?i===n:"*="===t?i.indexOf(n)>=0:"~="===t?(" "+i+" ").indexOf(" "+n+" ")>=0:"!="===t?i!=n:"^="===t?0===i.indexOf(n):"$="===t?i.substr(i.length-n.length)===n:!1:!!n}:void 0}function l(e){var t;return e?(e=/(?:not\((.+)\))|(.+)/i.exec(e),e[1]?(t=u(e[1],[]),function(e){return!d(e,t)}):(e=e[2],function(t,n,r){return"first"===e?0===n:"last"===e?n===r-1:"even"===e?n%2===0:"odd"===e?n%2===1:t[e]?t[e]():!1})):void 0}function c(e,r,c){function u(e){e&&r.push(e)}var d;return d=n.exec(e.replace(i,"")),u(t(d[1])),u(o(d[2])),u(a(d[3])),u(s(d[4],d[5],d[6])),u(l(d[7])),r.psuedo=!!d[7],r.direct=c,r}function u(e,t){var n=[],i,o,a;do if(r.exec(""),o=r.exec(e),o&&(e=o[3],n.push(o[1]),o[2])){i=o[3];break}while(o);for(i&&u(i,t),e=[],a=0;a"!=n[a]&&e.push(c(n[a],[],">"===n[a-1]));return t.push(e),t}var d=this.match;this._selectors=u(e,[])},match:function(e,t){var n,r,i,o,a,s,l,c,u,d,f,p,h;for(t=t||this._selectors,n=0,r=t.length;r>n;n++){for(a=t[n],o=a.length,h=e,p=0,i=o-1;i>=0;i--)for(c=a[i];h;){if(c.psuedo)for(f=h.parent().items(),u=d=f.length;u--&&f[u]!==h;);for(s=0,l=c.length;l>s;s++)if(!c[s](h,u,d)){s=l+1;break}if(s===l){p++;break}if(i===o-1)break;h=h.parent()}if(p===o)return!0}return!1},find:function(e){function n(e,t,i){var o,a,s,l,c,u=t[i];for(o=0,a=e.length;a>o;o++){for(c=e[o],s=0,l=u.length;l>s;s++)if(!u[s](c,o,a)){s=l+1;break}if(s===l)i==t.length-1?r.push(c):c.items&&n(c.items(),t,i+1);else if(u.direct)return;c.items&&n(c.items(),t,i)}}var r=[],i,s,l=this._selectors;if(e.items){for(i=0,s=l.length;s>i;i++)n(e.items(),l[i],0);s>1&&(r=t(r))}return o||(o=a.Collection),new o(r)}});return a}),r(U,[p,V,z],function(e,t,n){var r,i,o=Array.prototype.push,a=Array.prototype.slice;return i={length:0,init:function(e){e&&this.add(e)},add:function(t){var n=this;return e.isArray(t)?o.apply(n,t):t instanceof r?n.add(t.toArray()):o.call(n,t),n},set:function(e){var t=this,n=t.length,r;for(t.length=0,t.add(e),r=t.length;n>r;r++)delete t[r];return t},filter:function(e){var n=this,i,o,a=[],s,l;for("string"==typeof e?(e=new t(e),l=function(t){return e.match(t)}):l=e,i=0,o=n.length;o>i;i++)s=n[i],l(s)&&a.push(s);return new r(a)},slice:function(){return new r(a.apply(this,arguments))},eq:function(e){return-1===e?this.slice(e):this.slice(e,+e+1)},each:function(t){return e.each(this,t),this},toArray:function(){return e.toArray(this)},indexOf:function(e){for(var t=this,n=t.length;n--&&t[n]!==e;);return n},reverse:function(){return new r(e.toArray(this).reverse())},hasClass:function(e){return this[0]?this[0].hasClass(e):!1},prop:function(e,t){var n=this,r,i;return t!==r?(n.each(function(n){n[e]&&n[e](t)}),n):(i=n[0],i&&i[e]?i[e]():void 0)},exec:function(t){var n=this,r=e.toArray(arguments).slice(1);return n.each(function(e){e[t]&&e[t].apply(e,r)}),n},remove:function(){for(var e=this.length;e--;)this[e].remove();return this}},e.each("fire on off show hide addClass removeClass append prepend before after reflow".split(" "),function(t){i[t]=function(){var n=e.toArray(arguments);return this.each(function(e){t in e&&e[t].apply(e,n)}),this}}),e.each("text name disabled active selected checked visible parent value data".split(" "),function(e){i[e]=function(t){return this.prop(e,t)}}),r=n.extend(i),t.Collection=r,r}),r(q,[p,y],function(e,t){return{id:function(){return t.DOM.uniqueId()},createFragment:function(e){return t.DOM.createFragment(e)},getWindowSize:function(){return t.DOM.getViewPort()},getSize:function(e){var t,n;if(e.getBoundingClientRect){var r=e.getBoundingClientRect();t=Math.max(r.width||r.right-r.left,e.offsetWidth),n=Math.max(r.height||r.bottom-r.bottom,e.offsetHeight)}else t=e.offsetWidth,n=e.offsetHeight;return{width:t,height:n}},getPos:function(e,n){return t.DOM.getPos(e,n)},getViewPort:function(e){return t.DOM.getViewPort(e)},get:function(e){return document.getElementById(e)},addClass:function(e,n){return t.DOM.addClass(e,n)},removeClass:function(e,n){return t.DOM.removeClass(e,n)},hasClass:function(e,n){return t.DOM.hasClass(e,n)},toggleClass:function(e,n,r){return t.DOM.toggleClass(e,n,r)},css:function(e,n,r){return t.DOM.setStyle(e,n,r)},on:function(e,n,r,i){return t.DOM.bind(e,n,r,i)},off:function(e,n,r){return t.DOM.unbind(e,n,r)},fire:function(e,n,r){return t.DOM.fire(e,n,r)},innerHtml:function(e,n){t.DOM.setHTML(e,n)}}}),r($,[z,p,W,U,q],function(e,t,n,r,i){function o(e){return e._eventDispatcher||(e._eventDispatcher=new n({scope:e,toggleEvent:function(t,r){r&&n.isNative(t)&&(e._nativeEvents||(e._nativeEvents={}),e._nativeEvents[t]=!0,e._rendered&&e.bindPendingEvents())}})),e._eventDispatcher}var a={},s="onmousewheel"in document,l=!1,c="mce-",u=e.extend({Statics:{elementIdCache:a,classPrefix:c},isRtl:function(){return u.rtl},classPrefix:c,init:function(e){var n=this,r,o;if(n.settings=e=t.extend({},n.Defaults,e),n._id=e.id||i.id(),n._text=n._name="",n._width=n._height=0,n._aria={role:e.role},r=e.classes)for(r=r.split(" "),r.map={},o=r.length;o--;)r.map[r[o]]=!0;n._classes=r||[],n.visible(!0),t.each("title text width height name classes visible disabled active value".split(" "),function(t){var r=e[t],i;r!==i?n[t](r):n["_"+t]===i&&(n["_"+t]=!1)}),n.on("click",function(){return n.disabled()?!1:void 0}),e.classes&&t.each(e.classes.split(" "),function(e){n.addClass(e)}),n.settings=e,n._borderBox=n.parseBox(e.border),n._paddingBox=n.parseBox(e.padding),n._marginBox=n.parseBox(e.margin),e.hidden&&n.hide()},Properties:"parent,title,text,width,height,disabled,active,name,value",Methods:"renderHtml",getContainerElm:function(){return document.body},getParentCtrl:function(e){for(var t,n=this.getRoot().controlIdLookup;e&&n&&!(t=n[e.id]);)e=e.parentNode;return t},parseBox:function(e){var t,n=10;if(e)return"number"==typeof e?(e=e||0,{top:e,left:e,bottom:e,right:e}):(e=e.split(" "),t=e.length,1===t?e[1]=e[2]=e[3]=e[0]:2===t?(e[2]=e[0],e[3]=e[1]):3===t&&(e[3]=e[1]),{top:parseInt(e[0],n)||0,right:parseInt(e[1],n)||0,bottom:parseInt(e[2],n)||0,left:parseInt(e[3],n)||0})},borderBox:function(){return this._borderBox},paddingBox:function(){return this._paddingBox},marginBox:function(){return this._marginBox},measureBox:function(e,t){function n(t){var n=document.defaultView;return n?(t=t.replace(/[A-Z]/g,function(e){return"-"+e}),n.getComputedStyle(e,null).getPropertyValue(t)):e.currentStyle[t]}function r(e){var t=parseFloat(n(e),10);return isNaN(t)?0:t}return{top:r(t+"TopWidth"),right:r(t+"RightWidth"),bottom:r(t+"BottomWidth"),left:r(t+"LeftWidth")}},initLayoutRect:function(){var e=this,t=e.settings,n,r,o=e.getEl(),a,s,l,c,u,d,f,p;n=e._borderBox=e._borderBox||e.measureBox(o,"border"),e._paddingBox=e._paddingBox||e.measureBox(o,"padding"),e._marginBox=e._marginBox||e.measureBox(o,"margin"),p=i.getSize(o),d=t.minWidth,f=t.minHeight,l=d||p.width,c=f||p.height,a=t.width,s=t.height,u=t.autoResize,u="undefined"!=typeof u?u:!a&&!s,a=a||l,s=s||c;var h=n.left+n.right,m=n.top+n.bottom,g=t.maxWidth||65535,v=t.maxHeight||65535;return e._layoutRect=r={x:t.x||0,y:t.y||0,w:a,h:s,deltaW:h,deltaH:m,contentW:a-h,contentH:s-m,innerW:a-h,innerH:s-m,startMinWidth:d||0,startMinHeight:f||0,minW:Math.min(l,g),minH:Math.min(c,v),maxW:g,maxH:v,autoResize:u,scrollW:0},e._lastLayoutRect={},r},layoutRect:function(e){var t=this,n=t._layoutRect,r,i,o,a,s,l;return n||(n=t.initLayoutRect()),e?(o=n.deltaW,a=n.deltaH,e.x!==s&&(n.x=e.x),e.y!==s&&(n.y=e.y),e.minW!==s&&(n.minW=e.minW),e.minH!==s&&(n.minH=e.minH),i=e.w,i!==s&&(i=in.maxW?n.maxW:i,n.w=i,n.innerW=i-o),i=e.h,i!==s&&(i=in.maxH?n.maxH:i,n.h=i,n.innerH=i-a),i=e.innerW,i!==s&&(i=in.maxW-o?n.maxW-o:i,n.innerW=i,n.w=i+o),i=e.innerH,i!==s&&(i=in.maxH-a?n.maxH-a:i,n.innerH=i,n.h=i+a),e.contentW!==s&&(n.contentW=e.contentW),e.contentH!==s&&(n.contentH=e.contentH),r=t._lastLayoutRect,(r.x!==n.x||r.y!==n.y||r.w!==n.w||r.h!==n.h)&&(l=u.repaintControls,l&&l.map&&!l.map[t._id]&&(l.push(t),l.map[t._id]=!0),r.x=n.x,r.y=n.y,r.w=n.w,r.h=n.h),t):n},repaint:function(){var e=this,t,n,r,i,o=0,a=0,s,l;l=document.createRange?function(e){return e}:Math.round,t=e.getEl().style,r=e._layoutRect,s=e._lastRepaintRect||{},i=e._borderBox,o=i.left+i.right,a=i.top+i.bottom,r.x!==s.x&&(t.left=l(r.x)+"px",s.x=r.x),r.y!==s.y&&(t.top=l(r.y)+"px",s.y=r.y),r.w!==s.w&&(t.width=l(r.w-o)+"px",s.w=r.w),r.h!==s.h&&(t.height=l(r.h-a)+"px",s.h=r.h),e._hasBody&&r.innerW!==s.innerW&&(n=e.getEl("body").style,n.width=l(r.innerW)+"px",s.innerW=r.innerW),e._hasBody&&r.innerH!==s.innerH&&(n=n||e.getEl("body").style,n.height=l(r.innerH)+"px",s.innerH=r.innerH),e._lastRepaintRect=s,e.fire("repaint",{},!1)},on:function(e,t){function n(e){var t,n;return"string"!=typeof e?e:function(i){return t||r.parentsAndSelf().each(function(r){var i=r.settings.callbacks;return i&&(t=i[e])?(n=r,!1):void 0}),t.call(n,i)}}var r=this;return o(r).on(e,n(t)),r},off:function(e,t){return o(this).off(e,t),this},fire:function(e,t,n){var r=this;if(t=t||{},t.control||(t.control=r),t=o(r).fire(e,t),n!==!1&&r.parent)for(var i=r.parent();i&&!t.isPropagationStopped();)i.fire(e,t,!1),i=i.parent();return t},hasEventListeners:function(e){return o(this).has(e)},parents:function(e){var t=this,n,i=new r;for(n=t.parent();n;n=n.parent())i.add(n);return e&&(i=i.filter(e)),i},parentsAndSelf:function(e){return new r(this).add(this.parents(e))},next:function(){var e=this.parent().items();return e[e.indexOf(this)+1]},prev:function(){var e=this.parent().items();return e[e.indexOf(this)-1]},findCommonAncestor:function(e,t){for(var n;e;){for(n=t;n&&e!=n;)n=n.parent();if(e==n)break;e=e.parent()}return e},hasClass:function(e,t){var n=this._classes[t||"control"];return e=this.classPrefix+e,n&&!!n.map[e]},addClass:function(e,t){var n=this,r,i;return e=this.classPrefix+e,r=n._classes[t||"control"],r||(r=[],r.map={},n._classes[t||"control"]=r),r.map[e]||(r.map[e]=e,r.push(e),n._rendered&&(i=n.getEl(t),i&&(i.className=r.join(" ")))),n},removeClass:function(e,t){var n=this,r,i,o;if(e=this.classPrefix+e,r=n._classes[t||"control"],r&&r.map[e])for(delete r.map[e],i=r.length;i--;)r[i]===e&&r.splice(i,1);return n._rendered&&(o=n.getEl(t),o&&(o.className=r.join(" "))),n},toggleClass:function(e,t,n){var r=this;return t?r.addClass(e,n):r.removeClass(e,n),r},classes:function(e){var t=this._classes[e||"control"];return t?t.join(" "):""},innerHtml:function(e){return i.innerHtml(this.getEl(),e),this},getEl:function(e,t){var n,r=e?this._id+"-"+e:this._id;return n=a[r]=(t===!0?null:a[r])||i.get(r)},visible:function(e){var t=this,n;return"undefined"!=typeof e?(t._visible!==e&&(t._rendered&&(t.getEl().style.display=e?"":"none"),t._visible=e,n=t.parent(),n&&(n._lastRect=null),t.fire(e?"show":"hide")),t):t._visible},show:function(){return this.visible(!0)},hide:function(){return this.visible(!1)},focus:function(){try{this.getEl().focus()}catch(e){}return this},blur:function(){return this.getEl().blur(),this},aria:function(e,t){var n=this,r=n.getEl(n.ariaTarget);return"undefined"==typeof t?n._aria[e]:(n._aria[e]=t,n._rendered&&r.setAttribute("role"==e?e:"aria-"+e,t),n)},encode:function(e,t){return t!==!1&&(e=this.translate(e)),(e||"").replace(/[&<>"]/g,function(e){return"&#"+e.charCodeAt(0)+";"})},translate:function(e){return u.translate?u.translate(e):e},before:function(e){var t=this,n=t.parent();return n&&n.insert(e,n.items().indexOf(t),!0),t},after:function(e){var t=this,n=t.parent();return n&&n.insert(e,n.items().indexOf(t)),t},remove:function(){var e=this,t=e.getEl(),n=e.parent(),r,o;if(e.items){var s=e.items().toArray();for(o=s.length;o--;)s[o].remove()}n&&n.items&&(r=[],n.items().each(function(t){t!==e&&r.push(t)}),n.items().set(r),n._lastRect=null),e._eventsRoot&&e._eventsRoot==e&&i.off(t);var l=e.getRoot().controlIdLookup;if(l&&delete l[e._id],delete a[e._id],t&&t.parentNode){var c=t.getElementsByTagName("*");for(o=c.length;o--;)delete a[c[o].id];t.parentNode.removeChild(t)}return e._rendered=!1,e},renderBefore:function(e){var t=this;return e.parentNode.insertBefore(i.createFragment(t.renderHtml()),e),t.postRender(),t},renderTo:function(e){var t=this;return e=e||t.getContainerElm(),e.appendChild(i.createFragment(t.renderHtml())),t.postRender(),t},postRender:function(){var e=this,t=e.settings,n,r,o,a,s;for(a in t)0===a.indexOf("on")&&e.on(a.substr(2),t[a]);if(e._eventsRoot){for(o=e.parent();!s&&o;o=o.parent())s=o._eventsRoot;if(s)for(a in s._nativeEvents)e._nativeEvents[a]=!0}e.bindPendingEvents(),t.style&&(n=e.getEl(),n&&(n.setAttribute("style",t.style),n.style.cssText=t.style)),e._visible||i.css(e.getEl(),"display","none"),e.settings.border&&(r=e.borderBox(),i.css(e.getEl(),{"border-top-width":r.top,"border-right-width":r.right,"border-bottom-width":r.bottom,"border-left-width":r.left}));var l=e.getRoot();l.controlIdLookup||(l.controlIdLookup={}),l.controlIdLookup[e._id]=e;for(var c in e._aria)e.aria(c,e._aria[c]);e.fire("postrender",{},!1)},scrollIntoView:function(e){function t(e,t){var n,r,i=e;for(n=r=0;i&&i!=t&&i.nodeType;)n+=i.offsetLeft||0,r+=i.offsetTop||0,i=i.offsetParent;return{x:n,y:r}}var n=this.getEl(),r=n.parentNode,i,o,a,s,l,c,u=t(n,r);return i=u.x,o=u.y,a=n.offsetWidth,s=n.offsetHeight,l=r.clientWidth,c=r.clientHeight,"end"==e?(i-=l-a,o-=c-s):"center"==e&&(i-=l/2-a/2,o-=c/2-s/2),r.scrollLeft=i,r.scrollTop=o,this},bindPendingEvents:function(){function e(e){var t=o.getParentCtrl(e.target);t&&t.fire(e.type,e)}function t(){var e=d._lastHoverCtrl;e&&(e.fire("mouseleave",{target:e.getEl()}),e.parents().each(function(e){e.fire("mouseleave",{target:e.getEl()})}),d._lastHoverCtrl=null)}function n(e){var t=o.getParentCtrl(e.target),n=d._lastHoverCtrl,r=0,i,a,s;if(t!==n){if(d._lastHoverCtrl=t,a=t.parents().toArray().reverse(),a.push(t),n){for(s=n.parents().toArray().reverse(),s.push(n),r=0;r=r;i--)n=s[i],n.fire("mouseleave",{target:n.getEl()})}for(i=r;ia;a++)d=u[a]._eventsRoot;for(d||(d=u[u.length-1]||o),o._eventsRoot=d,c=a,a=0;c>a;a++)u[a]._eventsRoot=d;var h=d._delegates;h||(h=d._delegates={});for(p in f){if(!f)return!1;"wheel"!==p||l?("mouseenter"===p||"mouseleave"===p?d._hasMouseEnter||(i.on(d.getEl(),"mouseleave",t),i.on(d.getEl(),"mouseover",n),d._hasMouseEnter=1):h[p]||(i.on(d.getEl(),p,e),h[p]=!0),f[p]=!1):s?i.on(o.getEl(),"mousewheel",r):i.on(o.getEl(),"DOMMouseScroll",r)}}},getRoot:function(){for(var e=this,t,n=[];e;){if(e.rootControl){t=e.rootControl;break}n.push(e),t=e,e=e.parent()}t||(t=this);for(var r=n.length;r--;)n[r].rootControl=t;return t},reflow:function(){return this.repaint(),this}});return u}),r(j,[],function(){var e={},t;return{add:function(t,n){e[t.toLowerCase()]=n},has:function(t){return!!e[t.toLowerCase()]},create:function(n,r){var i,o,a;if(!t){a=tinymce.ui;for(o in a)e[o.toLowerCase()]=a[o];t=!0}if("string"==typeof n?(r=r||{},r.type=n):(r=n,n=r.type),n=n.toLowerCase(),i=e[n],!i)throw new Error("Could not find control by type: "+n);return i=new i(r),i.type=n,i}}}),r(K,[],function(){return function(e){function t(e){return e=e||b,e&&e.getAttribute("role")}function n(e){for(var n,r=e||b;r=r.parentNode;)if(n=t(r))return n}function r(e){var t=b;return t?t.getAttribute("aria-"+e):void 0}function i(e){var t=e.tagName.toUpperCase();return"INPUT"==t||"TEXTAREA"==t}function o(e){return i(e)&&!e.hidden?!0:/^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell)$/.test(t(e))?!0:!1}function a(e){function t(e){if(1==e.nodeType&&"none"!=e.style.display){o(e)&&n.push(e);for(var r=0;re?e=t.length-1:e>=t.length&&(e=0),t[e]&&t[e].focus(),e}function u(e,t){var n=-1,r=s();t=t||a(r.getEl());for(var i=0;i=0&&(n=t.getEl(),n&&n.parentNode.removeChild(n),n=e.getEl(),n&&n.parentNode.removeChild(n)),t.parent(this)},create:function(t){var n=this,i,a=[];return o.isArray(t)||(t=[t]),o.each(t,function(t){t&&(t instanceof e||("string"==typeof t&&(t={type:t}),i=o.extend({},n.settings.defaults,t),t.type=i.type=i.type||t.type||n.settings.defaultType||(i.defaults?i.defaults.type:null),t=r.create(i)),a.push(t))}),a},renderNew:function(){var e=this;return e.items().each(function(t,n){var r,i;t.parent(e),t._rendered||(r=e.getEl("body"),i=a.createFragment(t.renderHtml()),r.hasChildNodes()&&n<=r.childNodes.length-1?r.insertBefore(i,r.childNodes[n]):r.appendChild(i),t.postRender())}),e._layout.applyClasses(e),e._lastRect=null,e},append:function(e){return this.add(e).renderNew()},prepend:function(e){var t=this;return t.items().set(t.create(e).concat(t.items().toArray())),t.renderNew()},insert:function(e,t,n){var r=this,i,o,a;return e=r.create(e),i=r.items(),!n&&t=0&&t
'+(e.settings.html||"")+t.renderHtml(e)+"
"},postRender:function(){var e=this,t;return e.items().exec("postRender"),e._super(),e._layout.postRender(e),e._rendered=!0,e.settings.style&&a.css(e.getEl(),e.settings.style),e.settings.border&&(t=e.borderBox(),a.css(e.getEl(),{"border-top-width":t.top,"border-right-width":t.right,"border-bottom-width":t.bottom,"border-left-width":t.left})),e.parent()||(e.keyboardNav=new i({root:e})),e},initLayoutRect:function(){var e=this,t=e._super();return e._layout.recalc(e),t},recalc:function(){var e=this,t=e._layoutRect,n=e._lastRect;return n&&n.w==t.w&&n.h==t.h?void 0:(e._layout.recalc(e),t=e.layoutRect(),e._lastRect={x:t.x,y:t.y,w:t.w,h:t.h},!0)},reflow:function(){var t;if(this.visible()){for(e.repaintControls=[],e.repaintControls.map={},this.recalc(),t=e.repaintControls.length;t--;)e.repaintControls[t].repaint();"flow"!==this.settings.layout&&"stack"!==this.settings.layout&&this.repaint(),e.repaintControls=[]}return this}})}),r(Y,[q],function(e){function t(){var e=document,t,n,r,i,o,a,s,l,c=Math.max;return t=e.documentElement,n=e.body,r=c(t.scrollWidth,n.scrollWidth),i=c(t.clientWidth,n.clientWidth),o=c(t.offsetWidth,n.offsetWidth),a=c(t.scrollHeight,n.scrollHeight),s=c(t.clientHeight,n.clientHeight),l=c(t.offsetHeight,n.offsetHeight),{width:o>r?i:r,height:l>a?s:a}}return function(n,r){function i(){return a.getElementById(r.handle||n)}var o,a=document,s,l,c,u,d,f;r=r||{},l=function(n){var l=t(),p,h;n.preventDefault(),s=n.button,p=i(),d=n.screenX,f=n.screenY,h=window.getComputedStyle?window.getComputedStyle(p,null).getPropertyValue("cursor"):p.runtimeStyle.cursor,o=a.createElement("div"),e.css(o,{position:"absolute",top:0,left:0,width:l.width,height:l.height,zIndex:2147483647,opacity:1e-4,background:"red",cursor:h}),a.body.appendChild(o),e.on(a,"mousemove",u),e.on(a,"mouseup",c),r.start(n)},u=function(e){return e.button!==s?c(e):(e.deltaX=e.screenX-d,e.deltaY=e.screenY-f,e.preventDefault(),void r.drag(e))},c=function(t){e.off(a,"mousemove",u),e.off(a,"mouseup",c),o.parentNode.removeChild(o),r.stop&&r.stop(t)},this.destroy=function(){e.off(i())},e.on(i(),"mousedown",l)}}),r(X,[q,Y],function(e,t){return{init:function(){var e=this;e.on("repaint",e.renderScroll)},renderScroll:function(){function n(){function t(t,a,s,l,c,u){var d,f,p,h,m,g,v,y,b;if(f=i.getEl("scroll"+t)){if(y=a.toLowerCase(),b=s.toLowerCase(),i.getEl("absend")&&e.css(i.getEl("absend"),y,i.layoutRect()[l]-1),!c)return void e.css(f,"display","none");e.css(f,"display","block"),d=i.getEl("body"),p=i.getEl("scroll"+t+"t"),h=d["client"+s]-2*o,h-=n&&r?f["client"+u]:0,m=d["scroll"+s],g=h/m,v={},v[y]=d["offset"+a]+o,v[b]=h,e.css(f,v),v={},v[y]=d["scroll"+a]*g,v[b]=h*g,e.css(p,v)}}var n,r,a;a=i.getEl("body"),n=a.scrollWidth>a.clientWidth,r=a.scrollHeight>a.clientHeight,t("h","Left","Width","contentW",n,"Height"),t("v","Top","Height","contentH",r,"Width")}function r(){function n(n,r,a,s,l){var c,u=i._id+"-scroll"+n,d=i.classPrefix;i.getEl().appendChild(e.createFragment('
')),i.draghelper=new t(u+"t",{start:function(){c=i.getEl("body")["scroll"+r],e.addClass(e.get(u),d+"active")},drag:function(e){var t,u,d,f,p=i.layoutRect();u=p.contentW>p.innerW,d=p.contentH>p.innerH,f=i.getEl("body")["client"+a]-2*o,f-=u&&d?i.getEl("scroll"+n)["client"+l]:0,t=f/i.getEl("body")["scroll"+a],i.getEl("body")["scroll"+r]=c+e["delta"+s]/t},stop:function(){e.removeClass(e.get(u),d+"active")}})}i.addClass("scroll"),n("v","Top","Height","Y","Width"),n("h","Left","Width","X","Height")}var i=this,o=2;i.settings.autoScroll&&(i._hasScroll||(i._hasScroll=!0,r(),i.on("wheel",function(e){var t=i.getEl("body");t.scrollLeft+=10*(e.deltaX||0),t.scrollTop+=10*e.deltaY,n()}),e.on(i.getEl("body"),"scroll",n)),n())}}}),r(J,[G,X],function(e,t){return e.extend({Defaults:{layout:"fit",containerCls:"panel"},Mixins:[t],renderHtml:function(){var e=this,t=e._layout,n=e.settings.html;return e.preRender(),t.preRender(e),"undefined"==typeof n?n='
'+t.renderHtml(e)+"
":("function"==typeof n&&(n=n.call(e)),e._hasBody=!1),'
'+(e._preBodyHtml||"")+n+"
"}})}),r(Q,[q],function(e){function t(t,n,r){var i,o,a,s,l,c,u,d,f,p;return f=e.getViewPort(),o=e.getPos(n),a=o.x,s=o.y,t._fixed&&(a-=f.x,s-=f.y),i=t.getEl(),p=e.getSize(i),l=p.width,c=p.height,p=e.getSize(n),u=p.width,d=p.height,r=(r||"").split(""),"b"===r[0]&&(s+=d),"r"===r[1]&&(a+=u),"c"===r[0]&&(s+=Math.round(d/2)),"c"===r[1]&&(a+=Math.round(u/2)),"b"===r[3]&&(s-=c),"r"===r[4]&&(a-=l),"c"===r[3]&&(s-=Math.round(c/2)),"c"===r[4]&&(a-=Math.round(l/2)),{x:a,y:s,w:l,h:c}}return{testMoveRel:function(n,r){for(var i=e.getViewPort(),o=0;o0&&a.x+a.w0&&a.y+a.hi.x&&a.x+a.wi.y&&a.y+a.he?0:e+n>t?(e=t-n,0>e?0:e):e}var i=this;if(i.settings.constrainToViewport){var o=e.getViewPort(window),a=i.layoutRect();t=r(t,o.w+o.x,a.w),n=r(n,o.h+o.y,a.h)}return i._rendered?i.layoutRect({x:t,y:n}).repaint():(i.settings.x=t,i.settings.y=n),i.fire("move",{x:t,y:n}),i}}}),r(Z,[q],function(e){return{resizeToContent:function(){this._layoutRect.autoResize=!0,this._lastRect=null,this.reflow()},resizeTo:function(t,n){if(1>=t||1>=n){var r=e.getWindowSize();t=1>=t?t*r.w:t,n=1>=n?n*r.h:n}return this._layoutRect.autoResize=!1,this.layoutRect({minW:t,minH:n,w:t,h:n}).reflow()},resizeBy:function(e,t){var n=this,r=n.layoutRect();return n.resizeTo(r.w+e,r.h+t)}}}),r(et,[J,Q,Z,q],function(e,t,n,r){function i(e){var t;for(t=s.length;t--;)s[t]===e&&s.splice(t,1);for(t=l.length;t--;)l[t]===e&&l.splice(t,1)}var o,a,s=[],l=[],c,u=e.extend({Mixins:[t,n],init:function(e){function t(){var e,t=u.zIndex||65535,n;if(l.length)for(e=0;en&&(e.fixed(!1).layoutRect({y:e._autoFixY}).repaint(),t(!1,e._autoFixY-n)):(e._autoFixY=e.layoutRect().y,e._autoFixY'),n=n.firstChild,d.getContainerElm().appendChild(n),setTimeout(function(){r.addClass(n,i+"in"),r.addClass(d.getEl(),i+"in")},0),c=!0),l.push(d),t()}}),d.on("close hide",function(e){if(e.control==d){for(var n=l.length;n--;)l[n]===d&&l.splice(n,1);t()}}),d.on("show",function(){d.parents().each(function(e){return e._fixed?(d.fixed(!0),!1):void 0})}),e.popover&&(d._preBodyHtml='
',d.addClass("popover").addClass("bottom").addClass(d.isRtl()?"end":"start"))},fixed:function(e){var t=this;if(t._fixed!=e){if(t._rendered){var n=r.getViewPort();e?t.layoutRect().y-=n.y:t.layoutRect().y+=n.y}t.toggleClass("fixed",e),t._fixed=e}return t},show:function(){var e=this,t,n=e._super();for(t=s.length;t--&&s[t]!==e;);return-1===t&&s.push(e),n},hide:function(){return i(this),this._super()},hideAll:function(){u.hideAll()},close:function(){var e=this;return e.fire("close"),e.remove()},remove:function(){i(this),this._super()},postRender:function(){var e=this;return e.settings.bodyRole&&this.getEl("body").setAttribute("role",e.settings.bodyRole),e._super()}});return u.hideAll=function(){for(var e=s.length;e--;){var t=s[e];t&&t.settings.autohide&&(t.hide(),s.splice(e,1))}},u}),r(tt,[et,J,q,Y],function(e,t,n,r){var i=e.extend({modal:!0,Defaults:{border:1,layout:"flex",containerCls:"panel",role:"dialog",callbacks:{submit:function(){this.fire("submit",{data:this.toJSON()})},close:function(){this.close()}}},init:function(e){var n=this;n._super(e),n.isRtl()&&n.addClass("rtl"),n.addClass("window"),n._fixed=!0,e.buttons&&(n.statusbar=new t({layout:"flex",border:"1 0 0 0",spacing:3,padding:10,align:"center",pack:n.isRtl()?"start":"end",defaults:{type:"button"},items:e.buttons}),n.statusbar.addClass("foot"),n.statusbar.parent(n)),n.on("click",function(e){-1!=e.target.className.indexOf(n.classPrefix+"close")&&n.close()}),n.on("cancel",function(){n.close()}),n.aria("describedby",n.describedBy||n._id+"-none"),n.aria("label",e.title),n._fullscreen=!1},recalc:function(){var e=this,t=e.statusbar,r,i,o,a;e._fullscreen&&(e.layoutRect(n.getWindowSize()),e.layoutRect().contentH=e.layoutRect().innerH),e._super(),r=e.layoutRect(),e.settings.title&&!e._fullscreen&&(i=r.headerW,i>r.w&&(o=r.x-Math.max(0,i/2),e.layoutRect({w:i,x:o}),a=!0)),t&&(t.layoutRect({w:e.layoutRect().innerW}).recalc(),i=t.layoutRect().minW+r.deltaW,i>r.w&&(o=r.x-Math.max(0,i-r.w),e.layoutRect({w:i,x:o}),a=!0)),a&&e.recalc()},initLayoutRect:function(){var e=this,t=e._super(),r=0,i;if(e.settings.title&&!e._fullscreen){i=e.getEl("head");var o=n.getSize(i);t.headerW=o.width,t.headerH=o.height,r+=t.headerH}e.statusbar&&(r+=e.statusbar.layoutRect().h),t.deltaH+=r,t.minH+=r,t.h+=r;var a=n.getWindowSize();return t.x=Math.max(0,a.w/2-t.w/2),t.y=Math.max(0,a.h/2-t.h/2),t},renderHtml:function(){var e=this,t=e._layout,n=e._id,r=e.classPrefix,i=e.settings,o="",a="",s=i.html;return e.preRender(),t.preRender(e),i.title&&(o='
'+e.encode(i.title)+'
'),i.url&&(s=''),"undefined"==typeof s&&(s=t.renderHtml(e)),e.statusbar&&(a=e.statusbar.renderHtml()),'
'+o+'
'+s+"
"+a+"
"},fullscreen:function(e){var t=this,r=document.documentElement,i,o=t.classPrefix,a;if(e!=t._fullscreen)if(n.on(window,"resize",function(){var e;if(t._fullscreen)if(i)t._timer||(t._timer=setTimeout(function(){var e=n.getWindowSize();t.moveTo(0,0).resizeTo(e.w,e.h),t._timer=0},50));else{e=(new Date).getTime();var r=n.getWindowSize();t.moveTo(0,0).resizeTo(r.w,r.h),(new Date).getTime()-e>50&&(i=!0)}}),a=t.layoutRect(),t._fullscreen=e,e){t._initial={x:a.x,y:a.y,w:a.w,h:a.h},t._borderBox=t.parseBox("0"),t.getEl("head").style.display="none",a.deltaH-=a.headerH+2,n.addClass(r,o+"fullscreen"),n.addClass(document.body,o+"fullscreen"),t.addClass("fullscreen");var s=n.getWindowSize();t.moveTo(0,0).resizeTo(s.w,s.h)}else t._borderBox=t.parseBox(t.settings.border),t.getEl("head").style.display="",a.deltaH+=a.headerH,n.removeClass(r,o+"fullscreen"),n.removeClass(document.body,o+"fullscreen"),t.removeClass("fullscreen"),t.moveTo(t._initial.x,t._initial.y).resizeTo(t._initial.w,t._initial.h);return t.reflow()},postRender:function(){var e=this,t;setTimeout(function(){e.addClass("in")},0),e._super(),e.statusbar&&e.statusbar.postRender(),e.focus(),this.dragHelper=new r(e._id+"-dragh",{start:function(){t={x:e.layoutRect().x,y:e.layoutRect().y}},drag:function(n){e.moveTo(t.x+n.deltaX,t.y+n.deltaY)}}),e.on("submit",function(t){t.isDefaultPrevented()||e.close()})},submit:function(){return this.fire("submit",{data:this.toJSON()})},remove:function(){var e=this,t=e.classPrefix;e.dragHelper.destroy(),e._super(),e.statusbar&&this.statusbar.remove(),e._fullscreen&&(n.removeClass(document.documentElement,t+"fullscreen"),n.removeClass(document.body,t+"fullscreen"))},getContentWindow:function(){var e=this.getEl().getElementsByTagName("iframe")[0];return e?e.contentWindow:null}});return i}),r(nt,[tt],function(e){var t=e.extend({init:function(e){e={border:1,padding:20,layout:"flex",pack:"center",align:"center",containerCls:"panel",autoScroll:!0,buttons:{type:"button",text:"Ok",action:"ok"},items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200}},this._super(e)},Statics:{OK:1,OK_CANCEL:2,YES_NO:3,YES_NO_CANCEL:4,msgBox:function(n){var r,i=n.callback||function(){};switch(n.buttons){case t.OK_CANCEL:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close(),i(!0)}},{type:"button",text:"Cancel",onClick:function(e){e.control.parents()[1].close(),i(!1)}}];break;case t.YES_NO:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close(),i(!0)}}];break;case t.YES_NO_CANCEL:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close()}}];break;default:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close(),i(!0)}}]}return new e({padding:20,x:n.x,y:n.y,minWidth:300,minHeight:100,layout:"flex",pack:"center",align:"center",buttons:r,title:n.title,role:"alertdialog",items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200,text:n.text},onPostRender:function(){this.aria("describedby",this.items()[0]._id)},onClose:n.onClose,onCancel:function(){i(!1)}}).renderTo(document.body).reflow()},alert:function(e,n){return"string"==typeof e&&(e={text:e}),e.callback=n,t.msgBox(e)},confirm:function(e,n){return"string"==typeof e&&(e={text:e}),e.callback=n,e.buttons=t.OK_CANCEL,t.msgBox(e)}}});return t}),r(rt,[tt,nt],function(e,t){return function(n){function r(){return o.length?o[o.length-1]:void 0}var i=this,o=[];i.windows=o,i.open=function(t,r){var i;return n.editorManager.activeEditor=n,t.title=t.title||" ",t.url=t.url||t.file,t.url&&(t.width=parseInt(t.width||320,10),t.height=parseInt(t.height||240,10)),t.body&&(t.items={defaults:t.defaults,type:t.bodyType||"form",items:t.body}),t.url||t.buttons||(t.buttons=[{text:"Ok",subtype:"primary",onclick:function(){i.find("form")[0].submit()}},{text:"Cancel",onclick:function(){i.close()}}]),i=new e(t),o.push(i),i.on("close",function(){for(var e=o.length;e--;)o[e]===i&&o.splice(e,1);n.focus()}),t.data&&i.on("postRender",function(){this.find("*").each(function(e){var n=e.name();n in t.data&&e.value(t.data[n])})}),i.features=t||{},i.params=r||{},n.nodeChanged(),i.renderTo().reflow()},i.alert=function(e,r,i){t.alert(e,function(){r?r.call(i||this):n.focus()})},i.confirm=function(e,n,r){t.confirm(e,function(e){n.call(r||this,e)})},i.close=function(){r()&&r().close()},i.getParams=function(){return r()?r().params:null},i.setParams=function(e){r()&&(r().params=e)},i.getWindows=function(){return o}}}),r(it,[R,B,x,m,g,p],function(e,t,n,r,i,o){return function(a){function s(e,t){try{a.getDoc().execCommand(e,!1,t)}catch(n){}}function l(){var e=a.getDoc().documentMode;return e?e:6}function c(e){return e.isDefaultPrevented()}function u(){function t(e){var t=new i(function(){});o.each(a.getBody().getElementsByTagName("*"),function(e){"SPAN"==e.tagName&&e.setAttribute("mce-data-marked",1),!e.hasAttribute("data-mce-style")&&e.hasAttribute("style")&&a.dom.setAttrib(e,"style",e.getAttribute("style"))}),t.observe(a.getDoc(),{childList:!0,attributes:!0,subtree:!0,attributeFilter:["style"]}),a.getDoc().execCommand(e?"ForwardDelete":"Delete",!1,null);var n=a.selection.getRng(),r=n.startContainer.parentNode;o.each(t.takeRecords(),function(e){if(q.isChildOf(e.target,a.getBody())){if("style"==e.attributeName){var t=e.target.getAttribute("data-mce-style");t?e.target.setAttribute("style",t):e.target.removeAttribute("style")}o.each(e.addedNodes,function(e){if("SPAN"==e.nodeName&&!e.getAttribute("mce-data-marked")){var t,i;e==r&&(t=n.startOffset,i=e.firstChild),q.remove(e,!0),i&&(n.setStart(i,t),n.setEnd(i,t),a.selection.setRng(n))}})}}),t.disconnect(),o.each(a.dom.select("span[mce-data-marked]"),function(e){e.removeAttribute("mce-data-marked")})}var n=a.getDoc(),r="data:text/mce-internal,",i=window.MutationObserver,s,l;i||(s=!0,i=function(){function e(e){var t=e.relatedNode||e.target;n.push({target:t,addedNodes:[t]})}function t(e){var t=e.relatedNode||e.target;n.push({target:t,attributeName:e.attrName})}var n=[],r;this.observe=function(n){r=n,r.addEventListener("DOMSubtreeModified",e,!1),r.addEventListener("DOMNodeInsertedIntoDocument",e,!1),r.addEventListener("DOMNodeInserted",e,!1),r.addEventListener("DOMAttrModified",t,!1)},this.disconnect=function(){r.removeEventListener("DOMSubtreeModified",e,!1),r.removeEventListener("DOMNodeInsertedIntoDocument",e,!1),r.removeEventListener("DOMNodeInserted",e,!1),r.removeEventListener("DOMAttrModified",t,!1)},this.takeRecords=function(){return n}}),a.on("keydown",function(n){var r=n.keyCode==U,i=e.metaKeyPressed(n);if(!c(n)&&(r||n.keyCode==V)){var o=a.selection.getRng(),s=o.startContainer,l=o.startOffset;if(!i&&o.collapsed&&3==s.nodeType&&(r?l0))return;n.preventDefault(),i&&a.selection.getSel().modify("extend",r?"forward":"backward","word"),t(r)}}),a.on("keypress",function(n){c(n)||$.isCollapsed()||!n.charCode||e.metaKeyPressed(n)||(n.preventDefault(),t(!0),a.selection.setContent(String.fromCharCode(n.charCode)))}),a.addCommand("Delete",function(){t()}),a.addCommand("ForwardDelete",function(){t(!0)}),s||(a.on("dragstart",function(e){var t;a.selection.isCollapsed()&&"IMG"==e.target.tagName&&$.select(e.target),l=$.getRng(),t=a.selection.getContent(),t.length>0&&e.dataTransfer.setData("URL","data:text/mce-internal,"+escape(t))}),a.on("drop",function(e){if(!c(e)){var i=e.dataTransfer.getData("URL");if(!i||-1==i.indexOf(r)||!n.caretRangeFromPoint)return;i=unescape(i.substr(r.length)),n.caretRangeFromPoint&&(e.preventDefault(),window.setTimeout(function(){var r=n.caretRangeFromPoint(e.x,e.y);l&&($.setRng(l),l=null),t(),$.setRng(r),a.insertContent(i)},0))}}),a.on("cut",function(e){!c(e)&&e.clipboardData&&(e.preventDefault(),e.clipboardData.clearData(),e.clipboardData.setData("text/html",a.selection.getContent()),e.clipboardData.setData("text/plain",a.selection.getContent({format:"text"})),t(!0))}))}function d(){function e(e){var t=q.create("body"),n=e.cloneContents();return t.appendChild(n),$.serializer.serialize(t,{format:"html"})}function n(n){if(!n.setStart){if(n.item)return!1;var r=n.duplicate();return r.moveToElementText(a.getBody()),t.compareRanges(n,r)}var i=e(n),o=q.createRng();o.selectNode(a.getBody());var s=e(o);return i===s}a.on("keydown",function(e){var t=e.keyCode,r,i;if(!c(e)&&(t==U||t==V)){if(r=a.selection.isCollapsed(),i=a.getBody(),r&&!q.isEmpty(i))return;if(!r&&!n(a.selection.getRng()))return;e.preventDefault(),a.setContent(""),i.firstChild&&q.isBlock(i.firstChild)?a.selection.setCursorLocation(i.firstChild,0):a.selection.setCursorLocation(i,0),a.nodeChanged()}})}function f(){a.on("keydown",function(t){!c(t)&&65==t.keyCode&&e.metaKeyPressed(t)&&(t.preventDefault(),a.execCommand("SelectAll"))})}function p(){a.settings.content_editable||(q.bind(a.getDoc(),"focusin",function(){$.setRng($.getRng())}),q.bind(a.getDoc(),"mousedown",function(e){e.target==a.getDoc().documentElement&&(a.getBody().focus(),$.setRng($.getRng()))}))}function h(){a.on("keydown",function(e){if(!c(e)&&e.keyCode===V&&$.isCollapsed()&&0===$.getRng(!0).startOffset){var t=$.getNode(),n=t.previousSibling;if("HR"==t.nodeName)return q.remove(t),void e.preventDefault();n&&n.nodeName&&"hr"===n.nodeName.toLowerCase()&&(q.remove(n),e.preventDefault())}})}function m(){window.Range.prototype.getClientRects||a.on("mousedown",function(e){if(!c(e)&&"HTML"===e.target.nodeName){var t=a.getBody();t.blur(),setTimeout(function(){t.focus()},0)}})}function g(){a.on("click",function(e){e=e.target,/^(IMG|HR)$/.test(e.nodeName)&&$.getSel().setBaseAndExtent(e,0,e,1),"A"==e.nodeName&&q.hasClass(e,"mce-item-anchor")&&$.select(e),a.nodeChanged()})}function v(){function e(){var e=q.getAttribs($.getStart().cloneNode(!1));return function(){var t=$.getStart();t!==a.getBody()&&(q.setAttrib(t,"style",null),W(e,function(e){t.setAttributeNode(e.cloneNode(!0))}))}}function t(){return!$.isCollapsed()&&q.getParent($.getStart(),q.isBlock)!=q.getParent($.getEnd(),q.isBlock)}a.on("keypress",function(n){var r;return c(n)||8!=n.keyCode&&46!=n.keyCode||!t()?void 0:(r=e(),a.getDoc().execCommand("delete",!1,null),r(),n.preventDefault(),!1)}),q.bind(a.getDoc(),"cut",function(n){var r;!c(n)&&t()&&(r=e(),setTimeout(function(){r()},0))})}function y(){var e,n;a.on("selectionchange",function(){n&&(clearTimeout(n),n=0),n=window.setTimeout(function(){if(!a.removed){var n=$.getRng();e&&t.compareRanges(n,e)||(a.nodeChanged(),e=n)}},50)})}function b(){document.body.setAttribute("role","application")}function C(){a.on("keydown",function(e){if(!c(e)&&e.keyCode===V&&$.isCollapsed()&&0===$.getRng(!0).startOffset){var t=$.getNode().previousSibling;if(t&&t.nodeName&&"table"===t.nodeName.toLowerCase())return e.preventDefault(),!1}})}function x(){l()>7||(s("RespectVisibilityInDesign",!0),a.contentStyles.push(".mceHideBrInPre pre br {display: none}"),q.addClass(a.getBody(),"mceHideBrInPre"),K.addNodeFilter("pre",function(e){for(var t=e.length,r,i,o,a;t--;)for(r=e[t].getAll("br"),i=r.length;i--;)o=r[i],a=o.prev,a&&3===a.type&&"\n"!=a.value.charAt(a.value-1)?a.value+="\n":o.parent.insert(new n("#text",3),o,!0).value="\n"}),G.addNodeFilter("pre",function(e){for(var t=e.length,n,r,i,o;t--;)for(n=e[t].getAll("br"),r=n.length;r--;)i=n[r],o=i.prev,o&&3==o.type&&(o.value=o.value.replace(/\r?\n$/,""))}))}function w(){q.bind(a.getBody(),"mouseup",function(){var e,t=$.getNode();"IMG"==t.nodeName&&((e=q.getStyle(t,"width"))&&(q.setAttrib(t,"width",e.replace(/[^0-9%]+/g,"")),q.setStyle(t,"width","")),(e=q.getStyle(t,"height"))&&(q.setAttrib(t,"height",e.replace(/[^0-9%]+/g,"")),q.setStyle(t,"height","")))})}function _(){a.on("keydown",function(t){var n,r,i,o,s;if(!c(t)&&t.keyCode==e.BACKSPACE&&(n=$.getRng(),r=n.startContainer,i=n.startOffset,o=q.getRoot(),s=r,n.collapsed&&0===i)){for(;s&&s.parentNode&&s.parentNode.firstChild==s&&s.parentNode!=o;)s=s.parentNode;"BLOCKQUOTE"===s.tagName&&(a.formatter.toggle("blockquote",null,s),n=q.createRng(),n.setStart(r,0),n.setEnd(r,0),$.setRng(n))}})}function N(){function e(){a._refreshContentEditable(),s("StyleWithCSS",!1),s("enableInlineTableEditing",!1),j.object_resizing||s("enableObjectResizing",!1)}j.readonly||a.on("BeforeExecCommand MouseDown",e)}function E(){function e(){W(q.select("a"),function(e){var t=e.parentNode,n=q.getRoot();if(t.lastChild===e){for(;t&&!q.isBlock(t);){if(t.parentNode.lastChild!==t||t===n)return;t=t.parentNode}q.add(t,"br",{"data-mce-bogus":1})}})}a.on("SetContent ExecCommand",function(t){("setcontent"==t.type||"mceInsertLink"===t.command)&&e()})}function S(){j.forced_root_block&&a.on("init",function(){s("DefaultParagraphSeparator",j.forced_root_block)})}function k(){a.on("Undo Redo SetContent",function(e){e.initial||a.execCommand("mceRepaint")})}function T(){a.on("keydown",function(e){var t;c(e)||e.keyCode!=V||(t=a.getDoc().selection.createRange(),t&&t.item&&(e.preventDefault(),a.undoManager.beforeChange(),q.remove(t.item(0)),a.undoManager.add()))})}function R(){var e;l()>=10&&(e="",W("p div h1 h2 h3 h4 h5 h6".split(" "),function(t,n){e+=(n>0?",":"")+t+":empty"}),a.contentStyles.push(e+"{padding-right: 1px !important}"))}function A(){l()<9&&(K.addNodeFilter("noscript",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.firstChild,r&&n.attr("data-mce-innertext",r.value)}),G.addNodeFilter("noscript",function(e){for(var t=e.length,i,o,a;t--;)i=e[t],o=e[t].firstChild,o?o.value=r.decode(o.value):(a=i.attributes.map["data-mce-innertext"],a&&(i.attr("data-mce-innertext",null),o=new n("#text",3),o.value=a,o.raw=!0,i.append(o)))}))}function B(){function e(e,t){var n=i.createTextRange();try{n.moveToPoint(e,t)}catch(r){n=null}return n}function t(t){var r;t.button?(r=e(t.x,t.y),r&&(r.compareEndPoints("StartToStart",a)>0?r.setEndPoint("StartToStart",a):r.setEndPoint("EndToEnd",a),r.select())):n()}function n(){var e=r.selection.createRange();a&&!e.item&&0===e.compareEndPoints("StartToEnd",e)&&a.select(),q.unbind(r,"mouseup",n),q.unbind(r,"mousemove",t),a=o=0}var r=q.doc,i=r.body,o,a,s;r.documentElement.unselectable=!0,q.bind(r,"mousedown contextmenu",function(i){if("HTML"===i.target.nodeName){if(o&&n(),s=r.documentElement,s.scrollHeight>s.clientHeight)return;o=1,a=e(i.x,i.y),a&&(q.bind(r,"mouseup",n),q.bind(r,"mousemove",t),q.getRoot().focus(),a.select())}})}function D(){a.on("keyup focusin mouseup",function(t){65==t.keyCode&&e.metaKeyPressed(t)||$.normalize()},!0)}function L(){a.contentStyles.push("img:-moz-broken {-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}")}function M(){a.inline||a.on("keydown",function(){document.activeElement==document.body&&a.getWin().focus()})}function H(){a.inline||(a.contentStyles.push("body {min-height: 150px}"),a.on("click",function(e){"HTML"==e.target.nodeName&&(a.getBody().focus(),a.selection.normalize(),a.nodeChanged())}))}function P(){i.mac&&a.on("keydown",function(t){!e.metaKeyPressed(t)||37!=t.keyCode&&39!=t.keyCode||(t.preventDefault(),a.selection.getSel().modify("move",37==t.keyCode?"backward":"forward","word"))})}function O(){s("AutoUrlDetect",!1)}function I(){a.inline||a.on("focus blur beforegetcontent",function(){var e=a.dom.create("br");a.getBody().appendChild(e),e.parentNode.removeChild(e)},!0)}function F(){a.on("click",function(e){var t=e.target;do if("A"===t.tagName)return void e.preventDefault();while(t=t.parentNode)}),a.contentStyles.push(".mce-content-body {-webkit-touch-callout: none}")}function z(){a.on("init",function(){a.dom.bind(a.getBody(),"submit",function(e){e.preventDefault()})})}var W=o.each,V=e.BACKSPACE,U=e.DELETE,q=a.dom,$=a.selection,j=a.settings,K=a.parser,G=a.serializer,Y=i.gecko,X=i.ie,J=i.webkit;C(),_(),d(),D(),J&&(u(),p(),g(),S(),z(),i.iOS?(y(),M(),H(),F()):f()),X&&i.ie<11&&(h(),b(),x(),w(),T(),R(),A(),B()),i.ie>=11&&(H(),I()),i.ie&&(f(),O()),Y&&(h(),m(),v(),N(),E(),k(),L(),P())}}),r(ot,[W],function(e){function t(t){return t._eventDispatcher||(t._eventDispatcher=new e({scope:t,toggleEvent:function(n,r){e.isNative(n)&&t.toggleNativeEvent&&t.toggleNativeEvent(n,r)}})),t._eventDispatcher}return{fire:function(e,n,r){var i=this;if(i.removed&&"remove"!==e)return n;if(n=t(i).fire(e,n,r),r!==!1&&i.parent)for(var o=i.parent();o&&!n.isPropagationStopped();)o.fire(e,n,!1),o=o.parent();return n},on:function(e,n,r){return t(this).on(e,n,r)},off:function(e,n){return t(this).off(e,n)},hasEventListeners:function(e){return t(this).has(e)}}}),r(at,[ot,y,p],function(e,t,n){function r(e,t){return"selectionchange"==t?e.getDoc():!e.inline&&/^mouse|click|contextmenu|drop/.test(t)?e.getDoc():e.getBody()}function i(e,t){var n=e.settings.event_root,i=e.editorManager,a=i.eventRootElm||r(e,t);if(n){if(i.rootEvents||(i.rootEvents={},i.on("RemoveEditor",function(){i.activeEditor||(o.unbind(a),delete i.rootEvents)})),i.rootEvents[t])return;a==e.getBody()&&(a=o.select(n)[0],i.eventRootElm=a),i.rootEvents[t]=!0,o.bind(a,t,function(e){for(var n=e.target,r=i.editors,a=r.length;a--;){var s=r[a].getBody();(s===n||o.isChildOf(n,s))&&(r[a].hidden||r[a].fire(t,e))}})}else e.dom.bind(a,t,function(n){e.hidden||e.fire(t,n)})}var o=t.DOM,a={bindPendingEventDelegates:function(){var e=this;n.each(e._pendingNativeEvents,function(t){i(e,t)})},toggleNativeEvent:function(e,t){var n=this;n.settings.readonly||"focus"!=e&&"blur"!=e&&(t?n.initialized?i(n,e):n._pendingNativeEvents?n._pendingNativeEvents.push(e):n._pendingNativeEvents=[e]:n.initialized&&n.dom.unbind(r(n,e),e))}};return a=n.extend({},e,a)}),r(st,[p,g],function(e,t){var n=e.each,r=e.explode,i={f9:120,f10:121,f11:122};return function(o){var a=this,s={};o.on("keyup keypress keydown",function(e){(e.altKey||e.ctrlKey||e.metaKey)&&n(s,function(n){var r=t.mac?e.metaKey:e.ctrlKey;if(n.ctrl==r&&n.alt==e.altKey&&n.shift==e.shiftKey)return e.keyCode==n.keyCode||e.charCode&&e.charCode==n.charCode?(e.preventDefault(),"keydown"==e.type&&n.func.call(n.scope),!0):void 0})}),a.add=function(t,a,l,c){var u;return u=l,"string"==typeof l?l=function(){o.execCommand(u,!1,null)}:e.isArray(u)&&(l=function(){o.execCommand(u[0],u[1],u[2])}),n(r(t.toLowerCase()),function(e){var t={func:l,scope:c||o,desc:o.translate(a),alt:!1,ctrl:!1,shift:!1};n(r(e,"+"),function(e){switch(e){case"alt":case"ctrl":case"shift":t[e]=!0;break;default:t.charCode=e.charCodeAt(0),t.keyCode=i[e]||e.toUpperCase().charCodeAt(0)}}),s[(t.ctrl?"ctrl":"")+","+(t.alt?"alt":"")+","+(t.shift?"shift":"")+","+t.keyCode]=t}),!0}}}),r(lt,[y,C,x,k,S,D,M,H,P,O,I,F,b,l,rt,w,N,it,g,p,at,st],function(e,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v,y,b,C,x,w){function _(e,t,r){var i=this,o,a;o=i.documentBaseUrl=r.documentBaseURL,a=r.baseURI,i.settings=t=k({id:e,theme:"modern",delta_width:0,delta_height:0,popup_css:"",plugins:"",document_base_url:o,add_form_submit_trigger:!0,submit_patch:!0,add_unload_trigger:!0,convert_urls:!0,relative_urls:!0,remove_script_host:!0,object_resizing:!0,doctype:"",visual:!0,font_size_style_values:"xx-small,x-small,small,medium,large,x-large,xx-large",font_size_legacy_values:"xx-small,small,medium,large,x-large,xx-large,300%",forced_root_block:"p",hidden_input:!0,padd_empty_editor:!0,render_ui:!0,indentation:"30px",inline_styles:!0,convert_fonts_to_spans:!0,indent:"simple",indent_before:"p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist",indent_after:"p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist",validate:!0,entity_encoding:"named",url_converter:i.convertURL,url_converter_scope:i,ie7_compat:!0},t),n.language=t.language||"en",n.languageLoad=t.language_load,n.baseURL=r.baseURL,i.id=t.id=e,i.isNotDirty=!0,i.plugins={},i.documentBaseURI=new f(t.document_base_url||o,{base_uri:a}),i.baseURI=a,i.contentCSS=[],i.contentStyles=[],i.shortcuts=new w(i),i.execCommands={},i.queryStateCommands={},i.queryValueCommands={},i.loadedCSS={},i.suffix=r.suffix,i.editorManager=r,i.inline=t.inline,r.fire("SetupEditor",i),i.execCallback("setup",i)}var N=e.DOM,E=n.ThemeManager,S=n.PluginManager,k=C.extend,T=C.each,R=C.explode,A=C.inArray,B=C.trim,D=C.resolve,L=h.Event,M=b.gecko,H=b.ie;return _.prototype={render:function(){function e(){N.unbind(window,"ready",e),n.render()}function t(){var e=p.ScriptLoader;if(r.language&&"en"!=r.language&&!r.language_url&&(r.language_url=n.editorManager.baseURL+"/langs/"+r.language+".js"),r.language_url&&e.add(r.language_url),r.theme&&"function"!=typeof r.theme&&"-"!=r.theme.charAt(0)&&!E.urls[r.theme]){var t=r.theme_url;t=t?n.documentBaseURI.toAbsolute(t):"themes/"+r.theme+"/theme"+o+".js",E.load(r.theme,t)}C.isArray(r.plugins)&&(r.plugins=r.plugins.join(" ")),T(r.external_plugins,function(e,t){S.load(t,e),r.plugins+=" "+t}),T(r.plugins.split(/[ ,]/),function(e){if(e=B(e),e&&!S.urls[e])if("-"==e.charAt(0)){e=e.substr(1,e.length);var t=S.dependencies(e);T(t,function(e){var t={prefix:"plugins/",resource:e,suffix:"/plugin"+o+".js"};e=S.createUrl(t,e),S.load(e.resource,e)})}else S.load(e,{prefix:"plugins/",resource:e,suffix:"/plugin"+o+".js"})}),e.loadQueue(function(){n.removed||n.init()})}var n=this,r=n.settings,i=n.id,o=n.suffix;if(!L.domLoaded)return void N.bind(window,"ready",e);if(n.getElement()&&b.contentEditable){r.inline?n.inline=!0:(n.orgVisibility=n.getElement().style.visibility,n.getElement().style.visibility="hidden");var a=n.getElement().form||N.getParent(i,"form");a&&(n.formElement=a,r.hidden_input&&!/TEXTAREA|INPUT/i.test(n.getElement().nodeName)&&(N.insertAfter(N.create("input",{type:"hidden",name:i}),i),n.hasHiddenInput=!0),n.formEventDelegate=function(e){n.fire(e.type,e)},N.bind(a,"submit reset",n.formEventDelegate),n.on("reset",function(){n.setContent(n.startContent,{format:"raw"})}),!r.submit_patch||a.submit.nodeType||a.submit.length||a._mceOldSubmit||(a._mceOldSubmit=a.submit,a.submit=function(){return n.editorManager.triggerSave(),n.isNotDirty=!0,a._mceOldSubmit(a)})),n.windowManager=new m(n),"xml"==r.encoding&&n.on("GetContent",function(e){e.save&&(e.content=N.encode(e.content))}),r.add_form_submit_trigger&&n.on("submit",function(){n.initialized&&n.save()}),r.add_unload_trigger&&(n._beforeUnload=function(){!n.initialized||n.destroyed||n.isHidden()||n.save({format:"raw",no_events:!0,set_dirty:!1})},n.editorManager.on("BeforeUnload",n._beforeUnload)),t()}},init:function(){function e(n){var r=S.get(n),i,o;i=S.urls[n]||t.documentBaseUrl.replace(/\/$/,""),n=B(n),r&&-1===A(m,n)&&(T(S.dependencies(n),function(t){e(t)}),o=new r(t,i),t.plugins[n]=o,o.init&&(o.init(t,i),m.push(n)))}var t=this,n=t.settings,r=t.getElement(),i,o,a,s,l,c,u,d,f,p,h,m=[];if(t.rtl=this.editorManager.i18n.rtl,t.editorManager.add(t),n.aria_label=n.aria_label||N.getAttrib(r,"aria-label",t.getLang("aria.rich_text_area")),n.theme&&("function"!=typeof n.theme?(n.theme=n.theme.replace(/-/,""),c=E.get(n.theme),t.theme=new c(t,E.urls[n.theme]),t.theme.init&&t.theme.init(t,E.urls[n.theme]||t.documentBaseUrl.replace(/\/$/,""))):t.theme=n.theme),T(n.plugins.replace(/\-/g,"").split(/[ ,]/),e),n.render_ui&&t.theme&&(t.orgDisplay=r.style.display,"function"!=typeof n.theme?(i=n.width||r.style.width||r.offsetWidth,o=n.height||r.style.height||r.offsetHeight,a=n.min_height||100,p=/^[0-9\.]+(|px)$/i,p.test(""+i)&&(i=Math.max(parseInt(i,10),100)),p.test(""+o)&&(o=Math.max(parseInt(o,10),a)),l=t.theme.renderUI({targetNode:r,width:i,height:o,deltaWidth:n.delta_width,deltaHeight:n.delta_height}),n.content_editable||(N.setStyles(l.sizeContainer||l.editorContainer,{wi2dth:i,h2eight:o}),o=(l.iframeHeight||o)+("number"==typeof o?l.deltaHeight||0:""),a>o&&(o=a))):(l=n.theme(t,r),l.editorContainer.nodeType&&(l.editorContainer=l.editorContainer.id=l.editorContainer.id||t.id+"_parent"),l.iframeContainer.nodeType&&(l.iframeContainer=l.iframeContainer.id=l.iframeContainer.id||t.id+"_iframecontainer"),o=l.iframeHeight||r.offsetHeight),t.editorContainer=l.editorContainer),n.content_css&&T(R(n.content_css),function(e){t.contentCSS.push(t.documentBaseURI.toAbsolute(e))}),n.content_style&&t.contentStyles.push(n.content_style),n.content_editable)return r=s=l=null,t.initContentBody();for(t.iframeHTML=n.doctype+"",n.document_base_url!=t.documentBaseUrl&&(t.iframeHTML+=''),!b.caretAfter&&n.ie7_compat&&(t.iframeHTML+=''),t.iframeHTML+='',h=0;h',t.loadedCSS[g]=!0}d=n.body_id||"tinymce",-1!=d.indexOf("=")&&(d=t.getParam("body_id","","hash"),d=d[t.id]||d),f=n.body_class||"",-1!=f.indexOf("=")&&(f=t.getParam("body_class","","hash"),f=f[t.id]||""),t.iframeHTML+='
";var v='javascript:(function(){document.open();document.domain="'+document.domain+'";var ed = window.parent.tinymce.get("'+t.id+'");document.write(ed.iframeHTML);document.close();ed.initContentBody(true);})()';if(document.domain!=location.hostname&&(u=v),s=N.add(l.iframeContainer,"iframe",{id:t.id+"_ifr",src:u||'javascript:""',frameBorder:"0",allowTransparency:"true",title:t.editorManager.translate("Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help"),style:{width:"100%",height:o,display:"block"}}),H)try{t.getDoc()}catch(y){s.src=u=v}t.contentAreaContainer=l.iframeContainer,l.editorContainer&&(N.get(l.editorContainer).style.display=t.orgDisplay),N.get(t.id).style.display="none",N.setAttrib(t.id,"aria-hidden",!0),u||t.initContentBody(),r=s=l=null},initContentBody:function(t){var n=this,o=n.settings,f=N.get(n.id),p=n.getDoc(),h,m;o.inline||(n.getElement().style.visibility=n.orgVisibility),t||o.content_editable||(p.open(),p.write(n.iframeHTML),p.close()),o.content_editable&&(n.on("remove",function(){var e=this.getBody();N.removeClass(e,"mce-content-body"),N.removeClass(e,"mce-edit-focus"),N.setAttrib(e,"contentEditable",null)}),N.addClass(f,"mce-content-body"),n.contentDocument=p=o.content_document||document,n.contentWindow=o.content_window||window,n.bodyElement=f,o.content_document=o.content_window=null,o.root_name=f.nodeName.toLowerCase()),h=n.getBody(),h.disabled=!0,o.readonly||(n.inline&&"static"==N.getStyle(h,"position",!0)&&(h.style.position="relative"),h.contentEditable=n.getParam("content_editable_state",!0)),h.disabled=!1,n.schema=new g(o),n.dom=new e(p,{keep_values:!0,url_converter:n.convertURL,url_converter_scope:n,hex_colors:o.force_hex_style_colors,class_filter:o.class_filter,update_styles:!0,root_element:o.content_editable?n.id:null,collect:o.content_editable,schema:n.schema,onSetAttrib:function(e){n.fire("SetAttrib",e) +}}),n.parser=new v(o,n.schema),n.parser.addAttributeFilter("src,href,style,tabindex",function(e,t){for(var r=e.length,i,o=n.dom,a,s;r--;)i=e[r],a=i.attr(t),s="data-mce-"+t,i.attributes.map[s]||("style"===t?i.attr(s,o.serializeStyle(o.parseStyle(a),i.name)):"tabindex"===t?(i.attr(s,a),i.attr(t,null)):i.attr(s,n.convertURL(a,t,i.name)))}),n.parser.addNodeFilter("script",function(e){for(var t=e.length,n;t--;)n=e[t],n.attr("type","mce-"+(n.attr("type")||"text/javascript"))}),n.parser.addNodeFilter("#cdata",function(e){for(var t=e.length,n;t--;)n=e[t],n.type=8,n.name="#comment",n.value="[CDATA["+n.value+"]]"}),n.parser.addNodeFilter("p,h1,h2,h3,h4,h5,h6,div",function(e){for(var t=e.length,i,o=n.schema.getNonEmptyElements();t--;)i=e[t],i.isEmpty(o)&&(i.empty().append(new r("br",1)).shortEnded=!0)}),n.serializer=new i(o,n),n.selection=new a(n.dom,n.getWin(),n.serializer,n),n.formatter=new s(n),n.undoManager=new l(n),n.forceBlocks=new u(n),n.enterKey=new c(n),n.editorCommands=new d(n),n.fire("PreInit"),o.browser_spellcheck||o.gecko_spellcheck||(p.body.spellcheck=!1,N.setAttrib(h,"spellcheck","false")),n.fire("PostRender"),n.quirks=y(n),o.directionality&&(h.dir=o.directionality),o.nowrap&&(h.style.whiteSpace="nowrap"),o.protect&&n.on("BeforeSetContent",function(e){T(o.protect,function(t){e.content=e.content.replace(t,function(e){return""})})}),n.on("SetContent",function(){n.addVisual(n.getBody())}),o.padd_empty_editor&&n.on("PostProcess",function(e){e.content=e.content.replace(/^(]*>( | |\s|\u00a0|)<\/p>[\r\n]*|
[\r\n]*)$/,"")}),n.load({initial:!0,format:"html"}),n.startContent=n.getContent({format:"raw"}),n.initialized=!0,n.bindPendingEventDelegates(),n.fire("init"),n.focus(!0),n.nodeChanged({initial:!0}),n.execCallback("init_instance_callback",n),n.contentStyles.length>0&&(m="",T(n.contentStyles,function(e){m+=e+"\r\n"}),n.dom.addStyle(m)),T(n.contentCSS,function(e){n.loadedCSS[e]||(n.dom.loadCSS(e),n.loadedCSS[e]=!0)}),o.auto_focus&&setTimeout(function(){var e=n.editorManager.get(o.auto_focus);e.selection.select(e.getBody(),1),e.selection.collapse(1),e.getBody().focus(),e.getWin().focus()},100),f=p=h=null},focus:function(e){var t,n=this,r=n.selection,i=n.settings.content_editable,o,a,s=n.getDoc(),l;if(!e){if(o=r.getRng(),o.item&&(a=o.item(0)),n._refreshContentEditable(),i||(b.opera||n.getBody().focus(),n.getWin().focus()),M||i){if(l=n.getBody(),l.setActive)try{l.setActive()}catch(c){l.focus()}else l.focus();i&&r.normalize()}a&&a.ownerDocument==s&&(o=s.body.createControlRange(),o.addElement(a),o.select())}n.editorManager.activeEditor!=n&&((t=n.editorManager.activeEditor)&&t.fire("deactivate",{relatedTarget:n}),n.fire("activate",{relatedTarget:t})),n.editorManager.activeEditor=n},execCallback:function(e){var t=this,n=t.settings[e],r;if(n)return t.callbackLookup&&(r=t.callbackLookup[e])&&(n=r.func,r=r.scope),"string"==typeof n&&(r=n.replace(/\.\w+$/,""),r=r?D(r):0,n=D(n),t.callbackLookup=t.callbackLookup||{},t.callbackLookup[e]={func:n,scope:r}),n.apply(r||t,Array.prototype.slice.call(arguments,1))},translate:function(e){var t=this.settings.language||"en",n=this.editorManager.i18n;return e?n.data[t+"."+e]||e.replace(/\{\#([^\}]+)\}/g,function(e,r){return n.data[t+"."+r]||"{#"+r+"}"}):""},getLang:function(e,n){return this.editorManager.i18n.data[(this.settings.language||"en")+"."+e]||(n!==t?n:"{#"+e+"}")},getParam:function(e,t,n){var r=e in this.settings?this.settings[e]:t,i;return"hash"===n?(i={},"string"==typeof r?T(r.split(r.indexOf("=")>0?/[;,](?![^=;,]*(?:[;,]|$))/:","),function(e){e=e.split("="),i[B(e[0])]=B(e.length>1?e[1]:e)}):i=r,i):r},nodeChanged:function(){var e=this,t=e.selection,n,r,i;!e.initialized||e.settings.disable_nodechange||e.settings.readonly||(i=e.getBody(),n=t.getStart()||i,n=H&&n.ownerDocument!=e.getDoc()?e.getBody():n,"IMG"==n.nodeName&&t.isCollapsed()&&(n=n.parentNode),r=[],e.dom.getParent(n,function(e){return e===i?!0:void r.push(e)}),e.fire("NodeChange",{element:n,parents:r}))},addButton:function(e,t){var n=this;t.cmd&&(t.onclick=function(){n.execCommand(t.cmd)}),t.text||t.icon||(t.icon=e),n.buttons=n.buttons||{},t.tooltip=t.tooltip||t.title,n.buttons[e]=t},addMenuItem:function(e,t){var n=this;t.cmd&&(t.onclick=function(){n.execCommand(t.cmd)}),n.menuItems=n.menuItems||{},n.menuItems[e]=t},addCommand:function(e,t,n){this.execCommands[e]={func:t,scope:n||this}},addQueryStateHandler:function(e,t,n){this.queryStateCommands[e]={func:t,scope:n||this}},addQueryValueHandler:function(e,t,n){this.queryValueCommands[e]={func:t,scope:n||this}},addShortcut:function(e,t,n,r){this.shortcuts.add(e,t,n,r)},execCommand:function(e,t,n,r){var i=this,o=0,a;return/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(e)||r&&r.skip_focus||i.focus(),r=k({},r),r=i.fire("BeforeExecCommand",{command:e,ui:t,value:n}),r.isDefaultPrevented()?!1:(a=i.execCommands[e])&&a.func.call(a.scope,t,n)!==!0?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):(T(i.plugins,function(r){return r.execCommand&&r.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),o=!0,!1):void 0}),o?o:i.theme&&i.theme.execCommand&&i.theme.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):i.editorCommands.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):(i.getDoc().execCommand(e,t,n),void i.fire("ExecCommand",{command:e,ui:t,value:n})))},queryCommandState:function(e){var t=this,n,r;if(!t._isHidden()){if((n=t.queryStateCommands[e])&&(r=n.func.call(n.scope),r!==!0))return r;if(r=t.editorCommands.queryCommandState(e),-1!==r)return r;try{return t.getDoc().queryCommandState(e)}catch(i){}}},queryCommandValue:function(e){var n=this,r,i;if(!n._isHidden()){if((r=n.queryValueCommands[e])&&(i=r.func.call(r.scope),i!==!0))return i;if(i=n.editorCommands.queryCommandValue(e),i!==t)return i;try{return n.getDoc().queryCommandValue(e)}catch(o){}}},show:function(){var e=this;e.hidden&&(e.hidden=!1,e.inline?e.getBody().contentEditable=!0:(N.show(e.getContainer()),N.hide(e.id)),e.load(),e.fire("show"))},hide:function(){var e=this,t=e.getDoc();e.hidden||(e.hidden=!0,H&&t&&!e.inline&&t.execCommand("SelectAll"),e.save(),e.inline?(e.getBody().contentEditable=!1,e==e.editorManager.focusedEditor&&(e.editorManager.focusedEditor=null)):(N.hide(e.getContainer()),N.setStyle(e.id,"display",e.orgDisplay)),e.fire("hide"))},isHidden:function(){return!!this.hidden},setProgressState:function(e,t){this.fire("ProgressState",{state:e,time:t})},load:function(e){var n=this,r=n.getElement(),i;return r?(e=e||{},e.load=!0,i=n.setContent(r.value!==t?r.value:r.innerHTML,e),e.element=r,e.no_events||n.fire("LoadContent",e),e.element=r=null,i):void 0},save:function(e){var t=this,n=t.getElement(),r,i;if(n&&t.initialized)return e=e||{},e.save=!0,e.element=n,r=e.content=t.getContent(e),e.no_events||t.fire("SaveContent",e),r=e.content,/TEXTAREA|INPUT/i.test(n.nodeName)?n.value=r:(t.inline||(n.innerHTML=r),(i=N.getParent(t.id,"form"))&&T(i.elements,function(e){return e.name==t.id?(e.value=r,!1):void 0})),e.element=n=null,e.set_dirty!==!1&&(t.isNotDirty=!0),r},setContent:function(e,t){var n=this,r=n.getBody(),i;return t=t||{},t.format=t.format||"html",t.set=!0,t.content=e,t.no_events||n.fire("BeforeSetContent",t),e=t.content,0===e.length||/^\s+$/.test(e)?(i=n.settings.forced_root_block,i&&n.schema.isValidChild(r.nodeName.toLowerCase(),i.toLowerCase())?(e=H&&11>H?"":'
',e=n.dom.createHTML(i,n.settings.forced_root_block_attrs,e)):H||(e='
'),r.innerHTML=e,n.fire("SetContent",t)):("raw"!==t.format&&(e=new o({},n.schema).serialize(n.parser.parse(e,{isRootContent:!0}))),t.content=B(e),n.dom.setHTML(r,t.content),t.no_events||n.fire("SetContent",t)),t.content},getContent:function(e){var t=this,n,r=t.getBody();return e=e||{},e.format=e.format||"html",e.get=!0,e.getInner=!0,e.no_events||t.fire("BeforeGetContent",e),n="raw"==e.format?r.innerHTML:"text"==e.format?r.innerText||r.textContent:t.serializer.serialize(r,e),e.content="text"!=e.format?B(n):n,e.no_events||t.fire("GetContent",e),e.content},insertContent:function(e){this.execCommand("mceInsertContent",!1,e)},isDirty:function(){return!this.isNotDirty},getContainer:function(){var e=this;return e.container||(e.container=N.get(e.editorContainer||e.id+"_parent")),e.container},getContentAreaContainer:function(){return this.contentAreaContainer},getElement:function(){return N.get(this.settings.content_element||this.id)},getWin:function(){var e=this,t;return e.contentWindow||(t=N.get(e.id+"_ifr"),t&&(e.contentWindow=t.contentWindow)),e.contentWindow},getDoc:function(){var e=this,t;return e.contentDocument||(t=e.getWin(),t&&(e.contentDocument=t.document)),e.contentDocument},getBody:function(){return this.bodyElement||this.getDoc().body},convertURL:function(e,t,n){var r=this,i=r.settings;return i.urlconverter_callback?r.execCallback("urlconverter_callback",e,n,!0,t):!i.convert_urls||n&&"LINK"==n.nodeName||0===e.indexOf("file:")||0===e.length?e:i.relative_urls?r.documentBaseURI.toRelative(e):e=r.documentBaseURI.toAbsolute(e,i.remove_script_host)},addVisual:function(e){var n=this,r=n.settings,i=n.dom,o;e=e||n.getBody(),n.hasVisual===t&&(n.hasVisual=r.visual),T(i.select("table,a",e),function(e){var t;switch(e.nodeName){case"TABLE":return o=r.visual_table_class||"mce-item-table",t=i.getAttrib(e,"border"),void(t&&"0"!=t||(n.hasVisual?i.addClass(e,o):i.removeClass(e,o)));case"A":return void(i.getAttrib(e,"href",!1)||(t=i.getAttrib(e,"name")||e.id,o=r.visual_anchor_class||"mce-item-anchor",t&&(n.hasVisual?i.addClass(e,o):i.removeClass(e,o))))}}),n.fire("VisualAid",{element:e,hasVisual:n.hasVisual})},remove:function(){var e=this;if(!e.removed){e.removed=1,e.save(),e.hasHiddenInput&&N.remove(e.getElement().nextSibling),e.inline||(H&&10>H&&e.getDoc().execCommand("SelectAll",!1,null),N.setStyle(e.id,"display",e.orgDisplay),e.getBody().onload=null,L.unbind(e.getWin()),L.unbind(e.getDoc()));var t=e.getContainer();L.unbind(e.getBody()),L.unbind(t),e.fire("remove"),e.editorManager.remove(e),N.remove(t),e.destroy()}},destroy:function(e){var t=this,n;if(!t.destroyed){if(!e&&!t.removed)return void t.remove();e&&M&&(L.unbind(t.getDoc()),L.unbind(t.getWin()),L.unbind(t.getBody())),e||(t.editorManager.off("beforeunload",t._beforeUnload),t.theme&&t.theme.destroy&&t.theme.destroy(),t.selection.destroy(),t.dom.destroy()),n=t.formElement,n&&(n._mceOldSubmit&&(n.submit=n._mceOldSubmit,n._mceOldSubmit=null),N.unbind(n,"submit reset",t.formEventDelegate)),t.contentAreaContainer=t.formElement=t.container=t.editorContainer=null,t.settings.content_element=t.bodyElement=t.contentDocument=t.contentWindow=null,t.selection&&(t.selection=t.selection.win=t.selection.dom=t.selection.dom.doc=null),t.destroyed=1}},_refreshContentEditable:function(){var e=this,t,n;e._isHidden()&&(t=e.getBody(),n=t.parentNode,n.removeChild(t),n.appendChild(t),t.focus())},_isHidden:function(){var e;return M?(e=this.selection.getSel(),!e||!e.rangeCount||0===e.rangeCount):0}},k(_.prototype,x),_}),r(ct,[],function(){var e={};return{rtl:!1,add:function(t,n){for(var r in n)e[r]=n[r];this.rtl=this.rtl||"rtl"===e._dir},translate:function(t){if("undefined"==typeof t)return t;if("string"!=typeof t&&t.raw)return t.raw;if(t.push){var n=t.slice(1);t=(e[t[0]]||t[0]).replace(/\{([^\}]+)\}/g,function(e,t){return n[t]})}return e[t]||t},data:e}}),r(ut,[y,g],function(e,t){function n(e){function s(){try{return document.activeElement}catch(e){return document.body}}function l(e,t){if(t&&t.startContainer){if(!e.isChildOf(t.startContainer,e.getRoot())||!e.isChildOf(t.endContainer,e.getRoot()))return;return{startContainer:t.startContainer,startOffset:t.startOffset,endContainer:t.endContainer,endOffset:t.endOffset}}return t}function c(e,t){var n;return t.startContainer?(n=e.getDoc().createRange(),n.setStart(t.startContainer,t.startOffset),n.setEnd(t.endContainer,t.endOffset)):n=t,n}function u(e){return!!a.getParent(e,n.isEditorUIElement)}function d(n){var d=n.editor;d.on("init",function(){(d.inline||t.ie)&&(d.on("nodechange keyup",function(){var e=document.activeElement;e&&e.id==d.id+"_ifr"&&(e=d.getBody()),d.dom.isChildOf(e,d.getBody())&&(d.lastRng=d.selection.getRng())}),t.webkit&&!r&&(r=function(){var t=e.activeEditor;if(t&&t.selection){var n=t.selection.getRng();n&&!n.collapsed&&(d.lastRng=n)}},a.bind(document,"selectionchange",r)))}),d.on("setcontent",function(){d.lastRng=null}),d.on("mousedown",function(){d.selection.lastFocusBookmark=null}),d.on("focusin",function(){var t=e.focusedEditor;d.selection.lastFocusBookmark&&(d.selection.setRng(c(d,d.selection.lastFocusBookmark)),d.selection.lastFocusBookmark=null),t!=d&&(t&&t.fire("blur",{focusedEditor:d}),e.activeEditor=d,e.focusedEditor=d,d.fire("focus",{blurredEditor:t}),d.focus(!0)),d.lastRng=null}),d.on("focusout",function(){window.setTimeout(function(){var t=e.focusedEditor;u(s())||t!=d||(d.fire("blur",{focusedEditor:null}),e.focusedEditor=null,d.selection&&(d.selection.lastFocusBookmark=null))},0)}),i||(i=function(t){var n=e.activeEditor;n&&t.target.ownerDocument==document&&(n.selection&&(n.selection.lastFocusBookmark=l(n.dom,n.lastRng)),u(t.target)||e.focusedEditor!=n||(n.fire("blur",{focusedEditor:null}),e.focusedEditor=null))},a.bind(document,"focusin",i)),d.inline&&!o&&(o=function(t){var n=e.activeEditor;if(n.inline&&!n.dom.isChildOf(t.target,n.getBody())){var r=n.selection.getRng();r.collapsed||(n.lastRng=r)}},a.bind(document,"mouseup",o))}function f(t){e.focusedEditor==t.editor&&(e.focusedEditor=null),e.activeEditor||(a.unbind(document,"selectionchange",r),a.unbind(document,"focusin",i),a.unbind(document,"mouseup",o),r=i=o=null)}e.on("AddEditor",d),e.on("RemoveEditor",f)}var r,i,o,a=e.DOM;return n.isEditorUIElement=function(e){return-1!==e.className.toString().indexOf("mce-")},n}),r(dt,[lt,y,F,g,p,ot,ct,ut],function(e,t,n,r,i,o,a,s){function l(e){var t=g.editors,n;delete t[e.id];for(var r=0;r0&&f(d(c),function(n){u.get(n)?(m=new e(n,t,s),l.push(m),m.render()):f(document.forms,function(e){f(e.elements,function(e){e.name===n&&(n="mce_editor_"+h++,u.setAttrib(e,"id",n),r(n,t))})})});break;case"textareas":case"specific_textareas":f(u.select("textarea"),function(e){t.editor_deselector&&o(e,t.editor_deselector)||(!t.editor_selector||o(e,t.editor_selector))&&r(n(e),t)})}t.oninit&&(c=g=0,f(l,function(e){g++,e.initialized?c++:e.on("init",function(){c++,c==g&&i(t,"oninit")}),c==g&&i(t,"oninit")}))}var s=this,l=[],m;s.settings=t,u.bind(window,"ready",a)},get:function(e){return arguments.length?e in this.editors?this.editors[e]:null:this.editors},add:function(e){var t=this,n=t.editors;return n[e.id]=e,n.push(e),t.activeEditor=e,t.fire("AddEditor",{editor:e}),m||(m=function(){t.fire("BeforeUnload")},u.bind(window,"beforeunload",m)),e},createEditor:function(t,n){return this.add(new e(t,n,this))},remove:function(e){var t=this,n,r=t.editors,i;{if(e)return"string"==typeof e?(e=e.selector||e,void f(u.select(e),function(e){t.remove(r[e.id])})):(i=e,r[i.id]?(l(i)&&t.fire("RemoveEditor",{editor:i}),r.length||u.unbind(window,"beforeunload",m),i.remove(),i):null);for(n=r.length-1;n>=0;n--)t.remove(r[n])}},execCommand:function(t,n,r){var i=this,o=i.get(r);switch(t){case"mceAddEditor":return i.get(r)||new e(r,i.settings,i).render(),!0;case"mceRemoveEditor":return o&&o.remove(),!0;case"mceToggleEditor":return o?(o.isHidden()?o.show():o.hide(),!0):(i.execCommand("mceAddEditor",0,r),!0)}return i.activeEditor?i.activeEditor.execCommand(t,n,r):!1},triggerSave:function(){f(this.editors,function(e){e.save()})},addI18n:function(e,t){a.add(e,t)},translate:function(e){return a.translate(e)}},p(g,o),g.setup(),window.tinymce=window.tinyMCE=g,g}),r(ft,[dt,p],function(e,t){var n=t.each,r=t.explode;e.on("AddEditor",function(e){var t=e.editor;t.on("preInit",function(){function e(e,t){n(t,function(t,n){t&&s.setStyle(e,n,t)}),s.rename(e,"span")}function i(e){s=t.dom,l.convert_fonts_to_spans&&n(s.select("font,u,strike",e.node),function(e){o[e.nodeName.toLowerCase()](s,e)})}var o,a,s,l=t.settings;l.inline_styles&&(a=r(l.font_size_legacy_values),o={font:function(t,n){e(n,{backgroundColor:n.style.backgroundColor,color:n.color,fontFamily:n.face,fontSize:a[parseInt(n.size,10)-1]})},u:function(t,n){e(n,{textDecoration:"underline"})},strike:function(t,n){e(n,{textDecoration:"line-through"})}},t.on("PreProcess SetContent",i))})})}),r(pt,[],function(){return{send:function(e){function t(){!e.async||4==n.readyState||r++>1e4?(e.success&&1e4>r&&200==n.status?e.success.call(e.success_scope,""+n.responseText,n,e):e.error&&e.error.call(e.error_scope,r>1e4?"TIMED_OUT":"GENERAL",n,e),n=null):setTimeout(t,10)}var n,r=0;if(e.scope=e.scope||this,e.success_scope=e.success_scope||e.scope,e.error_scope=e.error_scope||e.scope,e.async=e.async===!1?!1:!0,e.data=e.data||"",n=new XMLHttpRequest){if(n.overrideMimeType&&n.overrideMimeType(e.content_type),n.open(e.type||(e.data?"POST":"GET"),e.url,e.async),e.content_type&&n.setRequestHeader("Content-Type",e.content_type),n.setRequestHeader("X-Requested-With","XMLHttpRequest"),n.send(e.data),!e.async)return t();setTimeout(t,10)}}}}),r(ht,[],function(){function e(t,n){var r,i,o,a;if(n=n||'"',null===t)return"null";if(o=typeof t,"string"==o)return i="\bb t\nn\ff\rr\"\"''\\\\",n+t.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g,function(e,t){return'"'===n&&"'"===e?e:(r=i.indexOf(t),r+1?"\\"+i.charAt(r+1):(e=t.charCodeAt().toString(16),"\\u"+"0000".substring(e.length)+e))})+n;if("object"==o){if(t.hasOwnProperty&&"[object Array]"===Object.prototype.toString.call(t)){for(r=0,i="[";r0?",":"")+e(t[r],n);return i+"]"}i="{";for(a in t)t.hasOwnProperty(a)&&(i+="function"!=typeof t[a]?(i.length>1?","+n:n)+a+n+":"+e(t[a],n):"");return i+"}"}return""+t}return{serialize:e,parse:function(e){try{return window[String.fromCharCode(101)+"val"]("("+e+")")}catch(t){}}}}),r(mt,[ht,pt,p],function(e,t,n){function r(e){this.settings=i({},e),this.count=0}var i=n.extend;return r.sendRPC=function(e){return(new r).send(e)},r.prototype={send:function(n){var r=n.error,o=n.success;n=i(this.settings,n),n.success=function(t,i){t=e.parse(t),"undefined"==typeof t&&(t={error:"JSON Parse error."}),t.error?r.call(n.error_scope||n.scope,t.error,i):o.call(n.success_scope||n.scope,t.result)},n.error=function(e,t){r&&r.call(n.error_scope||n.scope,e,t)},n.data=e.serialize({id:n.id||"c"+this.count++,method:n.method,params:n.params}),n.content_type="application/json",t.send(n)}},r}),r(gt,[y],function(e){return{callbacks:{},count:0,send:function(n){var r=this,i=e.DOM,o=n.count!==t?n.count:r.count,a="tinymce_jsonp_"+o;r.callbacks[o]=function(e){i.remove(a),delete r.callbacks[o],n.callback(e)},i.add(i.doc.body,"script",{id:a,src:n.url,type:"text/javascript"}),r.count++}}}),r(vt,[],function(){function e(){s=[];for(var e in a)s.push(e);i.length=s.length}function n(){function n(e){var n,r;return r=e!==t?u+e:i.indexOf(",",u),-1===r||r>i.length?null:(n=i.substring(u,r),u=r+1,n)}var r,i,s,u=0;if(a={},c){o.load(l),i=o.getAttribute(l)||"";do{var d=n();if(null===d)break;if(r=n(parseInt(d,32)||0),null!==r){if(d=n(),null===d)break;s=n(parseInt(d,32)||0),r&&(a[r]=s)}}while(null!==r);e()}}function r(){var t,n="";if(c){for(var r in a)t=a[r],n+=(n?",":"")+r.length.toString(32)+","+r+","+t.length.toString(32)+","+t;o.setAttribute(l,n);try{o.save(l)}catch(i){}e()}}var i,o,a,s,l,c;try{if(window.localStorage)return localStorage}catch(u){}return l="tinymce",o=document.documentElement,c=!!o.addBehavior,c&&o.addBehavior("#default#userData"),i={key:function(e){return s[e]},getItem:function(e){return e in a?a[e]:null},setItem:function(e,t){a[e]=""+t,r()},removeItem:function(e){delete a[e],r()},clear:function(){a={},r()}},n(),i}),r(yt,[y,l,b,C,p,g],function(e,t,n,r,i,o){var a=window.tinymce;return a.DOM=e.DOM,a.ScriptLoader=n.ScriptLoader,a.PluginManager=r.PluginManager,a.ThemeManager=r.ThemeManager,a.dom=a.dom||{},a.dom.Event=t.Event,i.each(i,function(e,t){a[t]=e}),i.each("isOpera isWebKit isIE isGecko isMac".split(" "),function(e){a[e]=o[e.substr(2).toLowerCase()]}),{}}),r(bt,[z,p],function(e,t){return e.extend({Defaults:{firstControlClass:"first",lastControlClass:"last"},init:function(e){this.settings=t.extend({},this.Defaults,e)},preRender:function(e){e.addClass(this.settings.containerClass,"body")},applyClasses:function(e){var t=this,n=t.settings,r,i,o;r=e.items().filter(":visible"),i=n.firstControlClass,o=n.lastControlClass,r.each(function(e){e.removeClass(i).removeClass(o),n.controlClass&&e.addClass(n.controlClass)}),r.eq(0).addClass(i),r.eq(-1).addClass(o)},renderHtml:function(e){var t=this,n=t.settings,r,i="";return r=e.items(),r.eq(0).addClass(n.firstControlClass),r.eq(-1).addClass(n.lastControlClass),r.each(function(e){n.controlClass&&e.addClass(n.controlClass),i+=e.renderHtml()}),i},recalc:function(){},postRender:function(){}})}),r(Ct,[bt],function(e){return e.extend({Defaults:{containerClass:"abs-layout",controlClass:"abs-layout-item"},recalc:function(e){e.items().filter(":visible").each(function(e){var t=e.settings;e.layoutRect({x:t.x,y:t.y,w:t.w,h:t.h}),e.recalc&&e.recalc()})},renderHtml:function(e){return'
'+this._super(e)}})}),r(xt,[$,Q],function(e,t){return e.extend({Mixins:[t],Defaults:{classes:"widget tooltip tooltip-n"},text:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t._rendered&&(t.getEl().lastChild.innerHTML=t.encode(e)),t):t._value},renderHtml:function(){var e=this,t=e.classPrefix;return'"},repaint:function(){var e=this,t,n;t=e.getEl().style,n=e._layoutRect,t.left=n.x+"px",t.top=n.y+"px",t.zIndex=131070}})}),r(wt,[$,xt],function(e,t){var n,r=e.extend({init:function(e){var t=this;t._super(e),e=t.settings,t.canFocus=!0,e.tooltip&&r.tooltips!==!1&&(t.on("mouseenter",function(n){var r=t.tooltip().moveTo(-65535);if(n.control==t){var i=r.text(e.tooltip).show().testMoveRel(t.getEl(),["bc-tc","bc-tl","bc-tr"]);r.toggleClass("tooltip-n","bc-tc"==i),r.toggleClass("tooltip-nw","bc-tl"==i),r.toggleClass("tooltip-ne","bc-tr"==i),r.moveRel(t.getEl(),i)}else r.hide()}),t.on("mouseleave mousedown click",function(){t.tooltip().hide()})),t.aria("label",e.ariaLabel||e.tooltip)},tooltip:function(){return n||(n=new t({type:"tooltip"}),n.renderTo()),n},active:function(e){var t=this,n;return e!==n&&(t.aria("pressed",e),t.toggleClass("active",e)),t._super(e)},disabled:function(e){var t=this,n;return e!==n&&(t.aria("disabled",e),t.toggleClass("disabled",e)),t._super(e)},postRender:function(){var e=this,t=e.settings;e._rendered=!0,e._super(),e.parent()||!t.width&&!t.height||(e.initLayoutRect(),e.repaint()),t.autofocus&&e.focus()},remove:function(){this._super(),n&&(n.remove(),n=null)}});return r}),r(_t,[wt],function(e){return e.extend({Defaults:{classes:"widget btn",role:"button"},init:function(e){var t=this,n;t.on("click mousedown",function(e){e.preventDefault()}),t._super(e),n=e.size,e.subtype&&t.addClass(e.subtype),n&&t.addClass("btn-"+n)},icon:function(e){var t=this,n=t.classPrefix;if("undefined"==typeof e)return t.settings.icon;if(t.settings.icon=e,e=e?n+"ico "+n+"i-"+t.settings.icon:"",t._rendered){var r=t.getEl().firstChild,i=r.getElementsByTagName("i")[0];e?(i&&i==r.firstChild||(i=document.createElement("i"),r.insertBefore(i,r.firstChild)),i.className=e):i&&r.removeChild(i),t.text(t._text)}return t},repaint:function(){var e=this.getEl().firstChild.style;e.width=e.height="100%",this._super()},text:function(e){var t=this;if(t._rendered){var n=t.getEl().lastChild.lastChild;n&&(n.data=t.translate(e))}return t._super(e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon,i;return i=e.settings.image,i?(r="none","string"!=typeof i&&(i=window.getSelection?i[0]:i[1]),i=" style=\"background-image: url('"+i+"')\""):i="",r=e.settings.icon?n+"ico "+n+"i-"+r:"",'
"}})}),r(Nt,[G],function(e){return e.extend({Defaults:{defaultType:"button",role:"group"},renderHtml:function(){var e=this,t=e._layout;return e.addClass("btn-group"),e.preRender(),t.preRender(e),'
'+(e.settings.html||"")+t.renderHtml(e)+"
"}})}),r(Et,[wt],function(e){return e.extend({Defaults:{classes:"checkbox",role:"checkbox",checked:!1},init:function(e){var t=this;t._super(e),t.on("click mousedown",function(e){e.preventDefault()}),t.on("click",function(e){e.preventDefault(),t.disabled()||t.checked(!t.checked())}),t.checked(t.settings.checked)},checked:function(e){var t=this;return"undefined"!=typeof e?(e?t.addClass("checked"):t.removeClass("checked"),t._checked=e,t.aria("checked",e),t):t._checked},value:function(e){return this.checked(e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix;return'
'+e.encode(e._text)+"
"}})}),r(St,[_t,et],function(e,t){return e.extend({showPanel:function(){var e=this,n=e.settings;if(e.active(!0),e.panel)e.panel.show();else{var r=n.panel;r.type&&(r={layout:"grid",items:r}),r.role=r.role||"dialog",r.popover=!0,r.autohide=!0,r.ariaRoot=!0,e.panel=new t(r).on("hide",function(){e.active(!1)}).on("cancel",function(t){t.stopPropagation(),e.focus(),e.hidePanel()}).parent(e).renderTo(e.getContainerElm()),e.panel.fire("show"),e.panel.reflow()}e.panel.moveRel(e.getEl(),n.popoverAlign||(e.isRtl()?["bc-tr","bc-tc"]:["bc-tl","bc-tc"]))},hidePanel:function(){var e=this;e.panel&&e.panel.hide()},postRender:function(){var e=this;return e.aria("haspopup",!0),e.on("click",function(t){t.control===e&&(e.panel&&e.panel.visible()?e.hidePanel():(e.showPanel(),e.panel.focus(!!t.aria)))}),e._super()}})}),r(kt,[St,y],function(e,t){var n=t.DOM;return e.extend({init:function(e){this._super(e),this.addClass("colorbutton")},color:function(e){return e?(this._color=e,this.getEl("preview").style.backgroundColor=e,this):this._color},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon?n+"ico "+n+"i-"+e.settings.icon:"",i=e.settings.image?" style=\"background-image: url('"+e.settings.image+"')\"":"";return'
'},postRender:function(){var e=this,t=e.settings.onclick;return e.on("click",function(r){r.aria&&"down"==r.aria.key||r.control!=e||n.getParent(r.target,"."+e.classPrefix+"open")||(r.stopImmediatePropagation(),t.call(e,r))}),delete e.settings.onclick,e._super()}})}),r(Tt,[wt,j,q],function(e,t,n){return e.extend({init:function(e){var t=this;t._super(e),t.addClass("combobox"),t.subinput=!0,t.ariaTarget="inp",e=t.settings,e.menu=e.menu||e.values,e.menu&&(e.icon="caret"),t.on("click",function(n){for(var r=n.target,i=t.getEl();r&&r!=i;)r.id&&-1!=r.id.indexOf("-open")&&(t.fire("action"),e.menu&&(t.showMenu(),n.aria&&t.menu.items()[0].focus())),r=r.parentNode}),t.on("keydown",function(e){"INPUT"==e.target.nodeName&&13==e.keyCode&&t.parents().reverse().each(function(n){return e.preventDefault(),t.fire("change"),n.hasEventListeners("submit")&&n.toJSON?(n.fire("submit",{data:n.toJSON()}),!1):void 0})}),e.placeholder&&(t.addClass("placeholder"),t.on("focusin",function(){t._hasOnChange||(n.on(t.getEl("inp"),"change",function(){t.fire("change")}),t._hasOnChange=!0),t.hasClass("placeholder")&&(t.getEl("inp").value="",t.removeClass("placeholder"))}),t.on("focusout",function(){0===t.value().length&&(t.getEl("inp").value=e.placeholder,t.addClass("placeholder"))}))},showMenu:function(){var e=this,n=e.settings,r;e.menu||(r=n.menu||[],r.length?r={type:"menu",items:r}:r.type=r.type||"menu",e.menu=t.create(r).parent(e).renderTo(e.getContainerElm()),e.fire("createmenu"),e.menu.reflow(),e.menu.on("cancel",function(t){t.control===e.menu&&e.focus()}),e.menu.on("show hide",function(t){t.control.items().each(function(t){t.active(t.value()==e.value())})}).fire("show"),e.menu.on("select",function(t){e.value(t.control.value())}),e.on("focusin",function(t){"INPUT"==t.target.tagName.toUpperCase()&&e.menu.hide()}),e.aria("expanded",!0)),e.menu.show(),e.menu.layoutRect({w:e.layoutRect().w}),e.menu.moveRel(e.getEl(),e.isRtl()?["br-tr","tr-br"]:["bl-tl","tl-bl"])},value:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t.removeClass("placeholder"),t._rendered&&(t.getEl("inp").value=e),t):t._rendered?(e=t.getEl("inp").value,e!=t.settings.placeholder?e:""):t._value},disabled:function(e){var t=this;return t._rendered&&"undefined"!=typeof e&&(t.getEl("inp").disabled=e),t._super(e)},focus:function(){this.getEl("inp").focus()},repaint:function(){var e=this,t=e.getEl(),r=e.getEl("open"),i=e.layoutRect(),o,a;o=r?i.w-n.getSize(r).width-10:i.w-10;var s=document;return s.all&&(!s.documentMode||s.documentMode<=8)&&(a=e.layoutRect().h-2+"px"),n.css(t.firstChild,{width:o,lineHeight:a}),e._super(),e},postRender:function(){var e=this;return n.on(this.getEl("inp"),"change",function(){e.fire("change")}),e._super()},remove:function(){n.off(this.getEl("inp")),this._super()},renderHtml:function(){var e=this,t=e._id,n=e.settings,r=e.classPrefix,i=n.value||n.placeholder||"",o,a,s="",l="";return"spellcheck"in n&&(l+=' spellcheck="'+n.spellcheck+'"'),n.maxLength&&(l+=' maxlength="'+n.maxLength+'"'),n.size&&(l+=' size="'+n.size+'"'),n.subtype&&(l+=' type="'+n.subtype+'"'),e.disabled()&&(l+=' disabled="disabled"'),o=n.icon,o&&"caret"!=o&&(o=r+"ico "+r+"i-"+n.icon),a=e._text,(o||a)&&(s='
",e.addClass("has-open")),'
"+s+"
" +}})}),r(Rt,[wt],function(e){return e.extend({init:function(e){var t=this;e.delimiter||(e.delimiter="\xbb"),t._super(e),t.addClass("path"),t.canFocus=!0,t.on("click",function(e){var n,r=e.target;(n=r.getAttribute("data-index"))&&t.fire("select",{value:t.data()[n],index:n})})},focus:function(){var e=this;return e.getEl().firstChild.focus(),e},data:function(e){var t=this;return"undefined"!=typeof e?(t._data=e,t.update(),t):t._data},update:function(){this.innerHtml(this._getPathHtml())},postRender:function(){var e=this;e._super(),e.data(e.settings.data)},renderHtml:function(){var e=this;return'
'+e._getPathHtml()+"
"},_getPathHtml:function(){var e=this,t=e._data||[],n,r,i="",o=e.classPrefix;for(n=0,r=t.length;r>n;n++)i+=(n>0?'":"")+'
'+t[n].name+"
";return i||(i='
\xa0
'),i}})}),r(At,[Rt,dt],function(e,t){return e.extend({postRender:function(){function e(e){if(1===e.nodeType){if("BR"==e.nodeName||e.getAttribute("data-mce-bogus"))return!0;if("bookmark"===e.getAttribute("data-mce-type"))return!0}return!1}var n=this,r=t.activeEditor;return n.on("select",function(t){var n=[],i,o=r.getBody();for(r.focus(),i=r.selection.getStart();i&&i!=o;)e(i)||n.push(i),i=i.parentNode;r.selection.select(n[n.length-1-t.index]),r.nodeChanged()}),r.on("nodeChange",function(t){for(var i=[],o=t.parents,a=o.length;a--;)if(1==o[a].nodeType&&!e(o[a])){var s=r.fire("ResolveName",{name:o[a].nodeName.toLowerCase(),target:o[a]});i.push({name:s.name})}n.data(i)}),n._super()}})}),r(Bt,[G],function(e){return e.extend({Defaults:{layout:"flex",align:"center",defaults:{flex:1}},renderHtml:function(){var e=this,t=e._layout,n=e.classPrefix;return e.addClass("formitem"),t.preRender(e),'
'+(e.settings.title?'
'+e.settings.title+"
":"")+'
'+(e.settings.html||"")+t.renderHtml(e)+"
"}})}),r(Dt,[G,Bt],function(e,t){return e.extend({Defaults:{containerCls:"form",layout:"flex",direction:"column",align:"stretch",flex:1,padding:20,labelGap:30,spacing:10,callbacks:{submit:function(){this.submit()}}},preRender:function(){var e=this,n=e.items();n.each(function(n){var r,i=n.settings.label;i&&(r=new t({layout:"flex",autoResize:"overflow",defaults:{flex:1},items:[{type:"label",id:n._id+"-l",text:i,flex:0,forId:n._id,disabled:n.disabled()}]}),r.type="formitem",n.aria("labelledby",n._id+"-l"),"undefined"==typeof n.settings.flex&&(n.settings.flex=1),e.replace(n,r),r.add(n))})},recalcLabels:function(){var e=this,t=0,n=[],r,i;if(e.settings.labelGapCalc!==!1)for(e.items().filter("formitem").each(function(e){var r=e.items()[0],i=r.getEl().clientWidth;t=i>t?i:t,n.push(r)}),i=e.settings.labelGap||0,r=n.length;r--;)n[r].settings.minWidth=t+i},visible:function(e){var t=this._super(e);return e===!0&&this._rendered&&this.recalcLabels(),t},submit:function(){return this.fire("submit",{data:this.toJSON()})},postRender:function(){var e=this;e._super(),e.recalcLabels(),e.fromJSON(e.settings.data)}})}),r(Lt,[Dt],function(e){return e.extend({Defaults:{containerCls:"fieldset",layout:"flex",direction:"column",align:"stretch",flex:1,padding:"25 15 5 15",labelGap:30,spacing:10,border:1},renderHtml:function(){var e=this,t=e._layout,n=e.classPrefix;return e.preRender(),t.preRender(e),'
'+(e.settings.title?''+e.settings.title+"":"")+'
'+(e.settings.html||"")+t.renderHtml(e)+"
"}})}),r(Mt,[Tt],function(e){return e.extend({init:function(e){var t=this,n=tinymce.activeEditor,r;e.spellcheck=!1,r=n.settings.file_browser_callback,r&&(e.icon="browse",e.onaction=function(){r(t.getEl("inp").id,t.getEl("inp").value,e.filetype,window)}),t._super(e)}})}),r(Ht,[Ct],function(e){return e.extend({recalc:function(e){var t=e.layoutRect(),n=e.paddingBox();e.items().filter(":visible").each(function(e){e.layoutRect({x:n.left,y:n.top,w:t.innerW-n.right-n.left,h:t.innerH-n.top-n.bottom}),e.recalc&&e.recalc()})}})}),r(Pt,[Ct],function(e){return e.extend({recalc:function(e){var t,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v=[],y,b,C,x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I,F,z=Math.max,W=Math.min;for(r=e.items().filter(":visible"),i=e.layoutRect(),o=e._paddingBox,a=e.settings,f=e.isRtl()?a.direction||"row-reversed":a.direction,s=a.align,l=e.isRtl()?a.pack||"end":a.pack,c=a.spacing||0,("row-reversed"==f||"column-reverse"==f)&&(r=r.set(r.toArray().reverse()),f=f.split("-")[0]),"column"==f?(S="y",N="h",E="minH",k="maxH",R="innerH",T="top",A="deltaH",B="contentH",P="left",M="w",D="x",L="innerW",H="minW",O="right",I="deltaW",F="contentW"):(S="x",N="w",E="minW",k="maxW",R="innerW",T="left",A="deltaW",B="contentW",P="top",M="h",D="y",L="innerH",H="minH",O="bottom",I="deltaH",F="contentH"),d=i[R]-o[T]-o[T],_=u=0,t=0,n=r.length;n>t;t++)p=r[t],h=p.layoutRect(),m=p.settings,g=m.flex,d-=n-1>t?c:0,g>0&&(u+=g,h[k]&&v.push(p),h.flex=g),d-=h[E],y=o[P]+h[H]+o[O],y>_&&(_=y);if(x={},x[E]=0>d?i[E]-d+i[A]:i[R]-d+i[A],x[H]=_+i[I],x[B]=i[R]-d,x[F]=_,x.minW=W(x.minW,i.maxW),x.minH=W(x.minH,i.maxH),x.minW=z(x.minW,i.startMinWidth),x.minH=z(x.minH,i.startMinHeight),!i.autoResize||x.minW==i.minW&&x.minH==i.minH){for(C=d/u,t=0,n=v.length;n>t;t++)p=v[t],h=p.layoutRect(),b=h[k],y=h[E]+h.flex*C,y>b?(d-=h[k]-h[E],u-=h.flex,h.flex=0,h.maxFlexSize=b):h.maxFlexSize=0;for(C=d/u,w=o[T],x={},0===u&&("end"==l?w=d+o[T]:"center"==l?(w=Math.round(i[R]/2-(i[R]-d)/2)+o[T],0>w&&(w=o[T])):"justify"==l&&(w=o[T],c=Math.floor(d/(r.length-1)))),x[D]=o[P],t=0,n=r.length;n>t;t++)p=r[t],h=p.layoutRect(),y=h.maxFlexSize||h[E],"center"===s?x[D]=Math.round(i[L]/2-h[M]/2):"stretch"===s?(x[M]=z(h[H]||0,i[L]-o[P]-o[O]),x[D]=o[P]):"end"===s&&(x[D]=i[L]-h[M]-o.top),h.flex>0&&(y+=h.flex*C),x[N]=y,x[S]=w,p.layoutRect(x),p.recalc&&p.recalc(),w+=y+c}else if(x.w=x.minW,x.h=x.minH,e.layoutRect(x),this.recalc(e),null===e._lastRect){var V=e.parent();V&&(V._lastRect=null,V.recalc())}}})}),r(Ot,[bt],function(e){return e.extend({Defaults:{containerClass:"flow-layout",controlClass:"flow-layout-item",endClass:"break"},recalc:function(e){e.items().filter(":visible").each(function(e){e.recalc&&e.recalc()})}})}),r(It,[$,wt,et,p,dt,g],function(e,t,n,r,i,o){function a(e){function t(t,n){return function(){var r=this;e.on("nodeChange",function(i){var o=e.formatter,a=null;s(i.parents,function(e){return s(t,function(t){return n?o.matchNode(e,n,{value:t.value})&&(a=t.value):o.matchNode(e,t.value)&&(a=t.value),a?!1:void 0}),a?!1:void 0}),r.value(a)})}}function r(e){e=e.replace(/;$/,"").split(";");for(var t=e.length;t--;)e[t]=e[t].split("=");return e}function i(){function t(e){var n=[];if(e)return s(e,function(e){var o={text:e.title,icon:e.icon};if(e.items)o.menu=t(e.items);else{var a=e.format||"custom"+r++;e.format||(e.name=a,i.push(e)),o.format=a}n.push(o)}),n}function n(){var n;return n=t(e.settings.style_formats_merge?e.settings.style_formats?o.concat(e.settings.style_formats):o:e.settings.style_formats||o)}var r=0,i=[],o=[{title:"Headings",items:[{title:"Heading 1",format:"h1"},{title:"Heading 2",format:"h2"},{title:"Heading 3",format:"h3"},{title:"Heading 4",format:"h4"},{title:"Heading 5",format:"h5"},{title:"Heading 6",format:"h6"}]},{title:"Inline",items:[{title:"Bold",icon:"bold",format:"bold"},{title:"Italic",icon:"italic",format:"italic"},{title:"Underline",icon:"underline",format:"underline"},{title:"Strikethrough",icon:"strikethrough",format:"strikethrough"},{title:"Superscript",icon:"superscript",format:"superscript"},{title:"Subscript",icon:"subscript",format:"subscript"},{title:"Code",icon:"code",format:"code"}]},{title:"Blocks",items:[{title:"Paragraph",format:"p"},{title:"Blockquote",format:"blockquote"},{title:"Div",format:"div"},{title:"Pre",format:"pre"}]},{title:"Alignment",items:[{title:"Left",icon:"alignleft",format:"alignleft"},{title:"Center",icon:"aligncenter",format:"aligncenter"},{title:"Right",icon:"alignright",format:"alignright"},{title:"Justify",icon:"alignjustify",format:"alignjustify"}]}];return e.on("init",function(){s(i,function(t){e.formatter.register(t.name,t)})}),{type:"menu",items:n(),onPostRender:function(t){e.fire("renderFormatsMenu",{control:t.control})},itemDefaults:{preview:!0,textStyle:function(){return this.settings.format?e.formatter.getCssText(this.settings.format):void 0},onPostRender:function(){var t=this,n=this.settings.format;n&&t.parent().on("show",function(){t.disabled(!e.formatter.canApply(n)),t.active(e.formatter.match(n))})},onclick:function(){this.settings.format&&d(this.settings.format)}}}}function o(){return e.undoManager?e.undoManager.hasUndo():!1}function a(){return e.undoManager?e.undoManager.hasRedo():!1}function l(){var t=this;t.disabled(!o()),e.on("Undo Redo AddUndo TypingUndo",function(){t.disabled(!o())})}function c(){var t=this;t.disabled(!a()),e.on("Undo Redo AddUndo TypingUndo",function(){t.disabled(!a())})}function u(){var t=this;e.on("VisualAid",function(e){t.active(e.hasVisual)}),t.active(e.hasVisual)}function d(t){t.control&&(t=t.control.value()),t&&e.execCommand("mceToggleFormat",!1,t)}var f;f=i(),s({bold:"Bold",italic:"Italic",underline:"Underline",strikethrough:"Strikethrough",subscript:"Subscript",superscript:"Superscript"},function(t,n){e.addButton(n,{tooltip:t,onPostRender:function(){var t=this;e.formatter?e.formatter.formatChanged(n,function(e){t.active(e)}):e.on("init",function(){e.formatter.formatChanged(n,function(e){t.active(e)})})},onclick:function(){d(n)}})}),s({outdent:["Decrease indent","Outdent"],indent:["Increase indent","Indent"],cut:["Cut","Cut"],copy:["Copy","Copy"],paste:["Paste","Paste"],help:["Help","mceHelp"],selectall:["Select all","SelectAll"],hr:["Insert horizontal rule","InsertHorizontalRule"],removeformat:["Clear formatting","RemoveFormat"],visualaid:["Visual aids","mceToggleVisualAid"],newdocument:["New document","mceNewDocument"]},function(t,n){e.addButton(n,{tooltip:t[0],cmd:t[1]})}),s({blockquote:["Blockquote","mceBlockQuote"],numlist:["Numbered list","InsertOrderedList"],bullist:["Bullet list","InsertUnorderedList"],subscript:["Subscript","Subscript"],superscript:["Superscript","Superscript"],alignleft:["Align left","JustifyLeft"],aligncenter:["Align center","JustifyCenter"],alignright:["Align right","JustifyRight"],alignjustify:["Justify","JustifyFull"]},function(t,n){e.addButton(n,{tooltip:t[0],cmd:t[1],onPostRender:function(){var t=this;e.formatter?e.formatter.formatChanged(n,function(e){t.active(e)}):e.on("init",function(){e.formatter.formatChanged(n,function(e){t.active(e)})})}})}),e.addButton("undo",{tooltip:"Undo",onPostRender:l,cmd:"undo"}),e.addButton("redo",{tooltip:"Redo",onPostRender:c,cmd:"redo"}),e.addMenuItem("newdocument",{text:"New document",shortcut:"Ctrl+N",icon:"newdocument",cmd:"mceNewDocument"}),e.addMenuItem("undo",{text:"Undo",icon:"undo",shortcut:"Ctrl+Z",onPostRender:l,cmd:"undo"}),e.addMenuItem("redo",{text:"Redo",icon:"redo",shortcut:"Ctrl+Y",onPostRender:c,cmd:"redo"}),e.addMenuItem("visualaid",{text:"Visual aids",selectable:!0,onPostRender:u,cmd:"mceToggleVisualAid"}),s({cut:["Cut","Cut","Ctrl+X"],copy:["Copy","Copy","Ctrl+C"],paste:["Paste","Paste","Ctrl+V"],selectall:["Select all","SelectAll","Ctrl+A"],bold:["Bold","Bold","Ctrl+B"],italic:["Italic","Italic","Ctrl+I"],underline:["Underline","Underline"],strikethrough:["Strikethrough","Strikethrough"],subscript:["Subscript","Subscript"],superscript:["Superscript","Superscript"],removeformat:["Clear formatting","RemoveFormat"]},function(t,n){e.addMenuItem(n,{text:t[0],icon:n,shortcut:t[2],cmd:t[1]})}),e.on("mousedown",function(){n.hideAll()}),e.addButton("styleselect",{type:"menubutton",text:"Formats",menu:f}),e.addButton("formatselect",function(){var n=[],i=r(e.settings.block_formats||"Paragraph=p;Address=address;Pre=pre;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6");return s(i,function(t){n.push({text:t[0],value:t[1],textStyle:function(){return e.formatter.getCssText(t[1])}})}),{type:"listbox",text:i[0][0],values:n,fixedWidth:!0,onselect:d,onPostRender:t(n)}}),e.addButton("fontselect",function(){var n="Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",i=[],o=r(e.settings.font_formats||n);return s(o,function(e){i.push({text:{raw:e[0]},value:e[1],textStyle:-1==e[1].indexOf("dings")?"font-family:"+e[1]:""})}),{type:"listbox",text:"Font Family",tooltip:"Font Family",values:i,fixedWidth:!0,onPostRender:t(i,"fontname"),onselect:function(t){t.control.settings.value&&e.execCommand("FontName",!1,t.control.settings.value)}}}),e.addButton("fontsizeselect",function(){var n=[],r="8pt 10pt 12pt 14pt 18pt 24pt 36pt",i=e.settings.fontsize_formats||r;return s(i.split(" "),function(e){n.push({text:e,value:e})}),{type:"listbox",text:"Font Sizes",tooltip:"Font Sizes",values:n,fixedWidth:!0,onPostRender:t(n,"fontsize"),onclick:function(t){t.control.settings.value&&e.execCommand("FontSize",!1,t.control.settings.value)}}}),e.addMenuItem("formats",{text:"Formats",menu:f})}var s=r.each;i.on("AddEditor",function(t){t.editor.rtl&&(e.rtl=!0),a(t.editor)}),e.translate=function(e){return i.translate(e)},t.tooltips=!o.iOS}),r(Ft,[Ct],function(e){return e.extend({recalc:function(e){var t=e.settings,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v,y,b,C,x,w,_,N=[],E=[],S,k,T,R;for(t=e.settings,i=e.items().filter(":visible"),o=e.layoutRect(),r=t.columns||Math.ceil(Math.sqrt(i.length)),n=Math.ceil(i.length/r),y=t.spacingH||t.spacing||0,b=t.spacingV||t.spacing||0,C=t.alignH||t.align,x=t.alignV||t.align,g=e._paddingBox,C&&"string"==typeof C&&(C=[C]),x&&"string"==typeof x&&(x=[x]),d=0;r>d;d++)N.push(0);for(f=0;n>f;f++)E.push(0);for(f=0;n>f;f++)for(d=0;r>d&&(u=i[f*r+d],u);d++)c=u.layoutRect(),S=c.minW,k=c.minH,N[d]=S>N[d]?S:N[d],E[f]=k>E[f]?k:E[f];for(T=o.innerW-g.left-g.right,w=0,d=0;r>d;d++)w+=N[d]+(d>0?y:0),T-=(d>0?y:0)+N[d];for(R=o.innerH-g.top-g.bottom,_=0,f=0;n>f;f++)_+=E[f]+(f>0?b:0),R-=(f>0?b:0)+E[f];if(w+=g.left+g.right,_+=g.top+g.bottom,l={},l.minW=w+(o.w-o.innerW),l.minH=_+(o.h-o.innerH),l.contentW=l.minW-o.deltaW,l.contentH=l.minH-o.deltaH,l.minW=Math.min(l.minW,o.maxW),l.minH=Math.min(l.minH,o.maxH),l.minW=Math.max(l.minW,o.startMinWidth),l.minH=Math.max(l.minH,o.startMinHeight),!o.autoResize||l.minW==o.minW&&l.minH==o.minH){o.autoResize&&(l=e.layoutRect(l),l.contentW=l.minW-o.deltaW,l.contentH=l.minH-o.deltaH);var A;A="start"==t.packV?0:R>0?Math.floor(R/n):0;var B=0,D=t.flexWidths;if(D)for(d=0;dd;d++)N[d]+=D?D[d]*L:L;for(h=g.top,f=0;n>f;f++){for(p=g.left,s=E[f]+A,d=0;r>d&&(u=i[f*r+d],u);d++)m=u.settings,c=u.layoutRect(),a=Math.max(N[d],c.startMinWidth),c.x=p,c.y=h,v=m.alignH||(C?C[d]||C[0]:null),"center"==v?c.x=p+a/2-c.w/2:"right"==v?c.x=p+a-c.w:"stretch"==v&&(c.w=a),v=m.alignV||(x?x[d]||x[0]:null),"center"==v?c.y=h+s/2-c.h/2:"bottom"==v?c.y=h+s-c.h:"stretch"==v&&(c.h=s),u.layoutRect(c),p+=a+y,u.recalc&&u.recalc();h+=s+b}}else if(l.w=l.minW,l.h=l.minH,e.layoutRect(l),this.recalc(e),null===e._lastRect){var M=e.parent();M&&(M._lastRect=null,M.recalc())}}})}),r(zt,[wt],function(e){return e.extend({renderHtml:function(){var e=this;return e.addClass("iframe"),e.canFocus=!1,''},src:function(e){this.getEl().src=e},html:function(e,t){var n=this,r=this.getEl().contentWindow.document.body;return r?(r.innerHTML=e,t&&t()):setTimeout(function(){n.html(e)},0),this}})}),r(Wt,[wt,q],function(e,t){return e.extend({init:function(e){var t=this;t._super(e),t.addClass("widget"),t.addClass("label"),t.canFocus=!1,e.multiline&&t.addClass("autoscroll"),e.strong&&t.addClass("strong")},initLayoutRect:function(){var e=this,n=e._super();if(e.settings.multiline){var r=t.getSize(e.getEl());r.width>n.maxW&&(n.minW=n.maxW,e.addClass("multiline")),e.getEl().style.width=n.minW+"px",n.startMinH=n.h=n.minH=Math.min(n.maxH,t.getSize(e.getEl()).height)}return n},repaint:function(){var e=this;return e.settings.multiline||(e.getEl().style.lineHeight=e.layoutRect().h+"px"),e._super()},text:function(e){var t=this;return t._rendered&&e&&this.innerHtml(t.encode(e)),t._super(e)},renderHtml:function(){var e=this,t=e.settings.forId;return'"}})}),r(Vt,[G],function(e){return e.extend({Defaults:{role:"toolbar",layout:"flow"},init:function(e){var t=this;t._super(e),t.addClass("toolbar")},postRender:function(){var e=this;return e.items().addClass("toolbar-item"),e._super()}})}),r(Ut,[Vt],function(e){return e.extend({Defaults:{role:"menubar",containerCls:"menubar",ariaRoot:!0,defaults:{type:"menubutton"}}})}),r(qt,[_t,j,Ut],function(e,t,n){function r(e,t){for(;e;){if(t===e)return!0;e=e.parentNode}return!1}var i=e.extend({init:function(e){var t=this;t._renderOpen=!0,t._super(e),t.addClass("menubtn"),e.fixedWidth&&t.addClass("fixed-width"),t.aria("haspopup",!0),t.hasPopup=!0},showMenu:function(){var e=this,n=e.settings,r;return e.menu&&e.menu.visible()?e.hideMenu():(e.menu||(r=n.menu||[],r.length?r={type:"menu",items:r}:r.type=r.type||"menu",e.menu=t.create(r).parent(e).renderTo(),e.fire("createmenu"),e.menu.reflow(),e.menu.on("cancel",function(t){t.control.parent()===e.menu&&(t.stopPropagation(),e.focus(),e.hideMenu())}),e.menu.on("select",function(){e.focus()}),e.menu.on("show hide",function(t){t.control==e.menu&&e.activeMenu("show"==t.type),e.aria("expanded","show"==t.type)}).fire("show")),e.menu.show(),e.menu.layoutRect({w:e.layoutRect().w}),void e.menu.moveRel(e.getEl(),e.isRtl()?["br-tr","tr-br"]:["bl-tl","tl-bl"]))},hideMenu:function(){var e=this;e.menu&&(e.menu.items().each(function(e){e.hideMenu&&e.hideMenu()}),e.menu.hide())},activeMenu:function(e){this.toggleClass("active",e)},renderHtml:function(){var e=this,t=e._id,r=e.classPrefix,i=e.settings.icon?r+"ico "+r+"i-"+e.settings.icon:"";return e.aria("role",e.parent()instanceof n?"menuitem":"button"),'
'},postRender:function(){var e=this;return e.on("click",function(t){t.control===e&&r(t.target,e.getEl())&&(e.showMenu(),t.aria&&e.menu.items()[0].focus())}),e.on("mouseenter",function(t){var n=t.control,r=e.parent(),o;n&&r&&n instanceof i&&n.parent()==r&&(r.items().filter("MenuButton").each(function(e){e.hideMenu&&e!=n&&(e.menu&&e.menu.visible()&&(o=!0),e.hideMenu())}),o&&(n.focus(),n.showMenu()))}),e._super()},text:function(e){var t=this,n,r;if(t._rendered)for(r=t.getEl("open").getElementsByTagName("span"),n=0;n0&&(o=n[0].text,t._value=n[0].value),e.menu=n}e.text=e.text||o||n[0].text,t._super(e),t.addClass("listbox"),t.on("select",function(n){var r=n.control;a&&(n.lastControl=a),e.multiple?r.active(!r.active()):t.value(n.control.settings.value),a=r})},value:function(e){function t(e,n){e.items().each(function(e){r=e.value()===n,r&&(i=i||e.text()),e.active(r),e.menu&&t(e.menu,n)})}var n=this,r,i,o,a;if("undefined"!=typeof e){if(n.menu)t(n.menu,e);else for(o=n.settings.menu,a=0;a'+("-"!==o?'\xa0":"")+("-"!==o?''+o+"":"")+(l?'
'+l+"
":"")+(r.menu?'
':"")+""},postRender:function(){var e=this,t=e.settings,n=t.textStyle;if("function"==typeof n&&(n=n.call(this)),n){var r=e.getEl("text");r&&r.setAttribute("style",n)}return e.on("mouseenter click",function(n){n.control===e&&(t.menu||"click"!==n.type?(e.showMenu(),n.aria&&e.menu.focus(!0)):(e.fire("select"),e.parent().hideAll()))}),e._super(),e},active:function(e){return"undefined"!=typeof e&&this.aria("checked",e),this._super(e)},remove:function(){this._super(),this.menu&&this.menu.remove()}})}),r(Kt,[et,jt,p],function(e,t,n){var r=e.extend({Defaults:{defaultType:"menuitem",border:1,layout:"stack",role:"application",bodyRole:"menu",ariaRoot:!0},init:function(e){var t=this;if(e.autohide=!0,e.constrainToViewport=!0,e.itemDefaults)for(var r=e.items,i=r.length;i--;)r[i]=n.extend({},e.itemDefaults,r[i]);t._super(e),t.addClass("menu")},repaint:function(){return this.toggleClass("menu-align",!0),this._super(),this.getEl().style.height="",this.getEl("body").style.height="",this},cancel:function(){var e=this;e.hideAll(),e.fire("select")},hideAll:function(){var e=this;return this.find("menuitem").exec("hideMenu"),e._super()},preRender:function(){var e=this;return e.items().each(function(t){var n=t.settings;return n.icon||n.selectable?(e._hasIcons=!0,!1):void 0}),e._super()}});return r}),r(Gt,[Et],function(e){return e.extend({Defaults:{classes:"radio",role:"radio"}})}),r(Yt,[wt,Y],function(e,t){return e.extend({renderHtml:function(){var e=this,t=e.classPrefix;return e.addClass("resizehandle"),"both"==e.settings.direction&&e.addClass("resizehandle-both"),e.canFocus=!1,'
'},postRender:function(){var e=this;e._super(),e.resizeDragHelper=new t(this._id,{start:function(){e.fire("ResizeStart")},drag:function(t){"both"!=e.settings.direction&&(t.deltaX=0),e.fire("Resize",t)},stop:function(){e.fire("ResizeEnd")}})},remove:function(){return this.resizeDragHelper&&this.resizeDragHelper.destroy(),this._super()}})}),r(Xt,[wt],function(e){return e.extend({renderHtml:function(){var e=this;return e.addClass("spacer"),e.canFocus=!1,'
'}})}),r(Jt,[qt,q],function(e,t){return e.extend({Defaults:{classes:"widget btn splitbtn",role:"button"},repaint:function(){var e=this,n=e.getEl(),r=e.layoutRect(),i,o;return e._super(),i=n.firstChild,o=n.lastChild,t.css(i,{width:r.w-t.getSize(o).width,height:r.h-2}),t.css(o,{height:r.h-2}),e},activeMenu:function(e){var n=this;t.toggleClass(n.getEl().lastChild,n.classPrefix+"active",e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon?n+"ico "+n+"i-"+e.settings.icon:"";return'
'},postRender:function(){var e=this,t=e.settings.onclick;return e.on("click",function(e){var n=e.target;if(e.control==this)for(;n;){if(e.aria&&"down"!=e.aria.key||"BUTTON"==n.nodeName&&-1==n.className.indexOf("open"))return e.stopImmediatePropagation(),void t.call(this,e);n=n.parentNode}}),delete e.settings.onclick,e._super()}})}),r(Qt,[Ot],function(e){return e.extend({Defaults:{containerClass:"stack-layout",controlClass:"stack-layout-item",endClass:"break"}})}),r(Zt,[J,q],function(e,t){return e.extend({lastIdx:0,Defaults:{layout:"absolute",defaults:{type:"panel"}},activateTab:function(e){var n;this.activeTabId&&(n=this.getEl(this.activeTabId),t.removeClass(n,this.classPrefix+"active"),n.setAttribute("aria-selected","false")),this.activeTabId="t"+e,n=this.getEl("t"+e),n.setAttribute("aria-selected","true"),t.addClass(n,this.classPrefix+"active"),e!=this.lastIdx&&(this.items()[this.lastIdx].hide(),this.lastIdx=e),this.items()[e].show().fire("showtab"),this.reflow()},renderHtml:function(){var e=this,t=e._layout,n="",r=e.classPrefix;return e.preRender(),t.preRender(e),e.items().each(function(t,i){var o=e._id+"-t"+i;t.aria("role","tabpanel"),t.aria("labelledby",o),n+='"}),'
'+n+'
'+t.renderHtml(e)+"
"},postRender:function(){var e=this;e._super(),e.settings.activeTab=e.settings.activeTab||0,e.activateTab(e.settings.activeTab),this.on("click",function(t){var n=t.target.parentNode;if(t.target.parentNode.id==e._id+"-head")for(var r=n.childNodes.length;r--;)n.childNodes[r]==t.target&&e.activateTab(r)})},initLayoutRect:function(){var e=this,n,r,i;r=t.getSize(e.getEl("head")).width,r=0>r?0:r,i=0,e.items().each(function(t,n){r=Math.max(r,t.layoutRect().minW),i=Math.max(i,t.layoutRect().minH),e.settings.activeTab!=n&&t.hide()}),e.items().each(function(e){e.settings.x=0,e.settings.y=0,e.settings.w=r,e.settings.h=i,e.layoutRect({x:0,y:0,w:r,h:i})});var o=t.getSize(e.getEl("head")).height;return e.settings.minWidth=r,e.settings.minHeight=i+o,n=e._super(),n.deltaH+=o,n.innerH=n.h-n.deltaH,n}})}),r(en,[wt,q],function(e,t){return e.extend({init:function(e){var t=this;t._super(e),t._value=e.value||"",t.addClass("textbox"),e.multiline?t.addClass("multiline"):t.on("keydown",function(e){13==e.keyCode&&t.parents().reverse().each(function(t){return e.preventDefault(),t.hasEventListeners("submit")&&t.toJSON?(t.fire("submit",{data:t.toJSON()}),!1):void 0})})},disabled:function(e){var t=this;return t._rendered&&"undefined"!=typeof e&&(t.getEl().disabled=e),t._super(e)},value:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t._rendered&&(t.getEl().value=e),t):t._rendered?t.getEl().value:t._value},repaint:function(){var e=this,t,n,r,i=0,o=0,a;t=e.getEl().style,n=e._layoutRect,a=e._lastRepaintRect||{};var s=document;return!e.settings.multiline&&s.all&&(!s.documentMode||s.documentMode<=8)&&(t.lineHeight=n.h-o+"px"),r=e._borderBox,i=r.left+r.right+8,o=r.top+r.bottom+(e.settings.multiline?8:0),n.x!==a.x&&(t.left=n.x+"px",a.x=n.x),n.y!==a.y&&(t.top=n.y+"px",a.y=n.y),n.w!==a.w&&(t.width=n.w-i+"px",a.w=n.w),n.h!==a.h&&(t.height=n.h-o+"px",a.h=n.h),e._lastRepaintRect=a,e.fire("repaint",{},!1),e},renderHtml:function(){var e=this,t=e._id,n=e.settings,r=e.encode(e._value,!1),i="";return"spellcheck"in n&&(i+=' spellcheck="'+n.spellcheck+'"'),n.maxLength&&(i+=' maxlength="'+n.maxLength+'"'),n.size&&(i+=' size="'+n.size+'"'),n.subtype&&(i+=' type="'+n.subtype+'"'),e.disabled()&&(i+=' disabled="disabled"'),n.multiline?'":'"},postRender:function(){var e=this;return t.on(e.getEl(),"change",function(t){e.fire("change",t)}),e._super()},remove:function(){t.off(this.getEl()),this._super()}})}),r(tn,[q,$],function(e,t){return function(n,r){var i=this,o,a=t.classPrefix;i.show=function(t){return i.hide(),o=!0,window.setTimeout(function(){o&&n.appendChild(e.createFragment('
'))},t||0),i},i.hide=function(){var e=n.lastChild;return e&&-1!=e.className.indexOf("throbber")&&e.parentNode.removeChild(e),o=!1,i}}}),a([l,c,u,d,f,p,h,m,g,v,y,b,C,x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I,F,z,W,V,U,q,$,j,K,G,Y,X,J,Q,Z,et,tt,nt,rt,it,ot,at,st,lt,ct,ut,dt,ft,pt,ht,mt,gt,vt,yt,bt,Ct,xt,wt,_t,Nt,Et,St,kt,Tt,Rt,At,Bt,Dt,Lt,Mt,Ht,Pt,Ot,It,Ft,zt,Wt,Vt,Ut,qt,$t,jt,Kt,Gt,Yt,Xt,Jt,Qt,Zt,en,tn])}(this);tinymce.PluginManager.add("advlist",function(t){function e(t,e){var n=[];return tinymce.each(e.split(/[ ,]/),function(t){n.push({text:t.replace(/\-/g," ").replace(/\b\w/g,function(t){return t.toUpperCase()}),data:"default"==t?"":t})}),n}function n(e,n){var o,l=t.dom,a=t.selection;o=l.getParent(a.getNode(),"ol,ul"),o&&o.nodeName==e&&n!==!1||t.execCommand("UL"==e?"InsertUnorderedList":"InsertOrderedList"),n=n===!1?i[e]:n,i[e]=n,o=l.getParent(a.getNode(),"ol,ul"),o&&(l.setStyle(o,"listStyleType",n),o.removeAttribute("data-mce-style")),t.focus()}function o(e){var n=t.dom.getStyle(t.dom.getParent(t.selection.getNode(),"ol,ul"),"listStyleType")||"";e.control.items().each(function(t){t.active(t.settings.data===n)})}var l,a,i={};l=e("OL",t.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman")),a=e("UL",t.getParam("advlist_bullet_styles","default,circle,disc,square")),t.addButton("numlist",{type:"splitbutton",tooltip:"Numbered list",menu:l,onshow:o,onselect:function(t){n("OL",t.control.settings.data)},onclick:function(){n("OL",!1)}}),t.addButton("bullist",{type:"splitbutton",tooltip:"Bullet list",menu:a,onshow:o,onselect:function(t){n("UL",t.control.settings.data)},onclick:function(){n("UL",!1)}})});tinymce.PluginManager.add("anchor",function(n){function e(){var e=n.selection.getNode();n.windowManager.open({title:"Anchor",body:{type:"textbox",name:"name",size:40,label:"Name",value:e.name||e.id},onsubmit:function(e){n.execCommand("mceInsertContent",!1,n.dom.createHTML("a",{id:e.data.name}))}})}n.addButton("anchor",{icon:"anchor",tooltip:"Anchor",onclick:e,stateSelector:"a:not([href])"}),n.addMenuItem("anchor",{icon:"anchor",text:"Anchor",context:"insert",onclick:e})});tinymce.PluginManager.add("autolink",function(t){function n(t){o(t,-1,"(",!0)}function e(t){o(t,0,"",!0)}function i(t){o(t,-1,"",!1)}function o(t,n,e){function i(t,n){if(0>n&&(n=0),3==t.nodeType){var e=t.data.length;n>e&&(n=e)}return n}function o(t,n){f.setStart(t,i(t,n))}function r(t,n){f.setEnd(t,i(t,n))}var f,d,a,s,c,l,u,g,h;if(f=t.selection.getRng(!0).cloneRange(),f.startOffset<5){if(g=f.endContainer.previousSibling,!g){if(!f.endContainer.firstChild||!f.endContainer.firstChild.nextSibling)return;g=f.endContainer.firstChild.nextSibling}if(h=g.length,o(g,h),r(g,h),f.endOffset<5)return;d=f.endOffset,s=g}else{if(s=f.endContainer,3!=s.nodeType&&s.firstChild){for(;3!=s.nodeType&&s.firstChild;)s=s.firstChild;3==s.nodeType&&(o(s,0),r(s,s.nodeValue.length))}d=1==f.endOffset?2:f.endOffset-1-n}a=d;do o(s,d>=2?d-2:0),r(s,d>=1?d-1:0),d-=1;while(" "!=f.toString()&&""!==f.toString()&&160!=f.toString().charCodeAt(0)&&d-2>=0&&f.toString()!=e);f.toString()==e||160==f.toString().charCodeAt(0)?(o(s,d),r(s,a),d+=1):0===f.startOffset?(o(s,0),r(s,a)):(o(s,d),r(s,a)),l=f.toString(),"."==l.charAt(l.length-1)&&r(s,a-1),l=f.toString(),u=l.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i),u&&("www."==u[1]?u[1]="http://www.":/@$/.test(u[1])&&!/^mailto:/.test(u[1])&&(u[1]="mailto:"+u[1]),c=t.selection.getBookmark(),t.selection.setRng(f),t.execCommand("createlink",!1,u[1]+u[2]),t.selection.moveToBookmark(c),t.nodeChanged())}var r;return t.on("keydown",function(n){return 13==n.keyCode?i(t):void 0}),tinymce.Env.ie?void t.on("focus",function(){if(!r){r=!0;try{t.execCommand("AutoUrlDetect",!1,!0)}catch(n){}}}):(t.on("keypress",function(e){return 41==e.keyCode?n(t):void 0}),void t.on("keyup",function(n){return 32==n.keyCode?e(t):void 0}))});tinymce.PluginManager.add("autoresize",function(e){function t(){return e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen()}function i(n){var s,r,g,u,l,m,h,d,f=tinymce.DOM;if(r=e.getDoc()){if(g=r.body,u=r.documentElement,l=o.autoresize_min_height,!g||n&&"setcontent"===n.type&&n.initial||t())return void(g&&u&&(g.style.overflowY="auto",u.style.overflowY="auto"));h=e.dom.getStyle(g,"margin-top",!0),d=e.dom.getStyle(g,"margin-bottom",!0),m=g.offsetHeight+parseInt(h,10)+parseInt(d,10),(isNaN(m)||0>=m)&&(m=tinymce.Env.ie?g.scrollHeight:tinymce.Env.webkit&&0===g.clientHeight?0:g.offsetHeight),m>o.autoresize_min_height&&(l=m),o.autoresize_max_height&&m>o.autoresize_max_height?(l=o.autoresize_max_height,g.style.overflowY="auto",u.style.overflowY="auto"):(g.style.overflowY="hidden",u.style.overflowY="hidden",g.scrollTop=0),l!==a&&(s=l-a,f.setStyle(f.get(e.id+"_ifr"),"height",l+"px"),a=l,tinymce.isWebKit&&0>s&&i(n))}}function n(e,t,o){setTimeout(function(){i({}),e--?n(e,t,o):o&&o()},t)}var o=e.settings,a=0;e.settings.inline||(o.autoresize_min_height=parseInt(e.getParam("autoresize_min_height",e.getElement().offsetHeight),10),o.autoresize_max_height=parseInt(e.getParam("autoresize_max_height",0),10),e.on("init",function(){var t=e.getParam("autoresize_overflow_padding",1);e.dom.setStyles(e.getBody(),{paddingBottom:e.getParam("autoresize_bottom_margin",50),paddingLeft:t,paddingRight:t})}),e.on("nodechange setcontent keyup FullscreenStateChanged",i),e.getParam("autoresize_on_init",!0)&&e.on("init",function(){n(20,100,function(){n(5,1e3)})}),e.addCommand("mceAutoResize",i))});tinymce.PluginManager.add("autosave",function(e){function t(e,t){var n={s:1e3,m:6e4};return e=/^(\d+)([ms]?)$/.exec(""+(e||t)),(e[2]?n[e[2]]:1)*parseInt(e,10)}function n(){var e=parseInt(l.getItem(d+"time"),10)||0;return(new Date).getTime()-e>v.autosave_retention?(a(!1),!1):!0}function a(t){l.removeItem(d+"draft"),l.removeItem(d+"time"),t!==!1&&e.fire("RemoveDraft")}function r(){!c()&&e.isDirty()&&(l.setItem(d+"draft",e.getContent({format:"raw",no_events:!0})),l.setItem(d+"time",(new Date).getTime()),e.fire("StoreDraft"))}function o(){n()&&(e.setContent(l.getItem(d+"draft"),{format:"raw"}),e.fire("RestoreDraft"))}function i(){m||(setInterval(function(){e.removed||r()},v.autosave_interval),m=!0)}function s(){var t=this;t.disabled(!n()),e.on("StoreDraft RestoreDraft RemoveDraft",function(){t.disabled(!n())}),i()}function u(){e.undoManager.beforeChange(),o(),a(),e.undoManager.add()}function f(){var e;return tinymce.each(tinymce.editors,function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&t.getParam("autosave_ask_before_unload",!0)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))}),e}function c(t){var n=e.settings.forced_root_block;return t=tinymce.trim("undefined"==typeof t?e.getBody().innerHTML:t),""===t||new RegExp("^<"+n+"[^>]*>(( | |[ ]|]*>)+?|)|
$","i").test(t)}var d,m,v=e.settings,l=tinymce.util.LocalStorage;d=v.autosave_prefix||"tinymce-autosave-{path}{query}-{id}-",d=d.replace(/\{path\}/g,document.location.pathname),d=d.replace(/\{query\}/g,document.location.search),d=d.replace(/\{id\}/g,e.id),v.autosave_interval=t(v.autosave_interval,"30s"),v.autosave_retention=t(v.autosave_retention,"20m"),e.addButton("restoredraft",{title:"Restore last draft",onclick:u,onPostRender:s}),e.addMenuItem("restoredraft",{text:"Restore last draft",onclick:u,onPostRender:s,context:"file"}),e.settings.autosave_restore_when_empty!==!1&&(e.on("init",function(){n()&&c()&&o()}),e.on("saveContent",function(){a()})),window.onbeforeunload=f,this.hasDraft=n,this.storeDraft=r,this.restoreDraft=o,this.removeDraft=a,this.isEmpty=c});!function(){tinymce.create("tinymce.plugins.BBCodePlugin",{init:function(o){var e=this,t=o.getParam("bbcode_dialect","punbb").toLowerCase();o.on("beforeSetContent",function(o){o.content=e["_"+t+"_bbcode2html"](o.content)}),o.on("postProcess",function(o){o.set&&(o.content=e["_"+t+"_bbcode2html"](o.content)),o.get&&(o.content=e["_"+t+"_html2bbcode"](o.content))})},getInfo:function(){return{longname:"BBCode Plugin",author:"Moxiecode Systems AB",authorurl:"http://www.tinymce.com",infourl:"http://www.tinymce.com/wiki.php/Plugin:bbcode"}},_punbb_html2bbcode:function(o){function e(e,t){o=o.replace(e,t)}return o=tinymce.trim(o),e(/(.*?)<\/a>/gi,"[url=$1]$2[/url]"),e(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),e(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),e(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),e(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),e(/(.*?)<\/span>/gi,"[color=$1]$2[/color]"),e(/(.*?)<\/font>/gi,"[color=$1]$2[/color]"),e(/(.*?)<\/span>/gi,"[size=$1]$2[/size]"),e(/(.*?)<\/font>/gi,"$1"),e(//gi,"[img]$1[/img]"),e(/(.*?)<\/span>/gi,"[code]$1[/code]"),e(/(.*?)<\/span>/gi,"[quote]$1[/quote]"),e(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),e(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),e(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),e(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),e(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),e(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),e(/<\/(strong|b)>/gi,"[/b]"),e(/<(strong|b)>/gi,"[b]"),e(/<\/(em|i)>/gi,"[/i]"),e(/<(em|i)>/gi,"[i]"),e(/<\/u>/gi,"[/u]"),e(/(.*?)<\/span>/gi,"[u]$1[/u]"),e(//gi,"[u]"),e(/]*>/gi,"[quote]"),e(/<\/blockquote>/gi,"[/quote]"),e(/
/gi,"\n"),e(//gi,"\n"),e(/
/gi,"\n"),e(/

/gi,""),e(/<\/p>/gi,"\n"),e(/ |\u00a0/gi," "),e(/"/gi,'"'),e(/</gi,"<"),e(/>/gi,">"),e(/&/gi,"&"),o},_punbb_bbcode2html:function(o){function e(e,t){o=o.replace(e,t)}return o=tinymce.trim(o),e(/\n/gi,"
"),e(/\[b\]/gi,""),e(/\[\/b\]/gi,""),e(/\[i\]/gi,""),e(/\[\/i\]/gi,""),e(/\[u\]/gi,""),e(/\[\/u\]/gi,""),e(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'$2'),e(/\[url\](.*?)\[\/url\]/gi,'$1'),e(/\[img\](.*?)\[\/img\]/gi,''),e(/\[color=(.*?)\](.*?)\[\/color\]/gi,'$2'),e(/\[code\](.*?)\[\/code\]/gi,'$1 '),e(/\[quote.*?\](.*?)\[\/quote\]/gi,'$1 '),o}}),tinymce.PluginManager.add("bbcode",tinymce.plugins.BBCodePlugin)}();tinymce.PluginManager.add("charmap",function(e){function a(){function a(e){for(;e;){if("TD"==e.nodeName)return e;e=e.parentNode}}var t,r,o,n;t='';var l=25;for(o=0;10>o;o++){for(t+="",r=0;l>r;r++){var s=i[o*l+r];t+='"}t+=""}t+="";var c={type:"container",html:t,onclick:function(a){var i=a.target;"TD"==i.tagName&&(i=i.firstChild),"DIV"==i.tagName&&(e.execCommand("mceInsertContent",!1,i.firstChild.data),a.ctrlKey||n.close())},onmouseover:function(e){var i=a(e.target);i&&n.find("#preview").text(i.firstChild.firstChild.data)}};n=e.windowManager.open({title:"Special character",spacing:10,padding:10,items:[c,{type:"label",name:"preview",text:" ",style:"font-size: 40px; text-align: center",border:1,minWidth:100,minHeight:80}],buttons:[{text:"Close",onclick:function(){n.close()}}]})}var i=[["160","no-break space"],["38","ampersand"],["34","quotation mark"],["162","cent sign"],["8364","euro sign"],["163","pound sign"],["165","yen sign"],["169","copyright sign"],["174","registered sign"],["8482","trade mark sign"],["8240","per mille sign"],["181","micro sign"],["183","middle dot"],["8226","bullet"],["8230","three dot leader"],["8242","minutes / feet"],["8243","seconds / inches"],["167","section sign"],["182","paragraph sign"],["223","sharp s / ess-zed"],["8249","single left-pointing angle quotation mark"],["8250","single right-pointing angle quotation mark"],["171","left pointing guillemet"],["187","right pointing guillemet"],["8216","left single quotation mark"],["8217","right single quotation mark"],["8220","left double quotation mark"],["8221","right double quotation mark"],["8218","single low-9 quotation mark"],["8222","double low-9 quotation mark"],["60","less-than sign"],["62","greater-than sign"],["8804","less-than or equal to"],["8805","greater-than or equal to"],["8211","en dash"],["8212","em dash"],["175","macron"],["8254","overline"],["164","currency sign"],["166","broken bar"],["168","diaeresis"],["161","inverted exclamation mark"],["191","turned question mark"],["710","circumflex accent"],["732","small tilde"],["176","degree sign"],["8722","minus sign"],["177","plus-minus sign"],["247","division sign"],["8260","fraction slash"],["215","multiplication sign"],["185","superscript one"],["178","superscript two"],["179","superscript three"],["188","fraction one quarter"],["189","fraction one half"],["190","fraction three quarters"],["402","function / florin"],["8747","integral"],["8721","n-ary sumation"],["8734","infinity"],["8730","square root"],["8764","similar to"],["8773","approximately equal to"],["8776","almost equal to"],["8800","not equal to"],["8801","identical to"],["8712","element of"],["8713","not an element of"],["8715","contains as member"],["8719","n-ary product"],["8743","logical and"],["8744","logical or"],["172","not sign"],["8745","intersection"],["8746","union"],["8706","partial differential"],["8704","for all"],["8707","there exists"],["8709","diameter"],["8711","backward difference"],["8727","asterisk operator"],["8733","proportional to"],["8736","angle"],["180","acute accent"],["184","cedilla"],["170","feminine ordinal indicator"],["186","masculine ordinal indicator"],["8224","dagger"],["8225","double dagger"],["192","A - grave"],["193","A - acute"],["194","A - circumflex"],["195","A - tilde"],["196","A - diaeresis"],["197","A - ring above"],["198","ligature AE"],["199","C - cedilla"],["200","E - grave"],["201","E - acute"],["202","E - circumflex"],["203","E - diaeresis"],["204","I - grave"],["205","I - acute"],["206","I - circumflex"],["207","I - diaeresis"],["208","ETH"],["209","N - tilde"],["210","O - grave"],["211","O - acute"],["212","O - circumflex"],["213","O - tilde"],["214","O - diaeresis"],["216","O - slash"],["338","ligature OE"],["352","S - caron"],["217","U - grave"],["218","U - acute"],["219","U - circumflex"],["220","U - diaeresis"],["221","Y - acute"],["376","Y - diaeresis"],["222","THORN"],["224","a - grave"],["225","a - acute"],["226","a - circumflex"],["227","a - tilde"],["228","a - diaeresis"],["229","a - ring above"],["230","ligature ae"],["231","c - cedilla"],["232","e - grave"],["233","e - acute"],["234","e - circumflex"],["235","e - diaeresis"],["236","i - grave"],["237","i - acute"],["238","i - circumflex"],["239","i - diaeresis"],["240","eth"],["241","n - tilde"],["242","o - grave"],["243","o - acute"],["244","o - circumflex"],["245","o - tilde"],["246","o - diaeresis"],["248","o slash"],["339","ligature oe"],["353","s - caron"],["249","u - grave"],["250","u - acute"],["251","u - circumflex"],["252","u - diaeresis"],["253","y - acute"],["254","thorn"],["255","y - diaeresis"],["913","Alpha"],["914","Beta"],["915","Gamma"],["916","Delta"],["917","Epsilon"],["918","Zeta"],["919","Eta"],["920","Theta"],["921","Iota"],["922","Kappa"],["923","Lambda"],["924","Mu"],["925","Nu"],["926","Xi"],["927","Omicron"],["928","Pi"],["929","Rho"],["931","Sigma"],["932","Tau"],["933","Upsilon"],["934","Phi"],["935","Chi"],["936","Psi"],["937","Omega"],["945","alpha"],["946","beta"],["947","gamma"],["948","delta"],["949","epsilon"],["950","zeta"],["951","eta"],["952","theta"],["953","iota"],["954","kappa"],["955","lambda"],["956","mu"],["957","nu"],["958","xi"],["959","omicron"],["960","pi"],["961","rho"],["962","final sigma"],["963","sigma"],["964","tau"],["965","upsilon"],["966","phi"],["967","chi"],["968","psi"],["969","omega"],["8501","alef symbol"],["982","pi symbol"],["8476","real part symbol"],["978","upsilon - hook symbol"],["8472","Weierstrass p"],["8465","imaginary part"],["8592","leftwards arrow"],["8593","upwards arrow"],["8594","rightwards arrow"],["8595","downwards arrow"],["8596","left right arrow"],["8629","carriage return"],["8656","leftwards double arrow"],["8657","upwards double arrow"],["8658","rightwards double arrow"],["8659","downwards double arrow"],["8660","left right double arrow"],["8756","therefore"],["8834","subset of"],["8835","superset of"],["8836","not a subset of"],["8838","subset of or equal to"],["8839","superset of or equal to"],["8853","circled plus"],["8855","circled times"],["8869","perpendicular"],["8901","dot operator"],["8968","left ceiling"],["8969","right ceiling"],["8970","left floor"],["8971","right floor"],["9001","left-pointing angle bracket"],["9002","right-pointing angle bracket"],["9674","lozenge"],["9824","black spade suit"],["9827","black club suit"],["9829","black heart suit"],["9830","black diamond suit"],["8194","en space"],["8195","em space"],["8201","thin space"],["8204","zero width non-joiner"],["8205","zero width joiner"],["8206","left-to-right mark"],["8207","right-to-left mark"],["173","soft hyphen"]];e.addButton("charmap",{icon:"charmap",tooltip:"Special character",onclick:a}),e.addMenuItem("charmap",{icon:"charmap",text:"Special character",onclick:a,context:"insert"})});tinymce.PluginManager.add("code",function(e){function o(){e.windowManager.open({title:"Source code",body:{type:"textbox",name:"code",multiline:!0,minWidth:e.getParam("code_dialog_width",600),minHeight:e.getParam("code_dialog_height",Math.min(tinymce.DOM.getViewPort().h-200,500)),value:e.getContent({source_view:!0}),spellcheck:!1,style:"direction: ltr; text-align: left"},onSubmit:function(o){e.focus(),e.undoManager.transact(function(){e.setContent(o.data.code)}),e.selection.setCursorLocation(),e.nodeChanged()}})}e.addCommand("mceCodeEditor",o),e.addButton("code",{icon:"code",tooltip:"Source code",onclick:o}),e.addMenuItem("code",{icon:"code",text:"Source code",context:"tools",onclick:o})});tinymce.PluginManager.add("contextmenu",function(e){var n,t=e.settings.contextmenu_never_use_native;e.on("contextmenu",function(i){var o;if(!i.ctrlKey||t){if(i.preventDefault(),o=e.settings.contextmenu||"link image inserttable | cell row column deletetable",n)n.show();else{var c=[];tinymce.each(o.split(/[ ,]/),function(n){var t=e.menuItems[n];"|"==n&&(t={text:n}),t&&(t.shortcut="",c.push(t))});for(var a=0;a'}),t+=""}),t+=""}var i=[["cool","cry","embarassed","foot-in-mouth"],["frown","innocent","kiss","laughing"],["money-mouth","sealed","smile","surprised"],["tongue-out","undecided","wink","yell"]];t.addButton("emoticons",{type:"panelbutton",panel:{role:"application",autohide:!0,html:a,onclick:function(e){var a=t.dom.getParent(e.target,"a");a&&(t.insertContent(''+a.getAttribute('),this.hide())}},tooltip:"Emoticons"})});tinymce.PluginManager.add("fullpage",function(e){function t(){var t=n();e.windowManager.open({title:"Document properties",data:t,defaults:{type:"textbox",size:40},body:[{name:"title",label:"Title"},{name:"keywords",label:"Keywords"},{name:"description",label:"Description"},{name:"robots",label:"Robots"},{name:"author",label:"Author"},{name:"docencoding",label:"Encoding"}],onSubmit:function(e){l(tinymce.extend(t,e.data))}})}function n(){function t(e,t){var n=e.attr(t);return n||""}var n,l,a=i(),r={};return r.fontface=e.getParam("fullpage_default_fontface",""),r.fontsize=e.getParam("fullpage_default_fontsize",""),n=a.firstChild,7==n.type&&(r.xml_pi=!0,l=/encoding="([^"]+)"/.exec(n.value),l&&(r.docencoding=l[1])),n=a.getAll("#doctype")[0],n&&(r.doctype=""),n=a.getAll("title")[0],n&&n.firstChild&&(r.title=n.firstChild.value),s(a.getAll("meta"),function(e){var t,n=e.attr("name"),l=e.attr("http-equiv");n?r[n.toLowerCase()]=e.attr("content"):"Content-Type"==l&&(t=/charset\s*=\s*(.*)\s*/gi.exec(e.attr("content")),t&&(r.docencoding=t[1]))}),n=a.getAll("html")[0],n&&(r.langcode=t(n,"lang")||t(n,"xml:lang")),r.stylesheets=[],tinymce.each(a.getAll("link"),function(e){"stylesheet"==e.attr("rel")&&r.stylesheets.push(e.attr("href"))}),n=a.getAll("body")[0],n&&(r.langdir=t(n,"dir"),r.style=t(n,"style"),r.visited_color=t(n,"vlink"),r.link_color=t(n,"link"),r.active_color=t(n,"alink")),r}function l(t){function n(e,t,n){e.attr(t,n?n:void 0)}function l(e){r.firstChild?r.insert(e,r.firstChild):r.append(e)}var a,r,o,c,u,f=e.dom;a=i(),r=a.getAll("head")[0],r||(c=a.getAll("html")[0],r=new m("head",1),c.firstChild?c.insert(r,c.firstChild,!0):c.append(r)),c=a.firstChild,t.xml_pi?(u='version="1.0"',t.docencoding&&(u+=' encoding="'+t.docencoding+'"'),7!=c.type&&(c=new m("xml",7),a.insert(c,a.firstChild,!0)),c.value=u):c&&7==c.type&&c.remove(),c=a.getAll("#doctype")[0],t.doctype?(c||(c=new m("#doctype",10),t.xml_pi?a.insert(c,a.firstChild):l(c)),c.value=t.doctype.substring(9,t.doctype.length-1)):c&&c.remove(),c=null,s(a.getAll("meta"),function(e){"Content-Type"==e.attr("http-equiv")&&(c=e)}),t.docencoding?(c||(c=new m("meta",1),c.attr("http-equiv","Content-Type"),c.shortEnded=!0,l(c)),c.attr("content","text/html; charset="+t.docencoding)):c.remove(),c=a.getAll("title")[0],t.title?(c?c.empty():(c=new m("title",1),l(c)),c.append(new m("#text",3)).value=t.title):c&&c.remove(),s("keywords,description,author,copyright,robots".split(","),function(e){var n,i,r=a.getAll("meta"),o=t[e];for(n=0;n"))}function i(){return new tinymce.html.DomParser({validate:!1,root_name:"#document"}).parse(d)}function a(t){function n(e){return e.replace(/<\/?[A-Z]+/g,function(e){return e.toLowerCase()})}var l,a,o,m,u=t.content,f="",g=e.dom;if(!t.selection&&!("raw"==t.format&&d||t.source_view&&e.getParam("fullpage_hide_in_source_view"))){u=u.replace(/<(\/?)BODY/gi,"<$1body"),l=u.indexOf("",l),d=n(u.substring(0,l+1)),a=u.indexOf("\n"),o=i(),s(o.getAll("style"),function(e){e.firstChild&&(f+=e.firstChild.value)}),m=o.getAll("body")[0],m&&g.setAttribs(e.getBody(),{style:m.attr("style")||"",dir:m.attr("dir")||"",vLink:m.attr("vlink")||"",link:m.attr("link")||"",aLink:m.attr("alink")||""}),g.remove("fullpage_styles");var y=e.getDoc().getElementsByTagName("head")[0];f&&(g.add(y,"style",{id:"fullpage_styles"},f),m=g.get("fullpage_styles"),m.styleSheet&&(m.styleSheet.cssText=f));var h={};tinymce.each(y.getElementsByTagName("link"),function(e){"stylesheet"==e.rel&&e.getAttribute("data-mce-fullpage")&&(h[e.href]=e)}),tinymce.each(o.getAll("link"),function(e){var t=e.attr("href");h[t]||"stylesheet"!=e.attr("rel")||g.add(y,"link",{rel:"stylesheet",text:"text/css",href:t,"data-mce-fullpage":"1"}),delete h[t]}),tinymce.each(h,function(e){e.parentNode.removeChild(e)})}}function r(){var t,n="",l="";return e.getParam("fullpage_default_xml_pi")&&(n+='\n'),n+=e.getParam("fullpage_default_doctype",""),n+="\n\n\n",(t=e.getParam("fullpage_default_title"))&&(n+=""+t+"\n"),(t=e.getParam("fullpage_default_encoding"))&&(n+='\n'),(t=e.getParam("fullpage_default_font_family"))&&(l+="font-family: "+t+";"),(t=e.getParam("fullpage_default_font_size"))&&(l+="font-size: "+t+";"),(t=e.getParam("fullpage_default_text_color"))&&(l+="color: "+t+";"),n+="\n\n"}function o(t){t.selection||t.source_view&&e.getParam("fullpage_hide_in_source_view")||(t.content=tinymce.trim(d)+"\n"+tinymce.trim(t.content)+"\n"+tinymce.trim(c))}var d,c,s=tinymce.each,m=tinymce.html.Node;e.addCommand("mceFullPageProperties",t),e.addButton("fullpage",{title:"Document properties",cmd:"mceFullPageProperties"}),e.addMenuItem("fullpage",{text:"Document properties",cmd:"mceFullPageProperties",context:"file"}),e.on("BeforeSetContent",a),e.on("GetContent",o)});tinymce.PluginManager.add("fullscreen",function(e){function t(){var e,t,n=window,i=document,l=i.body;return l.offsetWidth&&(e=l.offsetWidth,t=l.offsetHeight),n.innerWidth&&n.innerHeight&&(e=n.innerWidth,t=n.innerHeight),{w:e,h:t}}function n(){function n(){d.setStyle(a,"height",t().h-(h.clientHeight-a.clientHeight))}var u,h,a,f,m=document.body,g=document.documentElement;s=!s,h=e.getContainer(),u=h.style,a=e.getContentAreaContainer().firstChild,f=a.style,s?(i=f.width,l=f.height,f.width=f.height="100%",c=u.width,o=u.height,u.width=u.height="",d.addClass(m,"mce-fullscreen"),d.addClass(g,"mce-fullscreen"),d.addClass(h,"mce-fullscreen"),d.bind(window,"resize",n),n(),r=n):(f.width=i,f.height=l,c&&(u.width=c),o&&(u.height=o),d.removeClass(m,"mce-fullscreen"),d.removeClass(g,"mce-fullscreen"),d.removeClass(h,"mce-fullscreen"),d.unbind(window,"resize",r)),e.fire("FullscreenStateChanged",{state:s})}var i,l,r,c,o,s=!1,d=tinymce.DOM;return e.settings.inline?void 0:(e.on("init",function(){e.addShortcut("Ctrl+Alt+F","",n)}),e.on("remove",function(){r&&d.unbind(window,"resize",r)}),e.addCommand("mceFullScreen",n),e.addMenuItem("fullscreen",{text:"Fullscreen",shortcut:"Ctrl+Alt+F",selectable:!0,onClick:n,onPostRender:function(){var t=this;e.on("FullscreenStateChanged",function(e){t.active(e.state)})},context:"view"}),e.addButton("fullscreen",{tooltip:"Fullscreen",shortcut:"Ctrl+Alt+F",onClick:n,onPostRender:function(){var t=this;e.on("FullscreenStateChanged",function(e){t.active(e.state)})}}),{isFullscreen:function(){return s}})});tinymce.PluginManager.add("hr",function(n){n.addCommand("InsertHorizontalRule",function(){n.execCommand("mceInsertContent",!1,"


")}),n.addButton("hr",{icon:"hr",tooltip:"Horizontal line",cmd:"InsertHorizontalRule"}),n.addMenuItem("hr",{icon:"hr",text:"Horizontal line",cmd:"InsertHorizontalRule",context:"insert"})});tinymce.PluginManager.add("image",function(e){function t(e,t){function i(e,i){n.parentNode&&n.parentNode.removeChild(n),t({width:e,height:i})}var n=document.createElement("img");n.onload=function(){i(n.clientWidth,n.clientHeight)},n.onerror=function(){i()};var a=n.style;a.visibility="hidden",a.position="fixed",a.bottom=a.left=0,a.width=a.height="auto",document.body.appendChild(n),n.src=e}function i(t){return tinymce.each(t,function(t){t.textStyle=function(){return e.formatter.getCssText({inline:"img",classes:[t.value]})}}),t}function n(t){return function(){var i=e.settings.image_list;"string"==typeof i?tinymce.util.XHR.send({url:i,success:function(e){t(tinymce.util.JSON.parse(e))}}):"function"==typeof i?i(t):t(i)}}function a(n){function a(t,i,n){var a,l=[];return tinymce.each(e.settings[t]||n,function(e){var t={text:e.text||e.title,value:e.value};l.push(t),(f[i]===e.value||!a&&e.selected)&&(a=t)}),a&&!f[i]&&(f[i]=a.value,a.selected=!0),l}function l(){var t=[{text:"None",value:""}];return tinymce.each(n,function(i){t.push({text:i.text||i.title,value:e.convertURL(i.value||i.url,"src"),menu:i.menu})}),t}function o(){var e,t,i,n;e=u.find("#width")[0],t=u.find("#height")[0],i=e.value(),n=t.value(),u.find("#constrain")[0].checked()&&g&&h&&i&&n&&(g!=i?(n=Math.round(i/g*n),t.value(n)):(i=Math.round(n/h*i),e.value(i))),g=i,h=n}function s(){function t(t){function i(){t.onload=t.onerror=null,e.selection.select(t),e.nodeChanged()}t.onload=function(){f.width||f.height||y.setAttribs(t,{width:t.clientWidth,height:t.clientHeight}),i()},t.onerror=i}d(),o(),f=tinymce.extend(f,u.toJSON()),f.alt||(f.alt=""),""===f.width&&(f.width=null),""===f.height&&(f.height=null),f.style||(f.style=null),f={src:f.src,alt:f.alt,width:f.width,height:f.height,style:f.style,"class":f["class"]},f["class"]||delete f["class"],e.undoManager.transact(function(){return f.src?(v?y.setAttribs(v,f):(f.id="__mcenew",e.focus(),e.selection.setContent(y.createHTML("img",f)),v=y.get("__mcenew"),y.setAttrib(v,"id",null)),void t(v)):void(v&&(y.remove(v),e.focus(),e.nodeChanged()))})}function r(e){return e&&(e=e.replace(/px$/,"")),e}function c(){m&&m.value(e.convertURL(this.value(),"src")),t(this.value(),function(e){e.width&&e.height&&(g=e.width,h=e.height,u.find("#width").value(g),u.find("#height").value(h))})}function d(){function t(e){return e.length>0&&/^[0-9]+$/.test(e)&&(e+="px"),e}if(e.settings.image_advtab){var i=u.toJSON(),n=y.parseStyle(i.style);delete n.margin,n["margin-top"]=n["margin-bottom"]=t(i.vspace),n["margin-left"]=n["margin-right"]=t(i.hspace),n["border-width"]=t(i.border),u.find("#style").value(y.serializeStyle(y.parseStyle(y.serializeStyle(n))))}}var u,g,h,m,p,f={},y=e.dom,v=e.selection.getNode();g=y.getAttrib(v,"width"),h=y.getAttrib(v,"height"),"IMG"!=v.nodeName||v.getAttribute("data-mce-object")||v.getAttribute("data-mce-placeholder")?v=null:f={src:y.getAttrib(v,"src"),alt:y.getAttrib(v,"alt"),"class":y.getAttrib(v,"class"),width:g,height:h},n&&(m={type:"listbox",label:"Image list",values:l(),value:f.src&&e.convertURL(f.src,"src"),onselect:function(e){var t=u.find("#alt");(!t.value()||e.lastControl&&t.value()==e.lastControl.text())&&t.value(e.control.text()),u.find("#src").value(e.control.value())},onPostRender:function(){m=this}}),e.settings.image_class_list&&(p={name:"class",type:"listbox",label:"Class",values:i(a("image_class_list","class"))});var b=[{name:"src",type:"filepicker",filetype:"image",label:"Source",autofocus:!0,onchange:c},m];e.settings.image_description!==!1&&b.push({name:"alt",type:"textbox",label:"Image description"}),e.settings.image_dimensions!==!1&&b.push({type:"container",label:"Dimensions",layout:"flex",direction:"row",align:"center",spacing:5,items:[{name:"width",type:"textbox",maxLength:5,size:3,onchange:o,ariaLabel:"Width"},{type:"label",text:"x"},{name:"height",type:"textbox",maxLength:5,size:3,onchange:o,ariaLabel:"Height"},{name:"constrain",type:"checkbox",checked:!0,text:"Constrain proportions"}]}),b.push(p),e.settings.image_advtab?(v&&(f.hspace=r(v.style.marginLeft||v.style.marginRight),f.vspace=r(v.style.marginTop||v.style.marginBottom),f.border=r(v.style.borderWidth),f.style=e.dom.serializeStyle(e.dom.parseStyle(e.dom.getAttrib(v,"style")))),u=e.windowManager.open({title:"Insert/edit image",data:f,bodyType:"tabpanel",body:[{title:"General",type:"form",items:b},{title:"Advanced",type:"form",pack:"start",items:[{label:"Style",name:"style",type:"textbox"},{type:"form",layout:"grid",packV:"start",columns:2,padding:0,alignH:["left","right"],defaults:{type:"textbox",maxWidth:50,onchange:d},items:[{label:"Vertical space",name:"vspace"},{label:"Horizontal space",name:"hspace"},{label:"Border",name:"border"}]}]}],onSubmit:s})):u=e.windowManager.open({title:"Insert/edit image",data:f,body:b,onSubmit:s})}e.addButton("image",{icon:"image",tooltip:"Insert/edit image",onclick:n(a),stateSelector:"img:not([data-mce-object],[data-mce-placeholder])"}),e.addMenuItem("image",{icon:"image",text:"Insert image",onclick:n(a),context:"insert",prependToContext:!0})});tinymce.PluginManager.add("importcss",function(t){function e(t){return"string"==typeof t?function(e){return-1!==e.indexOf(t)}:t instanceof RegExp?function(e){return t.test(e)}:t}function n(e,n){function i(t,e){var c,o=t.href;if(o&&n(o,e)){s(t.imports,function(t){i(t,!0)});try{c=t.cssRules||t.rules}catch(a){}s(c,function(t){t.styleSheet?i(t.styleSheet,!0):t.selectorText&&s(t.selectorText.split(","),function(t){r.push(tinymce.trim(t))})})}}var r=[],c={};s(t.contentCSS,function(t){c[t]=!0}),n||(n=function(t,e){return e||c[t]});try{s(e.styleSheets,function(t){i(t)})}catch(o){}return r}function i(e){var n,i=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(e);if(i){var r=i[1],s=i[2].substr(1).split(".").join(" "),c=tinymce.makeMap("a,img");return i[1]?(n={title:e},t.schema.getTextBlockElements()[r]?n.block=r:t.schema.getBlockElements()[r]||c[r.toLowerCase()]?n.selector=r:n.inline=r):i[2]&&(n={inline:"span",title:e.substr(1),classes:s}),t.settings.importcss_merge_classes!==!1?n.classes=s:n.attributes={"class":s},n}}var r=this,s=tinymce.each;t.on("renderFormatsMenu",function(c){var o=t.settings,a={},l=o.importcss_selector_converter||i,f=e(o.importcss_selector_filter),m=c.control;t.settings.importcss_append||m.items().remove();var u=[];tinymce.each(o.importcss_groups,function(t){t=tinymce.extend({},t),t.filter=e(t.filter),u.push(t)}),s(n(c.doc||t.getDoc(),e(o.importcss_file_filter)),function(e){if(-1===e.indexOf(".mce-")&&!a[e]&&(!f||f(e))){var n,i=l.call(r,e);if(i){var s=i.name||tinymce.DOM.uniqueId();if(u)for(var c=0;c'+n+"";var i=e.dom.getParent(e.selection.getStart(),"time");if(i)return void e.dom.setOuterHTML(i,n)}e.insertContent(n)}var n,r,i="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),d="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),c="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),u=[];e.addCommand("mceInsertDate",function(){a(e.getParam("insertdatetime_dateformat",e.translate("%Y-%m-%d")))}),e.addCommand("mceInsertTime",function(){a(e.getParam("insertdatetime_timeformat",e.translate("%H:%M:%S")))}),e.addButton("insertdatetime",{type:"splitbutton",title:"Insert date/time",onclick:function(){a(n||r)},menu:u}),tinymce.each(e.settings.insertdatetime_formats||["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"],function(e){r||(r=e),u.push({text:t(e),onclick:function(){n=e,a(e)}})}),e.addMenuItem("insertdatetime",{icon:"date",text:"Insert date/time",menu:u,context:"insert"})});!function(e){e.on("AddEditor",function(e){e.editor.settings.inline_styles=!1}),e.PluginManager.add("legacyoutput",function(t){t.on("init",function(){var i="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",n=e.explode(t.settings.font_size_style_values),l=t.schema;t.formatter.register({alignleft:{selector:i,attributes:{align:"left"}},aligncenter:{selector:i,attributes:{align:"center"}},alignright:{selector:i,attributes:{align:"right"}},alignjustify:{selector:i,attributes:{align:"justify"}},bold:[{inline:"b",remove:"all"},{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}}],italic:[{inline:"i",remove:"all"},{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}}],underline:[{inline:"u",remove:"all"},{inline:"span",styles:{textDecoration:"underline"},exact:!0}],strikethrough:[{inline:"strike",remove:"all"},{inline:"span",styles:{textDecoration:"line-through"},exact:!0}],fontname:{inline:"font",attributes:{face:"%value"}},fontsize:{inline:"font",attributes:{size:function(t){return e.inArray(n,t.value)+1}}},forecolor:{inline:"font",attributes:{color:"%value"}},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"}}}),e.each("b,i,u,strike".split(","),function(e){l.addValidElements(e+"[*]")}),l.getElementRule("font")||l.addValidElements("font[face|size|color|style]"),e.each(i.split(","),function(e){var t=l.getElementRule(e);t&&(t.attributes.align||(t.attributes.align={},t.attributesOrder.push("align")))})})})}(tinymce);tinymce.PluginManager.add("link",function(t){function e(e){return function(){var n=t.settings.link_list;"string"==typeof n?tinymce.util.XHR.send({url:n,success:function(t){e(tinymce.util.JSON.parse(t))}}):"function"==typeof n?n(e):e(n)}}function n(e){function n(t){var e=d.find("#text");(!e.value()||t.lastControl&&e.value()==t.lastControl.text())&&e.value(t.control.text()),d.find("#href").value(t.control.value())}function l(){var n=[{text:"None",value:""}];return tinymce.each(e,function(e){n.push({text:e.text||e.title,value:t.convertURL(e.value||e.url,"href"),menu:e.menu})}),n}function i(e){return tinymce.each(e,function(e){e.textStyle=function(){return t.formatter.getCssText({inline:"a",classes:[e.value]})}}),e}function a(e,n,l){var i,a=[];return tinymce.each(t.settings[e]||l,function(t){var e={text:t.text||t.title,value:t.value};a.push(e),(b[n]===t.value||!i&&t.selected)&&(i=e)}),i&&!b[n]&&(b[n]=i.value,i.selected=!0),a}function r(e){var l=[];return tinymce.each(t.dom.select("a:not([href])"),function(t){var n=t.name||t.id;n&&l.push({text:n,value:"#"+n,selected:-1!=e.indexOf("#"+n)})}),l.length?(l.unshift({text:"None",value:""}),{name:"anchor",type:"listbox",label:"Anchors",values:l,onselect:n}):void 0}function o(){h&&h.value(t.convertURL(this.value(),"href")),!f&&0===b.text.length&&x&&this.parent().parent().find("#text")[0].value(this.value())}function s(t){var e=k.getContent();if(/]+>[^<]+<\/a>$/.test(e)||-1==e.indexOf("href=")))return!1;if(t){var n,l=t.childNodes;if(0===l.length)return!1;for(n=l.length-1;n>=0;n--)if(3!=l[n].nodeType)return!1}return!0}var u,c,f,d,x,v,h,g,m,p,y,b={},k=t.selection,w=t.dom;u=k.getNode(),c=w.getParent(u,"a[href]"),x=s(),b.text=f=c?c.innerText||c.textContent:k.getContent({format:"text"}),b.href=c?w.getAttrib(c,"href"):"",b.target=c?w.getAttrib(c,"target"):t.settings.default_link_target||null,b.rel=c?w.getAttrib(c,"rel"):null,b["class"]=c?w.getAttrib(c,"class"):null,b.title=c?w.getAttrib(c,"title"):"",x&&(v={name:"text",type:"textbox",size:40,label:"Text to display",onchange:function(){b.text=this.value()}}),e&&(h={type:"listbox",label:"Link list",values:l(),onselect:n,value:t.convertURL(b.href,"href"),onPostRender:function(){h=this}}),t.settings.target_list!==!1&&(m={name:"target",type:"listbox",label:"Target",values:a("target_list","target",[{text:"None",value:""},{text:"New window",value:"_blank"}])}),t.settings.rel_list&&(g={name:"rel",type:"listbox",label:"Rel",values:a("rel_list","rel",[{text:"None",value:""}])}),t.settings.link_class_list&&(p={name:"class",type:"listbox",label:"Class",values:i(a("link_class_list","class"))}),t.settings.link_title!==!1&&(y={name:"title",type:"textbox",label:"Title",value:b.title}),d=t.windowManager.open({title:"Insert link",data:b,body:[{name:"href",type:"filepicker",filetype:"file",size:40,autofocus:!0,label:"Url",onchange:o,onkeyup:o},v,y,r(b.href),h,g,m,p],onSubmit:function(e){function n(e,n){var l=t.selection.getRng();window.setTimeout(function(){t.windowManager.confirm(e,function(e){t.selection.setRng(l),n(e)})},0)}function l(){var e={href:i,target:b.target?b.target:null,rel:b.rel?b.rel:null,"class":b["class"]?b["class"]:null,title:b.title?b.title:null};c?(t.focus(),x&&b.text!=f&&("innerText"in c?c.innerText=b.text:c.textContent=b.text),w.setAttribs(c,e),k.select(c),t.undoManager.add()):x?t.insertContent(w.createHTML("a",e,w.encode(b.text))):t.execCommand("mceInsertLink",!1,e)}var i;return b=tinymce.extend(b,e.data),(i=b.href)?i.indexOf("@")>0&&-1==i.indexOf("//")&&-1==i.indexOf("mailto:")?void n("The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",function(t){t&&(i="mailto:"+i),l()}):/^\s*www\./i.test(i)?void n("The URL you entered seems to be an external link. Do you want to add the required http:// prefix?",function(t){t&&(i="http://"+i),l()}):void l():void t.execCommand("unlink")}})}t.addButton("link",{icon:"link",tooltip:"Insert/edit link",shortcut:"Ctrl+K",onclick:e(n),stateSelector:"a[href]"}),t.addButton("unlink",{icon:"unlink",tooltip:"Remove link",cmd:"unlink",stateSelector:"a[href]"}),t.addShortcut("Ctrl+K","",e(n)),this.showDialog=n,t.addMenuItem("link",{icon:"link",text:"Insert link",shortcut:"Ctrl+K",onclick:e(n),stateSelector:"a[href]",context:"insert",prependToContext:!0})});tinymce.PluginManager.add("lists",function(e){function t(e){return e&&/^(OL|UL)$/.test(e.nodeName)}function n(e){return e.parentNode.firstChild==e}function r(e){return e.parentNode.lastChild==e}function o(t){return t&&!!e.schema.getTextBlockElements()[t.nodeName]}function i(e){return e&&"SPAN"===e.nodeName&&"bookmark"===e.getAttribute("data-mce-type")}var a=this;e.on("init",function(){function d(e){function t(t){var r,o,i;o=e[t?"startContainer":"endContainer"],i=e[t?"startOffset":"endOffset"],1==o.nodeType&&(r=b.create("span",{"data-mce-type":"bookmark"}),o.hasChildNodes()?(i=Math.min(i,o.childNodes.length-1),t?o.insertBefore(r,o.childNodes[i]):b.insertAfter(r,o.childNodes[i])):o.appendChild(r),o=r,i=0),n[t?"startContainer":"endContainer"]=o,n[t?"startOffset":"endOffset"]=i}var n={};return t(!0),e.collapsed||t(),n}function s(e){function t(t){function n(e){for(var t=e.parentNode.firstChild,n=0;t;){if(t==e)return n;(1!=t.nodeType||"bookmark"!=t.getAttribute("data-mce-type"))&&n++,t=t.nextSibling}return-1}var r,o,i;r=i=e[t?"startContainer":"endContainer"],o=e[t?"startOffset":"endOffset"],r&&(1==r.nodeType&&(o=n(r),r=r.parentNode,b.remove(i)),e[t?"startContainer":"endContainer"]=r,e[t?"startOffset":"endOffset"]=o)}t(!0),t();var n=b.createRng();n.setStart(e.startContainer,e.startOffset),e.endContainer&&n.setEnd(e.endContainer,e.endOffset),k.setRng(n)}function f(t,n){var r,o,i,a=b.createFragment(),d=e.schema.getBlockElements();if(e.settings.forced_root_block&&(n=n||e.settings.forced_root_block),n&&(o=b.create(n),o.tagName===e.settings.forced_root_block&&b.setAttribs(o,e.settings.forced_root_block_attrs),a.appendChild(o)),t)for(;r=t.firstChild;){var s=r.nodeName;i||"SPAN"==s&&"bookmark"==r.getAttribute("data-mce-type")||(i=!0),d[s]?(a.appendChild(r),o=null):n?(o||(o=b.create(n),a.appendChild(o)),o.appendChild(r)):a.appendChild(r)}return e.settings.forced_root_block?i||tinymce.Env.ie&&!(tinymce.Env.ie>10)||o.appendChild(b.create("br",{"data-mce-bogus":"1"})):a.appendChild(b.create("br")),a}function l(){return tinymce.grep(k.getSelectedBlocks(),function(e){return"LI"==e.nodeName})}function c(e,t,n){var r,o,i=b.select('span[data-mce-type="bookmark"]',e);n=n||f(t),r=b.createRng(),r.setStartAfter(t),r.setEndAfter(e),o=r.extractContents(),b.isEmpty(o)||b.insertAfter(o,e),b.insertAfter(n,e),b.isEmpty(t.parentNode)&&(tinymce.each(i,function(e){t.parentNode.parentNode.insertBefore(e,t.parentNode)}),b.remove(t.parentNode)),b.remove(t)}function p(e){var n,r;if(n=e.nextSibling,n&&t(n)&&n.nodeName==e.nodeName){for(;r=n.firstChild;)e.appendChild(r);b.remove(n)}if(n=e.previousSibling,n&&t(n)&&n.nodeName==e.nodeName){for(;r=n.firstChild;)e.insertBefore(r,e.firstChild);b.remove(n)}}function u(e){tinymce.each(tinymce.grep(b.select("ol,ul",e)),function(e){var n,r=e.parentNode;"LI"==r.nodeName&&r.firstChild==e&&(n=r.previousSibling,n&&"LI"==n.nodeName&&(n.appendChild(e),b.isEmpty(r)&&b.remove(r))),t(r)&&(n=r.previousSibling,n&&"LI"==n.nodeName&&n.appendChild(e))})}function m(e){function o(e){b.isEmpty(e)&&b.remove(e)}var i,a=e.parentNode,d=a.parentNode;return n(e)&&r(e)?("LI"==d.nodeName?(b.insertAfter(e,d),o(d),b.remove(a)):t(d)?b.remove(a,!0):(d.insertBefore(f(e),a),b.remove(a)),!0):n(e)?("LI"==d.nodeName?(b.insertAfter(e,d),e.appendChild(a),o(d)):t(d)?d.insertBefore(e,a):(d.insertBefore(f(e),a),b.remove(e)),!0):r(e)?("LI"==d.nodeName?b.insertAfter(e,d):t(d)?b.insertAfter(e,a):(b.insertAfter(f(e),a),b.remove(e)),!0):("LI"==d.nodeName?(a=d,i=f(e,"LI")):i=t(d)?f(e,"LI"):f(e),c(a,e,i),u(a.parentNode),!0)}function h(e){function n(n,r){var o;if(t(n)){for(;o=e.lastChild.firstChild;)r.appendChild(o);b.remove(n)}}var r,o;return r=e.previousSibling,r&&t(r)?(r.appendChild(e),!0):r&&"LI"==r.nodeName&&t(r.lastChild)?(r.lastChild.appendChild(e),n(e.lastChild,r.lastChild),!0):(r=e.nextSibling,r&&t(r)?(r.insertBefore(e,r.firstChild),!0):r&&"LI"==r.nodeName&&t(e.lastChild)?!1:(r=e.previousSibling,r&&"LI"==r.nodeName?(o=b.create(e.parentNode.nodeName),r.appendChild(o),o.appendChild(e),n(e.lastChild,o),!0):!1))}function v(){var t=l();if(t.length){for(var n=d(k.getRng(!0)),r=0;r0))return n;for(var o=new tinymce.dom.TreeWalker(e.startContainer);n=o[t?"next":"prev"]();)if(3==n.nodeType&&n.data.length>0)return n}function r(e,n){var r,o,i=e.parentNode;for(t(n.lastChild)&&(o=n.lastChild),r=n.lastChild,r&&"BR"==r.nodeName&&e.hasChildNodes()&&b.remove(r);r=e.firstChild;)n.appendChild(r);o&&n.appendChild(o),b.remove(e),b.isEmpty(i)&&b.remove(i)}if(k.isCollapsed()){var o=b.getParent(k.getStart(),"LI");if(o){var i=k.getRng(!0),a=b.getParent(n(i,e),"LI");if(a&&a!=o){var f=d(i);return e?r(a,o):r(o,a),s(f),!0}if(!a&&!e&&N(o.parentNode.nodeName))return!0}}},e.addCommand("Indent",function(){return v()?void 0:!0}),e.addCommand("Outdent",function(){return C()?void 0:!0}),e.addCommand("InsertUnorderedList",function(){y("UL")}),e.addCommand("InsertOrderedList",function(){y("OL")}),e.on("keydown",function(t){9==t.keyCode&&e.dom.getParent(e.selection.getStart(),"LI")&&(t.preventDefault(),t.shiftKey?C():v())})}),e.addButton("indent",{icon:"indent",title:"Increase indent",cmd:"Indent",onPostRender:function(){var t=this;e.on("nodechange",function(){for(var r=e.selection.getSelectedBlocks(),o=!1,i=0,a=r.length;!o&&a>i;i++){var d=r[i].nodeName;o="LI"==d&&n(r[i])||"UL"==d||"OL"==d}t.disabled(o)})}}),e.on("keydown",function(e){e.keyCode==tinymce.util.VK.BACKSPACE?a.backspaceDelete()&&e.preventDefault():e.keyCode==tinymce.util.VK.DELETE&&a.backspaceDelete(!0)&&e.preventDefault()})});tinymce.PluginManager.add("media",function(e,t){function i(e){return-1!=e.indexOf(".mp3")?"audio/mpeg":-1!=e.indexOf(".wav")?"audio/wav":-1!=e.indexOf(".mp4")?"video/mp4":-1!=e.indexOf(".webm")?"video/webm":-1!=e.indexOf(".ogg")?"video/ogg":-1!=e.indexOf(".swf")?"application/x-shockwave-flash":""}function r(t){var i=e.settings.media_scripts;if(i)for(var r=0;r':"application/x-shockwave-flash"==o.source1mime?(a+='',o.poster&&(a+=''),a+=""):-1!=o.source1mime.indexOf("audio")?e.settings.audio_template_callback?a=e.settings.audio_template_callback(o):a+='":"script"==o.type?a+='':a=e.settings.video_template_callback?e.settings.video_template_callback(o):'"}return a}function s(e){var t={};return new tinymce.html.SaxParser({validate:!1,allow_conditional_comments:!0,special:"script,noscript",start:function(e,i){if(t.source1||"param"!=e||(t.source1=i.map.movie),("iframe"==e||"object"==e||"embed"==e||"video"==e||"audio"==e)&&(t.type||(t.type=e),t=tinymce.extend(i.map,t)),"script"==e){var o=r(i.map.src);if(!o)return;t={type:"script",source1:i.map.src,width:o.width,height:o.height}}"source"==e&&(t.source1?t.source2||(t.source2=i.map.src):t.source1=i.map.src),"img"!=e||t.poster||(t.poster=i.map.src)}}).parse(e),t.source1=t.source1||t.src||t.data,t.source2=t.source2||"",t.poster=t.poster||"",t}function n(t){return t.getAttribute("data-mce-object")?s(e.serializer.serialize(t,{selection:!0})):{}}function m(e,t,i){function r(e,t){var i,r,o,a;for(i in t)if(o=""+t[i],e.map[i])for(r=e.length;r--;)a=e[r],a.name==i&&(o?(e.map[i]=o,a.value=o):(delete e.map[i],e.splice(r,1)));else o&&(e.push({name:i,value:o}),e.map[i]=o)}var o,a=new tinymce.html.Writer,c=0;return new tinymce.html.SaxParser({validate:!1,allow_conditional_comments:!0,special:"script,noscript",comment:function(e){a.comment(e)},cdata:function(e){a.cdata(e)},text:function(e,t){a.text(e,t)},start:function(e,s,n){switch(e){case"video":case"object":case"embed":case"img":case"iframe":r(s,{width:t.width,height:t.height})}if(i)switch(e){case"video":r(s,{poster:t.poster,src:""}),t.source2&&r(s,{src:""});break;case"iframe":r(s,{src:t.source1});break;case"source":if(c++,2>=c&&(r(s,{src:t["source"+c],type:t["source"+c+"mime"]}),!t["source"+c]))return;break;case"img":if(!t.poster)return;o=!0}a.start(e,s,n)},end:function(e){if("video"==e&&i)for(var s=1;2>=s;s++)if(t["source"+s]){var n=[];n.map={},s>c&&(r(n,{src:t["source"+s],type:t["source"+s+"mime"]}),a.start("source",n,!0))}if(t.poster&&"object"==e&&i&&!o){var m=[];m.map={},r(m,{src:t.poster,width:t.width,height:t.height}),a.start("img",m,!0)}a.end(e)}},new tinymce.html.Schema({})).parse(e),a.getContent()}var u=[{regex:/youtu\.be\/([\w\-.]+)/,type:"iframe",w:425,h:350,url:"//www.youtube.com/embed/$1"},{regex:/youtube\.com(.+)v=([^&]+)/,type:"iframe",w:425,h:350,url:"//www.youtube.com/embed/$2"},{regex:/vimeo\.com\/([0-9]+)/,type:"iframe",w:425,h:350,url:"//player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc"},{regex:/maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/,type:"iframe",w:425,h:350,url:'//maps.google.com/maps/ms?msid=$2&output=embed"'}];e.on("ResolveName",function(e){var t;1==e.target.nodeType&&(t=e.target.getAttribute("data-mce-object"))&&(e.name=t)}),e.on("preInit",function(){var t=e.schema.getSpecialElements();tinymce.each("video audio iframe object".split(" "),function(e){t[e]=new RegExp("]*>","gi")});var i=e.schema.getBoolAttrs();tinymce.each("webkitallowfullscreen mozallowfullscreen allowfullscreen".split(" "),function(e){i[e]={}}),e.parser.addNodeFilter("iframe,video,audio,object,embed,script",function(t,i){for(var o,a,c,s,n,m,u,d,l=t.length;l--;)if(a=t[l],a.parent&&("script"!=a.name||(d=r(a.attr("src"))))){for(c=new tinymce.html.Node("img",1),c.shortEnded=!0,d&&(d.width&&a.attr("width",d.width.toString()),d.height&&a.attr("height",d.height.toString())),m=a.attributes,o=m.length;o--;)s=m[o].name,n=m[o].value,"width"!==s&&"height"!==s&&"style"!==s&&(("data"==s||"src"==s)&&(n=e.convertURL(n,s)),c.attr("data-mce-p-"+s,n));u=a.firstChild&&a.firstChild.value,u&&(c.attr("data-mce-html",escape(u)),c.firstChild=null),c.attr({width:a.attr("width")||"300",height:a.attr("height")||("audio"==i?"30":"150"),style:a.attr("style"),src:tinymce.Env.transparentSrc,"data-mce-object":i,"class":"mce-object mce-object-"+i}),a.replace(c)}}),e.serializer.addAttributeFilter("data-mce-object",function(e,t){for(var i,r,o,a,c,s,n,m=e.length;m--;)if(i=e[m],i.parent){for(n=i.attr(t),r=new tinymce.html.Node(n,1),"audio"!=n&&"script"!=n&&r.attr({width:i.attr("width"),height:i.attr("height")}),r.attr({style:i.attr("style")}),a=i.attributes,o=a.length;o--;){var u=a[o].name;0===u.indexOf("data-mce-p-")&&r.attr(u.substr(11),a[o].value)}"script"==n&&r.attr("type","text/javascript"),c=i.attr("data-mce-html"),c&&(s=new tinymce.html.Node("#text",3),s.raw=!0,s.value=unescape(c),r.append(s)),i.replace(r)}})}),e.on("ObjectSelected",function(e){var t=e.target.getAttribute("data-mce-object");("audio"==t||"script"==t)&&e.preventDefault()}),e.on("objectResized",function(e){var t,i=e.target;i.getAttribute("data-mce-object")&&(t=i.getAttribute("data-mce-html"),t&&(t=unescape(t),i.setAttribute("data-mce-html",escape(m(t,{width:e.width,height:e.height})))))}),e.addButton("media",{tooltip:"Insert/edit video",onclick:o,stateSelector:["img[data-mce-object=video]","img[data-mce-object=iframe]"]}),e.addMenuItem("media",{icon:"media",text:"Insert video",onclick:o,context:"insert",prependToContext:!0})});tinymce.PluginManager.add("nonbreaking",function(n){var e=n.getParam("nonbreaking_force_tab");if(n.addCommand("mceNonBreaking",function(){n.insertContent(n.plugins.visualchars&&n.plugins.visualchars.state?' ':" "),n.dom.setAttrib(n.dom.select("span.mce-nbsp"),"data-mce-bogus","1")}),n.addButton("nonbreaking",{title:"Insert nonbreaking space",cmd:"mceNonBreaking"}),n.addMenuItem("nonbreaking",{text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"}),e){var a=+e>1?+e:3;n.on("keydown",function(e){if(9==e.keyCode){if(e.shiftKey)return;e.preventDefault();for(var t=0;a>t;t++)n.execCommand("mceNonBreaking")}})}});tinymce.PluginManager.add("noneditable",function(e){function t(e){var t;if(1===e.nodeType){if(t=e.getAttribute(u),t&&"inherit"!==t)return t;if(t=e.contentEditable,"inherit"!==t)return t}return null}function n(e){for(var n;e;){if(n=t(e))return"false"===n?e:null;e=e.parentNode}}function r(){function r(e){for(;e;){if(e.id===g)return e;e=e.parentNode}}function a(e){var t;if(e)for(t=new f(e,e),e=t.current();e;e=t.next())if(3===e.nodeType)return e}function i(n,r){var a,i;return"false"===t(n)&&u.isBlock(n)?void s.select(n):(i=u.createRng(),"true"===t(n)&&(n.firstChild||n.appendChild(e.getDoc().createTextNode(" ")),n=n.firstChild,r=!0),a=u.create("span",{id:g,"data-mce-bogus":!0},m),r?n.parentNode.insertBefore(a,n):u.insertAfter(a,n),i.setStart(a.firstChild,1),i.collapse(!0),s.setRng(i),a)}function o(e){var t,n,i,o;if(e)t=s.getRng(!0),t.setStartBefore(e),t.setEndBefore(e),n=a(e),n&&n.nodeValue.charAt(0)==m&&(n=n.deleteData(0,1)),u.remove(e,!0),s.setRng(t);else for(i=r(s.getStart());(e=u.get(g))&&e!==o;)i!==e&&(n=a(e),n&&n.nodeValue.charAt(0)==m&&(n=n.deleteData(0,1)),u.remove(e,!0)),o=e}function l(){function e(e,n){var r,a,i,o,l;if(r=d.startContainer,a=d.startOffset,3==r.nodeType){if(l=r.nodeValue.length,a>0&&l>a||(n?a==l:0===a))return}else{if(!(a0?a-1:a;r=r.childNodes[u],r.hasChildNodes()&&(r=r.firstChild)}for(i=new f(r,e);o=i[n?"prev":"next"]();){if(3===o.nodeType&&o.nodeValue.length>0)return;if("true"===t(o))return o}return e}var r,a,l,d,u;o(),l=s.isCollapsed(),r=n(s.getStart()),a=n(s.getEnd()),(r||a)&&(d=s.getRng(!0),l?(r=r||a,(u=e(r,!0))?i(u,!0):(u=e(r,!1))?i(u,!1):s.select(r)):(d=s.getRng(!0),r&&d.setStartBefore(r),a&&d.setEndAfter(a),s.setRng(d)))}function d(a){function i(e,t){for(;e=e[t?"previousSibling":"nextSibling"];)if(3!==e.nodeType||e.nodeValue.length>0)return e}function d(e,t){s.select(e),s.collapse(t)}function g(a){function i(e){for(var t=d;t;){if(t===e)return;t=t.parentNode}u.remove(e),l()}function o(){var r,o,l=e.schema.getNonEmptyElements();for(o=new tinymce.dom.TreeWalker(d,e.getBody());(r=a?o.prev():o.next())&&!l[r.nodeName.toLowerCase()]&&!(3===r.nodeType&&tinymce.trim(r.nodeValue).length>0);)if("false"===t(r))return i(r),!0;return n(r)?!0:!1}var f,d,c,g;if(s.isCollapsed()){if(f=s.getRng(!0),d=f.startContainer,c=f.startOffset,d=r(d)||d,g=n(d))return i(g),!1;if(3==d.nodeType&&(a?c>0:ch||h>124)&&h!=c.DELETE&&h!=c.BACKSPACE){if((tinymce.isMac?a.metaKey:a.ctrlKey)&&(67==h||88==h||86==h))return;if(a.preventDefault(),h==c.LEFT||h==c.RIGHT){var y=h==c.LEFT;if(e.dom.isBlock(m)){var T=y?m.previousSibling:m.nextSibling,C=new f(T,T),b=y?C.prev():C.next();d(b,!y)}else d(m,y)}}else if(h==c.LEFT||h==c.RIGHT||h==c.BACKSPACE||h==c.DELETE){if(p=r(v)){if(h==c.LEFT||h==c.BACKSPACE)if(m=i(p,!0),m&&"false"===t(m)){if(a.preventDefault(),h!=c.LEFT)return void u.remove(m);d(m,!0)}else o(p);if(h==c.RIGHT||h==c.DELETE)if(m=i(p),m&&"false"===t(m)){if(a.preventDefault(),h!=c.RIGHT)return void u.remove(m);d(m,!1)}else o(p)}if((h==c.BACKSPACE||h==c.DELETE)&&!g(h==c.BACKSPACE))return a.preventDefault(),!1}}var u=e.dom,s=e.selection,g="mce_noneditablecaret",m="";e.on("mousedown",function(n){var r=e.selection.getNode();"false"===t(r)&&r==n.target&&l()}),e.on("mouseup keyup",l),e.on("keydown",d)}function a(t){var n=l.length,r=t.content,a=tinymce.trim(o);if("raw"!=t.format){for(;n--;)r=r.replace(l[n],function(t){var n=arguments,i=n[n.length-2];return i>0&&'"'==r.charAt(i-1)?t:''+e.dom.encode("string"==typeof n[1]?n[1]:n[0])+""});t.content=r}}var i,o,l,f=tinymce.dom.TreeWalker,d="contenteditable",u="data-mce-"+d,c=tinymce.util.VK;i=" "+tinymce.trim(e.getParam("noneditable_editable_class","mceEditable"))+" ",o=" "+tinymce.trim(e.getParam("noneditable_noneditable_class","mceNonEditable"))+" ",l=e.getParam("noneditable_regexp"),l&&!l.length&&(l=[l]),e.on("PreInit",function(){r(),l&&e.on("BeforeSetContent",a),e.parser.addAttributeFilter("class",function(e){for(var t,n,r=e.length;r--;)n=e[r],t=" "+n.attr("class")+" ",-1!==t.indexOf(i)?n.attr(u,"true"):-1!==t.indexOf(o)&&n.attr(u,"false")}),e.serializer.addAttributeFilter(u,function(e){for(var t,n=e.length;n--;)t=e[n],l&&t.attr("data-mce-content")?(t.name="#text",t.type=3,t.raw=!0,t.value=t.attr("data-mce-content")):(t.attr(d,null),t.attr(u,null))}),e.parser.addAttributeFilter(d,function(e){for(var t,n=e.length;n--;)t=e[n],t.attr(u,t.attr(d)),t.attr(d,null)})}),e.on("drop",function(e){n(e.target)&&e.preventDefault()})});tinymce.PluginManager.add("pagebreak",function(e){var a="mce-pagebreak",t=e.getParam("pagebreak_separator",""),n=new RegExp(t.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(e){return"\\"+e}),"gi"),r='';e.addCommand("mcePageBreak",function(){e.insertContent(e.settings.pagebreak_split_block?"

"+r+"

":r)}),e.addButton("pagebreak",{title:"Page break",cmd:"mcePageBreak"}),e.addMenuItem("pagebreak",{text:"Page break",icon:"pagebreak",cmd:"mcePageBreak",context:"insert"}),e.on("ResolveName",function(t){"IMG"==t.target.nodeName&&e.dom.hasClass(t.target,a)&&(t.name="pagebreak")}),e.on("click",function(t){t=t.target,"IMG"===t.nodeName&&e.dom.hasClass(t,a)&&e.selection.select(t)}),e.on("BeforeSetContent",function(e){e.content=e.content.replace(n,r)}),e.on("PreInit",function(){e.serializer.addNodeFilter("img",function(a){for(var n,r,c=a.length;c--;)if(n=a[c],r=n.attr("class"),r&&-1!==r.indexOf("mce-pagebreak")){var o=n.parent;if(e.schema.getBlockElements()[o.name]&&e.settings.pagebreak_split_block){o.type=3,o.value=t,o.raw=!0,n.remove();continue}n.type=3,n.value=t,n.raw=!0}})})});!function(e,t){"use strict";function n(e,t){for(var n,i=[],r=0;r"),t&&/^(PRE|DIV)$/.test(t.nodeName)||!o?e=n.filter(e,[[/\n/g,"
"]]):(e=n.filter(e,[[/\n\n/g,"

"+a],[/^(.*<\/p>)(

)$/,a+"$1"],[/\n/g,"
"]]),-1!=e.indexOf("

")&&(e=a+e)),r(e)}function a(){var t=i.dom,n=i.getBody(),r=i.dom.getViewPort(i.getWin()),o=r.y,a=20,s;if(v=i.selection.getRng(),i.inline&&(s=i.selection.getScrollContainer(),s&&s.scrollTop>0&&(o=s.scrollTop)),v.getClientRects){var l=v.getClientRects();if(l.length)a=o+(l[0].top-t.getPos(n).y);else{a=o;var c=v.startContainer;c&&(3==c.nodeType&&c.parentNode!=n&&(c=c.parentNode),1==c.nodeType&&(a=t.getPos(c,s||n).y))}}h=t.add(i.getBody(),"div",{id:"mcepastebin",contentEditable:!0,"data-mce-bogus":"1",style:"position: absolute; top: "+a+"px;width: 10px; height: 10px; overflow: hidden; opacity: 0"},y),(e.ie||e.gecko)&&t.setStyle(h,"left","rtl"==t.getStyle(n,"direction",!0)?65535:-65535),t.bind(h,"beforedeactivate focusin focusout",function(e){e.stopPropagation()}),h.focus(),i.selection.select(h,!0)}function s(){if(h){for(var e;e=i.dom.get("mcepastebin");)i.dom.remove(e),i.dom.unbind(e);v&&i.selection.setRng(v)}x=!1,h=v=null}function l(){var e=y,t,n;for(t=i.dom.select("div[id=mcepastebin]"),n=t.length;n--;){var r=t[n].innerHTML;e==y&&(e=""),r.length>e.length&&(e=r)}return e}function c(e){var t={};if(e&&e.types){var n=e.getData("Text");n&&n.length>0&&(t["text/plain"]=n);for(var i=0;i')},t.readAsDataURL(e.getAsFile()),!0}}if(!(!i.settings.paste_data_images||"text/html"in t||"text/plain"in t)&&e.clipboardData){var o=e.clipboardData.items;if(o)for(var a=0;a0}function p(){i.on("keydown",function(n){if(!n.isDefaultPrevented()&&(t.metaKeyPressed(n)&&86==n.keyCode||n.shiftKey&&45==n.keyCode)){if(x=n.shiftKey&&86==n.keyCode,n.stopImmediatePropagation(),b=(new Date).getTime(),e.ie&&x)return n.preventDefault(),void i.fire("paste",{ieFake:!0});s(),a()}}),i.on("paste",function(t){var c=d(t),f=(new Date).getTime()-b<1e3,p="text"==g.pasteFormat||x;return t.isDefaultPrevented()?void s():u(t,c)?void s():(f||t.preventDefault(),!e.ie||f&&!t.ieFake||(a(),i.dom.bind(h,"paste",function(e){e.stopPropagation()}),i.getDoc().execCommand("Paste",!1,null),c["text/html"]=l()),void setTimeout(function(){var e=l();return h&&h.firstChild&&"mcepastebin"===h.firstChild.id&&(p=!0),s(),!p&&f&&e&&e!=y&&(c["text/html"]=e),e!=y&&f||(e=c["text/html"]||c["text/plain"]||y,e!=y)?(!m(c,"text/html")&&m(c,"text/plain")&&(p=!0),void(p?o(c["text/plain"]||n.innerText(e)):r(e))):void(f||i.windowManager.alert("Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents."))},0))}),i.on("dragstart",function(e){if(e.dataTransfer.types)try{e.dataTransfer.setData("mce-internal",i.selection.getContent())}catch(t){}}),i.on("drop",function(e){var t=f(e);if(t&&!e.isDefaultPrevented()){var n=c(e.dataTransfer),a=n["mce-internal"]||n["text/html"]||n["text/plain"];a&&(e.preventDefault(),i.undoManager.transact(function(){n["mce-internal"]&&i.execCommand("Delete"),i.selection.setRng(t),n["text/html"]?r(a):o(a)}))}})}var g=this,h,v,b=0,y="%MCEPASTEBIN%",x;g.pasteHtml=r,g.pasteText=o,i.on("preInit",function(){p(),i.parser.addNodeFilter("img",function(t){if(!i.settings.paste_data_images)for(var n=t.length;n--;){var r=t[n].attributes.map.src;r&&0===r.indexOf("data:image")&&(t[n].attr("data-mce-object")||r===e.transparentSrc||t[n].remove())}})}),i.on("PreProcess",function(){i.dom.remove(i.dom.get("mcepastebin"))})}}),i(g,[c,d,u,h,v,l],function(e,t,n,i,r,o){function a(e){return/l?n&&(n=n.parent.parent):(i=n,n=null)),n&&n.name==a?n.append(e):(i=i||n,n=new r(a,1),s>1&&n.attr("start",""+s),e.wrap(n)),e.name="li",t.value="";var c=t.next;c&&3==c.type&&(c.value=c.value.replace(/^\u00a0+/,"")),l>o&&i&&i.lastChild.append(n),o=l}for(var n,i,o=1,a=e.getAll("p"),s=0;s/gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/ /gi,"\xa0"],[/([\s\u00a0]*)<\/span>/gi,function(e,t){return t.length>0?t.replace(/./," ").slice(Math.floor(t.length/2)).split("").join("\xa0"):""}]]);var g=l.paste_word_valid_elements;g||(g="-strong/b,-em/i,-span,-p,-ol,-ul,-li,-h1,-h2,-h3,-h4,-h5,-h6,-p/div,-table[width],-tr,-td[colspan|rowspan|width],-th,-thead,-tfoot,-tbody,-a[href|name],sub,sup,strike,br,del");var h=new n({valid_elements:g,valid_children:"-li[p]"});e.each(h.elements,function(e){e.attributes["class"]||(e.attributes["class"]={},e.attributesOrder.push("class")),e.attributes.style||(e.attributes.style={},e.attributesOrder.push("style"))});var v=new t({},h);v.addAttributeFilter("style",function(e){for(var t=e.length,n;t--;)n=e[t],n.attr("style",u(n,n.attr("style"))),"span"==n.name&&n.parent&&!n.attributes.length&&n.unwrap()}),v.addAttributeFilter("class",function(e){for(var t=e.length,n,i;t--;)n=e[t],i=n.attr("class"),/^(MsoCommentReference|MsoCommentText|msoDel)$/i.test(i)&&n.remove(),n.attr("class",null)}),v.addNodeFilter("del",function(e){for(var t=e.length;t--;)e[t].remove()}),v.addNodeFilter("a",function(e){for(var t=e.length,n,i,r;t--;)if(n=e[t],i=n.attr("href"),r=n.attr("name"),i&&-1!=i.indexOf("#_msocom_"))n.remove();else if(i&&0===i.indexOf("file://")&&(i=i.split("#")[1],i&&(i="#"+i)),i||r){if(r&&!/^_?(?:toc|edn|ftn)/i.test(r)){n.unwrap();continue}n.attr({href:i,name:r})}else n.unwrap()});var b=v.parse(f);d(b),c.content=new i({},h).serialize(b)}})}return s.isWordContent=a,s}),i(b,[m,c,g,l],function(e,t,n,i){return function(r){function o(e){r.on("BeforePastePreProcess",function(t){t.content=e(t.content)})}function a(e){return e=i.filter(e,[/^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/g,/|/g,[/\u00a0<\/span>/g,"\xa0"],/
$/i])}function s(e){if(!n.isWordContent(e))return e;var o=[];t.each(r.schema.getBlockElements(),function(e,t){o.push(t)});var a=new RegExp("(?:
 [\\s\\r\\n]+|
)*(<\\/?("+o.join("|")+")[^>]*>)(?:
 [\\s\\r\\n]+|
)*","g");return e=i.filter(e,[[a,"$1"]]),e=i.filter(e,[[/

/g,"

"],[/
/g," "],[/

/g,"
"]])}function l(e){if(n.isWordContent(e))return e;var t=r.settings.paste_webkit_styles;if(r.settings.paste_remove_styles_if_webkit===!1||"all"==t)return e;if(t&&(t=t.split(/[, ]/)),t){var i=r.dom,o=r.selection.getNode();e=e.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi,function(e,n,r,a){var s=i.parseStyle(r,"span"),l={};if("none"===t)return n+a;for(var c=0;c]+) style="([^"]*)"([^>]*>)/gi,"$1$3");return e=e.replace(/(<[^>]+) data-mce-style="([^"]+)"([^>]*>)/gi,function(e,t,n,i){return t+' style="'+n+'"'+i})}e.webkit&&(o(l),o(a)),e.ie&&o(s)}}),i(y,[x,f,g,b],function(e,t,n,i){var r;e.add("paste",function(e){function o(){"text"==s.pasteFormat?(this.active(!1),s.pasteFormat="html"):(s.pasteFormat="text",this.active(!0),r||(e.windowManager.alert("Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off."),r=!0))}var a=this,s,l=e.settings;a.clipboard=s=new t(e),a.quirks=new i(e),a.wordFilter=new n(e),e.settings.paste_as_text&&(a.clipboard.pasteFormat="text"),l.paste_preprocess&&e.on("PastePreProcess",function(e){l.paste_preprocess.call(a,a,e)}),l.paste_postprocess&&e.on("PastePostProcess",function(e){l.paste_postprocess.call(a,a,e)}),e.addCommand("mceInsertClipboardContent",function(e,t){t.content&&a.clipboard.pasteHtml(t.content),t.text&&a.clipboard.pasteText(t.text)}),e.paste_block_drop&&e.on("dragend dragover draggesture dragdrop drop drag",function(e){e.preventDefault(),e.stopPropagation()}),e.settings.paste_data_images||e.on("drop",function(e){var t=e.dataTransfer;t&&t.files&&t.files.length>0&&e.preventDefault()}),e.addButton("pastetext",{icon:"pastetext",tooltip:"Paste as text",onclick:o,active:"text"==a.clipboard.pasteFormat}),e.addMenuItem("pastetext",{text:"Paste as text",selectable:!0,active:s.pasteFormat,onclick:o})})}),a([l,f,g,b,y])}(this);tinymce.PluginManager.add("preview",function(e){var t=e.settings,i=!tinymce.Env.ie;e.addCommand("mcePreview",function(){e.windowManager.open({title:"Preview",width:parseInt(e.getParam("plugin_preview_width","650"),10),height:parseInt(e.getParam("plugin_preview_height","500"),10),html:'",buttons:{text:"Close",onclick:function(){this.parent().parent().close()}},onPostRender:function(){var n,a="";a+='',tinymce.each(e.contentCSS,function(t){a+=''});var r=t.body_id||"tinymce";-1!=r.indexOf("=")&&(r=e.getParam("body_id","","hash"),r=r[e.id]||r);var d=t.body_class||"";-1!=d.indexOf("=")&&(d=e.getParam("body_class","","hash"),d=d[e.id]||"");var o=e.settings.directionality?' dir="'+e.settings.directionality+'"':"";if(n=""+a+'"+e.getContent()+"",i)this.getEl("body").firstChild.src="data:text/html;charset=utf-8,"+encodeURIComponent(n);else{var s=this.getEl("body").firstChild.contentWindow.document;s.open(),s.write(n),s.close()}}})}),e.addButton("preview",{title:"Preview",cmd:"mcePreview"}),e.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})});tinymce.PluginManager.add("print",function(t){t.addCommand("mcePrint",function(){t.getWin().print()}),t.addButton("print",{title:"Print",cmd:"mcePrint"}),t.addShortcut("Ctrl+P","","mcePrint"),t.addMenuItem("print",{text:"Print",cmd:"mcePrint",icon:"print",shortcut:"Ctrl+P",context:"file"})});tinymce.PluginManager.add("save",function(e){function a(){var a;return a=tinymce.DOM.getParent(e.id,"form"),!e.getParam("save_enablewhendirty",!0)||e.isDirty()?(tinymce.triggerSave(),e.getParam("save_onsavecallback")?void(e.execCallback("save_onsavecallback",e)&&(e.startContent=tinymce.trim(e.getContent({format:"raw"})),e.nodeChanged())):void(a?(e.isNotDirty=!0,(!a.onsubmit||a.onsubmit())&&("function"==typeof a.submit?a.submit():e.windowManager.alert("Error: Form submit field collision.")),e.nodeChanged()):e.windowManager.alert("Error: No form element found."))):void 0}function n(){var a=tinymce.trim(e.startContent);return e.getParam("save_oncancelcallback")?void e.execCallback("save_oncancelcallback",e):(e.setContent(a),e.undoManager.clear(),void e.nodeChanged())}function t(){var a=this;e.on("nodeChange",function(){a.disabled(e.getParam("save_enablewhendirty",!0)&&!e.isDirty())})}e.addCommand("mceSave",a),e.addCommand("mceCancel",n),e.addButton("save",{icon:"save",text:"Save",cmd:"mceSave",disabled:!0,onPostRender:t}),e.addButton("cancel",{text:"Cancel",icon:!1,cmd:"mceCancel",disabled:!0,onPostRender:t}),e.addShortcut("ctrl+s","","mceSave")});!function(){function e(e,t,n,a,r){function i(e,t){if(t=t||0,!e[0])throw"findAndReplaceDOMText cannot handle zero-length matches";var n=e.index;if(t>0){var a=e[t];if(!a)throw"Invalid capture group";n+=e[0].indexOf(a),e[0]=a}return[n,n+e[0].length,[e[0]]]}function d(e){var t;if(3===e.nodeType)return e.data;if(h[e.nodeName]&&!u[e.nodeName])return"";if(t="",(u[e.nodeName]||m[e.nodeName])&&(t+="\n"),e=e.firstChild)do t+=d(e);while(e=e.nextSibling);return t}function o(e,t,n){var a,r,i,d,o=[],l=0,c=e,s=t.shift(),f=0;e:for(;;){if((u[c.nodeName]||m[c.nodeName])&&l++,3===c.nodeType&&(!r&&c.length+l>=s[1]?(r=c,d=s[1]-l):a&&o.push(c),!a&&c.length+l>s[0]&&(a=c,i=s[0]-l),l+=c.length),a&&r){if(c=n({startNode:a,startNodeIndex:i,endNode:r,endNodeIndex:d,innerNodes:o,match:s[2],matchIndex:f}),l-=r.length-d,a=null,r=null,o=[],s=t.shift(),f++,!s)break}else{if((!h[c.nodeName]||u[c.nodeName])&&c.firstChild){c=c.firstChild;continue}if(c.nextSibling){c=c.nextSibling;continue}}for(;;){if(c.nextSibling){c=c.nextSibling;break}if(c.parentNode===e)break e;c=c.parentNode}}}function l(e){var t;if("function"!=typeof e){var n=e.nodeType?e:f.createElement(e);t=function(e,t){var a=n.cloneNode(!1);return a.setAttribute("data-mce-index",t),e&&a.appendChild(f.createTextNode(e)),a}}else t=e;return function(e){var n,a,r,i=e.startNode,d=e.endNode,o=e.matchIndex;if(i===d){var l=i;r=l.parentNode,e.startNodeIndex>0&&(n=f.createTextNode(l.data.substring(0,e.startNodeIndex)),r.insertBefore(n,l));var c=t(e.match[0],o);return r.insertBefore(c,l),e.endNodeIndexh;++h){var g=e.innerNodes[h],p=t(g.data,o);g.parentNode.replaceChild(p,g),u.push(p)}var x=t(d.data.substring(0,e.endNodeIndex),o);return r=i.parentNode,r.insertBefore(n,i),r.insertBefore(s,i),r.removeChild(i),r=d.parentNode,r.insertBefore(x,d),r.insertBefore(a,d),r.removeChild(d),x}}var c,s,f,u,h,m,g=[],p=0;if(f=t.ownerDocument,u=r.getBlockElements(),h=r.getWhiteSpaceElements(),m=r.getShortEndedElements(),s=d(t)){if(e.global)for(;c=e.exec(s);)g.push(i(c,a));else c=s.match(e),g.push(i(c,a));return g.length&&(p=g.length,o(t,g,l(n))),p}}function t(t){function n(){function e(){r.statusbar.find("#next").disabled(!d(s+1).length),r.statusbar.find("#prev").disabled(!d(s-1).length)}function n(){tinymce.ui.MessageBox.alert("Could not find the specified string.",function(){r.find("#find")[0].focus()})}var a={},r=tinymce.ui.Factory.create({type:"window",layout:"flex",pack:"center",align:"center",onClose:function(){t.focus(),c.done()},onSubmit:function(t){var i,o,l,f;return t.preventDefault(),o=r.find("#case").checked(),f=r.find("#words").checked(),l=r.find("#find").value(),l.length?a.text==l&&a.caseState==o&&a.wholeWord==f?0===d(s+1).length?void n():(c.next(),void e()):(i=c.find(l,o,f),i||n(),r.statusbar.items().slice(1).disabled(0===i),e(),void(a={text:l,caseState:o,wholeWord:f})):(c.done(!1),void r.statusbar.items().slice(1).disabled(!0))},buttons:[{text:"Find",onclick:function(){r.submit()}},{text:"Replace",disabled:!0,onclick:function(){c.replace(r.find("#replace").value())||(r.statusbar.items().slice(1).disabled(!0),s=-1,a={})}},{text:"Replace all",disabled:!0,onclick:function(){c.replace(r.find("#replace").value(),!0,!0),r.statusbar.items().slice(1).disabled(!0),a={}}},{type:"spacer",flex:1},{text:"Prev",name:"prev",disabled:!0,onclick:function(){c.prev(),e()}},{text:"Next",name:"next",disabled:!0,onclick:function(){c.next(),e()}}],title:"Find and replace",items:{type:"form",padding:20,labelGap:30,spacing:10,items:[{type:"textbox",name:"find",size:40,label:"Find",value:t.selection.getNode().src},{type:"textbox",name:"replace",size:40,label:"Replace with"},{type:"checkbox",name:"case",text:"Match case",label:" "},{type:"checkbox",name:"words",text:"Whole words",label:" "}]}}).renderTo().reflow()}function a(e){var t=e.getAttribute("data-mce-index");return"number"==typeof t?""+t:t}function r(n){var a,r;return r=t.dom.create("span",{"data-mce-bogus":1}),r.className="mce-match-marker",a=t.getBody(),c.done(!1),e(n,a,r,!1,t.schema)}function i(e){var t=e.parentNode;e.firstChild&&t.insertBefore(e.firstChild,e),e.parentNode.removeChild(e)}function d(e){var n,r=[];if(n=tinymce.toArray(t.getBody().getElementsByTagName("span")),n.length)for(var i=0;is&&f[o].setAttribute("data-mce-index",m-1)}return t.undoManager.add(),s=p,n?(g=d(p+1).length>0,c.next()):(g=d(p-1).length>0,c.prev()),!r&&g},c.done=function(e){var n,r,d,o;for(r=tinymce.toArray(t.getBody().getElementsByTagName("span")),n=0;n=d.end?(r=c,a=d.end-s):o&&l.push(c),!o&&c.length+s>d.start&&(o=c,i=d.start-s),s+=c.length),o&&r){if(c=n({startNode:o,startNodeIndex:i,endNode:r,endNodeIndex:a,innerNodes:l,match:d.text,matchIndex:u}),s-=r.length-a,o=null,r=null,l=[],d=t.shift(),u++,!d)break}else{if((!P[c.nodeName]||S[c.nodeName])&&c.firstChild){c=c.firstChild;continue}if(c.nextSibling){c=c.nextSibling;continue}}for(;;){if(c.nextSibling){c=c.nextSibling;break}if(c.parentNode===e)break e;c=c.parentNode}}}function i(e){function t(t,n){var o=w[n];o.stencil||(o.stencil=e(o));var r=o.stencil.cloneNode(!1);return r.setAttribute("data-mce-index",n),t&&r.appendChild(k.doc.createTextNode(t)),r}return function(e){var n,o,r,i=e.startNode,a=e.endNode,l=e.matchIndex,s=k.doc;if(i===a){var c=i;r=c.parentNode,e.startNodeIndex>0&&(n=s.createTextNode(c.data.substring(0,e.startNodeIndex)),r.insertBefore(n,c));var d=t(e.match,l);return r.insertBefore(d,c),e.endNodeIndexm;++m){var g=e.innerNodes[m],h=t(g.data,l);g.parentNode.replaceChild(h,g),f.push(h)}var v=t(a.data.substring(0,e.endNodeIndex),l);return r=i.parentNode,r.insertBefore(n,i),r.insertBefore(u,i),r.removeChild(i),r=a.parentNode,r.insertBefore(v,a),r.insertBefore(o,a),r.removeChild(a),v}}function a(e){var t=e.parentNode;t.insertBefore(e.firstChild,e),e.parentNode.removeChild(e)}function l(t){var n=e.getElementsByTagName("*"),o=[];t="number"==typeof t?""+t:null;for(var r=0;rt&&e(w[t],t)!==!1;t++);return this}function u(t){return w.length&&r(e,w,i(t)),this}function f(e,t){if(C&&e.global)for(;x=e.exec(C);)w.push(n(x,t));return this}function m(e){var t,n=l(e?s(e):null);for(t=n.length;t--;)a(n[t]);return this}function p(e){return w[e.getAttribute("data-mce-index")]}function g(e){return l(s(e))[0]}function h(e,t,n){return w.push({start:e,end:e+t,text:C.substr(e,t),data:n}),this}function v(e){var n=l(s(e)),o=t.dom.createRng();return o.setStartBefore(n[0]),o.setEndAfter(n[n.length-1]),o}function b(e,n){var o=v(e);return o.deleteContents(),n.length>0&&o.insertNode(t.dom.doc.createTextNode(n)),o}function y(){return w.splice(0,w.length),m(),this}var x,w=[],C,k=t.dom,S,P,N;return S=t.schema.getBlockElements(),P=t.schema.getWhiteSpaceElements(),N=t.schema.getShortEndedElements(),C=o(e),{text:C,matches:w,each:d,filter:c,reset:y,matchFromElement:p,elementFromMatch:g,find:f,add:h,wrap:u,unwrap:m,replace:b,rangeFromMatch:v,indexOf:s}}}),o(c,[s,d,u,f,m,p,g,h],function(e,t,n,o,r,i,a,l){t.add("spellchecker",function(t,s){function c(){return C.textMatcher||(C.textMatcher=new e(t.getBody(),t)),C.textMatcher}function d(e,t){var o=[];return n.each(t,function(e){o.push({selectable:!0,text:e.name,data:e.value})}),o}function u(e){for(var t in e)return!1;return!0}function f(e,i){var a=[],l=k[e];n.each(l,function(e){a.push({text:e,onclick:function(){t.insertContent(t.dom.encode(e)),t.dom.remove(i),g()}})}),a.push.apply(a,[{text:"-"},{text:"Ignore",onclick:function(){h(e,i)}},{text:"Ignore all",onclick:function(){h(e,i,!0)}},{text:"Finish",onclick:v}]),P=new o({items:a,context:"contextmenu",onautohide:function(e){-1!=e.target.className.indexOf("spellchecker")&&e.preventDefault()},onhide:function(){P.remove(),P=null}}),P.renderTo(document.body);var s=r.DOM.getPos(t.getContentAreaContainer()),c=t.dom.getPos(i[0]),d=t.dom.getRoot();"BODY"==d.nodeName?(c.x-=d.ownerDocument.documentElement.scrollLeft||d.scrollLeft,c.y-=d.ownerDocument.documentElement.scrollTop||d.scrollTop):(c.x-=d.scrollLeft,c.y-=d.scrollTop),s.x+=c.x,s.y+=c.y,P.moveTo(s.x,s.y+i[0].offsetHeight)}function m(){return t.getParam("spellchecker_wordchar_pattern")||new RegExp('[^\\s!"#$%&()*+,-./:;<=>?@[\\]^_{|}`\xa7\xa9\xab\xae\xb1\xb6\xb7\xb8\xbb\xbc\xbd\xbe\xbf\xd7\xf7\xa4\u201d\u201c\u201e]+',"g")}function p(){function e(e){return t.setProgressState(!1),u(e)?(t.windowManager.alert("No misspellings found"),void(S=!1)):(k=e,c().find(m()).filter(function(t){return!!e[t.text]}).wrap(function(e){return t.dom.create("span",{"class":"mce-spellchecker-word","data-mce-bogus":1,"data-mce-word":e.text})}),void t.fire("SpellcheckStart"))}function n(e){t.windowManager.alert(e),t.setProgressState(!1),v()}function o(e,t,o){i.send({url:new a(s).toAbsolute(N.spellchecker_rpc_url),type:"post",content_type:"application/x-www-form-urlencoded",data:"text="+encodeURIComponent(t)+"&lang="+N.spellchecker_language,success:function(e){e=l.parse(e),e?e.error?n(e.error):o(e.words):n("Sever response wasn't proper JSON.")},error:function(e,t){n("Spellchecker request error: "+t.status)}})}if(S)return void v();v(),S=!0,t.setProgressState(!0);var r=N.spellchecker_callback||o;r.call(C,"spellcheck",c().text,e,n),t.focus()}function g(){t.dom.select("span.mce-spellchecker-word").length||v()}function h(e,o,r){t.selection.collapse(),r?n.each(t.dom.select("span.mce-spellchecker-word"),function(n){n.getAttribute("data-mce-word")==e&&t.dom.remove(n,!0)}):t.dom.remove(o,!0),g()}function v(){c().reset(),C.textMatcher=null,S&&(S=!1,t.fire("SpellcheckEnd"))}function b(e){var t=e.getAttribute("data-mce-index");return"number"==typeof t?""+t:t}function y(e){var o,r=[];if(o=n.toArray(t.getBody().getElementsByTagName("span")),o.length)for(var i=0;i0){var r=t.dom.createRng();r.setStartBefore(o[0]),r.setEndAfter(o[o.length-1]),t.selection.setRng(r),f(n.getAttribute("data-mce-word"),o)}}}),t.addMenuItem("spellchecker",{text:"Spellcheck",context:"tools",onclick:p,selectable:!0,onPostRender:function(){var e=this;t.on("SpellcheckStart SpellcheckEnd",function(){e.active(S)})}});var T={tooltip:"Spellcheck",onclick:p,onPostRender:function(){var e=this;t.on("SpellcheckStart SpellcheckEnd",function(){e.active(S)})}};w.length>1&&(T.type="splitbutton",T.menu=w,T.onshow=x,T.onselect=function(e){N.spellchecker_language=e.control.settings.data}),t.addButton("spellchecker",T),t.addCommand("mceSpellCheck",p),t.on("remove",function(){P&&(P.remove(),P=null)}),t.on("change",g),this.getTextMatcher=c,this.getWordCharPattern=m,this.getLanguage=function(){return N.spellchecker_language},N.spellchecker_language=N.spellchecker_language||N.language||"en"})}),a([s,c])}(this);tinymce.PluginManager.add("tabfocus",function(e){function n(e){9!==e.keyCode||e.ctrlKey||e.altKey||e.metaKey||e.preventDefault()}function t(n){function t(n){function t(e){return"BODY"===e.nodeName||"hidden"!=e.type&&"none"!=e.style.display&&"hidden"!=e.style.visibility&&t(e.parentNode)}function r(e){return e.tabIndex||"INPUT"==e.nodeName||"TEXTAREA"==e.nodeName}function c(e){return!r(e)&&"-1"!=e.getAttribute("tabindex")&&t(e)}if(u=i.select(":input:enabled,*[tabindex]:not(iframe)"),o(u,function(n,t){return n.id==e.id?(a=t,!1):void 0}),n>0){for(d=a+1;d=0;d--)if(c(u[d]))return u[d];return null}var a,u,c,d;if(!(9!==n.keyCode||n.ctrlKey||n.altKey||n.metaKey)&&(c=r(e.getParam("tab_focus",e.getParam("tabfocus_elements",":prev,:next"))),1==c.length&&(c[1]=c[0],c[0]=":prev"),u=n.shiftKey?":prev"==c[0]?t(-1):i.get(c[0]):":next"==c[1]?t(1):i.get(c[1]))){var y=tinymce.get(u.id||u.name);u.id&&y?y.focus():window.setTimeout(function(){tinymce.Env.webkit||window.focus(),u.focus()},10),n.preventDefault()}}var i=tinymce.DOM,o=tinymce.each,r=tinymce.explode;e.on("init",function(){e.inline&&tinymce.DOM.setAttrib(e.getBody(),"tabIndex",null)}),e.on("keyup",n),tinymce.Env.gecko?e.on("keypress keydown",t):e.on("keydown",t)});!function(e,t){"use strict";function n(e,t){for(var n,o=[],i=0;i "+t+" tr",a);i(n,function(n,r){r+=e,i(I.select("> td, > th",n),function(e,n){var i,a,l,s;if(A[r])for(;A[r][n];)n++;for(l=o(e,"rowspan"),s=o(e,"colspan"),a=r;r+l>a;a++)for(A[a]||(A[a]=[]),i=n;n+s>i;i++)A[a][i]={part:t,real:a==r&&i==n,elm:e,rowspan:l,colspan:s}})}),e+=n.length})}function s(e,t){return e=e.cloneNode(t),e.removeAttribute("id"),e}function c(e,t){var n;return n=A[t],n?n[e]:void 0}function d(e,t,n){e&&(n=parseInt(n,10),1===n?e.removeAttribute(t,1):e.setAttribute(t,n,1))}function u(e){return e&&(I.hasClass(e.elm,"mce-item-selected")||e==M)}function f(){var e=[];return i(a.rows,function(t){i(t.cells,function(n){return I.hasClass(n,"mce-item-selected")||M&&n==M.elm?(e.push(t),!1):void 0})}),e}function m(){var e=I.createRng();e.setStartAfter(a),e.setEndAfter(a),E.setRng(e),I.remove(a)}function p(t){var o,a={};return r.settings.table_clone_elements!==!1&&(a=e.makeMap((r.settings.table_clone_elements||"strong em b i span font h1 h2 h3 h4 h5 h6 p div").toUpperCase(),/[ ,]/)),e.walk(t,function(e){var r;return 3==e.nodeType?(i(I.getParents(e.parentNode,null,t).reverse(),function(e){a[e.nodeName]&&(e=s(e,!1),o?r&&r.appendChild(e):o=r=e,r=e)}),r&&(r.innerHTML=n.ie?" ":'
'),!1):void 0},"childNodes"),t=s(t,!1),d(t,"rowSpan",1),d(t,"colSpan",1),o?t.appendChild(o):n.ie||(t.innerHTML='
'),t}function g(){var e=I.createRng(),t;return i(I.select("tr",a),function(e){0===e.cells.length&&I.remove(e)}),0===I.select("tr",a).length?(e.setStartBefore(a),e.setEndBefore(a),E.setRng(e),void I.remove(a)):(i(I.select("thead,tbody,tfoot",a),function(e){0===e.rows.length&&I.remove(e)}),l(),void(B&&(t=A[Math.min(A.length-1,B.y)],t&&(E.select(t[Math.min(t.length-1,B.x)].elm,!0),E.collapse(!0)))))}function h(e,t,n,o){var i,r,a,l,s;for(i=A[t][e].elm.parentNode,a=1;n>=a;a++)if(i=I.getNext(i,"tr")){for(r=e;r>=0;r--)if(s=A[t+a][r].elm,s.parentNode==i){for(l=1;o>=l;l++)I.insertAfter(p(s),s);break}if(-1==r)for(l=1;o>=l;l++)i.insertBefore(p(i.cells[0]),i.cells[0])}}function v(){i(A,function(e,t){i(e,function(e,n){var i,r,a;if(u(e)&&(e=e.elm,i=o(e,"colspan"),r=o(e,"rowspan"),i>1||r>1)){for(d(e,"rowSpan",1),d(e,"colSpan",1),a=0;i-1>a;a++)I.insertAfter(p(e),e);h(n,t,r-1,i)}})})}function b(t,n,o){var r,a,s,f,m,p,h,b,y,w,x;if(t?(r=T(t),a=r.x,s=r.y,f=a+(n-1),m=s+(o-1)):(B=D=null,i(A,function(e,t){i(e,function(e,n){u(e)&&(B||(B={x:n,y:t}),D={x:n,y:t})})}),B&&(a=B.x,s=B.y,f=D.x,m=D.y)),b=c(a,s),y=c(f,m),b&&y&&b.part==y.part){for(v(),l(),b=c(a,s).elm,d(b,"colSpan",f-a+1),d(b,"rowSpan",m-s+1),h=s;m>=h;h++)for(p=a;f>=p;p++)A[h]&&A[h][p]&&(t=A[h][p].elm,t!=b&&(w=e.grep(t.childNodes),i(w,function(e){b.appendChild(e)}),w.length&&(w=e.grep(b.childNodes),x=0,i(w,function(e){"BR"==e.nodeName&&I.getAttrib(e,"data-mce-bogus")&&x++0&&A[n-1][l]&&(g=A[n-1][l].elm,h=o(g,"rowSpan"),h>1)){d(g,"rowSpan",h+1);continue}}else if(h=o(r,"rowspan"),h>1){d(r,"rowSpan",h+1);continue}m=p(r),d(m,"colSpan",r.colSpan),f.appendChild(m),a=r}f.hasChildNodes()&&(e?c.parentNode.insertBefore(f,c):I.insertAfter(f,c))}}function w(e){var t,n;i(A,function(n){return i(n,function(n,o){return u(n)&&(t=o,e)?!1:void 0}),e?!t:void 0}),i(A,function(i,r){var a,l,s;i[t]&&(a=i[t].elm,a!=n&&(s=o(a,"colspan"),l=o(a,"rowspan"),1==s?e?(a.parentNode.insertBefore(p(a),a),h(t,r,l-1,s)):(I.insertAfter(p(a),a),h(t,r,l-1,s)):d(a,"colSpan",a.colSpan+1),n=a))})}function x(){var t=[];i(A,function(n){i(n,function(n,r){u(n)&&-1===e.inArray(t,r)&&(i(A,function(e){var t=e[r].elm,n;n=o(t,"colSpan"),n>1?d(t,"colSpan",n-1):I.remove(t)}),t.push(r))})}),g()}function C(){function e(e){var t,n,r;t=I.getNext(e,"tr"),i(e.cells,function(e){var t=o(e,"rowSpan");t>1&&(d(e,"rowSpan",t-1),n=T(e),h(n.x,n.y,1,1))}),n=T(e.cells[0]),i(A[n.y],function(e){var t;e=e.elm,e!=r&&(t=o(e,"rowSpan"),1>=t?I.remove(e):d(e,"rowSpan",t-1),r=e)})}var t;t=f(),i(t.reverse(),function(t){e(t)}),g()}function P(){var e=f();return I.remove(e),g(),e}function S(){var e=f();return i(e,function(t,n){e[n]=s(t,!0)}),e}function R(e,t){var n=f(),o=n[t?0:n.length-1],r=o.cells.length;e&&(i(A,function(e){var t;return r=0,i(e,function(e){e.real&&(r+=e.colspan),e.elm.parentNode==o&&(t=1)}),t?!1:void 0}),t||e.reverse(),i(e,function(e){var n,i=e.cells.length,a;for(n=0;i>n;n++)a=e.cells[n],d(a,"colSpan",1),d(a,"rowSpan",1);for(n=i;r>n;n++)e.appendChild(p(e.cells[i-1]));for(n=r;i>n;n++)I.remove(e.cells[n]);t?o.parentNode.insertBefore(e,o):I.insertAfter(e,o)}),I.removeClass(I.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"))}function T(e){var t;return i(A,function(n,o){return i(n,function(n,i){return n.elm==e?(t={x:i,y:o},!1):void 0}),!t}),t}function k(e){B=T(e)}function N(){var e,t;return e=t=0,i(A,function(n,o){i(n,function(n,i){var r,a;u(n)&&(n=A[o][i],i>e&&(e=i),o>t&&(t=o),n.real&&(r=n.colspan-1,a=n.rowspan-1,r&&i+r>e&&(e=i+r),a&&o+a>t&&(t=o+a)))})}),{x:e,y:t}}function _(e){var t,n,o,i,r,a,l,s,c,d;if(D=T(e),B&&D){for(t=Math.min(B.x,D.x),n=Math.min(B.y,D.y),o=Math.max(B.x,D.x),i=Math.max(B.y,D.y),r=o,a=i,d=n;a>=d;d++)e=A[d][t],e.real||t-(e.colspan-1)=c;c++)e=A[n][c],e.real||n-(e.rowspan-1)=d;d++)for(c=t;o>=c;c++)e=A[d][c],e.real&&(l=e.colspan-1,s=e.rowspan-1,l&&c+l>r&&(r=c+l),s&&d+s>a&&(a=d+s));for(I.removeClass(I.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),d=n;a>=d;d++)for(c=t;r>=c;c++)A[d][c]&&I.addClass(A[d][c].elm,"mce-item-selected")}}var A,B,D,M,E=r.selection,I=E.dom;a=a||I.getParent(E.getStart(),"table"),l(),M=I.getParent(E.getStart(),"th,td"),M&&(B=T(M),D=N(),M=c(B.x,B.y)),e.extend(this,{deleteTable:m,split:v,merge:b,insertRow:y,insertCol:w,deleteCols:x,deleteRows:C,cutRows:P,copyRows:S,pasteRows:R,getPos:T,setStartCell:k,setEndCell:_})}}),o(u,[f,d,c],function(e,t,n){function o(e,t){return parseInt(e.getAttribute(t)||1,10)}var i=n.each;return function(n){function r(){function t(t){function r(e,o){var i=e?"previousSibling":"nextSibling",r=n.dom.getParent(o,"tr"),l=r[i];if(l)return h(n,o,l,e),t.preventDefault(),!0;var d=n.dom.getParent(r,"table"),u=r.parentNode,f=u.nodeName.toLowerCase();if("tbody"===f||f===(e?"tfoot":"thead")){var m=a(e,d,u,"tbody");if(null!==m)return s(e,m,o)}return c(e,r,i,d)}function a(e,t,o,i){var r=n.dom.select(">"+i,t),a=r.indexOf(o);if(e&&0===a||!e&&a===r.length-1)return l(e,t);if(-1===a){var s="thead"===o.tagName.toLowerCase()?0:r.length-1;return r[s]}return r[a+(e?-1:1)]}function l(e,t){var o=e?"thead":"tfoot",i=n.dom.select(">"+o,t);return 0!==i.length?i[0]:null}function s(e,o,i){var r=d(o,e);return r&&h(n,i,r,e),t.preventDefault(),!0}function c(e,o,i,a){var l=a[i];if(l)return u(l),!0;var s=n.dom.getParent(a,"td,th");if(s)return r(e,s,t);var c=d(o,!e);return u(c),t.preventDefault(),!1}function d(e,t){var o=e&&e[t?"lastChild":"firstChild"];return o&&"BR"===o.nodeName?n.dom.getParent(o,"td,th"):o}function u(e){n.selection.setCursorLocation(e,0)}function f(){return y==e.UP||y==e.DOWN}function m(e){var t=e.selection.getNode(),n=e.dom.getParent(t,"tr");return null!==n}function p(e){for(var t=0,n=e;n.previousSibling;)n=n.previousSibling,t+=o(n,"colspan");return t}function g(e,t){var n=0,r=0;return i(e.children,function(e,i){return n+=o(e,"colspan"),r=i,n>t?!1:void 0}),r}function h(e,t,o,i){var r=p(n.dom.getParent(t,"td,th")),a=g(o,r),l=o.childNodes[a],s=d(l,i);u(s||l)}function v(e){var t=n.selection.getNode(),o=n.dom.getParent(t,"td,th"),i=n.dom.getParent(e,"td,th");return o&&o!==i&&b(o,i)}function b(e,t){return n.dom.getParent(e,"TABLE")===n.dom.getParent(t,"TABLE")}var y=t.keyCode;if(f()&&m(n)){var w=n.selection.getNode();setTimeout(function(){v(w)&&r(!t.shiftKey&&y===e.UP,w,t)},0)}}n.on("KeyDown",function(e){t(e)})}function a(){function e(e,t){var n=t.ownerDocument,o=n.createRange(),i;return o.setStartBefore(t),o.setEnd(e.endContainer,e.endOffset),i=n.createElement("body"),i.appendChild(o.cloneContents()),0===i.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi,"-").replace(/<[^>]+>/g,"").length}n.on("KeyDown",function(t){var o,i,r=n.dom;(37==t.keyCode||38==t.keyCode)&&(o=n.selection.getRng(),i=r.getParent(o.startContainer,"table"),i&&n.getBody().firstChild==i&&e(o,i)&&(o=r.createRng(),o.setStartBefore(i),o.setEndBefore(i),n.selection.setRng(o),t.preventDefault()))})}function l(){n.on("KeyDown SetContent VisualAid",function(){var e;for(e=n.getBody().lastChild;e;e=e.previousSibling)if(3==e.nodeType){if(e.nodeValue.length>0)break}else if(1==e.nodeType&&!e.getAttribute("data-mce-bogus"))break;e&&"TABLE"==e.nodeName&&(n.settings.forced_root_block?n.dom.add(n.getBody(),n.settings.forced_root_block,n.settings.forced_root_block_attrs,t.ie&&t.ie<11?" ":'
'):n.dom.add(n.getBody(),"br",{"data-mce-bogus":"1"}))}),n.on("PreProcess",function(e){var t=e.node.lastChild;t&&("BR"==t.nodeName||1==t.childNodes.length&&("BR"==t.firstChild.nodeName||"\xa0"==t.firstChild.nodeValue))&&t.previousSibling&&"TABLE"==t.previousSibling.nodeName&&n.dom.remove(t)})}function s(){function e(e,t,n,o){var i=3,r=e.dom.getParent(t.startContainer,"TABLE"),a,l,s;return r&&(a=r.parentNode),l=t.startContainer.nodeType==i&&0===t.startOffset&&0===t.endOffset&&o&&("TR"==n.nodeName||n==a),s=("TD"==n.nodeName||"TH"==n.nodeName)&&!o,l||s}function t(){var t=n.selection.getRng(),o=n.selection.getNode(),i=n.dom.getParent(t.startContainer,"TD,TH");if(e(n,t,o,i)){i||(i=o);for(var r=i.lastChild;r.lastChild;)r=r.lastChild;t.setEnd(r,r.nodeValue.length),n.selection.setRng(t)}}n.on("KeyDown",function(){t()}),n.on("MouseDown",function(e){2!=e.button&&t()})}function c(){n.on("keydown",function(t){if((t.keyCode==e.DELETE||t.keyCode==e.BACKSPACE)&&!t.isDefaultPrevented()){var o=n.dom.getParent(n.selection.getStart(),"table");if(o){for(var i=n.dom.select("td,th",o),r=i.length;r--;)if(!n.dom.hasClass(i[r],"mce-item-selected"))return;t.preventDefault(),n.execCommand("mceTableDelete")}}})}c(),t.webkit&&(r(),s()),t.gecko&&(a(),l()),t.ie>10&&(a(),l())}}),o(m,[s,p,c],function(e,t,n){return function(o){function i(){o.getBody().style.webkitUserSelect="",d&&(o.dom.removeClass(o.dom.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),d=!1)}function r(t){var n,i,r=t.target;if(s&&(l||r!=s)&&("TD"==r.nodeName||"TH"==r.nodeName)){i=a.getParent(r,"table"),i==c&&(l||(l=new e(o,i),l.setStartCell(s),o.getBody().style.webkitUserSelect="none"),l.setEndCell(r),d=!0),n=o.selection.getSel();try{n.removeAllRanges?n.removeAllRanges():n.empty()}catch(u){}t.preventDefault()}}var a=o.dom,l,s,c,d=!0;return o.on("MouseDown",function(e){2!=e.button&&(i(),s=a.getParent(e.target,"td,th"),c=a.getParent(s,"table"))}),o.on("mouseover",r),o.on("remove",function(){a.unbind(o.getDoc(),"mouseover",r)}),o.on("MouseUp",function(){function e(e,o){var r=new t(e,e);do{if(3==e.nodeType&&0!==n.trim(e.nodeValue).length)return void(o?i.setStart(e,0):i.setEnd(e,e.nodeValue.length));if("BR"==e.nodeName)return void(o?i.setStartBefore(e):i.setEndBefore(e))}while(e=o?r.next():r.prev())}var i,r=o.selection,d,u,f,m,p;if(s){if(l&&(o.getBody().style.webkitUserSelect=""),d=a.select("td.mce-item-selected,th.mce-item-selected"),d.length>0){i=a.createRng(),f=d[0],p=d[d.length-1],i.setStartBefore(f),i.setEndAfter(f),e(f,1),u=new t(f,a.getParent(d[0],"table"));do if("TD"==f.nodeName||"TH"==f.nodeName){if(!a.hasClass(f,"mce-item-selected"))break;m=f}while(f=u.next());e(m),r.setRng(i)}o.nodeChanged(),s=l=c=null}}),o.on("KeyUp Drop",function(){i(),s=l=c=null}),{clear:i}}}),o(g,[s,u,m,c,p,d,h],function(e,t,n,o,i,r,a){function l(o){function i(e){return e?e.replace(/px$/,""):""}function a(e){return/^[0-9]+$/.test(e)&&(e+="px"),e}function l(e){s("left center right".split(" "),function(t){o.formatter.remove("align"+t,{},e)})}function c(e){s("top middle bottom".split(" "),function(t){o.formatter.remove("valign"+t,{},e)})}function d(){var e=o.dom,t,n,c,d;t=e.getParent(o.selection.getStart(),"table"),d={width:i(e.getStyle(t,"width")||e.getAttrib(t,"width")),height:i(e.getStyle(t,"height")||e.getAttrib(t,"height")),cellspacing:t?e.getAttrib(t,"cellspacing"):"",cellpadding:t?e.getAttrib(t,"cellpadding"):"",border:t?e.getAttrib(t,"border"):"",caption:!!e.select("caption",t)[0]},s("left center right".split(" "),function(e){o.formatter.matchNode(t,"align"+e)&&(d.align=e)}),t||(n={label:"Cols",name:"cols"},c={label:"Rows",name:"rows"}),o.windowManager.open({title:"Table properties",items:{type:"form",layout:"grid",columns:2,data:d,defaults:{type:"textbox",maxWidth:50},items:[n,c,{label:"Width",name:"width"},{label:"Height",name:"height"},{label:"Cell spacing",name:"cellspacing"},{label:"Cell padding",name:"cellpadding"},{label:"Border",name:"border"},{label:"Caption",name:"caption",type:"checkbox"},{label:"Alignment",minWidth:90,name:"align",type:"listbox",text:"None",maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]}]},onsubmit:function(){var n=this.toJSON(),i;o.undoManager.transact(function(){t||(t=g(n.cols||1,n.rows||1)),o.dom.setAttribs(t,{cellspacing:n.cellspacing,cellpadding:n.cellpadding,border:n.border}),o.dom.setStyles(t,{width:a(n.width),height:a(n.height)}),i=e.select("caption",t)[0],i&&!n.caption&&e.remove(i),!i&&n.caption&&(i=e.create("caption"),i.innerHTML=r.ie?"\xa0":'
',t.insertBefore(i,t.firstChild)),l(t),n.align&&o.formatter.apply("align"+n.align,{},t),o.focus(),o.addVisual()})}})}function u(e,t){o.windowManager.open({title:"Merge cells",body:[{label:"Cols",name:"cols",type:"textbox",size:10},{label:"Rows",name:"rows",type:"textbox",size:10}],onsubmit:function(){var n=this.toJSON();o.undoManager.transact(function(){e.merge(t,n.cols,n.rows)})}})}function f(){var e=o.dom,t,n,r=[];r=o.dom.select("td.mce-item-selected,th.mce-item-selected"),t=o.dom.getParent(o.selection.getStart(),"td,th"),!r.length&&t&&r.push(t),t=t||r[0],t&&(n={width:i(e.getStyle(t,"width")||e.getAttrib(t,"width")),height:i(e.getStyle(t,"height")||e.getAttrib(t,"height")),scope:e.getAttrib(t,"scope")},n.type=t.nodeName.toLowerCase(),s("left center right".split(" "),function(e){o.formatter.matchNode(t,"align"+e)&&(n.align=e)}),s("top middle bottom".split(" "),function(e){o.formatter.matchNode(t,"valign"+e)&&(n.valign=e)}),o.windowManager.open({title:"Cell properties",items:{type:"form",data:n,layout:"grid",columns:2,defaults:{type:"textbox",maxWidth:50},items:[{label:"Width",name:"width"},{label:"Height",name:"height"},{label:"Cell type",name:"type",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"Cell",value:"td"},{text:"Header cell",value:"th"}]},{label:"Scope",name:"scope",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Row",value:"row"},{text:"Column",value:"col"},{text:"Row group",value:"rowgroup"},{text:"Column group",value:"colgroup"}]},{label:"H Align",name:"align",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]},{label:"V Align",name:"valign",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Top",value:"top"},{text:"Middle",value:"middle"},{text:"Bottom",value:"bottom"}]}]},onsubmit:function(){var t=this.toJSON();o.undoManager.transact(function(){s(r,function(n){o.dom.setAttrib(n,"scope",t.scope),o.dom.setStyles(n,{width:a(t.width),height:a(t.height)}),t.type&&n.nodeName.toLowerCase()!=t.type&&(n=e.rename(n,t.type)),l(n),t.align&&o.formatter.apply("align"+t.align,{},n),c(n),t.valign&&o.formatter.apply("valign"+t.valign,{},n)}),o.focus()})}}))}function m(){var e=o.dom,t,n,r,c,d=[];t=o.dom.getParent(o.selection.getStart(),"table"),n=o.dom.getParent(o.selection.getStart(),"td,th"),s(t.rows,function(t){s(t.cells,function(o){return e.hasClass(o,"mce-item-selected")||o==n?(d.push(t),!1):void 0})}),r=d[0],r&&(c={height:i(e.getStyle(r,"height")||e.getAttrib(r,"height")),scope:e.getAttrib(r,"scope")},c.type=r.parentNode.nodeName.toLowerCase(),s("left center right".split(" "),function(e){o.formatter.matchNode(r,"align"+e)&&(c.align=e)}),o.windowManager.open({title:"Row properties",items:{type:"form",data:c,columns:2,defaults:{type:"textbox"},items:[{type:"listbox",name:"type",label:"Row type",text:"None",maxWidth:null,values:[{text:"Header",value:"thead"},{text:"Body",value:"tbody"},{text:"Footer",value:"tfoot"}]},{type:"listbox",name:"align",label:"Alignment",text:"None",maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]},{label:"Height",name:"height"}]},onsubmit:function(){var t=this.toJSON(),n,i,r;o.undoManager.transact(function(){var c=t.type;s(d,function(s){o.dom.setAttrib(s,"scope",t.scope),o.dom.setStyles(s,{height:a(t.height)}),c!=s.parentNode.nodeName.toLowerCase()&&(n=e.getParent(s,"table"),i=s.parentNode,r=e.select(c,n)[0],r||(r=e.create(c),n.firstChild?n.insertBefore(r,n.firstChild):n.appendChild(r)),r.appendChild(s),i.hasChildNodes()||e.remove(i)),l(s),t.align&&o.formatter.apply("align"+t.align,{},s)}),o.focus()})}}))}function p(e){return function(){o.execCommand(e)}}function g(e,t){var n,i,a;for(a='',n=0;t>n;n++){for(a+="",i=0;e>i;i++)a+="";a+=""}a+="
"+(r.ie?" ":"
")+"
",o.insertContent(a);var l=o.dom.get("__mce");return o.dom.setAttrib(l,"id",null),l}function h(e,t){function n(){e.disabled(!o.dom.getParent(o.selection.getStart(),t)),o.selection.selectorChanged(t,function(t){e.disabled(!t)})}o.initialized?n():o.on("init",n)}function v(){h(this,"table")}function b(){h(this,"td,th")}function y(){var e="";e='';for(var t=0;10>t;t++){e+="";for(var n=0;10>n;n++)e+='';e+=""}return e+="
",e+='

'}function w(e,t,n){var i=n.getEl().getElementsByTagName("table")[0],r,a,l,s,c,d=n.isRtl()||"tl-tr"==n.parent().rel;for(i.nextSibling.innerHTML=e+1+" x "+(t+1),d&&(e=9-e),a=0;10>a;a++)for(r=0;10>r;r++)s=i.rows[a].childNodes[r].firstChild,c=(d?r>=e:e>=r)&&t>=a,o.dom.toggleClass(s,"mce-active",c),c&&(l=s);return l.parentNode}var x,C,P=this;o.settings.table_grid===!1?o.addMenuItem("inserttable",{text:"Insert table",icon:"table",context:"table",onclick:d}):o.addMenuItem("inserttable",{text:"Insert table",icon:"table",context:"table",ariaHideMenu:!0,onclick:function(e){e.aria&&(this.parent().hideAll(),e.stopImmediatePropagation(),d())},onshow:function(){w(0,0,this.menu.items()[0])},onhide:function(){var e=this.menu.items()[0].getEl().getElementsByTagName("a");o.dom.removeClass(e,"mce-active"),o.dom.addClass(e[0],"mce-active")},menu:[{type:"container",html:y(),onPostRender:function(){this.lastX=this.lastY=0},onmousemove:function(e){var t=e.target,n,o;"A"==t.tagName.toUpperCase()&&(n=parseInt(t.getAttribute("data-mce-x"),10),o=parseInt(t.getAttribute("data-mce-y"),10),(this.isRtl()||"tl-tr"==this.parent().rel)&&(n=9-n),(n!==this.lastX||o!==this.lastY)&&(w(n,o,e.control),this.lastX=n,this.lastY=o))},onkeydown:function(e){var t=this.lastX,n=this.lastY,o;switch(e.keyCode){case 37:t>0&&(t--,o=!0);break;case 39:o=!0,9>t&&t++;break;case 38:o=!0,n>0&&n--;break;case 40:o=!0,9>n&&n++}o&&(e.preventDefault(),e.stopPropagation(),w(t,n,e.control).focus(),this.lastX=t,this.lastY=n)},onclick:function(e){"A"==e.target.tagName.toUpperCase()&&(e.preventDefault(),e.stopPropagation(),this.parent().cancel(),g(this.lastX+1,this.lastY+1))}}]}),o.addMenuItem("tableprops",{text:"Table properties",context:"table",onPostRender:v,onclick:d}),o.addMenuItem("deletetable",{text:"Delete table",context:"table",onPostRender:v,cmd:"mceTableDelete"}),o.addMenuItem("cell",{separator:"before",text:"Cell",context:"table",menu:[{text:"Cell properties",onclick:p("mceTableCellProps"),onPostRender:b},{text:"Merge cells",onclick:p("mceTableMergeCells"),onPostRender:b},{text:"Split cell",onclick:p("mceTableSplitCells"),onPostRender:b}]}),o.addMenuItem("row",{text:"Row",context:"table",menu:[{text:"Insert row before",onclick:p("mceTableInsertRowBefore"),onPostRender:b},{text:"Insert row after",onclick:p("mceTableInsertRowAfter"),onPostRender:b},{text:"Delete row",onclick:p("mceTableDeleteRow"),onPostRender:b},{text:"Row properties",onclick:p("mceTableRowProps"),onPostRender:b},{text:"-"},{text:"Cut row",onclick:p("mceTableCutRow"),onPostRender:b},{text:"Copy row",onclick:p("mceTableCopyRow"),onPostRender:b},{text:"Paste row before",onclick:p("mceTablePasteRowBefore"),onPostRender:b},{text:"Paste row after",onclick:p("mceTablePasteRowAfter"),onPostRender:b}]}),o.addMenuItem("column",{text:"Column",context:"table",menu:[{text:"Insert column before",onclick:p("mceTableInsertColBefore"),onPostRender:b},{text:"Insert column after",onclick:p("mceTableInsertColAfter"),onPostRender:b},{text:"Delete column",onclick:p("mceTableDeleteCol"),onPostRender:b}]});var S=[];s("inserttable tableprops deletetable | cell row column".split(" "),function(e){S.push("|"==e?{text:"-"}:o.menuItems[e])}),o.addButton("table",{type:"menubutton",title:"Table",menu:S}),r.isIE||o.on("click",function(e){e=e.target,"TABLE"===e.nodeName&&(o.selection.select(e),o.nodeChanged())}),P.quirks=new t(o),o.on("Init",function(){x=o.windowManager,P.cellSelection=new n(o)}),s({mceTableSplitCells:function(e){e.split()},mceTableMergeCells:function(e){var t,n,i;i=o.dom.getParent(o.selection.getStart(),"th,td"),i&&(t=i.rowSpan,n=i.colSpan),o.dom.select("td.mce-item-selected,th.mce-item-selected").length?e.merge():u(e,i)},mceTableInsertRowBefore:function(e){e.insertRow(!0)},mceTableInsertRowAfter:function(e){e.insertRow()},mceTableInsertColBefore:function(e){e.insertCol(!0)},mceTableInsertColAfter:function(e){e.insertCol()},mceTableDeleteCol:function(e){e.deleteCols()},mceTableDeleteRow:function(e){e.deleteRows()},mceTableCutRow:function(e){C=e.cutRows()},mceTableCopyRow:function(e){C=e.copyRows()},mceTablePasteRowBefore:function(e){e.pasteRows(C,!0)},mceTablePasteRowAfter:function(e){e.pasteRows(C)},mceTableDelete:function(e){e.deleteTable()}},function(t,n){o.addCommand(n,function(){var n=new e(o);n&&(t(n),o.execCommand("mceRepaint"),P.cellSelection.clear())})}),s({mceInsertTable:function(){d()},mceTableRowProps:m,mceTableCellProps:f},function(e,t){o.addCommand(t,function(t,n){e(n)})})}var s=o.each;a.add("table",l)}),a([s,u,m,g])}(this);tinymce.PluginManager.add("template",function(e){function t(t){return function(){var a=e.settings.templates;"string"==typeof a?tinymce.util.XHR.send({url:a,success:function(e){t(tinymce.util.JSON.parse(e))}}):t(a)}}function a(t){function a(t){function a(t){if(-1==t.indexOf("")){var a="";tinymce.each(e.contentCSS,function(t){a+=''}),t=""+a+""+t+""}t=r(t,"template_preview_replace_values");var l=n.find("iframe")[0].getEl().contentWindow.document;l.open(),l.write(t),l.close()}var c=t.control.value();c.url?tinymce.util.XHR.send({url:c.url,success:function(e){l=e,a(l)}}):(l=c.content,a(l)),n.find("#description")[0].text(t.control.value().description)}var n,l,i=[];return t&&0!==t.length?(tinymce.each(t,function(e){i.push({selected:!i.length,text:e.title,value:{url:e.url,content:e.content,description:e.description}})}),n=e.windowManager.open({title:"Insert template",layout:"flex",direction:"column",align:"stretch",padding:15,spacing:10,items:[{type:"form",flex:0,padding:0,items:[{type:"container",label:"Templates",items:{type:"listbox",label:"Templates",name:"template",values:i,onselect:a}}]},{type:"label",name:"description",label:"Description",text:" "},{type:"iframe",flex:1,border:1}],onsubmit:function(){c(!1,l)},width:e.getParam("template_popup_width",600),height:e.getParam("template_popup_height",500)}),void n.find("listbox")[0].fire("select")):void e.windowManager.alert("No templates defined")}function n(t,a){function n(e,t){if(e=""+e,e.length0&&(o=p.create("div",null),o.appendChild(s[0].cloneNode(!0))),i(p.select("*",o),function(t){c(t,e.getParam("template_cdate_classes","cdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_cdate_format",e.getLang("template.cdate_format")))),c(t,e.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_mdate_format",e.getLang("template.mdate_format")))),c(t,e.getParam("template_selected_content_classes","selcontent").replace(/\s+/g,"|"))&&(t.innerHTML=m)}),l(o),e.execCommand("mceInsertContent",!1,o.innerHTML),e.addVisual()}var i=tinymce.each;e.addCommand("mceInsertTemplate",c),e.addButton("template",{title:"Insert template",onclick:t(a)}),e.addMenuItem("template",{text:"Insert template",onclick:t(a),context:"insert"}),e.on("PreProcess",function(t){var a=e.dom;i(a.select("div",t.node),function(t){a.hasClass(t,"mceTmpl")&&(i(a.select("*",t),function(t){a.hasClass(t,e.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_mdate_format",e.getLang("template.mdate_format"))))}),l(t))})})});tinymce.PluginManager.add("textcolor",function(e){function t(){var t,o,l=[];for(o=e.settings.textcolor_map||["000000","Black","993300","Burnt orange","333300","Dark olive","003300","Dark green","003366","Dark azure","000080","Navy Blue","333399","Indigo","333333","Very dark gray","800000","Maroon","FF6600","Orange","808000","Olive","008000","Green","008080","Teal","0000FF","Blue","666699","Grayish blue","808080","Gray","FF0000","Red","FF9900","Amber","99CC00","Yellow green","339966","Sea green","33CCCC","Turquoise","3366FF","Royal blue","800080","Purple","999999","Medium gray","FF00FF","Magenta","FFCC00","Gold","FFFF00","Yellow","00FF00","Lime","00FFFF","Aqua","00CCFF","Sky blue","993366","Red violet","C0C0C0","Silver","FF99CC","Pink","FFCC99","Peach","FFFF99","Light yellow","CCFFCC","Pale green","CCFFFF","Pale cyan","99CCFF","Light sky blue","CC99FF","Plum","FFFFFF","White"],t=0;t',a=o.length-1,c=e.settings.textcolor_rows||5,i=e.settings.textcolor_cols||8,F=0;c>F;F++){for(r+="",n=0;i>n;n++)d=F*i+n,d>a?r+="":(l=o[d],r+='
');r+=""}return r+=""}function l(t){var o,l=this.parent();(o=t.target.getAttribute("data-mce-color"))&&(this.lastId&&document.getElementById(this.lastId).setAttribute("aria-selected",!1),t.target.setAttribute("aria-selected",!0),this.lastId=t.target.id,l.hidePanel(),o="#"+o,l.color(o),e.execCommand(l.settings.selectcmd,!1,o))}function r(){var t=this;t._color&&e.execCommand(t.settings.selectcmd,!1,t._color)}e.addButton("forecolor",{type:"colorbutton",tooltip:"Text color",selectcmd:"ForeColor",panel:{role:"application",ariaRemember:!0,html:o,onclick:l},onclick:r}),e.addButton("backcolor",{type:"colorbutton",tooltip:"Background color",selectcmd:"HiliteColor",panel:{role:"application",ariaRemember:!0,html:o,onclick:l},onclick:r})});tinymce.PluginManager.add("visualblocks",function(e,s){function o(){var s=this;s.active(a),e.on("VisualBlocks",function(){s.active(e.dom.hasClass(e.getBody(),"mce-visualblocks"))})}var l,t,a;window.NodeList&&(e.addCommand("mceVisualBlocks",function(){var o,c=e.dom;l||(l=c.uniqueId(),o=c.create("link",{id:l,rel:"stylesheet",href:s+"/css/visualblocks.css"}),e.getDoc().getElementsByTagName("head")[0].appendChild(o)),e.on("PreviewFormats AfterPreviewFormats",function(s){a&&c.toggleClass(e.getBody(),"mce-visualblocks","afterpreviewformats"==s.type)}),c.toggleClass(e.getBody(),"mce-visualblocks"),a=e.dom.hasClass(e.getBody(),"mce-visualblocks"),t&&t.active(c.hasClass(e.getBody(),"mce-visualblocks")),e.fire("VisualBlocks")}),e.addButton("visualblocks",{title:"Show blocks",cmd:"mceVisualBlocks",onPostRender:o}),e.addMenuItem("visualblocks",{text:"Show blocks",cmd:"mceVisualBlocks",onPostRender:o,selectable:!0,context:"view",prependToContext:!0}),e.on("init",function(){e.settings.visualblocks_default_state&&e.execCommand("mceVisualBlocks",!1,null,{skip_focus:!0})}),e.on("remove",function(){e.dom.removeClass(e.getBody(),"mce-visualblocks")}))});tinymce.PluginManager.add("visualchars",function(e){function a(a){var t,s,i,r,c,d,l=e.getBody(),m=e.selection;if(n=!n,o.state=n,e.fire("VisualChars",{state:n}),a&&(d=m.getBookmark()),n)for(s=[],tinymce.walk(l,function(e){3==e.nodeType&&e.nodeValue&&-1!=e.nodeValue.indexOf(" ")&&s.push(e)},"childNodes"),i=0;i$1
'),c=e.dom.create("div",null,r);t=c.lastChild;)e.dom.insertAfter(t,s[i]);e.dom.remove(s[i])}else for(s=e.dom.select("span.mce-nbsp",l),i=s.length-1;i>=0;i--)e.dom.remove(s[i],1);m.moveToBookmark(d)}function t(){var a=this;e.on("VisualChars",function(e){a.active(e.state)})}var n,o=this;e.addCommand("mceVisualChars",a),e.addButton("visualchars",{title:"Show invisible characters",cmd:"mceVisualChars",onPostRender:t}),e.addMenuItem("visualchars",{text:"Show invisible characters",cmd:"mceVisualChars",onPostRender:t,selectable:!0,context:"view",prependToContext:!0}),e.on("beforegetcontent",function(e){n&&"raw"!=e.format&&!e.draft&&(n=!0,a(!1))})});tinymce.PluginManager.add("wordcount",function(e){function t(){e.theme.panel.find("#wordcount").text(["Words: {0}",a.getCount()])}var n,o,a=this;n=e.getParam("wordcount_countregex",/[\w\u2019\x27\-\u00C0-\u1FFF]+/g),o=e.getParam("wordcount_cleanregex",/[0-9.(),;:!?%#$?\x27\x22_+=\\\/\-]*/g),e.on("init",function(){var n=e.theme.panel&&e.theme.panel.find("#statusbar")[0];n&&window.setTimeout(function(){n.insert({type:"label",name:"wordcount",text:["Words: {0}",a.getCount()],classes:"wordcount",disabled:e.settings.readonly},0),e.on("setcontent beforeaddundo",t),e.on("keyup",function(e){32==e.keyCode&&t()})},0)}),a.getCount=function(){var t=e.getContent({format:"raw"}),a=0;if(t){t=t.replace(/\.\.\./g," "),t=t.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," "),t=t.replace(/(\w+)(&#?[a-z0-9]+;)+(\w+)/i,"$1$3").replace(/&.+?;/g," "),t=t.replace(o,"");var r=t.match(n);r&&(a=r.length)}return a}});tinymce.ThemeManager.add("modern",function(e){function t(){function t(t){var n,o=[];if(t)return d(t.split(/[ ,]/),function(t){function i(){var i=e.selection;"bullist"==r&&i.selectorChanged("ul > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"UL"==n)}),"numlist"==r&&i.selectorChanged("ol > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"OL"==n)}),t.settings.stateSelector&&i.selectorChanged(t.settings.stateSelector,function(e){t.active(e)},!0),t.settings.disabledStateSelector&&i.selectorChanged(t.settings.disabledStateSelector,function(e){t.disabled(e)})}var r;"|"==t?n=null:c.has(t)?(t={type:t},u.toolbar_items_size&&(t.size=u.toolbar_items_size),o.push(t),n=null):(n||(n={type:"buttongroup",items:[]},o.push(n)),e.buttons[t]&&(r=t,t=e.buttons[r],"function"==typeof t&&(t=t()),t.type=t.type||"button",u.toolbar_items_size&&(t.size=u.toolbar_items_size),t=c.create(t),n.items.push(t),e.initialized?i():e.on("init",i)))}),i.push({type:"toolbar",layout:"flow",items:o}),!0}var i=[];if(tinymce.isArray(u.toolbar)){if(0===u.toolbar.length)return;tinymce.each(u.toolbar,function(e,t){u["toolbar"+(t+1)]=e}),delete u.toolbar}for(var n=1;10>n&&t(u["toolbar"+n]);n++);return i.length||u.toolbar===!1||t(u.toolbar||f),i.length?{type:"panel",layout:"stack",classes:"toolbar-grp",ariaRoot:!0,ariaRemember:!0,items:i}:void 0}function i(){function t(t){var i;return"|"==t?{text:"|"}:i=e.menuItems[t]}function i(i){var n,o,r,a,s;if(s=tinymce.makeMap((u.removed_menuitems||"").split(/[ ,]/)),u.menu?(o=u.menu[i],a=!0):o=h[i],o){n={text:o.title},r=[],d((o.items||"").split(/[ ,]/),function(e){var i=t(e);i&&!s[e]&&r.push(t(e))}),a||d(e.menuItems,function(e){e.context==i&&("before"==e.separator&&r.push({text:"|"}),e.prependToContext?r.unshift(e):r.push(e),"after"==e.separator&&r.push({text:"|"}))});for(var l=0;l +
Pressing "a" while this checkbox is + focused will remove it from the DOM.
+
+
+ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/keyboard_shortcut.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/keyboard_shortcut.html new file mode 100644 index 0000000..741d7f4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/keyboard_shortcut.html @@ -0,0 +1,36 @@ + + +
CTRL + 1: red
+
SHIFT + 1: green
+
CTRL + SHIFT + 1: yellow
+
ALT + 1: lightblue
+
CTRL + ALT + 1: lightgreen
+
SHIFT + ALT + 1: silver
+
CTRL + SHIFT + ALT + 1: magenta
+ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/linked_image.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/linked_image.html new file mode 100644 index 0000000..7c8df00 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/linked_image.html @@ -0,0 +1,16 @@ + + + + +Linking with an image + + +banner
+Click here for next page
+
+link to other link
+Just another link.
+

+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected.html new file mode 100644 index 0000000..42b0442 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected.html @@ -0,0 +1,13 @@ + + + Boolean Attribute Selected + + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected_html4.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected_html4.html new file mode 100644 index 0000000..60cd033 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected_html4.html @@ -0,0 +1,13 @@ + + + Boolean Attribute Selected + + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/longContentPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/longContentPage.html new file mode 100644 index 0000000..99a45e7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/longContentPage.html @@ -0,0 +1,55 @@ + + + TouchLongContent + + + +

Touch API

+

Page with long content

+
                   



+

Long text:                                                                                                                          This is a very long text to make the screen horizontally movable, to test the flick gesture at a long horizontal distance Normal link                                                                                                                                           at normal and fast speeds to see results of it Normal link end

+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+ Middle of the screen Normal link +










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+










+ Bottom of the screen Normal link


+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/macbeth.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/macbeth.html new file mode 100644 index 0000000..9fa39d5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/macbeth.html @@ -0,0 +1,5255 @@ + + + + Macbeth: Entire Play + + + + + + + +Quick link to last speech + +

ACT I

+

SCENE I. A desert place.

+

+Thunder and lightning. Enter three Witches +
+ +First Witch +
+When shall we three meet again
+In thunder, lightning, or in rain?
+
+ +Second Witch +
+When the hurlyburly's done,
+When the battle's lost and won.
+
+ +Third Witch +
+That will be ere the set of sun.
+
+ +First Witch +
+Where the place?
+
+ +Second Witch +
+ Upon the heath.
+
+ +Third Witch +
+There to meet with Macbeth.
+
+ +First Witch +
+I come, Graymalkin!
+
+ +Second Witch +
+Paddock calls.
+
+ +Third Witch +
+Anon.
+
+ +ALL +
+Fair is foul, and foul is fair:
+Hover through the fog and filthy air.
+

Exeunt

+
+

SCENE II. A camp near Forres.

+

+Alarum within. Enter DUNCAN, MALCOLM, DONALBAIN, LENNOX, with Attendants, meeting a bleeding Sergeant +
+ +DUNCAN +
+What bloody man is that? He can report,
+As seemeth by his plight, of the revolt
+The newest state.
+
+ +MALCOLM +
+ This is the sergeant
+Who like a good and hardy soldier fought
+'Gainst my captivity. Hail, brave friend!
+Say to the king the knowledge of the broil
+As thou didst leave it.
+
+ +Sergeant +
+Doubtful it stood;
+As two spent swimmers, that do cling together
+And choke their art. The merciless Macdonwald--
+Worthy to be a rebel, for to that
+The multiplying villanies of nature
+Do swarm upon him--from the western isles
+Of kerns and gallowglasses is supplied;
+And fortune, on his damned quarrel smiling,
+Show'd like a rebel's whore: but all's too weak:
+For brave Macbeth--well he deserves that name--
+Disdaining fortune, with his brandish'd steel,
+Which smoked with bloody execution,
+Like valour's minion carved out his passage
+Till he faced the slave;
+Which ne'er shook hands, nor bade farewell to him,
+Till he unseam'd him from the nave to the chaps,
+And fix'd his head upon our battlements.
+
+ +DUNCAN +
+O valiant cousin! worthy gentleman!
+
+ +Sergeant +
+As whence the sun 'gins his reflection
+Shipwrecking storms and direful thunders break,
+So from that spring whence comfort seem'd to come
+Discomfort swells. Mark, king of Scotland, mark:
+No sooner justice had with valour arm'd
+Compell'd these skipping kerns to trust their heels,
+But the Norweyan lord surveying vantage,
+With furbish'd arms and new supplies of men
+Began a fresh assault.
+
+ +DUNCAN +
+Dismay'd not this
+Our captains, Macbeth and Banquo?
+
+ +Sergeant +
+Yes;
+As sparrows eagles, or the hare the lion.
+If I say sooth, I must report they were
+As cannons overcharged with double cracks, so they
+Doubly redoubled strokes upon the foe:
+Except they meant to bathe in reeking wounds,
+Or memorise another Golgotha,
+I cannot tell.
+But I am faint, my gashes cry for help.
+
+ +DUNCAN +
+So well thy words become thee as thy wounds;
+They smack of honour both. Go get him surgeons.
+

Exit Sergeant, attended

+Who comes here?
+

Enter ROSS

+
+ +MALCOLM +
+ The worthy thane of Ross.
+
+ +LENNOX +
+What a haste looks through his eyes! So should he look
+That seems to speak things strange.
+
+ +ROSS +
+God save the king!
+
+ +DUNCAN +
+Whence camest thou, worthy thane?
+
+ +ROSS +
+From Fife, great king;
+Where the Norweyan banners flout the sky
+And fan our people cold. Norway himself,
+With terrible numbers,
+Assisted by that most disloyal traitor
+The thane of Cawdor, began a dismal conflict;
+Till that Bellona's bridegroom, lapp'd in proof,
+Confronted him with self-comparisons,
+Point against point rebellious, arm 'gainst arm.
+Curbing his lavish spirit: and, to conclude,
+The victory fell on us.
+
+ +DUNCAN +
+Great happiness!
+
+ +ROSS +
+That now
+Sweno, the Norways' king, craves composition:
+Nor would we deign him burial of his men
+Till he disbursed at Saint Colme's inch
+Ten thousand dollars to our general use.
+
+ +DUNCAN +
+No more that thane of Cawdor shall deceive
+Our bosom interest: go pronounce his present death,
+And with his former title greet Macbeth.
+
+ +ROSS +
+I'll see it done.
+
+ +DUNCAN +
+What he hath lost noble Macbeth hath won.
+

Exeunt

+
+

SCENE III. A heath near Forres.

+

+Thunder. Enter the three Witches +
+ +First Witch +
+Where hast thou been, sister?
+
+ +Second Witch +
+Killing swine.
+
+ +Third Witch +
+Sister, where thou?
+
+ +First Witch +
+A sailor's wife had chestnuts in her lap,
+And munch'd, and munch'd, and munch'd:--
+'Give me,' quoth I:
+'Aroint thee, witch!' the rump-fed ronyon cries.
+Her husband's to Aleppo gone, master o' the Tiger:
+But in a sieve I'll thither sail,
+And, like a rat without a tail,
+I'll do, I'll do, and I'll do.
+
+ +Second Witch +
+I'll give thee a wind.
+
+ +First Witch +
+Thou'rt kind.
+
+ +Third Witch +
+And I another.
+
+ +First Witch +
+I myself have all the other,
+And the very ports they blow,
+All the quarters that they know
+I' the shipman's card.
+I will drain him dry as hay:
+Sleep shall neither night nor day
+Hang upon his pent-house lid;
+He shall live a man forbid:
+Weary se'nnights nine times nine
+Shall he dwindle, peak and pine:
+Though his bark cannot be lost,
+Yet it shall be tempest-tost.
+Look what I have.
+
+ +Second Witch +
+Show me, show me.
+
+ +First Witch +
+Here I have a pilot's thumb,
+Wreck'd as homeward he did come.
+

Drum within

+
+ +Third Witch +
+A drum, a drum!
+Macbeth doth come.
+
+ +ALL +
+The weird sisters, hand in hand,
+Posters of the sea and land,
+Thus do go about, about:
+Thrice to thine and thrice to mine
+And thrice again, to make up nine.
+Peace! the charm's wound up.
+

Enter MACBETH and BANQUO

+
+ +MACBETH +
+So foul and fair a day I have not seen.
+
+ +BANQUO +
+How far is't call'd to Forres? What are these
+So wither'd and so wild in their attire,
+That look not like the inhabitants o' the earth,
+And yet are on't? Live you? or are you aught
+That man may question? You seem to understand me,
+By each at once her chappy finger laying
+Upon her skinny lips: you should be women,
+And yet your beards forbid me to interpret
+That you are so.
+
+ +MACBETH +
+ Speak, if you can: what are you?
+
+ +First Witch +
+All hail, Macbeth! hail to thee, thane of Glamis!
+
+ +Second Witch +
+All hail, Macbeth, hail to thee, thane of Cawdor!
+
+ +Third Witch +
+All hail, Macbeth, thou shalt be king hereafter!
+
+ +BANQUO +
+Good sir, why do you start; and seem to fear
+Things that do sound so fair? I' the name of truth,
+Are ye fantastical, or that indeed
+Which outwardly ye show? My noble partner
+You greet with present grace and great prediction
+Of noble having and of royal hope,
+That he seems rapt withal: to me you speak not.
+If you can look into the seeds of time,
+And say which grain will grow and which will not,
+Speak then to me, who neither beg nor fear
+Your favours nor your hate.
+
+ +First Witch +
+Hail!
+
+ +Second Witch +
+Hail!
+
+ +Third Witch +
+Hail!
+
+ +First Witch +
+Lesser than Macbeth, and greater.
+
+ +Second Witch +
+Not so happy, yet much happier.
+
+ +Third Witch +
+Thou shalt get kings, though thou be none:
+So all hail, Macbeth and Banquo!
+
+ +First Witch +
+Banquo and Macbeth, all hail!
+
+ +MACBETH +
+Stay, you imperfect speakers, tell me more:
+By Sinel's death I know I am thane of Glamis;
+But how of Cawdor? the thane of Cawdor lives,
+A prosperous gentleman; and to be king
+Stands not within the prospect of belief,
+No more than to be Cawdor. Say from whence
+You owe this strange intelligence? or why
+Upon this blasted heath you stop our way
+With such prophetic greeting? Speak, I charge you.
+

Witches vanish

+
+ +BANQUO +
+The earth hath bubbles, as the water has,
+And these are of them. Whither are they vanish'd?
+
+ +MACBETH +
+Into the air; and what seem'd corporal melted
+As breath into the wind. Would they had stay'd!
+
+ +BANQUO +
+Were such things here as we do speak about?
+Or have we eaten on the insane root
+That takes the reason prisoner?
+
+ +MACBETH +
+Your children shall be kings.
+
+ +BANQUO +
+You shall be king.
+
+ +MACBETH +
+And thane of Cawdor too: went it not so?
+
+ +BANQUO +
+To the selfsame tune and words. Who's here?
+

Enter ROSS and ANGUS

+
+ +ROSS +
+The king hath happily received, Macbeth,
+The news of thy success; and when he reads
+Thy personal venture in the rebels' fight,
+His wonders and his praises do contend
+Which should be thine or his: silenced with that,
+In viewing o'er the rest o' the selfsame day,
+He finds thee in the stout Norweyan ranks,
+Nothing afeard of what thyself didst make,
+Strange images of death. As thick as hail
+Came post with post; and every one did bear
+Thy praises in his kingdom's great defence,
+And pour'd them down before him.
+
+ +ANGUS +
+We are sent
+To give thee from our royal master thanks;
+Only to herald thee into his sight,
+Not pay thee.
+
+ +ROSS +
+And, for an earnest of a greater honour,
+He bade me, from him, call thee thane of Cawdor:
+In which addition, hail, most worthy thane!
+For it is thine.
+
+ +BANQUO +
+ What, can the devil speak true?
+
+ +MACBETH +
+The thane of Cawdor lives: why do you dress me
+In borrow'd robes?
+
+ +ANGUS +
+ Who was the thane lives yet;
+But under heavy judgment bears that life
+Which he deserves to lose. Whether he was combined
+With those of Norway, or did line the rebel
+With hidden help and vantage, or that with both
+He labour'd in his country's wreck, I know not;
+But treasons capital, confess'd and proved,
+Have overthrown him.
+
+ +MACBETH +
+[Aside] Glamis, and thane of Cawdor!
+The greatest is behind.
+

To ROSS and ANGUS

+Thanks for your pains.
+

To BANQUO

+Do you not hope your children shall be kings,
+When those that gave the thane of Cawdor to me
+Promised no less to them?
+
+ +BANQUO +
+That trusted home
+Might yet enkindle you unto the crown,
+Besides the thane of Cawdor. But 'tis strange:
+And oftentimes, to win us to our harm,
+The instruments of darkness tell us truths,
+Win us with honest trifles, to betray's
+In deepest consequence.
+Cousins, a word, I pray you.
+
+ +MACBETH +
+[Aside] Two truths are told,
+As happy prologues to the swelling act
+Of the imperial theme.--I thank you, gentlemen.
+

Aside

+Cannot be ill, cannot be good: if ill,
+Why hath it given me earnest of success,
+Commencing in a truth? I am thane of Cawdor:
+If good, why do I yield to that suggestion
+Whose horrid image doth unfix my hair
+And make my seated heart knock at my ribs,
+Against the use of nature? Present fears
+Are less than horrible imaginings:
+My thought, whose murder yet is but fantastical,
+Shakes so my single state of man that function
+Is smother'd in surmise, and nothing is
+But what is not.
+
+ +BANQUO +
+ Look, how our partner's rapt.
+
+ +MACBETH +
+[Aside] If chance will have me king, why, chance may crown me,
+Without my stir.
+
+ +BANQUO +
+ New horrors come upon him,
+Like our strange garments, cleave not to their mould
+But with the aid of use.
+
+ +MACBETH +
+[Aside] Come what come may,
+Time and the hour runs through the roughest day.
+
+ +BANQUO +
+Worthy Macbeth, we stay upon your leisure.
+
+ +MACBETH +
+Give me your favour: my dull brain was wrought
+With things forgotten. Kind gentlemen, your pains
+Are register'd where every day I turn
+The leaf to read them. Let us toward the king.
+Think upon what hath chanced, and, at more time,
+The interim having weigh'd it, let us speak
+Our free hearts each to other.
+
+ +BANQUO +
+Very gladly.
+
+ +MACBETH +
+Till then, enough. Come, friends.
+

Exeunt

+
+

SCENE IV. Forres. The palace.

+

+Flourish. Enter DUNCAN, MALCOLM, DONALBAIN, LENNOX, and Attendants +
+ +DUNCAN +
+Is execution done on Cawdor? Are not
+Those in commission yet return'd?
+
+ +MALCOLM +
+My liege,
+They are not yet come back. But I have spoke
+With one that saw him die: who did report
+That very frankly he confess'd his treasons,
+Implored your highness' pardon and set forth
+A deep repentance: nothing in his life
+Became him like the leaving it; he died
+As one that had been studied in his death
+To throw away the dearest thing he owed,
+As 'twere a careless trifle.
+
+ +DUNCAN +
+There's no art
+To find the mind's construction in the face:
+He was a gentleman on whom I built
+An absolute trust.
+

Enter MACBETH, BANQUO, ROSS, and ANGUS

+O worthiest cousin!
+The sin of my ingratitude even now
+Was heavy on me: thou art so far before
+That swiftest wing of recompense is slow
+To overtake thee. Would thou hadst less deserved,
+That the proportion both of thanks and payment
+Might have been mine! only I have left to say,
+More is thy due than more than all can pay.
+
+ +MACBETH +
+The service and the loyalty I owe,
+In doing it, pays itself. Your highness' part
+Is to receive our duties; and our duties
+Are to your throne and state children and servants,
+Which do but what they should, by doing every thing
+Safe toward your love and honour.
+
+ +DUNCAN +
+Welcome hither:
+I have begun to plant thee, and will labour
+To make thee full of growing. Noble Banquo,
+That hast no less deserved, nor must be known
+No less to have done so, let me enfold thee
+And hold thee to my heart.
+
+ +BANQUO +
+There if I grow,
+The harvest is your own.
+
+ +DUNCAN +
+My plenteous joys,
+Wanton in fulness, seek to hide themselves
+In drops of sorrow. Sons, kinsmen, thanes,
+And you whose places are the nearest, know
+We will establish our estate upon
+Our eldest, Malcolm, whom we name hereafter
+The Prince of Cumberland; which honour must
+Not unaccompanied invest him only,
+But signs of nobleness, like stars, shall shine
+On all deservers. From hence to Inverness,
+And bind us further to you.
+
+ +MACBETH +
+The rest is labour, which is not used for you:
+I'll be myself the harbinger and make joyful
+The hearing of my wife with your approach;
+So humbly take my leave.
+
+ +DUNCAN +
+My worthy Cawdor!
+
+ +MACBETH +
+[Aside] The Prince of Cumberland! that is a step
+On which I must fall down, or else o'erleap,
+For in my way it lies. Stars, hide your fires;
+Let not light see my black and deep desires:
+The eye wink at the hand; yet let that be,
+Which the eye fears, when it is done, to see.
+

Exit

+
+ +DUNCAN +
+True, worthy Banquo; he is full so valiant,
+And in his commendations I am fed;
+It is a banquet to me. Let's after him,
+Whose care is gone before to bid us welcome:
+It is a peerless kinsman.
+

Flourish. Exeunt

+
+

SCENE V. Inverness. Macbeth's castle.

+

+Enter LADY MACBETH, reading a letter +
+ +LADY MACBETH +
+'They met me in the day of success: and I have
+learned by the perfectest report, they have more in
+them than mortal knowledge. When I burned in desire
+to question them further, they made themselves air,
+into which they vanished. Whiles I stood rapt in
+the wonder of it, came missives from the king, who
+all-hailed me 'Thane of Cawdor;' by which title,
+before, these weird sisters saluted me, and referred
+me to the coming on of time, with 'Hail, king that
+shalt be!' This have I thought good to deliver
+thee, my dearest partner of greatness, that thou
+mightst not lose the dues of rejoicing, by being
+ignorant of what greatness is promised thee. Lay it
+to thy heart, and farewell.'
+Glamis thou art, and Cawdor; and shalt be
+What thou art promised: yet do I fear thy nature;
+It is too full o' the milk of human kindness
+To catch the nearest way: thou wouldst be great;
+Art not without ambition, but without
+The illness should attend it: what thou wouldst highly,
+That wouldst thou holily; wouldst not play false,
+And yet wouldst wrongly win: thou'ldst have, great Glamis,
+That which cries 'Thus thou must do, if thou have it;
+And that which rather thou dost fear to do
+Than wishest should be undone.' Hie thee hither,
+That I may pour my spirits in thine ear;
+And chastise with the valour of my tongue
+All that impedes thee from the golden round,
+Which fate and metaphysical aid doth seem
+To have thee crown'd withal.
+

Enter a Messenger

+What is your tidings?
+
+ +Messenger +
+The king comes here to-night.
+
+ +LADY MACBETH +
+Thou'rt mad to say it:
+Is not thy master with him? who, were't so,
+Would have inform'd for preparation.
+
+ +Messenger +
+So please you, it is true: our thane is coming:
+One of my fellows had the speed of him,
+Who, almost dead for breath, had scarcely more
+Than would make up his message.
+
+ +LADY MACBETH +
+Give him tending;
+He brings great news.
+

Exit Messenger

+The raven himself is hoarse
+That croaks the fatal entrance of Duncan
+Under my battlements. Come, you spirits
+That tend on mortal thoughts, unsex me here,
+And fill me from the crown to the toe top-full
+Of direst cruelty! make thick my blood;
+Stop up the access and passage to remorse,
+That no compunctious visitings of nature
+Shake my fell purpose, nor keep peace between
+The effect and it! Come to my woman's breasts,
+And take my milk for gall, you murdering ministers,
+Wherever in your sightless substances
+You wait on nature's mischief! Come, thick night,
+And pall thee in the dunnest smoke of hell,
+That my keen knife see not the wound it makes,
+Nor heaven peep through the blanket of the dark,
+To cry 'Hold, hold!'
+

Enter MACBETH

+Great Glamis! worthy Cawdor!
+Greater than both, by the all-hail hereafter!
+Thy letters have transported me beyond
+This ignorant present, and I feel now
+The future in the instant.
+
+ +MACBETH +
+My dearest love,
+Duncan comes here to-night.
+
+ +LADY MACBETH +
+And when goes hence?
+
+ +MACBETH +
+To-morrow, as he purposes.
+
+ +LADY MACBETH +
+O, never
+Shall sun that morrow see!
+Your face, my thane, is as a book where men
+May read strange matters. To beguile the time,
+Look like the time; bear welcome in your eye,
+Your hand, your tongue: look like the innocent flower,
+But be the serpent under't. He that's coming
+Must be provided for: and you shall put
+This night's great business into my dispatch;
+Which shall to all our nights and days to come
+Give solely sovereign sway and masterdom.
+
+ +MACBETH +
+We will speak further.
+
+ +LADY MACBETH +
+Only look up clear;
+To alter favour ever is to fear:
+Leave all the rest to me.
+

Exeunt

+
+

SCENE VI. Before Macbeth's castle.

+

+Hautboys and torches. Enter DUNCAN, MALCOLM, DONALBAIN, BANQUO, LENNOX, MACDUFF, ROSS, ANGUS, and Attendants +
+ +DUNCAN +
+This castle hath a pleasant seat; the air
+Nimbly and sweetly recommends itself
+Unto our gentle senses.
+
+ +BANQUO +
+This guest of summer,
+The temple-haunting martlet, does approve,
+By his loved mansionry, that the heaven's breath
+Smells wooingly here: no jutty, frieze,
+Buttress, nor coign of vantage, but this bird
+Hath made his pendent bed and procreant cradle:
+Where they most breed and haunt, I have observed,
+The air is delicate.
+

Enter LADY MACBETH

+
+ +DUNCAN +
+See, see, our honour'd hostess!
+The love that follows us sometime is our trouble,
+Which still we thank as love. Herein I teach you
+How you shall bid God 'ild us for your pains,
+And thank us for your trouble.
+
+ +LADY MACBETH +
+All our service
+In every point twice done and then done double
+Were poor and single business to contend
+Against those honours deep and broad wherewith
+Your majesty loads our house: for those of old,
+And the late dignities heap'd up to them,
+We rest your hermits.
+
+ +DUNCAN +
+Where's the thane of Cawdor?
+We coursed him at the heels, and had a purpose
+To be his purveyor: but he rides well;
+And his great love, sharp as his spur, hath holp him
+To his home before us. Fair and noble hostess,
+We are your guest to-night.
+
+ +LADY MACBETH +
+Your servants ever
+Have theirs, themselves and what is theirs, in compt,
+To make their audit at your highness' pleasure,
+Still to return your own.
+
+ +DUNCAN +
+Give me your hand;
+Conduct me to mine host: we love him highly,
+And shall continue our graces towards him.
+By your leave, hostess.
+

Exeunt

+
+

SCENE VII. Macbeth's castle.

+

+Hautboys and torches. Enter a Sewer, and divers Servants with dishes and service, and pass over the stage. Then enter MACBETH +
+ +MACBETH +
+If it were done when 'tis done, then 'twere well
+It were done quickly: if the assassination
+Could trammel up the consequence, and catch
+With his surcease success; that but this blow
+Might be the be-all and the end-all here,
+But here, upon this bank and shoal of time,
+We'ld jump the life to come. But in these cases
+We still have judgment here; that we but teach
+Bloody instructions, which, being taught, return
+To plague the inventor: this even-handed justice
+Commends the ingredients of our poison'd chalice
+To our own lips. He's here in double trust;
+First, as I am his kinsman and his subject,
+Strong both against the deed; then, as his host,
+Who should against his murderer shut the door,
+Not bear the knife myself. Besides, this Duncan
+Hath borne his faculties so meek, hath been
+So clear in his great office, that his virtues
+Will plead like angels, trumpet-tongued, against
+The deep damnation of his taking-off;
+And pity, like a naked new-born babe,
+Striding the blast, or heaven's cherubim, horsed
+Upon the sightless couriers of the air,
+Shall blow the horrid deed in every eye,
+That tears shall drown the wind. I have no spur
+To prick the sides of my intent, but only
+Vaulting ambition, which o'erleaps itself
+And falls on the other.
+

Enter LADY MACBETH

+How now! what news?
+
+ +LADY MACBETH +
+He has almost supp'd: why have you left the chamber?
+
+ +MACBETH +
+Hath he ask'd for me?
+
+ +LADY MACBETH +
+Know you not he has?
+
+ +MACBETH +
+We will proceed no further in this business:
+He hath honour'd me of late; and I have bought
+Golden opinions from all sorts of people,
+Which would be worn now in their newest gloss,
+Not cast aside so soon.
+
+ +LADY MACBETH +
+Was the hope drunk
+Wherein you dress'd yourself? hath it slept since?
+And wakes it now, to look so green and pale
+At what it did so freely? From this time
+Such I account thy love. Art thou afeard
+To be the same in thine own act and valour
+As thou art in desire? Wouldst thou have that
+Which thou esteem'st the ornament of life,
+And live a coward in thine own esteem,
+Letting 'I dare not' wait upon 'I would,'
+Like the poor cat i' the adage?
+
+ +MACBETH +
+Prithee, peace:
+I dare do all that may become a man;
+Who dares do more is none.
+
+ +LADY MACBETH +
+What beast was't, then,
+That made you break this enterprise to me?
+When you durst do it, then you were a man;
+And, to be more than what you were, you would
+Be so much more the man. Nor time nor place
+Did then adhere, and yet you would make both:
+They have made themselves, and that their fitness now
+Does unmake you. I have given suck, and know
+How tender 'tis to love the babe that milks me:
+I would, while it was smiling in my face,
+Have pluck'd my nipple from his boneless gums,
+And dash'd the brains out, had I so sworn as you
+Have done to this.
+
+ +MACBETH +
+ If we should fail?
+
+ +LADY MACBETH +
+We fail!
+But screw your courage to the sticking-place,
+And we'll not fail. When Duncan is asleep--
+Whereto the rather shall his day's hard journey
+Soundly invite him--his two chamberlains
+Will I with wine and wassail so convince
+That memory, the warder of the brain,
+Shall be a fume, and the receipt of reason
+A limbeck only: when in swinish sleep
+Their drenched natures lie as in a death,
+What cannot you and I perform upon
+The unguarded Duncan? what not put upon
+His spongy officers, who shall bear the guilt
+Of our great quell?
+
+ +MACBETH +
+Bring forth men-children only;
+For thy undaunted mettle should compose
+Nothing but males. Will it not be received,
+When we have mark'd with blood those sleepy two
+Of his own chamber and used their very daggers,
+That they have done't?
+
+ +LADY MACBETH +
+Who dares receive it other,
+As we shall make our griefs and clamour roar
+Upon his death?
+
+ +MACBETH +
+ I am settled, and bend up
+Each corporal agent to this terrible feat.
+Away, and mock the time with fairest show:
+False face must hide what the false heart doth know.
+

Exeunt

+

+

ACT II

+

SCENE I. Court of Macbeth's castle.

+

+Enter BANQUO, and FLEANCE bearing a torch before him +
+ +BANQUO +
+How goes the night, boy?
+
+ +FLEANCE +
+The moon is down; I have not heard the clock.
+
+ +BANQUO +
+And she goes down at twelve.
+
+ +FLEANCE +
+I take't, 'tis later, sir.
+
+ +BANQUO +
+Hold, take my sword. There's husbandry in heaven;
+Their candles are all out. Take thee that too.
+A heavy summons lies like lead upon me,
+And yet I would not sleep: merciful powers,
+Restrain in me the cursed thoughts that nature
+Gives way to in repose!
+

Enter MACBETH, and a Servant with a torch

+Give me my sword.
+Who's there?
+
+ +MACBETH +
+A friend.
+
+ +BANQUO +
+What, sir, not yet at rest? The king's a-bed:
+He hath been in unusual pleasure, and
+Sent forth great largess to your offices.
+This diamond he greets your wife withal,
+By the name of most kind hostess; and shut up
+In measureless content.
+
+ +MACBETH +
+Being unprepared,
+Our will became the servant to defect;
+Which else should free have wrought.
+
+ +BANQUO +
+All's well.
+I dreamt last night of the three weird sisters:
+To you they have show'd some truth.
+
+ +MACBETH +
+I think not of them:
+Yet, when we can entreat an hour to serve,
+We would spend it in some words upon that business,
+If you would grant the time.
+
+ +BANQUO +
+At your kind'st leisure.
+
+ +MACBETH +
+If you shall cleave to my consent, when 'tis,
+It shall make honour for you.
+
+ +BANQUO +
+So I lose none
+In seeking to augment it, but still keep
+My bosom franchised and allegiance clear,
+I shall be counsell'd.
+
+ +MACBETH +
+Good repose the while!
+
+ +BANQUO +
+Thanks, sir: the like to you!
+

Exeunt BANQUO and FLEANCE

+
+ +MACBETH +
+Go bid thy mistress, when my drink is ready,
+She strike upon the bell. Get thee to bed.
+

Exit Servant

+Is this a dagger which I see before me,
+The handle toward my hand? Come, let me clutch thee.
+I have thee not, and yet I see thee still.
+Art thou not, fatal vision, sensible
+To feeling as to sight? or art thou but
+A dagger of the mind, a false creation,
+Proceeding from the heat-oppressed brain?
+I see thee yet, in form as palpable
+As this which now I draw.
+Thou marshall'st me the way that I was going;
+And such an instrument I was to use.
+Mine eyes are made the fools o' the other senses,
+Or else worth all the rest; I see thee still,
+And on thy blade and dudgeon gouts of blood,
+Which was not so before. There's no such thing:
+It is the bloody business which informs
+Thus to mine eyes. Now o'er the one halfworld
+Nature seems dead, and wicked dreams abuse
+The curtain'd sleep; witchcraft celebrates
+Pale Hecate's offerings, and wither'd murder,
+Alarum'd by his sentinel, the wolf,
+Whose howl's his watch, thus with his stealthy pace.
+With Tarquin's ravishing strides, towards his design
+Moves like a ghost. Thou sure and firm-set earth,
+Hear not my steps, which way they walk, for fear
+Thy very stones prate of my whereabout,
+And take the present horror from the time,
+Which now suits with it. Whiles I threat, he lives:
+Words to the heat of deeds too cold breath gives.
+

A bell rings

+I go, and it is done; the bell invites me.
+Hear it not, Duncan; for it is a knell
+That summons thee to heaven or to hell.
+

Exit

+
+

SCENE II. The same.

+

+Enter LADY MACBETH +
+ +LADY MACBETH +
+That which hath made them drunk hath made me bold;
+What hath quench'd them hath given me fire.
+Hark! Peace!
+It was the owl that shriek'd, the fatal bellman,
+Which gives the stern'st good-night. He is about it:
+The doors are open; and the surfeited grooms
+Do mock their charge with snores: I have drugg'd
+their possets,
+That death and nature do contend about them,
+Whether they live or die.
+
+ +MACBETH +
+[Within] Who's there? what, ho!
+
+ +LADY MACBETH +
+Alack, I am afraid they have awaked,
+And 'tis not done. The attempt and not the deed
+Confounds us. Hark! I laid their daggers ready;
+He could not miss 'em. Had he not resembled
+My father as he slept, I had done't.
+

Enter MACBETH

+My husband!
+
+ +MACBETH +
+I have done the deed. Didst thou not hear a noise?
+
+ +LADY MACBETH +
+I heard the owl scream and the crickets cry.
+Did not you speak?
+
+ +MACBETH +
+ When?
+
+ +LADY MACBETH +
+Now.
+
+ +MACBETH +
+As I descended?
+
+ +LADY MACBETH +
+Ay.
+
+ +MACBETH +
+Hark!
+Who lies i' the second chamber?
+
+ +LADY MACBETH +
+Donalbain.
+
+ +MACBETH +
+This is a sorry sight.
+

Looking on his hands

+
+ +LADY MACBETH +
+A foolish thought, to say a sorry sight.
+
+ +MACBETH +
+There's one did laugh in's sleep, and one cried
+'Murder!'
+That they did wake each other: I stood and heard them:
+But they did say their prayers, and address'd them
+Again to sleep.
+
+ +LADY MACBETH +
+ There are two lodged together.
+
+ +MACBETH +
+One cried 'God bless us!' and 'Amen' the other;
+As they had seen me with these hangman's hands.
+Listening their fear, I could not say 'Amen,'
+When they did say 'God bless us!'
+
+ +LADY MACBETH +
+Consider it not so deeply.
+
+ +MACBETH +
+But wherefore could not I pronounce 'Amen'?
+I had most need of blessing, and 'Amen'
+Stuck in my throat.
+
+ +LADY MACBETH +
+These deeds must not be thought
+After these ways; so, it will make us mad.
+
+ +MACBETH +
+Methought I heard a voice cry 'Sleep no more!
+Macbeth does murder sleep', the innocent sleep,
+Sleep that knits up the ravell'd sleeve of care,
+The death of each day's life, sore labour's bath,
+Balm of hurt minds, great nature's second course,
+Chief nourisher in life's feast,--
+
+ +LADY MACBETH +
+What do you mean?
+
+ +MACBETH +
+Still it cried 'Sleep no more!' to all the house:
+'Glamis hath murder'd sleep, and therefore Cawdor
+Shall sleep no more; Macbeth shall sleep no more.'
+
+ +LADY MACBETH +
+Who was it that thus cried? Why, worthy thane,
+You do unbend your noble strength, to think
+So brainsickly of things. Go get some water,
+And wash this filthy witness from your hand.
+Why did you bring these daggers from the place?
+They must lie there: go carry them; and smear
+The sleepy grooms with blood.
+
+ +MACBETH +
+I'll go no more:
+I am afraid to think what I have done;
+Look on't again I dare not.
+
+ +LADY MACBETH +
+Infirm of purpose!
+Give me the daggers: the sleeping and the dead
+Are but as pictures: 'tis the eye of childhood
+That fears a painted devil. If he do bleed,
+I'll gild the faces of the grooms withal;
+For it must seem their guilt.
+

Exit. Knocking within

+
+ +MACBETH +
+Whence is that knocking?
+How is't with me, when every noise appals me?
+What hands are here? ha! they pluck out mine eyes.
+Will all great Neptune's ocean wash this blood
+Clean from my hand? No, this my hand will rather
+The multitudinous seas in incarnadine,
+Making the green one red.
+

Re-enter LADY MACBETH

+
+ +LADY MACBETH +
+My hands are of your colour; but I shame
+To wear a heart so white.
+

Knocking within

+I hear a knocking
+At the south entry: retire we to our chamber;
+A little water clears us of this deed:
+How easy is it, then! Your constancy
+Hath left you unattended.
+

Knocking within

+Hark! more knocking.
+Get on your nightgown, lest occasion call us,
+And show us to be watchers. Be not lost
+So poorly in your thoughts.
+
+ +MACBETH +
+To know my deed, 'twere best not know myself.
+

Knocking within

+Wake Duncan with thy knocking! I would thou couldst!
+

Exeunt

+
+

SCENE III. The same.

+

+Knocking within. Enter a Porter +
+ +Porter +
+Here's a knocking indeed! If a
+man were porter of hell-gate, he should have
+old turning the key.
+

Knocking within

+Knock,
+knock, knock! Who's there, i' the name of
+Beelzebub? Here's a farmer, that hanged
+himself on the expectation of plenty: come in
+time; have napkins enow about you; here
+you'll sweat for't.
+

Knocking within

+Knock,
+knock! Who's there, in the other devil's
+name? Faith, here's an equivocator, that could
+swear in both the scales against either scale;
+who committed treason enough for God's sake,
+yet could not equivocate to heaven: O, come
+in, equivocator.
+

Knocking within

+Knock,
+knock, knock! Who's there? Faith, here's an
+English tailor come hither, for stealing out of
+a French hose: come in, tailor; here you may
+roast your goose.
+

Knocking within

+Knock,
+knock; never at quiet! What are you? But
+this place is too cold for hell. I'll devil-porter
+it no further: I had thought to have let in
+some of all professions that go the primrose
+way to the everlasting bonfire.
+

Knocking within

+Anon, anon! I pray you, remember the porter.
+

Opens the gate

+

Enter MACDUFF and LENNOX

+
+ +MACDUFF +
+Was it so late, friend, ere you went to bed,
+That you do lie so late?
+
+ +Porter +
+'Faith sir, we were carousing till the
+second cock: and drink, sir, is a great
+provoker of three things.
+
+ +MACDUFF +
+What three things does drink especially provoke?
+
+ +Porter +
+Marry, sir, nose-painting, sleep, and
+urine. Lechery, sir, it provokes, and unprovokes;
+it provokes the desire, but it takes
+away the performance: therefore, much drink
+may be said to be an equivocator with lechery:
+it makes him, and it mars him; it sets
+him on, and it takes him off; it persuades him,
+and disheartens him; makes him stand to, and
+not stand to; in conclusion, equivocates him
+in a sleep, and, giving him the lie, leaves him.
+
+ +MACDUFF +
+I believe drink gave thee the lie last night.
+
+ +Porter +
+That it did, sir, i' the very throat on
+me: but I requited him for his lie; and, I
+think, being too strong for him, though he took
+up my legs sometime, yet I made a shift to cast
+him.
+
+ +MACDUFF +
+Is thy master stirring?
+

Enter MACBETH

+Our knocking has awaked him; here he comes.
+
+ +LENNOX +
+Good morrow, noble sir.
+
+ +MACBETH +
+Good morrow, both.
+
+ +MACDUFF +
+Is the king stirring, worthy thane?
+
+ +MACBETH +
+Not yet.
+
+ +MACDUFF +
+He did command me to call timely on him:
+I have almost slipp'd the hour.
+
+ +MACBETH +
+I'll bring you to him.
+
+ +MACDUFF +
+I know this is a joyful trouble to you;
+But yet 'tis one.
+
+ +MACBETH +
+The labour we delight in physics pain.
+This is the door.
+
+ +MACDUFF +
+ I'll make so bold to call,
+For 'tis my limited service.
+

Exit

+
+ +LENNOX +
+Goes the king hence to-day?
+
+ +MACBETH +
+He does: he did appoint so.
+
+ +LENNOX +
+The night has been unruly: where we lay,
+Our chimneys were blown down; and, as they say,
+Lamentings heard i' the air; strange screams of death,
+And prophesying with accents terrible
+Of dire combustion and confused events
+New hatch'd to the woeful time: the obscure bird
+Clamour'd the livelong night: some say, the earth
+Was feverous and did shake.
+
+ +MACBETH +
+'Twas a rough night.
+
+ +LENNOX +
+My young remembrance cannot parallel
+A fellow to it.
+

Re-enter MACDUFF

+
+ +MACDUFF +
+O horror, horror, horror! Tongue nor heart
+Cannot conceive nor name thee!
+
+ +MACBETH + +LENNOX +
+What's the matter.
+
+ +MACDUFF +
+Confusion now hath made his masterpiece!
+Most sacrilegious murder hath broke ope
+The Lord's anointed temple, and stole thence
+The life o' the building!
+
+ +MACBETH +
+What is 't you say? the life?
+
+ +LENNOX +
+Mean you his majesty?
+
+ +MACDUFF +
+Approach the chamber, and destroy your sight
+With a new Gorgon: do not bid me speak;
+See, and then speak yourselves.
+

Exeunt MACBETH and LENNOX

+Awake, awake!
+Ring the alarum-bell. Murder and treason!
+Banquo and Donalbain! Malcolm! awake!
+Shake off this downy sleep, death's counterfeit,
+And look on death itself! up, up, and see
+The great doom's image! Malcolm! Banquo!
+As from your graves rise up, and walk like sprites,
+To countenance this horror! Ring the bell.
+

Bell rings

+

Enter LADY MACBETH

+
+ +LADY MACBETH +
+What's the business,
+That such a hideous trumpet calls to parley
+The sleepers of the house? speak, speak!
+
+ +MACDUFF +
+O gentle lady,
+'Tis not for you to hear what I can speak:
+The repetition, in a woman's ear,
+Would murder as it fell.
+

Enter BANQUO

+O Banquo, Banquo,
+Our royal master 's murder'd!
+
+ +LADY MACBETH +
+Woe, alas!
+What, in our house?
+
+ +BANQUO +
+Too cruel any where.
+Dear Duff, I prithee, contradict thyself,
+And say it is not so.
+

Re-enter MACBETH and LENNOX, with ROSS

+
+ +MACBETH +
+Had I but died an hour before this chance,
+I had lived a blessed time; for, from this instant,
+There 's nothing serious in mortality:
+All is but toys: renown and grace is dead;
+The wine of life is drawn, and the mere lees
+Is left this vault to brag of.
+

Enter MALCOLM and DONALBAIN

+
+ +DONALBAIN +
+What is amiss?
+
+ +MACBETH +
+ You are, and do not know't:
+The spring, the head, the fountain of your blood
+Is stopp'd; the very source of it is stopp'd.
+
+ +MACDUFF +
+Your royal father 's murder'd.
+
+ +MALCOLM +
+O, by whom?
+
+ +LENNOX +
+Those of his chamber, as it seem'd, had done 't:
+Their hands and faces were an badged with blood;
+So were their daggers, which unwiped we found
+Upon their pillows:
+They stared, and were distracted; no man's life
+Was to be trusted with them.
+
+ +MACBETH +
+O, yet I do repent me of my fury,
+That I did kill them.
+
+ +MACDUFF +
+Wherefore did you so?
+
+ +MACBETH +
+Who can be wise, amazed, temperate and furious,
+Loyal and neutral, in a moment? No man:
+The expedition my violent love
+Outrun the pauser, reason. Here lay Duncan,
+His silver skin laced with his golden blood;
+And his gash'd stabs look'd like a breach in nature
+For ruin's wasteful entrance: there, the murderers,
+Steep'd in the colours of their trade, their daggers
+Unmannerly breech'd with gore: who could refrain,
+That had a heart to love, and in that heart
+Courage to make 's love kno wn?
+
+ +LADY MACBETH +
+Help me hence, ho!
+
+ +MACDUFF +
+Look to the lady.
+
+ +MALCOLM +
+[Aside to DONALBAIN] Why do we hold our tongues,
+That most may claim this argument for ours?
+
+ +DONALBAIN +
+[Aside to MALCOLM] What should be spoken here,
+where our fate,
+Hid in an auger-hole, may rush, and seize us?
+Let 's away;
+Our tears are not yet brew'd.
+
+ +MALCOLM +
+[Aside to DONALBAIN] Nor our strong sorrow
+Upon the foot of motion.
+
+ +BANQUO +
+Look to the lady:
+

LADY MACBETH is carried out

+And when we have our naked frailties hid,
+That suffer in exposure, let us meet,
+And question this most bloody piece of work,
+To know it further. Fears and scruples shake us:
+In the great hand of God I stand; and thence
+Against the undivulged pretence I fight
+Of treasonous malice.
+
+ +MACDUFF +
+And so do I.
+
+ +ALL +
+So all.
+
+ +MACBETH +
+Let's briefly put on manly readiness,
+And meet i' the hall together.
+
+ +ALL +
+Well contented.
+

Exeunt all but Malcolm and Donalbain.

+
+ +MALCOLM +
+What will you do? Let's not consort with them:
+To show an unfelt sorrow is an office
+Which the false man does easy. I'll to England.
+
+ +DONALBAIN +
+To Ireland, I; our separated fortune
+Shall keep us both the safer: where we are,
+There's daggers in men's smiles: the near in blood,
+The nearer bloody.
+
+ +MALCOLM +
+ This murderous shaft that's shot
+Hath not yet lighted, and our safest way
+Is to avoid the aim. Therefore, to horse;
+And let us not be dainty of leave-taking,
+But shift away: there's warrant in that theft
+Which steals itself, when there's no mercy left.
+

Exeunt

+
+

SCENE IV. Outside Macbeth's castle.

+

+Enter ROSS and an old Man +
+ +Old Man +
+Threescore and ten I can remember well:
+Within the volume of which time I have seen
+Hours dreadful and things strange; but this sore night
+Hath trifled former knowings.
+
+ +ROSS +
+Ah, good father,
+Thou seest, the heavens, as troubled with man's act,
+Threaten his bloody stage: by the clock, 'tis day,
+And yet dark night strangles the travelling lamp:
+Is't night's predominance, or the day's shame,
+That darkness does the face of earth entomb,
+When living light should kiss it?
+
+ +Old Man +
+'Tis unnatural,
+Even like the deed that's done. On Tuesday last,
+A falcon, towering in her pride of place,
+Was by a mousing owl hawk'd at and kill'd.
+
+ +ROSS +
+And Duncan's horses--a thing most strange and certain--
+Beauteous and swift, the minions of their race,
+Turn'd wild in nature, broke their stalls, flung out,
+Contending 'gainst obedience, as they would make
+War with mankind.
+
+ +Old Man +
+'Tis said they eat each other.
+
+ +ROSS +
+They did so, to the amazement of mine eyes
+That look'd upon't. Here comes the good Macduff.
+

Enter MACDUFF

+How goes the world, sir, now?
+
+ +MACDUFF +
+Why, see you not?
+
+ +ROSS +
+Is't known who did this more than bloody deed?
+
+ +MACDUFF +
+Those that Macbeth hath slain.
+
+ +ROSS +
+Alas, the day!
+What good could they pretend?
+
+ +MACDUFF +
+They were suborn'd:
+Malcolm and Donalbain, the king's two sons,
+Are stol'n away and fled; which puts upon them
+Suspicion of the deed.
+
+ +ROSS +
+'Gainst nature still!
+Thriftless ambition, that wilt ravin up
+Thine own life's means! Then 'tis most like
+The sovereignty will fall upon Macbeth.
+
+ +MACDUFF +
+He is already named, and gone to Scone
+To be invested.
+
+ +ROSS +
+ Where is Duncan's body?
+
+ +MACDUFF +
+Carried to Colmekill,
+The sacred storehouse of his predecessors,
+And guardian of their bones.
+
+ +ROSS +
+Will you to Scone?
+
+ +MACDUFF +
+No, cousin, I'll to Fife.
+
+ +ROSS +
+Well, I will thither.
+
+ +MACDUFF +
+Well, may you see things well done there: adieu!
+Lest our old robes sit easier than our new!
+
+ +ROSS +
+Farewell, father.
+
+ +Old Man +
+God's benison go with you; and with those
+That would make good of bad, and friends of foes!
+

Exeunt

+

+

ACT III

+

SCENE I. Forres. The palace.

+

+Enter BANQUO +
+ +BANQUO +
+Thou hast it now: king, Cawdor, Glamis, all,
+As the weird women promised, and, I fear,
+Thou play'dst most foully for't: yet it was said
+It should not stand in thy posterity,
+But that myself should be the root and father
+Of many kings. If there come truth from them--
+As upon thee, Macbeth, their speeches shine--
+Why, by the verities on thee made good,
+May they not be my oracles as well,
+And set me up in hope? But hush! no more.
+

Sennet sounded. Enter MACBETH, as king, LADY MACBETH, as queen, LENNOX, ROSS, Lords, Ladies, and Attendants

+
+ +MACBETH +
+Here's our chief guest.
+
+ +LADY MACBETH +
+If he had been forgotten,
+It had been as a gap in our great feast,
+And all-thing unbecoming.
+
+ +MACBETH +
+To-night we hold a solemn supper sir,
+And I'll request your presence.
+
+ +BANQUO +
+Let your highness
+Command upon me; to the which my duties
+Are with a most indissoluble tie
+For ever knit.
+
+ +MACBETH +
+ Ride you this afternoon?
+
+ +BANQUO +
+Ay, my good lord.
+
+ +MACBETH +
+We should have else desired your good advice,
+Which still hath been both grave and prosperous,
+In this day's council; but we'll take to-morrow.
+Is't far you ride?
+
+ +BANQUO +
+As far, my lord, as will fill up the time
+'Twixt this and supper: go not my horse the better,
+I must become a borrower of the night
+For a dark hour or twain.
+
+ +MACBETH +
+Fail not our feast.
+
+ +BANQUO +
+My lord, I will not.
+
+ +MACBETH +
+We hear, our bloody cousins are bestow'd
+In England and in Ireland, not confessing
+Their cruel parricide, filling their hearers
+With strange invention: but of that to-morrow,
+When therewithal we shall have cause of state
+Craving us jointly. Hie you to horse: adieu,
+Till you return at night. Goes Fleance with you?
+
+ +BANQUO +
+Ay, my good lord: our time does call upon 's.
+
+ +MACBETH +
+I wish your horses swift and sure of foot;
+And so I do commend you to their backs. Farewell.
+

Exit BANQUO

+Let every man be master of his time
+Till seven at night: to make society
+The sweeter welcome, we will keep ourself
+Till supper-time alone: while then, God be with you!
+

Exeunt all but MACBETH, and an attendant

+Sirrah, a word with you: attend those men
+Our pleasure?
+
+ +ATTENDANT +
+They are, my lord, without the palace gate.
+
+ +MACBETH +
+Bring them before us.
+

Exit Attendant

+To be thus is nothing;
+But to be safely thus.--Our fears in Banquo
+Stick deep; and in his royalty of nature
+Reigns that which would be fear'd: 'tis much he dares;
+And, to that dauntless temper of his mind,
+He hath a wisdom that doth guide his valour
+To act in safety. There is none but he
+Whose being I do fear: and, under him,
+My Genius is rebuked; as, it is said,
+Mark Antony's was by Caesar. He chid the sisters
+When first they put the name of king upon me,
+And bade them speak to him: then prophet-like
+They hail'd him father to a line of kings:
+Upon my head they placed a fruitless crown,
+And put a barren sceptre in my gripe,
+Thence to be wrench'd with an unlineal hand,
+No son of mine succeeding. If 't be so,
+For Banquo's issue have I filed my mind;
+For them the gracious Duncan have I murder'd;
+Put rancours in the vessel of my peace
+Only for them; and mine eternal jewel
+Given to the common enemy of man,
+To make them kings, the seed of Banquo kings!
+Rather than so, come fate into the list.
+And champion me to the utterance! Who's there!
+

Re-enter Attendant, with two Murderers

+Now go to the door, and stay there till we call.
+

Exit Attendant

+Was it not yesterday we spoke together?
+
+ +First Murderer +
+It was, so please your highness.
+
+ +MACBETH +
+Well then, now
+Have you consider'd of my speeches? Know
+That it was he in the times past which held you
+So under fortune, which you thought had been
+Our innocent self: this I made good to you
+In our last conference, pass'd in probation with you,
+How you were borne in hand, how cross'd,
+the instruments,
+Who wrought with them, and all things else that might
+To half a soul and to a notion crazed
+Say 'Thus did Banquo.'
+
+ +First Murderer +
+You made it known to us.
+
+ +MACBETH +
+I did so, and went further, which is now
+Our point of second meeting. Do you find
+Your patience so predominant in your nature
+That you can let this go? Are you so gospell'd
+To pray for this good man and for his issue,
+Whose heavy hand hath bow'd you to the grave
+And beggar'd yours for ever?
+
+ +First Murderer +
+We are men, my liege.
+
+ +MACBETH +
+Ay, in the catalogue ye go for men;
+As hounds and greyhounds, mongrels, spaniels, curs,
+Shoughs, water-rugs and demi-wolves, are clept
+All by the name of dogs: the valued file
+Distinguishes the swift, the slow, the subtle,
+The housekeeper, the hunter, every one
+According to the gift which bounteous nature
+Hath in him closed; whereby he does receive
+Particular addition. from the bill
+That writes them all alike: and so of men.
+Now, if you have a station in the file,
+Not i' the worst rank of manhood, say 't;
+And I will put that business in your bosoms,
+Whose execution takes your enemy off,
+Grapples you to the heart and love of us,
+Who wear our health but sickly in his life,
+Which in his death were perfect.
+
+ +Second Murderer +
+I am one, my liege,
+Whom the vile blows and buffets of the world
+Have so incensed that I am reckless what
+I do to spite the world.
+
+ +First Murderer +
+And I another
+So weary with disasters, tugg'd with fortune,
+That I would set my lie on any chance,
+To mend it, or be rid on't.
+
+ +MACBETH +
+Both of you
+Know Banquo was your enemy.
+
+ +Both Murderers +
+True, my lord.
+
+ +MACBETH +
+So is he mine; and in such bloody distance,
+That every minute of his being thrusts
+Against my near'st of life: and though I could
+With barefaced power sweep him from my sight
+And bid my will avouch it, yet I must not,
+For certain friends that are both his and mine,
+Whose loves I may not drop, but wail his fall
+Who I myself struck down; and thence it is,
+That I to your assistance do make love,
+Masking the business from the common eye
+For sundry weighty reasons.
+
+ +Second Murderer +
+We shall, my lord,
+Perform what you command us.
+
+ +First Murderer +
+Though our lives--
+
+ +MACBETH +
+Your spirits shine through you. Within this hour at most
+I will advise you where to plant yourselves;
+Acquaint you with the perfect spy o' the time,
+The moment on't; for't must be done to-night,
+And something from the palace; always thought
+That I require a clearness: and with him--
+To leave no rubs nor botches in the work--
+Fleance his son, that keeps him company,
+Whose absence is no less material to me
+Than is his father's, must embrace the fate
+Of that dark hour. Resolve yourselves apart:
+I'll come to you anon.
+
+ +Both Murderers +
+We are resolved, my lord.
+
+ +MACBETH +
+I'll call upon you straight: abide within.
+

Exeunt Murderers

+It is concluded. Banquo, thy soul's flight,
+If it find heaven, must find it out to-night.
+

Exit

+
+

SCENE II. The palace.

+

+Enter LADY MACBETH and a Servant +
+ +LADY MACBETH +
+Is Banquo gone from court?
+
+ +Servant +
+Ay, madam, but returns again to-night.
+
+ +LADY MACBETH +
+Say to the king, I would attend his leisure
+For a few words.
+
+ +Servant +
+ Madam, I will.
+

Exit

+
+ +LADY MACBETH +
+Nought's had, all's spent,
+Where our desire is got without content:
+'Tis safer to be that which we destroy
+Than by destruction dwell in doubtful joy.
+

Enter MACBETH

+How now, my lord! why do you keep alone,
+Of sorriest fancies your companions making,
+Using those thoughts which should indeed have died
+With them they think on? Things without all remedy
+Should be without regard: what's done is done.
+
+ +MACBETH +
+We have scotch'd the snake, not kill'd it:
+She'll close and be herself, whilst our poor malice
+Remains in danger of her former tooth.
+But let the frame of things disjoint, both the
+worlds suffer,
+Ere we will eat our meal in fear and sleep
+In the affliction of these terrible dreams
+That shake us nightly: better be with the dead,
+Whom we, to gain our peace, have sent to peace,
+Than on the torture of the mind to lie
+In restless ecstasy. Duncan is in his grave;
+After life's fitful fever he sleeps well;
+Treason has done his worst: nor steel, nor poison,
+Malice domestic, foreign levy, nothing,
+Can touch him further.
+
+ +LADY MACBETH +
+Come on;
+Gentle my lord, sleek o'er your rugged looks;
+Be bright and jovial among your guests to-night.
+
+ +MACBETH +
+So shall I, love; and so, I pray, be you:
+Let your remembrance apply to Banquo;
+Present him eminence, both with eye and tongue:
+Unsafe the while, that we
+Must lave our honours in these flattering streams,
+And make our faces vizards to our hearts,
+Disguising what they are.
+
+ +LADY MACBETH +
+You must leave this.
+
+ +MACBETH +
+O, full of scorpions is my mind, dear wife!
+Thou know'st that Banquo, and his Fleance, lives.
+
+ +LADY MACBETH +
+But in them nature's copy's not eterne.
+
+ +MACBETH +
+There's comfort yet; they are assailable;
+Then be thou jocund: ere the bat hath flown
+His cloister'd flight, ere to black Hecate's summons
+The shard-borne beetle with his drowsy hums
+Hath rung night's yawning peal, there shall be done
+A deed of dreadful note.
+
+ +LADY MACBETH +
+What's to be done?
+
+ +MACBETH +
+Be innocent of the knowledge, dearest chuck,
+Till thou applaud the deed. Come, seeling night,
+Scarf up the tender eye of pitiful day;
+And with thy bloody and invisible hand
+Cancel and tear to pieces that great bond
+Which keeps me pale! Light thickens; and the crow
+Makes wing to the rooky wood:
+Good things of day begin to droop and drowse;
+While night's black agents to their preys do rouse.
+Thou marvell'st at my words: but hold thee still;
+Things bad begun make strong themselves by ill.
+So, prithee, go with me.
+

Exeunt

+
+

SCENE III. A park near the palace.

+

+Enter three Murderers +
+ +First Murderer +
+But who did bid thee join with us?
+
+ +Third Murderer +
+Macbeth.
+
+ +Second Murderer +
+He needs not our mistrust, since he delivers
+Our offices and what we have to do
+To the direction just.
+
+ +First Murderer +
+Then stand with us.
+The west yet glimmers with some streaks of day:
+Now spurs the lated traveller apace
+To gain the timely inn; and near approaches
+The subject of our watch.
+
+ +Third Murderer +
+Hark! I hear horses.
+
+ +BANQUO +
+[Within] Give us a light there, ho!
+
+ +Second Murderer +
+Then 'tis he: the rest
+That are within the note of expectation
+Already are i' the court.
+
+ +First Murderer +
+His horses go about.
+
+ +Third Murderer +
+Almost a mile: but he does usually,
+So all men do, from hence to the palace gate
+Make it their walk.
+
+ +Second Murderer +
+A light, a light!
+

Enter BANQUO, and FLEANCE with a torch

+
+ +Third Murderer +
+'Tis he.
+
+ +First Murderer +
+Stand to't.
+
+ +BANQUO +
+It will be rain to-night.
+
+ +First Murderer +
+Let it come down.
+

They set upon BANQUO

+
+ +BANQUO +
+O, treachery! Fly, good Fleance, fly, fly, fly!
+Thou mayst revenge. O slave!
+

Dies. FLEANCE escapes

+
+ +Third Murderer +
+Who did strike out the light?
+
+ +First Murderer +
+Wast not the way?
+
+ +Third Murderer +
+There's but one down; the son is fled.
+
+ +Second Murderer +
+We have lost
+Best half of our affair.
+
+ +First Murderer +
+Well, let's away, and say how much is done.
+

Exeunt

+
+

SCENE IV. The same. Hall in the palace.

+

+A banquet prepared. Enter MACBETH, LADY MACBETH, ROSS, LENNOX, Lords, and Attendants +
+ +MACBETH +
+You know your own degrees; sit down: at first
+And last the hearty welcome.
+
+ +Lords +
+Thanks to your majesty.
+
+ +MACBETH +
+Ourself will mingle with society,
+And play the humble host.
+Our hostess keeps her state, but in best time
+We will require her welcome.
+
+ +LADY MACBETH +
+Pronounce it for me, sir, to all our friends;
+For my heart speaks they are welcome.
+

First Murderer appears at the door

+
+ +MACBETH +
+See, they encounter thee with their hearts' thanks.
+Both sides are even: here I'll sit i' the midst:
+Be large in mirth; anon we'll drink a measure
+The table round.
+

Approaching the door

+There's blood on thy face.
+
+ +First Murderer +
+'Tis Banquo's then.
+
+ +MACBETH +
+'Tis better thee without than he within.
+Is he dispatch'd?
+
+ +First Murderer +
+My lord, his throat is cut; that I did for him.
+
+ +MACBETH +
+Thou art the best o' the cut-throats: yet he's good
+That did the like for Fleance: if thou didst it,
+Thou art the nonpareil.
+
+ +First Murderer +
+Most royal sir,
+Fleance is 'scaped.
+
+ +MACBETH +
+Then comes my fit again: I had else been perfect,
+Whole as the marble, founded as the rock,
+As broad and general as the casing air:
+But now I am cabin'd, cribb'd, confined, bound in
+To saucy doubts and fears. But Banquo's safe?
+
+ +First Murderer +
+Ay, my good lord: safe in a ditch he bides,
+With twenty trenched gashes on his head;
+The least a death to nature.
+
+ +MACBETH +
+Thanks for that:
+There the grown serpent lies; the worm that's fled
+Hath nature that in time will venom breed,
+No teeth for the present. Get thee gone: to-morrow
+We'll hear, ourselves, again.
+

Exit Murderer

+
+ +LADY MACBETH +
+My royal lord,
+You do not give the cheer: the feast is sold
+That is not often vouch'd, while 'tis a-making,
+'Tis given with welcome: to feed were best at home;
+From thence the sauce to meat is ceremony;
+Meeting were bare without it.
+
+ +MACBETH +
+Sweet remembrancer!
+Now, good digestion wait on appetite,
+And health on both!
+
+ +LENNOX +
+May't please your highness sit.
+

The GHOST OF BANQUO enters, and sits in MACBETH's place

+
+ +MACBETH +
+Here had we now our country's honour roof'd,
+Were the graced person of our Banquo present;
+Who may I rather challenge for unkindness
+Than pity for mischance!
+
+ +ROSS +
+His absence, sir,
+Lays blame upon his promise. Please't your highness
+To grace us with your royal company.
+
+ +MACBETH +
+The table's full.
+
+ +LENNOX +
+ Here is a place reserved, sir.
+
+ +MACBETH +
+Where?
+
+ +LENNOX +
+Here, my good lord. What is't that moves your highness?
+
+ +MACBETH +
+Which of you have done this?
+
+ +Lords +
+What, my good lord?
+
+ +MACBETH +
+Thou canst not say I did it: never shake
+Thy gory locks at me.
+
+ +ROSS +
+Gentlemen, rise: his highness is not well.
+
+ +LADY MACBETH +
+Sit, worthy friends: my lord is often thus,
+And hath been from his youth: pray you, keep seat;
+The fit is momentary; upon a thought
+He will again be well: if much you note him,
+You shall offend him and extend his passion:
+Feed, and regard him not. Are you a man?
+
+ +MACBETH +
+Ay, and a bold one, that dare look on that
+Which might appal the devil.
+
+ +LADY MACBETH +
+O proper stuff!
+This is the very painting of your fear:
+This is the air-drawn dagger which, you said,
+Led you to Duncan. O, these flaws and starts,
+Impostors to true fear, would well become
+A woman's story at a winter's fire,
+Authorized by her grandam. Shame itself!
+Why do you make such faces? When all's done,
+You look but on a stool.
+
+ +MACBETH +
+Prithee, see there! behold! look! lo!
+how say you?
+Why, what care I? If thou canst nod, speak too.
+If charnel-houses and our graves must send
+Those that we bury back, our monuments
+Shall be the maws of kites.
+

GHOST OF BANQUO vanishes

+
+ +LADY MACBETH +
+What, quite unmann'd in folly?
+
+ +MACBETH +
+If I stand here, I saw him.
+
+ +LADY MACBETH +
+Fie, for shame!
+
+ +MACBETH +
+Blood hath been shed ere now, i' the olden time,
+Ere human statute purged the gentle weal;
+Ay, and since too, murders have been perform'd
+Too terrible for the ear: the times have been,
+That, when the brains were out, the man would die,
+And there an end; but now they rise again,
+With twenty mortal murders on their crowns,
+And push us from our stools: this is more strange
+Than such a murder is.
+
+ +LADY MACBETH +
+My worthy lord,
+Your noble friends do lack you.
+
+ +MACBETH +
+I do forget.
+Do not muse at me, my most worthy friends,
+I have a strange infirmity, which is nothing
+To those that know me. Come, love and health to all;
+Then I'll sit down. Give me some wine; fill full.
+I drink to the general joy o' the whole table,
+And to our dear friend Banquo, whom we miss;
+Would he were here! to all, and him, we thirst,
+And all to all.
+
+ +Lords +
+ Our duties, and the pledge.
+

Re-enter GHOST OF BANQUO

+
+ +MACBETH +
+Avaunt! and quit my sight! let the earth hide thee!
+Thy bones are marrowless, thy blood is cold;
+Thou hast no speculation in those eyes
+Which thou dost glare with!
+
+ +LADY MACBETH +
+Think of this, good peers,
+But as a thing of custom: 'tis no other;
+Only it spoils the pleasure of the time.
+
+ +MACBETH +
+What man dare, I dare:
+Approach thou like the rugged Russian bear,
+The arm'd rhinoceros, or the Hyrcan tiger;
+Take any shape but that, and my firm nerves
+Shall never tremble: or be alive again,
+And dare me to the desert with thy sword;
+If trembling I inhabit then, protest me
+The baby of a girl. Hence, horrible shadow!
+Unreal mockery, hence!
+

GHOST OF BANQUO vanishes

+Why, so: being gone,
+I am a man again. Pray you, sit still.
+
+ +LADY MACBETH +
+You have displaced the mirth, broke the good meeting,
+With most admired disorder.
+
+ +MACBETH +
+Can such things be,
+And overcome us like a summer's cloud,
+Without our special wonder? You make me strange
+Even to the disposition that I owe,
+When now I think you can behold such sights,
+And keep the natural ruby of your cheeks,
+When mine is blanched with fear.
+
+ +ROSS +
+What sights, my lord?
+
+ +LADY MACBETH +
+I pray you, speak not; he grows worse and worse;
+Question enrages him. At once, good night:
+Stand not upon the order of your going,
+But go at once.
+
+ +LENNOX +
+ Good night; and better health
+Attend his majesty!
+
+ +LADY MACBETH +
+A kind good night to all!
+

Exeunt all but MACBETH and LADY MACBETH

+
+ +MACBETH +
+It will have blood; they say, blood will have blood:
+Stones have been known to move and trees to speak;
+Augurs and understood relations have
+By magot-pies and choughs and rooks brought forth
+The secret'st man of blood. What is the night?
+
+ +LADY MACBETH +
+Almost at odds with morning, which is which.
+
+ +MACBETH +
+How say'st thou, that Macduff denies his person
+At our great bidding?
+
+ +LADY MACBETH +
+Did you send to him, sir?
+
+ +MACBETH +
+I hear it by the way; but I will send:
+There's not a one of them but in his house
+I keep a servant fee'd. I will to-morrow,
+And betimes I will, to the weird sisters:
+More shall they speak; for now I am bent to know,
+By the worst means, the worst. For mine own good,
+All causes shall give way: I am in blood
+Stepp'd in so far that, should I wade no more,
+Returning were as tedious as go o'er:
+Strange things I have in head, that will to hand;
+Which must be acted ere they may be scann'd.
+
+ +LADY MACBETH +
+You lack the season of all natures, sleep.
+
+ +MACBETH +
+Come, we'll to sleep. My strange and self-abuse
+Is the initiate fear that wants hard use:
+We are yet but young in deed.
+

Exeunt

+
+

SCENE V. A Heath.

+

+Thunder. Enter the three Witches meeting HECATE +
+ +First Witch +
+Why, how now, Hecate! you look angerly.
+
+ +HECATE +
+Have I not reason, beldams as you are,
+Saucy and overbold? How did you dare
+To trade and traffic with Macbeth
+In riddles and affairs of death;
+And I, the mistress of your charms,
+The close contriver of all harms,
+Was never call'd to bear my part,
+Or show the glory of our art?
+And, which is worse, all you have done
+Hath been but for a wayward son,
+Spiteful and wrathful, who, as others do,
+Loves for his own ends, not for you.
+But make amends now: get you gone,
+And at the pit of Acheron
+Meet me i' the morning: thither he
+Will come to know his destiny:
+Your vessels and your spells provide,
+Your charms and every thing beside.
+I am for the air; this night I'll spend
+Unto a dismal and a fatal end:
+Great business must be wrought ere noon:
+Upon the corner of the moon
+There hangs a vaporous drop profound;
+I'll catch it ere it come to ground:
+And that distill'd by magic sleights
+Shall raise such artificial sprites
+As by the strength of their illusion
+Shall draw him on to his confusion:
+He shall spurn fate, scorn death, and bear
+He hopes 'bove wisdom, grace and fear:
+And you all know, security
+Is mortals' chiefest enemy.
+

Music and a song within: 'Come away, come away,' & c

+Hark! I am call'd; my little spirit, see,
+Sits in a foggy cloud, and stays for me.
+

Exit

+
+ +First Witch +
+Come, let's make haste; she'll soon be back again.
+

Exeunt

+
+

SCENE VI. Forres. The palace.

+

+Enter LENNOX and another Lord +
+ +LENNOX +
+My former speeches have but hit your thoughts,
+Which can interpret further: only, I say,
+Things have been strangely borne. The
+gracious Duncan
+Was pitied of Macbeth: marry, he was dead:
+And the right-valiant Banquo walk'd too late;
+Whom, you may say, if't please you, Fleance kill'd,
+For Fleance fled: men must not walk too late.
+Who cannot want the thought how monstrous
+It was for Malcolm and for Donalbain
+To kill their gracious father? damned fact!
+How it did grieve Macbeth! did he not straight
+In pious rage the two delinquents tear,
+That were the slaves of drink and thralls of sleep?
+Was not that nobly done? Ay, and wisely too;
+For 'twould have anger'd any heart alive
+To hear the men deny't. So that, I say,
+He has borne all things well: and I do think
+That had he Duncan's sons under his key--
+As, an't please heaven, he shall not--they
+should find
+What 'twere to kill a father; so should Fleance.
+But, peace! for from broad words and 'cause he fail'd
+His presence at the tyrant's feast, I hear
+Macduff lives in disgrace: sir, can you tell
+Where he bestows himself?
+
+ +Lord +
+The son of Duncan,
+From whom this tyrant holds the due of birth
+Lives in the English court, and is received
+Of the most pious Edward with such grace
+That the malevolence of fortune nothing
+Takes from his high respect: thither Macduff
+Is gone to pray the holy king, upon his aid
+To wake Northumberland and warlike Siward:
+That, by the help of these--with Him above
+To ratify the work--we may again
+Give to our tables meat, sleep to our nights,
+Free from our feasts and banquets bloody knives,
+Do faithful homage and receive free honours:
+All which we pine for now: and this report
+Hath so exasperate the king that he
+Prepares for some attempt of war.
+
+ +LENNOX +
+Sent he to Macduff?
+
+ +Lord +
+He did: and with an absolute 'Sir, not I,'
+The cloudy messenger turns me his back,
+And hums, as who should say 'You'll rue the time
+That clogs me with this answer.'
+
+ +LENNOX +
+And that well might
+Advise him to a caution, to hold what distance
+His wisdom can provide. Some holy angel
+Fly to the court of England and unfold
+His message ere he come, that a swift blessing
+May soon return to this our suffering country
+Under a hand accursed!
+
+ +Lord +
+I'll send my prayers with him.
+

Exeunt

+

+

ACT IV

+

SCENE I. A cavern. In the middle, a boiling cauldron.

+

+Thunder. Enter the three Witches +
+ +First Witch +
+Thrice the brinded cat hath mew'd.
+
+ +Second Witch +
+Thrice and once the hedge-pig whined.
+
+ +Third Witch +
+Harpier cries 'Tis time, 'tis time.
+
+ +First Witch +
+Round about the cauldron go;
+In the poison'd entrails throw.
+Toad, that under cold stone
+Days and nights has thirty-one
+Swelter'd venom sleeping got,
+Boil thou first i' the charmed pot.
+
+ +ALL +
+Double, double toil and trouble;
+Fire burn, and cauldron bubble.
+
+ +Second Witch +
+Fillet of a fenny snake,
+In the cauldron boil and bake;
+Eye of newt and toe of frog,
+Wool of bat and tongue of dog,
+Adder's fork and blind-worm's sting,
+Lizard's leg and owlet's wing,
+For a charm of powerful trouble,
+Like a hell-broth boil and bubble.
+
+ +ALL +
+Double, double toil and trouble;
+Fire burn and cauldron bubble.
+
+ +Third Witch +
+Scale of dragon, tooth of wolf,
+Witches' mummy, maw and gulf
+Of the ravin'd salt-sea shark,
+Root of hemlock digg'd i' the dark,
+Liver of blaspheming Jew,
+Gall of goat, and slips of yew
+Silver'd in the moon's eclipse,
+Nose of Turk and Tartar's lips,
+Finger of birth-strangled babe
+Ditch-deliver'd by a drab,
+Make the gruel thick and slab:
+Add thereto a tiger's chaudron,
+For the ingredients of our cauldron.
+
+ +ALL +
+Double, double toil and trouble;
+Fire burn and cauldron bubble.
+
+ +Second Witch +
+Cool it with a baboon's blood,
+Then the charm is firm and good.
+

Enter HECATE to the other three Witches

+
+ +HECATE +
+O well done! I commend your pains;
+And every one shall share i' the gains;
+And now about the cauldron sing,
+Live elves and fairies in a ring,
+Enchanting all that you put in.
+

Music and a song: 'Black spirits,' & c

+

HECATE retires

+
+ +Second Witch +
+By the pricking of my thumbs,
+Something wicked this way comes.
+Open, locks,
+Whoever knocks!
+

Enter MACBETH

+
+ +MACBETH +
+How now, you secret, black, and midnight hags!
+What is't you do?
+
+ +ALL +
+ A deed without a name.
+
+ +MACBETH +
+I conjure you, by that which you profess,
+Howe'er you come to know it, answer me:
+Though you untie the winds and let them fight
+Against the churches; though the yesty waves
+Confound and swallow navigation up;
+Though bladed corn be lodged and trees blown down;
+Though castles topple on their warders' heads;
+Though palaces and pyramids do slope
+Their heads to their foundations; though the treasure
+Of nature's germens tumble all together,
+Even till destruction sicken; answer me
+To what I ask you.
+
+ +First Witch +
+ Speak.
+
+ +Second Witch +
+Demand.
+
+ +Third Witch +
+We'll answer.
+
+ +First Witch +
+Say, if thou'dst rather hear it from our mouths,
+Or from our masters?
+
+ +MACBETH +
+Call 'em; let me see 'em.
+
+ +First Witch +
+Pour in sow's blood, that hath eaten
+Her nine farrow; grease that's sweaten
+From the murderer's gibbet throw
+Into the flame.
+
+ +ALL +
+ Come, high or low;
+Thyself and office deftly show!
+

Thunder. First Apparition: an armed Head

+
+ +MACBETH +
+Tell me, thou unknown power,--
+
+ +First Witch +
+He knows thy thought:
+Hear his speech, but say thou nought.
+
+ +First Apparition +
+Macbeth! Macbeth! Macbeth! beware Macduff;
+Beware the thane of Fife. Dismiss me. Enough.
+

Descends

+
+ +MACBETH +
+Whate'er thou art, for thy good caution, thanks;
+Thou hast harp'd my fear aright: but one
+word more,--
+
+ +First Witch +
+He will not be commanded: here's another,
+More potent than the first.
+

Thunder. Second Apparition: A bloody Child

+
+ +Second Apparition +
+Macbeth! Macbeth! Macbeth!
+
+ +MACBETH +
+Had I three ears, I'ld hear thee.
+
+ +Second Apparition +
+Be bloody, bold, and resolute; laugh to scorn
+The power of man, for none of woman born
+Shall harm Macbeth.
+

Descends

+
+ +MACBETH +
+Then live, Macduff: what need I fear of thee?
+But yet I'll make assurance double sure,
+And take a bond of fate: thou shalt not live;
+That I may tell pale-hearted fear it lies,
+And sleep in spite of thunder.
+

Thunder. Third Apparition: a Child crowned, with a tree in his hand

+What is this
+That rises like the issue of a king,
+And wears upon his baby-brow the round
+And top of sovereignty?
+
+ +ALL +
+Listen, but speak not to't.
+
+ +Third Apparition +
+Be lion-mettled, proud; and take no care
+Who chafes, who frets, or where conspirers are:
+Macbeth shall never vanquish'd be until
+Great Birnam wood to high Dunsinane hill
+Shall come against him.
+

Descends

+
+ +MACBETH +
+That will never be
+Who can impress the forest, bid the tree
+Unfix his earth-bound root? Sweet bodements! good!
+Rebellion's head, rise never till the wood
+Of Birnam rise, and our high-placed Macbeth
+Shall live the lease of nature, pay his breath
+To time and mortal custom. Yet my heart
+Throbs to know one thing: tell me, if your art
+Can tell so much: shall Banquo's issue ever
+Reign in this kingdom?
+
+ +ALL +
+Seek to know no more.
+
+ +MACBETH +
+I will be satisfied: deny me this,
+And an eternal curse fall on you! Let me know.
+Why sinks that cauldron? and what noise is this?
+

Hautboys

+
+ +First Witch +
+Show!
+
+ +Second Witch +
+Show!
+
+ +Third Witch +
+Show!
+
+ +ALL +
+Show his eyes, and grieve his heart;
+Come like shadows, so depart!
+

A show of Eight Kings, the last with a glass in his hand; GHOST OF BANQUO following

+
+ +MACBETH +
+Thou art too like the spirit of Banquo: down!
+Thy crown does sear mine eye-balls. And thy hair,
+Thou other gold-bound brow, is like the first.
+A third is like the former. Filthy hags!
+Why do you show me this? A fourth! Start, eyes!
+What, will the line stretch out to the crack of doom?
+Another yet! A seventh! I'll see no more:
+And yet the eighth appears, who bears a glass
+Which shows me many more; and some I see
+That two-fold balls and treble scepters carry:
+Horrible sight! Now, I see, 'tis true;
+For the blood-bolter'd Banquo smiles upon me,
+And points at them for his.
+

Apparitions vanish

+What, is this so?
+
+ +First Witch +
+Ay, sir, all this is so: but why
+Stands Macbeth thus amazedly?
+Come, sisters, cheer we up his sprites,
+And show the best of our delights:
+I'll charm the air to give a sound,
+While you perform your antic round:
+That this great king may kindly say,
+Our duties did his welcome pay.
+

Music. The witches dance and then vanish, with HECATE

+
+ +MACBETH +
+Where are they? Gone? Let this pernicious hour
+Stand aye accursed in the calendar!
+Come in, without there!
+

Enter LENNOX

+
+ +LENNOX +
+What's your grace's will?
+
+ +MACBETH +
+Saw you the weird sisters?
+
+ +LENNOX +
+No, my lord.
+
+ +MACBETH +
+Came they not by you?
+
+ +LENNOX +
+No, indeed, my lord.
+
+ +MACBETH +
+Infected be the air whereon they ride;
+And damn'd all those that trust them! I did hear
+The galloping of horse: who was't came by?
+
+ +LENNOX +
+'Tis two or three, my lord, that bring you word
+Macduff is fled to England.
+
+ +MACBETH +
+Fled to England!
+
+ +LENNOX +
+Ay, my good lord.
+
+ +MACBETH +
+Time, thou anticipatest my dread exploits:
+The flighty purpose never is o'ertook
+Unless the deed go with it; from this moment
+The very firstlings of my heart shall be
+The firstlings of my hand. And even now,
+To crown my thoughts with acts, be it thought and done:
+The castle of Macduff I will surprise;
+Seize upon Fife; give to the edge o' the sword
+His wife, his babes, and all unfortunate souls
+That trace him in his line. No boasting like a fool;
+This deed I'll do before this purpose cool.
+But no more sights!--Where are these gentlemen?
+Come, bring me where they are.
+

Exeunt

+
+

SCENE II. Fife. Macduff's castle.

+

+Enter LADY MACDUFF, her Son, and ROSS +
+ +LADY MACDUFF +
+What had he done, to make him fly the land?
+
+ +ROSS +
+You must have patience, madam.
+
+ +LADY MACDUFF +
+He had none:
+His flight was madness: when our actions do not,
+Our fears do make us traitors.
+
+ +ROSS +
+You know not
+Whether it was his wisdom or his fear.
+
+ +LADY MACDUFF +
+Wisdom! to leave his wife, to leave his babes,
+His mansion and his titles in a place
+From whence himself does fly? He loves us not;
+He wants the natural touch: for the poor wren,
+The most diminutive of birds, will fight,
+Her young ones in her nest, against the owl.
+All is the fear and nothing is the love;
+As little is the wisdom, where the flight
+So runs against all reason.
+
+ +ROSS +
+My dearest coz,
+I pray you, school yourself: but for your husband,
+He is noble, wise, judicious, and best knows
+The fits o' the season. I dare not speak
+much further;
+But cruel are the times, when we are traitors
+And do not know ourselves, when we hold rumour
+From what we fear, yet know not what we fear,
+But float upon a wild and violent sea
+Each way and move. I take my leave of you:
+Shall not be long but I'll be here again:
+Things at the worst will cease, or else climb upward
+To what they were before. My pretty cousin,
+Blessing upon you!
+
+ +LADY MACDUFF +
+Father'd he is, and yet he's fatherless.
+
+ +ROSS +
+I am so much a fool, should I stay longer,
+It would be my disgrace and your discomfort:
+I take my leave at once.
+

Exit

+
+ +LADY MACDUFF +
+Sirrah, your father's dead;
+And what will you do now? How will you live?
+
+ +Son +
+As birds do, mother.
+
+ +LADY MACDUFF +
+What, with worms and flies?
+
+ +Son +
+With what I get, I mean; and so do they.
+
+ +LADY MACDUFF +
+Poor bird! thou'ldst never fear the net nor lime,
+The pitfall nor the gin.
+
+ +Son +
+Why should I, mother? Poor birds they are not set for.
+My father is not dead, for all your saying.
+
+ +LADY MACDUFF +
+Yes, he is dead; how wilt thou do for a father?
+
+ +Son +
+Nay, how will you do for a husband?
+
+ +LADY MACDUFF +
+Why, I can buy me twenty at any market.
+
+ +Son +
+Then you'll buy 'em to sell again.
+
+ +LADY MACDUFF +
+Thou speak'st with all thy wit: and yet, i' faith,
+With wit enough for thee.
+
+ +Son +
+Was my father a traitor, mother?
+
+ +LADY MACDUFF +
+Ay, that he was.
+
+ +Son +
+What is a traitor?
+
+ +LADY MACDUFF +
+Why, one that swears and lies.
+
+ +Son +
+And be all traitors that do so?
+
+ +LADY MACDUFF +
+Every one that does so is a traitor, and must be hanged.
+
+ +Son +
+And must they all be hanged that swear and lie?
+
+ +LADY MACDUFF +
+Every one.
+
+ +Son +
+Who must hang them?
+
+ +LADY MACDUFF +
+Why, the honest men.
+
+ +Son +
+Then the liars and swearers are fools,
+for there are liars and swearers enow to beat
+the honest men and hang up them.
+
+ +LADY MACDUFF +
+Now, God help thee, poor monkey!
+But how wilt thou do for a father?
+
+ +Son +
+If he were dead, you'ld weep for
+him: if you would not, it were a good sign
+that I should quickly have a new father.
+
+ +LADY MACDUFF +
+Poor prattler, how thou talk'st!
+

Enter a Messenger

+
+ +Messenger +
+Bless you, fair dame! I am not to you known,
+Though in your state of honour I am perfect.
+I doubt some danger does approach you nearly:
+If you will take a homely man's advice,
+Be not found here; hence, with your little ones.
+To fright you thus, methinks, I am too savage;
+To do worse to you were fell cruelty,
+Which is too nigh your person. Heaven preserve you!
+I dare abide no longer.
+

Exit

+
+ +LADY MACDUFF +
+Whither should I fly?
+I have done no harm. But I remember now
+I am in this earthly world; where to do harm
+Is often laudable, to do good sometime
+Accounted dangerous folly: why then, alas,
+Do I put up that womanly defence,
+To say I have done no harm?
+

Enter Murderers

+What are these faces?
+
+ +First Murderer +
+Where is your husband?
+
+ +LADY MACDUFF +
+I hope, in no place so unsanctified
+Where such as thou mayst find him.
+
+ +First Murderer +
+He's a traitor.
+
+ +Son +
+Thou liest, thou shag-hair'd villain!
+
+ +First Murderer +
+What, you egg!
+

Stabbing him

+Young fry of treachery!
+
+ +Son +
+He has kill'd me, mother:
+Run away, I pray you!
+

Dies

+

Exit LADY MACDUFF, crying 'Murder!' Exeunt Murderers, following her

+
+

SCENE III. England. Before the King's palace.

+

+Enter MALCOLM and MACDUFF +
+ +MALCOLM +
+Let us seek out some desolate shade, and there
+Weep our sad bosoms empty.
+
+ +MACDUFF +
+Let us rather
+Hold fast the mortal sword, and like good men
+Bestride our down-fall'n birthdom: each new morn
+New widows howl, new orphans cry, new sorrows
+Strike heaven on the face, that it resounds
+As if it felt with Scotland and yell'd out
+Like syllable of dolour.
+
+ +MALCOLM +
+What I believe I'll wail,
+What know believe, and what I can redress,
+As I shall find the time to friend, I will.
+What you have spoke, it may be so perchance.
+This tyrant, whose sole name blisters our tongues,
+Was once thought honest: you have loved him well.
+He hath not touch'd you yet. I am young;
+but something
+You may deserve of him through me, and wisdom
+To offer up a weak poor innocent lamb
+To appease an angry god.
+
+ +MACDUFF +
+I am not treacherous.
+
+ +MALCOLM +
+But Macbeth is.
+A good and virtuous nature may recoil
+In an imperial charge. But I shall crave
+your pardon;
+That which you are my thoughts cannot transpose:
+Angels are bright still, though the brightest fell;
+Though all things foul would wear the brows of grace,
+Yet grace must still look so.
+
+ +MACDUFF +
+I have lost my hopes.
+
+ +MALCOLM +
+Perchance even there where I did find my doubts.
+Why in that rawness left you wife and child,
+Those precious motives, those strong knots of love,
+Without leave-taking? I pray you,
+Let not my jealousies be your dishonours,
+But mine own safeties. You may be rightly just,
+Whatever I shall think.
+
+ +MACDUFF +
+Bleed, bleed, poor country!
+Great tyranny! lay thou thy basis sure,
+For goodness dare not cheque thee: wear thou
+thy wrongs;
+The title is affeer'd! Fare thee well, lord:
+I would not be the villain that thou think'st
+For the whole space that's in the tyrant's grasp,
+And the rich East to boot.
+
+ +MALCOLM +
+Be not offended:
+I speak not as in absolute fear of you.
+I think our country sinks beneath the yoke;
+It weeps, it bleeds; and each new day a gash
+Is added to her wounds: I think withal
+There would be hands uplifted in my right;
+And here from gracious England have I offer
+Of goodly thousands: but, for all this,
+When I shall tread upon the tyrant's head,
+Or wear it on my sword, yet my poor country
+Shall have more vices than it had before,
+More suffer and more sundry ways than ever,
+By him that shall succeed.
+
+ +MACDUFF +
+What should he be?
+
+ +MALCOLM +
+It is myself I mean: in whom I know
+All the particulars of vice so grafted
+That, when they shall be open'd, black Macbeth
+Will seem as pure as snow, and the poor state
+Esteem him as a lamb, being compared
+With my confineless harms.
+
+ +MACDUFF +
+Not in the legions
+Of horrid hell can come a devil more damn'd
+In evils to top Macbeth.
+
+ +MALCOLM +
+I grant him bloody,
+Luxurious, avaricious, false, deceitful,
+Sudden, malicious, smacking of every sin
+That has a name: but there's no bottom, none,
+In my voluptuousness: your wives, your daughters,
+Your matrons and your maids, could not fill up
+The cistern of my lust, and my desire
+All continent impediments would o'erbear
+That did oppose my will: better Macbeth
+Than such an one to reign.
+
+ +MACDUFF +
+Boundless intemperance
+In nature is a tyranny; it hath been
+The untimely emptying of the happy throne
+And fall of many kings. But fear not yet
+To take upon you what is yours: you may
+Convey your pleasures in a spacious plenty,
+And yet seem cold, the time you may so hoodwink.
+We have willing dames enough: there cannot be
+That vulture in you, to devour so many
+As will to greatness dedicate themselves,
+Finding it so inclined.
+
+ +MALCOLM +
+With this there grows
+In my most ill-composed affection such
+A stanchless avarice that, were I king,
+I should cut off the nobles for their lands,
+Desire his jewels and this other's house:
+And my more-having would be as a sauce
+To make me hunger more; that I should forge
+Quarrels unjust against the good and loyal,
+Destroying them for wealth.
+
+ +MACDUFF +
+This avarice
+Sticks deeper, grows with more pernicious root
+Than summer-seeming lust, and it hath been
+The sword of our slain kings: yet do not fear;
+Scotland hath foisons to fill up your will.
+Of your mere own: all these are portable,
+With other graces weigh'd.
+
+ +MALCOLM +
+But I have none: the king-becoming graces,
+As justice, verity, temperance, stableness,
+Bounty, perseverance, mercy, lowliness,
+Devotion, patience, courage, fortitude,
+I have no relish of them, but abound
+In the division of each several crime,
+Acting it many ways. Nay, had I power, I should
+Pour the sweet milk of concord into hell,
+Uproar the universal peace, confound
+All unity on earth.
+
+ +MACDUFF +
+O Scotland, Scotland!
+
+ +MALCOLM +
+If such a one be fit to govern, speak:
+I am as I have spoken.
+
+ +MACDUFF +
+Fit to govern!
+No, not to live. O nation miserable,
+With an untitled tyrant bloody-scepter'd,
+When shalt thou see thy wholesome days again,
+Since that the truest issue of thy throne
+By his own interdiction stands accursed,
+And does blaspheme his breed? Thy royal father
+Was a most sainted king: the queen that bore thee,
+Oftener upon her knees than on her feet,
+Died every day she lived. Fare thee well!
+These evils thou repeat'st upon thyself
+Have banish'd me from Scotland. O my breast,
+Thy hope ends here!
+
+ +MALCOLM +
+Macduff, this noble passion,
+Child of integrity, hath from my soul
+Wiped the black scruples, reconciled my thoughts
+To thy good truth and honour. Devilish Macbeth
+By many of these trains hath sought to win me
+Into his power, and modest wisdom plucks me
+From over-credulous haste: but God above
+Deal between thee and me! for even now
+I put myself to thy direction, and
+Unspeak mine own detraction, here abjure
+The taints and blames I laid upon myself,
+For strangers to my nature. I am yet
+Unknown to woman, never was forsworn,
+Scarcely have coveted what was mine own,
+At no time broke my faith, would not betray
+The devil to his fellow and delight
+No less in truth than life: my first false speaking
+Was this upon myself: what I am truly,
+Is thine and my poor country's to command:
+Whither indeed, before thy here-approach,
+Old Siward, with ten thousand warlike men,
+Already at a point, was setting forth.
+Now we'll together; and the chance of goodness
+Be like our warranted quarrel! Why are you silent?
+
+ +MACDUFF +
+Such welcome and unwelcome things at once
+'Tis hard to reconcile.
+

Enter a Doctor

+
+ +MALCOLM +
+Well; more anon.--Comes the king forth, I pray you?
+
+ +Doctor +
+Ay, sir; there are a crew of wretched souls
+That stay his cure: their malady convinces
+The great assay of art; but at his touch--
+Such sanctity hath heaven given his hand--
+They presently amend.
+
+ +MALCOLM +
+I thank you, doctor.
+

Exit Doctor

+
+ +MACDUFF +
+What's the disease he means?
+
+ +MALCOLM +
+'Tis call'd the evil:
+A most miraculous work in this good king;
+Which often, since my here-remain in England,
+I have seen him do. How he solicits heaven,
+Himself best knows: but strangely-visited people,
+All swoln and ulcerous, pitiful to the eye,
+The mere despair of surgery, he cures,
+Hanging a golden stamp about their necks,
+Put on with holy prayers: and 'tis spoken,
+To the succeeding royalty he leaves
+The healing benediction. With this strange virtue,
+He hath a heavenly gift of prophecy,
+And sundry blessings hang about his throne,
+That speak him full of grace.
+

Enter ROSS

+
+ +MACDUFF +
+See, who comes here?
+
+ +MALCOLM +
+My countryman; but yet I know him not.
+
+ +MACDUFF +
+My ever-gentle cousin, welcome hither.
+
+ +MALCOLM +
+I know him now. Good God, betimes remove
+The means that makes us strangers!
+
+ +ROSS +
+Sir, amen.
+
+ +MACDUFF +
+Stands Scotland where it did?
+
+ +ROSS +
+Alas, poor country!
+Almost afraid to know itself. It cannot
+Be call'd our mother, but our grave; where nothing,
+But who knows nothing, is once seen to smile;
+Where sighs and groans and shrieks that rend the air
+Are made, not mark'd; where violent sorrow seems
+A modern ecstasy; the dead man's knell
+Is there scarce ask'd for who; and good men's lives
+Expire before the flowers in their caps,
+Dying or ere they sicken.
+
+ +MACDUFF +
+O, relation
+Too nice, and yet too true!
+
+ +MALCOLM +
+What's the newest grief?
+
+ +ROSS +
+That of an hour's age doth hiss the speaker:
+Each minute teems a new one.
+
+ +MACDUFF +
+How does my wife?
+
+ +ROSS +
+Why, well.
+
+ +MACDUFF +
+ And all my children?
+
+ +ROSS +
+Well too.
+
+ +MACDUFF +
+The tyrant has not batter'd at their peace?
+
+ +ROSS +
+No; they were well at peace when I did leave 'em.
+
+ +MACDUFF +
+But not a niggard of your speech: how goes't?
+
+ +ROSS +
+When I came hither to transport the tidings,
+Which I have heavily borne, there ran a rumour
+Of many worthy fellows that were out;
+Which was to my belief witness'd the rather,
+For that I saw the tyrant's power a-foot:
+Now is the time of help; your eye in Scotland
+Would create soldiers, make our women fight,
+To doff their dire distresses.
+
+ +MALCOLM +
+Be't their comfort
+We are coming thither: gracious England hath
+Lent us good Siward and ten thousand men;
+An older and a better soldier none
+That Christendom gives out.
+
+ +ROSS +
+Would I could answer
+This comfort with the like! But I have words
+That would be howl'd out in the desert air,
+Where hearing should not latch them.
+
+ +MACDUFF +
+What concern they?
+The general cause? or is it a fee-grief
+Due to some single breast?
+
+ +ROSS +
+No mind that's honest
+But in it shares some woe; though the main part
+Pertains to you alone.
+
+ +MACDUFF +
+If it be mine,
+Keep it not from me, quickly let me have it.
+
+ +ROSS +
+Let not your ears despise my tongue for ever,
+Which shall possess them with the heaviest sound
+That ever yet they heard.
+
+ +MACDUFF +
+Hum! I guess at it.
+
+ +ROSS +
+Your castle is surprised; your wife and babes
+Savagely slaughter'd: to relate the manner,
+Were, on the quarry of these murder'd deer,
+To add the death of you.
+
+ +MALCOLM +
+Merciful heaven!
+What, man! ne'er pull your hat upon your brows;
+Give sorrow words: the grief that does not speak
+Whispers the o'er-fraught heart and bids it break.
+
+ +MACDUFF +
+My children too?
+
+ +ROSS +
+ Wife, children, servants, all
+That could be found.
+
+ +MACDUFF +
+And I must be from thence!
+My wife kill'd too?
+
+ +ROSS +
+I have said.
+
+ +MALCOLM +
+Be comforted:
+Let's make us medicines of our great revenge,
+To cure this deadly grief.
+
+ +MACDUFF +
+He has no children. All my pretty ones?
+Did you say all? O hell-kite! All?
+What, all my pretty chickens and their dam
+At one fell swoop?
+
+ +MALCOLM +
+Dispute it like a man.
+
+ +MACDUFF +
+I shall do so;
+But I must also feel it as a man:
+I cannot but remember such things were,
+That were most precious to me. Did heaven look on,
+And would not take their part? Sinful Macduff,
+They were all struck for thee! naught that I am,
+Not for their own demerits, but for mine,
+Fell slaughter on their souls. Heaven rest them now!
+
+ +MALCOLM +
+Be this the whetstone of your sword: let grief
+Convert to anger; blunt not the heart, enrage it.
+
+ +MACDUFF +
+O, I could play the woman with mine eyes
+And braggart with my tongue! But, gentle heavens,
+Cut short all intermission; front to front
+Bring thou this fiend of Scotland and myself;
+Within my sword's length set him; if he 'scape,
+Heaven forgive him too!
+
+ +MALCOLM +
+This tune goes manly.
+Come, go we to the king; our power is ready;
+Our lack is nothing but our leave; Macbeth
+Is ripe for shaking, and the powers above
+Put on their instruments. Receive what cheer you may:
+The night is long that never finds the day.
+

Exeunt

+

+

ACT V

+

SCENE I. Dunsinane. Ante-room in the castle.

+

+Enter a Doctor of Physic and a Waiting-Gentlewoman +
+ +Doctor +
+I have two nights watched with you, but can perceive
+no truth in your report. When was it she last walked?
+
+ +Gentlewoman +
+Since his majesty went into the field, I have seen
+her rise from her bed, throw her night-gown upon
+her, unlock her closet, take forth paper, fold it,
+write upon't, read it, afterwards seal it, and again
+return to bed; yet all this while in a most fast sleep.
+
+ +Doctor +
+A great perturbation in nature, to receive at once
+the benefit of sleep, and do the effects of
+watching! In this slumbery agitation, besides her
+walking and other actual performances, what, at any
+time, have you heard her say?
+
+ +Gentlewoman +
+That, sir, which I will not report after her.
+
+ +Doctor +
+You may to me: and 'tis most meet you should.
+
+ +Gentlewoman +
+Neither to you nor any one; having no witness to
+confirm my speech.
+

Enter LADY MACBETH, with a taper

+Lo you, here she comes! This is her very guise;
+and, upon my life, fast asleep. Observe her; stand close.
+
+ +Doctor +
+How came she by that light?
+
+ +Gentlewoman +
+Why, it stood by her: she has light by her
+continually; 'tis her command.
+
+ +Doctor +
+You see, her eyes are open.
+
+ +Gentlewoman +
+Ay, but their sense is shut.
+
+ +Doctor +
+What is it she does now? Look, how she rubs her hands.
+
+ +Gentlewoman +
+It is an accustomed action with her, to seem thus
+washing her hands: I have known her continue in
+this a quarter of an hour.
+
+ +LADY MACBETH +
+Yet here's a spot.
+
+ +Doctor +
+Hark! she speaks: I will set down what comes from
+her, to satisfy my remembrance the more strongly.
+
+ +LADY MACBETH +
+Out, damned spot! out, I say!--One: two: why,
+then, 'tis time to do't.--Hell is murky!--Fie, my
+lord, fie! a soldier, and afeard? What need we
+fear who knows it, when none can call our power to
+account?--Yet who would have thought the old man
+to have had so much blood in him.
+
+ +Doctor +
+Do you mark that?
+
+ +LADY MACBETH +
+The thane of Fife had a wife: where is she now?--
+What, will these hands ne'er be clean?--No more o'
+that, my lord, no more o' that: you mar all with
+this starting.
+
+ +Doctor +
+Go to, go to; you have known what you should not.
+
+ +Gentlewoman +
+She has spoke what she should not, I am sure of
+that: heaven knows what she has known.
+
+ +LADY MACBETH +
+Here's the smell of the blood still: all the
+perfumes of Arabia will not sweeten this little
+hand. Oh, oh, oh!
+
+ +Doctor +
+What a sigh is there! The heart is sorely charged.
+
+ +Gentlewoman +
+I would not have such a heart in my bosom for the
+dignity of the whole body.
+
+ +Doctor +
+Well, well, well,--
+
+ +Gentlewoman +
+Pray God it be, sir.
+
+ +Doctor +
+This disease is beyond my practise: yet I have known
+those which have walked in their sleep who have died
+holily in their beds.
+
+ +LADY MACBETH +
+Wash your hands, put on your nightgown; look not so
+pale.--I tell you yet again, Banquo's buried; he
+cannot come out on's grave.
+
+ +Doctor +
+Even so?
+
+ +LADY MACBETH +
+To bed, to bed! there's knocking at the gate:
+come, come, come, come, give me your hand. What's
+done cannot be undone.--To bed, to bed, to bed!
+

Exit

+
+ +Doctor +
+Will she go now to bed?
+
+ +Gentlewoman +
+Directly.
+
+ +Doctor +
+Foul whisperings are abroad: unnatural deeds
+Do breed unnatural troubles: infected minds
+To their deaf pillows will discharge their secrets:
+More needs she the divine than the physician.
+God, God forgive us all! Look after her;
+Remove from her the means of all annoyance,
+And still keep eyes upon her. So, good night:
+My mind she has mated, and amazed my sight.
+I think, but dare not speak.
+
+ +Gentlewoman +
+Good night, good doctor.
+

Exeunt

+
+

SCENE II. The country near Dunsinane.

+

+Drum and colours. Enter MENTEITH, CAITHNESS, ANGUS, LENNOX, and Soldiers +
+ +MENTEITH +
+The English power is near, led on by Malcolm,
+His uncle Siward and the good Macduff:
+Revenges burn in them; for their dear causes
+Would to the bleeding and the grim alarm
+Excite the mortified man.
+
+ +ANGUS +
+Near Birnam wood
+Shall we well meet them; that way are they coming.
+
+ +CAITHNESS +
+Who knows if Donalbain be with his brother?
+
+ +LENNOX +
+For certain, sir, he is not: I have a file
+Of all the gentry: there is Siward's son,
+And many unrough youths that even now
+Protest their first of manhood.
+
+ +MENTEITH +
+What does the tyrant?
+
+ +CAITHNESS +
+Great Dunsinane he strongly fortifies:
+Some say he's mad; others that lesser hate him
+Do call it valiant fury: but, for certain,
+He cannot buckle his distemper'd cause
+Within the belt of rule.
+
+ +ANGUS +
+Now does he feel
+His secret murders sticking on his hands;
+Now minutely revolts upbraid his faith-breach;
+Those he commands move only in command,
+Nothing in love: now does he feel his title
+Hang loose about him, like a giant's robe
+Upon a dwarfish thief.
+
+ +MENTEITH +
+Who then shall blame
+His pester'd senses to recoil and start,
+When all that is within him does condemn
+Itself for being there?
+
+ +CAITHNESS +
+Well, march we on,
+To give obedience where 'tis truly owed:
+Meet we the medicine of the sickly weal,
+And with him pour we in our country's purge
+Each drop of us.
+
+ +LENNOX +
+ Or so much as it needs,
+To dew the sovereign flower and drown the weeds.
+Make we our march towards Birnam.
+

Exeunt, marching

+
+

SCENE III. Dunsinane. A room in the castle.

+

+Enter MACBETH, Doctor, and Attendants +
+ +MACBETH +
+Bring me no more reports; let them fly all:
+Till Birnam wood remove to Dunsinane,
+I cannot taint with fear. What's the boy Malcolm?
+Was he not born of woman? The spirits that know
+All mortal consequences have pronounced me thus:
+'Fear not, Macbeth; no man that's born of woman
+Shall e'er have power upon thee.' Then fly,
+false thanes,
+And mingle with the English epicures:
+The mind I sway by and the heart I bear
+Shall never sag with doubt nor shake with fear.
+

Enter a Servant

+The devil damn thee black, thou cream-faced loon!
+Where got'st thou that goose look?
+
+ +Servant +
+There is ten thousand--
+
+ +MACBETH +
+Geese, villain!
+
+ +Servant +
+Soldiers, sir.
+
+ +MACBETH +
+Go prick thy face, and over-red thy fear,
+Thou lily-liver'd boy. What soldiers, patch?
+Death of thy soul! those linen cheeks of thine
+Are counsellors to fear. What soldiers, whey-face?
+
+ +Servant +
+The English force, so please you.
+
+ +MACBETH +
+Take thy face hence.
+

Exit Servant

+Seyton!--I am sick at heart,
+When I behold--Seyton, I say!--This push
+Will cheer me ever, or disseat me now.
+I have lived long enough: my way of life
+Is fall'n into the sear, the yellow leaf;
+And that which should accompany old age,
+As honour, love, obedience, troops of friends,
+I must not look to have; but, in their stead,
+Curses, not loud but deep, mouth-honour, breath,
+Which the poor heart would fain deny, and dare not. Seyton!
+

Enter SEYTON

+
+ +SEYTON +
+What is your gracious pleasure?
+
+ +MACBETH +
+What news more?
+
+ +SEYTON +
+All is confirm'd, my lord, which was reported.
+
+ +MACBETH +
+I'll fight till from my bones my flesh be hack'd.
+Give me my armour.
+
+ +SEYTON +
+'Tis not needed yet.
+
+ +MACBETH +
+I'll put it on.
+Send out more horses; skirr the country round;
+Hang those that talk of fear. Give me mine armour.
+How does your patient, doctor?
+
+ +Doctor +
+Not so sick, my lord,
+As she is troubled with thick coming fancies,
+That keep her from her rest.
+
+ +MACBETH +
+Cure her of that.
+Canst thou not minister to a mind diseased,
+Pluck from the memory a rooted sorrow,
+Raze out the written troubles of the brain
+And with some sweet oblivious antidote
+Cleanse the stuff'd bosom of that perilous stuff
+Which weighs upon the heart?
+
+ +Doctor +
+Therein the patient
+Must minister to himself.
+
+ +MACBETH +
+Throw physic to the dogs; I'll none of it.
+Come, put mine armour on; give me my staff.
+Seyton, send out. Doctor, the thanes fly from me.
+Come, sir, dispatch. If thou couldst, doctor, cast
+The water of my land, find her disease,
+And purge it to a sound and pristine health,
+I would applaud thee to the very echo,
+That should applaud again.--Pull't off, I say.--
+What rhubarb, cyme, or what purgative drug,
+Would scour these English hence? Hear'st thou of them?
+
+ +Doctor +
+Ay, my good lord; your royal preparation
+Makes us hear something.
+
+ +MACBETH +
+Bring it after me.
+I will not be afraid of death and bane,
+Till Birnam forest come to Dunsinane.
+
+ +Doctor +
+[Aside] Were I from Dunsinane away and clear,
+Profit again should hardly draw me here.
+

Exeunt

+
+

SCENE IV. Country near Birnam wood.

+

+Drum and colours. Enter MALCOLM, SIWARD and YOUNG SIWARD, MACDUFF, MENTEITH, CAITHNESS, ANGUS, LENNOX, ROSS, and Soldiers, marching +
+ +MALCOLM +
+Cousins, I hope the days are near at hand
+That chambers will be safe.
+
+ +MENTEITH +
+We doubt it nothing.
+
+ +SIWARD +
+What wood is this before us?
+
+ +MENTEITH +
+The wood of Birnam.
+
+ +MALCOLM +
+Let every soldier hew him down a bough
+And bear't before him: thereby shall we shadow
+The numbers of our host and make discovery
+Err in report of us.
+
+ +Soldiers +
+It shall be done.
+
+ +SIWARD +
+We learn no other but the confident tyrant
+Keeps still in Dunsinane, and will endure
+Our setting down before 't.
+
+ +MALCOLM +
+'Tis his main hope:
+For where there is advantage to be given,
+Both more and less have given him the revolt,
+And none serve with him but constrained things
+Whose hearts are absent too.
+
+ +MACDUFF +
+Let our just censures
+Attend the true event, and put we on
+Industrious soldiership.
+
+ +SIWARD +
+The time approaches
+That will with due decision make us know
+What we shall say we have and what we owe.
+Thoughts speculative their unsure hopes relate,
+But certain issue strokes must arbitrate:
+Towards which advance the war.
+

Exeunt, marching

+
+

SCENE V. Dunsinane. Within the castle.

+

+Enter MACBETH, SEYTON, and Soldiers, with drum and colours +
+ +MACBETH +
+Hang out our banners on the outward walls;
+The cry is still 'They come:' our castle's strength
+Will laugh a siege to scorn: here let them lie
+Till famine and the ague eat them up:
+Were they not forced with those that should be ours,
+We might have met them dareful, beard to beard,
+And beat them backward home.
+

A cry of women within

+What is that noise?
+
+ +SEYTON +
+It is the cry of women, my good lord.
+

Exit

+
+ +MACBETH +
+I have almost forgot the taste of fears;
+The time has been, my senses would have cool'd
+To hear a night-shriek; and my fell of hair
+Would at a dismal treatise rouse and stir
+As life were in't: I have supp'd full with horrors;
+Direness, familiar to my slaughterous thoughts
+Cannot once start me.
+

Re-enter SEYTON

+Wherefore was that cry?
+
+ +SEYTON +
+The queen, my lord, is dead.
+
+ +MACBETH +
+She should have died hereafter;
+There would have been a time for such a word.
+To-morrow, and to-morrow, and to-morrow,
+Creeps in this petty pace from day to day
+To the last syllable of recorded time,
+And all our yesterdays have lighted fools
+The way to dusty death. Out, out, brief candle!
+Life's but a walking shadow, a poor player
+That struts and frets his hour upon the stage
+And then is heard no more: it is a tale
+Told by an idiot, full of sound and fury,
+Signifying nothing.
+

Enter a Messenger

+Thou comest to use thy tongue; thy story quickly.
+
+ +Messenger +
+Gracious my lord,
+I should report that which I say I saw,
+But know not how to do it.
+
+ +MACBETH +
+Well, say, sir.
+
+ +Messenger +
+As I did stand my watch upon the hill,
+I look'd toward Birnam, and anon, methought,
+The wood began to move.
+
+ +MACBETH +
+Liar and slave!
+
+ +Messenger +
+Let me endure your wrath, if't be not so:
+Within this three mile may you see it coming;
+I say, a moving grove.
+
+ +MACBETH +
+If thou speak'st false,
+Upon the next tree shalt thou hang alive,
+Till famine cling thee: if thy speech be sooth,
+I care not if thou dost for me as much.
+I pull in resolution, and begin
+To doubt the equivocation of the fiend
+That lies like truth: 'Fear not, till Birnam wood
+Do come to Dunsinane:' and now a wood
+Comes toward Dunsinane. Arm, arm, and out!
+If this which he avouches does appear,
+There is nor flying hence nor tarrying here.
+I gin to be aweary of the sun,
+And wish the estate o' the world were now undone.
+Ring the alarum-bell! Blow, wind! come, wrack!
+At least we'll die with harness on our back.
+

Exeunt

+
+

SCENE VI. Dunsinane. Before the castle.

+

+Drum and colours. Enter MALCOLM, SIWARD, MACDUFF, and their Army, with boughs +
+ +MALCOLM +
+Now near enough: your leafy screens throw down.
+And show like those you are. You, worthy uncle,
+Shall, with my cousin, your right-noble son,
+Lead our first battle: worthy Macduff and we
+Shall take upon 's what else remains to do,
+According to our order.
+
+ +SIWARD +
+Fare you well.
+Do we but find the tyrant's power to-night,
+Let us be beaten, if we cannot fight.
+
+ +MACDUFF +
+Make all our trumpets speak; give them all breath,
+Those clamorous harbingers of blood and death.
+

Exeunt

+
+

SCENE VII. Another part of the field.

+

+Alarums. Enter MACBETH +
+ +MACBETH +
+They have tied me to a stake; I cannot fly,
+But, bear-like, I must fight the course. What's he
+That was not born of woman? Such a one
+Am I to fear, or none.
+

Enter YOUNG SIWARD

+
+ +YOUNG SIWARD +
+What is thy name?
+
+ +MACBETH +
+ Thou'lt be afraid to hear it.
+
+ +YOUNG SIWARD +
+No; though thou call'st thyself a hotter name
+Than any is in hell.
+
+ +MACBETH +
+My name's Macbeth.
+
+ +YOUNG SIWARD +
+The devil himself could not pronounce a title
+More hateful to mine ear.
+
+ +MACBETH +
+No, nor more fearful.
+
+ +YOUNG SIWARD +
+Thou liest, abhorred tyrant; with my sword
+I'll prove the lie thou speak'st.
+

They fight and YOUNG SIWARD is slain

+
+ +MACBETH +
+Thou wast born of woman
+But swords I smile at, weapons laugh to scorn,
+Brandish'd by man that's of a woman born.
+

Exit

+

Alarums. Enter MACDUFF

+
+ +MACDUFF +
+That way the noise is. Tyrant, show thy face!
+If thou be'st slain and with no stroke of mine,
+My wife and children's ghosts will haunt me still.
+I cannot strike at wretched kerns, whose arms
+Are hired to bear their staves: either thou, Macbeth,
+Or else my sword with an unbatter'd edge
+I sheathe again undeeded. There thou shouldst be;
+By this great clatter, one of greatest note
+Seems bruited. Let me find him, fortune!
+And more I beg not.
+

Exit. Alarums

+

Enter MALCOLM and SIWARD

+
+ +SIWARD +
+This way, my lord; the castle's gently render'd:
+The tyrant's people on both sides do fight;
+The noble thanes do bravely in the war;
+The day almost itself professes yours,
+And little is to do.
+
+ +MALCOLM +
+We have met with foes
+That strike beside us.
+
+ +SIWARD +
+Enter, sir, the castle.
+

Exeunt. Alarums

+
+

SCENE VIII. Another part of the field.

+

+Enter MACBETH +
+ +MACBETH +
+Why should I play the Roman fool, and die
+On mine own sword? whiles I see lives, the gashes
+Do better upon them.
+

Enter MACDUFF

+
+ +MACDUFF +
+Turn, hell-hound, turn!
+
+ +MACBETH +
+Of all men else I have avoided thee:
+But get thee back; my soul is too much charged
+With blood of thine already.
+
+ +MACDUFF +
+I have no words:
+My voice is in my sword: thou bloodier villain
+Than terms can give thee out!
+

They fight

+
+ +MACBETH +
+Thou losest labour:
+As easy mayst thou the intrenchant air
+With thy keen sword impress as make me bleed:
+Let fall thy blade on vulnerable crests;
+I bear a charmed life, which must not yield,
+To one of woman born.
+
+ +MACDUFF +
+Despair thy charm;
+And let the angel whom thou still hast served
+Tell thee, Macduff was from his mother's womb
+Untimely ripp'd.
+
+ +MACBETH +
+Accursed be that tongue that tells me so,
+For it hath cow'd my better part of man!
+And be these juggling fiends no more believed,
+That palter with us in a double sense;
+That keep the word of promise to our ear,
+And break it to our hope. I'll not fight with thee.
+
+ +MACDUFF +
+Then yield thee, coward,
+And live to be the show and gaze o' the time:
+We'll have thee, as our rarer monsters are,
+Painted on a pole, and underwrit,
+'Here may you see the tyrant.'
+
+ +MACBETH +
+I will not yield,
+To kiss the ground before young Malcolm's feet,
+And to be baited with the rabble's curse.
+Though Birnam wood be come to Dunsinane,
+And thou opposed, being of no woman born,
+Yet I will try the last. Before my body
+I throw my warlike shield. Lay on, Macduff,
+And damn'd be him that first cries, 'Hold, enough!'
+

Exeunt, fighting. Alarums

+

Retreat. Flourish. Enter, with drum and colours, MALCOLM, SIWARD, ROSS, the other Thanes, and Soldiers

+
+ +MALCOLM +
+I would the friends we miss were safe arrived.
+
+ +SIWARD +
+Some must go off: and yet, by these I see,
+So great a day as this is cheaply bought.
+
+ +MALCOLM +
+Macduff is missing, and your noble son.
+
+ +ROSS +
+Your son, my lord, has paid a soldier's debt:
+He only lived but till he was a man;
+The which no sooner had his prowess confirm'd
+In the unshrinking station where he fought,
+But like a man he died.
+
+ +SIWARD +
+Then he is dead?
+
+ +ROSS +
+Ay, and brought off the field: your cause of sorrow
+Must not be measured by his worth, for then
+It hath no end.
+
+ +SIWARD +
+ Had he his hurts before?
+
+ +ROSS +
+Ay, on the front.
+
+ +SIWARD +
+ Why then, God's soldier be he!
+Had I as many sons as I have hairs,
+I would not wish them to a fairer death:
+And so, his knell is knoll'd.
+
+ +MALCOLM +
+He's worth more sorrow,
+And that I'll spend for him.
+
+ +SIWARD +
+He's worth no more
+They say he parted well, and paid his score:
+And so, God be with him! Here comes newer comfort.
+

Re-enter MACDUFF, with MACBETH's head

+
+ +MACDUFF +
+Hail, king! for so thou art: behold, where stands
+The usurper's cursed head: the time is free:
+I see thee compass'd with thy kingdom's pearl,
+That speak my salutation in their minds;
+Whose voices I desire aloud with mine:
+Hail, King of Scotland!
+
+ +ALL +
+Hail, King of Scotland!
+

Flourish

+
+ +MALCOLM +
+We shall not spend a large expense of time
+Before we reckon with your several loves,
+And make us even with you. My thanes and kinsmen,
+Henceforth be earls, the first that ever Scotland
+In such an honour named. What's more to do,
+Which would be planted newly with the time,
+As calling home our exiled friends abroad
+That fled the snares of watchful tyranny;
+Producing forth the cruel ministers
+Of this dead butcher and his fiend-like queen,
+Who, as 'tis thought, by self and violent hands
+Took off her life; this, and what needful else
+That calls upon us, by the grace of Grace,
+We will perform in measure, time and place:
+So, thanks to all at once and to each one,
+Whom we invite to see us crown'd at Scone.
+

Flourish. Exeunt

+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/map.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/map.png new file mode 100644 index 0000000..763f562 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/map.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/map_visibility.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/map_visibility.html new file mode 100644 index 0000000..6cf5f76 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/map_visibility.html @@ -0,0 +1,8 @@ + + + Map test page + + +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/markerTransparent.png b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/markerTransparent.png new file mode 100644 index 0000000..ed4e5e7 Binary files /dev/null and b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/markerTransparent.png differ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/messages.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/messages.html new file mode 100644 index 0000000..74f1a37 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/messages.html @@ -0,0 +1,15 @@ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/meta-redirect.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/meta-redirect.html new file mode 100644 index 0000000..9d9c2f0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/meta-redirect.html @@ -0,0 +1,11 @@ + + + Some test page + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/missedJsReference.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/missedJsReference.html new file mode 100644 index 0000000..6167752 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/missedJsReference.html @@ -0,0 +1,11 @@ + + + + Example page + + +

This page contains a nested iframe. Execute some JS to locate a reference to an element in this + frame and return it. You should need to switch to that frame in order to use that element.

+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_1.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_1.html new file mode 100644 index 0000000..4eff01a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_1.html @@ -0,0 +1,21 @@ + + +First Modal + + + + +

Modal dialog sample

+ + + +lnk2 +
+ +
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_2.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_2.html new file mode 100644 index 0000000..cec3f3f --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_2.html @@ -0,0 +1,21 @@ + + +Second Modal + + + + +

Modal dialog sample

+ + + +lnk3 +
+ +
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_3.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_3.html new file mode 100644 index 0000000..6c5eb72 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_3.html @@ -0,0 +1,15 @@ + + +Third Modal + + + + +

Modal dialog sample

+ + +
+ +
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modalindex.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modalindex.html new file mode 100644 index 0000000..0a1c4c9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modalindex.html @@ -0,0 +1,21 @@ + + +Main window + + + + +

Modal dialog sample

+ + + +lnk1 +
+ +
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/mouseOver.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/mouseOver.html new file mode 100644 index 0000000..d4751bf --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/mouseOver.html @@ -0,0 +1,17 @@ + + +
+
+
+ +
diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/mousePositionTracker.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/mousePositionTracker.html new file mode 100644 index 0000000..39a31cd --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/mousePositionTracker.html @@ -0,0 +1,33 @@ + + + + + + + + + Div tracking mouse position. +
+
+ Move mouse here. +
+

+0, 0 +

+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/nestedElements.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/nestedElements.html new file mode 100644 index 0000000..cf00083 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/nestedElements.html @@ -0,0 +1,155 @@ + + +

outside

+

outside

+
+

inside

+
+ + Here's a checkbox:
+ + + +
+ Here's a checkbox:
+ + +
+ +hello world + + + + + + +
+ Here's a checkbox:
+ +
+ +
+ Here's a checkbox:
+ + +
+ +hello world + + + + + + +
+ Here's a checkbox:
+ +
+ +
+ Here's a checkbox:
+ + +
+ +hello world + + + + + + +
+ Here's a checkbox:
+ +
+ +
+ Here's a checkbox:
+ + +
+ +hello world + + +Span with class of one +
+ Find me + Also me + But not me +
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow-body.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow-body.html new file mode 100644 index 0000000..2d2264c --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow-body.html @@ -0,0 +1,15 @@ + + + + The Visibility of Everyday Things + + + +

This image is copyright Simon Stewart and donated to the Selenium project for use in its test suites. +

+a nice beach + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_auto.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_auto.html new file mode 100644 index 0000000..cf8a647 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_hidden.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_hidden.html new file mode 100644 index 0000000..96fd750 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_scroll.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_scroll.html new file mode 100644 index 0000000..6f1d90b --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_auto.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_auto.html new file mode 100644 index 0000000..24dd192 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_hidden.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_hidden.html new file mode 100644 index 0000000..cae5665 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_scroll.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_scroll.html new file mode 100644 index 0000000..d4ffa39 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_auto.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_auto.html new file mode 100644 index 0000000..d425a2a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_hidden.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_hidden.html new file mode 100644 index 0000000..4a6ff59 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_scroll.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_scroll.html new file mode 100644 index 0000000..efa8074 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
+ +
+ Right clicked:
+ Bottom clicked:
+ Bottom-right clicked:
+
+ + Click bottom +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnBeforeUnloadMessage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnBeforeUnloadMessage.html new file mode 100644 index 0000000..cb59707 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnBeforeUnloadMessage.html @@ -0,0 +1,20 @@ + + + + + + Page with OnBeforeUnload handler + + +

Page with onbeforeunload event handler. Click here to navigate to another page.

+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnLoad.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnLoad.html new file mode 100644 index 0000000..2c644ff --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnLoad.html @@ -0,0 +1,6 @@ + + + +

Page with onload event handler

+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnUnload.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnUnload.html new file mode 100644 index 0000000..6070341 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnUnload.html @@ -0,0 +1,6 @@ + + + +

Page with onunload event handler

+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/page_with_link_to_slow_loading_page.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/page_with_link_to_slow_loading_page.html new file mode 100644 index 0000000..ea94f8e --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/page_with_link_to_slow_loading_page.html @@ -0,0 +1,6 @@ + + + +load a slow page + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/plain.txt b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/plain.txt new file mode 100644 index 0000000..8318c86 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/plain.txt @@ -0,0 +1 @@ +Test \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/proxy/page1.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/proxy/page1.html new file mode 100644 index 0000000..1810f1c --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/proxy/page1.html @@ -0,0 +1,20 @@ + + + +Page 1 +

The next query param must be the URL for the next page to +link to. + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/proxy/page2.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/proxy/page2.html new file mode 100644 index 0000000..d826f17 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/proxy/page2.html @@ -0,0 +1,24 @@ + + + +Page 2 +This page is a middle man for referrer tests. +This page will include a link to a "next" page if the next query +parameter, or the document.referrer is set. +

+ diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/proxy/page3.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/proxy/page3.html new file mode 100644 index 0000000..27048f7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/proxy/page3.html @@ -0,0 +1,5 @@ + + + +Page 3 +

diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/readOnlyPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/readOnlyPage.html new file mode 100644 index 0000000..8f257fd --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/readOnlyPage.html @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + +

This

is a

contentEditable area

+ +
+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/rectangles.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/rectangles.html new file mode 100644 index 0000000..8ba2339 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/rectangles.html @@ -0,0 +1,40 @@ + + + + Rectangles + + + +
r1
+
r2
+
r3
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/resultPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/resultPage.html new file mode 100644 index 0000000..94f3e24 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/resultPage.html @@ -0,0 +1,25 @@ + + + We Arrive Here + + + +

Success!

+ +
+

List of stuff

+
    +
  1. Item 1
  2. +
  3. Item 2
  4. +
+
+
+

Almost empty

+
+ + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/rich_text.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/rich_text.html new file mode 100644 index 0000000..a42e43a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/rich_text.html @@ -0,0 +1,161 @@ + + + + + + +
+
+
+ + + + + +
+
IFRAME
+ +
+
frame.contentWindow.document.designMode: on
frame.contentWindow.document.body.contentEditable: false
+
+
DIV
+
+
+
+
div.ownerDocument.designMode: off
div.ownerDocument.body.contentEditable: false
div.contentEditable: true
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
type:[]
tagName:[]
id:[]
keyIdentifier:[]
keyLocation:[]
keyCode:[]
charCode:[]
which:[]
isTrusted:[]
---------------------
Modifiers
alt:[]
ctrl:[]
shift:[]
meta:[]
+
+ + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/safari/frames_benchmark.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/safari/frames_benchmark.html new file mode 100644 index 0000000..8a05925 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/safari/frames_benchmark.html @@ -0,0 +1,31 @@ + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.css b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.css new file mode 100644 index 0000000..8152618 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.css @@ -0,0 +1,19 @@ +* { + margin: 0; +} +html, body, #output { + width: 100%; + height: 100%; +} +table { + border: 0px; + border-collapse: collapse; + border-spacing: 0px; + display: table; +} +table td { + padding: 0px; +} +.cell { + color: black; +} diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.html new file mode 100644 index 0000000..166665d --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.js new file mode 100644 index 0000000..1d16859 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.js @@ -0,0 +1,7 @@ +function toColor(num) { + num >>>= 0; + var b = num & 0xFF, + g = (num & 0xFF00) >>> 8, + r = (num & 0xFF0000) >>> 16; + return "rgb(" + [r, g, b].join(",") + ")"; +} \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame1.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame1.html new file mode 100644 index 0000000..35b03ae --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame1.html @@ -0,0 +1,72 @@ + + +screen frame1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame2.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame2.html new file mode 100644 index 0000000..e6e17e6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame2.html @@ -0,0 +1,72 @@ + + +screen frame2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frames.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frames.html new file mode 100644 index 0000000..46852dc --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frames.html @@ -0,0 +1,11 @@ + + + screen test + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_iframes.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_iframes.html new file mode 100644 index 0000000..ae3ea1e --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_iframes.html @@ -0,0 +1,12 @@ + + +Screen test + + +
+ + + +
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_too_long.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_too_long.html new file mode 100644 index 0000000..4d00f02 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_too_long.html @@ -0,0 +1,68 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_long.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_long.html new file mode 100644 index 0000000..1a6a100 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_too_long.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_too_long.html new file mode 100644 index 0000000..3fee005 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_too_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_long.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_long.html new file mode 100644 index 0000000..31733e0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_too_long.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_too_long.html new file mode 100644 index 0000000..dbef936 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_too_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
     
     
     
     
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll.html new file mode 100644 index 0000000..cd5214f --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll.html @@ -0,0 +1,27 @@ + + + + + +
+
    +
  • line1
  • +
  • line2
  • +
  • line3
  • +
  • line4
  • +
  • line5
  • +
  • line6
  • +
  • line7
  • +
  • line8
  • +
  • line9
  • +
+
+Clicked: +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll2.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll2.html new file mode 100644 index 0000000..0ea66d3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll2.html @@ -0,0 +1,21 @@ + + + + +
    +
  • +
  • +
  • Text
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll3.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll3.html new file mode 100644 index 0000000..1aa1709 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll3.html @@ -0,0 +1,8 @@ + + +



























































































































































+ +



+ +                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 +
























































































































































\ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll4.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll4.html new file mode 100644 index 0000000..652a778 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll4.html @@ -0,0 +1,7 @@ + + +


































































































+ +


































































































+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll5.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll5.html new file mode 100644 index 0000000..b345a8c --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scroll5.html @@ -0,0 +1,18 @@ + + + + + +
+
+
+
+
+Clicked: +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_200.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_200.html new file mode 100644 index 0000000..3eb3bf4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_200.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

This is a scrolling frame test

+
+ + + + + + + + + + + + + +
First row
Second row
Third row
Fourth row
+
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_2000.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_2000.html new file mode 100644 index 0000000..61ffe85 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_2000.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

This is a tall frame test

+
+ + + + + + + + + + + + + +
First row
Second row
Third row
Fourth row
+
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame.html new file mode 100644 index 0000000..1530138 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html new file mode 100644 index 0000000..5781aeb --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
Placeholder
+
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_small_height.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_small_height.html new file mode 100644 index 0000000..047de0f --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_small_height.html @@ -0,0 +1,10 @@ + + + + Child frame + + +

This is a non-scrolling frame test

+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_double_overflow_auto.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_double_overflow_auto.html new file mode 100644 index 0000000..01b7c30 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_double_overflow_auto.html @@ -0,0 +1,19 @@ + + + + Page with overflow: auto + + + +
Placeholder
+
+ Click me! +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_frame_out_of_view.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_frame_out_of_view.html new file mode 100644 index 0000000..c536e41 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
Placeholder
+
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames.html new file mode 100644 index 0000000..e5b7602 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html new file mode 100644 index 0000000..f79f7c8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
Placeholder
+
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_non_scrolling_frame.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_non_scrolling_frame.html new file mode 100644 index 0000000..0a493fa --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_non_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame.html new file mode 100644 index 0000000..cb5d53a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame_out_of_view.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame_out_of_view.html new file mode 100644 index 0000000..5df1115 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
Placeholder
+
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_tall_frame.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_tall_frame.html new file mode 100644 index 0000000..b7cfaf5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_tall_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_y_overflow_auto.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_y_overflow_auto.html new file mode 100644 index 0000000..b5716e7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_y_overflow_auto.html @@ -0,0 +1,14 @@ + + + + Page with overflow: auto + + +
+
Placeholder
+
+ Click me! +
+
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/target_page.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/target_page.html new file mode 100644 index 0000000..0457a82 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/target_page.html @@ -0,0 +1,9 @@ + + + +Clicked Successfully! + + +

Clicked Successfully!

+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/selectPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/selectPage.html new file mode 100644 index 0000000..4028414 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/selectPage.html @@ -0,0 +1,58 @@ + + + + +Multiple Selection test page + + + + + + + + + + + + + + + + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/selectableItems.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/selectableItems.html new file mode 100644 index 0000000..190b2ad --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/selectableItems.html @@ -0,0 +1,65 @@ + + + + + jQuery UI Selectable - Default functionality + + + + + + + + +
+ +
    +
  1. Item 1
  2. +
  3. Item 2
  4. +
  5. Item 3
  6. +
  7. Item 4
  8. +
  9. Item 5
  10. +
  11. Item 6
  12. +
  13. Item 7
  14. +
+ +
+ +
+ +

Enable a DOM element (or group of elements) to be selectable. Draw a box with your cursor to select items. Hold down the Ctrl key to make multiple non-adjacent selections.

+ + + +
+

no info

+
+ + +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/sessionCookie.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/sessionCookie.html new file mode 100644 index 0000000..0ada24e --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/sessionCookie.html @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/sessionCookieDest.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/sessionCookieDest.html new file mode 100644 index 0000000..f5e2ef2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/sessionCookieDest.html @@ -0,0 +1,34 @@ + + + + + Session cookie destination + + + +This is the cookie destination page. + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/simple.xml b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/simple.xml new file mode 100644 index 0000000..01f4c87 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/simple.xml @@ -0,0 +1,5 @@ + + + baz + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/simpleTest.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/simpleTest.html new file mode 100644 index 0000000..38210b9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/simpleTest.html @@ -0,0 +1,98 @@ + + + Hello WebDriver + + +

Heading

+ +

A single line of text

+ + +
+

A div containing

+ More than one line of text
+ +
and block level elements
+
+ +An inline element + +

This line has lots + + of spaces. +

+ +

This line has a non-breaking space

+ +

This line has a   non-breaking space and spaces

+ +

These lines  
  have leading and trailing NBSPs  

+ +

This line has text within elements that are meant to be displayed + inline

+ +
+

before pre

+
   This section has a preformatted
+    text block    
+  split in four lines
+         
+

after pre

+
+ +

Some text

Some more text

+ +
Cheese

Some text

Some more text

and also

Brie
+ +
Hello, world
+ +
+ +
+ +
+

+ + +

+
+ + + + + +
Top level
+
+
Nested
+
+ + + + + +
beforeSpace afterSpace
+ + + + + +a link to an icon + +{a="b", c=1, d=true} +{a="\\b\\\"'\'"} + +  â€â€‚        ​‌â€â€¯âŸâ ã€€test  â€â€‚        ​‌â€â€¯âŸâ ã€€ + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingAlert.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingAlert.html new file mode 100644 index 0000000..a6216e3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingAlert.html @@ -0,0 +1,10 @@ + + + +slowLoadingAlert + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingResourcePage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingResourcePage.html new file mode 100644 index 0000000..02796c3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingResourcePage.html @@ -0,0 +1,12 @@ + + + This page loads something slowly + + +

Simulate the situation where a web-bug or analytics script takes waaay + too long to respond. Normally these things are loaded in an iframe, which is + what we're doing here.

+ + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/slow_loading_iframes.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/slow_loading_iframes.html new file mode 100644 index 0000000..d007248 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/slow_loading_iframes.html @@ -0,0 +1,14 @@ + + + + Page with slow loading iFrames + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/styledPage.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/styledPage.html new file mode 100644 index 0000000..30810f0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/styledPage.html @@ -0,0 +1,28 @@ + + + + Styled Page + + + + +
+ +
+ + +
+ +
+ +
Content
+ + + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/svgPiechart.xhtml b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/svgPiechart.xhtml new file mode 100644 index 0000000..bf060fd --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/svgPiechart.xhtml @@ -0,0 +1,81 @@ + + + + + Pie Chart Test + + + +
+ Some text for the chart. +
+
Nothing.
+
+ + + + + Test Chart + + + Apple + + Orange + + Banana + + Orange + + + + + + + + Example RotateScale - Rotate and scale transforms + + + + + + + + + + + + + + ABC (rotate) + + + + + + + + + + + + ABC (scale) + + + + +
WOrange
+
+
WOrange
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/svgTest.svg b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/svgTest.svg new file mode 100644 index 0000000..c6cc283 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/svgTest.svg @@ -0,0 +1,4 @@ + + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/tables.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/tables.html new file mode 100644 index 0000000..a2bc957 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/tables.html @@ -0,0 +1,36 @@ + + + + Here be tables + + + + + + + + + +
HelloWorld(Cheese!)
+ + + + + +
some text +
some more text
+
+ + + + + + + + + +
Heading
Data 1Data 2
+ + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/tinymce.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/tinymce.html new file mode 100644 index 0000000..067b66c --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/tinymce.html @@ -0,0 +1,10 @@ + + + + TinyMCE + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/transformable.xml b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/transformable.xml new file mode 100644 index 0000000..0b7e7fd --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/transformable.xml @@ -0,0 +1,11 @@ + + + ]> + + +

Click the button.

+ + Go to another page + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/transformable.xsl b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/transformable.xsl new file mode 100644 index 0000000..53db9fd --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/transformable.xsl @@ -0,0 +1,37 @@ + + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/transparentUpload.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/transparentUpload.html new file mode 100644 index 0000000..87b02bf --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/transparentUpload.html @@ -0,0 +1,70 @@ + + + + Upload Form + + + + +
+
+
+ Upload + +
+
+
+ + +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/underscore.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/underscore.html new file mode 100644 index 0000000..904a444 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/underscore.html @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/unicode_ltr.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/unicode_ltr.html new file mode 100644 index 0000000..245acc7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/unicode_ltr.html @@ -0,0 +1,8 @@ + + + + + +
‎Some notes‎
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/upload.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/upload.html new file mode 100644 index 0000000..aca398a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/upload.html @@ -0,0 +1,45 @@ + + + + Upload Form + + + +
+
+ Enter a file to upload: +
+
+
+ + +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/userDefinedProperty.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/userDefinedProperty.html new file mode 100644 index 0000000..2453e69 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/userDefinedProperty.html @@ -0,0 +1,8 @@ + + +
+ + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/veryLargeCanvas.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/veryLargeCanvas.html new file mode 100644 index 0000000..54a2aba --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/veryLargeCanvas.html @@ -0,0 +1,81 @@ + + + + Rectangles + + + + +
+
First Target
+
Second Target
+
Third Target
+
Fourth Target
+
Not a Target
+
Not a Target
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/visibility-css.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/visibility-css.html new file mode 100644 index 0000000..80cc649 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/visibility-css.html @@ -0,0 +1,21 @@ + + + + +Visibility test via CSS + +
+

Hello world. I like cheese.

+
+ + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/win32frameset.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/win32frameset.html new file mode 100644 index 0000000..108b80f --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/win32frameset.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/page_with_frame.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/page_with_frame.html new file mode 100644 index 0000000..b94733b --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/page_with_frame.html @@ -0,0 +1,12 @@ + + + + Test page for WindowSwitchingTest.testShouldFocusOnTheTopMostFrameAfterSwitchingToAWindow + + +

Open new window

+
+ +
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/simple_page.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/simple_page.html new file mode 100644 index 0000000..52c163c --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/simple_page.html @@ -0,0 +1,9 @@ + + + + Simple Page + + +
Simple page with simple test.
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/xhtmlFormPage.xhtml b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/xhtmlFormPage.xhtml new file mode 100644 index 0000000..aca53d3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/xhtmlFormPage.xhtml @@ -0,0 +1,17 @@ + + + + XHTML + + + +
+ + +
+ +

Here is some content that should not be in the previous p tag + + + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/xhtmlTest.html b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/xhtmlTest.html new file mode 100644 index 0000000..d2f3a5d --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/data/xhtmlTest.html @@ -0,0 +1,76 @@ + + + + XHTML Test Page + + +

+ + + +
+

XHTML Might Be The Future

+ +

If you'd like to go elsewhere then click me.

+ +

Alternatively, this goes to the same place.

+ +
+ +
+ + This link has the same text as another link: click me. +
+ +
Another div starts here.

+

An H2 title

+

Some more text

+
+ +
+ Foo +
    + +
+ +
+
+
+ + +
+
+
+ + I have width +
+
+
+
+ + +

+

+
Link=equalssign + +

Spaced out

+ + +
first_div
+
second_div
+ first_span + second_span +
+ +
I'm a parent +
I'm a child
+
+ +
Woo woo
+ + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/fileserver.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/fileserver.js new file mode 100644 index 0000000..448b0c9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/fileserver.js @@ -0,0 +1,319 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fs = require('fs'), + http = require('http'), + path = require('path'), + url = require('url'); + +var express = require('express'); +var multer = require('multer'); +var serveIndex = require('serve-index'); + +var Server = require('./httpserver').Server, + resources = require('./resources'), + isDevMode = require('../devmode'), + promise = require('../promise'); + +var WEB_ROOT = '/common'; +var JS_ROOT = '/javascript'; + +var baseDirectory = resources.locate(isDevMode ? 'common/src/web' : '.'); +var jsDirectory = resources.locate(isDevMode ? 'javascript' : '..'); + +var Pages = (function() { + var pages = {}; + function addPage(page, path) { + pages.__defineGetter__(page, function() { + return exports.whereIs(path); + }); + } + + addPage('ajaxyPage', 'ajaxy_page.html'); + addPage('alertsPage', 'alerts.html'); + addPage('bodyTypingPage', 'bodyTypingTest.html'); + addPage('booleanAttributes', 'booleanAttributes.html'); + addPage('childPage', 'child/childPage.html'); + addPage('chinesePage', 'cn-test.html'); + addPage('clickJacker', 'click_jacker.html'); + addPage('clickEventPage', 'clickEventPage.html'); + addPage('clicksPage', 'clicks.html'); + addPage('colorPage', 'colorPage.html'); + addPage('deletingFrame', 'deletingFrame.htm'); + addPage('draggableLists', 'draggableLists.html'); + addPage('dragAndDropPage', 'dragAndDropTest.html'); + addPage('droppableItems', 'droppableItems.html'); + addPage('documentWrite', 'document_write_in_onload.html'); + addPage('dynamicallyModifiedPage', 'dynamicallyModifiedPage.html'); + addPage('dynamicPage', 'dynamic.html'); + addPage('echoPage', 'echo'); + addPage('errorsPage', 'errors.html'); + addPage('xhtmlFormPage', 'xhtmlFormPage.xhtml'); + addPage('formPage', 'formPage.html'); + addPage('formSelectionPage', 'formSelectionPage.html'); + addPage('framesetPage', 'frameset.html'); + addPage('grandchildPage', 'child/grandchild/grandchildPage.html'); + addPage('html5Page', 'html5Page.html'); + addPage('html5OfflinePage', 'html5/offline.html'); + addPage('iframePage', 'iframes.html'); + addPage('javascriptEnhancedForm', 'javascriptEnhancedForm.html'); + addPage('javascriptPage', 'javascriptPage.html'); + addPage('linkedImage', 'linked_image.html'); + addPage('longContentPage', 'longContentPage.html'); + addPage('macbethPage', 'macbeth.html'); + addPage('mapVisibilityPage', 'map_visibility.html'); + addPage('metaRedirectPage', 'meta-redirect.html'); + addPage('missedJsReferencePage', 'missedJsReference.html'); + addPage('mouseTrackerPage', 'mousePositionTracker.html'); + addPage('nestedPage', 'nestedElements.html'); + addPage('readOnlyPage', 'readOnlyPage.html'); + addPage('rectanglesPage', 'rectangles.html'); + addPage('redirectPage', 'redirect'); + addPage('resultPage', 'resultPage.html'); + addPage('richTextPage', 'rich_text.html'); + addPage('selectableItemsPage', 'selectableItems.html'); + addPage('selectPage', 'selectPage.html'); + addPage('simpleTestPage', 'simpleTest.html'); + addPage('simpleXmlDocument', 'simple.xml'); + addPage('sleepingPage', 'sleep'); + addPage('slowIframes', 'slow_loading_iframes.html'); + addPage('slowLoadingAlertPage', 'slowLoadingAlert.html'); + addPage('svgPage', 'svgPiechart.xhtml'); + addPage('tables', 'tables.html'); + addPage('underscorePage', 'underscore.html'); + addPage('unicodeLtrPage', 'utf8/unicode_ltr.html'); + addPage('uploadPage', 'upload.html'); + addPage('veryLargeCanvas', 'veryLargeCanvas.html'); + addPage('xhtmlTestPage', 'xhtmlTest.html'); + + return pages; +})(); + + +var Path = { + BASIC_AUTH: WEB_ROOT + '/basicAuth', + ECHO: WEB_ROOT + '/echo', + GENERATED: WEB_ROOT + '/generated', + MANIFEST: WEB_ROOT + '/manifest', + REDIRECT: WEB_ROOT + '/redirect', + PAGE: WEB_ROOT + '/page', + SLEEP: WEB_ROOT + '/sleep', + UPLOAD: WEB_ROOT + '/upload' +}; + +var app = express(); + +app.get('/', sendIndex) +.get('/favicon.ico', function(req, res) { + res.writeHead(204); + res.end(); +}) +.use(JS_ROOT, serveIndex(jsDirectory), express.static(jsDirectory)) +.post(Path.UPLOAD, handleUpload) +.use(WEB_ROOT, serveIndex(baseDirectory), express.static(baseDirectory)) +.get(Path.ECHO, sendEcho) +.get(Path.PAGE, sendInifinitePage) +.get(Path.PAGE + '/*', sendInifinitePage) +.get(Path.REDIRECT, redirectToResultPage) +.get(Path.SLEEP, sendDelayedResponse) + +if (isDevMode) { + var closureDir = resources.locate('third_party/closure/goog'); + app.use('/third_party/closure/goog', + serveIndex(closureDir), express.static(closureDir)); +} +var server = new Server(app); + + +function redirectToResultPage(_, response) { + response.writeHead(303, { + Location: Pages.resultPage + }); + return response.end(); +} + + +function sendInifinitePage(request, response) { + var pathname = url.parse(request.url).pathname; + var lastIndex = pathname.lastIndexOf('/'); + var pageNumber = + (lastIndex == -1 ? 'Unknown' : pathname.substring(lastIndex + 1)); + var body = [ + '', + 'Page', pageNumber, '', + 'Page number ', pageNumber, '', + '

top' + ].join(''); + response.writeHead(200, { + 'Content-Length': Buffer.byteLength(body, 'utf8'), + 'Content-Type': 'text/html; charset=utf-8' + }); + response.end(body); +} + + +function sendDelayedResponse(request, response) { + var duration = 0; + var query = url.parse(request.url).query || ''; + var match = query.match(/\btime=(\d+)/); + if (match) { + duration = parseInt(match[1], 10); + } + + setTimeout(function() { + var body = [ + '', + 'Done', + 'Slept for ', duration, 's' + ].join(''); + response.writeHead(200, { + 'Content-Length': Buffer.byteLength(body, 'utf8'), + 'Content-Type': 'text/html; charset=utf-8', + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache', + 'Expires': 0 + }); + response.end(body); + }, duration * 1000); +} + + +function handleUpload(request, response, next) { + multer({ + inMemory: true, + onFileUploadComplete: function(file) { + response.writeHead(200); + response.write(file.buffer); + response.end(''); + } + })(request, response, function() {}); +} + + +function sendEcho(request, response) { + var body = [ + '', + 'Echo', + '

', + request.method, ' ', request.url, ' ', 'HTTP/', request.httpVersion, + '
' + ]; + for (var name in request.headers) { + body.push('
', + name, ': ', request.headers[name], '
'); + } + body = body.join(''); + response.writeHead(200, { + 'Content-Length': Buffer.byteLength(body, 'utf8'), + 'Content-Type': 'text/html; charset=utf-8' + }); + response.end(body); +} + + +/** + * Responds to a request for the file server's main index. + * @param {!http.ServerRequest} request The request object. + * @param {!http.ServerResponse} response The response object. + */ +function sendIndex(request, response) { + var pathname = url.parse(request.url).pathname; + + var host = request.headers.host; + if (!host) { + host = server.host(); + } + + var requestUrl = ['http://' + host + pathname].join(''); + + function createListEntry(path) { + var url = requestUrl + path; + return ['
  • ', path, ''].join(''); + } + + var data = ['

    /


      ', + createListEntry('common')]; + if (isDevMode) { + data.push(createListEntry('javascript')); + } + data.push('
    '); + data = data.join(''); + + response.writeHead(200, { + 'Content-Type': 'text/html; charset=UTF-8', + 'Content-Length': Buffer.byteLength(data, 'utf8') + }); + response.end(data); +} + + +// PUBLIC application + + +/** + * Starts the server on the specified port. + * @param {number=} opt_port The port to use, or 0 for any free port. + * @return {!webdriver.promise.Promise.} A promise that will resolve + * with the server host when it has fully started. + */ +exports.start = server.start.bind(server); + + +/** + * Stops the server. + * @return {!webdriver.promise.Promise} A promise that will resolve when the + * server has closed all connections. + */ +exports.stop = server.stop.bind(server); + + +/** + * Formats a URL for this server. + * @param {string=} opt_pathname The desired pathname on the server. + * @return {string} The formatted URL. + * @throws {Error} If the server is not running. + */ +exports.url = server.url.bind(server); + + +/** + * Builds the URL for a file in the //common/src/web directory of the + * Selenium client. + * @param {string} filePath A path relative to //common/src/web to compute a + * URL for. + * @return {string} The formatted URL. + * @throws {Error} If the server is not running. + */ +exports.whereIs = function(filePath) { + filePath = filePath.replace(/\\/g, '/'); + if (!filePath.startsWith('/')) { + filePath = '/' + filePath; + } + return server.url(WEB_ROOT + filePath); +}; + + +exports.Pages = Pages; + + +if (require.main === module) { + server.start(2310).then(function() { + console.log('Server running at ' + server.url()); + }); +} diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/httpserver.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/httpserver.js new file mode 100644 index 0000000..55b1255 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/httpserver.js @@ -0,0 +1,122 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'), + http = require('http'), + url = require('url'); + +var net = require('../../net'), + portprober = require('../../net/portprober'), + promise = require('../..').promise; + + + +/** + * Encapsulates a simple HTTP server for testing. The {@code onrequest} + * function should be overridden to define request handling behavior. + * @param {function(!http.ServerRequest, !http.ServerResponse)} requestHandler + * The request handler for the server. + * @constructor + */ +var Server = function(requestHandler) { + var server = http.createServer(function(req, res) { + requestHandler(req, res); + }); + + server.on('connection', function(stream) { + stream.setTimeout(4000); + }); + + /** @typedef {{port: number, address: string, family: string}} */ + var Host; + + /** + * Starts the server on the given port. If no port, or 0, is provided, + * the server will be started on a random port. + * @param {number=} opt_port The port to start on. + * @return {!webdriver.promise.Promise.} A promise that will resolve + * with the server host when it has fully started. + */ + this.start = function(opt_port) { + assert(typeof opt_port !== 'function', + "start invoked with function, not port (mocha callback)?"); + var port = opt_port || portprober.findFreePort('localhost'); + return promise.when(port, function(port) { + return promise.checkedNodeCall( + server.listen.bind(server, port, 'localhost')); + }).then(function() { + return server.address(); + }); + }; + + /** + * Stops the server. + * @return {!webdriver.promise.Promise} A promise that will resolve when the + * server has closed all connections. + */ + this.stop = function() { + var d = promise.defer(); + server.close(d.fulfill); + return d.promise; + }; + + /** + * @return {Host} This server's host info. + * @throws {Error} If the server is not running. + */ + this.address = function() { + var addr = server.address(); + if (!addr) { + throw Error('There server is not running!'); + } + return addr; + }; + + /** + * return {string} The host:port of this server. + * @throws {Error} If the server is not running. + */ + this.host = function() { + return net.getLoopbackAddress() + ':' + + this.address().port; + }; + + /** + * Formats a URL for this server. + * @param {string=} opt_pathname The desired pathname on the server. + * @return {string} The formatted URL. + * @throws {Error} If the server is not running. + */ + this.url = function(opt_pathname) { + var addr = this.address(); + var pathname = opt_pathname || ''; + return url.format({ + protocol: 'http', + hostname: net.getLoopbackAddress(), + port: addr.port, + pathname: pathname + }); + }; +}; + + +// PUBLIC API + + +exports.Server = Server; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/index.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/index.js new file mode 100644 index 0000000..8f576a8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/index.js @@ -0,0 +1,262 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'); + +var build = require('./build'), + isDevMode = require('../devmode'), + webdriver = require('../../'), + flow = webdriver.promise.controlFlow(), + remote = require('../../remote'), + testing = require('../../testing'), + fileserver = require('./fileserver'); + + +/** + * Browsers with native support. + * @type {!Array.} + */ +var NATIVE_BROWSERS = [ + webdriver.Browser.CHROME, + webdriver.Browser.EDGE, + webdriver.Browser.FIREFOX, + webdriver.Browser.IE, + webdriver.Browser.OPERA, + webdriver.Browser.PHANTOM_JS, + webdriver.Browser.SAFARI +]; + + +var serverJar = process.env['SELENIUM_SERVER_JAR']; +var remoteUrl = process.env['SELENIUM_REMOTE_URL']; +var useLoopback = process.env['SELENIUM_USE_LOOP_BACK'] == '1'; +var startServer = !!serverJar && !remoteUrl; +var nativeRun = !serverJar && !remoteUrl; + + +var browsersToTest = (function() { + var permitRemoteBrowsers = !!remoteUrl || !!serverJar; + var permitUnknownBrowsers = !nativeRun; + var browsers = process.env['SELENIUM_BROWSER'] || webdriver.Browser.FIREFOX; + + browsers = browsers.split(',').map(function(browser) { + var parts = browser.split(/:/); + if (parts[0] === 'ie') { + parts[0] = webdriver.Browser.IE; + } + if (parts[0] === 'edge') { + parts[0] = webdriver.Browser.EDGE; + } + return parts.join(':'); + }); + browsers.forEach(function(browser) { + var parts = browser.split(/:/, 3); + if (parts[0] === 'ie') { + parts[0] = webdriver.Browser.IE; + } + + if (NATIVE_BROWSERS.indexOf(parts[0]) == -1 && !permitRemoteBrowsers) { + throw Error('Browser ' + parts[0] + ' requires a WebDriver server and ' + + 'neither the SELENIUM_REMOTE_URL nor the SELENIUM_SERVER_JAR ' + + 'environment variables have been set.'); + } + + var recognized = false; + for (var prop in webdriver.Browser) { + if (webdriver.Browser.hasOwnProperty(prop) && + webdriver.Browser[prop] === parts[0]) { + recognized = true; + break; + } + } + + if (!recognized && !permitUnknownBrowsers) { + throw Error('Unrecognized browser: ' + browser); + } + }); + + console.log('Running tests against [' + browsers.join(',') + ']'); + if (remoteUrl) { + console.log('Using remote server ' + remoteUrl); + } else if (serverJar) { + console.log('Using standalone Selenium server ' + serverJar); + if (useLoopback) { + console.log('Running tests using loopback address') + } + } + + return browsers; +})(); + + +/** + * Creates a predicate function that ignores tests for specific browsers. + * @param {string} currentBrowser The name of the current browser. + * @param {!Array.} browsersToIgnore The browsers to ignore. + * @return {function(): boolean} The predicate function. + */ +function browsers(currentBrowser, browsersToIgnore) { + return function() { + return browsersToIgnore.indexOf(currentBrowser) != -1; + }; +} + + +/** + * @param {string} browserName The name to use. + * @param {remote.DriverService} server The server to use, if any. + * @constructor + */ +function TestEnvironment(browserName, server) { + var name = browserName; + + this.currentBrowser = function() { + return browserName; + }; + + this.isRemote = function() { + return server || remoteUrl; + }; + + this.browsers = function(var_args) { + var browsersToIgnore = Array.prototype.slice.apply(arguments, [0]); + return browsers(browserName, browsersToIgnore); + }; + + this.builder = function() { + var builder = new webdriver.Builder(); + var realBuild = builder.build; + + builder.build = function() { + var parts = browserName.split(/:/, 3); + builder.forBrowser(parts[0], parts[1], parts[2]); + if (server) { + builder.usingServer(server.address()); + } else if (remoteUrl) { + builder.usingServer(remoteUrl); + } + builder.disableEnvironmentOverrides(); + return realBuild.call(builder); + }; + + return builder; + }; +} + + +var seleniumServer; +var inSuite = false; + + +/** + * Expands a function to cover each of the target browsers. + * @param {function(!TestEnvironment)} fn The top level suite + * function. + * @param {{browsers: !Array.}=} opt_options Suite specific options. + */ +function suite(fn, opt_options) { + assert.ok(!inSuite, 'You may not nest suite calls'); + inSuite = true; + + var suiteOptions = opt_options || {}; + var browsers = suiteOptions.browsers; + if (browsers) { + // Filter out browser specific tests when that browser is not currently + // selected for testing. + browsers = browsers.filter(function(browser) { + return browsersToTest.indexOf(browser) != -1; + }); + } else { + browsers = browsersToTest; + } + + try { + + // Server is only started if required for a specific config. + testing.after(function() { + if (seleniumServer) { + return seleniumServer.stop(); + } + }); + + browsers.forEach(function(browser) { + testing.describe('[' + browser + ']', function() { + + if (isDevMode && nativeRun) { + if (browser === webdriver.Browser.FIREFOX) { + testing.before(function() { + return build.of('//javascript/firefox-driver:webdriver') + .onlyOnce().go(); + }); + } else if (browser === webdriver.Browser.SAFARI) { + testing.before(function() { + return build.of('//javascript/safari-driver:client') + .onlyOnce().go(); + }); + } + } + + var serverToUse = null; + + if (!!serverJar && !remoteUrl) { + if (!(serverToUse = seleniumServer)) { + serverToUse = seleniumServer = new remote.SeleniumServer( + serverJar, {loopback: useLoopback}); + } + + testing.before(function() { + this.timeout(0); + return seleniumServer.start(60 * 1000); + }); + } + fn(new TestEnvironment(browser, serverToUse)); + }); + }); + } finally { + inSuite = false; + } +} + + +// GLOBAL TEST SETUP + +testing.before(function() { + // Do not pass register fileserver.start directly with testing.before, + // as start takes an optional port, which before assumes is an async + // callback. + return fileserver.start(); +}); + +testing.after(function() { + return fileserver.stop(); +}); + +// PUBLIC API + + +exports.suite = suite; +exports.after = testing.after; +exports.afterEach = testing.afterEach; +exports.before = testing.before; +exports.beforeEach = testing.beforeEach; +exports.it = testing.it; +exports.ignore = testing.ignore; + +exports.Pages = fileserver.Pages; +exports.whereIs = fileserver.whereIs; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/resources.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/resources.js new file mode 100644 index 0000000..8e9cceb --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/test/resources.js @@ -0,0 +1,44 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fs = require('fs'), + path = require('path'); + +var resourceRoot = require('../devmode') ? + require('./build').projectRoot() : + path.join(__dirname, 'data'); + + +// PUBLIC API + + +/** + * Locates a test resource. + * @param {string} resourcePath Path of the resource to locate. + * @param {string} filePath The file to locate from the root of the project. + * @return {string} The full path for the file, if it exists. + * @throws {Error} If the file does not exist. + */ +exports.locate = function(filePath) { + var fullPath = path.normalize(path.join(resourceRoot, filePath)); + if (!fs.existsSync(fullPath)) { + throw Error('File does not exist: ' + filePath); + } + return fullPath; +}; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/until.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/until.js new file mode 100644 index 0000000..8b6e83d --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/until.js @@ -0,0 +1,428 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines common conditions for use with + * {@link webdriver.WebDriver#wait WebDriver wait}. + * + * Sample usage: + * + * driver.get('http://www.google.com/ncr'); + * + * var query = driver.wait(until.elementLocated(By.name('q'))); + * query.sendKeys('webdriver\n'); + * + * driver.wait(until.titleIs('webdriver - Google Search')); + * + * To define a custom condition, simply call WebDriver.wait with a function + * that will eventually return a truthy-value (neither null, undefined, false, + * 0, or the empty string): + * + * driver.wait(function() { + * return driver.getTitle().then(function(title) { + * return title === 'webdriver - Google Search'; + * }); + * }, 1000); + */ + +'use strict'; + +const by = require('./by'); +const By = require('./by').By; +const error = require('../error'); + + +/** + * Defines a condition for use with WebDriver's + * {@linkplain ./webdriver.WebDriver#wait wait command}. + * + * @template OUT + */ +class Condition { + /** + * @param {string} message A descriptive error message. Should complete the + * sentence "Waiting [...]" + * @param {function(!./webdriver.WebDriver): OUT} fn The condition function to + * evaluate on each iteration of the wait loop. + */ + constructor(message, fn) { + /** @private {string} */ + this.description_ = 'Waiting ' + message; + + /** @type {function(!./webdriver.WebDriver): OUT} */ + this.fn = fn; + } + + /** @return {string} A description of this condition. */ + description() { + return this.description_; + } +} + +/** + * @typedef {!(./webdriver.WebElement| + * ./promise.Promise)} + */ +var ElementConditionResult; + + +/** + * Defines a condition that will result in a + * {@link ./webdriver.WebElement WebElement}. + * + * @extends {Condition} + */ +class WebElementCondition extends Condition { + /** + * @param {string} message A descriptive error message. Should complete the + * sentence "Waiting [...]" + * @param {function(!./webdriver.WebDriver): ElementConditionResult} fn The + * condition function to evaluate on each iteration of the wait loop. + */ + constructor(message, fn) { + super(message, fn); + } +} + + +// PUBLIC API + + +exports.Condition = Condition; +exports.WebElementCondition = WebElementCondition; + + +/** + * Creates a condition that will wait until the input driver is able to switch + * to the designated frame. The target frame may be specified as + * + * 1. a numeric index into + * [window.frames](https://developer.mozilla.org/en-US/docs/Web/API/Window.frames) + * for the currently selected frame. + * 2. a {@link ./webdriver.WebElement}, which must reference a FRAME or IFRAME + * element on the current page. + * 3. a locator which may be used to first locate a FRAME or IFRAME on the + * current page before attempting to switch to it. + * + * Upon successful resolution of this condition, the driver will be left + * focused on the new frame. + * + * @param {!(number|./webdriver.WebElement|By| + * function(!./webdriver.WebDriver): !./webdriver.WebElement)} frame + * The frame identifier. + * @return {!Condition} A new condition. + */ +exports.ableToSwitchToFrame = function ableToSwitchToFrame(frame) { + // Not at top-level to avoid circular dependency. + const webdriver = require('./webdriver'); + + var condition; + if (typeof frame === 'number' || frame instanceof webdriver.WebElement) { + condition = attemptToSwitchFrames; + } else { + condition = function(driver) { + let locator = /** @type {!(By|Function)} */(frame); + return driver.findElements(locator).then(function(els) { + if (els.length) { + return attemptToSwitchFrames(driver, els[0]); + } + }); + }; + } + + return new Condition('to be able to switch to frame', condition); + + function attemptToSwitchFrames(driver, frame) { + return driver.switchTo().frame(frame).then( + function() { return true; }, + function(e) { + if (!(e instanceof error.NoSuchFrameError)) { + throw e; + } + }); + } +}; + + +/** + * Creates a condition that waits for an alert to be opened. Upon success, the + * returned promise will be fulfilled with the handle for the opened alert. + * + * @return {!Condition} The new condition. + */ +exports.alertIsPresent = function alertIsPresent() { + return new Condition('for alert to be present', function(driver) { + return driver.switchTo().alert().thenCatch(function(e) { + if (!(e instanceof error.NoSuchAlertError)) { + throw e; + } + }); + }); +}; + + +/** + * Creates a condition that will wait for the current page's title to match the + * given value. + * + * @param {string} title The expected page title. + * @return {!Condition} The new condition. + */ +exports.titleIs = function titleIs(title) { + return new Condition( + 'for title to be ' + JSON.stringify(title), + function(driver) { + return driver.getTitle().then(function(t) { + return t === title; + }); + }); +}; + + +/** + * Creates a condition that will wait for the current page's title to contain + * the given substring. + * + * @param {string} substr The substring that should be present in the page + * title. + * @return {!Condition} The new condition. + */ +exports.titleContains = function titleContains(substr) { + return new Condition( + 'for title to contain ' + JSON.stringify(substr), + function(driver) { + return driver.getTitle().then(function(title) { + return title.indexOf(substr) !== -1; + }); + }); +}; + + +/** + * Creates a condition that will wait for the current page's title to match the + * given regular expression. + * + * @param {!RegExp} regex The regular expression to test against. + * @return {!Condition} The new condition. + */ +exports.titleMatches = function titleMatches(regex) { + return new Condition('for title to match ' + regex, function(driver) { + return driver.getTitle().then(function(title) { + return regex.test(title); + }); + }); +}; + + +/** + * Creates a condition that will loop until an element is + * {@link ./webdriver.WebDriver#findElement found} with the given locator. + * + * @param {!(By|Function)} locator The locator to use. + * @return {!WebElementCondition} The new condition. + */ +exports.elementLocated = function elementLocated(locator) { + locator = by.checkedLocator(locator); + let locatorStr = + typeof locator === 'function' ? 'by function()' : locator + ''; + return new WebElementCondition('for element to be located ' + locatorStr, + function(driver) { + return driver.findElements(locator).then(function(elements) { + return elements[0]; + }); + }); +}; + + +/** + * Creates a condition that will loop until at least one element is + * {@link ./webdriver.WebDriver#findElement found} with the given locator. + * + * @param {!(By|Function)} locator The locator to use. + * @return {!Condition>} The new + * condition. + */ +exports.elementsLocated = function elementsLocated(locator) { + locator = by.checkedLocator(locator); + let locatorStr = + typeof locator === 'function' ? 'by function()' : locator + ''; + return new Condition( + 'for at least one element to be located ' + locatorStr, + function(driver) { + return driver.findElements(locator).then(function(elements) { + return elements.length > 0 ? elements : null; + }); + }); +}; + + +/** + * Creates a condition that will wait for the given element to become stale. An + * element is considered stale once it is removed from the DOM, or a new page + * has loaded. + * + * @param {!./webdriver.WebElement} element The element that should become stale. + * @return {!Condition} The new condition. + */ +exports.stalenessOf = function stalenessOf(element) { + return new Condition('element to become stale', function() { + return element.getTagName().then( + function() { return false; }, + function(e) { + if (e instanceof error.StaleElementReferenceError) { + return true; + } + throw e; + }); + }); +}; + + +/** + * Creates a condition that will wait for the given element to become visible. + * + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see ./webdriver.WebDriver#isDisplayed + */ +exports.elementIsVisible = function elementIsVisible(element) { + return new WebElementCondition('until element is visible', function() { + return element.isDisplayed().then(v => v ? element : null); + }); +}; + + +/** + * Creates a condition that will wait for the given element to be in the DOM, + * yet not visible to the user. + * + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see ./webdriver.WebDriver#isDisplayed + */ +exports.elementIsNotVisible = function elementIsNotVisible(element) { + return new WebElementCondition('until element is not visible', function() { + return element.isDisplayed().then(v => v ? null : element); + }); +}; + + +/** + * Creates a condition that will wait for the given element to be enabled. + * + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#isEnabled + */ +exports.elementIsEnabled = function elementIsEnabled(element) { + return new WebElementCondition('until element is enabled', function() { + return element.isEnabled().then(v => v ? element : null); + }); +}; + + +/** + * Creates a condition that will wait for the given element to be disabled. + * + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#isEnabled + */ +exports.elementIsDisabled = function elementIsDisabled(element) { + return new WebElementCondition('until element is disabled', function() { + return element.isEnabled().then(v => v ? null : element); + }); +}; + + +/** + * Creates a condition that will wait for the given element to be selected. + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#isSelected + */ +exports.elementIsSelected = function elementIsSelected(element) { + return new WebElementCondition('until element is selected', function() { + return element.isSelected().then(v => v ? element : null); + }); +}; + + +/** + * Creates a condition that will wait for the given element to be deselected. + * + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#isSelected + */ +exports.elementIsNotSelected = function elementIsNotSelected(element) { + return new WebElementCondition('until element is not selected', function() { + return element.isSelected().then(v => v ? null : element); + }); +}; + + +/** + * Creates a condition that will wait for the given element's + * {@link webdriver.WebDriver#getText visible text} to match the given + * {@code text} exactly. + * + * @param {!./webdriver.WebElement} element The element to test. + * @param {string} text The expected text. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#getText + */ +exports.elementTextIs = function elementTextIs(element, text) { + return new WebElementCondition('until element text is', function() { + return element.getText().then(t => t === text ? element : null); + }); +}; + + +/** + * Creates a condition that will wait for the given element's + * {@link webdriver.WebDriver#getText visible text} to contain the given + * substring. + * + * @param {!./webdriver.WebElement} element The element to test. + * @param {string} substr The substring to search for. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#getText + */ +exports.elementTextContains = function elementTextContains(element, substr) { + return new WebElementCondition('until element text contains', function() { + return element.getText() + .then(t => t.indexOf(substr) != -1 ? element : null); + }); +}; + + +/** + * Creates a condition that will wait for the given element's + * {@link webdriver.WebDriver#getText visible text} to match a regular + * expression. + * + * @param {!./webdriver.WebElement} element The element to test. + * @param {!RegExp} regex The regular expression to test against. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#getText + */ +exports.elementTextMatches = function elementTextMatches(element, regex) { + return new WebElementCondition('until element text matches', function() { + return element.getText().then(t => regex.test(t) ? element : null); + }); +}; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/lib/webdriver.js b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/webdriver.js new file mode 100644 index 0000000..0adcbb0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/lib/webdriver.js @@ -0,0 +1,2351 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview The heart of the WebDriver JavaScript API. + */ + +'use strict'; + +const error = require('../error'); +const actions = require('./actions'); +const by = require('./by'); +const Capabilities = require('./capabilities').Capabilities; +const command = require('./command'); +const input = require('./input'); +const logging = require('./logging'); +const Session = require('./session').Session; +const Symbols = require('./symbols'); +const promise = require('./promise'); +const until = require('./until'); + + + +////////////////////////////////////////////////////////////////////////////// +// +// WebDriver +// +////////////////////////////////////////////////////////////////////////////// + + +/** + * Sends a command to the server that is expected to return the details for a + * {@link Session}. This may either be an existing session, or a newly created + * one. + * + * @param {!command.Executor} executor Command executor to use when + * querying for session details. + * @param {!command.Command} command The command to send to fetch the session + * details. + * @param {string} description A descriptive debug label for this action. + * @param {promise.ControlFlow=} opt_flow The control flow all driver + * commands should execute under. Defaults to the + * {@link promise.controlFlow() currently active} control flow. + * @return {!WebDriver} A new WebDriver client for the session. + */ +function acquireSession(executor, command, description, opt_flow) { + let flow = opt_flow || promise.controlFlow(); + let session = flow.execute(function() { + return executeCommand(executor, command).then(function(response) { + error.checkLegacyResponse(response); + return new Session(response['sessionId'], response['value']); + }); + }, description); + return new WebDriver(session, executor, flow); +} + + +/** + * Translates a command to its wire-protocol representation before passing it + * to the given `executor` for execution. + * @param {!command.Executor} executor The executor to use. + * @param {!command.Command} command The command to execute. + * @return {!promise.Promise} A promise that will resolve with the + * command response. + */ +function executeCommand(executor, command) { + return toWireValue(command.getParameters()). + then(function(parameters) { + command.setParameters(parameters); + return executor.execute(command); + }); +} + + +/** + * Converts an object to its JSON representation in the WebDriver wire protocol. + * When converting values of type object, the following steps will be taken: + *
      + *
    1. if the object is a WebElement, the return value will be the element's + * server ID + *
    2. if the object defines a {@link Symbols.serialize} method, this algorithm + * will be recursively applied to the object's serialized representation + *
    3. if the object provides a "toJSON" function, this algorithm will + * recursively be applied to the result of that function + *
    4. otherwise, the value of each key will be recursively converted according + * to the rules above. + *
    + * + * @param {*} obj The object to convert. + * @return {!promise.Promise} A promise that will resolve to the + * input value's JSON representation. + */ +function toWireValue(obj) { + if (promise.isPromise(obj)) { + return obj.then(toWireValue); + } + return promise.fulfilled(convertValue(obj)); +} + + +function convertValue(value) { + if (value === void 0 || value === null) { + return value; + } + + if (typeof value === 'boolean' + || typeof value === 'number' + || typeof value === 'string') { + return value; + } + + if (Array.isArray(value)) { + return convertKeys(value); + } + + if (typeof value === 'function') { + return '' + value; + } + + if (typeof value[Symbols.serialize] === 'function') { + return toWireValue(value[Symbols.serialize]()); + } else if (typeof value.toJSON === 'function') { + return toWireValue(value.toJSON()); + } + return convertKeys(value); +} + + +function convertKeys(obj) { + const isArray = Array.isArray(obj); + const numKeys = isArray ? obj.length : Object.keys(obj).length; + const ret = isArray ? new Array(numKeys) : {}; + if (!numKeys) { + return promise.fulfilled(ret); + } + + let numResolved = 0; + + function forEachKey(obj, fn) { + if (Array.isArray(obj)) { + for (let i = 0, n = obj.length; i < n; i++) { + fn(obj[i], i); + } + } else { + for (let key in obj) { + fn(obj[key], key); + } + } + } + + return new promise.Promise(function(done, reject) { + forEachKey(obj, function(value, key) { + if (promise.isPromise(value)) { + value.then(toWireValue).then(setValue, reject); + } else { + value = convertValue(value); + if (promise.isPromise(value)) { + value.then(toWireValue).then(setValue, reject); + } else { + setValue(value); + } + } + + function setValue(value) { + ret[key] = value; + maybeFulfill(); + } + }); + + function maybeFulfill() { + if (++numResolved === numKeys) { + done(ret); + } + } + }); +} + + +/** + * Converts a value from its JSON representation according to the WebDriver wire + * protocol. Any JSON object that defines a WebElement ID will be decoded to a + * {@link WebElement} object. All other values will be passed through as is. + * + * @param {!WebDriver} driver The driver to use as the parent of any unwrapped + * {@link WebElement} values. + * @param {*} value The value to convert. + * @return {*} The converted value. + */ +function fromWireValue(driver, value) { + if (Array.isArray(value)) { + value = value.map(v => fromWireValue(driver, v)); + } else if (WebElement.isId(value)) { + let id = WebElement.extractId(value); + value = new WebElement(driver, id); + } else if (value && typeof value === 'object') { + let result = {}; + for (let key in value) { + if (value.hasOwnProperty(key)) { + result[key] = fromWireValue(driver, value[key]); + } + } + value = result; + } + return value; +} + + +/** + * Creates a new WebDriver client, which provides control over a browser. + * + * Every command.Command returns a {@link promise.Promise} that + * represents the result of that command. Callbacks may be registered on this + * object to manipulate the command result or catch an expected error. Any + * commands scheduled with a callback are considered sub-commands and will + * execute before the next command in the current frame. For example: + * + * var message = []; + * driver.call(message.push, message, 'a').then(function() { + * driver.call(message.push, message, 'b'); + * }); + * driver.call(message.push, message, 'c'); + * driver.call(function() { + * alert('message is abc? ' + (message.join('') == 'abc')); + * }); + * + */ +class WebDriver { + /** + * @param {!(Session|promise.Promise)} session Either a + * known session or a promise that will be resolved to a session. + * @param {!command.Executor} executor The executor to use when sending + * commands to the browser. + * @param {promise.ControlFlow=} opt_flow The flow to + * schedule commands through. Defaults to the active flow object. + */ + constructor(session, executor, opt_flow) { + /** @private {!promise.Promise} */ + this.session_ = promise.fulfilled(session);; + + /** @private {!command.Executor} */ + this.executor_ = executor; + + /** @private {!promise.ControlFlow} */ + this.flow_ = opt_flow || promise.controlFlow(); + + /** @private {input.FileDetector} */ + this.fileDetector_ = null; + } + + /** + * Creates a new WebDriver client for an existing session. + * @param {!command.Executor} executor Command executor to use when querying + * for session details. + * @param {string} sessionId ID of the session to attach to. + * @param {promise.ControlFlow=} opt_flow The control flow all + * driver commands should execute under. Defaults to the + * {@link promise.controlFlow() currently active} control flow. + * @return {!WebDriver} A new client for the specified session. + */ + static attachToSession(executor, sessionId, opt_flow) { + return acquireSession(executor, + new command.Command(command.Name.DESCRIBE_SESSION). + setParameter('sessionId', sessionId), + 'WebDriver.attachToSession()', + opt_flow); + } + + /** + * Creates a new WebDriver session. + * @param {!command.Executor} executor The executor to create the new session + * with. + * @param {!./capabilities.Capabilities} desiredCapabilities The desired + * capabilities for the new session. + * @param {promise.ControlFlow=} opt_flow The control flow all driver + * commands should execute under, including the initial session creation. + * Defaults to the {@link promise.controlFlow() currently active} + * control flow. + * @return {!WebDriver} The driver for the newly created session. + */ + static createSession(executor, desiredCapabilities, opt_flow) { + return acquireSession(executor, + new command.Command(command.Name.NEW_SESSION). + setParameter('desiredCapabilities', desiredCapabilities), + 'WebDriver.createSession()', + opt_flow); + } + + /** + * @return {!promise.ControlFlow} The control flow used by this + * instance. + */ + controlFlow() { + return this.flow_; + } + + /** + * Schedules a {@link command.Command} to be executed by this driver's + * {@link command.Executor}. + * + * @param {!command.Command} command The command to schedule. + * @param {string} description A description of the command for debugging. + * @return {!promise.Promise} A promise that will be resolved + * with the command result. + * @template T + */ + schedule(command, description) { + var self = this; + + checkHasNotQuit(); + command.setParameter('sessionId', this.session_); + + // If any of the command parameters are rejected promises, those + // rejections may be reported as unhandled before the control flow + // attempts to execute the command. To ensure parameters errors + // propagate through the command itself, we resolve all of the + // command parameters now, but suppress any errors until the ControlFlow + // actually executes the command. This addresses scenarios like catching + // an element not found error in: + // + // driver.findElement(By.id('foo')).click().thenCatch(function(e) { + // if (e instanceof NoSuchElementError) { + // // Do something. + // } + // }); + var prepCommand = toWireValue(command.getParameters()); + prepCommand.thenCatch(function() {}); + + var flow = this.flow_; + var executor = this.executor_; + return flow.execute(function() { + // A call to WebDriver.quit() may have been scheduled in the same event + // loop as this |command|, which would prevent us from detecting that the + // driver has quit above. Therefore, we need to make another quick check. + // We still check above so we can fail as early as possible. + checkHasNotQuit(); + + // Retrieve resolved command parameters; any previously suppressed errors + // will now propagate up through the control flow as part of the command + // execution. + return prepCommand.then(function(parameters) { + command.setParameters(parameters); + return executor.execute(command); + }); + }, description).then(function(response) { + try { + error.checkLegacyResponse(response); + } catch (ex) { + if (ex instanceof error.UnexpectedAlertOpenError) { + let text = ''; + if (response['value'] + && response['value']['alert'] + && typeof response['value']['alert']['text'] === 'string') { + text = response['value']['alert']['text']; + } + throw new error.UnexpectedAlertOpenError(ex.message, text); + } + throw ex; + } + return fromWireValue(self, response['value']); + }); + + function checkHasNotQuit() { + if (!self.session_) { + throw new error.UnsupportedOperationError( + 'This driver instance does not have a valid session ID ' + + '(did you call WebDriver.quit()?) and may no longer be ' + + 'used.'); + } + } + } + + /** + * Sets the {@linkplain input.FileDetector file detector} that should be + * used with this instance. + * @param {input.FileDetector} detector The detector to use or {@code null}. + */ + setFileDetector(detector) { + this.fileDetector_ = detector; + } + + /** + * @return {!promise.Promise} A promise for this client's + * session. + */ + getSession() { + return this.session_; + } + + /** + * @return {!promise.Promise} A promise + * that will resolve with the this instance's capabilities. + */ + getCapabilities() { + return this.session_.then(session => session.getCapabilities()); + } + + /** + * Schedules a command to quit the current session. After calling quit, this + * instance will be invalidated and may no longer be used to issue commands + * against the browser. + * @return {!promise.Promise} A promise that will be resolved + * when the command has completed. + */ + quit() { + var result = this.schedule( + new command.Command(command.Name.QUIT), + 'WebDriver.quit()'); + // Delete our session ID when the quit command finishes; this will allow us to + // throw an error when attemnpting to use a driver post-quit. + return result.thenFinally(() => delete this.session_); + } + + /** + * Creates a new action sequence using this driver. The sequence will not be + * scheduled for execution until {@link actions.ActionSequence#perform} is + * called. Example: + * + * driver.actions(). + * mouseDown(element1). + * mouseMove(element2). + * mouseUp(). + * perform(); + * + * @return {!actions.ActionSequence} A new action sequence for this instance. + */ + actions() { + return new actions.ActionSequence(this); + } + + /** + * Creates a new touch sequence using this driver. The sequence will not be + * scheduled for execution until {@link actions.TouchSequence#perform} is + * called. Example: + * + * driver.touchActions(). + * tap(element1). + * doubleTap(element2). + * perform(); + * + * @return {!actions.TouchSequence} A new touch sequence for this instance. + */ + touchActions() { + return new actions.TouchSequence(this); + } + + /** + * Schedules a command to execute JavaScript in the context of the currently + * selected frame or window. The script fragment will be executed as the body + * of an anonymous function. If the script is provided as a function object, + * that function will be converted to a string for injection into the target + * window. + * + * Any arguments provided in addition to the script will be included as script + * arguments and may be referenced using the {@code arguments} object. + * Arguments may be a boolean, number, string, or {@linkplain WebElement}. + * Arrays and objects may also be used as script arguments as long as each item + * adheres to the types previously mentioned. + * + * The script may refer to any variables accessible from the current window. + * Furthermore, the script will execute in the window's context, thus + * {@code document} may be used to refer to the current document. Any local + * variables will not be available once the script has finished executing, + * though global variables will persist. + * + * If the script has a return value (i.e. if the script contains a return + * statement), then the following steps will be taken for resolving this + * functions return value: + * + * - For a HTML element, the value will resolve to a {@linkplain WebElement} + * - Null and undefined return values will resolve to null
  • + * - Booleans, numbers, and strings will resolve as is + * - Functions will resolve to their string representation + * - For arrays and objects, each member item will be converted according to + * the rules above + * + * @param {!(string|Function)} script The script to execute. + * @param {...*} var_args The arguments to pass to the script. + * @return {!promise.Promise} A promise that will resolve to the + * scripts return value. + * @template T + */ + executeScript(script, var_args) { + if (typeof script === 'function') { + script = 'return (' + script + ').apply(null, arguments);'; + } + let args = + arguments.length > 1 ? Array.prototype.slice.call(arguments, 1) : []; + return this.schedule( + new command.Command(command.Name.EXECUTE_SCRIPT). + setParameter('script', script). + setParameter('args', args), + 'WebDriver.executeScript()'); + } + + /** + * Schedules a command to execute asynchronous JavaScript in the context of the + * currently selected frame or window. The script fragment will be executed as + * the body of an anonymous function. If the script is provided as a function + * object, that function will be converted to a string for injection into the + * target window. + * + * Any arguments provided in addition to the script will be included as script + * arguments and may be referenced using the {@code arguments} object. + * Arguments may be a boolean, number, string, or {@code WebElement}. + * Arrays and objects may also be used as script arguments as long as each item + * adheres to the types previously mentioned. + * + * Unlike executing synchronous JavaScript with {@link #executeScript}, + * scripts executed with this function must explicitly signal they are finished + * by invoking the provided callback. This callback will always be injected + * into the executed function as the last argument, and thus may be referenced + * with {@code arguments[arguments.length - 1]}. The following steps will be + * taken for resolving this functions return value against the first argument + * to the script's callback function: + * + * - For a HTML element, the value will resolve to a + * {@link WebElement} + * - Null and undefined return values will resolve to null + * - Booleans, numbers, and strings will resolve as is + * - Functions will resolve to their string representation + * - For arrays and objects, each member item will be converted according to + * the rules above + * + * __Example #1:__ Performing a sleep that is synchronized with the currently + * selected window: + * + * var start = new Date().getTime(); + * driver.executeAsyncScript( + * 'window.setTimeout(arguments[arguments.length - 1], 500);'). + * then(function() { + * console.log( + * 'Elapsed time: ' + (new Date().getTime() - start) + ' ms'); + * }); + * + * __Example #2:__ Synchronizing a test with an AJAX application: + * + * var button = driver.findElement(By.id('compose-button')); + * button.click(); + * driver.executeAsyncScript( + * 'var callback = arguments[arguments.length - 1];' + + * 'mailClient.getComposeWindowWidget().onload(callback);'); + * driver.switchTo().frame('composeWidget'); + * driver.findElement(By.id('to')).sendKeys('dog@example.com'); + * + * __Example #3:__ Injecting a XMLHttpRequest and waiting for the result. In + * this example, the inject script is specified with a function literal. When + * using this format, the function is converted to a string for injection, so it + * should not reference any symbols not defined in the scope of the page under + * test. + * + * driver.executeAsyncScript(function() { + * var callback = arguments[arguments.length - 1]; + * var xhr = new XMLHttpRequest(); + * xhr.open("GET", "/resource/data.json", true); + * xhr.onreadystatechange = function() { + * if (xhr.readyState == 4) { + * callback(xhr.responseText); + * } + * }; + * xhr.send(''); + * }).then(function(str) { + * console.log(JSON.parse(str)['food']); + * }); + * + * @param {!(string|Function)} script The script to execute. + * @param {...*} var_args The arguments to pass to the script. + * @return {!promise.Promise} A promise that will resolve to the + * scripts return value. + * @template T + */ + executeAsyncScript(script, var_args) { + if (typeof script === 'function') { + script = 'return (' + script + ').apply(null, arguments);'; + } + let args = Array.prototype.slice.call(arguments, 1); + return this.schedule( + new command.Command(command.Name.EXECUTE_ASYNC_SCRIPT). + setParameter('script', script). + setParameter('args', args), + 'WebDriver.executeScript()'); + } + + /** + * Schedules a command to execute a custom function. + * @param {function(...): (T|promise.Promise)} fn The function to + * execute. + * @param {Object=} opt_scope The object in whose scope to execute the function. + * @param {...*} var_args Any arguments to pass to the function. + * @return {!promise.Promise} A promise that will be resolved' + * with the function's result. + * @template T + */ + call(fn, opt_scope, var_args) { + let args = Array.prototype.slice.call(arguments, 2); + let flow = this.flow_; + return flow.execute(function() { + return promise.fullyResolved(args).then(function(args) { + if (promise.isGenerator(fn)) { + args.unshift(fn, opt_scope); + return promise.consume.apply(null, args); + } + return fn.apply(opt_scope, args); + }); + }, 'WebDriver.call(' + (fn.name || 'function') + ')'); + } + + /** + * Schedules a command to wait for a condition to hold. The condition may be + * specified by a {@link until.Condition}, as a custom function, or as any + * promise-like thenable. + * + * For a {@link until.Condition} or function, the wait will repeatedly + * evaluate the condition until it returns a truthy value. If any errors occur + * while evaluating the condition, they will be allowed to propagate. In the + * event a condition returns a {@link promise.Promise promise}, the polling + * loop will wait for it to be resolved and use the resolved value for whether + * the condition has been satisified. Note the resolution time for a promise + * is factored into whether a wait has timed out. + * + * Note, if the provided condition is a {@link until.WebElementCondition}, then + * the wait will return a {@link WebElementPromise} that will resolve to the + * element that satisified the condition. + * + * *Example:* waiting up to 10 seconds for an element to be present on the + * page. + * + * var button = driver.wait(until.elementLocated(By.id('foo')), 10000); + * button.click(); + * + * This function may also be used to block the command flow on the resolution + * of any thenable promise object. When given a promise, the command will + * simply wait for its resolution before completing. A timeout may be provided + * to fail the command if the promise does not resolve before the timeout + * expires. + * + * *Example:* Suppose you have a function, `startTestServer`, that returns a + * promise for when a server is ready for requests. You can block a WebDriver + * client on this promise with: + * + * var started = startTestServer(); + * driver.wait(started, 5 * 1000, 'Server should start within 5 seconds'); + * driver.get(getServerUrl()); + * + * @param {!(promise.Promise| + * until.Condition| + * function(!WebDriver): T)} condition The condition to + * wait on, defined as a promise, condition object, or a function to + * evaluate as a condition. + * @param {number=} opt_timeout How long to wait for the condition to be true. + * @param {string=} opt_message An optional message to use if the wait times + * out. + * @return {!(promise.Promise|WebElementPromise)} A promise that will be + * resolved with the first truthy value returned by the condition + * function, or rejected if the condition times out. If the input + * input condition is an instance of a {@link until.WebElementCondition}, + * the returned value will be a {@link WebElementPromise}. + * @template T + */ + wait(condition, opt_timeout, opt_message) { + if (promise.isPromise(condition)) { + return this.flow_.wait( + /** @type {!promise.Promise} */(condition), + opt_timeout, opt_message); + } + + var message = opt_message; + var fn = /** @type {!Function} */(condition); + if (condition instanceof until.Condition) { + message = message || condition.description(); + fn = condition.fn; + } + + var driver = this; + var result = this.flow_.wait(function() { + if (promise.isGenerator(fn)) { + return promise.consume(fn, null, [driver]); + } + return fn(driver); + }, opt_timeout, message); + + if (condition instanceof until.WebElementCondition) { + result = new WebElementPromise(this, result.then(function(value) { + if (!(value instanceof WebElement)) { + throw TypeError( + 'WebElementCondition did not resolve to a WebElement: ' + + Object.prototype.toString.call(value)); + } + return value; + })); + } + return result; + } + + /** + * Schedules a command to make the driver sleep for the given amount of time. + * @param {number} ms The amount of time, in milliseconds, to sleep. + * @return {!promise.Promise} A promise that will be resolved + * when the sleep has finished. + */ + sleep(ms) { + return this.flow_.timeout(ms, 'WebDriver.sleep(' + ms + ')'); + } + + /** + * Schedules a command to retrieve they current window handle. + * @return {!promise.Promise} A promise that will be + * resolved with the current window handle. + */ + getWindowHandle() { + return this.schedule( + new command.Command(command.Name.GET_CURRENT_WINDOW_HANDLE), + 'WebDriver.getWindowHandle()'); + } + + /** + * Schedules a command to retrieve the current list of available window handles. + * @return {!promise.Promise.>} A promise that will + * be resolved with an array of window handles. + */ + getAllWindowHandles() { + return this.schedule( + new command.Command(command.Name.GET_WINDOW_HANDLES), + 'WebDriver.getAllWindowHandles()'); + } + + /** + * Schedules a command to retrieve the current page's source. The page source + * returned is a representation of the underlying DOM: do not expect it to be + * formatted or escaped in the same way as the response sent from the web + * server. + * @return {!promise.Promise} A promise that will be + * resolved with the current page source. + */ + getPageSource() { + return this.schedule( + new command.Command(command.Name.GET_PAGE_SOURCE), + 'WebDriver.getPageSource()'); + } + + /** + * Schedules a command to close the current window. + * @return {!promise.Promise} A promise that will be resolved + * when this command has completed. + */ + close() { + return this.schedule(new command.Command(command.Name.CLOSE), + 'WebDriver.close()'); + } + + /** + * Schedules a command to navigate to the given URL. + * @param {string} url The fully qualified URL to open. + * @return {!promise.Promise} A promise that will be resolved + * when the document has finished loading. + */ + get(url) { + return this.navigate().to(url); + } + + /** + * Schedules a command to retrieve the URL of the current page. + * @return {!promise.Promise} A promise that will be + * resolved with the current URL. + */ + getCurrentUrl() { + return this.schedule( + new command.Command(command.Name.GET_CURRENT_URL), + 'WebDriver.getCurrentUrl()'); + } + + /** + * Schedules a command to retrieve the current page's title. + * @return {!promise.Promise} A promise that will be + * resolved with the current page's title. + */ + getTitle() { + return this.schedule(new command.Command(command.Name.GET_TITLE), + 'WebDriver.getTitle()'); + } + + /** + * Schedule a command to find an element on the page. If the element cannot be + * found, a {@link bot.ErrorCode.NO_SUCH_ELEMENT} result will be returned + * by the driver. Unlike other commands, this error cannot be suppressed. In + * other words, scheduling a command to find an element doubles as an assert + * that the element is present on the page. To test whether an element is + * present on the page, use {@link #isElementPresent} instead. + * + * The search criteria for an element may be defined using one of the + * factories in the {@link webdriver.By} namespace, or as a short-hand + * {@link webdriver.By.Hash} object. For example, the following two statements + * are equivalent: + * + * var e1 = driver.findElement(By.id('foo')); + * var e2 = driver.findElement({id:'foo'}); + * + * You may also provide a custom locator function, which takes as input this + * instance and returns a {@link WebElement}, or a promise that will resolve + * to a WebElement. If the returned promise resolves to an array of + * WebElements, WebDriver will use the first element. For example, to find the + * first visible link on a page, you could write: + * + * var link = driver.findElement(firstVisibleLink); + * + * function firstVisibleLink(driver) { + * var links = driver.findElements(By.tagName('a')); + * return promise.filter(links, function(link) { + * return link.isDisplayed(); + * }); + * } + * + * @param {!(by.By|Function)} locator The locator to use. + * @return {!WebElementPromise} A WebElement that can be used to issue + * commands against the located element. If the element is not found, the + * element will be invalidated and all scheduled commands aborted. + */ + findElement(locator) { + let id; + locator = by.checkedLocator(locator); + if (typeof locator === 'function') { + id = this.findElementInternal_(locator, this); + } else { + let cmd = new command.Command(command.Name.FIND_ELEMENT). + setParameter('using', locator.using). + setParameter('value', locator.value); + id = this.schedule(cmd, 'WebDriver.findElement(' + locator + ')'); + } + return new WebElementPromise(this, id); + } + + /** + * @param {!Function} locatorFn The locator function to use. + * @param {!(WebDriver|WebElement)} context The search + * context. + * @return {!promise.Promise.} A + * promise that will resolve to a list of WebElements. + * @private + */ + findElementInternal_(locatorFn, context) { + return this.call(() => locatorFn(context)).then(function(result) { + if (Array.isArray(result)) { + result = result[0]; + } + if (!(result instanceof WebElement)) { + throw new TypeError('Custom locator did not return a WebElement'); + } + return result; + }); + } + + /** + * Schedules a command to test if an element is present on the page. + * + * If given a DOM element, this function will check if it belongs to the + * document the driver is currently focused on. Otherwise, the function will + * test if at least one element can be found with the given search criteria. + * + * @param {!(by.By|Function)} locator The locator to use. + * @return {!promise.Promise} A promise that will resolve + * with whether the element is present on the page. + */ + isElementPresent(locator) { + return this.findElements.apply(this, arguments).then(function(result) { + return !!result.length; + }); + } + + /** + * Schedule a command to search for multiple elements on the page. + * + * @param {!(by.By|Function)} locator The locator to use. + * @return {!promise.Promise.>} A + * promise that will resolve to an array of WebElements. + */ + findElements(locator) { + locator = by.checkedLocator(locator); + if (typeof locator === 'function') { + return this.findElementsInternal_(locator, this); + } else { + let cmd = new command.Command(command.Name.FIND_ELEMENTS). + setParameter('using', locator.using). + setParameter('value', locator.value); + let res = this.schedule(cmd, 'WebDriver.findElements(' + locator + ')'); + return res.thenCatch(function(e) { + if (e instanceof error.NoSuchElementError) { + return []; + } + throw e; + }); + } + } + + /** + * @param {!Function} locatorFn The locator function to use. + * @param {!(WebDriver|WebElement)} context The search context. + * @return {!promise.Promise>} A promise that + * will resolve to an array of WebElements. + * @private + */ + findElementsInternal_(locatorFn, context) { + return this.call(() => locatorFn(context)).then(function(result) { + if (result instanceof WebElement) { + return [result]; + } + + if (!Array.isArray(result)) { + return []; + } + + return result.filter(function(item) { + return item instanceof WebElement; + }); + }); + } + + /** + * Schedule a command to take a screenshot. The driver makes a best effort to + * return a screenshot of the following, in order of preference: + * + * 1. Entire page + * 2. Current window + * 3. Visible portion of the current frame + * 4. The entire display containing the browser + * + * @return {!promise.Promise} A promise that will be + * resolved to the screenshot as a base-64 encoded PNG. + */ + takeScreenshot() { + return this.schedule(new command.Command(command.Name.SCREENSHOT), + 'WebDriver.takeScreenshot()'); + } + + /** + * @return {!Options} The options interface for this instance. + */ + manage() { + return new Options(this); + } + + /** + * @return {!Navigation} The navigation interface for this instance. + */ + navigate() { + return new Navigation(this); + } + + /** + * @return {!TargetLocator} The target locator interface for this + * instance. + */ + switchTo() { + return new TargetLocator(this); + } +} + + +/** + * Interface for navigating back and forth in the browser history. + * + * This class should never be instantiated directly. Insead, obtain an instance + * with + * + * webdriver.navigate() + * + * @see WebDriver#navigate() + */ +class Navigation { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Schedules a command to navigate to a new URL. + * @param {string} url The URL to navigate to. + * @return {!promise.Promise} A promise that will be resolved + * when the URL has been loaded. + */ + to(url) { + return this.driver_.schedule( + new command.Command(command.Name.GET). + setParameter('url', url), + 'WebDriver.navigate().to(' + url + ')'); + } + + /** + * Schedules a command to move backwards in the browser history. + * @return {!promise.Promise} A promise that will be resolved + * when the navigation event has completed. + */ + back() { + return this.driver_.schedule( + new command.Command(command.Name.GO_BACK), + 'WebDriver.navigate().back()'); + } + + /** + * Schedules a command to move forwards in the browser history. + * @return {!promise.Promise} A promise that will be resolved + * when the navigation event has completed. + */ + forward() { + return this.driver_.schedule( + new command.Command(command.Name.GO_FORWARD), + 'WebDriver.navigate().forward()'); + } + + /** + * Schedules a command to refresh the current page. + * @return {!promise.Promise} A promise that will be resolved + * when the navigation event has completed. + */ + refresh() { + return this.driver_.schedule( + new command.Command(command.Name.REFRESH), + 'WebDriver.navigate().refresh()'); + } +} + + +/** + * Provides methods for managing browser and driver state. + * + * This class should never be instantiated directly. Insead, obtain an instance + * with + * + * webdriver.manage() + * + * @see WebDriver#manage() + */ +class Options { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Schedules a command to add a cookie. + * @param {string} name The cookie name. + * @param {string} value The cookie value. + * @param {string=} opt_path The cookie path. + * @param {string=} opt_domain The cookie domain. + * @param {boolean=} opt_isSecure Whether the cookie is secure. + * @param {(number|!Date)=} opt_expiry When the cookie expires. If specified + * as a number, should be in milliseconds since midnight, + * January 1, 1970 UTC. + * @return {!promise.Promise} A promise that will be resolved + * when the cookie has been added to the page. + */ + addCookie(name, value, opt_path, opt_domain, opt_isSecure, opt_expiry) { + // We do not allow '=' or ';' in the name. + if (/[;=]/.test(name)) { + throw new error.InvalidArgumentError( + 'Invalid cookie name "' + name + '"'); + } + + // We do not allow ';' in value. + if (/;/.test(value)) { + throw new error.InvalidArgumentError( + 'Invalid cookie value "' + value + '"'); + } + + var cookieString = name + '=' + value + + (opt_domain ? ';domain=' + opt_domain : '') + + (opt_path ? ';path=' + opt_path : '') + + (opt_isSecure ? ';secure' : ''); + + var expiry; + if (opt_expiry !== void(0)) { + var expiryDate; + if (typeof opt_expiry === 'number') { + expiryDate = new Date(opt_expiry); + } else { + expiryDate = /** @type {!Date} */ (opt_expiry); + opt_expiry = expiryDate.getTime(); + } + cookieString += ';expires=' + expiryDate.toUTCString(); + // Convert from milliseconds to seconds. + expiry = Math.floor(/** @type {number} */ (opt_expiry) / 1000); + } + + return this.driver_.schedule( + new command.Command(command.Name.ADD_COOKIE). + setParameter('cookie', { + 'name': name, + 'value': value, + 'path': opt_path, + 'domain': opt_domain, + 'secure': !!opt_isSecure, + 'expiry': expiry + }), + 'WebDriver.manage().addCookie(' + cookieString + ')'); + } + + /** + * Schedules a command to delete all cookies visible to the current page. + * @return {!promise.Promise} A promise that will be resolved + * when all cookies have been deleted. + */ + deleteAllCookies() { + return this.driver_.schedule( + new command.Command(command.Name.DELETE_ALL_COOKIES), + 'WebDriver.manage().deleteAllCookies()'); + } + + /** + * Schedules a command to delete the cookie with the given name. This command is + * a no-op if there is no cookie with the given name visible to the current + * page. + * @param {string} name The name of the cookie to delete. + * @return {!promise.Promise} A promise that will be resolved + * when the cookie has been deleted. + */ + deleteCookie(name) { + return this.driver_.schedule( + new command.Command(command.Name.DELETE_COOKIE). + setParameter('name', name), + 'WebDriver.manage().deleteCookie(' + name + ')'); + } + + /** + * Schedules a command to retrieve all cookies visible to the current page. + * Each cookie will be returned as a JSON object as described by the WebDriver + * wire protocol. + * @return {!promise.Promise>} A + * promise that will be resolved with the cookies visible to the current page. + */ + getCookies() { + return this.driver_.schedule( + new command.Command(command.Name.GET_ALL_COOKIES), + 'WebDriver.manage().getCookies()'); + } + + /** + * Schedules a command to retrieve the cookie with the given name. Returns null + * if there is no such cookie. The cookie will be returned as a JSON object as + * described by the WebDriver wire protocol. + * + * @param {string} name The name of the cookie to retrieve. + * @return {!promise.Promise} A promise + * that will be resolved with the named cookie, or `null` if there is no + * such cookie. + */ + getCookie(name) { + return this.getCookies().then(function(cookies) { + for (let cookie of cookies) { + if (cookie && cookie['name'] === name) { + return cookie; + } + } + return null; + }); + } + + /** + * @return {!Logs} The interface for managing driver + * logs. + */ + logs() { + return new Logs(this.driver_); + } + + /** + * @return {!Timeouts} The interface for managing driver timeouts. + */ + timeouts() { + return new Timeouts(this.driver_); + } + + /** + * @return {!Window} The interface for managing the current window. + */ + window() { + return new Window(this.driver_); + } +} + + +/** + * A JSON description of a browser cookie. + * @typedef {{ + * name: string, + * value: string, + * path: (string|undefined), + * domain: (string|undefined), + * secure: (boolean|undefined), + * expiry: (number|undefined) + * }} + */ +Options.Cookie; + + +/** + * An interface for managing timeout behavior for WebDriver instances. + * + * This class should never be instantiated directly. Insead, obtain an instance + * with + * + * webdriver.manage().timeouts() + * + * @see WebDriver#manage() + * @see Options#timeouts() + */ +class Timeouts { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Specifies the amount of time the driver should wait when searching for an + * element if it is not immediately present. + * + * When searching for a single element, the driver should poll the page + * until the element has been found, or this timeout expires before failing + * with a {@link bot.ErrorCode.NO_SUCH_ELEMENT} error. When searching + * for multiple elements, the driver should poll the page until at least one + * element has been found or this timeout has expired. + * + * Setting the wait timeout to 0 (its default value), disables implicit + * waiting. + * + * Increasing the implicit wait timeout should be used judiciously as it + * will have an adverse effect on test run time, especially when used with + * slower location strategies like XPath. + * + * @param {number} ms The amount of time to wait, in milliseconds. + * @return {!promise.Promise} A promise that will be resolved + * when the implicit wait timeout has been set. + */ + implicitlyWait(ms) { + return this.driver_.schedule( + new command.Command(command.Name.IMPLICITLY_WAIT). + setParameter('ms', ms < 0 ? 0 : ms), + 'WebDriver.manage().timeouts().implicitlyWait(' + ms + ')'); + } + + /** + * Sets the amount of time to wait, in milliseconds, for an asynchronous + * script to finish execution before returning an error. If the timeout is + * less than or equal to 0, the script will be allowed to run indefinitely. + * + * @param {number} ms The amount of time to wait, in milliseconds. + * @return {!promise.Promise} A promise that will be resolved + * when the script timeout has been set. + */ + setScriptTimeout(ms) { + return this.driver_.schedule( + new command.Command(command.Name.SET_SCRIPT_TIMEOUT). + setParameter('ms', ms < 0 ? 0 : ms), + 'WebDriver.manage().timeouts().setScriptTimeout(' + ms + ')'); + } + + /** + * Sets the amount of time to wait for a page load to complete before + * returning an error. If the timeout is negative, page loads may be + * indefinite. + * + * @param {number} ms The amount of time to wait, in milliseconds. + * @return {!promise.Promise} A promise that will be resolved + * when the timeout has been set. + */ + pageLoadTimeout(ms) { + return this.driver_.schedule( + new command.Command(command.Name.SET_TIMEOUT). + setParameter('type', 'page load'). + setParameter('ms', ms), + 'WebDriver.manage().timeouts().pageLoadTimeout(' + ms + ')'); + } +} + + +/** + * An interface for managing the current window. + * + * This class should never be instantiated directly. Insead, obtain an instance + * with + * + * webdriver.manage().window() + * + * @see WebDriver#manage() + * @see Options#window() + */ +class Window { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Retrieves the window's current position, relative to the top left corner of + * the screen. + * @return {!promise.Promise.<{x: number, y: number}>} A promise + * that will be resolved with the window's position in the form of a + * {x:number, y:number} object literal. + */ + getPosition() { + return this.driver_.schedule( + new command.Command(command.Name.GET_WINDOW_POSITION). + setParameter('windowHandle', 'current'), + 'WebDriver.manage().window().getPosition()'); + } + + /** + * Repositions the current window. + * @param {number} x The desired horizontal position, relative to the left + * side of the screen. + * @param {number} y The desired vertical position, relative to the top of the + * of the screen. + * @return {!promise.Promise} A promise that will be resolved + * when the command has completed. + */ + setPosition(x, y) { + return this.driver_.schedule( + new command.Command(command.Name.SET_WINDOW_POSITION). + setParameter('windowHandle', 'current'). + setParameter('x', x). + setParameter('y', y), + 'WebDriver.manage().window().setPosition(' + x + ', ' + y + ')'); + } + + /** + * Retrieves the window's current size. + * @return {!promise.Promise<{width: number, height: number}>} A + * promise that will be resolved with the window's size in the form of a + * {width:number, height:number} object literal. + */ + getSize() { + return this.driver_.schedule( + new command.Command(command.Name.GET_WINDOW_SIZE). + setParameter('windowHandle', 'current'), + 'WebDriver.manage().window().getSize()'); + } + + /** + * Resizes the current window. + * @param {number} width The desired window width. + * @param {number} height The desired window height. + * @return {!promise.Promise} A promise that will be resolved + * when the command has completed. + */ + setSize(width, height) { + return this.driver_.schedule( + new command.Command(command.Name.SET_WINDOW_SIZE). + setParameter('windowHandle', 'current'). + setParameter('width', width). + setParameter('height', height), + 'WebDriver.manage().window().setSize(' + width + ', ' + height + ')'); + } + + /** + * Maximizes the current window. + * @return {!promise.Promise} A promise that will be resolved + * when the command has completed. + */ + maximize() { + return this.driver_.schedule( + new command.Command(command.Name.MAXIMIZE_WINDOW). + setParameter('windowHandle', 'current'), + 'WebDriver.manage().window().maximize()'); + } +} + + +/** + * Interface for managing WebDriver log records. + * + * This class should never be instantiated directly. Instead, obtain an + * instance with + * + * webdriver.manage().logs() + * + * @see WebDriver#manage() + * @see Options#logs() + */ +class Logs { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Fetches available log entries for the given type. + * + * Note that log buffers are reset after each call, meaning that available + * log entries correspond to those entries not yet returned for a given log + * type. In practice, this means that this call will return the available log + * entries since the last call, or from the start of the session. + * + * @param {!logging.Type} type The desired log type. + * @return {!promise.Promise.>} A + * promise that will resolve to a list of log entries for the specified + * type. + */ + get(type) { + let cmd = new command.Command(command.Name.GET_LOG). + setParameter('type', type); + return this.driver_.schedule( + cmd, 'WebDriver.manage().logs().get(' + type + ')'). + then(function(entries) { + return entries.map(function(entry) { + if (!(entry instanceof logging.Entry)) { + return new logging.Entry( + entry['level'], entry['message'], entry['timestamp'], + entry['type']); + } + return entry; + }); + }); + } + + /** + * Retrieves the log types available to this driver. + * @return {!promise.Promise>} A + * promise that will resolve to a list of available log types. + */ + getAvailableLogTypes() { + return this.driver_.schedule( + new command.Command(command.Name.GET_AVAILABLE_LOG_TYPES), + 'WebDriver.manage().logs().getAvailableLogTypes()'); + } +} + + +/** + * An interface for changing the focus of the driver to another frame or window. + * + * This class should never be instantiated directly. Instead, obtain an + * instance with + * + * webdriver.switchTo() + * + * @see WebDriver#switchTo() + */ +class TargetLocator { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Schedules a command retrieve the {@code document.activeElement} element on + * the current document, or {@code document.body} if activeElement is not + * available. + * @return {!WebElementPromise} The active element. + */ + activeElement() { + var id = this.driver_.schedule( + new command.Command(command.Name.GET_ACTIVE_ELEMENT), + 'WebDriver.switchTo().activeElement()'); + return new WebElementPromise(this.driver_, id); + } + + /** + * Schedules a command to switch focus of all future commands to the topmost + * frame on the page. + * @return {!promise.Promise} A promise that will be resolved + * when the driver has changed focus to the default content. + */ + defaultContent() { + return this.driver_.schedule( + new command.Command(command.Name.SWITCH_TO_FRAME). + setParameter('id', null), + 'WebDriver.switchTo().defaultContent()'); + } + + /** + * Schedules a command to switch the focus of all future commands to another + * frame on the page. The target frame may be specified as one of the + * following: + * + * - A number that specifies a (zero-based) index into [window.frames]( + * https://developer.mozilla.org/en-US/docs/Web/API/Window.frames). + * - A {@link WebElement} reference, which correspond to a `frame` or `iframe` + * DOM element. + * - The `null` value, to select the topmost frame on the page. Passing `null` + * is the same as calling {@link #defaultContent defaultContent()}. + * + * If the specified frame can not be found, the returned promise will be + * rejected with a {@linkplain error.NoSuchFrameError}. + * + * @param {(number|WebElement|null)} id The frame locator. + * @return {!promise.Promise} A promise that will be resolved + * when the driver has changed focus to the specified frame. + */ + frame(id) { + return this.driver_.schedule( + new command.Command(command.Name.SWITCH_TO_FRAME). + setParameter('id', id), + 'WebDriver.switchTo().frame(' + id + ')'); + } + + /** + * Schedules a command to switch the focus of all future commands to another + * window. Windows may be specified by their {@code window.name} attribute or + * by its handle (as returned by {@link WebDriver#getWindowHandles}). + * + * If the specified window cannot be found, the returned promise will be + * rejected with a {@linkplain error.NoSuchWindowError}. + * + * @param {string} nameOrHandle The name or window handle of the window to + * switch focus to. + * @return {!promise.Promise} A promise that will be resolved + * when the driver has changed focus to the specified window. + */ + window(nameOrHandle) { + return this.driver_.schedule( + new command.Command(command.Name.SWITCH_TO_WINDOW). + setParameter('name', nameOrHandle), + 'WebDriver.switchTo().window(' + nameOrHandle + ')'); + } + + /** + * Schedules a command to change focus to the active modal dialog, such as + * those opened by `window.alert()`, `window.confirm()`, and + * `window.prompt()`. The returned promise will be rejected with a + * {@linkplain error.NoSuchAlertError} if there are no open alerts. + * + * @return {!AlertPromise} The open alert. + */ + alert() { + var text = this.driver_.schedule( + new command.Command(command.Name.GET_ALERT_TEXT), + 'WebDriver.switchTo().alert()'); + var driver = this.driver_; + return new AlertPromise(driver, text.then(function(text) { + return new Alert(driver, text); + })); + } +} + + +////////////////////////////////////////////////////////////////////////////// +// +// WebElement +// +////////////////////////////////////////////////////////////////////////////// + + +const LEGACY_ELEMENT_ID_KEY = 'ELEMENT'; +const ELEMENT_ID_KEY = 'element-6066-11e4-a52e-4f735466cecf'; + + +/** + * Represents a DOM element. WebElements can be found by searching from the + * document root using a {@link WebDriver} instance, or by searching + * under another WebElement: + * + * driver.get('http://www.google.com'); + * var searchForm = driver.findElement(By.tagName('form')); + * var searchBox = searchForm.findElement(By.name('q')); + * searchBox.sendKeys('webdriver'); + */ +class WebElement { + /** + * @param {!WebDriver} driver the parent WebDriver instance for this element. + * @param {(!IThenable|string)} id The server-assigned opaque ID for + * the underlying DOM element. + */ + constructor(driver, id) { + /** @private {!WebDriver} */ + this.driver_ = driver; + + /** @private {!promise.Promise} */ + this.id_ = promise.fulfilled(id); + } + + /** + * @param {string} id The raw ID. + * @return {!Object} The element ID for use with WebDriver's wire protocol. + */ + static buildId(id) { + return {[ELEMENT_ID_KEY]: id, [LEGACY_ELEMENT_ID_KEY]: id}; + } + + /** + * Extracts the encoded WebElement ID from the object. + * + * @param {?} obj The object to extract the ID from. + * @return {string} the extracted ID. + * @throws {TypeError} if the object is not a valid encoded ID. + */ + static extractId(obj) { + if (obj && typeof obj === 'object') { + if (typeof obj[ELEMENT_ID_KEY] === 'string') { + return obj[ELEMENT_ID_KEY]; + } else if (typeof obj[LEGACY_ELEMENT_ID_KEY] === 'string') { + return obj[LEGACY_ELEMENT_ID_KEY]; + } + } + throw new TypeError('object is not a WebElement ID'); + } + + /** + * @param {?} obj the object to test. + * @return {boolean} whether the object is a valid encoded WebElement ID. + */ + static isId(obj) { + return obj && typeof obj === 'object' + && (typeof obj[ELEMENT_ID_KEY] === 'string' + || typeof obj[LEGACY_ELEMENT_ID_KEY] === 'string'); + } + + /** + * Compares two WebElements for equality. + * + * @param {!WebElement} a A WebElement. + * @param {!WebElement} b A WebElement. + * @return {!promise.Promise} A promise that will be + * resolved to whether the two WebElements are equal. + */ + static equals(a, b) { + if (a === b) { + return promise.fulfilled(true); + } + let ids = [a.getId(), b.getId()]; + return promise.all(ids).then(function(ids) { + // If the two element's have the same ID, they should be considered + // equal. Otherwise, they may still be equivalent, but we'll need to + // ask the server to check for us. + if (ids[0] === ids[1]) { + return true; + } + + let cmd = new command.Command(command.Name.ELEMENT_EQUALS); + cmd.setParameter('id', ids[0]); + cmd.setParameter('other', ids[1]); + return a.driver_.schedule(cmd, 'WebElement.equals()'); + }); + } + + /** @return {!WebDriver} The parent driver for this instance. */ + getDriver() { + return this.driver_; + } + + /** + * @return {!promise.Promise} A promise that resolves to + * the server-assigned opaque ID assigned to this element. + */ + getId() { + return this.id_; + } + + /** + * @deprecated Use {@link #getId()} instead. + */ + getRawId() { + return this.getId(); + } + + /** + * @return {!Object} Returns the serialized representation of this WebElement. + */ + [Symbols.serialize]() { + return this.getId().then(WebElement.buildId); + } + + /** + * Schedules a command that targets this element with the parent WebDriver + * instance. Will ensure this element's ID is included in the command + * parameters under the "id" key. + * + * @param {!command.Command} command The command to schedule. + * @param {string} description A description of the command for debugging. + * @return {!promise.Promise} A promise that will be resolved + * with the command result. + * @template T + * @see WebDriver#schedule + * @private + */ + schedule_(command, description) { + command.setParameter('id', this.getId()); + return this.driver_.schedule(command, description); + } + + /** + * Schedule a command to find a descendant of this element. If the element + * cannot be found, the returned promise will be rejected with a + * {@linkplain error.NoSuchElementError NoSuchElementError}. + * + * The search criteria for an element may be defined using one of the static + * factories on the {@link by.By} class, or as a short-hand + * {@link ./by.ByHash} object. For example, the following two statements + * are equivalent: + * + * var e1 = element.findElement(By.id('foo')); + * var e2 = element.findElement({id:'foo'}); + * + * You may also provide a custom locator function, which takes as input this + * instance and returns a {@link WebElement}, or a promise that will resolve + * to a WebElement. If the returned promise resolves to an array of + * WebElements, WebDriver will use the first element. For example, to find the + * first visible link on a page, you could write: + * + * var link = element.findElement(firstVisibleLink); + * + * function firstVisibleLink(element) { + * var links = element.findElements(By.tagName('a')); + * return promise.filter(links, function(link) { + * return link.isDisplayed(); + * }); + * } + * + * @param {!(by.By|Function)} locator The locator strategy to use when + * searching for the element. + * @return {!WebElementPromise} A WebElement that can be used to issue + * commands against the located element. If the element is not found, the + * element will be invalidated and all scheduled commands aborted. + */ + findElement(locator) { + locator = by.checkedLocator(locator); + let id; + if (typeof locator === 'function') { + id = this.driver_.findElementInternal_(locator, this); + } else { + let cmd = new command.Command( + command.Name.FIND_CHILD_ELEMENT). + setParameter('using', locator.using). + setParameter('value', locator.value); + id = this.schedule_(cmd, 'WebElement.findElement(' + locator + ')'); + } + return new WebElementPromise(this.driver_, id); + } + + /** + * Schedules a command to test if there is at least one descendant of this + * element that matches the given search criteria. + * + * @param {!(by.By|Function)} locator The locator strategy to use when + * searching for the element. + * @return {!promise.Promise} A promise that will be + * resolved with whether an element could be located on the page. + */ + isElementPresent(locator) { + return this.findElements(locator).then(function(result) { + return !!result.length; + }); + } + + /** + * Schedules a command to find all of the descendants of this element that + * match the given search criteria. + * + * @param {!(by.By|Function)} locator The locator strategy to use when + * searching for the element. + * @return {!promise.Promise>} A + * promise that will resolve to an array of WebElements. + */ + findElements(locator) { + locator = by.checkedLocator(locator); + let id; + if (typeof locator === 'function') { + return this.driver_.findElementsInternal_(locator, this); + } else { + var cmd = new command.Command( + command.Name.FIND_CHILD_ELEMENTS). + setParameter('using', locator.using). + setParameter('value', locator.value); + return this.schedule_(cmd, 'WebElement.findElements(' + locator + ')'); + } + } + + /** + * Schedules a command to click on this element. + * @return {!promise.Promise} A promise that will be resolved + * when the click command has completed. + */ + click() { + return this.schedule_( + new command.Command(command.Name.CLICK_ELEMENT), + 'WebElement.click()'); + } + + /** + * Schedules a command to type a sequence on the DOM element represented by + * this instance. + * + * Modifier keys (SHIFT, CONTROL, ALT, META) are stateful; once a modifier is + * processed in the keysequence, that key state is toggled until one of the + * following occurs: + * + * - The modifier key is encountered again in the sequence. At this point the + * state of the key is toggled (along with the appropriate keyup/down + * events). + * - The {@link input.Key.NULL} key is encountered in the sequence. When + * this key is encountered, all modifier keys current in the down state are + * released (with accompanying keyup events). The NULL key can be used to + * simulate common keyboard shortcuts: + * + * element.sendKeys("text was", + * Key.CONTROL, "a", Key.NULL, + * "now text is"); + * // Alternatively: + * element.sendKeys("text was", + * Key.chord(Key.CONTROL, "a"), + * "now text is"); + * + * - The end of the keysequence is encountered. When there are no more keys + * to type, all depressed modifier keys are released (with accompanying + * keyup events). + * + * If this element is a file input ({@code }), the + * specified key sequence should specify the path to the file to attach to + * the element. This is analgous to the user clicking "Browse..." and entering + * the path into the file select dialog. + * + * var form = driver.findElement(By.css('form')); + * var element = form.findElement(By.css('input[type=file]')); + * element.sendKeys('/path/to/file.txt'); + * form.submit(); + * + * For uploads to function correctly, the entered path must reference a file + * on the _browser's_ machine, not the local machine running this script. When + * running against a remote Selenium server, a {@link input.FileDetector} + * may be used to transparently copy files to the remote machine before + * attempting to upload them in the browser. + * + * __Note:__ On browsers where native keyboard events are not supported + * (e.g. Firefox on OS X), key events will be synthesized. Special + * punctionation keys will be synthesized according to a standard QWERTY en-us + * keyboard layout. + * + * @param {...(string|!promise.Promise)} var_args The + * sequence of keys to type. All arguments will be joined into a single + * sequence. + * @return {!promise.Promise} A promise that will be resolved + * when all keys have been typed. + */ + sendKeys(var_args) { + // Coerce every argument to a string. This protects us from users that + // ignore the jsdoc and give us a number (which ends up causing problems on + // the server, which requires strings). + let keys = promise.all(Array.prototype.slice.call(arguments, 0)). + then(keys => keys.map(String)); + if (!this.driver_.fileDetector_) { + return this.schedule_( + new command.Command(command.Name.SEND_KEYS_TO_ELEMENT). + setParameter('value', keys), + 'WebElement.sendKeys()'); + } + + // Suppress unhandled rejection errors until the flow executes the command. + keys.thenCatch(function() {}); + + var element = this; + return this.driver_.flow_.execute(function() { + return keys.then(function(keys) { + return element.driver_.fileDetector_ + .handleFile(element.driver_, keys.join('')); + }).then(function(keys) { + return element.schedule_( + new command.Command(command.Name.SEND_KEYS_TO_ELEMENT). + setParameter('value', [keys]), + 'WebElement.sendKeys()'); + }); + }, 'WebElement.sendKeys()'); + } + + /** + * Schedules a command to query for the tag/node name of this element. + * @return {!promise.Promise} A promise that will be + * resolved with the element's tag name. + */ + getTagName() { + return this.schedule_( + new command.Command(command.Name.GET_ELEMENT_TAG_NAME), + 'WebElement.getTagName()'); + } + + /** + * Schedules a command to query for the computed style of the element + * represented by this instance. If the element inherits the named style from + * its parent, the parent will be queried for its value. Where possible, color + * values will be converted to their hex representation (e.g. #00ff00 instead of + * rgb(0, 255, 0)). + * + * _Warning:_ the value returned will be as the browser interprets it, so + * it may be tricky to form a proper assertion. + * + * @param {string} cssStyleProperty The name of the CSS style property to look + * up. + * @return {!promise.Promise} A promise that will be + * resolved with the requested CSS value. + */ + getCssValue(cssStyleProperty) { + var name = command.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY; + return this.schedule_( + new command.Command(name). + setParameter('propertyName', cssStyleProperty), + 'WebElement.getCssValue(' + cssStyleProperty + ')'); + } + + /** + * Schedules a command to query for the value of the given attribute of the + * element. Will return the current value, even if it has been modified after + * the page has been loaded. More exactly, this method will return the value of + * the given attribute, unless that attribute is not present, in which case the + * value of the property with the same name is returned. If neither value is + * set, null is returned (for example, the "value" property of a textarea + * element). The "style" attribute is converted as best can be to a + * text representation with a trailing semi-colon. The following are deemed to + * be "boolean" attributes and will return either "true" or null: + * + * async, autofocus, autoplay, checked, compact, complete, controls, declare, + * defaultchecked, defaultselected, defer, disabled, draggable, ended, + * formnovalidate, hidden, indeterminate, iscontenteditable, ismap, itemscope, + * loop, multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open, + * paused, pubdate, readonly, required, reversed, scoped, seamless, seeking, + * selected, spellcheck, truespeed, willvalidate + * + * Finally, the following commonly mis-capitalized attribute/property names + * are evaluated as expected: + * + * - "class" + * - "readonly" + * + * @param {string} attributeName The name of the attribute to query. + * @return {!promise.Promise} A promise that will be + * resolved with the attribute's value. The returned value will always be + * either a string or null. + */ + getAttribute(attributeName) { + return this.schedule_( + new command.Command(command.Name.GET_ELEMENT_ATTRIBUTE). + setParameter('name', attributeName), + 'WebElement.getAttribute(' + attributeName + ')'); + } + + /** + * Get the visible (i.e. not hidden by CSS) innerText of this element, including + * sub-elements, without any leading or trailing whitespace. + * @return {!promise.Promise} A promise that will be + * resolved with the element's visible text. + */ + getText() { + return this.schedule_( + new command.Command(command.Name.GET_ELEMENT_TEXT), + 'WebElement.getText()'); + } + + /** + * Schedules a command to compute the size of this element's bounding box, in + * pixels. + * @return {!promise.Promise.<{width: number, height: number}>} A + * promise that will be resolved with the element's size as a + * {@code {width:number, height:number}} object. + */ + getSize() { + return this.schedule_( + new command.Command(command.Name.GET_ELEMENT_SIZE), + 'WebElement.getSize()'); + } + + /** + * Schedules a command to compute the location of this element in page space. + * @return {!promise.Promise.<{x: number, y: number}>} A promise that + * will be resolved to the element's location as a + * {@code {x:number, y:number}} object. + */ + getLocation() { + return this.schedule_( + new command.Command(command.Name.GET_ELEMENT_LOCATION), + 'WebElement.getLocation()'); + } + + /** + * Schedules a command to query whether the DOM element represented by this + * instance is enabled, as dicted by the {@code disabled} attribute. + * @return {!promise.Promise} A promise that will be + * resolved with whether this element is currently enabled. + */ + isEnabled() { + return this.schedule_( + new command.Command(command.Name.IS_ELEMENT_ENABLED), + 'WebElement.isEnabled()'); + } + + /** + * Schedules a command to query whether this element is selected. + * @return {!promise.Promise} A promise that will be + * resolved with whether this element is currently selected. + */ + isSelected() { + return this.schedule_( + new command.Command(command.Name.IS_ELEMENT_SELECTED), + 'WebElement.isSelected()'); + } + + /** + * Schedules a command to submit the form containing this element (or this + * element if it is a FORM element). This command is a no-op if the element is + * not contained in a form. + * @return {!promise.Promise} A promise that will be resolved + * when the form has been submitted. + */ + submit() { + return this.schedule_( + new command.Command(command.Name.SUBMIT_ELEMENT), + 'WebElement.submit()'); + } + + /** + * Schedules a command to clear the `value` of this element. This command has + * no effect if the underlying DOM element is neither a text INPUT element + * nor a TEXTAREA element. + * @return {!promise.Promise} A promise that will be resolved + * when the element has been cleared. + */ + clear() { + return this.schedule_( + new command.Command(command.Name.CLEAR_ELEMENT), + 'WebElement.clear()'); + } + + /** + * Schedules a command to test whether this element is currently displayed. + * @return {!promise.Promise} A promise that will be + * resolved with whether this element is currently visible on the page. + */ + isDisplayed() { + return this.schedule_( + new command.Command(command.Name.IS_ELEMENT_DISPLAYED), + 'WebElement.isDisplayed()'); + } + + /** + * Take a screenshot of the visible region encompassed by this element's + * bounding rectangle. + * + * @param {boolean=} opt_scroll Optional argument that indicates whether the + * element should be scrolled into view before taking a screenshot. + * Defaults to false. + * @return {!promise.Promise} A promise that will be + * resolved to the screenshot as a base-64 encoded PNG. + */ + takeScreenshot(opt_scroll) { + var scroll = !!opt_scroll; + return this.schedule_( + new command.Command(command.Name.TAKE_ELEMENT_SCREENSHOT) + .setParameter('scroll', scroll), + 'WebElement.takeScreenshot(' + scroll + ')'); + } + + /** + * Schedules a command to retrieve the outer HTML of this element. + * @return {!promise.Promise} A promise that will be + * resolved with the element's outer HTML. + */ + getOuterHtml() { + return this.driver_.executeScript(function() { + var element = arguments[0]; + if ('outerHTML' in element) { + return element.outerHTML; + } else { + var div = element.ownerDocument.createElement('div'); + div.appendChild(element.cloneNode(true)); + return div.innerHTML; + } + }, this); + } + + /** + * Schedules a command to retrieve the inner HTML of this element. + * @return {!promise.Promise} A promise that will be + * resolved with the element's inner HTML. + */ + getInnerHtml() { + return this.driver_.executeScript('return arguments[0].innerHTML', this); + } +} + + +/** + * WebElementPromise is a promise that will be fulfilled with a WebElement. + * This serves as a forward proxy on WebElement, allowing calls to be + * scheduled without directly on this instance before the underlying + * WebElement has been fulfilled. In other words, the following two statements + * are equivalent: + * + * driver.findElement({id: 'my-button'}).click(); + * driver.findElement({id: 'my-button'}).then(function(el) { + * return el.click(); + * }); + * + * @implements {promise.Thenable} + * @final + */ +class WebElementPromise extends WebElement { + /** + * @param {!WebDriver} driver The parent WebDriver instance for this + * element. + * @param {!promise.Promise} el A promise + * that will resolve to the promised element. + */ + constructor(driver, el) { + super(driver, 'unused'); + + /** @override */ + this.cancel = el.cancel.bind(el); + + /** @override */ + this.isPending = el.isPending.bind(el); + + /** @override */ + this.then = el.then.bind(el); + + /** @override */ + this.catch = el.catch.bind(el); + + /** @override */ + this.thenCatch = el.thenCatch.bind(el); + + /** @override */ + this.thenFinally = el.thenFinally.bind(el); + + /** + * Defers returning the element ID until the wrapped WebElement has been + * resolved. + * @override + */ + this.getId = function() { + return el.then(function(el) { + return el.getId(); + }); + }; + } +} +promise.Thenable.addImplementation(WebElementPromise); + + +////////////////////////////////////////////////////////////////////////////// +// +// Alert +// +////////////////////////////////////////////////////////////////////////////// + + +/** + * Represents a modal dialog such as {@code alert}, {@code confirm}, or + * {@code prompt}. Provides functions to retrieve the message displayed with + * the alert, accept or dismiss the alert, and set the response text (in the + * case of {@code prompt}). + */ +class Alert { + /** + * @param {!WebDriver} driver The driver controlling the browser this alert + * is attached to. + * @param {string} text The message text displayed with this alert. + */ + constructor(driver, text) { + /** @private {!WebDriver} */ + this.driver_ = driver; + + /** @private {!promise.Promise} */ + this.text_ = promise.fulfilled(text); + } + + /** + * Retrieves the message text displayed with this alert. For instance, if the + * alert were opened with alert("hello"), then this would return "hello". + * + * @return {!promise.Promise} A promise that will be + * resolved to the text displayed with this alert. + */ + getText() { + return this.text_; + } + + /** + * Accepts this alert. + * + * @return {!promise.Promise} A promise that will be resolved + * when this command has completed. + */ + accept() { + return this.driver_.schedule( + new command.Command(command.Name.ACCEPT_ALERT), + 'WebDriver.switchTo().alert().accept()'); + } + + /** + * Dismisses this alert. + * + * @return {!promise.Promise} A promise that will be resolved + * when this command has completed. + */ + dismiss() { + return this.driver_.schedule( + new command.Command(command.Name.DISMISS_ALERT), + 'WebDriver.switchTo().alert().dismiss()'); + } + + /** + * Sets the response text on this alert. This command will return an error if + * the underlying alert does not support response text (e.g. window.alert and + * window.confirm). + * + * @param {string} text The text to set. + * @return {!promise.Promise} A promise that will be resolved + * when this command has completed. + */ + sendKeys(text) { + return this.driver_.schedule( + new command.Command(command.Name.SET_ALERT_TEXT). + setParameter('text', text), + 'WebDriver.switchTo().alert().sendKeys(' + text + ')'); + } +} + + +/** + * AlertPromise is a promise that will be fulfilled with an Alert. This promise + * serves as a forward proxy on an Alert, allowing calls to be scheduled + * directly on this instance before the underlying Alert has been fulfilled. In + * other words, the following two statements are equivalent: + * + * driver.switchTo().alert().dismiss(); + * driver.switchTo().alert().then(function(alert) { + * return alert.dismiss(); + * }); + * + * @implements {promise.Thenable.} + * @final + */ +class AlertPromise extends Alert { + /** + * @param {!WebDriver} driver The driver controlling the browser this + * alert is attached to. + * @param {!promise.Thenable} alert A thenable + * that will be fulfilled with the promised alert. + */ + constructor(driver, alert) { + super(driver, 'unused'); + + /** @override */ + this.cancel = alert.cancel.bind(alert); + + /** @override */ + this.isPending = alert.isPending.bind(alert); + + /** @override */ + this.then = alert.then.bind(alert); + + /** @override */ + this.catch = alert.catch.bind(alert); + + /** @override */ + this.thenCatch = alert.thenCatch.bind(alert); + + /** @override */ + this.thenFinally = alert.thenFinally.bind(alert); + + /** + * Defer returning text until the promised alert has been resolved. + * @override + */ + this.getText = function() { + return alert.then(function(alert) { + return alert.getText(); + }); + }; + + /** + * Defers action until the alert has been located. + * @override + */ + this.accept = function() { + return alert.then(function(alert) { + return alert.accept(); + }); + }; + + /** + * Defers action until the alert has been located. + * @override + */ + this.dismiss = function() { + return alert.then(function(alert) { + return alert.dismiss(); + }); + }; + + /** + * Defers action until the alert has been located. + * @override + */ + this.sendKeys = function(text) { + return alert.then(function(alert) { + return alert.sendKeys(text); + }); + }; + } +} +promise.Thenable.addImplementation(AlertPromise); + + +// PUBLIC API + + +exports.Alert = Alert; +exports.AlertPromise = AlertPromise; +exports.Logs = Logs; +exports.Navigation = Navigation; +exports.Options = Options; +exports.TargetLocator = TargetLocator; +exports.Timeouts = Timeouts; +/** @deprecated Use {@link error.UnexpectedAlertOpenError} instead. */ +exports.UnhandledAlertError = error.UnexpectedAlertOpenError; +exports.WebDriver = WebDriver; +exports.WebElement = WebElement; +exports.WebElementPromise = WebElementPromise; +exports.Window = Window; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/net/index.js b/platforms/android/assets/www/node_modules/selenium-webdriver/net/index.js new file mode 100644 index 0000000..4142ebc --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/net/index.js @@ -0,0 +1,82 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var os = require('os'); + + +function getLoInterface() { + var name; + if (process.platform === 'darwin') { + name = 'lo0'; + } else if (process.platform === 'linux') { + name = 'lo'; + } + return name ? os.networkInterfaces()[name] : null; +} + + +/** + * Queries the system network interfaces for an IP address. + * @param {boolean} loopback Whether to find a loopback address. + * @param {string=} opt_family The IP family (IPv4 or IPv6). Defaults to IPv4. + * @return {string} The located IP address or undefined. + */ +function getAddress(loopback, opt_family) { + var family = opt_family || 'IPv4'; + var addresses = []; + + var interfaces; + if (loopback) { + var lo = getLoInterface(); + interfaces = lo ? [lo] : null; + } + interfaces = interfaces || os.networkInterfaces(); + for (var key in interfaces) { + interfaces[key].forEach(function(ipAddress) { + if (ipAddress.family === family && + ipAddress.internal === loopback) { + addresses.push(ipAddress.address); + } + }); + } + return addresses[0]; +} + + +// PUBLIC API + + +/** + * Retrieves the external IP address for this host. + * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4". + * @return {string} The IP address or undefined if not available. + */ +exports.getAddress = function(opt_family) { + return getAddress(false, opt_family); +}; + + +/** + * Retrieves a loopback address for this machine. + * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4". + * @return {string} The IP address or undefined if not available. + */ +exports.getLoopbackAddress = function(opt_family) { + return getAddress(true, opt_family); +}; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/net/portprober.js b/platforms/android/assets/www/node_modules/selenium-webdriver/net/portprober.js new file mode 100644 index 0000000..f455ede --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/net/portprober.js @@ -0,0 +1,219 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var exec = require('child_process').exec, + fs = require('fs'), + net = require('net'); + +var promise = require('../lib/promise'); + + +/** + * The IANA suggested ephemeral port range. + * @type {{min: number, max: number}} + * @const + * @see http://en.wikipedia.org/wiki/Ephemeral_ports + */ +var DEFAULT_IANA_RANGE = {min: 49152, max: 65535}; + + +/** + * The epheremal port range for the current system. Lazily computed on first + * access. + * @type {promise.Promise.<{min: number, max: number}>} + */ +var systemRange = null; + + +/** + * Computes the ephemeral port range for the current system. This is based on + * http://stackoverflow.com/a/924337. + * @return {promise.Promise.<{min: number, max: number}>} A promise + * that will resolve to the ephemeral port range of the current system. + */ +function findSystemPortRange() { + if (systemRange) { + return systemRange; + } + var range = process.platform === 'win32' ? + findWindowsPortRange() : findUnixPortRange(); + return systemRange = range.thenCatch(function() { + return DEFAULT_IANA_RANGE; + }); +} + + +/** + * Executes a command and returns its output if it succeeds. + * @param {string} cmd The command to execute. + * @return {!promise.Promise.} A promise that will resolve + * with the command's stdout data. + */ +function execute(cmd) { + var result = promise.defer(); + exec(cmd, function(err, stdout) { + if (err) { + result.reject(err); + } else { + result.fulfill(stdout); + } + }); + return result.promise; +} + + +/** + * Computes the ephemeral port range for a Unix-like system. + * @return {!promise.Promise.<{min: number, max: number}>} A promise + * that will resolve with the ephemeral port range on the current system. + */ +function findUnixPortRange() { + var cmd; + if (process.platform === 'sunos') { + cmd = + '/usr/sbin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port'; + } else if (fs.existsSync('/proc/sys/net/ipv4/ip_local_port_range')) { + // Linux + cmd = 'cat /proc/sys/net/ipv4/ip_local_port_range'; + } else { + cmd = 'sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last' + + ' | sed -e "s/.*:\\s*//"'; + } + + return execute(cmd).then(function(stdout) { + if (!stdout || !stdout.length) return DEFAULT_IANA_RANGE; + var range = stdout.trim().split(/\s+/).map(Number); + if (range.some(isNaN)) return DEFAULT_IANA_RANGE; + return {min: range[0], max: range[1]}; + }); +} + + +/** + * Computes the ephemeral port range for a Windows system. + * @return {!promise.Promise.<{min: number, max: number}>} A promise + * that will resolve with the ephemeral port range on the current system. + */ +function findWindowsPortRange() { + var deferredRange = promise.defer(); + // First, check if we're running on XP. If this initial command fails, + // we just fallback on the default IANA range. + return execute('cmd.exe /c ver').then(function(stdout) { + if (/Windows XP/.test(stdout)) { + // TODO: Try to read these values from the registry. + return {min: 1025, max: 5000}; + } else { + return execute('netsh int ipv4 show dynamicport tcp'). + then(function(stdout) { + /* > netsh int ipv4 show dynamicport tcp + Protocol tcp Dynamic Port Range + --------------------------------- + Start Port : 49152 + Number of Ports : 16384 + */ + var range = stdout.split(/\n/).filter(function(line) { + return /.*:\s*\d+/.test(line); + }).map(function(line) { + return Number(line.split(/:\s*/)[1]); + }); + + return { + min: range[0], + max: range[0] + range[1] + }; + }); + } + }); +} + + +/** + * Tests if a port is free. + * @param {number} port The port to test. + * @param {string=} opt_host The bound host to test the {@code port} against. + * Defaults to {@code INADDR_ANY}. + * @return {!promise.Promise.} A promise that will resolve + * with whether the port is free. + */ +function isFree(port, opt_host) { + var result = promise.defer(); + + result.promise.thenCatch(function(e) { + if (e instanceof promise.CancellationError) { + server.close(); + } + }); + + var server = net.createServer().on('error', function(e) { + if (e.code === 'EADDRINUSE') { + result.fulfill(false); + } else { + result.reject(e); + } + }); + + server.listen(port, opt_host, function() { + server.close(function() { + result.fulfill(true); + }); + }); + + return result.promise; +} + + +/** + * @param {string=} opt_host The bound host to test the {@code port} against. + * Defaults to {@code INADDR_ANY}. + * @return {!promise.Promise.} A promise that will resolve + * to a free port. If a port cannot be found, the promise will be + * rejected. + */ +function findFreePort(opt_host) { + return findSystemPortRange().then(function(range) { + var attempts = 0; + var deferredPort = promise.defer(); + findPort(); + return deferredPort.promise; + + function findPort() { + attempts += 1; + if (attempts > 10) { + deferredPort.reject(Error('Unable to find a free port')); + } + + var port = Math.floor( + Math.random() * (range.max - range.min) + range.min); + isFree(port, opt_host).then(function(isFree) { + if (isFree) { + deferredPort.fulfill(port); + } else { + findPort(); + } + }); + } + }); +} + + +// PUBLIC API + + +exports.findFreePort = findFreePort; +exports.isFree = isFree; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/opera.js b/platforms/android/assets/www/node_modules/selenium-webdriver/opera.js new file mode 100644 index 0000000..33f1e5b --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/opera.js @@ -0,0 +1,480 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a {@linkplain Driver WebDriver} client for the + * Opera web browser (v26+). Before using this module, you must download the + * latest OperaDriver + * [release](https://github.com/operasoftware/operachromiumdriver/releases) and + * ensure it can be found on your system + * [PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). + * + * There are three primary classes exported by this module: + * + * 1. {@linkplain ServiceBuilder}: configures the + * {@link selenium-webdriver/remote.DriverService remote.DriverService} + * that manages the + * [OperaDriver](https://github.com/operasoftware/operachromiumdriver) + * child process. + * + * 2. {@linkplain Options}: defines configuration options for each new Opera + * session, such as which {@linkplain Options#setProxy proxy} to use, + * what {@linkplain Options#addExtensions extensions} to install, or + * what {@linkplain Options#addArguments command-line switches} to use when + * starting the browser. + * + * 3. {@linkplain Driver}: the WebDriver client; each new instance will control + * a unique browser session with a clean user profile (unless otherwise + * configured through the {@link Options} class). + * + * By default, every Opera session will use a single driver service, which is + * started the first time a {@link Driver} instance is created and terminated + * when this process exits. The default service will inherit its environment + * from the current process and direct all output to /dev/null. You may obtain + * a handle to this default service using + * {@link #getDefaultService getDefaultService()} and change its configuration + * with {@link #setDefaultService setDefaultService()}. + * + * You may also create a {@link Driver} with its own driver service. This is + * useful if you need to capture the server's log output for a specific session: + * + * var opera = require('selenium-webdriver/opera'); + * + * var service = new opera.ServiceBuilder() + * .loggingTo('/my/log/file.txt') + * .enableVerboseLogging() + * .build(); + * + * var options = new opera.Options(); + * // configure browser options ... + * + * var driver = new opera.Driver(options, service); + * + * Users should only instantiate the {@link Driver} class directly when they + * need a custom driver service configuration (as shown above). For normal + * operation, users should start Opera using the + * {@link selenium-webdriver.Builder}. + */ + +'use strict'; + +const fs = require('fs'); + +const executors = require('./executors'), + io = require('./io'), + capabilities = require('./lib/capabilities'), + promise = require('./lib/promise'), + Symbols = require('./lib/symbols'), + webdriver = require('./lib/webdriver'), + portprober = require('./net/portprober'), + remote = require('./remote'); + + +/** + * Name of the OperaDriver executable. + * @type {string} + * @const + */ +const OPERADRIVER_EXE = + process.platform === 'win32' ? 'operadriver.exe' : 'operadriver'; + + +/** + * Creates {@link remote.DriverService} instances that manages an + * [OperaDriver](https://github.com/operasoftware/operachromiumdriver) + * server in a child process. + */ +class ServiceBuilder { + /** + * @param {string=} opt_exe Path to the server executable to use. If omitted, + * the builder will attempt to locate the operadriver on the current + * PATH. + * @throws {Error} If provided executable does not exist, or the operadriver + * cannot be found on the PATH. + */ + constructor(opt_exe) { + let exe = opt_exe || io.findInPath(OPERADRIVER_EXE, true); + if (!exe) { + throw Error( + 'The OperaDriver could not be found on the current PATH. Please ' + + 'download the latest version of the OperaDriver from ' + + 'https://github.com/operasoftware/operachromiumdriver/releases and ' + + 'ensure it can be found on your PATH.'); + } + + /** @private {string} */ + this.exe_ = /** @type {string} */(exe); + if (!fs.existsSync(this.exe_)) { + throw Error('File does not exist: ' + this.exe_); + } + + /** @private {!Array.} */ + this.args_ = []; + + /** @private {number} */ + this.port_ = 0; + + /** + * @private {(string|!Array)} + */ + this.stdio_ = 'ignore'; + + /** @private {Object.} */ + this.env_ = null; + } + + /** + * Sets the port to start the OperaDriver on. + * @param {number} port The port to use, or 0 for any free port. + * @return {!ServiceBuilder} A self reference. + * @throws {Error} If the port is invalid. + */ + usingPort(port) { + if (port < 0) { + throw Error('port must be >= 0: ' + port); + } + this.port_ = port; + return this; + } + + /** + * Sets the path of the log file the driver should log to. If a log file is + * not specified, the driver will log to stderr. + * @param {string} path Path of the log file to use. + * @return {!ServiceBuilder} A self reference. + */ + loggingTo(path) { + this.args_.push('--log-path=' + path); + return this; + } + + /** + * Enables verbose logging. + * @return {!ServiceBuilder} A self reference. + */ + enableVerboseLogging() { + this.args_.push('--verbose'); + return this; + } + + /** + * Silence sthe drivers output. + * @return {!ServiceBuilder} A self reference. + */ + silent() { + this.args_.push('--silent'); + return this; + } + + /** + * Defines the stdio configuration for the driver service. See + * {@code child_process.spawn} for more information. + * @param {(string|!Array)} + * config The configuration to use. + * @return {!ServiceBuilder} A self reference. + */ + setStdio(config) { + this.stdio_ = config; + return this; + } + + /** + * Defines the environment to start the server under. This settings will be + * inherited by every browser session started by the server. + * @param {!Object.} env The environment to use. + * @return {!ServiceBuilder} A self reference. + */ + withEnvironment(env) { + this.env_ = env; + return this; + } + + /** + * Creates a new DriverService using this instance's current configuration. + * @return {!remote.DriverService} A new driver service using this instance's + * current configuration. + * @throws {Error} If the driver exectuable was not specified and a default + * could not be found on the current PATH. + */ + build() { + var port = this.port_ || portprober.findFreePort(); + var args = this.args_.concat(); // Defensive copy. + + return new remote.DriverService(this.exe_, { + loopback: true, + port: port, + args: promise.when(port, function(port) { + return args.concat('--port=' + port); + }), + env: this.env_, + stdio: this.stdio_ + }); + }; +} + + + +/** @type {remote.DriverService} */ +var defaultService = null; + + +/** + * Sets the default service to use for new OperaDriver instances. + * @param {!remote.DriverService} service The service to use. + * @throws {Error} If the default service is currently running. + */ +function setDefaultService(service) { + if (defaultService && defaultService.isRunning()) { + throw Error( + 'The previously configured OperaDriver service is still running. ' + + 'You must shut it down before you may adjust its configuration.'); + } + defaultService = service; +} + + +/** + * Returns the default OperaDriver service. If such a service has not been + * configured, one will be constructed using the default configuration for + * a OperaDriver executable found on the system PATH. + * @return {!remote.DriverService} The default OperaDriver service. + */ +function getDefaultService() { + if (!defaultService) { + defaultService = new ServiceBuilder().build(); + } + return defaultService; +} + + +/** + * @type {string} + * @const + */ +var OPTIONS_CAPABILITY_KEY = 'chromeOptions'; + + +/** + * Class for managing {@linkplain Driver OperaDriver} specific options. + */ +class Options { + constructor() { + /** @private {!Array.} */ + this.args_ = []; + + /** @private {?string} */ + this.binary_ = null; + + /** @private {!Array.<(string|!Buffer)>} */ + this.extensions_ = []; + + /** @private {./lib/logging.Preferences} */ + this.logPrefs_ = null; + + /** @private {?capabilities.ProxyConfig} */ + this.proxy_ = null; + } + + /** + * Extracts the OperaDriver specific options from the given capabilities + * object. + * @param {!capabilities.Capabilities} caps The capabilities object. + * @return {!Options} The OperaDriver options. + */ + static fromCapabilities(caps) { + var options; + var o = caps.get(OPTIONS_CAPABILITY_KEY); + if (o instanceof Options) { + options = o; + } else if (o) { + options = new Options() + .addArguments(o.args || []) + .addExtensions(o.extensions || []) + .setOperaBinaryPath(o.binary); + } else { + options = new Options; + } + + if (caps.has(capabilities.Capability.PROXY)) { + options.setProxy(caps.get(capabilities.Capability.PROXY)); + } + + if (caps.has(capabilities.Capability.LOGGING_PREFS)) { + options.setLoggingPrefs( + caps.get(capabilities.Capability.LOGGING_PREFS)); + } + + return options; + } + + /** + * Add additional command line arguments to use when launching the Opera + * browser. Each argument may be specified with or without the "--" prefix + * (e.g. "--foo" and "foo"). Arguments with an associated value should be + * delimited by an "=": "foo=bar". + * @param {...(string|!Array.)} var_args The arguments to add. + * @return {!Options} A self reference. + */ + addArguments(var_args) { + this.args_ = this.args_.concat.apply(this.args_, arguments); + return this; + } + + /** + * Add additional extensions to install when launching Opera. Each extension + * should be specified as the path to the packed CRX file, or a Buffer for an + * extension. + * @param {...(string|!Buffer|!Array.<(string|!Buffer)>)} var_args The + * extensions to add. + * @return {!Options} A self reference. + */ + addExtensions(var_args) { + this.extensions_ = this.extensions_.concat.apply( + this.extensions_, arguments); + return this; + } + + /** + * Sets the path to the Opera binary to use. On Mac OS X, this path should + * reference the actual Opera executable, not just the application binary. The + * binary path be absolute or relative to the operadriver server executable, but + * it must exist on the machine that will launch Opera. + * + * @param {string} path The path to the Opera binary to use. + * @return {!Options} A self reference. + */ + setOperaBinaryPath(path) { + this.binary_ = path; + return this; + } + + /** + * Sets the logging preferences for the new session. + * @param {!./lib/logging.Preferences} prefs The logging preferences. + * @return {!Options} A self reference. + */ + setLoggingPrefs(prefs) { + this.logPrefs_ = prefs; + return this; + } + + /** + * Sets the proxy settings for the new session. + * @param {capabilities.ProxyConfig} proxy The proxy configuration to use. + * @return {!Options} A self reference. + */ + setProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * Converts this options instance to a {@link capabilities.Capabilities} + * object. + * @param {capabilities.Capabilities=} opt_capabilities The capabilities to + * merge these options into, if any. + * @return {!capabilities.Capabilities} The capabilities. + */ + toCapabilities(opt_capabilities) { + var caps = opt_capabilities || capabilities.Capabilities.opera(); + caps. + set(capabilities.Capability.PROXY, this.proxy_). + set(capabilities.Capability.LOGGING_PREFS, this.logPrefs_). + set(OPTIONS_CAPABILITY_KEY, this); + return caps; + } + + /** + * Converts this instance to its JSON wire protocol representation. Note this + * function is an implementation not intended for general use. + * @return {!Object} The JSON wire protocol representation of this instance. + */ + [Symbols.serialize]() { + var json = { + args: this.args_, + extensions: this.extensions_.map(function(extension) { + if (Buffer.isBuffer(extension)) { + return extension.toString('base64'); + } + return promise.checkedNodeCall( + fs.readFile, extension, 'base64'); + }) + }; + if (this.binary_) { + json.binary = this.binary_; + } + return json; + } +} + + +/** + * Creates a new WebDriver client for Opera. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(capabilities.Capabilities|Options)=} opt_config The configuration + * options. + * @param {remote.DriverService=} opt_service The session to use; will use + * the {@link getDefaultService default service} by default. + * @param {promise.ControlFlow=} opt_flow The control flow to use, + * or {@code null} to use the currently active flow. + */ + constructor(opt_config, opt_service, opt_flow) { + var service = opt_service || getDefaultService(); + var executor = executors.createExecutor(service.start()); + + var caps = + opt_config instanceof Options ? opt_config.toCapabilities() : + (opt_config || capabilities.Capabilities.opera()); + + // On Linux, the OperaDriver does not look for Opera on the PATH, so we + // must explicitly find it. See: operachromiumdriver #9. + if (process.platform === 'linux') { + var options = Options.fromCapabilities(caps); + if (!options.binary_) { + let exe = io.findInPath('opera', true); + if (!exe) { + throw Error( + 'The opera executable could not be found on the current PATH'); + } + options.setOperaBinaryPath(exe); + } + caps = options.toCapabilities(caps); + } + + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + super(driver.getSession(), executor, driver.controlFlow()); + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() {} +} + + +// PUBLIC API + + +exports.Driver = Driver; +exports.Options = Options; +exports.ServiceBuilder = ServiceBuilder; +exports.getDefaultService = getDefaultService; +exports.setDefaultService = setDefaultService; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/package.json b/platforms/android/assets/www/node_modules/selenium-webdriver/package.json new file mode 100644 index 0000000..6c227ff --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/package.json @@ -0,0 +1,94 @@ +{ + "_args": [ + [ + "selenium-webdriver", + "/Users/adamdon/Desktop/studywell/studywell/sw/www" + ] + ], + "_from": "selenium-webdriver@latest", + "_id": "selenium-webdriver@2.52.0", + "_inCache": true, + "_installable": true, + "_location": "/selenium-webdriver", + "_nodeVersion": "0.12.0", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/selenium-webdriver-2.52.0.tgz_1455259913894_0.6562679694034159" + }, + "_npmUser": { + "email": "jmleyba@gmail.com", + "name": "jmleyba" + }, + "_npmVersion": "2.5.1", + "_phantomChildren": {}, + "_requested": { + "name": "selenium-webdriver", + "raw": "selenium-webdriver", + "rawSpec": "", + "scope": null, + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.52.0.tgz", + "_shasum": "d2dcb2f51b48733d6c42829e52767ecee2bf4b6b", + "_shrinkwrap": null, + "_spec": "selenium-webdriver", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www", + "bugs": { + "url": "https://github.com/SeleniumHQ/selenium/issues" + }, + "dependencies": { + "adm-zip": "0.4.4", + "rimraf": "^2.2.8", + "tmp": "0.0.24", + "ws": "^1.0.1", + "xml2js": "0.4.4" + }, + "description": "The official WebDriver JavaScript bindings from the Selenium project", + "devDependencies": { + "express": "^4.11.2", + "mocha": ">= 1.21.x", + "multer": "^0.1.7", + "promises-aplus-tests": "^2.1.0", + "serve-index": "^1.6.1", + "sinon": "^1.17.2" + }, + "directories": {}, + "dist": { + "shasum": "d2dcb2f51b48733d6c42829e52767ecee2bf4b6b", + "tarball": "http://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.52.0.tgz" + }, + "engines": { + "node": ">= 4.2.x" + }, + "homepage": "https://github.com/SeleniumHQ/selenium", + "keywords": [ + "automation", + "selenium", + "testing", + "webdriver", + "webdriverjs" + ], + "license": "Apache-2.0", + "main": "./index", + "maintainers": [ + { + "email": "jmleyba@gmail.com", + "name": "jmleyba" + } + ], + "name": "selenium-webdriver", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/SeleniumHQ/selenium.git" + }, + "scripts": { + "test": "mocha --harmony -t 600000 --recursive test" + }, + "version": "2.52.0" +} diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/phantomjs.js b/platforms/android/assets/www/node_modules/selenium-webdriver/phantomjs.js new file mode 100644 index 0000000..7853149 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/phantomjs.js @@ -0,0 +1,260 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const fs = require('fs'); + +const executors = require('./executors'), + http = require('./http'), + io = require('./io'), + capabilities = require('./lib/capabilities'), + command = require('./lib/command'), + logging = require('./lib/logging'), + promise = require('./lib/promise'), + webdriver = require('./lib/webdriver'), + portprober = require('./net/portprober'), + remote = require('./remote'); + + +/** + * Name of the PhantomJS executable. + * @type {string} + * @const + */ +const PHANTOMJS_EXE = + process.platform === 'win32' ? 'phantomjs.exe' : 'phantomjs'; + + +/** + * Capability that designates the location of the PhantomJS executable to use. + * @type {string} + * @const + */ +const BINARY_PATH_CAPABILITY = 'phantomjs.binary.path'; + + +/** + * Capability that designates the CLI arguments to pass to PhantomJS. + * @type {string} + * @const + */ +const CLI_ARGS_CAPABILITY = 'phantomjs.cli.args'; + + +/** + * Default log file to use if one is not specified through CLI args. + * @type {string} + * @const + */ +const DEFAULT_LOG_FILE = 'phantomjsdriver.log'; + + +/** + * Custom command names supported by PhantomJS. + * @enum {string} + */ +const Command = { + EXECUTE_PHANTOM_SCRIPT: 'executePhantomScript' +}; + + +/** + * Finds the PhantomJS executable. + * @param {string=} opt_exe Path to the executable to use. + * @return {string} The located executable. + * @throws {Error} If the executable cannot be found on the PATH, or if the + * provided executable path does not exist. + */ +function findExecutable(opt_exe) { + var exe = opt_exe || io.findInPath(PHANTOMJS_EXE, true); + if (!exe) { + throw Error( + 'The PhantomJS executable could not be found on the current PATH. ' + + 'Please download the latest version from ' + + 'http://phantomjs.org/download.html and ensure it can be found on ' + + 'your PATH. For more information, see ' + + 'https://github.com/ariya/phantomjs/wiki'); + } + if (!fs.existsSync(exe)) { + throw Error('File does not exist: ' + exe); + } + return exe; +} + + +/** + * Maps WebDriver logging level name to those recognised by PhantomJS. + * @const {!Map} + */ +const WEBDRIVER_TO_PHANTOMJS_LEVEL = new Map([ + [logging.Level.ALL.name, 'DEBUG'], + [logging.Level.DEBUG.name, 'DEBUG'], + [logging.Level.INFO.name, 'INFO'], + [logging.Level.WARNING.name, 'WARN'], + [logging.Level.SEVERE.name, 'ERROR']]); + + +/** + * Creates a command executor with support for PhantomJS' custom commands. + * @param {!promise.Promise} url The server's URL. + * @return {!command.Executor} The new command executor. + */ +function createExecutor(url) { + return new executors.DeferredExecutor(url.then(function(url) { + var client = new http.HttpClient(url); + var executor = new http.Executor(client); + + executor.defineCommand( + Command.EXECUTE_PHANTOM_SCRIPT, + 'POST', '/session/:sessionId/phantom/execute'); + + return executor; + })); +} + +/** + * Creates a new WebDriver client for PhantomJS. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {capabilities.Capabilities=} opt_capabilities The desired + * capabilities. + * @param {promise.ControlFlow=} opt_flow The control flow to use, + * or {@code null} to use the currently active flow. + */ + constructor(opt_capabilities, opt_flow) { + var caps = opt_capabilities || capabilities.Capabilities.phantomjs(); + var exe = findExecutable(caps.get(BINARY_PATH_CAPABILITY)); + var args = ['--webdriver-logfile=' + DEFAULT_LOG_FILE]; + + var logPrefs = caps.get(capabilities.Capability.LOGGING_PREFS); + if (logPrefs instanceof logging.Preferences) { + logPrefs = logPrefs.toJSON(); + } + + if (logPrefs && logPrefs[logging.Type.DRIVER]) { + let level = WEBDRIVER_TO_PHANTOMJS_LEVEL.get( + logPrefs[logging.Type.DRIVER]); + if (level) { + args.push('--webdriver-loglevel=' + level); + } + } + + var proxy = caps.get(capabilities.Capability.PROXY); + if (proxy) { + switch (proxy.proxyType) { + case 'manual': + if (proxy.httpProxy) { + args.push( + '--proxy-type=http', + '--proxy=http://' + proxy.httpProxy); + } + break; + case 'pac': + throw Error('PhantomJS does not support Proxy PAC files'); + case 'system': + args.push('--proxy-type=system'); + break; + case 'direct': + args.push('--proxy-type=none'); + break; + } + } + args = args.concat(caps.get(CLI_ARGS_CAPABILITY) || []); + + var port = portprober.findFreePort(); + var service = new remote.DriverService(exe, { + port: port, + args: promise.when(port, function(port) { + args.push('--webdriver=' + port); + return args; + }) + }); + + var executor = createExecutor(service.start()); + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + + super(driver.getSession(), executor, driver.controlFlow()); + + var boundQuit = this.quit.bind(this); + + /** @override */ + this.quit = function() { + return boundQuit().thenFinally(service.kill.bind(service)); + }; + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() {} + + /** + * Executes a PhantomJS fragment. This method is similar to + * {@link #executeScript}, except it exposes the + * PhantomJS API to the injected + * script. + * + *

    The injected script will execute in the context of PhantomJS's + * {@code page} variable. If a page has not been loaded before calling this + * method, one will be created.

    + * + *

    Be sure to wrap callback definitions in a try/catch block, as failures + * may cause future WebDriver calls to fail.

    + * + *

    Certain callbacks are used by GhostDriver (the PhantomJS WebDriver + * implementation) and overriding these may cause the script to fail. It is + * recommended that you check for existing callbacks before defining your own. + *

    + * + * As with {@link #executeScript}, the injected script may be defined as + * a string for an anonymous function body (e.g. "return 123;"), or as a + * function. If a function is provided, it will be decompiled to its original + * source. Note that injecting functions is provided as a convenience to + * simplify defining complex scripts. Care must be taken that the function + * only references variables that will be defined in the page's scope and + * that the function does not override {@code Function.prototype.toString} + * (overriding toString() will interfere with how the function is + * decompiled. + * + * @param {(string|!Function)} script The script to execute. + * @param {...*} var_args The arguments to pass to the script. + * @return {!promise.Promise} A promise that resolve to the + * script's return value. + * @template T + */ + executePhantomJS(script, var_args) { + if (typeof script === 'function') { + script = 'return (' + script + ').apply(this, arguments);'; + } + var args = arguments.length > 1 + ? Array.prototype.slice.call(arguments, 1) : []; + return this.schedule( + new command.Command(Command.EXECUTE_PHANTOM_SCRIPT) + .setParameter('script', script) + .setParameter('args', args), + 'Driver.executePhantomJS()'); + } +} + + +// PUBLIC API + +exports.Driver = Driver; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/proxy.js b/platforms/android/assets/www/node_modules/selenium-webdriver/proxy.js new file mode 100644 index 0000000..e238cb1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/proxy.js @@ -0,0 +1,103 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines functions for configuring a webdriver proxy: + * + * var webdriver = require('selenium-webdriver'), + * proxy = require('selenium-webdriver/proxy'); + * + * var driver = new webdriver.Builder() + * .withCapabilities(webdriver.Capabilities.chrome()) + * .setProxy(proxy.manual({http: 'host:1234'})) + * .build(); + */ + +'use strict'; + +var util = require('util'); + +var ProxyConfig = require('./lib/capabilities').ProxyConfig; + + + +// PUBLIC API + + +/** + * Configures WebDriver to bypass all browser proxies. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.direct = function() { + return {proxyType: 'direct'}; +}; + + +/** + * Manually configures the browser proxy. The following options are + * supported: + * + * - `ftp`: Proxy host to use for FTP requests + * - `http`: Proxy host to use for HTTP requests + * - `https`: Proxy host to use for HTTPS requests + * - `bypass`: A list of hosts requests should directly connect to, + * bypassing any other proxies for that request. May be specified as a + * comma separated string, or a list of strings. + * + * Behavior is undefined for FTP, HTTP, and HTTPS requests if the + * corresponding key is omitted from the configuration options. + * + * @param {{ftp: (string|undefined), + * http: (string|undefined), + * https: (string|undefined), + * bypass: (string|!Array.|undefined)}} options Proxy + * configuration options. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.manual = function(options) { + return { + proxyType: 'manual', + ftpProxy: options.ftp, + httpProxy: options.http, + sslProxy: options.https, + noProxy: util.isArray(options.bypass) ? + options.bypass.join(',') : options.bypass + }; +}; + + +/** + * Configures WebDriver to configure the browser proxy using the PAC file at + * the given URL. + * @param {string} url URL for the PAC proxy to use. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.pac = function(url) { + return { + proxyType: 'pac', + proxyAutoconfigUrl: url + }; +}; + + +/** + * Configures WebDriver to use the current system's proxy. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.system = function() { + return {proxyType: 'system'}; +}; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/remote/index.js b/platforms/android/assets/www/node_modules/selenium-webdriver/remote/index.js new file mode 100644 index 0000000..7b5eeeb --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/remote/index.js @@ -0,0 +1,381 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const AdmZip = require('adm-zip'), + AdmConstants = require('adm-zip/util/constants'), + fs = require('fs'), + path = require('path'), + url = require('url'), + util = require('util'); + +const httpUtil = require('../http/util'), + exec = require('../io/exec'), + cmd = require('../lib/command'), + input = require('../lib/input'), + promise = require('../lib/promise'), + webdriver = require('../lib/webdriver'), + net = require('../net'), + portprober = require('../net/portprober'); + + + +/** + * Configuration options for a DriverService instance. + * + * - `loopback` - Whether the service should only be accessed on this host's + * loopback address. + * - `hostname` - The host name to access the server on. If this option is + * specified, the `loopback` option will be ignored. + * - `port` - The port to start the server on (must be > 0). If the port is + * provided as a promise, the service will wait for the promise to resolve + * before starting. + * - `args` - The arguments to pass to the service. If a promise is provided, + * the service will wait for it to resolve before starting. + * - `path` - The base path on the server for the WebDriver wire protocol + * (e.g. '/wd/hub'). Defaults to '/'. + * - `env` - The environment variables that should be visible to the server + * process. Defaults to inheriting the current process's environment. + * - `stdio` - IO configuration for the spawned server process. For more + * information, refer to the documentation of `child_process.spawn`. + * + * @typedef {{ + * loopback: (boolean|undefined), + * hostname: (string|undefined), + * port: (number|!promise.Promise), + * args: !(Array|promise.Promise>), + * path: (string|undefined|null), + * env: (Object|undefined), + * stdio: (string|!Array| + * undefined) + * }} + */ +var ServiceOptions; + + +/** + * Manages the life and death of a native executable WebDriver server. + * + * It is expected that the driver server implements the + * https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol. + * Furthermore, the managed server should support multiple concurrent sessions, + * so that this class may be reused for multiple clients. + */ +class DriverService { + /** + * @param {string} executable Path to the executable to run. + * @param {!ServiceOptions} options Configuration options for the service. + */ + constructor(executable, options) { + /** @private {string} */ + this.executable_ = executable; + + /** @private {boolean} */ + this.loopbackOnly_ = !!options.loopback; + + /** @private {(string|undefined)} */ + this.hostname_ = options.hostname; + + /** @private {(number|!promise.Promise)} */ + this.port_ = options.port; + + /** + * @private {!(Array|promise.Promise>)} + */ + this.args_ = options.args; + + /** @private {string} */ + this.path_ = options.path || '/'; + + /** @private {!Object} */ + this.env_ = options.env || process.env; + + /** + * @private {(string|!Array)} + */ + this.stdio_ = options.stdio || 'ignore'; + + /** + * A promise for the managed subprocess, or null if the server has not been + * started yet. This promise will never be rejected. + * @private {promise.Deferred} + */ + this.command_ = null; + + /** + * Promise that resolves to the server's address or null if the server has + * not been started. This promise will be rejected if the server terminates + * before it starts accepting WebDriver requests. + * @private {promise.Deferred} + */ + this.address_ = null; + } + + /** + * @return {!promise.Promise} A promise that resolves to + * the server's address. + * @throws {Error} If the server has not been started. + */ + address() { + if (this.address_) { + return this.address_.promise; + } + throw Error('Server has not been started.'); + } + + /** + * Returns whether the underlying process is still running. This does not take + * into account whether the process is in the process of shutting down. + * @return {boolean} Whether the underlying service process is running. + */ + isRunning() { + return !!this.address_; + } + + /** + * Starts the server if it is not already running. + * @param {number=} opt_timeoutMs How long to wait, in milliseconds, for the + * server to start accepting requests. Defaults to 30 seconds. + * @return {!promise.Promise} A promise that will resolve + * to the server's base URL when it has started accepting requests. If the + * timeout expires before the server has started, the promise will be + * rejected. + */ + start(opt_timeoutMs) { + if (this.address_) { + return this.address_.promise; + } + + var timeout = opt_timeoutMs || DriverService.DEFAULT_START_TIMEOUT_MS; + + var self = this; + this.command_ = promise.defer(); + this.address_ = promise.defer(); + this.address_.fulfill(promise.when(this.port_, function(port) { + if (port <= 0) { + throw Error('Port must be > 0: ' + port); + } + return promise.when(self.args_, function(args) { + var command = exec(self.executable_, { + args: args, + env: self.env_, + stdio: self.stdio_ + }); + + self.command_.fulfill(command); + + var earlyTermination = command.result().then(function(result) { + var error = result.code == null ? + Error('Server was killed with ' + result.signal) : + Error('Server terminated early with status ' + result.code); + self.address_.reject(error); + self.address_ = null; + self.command_ = null; + throw error; + }); + + var hostname = self.hostname_; + if (!hostname) { + hostname = !self.loopbackOnly_ && net.getAddress() + || net.getLoopbackAddress(); + } + + var serverUrl = url.format({ + protocol: 'http', + hostname: hostname, + port: port, + pathname: self.path_ + }); + + return new promise.Promise(function(fulfill, reject) { + var ready = httpUtil.waitForServer(serverUrl, timeout) + .then(fulfill, reject); + earlyTermination.thenCatch(function(e) { + ready.cancel(/** @type {Error} */(e)); + reject(Error(e.message)); + }); + }).then(function() { + return serverUrl; + }); + }); + })); + + return this.address_.promise; + } + + /** + * Stops the service if it is not currently running. This function will kill + * the server immediately. To synchronize with the active control flow, use + * {@link #stop()}. + * @return {!promise.Promise} A promise that will be resolved when + * the server has been stopped. + */ + kill() { + if (!this.address_ || !this.command_) { + return promise.fulfilled(); // Not currently running. + } + return this.command_.promise.then(function(command) { + command.kill('SIGTERM'); + }); + } + + /** + * Schedules a task in the current control flow to stop the server if it is + * currently running. + * @return {!promise.Promise} A promise that will be resolved when + * the server has been stopped. + */ + stop() { + return promise.controlFlow().execute(this.kill.bind(this)); + } +} + + +/** + * The default amount of time, in milliseconds, to wait for the server to + * start. + * @const {number} + */ +DriverService.DEFAULT_START_TIMEOUT_MS = 30 * 1000; + + +/** + * Manages the life and death of the + * + * standalone Selenium server. + */ +class SeleniumServer extends DriverService { + /** + * @param {string} jar Path to the Selenium server jar. + * @param {SeleniumServer.Options=} opt_options Configuration options for the + * server. + * @throws {Error} If the path to the Selenium jar is not specified or if an + * invalid port is specified. + */ + constructor(jar, opt_options) { + if (!jar) { + throw Error('Path to the Selenium jar not specified'); + } + + var options = opt_options || {}; + + if (options.port < 0) { + throw Error('Port must be >= 0: ' + options.port); + } + + var port = options.port || portprober.findFreePort(); + var args = promise.when(options.jvmArgs || [], function(jvmArgs) { + return promise.when(options.args || [], function(args) { + return promise.when(port, function(port) { + return jvmArgs.concat(['-jar', jar, '-port', port]).concat(args); + }); + }); + }); + + super('java', { + loopback: options.loopback, + port: port, + args: args, + path: '/wd/hub', + env: options.env, + stdio: options.stdio + }); + } +} + + +/** + * Options for the Selenium server: + * + * - `loopback` - Whether the server should only be accessed on this host's + * loopback address. + * - `port` - The port to start the server on (must be > 0). If the port is + * provided as a promise, the service will wait for the promise to resolve + * before starting. + * - `args` - The arguments to pass to the service. If a promise is provided, + * the service will wait for it to resolve before starting. + * - `jvmArgs` - The arguments to pass to the JVM. If a promise is provided, + * the service will wait for it to resolve before starting. + * - `env` - The environment variables that should be visible to the server + * process. Defaults to inheriting the current process's environment. + * - `stdio` - IO configuration for the spawned server process. For more + * information, refer to the documentation of `child_process.spawn`. + * + * @typedef {{ + * loopback: (boolean|undefined), + * port: (number|!promise.Promise), + * args: !(Array|promise.Promise>), + * jvmArgs: (!Array| + * !promise.Promise>| + * undefined), + * env: (!Object|undefined), + * stdio: (string|!Array| + * undefined) + * }} + */ +SeleniumServer.Options; + + + +/** + * A {@link webdriver.FileDetector} that may be used when running + * against a remote + * [Selenium server](http://selenium-release.storage.googleapis.com/index.html). + * + * When a file path on the local machine running this script is entered with + * {@link webdriver.WebElement#sendKeys WebElement#sendKeys}, this file detector + * will transfer the specified file to the Selenium server's host; the sendKeys + * command will be updated to use the transfered file's path. + * + * __Note:__ This class depends on a non-standard command supported on the + * Java Selenium server. The file detector will fail if used with a server that + * only supports standard WebDriver commands (such as the ChromeDriver). + * + * @final + */ +class FileDetector extends input.FileDetector { + /** @override */ + handleFile(driver, filePath) { + return promise.checkedNodeCall(fs.stat, filePath).then(function(stats) { + if (stats.isDirectory()) { + throw TypeError('Uploading directories is not supported: ' + filePath); + } + + var zip = new AdmZip(); + zip.addLocalFile(filePath); + zip.getEntries()[0].header.method = AdmConstants.STORED; + + var command = new cmd.Command(cmd.Name.UPLOAD_FILE) + .setParameter('file', zip.toBuffer().toString('base64')); + return driver.schedule(command, + 'remote.FileDetector.handleFile(' + filePath + ')'); + }, function(err) { + if (err.code === 'ENOENT') { + return filePath; // Not a file; return original input. + } + throw err; + }); + } +} + + +// PUBLIC API + +exports.DriverService = DriverService; +exports.FileDetector = FileDetector; +exports.SeleniumServer = SeleniumServer; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/safari.js b/platforms/android/assets/www/node_modules/selenium-webdriver/safari.js new file mode 100644 index 0000000..e4b56d6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/safari.js @@ -0,0 +1,547 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a WebDriver client for Safari. Before using this + * module, you must install the + * [latest version](http://selenium-release.storage.googleapis.com/index.html) + * of the SafariDriver browser extension; using Safari for normal browsing is + * not recommended once the extension has been installed. You can, and should, + * disable the extension when the browser is not being used with WebDriver. + */ + +'use strict'; + +const events = require('events'); +const fs = require('fs'); +const http = require('http'); +const path = require('path'); +const url = require('url'); +const util = require('util'); +const ws = require('ws'); + +const io = require('./io'); +const exec = require('./io/exec'); +const isDevMode = require('./lib/devmode'); +const Capabilities = require('./lib/capabilities').Capabilities; +const Capability = require('./lib/capabilities').Capability; +const command = require('./lib/command'); +const promise = require('./lib/promise'); +const Symbols = require('./lib/symbols'); +const webdriver = require('./lib/webdriver'); +const portprober = require('./net/portprober'); + + +/** @const */ +const CLIENT_PATH = isDevMode + ? path.join(__dirname, + '../../../build/javascript/safari-driver/client.js') + : path.join(__dirname, 'lib/safari/client.js'); + + +/** @const */ +const LIBRARY_DIR = (function() { + if (process.platform === 'darwin') { + return path.join('/Users', process.env['USER'], 'Library/Safari'); + } else if (process.platform === 'win32') { + return path.join(process.env['APPDATA'], 'Apple Computer', 'Safari'); + } else { + return '/dev/null'; + } +})(); + + +/** @const */ +const SESSION_DATA_FILES = (function() { + if (process.platform === 'darwin') { + var libraryDir = path.join('/Users', process.env['USER'], 'Library'); + return [ + path.join(libraryDir, 'Caches/com.apple.Safari/Cache.db'), + path.join(libraryDir, 'Cookies/Cookies.binarycookies'), + path.join(libraryDir, 'Cookies/Cookies.plist'), + path.join(libraryDir, 'Safari/History.plist'), + path.join(libraryDir, 'Safari/LastSession.plist'), + path.join(libraryDir, 'Safari/LocalStorage'), + path.join(libraryDir, 'Safari/Databases') + ]; + } else if (process.platform === 'win32') { + var appDataDir = path.join(process.env['APPDATA'], + 'Apple Computer', 'Safari'); + var localDataDir = path.join(process.env['LOCALAPPDATA'], + 'Apple Computer', 'Safari'); + return [ + path.join(appDataDir, 'History.plist'), + path.join(appDataDir, 'LastSession.plist'), + path.join(appDataDir, 'Cookies/Cookies.plist'), + path.join(appDataDir, 'Cookies/Cookies.binarycookies'), + path.join(localDataDir, 'Cache.db'), + path.join(localDataDir, 'Databases'), + path.join(localDataDir, 'LocalStorage') + ]; + } else { + return []; + } +})(); + + +/** @typedef {{port: number, address: string, family: string}} */ +var Host; + + +/** + * A basic HTTP/WebSocket server used to communicate with the SafariDriver + * browser extension. + */ +class Server extends events.EventEmitter { + constructor() { + super(); + var server = http.createServer(function(req, res) { + if (req.url === '/favicon.ico') { + res.writeHead(204); + res.end(); + return; + } + + var query = url.parse(/** @type {string} */(req.url)).query || ''; + if (query.indexOf('url=') == -1) { + var address = server.address() + var host = address.address + ':' + address.port; + res.writeHead( + 302, {'Location': 'http://' + host + '?url=ws://' + host}); + res.end(); + } + + fs.readFile(CLIENT_PATH, 'utf8', function(err, data) { + if (err) { + res.writeHead(500, {'Content-Type': 'text/plain'}); + res.end(err.stack); + return; + } + var content = ''; + res.writeHead(200, { + 'Content-Type': 'text/html; charset=utf-8', + 'Content-Length': Buffer.byteLength(content, 'utf8'), + }); + res.end(content); + }); + }); + + var wss = new ws.Server({server: server}); + wss.on('connection', this.emit.bind(this, 'connection')); + + /** + * Starts the server on a random port. + * @return {!promise.Promise} A promise that will resolve + * with the server host when it has fully started. + */ + this.start = function() { + if (server.address()) { + return promise.fulfilled(server.address()); + } + return portprober.findFreePort('localhost').then(function(port) { + return promise.checkedNodeCall( + server.listen.bind(server, port, 'localhost')); + }).then(function() { + return server.address(); + }); + }; + + /** + * Stops the server. + * @return {!promise.Promise} A promise that will resolve when + * the server has closed all connections. + */ + this.stop = function() { + return new promise.Promise(function(fulfill) { + server.close(fulfill); + }); + }; + + /** + * @return {Host} This server's host info. + * @throws {Error} If the server is not running. + */ + this.address = function() { + var addr = server.address(); + if (!addr) { + throw Error('There server is not running!'); + } + return addr; + }; + } +} + + +/** + * @return {!Promise} A promise that will resolve with the path + * to Safari on the current system. + */ +function findSafariExecutable() { + switch (process.platform) { + case 'darwin': + return Promise.resolve('/Applications/Safari.app/Contents/MacOS/Safari'); + + case 'win32': + var files = [ + process.env['PROGRAMFILES'] || '\\Program Files', + process.env['PROGRAMFILES(X86)'] || '\\Program Files (x86)' + ].map(function(prefix) { + return path.join(prefix, 'Safari\\Safari.exe'); + }); + return io.exists(files[0]).then(function(exists) { + return exists ? files[0] : io.exists(files[1]).then(function(exists) { + if (exists) { + return files[1]; + } + throw Error('Unable to find Safari on the current system'); + }); + }); + + default: + return Promise.reject( + Error('Safari is not supported on the current platform: ' + + process.platform)); + } +} + + +/** + * @param {string} serverUrl The URL to connect to. + * @return {!Promise} A promise for the path to a file that Safari can + * open on start-up to trigger a new connection to the WebSocket server. + */ +function createConnectFile(serverUrl) { + return io.tmpFile({postfix: '.html'}).then(function(f) { + var writeFile = promise.checkedNodeCall(fs.writeFile, + f, + '', + {encoding: 'utf8'}); + return writeFile.then(function() { + return f; + }); + }); +} + + +/** + * Deletes all session data files if so desired. + * @param {!Object} desiredCapabilities . + * @return {!Array} A list of promises for the deleted files. + */ +function cleanSession(desiredCapabilities) { + if (!desiredCapabilities) { + return []; + } + var options = desiredCapabilities[OPTIONS_CAPABILITY_KEY]; + if (!options) { + return []; + } + if (!options['cleanSession']) { + return []; + } + return SESSION_DATA_FILES.map(function(file) { + return io.unlink(file); + }); +} + + +/** @return {string} . */ +function getRandomString() { + let seed = Date.now(); + return Math.floor(Math.random() * seed).toString(36) + + Math.abs(Math.floor(Math.random() * seed) ^ Date.now()).toString(36); +} + + +/** + * @implements {command.Executor} + */ +class CommandExecutor { + constructor() { + this.server_ = null; + + /** @private {ws.WebSocket} */ + this.socket_ = null; + + /** @private {promise.Promise.} */ + this.safari_ = null; + } + + /** @override */ + execute(cmd) { + var self = this; + return new promise.Promise(function(fulfill, reject) { + var safariCommand = JSON.stringify({ + 'origin': 'webdriver', + 'type': 'command', + 'command': { + 'id': getRandomString(), + 'name': cmd.getName(), + 'parameters': cmd.getParameters() + } + }); + + switch (cmd.getName()) { + case command.Name.NEW_SESSION: + self.startSafari_(cmd) + .then(() => self.sendCommand_(safariCommand)) + .then(fulfill, reject); + break; + + case command.Name.QUIT: + self.destroySession_() + .then(() => fulfill({status: 0, value: null}), reject); + break; + + default: + self.sendCommand_(safariCommand).then(fulfill, reject); + break; + } + }); + } + + /** + * @param {string} data . + * @return {!promise.Promise} . + * @private + */ + sendCommand_(data) { + let self = this; + return new promise.Promise(function(fulfill, reject) { + // TODO: support reconnecting with the extension. + if (!self.socket_) { + self.destroySession_().thenFinally(function() { + reject(Error('The connection to the SafariDriver was closed')); + }); + return; + } + + self.socket_.send(data, function(err) { + if (err) { + reject(err); + return; + } + }); + + self.socket_.once('message', function(data) { + try { + data = JSON.parse(data); + } catch (ex) { + reject(Error('Failed to parse driver message: ' + data)); + return; + } + fulfill(data['response']); + }); + }); + } + + /** + * @param {!command.Command} command . + * @private + */ + startSafari_(command) { + this.server_ = new Server(); + + this.safari_ = this.server_.start().then(function(address) { + var tasks = cleanSession( + /** @type {!Object} */( + command.getParameters()['desiredCapabilities'])); + tasks.push( + findSafariExecutable(), + createConnectFile( + 'http://' + address.address + ':' + address.port)); + return promise.all(tasks).then(function(tasks) { + var exe = tasks[tasks.length - 2]; + var html = tasks[tasks.length - 1]; + return exec(exe, {args: [html]}); + }); + }); + + var connected = promise.defer(); + var self = this; + var start = Date.now(); + var timer = setTimeout(function() { + connected.reject(Error( + 'Failed to connect to the SafariDriver after ' + (Date.now() - start) + + ' ms; Have you installed the latest extension from ' + + 'http://selenium-release.storage.googleapis.com/index.html?')); + }, 10 * 1000); + this.server_.once('connection', function(socket) { + clearTimeout(timer); + self.socket_ = socket; + socket.once('close', function() { + self.socket_ = null; + }); + connected.fulfill(); + }); + return connected.promise; + } + + /** + * Destroys the active session by stopping the WebSocket server and killing the + * Safari subprocess. + * @private + */ + destroySession_() { + var tasks = []; + if (this.server_) { + tasks.push(this.server_.stop()); + } + if (this.safari_) { + tasks.push(this.safari_.then(function(safari) { + safari.kill(); + return safari.result(); + })); + } + var self = this; + return promise.all(tasks).thenFinally(function() { + self.server_ = null; + self.socket_ = null; + self.safari_ = null; + }); + } +} + + + +/** @const */ +const OPTIONS_CAPABILITY_KEY = 'safari.options'; + + + +/** + * Configuration options specific to the {@link Driver SafariDriver}. + */ +class Options { + constructor() { + /** @private {Object} */ + this.options_ = null; + + /** @private {./lib/logging.Preferences} */ + this.logPrefs_ = null; + } + + /** + * Extracts the SafariDriver specific options from the given capabilities + * object. + * @param {!Capabilities} capabilities The capabilities object. + * @return {!Options} The ChromeDriver options. + */ + static fromCapabilities(capabilities) { + var options = new Options(); + + var o = capabilities.get(OPTIONS_CAPABILITY_KEY); + if (o instanceof Options) { + options = o; + } else if (o) { + options.setCleanSession(o.cleanSession); + } + + if (capabilities.has(Capability.LOGGING_PREFS)) { + options.setLoggingPrefs(capabilities.get(Capability.LOGGING_PREFS)); + } + + return options; + } + + /** + * Sets whether to force Safari to start with a clean session. Enabling this + * option will cause all global browser data to be deleted. + * @param {boolean} clean Whether to make sure the session has no cookies, + * cache entries, local storage, or databases. + * @return {!Options} A self reference. + */ + setCleanSession(clean) { + if (!this.options_) { + this.options_ = {}; + } + this.options_['cleanSession'] = clean; + return this; + } + + /** + * Sets the logging preferences for the new session. + * @param {!./lib/logging.Preferences} prefs The logging preferences. + * @return {!Options} A self reference. + */ + setLoggingPrefs(prefs) { + this.logPrefs_ = prefs; + return this; + } + + /** + * Converts this options instance to a {@link Capabilities} object. + * @param {Capabilities=} opt_capabilities The capabilities to + * merge these options into, if any. + * @return {!Capabilities} The capabilities. + */ + toCapabilities(opt_capabilities) { + var caps = opt_capabilities || Capabilities.safari(); + if (this.logPrefs_) { + caps.set(Capability.LOGGING_PREFS, this.logPrefs_); + } + if (this.options_) { + caps.set(OPTIONS_CAPABILITY_KEY, this); + } + return caps; + } + + /** + * Converts this instance to its JSON wire protocol representation. Note this + * function is an implementation detail not intended for general use. + * @return {!Object} The JSON wire protocol representation of this + * instance. + */ + [Symbols.serialize]() { + return this.options_ || {}; + } +} + + +/** + * A WebDriver client for Safari. This class should never be instantiated + * directly; instead, use the {@linkplain ./builder.Builder Builder}: + * + * var driver = new Builder() + * .forBrowser('safari') + * .build(); + * + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(Options|Capabilities)=} opt_config The configuration + * options for the new session. + * @param {promise.ControlFlow=} opt_flow The control flow to create + * the driver under. + */ + constructor(opt_config, opt_flow) { + var executor = new CommandExecutor(); + var caps = + opt_config instanceof Options ? opt_config.toCapabilities() : + (opt_config || Capabilities.safari()); + + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + super(driver.getSession(), executor, driver.controlFlow()); + } +} + + +// Public API + + +exports.Driver = Driver; +exports.Options = Options; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/actions_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/actions_test.js new file mode 100644 index 0000000..8d6794a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/actions_test.js @@ -0,0 +1,53 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var Browser = require('..').Browser, + By = require('..').By, + until = require('..').until, + test = require('../lib/test'), + fileServer = require('../lib/test/fileserver'); + + +test.suite(function(env) { + var driver; + test.beforeEach(function() { driver = env.builder().build(); }); + test.afterEach(function() { driver.quit(); }); + + test.ignore(env.browsers(Browser.PHANTOM_JS, Browser.SAFARI)). + describe('WebDriver.actions()', function() { + + test.it('can move to and click element in an iframe', function() { + driver.get(fileServer.whereIs('click_tests/click_in_iframe.html')); + + driver.wait(until.elementLocated(By.id('ifr')), 5000) + .then(function(frame) { + driver.switchTo().frame(frame); + }); + + var link = driver.findElement(By.id('link')); + driver.actions() + .mouseMove(link) + .click() + .perform(); + + driver.wait(until.titleIs('Submitted Successfully!'), 5000); + }); + + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/chrome/options_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/chrome/options_test.js new file mode 100644 index 0000000..28c4faa --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/chrome/options_test.js @@ -0,0 +1,227 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fs = require('fs'); + +var webdriver = require('../..'), + chrome = require('../../chrome'), + symbols = require('../../lib/symbols'), + proxy = require('../../proxy'), + assert = require('../../testing/assert'); + +var test = require('../../lib/test'); + + +describe('chrome.Options', function() { + describe('fromCapabilities', function() { + + it('should return a new Options instance if none were defined', + function() { + var options = chrome.Options.fromCapabilities( + new webdriver.Capabilities()); + assert(options).instanceOf(chrome.Options); + }); + + it('should return options instance if present', function() { + var options = new chrome.Options(); + var caps = options.toCapabilities(); + assert(caps).instanceOf(webdriver.Capabilities); + assert(chrome.Options.fromCapabilities(caps)).equalTo(options); + }); + + it('should rebuild options from wire representation', function() { + var expectedExtension = fs.readFileSync(__filename, 'base64'); + var caps = webdriver.Capabilities.chrome().set('chromeOptions', { + args: ['a', 'b'], + extensions: [__filename], + binary: 'binaryPath', + logPath: 'logFilePath', + detach: true, + localState: 'localStateValue', + prefs: 'prefsValue' + }); + + var options = chrome.Options.fromCapabilities(caps); + var json = options[symbols.serialize](); + + assert(json.args.length).equalTo(2); + assert(json.args[0]).equalTo('a'); + assert(json.args[1]).equalTo('b'); + assert(json.extensions.length).equalTo(1); + assert(json.extensions[0]).equalTo(expectedExtension); + assert(json.binary).equalTo('binaryPath'); + assert(json.logPath).equalTo('logFilePath'); + assert(json.detach).equalTo(true); + assert(json.localState).equalTo('localStateValue'); + assert(json.prefs).equalTo('prefsValue'); + }); + + it('should rebuild options from incomplete wire representation', + function() { + var caps = webdriver.Capabilities.chrome().set('chromeOptions', { + logPath: 'logFilePath' + }); + + var options = chrome.Options.fromCapabilities(caps); + var json = options[symbols.serialize](); + assert(json.args).isUndefined(); + assert(json.binary).isUndefined(); + assert(json.detach).isUndefined(); + assert(json.excludeSwitches).isUndefined(); + assert(json.extensions).isUndefined(); + assert(json.localState).isUndefined(); + assert(json.logPath).equalTo('logFilePath'); + assert(json.prefs).isUndefined(); + assert(json.minidumpPath).isUndefined(); + assert(json.mobileEmulation).isUndefined(); + assert(json.perfLoggingPrefs).isUndefined(); + }); + + it('should extract supported WebDriver capabilities', function() { + var proxyPrefs = proxy.direct(); + var logPrefs = {}; + var caps = webdriver.Capabilities.chrome(). + set(webdriver.Capability.PROXY, proxyPrefs). + set(webdriver.Capability.LOGGING_PREFS, logPrefs); + + var options = chrome.Options.fromCapabilities(caps); + assert(options.proxy_).equalTo(proxyPrefs); + assert(options.logPrefs_).equalTo(logPrefs); + }); + }); + + describe('addArguments', function() { + it('takes var_args', function() { + var options = new chrome.Options(); + assert(options[symbols.serialize]().args).isUndefined(); + + options.addArguments('a', 'b'); + var json = options[symbols.serialize](); + assert(json.args.length).equalTo(2); + assert(json.args[0]).equalTo('a'); + assert(json.args[1]).equalTo('b'); + }); + + it('flattens input arrays', function() { + var options = new chrome.Options(); + assert(options[symbols.serialize]().args).isUndefined(); + + options.addArguments(['a', 'b'], 'c', [1, 2], 3); + var json = options[symbols.serialize](); + assert(json.args.length).equalTo(6); + assert(json.args[0]).equalTo('a'); + assert(json.args[1]).equalTo('b'); + assert(json.args[2]).equalTo('c'); + assert(json.args[3]).equalTo(1); + assert(json.args[4]).equalTo(2); + assert(json.args[5]).equalTo(3); + }); + }); + + describe('addExtensions', function() { + it('takes var_args', function() { + var options = new chrome.Options(); + assert(options.extensions_.length).equalTo(0); + + options.addExtensions('a', 'b'); + assert(options.extensions_.length).equalTo(2); + assert(options.extensions_[0]).equalTo('a'); + assert(options.extensions_[1]).equalTo('b'); + }); + + it('flattens input arrays', function() { + var options = new chrome.Options(); + assert(options.extensions_.length).equalTo(0); + + options.addExtensions(['a', 'b'], 'c', [1, 2], 3); + assert(options.extensions_.length).equalTo(6); + assert(options.extensions_[0]).equalTo('a'); + assert(options.extensions_[1]).equalTo('b'); + assert(options.extensions_[2]).equalTo('c'); + assert(options.extensions_[3]).equalTo(1); + assert(options.extensions_[4]).equalTo(2); + assert(options.extensions_[5]).equalTo(3); + }); + }); + + describe('serialize', function() { + it('base64 encodes extensions', function() { + var expected = fs.readFileSync(__filename, 'base64'); + var wire = new chrome.Options() + .addExtensions(__filename) + [symbols.serialize](); + assert(wire.extensions.length).equalTo(1); + assert(wire.extensions[0]).equalTo(expected); + }); + }); + + describe('toCapabilities', function() { + it('returns a new capabilities object if one is not provided', function() { + var options = new chrome.Options(); + var caps = options.toCapabilities(); + assert(caps.get('browserName')).equalTo('chrome'); + assert(caps.get('chromeOptions')).equalTo(options); + }); + + it('adds to input capabilities object', function() { + var caps = webdriver.Capabilities.firefox(); + var options = new chrome.Options(); + assert(options.toCapabilities(caps)).equalTo(caps); + assert(caps.get('browserName')).equalTo('firefox'); + assert(caps.get('chromeOptions')).equalTo(options); + }); + + it('sets generic driver capabilities', function() { + var proxyPrefs = {}; + var loggingPrefs = {}; + var options = new chrome.Options(). + setLoggingPrefs(loggingPrefs). + setProxy(proxyPrefs); + + var caps = options.toCapabilities(); + assert(caps.get('proxy')).equalTo(proxyPrefs); + assert(caps.get('loggingPrefs')).equalTo(loggingPrefs); + }); + }); +}); + +test.suite(function(env) { + var driver; + + test.afterEach(function() { + driver.quit(); + }); + + describe('Chrome options', function() { + test.it('can start Chrome with custom args', function() { + var options = new chrome.Options(). + addArguments('user-agent=foo;bar'); + + driver = env.builder(). + setChromeOptions(options). + build(); + + driver.get(test.Pages.ajaxyPage); + + var userAgent = driver.executeScript( + 'return window.navigator.userAgent'); + assert(userAgent).equalTo('foo;bar'); + }); + }); +}, {browsers: ['chrome']}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/chrome/service_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/chrome/service_test.js new file mode 100644 index 0000000..0e0209e --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/chrome/service_test.js @@ -0,0 +1,45 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var webdriver = require('../..'), + chrome = require('../../chrome'), + assert = require('../../testing/assert'); + +var test = require('../../lib/test'); + + +test.suite(function(env) { + describe('chromedriver', function() { + var service; + test.afterEach(function() { + if (service) { + return service.kill(); + } + }); + + test.it('can be started on a custom path', function() { + service = new chrome.ServiceBuilder() + .setUrlBasePath('/foo/bar/baz') + .build(); + return service.start().then(function(url) { + assert(url).endsWith('/foo/bar/baz'); + }); + }); + }); +}, {browsers: ['chrome']}); \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/cookie_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/cookie_test.js new file mode 100644 index 0000000..fe4c839 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/cookie_test.js @@ -0,0 +1,206 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'), + url = require('url'); + +var test = require('../lib/test'), + fileserver = require('../lib/test/fileserver'), + Browser = require('..').Browser, + Pages = test.Pages; + + +test.suite(function(env) { + var driver; + + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + test.ignore(env.browsers(Browser.SAFARI)). // Cookie handling is broken. + describe('Cookie Management;', function() { + + test.beforeEach(function() { + driver.get(fileserver.Pages.ajaxyPage); + driver.manage().deleteAllCookies(); + assertHasCookies(); + }); + + test.it('can add new cookies', function() { + var cookie = createCookieSpec(); + + driver.manage().addCookie(cookie.name, cookie.value); + driver.manage().getCookie(cookie.name).then(function(actual) { + assert.equal(actual.value, cookie.value); + }); + }); + + test.it('can get all cookies', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.manage().addCookie(cookie1.name, cookie1.value); + driver.manage().addCookie(cookie2.name, cookie2.value); + + assertHasCookies(cookie1, cookie2); + }); + + test.ignore(env.browsers(Browser.IE)). + it('only returns cookies visible to the current page', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.manage().addCookie(cookie1.name, cookie1.value); + + var pageUrl = fileserver.whereIs('page/1'); + driver.get(pageUrl); + driver.manage().addCookie( + cookie2.name, cookie2.value, url.parse(pageUrl).pathname); + assertHasCookies(cookie1, cookie2); + + driver.get(fileserver.Pages.ajaxyPage); + assertHasCookies(cookie1); + + driver.get(pageUrl); + assertHasCookies(cookie1, cookie2); + }); + + test.it('can delete all cookies', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.executeScript( + 'document.cookie = arguments[0] + "=" + arguments[1];' + + 'document.cookie = arguments[2] + "=" + arguments[3];', + cookie1.name, cookie1.value, cookie2.name, cookie2.value); + assertHasCookies(cookie1, cookie2); + + driver.manage().deleteAllCookies(); + assertHasCookies(); + }); + + test.it('can delete cookies by name', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.executeScript( + 'document.cookie = arguments[0] + "=" + arguments[1];' + + 'document.cookie = arguments[2] + "=" + arguments[3];', + cookie1.name, cookie1.value, cookie2.name, cookie2.value); + assertHasCookies(cookie1, cookie2); + + driver.manage().deleteCookie(cookie1.name); + assertHasCookies(cookie2); + }); + + test.it('should only delete cookie with exact name', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + var cookie3 = {name: cookie1.name + 'xx', value: cookie1.value}; + + driver.executeScript( + 'document.cookie = arguments[0] + "=" + arguments[1];' + + 'document.cookie = arguments[2] + "=" + arguments[3];' + + 'document.cookie = arguments[4] + "=" + arguments[5];', + cookie1.name, cookie1.value, cookie2.name, cookie2.value, + cookie3.name, cookie3.value); + assertHasCookies(cookie1, cookie2, cookie3); + + driver.manage().deleteCookie(cookie1.name); + assertHasCookies(cookie2, cookie3); + }); + + test.it('can delete cookies set higher in the path', function() { + var cookie = createCookieSpec(); + var childUrl = fileserver.whereIs('child/childPage.html'); + var grandchildUrl = fileserver.whereIs( + 'child/grandchild/grandchildPage.html'); + + driver.get(childUrl); + driver.manage().addCookie(cookie.name, cookie.value); + assertHasCookies(cookie); + + driver.get(grandchildUrl); + assertHasCookies(cookie); + + driver.manage().deleteCookie(cookie.name); + assertHasCookies(); + + driver.get(childUrl); + assertHasCookies(); + }); + + test.ignore(env.browsers(Browser.ANDROID, Browser.FIREFOX, Browser.IE)). + it('should retain cookie expiry', function() { + var cookie = createCookieSpec(); + var expirationDelay = 5 * 1000; + var futureTime = Date.now() + expirationDelay; + + driver.manage().addCookie( + cookie.name, cookie.value, null, null, false, futureTime); + driver.manage().getCookie(cookie.name).then(function(actual) { + assert.equal(actual.value, cookie.value); + // expiry times are exchanged in seconds since January 1, 1970 UTC. + assert.equal(actual.expiry, Math.floor(futureTime / 1000)); + }); + + driver.sleep(expirationDelay); + assertHasCookies(); + }); + }); + + function createCookieSpec() { + return { + name: getRandomString(), + value: getRandomString() + }; + } + + function buildCookieMap(cookies) { + var map = {}; + cookies.forEach(function(cookie) { + map[cookie.name] = cookie; + }); + return map; + } + + function assertHasCookies(var_args) { + var expected = Array.prototype.slice.call(arguments, 0); + driver.manage().getCookies().then(function(cookies) { + assert.equal(cookies.length, expected.length, + 'Wrong # of cookies.' + + '\n Expected: ' + JSON.stringify(expected) + + '\n Was : ' + JSON.stringify(cookies)); + + var map = buildCookieMap(cookies); + for (var i = 0; i < expected.length; ++i) { + assert.equal(expected[i].value, map[expected[i].name].value); + } + }); + } + + function getRandomString() { + var x = 1234567890; + return Math.floor(Math.random() * x).toString(36); + } +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/element_finding_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/element_finding_test.js new file mode 100644 index 0000000..3d56b54 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/element_finding_test.js @@ -0,0 +1,392 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fail = require('assert').fail; + +var Browser = require('..').Browser, + By = require('..').By, + error = require('..').error, + until = require('..').until, + promise = require('../lib/promise'), + test = require('../lib/test'), + assert = require('../testing/assert'), + Pages = test.Pages; + + +test.suite(function(env) { + var browsers = env.browsers; + + var driver; + + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + describe('finding elements', function() { + test.it( + 'should work after loading multiple pages in a row', + function() { + driver.get(Pages.formPage); + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.linkText('click me')).click(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + }); + + describe('By.id()', function() { + test.it('should work', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.id('linkId')).click(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + }); + + test.it('should fail if ID not present on page', function() { + driver.get(Pages.formPage); + driver.findElement(By.id('nonExistantButton')). + then(fail, function(e) { + assert(e).instanceOf(error.NoSuchElementError); + }); + }); + + test.it( + 'should find multiple elements by ID even though that is ' + + 'malformed HTML', + function() { + driver.get(Pages.nestedPage); + driver.findElements(By.id('2')).then(function(elements) { + assert(elements.length).equalTo(8); + }); + }); + }); + + describe('By.linkText()', function() { + test.it('should be able to click on link identified by text', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.linkText('click me')).click(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + }); + + test.it( + 'should be able to find elements by partial link text', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.partialLinkText('ick me')).click(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + }); + + test.it('should work when link text contains equals sign', function() { + driver.get(Pages.xhtmlTestPage); + var id = driver.findElement(By.linkText('Link=equalssign')). + getAttribute('id'); + assert(id).equalTo('linkWithEqualsSign'); + }); + + test.it('matches by partial text when containing equals sign', + function() { + driver.get(Pages.xhtmlTestPage); + var id = driver.findElement(By.partialLinkText('Link=')). + getAttribute('id'); + assert(id).equalTo('linkWithEqualsSign'); + }); + + test.it('works when searching for multiple and text contains =', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.linkText('Link=equalssign')). + then(function(elements) { + assert(elements.length).equalTo(1); + return elements[0].getAttribute('id'); + }). + then(function(id) { + assert(id).equalTo('linkWithEqualsSign'); + }); + }); + + test.it( + 'works when searching for multiple with partial text containing =', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.partialLinkText('Link=')). + then(function(elements) { + assert(elements.length).equalTo(1); + return elements[0].getAttribute('id'); + }). + then(function(id) { + assert(id).equalTo('linkWithEqualsSign'); + }); + }); + + test.it('should be able to find multiple exact matches', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.linkText('click me')). + then(function(elements) { + assert(elements.length).equalTo(2); + }); + }); + + test.it('should be able to find multiple partial matches', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.partialLinkText('ick me')). + then(function(elements) { + assert(elements.length).equalTo(2); + }); + }); + + test.it('works on XHTML pages', function() { + driver.get(test.whereIs('actualXhtmlPage.xhtml')); + + var el = driver.findElement(By.linkText('Foo')); + assert(el.getText()).equalTo('Foo'); + }); + }); + + describe('By.name()', function() { + test.it('should work', function() { + driver.get(Pages.formPage); + + var el = driver.findElement(By.name('checky')); + assert(el.getAttribute('value')).equalTo('furrfu'); + }); + + test.it('should find multiple elements with same name', function() { + driver.get(Pages.nestedPage); + driver.findElements(By.name('checky')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + + test.it( + 'should be able to find elements that do not support name property', + function() { + driver.get(Pages.nestedPage); + driver.findElement(By.name('div1')); + // Pass if this does not return an error. + }); + + test.it('shoudl be able to find hidden elements by name', function() { + driver.get(Pages.formPage); + driver.findElement(By.name('hidden')); + // Pass if this does not return an error. + }); + }); + + describe('By.className()', function() { + test.it('should work', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('extraDiv')); + assert(el.getText()).startsWith('Another div starts here.'); + }); + + test.it('should work when name is first name among many', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('nameA')); + assert(el.getText()).equalTo('An H2 title'); + }); + + test.it('should work when name is last name among many', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('nameC')); + assert(el.getText()).equalTo('An H2 title'); + }); + + test.it('should work when name is middle of many', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('nameBnoise')); + assert(el.getText()).equalTo('An H2 title'); + }); + + test.it('should work when name surrounded by whitespace', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('spaceAround')); + assert(el.getText()).equalTo('Spaced out'); + }); + + test.it('should fail if queried name only partially matches', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.className('nameB')). + then(fail, function(e) { + assert(e).instanceOf(error.NoSuchElementError); + }); + }); + + test.it('should be able to find multiple matches', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.className('nameC')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + + test.it('permits compound class names', function() { + return driver.get(Pages.xhtmlTestPage) + .then(() => driver.findElement(By.className('nameA nameC'))) + .then(el => el.getText()) + .then(text => assert(text).equalTo('An H2 title')); + }); + }); + + describe('By.xpath()', function() { + test.it('should work with multiple matches', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.xpath('//div')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + + test.it('should work for selectors using contains keyword', function() { + driver.get(Pages.nestedPage); + driver.findElement(By.xpath('//a[contains(., "hello world")]')); + // Pass if no error. + }); + }); + + describe('By.tagName()', function() { + test.it('works', function() { + driver.get(Pages.formPage); + + var el = driver.findElement(By.tagName('input')); + assert(el.getTagName()).equalTo('input'); + }); + + test.it('can find multiple elements', function() { + driver.get(Pages.formPage); + driver.findElements(By.tagName('input')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + }); + + describe('By.css()', function() { + test.it('works', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.css('div.content')); + // Pass if no error. + }); + + test.it('can find multiple elements', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.css('p')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + // Pass if no error. + }); + + test.it( + 'should find first matching element when searching by ' + + 'compound CSS selector', + function() { + driver.get(Pages.xhtmlTestPage); + var el = driver.findElement(By.css('div.extraDiv, div.content')); + assert(el.getAttribute('class')).equalTo('content'); + }); + + test.it('should be able to find multiple elements by compound selector', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.css('div.extraDiv, div.content')). + then(function(elements) { + assertClassIs(elements[0], 'content'); + assertClassIs(elements[1], 'extraDiv'); + + function assertClassIs(el, expected) { + assert(el.getAttribute('class')).equalTo(expected); + } + }); + }); + + // IE only supports short version option[selected]. + test.ignore(browsers(Browser.IE)). + it('should be able to find element by boolean attribute', function() { + driver.get(test.whereIs( + 'locators_tests/boolean_attribute_selected.html')); + + var el = driver.findElement(By.css('option[selected="selected"]')); + assert(el.getAttribute('value')).equalTo('two'); + }); + + test.it( + 'should be able to find element with short ' + + 'boolean attribute selector', + function() { + driver.get(test.whereIs( + 'locators_tests/boolean_attribute_selected.html')); + + var el = driver.findElement(By.css('option[selected]')); + assert(el.getAttribute('value')).equalTo('two'); + }); + + test.it( + 'should be able to find element with short boolean attribute ' + + 'selector on HTML4 page', + function() { + driver.get(test.whereIs( + 'locators_tests/boolean_attribute_selected_html4.html')); + + var el = driver.findElement(By.css('option[selected]')); + assert(el.getAttribute('value')).equalTo('two'); + }); + }); + + describe('by custom locator', function() { + test.it('handles single element result', function() { + driver.get(Pages.javascriptPage); + + let link = driver.findElement(function(driver) { + let links = driver.findElements(By.tagName('a')); + return promise.filter(links, function(link) { + return link.getAttribute('id').then(id => id === 'updatediv'); + }).then(links => links[0]); + }); + + assert(link.getText()).isEqualTo('Update a div'); + }); + + test.it('uses first element if locator resolves to list', function() { + driver.get(Pages.javascriptPage); + + let link = driver.findElement(function() { + return driver.findElements(By.tagName('a')); + }); + + assert(link.getText()).isEqualTo('Change the page title!'); + }); + + test.it('fails if locator returns non-webelement value', function() { + driver.get(Pages.javascriptPage); + + let link = driver.findElement(function() { + return driver.getTitle(); + }); + + return link.then( + () => fail('Should have failed'), + (e) => assert(e).instanceOf(TypeError)); + }); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/error_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/error_test.js new file mode 100644 index 0000000..c80423e --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/error_test.js @@ -0,0 +1,163 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +describe('error', function() { + let assert = require('assert'); + let error = require('../error'); + + describe('checkResponse', function() { + it('defaults to WebDriverError if type is unrecognized', function() { + assert.throws( + () => error.checkResponse({error: 'foo', message: 'hi there'}), + (e) => { + assert.equal(e.constructor, error.WebDriverError); + assert.equal(e.code, error.ErrorCode.UNKNOWN_ERROR); + return true; + }); + }); + + it('does not throw if error property is not a string', function() { + let resp = {error: 123, message: 'abc123'}; + let out = error.checkResponse(resp); + assert.strictEqual(out, resp); + }); + + test('unknown error', error.WebDriverError); + test('element not selectable', error.ElementNotSelectableError); + test('element not visible', error.ElementNotVisibleError); + test('invalid argument', error.InvalidArgumentError); + test('invalid cookie domain', error.InvalidCookieDomainError); + test('invalid element coordinates', error.InvalidElementCoordinatesError); + test('invalid element state', error.InvalidElementStateError); + test('invalid selector', error.InvalidSelectorError); + test('invalid session id', error.InvalidSessionIdError); + test('javascript error', error.JavascriptError); + test('move target out of bounds', error.MoveTargetOutOfBoundsError); + test('no such alert', error.NoSuchAlertError); + test('no such element', error.NoSuchElementError); + test('no such frame', error.NoSuchFrameError); + test('no such window', error.NoSuchWindowError); + test('script timeout', error.ScriptTimeoutError); + test('session not created', error.SessionNotCreatedError); + test('stale element reference', error.StaleElementReferenceError); + test('timeout', error.TimeoutError); + test('unable to set cookie', error.UnableToSetCookieError); + test('unable to capture screen', error.UnableToCaptureScreenError); + test('unexpected alert open', error.UnexpectedAlertOpenError); + test('unknown command', error.UnknownCommandError); + test('unknown method', error.UnknownMethodError); + test('unsupported operation', error.UnsupportedOperationError); + + function test(status, expectedType) { + it(`"${status}" => ${expectedType.name}`, function() { + assert.throws( + () => error.checkResponse({error: status, message: 'oops'}), + (e) => { + assert.equal(expectedType, e.constructor); + assert.equal(e.message, 'oops'); + return true; + }); + }); + } + }); + + describe('checkLegacyResponse', function() { + it('does not throw for success', function() { + let resp = {status: error.ErrorCode.SUCCESS}; + assert.strictEqual(resp, error.checkLegacyResponse(resp)); + }); + + test('NO_SUCH_ELEMENT', error.NoSuchElementError); + test('NO_SUCH_FRAME', error.NoSuchFrameError); + test('UNKNOWN_COMMAND', error.UnsupportedOperationError); + test('UNSUPPORTED_OPERATION', error.UnsupportedOperationError); + test('STALE_ELEMENT_REFERENCE', error.StaleElementReferenceError); + test('ELEMENT_NOT_VISIBLE', error.ElementNotVisibleError); + test('INVALID_ELEMENT_STATE', error.InvalidElementStateError); + test('UNKNOWN_ERROR', error.WebDriverError); + test('ELEMENT_NOT_SELECTABLE', error.ElementNotSelectableError); + test('JAVASCRIPT_ERROR', error.JavascriptError); + test('XPATH_LOOKUP_ERROR', error.InvalidSelectorError); + test('TIMEOUT', error.TimeoutError); + test('NO_SUCH_WINDOW', error.NoSuchWindowError); + test('INVALID_COOKIE_DOMAIN', error.InvalidCookieDomainError); + test('UNABLE_TO_SET_COOKIE', error.UnableToSetCookieError); + test('UNEXPECTED_ALERT_OPEN', error.UnexpectedAlertOpenError); + test('NO_SUCH_ALERT', error.NoSuchAlertError); + test('SCRIPT_TIMEOUT', error.ScriptTimeoutError); + test('INVALID_ELEMENT_COORDINATES', error.InvalidElementCoordinatesError); + test('INVALID_SELECTOR_ERROR', error.InvalidSelectorError); + test('SESSION_NOT_CREATED', error.SessionNotCreatedError); + test('MOVE_TARGET_OUT_OF_BOUNDS', error.MoveTargetOutOfBoundsError); + test('INVALID_XPATH_SELECTOR', error.InvalidSelectorError); + test('INVALID_XPATH_SELECTOR_RETURN_TYPE', error.InvalidSelectorError); + test('METHOD_NOT_ALLOWED', error.UnsupportedOperationError); + + function test(codeKey, expectedType) { + it(`${codeKey} => ${expectedType.name}`, function() { + let code = error.ErrorCode[codeKey]; + let resp = {status: code, value: {message: 'hi'}}; + assert.throws( + () => error.checkLegacyResponse(resp), + (e) => { + assert.equal(expectedType, e.constructor); + assert.equal(e.message, 'hi'); + return true; + }); + }); + } + }); + + describe('WebDriverError types provide a legacy error code', function() { + check(error.WebDriverError, 'UNKNOWN_ERROR'); + check(error.ElementNotSelectableError, 'ELEMENT_NOT_SELECTABLE'); + check(error.ElementNotVisibleError, 'ELEMENT_NOT_VISIBLE'); + check(error.InvalidArgumentError, 'UNKNOWN_ERROR'); + check(error.InvalidCookieDomainError, 'INVALID_COOKIE_DOMAIN'); + check(error.InvalidElementCoordinatesError, 'INVALID_ELEMENT_COORDINATES'); + check(error.InvalidElementStateError, 'INVALID_ELEMENT_STATE'); + check(error.InvalidSelectorError, 'INVALID_SELECTOR_ERROR'); + check(error.InvalidSessionIdError, 'UNKNOWN_ERROR'); + check(error.JavascriptError, 'JAVASCRIPT_ERROR'); + check(error.MoveTargetOutOfBoundsError, 'MOVE_TARGET_OUT_OF_BOUNDS'); + check(error.NoSuchAlertError, 'NO_SUCH_ALERT'); + check(error.NoSuchElementError, 'NO_SUCH_ELEMENT'); + check(error.NoSuchFrameError, 'NO_SUCH_FRAME'); + check(error.NoSuchWindowError, 'NO_SUCH_WINDOW'); + check(error.ScriptTimeoutError, 'SCRIPT_TIMEOUT'); + check(error.SessionNotCreatedError, 'SESSION_NOT_CREATED'); + check(error.StaleElementReferenceError, 'STALE_ELEMENT_REFERENCE'); + check(error.TimeoutError, 'TIMEOUT'); + check(error.UnableToSetCookieError, 'UNABLE_TO_SET_COOKIE'); + check(error.UnableToCaptureScreenError, 'UNKNOWN_ERROR'); + check(error.UnexpectedAlertOpenError, 'UNEXPECTED_ALERT_OPEN'); + check(error.UnknownCommandError, 'UNKNOWN_COMMAND'); + check(error.UnknownMethodError, 'UNSUPPORTED_OPERATION'); + check(error.UnsupportedOperationError, 'UNSUPPORTED_OPERATION'); + + function check(ctor, codeKey) { + it(`${ctor.name} => ${codeKey}`, function() { + let code = error.ErrorCode[codeKey]; + let e = new ctor(); + assert.equal(typeof e.code, 'number'); + assert.equal(e.code, code); + }); + } + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/execute_script_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/execute_script_test.js new file mode 100644 index 0000000..8d3b099 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/execute_script_test.js @@ -0,0 +1,322 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var path = require('path'); + +var webdriver = require('..'), + Browser = webdriver.Browser, + By = webdriver.By, + assert = require('../testing/assert'), + test = require('../lib/test'); + + +test.suite(function(env) { + var driver; + + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + test.beforeEach(function() { + driver.get(test.Pages.echoPage); + }); + + describe('executeScript;', function() { + var shouldHaveFailed = new Error('Should have failed'); + + test.it('fails if script throws', function() { + execute('throw new Error("boom")') + .then(function() { throw shoudlHaveFailed; }) + .thenCatch(function(e) { + // The java WebDriver server adds a bunch of crap to error messages. + // Error message will just be "JavaScript error" for IE. + assert(e.message).matches(/.*(JavaScript error|boom).*/); + }); + }); + + test.it('fails if script does not parse', function() { + execute('throw function\\*') + .then(function() { throw shoudlHaveFailed; }) + .thenCatch(function(e) { + assert(e).notEqualTo(shouldHaveFailed); + }); + }); + + describe('scripts;', function() { + test.it('do not pollute the global scope', function() { + execute('var x = 1;'); + assert(execute('return typeof x;')).equalTo('undefined'); + }); + + test.it('can set global variables', function() { + execute('window.x = 1234;'); + assert(execute('return x;')).equalTo(1234); + }); + + test.it('may be defined as a function expression', function() { + assert(execute(function() { + return 1234 + 'abc'; + })).equalTo('1234abc'); + }); + }); + + describe('return values;', function() { + + test.it('returns undefined as null', function() { + assert(execute('var x; return x;')).isNull(); + }); + + test.it('can return null', function() { + assert(execute('return null;')).isNull(); + }); + + test.it('can return numbers', function() { + assert(execute('return 1234')).equalTo(1234); + assert(execute('return 3.1456')).equalTo(3.1456); + }); + + test.it('can return strings', function() { + assert(execute('return "hello"')).equalTo('hello'); + }); + + test.it('can return booleans', function() { + assert(execute('return true')).equalTo(true); + assert(execute('return false')).equalTo(false); + }); + + test.it('can return an array of primitives', function() { + execute('var x; return [1, false, null, 3.14, x]') + .then(verifyJson([1, false, null, 3.14, null])); + }); + + test.it('can return nested arrays', function() { + execute('return [[1, 2, [3]]]') + .then(verifyJson([[1, 2, [3]]])); + }); + + test.ignore(env.browsers(Browser.IE, Browser.SAFARI)). + it('can return empty object literal', function() { + execute('return {}').then(verifyJson({})); + }); + + test.it('can return object literals', function() { + execute('return {a: 1, b: false, c: null}').then(function(result) { + verifyJson(['a', 'b', 'c'])(Object.keys(result).sort()); + assert(result.a).equalTo(1); + assert(result.b).equalTo(false); + assert(result.c).isNull(); + }); + }); + + test.it('can return complex object literals', function() { + execute('return {a:{b: "hello"}}').then(verifyJson({a:{b: 'hello'}})); + }); + + test.it('can return dom elements as web elements', function() { + execute('return document.querySelector(".header.host")') + .then(function(result) { + assert(result).instanceOf(webdriver.WebElement); + assert(result.getText()).startsWith('host: '); + }); + }); + + test.it('can return array of dom elements', function() { + execute('var nodes = document.querySelectorAll(".request,.host");' + + 'return [nodes[0], nodes[1]];') + .then(function(result) { + assert(result.length).equalTo(2); + + assert(result[0]).instanceOf(webdriver.WebElement); + assert(result[0].getText()).startsWith('GET '); + + assert(result[1]).instanceOf(webdriver.WebElement); + assert(result[1].getText()).startsWith('host: '); + }); + }); + + test.it('can return a NodeList as an array of web elements', function() { + execute('return document.querySelectorAll(".request,.host");') + .then(function(result) { + assert(result.length).equalTo(2); + + assert(result[0]).instanceOf(webdriver.WebElement); + assert(result[0].getText()).startsWith('GET '); + + assert(result[1]).instanceOf(webdriver.WebElement); + assert(result[1].getText()).startsWith('host: '); + }); + }); + + test.it('can return object literal with element property', function() { + execute('return {a: document.body}').then(function(result) { + assert(result.a).instanceOf(webdriver.WebElement); + assert(result.a.getTagName()).equalTo('body'); + }); + }); + }); + + describe('parameters;', function() { + test.it('can pass numeric arguments', function() { + assert(execute('return arguments[0]', 12)).equalTo(12); + assert(execute('return arguments[0]', 3.14)).equalTo(3.14); + }); + + test.it('can pass boolean arguments', function() { + assert(execute('return arguments[0]', true)).equalTo(true); + assert(execute('return arguments[0]', false)).equalTo(false); + }); + + test.it('can pass string arguments', function() { + assert(execute('return arguments[0]', 'hi')).equalTo('hi'); + }); + + test.it('can pass null arguments', function() { + assert(execute('return arguments[0] === null', null)).equalTo(true); + assert(execute('return arguments[0]', null)).equalTo(null); + }); + + test.it('passes undefined as a null argument', function() { + var x; + assert(execute('return arguments[0] === null', x)).equalTo(true); + assert(execute('return arguments[0]', x)).equalTo(null); + }); + + test.it('can pass multiple arguments', function() { + assert(execute('return arguments.length')).equalTo(0); + assert(execute('return arguments.length', 1, 'a', false)).equalTo(3); + }); + + test.it('can return arguments object as array', function() { + execute('return arguments', 1, 'a', false).then(function(val) { + assert(val.length).equalTo(3); + assert(val[0]).equalTo(1); + assert(val[1]).equalTo('a'); + assert(val[2]).equalTo(false); + }); + }); + + test.it('can pass object literal', function() { + execute( + 'return [typeof arguments[0], arguments[0].a]', {a: 'hello'}) + .then(function(result) { + assert(result[0]).equalTo('object'); + assert(result[1]).equalTo('hello'); + }); + }); + + test.it('WebElement arguments are passed as DOM elements', function() { + var el = driver.findElement(By.tagName('div')); + assert(execute('return arguments[0].tagName.toLowerCase();', el)) + .equalTo('div'); + }); + + test.it('can pass array containing object literals', function() { + execute('return arguments[0]', [{color: "red"}]).then(function(result) { + assert(result.length).equalTo(1); + assert(result[0].color).equalTo('red'); + }); + }); + + test.it('does not modify object literal parameters', function() { + var input = {color: 'red'}; + execute('return arguments[0];', input).then(verifyJson(input)); + }); + }); + + // See https://code.google.com/p/selenium/issues/detail?id=8223. + describe('issue 8223;', function() { + describe('using for..in loops;', function() { + test.it('can return array built from for-loop index', function() { + execute(function() { + var ret = []; + for (var i = 0; i < 3; i++) { + ret.push(i); + } + return ret; + }).then(verifyJson[0, 1, 2]); + }); + + test.it('can copy input array contents', function() { + execute(function(input) { + var ret = []; + for (var i in input) { + ret.push(input[i]); + } + return ret; + }, ['fa', 'fe', 'fi']).then(verifyJson(['fa', 'fe', 'fi'])); + }); + + test.it('can iterate over input object keys', function() { + execute(function(thing) { + var ret = []; + for (var w in thing.words) { + ret.push(thing.words[w].word); + } + return ret; + }, {words: [{word: 'fa'}, {word: 'fe'}, {word: 'fi'}]}) + .then(verifyJson(['fa', 'fe', 'fi'])); + }); + + describe('recursive functions;', function() { + test.it('can build array from input', function() { + var input = ['fa', 'fe', 'fi']; + execute(function(thearray) { + var ret = []; + function build_response(thearray, ret) { + ret.push(thearray.shift()); + return (!thearray.length && ret + || build_response(thearray, ret)); + } + return build_response(thearray, ret); + }, input).then(verifyJson(input)); + }); + + test.it('can build array from elements in object', function() { + var input = {words: [{word: 'fa'}, {word: 'fe'}, {word: 'fi'}]}; + execute(function(thing) { + var ret = []; + function build_response(thing, ret) { + var item = thing.words.shift(); + ret.push(item.word); + return (!thing.words.length && ret + || build_response(thing, ret)); + } + return build_response(thing, ret); + }, input).then(verifyJson(['fa', 'fe', 'fi'])); + }); + }); + }); + }); + + }); + + function verifyJson(expected) { + return function(actual) { + assert(JSON.stringify(actual)).equalTo(JSON.stringify(expected)); + }; + } + + function execute() { + return driver.executeScript.apply(driver, arguments); + } +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/fingerprint_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/fingerprint_test.js new file mode 100644 index 0000000..5a64494 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/fingerprint_test.js @@ -0,0 +1,57 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('../testing/assert'), + test = require('../lib/test'), + Pages = test.Pages; + + +test.suite(function(env) { + var browsers = env.browsers; + + var driver; + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + describe('fingerprinting', function() { + test.it('it should fingerprint the navigator object', function() { + driver.get(Pages.simpleTestPage); + assert(driver.executeScript('return navigator.webdriver')).equalTo(true); + }); + + test.it('fingerprint must not be writable', function() { + driver.get(Pages.simpleTestPage); + assert(driver.executeScript( + 'navigator.webdriver = "ohai"; return navigator.webdriver')) + .equalTo(true); + }); + + test.it('leaves fingerprint on svg pages', function() { + driver.get(Pages.svgPage); + assert(driver.executeScript('return navigator.webdriver')).equalTo(true); + }); + }); + +// Currently only implemented in firefox. +}, {browsers: ['firefox']}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/firefox/extension_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/firefox/extension_test.js new file mode 100644 index 0000000..50936f7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/firefox/extension_test.js @@ -0,0 +1,96 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var AdmZip = require('adm-zip'), + assert = require('assert'), + crypto = require('crypto'), + fs = require('fs'), + path = require('path'); + +var extension = require('../../firefox/extension'), + io = require('../../io'), + it = require('../../testing').it; + + +var JETPACK_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/jetpack-sample.xpi'); +var NORMAL_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/sample.xpi'); + +var JETPACK_EXTENSION_ID = 'jid1-EaXX7k0wwiZR7w@jetpack'; +var NORMAL_EXTENSION_ID = 'sample@seleniumhq.org'; + + +describe('extension', function() { + it('can install a jetpack xpi file', function() { + return io.tmpDir().then(function(dir) { + return extension.install(JETPACK_EXTENSION, dir).then(function(id) { + assert.equal(JETPACK_EXTENSION_ID, id); + var file = path.join(dir, id + '.xpi'); + assert.ok(fs.existsSync(file), 'no such file: ' + file); + assert.ok(!fs.statSync(file).isDirectory()); + + var copiedSha1 = crypto.createHash('sha1') + .update(fs.readFileSync(file)) + .digest('hex'); + + var goldenSha1 = crypto.createHash('sha1') + .update(fs.readFileSync(JETPACK_EXTENSION)) + .digest('hex'); + + assert.equal(copiedSha1, goldenSha1); + }); + }); + }); + + it('can install a normal xpi file', function() { + return io.tmpDir().then(function(dir) { + return extension.install(NORMAL_EXTENSION, dir).then(function(id) { + assert.equal(NORMAL_EXTENSION_ID, id); + + var file = path.join(dir, NORMAL_EXTENSION_ID); + assert.ok(fs.statSync(file).isDirectory()); + + assert.ok(fs.existsSync(path.join(file, 'chrome.manifest'))); + assert.ok(fs.existsSync(path.join(file, 'content/overlay.xul'))); + assert.ok(fs.existsSync(path.join(file, 'content/overlay.js'))); + assert.ok(fs.existsSync(path.join(file, 'install.rdf'))); + }); + }); + }); + + it('can install an extension from a directory', function() { + return io.tmpDir().then(function(srcDir) { + var buf = fs.readFileSync(NORMAL_EXTENSION); + new AdmZip(buf).extractAllTo(srcDir, true); + return io.tmpDir().then(function(dstDir) { + return extension.install(srcDir, dstDir).then(function(id) { + assert.equal(NORMAL_EXTENSION_ID, id); + + var dir = path.join(dstDir, NORMAL_EXTENSION_ID); + + assert.ok(fs.existsSync(path.join(dir, 'chrome.manifest'))); + assert.ok(fs.existsSync(path.join(dir, 'content/overlay.xul'))); + assert.ok(fs.existsSync(path.join(dir, 'content/overlay.js'))); + assert.ok(fs.existsSync(path.join(dir, 'install.rdf'))); + }); + }); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/firefox/firefox_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/firefox/firefox_test.js new file mode 100644 index 0000000..0a32940 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/firefox/firefox_test.js @@ -0,0 +1,183 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var path = require('path'); + +var firefox = require('../../firefox'), + io = require('../../io'), + test = require('../../lib/test'), + assert = require('../../testing/assert'); + + +var JETPACK_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/jetpack-sample.xpi'); +var NORMAL_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/sample.xpi'); + + +test.suite(function(env) { + describe('firefox', function() { + describe('Options', function() { + var driver; + + test.beforeEach(function() { + driver = null; + }); + + test.afterEach(function() { + if (driver) { + driver.quit(); + } + }); + + test.it('can start Firefox with custom preferences', function() { + var profile = new firefox.Profile(); + profile.setPreference('general.useragent.override', 'foo;bar'); + + var options = new firefox.Options().setProfile(profile); + + driver = env.builder(). + setFirefoxOptions(options). + build(); + + driver.get('data:text/html,
    content
    '); + + var userAgent = driver.executeScript( + 'return window.navigator.userAgent'); + assert(userAgent).equalTo('foo;bar'); + }); + + test.it('can start Firefox with a jetpack extension', function() { + var profile = new firefox.Profile(); + profile.addExtension(JETPACK_EXTENSION); + + var options = new firefox.Options().setProfile(profile); + + driver = env.builder(). + setFirefoxOptions(options). + build(); + + loadJetpackPage(driver, + 'data:text/html;charset=UTF-8,
    content
    '); + assert(driver.findElement({id: 'jetpack-sample-banner'}).getText()) + .equalTo('Hello, world!'); + }); + + test.it('can start Firefox with a normal extension', function() { + var profile = new firefox.Profile(); + profile.addExtension(NORMAL_EXTENSION); + + var options = new firefox.Options().setProfile(profile); + + driver = env.builder(). + setFirefoxOptions(options). + build(); + + driver.get('data:text/html,
    content
    '); + assert(driver.findElement({id: 'sample-extension-footer'}).getText()) + .equalTo('Goodbye'); + }); + + test.it('can start Firefox with multiple extensions', function() { + var profile = new firefox.Profile(); + profile.addExtension(JETPACK_EXTENSION); + profile.addExtension(NORMAL_EXTENSION); + + var options = new firefox.Options().setProfile(profile); + + driver = env.builder(). + setFirefoxOptions(options). + build(); + + loadJetpackPage(driver, + 'data:text/html;charset=UTF-8,
    content
    '); + assert(driver.findElement({id: 'jetpack-sample-banner'}).getText()) + .equalTo('Hello, world!'); + assert(driver.findElement({id: 'sample-extension-footer'}).getText()) + .equalTo('Goodbye'); + }); + + function loadJetpackPage(driver, url) { + // On linux the jetpack extension does not always run the first time + // we load a page. If this happens, just reload the page (a simple + // refresh doesn't appear to work). + driver.wait(function() { + driver.get(url); + return driver.isElementPresent({id: 'jetpack-sample-banner'}); + }, 3000); + } + }); + + describe('profile management', function() { + var driver; + + test.beforeEach(function() { + driver = null; + }); + + test.afterEach(function() { + if (driver) { + driver.quit(); + } + }); + + test.ignore(env.isRemote). + it('deletes the temp profile on quit', function() { + driver = env.builder().build(); + + var profilePath = driver.call(function() { + var path = driver.profilePath_; + assert(io.exists(path)).isTrue(); + return path; + }); + + return driver.quit().then(function() { + driver = null; + return profilePath; + }).then(function(path) { + assert(io.exists(path)).isFalse(); + }); + }); + }); + + describe('binary management', function() { + var driver1, driver2; + + test.ignore(env.isRemote). + it('can start multiple sessions with single binary instance', function() { + var options = new firefox.Options().setBinary(new firefox.Binary); + env.builder().setFirefoxOptions(options); + driver1 = env.builder().build(); + driver2 = env.builder().build(); + // Ok if this doesn't fail. + }); + + test.afterEach(function() { + if (driver1) { + driver1.quit(); + } + + if (driver2) { + driver2.quit(); + } + }); + }); + + }); +}, {browsers: ['firefox']}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/firefox/profile_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/firefox/profile_test.js new file mode 100644 index 0000000..feaa42f --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/firefox/profile_test.js @@ -0,0 +1,187 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var AdmZip = require('adm-zip'), + assert = require('assert'), + fs = require('fs'), + path = require('path'); + +var promise = require('../..').promise, + Profile = require('../../firefox/profile').Profile, + decode = require('../../firefox/profile').decode, + loadUserPrefs = require('../../firefox/profile').loadUserPrefs, + io = require('../../io'), + it = require('../../testing').it; + + +var JETPACK_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/jetpack-sample.xpi'); +var NORMAL_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/sample.xpi'); + +var JETPACK_EXTENSION_ID = 'jid1-EaXX7k0wwiZR7w@jetpack.xpi'; +var NORMAL_EXTENSION_ID = 'sample@seleniumhq.org'; +var WEBDRIVER_EXTENSION_ID = 'fxdriver@googlecode.com'; + + + +describe('Profile', function() { + describe('setPreference', function() { + it('allows setting custom properties', function() { + var profile = new Profile(); + assert.equal(undefined, profile.getPreference('foo')); + + profile.setPreference('foo', 'bar'); + assert.equal('bar', profile.getPreference('foo')); + }); + + it('allows overriding mutable properties', function() { + var profile = new Profile(); + assert.equal('about:blank', profile.getPreference('browser.newtab.url')); + + profile.setPreference('browser.newtab.url', 'http://www.example.com'); + assert.equal('http://www.example.com', + profile.getPreference('browser.newtab.url')); + }); + + it('throws if setting a frozen preference', function() { + var profile = new Profile(); + assert.throws(function() { + profile.setPreference('app.update.auto', true); + }); + }); + }); + + describe('writeToDisk', function() { + it('copies template directory recursively', function() { + var templateDir; + return io.tmpDir().then(function(td) { + templateDir = td; + var foo = path.join(templateDir, 'foo'); + fs.writeFileSync(foo, 'Hello, world'); + + var bar = path.join(templateDir, 'subfolder/bar'); + fs.mkdirSync(path.dirname(bar)); + fs.writeFileSync(bar, 'Goodbye, world!'); + + return new Profile(templateDir).writeToDisk(); + }).then(function(profileDir) { + assert.notEqual(profileDir, templateDir); + + assert.equal('Hello, world', + fs.readFileSync(path.join(profileDir, 'foo'))); + assert.equal('Goodbye, world!', + fs.readFileSync(path.join(profileDir, 'subfolder/bar'))); + }); + }); + + it('does not copy lock files', function() { + return io.tmpDir().then(function(dir) { + fs.writeFileSync(path.join(dir, 'parent.lock'), 'lock'); + fs.writeFileSync(path.join(dir, 'lock'), 'lock'); + fs.writeFileSync(path.join(dir, '.parentlock'), 'lock'); + return new Profile(dir).writeToDisk(); + }).then(function(dir) { + assert.ok(fs.existsSync(dir)); + assert.ok(!fs.existsSync(path.join(dir, 'parent.lock'))); + assert.ok(!fs.existsSync(path.join(dir, 'lock'))); + assert.ok(!fs.existsSync(path.join(dir, '.parentlock'))); + }); + }); + + describe('user.js', function() { + + it('writes defaults', function() { + return new Profile().writeToDisk().then(function(dir) { + return loadUserPrefs(path.join(dir, 'user.js')); + }).then(function(prefs) { + // Just check a few. + assert.equal(false, prefs['app.update.auto']); + assert.equal(true, prefs['browser.EULA.override']); + assert.equal(false, prefs['extensions.update.enabled']); + assert.equal('about:blank', prefs['browser.newtab.url']); + assert.equal(30, prefs['dom.max_script_run_time']); + }); + }); + + it('merges template user.js into preferences', function() { + return io.tmpDir().then(function(dir) { + fs.writeFileSync(path.join(dir, 'user.js'), [ + 'user_pref("browser.newtab.url", "http://www.example.com")', + 'user_pref("dom.max_script_run_time", 1234)' + ].join('\n')); + + return new Profile(dir).writeToDisk(); + }).then(function(profile) { + return loadUserPrefs(path.join(profile, 'user.js')); + }).then(function(prefs) { + assert.equal('http://www.example.com', prefs['browser.newtab.url']); + assert.equal(1234, prefs['dom.max_script_run_time']); + }); + }); + + it('ignores frozen preferences when merging template user.js', + function() { + return io.tmpDir().then(function(dir) { + fs.writeFileSync(path.join(dir, 'user.js'), + 'user_pref("app.update.auto", true)'); + return new Profile(dir).writeToDisk(); + }).then(function(profile) { + return loadUserPrefs(path.join(profile, 'user.js')); + }).then(function(prefs) { + assert.equal(false, prefs['app.update.auto']); + }); + }); + }); + + describe('extensions', function() { + it('are copied into new profile directory', function() { + var profile = new Profile(); + profile.addExtension(JETPACK_EXTENSION); + profile.addExtension(NORMAL_EXTENSION); + + return profile.writeToDisk().then(function(dir) { + dir = path.join(dir, 'extensions'); + assert.ok(fs.existsSync(path.join(dir, JETPACK_EXTENSION_ID))); + assert.ok(fs.existsSync(path.join(dir, NORMAL_EXTENSION_ID))); + assert.ok(fs.existsSync(path.join(dir, WEBDRIVER_EXTENSION_ID))); + }); + }); + }); + }); + + describe('encode', function() { + it('excludes the bundled WebDriver extension', function() { + return new Profile().encode().then(function(data) { + return decode(data); + }).then(function(dir) { + assert.ok(fs.existsSync(path.join(dir, 'user.js'))); + assert.ok(fs.existsSync(path.join(dir, 'extensions'))); + return loadUserPrefs(path.join(dir, 'user.js')); + }).then(function(prefs) { + // Just check a few. + assert.equal(false, prefs['app.update.auto']); + assert.equal(true, prefs['browser.EULA.override']); + assert.equal(false, prefs['extensions.update.enabled']); + assert.equal('about:blank', prefs['browser.newtab.url']); + assert.equal(30, prefs['dom.max_script_run_time']); + }); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/http/http_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/http/http_test.js new file mode 100644 index 0000000..b121f85 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/http/http_test.js @@ -0,0 +1,443 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'); +var http = require('http'); +var sinon = require('sinon'); +var url = require('url'); + +var error = require('../../error'); +var Executor = require('../../http').Executor; +var HttpClient = require('../../http').HttpClient; +var HttpRequest = require('../../http').Request; +var HttpResponse = require('../../http').Response; +var buildPath = require('../../http').buildPath; +var Command = require('../../lib/command').Command; +var CommandName = require('../../lib/command').Name; +var Server = require('../../lib/test/httpserver').Server; +var promise = require('../..').promise; + +describe('buildPath', function() { + it('properly replaces path segments with command parameters', function() { + var parameters = {'sessionId':'foo', 'url':'http://www.google.com'}; + var finalPath = buildPath('/session/:sessionId/url', parameters); + assert.equal(finalPath, '/session/foo/url'); + assert.deepEqual(parameters, {'url':'http://www.google.com'}); + }); + + it('handles web element references', function() { + var parameters = {'sessionId':'foo', 'id': {}}; + parameters['id']['ELEMENT'] = 'bar'; + + var finalPath = buildPath( + '/session/:sessionId/element/:id/click', parameters); + assert.equal(finalPath, '/session/foo/element/bar/click'); + assert.deepEqual(parameters, {}); + }); + + it('throws if missing a parameter', function() { + assert.throws( + () => buildPath('/session/:sessionId', {}), + function(err) { + return err instanceof error.InvalidArgumentError + && 'Missing required parameter: sessionId' === err.message; + }); + + assert.throws( + () => buildPath('/session/:sessionId/element/:id', {'sessionId': 'foo'}), + function(err) { + return err instanceof error.InvalidArgumentError + && 'Missing required parameter: id' === err.message; + }); + }); + + it('does not match on segments that do not start with a colon', function() { + assert.equal(buildPath('/session/foo:bar/baz', {}), '/session/foo:bar/baz'); + }); +}); + +describe('Executor', function() { + let executor; + let send; + + beforeEach(function setUp() { + let client = new HttpClient('http://www.example.com'); + send = sinon.stub(client, 'send'); + executor = new Executor(client); + }); + + it('rejects unrecognized commands', function() { + assert.throws( + () => executor.execute(new Command('fake-name')), + function (err) { + return err instanceof error.UnknownCommandError + && 'Unrecognized command: fake-name' === err.message; + }); + }); + + it('rejects promise if client fails to send request', function() { + let error = new Error('boom'); + send.returns(Promise.reject(error)); + return assertFailsToSend(new Command(CommandName.NEW_SESSION)) + .then(function(e) { + assert.strictEqual(error, e); + assertSent( + 'POST', '/session', {}, + [['Accept', 'application/json; charset=utf-8']]); + }); + }); + + it('can execute commands with no URL parameters', function() { + send.returns(Promise.resolve(new HttpResponse(200, {}, ''))); + + let command = new Command(CommandName.NEW_SESSION); + return assertSendsSuccessfully(command).then(function(response) { + assertSent( + 'POST', '/session', {}, + [['Accept', 'application/json; charset=utf-8']]); + }); + }); + + it('rejects commands missing URL parameters', function() { + let command = + new Command(CommandName.FIND_CHILD_ELEMENT). + setParameter('sessionId', 's123'). + // Let this be missing: setParameter('id', {'ELEMENT': 'e456'}). + setParameter('using', 'id'). + setParameter('value', 'foo'); + + assert.throws( + () => executor.execute(command), + function(err) { + return err instanceof error.InvalidArgumentError + && 'Missing required parameter: id' === err.message; + }); + assert.ok(!send.called); + }); + + it('replaces URL parameters with command parameters', function() { + var command = new Command(CommandName.GET). + setParameter('sessionId', 's123'). + setParameter('url', 'http://www.google.com'); + + send.returns(Promise.resolve(new HttpResponse(200, {}, ''))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent( + 'POST', '/session/s123/url', {'url': 'http://www.google.com'}, + [['Accept', 'application/json; charset=utf-8']]); + }); + }); + + it('returns parsed JSON response', function() { + var responseObj = { + 'status': error.ErrorCode.SUCCESS, + 'value': 'http://www.google.com' + }; + + var command = new Command(CommandName.GET_CURRENT_URL). + setParameter('sessionId', 's123'); + + + send.returns(Promise.resolve( + new HttpResponse(200, {}, JSON.stringify(responseObj)))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('GET', '/session/s123/url', {}, + [['Accept', 'application/json; charset=utf-8']]); + assert.deepEqual(response, responseObj); + }); + }); + + it('returns success for 2xx with body as value when not json', function() { + var command = new Command(CommandName.GET_CURRENT_URL). + setParameter('sessionId', 's123'); + + send.returns(Promise.resolve( + new HttpResponse(200, {}, 'hello, world\r\ngoodbye, world!'))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('GET', '/session/s123/url', {}, + [['Accept', 'application/json; charset=utf-8']]); + assert.deepEqual(response, { + 'status': error.ErrorCode.SUCCESS, + 'value': 'hello, world\ngoodbye, world!' + }); + }); + }); + + it('returns success for 2xx with invalid JSON body', function() { + var command = new Command(CommandName.GET_CURRENT_URL). + setParameter('sessionId', 's123'); + + send.returns(Promise.resolve( + new HttpResponse(200, {}, '['))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('GET', '/session/s123/url', {}, + [['Accept', 'application/json; charset=utf-8']]); + assert.deepEqual(response, { + 'status': error.ErrorCode.SUCCESS, + 'value': '[' + }); + }); + }); + + it('returns unknown command for 404 with body as value when not json', + function() { + var command = new Command(CommandName.GET_CURRENT_URL). + setParameter('sessionId', 's123'); + + send.returns(Promise.resolve( + new HttpResponse(404, {}, 'hello, world\r\ngoodbye, world!'))); + + return assertSendsSuccessfully(command, function(response) { + assertSent('GET', '/session/s123/url', {}, + [['Accept', 'application/json; charset=utf-8']]); + assert.deepEqual(response, { + 'status': error.ErrorCode.UNKNOWN_COMMAND, + 'value': 'hello, world\ngoodbye, world!' + }); + }); + }); + + it('returnsUnknownErrorForGenericErrorCodeWithBodyAsValueWhenNotJSON', + function() { + var command = new Command(CommandName.GET_CURRENT_URL). + setParameter('sessionId', 's123'); + + send.returns(Promise.resolve( + new HttpResponse(500, {}, 'hello, world\r\ngoodbye, world!'))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('GET', '/session/s123/url', {}, + [['Accept', 'application/json; charset=utf-8']]); + assert.deepEqual(response, { + 'status': error.ErrorCode.UNKNOWN_ERROR, + 'value': 'hello, world\ngoodbye, world!' + }); + }); + }); + + it('canDefineNewCommands', function() { + executor.defineCommand('greet', 'GET', '/person/:name'); + + var command = new Command('greet'). + setParameter('name', 'Bob'); + + send.returns(Promise.resolve(new HttpResponse(200, {}, ''))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('GET', '/person/Bob', {}, + [['Accept', 'application/json; charset=utf-8']]); + }); + }); + + it('canRedefineStandardCommands', function() { + executor.defineCommand(CommandName.GO_BACK, 'POST', '/custom/back'); + + var command = new Command(CommandName.GO_BACK). + setParameter('times', 3); + + send.returns(Promise.resolve(new HttpResponse(200, {}, ''))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('POST', '/custom/back', {'times': 3}, + [['Accept', 'application/json; charset=utf-8']]); + }); + }); + + function entries(map) { + let entries = []; + for (let e of map.entries()) { + entries.push(e); + } + return entries; + } + + function assertSent(method, path, data, headers) { + assert.ok(send.calledWith(sinon.match(function(value) { + assert.equal(value.method, method); + assert.equal(value.path, path); + assert.deepEqual(value.data, data); + assert.deepEqual(entries(value.headers), headers); + return true; + }))); + } + + function assertSendsSuccessfully(command) { + return executor.execute(command).then(function(response) { + return response; + }); + } + + function assertFailsToSend(command, opt_onError) { + return executor.execute(command).then( + () => {throw Error('should have failed')}, + (e) => {return e}); + } +}); + +describe('HttpClient', function() { + this.timeout(4 * 1000); + + var server = new Server(function(req, res) { + if (req.method == 'GET' && req.url == '/echo') { + res.writeHead(200, req.headers); + res.end(); + + } else if (req.method == 'GET' && req.url == '/redirect') { + res.writeHead(303, {'Location': server.url('/hello')}); + res.end(); + + } else if (req.method == 'GET' && req.url == '/hello') { + res.writeHead(200, {'content-type': 'text/plain'}); + res.end('hello, world!'); + + } else if (req.method == 'GET' && req.url == '/badredirect') { + res.writeHead(303, {}); + res.end(); + + } else if (req.method == 'GET' && req.url == '/protected') { + var denyAccess = function() { + res.writeHead(401, {'WWW-Authenticate': 'Basic realm="test"'}); + res.end('Access denied'); + }; + + var basicAuthRegExp = /^\s*basic\s+([a-z0-9\-\._~\+\/]+)=*\s*$/i + var auth = req.headers.authorization; + var match = basicAuthRegExp.exec(auth || ''); + if (!match) { + denyAccess(); + return; + } + + var userNameAndPass = new Buffer(match[1], 'base64').toString(); + var parts = userNameAndPass.split(':', 2); + if (parts[0] !== 'genie' && parts[1] !== 'bottle') { + denyAccess(); + return; + } + + res.writeHead(200, {'content-type': 'text/plain'}); + res.end('Access granted!'); + + } else if (req.method == 'GET' && req.url == '/proxy') { + res.writeHead(200, req.headers); + res.end(); + + } else if (req.method == 'GET' && req.url == '/proxy/redirect') { + res.writeHead(303, {'Location': '/proxy'}); + res.end(); + + } else { + res.writeHead(404, {}); + res.end(); + } + }); + + before(function() { + return server.start(); + }); + + after(function() { + return server.stop(); + }); + + it('can send a basic HTTP request', function() { + var request = new HttpRequest('GET', '/echo'); + request.headers.set('Foo', 'Bar'); + + var agent = new http.Agent(); + agent.maxSockets = 1; // Only making 1 request. + + var client = new HttpClient(server.url(), agent); + return client.send(request).then(function(response) { + assert.equal(200, response.status); + assert.equal(response.headers.get('content-length'), '0'); + assert.equal(response.headers.get('connection'), 'keep-alive'); + assert.equal(response.headers.get('host'), server.host()); + + assert.equal(request.headers.get('Foo'), 'Bar'); + assert.equal( + request.headers.get('Accept'), 'application/json; charset=utf-8'); + }); + }); + + it('can use basic auth', function() { + var parsed = url.parse(server.url()); + parsed.auth = 'genie:bottle'; + + var client = new HttpClient(url.format(parsed)); + var request = new HttpRequest('GET', '/protected'); + return client.send(request).then(function(response) { + assert.equal(200, response.status); + assert.equal(response.headers.get('content-type'), 'text/plain'); + assert.equal(response.body, 'Access granted!'); + }); + }); + + it('fails requests missing required basic auth', function() { + var client = new HttpClient(server.url()); + var request = new HttpRequest('GET', '/protected'); + return client.send(request).then(function(response) { + assert.equal(401, response.status); + assert.equal(response.body, 'Access denied'); + }); + }); + + it('automatically follows redirects', function() { + var request = new HttpRequest('GET', '/redirect'); + var client = new HttpClient(server.url()); + return client.send(request).then(function(response) { + assert.equal(200, response.status); + assert.equal(response.headers.get('content-type'), 'text/plain'); + assert.equal(response.body, 'hello, world!'); + }); + }); + + it('handles malformed redirect responses', function() { + var request = new HttpRequest('GET', '/badredirect'); + var client = new HttpClient(server.url()); + return client.send(request).then(assert.fail, function(err) { + assert.ok(/Failed to parse "Location"/.test(err.message), + 'Not the expected error: ' + err.message); + }); + }); + + it('proxies requests through the webdriver proxy', function() { + var request = new HttpRequest('GET', '/proxy'); + var client = new HttpClient( + 'http://another.server.com', undefined, server.url()); + return client.send(request).then(function(response) { + assert.equal(200, response.status); + assert.equal(response.headers.get('host'), 'another.server.com'); + }); + }); + + it('proxies requests through the webdriver proxy on redirect', function() { + var request = new HttpRequest('GET', '/proxy/redirect'); + var client = new HttpClient( + 'http://another.server.com', undefined, server.url()); + return client.send(request).then(function(response) { + assert.equal(200, response.status); + assert.equal(response.headers.get('host'), 'another.server.com'); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/http/util_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/http/util_test.js new file mode 100644 index 0000000..ca250c6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/http/util_test.js @@ -0,0 +1,184 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'), + http = require('http'); + +var error = require('../../error'); +var util = require('../../http/util'); + +describe('selenium-webdriver/http/util', function() { + + var server, baseUrl; + + var status, value, responseCode; + + function startServer(done) { + if (server) return done(); + + server = http.createServer(function(req, res) { + var data = JSON.stringify({status: status, value: value}); + res.writeHead(responseCode, { + 'Content-Type': 'application/json; charset=utf-8', + 'Content-Length': Buffer.byteLength(data, 'utf8') + }); + res.end(data); + }); + + server.listen(0, '127.0.0.1', function(e) { + if (e) return done(e); + + var addr = server.address(); + baseUrl = 'http://' + addr.address + ':' + addr.port; + done(); + }); + } + + function killServer(done) { + if (!server) return done(); + server.close(done); + server = null; + } + + after(killServer); + + beforeEach(function(done) { + status = 0; + value = 'abc123'; + responseCode = 200; + startServer(done); + }); + + describe('#getStatus', function() { + it('should return value field on success', function() { + return util.getStatus(baseUrl).then(function(response) { + assert.equal('abc123', response); + }); + }); + + it('should fail if response object is not success', function() { + status = 1; + return util.getStatus(baseUrl).then(function() { + throw Error('expected a failure'); + }, function(err) { + assert.ok(err instanceof error.WebDriverError); + assert.equal(err.code, error.WebDriverError.code); + assert.equal(err.message, value); + }); + }); + + it('should fail if the server is not listening', function(done) { + killServer(function(e) { + if(e) return done(e); + + util.getStatus(baseUrl).then(function() { + done(Error('expected a failure')); + }, function() { + // Expected. + done(); + }); + }); + }); + + it('should fail if HTTP status is not 200', function() { + status = 1; + responseCode = 404; + return util.getStatus(baseUrl).then(function() { + throw Error('expected a failure'); + }, function(err) { + assert.ok(err instanceof error.WebDriverError); + assert.equal(err.code, error.WebDriverError.code); + assert.equal(err.message, value); + }); + }); + }); + + describe('#waitForServer', function() { + it('resolves when server is ready', function() { + status = 1; + setTimeout(function() { status = 0; }, 50); + return util.waitForServer(baseUrl, 100); + }); + + it('should fail if server does not become ready', function() { + status = 1; + return util.waitForServer(baseUrl, 50). + then(function() {throw Error('Expected to time out')}, + function() {}); + }); + + it('can cancel wait', function(done) { + status = 1; + var err = Error('cancelled!'); + var isReady = util.waitForServer(baseUrl, 200). + then(function() { done('Did not expect to succeed'); }). + then(null, function(e) { + assert.equal('cancelled!', e.message); + }). + then(function() { done(); }, done); + + setTimeout(function() { + isReady.cancel('cancelled!'); + }, 50); + }); + }); + + describe('#waitForUrl', function() { + it('succeeds when URL returns 2xx', function(done) { + responseCode = 404; + setTimeout(function() { responseCode = 200; }, 50); + + util.waitForUrl(baseUrl, 200). + then(function() {}). // done needs no argument to pass. + thenFinally(done); + }); + + it('fails if URL always returns 4xx', function(done) { + responseCode = 404; + + util.waitForUrl(baseUrl, 50). + then(function() { done('Expected to time out'); }, + function() { done(); }); + }); + + it('fails if cannot connect to server', function(done) { + killServer(function(e) { + if (e) return done(e); + + util.waitForUrl(baseUrl, 50). + then(function() { done('Expected to time out'); }, + function() { done(); }); + }); + }); + + it('can cancel wait', function(done) { + responseCode = 404; + var isReady = util.waitForUrl(baseUrl, 200). + then(function() { done('Did not expect to succeed'); }). + then(null, function(e) { + assert.equal('cancelled!', e.message); + }). + then(function() { done(); }, done); + + setTimeout(function() { + isReady.cancel('cancelled!'); + }, 50); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/io_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/io_test.js new file mode 100644 index 0000000..bc2b457 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/io_test.js @@ -0,0 +1,232 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'), + fs = require('fs'), + path = require('path'), + tmp = require('tmp'); + +var io = require('../io'), + before = require('../testing').before, + beforeEach = require('../testing').beforeEach, + it = require('../testing').it; + + +describe('io', function() { + describe('copy', function() { + var tmpDir; + + before(function() { + return io.tmpDir().then(function(d) { + tmpDir = d; + + fs.writeFileSync(path.join(d, 'foo'), 'Hello, world'); + }); + }); + + it('can copy one file to another', function() { + return io.tmpFile().then(function(f) { + return io.copy(path.join(tmpDir, 'foo'), f).then(function(p) { + assert.equal(p, f); + assert.equal('Hello, world', fs.readFileSync(p)); + }); + }); + }); + + it('can copy symlink to destination', function() { + if (process.platform === 'win32') { + return; // No symlinks on windows. + } + fs.symlinkSync( + path.join(tmpDir, 'foo'), + path.join(tmpDir, 'symlinked-foo')); + return io.tmpFile().then(function(f) { + return io.copy(path.join(tmpDir, 'symlinked-foo'), f).then(function(p) { + assert.equal(p, f); + assert.equal('Hello, world', fs.readFileSync(p)); + }); + }); + }); + + it('fails if given a directory as a source', function() { + return io.tmpFile().then(function(f) { + return io.copy(tmpDir, f); + }).then(function() { + throw Error('Should have failed with a type error'); + }, function() { + // Do nothing; expected. + }); + }); + }); + + describe('copyDir', function() { + it('copies recursively', function() { + return io.tmpDir().then(function(dir) { + fs.writeFileSync(path.join(dir, 'file1'), 'hello'); + fs.mkdirSync(path.join(dir, 'sub')); + fs.mkdirSync(path.join(dir, 'sub/folder')); + fs.writeFileSync(path.join(dir, 'sub/folder/file2'), 'goodbye'); + + return io.tmpDir().then(function(dst) { + return io.copyDir(dir, dst).then(function(ret) { + assert.equal(dst, ret); + + assert.equal('hello', + fs.readFileSync(path.join(dst, 'file1'))); + assert.equal('goodbye', + fs.readFileSync(path.join(dst, 'sub/folder/file2'))); + }); + }); + }); + }); + + it('creates destination dir if necessary', function() { + return io.tmpDir().then(function(srcDir) { + fs.writeFileSync(path.join(srcDir, 'foo'), 'hi'); + return io.tmpDir().then(function(dstDir) { + return io.copyDir(srcDir, path.join(dstDir, 'sub')); + }); + }).then(function(p) { + assert.equal('sub', path.basename(p)); + assert.equal('hi', fs.readFileSync(path.join(p, 'foo'))); + }); + }); + + it('supports regex exclusion filter', function() { + return io.tmpDir().then(function(src) { + fs.writeFileSync(path.join(src, 'foo'), 'a'); + fs.writeFileSync(path.join(src, 'bar'), 'b'); + fs.writeFileSync(path.join(src, 'baz'), 'c'); + fs.mkdirSync(path.join(src, 'sub')); + fs.writeFileSync(path.join(src, 'sub/quux'), 'd'); + fs.writeFileSync(path.join(src, 'sub/quot'), 'e'); + + return io.tmpDir().then(function(dst) { + return io.copyDir(src, dst, /(bar|quux)/); + }); + }).then(function(dir) { + assert.equal('a', fs.readFileSync(path.join(dir, 'foo'))); + assert.equal('c', fs.readFileSync(path.join(dir, 'baz'))); + assert.equal('e', fs.readFileSync(path.join(dir, 'sub/quot'))); + + assert.ok(!fs.existsSync(path.join(dir, 'bar'))); + assert.ok(!fs.existsSync(path.join(dir, 'sub/quux'))); + }); + }); + + it('supports exclusion filter function', function() { + return io.tmpDir().then(function(src) { + fs.writeFileSync(path.join(src, 'foo'), 'a'); + fs.writeFileSync(path.join(src, 'bar'), 'b'); + fs.writeFileSync(path.join(src, 'baz'), 'c'); + fs.mkdirSync(path.join(src, 'sub')); + fs.writeFileSync(path.join(src, 'sub/quux'), 'd'); + fs.writeFileSync(path.join(src, 'sub/quot'), 'e'); + + return io.tmpDir().then(function(dst) { + return io.copyDir(src, dst, function(f) { + return f !== path.join(src, 'foo') + && f !== path.join(src, 'sub/quot'); + }); + }); + }).then(function(dir) { + assert.equal('b', fs.readFileSync(path.join(dir, 'bar'))); + assert.equal('c', fs.readFileSync(path.join(dir, 'baz'))); + assert.equal('d', fs.readFileSync(path.join(dir, 'sub/quux'))); + + assert.ok(!fs.existsSync(path.join(dir, 'foo'))); + assert.ok(!fs.existsSync(path.join(dir, 'sub/quot'))); + }); + }); + }); + + describe('exists', function() { + var dir; + + before(function() { + return io.tmpDir().then(function(d) { + dir = d; + }); + }); + + it('works for directories', function() { + return io.exists(dir).then(assert.ok); + }); + + it('works for files', function() { + var file = path.join(dir, 'foo'); + fs.writeFileSync(file, ''); + return io.exists(file).then(assert.ok); + }); + + it('does not return a rejected promise if file does not exist', function() { + return io.exists(path.join(dir, 'not-there')).then(function(exists) { + assert.ok(!exists); + }); + }); + }); + + describe('unlink', function() { + var dir; + + before(function() { + return io.tmpDir().then(function(d) { + dir = d; + }); + }); + + it('silently succeeds if the path does not exist', function() { + return io.unlink(path.join(dir, 'not-there')); + }); + + it('deletes files', function() { + var file = path.join(dir, 'foo'); + fs.writeFileSync(file, ''); + return io.exists(file).then(assert.ok).then(function() { + return io.unlink(file); + }).then(function() { + return io.exists(file); + }).then(function(exists) { + return assert.ok(!exists); + }); + }); + }); + + describe('rmDir', function() { + it('succeeds if the designated directory does not exist', function() { + return io.tmpDir().then(function(d) { + return io.rmDir(path.join(d, 'i/do/not/exist')); + }); + }); + + it('deletes recursively', function() { + return io.tmpDir().then(function(dir) { + fs.writeFileSync(path.join(dir, 'file1'), 'hello'); + fs.mkdirSync(path.join(dir, 'sub')); + fs.mkdirSync(path.join(dir, 'sub/folder')); + fs.writeFileSync(path.join(dir, 'sub/folder/file2'), 'goodbye'); + + return io.rmDir(dir).then(function() { + assert.ok(!fs.existsSync(dir)); + assert.ok(!fs.existsSync(path.join(dir, 'sub/folder/file2'))); + }); + }); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/by_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/by_test.js new file mode 100644 index 0000000..c4bd2f4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/by_test.js @@ -0,0 +1,127 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'); +var by = require('../../lib/by'); + +describe('by', function() { + describe('By', function() { + describe('className', function() { + it('delegates to By.css', function() { + let locator = by.By.className('foo'); + assert.equal('css selector', locator.using); + assert.equal('.foo', locator.value); + }); + + it('escapes class name', function() { + let locator = by.By.className('foo#bar'); + assert.equal('css selector', locator.using); + assert.equal('.foo\\#bar', locator.value); + }); + + it('translates compound class names', function() { + let locator = by.By.className('a b'); + assert.equal('css selector', locator.using); + assert.equal('.a.b', locator.value); + + locator = by.By.className(' x y z-1 "g" '); + assert.equal('css selector', locator.using); + assert.equal('.x.y.z-1.\\"g\\"', locator.value); + }); + }); + + describe('id', function() { + it('delegates to By.css', function() { + let locator = by.By.id('foo'); + assert.equal('css selector', locator.using); + assert.equal('*[id="foo"]', locator.value); + }); + + it('escapes the ID', function() { + let locator = by.By.id('foo#bar'); + assert.equal('css selector', locator.using); + assert.equal('*[id="foo\\#bar"]', locator.value); + }); + }); + + describe('name', function() { + it('delegates to By.css', function() { + let locator = by.By.name('foo') + assert.equal('css selector', locator.using); + assert.equal('*[name="foo"]', locator.value); + }); + + it('escapes the name', function() { + let locator = by.By.name('foo"bar"') + assert.equal('css selector', locator.using); + assert.equal('*[name="foo\\"bar\\""]', locator.value); + }); + }); + }); + + describe('checkedLocator', function() { + it('accepts class name', function() { + let locator = by.checkedLocator({className: 'foo'}); + assert.equal('css selector', locator.using); + assert.equal('.foo', locator.value); + }); + + it('accepts css', function() { + let locator = by.checkedLocator({css: 'a > b'}); + assert.equal('css selector', locator.using); + assert.equal('a > b', locator.value); + }); + + it('accepts id', function() { + let locator = by.checkedLocator({id: 'foobar'}); + assert.equal('css selector', locator.using); + assert.equal('*[id="foobar"]', locator.value); + }); + + it('accepts linkText', function() { + let locator = by.checkedLocator({linkText: 'hello'}); + assert.equal('link text', locator.using); + assert.equal('hello', locator.value); + }); + + it('accepts name', function() { + let locator = by.checkedLocator({name: 'foobar'}); + assert.equal('css selector', locator.using); + assert.equal('*[name="foobar"]', locator.value); + }); + + it('accepts partialLinkText', function() { + let locator = by.checkedLocator({partialLinkText: 'hello'}); + assert.equal('partial link text', locator.using); + assert.equal('hello', locator.value); + }); + + it('accepts tagName', function() { + let locator = by.checkedLocator({tagName: 'div'}); + assert.equal('css selector', locator.using); + assert.equal('div', locator.value); + }); + + it('accepts xpath', function() { + let locator = by.checkedLocator({xpath: '//div[1]'}); + assert.equal('xpath', locator.using); + assert.equal('//div[1]', locator.value); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/capabilities_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/capabilities_test.js new file mode 100644 index 0000000..78823d7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/capabilities_test.js @@ -0,0 +1,84 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const Capabilities = require('../../lib/capabilities').Capabilities; +const Symbols = require('../../lib/symbols'); + +const assert = require('assert'); + +describe('Capabilities', function() { + it('can set and unset a capability', function() { + let caps = new Capabilities(); + assert.equal(undefined, caps.get('foo')); + assert.ok(!caps.has('foo')); + + caps.set('foo', 'bar'); + assert.equal('bar', caps.get('foo')); + assert.ok(caps.has('foo')); + + caps.set('foo', null); + assert.equal(null, caps.get('foo')); + assert.ok(caps.has('foo')); + }); + + it('requires string capability keys', function() { + let caps = new Capabilities(); + assert.throws(() => caps.set({}, 'hi')); + }); + + it('can merge capabilities', function() { + let caps1 = new Capabilities() + .set('foo', 'bar') + .set('color', 'red'); + + let caps2 = new Capabilities() + .set('color', 'green'); + + assert.equal('bar', caps1.get('foo')); + assert.equal('red', caps1.get('color')); + assert.equal('green', caps2.get('color')); + assert.equal(undefined, caps2.get('foo')); + + caps2.merge(caps1); + assert.equal('bar', caps1.get('foo')); + assert.equal('red', caps1.get('color')); + assert.equal('red', caps2.get('color')); + assert.equal('bar', caps2.get('foo')); + }); + + it('can be initialized from a hash object', function() { + let caps = new Capabilities({'one': 123, 'abc': 'def'}); + assert.equal(123, caps.get('one')); + assert.equal('def', caps.get('abc')); + }); + + it('can be initialized from a map', function() { + let m = new Map([['one', 123], ['abc', 'def']]); + + let caps = new Capabilities(m); + assert.equal(123, caps.get('one')); + assert.equal('def', caps.get('abc')); + }); + + it('can be serialized', function() { + let m = new Map([['one', 123], ['abc', 'def']]); + let caps = new Capabilities(m); + assert.deepEqual({one: 123, abc: 'def'}, caps[Symbols.serialize]()); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/events_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/events_test.js new file mode 100644 index 0000000..a02da97 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/events_test.js @@ -0,0 +1,177 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const EventEmitter = require('../../lib/events').EventEmitter; + +const assert = require('assert'); +const sinon = require('sinon'); + +describe('EventEmitter', function() { + describe('#emit()', function() { + it('can emit events when nothing is registered', function() { + let emitter = new EventEmitter; + emitter.emit('foo'); + // Ok if no errors are thrown. + }); + + it('can pass args to listeners on emit', function() { + let emitter = new EventEmitter; + let now = Date.now(); + + let messages = []; + emitter.on('foo', (arg) => messages.push(arg)); + + emitter.emit('foo', now); + assert.deepEqual([now], messages); + + emitter.emit('foo', now + 15); + assert.deepEqual([now, now + 15], messages); + }); + }); + + describe('#addListener()', function() { + it('can add multiple listeners for one event', function() { + let emitter = new EventEmitter; + let count = 0; + emitter.addListener('foo', () => count++); + emitter.addListener('foo', () => count++); + emitter.addListener('foo', () => count++); + emitter.emit('foo'); + assert.equal(3, count); + }); + + it('only registers each listener function once', function() { + let emitter = new EventEmitter; + let count = 0; + let onFoo = () => count++; + emitter.addListener('foo', onFoo); + emitter.addListener('foo', onFoo); + emitter.addListener('foo', onFoo); + + emitter.emit('foo'); + assert.equal(1, count); + + emitter.emit('foo'); + assert.equal(2, count); + }); + + it('allows users to specify a custom scope', function() { + let obj = { + count: 0, + inc: function() { + this.count++; + } + }; + let emitter = new EventEmitter; + emitter.addListener('foo', obj.inc, obj); + + emitter.emit('foo'); + assert.equal(1, obj.count); + + emitter.emit('foo'); + assert.equal(2, obj.count); + }); + }); + + describe('#once()', function() { + it('only calls registered callback once', function() { + let emitter = new EventEmitter; + let count = 0; + emitter.once('foo', () => count++); + emitter.once('foo', () => count++); + emitter.once('foo', () => count++); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.emit('foo'); + assert.equal(3, count); + }); + }); + + describe('#removeListeners()', function() { + it('only removes the given listener function', function() { + let emitter = new EventEmitter; + let count = 0; + emitter.addListener('foo', () => count++); + emitter.addListener('foo', () => count++); + + let toRemove = () => count++; + emitter.addListener('foo', toRemove); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.removeListener('foo', toRemove); + emitter.emit('foo'); + assert.equal(5, count); + }); + }); + + describe('#removeAllListeners()', function() { + it('only removes listeners for type if specified', function() { + let emitter = new EventEmitter; + let count = 0; + emitter.addListener('foo', () => count++); + emitter.addListener('foo', () => count++); + emitter.addListener('foo', () => count++); + emitter.addListener('bar', () => count++); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.removeAllListeners('foo'); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.emit('bar'); + assert.equal(4, count); + }); + + it('removes absolutely all listeners if no type specified', function() { + let emitter = new EventEmitter; + let count = 0; + emitter.addListener('foo', () => count++); + emitter.addListener('bar', () => count++); + emitter.addListener('baz', () => count++); + emitter.addListener('baz', () => count++); + + emitter.emit('foo'); + assert.equal(1, count); + + emitter.emit('baz'); + assert.equal(3, count); + + emitter.removeAllListeners(); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.emit('bar'); + assert.equal(3, count); + + emitter.emit('baz'); + assert.equal(3, count); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/logging_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/logging_test.js new file mode 100644 index 0000000..29d2af4 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/logging_test.js @@ -0,0 +1,272 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); +const sinon = require('sinon'); +const logging = require('../../lib/logging'); + +describe('logging', function() { + let mgr, root, clock; + + beforeEach(function setUp() { + mgr = new logging.LogManager; + root = mgr.getLogger(''); + + clock = sinon.useFakeTimers(); + }); + + afterEach(function tearDown() { + clock.restore(); + }); + + describe('LogManager', function() { + describe('getLogger()', function() { + it('handles falsey input', function() { + assert.strictEqual(root, mgr.getLogger()); + assert.strictEqual(root, mgr.getLogger('')); + assert.strictEqual(root, mgr.getLogger(null)); + assert.strictEqual(root, mgr.getLogger(0)); + }); + + it('creates parent loggers', function() { + let logger = mgr.getLogger('foo.bar.baz'); + assert.strictEqual(logger.parent_, mgr.getLogger('foo.bar')); + + logger = logger.parent_; + assert.strictEqual(logger.parent_, mgr.getLogger('foo')); + + logger = logger.parent_; + assert.strictEqual(logger.parent_, mgr.getLogger('')); + + assert.strictEqual(logger.parent_.parent_, null); + }); + }); + }); + + describe('Logger', function() { + describe('getEffectiveLevel()', function() { + it('defaults to OFF', function() { + assert.strictEqual(root.getLevel(), logging.Level.OFF); + assert.strictEqual(root.getEffectiveLevel(), logging.Level.OFF); + + root.setLevel(null); + assert.strictEqual(root.getLevel(), null); + assert.strictEqual(root.getEffectiveLevel(), logging.Level.OFF); + }); + + it('uses own level if set', function() { + let logger = mgr.getLogger('foo.bar.baz'); + assert.strictEqual(logger.getLevel(), null); + assert.strictEqual(logger.getEffectiveLevel(), logging.Level.OFF); + + logger.setLevel(logging.Level.INFO); + assert.strictEqual(logger.getLevel(), logging.Level.INFO); + assert.strictEqual(logger.getEffectiveLevel(), logging.Level.INFO); + }); + + it('uses level from set on nearest parent', function() { + let ancestor = mgr.getLogger('foo'); + ancestor.setLevel(logging.Level.SEVERE); + + let logger = mgr.getLogger('foo.bar.baz'); + assert.strictEqual(logger.getLevel(), null); + assert.strictEqual(logger.getEffectiveLevel(), logging.Level.SEVERE); + }); + }); + + describe('isLoggable()', function() { + it('compares level against logger\'s effective level', function() { + const log1 = mgr.getLogger('foo'); + log1.setLevel(logging.Level.WARNING); + + const log2 = mgr.getLogger('foo.bar.baz'); + + assert(!log2.isLoggable(logging.Level.FINEST)); + assert(!log2.isLoggable(logging.Level.INFO)); + assert(log2.isLoggable(logging.Level.WARNING)); + assert(log2.isLoggable(logging.Level.SEVERE)); + + log2.setLevel(logging.Level.INFO); + + assert(!log2.isLoggable(logging.Level.FINEST)); + assert(log2.isLoggable(logging.Level.INFO)); + assert(log2.isLoggable(logging.Level.WARNING)); + assert(log2.isLoggable(logging.Level.SEVERE)); + + log2.setLevel(logging.Level.ALL); + + assert(log2.isLoggable(logging.Level.FINEST)); + assert(log2.isLoggable(logging.Level.INFO)); + assert(log2.isLoggable(logging.Level.WARNING)); + assert(log2.isLoggable(logging.Level.SEVERE)); + }); + + it('Level.OFF is never loggable', function() { + function test(level) { + root.setLevel(level); + assert(!root.isLoggable(logging.Level.OFF), + 'OFF should not be loggable at ' + level); + } + + test(logging.Level.ALL); + test(logging.Level.INFO); + test(logging.Level.OFF); + }); + }); + + describe('log()', function() { + it('does not invoke loggable if message is not loggable', function() { + const log = mgr.getLogger('foo'); + log.setLevel(logging.Level.OFF); + + let callback = sinon.spy(); + log.addHandler(callback); + root.addHandler(callback); + + assert(!callback.called); + }); + + it('invokes handlers for each parent logger', function() { + const cb1 = sinon.spy(); + const cb2 = sinon.spy(); + const cb3 = sinon.spy(); + const cb4 = sinon.spy(); + + const log1 = mgr.getLogger('foo'); + const log2 = mgr.getLogger('foo.bar'); + const log3 = mgr.getLogger('foo.bar.baz'); + const log4 = mgr.getLogger('foo.bar.baz.quot'); + + log1.addHandler(cb1); + log1.setLevel(logging.Level.INFO); + + log2.addHandler(cb2); + log2.setLevel(logging.Level.WARNING); + + log3.addHandler(cb3); + log3.setLevel(logging.Level.FINER); + + clock.tick(123456); + + log4.finest('this is the finest message'); + log4.finer('this is a finer message'); + log4.info('this is an info message'); + log4.warning('this is a warning message'); + log4.severe('this is a severe message'); + + assert.equal(4, cb1.callCount); + assert.equal(4, cb2.callCount); + assert.equal(4, cb3.callCount); + + const entry1 = new logging.Entry( + logging.Level.FINER, + '[foo.bar.baz.quot] this is a finer message', + 123456); + const entry2 = new logging.Entry( + logging.Level.INFO, + '[foo.bar.baz.quot] this is an info message', + 123456); + const entry3 = new logging.Entry( + logging.Level.WARNING, + '[foo.bar.baz.quot] this is a warning message', + 123456); + const entry4 = new logging.Entry( + logging.Level.SEVERE, + '[foo.bar.baz.quot] this is a severe message', + 123456); + + check(cb1.getCall(0).args[0], entry1); + check(cb1.getCall(1).args[0], entry2); + check(cb1.getCall(2).args[0], entry3); + check(cb1.getCall(3).args[0], entry4); + + check(cb2.getCall(0).args[0], entry1); + check(cb2.getCall(1).args[0], entry2); + check(cb2.getCall(2).args[0], entry3); + check(cb2.getCall(3).args[0], entry4); + + check(cb3.getCall(0).args[0], entry1); + check(cb3.getCall(1).args[0], entry2); + check(cb3.getCall(2).args[0], entry3); + check(cb3.getCall(3).args[0], entry4); + + function check(entry, expected) { + assert.equal(entry.level, expected.level, 'wrong level'); + assert.equal(entry.message, expected.message, 'wrong message'); + assert.equal(entry.timestamp, expected.timestamp, 'wrong time'); + } + }); + + it('does not invoke removed handler', function() { + root.setLevel(logging.Level.INFO); + const cb = sinon.spy(); + + root.addHandler(cb); + root.info('hi'); + assert.equal(1, cb.callCount); + + assert(root.removeHandler(cb)); + root.info('bye'); + assert.equal(1, cb.callCount); + + assert(!root.removeHandler(cb)); + }); + }); + }); + + describe('getLevel()', function() { + it('converts named levels', function() { + assert.strictEqual(logging.Level.DEBUG, logging.getLevel('DEBUG')); + assert.strictEqual(logging.Level.ALL, logging.getLevel('FAKE')); + }); + + it('converts numeric levels', function() { + assert.strictEqual( + logging.Level.DEBUG, + logging.getLevel(logging.Level.DEBUG.value)); + }); + + it('normalizes numeric levels', function() { + assert.strictEqual( + logging.Level.OFF, + logging.getLevel(logging.Level.OFF.value * 2)); + + let diff = logging.Level.SEVERE.value - logging.Level.WARNING.value; + assert.strictEqual( + logging.Level.WARNING, + logging.getLevel(logging.Level.WARNING.value + (diff * .5))); + + assert.strictEqual(logging.Level.ALL, logging.getLevel(0)); + assert.strictEqual(logging.Level.ALL, logging.getLevel(-1)); + }); + }); + + describe('Preferences', function() { + it('can be converted to JSON', function() { + let prefs = new logging.Preferences; + assert.equal('{}', JSON.stringify(prefs)); + + prefs.setLevel('foo', logging.Level.DEBUG); + assert.equal('{"foo":"DEBUG"}', JSON.stringify(prefs)); + + prefs.setLevel(logging.Type.BROWSER, logging.Level.FINE); + assert.equal('{"foo":"DEBUG","browser":"FINE"}', JSON.stringify(prefs)); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_aplus_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_aplus_test.js new file mode 100644 index 0000000..a893915 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_aplus_test.js @@ -0,0 +1,74 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const promise = require('../../lib/promise'); + +describe('Promises/A+ Compliance Tests', function() { + // The promise spec does not define behavior for unhandled rejections and + // assumes they are effectively swallowed. This is not the case with our + // implementation, so we have to disable error propagation to test that the + // rest of our behavior is compliant. + // We run the tests with a separate instance of the control flow to ensure + // disablign error propagation does not impact other tests. + var flow = new promise.ControlFlow(); + flow.setPropagateUnhandledRejections(false); + + // Skip the tests in 2.2.6.1/2. We are not compliant in these scenarios. + var realDescribe = global.describe; + global.describe = function(name, fn) { + realDescribe(name, function() { + var prefix = 'Promises/A+ Compliance Tests 2.2.6: ' + + '`then` may be called multiple times on the same promise.'; + var suffix = 'even when one handler is added inside another handler'; + if (this.fullTitle().startsWith(prefix) + && this.fullTitle().endsWith(suffix)) { + var realSpecify = global.specify; + try { + global.specify = function(name) { + realSpecify(name); + }; + fn(); + } finally { + global.specify = realSpecify; + } + } else { + fn(); + } + }); + }; + + require('promises-aplus-tests').mocha({ + resolved: function(value) { + return new promise.Promise((fulfill) => fulfill(value), flow); + }, + rejected: function(error) { + return new promise.Promise((_, reject) => reject(error), flow); + }, + deferred: function() { + var d = new promise.Deferred(flow); + return { + resolve: d.fulfill, + reject: d.reject, + promise: d.promise + }; + } + }); + + global.describe = realDescribe; +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_error_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_error_test.js new file mode 100644 index 0000000..114189c --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_error_test.js @@ -0,0 +1,808 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Contains tests against promise error handling. Many tests use + * NativePromise to control test termination independent of promise + * (and notably promise.ControlFlow). + */ + +'use strict'; + +const testutil = require('./testutil'); + +const assert = require('assert'); +const promise = require('../../lib/promise'); + +const NativePromise = Promise; +const StubError = testutil.StubError; +const throwStubError = testutil.throwStubError; +const assertIsStubError = testutil.assertIsStubError; + +describe('promise error handling', function() { + var flow, uncaughtExceptions; + + beforeEach(function setUp() { + flow = promise.controlFlow(); + uncaughtExceptions = []; + flow.on('uncaughtException', onUncaughtException); + }); + + afterEach(function tearDown() { + return waitForIdle(flow).then(function() { + assert.deepEqual( + [], uncaughtExceptions, 'There were uncaught exceptions'); + flow.reset(); + }); + }); + + function onUncaughtException(e) { + uncaughtExceptions.push(e); + } + + function waitForAbort(opt_flow, opt_n) { + var n = opt_n || 1; + var theFlow = opt_flow || flow; + theFlow.removeAllListeners( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION); + return new NativePromise(function(fulfill, reject) { + theFlow.once('idle', function() { + reject(Error('expected flow to report an unhandled error')); + }); + + var errors = []; + theFlow.on('uncaughtException', onError); + function onError(e) { + errors.push(e); + if (errors.length === n) { + theFlow.removeListener('uncaughtException', onError); + fulfill(n === 1 ? errors[0] : errors); + } + } + }); + } + + function waitForIdle(opt_flow) { + var theFlow = opt_flow || flow; + return new NativePromise(function(fulfill, reject) { + if (theFlow.isIdle()) { + fulfill(); + return; + } + theFlow.once('idle', fulfill); + theFlow.once('uncaughtException', reject); + }); + } + + it('testRejectedPromiseTriggersErrorCallback', function() { + return promise.rejected(new StubError). + then(assert.fail, assertIsStubError); + }); + + describe('callback throws trigger subsequent error callback', function() { + it('fulfilled promise', function() { + return promise.fulfilled(). + then(throwStubError). + then(assert.fail, assertIsStubError); + }); + + it('rejected promise', function() { + var e = Error('not the droids you are looking for'); + return promise.rejected(e). + then(assert.fail, throwStubError). + then(assert.fail, assertIsStubError); + }); + }); + + describe('callback returns rejected promise triggers subsequent errback', function() { + it('from fulfilled callback', function() { + return promise.fulfilled().then(function() { + return promise.rejected(new StubError); + }).then(assert.fail, assertIsStubError); + }); + + it('from rejected callback', function() { + var e = Error('not the droids you are looking for'); + return promise.rejected(e). + then(assert.fail, function() { + return promise.rejected(new StubError); + }). + then(assert.fail, assertIsStubError); + }); + }); + + it('testReportsUnhandledRejectionsThroughTheControlFlow', function() { + promise.rejected(new StubError); + return waitForAbort().then(assertIsStubError); + }); + + describe('multiple unhandled rejections outside a task', function() { + it('are reported in order they occurred', function() { + var e1 = Error('error 1'); + var e2 = Error('error 2'); + + promise.rejected(e1); + promise.rejected(e2); + + return waitForAbort(flow).then(function(error) { + assert.ok( + error instanceof promise.MultipleUnhandledRejectionError); + // TODO: switch to Array.from when we drop node 0.12.x + var errors = []; + for (var e of error.errors) { + errors.push(e); + } + assert.deepEqual([e1, e2], errors); + }); + }); + }); + + describe('does not report unhandled rejection when', function() { + it('handler added before next tick', function() { + promise.rejected(new StubError).then(assert.fail, assertIsStubError); + return waitForIdle(); + }); + + it('added async but before next tick', function() { + var called = false; + return new NativePromise(function(fulfill, reject) { + var aPromise; + NativePromise.resolve().then(function() { + aPromise.then(assert.fail, function(e) { + called = true; + assertIsStubError(e); + }); + waitForIdle().then(fulfill, reject); + }); + aPromise = promise.rejected(new StubError); + }).then(function() { + assert.ok(called); + }) + }); + }); + + it('testTaskThrows', function() { + return flow.execute(throwStubError).then(assert.fail, assertIsStubError); + }); + + it('testTaskReturnsRejectedPromise', function() { + return flow.execute(function() { + return promise.rejected(new StubError) + }).then(assert.fail, assertIsStubError); + }); + + it('testTaskHasUnhandledRejection', function() { + return flow.execute(function() { + promise.rejected(new StubError) + }).then(assert.fail, assertIsStubError); + }); + + it('testTaskfails_returnedPromiseIsUnhandled', function() { + flow.execute(throwStubError); + return waitForAbort().then(assertIsStubError); + }); + + it('testTaskHasUnhandledRejection_cancelsRemainingSubTasks', function() { + var seen = []; + flow.execute(function() { + promise.rejected(new StubError); + + flow.execute(() => seen.push('a')) + .then(() => seen.push('b'), (e) => seen.push(e)); + flow.execute(() => seen.push('c')) + .then(() => seen.push('b'), (e) => seen.push(e)); + }); + + return waitForAbort() + .then(assertIsStubError) + .then(() => assert.deepEqual([], seen)); + }); + + describe('nested task failures', function() { + it('returns up to paren', function() { + return flow.execute(function() { + return flow.execute(function() { + return flow.execute(throwStubError); + }); + }).then(assert.fail, assertIsStubError); + }); + + it('task throws; uncaught error bubbles up', function() { + flow.execute(function() { + flow.execute(function() { + flow.execute(throwStubError); + }); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('task throws; uncaught error bubbles up; is caught at root', function() { + flow.execute(function() { + flow.execute(function() { + flow.execute(throwStubError); + }); + }).then(assert.fail, assertIsStubError); + return waitForIdle(); + }); + + it('unhandled rejection bubbles up', function() { + flow.execute(function() { + flow.execute(function() { + flow.execute(function() { + promise.rejected(new StubError); + }); + }); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('unhandled rejection bubbles up; caught at root', function() { + flow.execute(function() { + flow.execute(function() { + promise.rejected(new StubError); + }); + }).then(assert.fail, assertIsStubError); + return waitForIdle(); + }); + + it('mixtureof hanging and free subtasks', function() { + flow.execute(function() { + return flow.execute(function() { + flow.execute(throwStubError); + }); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('cancels remaining tasks', function() { + var seen = []; + flow.execute(function() { + flow.execute(() => promise.rejected(new StubError)); + flow.execute(() => seen.push('a')) + .then(() => seen.push('b'), (e) => seen.push(e)); + flow.execute(() => seen.push('c')) + .then(() => seen.push('b'), (e) => seen.push(e)); + }); + + return waitForAbort() + .then(assertIsStubError) + .then(() => assert.deepEqual([], seen)); + }); + }); + + it('testTaskReturnsPromiseLikeObjectThatInvokesErrback', function() { + return flow.execute(function() { + return { + 'then': function(_, errback) { + errback('abc123'); + } + }; + }).then(assert.fail, function(value) { + assert.equal('abc123', value); + }); + }); + + describe('ControlFlow#wait();', function() { + describe('condition throws;', function() { + it('failure is caught', function() { + return flow.wait(throwStubError, 50).then(assert.fail, assertIsStubError); + }); + + it('failure is not caught', function() { + flow.wait(throwStubError, 50); + return waitForAbort().then(assertIsStubError); + }); + }); + + describe('condition returns promise', function() { + it('failure is caught', function() { + return flow.wait(function() { + return promise.rejected(new StubError); + }, 50).then(assert.fail, assertIsStubError); + }); + + it('failure is not caught', function() { + flow.wait(function() { + return promise.rejected(new StubError); + }, 50); + return waitForAbort().then(assertIsStubError); + }); + }); + + describe('condition has unhandled promise rejection', function() { + it('failure is caught', function() { + return flow.wait(function() { + promise.rejected(new StubError); + }, 50).then(assert.fail, assertIsStubError); + }); + + it('failure is not caught', function() { + flow.wait(function() { + promise.rejected(new StubError); + }, 50); + return waitForAbort().then(assertIsStubError); + }); + }); + + describe('condition has subtask failure', function() { + it('failure is caught', function() { + return flow.wait(function() { + flow.execute(function() { + flow.execute(throwStubError); + }); + }, 50).then(assert.fail, assertIsStubError); + }); + + it('failure is not caught', function() { + flow.wait(function() { + flow.execute(function() { + flow.execute(throwStubError); + }); + }, 50); + return waitForAbort().then(assertIsStubError); + }); + }); + }); + + describe('errback throws a new error', function() { + it('start with normal promise', function() { + var error = Error('an error'); + return promise.rejected(error). + thenCatch(function(e) { + assert.equal(e, error); + throw new StubError; + }). + thenCatch(assertIsStubError); + }); + + it('start with task result', function() { + var error = Error('an error'); + return flow.execute(function() { + throw error; + }). + thenCatch(function(e) { + assert.equal(e, error); + throw new StubError; + }). + thenCatch(assertIsStubError); + }); + + it('start with normal promise; uncaught error', function() { + var error = Error('an error'); + promise.rejected(error). + thenCatch(function(e) { + assert.equal(e, error); + throw new StubError; + }); + return waitForAbort().then(assertIsStubError); + }); + + it('start with task result; uncaught error', function() { + var error = Error('an error'); + flow.execute(function() { + throw error; + }). + thenCatch(function(e) { + assert.equal(e, error); + throw new StubError; + }); + return waitForAbort().then(assertIsStubError); + }); + }); + + it('thrownPromiseCausesCallbackRejection', function() { + let p = promise.fulfilled(1234); + return promise.fulfilled().then(function() { + throw p; + }).then(assert.fail, function(value) { + assert.strictEqual(p, value); + }); + }); + + describe('task throws promise', function() { + it('promise was fulfilled', function() { + var toThrow = promise.fulfilled(1234); + flow.execute(function() { + throw toThrow; + }).then(assert.fail, function(value) { + assert.equal(toThrow, value); + return toThrow; + }).then(function(value) { + assert.equal(1234, value); + }); + return waitForIdle(); + }); + + it('promise was rejected', function() { + var toThrow = promise.rejected(new StubError); + toThrow.thenCatch(function() {}); // For tearDown. + flow.execute(function() { + throw toThrow; + }).then(assert.fail, function(e) { + assert.equal(toThrow, e); + return e; + }).then(assert.fail, assertIsStubError); + return waitForIdle(); + }); + }); + + it('testFailsTaskIfThereIsAnUnhandledErrorWhileWaitingOnTaskResult', function() { + var d = promise.defer(); + flow.execute(function() { + promise.rejected(new StubError); + return d.promise; + }).then(assert.fail, assertIsStubError); + + return waitForIdle().then(function() { + return d.promise; + }).then(assert.fail, function(e) { + assert.equal('CancellationError: StubError', e.toString()); + }); + }); + + it('testFailsParentTaskIfAsyncScheduledTaskFails', function() { + var d = promise.defer(); + flow.execute(function() { + flow.execute(throwStubError); + return d.promise; + }).then(assert.fail, assertIsStubError); + + return waitForIdle().then(function() { + return d.promise; + }).then(assert.fail, function(e) { + assert.equal('CancellationError: StubError', e.toString()); + }); + }); + + describe('long stack traces', function() { + afterEach(() => promise.LONG_STACK_TRACES = false); + + it('always includes task stacks in failures', function() { + promise.LONG_STACK_TRACES = false; + flow.execute(function() { + flow.execute(function() { + flow.execute(throwStubError, 'throw error'); + }, 'two'); + }, 'three'). + then(assert.fail, function(e) { + assertIsStubError(e); + if (typeof e.stack !== 'string') { + return; + } + var messages = e.stack.split(/\n/).filter(function(line, index) { + return /^From: /.test(line); + }); + assert.deepEqual([ + 'From: Task: throw error', + 'From: Task: two', + 'From: Task: three' + ], messages); + }); + return waitForIdle(); + }); + + it('does not include completed tasks', function () { + flow.execute(function() {}, 'succeeds'); + flow.execute(throwStubError, 'kaboom').then(assert.fail, function(e) { + assertIsStubError(e); + if (typeof e.stack !== 'string') { + return; + } + var messages = e.stack.split(/\n/).filter(function(line, index) { + return /^From: /.test(line); + }); + assert.deepEqual(['From: Task: kaboom'], messages); + }); + return waitForIdle(); + }); + + it('does not include promise chain when disabled', function() { + promise.LONG_STACK_TRACES = false; + flow.execute(function() { + flow.execute(function() { + return promise.fulfilled(). + then(function() {}). + then(function() {}). + then(throwStubError); + }, 'eventually assert.fails'); + }, 'start'). + then(assert.fail, function(e) { + assertIsStubError(e); + if (typeof e.stack !== 'string') { + return; + } + var messages = e.stack.split(/\n/).filter(function(line, index) { + return /^From: /.test(line); + }); + assert.deepEqual([ + 'From: Task: eventually assert.fails', + 'From: Task: start' + ], messages); + }); + return waitForIdle(); + }); + + it('includes promise chain when enabled', function() { + promise.LONG_STACK_TRACES = true; + flow.execute(function() { + flow.execute(function() { + return promise.fulfilled(). + then(function() {}). + then(function() {}). + then(throwStubError); + }, 'eventually assert.fails'); + }, 'start'). + then(assert.fail, function(e) { + assertIsStubError(e); + if (typeof e.stack !== 'string') { + return; + } + var messages = e.stack.split(/\n/).filter(function(line, index) { + return /^From: /.test(line); + }); + assert.deepEqual([ + 'From: Promise: then', + 'From: Task: eventually assert.fails', + 'From: Task: start' + ], messages); + }); + return waitForIdle(); + }); + }); + + it('testFrameCancelsRemainingTasks_onUnhandledTaskFailure', function() { + var run = false; + return flow.execute(function() { + flow.execute(throwStubError); + flow.execute(function() { run = true; }); + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.ok(!run); + }); + }); + + it('testFrameCancelsRemainingTasks_onUnhandledPromiseRejection', function() { + var run = false; + return flow.execute(function() { + promise.rejected(new StubError); + flow.execute(function() { run = true; }); + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.ok(!run); + }); + }); + + it('testRegisteredTaskCallbacksAreDroppedWhenTaskIsCancelled_return', function() { + var seen = []; + return flow.execute(function() { + flow.execute(throwStubError); + + flow.execute(function() { + seen.push(1); + }).then(function() { + seen.push(2); + }, function() { + seen.push(3); + }); + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.deepEqual([], seen); + }); + }); + + it('testRegisteredTaskCallbacksAreDroppedWhenTaskIsCancelled_withReturn', function() { + var seen = []; + return flow.execute(function() { + flow.execute(throwStubError); + + return flow.execute(function() { + seen.push(1); + }).then(function() { + seen.push(2); + }, function() { + seen.push(3); + }); + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.deepEqual([], seen); + }); + }); + + it('testTasksWithinACallbackAreDroppedIfContainingTaskIsAborted', function() { + var seen = []; + return flow.execute(function() { + flow.execute(throwStubError); + + // None of the callbacks on this promise should execute because the + // task assert.failure above is never handled, causing the containing task to + // abort. + promise.fulfilled().then(function() { + seen.push(1); + return flow.execute(function() { + seen.push(2); + }); + }).thenFinally(function() { + seen.push(3); + }); + + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.deepEqual([], seen); + }); + }); + + it('testTaskIsCancelledAfterWaitTimeout', function() { + var seen = []; + return flow.execute(function() { + flow.wait(function() { + return promise.delayed(50); + }, 5); + + return flow.execute(function() { + seen.push(1); + }).then(function() { + seen.push(2); + }, function() { + seen.push(3); + }); + }).then(assert.fail, function() { + assert.deepEqual([], seen); + }); + }); + + describe('task callbacks get cancellation error if registered after task was cancelled', function() { + it('(a)', function() { + var task; + flow.execute(function() { + flow.execute(throwStubError); + task = flow.execute(function() {}); + }).then(assert.fail, assertIsStubError); + return waitForIdle().then(function() { + return task.then(assert.fail, function(e) { + assert.ok(e instanceof promise.CancellationError); + }); + }); + }); + + it('(b)', function() { + var seen = []; + + var task; + flow.execute(function() { + flow.execute(throwStubError); + task = flow.execute(function() {}); + + task.then(() => seen.push(1)) + .then(() => seen.push(2)); + task.then(() => seen.push(3)) + .then(() => seen.push(4)); + + }).then(assert.fail, assertIsStubError); + + return waitForIdle().then(function() { + return task.then(assert.fail, function(e) { + seen.push(5); + assert.ok(e instanceof promise.CancellationError); + }); + }).then(() => assert.deepEqual([5], seen)); + }); + }); + + it('unhandledRejectionInParallelTaskQueue', function() { + var seen = []; + function schedule(name) { + return flow.execute(() => seen.push(name), name); + } + + flow.async(function() { + schedule('a.1'); + flow.execute(throwStubError, 'a.2 (throws)'); + }); + + var b3; + flow.async(function() { + schedule('b.1'); + schedule('b.2'); + b3 = schedule('b.3'); + }); + + var c3; + flow.async(function() { + schedule('c.1'); + schedule('c.2'); + c3 = schedule('c.3'); + }); + + function assertWasCancelled(p) { + return p.then(assert.fail, function(e) { + assert.ok(e instanceof promise.CancellationError); + }); + } + + return waitForAbort() + .then(function() { + assert.deepEqual(['a.1', 'b.1', 'c.1', 'b.2', 'c.2'], seen); + assert.ok(!b3.isPending()); + assert.ok(!c3.isPending()); + }) + .then(() => assertWasCancelled(b3)) + .then(() => assertWasCancelled(c3)); + }); + + it('errorsInAsyncFunctionsAreReportedAsUnhandledRejection', function() { + flow.removeAllListeners(); // For tearDown. + + var task; + return new Promise(function(fulfill) { + flow.once('uncaughtException', fulfill); + flow.async(function() { + task = flow.execute(function() {}); + throw Error('boom'); + }); + }).then(function(error) { + assert.ok(error instanceof promise.CancellationError); + assert.ok(!task.isPending()); + return task.thenCatch(function(error) { + assert.ok(error instanceof promise.CancellationError); + }); + }); + }); + + describe('does not wait for values thrown from callbacks to be resolved', function() { + it('(a)', function() { + var p1 = promise.fulfilled(); + var reason = promise.fulfilled('should not see me'); + return p1.then(function() { + throw reason; + }).then(assert.fail, function(e) { + assert.equal(reason, e); + }); + }); + + it('(b)', function() { + var p1 = promise.fulfilled(); + var reason = promise.rejected('should not see me'); + reason.thenCatch(function() {}); // For tearDown. + return p1.then(function() { + throw reason; + }).then(assert.fail, function(e) { + assert.equal(reason, e); + }); + }); + + it('(c)', function() { + var p1 = promise.fulfilled(); + var reason = promise.defer(); + setTimeout(() => reason.fulfill('should not see me'), 100); + return p1.then(function() { + throw reason.promise; + }).then(assert.fail, function(e) { + assert.equal(reason.promise, e); + }); + }); + + it('(d)', function() { + var p1 = promise.fulfilled(); + var reason = {then: function() {}}; // A thenable like object. + return p1.then(function() { + throw reason; + }).then(assert.fail, function(e) { + assert.equal(reason, e); + }); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_flow_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_flow_test.js new file mode 100644 index 0000000..fd4469d --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_flow_test.js @@ -0,0 +1,2282 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); +const fail = assert.fail; +const sinon = require('sinon'); + +const testutil = require('./testutil'); +const promise = require('../../lib/promise'); + +const NativePromise = Promise; + +// Aliases for readability. +const StubError = testutil.StubError; +const assertIsStubError = testutil.assertIsStubError; +const callbackPair = testutil.callbackPair; +const throwStubError = testutil.throwStubError; + +describe('promise control flow', function() { + let flow, flowHistory, messages, uncaughtExceptions; + + beforeEach(function setUp() { + promise.LONG_STACK_TRACES = false; + flow = new promise.ControlFlow(); + promise.setDefaultFlow(flow); + messages = []; + flowHistory = []; + + uncaughtExceptions = []; + flow.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, + onUncaughtException); + }); + + afterEach(function tearDown() { + flow.removeAllListeners( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION); + assert.deepEqual([], uncaughtExceptions, + 'There were uncaught exceptions'); + flow.reset(); + promise.LONG_STACK_TRACES = false; + }); + + function onUncaughtException(e) { + uncaughtExceptions.push(e); + } + + function waitForAbort(opt_flow) { + var theFlow = opt_flow || flow; + theFlow.removeAllListeners( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION); + return new NativePromise(function(fulfill, reject) { + theFlow.once(promise.ControlFlow.EventType.IDLE, function() { + reject(Error('expected flow to report an unhandled error')); + }); + theFlow.once( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, + fulfill); + }); + } + + function waitForIdle(opt_flow) { + var theFlow = opt_flow || flow; + return new NativePromise(function(fulfill, reject) { + theFlow.once(promise.ControlFlow.EventType.IDLE, fulfill); + theFlow.once( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, reject); + }); + } + + function timeout(ms) { + return new NativePromise(function(fulfill) { + setTimeout(fulfill, ms); + }); + } + + + function schedule(msg, opt_return) { + return scheduleAction(msg, function() { + return opt_return; + }); + } + + /** + * @param {string} value The value to push. + * @param {promise.Promise=} opt_taskPromise Promise to return from + * the task. + * @return {!promise.Promise} The result. + */ + function schedulePush(value, opt_taskPromise) { + return scheduleAction(value, function() { + messages.push(value); + return opt_taskPromise; + }); + } + + /** + * @param {string} msg Debug message. + * @param {!Function} actionFn The function. + * @return {!promise.Promise} The function result. + */ + function scheduleAction(msg, actionFn) { + return promise.controlFlow().execute(function() { + flowHistory.push(msg); + return actionFn(); + }, msg); + } + + /** + * @param {!Function} condition The condition function. + * @param {number=} opt_timeout The timeout. + * @param {string=} opt_message Optional message. + * @return {!promise.Promise} The wait result. + */ + function scheduleWait(condition, opt_timeout, opt_message) { + var msg = opt_message || ''; + // It's not possible to hook into when the wait itself is scheduled, so + // we record each iteration of the wait loop. + var count = 0; + return promise.controlFlow().wait(function() { + flowHistory.push((count++) + ': ' + msg); + return condition(); + }, opt_timeout, msg); + } + + function asyncRun(fn, opt_self) { + NativePromise.resolve().then(() => fn.call(opt_self)); + } + + function assertFlowHistory(var_args) { + var expected = Array.prototype.slice.call(arguments, 0); + assert.deepEqual(expected, flowHistory); + } + + function assertMessages(var_args) { + var expected = Array.prototype.slice.call(arguments, 0); + assert.deepEqual(expected, messages); + } + + function assertingMessages(var_args) { + var args = Array.prototype.slice.call(arguments, 0); + return () => assertMessages.apply(null, args); + } + + function assertFlowIs(flow) { + assert.equal(flow, promise.controlFlow()); + } + + describe('testScheduling', function() { + it('aSimpleFunction', function() { + schedule('go'); + return waitForIdle().then(function() { + assertFlowHistory('go'); + }); + }); + + it('aSimpleFunctionWithANonPromiseReturnValue', function() { + schedule('go', 123).then(function(value) { + assert.equal(123, value); + }); + return waitForIdle().then(function() { + assertFlowHistory('go'); + }); + }); + + it('aSimpleSequence', function() { + schedule('a'); + schedule('b'); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('invokesCallbacksWhenTaskIsDone', function() { + var d = new promise.Deferred(); + var called = false; + var done = schedule('a', d.promise).then(function(value) { + called = true; + assert.equal(123, value); + }); + return timeout(5).then(function() { + assert.ok(!called); + d.fulfill(123); + return done; + }). + then(function() { + assertFlowHistory('a'); + }); + }); + + it('blocksUntilPromiseReturnedByTaskIsResolved', function() { + var done = promise.defer(); + schedulePush('a', done.promise); + schedulePush('b'); + setTimeout(function() { + done.fulfill(); + messages.push('c'); + }, 25); + return waitForIdle().then(assertingMessages('a', 'c', 'b')); + }); + + it('waitsForReturnedPromisesToResolve', function() { + var d1 = new promise.Deferred(); + var d2 = new promise.Deferred(); + + var callback = sinon.spy(); + schedule('a', d1.promise).then(callback); + + return timeout(5).then(function() { + assert(!callback.called); + d1.fulfill(d2); + return timeout(5); + }).then(function() { + assert(!callback.called); + d2.fulfill('fluffy bunny'); + return waitForIdle(); + }).then(function() { + assert(callback.called); + assert.equal('fluffy bunny', callback.getCall(0).args[0]); + assertFlowHistory('a'); + }); + }); + + it('executesTasksInAFutureTurnAfterTheyAreScheduled', function() { + var count = 0; + function incr() { count++; } + + scheduleAction('', incr); + assert.equal(0, count); + return waitForIdle().then(function() { + assert.equal(1, count); + }); + }); + + it('executesOneTaskPerTurnOfTheEventLoop', function() { + var order = []; + function go() { + order.push(order.length / 2); + asyncRun(function() { + order.push('-'); + }); + } + + scheduleAction('', go); + scheduleAction('', go); + return waitForIdle().then(function() { + assert.deepEqual([0, '-', 1, '-'], order); + }) + }); + + it('firstScheduledTaskIsWithinACallback', function() { + promise.fulfilled().then(function() { + schedule('a'); + schedule('b'); + schedule('c'); + }).then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + return waitForIdle(); + }); + + it('newTasksAddedWhileWaitingOnTaskReturnedPromise1', function() { + scheduleAction('a', function() { + var d = promise.defer(); + setTimeout(function() { + schedule('c'); + d.fulfill(); + }, 10); + return d.promise; + }); + schedule('b'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('newTasksAddedWhileWaitingOnTaskReturnedPromise2', function() { + scheduleAction('a', function() { + var d = promise.defer(); + setTimeout(function() { + schedule('c'); + asyncRun(d.fulfill); + }, 10); + return d.promise; + }); + schedule('b'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'b'); + }); + }); + }); + + describe('testFraming', function() { + it('callbacksRunInANewFrame', function() { + schedule('a').then(function() { + schedule('c'); + }); + schedule('b'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'b'); + }); + }); + + it('lotsOfNesting', function() { + schedule('a').then(function() { + schedule('c').then(function() { + schedule('e').then(function() { + schedule('g'); + }); + schedule('f'); + }); + schedule('d'); + }); + schedule('b'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'e', 'g', 'f', 'd', 'b'); + }); + }); + + it('callbackReturnsPromiseThatDependsOnATask_1', function() { + schedule('a').then(function() { + schedule('b'); + return promise.delayed(5).then(function() { + return schedule('c'); + }); + }); + schedule('d'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd'); + }); + }); + + it('callbackReturnsPromiseThatDependsOnATask_2', function() { + schedule('a').then(function() { + schedule('b'); + return promise.delayed(5). + then(function() { return promise.delayed(5) }). + then(function() { return promise.delayed(5) }). + then(function() { return promise.delayed(5) }). + then(function() { return schedule('c'); }); + }); + schedule('d'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd'); + }); + }); + + it('eachCallbackWaitsForAllScheduledTasksToComplete', function() { + schedule('a'). + then(function() { + schedule('b'); + schedule('c'); + }). + then(function() { + schedule('d'); + }); + schedule('e'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('eachCallbackWaitsForReturnTasksToComplete', function() { + schedule('a'). + then(function() { + schedule('b'); + return schedule('c'); + }). + then(function() { + schedule('d'); + }); + schedule('e'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('callbacksOnAResolvedPromiseInsertIntoTheCurrentFlow', function() { + promise.fulfilled().then(function() { + schedule('b'); + }); + schedule('a'); + + return waitForIdle().then(function() { + assertFlowHistory('b', 'a'); + }); + }); + + it('callbacksInterruptTheFlowWhenPromiseIsResolved', function() { + schedule('a').then(function() { + schedule('c'); + }); + schedule('b'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'b'); + }); + }); + + it('allCallbacksInAFrameAreScheduledWhenPromiseIsResolved', function() { + var a = schedule('a'); + a.then(function() { schedule('b'); }); + schedule('c'); + a.then(function() { schedule('d'); }); + schedule('e'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('tasksScheduledInInActiveFrameDoNotGetPrecedence', function() { + var d = promise.fulfilled(); + schedule('a'); + schedule('b'); + d.then(function() { schedule('c'); }); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('tasksScheduledInAFrameGetPrecedence_1', function() { + var a = schedule('a'); + schedule('b').then(function() { + a.then(function() { + schedule('c'); + schedule('d'); + }); + var e = schedule('e'); + a.then(function() { + schedule('f'); + e.then(function() { + schedule('g'); + }); + schedule('h'); + }); + schedule('i'); + }); + schedule('j'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'); + }); + }); + }); + + describe('testErrorHandling', function() { + it('thrownErrorsArePassedToTaskErrback', function() { + scheduleAction('function that throws', throwStubError). + then(fail, assertIsStubError); + return waitForIdle(); + }); + + it('thrownErrorsPropagateThroughPromiseChain', function() { + scheduleAction('function that throws', throwStubError). + then(fail). + then(fail, assertIsStubError); + return waitForIdle(); + }); + + it('catchesErrorsFromFailedTasksInAFrame', function() { + schedule('a').then(function() { + schedule('b'); + scheduleAction('function that throws', throwStubError); + }). + then(fail, assertIsStubError); + return waitForIdle(); + }); + + it('abortsIfOnlyTaskReturnsAnUnhandledRejection', function() { + scheduleAction('function that returns rejected promise', function() { + return promise.rejected(new StubError); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('abortsIfThereIsAnUnhandledRejection', function() { + promise.rejected(new StubError); + schedule('this should not run'); + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory(/* none */); + }); + }); + + it('abortsSequenceIfATaskFails', function() { + schedule('a'); + schedule('b'); + scheduleAction('c', throwStubError); + schedule('d'); // Should never execute. + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('abortsFromUnhandledFramedTaskFailures_1', function() { + schedule('outer task').then(function() { + scheduleAction('inner task', throwStubError); + }); + schedule('this should not run'); + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('outer task', 'inner task'); + }); + }); + + it('abortsFromUnhandledFramedTaskFailures_2', function() { + schedule('a').then(function() { + schedule('b').then(function() { + scheduleAction('c', throwStubError); + // This should not execute. + schedule('d'); + }); + }); + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject', function() { + var callback = sinon.spy(); + + scheduleAction('', function() { + var obj = {'foo': promise.rejected(new StubError)}; + return promise.fullyResolved(obj).then(callback); + }); + + return waitForAbort(). + then(assertIsStubError). + then(() => assert(!callback.called)); + }); + + it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject_withCallback', function() { + var callback1 = sinon.spy(); + var callback2 = sinon.spy(); + + scheduleAction('', function() { + var obj = {'foo': promise.rejected(new StubError)}; + return promise.fullyResolved(obj).then(callback1); + }).then(callback2); + + return waitForAbort(). + then(assertIsStubError). + then(() => assert(!callback1.called)). + then(() => assert(!callback2.called)); + }); + + it('canCatchErrorsFromNestedTasks', function() { + var errback = sinon.spy(); + schedule('a'). + then(function() { + return scheduleAction('b', throwStubError); + }). + thenCatch(errback); + return waitForIdle().then(function() { + assert(errback.called); + assertIsStubError(errback.getCall(0).args[0]); + }); + }); + + it('nestedCommandFailuresCanBeCaughtAndSuppressed', function() { + var errback = sinon.spy(); + schedule('a').then(function() { + return schedule('b').then(function() { + return schedule('c').then(function() { + throw new StubError; + }); + }); + }).thenCatch(errback); + schedule('d'); + return waitForIdle(). + then(function() { + assert(errback.called); + assertIsStubError(errback.getCall(0).args[0]); + assertFlowHistory('a', 'b', 'c', 'd'); + }); + }); + + it('aTaskWithAnUnhandledPromiseRejection', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + promise.rejected(new StubError); + }); + schedule('should never run'); + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'sub-tasks'); + }); + }); + + it('aTaskThatReutrnsARejectedPromise', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + return promise.rejected(new StubError); + }); + schedule('should never run'); + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'sub-tasks'); + }); + }); + + it('discardsSubtasksIfTaskThrows', function() { + var pair = callbackPair(null, assertIsStubError); + scheduleAction('a', function() { + schedule('b'); + schedule('c'); + throwStubError(); + }).then(pair.callback, pair.errback); + schedule('d'); + + return waitForIdle(). + then(pair.assertErrback). + then(function() { + assertFlowHistory('a', 'd'); + }); + }); + + it('discardsRemainingSubtasksIfASubtaskFails', function() { + var pair = callbackPair(null, assertIsStubError); + scheduleAction('a', function() { + schedule('b'); + scheduleAction('c', throwStubError); + schedule('d'); + }).then(pair.callback, pair.errback); + schedule('e'); + + return waitForIdle(). + then(pair.assertErrback). + then(function() { + assertFlowHistory('a', 'b', 'c', 'e'); + }); + }); + }); + + describe('testTryModelingFinally', function() { + it('happyPath', function() { + /* Model: + try { + doFoo(); + doBar(); + } finally { + doBaz(); + } + */ + schedulePush('foo'). + then(() => schedulePush('bar')). + thenFinally(() => schedulePush('baz')); + return waitForIdle().then(assertingMessages('foo', 'bar', 'baz')); + }); + + it('firstTryFails', function() { + /* Model: + try { + doFoo(); + doBar(); + } finally { + doBaz(); + } + */ + + scheduleAction('doFoo and throw', function() { + messages.push('foo'); + throw new StubError; + }). + then(function() { schedulePush('bar'); }). + thenFinally(function() { schedulePush('baz'); }); + + return waitForAbort(). + then(assertIsStubError). + then(assertingMessages('foo', 'baz')); + }); + + it('secondTryFails', function() { + /* Model: + try { + doFoo(); + doBar(); + } finally { + doBaz(); + } + */ + + schedulePush('foo'). + then(function() { + return scheduleAction('doBar and throw', function() { + messages.push('bar'); + throw new StubError; + }); + }). + thenFinally(function() { + return schedulePush('baz'); + }); + return waitForAbort(). + then(assertIsStubError). + then(assertingMessages('foo', 'bar', 'baz')); + }); + }); + + describe('testTaskCallbacksInterruptFlow', function() { + it('(base case)', function() { + schedule('a').then(function() { + schedule('b'); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskDependsOnImmediatelyFulfilledPromise', function() { + scheduleAction('a', function() { + return promise.fulfilled(); + }).then(function() { + schedule('b'); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskDependsOnPreviouslyFulfilledPromise', function() { + var aPromise = promise.fulfilled(123); + scheduleAction('a', function() { + return aPromise; + }).then(function(value) { + assert.equal(123, value); + schedule('b'); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskDependsOnAsyncPromise', function() { + scheduleAction('a', function() { + return promise.delayed(25); + }).then(function() { + schedule('b'); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('promiseChainedToTaskInterruptFlow', function() { + schedule('a').then(function() { + return promise.fulfilled(); + }).then(function() { + return promise.fulfilled(); + }).then(function() { + schedule('b'); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('nestedTaskCallbacksInterruptFlowWhenResolved', function() { + schedule('a').then(function() { + schedule('b').then(function() { + schedule('c'); + }); + }); + schedule('d'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd'); + }); + }); + }); + + describe('testDelayedNesting', function() { + + it('1', function() { + var a = schedule('a'); + schedule('b').then(function() { + a.then(function() { schedule('c'); }); + schedule('d'); + }); + schedule('e'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('2', function() { + var a = schedule('a'); + schedule('b').then(function() { + a.then(function() { schedule('c'); }); + schedule('d'); + a.then(function() { schedule('e'); }); + }); + schedule('f'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f'); + }); + }); + + it('3', function() { + var a = schedule('a'); + schedule('b').then(function() { + a.then(function() { schedule('c'); }); + a.then(function() { schedule('d'); }); + }); + schedule('e'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('4', function() { + var a = schedule('a'); + schedule('b').then(function() { + a.then(function() { schedule('c'); }).then(function() { + schedule('d'); + }); + a.then(function() { schedule('e'); }); + }); + schedule('f'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f'); + }); + }); + + it('5', function() { + var a = schedule('a'); + schedule('b').then(function() { + var c; + a.then(function() { c = schedule('c'); }).then(function() { + schedule('d'); + a.then(function() { schedule('e'); }); + c.then(function() { schedule('f'); }); + schedule('g'); + }); + a.then(function() { schedule('h'); }); + }); + schedule('i'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'); + }); + }); + }); + + describe('testWaiting', function() { + it('onAConditionThatIsAlwaysTrue', function() { + scheduleWait(function() { return true;}, 0, 'waiting on true'); + return waitForIdle().then(function() { + assertFlowHistory('0: waiting on true'); + }); + }); + + it('aSimpleCountingCondition', function() { + var count = 0; + scheduleWait(function() { + return ++count == 3; + }, 100, 'counting to 3'); + + return waitForIdle().then(function() { + assert.equal(3, count); + }); + }); + + it('aConditionThatReturnsAPromise', function() { + var d = new promise.Deferred(); + var count = 0; + + scheduleWait(function() { + count += 1; + return d.promise; + }, 0, 'waiting for promise'); + + return timeout(50).then(function() { + assert.equal(1, count); + d.fulfill(123); + return waitForIdle(); + }); + }); + + it('aConditionThatReturnsAPromise_2', function() { + var count = 0; + scheduleWait(function() { + return promise.fulfilled(++count == 3); + }, 100, 'waiting for promise'); + + return waitForIdle().then(function() { + assert.equal(3, count); + }); + }); + + it('aConditionThatReturnsATaskResult', function() { + var count = 0; + scheduleWait(function() { + return scheduleAction('increment count', function() { + return ++count == 3; + }); + }, 100, 'counting to 3'); + schedule('post wait'); + + return waitForIdle().then(function() { + assert.equal(3, count); + assertFlowHistory( + '0: counting to 3', 'increment count', + '1: counting to 3', 'increment count', + '2: counting to 3', 'increment count', + 'post wait'); + }); + }); + + it('conditionContainsASubtask', function() { + var count = 0; + scheduleWait(function() { + schedule('sub task'); + return ++count == 3; + }, 100, 'counting to 3'); + schedule('post wait'); + + return waitForIdle().then(function() { + assert.equal(3, count); + assertFlowHistory( + '0: counting to 3', 'sub task', + '1: counting to 3', 'sub task', + '2: counting to 3', 'sub task', + 'post wait'); + }); + }); + + it('cancelsWaitIfScheduledTaskFails', function() { + var pair = callbackPair(null, assertIsStubError); + scheduleWait(function() { + scheduleAction('boom', throwStubError); + schedule('this should not run'); + return true; + }, 100, 'waiting to go boom').then(pair.callback, pair.errback); + schedule('post wait'); + + return waitForIdle(). + then(pair.assertErrback). + then(function() { + assertFlowHistory( + '0: waiting to go boom', 'boom', + 'post wait'); + }); + }); + + it('failsIfConditionThrows', function() { + var callbacks = callbackPair(null, assertIsStubError); + scheduleWait(throwStubError, 0, 'goes boom'). + then(callbacks.callback, callbacks.errback); + schedule('post wait'); + + return waitForIdle(). + then(callbacks.assertErrback). + then(function() { + assertFlowHistory('0: goes boom', 'post wait'); + }); + }); + + it('failsIfConditionReturnsARejectedPromise', function() { + var callbacks = callbackPair(null, assertIsStubError); + scheduleWait(function() { + return promise.rejected(new StubError); + }, 0, 'goes boom').then(callbacks.callback, callbacks.errback); + schedule('post wait'); + + return waitForIdle(). + then(callbacks.assertErrback). + then(function() { + assertFlowHistory('0: goes boom', 'post wait'); + }); + }); + + it('failsIfConditionHasUnhandledRejection', function() { + var callbacks = callbackPair(null, assertIsStubError); + scheduleWait(function() { + promise.controlFlow().execute(throwStubError); + }, 0, 'goes boom').then(callbacks.callback, callbacks.errback); + schedule('post wait'); + + return waitForIdle(). + then(callbacks.assertErrback). + then(function() { + assertFlowHistory('0: goes boom', 'post wait'); + }); + }); + + it('failsIfConditionHasAFailedSubtask', function() { + var callbacks = callbackPair(null, assertIsStubError); + var count = 0; + scheduleWait(function() { + scheduleAction('maybe throw', function() { + if (++count == 2) { + throw new StubError; + } + }); + }, 100, 'waiting').then(callbacks.callback, callbacks.errback); + schedule('post wait'); + + return waitForIdle().then(function() { + assert.equal(2, count); + assertFlowHistory( + '0: waiting', 'maybe throw', + '1: waiting', 'maybe throw', + 'post wait'); + }); + }); + + it('pollingLoopWaitsForAllScheduledTasksInCondition', function() { + var count = 0; + scheduleWait(function() { + scheduleAction('increment count', function() { ++count; }); + return count >= 3; + }, 100, 'counting to 3'); + schedule('post wait'); + + return waitForIdle().then(function() { + assert.equal(4, count); + assertFlowHistory( + '0: counting to 3', 'increment count', + '1: counting to 3', 'increment count', + '2: counting to 3', 'increment count', + '3: counting to 3', 'increment count', + 'post wait'); + }); + }); + + it('waitsForeverOnAZeroTimeout', function() { + var done = false; + setTimeout(function() { + done = true; + }, 150); + var waitResult = scheduleWait(function() { + return done; + }, 0); + + return timeout(75).then(function() { + assert.ok(!done); + return timeout(100); + }).then(function() { + assert.ok(done); + return waitResult; + }); + }); + + it('waitsForeverIfTimeoutOmitted', function() { + var done = false; + setTimeout(function() { + done = true; + }, 150); + var waitResult = scheduleWait(function() { + return done; + }); + + return timeout(75).then(function() { + assert.ok(!done); + return timeout(100); + }).then(function() { + assert.ok(done); + return waitResult; + }); + }); + + it('timesOut_nonZeroTimeout', function() { + var count = 0; + scheduleWait(function() { + count += 1; + var ms = count === 2 ? 65 : 5; + return promise.delayed(ms).then(function() { + return false; + }); + }, 60, 'counting to 3'); + return waitForAbort().then(function(e) { + switch (count) { + case 1: + assertFlowHistory('0: counting to 3'); + break; + case 2: + assertFlowHistory('0: counting to 3', '1: counting to 3'); + break; + default: + fail('unexpected polling count: ' + count); + } + assert.ok( + /^counting to 3\nWait timed out after \d+ms$/.test(e.message)); + }); + }); + + it('shouldFailIfConditionReturnsARejectedPromise', function() { + scheduleWait(function() { + return promise.rejected(new StubError); + }, 100, 'returns rejected promise on first pass'); + return waitForAbort().then(assertIsStubError); + }); + + it('scheduleWithIntermittentWaits', function() { + schedule('a'); + scheduleWait(function() { return true; }, 0, 'wait 1'); + schedule('b'); + scheduleWait(function() { return true; }, 0, 'wait 2'); + schedule('c'); + scheduleWait(function() { return true; }, 0, 'wait 3'); + + return waitForIdle().then(function() { + assertFlowHistory('a', '0: wait 1', 'b', '0: wait 2', 'c', '0: wait 3'); + }); + }); + + it('scheduleWithIntermittentAndNestedWaits', function() { + schedule('a'); + scheduleWait(function() { return true; }, 0, 'wait 1'). + then(function() { + schedule('d'); + scheduleWait(function() { return true; }, 0, 'wait 2'); + schedule('e'); + }); + schedule('b'); + scheduleWait(function() { return true; }, 0, 'wait 3'); + schedule('c'); + scheduleWait(function() { return true; }, 0, 'wait 4'); + + return waitForIdle().then(function() { + assertFlowHistory( + 'a', '0: wait 1', 'd', '0: wait 2', 'e', 'b', '0: wait 3', 'c', + '0: wait 4'); + }); + }); + + it('requiresConditionToBeAPromiseOrFunction', function() { + assert.throws(function() { + flow.wait(1234, 0); + }); + flow.wait(function() { return true;}, 0); + flow.wait(promise.fulfilled(), 0); + return waitForIdle(); + }); + + it('promiseThatDoesNotResolveBeforeTimeout', function() { + var d = promise.defer(); + flow.wait(d.promise, 5).then(fail, function(e) { + assert.ok( + /Timed out waiting for promise to resolve after \d+ms/ + .test(e.message), + 'unexpected error message: ' + e.message); + }); + return waitForIdle().then(function() { + assert.ok('Promise should not be cancelled', d.promise.isPending()); + }); + }); + + it('unboundedWaitOnPromiseResolution', function() { + var messages = []; + var d = promise.defer(); + var waitResult = flow.wait(d.promise).then(function(value) { + messages.push('b'); + assert.equal(1234, value); + }); + setTimeout(function() { + messages.push('a'); + }, 5); + + timeout(10).then(function() { + assert.deepEqual(['a'], messages); + assert.ok(waitResult.isPending()); + d.fulfill(1234); + return waitResult; + }).then(function() { + assert.deepEqual(['a', 'b'], messages); + }); + + return waitForIdle(); + }); + }); + + describe('testSubtasks', function() { + it('(base case)', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + schedule('c'); + schedule('d'); + }); + schedule('b'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'sub-tasks', 'c', 'd', 'b'); + }); + }); + + it('nesting', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + schedule('b'); + scheduleAction('sub-sub-tasks', function() { + schedule('c'); + schedule('d'); + }); + schedule('e'); + }); + schedule('f'); + + return waitForIdle().then(function() { + assertFlowHistory( + 'a', 'sub-tasks', 'b', 'sub-sub-tasks', 'c', 'd', 'e', 'f'); + }); + }); + + it('taskReturnsSubTaskResult_1', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + return schedule('c'); + }); + schedule('b'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'sub-tasks', 'c', 'b'); + }); + }); + + it('taskReturnsSubTaskResult_2', function() { + let pair = callbackPair((value) => assert.equal(123, value)); + schedule('a'); + schedule('sub-tasks', promise.fulfilled(123)).then(pair.callback); + schedule('b'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'sub-tasks','b'); + pair.assertCallback(); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_1', function() { + scheduleAction('a', function() { + return promise.delayed(10).then(function() { + schedule('b'); + }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_2', function() { + scheduleAction('a', function() { + return promise.fulfilled().then(function() { + schedule('b'); + }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_3', function() { + scheduleAction('a', function() { + return promise.delayed(10).then(function() { + return schedule('b'); + }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_4', function() { + scheduleAction('a', function() { + return promise.delayed(5).then(function() { + return promise.delayed(5).then(function() { + return schedule('b'); + }); + }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_5', function() { + scheduleAction('a', function() { + return promise.delayed(5).then(function() { + return promise.delayed(5).then(function() { + return promise.delayed(5).then(function() { + return promise.delayed(5).then(function() { + return schedule('b'); + }); + }); + }); + }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_6', function() { + scheduleAction('a', function() { + return promise.delayed(5). + then(function() { return promise.delayed(5) }). + then(function() { return promise.delayed(5) }). + then(function() { return promise.delayed(5) }). + then(function() { return schedule('b'); }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('subTaskFails_1', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + scheduleAction('sub-task that fails', throwStubError); + }); + schedule('should never execute'); + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'sub-tasks', 'sub-task that fails'); + }); + }); + + it('subTaskFails_2', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + return promise.rejected(new StubError); + }); + schedule('should never execute'); + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'sub-tasks'); + }); + }); + + it('subTaskFails_3', function() { + var callbacks = callbackPair(null, assertIsStubError); + + schedule('a'); + scheduleAction('sub-tasks', function() { + return promise.rejected(new StubError); + }).then(callbacks.callback, callbacks.errback); + schedule('b'); + + return waitForIdle(). + then(function() { + assertFlowHistory('a', 'sub-tasks', 'b'); + callbacks.assertErrback(); + }); + }); + }); + + describe('testEventLoopWaitsOnPendingPromiseRejections', function() { + it('oneRejection', function() { + var d = new promise.Deferred; + scheduleAction('one', function() { + return d.promise; + }); + scheduleAction('two', function() {}); + + return timeout(50).then(function() { + assertFlowHistory('one'); + d.reject(new StubError); + return waitForAbort(); + }). + then(assertIsStubError). + then(function() { + assertFlowHistory('one'); + }); + }); + + it('multipleRejections', function() { + var once = Error('once'); + var twice = Error('twice'); + + scheduleAction('one', function() { + promise.rejected(once); + promise.rejected(twice); + }); + var twoResult = scheduleAction('two', function() {}); + + flow.removeAllListeners( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION); + return new NativePromise(function(fulfill, reject) { + setTimeout(function() { + reject(Error('Should have reported the two errors by now')); + }, 50); + flow.on( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, + fulfill); + }).then(function(e) { + assert.ok(e instanceof promise.MultipleUnhandledRejectionError, + 'Not a MultipleUnhandledRejectionError'); + let errors = Array.from(e.errors); + assert.deepEqual([once, twice], errors); + assertFlowHistory('one'); + assert.ok(!twoResult.isPending(), 'Did not cancel the second task'); + }); + }); + }); + + describe('testCancelsPromiseReturnedByCallbackIfFrameFails', function() { + it('promiseCallback', function() { + var chainPair = callbackPair(null, assertIsStubError); + var deferredPair = callbackPair(null, function(e) { + assert.equal('CancellationError: StubError', e.toString(), + 'callback result should be cancelled'); + }); + + var d = new promise.Deferred(); + d.then(deferredPair.callback, deferredPair.errback); + + promise.fulfilled(). + then(function() { + scheduleAction('boom', throwStubError); + schedule('this should not run'); + return d.promise; + }). + then(chainPair.callback, chainPair.errback); + + return waitForIdle().then(function() { + assertFlowHistory('boom'); + chainPair.assertErrback('chain errback not invoked'); + deferredPair.assertErrback('deferred errback not invoked'); + }); + }); + + it('taskCallback', function() { + var chainPair = callbackPair(null, assertIsStubError); + var deferredPair = callbackPair(null, function(e) { + assert.equal('CancellationError: StubError', e.toString(), + 'callback result should be cancelled'); + }); + + var d = new promise.Deferred(); + d.then(deferredPair.callback, deferredPair.errback); + + schedule('a'). + then(function() { + scheduleAction('boom', throwStubError); + schedule('this should not run'); + return d.promise; + }). + then(chainPair.callback, chainPair.errback); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'boom'); + chainPair.assertErrback('chain errback not invoked'); + deferredPair.assertErrback('deferred errback not invoked'); + }); + }); + }); + + it('testMaintainsOrderInCallbacksWhenATaskReturnsAPromise', function() { + schedule('__start__', promise.fulfilled()). + then(function() { + messages.push('a'); + schedulePush('b'); + messages.push('c'); + }). + then(function() { + messages.push('d'); + }); + schedulePush('e'); + + return waitForIdle().then(function() { + assertFlowHistory('__start__', 'b', 'e'); + assertMessages('a', 'c', 'b', 'd', 'e'); + }); + }); + + it('testOwningFlowIsActivatedForExecutingTasks', function() { + var defaultFlow = promise.controlFlow(); + var order = []; + + promise.createFlow(function(flow) { + assertFlowIs(flow); + order.push(0); + + defaultFlow.execute(function() { + assertFlowIs(defaultFlow); + order.push(1); + }); + }); + + return waitForIdle().then(function() { + assertFlowIs(defaultFlow); + assert.deepEqual([0, 1], order); + }); + }); + + it('testCreateFlowReturnsPromisePairedWithCreatedFlow', function() { + return new NativePromise(function(fulfill, reject) { + var newFlow; + promise.createFlow(function(flow) { + newFlow = flow; + assertFlowIs(newFlow); + }).then(function() { + assertFlowIs(newFlow); + waitForIdle(newFlow).then(fulfill, reject); + }); + }); + }); + + it('testDeferredFactoriesCreateForActiveFlow_defaultFlow', function() { + var e = Error(); + var defaultFlow = promise.controlFlow(); + promise.fulfilled().then(function() { + assertFlowIs(defaultFlow); + }); + promise.rejected(e).then(null, function(err) { + assert.equal(e, err); + assertFlowIs(defaultFlow); + }); + promise.defer().then(function() { + assertFlowIs(defaultFlow); + }); + + return waitForIdle(); + }); + + it('testDeferredFactoriesCreateForActiveFlow_newFlow', function() { + var e = Error(); + var newFlow = new promise.ControlFlow; + newFlow.execute(function() { + promise.fulfilled().then(function() { + assertFlowIs(newFlow); + }); + + promise.rejected(e).then(null, function(err) { + assert.equal(e, err); + assertFlowIs(newFlow); + }); + + promise.defer().then(function() { + assertFlowIs(newFlow); + }); + }).then(function() { + assertFlowIs(newFlow); + }); + + return waitForIdle(newFlow); + }); + + it('testFlowsSynchronizeWithThemselvesNotEachOther', function() { + var defaultFlow = promise.controlFlow(); + schedulePush('a', 'a'); + promise.controlFlow().timeout(250); + schedulePush('b', 'b'); + + promise.createFlow(function() { + schedulePush('c', 'c'); + schedulePush('d', 'd'); + }); + + return waitForIdle().then(function() { + assertMessages('a', 'c', 'd', 'b'); + }); + }); + + it('testUnhandledErrorsAreReportedToTheOwningFlow', function() { + var error1 = Error('e1'); + var error2 = Error('e2'); + + var defaultFlow = promise.controlFlow(); + defaultFlow.removeAllListeners('uncaughtException'); + + var flow1Error = NativePromise.defer(); + flow1Error.promise.then(function(value) { + assert.equal(error2, value); + }); + + var flow2Error = NativePromise.defer(); + flow2Error.promise.then(function(value) { + assert.equal(error1, value); + }); + + promise.createFlow(function(flow) { + flow.once('uncaughtException', flow2Error.resolve); + promise.rejected(error1); + + defaultFlow.once('uncaughtException', flow1Error.resolve); + defaultFlow.execute(function() { + promise.rejected(error2); + }); + }); + + return NativePromise.all([flow1Error.promise, flow2Error.promise]); + }); + + it('testCanSynchronizeFlowsByReturningPromiseFromOneToAnother', function() { + var flow1 = new promise.ControlFlow; + var flow1Done = NativePromise.defer(); + flow1.once('idle', flow1Done.resolve); + flow1.once('uncaughtException', flow1Done.reject); + + var flow2 = new promise.ControlFlow; + var flow2Done = NativePromise.defer(); + flow2.once('idle', flow2Done.resolve); + flow2.once('uncaughtException', flow2Done.reject); + + flow1.execute(function() { + schedulePush('a', 'a'); + return promise.delayed(25); + }, 'start flow 1'); + + flow2.execute(function() { + schedulePush('b', 'b'); + schedulePush('c', 'c'); + flow2.execute(function() { + return flow1.execute(function() { + schedulePush('d', 'd'); + }, 'flow 1 task'); + }, 'inject flow1 result into flow2'); + schedulePush('e', 'e'); + }, 'start flow 2'); + + return NativePromise.all([flow1Done.promise, flow2Done.promise]). + then(function() { + assertMessages('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('testFramesWaitToCompleteForPendingRejections', function() { + return new NativePromise(function(fulfill, reject) { + + promise.controlFlow().execute(function() { + promise.rejected(new StubError); + }).then(fulfill, reject); + + }). + then(() => fail('expected to fail'), assertIsStubError); + }); + + it('testSynchronizeErrorsPropagateToOuterFlow', function() { + var outerFlow = new promise.ControlFlow; + var innerFlow = new promise.ControlFlow; + + var block = NativePromise.defer(); + innerFlow.execute(function() { + return block.promise; + }, 'block inner flow'); + + outerFlow.execute(function() { + block.resolve(); + return innerFlow.execute(function() { + promise.rejected(new StubError); + }, 'trigger unhandled rejection error'); + }, 'run test'); + + return NativePromise.all([ + waitForIdle(innerFlow), + waitForAbort(outerFlow).then(assertIsStubError) + ]); + }); + + it('testFailsIfErrbackThrows', function() { + promise.rejected('').then(null, throwStubError); + return waitForAbort().then(assertIsStubError); + }); + + it('testFailsIfCallbackReturnsRejectedPromise', function() { + promise.fulfilled().then(function() { + return promise.rejected(new StubError); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('testAbortsFrameIfTaskFails', function() { + promise.fulfilled().then(function() { + promise.controlFlow().execute(throwStubError); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('testAbortsFramePromisedChainedFromTaskIsNotHandled', function() { + promise.fulfilled().then(function() { + promise.controlFlow().execute(function() {}). + then(throwStubError); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('testTrapsChainedUnhandledRejectionsWithinAFrame', function() { + var pair = callbackPair(null, assertIsStubError); + promise.fulfilled().then(function() { + promise.controlFlow().execute(function() {}). + then(throwStubError); + }).then(pair.callback, pair.errback); + + return waitForIdle().then(pair.assertErrback); + }); + + it('testCancelsRemainingTasksIfFrameThrowsDuringScheduling', function() { + var task1, task2; + var pair = callbackPair(null, assertIsStubError); + var flow = promise.controlFlow(); + flow.execute(function() { + task1 = flow.execute(function() {}); + task2 = flow.execute(function() {}); + throw new StubError; + }).then(pair.callback, pair.errback); + + return waitForIdle(). + then(pair.assertErrback). + then(function() { + assert.ok(!task1.isPending()); + pair = callbackPair(); + return task1.then(pair.callback, pair.errback); + }). + then(function() { + pair.assertErrback(); + assert.ok(!task2.isPending()); + pair = callbackPair(); + return task2.then(pair.callback, pair.errback); + }). + then(function() { + pair.assertErrback(); + }); + }); + + it('testCancelsRemainingTasksInFrameIfATaskFails', function() { + var task; + var pair = callbackPair(null, assertIsStubError); + var flow = promise.controlFlow(); + flow.execute(function() { + flow.execute(throwStubError); + task = flow.execute(function() {}); + }).then(pair.callback, pair.errback); + + return waitForIdle().then(pair.assertErrback).then(function() { + assert.ok(!task.isPending()); + pair = callbackPair(); + task.then(pair.callback, pair.errback); + }).then(function() { + pair.assertErrback(); + }); + }); + + it('testDoesNotModifyRejectionErrorIfPromiseNotInsideAFlow', function() { + var error = Error('original message'); + var originalStack = error.stack; + var originalStr = error.toString(); + + var pair = callbackPair(null, function(e) { + assert.equal(error, e); + assert.equal('original message', e.message); + assert.equal(originalStack, e.stack); + assert.equal(originalStr, e.toString()); + }); + + promise.rejected(error).then(pair.callback, pair.errback); + return waitForIdle().then(pair.assertErrback); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/444 */ + it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_1', function() { + var messages = []; + flow.execute(function() { + return promise.fulfilled(['a', 'b', 'c', 'd']); + }, 'start').then(function(steps) { + steps.forEach(function(step) { + promise.fulfilled(step) + .then(function() { + messages.push(step + '.1'); + }).then(function() { + messages.push(step + '.2'); + }); + }) + }); + return waitForIdle().then(function() { + assert.deepEqual( + ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'], + messages); + }); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/444 */ + it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_2', function() { + var messages = []; + flow.execute(function() { + return promise.fulfilled(['a', 'b', 'c', 'd']); + }, 'start').then(function(steps) { + steps.forEach(function(step) { + promise.fulfilled(step) + .then(function() { + messages.push(step + '.1'); + }).then(function() { + flow.execute(function() {}, step + '.2').then(function() { + messages.push(step + '.2'); + }); + }); + }) + }); + return waitForIdle().then(function() { + assert.deepEqual( + ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'], + messages); + }); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/444 */ + it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_3', function() { + var messages = []; + flow.execute(function() { + return promise.fulfilled(['a', 'b', 'c', 'd']); + }, 'start').then(function(steps) { + steps.forEach(function(step) { + promise.fulfilled(step) + .then(function(){}) + .then(function() { + messages.push(step + '.1'); + return flow.execute(function() {}, step + '.1'); + }).then(function() { + flow.execute(function() {}, step + '.2').then(function(text) { + messages.push(step + '.2'); + }); + }); + }) + }); + return waitForIdle().then(function() { + assert.deepEqual( + ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'], + messages); + }); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/363 */ + it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() { + scheduleAction('a', () => promise.delayed(10)); + schedule('b'); + setTimeout(() => schedule('c'), 0); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'b'); + }); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/363 */ + it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() { + scheduleAction('a', () => promise.delayed(10)); + schedule('b'); + schedule('c'); + setTimeout(function() { + schedule('d'); + scheduleAction('e', () => promise.delayed(10)); + schedule('f'); + }, 0); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'd', 'e', 'b', 'c', 'f'); + }); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/363 */ + it('testCanSynchronizeTasksFromAdjacentTaskQueues', function() { + var task1 = scheduleAction('a', () => promise.delayed(10)); + schedule('b'); + setTimeout(function() { + scheduleAction('c', () => task1); + schedule('d'); + }, 0); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'd', 'b'); + }); + }); + + describe('testCancellingAScheduledTask', function() { + it('1', function() { + var called = false; + var task1 = scheduleAction('a', () => called = true); + task1.cancel('no soup for you'); + + return waitForIdle().then(function() { + assert.ok(!called); + assertFlowHistory(); + return task1.thenCatch(function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('no soup for you', e.message); + }); + }); + }); + + it('2', function() { + schedule('a'); + var called = false; + var task2 = scheduleAction('b', () => called = true); + schedule('c'); + + task2.cancel('no soup for you'); + + return waitForIdle().then(function() { + assert.ok(!called); + assertFlowHistory('a', 'c'); + return task2.thenCatch(function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('no soup for you', e.message); + }); + }); + }); + + it('3', function() { + var called = false; + var task = scheduleAction('a', () => called = true); + task.cancel(new StubError); + + return waitForIdle().then(function() { + assert.ok(!called); + assertFlowHistory(); + return task.thenCatch(function(e) { + assert.ok(e instanceof promise.CancellationError); + }); + }); + }); + + it('4', function() { + var seen = []; + var task = scheduleAction('a', () => seen.push(1)) + .then(() => seen.push(2)) + .then(() => seen.push(3)) + .then(() => seen.push(4)) + .then(() => seen.push(5)); + task.cancel(new StubError); + + return waitForIdle().then(function() { + assert.deepEqual([], seen); + assertFlowHistory(); + return task.thenCatch(function(e) { + assert.ok(e instanceof promise.CancellationError); + }); + }); + }); + + it('fromWithinAnExecutingTask', function() { + var called = false; + var task; + scheduleAction('a', function() { + task.cancel('no soup for you'); + }); + task = scheduleAction('b', () => called = true); + schedule('c'); + + return waitForIdle().then(function() { + assert.ok(!called); + assertFlowHistory('a', 'c'); + return task.thenCatch(function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('no soup for you', e.message); + }); + }); + }); + }); + + it('testCancellingAPendingTask', function() { + var order = []; + var unresolved = promise.defer(); + + var innerTask; + var outerTask = scheduleAction('a', function() { + order.push(1); + + // Schedule a task that will never finish. + innerTask = scheduleAction('a.1', function() { + return unresolved.promise; + }); + + // Since the outerTask is cancelled below, innerTask should be cancelled + // with a DiscardedTaskError, which means its callbacks are silently + // dropped - so this should never execute. + innerTask.thenCatch(function(e) { + order.push(2); + }); + }); + schedule('b'); + + outerTask.thenCatch(function(e) { + order.push(3); + assert.ok(e instanceof promise.CancellationError); + assert.equal('no soup for you', e.message); + }); + + unresolved.promise.thenCatch(function(e) { + order.push(4); + assert.ok(e instanceof promise.CancellationError); + }); + + return timeout(10).then(function() { + assert.deepEqual([1], order); + assert.ok(unresolved.promise.isPending()); + + outerTask.cancel('no soup for you'); + return waitForIdle(); + }).then(function() { + assertFlowHistory('a', 'a.1', 'b'); + assert.deepEqual([1, 3, 4], order); + }); + }); + + it('testCancellingAPendingPromiseCallback', function() { + var called = false; + + var root = promise.fulfilled(); + root.then(function() { + cb2.cancel('no soup for you'); + }); + + var cb2 = root.then(fail, fail); // These callbacks should never be called. + cb2.then(fail, function(e) { + called = true; + assert.ok(e instanceof promise.CancellationError); + assert.equal('no soup for you', e.message); + }); + + return waitForIdle().then(function() { + assert.ok(called); + }); + }); + + describe('testResetFlow', function() { + it('1', function() { + var called = 0; + var task = flow.execute(() => called++); + task.thenFinally(() => called++); + + return new Promise(function(fulfill) { + flow.once('reset', fulfill); + flow.reset(); + + }).then(function() { + assert.equal(0, called); + assert.ok(!task.isPending()); + return task; + + }).then(fail, function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('ControlFlow was reset', e.message); + }); + }); + + it('2', function() { + var called = 0; + var task1 = flow.execute(() => called++); + task1.thenFinally(() => called++); + + var task2 = flow.execute(() => called++); + task2.thenFinally(() => called++); + + var task3 = flow.execute(() => called++); + task3.thenFinally(() => called++); + + return new Promise(function(fulfill) { + flow.once('reset', fulfill); + flow.reset(); + + }).then(function() { + assert.equal(0, called); + assert.ok(!task1.isPending()); + assert.ok(!task2.isPending()); + assert.ok(!task3.isPending()); + }); + }); + }); + + describe('testPromiseFulfilledInsideTask', function() { + it('1', function() { + var order = []; + + flow.execute(function() { + var d = promise.defer(); + + d.promise.then(() => order.push('a')); + d.promise.then(() => order.push('b')); + d.promise.then(() => order.push('c')); + d.fulfill(); + + flow.execute(() => order.push('d')); + + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order); + }); + }); + + it('2', function() { + var order = []; + + flow.execute(function() { + flow.execute(() => order.push('a')); + flow.execute(() => order.push('b')); + + var d = promise.defer(); + d.promise.then(() => order.push('c')); + d.promise.then(() => order.push('d')); + d.fulfill(); + + flow.execute(() => order.push('e')); + + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'fin'], order); + }); + }); + + it('3', function() { + var order = []; + var d = promise.defer(); + d.promise.then(() => order.push('c')); + d.promise.then(() => order.push('d')); + + flow.execute(function() { + flow.execute(() => order.push('a')); + flow.execute(() => order.push('b')); + + d.promise.then(() => order.push('e')); + d.fulfill(); + + flow.execute(() => order.push('f')); + + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['c', 'd', 'a', 'b', 'e', 'f', 'fin'], order); + }); + }); + + it('4', function() { + var order = []; + var d = promise.defer(); + d.promise.then(() => order.push('a')); + d.promise.then(() => order.push('b')); + + flow.execute(function() { + flow.execute(function() { + order.push('c'); + flow.execute(() => order.push('d')); + d.promise.then(() => order.push('e')); + }); + flow.execute(() => order.push('f')); + + d.promise.then(() => order.push('g')); + d.fulfill(); + + flow.execute(() => order.push('h')); + + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'fin'], order); + }); + }); + }); + + describe('testSettledPromiseCallbacksInsideATask', function() { + it('1', function() { + var order = []; + var p = promise.fulfilled(); + + flow.execute(function() { + flow.execute(() => order.push('a')); + p.then(() => order.push('b')); + flow.execute(() => order.push('c')); + p.then(() => order.push('d')); + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order); + }); + }); + + it('2', function() { + var order = []; + + flow.execute(function() { + flow.execute(() => order.push('a')) + .then( () => order.push('c')); + flow.execute(() => order.push('b')); + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'c', 'b', 'fin'], order); + }); + }); + }); + + it('testTasksDoNotWaitForNewlyCreatedPromises', function() { + var order = []; + + flow.execute(function() { + var d = promise.defer(); + + // This is a normal promise, not a task, so the task for this callback is + // considered volatile. Volatile tasks should be skipped when they reach + // the front of the task queue. + d.promise.then(() => order.push('a')); + + flow.execute(() => order.push('b')); + flow.execute(function() { + flow.execute(() => order.push('c')); + d.promise.then(() => order.push('d')); + d.fulfill(); + }); + flow.execute(() => order.push('e')); + + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['b', 'a', 'c', 'd', 'e', 'fin'], order); + }); + }); + + it('testCallbackDependenciesDoNotDeadlock', function() { + var order = []; + var root = promise.defer(); + var dep = promise.fulfilled().then(function() { + order.push('a'); + return root.promise.then(function() { + order.push('b'); + }); + }); + // This callback depends on |dep|, which depends on another callback + // attached to |root| via a chain. + root.promise.then(function() { + order.push('c'); + return dep.then(() => order.push('d')); + }).then(() => order.push('fin')); + + setTimeout(() => root.fulfill(), 20); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_generator_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_generator_test.js new file mode 100644 index 0000000..44568c9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_generator_test.js @@ -0,0 +1,308 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); +const promise = require('../../lib/promise'); + +describe('promise.consume()', function() { + it('requires inputs to be generator functions', function() { + assert.throws(function() { + promise.consume(function() {}); + }); + }); + + it('handles a basic generator with no yielded promises', function() { + var values = []; + return promise.consume(function* () { + var i = 0; + while (i < 4) { + i = yield i + 1; + values.push(i); + } + }).then(function() { + assert.deepEqual([1, 2, 3, 4], values); + }); + }); + + it('handles a promise yielding generator', function() { + var values = []; + return promise.consume(function* () { + var i = 0; + while (i < 4) { + // Test that things are actually async here. + setTimeout(function() { + values.push(i * 2); + }, 10); + + yield promise.delayed(10).then(function() { + values.push(i++); + }); + } + }).then(function() { + assert.deepEqual([0, 0, 2, 1, 4, 2, 6, 3], values); + }); + }); + + it('assignemnts to yielded promises get fulfilled value', function() { + return promise.consume(function* () { + var p = promise.fulfilled(2); + var x = yield p; + assert.equal(2, x); + }); + }); + + it('is possible to cancel promise generators', function() { + var values = []; + var p = promise.consume(function* () { + var i = 0; + while (i < 3) { + yield promise.delayed(100).then(function() { + values.push(i++); + }); + } + }); + return promise.delayed(75).then(function() { + p.cancel(); + return p.thenCatch(function() { + return promise.delayed(300); + }); + }).then(function() { + assert.deepEqual([0], values); + }); + }); + + it('uses final return value as fulfillment value', function() { + return promise.consume(function* () { + yield 1; + yield 2; + return 3; + }).then(function(value) { + assert.equal(3, value); + }); + }); + + it('throws rejected promise errors within the generator', function() { + var values = []; + return promise.consume(function* () { + values.push('a'); + var e = Error('stub error'); + try { + yield promise.rejected(e); + values.push('b'); + } catch (ex) { + assert.equal(e, ex); + values.push('c'); + } + values.push('d'); + }).then(function() { + assert.deepEqual(['a', 'c', 'd'], values); + }); + }); + + it('aborts the generator if there is an unhandled rejection', function() { + var values = []; + var e = Error('stub error'); + return promise.consume(function* () { + values.push(1); + yield promise.rejected(e); + values.push(2); + }).thenCatch(function() { + assert.deepEqual([1], values); + }); + }); + + it('yield waits for promises', function() { + var values = []; + var d = promise.defer(); + + setTimeout(function() { + assert.deepEqual([1], values); + d.fulfill(2); + }, 100); + + return promise.consume(function* () { + values.push(1); + values.push((yield d.promise), 3); + }).then(function() { + assert.deepEqual([1, 2, 3], values); + }); + }); + + it('accepts custom scopes', function() { + return promise.consume(function* () { + return this.name; + }, {name: 'Bob'}).then(function(value) { + assert.equal('Bob', value); + }); + }); + + it('accepts initial generator arguments', function() { + return promise.consume(function* (a, b) { + assert.equal('red', a); + assert.equal('apples', b); + }, null, 'red', 'apples'); + }); + + it('executes generator within the control flow', function() { + var promises = [ + promise.defer(), + promise.defer() + ]; + var values = []; + + setTimeout(function() { + assert.deepEqual([], values); + promises[0].fulfill(1); + }, 100); + + setTimeout(function() { + assert.deepEqual([1], values); + promises[1].fulfill(2); + }, 200); + + return promise.controlFlow().execute(function* () { + values.push(yield promises[0].promise); + values.push(yield promises[1].promise); + values.push('fin'); + }).then(function() { + assert.deepEqual([1, 2, 'fin'], values); + }); + }); + + it('handles tasks scheduled in generator', function() { + var flow = promise.controlFlow(); + return flow.execute(function* () { + var x = yield flow.execute(function() { + return promise.delayed(10).then(function() { + return 1; + }); + }); + + var y = yield flow.execute(function() { + return 2; + }); + + return x + y; + }).then(function(value) { + assert.equal(3, value); + }); + }); + + it('blocks the control flow while processing generator', function() { + var values = []; + return promise.controlFlow().wait(function* () { + yield values.push(1); + values.push(yield promise.delayed(10).then(function() { + return 2; + })); + yield values.push(3); + return values.length === 6; + }, 250).then(function() { + assert.deepEqual([1, 2, 3, 1, 2, 3], values); + }); + }); + + it('ControlFlow.wait() will timeout on long generator', function() { + var values = []; + return promise.controlFlow().wait(function* () { + var i = 0; + while (i < 3) { + yield promise.delayed(100).then(function() { + values.push(i++); + }); + } + }, 75).thenCatch(function() { + assert.deepEqual( + [0, 1, 2], values, 'Should complete one loop of wait condition'); + }); + }); + + describe('generators in promise callbacks', function() { + it('works with no initial value', function() { + var promises = [ + promise.defer(), + promise.defer() + ]; + var values = []; + + setTimeout(function() { + promises[0].fulfill(1); + }, 50); + + setTimeout(function() { + promises[1].fulfill(2); + }, 100); + + return promise.fulfilled().then(function*() { + values.push(yield promises[0].promise); + values.push(yield promises[1].promise); + values.push('fin'); + }).then(function() { + assert.deepEqual([1, 2, 'fin'], values); + }); + }); + + it('starts the generator with promised value', function() { + var promises = [ + promise.defer(), + promise.defer() + ]; + var values = []; + + setTimeout(function() { + promises[0].fulfill(1); + }, 50); + + setTimeout(function() { + promises[1].fulfill(2); + }, 100); + + return promise.fulfilled(3).then(function*(value) { + var p1 = yield promises[0].promise; + var p2 = yield promises[1].promise; + values.push(value + p1); + values.push(value + p2); + values.push('fin'); + }).then(function() { + assert.deepEqual([4, 5, 'fin'], values); + }); + }); + + it('throws yielded rejections within the generator callback', function() { + var d = promise.defer(); + var e = Error('stub'); + + setTimeout(function() { + d.reject(e); + }, 50); + + return promise.fulfilled().then(function*() { + var threw = false; + try { + yield d.promise; + } catch (ex) { + threw = true; + assert.equal(e, ex); + } + assert.ok(threw); + }); + }); + }); +}); + diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_test.js new file mode 100644 index 0000000..ed6d965 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/promise_test.js @@ -0,0 +1,996 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); + +const testutil = require('./testutil'); +const promise = require('../../lib/promise'); + +// Aliases for readability. +const NativePromise = Promise; +const StubError = testutil.StubError; +const assertIsStubError = testutil.assertIsStubError; +const callbackHelper = testutil.callbackHelper; +const callbackPair = testutil.callbackPair; +const throwStubError = testutil.throwStubError; +const fail = () => assert.fail(); + +// Refer to promise_aplus_test for promise compliance with standard behavior. +describe('promise', function() { + var app, uncaughtExceptions; + + beforeEach(function setUp() { + promise.LONG_STACK_TRACES = false; + uncaughtExceptions = []; + + app = promise.controlFlow(); + app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, + (e) => uncaughtExceptions.push(e)); + }); + + afterEach(function tearDown() { + app.reset(); + promise.setDefaultFlow(new promise.ControlFlow); + assert.deepEqual([], uncaughtExceptions, + 'Did not expect any uncaught exceptions'); + promise.LONG_STACK_TRACES = false; + }); + + const assertIsPromise = (p) => assert.ok(promise.isPromise(p)); + const assertNotPromise = (v) => assert.ok(!promise.isPromise(v)); + + function createRejectedPromise(reason) { + var p = promise.rejected(reason); + p.thenCatch(function() {}); + return p; + } + + it('testCanDetectPromiseLikeObjects', function() { + assertIsPromise(new promise.Promise(function(fulfill) { + fulfill(); + })); + assertIsPromise(new promise.Deferred()); + assertIsPromise(new promise.Deferred().promise); + assertIsPromise({then:function() {}}); + + assertNotPromise(undefined); + assertNotPromise(null); + assertNotPromise(''); + assertNotPromise(true); + assertNotPromise(false); + assertNotPromise(1); + assertNotPromise({}); + assertNotPromise({then:1}); + assertNotPromise({then:true}); + assertNotPromise({then:''}); + }); + + describe('then', function() { + it('returnsOwnPromiseIfNoCallbacksWereGiven', function() { + var deferred = new promise.Deferred(); + assert.equal(deferred.promise, deferred.promise.then()); + assert.equal(deferred.promise, deferred.promise.thenCatch()); + assert.equal(deferred.promise, promise.when(deferred.promise)); + }); + + it('stillConsideredUnHandledIfNoCallbacksWereGivenOnCallsToThen', function() { + promise.rejected(new StubError).then(); + var handler = callbackHelper(assertIsStubError); + + // so tearDown() doesn't throw + app.removeAllListeners(); + app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler); + return NativePromise.resolve().then(() => handler.assertCalled()); + }); + }); + + describe('thenFinally', function() { + it('nonFailingCallbackDoesNotSuppressOriginalError', function() { + var done = callbackHelper(assertIsStubError); + return promise.rejected(new StubError). + thenFinally(function() {}). + thenCatch(done). + thenFinally(done.assertCalled); + }); + + it('failingCallbackSuppressesOriginalError', function() { + var done = callbackHelper(assertIsStubError); + return promise.rejected(new Error('original')). + thenFinally(throwStubError). + thenCatch(done). + thenFinally(done.assertCalled); + }); + + it('callbackThrowsAfterFulfilledPromise', function() { + var done = callbackHelper(assertIsStubError); + return promise.fulfilled(). + thenFinally(throwStubError). + thenCatch(done). + thenFinally(done.assertCalled); + }); + + it('callbackReturnsRejectedPromise', function() { + var done = callbackHelper(assertIsStubError); + return promise.fulfilled(). + thenFinally(function() { + return promise.rejected(new StubError); + }). + thenCatch(done). + thenFinally(done.assertCalled); + }); + }); + + describe('cancel', function() { + it('passesTheCancellationReasonToReject', function() { + var d = new promise.Deferred(); + var res = d.then(assert.fail, function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('because i said so', e.message); + }); + d.cancel('because i said so'); + return res; + }); + + it('canCancelADeferredFromAChainedPromise', function() { + var d = new promise.Deferred(); + var p = d.then(assert.fail, function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('because i said so', e.message); + }); + var p2 = p.then(function() {}, assert.fail); + + p.cancel('because i said so'); + return p2; + }); + + it('canCancelATimeout', function() { + var p = promise.delayed(25) + .then(assert.fail, (e) => e instanceof promise.CancellationError); + setTimeout(() => p.cancel(), 20); + p.cancel(); + return p; + }); + + it('cancelIsANoopOnceAPromiseHasBeenFulfilled', function() { + var p = promise.fulfilled(123); + p.cancel(); + return p.then((v) => assert.equal(123, v)); + }); + + it('cancelIsANoopOnceAPromiseHasBeenRejected', function() { + var p = promise.rejected(new StubError); + p.cancel(); + + var pair = callbackPair(null, assertIsStubError); + return p.then(assert.fail, assertIsStubError); + }); + + it('noopCancelTriggeredOnCallbackOfResolvedPromise', function() { + var d = promise.defer(); + var p = d.promise.then(); + + d.fulfill(); + p.cancel(); // This should not throw. + return p; // This should not trigger a failure. + }); + }); + + describe('when', function() { + it('ReturnsAResolvedPromiseIfGivenANonPromiseValue', function() { + var ret = promise.when('abc'); + assertIsPromise(ret); + return ret.then((value) => assert.equal('abc', value)); + }); + + it('PassesRawErrorsToCallbacks', function() { + var error = new Error('boo!'); + return promise.when(error, function(value) { + assert.equal(error, value); + }); + }); + + it('WaitsForValueToBeResolvedBeforeInvokingCallback', function() { + var d = new promise.Deferred(), callback; + let result = promise.when(d, callback = callbackHelper(function(value) { + assert.equal('hi', value); + })); + callback.assertNotCalled(); + d.fulfill('hi'); + return result.then(callback.assertCalled); + }); + + it('canCancelReturnedPromise', function() { + var callbacks = callbackPair(null, function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('just because', e.message); + }); + + var promiseLike = { + then: function(cb, eb) { + this.callback = cb; + this.errback = eb; + } + }; + + var aPromise = promise.when(promiseLike, + callbacks.callback, callbacks.errback); + + assert.ok(aPromise.isPending()); + aPromise.cancel('just because'); + + return aPromise.thenFinally(callbacks.assertErrback); + }); + }); + + it('firesUncaughtExceptionEventIfRejectionNeverHandled', function() { + promise.rejected(new StubError); + var handler = callbackHelper(assertIsStubError); + + // so tearDown() doesn't throw + app.removeAllListeners(); + app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler); + + return NativePromise.resolve().then(handler.assertCalled); + }); + + it('cannotResolveADeferredWithItself', function() { + var deferred = new promise.Deferred(); + assert.throws(() => deferred.fulfill(deferred)); + assert.throws(() => deferred.reject(deferred)); + }); + + describe('fullyResolved', function() { + it('primitives', function() { + function runTest(value) { + var callback, errback; + return promise.fullyResolved(value) + .then((resolved) => assert.equal(value, resolved)); + } + return runTest(true) + .then(() => runTest(function() {})) + .then(() => runTest(null)) + .then(() => runTest(123)) + .then(() => runTest('foo bar')) + .then(() => runTest(undefined)); + }); + + it('arrayOfPrimitives', function() { + var fn = function() {}; + var array = [true, fn, null, 123, '', undefined, 1]; + return promise.fullyResolved(array).then(function(resolved) { + assert.equal(array, resolved); + assert.deepEqual([true, fn, null, 123, '', undefined, 1], + resolved); + }); + }); + + it('nestedArrayOfPrimitives', function() { + var fn = function() {}; + var array = [true, [fn, null, 123], '', undefined]; + return promise.fullyResolved(array) + .then(function(resolved) { + assert.equal(array, resolved); + assert.deepEqual([true, [fn, null, 123], '', undefined], resolved); + assert.deepEqual([fn, null, 123], resolved[1]); + }); + }); + + it('arrayWithPromisedPrimitive', function() { + return promise.fullyResolved([promise.fulfilled(123)]) + .then(function(resolved) { + assert.deepEqual([123], resolved); + }); + }); + + it('promiseResolvesToPrimitive', function() { + return promise.fullyResolved(promise.fulfilled(123)) + .then((resolved) => assert.equal(123, resolved)); + }); + + it('promiseResolvesToArray', function() { + var fn = function() {}; + var array = [true, [fn, null, 123], '', undefined]; + var aPromise = promise.fulfilled(array); + + var result = promise.fullyResolved(aPromise); + return result.then(function(resolved) { + assert.equal(array, resolved); + assert.deepEqual([true, [fn, null, 123], '', undefined], + resolved); + assert.deepEqual([fn, null, 123], resolved[1]); + }); + }); + + it('promiseResolvesToArrayWithPromises', function() { + var nestedPromise = promise.fulfilled(123); + var aPromise = promise.fulfilled([true, nestedPromise]); + return promise.fullyResolved(aPromise) + .then(function(resolved) { + assert.deepEqual([true, 123], resolved); + }); + }); + + it('rejectsIfArrayPromiseRejects', function() { + var nestedPromise = createRejectedPromise(new StubError); + var aPromise = promise.fulfilled([true, nestedPromise]); + + var pair = callbackPair(null, assertIsStubError); + return promise.fullyResolved(aPromise) + .then(assert.fail, assertIsStubError); + }); + + it('rejectsOnFirstArrayRejection', function() { + var e1 = new Error('foo'); + var e2 = new Error('bar'); + var aPromise = promise.fulfilled([ + createRejectedPromise(e1), + createRejectedPromise(e2) + ]); + + return promise.fullyResolved(aPromise) + .then(assert.fail, function(error) { + assert.strictEqual(e1, error); + }); + }); + + it('rejectsIfNestedArrayPromiseRejects', function() { + var aPromise = promise.fulfilled([ + promise.fulfilled([ + createRejectedPromise(new StubError) + ]) + ]); + + return promise.fullyResolved(aPromise) + .then(assert.fail, assertIsStubError); + }); + + it('simpleHash', function() { + var hash = {'a': 123}; + return promise.fullyResolved(hash) + .then(function(resolved) { + assert.strictEqual(hash, resolved); + assert.deepEqual(hash, {'a': 123}); + }); + }); + + it('nestedHash', function() { + var nestedHash = {'foo':'bar'}; + var hash = {'a': 123, 'b': nestedHash}; + + return promise.fullyResolved(hash) + .then(function(resolved) { + assert.strictEqual(hash, resolved); + assert.deepEqual({'a': 123, 'b': {'foo': 'bar'}}, resolved); + assert.strictEqual(nestedHash, resolved['b']); + }); + }); + + it('promiseResolvesToSimpleHash', function() { + var hash = {'a': 123}; + var aPromise = promise.fulfilled(hash); + + return promise.fullyResolved(aPromise) + .then((resolved) => assert.strictEqual(hash, resolved)); + }); + + it('promiseResolvesToNestedHash', function() { + var nestedHash = {'foo':'bar'}; + var hash = {'a': 123, 'b': nestedHash}; + var aPromise = promise.fulfilled(hash); + + return promise.fullyResolved(aPromise) + .then(function(resolved) { + assert.strictEqual(hash, resolved); + assert.strictEqual(nestedHash, resolved['b']); + assert.deepEqual(hash, {'a': 123, 'b': {'foo': 'bar'}}); + }); + }); + + it('promiseResolvesToHashWithPromises', function() { + var aPromise = promise.fulfilled({ + 'a': promise.fulfilled(123) + }); + + return promise.fullyResolved(aPromise) + .then(function(resolved) { + assert.deepEqual({'a': 123}, resolved); + }); + }); + + it('rejectsIfHashPromiseRejects', function() { + var aPromise = promise.fulfilled({ + 'a': createRejectedPromise(new StubError) + }); + + return promise.fullyResolved(aPromise) + .then(assert.fail, assertIsStubError); + }); + + it('rejectsIfNestedHashPromiseRejects', function() { + var aPromise = promise.fulfilled({ + 'a': {'b': createRejectedPromise(new StubError)} + }); + + return promise.fullyResolved(aPromise) + .then(assert.fail, assertIsStubError); + }); + + it('instantiatedObject', function() { + function Foo() { + this.bar = 'baz'; + } + var foo = new Foo; + + return promise.fullyResolved(foo).then(function(resolvedFoo) { + assert.equal(foo, resolvedFoo); + assert.ok(resolvedFoo instanceof Foo); + assert.deepEqual(new Foo, resolvedFoo); + }); + }); + + it('withEmptyArray', function() { + return promise.fullyResolved([]).then(function(resolved) { + assert.deepEqual([], resolved); + }); + }); + + it('withEmptyHash', function() { + return promise.fullyResolved({}).then(function(resolved) { + assert.deepEqual({}, resolved); + }); + }); + + it('arrayWithPromisedHash', function() { + var obj = {'foo': 'bar'}; + var array = [promise.fulfilled(obj)]; + + return promise.fullyResolved(array).then(function(resolved) { + assert.deepEqual(resolved, [obj]); + }); + }); + }); + + describe('checkedNodeCall', function() { + it('functionThrows', function() { + return promise.checkedNodeCall(throwStubError) + .then(assert.fail, assertIsStubError); + }); + + it('functionReturnsAnError', function() { + return promise.checkedNodeCall(function(callback) { + callback(new StubError); + }).then(assert.fail, assertIsStubError); + }); + + it('functionReturnsSuccess', function() { + var success = 'success!'; + return promise.checkedNodeCall(function(callback) { + callback(null, success); + }).then((value) => assert.equal(success, value)); + }); + + it('functionReturnsAndThrows', function() { + var error = new Error('boom'); + var error2 = new Error('boom again'); + return promise.checkedNodeCall(function(callback) { + callback(error); + throw error2; + }).then(assert.fail, (e) => assert.equal(error, e)); + }); + + it('functionThrowsAndReturns', function() { + var error = new Error('boom'); + var error2 = new Error('boom again'); + return promise.checkedNodeCall(function(callback) { + setTimeout(() => callback(error), 10); + throw error2; + }).then(assert.fail, (e) => assert.equal(error2, e)); + }); + }); + + describe('all', function() { + it('(base case)', function() { + var a = [ + 0, 1, + promise.defer(), + promise.defer(), + 4, 5, 6 + ]; + delete a[5]; + + var pair = callbackPair(function(value) { + assert.deepEqual([0, 1, 2, 3, 4, undefined, 6], value); + }); + + var result = promise.all(a).then(pair.callback, pair.errback); + pair.assertNeither(); + + a[2].fulfill(2); + pair.assertNeither(); + + a[3].fulfill(3); + return result.then(() => pair.assertCallback()); + }); + + it('empty array', function() { + return promise.all([]).then((a) => assert.deepEqual([], a)); + }); + + it('usesFirstRejection', function() { + var a = [ + promise.defer(), + promise.defer() + ]; + + var result = promise.all(a).then(assert.fail, assertIsStubError); + a[1].reject(new StubError); + setTimeout(() => a[0].reject(Error('ignored')), 0); + return result; + }); + }); + + describe('map', function() { + it('(base case)', function() { + var a = [1, 2, 3]; + return promise.map(a, function(value, index, a2) { + assert.equal(a, a2); + assert.equal('number', typeof index, 'not a number'); + return value + 1; + }).then(function(value) { + assert.deepEqual([2, 3, 4], value); + }); + }); + + it('omitsDeleted', function() { + var a = [0, 1, 2, 3, 4, 5, 6]; + delete a[1]; + delete a[3]; + delete a[4]; + delete a[6]; + + var expected = [0, 1, 4, 9, 16, 25, 36]; + delete expected[1]; + delete expected[3]; + delete expected[4]; + delete expected[6]; + + return promise.map(a, function(value) { + return value * value; + }).then(function(value) { + assert.deepEqual(expected, value); + }); + }); + + it('emptyArray', function() { + return promise.map([], function(value) { + return value + 1; + }).then(function(value) { + assert.deepEqual([], value); + }); + }); + + it('inputIsPromise', function() { + var input = promise.defer(); + var result = promise.map(input, function(value) { + return value + 1; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual([2, 3, 4], value); + }); + result = result.then(pair.callback, pair.errback); + + setTimeout(function() { + pair.assertNeither(); + input.fulfill([1, 2, 3]); + }, 10); + + return result; + }); + + it('waitsForFunctionResultToResolve', function() { + var innerResults = [ + promise.defer(), + promise.defer() + ]; + + var result = promise.map([1, 2], function(value, index) { + return innerResults[index].promise; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual(['a', 'b'], value); + }); + result = result.then(pair.callback, pair.errback); + + return NativePromise.resolve() + .then(function() { + pair.assertNeither(); + innerResults[0].fulfill('a'); + }) + .then(function() { + pair.assertNeither(); + innerResults[1].fulfill('b'); + return result; + }) + .then(pair.assertCallback); + }); + + it('rejectsPromiseIfFunctionThrows', function() { + return promise.map([1], throwStubError) + .then(assert.fail, assertIsStubError); + }); + + it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() { + return promise.map([1], function() { + return promise.rejected(new StubError); + }).then(assert.fail, assertIsStubError); + }); + + it('stopsCallingFunctionIfPreviousIterationFailed', function() { + var count = 0; + return promise.map([1, 2, 3, 4], function() { + count++; + if (count == 3) { + throw new StubError; + } + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.equal(3, count); + }); + }); + + it('rejectsWithFirstRejectedPromise', function() { + var innerResult = [ + promise.fulfilled(), + createRejectedPromise(new StubError), + createRejectedPromise(Error('should be ignored')) + ]; + var count = 0; + return promise.map([1, 2, 3, 4], function(value, index) { + count += 1; + return innerResult[index]; + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.equal(2, count); + }); + }); + + it('preservesOrderWhenMapReturnsPromise', function() { + var deferreds = [ + promise.defer(), + promise.defer(), + promise.defer(), + promise.defer() + ]; + var result = promise.map(deferreds, function(value) { + return value.promise; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual([0, 1, 2, 3], value); + }); + result = result.then(pair.callback, pair.errback); + + return NativePromise.resolve() + .then(function() { + pair.assertNeither(); + for (let i = deferreds.length; i > 0; i -= 1) { + deferreds[i - 1].fulfill(i - 1); + } + return result; + }).then(pair.assertCallback); + }); + }); + + describe('filter', function() { + it('basicFiltering', function() { + var a = [0, 1, 2, 3]; + return promise.filter(a, function(val, index, a2) { + assert.equal(a, a2); + assert.equal('number', typeof index, 'not a number'); + return val > 1; + }).then(function(val) { + assert.deepEqual([2, 3], val); + }); + }); + + it('omitsDeleted', function() { + var a = [0, 1, 2, 3, 4, 5, 6]; + delete a[3]; + delete a[4]; + + return promise.filter(a, function(value) { + return value > 1 && value < 6; + }).then(function(val) { + assert.deepEqual([2, 5], val); + }); + }); + + it('preservesInputs', function() { + var a = [0, 1, 2, 3]; + + return promise.filter(a, function(value, i, a2) { + assert.equal(a, a2); + // Even if a function modifies the input array, the original value + // should be inserted into the new array. + a2[i] = a2[i] - 1; + return a2[i] >= 1; + }).then(function(val) { + assert.deepEqual([2, 3], val); + }); + }); + + it('inputIsPromise', function() { + var input = promise.defer(); + var result = promise.filter(input, function(value) { + return value > 1 && value < 3; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual([2], value); + }); + result = result.then(pair.callback, pair.errback); + return NativePromise.resolve() + .then(function() { + pair.assertNeither(); + input.fulfill([1, 2, 3]); + return result; + }) + .then(pair.assertCallback); + }); + + it('waitsForFunctionResultToResolve', function() { + var innerResults = [ + promise.defer(), + promise.defer() + ]; + + var result = promise.filter([1, 2], function(value, index) { + return innerResults[index].promise; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual([2], value); + }); + result = result.then(pair.callback, pair.errback); + return NativePromise.resolve() + .then(function() { + pair.assertNeither(); + innerResults[0].fulfill(false); + }) + .then(function() { + pair.assertNeither(); + innerResults[1].fulfill(true); + return result; + }) + .then(pair.assertCallback); + }); + + it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() { + return promise.filter([1], function() { + return promise.rejected(new StubError); + }).then(assert.fail, assertIsStubError); + }); + + it('stopsCallingFunctionIfPreviousIterationFailed', function() { + var count = 0; + return promise.filter([1, 2, 3, 4], function() { + count++; + if (count == 3) { + throw new StubError; + } + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.equal(3, count); + }); + }); + + it('rejectsWithFirstRejectedPromise', function() { + var innerResult = [ + promise.fulfilled(), + createRejectedPromise(new StubError), + createRejectedPromise(Error('should be ignored')) + ]; + + return promise.filter([1, 2, 3, 4], function(value, index) { + assert.ok(index < innerResult.length); + return innerResult[index]; + }).then(assert.fail, assertIsStubError); + }); + + it('preservesOrderWhenFilterReturnsPromise', function() { + var deferreds = [ + promise.defer(), + promise.defer(), + promise.defer(), + promise.defer() + ]; + var result = promise.filter([0, 1, 2, 3], function(value, index) { + return deferreds[index].promise; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual([1, 2], value); + }); + result = result.then(pair.callback, pair.errback); + + return NativePromise.resolve() + .then(function() { + pair.assertNeither(); + for (let i = deferreds.length - 1; i >= 0; i -= 1) { + deferreds[i].fulfill(i > 0 && i < 3); + } + return result; + }).then(pair.assertCallback); + }); + }); + + it('testAddThenableImplementation', function() { + function tmp() {} + assert.ok(!promise.Thenable.isImplementation(new tmp())); + promise.Thenable.addImplementation(tmp); + assert.ok(promise.Thenable.isImplementation(new tmp())); + + class tmpClass {} + assert.ok(!promise.Thenable.isImplementation(new tmpClass())); + promise.Thenable.addImplementation(tmpClass); + assert.ok(promise.Thenable.isImplementation(new tmpClass())); + }); + + describe('testLongStackTraces', function() { + beforeEach(() => promise.LONG_STACK_TRACES = false); + afterEach(() => promise.LONG_STACK_TRACES = false); + + it('doesNotAppendStackIfFeatureDisabled', function() { + promise.LONG_STACK_TRACES = false; + + var error = Error('hello'); + var originalStack = error.stack; + return promise.rejected(error). + then(fail). + then(fail). + then(fail). + then(fail, function(e) { + assert.equal(error, e); + assert.equal(originalStack, e.stack); + }); + }); + + function getStackMessages(error) { + return error.stack.split(/\n/).filter(function(line) { + return /^From: /.test(line); + }); + } + + it('appendsInitialPromiseCreation_resolverThrows', function() { + promise.LONG_STACK_TRACES = true; + + var error = Error('hello'); + var originalStack = '(placeholder; will be overwritten later)'; + + return new promise.Promise(function() { + try { + throw error; + } catch (e) { + originalStack = e.stack; + throw e; + } + }).then(fail, function(e) { + assert.strictEqual(error, e); + if (typeof originalStack !== 'string') { + return; + } + assert.notEqual(originalStack, e.stack); + assert.equal(e.stack.indexOf(originalStack), 0, + 'should start with original stack'); + assert.deepEqual(['From: Promise: new'], getStackMessages(e)); + }); + }); + + it('appendsInitialPromiseCreation_rejectCalled', function() { + promise.LONG_STACK_TRACES = true; + + var error = Error('hello'); + var originalStack = error.stack; + + return new promise.Promise(function(_, reject) { + reject(error); + }).then(fail, function(e) { + assert.equal(error, e); + if (typeof originalStack !== 'string') { + return; + } + assert.notEqual(originalStack, e.stack); + assert.equal(e.stack.indexOf(originalStack), 0, + 'should start with original stack'); + assert.deepEqual(['From: Promise: new'], getStackMessages(e)); + }); + }); + + it('appendsEachStepToRejectionError', function() { + promise.LONG_STACK_TRACES = true; + + var error = Error('hello'); + var originalStack = '(placeholder; will be overwritten later)'; + + return new promise.Promise(function() { + try { + throw error; + } catch (e) { + originalStack = e.stack; + throw e; + } + }). + then(fail). + thenCatch(function(e) { throw e; }). + then(fail). + thenCatch(function(e) { throw e; }). + then(fail, function(e) { + assert.equal(error, e); + if (typeof originalStack !== 'string') { + return; + } + assert.notEqual(originalStack, e.stack); + assert.equal(e.stack.indexOf(originalStack), 0, + 'should start with original stack'); + assert.deepEqual([ + 'From: Promise: new', + 'From: Promise: then', + 'From: Promise: catch', + 'From: Promise: then', + 'From: Promise: catch', + ], getStackMessages(e)); + }); + }); + + it('errorOccursInCallbackChain', function() { + promise.LONG_STACK_TRACES = true; + + var error = Error('hello'); + var originalStack = '(placeholder; will be overwritten later)'; + + return promise.fulfilled(). + then(function() {}). + then(function() {}). + then(function() { + try { + throw error; + } catch (e) { + originalStack = e.stack; + throw e; + } + }). + thenCatch(function(e) { throw e; }). + then(fail, function(e) { + assert.equal(error, e); + if (typeof originalStack !== 'string') { + return; + } + assert.notEqual(originalStack, e.stack); + assert.equal(e.stack.indexOf(originalStack), 0, + 'should start with original stack'); + assert.deepEqual([ + 'From: Promise: then', + 'From: Promise: catch', + ], getStackMessages(e)); + }); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/testutil.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/testutil.js new file mode 100644 index 0000000..e68ca28 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/testutil.js @@ -0,0 +1,90 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); +const sinon = require('sinon'); + + +class StubError extends Error { + constructor(opt_msg) { + super(opt_msg); + this.name = this.constructor.name; + } +} +exports.StubError = StubError; + +exports.throwStubError = function() { + throw new StubError; +}; + +exports.assertIsStubError = function(value) { + assert.ok(value instanceof StubError, value + ' is not a ' + StubError.name); +}; + +exports.assertIsInstance = function(ctor, value) { + assert.ok(value instanceof ctor, 'Not a ' + ctor.name + ': ' + value); +}; + +function callbackPair(cb, eb) { + if (cb && eb) { + throw new TypeError('can only specify one of callback or errback'); + } + + let callback = cb ? sinon.spy(cb) : sinon.spy(); + let errback = eb ? sinon.spy(eb) : sinon.spy(); + + function assertCallback() { + assert.ok(callback.called, 'callback not called'); + assert.ok(!errback.called, 'errback called'); + if (callback.threw()) { + throw callback.exceptions[0]; + } + } + + function assertErrback() { + assert.ok(!callback.called, 'callback called'); + assert.ok(errback.called, 'errback not called'); + if (errback.threw()) { + throw errback.exceptions[0]; + } + } + + function assertNeither() { + assert.ok(!callback.called, 'callback called'); + assert.ok(!errback.called, 'errback called'); + } + + return { + callback, + errback, + assertCallback, + assertErrback, + assertNeither + }; +} +exports.callbackPair = callbackPair; + + +exports.callbackHelper = function(cb) { + let pair = callbackPair(cb); + let wrapped = pair.callback.bind(null); + wrapped.assertCalled = () => pair.assertCallback(); + wrapped.assertNotCalled = () => pair.assertNeither(); + return wrapped; +}; diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/until_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/until_test.js new file mode 100644 index 0000000..3a25b76 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/until_test.js @@ -0,0 +1,436 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); + +const error = require('../../error'); +const By = require('../../lib/by').By; +const CommandName = require('../../lib/command').Name; +const promise = require('../../lib/promise'); +const until = require('../../lib/until'); +const webdriver = require('../../lib/webdriver'); + +describe('until', function() { + let driver, executor; + + function createResponse(value) { + return {status: 0, value}; + } + + class TestExecutor { + constructor() { + this.handlers_ = {}; + } + + on(cmd, handler) { + this.handlers_[cmd] = handler; + return this; + } + + execute(cmd) { + let self = this; + return new Promise(function(fulfill) { + if (!self.handlers_[cmd.getName()]) { + throw new error.UnknownCommandError(cmd.getName()); + } + fulfill(self.handlers_[cmd.getName()](cmd)); + }); + } + } + + function fail(opt_msg) { + throw new assert.AssertionError({message: opt_msg}); + } + + beforeEach(function setUp() { + executor = new TestExecutor(); + driver = new webdriver.WebDriver('session-id', executor); + }); + + describe('ableToSwitchToFrame', function() { + it('failsFastForNonSwitchErrors', function() { + let e = Error('boom'); + executor.on(CommandName.SWITCH_TO_FRAME, function() { + throw e; + }); + return driver.wait(until.ableToSwitchToFrame(0), 100) + .then(fail, (e2) => assert.strictEqual(e2, e)); + }); + + it('byIndex', function() { + executor.on(CommandName.SWITCH_TO_FRAME, function() { + return {status: error.ErrorCode.SUCCESS}; + }); + return driver.wait(until.ableToSwitchToFrame(0), 100); + }); + + it('byWebElement', function() { + executor.on(CommandName.SWITCH_TO_FRAME, function(cmd, callback) { + return {status: error.ErrorCode.SUCCESS}; + }); + var el = new webdriver.WebElement(driver, {ELEMENT: 1234}); + return driver.wait(until.ableToSwitchToFrame(el), 100); + }); + + it('byWebElementPromise', function() { + executor.on(CommandName.SWITCH_TO_FRAME, function(cmd, callback) { + return {status: error.ErrorCode.SUCCESS}; + }); + var el = new webdriver.WebElementPromise(driver, + promise.fulfilled(new webdriver.WebElement(driver, {ELEMENT: 1234}))); + return driver.wait(until.ableToSwitchToFrame(el), 100); + }); + + it('byLocator', function() { + executor.on(CommandName.FIND_ELEMENTS, function() { + return { + status: error.ErrorCode.SUCCESS, + value: [{ELEMENT: 1234}] + }; + }).on(CommandName.SWITCH_TO_FRAME, function() { + return {status: error.ErrorCode.SUCCESS}; + }); + + return driver.wait(until.ableToSwitchToFrame(By.id('foo')), 100); + }); + + it('byLocator_elementNotInitiallyFound', function() { + var foundResponses = [[], [], [{ELEMENT: 1234}]]; + executor.on(CommandName.FIND_ELEMENTS, function() { + return { + status: error.ErrorCode.SUCCESS, + value: foundResponses.shift() + }; + }).on(CommandName.SWITCH_TO_FRAME, function(cmd, callback) { + return {status: error.ErrorCode.SUCCESS}; + }); + + return driver.wait(until.ableToSwitchToFrame(By.id('foo')), 2000) + .then(function() { + assert.equal(foundResponses.length, 0); + }); + }); + + it('timesOutIfNeverAbletoSwitchFrames', function() { + var count = 0; + executor.on(CommandName.SWITCH_TO_FRAME, function() { + count += 1; + return {status: error.ErrorCode.NO_SUCH_FRAME}; + }); + + return driver.wait(until.ableToSwitchToFrame(0), 100) + .then(fail, function(e) { + assert.ok(count > 0); + assert.ok( + e.message.startsWith('Waiting to be able to switch to frame'), + 'Wrong message: ' + e.message); + }); + }); + }); + + describe('alertIsPresent', function() { + it('failsFastForNonAlertSwitchErrors', function() { + return driver.wait(until.alertIsPresent(), 100).then(fail, function(e) { + assert.ok(e instanceof error.UnknownCommandError); + assert.equal(e.message, CommandName.GET_ALERT_TEXT); + }); + }); + + it('waitsForAlert', function() { + var count = 0; + executor.on(CommandName.GET_ALERT_TEXT, function() { + if (count++ < 3) { + return {status: error.ErrorCode.NO_SUCH_ALERT}; + } else { + return {status: error.ErrorCode.SUCCESS}; + } + }).on(CommandName.DISMISS_ALERT, function(cmd, callback) { + return {status: error.ErrorCode.SUCCESS}; + }); + + return driver.wait(until.alertIsPresent(), 1000).then(function(alert) { + assert.equal(count, 4); + return alert.dismiss(); + }); + }); + }); + + it('testUntilTitleIs', function() { + var titles = ['foo', 'bar', 'baz']; + executor.on(CommandName.GET_TITLE, function() { + return createResponse(titles.shift()); + }); + + return driver.wait(until.titleIs('bar'), 3000).then(function() { + assert.deepStrictEqual(titles, ['baz']); + }); + }); + + it('testUntilTitleContains', function() { + var titles = ['foo', 'froogle', 'google']; + executor.on(CommandName.GET_TITLE, function() { + return createResponse(titles.shift()); + }); + + return driver.wait(until.titleContains('oogle'), 3000).then(function() { + assert.deepStrictEqual(titles, ['google']); + }); + }); + + it('testUntilTitleMatches', function() { + var titles = ['foo', 'froogle', 'aaaabc', 'aabbbc', 'google']; + executor.on(CommandName.GET_TITLE, function() { + return createResponse(titles.shift()); + }); + + return driver.wait(until.titleMatches(/^a{2,3}b+c$/), 3000) + .then(function() { + assert.deepStrictEqual(titles, ['google']); + }); + }); + + it('testUntilElementLocated', function() { + var responses = [[], [{ELEMENT: 'abc123'}, {ELEMENT: 'foo'}], ['end']]; + executor.on(CommandName.FIND_ELEMENTS, function(cmd, callback) { + return createResponse(responses.shift()); + }); + + let element = driver.wait(until.elementLocated(By.id('quux')), 2000); + assert.ok(element instanceof webdriver.WebElementPromise); + return element.getId().then(function(id) { + assert.deepStrictEqual(responses, [['end']]); + assert.equal(id, 'abc123'); + }); + }); + + describe('untilElementLocated, elementNeverFound', function() { + function runNoElementFoundTest(locator, locatorStr) { + executor.on(CommandName.FIND_ELEMENTS, function() { + return createResponse([]); + }); + + function expectedFailure() { + fail('expected condition to timeout'); + } + + return driver.wait(until.elementLocated(locator), 100) + .then(expectedFailure, function(error) { + var expected = 'Waiting for element to be located ' + locatorStr; + var lines = error.message.split(/\n/, 2); + assert.equal(lines[0], expected); + + let regex = /^Wait timed out after \d+ms$/; + assert.ok(regex.test(lines[1]), + `Lines <${lines[1]}> does not match ${regex}`); + }); + } + + it('byLocator', function() { + return runNoElementFoundTest( + By.id('quux'), 'By(css selector, *[id="quux"])'); + }); + + it('byHash', function() { + return runNoElementFoundTest( + {id: 'quux'}, 'By(css selector, *[id="quux"])'); + }); + + it('byFunction', function() { + return runNoElementFoundTest(function() {}, 'by function()'); + }); + }); + + it('testUntilElementsLocated', function() { + var responses = [[], [{ELEMENT: 'abc123'}, {ELEMENT: 'foo'}], ['end']]; + executor.on(CommandName.FIND_ELEMENTS, function() { + return createResponse(responses.shift()); + }); + + return driver.wait(until.elementsLocated(By.id('quux')), 2000) + .then(function(els) { + return Promise.all(els.map(e => e.getId())); + }).then(function(ids) { + assert.deepStrictEqual(responses, [['end']]); + assert.equal(ids.length, 2); + assert.equal(ids[0], 'abc123'); + assert.equal(ids[1], 'foo'); + }); + }); + + describe('untilElementsLocated, noElementsFound', function() { + function runNoElementsFoundTest(locator, locatorStr) { + executor.on(CommandName.FIND_ELEMENTS, function() { + return createResponse([]); + }); + + function expectedFailure() { + fail('expected condition to timeout'); + } + + return driver.wait(until.elementsLocated(locator), 100) + .then(expectedFailure, function(error) { + var expected = + 'Waiting for at least one element to be located ' + locatorStr; + var lines = error.message.split(/\n/, 2); + assert.equal(lines[0], expected); + + let regex = /^Wait timed out after \d+ms$/; + assert.ok(regex.test(lines[1]), + `Lines <${lines[1]}> does not match ${regex}`); + }); + } + + it('byLocator', function() { + return runNoElementsFoundTest( + By.id('quux'), 'By(css selector, *[id="quux"])'); + }); + + it('byHash', function() { + return runNoElementsFoundTest( + {id: 'quux'}, 'By(css selector, *[id="quux"])'); + }); + + it('byFunction', function() { + return runNoElementsFoundTest(function() {}, 'by function()'); + }); + }); + + it('testUntilStalenessOf', function() { + var responses = [ + createResponse('body'), + createResponse('body'), + createResponse('body'), + {status: error.ErrorCode.STALE_ELEMENT_REFERENCE, + value: {message: 'now stale'}}, + ['end'] + ]; + executor.on(CommandName.GET_ELEMENT_TAG_NAME, function() { + return responses.shift(); + }); + + var el = new webdriver.WebElement(driver, {ELEMENT: 'foo'}); + return driver.wait(until.stalenessOf(el), 2000).then(function() { + assert.deepStrictEqual(responses, [['end']]); + }); + }); + + describe('element state conditions', function() { + function runElementStateTest(predicate, command, responses, var_args) { + let original = new webdriver.WebElement(driver, 'foo'); + let predicateArgs = [original]; + if (arguments.length > 3) { + predicateArgs = predicateArgs.concat(arguments[1]); + command = arguments[2]; + responses = arguments[3]; + } + + assert.ok(responses.length > 1); + + responses = responses.concat(['end']); + executor.on(command, function() { + return createResponse(responses.shift()); + }); + + let result = driver.wait(predicate.apply(null, predicateArgs), 2000); + assert.ok(result instanceof webdriver.WebElementPromise); + return result.then(function(value) { + assert.ok(value instanceof webdriver.WebElement); + assert.ok(!(value instanceof webdriver.WebElementPromise)); + return value.getId(); + }).then(function(id) { + assert.equal('foo', id); + assert.deepStrictEqual(responses, ['end']); + }); + } + + it('elementIsVisible', function() { + return runElementStateTest( + until.elementIsVisible, + CommandName.IS_ELEMENT_DISPLAYED, [false, false, true]); + }); + + it('elementIsNotVisible', function() { + return runElementStateTest( + until.elementIsNotVisible, + CommandName.IS_ELEMENT_DISPLAYED, [true, true, false]); + }); + + it('elementIsEnabled', function() { + return runElementStateTest( + until.elementIsEnabled, + CommandName.IS_ELEMENT_ENABLED, [false, false, true]); + }); + + it('elementIsDisabled', function() { + return runElementStateTest( + until.elementIsDisabled, + CommandName.IS_ELEMENT_ENABLED, [true, true, false]); + }); + + it('elementIsSelected', function() { + return runElementStateTest( + until.elementIsSelected, + CommandName.IS_ELEMENT_SELECTED, [false, false, true]); + }); + + it('elementIsNotSelected', function() { + return runElementStateTest( + until.elementIsNotSelected, + CommandName.IS_ELEMENT_SELECTED, [true, true, false]); + }); + + it('elementTextIs', function() { + return runElementStateTest( + until.elementTextIs, 'foobar', + CommandName.GET_ELEMENT_TEXT, + ['foo', 'fooba', 'foobar']); + }); + + it('elementTextContains', function() { + return runElementStateTest( + until.elementTextContains, 'bar', + CommandName.GET_ELEMENT_TEXT, + ['foo', 'foobaz', 'foobarbaz']); + }); + + it('elementTextMatches', function() { + return runElementStateTest( + until.elementTextMatches, /fo+bar{3}/, + CommandName.GET_ELEMENT_TEXT, + ['foo', 'foobar', 'fooobarrr']); + }); + }); + + describe('WebElementCondition', function() { + it('fails if wait completes with a non-WebElement value', function() { + let result = driver.wait( + new until.WebElementCondition('testing', () => 123), 1000); + + return result.then( + () => assert.fail('expected to fail'), + function(e) { + assert.ok(e instanceof TypeError); + assert.equal( + 'WebElementCondition did not resolve to a WebElement: ' + + '[object Number]', + e.message); + }); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/webdriver_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/webdriver_test.js new file mode 100644 index 0000000..eb68625 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/lib/webdriver_test.js @@ -0,0 +1,2207 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const testutil = require('./testutil'); + +const error = require('../../error'); + +const By = require('../../lib/by').By; +const Capabilities = require('../../lib/capabilities').Capabilities; +const Executor = require('../../lib/command').Executor; +const CName = require('../../lib/command').Name; +const Button = require('../../lib/input').Button; +const Key = require('../../lib/input').Key; +const logging = require('../../lib/logging'); +const Session = require('../../lib/session').Session; +const promise = require('../../lib/promise'); +const Alert = require('../../lib/webdriver').Alert; +const AlertPromise = require('../../lib/webdriver').AlertPromise; +const UnhandledAlertError = require('../../lib/webdriver').UnhandledAlertError; +const WebDriver = require('../../lib/webdriver').WebDriver; +const WebElement = require('../../lib/webdriver').WebElement; +const WebElementPromise = require('../../lib/webdriver').WebElementPromise; + +const assert = require('assert'); +const sinon = require('sinon'); + +const SESSION_ID = 'test_session_id'; + +// Aliases for readability. +const NativePromise = Promise; +const ECode = error.ErrorCode; +const StubError = testutil.StubError; +const assertIsInstance = testutil.assertIsInstance; +const assertIsStubError = testutil.assertIsStubError; +const throwStubError = testutil.throwStubError; +const fail = (msg) => assert.fail(msg); + +describe('WebDriver', function() { + const LOG = logging.getLogger('webdriver.test'); + + // before(function() { + // logging.getLogger('webdriver').setLevel(logging.Level.ALL); + // logging.installConsoleHandler(); + // }); + + // after(function() { + // logging.getLogger('webdriver').setLevel(null); + // logging.removeConsoleHandler(); + // }); + + var driver; + var flow; + var uncaughtExceptions; + + beforeEach(function setUp() { + flow = promise.controlFlow(); + uncaughtExceptions = []; + flow.on('uncaughtException', onUncaughtException); + }); + + afterEach(function tearDown() { + return waitForIdle(flow).then(function() { + assert.deepEqual([], uncaughtExceptions); + flow.reset(); + }); + }); + + function onUncaughtException(e) { + uncaughtExceptions.push(e); + } + + function waitForIdle(opt_flow) { + var theFlow = opt_flow || flow; + return new Promise(function(fulfill, reject) { + if (theFlow.isIdle()) { + fulfill(); + return; + } + theFlow.once('idle', fulfill); + theFlow.once('uncaughtException', reject); + }); + } + + function waitForAbort(opt_flow, opt_n) { + var n = opt_n || 1; + var theFlow = opt_flow || flow; + theFlow.removeAllListeners( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION); + return new Promise(function(fulfill, reject) { + theFlow.once('idle', function() { + reject(Error('expected flow to report an unhandled error')); + }); + + var errors = []; + theFlow.on('uncaughtException', onError); + function onError(e) { + errors.push(e); + if (errors.length === n) { + theFlow.removeListener('uncaughtException', onError); + fulfill(n === 1 ? errors[0] : errors); + } + } + }); + } + + function expectedError(ctor, message) { + return function(e) { + assertIsInstance(ctor, e); + assert.equal(message, e.message); + }; + } + + class Expectation { + constructor(executor, name, opt_parameters) { + this.executor_ = executor; + this.name_ = name; + this.times_ = 1; + this.sessionId_ = SESSION_ID; + this.check_ = null; + this.toDo_ = null; + this.withParameters(opt_parameters || {}); + } + + anyTimes() { + this.times_ = Infinity; + return this; + } + + times(n) { + this.times_ = n; + return this; + } + + withParameters(parameters) { + this.parameters_ = parameters; + if (this.name_ !== CName.NEW_SESSION) { + this.parameters_['sessionId'] = this.sessionId_; + } + return this; + } + + andReturn(code, opt_value) { + this.toDo_ = function(command) { + LOG.info('executing ' + command.getName() + '; returning ' + code); + return Promise.resolve({ + 'status': code, + 'sessionId': { + 'value': SESSION_ID + }, + 'value': opt_value !== void(0) ? opt_value : null + }); + }; + return this; + } + + andReturnSuccess(opt_value) { + return this.andReturn(0, opt_value); + } + + andReturnError(code, opt_value) { + return this.andReturn(code, opt_value); + } + + expect(name, opt_parameters) { + this.end(); + return this.executor_.expect(name, opt_parameters); + } + + end() { + if (!this.toDo_) { + this.andReturnSuccess(null); + } + return this.executor_; + } + + execute(command) { + assert.deepEqual(this.parameters_, command.getParameters()); + return this.toDo_(command); + } + } + + class FakeExecutor { + constructor() { + this.commands_ = new Map; + } + + execute(command) { + let expectations = this.commands_.get(command.getName()); + if (!expectations || !expectations.length) { + assert.fail('unexpected command: ' + command.getName()); + return; + } + + let next = expectations[0]; + let result = next.execute(command); + if (next.times_ != Infinity) { + next.times_ -= 1; + if (!next.times_) { + expectations.shift(); + } + } + return result; + } + + expect(commandName, opt_parameters) { + if (!this.commands_.has(commandName)) { + this.commands_.set(commandName, []); + } + let e = new Expectation(this, commandName, opt_parameters); + this.commands_.get(commandName).push(e); + return e; + } + + createDriver(opt_session) { + let session = opt_session || new Session(SESSION_ID, {}); + return new WebDriver(session, this); + } + } + + + ///////////////////////////////////////////////////////////////////////////// + // + // Tests + // + ///////////////////////////////////////////////////////////////////////////// + + + describe('testAttachToSession', function() { + it('sessionIsAvailable', function() { + let executor = new FakeExecutor(). + expect(CName.DESCRIBE_SESSION). + withParameters({'sessionId': SESSION_ID}). + andReturnSuccess({'browserName': 'firefox'}). + end(); + + let driver = WebDriver.attachToSession(executor, SESSION_ID); + return driver.getSession().then(function(session) { + assert.deepEqual({'value': 'test_session_id'}, session.getId()); + assert.equal('firefox', session.getCapability('browserName')); + }); + }); + + it('failsToGetSessionInfo', function() { + let executor = new FakeExecutor(). + expect(CName.DESCRIBE_SESSION). + withParameters({'sessionId': SESSION_ID}). + andReturnError(ECode.UNKNOWN_ERROR, {'message': 'boom'}). + end(); + + let driver = WebDriver.attachToSession(executor, SESSION_ID); + return driver.getSession() + .then(() => assert.fail('should have failed!'), function(e) { + assertIsInstance(error.WebDriverError, e); + assert.equal('boom', e.message); + }); + }); + + it('usesActiveFlowByDefault', function() { + let executor = new FakeExecutor(). + expect(CName.DESCRIBE_SESSION). + withParameters({'sessionId': SESSION_ID}). + andReturnSuccess({}). + end(); + + var driver = WebDriver.attachToSession(executor, SESSION_ID); + assert.equal(driver.controlFlow(), promise.controlFlow()); + + return waitForIdle(driver.controlFlow()); + }); + + it('canAttachInCustomFlow', function() { + let executor = new FakeExecutor(). + expect(CName.DESCRIBE_SESSION). + withParameters({'sessionId': SESSION_ID}). + andReturnSuccess({}). + end(); + + var otherFlow = new promise.ControlFlow(); + var driver = WebDriver.attachToSession(executor, SESSION_ID, otherFlow); + assert.equal(otherFlow, driver.controlFlow()); + assert.notEqual(otherFlow, promise.controlFlow()); + + return waitForIdle(otherFlow); + }); + }); + + describe('testCreateSession', function() { + it('happyPathWithCapabilitiesHashObject', function() { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({ + 'desiredCapabilities': {'browserName': 'firefox'} + }). + andReturnSuccess({'browserName': 'firefox'}). + end(); + + var driver = WebDriver.createSession(executor, { + 'browserName': 'firefox' + }); + return driver.getSession().then(function(session) { + assert.deepEqual({ + 'value':'test_session_id' + }, session.getId()); + assert.equal('firefox', session.getCapability('browserName')); + }); + }); + + it('happyPathWithCapabilitiesInstance', function() { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({'desiredCapabilities': {'browserName': 'firefox'}}). + andReturnSuccess({'browserName': 'firefox'}). + end(); + + var driver = WebDriver.createSession(executor, Capabilities.firefox()); + return driver.getSession().then(function(session) { + assert.deepEqual({'value':'test_session_id' }, session.getId()); + assert.equal('firefox', session.getCapability('browserName')); + }); + }); + + it('failsToCreateSession', function() { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({'desiredCapabilities': {'browserName': 'firefox'}}). + andReturnError(ECode.UNKNOWN_ERROR, {'message': 'boom'}). + end(); + + var driver = + WebDriver.createSession(executor, {'browserName': 'firefox'}); + return driver.getSession().then(fail, function(e) { + assertIsInstance(error.WebDriverError, e); + assert.equal('boom', e.message); + }); + }); + + it('usesActiveFlowByDefault', function() { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({'desiredCapabilities': {}}). + andReturnSuccess({}). + end(); + + var driver = WebDriver.createSession(executor, {}); + assert.equal(promise.controlFlow(), driver.controlFlow()); + + return waitForIdle(driver.controlFlow()); + }); + + it('canCreateInCustomFlow', function() { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({'desiredCapabilities': {}}). + andReturnSuccess({}). + end(); + + var otherFlow = new promise.ControlFlow(); + var driver = WebDriver.createSession(executor, {}, otherFlow); + assert.equal(otherFlow, driver.controlFlow()); + assert.notEqual(otherFlow, promise.controlFlow()); + + return waitForIdle(otherFlow); + }); + }); + + it('testDoesNotExecuteCommandIfSessionDoesNotResolve', function() { + var session = Promise.reject(new StubError); + new FakeExecutor().createDriver(session).getTitle(); + return waitForAbort().then(assertIsStubError); + }); + + it('testCommandReturnValuesArePassedToFirstCallback', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE).andReturnSuccess('Google Search'). + end(); + + var driver = executor.createDriver(); + return driver.getTitle().then(function(title) { + assert.equal('Google Search', title); + }); + }); + + it('testStopsCommandExecutionWhenAnErrorOccurs', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW). + withParameters({'name': 'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message': 'window not found'}). + end(); + + var driver = executor.createDriver(); + driver.switchTo().window('foo'); + driver.getTitle(); // mock should blow if this gets executed + + return waitForAbort(). + then(expectedError(error.NoSuchWindowError, 'window not found')); + }); + + it('testCanSuppressCommandFailures', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW). + withParameters({'name': 'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message': 'window not found'}). + expect(CName.GET_TITLE). + andReturnSuccess('Google Search'). + end(); + + var driver = executor.createDriver(); + driver.switchTo().window('foo') + .thenCatch(expectedError(error.NoSuchWindowError, 'window not found')); + driver.getTitle(); + return waitForIdle(); + }); + + it('testErrorsPropagateUpToTheRunningApplication', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW). + withParameters({'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message': 'window not found'}). + end(); + + executor.createDriver().switchTo().window('foo'); + return waitForAbort(). + then(expectedError(error.NoSuchWindowError, 'window not found')); + }); + + it('testErrbacksThatReturnErrorsStillSwitchToCallbackChain', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW). + withParameters({'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + end(); + + var driver = executor.createDriver(); + return driver.switchTo().window('foo'). + thenCatch(function() { return new StubError; }); + then(assertIsStubError); + }); + + it('testErrbacksThrownCanOverrideOriginalError', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + end(); + + var driver = executor.createDriver(); + driver.switchTo().window('foo').thenCatch(throwStubError); + + return waitForAbort().then(assertIsStubError); + }); + + it('testCannotScheduleCommandsIfTheSessionIdHasBeenDeleted', function() { + var driver = new FakeExecutor().createDriver(); + delete driver.session_; + assert.throws(() => driver.get('http://www.google.com')); + }); + + it('testDeletesSessionIdAfterQuitting', function() { + var driver; + let executor = new FakeExecutor(). + expect(CName.QUIT). + end(); + + driver = executor.createDriver(); + return driver.quit().then(function() { + assert.equal(void 0, driver.session_); + }); + }); + + it('testReportsErrorWhenExecutingCommandsAfterExecutingAQuit', function() { + let executor = new FakeExecutor(). + expect(CName.QUIT). + end(); + + var driver = executor.createDriver(); + driver.quit(); + driver.get('http://www.google.com'); + return waitForAbort(). + then(expectedError( + error.UnsupportedOperationError, + 'This driver instance does not have a valid session ID ' + + '(did you call WebDriver.quit()?) and may no longer be used.')); + }); + + it('testCallbackCommandsExecuteBeforeNextCommand', function() { + let executor = new FakeExecutor(). + expect(CName.GET_CURRENT_URL). + expect(CName.GET, {'url': 'http://www.google.com'}). + expect(CName.CLOSE). + expect(CName.GET_TITLE). + end(); + + var driver = executor.createDriver(); + driver.getCurrentUrl().then(function() { + driver.get('http://www.google.com').then(function() { + driver.close(); + }); + }); + driver.getTitle(); + + return waitForIdle(); + }); + + it('testEachCallbackFrameRunsToCompletionBeforeTheNext', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.GET_CURRENT_URL). + expect(CName.GET_CURRENT_WINDOW_HANDLE). + expect(CName.CLOSE). + expect(CName.QUIT). + end(); + + var driver = executor.createDriver(); + driver.getTitle(). + // Everything in this callback... + then(function() { + driver.getCurrentUrl(); + driver.getWindowHandle(); + }). + // ...should execute before everything in this callback. + then(function() { + driver.close(); + }); + // This should execute after everything above + driver.quit(); + + return waitForIdle(); + }); + + describe('nestedCommandFailures', function() { + it('bubbleUpToGlobalHandlerIfUnsuppressed', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + end(); + + var driver = executor.createDriver(); + driver.getTitle().then(function() { + driver.switchTo().window('foo'); + }); + + return waitForAbort(). + then(expectedError(error.NoSuchWindowError, 'window not found')); + }); + + it('canBeSuppressWhenTheyOccur', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + expect(CName.CLOSE). + end(); + + var driver = executor.createDriver(); + driver.getTitle().then(function() { + driver.switchTo().window('foo').thenCatch(function() {}); + }); + driver.close(); + + return waitForIdle(); + }); + + it('bubbleUpThroughTheFrameStack', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + end(); + + var driver = executor.createDriver(); + driver.getTitle(). + then(function() { + return driver.switchTo().window('foo'); + }). + thenCatch(function(e) { + assertIsInstance(error.NoSuchWindowError, e); + assert.equal('window not found', e.message); + }); + + return waitForIdle(); + }); + + it('canBeCaughtAndSuppressed', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.GET_CURRENT_URL). + expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + expect(CName.CLOSE). + end(); + + var driver = executor.createDriver(); + driver.getTitle().then(function() { + driver.getCurrentUrl(). + then(function() { + return driver.switchTo().window('foo'); + }). + thenCatch(function() {}); + driver.close(); + }); + + return waitForIdle(); + }); + }); + + describe('returningAPromise', function() { + it('fromACallback', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.GET_CURRENT_URL). + andReturnSuccess('http://www.google.com'). + end(); + + var driver = executor.createDriver(); + driver.getTitle(). + then(function() { + return driver.getCurrentUrl(); + }). + then(function(value) { + assert.equal('http://www.google.com', value); + }); + return waitForIdle(); + }); + + it('fromAnErrbackSuppressesTheError', function() { + var count = 0; + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + expect(CName.GET_CURRENT_URL). + andReturnSuccess('http://www.google.com'). + end(); + + var driver = executor.createDriver(); + driver.switchTo().window('foo'). + thenCatch(function(e) { + assertIsInstance(error.NoSuchWindowError, e); + assert.equal('window not found', e.message); + count += 1; + return driver.getCurrentUrl(); + }). + then(function(url) { + count += 1; + assert.equal('http://www.google.com', url); + }); + return waitForIdle().then(function() { + assert.equal(2, count); + }); + }); + }); + + describe('customFunctions', function() { + it('returnsANonPromiseValue', function() { + var driver = new FakeExecutor().createDriver(); + return driver.call(() => 'abc123').then(function(value) { + assert.equal('abc123', value); + }); + }); + + it('executionOrderWithCustomFunctions', function() { + var msg = []; + let executor = new FakeExecutor(). + expect(CName.GET_TITLE).andReturnSuccess('cheese '). + expect(CName.GET_CURRENT_URL).andReturnSuccess('tasty'). + end(); + + var driver = executor.createDriver(); + + var pushMsg = msg.push.bind(msg); + driver.getTitle().then(pushMsg); + driver.call(() => 'is ').then(pushMsg); + driver.getCurrentUrl().then(pushMsg); + driver.call(() => '!').then(pushMsg); + + return waitForIdle().then(function() { + assert.equal('cheese is tasty!', msg.join('')); + }); + }); + + it('passingArgumentsToACustomFunction', function() { + var add = function(a, b) { + return a + b; + }; + var driver = new FakeExecutor().createDriver(); + return driver.call(add, null, 1, 2).then(function(value) { + assert.equal(3, value); + }); + }); + + it('passingPromisedArgumentsToACustomFunction', function() { + var promisedArg = promise.fulfilled(2); + var add = function(a, b) { + return a + b; + }; + var driver = new FakeExecutor().createDriver(); + return driver.call(add, null, 1, promisedArg).then(function(value) { + assert.equal(3, value); + }); + }); + + it('passingArgumentsAndScopeToACustomFunction', function() { + function Foo(name) { + this.name = name; + } + Foo.prototype.getName = function() { + return this.name; + }; + var foo = new Foo('foo'); + + var driver = new FakeExecutor().createDriver(); + return driver.call(foo.getName, foo).then(function(value) { + assert.equal('foo', value); + }); + }); + + it('customFunctionThrowsAnError', function() { + var driver = new FakeExecutor().createDriver(); + return driver.call(throwStubError).then(fail, assertIsStubError); + }); + + it('customFunctionSchedulesCommands', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.CLOSE). + expect(CName.QUIT). + end(); + + var driver = executor.createDriver(); + driver.call(function() { + driver.getTitle(); + driver.close(); + }); + driver.quit(); + return waitForIdle(); + }); + + it('returnsATaskResultAfterSchedulingAnother', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + andReturnSuccess('Google Search'). + expect(CName.CLOSE). + end(); + + var driver = executor.createDriver(); + return driver.call(function() { + var title = driver.getTitle(); + driver.close(); + return title; + }).then(function(title) { + assert.equal('Google Search', title); + }); + }); + + it('hasANestedCommandThatFails', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + end(); + + var driver = executor.createDriver(); + return driver.call(function() { + return driver.switchTo().window('foo'); + }).then(fail, function(e) { + assertIsInstance(error.NoSuchWindowError, e); + assert.equal('window not found', e.message); + }); + }); + + it('doesNotCompleteUntilReturnedPromiseIsResolved', function() { + var order = []; + var driver = new FakeExecutor().createDriver(); + + var d = promise.defer(); + d.promise.then(function() { + order.push('b'); + }); + + driver.call(function() { + order.push('a'); + return d.promise; + }); + driver.call(function() { + order.push('c'); + }); + + // timeout to ensure the first function starts its execution before we + // trigger d's callbacks. + return new Promise(f => setTimeout(f, 0)).then(function() { + assert.deepEqual(['a'], order); + d.fulfill(); + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c'], order); + }); + }); + }); + + it('returnsADeferredAction', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE).andReturnSuccess('Google'). + end(); + + var driver = executor.createDriver(); + driver.call(function() { + return driver.getTitle(); + }).then(function(title) { + assert.equal('Google', title); + }); + return waitForIdle(); + }); + }); + + describe('nestedCommands', function() { + it('commandExecutionOrder', function() { + var msg = []; + var driver = new FakeExecutor().createDriver(); + driver.call(msg.push, msg, 'a'); + driver.call(function() { + driver.call(msg.push, msg, 'c'); + driver.call(function() { + driver.call(msg.push, msg, 'e'); + driver.call(msg.push, msg, 'f'); + }); + driver.call(msg.push, msg, 'd'); + }); + driver.call(msg.push, msg, 'b'); + return waitForIdle().then(function() { + assert.equal('acefdb', msg.join('')); + }); + }); + + it('basicUsage', function() { + var msg = []; + var driver = new FakeExecutor().createDriver(); + var pushMsg = msg.push.bind(msg); + driver.call(() => 'cheese ').then(pushMsg); + driver.call(function() { + driver.call(() => 'is ').then(pushMsg); + driver.call(() => 'tasty').then(pushMsg); + }); + driver.call(() => '!').then(pushMsg); + return waitForIdle().then(function() { + assert.equal('cheese is tasty!', msg.join('')); + }); + }); + + it('canReturnValueFromNestedFunction', function() { + var driver = new FakeExecutor().createDriver(); + return driver.call(function() { + return driver.call(function() { + return driver.call(() => 'foobar'); + }); + }).then(function(value) { + assert.equal('foobar', value); + }); + }); + + it('normalCommandAfterNestedCommandThatReturnsAnAction', function() { + var msg = []; + let executor = new FakeExecutor(). + expect(CName.CLOSE). + end(); + var driver = executor.createDriver(); + driver.call(function() { + return driver.call(function() { + msg.push('a'); + return driver.call(() => 'foobar'); + }); + }); + driver.close().then(function() { + msg.push('b'); + }); + return waitForIdle().then(function() { + assert.equal('ab', msg.join('')); + }); + }); + + it('errorsBubbleUp_caught', function() { + var driver = new FakeExecutor().createDriver(); + var result = driver.call(function() { + return driver.call(function() { + return driver.call(throwStubError); + }); + }).then(fail, assertIsStubError); + return Promise.all([waitForIdle(), result]); + }); + + it('errorsBubbleUp_uncaught', function() { + var driver = new FakeExecutor().createDriver(); + driver.call(function() { + return driver.call(function() { + return driver.call(throwStubError); + }); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('canScheduleCommands', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.CLOSE). + end(); + + var driver = executor.createDriver(); + driver.call(function() { + driver.call(function() { + driver.getTitle(); + }); + driver.close(); + }); + return waitForIdle(); + }); + }); + + describe('WebElementPromise', function() { + it('resolvesWhenUnderlyingElementDoes', function() { + var el = new WebElement({}, {'ELEMENT': 'foo'}); + return new WebElementPromise({}, promise.fulfilled(el)).then(function(e) { + assert.strictEqual(e, el); + }); + }); + + it('resolvesBeforeCallbacksOnWireValueTrigger', function() { + var el = new promise.Deferred(); + + var element = new WebElementPromise({}, el.promise); + var messages = []; + + element.then(function() { + messages.push('element resolved'); + }); + element.getId().then(function() { + messages.push('wire value resolved'); + }); + + assert.deepEqual([], messages); + el.fulfill(new WebElement({}, {'ELEMENT': 'foo'})); + return waitForIdle().then(function() { + assert.deepEqual([ + 'element resolved', + 'wire value resolved' + ], messages); + }); + }); + + it('isRejectedIfUnderlyingIdIsRejected', function() { + var element = new WebElementPromise({}, promise.rejected(new StubError)); + return element.then(fail, assertIsStubError); + }); + }); + + describe('executeScript', function() { + it('nullReturnValue', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return document.body;', + 'args': [] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + return driver.executeScript('return document.body;') + .then((result) => assert.equal(null, result)); + }); + + it('primitiveReturnValue', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return document.body;', + 'args': [] + }). + andReturnSuccess(123). + end(); + + var driver = executor.createDriver(); + return driver.executeScript('return document.body;') + .then((result) => assert.equal(123, result)); + }); + + it('webElementReturnValue', function() { + var json = WebElement.buildId('foo'); + + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return document.body;', + 'args': [] + }). + andReturnSuccess(json). + end(); + + var driver = executor.createDriver(); + return driver.executeScript('return document.body;') + .then((element) => element.getId()) + .then((id) => assert.equal(id, 'foo')); + }); + + it('arrayReturnValue', function() { + var json = [WebElement.buildId('foo')]; + + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return document.body;', + 'args': [] + }). + andReturnSuccess(json). + end(); + + var driver = executor.createDriver(); + return driver.executeScript('return document.body;') + .then(function(array) { + assert.equal(1, array.length); + return array[0].getId(); + }) + .then((id) => assert.equal('foo', id)); + }); + + it('objectReturnValue', function() { + var json = {'foo': WebElement.buildId('foo')}; + + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return document.body;', + 'args': [] + }). + andReturnSuccess(json). + end(); + + var driver = executor.createDriver(); + var callback; + return driver.executeScript('return document.body;') + .then((obj) => obj['foo'].getId()) + .then((id) => assert.equal(id, 'foo')); + }); + + it('scriptAsFunction', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return (' + function() {} + + ').apply(null, arguments);', + 'args': [] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + return driver.executeScript(function() {}); + }); + + it('simpleArgumentConversion', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return 1;', + 'args': ['abc', 123, true, [123, {'foo': 'bar'}]] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + return driver.executeScript( + 'return 1;', 'abc', 123, true, [123, {'foo': 'bar'}]); + }); + + it('webElementArgumentConversion', function() { + var elementJson = WebElement.buildId('fefifofum'); + + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return 1;', + 'args': [elementJson] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + return driver.executeScript('return 1;', + new WebElement(driver, 'fefifofum')); + }); + + it('webElementPromiseArgumentConversion', function() { + var elementJson = WebElement.buildId('bar'); + + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {'using': 'css selector', 'value': '*[id="foo"]'}). + andReturnSuccess(elementJson). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return 1;', + 'args': [elementJson] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.id('foo')); + return driver.executeScript('return 1;', element); + }); + + it('argumentConversion', function() { + var elementJson = WebElement.buildId('fefifofum'); + + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return 1;', + 'args': ['abc', 123, true, elementJson, [123, {'foo': 'bar'}]] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + var element = new WebElement(driver, 'fefifofum'); + return driver.executeScript('return 1;', + 'abc', 123, true, element, [123, {'foo': 'bar'}]); + }); + + it('scriptReturnsAnError', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'throw Error(arguments[0]);', + 'args': ['bam'] + }). + andReturnError(ECode.UNKNOWN_ERROR, {'message':'bam'}). + end(); + var driver = executor.createDriver(); + return driver.executeScript('throw Error(arguments[0]);', 'bam'). + then(fail, function(e) { + assertIsInstance(error.WebDriverError, e); + assert.equal('bam', e.message); + }); + }); + + it('failsIfArgumentIsARejectedPromise', function() { + let executor = new FakeExecutor(); + + var arg = promise.rejected(new StubError); + arg.thenCatch(function() {}); // Suppress default handler. + + var driver = executor.createDriver(); + return driver.executeScript(function() {}, arg). + then(fail, assertIsStubError); + }); + }); + + describe('executeAsyncScript', function() { + it('failsIfArgumentIsARejectedPromise', function() { + var arg = promise.rejected(new StubError); + arg.thenCatch(function() {}); // Suppress default handler. + + var driver = new FakeExecutor().createDriver(); + return driver.executeAsyncScript(function() {}, arg). + then(fail, assertIsStubError); + }); + }); + + describe('findElement', function() { + it('elementNotFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.NO_SUCH_ELEMENT, { + 'message':'Unable to find element' + }). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.id('foo')); + element.click(); // This should never execute. + return waitForAbort().then(function(e) { + assertIsInstance(error.NoSuchElementError, e); + assert.equal('Unable to find element', e.message); + }); + }); + + it('elementNotFoundInACallback', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError( + ECode.NO_SUCH_ELEMENT, {'message':'Unable to find element'}). + end(); + + var driver = executor.createDriver(); + promise.fulfilled().then(function() { + var element = driver.findElement(By.id('foo')); + return element.click(); // Should not execute. + }); + return waitForAbort().then(function(e) { + assertIsInstance(error.NoSuchElementError, e); + assert.equal('Unable to find element', e.message); + }); + }); + + it('elementFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess(WebElement.buildId('bar')). + expect(CName.CLICK_ELEMENT, {'id': 'bar'}). + andReturnSuccess(). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.id('foo')); + element.click(); + return waitForIdle(); + }); + + it('canUseElementInCallback', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess(WebElement.buildId('bar')). + expect(CName.CLICK_ELEMENT, {'id': 'bar'}). + andReturnSuccess(). + end(); + + var driver = executor.createDriver(); + driver.findElement(By.id('foo')).then(function(element) { + element.click(); + }); + return waitForIdle(); + }); + + it('byJs', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': 'return document.body', + 'args': [] + }). + andReturnSuccess(WebElement.buildId('bar')). + expect(CName.CLICK_ELEMENT, {'id': 'bar'}). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.js('return document.body')); + element.click(); // just to make sure + return waitForIdle(); + }); + + it('byJs_returnsNonWebElementValue', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, {'script': 'return 123', 'args': []}). + andReturnSuccess(123). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.js('return 123')); + element.click(); // Should not execute. + return waitForAbort().then(function(e) { + assertIsInstance(TypeError, e); + assert.equal('Custom locator did not return a WebElement', e.message); + }); + }); + + it('byJs_canPassArguments', function() { + var script = 'return document.getElementsByTagName(arguments[0]);'; + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': script, + 'args': ['div'] + }). + andReturnSuccess({'ELEMENT':'one'}). + end(); + var driver = executor.createDriver(); + driver.findElement(By.js(script, 'div')); + return waitForIdle(); + }); + + it('customLocator', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, {'using': 'css selector', 'value': 'a'}). + andReturnSuccess([ + WebElement.buildId('foo'), + WebElement.buildId('bar')]). + expect(CName.CLICK_ELEMENT, {'id': 'foo'}). + andReturnSuccess(). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(function(d) { + assert.equal(driver, d); + return d.findElements(By.tagName('a')); + }); + element.click(); + return waitForIdle(); + }); + + it('customLocatorThrowsIfresultIsNotAWebElement', function() { + var driver = new FakeExecutor().createDriver(); + driver.findElement(function() { + return 1; + }); + return waitForAbort().then(function(e) { + assertIsInstance(TypeError, e); + assert.equal('Custom locator did not return a WebElement', e.message); + }); + }); + }); + + describe('isElementPresent', function() { + it('elementNotFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([]). + end(); + + var driver = executor.createDriver(); + return driver.isElementPresent(By.id('foo')) + .then((found) => assert.ok(!found)); + }); + + it('elementFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([WebElement.buildId('bar')]). + end(); + + var driver = executor.createDriver(); + return driver.isElementPresent(By.id('foo')).then(assert.ok); + }); + + it('letsErrorsPropagate', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.UNKNOWN_ERROR, {'message':'There is no spoon'}). + end(); + + var driver = executor.createDriver(); + driver.isElementPresent(By.id('foo')); + return waitForAbort().then(function(e) { + assertIsInstance(error.WebDriverError, e); + assert.equal(e.message, 'There is no spoon'); + }); + }); + + it('byJs', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, {'script': 'return 123', 'args': []}). + andReturnSuccess([WebElement.buildId('bar')]). + end(); + + var driver = executor.createDriver(); + return driver.isElementPresent(By.js('return 123')).then(assert.ok); + }); + + it('byJs_canPassScriptArguments', function() { + var script = 'return document.getElementsByTagName(arguments[0]);'; + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': script, + 'args': ['div'] + }). + andReturnSuccess([WebElement.buildId('one')]). + end(); + + var driver = executor.createDriver(); + driver.isElementPresent(By.js(script, 'div')).then(assert.ok); + return waitForIdle(); + }); + }); + + describe('findElements', function() { + it('returnsMultipleElements', function() { + var ids = ['foo', 'bar', 'baz']; + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, {'using':'css selector', 'value':'a'}). + andReturnSuccess(ids.map(WebElement.buildId)). + end(); + + var driver = executor.createDriver(); + return driver.findElements(By.tagName('a')) + .then(function(elements) { + return promise.all(elements.map(function(e) { + assert.ok(e instanceof WebElement); + return e.getId(); + })); + }) + .then((actual) => assert.deepEqual(ids, actual)); + }); + + it('byJs', function() { + var ids = ['foo', 'bar', 'baz']; + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': 'return document.getElementsByTagName("div");', + 'args': [] + }). + andReturnSuccess(ids.map(WebElement.buildId)). + end(); + + var driver = executor.createDriver(); + + return driver. + findElements(By.js('return document.getElementsByTagName("div");')). + then(function(elements) { + return promise.all(elements.map(function(e) { + assert.ok(e instanceof WebElement); + return e.getId(); + })); + }). + then((actual) => assert.deepEqual(ids, actual)); + }); + + it('byJs_filtersOutNonWebElementResponses', function() { + var ids = ['foo', 'bar', 'baz']; + var json = [ + WebElement.buildId(ids[0]), + 123, + 'a', + false, + WebElement.buildId(ids[1]), + {'not a web element': 1}, + WebElement.buildId(ids[2]) + ]; + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': 'return document.getElementsByTagName("div");', + 'args': [] + }). + andReturnSuccess(json). + end(); + + var driver = executor.createDriver(); + driver.findElements(By.js('return document.getElementsByTagName("div");')). + then(function(elements) { + return promise.all(elements.map(function(e) { + assert.ok(e instanceof WebElement); + return e.getId(); + })); + }). + then((actual) => assert.deepEqual(ids, actual)); + return waitForIdle(); + }); + + it('byJs_convertsSingleWebElementResponseToArray', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': 'return document.getElementsByTagName("div");', + 'args': [] + }). + andReturnSuccess(WebElement.buildId('foo')). + end(); + + var driver = executor.createDriver(); + return driver. + findElements(By.js('return document.getElementsByTagName("div");')). + then(function(elements) { + return promise.all(elements.map(function(e) { + assert.ok(e instanceof WebElement); + return e.getId(); + })); + }). + then((actual) => assert.deepEqual(['foo'], actual)); + }); + + it('byJs_canPassScriptArguments', function() { + var script = 'return document.getElementsByTagName(arguments[0]);'; + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': script, + 'args': ['div'] + }). + andReturnSuccess([ + WebElement.buildId('one'), + WebElement.buildId('two') + ]). + end(); + + var driver = executor.createDriver(); + return driver.findElements(By.js(script, 'div')) + then(function(elements) { + return promise.all(elements.map(function(e) { + assert.ok(e instanceof WebElement); + return e.getId(); + })); + }). + then((actual) => assert.deepEqual(['one', 'two'], actual)); + }); + }); + + describe('sendKeys', function() { + it('convertsVarArgsIntoStrings_simpleArgs', function() { + let executor = new FakeExecutor(). + expect(CName.SEND_KEYS_TO_ELEMENT, {'id': 'one', + 'value':['1','2','abc','3']}). + andReturnSuccess(). + end(); + + var driver = executor.createDriver(); + var element = new WebElement(driver, 'one'); + element.sendKeys(1, 2, 'abc', 3); + return waitForIdle(); + }); + + it('convertsVarArgsIntoStrings_promisedArgs', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {'using':'css selector', 'value':'*[id="foo"]'}). + andReturnSuccess(WebElement.buildId('one')). + expect(CName.SEND_KEYS_TO_ELEMENT, {'id':'one', + 'value':['abc', '123', 'def']}). + andReturnSuccess(). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.id('foo')); + element.sendKeys( + promise.fulfilled('abc'), 123, + promise.fulfilled('def')); + return waitForIdle(); + }); + + it('sendKeysWithAFileDetector', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {'using':'css selector', 'value':'*[id="foo"]'}). + andReturnSuccess(WebElement.buildId('one')). + expect(CName.SEND_KEYS_TO_ELEMENT, {'id': 'one', + 'value':['modified/path']}). + andReturnSuccess(). + end(); + + let driver = executor.createDriver(); + let handleFile = function(d, path) { + assert.strictEqual(driver, d); + assert.equal(path, 'original/path'); + return promise.fulfilled('modified/path'); + }; + driver.setFileDetector({handleFile}); + + var element = driver.findElement(By.id('foo')); + element.sendKeys('original/', 'path'); + return waitForIdle(); + }); + }); + + describe('elementEquality', function() { + it('isReflexive', function() { + var a = new WebElement({}, 'foo'); + return WebElement.equals(a, a).then(assert.ok); + }); + + it('failsIfAnInputElementCouldNotBeFound', function() { + var id = promise.rejected(new StubError); + id.thenCatch(function() {}); // Suppress default handler. + + var driver = new FakeExecutor().createDriver(); + var a = new WebElement(driver, 'foo'); + var b = new WebElementPromise(driver, id); + + return WebElement.equals(a, b).then(fail, assertIsStubError); + }); + }); + + describe('waiting', function() { + it('waitSucceeds', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([]). + times(2). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([WebElement.buildId('bar')]). + end(); + + var driver = executor.createDriver(); + driver.wait(function() { + return driver.isElementPresent(By.id('foo')); + }, 200); + return waitForIdle(); + }); + + it('waitTimesout_timeoutCaught', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([]). + anyTimes(). + end(); + + var driver = executor.createDriver(); + return driver.wait(function() { + return driver.isElementPresent(By.id('foo')); + }, 25).then(fail, function(e) { + assert.equal('Wait timed out after ', + e.message.substring(0, 'Wait timed out after '.length)); + }); + }); + + it('waitTimesout_timeoutNotCaught', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([]). + anyTimes(). + end(); + + var driver = executor.createDriver(); + driver.wait(function() { + return driver.isElementPresent(By.id('foo')); + }, 25); + return waitForAbort().then(function(e) { + assert.equal('Wait timed out after ', + e.message.substring(0, 'Wait timed out after '.length)); + }); + }); + }); + + describe('alert handling', function() { + it('interceptsAndTransformsUnhandledAlertErrors', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.UNEXPECTED_ALERT_OPEN, { + 'message': 'boom', + 'alert': {'text': 'hello'} + }). + end(); + + var driver = executor.createDriver(); + return driver.findElement(By.id('foo')).then(fail, function(e) { + assertIsInstance(UnhandledAlertError, e); + assert.equal('hello', e.getAlertText()); + }); + }); + + it('usesEmptyStringIfAlertTextOmittedFromResponse', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.UNEXPECTED_ALERT_OPEN, {'message': 'boom'}). + end(); + + var driver = executor.createDriver(); + return driver.findElement(By.id('foo')).then(fail, function(e) { + assertIsInstance(UnhandledAlertError, e); + assert.equal('', e.getAlertText()); + }); + }); + + it('alertResolvesWhenPromisedTextResolves', function() { + var textPromise = new promise.Deferred(); + + var alert = new AlertPromise({}, textPromise); + assert.ok(alert.isPending()); + + textPromise.fulfill(new Alert({}, 'foo')); + return alert.getText().then(function(text) { + assert.equal('foo', text); + }); + }); + + it('cannotSwitchToAlertThatIsNotPresent', function() { + let executor = new FakeExecutor() + .expect(CName.GET_ALERT_TEXT) + .andReturnError(ECode.NO_SUCH_ALERT, {'message': 'no alert'}) + .end(); + + var driver = executor.createDriver(); + var alert = driver.switchTo().alert(); + alert.dismiss(); // Should never execute. + return waitForAbort().then(function(e) { + assertIsInstance(error.NoSuchAlertError, e); + assert.equal('no alert', e.message); + }); + }); + + it('alertsBelongToSameFlowAsParentDriver', function() { + let executor = new FakeExecutor() + .expect(CName.GET_ALERT_TEXT).andReturnSuccess('hello') + .end(); + + var driver = executor.createDriver(); + var otherFlow = new promise.ControlFlow(); + otherFlow.execute(function() { + driver.switchTo().alert().then(function() { + assert.strictEqual( + driver.controlFlow(), promise.controlFlow(), + 'Alert should belong to the same flow as its parent driver'); + }); + }); + + assert.notEqual(otherFlow, driver.controlFlow); + return Promise.all([ + waitForIdle(otherFlow), + waitForIdle(driver.controlFlow()) + ]); + }); + + it('commandsFailIfAlertNotPresent', function() { + let executor = new FakeExecutor() + .expect(CName.GET_ALERT_TEXT) + .andReturnError(ECode.NO_SUCH_ALERT, {'message': 'no alert'}) + .end(); + + var driver = executor.createDriver(); + var alert = driver.switchTo().alert(); + + var expectError = expectedError(error.NoSuchAlertError, 'no alert'); + + return alert.getText() + .then(fail, expectedError) + .then(() => alert.accept()) + .then(fail, expectedError) + .then(() => alert.dismiss()) + .then(fail, expectError) + .then(() => alert.sendKeys('hi')) + .then(fail, expectError); + }); + }); + + it('testWebElementsBelongToSameFlowAsParentDriver', function() { + let executor = new FakeExecutor() + .expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}) + .andReturnSuccess(WebElement.buildId('abc123')) + .end(); + + var driver = executor.createDriver(); + var otherFlow = new promise.ControlFlow(); + otherFlow.execute(function() { + driver.findElement({id: 'foo'}).then(function() { + assert.equal(driver.controlFlow(), promise.controlFlow()); + }); + }); + + assert.notEqual(otherFlow, driver.controlFlow); + return Promise.all([ + waitForIdle(otherFlow), + waitForIdle(driver.controlFlow()) + ]); + }); + + it('testFetchingLogs', function() { + let executor = new FakeExecutor(). + expect(CName.GET_LOG, {'type': 'browser'}). + andReturnSuccess([ + {'level': 'INFO', 'message': 'hello', 'timestamp': 1234}, + {'level': 'DEBUG', 'message': 'abc123', 'timestamp': 5678} + ]). + end(); + + var driver = executor.createDriver(); + return driver.manage().logs().get('browser').then(function(entries) { + assert.equal(2, entries.length); + + assert.ok(entries[0] instanceof logging.Entry); + assert.equal(logging.Level.INFO.value, entries[0].level.value); + assert.equal('hello', entries[0].message); + assert.equal(1234, entries[0].timestamp); + + assert.ok(entries[1] instanceof logging.Entry); + assert.equal(logging.Level.DEBUG.value, entries[1].level.value); + assert.equal('abc123', entries[1].message); + assert.equal(5678, entries[1].timestamp); + }); + }); + + it('testCommandsFailIfInitialSessionCreationFailed', function() { + var session = promise.rejected(new StubError); + + var driver = new FakeExecutor().createDriver(session); + var navigateResult = driver.get('some-url').then(fail, assertIsStubError); + var quitResult = driver.quit().then(fail, assertIsStubError); + + return waitForIdle().then(function() { + return promise.all(navigateResult, quitResult); + }); + }); + + it('testWebElementCommandsFailIfInitialDriverCreationFailed', function() { + var session = Promise.reject(new StubError); + var driver = new FakeExecutor().createDriver(session); + return driver.findElement(By.id('foo')).click(). + then(fail, assertIsStubError); + }); + + it('testWebElementCommansFailIfElementCouldNotBeFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.NO_SUCH_ELEMENT, + {'message':'Unable to find element'}). + end(); + + var driver = executor.createDriver(); + return driver.findElement(By.id('foo')).click() + .then(fail, function(e) { + assertIsInstance(error.NoSuchElementError, e); + assert.equal('Unable to find element', e.message); + }); + }); + + it('testCannotFindChildElementsIfParentCouldNotBeFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.NO_SUCH_ELEMENT, + {'message':'Unable to find element'}). + end(); + + var driver = executor.createDriver(); + return driver.findElement(By.id('foo')) + .findElement(By.id('bar')) + .findElement(By.id('baz')) + .then(fail, function(e) { + assertIsInstance(error.NoSuchElementError, e); + assert.equal('Unable to find element', e.message); + }); + }); + + describe('actions()', function() { + it('failsIfInitialDriverCreationFailed', function() { + let session = promise.rejected(new StubError); + session.catch(function() {}); + return new FakeExecutor(). + createDriver(session). + actions(). + mouseDown(). + mouseUp(). + perform(). + thenCatch(assertIsStubError); + }); + + describe('mouseMove', function() { + it('noElement', function() { + let executor = new FakeExecutor() + .expect(CName.MOVE_TO, {'xoffset': 0, 'yoffset': 125}) + .andReturnSuccess() + .end(); + + return executor.createDriver(). + actions(). + mouseMove({x: 0, y: 125}). + perform(); + }); + + it('element', function() { + let executor = new FakeExecutor() + .expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}) + .andReturnSuccess(WebElement.buildId('abc123')) + .expect(CName.MOVE_TO, + {'element': 'abc123', 'xoffset': 0, 'yoffset': 125}) + .andReturnSuccess() + .end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.id('foo')); + return driver.actions() + .mouseMove(element, {x: 0, y: 125}) + .perform(); + }); + }); + + it('supportsMouseDown', function() { + let executor = new FakeExecutor() + .expect(CName.MOUSE_DOWN, {'button': Button.LEFT}) + .andReturnSuccess() + .end(); + + return executor.createDriver(). + actions(). + mouseDown(). + perform(); + }); + + it('testActionSequence', function() { + let executor = new FakeExecutor() + .expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="a"]'}) + .andReturnSuccess(WebElement.buildId('id1')) + .expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="b"]'}) + .andReturnSuccess(WebElement.buildId('id2')) + .expect(CName.SEND_KEYS_TO_ACTIVE_ELEMENT, + {'value': [Key.SHIFT]}) + .andReturnSuccess() + .expect(CName.MOVE_TO, {'element': 'id1'}) + .andReturnSuccess() + .expect(CName.CLICK, {'button': Button.LEFT}) + .andReturnSuccess() + .expect(CName.MOVE_TO, {'element': 'id2'}) + .andReturnSuccess() + .expect(CName.CLICK, {'button': Button.LEFT}) + .andReturnSuccess() + .end(); + + var driver = executor.createDriver(); + var element1 = driver.findElement(By.id('a')); + var element2 = driver.findElement(By.id('b')); + + return driver.actions() + .keyDown(Key.SHIFT) + .click(element1) + .click(element2) + .perform(); + }); + }); + + describe('touchActions()', function() { + it('failsIfInitialDriverCreationFailed', function() { + let session = promise.rejected(new StubError); + session.catch(function() {}); + return new FakeExecutor(). + createDriver(session). + touchActions(). + scroll({x: 3, y: 4}). + perform(). + thenCatch(assertIsStubError); + }); + + it('testTouchActionSequence', function() { + let executor = new FakeExecutor() + .expect(CName.TOUCH_DOWN, {x: 1, y: 2}).andReturnSuccess() + .expect(CName.TOUCH_MOVE, {x: 3, y: 4}).andReturnSuccess() + .expect(CName.TOUCH_UP, {x: 5, y: 6}).andReturnSuccess() + .end(); + + var driver = executor.createDriver(); + return driver.touchActions() + .tapAndHold({x: 1, y: 2}) + .move({x: 3, y: 4}) + .release({x: 5, y: 6}) + .perform(); + }); + }); + + describe('generator support', function() { + var driver; + + beforeEach(function() { + driver = new WebDriver( + new Session('test-session', {}), + new ExplodingExecutor()); + }); + + it('canUseGeneratorsWithWebDriverCall', function() { + return driver.call(function* () { + var x = yield promise.fulfilled(1); + var y = yield promise.fulfilled(2); + return x + y; + }).then(function(value) { + assert.deepEqual(3, value); + }); + }); + + it('canDefineScopeOnGeneratorCall', function() { + return driver.call(function* () { + var x = yield promise.fulfilled(1); + return this.name + x; + }, {name: 'Bob'}).then(function(value) { + assert.deepEqual('Bob1', value); + }); + }); + + it('canSpecifyArgsOnGeneratorCall', function() { + return driver.call(function* (a, b) { + var x = yield promise.fulfilled(1); + var y = yield promise.fulfilled(2); + return [x + y, a, b]; + }, null, 'abc', 123).then(function(value) { + assert.deepEqual([3, 'abc', 123], value); + }); + }); + + it('canUseGeneratorWithWebDriverWait', function() { + var values = []; + return driver.wait(function* () { + yield values.push(1); + values.push(yield promise.delayed(10).then(function() { + return 2; + })); + yield values.push(3); + return values.length === 6; + }, 250).then(function() { + assert.deepEqual([1, 2, 3, 1, 2, 3], values); + }); + }); + + /** + * @constructor + * @implements {CommandExecutor} + */ + function ExplodingExecutor() {} + + + /** @override */ + ExplodingExecutor.prototype.execute = function(command, cb) { + cb(Error('Unsupported operation')); + }; + }); + + describe('wire format', function() { + describe('can serialize', function() { + function runSerializeTest(input, want) { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({'desiredCapabilities': want}). + andReturnSuccess({'browserName': 'firefox'}). + end(); + return WebDriver.createSession(executor, input) + .getSession(); + } + + it('function as a string', function() { + function foo() { return 'foo'; } + return runSerializeTest(foo, '' + foo); + }); + + it('object with toJSON()', function() { + return runSerializeTest( + new Date(605728511546), + '1989-03-12T17:55:11.546Z'); + }); + + it('Session', function() { + return runSerializeTest(new Session('foo', {}), 'foo'); + }); + + it('Capabilities', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG); + + var caps = Capabilities.chrome(); + caps.setLoggingPrefs(prefs); + + return runSerializeTest( + caps, + { + 'browserName': 'chrome', + 'loggingPrefs': {'browser': 'DEBUG'} + }); + }); + + it('WebElement', function() { + return runSerializeTest( + new WebElement({}, 'fefifofum'), + WebElement.buildId('fefifofum')); + }); + + it('WebElementPromise', function() { + return runSerializeTest( + new WebElementPromise( + {}, promise.fulfilled(new WebElement({}, 'fefifofum'))), + WebElement.buildId('fefifofum')); + }); + + describe('an array', function() { + it('with Serializable', function() { + return runSerializeTest([new Session('foo', {})], ['foo']); + }); + + it('with WebElement', function() { + return runSerializeTest( + [new WebElement({}, 'fefifofum')], + [WebElement.buildId('fefifofum')]); + }); + + it('with WebElementPromise', function() { + return runSerializeTest( + [new WebElementPromise( + {}, promise.fulfilled(new WebElement({}, 'fefifofum')))], + [WebElement.buildId('fefifofum')]); + }); + + it('complex array', function() { + var expected = [ + 'abc', 123, true, WebElement.buildId('fefifofum'), + [123, {'foo': 'bar'}] + ]; + + var element = new WebElement({}, 'fefifofum'); + var input = ['abc', 123, true, element, [123, {'foo': 'bar'}]]; + return runSerializeTest(input, expected); + }); + + it('nested promises', function() { + return runSerializeTest( + ['abc', Promise.resolve([123, Promise.resolve(true)])], + ['abc', [123, true]]); + }); + }); + + describe('an object', function() { + it('literal', function() { + var expected = {sessionId: 'foo'}; + return runSerializeTest({sessionId: 'foo'}, expected); + }); + + it('with sub-objects', function() { + var expected = {sessionId: {value: 'foo'}}; + return runSerializeTest( + {sessionId: {value: 'foo'}}, expected); + }); + + it('with values that have toJSON', function() { + return runSerializeTest( + {a: {b: new Date(605728511546)}}, + {a: {b: '1989-03-12T17:55:11.546Z'}}); + }); + + it('with a Session', function() { + return runSerializeTest( + {a: new Session('foo', {})}, + {a: 'foo'}); + }); + + it('nested', function() { + var elementJson = WebElement.buildId('fefifofum'); + var expected = { + 'script': 'return 1', + 'args': ['abc', 123, true, elementJson, [123, {'foo': 'bar'}]], + 'sessionId': 'foo' + }; + + var element = new WebElement({}, 'fefifofum'); + var parameters = { + 'script': 'return 1', + 'args':['abc', 123, true, element, [123, {'foo': 'bar'}]], + 'sessionId': new Session('foo', {}) + }; + + return runSerializeTest(parameters, expected); + }); + }); + }); + + describe('can deserialize', function() { + function runDeserializeTest(original, want) { + let executor = new FakeExecutor() + .expect(CName.GET_CURRENT_URL) + .andReturnSuccess(original) + .end(); + let driver = executor.createDriver(); + return driver.getCurrentUrl().then(function(got) { + assert.deepEqual(got, want); + }); + } + + it('primitives', function() { + return Promise.all([ + runDeserializeTest(1, 1), + runDeserializeTest('', ''), + runDeserializeTest(true, true), + runDeserializeTest(undefined, undefined), + runDeserializeTest(null, null) + ]); + }); + + it('simple object', function() { + return runDeserializeTest( + {sessionId: 'foo'}, + {sessionId: 'foo'}); + }); + + it('nested object', function() { + return runDeserializeTest( + {'foo': {'bar': 123}}, + {'foo': {'bar': 123}}); + }); + + it('array', function() { + return runDeserializeTest( + [{'foo': {'bar': 123}}], + [{'foo': {'bar': 123}}]); + }); + + it('passes through function properties', function() { + function bar() {} + return runDeserializeTest( + [{foo: {'bar': 123}, func: bar}], + [{foo: {'bar': 123}, func: bar}]); + }); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/logging_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/logging_test.js new file mode 100644 index 0000000..fb8cdb2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/logging_test.js @@ -0,0 +1,167 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var Browser = require('..').Browser, + By = require('..').By, + logging = require('..').logging, + assert = require('../testing/assert'), + test = require('../lib/test'); + +test.suite(function(env) { + // Logging API has numerous issues with PhantomJS: + // - does not support adjusting log levels for type "browser". + // - does not return proper log level for "browser" messages. + // - does not delete logs after retrieval + // Logging API is not supported in IE. + // Tests depend on opening data URLs, which is broken in Safari (issue 7586) + test.ignore(env.browsers(Browser.PHANTOM_JS, Browser.IE, Browser.SAFARI)). + describe('logging', function() { + var driver; + + test.beforeEach(function() { + driver = null; + }); + + test.afterEach(function() { + if (driver) { + driver.quit(); + } + }); + + test.it('can be disabled', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.OFF); + + driver = env.builder() + .setLoggingPrefs(prefs) + .build(); + + driver.get(dataUrl( + '')); + driver.manage().logs().get(logging.Type.BROWSER).then(function(entries) { + assert(entries.length).equalTo(0); + }); + }); + + // Firefox does not capture JS error console log messages. + test.ignore(env.browsers(Browser.FIREFOX)). + it('can be turned down', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.SEVERE); + + driver = env.builder() + .setLoggingPrefs(prefs) + .build(); + + driver.get(dataUrl( + '')); + driver.manage().logs().get(logging.Type.BROWSER).then(function(entries) { + assert(entries.length).equalTo(1); + assert(entries[0].level.name).equalTo('SEVERE'); + assert(entries[0].message).endsWith('and this is an error'); + }); + }); + + // Firefox does not capture JS error console log messages. + test.ignore(env.browsers(Browser.FIREFOX)). + it('can be made verbose', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG); + + driver = env.builder() + .setLoggingPrefs(prefs) + .build(); + + driver.get(dataUrl( + '')); + driver.manage().logs().get(logging.Type.BROWSER).then(function(entries) { + assert(entries.length).equalTo(3); + assert(entries[0].level.name).equalTo('DEBUG'); + assert(entries[0].message).endsWith('hello'); + + assert(entries[1].level.name).equalTo('WARNING'); + assert(entries[1].message).endsWith('this is a warning'); + + assert(entries[2].level.name).equalTo('SEVERE'); + assert(entries[2].message).endsWith('and this is an error'); + }); + }); + + // Firefox does not capture JS error console log messages. + test.ignore(env.browsers(Browser.FIREFOX)). + it('clears records after retrieval', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG); + + driver = env.builder() + .setLoggingPrefs(prefs) + .build(); + + driver.get(dataUrl( + '')); + driver.manage().logs().get(logging.Type.BROWSER).then(function(entries) { + assert(entries.length).equalTo(3); + }); + driver.manage().logs().get(logging.Type.BROWSER).then(function(entries) { + assert(entries.length).equalTo(0); + }); + }); + + test.it('does not mix log types', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG); + prefs.setLevel(logging.Type.DRIVER, logging.Level.SEVERE); + + driver = env.builder() + .setLoggingPrefs(prefs) + .build(); + + driver.get(dataUrl( + '')); + driver.manage().logs().get(logging.Type.DRIVER).then(function(entries) { + assert(entries.length).equalTo(0); + }); + }); + }); + + function dataUrl(var_args) { + return 'data:text/html,' + + Array.prototype.slice.call(arguments, 0).join(''); + } +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/net/portprober_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/net/portprober_test.js new file mode 100644 index 0000000..03a2f7a --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/net/portprober_test.js @@ -0,0 +1,129 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'), + net = require('net'); + +var promise = require('../..').promise, + portprober = require('../../net/portprober'); + +describe('isFree', function() { + + var server; + + beforeEach(function() { + server = net.createServer(function(){}); + }) + + afterEach(function(done) { + if (!server) return done(); + server.close(function() { + done(); + }); + }); + + it('should work for INADDR_ANY', function(done) { + server.listen(0, function() { + var port = server.address().port; + assertPortNotfree(port).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); + + it('should work for a specific host', function(done) { + var host = '127.0.0.1'; + server.listen(0, host, function() { + var port = server.address().port; + assertPortNotfree(port, host).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port, host)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); +}); + +describe('findFreePort', function() { + var server; + + beforeEach(function() { + server = net.createServer(function(){}); + }) + + afterEach(function(done) { + if (!server) return done(); + server.close(function() { + done(); + }); + }); + + it('should work for INADDR_ANY', function(done) { + portprober.findFreePort().then(function(port) { + server.listen(port, function() { + assertPortNotfree(port).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); + }); + + it('should work for a specific host', function(done) { + var host = '127.0.0.1'; + portprober.findFreePort(host).then(function(port) { + server.listen(port, host, function() { + assertPortNotfree(port, host).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port, host)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); + }); +}); + + +function assertPortIsFree(port, opt_host) { + return portprober.isFree(port, opt_host).then(function(free) { + assert.ok(free, 'port should be free'); + }); +} + + +function assertPortNotfree(port, opt_host) { + return portprober.isFree(port, opt_host).then(function(free) { + assert.ok(!free, 'port should is not free'); + }); +} diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/page_loading_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/page_loading_test.js new file mode 100644 index 0000000..d59ca36 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/page_loading_test.js @@ -0,0 +1,164 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var Browser = require('..').Browser, + By = require('..').By, + error = require('../error'), + until = require('..').until, + assert = require('../testing/assert'), + test = require('../lib/test'), + Pages = test.Pages; + + +test.suite(function(env) { + var browsers = env.browsers; + + var driver; + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + test.it('should wait for document to be loaded', function() { + driver.get(Pages.simpleTestPage); + assert(driver.getTitle()).equalTo('Hello WebDriver'); + }); + + test.it('should follow redirects sent in the http response headers', + function() { + driver.get(Pages.redirectPage); + assert(driver.getTitle()).equalTo('We Arrive Here'); + }); + + test.it('should follow meta redirects', function() { + driver.get(Pages.metaRedirectPage); + assert(driver.getTitle()).equalTo('We Arrive Here'); + }); + + test.it('should be able to get a fragment on the current page', function() { + driver.get(Pages.xhtmlTestPage); + driver.get(Pages.xhtmlTestPage + '#text'); + driver.findElement(By.id('id1')); + }); + + test.ignore(browsers(Browser.IPAD, Browser.IPHONE)). + it('should wait for all frames to load in a frameset', function() { + driver.get(Pages.framesetPage); + driver.switchTo().frame(0); + + driver.findElement(By.css('span#pageNumber')).getText().then(function(txt) { + assert(txt.trim()).equalTo('1'); + }); + + driver.switchTo().defaultContent(); + driver.switchTo().frame(1); + driver.findElement(By.css('span#pageNumber')).getText().then(function(txt) { + assert(txt.trim()).equalTo('2'); + }); + }); + + test.ignore(browsers(Browser.SAFARI)). + it('should be able to navigate back in browser history', function() { + driver.get(Pages.formPage); + + driver.findElement(By.id('imageButton')).click(); + driver.wait(until.titleIs('We Arrive Here'), 2500); + + driver.navigate().back(); + driver.wait(until.titleIs('We Leave From Here'), 2500); + }); + + test.ignore(browsers(Browser.SAFARI)). + it('should be able to navigate back in presence of iframes', function() { + driver.get(Pages.xhtmlTestPage); + + driver.findElement(By.name('sameWindow')).click(); + driver.wait(until.titleIs('This page has iframes'), 2500); + + driver.navigate().back(); + driver.wait(until.titleIs('XHTML Test Page'), 2500); + }); + + test.ignore(browsers(Browser.SAFARI)). + it('should be able to navigate forwards in browser history', function() { + driver.get(Pages.formPage); + + driver.findElement(By.id('imageButton')).click(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + + driver.navigate().back(); + driver.wait(until.titleIs('We Leave From Here'), 5000); + + driver.navigate().forward(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + }); + + // PhantomJS 2.0 does not properly reload pages on refresh. + test.ignore(browsers(Browser.PHANTOM_JS)). + it('should be able to refresh a page', function() { + driver.get(Pages.xhtmlTestPage); + + driver.navigate().refresh(); + + assert(driver.getTitle()).equalTo('XHTML Test Page'); + }); + + test.it('should return title of page if set', function() { + driver.get(Pages.xhtmlTestPage); + assert(driver.getTitle()).equalTo('XHTML Test Page'); + + driver.get(Pages.simpleTestPage); + assert(driver.getTitle()).equalTo('Hello WebDriver'); + }); + + // Only implemented in Firefox. + test.ignore(browsers( + Browser.CHROME, + Browser.IE, + Browser.IPAD, + Browser.IPHONE, + Browser.OPERA, + Browser.PHANTOM_JS, + Browser.SAFARI)). + it('should timeout if page load timeout is set', function() { + driver.call(function() { + driver.manage().timeouts().pageLoadTimeout(1); + driver.get(Pages.sleepingPage + '?time=3'). + then(function() { + throw Error('Should have timed out on page load'); + }, function(e) { + if (!(e instanceof error.ScriptTimeoutError) + && !(e instanceof error.TimeoutError)) { + throw Error('Unexpected error response: ' + e); + } + }); + }).then(resetPageLoad, function(err) { + resetPageLoad().thenFinally(function() { + throw err; + }); + }); + + function resetPageLoad() { + return driver.manage().timeouts().pageLoadTimeout(-1); + } + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/phantomjs/execute_phantomjs_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/phantomjs/execute_phantomjs_test.js new file mode 100644 index 0000000..22a9a22 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/phantomjs/execute_phantomjs_test.js @@ -0,0 +1,73 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'); +var path = require('path'); +var test = require('../../lib/test'); + +test.suite(function(env) { + var driver; + + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + var testPageUrl = + 'data:text/html,

    ' + path.basename(__filename) + '

    '; + + test.beforeEach(function() { + driver.get(testPageUrl); + }); + + describe('phantomjs.Driver', function() { + describe('#executePhantomJS()', function() { + + test.it('can execute scripts using PhantomJS API', function() { + return driver.executePhantomJS('return this.url;').then(function(url) { + assert.equal(testPageUrl, decodeURIComponent(url)); + }); + }); + + test.it('can execute scripts as functions', function() { + driver.executePhantomJS(function(a, b) { + return a + b; + }, 1, 2).then(function(result) { + assert.equal(3, result); + }); + }); + + test.it('can manipulate the current page', function() { + driver.manage().addCookie('foo', 'bar'); + driver.manage().getCookie('foo').then(function(cookie) { + assert.equal('bar', cookie.value); + }); + driver.executePhantomJS(function() { + this.clearCookies(); + }); + driver.manage().getCookie('foo').then(function(cookie) { + assert.equal(null, cookie); + }); + }); + }); + }); +}, {browsers: ['phantomjs']}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/proxy_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/proxy_test.js new file mode 100644 index 0000000..b7a894f --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/proxy_test.js @@ -0,0 +1,170 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var http = require('http'), + url = require('url'); + +var Browser = require('..').Browser, + promise = require('..').promise, + proxy = require('../proxy'), + assert = require('../testing/assert'), + test = require('../lib/test'), + Server = require('../lib/test/httpserver').Server, + Pages = test.Pages; + + +test.suite(function(env) { + function writeResponse(res, body, encoding, contentType) { + res.writeHead(200, { + 'Content-Length': Buffer.byteLength(body, encoding), + 'Content-Type': contentType + }); + res.end(body); + } + + function writePacFile(res) { + writeResponse(res, [ + 'function FindProxyForURL(url, host) {', + ' if (shExpMatch(url, "' + goodbyeServer.url('*') + '")) {', + ' return "DIRECT";', + ' }', + ' return "PROXY ' + proxyServer.host() + '";', + '}' + ].join('\n'), 'ascii', 'application/x-javascript-config'); + } + + var proxyServer = new Server(function(req, res) { + var pathname = url.parse(req.url).pathname; + if (pathname === '/proxy.pac') { + return writePacFile(res); + } + + writeResponse(res, [ + '', + 'Proxy page', + '

    This is the proxy landing page

    ' + ].join(''), 'utf8', 'text/html; charset=UTF-8'); + }); + + var helloServer = new Server(function(req, res) { + writeResponse(res, [ + '', + 'Hello', + '

    Hello, world!

    ' + ].join(''), 'utf8', 'text/html; charset=UTF-8'); + }); + + var goodbyeServer = new Server(function(req, res) { + writeResponse(res, [ + '', + 'Goodbye', + '

    Goodbye, world!

    ' + ].join(''), 'utf8', 'text/html; charset=UTF-8'); + }); + + // Cannot pass start directly to mocha's before, as mocha will interpret the optional + // port parameter as an async callback parameter. + function mkStartFunc(server) { + return function() { + return server.start(); + }; + } + + + test.before(mkStartFunc(proxyServer)); + test.before(mkStartFunc(helloServer)); + test.before(mkStartFunc(goodbyeServer)); + + test.after(proxyServer.stop.bind(proxyServer)); + test.after(helloServer.stop.bind(helloServer)); + test.after(goodbyeServer.stop.bind(goodbyeServer)); + + var driver; + test.beforeEach(function() { driver = null; }); + test.afterEach(function() { driver && driver.quit(); }); + + // Proxy support not implemented. + test.ignore(env.browsers(Browser.IE, Browser.OPERA, Browser.SAFARI)). + describe('manual proxy settings', function() { + // phantomjs 1.9.1 in webdriver mode does not appear to respect proxy + // settings. + test.ignore(env.browsers(Browser.PHANTOM_JS)). + it('can configure HTTP proxy host', function() { + driver = env.builder(). + setProxy(proxy.manual({ + http: proxyServer.host() + })). + build(); + + driver.get(helloServer.url()); + assert(driver.getTitle()).equalTo('Proxy page'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('This is the proxy landing page'); + }); + + // PhantomJS does not support bypassing the proxy for individual hosts. + test.ignore(env.browsers(Browser.PHANTOM_JS)). + it('can bypass proxy for specific hosts', function() { + driver = env.builder(). + setProxy(proxy.manual({ + http: proxyServer.host(), + bypass: helloServer.host() + })). + build(); + + driver.get(helloServer.url()); + assert(driver.getTitle()).equalTo('Hello'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('Hello, world!'); + + driver.get(goodbyeServer.url()); + assert(driver.getTitle()).equalTo('Proxy page'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('This is the proxy landing page'); + }); + + // TODO: test ftp and https proxies. + }); + + // PhantomJS does not support PAC file proxy configuration. + // Safari does not support proxies. + test.ignore(env.browsers( + Browser.IE, Browser.OPERA, Browser.PHANTOM_JS, Browser.SAFARI)). + describe('pac proxy settings', function() { + test.it('can configure proxy through PAC file', function() { + driver = env.builder(). + setProxy(proxy.pac(proxyServer.url('/proxy.pac'))). + build(); + + driver.get(helloServer.url()); + assert(driver.getTitle()).equalTo('Proxy page'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('This is the proxy landing page'); + + driver.get(goodbyeServer.url()); + assert(driver.getTitle()).equalTo('Goodbye'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('Goodbye, world!'); + }); + }); + + // TODO: figure out how to test direct and system proxy settings. + describe.skip('direct proxy settings', function() {}); + describe.skip('system proxy settings', function() {}); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/remote_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/remote_test.js new file mode 100644 index 0000000..c103d81 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/remote_test.js @@ -0,0 +1,72 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +var assert = require('assert'); + +var promise = require('../').promise; +var remote = require('../remote'); + +describe('DriverService', function() { + describe('start()', function() { + var service; + + beforeEach(function() { + service = new remote.DriverService(process.execPath, { + port: 1234, + args: ['-e', 'process.exit(1)'] + }); + }); + + afterEach(function(done) { + service.kill().thenFinally(function() { + done(); + }); + }); + + it('fails if child-process dies', function(done) { + this.timeout(1000); + service.start(500) + .then(expectFailure.bind(null, done), verifyFailure.bind(null, done)); + }); + + it('failures propagate through control flow if child-process dies', + function(done) { + this.timeout(1000); + + promise.controlFlow().execute(function() { + promise.controlFlow().execute(function() { + return service.start(500); + }); + }) + .then(expectFailure.bind(null, done), verifyFailure.bind(null, done)); + }); + + function verifyFailure(done, e) { + try { + assert.ok(!(e instanceof promise.CancellationError)); + assert.equal('Server terminated early with status 1', e.message); + done(); + } catch (ex) { + done(ex); + } + } + + function expectFailure(done) { + done(Error('expected to fail')); + } + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/stale_element_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/stale_element_test.js new file mode 100644 index 0000000..72833d8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/stale_element_test.js @@ -0,0 +1,58 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fail = require('assert').fail; + +var Browser = require('..').Browser, + By = require('..').By, + error = require('..').error, + until = require('..').until, + assert = require('../testing/assert'), + test = require('../lib/test'), + Pages = test.Pages; + + +test.suite(function(env) { + var driver; + test.before(function() { driver = env.builder().build(); }); + test.after(function() { driver.quit(); }); + + test.it( + 'dynamically removing elements from the DOM trigger a ' + + 'StaleElementReferenceError', + function() { + driver.get(Pages.javascriptPage); + + var toBeDeleted = driver.findElement(By.id('deleted')); + assert(toBeDeleted.isDisplayed()).isTrue(); + + driver.findElement(By.id('delete')).click(); + driver.wait(until.stalenessOf(toBeDeleted), 5000); + }); + + test.it('an element found in a different frame is stale', function() { + driver.get(Pages.missedJsReferencePage); + driver.switchTo().frame('inner'); + var el = driver.findElement(By.id('oneline')); + driver.switchTo().defaultContent(); + el.getText().then(fail, function(e) { + assert(e).instanceOf(error.StaleElementReferenceError); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/tag_name_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/tag_name_test.js new file mode 100644 index 0000000..d5e18a9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/tag_name_test.js @@ -0,0 +1,34 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var By = require('..').By, + assert = require('../testing/assert'), + test = require('../lib/test'); + + +test.suite(function(env) { + var driver; + test.after(function() { driver.quit(); }); + + test.it('should return lower case tag name', function() { + driver = env.builder().build(); + driver.get(test.Pages.formPage); + assert(driver.findElement(By.id('cheese')).getTagName()).equalTo('input'); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/testing/assert_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/testing/assert_test.js new file mode 100644 index 0000000..8c88482 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/testing/assert_test.js @@ -0,0 +1,374 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('../../testing/assert'); + +const AssertionError = require('assert').AssertionError; +const assertTrue = require('assert').ok; +const assertEqual = require('assert').equal; +const assertThrows = require('assert').throws; +const fail = require('assert').fail; + + +describe('assert', function() { + describe('atLeast', function() { + it('compares subject >= value', function() { + assert(1).atLeast(0); + assert(1).atLeast(1); + assertThrows(() => assert(1).atLeast(2)); + }); + + it('accepts failure message', function() { + assertThrows( + () => assert(1).atLeast(2, 'hi there!'), + (error) => error.message.indexOf('hi there') != -1); + }); + + it('fails if given a non-numeric subject', function() { + assertThrows(() => assert('a').atLeast(1)); + }); + + it('fails if given a non-numeric bound', function() { + assertThrows(() => assert(1).atLeast('a')); + }); + + it('waits for promised subject', function() { + return assert(Promise.resolve(123)).atLeast(100); + }); + + it('waits for promised subject (with failure)', function() { + return assert(Promise.resolve(100)) + .atLeast(123) + .then(() => fail('should have failed'), function(e) { + assertInstanceOf(AssertionError, e); + assertEqual('100 >= 123', e.message); + }); + }); + }); + + describe('atMost', function() { + it('compares subject <= value', function() { + assertThrows(() => assert(1).atMost(0)); + assert(1).atMost(1); + assert(1).atMost(2); + }); + + it('accepts failure message', function() { + assertThrows( + () => assert(1).atMost(0, 'hi there!'), + (error) => error.message.indexOf('hi there!') != -1); + }); + + it('fails if given a non-numeric subject', function() { + assertThrows(() => assert(1).atMost('a')); + }); + + it('fails if given a non-numeric bound', function() { + assertThrows(() => assert('a').atMost(1)); + }); + + it('waits for promised subject', function() { + return assert(Promise.resolve(100)).atMost(123); + }); + + it('waits for promised subject (with failure)', function() { + return assert(Promise.resolve(123)) + .atMost(100) + .then(() => fail('should have failed'), function(e) { + assertInstanceOf(AssertionError, e); + assertEqual('123 <= 100', e.message); + }); + }); + }); + + describe('greaterThan', function() { + it('compares subject > value', function() { + assertThrows(() => assert(1).greaterThan(1)); + assertThrows(() => assert(1).greaterThan(2)); + assert(2).greaterThan(1); + }); + + it('accepts failure message', function() { + assertThrows( + () => assert(0).greaterThan(1, 'hi there!'), + (error) => error.message.indexOf('hi there!') != -1); + }); + + it('fails if given a non-numeric subject', function() { + assertThrows(() => assert('a').atMost(1)); + }); + + it('fails if given a non-numeric bound', function() { + assertThrows(() => assert(1).atMost('a')); + }); + + it('waits for promised subject', function() { + return assert(Promise.resolve(123)).greaterThan(100); + }); + + it('waits for promised subject (with failure)', function() { + return assert(Promise.resolve(100)) + .greaterThan(123) + .then(() => fail('should have failed'), function(e) { + assertInstanceOf(AssertionError, e); + assertEqual('100 > 123', e.message); + }); + }); + }); + + describe('lessThan', function() { + it('compares subject < value', function() { + assertThrows(() => assert(1).lessThan(0)); + assertThrows(() => assert(1).lessThan(1)); + assert(1).lessThan(2); + }); + + it('accepts failure message', function() { + assertThrows( + () => assert(1).lessThan(0, 'hi there!'), + (error) => error.message.indexOf('hi there!') != -1); + }); + + it('fails if given a non-numeric subject', function() { + assertThrows(() => assert('a').lessThan(1)); + }); + + it('fails if given a non-numeric bound', function() { + assertThrows(() => assert(1).lessThan('a')); + }); + + it('waits for promised subject', function() { + return assert(Promise.resolve(100)).lessThan(123); + }); + + it('waits for promised subject (with failure)', function() { + return assert(Promise.resolve(123)) + .lessThan(100) + .then(() => fail('should have failed'), function(e) { + assertInstanceOf(AssertionError, e); + assertEqual('123 < 100', e.message); + }); + }); + }); + + describe('closeTo', function() { + it('accepts values within epislon of target', function() { + assert(123).closeTo(123, 0); + assert(123).closeTo(124, 1); + assert(125).closeTo(124, 1); + + assertThrows(() => assert(123).closeTo(125, .1)); + assertThrows(() => assert(1./3).closeTo(.8, .01)); + }); + + it('waits for promised values', function() { + let d = Promise.defer(); + setTimeout(() => d.resolve(123), 10); + return assert(d.promise).closeTo(124, 1); + }); + }); + + describe('instanceOf', function() { + it('works with direct instances', function() { + assert(Error('foo')).instanceOf(Error); + }); + + it('works with sub-types', function() { + assert(TypeError('foo')).instanceOf(Error); + }); + + it('parent types are not instances of sub-types', function() { + assertThrows(() => assert(Error('foo')).instanceOf(TypeError)); + }); + }); + + describe('isNull', function() { + it('normal case', function() { + assert(null).isNull(); + assertThrows(() => assert(1).isNull()); + }); + + it('handles promised values', function() { + let p = new Promise(function(f) { + setTimeout(() => f(null), 10); + }); + return assert(p).isNull(); + }); + + it('does not match on undefined', function() { + assertThrows(() => assert(void(0)).isNull()); + }) + }); + + describe('isUndefined', function() { + it('normal case', function() { + assert(void(0)).isUndefined(); + assertThrows(() => assert(1).isUndefined()); + }); + + it('handles promised values', function() { + let p = new Promise(function(f) { + setTimeout(() => f(void(0)), 10); + }); + return assert(p).isUndefined(); + }); + + it('does not match on null', function() { + assertThrows(() => assert(null).isUndefined()); + }) + }); + + describe('contains', function() { + it('works with strings', function() { + assert('abc').contains('a'); + assert('abc').contains('ab'); + assert('abc').contains('abc'); + assert('abc').contains('bc'); + assert('abc').contains('c'); + assertThrows(() => assert('abc').contains('d')); + }); + + it('works with arrays', function() { + assert([1, 2, 3]).contains(1); + assert([1, 2, 3]).contains(2); + assert([1, 2, 3]).contains(3); + assertThrows(() => assert([1, 2]).contains(3)); + }); + + it('works with maps', function() { + let m = new Map; + m.set(1, 2); + assert(m).contains(1); + assertThrows(() => assert(m).contains(2)); + }); + + it('works with sets', function() { + let s = new Set; + s.add(1); + assert(s).contains(1); + assertThrows(() => assert(s).contains(2)); + }); + + it('requires an array, string, map, or set subject', function() { + assertThrows(() => assert(123).contains('a')); + }); + }); + + describe('endsWith', function() { + it('works', function() { + assert('abc').endsWith('abc'); + assert('abc').endsWith('bc'); + assert('abc').endsWith('c'); + assertThrows(() => assert('abc').endsWith('d')); + }) + }); + + describe('startsWith', function() { + it('works', function() { + assert('abc').startsWith('abc'); + assert('abc').startsWith('ab'); + assert('abc').startsWith('a'); + assertThrows(() => assert('abc').startsWith('d')); + }) + }); + + describe('matches', function() { + it('requires a regex value', function() { + assertThrows(() => assert('abc').matches(1234)); + }); + + it('requires a string value', function() { + assertThrows(() => assert(1234).matches(/abc/)); + }); + + it('requires a string value (promise case)', function() { + return assert(Promise.resolve(1234)) + .matches(/abc/) + .then(fail, function(error) { + assertEqual( + 'Expected a string matching /abc/, got <1234> (number)', + error.message); + }); + }); + + it('applies regex', function() { + assert('abc').matches(/abc/); + assertThrows(() => assert('def').matches(/abc/)); + }); + }); + + describe('isTrue', function() { + it('only accepts booleans', function() { + assertThrows(() => assert(123).isTrue()); + }); + + it('accepts true values', function() { + assert(true).isTrue(); + assert(Boolean('abc')).isTrue(); + return assert(Promise.resolve(true)).isTrue(); + }); + + it('rejects false values', function() { + assertThrows(() => assert(false).isTrue()); + assertThrows(() => assert(Boolean(0)).isTrue()); + return assert(Promise.resolve(false)).isTrue() + .then(fail, function() {/*no-op, ok*/}); + }); + }); + + describe('isFalse', function() { + it('only accepts booleans', function() { + assertThrows(() => assert(123).isFalse()); + }) + + it('accepts false values', function() { + assert(false).isFalse(); + assert(Boolean('')).isFalse(); + return assert(Promise.resolve(false)).isFalse(); + }); + + it('rejects true values', function() { + assertThrows(() => assert(true).isFalse()); + assertThrows(() => assert(Boolean(1)).isFalse()); + return assert(Promise.resolve(true)).isFalse() + .then(fail, function() {/*no-op, ok*/}); + }); + }); + + describe('isEqualTo', function() { + it('is strict equality', function() { + assert('abc').isEqualTo('abc'); + assert('abc').equals('abc'); + assert('abc').equalTo('abc'); + assertThrows(() => assert('1').isEqualTo(1)); + }); + }); + + describe('notEqualTo', function() { + it('tests strict equality', function() { + assert('1').notEqualTo(1); + assert(1).notEqualTo('1'); + assertThrows(() => assert('abc').notEqualTo('abc')); + }); + }); + + function assertInstanceOf(ctor, value) { + assertTrue(value instanceof ctor); + } +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/testing/index_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/testing/index_test.js new file mode 100644 index 0000000..31acff2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/testing/index_test.js @@ -0,0 +1,178 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'); +var promise = require('../..').promise; + +var test = require('../../testing'); + +describe('Mocha Integration', function() { + + describe('beforeEach properly binds "this"', function() { + beforeEach(function() { this.x = 1; }); + test.beforeEach(function() { this.x = 2; }); + it('', function() { assert.equal(this.x, 2); }); + }); + + describe('afterEach properly binds "this"', function() { + it('', function() { this.x = 1; }); + test.afterEach(function() { this.x = 2; }); + afterEach(function() { assert.equal(this.x, 2); }); + }); + + describe('it properly binds "this"', function() { + beforeEach(function() { this.x = 1; }); + test.it('', function() { this.x = 2; }); + afterEach(function() { assert.equal(this.x, 2); }); + }); + + describe('timeout handling', function() { + describe('it does not reset the control flow on a non-timeout', function() { + var flowReset = false; + + beforeEach(function() { + flowReset = false; + test.controlFlow().once(promise.ControlFlow.EventType.RESET, onreset); + }); + + test.it('', function() { + this.timeout(100); + return promise.delayed(50); + }); + + afterEach(function() { + assert.ok(!flowReset); + test.controlFlow().removeListener( + promise.ControlFlow.EventType.RESET, onreset); + }); + + function onreset() { + flowReset = true; + } + }); + + describe('it resets the control flow after a timeout' ,function() { + var timeoutErr, flowReset; + + beforeEach(function() { + flowReset = false; + test.controlFlow().once(promise.ControlFlow.EventType.RESET, onreset); + }); + + test.it('', function() { + var callback = this.runnable().callback; + var test = this; + this.runnable().callback = function(err) { + timeoutErr = err; + // Reset our timeout to 0 so Mocha does not fail the test. + test.timeout(0); + // When we invoke the real callback, do not pass along the error so + // Mocha does not fail the test. + return callback.call(this); + }; + + test.timeout(50); + return promise.defer().promise; + }); + + afterEach(function() { + return Promise.resolve().then(function() { + test.controlFlow().removeListener( + promise.ControlFlow.EventType.RESET, onreset); + assert.ok(flowReset, 'control flow was not reset after a timeout'); + }); + }); + + function onreset() { + flowReset = true; + } + }); + }); +}); + +describe('Mocha async "done" support', function() { + this.timeout(2*1000); + + var waited = false; + var DELAY = 100; // ms enough to notice + + // Each test asynchronously sets waited to true, so clear/check waited + // before/after: + beforeEach(function() { + waited = false; + }); + + afterEach(function() { + assert.strictEqual(waited, true); + }); + + // --- First, vanilla mocha "it" should support the "done" callback correctly. + + // This 'it' should block until 'done' is invoked + it('vanilla delayed', function(done) { + setTimeout(function delayedVanillaTimeout() { + waited = true; + done(); + }, DELAY); + }); + + // --- Now with the webdriver wrappers for 'it' should support the "done" callback: + + test.it('delayed', function(done) { + assert(done); + assert.strictEqual(typeof done, 'function'); + setTimeout(function delayedTimeoutCallback() { + waited = true; + done(); + }, DELAY); + }); + + // --- And test that the webdriver wrapper for 'it' works with a returned promise, too: + + test.it('delayed by promise', function() { + var defer = promise.defer(); + setTimeout(function delayedPromiseCallback() { + waited = true; + defer.fulfill('ignored'); + }); + return defer.promise; + }); + +}); + +describe('ControlFlow and "done" work together', function() { + var flow, order; + before(function() { + order = []; + flow = test.controlFlow(); + flow.execute(function() { order.push(1); }); + }); + + test.it('control flow updates and async done', function(done) { + flow.execute(function() { order.push(2); }); + flow.execute(function() { order.push(3); }).then(function() { + order.push(4); + }); + done(); + }) + + after(function() { + assert.deepEqual([1, 2, 3, 4], order); + }) +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/upload_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/upload_test.js new file mode 100644 index 0000000..f7fd907 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/upload_test.js @@ -0,0 +1,85 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fs = require('fs'); + +var Browser = require('..').Browser, + By = require('..').By, + until = require('..').until, + io = require('../io'), + remote = require('../remote'), + assert = require('../testing/assert'), + test = require('../lib/test'), + Pages = test.Pages; + +test.suite(function(env) { + var LOREM_IPSUM_TEXT = 'lorem ipsum dolor sit amet'; + var FILE_HTML = '
    ' + LOREM_IPSUM_TEXT + '
    '; + + var fp; + test.before(function() { + return fp = io.tmpFile().then(function(fp) { + fs.writeFileSync(fp, FILE_HTML); + return fp; + }); + }) + + var driver; + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + if (driver) { + driver.quit(); + } + }); + + test.ignore(env.browsers( + Browser.IPAD, + Browser.IPHONE, + // Uploads broken in PhantomJS 2.0. + // See https://github.com/ariya/phantomjs/issues/12506 + Browser.PHANTOM_JS, + Browser.SAFARI)). + it('can upload files', function() { + driver.setFileDetector(new remote.FileDetector); + + driver.get(Pages.uploadPage); + + var fp = driver.call(function() { + return io.tmpFile().then(function(fp) { + fs.writeFileSync(fp, FILE_HTML); + return fp; + }); + }); + + driver.findElement(By.id('upload')).sendKeys(fp); + driver.findElement(By.id('go')).submit(); + + // Uploading files across a network may take a while, even if they're small. + var label = driver.findElement(By.id('upload_label')); + driver.wait(until.elementIsNotVisible(label), + 10 * 1000, 'File took longer than 10 seconds to upload!'); + + driver.switchTo().frame('upload_target'); + assert(driver.findElement(By.css('body')).getText()) + .equalTo(LOREM_IPSUM_TEXT); + }); +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/test/window_test.js b/platforms/android/assets/www/node_modules/selenium-webdriver/test/window_test.js new file mode 100644 index 0000000..959c9dc --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/test/window_test.js @@ -0,0 +1,128 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var Browser = require('..').Browser, + assert = require('../testing/assert'), + test = require('../lib/test'); + + +test.suite(function(env) { + var driver; + + test.before(function() { driver = env.builder().build(); }); + test.after(function() { driver.quit(); }); + + test.beforeEach(function() { + driver.switchTo().defaultContent(); + }); + + test.it('can set size of the current window', function() { + changeSizeBy(-20, -20); + }); + + test.it('can set size of the current window from frame', function() { + driver.get(test.Pages.framesetPage); + driver.switchTo().frame('fourth'); + changeSizeBy(-20, -20); + }); + + test.it('can set size of the current window from iframe', function() { + driver.get(test.Pages.iframePage); + driver.switchTo().frame('iframe1-name'); + changeSizeBy(-20, -20); + }); + + test.it('can set the window position of the current window', function() { + driver.manage().window().getPosition().then(function(position) { + driver.manage().window().setSize(640, 480); + driver.manage().window().setPosition(position.x + 10, position.y + 10); + + // For phantomjs, setPosition is a no-op and the "window" stays at (0, 0) + if (env.currentBrowser() === Browser.PHANTOM_JS) { + driver.manage().window().getPosition().then(function(position) { + assert(position.x).equalTo(0); + assert(position.y).equalTo(0); + }); + } else { + var dx = position.x + 10; + var dy = position.y + 10; + // On OSX, Safari position's the window relative to below the menubar + // at the top of the screen, which is 23 pixels tall. + if (env.currentBrowser() === Browser.SAFARI && + process.platform === 'darwin') { + dy += 23; + } + } + }); + }); + + test.it('can set the window position from a frame', function() { + driver.get(test.Pages.iframePage); + driver.switchTo().frame('iframe1-name'); + driver.manage().window().getPosition().then(function(position) { + driver.manage().window().setSize(640, 480); + driver.manage().window().setPosition(position.x + 10, position.y + 10); + + // For phantomjs, setPosition is a no-op and the "window" stays at (0, 0) + if (env.currentBrowser() === Browser.PHANTOM_JS) { + driver.manage().window().getPosition().then(function(position) { + assert(position.x).equalTo(0); + assert(position.y).equalTo(0); + }); + } else { + var dx = position.x + 10; + var dy = position.y + 10; + // On OSX, Safari position's the window relative to below the menubar + // at the top of the screen, which is 23 pixels tall. + if (env.currentBrowser() === Browser.SAFARI && + process.platform === 'darwin') { + dy += 23; + } + driver.wait(forPositionToBe(dx, dy), 1000); + } + }); + }); + + function changeSizeBy(dx, dy) { + driver.manage().window().getSize().then(function(size) { + driver.manage().window().setSize(size.width + dx, size.height + dy); + driver.wait(forSizeToBe(size.width + dx, size.height + dy), 1000); + }); + } + + function forSizeToBe(w, h) { + return function() { + return driver.manage().window().getSize().then(function(size) { + return size.width === w && size.height === h; + }); + }; + } + + function forPositionToBe(x, y) { + return function() { + return driver.manage().window().getPosition().then(function(position) { + return position.x === x && + // On OSX, the window height may be bumped down 22px for the top + // status bar. + // On Linux, Opera's window position will be off by 28px. + (position.y >= y && position.y <= (y + 28)); + }); + }; + } +}); diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/testing/assert.js b/platforms/android/assets/www/node_modules/selenium-webdriver/testing/assert.js new file mode 100644 index 0000000..0d8eb62 --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/testing/assert.js @@ -0,0 +1,378 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a library that simplifies writing assertions against + * promised values. + * + * >
    + * > __NOTE:__ This module is considered experimental and is subject to + * > change, or removal, at any time! + * >
    + * + * Sample usage: + * + * var driver = new webdriver.Builder().build(); + * driver.get('http://www.google.com'); + * + * assert(driver.getTitle()).equalTo('Google'); + */ + +'use strict'; + +const assert = require('assert'); + +function trueType(v) { + if (v === null) { + return 'null'; + } + + let type = typeof v; + if (type === 'object') { + if (Array.isArray(v)) { + type = 'array'; + } + } + return type; +} + + +function checkType(v, want) { + let got = trueType(v); + if (got !== want) { + throw new TypeError('require ' + want + ', but got ' + got); + } + return v; +} + +const checkNumber = v => checkType(v, 'number'); +const checkFunction = v => checkType(v, 'function'); +const checkString = v => checkType(v, 'string'); + +const isFunction = v => trueType(v) === 'function'; +const isNumber = v => trueType(v) === 'number'; +const isObject = v => trueType(v) === 'object'; +const isString = v => trueType(v) === 'string'; + + +function describe(value) { + let ret; + try { + ret = `<${String(value)}>`; + } catch (e) { + ret = ``; + } + + if (null !== value && void(0) !== value) { + ret += ` (${trueType(value)})`; + } + + return ret; +} + + +function evaluate(value, predicate) { + if (isObject(value) && isFunction(value.then)) { + return value.then(predicate); + } + predicate(value); +} + + +/** + * @private + */ +class Assertion { + /** + * @param {?} subject The subject of this assertion. + * @param {boolean=} opt_invert Whether to invert any assertions performed by + * this instance. + */ + constructor(subject, opt_invert) { + /** @private {?} */ + this.subject_ = subject; + /** @private {boolean} */ + this.invert_ = !!opt_invert; + } + + /** + * @param {number} expected The minimum permissible value (inclusive). + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + atLeast(expected, opt_message) { + checkNumber(expected); + return evaluate(this.subject_, function(actual) { + if (!isNumber(actual) || actual < expected) { + assert.fail(actual, expected, opt_message, '>='); + } + }); + } + + /** + * @param {number} expected The maximum permissible value (inclusive). + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + atMost(expected, opt_message) { + checkNumber(expected); + return evaluate(this.subject_, function (actual) { + if (!isNumber(actual) || actual > expected) { + assert.fail(actual, expected, opt_message, '<='); + } + }); + } + + /** + * @param {number} expected The maximum permissible value (exclusive). + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + greaterThan(expected, opt_message) { + checkNumber(expected); + return evaluate(this.subject_, function(actual) { + if (!isNumber(actual) || actual <= expected) { + assert.fail(actual, expected, opt_message, '>'); + } + }); + } + + /** + * @param {number} expected The minimum permissible value (exclusive). + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + lessThan(expected, opt_message) { + checkNumber(expected); + return evaluate(this.subject_, function (actual) { + if (!isNumber(actual) || actual >= expected) { + assert.fail(actual, expected, opt_message, '<'); + } + }); + } + + /** + * @param {number} expected The desired value. + * @param {number} epsilon The maximum distance from the desired value. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + closeTo(expected, episolon, opt_message) { + checkNumber(expected); + checkNumber(episolon); + return evaluate(this.subject_, function(actual) { + checkNumber(actual); + if (Math.abs(expected - actual) > episolon) { + assert.fail(opt_message || `${actual} === ${expected} (± ${episolon})`); + } + }); + } + + /** + * @param {function(new: ?)} ctor The exptected type's constructor. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + instanceOf(ctor, opt_message) { + checkFunction(ctor); + return evaluate(this.subject_, function(actual) { + if (!(actual instanceof ctor)) { + assert.fail( + opt_message + || `${describe(actual)} instanceof ${ctor.name || ctor}`); + } + }); + } + + /** + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + isNull(opt_message) { + return this.isEqualTo(null); + } + + /** + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + isUndefined(opt_message) { + return this.isEqualTo(void(0)); + } + + /** + * Ensures the subject of this assertion is either a string or array + * containing the given `value`. + * + * @param {?} value The value expected to be contained within the subject. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + contains(value, opt_message) { + return evaluate(this.subject_, function(actual) { + if (actual instanceof Map || actual instanceof Set) { + assert.ok(actual.has(value), opt_message || `${actual}.has(${value})`); + } else if (Array.isArray(actual) || isString(actual)) { + assert.ok( + actual.indexOf(value) !== -1, + opt_message || `${actual}.indexOf(${value}) !== -1`); + } else { + assert.fail( + `Expected an array, map, set, or string: got ${describe(actual)}`); + } + }); + } + + /** + * @param {string} str The expected suffix. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + endsWith(str, opt_message) { + checkString(str); + return evaluate(this.subject_, function(actual) { + if (!isString(actual) || !actual.endsWith(str)) { + assert.fail(actual, str, 'ends with'); + } + }); + } + + /** + * @param {string} str The expected prefix. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + startsWith(str, opt_message) { + checkString(str); + return evaluate(this.subject_, function(actual) { + if (!isString(actual) || !actual.startsWith(str)) { + assert.fail(actual, str, 'starts with'); + } + }); + } + + /** + * @param {!RegExp} regex The regex the subject is expected to match. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + matches(regex, opt_message) { + if (!(regex instanceof RegExp)) { + throw TypeError(`Not a RegExp: ${describe(regex)}`); + } + return evaluate(this.subject_, function(actual) { + if (!isString(actual) || !regex.test(actual)) { + let message = opt_message + || `Expected a string matching ${regex}, got ${describe(actual)}`; + assert.fail(actual, regex, message); + } + }); + } + + /** + * @param {?} value The unexpected value. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + notEqualTo(value, opt_message) { + return evaluate(this.subject_, function(actual) { + assert.notStrictEqual(actual, value, opt_message); + }); + } + + /** An alias for {@link #isEqualTo}. */ + equalTo(value, opt_message) { + return this.isEqualTo(value, opt_message); + } + + /** An alias for {@link #isEqualTo}. */ + equals(value, opt_message) { + return this.isEqualTo(value, opt_message); + } + + /** + * @param {?} value The expected value. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + isEqualTo(value, opt_message) { + return evaluate(this.subject_, function(actual) { + assert.strictEqual(actual, value, opt_message); + }); + } + + /** + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + isTrue(opt_message) { + return this.isEqualTo(true, opt_message); + } + + /** + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + isFalse(opt_message) { + return this.isEqualTo(false, opt_message); + } +} + + +// PUBLIC API + + +/** + * Creates an assertion about the given `value`. + * @return {!Assertion} the new assertion. + */ +module.exports = function assertThat(value) { + return new Assertion(value); +}; +module.exports.Assertion = Assertion; // Exported to help generated docs diff --git a/platforms/android/assets/www/node_modules/selenium-webdriver/testing/index.js b/platforms/android/assets/www/node_modules/selenium-webdriver/testing/index.js new file mode 100644 index 0000000..1ad1f8b --- /dev/null +++ b/platforms/android/assets/www/node_modules/selenium-webdriver/testing/index.js @@ -0,0 +1,268 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Provides wrappers around the following global functions from + * [Mocha's BDD interface](https://github.com/mochajs/mocha): + * + * - after + * - afterEach + * - before + * - beforeEach + * - it + * - it.only + * - it.skip + * - xit + * + * The provided wrappers leverage the {@link webdriver.promise.ControlFlow} + * to simplify writing asynchronous tests: + * + * var By = require('selenium-webdriver').By, + * until = require('selenium-webdriver').until, + * firefox = require('selenium-webdriver/firefox'), + * test = require('selenium-webdriver/testing'); + * + * test.describe('Google Search', function() { + * var driver; + * + * test.before(function() { + * driver = new firefox.Driver(); + * }); + * + * test.after(function() { + * driver.quit(); + * }); + * + * test.it('should append query to title', function() { + * driver.get('http://www.google.com/ncr'); + * driver.findElement(By.name('q')).sendKeys('webdriver'); + * driver.findElement(By.name('btnG')).click(); + * driver.wait(until.titleIs('webdriver - Google Search'), 1000); + * }); + * }); + * + * You may conditionally suppress a test function using the exported + * "ignore" function. If the provided predicate returns true, the attached + * test case will be skipped: + * + * test.ignore(maybe()).it('is flaky', function() { + * if (Math.random() < 0.5) throw Error(); + * }); + * + * function maybe() { return Math.random() < 0.5; } + */ + +var promise = require('..').promise; +var flow = promise.controlFlow(); + + +/** + * Wraps a function so that all passed arguments are ignored. + * @param {!Function} fn The function to wrap. + * @return {!Function} The wrapped function. + */ +function seal(fn) { + return function() { + fn(); + }; +} + + +/** + * Wraps a function on Mocha's BDD interface so it runs inside a + * webdriver.promise.ControlFlow and waits for the flow to complete before + * continuing. + * @param {!Function} globalFn The function to wrap. + * @return {!Function} The new function. + */ +function wrapped(globalFn) { + return function() { + if (arguments.length === 1) { + return globalFn(makeAsyncTestFn(arguments[0])); + } + else if (arguments.length === 2) { + return globalFn(arguments[0], makeAsyncTestFn(arguments[1])); + } + else { + throw Error('Invalid # arguments: ' + arguments.length); + } + }; +} + +/** + * Make a wrapper to invoke caller's test function, fn. Run the test function + * within a ControlFlow. + * + * Should preserve the semantics of Mocha's Runnable.prototype.run (See + * https://github.com/mochajs/mocha/blob/master/lib/runnable.js#L192) + * + * @param {Function} fn + * @return {Function} + */ +function makeAsyncTestFn(fn) { + var async = fn.length > 0; // if test function expects a callback, its "async" + + var ret = function(done) { + var runnable = this.runnable(); + var mochaCallback = runnable.callback; + runnable.callback = function() { + flow.reset(); + return mochaCallback.apply(this, arguments); + }; + + var testFn = fn.bind(this); + flow.execute(function controlFlowExecute() { + return new promise.Promise(function(fulfill, reject) { + if (async) { + // If testFn is async (it expects a done callback), resolve the promise of this + // test whenever that callback says to. Any promises returned from testFn are + // ignored. + testFn(function testFnDoneCallback(err) { + if (err) { + reject(err); + } else { + fulfill(); + } + }); + } else { + // Without a callback, testFn can return a promise, or it will + // be assumed to have completed synchronously + fulfill(testFn()); + } + }, flow); + }, runnable.fullTitle()).then(seal(done), done); + }; + + ret.toString = function() { + return fn.toString(); + }; + + return ret; +} + + +/** + * Ignores the test chained to this function if the provided predicate returns + * true. + * @param {function(): boolean} predicateFn A predicate to call to determine + * if the test should be suppressed. This function MUST be synchronous. + * @return {!Object} An object with wrapped versions of {@link #it()} and + * {@link #describe()} that ignore tests as indicated by the predicate. + */ +function ignore(predicateFn) { + var describe = wrap(exports.xdescribe, exports.describe); + describe.only = wrap(exports.xdescribe, exports.describe.only); + + var it = wrap(exports.xit, exports.it); + it.only = wrap(exports.xit, exports.it.only); + + return { + describe: describe, + it: it + }; + + function wrap(onSkip, onRun) { + return function(title, fn) { + if (predicateFn()) { + onSkip(title, fn); + } else { + onRun(title, fn); + } + }; + } +} + + +// PUBLIC API + + +/** + * @return {!promise.ControlFlow} the control flow instance used by this module + * to coordinate test actions. + */ +exports.controlFlow = function(){ + return flow; +}; + + +/** + * Registers a new test suite. + * @param {string} name The suite name. + * @param {function()=} fn The suite function, or {@code undefined} to define + * a pending test suite. + */ +exports.describe = global.describe; + +/** + * Defines a suppressed test suite. + * @param {string} name The suite name. + * @param {function()=} fn The suite function, or {@code undefined} to define + * a pending test suite. + */ +exports.xdescribe = global.xdescribe; +exports.describe.skip = global.describe.skip; + +/** + * Register a function to call after the current suite finishes. + * @param {function()} fn . + */ +exports.after = wrapped(global.after); + +/** + * Register a function to call after each test in a suite. + * @param {function()} fn . + */ +exports.afterEach = wrapped(global.afterEach); + +/** + * Register a function to call before the current suite starts. + * @param {function()} fn . + */ +exports.before = wrapped(global.before); + +/** + * Register a function to call before each test in a suite. + * @param {function()} fn . + */ +exports.beforeEach = wrapped(global.beforeEach); + +/** + * Add a test to the current suite. + * @param {string} name The test name. + * @param {function()=} fn The test function, or {@code undefined} to define + * a pending test case. + */ +exports.it = wrapped(global.it); + +/** + * An alias for {@link #it()} that flags the test as the only one that should + * be run within the current suite. + * @param {string} name The test name. + * @param {function()=} fn The test function, or {@code undefined} to define + * a pending test case. + */ +exports.iit = exports.it.only = wrapped(global.it.only); + +/** + * Adds a test to the current suite while suppressing it so it is not run. + * @param {string} name The test name. + * @param {function()=} fn The test function, or {@code undefined} to define + * a pending test case. + */ +exports.xit = exports.it.skip = wrapped(global.xit); + +exports.ignore = ignore; diff --git a/platforms/android/assets/www/node_modules/sigmund/LICENSE b/platforms/android/assets/www/node_modules/sigmund/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sigmund/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/sigmund/README.md b/platforms/android/assets/www/node_modules/sigmund/README.md new file mode 100644 index 0000000..25a38a5 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sigmund/README.md @@ -0,0 +1,53 @@ +# sigmund + +Quick and dirty signatures for Objects. + +This is like a much faster `deepEquals` comparison, which returns a +string key suitable for caches and the like. + +## Usage + +```javascript +function doSomething (someObj) { + var key = sigmund(someObj, maxDepth) // max depth defaults to 10 + var cached = cache.get(key) + if (cached) return cached + + var result = expensiveCalculation(someObj) + cache.set(key, result) + return result +} +``` + +The resulting key will be as unique and reproducible as calling +`JSON.stringify` or `util.inspect` on the object, but is much faster. +In order to achieve this speed, some differences are glossed over. +For example, the object `{0:'foo'}` will be treated identically to the +array `['foo']`. + +Also, just as there is no way to summon the soul from the scribblings +of a cocaine-addled psychoanalyst, there is no way to revive the object +from the signature string that sigmund gives you. In fact, it's +barely even readable. + +As with `util.inspect` and `JSON.stringify`, larger objects will +produce larger signature strings. + +Because sigmund is a bit less strict than the more thorough +alternatives, the strings will be shorter, and also there is a +slightly higher chance for collisions. For example, these objects +have the same signature: + + var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} + var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} + +Like a good Freudian, sigmund is most effective when you already have +some understanding of what you're looking for. It can help you help +yourself, but you must be willing to do some work as well. + +Cycles are handled, and cyclical objects are silently omitted (though +the key is included in the signature output.) + +The second argument is the maximum depth, which defaults to 10, +because that is the maximum object traversal depth covered by most +insurance carriers. diff --git a/platforms/android/assets/www/node_modules/sigmund/bench.js b/platforms/android/assets/www/node_modules/sigmund/bench.js new file mode 100644 index 0000000..5acfd6d --- /dev/null +++ b/platforms/android/assets/www/node_modules/sigmund/bench.js @@ -0,0 +1,283 @@ +// different ways to id objects +// use a req/res pair, since it's crazy deep and cyclical + +// sparseFE10 and sigmund are usually pretty close, which is to be expected, +// since they are essentially the same algorithm, except that sigmund handles +// regular expression objects properly. + + +var http = require('http') +var util = require('util') +var sigmund = require('./sigmund.js') +var sreq, sres, creq, cres, test + +http.createServer(function (q, s) { + sreq = q + sres = s + sres.end('ok') + this.close(function () { setTimeout(function () { + start() + }, 200) }) +}).listen(1337, function () { + creq = http.get({ port: 1337 }) + creq.on('response', function (s) { cres = s }) +}) + +function start () { + test = [sreq, sres, creq, cres] + // test = sreq + // sreq.sres = sres + // sreq.creq = creq + // sreq.cres = cres + + for (var i in exports.compare) { + console.log(i) + var hash = exports.compare[i]() + console.log(hash) + console.log(hash.length) + console.log('') + } + + require('bench').runMain() +} + +function customWs (obj, md, d) { + d = d || 0 + var to = typeof obj + if (to === 'undefined' || to === 'function' || to === null) return '' + if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '') + + if (Array.isArray(obj)) { + return obj.map(function (i, _, __) { + return customWs(i, md, d + 1) + }).reduce(function (a, b) { return a + b }, '') + } + + var keys = Object.keys(obj) + return keys.map(function (k, _, __) { + return k + ':' + customWs(obj[k], md, d + 1) + }).reduce(function (a, b) { return a + b }, '') +} + +function custom (obj, md, d) { + d = d || 0 + var to = typeof obj + if (to === 'undefined' || to === 'function' || to === null) return '' + if (d > md || !obj || to !== 'object') return '' + obj + + if (Array.isArray(obj)) { + return obj.map(function (i, _, __) { + return custom(i, md, d + 1) + }).reduce(function (a, b) { return a + b }, '') + } + + var keys = Object.keys(obj) + return keys.map(function (k, _, __) { + return k + ':' + custom(obj[k], md, d + 1) + }).reduce(function (a, b) { return a + b }, '') +} + +function sparseFE2 (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + Object.keys(v).forEach(function (k, _, __) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') return + var to = typeof v[k] + if (to === 'function' || to === 'undefined') return + soFar += k + ':' + ch(v[k], depth + 1) + }) + soFar += '}' + } + ch(obj, 0) + return soFar +} + +function sparseFE (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + Object.keys(v).forEach(function (k, _, __) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') return + var to = typeof v[k] + if (to === 'function' || to === 'undefined') return + soFar += k + ch(v[k], depth + 1) + }) + } + ch(obj, 0) + return soFar +} + +function sparse (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + for (var k in v) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') continue + var to = typeof v[k] + if (to === 'function' || to === 'undefined') continue + soFar += k + ch(v[k], depth + 1) + } + } + ch(obj, 0) + return soFar +} + +function noCommas (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + for (var k in v) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') continue + var to = typeof v[k] + if (to === 'function' || to === 'undefined') continue + soFar += k + ':' + ch(v[k], depth + 1) + } + soFar += '}' + } + ch(obj, 0) + return soFar +} + + +function flatten (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + for (var k in v) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') continue + var to = typeof v[k] + if (to === 'function' || to === 'undefined') continue + soFar += k + ':' + ch(v[k], depth + 1) + soFar += ',' + } + soFar += '}' + } + ch(obj, 0) + return soFar +} + +exports.compare = +{ + // 'custom 2': function () { + // return custom(test, 2, 0) + // }, + // 'customWs 2': function () { + // return customWs(test, 2, 0) + // }, + 'JSON.stringify (guarded)': function () { + var seen = [] + return JSON.stringify(test, function (k, v) { + if (typeof v !== 'object' || !v) return v + if (seen.indexOf(v) !== -1) return undefined + seen.push(v) + return v + }) + }, + + 'flatten 10': function () { + return flatten(test, 10) + }, + + // 'flattenFE 10': function () { + // return flattenFE(test, 10) + // }, + + 'noCommas 10': function () { + return noCommas(test, 10) + }, + + 'sparse 10': function () { + return sparse(test, 10) + }, + + 'sparseFE 10': function () { + return sparseFE(test, 10) + }, + + 'sparseFE2 10': function () { + return sparseFE2(test, 10) + }, + + sigmund: function() { + return sigmund(test, 10) + }, + + + // 'util.inspect 1': function () { + // return util.inspect(test, false, 1, false) + // }, + // 'util.inspect undefined': function () { + // util.inspect(test) + // }, + // 'util.inspect 2': function () { + // util.inspect(test, false, 2, false) + // }, + // 'util.inspect 3': function () { + // util.inspect(test, false, 3, false) + // }, + // 'util.inspect 4': function () { + // util.inspect(test, false, 4, false) + // }, + // 'util.inspect Infinity': function () { + // util.inspect(test, false, Infinity, false) + // } +} + +/** results +**/ diff --git a/platforms/android/assets/www/node_modules/sigmund/package.json b/platforms/android/assets/www/node_modules/sigmund/package.json new file mode 100644 index 0000000..f4862fc --- /dev/null +++ b/platforms/android/assets/www/node_modules/sigmund/package.json @@ -0,0 +1,85 @@ +{ + "_args": [ + [ + "sigmund@~1.0.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine/node_modules/minimatch" + ] + ], + "_from": "sigmund@>=1.0.0 <1.1.0", + "_id": "sigmund@1.0.1", + "_inCache": true, + "_installable": true, + "_location": "/sigmund", + "_nodeVersion": "2.0.1", + "_npmUser": { + "email": "isaacs@npmjs.com", + "name": "isaacs" + }, + "_npmVersion": "2.10.0", + "_phantomChildren": {}, + "_requested": { + "name": "sigmund", + "raw": "sigmund@~1.0.0", + "rawSpec": "~1.0.0", + "scope": null, + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine/minimatch" + ], + "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "_shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590", + "_shrinkwrap": null, + "_spec": "sigmund@~1.0.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine/node_modules/minimatch", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/sigmund/issues" + }, + "dependencies": {}, + "description": "Quick and dirty signatures for Objects.", + "devDependencies": { + "tap": "~0.3.0" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590", + "tarball": "http://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz" + }, + "gitHead": "527f97aa5bb253d927348698c0cd3bb267d098c6", + "homepage": "https://github.com/isaacs/sigmund#readme", + "keywords": [ + "object", + "signature", + "key", + "data", + "psychoanalysis" + ], + "license": "ISC", + "main": "sigmund.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "sigmund", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/sigmund.git" + }, + "scripts": { + "bench": "node bench.js", + "test": "tap test/*.js" + }, + "version": "1.0.1" +} diff --git a/platforms/android/assets/www/node_modules/sigmund/sigmund.js b/platforms/android/assets/www/node_modules/sigmund/sigmund.js new file mode 100644 index 0000000..82c7ab8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sigmund/sigmund.js @@ -0,0 +1,39 @@ +module.exports = sigmund +function sigmund (subject, maxSessions) { + maxSessions = maxSessions || 10; + var notes = []; + var analysis = ''; + var RE = RegExp; + + function psychoAnalyze (subject, session) { + if (session > maxSessions) return; + + if (typeof subject === 'function' || + typeof subject === 'undefined') { + return; + } + + if (typeof subject !== 'object' || !subject || + (subject instanceof RE)) { + analysis += subject; + return; + } + + if (notes.indexOf(subject) !== -1 || session === maxSessions) return; + + notes.push(subject); + analysis += '{'; + Object.keys(subject).forEach(function (issue, _, __) { + // pseudo-private values. skip those. + if (issue.charAt(0) === '_') return; + var to = typeof subject[issue]; + if (to === 'function' || to === 'undefined') return; + analysis += issue; + psychoAnalyze(subject[issue], session + 1); + }); + } + psychoAnalyze(subject, 0); + return analysis; +} + +// vim: set softtabstop=4 shiftwidth=4: diff --git a/platforms/android/assets/www/node_modules/sigmund/test/basic.js b/platforms/android/assets/www/node_modules/sigmund/test/basic.js new file mode 100644 index 0000000..50c53a1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/sigmund/test/basic.js @@ -0,0 +1,24 @@ +var test = require('tap').test +var sigmund = require('../sigmund.js') + + +// occasionally there are duplicates +// that's an acceptable edge-case. JSON.stringify and util.inspect +// have some collision potential as well, though less, and collision +// detection is expensive. +var hash = '{abc/def/g{0h1i2{jkl' +var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} +var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} + +var obj3 = JSON.parse(JSON.stringify(obj1)) +obj3.c = /def/ +obj3.g[2].cycle = obj3 +var cycleHash = '{abc/def/g{0h1i2{jklcycle' + +test('basic', function (t) { + t.equal(sigmund(obj1), hash) + t.equal(sigmund(obj2), hash) + t.equal(sigmund(obj3), cycleHash) + t.end() +}) + diff --git a/platforms/android/assets/www/node_modules/tmp/.npmignore b/platforms/android/assets/www/node_modules/tmp/.npmignore new file mode 100644 index 0000000..78f2710 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/.npmignore @@ -0,0 +1,2 @@ +node_modules/ +.idea/ diff --git a/platforms/android/assets/www/node_modules/tmp/.travis.yml b/platforms/android/assets/www/node_modules/tmp/.travis.yml new file mode 100644 index 0000000..0175d82 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "0.6" + - "0.8" + - "0.10" diff --git a/platforms/android/assets/www/node_modules/tmp/README.md b/platforms/android/assets/www/node_modules/tmp/README.md new file mode 100644 index 0000000..3a1a509 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/README.md @@ -0,0 +1,162 @@ +# Tmp + +A simple temporary file and directory creator for [node.js.][1] + +[![Build Status](https://secure.travis-ci.org/raszi/node-tmp.png?branch=master)](http://travis-ci.org/raszi/node-tmp) + +## About + +The main difference between bruce's [node-temp][2] is that mine more +aggressively checks for the existence of the newly created temporary file and +creates the new file with `O_EXCL` instead of simple `O_CREAT | O_RDRW`, so it +is safer. + +The API is slightly different as well, Tmp does not yet provide synchronous +calls and all the parameters are optional. + +You can set whether you want to remove the temporary file on process exit or +not, and the destination directory can also be set. + +## How to install + +```bash +npm install tmp +``` + +## Usage + +### File creation + +Simple temporary file creation, the file will be unlinked on process exit. + +```javascript +var tmp = require('tmp'); + +tmp.file(function _tempFileCreated(err, path, fd) { + if (err) throw err; + + console.log("File: ", path); + console.log("Filedescriptor: ", fd); +}); +``` + +### Directory creation + +Simple temporary directory creation, it will be removed on process exit. + +If the directory still contains items on process exit, then it won't be removed. + +```javascript +var tmp = require('tmp'); + +tmp.dir(function _tempDirCreated(err, path) { + if (err) throw err; + + console.log("Dir: ", path); +}); +``` + +If you want to cleanup the directory even when there are entries in it, then +you can pass the `unsafeCleanup` option when creating it. + +### Filename generation + +It is possible with this library to generate a unique filename in the specified +directory. + +```javascript +var tmp = require('tmp'); + +tmp.tmpName(function _tempNameGenerated(err, path) { + if (err) throw err; + + console.log("Created temporary filename: ", path); +}); +``` + +## Advanced usage + +### File creation + +Creates a file with mode `0644`, prefix will be `prefix-` and postfix will be `.txt`. + +```javascript +var tmp = require('tmp'); + +tmp.file({ mode: 0644, prefix: 'prefix-', postfix: '.txt' }, function _tempFileCreated(err, path, fd) { + if (err) throw err; + + console.log("File: ", path); + console.log("Filedescriptor: ", fd); +}); +``` + +### Directory creation + +Creates a directory with mode `0755`, prefix will be `myTmpDir_`. + +```javascript +var tmp = require('tmp'); + +tmp.dir({ mode: 0750, prefix: 'myTmpDir_' }, function _tempDirCreated(err, path) { + if (err) throw err; + + console.log("Dir: ", path); +}); +``` + +### mkstemps like + +Creates a new temporary directory with mode `0700` and filename like `/tmp/tmp-nk2J1u`. + +```javascript +var tmp = require('tmp'); + +tmp.dir({ template: '/tmp/tmp-XXXXXX' }, function _tempDirCreated(err, path) { + if (err) throw err; + + console.log("Dir: ", path); +}); +``` + +### Filename generation + +The `tmpName()` function accepts the `prefix`, `postfix`, `dir`, etc. parameters also: + +```javascript +var tmp = require('tmp'); + +tmp.tmpName({ template: '/tmp/tmp-XXXXXX' }, function _tempNameGenerated(err, path) { + if (err) throw err; + + console.log("Created temporary filename: ", path); +}); +``` + +## Graceful cleanup + +One may want to cleanup the temporary files even when an uncaught exception +occurs. To enforce this, you can call the `setGracefulCleanup()` method: + +```javascript +var tmp = require('tmp'); + +tmp.setGracefulCleanup(); +``` + +## Options + +All options are optional :) + + * `mode`: the file mode to create with, it fallbacks to `0600` on file creation and `0700` on directory creation + * `prefix`: the optional prefix, fallbacks to `tmp-` if not provided + * `postfix`: the optional postfix, fallbacks to `.tmp` on file creation + * `template`: [`mkstemps`][3] like filename template, no default + * `dir`: the optional temporary directory, fallbacks to system default (guesses from environment) + * `tries`: how many times should the function try to get a unique filename before giving up, default `3` + * `keep`: signals that the temporary file or directory should not be deleted on exit, default is `false`, means delete + * `unsafeCleanup`: recursively removes the created temporary directory, even when it's not empty. default is `false` + +[1]: http://nodejs.org/ +[2]: https://github.com/bruce/node-temp +[3]: http://www.kernel.org/doc/man-pages/online/pages/man3/mkstemp.3.html diff --git a/platforms/android/assets/www/node_modules/tmp/domain-test.js b/platforms/android/assets/www/node_modules/tmp/domain-test.js new file mode 100644 index 0000000..47221bc --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/domain-test.js @@ -0,0 +1,13 @@ +var domain = require('domain'); + +//throw new Error('bazz'); + +var d = domain.create(); +d.on('error', function ( e ) { + console.log('error!!!', e); +}); + +d.run(function () { + console.log('hey'); + throw new Error('bazz'); +}); diff --git a/platforms/android/assets/www/node_modules/tmp/lib/tmp.js b/platforms/android/assets/www/node_modules/tmp/lib/tmp.js new file mode 100644 index 0000000..ea84faa --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/lib/tmp.js @@ -0,0 +1,307 @@ +/*! + * Tmp + * + * Copyright (c) 2011-2013 KARASZI Istvan + * + * MIT Licensed + */ + +/** + * Module dependencies. + */ +var + fs = require('fs'), + path = require('path'), + os = require('os'), + exists = fs.exists || path.exists, + tmpDir = os.tmpDir || _getTMPDir, + _c = require('constants'); + +/** + * The working inner variables. + */ +var + // store the actual TMP directory + _TMP = tmpDir(), + + // the random characters to choose from + randomChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz", + randomCharsLength = randomChars.length, + + // this will hold the objects need to be removed on exit + _removeObjects = [], + + _gracefulCleanup = false, + _uncaughtException = false; + +/** + * Gets the temp directory. + * + * @return {String} + * @api private + */ +function _getTMPDir() { + var tmpNames = [ 'TMPDIR', 'TMP', 'TEMP' ]; + + for (var i = 0, length = tmpNames.length; i < length; i++) { + if (_isUndefined(process.env[tmpNames[i]])) continue; + + return process.env[tmpNames[i]]; + } + + // fallback to the default + return '/tmp'; +} + +/** + * Checks whether the `obj` parameter is defined or not. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ +function _isUndefined(obj) { + return typeof obj === 'undefined'; +} + +/** + * Parses the function arguments. + * + * This function helps to have optional arguments. + * + * @param {Object} options + * @param {Function} callback + * @api private + */ +function _parseArguments(options, callback) { + if (!callback || typeof callback != "function") { + callback = options; + options = {}; + } + + return [ options, callback ]; +} + +/** + * Gets a temporary file name. + * + * @param {Object} opts + * @param {Function} cb + * @api private + */ +function _getTmpName(options, callback) { + var + args = _parseArguments(options, callback), + opts = args[0], + cb = args[1], + template = opts.template, + templateDefined = !_isUndefined(template), + tries = opts.tries || 3; + + if (isNaN(tries) || tries < 0) + return cb(new Error('Invalid tries')); + + if (templateDefined && !template.match(/XXXXXX/)) + return cb(new Error('Invalid template provided')); + + function _getName() { + + // prefix and postfix + if (!templateDefined) { + var name = [ + (_isUndefined(opts.prefix)) ? 'tmp-' : opts.prefix, + process.pid, + (Math.random() * 0x1000000000).toString(36), + opts.postfix + ].join(''); + + return path.join(opts.dir || _TMP, name); + } + + // mkstemps like template + var chars = []; + + for (var i = 0; i < 6; i++) { + chars.push(randomChars.substr(Math.floor(Math.random() * randomCharsLength), 1)); + } + + return template.replace(/XXXXXX/, chars.join('')); + } + + (function _getUniqueName() { + var name = _getName(); + + // check whether the path exists then retry if needed + exists(name, function _pathExists(pathExists) { + if (pathExists) { + if (tries-- > 0) return _getUniqueName(); + + return cb(new Error('Could not get a unique tmp filename, max tries reached')); + } + + cb(null, name); + }); + }()); +} + +/** + * Creates and opens a temporary file. + * + * @param {Object} options + * @param {Function} callback + * @api public + */ +function _createTmpFile(options, callback) { + var + args = _parseArguments(options, callback), + opts = args[0], + cb = args[1]; + + opts.postfix = (_isUndefined(opts.postfix)) ? '.tmp' : opts.postfix; + + // gets a temporary filename + _getTmpName(opts, function _tmpNameCreated(err, name) { + if (err) return cb(err); + + // create and open the file + fs.open(name, _c.O_CREAT | _c.O_EXCL | _c.O_RDWR, opts.mode || 0600, function _fileCreated(err, fd) { + if (err) return cb(err); + + var removeCallback = _prepareRemoveCallback(fs.unlinkSync.bind(fs), name); + + if (!opts.keep) { + _removeObjects.unshift(removeCallback); + } + + cb(null, name, fd, removeCallback); + }); + }); +} + +/** + * Removes files and folders in a directory recursively. + * + * @param {String} dir + */ +function _rmdirRecursiveSync(dir) { + var files = fs.readdirSync(dir); + + for (var i = 0, length = files.length; i < length; i++) { + var file = path.join(dir, files[i]); + // lstat so we don't recurse into symlinked directories. + var stat = fs.lstatSync(file); + + if (stat.isDirectory()) { + _rmdirRecursiveSync(file); + } else { + fs.unlinkSync(file); + } + } + + fs.rmdirSync(dir); +} + +/** + * + * @param {Function} removeFunction + * @param {String} path + * @returns {Function} + * @private + */ +function _prepareRemoveCallback(removeFunction, path) { + var called = false; + return function() { + if (called) { + return; + } + + removeFunction(path); + + called = true; + }; +} + +/** + * Creates a temporary directory. + * + * @param {Object} options + * @param {Function} callback + * @api public + */ +function _createTmpDir(options, callback) { + var + args = _parseArguments(options, callback), + opts = args[0], + cb = args[1]; + + // gets a temporary filename + _getTmpName(opts, function _tmpNameCreated(err, name) { + if (err) return cb(err); + + // create the directory + fs.mkdir(name, opts.mode || 0700, function _dirCreated(err) { + if (err) return cb(err); + + var removeCallback = _prepareRemoveCallback( + opts.unsafeCleanup + ? _rmdirRecursiveSync + : fs.rmdirSync.bind(fs), + name + ); + + if (!opts.keep) { + _removeObjects.unshift(removeCallback); + } + + cb(null, name, removeCallback); + }); + }); +} + +/** + * The garbage collector. + * + * @api private + */ +function _garbageCollector() { + if (_uncaughtException && !_gracefulCleanup) { + return; + } + + for (var i = 0, length = _removeObjects.length; i < length; i++) { + try { + _removeObjects[i].call(null); + } catch (e) { + // already removed? + } + } +} + +function _setGracefulCleanup() { + _gracefulCleanup = true; +} + +var version = process.versions.node.split('.').map(function (value) { + return parseInt(value, 10); +}); + +if (version[0] === 0 && (version[1] < 9 || version[1] === 9 && version[2] < 5)) { + process.addListener('uncaughtException', function _uncaughtExceptionThrown( err ) { + _uncaughtException = true; + _garbageCollector(); + + throw err; + }); +} + +process.addListener('exit', function _exit(code) { + if (code) _uncaughtException = true; + _garbageCollector(); +}); + +// exporting all the needed methods +module.exports.tmpdir = _TMP; +module.exports.dir = _createTmpDir; +module.exports.file = _createTmpFile; +module.exports.tmpName = _getTmpName; +module.exports.setGracefulCleanup = _setGracefulCleanup; diff --git a/platforms/android/assets/www/node_modules/tmp/package.json b/platforms/android/assets/www/node_modules/tmp/package.json new file mode 100644 index 0000000..ede4cfa --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/package.json @@ -0,0 +1,91 @@ +{ + "_args": [ + [ + "tmp@0.0.24", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver" + ] + ], + "_from": "tmp@0.0.24", + "_id": "tmp@0.0.24", + "_inCache": true, + "_installable": true, + "_location": "/tmp", + "_npmUser": { + "email": "npm@spam.raszi.hu", + "name": "raszi" + }, + "_npmVersion": "1.4.16", + "_phantomChildren": {}, + "_requested": { + "name": "tmp", + "raw": "tmp@0.0.24", + "rawSpec": "0.0.24", + "scope": null, + "spec": "0.0.24", + "type": "version" + }, + "_requiredBy": [ + "/selenium-webdriver" + ], + "_resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz", + "_shasum": "d6a5e198d14a9835cc6f2d7c3d9e302428c8cf12", + "_shrinkwrap": null, + "_spec": "tmp@0.0.24", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver", + "author": { + "email": "github@spam.raszi.hu", + "name": "KARASZI István", + "url": "http://raszi.hu/" + }, + "bugs": { + "url": "http://github.com/raszi/node-tmp/issues" + }, + "dependencies": {}, + "description": "Temporary file and directory creator", + "devDependencies": { + "vows": "~0.7.0" + }, + "directories": {}, + "dist": { + "shasum": "d6a5e198d14a9835cc6f2d7c3d9e302428c8cf12", + "tarball": "http://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz" + }, + "engines": { + "node": ">=0.4.0" + }, + "gitHead": "6864655f13a11c6043c119a0cb60385f072bcecf", + "homepage": "http://github.com/raszi/node-tmp", + "keywords": [ + "temporary", + "tmp", + "temp", + "tempdir", + "tempfile", + "tmpdir", + "tmpfile" + ], + "licenses": [ + { + "type": "MIT", + "url": "http://opensource.org/licenses/MIT" + } + ], + "main": "lib/tmp.js", + "maintainers": [ + { + "email": "npm@spam.raszi.hu", + "name": "raszi" + } + ], + "name": "tmp", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/raszi/node-tmp.git" + }, + "scripts": { + "test": "vows test/*-test.js" + }, + "version": "0.0.24" +} diff --git a/platforms/android/assets/www/node_modules/tmp/test-all.sh b/platforms/android/assets/www/node_modules/tmp/test-all.sh new file mode 100755 index 0000000..4734d60 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/test-all.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +#node06 +for node in node08 node; do + command -v ${node} > /dev/null 2>&1 || continue + + echo "Testing with $(${node} --version)..." + ${node} node_modules/vows/bin/vows test/*test.js +done diff --git a/platforms/android/assets/www/node_modules/tmp/test.js b/platforms/android/assets/www/node_modules/tmp/test.js new file mode 100644 index 0000000..8058221 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/test.js @@ -0,0 +1,6 @@ +process.on('uncaughtException', function ( err ) { + console.log('blah'); + throw err; +}); + +throw "on purpose" diff --git a/platforms/android/assets/www/node_modules/tmp/test/base.js b/platforms/android/assets/www/node_modules/tmp/test/base.js new file mode 100644 index 0000000..498d8fb --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/test/base.js @@ -0,0 +1,74 @@ +var + assert = require('assert'), + path = require('path'), + exec = require('child_process').exec; + +function _spawnTestWithError(testFile, params, cb) { + _spawnTest(true, testFile, params, cb); +} + +function _spawnTestWithoutError(testFile, params, cb) { + _spawnTest(false, testFile, params, cb); +} + +function _spawnTest(passError, testFile, params, cb) { + var + filename, + node_path = process.argv[0], + command = [ node_path, path.join(__dirname, testFile) ].concat(params).join(' '); + + exec(command, function _execDone(err, stdout, stderr) { + if (passError) { + if (err) { + return cb(err); + } else if (stderr.length > 0) { + return cb(stderr.toString()); + } + } + + return cb(null, stdout.toString()); + }); +} + +function _testStat(stat, mode) { + assert.equal(stat.uid, process.getuid(), 'should have the same UID'); + assert.equal(stat.gid, process.getgid(), 'should have the same GUID'); + assert.equal(stat.mode, mode); +} + +function _testPrefix(prefix) { + return function _testPrefixGenerated(err, name, fd) { + assert.equal(path.basename(name).slice(0, prefix.length), prefix, 'should have the provided prefix'); + }; +} + +function _testPostfix(postfix) { + return function _testPostfixGenerated(err, name, fd) { + assert.equal(name.slice(name.length - postfix.length, name.length), postfix, 'should have the provided postfix'); + }; +} + +function _testKeep(type, keep, cb) { + _spawnTestWithError('keep.js', [ type, keep ], cb); +} + +function _testGraceful(type, graceful, cb) { + _spawnTestWithoutError('graceful.js', [ type, graceful ], cb); +} + +function _assertName(err, name) { + assert.isString(name); + assert.isNotZero(name.length); +} + +function _testUnsafeCleanup(unsafe, cb) { + _spawnTestWithoutError('unsafe.js', [ 'dir', unsafe ], cb); +} + +module.exports.testStat = _testStat; +module.exports.testPrefix = _testPrefix; +module.exports.testPostfix = _testPostfix; +module.exports.testKeep = _testKeep; +module.exports.testGraceful = _testGraceful; +module.exports.assertName = _assertName; +module.exports.testUnsafeCleanup = _testUnsafeCleanup; diff --git a/platforms/android/assets/www/node_modules/tmp/test/dir-test.js b/platforms/android/assets/www/node_modules/tmp/test/dir-test.js new file mode 100644 index 0000000..2e4e529 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/test/dir-test.js @@ -0,0 +1,196 @@ +var + vows = require('vows'), + assert = require('assert'), + + path = require('path'), + fs = require('fs'), + existsSync = fs.existsSync || path.existsSync, + + tmp = require('../lib/tmp.js'), + Test = require('./base.js'); + + +function _testDir(mode) { + return function _testDirGenerated(err, name) { + assert.ok(existsSync(name), 'should exist'); + + var stat = fs.statSync(name); + assert.ok(stat.isDirectory(), 'should be a directory'); + + Test.testStat(stat, mode); + }; +} + +vows.describe('Directory creation').addBatch({ + 'when using without parameters': { + topic: function () { + tmp.dir(this.callback); + }, + + 'should be a directory': _testDir(040700), + 'should have the default prefix': Test.testPrefix('tmp-') + }, + + 'when using with prefix': { + topic: function () { + tmp.dir({ prefix: 'something' }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a directory': _testDir(040700), + 'should have the provided prefix': Test.testPrefix('something') + }, + + 'when using with postfix': { + topic: function () { + tmp.dir({ postfix: '.txt' }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a directory': _testDir(040700), + 'should have the provided postfix': Test.testPostfix('.txt') + }, + + 'when using template': { + topic: function () { + tmp.dir({ template: path.join(tmp.tmpdir, 'clike-XXXXXX-postfix') }, this.callback); + }, + + 'should not return with error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testDir(040700), + 'should have the provided prefix': Test.testPrefix('clike-'), + 'should have the provided postfix': Test.testPostfix('-postfix') + }, + + 'when using multiple options': { + topic: function () { + tmp.dir({ prefix: 'foo', postfix: 'bar', mode: 0750 }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a directory': _testDir(040750), + 'should have the provided prefix': Test.testPrefix('foo'), + 'should have the provided postfix': Test.testPostfix('bar') + }, + + 'when using multiple options and mode': { + topic: function () { + tmp.dir({ prefix: 'complicated', postfix: 'options', mode: 0755 }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a directory': _testDir(040755), + 'should have the provided prefix': Test.testPrefix('complicated'), + 'should have the provided postfix': Test.testPostfix('options') + }, + + 'no tries': { + topic: function () { + tmp.dir({ tries: -1 }, this.callback); + }, + + 'should return with an error': assert.isObject + }, + + 'keep testing': { + topic: function () { + Test.testKeep('dir', '1', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a dir': function (err, name) { + _testDir(040700)(err, name); + fs.rmdirSync(name); + } + }, + + 'unlink testing': { + topic: function () { + Test.testKeep('dir', '0', this.callback); + }, + + 'should not return with error': assert.isNull, + 'should return with a name': Test.assertName, + 'should not exist': function (err, name) { + assert.ok(!existsSync(name), "Directory should be removed"); + } + }, + + 'non graceful testing': { + topic: function () { + Test.testGraceful('dir', '0', this.callback); + }, + + 'should not return with error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a dir': function (err, name) { + _testDir(040700)(err, name); + fs.rmdirSync(name); + } + }, + + 'graceful testing': { + topic: function () { + Test.testGraceful('dir', '1', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should not exist': function (err, name) { + assert.ok(!existsSync(name), "Directory should be removed"); + } + }, + + 'unsafeCleanup === true': { + topic: function () { + Test.testUnsafeCleanup('1', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should not exist': function (err, name) { + assert.ok(!existsSync(name), "Directory should be removed"); + }, + 'should remove symlinked dir': function(err, name) { + assert.ok( + !existsSync(name + '/symlinkme-target'), + 'should remove target' + ); + }, + 'should not remove contents of symlink dir': function(err, name) { + assert.ok( + existsSync(__dirname + '/symlinkme/file.js'), + 'should not remove symlinked directory\'s content' + ); + } + }, + + 'unsafeCleanup === false': { + topic: function () { + Test.testUnsafeCleanup('0', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a directory': _testDir(040700) + }, + + 'remove callback': { + topic: function () { + tmp.dir(this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'removeCallback should remove directory': function (_err, name, removeCallback) { + removeCallback(); + assert.ok(!existsSync(name), "Directory should be removed"); + } + } +}).exportTo(module); diff --git a/platforms/android/assets/www/node_modules/tmp/test/file-test.js b/platforms/android/assets/www/node_modules/tmp/test/file-test.js new file mode 100644 index 0000000..d9605b3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/test/file-test.js @@ -0,0 +1,177 @@ +var + vows = require('vows'), + assert = require('assert'), + + path = require('path'), + fs = require('fs'), + existsSync = fs.existsSync || path.existsSync, + + tmp = require('../lib/tmp.js'), + Test = require('./base.js'); + + +function _testFile(mode, fdTest) { + return function _testFileGenerated(err, name, fd) { + assert.ok(existsSync(name), 'should exist'); + + var stat = fs.statSync(name); + assert.equal(stat.size, 0, 'should have zero size'); + assert.ok(stat.isFile(), 'should be a file'); + + Test.testStat(stat, mode); + + // check with fstat as well (fd checking) + if (fdTest) { + var fstat = fs.fstatSync(fd); + assert.deepEqual(fstat, stat, 'fstat results should be the same'); + + var data = new Buffer('something'); + assert.equal(fs.writeSync(fd, data, 0, data.length, 0), data.length, 'should be writable'); + assert.ok(!fs.closeSync(fd), 'should not return with error'); + } + }; +} + +vows.describe('File creation').addBatch({ + 'when using without parameters': { + topic: function () { + tmp.file(this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100600, true), + 'should have the default prefix': Test.testPrefix('tmp-'), + 'should have the default postfix': Test.testPostfix('.tmp') + }, + + 'when using with prefix': { + topic: function () { + tmp.file({ prefix: 'something' }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100600, true), + 'should have the provided prefix': Test.testPrefix('something') + }, + + 'when using with postfix': { + topic: function () { + tmp.file({ postfix: '.txt' }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100600, true), + 'should have the provided postfix': Test.testPostfix('.txt') + }, + + 'when using template': { + topic: function () { + tmp.file({ template: path.join(tmp.tmpdir, 'clike-XXXXXX-postfix') }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100600, true), + 'should have the provided prefix': Test.testPrefix('clike-'), + 'should have the provided postfix': Test.testPostfix('-postfix') + }, + + 'when using multiple options': { + topic: function () { + tmp.file({ prefix: 'foo', postfix: 'bar', mode: 0640 }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100640, true), + 'should have the provided prefix': Test.testPrefix('foo'), + 'should have the provided postfix': Test.testPostfix('bar') + }, + + 'when using multiple options and mode': { + topic: function () { + tmp.file({ prefix: 'complicated', postfix: 'options', mode: 0644 }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100644, true), + 'should have the provided prefix': Test.testPrefix('complicated'), + 'should have the provided postfix': Test.testPostfix('options') + }, + + 'no tries': { + topic: function () { + tmp.file({ tries: -1 }, this.callback); + }, + + 'should not be created': assert.isObject + }, + + 'keep testing': { + topic: function () { + Test.testKeep('file', '1', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': function (err, name) { + _testFile(0100600, false)(err, name, null); + fs.unlinkSync(name); + } + }, + + 'unlink testing': { + topic: function () { + Test.testKeep('file', '0', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should not exist': function (err, name) { + assert.ok(!existsSync(name), "File should be removed"); + } + }, + + 'non graceful testing': { + topic: function () { + Test.testGraceful('file', '0', this.callback); + }, + + 'should not return with error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': function (err, name) { + _testFile(0100600, false)(err, name, null); + fs.unlinkSync(name); + } + }, + + 'graceful testing': { + topic: function () { + Test.testGraceful('file', '1', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should not exist': function (err, name) { + assert.ok(!existsSync(name), "File should be removed"); + } + }, + + 'remove callback': { + topic: function () { + tmp.file(this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'removeCallback should remove file': function (_err, name, _fd, removeCallback) { + removeCallback(); + assert.ok(!existsSync(name), "File should be removed"); + } + } + +}).exportTo(module); diff --git a/platforms/android/assets/www/node_modules/tmp/test/graceful.js b/platforms/android/assets/www/node_modules/tmp/test/graceful.js new file mode 100644 index 0000000..c898656 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/test/graceful.js @@ -0,0 +1,15 @@ +var + tmp = require('../lib/tmp'), + spawn = require('./spawn'); + +var graceful = spawn.arg; + +if (graceful) { + tmp.setGracefulCleanup(); +} + +spawn.tmpFunction(function (err, name) { + spawn.out(name, function () { + throw new Error("Thrown on purpose"); + }); +}); diff --git a/platforms/android/assets/www/node_modules/tmp/test/keep.js b/platforms/android/assets/www/node_modules/tmp/test/keep.js new file mode 100644 index 0000000..9538605 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/test/keep.js @@ -0,0 +1,11 @@ +var spawn = require('./spawn'); + +var keep = spawn.arg; + +spawn.tmpFunction({ keep: keep }, function (err, name) { + if (err) { + spawn.err(err, spawn.exit); + } else { + spawn.out(name, spawn.exit); + } +}); diff --git a/platforms/android/assets/www/node_modules/tmp/test/name-test.js b/platforms/android/assets/www/node_modules/tmp/test/name-test.js new file mode 100644 index 0000000..a242c21 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/test/name-test.js @@ -0,0 +1,82 @@ +var + vows = require('vows'), + assert = require('assert'), + + path = require('path'), + + tmp = require('../lib/tmp.js'), + Test = require('./base.js'); + +vows.describe('Name creation').addBatch({ + 'when using without parameters': { + topic: function () { + tmp.tmpName(this.callback); + }, + + 'should not return with error': assert.isNull, + 'should have the default prefix': Test.testPrefix('tmp-') + }, + + 'when using with prefix': { + topic: function () { + tmp.tmpName({ prefix: 'something' }, this.callback); + }, + + 'should not return with error': assert.isNull, + 'should have the provided prefix': Test.testPrefix('something') + }, + + 'when using with postfix': { + topic: function () { + tmp.tmpName({ postfix: '.txt' }, this.callback); + }, + + 'should not return with error': assert.isNull, + 'should have the provided postfix': Test.testPostfix('.txt') + + }, + + 'when using template': { + topic: function () { + tmp.tmpName({ template: path.join(tmp.tmpdir, 'clike-XXXXXX-postfix') }, this.callback); + }, + + 'should not return with error': assert.isNull, + 'should have the provided prefix': Test.testPrefix('clike-'), + 'should have the provided postfix': Test.testPostfix('-postfix'), + 'should have template filled': function (err, name) { + assert.isTrue(/[a-zA-Z0-9]{6}/.test(name)); + } + }, + + 'when using multiple options': { + topic: function () { + tmp.tmpName({ prefix: 'foo', postfix: 'bar', tries: 5 }, this.callback); + }, + + 'should not return with error': assert.isNull, + 'should have the provided prefix': Test.testPrefix('foo'), + 'should have the provided postfix': Test.testPostfix('bar') + }, + + 'no tries': { + topic: function () { + tmp.tmpName({ tries: -1 }, this.callback); + }, + + 'should fail': function (err, name) { + assert.isObject(err); + } + }, + + 'tries not numeric': { + topic: function () { + tmp.tmpName({ tries: 'hello'}, this.callback); + }, + + 'should fail': function (err, name) { + assert.isObject(err); + } + } + +}).exportTo(module); diff --git a/platforms/android/assets/www/node_modules/tmp/test/spawn.js b/platforms/android/assets/www/node_modules/tmp/test/spawn.js new file mode 100644 index 0000000..6468eb3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/test/spawn.js @@ -0,0 +1,32 @@ +var + fs = require('fs'), + tmp = require('../lib/tmp'); + +function _writeSync(stream, str, cb) { + var flushed = stream.write(str); + if (flushed) { + return cb(null); + } + + stream.once('drain', function _flushed() { + cb(null); + }); +} + +module.exports.out = function (str, cb) { + _writeSync(process.stdout, str, cb); +}; + +module.exports.err = function (str, cb) { + _writeSync(process.stderr, str, cb); +}; + +module.exports.exit = function () { + process.exit(0); +}; + +var type = process.argv[2]; +module.exports.tmpFunction = (type == 'file') ? tmp.file : tmp.dir; + +var arg = (process.argv[3] && parseInt(process.argv[3], 10) === 1) ? true : false; +module.exports.arg = arg; diff --git a/platforms/android/assets/www/node_modules/tmp/test/symlinkme/file.js b/platforms/android/assets/www/node_modules/tmp/test/symlinkme/file.js new file mode 100644 index 0000000..e69de29 diff --git a/platforms/android/assets/www/node_modules/tmp/test/unsafe.js b/platforms/android/assets/www/node_modules/tmp/test/unsafe.js new file mode 100644 index 0000000..73e4fb3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/tmp/test/unsafe.js @@ -0,0 +1,30 @@ +var + fs = require('fs'), + join = require('path').join, + spawn = require('./spawn'); + +var unsafe = spawn.arg; +spawn.tmpFunction({ unsafeCleanup: unsafe }, function (err, name) { + if (err) { + spawn.err(err, spawn.exit); + return; + } + + try { + // file that should be removed + var fd = fs.openSync(join(name, 'should-be-removed.file'), 'w'); + fs.closeSync(fd); + + // in tree source + var symlinkSource = join(__dirname, 'symlinkme'); + // testing target + var symlinkTarget = join(name, 'symlinkme-target'); + + // symlink that should be removed but the contents should be preserved. + fs.symlinkSync(symlinkSource, symlinkTarget, 'dir'); + + spawn.out(name, spawn.exit); + } catch (e) { + spawn.err(e.toString(), spawn.exit); + } +}); diff --git a/platforms/android/assets/www/node_modules/ultron/.npmignore b/platforms/android/assets/www/node_modules/ultron/.npmignore new file mode 100644 index 0000000..66210a2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ultron/.npmignore @@ -0,0 +1,3 @@ +node_modules +coverage +.tern-port diff --git a/platforms/android/assets/www/node_modules/ultron/.travis.yml b/platforms/android/assets/www/node_modules/ultron/.travis.yml new file mode 100644 index 0000000..a505004 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ultron/.travis.yml @@ -0,0 +1,21 @@ +sudo: false +language: node_js +node_js: + - "0.12" + - "0.10" + - "0.8" + - "iojs" +before_install: + - 'if [ "${TRAVIS_NODE_VERSION}" == "0.8" ]; then npm install -g npm@2.11.1; fi' +script: + - "npm run test-travis" +after_script: + - "npm install coveralls@2.11.x && cat coverage/lcov.info | coveralls" +matrix: + fast_finish: true +notifications: + irc: + channels: + - "irc.freenode.org#unshift" + on_success: change + on_failure: change diff --git a/platforms/android/assets/www/node_modules/ultron/LICENSE b/platforms/android/assets/www/node_modules/ultron/LICENSE new file mode 100644 index 0000000..6dc9316 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ultron/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Unshift.io, Arnout Kazemier, the Contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/platforms/android/assets/www/node_modules/ultron/README.md b/platforms/android/assets/www/node_modules/ultron/README.md new file mode 100644 index 0000000..84fa3f2 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ultron/README.md @@ -0,0 +1,97 @@ +# Ultron + +[![Made by unshift](https://img.shields.io/badge/made%20by-unshift-00ffcc.svg?style=flat-square)](http://unshift.io)[![Version npm](http://img.shields.io/npm/v/ultron.svg?style=flat-square)](http://browsenpm.org/package/ultron)[![Build Status](http://img.shields.io/travis/unshiftio/ultron/master.svg?style=flat-square)](https://travis-ci.org/unshiftio/ultron)[![Dependencies](https://img.shields.io/david/unshiftio/ultron.svg?style=flat-square)](https://david-dm.org/unshiftio/ultron)[![Coverage Status](http://img.shields.io/coveralls/unshiftio/ultron/master.svg?style=flat-square)](https://coveralls.io/r/unshiftio/ultron?branch=master)[![IRC channel](http://img.shields.io/badge/IRC-irc.freenode.net%23unshift-00a8ff.svg?style=flat-square)](http://webchat.freenode.net/?channels=unshift) + +Ultron is a high-intelligence robot. It gathers intelligence so it can start +improving upon his rudimentary design. It will learn your event emitting +patterns and find ways to exterminate them. Allowing you to remove only the +event emitters that **you** assigned and not the ones that your users or +developers assigned. This can prevent race conditions, memory leaks and even file +descriptor leaks from ever happening as you won't remove clean up processes. + +## Installation + +The module is designed to be used in browsers using browserify and in Node.js. +You can install the module through the public npm registry by running the +following command in CLI: + +``` +npm install --save ultron +``` + +## Usage + +In all examples we assume that you've required the library as following: + +```js +'use strict'; + +var Ultron = require('ultron'); +``` + +Now that we've required the library we can construct our first `Ultron` instance. +The constructor requires one argument which should be the `EventEmitter` +instance that we need to operate upon. This can be the `EventEmitter` module +that ships with Node.js or `EventEmitter3` or anything else as long as it +follow the same API and internal structure as these 2. So with that in mind we +can create the instance: + +```js +// +// For the sake of this example we're going to construct an empty EventEmitter +// +var EventEmitter = require('events').EventEmitter; // or require('eventmitter3'); +var events = new EventEmitter(); + +var ultron = new Ultron(events); +``` + +You can now use the following API's from the Ultron instance: + +### Ultron.on + +Register a new event listener for the given event. It follows the exact same API +as `EventEmitter.on` but it will return itself instead of returning the +EventEmitter instance. If you are using EventEmitter3 it also supports the +context param: + +```js +ultron.on('event-name', handler, { custom: 'function context' }); +``` + +### Ultron.once + +Exactly the same as the [Ultron.on](#ultronon) but it only allows the execution +once. + +### Ultron.remove + +This is where all the magic happens and the safe removal starts. This function +accepts different argument styles: + +- No arguments, assume that all events need to be removed so it will work as + `removeAllListeners()` API. +- 1 argument, when it's a string it will be split on ` ` and `,` to create a + list of events that need to be cleared. +- Multiple arguments, we assume that they are all names of events that need to + be cleared. + +```js +ultron.remove('foo, bar baz'); // Removes foo, bar and baz. +ultron.remove('foo', 'bar', 'baz'); // Removes foo, bar and baz. +ultron.remove(); // Removes everything. +``` + +If you just want to remove a single event listener using a function reference +you can still use the EventEmitter's `removeListener(event, fn)` API: + +```js +function foo() {} + +ulton.on('foo', foo); +events.removeListener('foo', foo); +``` + +## License + +MIT diff --git a/platforms/android/assets/www/node_modules/ultron/index.js b/platforms/android/assets/www/node_modules/ultron/index.js new file mode 100644 index 0000000..af17ab7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ultron/index.js @@ -0,0 +1,129 @@ +'use strict'; + +var has = Object.prototype.hasOwnProperty; + +/** + * An auto incrementing id which we can use to create "unique" Ultron instances + * so we can track the event emitters that are added through the Ultron + * interface. + * + * @type {Number} + * @private + */ +var id = 0; + +/** + * Ultron is high-intelligence robot. It gathers intelligence so it can start improving + * upon his rudimentary design. It will learn from your EventEmitting patterns + * and exterminate them. + * + * @constructor + * @param {EventEmitter} ee EventEmitter instance we need to wrap. + * @api public + */ +function Ultron(ee) { + if (!(this instanceof Ultron)) return new Ultron(ee); + + this.id = id++; + this.ee = ee; +} + +/** + * Register a new EventListener for the given event. + * + * @param {String} event Name of the event. + * @param {Functon} fn Callback function. + * @param {Mixed} context The context of the function. + * @returns {Ultron} + * @api public + */ +Ultron.prototype.on = function on(event, fn, context) { + fn.__ultron = this.id; + this.ee.on(event, fn, context); + + return this; +}; +/** + * Add an EventListener that's only called once. + * + * @param {String} event Name of the event. + * @param {Function} fn Callback function. + * @param {Mixed} context The context of the function. + * @returns {Ultron} + * @api public + */ +Ultron.prototype.once = function once(event, fn, context) { + fn.__ultron = this.id; + this.ee.once(event, fn, context); + + return this; +}; + +/** + * Remove the listeners we assigned for the given event. + * + * @returns {Ultron} + * @api public + */ +Ultron.prototype.remove = function remove() { + var args = arguments + , event; + + // + // When no event names are provided we assume that we need to clear all the + // events that were assigned through us. + // + if (args.length === 1 && 'string' === typeof args[0]) { + args = args[0].split(/[, ]+/); + } else if (!args.length) { + args = []; + + for (event in this.ee._events) { + if (has.call(this.ee._events, event)) args.push(event); + } + } + + for (var i = 0; i < args.length; i++) { + var listeners = this.ee.listeners(args[i]); + + for (var j = 0; j < listeners.length; j++) { + event = listeners[j]; + + // + // Once listeners have a `listener` property that stores the real listener + // in the EventEmitter that ships with Node.js. + // + if (event.listener) { + if (event.listener.__ultron !== this.id) continue; + delete event.listener.__ultron; + } else { + if (event.__ultron !== this.id) continue; + delete event.__ultron; + } + + this.ee.removeListener(args[i], event); + } + } + + return this; +}; + +/** + * Destroy the Ultron instance, remove all listeners and release all references. + * + * @returns {Boolean} + * @api public + */ +Ultron.prototype.destroy = function destroy() { + if (!this.ee) return false; + + this.remove(); + this.ee = null; + + return true; +}; + +// +// Expose the module. +// +module.exports = Ultron; diff --git a/platforms/android/assets/www/node_modules/ultron/package.json b/platforms/android/assets/www/node_modules/ultron/package.json new file mode 100644 index 0000000..28ad834 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ultron/package.json @@ -0,0 +1,100 @@ +{ + "_args": [ + [ + "ultron@1.0.x", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/ws" + ] + ], + "_from": "ultron@>=1.0.0 <1.1.0", + "_id": "ultron@1.0.2", + "_inCache": true, + "_installable": true, + "_location": "/ultron", + "_nodeVersion": "0.12.3", + "_npmUser": { + "email": "npm@3rd-Eden.com", + "name": "3rdeden" + }, + "_npmVersion": "2.9.1", + "_phantomChildren": {}, + "_requested": { + "name": "ultron", + "raw": "ultron@1.0.x", + "rawSpec": "1.0.x", + "scope": null, + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/ws" + ], + "_resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "_shasum": "ace116ab557cd197386a4e88f4685378c8b2e4fa", + "_shrinkwrap": null, + "_spec": "ultron@1.0.x", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/ws", + "author": { + "name": "Arnout Kazemier" + }, + "bugs": { + "url": "https://github.com/unshiftio/ultron/issues" + }, + "dependencies": {}, + "description": "Ultron is high-intelligence robot. It gathers intel so it can start improving upon his rudimentary design", + "devDependencies": { + "assume": "1.2.x", + "eventemitter3": "1.1.x", + "istanbul": "0.3.x", + "mocha": "2.2.x", + "pre-commit": "1.0.x" + }, + "directories": {}, + "dist": { + "shasum": "ace116ab557cd197386a4e88f4685378c8b2e4fa", + "tarball": "http://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz" + }, + "gitHead": "a10482ae98a09120821545456c90c6d60d540f7c", + "homepage": "https://github.com/unshiftio/ultron", + "keywords": [ + "Ultron", + "robot", + "gather", + "intelligence", + "event", + "events", + "eventemitter", + "emitter", + "cleanup" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "email": "npm@unshift.io", + "name": "unshift" + }, + { + "email": "info@3rd-Eden.com", + "name": "v1" + }, + { + "email": "npm@3rd-Eden.com", + "name": "3rdeden" + } + ], + "name": "ultron", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/unshiftio/ultron.git" + }, + "scripts": { + "100%": "istanbul check-coverage --statements 100 --functions 100 --lines 100 --branches 100", + "coverage": "istanbul cover ./node_modules/.bin/_mocha -- test.js", + "test": "mocha test.js", + "test-travis": "istanbul cover node_modules/.bin/_mocha --report lcovonly -- test.js", + "watch": "mocha --watch test.js" + }, + "version": "1.0.2" +} diff --git a/platforms/android/assets/www/node_modules/ultron/test.js b/platforms/android/assets/www/node_modules/ultron/test.js new file mode 100644 index 0000000..1fd4f1b --- /dev/null +++ b/platforms/android/assets/www/node_modules/ultron/test.js @@ -0,0 +1,327 @@ +/* istanbul ignore next */ +describe('Ultron', function () { + 'use strict'; + + var EventEmitter = require('eventemitter3') + , EE = require('events').EventEmitter + , assume = require('assume') + , Ultron = require('./') + , ultron + , ee; + + beforeEach(function () { + ee = new EventEmitter(); + ultron = new Ultron(ee); + }); + + afterEach(function () { + ultron.destroy(); + ee.removeAllListeners(); + }); + + it('is exposed as a function', function () { + assume(Ultron).is.a('function'); + }); + + it('can be initialized without the new keyword', function () { + assume(Ultron(ee)).is.instanceOf(Ultron); + }); + + it('assigns a unique id to every instance', function () { + for (var i = 0; i < 100; i++) { + assume(ultron.id).does.not.equal((new Ultron()).id); + } + }); + + it('allows removal through the event emitter', function () { + function foo() {} + function bar() {} + + ultron.on('foo', foo); + ultron.once('foo', bar); + + assume(foo.__ultron).equals(ultron.id); + assume(bar.__ultron).equals(ultron.id); + assume(ee.listeners('foo').length).equals(2); + + ee.removeListener('foo', foo); + assume(ee.listeners('foo').length).equals(1); + + ee.removeListener('foo', bar); + assume(ee.listeners('foo').length).equals(0); + }); + + describe('#on', function () { + it('assigns a listener', function () { + assume(ee.listeners('foo').length).equals(0); + + function foo() {} + + ultron.on('foo', foo); + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('foo')[0]).equals(foo); + }); + + it('tags the assigned function', function () { + assume(ee.listeners('foo').length).equals(0); + + ultron.on('foo', function () {}); + assume(ee.listeners('foo')[0].__ultron).equals(ultron.id); + }); + + it('also passes in the context', function (next) { + var context = 1313; + + ultron.on('foo', function (a, b, c) { + assume(a).equals('a'); + assume(b).equals('b'); + assume(c).equals('c'); + + assume(this).equals(context); + + next(); + }, context); + + ee.emit('foo', 'a', 'b', 'c'); + }); + + it('works with regular eventemitters as well', function (next) { + var ee = new EE() + , ultron = new Ultron(ee); + + ultron.on('foo', function (a, b, c) { + assume(a).equals('a'); + assume(b).equals('b'); + assume(c).equals('c'); + + next(); + }); + + ee.emit('foo', 'a', 'b', 'c'); + }); + }); + + describe('#once', function () { + it('assigns a listener', function () { + assume(ee.listeners('foo').length).equals(0); + + function foo() {} + ultron.once('foo', foo); + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('foo')[0]).equals(foo); + }); + + it('tags the assigned function', function () { + assume(ee.listeners('foo').length).equals(0); + + ultron.once('foo', function () {}); + assume(ee.listeners('foo')[0].__ultron).equals(ultron.id); + }); + + it('also passes in the context', function (next) { + var context = 1313; + + ultron.once('foo', function (a, b, c) { + assume(a).equals('a'); + assume(b).equals('b'); + assume(c).equals('c'); + + assume(this).equals(context); + + next(); + }, context); + + ee.emit('foo', 'a', 'b', 'c'); + ee.emit('foo', 'a', 'b', 'c'); // Ensure that we don't double execute + }); + + it('works with regular eventemitters as well', function (next) { + var ee = new EE() + , ultron = new Ultron(ee); + + ultron.once('foo', function (a, b, c) { + assume(a).equals('a'); + assume(b).equals('b'); + assume(c).equals('c'); + + next(); + }); + + ee.emit('foo', 'a', 'b', 'c'); + ee.emit('foo', 'a', 'b', 'c'); // Ensure that we don't double execute + }); + }); + + describe('#remove', function () { + it('removes only our assigned `on` listeners', function () { + function foo() {} + function bar() {} + + ee.on('foo', foo); + ultron.on('foo', bar); + assume(ee.listeners('foo').length).equals(2); + + ultron.remove('foo'); + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('foo')[0]).equals(foo); + }); + + it('removes our private __ultron references', function () { + function once() {} + function on() {} + + assume('__ultron' in once).is.false(); + assume('__ultron' in on).is.false(); + + ultron.on('foo', on); + ultron.once('bar', once); + + assume('__ultron' in once).is.true(); + assume('__ultron' in on).is.true(); + + ultron.remove('foo, bar'); + + assume('__ultron' in once).is.false(); + assume('__ultron' in on).is.false(); + + ultron.destroy(); + + ee = new EE(); + ultron = new Ultron(ee); + + assume('__ultron' in once).is.false(); + assume('__ultron' in on).is.false(); + + ultron.on('foo', on); + ultron.once('bar', once); + + assume('__ultron' in once).is.true(); + assume('__ultron' in on).is.true(); + + ultron.remove('foo, bar'); + + assume('__ultron' in once).is.false(); + assume('__ultron' in on).is.false(); + }); + + it('removes only our assigned `once` listeners', function () { + function foo() {} + function bar() {} + + ee.once('foo', foo); + ultron.once('foo', bar); + assume(ee.listeners('foo').length).equals(2); + + ultron.remove('foo'); + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('foo')[0]).equals(foo); + }); + + it('removes only our assigned `once` listeners from regular EE', function () { + var ee = new EE() + , ultron = new Ultron(ee); + + function foo() {} + function bar() {} + + ee.once('foo', foo); + ultron.once('foo', bar); + assume(ee.listeners('foo').length).equals(2); + + ultron.remove('foo'); + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('foo')[0].listener).equals(foo); + }); + + it('removes all assigned events if called without args', function () { + function foo() {} + function bar() {} + + ultron.on('foo', foo); + ultron.on('bar', bar); + + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('bar').length).equals(1); + + ultron.remove(); + + assume(ee.listeners('foo').length).equals(0); + assume(ee.listeners('bar').length).equals(0); + }); + + it('removes multiple listeners based on args', function () { + function foo() {} + function bar() {} + function baz() {} + + ultron.on('foo', foo); + ultron.on('bar', bar); + ultron.on('baz', baz); + + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('bar').length).equals(1); + assume(ee.listeners('baz').length).equals(1); + + ultron.remove('foo', 'bar'); + + assume(ee.listeners('foo').length).equals(0); + assume(ee.listeners('bar').length).equals(0); + assume(ee.listeners('baz').length).equals(1); + }); + + it('removes multiple listeners if first arg is seperated string', function () { + function foo() {} + function bar() {} + function baz() {} + + ultron.on('foo', foo); + ultron.on('bar', bar); + ultron.on('baz', baz); + + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('bar').length).equals(1); + assume(ee.listeners('baz').length).equals(1); + + ultron.remove('foo, bar'); + + assume(ee.listeners('foo').length).equals(0); + assume(ee.listeners('bar').length).equals(0); + assume(ee.listeners('baz').length).equals(1); + }); + }); + + describe('#destroy', function () { + it('removes all listeners', function () { + function foo() {} + function bar() {} + function baz() {} + + ultron.on('foo', foo); + ultron.on('bar', bar); + ultron.on('baz', baz); + + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('bar').length).equals(1); + assume(ee.listeners('baz').length).equals(1); + + ultron.destroy(); + + assume(ee.listeners('foo').length).equals(0); + assume(ee.listeners('bar').length).equals(0); + assume(ee.listeners('baz').length).equals(0); + }); + + it('removes the .ee reference', function () { + assume(ultron.ee).equals(ee); + ultron.destroy(); + assume(ultron.ee).equals(null); + }); + + it('returns booleans for state indication', function () { + assume(ultron.destroy()).is.true(); + assume(ultron.destroy()).is.false(); + assume(ultron.destroy()).is.false(); + assume(ultron.destroy()).is.false(); + }); + }); +}); diff --git a/platforms/android/assets/www/node_modules/wrappy/LICENSE b/platforms/android/assets/www/node_modules/wrappy/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/wrappy/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/wrappy/README.md b/platforms/android/assets/www/node_modules/wrappy/README.md new file mode 100644 index 0000000..98eab25 --- /dev/null +++ b/platforms/android/assets/www/node_modules/wrappy/README.md @@ -0,0 +1,36 @@ +# wrappy + +Callback wrapping utility + +## USAGE + +```javascript +var wrappy = require("wrappy") + +// var wrapper = wrappy(wrapperFunction) + +// make sure a cb is called only once +// See also: http://npm.im/once for this specific use case +var once = wrappy(function (cb) { + var called = false + return function () { + if (called) return + called = true + return cb.apply(this, arguments) + } +}) + +function printBoo () { + console.log('boo') +} +// has some rando property +printBoo.iAmBooPrinter = true + +var onlyPrintOnce = once(printBoo) + +onlyPrintOnce() // prints 'boo' +onlyPrintOnce() // does nothing + +// random property is retained! +assert.equal(onlyPrintOnce.iAmBooPrinter, true) +``` diff --git a/platforms/android/assets/www/node_modules/wrappy/package.json b/platforms/android/assets/www/node_modules/wrappy/package.json new file mode 100644 index 0000000..7069c85 --- /dev/null +++ b/platforms/android/assets/www/node_modules/wrappy/package.json @@ -0,0 +1,78 @@ +{ + "_args": [ + [ + "wrappy@1", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/inflight" + ] + ], + "_from": "wrappy@>=1.0.0 <2.0.0", + "_id": "wrappy@1.0.1", + "_inCache": true, + "_installable": true, + "_location": "/wrappy", + "_nodeVersion": "0.10.31", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "2.0.0", + "_phantomChildren": {}, + "_requested": { + "name": "wrappy", + "raw": "wrappy@1", + "rawSpec": "1", + "scope": null, + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/inflight", + "/once" + ], + "_resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", + "_shasum": "1e65969965ccbc2db4548c6b84a6f2c5aedd4739", + "_shrinkwrap": null, + "_spec": "wrappy@1", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/inflight", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/npm/wrappy/issues" + }, + "dependencies": {}, + "description": "Callback wrapping utility", + "devDependencies": { + "tap": "^0.4.12" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "1e65969965ccbc2db4548c6b84a6f2c5aedd4739", + "tarball": "http://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + }, + "gitHead": "006a8cbac6b99988315834c207896eed71fd069a", + "homepage": "https://github.com/npm/wrappy", + "license": "ISC", + "main": "wrappy.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "wrappy", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/wrappy.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "1.0.1" +} diff --git a/platforms/android/assets/www/node_modules/wrappy/test/basic.js b/platforms/android/assets/www/node_modules/wrappy/test/basic.js new file mode 100644 index 0000000..5ed0fcd --- /dev/null +++ b/platforms/android/assets/www/node_modules/wrappy/test/basic.js @@ -0,0 +1,51 @@ +var test = require('tap').test +var wrappy = require('../wrappy.js') + +test('basic', function (t) { + function onceifier (cb) { + var called = false + return function () { + if (called) return + called = true + return cb.apply(this, arguments) + } + } + onceifier.iAmOnce = {} + var once = wrappy(onceifier) + t.equal(once.iAmOnce, onceifier.iAmOnce) + + var called = 0 + function boo () { + t.equal(called, 0) + called++ + } + // has some rando property + boo.iAmBoo = true + + var onlyPrintOnce = once(boo) + + onlyPrintOnce() // prints 'boo' + onlyPrintOnce() // does nothing + t.equal(called, 1) + + // random property is retained! + t.equal(onlyPrintOnce.iAmBoo, true) + + var logs = [] + var logwrap = wrappy(function (msg, cb) { + logs.push(msg + ' wrapping cb') + return function () { + logs.push(msg + ' before cb') + var ret = cb.apply(this, arguments) + logs.push(msg + ' after cb') + } + }) + + var c = logwrap('foo', function () { + t.same(logs, [ 'foo wrapping cb', 'foo before cb' ]) + }) + c() + t.same(logs, [ 'foo wrapping cb', 'foo before cb', 'foo after cb' ]) + + t.end() +}) diff --git a/platforms/android/assets/www/node_modules/wrappy/wrappy.js b/platforms/android/assets/www/node_modules/wrappy/wrappy.js new file mode 100644 index 0000000..bb7e7d6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/wrappy/wrappy.js @@ -0,0 +1,33 @@ +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} diff --git a/platforms/android/assets/www/node_modules/ws/.npmignore b/platforms/android/assets/www/node_modules/ws/.npmignore new file mode 100644 index 0000000..1eba800 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/.npmignore @@ -0,0 +1,11 @@ +npm-debug.log +node_modules +.*.swp +.lock-* +build + +bench +doc +examples +test + diff --git a/platforms/android/assets/www/node_modules/ws/.travis.yml b/platforms/android/assets/www/node_modules/ws/.travis.yml new file mode 100644 index 0000000..5002b49 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/.travis.yml @@ -0,0 +1,15 @@ +language: node_js +sudo: false +node_js: + - "5" + - "4" + - "0.12" +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - gcc-4.9 + - g++-4.9 +before_install: + - export CC="gcc-4.9" CXX="g++-4.9" diff --git a/platforms/android/assets/www/node_modules/ws/Makefile b/platforms/android/assets/www/node_modules/ws/Makefile new file mode 100644 index 0000000..00f19fa --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/Makefile @@ -0,0 +1,40 @@ +ALL_TESTS = $(shell find test/ -name '*.test.js') +ALL_INTEGRATION = $(shell find test/ -name '*.integration.js') + +all: + node-gyp configure build + +clean: + node-gyp clean + +run-tests: + @./node_modules/.bin/mocha \ + -t 5000 \ + -s 2400 \ + $(TESTFLAGS) \ + $(TESTS) + +run-integrationtests: + @./node_modules/.bin/mocha \ + -t 5000 \ + -s 6000 \ + $(TESTFLAGS) \ + $(TESTS) + +test: + @$(MAKE) NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests + +integrationtest: + @$(MAKE) NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=lib TESTS="$(ALL_INTEGRATION)" run-integrationtests + +benchmark: + @node bench/sender.benchmark.js + @node bench/parser.benchmark.js + +autobahn: + @NODE_PATH=lib node test/autobahn.js + +autobahn-server: + @NODE_PATH=lib node test/autobahn-server.js + +.PHONY: test diff --git a/platforms/android/assets/www/node_modules/ws/README.md b/platforms/android/assets/www/node_modules/ws/README.md new file mode 100644 index 0000000..9be2e51 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/README.md @@ -0,0 +1,242 @@ +# ws: a node.js websocket library + +[![Build Status](https://travis-ci.org/websockets/ws.svg?branch=master)](https://travis-ci.org/websockets/ws) + +`ws` is a simple to use WebSocket implementation, up-to-date against RFC-6455, +and [probably the fastest WebSocket library for node.js][archive]. + +Passes the quite extensive Autobahn test suite. See http://websockets.github.com/ws +for the full reports. + +## Protocol support + +* **Hixie draft 76** (Old and deprecated, but still in use by Safari and Opera. + Added to ws version 0.4.2, but server only. Can be disabled by setting the + `disableHixie` option to true.) +* **HyBi drafts 07-12** (Use the option `protocolVersion: 8`) +* **HyBi drafts 13-17** (Current default, alternatively option `protocolVersion: 13`) + +### Installing + +``` +npm install --save ws +``` + +### Opt-in for performance + +There are 2 optional modules that can be installed along side with the `ws` +module. These modules are binary addons which improve certain operations, but as +they are binary addons they require compilation which can fail if no c++ +compiler is installed on the host system. + +- `npm install --save bufferutil`: Improves internal buffer operations which + allows for faster processing of masked WebSocket frames and general buffer + operations. +- `npm install --save utf-8-validate`: The specification requires validation of + invalid UTF-8 chars, some of these validations could not be done in JavaScript + hence the need for a binary addon. In most cases you will already be + validating the input that you receive for security purposes leading to double + validation. But if you want to be 100% spec conform and fast validation of UTF-8 + then this module is a must. + +### Sending and receiving text data + +```js +var WebSocket = require('ws'); +var ws = new WebSocket('ws://www.host.com/path'); + +ws.on('open', function open() { + ws.send('something'); +}); + +ws.on('message', function(data, flags) { + // flags.binary will be set if a binary data is received. + // flags.masked will be set if the data was masked. +}); +``` + +### Sending binary data + +```js +var WebSocket = require('ws'); +var ws = new WebSocket('ws://www.host.com/path'); + +ws.on('open', function open() { + var array = new Float32Array(5); + + for (var i = 0; i < array.length; ++i) { + array[i] = i / 2; + } + + ws.send(array, { binary: true, mask: true }); +}); +``` + +Setting `mask`, as done for the send options above, will cause the data to be +masked according to the WebSocket protocol. The same option applies for text +data. + +### Server example + +```js +var WebSocketServer = require('ws').Server + , wss = new WebSocketServer({ port: 8080 }); + +wss.on('connection', function connection(ws) { + ws.on('message', function incoming(message) { + console.log('received: %s', message); + }); + + ws.send('something'); +}); +``` + +### ExpressJS example + +```js +var server = require('http').createServer() + , url = require('url') + , WebSocketServer = require('ws').Server + , wss = new WebSocketServer({ server: server }) + , express = require('express') + , app = express() + , port = 4080; + +app.use(function (req, res) { + res.send({ msg: "hello" }); +}); + +wss.on('connection', function connection(ws) { + var location = url.parse(ws.upgradeReq.url, true); + // you might use location.query.access_token to authenticate or share sessions + // or ws.upgradeReq.headers.cookie (see http://stackoverflow.com/a/16395220/151312) + + ws.on('message', function incoming(message) { + console.log('received: %s', message); + }); + + ws.send('something'); +}); + +server.on('request', app); +server.listen(port, function () { console.log('Listening on ' + server.address().port) }); +``` + +### Server sending broadcast data + +```js +var WebSocketServer = require('ws').Server + , wss = new WebSocketServer({ port: 8080 }); + +wss.broadcast = function broadcast(data) { + wss.clients.forEach(function each(client) { + client.send(data); + }); +}; +``` + +### Error handling best practices + +```js +// If the WebSocket is closed before the following send is attempted +ws.send('something'); + +// Errors (both immediate and async write errors) can be detected in an optional +// callback. The callback is also the only way of being notified that data has +// actually been sent. +ws.send('something', function ack(error) { + // if error is not defined, the send has been completed, + // otherwise the error object will indicate what failed. +}); + +// Immediate errors can also be handled with try/catch-blocks, but **note** that +// since sends are inherently asynchronous, socket write failures will *not* be +// captured when this technique is used. +try { ws.send('something'); } +catch (e) { /* handle error */ } +``` + +### echo.websocket.org demo + +```js +var WebSocket = require('ws'); +var ws = new WebSocket('ws://echo.websocket.org/', { + protocolVersion: 8, + origin: 'http://websocket.org' +}); + +ws.on('open', function open() { + console.log('connected'); + ws.send(Date.now().toString(), {mask: true}); +}); + +ws.on('close', function close() { + console.log('disconnected'); +}); + +ws.on('message', function message(data, flags) { + console.log('Roundtrip time: ' + (Date.now() - parseInt(data)) + 'ms', flags); + + setTimeout(function timeout() { + ws.send(Date.now().toString(), {mask: true}); + }, 500); +}); +``` + +### Browserify users +When including ws via a browserify bundle, ws returns global.WebSocket which has slightly different API. +You should use the standard WebSockets API instead. + +https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_client_applications#Availability_of_WebSockets + + +### Other examples + +For a full example with a browser client communicating with a ws server, see the +examples folder. + +Note that the usage together with Express 3.0 is quite different from Express +2.x. The difference is expressed in the two different serverstats-examples. + +Otherwise, see the test cases. + +### Running the tests + +``` +make test +``` + +## API Docs + +See [`/doc/ws.md`](https://github.com/websockets/ws/blob/master/doc/ws.md) for Node.js-like docs for the ws classes. + +## Changelog + +We're using the GitHub [`releases`](https://github.com/websockets/ws/releases) for changelog entries. + +## License + +(The MIT License) + +Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +[archive]: http://web.archive.org/web/20130314230536/http://hobbycoding.posterous.com/the-fastest-websocket-module-for-nodejs diff --git a/platforms/android/assets/www/node_modules/ws/index.js b/platforms/android/assets/www/node_modules/ws/index.js new file mode 100644 index 0000000..a7e8644 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/index.js @@ -0,0 +1,49 @@ +'use strict'; + +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var WS = module.exports = require('./lib/WebSocket'); + +WS.Server = require('./lib/WebSocketServer'); +WS.Sender = require('./lib/Sender'); +WS.Receiver = require('./lib/Receiver'); + +/** + * Create a new WebSocket server. + * + * @param {Object} options Server options + * @param {Function} fn Optional connection listener. + * @returns {WS.Server} + * @api public + */ +WS.createServer = function createServer(options, fn) { + var server = new WS.Server(options); + + if (typeof fn === 'function') { + server.on('connection', fn); + } + + return server; +}; + +/** + * Create a new WebSocket connection. + * + * @param {String} address The URL/address we need to connect to. + * @param {Function} fn Open listener. + * @returns {WS} + * @api public + */ +WS.connect = WS.createConnection = function connect(address, fn) { + var client = new WS(address); + + if (typeof fn === 'function') { + client.on('open', fn); + } + + return client; +}; diff --git a/platforms/android/assets/www/node_modules/ws/lib/BufferPool.js b/platforms/android/assets/www/node_modules/ws/lib/BufferPool.js new file mode 100644 index 0000000..8ee5990 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/BufferPool.js @@ -0,0 +1,63 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util'); + +function BufferPool(initialSize, growStrategy, shrinkStrategy) { + if (this instanceof BufferPool === false) { + throw new TypeError("Classes can't be function-called"); + } + + if (typeof initialSize === 'function') { + shrinkStrategy = growStrategy; + growStrategy = initialSize; + initialSize = 0; + } + else if (typeof initialSize === 'undefined') { + initialSize = 0; + } + this._growStrategy = (growStrategy || function(db, size) { + return db.used + size; + }).bind(null, this); + this._shrinkStrategy = (shrinkStrategy || function(db) { + return initialSize; + }).bind(null, this); + this._buffer = initialSize ? new Buffer(initialSize) : null; + this._offset = 0; + this._used = 0; + this._changeFactor = 0; + this.__defineGetter__('size', function(){ + return this._buffer == null ? 0 : this._buffer.length; + }); + this.__defineGetter__('used', function(){ + return this._used; + }); +} + +BufferPool.prototype.get = function(length) { + if (this._buffer == null || this._offset + length > this._buffer.length) { + var newBuf = new Buffer(this._growStrategy(length)); + this._buffer = newBuf; + this._offset = 0; + } + this._used += length; + var buf = this._buffer.slice(this._offset, this._offset + length); + this._offset += length; + return buf; +} + +BufferPool.prototype.reset = function(forceNewBuffer) { + var len = this._shrinkStrategy(); + if (len < this.size) this._changeFactor -= 1; + if (forceNewBuffer || this._changeFactor < -2) { + this._changeFactor = 0; + this._buffer = len ? new Buffer(len) : null; + } + this._offset = 0; + this._used = 0; +} + +module.exports = BufferPool; diff --git a/platforms/android/assets/www/node_modules/ws/lib/BufferUtil.fallback.js b/platforms/android/assets/www/node_modules/ws/lib/BufferUtil.fallback.js new file mode 100644 index 0000000..508542c --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/BufferUtil.fallback.js @@ -0,0 +1,47 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +module.exports.BufferUtil = { + merge: function(mergedBuffer, buffers) { + var offset = 0; + for (var i = 0, l = buffers.length; i < l; ++i) { + var buf = buffers[i]; + buf.copy(mergedBuffer, offset); + offset += buf.length; + } + }, + mask: function(source, mask, output, offset, length) { + var maskNum = mask.readUInt32LE(0, true); + var i = 0; + for (; i < length - 3; i += 4) { + var num = maskNum ^ source.readUInt32LE(i, true); + if (num < 0) num = 4294967296 + num; + output.writeUInt32LE(num, offset + i, true); + } + switch (length % 4) { + case 3: output[offset + i + 2] = source[i + 2] ^ mask[2]; + case 2: output[offset + i + 1] = source[i + 1] ^ mask[1]; + case 1: output[offset + i] = source[i] ^ mask[0]; + case 0:; + } + }, + unmask: function(data, mask) { + var maskNum = mask.readUInt32LE(0, true); + var length = data.length; + var i = 0; + for (; i < length - 3; i += 4) { + var num = maskNum ^ data.readUInt32LE(i, true); + if (num < 0) num = 4294967296 + num; + data.writeUInt32LE(num, i, true); + } + switch (length % 4) { + case 3: data[i + 2] = data[i + 2] ^ mask[2]; + case 2: data[i + 1] = data[i + 1] ^ mask[1]; + case 1: data[i] = data[i] ^ mask[0]; + case 0:; + } + } +} diff --git a/platforms/android/assets/www/node_modules/ws/lib/BufferUtil.js b/platforms/android/assets/www/node_modules/ws/lib/BufferUtil.js new file mode 100644 index 0000000..18c6998 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/BufferUtil.js @@ -0,0 +1,13 @@ +'use strict'; + +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +try { + module.exports = require('bufferutil'); +} catch (e) { + module.exports = require('./BufferUtil.fallback'); +} diff --git a/platforms/android/assets/www/node_modules/ws/lib/ErrorCodes.js b/platforms/android/assets/www/node_modules/ws/lib/ErrorCodes.js new file mode 100644 index 0000000..55ebd52 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/ErrorCodes.js @@ -0,0 +1,24 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +module.exports = { + isValidErrorCode: function(code) { + return (code >= 1000 && code <= 1011 && code != 1004 && code != 1005 && code != 1006) || + (code >= 3000 && code <= 4999); + }, + 1000: 'normal', + 1001: 'going away', + 1002: 'protocol error', + 1003: 'unsupported data', + 1004: 'reserved', + 1005: 'reserved for extensions', + 1006: 'reserved for extensions', + 1007: 'inconsistent or invalid data', + 1008: 'policy violation', + 1009: 'message too big', + 1010: 'extension handshake missing', + 1011: 'an unexpected condition prevented the request from being fulfilled', +}; \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/ws/lib/Extensions.js b/platforms/android/assets/www/node_modules/ws/lib/Extensions.js new file mode 100644 index 0000000..a465ace --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/Extensions.js @@ -0,0 +1,70 @@ + +var util = require('util'); + +/** + * Module exports. + */ + +exports.parse = parse; +exports.format = format; + +/** + * Parse extensions header value + */ + +function parse(value) { + value = value || ''; + + var extensions = {}; + + value.split(',').forEach(function(v) { + var params = v.split(';'); + var token = params.shift().trim(); + var paramsList = extensions[token] = extensions[token] || []; + var parsedParams = {}; + + params.forEach(function(param) { + var parts = param.trim().split('='); + var key = parts[0]; + var value = parts[1]; + if (typeof value === 'undefined') { + value = true; + } else { + // unquote value + if (value[0] === '"') { + value = value.slice(1); + } + if (value[value.length - 1] === '"') { + value = value.slice(0, value.length - 1); + } + } + (parsedParams[key] = parsedParams[key] || []).push(value); + }); + + paramsList.push(parsedParams); + }); + + return extensions; +} + +/** + * Format extensions header value + */ + +function format(value) { + return Object.keys(value).map(function(token) { + var paramsList = value[token]; + if (!util.isArray(paramsList)) { + paramsList = [paramsList]; + } + return paramsList.map(function(params) { + return [token].concat(Object.keys(params).map(function(k) { + var p = params[k]; + if (!util.isArray(p)) p = [p]; + return p.map(function(v) { + return v === true ? k : k + '=' + v; + }).join('; '); + })).join('; '); + }).join(', '); + }).join(', '); +} diff --git a/platforms/android/assets/www/node_modules/ws/lib/PerMessageDeflate.js b/platforms/android/assets/www/node_modules/ws/lib/PerMessageDeflate.js new file mode 100644 index 0000000..5324bd8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/PerMessageDeflate.js @@ -0,0 +1,325 @@ + +var zlib = require('zlib'); + +var AVAILABLE_WINDOW_BITS = [8, 9, 10, 11, 12, 13, 14, 15]; +var DEFAULT_WINDOW_BITS = 15; +var DEFAULT_MEM_LEVEL = 8; + +PerMessageDeflate.extensionName = 'permessage-deflate'; + +/** + * Per-message Compression Extensions implementation + */ + +function PerMessageDeflate(options, isServer) { + if (this instanceof PerMessageDeflate === false) { + throw new TypeError("Classes can't be function-called"); + } + + this._options = options || {}; + this._isServer = !!isServer; + this._inflate = null; + this._deflate = null; + this.params = null; +} + +/** + * Create extension parameters offer + * + * @api public + */ + +PerMessageDeflate.prototype.offer = function() { + var params = {}; + if (this._options.serverNoContextTakeover) { + params.server_no_context_takeover = true; + } + if (this._options.clientNoContextTakeover) { + params.client_no_context_takeover = true; + } + if (this._options.serverMaxWindowBits) { + params.server_max_window_bits = this._options.serverMaxWindowBits; + } + if (this._options.clientMaxWindowBits) { + params.client_max_window_bits = this._options.clientMaxWindowBits; + } else if (this._options.clientMaxWindowBits == null) { + params.client_max_window_bits = true; + } + return params; +}; + +/** + * Accept extension offer + * + * @api public + */ + +PerMessageDeflate.prototype.accept = function(paramsList) { + paramsList = this.normalizeParams(paramsList); + + var params; + if (this._isServer) { + params = this.acceptAsServer(paramsList); + } else { + params = this.acceptAsClient(paramsList); + } + + this.params = params; + return params; +}; + +/** + * Releases all resources used by the extension + * + * @api public + */ + +PerMessageDeflate.prototype.cleanup = function() { + if (this._inflate) { + if (this._inflate.writeInProgress) { + this._inflate.pendingClose = true; + } else { + if (this._inflate.close) this._inflate.close(); + this._inflate = null; + } + } + if (this._deflate) { + if (this._deflate.writeInProgress) { + this._deflate.pendingClose = true; + } else { + if (this._deflate.close) this._deflate.close(); + this._deflate = null; + } + } +}; + +/** + * Accept extension offer from client + * + * @api private + */ + +PerMessageDeflate.prototype.acceptAsServer = function(paramsList) { + var accepted = {}; + var result = paramsList.some(function(params) { + accepted = {}; + if (this._options.serverNoContextTakeover === false && params.server_no_context_takeover) { + return; + } + if (this._options.serverMaxWindowBits === false && params.server_max_window_bits) { + return; + } + if (typeof this._options.serverMaxWindowBits === 'number' && + typeof params.server_max_window_bits === 'number' && + this._options.serverMaxWindowBits > params.server_max_window_bits) { + return; + } + if (typeof this._options.clientMaxWindowBits === 'number' && !params.client_max_window_bits) { + return; + } + + if (this._options.serverNoContextTakeover || params.server_no_context_takeover) { + accepted.server_no_context_takeover = true; + } + if (this._options.clientNoContextTakeover) { + accepted.client_no_context_takeover = true; + } + if (this._options.clientNoContextTakeover !== false && params.client_no_context_takeover) { + accepted.client_no_context_takeover = true; + } + if (typeof this._options.serverMaxWindowBits === 'number') { + accepted.server_max_window_bits = this._options.serverMaxWindowBits; + } else if (typeof params.server_max_window_bits === 'number') { + accepted.server_max_window_bits = params.server_max_window_bits; + } + if (typeof this._options.clientMaxWindowBits === 'number') { + accepted.client_max_window_bits = this._options.clientMaxWindowBits; + } else if (this._options.clientMaxWindowBits !== false && typeof params.client_max_window_bits === 'number') { + accepted.client_max_window_bits = params.client_max_window_bits; + } + return true; + }, this); + + if (!result) { + throw new Error('Doesn\'t support the offered configuration'); + } + + return accepted; +}; + +/** + * Accept extension response from server + * + * @api privaye + */ + +PerMessageDeflate.prototype.acceptAsClient = function(paramsList) { + var params = paramsList[0]; + if (this._options.clientNoContextTakeover != null) { + if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) { + throw new Error('Invalid value for "client_no_context_takeover"'); + } + } + if (this._options.clientMaxWindowBits != null) { + if (this._options.clientMaxWindowBits === false && params.client_max_window_bits) { + throw new Error('Invalid value for "client_max_window_bits"'); + } + if (typeof this._options.clientMaxWindowBits === 'number' && + (!params.client_max_window_bits || params.client_max_window_bits > this._options.clientMaxWindowBits)) { + throw new Error('Invalid value for "client_max_window_bits"'); + } + } + return params; +}; + +/** + * Normalize extensions parameters + * + * @api private + */ + +PerMessageDeflate.prototype.normalizeParams = function(paramsList) { + return paramsList.map(function(params) { + Object.keys(params).forEach(function(key) { + var value = params[key]; + if (value.length > 1) { + throw new Error('Multiple extension parameters for ' + key); + } + + value = value[0]; + + switch (key) { + case 'server_no_context_takeover': + case 'client_no_context_takeover': + if (value !== true) { + throw new Error('invalid extension parameter value for ' + key + ' (' + value + ')'); + } + params[key] = true; + break; + case 'server_max_window_bits': + case 'client_max_window_bits': + if (typeof value === 'string') { + value = parseInt(value, 10); + if (!~AVAILABLE_WINDOW_BITS.indexOf(value)) { + throw new Error('invalid extension parameter value for ' + key + ' (' + value + ')'); + } + } + if (!this._isServer && value === true) { + throw new Error('Missing extension parameter value for ' + key); + } + params[key] = value; + break; + default: + throw new Error('Not defined extension parameter (' + key + ')'); + } + }, this); + return params; + }, this); +}; + +/** + * Decompress message + * + * @api public + */ + +PerMessageDeflate.prototype.decompress = function (data, fin, callback) { + var endpoint = this._isServer ? 'client' : 'server'; + + if (!this._inflate) { + var maxWindowBits = this.params[endpoint + '_max_window_bits']; + this._inflate = zlib.createInflateRaw({ + windowBits: 'number' === typeof maxWindowBits ? maxWindowBits : DEFAULT_WINDOW_BITS + }); + } + this._inflate.writeInProgress = true; + + var self = this; + var buffers = []; + + this._inflate.on('error', onError).on('data', onData); + this._inflate.write(data); + if (fin) { + this._inflate.write(new Buffer([0x00, 0x00, 0xff, 0xff])); + } + this._inflate.flush(function() { + cleanup(); + callback(null, Buffer.concat(buffers)); + }); + + function onError(err) { + cleanup(); + callback(err); + } + + function onData(data) { + buffers.push(data); + } + + function cleanup() { + if (!self._inflate) return; + self._inflate.removeListener('error', onError); + self._inflate.removeListener('data', onData); + self._inflate.writeInProgress = false; + if ((fin && self.params[endpoint + '_no_context_takeover']) || self._inflate.pendingClose) { + if (self._inflate.close) self._inflate.close(); + self._inflate = null; + } + } +}; + +/** + * Compress message + * + * @api public + */ + +PerMessageDeflate.prototype.compress = function (data, fin, callback) { + var endpoint = this._isServer ? 'server' : 'client'; + + if (!this._deflate) { + var maxWindowBits = this.params[endpoint + '_max_window_bits']; + this._deflate = zlib.createDeflateRaw({ + flush: zlib.Z_SYNC_FLUSH, + windowBits: 'number' === typeof maxWindowBits ? maxWindowBits : DEFAULT_WINDOW_BITS, + memLevel: this._options.memLevel || DEFAULT_MEM_LEVEL + }); + } + this._deflate.writeInProgress = true; + + var self = this; + var buffers = []; + + this._deflate.on('error', onError).on('data', onData); + this._deflate.write(data); + this._deflate.flush(function() { + cleanup(); + var data = Buffer.concat(buffers); + if (fin) { + data = data.slice(0, data.length - 4); + } + callback(null, data); + }); + + function onError(err) { + cleanup(); + callback(err); + } + + function onData(data) { + buffers.push(data); + } + + function cleanup() { + if (!self._deflate) return; + self._deflate.removeListener('error', onError); + self._deflate.removeListener('data', onData); + self._deflate.writeInProgress = false; + if ((fin && self.params[endpoint + '_no_context_takeover']) || self._deflate.pendingClose) { + if (self._deflate.close) self._deflate.close(); + self._deflate = null; + } + } +}; + +module.exports = PerMessageDeflate; diff --git a/platforms/android/assets/www/node_modules/ws/lib/Receiver.hixie.js b/platforms/android/assets/www/node_modules/ws/lib/Receiver.hixie.js new file mode 100644 index 0000000..66bc561 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/Receiver.hixie.js @@ -0,0 +1,184 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util'); + +/** + * State constants + */ + +var EMPTY = 0 + , BODY = 1; +var BINARYLENGTH = 2 + , BINARYBODY = 3; + +/** + * Hixie Receiver implementation + */ + +function Receiver () { + if (this instanceof Receiver === false) { + throw new TypeError("Classes can't be function-called"); + } + + this.state = EMPTY; + this.buffers = []; + this.messageEnd = -1; + this.spanLength = 0; + this.dead = false; + + this.onerror = function() {}; + this.ontext = function() {}; + this.onbinary = function() {}; + this.onclose = function() {}; + this.onping = function() {}; + this.onpong = function() {}; +} + +module.exports = Receiver; + +/** + * Add new data to the parser. + * + * @api public + */ + +Receiver.prototype.add = function(data) { + var self = this; + function doAdd() { + if (self.state === EMPTY) { + if (data.length == 2 && data[0] == 0xFF && data[1] == 0x00) { + self.reset(); + self.onclose(); + return; + } + if (data[0] === 0x80) { + self.messageEnd = 0; + self.state = BINARYLENGTH; + data = data.slice(1); + } else { + + if (data[0] !== 0x00) { + self.error('payload must start with 0x00 byte', true); + return; + } + data = data.slice(1); + self.state = BODY; + + } + } + if (self.state === BINARYLENGTH) { + var i = 0; + while ((i < data.length) && (data[i] & 0x80)) { + self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f); + ++i; + } + if (i < data.length) { + self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f); + self.state = BINARYBODY; + ++i; + } + if (i > 0) + data = data.slice(i); + } + if (self.state === BINARYBODY) { + var dataleft = self.messageEnd - self.spanLength; + if (data.length >= dataleft) { + // consume the whole buffer to finish the frame + self.buffers.push(data); + self.spanLength += dataleft; + self.messageEnd = dataleft; + return self.parse(); + } + // frame's not done even if we consume it all + self.buffers.push(data); + self.spanLength += data.length; + return; + } + self.buffers.push(data); + if ((self.messageEnd = bufferIndex(data, 0xFF)) != -1) { + self.spanLength += self.messageEnd; + return self.parse(); + } + else self.spanLength += data.length; + } + while(data) data = doAdd(); +}; + +/** + * Releases all resources used by the receiver. + * + * @api public + */ + +Receiver.prototype.cleanup = function() { + this.dead = true; + this.state = EMPTY; + this.buffers = []; +}; + +/** + * Process buffered data. + * + * @api public + */ + +Receiver.prototype.parse = function() { + var output = new Buffer(this.spanLength); + var outputIndex = 0; + for (var bi = 0, bl = this.buffers.length; bi < bl - 1; ++bi) { + var buffer = this.buffers[bi]; + buffer.copy(output, outputIndex); + outputIndex += buffer.length; + } + var lastBuffer = this.buffers[this.buffers.length - 1]; + if (this.messageEnd > 0) lastBuffer.copy(output, outputIndex, 0, this.messageEnd); + if (this.state !== BODY) --this.messageEnd; + var tail = null; + if (this.messageEnd < lastBuffer.length - 1) { + tail = lastBuffer.slice(this.messageEnd + 1); + } + this.reset(); + this.ontext(output.toString('utf8')); + return tail; +}; + +/** + * Handles an error + * + * @api private + */ + +Receiver.prototype.error = function (reason, terminate) { + this.reset(); + this.onerror(reason, terminate); + return this; +}; + +/** + * Reset parser state + * + * @api private + */ + +Receiver.prototype.reset = function (reason) { + if (this.dead) return; + this.state = EMPTY; + this.buffers = []; + this.messageEnd = -1; + this.spanLength = 0; +}; + +/** + * Internal api + */ + +function bufferIndex(buffer, byte) { + for (var i = 0, l = buffer.length; i < l; ++i) { + if (buffer[i] === byte) return i; + } + return -1; +} diff --git a/platforms/android/assets/www/node_modules/ws/lib/Receiver.js b/platforms/android/assets/www/node_modules/ws/lib/Receiver.js new file mode 100644 index 0000000..b3183bf --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/Receiver.js @@ -0,0 +1,702 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util') + , Validation = require('./Validation').Validation + , ErrorCodes = require('./ErrorCodes') + , BufferPool = require('./BufferPool') + , bufferUtil = require('./BufferUtil').BufferUtil + , PerMessageDeflate = require('./PerMessageDeflate'); + +/** + * HyBi Receiver implementation + */ + +function Receiver (extensions) { + if (this instanceof Receiver === false) { + throw new TypeError("Classes can't be function-called"); + } + + // memory pool for fragmented messages + var fragmentedPoolPrevUsed = -1; + this.fragmentedBufferPool = new BufferPool(1024, function(db, length) { + return db.used + length; + }, function(db) { + return fragmentedPoolPrevUsed = fragmentedPoolPrevUsed >= 0 ? + Math.ceil((fragmentedPoolPrevUsed + db.used) / 2) : + db.used; + }); + + // memory pool for unfragmented messages + var unfragmentedPoolPrevUsed = -1; + this.unfragmentedBufferPool = new BufferPool(1024, function(db, length) { + return db.used + length; + }, function(db) { + return unfragmentedPoolPrevUsed = unfragmentedPoolPrevUsed >= 0 ? + Math.ceil((unfragmentedPoolPrevUsed + db.used) / 2) : + db.used; + }); + + this.extensions = extensions || {}; + this.state = { + activeFragmentedOperation: null, + lastFragment: false, + masked: false, + opcode: 0, + fragmentedOperation: false + }; + this.overflow = []; + this.headerBuffer = new Buffer(10); + this.expectOffset = 0; + this.expectBuffer = null; + this.expectHandler = null; + this.currentMessage = []; + this.messageHandlers = []; + this.expectHeader(2, this.processPacket); + this.dead = false; + this.processing = false; + + this.onerror = function() {}; + this.ontext = function() {}; + this.onbinary = function() {}; + this.onclose = function() {}; + this.onping = function() {}; + this.onpong = function() {}; +} + +module.exports = Receiver; + +/** + * Add new data to the parser. + * + * @api public + */ + +Receiver.prototype.add = function(data) { + var dataLength = data.length; + if (dataLength == 0) return; + if (this.expectBuffer == null) { + this.overflow.push(data); + return; + } + var toRead = Math.min(dataLength, this.expectBuffer.length - this.expectOffset); + fastCopy(toRead, data, this.expectBuffer, this.expectOffset); + this.expectOffset += toRead; + if (toRead < dataLength) { + this.overflow.push(data.slice(toRead)); + } + while (this.expectBuffer && this.expectOffset == this.expectBuffer.length) { + var bufferForHandler = this.expectBuffer; + this.expectBuffer = null; + this.expectOffset = 0; + this.expectHandler.call(this, bufferForHandler); + } +}; + +/** + * Releases all resources used by the receiver. + * + * @api public + */ + +Receiver.prototype.cleanup = function() { + this.dead = true; + this.overflow = null; + this.headerBuffer = null; + this.expectBuffer = null; + this.expectHandler = null; + this.unfragmentedBufferPool = null; + this.fragmentedBufferPool = null; + this.state = null; + this.currentMessage = null; + this.onerror = null; + this.ontext = null; + this.onbinary = null; + this.onclose = null; + this.onping = null; + this.onpong = null; +}; + +/** + * Waits for a certain amount of header bytes to be available, then fires a callback. + * + * @api private + */ + +Receiver.prototype.expectHeader = function(length, handler) { + if (length == 0) { + handler(null); + return; + } + this.expectBuffer = this.headerBuffer.slice(this.expectOffset, this.expectOffset + length); + this.expectHandler = handler; + var toRead = length; + while (toRead > 0 && this.overflow.length > 0) { + var fromOverflow = this.overflow.pop(); + if (toRead < fromOverflow.length) this.overflow.push(fromOverflow.slice(toRead)); + var read = Math.min(fromOverflow.length, toRead); + fastCopy(read, fromOverflow, this.expectBuffer, this.expectOffset); + this.expectOffset += read; + toRead -= read; + } +}; + +/** + * Waits for a certain amount of data bytes to be available, then fires a callback. + * + * @api private + */ + +Receiver.prototype.expectData = function(length, handler) { + if (length == 0) { + handler(null); + return; + } + this.expectBuffer = this.allocateFromPool(length, this.state.fragmentedOperation); + this.expectHandler = handler; + var toRead = length; + while (toRead > 0 && this.overflow.length > 0) { + var fromOverflow = this.overflow.pop(); + if (toRead < fromOverflow.length) this.overflow.push(fromOverflow.slice(toRead)); + var read = Math.min(fromOverflow.length, toRead); + fastCopy(read, fromOverflow, this.expectBuffer, this.expectOffset); + this.expectOffset += read; + toRead -= read; + } +}; + +/** + * Allocates memory from the buffer pool. + * + * @api private + */ + +Receiver.prototype.allocateFromPool = function(length, isFragmented) { + return (isFragmented ? this.fragmentedBufferPool : this.unfragmentedBufferPool).get(length); +}; + +/** + * Start processing a new packet. + * + * @api private + */ + +Receiver.prototype.processPacket = function (data) { + if (this.extensions[PerMessageDeflate.extensionName]) { + if ((data[0] & 0x30) != 0) { + this.error('reserved fields (2, 3) must be empty', 1002); + return; + } + } else { + if ((data[0] & 0x70) != 0) { + this.error('reserved fields must be empty', 1002); + return; + } + } + this.state.lastFragment = (data[0] & 0x80) == 0x80; + this.state.masked = (data[1] & 0x80) == 0x80; + var compressed = (data[0] & 0x40) == 0x40; + var opcode = data[0] & 0xf; + if (opcode === 0) { + if (compressed) { + this.error('continuation frame cannot have the Per-message Compressed bits', 1002); + return; + } + // continuation frame + this.state.fragmentedOperation = true; + this.state.opcode = this.state.activeFragmentedOperation; + if (!(this.state.opcode == 1 || this.state.opcode == 2)) { + this.error('continuation frame cannot follow current opcode', 1002); + return; + } + } + else { + if (opcode < 3 && this.state.activeFragmentedOperation != null) { + this.error('data frames after the initial data frame must have opcode 0', 1002); + return; + } + if (opcode >= 8 && compressed) { + this.error('control frames cannot have the Per-message Compressed bits', 1002); + return; + } + this.state.compressed = compressed; + this.state.opcode = opcode; + if (this.state.lastFragment === false) { + this.state.fragmentedOperation = true; + this.state.activeFragmentedOperation = opcode; + } + else this.state.fragmentedOperation = false; + } + var handler = opcodes[this.state.opcode]; + if (typeof handler == 'undefined') this.error('no handler for opcode ' + this.state.opcode, 1002); + else { + handler.start.call(this, data); + } +}; + +/** + * Endprocessing a packet. + * + * @api private + */ + +Receiver.prototype.endPacket = function() { + if (!this.state.fragmentedOperation) this.unfragmentedBufferPool.reset(true); + else if (this.state.lastFragment) this.fragmentedBufferPool.reset(true); + this.expectOffset = 0; + this.expectBuffer = null; + this.expectHandler = null; + if (this.state.lastFragment && this.state.opcode === this.state.activeFragmentedOperation) { + // end current fragmented operation + this.state.activeFragmentedOperation = null; + } + this.state.lastFragment = false; + this.state.opcode = this.state.activeFragmentedOperation != null ? this.state.activeFragmentedOperation : 0; + this.state.masked = false; + this.expectHeader(2, this.processPacket); +}; + +/** + * Reset the parser state. + * + * @api private + */ + +Receiver.prototype.reset = function() { + if (this.dead) return; + this.state = { + activeFragmentedOperation: null, + lastFragment: false, + masked: false, + opcode: 0, + fragmentedOperation: false + }; + this.fragmentedBufferPool.reset(true); + this.unfragmentedBufferPool.reset(true); + this.expectOffset = 0; + this.expectBuffer = null; + this.expectHandler = null; + this.overflow = []; + this.currentMessage = []; + this.messageHandlers = []; +}; + +/** + * Unmask received data. + * + * @api private + */ + +Receiver.prototype.unmask = function (mask, buf, binary) { + if (mask != null && buf != null) bufferUtil.unmask(buf, mask); + if (binary) return buf; + return buf != null ? buf.toString('utf8') : ''; +}; + +/** + * Concatenates a list of buffers. + * + * @api private + */ + +Receiver.prototype.concatBuffers = function(buffers) { + var length = 0; + for (var i = 0, l = buffers.length; i < l; ++i) length += buffers[i].length; + var mergedBuffer = new Buffer(length); + bufferUtil.merge(mergedBuffer, buffers); + return mergedBuffer; +}; + +/** + * Handles an error + * + * @api private + */ + +Receiver.prototype.error = function (reason, protocolErrorCode) { + this.reset(); + this.onerror(reason, protocolErrorCode); + return this; +}; + +/** + * Execute message handler buffers + * + * @api private + */ + +Receiver.prototype.flush = function() { + if (this.processing || this.dead) return; + + var handler = this.messageHandlers.shift(); + if (!handler) return; + + this.processing = true; + var self = this; + + handler(function() { + self.processing = false; + self.flush(); + }); +}; + +/** + * Apply extensions to message + * + * @api private + */ + +Receiver.prototype.applyExtensions = function(messageBuffer, fin, compressed, callback) { + var self = this; + if (compressed) { + this.extensions[PerMessageDeflate.extensionName].decompress(messageBuffer, fin, function(err, buffer) { + if (self.dead) return; + if (err) { + callback(new Error('invalid compressed data')); + return; + } + callback(null, buffer); + }); + } else { + callback(null, messageBuffer); + } +}; + +/** + * Buffer utilities + */ + +function readUInt16BE(start) { + return (this[start]<<8) + + this[start+1]; +} + +function readUInt32BE(start) { + return (this[start]<<24) + + (this[start+1]<<16) + + (this[start+2]<<8) + + this[start+3]; +} + +function fastCopy(length, srcBuffer, dstBuffer, dstOffset) { + switch (length) { + default: srcBuffer.copy(dstBuffer, dstOffset, 0, length); break; + case 16: dstBuffer[dstOffset+15] = srcBuffer[15]; + case 15: dstBuffer[dstOffset+14] = srcBuffer[14]; + case 14: dstBuffer[dstOffset+13] = srcBuffer[13]; + case 13: dstBuffer[dstOffset+12] = srcBuffer[12]; + case 12: dstBuffer[dstOffset+11] = srcBuffer[11]; + case 11: dstBuffer[dstOffset+10] = srcBuffer[10]; + case 10: dstBuffer[dstOffset+9] = srcBuffer[9]; + case 9: dstBuffer[dstOffset+8] = srcBuffer[8]; + case 8: dstBuffer[dstOffset+7] = srcBuffer[7]; + case 7: dstBuffer[dstOffset+6] = srcBuffer[6]; + case 6: dstBuffer[dstOffset+5] = srcBuffer[5]; + case 5: dstBuffer[dstOffset+4] = srcBuffer[4]; + case 4: dstBuffer[dstOffset+3] = srcBuffer[3]; + case 3: dstBuffer[dstOffset+2] = srcBuffer[2]; + case 2: dstBuffer[dstOffset+1] = srcBuffer[1]; + case 1: dstBuffer[dstOffset] = srcBuffer[0]; + } +} + +function clone(obj) { + var cloned = {}; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + cloned[k] = obj[k]; + } + } + return cloned; +} + +/** + * Opcode handlers + */ + +var opcodes = { + // text + '1': { + start: function(data) { + var self = this; + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['1'].getData.call(self, firstLength); + } + else if (firstLength == 126) { + self.expectHeader(2, function(data) { + opcodes['1'].getData.call(self, readUInt16BE.call(data, 0)); + }); + } + else if (firstLength == 127) { + self.expectHeader(8, function(data) { + if (readUInt32BE.call(data, 0) != 0) { + self.error('packets with length spanning more than 32 bit is currently not supported', 1008); + return; + } + opcodes['1'].getData.call(self, readUInt32BE.call(data, 4)); + }); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['1'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['1'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var self = this; + var packet = this.unmask(mask, data, true) || new Buffer(0); + var state = clone(this.state); + this.messageHandlers.push(function(callback) { + self.applyExtensions(packet, state.lastFragment, state.compressed, function(err, buffer) { + if (err) return self.error(err.message, 1007); + if (buffer != null) self.currentMessage.push(buffer); + + if (state.lastFragment) { + var messageBuffer = self.concatBuffers(self.currentMessage); + self.currentMessage = []; + if (!Validation.isValidUTF8(messageBuffer)) { + self.error('invalid utf8 sequence', 1007); + return; + } + self.ontext(messageBuffer.toString('utf8'), {masked: state.masked, buffer: messageBuffer}); + } + callback(); + }); + }); + this.flush(); + this.endPacket(); + } + }, + // binary + '2': { + start: function(data) { + var self = this; + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['2'].getData.call(self, firstLength); + } + else if (firstLength == 126) { + self.expectHeader(2, function(data) { + opcodes['2'].getData.call(self, readUInt16BE.call(data, 0)); + }); + } + else if (firstLength == 127) { + self.expectHeader(8, function(data) { + if (readUInt32BE.call(data, 0) != 0) { + self.error('packets with length spanning more than 32 bit is currently not supported', 1008); + return; + } + opcodes['2'].getData.call(self, readUInt32BE.call(data, 4, true)); + }); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['2'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['2'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var self = this; + var packet = this.unmask(mask, data, true) || new Buffer(0); + var state = clone(this.state); + this.messageHandlers.push(function(callback) { + self.applyExtensions(packet, state.lastFragment, state.compressed, function(err, buffer) { + if (err) return self.error(err.message, 1007); + if (buffer != null) self.currentMessage.push(buffer); + if (state.lastFragment) { + var messageBuffer = self.concatBuffers(self.currentMessage); + self.currentMessage = []; + self.onbinary(messageBuffer, {masked: state.masked, buffer: messageBuffer}); + } + callback(); + }); + }); + this.flush(); + this.endPacket(); + } + }, + // close + '8': { + start: function(data) { + var self = this; + if (self.state.lastFragment == false) { + self.error('fragmented close is not supported', 1002); + return; + } + + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['8'].getData.call(self, firstLength); + } + else { + self.error('control frames cannot have more than 125 bytes of data', 1002); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['8'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['8'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var self = this; + data = self.unmask(mask, data, true); + + var state = clone(this.state); + this.messageHandlers.push(function() { + if (data && data.length == 1) { + self.error('close packets with data must be at least two bytes long', 1002); + return; + } + var code = data && data.length > 1 ? readUInt16BE.call(data, 0) : 1000; + if (!ErrorCodes.isValidErrorCode(code)) { + self.error('invalid error code', 1002); + return; + } + var message = ''; + if (data && data.length > 2) { + var messageBuffer = data.slice(2); + if (!Validation.isValidUTF8(messageBuffer)) { + self.error('invalid utf8 sequence', 1007); + return; + } + message = messageBuffer.toString('utf8'); + } + self.onclose(code, message, {masked: state.masked}); + self.reset(); + }); + this.flush(); + }, + }, + // ping + '9': { + start: function(data) { + var self = this; + if (self.state.lastFragment == false) { + self.error('fragmented ping is not supported', 1002); + return; + } + + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['9'].getData.call(self, firstLength); + } + else { + self.error('control frames cannot have more than 125 bytes of data', 1002); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['9'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['9'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var self = this; + data = this.unmask(mask, data, true); + var state = clone(this.state); + this.messageHandlers.push(function(callback) { + self.onping(data, {masked: state.masked, binary: true}); + callback(); + }); + this.flush(); + this.endPacket(); + } + }, + // pong + '10': { + start: function(data) { + var self = this; + if (self.state.lastFragment == false) { + self.error('fragmented pong is not supported', 1002); + return; + } + + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['10'].getData.call(self, firstLength); + } + else { + self.error('control frames cannot have more than 125 bytes of data', 1002); + } + }, + getData: function(length) { + var self = this; + if (this.state.masked) { + this.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['10'].finish.call(self, mask, data); + }); + }); + } + else { + this.expectData(length, function(data) { + opcodes['10'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var self = this; + data = self.unmask(mask, data, true); + var state = clone(this.state); + this.messageHandlers.push(function(callback) { + self.onpong(data, {masked: state.masked, binary: true}); + callback(); + }); + this.flush(); + this.endPacket(); + } + } +} diff --git a/platforms/android/assets/www/node_modules/ws/lib/Sender.hixie.js b/platforms/android/assets/www/node_modules/ws/lib/Sender.hixie.js new file mode 100644 index 0000000..b87d9dd --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/Sender.hixie.js @@ -0,0 +1,124 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var events = require('events') + , util = require('util') + , EventEmitter = events.EventEmitter; + +/** + * Hixie Sender implementation + */ + +function Sender(socket) { + if (this instanceof Sender === false) { + throw new TypeError("Classes can't be function-called"); + } + + events.EventEmitter.call(this); + + this.socket = socket; + this.continuationFrame = false; + this.isClosed = false; +} + +module.exports = Sender; + +/** + * Inherits from EventEmitter. + */ + +util.inherits(Sender, events.EventEmitter); + +/** + * Frames and writes data. + * + * @api public + */ + +Sender.prototype.send = function(data, options, cb) { + if (this.isClosed) return; + + var isString = typeof data == 'string' + , length = isString ? Buffer.byteLength(data) : data.length + , lengthbytes = (length > 127) ? 2 : 1 // assume less than 2**14 bytes + , writeStartMarker = this.continuationFrame == false + , writeEndMarker = !options || !(typeof options.fin != 'undefined' && !options.fin) + , buffer = new Buffer((writeStartMarker ? ((options && options.binary) ? (1 + lengthbytes) : 1) : 0) + length + ((writeEndMarker && !(options && options.binary)) ? 1 : 0)) + , offset = writeStartMarker ? 1 : 0; + + if (writeStartMarker) { + if (options && options.binary) { + buffer.write('\x80', 'binary'); + // assume length less than 2**14 bytes + if (lengthbytes > 1) + buffer.write(String.fromCharCode(128+length/128), offset++, 'binary'); + buffer.write(String.fromCharCode(length&0x7f), offset++, 'binary'); + } else + buffer.write('\x00', 'binary'); + } + + if (isString) buffer.write(data, offset, 'utf8'); + else data.copy(buffer, offset, 0); + + if (writeEndMarker) { + if (options && options.binary) { + // sending binary, not writing end marker + } else + buffer.write('\xff', offset + length, 'binary'); + this.continuationFrame = false; + } + else this.continuationFrame = true; + + try { + this.socket.write(buffer, 'binary', cb); + } catch (e) { + this.error(e.toString()); + } +}; + +/** + * Sends a close instruction to the remote party. + * + * @api public + */ + +Sender.prototype.close = function(code, data, mask, cb) { + if (this.isClosed) return; + this.isClosed = true; + try { + if (this.continuationFrame) this.socket.write(new Buffer([0xff], 'binary')); + this.socket.write(new Buffer([0xff, 0x00]), 'binary', cb); + } catch (e) { + this.error(e.toString()); + } +}; + +/** + * Sends a ping message to the remote party. Not available for hixie. + * + * @api public + */ + +Sender.prototype.ping = function(data, options) {}; + +/** + * Sends a pong message to the remote party. Not available for hixie. + * + * @api public + */ + +Sender.prototype.pong = function(data, options) {}; + +/** + * Handles an error + * + * @api private + */ + +Sender.prototype.error = function (reason) { + this.emit('error', reason); + return this; +}; diff --git a/platforms/android/assets/www/node_modules/ws/lib/Sender.js b/platforms/android/assets/www/node_modules/ws/lib/Sender.js new file mode 100644 index 0000000..d34061e --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/Sender.js @@ -0,0 +1,324 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var events = require('events') + , util = require('util') + , EventEmitter = events.EventEmitter + , ErrorCodes = require('./ErrorCodes') + , bufferUtil = require('./BufferUtil').BufferUtil + , PerMessageDeflate = require('./PerMessageDeflate'); + +/** + * HyBi Sender implementation + */ + +function Sender(socket, extensions) { + if (this instanceof Sender === false) { + throw new TypeError("Classes can't be function-called"); + } + + events.EventEmitter.call(this); + + this._socket = socket; + this.extensions = extensions || {}; + this.firstFragment = true; + this.compress = false; + this.messageHandlers = []; + this.processing = false; +} + +/** + * Inherits from EventEmitter. + */ + +util.inherits(Sender, events.EventEmitter); + +/** + * Sends a close instruction to the remote party. + * + * @api public + */ + +Sender.prototype.close = function(code, data, mask, cb) { + if (typeof code !== 'undefined') { + if (typeof code !== 'number' || + !ErrorCodes.isValidErrorCode(code)) throw new Error('first argument must be a valid error code number'); + } + code = code || 1000; + var dataBuffer = new Buffer(2 + (data ? Buffer.byteLength(data) : 0)); + writeUInt16BE.call(dataBuffer, code, 0); + if (dataBuffer.length > 2) dataBuffer.write(data, 2); + + var self = this; + this.messageHandlers.push(function(callback) { + self.frameAndSend(0x8, dataBuffer, true, mask); + callback(); + if (typeof cb == 'function') cb(); + }); + this.flush(); +}; + +/** + * Sends a ping message to the remote party. + * + * @api public + */ + +Sender.prototype.ping = function(data, options) { + var mask = options && options.mask; + var self = this; + this.messageHandlers.push(function(callback) { + self.frameAndSend(0x9, data || '', true, mask); + callback(); + }); + this.flush(); +}; + +/** + * Sends a pong message to the remote party. + * + * @api public + */ + +Sender.prototype.pong = function(data, options) { + var mask = options && options.mask; + var self = this; + this.messageHandlers.push(function(callback) { + self.frameAndSend(0xa, data || '', true, mask); + callback(); + }); + this.flush(); +}; + +/** + * Sends text or binary data to the remote party. + * + * @api public + */ + +Sender.prototype.send = function(data, options, cb) { + var finalFragment = options && options.fin === false ? false : true; + var mask = options && options.mask; + var compress = options && options.compress; + var opcode = options && options.binary ? 2 : 1; + if (this.firstFragment === false) { + opcode = 0; + compress = false; + } else { + this.firstFragment = false; + this.compress = compress; + } + if (finalFragment) this.firstFragment = true + + var compressFragment = this.compress; + + var self = this; + this.messageHandlers.push(function(callback) { + self.applyExtensions(data, finalFragment, compressFragment, function(err, data) { + if (err) { + if (typeof cb == 'function') cb(err); + else self.emit('error', err); + return; + } + self.frameAndSend(opcode, data, finalFragment, mask, compress, cb); + callback(); + }); + }); + this.flush(); +}; + +/** + * Frames and sends a piece of data according to the HyBi WebSocket protocol. + * + * @api private + */ + +Sender.prototype.frameAndSend = function(opcode, data, finalFragment, maskData, compressed, cb) { + var canModifyData = false; + + if (!data) { + try { + this._socket.write(new Buffer([opcode | (finalFragment ? 0x80 : 0), 0 | (maskData ? 0x80 : 0)].concat(maskData ? [0, 0, 0, 0] : [])), 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + return; + } + + if (!Buffer.isBuffer(data)) { + canModifyData = true; + if (data && (typeof data.byteLength !== 'undefined' || typeof data.buffer !== 'undefined')) { + data = getArrayBuffer(data); + } else { + // + // If people want to send a number, this would allocate the number in + // bytes as memory size instead of storing the number as buffer value. So + // we need to transform it to string in order to prevent possible + // vulnerabilities / memory attacks. + // + if (typeof data === 'number') data = data.toString(); + + data = new Buffer(data); + } + } + + var dataLength = data.length + , dataOffset = maskData ? 6 : 2 + , secondByte = dataLength; + + if (dataLength >= 65536) { + dataOffset += 8; + secondByte = 127; + } + else if (dataLength > 125) { + dataOffset += 2; + secondByte = 126; + } + + var mergeBuffers = dataLength < 32768 || (maskData && !canModifyData); + var totalLength = mergeBuffers ? dataLength + dataOffset : dataOffset; + var outputBuffer = new Buffer(totalLength); + outputBuffer[0] = finalFragment ? opcode | 0x80 : opcode; + if (compressed) outputBuffer[0] |= 0x40; + + switch (secondByte) { + case 126: + writeUInt16BE.call(outputBuffer, dataLength, 2); + break; + case 127: + writeUInt32BE.call(outputBuffer, 0, 2); + writeUInt32BE.call(outputBuffer, dataLength, 6); + } + + if (maskData) { + outputBuffer[1] = secondByte | 0x80; + var mask = this._randomMask || (this._randomMask = getRandomMask()); + outputBuffer[dataOffset - 4] = mask[0]; + outputBuffer[dataOffset - 3] = mask[1]; + outputBuffer[dataOffset - 2] = mask[2]; + outputBuffer[dataOffset - 1] = mask[3]; + if (mergeBuffers) { + bufferUtil.mask(data, mask, outputBuffer, dataOffset, dataLength); + try { + this._socket.write(outputBuffer, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + else { + bufferUtil.mask(data, mask, data, 0, dataLength); + try { + this._socket.write(outputBuffer, 'binary'); + this._socket.write(data, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + } + else { + outputBuffer[1] = secondByte; + if (mergeBuffers) { + data.copy(outputBuffer, dataOffset); + try { + this._socket.write(outputBuffer, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + else { + try { + this._socket.write(outputBuffer, 'binary'); + this._socket.write(data, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + } +}; + +/** + * Execute message handler buffers + * + * @api private + */ + +Sender.prototype.flush = function() { + if (this.processing) return; + + var handler = this.messageHandlers.shift(); + if (!handler) return; + + this.processing = true; + + var self = this; + + handler(function() { + self.processing = false; + self.flush(); + }); +}; + +/** + * Apply extensions to message + * + * @api private + */ + +Sender.prototype.applyExtensions = function(data, fin, compress, callback) { + if (compress && data) { + if ((data.buffer || data) instanceof ArrayBuffer) { + data = getArrayBuffer(data); + } + this.extensions[PerMessageDeflate.extensionName].compress(data, fin, callback); + } else { + callback(null, data); + } +}; + +module.exports = Sender; + +function writeUInt16BE(value, offset) { + this[offset] = (value & 0xff00)>>8; + this[offset+1] = value & 0xff; +} + +function writeUInt32BE(value, offset) { + this[offset] = (value & 0xff000000)>>24; + this[offset+1] = (value & 0xff0000)>>16; + this[offset+2] = (value & 0xff00)>>8; + this[offset+3] = value & 0xff; +} + +function getArrayBuffer(data) { + // data is either an ArrayBuffer or ArrayBufferView. + var array = new Uint8Array(data.buffer || data) + , l = data.byteLength || data.length + , o = data.byteOffset || 0 + , buffer = new Buffer(l); + for (var i = 0; i < l; ++i) { + buffer[i] = array[o+i]; + } + return buffer; +} + +function getRandomMask() { + return new Buffer([ + ~~(Math.random() * 255), + ~~(Math.random() * 255), + ~~(Math.random() * 255), + ~~(Math.random() * 255) + ]); +} diff --git a/platforms/android/assets/www/node_modules/ws/lib/Validation.fallback.js b/platforms/android/assets/www/node_modules/ws/lib/Validation.fallback.js new file mode 100644 index 0000000..2c7c4fd --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/Validation.fallback.js @@ -0,0 +1,12 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +module.exports.Validation = { + isValidUTF8: function(buffer) { + return true; + } +}; + diff --git a/platforms/android/assets/www/node_modules/ws/lib/Validation.js b/platforms/android/assets/www/node_modules/ws/lib/Validation.js new file mode 100644 index 0000000..0795fb7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/Validation.js @@ -0,0 +1,13 @@ +'use strict'; + +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +try { + module.exports = require('utf-8-validate'); +} catch (e) { + module.exports = require('./Validation.fallback'); +} diff --git a/platforms/android/assets/www/node_modules/ws/lib/WebSocket.js b/platforms/android/assets/www/node_modules/ws/lib/WebSocket.js new file mode 100644 index 0000000..4e06c80 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/WebSocket.js @@ -0,0 +1,965 @@ +'use strict'; + +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var url = require('url') + , util = require('util') + , http = require('http') + , https = require('https') + , crypto = require('crypto') + , stream = require('stream') + , Ultron = require('ultron') + , Options = require('options') + , Sender = require('./Sender') + , Receiver = require('./Receiver') + , SenderHixie = require('./Sender.hixie') + , ReceiverHixie = require('./Receiver.hixie') + , Extensions = require('./Extensions') + , PerMessageDeflate = require('./PerMessageDeflate') + , EventEmitter = require('events').EventEmitter; + +/** + * Constants + */ + +// Default protocol version + +var protocolVersion = 13; + +// Close timeout + +var closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly + +/** + * WebSocket implementation + * + * @constructor + * @param {String} address Connection address. + * @param {String|Array} protocols WebSocket protocols. + * @param {Object} options Additional connection options. + * @api public + */ +function WebSocket(address, protocols, options) { + if (this instanceof WebSocket === false) { + return new WebSocket(address, protocols, options); + } + + EventEmitter.call(this); + + if (protocols && !Array.isArray(protocols) && 'object' === typeof protocols) { + // accept the "options" Object as the 2nd argument + options = protocols; + protocols = null; + } + + if ('string' === typeof protocols) { + protocols = [ protocols ]; + } + + if (!Array.isArray(protocols)) { + protocols = []; + } + + this._socket = null; + this._ultron = null; + this._closeReceived = false; + this.bytesReceived = 0; + this.readyState = null; + this.supports = {}; + this.extensions = {}; + + if (Array.isArray(address)) { + initAsServerClient.apply(this, address.concat(options)); + } else { + initAsClient.apply(this, [address, protocols, options]); + } +} + +/** + * Inherits from EventEmitter. + */ +util.inherits(WebSocket, EventEmitter); + +/** + * Ready States + */ +["CONNECTING", "OPEN", "CLOSING", "CLOSED"].forEach(function each(state, index) { + WebSocket.prototype[state] = WebSocket[state] = index; +}); + +/** + * Gracefully closes the connection, after sending a description message to the server + * + * @param {Object} data to be sent to the server + * @api public + */ +WebSocket.prototype.close = function close(code, data) { + if (this.readyState === WebSocket.CLOSED) return; + + if (this.readyState === WebSocket.CONNECTING) { + this.readyState = WebSocket.CLOSED; + return; + } + + if (this.readyState === WebSocket.CLOSING) { + if (this._closeReceived && this._isServer) { + this.terminate(); + } + return; + } + + var self = this; + try { + this.readyState = WebSocket.CLOSING; + this._closeCode = code; + this._closeMessage = data; + var mask = !this._isServer; + this._sender.close(code, data, mask, function(err) { + if (err) self.emit('error', err); + + if (self._closeReceived && self._isServer) { + self.terminate(); + } else { + // ensure that the connection is cleaned up even when no response of closing handshake. + clearTimeout(self._closeTimer); + self._closeTimer = setTimeout(cleanupWebsocketResources.bind(self, true), closeTimeout); + } + }); + } catch (e) { + this.emit('error', e); + } +}; + +/** + * Pause the client stream + * + * @api public + */ +WebSocket.prototype.pause = function pauser() { + if (this.readyState !== WebSocket.OPEN) throw new Error('not opened'); + + return this._socket.pause(); +}; + +/** + * Sends a ping + * + * @param {Object} data to be sent to the server + * @param {Object} Members - mask: boolean, binary: boolean + * @param {boolean} dontFailWhenClosed indicates whether or not to throw if the connection isnt open + * @api public + */ +WebSocket.prototype.ping = function ping(data, options, dontFailWhenClosed) { + if (this.readyState !== WebSocket.OPEN) { + if (dontFailWhenClosed === true) return; + throw new Error('not opened'); + } + + options = options || {}; + + if (typeof options.mask === 'undefined') options.mask = !this._isServer; + + this._sender.ping(data, options); +}; + +/** + * Sends a pong + * + * @param {Object} data to be sent to the server + * @param {Object} Members - mask: boolean, binary: boolean + * @param {boolean} dontFailWhenClosed indicates whether or not to throw if the connection isnt open + * @api public + */ +WebSocket.prototype.pong = function(data, options, dontFailWhenClosed) { + if (this.readyState !== WebSocket.OPEN) { + if (dontFailWhenClosed === true) return; + throw new Error('not opened'); + } + + options = options || {}; + + if (typeof options.mask === 'undefined') options.mask = !this._isServer; + + this._sender.pong(data, options); +}; + +/** + * Resume the client stream + * + * @api public + */ +WebSocket.prototype.resume = function resume() { + if (this.readyState !== WebSocket.OPEN) throw new Error('not opened'); + + return this._socket.resume(); +}; + +/** + * Sends a piece of data + * + * @param {Object} data to be sent to the server + * @param {Object} Members - mask: boolean, binary: boolean, compress: boolean + * @param {function} Optional callback which is executed after the send completes + * @api public + */ + +WebSocket.prototype.send = function send(data, options, cb) { + if (typeof options === 'function') { + cb = options; + options = {}; + } + + if (this.readyState !== WebSocket.OPEN) { + if (typeof cb === 'function') cb(new Error('not opened')); + else throw new Error('not opened'); + return; + } + + if (!data) data = ''; + if (this._queue) { + var self = this; + this._queue.push(function() { self.send(data, options, cb); }); + return; + } + + options = options || {}; + options.fin = true; + + if (typeof options.binary === 'undefined') { + options.binary = (data instanceof ArrayBuffer || data instanceof Buffer || + data instanceof Uint8Array || + data instanceof Uint16Array || + data instanceof Uint32Array || + data instanceof Int8Array || + data instanceof Int16Array || + data instanceof Int32Array || + data instanceof Float32Array || + data instanceof Float64Array); + } + + if (typeof options.mask === 'undefined') options.mask = !this._isServer; + if (typeof options.compress === 'undefined') options.compress = true; + if (!this.extensions[PerMessageDeflate.extensionName]) { + options.compress = false; + } + + var readable = typeof stream.Readable === 'function' + ? stream.Readable + : stream.Stream; + + if (data instanceof readable) { + startQueue(this); + var self = this; + + sendStream(this, data, options, function send(error) { + process.nextTick(function tock() { + executeQueueSends(self); + }); + + if (typeof cb === 'function') cb(error); + }); + } else { + this._sender.send(data, options, cb); + } +}; + +/** + * Streams data through calls to a user supplied function + * + * @param {Object} Members - mask: boolean, binary: boolean, compress: boolean + * @param {function} 'function (error, send)' which is executed on successive ticks of which send is 'function (data, final)'. + * @api public + */ +WebSocket.prototype.stream = function stream(options, cb) { + if (typeof options === 'function') { + cb = options; + options = {}; + } + + var self = this; + + if (typeof cb !== 'function') throw new Error('callback must be provided'); + + if (this.readyState !== WebSocket.OPEN) { + if (typeof cb === 'function') cb(new Error('not opened')); + else throw new Error('not opened'); + return; + } + + if (this._queue) { + this._queue.push(function () { self.stream(options, cb); }); + return; + } + + options = options || {}; + + if (typeof options.mask === 'undefined') options.mask = !this._isServer; + if (typeof options.compress === 'undefined') options.compress = true; + if (!this.extensions[PerMessageDeflate.extensionName]) { + options.compress = false; + } + + startQueue(this); + + function send(data, final) { + try { + if (self.readyState !== WebSocket.OPEN) throw new Error('not opened'); + options.fin = final === true; + self._sender.send(data, options); + if (!final) process.nextTick(cb.bind(null, null, send)); + else executeQueueSends(self); + } catch (e) { + if (typeof cb === 'function') cb(e); + else { + delete self._queue; + self.emit('error', e); + } + } + } + + process.nextTick(cb.bind(null, null, send)); +}; + +/** + * Immediately shuts down the connection + * + * @api public + */ +WebSocket.prototype.terminate = function terminate() { + if (this.readyState === WebSocket.CLOSED) return; + + if (this._socket) { + this.readyState = WebSocket.CLOSING; + + // End the connection + try { this._socket.end(); } + catch (e) { + // Socket error during end() call, so just destroy it right now + cleanupWebsocketResources.call(this, true); + return; + } + + // Add a timeout to ensure that the connection is completely + // cleaned up within 30 seconds, even if the clean close procedure + // fails for whatever reason + // First cleanup any pre-existing timeout from an earlier "terminate" call, + // if one exists. Otherwise terminate calls in quick succession will leak timeouts + // and hold the program open for `closeTimout` time. + if (this._closeTimer) { clearTimeout(this._closeTimer); } + this._closeTimer = setTimeout(cleanupWebsocketResources.bind(this, true), closeTimeout); + } else if (this.readyState === WebSocket.CONNECTING) { + cleanupWebsocketResources.call(this, true); + } +}; + +/** + * Expose bufferedAmount + * + * @api public + */ +Object.defineProperty(WebSocket.prototype, 'bufferedAmount', { + get: function get() { + var amount = 0; + if (this._socket) { + amount = this._socket.bufferSize || 0; + } + return amount; + } +}); + +/** + * Emulates the W3C Browser based WebSocket interface using function members. + * + * @see http://dev.w3.org/html5/websockets/#the-websocket-interface + * @api public + */ +['open', 'error', 'close', 'message'].forEach(function(method) { + Object.defineProperty(WebSocket.prototype, 'on' + method, { + /** + * Returns the current listener + * + * @returns {Mixed} the set function or undefined + * @api public + */ + get: function get() { + var listener = this.listeners(method)[0]; + return listener ? (listener._listener ? listener._listener : listener) : undefined; + }, + + /** + * Start listening for events + * + * @param {Function} listener the listener + * @returns {Mixed} the set function or undefined + * @api public + */ + set: function set(listener) { + this.removeAllListeners(method); + this.addEventListener(method, listener); + } + }); +}); + +/** + * Emulates the W3C Browser based WebSocket interface using addEventListener. + * + * @see https://developer.mozilla.org/en/DOM/element.addEventListener + * @see http://dev.w3.org/html5/websockets/#the-websocket-interface + * @api public + */ +WebSocket.prototype.addEventListener = function(method, listener) { + var target = this; + + function onMessage (data, flags) { + listener.call(target, new MessageEvent(data, !!flags.binary, target)); + } + + function onClose (code, message) { + listener.call(target, new CloseEvent(code, message, target)); + } + + function onError (event) { + event.type = 'error'; + event.target = target; + listener.call(target, event); + } + + function onOpen () { + listener.call(target, new OpenEvent(target)); + } + + if (typeof listener === 'function') { + if (method === 'message') { + // store a reference so we can return the original function from the + // addEventListener hook + onMessage._listener = listener; + this.on(method, onMessage); + } else if (method === 'close') { + // store a reference so we can return the original function from the + // addEventListener hook + onClose._listener = listener; + this.on(method, onClose); + } else if (method === 'error') { + // store a reference so we can return the original function from the + // addEventListener hook + onError._listener = listener; + this.on(method, onError); + } else if (method === 'open') { + // store a reference so we can return the original function from the + // addEventListener hook + onOpen._listener = listener; + this.on(method, onOpen); + } else { + this.on(method, listener); + } + } +}; + +module.exports = WebSocket; +module.exports.buildHostHeader = buildHostHeader + +/** + * W3C MessageEvent + * + * @see http://www.w3.org/TR/html5/comms.html + * @constructor + * @api private + */ +function MessageEvent(dataArg, isBinary, target) { + this.type = 'message'; + this.data = dataArg; + this.target = target; + this.binary = isBinary; // non-standard. +} + +/** + * W3C CloseEvent + * + * @see http://www.w3.org/TR/html5/comms.html + * @constructor + * @api private + */ +function CloseEvent(code, reason, target) { + this.type = 'close'; + this.wasClean = (typeof code === 'undefined' || code === 1000); + this.code = code; + this.reason = reason; + this.target = target; +} + +/** + * W3C OpenEvent + * + * @see http://www.w3.org/TR/html5/comms.html + * @constructor + * @api private + */ +function OpenEvent(target) { + this.type = 'open'; + this.target = target; +} + +// Append port number to Host header, only if specified in the url +// and non-default +function buildHostHeader(isSecure, hostname, port) { + var headerHost = hostname; + if (hostname) { + if ((isSecure && (port != 443)) || (!isSecure && (port != 80))){ + headerHost = headerHost + ':' + port; + } + } + return headerHost; +} + +/** + * Entirely private apis, + * which may or may not be bound to a sepcific WebSocket instance. + */ +function initAsServerClient(req, socket, upgradeHead, options) { + options = new Options({ + protocolVersion: protocolVersion, + protocol: null, + extensions: {} + }).merge(options); + + // expose state properties + this.protocol = options.value.protocol; + this.protocolVersion = options.value.protocolVersion; + this.extensions = options.value.extensions; + this.supports.binary = (this.protocolVersion !== 'hixie-76'); + this.upgradeReq = req; + this.readyState = WebSocket.CONNECTING; + this._isServer = true; + + // establish connection + if (options.value.protocolVersion === 'hixie-76') { + establishConnection.call(this, ReceiverHixie, SenderHixie, socket, upgradeHead); + } else { + establishConnection.call(this, Receiver, Sender, socket, upgradeHead); + } +} + +function initAsClient(address, protocols, options) { + options = new Options({ + origin: null, + protocolVersion: protocolVersion, + host: null, + headers: null, + protocol: protocols.join(','), + agent: null, + + // ssl-related options + pfx: null, + key: null, + passphrase: null, + cert: null, + ca: null, + ciphers: null, + rejectUnauthorized: null, + perMessageDeflate: true, + localAddress: null + }).merge(options); + + if (options.value.protocolVersion !== 8 && options.value.protocolVersion !== 13) { + throw new Error('unsupported protocol version'); + } + + // verify URL and establish http class + var serverUrl = url.parse(address); + var isUnixSocket = serverUrl.protocol === 'ws+unix:'; + if (!serverUrl.host && !isUnixSocket) throw new Error('invalid url'); + var isSecure = serverUrl.protocol === 'wss:' || serverUrl.protocol === 'https:'; + var httpObj = isSecure ? https : http; + var port = serverUrl.port || (isSecure ? 443 : 80); + var auth = serverUrl.auth; + + // prepare extensions + var extensionsOffer = {}; + var perMessageDeflate; + if (options.value.perMessageDeflate) { + perMessageDeflate = new PerMessageDeflate(typeof options.value.perMessageDeflate !== true ? options.value.perMessageDeflate : {}, false); + extensionsOffer[PerMessageDeflate.extensionName] = perMessageDeflate.offer(); + } + + // expose state properties + this._isServer = false; + this.url = address; + this.protocolVersion = options.value.protocolVersion; + this.supports.binary = (this.protocolVersion !== 'hixie-76'); + + // begin handshake + var key = new Buffer(options.value.protocolVersion + '-' + Date.now()).toString('base64'); + var shasum = crypto.createHash('sha1'); + shasum.update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'); + var expectedServerKey = shasum.digest('base64'); + + var agent = options.value.agent; + + var headerHost = buildHostHeader(isSecure, serverUrl.hostname, port) + + var requestOptions = { + port: port, + host: serverUrl.hostname, + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Host': headerHost, + 'Sec-WebSocket-Version': options.value.protocolVersion, + 'Sec-WebSocket-Key': key + } + }; + + // If we have basic auth. + if (auth) { + requestOptions.headers.Authorization = 'Basic ' + new Buffer(auth).toString('base64'); + } + + if (options.value.protocol) { + requestOptions.headers['Sec-WebSocket-Protocol'] = options.value.protocol; + } + + if (options.value.host) { + requestOptions.headers.Host = options.value.host; + } + + if (options.value.headers) { + for (var header in options.value.headers) { + if (options.value.headers.hasOwnProperty(header)) { + requestOptions.headers[header] = options.value.headers[header]; + } + } + } + + if (Object.keys(extensionsOffer).length) { + requestOptions.headers['Sec-WebSocket-Extensions'] = Extensions.format(extensionsOffer); + } + + if (options.isDefinedAndNonNull('pfx') + || options.isDefinedAndNonNull('key') + || options.isDefinedAndNonNull('passphrase') + || options.isDefinedAndNonNull('cert') + || options.isDefinedAndNonNull('ca') + || options.isDefinedAndNonNull('ciphers') + || options.isDefinedAndNonNull('rejectUnauthorized')) { + + if (options.isDefinedAndNonNull('pfx')) requestOptions.pfx = options.value.pfx; + if (options.isDefinedAndNonNull('key')) requestOptions.key = options.value.key; + if (options.isDefinedAndNonNull('passphrase')) requestOptions.passphrase = options.value.passphrase; + if (options.isDefinedAndNonNull('cert')) requestOptions.cert = options.value.cert; + if (options.isDefinedAndNonNull('ca')) requestOptions.ca = options.value.ca; + if (options.isDefinedAndNonNull('ciphers')) requestOptions.ciphers = options.value.ciphers; + if (options.isDefinedAndNonNull('rejectUnauthorized')) requestOptions.rejectUnauthorized = options.value.rejectUnauthorized; + + if (!agent) { + // global agent ignores client side certificates + agent = new httpObj.Agent(requestOptions); + } + } + + requestOptions.path = serverUrl.path || '/'; + + if (agent) { + requestOptions.agent = agent; + } + + if (isUnixSocket) { + requestOptions.socketPath = serverUrl.pathname; + } + + if (options.value.localAddress) { + requestOptions.localAddress = options.value.localAddress; + } + + if (options.value.origin) { + if (options.value.protocolVersion < 13) requestOptions.headers['Sec-WebSocket-Origin'] = options.value.origin; + else requestOptions.headers.Origin = options.value.origin; + } + + var self = this; + var req = httpObj.request(requestOptions); + + req.on('error', function onerror(error) { + self.emit('error', error); + cleanupWebsocketResources.call(self, error); + }); + + req.once('response', function response(res) { + var error; + + if (!self.emit('unexpected-response', req, res)) { + error = new Error('unexpected server response (' + res.statusCode + ')'); + req.abort(); + self.emit('error', error); + } + + cleanupWebsocketResources.call(self, error); + }); + + req.once('upgrade', function upgrade(res, socket, upgradeHead) { + if (self.readyState === WebSocket.CLOSED) { + // client closed before server accepted connection + self.emit('close'); + self.removeAllListeners(); + socket.end(); + return; + } + + var serverKey = res.headers['sec-websocket-accept']; + if (typeof serverKey === 'undefined' || serverKey !== expectedServerKey) { + self.emit('error', 'invalid server key'); + self.removeAllListeners(); + socket.end(); + return; + } + + var serverProt = res.headers['sec-websocket-protocol']; + var protList = (options.value.protocol || "").split(/, */); + var protError = null; + + if (!options.value.protocol && serverProt) { + protError = 'server sent a subprotocol even though none requested'; + } else if (options.value.protocol && !serverProt) { + protError = 'server sent no subprotocol even though requested'; + } else if (serverProt && protList.indexOf(serverProt) === -1) { + protError = 'server responded with an invalid protocol'; + } + + if (protError) { + self.emit('error', protError); + self.removeAllListeners(); + socket.end(); + return; + } else if (serverProt) { + self.protocol = serverProt; + } + + var serverExtensions = Extensions.parse(res.headers['sec-websocket-extensions']); + if (perMessageDeflate && serverExtensions[PerMessageDeflate.extensionName]) { + try { + perMessageDeflate.accept(serverExtensions[PerMessageDeflate.extensionName]); + } catch (err) { + self.emit('error', 'invalid extension parameter'); + self.removeAllListeners(); + socket.end(); + return; + } + self.extensions[PerMessageDeflate.extensionName] = perMessageDeflate; + } + + establishConnection.call(self, Receiver, Sender, socket, upgradeHead); + + // perform cleanup on http resources + req.removeAllListeners(); + req = null; + agent = null; + }); + + req.end(); + this.readyState = WebSocket.CONNECTING; +} + +function establishConnection(ReceiverClass, SenderClass, socket, upgradeHead) { + var ultron = this._ultron = new Ultron(socket) + , called = false + , self = this; + + socket.setTimeout(0); + socket.setNoDelay(true); + + this._receiver = new ReceiverClass(this.extensions); + this._socket = socket; + + // socket cleanup handlers + ultron.on('end', cleanupWebsocketResources.bind(this)); + ultron.on('close', cleanupWebsocketResources.bind(this)); + ultron.on('error', cleanupWebsocketResources.bind(this)); + + // ensure that the upgradeHead is added to the receiver + function firstHandler(data) { + if (called || self.readyState === WebSocket.CLOSED) return; + + called = true; + socket.removeListener('data', firstHandler); + ultron.on('data', realHandler); + + if (upgradeHead && upgradeHead.length > 0) { + realHandler(upgradeHead); + upgradeHead = null; + } + + if (data) realHandler(data); + } + + // subsequent packets are pushed straight to the receiver + function realHandler(data) { + self.bytesReceived += data.length; + self._receiver.add(data); + } + + ultron.on('data', firstHandler); + + // if data was passed along with the http upgrade, + // this will schedule a push of that on to the receiver. + // this has to be done on next tick, since the caller + // hasn't had a chance to set event handlers on this client + // object yet. + process.nextTick(firstHandler); + + // receiver event handlers + self._receiver.ontext = function ontext(data, flags) { + flags = flags || {}; + + self.emit('message', data, flags); + }; + + self._receiver.onbinary = function onbinary(data, flags) { + flags = flags || {}; + + flags.binary = true; + self.emit('message', data, flags); + }; + + self._receiver.onping = function onping(data, flags) { + flags = flags || {}; + + self.pong(data, { + mask: !self._isServer, + binary: flags.binary === true + }, true); + + self.emit('ping', data, flags); + }; + + self._receiver.onpong = function onpong(data, flags) { + self.emit('pong', data, flags || {}); + }; + + self._receiver.onclose = function onclose(code, data, flags) { + flags = flags || {}; + + self._closeReceived = true; + self.close(code, data); + }; + + self._receiver.onerror = function onerror(reason, errorCode) { + // close the connection when the receiver reports a HyBi error code + self.close(typeof errorCode !== 'undefined' ? errorCode : 1002, ''); + self.emit('error', reason, errorCode); + }; + + // finalize the client + this._sender = new SenderClass(socket, this.extensions); + this._sender.on('error', function onerror(error) { + self.close(1002, ''); + self.emit('error', error); + }); + + this.readyState = WebSocket.OPEN; + this.emit('open'); +} + +function startQueue(instance) { + instance._queue = instance._queue || []; +} + +function executeQueueSends(instance) { + var queue = instance._queue; + if (typeof queue === 'undefined') return; + + delete instance._queue; + for (var i = 0, l = queue.length; i < l; ++i) { + queue[i](); + } +} + +function sendStream(instance, stream, options, cb) { + stream.on('data', function incoming(data) { + if (instance.readyState !== WebSocket.OPEN) { + if (typeof cb === 'function') cb(new Error('not opened')); + else { + delete instance._queue; + instance.emit('error', new Error('not opened')); + } + return; + } + + options.fin = false; + instance._sender.send(data, options); + }); + + stream.on('end', function end() { + if (instance.readyState !== WebSocket.OPEN) { + if (typeof cb === 'function') cb(new Error('not opened')); + else { + delete instance._queue; + instance.emit('error', new Error('not opened')); + } + return; + } + + options.fin = true; + instance._sender.send(null, options); + + if (typeof cb === 'function') cb(null); + }); +} + +function cleanupWebsocketResources(error) { + if (this.readyState === WebSocket.CLOSED) return; + + var emitClose = this.readyState !== WebSocket.CONNECTING; + this.readyState = WebSocket.CLOSED; + + clearTimeout(this._closeTimer); + this._closeTimer = null; + + if (emitClose) { + // If the connection was closed abnormally (with an error), or if + // the close control frame was not received then the close code + // must default to 1006. + if (error || !this._closeReceived) { + this._closeCode = 1006; + } + this.emit('close', this._closeCode || 1000, this._closeMessage || ''); + } + + if (this._socket) { + if (this._ultron) this._ultron.destroy(); + this._socket.on('error', function onerror() { + try { this.destroy(); } + catch (e) {} + }); + + try { + if (!error) this._socket.end(); + else this._socket.destroy(); + } catch (e) { /* Ignore termination errors */ } + + this._socket = null; + this._ultron = null; + } + + if (this._sender) { + this._sender.removeAllListeners(); + this._sender = null; + } + + if (this._receiver) { + this._receiver.cleanup(); + this._receiver = null; + } + + if (this.extensions[PerMessageDeflate.extensionName]) { + this.extensions[PerMessageDeflate.extensionName].cleanup(); + } + + this.extensions = null; + + this.removeAllListeners(); + this.on('error', function onerror() {}); // catch all errors after this + delete this._queue; +} diff --git a/platforms/android/assets/www/node_modules/ws/lib/WebSocketServer.js b/platforms/android/assets/www/node_modules/ws/lib/WebSocketServer.js new file mode 100644 index 0000000..ba0e4c0 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/lib/WebSocketServer.js @@ -0,0 +1,513 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util') + , events = require('events') + , http = require('http') + , crypto = require('crypto') + , Options = require('options') + , WebSocket = require('./WebSocket') + , Extensions = require('./Extensions') + , PerMessageDeflate = require('./PerMessageDeflate') + , tls = require('tls') + , url = require('url'); + +/** + * WebSocket Server implementation + */ + +function WebSocketServer(options, callback) { + if (this instanceof WebSocketServer === false) { + return new WebSocketServer(options, callback); + } + + events.EventEmitter.call(this); + + options = new Options({ + host: '0.0.0.0', + port: null, + server: null, + verifyClient: null, + handleProtocols: null, + path: null, + noServer: false, + disableHixie: false, + clientTracking: true, + perMessageDeflate: true + }).merge(options); + + if (!options.isDefinedAndNonNull('port') && !options.isDefinedAndNonNull('server') && !options.value.noServer) { + throw new TypeError('`port` or a `server` must be provided'); + } + + var self = this; + + if (options.isDefinedAndNonNull('port')) { + this._server = http.createServer(function (req, res) { + var body = http.STATUS_CODES[426]; + res.writeHead(426, { + 'Content-Length': body.length, + 'Content-Type': 'text/plain' + }); + res.end(body); + }); + this._server.allowHalfOpen = false; + this._server.listen(options.value.port, options.value.host, callback); + this._closeServer = function() { if (self._server) self._server.close(); }; + } + else if (options.value.server) { + this._server = options.value.server; + if (options.value.path) { + // take note of the path, to avoid collisions when multiple websocket servers are + // listening on the same http server + if (this._server._webSocketPaths && options.value.server._webSocketPaths[options.value.path]) { + throw new Error('two instances of WebSocketServer cannot listen on the same http server path'); + } + if (typeof this._server._webSocketPaths !== 'object') { + this._server._webSocketPaths = {}; + } + this._server._webSocketPaths[options.value.path] = 1; + } + } + if (this._server) this._server.once('listening', function() { self.emit('listening'); }); + + if (typeof this._server != 'undefined') { + this._server.on('error', function(error) { + self.emit('error', error) + }); + this._server.on('upgrade', function(req, socket, upgradeHead) { + //copy upgradeHead to avoid retention of large slab buffers used in node core + var head = new Buffer(upgradeHead.length); + upgradeHead.copy(head); + + self.handleUpgrade(req, socket, head, function(client) { + self.emit('connection'+req.url, client); + self.emit('connection', client); + }); + }); + } + + this.options = options.value; + this.path = options.value.path; + this.clients = []; +} + +/** + * Inherits from EventEmitter. + */ + +util.inherits(WebSocketServer, events.EventEmitter); + +/** + * Immediately shuts down the connection. + * + * @api public + */ + +WebSocketServer.prototype.close = function(callback) { + // terminate all associated clients + var error = null; + try { + for (var i = 0, l = this.clients.length; i < l; ++i) { + this.clients[i].terminate(); + } + } + catch (e) { + error = e; + } + + // remove path descriptor, if any + if (this.path && this._server._webSocketPaths) { + delete this._server._webSocketPaths[this.path]; + if (Object.keys(this._server._webSocketPaths).length == 0) { + delete this._server._webSocketPaths; + } + } + + // close the http server if it was internally created + try { + if (typeof this._closeServer !== 'undefined') { + this._closeServer(); + } + } + finally { + delete this._server; + } + if(callback) + callback(error); + else if(error) + throw error; +} + +/** + * Handle a HTTP Upgrade request. + * + * @api public + */ + +WebSocketServer.prototype.handleUpgrade = function(req, socket, upgradeHead, cb) { + // check for wrong path + if (this.options.path) { + var u = url.parse(req.url); + if (u && u.pathname !== this.options.path) return; + } + + if (typeof req.headers.upgrade === 'undefined' || req.headers.upgrade.toLowerCase() !== 'websocket') { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + if (req.headers['sec-websocket-key1']) handleHixieUpgrade.apply(this, arguments); + else handleHybiUpgrade.apply(this, arguments); +} + +module.exports = WebSocketServer; + +/** + * Entirely private apis, + * which may or may not be bound to a sepcific WebSocket instance. + */ + +function handleHybiUpgrade(req, socket, upgradeHead, cb) { + // handle premature socket errors + var errorHandler = function() { + try { socket.destroy(); } catch (e) {} + } + socket.on('error', errorHandler); + + // verify key presence + if (!req.headers['sec-websocket-key']) { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + // verify version + var version = parseInt(req.headers['sec-websocket-version']); + if ([8, 13].indexOf(version) === -1) { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + // verify protocol + var protocols = req.headers['sec-websocket-protocol']; + + // verify client + var origin = version < 13 ? + req.headers['sec-websocket-origin'] : + req.headers['origin']; + + // handle extensions offer + var extensionsOffer = Extensions.parse(req.headers['sec-websocket-extensions']); + + // handler to call when the connection sequence completes + var self = this; + var completeHybiUpgrade2 = function(protocol) { + + // calc key + var key = req.headers['sec-websocket-key']; + var shasum = crypto.createHash('sha1'); + shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); + key = shasum.digest('base64'); + + var headers = [ + 'HTTP/1.1 101 Switching Protocols' + , 'Upgrade: websocket' + , 'Connection: Upgrade' + , 'Sec-WebSocket-Accept: ' + key + ]; + + if (typeof protocol != 'undefined') { + headers.push('Sec-WebSocket-Protocol: ' + protocol); + } + + var extensions = {}; + try { + extensions = acceptExtensions.call(self, extensionsOffer); + } catch (err) { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + if (Object.keys(extensions).length) { + var serverExtensions = {}; + Object.keys(extensions).forEach(function(token) { + serverExtensions[token] = [extensions[token].params] + }); + headers.push('Sec-WebSocket-Extensions: ' + Extensions.format(serverExtensions)); + } + + // allows external modification/inspection of handshake headers + self.emit('headers', headers); + + socket.setTimeout(0); + socket.setNoDelay(true); + try { + socket.write(headers.concat('', '').join('\r\n')); + } + catch (e) { + // if the upgrade write fails, shut the connection down hard + try { socket.destroy(); } catch (e) {} + return; + } + + var client = new WebSocket([req, socket, upgradeHead], { + protocolVersion: version, + protocol: protocol, + extensions: extensions + }); + + if (self.options.clientTracking) { + self.clients.push(client); + client.on('close', function() { + var index = self.clients.indexOf(client); + if (index != -1) { + self.clients.splice(index, 1); + } + }); + } + + // signal upgrade complete + socket.removeListener('error', errorHandler); + cb(client); + } + + // optionally call external protocol selection handler before + // calling completeHybiUpgrade2 + var completeHybiUpgrade1 = function() { + // choose from the sub-protocols + if (typeof self.options.handleProtocols == 'function') { + var protList = (protocols || "").split(/, */); + var callbackCalled = false; + var res = self.options.handleProtocols(protList, function(result, protocol) { + callbackCalled = true; + if (!result) abortConnection(socket, 401, 'Unauthorized'); + else completeHybiUpgrade2(protocol); + }); + if (!callbackCalled) { + // the handleProtocols handler never called our callback + abortConnection(socket, 501, 'Could not process protocols'); + } + return; + } else { + if (typeof protocols !== 'undefined') { + completeHybiUpgrade2(protocols.split(/, */)[0]); + } + else { + completeHybiUpgrade2(); + } + } + } + + // optionally call external client verification handler + if (typeof this.options.verifyClient == 'function') { + var info = { + origin: origin, + secure: typeof req.connection.authorized !== 'undefined' || typeof req.connection.encrypted !== 'undefined', + req: req + }; + if (this.options.verifyClient.length == 2) { + this.options.verifyClient(info, function(result, code, name) { + if (typeof code === 'undefined') code = 401; + if (typeof name === 'undefined') name = http.STATUS_CODES[code]; + + if (!result) abortConnection(socket, code, name); + else completeHybiUpgrade1(); + }); + return; + } + else if (!this.options.verifyClient(info)) { + abortConnection(socket, 401, 'Unauthorized'); + return; + } + } + + completeHybiUpgrade1(); +} + +function handleHixieUpgrade(req, socket, upgradeHead, cb) { + // handle premature socket errors + var errorHandler = function() { + try { socket.destroy(); } catch (e) {} + } + socket.on('error', errorHandler); + + // bail if options prevent hixie + if (this.options.disableHixie) { + abortConnection(socket, 401, 'Hixie support disabled'); + return; + } + + // verify key presence + if (!req.headers['sec-websocket-key2']) { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + var origin = req.headers['origin'] + , self = this; + + // setup handshake completion to run after client has been verified + var onClientVerified = function() { + var wshost; + if (!req.headers['x-forwarded-host']) + wshost = req.headers.host; + else + wshost = req.headers['x-forwarded-host']; + var location = ((req.headers['x-forwarded-proto'] === 'https' || socket.encrypted) ? 'wss' : 'ws') + '://' + wshost + req.url + , protocol = req.headers['sec-websocket-protocol']; + + // handshake completion code to run once nonce has been successfully retrieved + var completeHandshake = function(nonce, rest) { + // calculate key + var k1 = req.headers['sec-websocket-key1'] + , k2 = req.headers['sec-websocket-key2'] + , md5 = crypto.createHash('md5'); + + [k1, k2].forEach(function (k) { + var n = parseInt(k.replace(/[^\d]/g, '')) + , spaces = k.replace(/[^ ]/g, '').length; + if (spaces === 0 || n % spaces !== 0){ + abortConnection(socket, 400, 'Bad Request'); + return; + } + n /= spaces; + md5.update(String.fromCharCode( + n >> 24 & 0xFF, + n >> 16 & 0xFF, + n >> 8 & 0xFF, + n & 0xFF)); + }); + md5.update(nonce.toString('binary')); + + var headers = [ + 'HTTP/1.1 101 Switching Protocols' + , 'Upgrade: WebSocket' + , 'Connection: Upgrade' + , 'Sec-WebSocket-Location: ' + location + ]; + if (typeof protocol != 'undefined') headers.push('Sec-WebSocket-Protocol: ' + protocol); + if (typeof origin != 'undefined') headers.push('Sec-WebSocket-Origin: ' + origin); + + socket.setTimeout(0); + socket.setNoDelay(true); + try { + // merge header and hash buffer + var headerBuffer = new Buffer(headers.concat('', '').join('\r\n')); + var hashBuffer = new Buffer(md5.digest('binary'), 'binary'); + var handshakeBuffer = new Buffer(headerBuffer.length + hashBuffer.length); + headerBuffer.copy(handshakeBuffer, 0); + hashBuffer.copy(handshakeBuffer, headerBuffer.length); + + // do a single write, which - upon success - causes a new client websocket to be setup + socket.write(handshakeBuffer, 'binary', function(err) { + if (err) return; // do not create client if an error happens + var client = new WebSocket([req, socket, rest], { + protocolVersion: 'hixie-76', + protocol: protocol + }); + if (self.options.clientTracking) { + self.clients.push(client); + client.on('close', function() { + var index = self.clients.indexOf(client); + if (index != -1) { + self.clients.splice(index, 1); + } + }); + } + + // signal upgrade complete + socket.removeListener('error', errorHandler); + cb(client); + }); + } + catch (e) { + try { socket.destroy(); } catch (e) {} + return; + } + } + + // retrieve nonce + var nonceLength = 8; + if (upgradeHead && upgradeHead.length >= nonceLength) { + var nonce = upgradeHead.slice(0, nonceLength); + var rest = upgradeHead.length > nonceLength ? upgradeHead.slice(nonceLength) : null; + completeHandshake.call(self, nonce, rest); + } + else { + // nonce not present in upgradeHead, so we must wait for enough data + // data to arrive before continuing + var nonce = new Buffer(nonceLength); + upgradeHead.copy(nonce, 0); + var received = upgradeHead.length; + var rest = null; + var handler = function (data) { + var toRead = Math.min(data.length, nonceLength - received); + if (toRead === 0) return; + data.copy(nonce, received, 0, toRead); + received += toRead; + if (received == nonceLength) { + socket.removeListener('data', handler); + if (toRead < data.length) rest = data.slice(toRead); + completeHandshake.call(self, nonce, rest); + } + } + socket.on('data', handler); + } + } + + // verify client + if (typeof this.options.verifyClient == 'function') { + var info = { + origin: origin, + secure: typeof req.connection.authorized !== 'undefined' || typeof req.connection.encrypted !== 'undefined', + req: req + }; + if (this.options.verifyClient.length == 2) { + var self = this; + this.options.verifyClient(info, function(result, code, name) { + if (typeof code === 'undefined') code = 401; + if (typeof name === 'undefined') name = http.STATUS_CODES[code]; + + if (!result) abortConnection(socket, code, name); + else onClientVerified.apply(self); + }); + return; + } + else if (!this.options.verifyClient(info)) { + abortConnection(socket, 401, 'Unauthorized'); + return; + } + } + + // no client verification required + onClientVerified(); +} + +function acceptExtensions(offer) { + var extensions = {}; + var options = this.options.perMessageDeflate; + if (options && offer[PerMessageDeflate.extensionName]) { + var perMessageDeflate = new PerMessageDeflate(options !== true ? options : {}, true); + perMessageDeflate.accept(offer[PerMessageDeflate.extensionName]); + extensions[PerMessageDeflate.extensionName] = perMessageDeflate; + } + return extensions; +} + +function abortConnection(socket, code, name) { + try { + var response = [ + 'HTTP/1.1 ' + code + ' ' + name, + 'Content-type: text/html' + ]; + socket.write(response.concat('', '').join('\r\n')); + } + catch (e) { /* ignore errors - we've aborted this connection */ } + finally { + // ensure that an early aborted connection is shut down completely + try { socket.destroy(); } catch (e) {} + } +} diff --git a/platforms/android/assets/www/node_modules/ws/package.json b/platforms/android/assets/www/node_modules/ws/package.json new file mode 100644 index 0000000..b597874 --- /dev/null +++ b/platforms/android/assets/www/node_modules/ws/package.json @@ -0,0 +1,102 @@ +{ + "_args": [ + [ + "ws@^1.0.1", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver" + ] + ], + "_from": "ws@>=1.0.1 <2.0.0", + "_id": "ws@1.0.1", + "_inCache": true, + "_installable": true, + "_location": "/ws", + "_nodeVersion": "4.2.3", + "_npmUser": { + "email": "npm@3rd-Eden.com", + "name": "3rdeden" + }, + "_npmVersion": "3.5.1", + "_phantomChildren": {}, + "_requested": { + "name": "ws", + "raw": "ws@^1.0.1", + "rawSpec": "^1.0.1", + "scope": null, + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/selenium-webdriver" + ], + "_resolved": "https://registry.npmjs.org/ws/-/ws-1.0.1.tgz", + "_shasum": "7d0b2a2e58cddd819039c29c9de65045e1b310e9", + "_shrinkwrap": null, + "_spec": "ws@^1.0.1", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver", + "author": { + "email": "einaros@gmail.com", + "name": "Einar Otto Stangvik", + "url": "http://2x.io" + }, + "bugs": { + "url": "https://github.com/websockets/ws/issues" + }, + "dependencies": { + "options": ">=0.0.5", + "ultron": "1.0.x" + }, + "description": "simple to use, blazing fast and thoroughly tested websocket client, server and console for node.js, up-to-date against RFC-6455", + "devDependencies": { + "ansi": "0.3.x", + "benchmark": "0.3.x", + "bufferutil": "1.2.x", + "expect.js": "0.3.x", + "mocha": "2.3.x", + "should": "8.0.x", + "tinycolor": "0.0.x", + "utf-8-validate": "1.2.x" + }, + "directories": {}, + "dist": { + "shasum": "7d0b2a2e58cddd819039c29c9de65045e1b310e9", + "tarball": "http://registry.npmjs.org/ws/-/ws-1.0.1.tgz" + }, + "gitHead": "40a9d686288b5d0be13f2bf2f3f5da07afc8cda2", + "gypfile": true, + "homepage": "https://github.com/websockets/ws#readme", + "keywords": [ + "Hixie", + "HyBi", + "Push", + "RFC-6455", + "WebSocket", + "WebSockets", + "real-time" + ], + "license": "MIT", + "maintainers": [ + { + "email": "einaros@gmail.com", + "name": "einaros" + }, + { + "email": "info@3rd-Eden.com", + "name": "v1" + }, + { + "email": "npm@3rd-Eden.com", + "name": "3rdeden" + } + ], + "name": "ws", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/websockets/ws.git" + }, + "scripts": { + "test": "make test" + }, + "version": "1.0.1" +} diff --git a/platforms/android/assets/www/node_modules/xml2js/.npmignore b/platforms/android/assets/www/node_modules/xml2js/.npmignore new file mode 100644 index 0000000..ef7b9b9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/.npmignore @@ -0,0 +1,6 @@ +*.swp +.idea +node_modules +src +test +Cakefile \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/xml2js/.travis.yml b/platforms/android/assets/www/node_modules/xml2js/.travis.yml new file mode 100644 index 0000000..755a6b7 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/.travis.yml @@ -0,0 +1,5 @@ +language: node_js + +node_js: + - "0.8" + - "0.10" diff --git a/platforms/android/assets/www/node_modules/xml2js/83.coffee b/platforms/android/assets/www/node_modules/xml2js/83.coffee new file mode 100644 index 0000000..3443540 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/83.coffee @@ -0,0 +1,6 @@ +xml2js = require 'xml2js' +util = require 'util' + +body = 'Character data here!' +xml2js.parseString body, (err, result) -> + console.log util.inspect result, false, null diff --git a/platforms/android/assets/www/node_modules/xml2js/CONTRIBUTING.md b/platforms/android/assets/www/node_modules/xml2js/CONTRIBUTING.md new file mode 100644 index 0000000..2209adf --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/CONTRIBUTING.md @@ -0,0 +1,19 @@ +# How to contribute + +We're always happy about useful new pull requests. Keep in mind that the better +your pull request is, the easier it can be added to `xml2js`. As such please +make sure your patch is ok: + + * `xml2js` is written in CoffeeScript. Please don't send patches to + the JavaScript source, as it get's overwritten by the CoffeeScript + compiler. The reason we have the JS code in the repository is for easier + use with eg. `git submodule` + * Make sure that the unit tests still all pass. Failing unit tests mean that + someone *will* run into a bug, if we accept your pull request. + * Please, add a unit test with your pull request, to show what was broken and + is now fixed or what was impossible and now works due to your new code. + * If you add a new feature, please add some documentation that it exists. + +If you like, you can add yourself in the `package.json` as contributor if you +deem your contribution significant enough. Otherwise, we will decide and maybe +add you. diff --git a/platforms/android/assets/www/node_modules/xml2js/LICENSE b/platforms/android/assets/www/node_modules/xml2js/LICENSE new file mode 100644 index 0000000..e3b4222 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/LICENSE @@ -0,0 +1,19 @@ +Copyright 2010, 2011, 2012, 2013. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/xml2js/README.md b/platforms/android/assets/www/node_modules/xml2js/README.md new file mode 100644 index 0000000..4e01478 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/README.md @@ -0,0 +1,343 @@ +node-xml2js +=========== + +Ever had the urge to parse XML? And wanted to access the data in some sane, +easy way? Don't want to compile a C parser, for whatever reason? Then xml2js is +what you're looking for! + +Description +=========== + +Simple XML to JavaScript object converter. It supports bi-directional conversion. +Uses [sax-js](https://github.com/isaacs/sax-js/) and +[xmlbuilder-js](https://github.com/oozcitak/xmlbuilder-js/). + +Note: If you're looking for a full DOM parser, you probably want +[JSDom](https://github.com/tmpvar/jsdom). + +Installation +============ + +Simplest way to install `xml2js` is to use [npm](http://npmjs.org), just `npm +install xml2js` which will download xml2js and all dependencies. + +Usage +===== + +No extensive tutorials required because you are a smart developer! The task of +parsing XML should be an easy one, so let's make it so! Here's some examples. + +Shoot-and-forget usage +---------------------- + +You want to parse XML as simple and easy as possible? It's dangerous to go +alone, take this: + +```javascript +var parseString = require('xml2js').parseString; +var xml = "Hello xml2js!" +parseString(xml, function (err, result) { + console.dir(result); +}); +``` + +Can't get easier than this, right? This works starting with `xml2js` 0.2.3. +With CoffeeScript it looks like this: + +```coffeescript +{parseString} = require 'xml2js' +xml = "Hello xml2js!" +parseString xml, (err, result) -> + console.dir result +``` + +If you need some special options, fear not, `xml2js` supports a number of +options (see below), you can specify these as second argument: + +```javascript +parseString(xml, {trim: true}, function (err, result) { +}); +``` + +Simple as pie usage +------------------- + +That's right, if you have been using xml-simple or a home-grown +wrapper, this was added in 0.1.11 just for you: + +```javascript +var fs = require('fs'), + xml2js = require('xml2js'); + +var parser = new xml2js.Parser(); +fs.readFile(__dirname + '/foo.xml', function(err, data) { + parser.parseString(data, function (err, result) { + console.dir(result); + console.log('Done'); + }); +}); +``` + +Look ma, no event listeners! + +You can also use `xml2js` from +[CoffeeScript](http://jashkenas.github.com/coffee-script/), further reducing +the clutter: + +```coffeescript +fs = require 'fs', +xml2js = require 'xml2js' + +parser = new xml2js.Parser() +fs.readFile __dirname + '/foo.xml', (err, data) -> + parser.parseString data, (err, result) -> + console.dir result + console.log 'Done.' +``` + +But what happens if you forget the `new` keyword to create a new `Parser`? In +the middle of a nightly coding session, it might get lost, after all. Worry +not, we got you covered! Starting with 0.2.8 you can also leave it out, in +which case `xml2js` will helpfully add it for you, no bad surprises and +inexplicable bugs! + +"Traditional" usage +------------------- + +Alternatively you can still use the traditional `addListener` variant that was +supported since forever: + +```javascript +var fs = require('fs'), + xml2js = require('xml2js'); + +var parser = new xml2js.Parser(); +parser.addListener('end', function(result) { + console.dir(result); + console.log('Done.'); +}); +fs.readFile(__dirname + '/foo.xml', function(err, data) { + parser.parseString(data); +}); +``` + +If you want to parse multiple files, you have multiple possibilites: + + * You can create one `xml2js.Parser` per file. That's the recommended one + and is promised to always *just work*. + * You can call `reset()` on your parser object. + * You can hope everything goes well anyway. This behaviour is not + guaranteed work always, if ever. Use option #1 if possible. Thanks! + +So you wanna some JSON? +----------------------- + +Just wrap the `result` object in a call to `JSON.stringify` like this +`JSON.stringify(result)`. You get a string containing the JSON representation +of the parsed object that you can feed to JSON-hungry consumers. + +Displaying results +------------------ + +You might wonder why, using `console.dir` or `console.log` the output at some +level is only `[Object]`. Don't worry, this is not because xml2js got lazy. +That's because Node uses `util.inspect` to convert the object into strings and +that function stops after `depth=2` which is a bit low for most XML. + +To display the whole deal, you can use `console.log(util.inspect(result, false, +null))`, which displays the whole result. + +So much for that, but what if you use +[eyes](https://github.com/cloudhead/eyes.js) for nice colored output and it +truncates the output with `…`? Don't fear, there's also a solution for that, +you just need to increase the `maxLength` limit by creating a custom inspector +`var inspect = require('eyes').inspector({maxLength: false})` and then you can +easily `inspect(result)`. + +XML builder usage +----------------- + +Since 0.4.0, objects can be also be used to build XML: + +```javascript +var fs = require('fs'), + xml2js = require('xml2js'); + +var obj = {name: "Super", Surname: "Man", age: 23}; + +var builder = new xml2js.Builder(); +var xml = builder.buildObject(obj); +``` + +At the moment, a one to one bi-directional conversion is guaranteed only for +default configuration, except for `attrkey`, `charkey` and `explicitArray` options +you can redefine to your taste. Writing CDATA is not currently supported. + +Processing attribute and tag names +---------------------------------- + +Since 0.4.1 you can optionally provide the parser with attribute and tag name processors: + +```javascript + +function nameToUpperCase(name){ + return name.toUpperCase(); +} + +//transform all attribute and tag names to uppercase +parseString(xml, {tagNameProcessors: [nameToUpperCase], attrNameProcessors: [nameToUpperCase]}, function (err, result) { +}); +``` + +The `tagNameProcessors` and `attrNameProcessors` options both accept an `Array` of functions with the following signature: +```javascript +function (name){ + //do something with `name` + return name +} +``` + +Some processors are provided out-of-the-box and can be found in `lib/processors.js`: + +- `normalize`: transforms the name to lowercase. +(Automatically used when `options.normalize` is set to `true`) + +- `firstCharLowerCase`: transforms the first character to lower case. +E.g. 'MyTagName' becomes 'myTagName' + +- `stripPrefix`: strips the xml namespace prefix. E.g `` will become 'Bar'. +(N.B.: the `xmlns` prefix is NOT stripped.) + +Options +======= + +Apart from the default settings, there are a number of options that can be +specified for the parser. Options are specified by ``new Parser({optionName: +value})``. Possible options are: + + * `attrkey` (default: `$`): Prefix that is used to access the attributes. + Version 0.1 default was `@`. + * `charkey` (default: `_`): Prefix that is used to access the character + content. Version 0.1 default was `#`. + * `explicitCharkey` (default: `false`) + * `trim` (default: `false`): Trim the whitespace at the beginning and end of + text nodes. + * `normalizeTags` (default: `false`): Normalize all tag names to lowercase. + * `normalize` (default: `false`): Trim whitespaces inside text nodes. + * `explicitRoot` (default: `true`): Set this if you want to get the root + node in the resulting object. + * `emptyTag` (default: `undefined`): what will the value of empty nodes be. + Default is `{}`. + * `explicitArray` (default: `true`): Always put child nodes in an array if + true; otherwise an array is created only if there is more than one. + * `ignoreAttrs` (default: `false`): Ignore all XML attributes and only create + text nodes. + * `mergeAttrs` (default: `false`): Merge attributes and child elements as + properties of the parent, instead of keying attributes off a child + attribute object. This option is ignored if `ignoreAttrs` is `false`. + * `validator` (default `null`): You can specify a callable that validates + the resulting structure somehow, however you want. See unit tests + for an example. + * `xmlns` (default `false`): Give each element a field usually called '$ns' + (the first character is the same as attrkey) that contains its local name + and namespace URI. + * `explicitChildren` (default `false`): Put child elements to separate + property. Doesn't work with `mergeAttrs = true`. If element has no children + then "children" won't be created. Added in 0.2.5. + * `childkey` (default `$$`): Prefix that is used to access child elements if + `explicitChildren` is set to `true`. Added in 0.2.5. + * `charsAsChildren` (default `false`): Determines whether chars should be + considered children if `explicitChildren` is on. Added in 0.2.5. + * `async` (default `false`): Should the callbacks be async? This *might* be + an incompatible change if your code depends on sync execution of callbacks. + xml2js 0.3 might change this default, so the recommendation is to not + depend on sync execution anyway. Added in 0.2.6. + * `strict` (default `true`): Set sax-js to strict or non-strict parsing mode. + Defaults to `true` which is *highly* recommended, since parsing HTML which + is not well-formed XML might yield just about anything. Added in 0.2.7. + * `attrNameProcessors` (default: `null`): Allows the addition of attribute name processing functions. + Accepts an `Array` of functions with following signature: + ```javascript + function (name){ + //do something with `name` + return name + } + ``` + Added in 0.4.1 + * `tagNameProcessors` (default: `null`):Allows the addition of tag name processing functions. + Accepts an `Array` of functions with following signature: + ```javascript + function (name){ + //do something with `name` + return name + } + ``` + Added in 0.4.1 + +Options for the `Builder` class +------------------------------- + + * `rootName` (default `root`): root element name to be used in case + `explicitRoot` is `false` or to override the root element name. + * `renderOpts` (default `{ 'pretty': true, 'indent': ' ', 'newline': '\n' }`): + Rendering options for xmlbuilder-js. + * pretty: prettify generated XML + * indent: whitespace for indentation (only when pretty) + * newline: newline char (only when pretty) + * `xmldec` (default `{ 'version': '1.0', 'encoding': 'UTF-8', 'standalone': true }`: + XML declaration attributes. + * `xmldec.version` A version number string, e.g. 1.0 + * `xmldec.encoding` Encoding declaration, e.g. UTF-8 + * `xmldec.standalone` standalone document declaration: true or false + * `doctype` (default `null`): optional DTD. Eg. `{'ext': 'hello.dtd'}` + * `headless` (default: `false`): omit the XML header. Added in 0.4.3. + +`renderOpts`, `xmldec`,`doctype` and `headless` pass through to +[xmlbuilder-js](https://github.com/oozcitak/xmlbuilder-js). + +Updating to new version +======================= + +Version 0.2 changed the default parsing settings, but version 0.1.14 introduced +the default settings for version 0.2, so these settings can be tried before the +migration. + +```javascript +var xml2js = require('xml2js'); +var parser = new xml2js.Parser(xml2js.defaults["0.2"]); +``` + +To get the 0.1 defaults in version 0.2 you can just use +`xml2js.defaults["0.1"]` in the same place. This provides you with enough time +to migrate to the saner way of parsing in xml2js 0.2. We try to make the +migration as simple and gentle as possible, but some breakage cannot be +avoided. + +So, what exactly did change and why? In 0.2 we changed some defaults to parse +the XML in a more universal and sane way. So we disabled `normalize` and `trim` +so xml2js does not cut out any text content. You can reenable this at will of +course. A more important change is that we return the root tag in the resulting +JavaScript structure via the `explicitRoot` setting, so you need to access the +first element. This is useful for anybody who wants to know what the root node +is and preserves more information. The last major change was to enable +`explicitArray`, so everytime it is possible that one might embed more than one +sub-tag into a tag, xml2js >= 0.2 returns an array even if the array just +includes one element. This is useful when dealing with APIs that return +variable amounts of subtags. + +Running tests, development +========================== + +[![Build Status](https://secure.travis-ci.org/Leonidas-from-XIV/node-xml2js.png?branch=master)](https://travis-ci.org/Leonidas-from-XIV/node-xml2js) +[![Dependency Status](https://david-dm.org/Leonidas-from-XIV/node-xml2js.png)](https://david-dm.org/Leonidas-from-XIV/node-xml2js) + +The development requirements are handled by npm, you just need to install them. +We also have a number of unit tests, they can be run using `npm test` directly +from the project root. This runs zap to discover all the tests and execute +them. + +If you like to contribute, keep in mind that xml2js is written in CoffeeScript, +so don't develop on the JavaScript files that are checked into the repository +for convenience reasons. Also, please write some unit test to check your +behaviour and if it is some user-facing thing, add some documentation to this +README, so people will know it exists. Thanks in advance! diff --git a/platforms/android/assets/www/node_modules/xml2js/canon.xml b/platforms/android/assets/www/node_modules/xml2js/canon.xml new file mode 100644 index 0000000..f24ddd1 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/canon.xml @@ -0,0 +1,482 @@ + + + AF485783 + 14758 + double + DNA + circular + SYN + 15-MAY-2003 + 21-MAR-2002 + Binary vector pBI121, complete sequence + AF485783 + AF485783.1 + + gb|AF485783.1| + gi|19569229 + + Binary vector pBI121 + Binary vector pBI121 + other sequences; artificial sequences; vectors + + + 1 + 1..14758 + + Chen,P.Y. + Wang,C.K. + Soong,S.C. + To,K.Y. + + Complete sequence of the binary vector pBI121 and its application in cloning T-DNA insertion from transgenic plants + Mol. Breed. 11, 287-293 (2003) + + + 2 + 1..14758 + + To,K.Y. + + Direct Submission + Submitted (20-FEB-2002) Institute of BioAgricultural Sciences, Academia Sinica, Taipei 11529, Taiwan + + + + + source + 1..14758 + + + 1 + 14758 + AF485783.1 + + + + + organism + Binary vector pBI121 + + + mol_type + genomic DNA + + + db_xref + taxon:189807 + + + note + constructed using pB221 from Clontech Laboratories and Bin19 described in GenBank Accession Number U09365 + + + + + misc_feature + complement(13..796) + + + 796 + 13 + + AF485783.1 + + + + + note + similar to traF in GenBank Accession Number X54459 + + + + + rep_origin + complement(790..1168) + + + 1168 + 790 + + AF485783.1 + + + + + note + ColE1 ori; similar to sequence in GenBank Accession Number V00268 + + + + + misc_feature + complement(1161..2344) + + + 2344 + 1161 + + AF485783.1 + + + + + note + similar to tetA in GenBank Accession Number X75761 + + + + + misc_feature + complement(2454..2478) + + + 2478 + 2454 + + AF485783.1 + + + + + note + T-DNA right border + + + + + promoter + 2519..2825 + + + 2519 + 2825 + AF485783.1 + + + + + note + NOS + + + + + gene + 2838..3632 + + + 2838 + 3632 + AF485783.1 + + + + + gene + nptII + + + + + CDS + 2838..3632 + + + 2838 + 3632 + AF485783.1 + + + + + gene + nptII + + + codon_start + 1 + + + transl_table + 1 + + + product + neomycin phosphotransferase II + + + protein_id + AAL92039.1 + + + db_xref + GI:19569230 + + + translation + MIEQDGLHAGSPAAWVERLFGYDWAQQTIGCSDAAVFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLLLGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAGLVDQDDLDEEHQGLAPAELFARLKARMPDGDDLVVTHGDACLPNIMVENGRFSGFIDCGRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF + + + + + terminator + 4022..4277 + + + 4022 + 4277 + AF485783.1 + + + + + note + NOS + + + + + promoter + 4974..5808 + + + 4974 + 5808 + AF485783.1 + + + + + note + CaMV 35S + + + + + gene + 5845..7656 + + + 5845 + 7656 + AF485783.1 + + + + + gene + gusA + + + + + CDS + 5845..7656 + + + 5845 + 7656 + AF485783.1 + + + + + gene + gusA + + + note + GUS + + + codon_start + 1 + + + transl_table + 1 + + + product + beta-glucuronidase + + + protein_id + AAL92040.1 + + + db_xref + GI:19569231 + + + translation + MLRPVETPTREIKKLDGLWAFSLDRENCGIDQRWWESALQESRAIAVPGSFNDQFADADIRNYAGNVWYQREVFIPKGWAGQRIVLRFDAVTHYGKVWVNNQEVMEHQGGYTPFEADVTPYVIAGKSVRITVCVNNELNWQTIPPGMVITDENGKKKQSYFHDFFNYAGIHRSVMLYTTPNTWVDDITVVTHVAQDCNHASVDWQVVANGDVSVELRDADQQVVATGQGTSGTLQVVNPHLWQPGEGYLYELCVTAKSQTECDIYPLRVGIRSVAVKGEQFLINHKPFYFTGFGRHEDADLRGKGFDNVLMVHDHALMDWIGANSYRTSHYPYAEEMLDWADEHGIVVIDETAAVGFNLSLGIGFEAGNKPKELYSEEAVNGETQQAHLQAIKELIARDKNHPSVVMWSIANEPDTRPQGAREYFAPLAEATRKLDPTRPITCVNVMFCDAHTDTISDLFDVLCLNRYYGWYVQSGDLETAEKVLEKELLAWQEKLHQPIIITEYGVDTLAGLHSMYTDMWSEEYQCAWLDMYHRVFDRVSAVVGEQVWNFADFATSQGILRVGGNKKGIFTRDRKPKSAAFLLQKRWTGMNFGEKPQQGGKQ + + + + + terminator + 7727..7979 + + + 7727 + 7979 + AF485783.1 + + + + + note + NOS + + + + + misc_feature + complement(8621..8646) + + + 8646 + 8621 + + AF485783.1 + + + + + note + T-DNA left border + + + + + misc_feature + complement(9156..10198) + + + 10198 + 9156 + + AF485783.1 + + + + + note + similar to tetA in GenBank Accession Number L13842 + + + + + misc_feature + complement(10199..11680) + + + 11680 + 10199 + + AF485783.1 + + + + + note + similar to trfA in GenBank Accession Number X00713 + + + + + misc_feature + complement(11681..12673) + + + 12673 + 11681 + + AF485783.1 + + + + + note + similar to NPTIII gene in GenBank Accession Number V01547 + + + + + misc_feature + complement(12674..13443) + + + 13443 + 12674 + + AF485783.1 + + + + + note + similar to transposable element IS1 in GenBank Accession Number X58999 + + + + + misc_feature + complement(13444..13794) + + + 13794 + 13444 + + AF485783.1 + + + + + note + similarity to NPT III gene in GenBank Accession Number V01547 + + + + + misc_feature + complement(13795..14066) + + + 14066 + 13795 + + AF485783.1 + + + + + note + similar to kilA in GenBank Accession Number M62846 + + + + + rep_origin + complement(14141..14758) + + + 14758 + 14141 + + AF485783.1 + + + + + note + ori V; similar to sequence in GenBank Accession Number M20134 + + + + + tgagcgtcgcaaaggcgctcggtcttgccttgctcgtcggtgatgtacttcaccagctccgcgaagtcgctcttcttgatggagcgcatggggacgtgcttggcaatcacgcgcaccccccggccgttttagcggctaaaaaagtcatggctctgccctcgggcggaccacgcccatcatgaccttgccaagctcgtcctgcttctcttcgatcttcgccagcagggcgaggatcgtggcatcaccgaaccgcgccgtgcgcgggtcgtcggtgagccagagtttcagcaggccgcccaggcggcccaggtcgccattgatgcgggccagctcgcggacgtgctcatagtccacgacgcccgtgattttgtagccctggccgacggccagcaggtaggccgacaggctcatgccggccgccgccgccttttcctcaatcgctcttcgttcgtctggaaggcagtacaccttgataggtgggctgcccttcctggttggcttggtttcatcagccatccgcttgccctcatctgttacgccggcggtagccggccagcctcgcagagcaggattcccgttgagcaccgccaggtgcgaataagggacagtgaagaaggaacacccgctcgcgggtgggcctacttcacctatcctgcccggctgacgccgttggatacaccaaggaaagtctacacgaaccctttggcaaaatcctgtatatcgtgcgaaaaaggatggatataccgaaaaaatcgctataatgaccccgaagcagggttatgcagcggaaaagcgccacgcttcccgaagggagaaaggcggacaggtatccggtaagcggcagggtcggaacaggagagcgcacgagggagcttccagggggaaacgcctggtatctttatagtcctgtcgggtttcgccacctctgacttgagcgtcgatttttgtgatgctcgtcaggggggcggagcctatggaaaaacgccagcaacgcggcctttttacggttcctggccttttgctggccttttgctcacatgttctttcctgcgttatcccctgattctgtggataaccgtattaccgcctttgagtgagctgataccgctcgccgcagccgaacgaccgagcgcagcgagtcagtgagcgaggaagcggaagagcgccagaaggccgccagagaggccgagcgcggccgtgaggcttggacgctagggcagggcatgaaaaagcccgtagcgggctgctacgggcgtctgacgcggtggaaagggggaggggatgttgtctacatggctctgctgtagtgagtgggttgcgctccggcagcggtcctgatcaatcgtcaccctttctcggtccttcaacgttcctgacaacgagcctccttttcgccaatccatcgacaatcaccgcgagtccctgctcgaacgctgcgtccggaccggcttcgtcgaaggcgtctatcgcggcccgcaacagcggcgagagcggagcctgttcaacggtgccgccgcgctcgccggcatcgctgtcgccggcctgctcctcaagcacggccccaacagtgaagtagctgattgtcatcagcgcattgacggcgtccccggccgaaaaacccgcctcgcagaggaagcgaagctgcgcgtcggccgtttccatctgcggtgcgcccggtcgcgtgccggcatggatgcgcgcgccatcgcggtaggcgagcagcgcctgcctgaagctgcgggcattcccgatcagaaatgagcgccagtcgtcgtcggctctcggcaccgaatgcgtatgattctccgccagcatggcttcggccagtgcgtcgagcagcgcccgcttgttcctgaagtgccagtaaagcgccggctgctgaacccccaaccgttccgccagtttgcgtgtcgtcagaccgtctacgccgacctcgttcaacaggtccagggcggcacggatcactgtattcggctgcaactttgtcatgcttgacactttatcactgataaacataatatgtccaccaacttatcagtgataaagaatccgcgcgttcaatcggaccagcggaggctggtccggaggccagacgtgaaacccaacatacccctgatcgtaattctgagcactgtcgcgctcgacgctgtcggcatcggcctgattatgccggtgctgccgggcctcctgcgcgatctggttcactcgaacgacgtcaccgcccactatggcattctgctggcgctgtatgcgttggtgcaatttgcctgcgcacctgtgctgggcgcgctgtcggatcgtttcgggcggcggccaatcttgctcgtctcgctggccggcgccagatctggggaaccctgtggttggcatgcacatacaaatggacgaacggataaaccttttcacgcccttttaaatatccgattattctaataaacgctcttttctcttaggtttacccgccaatatatcctgtcaaacactgatagtttaaactgaaggcgggaaacgacaatctgatcatgagcggagaattaagggagtcacgttatgacccccgccgatgacgcgggacaagccgttttacgtttggaactgacagaaccgcaacgttgaaggagccactcagccgcgggtttctggagtttaatgagctaagcacatacgtcagaaaccattattgcgcgttcaaaagtcgcctaaggtcactatcagctagcaaatatttcttgtcaaaaatgctccactgacgttccataaattcccctcggtatccaattagagtctcatattcactctcaatccaaataatctgcaccggatctggatcgtttcgcatgattgaacaagatggattgcacgcaggttctccggccgcttgggtggagaggctattcggctatgactgggcacaacagacaatcggctgctctgatgccgccgtgttccggctgtcagcgcaggggcgcccggttctttttgtcaagaccgacctgtccggtgccctgaatgaactgcaggacgaggcagcgcggctatcgtggctggccacgacgggcgttccttgcgcagctgtgctcgacgttgtcactgaagcgggaagggactggctgctattgggcgaagtgccggggcaggatctcctgtcatctcaccttgctcctgccgagaaagtatccatcatggctgatgcaatgcggcggctgcatacgcttgatccggctacctgcccattcgaccaccaagcgaaacatcgcatcgagcgagcacgtactcggatggaagccggtcttgtcgatcaggatgatctggacgaagagcatcaggggctcgcgccagccgaactgttcgccaggctcaaggcgcgcatgcccgacggcgatgatctcgtcgtgacccatggcgatgcctgcttgccgaatatcatggtggaaaatggccgcttttctggattcatcgactgtggccggctgggtgtggcggaccgctatcaggacatagcgttggctacccgtgatattgctgaagagcttggcggcgaatgggctgaccgcttcctcgtgctttacggtatcgccgctcccgattcgcagcgcatcgccttctatcgccttcttgacgagttcttctgagcgggactctggggttcgaaatgaccgaccaagcgacgcccaacctgccatcacgagatttcgattccaccgccgccttctatgaaaggttgggcttcggaatcgttttccgggacgccggctggatgatcctccagcgcggggatctcatgctggagttcttcgcccacgggatctctgcggaacaggcggtcgaaggtgccgatatcattacgacagcaacggccgacaagcacaacgccacgatcctgagcgacaatatgatcgggcccggcgtccacatcaacggcgtcggcggcgactgcccaggcaagaccgagatgcaccgcgatatcttgctgcgttcggatattttcgtggagttcccgccacagacccggatgatccccgatcgttcaaacatttggcaataaagtttcttaagattgaatcctgttgccggtcttgcgatgattatcatataatttctgttgaattacgttaagcatgtaataattaacatgtaatgcatgacgttatttatgagatgggtttttatgattagagtcccgcaattatacatttaatacgcgatagaaaacaaaatatagcgcgcaaactaggataaattatcgcgcgcggtgtcatctatgttactagatcgggcctcctgtcaatgctggcggcggctctggtggtggttctggtggcggctctgagggtggtggctctgagggtggcggttctgagggtggcggctctgagggaggcggttccggtggtggctctggttccggtgattttgattatgaaaagatggcaaacgctaataagggggctatgaccgaaaatgccgatgaaaacgcgctacagtctgacgctaaaggcaaacttgattctgtcgctactgattacggtgctgctatcgatggtttcattggtgacgtttccggccttgctaatggtaatggtgctactggtgattttgctggctctaattcccaaatggctcaagtcggtgacggtgataattcacctttaatgaataatttccgtcaatatttaccttccctccctcaatcggttgaatgtcgcccttttgtctttggcccaatacgcaaaccgcctctccccgcgcgttggccgattcattaatgcagctggcacgacaggtttcccgactggaaagcgggcagtgagcgcaacgcaattaatgtgagttagctcactcattaggcaccccaggctttacactttatgcttccggctcgtatgttgtgtggaattgtgagcggataacaatttcacacaggaaacagctatgaccatgattacgccaagcttgcatgcctgcaggtccccagattagccttttcaatttcagaaagaatgctaacccacagatggttagagaggcttacgcagcaggtctcatcaagacgatctacccgagcaataatctccaggaaatcaaataccttcccaagaaggttaaagatgcagtcaaaagattcaggactaactgcatcaagaacacagagaaagatatatttctcaagatcagaagtactattccagtatggacgattcaaggcttgcttcacaaaccaaggcaagtaatagagattggagtctctaaaaaggtagttcccactgaatcaaaggccatggagtcaaagattcaaatagaggacctaacagaactcgccgtaaagactggcgaacagttcatacagagtctcttacgactcaatgacaagaagaaaatcttcgtcaacatggtggagcacgacacacttgtctactccaaaaatatcaaagatacagtctcagaagaccaaagggcaattgagacttttcaacaaagggtaatatccggaaacctcctcggattccattgcccagctatctgtcactttattgtgaagatagtggaaaaggaaggtggctcctacaaatgccatcattgcgataaaggaaaggccatcgttgaagatgcctctgccgacagtggtcccaaagatggacccccacccacgaggagcatcgtggaaaaagaagacgttccaaccacgtcttcaaagcaagtggattgatgtgatatctccactgacgtaagggatgacgcacaatcccactatccttcgcaagacccttcctctatataaggaagttcatttcatttggagagaacacgggggactctagaggatccccgggtggtcagtcccttatgttacgtcctgtagaaaccccaacccgtgaaatcaaaaaactcgacggcctgtgggcattcagtctggatcgcgaaaactgtggaattgatcagcgttggtgggaaagcgcgttacaagaaagccgggcaattgctgtgccaggcagttttaacgatcagttcgccgatgcagatattcgtaattatgcgggcaacgtctggtatcagcgcgaagtctttataccgaaaggttgggcaggccagcgtatcgtgctgcgtttcgatgcggtcactcattacggcaaagtgtgggtcaataatcaggaagtgatggagcatcagggcggctatacgccatttgaagccgatgtcacgccgtatgttattgccgggaaaagtgtacgtatcaccgtttgtgtgaacaacgaactgaactggcagactatcccgccgggaatggtgattaccgacgaaaacggcaagaaaaagcagtcttacttccatgatttctttaactatgccggaatccatcgcagcgtaatgctctacaccacgccgaacacctgggtggacgatatcaccgtggtgacgcatgtcgcgcaagactgtaaccacgcgtctgttgactggcaggtggtggccaatggtgatgtcagcgttgaactgcgtgatgcggatcaacaggtggttgcaactggacaaggcactagcgggactttgcaagtggtgaatccgcacctctggcaaccgggtgaaggttatctctatgaactgtgcgtcacagccaaaagccagacagagtgtgatatctacccgcttcgcgtcggcatccggtcagtggcagtgaagggcgaacagttcctgattaaccacaaaccgttctactttactggctttggtcgtcatgaagatgcggacttgcgtggcaaaggattcgataacgtgctgatggtgcacgaccacgcattaatggactggattggggccaactcctaccgtacctcgcattacccttacgctgaagagatgctcgactgggcagatgaacatggcatcgtggtgattgatgaaactgctgctgtcggctttaacctctctttaggcattggtttcgaagcgggcaacaagccgaaagaactgtacagcgaagaggcagtcaacggggaaactcagcaagcgcacttacaggcgattaaagagctgatagcgcgtgacaaaaaccacccaagcgtggtgatgtggagtattgccaacgaaccggatacccgtccgcaaggtgcacgggaatatttcgcgccactggcggaagcaacgcgtaaactcgacccgacgcgtccgatcacctgcgtcaatgtaatgttctgcgacgctcacaccgataccatcagcgatctctttgatgtgctgtgcctgaaccgttattacggatggtatgtccaaagcggcgatttggaaacggcagagaaggtactggaaaaagaacttctggcctggcaggagaaactgcatcagccgattatcatcaccgaatacggcgtggatacgttagccgggctgcactcaatgtacaccgacatgtggagtgaagagtatcagtgtgcatggctggatatgtatcaccgcgtctttgatcgcgtcagcgccgtcgtcggtgaacaggtatggaatttcgccgattttgcgacctcgcaaggcatattgcgcgttggcggtaacaagaaagggatcttcactcgcgaccgcaaaccgaagtcggcggcttttctgctgcaaaaacgctggactggcatgaacttcggtgaaaaaccgcagcagggaggcaaacaatgaatcaacaactctcctggcgcaccatcgtcggctacagcctcgggaattgctaccgagctcgaatttccccgatcgttcaaacatttggcaataaagtttcttaagattgaatcctgttgccggtcttgcgatgattatcatataatttctgttgaattacgttaagcatgtaataattaacatgtaatgcatgacgttatttatgagatgggtttttatgattagagtcccgcaattatacatttaatacgcgatagaaaacaaaatatagcgcgcaaactaggataaattatcgcgcgcggtgtcatctatgttactagatcgggaattcactggccgtcgttttacaacgtcgtgactgggaaaaccctggcgttacccaacttaatcgccttgcagcacatccccctttcgccagctggcgtaatagcgaagaggcccgcaccgatcgcccttcccaacagttgcgcagcctgaatggcgcccgctcctttcgctttcttcccttcctttctcgccacgttcgccggctttccccgtcaagctctaaatcgggggctccctttagggttccgatttagtgctttacggcacctcgaccccaaaaaacttgatttgggtgatggttcacgtagtgggccatcgccctgatagacggtttttcgccctttgacgttggagtccacgttctttaatagtggactcttgttccaaactggaacaacactcaaccctatctcgggctattcttttgatttataagggattttgccgatttcggaaccaccatcaaacaggattttcgcctgctggggcaaaccagcgtggaccgcttgctgcaactctctcagggccaggcggtgaagggcaatcagctgttgcccgtctcactggtgaaaagaaaaaccaccccagtacattaaaaacgtccgcaatgtgttattaagttgtctaagcgtcaatttgtttacaccacaatatatcctgccaccagccagccaacagctccccgaccggcagctcggcacaaaatcaccactcgatacaggcagcccatcagtccgggacggcgtcagcgggagagccgttgtaaggcggcagactttgctcatgttaccgatgctattcggaagaacggcaactaagctgccgggtttgaaacacggatgatctcgcggagggtagcatgttgattgtaacgatgacagagcgttgctgcctgtgatcaaatatcatctccctcgcagagatccgaattatcagccttcttattcatttctcgcttaaccgtgacaggctgtcgatcttgagaactatgccgacataataggaaatcgctggataaagccgctgaggaagctgagtggcgctatttctttagaagtgaacgttgacgatatcaactcccctatccattgctcaccgaatggtacaggtcggggacccgaagttccgactgtcggcctgatgcatccccggctgatcgaccccagatctggggctgagaaagcccagtaaggaaacaactgtaggttcgagtcgcgagatcccccggaaccaaaggaagtaggttaaacccgctccgatcaggccgagccacgccaggccgagaacattggttcctgtaggcatcgggattggcggatcaaacactaaagctactggaacgagcagaagtcctccggccgccagttgccaggcggtaaaggtgagcagaggcacgggaggttgccacttgcgggtcagcacggttccgaacgccatggaaaccgcccccgccaggcccgctgcgacgccgacaggatctagcgctgcgtttggtgtcaacaccaacagcgccacgcccgcagttccgcaaatagcccccaggaccgccatcaatcgtatcgggctacctagcagagcggcagagatgaacacgaccatcagcggctgcacagcgcctaccgtcgccgcgaccccgcccggcaggcggtagaccgaaataaacaacaagctccagaatagcgaaatattaagtgcgccgaggatgaagatgcgcatccaccagattcccgttggaatctgtcggacgatcatcacgagcaataaacccgccggcaacgcccgcagcagcataccggcgacccctcggcctcgctgttcgggctccacgaaaacgccggacagatgcgccttgtgagcgtccttggggccgtcctcctgtttgaagaccgacagcccaatgatctcgccgtcgatgtaggcgccgaatgccacggcatctcgcaaccgttcagcgaacgcctccatgggctttttctcctcgtgctcgtaaacggacccgaacatctctggagctttcttcagggccgacaatcggatctcgcggaaatcctgcacgtcggccgctccaagccgtcgaatctgagccttaatcacaattgtcaattttaatcctctgtttatcggcagttcgtagagcgcgccgtgcgtcccgagcgatactgagcgaagcaagtgcgtcgagcagtgcccgcttgttcctgaaatgccagtaaagcgctggctgctgaacccccagccggaactgaccccacaaggccctagcgtttgcaatgcaccaggtcatcattgacccaggcgtgttccaccaggccgctgcctcgcaactcttcgcaggcttcgccgacctgctcgcgccacttcttcacgcgggtggaatccgatccgcacatgaggcggaaggtttccagcttgagcgggtacggctcccggtgcgagctgaaatagtcgaacatccgtcgggccgtcggcgacagcttgcggtacttctcccatatgaatttcgtgtagtggtcgccagcaaacagcacgacgatttcctcgtcgatcaggacctggcaacgggacgttttcttgccacggtccaggacgcggaagcggtgcagcagcgacaccgattccaggtgcccaacgcggtcggacgtgaagcccatcgccgtcgcctgtaggcgcgacaggcattcctcggccttcgtgtaataccggccattgatcgaccagcccaggtcctggcaaagctcgtagaacgtgaaggtgatcggctcgccgataggggtgcgcttcgcgtactccaacacctgctgccacaccagttcgtcatcgtcggcccgcagctcgacgccggtgtaggtgatcttcacgtccttgttgacgtggaaaatgaccttgttttgcagcgcctcgcgcgggattttcttgttgcgcgtggtgaacagggcagagcgggccgtgtcgtttggcatcgctcgcatcgtgtccggccacggcgcaatatcgaacaaggaaagctgcatttccttgatctgctgcttcgtgtgtttcagcaacgcggcctgcttggcctcgctgacctgttttgccaggtcctcgccggcggtttttcgcttcttggtcgtcatagttcctcgcgtgtcgatggtcatcgacttcgccaaacctgccgcctcctgttcgagacgacgcgaacgctccacggcggccgatggcgcgggcagggcagggggagccagttgcacgctgtcgcgctcgatcttggccgtagcttgctggaccatcgagccgacggactggaaggtttcgcggggcgcacgcatgacggtgcggcttgcgatggtttcggcatcctcggcggaaaaccccgcgtcgatcagttcttgcctgtatgccttccggtcaaacgtccgattcattcaccctccttgcgggattgccccgactcacgccggggcaatgtgcccttattcctgatttgacccgcctggtgccttggtgtccagataatccaccttatcggcaatgaagtcggtcccgtagaccgtctggccgtccttctcgtacttggtattccgaatcttgccctgcacgaataccagcgaccccttgcccaaatacttgccgtgggcctcggcctgagagccaaaacacttgatgcggaagaagtcggtgcgctcctgcttgtcgccggcatcgttgcgccacatctaggtactaaaacaattcatccagtaaaatataatattttattttctcccaatcaggcttgatccccagtaagtcaaaaaatagctcgacatactgttcttccccgatatcctccctgatcgaccggacgcagaaggcaatgtcataccacttgtccgccctgccgcttctcccaagatcaataaagccacttactttgccatctttcacaaagatgttgctgtctcccaggtcgccgtgggaaaagacaagttcctcttcgggcttttccgtctttaaaaaatcatacagctcgcgcggatctttaaatggagtgtcttcttcccagttttcgcaatccacatcggccagatcgttattcagtaagtaatccaattcggctaagcggctgtctaagctattcgtatagggacaatccgatatgtcgatggagtgaaagagcctgatgcactccgcatacagctcgataatcttttcagggctttgttcatcttcatactcttccgagcaaaggacgccatcggcctcactcatgagcagattgctccagccatcatgccgttcaaagtgcaggacctttggaacaggcagctttccttccagccatagcatcatgtccttttcccgttccacatcataggtggtccctttataccggctgtccgtcatttttaaatataggttttcattttctcccaccagcttatataccttagcaggagacattccttccgtatcttttacgcagcggtatttttcgatcagttttttcaattccggtgatattctcattttagccatttattatttccttcctcttttctacagtatttaaagataccccaagaagctaattataacaagacgaactccaattcactgttccttgcattctaaaaccttaaataccagaaaacagctttttcaaagttgttttcaaagttggcgtataacatagtatcgacggagccgattttgaaaccacaattatgggtgatgctgccaacttactgatttagtgtatgatggtgtttttgaggtgctccagtggcttctgtgtctatcagctgtccctcctgttcagctactgacggggtggtgcgtaacggcaaaagcaccgccggacatcagcgctatctctgctctcactgccgtaaaacatggcaactgcagttcacttacaccgcttctcaacccggtacgcaccagaaaatcattgatatggccatgaatggcgttggatgccgggcaacagcccgcattatgggcgttggcctcaacacgattttacgtcacttaaaaaactcaggccgcagtcggtaacctcgcgcatacagccgggcagtgacgtcatcgtctgcgcggaaatggacgaacagtggggctatgtcggggctaaatcgcgccagcgctggctgttttacgcgtatgacagtctccggaagacggttgttgcgcacgtattcggtgaacgcactatggcgacgctggggcgtcttatgagcctgctgtcaccctttgacgtggtgatatggatgacggatggctggccgctgtatgaatcccgcctgaagggaaagctgcacgtaatcagcaagcgatatacgcagcgaattgagcggcataacctgaatctgaggcagcacctggcacggctgggacggaagtcgctgtcgttctcaaaatcggtggagctgcatgacaaagtcatcgggcattatctgaacataaaacactatcaataagttggagtcattacccaattatgatagaatttacaagctataaggttattgtcctgggtttcaagcattagtccatgcaagtttttatgctttgcccattctatagatatattgataagcgcgctgcctatgccttgccccctgaaatccttacatacggcgatatcttctatataaaagatatattatcttatcagtattgtcaatatattcaaggcaatctgcctcctcatcctcttcatcctcttcgtcttggtagctttttaaatatggcgcttcatagagtaattctgtaaaggtccaattctcgttttcatacctcggtataatcttacctatcacctcaaatggttcgctgggtttatcgcacccccgaacacgagcacggcacccgcgaccactatgccaagaatgcccaaggtaaaaattgccggccccgccatgaagtccgtgaatgccccgacggccgaagtgaagggcaggccgccacccaggccgccgccctcactgcccggcacctggtcgctgaatgtcgatgccagcacctgcggcacgtcaatgcttccgggcgtcgcgctcgggctgatcgcccatcccgttactgccccgatcccggcaatggcaaggactgccagcgctgccatttttggggtgaggccgttcgcggccgaggggcgcagcccctggggggatgggaggcccgcgttagcgggccgggagggttcgagaagggggggcaccccccttcggcgtgcgcggtcacgcgcacagggcgcagccctggttaaaaacaaggtttataaatattggtttaaaagcaggttaaaagacaggttagcggtggccgaaaaacgggcggaaacccttgcaaatgctggattttctgcctgtggacagcccctcaaatgtcaataggtgcgcccctcatctgtcagcactctgcccctcaagtgtcaaggatcgcgcccctcatctgtcagtagtcgcgcccctcaagtgtcaataccgcagggcacttatccccaggcttgtccacatcatctgtgggaaactcgcgtaaaatcaggcgttttcgccgatttgcgaggctggccagctccacgtcgccggccgaaatcgagcctgcccctcatctgtcaacgccgcgccgggtgagtcggcccctcaagtgtcaacgtccgcccctcatctgtcagtgagggccaagttttccgcgaggtatccacaacgccggcggccgcggtgtctcgcacacggcttcgacggcgtttctggcgcgtttgcagggccatagacggccgccagcccagcggcgagggcaaccagcccgg + + + \ No newline at end of file diff --git a/platforms/android/assets/www/node_modules/xml2js/incompat.coffee b/platforms/android/assets/www/node_modules/xml2js/incompat.coffee new file mode 100644 index 0000000..5533965 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/incompat.coffee @@ -0,0 +1,5 @@ +{parseString} = require './lib/xml2js' +xml = '' +parseString xml, (err, result) -> + console.dir result + diff --git a/platforms/android/assets/www/node_modules/xml2js/incompat2.js b/platforms/android/assets/www/node_modules/xml2js/incompat2.js new file mode 100644 index 0000000..31cfbc8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/incompat2.js @@ -0,0 +1,7 @@ +var xml2js = require('xml2js'); +var parser = new xml2js.Parser({ + mergeAttrs: true +}); +parser.parseString('', function (err, result) { + console.dir(result); +}); diff --git a/platforms/android/assets/www/node_modules/xml2js/lib/bom.js b/platforms/android/assets/www/node_modules/xml2js/lib/bom.js new file mode 100644 index 0000000..d7f226e --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/lib/bom.js @@ -0,0 +1,15 @@ +// Generated by CoffeeScript 1.7.1 +(function() { + var xml2js; + + xml2js = require('../lib/xml2js'); + + exports.stripBOM = function(str) { + if (str[0] === '\uFEFF') { + return str.substring(1); + } else { + return str; + } + }; + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xml2js/lib/processors.js b/platforms/android/assets/www/node_modules/xml2js/lib/processors.js new file mode 100644 index 0000000..aeadaef --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/lib/processors.js @@ -0,0 +1,19 @@ +// Generated by CoffeeScript 1.7.1 +(function() { + var prefixMatch; + + prefixMatch = new RegExp(/(?!xmlns)^.*:/); + + exports.normalize = function(str) { + return str.toLowerCase(); + }; + + exports.firstCharLowerCase = function(str) { + return str.charAt(0).toLowerCase() + str.slice(1); + }; + + exports.stripPrefix = function(str) { + return str.replace(prefixMatch, ''); + }; + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xml2js/lib/xml2js.js b/platforms/android/assets/www/node_modules/xml2js/lib/xml2js.js new file mode 100644 index 0000000..7c1cad3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/lib/xml2js.js @@ -0,0 +1,436 @@ +// Generated by CoffeeScript 1.7.1 +(function() { + var bom, builder, events, isEmpty, processName, processors, sax, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + + sax = require('sax'); + + events = require('events'); + + builder = require('xmlbuilder'); + + bom = require('./bom'); + + processors = require('./processors'); + + isEmpty = function(thing) { + return typeof thing === "object" && (thing != null) && Object.keys(thing).length === 0; + }; + + processName = function(processors, processedName) { + var process, _i, _len; + for (_i = 0, _len = processors.length; _i < _len; _i++) { + process = processors[_i]; + processedName = process(processedName); + } + return processedName; + }; + + exports.processors = processors; + + exports.defaults = { + "0.1": { + explicitCharkey: false, + trim: true, + normalize: true, + normalizeTags: false, + attrkey: "@", + charkey: "#", + explicitArray: false, + ignoreAttrs: false, + mergeAttrs: false, + explicitRoot: false, + validator: null, + xmlns: false, + explicitChildren: false, + childkey: '@@', + charsAsChildren: false, + async: false, + strict: true, + attrNameProcessors: null, + tagNameProcessors: null + }, + "0.2": { + explicitCharkey: false, + trim: false, + normalize: false, + normalizeTags: false, + attrkey: "$", + charkey: "_", + explicitArray: true, + ignoreAttrs: false, + mergeAttrs: false, + explicitRoot: true, + validator: null, + xmlns: false, + explicitChildren: false, + childkey: '$$', + charsAsChildren: false, + async: false, + strict: true, + attrNameProcessors: null, + tagNameProcessors: null, + rootName: 'root', + xmldec: { + 'version': '1.0', + 'encoding': 'UTF-8', + 'standalone': true + }, + doctype: null, + renderOpts: { + 'pretty': true, + 'indent': ' ', + 'newline': '\n' + }, + headless: false + } + }; + + exports.ValidationError = (function(_super) { + __extends(ValidationError, _super); + + function ValidationError(message) { + this.message = message; + } + + return ValidationError; + + })(Error); + + exports.Builder = (function() { + function Builder(opts) { + var key, value, _ref; + this.options = {}; + _ref = exports.defaults["0.2"]; + for (key in _ref) { + if (!__hasProp.call(_ref, key)) continue; + value = _ref[key]; + this.options[key] = value; + } + for (key in opts) { + if (!__hasProp.call(opts, key)) continue; + value = opts[key]; + this.options[key] = value; + } + } + + Builder.prototype.buildObject = function(rootObj) { + var attrkey, charkey, render, rootElement, rootName; + attrkey = this.options.attrkey; + charkey = this.options.charkey; + if ((Object.keys(rootObj).length === 1) && (this.options.rootName === exports.defaults['0.2'].rootName)) { + rootName = Object.keys(rootObj)[0]; + rootObj = rootObj[rootName]; + } else { + rootName = this.options.rootName; + } + render = function(element, obj) { + var attr, child, entry, index, key, value, _ref, _ref1; + if (typeof obj !== 'object') { + element.txt(obj); + } else { + for (key in obj) { + if (!__hasProp.call(obj, key)) continue; + child = obj[key]; + if (key === attrkey) { + if (typeof child === "object") { + for (attr in child) { + value = child[attr]; + element = element.att(attr, value); + } + } + } else if (key === charkey) { + element = element.txt(child); + } else if (typeof child === 'object' && ((child != null ? child.constructor : void 0) != null) && ((child != null ? (_ref = child.constructor) != null ? _ref.name : void 0 : void 0) != null) && (child != null ? (_ref1 = child.constructor) != null ? _ref1.name : void 0 : void 0) === 'Array') { + for (index in child) { + if (!__hasProp.call(child, index)) continue; + entry = child[index]; + if (typeof entry === 'string') { + element = element.ele(key, entry).up(); + } else { + element = arguments.callee(element.ele(key), entry).up(); + } + } + } else if (typeof child === "object") { + element = arguments.callee(element.ele(key), child).up(); + } else { + element = element.ele(key, child.toString()).up(); + } + } + } + return element; + }; + rootElement = builder.create(rootName, this.options.xmldec, this.options.doctype, { + headless: this.options.headless + }); + return render(rootElement, rootObj).end(this.options.renderOpts); + }; + + return Builder; + + })(); + + exports.Parser = (function(_super) { + __extends(Parser, _super); + + function Parser(opts) { + this.parseString = __bind(this.parseString, this); + this.reset = __bind(this.reset, this); + this.assignOrPush = __bind(this.assignOrPush, this); + var key, value, _ref; + if (!(this instanceof exports.Parser)) { + return new exports.Parser(opts); + } + this.options = {}; + _ref = exports.defaults["0.2"]; + for (key in _ref) { + if (!__hasProp.call(_ref, key)) continue; + value = _ref[key]; + this.options[key] = value; + } + for (key in opts) { + if (!__hasProp.call(opts, key)) continue; + value = opts[key]; + this.options[key] = value; + } + if (this.options.xmlns) { + this.options.xmlnskey = this.options.attrkey + "ns"; + } + if (this.options.normalizeTags) { + if (!this.options.tagNameProcessors) { + this.options.tagNameProcessors = []; + } + this.options.tagNameProcessors.unshift(processors.normalize); + } + this.reset(); + } + + Parser.prototype.assignOrPush = function(obj, key, newValue) { + if (!(key in obj)) { + if (!this.options.explicitArray) { + return obj[key] = newValue; + } else { + return obj[key] = [newValue]; + } + } else { + if (!(obj[key] instanceof Array)) { + obj[key] = [obj[key]]; + } + return obj[key].push(newValue); + } + }; + + Parser.prototype.reset = function() { + var attrkey, charkey, ontext, stack; + this.removeAllListeners(); + this.saxParser = sax.parser(this.options.strict, { + trim: false, + normalize: false, + xmlns: this.options.xmlns + }); + this.saxParser.errThrown = false; + this.saxParser.onerror = (function(_this) { + return function(error) { + _this.saxParser.resume(); + if (!_this.saxParser.errThrown) { + _this.saxParser.errThrown = true; + return _this.emit("error", error); + } + }; + })(this); + this.saxParser.ended = false; + this.EXPLICIT_CHARKEY = this.options.explicitCharkey; + this.resultObject = null; + stack = []; + attrkey = this.options.attrkey; + charkey = this.options.charkey; + this.saxParser.onopentag = (function(_this) { + return function(node) { + var key, newValue, obj, processedKey, _ref; + obj = {}; + obj[charkey] = ""; + if (!_this.options.ignoreAttrs) { + _ref = node.attributes; + for (key in _ref) { + if (!__hasProp.call(_ref, key)) continue; + if (!(attrkey in obj) && !_this.options.mergeAttrs) { + obj[attrkey] = {}; + } + newValue = node.attributes[key]; + processedKey = _this.options.attrNameProcessors ? processName(_this.options.attrNameProcessors, key) : key; + if (_this.options.mergeAttrs) { + _this.assignOrPush(obj, processedKey, newValue); + } else { + obj[attrkey][processedKey] = newValue; + } + } + } + obj["#name"] = _this.options.tagNameProcessors ? processName(_this.options.tagNameProcessors, node.name) : node.name; + if (_this.options.xmlns) { + obj[_this.options.xmlnskey] = { + uri: node.uri, + local: node.local + }; + } + return stack.push(obj); + }; + })(this); + this.saxParser.onclosetag = (function(_this) { + return function() { + var cdata, emptyStr, err, node, nodeName, obj, old, s, xpath; + obj = stack.pop(); + nodeName = obj["#name"]; + delete obj["#name"]; + cdata = obj.cdata; + delete obj.cdata; + s = stack[stack.length - 1]; + if (obj[charkey].match(/^\s*$/) && !cdata) { + emptyStr = obj[charkey]; + delete obj[charkey]; + } else { + if (_this.options.trim) { + obj[charkey] = obj[charkey].trim(); + } + if (_this.options.normalize) { + obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim(); + } + if (Object.keys(obj).length === 1 && charkey in obj && !_this.EXPLICIT_CHARKEY) { + obj = obj[charkey]; + } + } + if (isEmpty(obj)) { + obj = _this.options.emptyTag !== void 0 ? _this.options.emptyTag : emptyStr; + } + if (_this.options.validator != null) { + xpath = "/" + ((function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = stack.length; _i < _len; _i++) { + node = stack[_i]; + _results.push(node["#name"]); + } + return _results; + })()).concat(nodeName).join("/"); + try { + obj = _this.options.validator(xpath, s && s[nodeName], obj); + } catch (_error) { + err = _error; + _this.emit("error", err); + } + } + if (_this.options.explicitChildren && !_this.options.mergeAttrs && typeof obj === 'object') { + node = {}; + if (_this.options.attrkey in obj) { + node[_this.options.attrkey] = obj[_this.options.attrkey]; + delete obj[_this.options.attrkey]; + } + if (!_this.options.charsAsChildren && _this.options.charkey in obj) { + node[_this.options.charkey] = obj[_this.options.charkey]; + delete obj[_this.options.charkey]; + } + if (Object.getOwnPropertyNames(obj).length > 0) { + node[_this.options.childkey] = obj; + } + obj = node; + } + if (stack.length > 0) { + return _this.assignOrPush(s, nodeName, obj); + } else { + if (_this.options.explicitRoot) { + old = obj; + obj = {}; + obj[nodeName] = old; + } + _this.resultObject = obj; + _this.saxParser.ended = true; + return _this.emit("end", _this.resultObject); + } + }; + })(this); + ontext = (function(_this) { + return function(text) { + var s; + s = stack[stack.length - 1]; + if (s) { + s[charkey] += text; + return s; + } + }; + })(this); + this.saxParser.ontext = ontext; + return this.saxParser.oncdata = (function(_this) { + return function(text) { + var s; + s = ontext(text); + if (s) { + return s.cdata = true; + } + }; + })(this); + }; + + Parser.prototype.parseString = function(str, cb) { + var err; + if ((cb != null) && typeof cb === "function") { + this.on("end", function(result) { + this.reset(); + if (this.options.async) { + return process.nextTick(function() { + return cb(null, result); + }); + } else { + return cb(null, result); + } + }); + this.on("error", function(err) { + this.reset(); + if (this.options.async) { + return process.nextTick(function() { + return cb(err); + }); + } else { + return cb(err); + } + }); + } + if (str.toString().trim() === '') { + this.emit("end", null); + return true; + } + try { + return this.saxParser.write(bom.stripBOM(str.toString())).close(); + } catch (_error) { + err = _error; + if (!(this.saxParser.errThrown || this.saxParser.ended)) { + this.emit('error', err); + return this.saxParser.errThrown = true; + } + } + }; + + return Parser; + + })(events.EventEmitter); + + exports.parseString = function(str, a, b) { + var cb, options, parser; + if (b != null) { + if (typeof b === 'function') { + cb = b; + } + if (typeof a === 'object') { + options = a; + } + } else { + if (typeof a === 'function') { + cb = a; + } + options = {}; + } + parser = new exports.Parser(options); + return parser.parseString(str, cb); + }; + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xml2js/package.json b/platforms/android/assets/www/node_modules/xml2js/package.json new file mode 100644 index 0000000..a4c768f --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/package.json @@ -0,0 +1,211 @@ +{ + "_args": [ + [ + "xml2js@0.4.4", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver" + ] + ], + "_from": "xml2js@0.4.4", + "_id": "xml2js@0.4.4", + "_inCache": true, + "_installable": true, + "_location": "/xml2js", + "_npmUser": { + "email": "marek@xivilization.net", + "name": "leonidas" + }, + "_npmVersion": "1.4.9", + "_phantomChildren": {}, + "_requested": { + "name": "xml2js", + "raw": "xml2js@0.4.4", + "rawSpec": "0.4.4", + "scope": null, + "spec": "0.4.4", + "type": "version" + }, + "_requiredBy": [ + "/selenium-webdriver" + ], + "_resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz", + "_shasum": "3111010003008ae19240eba17497b57c729c555d", + "_shrinkwrap": null, + "_spec": "xml2js@0.4.4", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver", + "author": { + "email": "marek@xivilization.net", + "name": "Marek Kubica", + "url": "http://xivilization.net" + }, + "bugs": { + "url": "https://github.com/Leonidas-from-XIV/node-xml2js/issues" + }, + "contributors": [ + { + "email": "maqr.lollerskates@gmail.com", + "name": "maqr", + "url": "https://github.com/maqr" + }, + { + "name": "Ben Weaver", + "url": "http://benweaver.com/" + }, + { + "name": "Jae Kwon", + "url": "https://github.com/jaekwon" + }, + { + "name": "Jim Robert" + }, + { + "name": "Ștefan Rusu", + "url": "http://www.saltwaterc.eu/" + }, + { + "email": "carter.cole@cartercole.com", + "name": "Carter Cole", + "url": "http://cartercole.com/" + }, + { + "email": "kurt@kurtraschke.com", + "name": "Kurt Raschke", + "url": "http://www.kurtraschke.com/" + }, + { + "email": "contra@australia.edu", + "name": "Contra", + "url": "https://github.com/Contra" + }, + { + "email": "marudiniz@gmail.com", + "name": "Marcelo Diniz", + "url": "https://github.com/mdiniz" + }, + { + "name": "Michael Hart", + "url": "https://github.com/mhart" + }, + { + "email": "zachary@zacharyscott.net", + "name": "Zachary Scott", + "url": "http://zacharyscott.net/" + }, + { + "name": "Raoul Millais", + "url": "https://github.com/raoulmillais" + }, + { + "name": "Salsita Software", + "url": "http://www.salsitasoft.com/" + }, + { + "email": "mike@emotive.com", + "name": "Mike Schilling", + "url": "http://www.emotive.com/" + }, + { + "email": "shyvo1987@gmail.com", + "name": "Jackson Tian", + "url": "http://weibo.com/shyvo" + }, + { + "email": "mikhail.zyatin@gmail.com", + "name": "Mikhail Zyatin", + "url": "https://github.com/Sitin" + }, + { + "email": "ctavares@microsoft.com", + "name": "Chris Tavares", + "url": "https://github.com/christav" + }, + { + "email": "yyfrankyy@gmail.com", + "name": "Frank Xu", + "url": "http://f2e.us/" + }, + { + "email": "guido@bitstorm.it", + "name": "Guido D'Albore", + "url": "http://www.bitstorm.it/" + }, + { + "name": "Jack Senechal", + "url": "http://jacksenechal.com/" + }, + { + "email": "tc@xantira.com", + "name": "Matthias Hölzl", + "url": "https://github.com/hoelzl" + }, + { + "email": "info@creynders.be", + "name": "Camille Reynders", + "url": "http://www.creynders.be/" + }, + { + "name": "Taylor Gautier", + "url": "https://github.com/tsgautier" + }, + { + "name": "Todd Bryan", + "url": "https://github.com/toddrbryan" + }, + { + "email": "leore.avidar@gmail.com", + "name": "Leore Avidar", + "url": "http://leoreavidar.com/" + }, + { + "email": "dave.aitken@gmail.com", + "name": "Dave Aitken", + "url": "http://www.actionshrimp.com/" + } + ], + "dependencies": { + "sax": "0.6.x", + "xmlbuilder": ">=1.0.0" + }, + "description": "Simple XML to JavaScript object converter.", + "devDependencies": { + "coffee-script": ">=1.7.1", + "diff": ">=1.0.8", + "docco": ">=0.6.2", + "zap": ">=0.2.6" + }, + "directories": { + "lib": "./lib" + }, + "dist": { + "shasum": "3111010003008ae19240eba17497b57c729c555d", + "tarball": "http://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz" + }, + "homepage": "https://github.com/Leonidas-from-XIV/node-xml2js", + "keywords": [ + "xml", + "json" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://raw.github.com/Leonidas-from-XIV/node-xml2js/master/LICENSE" + } + ], + "main": "./lib/xml2js", + "maintainers": [ + { + "email": "marek@xivilization.net", + "name": "leonidas" + } + ], + "name": "xml2js", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/Leonidas-from-XIV/node-xml2js.git" + }, + "scripts": { + "test": "zap" + }, + "version": "0.4.4" +} diff --git a/platforms/android/assets/www/node_modules/xml2js/text.coffee b/platforms/android/assets/www/node_modules/xml2js/text.coffee new file mode 100644 index 0000000..c5d8c66 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/text.coffee @@ -0,0 +1,11 @@ +fs = require 'fs' +xml2js = require 'xml2js' + +parser = new xml2js.Parser + +fs.readFile 'canon.xml', (err, data) -> + console.log err + parser.parseString (err, result) -> + console.log err + console.dir result + diff --git a/platforms/android/assets/www/node_modules/xml2js/text.xml b/platforms/android/assets/www/node_modules/xml2js/text.xml new file mode 100644 index 0000000..bd3b482 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/text.xml @@ -0,0 +1,485 @@ + + + + + AF485783 + 14758 + double + DNA + circular + SYN + 15-MAY-2003 + 21-MAR-2002 + Binary vector pBI121, complete sequence + AF485783 + AF485783.1 + + gb|AF485783.1| + gi|19569229 + + Binary vector pBI121 + Binary vector pBI121 + other sequences; artificial sequences; vectors + + + 1 + 1..14758 + + Chen,P.Y. + Wang,C.K. + Soong,S.C. + To,K.Y. + + Complete sequence of the binary vector pBI121 and its application in cloning T-DNA insertion from transgenic plants + Mol. Breed. 11, 287-293 (2003) + + + 2 + 1..14758 + + To,K.Y. + + Direct Submission + Submitted (20-FEB-2002) Institute of BioAgricultural Sciences, Academia Sinica, Taipei 11529, Taiwan + + + + + source + 1..14758 + + + 1 + 14758 + AF485783.1 + + + + + organism + Binary vector pBI121 + + + mol_type + genomic DNA + + + db_xref + taxon:189807 + + + note + constructed using pB221 from Clontech Laboratories and Bin19 described in GenBank Accession Number U09365 + + + + + misc_feature + complement(13..796) + + + 796 + 13 + + AF485783.1 + + + + + note + similar to traF in GenBank Accession Number X54459 + + + + + rep_origin + complement(790..1168) + + + 1168 + 790 + + AF485783.1 + + + + + note + ColE1 ori; similar to sequence in GenBank Accession Number V00268 + + + + + misc_feature + complement(1161..2344) + + + 2344 + 1161 + + AF485783.1 + + + + + note + similar to tetA in GenBank Accession Number X75761 + + + + + misc_feature + complement(2454..2478) + + + 2478 + 2454 + + AF485783.1 + + + + + note + T-DNA right border + + + + + promoter + 2519..2825 + + + 2519 + 2825 + AF485783.1 + + + + + note + NOS + + + + + gene + 2838..3632 + + + 2838 + 3632 + AF485783.1 + + + + + gene + nptII + + + + + CDS + 2838..3632 + + + 2838 + 3632 + AF485783.1 + + + + + gene + nptII + + + codon_start + 1 + + + transl_table + 1 + + + product + neomycin phosphotransferase II + + + protein_id + AAL92039.1 + + + db_xref + GI:19569230 + + + translation + MIEQDGLHAGSPAAWVERLFGYDWAQQTIGCSDAAVFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLLLGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAGLVDQDDLDEEHQGLAPAELFARLKARMPDGDDLVVTHGDACLPNIMVENGRFSGFIDCGRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF + + + + + terminator + 4022..4277 + + + 4022 + 4277 + AF485783.1 + + + + + note + NOS + + + + + promoter + 4974..5808 + + + 4974 + 5808 + AF485783.1 + + + + + note + CaMV 35S + + + + + gene + 5845..7656 + + + 5845 + 7656 + AF485783.1 + + + + + gene + gusA + + + + + CDS + 5845..7656 + + + 5845 + 7656 + AF485783.1 + + + + + gene + gusA + + + note + GUS + + + codon_start + 1 + + + transl_table + 1 + + + product + beta-glucuronidase + + + protein_id + AAL92040.1 + + + db_xref + GI:19569231 + + + translation + MLRPVETPTREIKKLDGLWAFSLDRENCGIDQRWWESALQESRAIAVPGSFNDQFADADIRNYAGNVWYQREVFIPKGWAGQRIVLRFDAVTHYGKVWVNNQEVMEHQGGYTPFEADVTPYVIAGKSVRITVCVNNELNWQTIPPGMVITDENGKKKQSYFHDFFNYAGIHRSVMLYTTPNTWVDDITVVTHVAQDCNHASVDWQVVANGDVSVELRDADQQVVATGQGTSGTLQVVNPHLWQPGEGYLYELCVTAKSQTECDIYPLRVGIRSVAVKGEQFLINHKPFYFTGFGRHEDADLRGKGFDNVLMVHDHALMDWIGANSYRTSHYPYAEEMLDWADEHGIVVIDETAAVGFNLSLGIGFEAGNKPKELYSEEAVNGETQQAHLQAIKELIARDKNHPSVVMWSIANEPDTRPQGAREYFAPLAEATRKLDPTRPITCVNVMFCDAHTDTISDLFDVLCLNRYYGWYVQSGDLETAEKVLEKELLAWQEKLHQPIIITEYGVDTLAGLHSMYTDMWSEEYQCAWLDMYHRVFDRVSAVVGEQVWNFADFATSQGILRVGGNKKGIFTRDRKPKSAAFLLQKRWTGMNFGEKPQQGGKQ + + + + + terminator + 7727..7979 + + + 7727 + 7979 + AF485783.1 + + + + + note + NOS + + + + + misc_feature + complement(8621..8646) + + + 8646 + 8621 + + AF485783.1 + + + + + note + T-DNA left border + + + + + misc_feature + complement(9156..10198) + + + 10198 + 9156 + + AF485783.1 + + + + + note + similar to tetA in GenBank Accession Number L13842 + + + + + misc_feature + complement(10199..11680) + + + 11680 + 10199 + + AF485783.1 + + + + + note + similar to trfA in GenBank Accession Number X00713 + + + + + misc_feature + complement(11681..12673) + + + 12673 + 11681 + + AF485783.1 + + + + + note + similar to NPTIII gene in GenBank Accession Number V01547 + + + + + misc_feature + complement(12674..13443) + + + 13443 + 12674 + + AF485783.1 + + + + + note + similar to transposable element IS1 in GenBank Accession Number X58999 + + + + + misc_feature + complement(13444..13794) + + + 13794 + 13444 + + AF485783.1 + + + + + note + similarity to NPT III gene in GenBank Accession Number V01547 + + + + + misc_feature + complement(13795..14066) + + + 14066 + 13795 + + AF485783.1 + + + + + note + similar to kilA in GenBank Accession Number M62846 + + + + + rep_origin + complement(14141..14758) + + + 14758 + 14141 + + AF485783.1 + + + + + note + ori V; similar to sequence in GenBank Accession Number M20134 + + + + + tgagcgtcgcaaaggcgctcggtcttgccttgctcgtcggtgatgtacttcaccagctccgcgaagtcgctcttcttgatggagcgcatggggacgtgcttggcaatcacgcgcaccccccggccgttttagcggctaaaaaagtcatggctctgccctcgggcggaccacgcccatcatgaccttgccaagctcgtcctgcttctcttcgatcttcgccagcagggcgaggatcgtggcatcaccgaaccgcgccgtgcgcgggtcgtcggtgagccagagtttcagcaggccgcccaggcggcccaggtcgccattgatgcgggccagctcgcggacgtgctcatagtccacgacgcccgtgattttgtagccctggccgacggccagcaggtaggccgacaggctcatgccggccgccgccgccttttcctcaatcgctcttcgttcgtctggaaggcagtacaccttgataggtgggctgcccttcctggttggcttggtttcatcagccatccgcttgccctcatctgttacgccggcggtagccggccagcctcgcagagcaggattcccgttgagcaccgccaggtgcgaataagggacagtgaagaaggaacacccgctcgcgggtgggcctacttcacctatcctgcccggctgacgccgttggatacaccaaggaaagtctacacgaaccctttggcaaaatcctgtatatcgtgcgaaaaaggatggatataccgaaaaaatcgctataatgaccccgaagcagggttatgcagcggaaaagcgccacgcttcccgaagggagaaaggcggacaggtatccggtaagcggcagggtcggaacaggagagcgcacgagggagcttccagggggaaacgcctggtatctttatagtcctgtcgggtttcgccacctctgacttgagcgtcgatttttgtgatgctcgtcaggggggcggagcctatggaaaaacgccagcaacgcggcctttttacggttcctggccttttgctggccttttgctcacatgttctttcctgcgttatcccctgattctgtggataaccgtattaccgcctttgagtgagctgataccgctcgccgcagccgaacgaccgagcgcagcgagtcagtgagcgaggaagcggaagagcgccagaaggccgccagagaggccgagcgcggccgtgaggcttggacgctagggcagggcatgaaaaagcccgtagcgggctgctacgggcgtctgacgcggtggaaagggggaggggatgttgtctacatggctctgctgtagtgagtgggttgcgctccggcagcggtcctgatcaatcgtcaccctttctcggtccttcaacgttcctgacaacgagcctccttttcgccaatccatcgacaatcaccgcgagtccctgctcgaacgctgcgtccggaccggcttcgtcgaaggcgtctatcgcggcccgcaacagcggcgagagcggagcctgttcaacggtgccgccgcgctcgccggcatcgctgtcgccggcctgctcctcaagcacggccccaacagtgaagtagctgattgtcatcagcgcattgacggcgtccccggccgaaaaacccgcctcgcagaggaagcgaagctgcgcgtcggccgtttccatctgcggtgcgcccggtcgcgtgccggcatggatgcgcgcgccatcgcggtaggcgagcagcgcctgcctgaagctgcgggcattcccgatcagaaatgagcgccagtcgtcgtcggctctcggcaccgaatgcgtatgattctccgccagcatggcttcggccagtgcgtcgagcagcgcccgcttgttcctgaagtgccagtaaagcgccggctgctgaacccccaaccgttccgccagtttgcgtgtcgtcagaccgtctacgccgacctcgttcaacaggtccagggcggcacggatcactgtattcggctgcaactttgtcatgcttgacactttatcactgataaacataatatgtccaccaacttatcagtgataaagaatccgcgcgttcaatcggaccagcggaggctggtccggaggccagacgtgaaacccaacatacccctgatcgtaattctgagcactgtcgcgctcgacgctgtcggcatcggcctgattatgccggtgctgccgggcctcctgcgcgatctggttcactcgaacgacgtcaccgcccactatggcattctgctggcgctgtatgcgttggtgcaatttgcctgcgcacctgtgctgggcgcgctgtcggatcgtttcgggcggcggccaatcttgctcgtctcgctggccggcgccagatctggggaaccctgtggttggcatgcacatacaaatggacgaacggataaaccttttcacgcccttttaaatatccgattattctaataaacgctcttttctcttaggtttacccgccaatatatcctgtcaaacactgatagtttaaactgaaggcgggaaacgacaatctgatcatgagcggagaattaagggagtcacgttatgacccccgccgatgacgcgggacaagccgttttacgtttggaactgacagaaccgcaacgttgaaggagccactcagccgcgggtttctggagtttaatgagctaagcacatacgtcagaaaccattattgcgcgttcaaaagtcgcctaaggtcactatcagctagcaaatatttcttgtcaaaaatgctccactgacgttccataaattcccctcggtatccaattagagtctcatattcactctcaatccaaataatctgcaccggatctggatcgtttcgcatgattgaacaagatggattgcacgcaggttctccggccgcttgggtggagaggctattcggctatgactgggcacaacagacaatcggctgctctgatgccgccgtgttccggctgtcagcgcaggggcgcccggttctttttgtcaagaccgacctgtccggtgccctgaatgaactgcaggacgaggcagcgcggctatcgtggctggccacgacgggcgttccttgcgcagctgtgctcgacgttgtcactgaagcgggaagggactggctgctattgggcgaagtgccggggcaggatctcctgtcatctcaccttgctcctgccgagaaagtatccatcatggctgatgcaatgcggcggctgcatacgcttgatccggctacctgcccattcgaccaccaagcgaaacatcgcatcgagcgagcacgtactcggatggaagccggtcttgtcgatcaggatgatctggacgaagagcatcaggggctcgcgccagccgaactgttcgccaggctcaaggcgcgcatgcccgacggcgatgatctcgtcgtgacccatggcgatgcctgcttgccgaatatcatggtggaaaatggccgcttttctggattcatcgactgtggccggctgggtgtggcggaccgctatcaggacatagcgttggctacccgtgatattgctgaagagcttggcggcgaatgggctgaccgcttcctcgtgctttacggtatcgccgctcccgattcgcagcgcatcgccttctatcgccttcttgacgagttcttctgagcgggactctggggttcgaaatgaccgaccaagcgacgcccaacctgccatcacgagatttcgattccaccgccgccttctatgaaaggttgggcttcggaatcgttttccgggacgccggctggatgatcctccagcgcggggatctcatgctggagttcttcgcccacgggatctctgcggaacaggcggtcgaaggtgccgatatcattacgacagcaacggccgacaagcacaacgccacgatcctgagcgacaatatgatcgggcccggcgtccacatcaacggcgtcggcggcgactgcccaggcaagaccgagatgcaccgcgatatcttgctgcgttcggatattttcgtggagttcccgccacagacccggatgatccccgatcgttcaaacatttggcaataaagtttcttaagattgaatcctgttgccggtcttgcgatgattatcatataatttctgttgaattacgttaagcatgtaataattaacatgtaatgcatgacgttatttatgagatgggtttttatgattagagtcccgcaattatacatttaatacgcgatagaaaacaaaatatagcgcgcaaactaggataaattatcgcgcgcggtgtcatctatgttactagatcgggcctcctgtcaatgctggcggcggctctggtggtggttctggtggcggctctgagggtggtggctctgagggtggcggttctgagggtggcggctctgagggaggcggttccggtggtggctctggttccggtgattttgattatgaaaagatggcaaacgctaataagggggctatgaccgaaaatgccgatgaaaacgcgctacagtctgacgctaaaggcaaacttgattctgtcgctactgattacggtgctgctatcgatggtttcattggtgacgtttccggccttgctaatggtaatggtgctactggtgattttgctggctctaattcccaaatggctcaagtcggtgacggtgataattcacctttaatgaataatttccgtcaatatttaccttccctccctcaatcggttgaatgtcgcccttttgtctttggcccaatacgcaaaccgcctctccccgcgcgttggccgattcattaatgcagctggcacgacaggtttcccgactggaaagcgggcagtgagcgcaacgcaattaatgtgagttagctcactcattaggcaccccaggctttacactttatgcttccggctcgtatgttgtgtggaattgtgagcggataacaatttcacacaggaaacagctatgaccatgattacgccaagcttgcatgcctgcaggtccccagattagccttttcaatttcagaaagaatgctaacccacagatggttagagaggcttacgcagcaggtctcatcaagacgatctacccgagcaataatctccaggaaatcaaataccttcccaagaaggttaaagatgcagtcaaaagattcaggactaactgcatcaagaacacagagaaagatatatttctcaagatcagaagtactattccagtatggacgattcaaggcttgcttcacaaaccaaggcaagtaatagagattggagtctctaaaaaggtagttcccactgaatcaaaggccatggagtcaaagattcaaatagaggacctaacagaactcgccgtaaagactggcgaacagttcatacagagtctcttacgactcaatgacaagaagaaaatcttcgtcaacatggtggagcacgacacacttgtctactccaaaaatatcaaagatacagtctcagaagaccaaagggcaattgagacttttcaacaaagggtaatatccggaaacctcctcggattccattgcccagctatctgtcactttattgtgaagatagtggaaaaggaaggtggctcctacaaatgccatcattgcgataaaggaaaggccatcgttgaagatgcctctgccgacagtggtcccaaagatggacccccacccacgaggagcatcgtggaaaaagaagacgttccaaccacgtcttcaaagcaagtggattgatgtgatatctccactgacgtaagggatgacgcacaatcccactatccttcgcaagacccttcctctatataaggaagttcatttcatttggagagaacacgggggactctagaggatccccgggtggtcagtcccttatgttacgtcctgtagaaaccccaacccgtgaaatcaaaaaactcgacggcctgtgggcattcagtctggatcgcgaaaactgtggaattgatcagcgttggtgggaaagcgcgttacaagaaagccgggcaattgctgtgccaggcagttttaacgatcagttcgccgatgcagatattcgtaattatgcgggcaacgtctggtatcagcgcgaagtctttataccgaaaggttgggcaggccagcgtatcgtgctgcgtttcgatgcggtcactcattacggcaaagtgtgggtcaataatcaggaagtgatggagcatcagggcggctatacgccatttgaagccgatgtcacgccgtatgttattgccgggaaaagtgtacgtatcaccgtttgtgtgaacaacgaactgaactggcagactatcccgccgggaatggtgattaccgacgaaaacggcaagaaaaagcagtcttacttccatgatttctttaactatgccggaatccatcgcagcgtaatgctctacaccacgccgaacacctgggtggacgatatcaccgtggtgacgcatgtcgcgcaagactgtaaccacgcgtctgttgactggcaggtggtggccaatggtgatgtcagcgttgaactgcgtgatgcggatcaacaggtggttgcaactggacaaggcactagcgggactttgcaagtggtgaatccgcacctctggcaaccgggtgaaggttatctctatgaactgtgcgtcacagccaaaagccagacagagtgtgatatctacccgcttcgcgtcggcatccggtcagtggcagtgaagggcgaacagttcctgattaaccacaaaccgttctactttactggctttggtcgtcatgaagatgcggacttgcgtggcaaaggattcgataacgtgctgatggtgcacgaccacgcattaatggactggattggggccaactcctaccgtacctcgcattacccttacgctgaagagatgctcgactgggcagatgaacatggcatcgtggtgattgatgaaactgctgctgtcggctttaacctctctttaggcattggtttcgaagcgggcaacaagccgaaagaactgtacagcgaagaggcagtcaacggggaaactcagcaagcgcacttacaggcgattaaagagctgatagcgcgtgacaaaaaccacccaagcgtggtgatgtggagtattgccaacgaaccggatacccgtccgcaaggtgcacgggaatatttcgcgccactggcggaagcaacgcgtaaactcgacccgacgcgtccgatcacctgcgtcaatgtaatgttctgcgacgctcacaccgataccatcagcgatctctttgatgtgctgtgcctgaaccgttattacggatggtatgtccaaagcggcgatttggaaacggcagagaaggtactggaaaaagaacttctggcctggcaggagaaactgcatcagccgattatcatcaccgaatacggcgtggatacgttagccgggctgcactcaatgtacaccgacatgtggagtgaagagtatcagtgtgcatggctggatatgtatcaccgcgtctttgatcgcgtcagcgccgtcgtcggtgaacaggtatggaatttcgccgattttgcgacctcgcaaggcatattgcgcgttggcggtaacaagaaagggatcttcactcgcgaccgcaaaccgaagtcggcggcttttctgctgcaaaaacgctggactggcatgaacttcggtgaaaaaccgcagcagggaggcaaacaatgaatcaacaactctcctggcgcaccatcgtcggctacagcctcgggaattgctaccgagctcgaatttccccgatcgttcaaacatttggcaataaagtttcttaagattgaatcctgttgccggtcttgcgatgattatcatataatttctgttgaattacgttaagcatgtaataattaacatgtaatgcatgacgttatttatgagatgggtttttatgattagagtcccgcaattatacatttaatacgcgatagaaaacaaaatatagcgcgcaaactaggataaattatcgcgcgcggtgtcatctatgttactagatcgggaattcactggccgtcgttttacaacgtcgtgactgggaaaaccctggcgttacccaacttaatcgccttgcagcacatccccctttcgccagctggcgtaatagcgaagaggcccgcaccgatcgcccttcccaacagttgcgcagcctgaatggcgcccgctcctttcgctttcttcccttcctttctcgccacgttcgccggctttccccgtcaagctctaaatcgggggctccctttagggttccgatttagtgctttacggcacctcgaccccaaaaaacttgatttgggtgatggttcacgtagtgggccatcgccctgatagacggtttttcgccctttgacgttggagtccacgttctttaatagtggactcttgttccaaactggaacaacactcaaccctatctcgggctattcttttgatttataagggattttgccgatttcggaaccaccatcaaacaggattttcgcctgctggggcaaaccagcgtggaccgcttgctgcaactctctcagggccaggcggtgaagggcaatcagctgttgcccgtctcactggtgaaaagaaaaaccaccccagtacattaaaaacgtccgcaatgtgttattaagttgtctaagcgtcaatttgtttacaccacaatatatcctgccaccagccagccaacagctccccgaccggcagctcggcacaaaatcaccactcgatacaggcagcccatcagtccgggacggcgtcagcgggagagccgttgtaaggcggcagactttgctcatgttaccgatgctattcggaagaacggcaactaagctgccgggtttgaaacacggatgatctcgcggagggtagcatgttgattgtaacgatgacagagcgttgctgcctgtgatcaaatatcatctccctcgcagagatccgaattatcagccttcttattcatttctcgcttaaccgtgacaggctgtcgatcttgagaactatgccgacataataggaaatcgctggataaagccgctgaggaagctgagtggcgctatttctttagaagtgaacgttgacgatatcaactcccctatccattgctcaccgaatggtacaggtcggggacccgaagttccgactgtcggcctgatgcatccccggctgatcgaccccagatctggggctgagaaagcccagtaaggaaacaactgtaggttcgagtcgcgagatcccccggaaccaaaggaagtaggttaaacccgctccgatcaggccgagccacgccaggccgagaacattggttcctgtaggcatcgggattggcggatcaaacactaaagctactggaacgagcagaagtcctccggccgccagttgccaggcggtaaaggtgagcagaggcacgggaggttgccacttgcgggtcagcacggttccgaacgccatggaaaccgcccccgccaggcccgctgcgacgccgacaggatctagcgctgcgtttggtgtcaacaccaacagcgccacgcccgcagttccgcaaatagcccccaggaccgccatcaatcgtatcgggctacctagcagagcggcagagatgaacacgaccatcagcggctgcacagcgcctaccgtcgccgcgaccccgcccggcaggcggtagaccgaaataaacaacaagctccagaatagcgaaatattaagtgcgccgaggatgaagatgcgcatccaccagattcccgttggaatctgtcggacgatcatcacgagcaataaacccgccggcaacgcccgcagcagcataccggcgacccctcggcctcgctgttcgggctccacgaaaacgccggacagatgcgccttgtgagcgtccttggggccgtcctcctgtttgaagaccgacagcccaatgatctcgccgtcgatgtaggcgccgaatgccacggcatctcgcaaccgttcagcgaacgcctccatgggctttttctcctcgtgctcgtaaacggacccgaacatctctggagctttcttcagggccgacaatcggatctcgcggaaatcctgcacgtcggccgctccaagccgtcgaatctgagccttaatcacaattgtcaattttaatcctctgtttatcggcagttcgtagagcgcgccgtgcgtcccgagcgatactgagcgaagcaagtgcgtcgagcagtgcccgcttgttcctgaaatgccagtaaagcgctggctgctgaacccccagccggaactgaccccacaaggccctagcgtttgcaatgcaccaggtcatcattgacccaggcgtgttccaccaggccgctgcctcgcaactcttcgcaggcttcgccgacctgctcgcgccacttcttcacgcgggtggaatccgatccgcacatgaggcggaaggtttccagcttgagcgggtacggctcccggtgcgagctgaaatagtcgaacatccgtcgggccgtcggcgacagcttgcggtacttctcccatatgaatttcgtgtagtggtcgccagcaaacagcacgacgatttcctcgtcgatcaggacctggcaacgggacgttttcttgccacggtccaggacgcggaagcggtgcagcagcgacaccgattccaggtgcccaacgcggtcggacgtgaagcccatcgccgtcgcctgtaggcgcgacaggcattcctcggccttcgtgtaataccggccattgatcgaccagcccaggtcctggcaaagctcgtagaacgtgaaggtgatcggctcgccgataggggtgcgcttcgcgtactccaacacctgctgccacaccagttcgtcatcgtcggcccgcagctcgacgccggtgtaggtgatcttcacgtccttgttgacgtggaaaatgaccttgttttgcagcgcctcgcgcgggattttcttgttgcgcgtggtgaacagggcagagcgggccgtgtcgtttggcatcgctcgcatcgtgtccggccacggcgcaatatcgaacaaggaaagctgcatttccttgatctgctgcttcgtgtgtttcagcaacgcggcctgcttggcctcgctgacctgttttgccaggtcctcgccggcggtttttcgcttcttggtcgtcatagttcctcgcgtgtcgatggtcatcgacttcgccaaacctgccgcctcctgttcgagacgacgcgaacgctccacggcggccgatggcgcgggcagggcagggggagccagttgcacgctgtcgcgctcgatcttggccgtagcttgctggaccatcgagccgacggactggaaggtttcgcggggcgcacgcatgacggtgcggcttgcgatggtttcggcatcctcggcggaaaaccccgcgtcgatcagttcttgcctgtatgccttccggtcaaacgtccgattcattcaccctccttgcgggattgccccgactcacgccggggcaatgtgcccttattcctgatttgacccgcctggtgccttggtgtccagataatccaccttatcggcaatgaagtcggtcccgtagaccgtctggccgtccttctcgtacttggtattccgaatcttgccctgcacgaataccagcgaccccttgcccaaatacttgccgtgggcctcggcctgagagccaaaacacttgatgcggaagaagtcggtgcgctcctgcttgtcgccggcatcgttgcgccacatctaggtactaaaacaattcatccagtaaaatataatattttattttctcccaatcaggcttgatccccagtaagtcaaaaaatagctcgacatactgttcttccccgatatcctccctgatcgaccggacgcagaaggcaatgtcataccacttgtccgccctgccgcttctcccaagatcaataaagccacttactttgccatctttcacaaagatgttgctgtctcccaggtcgccgtgggaaaagacaagttcctcttcgggcttttccgtctttaaaaaatcatacagctcgcgcggatctttaaatggagtgtcttcttcccagttttcgcaatccacatcggccagatcgttattcagtaagtaatccaattcggctaagcggctgtctaagctattcgtatagggacaatccgatatgtcgatggagtgaaagagcctgatgcactccgcatacagctcgataatcttttcagggctttgttcatcttcatactcttccgagcaaaggacgccatcggcctcactcatgagcagattgctccagccatcatgccgttcaaagtgcaggacctttggaacaggcagctttccttccagccatagcatcatgtccttttcccgttccacatcataggtggtccctttataccggctgtccgtcatttttaaatataggttttcattttctcccaccagcttatataccttagcaggagacattccttccgtatcttttacgcagcggtatttttcgatcagttttttcaattccggtgatattctcattttagccatttattatttccttcctcttttctacagtatttaaagataccccaagaagctaattataacaagacgaactccaattcactgttccttgcattctaaaaccttaaataccagaaaacagctttttcaaagttgttttcaaagttggcgtataacatagtatcgacggagccgattttgaaaccacaattatgggtgatgctgccaacttactgatttagtgtatgatggtgtttttgaggtgctccagtggcttctgtgtctatcagctgtccctcctgttcagctactgacggggtggtgcgtaacggcaaaagcaccgccggacatcagcgctatctctgctctcactgccgtaaaacatggcaactgcagttcacttacaccgcttctcaacccggtacgcaccagaaaatcattgatatggccatgaatggcgttggatgccgggcaacagcccgcattatgggcgttggcctcaacacgattttacgtcacttaaaaaactcaggccgcagtcggtaacctcgcgcatacagccgggcagtgacgtcatcgtctgcgcggaaatggacgaacagtggggctatgtcggggctaaatcgcgccagcgctggctgttttacgcgtatgacagtctccggaagacggttgttgcgcacgtattcggtgaacgcactatggcgacgctggggcgtcttatgagcctgctgtcaccctttgacgtggtgatatggatgacggatggctggccgctgtatgaatcccgcctgaagggaaagctgcacgtaatcagcaagcgatatacgcagcgaattgagcggcataacctgaatctgaggcagcacctggcacggctgggacggaagtcgctgtcgttctcaaaatcggtggagctgcatgacaaagtcatcgggcattatctgaacataaaacactatcaataagttggagtcattacccaattatgatagaatttacaagctataaggttattgtcctgggtttcaagcattagtccatgcaagtttttatgctttgcccattctatagatatattgataagcgcgctgcctatgccttgccccctgaaatccttacatacggcgatatcttctatataaaagatatattatcttatcagtattgtcaatatattcaaggcaatctgcctcctcatcctcttcatcctcttcgtcttggtagctttttaaatatggcgcttcatagagtaattctgtaaaggtccaattctcgttttcatacctcggtataatcttacctatcacctcaaatggttcgctgggtttatcgcacccccgaacacgagcacggcacccgcgaccactatgccaagaatgcccaaggtaaaaattgccggccccgccatgaagtccgtgaatgccccgacggccgaagtgaagggcaggccgccacccaggccgccgccctcactgcccggcacctggtcgctgaatgtcgatgccagcacctgcggcacgtcaatgcttccgggcgtcgcgctcgggctgatcgcccatcccgttactgccccgatcccggcaatggcaaggactgccagcgctgccatttttggggtgaggccgttcgcggccgaggggcgcagcccctggggggatgggaggcccgcgttagcgggccgggagggttcgagaagggggggcaccccccttcggcgtgcgcggtcacgcgcacagggcgcagccctggttaaaaacaaggtttataaatattggtttaaaagcaggttaaaagacaggttagcggtggccgaaaaacgggcggaaacccttgcaaatgctggattttctgcctgtggacagcccctcaaatgtcaataggtgcgcccctcatctgtcagcactctgcccctcaagtgtcaaggatcgcgcccctcatctgtcagtagtcgcgcccctcaagtgtcaataccgcagggcacttatccccaggcttgtccacatcatctgtgggaaactcgcgtaaaatcaggcgttttcgccgatttgcgaggctggccagctccacgtcgccggccgaaatcgagcctgcccctcatctgtcaacgccgcgccgggtgagtcggcccctcaagtgtcaacgtccgcccctcatctgtcagtgagggccaagttttccgcgaggtatccacaacgccggcggccgcggtgtctcgcacacggcttcgacggcgtttctggcgcgtttgcagggccatagacggccgccagcccagcggcgagggcaaccagcccgg + + + + diff --git a/platforms/android/assets/www/node_modules/xml2js/x.js b/platforms/android/assets/www/node_modules/xml2js/x.js new file mode 100644 index 0000000..b51ce57 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xml2js/x.js @@ -0,0 +1,24 @@ +var util = require('util'); +var xml2js = require('xml2js'); + +var myxml = " \ + \ + \ + 1 \ + green \ + \ + \ + 2 \ + red \ + \ + \ + 3 \ + yellow \ + \ +" + +xml2js.parseString(myxml, function (e, r) { + console.log(util.inspect(r, false, null)); + console.log(new xml2js.Builder().buildObject(r)); +}); + diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/.npmignore b/platforms/android/assets/www/node_modules/xmlbuilder/.npmignore new file mode 100644 index 0000000..b6ad1f6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/.npmignore @@ -0,0 +1,5 @@ +.travis.yml +src +test +perf +coverage diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/CHANGELOG.md b/platforms/android/assets/www/node_modules/xmlbuilder/CHANGELOG.md new file mode 100644 index 0000000..86f1e94 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/CHANGELOG.md @@ -0,0 +1,329 @@ +# Change Log + +## [5.0.0] - 2016-03-05 +- Added text case option for element names and attribute names. Valid cases are `lower`, `upper`, `camel`, `kebab` and `snake`. +- Attribute and element values are escaped according to the [Canonical XML 1.0 specification](http://www.w3.org/TR/2000/WD-xml-c14n-20000119.html#charescaping). See [#54](https://github.com/oozcitak/xmlbuilder-js/issues/54) and [#86](https://github.com/oozcitak/xmlbuilder-js/issues/86). +- Added the `allowEmpty` option to `end()`. When this option is set, empty elements are not self-closed. +- Added support for [nested CDATA](https://en.wikipedia.org/wiki/CDATA#Nesting). The triad `]]>` in CDATA is now automatically replaced with `]]]]>`. + +## [4.2.1] - 2016-01-15 +- Updated lodash dependency to 4.0.0. + +## [4.2.0] - 2015-12-16 +- Added the `noDoubleEncoding` option to `create()` to control whether existing html entities are encoded. + +## [4.1.0] - 2015-11-11 +- Added the `separateArrayItems` option to `create()` to control how arrays are handled when converting from objects. e.g. + +```js +root.ele({ number: [ "one", "two" ]}); +// with separateArrayItems: true + + + + +// with separateArrayItems: false +one +two +``` + +## [4.0.0] - 2015-11-01 +- Removed the `#list` decorator. Array items are now created as child nodes by default. +- Fixed a bug where the XML encoding string was checked partially. + +## [3.1.0] - 2015-09-19 +- `#list` decorator ignores empty arrays. + +## [3.0.0] - 2015-09-10 +- Allow `\r`, `\n` and `\t` in attribute values without escaping. See [#86](https://github.com/oozcitak/xmlbuilder-js/issues/86). + +## [2.6.5] - 2015-09-09 +- Use native `isArray` instead of lodash. +- Indentation of processing intructions are set to the parent element's. + +## [2.6.4] - 2015-05-27 +- Updated lodash dependency to 3.5.0. + +## [2.6.3] - 2015-05-27 +- Bumped version because previous release was not published on npm. + +## [2.6.2] - 2015-03-10 +- Updated lodash dependency to 3.5.0. + +## [2.6.1] - 2015-02-20 +- Updated lodash dependency to 3.3.0. + +## [2.6.0] - 2015-02-20 +- Fixed a bug where the `XMLNode` constructor overwrote the super class parent. +- Removed document property from cloned nodes. +- Switched to mocha.js for testing. + +## [2.5.2] - 2015-02-16 +- Updated lodash dependency to 3.2.0. + +## [2.5.1] - 2015-02-09 +- Updated lodash dependency to 3.1.0. +- Support all node >= 0.8. + +## [2.5.0] - 2015-00-03 +- Updated lodash dependency to 3.0.0. + +## [2.4.6] - 2015-01-26 +- Show more information from attribute creation with null values. +- Added iojs as an engine. +- Self close elements with empty text. + +## [2.4.5] - 2014-11-15 +- Fixed prepublish script to run on windows. +- Fixed bug in XMLStringifier where an undefined value was used while reporting an invalid encoding value. +- Moved require statements to the top of files to reduce CPU usage from lazy requires. See [#62](https://github.com/oozcitak/xmlbuilder-js/issues/62). + +## [2.4.4] - 2014-09-08 +- Added the `offset` option to `toSTring()` for use in XML fragments. + +## [2.4.3] - 2014-08-13 +- Corrected license in package description. + +## [2.4.2] - 2014-08-13 +- Dropped performance test and memwatch dependency. + +## [2.4.1] - 2014-08-12 +- Fixed a bug where empty indent string was omitted when pretty printing. See [#59](https://github.com/oozcitak/xmlbuilder-js/issues/59). + +## [2.4.0] - 2014-08-04 +- Correct cases of pubID and sysID. +- Use single lodash instead of seperate npm modules. See [#53](https://github.com/oozcitak/xmlbuilder-js/issues/53). +- Escape according to Canonical XML 1.0. See [#54](https://github.com/oozcitak/xmlbuilder-js/issues/54). + +## [2.3.0] - 2014-07-17 +- Convert objects to JS primitives while sanitizing user input. +- Object builder preserves items with null values. See [#44](https://github.com/oozcitak/xmlbuilder-js/issues/44). +- Use modularized lodash functions to cut down dependencies. +- Process empty objects when converting from objects so that we don't throw on empty child objects. + +## [2.2.1] - 2014-04-04 +- Bumped version because previous release was not published on npm. + +## [2.2.0] - 2014-04-04 +- Switch to lodash from underscore. +- Removed legacy `ext` option from `create()`. +- Drop old node versions: 0.4, 0.5, 0.6. 0.8 is the minimum requirement from now on. + +## [2.1.0] - 2013-12-30 +- Removed duplicate null checks from constructors. +- Fixed node count in performance test. +- Added option for skipping null attribute values. See [#26](https://github.com/oozcitak/xmlbuilder-js/issues/26). +- Allow multiple values in `att()` and `ins()`. +- Added ability to run individual performance tests. +- Added flag for ignoring decorator strings. + +## [2.0.1] - 2013-12-24 +- Removed performance tests from npm package. + +## [2.0.0] - 2013-12-24 +- Combined loops for speed up. +- Added support for the DTD and XML declaration. +- `clone` includes attributes. +- Added performance tests. +- Evaluate attribute value if function. +- Evaluate instruction value if function. + +## [1.1.2] - 2013-12-11 +- Changed processing instruction decorator to `?`. + +## [1.1.1] - 2013-12-11 +- Added processing instructions to JS object conversion. + +## [1.1.0] - 2013-12-10 +- Added license to package. +- `create()` and `element()` accept JS object to fully build the document. +- Added `nod()` and `n()` aliases for `node()`. +- Renamed `convertAttChar` decorator to `convertAttKey`. +- Ignore empty decorator strings when converting JS objects. + +## [1.0.2] - 2013-11-27 +- Removed temp file which was accidentally included in the package. + +## [1.0.1] - 2013-11-27 +- Custom stringify functions affect current instance only. + +## [1.0.0] - 2013-11-27 +- Added processing instructions. +- Added stringify functions to sanitize and convert input values. +- Added option for headless XML documents. +- Added vows tests. +- Removed Makefile. Using npm publish scripts instead. +- Removed the `begin()` function. `create()` begins the document by creating the root node. + +## [0.4.3] - 2013-11-08 +- Added option to include surrogate pairs in XML content. See [#29](https://github.com/oozcitak/xmlbuilder-js/issues/29). +- Fixed empty value string representation in pretty mode. +- Added pre and postpublish scripts to package.json. +- Filtered out prototype properties when appending attributes. See [#31](https://github.com/oozcitak/xmlbuilder-js/issues/31). + +## [0.4.2] - 2012-09-14 +- Removed README.md from `.npmignore`. + +## [0.4.1] - 2012-08-31 +- Removed `begin()` calls in favor of `XMLBuilder` constructor. +- Added the `end()` function. `end()` is a convenience over `doc().toString()`. + +## [0.4.0] - 2012-08-31 +- Added arguments to `XMLBuilder` constructor to allow the name of the root element and XML prolog to be defined in one line. +- Soft deprecated `begin()`. + +## [0.3.11] - 2012-08-13 +- Package keywords are fixed to be an array of values. + +## [0.3.10] - 2012-08-13 +- Brought back npm package contents which were lost due to incorrect configuration of `package.json` in previous releases. + +## [0.3.3] - 2012-07-27 +- Implemented `importXMLBuilder()`. + +## [0.3.2] - 2012-07-20 +- Fixed a duplicated escaping problem on `element()`. +- Fixed a problem with text node creation from empty string. +- Calling `root()` on the document element returns the root element. +- `XMLBuilder` no longer extends `XMLFragment`. + +## [0.3.1] - 2011-11-28 +- Added guards for document element so that nodes cannot be inserted at document level. + +## [0.3.0] - 2011-11-28 +- Added `doc()` to return the document element. + +## [0.2.2] - 2011-11-28 +- Prevent code relying on `up()`'s older behavior to break. + +## [0.2.1] - 2011-11-28 +- Added the `root()` function. + +## [0.2.0] - 2011-11-21 +- Added Travis-CI integration. +- Added coffee-script dependency. +- Added insert, traversal and delete functions. + +## [0.1.7] - 2011-10-25 +- No changes. Accidental release. + +## [0.1.6] - 2011-10-25 +- Corrected `package.json` bugs link to `url` from `web`. + +## [0.1.5] - 2011-08-08 +- Added missing npm package contents. + +## [0.1.4] - 2011-07-29 +- Text-only nodes are no longer indented. +- Added documentation for multiple instances. + +## [0.1.3] - 2011-07-27 +- Exported the `create()` function to return a new instance. This allows multiple builder instances to be constructed. +- Fixed `u()` function so that it now correctly calls `up()`. +- Fixed typo in `element()` so that `attributes` and `text` van be passes interchangeably. + +## [0.1.2] - 2011-06-03 +- `ele()` accepts element text. +- `attributes()` now overrides existing attributes if passed the same attribute name. + +## [0.1.1] - 2011-05-19 +- Added the raw output option. +- Removed most validity checks. + +## [0.1.0] - 2011-04-27 +- `text()` and `cdata()` now return parent element. +- Attribute values are escaped. + +## [0.0.7] - 2011-04-23 +- Coerced text values to string. + +## [0.0.6] - 2011-02-23 +- Added support for XML comments. +- Text nodes are checked against CharData. + +## [0.0.5] - 2010-12-31 +- Corrected the name of the main npm module in `package.json`. + +## [0.0.4] - 2010-12-28 +- Added `.npmignore`. + +## [0.0.3] - 2010-12-27 +- root element is now constructed in `begin()`. +- moved prolog to `begin()`. +- Added the ability to have CDATA in element text. +- Removed unused prolog aliases. +- Removed `builder()` function from main module. +- Added the name of the main npm module in `package.json`. + +## [0.0.2] - 2010-11-03 +- `element()` expands nested arrays. +- Added pretty printing. +- Added the `up()`, `build()` and `prolog()` functions. +- Added readme. + +## 0.0.1 - 2010-11-02 +- Initial release + +[5.0.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v4.2.1...v5.0.0 +[4.2.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v4.2.0...v4.2.1 +[4.2.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v4.1.0...v4.2.0 +[4.1.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v4.0.0...v4.1.0 +[4.0.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v3.1.0...v4.0.0 +[3.1.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v3.0.0...v3.1.0 +[3.0.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.5...v3.0.0 +[2.6.5]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.4...v2.6.5 +[2.6.4]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.3...v2.6.4 +[2.6.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.2...v2.6.3 +[2.6.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.1...v2.6.2 +[2.6.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.0...v2.6.1 +[2.6.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.5.2...v2.6.0 +[2.5.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.5.1...v2.5.2 +[2.5.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.5.0...v2.5.1 +[2.5.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.6...v2.5.0 +[2.4.6]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.5...v2.4.6 +[2.4.5]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.4...v2.4.5 +[2.4.4]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.3...v2.4.4 +[2.4.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.2...v2.4.3 +[2.4.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.1...v2.4.2 +[2.4.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.0...v2.4.1 +[2.4.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.3.0...v2.4.0 +[2.3.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.2.1...v2.3.0 +[2.2.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.2.0...v2.2.1 +[2.2.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.1.0...v2.2.0 +[2.1.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.0.1...v2.1.0 +[2.0.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.0.0...v2.0.1 +[2.0.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.1.2...v2.0.0 +[1.1.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.1.1...v1.1.2 +[1.1.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.1.0...v1.1.1 +[1.1.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.0.2...v1.1.0 +[1.0.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.0.1...v1.0.2 +[1.0.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.0.0...v1.0.1 +[1.0.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.4.3...v1.0.0 +[0.4.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.4.2...v0.4.3 +[0.4.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.4.1...v0.4.2 +[0.4.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.4.0...v0.4.1 +[0.4.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.11...v0.4.0 +[0.3.11]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.10...v0.3.11 +[0.3.10]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.3...v0.3.10 +[0.3.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.2...v0.3.3 +[0.3.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.1...v0.3.2 +[0.3.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.0...v0.3.1 +[0.3.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.2.2...v0.3.0 +[0.2.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.2.1...v0.2.2 +[0.2.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.2.0...v0.2.1 +[0.2.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.7...v0.2.0 +[0.1.7]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.6...v0.1.7 +[0.1.6]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.5...v0.1.6 +[0.1.5]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.4...v0.1.5 +[0.1.4]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.3...v0.1.4 +[0.1.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.2...v0.1.3 +[0.1.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.1...v0.1.2 +[0.1.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.0...v0.1.1 +[0.1.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.7...v0.1.0 +[0.0.7]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.6...v0.0.7 +[0.0.6]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.5...v0.0.6 +[0.0.5]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.4...v0.0.5 +[0.0.4]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.3...v0.0.4 +[0.0.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.2...v0.0.3 +[0.0.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.1...v0.0.2 + diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/LICENSE b/platforms/android/assets/www/node_modules/xmlbuilder/LICENSE new file mode 100644 index 0000000..e7cbac9 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Ozgur Ozcitak + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/README.md b/platforms/android/assets/www/node_modules/xmlbuilder/README.md new file mode 100644 index 0000000..13a5b12 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/README.md @@ -0,0 +1,86 @@ +# xmlbuilder-js + +An XML builder for [node.js](https://nodejs.org/) similar to +[java-xmlbuilder](https://github.com/jmurty/java-xmlbuilder). + +[![License](http://img.shields.io/npm/l/xmlbuilder.svg?style=flat-square)](http://opensource.org/licenses/MIT) +[![NPM Version](http://img.shields.io/npm/v/xmlbuilder.svg?style=flat-square)](https://npmjs.com/package/xmlbuilder) +[![NPM Downloads](https://img.shields.io/npm/dm/xmlbuilder.svg?style=flat-square)](https://npmjs.com/package/xmlbuilder) + +[![Build Status](http://img.shields.io/travis/oozcitak/xmlbuilder-js.svg?style=flat-square)](http://travis-ci.org/oozcitak/xmlbuilder-js) +[![Dependency Status](http://img.shields.io/david/oozcitak/xmlbuilder-js.svg?style=flat-square)](https://david-dm.org/oozcitak/xmlbuilder-js) +[![Dev Dependency Status](http://img.shields.io/david/dev/oozcitak/xmlbuilder-js.svg?style=flat-square)](https://david-dm.org/oozcitak/xmlbuilder-js) +[![Code Coverage](https://img.shields.io/coveralls/oozcitak/xmlbuilder-js.svg?style=flat-square)](https://coveralls.io/github/oozcitak/xmlbuilder-js) + +### Installation: + +``` sh +npm install xmlbuilder +``` + +### Usage: + +``` js +var builder = require('xmlbuilder'); +var xml = builder.create('root') + .ele('xmlbuilder') + .ele('repo', {'type': 'git'}, 'git://github.com/oozcitak/xmlbuilder-js.git') + .end({ pretty: true}); + +console.log(xml); +``` + +will result in: + +``` xml + + + + git://github.com/oozcitak/xmlbuilder-js.git + + +``` + +It is also possible to convert objects into nodes: + +``` js +builder.create({ + root: { + xmlbuilder: { + repo: { + '@type': 'git', // attributes start with @ + '#text': 'git://github.com/oozcitak/xmlbuilder-js.git' // text node + } + } + } +}); +``` + +If you need to do some processing: + +``` js +var root = builder.create('squares'); +root.com('f(x) = x^2'); +for(var i = 1; i <= 5; i++) +{ + var item = root.ele('data'); + item.att('x', i); + item.att('y', i * i); +} +``` + +This will result in: + +``` xml + + + + + + + + + +``` + +See the [wiki](https://github.com/oozcitak/xmlbuilder-js/wiki) for details. diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLAttribute.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLAttribute.js new file mode 100644 index 0000000..f6c6bd8 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLAttribute.js @@ -0,0 +1,32 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLAttribute, create; + + create = require('lodash/create'); + + module.exports = XMLAttribute = (function() { + function XMLAttribute(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing attribute name of element " + parent.name); + } + if (value == null) { + throw new Error("Missing attribute value for attribute " + name + " of element " + parent.name); + } + this.name = this.stringify.attName(name); + this.value = this.stringify.attValue(value); + } + + XMLAttribute.prototype.clone = function() { + return create(XMLAttribute.prototype, this); + }; + + XMLAttribute.prototype.toString = function(options, level) { + return ' ' + this.name + '="' + this.value + '"'; + }; + + return XMLAttribute; + + })(); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLBuilder.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLBuilder.js new file mode 100644 index 0000000..4282833 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLBuilder.js @@ -0,0 +1,69 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLBuilder, XMLDeclaration, XMLDocType, XMLElement, XMLStringifier; + + XMLStringifier = require('./XMLStringifier'); + + XMLDeclaration = require('./XMLDeclaration'); + + XMLDocType = require('./XMLDocType'); + + XMLElement = require('./XMLElement'); + + module.exports = XMLBuilder = (function() { + function XMLBuilder(name, options) { + var root, temp; + if (name == null) { + throw new Error("Root element needs a name"); + } + if (options == null) { + options = {}; + } + this.options = options; + this.stringify = new XMLStringifier(options); + temp = new XMLElement(this, 'doc'); + root = temp.element(name); + root.isRoot = true; + root.documentObject = this; + this.rootObject = root; + if (!options.headless) { + root.declaration(options); + if ((options.pubID != null) || (options.sysID != null)) { + root.doctype(options); + } + } + } + + XMLBuilder.prototype.root = function() { + return this.rootObject; + }; + + XMLBuilder.prototype.end = function(options) { + return this.toString(options); + }; + + XMLBuilder.prototype.toString = function(options) { + var indent, newline, offset, pretty, r, ref, ref1, ref2; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + r = ''; + if (this.xmldec != null) { + r += this.xmldec.toString(options); + } + if (this.doctype != null) { + r += this.doctype.toString(options); + } + r += this.rootObject.toString(options); + if (pretty && r.slice(-newline.length) === newline) { + r = r.slice(0, -newline.length); + } + return r; + }; + + return XMLBuilder; + + })(); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLCData.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLCData.js new file mode 100644 index 0000000..c171a28 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLCData.js @@ -0,0 +1,49 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLNode, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLCData = (function(superClass) { + extend(XMLCData, superClass); + + function XMLCData(parent, text) { + XMLCData.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing CDATA text"); + } + this.text = this.stringify.cdata(text); + } + + XMLCData.prototype.clone = function() { + return create(XMLCData.prototype, this); + }; + + XMLCData.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLCData; + + })(XMLNode); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLComment.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLComment.js new file mode 100644 index 0000000..ca801f6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLComment.js @@ -0,0 +1,49 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLComment, XMLNode, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLComment = (function(superClass) { + extend(XMLComment, superClass); + + function XMLComment(parent, text) { + XMLComment.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing comment text"); + } + this.text = this.stringify.comment(text); + } + + XMLComment.prototype.clone = function() { + return create(XMLComment.prototype, this); + }; + + XMLComment.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLComment; + + })(XMLNode); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDAttList.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDAttList.js new file mode 100644 index 0000000..4a71866 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDAttList.js @@ -0,0 +1,68 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDAttList, create; + + create = require('lodash/create'); + + module.exports = XMLDTDAttList = (function() { + function XMLDTDAttList(parent, elementName, attributeName, attributeType, defaultValueType, defaultValue) { + this.stringify = parent.stringify; + if (elementName == null) { + throw new Error("Missing DTD element name"); + } + if (attributeName == null) { + throw new Error("Missing DTD attribute name"); + } + if (!attributeType) { + throw new Error("Missing DTD attribute type"); + } + if (!defaultValueType) { + throw new Error("Missing DTD attribute default"); + } + if (defaultValueType.indexOf('#') !== 0) { + defaultValueType = '#' + defaultValueType; + } + if (!defaultValueType.match(/^(#REQUIRED|#IMPLIED|#FIXED|#DEFAULT)$/)) { + throw new Error("Invalid default value type; expected: #REQUIRED, #IMPLIED, #FIXED or #DEFAULT"); + } + if (defaultValue && !defaultValueType.match(/^(#FIXED|#DEFAULT)$/)) { + throw new Error("Default value only applies to #FIXED or #DEFAULT"); + } + this.elementName = this.stringify.eleName(elementName); + this.attributeName = this.stringify.attName(attributeName); + this.attributeType = this.stringify.dtdAttType(attributeType); + this.defaultValue = this.stringify.dtdAttDefault(defaultValue); + this.defaultValueType = defaultValueType; + } + + XMLDTDAttList.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDAttList; + + })(); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDElement.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDElement.js new file mode 100644 index 0000000..0002c1b --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDElement.js @@ -0,0 +1,46 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDElement, create; + + create = require('lodash/create'); + + module.exports = XMLDTDElement = (function() { + function XMLDTDElement(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing DTD element name"); + } + if (!value) { + value = '(#PCDATA)'; + } + if (Array.isArray(value)) { + value = '(' + value.join(',') + ')'; + } + this.name = this.stringify.eleName(name); + this.value = this.stringify.dtdElementValue(value); + } + + XMLDTDElement.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDElement; + + })(); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDEntity.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDEntity.js new file mode 100644 index 0000000..f27d567 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDEntity.js @@ -0,0 +1,84 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDEntity, create, isObject; + + create = require('lodash/create'); + + isObject = require('lodash/isObject'); + + module.exports = XMLDTDEntity = (function() { + function XMLDTDEntity(parent, pe, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing entity name"); + } + if (value == null) { + throw new Error("Missing entity value"); + } + this.pe = !!pe; + this.name = this.stringify.eleName(name); + if (!isObject(value)) { + this.value = this.stringify.dtdEntityValue(value); + } else { + if (!value.pubID && !value.sysID) { + throw new Error("Public and/or system identifiers are required for an external entity"); + } + if (value.pubID && !value.sysID) { + throw new Error("System identifier is required for a public external entity"); + } + if (value.pubID != null) { + this.pubID = this.stringify.dtdPubID(value.pubID); + } + if (value.sysID != null) { + this.sysID = this.stringify.dtdSysID(value.sysID); + } + if (value.nData != null) { + this.nData = this.stringify.dtdNData(value.nData); + } + if (this.pe && this.nData) { + throw new Error("Notation declaration is not allowed in a parameter entity"); + } + } + } + + XMLDTDEntity.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDEntity; + + })(); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDNotation.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDNotation.js new file mode 100644 index 0000000..edd3501 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDTDNotation.js @@ -0,0 +1,56 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDNotation, create; + + create = require('lodash/create'); + + module.exports = XMLDTDNotation = (function() { + function XMLDTDNotation(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing notation name"); + } + if (!value.pubID && !value.sysID) { + throw new Error("Public or system identifiers are required for an external entity"); + } + this.name = this.stringify.eleName(name); + if (value.pubID != null) { + this.pubID = this.stringify.dtdPubID(value.pubID); + } + if (value.sysID != null) { + this.sysID = this.stringify.dtdSysID(value.sysID); + } + } + + XMLDTDNotation.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDNotation; + + })(); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDeclaration.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDeclaration.js new file mode 100644 index 0000000..b502892 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDeclaration.js @@ -0,0 +1,65 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDeclaration, XMLNode, create, isObject, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/create'); + + isObject = require('lodash/isObject'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLDeclaration = (function(superClass) { + extend(XMLDeclaration, superClass); + + function XMLDeclaration(parent, version, encoding, standalone) { + var ref; + XMLDeclaration.__super__.constructor.call(this, parent); + if (isObject(version)) { + ref = version, version = ref.version, encoding = ref.encoding, standalone = ref.standalone; + } + if (!version) { + version = '1.0'; + } + this.version = this.stringify.xmlVersion(version); + if (encoding != null) { + this.encoding = this.stringify.xmlEncoding(encoding); + } + if (standalone != null) { + this.standalone = this.stringify.xmlStandalone(standalone); + } + } + + XMLDeclaration.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDeclaration; + + })(XMLNode); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDocType.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDocType.js new file mode 100644 index 0000000..cbc61b3 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLDocType.js @@ -0,0 +1,188 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLComment, XMLDTDAttList, XMLDTDElement, XMLDTDEntity, XMLDTDNotation, XMLDocType, XMLProcessingInstruction, create, isObject; + + create = require('lodash/create'); + + isObject = require('lodash/isObject'); + + XMLCData = require('./XMLCData'); + + XMLComment = require('./XMLComment'); + + XMLDTDAttList = require('./XMLDTDAttList'); + + XMLDTDEntity = require('./XMLDTDEntity'); + + XMLDTDElement = require('./XMLDTDElement'); + + XMLDTDNotation = require('./XMLDTDNotation'); + + XMLProcessingInstruction = require('./XMLProcessingInstruction'); + + module.exports = XMLDocType = (function() { + function XMLDocType(parent, pubID, sysID) { + var ref, ref1; + this.documentObject = parent; + this.stringify = this.documentObject.stringify; + this.children = []; + if (isObject(pubID)) { + ref = pubID, pubID = ref.pubID, sysID = ref.sysID; + } + if (sysID == null) { + ref1 = [pubID, sysID], sysID = ref1[0], pubID = ref1[1]; + } + if (pubID != null) { + this.pubID = this.stringify.dtdPubID(pubID); + } + if (sysID != null) { + this.sysID = this.stringify.dtdSysID(sysID); + } + } + + XMLDocType.prototype.element = function(name, value) { + var child; + child = new XMLDTDElement(this, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.attList = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) { + var child; + child = new XMLDTDAttList(this, elementName, attributeName, attributeType, defaultValueType, defaultValue); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.entity = function(name, value) { + var child; + child = new XMLDTDEntity(this, false, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.pEntity = function(name, value) { + var child; + child = new XMLDTDEntity(this, true, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.notation = function(name, value) { + var child; + child = new XMLDTDNotation(this, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.cdata = function(value) { + var child; + child = new XMLCData(this, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.comment = function(value) { + var child; + child = new XMLComment(this, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.instruction = function(target, value) { + var child; + child = new XMLProcessingInstruction(this, target, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.root = function() { + return this.documentObject.root(); + }; + + XMLDocType.prototype.document = function() { + return this.documentObject; + }; + + XMLDocType.prototype.toString = function(options, level) { + var child, i, indent, len, newline, offset, pretty, r, ref, ref1, ref2, ref3, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ' 0) { + r += ' ['; + if (pretty) { + r += newline; + } + ref3 = this.children; + for (i = 0, len = ref3.length; i < len; i++) { + child = ref3[i]; + r += child.toString(options, level + 1); + } + r += ']'; + } + r += '>'; + if (pretty) { + r += newline; + } + return r; + }; + + XMLDocType.prototype.ele = function(name, value) { + return this.element(name, value); + }; + + XMLDocType.prototype.att = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) { + return this.attList(elementName, attributeName, attributeType, defaultValueType, defaultValue); + }; + + XMLDocType.prototype.ent = function(name, value) { + return this.entity(name, value); + }; + + XMLDocType.prototype.pent = function(name, value) { + return this.pEntity(name, value); + }; + + XMLDocType.prototype.not = function(name, value) { + return this.notation(name, value); + }; + + XMLDocType.prototype.dat = function(value) { + return this.cdata(value); + }; + + XMLDocType.prototype.com = function(value) { + return this.comment(value); + }; + + XMLDocType.prototype.ins = function(target, value) { + return this.instruction(target, value); + }; + + XMLDocType.prototype.up = function() { + return this.root(); + }; + + XMLDocType.prototype.doc = function() { + return this.document(); + }; + + return XMLDocType; + + })(); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLElement.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLElement.js new file mode 100644 index 0000000..3e5e1eb --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLElement.js @@ -0,0 +1,217 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLAttribute, XMLElement, XMLNode, XMLProcessingInstruction, create, every, isFunction, isObject, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/create'); + + isObject = require('lodash/isObject'); + + isFunction = require('lodash/isFunction'); + + every = require('lodash/every'); + + XMLNode = require('./XMLNode'); + + XMLAttribute = require('./XMLAttribute'); + + XMLProcessingInstruction = require('./XMLProcessingInstruction'); + + module.exports = XMLElement = (function(superClass) { + extend(XMLElement, superClass); + + function XMLElement(parent, name, attributes) { + XMLElement.__super__.constructor.call(this, parent); + if (name == null) { + throw new Error("Missing element name"); + } + this.name = this.stringify.eleName(name); + this.children = []; + this.instructions = []; + this.attributes = {}; + if (attributes != null) { + this.attribute(attributes); + } + } + + XMLElement.prototype.clone = function() { + var att, attName, clonedSelf, i, len, pi, ref, ref1; + clonedSelf = create(XMLElement.prototype, this); + if (clonedSelf.isRoot) { + clonedSelf.documentObject = null; + } + clonedSelf.attributes = {}; + ref = this.attributes; + for (attName in ref) { + if (!hasProp.call(ref, attName)) continue; + att = ref[attName]; + clonedSelf.attributes[attName] = att.clone(); + } + clonedSelf.instructions = []; + ref1 = this.instructions; + for (i = 0, len = ref1.length; i < len; i++) { + pi = ref1[i]; + clonedSelf.instructions.push(pi.clone()); + } + clonedSelf.children = []; + this.children.forEach(function(child) { + var clonedChild; + clonedChild = child.clone(); + clonedChild.parent = clonedSelf; + return clonedSelf.children.push(clonedChild); + }); + return clonedSelf; + }; + + XMLElement.prototype.attribute = function(name, value) { + var attName, attValue; + if (name != null) { + name = name.valueOf(); + } + if (isObject(name)) { + for (attName in name) { + if (!hasProp.call(name, attName)) continue; + attValue = name[attName]; + this.attribute(attName, attValue); + } + } else { + if (isFunction(value)) { + value = value.apply(); + } + if (!this.options.skipNullAttributes || (value != null)) { + this.attributes[name] = new XMLAttribute(this, name, value); + } + } + return this; + }; + + XMLElement.prototype.removeAttribute = function(name) { + var attName, i, len; + if (name == null) { + throw new Error("Missing attribute name"); + } + name = name.valueOf(); + if (Array.isArray(name)) { + for (i = 0, len = name.length; i < len; i++) { + attName = name[i]; + delete this.attributes[attName]; + } + } else { + delete this.attributes[name]; + } + return this; + }; + + XMLElement.prototype.instruction = function(target, value) { + var i, insTarget, insValue, instruction, len; + if (target != null) { + target = target.valueOf(); + } + if (value != null) { + value = value.valueOf(); + } + if (Array.isArray(target)) { + for (i = 0, len = target.length; i < len; i++) { + insTarget = target[i]; + this.instruction(insTarget); + } + } else if (isObject(target)) { + for (insTarget in target) { + if (!hasProp.call(target, insTarget)) continue; + insValue = target[insTarget]; + this.instruction(insTarget, insValue); + } + } else { + if (isFunction(value)) { + value = value.apply(); + } + instruction = new XMLProcessingInstruction(this, target, value); + this.instructions.push(instruction); + } + return this; + }; + + XMLElement.prototype.toString = function(options, level) { + var allowEmpty, att, child, i, indent, instruction, j, len, len1, name, newline, offset, pretty, r, ref, ref1, ref2, ref3, ref4, ref5, ref6, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + allowEmpty = (ref3 = options != null ? options.allowEmpty : void 0) != null ? ref3 : false; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + ref4 = this.instructions; + for (i = 0, len = ref4.length; i < len; i++) { + instruction = ref4[i]; + r += instruction.toString(options, level); + } + if (pretty) { + r += space; + } + r += '<' + this.name; + ref5 = this.attributes; + for (name in ref5) { + if (!hasProp.call(ref5, name)) continue; + att = ref5[name]; + r += att.toString(options); + } + if (this.children.length === 0 || every(this.children, function(e) { + return e.value === ''; + })) { + if (allowEmpty) { + r += '>'; + } else { + r += '/>'; + } + if (pretty) { + r += newline; + } + } else if (pretty && this.children.length === 1 && (this.children[0].value != null)) { + r += '>'; + r += this.children[0].value; + r += ''; + r += newline; + } else { + r += '>'; + if (pretty) { + r += newline; + } + ref6 = this.children; + for (j = 0, len1 = ref6.length; j < len1; j++) { + child = ref6[j]; + r += child.toString(options, level + 1); + } + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + } + return r; + }; + + XMLElement.prototype.att = function(name, value) { + return this.attribute(name, value); + }; + + XMLElement.prototype.ins = function(target, value) { + return this.instruction(target, value); + }; + + XMLElement.prototype.a = function(name, value) { + return this.attribute(name, value); + }; + + XMLElement.prototype.i = function(target, value) { + return this.instruction(target, value); + }; + + return XMLElement; + + })(XMLNode); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLNode.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLNode.js new file mode 100644 index 0000000..0a6340b --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLNode.js @@ -0,0 +1,331 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLComment, XMLDeclaration, XMLDocType, XMLElement, XMLNode, XMLRaw, XMLText, isEmpty, isFunction, isObject, + hasProp = {}.hasOwnProperty; + + isObject = require('lodash/isObject'); + + isFunction = require('lodash/isFunction'); + + isEmpty = require('lodash/isEmpty'); + + XMLElement = null; + + XMLCData = null; + + XMLComment = null; + + XMLDeclaration = null; + + XMLDocType = null; + + XMLRaw = null; + + XMLText = null; + + module.exports = XMLNode = (function() { + function XMLNode(parent) { + this.parent = parent; + this.options = this.parent.options; + this.stringify = this.parent.stringify; + if (XMLElement === null) { + XMLElement = require('./XMLElement'); + XMLCData = require('./XMLCData'); + XMLComment = require('./XMLComment'); + XMLDeclaration = require('./XMLDeclaration'); + XMLDocType = require('./XMLDocType'); + XMLRaw = require('./XMLRaw'); + XMLText = require('./XMLText'); + } + } + + XMLNode.prototype.element = function(name, attributes, text) { + var childNode, item, j, k, key, lastChild, len, len1, ref, val; + lastChild = null; + if (attributes == null) { + attributes = {}; + } + attributes = attributes.valueOf(); + if (!isObject(attributes)) { + ref = [attributes, text], text = ref[0], attributes = ref[1]; + } + if (name != null) { + name = name.valueOf(); + } + if (Array.isArray(name)) { + for (j = 0, len = name.length; j < len; j++) { + item = name[j]; + lastChild = this.element(item); + } + } else if (isFunction(name)) { + lastChild = this.element(name.apply()); + } else if (isObject(name)) { + for (key in name) { + if (!hasProp.call(name, key)) continue; + val = name[key]; + if (isFunction(val)) { + val = val.apply(); + } + if ((isObject(val)) && (isEmpty(val))) { + val = null; + } + if (!this.options.ignoreDecorators && this.stringify.convertAttKey && key.indexOf(this.stringify.convertAttKey) === 0) { + lastChild = this.attribute(key.substr(this.stringify.convertAttKey.length), val); + } else if (!this.options.ignoreDecorators && this.stringify.convertPIKey && key.indexOf(this.stringify.convertPIKey) === 0) { + lastChild = this.instruction(key.substr(this.stringify.convertPIKey.length), val); + } else if (!this.options.separateArrayItems && Array.isArray(val)) { + for (k = 0, len1 = val.length; k < len1; k++) { + item = val[k]; + childNode = {}; + childNode[key] = item; + lastChild = this.element(childNode); + } + } else if (isObject(val)) { + lastChild = this.element(key); + lastChild.element(val); + } else { + lastChild = this.element(key, val); + } + } + } else { + if (!this.options.ignoreDecorators && this.stringify.convertTextKey && name.indexOf(this.stringify.convertTextKey) === 0) { + lastChild = this.text(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertCDataKey && name.indexOf(this.stringify.convertCDataKey) === 0) { + lastChild = this.cdata(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertCommentKey && name.indexOf(this.stringify.convertCommentKey) === 0) { + lastChild = this.comment(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertRawKey && name.indexOf(this.stringify.convertRawKey) === 0) { + lastChild = this.raw(text); + } else { + lastChild = this.node(name, attributes, text); + } + } + if (lastChild == null) { + throw new Error("Could not create any elements with: " + name); + } + return lastChild; + }; + + XMLNode.prototype.insertBefore = function(name, attributes, text) { + var child, i, removed; + if (this.isRoot) { + throw new Error("Cannot insert elements at root level"); + } + i = this.parent.children.indexOf(this); + removed = this.parent.children.splice(i); + child = this.parent.element(name, attributes, text); + Array.prototype.push.apply(this.parent.children, removed); + return child; + }; + + XMLNode.prototype.insertAfter = function(name, attributes, text) { + var child, i, removed; + if (this.isRoot) { + throw new Error("Cannot insert elements at root level"); + } + i = this.parent.children.indexOf(this); + removed = this.parent.children.splice(i + 1); + child = this.parent.element(name, attributes, text); + Array.prototype.push.apply(this.parent.children, removed); + return child; + }; + + XMLNode.prototype.remove = function() { + var i, ref; + if (this.isRoot) { + throw new Error("Cannot remove the root element"); + } + i = this.parent.children.indexOf(this); + [].splice.apply(this.parent.children, [i, i - i + 1].concat(ref = [])), ref; + return this.parent; + }; + + XMLNode.prototype.node = function(name, attributes, text) { + var child, ref; + if (name != null) { + name = name.valueOf(); + } + if (attributes == null) { + attributes = {}; + } + attributes = attributes.valueOf(); + if (!isObject(attributes)) { + ref = [attributes, text], text = ref[0], attributes = ref[1]; + } + child = new XMLElement(this, name, attributes); + if (text != null) { + child.text(text); + } + this.children.push(child); + return child; + }; + + XMLNode.prototype.text = function(value) { + var child; + child = new XMLText(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.cdata = function(value) { + var child; + child = new XMLCData(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.comment = function(value) { + var child; + child = new XMLComment(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.raw = function(value) { + var child; + child = new XMLRaw(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.declaration = function(version, encoding, standalone) { + var doc, xmldec; + doc = this.document(); + xmldec = new XMLDeclaration(doc, version, encoding, standalone); + doc.xmldec = xmldec; + return doc.root(); + }; + + XMLNode.prototype.doctype = function(pubID, sysID) { + var doc, doctype; + doc = this.document(); + doctype = new XMLDocType(doc, pubID, sysID); + doc.doctype = doctype; + return doctype; + }; + + XMLNode.prototype.up = function() { + if (this.isRoot) { + throw new Error("The root node has no parent. Use doc() if you need to get the document object."); + } + return this.parent; + }; + + XMLNode.prototype.root = function() { + var child; + if (this.isRoot) { + return this; + } + child = this.parent; + while (!child.isRoot) { + child = child.parent; + } + return child; + }; + + XMLNode.prototype.document = function() { + return this.root().documentObject; + }; + + XMLNode.prototype.end = function(options) { + return this.document().toString(options); + }; + + XMLNode.prototype.prev = function() { + var i; + if (this.isRoot) { + throw new Error("Root node has no siblings"); + } + i = this.parent.children.indexOf(this); + if (i < 1) { + throw new Error("Already at the first node"); + } + return this.parent.children[i - 1]; + }; + + XMLNode.prototype.next = function() { + var i; + if (this.isRoot) { + throw new Error("Root node has no siblings"); + } + i = this.parent.children.indexOf(this); + if (i === -1 || i === this.parent.children.length - 1) { + throw new Error("Already at the last node"); + } + return this.parent.children[i + 1]; + }; + + XMLNode.prototype.importXMLBuilder = function(xmlbuilder) { + var clonedRoot; + clonedRoot = xmlbuilder.root().clone(); + clonedRoot.parent = this; + clonedRoot.isRoot = false; + this.children.push(clonedRoot); + return this; + }; + + XMLNode.prototype.ele = function(name, attributes, text) { + return this.element(name, attributes, text); + }; + + XMLNode.prototype.nod = function(name, attributes, text) { + return this.node(name, attributes, text); + }; + + XMLNode.prototype.txt = function(value) { + return this.text(value); + }; + + XMLNode.prototype.dat = function(value) { + return this.cdata(value); + }; + + XMLNode.prototype.com = function(value) { + return this.comment(value); + }; + + XMLNode.prototype.doc = function() { + return this.document(); + }; + + XMLNode.prototype.dec = function(version, encoding, standalone) { + return this.declaration(version, encoding, standalone); + }; + + XMLNode.prototype.dtd = function(pubID, sysID) { + return this.doctype(pubID, sysID); + }; + + XMLNode.prototype.e = function(name, attributes, text) { + return this.element(name, attributes, text); + }; + + XMLNode.prototype.n = function(name, attributes, text) { + return this.node(name, attributes, text); + }; + + XMLNode.prototype.t = function(value) { + return this.text(value); + }; + + XMLNode.prototype.d = function(value) { + return this.cdata(value); + }; + + XMLNode.prototype.c = function(value) { + return this.comment(value); + }; + + XMLNode.prototype.r = function(value) { + return this.raw(value); + }; + + XMLNode.prototype.u = function() { + return this.up(); + }; + + return XMLNode; + + })(); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLProcessingInstruction.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLProcessingInstruction.js new file mode 100644 index 0000000..596f5a6 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLProcessingInstruction.js @@ -0,0 +1,51 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLProcessingInstruction, create; + + create = require('lodash/create'); + + module.exports = XMLProcessingInstruction = (function() { + function XMLProcessingInstruction(parent, target, value) { + this.stringify = parent.stringify; + if (target == null) { + throw new Error("Missing instruction target"); + } + this.target = this.stringify.insTarget(target); + if (value) { + this.value = this.stringify.insValue(value); + } + } + + XMLProcessingInstruction.prototype.clone = function() { + return create(XMLProcessingInstruction.prototype, this); + }; + + XMLProcessingInstruction.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLProcessingInstruction; + + })(); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLRaw.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLRaw.js new file mode 100644 index 0000000..9f48962 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLRaw.js @@ -0,0 +1,49 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLNode, XMLRaw, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLRaw = (function(superClass) { + extend(XMLRaw, superClass); + + function XMLRaw(parent, text) { + XMLRaw.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing raw text"); + } + this.value = this.stringify.raw(text); + } + + XMLRaw.prototype.clone = function() { + return create(XMLRaw.prototype, this); + }; + + XMLRaw.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += this.value; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLRaw; + + })(XMLNode); + +}).call(this); diff --git a/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLStringifier.js b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLStringifier.js new file mode 100644 index 0000000..bee8587 --- /dev/null +++ b/platforms/android/assets/www/node_modules/xmlbuilder/lib/XMLStringifier.js @@ -0,0 +1,193 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLStringifier, camelCase, kebabCase, snakeCase, + bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + hasProp = {}.hasOwnProperty; + + camelCase = require('lodash/camelCase'); + + kebabCase = require('lodash/kebabCase'); + + snakeCase = require('lodash/snakeCase'); + + module.exports = XMLStringifier = (function() { + function XMLStringifier(options) { + this.assertLegalChar = bind(this.assertLegalChar, this); + var key, ref, value; + this.allowSurrogateChars = options != null ? options.allowSurrogateChars : void 0; + this.noDoubleEncoding = options != null ? options.noDoubleEncoding : void 0; + this.textCase = options != null ? options.textCase : void 0; + ref = (options != null ? options.stringify : void 0) || {}; + for (key in ref) { + if (!hasProp.call(ref, key)) continue; + value = ref[key]; + this[key] = value; + } + } + + XMLStringifier.prototype.eleName = function(val) { + val = '' + val || ''; + val = this.applyCase(val); + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.eleText = function(val) { + val = '' + val || ''; + return this.assertLegalChar(this.elEscape(val)); + }; + + XMLStringifier.prototype.cdata = function(val) { + val = '' + val || ''; + val = val.replace(']]>', ']]]]>'); + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.comment = function(val) { + val = '' + val || ''; + if (val.match(/--/)) { + throw new Error("Comment text cannot contain double-hypen: " + val); + } + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.raw = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.attName = function(val) { + val = '' + val || ''; + return val = this.applyCase(val); + }; + + XMLStringifier.prototype.attValue = function(val) { + val = '' + val || ''; + return this.attEscape(val); + }; + + XMLStringifier.prototype.insTarget = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.insValue = function(val) { + val = '' + val || ''; + if (val.match(/\?>/)) { + throw new Error("Invalid processing instruction value: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlVersion = function(val) { + val = '' + val || ''; + if (!val.match(/1\.[0-9]+/)) { + throw new Error("Invalid version number: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlEncoding = function(val) { + val = '' + val || ''; + if (!val.match(/^[A-Za-z](?:[A-Za-z0-9._-]|-)*$/)) { + throw new Error("Invalid encoding: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlStandalone = function(val) { + if (val) { + return "yes"; + } else { + return "no"; + } + }; + + XMLStringifier.prototype.dtdPubID = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdSysID = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdElementValue = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdAttType = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdAttDefault = function(val) { + if (val != null) { + return '' + val || ''; + } else { + return val; + } + }; + + XMLStringifier.prototype.dtdEntityValue = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdNData = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.convertAttKey = '@'; + + XMLStringifier.prototype.convertPIKey = '?'; + + XMLStringifier.prototype.convertTextKey = '#text'; + + XMLStringifier.prototype.convertCDataKey = '#cdata'; + + XMLStringifier.prototype.convertCommentKey = '#comment'; + + XMLStringifier.prototype.convertRawKey = '#raw'; + + XMLStringifier.prototype.assertLegalChar = function(str) { + var chars, chr; + if (this.allowSurrogateChars) { + chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uFFFE-\uFFFF]/; + } else { + chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]/; + } + chr = str.match(chars); + if (chr) { + throw new Error("Invalid character (" + chr + ") in string: " + str + " at index " + chr.index); + } + return str; + }; + + XMLStringifier.prototype.applyCase = function(str) { + switch (this.textCase) { + case "camel": + return camelCase(str); + case "kebab": + case "lower": + return kebabCase(str); + case "snake": + return snakeCase(str); + case "upper": + return kebabCase(str).toUpperCase(); + default: + return str; + } + }; + + XMLStringifier.prototype.elEscape = function(str) { + var ampregex; + ampregex = this.noDoubleEncoding ? /(?!&\S+;)&/g : /&/g; + return str.replace(ampregex, '&').replace(//g, '>').replace(/\r/g, ' '); + }; + + XMLStringifier.prototype.attEscape = function(str) { + var ampregex; + ampregex = this.noDoubleEncoding ? /(?!&\S+;)&/g : /&/g; + return str.replace(ampregex, '&').replace(/=1.0.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/xml2js" + ] + ], + "_from": "xmlbuilder@>=1.0.0", + "_id": "xmlbuilder@5.0.1", + "_inCache": true, + "_installable": true, + "_location": "/xmlbuilder", + "_npmOperationalInternal": { + "host": "packages-13-west.internal.npmjs.com", + "tmp": "tmp/xmlbuilder-5.0.1.tgz_1457392734733_0.19968478404916823" + }, + "_npmUser": { + "email": "oozcitak@gmail.com", + "name": "oozcitak" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "name": "xmlbuilder", + "raw": "xmlbuilder@>=1.0.0", + "rawSpec": ">=1.0.0", + "scope": null, + "spec": ">=1.0.0", + "type": "range" + }, + "_requiredBy": [ + "/xml2js" + ], + "_resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-5.0.1.tgz", + "_shasum": "155f1fb6e860137047443db54a9b263761b1f5c3", + "_shrinkwrap": null, + "_spec": "xmlbuilder@>=1.0.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/xml2js", + "author": { + "email": "oozcitak@gmail.com", + "name": "Ozgur Ozcitak" + }, + "bugs": { + "url": "http://github.com/oozcitak/xmlbuilder-js/issues" + }, + "contributors": [], + "dependencies": { + "lodash": "^4.0.0" + }, + "description": "An XML builder for node.js", + "devDependencies": { + "coffee-coverage": "*", + "coffee-script": "*", + "coveralls": "*", + "istanbul": "*", + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "155f1fb6e860137047443db54a9b263761b1f5c3", + "tarball": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-5.0.1.tgz" + }, + "engines": { + "node": ">=0.10" + }, + "gitHead": "328bfb90488b9823361e329598c5b2c8b9d3c1a8", + "homepage": "http://github.com/oozcitak/xmlbuilder-js", + "keywords": [ + "xml", + "xmlbuilder" + ], + "license": "MIT", + "main": "./lib/index", + "maintainers": [ + { + "email": "oozcitak@gmail.com", + "name": "oozcitak" + } + ], + "name": "xmlbuilder", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/oozcitak/xmlbuilder-js.git" + }, + "scripts": { + "postpublish": "rm -rf lib", + "prepublish": "coffee -co lib src", + "test": "mocha && istanbul report text lcov" + }, + "version": "5.0.1" +} diff --git a/platforms/android/assets/www/package.json b/platforms/android/assets/www/package.json new file mode 100644 index 0000000..70a9554 --- /dev/null +++ b/platforms/android/assets/www/package.json @@ -0,0 +1,15 @@ +{ + "name": "studywelltests", + "version": "1.0.0", + "description": "gui tests for studywell", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Adam Don", + "license": "ISC", + "dependencies": { + "jasmine": "^2.4.1", + "selenium-webdriver": "^2.52.0" + } +} diff --git a/platforms/android/assets/www/plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js b/platforms/android/assets/www/plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js index a51c286..118dfad 100644 --- a/platforms/android/assets/www/plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js +++ b/platforms/android/assets/www/plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js @@ -1,4 +1,5 @@ -cordova.define("at.gofg.sportscomputer.powermanagement.device", function(require, exports, module) { /* +cordova.define("at.gofg.sportscomputer.powermanagement.device", function(require, exports, module) { +/* * Copyright 2013 Wolfgang Koller * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/platforms/android/assets/www/plugins/com.lampa.startapp/www/startApp.js b/platforms/android/assets/www/plugins/com.lampa.startapp/www/startApp.js index a1c89f2..2ff7912 100644 --- a/platforms/android/assets/www/plugins/com.lampa.startapp/www/startApp.js +++ b/platforms/android/assets/www/plugins/com.lampa.startapp/www/startApp.js @@ -1,4 +1,5 @@ -cordova.define("com.lampa.startapp.startapp", function(require, exports, module) { /** +cordova.define("com.lampa.startapp.startapp", function(require, exports, module) { +/** com.lampa.startapp https://github.com/lampaa/com.lampa.startapp diff --git a/platforms/android/assets/www/plugins/com.shukriadams.micVolume/www/micVolume.js b/platforms/android/assets/www/plugins/com.shukriadams.micVolume/www/micVolume.js index 7d95be1..3479043 100644 --- a/platforms/android/assets/www/plugins/com.shukriadams.micVolume/www/micVolume.js +++ b/platforms/android/assets/www/plugins/com.shukriadams.micVolume/www/micVolume.js @@ -1,4 +1,5 @@ -cordova.define("com.shukriadams.micVolume.MicVolume", function(require, exports, module) { var micVolume = { +cordova.define("com.shukriadams.micVolume.MicVolume", function(require, exports, module) { +var micVolume = { start: function(successCallback, errorCallback) { cordova.exec( successCallback, // success callback function diff --git a/platforms/android/assets/www/plugins/cordova-plugin-background-mode/www/background-mode.js b/platforms/android/assets/www/plugins/cordova-plugin-background-mode/www/background-mode.js index 86355df..98b3645 100644 --- a/platforms/android/assets/www/plugins/cordova-plugin-background-mode/www/background-mode.js +++ b/platforms/android/assets/www/plugins/cordova-plugin-background-mode/www/background-mode.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-background-mode.BackgroundMode", function(require, exports, module) { /* +cordova.define("cordova-plugin-background-mode.BackgroundMode", function(require, exports, module) { +/* Copyright 2013-2014 appPlant UG Licensed to the Apache Software Foundation (ASF) under one diff --git a/platforms/android/assets/www/plugins/cordova-plugin-device-motion-tests/tests.js b/platforms/android/assets/www/plugins/cordova-plugin-device-motion-tests/tests.js new file mode 100644 index 0000000..892ca60 --- /dev/null +++ b/platforms/android/assets/www/plugins/cordova-plugin-device-motion-tests/tests.js @@ -0,0 +1,367 @@ +cordova.define("cordova-plugin-device-motion-tests.tests", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint jasmine: true */ +/* global Windows */ + +exports.defineAutoTests = function () { + var isWindows = (cordova.platformId === "windows") || (cordova.platformId === "windows8"), + // Checking existence of accelerometer for windows platform + // Assumed that accelerometer always exists on other platforms. Extend + // condition to support accelerometer check on other platforms + isAccelExist = isWindows ? Windows.Devices.Sensors.Accelerometer.getDefault() !== null : true; + + describe('Accelerometer (navigator.accelerometer)', function () { + var fail = function(done) { + expect(true).toBe(false); + done(); + }; + + // This timeout is here to lessen the load on native accelerometer + // intensive use of which can lead to occasional test failures + afterEach(function(done) { + setTimeout(function() { + done(); + }, 100); + }); + + it("accelerometer.spec.1 should exist", function () { + expect(navigator.accelerometer).toBeDefined(); + }); + + describe("getCurrentAcceleration", function() { + it("accelerometer.spec.2 should exist", function() { + expect(typeof navigator.accelerometer.getCurrentAcceleration).toBeDefined(); + expect(typeof navigator.accelerometer.getCurrentAcceleration == 'function').toBe(true); + }); + + it("accelerometer.spec.3 success callback should be called with an Acceleration object", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var win = function(a) { + expect(a).toBeDefined(); + expect(a.x).toBeDefined(); + expect(typeof a.x == 'number').toBe(true); + expect(a.y).toBeDefined(); + expect(typeof a.y == 'number').toBe(true); + expect(a.z).toBeDefined(); + expect(typeof a.z == 'number').toBe(true); + expect(a.timestamp).toBeDefined(); + expect(typeof a.timestamp).toBe('number'); + done(); + }; + + var onError = function(err){ + console.log(err); + console.log("Skipping gyroscope tests, marking all as pending."); + isAccelExist = false; + expect(true).toBe(true); + done(); + }; + + navigator.accelerometer.getCurrentAcceleration(win, onError); + }); + + it("accelerometer.spec.4 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var reasonableThreshold = 15; + var win = function(a) { + expect(a.x).toBeLessThan(reasonableThreshold); + expect(a.x).toBeGreaterThan(reasonableThreshold * -1); + expect(a.y).toBeLessThan(reasonableThreshold); + expect(a.y).toBeGreaterThan(reasonableThreshold * -1); + expect(a.z).toBeLessThan(reasonableThreshold); + expect(a.z).toBeGreaterThan(reasonableThreshold * -1); + done(); + }; + + navigator.accelerometer.getCurrentAcceleration(win, fail.bind(null,done)); + }); + + it("accelerometer.spec.5 success callback Acceleration object should return a recent timestamp", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var veryRecently = (new Date()).getTime(); + // Need to check that dates returned are not vastly greater than a recent time stamp. + // In case the timestamps returned are ridiculously high + var reasonableTimeLimit = veryRecently + 5000; // 5 seconds from now + var win = function(a) { + expect(a.timestamp).toBeGreaterThan(veryRecently); + expect(a.timestamp).toBeLessThan(reasonableTimeLimit); + done(); + }; + + navigator.accelerometer.getCurrentAcceleration(win, fail.bind(null,done)); + }); + }); + + describe("watchAcceleration", function() { + var id; + + afterEach(function() { + navigator.accelerometer.clearWatch(id); + }); + + it("accelerometer.spec.6 should exist", function() { + expect(navigator.accelerometer.watchAcceleration).toBeDefined(); + expect(typeof navigator.accelerometer.watchAcceleration == 'function').toBe(true); + }); + + it("accelerometer.spec.7 success callback should be called with an Acceleration object", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var win = function(a) { + expect(a).toBeDefined(); + expect(a.x).toBeDefined(); + expect(typeof a.x == 'number').toBe(true); + expect(a.y).toBeDefined(); + expect(typeof a.y == 'number').toBe(true); + expect(a.z).toBeDefined(); + expect(typeof a.z == 'number').toBe(true); + expect(a.timestamp).toBeDefined(); + expect(typeof a.timestamp).toBe('number'); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null,done), {frequency:100}); + }); + + it("accelerometer.spec.8 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var reasonableThreshold = 15; + var win = function(a) { + expect(a.x).toBeLessThan(reasonableThreshold); + expect(a.x).toBeGreaterThan(reasonableThreshold * -1); + expect(a.y).toBeLessThan(reasonableThreshold); + expect(a.y).toBeGreaterThan(reasonableThreshold * -1); + expect(a.z).toBeLessThan(reasonableThreshold); + expect(a.z).toBeGreaterThan(reasonableThreshold * -1); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null,done), {frequency:100}); + }); + + it("accelerometer.spec.9 success callback Acceleration object should return a recent timestamp", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var veryRecently = (new Date()).getTime(); + // Need to check that dates returned are not vastly greater than a recent time stamp. + // In case the timestamps returned are ridiculously high + var reasonableTimeLimit = veryRecently + 5000; // 5 seconds from now + var win = function(a) { + expect(a.timestamp).toBeGreaterThan(veryRecently); + expect(a.timestamp).toBeLessThan(reasonableTimeLimit); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null,done), {frequency:100}); + }); + + it("accelerometer.spec.12 success callback should be preserved and called several times", function (done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var callbacksCallCount = 0, + callbacksCallTestCount = 3; + + var win = function (a) { + if (callbacksCallCount++ < callbacksCallTestCount) return; + expect(typeof a).toBe('object'); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null, done), { frequency: 100 }); + }); + }); + + describe("clearWatch", function() { + it("accelerometer.spec.10 should exist", function() { + expect(navigator.accelerometer.clearWatch).toBeDefined(); + expect(typeof navigator.accelerometer.clearWatch == 'function').toBe(true); + }); + + it("accelerometer.spec.11 should clear an existing watch", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var id; + + // expect win to get called exactly once + var win = function(a) { + // clear watch on first call + navigator.accelerometer.clearWatch(id); + // if win isn't called again in 201 ms we assume success + var tid = setTimeout(function() { + expect(true).toBe(true); + done(); + }, 101); + // if win is called again, clear the timeout and fail the test + win = function() { + clearTimeout(tid); + fail(done); + }; + }; + + // wrap the success call in a closure since the value of win changes between calls + id = navigator.accelerometer.watchAcceleration(function() { win(); }, fail.bind(null, done), {frequency:100}); + }); + }); + }); +}; + +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +exports.defineManualTests = function (contentEl, createActionButton) { + function roundNumber(num) { + var dec = 3; + var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); + return result; + } + + var watchAccelId = null; + + /** + * Set accelerometer status + */ + function setAccelStatus(status) { + document.getElementById('accel_status').innerHTML = status; + } + + /** + * Stop watching the acceleration + */ + function stopAccel() { + console.log("stopAccel()"); + setAccelStatus("Stopped"); + if (watchAccelId) { + navigator.accelerometer.clearWatch(watchAccelId); + watchAccelId = null; + } + } + + /** + * Start watching acceleration + */ + var watchAccel = function () { + console.log("watchAccel()"); + + // Success callback + var success = function (a) { + document.getElementById('x').innerHTML = roundNumber(a.x); + document.getElementById('y').innerHTML = roundNumber(a.y); + document.getElementById('z').innerHTML = roundNumber(a.z); + }; + + // Fail callback + var fail = function (e) { + console.log("watchAccel fail callback with error code " + e); + stopAccel(); + setAccelStatus(e); + }; + + // Update acceleration every 1 sec + var opt = {}; + opt.frequency = 1000; + watchAccelId = navigator.accelerometer.watchAcceleration(success, fail, opt); + + setAccelStatus("Running"); + }; + + /** + * Get current acceleration + */ + var getAccel = function () { + console.log("getAccel()"); + + // Stop accel if running + stopAccel(); + + // Success callback + var success = function (a) { + document.getElementById('x').innerHTML = roundNumber(a.x); + document.getElementById('y').innerHTML = roundNumber(a.y); + document.getElementById('z').innerHTML = roundNumber(a.z); + console.log("getAccel success callback"); + }; + + // Fail callback + var fail = function (e) { + console.log("getAccel fail callback with error code " + e); + setAccelStatus(e); + }; + + // Make call + var opt = {}; + navigator.accelerometer.getCurrentAcceleration(success, fail, opt); + }; + + /******************************************************************************/ + + var accelerometer_tests = '
    ' + + 'Expected result: Will update the status box with X, Y, and Z values when pressed. Status will read "Stopped"' + + '

    ' + + 'Expected result: When pressed, will start a watch on the accelerometer and update X,Y,Z values when movement is sensed. Status will read "Running"' + + '

    ' + + 'Expected result: Will clear the accelerometer watch, so X,Y,Z values will no longer be updated. Status will read "Stopped"'; + + contentEl.innerHTML = '
    ' + + 'Status: Stopped' + + '' + + '' + + '' + + '' + + '
    X:
    Y:
    Z:
    ' + + accelerometer_tests; + + createActionButton('Get Acceleration', function () { + getAccel(); + }, 'getAcceleration'); + + createActionButton('Start Watch', function () { + watchAccel(); + }, 'watchAcceleration'); + + createActionButton('Clear Watch', function () { + stopAccel(); + }, 'clearAcceleration'); +}; + +}); diff --git a/platforms/android/assets/www/plugins/cordova-plugin-device-motion/www/Acceleration.js b/platforms/android/assets/www/plugins/cordova-plugin-device-motion/www/Acceleration.js index fd4ea4e..794476b 100644 --- a/platforms/android/assets/www/plugins/cordova-plugin-device-motion/www/Acceleration.js +++ b/platforms/android/assets/www/plugins/cordova-plugin-device-motion/www/Acceleration.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-device-motion.Acceleration", function(require, exports, module) { /* +cordova.define("cordova-plugin-device-motion.Acceleration", function(require, exports, module) { +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/platforms/android/assets/www/plugins/cordova-plugin-device-motion/www/accelerometer.js b/platforms/android/assets/www/plugins/cordova-plugin-device-motion/www/accelerometer.js index ddd7a57..01f533a 100644 --- a/platforms/android/assets/www/plugins/cordova-plugin-device-motion/www/accelerometer.js +++ b/platforms/android/assets/www/plugins/cordova-plugin-device-motion/www/accelerometer.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-device-motion.accelerometer", function(require, exports, module) { /* +cordova.define("cordova-plugin-device-motion.accelerometer", function(require, exports, module) { +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/platforms/android/assets/www/plugins/cordova-plugin-device-tests/tests.js b/platforms/android/assets/www/plugins/cordova-plugin-device-tests/tests.js new file mode 100644 index 0000000..9687554 --- /dev/null +++ b/platforms/android/assets/www/plugins/cordova-plugin-device-tests/tests.js @@ -0,0 +1,116 @@ +cordova.define("cordova-plugin-device-tests.tests", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint jasmine: true */ + +exports.defineAutoTests = function() { + describe('Device Information (window.device)', function () { + it("should exist", function() { + expect(window.device).toBeDefined(); + }); + + it("should contain a platform specification that is a string", function() { + expect(window.device.platform).toBeDefined(); + expect((String(window.device.platform)).length > 0).toBe(true); + }); + + it("should contain a version specification that is a string", function() { + expect(window.device.version).toBeDefined(); + expect((String(window.device.version)).length > 0).toBe(true); + }); + + it("should contain a UUID specification that is a string or a number", function() { + expect(window.device.uuid).toBeDefined(); + if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') { + expect((String(window.device.uuid)).length > 0).toBe(true); + } else { + expect(window.device.uuid > 0).toBe(true); + } + }); + + it("should contain a cordova specification that is a string", function() { + expect(window.device.cordova).toBeDefined(); + expect((String(window.device.cordova)).length > 0).toBe(true); + }); + + it("should depend on the presence of cordova.version string", function() { + expect(window.cordova.version).toBeDefined(); + expect((String(window.cordova.version)).length > 0).toBe(true); + }); + + it("should contain device.cordova equal to cordova.version", function() { + expect(window.device.cordova).toBe(window.cordova.version); + }); + + it("should contain a model specification that is a string", function() { + expect(window.device.model).toBeDefined(); + expect((String(window.device.model)).length > 0).toBe(true); + }); + + it("should contain a manufacturer property that is a string", function() { + expect(window.device.manufacturer).toBeDefined(); + expect((String(window.device.manufacturer)).length > 0).toBe(true); + }); + + it("should contain an isVirtual property that is a boolean", function() { + expect(window.device.isVirtual).toBeDefined(); + expect(typeof window.device.isVirtual).toBe("boolean"); + }); + + it("should contain a serial number specification that is a string", function() { + expect(window.device.serial).toBeDefined(); + expect((String(window.device.serial)).length > 0).toBe(true); + + }); + + }); +}; + +exports.defineManualTests = function(contentEl, createActionButton) { + var logMessage = function (message, color) { + var log = document.getElementById('info'); + var logLine = document.createElement('div'); + if (color) { + logLine.style.color = color; + } + logLine.innerHTML = message; + log.appendChild(logLine); + }; + + var clearLog = function () { + var log = document.getElementById('info'); + log.innerHTML = ''; + }; + + var device_tests = '

    Press Dump Device button to get device information

    ' + + '
    ' + + 'Expected result: Status box will get updated with device info. (i.e. platform, version, uuid, model, etc)'; + + contentEl.innerHTML = '
    ' + device_tests; + + createActionButton('Dump device', function() { + clearLog(); + logMessage(JSON.stringify(window.device, null, '\t')); + }, "dump_device"); +}; + +}); diff --git a/platforms/android/assets/www/plugins/cordova-plugin-device/www/device.js b/platforms/android/assets/www/plugins/cordova-plugin-device/www/device.js index ff0c5b4..977dfc0 100644 --- a/platforms/android/assets/www/plugins/cordova-plugin-device/www/device.js +++ b/platforms/android/assets/www/plugins/cordova-plugin-device/www/device.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-device.device", function(require, exports, module) { /* +cordova.define("cordova-plugin-device.device", function(require, exports, module) { +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/platforms/android/assets/www/plugins/cordova-plugin-dialogs/www/android/notification.js b/platforms/android/assets/www/plugins/cordova-plugin-dialogs/www/android/notification.js index 07b9237..69cb5a4 100644 --- a/platforms/android/assets/www/plugins/cordova-plugin-dialogs/www/android/notification.js +++ b/platforms/android/assets/www/plugins/cordova-plugin-dialogs/www/android/notification.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-dialogs.notification_android", function(require, exports, module) { /* +cordova.define("cordova-plugin-dialogs.notification_android", function(require, exports, module) { +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/platforms/android/assets/www/plugins/cordova-plugin-dialogs/www/notification.js b/platforms/android/assets/www/plugins/cordova-plugin-dialogs/www/notification.js index b7236a2..3787c0f 100644 --- a/platforms/android/assets/www/plugins/cordova-plugin-dialogs/www/notification.js +++ b/platforms/android/assets/www/plugins/cordova-plugin-dialogs/www/notification.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-dialogs.notification", function(require, exports, module) { /* +cordova.define("cordova-plugin-dialogs.notification", function(require, exports, module) { +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/jasmine_helpers.js b/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/jasmine_helpers.js new file mode 100644 index 0000000..a77be0e --- /dev/null +++ b/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/jasmine_helpers.js @@ -0,0 +1,86 @@ +cordova.define("cordova-plugin-test-framework.jasmine_helpers", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint -W097 */ +'use strict'; + +exports.setUpJasmine = function() { + // Set up jasmine + var jasmine = jasmineRequire.core(jasmineRequire); + jasmineRequire.html(jasmine); + var jasmineEnv = jasmine.currentEnv_ = new jasmine.Env(); + + jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; + jasmineEnv.catchExceptions(false); + + // Set up jasmine interface + var jasmineInterface = jasmineRequire.interface(jasmine, jasmineEnv); + + // Add Reporters + addJasmineReporters(jasmineInterface, jasmineEnv); + + // Add Spec Filter + jasmineEnv.specFilter = function(spec) { + //console.log(spec.getFullName()); + return true; + }; + + // Jasmine 2.2.0 moved this symbol, so we add a shim here. + jasmine.Expectation.addMatchers = jasmine.Expectation.addMatchers || function() { + return jasmine.addMatchers.apply(this, arguments); + }; + + return jasmineInterface; +}; + +function addJasmineReporters(jasmineInterface, jasmineEnv) { + jasmineInterface.jsApiReporter = new jasmineInterface.jasmine.JsApiReporter({ timer: new jasmineInterface.jasmine.Timer() }); + jasmineEnv.addReporter(jasmineInterface.jsApiReporter); + + jasmineInterface.htmlReporter = new jasmineInterface.jasmine.HtmlReporter({ + env: jasmineEnv, + queryString: function() { return null; }, + onRaiseExceptionsClick: function() { }, + getContainer: function() { return document.getElementById('content'); }, + createElement: function() { return document.createElement.apply(document, arguments); }, + createTextNode: function() { return document.createTextNode.apply(document, arguments); }, + timer: new jasmineInterface.jasmine.Timer() + }); + jasmineInterface.htmlReporter.initialize(); + jasmineEnv.addReporter(jasmineInterface.htmlReporter); + + var medic = require('cordova-plugin-test-framework.medic'); + + if (medic.enabled) { + jasmineRequire.medic(jasmineInterface.jasmine); + jasmineInterface.MedicReporter = new jasmineInterface.jasmine.MedicReporter({ + env: jasmineEnv, + log: { logurl: medic.logurl }, + sha: medic.sha + }); + jasmineInterface.MedicReporter.initialize(); + jasmineEnv.addReporter(jasmineInterface.MedicReporter); + } + +} + +}); diff --git a/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/main.js b/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/main.js new file mode 100644 index 0000000..c3e1aa4 --- /dev/null +++ b/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/main.js @@ -0,0 +1,449 @@ +cordova.define("cordova-plugin-test-framework.main", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* global WinJS */ +/* jshint -W097 */ +'use strict'; + +var LOG_HEADER_HEIGHT = 20, + CONTENT_TOP_OFFSET = 30; + +var isWin = cordova.platformId === "windows", + isWP8 = cordova.platformId === "windowsphone"; + +/******************************************************************************/ + +function getMode(callback) { + var mode = localStorage.getItem('cdvtests-mode') || 'main'; + callback(mode); +} + +function setMode(mode) { + var handlers = { + 'main': runMain, + 'auto': runAutoTests, + 'manual': runManualTests + }; + if (!handlers.hasOwnProperty(mode)) { + console.error("Unsupported mode: " + mode); + console.error("Defaulting to 'main'"); + mode = 'main'; + } + + localStorage.setItem('cdvtests-mode', mode); + clearContent(); + + handlers[mode](); +} + +/******************************************************************************/ + +function clearContent() { + var content = document.getElementById('content'); + content.innerHTML = ''; + var log = document.getElementById('log--content'); + log.innerHTML = ''; + var buttons = document.getElementById('buttons'); + buttons.innerHTML = ''; + + setLogVisibility(false); +} + +/******************************************************************************/ + +function setTitle(title) { + var el = document.getElementById('title'); + el.textContent = title; +} + +/******************************************************************************/ + +function setLogVisibility(visible) { + if (visible) { + document.querySelector('body').classList.add('expanded-log'); + + if (isWin || isWP8) { + var h = document.querySelector('body').offsetHeight; + + document.getElementById('middle').style.height = (h * 0.6 - LOG_HEADER_HEIGHT - CONTENT_TOP_OFFSET) + "px"; + document.getElementById('middle').style.marginBottom = (h * 0.4) + "px"; + document.getElementById('middle').style.paddingBottom = (h * 0.4) + "px"; + } + } else { + document.querySelector('body').classList.remove('expanded-log'); + + if (isWin || isWP8) { + document.getElementById('middle').style.height = ""; + document.getElementById('middle').style.marginBottom = ""; + document.getElementById('middle').style.paddingBottom = ""; + } + } +} + +window.onresize = function (event) { + // Update content and log heights + if (isWin || isWP8) { + setLogVisibility(getLogVisibility()); + } +}; + +function getLogVisibility() { + var e = document.querySelector('body'); + return e.classList.contains('expanded-log'); +} + +function toggleLogVisibility() { + if (getLogVisibility()) { + setLogVisibility(false); + } else { + setLogVisibility(true); + } +} + +/******************************************************************************/ + +function attachEvents() { + document.getElementById('log--title').addEventListener('click', toggleLogVisibility); +} + +/******************************************************************************/ + +var origConsole = window.console; + +exports.wrapConsole = function() { + function appendToOnscreenLog(type, args) { + var el = document.getElementById('log--content'); + var div = document.createElement('div'); + div.classList.add('log--content--line'); + div.classList.add('log--content--line--' + type); + div.textContent = Array.prototype.slice.apply(args).map(function(arg) { + return (typeof arg === 'string') ? arg : JSON.stringify(arg); + }).join(' '); + el.appendChild(div); + // scroll to bottom + el.scrollTop = el.scrollHeight; + } + + function createCustomLogger(type) { + var medic = require('cordova-plugin-test-framework.medic'); + return function() { + origConsole[type].apply(origConsole, arguments); + // TODO: encode log type somehow for medic logs? + medic.log.apply(medic, arguments); + appendToOnscreenLog(type, arguments); + setLogVisibility(true); + }; + } + + window.console = { + log: createCustomLogger('log'), + warn: createCustomLogger('warn'), + error: createCustomLogger('error'), + }; +}; + +exports.unwrapConsole = function() { + window.console = origConsole; +}; + +/******************************************************************************/ + +function createActionButton(title, callback, appendTo) { + appendTo = appendTo ? appendTo : 'buttons'; + var buttons = document.getElementById(appendTo); + var div = document.createElement('div'); + var button = document.createElement('a'); + button.textContent = title; + button.onclick = function(e) { + e.preventDefault(); + callback(); + }; + button.classList.add('topcoat-button'); + div.appendChild(button); + buttons.appendChild(div); +} + +/******************************************************************************/ + +function setupAutoTestsEnablers(cdvtests) { + var enablerList = createEnablerList(); + + // Iterate over all the registered test modules + iterateAutoTests(cdvtests, function(api, testModule) { + // For "standard" plugins remove the common/repetitive bits of + // the api key, for use as the title. For third-party plugins, the full + // api will be used as the title + var title = api.replace(/org\.apache\.cordova\./i, '').replace(/\.tests.tests/i, ''); + + createEnablerCheckbox(api, title, testModule.getEnabled(), enablerList.id, toggleTestHandler); + }); + + updateEnabledTestCount(); +} + +/******************************************************************************/ + +function createEnablerList() { + var buttons = document.getElementById('buttons'); + + var enablerContainer = document.createElement('div'); + enablerContainer.id = 'test-enablers-container'; + + // Create header to show count of enabled/total tests + var header = document.createElement('h3'); + header.id = 'tests-enabled'; + + // Create widget to show/hide list + var expander = document.createElement('span'); + expander.id = 'test-expander'; + expander.innerText = 'Show/hide tests to be run'; + expander.onclick = toggleEnablerVisibility; + + // Create list to contain checkboxes for each test + var enablerList = document.createElement('div'); + enablerList.id = "test-list"; + + // Create select/deselect all buttons (in button bar) + var checkButtonBar = document.createElement('ul'); + checkButtonBar.classList.add('topcoat-button-bar'); + + function createSelectToggleButton(title, selected) { + var barItem = document.createElement('li'); + barItem.classList.add('topcoat-button-bar__item'); + + var link = document.createElement('a'); + link.classList.add('topcoat-button-bar__button'); + link.innerText = title; + link.href = null; + link.onclick = function(e) { + e.preventDefault(); + toggleSelected(enablerList.id, selected); + return false; + }; + + barItem.appendChild(link); + checkButtonBar.appendChild(barItem); + } + createSelectToggleButton('Check all', true); + createSelectToggleButton('Uncheck all', false); + enablerList.appendChild(checkButtonBar); + + enablerContainer.appendChild(header); + enablerContainer.appendChild(expander); + enablerContainer.appendChild(enablerList); + + buttons.appendChild(enablerContainer); + + return enablerList; +} + +/******************************************************************************/ + +function updateEnabledTestCount() { + var enabledLabel = document.getElementById('tests-enabled'); + + // Determine how many tests are currently enabled + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + var total = 0; + var enabled = 0; + iterateAutoTests(cdvtests, function(api, testModule) { + total++; + if (testModule.getEnabled()) { + enabled++; + } + }); + + if (enabled == total) { + enabledLabel.innerText = 'Running All Tests.'; + } else { + enabledLabel.innerText = 'Running ' + enabled + ' of ' + total + ' Tests.'; + } +} + +/******************************************************************************/ + +function toggleSelected(containerId, newCheckedValue) { + [].forEach.call(document.getElementById(containerId).getElementsByTagName('input'), function(input) { + if (input.type !== 'checkbox') return; + input.checked = newCheckedValue; + toggleTestEnabled(input); + }); + updateEnabledTestCount(); +} + +/******************************************************************************/ + +function toggleEnablerVisibility() { + var enablerList = document.getElementById('test-list'); + if (enablerList.classList.contains('expanded')) { + enablerList.classList.remove('expanded'); + } else { + enablerList.classList.add('expanded'); + } +} + +/******************************************************************************/ + +function createEnablerCheckbox(api, title, isEnabled, appendTo, callback) { + var container = document.getElementById(appendTo); + + var label = document.createElement('label'); + label.classList.add('topcoat-checkbox'); + + var checkbox = document.createElement('input'); + checkbox.type = "checkbox"; + checkbox.value = api; + checkbox.checked = isEnabled; + label.htmlFor = checkbox.id = 'enable_' + api; + + checkbox.onchange = function(e) { + e.preventDefault(); + callback(e); + }; + + var div = document.createElement('div'); + div.classList.add('topcoat-checkbox__checkmark'); + + var text = document.createElement('span'); + text.innerText = title; + + label.appendChild(checkbox); + label.appendChild(div); + label.appendChild(text); + + container.appendChild(label); +} + +/******************************************************************************/ + +function toggleTestHandler(event) { + var checkbox = event.target; + + toggleTestEnabled(checkbox); + updateEnabledTestCount(); +} + +/******************************************************************************/ + +function toggleTestEnabled(checkbox) { + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + cdvtests.tests[checkbox.value].setEnabled(checkbox.checked); +} + +/******************************************************************************/ + +function iterateAutoTests(cdvtests, callback) { + Object.keys(cdvtests.tests).forEach(function(api) { + var testModule = cdvtests.tests[api]; + if (!testModule.hasOwnProperty('defineAutoTests')) { + return; + } + callback(api, testModule); + }); +} + +/******************************************************************************/ + +function runAutoTests() { + setTitle('Auto Tests'); + + createActionButton('Run', setMode.bind(null, 'auto')); + createActionButton('Reset App', location.reload.bind(location)); + createActionButton('Back', setMode.bind(null, 'main')); + + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + cdvtests.init(); + setupAutoTestsEnablers(cdvtests); + + cdvtests.defineAutoTests(); + + // Run the tests! + var jasmineEnv = window.jasmine.getEnv(); + + jasmineEnv.execute(); +} + +/******************************************************************************/ + +function runManualTests() { + setTitle('Manual Tests'); + + createActionButton('Reset App', location.reload.bind(location)); + createActionButton('Back', setMode.bind(null, 'main')); + + var contentEl = document.getElementById('content'); + var beforeEach = function(title) { + clearContent(); + setTitle(title || 'Manual Tests'); + createActionButton('Reset App', location.reload.bind(location)); + createActionButton('Back', setMode.bind(null, 'manual')); + }; + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + cdvtests.defineManualTests(contentEl, beforeEach, createActionButton); +} + +/******************************************************************************/ + +function runMain() { + setTitle('Apache Cordova Plugin Tests'); + + createActionButton('Auto Tests', setMode.bind(null, 'auto')); + createActionButton('Manual Tests', setMode.bind(null, 'manual')); + createActionButton('Reset App', location.reload.bind(location)); + if (/showBack/.exec(location.hash)) { + createActionButton('Back', function() { + history.go(-1); + }); + } + + if (isWin && typeof WinJS !== 'undefined') { + var app = WinJS.Application; + app.addEventListener("error", function (err) { + // We do not want an unhandled exception to crash the test app + // Returning true marks it as being handled + return true; + }); + } +} + +/******************************************************************************/ + +exports.init = function() { + // TODO: have a way to opt-out of console wrapping in case line numbers are important. + // ...Or find a custom way to print line numbers using stack or something. + // make sure to always wrap when using medic. + attachEvents(); + exports.wrapConsole(); + + var medic = require('cordova-plugin-test-framework.medic'); + medic.load(function() { + if (medic.enabled) { + setMode('auto'); + } else { + getMode(setMode); + } + }); +}; + +/******************************************************************************/ + +}); diff --git a/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/medic.js b/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/medic.js new file mode 100644 index 0000000..c805a25 --- /dev/null +++ b/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/medic.js @@ -0,0 +1,66 @@ +cordova.define("cordova-plugin-test-framework.medic", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint -W097 */ +'use strict'; + +exports.logurl = 'http://127.0.0.1:7800'; + +exports.enabled = false; + +exports.log = function() { + if (!exports.enabled) + return; + var xhr = new XMLHttpRequest(); + xhr.open("POST", exports.logurl, true); + xhr.setRequestHeader("Content-Type", "text/plain"); + xhr.send(Array.prototype.slice.apply(arguments)); +}; + +exports.load = function (callback) { + var cfg = null; + + try { + // attempt to synchronously load medic config + var xhr = new XMLHttpRequest(); + xhr.open("GET", "../medic.json", false); + xhr.send(null); + cfg = JSON.parse(xhr.responseText); + } catch (ex) { } + + // config is available + if (cfg) { + exports.logurl = cfg.couchdb || cfg.logurl; + exports.sha = cfg.sha; + exports.enabled = true; + console.log('Loaded Medic Config: logurl=' + exports.logurl); + } else { + // config does not exist + console.log('Did not find medic config file'); + } + + setTimeout(function () { + callback(); + }, 0); +}; + +}); diff --git a/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/tests.js b/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/tests.js new file mode 100644 index 0000000..5c861b3 --- /dev/null +++ b/platforms/android/assets/www/plugins/cordova-plugin-test-framework/www/tests.js @@ -0,0 +1,138 @@ +cordova.define("cordova-plugin-test-framework.cdvtests", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint jasmine: true */ +/* jshint -W097 */ +'use strict'; + +exports.tests = Object.create(null); + +function TestModule(api) { + var name = api; + var enabled = true; + + var enabledPref = localStorage.getItem('cordova-tests-enabled-' + name); + if (enabledPref) + { + enabled = (enabledPref == true.toString()); + } + + this.getEnabled = function () { + return enabled; + }; + + this.setEnabled = function (isEnabled) { + enabled = isEnabled; + localStorage.setItem('cordova-tests-enabled-' + name, enabled); + }; +} + +function getTestsObject(api) { + exports.tests[api] = exports.tests[api] || new TestModule(api); + return exports.tests[api]; +} + +function requireAllTestModules() { + // This finds all js-modules named "tests" (regardless of plugins they came from) + var test_modules = cordova.require('cordova/plugin_list') + .map(function(jsmodule) { + return jsmodule.id; + }) + .filter(function(id) { + return /\.tests$/.test(id); + }); + + // Map auto / manual test definitions for each, but without actually running the handlers + test_modules.forEach(function(id) { + try { + var plugintests = cordova.require(id); + + if (plugintests.hasOwnProperty('defineAutoTests')) { + getTestsObject(id).defineAutoTests = function() { + describe(id + ' >>', plugintests.defineAutoTests.bind(plugintests)); + }; + } + + if (plugintests.hasOwnProperty('defineManualTests')) { + getTestsObject(id).defineManualTests = plugintests.defineManualTests.bind(plugintests); + } + } catch(ex) { + console.warn('Failed to load tests: ', id); + return; + } + }); +} + +function createJasmineInterface() { + var jasmine_helpers = require('cordova-plugin-test-framework.jasmine_helpers'); + var jasmineInterface = jasmine_helpers.setUpJasmine(); + return jasmineInterface; +} + +function attachJasmineInterfaceToGlobal() { + var jasmineInterface = createJasmineInterface(); + for (var property in jasmineInterface) { + window[property] = jasmineInterface[property]; + } +} + +function detachJasmineInterfaceFromGlobal() { + var jasmineInterface = createJasmineInterface(); + for (var property in jasmineInterface) { + delete window[property]; + } +} + +exports.defineAutoTests = function() { + requireAllTestModules(); + attachJasmineInterfaceToGlobal(); + + Object.keys(exports.tests).forEach(function(key) { + if (!exports.tests[key].getEnabled()) + return; + if (!exports.tests[key].hasOwnProperty('defineAutoTests')) + return; + exports.tests[key].defineAutoTests(); + }); +}; + +exports.defineManualTests = function(contentEl, beforeEach, createActionButton) { + requireAllTestModules(); + detachJasmineInterfaceFromGlobal(); + + Object.keys(exports.tests).forEach(function(key) { + if (!exports.tests[key].getEnabled()) + return; + if (!exports.tests[key].hasOwnProperty('defineManualTests')) + return; + createActionButton(key, function() { + beforeEach(key); + exports.tests[key].defineManualTests(contentEl, createActionButton); + }); + }); +}; + +exports.init = function() { + requireAllTestModules(); +}; + +}); diff --git a/platforms/android/assets/www/plugins/cordova-plugin-whitelist/whitelist.js b/platforms/android/assets/www/plugins/cordova-plugin-whitelist/whitelist.js index b83f579..a2ba8a3 100644 --- a/platforms/android/assets/www/plugins/cordova-plugin-whitelist/whitelist.js +++ b/platforms/android/assets/www/plugins/cordova-plugin-whitelist/whitelist.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-whitelist.whitelist", function(require, exports, module) { /* +cordova.define("cordova-plugin-whitelist.whitelist", function(require, exports, module) { +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information diff --git a/platforms/android/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js b/platforms/android/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js new file mode 100644 index 0000000..d3807de --- /dev/null +++ b/platforms/android/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js @@ -0,0 +1,510 @@ +cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Core", function(require, exports, module) { +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +var exec = require('cordova/exec'); + + +/******** + * CORE * + ********/ + +/** + * Returns the default settings. + * + * @return {Object} + */ +exports.getDefaults = function () { + return this._defaults; +}; + +/** + * Overwrite default settings. + * + * @param {Object} defaults + */ +exports.setDefaults = function (newDefaults) { + var defaults = this.getDefaults(); + + for (var key in defaults) { + if (newDefaults.hasOwnProperty(key)) { + defaults[key] = newDefaults[key]; + } + } +}; + +/** + * Schedule a new local notification. + * + * @param {Object} msgs + * The notification properties + * @param {Function} callback + * A function to be called after the notification has been canceled + * @param {Object?} scope + * The scope for the callback function + * @param {Object?} args + * skipPermission:true schedules the notifications immediatly without + * registering or checking for permission + */ +exports.schedule = function (msgs, callback, scope, args) { + var fn = function(granted) { + + if (!granted) return; + + var notifications = Array.isArray(msgs) ? msgs : [msgs]; + + for (var i = 0; i < notifications.length; i++) { + var notification = notifications[i]; + + this.mergeWithDefaults(notification); + this.convertProperties(notification); + } + + this.exec('schedule', notifications, callback, scope); + }; + + if (args && args.skipPermission) { + fn.call(this, true); + } else { + this.registerPermission(fn, this); + } +}; + +/** + * Update existing notifications specified by IDs in options. + * + * @param {Object} notifications + * The notification properties to update + * @param {Function} callback + * A function to be called after the notification has been updated + * @param {Object?} scope + * The scope for the callback function + * @param {Object?} args + * skipPermission:true schedules the notifications immediatly without + * registering or checking for permission + */ +exports.update = function (msgs, callback, scope, args) { + var fn = function(granted) { + + if (!granted) return; + + var notifications = Array.isArray(msgs) ? msgs : [msgs]; + + for (var i = 0; i < notifications.length; i++) { + var notification = notifications[i]; + + this.convertProperties(notification); + } + + this.exec('update', notifications, callback, scope); + }; + + if (args && args.skipPermission) { + fn.call(this, true); + } else { + this.registerPermission(fn, this); + } +}; + +/** + * Clear the specified notification. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A function to be called after the notification has been cleared + * @param {Object?} scope + * The scope for the callback function + */ +exports.clear = function (ids, callback, scope) { + ids = Array.isArray(ids) ? ids : [ids]; + ids = this.convertIds(ids); + + this.exec('clear', ids, callback, scope); +}; + +/** + * Clear all previously sheduled notifications. + * + * @param {Function} callback + * A function to be called after all notifications have been cleared + * @param {Object?} scope + * The scope for the callback function + */ +exports.clearAll = function (callback, scope) { + this.exec('clearAll', null, callback, scope); +}; + +/** + * Cancel the specified notifications. + * + * @param {String[]} ids + * The IDs of the notifications + * @param {Function} callback + * A function to be called after the notifications has been canceled + * @param {Object?} scope + * The scope for the callback function + */ +exports.cancel = function (ids, callback, scope) { + ids = Array.isArray(ids) ? ids : [ids]; + ids = this.convertIds(ids); + + this.exec('cancel', ids, callback, scope); +}; + +/** + * Remove all previously registered notifications. + * + * @param {Function} callback + * A function to be called after all notifications have been canceled + * @param {Object?} scope + * The scope for the callback function + */ +exports.cancelAll = function (callback, scope) { + this.exec('cancelAll', null, callback, scope); +}; + +/** + * Check if a notification with an ID is present. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isPresent = function (id, callback, scope) { + this.exec('isPresent', id || 0, callback, scope); +}; + +/** + * Check if a notification with an ID is scheduled. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isScheduled = function (id, callback, scope) { + this.exec('isScheduled', id || 0, callback, scope); +}; + +/** + * Check if a notification with an ID was triggered. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isTriggered = function (id, callback, scope) { + this.exec('isTriggered', id || 0, callback, scope); +}; + +/** + * List all local notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllIds = function (callback, scope) { + this.exec('getAllIds', null, callback, scope); +}; + +/** + * Alias for `getAllIds`. + */ +exports.getIds = function () { + this.getAllIds.apply(this, arguments); +}; + +/** + * List all scheduled notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getScheduledIds = function (callback, scope) { + this.exec('getScheduledIds', null, callback, scope); +}; + +/** + * List all triggered notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getTriggeredIds = function (callback, scope) { + this.exec('getTriggeredIds', null, callback, scope); +}; + +/** + * Property list for given local notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.get = function () { + var args = Array.apply(null, arguments); + + if (typeof args[0] == 'function') { + args.unshift([]); + } + + var ids = args[0], + callback = args[1], + scope = args[2]; + + if (!Array.isArray(ids)) { + this.exec('getSingle', Number(ids), callback, scope); + return; + } + + ids = this.convertIds(ids); + + this.exec('getAll', ids, callback, scope); +}; + +/** + * Property list for all local notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAll = function (callback, scope) { + this.exec('getAll', null, callback, scope); +}; + +/** + * Property list for given scheduled notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getScheduled = function () { + var args = Array.apply(null, arguments); + + if (typeof args[0] == 'function') { + args.unshift([]); + } + + var ids = args[0], + callback = args[1], + scope = args[2]; + + if (!Array.isArray(ids)) { + ids = [ids]; + } + + if (!Array.isArray(ids)) { + this.exec('getSingleScheduled', Number(ids), callback, scope); + return; + } + + ids = this.convertIds(ids); + + this.exec('getScheduled', ids, callback, scope); +}; + +/** + * Property list for all scheduled notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllScheduled = function (callback, scope) { + this.exec('getScheduled', null, callback, scope); +}; + +/** + * Property list for given triggered notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getTriggered = function () { + var args = Array.apply(null, arguments); + + if (typeof args[0] == 'function') { + args.unshift([]); + } + + var ids = args[0], + callback = args[1], + scope = args[2]; + + if (!Array.isArray(ids)) { + ids = [ids]; + } + + if (!Array.isArray(ids)) { + this.exec('getSingleTriggered', Number(ids), callback, scope); + return; + } + + ids = this.convertIds(ids); + + this.exec('getTriggered', ids, callback, scope); +}; + +/** + * Property list for all triggered notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllTriggered = function (callback, scope) { + this.exec('getTriggered', null, callback, scope); +}; + +/** + * Informs if the app has the permission to show notifications. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.hasPermission = function (callback, scope) { + var fn = this.createCallbackFn(callback, scope); + + if (device.platform != 'iOS') { + fn(true); + return; + } + + exec(fn, null, 'LocalNotification', 'hasPermission', []); +}; + +/** + * Register permission to show notifications if not already granted. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.registerPermission = function (callback, scope) { + + if (this._registered) { + return this.hasPermission(callback, scope); + } else { + this._registered = true; + } + + var fn = this.createCallbackFn(callback, scope); + + if (device.platform != 'iOS') { + fn(true); + return; + } + + exec(fn, null, 'LocalNotification', 'registerPermission', []); +}; + + +/********** + * EVENTS * + **********/ + +/** + * Register callback for given event. + * + * @param {String} event + * The event's name + * @param {Function} callback + * The function to be exec as callback + * @param {Object?} scope + * The callback function's scope + */ +exports.on = function (event, callback, scope) { + + if (typeof callback !== "function") + return; + + if (!this._listener[event]) { + this._listener[event] = []; + } + + var item = [callback, scope || window]; + + this._listener[event].push(item); +}; + +/** + * Unregister callback for given event. + * + * @param {String} event + * The event's name + * @param {Function} callback + * The function to be exec as callback + */ +exports.un = function (event, callback) { + var listener = this._listener[event]; + + if (!listener) + return; + + for (var i = 0; i < listener.length; i++) { + var fn = listener[i][0]; + + if (fn == callback) { + listener.splice(i, 1); + break; + } + } +}; + +}); diff --git a/platforms/android/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js b/platforms/android/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js new file mode 100644 index 0000000..b206de9 --- /dev/null +++ b/platforms/android/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js @@ -0,0 +1,316 @@ +cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Util", function(require, exports, module) { +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +var exec = require('cordova/exec'), + channel = require('cordova/channel'); + + +/*********** + * MEMBERS * + ***********/ + +// Default values +exports._defaults = { + text: '', + title: '', + sound: 'res://platform_default', + badge: 0, + id: 0, + data: undefined, + every: undefined, + at: undefined +}; + +// listener +exports._listener = {}; + +// Registered permission flag +exports._registered = false; + + +/******** + * UTIL * + ********/ + +/** + * Merge platform specific properties into the default ones. + * + * @return {Object} + * The default properties for the platform + */ +exports.applyPlatformSpecificOptions = function () { + var defaults = this._defaults; + + switch (device.platform) { + case 'Android': + defaults.icon = 'res://ic_popup_reminder'; + defaults.smallIcon = undefined; + defaults.ongoing = false; + defaults.autoClear = true; + defaults.led = 'FF0000'; + defaults.color = undefined; + break; + } + + return defaults; +}; + +/** + * Merge custom properties with the default values. + * + * @param {Object} options + * Set of custom values + * + * @retrun {Object} + * The merged property list + */ +exports.mergeWithDefaults = function (options) { + var defaults = this.getDefaults(); + + options.at = this.getValueFor(options, 'at', 'firstAt', 'date'); + options.text = this.getValueFor(options, 'text', 'message'); + options.data = this.getValueFor(options, 'data', 'json'); + + if (defaults.hasOwnProperty('autoClear')) { + options.autoClear = this.getValueFor(options, 'autoClear', 'autoCancel'); + } + + if (options.autoClear !== true && options.ongoing) { + options.autoClear = false; + } + + if (options.at === undefined || options.at === null) { + options.at = new Date(); + } + + for (var key in defaults) { + if (options[key] === null || options[key] === undefined) { + if (options.hasOwnProperty(key) && ['data','sound'].indexOf(key) > -1) { + options[key] = undefined; + } else { + options[key] = defaults[key]; + } + } + } + + for (key in options) { + if (!defaults.hasOwnProperty(key)) { + delete options[key]; + console.warn('Unknown property: ' + key); + } + } + + return options; +}; + +/** + * Convert the passed values to their required type. + * + * @param {Object} options + * Set of custom values + * + * @retrun {Object} + * The converted property list + */ +exports.convertProperties = function (options) { + + if (options.id) { + if (isNaN(options.id)) { + options.id = this.getDefaults().id; + console.warn('Id is not a number: ' + options.id); + } else { + options.id = Number(options.id); + } + } + + if (options.title) { + options.title = options.title.toString(); + } + + if (options.text) { + options.text = options.text.toString(); + } + + if (options.badge) { + if (isNaN(options.badge)) { + options.badge = this.getDefaults().badge; + console.warn('Badge number is not a number: ' + options.id); + } else { + options.badge = Number(options.badge); + } + } + + if (options.at) { + if (typeof options.at == 'object') { + options.at = options.at.getTime(); + } + + options.at = Math.round(options.at/1000); + } + + if (typeof options.data == 'object') { + options.data = JSON.stringify(options.data); + } + + if (options.every) { + if (device.platform == 'iOS' && typeof options.every != 'string') { + options.every = this.getDefaults().every; + var warning = 'Every option is not a string: ' + options.id; + warning += '. Expects one of: second, minute, hour, day, week, '; + warning += 'month, year on iOS.'; + console.warn(warning); + } + } + + return options; +}; + +/** + * Create callback, which will be executed within a specific scope. + * + * @param {Function} callbackFn + * The callback function + * @param {Object} scope + * The scope for the function + * + * @return {Function} + * The new callback function + */ +exports.createCallbackFn = function (callbackFn, scope) { + + if (typeof callbackFn != 'function') + return; + + return function () { + callbackFn.apply(scope || this, arguments); + }; +}; + +/** + * Convert the IDs to numbers. + * + * @param {String/Number[]} ids + * + * @return Array of Numbers + */ +exports.convertIds = function (ids) { + var convertedIds = []; + + for (var i = 0; i < ids.length; i++) { + convertedIds.push(Number(ids[i])); + } + + return convertedIds; +}; + +/** + * First found value for the given keys. + * + * @param {Object} options + * Object with key-value properties + * @param {String[]} keys* + * Key list + */ +exports.getValueFor = function (options) { + var keys = Array.apply(null, arguments).slice(1); + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + + if (options.hasOwnProperty(key)) { + return options[key]; + } + } +}; + +/** + * Fire event with given arguments. + * + * @param {String} event + * The event's name + * @param {args*} + * The callback's arguments + */ +exports.fireEvent = function (event) { + var args = Array.apply(null, arguments).slice(1), + listener = this._listener[event]; + + if (!listener) + return; + + for (var i = 0; i < listener.length; i++) { + var fn = listener[i][0], + scope = listener[i][1]; + + fn.apply(scope, args); + } +}; + +/** + * Execute the native counterpart. + * + * @param {String} action + * The name of the action + * @param args[] + * Array of arguments + * @param {Function} callback + * The callback function + * @param {Object} scope + * The scope for the function + */ +exports.exec = function (action, args, callback, scope) { + var fn = this.createCallbackFn(callback, scope), + params = []; + + if (Array.isArray(args)) { + params = args; + } else if (args) { + params.push(args); + } + + exec(fn, null, 'LocalNotification', action, params); +}; + + +/********* + * HOOKS * + *********/ + +// Called after 'deviceready' event +channel.deviceready.subscribe(function () { + // Device is ready now, the listeners are registered + // and all queued events can be executed. + exec(null, null, 'LocalNotification', 'deviceready', []); +}); + +// Called before 'deviceready' event +channel.onCordovaReady.subscribe(function () { + // Device plugin is ready now + channel.onCordovaInfoReady.subscribe(function () { + // Merge platform specifics into defaults + exports.applyPlatformSpecificOptions(); + }); +}); + +}); diff --git a/platforms/android/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js b/platforms/android/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js new file mode 100644 index 0000000..69b159b --- /dev/null +++ b/platforms/android/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js @@ -0,0 +1,379 @@ +cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification", function(require, exports, module) { +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + + +/************* + * INTERFACE * + *************/ + +/** + * Returns the default settings. + * + * @return {Object} + */ +exports.getDefaults = function () { + return this.core.getDefaults(); +}; + +/** + * Overwrite default settings. + * + * @param {Object} defaults + */ +exports.setDefaults = function (defaults) { + this.core.setDefaults(defaults); +}; + +/** + * Schedule a new local notification. + * + * @param {Object} notifications + * The notification properties + * @param {Function} callback + * A function to be called after the notification has been canceled + * @param {Object?} scope + * The scope for the callback function + * @param {Object?} args + * skipPermission:true schedules the notifications immediatly without + * registering or checking for permission + */ +exports.schedule = function (notifications, callback, scope, args) { + this.core.schedule(notifications, callback, scope, args); +}; + +/** + * Update existing notifications specified by IDs in options. + * + * @param {Object} notifications + * The notification properties to update + * @param {Function} callback + * A function to be called after the notification has been updated + * @param {Object?} scope + * The scope for the callback function + * @param {Object?} args + * skipPermission:true schedules the notifications immediatly without + * registering or checking for permission + */ +exports.update = function (notifications, callback, scope, args) { + this.core.update(notifications, callback, scope, args); +}; + +/** + * Clear the specified notification. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A function to be called after the notification has been cleared + * @param {Object?} scope + * The scope for the callback function + */ +exports.clear = function (ids, callback, scope) { + this.core.clear(ids, callback, scope); +}; + +/** + * Clear all previously sheduled notifications. + * + * @param {Function} callback + * A function to be called after all notifications have been cleared + * @param {Object?} scope + * The scope for the callback function + */ +exports.clearAll = function (callback, scope) { + this.core.clearAll(callback, scope); +}; + +/** + * Cancel the specified notifications. + * + * @param {String[]} ids + * The IDs of the notifications + * @param {Function} callback + * A function to be called after the notifications has been canceled + * @param {Object?} scope + * The scope for the callback function + */ +exports.cancel = function (ids, callback, scope) { + this.core.cancel(ids, callback, scope); +}; + +/** + * Remove all previously registered notifications. + * + * @param {Function} callback + * A function to be called after all notifications have been canceled + * @param {Object?} scope + * The scope for the callback function + */ +exports.cancelAll = function (callback, scope) { + this.core.cancelAll(callback, scope); +}; + +/** + * Check if a notification with an ID is present. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isPresent = function (id, callback, scope) { + this.core.isPresent(id, callback, scope); +}; + +/** + * Check if a notification with an ID is scheduled. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isScheduled = function (id, callback, scope) { + this.core.isScheduled(id, callback, scope); +}; + +/** + * Check if a notification with an ID was triggered. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isTriggered = function (id, callback, scope) { + this.core.isTriggered(id, callback, scope); +}; + +/** + * List all local notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllIds = function (callback, scope) { + this.core.getAllIds(callback, scope); +}; + +/** + * Alias for `getAllIds`. + */ +exports.getIds = function () { + this.getAllIds.apply(this, arguments); +}; + +/** + * List all scheduled notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getScheduledIds = function (callback, scope) { + this.core.getScheduledIds(callback, scope); +}; + +/** + * List all triggered notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getTriggeredIds = function (callback, scope) { + this.core.getTriggeredIds(callback, scope); +}; + +/** + * Property list for given local notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.get = function () { + this.core.get.apply(this.core, arguments); +}; + +/** + * Property list for all local notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAll = function (callback, scope) { + this.core.getAll(callback, scope); +}; + +/** + * Property list for given scheduled notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getScheduled = function () { + this.core.getScheduled.apply(this.core, arguments); +}; + +/** + * Property list for all scheduled notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllScheduled = function (callback, scope) { + this.core.getAllScheduled(callback, scope); +}; + +/** + * Property list for given triggered notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getTriggered = function () { + this.core.getTriggered.apply(this.core, arguments); +}; + +/** + * Property list for all triggered notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllTriggered = function (callback, scope) { + this.core.getAllTriggered(callback, scope); +}; + +/** + * Informs if the app has the permission to show notifications. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.hasPermission = function (callback, scope) { + this.core.hasPermission(callback, scope); +}; + +/** + * Register permission to show notifications if not already granted. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.registerPermission = function (callback, scope) { + this.core.registerPermission(callback, scope); +}; + + +/**************** + * DEPRECATIONS * + ****************/ + +/** + * Schedule a new local notification. + */ +exports.add = function () { + console.warn('Depreated: Please use `notification.local.schedule` instead.'); + + this.schedule.apply(this, arguments); +}; + +/** + * Register permission to show notifications + * if not already granted. + */ +exports.promptForPermission = function () { + console.warn('Depreated: Please use `notification.local.registerPermission` instead.'); + + this.registerPermission.apply(this, arguments); +}; + + +/********** + * EVENTS * + **********/ + +/** + * Register callback for given event. + * + * @param {String} event + * The event's name + * @param {Function} callback + * The function to be exec as callback + * @param {Object?} scope + * The callback function's scope + */ +exports.on = function (event, callback, scope) { + this.core.on(event, callback, scope); +}; + +/** + * Unregister callback for given event. + * + * @param {String} event + * The event's name + * @param {Function} callback + * The function to be exec as callback + */ +exports.un = function (event, callback) { + this.core.un(event, callback, scope); +}; + +}); diff --git a/platforms/android/assets/www/reports.html b/platforms/android/assets/www/reports.html index 3273dff..93f0fc1 100644 --- a/platforms/android/assets/www/reports.html +++ b/platforms/android/assets/www/reports.html @@ -6,7 +6,9 @@ Reports - + + + @@ -23,7 +25,7 @@ - +
    diff --git a/platforms/android/assets/www/resources/css/index.css b/platforms/android/assets/www/resources/css/index.css deleted file mode 100644 index 7db53e4..0000000 --- a/platforms/android/assets/www/resources/css/index.css +++ /dev/null @@ -1,4 +0,0 @@ -/* Stop main content being scrollable - */.noScroll { - {overflow: hidden; - } \ No newline at end of file diff --git a/platforms/android/assets/www/resources/js/alerts.js b/platforms/android/assets/www/resources/js/alerts.js index c1e5b45..0475c84 100644 --- a/platforms/android/assets/www/resources/js/alerts.js +++ b/platforms/android/assets/www/resources/js/alerts.js @@ -1,3 +1,7 @@ +var breakAlertUp = false; +var breakReminderCount = 0; +var distractedReminderCount = 0; + //Alert the user they have successfully set a custom ambient noise level function customVolumeLevelSet() { navigator.notification.alert( @@ -43,16 +47,17 @@ function stillRecordingNoiseLevelWarning() { ); } +//for some reason this nicer looking prompt broke (text input colour became white on white) //Ask the user for notes on their session. ---------------------------------------------------------------- -function askUserNotes() { - navigator.notification.prompt( - 'This is an opportunity to enter any notes you wish to remember about this session', // message - onPrompt, // callback to invoke - 'User Notes', // title - ['Ok'], // buttonLabels - ' ' // defaultText - ); -} +// function askUserNotes() { +// navigator.notification.prompt( +// 'This is an opportunity to enter any notes you wish to remember about this session', // message +// onPrompt, // callback to invoke +// 'User Notes', // title +// ['Ok'] // buttonLabels + +// ); +// } function onPrompt(results) { userNotes = results.input1; @@ -103,7 +108,7 @@ function onConfirmStopMon(buttonIndex) { function pausedPrompt() { pauseMonitoring(); navigator.notification.alert( - 'Monitoring has been paused, click OK when you wish to resume!', // message + 'Monitoring has been paused, click OK when you wish to resume.', // message resumeMonitoring, // callback 'Monitoring Paused', // title 'OK' // buttonName @@ -120,6 +125,11 @@ function checkDistractedReminder() { if (localStorage.getItem("score") > score) { if ((localStorage.getItem("score") - score) > 15) { returnToStudyAlert(); + distractedReminderCount++; + if (cordova.plugins.backgroundMode.isActive()) { + returnToStudyNotif(); + } + } } } @@ -132,7 +142,7 @@ function returnToStudyAlert() { navigator.notification.beep(1); navigator.notification.confirm( - 'Seems like you may have become a little distracted. Have you finished your study session?', // message + 'We think you may have become a little distracted. Have you finished your study session?', // message onConfirmReturn, // callback 'Sorry to interrupt, but...', // title ['Take a Break', 'Yes', 'No'] // button labels @@ -153,6 +163,14 @@ function onConfirmReturn(buttonIndex) { //continue monitoring (do nothing) } } + +function returnToStudyNotif() { + cordova.plugins.notification.local.schedule({ + id: 20, + title: "Sorry to interrupt, but...", + text: "We think you may have become a little distracted. Have you finished your study session?" + }); +} //End of Alert the user that they've been distracted for a while------------------------------------------------- @@ -161,19 +179,23 @@ function onConfirmReturn(buttonIndex) { function takeABreakAlert() { navigator.notification.beep(1); - - navigator.notification.confirm( - 'Seems like you\'ve been studying well for quite some time now. We recommend a 10 minute break for optimum brain functionality!', // message - onConfirmBreak, // callback - 'Sorry to interrupt, but...', // title - ['Continue Studying', 'Take a Break'] // button labels - ); - + if (breakAlertUp != true) { + breakAlertUp = true; + navigator.notification.confirm( + 'Seems like you\'ve been studying well for ' +((getOptimalStudyPeriod()/1000)/60) +' minutes now. We recommend a 5 to 10 minute break for optimum brain functionality!', // message + onConfirmBreak, // callback + 'Sorry to interrupt, but...', // title + ['Continue Studying', 'Take a Break'] // button labels + ); + } } function onConfirmBreak(buttonIndex) { + breakAlertUp = false; if (buttonIndex == 1) { //continue monitoring (do nothing) + timeResumed = new Date(); + } if (buttonIndex == 2) { //pause monitoring @@ -193,14 +215,29 @@ function checkBreakReminder() { if ((localStorage.getItem("oldScore") - 5) <= score) { if (score > 60) { //prompt break + if (cordova.plugins.backgroundMode.isActive()) { + takeABreakNotif(); + } takeABreakAlert(); + console.log("break suggested at: " + currentT + "time since break: " +timeSinceBreak); + localStorage.setItem("breakSuggestedTime", currentT); + localStorage.setItem("timeSinceBreak", timeSinceBreak); timeResumed = new Date(); + breakReminderCount++; } } } } } +function takeABreakNotif() { + cordova.plugins.notification.local.schedule({ + id: 10, + title: "Sorry to interrupt, but...", + text: "Seems like you've been studying well for " +((getOptimalStudyPeriod()/1000)/60) + " minutes now. We recommend a 5 to 10 minute break for optimum brain functionality!" + }); +} + function checkScore() { var score = createStudyScore(micNotStudying, micIntervalCount, accelNotStudying, accelIntervalCount);; localStorage.setItem("oldScore", score); diff --git a/platforms/android/assets/www/resources/js/backend.js b/platforms/android/assets/www/resources/js/backend.js index de020bd..e73c071 100644 --- a/platforms/android/assets/www/resources/js/backend.js +++ b/platforms/android/assets/www/resources/js/backend.js @@ -1,3 +1,4 @@ + var swFireBase = new Firebase("https://vivid-heat-9475.firebaseIO.com/"); var users = swFireBase.child('users'); @@ -19,7 +20,10 @@ function pushData() { accelIntervalCount: accelIntervalCount, accelNotStudingCount: accelNotStudying, appMessage: appMessage, - userNotes: getUserNotes() + userNotes: getUserNotes(), + distractedReminder: getDistractedBool() +" Count: " +distractedReminderCount, + breakReminder: getBreakNotifBool() +" Count: " +breakReminderCount + } ); } diff --git a/platforms/android/assets/www/resources/js/mic.js b/platforms/android/assets/www/resources/js/mic.js index b9093fd..addd671 100644 --- a/platforms/android/assets/www/resources/js/mic.js +++ b/platforms/android/assets/www/resources/js/mic.js @@ -49,44 +49,57 @@ function readMic(reading) { micOn(); } - micCount++; - micVolume.read(function(reading) { - console.log(reading.volume); - vol = reading.volume; - totalVol = totalVol + vol; - }, errorCallback); + micPulseCount++; - averageVol = totalVol / micCount; - if (averageVol > (getAmbientNoiseLevel() + 10) && micCount > 29) { - noisyBackground(); - noiseLevel = "vhigh"; - } else if (averageVol > (getAmbientNoiseLevel() + 5) && micCount > 29) { - noisyBackground(); - noiseLevel = "high"; - } else if (averageVol > getAmbientNoiseLevel() && micCount > 29) { - noisyBackground(); - noiseLevel = "medium"; - } else if (micCount > 29) { - noiseLevel = "low"; - micIntervalNSBool = "false"; //look to sampling method for more information on what this is for + //check how fast the phone can pulse mic (some phones limited) + if (localStorage.getItem("micPulseCount") == null) { + localStorage.setItem("micPulseCount", micPulseCount); + } else if (micPulseCount > localStorage.getItem("micPulseCount")) { + localStorage.setItem("micPulseCount", micPulseCount); } - - //As long as this isn't the first time this method is running, check if the sample rate needs updated. - if (localStorage.getItem("oldMicIntervalNSBool") != null) { - //console.log('running updateSampleR'); - updateSampleRate(micIntervalNSBool, micSampleRate, localStorage.getItem("oldMicIntervalNSBool"), "microphone"); + //safety precausion to make sure micPulseCount does not go above 30 + if (localStorage.getItem("accelPulseCount") > 30) { + localStorage.setItem("accelPulseCount", 30); } + if (firstRunMic != true) { + + micVolume.read(function(reading) { + // console.log("micPulseCount: " + micPulseCount + " vol: " + reading.volume); + vol = reading.volume; + totalVol = totalVol + vol; + }, errorCallback); + + averageVol = totalVol / micPulseCount; + if (averageVol > (getAmbientNoiseLevel() + 10) && micPulseCount > (localStorage.getItem("micPulseCount")-1)) { + noisyBackground(); + noiseLevel = "vhigh"; + } else if (averageVol > (getAmbientNoiseLevel() + 5) && micPulseCount > (localStorage.getItem("micPulseCount")-1)) { + noisyBackground(); + noiseLevel = "high"; + } else if (averageVol > getAmbientNoiseLevel() && micPulseCount > (localStorage.getItem("micPulseCount")-1)) { + noisyBackground(); + noiseLevel = "medium"; + } else if (micPulseCount > (localStorage.getItem("micPulseCount")-1)) { + noiseLevel = "low"; + micIntervalNSBool = "false"; //look to sampling method for more information on what this is for + } + + //As long as this isn't the first time this method is running, check if the sample rate needs updated. + if (localStorage.getItem("oldMicIntervalNSBool") != null) { + //console.log('running updateSampleR'); + //updateSampleRate(micIntervalNSBool, micSampleRate, localStorage.getItem("oldMicIntervalNSBool"), "microphone"); + } + + //This is so we can compare the values from this interval and the previous interval + if (typeof(Storage) !== "undefined") { + localStorage.setItem("oldMicIntervalNSBool", micIntervalNSBool); + + } else { + // Sorry! No Web Storage support.. + console.log("No web storage support - oh dear."); + } - //This is so we can compare the values from this interval and the previous interval - if (typeof(Storage) !== "undefined") { - localStorage.setItem("oldMicIntervalNSBool", micIntervalNSBool); - - } else { - // Sorry! No Web Storage support.. - console.log("No web storage support - oh dear."); } - - } //Loop the microphone sensor for 10 seconds (perform an interval) @@ -95,7 +108,7 @@ function micInterval() { micIntervalNSBool = false; //boolean to determine if the user is not studying during the current interval micIntervalCount++; - micCount = 0; //this is a count of how many pulses the microphones sensors has read (how many times readMic was called in this interval) + micPulseCount = 0; //this is a count of how many pulses the microphones sensors has read (how many times readMic was called in this interval) totalVol = 0; //for working out the average within readMic micSensor = setInterval(readMic, 333); //measure values every x milliseconds setTimeout(stopMicInterval, 10000); //stop reading after x milliseconds @@ -103,6 +116,7 @@ function micInterval() { //stop the mic sensing function stopMicInterval() { + firstRunMic = false; clearInterval(micSensor); clearTimeout(micSensor); clearTimeout(stopMicInterval); @@ -111,7 +125,7 @@ function stopMicInterval() { //If the surrounding noise level is above the threshold value, do these things. function noisyBackground() { - //console.log('It is noisy!'); + console.log('mic not studying count went up'); micIntervalNSBool = "true"; micNotStudying++; } @@ -124,14 +138,14 @@ function getAverageVolume() { //-------------------Recording ambient noise level within settings to set a custom threshold value----------- function recordAmbientNoiseLevel(reading) { - micCount++; + micPulseCount++; micVolume.read(function(reading) { console.log(reading.volume); vol = reading.volume; totalVol = totalVol + vol; }, errorCallback); - averageVol = totalVol / micCount; + averageVol = totalVol / micPulseCount; if (typeof(Storage) !== "undefined") { localStorage.setItem("ambientNoiseLevel", (averageVol + 1)); @@ -151,12 +165,13 @@ function startRecordingAmbientNoiseLevel(button) { micOff(); micOn(); button.disabled = true; //disable the button - micCount = 0; + micPulseCount = 0; totalVol = 0; recordLevel = setInterval(recordAmbientNoiseLevel, 200); setTimeout(killNoiseLevelRecording, 10000); setTimeout(function() { - button.disabled = false; } //enable the button again + button.disabled = false; + } //enable the button again , 10000) } diff --git a/platforms/android/assets/www/resources/js/motion.js b/platforms/android/assets/www/resources/js/motion.js index 7f2b66e..81dfdf7 100644 --- a/platforms/android/assets/www/resources/js/motion.js +++ b/platforms/android/assets/www/resources/js/motion.js @@ -1,9 +1,9 @@ // function onSuccessAcc(acceleration) { - console.log('Acceleration X: ' + acceleration.x + '\n' + - 'Acceleration Y: ' + acceleration.y + '\n' + - 'Acceleration Z: ' + acceleration.z + '\n' + - 'Timestamp: ' + acceleration.timestamp + '\n'); + // console.log('Acceleration X: ' + acceleration.x + '\n' + + // 'Acceleration Y: ' + acceleration.y + '\n' + + // 'Acceleration Z: ' + acceleration.z + '\n' + + // 'Timestamp: ' + acceleration.timestamp + '\n'); // var currentAccelValues = new accelValues(acceleration.x, acceleration.y, acceleration.z, acceleration.timestamp); //boolean for if the device is moving or not @@ -11,6 +11,11 @@ function onSuccessAcc(acceleration) { accelPulseCount++; //this is a count of how many pulses the accelerometer sensor has read (how many pulses within this interval) + + + + + //check how fast the phone can pulse accelerometer (some phones limited) if (localStorage.getItem("accelPulseCount") == null) { localStorage.setItem("accelPulseCount", accelPulseCount); @@ -20,30 +25,33 @@ function onSuccessAcc(acceleration) { //safety precausion to make sure accelPulseCount does not go above 9 if (localStorage.getItem("accelPulseCount") > 9) { localStorage.setItem("accelPulseCount", 9); -} + } //if this is the first interval run then skip (we want to count the number of pulses per interval first) - if (firstRun != true) { - - //check if phone is in motion - if (acceleration.x > 1 || acceleration.x < -1) { - moving = true; - } - if (acceleration.y > 1 || acceleration.y < -1) { - moving = true; - } - if (acceleration.z > 10.2 || acceleration.z < 8.2) { - moving = true; + if (firstRunAccel != true) { + + if (localStorage.getItem("accelX") != null) { + //check if phone was in motion + if (Math.abs(localStorage.getItem("accelX")) - Math.abs(acceleration.x) > 0.5 || Math.abs(localStorage.getItem("accelX")) - Math.abs(acceleration.x) < -0.5) { + hasMoved = true; + } + if (Math.abs(localStorage.getItem("accelY")) - Math.abs(acceleration.y) > 0.5 || Math.abs(localStorage.getItem("accelY")) - Math.abs(acceleration.y) < -0.5) { + hasMoved = true; + } + if (Math.abs(localStorage.getItem("accelZ")) - Math.abs(acceleration.z) > 0.5 || Math.abs(localStorage.getItem("accelZ")) - Math.abs(acceleration.z) < -0.5) { + hasMoved = true; + } else + hasMoved = false; + console.log("X difference: " + (Math.abs(localStorage.getItem("accelX")) - Math.abs(acceleration.x))); + console.log("Y difference: " + (Math.abs(localStorage.getItem("accelY")) - Math.abs(acceleration.y))); + console.log("Z difference: " + (Math.abs(localStorage.getItem("accelZ")) - Math.abs(acceleration.z))); } - if (moving) { - motionCount++; - } - //if total count of moving is greater than the total number of pulses per interval divided by 3 then device is said to be moving in this interval - if (motionCount > (localStorage.getItem("accelPulseCount") / 3)) { - accelNotStudying++; - accelIntervalNSBool = "true"; - //console.log("Hit the interval move loop"); + + if (hasMoved) { + console.log("accel not studying count went up"); + accelNotStudying++; + accelIntervalNSBool = "true"; stopAccelInterval(); } else if (accelPulseCount > (localStorage.getItem("accelPulseCount") - 1)) { //once the interval is nearly finished, device is not moving this interval @@ -51,6 +59,8 @@ function onSuccessAcc(acceleration) { //console.log("accelIntervalNSBool: " +accelIntervalNSBool ); accelPulseCount = 0; //console.log("Hit the interval not moving loop"); + console.log("accel not studying REMAINS the same"); + } //As long as this isn't the first time this method is running, check if the sample rate needs updated. @@ -66,8 +76,15 @@ function onSuccessAcc(acceleration) { // Sorry! No Web Storage support.. console.log("No web storage support - oh dear."); } - console.log('Device moving: ' + moving); + // console.log('Device moving: ' + moving); + console.log('Device moving: ' + hasMoved); + } + + //Store the values to compare next interval + localStorage.setItem("accelX", acceleration.x); + localStorage.setItem("accelY", acceleration.y); + localStorage.setItem("accelZ", acceleration.z); } @@ -85,7 +102,7 @@ function readAccel() { function accelInterval() { //localStorage.setItem("oldAccelIntervalNotStudyingBool", "initial"); accelPulseCount = 0; //this is a count of how many pulses the accelerometer sensor has read (how many pulses within this interval) - + hasMoved = false; //console.log("Accelerometer sampling rate: " + accelSampleRate); accelIntervalNSBool = false; //boolean to determine if the user is not studying during the current interval @@ -97,7 +114,7 @@ function accelInterval() { //finish the interval function stopAccelInterval() { - firstRun = false; + firstRunAccel = false; clearInterval(accelSensor); clearTimeout(accelSensor); clearTimeout(stopAccelInterval); diff --git a/platforms/android/assets/www/resources/js/motionOldAlgo.js b/platforms/android/assets/www/resources/js/motionOldAlgo.js new file mode 100644 index 0000000..750ae00 --- /dev/null +++ b/platforms/android/assets/www/resources/js/motionOldAlgo.js @@ -0,0 +1,104 @@ +// +function onSuccessAcc(acceleration) { + console.log('Acceleration X: ' + acceleration.x + '\n' + + 'Acceleration Y: ' + acceleration.y + '\n' + + 'Acceleration Z: ' + acceleration.z + '\n' + + 'Timestamp: ' + acceleration.timestamp + '\n'); + // var currentAccelValues = new accelValues(acceleration.x, acceleration.y, acceleration.z, acceleration.timestamp); + + //boolean for if the device is moving or not + var moving = false; + + accelPulseCount++; //this is a count of how many pulses the accelerometer sensor has read (how many pulses within this interval) + + //check how fast the phone can pulse accelerometer (some phones limited) + if (localStorage.getItem("accelPulseCount") == null) { + localStorage.setItem("accelPulseCount", accelPulseCount); + } else if (accelPulseCount > localStorage.getItem("accelPulseCount")) { + localStorage.setItem("accelPulseCount", accelPulseCount); + } + //safety precausion to make sure accelPulseCount does not go above 9 + if (localStorage.getItem("accelPulseCount") > 9) { + localStorage.setItem("accelPulseCount", 9); +} + //if this is the first interval run then skip (we want to count the number of pulses per interval first) + if (firstRunAccel != true) { + + //check if phone is in motion + if (acceleration.x > 1 || acceleration.x < -1) { + moving = true; + } + if (acceleration.y > 1 || acceleration.y < -1) { + moving = true; + } + if (acceleration.z > 10.2 || acceleration.z < 8.2) { + moving = true; + } + if (moving) { + motionCount++; + } + //if total count of moving is greater than the total number of pulses per interval divided by 3 then device is said to be moving in this interval + if (motionCount > (localStorage.getItem("accelPulseCount") / 3)) { + accelNotStudying++; + accelIntervalNSBool = "true"; + //console.log("Hit the interval move loop"); + + + stopAccelInterval(); + + } else if (accelPulseCount > (localStorage.getItem("accelPulseCount") - 1)) { //once the interval is nearly finished, device is not moving this interval + accelIntervalNSBool = "false"; + //console.log("accelIntervalNSBool: " +accelIntervalNSBool ); + accelPulseCount = 0; + //console.log("Hit the interval not moving loop"); + + } + //As long as this isn't the first time this method is running, check if the sample rate needs updated. + if (localStorage.getItem("oldAccelIntervalNSBool") != null) { + //console.log('running updateSampleR'); + //updateSampleRate(accelIntervalNSBool, accelSampleRate, localStorage.getItem("oldAccelIntervalNSBool"), "accelerometer"); + } + //This is so we can compare the values from this interval and the previous interval + if (typeof(Storage) !== "undefined") { + localStorage.setItem("oldAccelIntervalNSBool", accelIntervalNSBool); + + } else { + // Sorry! No Web Storage support.. + console.log("No web storage support - oh dear."); + } + console.log('Device moving: ' + moving); + } +} + + +function onErrorAcc() { + alert('Error: ' + error); +} + + +function readAccel() { + navigator.accelerometer.getCurrentAcceleration(onSuccessAcc, onErrorAcc); +} + + +//Loop the accelerometer sensor reading to pulse every one second for 10 seconds. +function accelInterval() { + //localStorage.setItem("oldAccelIntervalNotStudyingBool", "initial"); + accelPulseCount = 0; //this is a count of how many pulses the accelerometer sensor has read (how many pulses within this interval) + + //console.log("Accelerometer sampling rate: " + accelSampleRate); + accelIntervalNSBool = false; //boolean to determine if the user is not studying during the current interval + + accelIntervalCount++; //how many intervals the accelerometer has been monitored for during this session + motionCount = 0; //how many times the accelerometer has pulsed during this session + accelSensor = setInterval(readAccel, 1000); //measure values every x milliseconds + setTimeout(stopAccelInterval, 10000); //stop reading after x milliseconds +} + +//finish the interval +function stopAccelInterval() { + firstRunAccel = false; + clearInterval(accelSensor); + clearTimeout(accelSensor); + clearTimeout(stopAccelInterval); +} \ No newline at end of file diff --git a/platforms/android/assets/www/resources/js/reports.js b/platforms/android/assets/www/resources/js/reports.js index b79e3a2..9ebc1a0 100644 --- a/platforms/android/assets/www/resources/js/reports.js +++ b/platforms/android/assets/www/resources/js/reports.js @@ -34,7 +34,7 @@ function drawData(date, time, duration, score, appMessage, userNotes, sessionID) var sessionTable = "" sessionTable += "" sessionTable += "" - sessionTable += "" + sessionTable += "" sessionTable += "" sessionTable += "" sessionTable += "
    Date: " +date + "
    Start Time: " +time + "
    Duration: " +duration + "
    Score: " +score + "
    Score: " +score + " / 100
    App Notes: " +appMessage + "
    User Notes: " +userNotes + "
    Session ID: " +sessionID + "


    " diff --git a/platforms/android/assets/www/resources/js/sampling.js b/platforms/android/assets/www/resources/js/sampling.js index 9b40fe4..7f87c03 100644 --- a/platforms/android/assets/www/resources/js/sampling.js +++ b/platforms/android/assets/www/resources/js/sampling.js @@ -1,7 +1,7 @@ //class to control sampling rates of sensors function increaseSampleRate(currentRate) { - if (currentRate > 30000) { + if (currentRate > 30000) { //highest sampling rate is 30 seconds var newRate = currentRate - 30000; return newRate; } else { @@ -11,7 +11,7 @@ function increaseSampleRate(currentRate) { } function decreaseSampleRate(currentRate) { - if (currentRate < 1200000) { + if (currentRate < 300000) { //slowest sampling rate is 5 minutes var newRate = currentRate + 30000; return newRate; } else { diff --git a/platforms/android/assets/www/resources/js/scoring.js b/platforms/android/assets/www/resources/js/scoring.js index 51272f3..67f09cb 100644 --- a/platforms/android/assets/www/resources/js/scoring.js +++ b/platforms/android/assets/www/resources/js/scoring.js @@ -19,9 +19,9 @@ function createStudyScore(micNotStudying, micIntervalCount, accelNotStudying, ac } if (accelStudyScore > 75) { - appMessage += " There was also a lot of phone movement during this session."; + appMessage += " There was a lot of phone movement during this session."; } else if (accelStudyScore > 50) { - appMessage += " There also seemed to be quite a bit of phone movement - were you fiddling with your phone a lot?"; + appMessage += " There seemed to be quite a bit of phone movement - were you fiddling with your phone a lot?"; } else if (accelStudyScore > 25) { appMessage += " There seemed to be a moderate amount of phone movement, maybe you were fiddling with your phone every now and then?"; } else if (accelStudyScore < 25) { diff --git a/platforms/android/assets/www/resources/js/study.js b/platforms/android/assets/www/resources/js/study.js index 3830f52..b07b7c5 100644 --- a/platforms/android/assets/www/resources/js/study.js +++ b/platforms/android/assets/www/resources/js/study.js @@ -49,6 +49,11 @@ var app = { } }); + cordova.plugins.backgroundMode.setDefaults({ + title: "Session In Progress", + text: "StudyWell is running in the background." + }) + @@ -77,13 +82,13 @@ function startMonitoringSensors() { updateScore = setInterval(scoreOnStudyPage, 60000); //Check if the user wants to be reminded if they are too distracted. - if (getDistractedBool) { + if (getDistractedBool() == "true") { setTimeout(checkDistractedReminder, 600000); //first check begins at 10 mins in (score would be 100 if we did it immediately and cause the next check to immeditately flag) studyCheck = setInterval(checkDistractedReminder, 1200000); //timer to check if the users score has dropped significantly in the last 20 mins } //Check if the user wants to be reminded of breaks - if (getBreakNotifBool()) { + if (getBreakNotifBool() == "true") { // setTimeout(checkBreakReminder, 600000); //first check begins at 10 mins in (score would be 100 if we did it immediately and cause the next check to immeditately flag) // breakCheck = setInterval(checkBreakReminder, 1200000); //timer to check if the users score has dropped significantly in the last 20 mins setTimeout(checkScore, 300000); //first check begins at 10 mins in (score would be 100 if we did it immediately and cause the next check to immeditately flag) @@ -125,10 +130,10 @@ function stopMonitoringSensors() { //timeStop = new Date(); //sessionDuration = (timeStop - timeBegin) - totalDurationPaused; - if (getDistractedBool()) { + if (getDistractedBool() == "true") { clearInterval(studyCheck); } - if (getBreakNotifBool()) { + if (getBreakNotifBool() == "true") { clearInterval(breakCheck); } clearInterval(accelMonSensor); @@ -173,7 +178,7 @@ function pauseMonitoring() { timePaused = new Date(); document.getElementById('myonoffswitch').checked = false; - if (getBreakNotifBool()) { + if (getBreakNotifBool() == "true") { clearInterval(breakCheck); } @@ -197,7 +202,7 @@ function resumeMonitoring() { durationPaused = timeResumed - timePaused; //keep track of duration of pausing totalDurationPaused += durationPaused; - if (getBreakNotifBool()) { + if (getBreakNotifBool() == "true") { breakCheck = setInterval(checkBreakReminder, 60000); //check if the user should consider having a break every minute } @@ -224,7 +229,9 @@ function getUserNotes() { function initialiseMonitoring() { document.getElementById("studyPageScore").innerHTML = ""; //clear the previous score from the page. - firstRun = true; //var to check if the phone has to indentify the speed at which accel can be checked + firstRunAccel = true; //var to check if the phone has to indentify the speed at which accel can be checked + firstRunMic = true; //var to check if the phone has to indentify the speed at which accel can be checked + timeResumed = new Date(); //for checking if user should have break (used to get duration since last break) localStorage.setItem("accelPulseCount", 0); @@ -232,12 +239,14 @@ function initialiseMonitoring() { micOff(); localStorage.removeItem("oldScore"); - + localStorage.removeItem("score"); + breakReminderCount = 0; + distractedReminderCount = 0; totalDurationPaused = 0; - accelSampleRate = 30000; - micSampleRate = 30000; + accelSampleRate = 30000; //sampling rate for accelerometer + micSampleRate = 30000; //sampling rate for microphone micSteadyScoreCount = 0; micFluctuatingScoreCount = 0; accelSteadyScoreCount = 0; @@ -298,10 +307,14 @@ function disableWakeLock() { } -// function askUserNotes() { -// userNotes = prompt("This is an opportunity to enter any notes you wish to remember about this session. If you have nothing to add then just click OK."); -// localStorage.setItem("userNotes", userNotes); -// } + +//for some reason the nicer looking prompt broke (text input colour became white on white) +function askUserNotes() { + userNotes = prompt("This is an opportunity to enter any notes you wish to remember about this session. If you have nothing to add then just click OK."); + localStorage.setItem("userNotes", userNotes); + + pushData(); +} // function getUserNotes() { // if (localStorage.getItem("userNotes") != null) { diff --git a/platforms/android/assets/www/schedule.html b/platforms/android/assets/www/schedule.html index 02b456e..3acaa6c 100644 --- a/platforms/android/assets/www/schedule.html +++ b/platforms/android/assets/www/schedule.html @@ -14,7 +14,7 @@ - +
    diff --git a/platforms/android/assets/www/settings.html b/platforms/android/assets/www/settings.html index 53da3e7..99e7afa 100644 --- a/platforms/android/assets/www/settings.html +++ b/platforms/android/assets/www/settings.html @@ -11,7 +11,6 @@ - @@ -26,7 +25,7 @@ - +
    diff --git a/platforms/android/assets/www/spec/UI-help-test.js b/platforms/android/assets/www/spec/UI-help-test.js new file mode 100644 index 0000000..441e50c --- /dev/null +++ b/platforms/android/assets/www/spec/UI-help-test.js @@ -0,0 +1,133 @@ +// + +var selenium = require('selenium-webdriver'); + +describe('StudyWell Help Page UI Tests', function() { + + // Open the web app in the browser before each test is run + beforeEach(function(done) { + this.driver = new selenium.Builder(). + withCapabilities(selenium.Capabilities.chrome()). + build(); + + this.driver.get('http://localhost:8000/help.html').then(done); + }); + + // Close the website after each test is run (so that it is opened fresh each time) + afterEach(function(done) { + this.driver.quit().then(done); + }); + + // Test to ensure we are on the home page by checking the tag id attribute + it('Should be on the home page', function(done) { + var element = this.driver.findElement(selenium.By.tagName('body')); + + element.getAttribute('id').then(function(id) { + expect(id).toBe('help'); + done(); + }); + }); + + // Test the navigation bar and home button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + + // Test the navigation bar and schedule button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('sched')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/schedule'); + done(); + }); + + }); + + // Test the navigation bar and reports button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('reps')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/reports'); + done(); + }); + + }); + + // Test the navigation bar and settings button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('set')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/settings'); + done(); + }); + + }); + + // Test the navigation bar and help button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('help')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/help'); + done(); + }); + + }); + + // Test the navigation bar and survey button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('survey')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/viewform'); + done(); + }); + + }); + + }); \ No newline at end of file diff --git a/platforms/android/assets/www/spec/UI-home-test.js b/platforms/android/assets/www/spec/UI-home-test.js new file mode 100644 index 0000000..b76e64f --- /dev/null +++ b/platforms/android/assets/www/spec/UI-home-test.js @@ -0,0 +1,133 @@ +// + +var selenium = require('selenium-webdriver'); + +describe('StudyWell Home Page UI Tests', function() { + + // Open the web app in the browser before each test is run + beforeEach(function(done) { + this.driver = new selenium.Builder(). + withCapabilities(selenium.Capabilities.chrome()). + build(); + + this.driver.get('http://localhost:8000/index.html').then(done); + }); + + // Close the website after each test is run (so that it is opened fresh each time) + afterEach(function(done) { + this.driver.quit().then(done); + }); + + // Test to ensure we are on the home page by checking the tag id attribute + it('Should be on the home page', function(done) { + var element = this.driver.findElement(selenium.By.tagName('body')); + + element.getAttribute('id').then(function(id) { + expect(id).toBe('home'); + done(); + }); + }); + + // Test the navigation bar and home button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + + // Test the navigation bar and schedule button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('sched')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/schedule'); + done(); + }); + + }); + + // Test the navigation bar and reports button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('reps')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/reports'); + done(); + }); + + }); + + // Test the navigation bar and settings button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('set')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/settings'); + done(); + }); + + }); + + // Test the navigation bar and help button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('help')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/help'); + done(); + }); + + }); + + // Test the navigation bar and survey button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('survey')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/viewform'); + done(); + }); + + }); + + }); \ No newline at end of file diff --git a/platforms/android/assets/www/spec/UI-reports-test.js b/platforms/android/assets/www/spec/UI-reports-test.js new file mode 100644 index 0000000..d8643e9 --- /dev/null +++ b/platforms/android/assets/www/spec/UI-reports-test.js @@ -0,0 +1,133 @@ +// + +var selenium = require('selenium-webdriver'); + +describe('StudyWell Report Page UI Tests', function() { + + // Open the web app in the browser before each test is run + beforeEach(function(done) { + this.driver = new selenium.Builder(). + withCapabilities(selenium.Capabilities.chrome()). + build(); + + this.driver.get('http://localhost:8000/reports.html').then(done); + }); + + // Close the website after each test is run (so that it is opened fresh each time) + afterEach(function(done) { + this.driver.quit().then(done); + }); + + // Test to ensure we are on the home page by checking the tag id attribute + it('Should be on the home page', function(done) { + var element = this.driver.findElement(selenium.By.tagName('body')); + + element.getAttribute('id').then(function(id) { + expect(id).toBe('reports'); + done(); + }); + }); + + // Test the navigation bar and home button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + + // Test the navigation bar and schedule button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('sched')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/schedule'); + done(); + }); + + }); + + // Test the navigation bar and reports button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('reps')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/reports'); + done(); + }); + + }); + + // Test the navigation bar and settings button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('set')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/settings'); + done(); + }); + + }); + + // Test the navigation bar and help button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('help')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/help'); + done(); + }); + + }); + + // Test the navigation bar and survey button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('survey')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/viewform'); + done(); + }); + + }); + + }); \ No newline at end of file diff --git a/platforms/android/assets/www/spec/UI-schedule-test.js b/platforms/android/assets/www/spec/UI-schedule-test.js new file mode 100644 index 0000000..19e0895 --- /dev/null +++ b/platforms/android/assets/www/spec/UI-schedule-test.js @@ -0,0 +1,133 @@ +// + +var selenium = require('selenium-webdriver'); + +describe('StudyWell Schedule page UI Tests', function() { + + // Open the web app in the browser before each test is run + beforeEach(function(done) { + this.driver = new selenium.Builder(). + withCapabilities(selenium.Capabilities.chrome()). + build(); + + this.driver.get('http://localhost:8000/schedule.html').then(done); + }); + + // Close the website after each test is run (so that it is opened fresh each time) + afterEach(function(done) { + this.driver.quit().then(done); + }); + + // Test to ensure we are on the home page by checking the tag id attribute + it('Should be on the home page', function(done) { + var element = this.driver.findElement(selenium.By.tagName('body')); + + element.getAttribute('id').then(function(id) { + expect(id).toBe('schedule'); + done(); + }); + }); + + // Test the navigation bar and home button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + + // Test the navigation bar and schedule button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('sched')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/schedule'); + done(); + }); + + }); + + // Test the navigation bar and reports button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('reps')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/reports'); + done(); + }); + + }); + + // Test the navigation bar and settings button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('set')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/settings'); + done(); + }); + + }); + + // Test the navigation bar and help button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('help')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/help'); + done(); + }); + + }); + + // Test the navigation bar and survey button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('survey')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/viewform'); + done(); + }); + + }); + + }); \ No newline at end of file diff --git a/platforms/android/assets/www/spec/UI-settings-test.js b/platforms/android/assets/www/spec/UI-settings-test.js new file mode 100644 index 0000000..df8240b --- /dev/null +++ b/platforms/android/assets/www/spec/UI-settings-test.js @@ -0,0 +1,133 @@ +// + +var selenium = require('selenium-webdriver'); + +describe('StudyWell Settings Page UI Tests', function() { + + // Open the web app in the browser before each test is run + beforeEach(function(done) { + this.driver = new selenium.Builder(). + withCapabilities(selenium.Capabilities.chrome()). + build(); + + this.driver.get('http://localhost:8000/settings.html').then(done); + }); + + // Close the website after each test is run (so that it is opened fresh each time) + afterEach(function(done) { + this.driver.quit().then(done); + }); + + // Test to ensure we are on the home page by checking the tag id attribute + it('Should be on the home page', function(done) { + var element = this.driver.findElement(selenium.By.tagName('body')); + + element.getAttribute('id').then(function(id) { + expect(id).toBe('settings'); + done(); + }); + }); + + // Test the navigation bar and home button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + + // Test the navigation bar and schedule button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('sched')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/schedule'); + done(); + }); + + }); + + // Test the navigation bar and reports button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('reps')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/reports'); + done(); + }); + + }); + + // Test the navigation bar and settings button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('set')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/settings'); + done(); + }); + + }); + + // Test the navigation bar and help button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('help')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/help'); + done(); + }); + + }); + + // Test the navigation bar and survey button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('survey')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/viewform'); + done(); + }); + + }); + + }); \ No newline at end of file diff --git a/platforms/android/assets/www/spec/support/jasmine.json b/platforms/android/assets/www/spec/support/jasmine.json new file mode 100644 index 0000000..3ea3166 --- /dev/null +++ b/platforms/android/assets/www/spec/support/jasmine.json @@ -0,0 +1,11 @@ +{ + "spec_dir": "spec", + "spec_files": [ + "**/*[sS]pec.js" + ], + "helpers": [ + "helpers/**/*.js" + ], + "stopSpecOnExpectationFailure": false, + "random": false +} diff --git a/platforms/android/assets/www/vendors/jquery/slidemenu.hamburger.scroll.css b/platforms/android/assets/www/vendors/jquery/slidemenu.hamburger.scroll.css index 4b80ac7..6b27568 100644 --- a/platforms/android/assets/www/vendors/jquery/slidemenu.hamburger.scroll.css +++ b/platforms/android/assets/www/vendors/jquery/slidemenu.hamburger.scroll.css @@ -3,8 +3,6 @@ body { margin: 0; padding: 0; background: #eee; - overflow-x: auto; - overflow-y: auto; } a { text-decoration: none; } @@ -51,6 +49,8 @@ header { -webkit-box-shadow: -10px 0px 9px 0px rgba(0, 0, 0, 0.4); box-shadow: -10px 0px 9px 0px rgba(0, 0, 0, 0.4); overflow: auto; + overflow-x: auto; + overflow-y: auto; } nav { diff --git a/platforms/android/assets/www/vendors/js/firebase2.4.js b/platforms/android/assets/www/vendors/js/firebase2.4.js new file mode 100644 index 0000000..a4a0f92 --- /dev/null +++ b/platforms/android/assets/www/vendors/js/firebase2.4.js @@ -0,0 +1,7148 @@ +/*! @license Firebase v2.4.0 + License: https://www.firebase.com/terms/terms-of-service.html */ +(function() { + var h, n = this; + + function p(a) { + return void 0 !== a + } + + function aa() {} + + function ba(a) { + a.yb = function() { + return a.zf ? a.zf : a.zf = new a + } + } + + function ca(a) { + var b = typeof a; + if ("object" == b) + if (a) { + if (a instanceof Array) return "array"; + if (a instanceof Object) return b; + var c = Object.prototype.toString.call(a); + if ("[object Window]" == c) return "object"; + if ("[object Array]" == c || "number" == typeof a.length && "undefined" != typeof a.splice && "undefined" != typeof a.propertyIsEnumerable && !a.propertyIsEnumerable("splice")) return "array"; + if ("[object Function]" == c || "undefined" != typeof a.call && "undefined" != typeof a.propertyIsEnumerable && !a.propertyIsEnumerable("call")) return "function" + } else return "null"; + else if ("function" == b && "undefined" == typeof a.call) return "object"; + return b + } + + function da(a) { + return "array" == ca(a) + } + + function ea(a) { + var b = ca(a); + return "array" == b || "object" == b && "number" == typeof a.length + } + + function q(a) { + return "string" == typeof a + } + + function fa(a) { + return "number" == typeof a + } + + function r(a) { + return "function" == ca(a) + } + + function ga(a) { + var b = typeof a; + return "object" == b && null != a || "function" == b + } + + function ha(a, b, c) { + return a.call.apply(a.bind, arguments) + } + + function ia(a, b, c) { + if (!a) throw Error(); + if (2 < arguments.length) { + var d = Array.prototype.slice.call(arguments, 2); + return function() { + var c = Array.prototype.slice.call(arguments); + Array.prototype.unshift.apply(c, d); + return a.apply(b, c) + } + } + return function() { + return a.apply(b, arguments) + } + } + + function u(a, b, c) { + u = Function.prototype.bind && -1 != Function.prototype.bind.toString().indexOf("native code") ? ha : ia; + return u.apply(null, arguments) + } + var ja = Date.now || function() { + return +new Date + }; + + function ka(a, b) { + function c() {} + c.prototype = b.prototype; + a.nh = b.prototype; + a.prototype = new c; + a.prototype.constructor = a; + a.jh = function(a, c, f) { + for (var g = Array(arguments.length - 2), k = 2; k < arguments.length; k++) g[k - 2] = arguments[k]; + return b.prototype[c].apply(a, g) + } + }; + + function la(a) { + if (Error.captureStackTrace) Error.captureStackTrace(this, la); + else { + var b = Error().stack; + b && (this.stack = b) + } + a && (this.message = String(a)) + } + ka(la, Error); + la.prototype.name = "CustomError"; + + function v(a, b) { + for (var c in a) b.call(void 0, a[c], c, a) + } + + function ma(a, b) { + var c = {}, + d; + for (d in a) c[d] = b.call(void 0, a[d], d, a); + return c + } + + function na(a, b) { + for (var c in a) + if (!b.call(void 0, a[c], c, a)) return !1; + return !0 + } + + function oa(a) { + var b = 0, + c; + for (c in a) b++; + return b + } + + function pa(a) { + for (var b in a) return b + } + + function qa(a) { + var b = [], + c = 0, + d; + for (d in a) b[c++] = a[d]; + return b + } + + function ra(a) { + var b = [], + c = 0, + d; + for (d in a) b[c++] = d; + return b + } + + function sa(a, b) { + for (var c in a) + if (a[c] == b) return !0; + return !1 + } + + function ta(a, b, c) { + for (var d in a) + if (b.call(c, a[d], d, a)) return d + } + + function ua(a, b) { + var c = ta(a, b, void 0); + return c && a[c] + } + + function va(a) { + for (var b in a) return !1; + return !0 + } + + function wa(a) { + var b = {}, + c; + for (c in a) b[c] = a[c]; + return b + } + var xa = "constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "); + + function ya(a, b) { + for (var c, d, e = 1; e < arguments.length; e++) { + d = arguments[e]; + for (c in d) a[c] = d[c]; + for (var f = 0; f < xa.length; f++) c = xa[f], Object.prototype.hasOwnProperty.call(d, c) && (a[c] = d[c]) + } + }; + + function za(a) { + a = String(a); + if (/^\s*$/.test(a) ? 0 : /^[\],:{}\s\u2028\u2029]*$/.test(a.replace(/\\["\\\/bfnrtu]/g, "@").replace(/"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g, ""))) try { + return eval("(" + a + ")") + } catch (b) {} + throw Error("Invalid JSON string: " + a); + } + + function Aa() { + this.Vd = void 0 + } + + function Ba(a, b, c) { + switch (typeof b) { + case "string": + Ca(b, c); + break; + case "number": + c.push(isFinite(b) && !isNaN(b) ? b : "null"); + break; + case "boolean": + c.push(b); + break; + case "undefined": + c.push("null"); + break; + case "object": + if (null == b) { + c.push("null"); + break + } + if (da(b)) { + var d = b.length; + c.push("["); + for (var e = "", f = 0; f < d; f++) c.push(e), e = b[f], Ba(a, a.Vd ? a.Vd.call(b, String(f), e) : e, c), e = ","; + c.push("]"); + break + } + c.push("{"); + d = ""; + for (f in b) Object.prototype.hasOwnProperty.call(b, f) && (e = b[f], "function" != typeof e && (c.push(d), Ca(f, c), + c.push(":"), Ba(a, a.Vd ? a.Vd.call(b, f, e) : e, c), d = ",")); + c.push("}"); + break; + case "function": + break; + default: + throw Error("Unknown type: " + typeof b); + } + } + var Da = { + '"': '\\"', + "\\": "\\\\", + "/": "\\/", + "\b": "\\b", + "\f": "\\f", + "\n": "\\n", + "\r": "\\r", + "\t": "\\t", + "\x0B": "\\u000b" + }, + Ea = /\uffff/.test("\uffff") ? /[\\\"\x00-\x1f\x7f-\uffff]/g : /[\\\"\x00-\x1f\x7f-\xff]/g; + + function Ca(a, b) { + b.push('"', a.replace(Ea, function(a) { + if (a in Da) return Da[a]; + var b = a.charCodeAt(0), + e = "\\u"; + 16 > b ? e += "000" : 256 > b ? e += "00" : 4096 > b && (e += "0"); + return Da[a] = e + b.toString(16) + }), '"') + }; + + function Fa() { + return Math.floor(2147483648 * Math.random()).toString(36) + Math.abs(Math.floor(2147483648 * Math.random()) ^ ja()).toString(36) + }; + var w; + a: { + var Ga = n.navigator; + if (Ga) { + var Ha = Ga.userAgent; + if (Ha) { + w = Ha; + break a + } + } + w = "" + }; + + function Ia() { + this.Ya = -1 + }; + + function Ja() { + this.Ya = -1; + this.Ya = 64; + this.P = []; + this.pe = []; + this.eg = []; + this.Od = []; + this.Od[0] = 128; + for (var a = 1; a < this.Ya; ++a) this.Od[a] = 0; + this.ge = this.ec = 0; + this.reset() + } + ka(Ja, Ia); + Ja.prototype.reset = function() { + this.P[0] = 1732584193; + this.P[1] = 4023233417; + this.P[2] = 2562383102; + this.P[3] = 271733878; + this.P[4] = 3285377520; + this.ge = this.ec = 0 + }; + + function Ka(a, b, c) { + c || (c = 0); + var d = a.eg; + if (q(b)) + for (var e = 0; 16 > e; e++) d[e] = b.charCodeAt(c) << 24 | b.charCodeAt(c + 1) << 16 | b.charCodeAt(c + 2) << 8 | b.charCodeAt(c + 3), c += 4; + else + for (e = 0; 16 > e; e++) d[e] = b[c] << 24 | b[c + 1] << 16 | b[c + 2] << 8 | b[c + 3], c += 4; + for (e = 16; 80 > e; e++) { + var f = d[e - 3] ^ d[e - 8] ^ d[e - 14] ^ d[e - 16]; + d[e] = (f << 1 | f >>> 31) & 4294967295 + } + b = a.P[0]; + c = a.P[1]; + for (var g = a.P[2], k = a.P[3], m = a.P[4], l, e = 0; 80 > e; e++) 40 > e ? 20 > e ? (f = k ^ c & (g ^ k), l = 1518500249) : (f = c ^ g ^ k, l = 1859775393) : 60 > e ? (f = c & g | k & (c | g), l = 2400959708) : (f = c ^ g ^ k, l = 3395469782), f = (b << + 5 | b >>> 27) + f + m + l + d[e] & 4294967295, m = k, k = g, g = (c << 30 | c >>> 2) & 4294967295, c = b, b = f; + a.P[0] = a.P[0] + b & 4294967295; + a.P[1] = a.P[1] + c & 4294967295; + a.P[2] = a.P[2] + g & 4294967295; + a.P[3] = a.P[3] + k & 4294967295; + a.P[4] = a.P[4] + m & 4294967295 + } + Ja.prototype.update = function(a, b) { + if (null != a) { + p(b) || (b = a.length); + for (var c = b - this.Ya, d = 0, e = this.pe, f = this.ec; d < b;) { + if (0 == f) + for (; d <= c;) Ka(this, a, d), d += this.Ya; + if (q(a)) + for (; d < b;) { + if (e[f] = a.charCodeAt(d), ++f, ++d, f == this.Ya) { + Ka(this, e); + f = 0; + break + } + } else + for (; d < b;) + if (e[f] = a[d], ++f, ++d, f == this.Ya) { + Ka(this, e); + f = 0; + break + } + } + this.ec = f; + this.ge += b + } + }; + var x = Array.prototype, + La = x.indexOf ? function(a, b, c) { + return x.indexOf.call(a, b, c) + } : function(a, b, c) { + c = null == c ? 0 : 0 > c ? Math.max(0, a.length + c) : c; + if (q(a)) return q(b) && 1 == b.length ? a.indexOf(b, c) : -1; + for (; c < a.length; c++) + if (c in a && a[c] === b) return c; + return -1 + }, + Ma = x.forEach ? function(a, b, c) { + x.forEach.call(a, b, c) + } : function(a, b, c) { + for (var d = a.length, e = q(a) ? a.split("") : a, f = 0; f < d; f++) f in e && b.call(c, e[f], f, a) + }, + Na = x.filter ? function(a, b, c) { + return x.filter.call(a, b, c) + } : function(a, b, c) { + for (var d = a.length, e = [], f = 0, g = q(a) ? + a.split("") : a, k = 0; k < d; k++) + if (k in g) { + var m = g[k]; + b.call(c, m, k, a) && (e[f++] = m) + } + return e + }, + Oa = x.map ? function(a, b, c) { + return x.map.call(a, b, c) + } : function(a, b, c) { + for (var d = a.length, e = Array(d), f = q(a) ? a.split("") : a, g = 0; g < d; g++) g in f && (e[g] = b.call(c, f[g], g, a)); + return e + }, + Pa = x.reduce ? function(a, b, c, d) { + for (var e = [], f = 1, g = arguments.length; f < g; f++) e.push(arguments[f]); + d && (e[0] = u(b, d)); + return x.reduce.apply(a, e) + } : function(a, b, c, d) { + var e = c; + Ma(a, function(c, g) { + e = b.call(d, e, c, g, a) + }); + return e + }, + Qa = x.every ? function(a, b, + c) { + return x.every.call(a, b, c) + } : function(a, b, c) { + for (var d = a.length, e = q(a) ? a.split("") : a, f = 0; f < d; f++) + if (f in e && !b.call(c, e[f], f, a)) return !1; + return !0 + }; + + function Ra(a, b) { + var c = Sa(a, b, void 0); + return 0 > c ? null : q(a) ? a.charAt(c) : a[c] + } + + function Sa(a, b, c) { + for (var d = a.length, e = q(a) ? a.split("") : a, f = 0; f < d; f++) + if (f in e && b.call(c, e[f], f, a)) return f; + return -1 + } + + function Ta(a, b) { + var c = La(a, b); + 0 <= c && x.splice.call(a, c, 1) + } + + function Ua(a, b, c) { + return 2 >= arguments.length ? x.slice.call(a, b) : x.slice.call(a, b, c) + } + + function Va(a, b) { + a.sort(b || Wa) + } + + function Wa(a, b) { + return a > b ? 1 : a < b ? -1 : 0 + }; + + function Xa(a) { + n.setTimeout(function() { + throw a; + }, 0) + } + var Ya; + + function Za() { + var a = n.MessageChannel; + "undefined" === typeof a && "undefined" !== typeof window && window.postMessage && window.addEventListener && -1 == w.indexOf("Presto") && (a = function() { + var a = document.createElement("iframe"); + a.style.display = "none"; + a.src = ""; + document.documentElement.appendChild(a); + var b = a.contentWindow, + a = b.document; + a.open(); + a.write(""); + a.close(); + var c = "callImmediate" + Math.random(), + d = "file:" == b.location.protocol ? "*" : b.location.protocol + "//" + b.location.host, + a = u(function(a) { + if (("*" == d || a.origin == + d) && a.data == c) this.port1.onmessage() + }, this); + b.addEventListener("message", a, !1); + this.port1 = {}; + this.port2 = { + postMessage: function() { + b.postMessage(c, d) + } + } + }); + if ("undefined" !== typeof a && -1 == w.indexOf("Trident") && -1 == w.indexOf("MSIE")) { + var b = new a, + c = {}, + d = c; + b.port1.onmessage = function() { + if (p(c.next)) { + c = c.next; + var a = c.hb; + c.hb = null; + a() + } + }; + return function(a) { + d.next = { + hb: a + }; + d = d.next; + b.port2.postMessage(0) + } + } + return "undefined" !== typeof document && "onreadystatechange" in document.createElement("script") ? function(a) { + var b = + document.createElement("script"); + b.onreadystatechange = function() { + b.onreadystatechange = null; + b.parentNode.removeChild(b); + b = null; + a(); + a = null + }; + document.documentElement.appendChild(b) + } : function(a) { + n.setTimeout(a, 0) + } + }; + + function $a(a, b) { + ab || bb(); + cb || (ab(), cb = !0); + db.push(new eb(a, b)) + } + var ab; + + function bb() { + if (n.Promise && n.Promise.resolve) { + var a = n.Promise.resolve(); + ab = function() { + a.then(fb) + } + } else ab = function() { + var a = fb; + !r(n.setImmediate) || n.Window && n.Window.prototype && n.Window.prototype.setImmediate == n.setImmediate ? (Ya || (Ya = Za()), Ya(a)) : n.setImmediate(a) + } + } + var cb = !1, + db = []; + [].push(function() { + cb = !1; + db = [] + }); + + function fb() { + for (; db.length;) { + var a = db; + db = []; + for (var b = 0; b < a.length; b++) { + var c = a[b]; + try { + c.yg.call(c.scope) + } catch (d) { + Xa(d) + } + } + } + cb = !1 + } + + function eb(a, b) { + this.yg = a; + this.scope = b + }; + var gb = -1 != w.indexOf("Opera") || -1 != w.indexOf("OPR"), + hb = -1 != w.indexOf("Trident") || -1 != w.indexOf("MSIE"), + ib = -1 != w.indexOf("Gecko") && -1 == w.toLowerCase().indexOf("webkit") && !(-1 != w.indexOf("Trident") || -1 != w.indexOf("MSIE")), + jb = -1 != w.toLowerCase().indexOf("webkit"); + (function() { + var a = "", + b; + if (gb && n.opera) return a = n.opera.version, r(a) ? a() : a; + ib ? b = /rv\:([^\);]+)(\)|;)/ : hb ? b = /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/ : jb && (b = /WebKit\/(\S+)/); + b && (a = (a = b.exec(w)) ? a[1] : ""); + return hb && (b = (b = n.document) ? b.documentMode : void 0, b > parseFloat(a)) ? String(b) : a + })(); + var kb = null, + lb = null, + mb = null; + + function nb(a, b) { + if (!ea(a)) throw Error("encodeByteArray takes an array as a parameter"); + ob(); + for (var c = b ? lb : kb, d = [], e = 0; e < a.length; e += 3) { + var f = a[e], + g = e + 1 < a.length, + k = g ? a[e + 1] : 0, + m = e + 2 < a.length, + l = m ? a[e + 2] : 0, + t = f >> 2, + f = (f & 3) << 4 | k >> 4, + k = (k & 15) << 2 | l >> 6, + l = l & 63; + m || (l = 64, g || (k = 64)); + d.push(c[t], c[f], c[k], c[l]) + } + return d.join("") + } + + function ob() { + if (!kb) { + kb = {}; + lb = {}; + mb = {}; + for (var a = 0; 65 > a; a++) kb[a] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a), lb[a] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.".charAt(a), mb[lb[a]] = a, 62 <= a && (mb["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a)] = a) + } + }; + + function pb(a, b) { + this.N = qb; + this.Rf = void 0; + this.Ba = this.Ha = null; + this.yd = this.ye = !1; + if (a == rb) sb(this, tb, b); + else try { + var c = this; + a.call(b, function(a) { + sb(c, tb, a) + }, function(a) { + if (!(a instanceof ub)) try { + if (a instanceof Error) throw a; + throw Error("Promise rejected."); + } catch (b) {} + sb(c, vb, a) + }) + } catch (d) { + sb(this, vb, d) + } + } + var qb = 0, + tb = 2, + vb = 3; + + function rb() {} + pb.prototype.then = function(a, b, c) { + return wb(this, r(a) ? a : null, r(b) ? b : null, c) + }; + pb.prototype.then = pb.prototype.then; + pb.prototype.$goog_Thenable = !0; + pb.prototype.cancel = function(a) { + this.N == qb && $a(function() { + var b = new ub(a); + xb(this, b) + }, this) + }; + + function xb(a, b) { + if (a.N == qb) + if (a.Ha) { + var c = a.Ha; + if (c.Ba) { + for (var d = 0, e = -1, f = 0, g; g = c.Ba[f]; f++) + if (g = g.o) + if (d++, g == a && (e = f), 0 <= e && 1 < d) break; + 0 <= e && (c.N == qb && 1 == d ? xb(c, b) : (d = c.Ba.splice(e, 1)[0], yb(c, d, vb, b))) + } + a.Ha = null + } else sb(a, vb, b) + } + + function zb(a, b) { + a.Ba && a.Ba.length || a.N != tb && a.N != vb || Ab(a); + a.Ba || (a.Ba = []); + a.Ba.push(b) + } + + function wb(a, b, c, d) { + var e = { + o: null, + Hf: null, + Jf: null + }; + e.o = new pb(function(a, g) { + e.Hf = b ? function(c) { + try { + var e = b.call(d, c); + a(e) + } catch (l) { + g(l) + } + } : a; + e.Jf = c ? function(b) { + try { + var e = c.call(d, b); + !p(e) && b instanceof ub ? g(b) : a(e) + } catch (l) { + g(l) + } + } : g + }); + e.o.Ha = a; + zb(a, e); + return e.o + } + pb.prototype.Yf = function(a) { + this.N = qb; + sb(this, tb, a) + }; + pb.prototype.Zf = function(a) { + this.N = qb; + sb(this, vb, a) + }; + + function sb(a, b, c) { + if (a.N == qb) { + if (a == c) b = vb, c = new TypeError("Promise cannot resolve to itself"); + else { + var d; + if (c) try { + d = !!c.$goog_Thenable + } catch (e) { + d = !1 + } else d = !1; + if (d) { + a.N = 1; + c.then(a.Yf, a.Zf, a); + return + } + if (ga(c)) try { + var f = c.then; + if (r(f)) { + Bb(a, c, f); + return + } + } catch (g) { + b = vb, c = g + } + } + a.Rf = c; + a.N = b; + a.Ha = null; + Ab(a); + b != vb || c instanceof ub || Cb(a, c) + } + } + + function Bb(a, b, c) { + function d(b) { + f || (f = !0, a.Zf(b)) + } + + function e(b) { + f || (f = !0, a.Yf(b)) + } + a.N = 1; + var f = !1; + try { + c.call(b, e, d) + } catch (g) { + d(g) + } + } + + function Ab(a) { + a.ye || (a.ye = !0, $a(a.wg, a)) + } + pb.prototype.wg = function() { + for (; this.Ba && this.Ba.length;) { + var a = this.Ba; + this.Ba = null; + for (var b = 0; b < a.length; b++) yb(this, a[b], this.N, this.Rf) + } + this.ye = !1 + }; + + function yb(a, b, c, d) { + if (c == tb) b.Hf(d); + else { + if (b.o) + for (; a && a.yd; a = a.Ha) a.yd = !1; + b.Jf(d) + } + } + + function Cb(a, b) { + a.yd = !0; + $a(function() { + a.yd && Db.call(null, b) + }) + } + var Db = Xa; + + function ub(a) { + la.call(this, a) + } + ka(ub, la); + ub.prototype.name = "cancel"; + var Eb = Eb || "2.4.0"; + + function y(a, b) { + return Object.prototype.hasOwnProperty.call(a, b) + } + + function z(a, b) { + if (Object.prototype.hasOwnProperty.call(a, b)) return a[b] + } + + function Fb(a, b) { + for (var c in a) Object.prototype.hasOwnProperty.call(a, c) && b(c, a[c]) + } + + function Gb(a) { + var b = {}; + Fb(a, function(a, d) { + b[a] = d + }); + return b + } + + function Hb(a) { + return "object" === typeof a && null !== a + }; + + function Ib(a) { + var b = []; + Fb(a, function(a, d) { + da(d) ? Ma(d, function(d) { + b.push(encodeURIComponent(a) + "=" + encodeURIComponent(d)) + }) : b.push(encodeURIComponent(a) + "=" + encodeURIComponent(d)) + }); + return b.length ? "&" + b.join("&") : "" + } + + function Jb(a) { + var b = {}; + a = a.replace(/^\?/, "").split("&"); + Ma(a, function(a) { + a && (a = a.split("="), b[a[0]] = a[1]) + }); + return b + }; + + function Kb(a, b) { + if (!a) throw Lb(b); + } + + function Lb(a) { + return Error("Firebase (" + Eb + ") INTERNAL ASSERT FAILED: " + a) + }; + var Mb = n.Promise || pb; + + function B() { + var a = this; + this.reject = this.resolve = null; + this.D = new Mb(function(b, c) { + a.resolve = b; + a.reject = c + }) + } + + function C(a, b) { + return function(c, d) { + c ? a.reject(c) : a.resolve(d); + r(b) && (Nb(a.D), 1 === b.length ? b(c) : b(c, d)) + } + } + + function Nb(a) { + a.then(void 0, aa) + }; + + function Ob(a) { + for (var b = [], c = 0, d = 0; d < a.length; d++) { + var e = a.charCodeAt(d); + 55296 <= e && 56319 >= e && (e -= 55296, d++, Kb(d < a.length, "Surrogate pair missing trail surrogate."), e = 65536 + (e << 10) + (a.charCodeAt(d) - 56320)); + 128 > e ? b[c++] = e : (2048 > e ? b[c++] = e >> 6 | 192 : (65536 > e ? b[c++] = e >> 12 | 224 : (b[c++] = e >> 18 | 240, b[c++] = e >> 12 & 63 | 128), b[c++] = e >> 6 & 63 | 128), b[c++] = e & 63 | 128) + } + return b + } + + function Pb(a) { + for (var b = 0, c = 0; c < a.length; c++) { + var d = a.charCodeAt(c); + 128 > d ? b++ : 2048 > d ? b += 2 : 55296 <= d && 56319 >= d ? (b += 4, c++) : b += 3 + } + return b + }; + + function D(a, b, c, d) { + var e; + d < b ? e = "at least " + b : d > c && (e = 0 === c ? "none" : "no more than " + c); + if (e) throw Error(a + " failed: Was called with " + d + (1 === d ? " argument." : " arguments.") + " Expects " + e + "."); + } + + function E(a, b, c) { + var d = ""; + switch (b) { + case 1: + d = c ? "first" : "First"; + break; + case 2: + d = c ? "second" : "Second"; + break; + case 3: + d = c ? "third" : "Third"; + break; + case 4: + d = c ? "fourth" : "Fourth"; + break; + default: + throw Error("errorPrefix called with argumentNumber > 4. Need to update it?"); + } + return a = a + " failed: " + (d + " argument ") + } + + function F(a, b, c, d) { + if ((!d || p(c)) && !r(c)) throw Error(E(a, b, d) + "must be a valid function."); + } + + function Qb(a, b, c) { + if (p(c) && (!ga(c) || null === c)) throw Error(E(a, b, !0) + "must be a valid context object."); + }; + + function Rb(a) { + return "undefined" !== typeof JSON && p(JSON.parse) ? JSON.parse(a) : za(a) + } + + function G(a) { + if ("undefined" !== typeof JSON && p(JSON.stringify)) a = JSON.stringify(a); + else { + var b = []; + Ba(new Aa, a, b); + a = b.join("") + } + return a + }; + + function Sb() { + this.Zd = H + } + Sb.prototype.j = function(a) { + return this.Zd.S(a) + }; + Sb.prototype.toString = function() { + return this.Zd.toString() + }; + + function Tb() {} + Tb.prototype.uf = function() { + return null + }; + Tb.prototype.Ce = function() { + return null + }; + var Ub = new Tb; + + function Vb(a, b, c) { + this.bg = a; + this.Oa = b; + this.Nd = c + } + Vb.prototype.uf = function(a) { + var b = this.Oa.Q; + if (Wb(b, a)) return b.j().T(a); + b = null != this.Nd ? new Xb(this.Nd, !0, !1) : this.Oa.w(); + return this.bg.Bc(a, b) + }; + Vb.prototype.Ce = function(a, b, c) { + var d = null != this.Nd ? this.Nd : Yb(this.Oa); + a = this.bg.qe(d, b, 1, c, a); + return 0 === a.length ? null : a[0] + }; + + function Zb() { + this.xb = [] + } + + function $b(a, b) { + for (var c = null, d = 0; d < b.length; d++) { + var e = b[d], + f = e.cc(); + null === c || f.ea(c.cc()) || (a.xb.push(c), c = null); + null === c && (c = new ac(f)); + c.add(e) + } + c && a.xb.push(c) + } + + function bc(a, b, c) { + $b(a, c); + cc(a, function(a) { + return a.ea(b) + }) + } + + function dc(a, b, c) { + $b(a, c); + cc(a, function(a) { + return a.contains(b) || b.contains(a) + }) + } + + function cc(a, b) { + for (var c = !0, d = 0; d < a.xb.length; d++) { + var e = a.xb[d]; + if (e) + if (e = e.cc(), b(e)) { + for (var e = a.xb[d], f = 0; f < e.xd.length; f++) { + var g = e.xd[f]; + if (null !== g) { + e.xd[f] = null; + var k = g.Zb(); + ec && fc("event: " + g.toString()); + gc(k) + } + } + a.xb[d] = null + } else c = !1 + } + c && (a.xb = []) + } + + function ac(a) { + this.ta = a; + this.xd = [] + } + ac.prototype.add = function(a) { + this.xd.push(a) + }; + ac.prototype.cc = function() { + return this.ta + }; + + function J(a, b, c, d) { + this.type = a; + this.Na = b; + this.Za = c; + this.Oe = d; + this.Td = void 0 + } + + function hc(a) { + return new J(ic, a) + } + var ic = "value"; + + function jc(a, b, c, d) { + this.xe = b; + this.be = c; + this.Td = d; + this.wd = a + } + jc.prototype.cc = function() { + var a = this.be.Mb(); + return "value" === this.wd ? a.path : a.parent().path + }; + jc.prototype.De = function() { + return this.wd + }; + jc.prototype.Zb = function() { + return this.xe.Zb(this) + }; + jc.prototype.toString = function() { + return this.cc().toString() + ":" + this.wd + ":" + G(this.be.qf()) + }; + + function kc(a, b, c) { + this.xe = a; + this.error = b; + this.path = c + } + kc.prototype.cc = function() { + return this.path + }; + kc.prototype.De = function() { + return "cancel" + }; + kc.prototype.Zb = function() { + return this.xe.Zb(this) + }; + kc.prototype.toString = function() { + return this.path.toString() + ":cancel" + }; + + function Xb(a, b, c) { + this.A = a; + this.ga = b; + this.Yb = c + } + + function lc(a) { + return a.ga + } + + function mc(a) { + return a.Yb + } + + function nc(a, b) { + return b.e() ? a.ga && !a.Yb : Wb(a, K(b)) + } + + function Wb(a, b) { + return a.ga && !a.Yb || a.A.Fa(b) + } + Xb.prototype.j = function() { + return this.A + }; + + function oc(a) { + this.pg = a; + this.Gd = null + } + oc.prototype.get = function() { + var a = this.pg.get(), + b = wa(a); + if (this.Gd) + for (var c in this.Gd) b[c] -= this.Gd[c]; + this.Gd = a; + return b + }; + + function pc(a, b) { + this.Vf = {}; + this.hd = new oc(a); + this.da = b; + var c = 1E4 + 2E4 * Math.random(); + setTimeout(u(this.Of, this), Math.floor(c)) + } + pc.prototype.Of = function() { + var a = this.hd.get(), + b = {}, + c = !1, + d; + for (d in a) 0 < a[d] && y(this.Vf, d) && (b[d] = a[d], c = !0); + c && this.da.Ye(b); + setTimeout(u(this.Of, this), Math.floor(6E5 * Math.random())) + }; + + function qc() { + this.Hc = {} + } + + function rc(a, b, c) { + p(c) || (c = 1); + y(a.Hc, b) || (a.Hc[b] = 0); + a.Hc[b] += c + } + qc.prototype.get = function() { + return wa(this.Hc) + }; + var sc = {}, + tc = {}; + + function uc(a) { + a = a.toString(); + sc[a] || (sc[a] = new qc); + return sc[a] + } + + function vc(a, b) { + var c = a.toString(); + tc[c] || (tc[c] = b()); + return tc[c] + }; + + function L(a, b) { + this.name = a; + this.U = b + } + + function wc(a, b) { + return new L(a, b) + }; + + function xc(a, b) { + return yc(a.name, b.name) + } + + function zc(a, b) { + return yc(a, b) + }; + + function Ac(a, b, c) { + this.type = Bc; + this.source = a; + this.path = b; + this.Ja = c + } + Ac.prototype.$c = function(a) { + return this.path.e() ? new Ac(this.source, M, this.Ja.T(a)) : new Ac(this.source, N(this.path), this.Ja) + }; + Ac.prototype.toString = function() { + return "Operation(" + this.path + ": " + this.source.toString() + " overwrite: " + this.Ja.toString() + ")" + }; + + function Cc(a, b) { + this.type = Dc; + this.source = a; + this.path = b + } + Cc.prototype.$c = function() { + return this.path.e() ? new Cc(this.source, M) : new Cc(this.source, N(this.path)) + }; + Cc.prototype.toString = function() { + return "Operation(" + this.path + ": " + this.source.toString() + " listen_complete)" + }; + + function Ec(a, b) { + this.Pa = a; + this.xa = b ? b : Fc + } + h = Ec.prototype; + h.Sa = function(a, b) { + return new Ec(this.Pa, this.xa.Sa(a, b, this.Pa).$(null, null, !1, null, null)) + }; + h.remove = function(a) { + return new Ec(this.Pa, this.xa.remove(a, this.Pa).$(null, null, !1, null, null)) + }; + h.get = function(a) { + for (var b, c = this.xa; !c.e();) { + b = this.Pa(a, c.key); + if (0 === b) return c.value; + 0 > b ? c = c.left : 0 < b && (c = c.right) + } + return null + }; + + function Gc(a, b) { + for (var c, d = a.xa, e = null; !d.e();) { + c = a.Pa(b, d.key); + if (0 === c) { + if (d.left.e()) return e ? e.key : null; + for (d = d.left; !d.right.e();) d = d.right; + return d.key + } + 0 > c ? d = d.left : 0 < c && (e = d, d = d.right) + } + throw Error("Attempted to find predecessor key for a nonexistent key. What gives?"); + } + h.e = function() { + return this.xa.e() + }; + h.count = function() { + return this.xa.count() + }; + h.Vc = function() { + return this.xa.Vc() + }; + h.jc = function() { + return this.xa.jc() + }; + h.ka = function(a) { + return this.xa.ka(a) + }; + h.ac = function(a) { + return new Hc(this.xa, null, this.Pa, !1, a) + }; + h.bc = function(a, b) { + return new Hc(this.xa, a, this.Pa, !1, b) + }; + h.dc = function(a, b) { + return new Hc(this.xa, a, this.Pa, !0, b) + }; + h.xf = function(a) { + return new Hc(this.xa, null, this.Pa, !0, a) + }; + + function Hc(a, b, c, d, e) { + this.Xd = e || null; + this.Je = d; + this.Ta = []; + for (e = 1; !a.e();) + if (e = b ? c(a.key, b) : 1, d && (e *= -1), 0 > e) a = this.Je ? a.left : a.right; + else if (0 === e) { + this.Ta.push(a); + break + } else this.Ta.push(a), a = this.Je ? a.right : a.left + } + + function Ic(a) { + if (0 === a.Ta.length) return null; + var b = a.Ta.pop(), + c; + c = a.Xd ? a.Xd(b.key, b.value) : { + key: b.key, + value: b.value + }; + if (a.Je) + for (b = b.left; !b.e();) a.Ta.push(b), b = b.right; + else + for (b = b.right; !b.e();) a.Ta.push(b), b = b.left; + return c + } + + function Jc(a) { + if (0 === a.Ta.length) return null; + var b; + b = a.Ta; + b = b[b.length - 1]; + return a.Xd ? a.Xd(b.key, b.value) : { + key: b.key, + value: b.value + } + } + + function Kc(a, b, c, d, e) { + this.key = a; + this.value = b; + this.color = null != c ? c : !0; + this.left = null != d ? d : Fc; + this.right = null != e ? e : Fc + } + h = Kc.prototype; + h.$ = function(a, b, c, d, e) { + return new Kc(null != a ? a : this.key, null != b ? b : this.value, null != c ? c : this.color, null != d ? d : this.left, null != e ? e : this.right) + }; + h.count = function() { + return this.left.count() + 1 + this.right.count() + }; + h.e = function() { + return !1 + }; + h.ka = function(a) { + return this.left.ka(a) || a(this.key, this.value) || this.right.ka(a) + }; + + function Lc(a) { + return a.left.e() ? a : Lc(a.left) + } + h.Vc = function() { + return Lc(this).key + }; + h.jc = function() { + return this.right.e() ? this.key : this.right.jc() + }; + h.Sa = function(a, b, c) { + var d, e; + e = this; + d = c(a, e.key); + e = 0 > d ? e.$(null, null, null, e.left.Sa(a, b, c), null) : 0 === d ? e.$(null, b, null, null, null) : e.$(null, null, null, null, e.right.Sa(a, b, c)); + return Mc(e) + }; + + function Nc(a) { + if (a.left.e()) return Fc; + a.left.ha() || a.left.left.ha() || (a = Oc(a)); + a = a.$(null, null, null, Nc(a.left), null); + return Mc(a) + } + h.remove = function(a, b) { + var c, d; + c = this; + if (0 > b(a, c.key)) c.left.e() || c.left.ha() || c.left.left.ha() || (c = Oc(c)), c = c.$(null, null, null, c.left.remove(a, b), null); + else { + c.left.ha() && (c = Pc(c)); + c.right.e() || c.right.ha() || c.right.left.ha() || (c = Qc(c), c.left.left.ha() && (c = Pc(c), c = Qc(c))); + if (0 === b(a, c.key)) { + if (c.right.e()) return Fc; + d = Lc(c.right); + c = c.$(d.key, d.value, null, null, Nc(c.right)) + } + c = c.$(null, null, null, null, c.right.remove(a, b)) + } + return Mc(c) + }; + h.ha = function() { + return this.color + }; + + function Mc(a) { + a.right.ha() && !a.left.ha() && (a = Rc(a)); + a.left.ha() && a.left.left.ha() && (a = Pc(a)); + a.left.ha() && a.right.ha() && (a = Qc(a)); + return a + } + + function Oc(a) { + a = Qc(a); + a.right.left.ha() && (a = a.$(null, null, null, null, Pc(a.right)), a = Rc(a), a = Qc(a)); + return a + } + + function Rc(a) { + return a.right.$(null, null, a.color, a.$(null, null, !0, null, a.right.left), null) + } + + function Pc(a) { + return a.left.$(null, null, a.color, null, a.$(null, null, !0, a.left.right, null)) + } + + function Qc(a) { + return a.$(null, null, !a.color, a.left.$(null, null, !a.left.color, null, null), a.right.$(null, null, !a.right.color, null, null)) + } + + function Sc() {} + h = Sc.prototype; + h.$ = function() { + return this + }; + h.Sa = function(a, b) { + return new Kc(a, b, null) + }; + h.remove = function() { + return this + }; + h.count = function() { + return 0 + }; + h.e = function() { + return !0 + }; + h.ka = function() { + return !1 + }; + h.Vc = function() { + return null + }; + h.jc = function() { + return null + }; + h.ha = function() { + return !1 + }; + var Fc = new Sc; + + function Tc(a, b) { + return a && "object" === typeof a ? (O(".sv" in a, "Unexpected leaf node or priority contents"), b[a[".sv"]]) : a + } + + function Uc(a, b) { + var c = new Vc; + Wc(a, new P(""), function(a, e) { + c.rc(a, Xc(e, b)) + }); + return c + } + + function Xc(a, b) { + var c = a.C().J(), + c = Tc(c, b), + d; + if (a.L()) { + var e = Tc(a.Ea(), b); + return e !== a.Ea() || c !== a.C().J() ? new Yc(e, Q(c)) : a + } + d = a; + c !== a.C().J() && (d = d.ia(new Yc(c))); + a.R(R, function(a, c) { + var e = Xc(c, b); + e !== c && (d = d.W(a, e)) + }); + return d + }; + + function Zc() { + this.Ac = {} + } + Zc.prototype.set = function(a, b) { + null == b ? delete this.Ac[a] : this.Ac[a] = b + }; + Zc.prototype.get = function(a) { + return y(this.Ac, a) ? this.Ac[a] : null + }; + Zc.prototype.remove = function(a) { + delete this.Ac[a] + }; + Zc.prototype.Af = !0; + + function $c(a) { + this.Ic = a; + this.Sd = "firebase:" + } + h = $c.prototype; + h.set = function(a, b) { + null == b ? this.Ic.removeItem(this.Sd + a) : this.Ic.setItem(this.Sd + a, G(b)) + }; + h.get = function(a) { + a = this.Ic.getItem(this.Sd + a); + return null == a ? null : Rb(a) + }; + h.remove = function(a) { + this.Ic.removeItem(this.Sd + a) + }; + h.Af = !1; + h.toString = function() { + return this.Ic.toString() + }; + + function ad(a) { + try { + if ("undefined" !== typeof window && "undefined" !== typeof window[a]) { + var b = window[a]; + b.setItem("firebase:sentinel", "cache"); + b.removeItem("firebase:sentinel"); + return new $c(b) + } + } catch (c) {} + return new Zc + } + var bd = ad("localStorage"), + cd = ad("sessionStorage"); + + function dd(a, b, c, d, e) { + this.host = a.toLowerCase(); + this.domain = this.host.substr(this.host.indexOf(".") + 1); + this.ob = b; + this.lc = c; + this.hh = d; + this.Rd = e || ""; + this.ab = bd.get("host:" + a) || this.host + } + + function ed(a, b) { + b !== a.ab && (a.ab = b, "s-" === a.ab.substr(0, 2) && bd.set("host:" + a.host, a.ab)) + } + + function fd(a, b, c) { + O("string" === typeof b, "typeof type must == string"); + O("object" === typeof c, "typeof params must == object"); + if (b === gd) b = (a.ob ? "wss://" : "ws://") + a.ab + "/.ws?"; + else if (b === hd) b = (a.ob ? "https://" : "http://") + a.ab + "/.lp?"; + else throw Error("Unknown connection type: " + b); + a.host !== a.ab && (c.ns = a.lc); + var d = []; + v(c, function(a, b) { + d.push(b + "=" + a) + }); + return b + d.join("&") + } + dd.prototype.toString = function() { + var a = (this.ob ? "https://" : "http://") + this.host; + this.Rd && (a += "<" + this.Rd + ">"); + return a + }; + var id = function() { + var a = 1; + return function() { + return a++ + } + }(), + O = Kb, + jd = Lb; + + function kd(a) { + try { + var b; + if ("undefined" !== typeof atob) b = atob(a); + else { + ob(); + for (var c = mb, d = [], e = 0; e < a.length;) { + var f = c[a.charAt(e++)], + g = e < a.length ? c[a.charAt(e)] : 0; + ++e; + var k = e < a.length ? c[a.charAt(e)] : 64; + ++e; + var m = e < a.length ? c[a.charAt(e)] : 64; + ++e; + if (null == f || null == g || null == k || null == m) throw Error(); + d.push(f << 2 | g >> 4); + 64 != k && (d.push(g << 4 & 240 | k >> 2), 64 != m && d.push(k << 6 & 192 | m)) + } + if (8192 > d.length) b = String.fromCharCode.apply(null, d); + else { + a = ""; + for (c = 0; c < d.length; c += 8192) a += String.fromCharCode.apply(null, Ua(d, c, + c + 8192)); + b = a + } + } + return b + } catch (l) { + fc("base64Decode failed: ", l) + } + return null + } + + function ld(a) { + var b = Ob(a); + a = new Ja; + a.update(b); + var b = [], + c = 8 * a.ge; + 56 > a.ec ? a.update(a.Od, 56 - a.ec) : a.update(a.Od, a.Ya - (a.ec - 56)); + for (var d = a.Ya - 1; 56 <= d; d--) a.pe[d] = c & 255, c /= 256; + Ka(a, a.pe); + for (d = c = 0; 5 > d; d++) + for (var e = 24; 0 <= e; e -= 8) b[c] = a.P[d] >> e & 255, ++c; + return nb(b) + } + + function md(a) { + for (var b = "", c = 0; c < arguments.length; c++) b = ea(arguments[c]) ? b + md.apply(null, arguments[c]) : "object" === typeof arguments[c] ? b + G(arguments[c]) : b + arguments[c], b += " "; + return b + } + var ec = null, + nd = !0; + + function od(a, b) { + Kb(!b || !0 === a || !1 === a, "Can't turn on custom loggers persistently."); + !0 === a ? ("undefined" !== typeof console && ("function" === typeof console.log ? ec = u(console.log, console) : "object" === typeof console.log && (ec = function(a) { + console.log(a) + })), b && cd.set("logging_enabled", !0)) : r(a) ? ec = a : (ec = null, cd.remove("logging_enabled")) + } + + function fc(a) { + !0 === nd && (nd = !1, null === ec && !0 === cd.get("logging_enabled") && od(!0)); + if (ec) { + var b = md.apply(null, arguments); + ec(b) + } + } + + function pd(a) { + return function() { + fc(a, arguments) + } + } + + function qd(a) { + if ("undefined" !== typeof console) { + var b = "FIREBASE INTERNAL ERROR: " + md.apply(null, arguments); + "undefined" !== typeof console.error ? console.error(b) : console.log(b) + } + } + + function rd(a) { + var b = md.apply(null, arguments); + throw Error("FIREBASE FATAL ERROR: " + b); + } + + function S(a) { + if ("undefined" !== typeof console) { + var b = "FIREBASE WARNING: " + md.apply(null, arguments); + "undefined" !== typeof console.warn ? console.warn(b) : console.log(b) + } + } + + function sd(a) { + var b = "", + c = "", + d = "", + e = "", + f = !0, + g = "https", + k = 443; + if (q(a)) { + var m = a.indexOf("//"); + 0 <= m && (g = a.substring(0, m - 1), a = a.substring(m + 2)); + m = a.indexOf("/"); - 1 === m && (m = a.length); + b = a.substring(0, m); + e = ""; + a = a.substring(m).split("/"); + for (m = 0; m < a.length; m++) + if (0 < a[m].length) { + var l = a[m]; + try { + l = decodeURIComponent(l.replace(/\+/g, " ")) + } catch (t) {} + e += "/" + l + } + a = b.split("."); + 3 === a.length ? (c = a[1], d = a[0].toLowerCase()) : 2 === a.length && (c = a[0]); + m = b.indexOf(":"); + 0 <= m && (f = "https" === g || "wss" === g, k = b.substring(m + 1), isFinite(k) && + (k = String(k)), k = q(k) ? /^\s*-?0x/i.test(k) ? parseInt(k, 16) : parseInt(k, 10) : NaN) + } + return { + host: b, + port: k, + domain: c, + eh: d, + ob: f, + scheme: g, + bd: e + } + } + + function td(a) { + return fa(a) && (a != a || a == Number.POSITIVE_INFINITY || a == Number.NEGATIVE_INFINITY) + } + + function ud(a) { + if ("complete" === document.readyState) a(); + else { + var b = !1, + c = function() { + document.body ? b || (b = !0, a()) : setTimeout(c, Math.floor(10)) + }; + document.addEventListener ? (document.addEventListener("DOMContentLoaded", c, !1), window.addEventListener("load", c, !1)) : document.attachEvent && (document.attachEvent("onreadystatechange", function() { + "complete" === document.readyState && c() + }), window.attachEvent("onload", c)) + } + } + + function yc(a, b) { + if (a === b) return 0; + if ("[MIN_NAME]" === a || "[MAX_NAME]" === b) return -1; + if ("[MIN_NAME]" === b || "[MAX_NAME]" === a) return 1; + var c = vd(a), + d = vd(b); + return null !== c ? null !== d ? 0 == c - d ? a.length - b.length : c - d : -1 : null !== d ? 1 : a < b ? -1 : 1 + } + + function wd(a, b) { + if (b && a in b) return b[a]; + throw Error("Missing required key (" + a + ") in object: " + G(b)); + } + + function xd(a) { + if ("object" !== typeof a || null === a) return G(a); + var b = [], + c; + for (c in a) b.push(c); + b.sort(); + c = "{"; + for (var d = 0; d < b.length; d++) 0 !== d && (c += ","), c += G(b[d]), c += ":", c += xd(a[b[d]]); + return c + "}" + } + + function yd(a, b) { + if (a.length <= b) return [a]; + for (var c = [], d = 0; d < a.length; d += b) d + b > a ? c.push(a.substring(d, a.length)) : c.push(a.substring(d, d + b)); + return c + } + + function zd(a, b) { + if (da(a)) + for (var c = 0; c < a.length; ++c) b(c, a[c]); + else v(a, b) + } + + function Ad(a) { + O(!td(a), "Invalid JSON number"); + var b, c, d, e; + 0 === a ? (d = c = 0, b = -Infinity === 1 / a ? 1 : 0) : (b = 0 > a, a = Math.abs(a), a >= Math.pow(2, -1022) ? (d = Math.min(Math.floor(Math.log(a) / Math.LN2), 1023), c = d + 1023, d = Math.round(a * Math.pow(2, 52 - d) - Math.pow(2, 52))) : (c = 0, d = Math.round(a / Math.pow(2, -1074)))); + e = []; + for (a = 52; a; --a) e.push(d % 2 ? 1 : 0), d = Math.floor(d / 2); + for (a = 11; a; --a) e.push(c % 2 ? 1 : 0), c = Math.floor(c / 2); + e.push(b ? 1 : 0); + e.reverse(); + b = e.join(""); + c = ""; + for (a = 0; 64 > a; a += 8) d = parseInt(b.substr(a, 8), 2).toString(16), 1 === d.length && + (d = "0" + d), c += d; + return c.toLowerCase() + } + var Bd = /^-?\d{1,10}$/; + + function vd(a) { + return Bd.test(a) && (a = Number(a), -2147483648 <= a && 2147483647 >= a) ? a : null + } + + function gc(a) { + try { + a() + } catch (b) { + setTimeout(function() { + S("Exception was thrown by user callback.", b.stack || ""); + throw b; + }, Math.floor(0)) + } + } + + function T(a, b) { + if (r(a)) { + var c = Array.prototype.slice.call(arguments, 1).slice(); + gc(function() { + a.apply(null, c) + }) + } + }; + + function Cd(a) { + var b = {}, + c = {}, + d = {}, + e = ""; + try { + var f = a.split("."), + b = Rb(kd(f[0]) || ""), + c = Rb(kd(f[1]) || ""), + e = f[2], + d = c.d || {}; + delete c.d + } catch (g) {} + return { + kh: b, + Ec: c, + data: d, + ah: e + } + } + + function Dd(a) { + a = Cd(a).Ec; + return "object" === typeof a && a.hasOwnProperty("iat") ? z(a, "iat") : null + } + + function Ed(a) { + a = Cd(a); + var b = a.Ec; + return !!a.ah && !!b && "object" === typeof b && b.hasOwnProperty("iat") + }; + + function Fd(a) { + this.Y = a; + this.g = a.n.g + } + + function Gd(a, b, c, d) { + var e = [], + f = []; + Ma(b, function(b) { + "child_changed" === b.type && a.g.Dd(b.Oe, b.Na) && f.push(new J("child_moved", b.Na, b.Za)) + }); + Hd(a, e, "child_removed", b, d, c); + Hd(a, e, "child_added", b, d, c); + Hd(a, e, "child_moved", f, d, c); + Hd(a, e, "child_changed", b, d, c); + Hd(a, e, ic, b, d, c); + return e + } + + function Hd(a, b, c, d, e, f) { + d = Na(d, function(a) { + return a.type === c + }); + Va(d, u(a.qg, a)); + Ma(d, function(c) { + var d = Id(a, c, f); + Ma(e, function(e) { + e.Qf(c.type) && b.push(e.createEvent(d, a.Y)) + }) + }) + } + + function Id(a, b, c) { + "value" !== b.type && "child_removed" !== b.type && (b.Td = c.wf(b.Za, b.Na, a.g)); + return b + } + Fd.prototype.qg = function(a, b) { + if (null == a.Za || null == b.Za) throw jd("Should only compare child_ events."); + return this.g.compare(new L(a.Za, a.Na), new L(b.Za, b.Na)) + }; + + function Jd() { + this.ib = {} + } + + function Kd(a, b) { + var c = b.type, + d = b.Za; + O("child_added" == c || "child_changed" == c || "child_removed" == c, "Only child changes supported for tracking"); + O(".priority" !== d, "Only non-priority child changes can be tracked."); + var e = z(a.ib, d); + if (e) { + var f = e.type; + if ("child_added" == c && "child_removed" == f) a.ib[d] = new J("child_changed", b.Na, d, e.Na); + else if ("child_removed" == c && "child_added" == f) delete a.ib[d]; + else if ("child_removed" == c && "child_changed" == f) a.ib[d] = new J("child_removed", e.Oe, d); + else if ("child_changed" == c && + "child_added" == f) a.ib[d] = new J("child_added", b.Na, d); + else if ("child_changed" == c && "child_changed" == f) a.ib[d] = new J("child_changed", b.Na, d, e.Oe); + else throw jd("Illegal combination of changes: " + b + " occurred after " + e); + } else a.ib[d] = b + }; + + function Ld(a) { + this.g = a + } + h = Ld.prototype; + h.H = function(a, b, c, d, e, f) { + O(a.Mc(this.g), "A node must be indexed if only a child is updated"); + e = a.T(b); + if (e.S(d).ea(c.S(d)) && e.e() == c.e()) return a; + null != f && (c.e() ? a.Fa(b) ? Kd(f, new J("child_removed", e, b)) : O(a.L(), "A child remove without an old child only makes sense on a leaf node") : e.e() ? Kd(f, new J("child_added", c, b)) : Kd(f, new J("child_changed", c, b, e))); + return a.L() && c.e() ? a : a.W(b, c).pb(this.g) + }; + h.ya = function(a, b, c) { + null != c && (a.L() || a.R(R, function(a, e) { + b.Fa(a) || Kd(c, new J("child_removed", e, a)) + }), b.L() || b.R(R, function(b, e) { + if (a.Fa(b)) { + var f = a.T(b); + f.ea(e) || Kd(c, new J("child_changed", e, b, f)) + } else Kd(c, new J("child_added", e, b)) + })); + return b.pb(this.g) + }; + h.ia = function(a, b) { + return a.e() ? H : a.ia(b) + }; + h.Ra = function() { + return !1 + }; + h.$b = function() { + return this + }; + + function Md(a) { + this.Fe = new Ld(a.g); + this.g = a.g; + var b; + a.oa ? (b = Nd(a), b = a.g.Sc(Od(a), b)) : b = a.g.Wc(); + this.gd = b; + a.ra ? (b = Pd(a), a = a.g.Sc(Rd(a), b)) : a = a.g.Tc(); + this.Jc = a + } + h = Md.prototype; + h.matches = function(a) { + return 0 >= this.g.compare(this.gd, a) && 0 >= this.g.compare(a, this.Jc) + }; + h.H = function(a, b, c, d, e, f) { + this.matches(new L(b, c)) || (c = H); + return this.Fe.H(a, b, c, d, e, f) + }; + h.ya = function(a, b, c) { + b.L() && (b = H); + var d = b.pb(this.g), + d = d.ia(H), + e = this; + b.R(R, function(a, b) { + e.matches(new L(a, b)) || (d = d.W(a, H)) + }); + return this.Fe.ya(a, d, c) + }; + h.ia = function(a) { + return a + }; + h.Ra = function() { + return !0 + }; + h.$b = function() { + return this.Fe + }; + + function Sd(a) { + this.ua = new Md(a); + this.g = a.g; + O(a.la, "Only valid if limit has been set"); + this.ma = a.ma; + this.Nb = !Td(a) + } + h = Sd.prototype; + h.H = function(a, b, c, d, e, f) { + this.ua.matches(new L(b, c)) || (c = H); + return a.T(b).ea(c) ? a : a.Hb() < this.ma ? this.ua.$b().H(a, b, c, d, e, f) : Ud(this, a, b, c, e, f) + }; + h.ya = function(a, b, c) { + var d; + if (b.L() || b.e()) d = H.pb(this.g); + else if (2 * this.ma < b.Hb() && b.Mc(this.g)) { + d = H.pb(this.g); + b = this.Nb ? b.dc(this.ua.Jc, this.g) : b.bc(this.ua.gd, this.g); + for (var e = 0; 0 < b.Ta.length && e < this.ma;) { + var f = Ic(b), + g; + if (g = this.Nb ? 0 >= this.g.compare(this.ua.gd, f) : 0 >= this.g.compare(f, this.ua.Jc)) d = d.W(f.name, f.U), e++; + else break + } + } else { + d = b.pb(this.g); + d = d.ia(H); + var k, m, l; + if (this.Nb) { + b = d.xf(this.g); + k = this.ua.Jc; + m = this.ua.gd; + var t = Vd(this.g); + l = function(a, b) { + return t(b, a) + } + } else b = d.ac(this.g), k = this.ua.gd, + m = this.ua.Jc, l = Vd(this.g); + for (var e = 0, A = !1; 0 < b.Ta.length;) f = Ic(b), !A && 0 >= l(k, f) && (A = !0), (g = A && e < this.ma && 0 >= l(f, m)) ? e++ : d = d.W(f.name, H) + } + return this.ua.$b().ya(a, d, c) + }; + h.ia = function(a) { + return a + }; + h.Ra = function() { + return !0 + }; + h.$b = function() { + return this.ua.$b() + }; + + function Ud(a, b, c, d, e, f) { + var g; + if (a.Nb) { + var k = Vd(a.g); + g = function(a, b) { + return k(b, a) + } + } else g = Vd(a.g); + O(b.Hb() == a.ma, ""); + var m = new L(c, d), + l = a.Nb ? Wd(b, a.g) : Xd(b, a.g), + t = a.ua.matches(m); + if (b.Fa(c)) { + for (var A = b.T(c), l = e.Ce(a.g, l, a.Nb); null != l && (l.name == c || b.Fa(l.name));) l = e.Ce(a.g, l, a.Nb); + e = null == l ? 1 : g(l, m); + if (t && !d.e() && 0 <= e) return null != f && Kd(f, new J("child_changed", d, c, A)), b.W(c, d); + null != f && Kd(f, new J("child_removed", A, c)); + b = b.W(c, H); + return null != l && a.ua.matches(l) ? (null != f && Kd(f, new J("child_added", + l.U, l.name)), b.W(l.name, l.U)) : b + } + return d.e() ? b : t && 0 <= g(l, m) ? (null != f && (Kd(f, new J("child_removed", l.U, l.name)), Kd(f, new J("child_added", d, c))), b.W(c, d).W(l.name, H)) : b + }; + + function Yd(a, b) { + this.me = a; + this.og = b + } + + function Zd(a) { + this.X = a + } + Zd.prototype.gb = function(a, b, c, d) { + var e = new Jd, + f; + if (b.type === Bc) b.source.Ae ? c = $d(this, a, b.path, b.Ja, c, d, e) : (O(b.source.tf, "Unknown source."), f = b.source.ef || mc(a.w()) && !b.path.e(), c = ae(this, a, b.path, b.Ja, c, d, f, e)); + else if (b.type === be) b.source.Ae ? c = ce(this, a, b.path, b.children, c, d, e) : (O(b.source.tf, "Unknown source."), f = b.source.ef || mc(a.w()), c = de(this, a, b.path, b.children, c, d, f, e)); + else if (b.type === ee) + if (b.Yd) + if (b = b.path, null != c.xc(b)) c = a; + else { + f = new Vb(c, a, d); + d = a.Q.j(); + if (b.e() || ".priority" === K(b)) lc(a.w()) ? + b = c.Aa(Yb(a)) : (b = a.w().j(), O(b instanceof fe, "serverChildren would be complete if leaf node"), b = c.Cc(b)), b = this.X.ya(d, b, e); + else { + var g = K(b), + k = c.Bc(g, a.w()); + null == k && Wb(a.w(), g) && (k = d.T(g)); + b = null != k ? this.X.H(d, g, k, N(b), f, e) : a.Q.j().Fa(g) ? this.X.H(d, g, H, N(b), f, e) : d; + b.e() && lc(a.w()) && (d = c.Aa(Yb(a)), d.L() && (b = this.X.ya(b, d, e))) + } + d = lc(a.w()) || null != c.xc(M); + c = ge(a, b, d, this.X.Ra()) + } else c = he(this, a, b.path, b.Ub, c, d, e); + else if (b.type === Dc) d = b.path, b = a.w(), f = b.j(), g = b.ga || d.e(), c = ie(this, new je(a.Q, new Xb(f, + g, b.Yb)), d, c, Ub, e); + else throw jd("Unknown operation type: " + b.type); + e = qa(e.ib); + d = c; + b = d.Q; + b.ga && (f = b.j().L() || b.j().e(), g = ke(a), (0 < e.length || !a.Q.ga || f && !b.j().ea(g) || !b.j().C().ea(g.C())) && e.push(hc(ke(d)))); + return new Yd(c, e) + }; + + function ie(a, b, c, d, e, f) { + var g = b.Q; + if (null != d.xc(c)) return b; + var k; + if (c.e()) O(lc(b.w()), "If change path is empty, we must have complete server data"), mc(b.w()) ? (e = Yb(b), d = d.Cc(e instanceof fe ? e : H)) : d = d.Aa(Yb(b)), f = a.X.ya(b.Q.j(), d, f); + else { + var m = K(c); + if (".priority" == m) O(1 == le(c), "Can't have a priority with additional path components"), f = g.j(), k = b.w().j(), d = d.nd(c, f, k), f = null != d ? a.X.ia(f, d) : g.j(); + else { + var l = N(c); + Wb(g, m) ? (k = b.w().j(), d = d.nd(c, g.j(), k), d = null != d ? g.j().T(m).H(l, d) : g.j().T(m)) : d = d.Bc(m, + b.w()); + f = null != d ? a.X.H(g.j(), m, d, l, e, f) : g.j() + } + } + return ge(b, f, g.ga || c.e(), a.X.Ra()) + } + + function ae(a, b, c, d, e, f, g, k) { + var m = b.w(); + g = g ? a.X : a.X.$b(); + if (c.e()) d = g.ya(m.j(), d, null); + else if (g.Ra() && !m.Yb) d = m.j().H(c, d), d = g.ya(m.j(), d, null); + else { + var l = K(c); + if (!nc(m, c) && 1 < le(c)) return b; + var t = N(c); + d = m.j().T(l).H(t, d); + d = ".priority" == l ? g.ia(m.j(), d) : g.H(m.j(), l, d, t, Ub, null) + } + m = m.ga || c.e(); + b = new je(b.Q, new Xb(d, m, g.Ra())); + return ie(a, b, c, e, new Vb(e, b, f), k) + } + + function $d(a, b, c, d, e, f, g) { + var k = b.Q; + e = new Vb(e, b, f); + if (c.e()) g = a.X.ya(b.Q.j(), d, g), a = ge(b, g, !0, a.X.Ra()); + else if (f = K(c), ".priority" === f) g = a.X.ia(b.Q.j(), d), a = ge(b, g, k.ga, k.Yb); + else { + c = N(c); + var m = k.j().T(f); + if (!c.e()) { + var l = e.uf(f); + d = null != l ? ".priority" === me(c) && l.S(c.parent()).e() ? l : l.H(c, d) : H + } + m.ea(d) ? a = b : (g = a.X.H(k.j(), f, d, c, e, g), a = ge(b, g, k.ga, a.X.Ra())) + } + return a + } + + function ce(a, b, c, d, e, f, g) { + var k = b; + ne(d, function(d, l) { + var t = c.o(d); + Wb(b.Q, K(t)) && (k = $d(a, k, t, l, e, f, g)) + }); + ne(d, function(d, l) { + var t = c.o(d); + Wb(b.Q, K(t)) || (k = $d(a, k, t, l, e, f, g)) + }); + return k + } + + function oe(a, b) { + ne(b, function(b, d) { + a = a.H(b, d) + }); + return a + } + + function de(a, b, c, d, e, f, g, k) { + if (b.w().j().e() && !lc(b.w())) return b; + var m = b; + c = c.e() ? d : pe(qe, c, d); + var l = b.w().j(); + c.children.ka(function(c, d) { + if (l.Fa(c)) { + var I = b.w().j().T(c), + I = oe(I, d); + m = ae(a, m, new P(c), I, e, f, g, k) + } + }); + c.children.ka(function(c, d) { + var I = !Wb(b.w(), c) && null == d.value; + l.Fa(c) || I || (I = b.w().j().T(c), I = oe(I, d), m = ae(a, m, new P(c), I, e, f, g, k)) + }); + return m + } + + function he(a, b, c, d, e, f, g) { + if (null != e.xc(c)) return b; + var k = mc(b.w()), + m = b.w(); + if (null != d.value) { + if (c.e() && m.ga || nc(m, c)) return ae(a, b, c, m.j().S(c), e, f, k, g); + if (c.e()) { + var l = qe; + m.j().R(re, function(a, b) { + l = l.set(new P(a), b) + }); + return de(a, b, c, l, e, f, k, g) + } + return b + } + l = qe; + ne(d, function(a) { + var b = c.o(a); + nc(m, b) && (l = l.set(a, m.j().S(b))) + }); + return de(a, b, c, l, e, f, k, g) + }; + + function se() {} + var te = {}; + + function Vd(a) { + return u(a.compare, a) + } + se.prototype.Dd = function(a, b) { + return 0 !== this.compare(new L("[MIN_NAME]", a), new L("[MIN_NAME]", b)) + }; + se.prototype.Wc = function() { + return ue + }; + + function ve(a) { + O(!a.e() && ".priority" !== K(a), "Can't create PathIndex with empty path or .priority key"); + this.gc = a + } + ka(ve, se); + h = ve.prototype; + h.Lc = function(a) { + return !a.S(this.gc).e() + }; + h.compare = function(a, b) { + var c = a.U.S(this.gc), + d = b.U.S(this.gc), + c = c.Gc(d); + return 0 === c ? yc(a.name, b.name) : c + }; + h.Sc = function(a, b) { + var c = Q(a), + c = H.H(this.gc, c); + return new L(b, c) + }; + h.Tc = function() { + var a = H.H(this.gc, we); + return new L("[MAX_NAME]", a) + }; + h.toString = function() { + return this.gc.slice().join("/") + }; + + function xe() {} + ka(xe, se); + h = xe.prototype; + h.compare = function(a, b) { + var c = a.U.C(), + d = b.U.C(), + c = c.Gc(d); + return 0 === c ? yc(a.name, b.name) : c + }; + h.Lc = function(a) { + return !a.C().e() + }; + h.Dd = function(a, b) { + return !a.C().ea(b.C()) + }; + h.Wc = function() { + return ue + }; + h.Tc = function() { + return new L("[MAX_NAME]", new Yc("[PRIORITY-POST]", we)) + }; + h.Sc = function(a, b) { + var c = Q(a); + return new L(b, new Yc("[PRIORITY-POST]", c)) + }; + h.toString = function() { + return ".priority" + }; + var R = new xe; + + function ye() {} + ka(ye, se); + h = ye.prototype; + h.compare = function(a, b) { + return yc(a.name, b.name) + }; + h.Lc = function() { + throw jd("KeyIndex.isDefinedOn not expected to be called."); + }; + h.Dd = function() { + return !1 + }; + h.Wc = function() { + return ue + }; + h.Tc = function() { + return new L("[MAX_NAME]", H) + }; + h.Sc = function(a) { + O(q(a), "KeyIndex indexValue must always be a string."); + return new L(a, H) + }; + h.toString = function() { + return ".key" + }; + var re = new ye; + + function ze() {} + ka(ze, se); + h = ze.prototype; + h.compare = function(a, b) { + var c = a.U.Gc(b.U); + return 0 === c ? yc(a.name, b.name) : c + }; + h.Lc = function() { + return !0 + }; + h.Dd = function(a, b) { + return !a.ea(b) + }; + h.Wc = function() { + return ue + }; + h.Tc = function() { + return Ae + }; + h.Sc = function(a, b) { + var c = Q(a); + return new L(b, c) + }; + h.toString = function() { + return ".value" + }; + var Be = new ze; + + function Ce() { + this.Xb = this.ra = this.Pb = this.oa = this.la = !1; + this.ma = 0; + this.Rb = ""; + this.ic = null; + this.Bb = ""; + this.fc = null; + this.zb = ""; + this.g = R + } + var De = new Ce; + + function Td(a) { + return "" === a.Rb ? a.oa : "l" === a.Rb + } + + function Od(a) { + O(a.oa, "Only valid if start has been set"); + return a.ic + } + + function Nd(a) { + O(a.oa, "Only valid if start has been set"); + return a.Pb ? a.Bb : "[MIN_NAME]" + } + + function Rd(a) { + O(a.ra, "Only valid if end has been set"); + return a.fc + } + + function Pd(a) { + O(a.ra, "Only valid if end has been set"); + return a.Xb ? a.zb : "[MAX_NAME]" + } + + function Ee(a) { + var b = new Ce; + b.la = a.la; + b.ma = a.ma; + b.oa = a.oa; + b.ic = a.ic; + b.Pb = a.Pb; + b.Bb = a.Bb; + b.ra = a.ra; + b.fc = a.fc; + b.Xb = a.Xb; + b.zb = a.zb; + b.g = a.g; + return b + } + h = Ce.prototype; + h.Le = function(a) { + var b = Ee(this); + b.la = !0; + b.ma = a; + b.Rb = ""; + return b + }; + h.Me = function(a) { + var b = Ee(this); + b.la = !0; + b.ma = a; + b.Rb = "l"; + return b + }; + h.Ne = function(a) { + var b = Ee(this); + b.la = !0; + b.ma = a; + b.Rb = "r"; + return b + }; + h.ce = function(a, b) { + var c = Ee(this); + c.oa = !0; + p(a) || (a = null); + c.ic = a; + null != b ? (c.Pb = !0, c.Bb = b) : (c.Pb = !1, c.Bb = ""); + return c + }; + h.vd = function(a, b) { + var c = Ee(this); + c.ra = !0; + p(a) || (a = null); + c.fc = a; + p(b) ? (c.Xb = !0, c.zb = b) : (c.mh = !1, c.zb = ""); + return c + }; + + function Fe(a, b) { + var c = Ee(a); + c.g = b; + return c + } + + function Ge(a) { + var b = {}; + a.oa && (b.sp = a.ic, a.Pb && (b.sn = a.Bb)); + a.ra && (b.ep = a.fc, a.Xb && (b.en = a.zb)); + if (a.la) { + b.l = a.ma; + var c = a.Rb; + "" === c && (c = Td(a) ? "l" : "r"); + b.vf = c + } + a.g !== R && (b.i = a.g.toString()); + return b + } + + function He(a) { + return !(a.oa || a.ra || a.la) + } + + function Ie(a) { + return He(a) && a.g == R + } + + function Je(a) { + var b = {}; + if (Ie(a)) return b; + var c; + a.g === R ? c = "$priority" : a.g === Be ? c = "$value" : a.g === re ? c = "$key" : (O(a.g instanceof ve, "Unrecognized index type!"), c = a.g.toString()); + b.orderBy = G(c); + a.oa && (b.startAt = G(a.ic), a.Pb && (b.startAt += "," + G(a.Bb))); + a.ra && (b.endAt = G(a.fc), a.Xb && (b.endAt += "," + G(a.zb))); + a.la && (Td(a) ? b.limitToFirst = a.ma : b.limitToLast = a.ma); + return b + } + h.toString = function() { + return G(Ge(this)) + }; + + function Ke(a, b) { + this.Ed = a; + this.hc = b + } + Ke.prototype.get = function(a) { + var b = z(this.Ed, a); + if (!b) throw Error("No index defined for " + a); + return b === te ? null : b + }; + + function Le(a, b, c) { + var d = ma(a.Ed, function(d, f) { + var g = z(a.hc, f); + O(g, "Missing index implementation for " + f); + if (d === te) { + if (g.Lc(b.U)) { + for (var k = [], m = c.ac(wc), l = Ic(m); l;) l.name != b.name && k.push(l), l = Ic(m); + k.push(b); + return Me(k, Vd(g)) + } + return te + } + g = c.get(b.name); + k = d; + g && (k = k.remove(new L(b.name, g))); + return k.Sa(b, b.U) + }); + return new Ke(d, a.hc) + } + + function Ne(a, b, c) { + var d = ma(a.Ed, function(a) { + if (a === te) return a; + var d = c.get(b.name); + return d ? a.remove(new L(b.name, d)) : a + }); + return new Ke(d, a.hc) + } + var Oe = new Ke({ + ".priority": te + }, { + ".priority": R + }); + + function Yc(a, b) { + this.B = a; + O(p(this.B) && null !== this.B, "LeafNode shouldn't be created with null/undefined value."); + this.ca = b || H; + Pe(this.ca); + this.Gb = null + } + var Qe = ["object", "boolean", "number", "string"]; + h = Yc.prototype; + h.L = function() { + return !0 + }; + h.C = function() { + return this.ca + }; + h.ia = function(a) { + return new Yc(this.B, a) + }; + h.T = function(a) { + return ".priority" === a ? this.ca : H + }; + h.S = function(a) { + return a.e() ? this : ".priority" === K(a) ? this.ca : H + }; + h.Fa = function() { + return !1 + }; + h.wf = function() { + return null + }; + h.W = function(a, b) { + return ".priority" === a ? this.ia(b) : b.e() && ".priority" !== a ? this : H.W(a, b).ia(this.ca) + }; + h.H = function(a, b) { + var c = K(a); + if (null === c) return b; + if (b.e() && ".priority" !== c) return this; + O(".priority" !== c || 1 === le(a), ".priority must be the last token in a path"); + return this.W(c, H.H(N(a), b)) + }; + h.e = function() { + return !1 + }; + h.Hb = function() { + return 0 + }; + h.R = function() { + return !1 + }; + h.J = function(a) { + return a && !this.C().e() ? { + ".value": this.Ea(), + ".priority": this.C().J() + } : this.Ea() + }; + h.hash = function() { + if (null === this.Gb) { + var a = ""; + this.ca.e() || (a += "priority:" + Re(this.ca.J()) + ":"); + var b = typeof this.B, + a = a + (b + ":"), + a = "number" === b ? a + Ad(this.B) : a + this.B; + this.Gb = ld(a) + } + return this.Gb + }; + h.Ea = function() { + return this.B + }; + h.Gc = function(a) { + if (a === H) return 1; + if (a instanceof fe) return -1; + O(a.L(), "Unknown node type"); + var b = typeof a.B, + c = typeof this.B, + d = La(Qe, b), + e = La(Qe, c); + O(0 <= d, "Unknown leaf type: " + b); + O(0 <= e, "Unknown leaf type: " + c); + return d === e ? "object" === c ? 0 : this.B < a.B ? -1 : this.B === a.B ? 0 : 1 : e - d + }; + h.pb = function() { + return this + }; + h.Mc = function() { + return !0 + }; + h.ea = function(a) { + return a === this ? !0 : a.L() ? this.B === a.B && this.ca.ea(a.ca) : !1 + }; + h.toString = function() { + return G(this.J(!0)) + }; + + function fe(a, b, c) { + this.m = a; + (this.ca = b) && Pe(this.ca); + a.e() && O(!this.ca || this.ca.e(), "An empty node cannot have a priority"); + this.Ab = c; + this.Gb = null + } + h = fe.prototype; + h.L = function() { + return !1 + }; + h.C = function() { + return this.ca || H + }; + h.ia = function(a) { + return this.m.e() ? this : new fe(this.m, a, this.Ab) + }; + h.T = function(a) { + if (".priority" === a) return this.C(); + a = this.m.get(a); + return null === a ? H : a + }; + h.S = function(a) { + var b = K(a); + return null === b ? this : this.T(b).S(N(a)) + }; + h.Fa = function(a) { + return null !== this.m.get(a) + }; + h.W = function(a, b) { + O(b, "We should always be passing snapshot nodes"); + if (".priority" === a) return this.ia(b); + var c = new L(a, b), + d, e; + b.e() ? (d = this.m.remove(a), c = Ne(this.Ab, c, this.m)) : (d = this.m.Sa(a, b), c = Le(this.Ab, c, this.m)); + e = d.e() ? H : this.ca; + return new fe(d, e, c) + }; + h.H = function(a, b) { + var c = K(a); + if (null === c) return b; + O(".priority" !== K(a) || 1 === le(a), ".priority must be the last token in a path"); + var d = this.T(c).H(N(a), b); + return this.W(c, d) + }; + h.e = function() { + return this.m.e() + }; + h.Hb = function() { + return this.m.count() + }; + var Se = /^(0|[1-9]\d*)$/; + h = fe.prototype; + h.J = function(a) { + if (this.e()) return null; + var b = {}, + c = 0, + d = 0, + e = !0; + this.R(R, function(f, g) { + b[f] = g.J(a); + c++; + e && Se.test(f) ? d = Math.max(d, Number(f)) : e = !1 + }); + if (!a && e && d < 2 * c) { + var f = [], + g; + for (g in b) f[g] = b[g]; + return f + } + a && !this.C().e() && (b[".priority"] = this.C().J()); + return b + }; + h.hash = function() { + if (null === this.Gb) { + var a = ""; + this.C().e() || (a += "priority:" + Re(this.C().J()) + ":"); + this.R(R, function(b, c) { + var d = c.hash(); + "" !== d && (a += ":" + b + ":" + d) + }); + this.Gb = "" === a ? "" : ld(a) + } + return this.Gb + }; + h.wf = function(a, b, c) { + return (c = Te(this, c)) ? (a = Gc(c, new L(a, b))) ? a.name : null : Gc(this.m, a) + }; + + function Wd(a, b) { + var c; + c = (c = Te(a, b)) ? (c = c.Vc()) && c.name : a.m.Vc(); + return c ? new L(c, a.m.get(c)) : null + } + + function Xd(a, b) { + var c; + c = (c = Te(a, b)) ? (c = c.jc()) && c.name : a.m.jc(); + return c ? new L(c, a.m.get(c)) : null + } + h.R = function(a, b) { + var c = Te(this, a); + return c ? c.ka(function(a) { + return b(a.name, a.U) + }) : this.m.ka(b) + }; + h.ac = function(a) { + return this.bc(a.Wc(), a) + }; + h.bc = function(a, b) { + var c = Te(this, b); + if (c) return c.bc(a, function(a) { + return a + }); + for (var c = this.m.bc(a.name, wc), d = Jc(c); null != d && 0 > b.compare(d, a);) Ic(c), d = Jc(c); + return c + }; + h.xf = function(a) { + return this.dc(a.Tc(), a) + }; + h.dc = function(a, b) { + var c = Te(this, b); + if (c) return c.dc(a, function(a) { + return a + }); + for (var c = this.m.dc(a.name, wc), d = Jc(c); null != d && 0 < b.compare(d, a);) Ic(c), d = Jc(c); + return c + }; + h.Gc = function(a) { + return this.e() ? a.e() ? 0 : -1 : a.L() || a.e() ? 1 : a === we ? -1 : 0 + }; + h.pb = function(a) { + if (a === re || sa(this.Ab.hc, a.toString())) return this; + var b = this.Ab, + c = this.m; + O(a !== re, "KeyIndex always exists and isn't meant to be added to the IndexMap."); + for (var d = [], e = !1, c = c.ac(wc), f = Ic(c); f;) e = e || a.Lc(f.U), d.push(f), f = Ic(c); + d = e ? Me(d, Vd(a)) : te; + e = a.toString(); + c = wa(b.hc); + c[e] = a; + a = wa(b.Ed); + a[e] = d; + return new fe(this.m, this.ca, new Ke(a, c)) + }; + h.Mc = function(a) { + return a === re || sa(this.Ab.hc, a.toString()) + }; + h.ea = function(a) { + if (a === this) return !0; + if (a.L()) return !1; + if (this.C().ea(a.C()) && this.m.count() === a.m.count()) { + var b = this.ac(R); + a = a.ac(R); + for (var c = Ic(b), d = Ic(a); c && d;) { + if (c.name !== d.name || !c.U.ea(d.U)) return !1; + c = Ic(b); + d = Ic(a) + } + return null === c && null === d + } + return !1 + }; + + function Te(a, b) { + return b === re ? null : a.Ab.get(b.toString()) + } + h.toString = function() { + return G(this.J(!0)) + }; + + function Q(a, b) { + if (null === a) return H; + var c = null; + "object" === typeof a && ".priority" in a ? c = a[".priority"] : "undefined" !== typeof b && (c = b); + O(null === c || "string" === typeof c || "number" === typeof c || "object" === typeof c && ".sv" in c, "Invalid priority type found: " + typeof c); + "object" === typeof a && ".value" in a && null !== a[".value"] && (a = a[".value"]); + if ("object" !== typeof a || ".sv" in a) return new Yc(a, Q(c)); + if (a instanceof Array) { + var d = H, + e = a; + v(e, function(a, b) { + if (y(e, b) && "." !== b.substring(0, 1)) { + var c = Q(a); + if (c.L() || !c.e()) d = + d.W(b, c) + } + }); + return d.ia(Q(c)) + } + var f = [], + g = !1, + k = a; + Fb(k, function(a) { + if ("string" !== typeof a || "." !== a.substring(0, 1)) { + var b = Q(k[a]); + b.e() || (g = g || !b.C().e(), f.push(new L(a, b))) + } + }); + if (0 == f.length) return H; + var m = Me(f, xc, function(a) { + return a.name + }, zc); + if (g) { + var l = Me(f, Vd(R)); + return new fe(m, Q(c), new Ke({ + ".priority": l + }, { + ".priority": R + })) + } + return new fe(m, Q(c), Oe) + } + var Ue = Math.log(2); + + function Ve(a) { + this.count = parseInt(Math.log(a + 1) / Ue, 10); + this.nf = this.count - 1; + this.ng = a + 1 & parseInt(Array(this.count + 1).join("1"), 2) + } + + function We(a) { + var b = !(a.ng & 1 << a.nf); + a.nf--; + return b + } + + function Me(a, b, c, d) { + function e(b, d) { + var f = d - b; + if (0 == f) return null; + if (1 == f) { + var l = a[b], + t = c ? c(l) : l; + return new Kc(t, l.U, !1, null, null) + } + var l = parseInt(f / 2, 10) + b, + f = e(b, l), + A = e(l + 1, d), + l = a[l], + t = c ? c(l) : l; + return new Kc(t, l.U, !1, f, A) + } + a.sort(b); + var f = function(b) { + function d(b, g) { + var k = t - b, + A = t; + t -= b; + var A = e(k + 1, A), + k = a[k], + I = c ? c(k) : k, + A = new Kc(I, k.U, g, null, A); + f ? f.left = A : l = A; + f = A + } + for (var f = null, l = null, t = a.length, A = 0; A < b.count; ++A) { + var I = We(b), + Qd = Math.pow(2, b.count - (A + 1)); + I ? d(Qd, !1) : (d(Qd, !1), d(Qd, !0)) + } + return l + }(new Ve(a.length)); + return null !== f ? new Ec(d || b, f) : new Ec(d || b) + } + + function Re(a) { + return "number" === typeof a ? "number:" + Ad(a) : "string:" + a + } + + function Pe(a) { + if (a.L()) { + var b = a.J(); + O("string" === typeof b || "number" === typeof b || "object" === typeof b && y(b, ".sv"), "Priority must be a string or number.") + } else O(a === we || a.e(), "priority of unexpected type."); + O(a === we || a.C().e(), "Priority nodes can't have a priority of their own.") + } + var H = new fe(new Ec(zc), null, Oe); + + function Xe() { + fe.call(this, new Ec(zc), H, Oe) + } + ka(Xe, fe); + h = Xe.prototype; + h.Gc = function(a) { + return a === this ? 0 : 1 + }; + h.ea = function(a) { + return a === this + }; + h.C = function() { + return this + }; + h.T = function() { + return H + }; + h.e = function() { + return !1 + }; + var we = new Xe, + ue = new L("[MIN_NAME]", H), + Ae = new L("[MAX_NAME]", we); + + function je(a, b) { + this.Q = a; + this.ae = b + } + + function ge(a, b, c, d) { + return new je(new Xb(b, c, d), a.ae) + } + + function ke(a) { + return a.Q.ga ? a.Q.j() : null + } + je.prototype.w = function() { + return this.ae + }; + + function Yb(a) { + return a.ae.ga ? a.ae.j() : null + }; + + function Ye(a, b) { + this.Y = a; + var c = a.n, + d = new Ld(c.g), + c = He(c) ? new Ld(c.g) : c.la ? new Sd(c) : new Md(c); + this.Nf = new Zd(c); + var e = b.w(), + f = b.Q, + g = d.ya(H, e.j(), null), + k = c.ya(H, f.j(), null); + this.Oa = new je(new Xb(k, f.ga, c.Ra()), new Xb(g, e.ga, d.Ra())); + this.$a = []; + this.ug = new Fd(a) + } + + function Ze(a) { + return a.Y + } + h = Ye.prototype; + h.w = function() { + return this.Oa.w().j() + }; + h.kb = function(a) { + var b = Yb(this.Oa); + return b && (He(this.Y.n) || !a.e() && !b.T(K(a)).e()) ? b.S(a) : null + }; + h.e = function() { + return 0 === this.$a.length + }; + h.Tb = function(a) { + this.$a.push(a) + }; + h.nb = function(a, b) { + var c = []; + if (b) { + O(null == a, "A cancel should cancel all event registrations."); + var d = this.Y.path; + Ma(this.$a, function(a) { + (a = a.lf(b, d)) && c.push(a) + }) + } + if (a) { + for (var e = [], f = 0; f < this.$a.length; ++f) { + var g = this.$a[f]; + if (!g.matches(a)) e.push(g); + else if (a.yf()) { + e = e.concat(this.$a.slice(f + 1)); + break + } + } + this.$a = e + } else this.$a = []; + return c + }; + h.gb = function(a, b, c) { + a.type === be && null !== a.source.Lb && (O(Yb(this.Oa), "We should always have a full cache before handling merges"), O(ke(this.Oa), "Missing event cache, even though we have a server cache")); + var d = this.Oa; + a = this.Nf.gb(d, a, b, c); + b = this.Nf; + c = a.me; + O(c.Q.j().Mc(b.X.g), "Event snap not indexed"); + O(c.w().j().Mc(b.X.g), "Server snap not indexed"); + O(lc(a.me.w()) || !lc(d.w()), "Once a server snap is complete, it should never go back"); + this.Oa = a.me; + return $e(this, a.og, a.me.Q.j(), null) + }; + + function af(a, b) { + var c = a.Oa.Q, + d = []; + c.j().L() || c.j().R(R, function(a, b) { + d.push(new J("child_added", b, a)) + }); + c.ga && d.push(hc(c.j())); + return $e(a, d, c.j(), b) + } + + function $e(a, b, c, d) { + return Gd(a.ug, b, c, d ? [d] : a.$a) + }; + + function bf(a, b, c) { + this.type = be; + this.source = a; + this.path = b; + this.children = c + } + bf.prototype.$c = function(a) { + if (this.path.e()) return a = this.children.subtree(new P(a)), a.e() ? null : a.value ? new Ac(this.source, M, a.value) : new bf(this.source, M, a); + O(K(this.path) === a, "Can't get a merge for a child not on the path of the operation"); + return new bf(this.source, N(this.path), this.children) + }; + bf.prototype.toString = function() { + return "Operation(" + this.path + ": " + this.source.toString() + " merge: " + this.children.toString() + ")" + }; + + function cf(a, b) { + this.f = pd("p:rest:"); + this.G = a; + this.Kb = b; + this.Ca = null; + this.ba = {} + } + + function df(a, b) { + if (p(b)) return "tag$" + b; + O(Ie(a.n), "should have a tag if it's not a default query."); + return a.path.toString() + } + h = cf.prototype; + h.Cf = function(a, b, c, d) { + var e = a.path.toString(); + this.f("Listen called for " + e + " " + a.wa()); + var f = df(a, c), + g = {}; + this.ba[f] = g; + a = Je(a.n); + var k = this; + ef(this, e + ".json", a, function(a, b) { + var t = b; + 404 === a && (a = t = null); + null === a && k.Kb(e, t, !1, c); + z(k.ba, f) === g && d(a ? 401 == a ? "permission_denied" : "rest_error:" + a : "ok", null) + }) + }; + h.$f = function(a, b) { + var c = df(a, b); + delete this.ba[c] + }; + h.O = function(a, b) { + this.Ca = a; + var c = Cd(a), + d = c.data, + c = c.Ec && c.Ec.exp; + b && b("ok", { + auth: d, + expires: c + }) + }; + h.je = function(a) { + this.Ca = null; + a("ok", null) + }; + h.Qe = function() {}; + h.Gf = function() {}; + h.Md = function() {}; + h.put = function() {}; + h.Df = function() {}; + h.Ye = function() {}; + + function ef(a, b, c, d) { + c = c || {}; + c.format = "export"; + a.Ca && (c.auth = a.Ca); + var e = (a.G.ob ? "https://" : "http://") + a.G.host + b + "?" + Ib(c); + a.f("Sending REST request for " + e); + var f = new XMLHttpRequest; + f.onreadystatechange = function() { + if (d && 4 === f.readyState) { + a.f("REST Response for " + e + " received. status:", f.status, "response:", f.responseText); + var b = null; + if (200 <= f.status && 300 > f.status) { + try { + b = Rb(f.responseText) + } catch (c) { + S("Failed to parse JSON response for " + e + ": " + f.responseText) + } + d(null, b) + } else 401 !== f.status && 404 !== + f.status && S("Got unsuccessful REST response for " + e + " Status: " + f.status), d(f.status); + d = null + } + }; + f.open("GET", e, !0); + f.send() + }; + + function ff(a) { + O(da(a) && 0 < a.length, "Requires a non-empty array"); + this.fg = a; + this.Rc = {} + } + ff.prototype.ie = function(a, b) { + var c; + c = this.Rc[a] || []; + var d = c.length; + if (0 < d) { + for (var e = Array(d), f = 0; f < d; f++) e[f] = c[f]; + c = e + } else c = []; + for (d = 0; d < c.length; d++) c[d].Dc.apply(c[d].Qa, Array.prototype.slice.call(arguments, 1)) + }; + ff.prototype.Ib = function(a, b, c) { + gf(this, a); + this.Rc[a] = this.Rc[a] || []; + this.Rc[a].push({ + Dc: b, + Qa: c + }); + (a = this.Ee(a)) && b.apply(c, a) + }; + ff.prototype.mc = function(a, b, c) { + gf(this, a); + a = this.Rc[a] || []; + for (var d = 0; d < a.length; d++) + if (a[d].Dc === b && (!c || c === a[d].Qa)) { + a.splice(d, 1); + break + } + }; + + function gf(a, b) { + O(Ra(a.fg, function(a) { + return a === b + }), "Unknown event: " + b) + }; + var hf = function() { + var a = 0, + b = []; + return function(c) { + var d = c === a; + a = c; + for (var e = Array(8), f = 7; 0 <= f; f--) e[f] = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(c % 64), c = Math.floor(c / 64); + O(0 === c, "Cannot push at time == 0"); + c = e.join(""); + if (d) { + for (f = 11; 0 <= f && 63 === b[f]; f--) b[f] = 0; + b[f]++ + } else + for (f = 0; 12 > f; f++) b[f] = Math.floor(64 * Math.random()); + for (f = 0; 12 > f; f++) c += "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(b[f]); + O(20 === c.length, "nextPushId: Length should be 20."); + return c + } + }(); + + function jf() { + ff.call(this, ["online"]); + this.oc = !0; + if ("undefined" !== typeof window && "undefined" !== typeof window.addEventListener) { + var a = this; + window.addEventListener("online", function() { + a.oc || (a.oc = !0, a.ie("online", !0)) + }, !1); + window.addEventListener("offline", function() { + a.oc && (a.oc = !1, a.ie("online", !1)) + }, !1) + } + } + ka(jf, ff); + jf.prototype.Ee = function(a) { + O("online" === a, "Unknown event type: " + a); + return [this.oc] + }; + ba(jf); + + function kf() { + ff.call(this, ["visible"]); + var a, b; + "undefined" !== typeof document && "undefined" !== typeof document.addEventListener && ("undefined" !== typeof document.hidden ? (b = "visibilitychange", a = "hidden") : "undefined" !== typeof document.mozHidden ? (b = "mozvisibilitychange", a = "mozHidden") : "undefined" !== typeof document.msHidden ? (b = "msvisibilitychange", a = "msHidden") : "undefined" !== typeof document.webkitHidden && (b = "webkitvisibilitychange", a = "webkitHidden")); + this.Sb = !0; + if (b) { + var c = this; + document.addEventListener(b, + function() { + var b = !document[a]; + b !== c.Sb && (c.Sb = b, c.ie("visible", b)) + }, !1) + } + } + ka(kf, ff); + kf.prototype.Ee = function(a) { + O("visible" === a, "Unknown event type: " + a); + return [this.Sb] + }; + ba(kf); + + function P(a, b) { + if (1 == arguments.length) { + this.u = a.split("/"); + for (var c = 0, d = 0; d < this.u.length; d++) 0 < this.u[d].length && (this.u[c] = this.u[d], c++); + this.u.length = c; + this.aa = 0 + } else this.u = a, this.aa = b + } + + function lf(a, b) { + var c = K(a); + if (null === c) return b; + if (c === K(b)) return lf(N(a), N(b)); + throw Error("INTERNAL ERROR: innerPath (" + b + ") is not within outerPath (" + a + ")"); + } + + function mf(a, b) { + for (var c = a.slice(), d = b.slice(), e = 0; e < c.length && e < d.length; e++) { + var f = yc(c[e], d[e]); + if (0 !== f) return f + } + return c.length === d.length ? 0 : c.length < d.length ? -1 : 1 + } + + function K(a) { + return a.aa >= a.u.length ? null : a.u[a.aa] + } + + function le(a) { + return a.u.length - a.aa + } + + function N(a) { + var b = a.aa; + b < a.u.length && b++; + return new P(a.u, b) + } + + function me(a) { + return a.aa < a.u.length ? a.u[a.u.length - 1] : null + } + h = P.prototype; + h.toString = function() { + for (var a = "", b = this.aa; b < this.u.length; b++) "" !== this.u[b] && (a += "/" + this.u[b]); + return a || "/" + }; + h.slice = function(a) { + return this.u.slice(this.aa + (a || 0)) + }; + h.parent = function() { + if (this.aa >= this.u.length) return null; + for (var a = [], b = this.aa; b < this.u.length - 1; b++) a.push(this.u[b]); + return new P(a, 0) + }; + h.o = function(a) { + for (var b = [], c = this.aa; c < this.u.length; c++) b.push(this.u[c]); + if (a instanceof P) + for (c = a.aa; c < a.u.length; c++) b.push(a.u[c]); + else + for (a = a.split("/"), c = 0; c < a.length; c++) 0 < a[c].length && b.push(a[c]); + return new P(b, 0) + }; + h.e = function() { + return this.aa >= this.u.length + }; + h.ea = function(a) { + if (le(this) !== le(a)) return !1; + for (var b = this.aa, c = a.aa; b <= this.u.length; b++, c++) + if (this.u[b] !== a.u[c]) return !1; + return !0 + }; + h.contains = function(a) { + var b = this.aa, + c = a.aa; + if (le(this) > le(a)) return !1; + for (; b < this.u.length;) { + if (this.u[b] !== a.u[c]) return !1; + ++b; + ++c + } + return !0 + }; + var M = new P(""); + + function nf(a, b) { + this.Ua = a.slice(); + this.Ka = Math.max(1, this.Ua.length); + this.pf = b; + for (var c = 0; c < this.Ua.length; c++) this.Ka += Pb(this.Ua[c]); + of(this) + } + nf.prototype.push = function(a) { + 0 < this.Ua.length && (this.Ka += 1); + this.Ua.push(a); + this.Ka += Pb(a); + of(this) + }; + nf.prototype.pop = function() { + var a = this.Ua.pop(); + this.Ka -= Pb(a); + 0 < this.Ua.length && --this.Ka + }; + + function of(a) { + if (768 < a.Ka) throw Error(a.pf + "has a key path longer than 768 bytes (" + a.Ka + ")."); + if (32 < a.Ua.length) throw Error(a.pf + "path specified exceeds the maximum depth that can be written (32) or object contains a cycle " + pf(a)); + } + + function pf(a) { + return 0 == a.Ua.length ? "" : "in property '" + a.Ua.join(".") + "'" + }; + + function qf(a, b) { + this.value = a; + this.children = b || rf + } + var rf = new Ec(function(a, b) { + return a === b ? 0 : a < b ? -1 : 1 + }); + + function sf(a) { + var b = qe; + v(a, function(a, d) { + b = b.set(new P(d), a) + }); + return b + } + h = qf.prototype; + h.e = function() { + return null === this.value && this.children.e() + }; + + function tf(a, b, c) { + if (null != a.value && c(a.value)) return { + path: M, + value: a.value + }; + if (b.e()) return null; + var d = K(b); + a = a.children.get(d); + return null !== a ? (b = tf(a, N(b), c), null != b ? { + path: (new P(d)).o(b.path), + value: b.value + } : null) : null + } + + function uf(a, b) { + return tf(a, b, function() { + return !0 + }) + } + h.subtree = function(a) { + if (a.e()) return this; + var b = this.children.get(K(a)); + return null !== b ? b.subtree(N(a)) : qe + }; + h.set = function(a, b) { + if (a.e()) return new qf(b, this.children); + var c = K(a), + d = (this.children.get(c) || qe).set(N(a), b), + c = this.children.Sa(c, d); + return new qf(this.value, c) + }; + h.remove = function(a) { + if (a.e()) return this.children.e() ? qe : new qf(null, this.children); + var b = K(a), + c = this.children.get(b); + return c ? (a = c.remove(N(a)), b = a.e() ? this.children.remove(b) : this.children.Sa(b, a), null === this.value && b.e() ? qe : new qf(this.value, b)) : this + }; + h.get = function(a) { + if (a.e()) return this.value; + var b = this.children.get(K(a)); + return b ? b.get(N(a)) : null + }; + + function pe(a, b, c) { + if (b.e()) return c; + var d = K(b); + b = pe(a.children.get(d) || qe, N(b), c); + d = b.e() ? a.children.remove(d) : a.children.Sa(d, b); + return new qf(a.value, d) + } + + function vf(a, b) { + return wf(a, M, b) + } + + function wf(a, b, c) { + var d = {}; + a.children.ka(function(a, f) { + d[a] = wf(f, b.o(a), c) + }); + return c(b, a.value, d) + } + + function xf(a, b, c) { + return yf(a, b, M, c) + } + + function yf(a, b, c, d) { + var e = a.value ? d(c, a.value) : !1; + if (e) return e; + if (b.e()) return null; + e = K(b); + return (a = a.children.get(e)) ? yf(a, N(b), c.o(e), d) : null + } + + function zf(a, b, c) { + Af(a, b, M, c) + } + + function Af(a, b, c, d) { + if (b.e()) return a; + a.value && d(c, a.value); + var e = K(b); + return (a = a.children.get(e)) ? Af(a, N(b), c.o(e), d) : qe + } + + function ne(a, b) { + Bf(a, M, b) + } + + function Bf(a, b, c) { + a.children.ka(function(a, e) { + Bf(e, b.o(a), c) + }); + a.value && c(b, a.value) + } + + function Cf(a, b) { + a.children.ka(function(a, d) { + d.value && b(a, d.value) + }) + } + var qe = new qf(null); + qf.prototype.toString = function() { + var a = {}; + ne(this, function(b, c) { + a[b.toString()] = c.toString() + }); + return G(a) + }; + + function Df(a, b, c) { + this.type = ee; + this.source = Ef; + this.path = a; + this.Ub = b; + this.Yd = c + } + Df.prototype.$c = function(a) { + if (this.path.e()) { + if (null != this.Ub.value) return O(this.Ub.children.e(), "affectedTree should not have overlapping affected paths."), this; + a = this.Ub.subtree(new P(a)); + return new Df(M, a, this.Yd) + } + O(K(this.path) === a, "operationForChild called for unrelated child."); + return new Df(N(this.path), this.Ub, this.Yd) + }; + Df.prototype.toString = function() { + return "Operation(" + this.path + ": " + this.source.toString() + " ack write revert=" + this.Yd + " affectedTree=" + this.Ub + ")" + }; + var Bc = 0, + be = 1, + ee = 2, + Dc = 3; + + function Ff(a, b, c, d) { + this.Ae = a; + this.tf = b; + this.Lb = c; + this.ef = d; + O(!d || b, "Tagged queries must be from server.") + } + var Ef = new Ff(!0, !1, null, !1), + Gf = new Ff(!1, !0, null, !1); + Ff.prototype.toString = function() { + return this.Ae ? "user" : this.ef ? "server(queryID=" + this.Lb + ")" : "server" + }; + + function Hf(a) { + this.Z = a + } + var If = new Hf(new qf(null)); + + function Jf(a, b, c) { + if (b.e()) return new Hf(new qf(c)); + var d = uf(a.Z, b); + if (null != d) { + var e = d.path, + d = d.value; + b = lf(e, b); + d = d.H(b, c); + return new Hf(a.Z.set(e, d)) + } + a = pe(a.Z, b, new qf(c)); + return new Hf(a) + } + + function Kf(a, b, c) { + var d = a; + Fb(c, function(a, c) { + d = Jf(d, b.o(a), c) + }); + return d + } + Hf.prototype.Ud = function(a) { + if (a.e()) return If; + a = pe(this.Z, a, qe); + return new Hf(a) + }; + + function Lf(a, b) { + var c = uf(a.Z, b); + return null != c ? a.Z.get(c.path).S(lf(c.path, b)) : null + } + + function Mf(a) { + var b = [], + c = a.Z.value; + null != c ? c.L() || c.R(R, function(a, c) { + b.push(new L(a, c)) + }) : a.Z.children.ka(function(a, c) { + null != c.value && b.push(new L(a, c.value)) + }); + return b + } + + function Nf(a, b) { + if (b.e()) return a; + var c = Lf(a, b); + return null != c ? new Hf(new qf(c)) : new Hf(a.Z.subtree(b)) + } + Hf.prototype.e = function() { + return this.Z.e() + }; + Hf.prototype.apply = function(a) { + return Of(M, this.Z, a) + }; + + function Of(a, b, c) { + if (null != b.value) return c.H(a, b.value); + var d = null; + b.children.ka(function(b, f) { + ".priority" === b ? (O(null !== f.value, "Priority writes must always be leaf nodes"), d = f.value) : c = Of(a.o(b), f, c) + }); + c.S(a).e() || null === d || (c = c.H(a.o(".priority"), d)); + return c + }; + + function Pf() { + this.V = If; + this.pa = []; + this.Pc = -1 + } + + function Qf(a, b) { + for (var c = 0; c < a.pa.length; c++) { + var d = a.pa[c]; + if (d.md === b) return d + } + return null + } + h = Pf.prototype; + h.Ud = function(a) { + var b = Sa(this.pa, function(b) { + return b.md === a + }); + O(0 <= b, "removeWrite called with nonexistent writeId."); + var c = this.pa[b]; + this.pa.splice(b, 1); + for (var d = c.visible, e = !1, f = this.pa.length - 1; d && 0 <= f;) { + var g = this.pa[f]; + g.visible && (f >= b && Rf(g, c.path) ? d = !1 : c.path.contains(g.path) && (e = !0)); + f-- + } + if (d) { + if (e) this.V = Sf(this.pa, Tf, M), this.Pc = 0 < this.pa.length ? this.pa[this.pa.length - 1].md : -1; + else if (c.Ja) this.V = this.V.Ud(c.path); + else { + var k = this; + v(c.children, function(a, b) { + k.V = k.V.Ud(c.path.o(b)) + }) + } + return !0 + } + return !1 + }; + h.Aa = function(a, b, c, d) { + if (c || d) { + var e = Nf(this.V, a); + return !d && e.e() ? b : d || null != b || null != Lf(e, M) ? (e = Sf(this.pa, function(b) { + return (b.visible || d) && (!c || !(0 <= La(c, b.md))) && (b.path.contains(a) || a.contains(b.path)) + }, a), b = b || H, e.apply(b)) : null + } + e = Lf(this.V, a); + if (null != e) return e; + e = Nf(this.V, a); + return e.e() ? b : null != b || null != Lf(e, M) ? (b = b || H, e.apply(b)) : null + }; + h.Cc = function(a, b) { + var c = H, + d = Lf(this.V, a); + if (d) d.L() || d.R(R, function(a, b) { + c = c.W(a, b) + }); + else if (b) { + var e = Nf(this.V, a); + b.R(R, function(a, b) { + var d = Nf(e, new P(a)).apply(b); + c = c.W(a, d) + }); + Ma(Mf(e), function(a) { + c = c.W(a.name, a.U) + }) + } else e = Nf(this.V, a), Ma(Mf(e), function(a) { + c = c.W(a.name, a.U) + }); + return c + }; + h.nd = function(a, b, c, d) { + O(c || d, "Either existingEventSnap or existingServerSnap must exist"); + a = a.o(b); + if (null != Lf(this.V, a)) return null; + a = Nf(this.V, a); + return a.e() ? d.S(b) : a.apply(d.S(b)) + }; + h.Bc = function(a, b, c) { + a = a.o(b); + var d = Lf(this.V, a); + return null != d ? d : Wb(c, b) ? Nf(this.V, a).apply(c.j().T(b)) : null + }; + h.xc = function(a) { + return Lf(this.V, a) + }; + h.qe = function(a, b, c, d, e, f) { + var g; + a = Nf(this.V, a); + g = Lf(a, M); + if (null == g) + if (null != b) g = a.apply(b); + else return []; + g = g.pb(f); + if (g.e() || g.L()) return []; + b = []; + a = Vd(f); + e = e ? g.dc(c, f) : g.bc(c, f); + for (f = Ic(e); f && b.length < d;) 0 !== a(f, c) && b.push(f), f = Ic(e); + return b + }; + + function Rf(a, b) { + return a.Ja ? a.path.contains(b) : !!ta(a.children, function(c, d) { + return a.path.o(d).contains(b) + }) + } + + function Tf(a) { + return a.visible + } + + function Sf(a, b, c) { + for (var d = If, e = 0; e < a.length; ++e) { + var f = a[e]; + if (b(f)) { + var g = f.path; + if (f.Ja) c.contains(g) ? (g = lf(c, g), d = Jf(d, g, f.Ja)) : g.contains(c) && (g = lf(g, c), d = Jf(d, M, f.Ja.S(g))); + else if (f.children) + if (c.contains(g)) g = lf(c, g), d = Kf(d, g, f.children); + else { + if (g.contains(c)) + if (g = lf(g, c), g.e()) d = Kf(d, M, f.children); + else if (f = z(f.children, K(g))) f = f.S(N(g)), d = Jf(d, M, f) + } else throw jd("WriteRecord should have .snap or .children"); + } + } + return d + } + + function Uf(a, b) { + this.Qb = a; + this.Z = b + } + h = Uf.prototype; + h.Aa = function(a, b, c) { + return this.Z.Aa(this.Qb, a, b, c) + }; + h.Cc = function(a) { + return this.Z.Cc(this.Qb, a) + }; + h.nd = function(a, b, c) { + return this.Z.nd(this.Qb, a, b, c) + }; + h.xc = function(a) { + return this.Z.xc(this.Qb.o(a)) + }; + h.qe = function(a, b, c, d, e) { + return this.Z.qe(this.Qb, a, b, c, d, e) + }; + h.Bc = function(a, b) { + return this.Z.Bc(this.Qb, a, b) + }; + h.o = function(a) { + return new Uf(this.Qb.o(a), this.Z) + }; + + function Vf() { + this.children = {}; + this.pd = 0; + this.value = null + } + + function Wf(a, b, c) { + this.Jd = a ? a : ""; + this.Ha = b ? b : null; + this.A = c ? c : new Vf + } + + function Xf(a, b) { + for (var c = b instanceof P ? b : new P(b), d = a, e; null !== (e = K(c));) d = new Wf(e, d, z(d.A.children, e) || new Vf), c = N(c); + return d + } + h = Wf.prototype; + h.Ea = function() { + return this.A.value + }; + + function Yf(a, b) { + O("undefined" !== typeof b, "Cannot set value to undefined"); + a.A.value = b; + Zf(a) + } + h.clear = function() { + this.A.value = null; + this.A.children = {}; + this.A.pd = 0; + Zf(this) + }; + h.zd = function() { + return 0 < this.A.pd + }; + h.e = function() { + return null === this.Ea() && !this.zd() + }; + h.R = function(a) { + var b = this; + v(this.A.children, function(c, d) { + a(new Wf(d, b, c)) + }) + }; + + function $f(a, b, c, d) { + c && !d && b(a); + a.R(function(a) { + $f(a, b, !0, d) + }); + c && d && b(a) + } + + function ag(a, b) { + for (var c = a.parent(); null !== c && !b(c);) c = c.parent() + } + h.path = function() { + return new P(null === this.Ha ? this.Jd : this.Ha.path() + "/" + this.Jd) + }; + h.name = function() { + return this.Jd + }; + h.parent = function() { + return this.Ha + }; + + function Zf(a) { + if (null !== a.Ha) { + var b = a.Ha, + c = a.Jd, + d = a.e(), + e = y(b.A.children, c); + d && e ? (delete b.A.children[c], b.A.pd--, Zf(b)) : d || e || (b.A.children[c] = a.A, b.A.pd++, Zf(b)) + } + }; + var bg = /[\[\].#$\/\u0000-\u001F\u007F]/, + cg = /[\[\].#$\u0000-\u001F\u007F]/, + dg = /^[a-zA-Z][a-zA-Z._\-+]+$/; + + function eg(a) { + return q(a) && 0 !== a.length && !bg.test(a) + } + + function fg(a) { + return null === a || q(a) || fa(a) && !td(a) || ga(a) && y(a, ".sv") + } + + function gg(a, b, c, d) { + d && !p(b) || hg(E(a, 1, d), b, c) + } + + function hg(a, b, c) { + c instanceof P && (c = new nf(c, a)); + if (!p(b)) throw Error(a + "contains undefined " + pf(c)); + if (r(b)) throw Error(a + "contains a function " + pf(c) + " with contents: " + b.toString()); + if (td(b)) throw Error(a + "contains " + b.toString() + " " + pf(c)); + if (q(b) && b.length > 10485760 / 3 && 10485760 < Pb(b)) throw Error(a + "contains a string greater than 10485760 utf8 bytes " + pf(c) + " ('" + b.substring(0, 50) + "...')"); + if (ga(b)) { + var d = !1, + e = !1; + Fb(b, function(b, g) { + if (".value" === b) d = !0; + else if (".priority" !== b && ".sv" !== b && (e = !0, !eg(b))) throw Error(a + " contains an invalid key (" + b + ") " + pf(c) + '. Keys must be non-empty strings and can\'t contain ".", "#", "$", "/", "[", or "]"'); + c.push(b); + hg(a, g, c); + c.pop() + }); + if (d && e) throw Error(a + ' contains ".value" child ' + pf(c) + " in addition to actual children."); + } + } + + function ig(a, b) { + var c, d; + for (c = 0; c < b.length; c++) { + d = b[c]; + for (var e = d.slice(), f = 0; f < e.length; f++) + if ((".priority" !== e[f] || f !== e.length - 1) && !eg(e[f])) throw Error(a + "contains an invalid key (" + e[f] + ") in path " + d.toString() + '. Keys must be non-empty strings and can\'t contain ".", "#", "$", "/", "[", or "]"'); + } + b.sort(mf); + e = null; + for (c = 0; c < b.length; c++) { + d = b[c]; + if (null !== e && e.contains(d)) throw Error(a + "contains a path " + e.toString() + " that is ancestor of another path " + d.toString()); + e = d + } + } + + function jg(a, b, c) { + var d = E(a, 1, !1); + if (!ga(b) || da(b)) throw Error(d + " must be an object containing the children to replace."); + var e = []; + Fb(b, function(a, b) { + var k = new P(a); + hg(d, b, c.o(k)); + if (".priority" === me(k) && !fg(b)) throw Error(d + "contains an invalid value for '" + k.toString() + "', which must be a valid Firebase priority (a string, finite number, server value, or null)."); + e.push(k) + }); + ig(d, e) + } + + function kg(a, b, c) { + if (td(c)) throw Error(E(a, b, !1) + "is " + c.toString() + ", but must be a valid Firebase priority (a string, finite number, server value, or null)."); + if (!fg(c)) throw Error(E(a, b, !1) + "must be a valid Firebase priority (a string, finite number, server value, or null)."); + } + + function lg(a, b, c) { + if (!c || p(b)) switch (b) { + case "value": + case "child_added": + case "child_removed": + case "child_changed": + case "child_moved": + break; + default: + throw Error(E(a, 1, c) + 'must be a valid event type: "value", "child_added", "child_removed", "child_changed", or "child_moved".'); + } + } + + function mg(a, b) { + if (p(b) && !eg(b)) throw Error(E(a, 2, !0) + 'was an invalid key: "' + b + '". Firebase keys must be non-empty strings and can\'t contain ".", "#", "$", "/", "[", or "]").'); + } + + function ng(a, b) { + if (!q(b) || 0 === b.length || cg.test(b)) throw Error(E(a, 1, !1) + 'was an invalid path: "' + b + '". Paths must be non-empty strings and can\'t contain ".", "#", "$", "[", or "]"'); + } + + function og(a, b) { + if (".info" === K(b)) throw Error(a + " failed: Can't modify data under /.info/"); + } + + function pg(a, b) { + if (!q(b)) throw Error(E(a, 1, !1) + "must be a valid credential (a string)."); + } + + function qg(a, b, c) { + if (!q(c)) throw Error(E(a, b, !1) + "must be a valid string."); + } + + function rg(a, b) { + qg(a, 1, b); + if (!dg.test(b)) throw Error(E(a, 1, !1) + "'" + b + "' is not a valid authentication provider."); + } + + function sg(a, b, c, d) { + if (!d || p(c)) + if (!ga(c) || null === c) throw Error(E(a, b, d) + "must be a valid object."); + } + + function tg(a, b, c) { + if (!ga(b) || !y(b, c)) throw Error(E(a, 1, !1) + 'must contain the key "' + c + '"'); + if (!q(z(b, c))) throw Error(E(a, 1, !1) + 'must contain the key "' + c + '" with type "string"'); + }; + + function ug() { + this.set = {} + } + h = ug.prototype; + h.add = function(a, b) { + this.set[a] = null !== b ? b : !0 + }; + h.contains = function(a) { + return y(this.set, a) + }; + h.get = function(a) { + return this.contains(a) ? this.set[a] : void 0 + }; + h.remove = function(a) { + delete this.set[a] + }; + h.clear = function() { + this.set = {} + }; + h.e = function() { + return va(this.set) + }; + h.count = function() { + return oa(this.set) + }; + + function vg(a, b) { + v(a.set, function(a, d) { + b(d, a) + }) + } + h.keys = function() { + var a = []; + v(this.set, function(b, c) { + a.push(c) + }); + return a + }; + + function Vc() { + this.m = this.B = null + } + Vc.prototype.find = function(a) { + if (null != this.B) return this.B.S(a); + if (a.e() || null == this.m) return null; + var b = K(a); + a = N(a); + return this.m.contains(b) ? this.m.get(b).find(a) : null + }; + Vc.prototype.rc = function(a, b) { + if (a.e()) this.B = b, this.m = null; + else if (null !== this.B) this.B = this.B.H(a, b); + else { + null == this.m && (this.m = new ug); + var c = K(a); + this.m.contains(c) || this.m.add(c, new Vc); + c = this.m.get(c); + a = N(a); + c.rc(a, b) + } + }; + + function wg(a, b) { + if (b.e()) return a.B = null, a.m = null, !0; + if (null !== a.B) { + if (a.B.L()) return !1; + var c = a.B; + a.B = null; + c.R(R, function(b, c) { + a.rc(new P(b), c) + }); + return wg(a, b) + } + return null !== a.m ? (c = K(b), b = N(b), a.m.contains(c) && wg(a.m.get(c), b) && a.m.remove(c), a.m.e() ? (a.m = null, !0) : !1) : !0 + } + + function Wc(a, b, c) { + null !== a.B ? c(b, a.B) : a.R(function(a, e) { + var f = new P(b.toString() + "/" + a); + Wc(e, f, c) + }) + } + Vc.prototype.R = function(a) { + null !== this.m && vg(this.m, function(b, c) { + a(b, c) + }) + }; + var xg = "auth.firebase.com"; + + function yg(a, b, c) { + this.qd = a || {}; + this.he = b || {}; + this.fb = c || {}; + this.qd.remember || (this.qd.remember = "default") + } + var zg = ["remember", "redirectTo"]; + + function Ag(a) { + var b = {}, + c = {}; + Fb(a || {}, function(a, e) { + 0 <= La(zg, a) ? b[a] = e : c[a] = e + }); + return new yg(b, {}, c) + }; + + function Bg(a, b) { + this.Ue = ["session", a.Rd, a.lc].join(":"); + this.ee = b + } + Bg.prototype.set = function(a, b) { + if (!b) + if (this.ee.length) b = this.ee[0]; + else throw Error("fb.login.SessionManager : No storage options available!"); + b.set(this.Ue, a) + }; + Bg.prototype.get = function() { + var a = Oa(this.ee, u(this.Bg, this)), + a = Na(a, function(a) { + return null !== a + }); + Va(a, function(a, c) { + return Dd(c.token) - Dd(a.token) + }); + return 0 < a.length ? a.shift() : null + }; + Bg.prototype.Bg = function(a) { + try { + var b = a.get(this.Ue); + if (b && b.token) return b + } catch (c) {} + return null + }; + Bg.prototype.clear = function() { + var a = this; + Ma(this.ee, function(b) { + b.remove(a.Ue) + }) + }; + + function Cg() { + return "undefined" !== typeof navigator && "string" === typeof navigator.userAgent ? navigator.userAgent : "" + } + + function Dg() { + return "undefined" !== typeof window && !!(window.cordova || window.phonegap || window.PhoneGap) && /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(Cg()) + } + + function Eg() { + return "undefined" !== typeof location && /^file:\//.test(location.href) + } + + function Fg(a) { + var b = Cg(); + if ("" === b) return !1; + if ("Microsoft Internet Explorer" === navigator.appName) { + if ((b = b.match(/MSIE ([0-9]{1,}[\.0-9]{0,})/)) && 1 < b.length) return parseFloat(b[1]) >= a + } else if (-1 < b.indexOf("Trident") && (b = b.match(/rv:([0-9]{2,2}[\.0-9]{0,})/)) && 1 < b.length) return parseFloat(b[1]) >= a; + return !1 + }; + + function Gg() { + var a = window.opener.frames, + b; + for (b = a.length - 1; 0 <= b; b--) try { + if (a[b].location.protocol === window.location.protocol && a[b].location.host === window.location.host && "__winchan_relay_frame" === a[b].name) return a[b] + } catch (c) {} + return null + } + + function Hg(a, b, c) { + a.attachEvent ? a.attachEvent("on" + b, c) : a.addEventListener && a.addEventListener(b, c, !1) + } + + function Ig(a, b, c) { + a.detachEvent ? a.detachEvent("on" + b, c) : a.removeEventListener && a.removeEventListener(b, c, !1) + } + + function Jg(a) { + /^https?:\/\//.test(a) || (a = window.location.href); + var b = /^(https?:\/\/[\-_a-zA-Z\.0-9:]+)/.exec(a); + return b ? b[1] : a + } + + function Kg(a) { + var b = ""; + try { + a = a.replace(/.*\?/, ""); + var c = Jb(a); + c && y(c, "__firebase_request_key") && (b = z(c, "__firebase_request_key")) + } catch (d) {} + return b + } + + function Lg() { + var a = sd(xg); + return a.scheme + "://" + a.host + "/v2" + } + + function Mg(a) { + return Lg() + "/" + a + "/auth/channel" + }; + + function Ng(a) { + var b = this; + this.hb = a; + this.fe = "*"; + Fg(8) ? this.Uc = this.Cd = Gg() : (this.Uc = window.opener, this.Cd = window); + if (!b.Uc) throw "Unable to find relay frame"; + Hg(this.Cd, "message", u(this.nc, this)); + Hg(this.Cd, "message", u(this.Ff, this)); + try { + Og(this, { + a: "ready" + }) + } catch (c) { + Hg(this.Uc, "load", function() { + Og(b, { + a: "ready" + }) + }) + } + Hg(window, "unload", u(this.Mg, this)) + } + + function Og(a, b) { + b = G(b); + Fg(8) ? a.Uc.doPost(b, a.fe) : a.Uc.postMessage(b, a.fe) + } + Ng.prototype.nc = function(a) { + var b = this, + c; + try { + c = Rb(a.data) + } catch (d) {} + c && "request" === c.a && (Ig(window, "message", this.nc), this.fe = a.origin, this.hb && setTimeout(function() { + b.hb(b.fe, c.d, function(a, c) { + b.mg = !c; + b.hb = void 0; + Og(b, { + a: "response", + d: a, + forceKeepWindowOpen: c + }) + }) + }, 0)) + }; + Ng.prototype.Mg = function() { + try { + Ig(this.Cd, "message", this.Ff) + } catch (a) {} + this.hb && (Og(this, { + a: "error", + d: "unknown closed window" + }), this.hb = void 0); + try { + window.close() + } catch (b) {} + }; + Ng.prototype.Ff = function(a) { + if (this.mg && "die" === a.data) try { + window.close() + } catch (b) {} + }; + + function Pg(a) { + this.tc = Fa() + Fa() + Fa(); + this.Kf = a + } + Pg.prototype.open = function(a, b) { + cd.set("redirect_request_id", this.tc); + cd.set("redirect_request_id", this.tc); + b.requestId = this.tc; + b.redirectTo = b.redirectTo || window.location.href; + a += (/\?/.test(a) ? "" : "?") + Ib(b); + window.location = a + }; + Pg.isAvailable = function() { + return !Eg() && !Dg() + }; + Pg.prototype.Fc = function() { + return "redirect" + }; + var Qg = { + NETWORK_ERROR: "Unable to contact the Firebase server.", + SERVER_ERROR: "An unknown server error occurred.", + TRANSPORT_UNAVAILABLE: "There are no login transports available for the requested method.", + REQUEST_INTERRUPTED: "The browser redirected the page before the login request could complete.", + USER_CANCELLED: "The user cancelled authentication." + }; + + function Rg(a) { + var b = Error(z(Qg, a), a); + b.code = a; + return b + }; + + function Sg(a) { + var b; + (b = !a.window_features) || (b = Cg(), b = -1 !== b.indexOf("Fennec/") || -1 !== b.indexOf("Firefox/") && -1 !== b.indexOf("Android")); + b && (a.window_features = void 0); + a.window_name || (a.window_name = "_blank"); + this.options = a + } + Sg.prototype.open = function(a, b, c) { + function d(a) { + g && (document.body.removeChild(g), g = void 0); + t && (t = clearInterval(t)); + Ig(window, "message", e); + Ig(window, "unload", d); + if (l && !a) try { + l.close() + } catch (b) { + k.postMessage("die", m) + } + l = k = void 0 + } + + function e(a) { + if (a.origin === m) try { + var b = Rb(a.data); + "ready" === b.a ? k.postMessage(A, m) : "error" === b.a ? (d(!1), c && (c(b.d), c = null)) : "response" === b.a && (d(b.forceKeepWindowOpen), c && (c(null, b.d), c = null)) + } catch (e) {} + } + var f = Fg(8), + g, k; + if (!this.options.relay_url) return c(Error("invalid arguments: origin of url and relay_url must match")); + var m = Jg(a); + if (m !== Jg(this.options.relay_url)) c && setTimeout(function() { + c(Error("invalid arguments: origin of url and relay_url must match")) + }, 0); + else { + f && (g = document.createElement("iframe"), g.setAttribute("src", this.options.relay_url), g.style.display = "none", g.setAttribute("name", "__winchan_relay_frame"), document.body.appendChild(g), k = g.contentWindow); + a += (/\?/.test(a) ? "" : "?") + Ib(b); + var l = window.open(a, this.options.window_name, this.options.window_features); + k || (k = l); + var t = setInterval(function() { + l && l.closed && + (d(!1), c && (c(Rg("USER_CANCELLED")), c = null)) + }, 500), + A = G({ + a: "request", + d: b + }); + Hg(window, "unload", d); + Hg(window, "message", e) + } + }; + Sg.isAvailable = function() { + var a; + if (a = "postMessage" in window && !Eg())(a = Dg() || "undefined" !== typeof navigator && (!!Cg().match(/Windows Phone/) || !!window.Windows && /^ms-appx:/.test(location.href))) || (a = Cg(), a = "undefined" !== typeof navigator && "undefined" !== typeof window && !!(a.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i) || a.match(/CriOS/) || a.match(/Twitter for iPhone/) || a.match(/FBAN\/FBIOS/) || window.navigator.standalone)), a = !a; + return a && !Cg().match(/PhantomJS/) + }; + Sg.prototype.Fc = function() { + return "popup" + }; + + function Tg(a) { + a.method || (a.method = "GET"); + a.headers || (a.headers = {}); + a.headers.content_type || (a.headers.content_type = "application/json"); + a.headers.content_type = a.headers.content_type.toLowerCase(); + this.options = a + } + Tg.prototype.open = function(a, b, c) { + function d() { + c && (c(Rg("REQUEST_INTERRUPTED")), c = null) + } + var e = new XMLHttpRequest, + f = this.options.method.toUpperCase(), + g; + Hg(window, "beforeunload", d); + e.onreadystatechange = function() { + if (c && 4 === e.readyState) { + var a; + if (200 <= e.status && 300 > e.status) { + try { + a = Rb(e.responseText) + } catch (b) {} + c(null, a) + } else 500 <= e.status && 600 > e.status ? c(Rg("SERVER_ERROR")) : c(Rg("NETWORK_ERROR")); + c = null; + Ig(window, "beforeunload", d) + } + }; + if ("GET" === f) a += (/\?/.test(a) ? "" : "?") + Ib(b), g = null; + else { + var k = this.options.headers.content_type; + "application/json" === k && (g = G(b)); + "application/x-www-form-urlencoded" === k && (g = Ib(b)) + } + e.open(f, a, !0); + a = { + "X-Requested-With": "XMLHttpRequest", + Accept: "application/json;text/plain" + }; + ya(a, this.options.headers); + for (var m in a) e.setRequestHeader(m, a[m]); + e.send(g) + }; + Tg.isAvailable = function() { + var a; + if (a = !!window.XMLHttpRequest) a = Cg(), a = !(a.match(/MSIE/) || a.match(/Trident/)) || Fg(10); + return a + }; + Tg.prototype.Fc = function() { + return "json" + }; + + function Ug(a) { + this.tc = Fa() + Fa() + Fa(); + this.Kf = a + } + Ug.prototype.open = function(a, b, c) { + function d() { + c && (c(Rg("USER_CANCELLED")), c = null) + } + var e = this, + f = sd(xg), + g; + b.requestId = this.tc; + b.redirectTo = f.scheme + "://" + f.host + "/blank/page.html"; + a += /\?/.test(a) ? "" : "?"; + a += Ib(b); + (g = window.open(a, "_blank", "location=no")) && r(g.addEventListener) ? (g.addEventListener("loadstart", function(a) { + var b; + if (b = a && a.url) a: { + try { + var l = document.createElement("a"); + l.href = a.url; + b = l.host === f.host && "/blank/page.html" === l.pathname; + break a + } catch (t) {} + b = !1 + } + b && (a = Kg(a.url), g.removeEventListener("exit", + d), g.close(), a = new yg(null, null, { + requestId: e.tc, + requestKey: a + }), e.Kf.requestWithCredential("/auth/session", a, c), c = null) + }), g.addEventListener("exit", d)) : c(Rg("TRANSPORT_UNAVAILABLE")) + }; + Ug.isAvailable = function() { + return Dg() + }; + Ug.prototype.Fc = function() { + return "redirect" + }; + + function Vg(a) { + a.callback_parameter || (a.callback_parameter = "callback"); + this.options = a; + window.__firebase_auth_jsonp = window.__firebase_auth_jsonp || {} + } + Vg.prototype.open = function(a, b, c) { + function d() { + c && (c(Rg("REQUEST_INTERRUPTED")), c = null) + } + + function e() { + setTimeout(function() { + window.__firebase_auth_jsonp[f] = void 0; + va(window.__firebase_auth_jsonp) && (window.__firebase_auth_jsonp = void 0); + try { + var a = document.getElementById(f); + a && a.parentNode.removeChild(a) + } catch (b) {} + }, 1); + Ig(window, "beforeunload", d) + } + var f = "fn" + (new Date).getTime() + Math.floor(99999 * Math.random()); + b[this.options.callback_parameter] = "__firebase_auth_jsonp." + f; + a += (/\?/.test(a) ? "" : "?") + Ib(b); + Hg(window, "beforeunload", d); + window.__firebase_auth_jsonp[f] = function(a) { + c && (c(null, a), c = null); + e() + }; + Wg(f, a, c) + }; + + function Wg(a, b, c) { + setTimeout(function() { + try { + var d = document.createElement("script"); + d.type = "text/javascript"; + d.id = a; + d.async = !0; + d.src = b; + d.onerror = function() { + var b = document.getElementById(a); + null !== b && b.parentNode.removeChild(b); + c && c(Rg("NETWORK_ERROR")) + }; + var e = document.getElementsByTagName("head"); + (e && 0 != e.length ? e[0] : document.documentElement).appendChild(d) + } catch (f) { + c && c(Rg("NETWORK_ERROR")) + } + }, 0) + } + Vg.isAvailable = function() { + return "undefined" !== typeof document && null != document.createElement + }; + Vg.prototype.Fc = function() { + return "json" + }; + + function Xg(a, b, c, d) { + ff.call(this, ["auth_status"]); + this.G = a; + this.hf = b; + this.gh = c; + this.Pe = d; + this.wc = new Bg(a, [bd, cd]); + this.qb = null; + this.We = !1; + Yg(this) + } + ka(Xg, ff); + h = Xg.prototype; + h.Be = function() { + return this.qb || null + }; + + function Yg(a) { + cd.get("redirect_request_id") && Zg(a); + var b = a.wc.get(); + b && b.token ? ($g(a, b), a.hf(b.token, function(c, d) { + ah(a, c, d, !1, b.token, b) + }, function(b, d) { + bh(a, "resumeSession()", b, d) + })) : $g(a, null) + } + + function ch(a, b, c, d, e, f) { + "firebaseio-demo.com" === a.G.domain && S("Firebase authentication is not supported on demo Firebases (*.firebaseio-demo.com). To secure your Firebase, create a production Firebase at https://www.firebase.com."); + a.hf(b, function(f, k) { + ah(a, f, k, !0, b, c, d || {}, e) + }, function(b, c) { + bh(a, "auth()", b, c, f) + }) + } + + function dh(a, b) { + a.wc.clear(); + $g(a, null); + a.gh(function(a, d) { + if ("ok" === a) T(b, null); + else { + var e = (a || "error").toUpperCase(), + f = e; + d && (f += ": " + d); + f = Error(f); + f.code = e; + T(b, f) + } + }) + } + + function ah(a, b, c, d, e, f, g, k) { + "ok" === b ? (d && (b = c.auth, f.auth = b, f.expires = c.expires, f.token = Ed(e) ? e : "", c = null, b && y(b, "uid") ? c = z(b, "uid") : y(f, "uid") && (c = z(f, "uid")), f.uid = c, c = "custom", b && y(b, "provider") ? c = z(b, "provider") : y(f, "provider") && (c = z(f, "provider")), f.provider = c, a.wc.clear(), Ed(e) && (g = g || {}, c = bd, "sessionOnly" === g.remember && (c = cd), "none" !== g.remember && a.wc.set(f, c)), $g(a, f)), T(k, null, f)) : (a.wc.clear(), $g(a, null), f = a = (b || "error").toUpperCase(), c && (f += ": " + c), f = Error(f), f.code = a, T(k, f)) + } + + function bh(a, b, c, d, e) { + S(b + " was canceled: " + d); + a.wc.clear(); + $g(a, null); + a = Error(d); + a.code = c.toUpperCase(); + T(e, a) + } + + function eh(a, b, c, d, e) { + fh(a); + c = new yg(d || {}, {}, c || {}); + gh(a, [Tg, Vg], "/auth/" + b, c, e) + } + + function hh(a, b, c, d) { + fh(a); + var e = [Sg, Ug]; + c = Ag(c); + "anonymous" === b || "password" === b ? setTimeout(function() { + T(d, Rg("TRANSPORT_UNAVAILABLE")) + }, 0) : (c.he.window_features = "menubar=yes,modal=yes,alwaysRaised=yeslocation=yes,resizable=yes,scrollbars=yes,status=yes,height=625,width=625,top=" + ("object" === typeof screen ? .5 * (screen.height - 625) : 0) + ",left=" + ("object" === typeof screen ? .5 * (screen.width - 625) : 0), c.he.relay_url = Mg(a.G.lc), c.he.requestWithCredential = u(a.uc, a), gh(a, e, "/auth/" + b, c, d)) + } + + function Zg(a) { + var b = cd.get("redirect_request_id"); + if (b) { + var c = cd.get("redirect_client_options"); + cd.remove("redirect_request_id"); + cd.remove("redirect_client_options"); + var d = [Tg, Vg], + b = { + requestId: b, + requestKey: Kg(document.location.hash) + }, + c = new yg(c, {}, b); + a.We = !0; + try { + document.location.hash = document.location.hash.replace(/&__firebase_request_key=([a-zA-z0-9]*)/, "") + } catch (e) {} + gh(a, d, "/auth/session", c, function() { + this.We = !1 + }.bind(a)) + } + } + h.ve = function(a, b) { + fh(this); + var c = Ag(a); + c.fb._method = "POST"; + this.uc("/users", c, function(a, c) { + a ? T(b, a) : T(b, a, c) + }) + }; + h.Xe = function(a, b) { + var c = this; + fh(this); + var d = "/users/" + encodeURIComponent(a.email), + e = Ag(a); + e.fb._method = "DELETE"; + this.uc(d, e, function(a, d) { + !a && d && d.uid && c.qb && c.qb.uid && c.qb.uid === d.uid && dh(c); + T(b, a) + }) + }; + h.se = function(a, b) { + fh(this); + var c = "/users/" + encodeURIComponent(a.email) + "/password", + d = Ag(a); + d.fb._method = "PUT"; + d.fb.password = a.newPassword; + this.uc(c, d, function(a) { + T(b, a) + }) + }; + h.re = function(a, b) { + fh(this); + var c = "/users/" + encodeURIComponent(a.oldEmail) + "/email", + d = Ag(a); + d.fb._method = "PUT"; + d.fb.email = a.newEmail; + d.fb.password = a.password; + this.uc(c, d, function(a) { + T(b, a) + }) + }; + h.Ze = function(a, b) { + fh(this); + var c = "/users/" + encodeURIComponent(a.email) + "/password", + d = Ag(a); + d.fb._method = "POST"; + this.uc(c, d, function(a) { + T(b, a) + }) + }; + h.uc = function(a, b, c) { + ih(this, [Tg, Vg], a, b, c) + }; + + function gh(a, b, c, d, e) { + ih(a, b, c, d, function(b, c) { + !b && c && c.token && c.uid ? ch(a, c.token, c, d.qd, function(a, b) { + a ? T(e, a) : T(e, null, b) + }) : T(e, b || Rg("UNKNOWN_ERROR")) + }) + } + + function ih(a, b, c, d, e) { + b = Na(b, function(a) { + return "function" === typeof a.isAvailable && a.isAvailable() + }); + 0 === b.length ? setTimeout(function() { + T(e, Rg("TRANSPORT_UNAVAILABLE")) + }, 0) : (b = new(b.shift())(d.he), d = Gb(d.fb), d.v = "js-" + Eb, d.transport = b.Fc(), d.suppress_status_codes = !0, a = Lg() + "/" + a.G.lc + c, b.open(a, d, function(a, b) { + if (a) T(e, a); + else if (b && b.error) { + var c = Error(b.error.message); + c.code = b.error.code; + c.details = b.error.details; + T(e, c) + } else T(e, null, b) + })) + } + + function $g(a, b) { + var c = null !== a.qb || null !== b; + a.qb = b; + c && a.ie("auth_status", b); + a.Pe(null !== b) + } + h.Ee = function(a) { + O("auth_status" === a, 'initial event must be of type "auth_status"'); + return this.We ? null : [this.qb] + }; + + function fh(a) { + var b = a.G; + if ("firebaseio.com" !== b.domain && "firebaseio-demo.com" !== b.domain && "auth.firebase.com" === xg) throw Error("This custom Firebase server ('" + a.G.domain + "') does not support delegated login."); + }; + var gd = "websocket", + hd = "long_polling"; + + function jh(a) { + this.nc = a; + this.Qd = []; + this.Wb = 0; + this.te = -1; + this.Jb = null + } + + function kh(a, b, c) { + a.te = b; + a.Jb = c; + a.te < a.Wb && (a.Jb(), a.Jb = null) + } + + function lh(a, b, c) { + for (a.Qd[b] = c; a.Qd[a.Wb];) { + var d = a.Qd[a.Wb]; + delete a.Qd[a.Wb]; + for (var e = 0; e < d.length; ++e) + if (d[e]) { + var f = a; + gc(function() { + f.nc(d[e]) + }) + } + if (a.Wb === a.te) { + a.Jb && (clearTimeout(a.Jb), a.Jb(), a.Jb = null); + break + } + a.Wb++ + } + }; + + function mh(a, b, c, d) { + this.ue = a; + this.f = pd(a); + this.rb = this.sb = 0; + this.Xa = uc(b); + this.Xf = c; + this.Kc = !1; + this.Fb = d; + this.ld = function(a) { + return fd(b, hd, a) + } + } + var nh, oh; + mh.prototype.open = function(a, b) { + this.mf = 0; + this.na = b; + this.Ef = new jh(a); + this.Db = !1; + var c = this; + this.ub = setTimeout(function() { + c.f("Timed out trying to connect."); + c.bb(); + c.ub = null + }, Math.floor(3E4)); + ud(function() { + if (!c.Db) { + c.Wa = new ph(function(a, b, d, k, m) { + qh(c, arguments); + if (c.Wa) + if (c.ub && (clearTimeout(c.ub), c.ub = null), c.Kc = !0, "start" == a) c.id = b, c.Mf = d; + else if ("close" === a) b ? (c.Wa.$d = !1, kh(c.Ef, b, function() { + c.bb() + })) : c.bb(); + else throw Error("Unrecognized command received: " + a); + }, function(a, b) { + qh(c, arguments); + lh(c.Ef, a, b) + }, function() { + c.bb() + }, c.ld); + var a = { + start: "t" + }; + a.ser = Math.floor(1E8 * Math.random()); + c.Wa.ke && (a.cb = c.Wa.ke); + a.v = "5"; + c.Xf && (a.s = c.Xf); + c.Fb && (a.ls = c.Fb); + "undefined" !== typeof location && location.href && -1 !== location.href.indexOf("firebaseio.com") && (a.r = "f"); + a = c.ld(a); + c.f("Connecting via long-poll to " + a); + rh(c.Wa, a, function() {}) + } + }) + }; + mh.prototype.start = function() { + var a = this.Wa, + b = this.Mf; + a.Fg = this.id; + a.Gg = b; + for (a.oe = !0; sh(a);); + a = this.id; + b = this.Mf; + this.kc = document.createElement("iframe"); + var c = { + dframe: "t" + }; + c.id = a; + c.pw = b; + this.kc.src = this.ld(c); + this.kc.style.display = "none"; + document.body.appendChild(this.kc) + }; + mh.isAvailable = function() { + return nh || !oh && "undefined" !== typeof document && null != document.createElement && !("object" === typeof window && window.chrome && window.chrome.extension && !/^chrome/.test(window.location.href)) && !("object" === typeof Windows && "object" === typeof Windows.ih) && !0 + }; + h = mh.prototype; + h.Hd = function() {}; + h.fd = function() { + this.Db = !0; + this.Wa && (this.Wa.close(), this.Wa = null); + this.kc && (document.body.removeChild(this.kc), this.kc = null); + this.ub && (clearTimeout(this.ub), this.ub = null) + }; + h.bb = function() { + this.Db || (this.f("Longpoll is closing itself"), this.fd(), this.na && (this.na(this.Kc), this.na = null)) + }; + h.close = function() { + this.Db || (this.f("Longpoll is being closed."), this.fd()) + }; + h.send = function(a) { + a = G(a); + this.sb += a.length; + rc(this.Xa, "bytes_sent", a.length); + a = Ob(a); + a = nb(a, !0); + a = yd(a, 1840); + for (var b = 0; b < a.length; b++) { + var c = this.Wa; + c.cd.push({ + Xg: this.mf, + fh: a.length, + of: a[b] + }); + c.oe && sh(c); + this.mf++ + } + }; + + function qh(a, b) { + var c = G(b).length; + a.rb += c; + rc(a.Xa, "bytes_received", c) + } + + function ph(a, b, c, d) { + this.ld = d; + this.lb = c; + this.Te = new ug; + this.cd = []; + this.we = Math.floor(1E8 * Math.random()); + this.$d = !0; + this.ke = id(); + window["pLPCommand" + this.ke] = a; + window["pRTLPCB" + this.ke] = b; + a = document.createElement("iframe"); + a.style.display = "none"; + if (document.body) { + document.body.appendChild(a); + try { + a.contentWindow.document || fc("No IE domain setting required") + } catch (e) { + a.src = "javascript:void((function(){document.open();document.domain='" + document.domain + "';document.close();})())" + } + } else throw "Document body has not initialized. Wait to initialize Firebase until after the document is ready."; + a.contentDocument ? a.jb = a.contentDocument : a.contentWindow ? a.jb = a.contentWindow.document : a.document && (a.jb = a.document); + this.Ga = a; + a = ""; + this.Ga.src && "javascript:" === this.Ga.src.substr(0, 11) && (a = ' + +If you are using node, you can install BigInteger with [npm](https://npmjs.org/). + + npm install big-integer + +Then you can include it in your code: + + var bigInt = require("big-integer"); + + +## Usage +### `bigInt(number, [base])` + +You can create a bigInt by calling the `bigInt` function. You can pass in + + - a string, which it will parse as an bigInt and throw an `"Invalid integer"` error if the parsing fails. + - a Javascript number, which it will parse as an bigInt and throw an `"Invalid integer"` error if the parsing fails. + - another bigInt. + - nothing, and it will return `bigInt.zero`. + + If you provide a second parameter, then it will parse `number` as a number in base `base`. Note that `base` can be any bigInt (even negative or zero). The letters "a-z" and "A-Z" will be interpreted as the numbers 10 to 35. Higher digits can be specified in angle brackets (`<` and `>`). + +Examples: + + var zero = bigInt(); + var ninetyThree = bigInt(93); + var largeNumber = bigInt("75643564363473453456342378564387956906736546456235345"); + var googol = bigInt("1e100"); + var bigNumber = bigInt(largeNumber); + + var maximumByte = bigInt("FF", 16); + var fiftyFiveGoogol = bigInt("<55>0", googol); + +Note that Javascript numbers larger than `9007199254740992` and smaller than `-9007199254740992` are not precisely represented numbers and will not produce exact results. If you are dealing with numbers outside that range, it is better to pass in strings. + +### Method Chaining + +Note that bigInt operations return bigInts, which allows you to chain methods, for example: + + var salary = bigInt(dollarsPerHour).times(hoursWorked).plus(randomBonuses) + +### Constants + +There are three named constants already stored that you do not have to construct with the `bigInt` function yourself: + + - `bigInt.one`, equivalent to `bigInt(1)` + - `bigInt.zero`, equivalent to `bigInt(0)` + - `bigInt.minusOne`, equivalent to `bigInt(-1)` + +The numbers from -999 to 999 are also already prestored and can be accessed using `bigInt[index]`, for example: + + - `bigInt[-999]`, equivalent to `bigInt(-999)` + - `bigInt[256]`, equivalent to `bigInt(256)` + +### Methods + +#### `abs()` + +Returns the absolute value of a bigInt. + + - `bigInt(-45).abs()` => `45` + - `bigInt(45).abs()` => `45` + +#### `add(number)` + +Performs addition. + + - `bigInt(5).add(7)` => `12` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Addition) + +#### `and(number)` + +Performs the bitwise AND operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement). + + - `bigInt(6).and(3)` => `2` + - `bigInt(6).and(-3)` => `4` + +#### `compare(number)` + +Performs a comparison between two numbers. If the numbers are equal, it returns `0`. If the first number is greater, it returns `1`. If the first number is lesser, it returns `-1`. + + - `bigInt(5).compare(5)` => `0` + - `bigInt(5).compare(4)` => `1` + - `bigInt(4).compare(5)` => `-1` + +#### `compareAbs(number)` + +Performs a comparison between the absolute value of two numbers. + + - `bigInt(5).compareAbs(-5)` => `0` + - `bigInt(5).compareAbs(4)` => `1` + - `bigInt(4).compareAbs(-5)` => `-1` + +#### `compareTo(number)` + +Alias for the `compare` method. + +#### `divide(number)` + +Performs integer division, disregarding the remainder. + + - `bigInt(59).divide(5)` => `11` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division) + +#### `divmod(number)` + +Performs division and returns an object with two properties: `quotient` and `remainder`. The sign of the remainder will match the sign of the dividend. + + - `bigInt(59).divmod(5)` => `{quotient: bigInt(11), remainder: bigInt(4) }` + - `bigInt(-5).divmod(2)` => `{quotient: bigInt(-2), remainder: bigInt(-1) }` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division) + +#### `eq(number)` + +Alias for the `equals` method. + +#### `equals(number)` + +Checks if two numbers are equal. + + - `bigInt(5).equals(5)` => `true` + - `bigInt(4).equals(7)` => `false` + +#### `geq(number)` + +Alias for the `greaterOrEquals` method. + + +#### `greater(number)` + +Checks if the first number is greater than the second. + + - `bigInt(5).greater(6)` => `false` + - `bigInt(5).greater(5)` => `false` + - `bigInt(5).greater(4)` => `true` + +#### `greaterOrEquals(number)` + +Checks if the first number is greater than or equal to the second. + + - `bigInt(5).greaterOrEquals(6)` => `false` + - `bigInt(5).greaterOrEquals(5)` => `true` + - `bigInt(5).greaterOrEquals(4)` => `true` + +#### `gt(number)` + +Alias for the `greater` method. + +#### `isDivisibleBy(number)` + +Returns `true` if the first number is divisible by the second number, `false` otherwise. + + - `bigInt(999).isDivisibleBy(333)` => `true` + - `bigInt(99).isDivisibleBy(5)` => `false` + +#### `isEven()` + +Returns `true` if the number is even, `false` otherwise. + + - `bigInt(6).isEven()` => `true` + - `bigInt(3).isEven()` => `false` + +#### `isNegative()` + +Returns `true` if the number is negative, `false` otherwise. +Returns `false` for `0` and `-0`. + + - `bigInt(-23).isNegative()` => `true` + - `bigInt(50).isNegative()` => `false` + +#### `isOdd()` + +Returns `true` if the number is odd, `false` otherwise. + + - `bigInt(13).isOdd()` => `true` + - `bigInt(40).isOdd()` => `false` + +#### `isPositive()` + +Return `true` if the number is positive, `false` otherwise. +Returns `false` for `0` and `-0`. + + - `bigInt(54).isPositive()` => `true` + - `bigInt(-1).isPositive()` => `false` + +#### `isPrime()` + +Returns `true` if the number is prime, `false` otherwise. + + - `bigInt(5).isPrime()` => `true` + - `bigInt(6).isPrime()` => `false` + +#### `isProbablePrime([iterations])` + +Returns `true` if the number is very likely to be positive, `false` otherwise. +Argument is optional and determines the amount of iterations of the test (default: `5`). The more iterations, the lower chance of getting a false positive. +This uses the [Fermat primality test](https://en.wikipedia.org/wiki/Fermat_primality_test). + + - `bigInt(5).isProbablePrime()` => `true` + - `bigInt(49).isProbablePrime()` => `false` + - `bigInt(1729).isProbablePrime(50)` => `false` + +Note that this function is not deterministic, since it relies on random sampling of factors, so the result for some numbers is not always the same. [Carmichael numbers](https://en.wikipedia.org/wiki/Carmichael_number) are particularly prone to give unreliable results. + +For example, `bigInt(1729).isProbablePrime()` returns `false` about 76% of the time and `true` about 24% of the time. The correct result is `false`. + +#### `isUnit()` + +Returns `true` if the number is `1` or `-1`, `false` otherwise. + + - `bigInt.one.isUnit()` => `true` + - `bigInt.minusOne.isUnit()` => `true` + - `bigInt(5).isUnit()` => `false` + +#### `isZero()` + +Return `true` if the number is `0` or `-0`, `false` otherwise. + + - `bigInt.zero.isZero()` => `true` + - `bigInt("-0").isZero()` => `true` + - `bigInt(50).isZero()` => `false` + +#### `leq(number)` + +Alias for the `lesserOrEquals` method. + +#### `lesser(number)` + +Checks if the first number is lesser than the second. + + - `bigInt(5).lesser(6)` => `true` + - `bigInt(5).lesser(5)` => `false` + - `bigInt(5).lesser(4)` => `false` + +#### `lesserOrEquals(number)` + +Checks if the first number is less than or equal to the second. + + - `bigInt(5).lesserOrEquals(6)` => `true` + - `bigInt(5).lesserOrEquals(5)` => `true` + - `bigInt(5).lesserOrEquals(4)` => `false` + +#### `lt(number)` + +Alias for the `lesser` method. + +#### `minus(number)` + +Alias for the `subtract` method. + + - `bigInt(3).minus(5)` => `-2` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Subtraction) + +#### `mod(number)` + +Performs division and returns the remainder, disregarding the quotient. The sign of the remainder will match the sign of the dividend. + + - `bigInt(59).mod(5)` => `4` + - `bigInt(-5).mod(2)` => `-1` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division) + +#### `modPow(exp, mod)` + +Takes the number to the power `exp` modulo `mod`. + + - `bigInt(10).modPow(3, 30)` => `10` + +#### `multiply(number)` + +Performs multiplication. + + - `bigInt(111).multiply(111)` => `12321` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Multiplication) + +#### `neq(number)` + +Alias for the `notEquals` method. + +#### `next()` + +Adds one to the number. + + - `bigInt(6).next()` => `7` + +#### `not()` + +Performs the bitwise NOT operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement). + + - `bigInt(10).not()` => `-11` + - `bigInt(0).not()` => `-1` + +#### `notEquals(number)` + +Checks if two numbers are not equal. + + - `bigInt(5).notEquals(5)` => `false` + - `bigInt(4).notEquals(7)` => `true` + +#### `or(number)` + +Performs the bitwise OR operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement). + + - `bigInt(13).or(10)` => `15` + - `bigInt(13).or(-8)` => `-3` + +#### `over(number)` + +Alias for the `divide` method. + + - `bigInt(59).over(5)` => `11` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division) + +#### `plus(number)` + +Alias for the `add` method. + + - `bigInt(5).plus(7)` => `12` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Addition) + +#### `pow(number)` + +Performs exponentiation. If the exponent is less than `0`, `pow` returns `0`. `bigInt.zero.pow(0)` returns `1`. + + - `bigInt(16).pow(16)` => `18446744073709551616` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Exponentiation) + +#### `prev(number)` + +Subtracts one from the number. + + - `bigInt(6).prev()` => `5` + +#### `remainder(number)` + +Alias for the `mod` method. + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Division) + +#### `shiftLeft(n)` + +Shifts the number left by `n` places in its binary representation. If a negative number is provided, it will shift right. Throws an error if `n` is outside of the range `[-9007199254740992, 9007199254740992]`. + + - `bigInt(8).shiftLeft(2)` => `32` + - `bigInt(8).shiftLeft(-2)` => `2` + +#### `shiftRight(n)` + +Shifts the number right by `n` places in its binary representation. If a negative number is provided, it will shift left. Throws an error if `n` is outside of the range `[-9007199254740992, 9007199254740992]`. + + - `bigInt(8).shiftRight(2)` => `2` + - `bigInt(8).shiftRight(-2)` => `32` + +#### `square()` + +Squares the number + + - `bigInt(3).square()` => `9` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Squaring) + +#### `subtract(number)` + +Performs subtraction. + + - `bigInt(3).subtract(5)` => `-2` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Subtraction) + +#### `times(number)` + +Alias for the `multiply` method. + + - `bigInt(111).times(111)` => `12321` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#Multiplication) + +#### `toJSNumber()` + +Converts a bigInt into a native Javascript number. Loses precision for numbers outside the range `[-9007199254740992, 9007199254740992]`. + + - `bigInt("18446744073709551616").toJSNumber()` => `18446744073709552000` + +#### `xor(number)` + +Performs the bitwise XOR operation. The operands are treated as if they were represented using [two's complement representation](http://en.wikipedia.org/wiki/Two%27s_complement). + + - `bigInt(12).xor(5)` => `9` + - `bigInt(12).xor(-5)` => `-9` + +### Static Methods + +#### `gcd(a, b)` + +Finds the greatest common denominator of `a` and `b`. + + - `bigInt.gcd(42,56)` => `14` + +#### `isInstance(x)` + +Returns `true` if `x` is a BigInteger, `false` otherwise. + + - `bigInt.isInstance(bigInt(14))` => `true` + - `bigInt.isInstance(14)` => `false` + +#### `lcm(a,b)` + +Finds the least common multiple of `a` and `b`. + + - `bigInt.lcm(21, 6)` => `42` + +#### `max(a,b)` + +Returns the largest of `a` and `b`. + + - `bigInt.max(77, 432)` => `432` + +#### `min(a,b)` + +Returns the smallest of `a` and `b`. + + - `bigInt.min(77, 432)` => `77` + +#### `randBetween(min, max)` + +Returns a random number between `min` and `max`. + + - `bigInt.randBetween("-1e100", "1e100")` => (for example) `8494907165436643479673097939554427056789510374838494147955756275846226209006506706784609314471378745` + + +### Override Methods + +#### `toString(radix = 10)` + +Converts a bigInt to a string. There is an optional radix parameter (which defaults to 10) that converts the number to the given radix. Digits in the range `10-35` will use the letters `a-z`. + + - `bigInt("1e9").toString()` => `"1000000000"` + - `bigInt("1e9").toString(16)` => `"3b9aca00"` + +**Note that arithmetical operators will trigger the `valueOf` function rather than the `toString` function.** When converting a bigInteger to a string, you should use the `toString` method or the `String` function instead of adding the empty string. + + - `bigInt("999999999999999999").toString()` => `"999999999999999999"` + - `String(bigInt("999999999999999999"))` => `"999999999999999999"` + - `bigInt("999999999999999999") + ""` => `1000000000000000000` + +Bases larger than 36 are supported. If a digit is greater than or equal to 36, it will be enclosed in angle brackets. + + - `bigInt(567890).toString(100)` => `"<56><78><90>"` + +Negative bases are also supported. + + - `bigInt(12345).toString(-10)` => `"28465"` + +Base 1 and base -1 are also supported. + + - `bigInt(-15).toString(1)` => `"-111111111111111"` + - `bigInt(-15).toString(-1)` => `"101010101010101010101010101010"` + +Base 0 is only allowed for the number zero. + + - `bigInt(0).toString(0)` => `0` + - `bigInt(1).toString(0)` => `Error: Cannot convert nonzero numbers to base 0.` + +[View benchmarks for this method](http://peterolson.github.io/BigInteger.js/benchmark/#toString) + +#### `valueOf()` + +Converts a bigInt to a native Javascript number. This override allows you to use native arithmetic operators without explicit conversion: + + - `bigInt("100") + bigInt("200") === 300; //true` + +## Contributors + +To contribute, just fork the project, make some changes, and submit a pull request. Please verify that the unit tests pass before submitting. + +The unit tests are contained in the `spec/spec.js` file. You can run them locally by opening the `spec/SpecRunner.html` or file or running `npm test`. You can also [run the tests online from GitHub](http://peterolson.github.io/BigInteger.js/spec/SpecRunner.html). + +There are performance benchmarks that can be viewed from the `benchmarks/index.html` page. You can [run them online from GitHub](http://peterolson.github.io/BigInteger.js/benchmark/). + +## License + +This project is public domain. For more details, read about the [Unlicense](http://unlicense.org/). \ No newline at end of file diff --git a/platforms/android/cordova/node_modules/big-integer/package.json b/platforms/android/cordova/node_modules/big-integer/package.json new file mode 100644 index 0000000..f51a9b6 --- /dev/null +++ b/platforms/android/cordova/node_modules/big-integer/package.json @@ -0,0 +1,100 @@ +{ + "_args": [ + [ + "big-integer@^1.6.7", + "/Users/steveng/repo/cordova/cordova-android/node_modules/bplist-parser" + ] + ], + "_from": "big-integer@>=1.6.7 <2.0.0", + "_id": "big-integer@1.6.12", + "_inCache": true, + "_installable": true, + "_location": "/big-integer", + "_nodeVersion": "0.12.3", + "_npmOperationalInternal": { + "host": "packages-6-west.internal.npmjs.com", + "tmp": "tmp/big-integer-1.6.12.tgz_1455702804335_0.11810904298909009" + }, + "_npmUser": { + "email": "peter.e.c.olson+npm@gmail.com", + "name": "peterolson" + }, + "_npmVersion": "2.9.1", + "_phantomChildren": {}, + "_requested": { + "name": "big-integer", + "raw": "big-integer@^1.6.7", + "rawSpec": "^1.6.7", + "scope": null, + "spec": ">=1.6.7 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/bplist-parser" + ], + "_resolved": "http://registry.npmjs.org/big-integer/-/big-integer-1.6.12.tgz", + "_shasum": "39afcddafcd5c4480864efb757337d508938bb26", + "_shrinkwrap": null, + "_spec": "big-integer@^1.6.7", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/bplist-parser", + "author": { + "email": "peter.e.c.olson+npm@gmail.com", + "name": "Peter Olson" + }, + "bin": {}, + "bugs": { + "url": "https://github.com/peterolson/BigInteger.js/issues" + }, + "contributors": [], + "dependencies": {}, + "description": "An arbitrary length integer library for Javascript", + "devDependencies": { + "coveralls": "^2.11.4", + "jasmine": "2.1.x", + "jasmine-core": "^2.3.4", + "karma": "^0.13.3", + "karma-coverage": "^0.4.2", + "karma-jasmine": "^0.3.6", + "karma-phantomjs-launcher": "~0.1" + }, + "directories": {}, + "dist": { + "shasum": "39afcddafcd5c4480864efb757337d508938bb26", + "tarball": "http://registry.npmjs.org/big-integer/-/big-integer-1.6.12.tgz" + }, + "engines": { + "node": ">=0.6" + }, + "gitHead": "56f449108e31542f939e701f1fe562a46e6c1fab", + "homepage": "https://github.com/peterolson/BigInteger.js#readme", + "keywords": [ + "arbitrary", + "arithmetic", + "big", + "bigint", + "biginteger", + "bignum", + "integer", + "math", + "precision" + ], + "license": "Unlicense", + "main": "./BigInteger", + "maintainers": [ + { + "name": "peterolson", + "email": "peter.e.c.olson+npm@gmail.com" + } + ], + "name": "big-integer", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/peterolson/BigInteger.js.git" + }, + "scripts": { + "test": "karma start my.conf.js" + }, + "version": "1.6.12" +} diff --git a/platforms/android/cordova/node_modules/bplist-parser/.npmignore b/platforms/android/cordova/node_modules/bplist-parser/.npmignore new file mode 100644 index 0000000..a9b46ea --- /dev/null +++ b/platforms/android/cordova/node_modules/bplist-parser/.npmignore @@ -0,0 +1,8 @@ +/build/* +node_modules +*.node +*.sh +*.swp +.lock* +npm-debug.log +.idea diff --git a/platforms/android/cordova/node_modules/bplist-parser/README.md b/platforms/android/cordova/node_modules/bplist-parser/README.md new file mode 100644 index 0000000..37e5e1c --- /dev/null +++ b/platforms/android/cordova/node_modules/bplist-parser/README.md @@ -0,0 +1,47 @@ +bplist-parser +============= + +Binary Mac OS X Plist (property list) parser. + +## Installation + +```bash +$ npm install bplist-parser +``` + +## Quick Examples + +```javascript +var bplist = require('bplist-parser'); + +bplist.parseFile('myPlist.bplist', function(err, obj) { + if (err) throw err; + + console.log(JSON.stringify(obj)); +}); +``` + +## License + +(The MIT License) + +Copyright (c) 2012 Near Infinity Corporation + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/cordova/node_modules/bplist-parser/bplistParser.js b/platforms/android/cordova/node_modules/bplist-parser/bplistParser.js new file mode 100644 index 0000000..f8335bc --- /dev/null +++ b/platforms/android/cordova/node_modules/bplist-parser/bplistParser.js @@ -0,0 +1,357 @@ +'use strict'; + +// adapted from http://code.google.com/p/plist/source/browse/trunk/src/com/dd/plist/BinaryPropertyListParser.java + +var fs = require('fs'); +var bigInt = require("big-integer"); +var debug = false; + +exports.maxObjectSize = 100 * 1000 * 1000; // 100Meg +exports.maxObjectCount = 32768; + +// EPOCH = new SimpleDateFormat("yyyy MM dd zzz").parse("2001 01 01 GMT").getTime(); +// ...but that's annoying in a static initializer because it can throw exceptions, ick. +// So we just hardcode the correct value. +var EPOCH = 978307200000; + +// UID object definition +var UID = exports.UID = function(id) { + this.UID = id; +} + +var parseFile = exports.parseFile = function (fileNameOrBuffer, callback) { + function tryParseBuffer(buffer) { + var err = null; + var result; + try { + result = parseBuffer(buffer); + } catch (ex) { + err = ex; + } + callback(err, result); + } + + if (Buffer.isBuffer(fileNameOrBuffer)) { + return tryParseBuffer(fileNameOrBuffer); + } else { + fs.readFile(fileNameOrBuffer, function (err, data) { + if (err) { return callback(err); } + tryParseBuffer(data); + }); + } +}; + +var parseBuffer = exports.parseBuffer = function (buffer) { + var result = {}; + + // check header + var header = buffer.slice(0, 'bplist'.length).toString('utf8'); + if (header !== 'bplist') { + throw new Error("Invalid binary plist. Expected 'bplist' at offset 0."); + } + + // Handle trailer, last 32 bytes of the file + var trailer = buffer.slice(buffer.length - 32, buffer.length); + // 6 null bytes (index 0 to 5) + var offsetSize = trailer.readUInt8(6); + if (debug) { + console.log("offsetSize: " + offsetSize); + } + var objectRefSize = trailer.readUInt8(7); + if (debug) { + console.log("objectRefSize: " + objectRefSize); + } + var numObjects = readUInt64BE(trailer, 8); + if (debug) { + console.log("numObjects: " + numObjects); + } + var topObject = readUInt64BE(trailer, 16); + if (debug) { + console.log("topObject: " + topObject); + } + var offsetTableOffset = readUInt64BE(trailer, 24); + if (debug) { + console.log("offsetTableOffset: " + offsetTableOffset); + } + + if (numObjects > exports.maxObjectCount) { + throw new Error("maxObjectCount exceeded"); + } + + // Handle offset table + var offsetTable = []; + + for (var i = 0; i < numObjects; i++) { + var offsetBytes = buffer.slice(offsetTableOffset + i * offsetSize, offsetTableOffset + (i + 1) * offsetSize); + offsetTable[i] = readUInt(offsetBytes, 0); + if (debug) { + console.log("Offset for Object #" + i + " is " + offsetTable[i] + " [" + offsetTable[i].toString(16) + "]"); + } + } + + // Parses an object inside the currently parsed binary property list. + // For the format specification check + // + // Apple's binary property list parser implementation. + function parseObject(tableOffset) { + var offset = offsetTable[tableOffset]; + var type = buffer[offset]; + var objType = (type & 0xF0) >> 4; //First 4 bits + var objInfo = (type & 0x0F); //Second 4 bits + switch (objType) { + case 0x0: + return parseSimple(); + case 0x1: + return parseInteger(); + case 0x8: + return parseUID(); + case 0x2: + return parseReal(); + case 0x3: + return parseDate(); + case 0x4: + return parseData(); + case 0x5: // ASCII + return parsePlistString(); + case 0x6: // UTF-16 + return parsePlistString(true); + case 0xA: + return parseArray(); + case 0xD: + return parseDictionary(); + default: + throw new Error("Unhandled type 0x" + objType.toString(16)); + } + + function parseSimple() { + //Simple + switch (objInfo) { + case 0x0: // null + return null; + case 0x8: // false + return false; + case 0x9: // true + return true; + case 0xF: // filler byte + return null; + default: + throw new Error("Unhandled simple type 0x" + objType.toString(16)); + } + } + + function bufferToHexString(buffer) { + var str = ''; + var i; + for (i = 0; i < buffer.length; i++) { + if (buffer[i] != 0x00) { + break; + } + } + for (; i < buffer.length; i++) { + var part = '00' + buffer[i].toString(16); + str += part.substr(part.length - 2); + } + return str; + } + + function parseInteger() { + var length = Math.pow(2, objInfo); + if (length > 4) { + var data = buffer.slice(offset + 1, offset + 1 + length); + var str = bufferToHexString(data); + return bigInt(str, 16); + } if (length < exports.maxObjectSize) { + return readUInt(buffer.slice(offset + 1, offset + 1 + length)); + } else { + throw new Error("To little heap space available! Wanted to read " + length + " bytes, but only " + exports.maxObjectSize + " are available."); + } + } + + function parseUID() { + var length = objInfo + 1; + if (length < exports.maxObjectSize) { + return new UID(readUInt(buffer.slice(offset + 1, offset + 1 + length))); + } else { + throw new Error("To little heap space available! Wanted to read " + length + " bytes, but only " + exports.maxObjectSize + " are available."); + } + } + + function parseReal() { + var length = Math.pow(2, objInfo); + if (length < exports.maxObjectSize) { + var realBuffer = buffer.slice(offset + 1, offset + 1 + length); + if (length === 4) { + return realBuffer.readFloatBE(0); + } + else if (length === 8) { + return realBuffer.readDoubleBE(0); + } + } else { + throw new Error("To little heap space available! Wanted to read " + length + " bytes, but only " + exports.maxObjectSize + " are available."); + } + } + + function parseDate() { + if (objInfo != 0x3) { + console.error("Unknown date type :" + objInfo + ". Parsing anyway..."); + } + var dateBuffer = buffer.slice(offset + 1, offset + 9); + return new Date(EPOCH + (1000 * dateBuffer.readDoubleBE(0))); + } + + function parseData() { + var dataoffset = 1; + var length = objInfo; + if (objInfo == 0xF) { + var int_type = buffer[offset + 1]; + var intType = (int_type & 0xF0) / 0x10; + if (intType != 0x1) { + console.error("0x4: UNEXPECTED LENGTH-INT TYPE! " + intType); + } + var intInfo = int_type & 0x0F; + var intLength = Math.pow(2, intInfo); + dataoffset = 2 + intLength; + if (intLength < 3) { + length = readUInt(buffer.slice(offset + 2, offset + 2 + intLength)); + } else { + length = readUInt(buffer.slice(offset + 2, offset + 2 + intLength)); + } + } + if (length < exports.maxObjectSize) { + return buffer.slice(offset + dataoffset, offset + dataoffset + length); + } else { + throw new Error("To little heap space available! Wanted to read " + length + " bytes, but only " + exports.maxObjectSize + " are available."); + } + } + + function parsePlistString (isUtf16) { + isUtf16 = isUtf16 || 0; + var enc = "utf8"; + var length = objInfo; + var stroffset = 1; + if (objInfo == 0xF) { + var int_type = buffer[offset + 1]; + var intType = (int_type & 0xF0) / 0x10; + if (intType != 0x1) { + console.err("UNEXPECTED LENGTH-INT TYPE! " + intType); + } + var intInfo = int_type & 0x0F; + var intLength = Math.pow(2, intInfo); + var stroffset = 2 + intLength; + if (intLength < 3) { + length = readUInt(buffer.slice(offset + 2, offset + 2 + intLength)); + } else { + length = readUInt(buffer.slice(offset + 2, offset + 2 + intLength)); + } + } + // length is String length -> to get byte length multiply by 2, as 1 character takes 2 bytes in UTF-16 + length *= (isUtf16 + 1); + if (length < exports.maxObjectSize) { + var plistString = new Buffer(buffer.slice(offset + stroffset, offset + stroffset + length)); + if (isUtf16) { + plistString = swapBytes(plistString); + enc = "ucs2"; + } + return plistString.toString(enc); + } else { + throw new Error("To little heap space available! Wanted to read " + length + " bytes, but only " + exports.maxObjectSize + " are available."); + } + } + + function parseArray() { + var length = objInfo; + var arrayoffset = 1; + if (objInfo == 0xF) { + var int_type = buffer[offset + 1]; + var intType = (int_type & 0xF0) / 0x10; + if (intType != 0x1) { + console.error("0xa: UNEXPECTED LENGTH-INT TYPE! " + intType); + } + var intInfo = int_type & 0x0F; + var intLength = Math.pow(2, intInfo); + arrayoffset = 2 + intLength; + if (intLength < 3) { + length = readUInt(buffer.slice(offset + 2, offset + 2 + intLength)); + } else { + length = readUInt(buffer.slice(offset + 2, offset + 2 + intLength)); + } + } + if (length * objectRefSize > exports.maxObjectSize) { + throw new Error("To little heap space available!"); + } + var array = []; + for (var i = 0; i < length; i++) { + var objRef = readUInt(buffer.slice(offset + arrayoffset + i * objectRefSize, offset + arrayoffset + (i + 1) * objectRefSize)); + array[i] = parseObject(objRef); + } + return array; + } + + function parseDictionary() { + var length = objInfo; + var dictoffset = 1; + if (objInfo == 0xF) { + var int_type = buffer[offset + 1]; + var intType = (int_type & 0xF0) / 0x10; + if (intType != 0x1) { + console.error("0xD: UNEXPECTED LENGTH-INT TYPE! " + intType); + } + var intInfo = int_type & 0x0F; + var intLength = Math.pow(2, intInfo); + dictoffset = 2 + intLength; + if (intLength < 3) { + length = readUInt(buffer.slice(offset + 2, offset + 2 + intLength)); + } else { + length = readUInt(buffer.slice(offset + 2, offset + 2 + intLength)); + } + } + if (length * 2 * objectRefSize > exports.maxObjectSize) { + throw new Error("To little heap space available!"); + } + if (debug) { + console.log("Parsing dictionary #" + tableOffset); + } + var dict = {}; + for (var i = 0; i < length; i++) { + var keyRef = readUInt(buffer.slice(offset + dictoffset + i * objectRefSize, offset + dictoffset + (i + 1) * objectRefSize)); + var valRef = readUInt(buffer.slice(offset + dictoffset + (length * objectRefSize) + i * objectRefSize, offset + dictoffset + (length * objectRefSize) + (i + 1) * objectRefSize)); + var key = parseObject(keyRef); + var val = parseObject(valRef); + if (debug) { + console.log(" DICT #" + tableOffset + ": Mapped " + key + " to " + val); + } + dict[key] = val; + } + return dict; + } + } + + return [ parseObject(topObject) ]; +}; + +function readUInt(buffer, start) { + start = start || 0; + + var l = 0; + for (var i = start; i < buffer.length; i++) { + l <<= 8; + l |= buffer[i] & 0xFF; + } + return l; +} + +// we're just going to toss the high order bits because javascript doesn't have 64-bit ints +function readUInt64BE(buffer, start) { + var data = buffer.slice(start, start + 8); + return data.readUInt32BE(4, 8); +} + +function swapBytes(buffer) { + var len = buffer.length; + for (var i = 0; i < len; i += 2) { + var a = buffer[i]; + buffer[i] = buffer[i+1]; + buffer[i+1] = a; + } + return buffer; +} diff --git a/platforms/android/cordova/node_modules/bplist-parser/package.json b/platforms/android/cordova/node_modules/bplist-parser/package.json new file mode 100644 index 0000000..899b577 --- /dev/null +++ b/platforms/android/cordova/node_modules/bplist-parser/package.json @@ -0,0 +1,81 @@ +{ + "_args": [ + [ + "bplist-parser@^0.1.0", + "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common" + ] + ], + "_from": "bplist-parser@>=0.1.0 <0.2.0", + "_id": "bplist-parser@0.1.1", + "_inCache": true, + "_installable": true, + "_location": "/bplist-parser", + "_nodeVersion": "5.1.0", + "_npmUser": { + "email": "joe@fernsroth.com", + "name": "joeferner" + }, + "_npmVersion": "3.4.0", + "_phantomChildren": {}, + "_requested": { + "name": "bplist-parser", + "raw": "bplist-parser@^0.1.0", + "rawSpec": "^0.1.0", + "scope": null, + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/cordova-common" + ], + "_resolved": "http://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz", + "_shasum": "d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6", + "_shrinkwrap": null, + "_spec": "bplist-parser@^0.1.0", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common", + "author": { + "email": "joe.ferner@nearinfinity.com", + "name": "Joe Ferner" + }, + "bugs": { + "url": "https://github.com/nearinfinity/node-bplist-parser/issues" + }, + "dependencies": { + "big-integer": "^1.6.7" + }, + "description": "Binary plist parser.", + "devDependencies": { + "nodeunit": "~0.9.1" + }, + "directories": {}, + "dist": { + "shasum": "d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6", + "tarball": "http://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz" + }, + "gitHead": "c4f22650de2cc95edd21a6e609ff0654a2b951bd", + "homepage": "https://github.com/nearinfinity/node-bplist-parser#readme", + "keywords": [ + "bplist", + "parser", + "plist" + ], + "license": "MIT", + "main": "bplistParser.js", + "maintainers": [ + { + "name": "joeferner", + "email": "joe@fernsroth.com" + } + ], + "name": "bplist-parser", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/nearinfinity/node-bplist-parser.git" + }, + "scripts": { + "test": "./node_modules/nodeunit/bin/nodeunit test" + }, + "version": "0.1.1" +} diff --git a/platforms/android/cordova/node_modules/bplist-parser/test/airplay.bplist b/platforms/android/cordova/node_modules/bplist-parser/test/airplay.bplist new file mode 100644 index 0000000..931adea Binary files /dev/null and b/platforms/android/cordova/node_modules/bplist-parser/test/airplay.bplist differ diff --git a/platforms/android/cordova/node_modules/bplist-parser/test/iTunes-small.bplist b/platforms/android/cordova/node_modules/bplist-parser/test/iTunes-small.bplist new file mode 100644 index 0000000..b7edb14 Binary files /dev/null and b/platforms/android/cordova/node_modules/bplist-parser/test/iTunes-small.bplist differ diff --git a/platforms/android/cordova/node_modules/bplist-parser/test/int64.bplist b/platforms/android/cordova/node_modules/bplist-parser/test/int64.bplist new file mode 100644 index 0000000..6da9c04 Binary files /dev/null and b/platforms/android/cordova/node_modules/bplist-parser/test/int64.bplist differ diff --git a/platforms/android/cordova/node_modules/bplist-parser/test/int64.xml b/platforms/android/cordova/node_modules/bplist-parser/test/int64.xml new file mode 100644 index 0000000..cc6cb03 --- /dev/null +++ b/platforms/android/cordova/node_modules/bplist-parser/test/int64.xml @@ -0,0 +1,10 @@ + + + + + zero + 0 + int64item + 12345678901234567890 + + diff --git a/platforms/android/cordova/node_modules/bplist-parser/test/parseTest.js b/platforms/android/cordova/node_modules/bplist-parser/test/parseTest.js new file mode 100644 index 0000000..67e7bfa --- /dev/null +++ b/platforms/android/cordova/node_modules/bplist-parser/test/parseTest.js @@ -0,0 +1,159 @@ +'use strict'; + +// tests are adapted from https://github.com/TooTallNate/node-plist + +var path = require('path'); +var nodeunit = require('nodeunit'); +var bplist = require('../'); + +module.exports = { + 'iTunes Small': function (test) { + var file = path.join(__dirname, "iTunes-small.bplist"); + var startTime1 = new Date(); + + bplist.parseFile(file, function (err, dicts) { + if (err) { + throw err; + } + + var endTime = new Date(); + console.log('Parsed "' + file + '" in ' + (endTime - startTime1) + 'ms'); + var dict = dicts[0]; + test.equal(dict['Application Version'], "9.0.3"); + test.equal(dict['Library Persistent ID'], "6F81D37F95101437"); + test.done(); + }); + }, + + 'sample1': function (test) { + var file = path.join(__dirname, "sample1.bplist"); + var startTime = new Date(); + + bplist.parseFile(file, function (err, dicts) { + if (err) { + throw err; + } + + var endTime = new Date(); + console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms'); + var dict = dicts[0]; + test.equal(dict['CFBundleIdentifier'], 'com.apple.dictionary.MySample'); + test.done(); + }); + }, + + 'sample2': function (test) { + var file = path.join(__dirname, "sample2.bplist"); + var startTime = new Date(); + + bplist.parseFile(file, function (err, dicts) { + if (err) { + throw err; + } + + var endTime = new Date(); + console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms'); + var dict = dicts[0]; + test.equal(dict['PopupMenu'][2]['Key'], "\n #import \n\n#import \n\nint main(int argc, char *argv[])\n{\n return macruby_main(\"rb_main.rb\", argc, argv);\n}\n"); + test.done(); + }); + }, + + 'airplay': function (test) { + var file = path.join(__dirname, "airplay.bplist"); + var startTime = new Date(); + + bplist.parseFile(file, function (err, dicts) { + if (err) { + throw err; + } + + var endTime = new Date(); + console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms'); + + var dict = dicts[0]; + test.equal(dict['duration'], 5555.0495000000001); + test.equal(dict['position'], 4.6269989039999997); + test.done(); + }); + }, + + 'utf16': function (test) { + var file = path.join(__dirname, "utf16.bplist"); + var startTime = new Date(); + + bplist.parseFile(file, function (err, dicts) { + if (err) { + throw err; + } + + var endTime = new Date(); + console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms'); + + var dict = dicts[0]; + test.equal(dict['CFBundleName'], 'sellStuff'); + test.equal(dict['CFBundleShortVersionString'], '2.6.1'); + test.equal(dict['NSHumanReadableCopyright'], '©2008-2012, sellStuff, Inc.'); + test.done(); + }); + }, + + 'utf16chinese': function (test) { + var file = path.join(__dirname, "utf16_chinese.plist"); + var startTime = new Date(); + + bplist.parseFile(file, function (err, dicts) { + if (err) { + throw err; + } + + var endTime = new Date(); + console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms'); + + var dict = dicts[0]; + test.equal(dict['CFBundleName'], '天翼阅读'); + test.equal(dict['CFBundleDisplayName'], '天翼阅读'); + test.done(); + }); + }, + + + + 'uid': function (test) { + var file = path.join(__dirname, "uid.bplist"); + var startTime = new Date(); + + bplist.parseFile(file, function (err, dicts) { + if (err) { + throw err; + } + + var endTime = new Date(); + console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms'); + + var dict = dicts[0]; + test.deepEqual(dict['$objects'][1]['NS.keys'], [{UID:2}, {UID:3}, {UID:4}]); + test.deepEqual(dict['$objects'][1]['NS.objects'], [{UID: 5}, {UID:6}, {UID:7}]); + test.deepEqual(dict['$top']['root'], {UID:1}); + test.done(); + }); + }, + + 'int64': function (test) { + var file = path.join(__dirname, "int64.bplist"); + var startTime = new Date(); + + bplist.parseFile(file, function (err, dicts) { + if (err) { + throw err; + } + + var endTime = new Date(); + console.log('Parsed "' + file + '" in ' + (endTime - startTime) + 'ms'); + var dict = dicts[0]; + test.equal(dict['zero'], '0'); + test.equal(dict['int64item'], '12345678901234567890'); + test.done(); + }); + } +}; diff --git a/platforms/android/cordova/node_modules/bplist-parser/test/sample1.bplist b/platforms/android/cordova/node_modules/bplist-parser/test/sample1.bplist new file mode 100644 index 0000000..5b808ff Binary files /dev/null and b/platforms/android/cordova/node_modules/bplist-parser/test/sample1.bplist differ diff --git a/platforms/android/cordova/node_modules/bplist-parser/test/sample2.bplist b/platforms/android/cordova/node_modules/bplist-parser/test/sample2.bplist new file mode 100644 index 0000000..fc42979 Binary files /dev/null and b/platforms/android/cordova/node_modules/bplist-parser/test/sample2.bplist differ diff --git a/platforms/android/cordova/node_modules/bplist-parser/test/uid.bplist b/platforms/android/cordova/node_modules/bplist-parser/test/uid.bplist new file mode 100644 index 0000000..59f341e Binary files /dev/null and b/platforms/android/cordova/node_modules/bplist-parser/test/uid.bplist differ diff --git a/platforms/android/cordova/node_modules/bplist-parser/test/utf16.bplist b/platforms/android/cordova/node_modules/bplist-parser/test/utf16.bplist new file mode 100644 index 0000000..ba4bcfa Binary files /dev/null and b/platforms/android/cordova/node_modules/bplist-parser/test/utf16.bplist differ diff --git a/platforms/android/cordova/node_modules/bplist-parser/test/utf16_chinese.plist b/platforms/android/cordova/node_modules/bplist-parser/test/utf16_chinese.plist new file mode 100755 index 0000000..ba1e2d7 Binary files /dev/null and b/platforms/android/cordova/node_modules/bplist-parser/test/utf16_chinese.plist differ diff --git a/platforms/android/cordova/node_modules/brace-expansion/.npmignore b/platforms/android/cordova/node_modules/brace-expansion/.npmignore new file mode 100644 index 0000000..353546a --- /dev/null +++ b/platforms/android/cordova/node_modules/brace-expansion/.npmignore @@ -0,0 +1,3 @@ +test +.gitignore +.travis.yml diff --git a/platforms/android/cordova/node_modules/brace-expansion/README.md b/platforms/android/cordova/node_modules/brace-expansion/README.md new file mode 100644 index 0000000..1793929 --- /dev/null +++ b/platforms/android/cordova/node_modules/brace-expansion/README.md @@ -0,0 +1,122 @@ +# brace-expansion + +[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), +as known from sh/bash, in JavaScript. + +[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) +[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) + +[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) + +## Example + +```js +var expand = require('brace-expansion'); + +expand('file-{a,b,c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('-v{,,}') +// => ['-v', '-v', '-v'] + +expand('file{0..2}.jpg') +// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] + +expand('file-{a..c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('file{2..0}.jpg') +// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] + +expand('file{0..4..2}.jpg') +// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] + +expand('file-{a..e..2}.jpg') +// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] + +expand('file{00..10..5}.jpg') +// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] + +expand('{{A..C},{a..c}}') +// => ['A', 'B', 'C', 'a', 'b', 'c'] + +expand('ppp{,config,oe{,conf}}') +// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] +``` + +## API + +```js +var expand = require('brace-expansion'); +``` + +### var expanded = expand(str) + +Return an array of all possible and valid expansions of `str`. If none are +found, `[str]` is returned. + +Valid expansions are: + +```js +/^(.*,)+(.+)?$/ +// {a,b,...} +``` + +A comma seperated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +A numeric sequence from `x` to `y` inclusive, with optional increment. +If `x` or `y` start with a leading `0`, all the numbers will be padded +to have equal length. Negative numbers and backwards iteration work too. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +An alphabetic sequence from `x` to `y` inclusive, with optional increment. +`x` and `y` must be exactly one character, and if given, `incr` must be a +number. + +For compatibility reasons, the string `${` is not eligible for brace expansion. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install brace-expansion +``` + +## Contributors + +- [Julian Gruber](https://github.com/juliangruber) +- [Isaac Z. Schlueter](https://github.com/isaacs) + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/platforms/android/cordova/node_modules/brace-expansion/example.js b/platforms/android/cordova/node_modules/brace-expansion/example.js new file mode 100644 index 0000000..60ecfc7 --- /dev/null +++ b/platforms/android/cordova/node_modules/brace-expansion/example.js @@ -0,0 +1,8 @@ +var expand = require('./'); + +console.log(expand('http://any.org/archive{1996..1999}/vol{1..4}/part{a,b,c}.html')); +console.log(expand('http://www.numericals.com/file{1..100..10}.txt')); +console.log(expand('http://www.letters.com/file{a..z..2}.txt')); +console.log(expand('mkdir /usr/local/src/bash/{old,new,dist,bugs}')); +console.log(expand('chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}')); + diff --git a/platforms/android/cordova/node_modules/brace-expansion/index.js b/platforms/android/cordova/node_modules/brace-expansion/index.js new file mode 100644 index 0000000..932718f --- /dev/null +++ b/platforms/android/cordova/node_modules/brace-expansion/index.js @@ -0,0 +1,191 @@ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = /^(.*,)+(.+)?$/.test(m.body); + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + diff --git a/platforms/android/cordova/node_modules/brace-expansion/package.json b/platforms/android/cordova/node_modules/brace-expansion/package.json new file mode 100644 index 0000000..d6d2f78 --- /dev/null +++ b/platforms/android/cordova/node_modules/brace-expansion/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + "brace-expansion@^1.0.0", + "/Users/steveng/repo/cordova/cordova-android/node_modules/minimatch" + ] + ], + "_from": "brace-expansion@>=1.0.0 <2.0.0", + "_id": "brace-expansion@1.1.3", + "_inCache": true, + "_installable": true, + "_location": "/brace-expansion", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-6-west.internal.npmjs.com", + "tmp": "tmp/brace-expansion-1.1.3.tgz_1455216688668_0.948847763473168" + }, + "_npmUser": { + "email": "julian@juliangruber.com", + "name": "juliangruber" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "name": "brace-expansion", + "raw": "brace-expansion@^1.0.0", + "rawSpec": "^1.0.0", + "scope": null, + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/minimatch" + ], + "_resolved": "http://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.3.tgz", + "_shasum": "46bff50115d47fc9ab89854abb87d98078a10991", + "_shrinkwrap": null, + "_spec": "brace-expansion@^1.0.0", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/minimatch", + "author": { + "email": "mail@juliangruber.com", + "name": "Julian Gruber", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/brace-expansion/issues" + }, + "dependencies": { + "balanced-match": "^0.3.0", + "concat-map": "0.0.1" + }, + "description": "Brace expansion as known from sh/bash", + "devDependencies": { + "tape": "4.4.0" + }, + "directories": {}, + "dist": { + "shasum": "46bff50115d47fc9ab89854abb87d98078a10991", + "tarball": "http://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.3.tgz" + }, + "gitHead": "f0da1bb668e655f67b6b2d660c6e1c19e2a6f231", + "homepage": "https://github.com/juliangruber/brace-expansion", + "keywords": [], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + { + "name": "isaacs", + "email": "isaacs@npmjs.com" + } + ], + "name": "brace-expansion", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + }, + "scripts": { + "gentest": "bash test/generate.sh", + "test": "tape test/*.js" + }, + "testling": { + "browsers": [ + "android-browser/4.2..latest", + "chrome/25..latest", + "chrome/canary", + "firefox/20..latest", + "firefox/nightly", + "ie/8..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "opera/12..latest", + "opera/next", + "safari/5.1..latest" + ], + "files": "test/*.js" + }, + "version": "1.1.3" +} diff --git a/platforms/android/cordova/node_modules/concat-map/.travis.yml b/platforms/android/cordova/node_modules/concat-map/.travis.yml new file mode 100644 index 0000000..f1d0f13 --- /dev/null +++ b/platforms/android/cordova/node_modules/concat-map/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.4 + - 0.6 diff --git a/platforms/android/cordova/node_modules/concat-map/LICENSE b/platforms/android/cordova/node_modules/concat-map/LICENSE new file mode 100644 index 0000000..ee27ba4 --- /dev/null +++ b/platforms/android/cordova/node_modules/concat-map/LICENSE @@ -0,0 +1,18 @@ +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/cordova/node_modules/concat-map/README.markdown b/platforms/android/cordova/node_modules/concat-map/README.markdown new file mode 100644 index 0000000..408f70a --- /dev/null +++ b/platforms/android/cordova/node_modules/concat-map/README.markdown @@ -0,0 +1,62 @@ +concat-map +========== + +Concatenative mapdashery. + +[![browser support](http://ci.testling.com/substack/node-concat-map.png)](http://ci.testling.com/substack/node-concat-map) + +[![build status](https://secure.travis-ci.org/substack/node-concat-map.png)](http://travis-ci.org/substack/node-concat-map) + +example +======= + +``` js +var concatMap = require('concat-map'); +var xs = [ 1, 2, 3, 4, 5, 6 ]; +var ys = concatMap(xs, function (x) { + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; +}); +console.dir(ys); +``` + +*** + +``` +[ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ] +``` + +methods +======= + +``` js +var concatMap = require('concat-map') +``` + +concatMap(xs, fn) +----------------- + +Return an array of concatenated elements by calling `fn(x, i)` for each element +`x` and each index `i` in the array `xs`. + +When `fn(x, i)` returns an array, its result will be concatenated with the +result array. If `fn(x, i)` returns anything else, that value will be pushed +onto the end of the result array. + +install +======= + +With [npm](http://npmjs.org) do: + +``` +npm install concat-map +``` + +license +======= + +MIT + +notes +===== + +This module was written while sitting high above the ground in a tree. diff --git a/platforms/android/cordova/node_modules/concat-map/example/map.js b/platforms/android/cordova/node_modules/concat-map/example/map.js new file mode 100644 index 0000000..3365621 --- /dev/null +++ b/platforms/android/cordova/node_modules/concat-map/example/map.js @@ -0,0 +1,6 @@ +var concatMap = require('../'); +var xs = [ 1, 2, 3, 4, 5, 6 ]; +var ys = concatMap(xs, function (x) { + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; +}); +console.dir(ys); diff --git a/platforms/android/cordova/node_modules/concat-map/index.js b/platforms/android/cordova/node_modules/concat-map/index.js new file mode 100644 index 0000000..b29a781 --- /dev/null +++ b/platforms/android/cordova/node_modules/concat-map/index.js @@ -0,0 +1,13 @@ +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; diff --git a/platforms/android/cordova/node_modules/concat-map/package.json b/platforms/android/cordova/node_modules/concat-map/package.json new file mode 100644 index 0000000..3ebe787 --- /dev/null +++ b/platforms/android/cordova/node_modules/concat-map/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + "concat-map@0.0.1", + "/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion" + ] + ], + "_from": "concat-map@0.0.1", + "_id": "concat-map@0.0.1", + "_inCache": true, + "_installable": true, + "_location": "/concat-map", + "_npmUser": { + "email": "mail@substack.net", + "name": "substack" + }, + "_npmVersion": "1.3.21", + "_phantomChildren": {}, + "_requested": { + "name": "concat-map", + "raw": "concat-map@0.0.1", + "rawSpec": "0.0.1", + "scope": null, + "spec": "0.0.1", + "type": "version" + }, + "_requiredBy": [ + "/brace-expansion" + ], + "_resolved": "http://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "_shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b", + "_shrinkwrap": null, + "_spec": "concat-map@0.0.1", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion", + "author": { + "email": "mail@substack.net", + "name": "James Halliday", + "url": "http://substack.net" + }, + "bugs": { + "url": "https://github.com/substack/node-concat-map/issues" + }, + "dependencies": {}, + "description": "concatenative mapdashery", + "devDependencies": { + "tape": "~2.4.0" + }, + "directories": { + "example": "example", + "test": "test" + }, + "dist": { + "shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b", + "tarball": "http://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + }, + "homepage": "https://github.com/substack/node-concat-map", + "keywords": [ + "concat", + "concatMap", + "functional", + "higher-order", + "map" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + } + ], + "name": "concat-map", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/substack/node-concat-map.git" + }, + "scripts": { + "test": "tape test/*.js" + }, + "testling": { + "browsers": { + "chrome": [ + 10, + 22 + ], + "ff": [ + 10, + 15, + 3.5 + ], + "ie": [ + 6, + 7, + 8, + 9 + ], + "opera": [ + 12 + ], + "safari": [ + 5.1 + ] + }, + "files": "test/*.js" + }, + "version": "0.0.1" +} diff --git a/platforms/android/cordova/node_modules/concat-map/test/map.js b/platforms/android/cordova/node_modules/concat-map/test/map.js new file mode 100644 index 0000000..fdbd702 --- /dev/null +++ b/platforms/android/cordova/node_modules/concat-map/test/map.js @@ -0,0 +1,39 @@ +var concatMap = require('../'); +var test = require('tape'); + +test('empty or not', function (t) { + var xs = [ 1, 2, 3, 4, 5, 6 ]; + var ixes = []; + var ys = concatMap(xs, function (x, ix) { + ixes.push(ix); + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; + }); + t.same(ys, [ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]); + t.same(ixes, [ 0, 1, 2, 3, 4, 5 ]); + t.end(); +}); + +test('always something', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function (x) { + return x === 'b' ? [ 'B', 'B', 'B' ] : [ x ]; + }); + t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); + t.end(); +}); + +test('scalars', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function (x) { + return x === 'b' ? [ 'B', 'B', 'B' ] : x; + }); + t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); + t.end(); +}); + +test('undefs', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function () {}); + t.same(ys, [ undefined, undefined, undefined, undefined ]); + t.end(); +}); diff --git a/platforms/android/cordova/node_modules/cordova-common/.jscs.json b/platforms/android/cordova/node_modules/cordova-common/.jscs.json new file mode 100644 index 0000000..5cc7e26 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/.jscs.json @@ -0,0 +1,24 @@ +{ + "disallowMixedSpacesAndTabs": true, + "disallowTrailingWhitespace": true, + "validateLineBreaks": "LF", + "validateIndentation": 4, + "requireLineFeedAtFileEnd": true, + + "disallowSpaceAfterPrefixUnaryOperators": true, + "disallowSpaceBeforePostfixUnaryOperators": true, + "requireSpaceAfterLineComment": true, + "requireCapitalizedConstructors": true, + + "disallowSpacesInNamedFunctionExpression": { + "beforeOpeningRoundBrace": true + }, + + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do" + ] +} diff --git a/platforms/android/cordova/node_modules/cordova-common/.jshintignore b/platforms/android/cordova/node_modules/cordova-common/.jshintignore new file mode 100644 index 0000000..d606f61 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/.jshintignore @@ -0,0 +1 @@ +spec/fixtures/* diff --git a/platforms/android/cordova/node_modules/cordova-common/.npmignore b/platforms/android/cordova/node_modules/cordova-common/.npmignore new file mode 100644 index 0000000..5d14118 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/.npmignore @@ -0,0 +1,2 @@ +spec +coverage diff --git a/platforms/android/cordova/node_modules/cordova-common/.ratignore b/platforms/android/cordova/node_modules/cordova-common/.ratignore new file mode 100644 index 0000000..26f7205 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/.ratignore @@ -0,0 +1,2 @@ +fixtures +coverage diff --git a/platforms/android/cordova/node_modules/cordova-common/README.md b/platforms/android/cordova/node_modules/cordova-common/README.md new file mode 100644 index 0000000..6454481 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/README.md @@ -0,0 +1,153 @@ + + +# cordova-common +Expoeses shared functionality used by [cordova-lib](https://github.com/apache/cordova-lib/) and Cordova platforms. +## Exposed APIs + +### `events` + +Represents special instance of NodeJS EventEmitter which is intended to be used to post events to cordova-lib and cordova-cli + +Usage: +``` +var events = require('cordova-common').events; +events.emit('warn', 'Some warning message') +``` + +There are the following events supported by cordova-cli: `verbose`, `log`, `info`, `warn`, `error`. + +### `CordovaError` + +An error class used by Cordova to throw cordova-specific errors. The CordovaError class is inherited from Error, so CordovaError instances is also valid Error instances (`instanceof` check succeeds). + +Usage: + +``` +var CordovaError = require('cordova-common').CordovaError; +throw new CordovaError('Some error message', SOME_ERR_CODE); +``` + +See [CordovaError](src/CordovaError/CordovaError.js) for supported error codes. + +### `ConfigParser` + +Exposes functionality to deal with cordova project `config.xml` files. For ConfigParser API reference check [ConfigParser Readme](src/ConfigParser/README.md). + +Usage: +``` +var ConfigParser = require('cordova-common').ConfigParser; +var appConfig = new ConfigParser('path/to/cordova-app/config.xml'); +console.log(appconfig.name() + ':' + appConfig.version()); +``` + +### `PluginInfoProvider` and `PluginInfo` + +`PluginInfo` is a wrapper for cordova plugins' `plugin.xml` files. This class may be instantiated directly or via `PluginInfoProvider`. The difference is that `PluginInfoProvider` caches `PluginInfo` instances based on plugin source directory. + +Usage: +``` +var PluginInfo: require('cordova-common').PluginInfo; +var PluginInfoProvider: require('cordova-common').PluginInfoProvider; + +// The following instances are equal +var plugin1 = new PluginInfo('path/to/plugin_directory'); +var plugin2 = new PluginInfoProvider().get('path/to/plugin_directory'); + +console.log('The plugin ' + plugin1.id + ' has version ' + plugin1.version) +``` + +### `ActionStack` + +Utility module for dealing with sequential tasks. Provides a set of tasks that are needed to be done and reverts all tasks that are already completed if one of those tasks fail to complete. Used internally by cordova-lib and platform's plugin installation routines. + +Usage: +``` +var ActionStack = require('cordova-common').ActionStack; +var stack = new ActionStack() + +var action1 = stack.createAction(task1, [], task1_reverter, []); +var action2 = stack.createAction(task2, [], task2_reverter, []); + +stack.push(action1); +stack.push(action2); + +stack.process() +.then(function() { + // all actions succeded +}) +.catch(function(error){ + // One of actions failed with error +}) +``` + +### `superspawn` + +Module for spawning child processes with some advanced logic. + +Usage: +``` +var superspawn = require('cordova-common').superspawn; +superspawn.spawn('adb', ['devices']) +.progress(function(data){ + if (data.stderr) + console.error('"adb devices" raised an error: ' + data.stderr); +}) +.then(function(devices){ + // Do something... +}) +``` + +### `xmlHelpers` + +A set of utility methods for dealing with xml files. + +Usage: +``` +var xml = require('cordova-common').xmlHelpers; + +var xmlDoc1 = xml.parseElementtreeSync('some/xml/file'); +var xmlDoc2 = xml.parseElementtreeSync('another/xml/file'); + +xml.mergeXml(doc1, doc2); // doc2 now contains all the nodes from doc1 +``` + +### Other APIs + +The APIs listed below are also exposed but are intended to be only used internally by cordova plugin installation routines. + +``` +PlatformJson +ConfigChanges +ConfigKeeper +ConfigFile +mungeUtil +``` + +## Setup +* Clone this repository onto your local machine + `git clone https://git-wip-us.apache.org/repos/asf/cordova-lib.git` +* In terminal, navigate to the inner cordova-common directory + `cd cordova-lib/cordova-common` +* Install dependencies and npm-link + `npm install && npm link` +* Navigate to cordova-lib directory and link cordova-common + `cd ../cordova-lib && npm link cordova-common && npm install` diff --git a/platforms/android/cordova/node_modules/cordova-common/RELEASENOTES.md b/platforms/android/cordova/node_modules/cordova-common/RELEASENOTES.md new file mode 100644 index 0000000..e7db69c --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/RELEASENOTES.md @@ -0,0 +1,42 @@ + +# Cordova-common Release Notes + +### 1.1.0 (Feb 16, 2016) +* CB-10482 Remove references to windows8 from cordova-lib/cli +* CB-10430 Adds forwardEvents method to easily connect two EventEmitters +* CB-10176 Adds CordovaLogger class, based on logger module from cordova-cli +* CB-10052 Expose child process' io streams via promise progress notification +* CB-10497 Prefer .bat over .cmd on windows platform +* CB-9984 Bumps plist version and fixes failing cordova-common test + +### 1.0.0 (Oct 29, 2015) + +* CB-9890 Documents cordova-common +* CB-9598 Correct cordova-lib -> cordova-common in README +* Pick ConfigParser changes from apache@0c3614e +* CB-9743 Removes system frameworks handling from ConfigChanges +* CB-9598 Cleans out code which has been moved to `cordova-common` +* Pick ConfigParser changes from apache@ddb027b +* Picking CordovaError changes from apache@a3b1fca +* CB-9598 Adds tests and fixtures based on existing cordova-lib ones +* CB-9598 Initial implementation for cordova-common + diff --git a/platforms/android/cordova/node_modules/cordova-common/cordova-common.js b/platforms/android/cordova/node_modules/cordova-common/cordova-common.js new file mode 100644 index 0000000..22e90a7 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/cordova-common.js @@ -0,0 +1,43 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +/* jshint node:true */ + +// For now expose plugman and cordova just as they were in the old repos +exports = module.exports = { + events: require('./src/events'), + superspawn: require('./src/superspawn'), + + ActionStack: require('./src/ActionStack'), + CordovaError: require('./src/CordovaError/CordovaError'), + CordovaLogger: require('./src/CordovaLogger'), + CordovaExternalToolErrorContext: require('./src/CordovaError/CordovaExternalToolErrorContext'), + PlatformJson: require('./src/PlatformJson'), + ConfigParser: require('./src/ConfigParser/ConfigParser.js'), + + PluginInfo: require('./src/PluginInfo/PluginInfo.js'), + PluginInfoProvider: require('./src/PluginInfo/PluginInfoProvider.js'), + + ConfigChanges: require('./src/ConfigChanges/ConfigChanges.js'), + ConfigKeeper: require('./src/ConfigChanges/ConfigKeeper.js'), + ConfigFile: require('./src/ConfigChanges/ConfigFile.js'), + mungeUtil: require('./src/ConfigChanges/munge-util.js'), + + xmlHelpers: require('./src/util/xml-helpers') +}; diff --git a/platforms/android/cordova/node_modules/cordova-common/package.json b/platforms/android/cordova/node_modules/cordova-common/package.json new file mode 100644 index 0000000..4bd1675 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/package.json @@ -0,0 +1,119 @@ +{ + "_args": [ + [ + "cordova-common@^1.1.0", + "/Users/steveng/repo/cordova/cordova-android" + ] + ], + "_from": "cordova-common@>=1.1.0 <2.0.0", + "_id": "cordova-common@1.1.0", + "_inCache": true, + "_installable": true, + "_location": "/cordova-common", + "_nodeVersion": "4.2.3", + "_npmOperationalInternal": { + "host": "packages-5-east.internal.npmjs.com", + "tmp": "tmp/cordova-common-1.1.0.tgz_1455781889491_0.6937742941081524" + }, + "_npmUser": { + "email": "kotikov.vladimir@gmail.com", + "name": "kotikov.vladimir" + }, + "_npmVersion": "2.14.7", + "_phantomChildren": {}, + "_requested": { + "name": "cordova-common", + "raw": "cordova-common@^1.1.0", + "rawSpec": "^1.1.0", + "scope": null, + "spec": ">=1.1.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "http://registry.npmjs.org/cordova-common/-/cordova-common-1.1.0.tgz", + "_shasum": "8682721466ee354747ec6241f34f412b7e0ef636", + "_shrinkwrap": null, + "_spec": "cordova-common@^1.1.0", + "_where": "/Users/steveng/repo/cordova/cordova-android", + "author": { + "name": "Apache Software Foundation" + }, + "bugs": { + "email": "dev@cordova.apache.org", + "url": "https://issues.apache.org/jira/browse/CB" + }, + "contributors": [], + "dependencies": { + "ansi": "^0.3.1", + "bplist-parser": "^0.1.0", + "cordova-registry-mapper": "^1.1.8", + "elementtree": "^0.1.6", + "glob": "^5.0.13", + "osenv": "^0.1.3", + "plist": "^1.2.0", + "q": "^1.4.1", + "semver": "^5.0.1", + "shelljs": "^0.5.1", + "underscore": "^1.8.3", + "unorm": "^1.3.3" + }, + "description": "Apache Cordova tools and platforms shared routines", + "devDependencies": { + "istanbul": "^0.3.17", + "jasmine-node": "^1.14.5", + "jshint": "^2.8.0" + }, + "directories": {}, + "dist": { + "shasum": "8682721466ee354747ec6241f34f412b7e0ef636", + "tarball": "http://registry.npmjs.org/cordova-common/-/cordova-common-1.1.0.tgz" + }, + "engineStrict": true, + "engines": { + "node": ">=0.9.9" + }, + "license": "Apache-2.0", + "main": "cordova-common.js", + "maintainers": [ + { + "name": "bowserj", + "email": "bowserj@apache.org" + }, + { + "name": "kotikov.vladimir", + "email": "kotikov.vladimir@gmail.com" + }, + { + "name": "purplecabbage", + "email": "purplecabbage@gmail.com" + }, + { + "name": "shazron", + "email": "shazron@gmail.com" + }, + { + "name": "stevegill", + "email": "stevengill97@gmail.com" + }, + { + "name": "timbarham", + "email": "npmjs@barhams.info" + } + ], + "name": "cordova-common", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://git-wip-us.apache.org/repos/asf/cordova-common.git" + }, + "scripts": { + "cover": "node node_modules/istanbul/lib/cli.js cover --root src --print detail node_modules/jasmine-node/bin/jasmine-node -- spec", + "jasmine": "node node_modules/jasmine-node/bin/jasmine-node --captureExceptions --color spec", + "jshint": "node node_modules/jshint/bin/jshint src && node node_modules/jshint/bin/jshint spec", + "test": "npm run jshint && npm run jasmine" + }, + "version": "1.1.0" +} diff --git a/platforms/android/cordova/node_modules/cordova-common/src/.jshintrc b/platforms/android/cordova/node_modules/cordova-common/src/.jshintrc new file mode 100644 index 0000000..89a121c --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/.jshintrc @@ -0,0 +1,10 @@ +{ + "node": true + , "bitwise": true + , "undef": true + , "trailing": true + , "quotmark": true + , "indent": 4 + , "unused": "vars" + , "latedef": "nofunc" +} diff --git a/platforms/android/cordova/node_modules/cordova-common/src/ActionStack.js b/platforms/android/cordova/node_modules/cordova-common/src/ActionStack.js new file mode 100644 index 0000000..5ef6f84 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/ActionStack.js @@ -0,0 +1,85 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +/* jshint quotmark:false */ + +var events = require('./events'), + Q = require('q'); + +function ActionStack() { + this.stack = []; + this.completed = []; +} + +ActionStack.prototype = { + createAction:function(handler, action_params, reverter, revert_params) { + return { + handler:{ + run:handler, + params:action_params + }, + reverter:{ + run:reverter, + params:revert_params + } + }; + }, + push:function(tx) { + this.stack.push(tx); + }, + // Returns a promise. + process:function(platform) { + events.emit('verbose', 'Beginning processing of action stack for ' + platform + ' project...'); + + while (this.stack.length) { + var action = this.stack.shift(); + var handler = action.handler.run; + var action_params = action.handler.params; + + try { + handler.apply(null, action_params); + } catch(e) { + events.emit('warn', 'Error during processing of action! Attempting to revert...'); + this.stack.unshift(action); + var issue = 'Uh oh!\n'; + // revert completed tasks + while(this.completed.length) { + var undo = this.completed.shift(); + var revert = undo.reverter.run; + var revert_params = undo.reverter.params; + + try { + revert.apply(null, revert_params); + } catch(err) { + events.emit('warn', 'Error during reversion of action! We probably really messed up your project now, sorry! D:'); + issue += 'A reversion action failed: ' + err.message + '\n'; + } + } + e.message = issue + e.message; + return Q.reject(e); + } + this.completed.push(action); + } + events.emit('verbose', 'Action stack processing complete.'); + + return Q(); + } +}; + +module.exports = ActionStack; diff --git a/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js b/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js new file mode 100644 index 0000000..a914fc8 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js @@ -0,0 +1,323 @@ +/* + * + * Copyright 2013 Anis Kadri + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* + * This module deals with shared configuration / dependency "stuff". That is: + * - XML configuration files such as config.xml, AndroidManifest.xml or WMAppManifest.xml. + * - plist files in iOS + * Essentially, any type of shared resources that we need to handle with awareness + * of how potentially multiple plugins depend on a single shared resource, should be + * handled in this module. + * + * The implementation uses an object as a hash table, with "leaves" of the table tracking + * reference counts. + */ + +/* jshint sub:true */ + +var fs = require('fs'), + path = require('path'), + et = require('elementtree'), + semver = require('semver'), + events = require('../events'), + ConfigKeeper = require('./ConfigKeeper'); + +var mungeutil = require('./munge-util'); + +exports.PlatformMunger = PlatformMunger; + +exports.process = function(plugins_dir, project_dir, platform, platformJson, pluginInfoProvider) { + var munger = new PlatformMunger(platform, project_dir, platformJson, pluginInfoProvider); + munger.process(plugins_dir); + munger.save_all(); +}; + +/****************************************************************************** +* PlatformMunger class +* +* Can deal with config file of a single project. +* Parsed config files are cached in a ConfigKeeper object. +******************************************************************************/ +function PlatformMunger(platform, project_dir, platformJson, pluginInfoProvider) { + this.platform = platform; + this.project_dir = project_dir; + this.config_keeper = new ConfigKeeper(project_dir); + this.platformJson = platformJson; + this.pluginInfoProvider = pluginInfoProvider; +} + +// Write out all unsaved files. +PlatformMunger.prototype.save_all = PlatformMunger_save_all; +function PlatformMunger_save_all() { + this.config_keeper.save_all(); + this.platformJson.save(); +} + +// Apply a munge object to a single config file. +// The remove parameter tells whether to add the change or remove it. +PlatformMunger.prototype.apply_file_munge = PlatformMunger_apply_file_munge; +function PlatformMunger_apply_file_munge(file, munge, remove) { + var self = this; + + for (var selector in munge.parents) { + for (var xml_child in munge.parents[selector]) { + // this xml child is new, graft it (only if config file exists) + var config_file = self.config_keeper.get(self.project_dir, self.platform, file); + if (config_file.exists) { + if (remove) config_file.prune_child(selector, munge.parents[selector][xml_child]); + else config_file.graft_child(selector, munge.parents[selector][xml_child]); + } + } + } +} + + +PlatformMunger.prototype.remove_plugin_changes = remove_plugin_changes; +function remove_plugin_changes(pluginInfo, is_top_level) { + var self = this; + var platform_config = self.platformJson.root; + var plugin_vars = is_top_level ? + platform_config.installed_plugins[pluginInfo.id] : + platform_config.dependent_plugins[pluginInfo.id]; + + // get config munge, aka how did this plugin change various config files + var config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars); + // global munge looks at all plugins' changes to config files + var global_munge = platform_config.config_munge; + var munge = mungeutil.decrement_munge(global_munge, config_munge); + + for (var file in munge.files) { + // CB-6976 Windows Universal Apps. Compatibility fix for existing plugins. + if (self.platform == 'windows' && file == 'package.appxmanifest' && + !fs.existsSync(path.join(self.project_dir, 'package.appxmanifest'))) { + // New windows template separate manifest files for Windows10, Windows8.1 and WP8.1 + var substs = ['package.phone.appxmanifest', 'package.windows.appxmanifest', 'package.windows10.appxmanifest']; + /* jshint loopfunc:true */ + substs.forEach(function(subst) { + events.emit('verbose', 'Applying munge to ' + subst); + self.apply_file_munge(subst, munge.files[file], true); + }); + /* jshint loopfunc:false */ + } + self.apply_file_munge(file, munge.files[file], /* remove = */ true); + } + + // Remove from installed_plugins + self.platformJson.removePlugin(pluginInfo.id, is_top_level); + return self; +} + + +PlatformMunger.prototype.add_plugin_changes = add_plugin_changes; +function add_plugin_changes(pluginInfo, plugin_vars, is_top_level, should_increment) { + var self = this; + var platform_config = self.platformJson.root; + + // get config munge, aka how should this plugin change various config files + var config_munge = self.generate_plugin_config_munge(pluginInfo, plugin_vars); + // global munge looks at all plugins' changes to config files + + // TODO: The should_increment param is only used by cordova-cli and is going away soon. + // If should_increment is set to false, avoid modifying the global_munge (use clone) + // and apply the entire config_munge because it's already a proper subset of the global_munge. + var munge, global_munge; + if (should_increment) { + global_munge = platform_config.config_munge; + munge = mungeutil.increment_munge(global_munge, config_munge); + } else { + global_munge = mungeutil.clone_munge(platform_config.config_munge); + munge = config_munge; + } + + for (var file in munge.files) { + // CB-6976 Windows Universal Apps. Compatibility fix for existing plugins. + if (self.platform == 'windows' && file == 'package.appxmanifest' && + !fs.existsSync(path.join(self.project_dir, 'package.appxmanifest'))) { + var substs = ['package.phone.appxmanifest', 'package.windows.appxmanifest', 'package.windows10.appxmanifest']; + /* jshint loopfunc:true */ + substs.forEach(function(subst) { + events.emit('verbose', 'Applying munge to ' + subst); + self.apply_file_munge(subst, munge.files[file]); + }); + /* jshint loopfunc:false */ + } + self.apply_file_munge(file, munge.files[file]); + } + + // Move to installed/dependent_plugins + self.platformJson.addPlugin(pluginInfo.id, plugin_vars || {}, is_top_level); + return self; +} + + +// Load the global munge from platform json and apply all of it. +// Used by cordova prepare to re-generate some config file from platform +// defaults and the global munge. +PlatformMunger.prototype.reapply_global_munge = reapply_global_munge ; +function reapply_global_munge () { + var self = this; + + var platform_config = self.platformJson.root; + var global_munge = platform_config.config_munge; + for (var file in global_munge.files) { + self.apply_file_munge(file, global_munge.files[file]); + } + + return self; +} + + +// generate_plugin_config_munge +// Generate the munge object from plugin.xml + vars +PlatformMunger.prototype.generate_plugin_config_munge = generate_plugin_config_munge; +function generate_plugin_config_munge(pluginInfo, vars) { + var self = this; + + vars = vars || {}; + var munge = { files: {} }; + var changes = pluginInfo.getConfigFiles(self.platform); + + // Demux 'package.appxmanifest' into relevant platform-specific appx manifests. + // Only spend the cycles if there are version-specific plugin settings + if (self.platform === 'windows' && + changes.some(function(change) { + return ((typeof change.versions !== 'undefined') || + (typeof change.deviceTarget !== 'undefined')); + })) + { + var manifests = { + 'windows': { + '8.1.0': 'package.windows.appxmanifest', + '10.0.0': 'package.windows10.appxmanifest' + }, + 'phone': { + '8.1.0': 'package.phone.appxmanifest', + '10.0.0': 'package.windows10.appxmanifest' + }, + 'all': { + '8.1.0': ['package.windows.appxmanifest', 'package.phone.appxmanifest'], + '10.0.0': 'package.windows10.appxmanifest' + } + }; + + var oldChanges = changes; + changes = []; + + oldChanges.forEach(function(change, changeIndex) { + // Only support semver/device-target demux for package.appxmanifest + // Pass through in case something downstream wants to use it + if (change.target !== 'package.appxmanifest') { + changes.push(change); + return; + } + + var hasVersion = (typeof change.versions !== 'undefined'); + var hasTargets = (typeof change.deviceTarget !== 'undefined'); + + // No semver/device-target for this config-file, pass it through + if (!(hasVersion || hasTargets)) { + changes.push(change); + return; + } + + var targetDeviceSet = hasTargets ? change.deviceTarget : 'all'; + if (['windows', 'phone', 'all'].indexOf(targetDeviceSet) === -1) { + // target-device couldn't be resolved, fix it up here to a valid value + targetDeviceSet = 'all'; + } + var knownWindowsVersionsForTargetDeviceSet = Object.keys(manifests[targetDeviceSet]); + + // at this point, 'change' targets package.appxmanifest and has a version attribute + knownWindowsVersionsForTargetDeviceSet.forEach(function(winver) { + // This is a local function that creates the new replacement representing the + // mutation. Used to save code further down. + var createReplacement = function(manifestFile, originalChange) { + var replacement = { + target: manifestFile, + parent: originalChange.parent, + after: originalChange.after, + xmls: originalChange.xmls, + versions: originalChange.versions, + deviceTarget: originalChange.deviceTarget + }; + return replacement; + }; + + // version doesn't satisfy, so skip + if (hasVersion && !semver.satisfies(winver, change.versions)) { + return; + } + + var versionSpecificManifests = manifests[targetDeviceSet][winver]; + if (versionSpecificManifests.constructor === Array) { + // e.g. all['8.1.0'] === ['pkg.windows.appxmanifest', 'pkg.phone.appxmanifest'] + versionSpecificManifests.forEach(function(manifestFile) { + changes.push(createReplacement(manifestFile, change)); + }); + } + else { + // versionSpecificManifests is actually a single string + changes.push(createReplacement(versionSpecificManifests, change)); + } + }); + }); + } + + changes.forEach(function(change) { + change.xmls.forEach(function(xml) { + // 1. stringify each xml + var stringified = (new et.ElementTree(xml)).write({xml_declaration:false}); + // interp vars + if (vars) { + Object.keys(vars).forEach(function(key) { + var regExp = new RegExp('\\$' + key, 'g'); + stringified = stringified.replace(regExp, vars[key]); + }); + } + // 2. add into munge + mungeutil.deep_add(munge, change.target, change.parent, { xml: stringified, count: 1, after: change.after }); + }); + }); + return munge; +} + +// Go over the prepare queue and apply the config munges for each plugin +// that has been (un)installed. +PlatformMunger.prototype.process = PlatformMunger_process; +function PlatformMunger_process(plugins_dir) { + var self = this; + var platform_config = self.platformJson.root; + + // Uninstallation first + platform_config.prepare_queue.uninstalled.forEach(function(u) { + var pluginInfo = self.pluginInfoProvider.get(path.join(plugins_dir, u.plugin)); + self.remove_plugin_changes(pluginInfo, u.topLevel); + }); + + // Now handle installation + platform_config.prepare_queue.installed.forEach(function(u) { + var pluginInfo = self.pluginInfoProvider.get(path.join(plugins_dir, u.plugin)); + self.add_plugin_changes(pluginInfo, u.vars, u.topLevel, true); + }); + + // Empty out installed/ uninstalled queues. + platform_config.prepare_queue.uninstalled = []; + platform_config.prepare_queue.installed = []; +} +/**** END of PlatformMunger ****/ diff --git a/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigFile.js b/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigFile.js new file mode 100644 index 0000000..dd9ebbc --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigFile.js @@ -0,0 +1,208 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +var fs = require('fs'); +var path = require('path'); + +var bplist = require('bplist-parser'); +var et = require('elementtree'); +var glob = require('glob'); +var plist = require('plist'); + +var plist_helpers = require('../util/plist-helpers'); +var xml_helpers = require('../util/xml-helpers'); + +/****************************************************************************** +* ConfigFile class +* +* Can load and keep various types of config files. Provides some functionality +* specific to some file types such as grafting XML children. In most cases it +* should be instantiated by ConfigKeeper. +* +* For plugin.xml files use as: +* plugin_config = self.config_keeper.get(plugin_dir, '', 'plugin.xml'); +* +* TODO: Consider moving it out to a separate file and maybe partially with +* overrides in platform handlers. +******************************************************************************/ +function ConfigFile(project_dir, platform, file_tag) { + this.project_dir = project_dir; + this.platform = platform; + this.file_tag = file_tag; + this.is_changed = false; + + this.load(); +} + +// ConfigFile.load() +ConfigFile.prototype.load = ConfigFile_load; +function ConfigFile_load() { + var self = this; + + // config file may be in a place not exactly specified in the target + var filepath = self.filepath = resolveConfigFilePath(self.project_dir, self.platform, self.file_tag); + + if ( !filepath || !fs.existsSync(filepath) ) { + self.exists = false; + return; + } + self.exists = true; + self.mtime = fs.statSync(self.filepath).mtime; + + var ext = path.extname(filepath); + // Windows8 uses an appxmanifest, and wp8 will likely use + // the same in a future release + if (ext == '.xml' || ext == '.appxmanifest') { + self.type = 'xml'; + self.data = xml_helpers.parseElementtreeSync(filepath); + } else { + // plist file + self.type = 'plist'; + // TODO: isBinaryPlist() reads the file and then parse re-reads it again. + // We always write out text plist, not binary. + // Do we still need to support binary plist? + // If yes, use plist.parseStringSync() and read the file once. + self.data = isBinaryPlist(filepath) ? + bplist.parseBuffer(fs.readFileSync(filepath)) : + plist.parse(fs.readFileSync(filepath, 'utf8')); + } +} + +ConfigFile.prototype.save = function ConfigFile_save() { + var self = this; + if (self.type === 'xml') { + fs.writeFileSync(self.filepath, self.data.write({indent: 4}), 'utf-8'); + } else { + // plist + var regExp = new RegExp('[ \t\r\n]+?', 'g'); + fs.writeFileSync(self.filepath, plist.build(self.data).replace(regExp, '')); + } + self.is_changed = false; +}; + +ConfigFile.prototype.graft_child = function ConfigFile_graft_child(selector, xml_child) { + var self = this; + var filepath = self.filepath; + var result; + if (self.type === 'xml') { + var xml_to_graft = [et.XML(xml_child.xml)]; + result = xml_helpers.graftXML(self.data, xml_to_graft, selector, xml_child.after); + if ( !result) { + throw new Error('grafting xml at selector "' + selector + '" from "' + filepath + '" during config install went bad :('); + } + } else { + // plist file + result = plist_helpers.graftPLIST(self.data, xml_child.xml, selector); + if ( !result ) { + throw new Error('grafting to plist "' + filepath + '" during config install went bad :('); + } + } + self.is_changed = true; +}; + +ConfigFile.prototype.prune_child = function ConfigFile_prune_child(selector, xml_child) { + var self = this; + var filepath = self.filepath; + var result; + if (self.type === 'xml') { + var xml_to_graft = [et.XML(xml_child.xml)]; + result = xml_helpers.pruneXML(self.data, xml_to_graft, selector); + } else { + // plist file + result = plist_helpers.prunePLIST(self.data, xml_child.xml, selector); + } + if (!result) { + var err_msg = 'Pruning at selector "' + selector + '" from "' + filepath + '" went bad.'; + throw new Error(err_msg); + } + self.is_changed = true; +}; + +// Some config-file target attributes are not qualified with a full leading directory, or contain wildcards. +// Resolve to a real path in this function. +// TODO: getIOSProjectname is slow because of glob, try to avoid calling it several times per project. +function resolveConfigFilePath(project_dir, platform, file) { + var filepath = path.join(project_dir, file); + var matches; + + if (file.indexOf('*') > -1) { + // handle wildcards in targets using glob. + matches = glob.sync(path.join(project_dir, '**', file)); + if (matches.length) filepath = matches[0]; + + // [CB-5989] multiple Info.plist files may exist. default to $PROJECT_NAME-Info.plist + if(matches.length > 1 && file.indexOf('-Info.plist')>-1){ + var plistName = getIOSProjectname(project_dir)+'-Info.plist'; + for (var i=0; i < matches.length; i++) { + if(matches[i].indexOf(plistName) > -1){ + filepath = matches[i]; + break; + } + } + } + return filepath; + } + + // special-case config.xml target that is just "config.xml". This should be resolved to the real location of the file. + // TODO: move the logic that contains the locations of config.xml from cordova CLI into plugman. + if (file == 'config.xml') { + if (platform == 'ubuntu') { + filepath = path.join(project_dir, 'config.xml'); + } else if (platform == 'ios') { + var iospath = getIOSProjectname(project_dir); + filepath = path.join(project_dir,iospath, 'config.xml'); + } else if (platform == 'android') { + filepath = path.join(project_dir, 'res', 'xml', 'config.xml'); + } else { + matches = glob.sync(path.join(project_dir, '**', 'config.xml')); + if (matches.length) filepath = matches[0]; + } + return filepath; + } + + // None of the special cases matched, returning project_dir/file. + return filepath; +} + +// Find out the real name of an iOS project +// TODO: glob is slow, need a better way or caching, or avoid using more than once. +function getIOSProjectname(project_dir) { + var matches = glob.sync(path.join(project_dir, '*.xcodeproj')); + var iospath; + if (matches.length === 1) { + iospath = path.basename(matches[0],'.xcodeproj'); + } else { + var msg; + if (matches.length === 0) { + msg = 'Does not appear to be an xcode project, no xcode project file in ' + project_dir; + } else { + msg = 'There are multiple *.xcodeproj dirs in ' + project_dir; + } + throw new Error(msg); + } + return iospath; +} + +// determine if a plist file is binary +function isBinaryPlist(filename) { + // I wish there was a synchronous way to read only the first 6 bytes of a + // file. This is wasteful :/ + var buf = '' + fs.readFileSync(filename, 'utf8'); + // binary plists start with a magic header, "bplist" + return buf.substring(0, 6) === 'bplist'; +} + +module.exports = ConfigFile; diff --git a/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigKeeper.js b/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigKeeper.js new file mode 100644 index 0000000..894e922 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigKeeper.js @@ -0,0 +1,65 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ +/* jshint sub:true */ + +var path = require('path'); +var ConfigFile = require('./ConfigFile'); + +/****************************************************************************** +* ConfigKeeper class +* +* Used to load and store config files to avoid re-parsing and writing them out +* multiple times. +* +* The config files are referred to by a fake path constructed as +* project_dir/platform/file +* where file is the name used for the file in config munges. +******************************************************************************/ +function ConfigKeeper(project_dir, plugins_dir) { + this.project_dir = project_dir; + this.plugins_dir = plugins_dir; + this._cached = {}; +} + +ConfigKeeper.prototype.get = function ConfigKeeper_get(project_dir, platform, file) { + var self = this; + + // This fixes a bug with older plugins - when specifying config xml instead of res/xml/config.xml + // https://issues.apache.org/jira/browse/CB-6414 + if(file == 'config.xml' && platform == 'android'){ + file = 'res/xml/config.xml'; + } + var fake_path = path.join(project_dir, platform, file); + + if (self._cached[fake_path]) { + return self._cached[fake_path]; + } + // File was not cached, need to load. + var config_file = new ConfigFile(project_dir, platform, file); + self._cached[fake_path] = config_file; + return config_file; +}; + + +ConfigKeeper.prototype.save_all = function ConfigKeeper_save_all() { + var self = this; + Object.keys(self._cached).forEach(function (fake_path) { + var config_file = self._cached[fake_path]; + if (config_file.is_changed) config_file.save(); + }); +}; + +module.exports = ConfigKeeper; diff --git a/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/munge-util.js b/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/munge-util.js new file mode 100644 index 0000000..307b3c1 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/munge-util.js @@ -0,0 +1,160 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ +/* jshint sub:true */ + +var _ = require('underscore'); + +// add the count of [key1][key2]...[keyN] to obj +// return true if it didn't exist before +exports.deep_add = function deep_add(obj, keys /* or key1, key2 .... */ ) { + if ( !Array.isArray(keys) ) { + keys = Array.prototype.slice.call(arguments, 1); + } + + return exports.process_munge(obj, true/*createParents*/, function (parentArray, k) { + var found = _.find(parentArray, function(element) { + return element.xml == k.xml; + }); + if (found) { + found.after = found.after || k.after; + found.count += k.count; + } else { + parentArray.push(k); + } + return !found; + }, keys); +}; + +// decrement the count of [key1][key2]...[keyN] from obj and remove if it reaches 0 +// return true if it was removed or not found +exports.deep_remove = function deep_remove(obj, keys /* or key1, key2 .... */ ) { + if ( !Array.isArray(keys) ) { + keys = Array.prototype.slice.call(arguments, 1); + } + + var result = exports.process_munge(obj, false/*createParents*/, function (parentArray, k) { + var index = -1; + var found = _.find(parentArray, function (element) { + index++; + return element.xml == k.xml; + }); + if (found) { + found.count -= k.count; + if (found.count > 0) { + return false; + } + else { + parentArray.splice(index, 1); + } + } + return undefined; + }, keys); + + return typeof result === 'undefined' ? true : result; +}; + +// search for [key1][key2]...[keyN] +// return the object or undefined if not found +exports.deep_find = function deep_find(obj, keys /* or key1, key2 .... */ ) { + if ( !Array.isArray(keys) ) { + keys = Array.prototype.slice.call(arguments, 1); + } + + return exports.process_munge(obj, false/*createParents?*/, function (parentArray, k) { + return _.find(parentArray, function (element) { + return element.xml == (k.xml || k); + }); + }, keys); +}; + +// Execute func passing it the parent array and the xmlChild key. +// When createParents is true, add the file and parent items they are missing +// When createParents is false, stop and return undefined if the file and/or parent items are missing + +exports.process_munge = function process_munge(obj, createParents, func, keys /* or key1, key2 .... */ ) { + if ( !Array.isArray(keys) ) { + keys = Array.prototype.slice.call(arguments, 1); + } + var k = keys[0]; + if (keys.length == 1) { + return func(obj, k); + } else if (keys.length == 2) { + if (!obj.parents[k] && !createParents) { + return undefined; + } + obj.parents[k] = obj.parents[k] || []; + return exports.process_munge(obj.parents[k], createParents, func, keys.slice(1)); + } else if (keys.length == 3){ + if (!obj.files[k] && !createParents) { + return undefined; + } + obj.files[k] = obj.files[k] || { parents: {} }; + return exports.process_munge(obj.files[k], createParents, func, keys.slice(1)); + } else { + throw new Error('Invalid key format. Must contain at most 3 elements (file, parent, xmlChild).'); + } +}; + +// All values from munge are added to base as +// base[file][selector][child] += munge[file][selector][child] +// Returns a munge object containing values that exist in munge +// but not in base. +exports.increment_munge = function increment_munge(base, munge) { + var diff = { files: {} }; + + for (var file in munge.files) { + for (var selector in munge.files[file].parents) { + for (var xml_child in munge.files[file].parents[selector]) { + var val = munge.files[file].parents[selector][xml_child]; + // if node not in base, add it to diff and base + // else increment it's value in base without adding to diff + var newlyAdded = exports.deep_add(base, [file, selector, val]); + if (newlyAdded) { + exports.deep_add(diff, file, selector, val); + } + } + } + } + return diff; +}; + +// Update the base munge object as +// base[file][selector][child] -= munge[file][selector][child] +// nodes that reached zero value are removed from base and added to the returned munge +// object. +exports.decrement_munge = function decrement_munge(base, munge) { + var zeroed = { files: {} }; + + for (var file in munge.files) { + for (var selector in munge.files[file].parents) { + for (var xml_child in munge.files[file].parents[selector]) { + var val = munge.files[file].parents[selector][xml_child]; + // if node not in base, add it to diff and base + // else increment it's value in base without adding to diff + var removed = exports.deep_remove(base, [file, selector, val]); + if (removed) { + exports.deep_add(zeroed, file, selector, val); + } + } + } + } + return zeroed; +}; + +// For better readability where used +exports.clone_munge = function clone_munge(munge) { + return exports.increment_munge({}, munge); +}; diff --git a/platforms/android/cordova/node_modules/cordova-common/src/ConfigParser/ConfigParser.js b/platforms/android/cordova/node_modules/cordova-common/src/ConfigParser/ConfigParser.js new file mode 100644 index 0000000..7abddf6 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/ConfigParser/ConfigParser.js @@ -0,0 +1,499 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +/* jshint sub:true */ + +var et = require('elementtree'), + xml= require('../util/xml-helpers'), + CordovaError = require('../CordovaError/CordovaError'), + fs = require('fs'), + events = require('../events'); + + +/** Wraps a config.xml file */ +function ConfigParser(path) { + this.path = path; + try { + this.doc = xml.parseElementtreeSync(path); + this.cdvNamespacePrefix = getCordovaNamespacePrefix(this.doc); + et.register_namespace(this.cdvNamespacePrefix, 'http://cordova.apache.org/ns/1.0'); + } catch (e) { + console.error('Parsing '+path+' failed'); + throw e; + } + var r = this.doc.getroot(); + if (r.tag !== 'widget') { + throw new CordovaError(path + ' has incorrect root node name (expected "widget", was "' + r.tag + '")'); + } +} + +function getNodeTextSafe(el) { + return el && el.text && el.text.trim(); +} + +function findOrCreate(doc, name) { + var ret = doc.find(name); + if (!ret) { + ret = new et.Element(name); + doc.getroot().append(ret); + } + return ret; +} + +function getCordovaNamespacePrefix(doc){ + var rootAtribs = Object.getOwnPropertyNames(doc.getroot().attrib); + var prefix = 'cdv'; + for (var j = 0; j < rootAtribs.length; j++ ) { + if(rootAtribs[j].indexOf('xmlns:') === 0 && + doc.getroot().attrib[rootAtribs[j]] === 'http://cordova.apache.org/ns/1.0'){ + var strings = rootAtribs[j].split(':'); + prefix = strings[1]; + break; + } + } + return prefix; +} + +/** + * Finds the value of an element's attribute + * @param {String} attributeName Name of the attribute to search for + * @param {Array} elems An array of ElementTree nodes + * @return {String} + */ +function findElementAttributeValue(attributeName, elems) { + + elems = Array.isArray(elems) ? elems : [ elems ]; + + var value = elems.filter(function (elem) { + return elem.attrib.name.toLowerCase() === attributeName.toLowerCase(); + }).map(function (filteredElems) { + return filteredElems.attrib.value; + }).pop(); + + return value ? value : ''; +} + +ConfigParser.prototype = { + packageName: function(id) { + return this.doc.getroot().attrib['id']; + }, + setPackageName: function(id) { + this.doc.getroot().attrib['id'] = id; + }, + android_packageName: function() { + return this.doc.getroot().attrib['android-packageName']; + }, + android_activityName: function() { + return this.doc.getroot().attrib['android-activityName']; + }, + ios_CFBundleIdentifier: function() { + return this.doc.getroot().attrib['ios-CFBundleIdentifier']; + }, + name: function() { + return getNodeTextSafe(this.doc.find('name')); + }, + setName: function(name) { + var el = findOrCreate(this.doc, 'name'); + el.text = name; + }, + description: function() { + return getNodeTextSafe(this.doc.find('description')); + }, + setDescription: function(text) { + var el = findOrCreate(this.doc, 'description'); + el.text = text; + }, + version: function() { + return this.doc.getroot().attrib['version']; + }, + windows_packageVersion: function() { + return this.doc.getroot().attrib('windows-packageVersion'); + }, + android_versionCode: function() { + return this.doc.getroot().attrib['android-versionCode']; + }, + ios_CFBundleVersion: function() { + return this.doc.getroot().attrib['ios-CFBundleVersion']; + }, + setVersion: function(value) { + this.doc.getroot().attrib['version'] = value; + }, + author: function() { + return getNodeTextSafe(this.doc.find('author')); + }, + getGlobalPreference: function (name) { + return findElementAttributeValue(name, this.doc.findall('preference')); + }, + setGlobalPreference: function (name, value) { + var pref = this.doc.find('preference[@name="' + name + '"]'); + if (!pref) { + pref = new et.Element('preference'); + pref.attrib.name = name; + this.doc.getroot().append(pref); + } + pref.attrib.value = value; + }, + getPlatformPreference: function (name, platform) { + return findElementAttributeValue(name, this.doc.findall('platform[@name=\'' + platform + '\']/preference')); + }, + getPreference: function(name, platform) { + + var platformPreference = ''; + + if (platform) { + platformPreference = this.getPlatformPreference(name, platform); + } + + return platformPreference ? platformPreference : this.getGlobalPreference(name); + + }, + /** + * Returns all resources for the platform specified. + * @param {String} platform The platform. + * @param {string} resourceName Type of static resources to return. + * "icon" and "splash" currently supported. + * @return {Array} Resources for the platform specified. + */ + getStaticResources: function(platform, resourceName) { + var ret = [], + staticResources = []; + if (platform) { // platform specific icons + this.doc.findall('platform[@name=\'' + platform + '\']/' + resourceName).forEach(function(elt){ + elt.platform = platform; // mark as platform specific resource + staticResources.push(elt); + }); + } + // root level resources + staticResources = staticResources.concat(this.doc.findall(resourceName)); + // parse resource elements + var that = this; + staticResources.forEach(function (elt) { + var res = {}; + res.src = elt.attrib.src; + res.density = elt.attrib['density'] || elt.attrib[that.cdvNamespacePrefix+':density'] || elt.attrib['gap:density']; + res.platform = elt.platform || null; // null means icon represents default icon (shared between platforms) + res.width = +elt.attrib.width || undefined; + res.height = +elt.attrib.height || undefined; + + // default icon + if (!res.width && !res.height && !res.density) { + ret.defaultResource = res; + } + ret.push(res); + }); + + /** + * Returns resource with specified width and/or height. + * @param {number} width Width of resource. + * @param {number} height Height of resource. + * @return {Resource} Resource object or null if not found. + */ + ret.getBySize = function(width, height) { + return ret.filter(function(res) { + if (!res.width && !res.height) { + return false; + } + return ((!res.width || (width == res.width)) && + (!res.height || (height == res.height))); + })[0] || null; + }; + + /** + * Returns resource with specified density. + * @param {string} density Density of resource. + * @return {Resource} Resource object or null if not found. + */ + ret.getByDensity = function(density) { + return ret.filter(function(res) { + return res.density == density; + })[0] || null; + }; + + /** Returns default icons */ + ret.getDefault = function() { + return ret.defaultResource; + }; + + return ret; + }, + + /** + * Returns all icons for specific platform. + * @param {string} platform Platform name + * @return {Resource[]} Array of icon objects. + */ + getIcons: function(platform) { + return this.getStaticResources(platform, 'icon'); + }, + + /** + * Returns all splash images for specific platform. + * @param {string} platform Platform name + * @return {Resource[]} Array of Splash objects. + */ + getSplashScreens: function(platform) { + return this.getStaticResources(platform, 'splash'); + }, + + /** + * Returns all hook scripts for the hook type specified. + * @param {String} hook The hook type. + * @param {Array} platforms Platforms to look for scripts into (root scripts will be included as well). + * @return {Array} Script elements. + */ + getHookScripts: function(hook, platforms) { + var self = this; + var scriptElements = self.doc.findall('./hook'); + + if(platforms) { + platforms.forEach(function (platform) { + scriptElements = scriptElements.concat(self.doc.findall('./platform[@name="' + platform + '"]/hook')); + }); + } + + function filterScriptByHookType(el) { + return el.attrib.src && el.attrib.type && el.attrib.type.toLowerCase() === hook; + } + + return scriptElements.filter(filterScriptByHookType); + }, + /** + * Returns a list of plugin (IDs). + * + * This function also returns any plugin's that + * were defined using the legacy tags. + * @return {string[]} Array of plugin IDs + */ + getPluginIdList: function () { + var plugins = this.doc.findall('plugin'); + var result = plugins.map(function(plugin){ + return plugin.attrib.name; + }); + var features = this.doc.findall('feature'); + features.forEach(function(element ){ + var idTag = element.find('./param[@name="id"]'); + if(idTag){ + result.push(idTag.attrib.value); + } + }); + return result; + }, + getPlugins: function () { + return this.getPluginIdList().map(function (pluginId) { + return this.getPlugin(pluginId); + }, this); + }, + /** + * Adds a plugin element. Does not check for duplicates. + * @name addPlugin + * @function + * @param {object} attributes name and spec are supported + * @param {Array|object} variables name, value or arbitary object + */ + addPlugin: function (attributes, variables) { + if (!attributes && !attributes.name) return; + var el = new et.Element('plugin'); + el.attrib.name = attributes.name; + if (attributes.spec) { + el.attrib.spec = attributes.spec; + } + + // support arbitrary object as variables source + if (variables && typeof variables === 'object' && !Array.isArray(variables)) { + variables = Object.keys(variables) + .map(function (variableName) { + return {name: variableName, value: variables[variableName]}; + }); + } + + if (variables) { + variables.forEach(function (variable) { + el.append(new et.Element('variable', { name: variable.name, value: variable.value })); + }); + } + this.doc.getroot().append(el); + }, + /** + * Retrives the plugin with the given id or null if not found. + * + * This function also returns any plugin's that + * were defined using the legacy tags. + * @name getPlugin + * @function + * @param {String} id + * @returns {object} plugin including any variables + */ + getPlugin: function(id){ + if(!id){ + return undefined; + } + var pluginElement = this.doc.find('./plugin/[@name="' + id + '"]'); + if (null === pluginElement) { + var legacyFeature = this.doc.find('./feature/param[@name="id"][@value="' + id + '"]/..'); + if(legacyFeature){ + events.emit('log', 'Found deprecated feature entry for ' + id +' in config.xml.'); + return featureToPlugin(legacyFeature); + } + return undefined; + } + var plugin = {}; + + plugin.name = pluginElement.attrib.name; + plugin.spec = pluginElement.attrib.spec || pluginElement.attrib.src || pluginElement.attrib.version; + plugin.variables = {}; + var variableElements = pluginElement.findall('variable'); + variableElements.forEach(function(varElement){ + var name = varElement.attrib.name; + var value = varElement.attrib.value; + if(name){ + plugin.variables[name] = value; + } + }); + return plugin; + }, + /** + * Remove the plugin entry with give name (id). + * + * This function also operates on any plugin's that + * were defined using the legacy tags. + * @name removePlugin + * @function + * @param id name of the plugin + */ + removePlugin: function(id){ + if(id){ + var plugins = this.doc.findall('./plugin/[@name="' + id + '"]') + .concat(this.doc.findall('./feature/param[@name="id"][@value="' + id + '"]/..')); + var children = this.doc.getroot().getchildren(); + plugins.forEach(function (plugin) { + var idx = children.indexOf(plugin); + if (idx > -1) { + children.splice(idx, 1); + } + }); + } + }, + + // Add any element to the root + addElement: function(name, attributes) { + var el = et.Element(name); + for (var a in attributes) { + el.attrib[a] = attributes[a]; + } + this.doc.getroot().append(el); + }, + + /** + * Adds an engine. Does not check for duplicates. + * @param {String} name the engine name + * @param {String} spec engine source location or version (optional) + */ + addEngine: function(name, spec){ + if(!name) return; + var el = et.Element('engine'); + el.attrib.name = name; + if(spec){ + el.attrib.spec = spec; + } + this.doc.getroot().append(el); + }, + /** + * Removes all the engines with given name + * @param {String} name the engine name. + */ + removeEngine: function(name){ + var engines = this.doc.findall('./engine/[@name="' +name+'"]'); + for(var i=0; i < engines.length; i++){ + var children = this.doc.getroot().getchildren(); + var idx = children.indexOf(engines[i]); + if(idx > -1){ + children.splice(idx,1); + } + } + }, + getEngines: function(){ + var engines = this.doc.findall('./engine'); + return engines.map(function(engine){ + var spec = engine.attrib.spec || engine.attrib.version; + return { + 'name': engine.attrib.name, + 'spec': spec ? spec : null + }; + }); + }, + /* Get all the access tags */ + getAccesses: function() { + var accesses = this.doc.findall('./access'); + return accesses.map(function(access){ + var minimum_tls_version = access.attrib['minimum-tls-version']; /* String */ + var requires_forward_secrecy = access.attrib['requires-forward-secrecy']; /* Boolean */ + return { + 'origin': access.attrib.origin, + 'minimum_tls_version': minimum_tls_version, + 'requires_forward_secrecy' : requires_forward_secrecy + }; + }); + }, + /* Get all the allow-navigation tags */ + getAllowNavigations: function() { + var allow_navigations = this.doc.findall('./allow-navigation'); + return allow_navigations.map(function(allow_navigation){ + var minimum_tls_version = allow_navigation.attrib['minimum-tls-version']; /* String */ + var requires_forward_secrecy = allow_navigation.attrib['requires-forward-secrecy']; /* Boolean */ + return { + 'href': allow_navigation.attrib.href, + 'minimum_tls_version': minimum_tls_version, + 'requires_forward_secrecy' : requires_forward_secrecy + }; + }); + }, + write:function() { + fs.writeFileSync(this.path, this.doc.write({indent: 4}), 'utf-8'); + } +}; + +function featureToPlugin(featureElement) { + var plugin = {}; + plugin.variables = []; + var pluginVersion, + pluginSrc; + + var nodes = featureElement.findall('param'); + nodes.forEach(function (element) { + var n = element.attrib.name; + var v = element.attrib.value; + if (n === 'id') { + plugin.name = v; + } else if (n === 'version') { + pluginVersion = v; + } else if (n === 'url' || n === 'installPath') { + pluginSrc = v; + } else { + plugin.variables[n] = v; + } + }); + + var spec = pluginSrc || pluginVersion; + if (spec) { + plugin.spec = spec; + } + + return plugin; +} +module.exports = ConfigParser; diff --git a/platforms/android/cordova/node_modules/cordova-common/src/ConfigParser/README.md b/platforms/android/cordova/node_modules/cordova-common/src/ConfigParser/README.md new file mode 100644 index 0000000..e5cd1bf --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/ConfigParser/README.md @@ -0,0 +1,86 @@ + + +# Cordova-Lib + +## ConfigParser + +wraps a valid cordova config.xml file + +### Usage + +### Include the ConfigParser module in a projet + + var ConfigParser = require('cordova-lib').configparser; + +### Create a new ConfigParser + + var config = new ConfigParser('path/to/config/xml/'); + +### Utility Functions + +#### packageName(id) +returns document root 'id' attribute value +#### Usage + + config.packageName: function(id) + +/* + * sets document root element 'id' attribute to @id + * + * @id - new id value + * + */ +#### setPackageName(id) +set document root 'id' attribute to + function(id) { + this.doc.getroot().attrib['id'] = id; + }, + +### + name: function() { + return getNodeTextSafe(this.doc.find('name')); + }, + setName: function(name) { + var el = findOrCreate(this.doc, 'name'); + el.text = name; + }, + +### read the description element + + config.description() + + var text = "New and improved description of App" + setDescription(text) + +### version management + version() + android_versionCode() + ios_CFBundleVersion() + setVersion() + +### read author element + + config.author(); + +### read preference + + config.getPreference(name); diff --git a/platforms/android/cordova/node_modules/cordova-common/src/CordovaError/CordovaError.js b/platforms/android/cordova/node_modules/cordova-common/src/CordovaError/CordovaError.js new file mode 100644 index 0000000..7262448 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/CordovaError/CordovaError.js @@ -0,0 +1,91 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +/* jshint proto:true */ + +var EOL = require('os').EOL; + +/** + * A derived exception class. See usage example in cli.js + * Based on: + * stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript/8460753#8460753 + * @param {String} message Error message + * @param {Number} [code=0] Error code + * @param {CordovaExternalToolErrorContext} [context] External tool error context object + * @constructor + */ +function CordovaError(message, code, context) { + Error.captureStackTrace(this, this.constructor); + this.name = this.constructor.name; + this.message = message; + this.code = code || CordovaError.UNKNOWN_ERROR; + this.context = context; +} +CordovaError.prototype.__proto__ = Error.prototype; + +// TODO: Extend error codes according the projects specifics +CordovaError.UNKNOWN_ERROR = 0; +CordovaError.EXTERNAL_TOOL_ERROR = 1; + +/** + * Translates instance's error code number into error code name, e.g. 0 -> UNKNOWN_ERROR + * @returns {string} Error code string name + */ +CordovaError.prototype.getErrorCodeName = function() { + for(var key in CordovaError) { + if(CordovaError.hasOwnProperty(key)) { + if(CordovaError[key] === this.code) { + return key; + } + } + } +}; + +/** + * Converts CordovaError instance to string representation + * @param {Boolean} [isVerbose] Set up verbose mode. Used to provide more + * details including information about error code name and context + * @return {String} Stringified error representation + */ +CordovaError.prototype.toString = function(isVerbose) { + var message = '', codePrefix = ''; + + if(this.code !== CordovaError.UNKNOWN_ERROR) { + codePrefix = 'code: ' + this.code + (isVerbose ? (' (' + this.getErrorCodeName() + ')') : '') + ' '; + } + + if(this.code === CordovaError.EXTERNAL_TOOL_ERROR) { + if(typeof this.context !== 'undefined') { + if(isVerbose) { + message = codePrefix + EOL + this.context.toString(isVerbose) + '\n failed with an error: ' + + this.message + EOL + 'Stack trace: ' + this.stack; + } else { + message = codePrefix + '\'' + this.context.toString(isVerbose) + '\' ' + this.message; + } + } else { + message = 'External tool failed with an error: ' + this.message; + } + } else { + message = isVerbose ? codePrefix + this.stack : codePrefix + this.message; + } + + return message; +}; + +module.exports = CordovaError; diff --git a/platforms/android/cordova/node_modules/cordova-common/src/CordovaError/CordovaExternalToolErrorContext.js b/platforms/android/cordova/node_modules/cordova-common/src/CordovaError/CordovaExternalToolErrorContext.js new file mode 100644 index 0000000..ca9a4aa --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/CordovaError/CordovaExternalToolErrorContext.js @@ -0,0 +1,48 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +/* jshint proto:true */ + +var path = require('path'); + +/** + * @param {String} cmd Command full path + * @param {String[]} args Command args + * @param {String} [cwd] Command working directory + * @constructor + */ +function CordovaExternalToolErrorContext(cmd, args, cwd) { + this.cmd = cmd; + // Helper field for readability + this.cmdShortName = path.basename(cmd); + this.args = args; + this.cwd = cwd; +} + +CordovaExternalToolErrorContext.prototype.toString = function(isVerbose) { + if(isVerbose) { + return 'External tool \'' + this.cmdShortName + '\'' + + '\nCommand full path: ' + this.cmd + '\nCommand args: ' + this.args + + (typeof this.cwd !== 'undefined' ? '\nCommand cwd: ' + this.cwd : ''); + } + + return this.cmdShortName; +}; + +module.exports = CordovaExternalToolErrorContext; diff --git a/platforms/android/cordova/node_modules/cordova-common/src/CordovaLogger.js b/platforms/android/cordova/node_modules/cordova-common/src/CordovaLogger.js new file mode 100644 index 0000000..06dbcf3 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/CordovaLogger.js @@ -0,0 +1,203 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +var ansi = require('ansi'); +var EventEmitter = require('events').EventEmitter; +var CordovaError = require('./CordovaError/CordovaError'); +var EOL = require('os').EOL; + +var INSTANCE; + +/** + * @class CordovaLogger + * + * Implements logging facility that anybody could use. Should not be + * instantiated directly, `CordovaLogger.get()` method should be used instead + * to acquire logger instance + */ +function CordovaLogger () { + this.levels = {}; + this.colors = {}; + this.stdout = process.stdout; + this.stderr = process.stderr; + + this.stdoutCursor = ansi(this.stdout); + this.stderrCursor = ansi(this.stderr); + + this.addLevel('verbose', 1000, 'grey'); + this.addLevel('normal' , 2000); + this.addLevel('warn' , 2000, 'yellow'); + this.addLevel('info' , 3000, 'blue'); + this.addLevel('error' , 5000, 'red'); + this.addLevel('results' , 10000); + + this.setLevel('normal'); +} + +/** + * Static method to create new or acquire existing instance. + * + * @return {CordovaLogger} Logger instance + */ +CordovaLogger.get = function () { + return INSTANCE || (INSTANCE = new CordovaLogger()); +}; + +CordovaLogger.VERBOSE = 'verbose'; +CordovaLogger.NORMAL = 'normal'; +CordovaLogger.WARN = 'warn'; +CordovaLogger.INFO = 'info'; +CordovaLogger.ERROR = 'error'; +CordovaLogger.RESULTS = 'results'; + +/** + * Emits log message to process' stdout/stderr depending on message's severity + * and current log level. If severity is less than current logger's level, + * then the message is ignored. + * + * @param {String} logLevel The message's log level. The logger should have + * corresponding level added (via logger.addLevel), otherwise + * `CordovaLogger.NORMAL` level will be used. + * @param {String} message The message, that should be logged to process' + * stdio + * + * @return {CordovaLogger} Current instance, to allow calls chaining. + */ +CordovaLogger.prototype.log = function (logLevel, message) { + // if there is no such logLevel defined, or provided level has + // less severity than active level, then just ignore this call and return + if (!this.levels[logLevel] || this.levels[logLevel] < this.levels[this.logLevel]) + // return instance to allow to chain calls + return this; + + var isVerbose = this.logLevel === 'verbose'; + var cursor = this.stdoutCursor; + + if(message instanceof Error || logLevel === CordovaLogger.ERROR) { + message = formatError(message, isVerbose); + cursor = this.stderrCursor; + } + + var color = this.colors[logLevel]; + if (color) { + cursor.bold().fg[color](); + } + + cursor.write(message).reset().write(EOL); + + return this; +}; + +/** + * Adds a new level to logger instance. This method also creates a shortcut + * method to log events with the level provided (i.e. after adding new level + * 'debug', the method `debug(message)`, equal to logger.log('debug', message), + * will be added to logger instance) + * + * @param {String} level A log level name. The levels with the following + * names added by default to every instance: 'verbose', 'normal', 'warn', + * 'info', 'error', 'results' + * @param {Number} severity A number that represents level's severity. + * @param {String} color A valid color name, that will be used to log + * messages with this level. Any CSS color code or RGB value is allowed + * (according to ansi documentation: + * https://github.com/TooTallNate/ansi.js#features) + * + * @return {CordovaLogger} Current instance, to allow calls chaining. + */ +CordovaLogger.prototype.addLevel = function (level, severity, color) { + + this.levels[level] = severity; + + if (color) { + this.colors[level] = color; + } + + // Define own method with corresponding name + if (!this[level]) { + this[level] = this.log.bind(this, level); + } + + return this; +}; + +/** + * Sets the current logger level to provided value. If logger doesn't have level + * with this name, `CordovaLogger.NORMAL` will be used. + * + * @param {String} logLevel Level name. The level with this name should be + * added to logger before. + * + * @return {CordovaLogger} Current instance, to allow calls chaining. + */ +CordovaLogger.prototype.setLevel = function (logLevel) { + this.logLevel = this.levels[logLevel] ? logLevel : CordovaLogger.NORMAL; + + return this; +}; + +/** + * Attaches logger to EventEmitter instance provided. + * + * @param {EventEmitter} eventEmitter An EventEmitter instance to attach + * logger to. + * + * @return {CordovaLogger} Current instance, to allow calls chaining. + */ +CordovaLogger.prototype.subscribe = function (eventEmitter) { + + if (!(eventEmitter instanceof EventEmitter)) + throw new Error('Subscribe method only accepts an EventEmitter instance as argument'); + + eventEmitter.on('verbose', this.verbose) + .on('log', this.normal) + .on('info', this.info) + .on('warn', this.warn) + .on('warning', this.warn) + // Set up event handlers for logging and results emitted as events. + .on('results', this.results); + + return this; +}; + +function formatError(error, isVerbose) { + var message = ''; + + if(error instanceof CordovaError) { + message = error.toString(isVerbose); + } else if(error instanceof Error) { + if(isVerbose) { + message = error.stack; + } else { + message = error.message; + } + } else { + // Plain text error message + message = error; + } + + if(message.toUpperCase().indexOf('ERROR:') !== 0) { + // Needed for backward compatibility with external tools + message = 'Error: ' + message; + } + + return message; +} + +module.exports = CordovaLogger; diff --git a/platforms/android/cordova/node_modules/cordova-common/src/PlatformJson.js b/platforms/android/cordova/node_modules/cordova-common/src/PlatformJson.js new file mode 100644 index 0000000..793e976 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/PlatformJson.js @@ -0,0 +1,155 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ +/* jshint sub:true */ + +var fs = require('fs'); +var path = require('path'); +var shelljs = require('shelljs'); +var mungeutil = require('./ConfigChanges/munge-util'); +var pluginMappernto = require('cordova-registry-mapper').newToOld; +var pluginMapperotn = require('cordova-registry-mapper').oldToNew; + +function PlatformJson(filePath, platform, root) { + this.filePath = filePath; + this.platform = platform; + this.root = fix_munge(root || {}); +} + +PlatformJson.load = function(plugins_dir, platform) { + var filePath = path.join(plugins_dir, platform + '.json'); + var root = null; + if (fs.existsSync(filePath)) { + root = JSON.parse(fs.readFileSync(filePath, 'utf-8')); + } + return new PlatformJson(filePath, platform, root); +}; + +PlatformJson.prototype.save = function() { + shelljs.mkdir('-p', path.dirname(this.filePath)); + fs.writeFileSync(this.filePath, JSON.stringify(this.root, null, 4), 'utf-8'); +}; + +/** + * Indicates whether the specified plugin is installed as a top-level (not as + * dependency to others) + * @method function + * @param {String} pluginId A plugin id to check for. + * @return {Boolean} true if plugin installed as top-level, otherwise false. + */ +PlatformJson.prototype.isPluginTopLevel = function(pluginId) { + var installedPlugins = this.root.installed_plugins; + return installedPlugins[pluginId] || + installedPlugins[pluginMappernto[pluginId]] || + installedPlugins[pluginMapperotn[pluginId]]; +}; + +/** + * Indicates whether the specified plugin is installed as a dependency to other + * plugin. + * @method function + * @param {String} pluginId A plugin id to check for. + * @return {Boolean} true if plugin installed as a dependency, otherwise false. + */ +PlatformJson.prototype.isPluginDependent = function(pluginId) { + var dependentPlugins = this.root.dependent_plugins; + return dependentPlugins[pluginId] || + dependentPlugins[pluginMappernto[pluginId]] || + dependentPlugins[pluginMapperotn[pluginId]]; +}; + +/** + * Indicates whether plugin is installed either as top-level or as dependency. + * @method function + * @param {String} pluginId A plugin id to check for. + * @return {Boolean} true if plugin installed, otherwise false. + */ +PlatformJson.prototype.isPluginInstalled = function(pluginId) { + return this.isPluginTopLevel(pluginId) || + this.isPluginDependent(pluginId); +}; + +PlatformJson.prototype.addPlugin = function(pluginId, variables, isTopLevel) { + var pluginsList = isTopLevel ? + this.root.installed_plugins : + this.root.dependent_plugins; + + pluginsList[pluginId] = variables; + + return this; +}; + +PlatformJson.prototype.removePlugin = function(pluginId, isTopLevel) { + var pluginsList = isTopLevel ? + this.root.installed_plugins : + this.root.dependent_plugins; + + delete pluginsList[pluginId]; + + return this; +}; + +PlatformJson.prototype.addInstalledPluginToPrepareQueue = function(pluginDirName, vars, is_top_level) { + this.root.prepare_queue.installed.push({'plugin':pluginDirName, 'vars':vars, 'topLevel':is_top_level}); +}; + +PlatformJson.prototype.addUninstalledPluginToPrepareQueue = function(pluginId, is_top_level) { + this.root.prepare_queue.uninstalled.push({'plugin':pluginId, 'id':pluginId, 'topLevel':is_top_level}); +}; + +/** + * Moves plugin, specified by id to top-level plugins. If plugin is top-level + * already, then does nothing. + * @method function + * @param {String} pluginId A plugin id to make top-level. + * @return {PlatformJson} PlatformJson instance. + */ +PlatformJson.prototype.makeTopLevel = function(pluginId) { + var plugin = this.root.dependent_plugins[pluginId]; + if (plugin) { + delete this.root.dependent_plugins[pluginId]; + this.root.installed_plugins[pluginId] = plugin; + } + return this; +}; + +// convert a munge from the old format ([file][parent][xml] = count) to the current one +function fix_munge(root) { + root.prepare_queue = root.prepare_queue || {installed:[], uninstalled:[]}; + root.config_munge = root.config_munge || {files: {}}; + root.installed_plugins = root.installed_plugins || {}; + root.dependent_plugins = root.dependent_plugins || {}; + + var munge = root.config_munge; + if (!munge.files) { + var new_munge = { files: {} }; + for (var file in munge) { + for (var selector in munge[file]) { + for (var xml_child in munge[file][selector]) { + var val = parseInt(munge[file][selector][xml_child]); + for (var i = 0; i < val; i++) { + mungeutil.deep_add(new_munge, [file, selector, { xml: xml_child, count: val }]); + } + } + } + } + root.config_munge = new_munge; + } + + return root; +} + +module.exports = PlatformJson; + diff --git a/platforms/android/cordova/node_modules/cordova-common/src/PluginInfo/PluginInfo.js b/platforms/android/cordova/node_modules/cordova-common/src/PluginInfo/PluginInfo.js new file mode 100644 index 0000000..2554a3c --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/PluginInfo/PluginInfo.js @@ -0,0 +1,410 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +/* jshint sub:true, laxcomma:true, laxbreak:true */ + +/* +A class for holidng the information currently stored in plugin.xml +It should also be able to answer questions like whether the plugin +is compatible with a given engine version. + +TODO (kamrik): refactor this to not use sync functions and return promises. +*/ + + +var path = require('path') + , fs = require('fs') + , xml_helpers = require('../util/xml-helpers') + , CordovaError = require('../CordovaError/CordovaError') + ; + +function PluginInfo(dirname) { + var self = this; + + // METHODS + // Defined inside the constructor to avoid the "this" binding problems. + + // tag + // Example: + // Used to require a variable to be specified via --variable when installing the plugin. + self.getPreferences = getPreferences; + function getPreferences(platform) { + var arprefs = _getTags(self._et, 'preference', platform, _parsePreference); + + var prefs= {}; + for(var i in arprefs) + { + var pref=arprefs[i]; + prefs[pref.preference]=pref.default; + } + // returns { key : default | null} + return prefs; + } + + function _parsePreference(prefTag) { + var name = prefTag.attrib.name.toUpperCase(); + var def = prefTag.attrib.default || null; + return {preference: name, default: def}; + } + + // + self.getAssets = getAssets; + function getAssets(platform) { + var assets = _getTags(self._et, 'asset', platform, _parseAsset); + return assets; + } + + function _parseAsset(tag) { + var src = tag.attrib.src; + var target = tag.attrib.target; + + if ( !src || !target) { + var msg = + 'Malformed tag. Both "src" and "target" attributes' + + 'must be specified in\n' + + self.filepath + ; + throw new Error(msg); + } + + var asset = { + itemType: 'asset', + src: src, + target: target + }; + return asset; + } + + + // + // Example: + // + self.getDependencies = getDependencies; + function getDependencies(platform) { + var deps = _getTags( + self._et, + 'dependency', + platform, + _parseDependency + ); + return deps; + } + + function _parseDependency(tag) { + var dep = + { id : tag.attrib.id + , url : tag.attrib.url || '' + , subdir : tag.attrib.subdir || '' + , commit : tag.attrib.commit + }; + + dep.git_ref = dep.commit; + + if ( !dep.id ) { + var msg = + ' tag is missing id attribute in ' + + self.filepath + ; + throw new CordovaError(msg); + } + return dep; + } + + + // tag + self.getConfigFiles = getConfigFiles; + function getConfigFiles(platform) { + var configFiles = _getTags(self._et, 'config-file', platform, _parseConfigFile); + return configFiles; + } + + function _parseConfigFile(tag) { + var configFile = + { target : tag.attrib['target'] + , parent : tag.attrib['parent'] + , after : tag.attrib['after'] + , xmls : tag.getchildren() + // To support demuxing via versions + , versions : tag.attrib['versions'] + , deviceTarget: tag.attrib['device-target'] + }; + return configFile; + } + + // tags, both global and within a + // TODO (kamrik): Do we ever use under ? Example wanted. + self.getInfo = getInfo; + function getInfo(platform) { + var infos = _getTags( + self._et, + 'info', + platform, + function(elem) { return elem.text; } + ); + // Filter out any undefined or empty strings. + infos = infos.filter(Boolean); + return infos; + } + + // + // Examples: + // + // + self.getSourceFiles = getSourceFiles; + function getSourceFiles(platform) { + var sourceFiles = _getTagsInPlatform(self._et, 'source-file', platform, _parseSourceFile); + return sourceFiles; + } + + function _parseSourceFile(tag) { + return { + itemType: 'source-file', + src: tag.attrib.src, + framework: isStrTrue(tag.attrib.framework), + weak: isStrTrue(tag.attrib.weak), + compilerFlags: tag.attrib['compiler-flags'], + targetDir: tag.attrib['target-dir'] + }; + } + + // + // Example: + // + self.getHeaderFiles = getHeaderFiles; + function getHeaderFiles(platform) { + var headerFiles = _getTagsInPlatform(self._et, 'header-file', platform, function(tag) { + return { + itemType: 'header-file', + src: tag.attrib.src, + targetDir: tag.attrib['target-dir'] + }; + }); + return headerFiles; + } + + // + // Example: + // + self.getResourceFiles = getResourceFiles; + function getResourceFiles(platform) { + var resourceFiles = _getTagsInPlatform(self._et, 'resource-file', platform, function(tag) { + return { + itemType: 'resource-file', + src: tag.attrib.src, + target: tag.attrib.target, + versions: tag.attrib.versions, + deviceTarget: tag.attrib['device-target'], + arch: tag.attrib.arch + }; + }); + return resourceFiles; + } + + // + // Example: + // + self.getLibFiles = getLibFiles; + function getLibFiles(platform) { + var libFiles = _getTagsInPlatform(self._et, 'lib-file', platform, function(tag) { + return { + itemType: 'lib-file', + src: tag.attrib.src, + arch: tag.attrib.arch, + Include: tag.attrib.Include, + versions: tag.attrib.versions, + deviceTarget: tag.attrib['device-target'] || tag.attrib.target + }; + }); + return libFiles; + } + + // + // Example: + // + self.getHookScripts = getHookScripts; + function getHookScripts(hook, platforms) { + var scriptElements = self._et.findall('./hook'); + + if(platforms) { + platforms.forEach(function (platform) { + scriptElements = scriptElements.concat(self._et.findall('./platform[@name="' + platform + '"]/hook')); + }); + } + + function filterScriptByHookType(el) { + return el.attrib.src && el.attrib.type && el.attrib.type.toLowerCase() === hook; + } + + return scriptElements.filter(filterScriptByHookType); + } + + self.getJsModules = getJsModules; + function getJsModules(platform) { + var modules = _getTags(self._et, 'js-module', platform, _parseJsModule); + return modules; + } + + function _parseJsModule(tag) { + var ret = { + itemType: 'js-module', + name: tag.attrib.name, + src: tag.attrib.src, + clobbers: tag.findall('clobbers').map(function(tag) { return { target: tag.attrib.target }; }), + merges: tag.findall('merges').map(function(tag) { return { target: tag.attrib.target }; }), + runs: tag.findall('runs').length > 0 + }; + + return ret; + } + + self.getEngines = function() { + return self._et.findall('engines/engine').map(function(n) { + return { + name: n.attrib.name, + version: n.attrib.version, + platform: n.attrib.platform, + scriptSrc: n.attrib.scriptSrc + }; + }); + }; + + self.getPlatforms = function() { + return self._et.findall('platform').map(function(n) { + return { name: n.attrib.name }; + }); + }; + + self.getPlatformsArray = function() { + return self._et.findall('platform').map(function(n) { + return n.attrib.name; + }); + }; + self.getFrameworks = function(platform) { + return _getTags(self._et, 'framework', platform, function(el) { + var ret = { + itemType: 'framework', + type: el.attrib.type, + parent: el.attrib.parent, + custom: isStrTrue(el.attrib.custom), + src: el.attrib.src, + weak: isStrTrue(el.attrib.weak), + versions: el.attrib.versions, + targetDir: el.attrib['target-dir'], + deviceTarget: el.attrib['device-target'] || el.attrib.target, + arch: el.attrib.arch + }; + return ret; + }); + }; + + self.getFilesAndFrameworks = getFilesAndFrameworks; + function getFilesAndFrameworks(platform) { + // Please avoid changing the order of the calls below, files will be + // installed in this order. + var items = [].concat( + self.getSourceFiles(platform), + self.getHeaderFiles(platform), + self.getResourceFiles(platform), + self.getFrameworks(platform), + self.getLibFiles(platform) + ); + return items; + } + ///// End of PluginInfo methods ///// + + + ///// PluginInfo Constructor logic ///// + self.filepath = path.join(dirname, 'plugin.xml'); + if (!fs.existsSync(self.filepath)) { + throw new CordovaError('Cannot find plugin.xml for plugin \'' + path.basename(dirname) + '\'. Please try adding it again.'); + } + + self.dir = dirname; + var et = self._et = xml_helpers.parseElementtreeSync(self.filepath); + var pelem = et.getroot(); + self.id = pelem.attrib.id; + self.version = pelem.attrib.version; + + // Optional fields + self.name = pelem.findtext('name'); + self.description = pelem.findtext('description'); + self.license = pelem.findtext('license'); + self.repo = pelem.findtext('repo'); + self.issue = pelem.findtext('issue'); + self.keywords = pelem.findtext('keywords'); + self.info = pelem.findtext('info'); + if (self.keywords) { + self.keywords = self.keywords.split(',').map( function(s) { return s.trim(); } ); + } + self.getKeywordsAndPlatforms = function () { + var ret = self.keywords || []; + return ret.concat('ecosystem:cordova').concat(addCordova(self.getPlatformsArray())); + }; +} // End of PluginInfo constructor. + +// Helper function used to prefix every element of an array with cordova- +// Useful when we want to modify platforms to be cordova-platform +function addCordova(someArray) { + var newArray = someArray.map(function(element) { + return 'cordova-' + element; + }); + return newArray; +} + +// Helper function used by most of the getSomething methods of PluginInfo. +// Get all elements of a given name. Both in root and in platform sections +// for the given platform. If transform is given and is a function, it is +// applied to each element. +function _getTags(pelem, tag, platform, transform) { + var platformTag = pelem.find('./platform[@name="' + platform + '"]'); + var tagsInRoot = pelem.findall(tag); + tagsInRoot = tagsInRoot || []; + var tagsInPlatform = platformTag ? platformTag.findall(tag) : []; + var tags = tagsInRoot.concat(tagsInPlatform); + if ( typeof transform === 'function' ) { + tags = tags.map(transform); + } + return tags; +} + +// Same as _getTags() but only looks inside a platfrom section. +function _getTagsInPlatform(pelem, tag, platform, transform) { + var platformTag = pelem.find('./platform[@name="' + platform + '"]'); + var tags = platformTag ? platformTag.findall(tag) : []; + if ( typeof transform === 'function' ) { + tags = tags.map(transform); + } + return tags; +} + +// Check if x is a string 'true'. +function isStrTrue(x) { + return String(x).toLowerCase() == 'true'; +} + +module.exports = PluginInfo; +// Backwards compat: +PluginInfo.PluginInfo = PluginInfo; +PluginInfo.loadPluginsDir = function(dir) { + var PluginInfoProvider = require('./PluginInfoProvider'); + return new PluginInfoProvider().getAllWithinSearchPath(dir); +}; diff --git a/platforms/android/cordova/node_modules/cordova-common/src/PluginInfo/PluginInfoProvider.js b/platforms/android/cordova/node_modules/cordova-common/src/PluginInfo/PluginInfoProvider.js new file mode 100644 index 0000000..6240119 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/PluginInfo/PluginInfoProvider.js @@ -0,0 +1,82 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +/* jshint sub:true, laxcomma:true, laxbreak:true */ + +var fs = require('fs'); +var path = require('path'); +var PluginInfo = require('./PluginInfo'); +var events = require('../events'); + +function PluginInfoProvider() { + this._cache = {}; + this._getAllCache = {}; +} + +PluginInfoProvider.prototype.get = function(dirName) { + var absPath = path.resolve(dirName); + if (!this._cache[absPath]) { + this._cache[absPath] = new PluginInfo(dirName); + } + return this._cache[absPath]; +}; + +// Normally you don't need to put() entries, but it's used +// when copying plugins, and in unit tests. +PluginInfoProvider.prototype.put = function(pluginInfo) { + var absPath = path.resolve(pluginInfo.dir); + this._cache[absPath] = pluginInfo; +}; + +// Used for plugin search path processing. +// Given a dir containing multiple plugins, create a PluginInfo object for +// each of them and return as array. +// Should load them all in parallel and return a promise, but not yet. +PluginInfoProvider.prototype.getAllWithinSearchPath = function(dirName) { + var absPath = path.resolve(dirName); + if (!this._getAllCache[absPath]) { + this._getAllCache[absPath] = getAllHelper(absPath, this); + } + return this._getAllCache[absPath]; +}; + +function getAllHelper(absPath, provider) { + if (!fs.existsSync(absPath)){ + return []; + } + // If dir itself is a plugin, return it in an array with one element. + if (fs.existsSync(path.join(absPath, 'plugin.xml'))) { + return [provider.get(absPath)]; + } + var subdirs = fs.readdirSync(absPath); + var plugins = []; + subdirs.forEach(function(subdir) { + var d = path.join(absPath, subdir); + if (fs.existsSync(path.join(d, 'plugin.xml'))) { + try { + plugins.push(provider.get(d)); + } catch (e) { + events.emit('warn', 'Error parsing ' + path.join(d, 'plugin.xml.\n' + e.stack)); + } + } + }); + return plugins; +} + +module.exports = PluginInfoProvider; diff --git a/platforms/android/cordova/node_modules/cordova-common/src/events.js b/platforms/android/cordova/node_modules/cordova-common/src/events.js new file mode 100644 index 0000000..868d363 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/events.js @@ -0,0 +1,65 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +var EventEmitter = require('events').EventEmitter; + +var INSTANCE = new EventEmitter(); +var EVENTS_RECEIVER; + +module.exports = INSTANCE; + +/** + * Sets up current instance to forward emitted events to another EventEmitter + * instance. + * + * @param {EventEmitter} [eventEmitter] The emitter instance to forward + * events to. Falsy value, when passed, disables forwarding. + */ +module.exports.forwardEventsTo = function (eventEmitter) { + + // If no argument is specified disable events forwarding + if (!eventEmitter) { + EVENTS_RECEIVER = undefined; + return; + } + + if (!(eventEmitter instanceof EventEmitter)) + throw new Error('Cordova events could be redirected to another EventEmitter instance only'); + + EVENTS_RECEIVER = eventEmitter; +}; + +var emit = INSTANCE.emit; + +/** + * This method replaces original 'emit' method to allow events forwarding. + * + * @return {eventEmitter} Current instance to allow calls chaining, as + * original 'emit' does + */ +module.exports.emit = function () { + + var args = Array.prototype.slice.call(arguments); + + if (EVENTS_RECEIVER) { + EVENTS_RECEIVER.emit.apply(EVENTS_RECEIVER, args); + } + + return emit.apply(this, args); +}; diff --git a/platforms/android/cordova/node_modules/cordova-common/src/superspawn.js b/platforms/android/cordova/node_modules/cordova-common/src/superspawn.js new file mode 100644 index 0000000..a3f1431 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/superspawn.js @@ -0,0 +1,184 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +var child_process = require('child_process'); +var fs = require('fs'); +var path = require('path'); +var _ = require('underscore'); +var Q = require('q'); +var shell = require('shelljs'); +var events = require('./events'); +var iswin32 = process.platform == 'win32'; + +// On Windows, spawn() for batch files requires absolute path & having the extension. +function resolveWindowsExe(cmd) { + var winExtensions = ['.exe', '.bat', '.cmd', '.js', '.vbs']; + function isValidExe(c) { + return winExtensions.indexOf(path.extname(c)) !== -1 && fs.existsSync(c); + } + if (isValidExe(cmd)) { + return cmd; + } + cmd = shell.which(cmd) || cmd; + if (!isValidExe(cmd)) { + winExtensions.some(function(ext) { + if (fs.existsSync(cmd + ext)) { + cmd = cmd + ext; + return true; + } + }); + } + return cmd; +} + +function maybeQuote(a) { + if (/^[^"].*[ &].*[^"]/.test(a)) return '"' + a + '"'; + return a; +} + +/** + * A special implementation for child_process.spawn that handles + * Windows-specific issues with batch files and spaces in paths. Returns a + * promise that succeeds only for return code 0. It is also possible to + * subscribe on spawned process' stdout and stderr streams using progress + * handler for resultant promise. + * + * @example spawn('mycommand', [], {stdio: 'pipe'}) .progress(function (stdio){ + * if (stdio.stderr) { console.error(stdio.stderr); } }) + * .then(function(result){ // do other stuff }) + * + * @param {String} cmd A command to spawn + * @param {String[]} [args=[]] An array of arguments, passed to spawned + * process + * @param {Object} [opts={}] A configuration object + * @param {String|String[]|Object} opts.stdio Property that configures how + * spawned process' stdio will behave. Has the same meaning and possible + * values as 'stdio' options for child_process.spawn method + * (https://nodejs.org/api/child_process.html#child_process_options_stdio). + * @param {Object} [env={}] A map of extra environment variables + * @param {String} [cwd=process.cwd()] Working directory for the command + * @param {Boolean} [chmod=false] If truthy, will attempt to set the execute + * bit before executing on non-Windows platforms + * + * @return {Promise} A promise that is either fulfilled if the spawned + * process is exited with zero error code or rejected otherwise. If the + * 'stdio' option set to 'default' or 'pipe', the promise also emits progress + * messages with the following contents: + * { + * 'stdout': ..., + * 'stderr': ... + * } + */ +exports.spawn = function(cmd, args, opts) { + args = args || []; + opts = opts || {}; + var spawnOpts = {}; + var d = Q.defer(); + + if (iswin32) { + cmd = resolveWindowsExe(cmd); + // If we couldn't find the file, likely we'll end up failing, + // but for things like "del", cmd will do the trick. + if (path.extname(cmd) != '.exe') { + var cmdArgs = '"' + [cmd].concat(args).map(maybeQuote).join(' ') + '"'; + // We need to use /s to ensure that spaces are parsed properly with cmd spawned content + args = [['/s', '/c', cmdArgs].join(' ')]; + cmd = 'cmd'; + spawnOpts.windowsVerbatimArguments = true; + } else if (!fs.existsSync(cmd)) { + // We need to use /s to ensure that spaces are parsed properly with cmd spawned content + args = ['/s', '/c', cmd].concat(args).map(maybeQuote); + } + } + + if (opts.stdio !== 'default') { + // Ignore 'default' value for stdio because it corresponds to child_process's default 'pipe' option + spawnOpts.stdio = opts.stdio; + } + + if (opts.cwd) { + spawnOpts.cwd = opts.cwd; + } + + if (opts.env) { + spawnOpts.env = _.extend(_.extend({}, process.env), opts.env); + } + + if (opts.chmod && !iswin32) { + try { + // This fails when module is installed in a system directory (e.g. via sudo npm install) + fs.chmodSync(cmd, '755'); + } catch (e) { + // If the perms weren't set right, then this will come as an error upon execution. + } + } + + events.emit(opts.printCommand ? 'log' : 'verbose', 'Running command: ' + maybeQuote(cmd) + ' ' + args.map(maybeQuote).join(' ')); + + var child = child_process.spawn(cmd, args, spawnOpts); + var capturedOut = ''; + var capturedErr = ''; + + if (child.stdout) { + child.stdout.setEncoding('utf8'); + child.stdout.on('data', function(data) { + capturedOut += data; + d.notify({'stdout': data}); + }); + } + + if (child.stderr) { + child.stderr.setEncoding('utf8'); + child.stderr.on('data', function(data) { + capturedErr += data; + d.notify({'stderr': data}); + }); + } + + child.on('close', whenDone); + child.on('error', whenDone); + function whenDone(arg) { + child.removeListener('close', whenDone); + child.removeListener('error', whenDone); + var code = typeof arg == 'number' ? arg : arg && arg.code; + + events.emit('verbose', 'Command finished with error code ' + code + ': ' + cmd + ' ' + args); + if (code === 0) { + d.resolve(capturedOut.trim()); + } else { + var errMsg = cmd + ': Command failed with exit code ' + code; + if (capturedErr) { + errMsg += ' Error output:\n' + capturedErr.trim(); + } + var err = new Error(errMsg); + err.code = code; + d.reject(err); + } + } + + return d.promise; +}; + +exports.maybeSpawn = function(cmd, args, opts) { + if (fs.existsSync(cmd)) { + return exports.spawn(cmd, args, opts); + } + return Q(null); +}; + diff --git a/platforms/android/cordova/node_modules/cordova-common/src/util/plist-helpers.js b/platforms/android/cordova/node_modules/cordova-common/src/util/plist-helpers.js new file mode 100644 index 0000000..9dee5c6 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/util/plist-helpers.js @@ -0,0 +1,101 @@ +/* + * + * Copyright 2013 Brett Rudd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +// contains PLIST utility functions +var __ = require('underscore'); +var plist = require('plist'); + +// adds node to doc at selector +module.exports.graftPLIST = graftPLIST; +function graftPLIST(doc, xml, selector) { + var obj = plist.parse(''+xml+''); + + var node = doc[selector]; + if (node && Array.isArray(node) && Array.isArray(obj)){ + node = node.concat(obj); + for (var i =0;i. If we have two dicts we merge them instead of + // overriding the old one. See CB-6472 + if (node && __.isObject(node) && __.isObject(obj) && !__.isDate(node) && !__.isDate(obj)){//arrays checked above + __.extend(obj,node); + } + doc[selector] = obj; + } + + return true; +} + +// removes node from doc at selector +module.exports.prunePLIST = prunePLIST; +function prunePLIST(doc, xml, selector) { + var obj = plist.parse(''+xml+''); + + pruneOBJECT(doc, selector, obj); + + return true; +} + +function pruneOBJECT(doc, selector, fragment) { + if (Array.isArray(fragment) && Array.isArray(doc[selector])) { + var empty = true; + for (var i in fragment) { + for (var j in doc[selector]) { + empty = pruneOBJECT(doc[selector], j, fragment[i]) && empty; + } + } + if (empty) + { + delete doc[selector]; + return true; + } + } + else if (nodeEqual(doc[selector], fragment)) { + delete doc[selector]; + return true; + } + + return false; +} + +function nodeEqual(node1, node2) { + if (typeof node1 != typeof node2) + return false; + else if (typeof node1 == 'string') { + node2 = escapeRE(node2).replace(new RegExp('\\$[a-zA-Z0-9-_]+','gm'),'(.*?)'); + return new RegExp('^' + node2 + '$').test(node1); + } + else { + for (var key in node2) { + if (!nodeEqual(node1[key], node2[key])) return false; + } + return true; + } +} + +// escape string for use in regex +function escapeRE(str) { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '$&'); +} diff --git a/platforms/android/cordova/node_modules/cordova-common/src/util/xml-helpers.js b/platforms/android/cordova/node_modules/cordova-common/src/util/xml-helpers.js new file mode 100644 index 0000000..8b02989 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-common/src/util/xml-helpers.js @@ -0,0 +1,266 @@ +/* + * + * Copyright 2013 Anis Kadri + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint sub:true, laxcomma:true */ + +/** + * contains XML utility functions, some of which are specific to elementtree + */ + +var fs = require('fs') + , path = require('path') + , _ = require('underscore') + , et = require('elementtree') + ; + +module.exports = { + // compare two et.XML nodes, see if they match + // compares tagName, text, attributes and children (recursively) + equalNodes: function(one, two) { + if (one.tag != two.tag) { + return false; + } else if (one.text.trim() != two.text.trim()) { + return false; + } else if (one._children.length != two._children.length) { + return false; + } + + var oneAttribKeys = Object.keys(one.attrib), + twoAttribKeys = Object.keys(two.attrib), + i = 0, attribName; + + if (oneAttribKeys.length != twoAttribKeys.length) { + return false; + } + + for (i; i < oneAttribKeys.length; i++) { + attribName = oneAttribKeys[i]; + + if (one.attrib[attribName] != two.attrib[attribName]) { + return false; + } + } + + for (i; i < one._children.length; i++) { + if (!module.exports.equalNodes(one._children[i], two._children[i])) { + return false; + } + } + + return true; + }, + + // adds node to doc at selector, creating parent if it doesn't exist + graftXML: function(doc, nodes, selector, after) { + var parent = resolveParent(doc, selector); + if (!parent) { + //Try to create the parent recursively if necessary + try { + var parentToCreate = et.XML('<' + path.basename(selector) + '>'), + parentSelector = path.dirname(selector); + + this.graftXML(doc, [parentToCreate], parentSelector); + } catch (e) { + return false; + } + parent = resolveParent(doc, selector); + if (!parent) return false; + } + + nodes.forEach(function (node) { + // check if child is unique first + if (uniqueChild(node, parent)) { + var children = parent.getchildren(); + var insertIdx = after ? findInsertIdx(children, after) : children.length; + + //TODO: replace with parent.insert after the bug in ElementTree is fixed + parent.getchildren().splice(insertIdx, 0, node); + } + }); + + return true; + }, + + // removes node from doc at selector + pruneXML: function(doc, nodes, selector) { + var parent = resolveParent(doc, selector); + if (!parent) return false; + + nodes.forEach(function (node) { + var matchingKid = null; + if ((matchingKid = findChild(node, parent)) !== null) { + // stupid elementtree takes an index argument it doesn't use + // and does not conform to the python lib + parent.remove(matchingKid); + } + }); + + return true; + }, + + parseElementtreeSync: function (filename) { + var contents = fs.readFileSync(filename, 'utf-8'); + if(contents) { + //Windows is the BOM. Skip the Byte Order Mark. + contents = contents.substring(contents.indexOf('<')); + } + return new et.ElementTree(et.XML(contents)); + } +}; + +function findChild(node, parent) { + var matchingKids = parent.findall(node.tag) + , i, j; + + for (i = 0, j = matchingKids.length ; i < j ; i++) { + if (module.exports.equalNodes(node, matchingKids[i])) { + return matchingKids[i]; + } + } + return null; +} + +function uniqueChild(node, parent) { + var matchingKids = parent.findall(node.tag) + , i = 0; + + if (matchingKids.length === 0) { + return true; + } else { + for (i; i < matchingKids.length; i++) { + if (module.exports.equalNodes(node, matchingKids[i])) { + return false; + } + } + return true; + } +} + +var ROOT = /^\/([^\/]*)/, + ABSOLUTE = /^\/([^\/]*)\/(.*)/; + +function resolveParent(doc, selector) { + var parent, tagName, subSelector; + + // handle absolute selector (which elementtree doesn't like) + if (ROOT.test(selector)) { + tagName = selector.match(ROOT)[1]; + // test for wildcard "any-tag" root selector + if (tagName == '*' || tagName === doc._root.tag) { + parent = doc._root; + + // could be an absolute path, but not selecting the root + if (ABSOLUTE.test(selector)) { + subSelector = selector.match(ABSOLUTE)[2]; + parent = parent.find(subSelector); + } + } else { + return false; + } + } else { + parent = doc.find(selector); + } + return parent; +} + +// Find the index at which to insert an entry. After is a ;-separated priority list +// of tags after which the insertion should be made. E.g. If we need to +// insert an element C, and the rule is that the order of children has to be +// As, Bs, Cs. After will be equal to "C;B;A". +function findInsertIdx(children, after) { + var childrenTags = children.map(function(child) { return child.tag; }); + var afters = after.split(';'); + var afterIndexes = afters.map(function(current) { return childrenTags.lastIndexOf(current); }); + var foundIndex = _.find(afterIndexes, function(index) { return index != -1; }); + + //add to the beginning if no matching nodes are found + return typeof foundIndex === 'undefined' ? 0 : foundIndex+1; +} + +var BLACKLIST = ['platform', 'feature','plugin','engine']; +var SINGLETONS = ['content', 'author']; +function mergeXml(src, dest, platform, clobber) { + // Do nothing for blacklisted tags. + if (BLACKLIST.indexOf(src.tag) != -1) return; + + //Handle attributes + Object.getOwnPropertyNames(src.attrib).forEach(function (attribute) { + if (clobber || !dest.attrib[attribute]) { + dest.attrib[attribute] = src.attrib[attribute]; + } + }); + //Handle text + if (src.text && (clobber || !dest.text)) { + dest.text = src.text; + } + //Handle platform + if (platform) { + src.findall('platform[@name="' + platform + '"]').forEach(function (platformElement) { + platformElement.getchildren().forEach(mergeChild); + }); + } + + //Handle children + src.getchildren().forEach(mergeChild); + + function mergeChild (srcChild) { + var srcTag = srcChild.tag, + destChild = new et.Element(srcTag), + foundChild, + query = srcTag + '', + shouldMerge = true; + + if (BLACKLIST.indexOf(srcTag) === -1) { + if (SINGLETONS.indexOf(srcTag) !== -1) { + foundChild = dest.find(query); + if (foundChild) { + destChild = foundChild; + dest.remove(destChild); + } + } else { + //Check for an exact match and if you find one don't add + Object.getOwnPropertyNames(srcChild.attrib).forEach(function (attribute) { + query += '[@' + attribute + '="' + srcChild.attrib[attribute] + '"]'; + }); + var foundChildren = dest.findall(query); + for(var i = 0; i < foundChildren.length; i++) { + foundChild = foundChildren[i]; + if (foundChild && textMatch(srcChild, foundChild) && (Object.keys(srcChild.attrib).length==Object.keys(foundChild.attrib).length)) { + destChild = foundChild; + dest.remove(destChild); + shouldMerge = false; + break; + } + } + } + + mergeXml(srcChild, destChild, platform, clobber && shouldMerge); + dest.append(destChild); + } + } +} + +// Expose for testing. +module.exports.mergeXml = mergeXml; + +function textMatch(elm1, elm2) { + var text1 = elm1.text ? elm1.text.replace(/\s+/, '') : '', + text2 = elm2.text ? elm2.text.replace(/\s+/, '') : ''; + return (text1 === '' || text1 === text2); +} diff --git a/platforms/android/cordova/node_modules/cordova-registry-mapper/.npmignore b/platforms/android/cordova/node_modules/cordova-registry-mapper/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-registry-mapper/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/platforms/android/cordova/node_modules/cordova-registry-mapper/.travis.yml b/platforms/android/cordova/node_modules/cordova-registry-mapper/.travis.yml new file mode 100644 index 0000000..ae381fc --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-registry-mapper/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +sudo: false +node_js: + - "0.10" +install: npm install +script: + - npm test diff --git a/platforms/android/cordova/node_modules/cordova-registry-mapper/README.md b/platforms/android/cordova/node_modules/cordova-registry-mapper/README.md new file mode 100644 index 0000000..3b93e5f --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-registry-mapper/README.md @@ -0,0 +1,14 @@ +[![Build Status](https://travis-ci.org/stevengill/cordova-registry-mapper.svg?branch=master)](https://travis-ci.org/stevengill/cordova-registry-mapper) + +#Cordova Registry Mapper + +This module is used to map Cordova plugin ids to package names and vice versa. + +When Cordova users add plugins to their projects using ids +(e.g. `cordova plugin add org.apache.cordova.device`), +this module will map that id to the corresponding package name so `cordova-lib` knows what to fetch from **npm**. + +This module was created so the Apache Cordova project could migrate its plugins from +the [Cordova Registry](http://registry.cordova.io/) +to [npm](https://registry.npmjs.com/) +instead of having to maintain a registry. diff --git a/platforms/android/cordova/node_modules/cordova-registry-mapper/index.js b/platforms/android/cordova/node_modules/cordova-registry-mapper/index.js new file mode 100644 index 0000000..4550774 --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-registry-mapper/index.js @@ -0,0 +1,204 @@ +var map = { + 'org.apache.cordova.battery-status':'cordova-plugin-battery-status', + 'org.apache.cordova.camera':'cordova-plugin-camera', + 'org.apache.cordova.console':'cordova-plugin-console', + 'org.apache.cordova.contacts':'cordova-plugin-contacts', + 'org.apache.cordova.device':'cordova-plugin-device', + 'org.apache.cordova.device-motion':'cordova-plugin-device-motion', + 'org.apache.cordova.device-orientation':'cordova-plugin-device-orientation', + 'org.apache.cordova.dialogs':'cordova-plugin-dialogs', + 'org.apache.cordova.file':'cordova-plugin-file', + 'org.apache.cordova.file-transfer':'cordova-plugin-file-transfer', + 'org.apache.cordova.geolocation':'cordova-plugin-geolocation', + 'org.apache.cordova.globalization':'cordova-plugin-globalization', + 'org.apache.cordova.inappbrowser':'cordova-plugin-inappbrowser', + 'org.apache.cordova.media':'cordova-plugin-media', + 'org.apache.cordova.media-capture':'cordova-plugin-media-capture', + 'org.apache.cordova.network-information':'cordova-plugin-network-information', + 'org.apache.cordova.splashscreen':'cordova-plugin-splashscreen', + 'org.apache.cordova.statusbar':'cordova-plugin-statusbar', + 'org.apache.cordova.vibration':'cordova-plugin-vibration', + 'org.apache.cordova.test-framework':'cordova-plugin-test-framework', + 'com.msopentech.websql' : 'cordova-plugin-websql', + 'com.msopentech.indexeddb' : 'cordova-plugin-indexeddb', + 'com.microsoft.aad.adal' : 'cordova-plugin-ms-adal', + 'com.microsoft.capptain' : 'capptain-cordova', + 'com.microsoft.services.aadgraph' : 'cordova-plugin-ms-aad-graph', + 'com.microsoft.services.files' : 'cordova-plugin-ms-files', + 'om.microsoft.services.outlook' : 'cordova-plugin-ms-outlook', + 'com.pbakondy.sim' : 'cordova-plugin-sim', + 'android.support.v4' : 'cordova-plugin-android-support-v4', + 'android.support.v7-appcompat' : 'cordova-plugin-android-support-v7-appcompat', + 'com.google.playservices' : 'cordova-plugin-googleplayservices', + 'com.google.cordova.admob' : 'cordova-plugin-admobpro', + 'com.rjfun.cordova.extension' : 'cordova-plugin-extension', + 'com.rjfun.cordova.plugin.admob' : 'cordova-plugin-admob', + 'com.rjfun.cordova.flurryads' : 'cordova-plugin-flurry', + 'com.rjfun.cordova.facebookads' : 'cordova-plugin-facebookads', + 'com.rjfun.cordova.httpd' : 'cordova-plugin-httpd', + 'com.rjfun.cordova.iad' : 'cordova-plugin-iad', + 'com.rjfun.cordova.iflyspeech' : 'cordova-plugin-iflyspeech', + 'com.rjfun.cordova.lianlianpay' : 'cordova-plugin-lianlianpay', + 'com.rjfun.cordova.mobfox' : 'cordova-plugin-mobfox', + 'com.rjfun.cordova.mopub' : 'cordova-plugin-mopub', + 'com.rjfun.cordova.mmedia' : 'cordova-plugin-mmedia', + 'com.rjfun.cordova.nativeaudio' : 'cordova-plugin-nativeaudio', + 'com.rjfun.cordova.plugin.paypalmpl' : 'cordova-plugin-paypalmpl', + 'com.rjfun.cordova.smartadserver' : 'cordova-plugin-smartadserver', + 'com.rjfun.cordova.sms' : 'cordova-plugin-sms', + 'com.rjfun.cordova.wifi' : 'cordova-plugin-wifi', + 'com.ohh2ahh.plugins.appavailability' : 'cordova-plugin-appavailability', + 'org.adapt-it.cordova.fonts' : 'cordova-plugin-fonts', + 'de.martinreinhardt.cordova.plugins.barcodeScanner' : 'cordova-plugin-barcodescanner', + 'de.martinreinhardt.cordova.plugins.urlhandler' : 'cordova-plugin-urlhandler', + 'de.martinreinhardt.cordova.plugins.email' : 'cordova-plugin-email', + 'de.martinreinhardt.cordova.plugins.certificates' : 'cordova-plugin-certificates', + 'de.martinreinhardt.cordova.plugins.sqlite' : 'cordova-plugin-sqlite', + 'fr.smile.cordova.fileopener' : 'cordova-plugin-fileopener', + 'org.smile.websqldatabase.initializer' : 'cordova-plugin-websqldatabase-initializer', + 'org.smile.websqldatabase.wpdb' : 'cordova-plugin-websqldatabase', + 'org.jboss.aerogear.cordova.push' : 'aerogear-cordova-push', + 'org.jboss.aerogear.cordova.oauth2' : 'aerogear-cordova-oauth2', + 'org.jboss.aerogear.cordova.geo' : 'aerogear-cordova-geo', + 'org.jboss.aerogear.cordova.crypto' : 'aerogear-cordova-crypto', + 'org.jboss.aerogaer.cordova.otp' : 'aerogear-cordova-otp', + 'uk.co.ilee.applewatch' : 'cordova-plugin-apple-watch', + 'uk.co.ilee.directions' : 'cordova-plugin-directions', + 'uk.co.ilee.gamecenter' : 'cordova-plugin-game-center', + 'uk.co.ilee.jailbreakdetection' : 'cordova-plugin-jailbreak-detection', + 'uk.co.ilee.nativetransitions' : 'cordova-plugin-native-transitions', + 'uk.co.ilee.pedometer' : 'cordova-plugin-pedometer', + 'uk.co.ilee.shake' : 'cordova-plugin-shake', + 'uk.co.ilee.touchid' : 'cordova-plugin-touchid', + 'com.knowledgecode.cordova.websocket' : 'cordova-plugin-websocket', + 'com.elixel.plugins.settings' : 'cordova-plugin-settings', + 'com.cowbell.cordova.geofence' : 'cordova-plugin-geofence', + 'com.blackberry.community.preventsleep' : 'cordova-plugin-preventsleep', + 'com.blackberry.community.gamepad' : 'cordova-plugin-gamepad', + 'com.blackberry.community.led' : 'cordova-plugin-led', + 'com.blackberry.community.thumbnail' : 'cordova-plugin-thumbnail', + 'com.blackberry.community.mediakeys' : 'cordova-plugin-mediakeys', + 'com.blackberry.community.simplebtlehrplugin' : 'cordova-plugin-bluetoothheartmonitor', + 'com.blackberry.community.simplebeaconplugin' : 'cordova-plugin-bluetoothibeacon', + 'com.blackberry.community.simplebtsppplugin' : 'cordova-plugin-bluetoothspp', + 'com.blackberry.community.clipboard' : 'cordova-plugin-clipboard', + 'com.blackberry.community.curl' : 'cordova-plugin-curl', + 'com.blackberry.community.qt' : 'cordova-plugin-qtbridge', + 'com.blackberry.community.upnp' : 'cordova-plugin-upnp', + 'com.blackberry.community.PasswordCrypto' : 'cordova-plugin-password-crypto', + 'com.blackberry.community.deviceinfoplugin' : 'cordova-plugin-deviceinfo', + 'com.blackberry.community.gsecrypto' : 'cordova-plugin-bb-crypto', + 'com.blackberry.community.mongoose' : 'cordova-plugin-mongoose', + 'com.blackberry.community.sysdialog' : 'cordova-plugin-bb-sysdialog', + 'com.blackberry.community.screendisplay' : 'cordova-plugin-screendisplay', + 'com.blackberry.community.messageplugin' : 'cordova-plugin-bb-messageretrieve', + 'com.blackberry.community.emailsenderplugin' : 'cordova-plugin-emailsender', + 'com.blackberry.community.audiometadata' : 'cordova-plugin-audiometadata', + 'com.blackberry.community.deviceemails' : 'cordova-plugin-deviceemails', + 'com.blackberry.community.audiorecorder' : 'cordova-plugin-audiorecorder', + 'com.blackberry.community.vibration' : 'cordova-plugin-vibrate-intense', + 'com.blackberry.community.SMSPlugin' : 'cordova-plugin-bb-sms', + 'com.blackberry.community.extractZipFile' : 'cordova-plugin-bb-zip', + 'com.blackberry.community.lowlatencyaudio' : 'cordova-plugin-bb-nativeaudio', + 'com.blackberry.community.barcodescanner' : 'phonegap-plugin-barcodescanner', + 'com.blackberry.app' : 'cordova-plugin-bb-app', + 'com.blackberry.bbm.platform' : 'cordova-plugin-bbm', + 'com.blackberry.connection' : 'cordova-plugin-bb-connection', + 'com.blackberry.identity' : 'cordova-plugin-bb-identity', + 'com.blackberry.invoke.card' : 'cordova-plugin-bb-card', + 'com.blackberry.invoke' : 'cordova-plugin-bb-invoke', + 'com.blackberry.invoked' : 'cordova-plugin-bb-invoked', + 'com.blackberry.io.filetransfer' : 'cordova-plugin-bb-filetransfer', + 'com.blackberry.io' : 'cordova-plugin-bb-io', + 'com.blackberry.notification' : 'cordova-plugin-bb-notification', + 'com.blackberry.payment' : 'cordova-plugin-bb-payment', + 'com.blackberry.pim.calendar' : 'cordova-plugin-bb-calendar', + 'com.blackberry.pim.contacts' : 'cordova-plugin-bb-contacts', + 'com.blackberry.pim.lib' : 'cordova-plugin-bb-pimlib', + 'com.blackberry.push' : 'cordova-plugin-bb-push', + 'com.blackberry.screenshot' : 'cordova-plugin-screenshot', + 'com.blackberry.sensors' : 'cordova-plugin-bb-sensors', + 'com.blackberry.system' : 'cordova-plugin-bb-system', + 'com.blackberry.ui.contextmenu' : 'cordova-plugin-bb-ctxmenu', + 'com.blackberry.ui.cover' : 'cordova-plugin-bb-cover', + 'com.blackberry.ui.dialog' : 'cordova-plugin-bb-dialog', + 'com.blackberry.ui.input' : 'cordova-plugin-touch-keyboard', + 'com.blackberry.ui.toast' : 'cordova-plugin-toast', + 'com.blackberry.user.identity' : 'cordova-plugin-bb-idservice', + 'com.blackberry.utils' : 'cordova-plugin-bb-utils', + 'net.yoik.cordova.plugins.screenorientation' : 'cordova-plugin-screen-orientation', + 'com.phonegap.plugins.barcodescanner' : 'phonegap-plugin-barcodescanner', + 'com.manifoldjs.hostedwebapp' : 'cordova-plugin-hostedwebapp', + 'com.initialxy.cordova.themeablebrowser' : 'cordova-plugin-themeablebrowser', + 'gr.denton.photosphere' : 'cordova-plugin-panoramaviewer', + 'nl.x-services.plugins.actionsheet' : 'cordova-plugin-actionsheet', + 'nl.x-services.plugins.socialsharing' : 'cordova-plugin-x-socialsharing', + 'nl.x-services.plugins.googleplus' : 'cordova-plugin-googleplus', + 'nl.x-services.plugins.insomnia' : 'cordova-plugin-insomnia', + 'nl.x-services.plugins.toast' : 'cordova-plugin-x-toast', + 'nl.x-services.plugins.calendar' : 'cordova-plugin-calendar', + 'nl.x-services.plugins.launchmyapp' : 'cordova-plugin-customurlscheme', + 'nl.x-services.plugins.flashlight' : 'cordova-plugin-flashlight', + 'nl.x-services.plugins.sslcertificatechecker' : 'cordova-plugin-sslcertificatechecker', + 'com.bridge.open' : 'cordova-open', + 'com.bridge.safe' : 'cordova-safe', + 'com.disusered.open' : 'cordova-open', + 'com.disusered.safe' : 'cordova-safe', + 'me.apla.cordova.app-preferences' : 'cordova-plugin-app-preferences', + 'com.konotor.cordova' : 'cordova-plugin-konotor', + 'io.intercom.cordova' : 'cordova-plugin-intercom', + 'com.onesignal.plugins.onesignal' : 'onesignal-cordova-plugin', + 'com.danjarvis.document-contract': 'cordova-plugin-document-contract', + 'com.eface2face.iosrtc' : 'cordova-plugin-iosrtc', + 'com.mobileapptracking.matplugin' : 'cordova-plugin-tune', + 'com.marianhello.cordova.background-geolocation' : 'cordova-plugin-mauron85-background-geolocation', + 'fr.louisbl.cordova.locationservices' : 'cordova-plugin-locationservices', + 'fr.louisbl.cordova.gpslocation' : 'cordova-plugin-gpslocation', + 'com.hiliaox.weibo' : 'cordova-plugin-weibo', + 'com.uxcam.cordova.plugin' : 'cordova-uxcam', + 'de.fastr.phonegap.plugins.downloader' : 'cordova-plugin-fastrde-downloader', + 'de.fastr.phonegap.plugins.injectView' : 'cordova-plugin-fastrde-injectview', + 'de.fastr.phonegap.plugins.CheckGPS' : 'cordova-plugin-fastrde-checkgps', + 'de.fastr.phonegap.plugins.md5chksum' : 'cordova-plugin-fastrde-md5', + 'io.repro.cordova' : 'cordova-plugin-repro', + 're.notifica.cordova': 'cordova-plugin-notificare-push', + 'com.megster.cordova.ble': 'cordova-plugin-ble-central', + 'com.megster.cordova.bluetoothserial': 'cordova-plugin-bluetooth-serial', + 'com.megster.cordova.rfduino': 'cordova-plugin-rfduino', + 'cz.velda.cordova.plugin.devicefeedback': 'cordova-plugin-velda-devicefeedback', + 'cz.Velda.cordova.plugin.devicefeedback': 'cordova-plugin-velda-devicefeedback', + 'org.scriptotek.appinfo': 'cordova-plugin-appinfo', + 'com.yezhiming.cordova.appinfo': 'cordova-plugin-appinfo', + 'pl.makingwaves.estimotebeacons': 'cordova-plugin-estimote', + 'com.evothings.ble': 'cordova-plugin-ble', + 'com.appsee.plugin' : 'cordova-plugin-appsee', + 'am.armsoft.plugins.listpicker': 'cordova-plugin-listpicker', + 'com.pushbots.push': 'pushbots-cordova-plugin', + 'com.admob.google': 'cordova-admob', + 'admob.ads.google': 'cordova-admob-ads', + 'admob.google.plugin': 'admob-google', + 'com.admob.admobads': 'admob-ads', + 'com.connectivity.monitor': 'cordova-connectivity-monitor', + 'com.ios.libgoogleadmobads': 'cordova-libgoogleadmobads', + 'com.google.play.services': 'cordova-google-play-services', + 'android.support.v13': 'cordova-android-support-v13', + 'android.support.v4': 'cordova-android-support-v4', // Duplicated key ;) + 'com.analytics.google': 'cordova-plugin-analytics', + 'com.analytics.adid.google': 'cordova-plugin-analytics-adid', + 'com.chariotsolutions.nfc.plugin': 'phonegap-nfc', + 'com.samz.mixpanel': 'cordova-plugin-mixpanel', + 'de.appplant.cordova.common.RegisterUserNotificationSettings': 'cordova-plugin-registerusernotificationsettings', + 'plugin.google.maps': 'cordova-plugin-googlemaps', + 'xu.li.cordova.wechat': 'cordova-plugin-wechat', + 'es.keensoft.fullscreenimage': 'cordova-plugin-fullscreenimage', + 'com.arcoirislabs.plugin.mqtt' : 'cordova-plugin-mqtt' +}; + +module.exports.oldToNew = map; + +var reverseMap = {}; +Object.keys(map).forEach(function(elem){ + reverseMap[map[elem]] = elem; +}); + +module.exports.newToOld = reverseMap; diff --git a/platforms/android/cordova/node_modules/cordova-registry-mapper/package.json b/platforms/android/cordova/node_modules/cordova-registry-mapper/package.json new file mode 100644 index 0000000..989efad --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-registry-mapper/package.json @@ -0,0 +1,77 @@ +{ + "_args": [ + [ + "cordova-registry-mapper@^1.1.8", + "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common" + ] + ], + "_from": "cordova-registry-mapper@>=1.1.8 <2.0.0", + "_id": "cordova-registry-mapper@1.1.15", + "_inCache": true, + "_installable": true, + "_location": "/cordova-registry-mapper", + "_nodeVersion": "5.4.1", + "_npmUser": { + "email": "stevengill97@gmail.com", + "name": "stevegill" + }, + "_npmVersion": "3.5.3", + "_phantomChildren": {}, + "_requested": { + "name": "cordova-registry-mapper", + "raw": "cordova-registry-mapper@^1.1.8", + "rawSpec": "^1.1.8", + "scope": null, + "spec": ">=1.1.8 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/cordova-common" + ], + "_resolved": "http://registry.npmjs.org/cordova-registry-mapper/-/cordova-registry-mapper-1.1.15.tgz", + "_shasum": "e244b9185b8175473bff6079324905115f83dc7c", + "_shrinkwrap": null, + "_spec": "cordova-registry-mapper@^1.1.8", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common", + "author": { + "name": "Steve Gill" + }, + "bugs": { + "url": "https://github.com/stevengill/cordova-registry-mapper/issues" + }, + "dependencies": {}, + "description": "Maps old plugin ids to new plugin names for fetching from npm", + "devDependencies": { + "tape": "^3.5.0" + }, + "directories": {}, + "dist": { + "shasum": "e244b9185b8175473bff6079324905115f83dc7c", + "tarball": "http://registry.npmjs.org/cordova-registry-mapper/-/cordova-registry-mapper-1.1.15.tgz" + }, + "gitHead": "00af0f028ec94154a364eeabe38b8e22320647bd", + "homepage": "https://github.com/stevengill/cordova-registry-mapper#readme", + "keywords": [ + "cordova", + "plugins" + ], + "license": "Apache version 2.0", + "main": "index.js", + "maintainers": [ + { + "name": "stevegill", + "email": "stevengill97@gmail.com" + } + ], + "name": "cordova-registry-mapper", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/stevengill/cordova-registry-mapper.git" + }, + "scripts": { + "test": "node tests/test.js" + }, + "version": "1.1.15" +} diff --git a/platforms/android/cordova/node_modules/cordova-registry-mapper/tests/test.js b/platforms/android/cordova/node_modules/cordova-registry-mapper/tests/test.js new file mode 100644 index 0000000..35343be --- /dev/null +++ b/platforms/android/cordova/node_modules/cordova-registry-mapper/tests/test.js @@ -0,0 +1,11 @@ +var test = require('tape'); +var oldToNew = require('../index').oldToNew; +var newToOld = require('../index').newToOld; + +test('plugin mappings exist', function(t) { + t.plan(2); + + t.equal('cordova-plugin-device', oldToNew['org.apache.cordova.device']); + + t.equal('org.apache.cordova.device', newToOld['cordova-plugin-device']); +}) diff --git a/platforms/android/cordova/node_modules/elementtree/.npmignore b/platforms/android/cordova/node_modules/elementtree/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/platforms/android/cordova/node_modules/elementtree/.travis.yml b/platforms/android/cordova/node_modules/elementtree/.travis.yml new file mode 100644 index 0000000..6f27c96 --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/.travis.yml @@ -0,0 +1,10 @@ +language: node_js + +node_js: + - 0.6 + +script: make test + +notifications: + email: + - tomaz+travisci@tomaz.me diff --git a/platforms/android/cordova/node_modules/elementtree/CHANGES.md b/platforms/android/cordova/node_modules/elementtree/CHANGES.md new file mode 100644 index 0000000..50d415d --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/CHANGES.md @@ -0,0 +1,39 @@ +elementtree v0.1.6 (in development) + +* Add support for CData elements. (#14) + [hermannpencole] + +elementtree v0.1.5 - 2012-11-14 + +* Fix a bug in the find() and findtext() method which could manifest itself + under some conditions. + [metagriffin] + +elementtree v0.1.4 - 2012-10-15 + +* Allow user to use namespaced attributes when using find* functions. + [Andrew Lunny] + +elementtree v0.1.3 - 2012-09-21 + +* Improve the output of text content in the tags (strip unnecessary line break + characters). + +[Darryl Pogue] + +elementtree v0.1.2 - 2012-09-04 + + * Allow user to pass 'indent' option to ElementTree.write method. If this + option is specified (e.g. {'indent': 4}). XML will be pretty printed. + [Darryl Pogue, Tomaz Muraus] + + * Bump sax dependency version. + +elementtree v0.1.1 - 2011-09-23 + + * Improve special character escaping. + [Ryan Phillips] + +elementtree v0.1.0 - 2011-09-05 + + * Initial release. diff --git a/platforms/android/cordova/node_modules/elementtree/LICENSE.txt b/platforms/android/cordova/node_modules/elementtree/LICENSE.txt new file mode 100644 index 0000000..6b0b127 --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/LICENSE.txt @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/platforms/android/cordova/node_modules/elementtree/Makefile b/platforms/android/cordova/node_modules/elementtree/Makefile new file mode 100755 index 0000000..ab7c4e0 --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/Makefile @@ -0,0 +1,21 @@ +TESTS := \ + tests/test-simple.js + + + +PATH := ./node_modules/.bin:$(PATH) + +WHISKEY := $(shell bash -c 'PATH=$(PATH) type -p whiskey') + +default: test + +test: + NODE_PATH=`pwd`/lib/ ${WHISKEY} --scope-leaks --sequential --real-time --tests "${TESTS}" + +tap: + NODE_PATH=`pwd`/lib/ ${WHISKEY} --test-reporter tap --sequential --real-time --tests "${TESTS}" + +coverage: + NODE_PATH=`pwd`/lib/ ${WHISKEY} --sequential --coverage --coverage-reporter html --coverage-dir coverage_html --tests "${TESTS}" + +.PHONY: default test coverage tap scope diff --git a/platforms/android/cordova/node_modules/elementtree/NOTICE b/platforms/android/cordova/node_modules/elementtree/NOTICE new file mode 100644 index 0000000..28ad70a --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/NOTICE @@ -0,0 +1,5 @@ +node-elementtree +Copyright (c) 2011, Rackspace, Inc. + +The ElementTree toolkit is Copyright (c) 1999-2007 by Fredrik Lundh + diff --git a/platforms/android/cordova/node_modules/elementtree/README.md b/platforms/android/cordova/node_modules/elementtree/README.md new file mode 100644 index 0000000..738420c --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/README.md @@ -0,0 +1,141 @@ +node-elementtree +==================== + +node-elementtree is a [Node.js](http://nodejs.org) XML parser and serializer based upon the [Python ElementTree v1.3](http://effbot.org/zone/element-index.htm) module. + +Installation +==================== + + $ npm install elementtree + +Using the library +==================== + +For the usage refer to the Python ElementTree library documentation - [http://effbot.org/zone/element-index.htm#usage](http://effbot.org/zone/element-index.htm#usage). + +Supported XPath expressions in `find`, `findall` and `findtext` methods are listed on [http://effbot.org/zone/element-xpath.htm](http://effbot.org/zone/element-xpath.htm). + +Example 1 – Creating An XML Document +==================== + +This example shows how to build a valid XML document that can be published to +Atom Hopper. Atom Hopper is used internally as a bridge from products all the +way to collecting revenue, called “Usage.†MaaS and other products send similar +events to it every time user performs an action on a resource +(e.g. creates,updates or deletes). Below is an example of leveraging the API +to create a new XML document. + +```javascript +var et = require('elementtree'); +var XML = et.XML; +var ElementTree = et.ElementTree; +var element = et.Element; +var subElement = et.SubElement; + +var date, root, tenantId, serviceName, eventType, usageId, dataCenter, region, +checks, resourceId, category, startTime, resourceName, etree, xml; + +date = new Date(); + +root = element('entry'); +root.set('xmlns', 'http://www.w3.org/2005/Atom'); + +tenantId = subElement(root, 'TenantId'); +tenantId.text = '12345'; + +serviceName = subElement(root, 'ServiceName'); +serviceName.text = 'MaaS'; + +resourceId = subElement(root, 'ResourceID'); +resourceId.text = 'enAAAA'; + +usageId = subElement(root, 'UsageID'); +usageId.text = '550e8400-e29b-41d4-a716-446655440000'; + +eventType = subElement(root, 'EventType'); +eventType.text = 'create'; + +category = subElement(root, 'category'); +category.set('term', 'monitoring.entity.create'); + +dataCenter = subElement(root, 'DataCenter'); +dataCenter.text = 'global'; + +region = subElement(root, 'Region'); +region.text = 'global'; + +startTime = subElement(root, 'StartTime'); +startTime.text = date; + +resourceName = subElement(root, 'ResourceName'); +resourceName.text = 'entity'; + +etree = new ElementTree(root); +xml = etree.write({'xml_declaration': false}); +console.log(xml); +``` + +As you can see, both et.Element and et.SubElement are factory methods which +return a new instance of Element and SubElement class, respectively. +When you create a new element (tag) you can use set method to set an attribute. +To set the tag value, assign a value to the .text attribute. + +This example would output a document that looks like this: + +```xml + + 12345 + MaaS + enAAAA + 550e8400-e29b-41d4-a716-446655440000 + create + + global + global + Sun Apr 29 2012 16:37:32 GMT-0700 (PDT) + entity + +``` + +Example 2 – Parsing An XML Document +==================== + +This example shows how to parse an XML document and use simple XPath selectors. +For demonstration purposes, we will use the XML document located at +https://gist.github.com/2554343. + +Behind the scenes, node-elementtree uses Isaac’s sax library for parsing XML, +but the library has a concept of “parsers,†which means it’s pretty simple to +add support for a different parser. + +```javascript +var fs = require('fs'); + +var et = require('elementtree'); + +var XML = et.XML; +var ElementTree = et.ElementTree; +var element = et.Element; +var subElement = et.SubElement; + +var data, etree; + +data = fs.readFileSync('document.xml').toString(); +etree = et.parse(data); + +console.log(etree.findall('./entry/TenantId').length); // 2 +console.log(etree.findtext('./entry/ServiceName')); // MaaS +console.log(etree.findall('./entry/category')[0].get('term')); // monitoring.entity.create +console.log(etree.findall('*/category/[@term="monitoring.entity.update"]').length); // 1 +``` + +Build status +==================== + +[![Build Status](https://secure.travis-ci.org/racker/node-elementtree.png)](http://travis-ci.org/racker/node-elementtree) + + +License +==================== + +node-elementtree is distributed under the [Apache license](http://www.apache.org/licenses/LICENSE-2.0.html). diff --git a/platforms/android/cordova/node_modules/elementtree/lib/constants.js b/platforms/android/cordova/node_modules/elementtree/lib/constants.js new file mode 100644 index 0000000..b057faf --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/lib/constants.js @@ -0,0 +1,20 @@ +/* + * Copyright 2011 Rackspace + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +var DEFAULT_PARSER = 'sax'; + +exports.DEFAULT_PARSER = DEFAULT_PARSER; diff --git a/platforms/android/cordova/node_modules/elementtree/lib/elementpath.js b/platforms/android/cordova/node_modules/elementtree/lib/elementpath.js new file mode 100644 index 0000000..2e93f47 --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/lib/elementpath.js @@ -0,0 +1,343 @@ +/** + * Copyright 2011 Rackspace + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +var sprintf = require('./sprintf').sprintf; + +var utils = require('./utils'); +var SyntaxError = require('./errors').SyntaxError; + +var _cache = {}; + +var RE = new RegExp( + "(" + + "'[^']*'|\"[^\"]*\"|" + + "::|" + + "//?|" + + "\\.\\.|" + + "\\(\\)|" + + "[/.*:\\[\\]\\(\\)@=])|" + + "((?:\\{[^}]+\\})?[^/\\[\\]\\(\\)@=\\s]+)|" + + "\\s+", 'g' +); + +var xpath_tokenizer = utils.findall.bind(null, RE); + +function prepare_tag(next, token) { + var tag = token[0]; + + function select(context, result) { + var i, len, elem, rv = []; + + for (i = 0, len = result.length; i < len; i++) { + elem = result[i]; + elem._children.forEach(function(e) { + if (e.tag === tag) { + rv.push(e); + } + }); + } + + return rv; + } + + return select; +} + +function prepare_star(next, token) { + function select(context, result) { + var i, len, elem, rv = []; + + for (i = 0, len = result.length; i < len; i++) { + elem = result[i]; + elem._children.forEach(function(e) { + rv.push(e); + }); + } + + return rv; + } + + return select; +} + +function prepare_dot(next, token) { + function select(context, result) { + var i, len, elem, rv = []; + + for (i = 0, len = result.length; i < len; i++) { + elem = result[i]; + rv.push(elem); + } + + return rv; + } + + return select; +} + +function prepare_iter(next, token) { + var tag; + token = next(); + + if (token[1] === '*') { + tag = '*'; + } + else if (!token[1]) { + tag = token[0] || ''; + } + else { + throw new SyntaxError(token); + } + + function select(context, result) { + var i, len, elem, rv = []; + + for (i = 0, len = result.length; i < len; i++) { + elem = result[i]; + elem.iter(tag, function(e) { + if (e !== elem) { + rv.push(e); + } + }); + } + + return rv; + } + + return select; +} + +function prepare_dot_dot(next, token) { + function select(context, result) { + var i, len, elem, rv = [], parent_map = context.parent_map; + + if (!parent_map) { + context.parent_map = parent_map = {}; + + context.root.iter(null, function(p) { + p._children.forEach(function(e) { + parent_map[e] = p; + }); + }); + } + + for (i = 0, len = result.length; i < len; i++) { + elem = result[i]; + + if (parent_map.hasOwnProperty(elem)) { + rv.push(parent_map[elem]); + } + } + + return rv; + } + + return select; +} + + +function prepare_predicate(next, token) { + var tag, key, value, select; + token = next(); + + if (token[1] === '@') { + // attribute + token = next(); + + if (token[1]) { + throw new SyntaxError(token, 'Invalid attribute predicate'); + } + + key = token[0]; + token = next(); + + if (token[1] === ']') { + select = function(context, result) { + var i, len, elem, rv = []; + + for (i = 0, len = result.length; i < len; i++) { + elem = result[i]; + + if (elem.get(key)) { + rv.push(elem); + } + } + + return rv; + }; + } + else if (token[1] === '=') { + value = next()[1]; + + if (value[0] === '"' || value[value.length - 1] === '\'') { + value = value.slice(1, value.length - 1); + } + else { + throw new SyntaxError(token, 'Ivalid comparison target'); + } + + token = next(); + select = function(context, result) { + var i, len, elem, rv = []; + + for (i = 0, len = result.length; i < len; i++) { + elem = result[i]; + + if (elem.get(key) === value) { + rv.push(elem); + } + } + + return rv; + }; + } + + if (token[1] !== ']') { + throw new SyntaxError(token, 'Invalid attribute predicate'); + } + } + else if (!token[1]) { + tag = token[0] || ''; + token = next(); + + if (token[1] !== ']') { + throw new SyntaxError(token, 'Invalid node predicate'); + } + + select = function(context, result) { + var i, len, elem, rv = []; + + for (i = 0, len = result.length; i < len; i++) { + elem = result[i]; + + if (elem.find(tag)) { + rv.push(elem); + } + } + + return rv; + }; + } + else { + throw new SyntaxError(null, 'Invalid predicate'); + } + + return select; +} + + + +var ops = { + "": prepare_tag, + "*": prepare_star, + ".": prepare_dot, + "..": prepare_dot_dot, + "//": prepare_iter, + "[": prepare_predicate, +}; + +function _SelectorContext(root) { + this.parent_map = null; + this.root = root; +} + +function findall(elem, path) { + var selector, result, i, len, token, value, select, context; + + if (_cache.hasOwnProperty(path)) { + selector = _cache[path]; + } + else { + // TODO: Use smarter cache purging approach + if (Object.keys(_cache).length > 100) { + _cache = {}; + } + + if (path.charAt(0) === '/') { + throw new SyntaxError(null, 'Cannot use absolute path on element'); + } + + result = xpath_tokenizer(path); + selector = []; + + function getToken() { + return result.shift(); + } + + token = getToken(); + while (true) { + var c = token[1] || ''; + value = ops[c](getToken, token); + + if (!value) { + throw new SyntaxError(null, sprintf('Invalid path: %s', path)); + } + + selector.push(value); + token = getToken(); + + if (!token) { + break; + } + else if (token[1] === '/') { + token = getToken(); + } + + if (!token) { + break; + } + } + + _cache[path] = selector; + } + + // Execute slector pattern + result = [elem]; + context = new _SelectorContext(elem); + + for (i = 0, len = selector.length; i < len; i++) { + select = selector[i]; + result = select(context, result); + } + + return result || []; +} + +function find(element, path) { + var resultElements = findall(element, path); + + if (resultElements && resultElements.length > 0) { + return resultElements[0]; + } + + return null; +} + +function findtext(element, path, defvalue) { + var resultElements = findall(element, path); + + if (resultElements && resultElements.length > 0) { + return resultElements[0].text; + } + + return defvalue; +} + + +exports.find = find; +exports.findall = findall; +exports.findtext = findtext; diff --git a/platforms/android/cordova/node_modules/elementtree/lib/elementtree.js b/platforms/android/cordova/node_modules/elementtree/lib/elementtree.js new file mode 100644 index 0000000..61d9276 --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/lib/elementtree.js @@ -0,0 +1,611 @@ +/** + * Copyright 2011 Rackspace + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +var sprintf = require('./sprintf').sprintf; + +var utils = require('./utils'); +var ElementPath = require('./elementpath'); +var TreeBuilder = require('./treebuilder').TreeBuilder; +var get_parser = require('./parser').get_parser; +var constants = require('./constants'); + +var element_ids = 0; + +function Element(tag, attrib) +{ + this._id = element_ids++; + this.tag = tag; + this.attrib = {}; + this.text = null; + this.tail = null; + this._children = []; + + if (attrib) { + this.attrib = utils.merge(this.attrib, attrib); + } +} + +Element.prototype.toString = function() +{ + return sprintf("", this.tag, this._id); +}; + +Element.prototype.makeelement = function(tag, attrib) +{ + return new Element(tag, attrib); +}; + +Element.prototype.len = function() +{ + return this._children.length; +}; + +Element.prototype.getItem = function(index) +{ + return this._children[index]; +}; + +Element.prototype.setItem = function(index, element) +{ + this._children[index] = element; +}; + +Element.prototype.delItem = function(index) +{ + this._children.splice(index, 1); +}; + +Element.prototype.getSlice = function(start, stop) +{ + return this._children.slice(start, stop); +}; + +Element.prototype.setSlice = function(start, stop, elements) +{ + var i; + var k = 0; + for (i = start; i < stop; i++, k++) { + this._children[i] = elements[k]; + } +}; + +Element.prototype.delSlice = function(start, stop) +{ + this._children.splice(start, stop - start); +}; + +Element.prototype.append = function(element) +{ + this._children.push(element); +}; + +Element.prototype.extend = function(elements) +{ + this._children.concat(elements); +}; + +Element.prototype.insert = function(index, element) +{ + this._children[index] = element; +}; + +Element.prototype.remove = function(element) +{ + this._children = this._children.filter(function(e) { + /* TODO: is this the right way to do this? */ + if (e._id === element._id) { + return false; + } + return true; + }); +}; + +Element.prototype.getchildren = function() { + return this._children; +}; + +Element.prototype.find = function(path) +{ + return ElementPath.find(this, path); +}; + +Element.prototype.findtext = function(path, defvalue) +{ + return ElementPath.findtext(this, path, defvalue); +}; + +Element.prototype.findall = function(path, defvalue) +{ + return ElementPath.findall(this, path, defvalue); +}; + +Element.prototype.clear = function() +{ + this.attrib = {}; + this._children = []; + this.text = null; + this.tail = null; +}; + +Element.prototype.get = function(key, defvalue) +{ + if (this.attrib[key] !== undefined) { + return this.attrib[key]; + } + else { + return defvalue; + } +}; + +Element.prototype.set = function(key, value) +{ + this.attrib[key] = value; +}; + +Element.prototype.keys = function() +{ + return Object.keys(this.attrib); +}; + +Element.prototype.items = function() +{ + return utils.items(this.attrib); +}; + +/* + * In python this uses a generator, but in v8 we don't have em, + * so we use a callback instead. + **/ +Element.prototype.iter = function(tag, callback) +{ + var self = this; + var i, child; + + if (tag === "*") { + tag = null; + } + + if (tag === null || this.tag === tag) { + callback(self); + } + + for (i = 0; i < this._children.length; i++) { + child = this._children[i]; + child.iter(tag, function(e) { + callback(e); + }); + } +}; + +Element.prototype.itertext = function(callback) +{ + this.iter(null, function(e) { + if (e.text) { + callback(e.text); + } + + if (e.tail) { + callback(e.tail); + } + }); +}; + + +function SubElement(parent, tag, attrib) { + var element = parent.makeelement(tag, attrib); + parent.append(element); + return element; +} + +function Comment(text) { + var element = new Element(Comment); + if (text) { + element.text = text; + } + return element; +} + +function CData(text) { + var element = new Element(CData); + if (text) { + element.text = text; + } + return element; +} + +function ProcessingInstruction(target, text) +{ + var element = new Element(ProcessingInstruction); + element.text = target; + if (text) { + element.text = element.text + " " + text; + } + return element; +} + +function QName(text_or_uri, tag) +{ + if (tag) { + text_or_uri = sprintf("{%s}%s", text_or_uri, tag); + } + this.text = text_or_uri; +} + +QName.prototype.toString = function() { + return this.text; +}; + +function ElementTree(element) +{ + this._root = element; +} + +ElementTree.prototype.getroot = function() { + return this._root; +}; + +ElementTree.prototype._setroot = function(element) { + this._root = element; +}; + +ElementTree.prototype.parse = function(source, parser) { + if (!parser) { + parser = get_parser(constants.DEFAULT_PARSER); + parser = new parser.XMLParser(new TreeBuilder()); + } + + parser.feed(source); + this._root = parser.close(); + return this._root; +}; + +ElementTree.prototype.iter = function(tag, callback) { + this._root.iter(tag, callback); +}; + +ElementTree.prototype.find = function(path) { + return this._root.find(path); +}; + +ElementTree.prototype.findtext = function(path, defvalue) { + return this._root.findtext(path, defvalue); +}; + +ElementTree.prototype.findall = function(path) { + return this._root.findall(path); +}; + +/** + * Unlike ElementTree, we don't write to a file, we return you a string. + */ +ElementTree.prototype.write = function(options) { + var sb = []; + options = utils.merge({ + encoding: 'utf-8', + xml_declaration: null, + default_namespace: null, + method: 'xml'}, options); + + if (options.xml_declaration !== false) { + sb.push("\n"); + } + + if (options.method === "text") { + _serialize_text(sb, self._root, encoding); + } + else { + var qnames, namespaces, indent, indent_string; + var x = _namespaces(this._root, options.encoding, options.default_namespace); + qnames = x[0]; + namespaces = x[1]; + + if (options.hasOwnProperty('indent')) { + indent = 0; + indent_string = new Array(options.indent + 1).join(' '); + } + else { + indent = false; + } + + if (options.method === "xml") { + _serialize_xml(function(data) { + sb.push(data); + }, this._root, options.encoding, qnames, namespaces, indent, indent_string); + } + else { + /* TODO: html */ + throw new Error("unknown serialization method "+ options.method); + } + } + + return sb.join(""); +}; + +var _namespace_map = { + /* "well-known" namespace prefixes */ + "http://www.w3.org/XML/1998/namespace": "xml", + "http://www.w3.org/1999/xhtml": "html", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf", + "http://schemas.xmlsoap.org/wsdl/": "wsdl", + /* xml schema */ + "http://www.w3.org/2001/XMLSchema": "xs", + "http://www.w3.org/2001/XMLSchema-instance": "xsi", + /* dublic core */ + "http://purl.org/dc/elements/1.1/": "dc", +}; + +function register_namespace(prefix, uri) { + if (/ns\d+$/.test(prefix)) { + throw new Error('Prefix format reserved for internal use'); + } + + if (_namespace_map.hasOwnProperty(uri) && _namespace_map[uri] === prefix) { + delete _namespace_map[uri]; + } + + _namespace_map[uri] = prefix; +} + + +function _escape(text, encoding, isAttribute, isText) { + if (text) { + text = text.toString(); + text = text.replace(/&/g, '&'); + text = text.replace(//g, '>'); + if (!isText) { + text = text.replace(/\n/g, ' '); + text = text.replace(/\r/g, ' '); + } + if (isAttribute) { + text = text.replace(/"/g, '"'); + } + } + return text; +} + +/* TODO: benchmark single regex */ +function _escape_attrib(text, encoding) { + return _escape(text, encoding, true); +} + +function _escape_cdata(text, encoding) { + return _escape(text, encoding, false); +} + +function _escape_text(text, encoding) { + return _escape(text, encoding, false, true); +} + +function _namespaces(elem, encoding, default_namespace) { + var qnames = {}; + var namespaces = {}; + + if (default_namespace) { + namespaces[default_namespace] = ""; + } + + function encode(text) { + return text; + } + + function add_qname(qname) { + if (qname[0] === "{") { + var tmp = qname.substring(1).split("}", 2); + var uri = tmp[0]; + var tag = tmp[1]; + var prefix = namespaces[uri]; + + if (prefix === undefined) { + prefix = _namespace_map[uri]; + if (prefix === undefined) { + prefix = "ns" + Object.keys(namespaces).length; + } + if (prefix !== "xml") { + namespaces[uri] = prefix; + } + } + + if (prefix) { + qnames[qname] = sprintf("%s:%s", prefix, tag); + } + else { + qnames[qname] = tag; + } + } + else { + if (default_namespace) { + throw new Error('cannot use non-qualified names with default_namespace option'); + } + + qnames[qname] = qname; + } + } + + + elem.iter(null, function(e) { + var i; + var tag = e.tag; + var text = e.text; + var items = e.items(); + + if (tag instanceof QName && qnames[tag.text] === undefined) { + add_qname(tag.text); + } + else if (typeof(tag) === "string") { + add_qname(tag); + } + else if (tag !== null && tag !== Comment && tag !== CData && tag !== ProcessingInstruction) { + throw new Error('Invalid tag type for serialization: '+ tag); + } + + if (text instanceof QName && qnames[text.text] === undefined) { + add_qname(text.text); + } + + items.forEach(function(item) { + var key = item[0], + value = item[1]; + if (key instanceof QName) { + key = key.text; + } + + if (qnames[key] === undefined) { + add_qname(key); + } + + if (value instanceof QName && qnames[value.text] === undefined) { + add_qname(value.text); + } + }); + }); + return [qnames, namespaces]; +} + +function _serialize_xml(write, elem, encoding, qnames, namespaces, indent, indent_string) { + var tag = elem.tag; + var text = elem.text; + var items; + var i; + + var newlines = indent || (indent === 0); + write(Array(indent + 1).join(indent_string)); + + if (tag === Comment) { + write(sprintf("", _escape_cdata(text, encoding))); + } + else if (tag === ProcessingInstruction) { + write(sprintf("", _escape_cdata(text, encoding))); + } + else if (tag === CData) { + text = text || ''; + write(sprintf("", text)); + } + else { + tag = qnames[tag]; + if (tag === undefined) { + if (text) { + write(_escape_text(text, encoding)); + } + elem.iter(function(e) { + _serialize_xml(write, e, encoding, qnames, null, newlines ? indent + 1 : false, indent_string); + }); + } + else { + write("<" + tag); + items = elem.items(); + + if (items || namespaces) { + items.sort(); // lexical order + + items.forEach(function(item) { + var k = item[0], + v = item[1]; + + if (k instanceof QName) { + k = k.text; + } + + if (v instanceof QName) { + v = qnames[v.text]; + } + else { + v = _escape_attrib(v, encoding); + } + write(sprintf(" %s=\"%s\"", qnames[k], v)); + }); + + if (namespaces) { + items = utils.items(namespaces); + items.sort(function(a, b) { return a[1] < b[1]; }); + + items.forEach(function(item) { + var k = item[1], + v = item[0]; + + if (k) { + k = ':' + k; + } + + write(sprintf(" xmlns%s=\"%s\"", k, _escape_attrib(v, encoding))); + }); + } + } + + if (text || elem.len()) { + if (text && text.toString().match(/^\s*$/)) { + text = null; + } + + write(">"); + if (!text && newlines) { + write("\n"); + } + + if (text) { + write(_escape_text(text, encoding)); + } + elem._children.forEach(function(e) { + _serialize_xml(write, e, encoding, qnames, null, newlines ? indent + 1 : false, indent_string); + }); + + if (!text && indent) { + write(Array(indent + 1).join(indent_string)); + } + write(""); + } + else { + write(" />"); + } + } + } + + if (newlines) { + write("\n"); + } +} + +function parse(source, parser) { + var tree = new ElementTree(); + tree.parse(source, parser); + return tree; +} + +function tostring(element, options) { + return new ElementTree(element).write(options); +} + +exports.PI = ProcessingInstruction; +exports.Comment = Comment; +exports.CData = CData; +exports.ProcessingInstruction = ProcessingInstruction; +exports.SubElement = SubElement; +exports.QName = QName; +exports.ElementTree = ElementTree; +exports.ElementPath = ElementPath; +exports.Element = function(tag, attrib) { + return new Element(tag, attrib); +}; + +exports.XML = function(data) { + var et = new ElementTree(); + return et.parse(data); +}; + +exports.parse = parse; +exports.register_namespace = register_namespace; +exports.tostring = tostring; diff --git a/platforms/android/cordova/node_modules/elementtree/lib/errors.js b/platforms/android/cordova/node_modules/elementtree/lib/errors.js new file mode 100644 index 0000000..e8742be --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/lib/errors.js @@ -0,0 +1,31 @@ +/** + * Copyright 2011 Rackspace + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +var util = require('util'); + +var sprintf = require('./sprintf').sprintf; + +function SyntaxError(token, msg) { + msg = msg || sprintf('Syntax Error at token %s', token.toString()); + this.token = token; + this.message = msg; + Error.call(this, msg); +} + +util.inherits(SyntaxError, Error); + +exports.SyntaxError = SyntaxError; diff --git a/platforms/android/cordova/node_modules/elementtree/lib/parser.js b/platforms/android/cordova/node_modules/elementtree/lib/parser.js new file mode 100644 index 0000000..7307ee4 --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/lib/parser.js @@ -0,0 +1,33 @@ +/* + * Copyright 2011 Rackspace + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* TODO: support node-expat C++ module optionally */ + +var util = require('util'); +var parsers = require('./parsers/index'); + +function get_parser(name) { + if (name === 'sax') { + return parsers.sax; + } + else { + throw new Error('Invalid parser: ' + name); + } +} + + +exports.get_parser = get_parser; diff --git a/platforms/android/cordova/node_modules/elementtree/lib/parsers/index.js b/platforms/android/cordova/node_modules/elementtree/lib/parsers/index.js new file mode 100644 index 0000000..5eac5c8 --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/lib/parsers/index.js @@ -0,0 +1 @@ +exports.sax = require('./sax'); diff --git a/platforms/android/cordova/node_modules/elementtree/lib/parsers/sax.js b/platforms/android/cordova/node_modules/elementtree/lib/parsers/sax.js new file mode 100644 index 0000000..69b0a59 --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/lib/parsers/sax.js @@ -0,0 +1,56 @@ +var util = require('util'); + +var sax = require('sax'); + +var TreeBuilder = require('./../treebuilder').TreeBuilder; + +function XMLParser(target) { + this.parser = sax.parser(true); + + this.target = (target) ? target : new TreeBuilder(); + + this.parser.onopentag = this._handleOpenTag.bind(this); + this.parser.ontext = this._handleText.bind(this); + this.parser.oncdata = this._handleCdata.bind(this); + this.parser.ondoctype = this._handleDoctype.bind(this); + this.parser.oncomment = this._handleComment.bind(this); + this.parser.onclosetag = this._handleCloseTag.bind(this); + this.parser.onerror = this._handleError.bind(this); +} + +XMLParser.prototype._handleOpenTag = function(tag) { + this.target.start(tag.name, tag.attributes); +}; + +XMLParser.prototype._handleText = function(text) { + this.target.data(text); +}; + +XMLParser.prototype._handleCdata = function(text) { + this.target.data(text); +}; + +XMLParser.prototype._handleDoctype = function(text) { +}; + +XMLParser.prototype._handleComment = function(comment) { +}; + +XMLParser.prototype._handleCloseTag = function(tag) { + this.target.end(tag); +}; + +XMLParser.prototype._handleError = function(err) { + throw err; +}; + +XMLParser.prototype.feed = function(chunk) { + this.parser.write(chunk); +}; + +XMLParser.prototype.close = function() { + this.parser.close(); + return this.target.close(); +}; + +exports.XMLParser = XMLParser; diff --git a/platforms/android/cordova/node_modules/elementtree/lib/sprintf.js b/platforms/android/cordova/node_modules/elementtree/lib/sprintf.js new file mode 100644 index 0000000..f802c1b --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/lib/sprintf.js @@ -0,0 +1,86 @@ +/* + * Copyright 2011 Rackspace + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +var cache = {}; + + +// Do any others need escaping? +var TO_ESCAPE = { + '\'': '\\\'', + '\n': '\\n' +}; + + +function populate(formatter) { + var i, type, + key = formatter, + prev = 0, + arg = 1, + builder = 'return \''; + + for (i = 0; i < formatter.length; i++) { + if (formatter[i] === '%') { + type = formatter[i + 1]; + + switch (type) { + case 's': + builder += formatter.slice(prev, i) + '\' + arguments[' + arg + '] + \''; + prev = i + 2; + arg++; + break; + case 'j': + builder += formatter.slice(prev, i) + '\' + JSON.stringify(arguments[' + arg + ']) + \''; + prev = i + 2; + arg++; + break; + case '%': + builder += formatter.slice(prev, i + 1); + prev = i + 2; + i++; + break; + } + + + } else if (TO_ESCAPE[formatter[i]]) { + builder += formatter.slice(prev, i) + TO_ESCAPE[formatter[i]]; + prev = i + 1; + } + } + + builder += formatter.slice(prev) + '\';'; + cache[key] = new Function(builder); +} + + +/** + * A fast version of sprintf(), which currently only supports the %s and %j. + * This caches a formatting function for each format string that is used, so + * you should only use this sprintf() will be called many times with a single + * format string and a limited number of format strings will ever be used (in + * general this means that format strings should be string literals). + * + * @param {String} formatter A format string. + * @param {...String} var_args Values that will be formatted by %s and %j. + * @return {String} The formatted output. + */ +exports.sprintf = function(formatter, var_args) { + if (!cache[formatter]) { + populate(formatter); + } + + return cache[formatter].apply(null, arguments); +}; diff --git a/platforms/android/cordova/node_modules/elementtree/lib/treebuilder.js b/platforms/android/cordova/node_modules/elementtree/lib/treebuilder.js new file mode 100644 index 0000000..393a98f --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/lib/treebuilder.js @@ -0,0 +1,60 @@ +function TreeBuilder(element_factory) { + this._data = []; + this._elem = []; + this._last = null; + this._tail = null; + if (!element_factory) { + /* evil circular dep */ + element_factory = require('./elementtree').Element; + } + this._factory = element_factory; +} + +TreeBuilder.prototype.close = function() { + return this._last; +}; + +TreeBuilder.prototype._flush = function() { + if (this._data) { + if (this._last !== null) { + var text = this._data.join(""); + if (this._tail) { + this._last.tail = text; + } + else { + this._last.text = text; + } + } + this._data = []; + } +}; + +TreeBuilder.prototype.data = function(data) { + this._data.push(data); +}; + +TreeBuilder.prototype.start = function(tag, attrs) { + this._flush(); + var elem = this._factory(tag, attrs); + this._last = elem; + + if (this._elem.length) { + this._elem[this._elem.length - 1].append(elem); + } + + this._elem.push(elem); + + this._tail = null; +}; + +TreeBuilder.prototype.end = function(tag) { + this._flush(); + this._last = this._elem.pop(); + if (this._last.tag !== tag) { + throw new Error("end tag mismatch"); + } + this._tail = 1; + return this._last; +}; + +exports.TreeBuilder = TreeBuilder; diff --git a/platforms/android/cordova/node_modules/elementtree/lib/utils.js b/platforms/android/cordova/node_modules/elementtree/lib/utils.js new file mode 100644 index 0000000..b08a670 --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/lib/utils.js @@ -0,0 +1,72 @@ +/** + * Copyright 2011 Rackspace + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * @param {Object} hash. + * @param {Array} ignored. + */ +function items(hash, ignored) { + ignored = ignored || null; + var k, rv = []; + + function is_ignored(key) { + if (!ignored || ignored.length === 0) { + return false; + } + + return ignored.indexOf(key); + } + + for (k in hash) { + if (hash.hasOwnProperty(k) && !(is_ignored(ignored))) { + rv.push([k, hash[k]]); + } + } + + return rv; +} + + +function findall(re, str) { + var match, matches = []; + + while ((match = re.exec(str))) { + matches.push(match); + } + + return matches; +} + +function merge(a, b) { + var c = {}, attrname; + + for (attrname in a) { + if (a.hasOwnProperty(attrname)) { + c[attrname] = a[attrname]; + } + } + for (attrname in b) { + if (b.hasOwnProperty(attrname)) { + c[attrname] = b[attrname]; + } + } + return c; +} + +exports.items = items; +exports.findall = findall; +exports.merge = merge; diff --git a/platforms/android/cordova/node_modules/elementtree/package.json b/platforms/android/cordova/node_modules/elementtree/package.json new file mode 100644 index 0000000..f1a5f14 --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/package.json @@ -0,0 +1,101 @@ +{ + "_args": [ + [ + "elementtree@^0.1.6", + "/Users/steveng/repo/cordova/cordova-android" + ] + ], + "_from": "elementtree@>=0.1.6 <0.2.0", + "_id": "elementtree@0.1.6", + "_inCache": true, + "_installable": true, + "_location": "/elementtree", + "_npmUser": { + "email": "ryan@trolocsis.com", + "name": "rphillips" + }, + "_npmVersion": "1.3.24", + "_phantomChildren": {}, + "_requested": { + "name": "elementtree", + "raw": "elementtree@^0.1.6", + "rawSpec": "^0.1.6", + "scope": null, + "spec": ">=0.1.6 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/", + "/cordova-common" + ], + "_resolved": "http://registry.npmjs.org/elementtree/-/elementtree-0.1.6.tgz", + "_shasum": "2ac4c46ea30516c8c4cbdb5e3ac7418e592de20c", + "_shrinkwrap": null, + "_spec": "elementtree@^0.1.6", + "_where": "/Users/steveng/repo/cordova/cordova-android", + "author": { + "name": "Rackspace US, Inc." + }, + "bugs": { + "url": "https://github.com/racker/node-elementtree/issues" + }, + "contributors": [ + { + "name": "Paul Querna", + "email": "paul.querna@rackspace.com" + }, + { + "name": "Tomaz Muraus", + "email": "tomaz.muraus@rackspace.com" + } + ], + "dependencies": { + "sax": "0.3.5" + }, + "description": "XML Serialization and Parsing module based on Python's ElementTree.", + "devDependencies": { + "whiskey": "0.8.x" + }, + "directories": { + "lib": "lib" + }, + "dist": { + "shasum": "2ac4c46ea30516c8c4cbdb5e3ac7418e592de20c", + "tarball": "http://registry.npmjs.org/elementtree/-/elementtree-0.1.6.tgz" + }, + "engines": { + "node": ">= 0.4.0" + }, + "homepage": "https://github.com/racker/node-elementtree", + "keywords": [ + "elementtree", + "parser", + "sax", + "seralization", + "xml" + ], + "licenses": [ + { + "type": "Apache", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + } + ], + "main": "lib/elementtree.js", + "maintainers": [ + { + "name": "rphillips", + "email": "ryan@trolocsis.com" + } + ], + "name": "elementtree", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/racker/node-elementtree.git" + }, + "scripts": { + "test": "make test" + }, + "version": "0.1.6" +} diff --git a/platforms/android/cordova/node_modules/elementtree/tests/data/xml1.xml b/platforms/android/cordova/node_modules/elementtree/tests/data/xml1.xml new file mode 100644 index 0000000..72c33ae --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/tests/data/xml1.xml @@ -0,0 +1,17 @@ + + + dd + test_object_1 + 4281c348eaf83e70ddce0e07221c3d28 + 14 + application/octetstream + 2009-02-03T05:26:32.612278 + + + test_object_2 + b039efe731ad111bc1b0ef221c3849d0 + 64 + application/octetstream + 2009-02-03T05:26:32.612278 + + diff --git a/platforms/android/cordova/node_modules/elementtree/tests/data/xml2.xml b/platforms/android/cordova/node_modules/elementtree/tests/data/xml2.xml new file mode 100644 index 0000000..5f94bbd --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/tests/data/xml2.xml @@ -0,0 +1,14 @@ + + + + Hello World + + + + + + + + diff --git a/platforms/android/cordova/node_modules/elementtree/tests/test-simple.js b/platforms/android/cordova/node_modules/elementtree/tests/test-simple.js new file mode 100644 index 0000000..1fc04b8 --- /dev/null +++ b/platforms/android/cordova/node_modules/elementtree/tests/test-simple.js @@ -0,0 +1,339 @@ +/** + * Copyright 2011 Rackspace + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +var fs = require('fs'); +var path = require('path'); + +var sprintf = require('./../lib/sprintf').sprintf; +var et = require('elementtree'); +var XML = et.XML; +var ElementTree = et.ElementTree; +var Element = et.Element; +var SubElement = et.SubElement; +var SyntaxError = require('./../lib/errors').SyntaxError; + +function readFile(name) { + return fs.readFileSync(path.join(__dirname, '/data/', name), 'utf8'); +} + +exports['test_simplest'] = function(test, assert) { + /* Ported from */ + var Element = et.Element; + var root = Element('root'); + root.append(Element('one')); + root.append(Element('two')); + root.append(Element('three')); + assert.equal(3, root.len()); + assert.equal('one', root.getItem(0).tag); + assert.equal('two', root.getItem(1).tag); + assert.equal('three', root.getItem(2).tag); + test.finish(); +}; + + +exports['test_attribute_values'] = function(test, assert) { + var XML = et.XML; + var root = XML(''); + assert.equal('Alpha', root.attrib['alpha']); + assert.equal('Beta', root.attrib['beta']); + assert.equal('Gamma', root.attrib['gamma']); + test.finish(); +}; + + +exports['test_findall'] = function(test, assert) { + var XML = et.XML; + var root = XML(''); + + assert.equal(root.findall("c").length, 1); + assert.equal(root.findall(".//c").length, 2); + assert.equal(root.findall(".//b").length, 3); + assert.equal(root.findall(".//b")[0]._children.length, 1); + assert.equal(root.findall(".//b")[1]._children.length, 0); + assert.equal(root.findall(".//b")[2]._children.length, 0); + assert.deepEqual(root.findall('.//b')[0], root.getchildren()[0]); + + test.finish(); +}; + +exports['test_find'] = function(test, assert) { + var a = Element('a'); + var b = SubElement(a, 'b'); + var c = SubElement(a, 'c'); + + assert.deepEqual(a.find('./b/..'), a); + test.finish(); +}; + +exports['test_elementtree_find_qname'] = function(test, assert) { + var tree = new et.ElementTree(XML('')); + assert.deepEqual(tree.find(new et.QName('c')), tree.getroot()._children[2]); + test.finish(); +}; + +exports['test_attrib_ns_clear'] = function(test, assert) { + var attribNS = '{http://foo/bar}x'; + + var par = Element('par'); + par.set(attribNS, 'a'); + var child = SubElement(par, 'child'); + child.set(attribNS, 'b'); + + assert.equal('a', par.get(attribNS)); + assert.equal('b', child.get(attribNS)); + + par.clear(); + assert.equal(null, par.get(attribNS)); + assert.equal('b', child.get(attribNS)); + test.finish(); +}; + +exports['test_create_tree_and_parse_simple'] = function(test, assert) { + var i = 0; + var e = new Element('bar', {}); + var expected = "\n" + + 'ponies'; + + SubElement(e, "blah", {a: 11}); + SubElement(e, "blah", {a: 12}); + var se = et.SubElement(e, "gag", {a: '13', b: 'abc'}); + se.text = 'ponies'; + + se.itertext(function(text) { + assert.equal(text, 'ponies'); + i++; + }); + + assert.equal(i, 1); + var etree = new ElementTree(e); + var xml = etree.write(); + assert.equal(xml, expected); + test.finish(); +}; + +exports['test_write_with_options'] = function(test, assert) { + var i = 0; + var e = new Element('bar', {}); + var expected1 = "\n" + + '\n' + + ' \n' + + ' test\n' + + ' \n' + + ' \n' + + ' ponies\n' + + '\n'; + var expected2 = "\n" + + '\n' + + ' \n' + + ' test\n' + + ' \n' + + ' \n' + + ' ponies\n' + + '\n'; + + var expected3 = "\n" + + '\n' + + ' \n' + + ' Hello World\n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' Test & Test & Test\n' + + ' \n' + + '\n'; + + var se1 = SubElement(e, "blah", {a: 11}); + var se2 = SubElement(se1, "baz", {d: 11}); + se2.text = 'test'; + SubElement(e, "blah", {a: 12}); + var se = et.SubElement(e, "gag", {a: '13', b: 'abc'}); + se.text = 'ponies'; + + se.itertext(function(text) { + assert.equal(text, 'ponies'); + i++; + }); + + assert.equal(i, 1); + var etree = new ElementTree(e); + var xml1 = etree.write({'indent': 4}); + var xml2 = etree.write({'indent': 2}); + assert.equal(xml1, expected1); + assert.equal(xml2, expected2); + + var file = readFile('xml2.xml'); + var etree2 = et.parse(file); + var xml3 = etree2.write({'indent': 4}); + assert.equal(xml3, expected3); + test.finish(); +}; + +exports['test_parse_and_find_2'] = function(test, assert) { + var data = readFile('xml1.xml'); + var etree = et.parse(data); + + assert.equal(etree.findall('./object').length, 2); + assert.equal(etree.findall('[@name]').length, 1); + assert.equal(etree.findall('[@name="test_container_1"]').length, 1); + assert.equal(etree.findall('[@name=\'test_container_1\']').length, 1); + assert.equal(etree.findall('./object')[0].findtext('name'), 'test_object_1'); + assert.equal(etree.findtext('./object/name'), 'test_object_1'); + assert.equal(etree.findall('.//bytes').length, 2); + assert.equal(etree.findall('*/bytes').length, 2); + assert.equal(etree.findall('*/foobar').length, 0); + + test.finish(); +}; + +exports['test_namespaced_attribute'] = function(test, assert) { + var data = readFile('xml1.xml'); + var etree = et.parse(data); + + assert.equal(etree.findall('*/bytes[@android:type="cool"]').length, 1); + + test.finish(); +} + +exports['test_syntax_errors'] = function(test, assert) { + var expressions = [ './/@bar', '[@bar', '[@foo=bar]', '[@', '/bar' ]; + var errCount = 0; + var data = readFile('xml1.xml'); + var etree = et.parse(data); + + expressions.forEach(function(expression) { + try { + etree.findall(expression); + } + catch (err) { + errCount++; + } + }); + + assert.equal(errCount, expressions.length); + test.finish(); +}; + +exports['test_register_namespace'] = function(test, assert){ + var prefix = 'TESTPREFIX'; + var namespace = 'http://seriously.unknown/namespace/URI'; + var errCount = 0; + + var etree = Element(sprintf('{%s}test', namespace)); + assert.equal(et.tostring(etree, { 'xml_declaration': false}), + sprintf('', namespace)); + + et.register_namespace(prefix, namespace); + var etree = Element(sprintf('{%s}test', namespace)); + assert.equal(et.tostring(etree, { 'xml_declaration': false}), + sprintf('<%s:test xmlns:%s="%s" />', prefix, prefix, namespace)); + + try { + et.register_namespace('ns25', namespace); + } + catch (err) { + errCount++; + } + + assert.equal(errCount, 1, 'Reserved prefix used, but exception was not thrown'); + test.finish(); +}; + +exports['test_tostring'] = function(test, assert) { + var a = Element('a'); + var b = SubElement(a, 'b'); + var c = SubElement(a, 'c'); + c.text = 543; + + assert.equal(et.tostring(a, { 'xml_declaration': false }), '543'); + assert.equal(et.tostring(c, { 'xml_declaration': false }), '543'); + test.finish(); +}; + +exports['test_escape'] = function(test, assert) { + var a = Element('a'); + var b = SubElement(a, 'b'); + b.text = '&&&&<>"\n\r'; + + assert.equal(et.tostring(a, { 'xml_declaration': false }), '&&&&<>\"\n\r'); + test.finish(); +}; + +exports['test_find_null'] = function(test, assert) { + var root = Element('root'); + var node = SubElement(root, 'node'); + var leaf = SubElement(node, 'leaf'); + leaf.text = 'ipsum'; + + assert.equal(root.find('node/leaf'), leaf); + assert.equal(root.find('no-such-node/leaf'), null); + test.finish(); +}; + +exports['test_findtext_null'] = function(test, assert) { + var root = Element('root'); + var node = SubElement(root, 'node'); + var leaf = SubElement(node, 'leaf'); + leaf.text = 'ipsum'; + + assert.equal(root.findtext('node/leaf'), 'ipsum'); + assert.equal(root.findtext('no-such-node/leaf'), null); + test.finish(); +}; + +exports['test_remove'] = function(test, assert) { + var root = Element('root'); + var node1 = SubElement(root, 'node1'); + var node2 = SubElement(root, 'node2'); + var node3 = SubElement(root, 'node3'); + + assert.equal(root.len(), 3); + + root.remove(node2); + + assert.equal(root.len(), 2); + assert.equal(root.getItem(0).tag, 'node1') + assert.equal(root.getItem(1).tag, 'node3') + + test.finish(); +}; + +exports['test_cdata_write'] = function(test, assert) { + var root, etree, xml, values, value, i; + + values = [ + 'if(0>1) then true;', + 'ponies hello', + '' + ]; + + for (i = 0; i < values.length; i++) { + value = values[i]; + + root = Element('root'); + root.append(et.CData(value)); + etree = new ElementTree(root); + xml = etree.write({'xml_declaration': false}); + + assert.equal(xml, sprintf('', value)); + } + + test.finish(); +}; diff --git a/platforms/android/cordova/node_modules/glob/LICENSE b/platforms/android/cordova/node_modules/glob/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/platforms/android/cordova/node_modules/glob/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/platforms/android/cordova/node_modules/glob/README.md b/platforms/android/cordova/node_modules/glob/README.md new file mode 100644 index 0000000..063cf95 --- /dev/null +++ b/platforms/android/cordova/node_modules/glob/README.md @@ -0,0 +1,377 @@ +[![Build Status](https://travis-ci.org/isaacs/node-glob.svg?branch=master)](https://travis-ci.org/isaacs/node-glob/) [![Dependency Status](https://david-dm.org/isaacs/node-glob.svg)](https://david-dm.org/isaacs/node-glob) [![devDependency Status](https://david-dm.org/isaacs/node-glob/dev-status.svg)](https://david-dm.org/isaacs/node-glob#info=devDependencies) [![optionalDependency Status](https://david-dm.org/isaacs/node-glob/optional-status.svg)](https://david-dm.org/isaacs/node-glob#info=optionalDependencies) + +# Glob + +Match files using the patterns the shell uses, like stars and stuff. + +This is a glob implementation in JavaScript. It uses the `minimatch` +library to do its matching. + +![](oh-my-glob.gif) + +## Usage + +```javascript +var glob = require("glob") + +// options is optional +glob("**/*.js", options, function (er, files) { + // files is an array of filenames. + // If the `nonull` option is set, and nothing + // was found, then files is ["**/*.js"] + // er is an error object or null. +}) +``` + +## Glob Primer + +"Globs" are the patterns you type when you do stuff like `ls *.js` on +the command line, or put `build/*` in a `.gitignore` file. + +Before parsing the path part patterns, braced sections are expanded +into a set. Braced sections start with `{` and end with `}`, with any +number of comma-delimited sections within. Braced sections may contain +slash characters, so `a{/b/c,bcd}` would expand into `a/b/c` and `abcd`. + +The following characters have special magic meaning when used in a +path portion: + +* `*` Matches 0 or more characters in a single path portion +* `?` Matches 1 character +* `[...]` Matches a range of characters, similar to a RegExp range. + If the first character of the range is `!` or `^` then it matches + any character not in the range. +* `!(pattern|pattern|pattern)` Matches anything that does not match + any of the patterns provided. +* `?(pattern|pattern|pattern)` Matches zero or one occurrence of the + patterns provided. +* `+(pattern|pattern|pattern)` Matches one or more occurrences of the + patterns provided. +* `*(a|b|c)` Matches zero or more occurrences of the patterns provided +* `@(pattern|pat*|pat?erN)` Matches exactly one of the patterns + provided +* `**` If a "globstar" is alone in a path portion, then it matches + zero or more directories and subdirectories searching for matches. + It does not crawl symlinked directories. + +### Dots + +If a file or directory path portion has a `.` as the first character, +then it will not match any glob pattern unless that pattern's +corresponding path part also has a `.` as its first character. + +For example, the pattern `a/.*/c` would match the file at `a/.b/c`. +However the pattern `a/*/c` would not, because `*` does not start with +a dot character. + +You can make glob treat dots as normal characters by setting +`dot:true` in the options. + +### Basename Matching + +If you set `matchBase:true` in the options, and the pattern has no +slashes in it, then it will seek for any file anywhere in the tree +with a matching basename. For example, `*.js` would match +`test/simple/basic.js`. + +### Negation + +The intent for negation would be for a pattern starting with `!` to +match everything that *doesn't* match the supplied pattern. However, +the implementation is weird, and for the time being, this should be +avoided. The behavior is deprecated in version 5, and will be removed +entirely in version 6. + +### Empty Sets + +If no matching files are found, then an empty array is returned. This +differs from the shell, where the pattern itself is returned. For +example: + + $ echo a*s*d*f + a*s*d*f + +To get the bash-style behavior, set the `nonull:true` in the options. + +### See Also: + +* `man sh` +* `man bash` (Search for "Pattern Matching") +* `man 3 fnmatch` +* `man 5 gitignore` +* [minimatch documentation](https://github.com/isaacs/minimatch) + +## glob.hasMagic(pattern, [options]) + +Returns `true` if there are any special characters in the pattern, and +`false` otherwise. + +Note that the options affect the results. If `noext:true` is set in +the options object, then `+(a|b)` will not be considered a magic +pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}` +then that is considered magical, unless `nobrace:true` is set in the +options. + +## glob(pattern, [options], cb) + +* `pattern` {String} Pattern to be matched +* `options` {Object} +* `cb` {Function} + * `err` {Error | null} + * `matches` {Array} filenames found matching the pattern + +Perform an asynchronous glob search. + +## glob.sync(pattern, [options]) + +* `pattern` {String} Pattern to be matched +* `options` {Object} +* return: {Array} filenames found matching the pattern + +Perform a synchronous glob search. + +## Class: glob.Glob + +Create a Glob object by instantiating the `glob.Glob` class. + +```javascript +var Glob = require("glob").Glob +var mg = new Glob(pattern, options, cb) +``` + +It's an EventEmitter, and starts walking the filesystem to find matches +immediately. + +### new glob.Glob(pattern, [options], [cb]) + +* `pattern` {String} pattern to search for +* `options` {Object} +* `cb` {Function} Called when an error occurs, or matches are found + * `err` {Error | null} + * `matches` {Array} filenames found matching the pattern + +Note that if the `sync` flag is set in the options, then matches will +be immediately available on the `g.found` member. + +### Properties + +* `minimatch` The minimatch object that the glob uses. +* `options` The options object passed in. +* `aborted` Boolean which is set to true when calling `abort()`. There + is no way at this time to continue a glob search after aborting, but + you can re-use the statCache to avoid having to duplicate syscalls. +* `cache` Convenience object. Each field has the following possible + values: + * `false` - Path does not exist + * `true` - Path exists + * `'DIR'` - Path exists, and is not a directory + * `'FILE'` - Path exists, and is a directory + * `[file, entries, ...]` - Path exists, is a directory, and the + array value is the results of `fs.readdir` +* `statCache` Cache of `fs.stat` results, to prevent statting the same + path multiple times. +* `symlinks` A record of which paths are symbolic links, which is + relevant in resolving `**` patterns. +* `realpathCache` An optional object which is passed to `fs.realpath` + to minimize unnecessary syscalls. It is stored on the instantiated + Glob object, and may be re-used. + +### Events + +* `end` When the matching is finished, this is emitted with all the + matches found. If the `nonull` option is set, and no match was found, + then the `matches` list contains the original pattern. The matches + are sorted, unless the `nosort` flag is set. +* `match` Every time a match is found, this is emitted with the matched. +* `error` Emitted when an unexpected error is encountered, or whenever + any fs error occurs if `options.strict` is set. +* `abort` When `abort()` is called, this event is raised. + +### Methods + +* `pause` Temporarily stop the search +* `resume` Resume the search +* `abort` Stop the search forever + +### Options + +All the options that can be passed to Minimatch can also be passed to +Glob to change pattern matching behavior. Also, some have been added, +or have glob-specific ramifications. + +All options are false by default, unless otherwise noted. + +All options are added to the Glob object, as well. + +If you are running many `glob` operations, you can pass a Glob object +as the `options` argument to a subsequent operation to shortcut some +`stat` and `readdir` calls. At the very least, you may pass in shared +`symlinks`, `statCache`, `realpathCache`, and `cache` options, so that +parallel glob operations will be sped up by sharing information about +the filesystem. + +* `cwd` The current working directory in which to search. Defaults + to `process.cwd()`. +* `root` The place where patterns starting with `/` will be mounted + onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix + systems, and `C:\` or some such on Windows.) +* `dot` Include `.dot` files in normal matches and `globstar` matches. + Note that an explicit dot in a portion of the pattern will always + match dot files. +* `nomount` By default, a pattern starting with a forward-slash will be + "mounted" onto the root setting, so that a valid filesystem path is + returned. Set this flag to disable that behavior. +* `mark` Add a `/` character to directory matches. Note that this + requires additional stat calls. +* `nosort` Don't sort the results. +* `stat` Set to true to stat *all* results. This reduces performance + somewhat, and is completely unnecessary, unless `readdir` is presumed + to be an untrustworthy indicator of file existence. +* `silent` When an unusual error is encountered when attempting to + read a directory, a warning will be printed to stderr. Set the + `silent` option to true to suppress these warnings. +* `strict` When an unusual error is encountered when attempting to + read a directory, the process will just continue on in search of + other matches. Set the `strict` option to raise an error in these + cases. +* `cache` See `cache` property above. Pass in a previously generated + cache object to save some fs calls. +* `statCache` A cache of results of filesystem information, to prevent + unnecessary stat calls. While it should not normally be necessary + to set this, you may pass the statCache from one glob() call to the + options object of another, if you know that the filesystem will not + change between calls. (See "Race Conditions" below.) +* `symlinks` A cache of known symbolic links. You may pass in a + previously generated `symlinks` object to save `lstat` calls when + resolving `**` matches. +* `sync` DEPRECATED: use `glob.sync(pattern, opts)` instead. +* `nounique` In some cases, brace-expanded patterns can result in the + same file showing up multiple times in the result set. By default, + this implementation prevents duplicates in the result set. Set this + flag to disable that behavior. +* `nonull` Set to never return an empty set, instead returning a set + containing the pattern itself. This is the default in glob(3). +* `debug` Set to enable debug logging in minimatch and glob. +* `nobrace` Do not expand `{a,b}` and `{1..3}` brace sets. +* `noglobstar` Do not match `**` against multiple filenames. (Ie, + treat it as a normal `*` instead.) +* `noext` Do not match `+(a|b)` "extglob" patterns. +* `nocase` Perform a case-insensitive match. Note: on + case-insensitive filesystems, non-magic patterns will match by + default, since `stat` and `readdir` will not raise errors. +* `matchBase` Perform a basename-only match if the pattern does not + contain any slash characters. That is, `*.js` would be treated as + equivalent to `**/*.js`, matching all js files in all directories. +* `nodir` Do not match directories, only files. (Note: to match + *only* directories, simply put a `/` at the end of the pattern.) +* `ignore` Add a pattern or an array of patterns to exclude matches. +* `follow` Follow symlinked directories when expanding `**` patterns. + Note that this can result in a lot of duplicate references in the + presence of cyclic links. +* `realpath` Set to true to call `fs.realpath` on all of the results. + In the case of a symlink that cannot be resolved, the full absolute + path to the matched entry is returned (though it will usually be a + broken symlink) +* `nonegate` Suppress deprecated `negate` behavior. (See below.) + Default=true +* `nocomment` Suppress deprecated `comment` behavior. (See below.) + Default=true + +## Comparisons to other fnmatch/glob implementations + +While strict compliance with the existing standards is a worthwhile +goal, some discrepancies exist between node-glob and other +implementations, and are intentional. + +The double-star character `**` is supported by default, unless the +`noglobstar` flag is set. This is supported in the manner of bsdglob +and bash 4.3, where `**` only has special significance if it is the only +thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but +`a/**b` will not. + +Note that symlinked directories are not crawled as part of a `**`, +though their contents may match against subsequent portions of the +pattern. This prevents infinite loops and duplicates and the like. + +If an escaped pattern has no matches, and the `nonull` flag is set, +then glob returns the pattern as-provided, rather than +interpreting the character escapes. For example, +`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than +`"*a?"`. This is akin to setting the `nullglob` option in bash, except +that it does not resolve escaped pattern characters. + +If brace expansion is not disabled, then it is performed before any +other interpretation of the glob pattern. Thus, a pattern like +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are +checked for validity. Since those two are valid, matching proceeds. + +### Comments and Negation + +**Note**: In version 5 of this module, negation and comments are +**disabled** by default. You can explicitly set `nonegate:false` or +`nocomment:false` to re-enable them. They are going away entirely in +version 6. + +The intent for negation would be for a pattern starting with `!` to +match everything that *doesn't* match the supplied pattern. However, +the implementation is weird. It is better to use the `ignore` option +to set a pattern or set of patterns to exclude from matches. If you +want the "everything except *x*" type of behavior, you can use `**` as +the main pattern, and set an `ignore` for the things to exclude. + +The comments feature is added in minimatch, primarily to more easily +support use cases like ignore files, where a `#` at the start of a +line makes the pattern "empty". However, in the context of a +straightforward filesystem globber, "comments" don't make much sense. + +## Windows + +**Please only use forward-slashes in glob expressions.** + +Though windows uses either `/` or `\` as its path separator, only `/` +characters are used by this glob implementation. You must use +forward-slashes **only** in glob expressions. Back-slashes will always +be interpreted as escape characters, not path separators. + +Results from absolute patterns such as `/foo/*` are mounted onto the +root setting using `path.join`. On windows, this will by default result +in `/foo/*` matching `C:\foo\bar.txt`. + +## Race Conditions + +Glob searching, by its very nature, is susceptible to race conditions, +since it relies on directory walking and such. + +As a result, it is possible that a file that exists when glob looks for +it may have been deleted or modified by the time it returns the result. + +As part of its internal implementation, this program caches all stat +and readdir calls that it makes, in order to cut down on system +overhead. However, this also makes it even more susceptible to races, +especially if the cache or statCache objects are reused between glob +calls. + +Users are thus advised not to use a glob result as a guarantee of +filesystem state in the face of rapid changes. For the vast majority +of operations, this is never a problem. + +## Contributing + +Any change to behavior (including bugfixes) must come with a test. + +Patches that fail tests or reduce performance will be rejected. + +``` +# to run tests +npm test + +# to re-generate test fixtures +npm run test-regen + +# to benchmark against bash/zsh +npm run bench + +# to profile javascript +npm run prof +``` diff --git a/platforms/android/cordova/node_modules/glob/common.js b/platforms/android/cordova/node_modules/glob/common.js new file mode 100644 index 0000000..e36a631 --- /dev/null +++ b/platforms/android/cordova/node_modules/glob/common.js @@ -0,0 +1,245 @@ +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern) + } + + return { + matcher: new Minimatch(pattern), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = options.cwd + self.changedCwd = path.resolve(options.cwd) !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + self.nomount = !!options.nomount + + // disable comments and negation unless the user explicitly + // passes in false as the option. + options.nonegate = options.nonegate === false ? false : true + options.nocomment = options.nocomment === false ? false : true + deprecationWarning(options) + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +// TODO(isaacs): remove entirely in v6 +// exported to reset in tests +exports.deprecationWarned +function deprecationWarning(options) { + if (!options.nonegate || !options.nocomment) { + if (process.noDeprecation !== true && !exports.deprecationWarned) { + var msg = 'glob WARNING: comments and negation will be disabled in v6' + if (process.throwDeprecation) + throw new Error(msg) + else if (process.traceDeprecation) + console.trace(msg) + else + console.error(msg) + + exports.deprecationWarned = true + } + } +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + return !(/\/$/.test(e)) + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} diff --git a/platforms/android/cordova/node_modules/glob/glob.js b/platforms/android/cordova/node_modules/glob/glob.js new file mode 100644 index 0000000..022d2ac --- /dev/null +++ b/platforms/android/cordova/node_modules/glob/glob.js @@ -0,0 +1,752 @@ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +glob.hasMagic = function (pattern, options_) { + var options = util._extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + var n = this.minimatch.set.length + this._processing = 0 + this.matches = new Array(n) + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + + function done () { + --self._processing + if (self._processing <= 0) + self._finish() + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + fs.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (this.matches[index][e]) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = this._makeAbs(e) + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + if (this.mark) + e = this._mark(e) + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er) + return cb() + + var isSym = lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && !stat.isDirectory()) + return cb(null, false, stat) + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return cb() + + return cb(null, c, stat) +} diff --git a/platforms/android/cordova/node_modules/glob/package.json b/platforms/android/cordova/node_modules/glob/package.json new file mode 100644 index 0000000..7c398ae --- /dev/null +++ b/platforms/android/cordova/node_modules/glob/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + "glob@^5.0.13", + "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common" + ] + ], + "_from": "glob@>=5.0.13 <6.0.0", + "_id": "glob@5.0.15", + "_inCache": true, + "_installable": true, + "_location": "/glob", + "_nodeVersion": "4.0.0", + "_npmUser": { + "email": "isaacs@npmjs.com", + "name": "isaacs" + }, + "_npmVersion": "3.3.2", + "_phantomChildren": {}, + "_requested": { + "name": "glob", + "raw": "glob@^5.0.13", + "rawSpec": "^5.0.13", + "scope": null, + "spec": ">=5.0.13 <6.0.0", + "type": "range" + }, + "_requiredBy": [ + "/cordova-common" + ], + "_resolved": "http://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "_shasum": "1bc936b9e02f4a603fcc222ecf7633d30b8b93b1", + "_shrinkwrap": null, + "_spec": "glob@^5.0.13", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/node-glob/issues" + }, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "description": "a little globber", + "devDependencies": { + "mkdirp": "0", + "rimraf": "^2.2.8", + "tap": "^1.1.4", + "tick": "0.0.6" + }, + "directories": {}, + "dist": { + "shasum": "1bc936b9e02f4a603fcc222ecf7633d30b8b93b1", + "tarball": "http://registry.npmjs.org/glob/-/glob-5.0.15.tgz" + }, + "engines": { + "node": "*" + }, + "files": [ + "common.js", + "glob.js", + "sync.js" + ], + "gitHead": "3a7e71d453dd80e75b196fd262dd23ed54beeceb", + "homepage": "https://github.com/isaacs/node-glob#readme", + "license": "ISC", + "main": "glob.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "glob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "scripts": { + "bench": "bash benchmark.sh", + "benchclean": "node benchclean.js", + "prepublish": "npm run benchclean", + "prof": "bash prof.sh && cat profile.txt", + "profclean": "rm -f v8.log profile.txt", + "test": "tap test/*.js --cov", + "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js" + }, + "version": "5.0.15" +} diff --git a/platforms/android/cordova/node_modules/glob/sync.js b/platforms/android/cordova/node_modules/glob/sync.js new file mode 100644 index 0000000..09883d2 --- /dev/null +++ b/platforms/android/cordova/node_modules/glob/sync.js @@ -0,0 +1,460 @@ +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = fs.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this.matches[index][e] = true + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + var abs = this._makeAbs(e) + if (this.mark) + e = this._mark(e) + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[this._makeAbs(e)] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + // lstat failed, doesn't exist + return null + } + + var isSym = lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this.matches[index][prefix] = true +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + return false + } + + if (lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} diff --git a/platforms/android/cordova/node_modules/inflight/.eslintrc b/platforms/android/cordova/node_modules/inflight/.eslintrc new file mode 100644 index 0000000..b7a1550 --- /dev/null +++ b/platforms/android/cordova/node_modules/inflight/.eslintrc @@ -0,0 +1,17 @@ +{ + "env" : { + "node" : true + }, + "rules" : { + "semi": [2, "never"], + "strict": 0, + "quotes": [1, "single", "avoid-escape"], + "no-use-before-define": 0, + "curly": 0, + "no-underscore-dangle": 0, + "no-lonely-if": 1, + "no-unused-vars": [2, {"vars" : "all", "args" : "after-used"}], + "no-mixed-requires": 0, + "space-infix-ops": 0 + } +} diff --git a/platforms/android/cordova/node_modules/inflight/LICENSE b/platforms/android/cordova/node_modules/inflight/LICENSE new file mode 100644 index 0000000..05eeeb8 --- /dev/null +++ b/platforms/android/cordova/node_modules/inflight/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/platforms/android/cordova/node_modules/inflight/README.md b/platforms/android/cordova/node_modules/inflight/README.md new file mode 100644 index 0000000..6dc8929 --- /dev/null +++ b/platforms/android/cordova/node_modules/inflight/README.md @@ -0,0 +1,37 @@ +# inflight + +Add callbacks to requests in flight to avoid async duplication + +## USAGE + +```javascript +var inflight = require('inflight') + +// some request that does some stuff +function req(key, callback) { + // key is any random string. like a url or filename or whatever. + // + // will return either a falsey value, indicating that the + // request for this key is already in flight, or a new callback + // which when called will call all callbacks passed to inflightk + // with the same key + callback = inflight(key, callback) + + // If we got a falsey value back, then there's already a req going + if (!callback) return + + // this is where you'd fetch the url or whatever + // callback is also once()-ified, so it can safely be assigned + // to multiple events etc. First call wins. + setTimeout(function() { + callback(null, key) + }, 100) +} + +// only assigns a single setTimeout +// when it dings, all cbs get called +req('foo', cb1) +req('foo', cb2) +req('foo', cb3) +req('foo', cb4) +``` diff --git a/platforms/android/cordova/node_modules/inflight/inflight.js b/platforms/android/cordova/node_modules/inflight/inflight.js new file mode 100644 index 0000000..8bc96cb --- /dev/null +++ b/platforms/android/cordova/node_modules/inflight/inflight.js @@ -0,0 +1,44 @@ +var wrappy = require('wrappy') +var reqs = Object.create(null) +var once = require('once') + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} diff --git a/platforms/android/cordova/node_modules/inflight/package.json b/platforms/android/cordova/node_modules/inflight/package.json new file mode 100644 index 0000000..3bc7cf7 --- /dev/null +++ b/platforms/android/cordova/node_modules/inflight/package.json @@ -0,0 +1,86 @@ +{ + "_args": [ + [ + "inflight@^1.0.4", + "/Users/steveng/repo/cordova/cordova-android/node_modules/glob" + ] + ], + "_from": "inflight@>=1.0.4 <2.0.0", + "_id": "inflight@1.0.4", + "_inCache": true, + "_installable": true, + "_location": "/inflight", + "_nodeVersion": "0.10.32", + "_npmUser": { + "email": "ogd@aoaioxxysz.net", + "name": "othiym23" + }, + "_npmVersion": "2.1.3", + "_phantomChildren": {}, + "_requested": { + "name": "inflight", + "raw": "inflight@^1.0.4", + "rawSpec": "^1.0.4", + "scope": null, + "spec": ">=1.0.4 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob" + ], + "_resolved": "http://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", + "_shasum": "6cbb4521ebd51ce0ec0a936bfd7657ef7e9b172a", + "_shrinkwrap": null, + "_spec": "inflight@^1.0.4", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/glob", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/inflight/issues" + }, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + }, + "description": "Add callbacks to requests in flight to avoid async duplication", + "devDependencies": { + "tap": "^0.4.10" + }, + "directories": {}, + "dist": { + "shasum": "6cbb4521ebd51ce0ec0a936bfd7657ef7e9b172a", + "tarball": "http://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz" + }, + "gitHead": "c7b5531d572a867064d4a1da9e013e8910b7d1ba", + "homepage": "https://github.com/isaacs/inflight", + "license": "ISC", + "main": "inflight.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + }, + { + "name": "othiym23", + "email": "ogd@aoaioxxysz.net" + }, + { + "name": "iarna", + "email": "me@re-becca.org" + } + ], + "name": "inflight", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/inflight.git" + }, + "scripts": { + "test": "tap test.js" + }, + "version": "1.0.4" +} diff --git a/platforms/android/cordova/node_modules/inflight/test.js b/platforms/android/cordova/node_modules/inflight/test.js new file mode 100644 index 0000000..2bb75b3 --- /dev/null +++ b/platforms/android/cordova/node_modules/inflight/test.js @@ -0,0 +1,97 @@ +var test = require('tap').test +var inf = require('./inflight.js') + + +function req (key, cb) { + cb = inf(key, cb) + if (cb) setTimeout(function () { + cb(key) + cb(key) + }) + return cb +} + +test('basic', function (t) { + var calleda = false + var a = req('key', function (k) { + t.notOk(calleda) + calleda = true + t.equal(k, 'key') + if (calledb) t.end() + }) + t.ok(a, 'first returned cb function') + + var calledb = false + var b = req('key', function (k) { + t.notOk(calledb) + calledb = true + t.equal(k, 'key') + if (calleda) t.end() + }) + + t.notOk(b, 'second should get falsey inflight response') +}) + +test('timing', function (t) { + var expect = [ + 'method one', + 'start one', + 'end one', + 'two', + 'tick', + 'three' + ] + var i = 0 + + function log (m) { + t.equal(m, expect[i], m + ' === ' + expect[i]) + ++i + if (i === expect.length) + t.end() + } + + function method (name, cb) { + log('method ' + name) + process.nextTick(cb) + } + + var one = inf('foo', function () { + log('start one') + var three = inf('foo', function () { + log('three') + }) + if (three) method('three', three) + log('end one') + }) + + method('one', one) + + var two = inf('foo', function () { + log('two') + }) + if (two) method('one', two) + + process.nextTick(log.bind(null, 'tick')) +}) + +test('parameters', function (t) { + t.plan(8) + + var a = inf('key', function (first, second, third) { + t.equal(first, 1) + t.equal(second, 2) + t.equal(third, 3) + }) + t.ok(a, 'first returned cb function') + + var b = inf('key', function (first, second, third) { + t.equal(first, 1) + t.equal(second, 2) + t.equal(third, 3) + }) + t.notOk(b, 'second should get falsey inflight response') + + setTimeout(function () { + a(1, 2, 3) + }) +}) diff --git a/platforms/android/cordova/node_modules/inherits/LICENSE b/platforms/android/cordova/node_modules/inherits/LICENSE new file mode 100644 index 0000000..dea3013 --- /dev/null +++ b/platforms/android/cordova/node_modules/inherits/LICENSE @@ -0,0 +1,16 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/platforms/android/cordova/node_modules/inherits/README.md b/platforms/android/cordova/node_modules/inherits/README.md new file mode 100644 index 0000000..b1c5665 --- /dev/null +++ b/platforms/android/cordova/node_modules/inherits/README.md @@ -0,0 +1,42 @@ +Browser-friendly inheritance fully compatible with standard node.js +[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). + +This package exports standard `inherits` from node.js `util` module in +node environment, but also provides alternative browser-friendly +implementation through [browser +field](https://gist.github.com/shtylman/4339901). Alternative +implementation is a literal copy of standard one located in standalone +module to avoid requiring of `util`. It also has a shim for old +browsers with no `Object.create` support. + +While keeping you sure you are using standard `inherits` +implementation in node.js environment, it allows bundlers such as +[browserify](https://github.com/substack/node-browserify) to not +include full `util` package to your client code if all you need is +just `inherits` function. It worth, because browser shim for `util` +package is large and `inherits` is often the single function you need +from it. + +It's recommended to use this package instead of +`require('util').inherits` for any code that has chances to be used +not only in node.js but in browser too. + +## usage + +```js +var inherits = require('inherits'); +// then use exactly as the standard one +``` + +## note on version ~1.0 + +Version ~1.0 had completely different motivation and is not compatible +neither with 2.0 nor with standard node.js `inherits`. + +If you are using version ~1.0 and planning to switch to ~2.0, be +careful: + +* new version uses `super_` instead of `super` for referencing + superclass +* new version overwrites current prototype while old one preserves any + existing fields on it diff --git a/platforms/android/cordova/node_modules/inherits/inherits.js b/platforms/android/cordova/node_modules/inherits/inherits.js new file mode 100644 index 0000000..29f5e24 --- /dev/null +++ b/platforms/android/cordova/node_modules/inherits/inherits.js @@ -0,0 +1 @@ +module.exports = require('util').inherits diff --git a/platforms/android/cordova/node_modules/inherits/inherits_browser.js b/platforms/android/cordova/node_modules/inherits/inherits_browser.js new file mode 100644 index 0000000..c1e78a7 --- /dev/null +++ b/platforms/android/cordova/node_modules/inherits/inherits_browser.js @@ -0,0 +1,23 @@ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} diff --git a/platforms/android/cordova/node_modules/inherits/package.json b/platforms/android/cordova/node_modules/inherits/package.json new file mode 100644 index 0000000..6313b8e --- /dev/null +++ b/platforms/android/cordova/node_modules/inherits/package.json @@ -0,0 +1,77 @@ +{ + "_args": [ + [ + "inherits@2", + "/Users/steveng/repo/cordova/cordova-android/node_modules/glob" + ] + ], + "_from": "inherits@>=2.0.0 <3.0.0", + "_id": "inherits@2.0.1", + "_inCache": true, + "_installable": true, + "_location": "/inherits", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "1.3.8", + "_phantomChildren": {}, + "_requested": { + "name": "inherits", + "raw": "inherits@2", + "rawSpec": "2", + "scope": null, + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob" + ], + "_resolved": "http://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", + "_shrinkwrap": null, + "_spec": "inherits@2", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/glob", + "browser": "./inherits_browser.js", + "bugs": { + "url": "https://github.com/isaacs/inherits/issues" + }, + "dependencies": {}, + "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", + "tarball": "http://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "homepage": "https://github.com/isaacs/inherits#readme", + "keywords": [ + "browser", + "browserify", + "class", + "inheritance", + "inherits", + "klass", + "object-oriented", + "oop" + ], + "license": "ISC", + "main": "./inherits.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "inherits", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/inherits.git" + }, + "scripts": { + "test": "node test" + }, + "version": "2.0.1" +} diff --git a/platforms/android/cordova/node_modules/inherits/test.js b/platforms/android/cordova/node_modules/inherits/test.js new file mode 100644 index 0000000..fc53012 --- /dev/null +++ b/platforms/android/cordova/node_modules/inherits/test.js @@ -0,0 +1,25 @@ +var inherits = require('./inherits.js') +var assert = require('assert') + +function test(c) { + assert(c.constructor === Child) + assert(c.constructor.super_ === Parent) + assert(Object.getPrototypeOf(c) === Child.prototype) + assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype) + assert(c instanceof Child) + assert(c instanceof Parent) +} + +function Child() { + Parent.call(this) + test(this) +} + +function Parent() {} + +inherits(Child, Parent) + +var c = new Child +test(c) + +console.log('ok') diff --git a/platforms/android/cordova/node_modules/lodash/LICENSE b/platforms/android/cordova/node_modules/lodash/LICENSE new file mode 100644 index 0000000..9cd87e5 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/cordova/node_modules/lodash/README.md b/platforms/android/cordova/node_modules/lodash/README.md new file mode 100644 index 0000000..fd98e5c --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/README.md @@ -0,0 +1,121 @@ +# lodash v3.10.1 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) exported as [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) modules. + +Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli): +```bash +$ lodash modularize modern exports=node -o ./ +$ lodash modern -d -o ./index.js +``` + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash +``` + +In Node.js/io.js: + +```js +// load the modern build +var _ = require('lodash'); +// or a method category +var array = require('lodash/array'); +// or a method (great for smaller builds with browserify/webpack) +var chunk = require('lodash/array/chunk'); +``` + +See the [package source](https://github.com/lodash/lodash/tree/3.10.1-npm) for more details. + +**Note:**
    +Don’t assign values to the [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL.
    +Install [n_](https://www.npmjs.com/package/n_) for a REPL that includes lodash by default. + +## Module formats + +lodash is also available in a variety of other builds & module formats. + + * npm packages for [modern](https://www.npmjs.com/package/lodash), [compatibility](https://www.npmjs.com/package/lodash-compat), & [per method](https://www.npmjs.com/browse/keyword/lodash-modularized) builds + * AMD modules for [modern](https://github.com/lodash/lodash/tree/3.10.1-amd) & [compatibility](https://github.com/lodash/lodash-compat/tree/3.10.1-amd) builds + * ES modules for the [modern](https://github.com/lodash/lodash/tree/3.10.1-es) build + +## Further Reading + + * [API Documentation](https://lodash.com/docs) + * [Build Differences](https://github.com/lodash/lodash/wiki/Build-Differences) + * [Changelog](https://github.com/lodash/lodash/wiki/Changelog) + * [Roadmap](https://github.com/lodash/lodash/wiki/Roadmap) + * [More Resources](https://github.com/lodash/lodash/wiki/Resources) + +## Features + + * ~100% [code coverage](https://coveralls.io/r/lodash) + * Follows [semantic versioning](http://semver.org/) for releases + * [Lazily evaluated](http://filimanjaro.com/blog/2014/introducing-lazy-evaluation/) chaining + * [_(…)](https://lodash.com/docs#_) supports implicit chaining + * [_.ary](https://lodash.com/docs#ary) & [_.rearg](https://lodash.com/docs#rearg) to change function argument limits & order + * [_.at](https://lodash.com/docs#at) for cherry-picking collection values + * [_.attempt](https://lodash.com/docs#attempt) to execute functions which may error without a try-catch + * [_.before](https://lodash.com/docs#before) to complement [_.after](https://lodash.com/docs#after) + * [_.bindKey](https://lodash.com/docs#bindKey) for binding [*“lazyâ€*](http://michaux.ca/articles/lazy-function-definition-pattern) defined methods + * [_.chunk](https://lodash.com/docs#chunk) for splitting an array into chunks of a given size + * [_.clone](https://lodash.com/docs#clone) supports shallow cloning of `Date` & `RegExp` objects + * [_.cloneDeep](https://lodash.com/docs#cloneDeep) for deep cloning arrays & objects + * [_.curry](https://lodash.com/docs#curry) & [_.curryRight](https://lodash.com/docs#curryRight) for creating [curried](http://hughfdjackson.com/javascript/why-curry-helps/) functions + * [_.debounce](https://lodash.com/docs#debounce) & [_.throttle](https://lodash.com/docs#throttle) are cancelable & accept options for more control + * [_.defaultsDeep](https://lodash.com/docs#defaultsDeep) for recursively assigning default properties + * [_.fill](https://lodash.com/docs#fill) to fill arrays with values + * [_.findKey](https://lodash.com/docs#findKey) for finding keys + * [_.flow](https://lodash.com/docs#flow) to complement [_.flowRight](https://lodash.com/docs#flowRight) (a.k.a `_.compose`) + * [_.forEach](https://lodash.com/docs#forEach) supports exiting early + * [_.forIn](https://lodash.com/docs#forIn) for iterating all enumerable properties + * [_.forOwn](https://lodash.com/docs#forOwn) for iterating own properties + * [_.get](https://lodash.com/docs#get) & [_.set](https://lodash.com/docs#set) for deep property getting & setting + * [_.gt](https://lodash.com/docs#gt), [_.gte](https://lodash.com/docs#gte), [_.lt](https://lodash.com/docs#lt), & [_.lte](https://lodash.com/docs#lte) relational methods + * [_.inRange](https://lodash.com/docs#inRange) for checking whether a number is within a given range + * [_.isNative](https://lodash.com/docs#isNative) to check for native functions + * [_.isPlainObject](https://lodash.com/docs#isPlainObject) & [_.toPlainObject](https://lodash.com/docs#toPlainObject) to check for & convert to `Object` objects + * [_.isTypedArray](https://lodash.com/docs#isTypedArray) to check for typed arrays + * [_.mapKeys](https://lodash.com/docs#mapKeys) for mapping keys to an object + * [_.matches](https://lodash.com/docs#matches) supports deep object comparisons + * [_.matchesProperty](https://lodash.com/docs#matchesProperty) to complement [_.matches](https://lodash.com/docs#matches) & [_.property](https://lodash.com/docs#property) + * [_.merge](https://lodash.com/docs#merge) for a deep [_.extend](https://lodash.com/docs#extend) + * [_.method](https://lodash.com/docs#method) & [_.methodOf](https://lodash.com/docs#methodOf) to create functions that invoke methods + * [_.modArgs](https://lodash.com/docs#modArgs) for more advanced functional composition + * [_.parseInt](https://lodash.com/docs#parseInt) for consistent cross-environment behavior + * [_.pull](https://lodash.com/docs#pull), [_.pullAt](https://lodash.com/docs#pullAt), & [_.remove](https://lodash.com/docs#remove) for mutating arrays + * [_.random](https://lodash.com/docs#random) supports returning floating-point numbers + * [_.restParam](https://lodash.com/docs#restParam) & [_.spread](https://lodash.com/docs#spread) for applying rest parameters & spreading arguments to functions + * [_.runInContext](https://lodash.com/docs#runInContext) for collisionless mixins & easier mocking + * [_.slice](https://lodash.com/docs#slice) for creating subsets of array-like values + * [_.sortByAll](https://lodash.com/docs#sortByAll) & [_.sortByOrder](https://lodash.com/docs#sortByOrder) for sorting by multiple properties & orders + * [_.support](https://lodash.com/docs#support) for flagging environment features + * [_.template](https://lodash.com/docs#template) supports [*“importsâ€*](https://lodash.com/docs#templateSettings-imports) options & [ES template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components) + * [_.transform](https://lodash.com/docs#transform) as a powerful alternative to [_.reduce](https://lodash.com/docs#reduce) for transforming objects + * [_.unzipWith](https://lodash.com/docs#unzipWith) & [_.zipWith](https://lodash.com/docs#zipWith) to specify how grouped values should be combined + * [_.valuesIn](https://lodash.com/docs#valuesIn) for getting values of all enumerable properties + * [_.xor](https://lodash.com/docs#xor) to complement [_.difference](https://lodash.com/docs#difference), [_.intersection](https://lodash.com/docs#intersection), & [_.union](https://lodash.com/docs#union) + * [_.add](https://lodash.com/docs#add), [_.round](https://lodash.com/docs#round), [_.sum](https://lodash.com/docs#sum), & + [more](https://lodash.com/docs "_.ceil & _.floor") math methods + * [_.bind](https://lodash.com/docs#bind), [_.curry](https://lodash.com/docs#curry), [_.partial](https://lodash.com/docs#partial), & + [more](https://lodash.com/docs "_.bindKey, _.curryRight, _.partialRight") support customizable argument placeholders + * [_.capitalize](https://lodash.com/docs#capitalize), [_.trim](https://lodash.com/docs#trim), & + [more](https://lodash.com/docs "_.camelCase, _.deburr, _.endsWith, _.escapeRegExp, _.kebabCase, _.pad, _.padLeft, _.padRight, _.repeat, _.snakeCase, _.startCase, _.startsWith, _.trimLeft, _.trimRight, _.trunc, _.words") string methods + * [_.clone](https://lodash.com/docs#clone), [_.isEqual](https://lodash.com/docs#isEqual), & + [more](https://lodash.com/docs "_.assign, _.cloneDeep, _.merge") accept customizer callbacks + * [_.dropWhile](https://lodash.com/docs#dropWhile), [_.takeWhile](https://lodash.com/docs#takeWhile), & + [more](https://lodash.com/docs "_.drop, _.dropRight, _.dropRightWhile, _.take, _.takeRight, _.takeRightWhile") to complement [_.first](https://lodash.com/docs#first), [_.initial](https://lodash.com/docs#initial), [_.last](https://lodash.com/docs#last), & [_.rest](https://lodash.com/docs#rest) + * [_.findLast](https://lodash.com/docs#findLast), [_.findLastKey](https://lodash.com/docs#findLastKey), & + [more](https://lodash.com/docs "_.curryRight, _.dropRight, _.dropRightWhile, _.flowRight, _.forEachRight, _.forInRight, _.forOwnRight, _.padRight, partialRight, _.takeRight, _.trimRight, _.takeRightWhile") right-associative methods + * [_.includes](https://lodash.com/docs#includes), [_.toArray](https://lodash.com/docs#toArray), & + [more](https://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.findLast, _.findWhere, _.forEach, _.forEachRight, _.groupBy, _.indexBy, _.invoke, _.map, _.max, _.min, _.partition, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.size, _.some, _.sortBy, _.sortByAll, _.sortByOrder, _.sum, _.where") accept strings + * [_#commit](https://lodash.com/docs#prototype-commit) & [_#plant](https://lodash.com/docs#prototype-plant) for working with chain sequences + * [_#thru](https://lodash.com/docs#thru) to pass values thru a chain sequence + +## Support + +Tested in Chrome 43-44, Firefox 38-39, IE 6-11, MS Edge, Safari 5-8, ChakraNode 0.12.2, io.js 2.5.0, Node.js 0.8.28, 0.10.40, & 0.12.7, PhantomJS 1.9.8, RingoJS 0.11, & Rhino 1.7.6. +Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available. Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing. diff --git a/platforms/android/cordova/node_modules/lodash/array.js b/platforms/android/cordova/node_modules/lodash/array.js new file mode 100644 index 0000000..e5121fa --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array.js @@ -0,0 +1,44 @@ +module.exports = { + 'chunk': require('./array/chunk'), + 'compact': require('./array/compact'), + 'difference': require('./array/difference'), + 'drop': require('./array/drop'), + 'dropRight': require('./array/dropRight'), + 'dropRightWhile': require('./array/dropRightWhile'), + 'dropWhile': require('./array/dropWhile'), + 'fill': require('./array/fill'), + 'findIndex': require('./array/findIndex'), + 'findLastIndex': require('./array/findLastIndex'), + 'first': require('./array/first'), + 'flatten': require('./array/flatten'), + 'flattenDeep': require('./array/flattenDeep'), + 'head': require('./array/head'), + 'indexOf': require('./array/indexOf'), + 'initial': require('./array/initial'), + 'intersection': require('./array/intersection'), + 'last': require('./array/last'), + 'lastIndexOf': require('./array/lastIndexOf'), + 'object': require('./array/object'), + 'pull': require('./array/pull'), + 'pullAt': require('./array/pullAt'), + 'remove': require('./array/remove'), + 'rest': require('./array/rest'), + 'slice': require('./array/slice'), + 'sortedIndex': require('./array/sortedIndex'), + 'sortedLastIndex': require('./array/sortedLastIndex'), + 'tail': require('./array/tail'), + 'take': require('./array/take'), + 'takeRight': require('./array/takeRight'), + 'takeRightWhile': require('./array/takeRightWhile'), + 'takeWhile': require('./array/takeWhile'), + 'union': require('./array/union'), + 'uniq': require('./array/uniq'), + 'unique': require('./array/unique'), + 'unzip': require('./array/unzip'), + 'unzipWith': require('./array/unzipWith'), + 'without': require('./array/without'), + 'xor': require('./array/xor'), + 'zip': require('./array/zip'), + 'zipObject': require('./array/zipObject'), + 'zipWith': require('./array/zipWith') +}; diff --git a/platforms/android/cordova/node_modules/lodash/array/chunk.js b/platforms/android/cordova/node_modules/lodash/array/chunk.js new file mode 100644 index 0000000..c8be1fb --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/chunk.js @@ -0,0 +1,46 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeFloor = Math.floor, + nativeMax = Math.max; + +/** + * Creates an array of elements split into groups the length of `size`. + * If `collection` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ +function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size == null) { + size = 1; + } else { + size = nativeMax(nativeFloor(size) || 1, 1); + } + var index = 0, + length = array ? array.length : 0, + resIndex = -1, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[++resIndex] = baseSlice(array, index, (index += size)); + } + return result; +} + +module.exports = chunk; diff --git a/platforms/android/cordova/node_modules/lodash/array/compact.js b/platforms/android/cordova/node_modules/lodash/array/compact.js new file mode 100644 index 0000000..1dc1c55 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/compact.js @@ -0,0 +1,30 @@ +/** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ +function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[++resIndex] = value; + } + } + return result; +} + +module.exports = compact; diff --git a/platforms/android/cordova/node_modules/lodash/array/difference.js b/platforms/android/cordova/node_modules/lodash/array/difference.js new file mode 100644 index 0000000..128932a --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/difference.js @@ -0,0 +1,29 @@ +var baseDifference = require('../internal/baseDifference'), + baseFlatten = require('../internal/baseFlatten'), + isArrayLike = require('../internal/isArrayLike'), + isObjectLike = require('../internal/isObjectLike'), + restParam = require('../function/restParam'); + +/** + * Creates an array of unique `array` values not included in the other + * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([1, 2, 3], [4, 2]); + * // => [1, 3] + */ +var difference = restParam(function(array, values) { + return (isObjectLike(array) && isArrayLike(array)) + ? baseDifference(array, baseFlatten(values, false, true)) + : []; +}); + +module.exports = difference; diff --git a/platforms/android/cordova/node_modules/lodash/array/drop.js b/platforms/android/cordova/node_modules/lodash/array/drop.js new file mode 100644 index 0000000..039a0b5 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/drop.js @@ -0,0 +1,39 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ +function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, n < 0 ? 0 : n); +} + +module.exports = drop; diff --git a/platforms/android/cordova/node_modules/lodash/array/dropRight.js b/platforms/android/cordova/node_modules/lodash/array/dropRight.js new file mode 100644 index 0000000..14b5eb6 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/dropRight.js @@ -0,0 +1,40 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ +function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, 0, n < 0 ? 0 : n); +} + +module.exports = dropRight; diff --git a/platforms/android/cordova/node_modules/lodash/array/dropRightWhile.js b/platforms/android/cordova/node_modules/lodash/array/dropRightWhile.js new file mode 100644 index 0000000..be158bd --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/dropRightWhile.js @@ -0,0 +1,59 @@ +var baseCallback = require('../internal/baseCallback'), + baseWhile = require('../internal/baseWhile'); + +/** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that match the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [1] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); + * // => ['barney'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ +function dropRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, baseCallback(predicate, thisArg, 3), true, true) + : []; +} + +module.exports = dropRightWhile; diff --git a/platforms/android/cordova/node_modules/lodash/array/dropWhile.js b/platforms/android/cordova/node_modules/lodash/array/dropWhile.js new file mode 100644 index 0000000..d9eabae --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/dropWhile.js @@ -0,0 +1,59 @@ +var baseCallback = require('../internal/baseCallback'), + baseWhile = require('../internal/baseWhile'); + +/** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [3] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropWhile(users, 'active', false), 'user'); + * // => ['pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ +function dropWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, baseCallback(predicate, thisArg, 3), true) + : []; +} + +module.exports = dropWhile; diff --git a/platforms/android/cordova/node_modules/lodash/array/fill.js b/platforms/android/cordova/node_modules/lodash/array/fill.js new file mode 100644 index 0000000..2c8f6da --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/fill.js @@ -0,0 +1,44 @@ +var baseFill = require('../internal/baseFill'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8], '*', 1, 2); + * // => [4, '*', 8] + */ +function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); +} + +module.exports = fill; diff --git a/platforms/android/cordova/node_modules/lodash/array/findIndex.js b/platforms/android/cordova/node_modules/lodash/array/findIndex.js new file mode 100644 index 0000000..2a6b8e1 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/findIndex.js @@ -0,0 +1,53 @@ +var createFindIndex = require('../internal/createFindIndex'); + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(chr) { + * return chr.user == 'barney'; + * }); + * // => 0 + * + * // using the `_.matches` callback shorthand + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // using the `_.matchesProperty` callback shorthand + * _.findIndex(users, 'active', false); + * // => 0 + * + * // using the `_.property` callback shorthand + * _.findIndex(users, 'active'); + * // => 2 + */ +var findIndex = createFindIndex(); + +module.exports = findIndex; diff --git a/platforms/android/cordova/node_modules/lodash/array/findLastIndex.js b/platforms/android/cordova/node_modules/lodash/array/findLastIndex.js new file mode 100644 index 0000000..d6d8eca --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/findLastIndex.js @@ -0,0 +1,53 @@ +var createFindIndex = require('../internal/createFindIndex'); + +/** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(chr) { + * return chr.user == 'pebbles'; + * }); + * // => 2 + * + * // using the `_.matches` callback shorthand + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastIndex(users, 'active', false); + * // => 2 + * + * // using the `_.property` callback shorthand + * _.findLastIndex(users, 'active'); + * // => 0 + */ +var findLastIndex = createFindIndex(true); + +module.exports = findLastIndex; diff --git a/platforms/android/cordova/node_modules/lodash/array/first.js b/platforms/android/cordova/node_modules/lodash/array/first.js new file mode 100644 index 0000000..b3b9c79 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/first.js @@ -0,0 +1,22 @@ +/** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias head + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([]); + * // => undefined + */ +function first(array) { + return array ? array[0] : undefined; +} + +module.exports = first; diff --git a/platforms/android/cordova/node_modules/lodash/array/flatten.js b/platforms/android/cordova/node_modules/lodash/array/flatten.js new file mode 100644 index 0000000..dc2eff8 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/flatten.js @@ -0,0 +1,32 @@ +var baseFlatten = require('../internal/baseFlatten'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it's only flattened a single level. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, 3, [4]]]); + * // => [1, 2, 3, [4]] + * + * // using `isDeep` + * _.flatten([1, [2, 3, [4]]], true); + * // => [1, 2, 3, 4] + */ +function flatten(array, isDeep, guard) { + var length = array ? array.length : 0; + if (guard && isIterateeCall(array, isDeep, guard)) { + isDeep = false; + } + return length ? baseFlatten(array, isDeep) : []; +} + +module.exports = flatten; diff --git a/platforms/android/cordova/node_modules/lodash/array/flattenDeep.js b/platforms/android/cordova/node_modules/lodash/array/flattenDeep.js new file mode 100644 index 0000000..9f775fe --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/flattenDeep.js @@ -0,0 +1,21 @@ +var baseFlatten = require('../internal/baseFlatten'); + +/** + * Recursively flattens a nested array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to recursively flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, 3, [4]]]); + * // => [1, 2, 3, 4] + */ +function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, true) : []; +} + +module.exports = flattenDeep; diff --git a/platforms/android/cordova/node_modules/lodash/array/head.js b/platforms/android/cordova/node_modules/lodash/array/head.js new file mode 100644 index 0000000..1961b08 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/head.js @@ -0,0 +1 @@ +module.exports = require('./first'); diff --git a/platforms/android/cordova/node_modules/lodash/array/indexOf.js b/platforms/android/cordova/node_modules/lodash/array/indexOf.js new file mode 100644 index 0000000..4cfc682 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/indexOf.js @@ -0,0 +1,53 @@ +var baseIndexOf = require('../internal/baseIndexOf'), + binaryIndex = require('../internal/binaryIndex'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` + * performs a faster binary search. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + * + * // performing a binary search + * _.indexOf([1, 1, 2, 2], 2, true); + * // => 2 + */ +function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else if (fromIndex) { + var index = binaryIndex(array, value); + if (index < length && + (value === value ? (value === array[index]) : (array[index] !== array[index]))) { + return index; + } + return -1; + } + return baseIndexOf(array, value, fromIndex || 0); +} + +module.exports = indexOf; diff --git a/platforms/android/cordova/node_modules/lodash/array/initial.js b/platforms/android/cordova/node_modules/lodash/array/initial.js new file mode 100644 index 0000000..59b7a7d --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/initial.js @@ -0,0 +1,20 @@ +var dropRight = require('./dropRight'); + +/** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ +function initial(array) { + return dropRight(array, 1); +} + +module.exports = initial; diff --git a/platforms/android/cordova/node_modules/lodash/array/intersection.js b/platforms/android/cordova/node_modules/lodash/array/intersection.js new file mode 100644 index 0000000..f218432 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/intersection.js @@ -0,0 +1,58 @@ +var baseIndexOf = require('../internal/baseIndexOf'), + cacheIndexOf = require('../internal/cacheIndexOf'), + createCache = require('../internal/createCache'), + isArrayLike = require('../internal/isArrayLike'), + restParam = require('../function/restParam'); + +/** + * Creates an array of unique values that are included in all of the provided + * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of shared values. + * @example + * _.intersection([1, 2], [4, 2], [2, 1]); + * // => [2] + */ +var intersection = restParam(function(arrays) { + var othLength = arrays.length, + othIndex = othLength, + caches = Array(length), + indexOf = baseIndexOf, + isCommon = true, + result = []; + + while (othIndex--) { + var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; + caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; + } + var array = arrays[0], + index = -1, + length = array ? array.length : 0, + seen = caches[0]; + + outer: + while (++index < length) { + value = array[index]; + if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { + var othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { + continue outer; + } + } + if (seen) { + seen.push(value); + } + result.push(value); + } + } + return result; +}); + +module.exports = intersection; diff --git a/platforms/android/cordova/node_modules/lodash/array/last.js b/platforms/android/cordova/node_modules/lodash/array/last.js new file mode 100644 index 0000000..299af31 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/last.js @@ -0,0 +1,19 @@ +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; +} + +module.exports = last; diff --git a/platforms/android/cordova/node_modules/lodash/array/lastIndexOf.js b/platforms/android/cordova/node_modules/lodash/array/lastIndexOf.js new file mode 100644 index 0000000..02b8062 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/lastIndexOf.js @@ -0,0 +1,60 @@ +var binaryIndex = require('../internal/binaryIndex'), + indexOfNaN = require('../internal/indexOfNaN'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=array.length-1] The index to search from + * or `true` to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // using `fromIndex` + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + * + * // performing a binary search + * _.lastIndexOf([1, 1, 2, 2], 2, true); + * // => 3 + */ +function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; + } else if (fromIndex) { + index = binaryIndex(array, value, true) - 1; + var other = array[index]; + if (value === value ? (value === other) : (other !== other)) { + return index; + } + return -1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +module.exports = lastIndexOf; diff --git a/platforms/android/cordova/node_modules/lodash/array/object.js b/platforms/android/cordova/node_modules/lodash/array/object.js new file mode 100644 index 0000000..f4a3453 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/object.js @@ -0,0 +1 @@ +module.exports = require('./zipObject'); diff --git a/platforms/android/cordova/node_modules/lodash/array/pull.js b/platforms/android/cordova/node_modules/lodash/array/pull.js new file mode 100644 index 0000000..7bcbb4a --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/pull.js @@ -0,0 +1,52 @@ +var baseIndexOf = require('../internal/baseIndexOf'); + +/** Used for native method references. */ +var arrayProto = Array.prototype; + +/** Native method references. */ +var splice = arrayProto.splice; + +/** + * Removes all provided values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ +function pull() { + var args = arguments, + array = args[0]; + + if (!(array && array.length)) { + return array; + } + var index = 0, + indexOf = baseIndexOf, + length = args.length; + + while (++index < length) { + var fromIndex = 0, + value = args[index]; + + while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { + splice.call(array, fromIndex, 1); + } + } + return array; +} + +module.exports = pull; diff --git a/platforms/android/cordova/node_modules/lodash/array/pullAt.js b/platforms/android/cordova/node_modules/lodash/array/pullAt.js new file mode 100644 index 0000000..4ca2476 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/pullAt.js @@ -0,0 +1,40 @@ +var baseAt = require('../internal/baseAt'), + baseCompareAscending = require('../internal/baseCompareAscending'), + baseFlatten = require('../internal/baseFlatten'), + basePullAt = require('../internal/basePullAt'), + restParam = require('../function/restParam'); + +/** + * Removes elements from `array` corresponding to the given indexes and returns + * an array of the removed elements. Indexes may be specified as an array of + * indexes or as individual arguments. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified as individual indexes or arrays of indexes. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, 1, 3); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] + */ +var pullAt = restParam(function(array, indexes) { + indexes = baseFlatten(indexes); + + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(baseCompareAscending)); + return result; +}); + +module.exports = pullAt; diff --git a/platforms/android/cordova/node_modules/lodash/array/remove.js b/platforms/android/cordova/node_modules/lodash/array/remove.js new file mode 100644 index 0000000..0cf979b --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/remove.js @@ -0,0 +1,64 @@ +var baseCallback = require('../internal/baseCallback'), + basePullAt = require('../internal/basePullAt'); + +/** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** Unlike `_.filter`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ +function remove(array, predicate, thisArg) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = baseCallback(predicate, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; +} + +module.exports = remove; diff --git a/platforms/android/cordova/node_modules/lodash/array/rest.js b/platforms/android/cordova/node_modules/lodash/array/rest.js new file mode 100644 index 0000000..9bfb734 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/rest.js @@ -0,0 +1,21 @@ +var drop = require('./drop'); + +/** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @alias tail + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + */ +function rest(array) { + return drop(array, 1); +} + +module.exports = rest; diff --git a/platforms/android/cordova/node_modules/lodash/array/slice.js b/platforms/android/cordova/node_modules/lodash/array/slice.js new file mode 100644 index 0000000..48ef1a1 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/slice.js @@ -0,0 +1,30 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of `Array#slice` to support node + * lists in IE < 9 and to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + return baseSlice(array, start, end); +} + +module.exports = slice; diff --git a/platforms/android/cordova/node_modules/lodash/array/sortedIndex.js b/platforms/android/cordova/node_modules/lodash/array/sortedIndex.js new file mode 100644 index 0000000..6903bca --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/sortedIndex.js @@ -0,0 +1,53 @@ +var createSortedIndex = require('../internal/createSortedIndex'); + +/** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. If an iteratee + * function is provided it's invoked for `value` and each element of `array` + * to compute their sort ranking. The iteratee is bound to `thisArg` and + * invoked with one argument; (value). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 4, 5, 5], 5); + * // => 2 + * + * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * + * // using an iteratee function + * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { + * return this.data[word]; + * }, dict); + * // => 1 + * + * // using the `_.property` callback shorthand + * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 1 + */ +var sortedIndex = createSortedIndex(); + +module.exports = sortedIndex; diff --git a/platforms/android/cordova/node_modules/lodash/array/sortedLastIndex.js b/platforms/android/cordova/node_modules/lodash/array/sortedLastIndex.js new file mode 100644 index 0000000..81a4a86 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/sortedLastIndex.js @@ -0,0 +1,25 @@ +var createSortedIndex = require('../internal/createSortedIndex'); + +/** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 4, 5, 5], 5); + * // => 4 + */ +var sortedLastIndex = createSortedIndex(true); + +module.exports = sortedLastIndex; diff --git a/platforms/android/cordova/node_modules/lodash/array/tail.js b/platforms/android/cordova/node_modules/lodash/array/tail.js new file mode 100644 index 0000000..c5dfe77 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/tail.js @@ -0,0 +1 @@ +module.exports = require('./rest'); diff --git a/platforms/android/cordova/node_modules/lodash/array/take.js b/platforms/android/cordova/node_modules/lodash/array/take.js new file mode 100644 index 0000000..875917a --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/take.js @@ -0,0 +1,39 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ +function take(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, 0, n < 0 ? 0 : n); +} + +module.exports = take; diff --git a/platforms/android/cordova/node_modules/lodash/array/takeRight.js b/platforms/android/cordova/node_modules/lodash/array/takeRight.js new file mode 100644 index 0000000..6e89c87 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/takeRight.js @@ -0,0 +1,40 @@ +var baseSlice = require('../internal/baseSlice'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ +function takeRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, n < 0 ? 0 : n); +} + +module.exports = takeRight; diff --git a/platforms/android/cordova/node_modules/lodash/array/takeRightWhile.js b/platforms/android/cordova/node_modules/lodash/array/takeRightWhile.js new file mode 100644 index 0000000..5464d13 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/takeRightWhile.js @@ -0,0 +1,59 @@ +var baseCallback = require('../internal/baseCallback'), + baseWhile = require('../internal/baseWhile'); + +/** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is bound to `thisArg` + * and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [2, 3] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // => [] + */ +function takeRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, baseCallback(predicate, thisArg, 3), false, true) + : []; +} + +module.exports = takeRightWhile; diff --git a/platforms/android/cordova/node_modules/lodash/array/takeWhile.js b/platforms/android/cordova/node_modules/lodash/array/takeWhile.js new file mode 100644 index 0000000..f7e28a1 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/takeWhile.js @@ -0,0 +1,59 @@ +var baseCallback = require('../internal/baseCallback'), + baseWhile = require('../internal/baseWhile'); + +/** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [1, 2] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeWhile(users, 'active', false), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // => [] + */ +function takeWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, baseCallback(predicate, thisArg, 3)) + : []; +} + +module.exports = takeWhile; diff --git a/platforms/android/cordova/node_modules/lodash/array/union.js b/platforms/android/cordova/node_modules/lodash/array/union.js new file mode 100644 index 0000000..53cefe4 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/union.js @@ -0,0 +1,24 @@ +var baseFlatten = require('../internal/baseFlatten'), + baseUniq = require('../internal/baseUniq'), + restParam = require('../function/restParam'); + +/** + * Creates an array of unique values, in order, from all of the provided arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([1, 2], [4, 2], [2, 1]); + * // => [1, 2, 4] + */ +var union = restParam(function(arrays) { + return baseUniq(baseFlatten(arrays, false, true)); +}); + +module.exports = union; diff --git a/platforms/android/cordova/node_modules/lodash/array/uniq.js b/platforms/android/cordova/node_modules/lodash/array/uniq.js new file mode 100644 index 0000000..ae937ef --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/uniq.js @@ -0,0 +1,71 @@ +var baseCallback = require('../internal/baseCallback'), + baseUniq = require('../internal/baseUniq'), + isIterateeCall = require('../internal/isIterateeCall'), + sortedUniq = require('../internal/sortedUniq'); + +/** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurence of each element + * is kept. Providing `true` for `isSorted` performs a faster search algorithm + * for sorted arrays. If an iteratee function is provided it's invoked for + * each element in the array to generate the criterion by which uniqueness + * is computed. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index, array). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Array + * @param {Array} array The array to inspect. + * @param {boolean} [isSorted] Specify the array is sorted. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new duplicate-value-free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + * + * // using `isSorted` + * _.uniq([1, 1, 2], true); + * // => [1, 2] + * + * // using an iteratee function + * _.uniq([1, 2.5, 1.5, 2], function(n) { + * return this.floor(n); + * }, Math); + * // => [1, 2.5] + * + * // using the `_.property` callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ +function uniq(array, isSorted, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (isSorted != null && typeof isSorted != 'boolean') { + thisArg = iteratee; + iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; + isSorted = false; + } + iteratee = iteratee == null ? iteratee : baseCallback(iteratee, thisArg, 3); + return (isSorted) + ? sortedUniq(array, iteratee) + : baseUniq(array, iteratee); +} + +module.exports = uniq; diff --git a/platforms/android/cordova/node_modules/lodash/array/unique.js b/platforms/android/cordova/node_modules/lodash/array/unique.js new file mode 100644 index 0000000..396de1b --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/unique.js @@ -0,0 +1 @@ +module.exports = require('./uniq'); diff --git a/platforms/android/cordova/node_modules/lodash/array/unzip.js b/platforms/android/cordova/node_modules/lodash/array/unzip.js new file mode 100644 index 0000000..0a539fa --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/unzip.js @@ -0,0 +1,47 @@ +var arrayFilter = require('../internal/arrayFilter'), + arrayMap = require('../internal/arrayMap'), + baseProperty = require('../internal/baseProperty'), + isArrayLike = require('../internal/isArrayLike'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ +function unzip(array) { + if (!(array && array.length)) { + return []; + } + var index = -1, + length = 0; + + array = arrayFilter(array, function(group) { + if (isArrayLike(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + var result = Array(length); + while (++index < length) { + result[index] = arrayMap(array, baseProperty(index)); + } + return result; +} + +module.exports = unzip; diff --git a/platforms/android/cordova/node_modules/lodash/array/unzipWith.js b/platforms/android/cordova/node_modules/lodash/array/unzipWith.js new file mode 100644 index 0000000..324a2b1 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/unzipWith.js @@ -0,0 +1,41 @@ +var arrayMap = require('../internal/arrayMap'), + arrayReduce = require('../internal/arrayReduce'), + bindCallback = require('../internal/bindCallback'), + unzip = require('./unzip'); + +/** + * This method is like `_.unzip` except that it accepts an iteratee to specify + * how regrouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee] The function to combine regrouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ +function unzipWith(array, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + iteratee = bindCallback(iteratee, thisArg, 4); + return arrayMap(result, function(group) { + return arrayReduce(group, iteratee, undefined, true); + }); +} + +module.exports = unzipWith; diff --git a/platforms/android/cordova/node_modules/lodash/array/without.js b/platforms/android/cordova/node_modules/lodash/array/without.js new file mode 100644 index 0000000..2ac3d11 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/without.js @@ -0,0 +1,27 @@ +var baseDifference = require('../internal/baseDifference'), + isArrayLike = require('../internal/isArrayLike'), + restParam = require('../function/restParam'); + +/** + * Creates an array excluding all provided values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 3], 1, 2); + * // => [3] + */ +var without = restParam(function(array, values) { + return isArrayLike(array) + ? baseDifference(array, values) + : []; +}); + +module.exports = without; diff --git a/platforms/android/cordova/node_modules/lodash/array/xor.js b/platforms/android/cordova/node_modules/lodash/array/xor.js new file mode 100644 index 0000000..04ef32a --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/xor.js @@ -0,0 +1,35 @@ +var arrayPush = require('../internal/arrayPush'), + baseDifference = require('../internal/baseDifference'), + baseUniq = require('../internal/baseUniq'), + isArrayLike = require('../internal/isArrayLike'); + +/** + * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the provided arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([1, 2], [4, 2]); + * // => [1, 4] + */ +function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArrayLike(array)) { + var result = result + ? arrayPush(baseDifference(result, array), baseDifference(array, result)) + : array; + } + } + return result ? baseUniq(result) : []; +} + +module.exports = xor; diff --git a/platforms/android/cordova/node_modules/lodash/array/zip.js b/platforms/android/cordova/node_modules/lodash/array/zip.js new file mode 100644 index 0000000..53a6f69 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/zip.js @@ -0,0 +1,21 @@ +var restParam = require('../function/restParam'), + unzip = require('./unzip'); + +/** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second elements + * of the given arrays, and so on. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ +var zip = restParam(unzip); + +module.exports = zip; diff --git a/platforms/android/cordova/node_modules/lodash/array/zipObject.js b/platforms/android/cordova/node_modules/lodash/array/zipObject.js new file mode 100644 index 0000000..dec7a21 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/zipObject.js @@ -0,0 +1,43 @@ +var isArray = require('../lang/isArray'); + +/** + * The inverse of `_.pairs`; this method returns an object composed from arrays + * of property names and values. Provide either a single two dimensional array, + * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names + * and one of corresponding values. + * + * @static + * @memberOf _ + * @alias object + * @category Array + * @param {Array} props The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ +function zipObject(props, values) { + var index = -1, + length = props ? props.length : 0, + result = {}; + + if (length && !values && !isArray(props[0])) { + values = []; + } + while (++index < length) { + var key = props[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; +} + +module.exports = zipObject; diff --git a/platforms/android/cordova/node_modules/lodash/array/zipWith.js b/platforms/android/cordova/node_modules/lodash/array/zipWith.js new file mode 100644 index 0000000..ad10374 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/array/zipWith.js @@ -0,0 +1,36 @@ +var restParam = require('../function/restParam'), + unzipWith = require('./unzipWith'); + +/** + * This method is like `_.zip` except that it accepts an iteratee to specify + * how grouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee] The function to combine grouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], _.add); + * // => [111, 222] + */ +var zipWith = restParam(function(arrays) { + var length = arrays.length, + iteratee = length > 2 ? arrays[length - 2] : undefined, + thisArg = length > 1 ? arrays[length - 1] : undefined; + + if (length > 2 && typeof iteratee == 'function') { + length -= 2; + } else { + iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; + thisArg = undefined; + } + arrays.length = length; + return unzipWith(arrays, iteratee, thisArg); +}); + +module.exports = zipWith; diff --git a/platforms/android/cordova/node_modules/lodash/chain.js b/platforms/android/cordova/node_modules/lodash/chain.js new file mode 100644 index 0000000..6439627 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain.js @@ -0,0 +1,16 @@ +module.exports = { + 'chain': require('./chain/chain'), + 'commit': require('./chain/commit'), + 'concat': require('./chain/concat'), + 'lodash': require('./chain/lodash'), + 'plant': require('./chain/plant'), + 'reverse': require('./chain/reverse'), + 'run': require('./chain/run'), + 'tap': require('./chain/tap'), + 'thru': require('./chain/thru'), + 'toJSON': require('./chain/toJSON'), + 'toString': require('./chain/toString'), + 'value': require('./chain/value'), + 'valueOf': require('./chain/valueOf'), + 'wrapperChain': require('./chain/wrapperChain') +}; diff --git a/platforms/android/cordova/node_modules/lodash/chain/chain.js b/platforms/android/cordova/node_modules/lodash/chain/chain.js new file mode 100644 index 0000000..453ba1e --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/chain.js @@ -0,0 +1,35 @@ +var lodash = require('./lodash'); + +/** + * Creates a `lodash` object that wraps `value` with explicit method + * chaining enabled. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(users) + * .sortBy('age') + * .map(function(chr) { + * return chr.user + ' is ' + chr.age; + * }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ +function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; +} + +module.exports = chain; diff --git a/platforms/android/cordova/node_modules/lodash/chain/commit.js b/platforms/android/cordova/node_modules/lodash/chain/commit.js new file mode 100644 index 0000000..c732d1b --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/commit.js @@ -0,0 +1 @@ +module.exports = require('./wrapperCommit'); diff --git a/platforms/android/cordova/node_modules/lodash/chain/concat.js b/platforms/android/cordova/node_modules/lodash/chain/concat.js new file mode 100644 index 0000000..90607d1 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/concat.js @@ -0,0 +1 @@ +module.exports = require('./wrapperConcat'); diff --git a/platforms/android/cordova/node_modules/lodash/chain/lodash.js b/platforms/android/cordova/node_modules/lodash/chain/lodash.js new file mode 100644 index 0000000..1c3467e --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/lodash.js @@ -0,0 +1,125 @@ +var LazyWrapper = require('../internal/LazyWrapper'), + LodashWrapper = require('../internal/LodashWrapper'), + baseLodash = require('../internal/baseLodash'), + isArray = require('../lang/isArray'), + isObjectLike = require('../internal/isObjectLike'), + wrapperClone = require('../internal/wrapperClone'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates a `lodash` object which wraps `value` to enable implicit chaining. + * Methods that operate on and return arrays, collections, and functions can + * be chained together. Methods that retrieve a single value or may return a + * primitive value will automatically end the chain returning the unwrapped + * value. Explicit chaining may be enabled using `_.chain`. The execution of + * chained methods is lazy, that is, execution is deferred until `_#value` + * is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization strategy which merge iteratee calls; this can help + * to avoid the creation of intermediate data structures and greatly reduce the + * number of iteratee executions. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, + * `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, + * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, + * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, + * and `where` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, + * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, + * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, + * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, + * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, + * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, + * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, + * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, + * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, + * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, + * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, + * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, + * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, + * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, + * `unescape`, `uniqueId`, `value`, and `words` + * + * The wrapper method `sample` will return a wrapped value when `n` is provided, + * otherwise an unwrapped value is returned. + * + * @name _ + * @constructor + * @category Chain + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(total, n) { + * return total + n; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(n) { + * return n * n; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ +function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); +} + +// Ensure wrappers are instances of `baseLodash`. +lodash.prototype = baseLodash.prototype; + +module.exports = lodash; diff --git a/platforms/android/cordova/node_modules/lodash/chain/plant.js b/platforms/android/cordova/node_modules/lodash/chain/plant.js new file mode 100644 index 0000000..04099f2 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/plant.js @@ -0,0 +1 @@ +module.exports = require('./wrapperPlant'); diff --git a/platforms/android/cordova/node_modules/lodash/chain/reverse.js b/platforms/android/cordova/node_modules/lodash/chain/reverse.js new file mode 100644 index 0000000..f72a64a --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/reverse.js @@ -0,0 +1 @@ +module.exports = require('./wrapperReverse'); diff --git a/platforms/android/cordova/node_modules/lodash/chain/run.js b/platforms/android/cordova/node_modules/lodash/chain/run.js new file mode 100644 index 0000000..5e751a2 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/run.js @@ -0,0 +1 @@ +module.exports = require('./wrapperValue'); diff --git a/platforms/android/cordova/node_modules/lodash/chain/tap.js b/platforms/android/cordova/node_modules/lodash/chain/tap.js new file mode 100644 index 0000000..3d0257e --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/tap.js @@ -0,0 +1,29 @@ +/** + * This method invokes `interceptor` and returns `value`. The interceptor is + * bound to `thisArg` and invoked with one argument; (value). The purpose of + * this method is to "tap into" a method chain in order to perform operations + * on intermediate results within the chain. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ +function tap(value, interceptor, thisArg) { + interceptor.call(thisArg, value); + return value; +} + +module.exports = tap; diff --git a/platforms/android/cordova/node_modules/lodash/chain/thru.js b/platforms/android/cordova/node_modules/lodash/chain/thru.js new file mode 100644 index 0000000..a715780 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/thru.js @@ -0,0 +1,26 @@ +/** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ +function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); +} + +module.exports = thru; diff --git a/platforms/android/cordova/node_modules/lodash/chain/toJSON.js b/platforms/android/cordova/node_modules/lodash/chain/toJSON.js new file mode 100644 index 0000000..5e751a2 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/toJSON.js @@ -0,0 +1 @@ +module.exports = require('./wrapperValue'); diff --git a/platforms/android/cordova/node_modules/lodash/chain/toString.js b/platforms/android/cordova/node_modules/lodash/chain/toString.js new file mode 100644 index 0000000..c7bcbf9 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/toString.js @@ -0,0 +1 @@ +module.exports = require('./wrapperToString'); diff --git a/platforms/android/cordova/node_modules/lodash/chain/value.js b/platforms/android/cordova/node_modules/lodash/chain/value.js new file mode 100644 index 0000000..5e751a2 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/value.js @@ -0,0 +1 @@ +module.exports = require('./wrapperValue'); diff --git a/platforms/android/cordova/node_modules/lodash/chain/valueOf.js b/platforms/android/cordova/node_modules/lodash/chain/valueOf.js new file mode 100644 index 0000000..5e751a2 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/valueOf.js @@ -0,0 +1 @@ +module.exports = require('./wrapperValue'); diff --git a/platforms/android/cordova/node_modules/lodash/chain/wrapperChain.js b/platforms/android/cordova/node_modules/lodash/chain/wrapperChain.js new file mode 100644 index 0000000..3823481 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/wrapperChain.js @@ -0,0 +1,32 @@ +var chain = require('./chain'); + +/** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(users).chain() + * .first() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ +function wrapperChain() { + return chain(this); +} + +module.exports = wrapperChain; diff --git a/platforms/android/cordova/node_modules/lodash/chain/wrapperCommit.js b/platforms/android/cordova/node_modules/lodash/chain/wrapperCommit.js new file mode 100644 index 0000000..c3d2898 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/wrapperCommit.js @@ -0,0 +1,32 @@ +var LodashWrapper = require('../internal/LodashWrapper'); + +/** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ +function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); +} + +module.exports = wrapperCommit; diff --git a/platforms/android/cordova/node_modules/lodash/chain/wrapperConcat.js b/platforms/android/cordova/node_modules/lodash/chain/wrapperConcat.js new file mode 100644 index 0000000..799156c --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/wrapperConcat.js @@ -0,0 +1,34 @@ +var arrayConcat = require('../internal/arrayConcat'), + baseFlatten = require('../internal/baseFlatten'), + isArray = require('../lang/isArray'), + restParam = require('../function/restParam'), + toObject = require('../internal/toObject'); + +/** + * Creates a new array joining a wrapped array with any additional arrays + * and/or values. + * + * @name concat + * @memberOf _ + * @category Chain + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var wrapped = _(array).concat(2, [3], [[4]]); + * + * console.log(wrapped.value()); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ +var wrapperConcat = restParam(function(values) { + values = baseFlatten(values); + return this.thru(function(array) { + return arrayConcat(isArray(array) ? array : [toObject(array)], values); + }); +}); + +module.exports = wrapperConcat; diff --git a/platforms/android/cordova/node_modules/lodash/chain/wrapperPlant.js b/platforms/android/cordova/node_modules/lodash/chain/wrapperPlant.js new file mode 100644 index 0000000..234fe41 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/wrapperPlant.js @@ -0,0 +1,45 @@ +var baseLodash = require('../internal/baseLodash'), + wrapperClone = require('../internal/wrapperClone'); + +/** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).map(function(value) { + * return Math.pow(value, 2); + * }); + * + * var other = [3, 4]; + * var otherWrapped = wrapped.plant(other); + * + * otherWrapped.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ +function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; +} + +module.exports = wrapperPlant; diff --git a/platforms/android/cordova/node_modules/lodash/chain/wrapperReverse.js b/platforms/android/cordova/node_modules/lodash/chain/wrapperReverse.js new file mode 100644 index 0000000..6ba546d --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/wrapperReverse.js @@ -0,0 +1,43 @@ +var LazyWrapper = require('../internal/LazyWrapper'), + LodashWrapper = require('../internal/LodashWrapper'), + thru = require('./thru'); + +/** + * Reverses the wrapped array so the first element becomes the last, the + * second element becomes the second to last, and so on. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new reversed `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ +function wrapperReverse() { + var value = this.__wrapped__; + + var interceptor = function(value) { + return value.reverse(); + }; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(interceptor); +} + +module.exports = wrapperReverse; diff --git a/platforms/android/cordova/node_modules/lodash/chain/wrapperToString.js b/platforms/android/cordova/node_modules/lodash/chain/wrapperToString.js new file mode 100644 index 0000000..db975a5 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/wrapperToString.js @@ -0,0 +1,17 @@ +/** + * Produces the result of coercing the unwrapped value to a string. + * + * @name toString + * @memberOf _ + * @category Chain + * @returns {string} Returns the coerced string value. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' + */ +function wrapperToString() { + return (this.value() + ''); +} + +module.exports = wrapperToString; diff --git a/platforms/android/cordova/node_modules/lodash/chain/wrapperValue.js b/platforms/android/cordova/node_modules/lodash/chain/wrapperValue.js new file mode 100644 index 0000000..2734e41 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/chain/wrapperValue.js @@ -0,0 +1,20 @@ +var baseWrapperValue = require('../internal/baseWrapperValue'); + +/** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias run, toJSON, valueOf + * @category Chain + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ +function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); +} + +module.exports = wrapperValue; diff --git a/platforms/android/cordova/node_modules/lodash/collection.js b/platforms/android/cordova/node_modules/lodash/collection.js new file mode 100644 index 0000000..0338857 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection.js @@ -0,0 +1,44 @@ +module.exports = { + 'all': require('./collection/all'), + 'any': require('./collection/any'), + 'at': require('./collection/at'), + 'collect': require('./collection/collect'), + 'contains': require('./collection/contains'), + 'countBy': require('./collection/countBy'), + 'detect': require('./collection/detect'), + 'each': require('./collection/each'), + 'eachRight': require('./collection/eachRight'), + 'every': require('./collection/every'), + 'filter': require('./collection/filter'), + 'find': require('./collection/find'), + 'findLast': require('./collection/findLast'), + 'findWhere': require('./collection/findWhere'), + 'foldl': require('./collection/foldl'), + 'foldr': require('./collection/foldr'), + 'forEach': require('./collection/forEach'), + 'forEachRight': require('./collection/forEachRight'), + 'groupBy': require('./collection/groupBy'), + 'include': require('./collection/include'), + 'includes': require('./collection/includes'), + 'indexBy': require('./collection/indexBy'), + 'inject': require('./collection/inject'), + 'invoke': require('./collection/invoke'), + 'map': require('./collection/map'), + 'max': require('./math/max'), + 'min': require('./math/min'), + 'partition': require('./collection/partition'), + 'pluck': require('./collection/pluck'), + 'reduce': require('./collection/reduce'), + 'reduceRight': require('./collection/reduceRight'), + 'reject': require('./collection/reject'), + 'sample': require('./collection/sample'), + 'select': require('./collection/select'), + 'shuffle': require('./collection/shuffle'), + 'size': require('./collection/size'), + 'some': require('./collection/some'), + 'sortBy': require('./collection/sortBy'), + 'sortByAll': require('./collection/sortByAll'), + 'sortByOrder': require('./collection/sortByOrder'), + 'sum': require('./math/sum'), + 'where': require('./collection/where') +}; diff --git a/platforms/android/cordova/node_modules/lodash/collection/all.js b/platforms/android/cordova/node_modules/lodash/collection/all.js new file mode 100644 index 0000000..d0839f7 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/all.js @@ -0,0 +1 @@ +module.exports = require('./every'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/any.js b/platforms/android/cordova/node_modules/lodash/collection/any.js new file mode 100644 index 0000000..900ac25 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/any.js @@ -0,0 +1 @@ +module.exports = require('./some'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/at.js b/platforms/android/cordova/node_modules/lodash/collection/at.js new file mode 100644 index 0000000..29236e5 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/at.js @@ -0,0 +1,29 @@ +var baseAt = require('../internal/baseAt'), + baseFlatten = require('../internal/baseFlatten'), + restParam = require('../function/restParam'); + +/** + * Creates an array of elements corresponding to the given keys, or indexes, + * of `collection`. Keys may be specified as individual arguments or as arrays + * of keys. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [props] The property names + * or indexes of elements to pick, specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * _.at(['a', 'b', 'c'], [0, 2]); + * // => ['a', 'c'] + * + * _.at(['barney', 'fred', 'pebbles'], 0, 2); + * // => ['barney', 'pebbles'] + */ +var at = restParam(function(collection, props) { + return baseAt(collection, baseFlatten(props)); +}); + +module.exports = at; diff --git a/platforms/android/cordova/node_modules/lodash/collection/collect.js b/platforms/android/cordova/node_modules/lodash/collection/collect.js new file mode 100644 index 0000000..0d1e1ab --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/collect.js @@ -0,0 +1 @@ +module.exports = require('./map'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/contains.js b/platforms/android/cordova/node_modules/lodash/collection/contains.js new file mode 100644 index 0000000..594722a --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/contains.js @@ -0,0 +1 @@ +module.exports = require('./includes'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/countBy.js b/platforms/android/cordova/node_modules/lodash/collection/countBy.js new file mode 100644 index 0000000..e97dbb7 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/countBy.js @@ -0,0 +1,54 @@ +var createAggregator = require('../internal/createAggregator'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ +var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); +}); + +module.exports = countBy; diff --git a/platforms/android/cordova/node_modules/lodash/collection/detect.js b/platforms/android/cordova/node_modules/lodash/collection/detect.js new file mode 100644 index 0000000..2fb6303 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/detect.js @@ -0,0 +1 @@ +module.exports = require('./find'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/each.js b/platforms/android/cordova/node_modules/lodash/collection/each.js new file mode 100644 index 0000000..8800f42 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/each.js @@ -0,0 +1 @@ +module.exports = require('./forEach'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/eachRight.js b/platforms/android/cordova/node_modules/lodash/collection/eachRight.js new file mode 100644 index 0000000..3252b2a --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/eachRight.js @@ -0,0 +1 @@ +module.exports = require('./forEachRight'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/every.js b/platforms/android/cordova/node_modules/lodash/collection/every.js new file mode 100644 index 0000000..5a2d0f5 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/every.js @@ -0,0 +1,66 @@ +var arrayEvery = require('../internal/arrayEvery'), + baseCallback = require('../internal/baseCallback'), + baseEvery = require('../internal/baseEvery'), + isArray = require('../lang/isArray'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.every(users, 'active'); + * // => false + */ +function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = baseCallback(predicate, thisArg, 3); + } + return func(collection, predicate); +} + +module.exports = every; diff --git a/platforms/android/cordova/node_modules/lodash/collection/filter.js b/platforms/android/cordova/node_modules/lodash/collection/filter.js new file mode 100644 index 0000000..7620aa7 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/filter.js @@ -0,0 +1,61 @@ +var arrayFilter = require('../internal/arrayFilter'), + baseCallback = require('../internal/baseCallback'), + baseFilter = require('../internal/baseFilter'), + isArray = require('../lang/isArray'); + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.filter([4, 5, 6], function(n) { + * return n % 2 == 0; + * }); + * // => [4, 6] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.filter(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.filter(users, 'active'), 'user'); + * // => ['barney'] + */ +function filter(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = baseCallback(predicate, thisArg, 3); + return func(collection, predicate); +} + +module.exports = filter; diff --git a/platforms/android/cordova/node_modules/lodash/collection/find.js b/platforms/android/cordova/node_modules/lodash/collection/find.js new file mode 100644 index 0000000..7358cfe --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/find.js @@ -0,0 +1,56 @@ +var baseEach = require('../internal/baseEach'), + createFind = require('../internal/createFind'); + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias detect + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.result(_.find(users, function(chr) { + * return chr.age < 40; + * }), 'user'); + * // => 'barney' + * + * // using the `_.matches` callback shorthand + * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.result(_.find(users, 'active', false), 'user'); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'barney' + */ +var find = createFind(baseEach); + +module.exports = find; diff --git a/platforms/android/cordova/node_modules/lodash/collection/findLast.js b/platforms/android/cordova/node_modules/lodash/collection/findLast.js new file mode 100644 index 0000000..75dbadc --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/findLast.js @@ -0,0 +1,25 @@ +var baseEachRight = require('../internal/baseEachRight'), + createFind = require('../internal/createFind'); + +/** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ +var findLast = createFind(baseEachRight, true); + +module.exports = findLast; diff --git a/platforms/android/cordova/node_modules/lodash/collection/findWhere.js b/platforms/android/cordova/node_modules/lodash/collection/findWhere.js new file mode 100644 index 0000000..2d62065 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/findWhere.js @@ -0,0 +1,37 @@ +var baseMatches = require('../internal/baseMatches'), + find = require('./find'); + +/** + * Performs a deep comparison between each element in `collection` and the + * source object, returning the first element that has equivalent property + * values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); + * // => 'barney' + * + * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); + * // => 'fred' + */ +function findWhere(collection, source) { + return find(collection, baseMatches(source)); +} + +module.exports = findWhere; diff --git a/platforms/android/cordova/node_modules/lodash/collection/foldl.js b/platforms/android/cordova/node_modules/lodash/collection/foldl.js new file mode 100644 index 0000000..26f53cf --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/foldl.js @@ -0,0 +1 @@ +module.exports = require('./reduce'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/foldr.js b/platforms/android/cordova/node_modules/lodash/collection/foldr.js new file mode 100644 index 0000000..8fb199e --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/foldr.js @@ -0,0 +1 @@ +module.exports = require('./reduceRight'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/forEach.js b/platforms/android/cordova/node_modules/lodash/collection/forEach.js new file mode 100644 index 0000000..05a8e21 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/forEach.js @@ -0,0 +1,37 @@ +var arrayEach = require('../internal/arrayEach'), + baseEach = require('../internal/baseEach'), + createForEach = require('../internal/createForEach'); + +/** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). Iteratee functions may exit iteration early + * by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from left to right and returns the array + * + * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { + * console.log(n, key); + * }); + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) + */ +var forEach = createForEach(arrayEach, baseEach); + +module.exports = forEach; diff --git a/platforms/android/cordova/node_modules/lodash/collection/forEachRight.js b/platforms/android/cordova/node_modules/lodash/collection/forEachRight.js new file mode 100644 index 0000000..3499711 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/forEachRight.js @@ -0,0 +1,26 @@ +var arrayEachRight = require('../internal/arrayEachRight'), + baseEachRight = require('../internal/baseEachRight'), + createForEach = require('../internal/createForEach'); + +/** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEachRight(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from right to left and returns the array + */ +var forEachRight = createForEach(arrayEachRight, baseEachRight); + +module.exports = forEachRight; diff --git a/platforms/android/cordova/node_modules/lodash/collection/groupBy.js b/platforms/android/cordova/node_modules/lodash/collection/groupBy.js new file mode 100644 index 0000000..a925c89 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/groupBy.js @@ -0,0 +1,59 @@ +var createAggregator = require('../internal/createAggregator'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using the `_.property` callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ +var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } +}); + +module.exports = groupBy; diff --git a/platforms/android/cordova/node_modules/lodash/collection/include.js b/platforms/android/cordova/node_modules/lodash/collection/include.js new file mode 100644 index 0000000..594722a --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/include.js @@ -0,0 +1 @@ +module.exports = require('./includes'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/includes.js b/platforms/android/cordova/node_modules/lodash/collection/includes.js new file mode 100644 index 0000000..329486a --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/includes.js @@ -0,0 +1,57 @@ +var baseIndexOf = require('../internal/baseIndexOf'), + getLength = require('../internal/getLength'), + isArray = require('../lang/isArray'), + isIterateeCall = require('../internal/isIterateeCall'), + isLength = require('../internal/isLength'), + isString = require('../lang/isString'), + values = require('../object/values'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Checks if `target` is in `collection` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `collection`. + * + * @static + * @memberOf _ + * @alias contains, include + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} target The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ +function includes(collection, target, fromIndex, guard) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + collection = values(collection); + length = collection.length; + } + if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { + fromIndex = 0; + } else { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + } + return (typeof collection == 'string' || !isArray(collection) && isString(collection)) + ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) + : (!!length && baseIndexOf(collection, target, fromIndex) > -1); +} + +module.exports = includes; diff --git a/platforms/android/cordova/node_modules/lodash/collection/indexBy.js b/platforms/android/cordova/node_modules/lodash/collection/indexBy.js new file mode 100644 index 0000000..34a941e --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/indexBy.js @@ -0,0 +1,53 @@ +var createAggregator = require('../internal/createAggregator'); + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keyData = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keyData, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return String.fromCharCode(object.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return this.fromCharCode(object.code); + * }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ +var indexBy = createAggregator(function(result, value, key) { + result[key] = value; +}); + +module.exports = indexBy; diff --git a/platforms/android/cordova/node_modules/lodash/collection/inject.js b/platforms/android/cordova/node_modules/lodash/collection/inject.js new file mode 100644 index 0000000..26f53cf --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/inject.js @@ -0,0 +1 @@ +module.exports = require('./reduce'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/invoke.js b/platforms/android/cordova/node_modules/lodash/collection/invoke.js new file mode 100644 index 0000000..6e71721 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/invoke.js @@ -0,0 +1,42 @@ +var baseEach = require('../internal/baseEach'), + invokePath = require('../internal/invokePath'), + isArrayLike = require('../internal/isArrayLike'), + isKey = require('../internal/isKey'), + restParam = require('../function/restParam'); + +/** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it's + * invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ +var invoke = restParam(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); + }); + return result; +}); + +module.exports = invoke; diff --git a/platforms/android/cordova/node_modules/lodash/collection/map.js b/platforms/android/cordova/node_modules/lodash/collection/map.js new file mode 100644 index 0000000..5381110 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/map.js @@ -0,0 +1,68 @@ +var arrayMap = require('../internal/arrayMap'), + baseCallback = require('../internal/baseCallback'), + baseMap = require('../internal/baseMap'), + isArray = require('../lang/isArray'); + +/** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, + * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, + * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, + * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, + * `sum`, `uniq`, and `words` + * + * @static + * @memberOf _ + * @alias collect + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new mapped array. + * @example + * + * function timesThree(n) { + * return n * 3; + * } + * + * _.map([1, 2], timesThree); + * // => [3, 6] + * + * _.map({ 'a': 1, 'b': 2 }, timesThree); + * // => [3, 6] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // using the `_.property` callback shorthand + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee, thisArg) { + var func = isArray(collection) ? arrayMap : baseMap; + iteratee = baseCallback(iteratee, thisArg, 3); + return func(collection, iteratee); +} + +module.exports = map; diff --git a/platforms/android/cordova/node_modules/lodash/collection/max.js b/platforms/android/cordova/node_modules/lodash/collection/max.js new file mode 100644 index 0000000..bb1d213 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/max.js @@ -0,0 +1 @@ +module.exports = require('../math/max'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/min.js b/platforms/android/cordova/node_modules/lodash/collection/min.js new file mode 100644 index 0000000..eef13d0 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/min.js @@ -0,0 +1 @@ +module.exports = require('../math/min'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/partition.js b/platforms/android/cordova/node_modules/lodash/collection/partition.js new file mode 100644 index 0000000..ee35f27 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/partition.js @@ -0,0 +1,66 @@ +var createAggregator = require('../internal/createAggregator'); + +/** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, while the second of which + * contains elements `predicate` returns falsey for. The predicate is bound + * to `thisArg` and invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * _.partition([1, 2, 3], function(n) { + * return n % 2; + * }); + * // => [[1, 3], [2]] + * + * _.partition([1.2, 2.3, 3.4], function(n) { + * return this.floor(n) % 2; + * }, Math); + * // => [[1.2, 3.4], [2.3]] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * var mapper = function(array) { + * return _.pluck(array, 'user'); + * }; + * + * // using the `_.matches` callback shorthand + * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); + * // => [['pebbles'], ['barney', 'fred']] + * + * // using the `_.matchesProperty` callback shorthand + * _.map(_.partition(users, 'active', false), mapper); + * // => [['barney', 'pebbles'], ['fred']] + * + * // using the `_.property` callback shorthand + * _.map(_.partition(users, 'active'), mapper); + * // => [['fred'], ['barney', 'pebbles']] + */ +var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); +}, function() { return [[], []]; }); + +module.exports = partition; diff --git a/platforms/android/cordova/node_modules/lodash/collection/pluck.js b/platforms/android/cordova/node_modules/lodash/collection/pluck.js new file mode 100644 index 0000000..5ee1ec8 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/pluck.js @@ -0,0 +1,31 @@ +var map = require('./map'), + property = require('../utility/property'); + +/** + * Gets the property value of `path` from all elements in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|string} path The path of the property to pluck. + * @returns {Array} Returns the property values. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.pluck(users, 'user'); + * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) + */ +function pluck(collection, path) { + return map(collection, property(path)); +} + +module.exports = pluck; diff --git a/platforms/android/cordova/node_modules/lodash/collection/reduce.js b/platforms/android/cordova/node_modules/lodash/collection/reduce.js new file mode 100644 index 0000000..5d5e8c9 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/reduce.js @@ -0,0 +1,44 @@ +var arrayReduce = require('../internal/arrayReduce'), + baseEach = require('../internal/baseEach'), + createReduce = require('../internal/createReduce'); + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not provided the first element of `collection` is used as the initial + * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, + * and `sortByOrder` + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(total, n) { + * return total + n; + * }); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) + */ +var reduce = createReduce(arrayReduce, baseEach); + +module.exports = reduce; diff --git a/platforms/android/cordova/node_modules/lodash/collection/reduceRight.js b/platforms/android/cordova/node_modules/lodash/collection/reduceRight.js new file mode 100644 index 0000000..5a5753b --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/reduceRight.js @@ -0,0 +1,29 @@ +var arrayReduceRight = require('../internal/arrayReduceRight'), + baseEachRight = require('../internal/baseEachRight'), + createReduce = require('../internal/createReduce'); + +/** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ +var reduceRight = createReduce(arrayReduceRight, baseEachRight); + +module.exports = reduceRight; diff --git a/platforms/android/cordova/node_modules/lodash/collection/reject.js b/platforms/android/cordova/node_modules/lodash/collection/reject.js new file mode 100644 index 0000000..5592453 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/reject.js @@ -0,0 +1,50 @@ +var arrayFilter = require('../internal/arrayFilter'), + baseCallback = require('../internal/baseCallback'), + baseFilter = require('../internal/baseFilter'), + isArray = require('../lang/isArray'); + +/** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.reject([1, 2, 3, 4], function(n) { + * return n % 2 == 0; + * }); + * // => [1, 3] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.reject(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.reject(users, 'active'), 'user'); + * // => ['barney'] + */ +function reject(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = baseCallback(predicate, thisArg, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); +} + +module.exports = reject; diff --git a/platforms/android/cordova/node_modules/lodash/collection/sample.js b/platforms/android/cordova/node_modules/lodash/collection/sample.js new file mode 100644 index 0000000..8e01533 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/sample.js @@ -0,0 +1,50 @@ +var baseRandom = require('../internal/baseRandom'), + isIterateeCall = require('../internal/isIterateeCall'), + toArray = require('../lang/toArray'), + toIterable = require('../internal/toIterable'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Gets a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {*} Returns the random sample(s). + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ +function sample(collection, n, guard) { + if (guard ? isIterateeCall(collection, n, guard) : n == null) { + collection = toIterable(collection); + var length = collection.length; + return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; + } + var index = -1, + result = toArray(collection), + length = result.length, + lastIndex = length - 1; + + n = nativeMin(n < 0 ? 0 : (+n || 0), length); + while (++index < n) { + var rand = baseRandom(index, lastIndex), + value = result[rand]; + + result[rand] = result[index]; + result[index] = value; + } + result.length = n; + return result; +} + +module.exports = sample; diff --git a/platforms/android/cordova/node_modules/lodash/collection/select.js b/platforms/android/cordova/node_modules/lodash/collection/select.js new file mode 100644 index 0000000..ade80f6 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/select.js @@ -0,0 +1 @@ +module.exports = require('./filter'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/shuffle.js b/platforms/android/cordova/node_modules/lodash/collection/shuffle.js new file mode 100644 index 0000000..949689c --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/shuffle.js @@ -0,0 +1,24 @@ +var sample = require('./sample'); + +/** Used as references for `-Infinity` and `Infinity`. */ +var POSITIVE_INFINITY = Number.POSITIVE_INFINITY; + +/** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ +function shuffle(collection) { + return sample(collection, POSITIVE_INFINITY); +} + +module.exports = shuffle; diff --git a/platforms/android/cordova/node_modules/lodash/collection/size.js b/platforms/android/cordova/node_modules/lodash/collection/size.js new file mode 100644 index 0000000..78dcf4c --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/size.js @@ -0,0 +1,30 @@ +var getLength = require('../internal/getLength'), + isLength = require('../internal/isLength'), + keys = require('../object/keys'); + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the size of `collection`. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + var length = collection ? getLength(collection) : 0; + return isLength(length) ? length : keys(collection).length; +} + +module.exports = size; diff --git a/platforms/android/cordova/node_modules/lodash/collection/some.js b/platforms/android/cordova/node_modules/lodash/collection/some.js new file mode 100644 index 0000000..d0b09a4 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/some.js @@ -0,0 +1,67 @@ +var arraySome = require('../internal/arraySome'), + baseCallback = require('../internal/baseCallback'), + baseSome = require('../internal/baseSome'), + isArray = require('../lang/isArray'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * The function returns as soon as it finds a passing value and does not iterate + * over the entire collection. The predicate is bound to `thisArg` and invoked + * with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.some(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.some(users, 'active'); + * // => true + */ +function some(collection, predicate, thisArg) { + var func = isArray(collection) ? arraySome : baseSome; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = baseCallback(predicate, thisArg, 3); + } + return func(collection, predicate); +} + +module.exports = some; diff --git a/platforms/android/cordova/node_modules/lodash/collection/sortBy.js b/platforms/android/cordova/node_modules/lodash/collection/sortBy.js new file mode 100644 index 0000000..4401c77 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/sortBy.js @@ -0,0 +1,71 @@ +var baseCallback = require('../internal/baseCallback'), + baseMap = require('../internal/baseMap'), + baseSortBy = require('../internal/baseSortBy'), + compareAscending = require('../internal/compareAscending'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through `iteratee`. This method performs + * a stable sort, that is, it preserves the original sort order of equal elements. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new sorted array. + * @example + * + * _.sortBy([1, 2, 3], function(n) { + * return Math.sin(n); + * }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(n) { + * return this.sin(n); + * }, Math); + * // => [3, 1, 2] + * + * var users = [ + * { 'user': 'fred' }, + * { 'user': 'pebbles' }, + * { 'user': 'barney' } + * ]; + * + * // using the `_.property` callback shorthand + * _.pluck(_.sortBy(users, 'user'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ +function sortBy(collection, iteratee, thisArg) { + if (collection == null) { + return []; + } + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + var index = -1; + iteratee = baseCallback(iteratee, thisArg, 3); + + var result = baseMap(collection, function(value, key, collection) { + return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; + }); + return baseSortBy(result, compareAscending); +} + +module.exports = sortBy; diff --git a/platforms/android/cordova/node_modules/lodash/collection/sortByAll.js b/platforms/android/cordova/node_modules/lodash/collection/sortByAll.js new file mode 100644 index 0000000..4766c20 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/sortByAll.js @@ -0,0 +1,52 @@ +var baseFlatten = require('../internal/baseFlatten'), + baseSortByOrder = require('../internal/baseSortByOrder'), + isIterateeCall = require('../internal/isIterateeCall'), + restParam = require('../function/restParam'); + +/** + * This method is like `_.sortBy` except that it can sort by multiple iteratees + * or property names. + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees + * The iteratees to sort by, specified as individual values or arrays of values. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.map(_.sortByAll(users, ['user', 'age']), _.values); + * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.map(_.sortByAll(users, 'user', function(chr) { + * return Math.floor(chr.age / 10); + * }), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ +var sortByAll = restParam(function(collection, iteratees) { + if (collection == null) { + return []; + } + var guard = iteratees[2]; + if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { + iteratees.length = 1; + } + return baseSortByOrder(collection, baseFlatten(iteratees), []); +}); + +module.exports = sortByAll; diff --git a/platforms/android/cordova/node_modules/lodash/collection/sortByOrder.js b/platforms/android/cordova/node_modules/lodash/collection/sortByOrder.js new file mode 100644 index 0000000..8b4fc19 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/sortByOrder.js @@ -0,0 +1,55 @@ +var baseSortByOrder = require('../internal/baseSortByOrder'), + isArray = require('../lang/isArray'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * This method is like `_.sortByAll` except that it allows specifying the + * sort orders of the iteratees to sort by. If `orders` is unspecified, all + * values are sorted in ascending order. Otherwise, a value is sorted in + * ascending order if its corresponding order is "asc", and descending if "desc". + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // sort by `user` in ascending order and by `age` in descending order + * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ +function sortByOrder(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (guard && isIterateeCall(iteratees, orders, guard)) { + orders = undefined; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseSortByOrder(collection, iteratees, orders); +} + +module.exports = sortByOrder; diff --git a/platforms/android/cordova/node_modules/lodash/collection/sum.js b/platforms/android/cordova/node_modules/lodash/collection/sum.js new file mode 100644 index 0000000..a2e9380 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/sum.js @@ -0,0 +1 @@ +module.exports = require('../math/sum'); diff --git a/platforms/android/cordova/node_modules/lodash/collection/where.js b/platforms/android/cordova/node_modules/lodash/collection/where.js new file mode 100644 index 0000000..f603bf8 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/collection/where.js @@ -0,0 +1,37 @@ +var baseMatches = require('../internal/baseMatches'), + filter = require('./filter'); + +/** + * Performs a deep comparison between each element in `collection` and the + * source object, returning an array of all elements that have equivalent + * property values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); + * // => ['barney'] + * + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); + * // => ['fred'] + */ +function where(collection, source) { + return filter(collection, baseMatches(source)); +} + +module.exports = where; diff --git a/platforms/android/cordova/node_modules/lodash/date.js b/platforms/android/cordova/node_modules/lodash/date.js new file mode 100644 index 0000000..195366e --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/date.js @@ -0,0 +1,3 @@ +module.exports = { + 'now': require('./date/now') +}; diff --git a/platforms/android/cordova/node_modules/lodash/date/now.js b/platforms/android/cordova/node_modules/lodash/date/now.js new file mode 100644 index 0000000..ffe3060 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/date/now.js @@ -0,0 +1,24 @@ +var getNative = require('../internal/getNative'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeNow = getNative(Date, 'now'); + +/** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Date + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked + */ +var now = nativeNow || function() { + return new Date().getTime(); +}; + +module.exports = now; diff --git a/platforms/android/cordova/node_modules/lodash/function.js b/platforms/android/cordova/node_modules/lodash/function.js new file mode 100644 index 0000000..71f8ebe --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function.js @@ -0,0 +1,28 @@ +module.exports = { + 'after': require('./function/after'), + 'ary': require('./function/ary'), + 'backflow': require('./function/backflow'), + 'before': require('./function/before'), + 'bind': require('./function/bind'), + 'bindAll': require('./function/bindAll'), + 'bindKey': require('./function/bindKey'), + 'compose': require('./function/compose'), + 'curry': require('./function/curry'), + 'curryRight': require('./function/curryRight'), + 'debounce': require('./function/debounce'), + 'defer': require('./function/defer'), + 'delay': require('./function/delay'), + 'flow': require('./function/flow'), + 'flowRight': require('./function/flowRight'), + 'memoize': require('./function/memoize'), + 'modArgs': require('./function/modArgs'), + 'negate': require('./function/negate'), + 'once': require('./function/once'), + 'partial': require('./function/partial'), + 'partialRight': require('./function/partialRight'), + 'rearg': require('./function/rearg'), + 'restParam': require('./function/restParam'), + 'spread': require('./function/spread'), + 'throttle': require('./function/throttle'), + 'wrap': require('./function/wrap') +}; diff --git a/platforms/android/cordova/node_modules/lodash/function/after.js b/platforms/android/cordova/node_modules/lodash/function/after.js new file mode 100644 index 0000000..96a51fd --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/after.js @@ -0,0 +1,48 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeIsFinite = global.isFinite; + +/** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ +function after(n, func) { + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + n = nativeIsFinite(n = +n) ? n : 0; + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; +} + +module.exports = after; diff --git a/platforms/android/cordova/node_modules/lodash/function/ary.js b/platforms/android/cordova/node_modules/lodash/function/ary.js new file mode 100644 index 0000000..53a6913 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/ary.js @@ -0,0 +1,34 @@ +var createWrapper = require('../internal/createWrapper'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** Used to compose bitmasks for wrapper metadata. */ +var ARY_FLAG = 128; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a function that accepts up to `n` arguments ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ +function ary(func, n, guard) { + if (guard && isIterateeCall(func, n, guard)) { + n = undefined; + } + n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); +} + +module.exports = ary; diff --git a/platforms/android/cordova/node_modules/lodash/function/backflow.js b/platforms/android/cordova/node_modules/lodash/function/backflow.js new file mode 100644 index 0000000..1954e94 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/backflow.js @@ -0,0 +1 @@ +module.exports = require('./flowRight'); diff --git a/platforms/android/cordova/node_modules/lodash/function/before.js b/platforms/android/cordova/node_modules/lodash/function/before.js new file mode 100644 index 0000000..3d94216 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/before.js @@ -0,0 +1,42 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery('#add').on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ +function before(n, func) { + var result; + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; +} + +module.exports = before; diff --git a/platforms/android/cordova/node_modules/lodash/function/bind.js b/platforms/android/cordova/node_modules/lodash/function/bind.js new file mode 100644 index 0000000..0de126a --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/bind.js @@ -0,0 +1,56 @@ +var createWrapper = require('../internal/createWrapper'), + replaceHolders = require('../internal/replaceHolders'), + restParam = require('./restParam'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method does not set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // using placeholders + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ +var bind = restParam(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bind.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); +}); + +// Assign default placeholders. +bind.placeholder = {}; + +module.exports = bind; diff --git a/platforms/android/cordova/node_modules/lodash/function/bindAll.js b/platforms/android/cordova/node_modules/lodash/function/bindAll.js new file mode 100644 index 0000000..a09e948 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/bindAll.js @@ -0,0 +1,50 @@ +var baseFlatten = require('../internal/baseFlatten'), + createWrapper = require('../internal/createWrapper'), + functions = require('../object/functions'), + restParam = require('./restParam'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1; + +/** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all enumerable function + * properties, own and inherited, of `object` are bound. + * + * **Note:** This method does not set the "length" property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} [methodNames] The object method names to bind, + * specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs' when the element is clicked + */ +var bindAll = restParam(function(object, methodNames) { + methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); + + var index = -1, + length = methodNames.length; + + while (++index < length) { + var key = methodNames[index]; + object[key] = createWrapper(object[key], BIND_FLAG, object); + } + return object; +}); + +module.exports = bindAll; diff --git a/platforms/android/cordova/node_modules/lodash/function/bindKey.js b/platforms/android/cordova/node_modules/lodash/function/bindKey.js new file mode 100644 index 0000000..b787fe7 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/bindKey.js @@ -0,0 +1,66 @@ +var createWrapper = require('../internal/createWrapper'), + replaceHolders = require('../internal/replaceHolders'), + restParam = require('./restParam'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // using placeholders + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ +var bindKey = restParam(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bindKey.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); +}); + +// Assign default placeholders. +bindKey.placeholder = {}; + +module.exports = bindKey; diff --git a/platforms/android/cordova/node_modules/lodash/function/compose.js b/platforms/android/cordova/node_modules/lodash/function/compose.js new file mode 100644 index 0000000..1954e94 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/compose.js @@ -0,0 +1 @@ +module.exports = require('./flowRight'); diff --git a/platforms/android/cordova/node_modules/lodash/function/curry.js b/platforms/android/cordova/node_modules/lodash/function/curry.js new file mode 100644 index 0000000..b7db3fd --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/curry.js @@ -0,0 +1,51 @@ +var createCurry = require('../internal/createCurry'); + +/** Used to compose bitmasks for wrapper metadata. */ +var CURRY_FLAG = 8; + +/** + * Creates a function that accepts one or more arguments of `func` that when + * called either invokes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` may be specified + * if `func.length` is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ +var curry = createCurry(CURRY_FLAG); + +// Assign default placeholders. +curry.placeholder = {}; + +module.exports = curry; diff --git a/platforms/android/cordova/node_modules/lodash/function/curryRight.js b/platforms/android/cordova/node_modules/lodash/function/curryRight.js new file mode 100644 index 0000000..11c5403 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/curryRight.js @@ -0,0 +1,48 @@ +var createCurry = require('../internal/createCurry'); + +/** Used to compose bitmasks for wrapper metadata. */ +var CURRY_RIGHT_FLAG = 16; + +/** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ +var curryRight = createCurry(CURRY_RIGHT_FLAG); + +// Assign default placeholders. +curryRight.placeholder = {}; + +module.exports = curryRight; diff --git a/platforms/android/cordova/node_modules/lodash/function/debounce.js b/platforms/android/cordova/node_modules/lodash/function/debounce.js new file mode 100644 index 0000000..163af90 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/debounce.js @@ -0,0 +1,181 @@ +var isObject = require('../lang/isObject'), + now = require('../date/now'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. + * Subsequent calls to the debounced function return the result of the last + * `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it's invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // invoke `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // ensure `batchLog` is invoked once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * jQuery(source).on('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * })); + * + * // cancel a debounced call + * var todoChanges = _.debounce(batchLog, 1000); + * Object.observe(models.todo, todoChanges); + * + * Object.observe(models, function(changes) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { + * todoChanges.cancel(); + * } + * }, ['delete']); + * + * // ...at some point `models.todo` is changed + * models.todo.completed = true; + * + * // ...before 1 second has passed `models.todo` is deleted + * // which cancels the debounced `todoChanges` call + * delete models.todo; + */ +function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = wait < 0 ? 0 : (+wait || 0); + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = !!options.leading; + maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + lastCalled = 0; + maxTimeoutId = timeoutId = trailingCall = undefined; + } + + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function maxDelayed() { + complete(trailing, timeoutId); + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0 || remaining > maxWait; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + return result; + } + debounced.cancel = cancel; + return debounced; +} + +module.exports = debounce; diff --git a/platforms/android/cordova/node_modules/lodash/function/defer.js b/platforms/android/cordova/node_modules/lodash/function/defer.js new file mode 100644 index 0000000..3accbf9 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/defer.js @@ -0,0 +1,25 @@ +var baseDelay = require('../internal/baseDelay'), + restParam = require('./restParam'); + +/** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ +var defer = restParam(function(func, args) { + return baseDelay(func, 1, args); +}); + +module.exports = defer; diff --git a/platforms/android/cordova/node_modules/lodash/function/delay.js b/platforms/android/cordova/node_modules/lodash/function/delay.js new file mode 100644 index 0000000..d5eef27 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/delay.js @@ -0,0 +1,26 @@ +var baseDelay = require('../internal/baseDelay'), + restParam = require('./restParam'); + +/** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ +var delay = restParam(function(func, wait, args) { + return baseDelay(func, wait, args); +}); + +module.exports = delay; diff --git a/platforms/android/cordova/node_modules/lodash/function/flow.js b/platforms/android/cordova/node_modules/lodash/function/flow.js new file mode 100644 index 0000000..a435a3d --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/flow.js @@ -0,0 +1,25 @@ +var createFlow = require('../internal/createFlow'); + +/** + * Creates a function that returns the result of invoking the provided + * functions with the `this` binding of the created function, where each + * successive invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 + */ +var flow = createFlow(); + +module.exports = flow; diff --git a/platforms/android/cordova/node_modules/lodash/function/flowRight.js b/platforms/android/cordova/node_modules/lodash/function/flowRight.js new file mode 100644 index 0000000..23b9d76 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/flowRight.js @@ -0,0 +1,25 @@ +var createFlow = require('../internal/createFlow'); + +/** + * This method is like `_.flow` except that it creates a function that + * invokes the provided functions from right to left. + * + * @static + * @memberOf _ + * @alias backflow, compose + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 + */ +var flowRight = createFlow(true); + +module.exports = flowRight; diff --git a/platforms/android/cordova/node_modules/lodash/function/memoize.js b/platforms/android/cordova/node_modules/lodash/function/memoize.js new file mode 100644 index 0000000..f3b8d69 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/memoize.js @@ -0,0 +1,80 @@ +var MapCache = require('../internal/MapCache'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is coerced to a string and used as the + * cache key. The `func` is invoked with the `this` binding of the memoized + * function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) + * method interface of `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var upperCase = _.memoize(function(string) { + * return string.toUpperCase(); + * }); + * + * upperCase('fred'); + * // => 'FRED' + * + * // modifying the result cache + * upperCase.cache.set('fred', 'BARNEY'); + * upperCase('fred'); + * // => 'BARNEY' + * + * // replacing `_.memoize.Cache` + * var object = { 'user': 'fred' }; + * var other = { 'user': 'barney' }; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'fred' } + * + * _.memoize.Cache = WeakMap; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'barney' } + */ +function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; +} + +// Assign cache to `_.memoize`. +memoize.Cache = MapCache; + +module.exports = memoize; diff --git a/platforms/android/cordova/node_modules/lodash/function/modArgs.js b/platforms/android/cordova/node_modules/lodash/function/modArgs.js new file mode 100644 index 0000000..49b9b5e --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/modArgs.js @@ -0,0 +1,58 @@ +var arrayEvery = require('../internal/arrayEvery'), + baseFlatten = require('../internal/baseFlatten'), + baseIsFunction = require('../internal/baseIsFunction'), + restParam = require('./restParam'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Creates a function that runs each argument through a corresponding + * transform function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified as individual functions or arrays of functions. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var modded = _.modArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * modded(1, 2); + * // => [1, 4] + * + * modded(5, 10); + * // => [25, 20] + */ +var modArgs = restParam(function(func, transforms) { + transforms = baseFlatten(transforms); + if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = transforms.length; + return restParam(function(args) { + var index = nativeMin(args.length, length); + while (index--) { + args[index] = transforms[index](args[index]); + } + return func.apply(this, args); + }); +}); + +module.exports = modArgs; diff --git a/platforms/android/cordova/node_modules/lodash/function/negate.js b/platforms/android/cordova/node_modules/lodash/function/negate.js new file mode 100644 index 0000000..8247939 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/negate.js @@ -0,0 +1,32 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ +function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; +} + +module.exports = negate; diff --git a/platforms/android/cordova/node_modules/lodash/function/once.js b/platforms/android/cordova/node_modules/lodash/function/once.js new file mode 100644 index 0000000..0b5bd85 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/once.js @@ -0,0 +1,24 @@ +var before = require('./before'); + +/** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first call. The `func` is invoked + * with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ +function once(func) { + return before(2, func); +} + +module.exports = once; diff --git a/platforms/android/cordova/node_modules/lodash/function/partial.js b/platforms/android/cordova/node_modules/lodash/function/partial.js new file mode 100644 index 0000000..fb1d04f --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/partial.js @@ -0,0 +1,43 @@ +var createPartial = require('../internal/createPartial'); + +/** Used to compose bitmasks for wrapper metadata. */ +var PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. This method is like `_.bind` except + * it does **not** alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // using placeholders + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ +var partial = createPartial(PARTIAL_FLAG); + +// Assign default placeholders. +partial.placeholder = {}; + +module.exports = partial; diff --git a/platforms/android/cordova/node_modules/lodash/function/partialRight.js b/platforms/android/cordova/node_modules/lodash/function/partialRight.js new file mode 100644 index 0000000..634e6a4 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/partialRight.js @@ -0,0 +1,42 @@ +var createPartial = require('../internal/createPartial'); + +/** Used to compose bitmasks for wrapper metadata. */ +var PARTIAL_RIGHT_FLAG = 64; + +/** + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // using placeholders + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ +var partialRight = createPartial(PARTIAL_RIGHT_FLAG); + +// Assign default placeholders. +partialRight.placeholder = {}; + +module.exports = partialRight; diff --git a/platforms/android/cordova/node_modules/lodash/function/rearg.js b/platforms/android/cordova/node_modules/lodash/function/rearg.js new file mode 100644 index 0000000..f2bd9c4 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/rearg.js @@ -0,0 +1,40 @@ +var baseFlatten = require('../internal/baseFlatten'), + createWrapper = require('../internal/createWrapper'), + restParam = require('./restParam'); + +/** Used to compose bitmasks for wrapper metadata. */ +var REARG_FLAG = 256; + +/** + * Creates a function that invokes `func` with arguments arranged according + * to the specified indexes where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, + * specified as individual indexes or arrays of indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + * + * var map = _.rearg(_.map, [1, 0]); + * map(function(n) { + * return n * 3; + * }, [1, 2, 3]); + * // => [3, 6, 9] + */ +var rearg = restParam(function(func, indexes) { + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); +}); + +module.exports = rearg; diff --git a/platforms/android/cordova/node_modules/lodash/function/restParam.js b/platforms/android/cordova/node_modules/lodash/function/restParam.js new file mode 100644 index 0000000..8852286 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/restParam.js @@ -0,0 +1,58 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ +function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); + + while (++index < length) { + rest[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; +} + +module.exports = restParam; diff --git a/platforms/android/cordova/node_modules/lodash/function/spread.js b/platforms/android/cordova/node_modules/lodash/function/spread.js new file mode 100644 index 0000000..780f504 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/spread.js @@ -0,0 +1,44 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). + * + * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/Web/JavaScript/Reference/Operators/Spread_operator). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to spread arguments over. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * // with a Promise + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ +function spread(func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function(array) { + return func.apply(this, array); + }; +} + +module.exports = spread; diff --git a/platforms/android/cordova/node_modules/lodash/function/throttle.js b/platforms/android/cordova/node_modules/lodash/function/throttle.js new file mode 100644 index 0000000..1dd00ea --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/throttle.js @@ -0,0 +1,62 @@ +var debounce = require('./debounce'), + isObject = require('../lang/isObject'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed invocations. Provide an options object to indicate + * that `func` should be invoked on the leading and/or trailing edge of the + * `wait` timeout. Subsequent calls to the throttled function return the + * result of the last `func` call. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify invoking on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + * + * // cancel a trailing throttled call + * jQuery(window).on('popstate', throttled.cancel); + */ +function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); +} + +module.exports = throttle; diff --git a/platforms/android/cordova/node_modules/lodash/function/wrap.js b/platforms/android/cordova/node_modules/lodash/function/wrap.js new file mode 100644 index 0000000..6a33c5e --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/function/wrap.js @@ -0,0 +1,33 @@ +var createWrapper = require('../internal/createWrapper'), + identity = require('../utility/identity'); + +/** Used to compose bitmasks for wrapper metadata. */ +var PARTIAL_FLAG = 32; + +/** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

    ' + func(text) + '

    '; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

    fred, barney, & pebbles

    ' + */ +function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); +} + +module.exports = wrap; diff --git a/platforms/android/cordova/node_modules/lodash/index.js b/platforms/android/cordova/node_modules/lodash/index.js new file mode 100644 index 0000000..5f17319 --- /dev/null +++ b/platforms/android/cordova/node_modules/lodash/index.js @@ -0,0 +1,12351 @@ +/** + * @license + * lodash 3.10.1 (Custom Build) + * Build: `lodash modern -d -o ./index.js` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '3.10.1'; + + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64, + ARY_FLAG = 128, + REARG_FLAG = 256; + + /** Used as default options for `_.trunc`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect when a function becomes hot. */ + var HOT_COUNT = 150, + HOT_SPAN = 16; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2; + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, + reUnescapedHtml = /[&<>"'`]/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; + + /** + * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) + * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). + */ + var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, + reHasRegExpChars = RegExp(reRegExpChars.source); + + /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ + var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect hexadecimal string values. */ + var reHasHexPrefix = /^0[xX]/; + + /** Used to detect host constructors (Safari > 5). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^\d+$/; + + /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ + var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; + + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + + /** Used to match words to create compound words. */ + var reWords = (function() { + var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', + lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; + + return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); + }()); + + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', + 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite', + 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' + ]; + + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dateTag] = typedArrayTags[errorTag] = + typedArrayTags[funcTag] = typedArrayTags[mapTag] = + typedArrayTags[numberTag] = typedArrayTags[objectTag] = + typedArrayTags[regexpTag] = typedArrayTags[setTag] = + typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = + cloneableTags[dateTag] = cloneableTags[float32Tag] = + cloneableTags[float64Tag] = cloneableTags[int8Tag] = + cloneableTags[int16Tag] = cloneableTags[int32Tag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[stringTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[mapTag] = cloneableTags[setTag] = + cloneableTags[weakMapTag] = false; + + /** Used to map latin-1 supplementary letters to basic latin letters. */ + var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' + }; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' + }; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used to escape characters for inclusion in compiled regexes. */ + var regexpEscapes = { + '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', + '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', + 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', + 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', + 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' + }; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; + + /** Detect free variable `self`. */ + var freeSelf = objectTypes[typeof self] && self && self.Object && self; + + /** Detect free variable `window`. */ + var freeWindow = objectTypes[typeof window] && window && window.Object && window; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `compareAscending` which compares values and + * sorts them in ascending order without guaranteeing a stable sort. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function baseCompareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without support for binary searches. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); + } + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.isFunction` without support for environments + * with incorrect `typeof` results. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + */ + function baseIsFunction(value) { + // Avoid a Chakra JIT bug in compatibility modes of IE 11. + // See https://github.com/jashkenas/underscore/issues/1621 for more details. + return typeof value == 'function' || false; + } + + /** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` or `undefined` values. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + return value == null ? '' : (value + ''); + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the first character not found in `chars`. + */ + function charsLeftIndex(string, chars) { + var index = -1, + length = string.length; + + while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the last character not found in `chars`. + */ + function charsRightIndex(string, chars) { + var index = string.length; + + while (index-- && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.sortBy` to compare transformed elements of a collection and stable + * sort them in ascending order. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareAscending(object, other) { + return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); + } + + /** + * Used by `_.sortByOrder` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, + * a value is sorted in ascending order if its corresponding order is "asc", and + * descending if "desc". + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = baseCompareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * ((order === 'asc' || order === true) ? 1 : -1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + function deburrLetter(letter) { + return deburredLetters[letter]; + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. + * + * @private + * @param {string} chr The matched character to escape. + * @param {string} leadingChar The capture group for a leading character. + * @param {string} whitespaceChar The capture group for a whitespace character. + * @returns {string} Returns the escaped character. + */ + function escapeRegExpChar(chr, leadingChar, whitespaceChar) { + if (leadingChar) { + chr = regexpEscapes[chr]; + } else if (whitespaceChar) { + chr = stringEscapes[chr]; + } + return '\\' + chr; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * + * @private + * @param {Array} array The array to search. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched `NaN`, else `-1`. + */ + function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 0 : -1); + + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; + } + } + return -1; + } + + /** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a + * character code is whitespace. + * + * @private + * @param {number} charCode The character code to inspect. + * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. + */ + function isSpace(charCode) { + return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || + (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + if (array[index] === placeholder) { + array[index] = PLACEHOLDER; + result[++resIndex] = index; + } + } + return result; + } + + /** + * An implementation of `_.uniq` optimized for sorted arrays without support + * for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function sortedUniq(array, iteratee) { + var seen, + index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (!index || seen !== computed) { + seen = computed; + result[++resIndex] = value; + } + } + return result; + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the first non-whitespace character. + */ + function trimmedLeftIndex(string) { + var index = -1, + length = string.length; + + while (++index < length && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ + function trimmedRightIndex(string) { + var index = string.length; + + while (index-- && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new pristine `lodash` function using the given `context` object. + * + * @static + * @memberOf _ + * @category Utility + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // using `context` to mock `Date#getTime` use in `_.now` + * var mock = _.runInContext({ + * 'Date': function() { + * return { 'getTime': getTimeMock }; + * } + * }); + * + * // or creating a suped-up `defer` in Node.js + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See https://es5.github.io/#x11.1.5 for more details. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** Used for native method references. */ + var arrayProto = Array.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to resolve the decompiled source of functions. */ + var fnToString = Function.prototype.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Native method references. */ + var ArrayBuffer = context.ArrayBuffer, + clearTimeout = context.clearTimeout, + parseFloat = context.parseFloat, + pow = Math.pow, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + Set = getNative(context, 'Set'), + setTimeout = context.setTimeout, + splice = arrayProto.splice, + Uint8Array = context.Uint8Array, + WeakMap = getNative(context, 'WeakMap'); + + /* Native method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeCreate = getNative(Object, 'create'), + nativeFloor = Math.floor, + nativeIsArray = getNative(Array, 'isArray'), + nativeIsFinite = context.isFinite, + nativeKeys = getNative(Object, 'keys'), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = getNative(Date, 'now'), + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used as references for `-Infinity` and `Infinity`. */ + var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, + POSITIVE_INFINITY = Number.POSITIVE_INFINITY; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit chaining. + * Methods that operate on and return arrays, collections, and functions can + * be chained together. Methods that retrieve a single value or may return a + * primitive value will automatically end the chain returning the unwrapped + * value. Explicit chaining may be enabled using `_.chain`. The execution of + * chained methods is lazy, that is, execution is deferred until `_#value` + * is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization strategy which merge iteratee calls; this can help + * to avoid the creation of intermediate data structures and greatly reduce the + * number of iteratee executions. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, + * `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, + * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, + * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, + * and `where` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, + * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, + * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, + * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, + * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, + * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, + * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, + * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, + * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, + * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, + * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, + * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, + * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, + * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, + * `unescape`, `uniqueId`, `value`, and `words` + * + * The wrapper method `sample` will return a wrapped value when `n` is provided, + * otherwise an unwrapped value is returned. + * + * @name _ + * @constructor + * @category Chain + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(total, n) { + * return total + n; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(n) { + * return n * n; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The function whose prototype all chaining wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. + */ + function LodashWrapper(value, chainAll, actions) { + this.__wrapped__ = value; + this.__actions__ = actions || []; + this.__chain__ = !!chainAll; + } + + /** + * An object environment feature flags. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB). Change the following template settings to use + * alternative delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = POSITIVE_INFINITY; + this.__views__ = []; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = arrayCopy(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = arrayCopy(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = arrayCopy(this.__views__); + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { + return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a cache object to store key/value pairs. + * + * @private + * @static + * @name Cache + * @memberOf _.memoize + */ + function MapCache() { + this.__data__ = {}; + } + + /** + * Removes `key` and its value from the cache. + * + * @private + * @name delete + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. + */ + function mapDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the cached value for `key`. + * + * @private + * @name get + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to get. + * @returns {*} Returns the cached value. + */ + function mapGet(key) { + return key == '__proto__' ? undefined : this.__data__[key]; + } + + /** + * Checks if a cached value for `key` exists. + * + * @private + * @name has + * @memberOf _.memoize.Cache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapHas(key) { + return key != '__proto__' && hasOwnProperty.call(this.__data__, key); + } + + /** + * Sets `value` to `key` of the cache. + * + * @private + * @name set + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to cache. + * @param {*} value The value to cache. + * @returns {Object} Returns the cache object. + */ + function mapSet(key, value) { + if (key != '__proto__') { + this.__data__[key] = value; + } + return this; + } + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates a cache object to store unique values. + * + * @private + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var length = values ? values.length : 0; + + this.data = { 'hash': nativeCreate(null), 'set': new Set }; + while (length--) { + this.push(values[length]); + } + } + + /** + * Checks if `value` is in `cache` mimicking the return signature of + * `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var data = cache.data, + result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; + + return result ? 0 : -1; + } + + /** + * Adds `value` to the cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ + function cachePush(value) { + var data = this.data; + if (typeof value == 'string' || isObject(value)) { + data.set.add(value); + } else { + data.hash[value] = true; + } + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a new array joining `array` with `other`. + * + * @private + * @param {Array} array The array to join. + * @param {Array} other The other array to join. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function arrayCopy(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * A specialized version of `_.forEach` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `baseExtremum` for arrays which invokes `iteratee` + * with one argument: (value). + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function arrayExtremum(array, iteratee, comparator, exValue) { + var index = -1, + length = array.length, + computed = exValue, + result = computed; + + while (++index < length) { + var value = array[index], + current = +iteratee(value); + + if (comparator(current, computed)) { + computed = current; + result = value; + } + } + return result; + } + + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * A specialized version of `_.map` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the first element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initFromArray) { + var index = -1, + length = array.length; + + if (initFromArray && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the last element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initFromArray) { + var length = array.length; + if (initFromArray && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.sum` for arrays without support for callback + * shorthands and `this` binding.. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function arraySum(array, iteratee) { + var length = array.length, + result = 0; + + while (length--) { + result += +iteratee(array[length]) || 0; + } + return result; + } + + /** + * Used by `_.defaults` to customize its `_.assign` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : objectValue; + } + + /** + * Used by `_.template` to customize its `_.assign` use. + * + * **Note:** This function is like `assignDefaults` except that it ignores + * inherited property values when checking if a property is `undefined`. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @param {string} key The key associated with the object and source values. + * @param {Object} object The destination object. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignOwnDefaults(objectValue, sourceValue, key, object) { + return (objectValue === undefined || !hasOwnProperty.call(object, key)) + ? sourceValue + : objectValue; + } + + /** + * A specialized version of `_.assign` for customizing assigned values without + * support for argument juggling, multiple sources, and `this` binding `customizer` + * functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + */ + function assignWith(object, source, customizer) { + var index = -1, + props = keys(source), + length = props.length; + + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); + + if ((result === result ? (result !== value) : (value === value)) || + (value === undefined && !(key in object))) { + object[key] = result; + } + } + return object; + } + + /** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return source == null + ? object + : baseCopy(source, keys(source), object); + } + + /** + * The base implementation of `_.at` without support for string collections + * and individual key arguments. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {number[]|string[]} props The property names or indexes of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ + function baseAt(collection, props) { + var index = -1, + isNil = collection == null, + isArr = !isNil && isArrayLike(collection), + length = isArr ? collection.length : 0, + propsLength = props.length, + result = Array(propsLength); + + while(++index < propsLength) { + var key = props[index]; + if (isArr) { + result[index] = isIndex(key, length) ? collection[key] : undefined; + } else { + result[index] = isNil ? undefined : collection[key]; + } + } + return result; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + function baseCopy(source, props, object) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; + } + + /** + * The base implementation of `_.callback` which supports specifying the + * number of arguments to provide to `func`. + * + * @private + * @param {*} [func=_.identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function baseCallback(func, thisArg, argCount) { + var type = typeof func; + if (type == 'function') { + return thisArg === undefined + ? func + : bindCallback(func, thisArg, argCount); + } + if (func == null) { + return identity; + } + if (type == 'object') { + return baseMatches(func); + } + return thisArg === undefined + ? property(func) + : baseMatchesProperty(func, thisArg); + } + + /** + * The base implementation of `_.clone` without support for argument juggling + * and `this` binding `customizer` functions. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The object `value` belongs to. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { + var result; + if (customizer) { + result = object ? customizer(value, key, object) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return arrayCopy(value, result); + } + } else { + var tag = objToString.call(value), + isFunc = tag == funcTag; + + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return baseAssign(result, value); + } + } else { + return cloneableTags[tag] + ? initCloneByTag(value, tag, isDeep) + : (object ? value : {}); + } + } + // Check for circular references and return its corresponding clone. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + // Add the source value to the stack of traversed objects and associate it with its clone. + stackA.push(value); + stackB.push(result); + + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(prototype) { + if (isObject(prototype)) { + object.prototype = prototype; + var result = new object; + object.prototype = undefined; + } + return result || {}; + }; + }()); + + /** + * The base implementation of `_.delay` and `_.defer` which accepts an index + * of where to slice the arguments to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of `_.difference` which accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values) { + var length = array ? array.length : 0, + result = []; + + if (!length) { + return result; + } + var index = -1, + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, + valuesLength = values.length; + + if (cache) { + indexOf = cacheIndexOf; + isCommon = false; + values = cache; + } + outer: + while (++index < length) { + var value = array[index]; + + if (isCommon && value === value) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === value) { + continue outer; + } + } + result.push(value); + } + else if (indexOf(values, value, 0) < 0) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.forEachRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); + + /** + * The base implementation of `_.every` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * Gets the extremum value of `collection` invoking `iteratee` for each value + * in `collection` to generate the criterion by which the value is ranked. + * The `iteratee` is invoked with three arguments: (value, index|key, collection). + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(collection, iteratee, comparator, exValue) { + var computed = exValue, + result = computed; + + baseEach(collection, function(value, index, collection) { + var current = +iteratee(value, index, collection); + if (comparator(current, computed) || (current === exValue && current === result)) { + computed = current; + result = value; + } + }); + return result; + } + + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ + function baseFill(array, value, start, end) { + var length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : (end >>> 0); + start >>>= 0; + + while (start < length) { + array[start++] = value; + } + return array; + } + + /** + * The base implementation of `_.filter` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, + * without support for callback shorthands and `this` binding, which iterates + * over `collection` using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element + * instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with added support for restricting + * flattening and specifying the start index. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, isDeep, isStrict, result) { + result || (result = []); + + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + if (isObjectLike(value) && isArrayLike(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (isDeep) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, isDeep, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); + + /** + * The base implementation of `_.forIn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForIn(object, iteratee) { + return baseFor(object, iteratee, keysIn); + } + + /** + * The base implementation of `_.forOwn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from those provided. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ + function baseFunctions(object, props) { + var index = -1, + length = props.length, + resIndex = -1, + result = []; + + while (++index < length) { + var key = props[index]; + if (isFunction(object[key])) { + result[++resIndex] = key; + } + } + return result; + } + + /** + * The base implementation of `get` without support for string paths + * and default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path of the property to get. + * @param {string} [pathKey] The key representation of path. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path, pathKey) { + if (object == null) { + return; + } + if (pathKey !== undefined && pathKey in toObject(object)) { + path = [pathKey]; + } + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[path[index++]]; + } + return (index && index == length) ? object : undefined; + } + + /** + * The base implementation of `_.isEqual` without support for `this` binding + * `customizer` functions. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing objects. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `value` objects. + * @param {Array} [stackB=[]] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objToString.call(object); + if (objTag == argsTag) { + objTag = objectTag; + } else if (objTag != objectTag) { + objIsArr = isTypedArray(object); + } + } + if (!othIsArr) { + othTag = objToString.call(other); + if (othTag == argsTag) { + othTag = objectTag; + } else if (othTag != objectTag) { + othIsArr = isTypedArray(other); + } + } + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && !(objIsArr || objIsObj)) { + return equalByTag(object, other, objTag); + } + if (!isLoose) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); + } + } + if (!isSameTag) { + return false; + } + // Assume cyclic values are equal. + // For more information on detecting circular references see https://es5.github.io/#JO. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == object) { + return stackB[length] == other; + } + } + // Add `object` and `other` to the stack of traversed objects. + stackA.push(object); + stackB.push(other); + + var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); + + stackA.pop(); + stackB.pop(); + + return result; + } + + /** + * The base implementation of `_.isMatch` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} matchData The propery names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparing objects. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = toObject(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { + return false; + } + } + } + return true; + } + + /** + * The base implementation of `_.map` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which does not clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; + + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && (value !== undefined || (key in toObject(object))); + }; + } + return function(object) { + return baseIsMatch(object, matchData); + }; + } + + /** + * The base implementation of `_.matchesProperty` which does not clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to compare. + * @returns {Function} Returns the new function. + */ + function baseMatchesProperty(path, srcValue) { + var isArr = isArray(path), + isCommon = isKey(path) && isStrictComparable(srcValue), + pathKey = (path + ''); + + path = toPath(path); + return function(object) { + if (object == null) { + return false; + } + var key = pathKey; + object = toObject(object); + if ((isArr || !isCommon) && !(key in object)) { + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + key = last(path); + object = toObject(object); + } + return object[key] === srcValue + ? (srcValue !== undefined || (key in object)) + : baseIsEqual(srcValue, object[key], undefined, true); + }; + } + + /** + * The base implementation of `_.merge` without support for argument juggling, + * multiple sources, and `this` binding `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [customizer] The function to customize merged values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {Object} Returns `object`. + */ + function baseMerge(object, source, customizer, stackA, stackB) { + if (!isObject(object)) { + return object; + } + var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), + props = isSrcArr ? undefined : keys(source); + + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; + } + if (isObjectLike(srcValue)) { + stackA || (stackA = []); + stackB || (stackB = []); + baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); + } + else { + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + } + if ((result !== undefined || (isSrcArr && !(key in object))) && + (isCommon || (result === result ? (result !== value) : (value === value)))) { + object[key] = result; + } + } + }); + return object; + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize merged values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { + var length = stackA.length, + srcValue = source[key]; + + while (length--) { + if (stackA[length] == srcValue) { + object[key] = stackB[length]; + return; + } + } + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { + result = isArray(value) + ? value + : (isArrayLike(value) ? arrayCopy(value) : []); + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + result = isArguments(value) + ? toPlainObject(value) + : (isPlainObject(value) ? value : {}); + } + else { + isCommon = false; + } + } + // Add the source value to the stack of traversed objects and associate + // it with its merged value. + stackA.push(srcValue); + stackB.push(result); + + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); + } else if (result === result ? (result !== value) : (value === value)) { + object[key] = result; + } + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ + function basePropertyDeep(path) { + var pathKey = (path + ''); + path = toPath(path); + return function(object) { + return baseGet(object, path, pathKey); + }; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * index arguments and capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0; + while (length--) { + var index = indexes[length]; + if (index != previous && isIndex(index)) { + var previous = index; + splice.call(array, index, 1); + } + } + return array; + } + + /** + * The base implementation of `_.random` without support for argument juggling + * and returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns the random number. + */ + function baseRandom(min, max) { + return min + nativeFloor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight` without support + * for callback shorthands and `this` binding, which iterates over `collection` + * using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initFromCollection Specify using the first or last element + * of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initFromCollection + ? (initFromCollection = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `setData` without support for hot loop detection. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define + * the sort order of `array` and replaces criteria objects with their + * corresponding values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * The base implementation of `_.sortByOrder` without param guards. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseSortByOrder(collection, iteratees, orders) { + var callback = getCallback(), + index = -1; + + iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); + + var result = baseMap(collection, function(value) { + var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.sum` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(collection, iteratee) { + var result = 0; + baseEach(collection, function(value, index, collection) { + result += +iteratee(value, index, collection) || 0; + }); + return result; + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function baseUniq(array, iteratee) { + var index = -1, + indexOf = getIndexOf(), + length = array.length, + isCommon = indexOf == baseIndexOf, + isLarge = isCommon && length >= LARGE_ARRAY_SIZE, + seen = isLarge ? createCache() : null, + result = []; + + if (seen) { + indexOf = cacheIndexOf; + isCommon = false; + } else { + isLarge = false; + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (isCommon && value === value) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (indexOf(seen, computed, 0) < 0) { + if (iteratee || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + var index = -1, + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /** + * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, + * and `_.takeWhile` without support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to peform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + var index = -1, + length = actions.length; + + while (++index < length) { + var action = actions[index]; + result = action.func.apply(action.thisArg, arrayPush([result], action.args)); + } + return result; + } + + /** + * Performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return binaryIndexBy(array, value, identity, retHighest); + } + + /** + * This function is like `binaryIndex` except that it invokes `iteratee` for + * `value` and each element of `array` to compute their sort ranking. The + * iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The function invoked per iteration. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); + + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsNull = value === null, + valIsUndef = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + isDef = computed !== undefined, + isReflexive = computed === computed; + + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } + + /** + * A specialized version of `baseCallback` which only supports `this` binding + * and specifying the number of arguments to provide to `func`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function bindCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + if (thisArg === undefined) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; + } + + /** + * Creates a clone of the given array buffer. + * + * @private + * @param {ArrayBuffer} buffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function bufferClone(buffer) { + var result = new ArrayBuffer(buffer.byteLength), + view = new Uint8Array(result); + + view.set(new Uint8Array(buffer)); + return result; + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders) { + var holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + leftIndex = -1, + leftLength = partials.length, + result = Array(leftLength + argsLength); + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + while (argsLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders) { + var holdersIndex = -1, + holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + rightIndex = -1, + rightLength = partials.length, + result = Array(argsLength + rightLength); + + while (++argsIndex < argsLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + return result; + } + + /** + * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. + * + * @private + * @param {Function} setter The function to set keys and values of the accumulator object. + * @param {Function} [initializer] The function to initialize the accumulator object. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee, thisArg) { + var result = initializer ? initializer() : {}; + iteratee = getCallback(iteratee, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, iteratee(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, iteratee(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a `_.assign`, `_.defaults`, or `_.merge` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return restParam(function(object, sources) { + var index = -1, + length = object == null ? 0 : sources.length, + customizer = length > 2 ? sources[length - 2] : undefined, + guard = length > 2 ? sources[2] : undefined, + thisArg = length > 1 ? sources[length - 1] : undefined; + + if (typeof customizer == 'function') { + customizer = bindCallback(customizer, thisArg, 5); + length -= 2; + } else { + customizer = typeof thisArg == 'function' ? thisArg : undefined; + length -= (customizer ? 1 : 0); + } + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + return eachFunc(collection, iteratee); + } + var index = fromRight ? length : -1, + iterable = toObject(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var iterable = toObject(object), + props = keysFunc(object), + length = props.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` and invokes it with the `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new bound function. + */ + function createBindWrapper(func, thisArg) { + var Ctor = createCtorWrapper(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(thisArg, arguments); + } + return wrapper; + } + + /** + * Creates a `Set` cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [values] The values to cache. + * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. + */ + function createCache(values) { + return (nativeCreate && Set) ? new SetCache(values) : null; + } + + /** + * Creates a function that produces compound words out of the words in a + * given string. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + var index = -1, + array = words(deburr(string)), + length = array.length, + result = ''; + + while (++index < length) { + result = callback(result, array[index], index); + } + return result; + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtorWrapper(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a `_.curry` or `_.curryRight` function. + * + * @private + * @param {boolean} flag The curry bit flag. + * @returns {Function} Returns the new curry function. + */ + function createCurry(flag) { + function curryFunc(func, arity, guard) { + if (guard && isIterateeCall(func, arity, guard)) { + arity = undefined; + } + var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryFunc.placeholder; + return result; + } + return curryFunc; + } + + /** + * Creates a `_.defaults` or `_.defaultsDeep` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @param {Function} customizer The function to customize assigned values. + * @returns {Function} Returns the new defaults function. + */ + function createDefaults(assigner, customizer) { + return restParam(function(args) { + var object = args[0]; + if (object == null) { + return object; + } + args.push(customizer); + return assigner.apply(undefined, args); + }); + } + + /** + * Creates a `_.max` or `_.min` function. + * + * @private + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {Function} Returns the new extremum function. + */ + function createExtremum(comparator, exValue) { + return function(collection, iteratee, thisArg) { + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + iteratee = getCallback(iteratee, thisArg, 3); + if (iteratee.length == 1) { + collection = isArray(collection) ? collection : toIterable(collection); + var result = arrayExtremum(collection, iteratee, comparator, exValue); + if (!(collection.length && result === exValue)) { + return result; + } + } + return baseExtremum(collection, iteratee, comparator, exValue); + }; + } + + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFind(eachFunc, fromRight) { + return function(collection, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, fromRight); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, eachFunc); + }; + } + + /** + * Creates a `_.findIndex` or `_.findLastIndex` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFindIndex(fromRight) { + return function(array, predicate, thisArg) { + if (!(array && array.length)) { + return -1; + } + predicate = getCallback(predicate, thisArg, 3); + return baseFindIndex(array, predicate, fromRight); + }; + } + + /** + * Creates a `_.findKey` or `_.findLastKey` function. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new find function. + */ + function createFindKey(objectFunc) { + return function(object, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(object, predicate, objectFunc, true); + }; + } + + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return function() { + var wrapper, + length = arguments.length, + index = fromRight ? length : -1, + leftIndex = 0, + funcs = Array(length); + + while ((fromRight ? index-- : ++index < length)) { + var func = funcs[leftIndex++] = arguments[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { + wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? -1 : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }; + } + + /** + * Creates a function for `_.forEach` or `_.forEachRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createForEach(arrayFunc, eachFunc) { + return function(collection, iteratee, thisArg) { + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee) + : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); + }; + } + + /** + * Creates a function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForIn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee, keysIn); + }; + } + + /** + * Creates a function for `_.forOwn` or `_.forOwnRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForOwn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee); + }; + } + + /** + * Creates a function for `_.mapKeys` or `_.mapValues`. + * + * @private + * @param {boolean} [isMapKeys] Specify mapping keys instead of values. + * @returns {Function} Returns the new map function. + */ + function createObjectMapper(isMapKeys) { + return function(object, iteratee, thisArg) { + var result = {}; + iteratee = getCallback(iteratee, thisArg, 3); + + baseForOwn(object, function(value, key, object) { + var mapped = iteratee(value, key, object); + key = isMapKeys ? mapped : key; + value = isMapKeys ? value : mapped; + result[key] = value; + }); + return result; + }; + } + + /** + * Creates a function for `_.padLeft` or `_.padRight`. + * + * @private + * @param {boolean} [fromRight] Specify padding from the right. + * @returns {Function} Returns the new pad function. + */ + function createPadDir(fromRight) { + return function(string, length, chars) { + string = baseToString(string); + return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); + }; + } + + /** + * Creates a `_.partial` or `_.partialRight` function. + * + * @private + * @param {boolean} flag The partial bit flag. + * @returns {Function} Returns the new partial function. + */ + function createPartial(flag) { + var partialFunc = restParam(function(func, partials) { + var holders = replaceHolders(partials, partialFunc.placeholder); + return createWrapper(func, flag, undefined, partials, holders); + }); + return partialFunc; + } + + /** + * Creates a function for `_.reduce` or `_.reduceRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createReduce(arrayFunc, eachFunc) { + return function(collection, iteratee, accumulator, thisArg) { + var initFromArray = arguments.length < 3; + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee, accumulator, initFromArray) + : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); + }; + } + + /** + * Creates a function that wraps `func` and invokes it with optional `this` + * binding of, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurry = bitmask & CURRY_FLAG, + isCurryBound = bitmask & CURRY_BOUND_FLAG, + isCurryRight = bitmask & CURRY_RIGHT_FLAG, + Ctor = isBindKey ? undefined : createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it to other functions. + var length = arguments.length, + index = length, + args = Array(length); + + while (index--) { + args[index] = arguments[index]; + } + if (partials) { + args = composeArgs(args, partials, holders); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight); + } + if (isCurry || isCurryRight) { + var placeholder = wrapper.placeholder, + argsHolders = replaceHolders(args, placeholder); + + length -= argsHolders.length; + if (length < arity) { + var newArgPos = argPos ? arrayCopy(argPos) : undefined, + newArity = nativeMax(arity - length, 0), + newsHolders = isCurry ? argsHolders : undefined, + newHoldersRight = isCurry ? undefined : argsHolders, + newPartials = isCurry ? args : undefined, + newPartialsRight = isCurry ? undefined : args; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!isCurryBound) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], + result = createHybridWrapper.apply(undefined, newData); + + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; + } + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + if (argPos) { + args = reorder(args, argPos); + } + if (isAry && ary < args.length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtorWrapper(func); + } + return fn.apply(thisBinding, args); + } + return wrapper; + } + + /** + * Creates the padding required for `string` based on the given `length`. + * The `chars` string is truncated if the number of characters exceeds `length`. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the pad for `string`. + */ + function createPadding(string, length, chars) { + var strLength = string.length; + length = +length; + + if (strLength >= length || !nativeIsFinite(length)) { + return ''; + } + var padLength = length - strLength; + chars = chars == null ? ' ' : (chars + ''); + return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); + } + + /** + * Creates a function that wraps `func` and invokes it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to partially apply arguments to. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new bound function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it `func`. + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength); + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * Creates a `_.ceil`, `_.floor`, or `_.round` function. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + precision = precision === undefined ? 0 : (+precision || 0); + if (precision) { + precision = pow(10, precision); + return func(number * precision) / precision; + } + return func(number); + }; + } + + /** + * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. + * + * @private + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {Function} Returns the new index function. + */ + function createSortedIndex(retHighest) { + return function(array, value, iteratee, thisArg) { + var callback = getCallback(iteratee); + return (iteratee == null && callback === baseCallback) + ? binaryIndex(array, value, retHighest) + : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest); + }; + } + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + length -= (holders ? holders.length : 0); + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func), + newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; + + if (data) { + mergeData(newData, data); + bitmask = newData[1]; + arity = newData[9]; + } + newData[9] = arity == null + ? (isBindKey ? 0 : func.length) + : (nativeMax(arity - length, 0) || 0); + + if (bitmask == BIND_FLAG) { + var result = createBindWrapper(newData[0], newData[2]); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { + result = createPartialWrapper.apply(undefined, newData); + } else { + result = createHybridWrapper.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing arrays. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isLoose && othLength > arrLength)) { + return false; + } + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index], + result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; + + if (result !== undefined) { + if (result) { + continue; + } + return false; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isLoose) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + })) { + return false; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { + return false; + } + } + return true; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag) { + switch (tag) { + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isLoose) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + var skipCtor = isLoose; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key], + result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; + + // Recursively compare objects (susceptible to call stack limits). + if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { + return false; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (!skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + return false; + } + } + return true; + } + + /** + * Gets the appropriate "callback" function. If the `_.callback` method is + * customized this function returns the custom method, otherwise it returns + * the `baseCallback` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function} Returns the chosen function or its result. + */ + function getCallback(func, thisArg, argCount) { + var result = lodash.callback || callback; + result = result === callback ? baseCallback : result; + return argCount ? result(func, thisArg, argCount) : result; + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; + + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = func.name, + array = realNames[result], + length = array ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized this function returns the custom method, otherwise it returns + * the `baseIndexOf` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function|number} Returns the chosen function or its result. + */ + function getIndexOf(collection, target, fromIndex) { + var result = lodash.indexOf || indexOf; + result = result === indexOf ? baseIndexOf : result; + return collection ? result(collection, target, fromIndex) : result; + } + + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Gets the propery names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = pairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; + } + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add array properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + var Ctor = object.constructor; + if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { + Ctor = Object; + } + return new Ctor; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return bufferClone(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + var buffer = object.buffer; + return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + var result = new Ctor(object.source, reFlags.exec(object)); + result.lastIndex = object.lastIndex; + } + return result; + } + + /** + * Invokes the method at `path` on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function invokePath(object, path, args) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : func.apply(object, args); + } + + /** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)); + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; + } + + /** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; + } + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + var type = typeof value; + if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { + return true; + } + if (isArray(value)) { + return false; + } + var result = !reIsDeepProp.test(value); + return result || (object != null && value in toObject(object)); + } + + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func); + if (!(funcName in LazyWrapper.prototype)) { + return false; + } + var other = lodash[funcName]; + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ + function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers required to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` + * augment function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * common case where curried functions have `_.ary` and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < ARY_FLAG; + + var isCombo = + (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || + (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || + (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = arrayCopy(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function mergeDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); + } + + /** + * A specialized version of `_.pick` which picks `object` properties specified + * by `props`. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function pickByArray(object, props) { + object = toObject(object); + + var index = -1, + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + return result; + } + + /** + * A specialized version of `_.pick` which picks `object` properties `predicate` + * returns truthy for. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per iteration. + * @returns {Object} Returns the new object. + */ + function pickByCallback(object, predicate) { + var result = {}; + baseForIn(object, function(value, key, object) { + if (predicate(value, key, object)) { + result[key] = value; + } + }); + return result; + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = arrayCopy(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity function + * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = (function() { + var count = 0, + lastCalled = 0; + + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; + } + return baseSetData(key, value); + }; + }()); + + /** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; + + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to an array-like object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array|Object} Returns the array-like object. + */ + function toIterable(value) { + if (value == null) { + return []; + } + if (!isArrayLike(value)) { + return values(value); + } + return isObject(value) ? value : Object(value); + } + + /** + * Converts `value` to an object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Object} Returns the object. + */ + function toObject(value) { + return isObject(value) ? value : Object(value); + } + + /** + * Converts `value` to property path array if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array} Returns the property path array. + */ + function toPath(value) { + if (isArray(value)) { + return value; + } + var result = []; + baseToString(value).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + return wrapper instanceof LazyWrapper + ? wrapper.clone() + : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `collection` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size == null) { + size = 1; + } else { + size = nativeMax(nativeFloor(size) || 1, 1); + } + var index = 0, + length = array ? array.length : 0, + resIndex = -1, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[++resIndex] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * Creates an array of unique `array` values not included in the other + * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([1, 2, 3], [4, 2]); + * // => [1, 3] + */ + var difference = restParam(function(array, values) { + return (isObjectLike(array) && isArrayLike(array)) + ? baseDifference(array, baseFlatten(values, false, true)) + : []; + }); + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that match the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [1] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); + * // => ['barney'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) + : []; + } + + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [3] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropWhile(users, 'active', false), 'user'); + * // => ['pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true) + : []; + } + + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8], '*', 1, 2); + * // => [4, '*', 8] + */ + function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(chr) { + * return chr.user == 'barney'; + * }); + * // => 0 + * + * // using the `_.matches` callback shorthand + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // using the `_.matchesProperty` callback shorthand + * _.findIndex(users, 'active', false); + * // => 0 + * + * // using the `_.property` callback shorthand + * _.findIndex(users, 'active'); + * // => 2 + */ + var findIndex = createFindIndex(); + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(chr) { + * return chr.user == 'pebbles'; + * }); + * // => 2 + * + * // using the `_.matches` callback shorthand + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastIndex(users, 'active', false); + * // => 2 + * + * // using the `_.property` callback shorthand + * _.findLastIndex(users, 'active'); + * // => 0 + */ + var findLastIndex = createFindIndex(true); + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias head + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([]); + * // => undefined + */ + function first(array) { + return array ? array[0] : undefined; + } + + /** + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it is only flattened a single level. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, 3, [4]]]); + * // => [1, 2, 3, [4]] + * + * // using `isDeep` + * _.flatten([1, [2, 3, [4]]], true); + * // => [1, 2, 3, 4] + */ + function flatten(array, isDeep, guard) { + var length = array ? array.length : 0; + if (guard && isIterateeCall(array, isDeep, guard)) { + isDeep = false; + } + return length ? baseFlatten(array, isDeep) : []; + } + + /** + * Recursively flattens a nested array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to recursively flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, 3, [4]]]); + * // => [1, 2, 3, 4] + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, true) : []; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` + * performs a faster binary search. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + * + * // performing a binary search + * _.indexOf([1, 1, 2, 2], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else if (fromIndex) { + var index = binaryIndex(array, value); + if (index < length && + (value === value ? (value === array[index]) : (array[index] !== array[index]))) { + return index; + } + return -1; + } + return baseIndexOf(array, value, fromIndex || 0); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + return dropRight(array, 1); + } + + /** + * Creates an array of unique values that are included in all of the provided + * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of shared values. + * @example + * _.intersection([1, 2], [4, 2], [2, 1]); + * // => [2] + */ + var intersection = restParam(function(arrays) { + var othLength = arrays.length, + othIndex = othLength, + caches = Array(length), + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + result = []; + + while (othIndex--) { + var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; + caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; + } + var array = arrays[0], + index = -1, + length = array ? array.length : 0, + seen = caches[0]; + + outer: + while (++index < length) { + value = array[index]; + if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { + var othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { + continue outer; + } + } + if (seen) { + seen.push(value); + } + result.push(value); + } + } + return result; + }); + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } + + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=array.length-1] The index to search from + * or `true` to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // using `fromIndex` + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + * + * // performing a binary search + * _.lastIndexOf([1, 1, 2, 2], 2, true); + * // => 3 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; + } else if (fromIndex) { + index = binaryIndex(array, value, true) - 1; + var other = array[index]; + if (value === value ? (value === other) : (other !== other)) { + return index; + } + return -1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull() { + var args = arguments, + array = args[0]; + + if (!(array && array.length)) { + return array; + } + var index = 0, + indexOf = getIndexOf(), + length = args.length; + + while (++index < length) { + var fromIndex = 0, + value = args[index]; + + while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** + * Removes elements from `array` corresponding to the given indexes and returns + * an array of the removed elements. Indexes may be specified as an array of + * indexes or as individual arguments. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified as individual indexes or arrays of indexes. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, 1, 3); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] + */ + var pullAt = restParam(function(array, indexes) { + indexes = baseFlatten(indexes); + + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(baseCompareAscending)); + return result; + }); + + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** Unlike `_.filter`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate, thisArg) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = getCallback(predicate, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @alias tail + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + */ + function rest(array) { + return drop(array, 1); + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of `Array#slice` to support node + * lists in IE < 9 and to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + return baseSlice(array, start, end); + } + + /** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. If an iteratee + * function is provided it is invoked for `value` and each element of `array` + * to compute their sort ranking. The iteratee is bound to `thisArg` and + * invoked with one argument; (value). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 4, 5, 5], 5); + * // => 2 + * + * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * + * // using an iteratee function + * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { + * return this.data[word]; + * }, dict); + * // => 1 + * + * // using the `_.property` callback shorthand + * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 1 + */ + var sortedIndex = createSortedIndex(); + + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 4, 5, 5], 5); + * // => 4 + */ + var sortedLastIndex = createSortedIndex(true); + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is bound to `thisArg` + * and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [2, 3] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // => [] + */ + function takeRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) + : []; + } + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [1, 2] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeWhile(users, 'active', false), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // => [] + */ + function takeWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3)) + : []; + } + + /** + * Creates an array of unique values, in order, from all of the provided arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([1, 2], [4, 2], [2, 1]); + * // => [1, 2, 4] + */ + var union = restParam(function(arrays) { + return baseUniq(baseFlatten(arrays, false, true)); + }); + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurence of each element + * is kept. Providing `true` for `isSorted` performs a faster search algorithm + * for sorted arrays. If an iteratee function is provided it is invoked for + * each element in the array to generate the criterion by which uniqueness + * is computed. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index, array). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Array + * @param {Array} array The array to inspect. + * @param {boolean} [isSorted] Specify the array is sorted. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new duplicate-value-free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + * + * // using `isSorted` + * _.uniq([1, 1, 2], true); + * // => [1, 2] + * + * // using an iteratee function + * _.uniq([1, 2.5, 1.5, 2], function(n) { + * return this.floor(n); + * }, Math); + * // => [1, 2.5] + * + * // using the `_.property` callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (isSorted != null && typeof isSorted != 'boolean') { + thisArg = iteratee; + iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; + isSorted = false; + } + var callback = getCallback(); + if (!(iteratee == null && callback === baseCallback)) { + iteratee = callback(iteratee, thisArg, 3); + } + return (isSorted && getIndexOf() == baseIndexOf) + ? sortedUniq(array, iteratee) + : baseUniq(array, iteratee); + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ + function unzip(array) { + if (!(array && array.length)) { + return []; + } + var index = -1, + length = 0; + + array = arrayFilter(array, function(group) { + if (isArrayLike(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + var result = Array(length); + while (++index < length) { + result[index] = arrayMap(array, baseProperty(index)); + } + return result; + } + + /** + * This method is like `_.unzip` except that it accepts an iteratee to specify + * how regrouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee] The function to combine regrouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ + function unzipWith(array, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + iteratee = bindCallback(iteratee, thisArg, 4); + return arrayMap(result, function(group) { + return arrayReduce(group, iteratee, undefined, true); + }); + } + + /** + * Creates an array excluding all provided values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 3], 1, 2); + * // => [3] + */ + var without = restParam(function(array, values) { + return isArrayLike(array) + ? baseDifference(array, values) + : []; + }); + + /** + * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the provided arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([1, 2], [4, 2]); + * // => [1, 4] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArrayLike(array)) { + var result = result + ? arrayPush(baseDifference(result, array), baseDifference(array, result)) + : array; + } + } + return result ? baseUniq(result) : []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second elements + * of the given arrays, and so on. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + var zip = restParam(unzip); + + /** + * The inverse of `_.pairs`; this method returns an object composed from arrays + * of property names and values. Provide either a single two dimensional array, + * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names + * and one of corresponding values. + * + * @static + * @memberOf _ + * @alias object + * @category Array + * @param {Array} props The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(props, values) { + var index = -1, + length = props ? props.length : 0, + result = {}; + + if (length && !values && !isArray(props[0])) { + values = []; + } + while (++index < length) { + var key = props[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /** + * This method is like `_.zip` except that it accepts an iteratee to specify + * how grouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee] The function to combine grouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], _.add); + * // => [111, 222] + */ + var zipWith = restParam(function(arrays) { + var length = arrays.length, + iteratee = length > 2 ? arrays[length - 2] : undefined, + thisArg = length > 1 ? arrays[length - 1] : undefined; + + if (length > 2 && typeof iteratee == 'function') { + length -= 2; + } else { + iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; + thisArg = undefined; + } + arrays.length = length; + return unzipWith(arrays, iteratee, thisArg); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps `value` with explicit method + * chaining enabled. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(users) + * .sortBy('age') + * .map(function(chr) { + * return chr.user + ' is ' + chr.age; + * }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor is + * bound to `thisArg` and invoked with one argument; (value). The purpose of + * this method is to "tap into" a method chain in order to perform operations + * on intermediate results within the chain. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor, thisArg) { + interceptor.call(thisArg, value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); + } + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(users).chain() + * .first() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } + + /** + * Creates a new array joining a wrapped array with any additional arrays + * and/or values. + * + * @name concat + * @memberOf _ + * @category Chain + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var wrapped = _(array).concat(2, [3], [[4]]); + * + * console.log(wrapped.value()); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var wrapperConcat = restParam(function(values) { + values = baseFlatten(values); + return this.thru(function(array) { + return arrayConcat(isArray(array) ? array : [toObject(array)], values); + }); + }); + + /** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).map(function(value) { + * return Math.pow(value, 2); + * }); + * + * var other = [3, 4]; + * var otherWrapped = wrapped.plant(other); + * + * otherWrapped.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } + + /** + * Reverses the wrapped array so the first element becomes the last, the + * second element becomes the second to last, and so on. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new reversed `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + + var interceptor = function(value) { + return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse(); + }; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(interceptor); + } + + /** + * Produces the result of coercing the unwrapped value to a string. + * + * @name toString + * @memberOf _ + * @category Chain + * @returns {string} Returns the coerced string value. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' + */ + function wrapperToString() { + return (this.value() + ''); + } + + /** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias run, toJSON, valueOf + * @category Chain + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements corresponding to the given keys, or indexes, + * of `collection`. Keys may be specified as individual arguments or as arrays + * of keys. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [props] The property names + * or indexes of elements to pick, specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * _.at(['a', 'b', 'c'], [0, 2]); + * // => ['a', 'c'] + * + * _.at(['barney', 'fred', 'pebbles'], 0, 2); + * // => ['barney', 'pebbles'] + */ + var at = restParam(function(collection, props) { + return baseAt(collection, baseFlatten(props)); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.filter([4, 5, 6], function(n) { + * return n % 2 == 0; + * }); + * // => [4, 6] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.filter(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.filter(users, 'active'), 'user'); + * // => ['barney'] + */ + function filter(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias detect + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.result(_.find(users, function(chr) { + * return chr.age < 40; + * }), 'user'); + * // => 'barney' + * + * // using the `_.matches` callback shorthand + * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.result(_.find(users, 'active', false), 'user'); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'barney' + */ + var find = createFind(baseEach); + + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ + var findLast = createFind(baseEachRight, true); + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning the first element that has equivalent property + * values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); + * // => 'barney' + * + * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); + * // => 'fred' + */ + function findWhere(collection, source) { + return find(collection, baseMatches(source)); + } + + /** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). Iteratee functions may exit iteration early + * by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from left to right and returns the array + * + * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { + * console.log(n, key); + * }); + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) + */ + var forEach = createForEach(arrayEach, baseEach); + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEachRight(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from right to left and returns the array + */ + var forEachRight = createForEach(arrayEachRight, baseEachRight); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using the `_.property` callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } + }); + + /** + * Checks if `value` is in `collection` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `collection`. + * + * @static + * @memberOf _ + * @alias contains, include + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} target The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ + function includes(collection, target, fromIndex, guard) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + collection = values(collection); + length = collection.length; + } + if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { + fromIndex = 0; + } else { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + } + return (typeof collection == 'string' || !isArray(collection) && isString(collection)) + ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) + : (!!length && getIndexOf(collection, target, fromIndex) > -1); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keyData = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keyData, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return String.fromCharCode(object.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return this.fromCharCode(object.code); + * }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it is + * invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + var invoke = restParam(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); + }); + return result; + }); + + /** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, + * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, + * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, + * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, + * `sum`, `uniq`, and `words` + * + * @static + * @memberOf _ + * @alias collect + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new mapped array. + * @example + * + * function timesThree(n) { + * return n * 3; + * } + * + * _.map([1, 2], timesThree); + * // => [3, 6] + * + * _.map({ 'a': 1, 'b': 2 }, timesThree); + * // => [3, 6] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // using the `_.property` callback shorthand + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee, thisArg) { + var func = isArray(collection) ? arrayMap : baseMap; + iteratee = getCallback(iteratee, thisArg, 3); + return func(collection, iteratee); + } + + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, while the second of which + * contains elements `predicate` returns falsey for. The predicate is bound + * to `thisArg` and invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * _.partition([1, 2, 3], function(n) { + * return n % 2; + * }); + * // => [[1, 3], [2]] + * + * _.partition([1.2, 2.3, 3.4], function(n) { + * return this.floor(n) % 2; + * }, Math); + * // => [[1.2, 3.4], [2.3]] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * var mapper = function(array) { + * return _.pluck(array, 'user'); + * }; + * + * // using the `_.matches` callback shorthand + * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); + * // => [['pebbles'], ['barney', 'fred']] + * + * // using the `_.matchesProperty` callback shorthand + * _.map(_.partition(users, 'active', false), mapper); + * // => [['barney', 'pebbles'], ['fred']] + * + * // using the `_.property` callback shorthand + * _.map(_.partition(users, 'active'), mapper); + * // => [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); + + /** + * Gets the property value of `path` from all elements in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|string} path The path of the property to pluck. + * @returns {Array} Returns the property values. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.pluck(users, 'user'); + * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) + */ + function pluck(collection, path) { + return map(collection, property(path)); + } + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not provided the first element of `collection` is used as the initial + * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, + * and `sortByOrder` + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(total, n) { + * return total + n; + * }); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) + */ + var reduce = createReduce(arrayReduce, baseEach); + + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + var reduceRight = createReduce(arrayReduceRight, baseEachRight); + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.reject([1, 2, 3, 4], function(n) { + * return n % 2 == 0; + * }); + * // => [1, 3] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.reject(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.reject(users, 'active'), 'user'); + * // => ['barney'] + */ + function reject(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); + } + + /** + * Gets a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {*} Returns the random sample(s). + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (guard ? isIterateeCall(collection, n, guard) : n == null) { + collection = toIterable(collection); + var length = collection.length; + return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; + } + var index = -1, + result = toArray(collection), + length = result.length, + lastIndex = length - 1; + + n = nativeMin(n < 0 ? 0 : (+n || 0), length); + while (++index < n) { + var rand = baseRandom(index, lastIndex), + value = result[rand]; + + result[rand] = result[index]; + result[index] = value; + } + result.length = n; + return result; + } + + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + return sample(collection, POSITIVE_INFINITY); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the size of `collection`. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? getLength(collection) : 0; + return isLength(length) ? length : keys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * The function returns as soon as it finds a passing value and does not iterate + * over the entire collection. The predicate is bound to `thisArg` and invoked + * with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.some(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, thisArg) { + var func = isArray(collection) ? arraySome : baseSome; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through `iteratee`. This method performs + * a stable sort, that is, it preserves the original sort order of equal elements. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new sorted array. + * @example + * + * _.sortBy([1, 2, 3], function(n) { + * return Math.sin(n); + * }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(n) { + * return this.sin(n); + * }, Math); + * // => [3, 1, 2] + * + * var users = [ + * { 'user': 'fred' }, + * { 'user': 'pebbles' }, + * { 'user': 'barney' } + * ]; + * + * // using the `_.property` callback shorthand + * _.pluck(_.sortBy(users, 'user'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function sortBy(collection, iteratee, thisArg) { + if (collection == null) { + return []; + } + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + var index = -1; + iteratee = getCallback(iteratee, thisArg, 3); + + var result = baseMap(collection, function(value, key, collection) { + return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; + }); + return baseSortBy(result, compareAscending); + } + + /** + * This method is like `_.sortBy` except that it can sort by multiple iteratees + * or property names. + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees + * The iteratees to sort by, specified as individual values or arrays of values. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.map(_.sortByAll(users, ['user', 'age']), _.values); + * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.map(_.sortByAll(users, 'user', function(chr) { + * return Math.floor(chr.age / 10); + * }), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + var sortByAll = restParam(function(collection, iteratees) { + if (collection == null) { + return []; + } + var guard = iteratees[2]; + if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { + iteratees.length = 1; + } + return baseSortByOrder(collection, baseFlatten(iteratees), []); + }); + + /** + * This method is like `_.sortByAll` except that it allows specifying the + * sort orders of the iteratees to sort by. If `orders` is unspecified, all + * values are sorted in ascending order. Otherwise, a value is sorted in + * ascending order if its corresponding order is "asc", and descending if "desc". + * + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // sort by `user` in ascending order and by `age` in descending order + * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + function sortByOrder(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (guard && isIterateeCall(iteratees, orders, guard)) { + orders = undefined; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseSortByOrder(collection, iteratees, orders); + } + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning an array of all elements that have equivalent + * property values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); + * // => ['barney'] + * + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); + * // => ['fred'] + */ + function where(collection, source) { + return filter(collection, baseMatches(source)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Date + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked + */ + var now = nativeNow || function() { + return new Date().getTime(); + }; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it is called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ + function after(n, func) { + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + n = nativeIsFinite(n = +n) ? n : 0; + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that accepts up to `n` arguments ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ + function ary(func, n, guard) { + if (guard && isIterateeCall(func, n, guard)) { + n = undefined; + } + n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it is called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery('#add').on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method does not set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // using placeholders + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = restParam(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bind.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); + }); + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all enumerable function + * properties, own and inherited, of `object` are bound. + * + * **Note:** This method does not set the "length" property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} [methodNames] The object method names to bind, + * specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs' when the element is clicked + */ + var bindAll = restParam(function(object, methodNames) { + methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); + + var index = -1, + length = methodNames.length; + + while (++index < length) { + var key = methodNames[index]; + object[key] = createWrapper(object[key], BIND_FLAG, object); + } + return object; + }); + + /** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // using placeholders + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + var bindKey = restParam(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bindKey.placeholder); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); + }); + + /** + * Creates a function that accepts one or more arguments of `func` that when + * called either invokes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` may be specified + * if `func.length` is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + var curry = createCurry(CURRY_FLAG); + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ + var curryRight = createCurry(CURRY_RIGHT_FLAG); + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. + * Subsequent calls to the debounced function return the result of the last + * `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it is invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // invoke `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // ensure `batchLog` is invoked once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * jQuery(source).on('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * })); + * + * // cancel a debounced call + * var todoChanges = _.debounce(batchLog, 1000); + * Object.observe(models.todo, todoChanges); + * + * Object.observe(models, function(changes) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { + * todoChanges.cancel(); + * } + * }, ['delete']); + * + * // ...at some point `models.todo` is changed + * models.todo.completed = true; + * + * // ...before 1 second has passed `models.todo` is deleted + * // which cancels the debounced `todoChanges` call + * delete models.todo; + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = wait < 0 ? 0 : (+wait || 0); + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = !!options.leading; + maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + lastCalled = 0; + maxTimeoutId = timeoutId = trailingCall = undefined; + } + + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function maxDelayed() { + complete(trailing, timeoutId); + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0 || remaining > maxWait; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + return result; + } + debounced.cancel = cancel; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + var defer = restParam(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ + var delay = restParam(function(func, wait, args) { + return baseDelay(func, wait, args); + }); + + /** + * Creates a function that returns the result of invoking the provided + * functions with the `this` binding of the created function, where each + * successive invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 + */ + var flow = createFlow(); + + /** + * This method is like `_.flow` except that it creates a function that + * invokes the provided functions from right to left. + * + * @static + * @memberOf _ + * @alias backflow, compose + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 + */ + var flowRight = createFlow(true); + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is coerced to a string and used as the + * cache key. The `func` is invoked with the `this` binding of the memoized + * function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) + * method interface of `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var upperCase = _.memoize(function(string) { + * return string.toUpperCase(); + * }); + * + * upperCase('fred'); + * // => 'FRED' + * + * // modifying the result cache + * upperCase.cache.set('fred', 'BARNEY'); + * upperCase('fred'); + * // => 'BARNEY' + * + * // replacing `_.memoize.Cache` + * var object = { 'user': 'fred' }; + * var other = { 'user': 'barney' }; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'fred' } + * + * _.memoize.Cache = WeakMap; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'barney' } + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; + } + + /** + * Creates a function that runs each argument through a corresponding + * transform function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified as individual functions or arrays of functions. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var modded = _.modArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * modded(1, 2); + * // => [1, 4] + * + * modded(5, 10); + * // => [25, 20] + */ + var modArgs = restParam(function(func, transforms) { + transforms = baseFlatten(transforms); + if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = transforms.length; + return restParam(function(args) { + var index = nativeMin(args.length, length); + while (index--) { + args[index] = transforms[index](args[index]); + } + return func.apply(this, args); + }); + }); + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first call. The `func` is invoked + * with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. This method is like `_.bind` except + * it does **not** alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // using placeholders + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ + var partial = createPartial(PARTIAL_FLAG); + + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // using placeholders + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ + var partialRight = createPartial(PARTIAL_RIGHT_FLAG); + + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified indexes where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, + * specified as individual indexes or arrays of indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + * + * var map = _.rearg(_.map, [1, 0]); + * map(function(n) { + * return n * 3; + * }, [1, 2, 3]); + * // => [3, 6, 9] + */ + var rearg = restParam(function(func, indexes) { + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); + }); + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); + + while (++index < length) { + rest[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). + * + * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to spread arguments over. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * // with a Promise + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ + function spread(func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function(array) { + return func.apply(this, array); + }; + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed invocations. Provide an options object to indicate + * that `func` should be invoked on the leading and/or trailing edge of the + * `wait` timeout. Subsequent calls to the throttled function return the + * result of the last `func` call. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify invoking on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + * + * // cancel a trailing throttled call + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

    ' + func(text) + '

    '; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

    fred, barney, & pebbles

    ' + */ + function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, + * otherwise they are assigned by reference. If `customizer` is provided it is + * invoked to produce the cloned values. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is bound to + * `thisArg` and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var shallow = _.clone(users); + * shallow[0] === users[0]; + * // => true + * + * var deep = _.clone(users, true); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.clone(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, customizer, thisArg) { + if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { + isDeep = false; + } + else if (typeof isDeep == 'function') { + thisArg = customizer; + customizer = isDeep; + isDeep = false; + } + return typeof customizer == 'function' + ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1)) + : baseClone(value, isDeep); + } + + /** + * Creates a deep clone of `value`. If `customizer` is provided it is invoked + * to produce the cloned values. If `customizer` returns `undefined` cloning + * is handled by the method instead. The `customizer` is bound to `thisArg` + * and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var deep = _.cloneDeep(users); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.cloneDeep(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 20 + */ + function cloneDeep(value, customizer, thisArg) { + return typeof customizer == 'function' + ? baseClone(value, true, bindCallback(customizer, thisArg, 1)) + : baseClone(value, true); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + function gt(value, other) { + return value > other; + } + + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ + function gte(value, other) { + return value >= other; + } + + /** + * Checks if `value` is classified as an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return isObjectLike(value) && isArrayLike(value) && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(function() { return arguments; }()); + * // => false + */ + var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; + }; + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); + } + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + function isDate(value) { + return isObjectLike(value) && objToString.call(value) == dateTag; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); + } + + /** + * Checks if `value` is empty. A value is considered empty unless it is an + * `arguments` object, array, string, or jQuery-like collection with a length + * greater than `0` or an object with own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || + (isObjectLike(value) && isFunction(value.splice)))) { + return !value.length; + } + return !keys(value).length; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. If `customizer` is provided it is invoked to compare values. + * If `customizer` returns `undefined` comparisons are handled by the method + * instead. The `customizer` is bound to `thisArg` and invoked with three + * arguments: (value, other [, index|key]). + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. Functions and DOM nodes + * are **not** supported. Provide a customizer function to extend support + * for comparing other values. + * + * @static + * @memberOf _ + * @alias eq + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * object == other; + * // => false + * + * _.isEqual(object, other); + * // => true + * + * // using a customizer callback + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqual(array, other, function(value, other) { + * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { + * return true; + * } + * }); + * // => true + */ + function isEqual(value, other, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(10); + * // => true + * + * _.isFinite('10'); + * // => false + * + * _.isFinite(true); + * // => false + * + * _.isFinite(Object(10)); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return isObject(value) && objToString.call(value) == funcTag; + } + + /** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Performs a deep comparison between `object` and `source` to determine if + * `object` contains equivalent property values. If `customizer` is provided + * it is invoked to compare values. If `customizer` returns `undefined` + * comparisons are handled by the method instead. The `customizer` is bound + * to `thisArg` and invoked with three arguments: (value, other, index|key). + * + * **Note:** This method supports comparing properties of arrays, booleans, + * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions + * and DOM nodes are **not** supported. Provide a customizer function to extend + * support for comparing other values. + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + * + * // using a customizer callback + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatch(object, source, function(value, other) { + * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; + * }); + * // => true + */ + function isMatch(object, source, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + return baseIsMatch(object, getMatchData(source), customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some host objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(8.4); + * // => true + * + * _.isNumber(NaN); + * // => true + * + * _.isNumber('8.4'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * **Note:** This method assumes objects created by the `Object` constructor + * have no inherited enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + var Ctor; + + // Exit early for non `Object` objects. + if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) || + (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + var result; + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + baseForIn(value, function(subValue, key) { + result = key; + }); + return result === undefined || hasOwnProperty.call(value, result); + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + function isRegExp(value) { + return isObject(value) && objToString.call(value) == regexpTag; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + function isTypedArray(value) { + return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + function lt(value, other) { + return value < other; + } + + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ + function lte(value, other) { + return value <= other; + } + + /** + * Converts `value` to an array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * (function() { + * return _.toArray(arguments).slice(1); + * }(1, 2, 3)); + * // => [2, 3] + */ + function toArray(value) { + var length = value ? getLength(value) : 0; + if (!isLength(length)) { + return values(value); + } + if (!length) { + return []; + } + return arrayCopy(value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable + * properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return baseCopy(value, keysIn(value)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * overwrite property assignments of previous sources. If `customizer` is + * provided it is invoked to produce the merged values of the destination and + * source properties. If `customizer` returns `undefined` merging is handled + * by the method instead. The `customizer` is bound to `thisArg` and invoked + * with five arguments: (objectValue, sourceValue, key, object, source). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + * + * // using a customizer callback + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(object, other, function(a, b) { + * if (_.isArray(a)) { + * return a.concat(b); + * } + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + var merge = createAssigner(baseMerge); + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it is invoked to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments: + * (objectValue, sourceValue, key, object, source). + * + * **Note:** This method mutates `object` and is based on + * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } + * + * // using a customizer callback + * var defaults = _.partialRight(_.assign, function(value, other) { + * return _.isUndefined(value) ? other : value; + * }); + * + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var assign = createAssigner(function(object, source, customizer) { + return customizer + ? assignWith(object, source, customizer) + : baseAssign(object, source); + }); + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = undefined; + } + return properties ? baseAssign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var defaults = createDefaults(assign, assignDefaults); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } + * + */ + var defaultsDeep = createDefaults(merge, mergeDefaults); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (iteration order is not guaranteed) + * + * // using the `_.matches` callback shorthand + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.findKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findKey(users, 'active'); + * // => 'barney' + */ + var findKey = createFindKey(baseForOwn); + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles` assuming `_.findKey` returns `barney` + * + * // using the `_.matches` callback shorthand + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + var findLastKey = createFindKey(baseForOwnRight); + + /** + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) + */ + var forIn = createForIn(baseFor); + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' + */ + var forInRight = createForIn(baseForRight); + + /** + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The `iteratee` is bound to `thisArg` and invoked with + * three arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' and 'b' (iteration order is not guaranteed) + */ + var forOwn = createForOwn(baseForOwn); + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' + */ + var forOwnRight = createForOwn(baseForOwnRight); + + /** + * Creates an array of function property names from all enumerable properties, + * own and inherited, of `object`. + * + * @static + * @memberOf _ + * @alias methods + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * _.functions(_); + * // => ['after', 'ary', 'assign', ...] + */ + function functions(object) { + return baseFunctions(object, keysIn(object)); + } + + /** + * Gets the property value at `path` of `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, toPath(path), path + ''); + return result === undefined ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + */ + function has(object, path) { + if (object == null) { + return false; + } + var result = hasOwnProperty.call(object, path); + if (!result && !isKey(path)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + path = last(path); + result = hasOwnProperty.call(object, path); + } + return result || (isLength(object.length) && isIndex(path, object.length) && + (isArray(object) || isArguments(object))); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite property + * assignments of previous values unless `multiValue` is `true`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @param {boolean} [multiValue] Allow multiple values per key. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + * + * // with `multiValue` + * _.invert(object, true); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function invert(object, multiValue, guard) { + if (guard && isIterateeCall(object, multiValue, guard)) { + multiValue = undefined; + } + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index], + value = object[key]; + + if (multiValue) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + } + else { + result[value] = key; + } + } + return result; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object == null ? undefined : object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; + }; + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || isArguments(object)) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * property of `object` through `iteratee`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + var mapKeys = createObjectMapper(true); + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through `iteratee`. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, key, object). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { + * return n * 3; + * }); + * // => { 'a': 3, 'b': 6 } + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * // using the `_.property` callback shorthand + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + var mapValues = createObjectMapper(); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to omit, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.omit(object, 'age'); + * // => { 'user': 'fred' } + * + * _.omit(object, _.isNumber); + * // => { 'user': 'fred' } + */ + var omit = restParam(function(object, props) { + if (object == null) { + return {}; + } + if (typeof props[0] != 'function') { + var props = arrayMap(baseFlatten(props), String); + return pickByArray(object, baseDifference(keysIn(object), props)); + } + var predicate = bindCallback(props[0], props[1], 3); + return pickByCallback(object, function(value, key, object) { + return !predicate(value, key, object); + }); + }); + + /** + * Creates a two dimensional array of the key-value pairs for `object`, + * e.g. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) + */ + function pairs(object) { + object = toObject(object); + + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates an object composed of the picked `object` properties. Property + * names may be specified as individual arguments or as arrays of property + * names. If `predicate` is provided it is invoked for each property of `object` + * picking the properties `predicate` returns truthy for. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.pick(object, 'user'); + * // => { 'user': 'fred' } + * + * _.pick(object, _.isString); + * // => { 'user': 'fred' } + */ + var pick = restParam(function(object, props) { + if (object == null) { + return {}; + } + return typeof props[0] == 'function' + ? pickByCallback(object, bindCallback(props[0], props[1], 3)) + : pickByArray(object, baseFlatten(props)); + }); + + /** + * This method is like `_.get` except that if the resolved value is a function + * it is invoked with the `this` binding of its parent object and its result + * is returned. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a.b.c', 'default'); + * // => 'default' + * + * _.result(object, 'a.b.c', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + var result = object == null ? undefined : object[path]; + if (result === undefined) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + result = object == null ? undefined : object[last(path)]; + } + result = result === undefined ? defaultValue : result; + } + return isFunction(result) ? result.call(object) : result; + } + + /** + * Sets the property value of `path` on `object`. If a portion of `path` + * does not exist it is created. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to augment. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, 'x[0].y.z', 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + if (object == null) { + return object; + } + var pathKey = (path + ''); + path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + if (index == lastIndex) { + nested[key] = value; + } else if (nested[key] == null) { + nested[key] = isIndex(path[index + 1]) ? [] : {}; + } + } + nested = nested[key]; + } + return object; + } + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own enumerable + * properties through `iteratee`, with each invocation potentially mutating + * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked + * with four arguments: (accumulator, value, key, object). Iteratee functions + * may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Array|Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * }); + * // => { 'a': 3, 'b': 6 } + */ + function transform(object, iteratee, accumulator, thisArg) { + var isArr = isArray(object) || isTypedArray(object); + iteratee = getCallback(iteratee, thisArg, 4); + + if (accumulator == null) { + if (isArr || isObject(object)) { + var Ctor = object.constructor; + if (isArr) { + accumulator = isArray(object) ? new Ctor : []; + } else { + accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); + } + } else { + accumulator = {}; + } + } + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Creates an array of the own enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return baseValues(object, keys(object)); + } + + /** + * Creates an array of the own and inherited enumerable property values + * of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Checks if `n` is between `start` and up to but not including, `end`. If + * `end` is not specified it is set to `start` with `start` then set to `0`. + * + * @static + * @memberOf _ + * @category Number + * @param {number} n The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `n` is in the range, else `false`. + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + */ + function inRange(value, start, end) { + start = +start || 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = +end || 0; + } + return value >= nativeMin(start, end) && value < nativeMax(start, end); + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number is returned. + * If `floating` is `true`, or either `min` or `max` are floats, a floating-point + * number is returned instead of an integer. + * + * @static + * @memberOf _ + * @category Number + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + if (floating && isIterateeCall(min, max, floating)) { + max = floating = undefined; + } + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (noMax && typeof min == 'boolean') { + floating = min; + min = 1; + } + else if (typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + noMax = false; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); + } + return baseRandom(min, max); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar'); + * // => 'fooBar' + * + * _.camelCase('__foo_bar__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); + }); + + /** + * Capitalizes the first character of `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('fred'); + * // => 'Fred' + */ + function capitalize(string) { + string = baseToString(string); + return string && (string.charAt(0).toUpperCase() + string.slice(1)); + } + + /** + * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = baseToString(string); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search from. + * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = baseToString(string); + target = (target + ''); + + var length = string.length; + position = position === undefined + ? length + : nativeMin(position < 0 ? 0 : (+position || 0), length); + + position -= target.length; + return position >= 0 && string.indexOf(target, position) == position; + } + + /** + * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional characters + * use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in Internet Explorer < 9, they can break out + * of attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + // Reset `lastIndex` because in IE < 9 `String#replace` does not. + string = baseToString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", + * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' + */ + function escapeRegExp(string) { + string = baseToString(string); + return (string && reHasRegExpChars.test(string)) + ? string.replace(reRegExpChars, escapeRegExpChar) + : (string || '(?:)'); + } + + /** + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = baseToString(string); + length = +length; + + var strLength = string.length; + if (strLength >= length || !nativeIsFinite(length)) { + return string; + } + var mid = (length - strLength) / 2, + leftLength = nativeFloor(mid), + rightLength = nativeCeil(mid); + + chars = createPadding('', rightLength, chars); + return chars.slice(0, leftLength) + string + chars; + } + + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padLeft('abc', 6); + * // => ' abc' + * + * _.padLeft('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padLeft('abc', 3); + * // => 'abc' + */ + var padLeft = createPadDir(); + + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padRight('abc', 6); + * // => 'abc ' + * + * _.padRight('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padRight('abc', 3); + * // => 'abc' + */ + var padRight = createPadDir(true); + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, + * in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E) + * of `parseInt`. + * + * @static + * @memberOf _ + * @category String + * @param {string} string The string to convert. + * @param {number} [radix] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. + // Chrome fails to trim leading whitespace characters. + // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. + if (guard ? isIterateeCall(string, radix, guard) : radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + string = trim(string); + return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=0] The number of times to repeat the string. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n) { + var result = ''; + string = baseToString(string); + n = +n; + if (n < 1 || !string || !nativeIsFinite(n)) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + string += string; + } while (n); + + return result; + } + + /** + * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--foo-bar'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = baseToString(string); + position = position == null + ? 0 + : nativeMin(position < 0 ? 0 : (+position || 0), string.length); + + return string.lastIndexOf(target, position) == position; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is provided it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as free variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. + * @param {string} [options.variable] The data object variable name. + * @param- {Object} [otherOptions] Enables the legacy `options` param signature. + * @returns {Function} Returns the compiled template function. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // using the HTML "escape" delimiter to escape data property values + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': ' + +``` + + +## API + +### Parsing + +Parsing a plist from filename: + +``` javascript +var fs = require('fs'); +var plist = require('plist'); + +var obj = plist.parse(fs.readFileSync('myPlist.plist', 'utf8')); +console.log(JSON.stringify(obj)); +``` + +Parsing a plist from string payload: + +``` javascript +var plist = require('plist'); + +var obj = plist.parse('Hello World!'); +console.log(obj); // Hello World! +``` + +### Building + +Given an existing JavaScript Object, you can turn it into an XML document +that complies with the plist DTD: + +``` javascript +var plist = require('plist'); + +console.log(plist.build({ foo: 'bar' })); +``` + + +## License + +(The MIT License) + +Copyright (c) 2010-2014 Nathan Rajlich + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/cordova/node_modules/plist/dist/plist-build.js b/platforms/android/cordova/node_modules/plist/dist/plist-build.js new file mode 100644 index 0000000..4fcd378 --- /dev/null +++ b/platforms/android/cordova/node_modules/plist/dist/plist-build.js @@ -0,0 +1,3982 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.plist = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + var len = b64.length + placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(b64.length * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length + + var L = 0 + + function push (v) { + arr[L++] = v + } + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) + push((tmp & 0xFF0000) >> 16) + push((tmp & 0xFF00) >> 8) + push(tmp & 0xFF) + } + + if (placeHolders === 2) { + tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) + push(tmp & 0xFF) + } else if (placeHolders === 1) { + tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) + push((tmp >> 8) & 0xFF) + push(tmp & 0xFF) + } + + return arr + } + + function uint8ToBase64 (uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length + + function encode (num) { + return lookup.charAt(num) + } + + function tripletToBase64 (num) { + return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) + } + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output += tripletToBase64(temp) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1] + output += encode(temp >> 2) + output += encode((temp << 4) & 0x3F) + output += '==' + break + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) + output += encode(temp >> 10) + output += encode((temp >> 4) & 0x3F) + output += encode((temp << 2) & 0x3F) + output += '=' + break + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) + +},{}],3:[function(require,module,exports){ +/** + * Determine if an object is Buffer + * + * Author: Feross Aboukhadijeh + * License: MIT + * + * `npm install is-buffer` + */ + +module.exports = function (obj) { + return !!(obj != null && + (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) + (obj.constructor && + typeof obj.constructor.isBuffer === 'function' && + obj.constructor.isBuffer(obj)) + )) +} + +},{}],4:[function(require,module,exports){ +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; +} + +module.exports = last; + +},{}],5:[function(require,module,exports){ +var arrayEvery = require('../internal/arrayEvery'), + baseCallback = require('../internal/baseCallback'), + baseEvery = require('../internal/baseEvery'), + isArray = require('../lang/isArray'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.every(users, 'active'); + * // => false + */ +function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = baseCallback(predicate, thisArg, 3); + } + return func(collection, predicate); +} + +module.exports = every; + +},{"../internal/arrayEvery":7,"../internal/baseCallback":11,"../internal/baseEvery":15,"../internal/isIterateeCall":40,"../lang/isArray":49}],6:[function(require,module,exports){ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ +function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); + + while (++index < length) { + rest[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; +} + +module.exports = restParam; + +},{}],7:[function(require,module,exports){ +/** + * A specialized version of `_.every` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ +function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; +} + +module.exports = arrayEvery; + +},{}],8:[function(require,module,exports){ +/** + * A specialized version of `_.some` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +module.exports = arraySome; + +},{}],9:[function(require,module,exports){ +var keys = require('../object/keys'); + +/** + * A specialized version of `_.assign` for customizing assigned values without + * support for argument juggling, multiple sources, and `this` binding `customizer` + * functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + */ +function assignWith(object, source, customizer) { + var index = -1, + props = keys(source), + length = props.length; + + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); + + if ((result === result ? (result !== value) : (value === value)) || + (value === undefined && !(key in object))) { + object[key] = result; + } + } + return object; +} + +module.exports = assignWith; + +},{"../object/keys":58}],10:[function(require,module,exports){ +var baseCopy = require('./baseCopy'), + keys = require('../object/keys'); + +/** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return source == null + ? object + : baseCopy(source, keys(source), object); +} + +module.exports = baseAssign; + +},{"../object/keys":58,"./baseCopy":12}],11:[function(require,module,exports){ +var baseMatches = require('./baseMatches'), + baseMatchesProperty = require('./baseMatchesProperty'), + bindCallback = require('./bindCallback'), + identity = require('../utility/identity'), + property = require('../utility/property'); + +/** + * The base implementation of `_.callback` which supports specifying the + * number of arguments to provide to `func`. + * + * @private + * @param {*} [func=_.identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ +function baseCallback(func, thisArg, argCount) { + var type = typeof func; + if (type == 'function') { + return thisArg === undefined + ? func + : bindCallback(func, thisArg, argCount); + } + if (func == null) { + return identity; + } + if (type == 'object') { + return baseMatches(func); + } + return thisArg === undefined + ? property(func) + : baseMatchesProperty(func, thisArg); +} + +module.exports = baseCallback; + +},{"../utility/identity":61,"../utility/property":62,"./baseMatches":22,"./baseMatchesProperty":23,"./bindCallback":28}],12:[function(require,module,exports){ +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ +function baseCopy(source, props, object) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; +} + +module.exports = baseCopy; + +},{}],13:[function(require,module,exports){ +var isObject = require('../lang/isObject'); + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ +var baseCreate = (function() { + function object() {} + return function(prototype) { + if (isObject(prototype)) { + object.prototype = prototype; + var result = new object; + object.prototype = undefined; + } + return result || {}; + }; +}()); + +module.exports = baseCreate; + +},{"../lang/isObject":53}],14:[function(require,module,exports){ +var baseForOwn = require('./baseForOwn'), + createBaseEach = require('./createBaseEach'); + +/** + * The base implementation of `_.forEach` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ +var baseEach = createBaseEach(baseForOwn); + +module.exports = baseEach; + +},{"./baseForOwn":17,"./createBaseEach":30}],15:[function(require,module,exports){ +var baseEach = require('./baseEach'); + +/** + * The base implementation of `_.every` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ +function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; +} + +module.exports = baseEvery; + +},{"./baseEach":14}],16:[function(require,module,exports){ +var createBaseFor = require('./createBaseFor'); + +/** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ +var baseFor = createBaseFor(); + +module.exports = baseFor; + +},{"./createBaseFor":31}],17:[function(require,module,exports){ +var baseFor = require('./baseFor'), + keys = require('../object/keys'); + +/** + * The base implementation of `_.forOwn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return baseFor(object, iteratee, keys); +} + +module.exports = baseForOwn; + +},{"../object/keys":58,"./baseFor":16}],18:[function(require,module,exports){ +var toObject = require('./toObject'); + +/** + * The base implementation of `get` without support for string paths + * and default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path of the property to get. + * @param {string} [pathKey] The key representation of path. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path, pathKey) { + if (object == null) { + return; + } + if (pathKey !== undefined && pathKey in toObject(object)) { + path = [pathKey]; + } + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[path[index++]]; + } + return (index && index == length) ? object : undefined; +} + +module.exports = baseGet; + +},{"./toObject":46}],19:[function(require,module,exports){ +var baseIsEqualDeep = require('./baseIsEqualDeep'), + isObject = require('../lang/isObject'), + isObjectLike = require('./isObjectLike'); + +/** + * The base implementation of `_.isEqual` without support for `this` binding + * `customizer` functions. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); +} + +module.exports = baseIsEqual; + +},{"../lang/isObject":53,"./baseIsEqualDeep":20,"./isObjectLike":43}],20:[function(require,module,exports){ +var equalArrays = require('./equalArrays'), + equalByTag = require('./equalByTag'), + equalObjects = require('./equalObjects'), + isArray = require('../lang/isArray'), + isTypedArray = require('../lang/isTypedArray'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing objects. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `value` objects. + * @param {Array} [stackB=[]] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objToString.call(object); + if (objTag == argsTag) { + objTag = objectTag; + } else if (objTag != objectTag) { + objIsArr = isTypedArray(object); + } + } + if (!othIsArr) { + othTag = objToString.call(other); + if (othTag == argsTag) { + othTag = objectTag; + } else if (othTag != objectTag) { + othIsArr = isTypedArray(other); + } + } + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && !(objIsArr || objIsObj)) { + return equalByTag(object, other, objTag); + } + if (!isLoose) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); + } + } + if (!isSameTag) { + return false; + } + // Assume cyclic values are equal. + // For more information on detecting circular references see https://es5.github.io/#JO. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == object) { + return stackB[length] == other; + } + } + // Add `object` and `other` to the stack of traversed objects. + stackA.push(object); + stackB.push(other); + + var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); + + stackA.pop(); + stackB.pop(); + + return result; +} + +module.exports = baseIsEqualDeep; + +},{"../lang/isArray":49,"../lang/isTypedArray":55,"./equalArrays":32,"./equalByTag":33,"./equalObjects":34}],21:[function(require,module,exports){ +var baseIsEqual = require('./baseIsEqual'), + toObject = require('./toObject'); + +/** + * The base implementation of `_.isMatch` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} matchData The propery names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparing objects. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = toObject(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { + return false; + } + } + } + return true; +} + +module.exports = baseIsMatch; + +},{"./baseIsEqual":19,"./toObject":46}],22:[function(require,module,exports){ +var baseIsMatch = require('./baseIsMatch'), + getMatchData = require('./getMatchData'), + toObject = require('./toObject'); + +/** + * The base implementation of `_.matches` which does not clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ +function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; + + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && (value !== undefined || (key in toObject(object))); + }; + } + return function(object) { + return baseIsMatch(object, matchData); + }; +} + +module.exports = baseMatches; + +},{"./baseIsMatch":21,"./getMatchData":36,"./toObject":46}],23:[function(require,module,exports){ +var baseGet = require('./baseGet'), + baseIsEqual = require('./baseIsEqual'), + baseSlice = require('./baseSlice'), + isArray = require('../lang/isArray'), + isKey = require('./isKey'), + isStrictComparable = require('./isStrictComparable'), + last = require('../array/last'), + toObject = require('./toObject'), + toPath = require('./toPath'); + +/** + * The base implementation of `_.matchesProperty` which does not clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to compare. + * @returns {Function} Returns the new function. + */ +function baseMatchesProperty(path, srcValue) { + var isArr = isArray(path), + isCommon = isKey(path) && isStrictComparable(srcValue), + pathKey = (path + ''); + + path = toPath(path); + return function(object) { + if (object == null) { + return false; + } + var key = pathKey; + object = toObject(object); + if ((isArr || !isCommon) && !(key in object)) { + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + key = last(path); + object = toObject(object); + } + return object[key] === srcValue + ? (srcValue !== undefined || (key in object)) + : baseIsEqual(srcValue, object[key], undefined, true); + }; +} + +module.exports = baseMatchesProperty; + +},{"../array/last":4,"../lang/isArray":49,"./baseGet":18,"./baseIsEqual":19,"./baseSlice":26,"./isKey":41,"./isStrictComparable":44,"./toObject":46,"./toPath":47}],24:[function(require,module,exports){ +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +module.exports = baseProperty; + +},{}],25:[function(require,module,exports){ +var baseGet = require('./baseGet'), + toPath = require('./toPath'); + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ +function basePropertyDeep(path) { + var pathKey = (path + ''); + path = toPath(path); + return function(object) { + return baseGet(object, path, pathKey); + }; +} + +module.exports = basePropertyDeep; + +},{"./baseGet":18,"./toPath":47}],26:[function(require,module,exports){ +/** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; +} + +module.exports = baseSlice; + +},{}],27:[function(require,module,exports){ +/** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` or `undefined` values. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + return value == null ? '' : (value + ''); +} + +module.exports = baseToString; + +},{}],28:[function(require,module,exports){ +var identity = require('../utility/identity'); + +/** + * A specialized version of `baseCallback` which only supports `this` binding + * and specifying the number of arguments to provide to `func`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ +function bindCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + if (thisArg === undefined) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; +} + +module.exports = bindCallback; + +},{"../utility/identity":61}],29:[function(require,module,exports){ +var bindCallback = require('./bindCallback'), + isIterateeCall = require('./isIterateeCall'), + restParam = require('../function/restParam'); + +/** + * Creates a `_.assign`, `_.defaults`, or `_.merge` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return restParam(function(object, sources) { + var index = -1, + length = object == null ? 0 : sources.length, + customizer = length > 2 ? sources[length - 2] : undefined, + guard = length > 2 ? sources[2] : undefined, + thisArg = length > 1 ? sources[length - 1] : undefined; + + if (typeof customizer == 'function') { + customizer = bindCallback(customizer, thisArg, 5); + length -= 2; + } else { + customizer = typeof thisArg == 'function' ? thisArg : undefined; + length -= (customizer ? 1 : 0); + } + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }); +} + +module.exports = createAssigner; + +},{"../function/restParam":6,"./bindCallback":28,"./isIterateeCall":40}],30:[function(require,module,exports){ +var getLength = require('./getLength'), + isLength = require('./isLength'), + toObject = require('./toObject'); + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + return eachFunc(collection, iteratee); + } + var index = fromRight ? length : -1, + iterable = toObject(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +module.exports = createBaseEach; + +},{"./getLength":35,"./isLength":42,"./toObject":46}],31:[function(require,module,exports){ +var toObject = require('./toObject'); + +/** + * Creates a base function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var iterable = toObject(object), + props = keysFunc(object), + length = props.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; +} + +module.exports = createBaseFor; + +},{"./toObject":46}],32:[function(require,module,exports){ +var arraySome = require('./arraySome'); + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing arrays. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isLoose && othLength > arrLength)) { + return false; + } + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index], + result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; + + if (result !== undefined) { + if (result) { + continue; + } + return false; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isLoose) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + })) { + return false; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { + return false; + } + } + return true; +} + +module.exports = equalArrays; + +},{"./arraySome":8}],33:[function(require,module,exports){ +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + stringTag = '[object String]'; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag) { + switch (tag) { + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + } + return false; +} + +module.exports = equalByTag; + +},{}],34:[function(require,module,exports){ +var keys = require('../object/keys'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isLoose) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + var skipCtor = isLoose; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key], + result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; + + // Recursively compare objects (susceptible to call stack limits). + if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { + return false; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (!skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + return false; + } + } + return true; +} + +module.exports = equalObjects; + +},{"../object/keys":58}],35:[function(require,module,exports){ +var baseProperty = require('./baseProperty'); + +/** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ +var getLength = baseProperty('length'); + +module.exports = getLength; + +},{"./baseProperty":24}],36:[function(require,module,exports){ +var isStrictComparable = require('./isStrictComparable'), + pairs = require('../object/pairs'); + +/** + * Gets the propery names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = pairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; +} + +module.exports = getMatchData; + +},{"../object/pairs":60,"./isStrictComparable":44}],37:[function(require,module,exports){ +var isNative = require('../lang/isNative'); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; +} + +module.exports = getNative; + +},{"../lang/isNative":52}],38:[function(require,module,exports){ +var getLength = require('./getLength'), + isLength = require('./isLength'); + +/** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ +function isArrayLike(value) { + return value != null && isLength(getLength(value)); +} + +module.exports = isArrayLike; + +},{"./getLength":35,"./isLength":42}],39:[function(require,module,exports){ +/** Used to detect unsigned integer values. */ +var reIsUint = /^\d+$/; + +/** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; +} + +module.exports = isIndex; + +},{}],40:[function(require,module,exports){ +var isArrayLike = require('./isArrayLike'), + isIndex = require('./isIndex'), + isObject = require('../lang/isObject'); + +/** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; +} + +module.exports = isIterateeCall; + +},{"../lang/isObject":53,"./isArrayLike":38,"./isIndex":39}],41:[function(require,module,exports){ +var isArray = require('../lang/isArray'), + toObject = require('./toObject'); + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + var type = typeof value; + if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { + return true; + } + if (isArray(value)) { + return false; + } + var result = !reIsDeepProp.test(value); + return result || (object != null && value in toObject(object)); +} + +module.exports = isKey; + +},{"../lang/isArray":49,"./toObject":46}],42:[function(require,module,exports){ +/** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +module.exports = isLength; + +},{}],43:[function(require,module,exports){ +/** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +module.exports = isObjectLike; + +},{}],44:[function(require,module,exports){ +var isObject = require('../lang/isObject'); + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !isObject(value); +} + +module.exports = isStrictComparable; + +},{"../lang/isObject":53}],45:[function(require,module,exports){ +var isArguments = require('../lang/isArguments'), + isArray = require('../lang/isArray'), + isIndex = require('./isIndex'), + isLength = require('./isLength'), + keysIn = require('../object/keysIn'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; + + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; +} + +module.exports = shimKeys; + +},{"../lang/isArguments":48,"../lang/isArray":49,"../object/keysIn":59,"./isIndex":39,"./isLength":42}],46:[function(require,module,exports){ +var isObject = require('../lang/isObject'); + +/** + * Converts `value` to an object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Object} Returns the object. + */ +function toObject(value) { + return isObject(value) ? value : Object(value); +} + +module.exports = toObject; + +},{"../lang/isObject":53}],47:[function(require,module,exports){ +var baseToString = require('./baseToString'), + isArray = require('../lang/isArray'); + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `value` to property path array if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array} Returns the property path array. + */ +function toPath(value) { + if (isArray(value)) { + return value; + } + var result = []; + baseToString(value).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +} + +module.exports = toPath; + +},{"../lang/isArray":49,"./baseToString":27}],48:[function(require,module,exports){ +var isArrayLike = require('../internal/isArrayLike'), + isObjectLike = require('../internal/isObjectLike'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Native method references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** + * Checks if `value` is classified as an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + return isObjectLike(value) && isArrayLike(value) && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); +} + +module.exports = isArguments; + +},{"../internal/isArrayLike":38,"../internal/isObjectLike":43}],49:[function(require,module,exports){ +var getNative = require('../internal/getNative'), + isLength = require('../internal/isLength'), + isObjectLike = require('../internal/isObjectLike'); + +/** `Object#toString` result references. */ +var arrayTag = '[object Array]'; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeIsArray = getNative(Array, 'isArray'); + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(function() { return arguments; }()); + * // => false + */ +var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; +}; + +module.exports = isArray; + +},{"../internal/getNative":37,"../internal/isLength":42,"../internal/isObjectLike":43}],50:[function(require,module,exports){ +var isArguments = require('./isArguments'), + isArray = require('./isArray'), + isArrayLike = require('../internal/isArrayLike'), + isFunction = require('./isFunction'), + isObjectLike = require('../internal/isObjectLike'), + isString = require('./isString'), + keys = require('../object/keys'); + +/** + * Checks if `value` is empty. A value is considered empty unless it's an + * `arguments` object, array, string, or jQuery-like collection with a length + * greater than `0` or an object with own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ +function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || + (isObjectLike(value) && isFunction(value.splice)))) { + return !value.length; + } + return !keys(value).length; +} + +module.exports = isEmpty; + +},{"../internal/isArrayLike":38,"../internal/isObjectLike":43,"../object/keys":58,"./isArguments":48,"./isArray":49,"./isFunction":51,"./isString":54}],51:[function(require,module,exports){ +var isObject = require('./isObject'); + +/** `Object#toString` result references. */ +var funcTag = '[object Function]'; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 which returns 'object' for typed array constructors. + return isObject(value) && objToString.call(value) == funcTag; +} + +module.exports = isFunction; + +},{"./isObject":53}],52:[function(require,module,exports){ +var isFunction = require('./isFunction'), + isObjectLike = require('../internal/isObjectLike'); + +/** Used to detect host constructors (Safari > 5). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var fnToString = Function.prototype.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ +function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); +} + +module.exports = isNative; + +},{"../internal/isObjectLike":43,"./isFunction":51}],53:[function(require,module,exports){ +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +module.exports = isObject; + +},{}],54:[function(require,module,exports){ +var isObjectLike = require('../internal/isObjectLike'); + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); +} + +module.exports = isString; + +},{"../internal/isObjectLike":43}],55:[function(require,module,exports){ +var isLength = require('../internal/isLength'), + isObjectLike = require('../internal/isObjectLike'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dateTag] = typedArrayTags[errorTag] = +typedArrayTags[funcTag] = typedArrayTags[mapTag] = +typedArrayTags[numberTag] = typedArrayTags[objectTag] = +typedArrayTags[regexpTag] = typedArrayTags[setTag] = +typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ +function isTypedArray(value) { + return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; +} + +module.exports = isTypedArray; + +},{"../internal/isLength":42,"../internal/isObjectLike":43}],56:[function(require,module,exports){ +var assignWith = require('../internal/assignWith'), + baseAssign = require('../internal/baseAssign'), + createAssigner = require('../internal/createAssigner'); + +/** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it's invoked to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments: + * (objectValue, sourceValue, key, object, source). + * + * **Note:** This method mutates `object` and is based on + * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } + * + * // using a customizer callback + * var defaults = _.partialRight(_.assign, function(value, other) { + * return _.isUndefined(value) ? other : value; + * }); + * + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ +var assign = createAssigner(function(object, source, customizer) { + return customizer + ? assignWith(object, source, customizer) + : baseAssign(object, source); +}); + +module.exports = assign; + +},{"../internal/assignWith":9,"../internal/baseAssign":10,"../internal/createAssigner":29}],57:[function(require,module,exports){ +var baseAssign = require('../internal/baseAssign'), + baseCreate = require('../internal/baseCreate'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ +function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = undefined; + } + return properties ? baseAssign(result, properties) : result; +} + +module.exports = create; + +},{"../internal/baseAssign":10,"../internal/baseCreate":13,"../internal/isIterateeCall":40}],58:[function(require,module,exports){ +var getNative = require('../internal/getNative'), + isArrayLike = require('../internal/isArrayLike'), + isObject = require('../lang/isObject'), + shimKeys = require('../internal/shimKeys'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeKeys = getNative(Object, 'keys'); + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object == null ? undefined : object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; +}; + +module.exports = keys; + +},{"../internal/getNative":37,"../internal/isArrayLike":38,"../internal/shimKeys":45,"../lang/isObject":53}],59:[function(require,module,exports){ +var isArguments = require('../lang/isArguments'), + isArray = require('../lang/isArray'), + isIndex = require('../internal/isIndex'), + isLength = require('../internal/isLength'), + isObject = require('../lang/isObject'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || isArguments(object)) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} + +module.exports = keysIn; + +},{"../internal/isIndex":39,"../internal/isLength":42,"../lang/isArguments":48,"../lang/isArray":49,"../lang/isObject":53}],60:[function(require,module,exports){ +var keys = require('./keys'), + toObject = require('../internal/toObject'); + +/** + * Creates a two dimensional array of the key-value pairs for `object`, + * e.g. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) + */ +function pairs(object) { + object = toObject(object); + + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; +} + +module.exports = pairs; + +},{"../internal/toObject":46,"./keys":58}],61:[function(require,module,exports){ +/** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utility + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'user': 'fred' }; + * + * _.identity(object) === object; + * // => true + */ +function identity(value) { + return value; +} + +module.exports = identity; + +},{}],62:[function(require,module,exports){ +var baseProperty = require('../internal/baseProperty'), + basePropertyDeep = require('../internal/basePropertyDeep'), + isKey = require('../internal/isKey'); + +/** + * Creates a function that returns the property value at `path` on a + * given object. + * + * @static + * @memberOf _ + * @category Utility + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + * @example + * + * var objects = [ + * { 'a': { 'b': { 'c': 2 } } }, + * { 'a': { 'b': { 'c': 1 } } } + * ]; + * + * _.map(objects, _.property('a.b.c')); + * // => [2, 1] + * + * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); + * // => [1, 2] + */ +function property(path) { + return isKey(path) ? baseProperty(path) : basePropertyDeep(path); +} + +module.exports = property; + +},{"../internal/baseProperty":24,"../internal/basePropertyDeep":25,"../internal/isKey":41}],63:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLAttribute, create; + + create = require('lodash/object/create'); + + module.exports = XMLAttribute = (function() { + function XMLAttribute(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing attribute name of element " + parent.name); + } + if (value == null) { + throw new Error("Missing attribute value for attribute " + name + " of element " + parent.name); + } + this.name = this.stringify.attName(name); + this.value = this.stringify.attValue(value); + } + + XMLAttribute.prototype.clone = function() { + return create(XMLAttribute.prototype, this); + }; + + XMLAttribute.prototype.toString = function(options, level) { + return ' ' + this.name + '="' + this.value + '"'; + }; + + return XMLAttribute; + + })(); + +}).call(this); + +},{"lodash/object/create":57}],64:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLBuilder, XMLDeclaration, XMLDocType, XMLElement, XMLStringifier; + + XMLStringifier = require('./XMLStringifier'); + + XMLDeclaration = require('./XMLDeclaration'); + + XMLDocType = require('./XMLDocType'); + + XMLElement = require('./XMLElement'); + + module.exports = XMLBuilder = (function() { + function XMLBuilder(name, options) { + var root, temp; + if (name == null) { + throw new Error("Root element needs a name"); + } + if (options == null) { + options = {}; + } + this.options = options; + this.stringify = new XMLStringifier(options); + temp = new XMLElement(this, 'doc'); + root = temp.element(name); + root.isRoot = true; + root.documentObject = this; + this.rootObject = root; + if (!options.headless) { + root.declaration(options); + if ((options.pubID != null) || (options.sysID != null)) { + root.doctype(options); + } + } + } + + XMLBuilder.prototype.root = function() { + return this.rootObject; + }; + + XMLBuilder.prototype.end = function(options) { + return this.toString(options); + }; + + XMLBuilder.prototype.toString = function(options) { + var indent, newline, offset, pretty, r, ref, ref1, ref2; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + r = ''; + if (this.xmldec != null) { + r += this.xmldec.toString(options); + } + if (this.doctype != null) { + r += this.doctype.toString(options); + } + r += this.rootObject.toString(options); + if (pretty && r.slice(-newline.length) === newline) { + r = r.slice(0, -newline.length); + } + return r; + }; + + return XMLBuilder; + + })(); + +}).call(this); + +},{"./XMLDeclaration":71,"./XMLDocType":72,"./XMLElement":73,"./XMLStringifier":77}],65:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLNode, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLCData = (function(superClass) { + extend(XMLCData, superClass); + + function XMLCData(parent, text) { + XMLCData.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing CDATA text"); + } + this.text = this.stringify.cdata(text); + } + + XMLCData.prototype.clone = function() { + return create(XMLCData.prototype, this); + }; + + XMLCData.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLCData; + + })(XMLNode); + +}).call(this); + +},{"./XMLNode":74,"lodash/object/create":57}],66:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLComment, XMLNode, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLComment = (function(superClass) { + extend(XMLComment, superClass); + + function XMLComment(parent, text) { + XMLComment.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing comment text"); + } + this.text = this.stringify.comment(text); + } + + XMLComment.prototype.clone = function() { + return create(XMLComment.prototype, this); + }; + + XMLComment.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLComment; + + })(XMLNode); + +}).call(this); + +},{"./XMLNode":74,"lodash/object/create":57}],67:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDAttList, create; + + create = require('lodash/object/create'); + + module.exports = XMLDTDAttList = (function() { + function XMLDTDAttList(parent, elementName, attributeName, attributeType, defaultValueType, defaultValue) { + this.stringify = parent.stringify; + if (elementName == null) { + throw new Error("Missing DTD element name"); + } + if (attributeName == null) { + throw new Error("Missing DTD attribute name"); + } + if (!attributeType) { + throw new Error("Missing DTD attribute type"); + } + if (!defaultValueType) { + throw new Error("Missing DTD attribute default"); + } + if (defaultValueType.indexOf('#') !== 0) { + defaultValueType = '#' + defaultValueType; + } + if (!defaultValueType.match(/^(#REQUIRED|#IMPLIED|#FIXED|#DEFAULT)$/)) { + throw new Error("Invalid default value type; expected: #REQUIRED, #IMPLIED, #FIXED or #DEFAULT"); + } + if (defaultValue && !defaultValueType.match(/^(#FIXED|#DEFAULT)$/)) { + throw new Error("Default value only applies to #FIXED or #DEFAULT"); + } + this.elementName = this.stringify.eleName(elementName); + this.attributeName = this.stringify.attName(attributeName); + this.attributeType = this.stringify.dtdAttType(attributeType); + this.defaultValue = this.stringify.dtdAttDefault(defaultValue); + this.defaultValueType = defaultValueType; + } + + XMLDTDAttList.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDAttList; + + })(); + +}).call(this); + +},{"lodash/object/create":57}],68:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDElement, create; + + create = require('lodash/object/create'); + + module.exports = XMLDTDElement = (function() { + function XMLDTDElement(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing DTD element name"); + } + if (!value) { + value = '(#PCDATA)'; + } + if (Array.isArray(value)) { + value = '(' + value.join(',') + ')'; + } + this.name = this.stringify.eleName(name); + this.value = this.stringify.dtdElementValue(value); + } + + XMLDTDElement.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDElement; + + })(); + +}).call(this); + +},{"lodash/object/create":57}],69:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDEntity, create, isObject; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + module.exports = XMLDTDEntity = (function() { + function XMLDTDEntity(parent, pe, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing entity name"); + } + if (value == null) { + throw new Error("Missing entity value"); + } + this.pe = !!pe; + this.name = this.stringify.eleName(name); + if (!isObject(value)) { + this.value = this.stringify.dtdEntityValue(value); + } else { + if (!value.pubID && !value.sysID) { + throw new Error("Public and/or system identifiers are required for an external entity"); + } + if (value.pubID && !value.sysID) { + throw new Error("System identifier is required for a public external entity"); + } + if (value.pubID != null) { + this.pubID = this.stringify.dtdPubID(value.pubID); + } + if (value.sysID != null) { + this.sysID = this.stringify.dtdSysID(value.sysID); + } + if (value.nData != null) { + this.nData = this.stringify.dtdNData(value.nData); + } + if (this.pe && this.nData) { + throw new Error("Notation declaration is not allowed in a parameter entity"); + } + } + } + + XMLDTDEntity.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDEntity; + + })(); + +}).call(this); + +},{"lodash/lang/isObject":53,"lodash/object/create":57}],70:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDNotation, create; + + create = require('lodash/object/create'); + + module.exports = XMLDTDNotation = (function() { + function XMLDTDNotation(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing notation name"); + } + if (!value.pubID && !value.sysID) { + throw new Error("Public or system identifiers are required for an external entity"); + } + this.name = this.stringify.eleName(name); + if (value.pubID != null) { + this.pubID = this.stringify.dtdPubID(value.pubID); + } + if (value.sysID != null) { + this.sysID = this.stringify.dtdSysID(value.sysID); + } + } + + XMLDTDNotation.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDNotation; + + })(); + +}).call(this); + +},{"lodash/object/create":57}],71:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDeclaration, XMLNode, create, isObject, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLDeclaration = (function(superClass) { + extend(XMLDeclaration, superClass); + + function XMLDeclaration(parent, version, encoding, standalone) { + var ref; + XMLDeclaration.__super__.constructor.call(this, parent); + if (isObject(version)) { + ref = version, version = ref.version, encoding = ref.encoding, standalone = ref.standalone; + } + if (!version) { + version = '1.0'; + } + this.version = this.stringify.xmlVersion(version); + if (encoding != null) { + this.encoding = this.stringify.xmlEncoding(encoding); + } + if (standalone != null) { + this.standalone = this.stringify.xmlStandalone(standalone); + } + } + + XMLDeclaration.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDeclaration; + + })(XMLNode); + +}).call(this); + +},{"./XMLNode":74,"lodash/lang/isObject":53,"lodash/object/create":57}],72:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLComment, XMLDTDAttList, XMLDTDElement, XMLDTDEntity, XMLDTDNotation, XMLDocType, XMLProcessingInstruction, create, isObject; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + XMLCData = require('./XMLCData'); + + XMLComment = require('./XMLComment'); + + XMLDTDAttList = require('./XMLDTDAttList'); + + XMLDTDEntity = require('./XMLDTDEntity'); + + XMLDTDElement = require('./XMLDTDElement'); + + XMLDTDNotation = require('./XMLDTDNotation'); + + XMLProcessingInstruction = require('./XMLProcessingInstruction'); + + module.exports = XMLDocType = (function() { + function XMLDocType(parent, pubID, sysID) { + var ref, ref1; + this.documentObject = parent; + this.stringify = this.documentObject.stringify; + this.children = []; + if (isObject(pubID)) { + ref = pubID, pubID = ref.pubID, sysID = ref.sysID; + } + if (sysID == null) { + ref1 = [pubID, sysID], sysID = ref1[0], pubID = ref1[1]; + } + if (pubID != null) { + this.pubID = this.stringify.dtdPubID(pubID); + } + if (sysID != null) { + this.sysID = this.stringify.dtdSysID(sysID); + } + } + + XMLDocType.prototype.element = function(name, value) { + var child; + child = new XMLDTDElement(this, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.attList = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) { + var child; + child = new XMLDTDAttList(this, elementName, attributeName, attributeType, defaultValueType, defaultValue); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.entity = function(name, value) { + var child; + child = new XMLDTDEntity(this, false, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.pEntity = function(name, value) { + var child; + child = new XMLDTDEntity(this, true, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.notation = function(name, value) { + var child; + child = new XMLDTDNotation(this, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.cdata = function(value) { + var child; + child = new XMLCData(this, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.comment = function(value) { + var child; + child = new XMLComment(this, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.instruction = function(target, value) { + var child; + child = new XMLProcessingInstruction(this, target, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.root = function() { + return this.documentObject.root(); + }; + + XMLDocType.prototype.document = function() { + return this.documentObject; + }; + + XMLDocType.prototype.toString = function(options, level) { + var child, i, indent, len, newline, offset, pretty, r, ref, ref1, ref2, ref3, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ' 0) { + r += ' ['; + if (pretty) { + r += newline; + } + ref3 = this.children; + for (i = 0, len = ref3.length; i < len; i++) { + child = ref3[i]; + r += child.toString(options, level + 1); + } + r += ']'; + } + r += '>'; + if (pretty) { + r += newline; + } + return r; + }; + + XMLDocType.prototype.ele = function(name, value) { + return this.element(name, value); + }; + + XMLDocType.prototype.att = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) { + return this.attList(elementName, attributeName, attributeType, defaultValueType, defaultValue); + }; + + XMLDocType.prototype.ent = function(name, value) { + return this.entity(name, value); + }; + + XMLDocType.prototype.pent = function(name, value) { + return this.pEntity(name, value); + }; + + XMLDocType.prototype.not = function(name, value) { + return this.notation(name, value); + }; + + XMLDocType.prototype.dat = function(value) { + return this.cdata(value); + }; + + XMLDocType.prototype.com = function(value) { + return this.comment(value); + }; + + XMLDocType.prototype.ins = function(target, value) { + return this.instruction(target, value); + }; + + XMLDocType.prototype.up = function() { + return this.root(); + }; + + XMLDocType.prototype.doc = function() { + return this.document(); + }; + + return XMLDocType; + + })(); + +}).call(this); + +},{"./XMLCData":65,"./XMLComment":66,"./XMLDTDAttList":67,"./XMLDTDElement":68,"./XMLDTDEntity":69,"./XMLDTDNotation":70,"./XMLProcessingInstruction":75,"lodash/lang/isObject":53,"lodash/object/create":57}],73:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLAttribute, XMLElement, XMLNode, XMLProcessingInstruction, create, every, isFunction, isObject, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + isFunction = require('lodash/lang/isFunction'); + + every = require('lodash/collection/every'); + + XMLNode = require('./XMLNode'); + + XMLAttribute = require('./XMLAttribute'); + + XMLProcessingInstruction = require('./XMLProcessingInstruction'); + + module.exports = XMLElement = (function(superClass) { + extend(XMLElement, superClass); + + function XMLElement(parent, name, attributes) { + XMLElement.__super__.constructor.call(this, parent); + if (name == null) { + throw new Error("Missing element name"); + } + this.name = this.stringify.eleName(name); + this.children = []; + this.instructions = []; + this.attributes = {}; + if (attributes != null) { + this.attribute(attributes); + } + } + + XMLElement.prototype.clone = function() { + var att, attName, clonedSelf, i, len, pi, ref, ref1; + clonedSelf = create(XMLElement.prototype, this); + if (clonedSelf.isRoot) { + clonedSelf.documentObject = null; + } + clonedSelf.attributes = {}; + ref = this.attributes; + for (attName in ref) { + if (!hasProp.call(ref, attName)) continue; + att = ref[attName]; + clonedSelf.attributes[attName] = att.clone(); + } + clonedSelf.instructions = []; + ref1 = this.instructions; + for (i = 0, len = ref1.length; i < len; i++) { + pi = ref1[i]; + clonedSelf.instructions.push(pi.clone()); + } + clonedSelf.children = []; + this.children.forEach(function(child) { + var clonedChild; + clonedChild = child.clone(); + clonedChild.parent = clonedSelf; + return clonedSelf.children.push(clonedChild); + }); + return clonedSelf; + }; + + XMLElement.prototype.attribute = function(name, value) { + var attName, attValue; + if (name != null) { + name = name.valueOf(); + } + if (isObject(name)) { + for (attName in name) { + if (!hasProp.call(name, attName)) continue; + attValue = name[attName]; + this.attribute(attName, attValue); + } + } else { + if (isFunction(value)) { + value = value.apply(); + } + if (!this.options.skipNullAttributes || (value != null)) { + this.attributes[name] = new XMLAttribute(this, name, value); + } + } + return this; + }; + + XMLElement.prototype.removeAttribute = function(name) { + var attName, i, len; + if (name == null) { + throw new Error("Missing attribute name"); + } + name = name.valueOf(); + if (Array.isArray(name)) { + for (i = 0, len = name.length; i < len; i++) { + attName = name[i]; + delete this.attributes[attName]; + } + } else { + delete this.attributes[name]; + } + return this; + }; + + XMLElement.prototype.instruction = function(target, value) { + var i, insTarget, insValue, instruction, len; + if (target != null) { + target = target.valueOf(); + } + if (value != null) { + value = value.valueOf(); + } + if (Array.isArray(target)) { + for (i = 0, len = target.length; i < len; i++) { + insTarget = target[i]; + this.instruction(insTarget); + } + } else if (isObject(target)) { + for (insTarget in target) { + if (!hasProp.call(target, insTarget)) continue; + insValue = target[insTarget]; + this.instruction(insTarget, insValue); + } + } else { + if (isFunction(value)) { + value = value.apply(); + } + instruction = new XMLProcessingInstruction(this, target, value); + this.instructions.push(instruction); + } + return this; + }; + + XMLElement.prototype.toString = function(options, level) { + var att, child, i, indent, instruction, j, len, len1, name, newline, offset, pretty, r, ref, ref1, ref2, ref3, ref4, ref5, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + ref3 = this.instructions; + for (i = 0, len = ref3.length; i < len; i++) { + instruction = ref3[i]; + r += instruction.toString(options, level); + } + if (pretty) { + r += space; + } + r += '<' + this.name; + ref4 = this.attributes; + for (name in ref4) { + if (!hasProp.call(ref4, name)) continue; + att = ref4[name]; + r += att.toString(options); + } + if (this.children.length === 0 || every(this.children, function(e) { + return e.value === ''; + })) { + r += '/>'; + if (pretty) { + r += newline; + } + } else if (pretty && this.children.length === 1 && (this.children[0].value != null)) { + r += '>'; + r += this.children[0].value; + r += ''; + r += newline; + } else { + r += '>'; + if (pretty) { + r += newline; + } + ref5 = this.children; + for (j = 0, len1 = ref5.length; j < len1; j++) { + child = ref5[j]; + r += child.toString(options, level + 1); + } + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + } + return r; + }; + + XMLElement.prototype.att = function(name, value) { + return this.attribute(name, value); + }; + + XMLElement.prototype.ins = function(target, value) { + return this.instruction(target, value); + }; + + XMLElement.prototype.a = function(name, value) { + return this.attribute(name, value); + }; + + XMLElement.prototype.i = function(target, value) { + return this.instruction(target, value); + }; + + return XMLElement; + + })(XMLNode); + +}).call(this); + +},{"./XMLAttribute":63,"./XMLNode":74,"./XMLProcessingInstruction":75,"lodash/collection/every":5,"lodash/lang/isFunction":51,"lodash/lang/isObject":53,"lodash/object/create":57}],74:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLComment, XMLDeclaration, XMLDocType, XMLElement, XMLNode, XMLRaw, XMLText, isEmpty, isFunction, isObject, + hasProp = {}.hasOwnProperty; + + isObject = require('lodash/lang/isObject'); + + isFunction = require('lodash/lang/isFunction'); + + isEmpty = require('lodash/lang/isEmpty'); + + XMLElement = null; + + XMLCData = null; + + XMLComment = null; + + XMLDeclaration = null; + + XMLDocType = null; + + XMLRaw = null; + + XMLText = null; + + module.exports = XMLNode = (function() { + function XMLNode(parent) { + this.parent = parent; + this.options = this.parent.options; + this.stringify = this.parent.stringify; + if (XMLElement === null) { + XMLElement = require('./XMLElement'); + XMLCData = require('./XMLCData'); + XMLComment = require('./XMLComment'); + XMLDeclaration = require('./XMLDeclaration'); + XMLDocType = require('./XMLDocType'); + XMLRaw = require('./XMLRaw'); + XMLText = require('./XMLText'); + } + } + + XMLNode.prototype.element = function(name, attributes, text) { + var childNode, item, j, k, key, lastChild, len, len1, ref, val; + lastChild = null; + if (attributes == null) { + attributes = {}; + } + attributes = attributes.valueOf(); + if (!isObject(attributes)) { + ref = [attributes, text], text = ref[0], attributes = ref[1]; + } + if (name != null) { + name = name.valueOf(); + } + if (Array.isArray(name)) { + for (j = 0, len = name.length; j < len; j++) { + item = name[j]; + lastChild = this.element(item); + } + } else if (isFunction(name)) { + lastChild = this.element(name.apply()); + } else if (isObject(name)) { + for (key in name) { + if (!hasProp.call(name, key)) continue; + val = name[key]; + if (isFunction(val)) { + val = val.apply(); + } + if ((isObject(val)) && (isEmpty(val))) { + val = null; + } + if (!this.options.ignoreDecorators && this.stringify.convertAttKey && key.indexOf(this.stringify.convertAttKey) === 0) { + lastChild = this.attribute(key.substr(this.stringify.convertAttKey.length), val); + } else if (!this.options.ignoreDecorators && this.stringify.convertPIKey && key.indexOf(this.stringify.convertPIKey) === 0) { + lastChild = this.instruction(key.substr(this.stringify.convertPIKey.length), val); + } else if (Array.isArray(val)) { + for (k = 0, len1 = val.length; k < len1; k++) { + item = val[k]; + childNode = {}; + childNode[key] = item; + lastChild = this.element(childNode); + } + } else if (isObject(val)) { + lastChild = this.element(key); + lastChild.element(val); + } else { + lastChild = this.element(key, val); + } + } + } else { + if (!this.options.ignoreDecorators && this.stringify.convertTextKey && name.indexOf(this.stringify.convertTextKey) === 0) { + lastChild = this.text(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertCDataKey && name.indexOf(this.stringify.convertCDataKey) === 0) { + lastChild = this.cdata(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertCommentKey && name.indexOf(this.stringify.convertCommentKey) === 0) { + lastChild = this.comment(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertRawKey && name.indexOf(this.stringify.convertRawKey) === 0) { + lastChild = this.raw(text); + } else { + lastChild = this.node(name, attributes, text); + } + } + if (lastChild == null) { + throw new Error("Could not create any elements with: " + name); + } + return lastChild; + }; + + XMLNode.prototype.insertBefore = function(name, attributes, text) { + var child, i, removed; + if (this.isRoot) { + throw new Error("Cannot insert elements at root level"); + } + i = this.parent.children.indexOf(this); + removed = this.parent.children.splice(i); + child = this.parent.element(name, attributes, text); + Array.prototype.push.apply(this.parent.children, removed); + return child; + }; + + XMLNode.prototype.insertAfter = function(name, attributes, text) { + var child, i, removed; + if (this.isRoot) { + throw new Error("Cannot insert elements at root level"); + } + i = this.parent.children.indexOf(this); + removed = this.parent.children.splice(i + 1); + child = this.parent.element(name, attributes, text); + Array.prototype.push.apply(this.parent.children, removed); + return child; + }; + + XMLNode.prototype.remove = function() { + var i, ref; + if (this.isRoot) { + throw new Error("Cannot remove the root element"); + } + i = this.parent.children.indexOf(this); + [].splice.apply(this.parent.children, [i, i - i + 1].concat(ref = [])), ref; + return this.parent; + }; + + XMLNode.prototype.node = function(name, attributes, text) { + var child, ref; + if (name != null) { + name = name.valueOf(); + } + if (attributes == null) { + attributes = {}; + } + attributes = attributes.valueOf(); + if (!isObject(attributes)) { + ref = [attributes, text], text = ref[0], attributes = ref[1]; + } + child = new XMLElement(this, name, attributes); + if (text != null) { + child.text(text); + } + this.children.push(child); + return child; + }; + + XMLNode.prototype.text = function(value) { + var child; + child = new XMLText(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.cdata = function(value) { + var child; + child = new XMLCData(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.comment = function(value) { + var child; + child = new XMLComment(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.raw = function(value) { + var child; + child = new XMLRaw(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.declaration = function(version, encoding, standalone) { + var doc, xmldec; + doc = this.document(); + xmldec = new XMLDeclaration(doc, version, encoding, standalone); + doc.xmldec = xmldec; + return doc.root(); + }; + + XMLNode.prototype.doctype = function(pubID, sysID) { + var doc, doctype; + doc = this.document(); + doctype = new XMLDocType(doc, pubID, sysID); + doc.doctype = doctype; + return doctype; + }; + + XMLNode.prototype.up = function() { + if (this.isRoot) { + throw new Error("The root node has no parent. Use doc() if you need to get the document object."); + } + return this.parent; + }; + + XMLNode.prototype.root = function() { + var child; + if (this.isRoot) { + return this; + } + child = this.parent; + while (!child.isRoot) { + child = child.parent; + } + return child; + }; + + XMLNode.prototype.document = function() { + return this.root().documentObject; + }; + + XMLNode.prototype.end = function(options) { + return this.document().toString(options); + }; + + XMLNode.prototype.prev = function() { + var i; + if (this.isRoot) { + throw new Error("Root node has no siblings"); + } + i = this.parent.children.indexOf(this); + if (i < 1) { + throw new Error("Already at the first node"); + } + return this.parent.children[i - 1]; + }; + + XMLNode.prototype.next = function() { + var i; + if (this.isRoot) { + throw new Error("Root node has no siblings"); + } + i = this.parent.children.indexOf(this); + if (i === -1 || i === this.parent.children.length - 1) { + throw new Error("Already at the last node"); + } + return this.parent.children[i + 1]; + }; + + XMLNode.prototype.importXMLBuilder = function(xmlbuilder) { + var clonedRoot; + clonedRoot = xmlbuilder.root().clone(); + clonedRoot.parent = this; + clonedRoot.isRoot = false; + this.children.push(clonedRoot); + return this; + }; + + XMLNode.prototype.ele = function(name, attributes, text) { + return this.element(name, attributes, text); + }; + + XMLNode.prototype.nod = function(name, attributes, text) { + return this.node(name, attributes, text); + }; + + XMLNode.prototype.txt = function(value) { + return this.text(value); + }; + + XMLNode.prototype.dat = function(value) { + return this.cdata(value); + }; + + XMLNode.prototype.com = function(value) { + return this.comment(value); + }; + + XMLNode.prototype.doc = function() { + return this.document(); + }; + + XMLNode.prototype.dec = function(version, encoding, standalone) { + return this.declaration(version, encoding, standalone); + }; + + XMLNode.prototype.dtd = function(pubID, sysID) { + return this.doctype(pubID, sysID); + }; + + XMLNode.prototype.e = function(name, attributes, text) { + return this.element(name, attributes, text); + }; + + XMLNode.prototype.n = function(name, attributes, text) { + return this.node(name, attributes, text); + }; + + XMLNode.prototype.t = function(value) { + return this.text(value); + }; + + XMLNode.prototype.d = function(value) { + return this.cdata(value); + }; + + XMLNode.prototype.c = function(value) { + return this.comment(value); + }; + + XMLNode.prototype.r = function(value) { + return this.raw(value); + }; + + XMLNode.prototype.u = function() { + return this.up(); + }; + + return XMLNode; + + })(); + +}).call(this); + +},{"./XMLCData":65,"./XMLComment":66,"./XMLDeclaration":71,"./XMLDocType":72,"./XMLElement":73,"./XMLRaw":76,"./XMLText":78,"lodash/lang/isEmpty":50,"lodash/lang/isFunction":51,"lodash/lang/isObject":53}],75:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLProcessingInstruction, create; + + create = require('lodash/object/create'); + + module.exports = XMLProcessingInstruction = (function() { + function XMLProcessingInstruction(parent, target, value) { + this.stringify = parent.stringify; + if (target == null) { + throw new Error("Missing instruction target"); + } + this.target = this.stringify.insTarget(target); + if (value) { + this.value = this.stringify.insValue(value); + } + } + + XMLProcessingInstruction.prototype.clone = function() { + return create(XMLProcessingInstruction.prototype, this); + }; + + XMLProcessingInstruction.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLProcessingInstruction; + + })(); + +}).call(this); + +},{"lodash/object/create":57}],76:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLNode, XMLRaw, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLRaw = (function(superClass) { + extend(XMLRaw, superClass); + + function XMLRaw(parent, text) { + XMLRaw.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing raw text"); + } + this.value = this.stringify.raw(text); + } + + XMLRaw.prototype.clone = function() { + return create(XMLRaw.prototype, this); + }; + + XMLRaw.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += this.value; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLRaw; + + })(XMLNode); + +}).call(this); + +},{"./XMLNode":74,"lodash/object/create":57}],77:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLStringifier, + bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + hasProp = {}.hasOwnProperty; + + module.exports = XMLStringifier = (function() { + function XMLStringifier(options) { + this.assertLegalChar = bind(this.assertLegalChar, this); + var key, ref, value; + this.allowSurrogateChars = options != null ? options.allowSurrogateChars : void 0; + ref = (options != null ? options.stringify : void 0) || {}; + for (key in ref) { + if (!hasProp.call(ref, key)) continue; + value = ref[key]; + this[key] = value; + } + } + + XMLStringifier.prototype.eleName = function(val) { + val = '' + val || ''; + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.eleText = function(val) { + val = '' + val || ''; + return this.assertLegalChar(this.elEscape(val)); + }; + + XMLStringifier.prototype.cdata = function(val) { + val = '' + val || ''; + if (val.match(/]]>/)) { + throw new Error("Invalid CDATA text: " + val); + } + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.comment = function(val) { + val = '' + val || ''; + if (val.match(/--/)) { + throw new Error("Comment text cannot contain double-hypen: " + val); + } + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.raw = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.attName = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.attValue = function(val) { + val = '' + val || ''; + return this.attEscape(val); + }; + + XMLStringifier.prototype.insTarget = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.insValue = function(val) { + val = '' + val || ''; + if (val.match(/\?>/)) { + throw new Error("Invalid processing instruction value: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlVersion = function(val) { + val = '' + val || ''; + if (!val.match(/1\.[0-9]+/)) { + throw new Error("Invalid version number: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlEncoding = function(val) { + val = '' + val || ''; + if (!val.match(/^[A-Za-z](?:[A-Za-z0-9._-]|-)*$/)) { + throw new Error("Invalid encoding: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlStandalone = function(val) { + if (val) { + return "yes"; + } else { + return "no"; + } + }; + + XMLStringifier.prototype.dtdPubID = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdSysID = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdElementValue = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdAttType = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdAttDefault = function(val) { + if (val != null) { + return '' + val || ''; + } else { + return val; + } + }; + + XMLStringifier.prototype.dtdEntityValue = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdNData = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.convertAttKey = '@'; + + XMLStringifier.prototype.convertPIKey = '?'; + + XMLStringifier.prototype.convertTextKey = '#text'; + + XMLStringifier.prototype.convertCDataKey = '#cdata'; + + XMLStringifier.prototype.convertCommentKey = '#comment'; + + XMLStringifier.prototype.convertRawKey = '#raw'; + + XMLStringifier.prototype.assertLegalChar = function(str) { + var chars, chr; + if (this.allowSurrogateChars) { + chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uFFFE-\uFFFF]/; + } else { + chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]/; + } + chr = str.match(chars); + if (chr) { + throw new Error("Invalid character (" + chr + ") in string: " + str + " at index " + chr.index); + } + return str; + }; + + XMLStringifier.prototype.elEscape = function(str) { + return str.replace(/&/g, '&').replace(//g, '>').replace(/\r/g, ' '); + }; + + XMLStringifier.prototype.attEscape = function(str) { + return str.replace(/&/g, '&').replace(/, + * and raw CDATA nodes. + * + * @param {Element} node + * @returns {Boolean} + * @api private + */ + +function shouldIgnoreNode (node) { + return node.nodeType === 3 // text + || node.nodeType === 8 // comment + || node.nodeType === 4; // cdata +} + + +/** + * Parses a Plist XML string. Returns an Object. + * + * @param {String} xml - the XML String to decode + * @returns {Mixed} the decoded value from the Plist XML + * @api public + */ + +function parse (xml) { + var doc = new DOMParser().parseFromString(xml); + if (doc.documentElement.nodeName !== 'plist') { + throw new Error('malformed document. First element should be '); + } + var plist = parsePlistXML(doc.documentElement); + + // the root node gets interpreted as an Array, + // so pull out the inner data first + if (plist.length == 1) plist = plist[0]; + + return plist; +} + +/** + * Parses a Plist XML string. Returns an Object. Takes a `callback` function. + * + * @param {String} xml - the XML String to decode + * @param {Function} callback - callback function + * @returns {Mixed} the decoded value from the Plist XML + * @api public + * @deprecated not actually async. use parse() instead + */ + +function parseString (xml, callback) { + var doc, error, plist; + try { + doc = new DOMParser().parseFromString(xml); + plist = parsePlistXML(doc.documentElement); + } catch(e) { + error = e; + } + callback(error, plist); +} + +/** + * Parses a Plist XML string. Returns an Object. + * + * @param {String} xml - the XML String to decode + * @param {Function} callback - callback function + * @returns {Mixed} the decoded value from the Plist XML + * @api public + * @deprecated use parse() instead + */ + +function parseStringSync (xml) { + var doc = new DOMParser().parseFromString(xml); + var plist; + if (doc.documentElement.nodeName !== 'plist') { + throw new Error('malformed document. First element should be '); + } + plist = parsePlistXML(doc.documentElement); + + // if the plist is an array with 1 element, pull it out of the array + if (plist.length == 1) { + plist = plist[0]; + } + return plist; +} + +/** + * Convert an XML based plist document into a JSON representation. + * + * @param {Object} xml_node - current XML node in the plist + * @returns {Mixed} built up JSON object + * @api private + */ + +function parsePlistXML (node) { + var i, new_obj, key, val, new_arr, res, d; + + if (!node) + return null; + + if (node.nodeName === 'plist') { + new_arr = []; + for (i=0; i < node.childNodes.length; i++) { + // ignore comment nodes (text) + if (!shouldIgnoreNode(node.childNodes[i])) { + new_arr.push( parsePlistXML(node.childNodes[i])); + } + } + return new_arr; + + } else if (node.nodeName === 'dict') { + new_obj = {}; + key = null; + for (i=0; i < node.childNodes.length; i++) { + // ignore comment nodes (text) + if (!shouldIgnoreNode(node.childNodes[i])) { + if (key === null) { + key = parsePlistXML(node.childNodes[i]); + } else { + new_obj[key] = parsePlistXML(node.childNodes[i]); + key = null; + } + } + } + return new_obj; + + } else if (node.nodeName === 'array') { + new_arr = []; + for (i=0; i < node.childNodes.length; i++) { + // ignore comment nodes (text) + if (!shouldIgnoreNode(node.childNodes[i])) { + res = parsePlistXML(node.childNodes[i]); + if (null != res) new_arr.push(res); + } + } + return new_arr; + + } else if (node.nodeName === '#text') { + // TODO: what should we do with text types? (CDATA sections) + + } else if (node.nodeName === 'key') { + return node.childNodes[0].nodeValue; + + } else if (node.nodeName === 'string') { + res = ''; + for (d=0; d < node.childNodes.length; d++) { + res += node.childNodes[d].nodeValue; + } + return res; + + } else if (node.nodeName === 'integer') { + // parse as base 10 integer + return parseInt(node.childNodes[0].nodeValue, 10); + + } else if (node.nodeName === 'real') { + res = ''; + for (d=0; d < node.childNodes.length; d++) { + if (node.childNodes[d].nodeType === 3) { + res += node.childNodes[d].nodeValue; + } + } + return parseFloat(res); + + } else if (node.nodeName === 'data') { + res = ''; + for (d=0; d < node.childNodes.length; d++) { + if (node.childNodes[d].nodeType === 3) { + res += node.childNodes[d].nodeValue.replace(/\s+/g, ''); + } + } + + // decode base64 data to a Buffer instance + return new Buffer(res, 'base64'); + + } else if (node.nodeName === 'date') { + return new Date(node.childNodes[0].nodeValue); + + } else if (node.nodeName === 'true') { + return true; + + } else if (node.nodeName === 'false') { + return false; + } +} + +}).call(this,require("buffer").Buffer) +},{"buffer":3,"util-deprecate":6,"xmldom":7}],2:[function(require,module,exports){ +var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +;(function (exports) { + 'use strict'; + + var Arr = (typeof Uint8Array !== 'undefined') + ? Uint8Array + : Array + + var PLUS = '+'.charCodeAt(0) + var SLASH = '/'.charCodeAt(0) + var NUMBER = '0'.charCodeAt(0) + var LOWER = 'a'.charCodeAt(0) + var UPPER = 'A'.charCodeAt(0) + var PLUS_URL_SAFE = '-'.charCodeAt(0) + var SLASH_URL_SAFE = '_'.charCodeAt(0) + + function decode (elt) { + var code = elt.charCodeAt(0) + if (code === PLUS || + code === PLUS_URL_SAFE) + return 62 // '+' + if (code === SLASH || + code === SLASH_URL_SAFE) + return 63 // '/' + if (code < NUMBER) + return -1 //no match + if (code < NUMBER + 10) + return code - NUMBER + 26 + 26 + if (code < UPPER + 26) + return code - UPPER + if (code < LOWER + 26) + return code - LOWER + 26 + } + + function b64ToByteArray (b64) { + var i, j, l, tmp, placeHolders, arr + + if (b64.length % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + var len = b64.length + placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(b64.length * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length + + var L = 0 + + function push (v) { + arr[L++] = v + } + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) + push((tmp & 0xFF0000) >> 16) + push((tmp & 0xFF00) >> 8) + push(tmp & 0xFF) + } + + if (placeHolders === 2) { + tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) + push(tmp & 0xFF) + } else if (placeHolders === 1) { + tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) + push((tmp >> 8) & 0xFF) + push(tmp & 0xFF) + } + + return arr + } + + function uint8ToBase64 (uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length + + function encode (num) { + return lookup.charAt(num) + } + + function tripletToBase64 (num) { + return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) + } + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output += tripletToBase64(temp) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1] + output += encode(temp >> 2) + output += encode((temp << 4) & 0x3F) + output += '==' + break + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) + output += encode(temp >> 10) + output += encode((temp >> 4) & 0x3F) + output += encode((temp << 2) & 0x3F) + output += '=' + break + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) + +},{}],3:[function(require,module,exports){ +(function (global){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +/* eslint-disable no-proto */ + +var base64 = require('base64-js') +var ieee754 = require('ieee754') +var isArray = require('is-array') + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 +Buffer.poolSize = 8192 // not used by this implementation + +var rootParent = {} + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property + * on objects. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined + ? global.TYPED_ARRAY_SUPPORT + : typedArraySupport() + +function typedArraySupport () { + function Bar () {} + try { + var arr = new Uint8Array(1) + arr.foo = function () { return 42 } + arr.constructor = Bar + return arr.foo() === 42 && // typed array instances can be augmented + arr.constructor === Bar && // constructor can be set + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false + } +} + +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} + +/** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ +function Buffer (arg) { + if (!(this instanceof Buffer)) { + // Avoid going through an ArgumentsAdaptorTrampoline in the common case. + if (arguments.length > 1) return new Buffer(arg, arguments[1]) + return new Buffer(arg) + } + + this.length = 0 + this.parent = undefined + + // Common case. + if (typeof arg === 'number') { + return fromNumber(this, arg) + } + + // Slightly less common case. + if (typeof arg === 'string') { + return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') + } + + // Unusual. + return fromObject(this, arg) +} + +function fromNumber (that, length) { + that = allocate(that, length < 0 ? 0 : checked(length) | 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < length; i++) { + that[i] = 0 + } + } + return that +} + +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' + + // Assumption: byteLength() return value is always < kMaxLength. + var length = byteLength(string, encoding) | 0 + that = allocate(that, length) + + that.write(string, encoding) + return that +} + +function fromObject (that, object) { + if (Buffer.isBuffer(object)) return fromBuffer(that, object) + + if (isArray(object)) return fromArray(that, object) + + if (object == null) { + throw new TypeError('must start with number, buffer, array or string') + } + + if (typeof ArrayBuffer !== 'undefined') { + if (object.buffer instanceof ArrayBuffer) { + return fromTypedArray(that, object) + } + if (object instanceof ArrayBuffer) { + return fromArrayBuffer(that, object) + } + } + + if (object.length) return fromArrayLike(that, object) + + return fromJsonObject(that, object) +} + +function fromBuffer (that, buffer) { + var length = checked(buffer.length) | 0 + that = allocate(that, length) + buffer.copy(that, 0, 0, length) + return that +} + +function fromArray (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +// Duplicate of fromArray() to keep fromArray() monomorphic. +function fromTypedArray (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + // Truncating the elements is probably not what people expect from typed + // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior + // of the old Buffer constructor. + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +function fromArrayBuffer (that, array) { + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + array.byteLength + that = Buffer._augment(new Uint8Array(array)) + } else { + // Fallback: Return an object instance of the Buffer class + that = fromTypedArray(that, new Uint8Array(array)) + } + return that +} + +function fromArrayLike (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. +// Returns a zero-length buffer for inputs that don't conform to the spec. +function fromJsonObject (that, object) { + var array + var length = 0 + + if (object.type === 'Buffer' && isArray(object.data)) { + array = object.data + length = checked(array.length) | 0 + } + that = allocate(that, length) + + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype + Buffer.__proto__ = Uint8Array +} + +function allocate (that, length) { + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = Buffer._augment(new Uint8Array(length)) + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + that.length = length + that._isBuffer = true + } + + var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 + if (fromPool) that.parent = rootParent + + return that +} + +function checked (length) { + // Note: cannot use `length < kMaxLength` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} + +function SlowBuffer (subject, encoding) { + if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) + + var buf = new Buffer(subject, encoding) + delete buf.parent + return buf +} + +Buffer.isBuffer = function isBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length + var y = b.length + + var i = 0 + var len = Math.min(x, y) + while (i < len) { + if (a[i] !== b[i]) break + + ++i + } + + if (i !== len) { + x = a[i] + y = b[i] + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'binary': + case 'base64': + case 'raw': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') + + if (list.length === 0) { + return new Buffer(0) + } + + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; i++) { + length += list[i].length + } + } + + var buf = new Buffer(length) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf +} + +function byteLength (string, encoding) { + if (typeof string !== 'string') string = '' + string + + var len = string.length + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'binary': + // Deprecated + case 'raw': + case 'raws': + return len + case 'utf8': + case 'utf-8': + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} +Buffer.byteLength = byteLength + +// pre-set for values that may exist in the future +Buffer.prototype.length = undefined +Buffer.prototype.parent = undefined + +function slowToString (encoding, start, end) { + var loweredCase = false + + start = start | 0 + end = end === undefined || end === Infinity ? this.length : end | 0 + + if (!encoding) encoding = 'utf8' + if (start < 0) start = 0 + if (end > this.length) end = this.length + if (end <= start) return '' + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'binary': + return binarySlice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toString = function toString () { + var length = this.length | 0 + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +} + +Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +} + +Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) str += ' ... ' + } + return '' +} + +Buffer.prototype.compare = function compare (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return 0 + return Buffer.compare(this, b) +} + +Buffer.prototype.indexOf = function indexOf (val, byteOffset) { + if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff + else if (byteOffset < -0x80000000) byteOffset = -0x80000000 + byteOffset >>= 0 + + if (this.length === 0) return -1 + if (byteOffset >= this.length) return -1 + + // Negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) + + if (typeof val === 'string') { + if (val.length === 0) return -1 // special case: looking for empty string always fails + return String.prototype.indexOf.call(this, val, byteOffset) + } + if (Buffer.isBuffer(val)) { + return arrayIndexOf(this, val, byteOffset) + } + if (typeof val === 'number') { + if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { + return Uint8Array.prototype.indexOf.call(this, val, byteOffset) + } + return arrayIndexOf(this, [ val ], byteOffset) + } + + function arrayIndexOf (arr, val, byteOffset) { + var foundIndex = -1 + for (var i = 0; byteOffset + i < arr.length; i++) { + if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex + } else { + foundIndex = -1 + } + } + return -1 + } + + throw new TypeError('val must be string, number or Buffer') +} + +// `get` is deprecated +Buffer.prototype.get = function get (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) +} + +// `set` is deprecated +Buffer.prototype.set = function set (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) +} + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new Error('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(parsed)) throw new Error('Invalid hex string') + buf[offset + i] = parsed + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function binaryWrite (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0 + if (isFinite(length)) { + length = length | 0 + if (encoding === undefined) encoding = 'utf8' + } else { + encoding = length + length = undefined + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + var swap = encoding + encoding = offset + offset = length | 0 + length = swap + } + + var remaining = this.length - offset + if (length === undefined || length > remaining) length = remaining + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('attempt to write outside buffer bounds') + } + + if (!encoding) encoding = 'utf8' + + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'binary': + return binaryWrite(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end) + var res = [] + + var i = start + while (i < end) { + var firstByte = buf[i] + var codePoint = null + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1 + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte + } + break + case 2: + secondByte = buf[i + 1] + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint + } + } + break + case 3: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint + } + } + break + case 4: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + fourthByte = buf[i + 3] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD + bytesPerSequence = 1 + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000 + res.push(codePoint >>> 10 & 0x3FF | 0xD800) + codePoint = 0xDC00 | codePoint & 0x3FF + } + + res.push(codePoint) + i += bytesPerSequence + } + + return decodeCodePointsArray(res) +} + +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000 + +function decodeCodePointsArray (codePoints) { + var len = codePoints.length + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = '' + var i = 0 + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ) + } + return res +} + +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret +} + +function binarySlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i]) + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; i++) { + out += toHex(buf[i]) + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end + + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len + } + + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } + + if (end < start) end = start + + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + } + + if (newBuf.length) newBuf.parent = this.parent || this + + return newBuf +} + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + + return val +} + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) + } + + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul + } + + return val +} + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] +} + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} + +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') +} + +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = (value & 0xff) + return offset + 1 +} + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = 0 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = byteLength - 1 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = (value & 0xff) + return offset + 1 +} + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') + if (offset < 0) throw new RangeError('index out of range') +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start + } + + var len = end - start + var i + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; i--) { + target[i + targetStart] = this[i + start] + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; i++) { + target[i + targetStart] = this[i + start] + } + } else { + target._set(this.subarray(start, start + len), targetStart) + } + + return len +} + +// fill(value, start=0, end=buffer.length) +Buffer.prototype.fill = function fill (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length + + if (end < start) throw new RangeError('end < start') + + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') + if (end < 0 || end > this.length) throw new RangeError('end out of bounds') + + var i + if (typeof value === 'number') { + for (i = start; i < end; i++) { + this[i] = value + } + } else { + var bytes = utf8ToBytes(value.toString()) + var len = bytes.length + for (i = start; i < end; i++) { + this[i] = bytes[i % len] + } + } + + return this +} + +/** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ +Buffer.prototype.toArrayBuffer = function toArrayBuffer () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer.TYPED_ARRAY_SUPPORT) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) { + buf[i] = this[i] + } + return buf.buffer + } + } else { + throw new TypeError('Buffer.toArrayBuffer not supported in this browser') + } +} + +// HELPER FUNCTIONS +// ================ + +var BP = Buffer.prototype + +/** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ +Buffer._augment = function _augment (arr) { + arr.constructor = Buffer + arr._isBuffer = true + + // save reference to original Uint8Array set method before overwriting + arr._set = arr.set + + // deprecated + arr.get = BP.get + arr.set = BP.set + + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.equals = BP.equals + arr.compare = BP.compare + arr.indexOf = BP.indexOf + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUIntLE = BP.readUIntLE + arr.readUIntBE = BP.readUIntBE + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readIntLE = BP.readIntLE + arr.readIntBE = BP.readIntBE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUIntLE = BP.writeUIntLE + arr.writeUIntBE = BP.writeUIntBE + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeIntLE = BP.writeIntLE + arr.writeIntBE = BP.writeIntBE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer + + return arr +} + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + + for (var i = 0; i < length; i++) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } + + // valid lead + leadSurrogate = codePoint + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } + + // valid surrogate pair + codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + } + + leadSurrogate = null + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] + } + return i +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"base64-js":2,"ieee754":4,"is-array":5}],4:[function(require,module,exports){ +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } + + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 +} + +},{}],5:[function(require,module,exports){ + +/** + * isArray + */ + +var isArray = Array.isArray; + +/** + * toString + */ + +var str = Object.prototype.toString; + +/** + * Whether or not the given `val` + * is an array. + * + * example: + * + * isArray([]); + * // > true + * isArray(arguments); + * // > false + * isArray(''); + * // > false + * + * @param {mixed} val + * @return {bool} + */ + +module.exports = isArray || function (val) { + return !! val && '[object Array]' == str.call(val); +}; + +},{}],6:[function(require,module,exports){ +(function (global){ + +/** + * Module exports. + */ + +module.exports = deprecate; + +/** + * Mark that a method should not be used. + * Returns a modified function which warns once by default. + * + * If `localStorage.noDeprecation = true` is set, then it is a no-op. + * + * If `localStorage.throwDeprecation = true` is set, then deprecated functions + * will throw an Error when invoked. + * + * If `localStorage.traceDeprecation = true` is set, then deprecated functions + * will invoke `console.trace()` instead of `console.error()`. + * + * @param {Function} fn - the function to deprecate + * @param {String} msg - the string to print to the console when `fn` is invoked + * @returns {Function} a new "deprecated" version of `fn` + * @api public + */ + +function deprecate (fn, msg) { + if (config('noDeprecation')) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (config('throwDeprecation')) { + throw new Error(msg); + } else if (config('traceDeprecation')) { + console.trace(msg); + } else { + console.warn(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +} + +/** + * Checks `localStorage` for boolean values for the given `name`. + * + * @param {String} name + * @returns {Boolean} + * @api private + */ + +function config (name) { + // accessing global.localStorage can trigger a DOMException in sandboxed iframes + try { + if (!global.localStorage) return false; + } catch (_) { + return false; + } + var val = global.localStorage[name]; + if (null == val) return false; + return String(val).toLowerCase() === 'true'; +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],7:[function(require,module,exports){ +function DOMParser(options){ + this.options = options ||{locator:{}}; + +} +DOMParser.prototype.parseFromString = function(source,mimeType){ + var options = this.options; + var sax = new XMLReader(); + var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler + var errorHandler = options.errorHandler; + var locator = options.locator; + var defaultNSMap = options.xmlns||{}; + var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"} + if(locator){ + domBuilder.setDocumentLocator(locator) + } + + sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator); + sax.domBuilder = options.domBuilder || domBuilder; + if(/\/x?html?$/.test(mimeType)){ + entityMap.nbsp = '\xa0'; + entityMap.copy = '\xa9'; + defaultNSMap['']= 'http://www.w3.org/1999/xhtml'; + } + if(source){ + sax.parse(source,defaultNSMap,entityMap); + }else{ + sax.errorHandler.error("invalid document source"); + } + return domBuilder.document; +} +function buildErrorHandler(errorImpl,domBuilder,locator){ + if(!errorImpl){ + if(domBuilder instanceof DOMHandler){ + return domBuilder; + } + errorImpl = domBuilder ; + } + var errorHandler = {} + var isCallback = errorImpl instanceof Function; + locator = locator||{} + function build(key){ + var fn = errorImpl[key]; + if(!fn){ + if(isCallback){ + fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl; + }else{ + var i=arguments.length; + while(--i){ + if(fn = errorImpl[arguments[i]]){ + break; + } + } + } + } + errorHandler[key] = fn && function(msg){ + fn(msg+_locator(locator)); + }||function(){}; + } + build('warning','warn'); + build('error','warn','warning'); + build('fatalError','warn','warning','error'); + return errorHandler; +} +/** + * +ContentHandler+ErrorHandler + * +LexicalHandler+EntityResolver2 + * -DeclHandler-DTDHandler + * + * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler + * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2 + * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html + */ +function DOMHandler() { + this.cdata = false; +} +function position(locator,node){ + node.lineNumber = locator.lineNumber; + node.columnNumber = locator.columnNumber; +} +/** + * @see org.xml.sax.ContentHandler#startDocument + * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html + */ +DOMHandler.prototype = { + startDocument : function() { + this.document = new DOMImplementation().createDocument(null, null, null); + if (this.locator) { + this.document.documentURI = this.locator.systemId; + } + }, + startElement:function(namespaceURI, localName, qName, attrs) { + var doc = this.document; + var el = doc.createElementNS(namespaceURI, qName||localName); + var len = attrs.length; + appendElement(this, el); + this.currentElement = el; + + this.locator && position(this.locator,el) + for (var i = 0 ; i < len; i++) { + var namespaceURI = attrs.getURI(i); + var value = attrs.getValue(i); + var qName = attrs.getQName(i); + var attr = doc.createAttributeNS(namespaceURI, qName); + if( attr.getOffset){ + position(attr.getOffset(1),attr) + } + attr.value = attr.nodeValue = value; + el.setAttributeNode(attr) + } + }, + endElement:function(namespaceURI, localName, qName) { + var current = this.currentElement + var tagName = current.tagName; + this.currentElement = current.parentNode; + }, + startPrefixMapping:function(prefix, uri) { + }, + endPrefixMapping:function(prefix) { + }, + processingInstruction:function(target, data) { + var ins = this.document.createProcessingInstruction(target, data); + this.locator && position(this.locator,ins) + appendElement(this, ins); + }, + ignorableWhitespace:function(ch, start, length) { + }, + characters:function(chars, start, length) { + chars = _toString.apply(this,arguments) + //console.log(chars) + if(this.currentElement && chars){ + if (this.cdata) { + var charNode = this.document.createCDATASection(chars); + this.currentElement.appendChild(charNode); + } else { + var charNode = this.document.createTextNode(chars); + this.currentElement.appendChild(charNode); + } + this.locator && position(this.locator,charNode) + } + }, + skippedEntity:function(name) { + }, + endDocument:function() { + this.document.normalize(); + }, + setDocumentLocator:function (locator) { + if(this.locator = locator){// && !('lineNumber' in locator)){ + locator.lineNumber = 0; + } + }, + //LexicalHandler + comment:function(chars, start, length) { + chars = _toString.apply(this,arguments) + var comm = this.document.createComment(chars); + this.locator && position(this.locator,comm) + appendElement(this, comm); + }, + + startCDATA:function() { + //used in characters() methods + this.cdata = true; + }, + endCDATA:function() { + this.cdata = false; + }, + + startDTD:function(name, publicId, systemId) { + var impl = this.document.implementation; + if (impl && impl.createDocumentType) { + var dt = impl.createDocumentType(name, publicId, systemId); + this.locator && position(this.locator,dt) + appendElement(this, dt); + } + }, + /** + * @see org.xml.sax.ErrorHandler + * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html + */ + warning:function(error) { + console.warn(error,_locator(this.locator)); + }, + error:function(error) { + console.error(error,_locator(this.locator)); + }, + fatalError:function(error) { + console.error(error,_locator(this.locator)); + throw error; + } +} +function _locator(l){ + if(l){ + return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']' + } +} +function _toString(chars,start,length){ + if(typeof chars == 'string'){ + return chars.substr(start,length) + }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)") + if(chars.length >= start+length || start){ + return new java.lang.String(chars,start,length)+''; + } + return chars; + } +} + +/* + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html + * used method of org.xml.sax.ext.LexicalHandler: + * #comment(chars, start, length) + * #startCDATA() + * #endCDATA() + * #startDTD(name, publicId, systemId) + * + * + * IGNORED method of org.xml.sax.ext.LexicalHandler: + * #endDTD() + * #startEntity(name) + * #endEntity(name) + * + * + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html + * IGNORED method of org.xml.sax.ext.DeclHandler + * #attributeDecl(eName, aName, type, mode, value) + * #elementDecl(name, model) + * #externalEntityDecl(name, publicId, systemId) + * #internalEntityDecl(name, value) + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html + * IGNORED method of org.xml.sax.EntityResolver2 + * #resolveEntity(String name,String publicId,String baseURI,String systemId) + * #resolveEntity(publicId, systemId) + * #getExternalSubset(name, baseURI) + * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html + * IGNORED method of org.xml.sax.DTDHandler + * #notationDecl(name, publicId, systemId) {}; + * #unparsedEntityDecl(name, publicId, systemId, notationName) {}; + */ +"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){ + DOMHandler.prototype[key] = function(){return null} +}) + +/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */ +function appendElement (hander,node) { + if (!hander.currentElement) { + hander.document.appendChild(node); + } else { + hander.currentElement.appendChild(node); + } +}//appendChild and setAttributeNS are preformance key + +if(typeof require == 'function'){ + var XMLReader = require('./sax').XMLReader; + var DOMImplementation = exports.DOMImplementation = require('./dom').DOMImplementation; + exports.XMLSerializer = require('./dom').XMLSerializer ; + exports.DOMParser = DOMParser; +} + +},{"./dom":8,"./sax":9}],8:[function(require,module,exports){ +/* + * DOM Level 2 + * Object DOMException + * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html + */ + +function copy(src,dest){ + for(var p in src){ + dest[p] = src[p]; + } +} +/** +^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));? +^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));? + */ +function _extends(Class,Super){ + var pt = Class.prototype; + if(Object.create){ + var ppt = Object.create(Super.prototype) + pt.__proto__ = ppt; + } + if(!(pt instanceof Super)){ + function t(){}; + t.prototype = Super.prototype; + t = new t(); + copy(pt,t); + Class.prototype = pt = t; + } + if(pt.constructor != Class){ + if(typeof Class != 'function'){ + console.error("unknow Class:"+Class) + } + pt.constructor = Class + } +} +var htmlns = 'http://www.w3.org/1999/xhtml' ; +// Node Types +var NodeType = {} +var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1; +var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2; +var TEXT_NODE = NodeType.TEXT_NODE = 3; +var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4; +var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5; +var ENTITY_NODE = NodeType.ENTITY_NODE = 6; +var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7; +var COMMENT_NODE = NodeType.COMMENT_NODE = 8; +var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9; +var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10; +var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11; +var NOTATION_NODE = NodeType.NOTATION_NODE = 12; + +// ExceptionCode +var ExceptionCode = {} +var ExceptionMessage = {}; +var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1); +var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2); +var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3); +var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4); +var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5); +var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6); +var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7); +var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8); +var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9); +var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10); +//level2 +var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11); +var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12); +var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13); +var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14); +var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15); + + +function DOMException(code, message) { + if(message instanceof Error){ + var error = message; + }else{ + error = this; + Error.call(this, ExceptionMessage[code]); + this.message = ExceptionMessage[code]; + if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException); + } + error.code = code; + if(message) this.message = this.message + ": " + message; + return error; +}; +DOMException.prototype = Error.prototype; +copy(ExceptionCode,DOMException) +/** + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177 + * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live. + * The items in the NodeList are accessible via an integral index, starting from 0. + */ +function NodeList() { +}; +NodeList.prototype = { + /** + * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive. + * @standard level1 + */ + length:0, + /** + * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null. + * @standard level1 + * @param index unsigned long + * Index into the collection. + * @return Node + * The node at the indexth position in the NodeList, or null if that is not a valid index. + */ + item: function(index) { + return this[index] || null; + } +}; +function LiveNodeList(node,refresh){ + this._node = node; + this._refresh = refresh + _updateLiveList(this); +} +function _updateLiveList(list){ + var inc = list._node._inc || list._node.ownerDocument._inc; + if(list._inc != inc){ + var ls = list._refresh(list._node); + //console.log(ls.length) + __set__(list,'length',ls.length); + copy(ls,list); + list._inc = inc; + } +} +LiveNodeList.prototype.item = function(i){ + _updateLiveList(this); + return this[i]; +} + +_extends(LiveNodeList,NodeList); +/** + * + * Objects implementing the NamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that NamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes. + * NamedNodeMap objects in the DOM are live. + * used for attributes or DocumentType entities + */ +function NamedNodeMap() { +}; + +function _findNodeIndex(list,node){ + var i = list.length; + while(i--){ + if(list[i] === node){return i} + } +} + +function _addNamedNode(el,list,newAttr,oldAttr){ + if(oldAttr){ + list[_findNodeIndex(list,oldAttr)] = newAttr; + }else{ + list[list.length++] = newAttr; + } + if(el){ + newAttr.ownerElement = el; + var doc = el.ownerDocument; + if(doc){ + oldAttr && _onRemoveAttribute(doc,el,oldAttr); + _onAddAttribute(doc,el,newAttr); + } + } +} +function _removeNamedNode(el,list,attr){ + var i = _findNodeIndex(list,attr); + if(i>=0){ + var lastIndex = list.length-1 + while(i0 || key == 'xmlns'){ +// return null; +// } + var i = this.length; + while(i--){ + var attr = this[i]; + if(attr.nodeName == key){ + return attr; + } + } + }, + setNamedItem: function(attr) { + var el = attr.ownerElement; + if(el && el!=this._ownerElement){ + throw new DOMException(INUSE_ATTRIBUTE_ERR); + } + var oldAttr = this.getNamedItem(attr.nodeName); + _addNamedNode(this._ownerElement,this,attr,oldAttr); + return oldAttr; + }, + /* returns Node */ + setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR + var el = attr.ownerElement, oldAttr; + if(el && el!=this._ownerElement){ + throw new DOMException(INUSE_ATTRIBUTE_ERR); + } + oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName); + _addNamedNode(this._ownerElement,this,attr,oldAttr); + return oldAttr; + }, + + /* returns Node */ + removeNamedItem: function(key) { + var attr = this.getNamedItem(key); + _removeNamedNode(this._ownerElement,this,attr); + return attr; + + + },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR + + //for level2 + removeNamedItemNS:function(namespaceURI,localName){ + var attr = this.getNamedItemNS(namespaceURI,localName); + _removeNamedNode(this._ownerElement,this,attr); + return attr; + }, + getNamedItemNS: function(namespaceURI, localName) { + var i = this.length; + while(i--){ + var node = this[i]; + if(node.localName == localName && node.namespaceURI == namespaceURI){ + return node; + } + } + return null; + } +}; +/** + * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 + */ +function DOMImplementation(/* Object */ features) { + this._features = {}; + if (features) { + for (var feature in features) { + this._features = features[feature]; + } + } +}; + +DOMImplementation.prototype = { + hasFeature: function(/* string */ feature, /* string */ version) { + var versions = this._features[feature.toLowerCase()]; + if (versions && (!version || version in versions)) { + return true; + } else { + return false; + } + }, + // Introduced in DOM Level 2: + createDocument:function(namespaceURI, qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR + var doc = new Document(); + doc.doctype = doctype; + if(doctype){ + doc.appendChild(doctype); + } + doc.implementation = this; + doc.childNodes = new NodeList(); + if(qualifiedName){ + var root = doc.createElementNS(namespaceURI,qualifiedName); + doc.appendChild(root); + } + return doc; + }, + // Introduced in DOM Level 2: + createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR + var node = new DocumentType(); + node.name = qualifiedName; + node.nodeName = qualifiedName; + node.publicId = publicId; + node.systemId = systemId; + // Introduced in DOM Level 2: + //readonly attribute DOMString internalSubset; + + //TODO:.. + // readonly attribute NamedNodeMap entities; + // readonly attribute NamedNodeMap notations; + return node; + } +}; + + +/** + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 + */ + +function Node() { +}; + +Node.prototype = { + firstChild : null, + lastChild : null, + previousSibling : null, + nextSibling : null, + attributes : null, + parentNode : null, + childNodes : null, + ownerDocument : null, + nodeValue : null, + namespaceURI : null, + prefix : null, + localName : null, + // Modified in DOM Level 2: + insertBefore:function(newChild, refChild){//raises + return _insertBefore(this,newChild,refChild); + }, + replaceChild:function(newChild, oldChild){//raises + this.insertBefore(newChild,oldChild); + if(oldChild){ + this.removeChild(oldChild); + } + }, + removeChild:function(oldChild){ + return _removeChild(this,oldChild); + }, + appendChild:function(newChild){ + return this.insertBefore(newChild,null); + }, + hasChildNodes:function(){ + return this.firstChild != null; + }, + cloneNode:function(deep){ + return cloneNode(this.ownerDocument||this,this,deep); + }, + // Modified in DOM Level 2: + normalize:function(){ + var child = this.firstChild; + while(child){ + var next = child.nextSibling; + if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){ + this.removeChild(next); + child.appendData(next.data); + }else{ + child.normalize(); + child = next; + } + } + }, + // Introduced in DOM Level 2: + isSupported:function(feature, version){ + return this.ownerDocument.implementation.hasFeature(feature,version); + }, + // Introduced in DOM Level 2: + hasAttributes:function(){ + return this.attributes.length>0; + }, + lookupPrefix:function(namespaceURI){ + var el = this; + while(el){ + var map = el._nsMap; + //console.dir(map) + if(map){ + for(var n in map){ + if(map[n] == namespaceURI){ + return n; + } + } + } + el = el.nodeType == 2?el.ownerDocument : el.parentNode; + } + return null; + }, + // Introduced in DOM Level 3: + lookupNamespaceURI:function(prefix){ + var el = this; + while(el){ + var map = el._nsMap; + //console.dir(map) + if(map){ + if(prefix in map){ + return map[prefix] ; + } + } + el = el.nodeType == 2?el.ownerDocument : el.parentNode; + } + return null; + }, + // Introduced in DOM Level 3: + isDefaultNamespace:function(namespaceURI){ + var prefix = this.lookupPrefix(namespaceURI); + return prefix == null; + } +}; + + +function _xmlEncoder(c){ + return c == '<' && '<' || + c == '>' && '>' || + c == '&' && '&' || + c == '"' && '"' || + '&#'+c.charCodeAt()+';' +} + + +copy(NodeType,Node); +copy(NodeType,Node.prototype); + +/** + * @param callback return true for continue,false for break + * @return boolean true: break visit; + */ +function _visitNode(node,callback){ + if(callback(node)){ + return true; + } + if(node = node.firstChild){ + do{ + if(_visitNode(node,callback)){return true} + }while(node=node.nextSibling) + } +} + + + +function Document(){ +} +function _onAddAttribute(doc,el,newAttr){ + doc && doc._inc++; + var ns = newAttr.namespaceURI ; + if(ns == 'http://www.w3.org/2000/xmlns/'){ + //update namespace + el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value + } +} +function _onRemoveAttribute(doc,el,newAttr,remove){ + doc && doc._inc++; + var ns = newAttr.namespaceURI ; + if(ns == 'http://www.w3.org/2000/xmlns/'){ + //update namespace + delete el._nsMap[newAttr.prefix?newAttr.localName:''] + } +} +function _onUpdateChild(doc,el,newChild){ + if(doc && doc._inc){ + doc._inc++; + //update childNodes + var cs = el.childNodes; + if(newChild){ + cs[cs.length++] = newChild; + }else{ + //console.log(1) + var child = el.firstChild; + var i = 0; + while(child){ + cs[i++] = child; + child =child.nextSibling; + } + cs.length = i; + } + } +} + +/** + * attributes; + * children; + * + * writeable properties: + * nodeValue,Attr:value,CharacterData:data + * prefix + */ +function _removeChild(parentNode,child){ + var previous = child.previousSibling; + var next = child.nextSibling; + if(previous){ + previous.nextSibling = next; + }else{ + parentNode.firstChild = next + } + if(next){ + next.previousSibling = previous; + }else{ + parentNode.lastChild = previous; + } + _onUpdateChild(parentNode.ownerDocument,parentNode); + return child; +} +/** + * preformance key(refChild == null) + */ +function _insertBefore(parentNode,newChild,nextChild){ + var cp = newChild.parentNode; + if(cp){ + cp.removeChild(newChild);//remove and update + } + if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){ + var newFirst = newChild.firstChild; + if (newFirst == null) { + return newChild; + } + var newLast = newChild.lastChild; + }else{ + newFirst = newLast = newChild; + } + var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild; + + newFirst.previousSibling = pre; + newLast.nextSibling = nextChild; + + + if(pre){ + pre.nextSibling = newFirst; + }else{ + parentNode.firstChild = newFirst; + } + if(nextChild == null){ + parentNode.lastChild = newLast; + }else{ + nextChild.previousSibling = newLast; + } + do{ + newFirst.parentNode = parentNode; + }while(newFirst !== newLast && (newFirst= newFirst.nextSibling)) + _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode); + //console.log(parentNode.lastChild.nextSibling == null) + if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) { + newChild.firstChild = newChild.lastChild = null; + } + return newChild; +} +function _appendSingleChild(parentNode,newChild){ + var cp = newChild.parentNode; + if(cp){ + var pre = parentNode.lastChild; + cp.removeChild(newChild);//remove and update + var pre = parentNode.lastChild; + } + var pre = parentNode.lastChild; + newChild.parentNode = parentNode; + newChild.previousSibling = pre; + newChild.nextSibling = null; + if(pre){ + pre.nextSibling = newChild; + }else{ + parentNode.firstChild = newChild; + } + parentNode.lastChild = newChild; + _onUpdateChild(parentNode.ownerDocument,parentNode,newChild); + return newChild; + //console.log("__aa",parentNode.lastChild.nextSibling == null) +} +Document.prototype = { + //implementation : null, + nodeName : '#document', + nodeType : DOCUMENT_NODE, + doctype : null, + documentElement : null, + _inc : 1, + + insertBefore : function(newChild, refChild){//raises + if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){ + var child = newChild.firstChild; + while(child){ + var next = child.nextSibling; + this.insertBefore(child,refChild); + child = next; + } + return newChild; + } + if(this.documentElement == null && newChild.nodeType == 1){ + this.documentElement = newChild; + } + + return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild; + }, + removeChild : function(oldChild){ + if(this.documentElement == oldChild){ + this.documentElement = null; + } + return _removeChild(this,oldChild); + }, + // Introduced in DOM Level 2: + importNode : function(importedNode,deep){ + return importNode(this,importedNode,deep); + }, + // Introduced in DOM Level 2: + getElementById : function(id){ + var rtv = null; + _visitNode(this.documentElement,function(node){ + if(node.nodeType == 1){ + if(node.getAttribute('id') == id){ + rtv = node; + return true; + } + } + }) + return rtv; + }, + + //document factory method: + createElement : function(tagName){ + var node = new Element(); + node.ownerDocument = this; + node.nodeName = tagName; + node.tagName = tagName; + node.childNodes = new NodeList(); + var attrs = node.attributes = new NamedNodeMap(); + attrs._ownerElement = node; + return node; + }, + createDocumentFragment : function(){ + var node = new DocumentFragment(); + node.ownerDocument = this; + node.childNodes = new NodeList(); + return node; + }, + createTextNode : function(data){ + var node = new Text(); + node.ownerDocument = this; + node.appendData(data) + return node; + }, + createComment : function(data){ + var node = new Comment(); + node.ownerDocument = this; + node.appendData(data) + return node; + }, + createCDATASection : function(data){ + var node = new CDATASection(); + node.ownerDocument = this; + node.appendData(data) + return node; + }, + createProcessingInstruction : function(target,data){ + var node = new ProcessingInstruction(); + node.ownerDocument = this; + node.tagName = node.target = target; + node.nodeValue= node.data = data; + return node; + }, + createAttribute : function(name){ + var node = new Attr(); + node.ownerDocument = this; + node.name = name; + node.nodeName = name; + node.localName = name; + node.specified = true; + return node; + }, + createEntityReference : function(name){ + var node = new EntityReference(); + node.ownerDocument = this; + node.nodeName = name; + return node; + }, + // Introduced in DOM Level 2: + createElementNS : function(namespaceURI,qualifiedName){ + var node = new Element(); + var pl = qualifiedName.split(':'); + var attrs = node.attributes = new NamedNodeMap(); + node.childNodes = new NodeList(); + node.ownerDocument = this; + node.nodeName = qualifiedName; + node.tagName = qualifiedName; + node.namespaceURI = namespaceURI; + if(pl.length == 2){ + node.prefix = pl[0]; + node.localName = pl[1]; + }else{ + //el.prefix = null; + node.localName = qualifiedName; + } + attrs._ownerElement = node; + return node; + }, + // Introduced in DOM Level 2: + createAttributeNS : function(namespaceURI,qualifiedName){ + var node = new Attr(); + var pl = qualifiedName.split(':'); + node.ownerDocument = this; + node.nodeName = qualifiedName; + node.name = qualifiedName; + node.namespaceURI = namespaceURI; + node.specified = true; + if(pl.length == 2){ + node.prefix = pl[0]; + node.localName = pl[1]; + }else{ + //el.prefix = null; + node.localName = qualifiedName; + } + return node; + } +}; +_extends(Document,Node); + + +function Element() { + this._nsMap = {}; +}; +Element.prototype = { + nodeType : ELEMENT_NODE, + hasAttribute : function(name){ + return this.getAttributeNode(name)!=null; + }, + getAttribute : function(name){ + var attr = this.getAttributeNode(name); + return attr && attr.value || ''; + }, + getAttributeNode : function(name){ + return this.attributes.getNamedItem(name); + }, + setAttribute : function(name, value){ + var attr = this.ownerDocument.createAttribute(name); + attr.value = attr.nodeValue = "" + value; + this.setAttributeNode(attr) + }, + removeAttribute : function(name){ + var attr = this.getAttributeNode(name) + attr && this.removeAttributeNode(attr); + }, + + //four real opeartion method + appendChild:function(newChild){ + if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){ + return this.insertBefore(newChild,null); + }else{ + return _appendSingleChild(this,newChild); + } + }, + setAttributeNode : function(newAttr){ + return this.attributes.setNamedItem(newAttr); + }, + setAttributeNodeNS : function(newAttr){ + return this.attributes.setNamedItemNS(newAttr); + }, + removeAttributeNode : function(oldAttr){ + return this.attributes.removeNamedItem(oldAttr.nodeName); + }, + //get real attribute name,and remove it by removeAttributeNode + removeAttributeNS : function(namespaceURI, localName){ + var old = this.getAttributeNodeNS(namespaceURI, localName); + old && this.removeAttributeNode(old); + }, + + hasAttributeNS : function(namespaceURI, localName){ + return this.getAttributeNodeNS(namespaceURI, localName)!=null; + }, + getAttributeNS : function(namespaceURI, localName){ + var attr = this.getAttributeNodeNS(namespaceURI, localName); + return attr && attr.value || ''; + }, + setAttributeNS : function(namespaceURI, qualifiedName, value){ + var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName); + attr.value = attr.nodeValue = value; + this.setAttributeNode(attr) + }, + getAttributeNodeNS : function(namespaceURI, localName){ + return this.attributes.getNamedItemNS(namespaceURI, localName); + }, + + getElementsByTagName : function(tagName){ + return new LiveNodeList(this,function(base){ + var ls = []; + _visitNode(base,function(node){ + if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){ + ls.push(node); + } + }); + return ls; + }); + }, + getElementsByTagNameNS : function(namespaceURI, localName){ + return new LiveNodeList(this,function(base){ + var ls = []; + _visitNode(base,function(node){ + if(node !== base && node.nodeType === ELEMENT_NODE && node.namespaceURI === namespaceURI && (localName === '*' || node.localName == localName)){ + ls.push(node); + } + }); + return ls; + }); + } +}; +Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName; +Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS; + + +_extends(Element,Node); +function Attr() { +}; +Attr.prototype.nodeType = ATTRIBUTE_NODE; +_extends(Attr,Node); + + +function CharacterData() { +}; +CharacterData.prototype = { + data : '', + substringData : function(offset, count) { + return this.data.substring(offset, offset+count); + }, + appendData: function(text) { + text = this.data+text; + this.nodeValue = this.data = text; + this.length = text.length; + }, + insertData: function(offset,text) { + this.replaceData(offset,0,text); + + }, + appendChild:function(newChild){ + //if(!(newChild instanceof CharacterData)){ + throw new Error(ExceptionMessage[3]) + //} + return Node.prototype.appendChild.apply(this,arguments) + }, + deleteData: function(offset, count) { + this.replaceData(offset,count,""); + }, + replaceData: function(offset, count, text) { + var start = this.data.substring(0,offset); + var end = this.data.substring(offset+count); + text = start + text + end; + this.nodeValue = this.data = text; + this.length = text.length; + } +} +_extends(CharacterData,Node); +function Text() { +}; +Text.prototype = { + nodeName : "#text", + nodeType : TEXT_NODE, + splitText : function(offset) { + var text = this.data; + var newText = text.substring(offset); + text = text.substring(0, offset); + this.data = this.nodeValue = text; + this.length = text.length; + var newNode = this.ownerDocument.createTextNode(newText); + if(this.parentNode){ + this.parentNode.insertBefore(newNode, this.nextSibling); + } + return newNode; + } +} +_extends(Text,CharacterData); +function Comment() { +}; +Comment.prototype = { + nodeName : "#comment", + nodeType : COMMENT_NODE +} +_extends(Comment,CharacterData); + +function CDATASection() { +}; +CDATASection.prototype = { + nodeName : "#cdata-section", + nodeType : CDATA_SECTION_NODE +} +_extends(CDATASection,CharacterData); + + +function DocumentType() { +}; +DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE; +_extends(DocumentType,Node); + +function Notation() { +}; +Notation.prototype.nodeType = NOTATION_NODE; +_extends(Notation,Node); + +function Entity() { +}; +Entity.prototype.nodeType = ENTITY_NODE; +_extends(Entity,Node); + +function EntityReference() { +}; +EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE; +_extends(EntityReference,Node); + +function DocumentFragment() { +}; +DocumentFragment.prototype.nodeName = "#document-fragment"; +DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE; +_extends(DocumentFragment,Node); + + +function ProcessingInstruction() { +} +ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE; +_extends(ProcessingInstruction,Node); +function XMLSerializer(){} +XMLSerializer.prototype.serializeToString = function(node){ + var buf = []; + serializeToString(node,buf); + return buf.join(''); +} +Node.prototype.toString =function(){ + return XMLSerializer.prototype.serializeToString(this); +} +function serializeToString(node,buf){ + switch(node.nodeType){ + case ELEMENT_NODE: + var attrs = node.attributes; + var len = attrs.length; + var child = node.firstChild; + var nodeName = node.tagName; + var isHTML = htmlns === node.namespaceURI + buf.push('<',nodeName); + for(var i=0;i'); + //if is cdata child node + if(isHTML && /^script$/i.test(nodeName)){ + if(child){ + buf.push(child.data); + } + }else{ + while(child){ + serializeToString(child,buf); + child = child.nextSibling; + } + } + buf.push(''); + }else{ + buf.push('/>'); + } + return; + case DOCUMENT_NODE: + case DOCUMENT_FRAGMENT_NODE: + var child = node.firstChild; + while(child){ + serializeToString(child,buf); + child = child.nextSibling; + } + return; + case ATTRIBUTE_NODE: + return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"'); + case TEXT_NODE: + return buf.push(node.data.replace(/[<&]/g,_xmlEncoder)); + case CDATA_SECTION_NODE: + return buf.push( ''); + case COMMENT_NODE: + return buf.push( ""); + case DOCUMENT_TYPE_NODE: + var pubid = node.publicId; + var sysid = node.systemId; + buf.push(''); + }else if(sysid && sysid!='.'){ + buf.push(' SYSTEM "',sysid,'">'); + }else{ + var sub = node.internalSubset; + if(sub){ + buf.push(" [",sub,"]"); + } + buf.push(">"); + } + return; + case PROCESSING_INSTRUCTION_NODE: + return buf.push( ""); + case ENTITY_REFERENCE_NODE: + return buf.push( '&',node.nodeName,';'); + //case ENTITY_NODE: + //case NOTATION_NODE: + default: + buf.push('??',node.nodeName); + } +} +function importNode(doc,node,deep){ + var node2; + switch (node.nodeType) { + case ELEMENT_NODE: + node2 = node.cloneNode(false); + node2.ownerDocument = doc; + //var attrs = node2.attributes; + //var len = attrs.length; + //for(var i=0;i + +function XMLReader(){ + +} + +XMLReader.prototype = { + parse:function(source,defaultNSMap,entityMap){ + var domBuilder = this.domBuilder; + domBuilder.startDocument(); + _copy(defaultNSMap ,defaultNSMap = {}) + parse(source,defaultNSMap,entityMap, + domBuilder,this.errorHandler); + domBuilder.endDocument(); + } +} +function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){ + function fixedFromCharCode(code) { + // String.prototype.fromCharCode does not supports + // > 2 bytes unicode chars directly + if (code > 0xffff) { + code -= 0x10000; + var surrogate1 = 0xd800 + (code >> 10) + , surrogate2 = 0xdc00 + (code & 0x3ff); + + return String.fromCharCode(surrogate1, surrogate2); + } else { + return String.fromCharCode(code); + } + } + function entityReplacer(a){ + var k = a.slice(1,-1); + if(k in entityMap){ + return entityMap[k]; + }else if(k.charAt(0) === '#'){ + return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x'))) + }else{ + errorHandler.error('entity not found:'+a); + return a; + } + } + function appendText(end){//has some bugs + var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer); + locator&&position(start); + domBuilder.characters(xt,0,end-start); + start = end + } + function position(start,m){ + while(start>=endPos && (m = linePattern.exec(source))){ + startPos = m.index; + endPos = startPos + m[0].length; + locator.lineNumber++; + //console.log('line++:',locator,startPos,endPos) + } + locator.columnNumber = start-startPos+1; + } + var startPos = 0; + var endPos = 0; + var linePattern = /.+(?:\r\n?|\n)|.*$/g + var locator = domBuilder.locator; + + var parseStack = [{currentNSMap:defaultNSMapCopy}] + var closeMap = {}; + var start = 0; + while(true){ + var i = source.indexOf('<',start); + if(i<0){ + if(!source.substr(start).match(/^\s*$/)){ + var doc = domBuilder.document; + var text = doc.createTextNode(source.substr(start)); + doc.appendChild(text); + domBuilder.currentElement = text; + } + return; + } + if(i>start){ + appendText(i); + } + switch(source.charAt(i+1)){ + case '/': + var end = source.indexOf('>',i+3); + var tagName = source.substring(i+2,end); + var config = parseStack.pop(); + var localNSMap = config.localNSMap; + + if(config.tagName != tagName){ + errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName ); + } + domBuilder.endElement(config.uri,config.localName,tagName); + if(localNSMap){ + for(var prefix in localNSMap){ + domBuilder.endPrefixMapping(prefix) ; + } + } + end++; + break; + // end elment + case '?':// + locator&&position(i); + end = parseInstruction(source,i,domBuilder); + break; + case '!':// 0){ + value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + el.add(attrName,value,start-1); + s = S_E; + }else{ + //fatalError: no end quot match + throw new Error('attribute value no end \''+c+'\' match'); + } + }else if(s == S_V){ + value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + //console.log(attrName,value,start,p) + el.add(attrName,value,start); + //console.dir(el) + errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!'); + start = p+1; + s = S_E + }else{ + //fatalError: no equal before + throw new Error('attribute value must after "="'); + } + break; + case '/': + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p)); + case S_E: + case S_S: + case S_C: + s = S_C; + el.closed = true; + case S_V: + case S_ATTR: + case S_ATTR_S: + break; + //case S_EQ: + default: + throw new Error("attribute invalid close char('/')") + } + break; + case ''://end document + //throw new Error('unexpected end of input') + errorHandler.error('unexpected end of input'); + case '>': + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p)); + case S_E: + case S_S: + case S_C: + break;//normal + case S_V://Compatible state + case S_ATTR: + value = source.slice(start,p); + if(value.slice(-1) === '/'){ + el.closed = true; + value = value.slice(0,-1) + } + case S_ATTR_S: + if(s === S_ATTR_S){ + value = attrName; + } + if(s == S_V){ + errorHandler.warning('attribute "'+value+'" missed quot(")!!'); + el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start) + }else{ + errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!') + el.add(value,value,start) + } + break; + case S_EQ: + throw new Error('attribute value missed!!'); + } +// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName)) + return p; + /*xml space '\x20' | #x9 | #xD | #xA; */ + case '\u0080': + c = ' '; + default: + if(c<= ' '){//space + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p));//tagName + s = S_S; + break; + case S_ATTR: + attrName = source.slice(start,p) + s = S_ATTR_S; + break; + case S_V: + var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + errorHandler.warning('attribute "'+value+'" missed quot(")!!'); + el.add(attrName,value,start) + case S_E: + s = S_S; + break; + //case S_S: + //case S_EQ: + //case S_ATTR_S: + // void();break; + //case S_C: + //ignore warning + } + }else{//not space +//S_TAG, S_ATTR, S_EQ, S_V +//S_ATTR_S, S_E, S_S, S_C + switch(s){ + //case S_TAG:void();break; + //case S_ATTR:void();break; + //case S_V:void();break; + case S_ATTR_S: + errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!') + el.add(attrName,attrName,start); + start = p; + s = S_ATTR; + break; + case S_E: + errorHandler.warning('attribute space is required"'+attrName+'"!!') + case S_S: + s = S_ATTR; + start = p; + break; + case S_EQ: + s = S_V; + start = p; + break; + case S_C: + throw new Error("elements closed character '/' and '>' must be connected to"); + } + } + } + p++; + } +} +/** + * @return end of the elementStartPart(end of elementEndPart for selfClosed el) + */ +function appendElement(el,domBuilder,parseStack){ + var tagName = el.tagName; + var localNSMap = null; + var currentNSMap = parseStack[parseStack.length-1].currentNSMap; + var i = el.length; + while(i--){ + var a = el[i]; + var qName = a.qName; + var value = a.value; + var nsp = qName.indexOf(':'); + if(nsp>0){ + var prefix = a.prefix = qName.slice(0,nsp); + var localName = qName.slice(nsp+1); + var nsPrefix = prefix === 'xmlns' && localName + }else{ + localName = qName; + prefix = null + nsPrefix = qName === 'xmlns' && '' + } + //can not set prefix,because prefix !== '' + a.localName = localName ; + //prefix == null for no ns prefix attribute + if(nsPrefix !== false){//hack!! + if(localNSMap == null){ + localNSMap = {} + //console.log(currentNSMap,0) + _copy(currentNSMap,currentNSMap={}) + //console.log(currentNSMap,1) + } + currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value; + a.uri = 'http://www.w3.org/2000/xmlns/' + domBuilder.startPrefixMapping(nsPrefix, value) + } + } + var i = el.length; + while(i--){ + a = el[i]; + var prefix = a.prefix; + if(prefix){//no prefix attribute has no namespace + if(prefix === 'xml'){ + a.uri = 'http://www.w3.org/XML/1998/namespace'; + }if(prefix !== 'xmlns'){ + a.uri = currentNSMap[prefix] + + //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)} + } + } + } + var nsp = tagName.indexOf(':'); + if(nsp>0){ + prefix = el.prefix = tagName.slice(0,nsp); + localName = el.localName = tagName.slice(nsp+1); + }else{ + prefix = null;//important!! + localName = el.localName = tagName; + } + //no prefix element has default namespace + var ns = el.uri = currentNSMap[prefix || '']; + domBuilder.startElement(ns,localName,tagName,el); + //endPrefixMapping and startPrefixMapping have not any help for dom builder + //localNSMap = null + if(el.closed){ + domBuilder.endElement(ns,localName,tagName); + if(localNSMap){ + for(prefix in localNSMap){ + domBuilder.endPrefixMapping(prefix) + } + } + }else{ + el.currentNSMap = currentNSMap; + el.localNSMap = localNSMap; + parseStack.push(el); + } +} +function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){ + if(/^(?:script|textarea)$/i.test(tagName)){ + var elEndStart = source.indexOf('',elStartEnd); + var text = source.substring(elStartEnd+1,elEndStart); + if(/[&<]/.test(text)){ + if(/^script$/i.test(tagName)){ + //if(!/\]\]>/.test(text)){ + //lexHandler.startCDATA(); + domBuilder.characters(text,0,text.length); + //lexHandler.endCDATA(); + return elEndStart; + //} + }//}else{//text area + text = text.replace(/&#?\w+;/g,entityReplacer); + domBuilder.characters(text,0,text.length); + return elEndStart; + //} + + } + } + return elStartEnd+1; +} +function fixSelfClosed(source,elStartEnd,tagName,closeMap){ + //if(tagName in closeMap){ + var pos = closeMap[tagName]; + if(pos == null){ + //console.log(tagName) + pos = closeMap[tagName] = source.lastIndexOf('') + } + return pos',start+4); + //append comment source.substring(4,end)//, + * and raw CDATA nodes. + * + * @param {Element} node + * @returns {Boolean} + * @api private + */ + +function shouldIgnoreNode (node) { + return node.nodeType === 3 // text + || node.nodeType === 8 // comment + || node.nodeType === 4; // cdata +} + + +/** + * Parses a Plist XML string. Returns an Object. + * + * @param {String} xml - the XML String to decode + * @returns {Mixed} the decoded value from the Plist XML + * @api public + */ + +function parse (xml) { + var doc = new DOMParser().parseFromString(xml); + if (doc.documentElement.nodeName !== 'plist') { + throw new Error('malformed document. First element should be '); + } + var plist = parsePlistXML(doc.documentElement); + + // the root node gets interpreted as an Array, + // so pull out the inner data first + if (plist.length == 1) plist = plist[0]; + + return plist; +} + +/** + * Parses a Plist XML string. Returns an Object. Takes a `callback` function. + * + * @param {String} xml - the XML String to decode + * @param {Function} callback - callback function + * @returns {Mixed} the decoded value from the Plist XML + * @api public + * @deprecated not actually async. use parse() instead + */ + +function parseString (xml, callback) { + var doc, error, plist; + try { + doc = new DOMParser().parseFromString(xml); + plist = parsePlistXML(doc.documentElement); + } catch(e) { + error = e; + } + callback(error, plist); +} + +/** + * Parses a Plist XML string. Returns an Object. + * + * @param {String} xml - the XML String to decode + * @param {Function} callback - callback function + * @returns {Mixed} the decoded value from the Plist XML + * @api public + * @deprecated use parse() instead + */ + +function parseStringSync (xml) { + var doc = new DOMParser().parseFromString(xml); + var plist; + if (doc.documentElement.nodeName !== 'plist') { + throw new Error('malformed document. First element should be '); + } + plist = parsePlistXML(doc.documentElement); + + // if the plist is an array with 1 element, pull it out of the array + if (plist.length == 1) { + plist = plist[0]; + } + return plist; +} + +/** + * Convert an XML based plist document into a JSON representation. + * + * @param {Object} xml_node - current XML node in the plist + * @returns {Mixed} built up JSON object + * @api private + */ + +function parsePlistXML (node) { + var i, new_obj, key, val, new_arr, res, d; + + if (!node) + return null; + + if (node.nodeName === 'plist') { + new_arr = []; + for (i=0; i < node.childNodes.length; i++) { + // ignore comment nodes (text) + if (!shouldIgnoreNode(node.childNodes[i])) { + new_arr.push( parsePlistXML(node.childNodes[i])); + } + } + return new_arr; + + } else if (node.nodeName === 'dict') { + new_obj = {}; + key = null; + for (i=0; i < node.childNodes.length; i++) { + // ignore comment nodes (text) + if (!shouldIgnoreNode(node.childNodes[i])) { + if (key === null) { + key = parsePlistXML(node.childNodes[i]); + } else { + new_obj[key] = parsePlistXML(node.childNodes[i]); + key = null; + } + } + } + return new_obj; + + } else if (node.nodeName === 'array') { + new_arr = []; + for (i=0; i < node.childNodes.length; i++) { + // ignore comment nodes (text) + if (!shouldIgnoreNode(node.childNodes[i])) { + res = parsePlistXML(node.childNodes[i]); + if (null != res) new_arr.push(res); + } + } + return new_arr; + + } else if (node.nodeName === '#text') { + // TODO: what should we do with text types? (CDATA sections) + + } else if (node.nodeName === 'key') { + return node.childNodes[0].nodeValue; + + } else if (node.nodeName === 'string') { + res = ''; + for (d=0; d < node.childNodes.length; d++) { + res += node.childNodes[d].nodeValue; + } + return res; + + } else if (node.nodeName === 'integer') { + // parse as base 10 integer + return parseInt(node.childNodes[0].nodeValue, 10); + + } else if (node.nodeName === 'real') { + res = ''; + for (d=0; d < node.childNodes.length; d++) { + if (node.childNodes[d].nodeType === 3) { + res += node.childNodes[d].nodeValue; + } + } + return parseFloat(res); + + } else if (node.nodeName === 'data') { + res = ''; + for (d=0; d < node.childNodes.length; d++) { + if (node.childNodes[d].nodeType === 3) { + res += node.childNodes[d].nodeValue.replace(/\s+/g, ''); + } + } + + // decode base64 data to a Buffer instance + return new Buffer(res, 'base64'); + + } else if (node.nodeName === 'date') { + return new Date(node.childNodes[0].nodeValue); + + } else if (node.nodeName === 'true') { + return true; + + } else if (node.nodeName === 'false') { + return false; + } +} + +}).call(this,require("buffer").Buffer) +},{"buffer":7,"util-deprecate":70,"xmldom":88}],4:[function(require,module,exports){ + +var i; + +/** + * Parser functions. + */ + +var parserFunctions = require('./parse'); +for (i in parserFunctions) exports[i] = parserFunctions[i]; + +/** + * Builder functions. + */ + +var builderFunctions = require('./build'); +for (i in builderFunctions) exports[i] = builderFunctions[i]; + +/** + * Add Node.js-specific functions (they're deprecated…). + */ + +var nodeFunctions = require('./node'); +for (i in nodeFunctions) exports[i] = nodeFunctions[i]; + +},{"./build":1,"./node":2,"./parse":3}],5:[function(require,module,exports){ +var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +;(function (exports) { + 'use strict'; + + var Arr = (typeof Uint8Array !== 'undefined') + ? Uint8Array + : Array + + var PLUS = '+'.charCodeAt(0) + var SLASH = '/'.charCodeAt(0) + var NUMBER = '0'.charCodeAt(0) + var LOWER = 'a'.charCodeAt(0) + var UPPER = 'A'.charCodeAt(0) + var PLUS_URL_SAFE = '-'.charCodeAt(0) + var SLASH_URL_SAFE = '_'.charCodeAt(0) + + function decode (elt) { + var code = elt.charCodeAt(0) + if (code === PLUS || + code === PLUS_URL_SAFE) + return 62 // '+' + if (code === SLASH || + code === SLASH_URL_SAFE) + return 63 // '/' + if (code < NUMBER) + return -1 //no match + if (code < NUMBER + 10) + return code - NUMBER + 26 + 26 + if (code < UPPER + 26) + return code - UPPER + if (code < LOWER + 26) + return code - LOWER + 26 + } + + function b64ToByteArray (b64) { + var i, j, l, tmp, placeHolders, arr + + if (b64.length % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + var len = b64.length + placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(b64.length * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length + + var L = 0 + + function push (v) { + arr[L++] = v + } + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) + push((tmp & 0xFF0000) >> 16) + push((tmp & 0xFF00) >> 8) + push(tmp & 0xFF) + } + + if (placeHolders === 2) { + tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) + push(tmp & 0xFF) + } else if (placeHolders === 1) { + tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) + push((tmp >> 8) & 0xFF) + push(tmp & 0xFF) + } + + return arr + } + + function uint8ToBase64 (uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length + + function encode (num) { + return lookup.charAt(num) + } + + function tripletToBase64 (num) { + return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) + } + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output += tripletToBase64(temp) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1] + output += encode(temp >> 2) + output += encode((temp << 4) & 0x3F) + output += '==' + break + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) + output += encode(temp >> 10) + output += encode((temp >> 4) & 0x3F) + output += encode((temp << 2) & 0x3F) + output += '=' + break + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) + +},{}],6:[function(require,module,exports){ + +},{}],7:[function(require,module,exports){ +(function (global){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +/* eslint-disable no-proto */ + +var base64 = require('base64-js') +var ieee754 = require('ieee754') +var isArray = require('is-array') + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 +Buffer.poolSize = 8192 // not used by this implementation + +var rootParent = {} + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property + * on objects. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined + ? global.TYPED_ARRAY_SUPPORT + : typedArraySupport() + +function typedArraySupport () { + function Bar () {} + try { + var arr = new Uint8Array(1) + arr.foo = function () { return 42 } + arr.constructor = Bar + return arr.foo() === 42 && // typed array instances can be augmented + arr.constructor === Bar && // constructor can be set + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false + } +} + +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} + +/** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ +function Buffer (arg) { + if (!(this instanceof Buffer)) { + // Avoid going through an ArgumentsAdaptorTrampoline in the common case. + if (arguments.length > 1) return new Buffer(arg, arguments[1]) + return new Buffer(arg) + } + + this.length = 0 + this.parent = undefined + + // Common case. + if (typeof arg === 'number') { + return fromNumber(this, arg) + } + + // Slightly less common case. + if (typeof arg === 'string') { + return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') + } + + // Unusual. + return fromObject(this, arg) +} + +function fromNumber (that, length) { + that = allocate(that, length < 0 ? 0 : checked(length) | 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < length; i++) { + that[i] = 0 + } + } + return that +} + +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' + + // Assumption: byteLength() return value is always < kMaxLength. + var length = byteLength(string, encoding) | 0 + that = allocate(that, length) + + that.write(string, encoding) + return that +} + +function fromObject (that, object) { + if (Buffer.isBuffer(object)) return fromBuffer(that, object) + + if (isArray(object)) return fromArray(that, object) + + if (object == null) { + throw new TypeError('must start with number, buffer, array or string') + } + + if (typeof ArrayBuffer !== 'undefined') { + if (object.buffer instanceof ArrayBuffer) { + return fromTypedArray(that, object) + } + if (object instanceof ArrayBuffer) { + return fromArrayBuffer(that, object) + } + } + + if (object.length) return fromArrayLike(that, object) + + return fromJsonObject(that, object) +} + +function fromBuffer (that, buffer) { + var length = checked(buffer.length) | 0 + that = allocate(that, length) + buffer.copy(that, 0, 0, length) + return that +} + +function fromArray (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +// Duplicate of fromArray() to keep fromArray() monomorphic. +function fromTypedArray (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + // Truncating the elements is probably not what people expect from typed + // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior + // of the old Buffer constructor. + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +function fromArrayBuffer (that, array) { + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + array.byteLength + that = Buffer._augment(new Uint8Array(array)) + } else { + // Fallback: Return an object instance of the Buffer class + that = fromTypedArray(that, new Uint8Array(array)) + } + return that +} + +function fromArrayLike (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. +// Returns a zero-length buffer for inputs that don't conform to the spec. +function fromJsonObject (that, object) { + var array + var length = 0 + + if (object.type === 'Buffer' && isArray(object.data)) { + array = object.data + length = checked(array.length) | 0 + } + that = allocate(that, length) + + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype + Buffer.__proto__ = Uint8Array +} + +function allocate (that, length) { + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = Buffer._augment(new Uint8Array(length)) + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + that.length = length + that._isBuffer = true + } + + var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 + if (fromPool) that.parent = rootParent + + return that +} + +function checked (length) { + // Note: cannot use `length < kMaxLength` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} + +function SlowBuffer (subject, encoding) { + if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) + + var buf = new Buffer(subject, encoding) + delete buf.parent + return buf +} + +Buffer.isBuffer = function isBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length + var y = b.length + + var i = 0 + var len = Math.min(x, y) + while (i < len) { + if (a[i] !== b[i]) break + + ++i + } + + if (i !== len) { + x = a[i] + y = b[i] + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'binary': + case 'base64': + case 'raw': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') + + if (list.length === 0) { + return new Buffer(0) + } + + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; i++) { + length += list[i].length + } + } + + var buf = new Buffer(length) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf +} + +function byteLength (string, encoding) { + if (typeof string !== 'string') string = '' + string + + var len = string.length + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'binary': + // Deprecated + case 'raw': + case 'raws': + return len + case 'utf8': + case 'utf-8': + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} +Buffer.byteLength = byteLength + +// pre-set for values that may exist in the future +Buffer.prototype.length = undefined +Buffer.prototype.parent = undefined + +function slowToString (encoding, start, end) { + var loweredCase = false + + start = start | 0 + end = end === undefined || end === Infinity ? this.length : end | 0 + + if (!encoding) encoding = 'utf8' + if (start < 0) start = 0 + if (end > this.length) end = this.length + if (end <= start) return '' + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'binary': + return binarySlice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toString = function toString () { + var length = this.length | 0 + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +} + +Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +} + +Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) str += ' ... ' + } + return '' +} + +Buffer.prototype.compare = function compare (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return 0 + return Buffer.compare(this, b) +} + +Buffer.prototype.indexOf = function indexOf (val, byteOffset) { + if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff + else if (byteOffset < -0x80000000) byteOffset = -0x80000000 + byteOffset >>= 0 + + if (this.length === 0) return -1 + if (byteOffset >= this.length) return -1 + + // Negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) + + if (typeof val === 'string') { + if (val.length === 0) return -1 // special case: looking for empty string always fails + return String.prototype.indexOf.call(this, val, byteOffset) + } + if (Buffer.isBuffer(val)) { + return arrayIndexOf(this, val, byteOffset) + } + if (typeof val === 'number') { + if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { + return Uint8Array.prototype.indexOf.call(this, val, byteOffset) + } + return arrayIndexOf(this, [ val ], byteOffset) + } + + function arrayIndexOf (arr, val, byteOffset) { + var foundIndex = -1 + for (var i = 0; byteOffset + i < arr.length; i++) { + if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex + } else { + foundIndex = -1 + } + } + return -1 + } + + throw new TypeError('val must be string, number or Buffer') +} + +// `get` is deprecated +Buffer.prototype.get = function get (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) +} + +// `set` is deprecated +Buffer.prototype.set = function set (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) +} + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new Error('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(parsed)) throw new Error('Invalid hex string') + buf[offset + i] = parsed + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function binaryWrite (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0 + if (isFinite(length)) { + length = length | 0 + if (encoding === undefined) encoding = 'utf8' + } else { + encoding = length + length = undefined + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + var swap = encoding + encoding = offset + offset = length | 0 + length = swap + } + + var remaining = this.length - offset + if (length === undefined || length > remaining) length = remaining + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('attempt to write outside buffer bounds') + } + + if (!encoding) encoding = 'utf8' + + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'binary': + return binaryWrite(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end) + var res = [] + + var i = start + while (i < end) { + var firstByte = buf[i] + var codePoint = null + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1 + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte + } + break + case 2: + secondByte = buf[i + 1] + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint + } + } + break + case 3: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint + } + } + break + case 4: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + fourthByte = buf[i + 3] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD + bytesPerSequence = 1 + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000 + res.push(codePoint >>> 10 & 0x3FF | 0xD800) + codePoint = 0xDC00 | codePoint & 0x3FF + } + + res.push(codePoint) + i += bytesPerSequence + } + + return decodeCodePointsArray(res) +} + +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000 + +function decodeCodePointsArray (codePoints) { + var len = codePoints.length + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = '' + var i = 0 + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ) + } + return res +} + +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret +} + +function binarySlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i]) + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; i++) { + out += toHex(buf[i]) + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end + + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len + } + + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } + + if (end < start) end = start + + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + } + + if (newBuf.length) newBuf.parent = this.parent || this + + return newBuf +} + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + + return val +} + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) + } + + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul + } + + return val +} + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] +} + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} + +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') +} + +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = (value & 0xff) + return offset + 1 +} + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = 0 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = byteLength - 1 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = (value & 0xff) + return offset + 1 +} + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') + if (offset < 0) throw new RangeError('index out of range') +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start + } + + var len = end - start + var i + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; i--) { + target[i + targetStart] = this[i + start] + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; i++) { + target[i + targetStart] = this[i + start] + } + } else { + target._set(this.subarray(start, start + len), targetStart) + } + + return len +} + +// fill(value, start=0, end=buffer.length) +Buffer.prototype.fill = function fill (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length + + if (end < start) throw new RangeError('end < start') + + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') + if (end < 0 || end > this.length) throw new RangeError('end out of bounds') + + var i + if (typeof value === 'number') { + for (i = start; i < end; i++) { + this[i] = value + } + } else { + var bytes = utf8ToBytes(value.toString()) + var len = bytes.length + for (i = start; i < end; i++) { + this[i] = bytes[i % len] + } + } + + return this +} + +/** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ +Buffer.prototype.toArrayBuffer = function toArrayBuffer () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer.TYPED_ARRAY_SUPPORT) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) { + buf[i] = this[i] + } + return buf.buffer + } + } else { + throw new TypeError('Buffer.toArrayBuffer not supported in this browser') + } +} + +// HELPER FUNCTIONS +// ================ + +var BP = Buffer.prototype + +/** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ +Buffer._augment = function _augment (arr) { + arr.constructor = Buffer + arr._isBuffer = true + + // save reference to original Uint8Array set method before overwriting + arr._set = arr.set + + // deprecated + arr.get = BP.get + arr.set = BP.set + + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.equals = BP.equals + arr.compare = BP.compare + arr.indexOf = BP.indexOf + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUIntLE = BP.readUIntLE + arr.readUIntBE = BP.readUIntBE + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readIntLE = BP.readIntLE + arr.readIntBE = BP.readIntBE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUIntLE = BP.writeUIntLE + arr.writeUIntBE = BP.writeUIntBE + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeIntLE = BP.writeIntLE + arr.writeIntBE = BP.writeIntBE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer + + return arr +} + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + + for (var i = 0; i < length; i++) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } + + // valid lead + leadSurrogate = codePoint + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } + + // valid surrogate pair + codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + } + + leadSurrogate = null + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] + } + return i +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"base64-js":5,"ieee754":8,"is-array":9}],8:[function(require,module,exports){ +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } + + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 +} + +},{}],9:[function(require,module,exports){ + +/** + * isArray + */ + +var isArray = Array.isArray; + +/** + * toString + */ + +var str = Object.prototype.toString; + +/** + * Whether or not the given `val` + * is an array. + * + * example: + * + * isArray([]); + * // > true + * isArray(arguments); + * // > false + * isArray(''); + * // > false + * + * @param {mixed} val + * @return {bool} + */ + +module.exports = isArray || function (val) { + return !! val && '[object Array]' == str.call(val); +}; + +},{}],10:[function(require,module,exports){ +/** + * Determine if an object is Buffer + * + * Author: Feross Aboukhadijeh + * License: MIT + * + * `npm install is-buffer` + */ + +module.exports = function (obj) { + return !!(obj != null && + (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) + (obj.constructor && + typeof obj.constructor.isBuffer === 'function' && + obj.constructor.isBuffer(obj)) + )) +} + +},{}],11:[function(require,module,exports){ +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; +} + +module.exports = last; + +},{}],12:[function(require,module,exports){ +var arrayEvery = require('../internal/arrayEvery'), + baseCallback = require('../internal/baseCallback'), + baseEvery = require('../internal/baseEvery'), + isArray = require('../lang/isArray'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.every(users, 'active'); + * // => false + */ +function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = baseCallback(predicate, thisArg, 3); + } + return func(collection, predicate); +} + +module.exports = every; + +},{"../internal/arrayEvery":14,"../internal/baseCallback":18,"../internal/baseEvery":22,"../internal/isIterateeCall":47,"../lang/isArray":56}],13:[function(require,module,exports){ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ +function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); + + while (++index < length) { + rest[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; +} + +module.exports = restParam; + +},{}],14:[function(require,module,exports){ +/** + * A specialized version of `_.every` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ +function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; +} + +module.exports = arrayEvery; + +},{}],15:[function(require,module,exports){ +/** + * A specialized version of `_.some` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +module.exports = arraySome; + +},{}],16:[function(require,module,exports){ +var keys = require('../object/keys'); + +/** + * A specialized version of `_.assign` for customizing assigned values without + * support for argument juggling, multiple sources, and `this` binding `customizer` + * functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + */ +function assignWith(object, source, customizer) { + var index = -1, + props = keys(source), + length = props.length; + + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); + + if ((result === result ? (result !== value) : (value === value)) || + (value === undefined && !(key in object))) { + object[key] = result; + } + } + return object; +} + +module.exports = assignWith; + +},{"../object/keys":65}],17:[function(require,module,exports){ +var baseCopy = require('./baseCopy'), + keys = require('../object/keys'); + +/** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return source == null + ? object + : baseCopy(source, keys(source), object); +} + +module.exports = baseAssign; + +},{"../object/keys":65,"./baseCopy":19}],18:[function(require,module,exports){ +var baseMatches = require('./baseMatches'), + baseMatchesProperty = require('./baseMatchesProperty'), + bindCallback = require('./bindCallback'), + identity = require('../utility/identity'), + property = require('../utility/property'); + +/** + * The base implementation of `_.callback` which supports specifying the + * number of arguments to provide to `func`. + * + * @private + * @param {*} [func=_.identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ +function baseCallback(func, thisArg, argCount) { + var type = typeof func; + if (type == 'function') { + return thisArg === undefined + ? func + : bindCallback(func, thisArg, argCount); + } + if (func == null) { + return identity; + } + if (type == 'object') { + return baseMatches(func); + } + return thisArg === undefined + ? property(func) + : baseMatchesProperty(func, thisArg); +} + +module.exports = baseCallback; + +},{"../utility/identity":68,"../utility/property":69,"./baseMatches":29,"./baseMatchesProperty":30,"./bindCallback":35}],19:[function(require,module,exports){ +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ +function baseCopy(source, props, object) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; +} + +module.exports = baseCopy; + +},{}],20:[function(require,module,exports){ +var isObject = require('../lang/isObject'); + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ +var baseCreate = (function() { + function object() {} + return function(prototype) { + if (isObject(prototype)) { + object.prototype = prototype; + var result = new object; + object.prototype = undefined; + } + return result || {}; + }; +}()); + +module.exports = baseCreate; + +},{"../lang/isObject":60}],21:[function(require,module,exports){ +var baseForOwn = require('./baseForOwn'), + createBaseEach = require('./createBaseEach'); + +/** + * The base implementation of `_.forEach` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ +var baseEach = createBaseEach(baseForOwn); + +module.exports = baseEach; + +},{"./baseForOwn":24,"./createBaseEach":37}],22:[function(require,module,exports){ +var baseEach = require('./baseEach'); + +/** + * The base implementation of `_.every` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ +function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; +} + +module.exports = baseEvery; + +},{"./baseEach":21}],23:[function(require,module,exports){ +var createBaseFor = require('./createBaseFor'); + +/** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ +var baseFor = createBaseFor(); + +module.exports = baseFor; + +},{"./createBaseFor":38}],24:[function(require,module,exports){ +var baseFor = require('./baseFor'), + keys = require('../object/keys'); + +/** + * The base implementation of `_.forOwn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return baseFor(object, iteratee, keys); +} + +module.exports = baseForOwn; + +},{"../object/keys":65,"./baseFor":23}],25:[function(require,module,exports){ +var toObject = require('./toObject'); + +/** + * The base implementation of `get` without support for string paths + * and default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path of the property to get. + * @param {string} [pathKey] The key representation of path. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path, pathKey) { + if (object == null) { + return; + } + if (pathKey !== undefined && pathKey in toObject(object)) { + path = [pathKey]; + } + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[path[index++]]; + } + return (index && index == length) ? object : undefined; +} + +module.exports = baseGet; + +},{"./toObject":53}],26:[function(require,module,exports){ +var baseIsEqualDeep = require('./baseIsEqualDeep'), + isObject = require('../lang/isObject'), + isObjectLike = require('./isObjectLike'); + +/** + * The base implementation of `_.isEqual` without support for `this` binding + * `customizer` functions. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); +} + +module.exports = baseIsEqual; + +},{"../lang/isObject":60,"./baseIsEqualDeep":27,"./isObjectLike":50}],27:[function(require,module,exports){ +var equalArrays = require('./equalArrays'), + equalByTag = require('./equalByTag'), + equalObjects = require('./equalObjects'), + isArray = require('../lang/isArray'), + isTypedArray = require('../lang/isTypedArray'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing objects. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `value` objects. + * @param {Array} [stackB=[]] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objToString.call(object); + if (objTag == argsTag) { + objTag = objectTag; + } else if (objTag != objectTag) { + objIsArr = isTypedArray(object); + } + } + if (!othIsArr) { + othTag = objToString.call(other); + if (othTag == argsTag) { + othTag = objectTag; + } else if (othTag != objectTag) { + othIsArr = isTypedArray(other); + } + } + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && !(objIsArr || objIsObj)) { + return equalByTag(object, other, objTag); + } + if (!isLoose) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); + } + } + if (!isSameTag) { + return false; + } + // Assume cyclic values are equal. + // For more information on detecting circular references see https://es5.github.io/#JO. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == object) { + return stackB[length] == other; + } + } + // Add `object` and `other` to the stack of traversed objects. + stackA.push(object); + stackB.push(other); + + var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); + + stackA.pop(); + stackB.pop(); + + return result; +} + +module.exports = baseIsEqualDeep; + +},{"../lang/isArray":56,"../lang/isTypedArray":62,"./equalArrays":39,"./equalByTag":40,"./equalObjects":41}],28:[function(require,module,exports){ +var baseIsEqual = require('./baseIsEqual'), + toObject = require('./toObject'); + +/** + * The base implementation of `_.isMatch` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} matchData The propery names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparing objects. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = toObject(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { + return false; + } + } + } + return true; +} + +module.exports = baseIsMatch; + +},{"./baseIsEqual":26,"./toObject":53}],29:[function(require,module,exports){ +var baseIsMatch = require('./baseIsMatch'), + getMatchData = require('./getMatchData'), + toObject = require('./toObject'); + +/** + * The base implementation of `_.matches` which does not clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ +function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; + + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && (value !== undefined || (key in toObject(object))); + }; + } + return function(object) { + return baseIsMatch(object, matchData); + }; +} + +module.exports = baseMatches; + +},{"./baseIsMatch":28,"./getMatchData":43,"./toObject":53}],30:[function(require,module,exports){ +var baseGet = require('./baseGet'), + baseIsEqual = require('./baseIsEqual'), + baseSlice = require('./baseSlice'), + isArray = require('../lang/isArray'), + isKey = require('./isKey'), + isStrictComparable = require('./isStrictComparable'), + last = require('../array/last'), + toObject = require('./toObject'), + toPath = require('./toPath'); + +/** + * The base implementation of `_.matchesProperty` which does not clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to compare. + * @returns {Function} Returns the new function. + */ +function baseMatchesProperty(path, srcValue) { + var isArr = isArray(path), + isCommon = isKey(path) && isStrictComparable(srcValue), + pathKey = (path + ''); + + path = toPath(path); + return function(object) { + if (object == null) { + return false; + } + var key = pathKey; + object = toObject(object); + if ((isArr || !isCommon) && !(key in object)) { + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + key = last(path); + object = toObject(object); + } + return object[key] === srcValue + ? (srcValue !== undefined || (key in object)) + : baseIsEqual(srcValue, object[key], undefined, true); + }; +} + +module.exports = baseMatchesProperty; + +},{"../array/last":11,"../lang/isArray":56,"./baseGet":25,"./baseIsEqual":26,"./baseSlice":33,"./isKey":48,"./isStrictComparable":51,"./toObject":53,"./toPath":54}],31:[function(require,module,exports){ +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +module.exports = baseProperty; + +},{}],32:[function(require,module,exports){ +var baseGet = require('./baseGet'), + toPath = require('./toPath'); + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ +function basePropertyDeep(path) { + var pathKey = (path + ''); + path = toPath(path); + return function(object) { + return baseGet(object, path, pathKey); + }; +} + +module.exports = basePropertyDeep; + +},{"./baseGet":25,"./toPath":54}],33:[function(require,module,exports){ +/** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; +} + +module.exports = baseSlice; + +},{}],34:[function(require,module,exports){ +/** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` or `undefined` values. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + return value == null ? '' : (value + ''); +} + +module.exports = baseToString; + +},{}],35:[function(require,module,exports){ +var identity = require('../utility/identity'); + +/** + * A specialized version of `baseCallback` which only supports `this` binding + * and specifying the number of arguments to provide to `func`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ +function bindCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + if (thisArg === undefined) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; +} + +module.exports = bindCallback; + +},{"../utility/identity":68}],36:[function(require,module,exports){ +var bindCallback = require('./bindCallback'), + isIterateeCall = require('./isIterateeCall'), + restParam = require('../function/restParam'); + +/** + * Creates a `_.assign`, `_.defaults`, or `_.merge` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return restParam(function(object, sources) { + var index = -1, + length = object == null ? 0 : sources.length, + customizer = length > 2 ? sources[length - 2] : undefined, + guard = length > 2 ? sources[2] : undefined, + thisArg = length > 1 ? sources[length - 1] : undefined; + + if (typeof customizer == 'function') { + customizer = bindCallback(customizer, thisArg, 5); + length -= 2; + } else { + customizer = typeof thisArg == 'function' ? thisArg : undefined; + length -= (customizer ? 1 : 0); + } + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }); +} + +module.exports = createAssigner; + +},{"../function/restParam":13,"./bindCallback":35,"./isIterateeCall":47}],37:[function(require,module,exports){ +var getLength = require('./getLength'), + isLength = require('./isLength'), + toObject = require('./toObject'); + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + return eachFunc(collection, iteratee); + } + var index = fromRight ? length : -1, + iterable = toObject(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +module.exports = createBaseEach; + +},{"./getLength":42,"./isLength":49,"./toObject":53}],38:[function(require,module,exports){ +var toObject = require('./toObject'); + +/** + * Creates a base function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var iterable = toObject(object), + props = keysFunc(object), + length = props.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; +} + +module.exports = createBaseFor; + +},{"./toObject":53}],39:[function(require,module,exports){ +var arraySome = require('./arraySome'); + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing arrays. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isLoose && othLength > arrLength)) { + return false; + } + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index], + result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; + + if (result !== undefined) { + if (result) { + continue; + } + return false; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isLoose) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + })) { + return false; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { + return false; + } + } + return true; +} + +module.exports = equalArrays; + +},{"./arraySome":15}],40:[function(require,module,exports){ +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + stringTag = '[object String]'; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag) { + switch (tag) { + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + } + return false; +} + +module.exports = equalByTag; + +},{}],41:[function(require,module,exports){ +var keys = require('../object/keys'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isLoose) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + var skipCtor = isLoose; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key], + result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; + + // Recursively compare objects (susceptible to call stack limits). + if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { + return false; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (!skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + return false; + } + } + return true; +} + +module.exports = equalObjects; + +},{"../object/keys":65}],42:[function(require,module,exports){ +var baseProperty = require('./baseProperty'); + +/** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ +var getLength = baseProperty('length'); + +module.exports = getLength; + +},{"./baseProperty":31}],43:[function(require,module,exports){ +var isStrictComparable = require('./isStrictComparable'), + pairs = require('../object/pairs'); + +/** + * Gets the propery names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = pairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; +} + +module.exports = getMatchData; + +},{"../object/pairs":67,"./isStrictComparable":51}],44:[function(require,module,exports){ +var isNative = require('../lang/isNative'); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; +} + +module.exports = getNative; + +},{"../lang/isNative":59}],45:[function(require,module,exports){ +var getLength = require('./getLength'), + isLength = require('./isLength'); + +/** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ +function isArrayLike(value) { + return value != null && isLength(getLength(value)); +} + +module.exports = isArrayLike; + +},{"./getLength":42,"./isLength":49}],46:[function(require,module,exports){ +/** Used to detect unsigned integer values. */ +var reIsUint = /^\d+$/; + +/** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; +} + +module.exports = isIndex; + +},{}],47:[function(require,module,exports){ +var isArrayLike = require('./isArrayLike'), + isIndex = require('./isIndex'), + isObject = require('../lang/isObject'); + +/** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; +} + +module.exports = isIterateeCall; + +},{"../lang/isObject":60,"./isArrayLike":45,"./isIndex":46}],48:[function(require,module,exports){ +var isArray = require('../lang/isArray'), + toObject = require('./toObject'); + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + var type = typeof value; + if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { + return true; + } + if (isArray(value)) { + return false; + } + var result = !reIsDeepProp.test(value); + return result || (object != null && value in toObject(object)); +} + +module.exports = isKey; + +},{"../lang/isArray":56,"./toObject":53}],49:[function(require,module,exports){ +/** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +module.exports = isLength; + +},{}],50:[function(require,module,exports){ +/** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +module.exports = isObjectLike; + +},{}],51:[function(require,module,exports){ +var isObject = require('../lang/isObject'); + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !isObject(value); +} + +module.exports = isStrictComparable; + +},{"../lang/isObject":60}],52:[function(require,module,exports){ +var isArguments = require('../lang/isArguments'), + isArray = require('../lang/isArray'), + isIndex = require('./isIndex'), + isLength = require('./isLength'), + keysIn = require('../object/keysIn'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; + + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; +} + +module.exports = shimKeys; + +},{"../lang/isArguments":55,"../lang/isArray":56,"../object/keysIn":66,"./isIndex":46,"./isLength":49}],53:[function(require,module,exports){ +var isObject = require('../lang/isObject'); + +/** + * Converts `value` to an object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Object} Returns the object. + */ +function toObject(value) { + return isObject(value) ? value : Object(value); +} + +module.exports = toObject; + +},{"../lang/isObject":60}],54:[function(require,module,exports){ +var baseToString = require('./baseToString'), + isArray = require('../lang/isArray'); + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `value` to property path array if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array} Returns the property path array. + */ +function toPath(value) { + if (isArray(value)) { + return value; + } + var result = []; + baseToString(value).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +} + +module.exports = toPath; + +},{"../lang/isArray":56,"./baseToString":34}],55:[function(require,module,exports){ +var isArrayLike = require('../internal/isArrayLike'), + isObjectLike = require('../internal/isObjectLike'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Native method references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** + * Checks if `value` is classified as an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + return isObjectLike(value) && isArrayLike(value) && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); +} + +module.exports = isArguments; + +},{"../internal/isArrayLike":45,"../internal/isObjectLike":50}],56:[function(require,module,exports){ +var getNative = require('../internal/getNative'), + isLength = require('../internal/isLength'), + isObjectLike = require('../internal/isObjectLike'); + +/** `Object#toString` result references. */ +var arrayTag = '[object Array]'; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeIsArray = getNative(Array, 'isArray'); + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(function() { return arguments; }()); + * // => false + */ +var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; +}; + +module.exports = isArray; + +},{"../internal/getNative":44,"../internal/isLength":49,"../internal/isObjectLike":50}],57:[function(require,module,exports){ +var isArguments = require('./isArguments'), + isArray = require('./isArray'), + isArrayLike = require('../internal/isArrayLike'), + isFunction = require('./isFunction'), + isObjectLike = require('../internal/isObjectLike'), + isString = require('./isString'), + keys = require('../object/keys'); + +/** + * Checks if `value` is empty. A value is considered empty unless it's an + * `arguments` object, array, string, or jQuery-like collection with a length + * greater than `0` or an object with own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ +function isEmpty(value) { + if (value == null) { + return true; + } + if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || + (isObjectLike(value) && isFunction(value.splice)))) { + return !value.length; + } + return !keys(value).length; +} + +module.exports = isEmpty; + +},{"../internal/isArrayLike":45,"../internal/isObjectLike":50,"../object/keys":65,"./isArguments":55,"./isArray":56,"./isFunction":58,"./isString":61}],58:[function(require,module,exports){ +var isObject = require('./isObject'); + +/** `Object#toString` result references. */ +var funcTag = '[object Function]'; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 which returns 'object' for typed array constructors. + return isObject(value) && objToString.call(value) == funcTag; +} + +module.exports = isFunction; + +},{"./isObject":60}],59:[function(require,module,exports){ +var isFunction = require('./isFunction'), + isObjectLike = require('../internal/isObjectLike'); + +/** Used to detect host constructors (Safari > 5). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var fnToString = Function.prototype.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ +function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); +} + +module.exports = isNative; + +},{"../internal/isObjectLike":50,"./isFunction":58}],60:[function(require,module,exports){ +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +module.exports = isObject; + +},{}],61:[function(require,module,exports){ +var isObjectLike = require('../internal/isObjectLike'); + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); +} + +module.exports = isString; + +},{"../internal/isObjectLike":50}],62:[function(require,module,exports){ +var isLength = require('../internal/isLength'), + isObjectLike = require('../internal/isObjectLike'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dateTag] = typedArrayTags[errorTag] = +typedArrayTags[funcTag] = typedArrayTags[mapTag] = +typedArrayTags[numberTag] = typedArrayTags[objectTag] = +typedArrayTags[regexpTag] = typedArrayTags[setTag] = +typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ +function isTypedArray(value) { + return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; +} + +module.exports = isTypedArray; + +},{"../internal/isLength":49,"../internal/isObjectLike":50}],63:[function(require,module,exports){ +var assignWith = require('../internal/assignWith'), + baseAssign = require('../internal/baseAssign'), + createAssigner = require('../internal/createAssigner'); + +/** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it's invoked to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments: + * (objectValue, sourceValue, key, object, source). + * + * **Note:** This method mutates `object` and is based on + * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } + * + * // using a customizer callback + * var defaults = _.partialRight(_.assign, function(value, other) { + * return _.isUndefined(value) ? other : value; + * }); + * + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ +var assign = createAssigner(function(object, source, customizer) { + return customizer + ? assignWith(object, source, customizer) + : baseAssign(object, source); +}); + +module.exports = assign; + +},{"../internal/assignWith":16,"../internal/baseAssign":17,"../internal/createAssigner":36}],64:[function(require,module,exports){ +var baseAssign = require('../internal/baseAssign'), + baseCreate = require('../internal/baseCreate'), + isIterateeCall = require('../internal/isIterateeCall'); + +/** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ +function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = undefined; + } + return properties ? baseAssign(result, properties) : result; +} + +module.exports = create; + +},{"../internal/baseAssign":17,"../internal/baseCreate":20,"../internal/isIterateeCall":47}],65:[function(require,module,exports){ +var getNative = require('../internal/getNative'), + isArrayLike = require('../internal/isArrayLike'), + isObject = require('../lang/isObject'), + shimKeys = require('../internal/shimKeys'); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeKeys = getNative(Object, 'keys'); + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object == null ? undefined : object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; +}; + +module.exports = keys; + +},{"../internal/getNative":44,"../internal/isArrayLike":45,"../internal/shimKeys":52,"../lang/isObject":60}],66:[function(require,module,exports){ +var isArguments = require('../lang/isArguments'), + isArray = require('../lang/isArray'), + isIndex = require('../internal/isIndex'), + isLength = require('../internal/isLength'), + isObject = require('../lang/isObject'); + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || isArguments(object)) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} + +module.exports = keysIn; + +},{"../internal/isIndex":46,"../internal/isLength":49,"../lang/isArguments":55,"../lang/isArray":56,"../lang/isObject":60}],67:[function(require,module,exports){ +var keys = require('./keys'), + toObject = require('../internal/toObject'); + +/** + * Creates a two dimensional array of the key-value pairs for `object`, + * e.g. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) + */ +function pairs(object) { + object = toObject(object); + + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; +} + +module.exports = pairs; + +},{"../internal/toObject":53,"./keys":65}],68:[function(require,module,exports){ +/** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utility + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'user': 'fred' }; + * + * _.identity(object) === object; + * // => true + */ +function identity(value) { + return value; +} + +module.exports = identity; + +},{}],69:[function(require,module,exports){ +var baseProperty = require('../internal/baseProperty'), + basePropertyDeep = require('../internal/basePropertyDeep'), + isKey = require('../internal/isKey'); + +/** + * Creates a function that returns the property value at `path` on a + * given object. + * + * @static + * @memberOf _ + * @category Utility + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + * @example + * + * var objects = [ + * { 'a': { 'b': { 'c': 2 } } }, + * { 'a': { 'b': { 'c': 1 } } } + * ]; + * + * _.map(objects, _.property('a.b.c')); + * // => [2, 1] + * + * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); + * // => [1, 2] + */ +function property(path) { + return isKey(path) ? baseProperty(path) : basePropertyDeep(path); +} + +module.exports = property; + +},{"../internal/baseProperty":31,"../internal/basePropertyDeep":32,"../internal/isKey":48}],70:[function(require,module,exports){ +(function (global){ + +/** + * Module exports. + */ + +module.exports = deprecate; + +/** + * Mark that a method should not be used. + * Returns a modified function which warns once by default. + * + * If `localStorage.noDeprecation = true` is set, then it is a no-op. + * + * If `localStorage.throwDeprecation = true` is set, then deprecated functions + * will throw an Error when invoked. + * + * If `localStorage.traceDeprecation = true` is set, then deprecated functions + * will invoke `console.trace()` instead of `console.error()`. + * + * @param {Function} fn - the function to deprecate + * @param {String} msg - the string to print to the console when `fn` is invoked + * @returns {Function} a new "deprecated" version of `fn` + * @api public + */ + +function deprecate (fn, msg) { + if (config('noDeprecation')) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (config('throwDeprecation')) { + throw new Error(msg); + } else if (config('traceDeprecation')) { + console.trace(msg); + } else { + console.warn(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +} + +/** + * Checks `localStorage` for boolean values for the given `name`. + * + * @param {String} name + * @returns {Boolean} + * @api private + */ + +function config (name) { + // accessing global.localStorage can trigger a DOMException in sandboxed iframes + try { + if (!global.localStorage) return false; + } catch (_) { + return false; + } + var val = global.localStorage[name]; + if (null == val) return false; + return String(val).toLowerCase() === 'true'; +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],71:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLAttribute, create; + + create = require('lodash/object/create'); + + module.exports = XMLAttribute = (function() { + function XMLAttribute(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing attribute name of element " + parent.name); + } + if (value == null) { + throw new Error("Missing attribute value for attribute " + name + " of element " + parent.name); + } + this.name = this.stringify.attName(name); + this.value = this.stringify.attValue(value); + } + + XMLAttribute.prototype.clone = function() { + return create(XMLAttribute.prototype, this); + }; + + XMLAttribute.prototype.toString = function(options, level) { + return ' ' + this.name + '="' + this.value + '"'; + }; + + return XMLAttribute; + + })(); + +}).call(this); + +},{"lodash/object/create":64}],72:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLBuilder, XMLDeclaration, XMLDocType, XMLElement, XMLStringifier; + + XMLStringifier = require('./XMLStringifier'); + + XMLDeclaration = require('./XMLDeclaration'); + + XMLDocType = require('./XMLDocType'); + + XMLElement = require('./XMLElement'); + + module.exports = XMLBuilder = (function() { + function XMLBuilder(name, options) { + var root, temp; + if (name == null) { + throw new Error("Root element needs a name"); + } + if (options == null) { + options = {}; + } + this.options = options; + this.stringify = new XMLStringifier(options); + temp = new XMLElement(this, 'doc'); + root = temp.element(name); + root.isRoot = true; + root.documentObject = this; + this.rootObject = root; + if (!options.headless) { + root.declaration(options); + if ((options.pubID != null) || (options.sysID != null)) { + root.doctype(options); + } + } + } + + XMLBuilder.prototype.root = function() { + return this.rootObject; + }; + + XMLBuilder.prototype.end = function(options) { + return this.toString(options); + }; + + XMLBuilder.prototype.toString = function(options) { + var indent, newline, offset, pretty, r, ref, ref1, ref2; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + r = ''; + if (this.xmldec != null) { + r += this.xmldec.toString(options); + } + if (this.doctype != null) { + r += this.doctype.toString(options); + } + r += this.rootObject.toString(options); + if (pretty && r.slice(-newline.length) === newline) { + r = r.slice(0, -newline.length); + } + return r; + }; + + return XMLBuilder; + + })(); + +}).call(this); + +},{"./XMLDeclaration":79,"./XMLDocType":80,"./XMLElement":81,"./XMLStringifier":85}],73:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLNode, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLCData = (function(superClass) { + extend(XMLCData, superClass); + + function XMLCData(parent, text) { + XMLCData.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing CDATA text"); + } + this.text = this.stringify.cdata(text); + } + + XMLCData.prototype.clone = function() { + return create(XMLCData.prototype, this); + }; + + XMLCData.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLCData; + + })(XMLNode); + +}).call(this); + +},{"./XMLNode":82,"lodash/object/create":64}],74:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLComment, XMLNode, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLComment = (function(superClass) { + extend(XMLComment, superClass); + + function XMLComment(parent, text) { + XMLComment.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing comment text"); + } + this.text = this.stringify.comment(text); + } + + XMLComment.prototype.clone = function() { + return create(XMLComment.prototype, this); + }; + + XMLComment.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLComment; + + })(XMLNode); + +}).call(this); + +},{"./XMLNode":82,"lodash/object/create":64}],75:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDAttList, create; + + create = require('lodash/object/create'); + + module.exports = XMLDTDAttList = (function() { + function XMLDTDAttList(parent, elementName, attributeName, attributeType, defaultValueType, defaultValue) { + this.stringify = parent.stringify; + if (elementName == null) { + throw new Error("Missing DTD element name"); + } + if (attributeName == null) { + throw new Error("Missing DTD attribute name"); + } + if (!attributeType) { + throw new Error("Missing DTD attribute type"); + } + if (!defaultValueType) { + throw new Error("Missing DTD attribute default"); + } + if (defaultValueType.indexOf('#') !== 0) { + defaultValueType = '#' + defaultValueType; + } + if (!defaultValueType.match(/^(#REQUIRED|#IMPLIED|#FIXED|#DEFAULT)$/)) { + throw new Error("Invalid default value type; expected: #REQUIRED, #IMPLIED, #FIXED or #DEFAULT"); + } + if (defaultValue && !defaultValueType.match(/^(#FIXED|#DEFAULT)$/)) { + throw new Error("Default value only applies to #FIXED or #DEFAULT"); + } + this.elementName = this.stringify.eleName(elementName); + this.attributeName = this.stringify.attName(attributeName); + this.attributeType = this.stringify.dtdAttType(attributeType); + this.defaultValue = this.stringify.dtdAttDefault(defaultValue); + this.defaultValueType = defaultValueType; + } + + XMLDTDAttList.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDAttList; + + })(); + +}).call(this); + +},{"lodash/object/create":64}],76:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDElement, create; + + create = require('lodash/object/create'); + + module.exports = XMLDTDElement = (function() { + function XMLDTDElement(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing DTD element name"); + } + if (!value) { + value = '(#PCDATA)'; + } + if (Array.isArray(value)) { + value = '(' + value.join(',') + ')'; + } + this.name = this.stringify.eleName(name); + this.value = this.stringify.dtdElementValue(value); + } + + XMLDTDElement.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDElement; + + })(); + +}).call(this); + +},{"lodash/object/create":64}],77:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDEntity, create, isObject; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + module.exports = XMLDTDEntity = (function() { + function XMLDTDEntity(parent, pe, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing entity name"); + } + if (value == null) { + throw new Error("Missing entity value"); + } + this.pe = !!pe; + this.name = this.stringify.eleName(name); + if (!isObject(value)) { + this.value = this.stringify.dtdEntityValue(value); + } else { + if (!value.pubID && !value.sysID) { + throw new Error("Public and/or system identifiers are required for an external entity"); + } + if (value.pubID && !value.sysID) { + throw new Error("System identifier is required for a public external entity"); + } + if (value.pubID != null) { + this.pubID = this.stringify.dtdPubID(value.pubID); + } + if (value.sysID != null) { + this.sysID = this.stringify.dtdSysID(value.sysID); + } + if (value.nData != null) { + this.nData = this.stringify.dtdNData(value.nData); + } + if (this.pe && this.nData) { + throw new Error("Notation declaration is not allowed in a parameter entity"); + } + } + } + + XMLDTDEntity.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDEntity; + + })(); + +}).call(this); + +},{"lodash/lang/isObject":60,"lodash/object/create":64}],78:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDNotation, create; + + create = require('lodash/object/create'); + + module.exports = XMLDTDNotation = (function() { + function XMLDTDNotation(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing notation name"); + } + if (!value.pubID && !value.sysID) { + throw new Error("Public or system identifiers are required for an external entity"); + } + this.name = this.stringify.eleName(name); + if (value.pubID != null) { + this.pubID = this.stringify.dtdPubID(value.pubID); + } + if (value.sysID != null) { + this.sysID = this.stringify.dtdSysID(value.sysID); + } + } + + XMLDTDNotation.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDNotation; + + })(); + +}).call(this); + +},{"lodash/object/create":64}],79:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDeclaration, XMLNode, create, isObject, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLDeclaration = (function(superClass) { + extend(XMLDeclaration, superClass); + + function XMLDeclaration(parent, version, encoding, standalone) { + var ref; + XMLDeclaration.__super__.constructor.call(this, parent); + if (isObject(version)) { + ref = version, version = ref.version, encoding = ref.encoding, standalone = ref.standalone; + } + if (!version) { + version = '1.0'; + } + this.version = this.stringify.xmlVersion(version); + if (encoding != null) { + this.encoding = this.stringify.xmlEncoding(encoding); + } + if (standalone != null) { + this.standalone = this.stringify.xmlStandalone(standalone); + } + } + + XMLDeclaration.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDeclaration; + + })(XMLNode); + +}).call(this); + +},{"./XMLNode":82,"lodash/lang/isObject":60,"lodash/object/create":64}],80:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLComment, XMLDTDAttList, XMLDTDElement, XMLDTDEntity, XMLDTDNotation, XMLDocType, XMLProcessingInstruction, create, isObject; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + XMLCData = require('./XMLCData'); + + XMLComment = require('./XMLComment'); + + XMLDTDAttList = require('./XMLDTDAttList'); + + XMLDTDEntity = require('./XMLDTDEntity'); + + XMLDTDElement = require('./XMLDTDElement'); + + XMLDTDNotation = require('./XMLDTDNotation'); + + XMLProcessingInstruction = require('./XMLProcessingInstruction'); + + module.exports = XMLDocType = (function() { + function XMLDocType(parent, pubID, sysID) { + var ref, ref1; + this.documentObject = parent; + this.stringify = this.documentObject.stringify; + this.children = []; + if (isObject(pubID)) { + ref = pubID, pubID = ref.pubID, sysID = ref.sysID; + } + if (sysID == null) { + ref1 = [pubID, sysID], sysID = ref1[0], pubID = ref1[1]; + } + if (pubID != null) { + this.pubID = this.stringify.dtdPubID(pubID); + } + if (sysID != null) { + this.sysID = this.stringify.dtdSysID(sysID); + } + } + + XMLDocType.prototype.element = function(name, value) { + var child; + child = new XMLDTDElement(this, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.attList = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) { + var child; + child = new XMLDTDAttList(this, elementName, attributeName, attributeType, defaultValueType, defaultValue); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.entity = function(name, value) { + var child; + child = new XMLDTDEntity(this, false, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.pEntity = function(name, value) { + var child; + child = new XMLDTDEntity(this, true, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.notation = function(name, value) { + var child; + child = new XMLDTDNotation(this, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.cdata = function(value) { + var child; + child = new XMLCData(this, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.comment = function(value) { + var child; + child = new XMLComment(this, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.instruction = function(target, value) { + var child; + child = new XMLProcessingInstruction(this, target, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.root = function() { + return this.documentObject.root(); + }; + + XMLDocType.prototype.document = function() { + return this.documentObject; + }; + + XMLDocType.prototype.toString = function(options, level) { + var child, i, indent, len, newline, offset, pretty, r, ref, ref1, ref2, ref3, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ' 0) { + r += ' ['; + if (pretty) { + r += newline; + } + ref3 = this.children; + for (i = 0, len = ref3.length; i < len; i++) { + child = ref3[i]; + r += child.toString(options, level + 1); + } + r += ']'; + } + r += '>'; + if (pretty) { + r += newline; + } + return r; + }; + + XMLDocType.prototype.ele = function(name, value) { + return this.element(name, value); + }; + + XMLDocType.prototype.att = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) { + return this.attList(elementName, attributeName, attributeType, defaultValueType, defaultValue); + }; + + XMLDocType.prototype.ent = function(name, value) { + return this.entity(name, value); + }; + + XMLDocType.prototype.pent = function(name, value) { + return this.pEntity(name, value); + }; + + XMLDocType.prototype.not = function(name, value) { + return this.notation(name, value); + }; + + XMLDocType.prototype.dat = function(value) { + return this.cdata(value); + }; + + XMLDocType.prototype.com = function(value) { + return this.comment(value); + }; + + XMLDocType.prototype.ins = function(target, value) { + return this.instruction(target, value); + }; + + XMLDocType.prototype.up = function() { + return this.root(); + }; + + XMLDocType.prototype.doc = function() { + return this.document(); + }; + + return XMLDocType; + + })(); + +}).call(this); + +},{"./XMLCData":73,"./XMLComment":74,"./XMLDTDAttList":75,"./XMLDTDElement":76,"./XMLDTDEntity":77,"./XMLDTDNotation":78,"./XMLProcessingInstruction":83,"lodash/lang/isObject":60,"lodash/object/create":64}],81:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLAttribute, XMLElement, XMLNode, XMLProcessingInstruction, create, every, isFunction, isObject, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + isFunction = require('lodash/lang/isFunction'); + + every = require('lodash/collection/every'); + + XMLNode = require('./XMLNode'); + + XMLAttribute = require('./XMLAttribute'); + + XMLProcessingInstruction = require('./XMLProcessingInstruction'); + + module.exports = XMLElement = (function(superClass) { + extend(XMLElement, superClass); + + function XMLElement(parent, name, attributes) { + XMLElement.__super__.constructor.call(this, parent); + if (name == null) { + throw new Error("Missing element name"); + } + this.name = this.stringify.eleName(name); + this.children = []; + this.instructions = []; + this.attributes = {}; + if (attributes != null) { + this.attribute(attributes); + } + } + + XMLElement.prototype.clone = function() { + var att, attName, clonedSelf, i, len, pi, ref, ref1; + clonedSelf = create(XMLElement.prototype, this); + if (clonedSelf.isRoot) { + clonedSelf.documentObject = null; + } + clonedSelf.attributes = {}; + ref = this.attributes; + for (attName in ref) { + if (!hasProp.call(ref, attName)) continue; + att = ref[attName]; + clonedSelf.attributes[attName] = att.clone(); + } + clonedSelf.instructions = []; + ref1 = this.instructions; + for (i = 0, len = ref1.length; i < len; i++) { + pi = ref1[i]; + clonedSelf.instructions.push(pi.clone()); + } + clonedSelf.children = []; + this.children.forEach(function(child) { + var clonedChild; + clonedChild = child.clone(); + clonedChild.parent = clonedSelf; + return clonedSelf.children.push(clonedChild); + }); + return clonedSelf; + }; + + XMLElement.prototype.attribute = function(name, value) { + var attName, attValue; + if (name != null) { + name = name.valueOf(); + } + if (isObject(name)) { + for (attName in name) { + if (!hasProp.call(name, attName)) continue; + attValue = name[attName]; + this.attribute(attName, attValue); + } + } else { + if (isFunction(value)) { + value = value.apply(); + } + if (!this.options.skipNullAttributes || (value != null)) { + this.attributes[name] = new XMLAttribute(this, name, value); + } + } + return this; + }; + + XMLElement.prototype.removeAttribute = function(name) { + var attName, i, len; + if (name == null) { + throw new Error("Missing attribute name"); + } + name = name.valueOf(); + if (Array.isArray(name)) { + for (i = 0, len = name.length; i < len; i++) { + attName = name[i]; + delete this.attributes[attName]; + } + } else { + delete this.attributes[name]; + } + return this; + }; + + XMLElement.prototype.instruction = function(target, value) { + var i, insTarget, insValue, instruction, len; + if (target != null) { + target = target.valueOf(); + } + if (value != null) { + value = value.valueOf(); + } + if (Array.isArray(target)) { + for (i = 0, len = target.length; i < len; i++) { + insTarget = target[i]; + this.instruction(insTarget); + } + } else if (isObject(target)) { + for (insTarget in target) { + if (!hasProp.call(target, insTarget)) continue; + insValue = target[insTarget]; + this.instruction(insTarget, insValue); + } + } else { + if (isFunction(value)) { + value = value.apply(); + } + instruction = new XMLProcessingInstruction(this, target, value); + this.instructions.push(instruction); + } + return this; + }; + + XMLElement.prototype.toString = function(options, level) { + var att, child, i, indent, instruction, j, len, len1, name, newline, offset, pretty, r, ref, ref1, ref2, ref3, ref4, ref5, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + ref3 = this.instructions; + for (i = 0, len = ref3.length; i < len; i++) { + instruction = ref3[i]; + r += instruction.toString(options, level); + } + if (pretty) { + r += space; + } + r += '<' + this.name; + ref4 = this.attributes; + for (name in ref4) { + if (!hasProp.call(ref4, name)) continue; + att = ref4[name]; + r += att.toString(options); + } + if (this.children.length === 0 || every(this.children, function(e) { + return e.value === ''; + })) { + r += '/>'; + if (pretty) { + r += newline; + } + } else if (pretty && this.children.length === 1 && (this.children[0].value != null)) { + r += '>'; + r += this.children[0].value; + r += ''; + r += newline; + } else { + r += '>'; + if (pretty) { + r += newline; + } + ref5 = this.children; + for (j = 0, len1 = ref5.length; j < len1; j++) { + child = ref5[j]; + r += child.toString(options, level + 1); + } + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + } + return r; + }; + + XMLElement.prototype.att = function(name, value) { + return this.attribute(name, value); + }; + + XMLElement.prototype.ins = function(target, value) { + return this.instruction(target, value); + }; + + XMLElement.prototype.a = function(name, value) { + return this.attribute(name, value); + }; + + XMLElement.prototype.i = function(target, value) { + return this.instruction(target, value); + }; + + return XMLElement; + + })(XMLNode); + +}).call(this); + +},{"./XMLAttribute":71,"./XMLNode":82,"./XMLProcessingInstruction":83,"lodash/collection/every":12,"lodash/lang/isFunction":58,"lodash/lang/isObject":60,"lodash/object/create":64}],82:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLComment, XMLDeclaration, XMLDocType, XMLElement, XMLNode, XMLRaw, XMLText, isEmpty, isFunction, isObject, + hasProp = {}.hasOwnProperty; + + isObject = require('lodash/lang/isObject'); + + isFunction = require('lodash/lang/isFunction'); + + isEmpty = require('lodash/lang/isEmpty'); + + XMLElement = null; + + XMLCData = null; + + XMLComment = null; + + XMLDeclaration = null; + + XMLDocType = null; + + XMLRaw = null; + + XMLText = null; + + module.exports = XMLNode = (function() { + function XMLNode(parent) { + this.parent = parent; + this.options = this.parent.options; + this.stringify = this.parent.stringify; + if (XMLElement === null) { + XMLElement = require('./XMLElement'); + XMLCData = require('./XMLCData'); + XMLComment = require('./XMLComment'); + XMLDeclaration = require('./XMLDeclaration'); + XMLDocType = require('./XMLDocType'); + XMLRaw = require('./XMLRaw'); + XMLText = require('./XMLText'); + } + } + + XMLNode.prototype.element = function(name, attributes, text) { + var childNode, item, j, k, key, lastChild, len, len1, ref, val; + lastChild = null; + if (attributes == null) { + attributes = {}; + } + attributes = attributes.valueOf(); + if (!isObject(attributes)) { + ref = [attributes, text], text = ref[0], attributes = ref[1]; + } + if (name != null) { + name = name.valueOf(); + } + if (Array.isArray(name)) { + for (j = 0, len = name.length; j < len; j++) { + item = name[j]; + lastChild = this.element(item); + } + } else if (isFunction(name)) { + lastChild = this.element(name.apply()); + } else if (isObject(name)) { + for (key in name) { + if (!hasProp.call(name, key)) continue; + val = name[key]; + if (isFunction(val)) { + val = val.apply(); + } + if ((isObject(val)) && (isEmpty(val))) { + val = null; + } + if (!this.options.ignoreDecorators && this.stringify.convertAttKey && key.indexOf(this.stringify.convertAttKey) === 0) { + lastChild = this.attribute(key.substr(this.stringify.convertAttKey.length), val); + } else if (!this.options.ignoreDecorators && this.stringify.convertPIKey && key.indexOf(this.stringify.convertPIKey) === 0) { + lastChild = this.instruction(key.substr(this.stringify.convertPIKey.length), val); + } else if (Array.isArray(val)) { + for (k = 0, len1 = val.length; k < len1; k++) { + item = val[k]; + childNode = {}; + childNode[key] = item; + lastChild = this.element(childNode); + } + } else if (isObject(val)) { + lastChild = this.element(key); + lastChild.element(val); + } else { + lastChild = this.element(key, val); + } + } + } else { + if (!this.options.ignoreDecorators && this.stringify.convertTextKey && name.indexOf(this.stringify.convertTextKey) === 0) { + lastChild = this.text(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertCDataKey && name.indexOf(this.stringify.convertCDataKey) === 0) { + lastChild = this.cdata(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertCommentKey && name.indexOf(this.stringify.convertCommentKey) === 0) { + lastChild = this.comment(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertRawKey && name.indexOf(this.stringify.convertRawKey) === 0) { + lastChild = this.raw(text); + } else { + lastChild = this.node(name, attributes, text); + } + } + if (lastChild == null) { + throw new Error("Could not create any elements with: " + name); + } + return lastChild; + }; + + XMLNode.prototype.insertBefore = function(name, attributes, text) { + var child, i, removed; + if (this.isRoot) { + throw new Error("Cannot insert elements at root level"); + } + i = this.parent.children.indexOf(this); + removed = this.parent.children.splice(i); + child = this.parent.element(name, attributes, text); + Array.prototype.push.apply(this.parent.children, removed); + return child; + }; + + XMLNode.prototype.insertAfter = function(name, attributes, text) { + var child, i, removed; + if (this.isRoot) { + throw new Error("Cannot insert elements at root level"); + } + i = this.parent.children.indexOf(this); + removed = this.parent.children.splice(i + 1); + child = this.parent.element(name, attributes, text); + Array.prototype.push.apply(this.parent.children, removed); + return child; + }; + + XMLNode.prototype.remove = function() { + var i, ref; + if (this.isRoot) { + throw new Error("Cannot remove the root element"); + } + i = this.parent.children.indexOf(this); + [].splice.apply(this.parent.children, [i, i - i + 1].concat(ref = [])), ref; + return this.parent; + }; + + XMLNode.prototype.node = function(name, attributes, text) { + var child, ref; + if (name != null) { + name = name.valueOf(); + } + if (attributes == null) { + attributes = {}; + } + attributes = attributes.valueOf(); + if (!isObject(attributes)) { + ref = [attributes, text], text = ref[0], attributes = ref[1]; + } + child = new XMLElement(this, name, attributes); + if (text != null) { + child.text(text); + } + this.children.push(child); + return child; + }; + + XMLNode.prototype.text = function(value) { + var child; + child = new XMLText(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.cdata = function(value) { + var child; + child = new XMLCData(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.comment = function(value) { + var child; + child = new XMLComment(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.raw = function(value) { + var child; + child = new XMLRaw(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.declaration = function(version, encoding, standalone) { + var doc, xmldec; + doc = this.document(); + xmldec = new XMLDeclaration(doc, version, encoding, standalone); + doc.xmldec = xmldec; + return doc.root(); + }; + + XMLNode.prototype.doctype = function(pubID, sysID) { + var doc, doctype; + doc = this.document(); + doctype = new XMLDocType(doc, pubID, sysID); + doc.doctype = doctype; + return doctype; + }; + + XMLNode.prototype.up = function() { + if (this.isRoot) { + throw new Error("The root node has no parent. Use doc() if you need to get the document object."); + } + return this.parent; + }; + + XMLNode.prototype.root = function() { + var child; + if (this.isRoot) { + return this; + } + child = this.parent; + while (!child.isRoot) { + child = child.parent; + } + return child; + }; + + XMLNode.prototype.document = function() { + return this.root().documentObject; + }; + + XMLNode.prototype.end = function(options) { + return this.document().toString(options); + }; + + XMLNode.prototype.prev = function() { + var i; + if (this.isRoot) { + throw new Error("Root node has no siblings"); + } + i = this.parent.children.indexOf(this); + if (i < 1) { + throw new Error("Already at the first node"); + } + return this.parent.children[i - 1]; + }; + + XMLNode.prototype.next = function() { + var i; + if (this.isRoot) { + throw new Error("Root node has no siblings"); + } + i = this.parent.children.indexOf(this); + if (i === -1 || i === this.parent.children.length - 1) { + throw new Error("Already at the last node"); + } + return this.parent.children[i + 1]; + }; + + XMLNode.prototype.importXMLBuilder = function(xmlbuilder) { + var clonedRoot; + clonedRoot = xmlbuilder.root().clone(); + clonedRoot.parent = this; + clonedRoot.isRoot = false; + this.children.push(clonedRoot); + return this; + }; + + XMLNode.prototype.ele = function(name, attributes, text) { + return this.element(name, attributes, text); + }; + + XMLNode.prototype.nod = function(name, attributes, text) { + return this.node(name, attributes, text); + }; + + XMLNode.prototype.txt = function(value) { + return this.text(value); + }; + + XMLNode.prototype.dat = function(value) { + return this.cdata(value); + }; + + XMLNode.prototype.com = function(value) { + return this.comment(value); + }; + + XMLNode.prototype.doc = function() { + return this.document(); + }; + + XMLNode.prototype.dec = function(version, encoding, standalone) { + return this.declaration(version, encoding, standalone); + }; + + XMLNode.prototype.dtd = function(pubID, sysID) { + return this.doctype(pubID, sysID); + }; + + XMLNode.prototype.e = function(name, attributes, text) { + return this.element(name, attributes, text); + }; + + XMLNode.prototype.n = function(name, attributes, text) { + return this.node(name, attributes, text); + }; + + XMLNode.prototype.t = function(value) { + return this.text(value); + }; + + XMLNode.prototype.d = function(value) { + return this.cdata(value); + }; + + XMLNode.prototype.c = function(value) { + return this.comment(value); + }; + + XMLNode.prototype.r = function(value) { + return this.raw(value); + }; + + XMLNode.prototype.u = function() { + return this.up(); + }; + + return XMLNode; + + })(); + +}).call(this); + +},{"./XMLCData":73,"./XMLComment":74,"./XMLDeclaration":79,"./XMLDocType":80,"./XMLElement":81,"./XMLRaw":84,"./XMLText":86,"lodash/lang/isEmpty":57,"lodash/lang/isFunction":58,"lodash/lang/isObject":60}],83:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLProcessingInstruction, create; + + create = require('lodash/object/create'); + + module.exports = XMLProcessingInstruction = (function() { + function XMLProcessingInstruction(parent, target, value) { + this.stringify = parent.stringify; + if (target == null) { + throw new Error("Missing instruction target"); + } + this.target = this.stringify.insTarget(target); + if (value) { + this.value = this.stringify.insValue(value); + } + } + + XMLProcessingInstruction.prototype.clone = function() { + return create(XMLProcessingInstruction.prototype, this); + }; + + XMLProcessingInstruction.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLProcessingInstruction; + + })(); + +}).call(this); + +},{"lodash/object/create":64}],84:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLNode, XMLRaw, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLRaw = (function(superClass) { + extend(XMLRaw, superClass); + + function XMLRaw(parent, text) { + XMLRaw.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing raw text"); + } + this.value = this.stringify.raw(text); + } + + XMLRaw.prototype.clone = function() { + return create(XMLRaw.prototype, this); + }; + + XMLRaw.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += this.value; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLRaw; + + })(XMLNode); + +}).call(this); + +},{"./XMLNode":82,"lodash/object/create":64}],85:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLStringifier, + bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + hasProp = {}.hasOwnProperty; + + module.exports = XMLStringifier = (function() { + function XMLStringifier(options) { + this.assertLegalChar = bind(this.assertLegalChar, this); + var key, ref, value; + this.allowSurrogateChars = options != null ? options.allowSurrogateChars : void 0; + ref = (options != null ? options.stringify : void 0) || {}; + for (key in ref) { + if (!hasProp.call(ref, key)) continue; + value = ref[key]; + this[key] = value; + } + } + + XMLStringifier.prototype.eleName = function(val) { + val = '' + val || ''; + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.eleText = function(val) { + val = '' + val || ''; + return this.assertLegalChar(this.elEscape(val)); + }; + + XMLStringifier.prototype.cdata = function(val) { + val = '' + val || ''; + if (val.match(/]]>/)) { + throw new Error("Invalid CDATA text: " + val); + } + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.comment = function(val) { + val = '' + val || ''; + if (val.match(/--/)) { + throw new Error("Comment text cannot contain double-hypen: " + val); + } + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.raw = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.attName = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.attValue = function(val) { + val = '' + val || ''; + return this.attEscape(val); + }; + + XMLStringifier.prototype.insTarget = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.insValue = function(val) { + val = '' + val || ''; + if (val.match(/\?>/)) { + throw new Error("Invalid processing instruction value: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlVersion = function(val) { + val = '' + val || ''; + if (!val.match(/1\.[0-9]+/)) { + throw new Error("Invalid version number: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlEncoding = function(val) { + val = '' + val || ''; + if (!val.match(/^[A-Za-z](?:[A-Za-z0-9._-]|-)*$/)) { + throw new Error("Invalid encoding: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlStandalone = function(val) { + if (val) { + return "yes"; + } else { + return "no"; + } + }; + + XMLStringifier.prototype.dtdPubID = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdSysID = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdElementValue = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdAttType = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdAttDefault = function(val) { + if (val != null) { + return '' + val || ''; + } else { + return val; + } + }; + + XMLStringifier.prototype.dtdEntityValue = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdNData = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.convertAttKey = '@'; + + XMLStringifier.prototype.convertPIKey = '?'; + + XMLStringifier.prototype.convertTextKey = '#text'; + + XMLStringifier.prototype.convertCDataKey = '#cdata'; + + XMLStringifier.prototype.convertCommentKey = '#comment'; + + XMLStringifier.prototype.convertRawKey = '#raw'; + + XMLStringifier.prototype.assertLegalChar = function(str) { + var chars, chr; + if (this.allowSurrogateChars) { + chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uFFFE-\uFFFF]/; + } else { + chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]/; + } + chr = str.match(chars); + if (chr) { + throw new Error("Invalid character (" + chr + ") in string: " + str + " at index " + chr.index); + } + return str; + }; + + XMLStringifier.prototype.elEscape = function(str) { + return str.replace(/&/g, '&').replace(//g, '>').replace(/\r/g, ' '); + }; + + XMLStringifier.prototype.attEscape = function(str) { + return str.replace(/&/g, '&').replace(/','amp':'&','quot':'"','apos':"'"} + if(locator){ + domBuilder.setDocumentLocator(locator) + } + + sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator); + sax.domBuilder = options.domBuilder || domBuilder; + if(/\/x?html?$/.test(mimeType)){ + entityMap.nbsp = '\xa0'; + entityMap.copy = '\xa9'; + defaultNSMap['']= 'http://www.w3.org/1999/xhtml'; + } + if(source){ + sax.parse(source,defaultNSMap,entityMap); + }else{ + sax.errorHandler.error("invalid document source"); + } + return domBuilder.document; +} +function buildErrorHandler(errorImpl,domBuilder,locator){ + if(!errorImpl){ + if(domBuilder instanceof DOMHandler){ + return domBuilder; + } + errorImpl = domBuilder ; + } + var errorHandler = {} + var isCallback = errorImpl instanceof Function; + locator = locator||{} + function build(key){ + var fn = errorImpl[key]; + if(!fn){ + if(isCallback){ + fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl; + }else{ + var i=arguments.length; + while(--i){ + if(fn = errorImpl[arguments[i]]){ + break; + } + } + } + } + errorHandler[key] = fn && function(msg){ + fn(msg+_locator(locator)); + }||function(){}; + } + build('warning','warn'); + build('error','warn','warning'); + build('fatalError','warn','warning','error'); + return errorHandler; +} +/** + * +ContentHandler+ErrorHandler + * +LexicalHandler+EntityResolver2 + * -DeclHandler-DTDHandler + * + * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler + * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2 + * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html + */ +function DOMHandler() { + this.cdata = false; +} +function position(locator,node){ + node.lineNumber = locator.lineNumber; + node.columnNumber = locator.columnNumber; +} +/** + * @see org.xml.sax.ContentHandler#startDocument + * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html + */ +DOMHandler.prototype = { + startDocument : function() { + this.document = new DOMImplementation().createDocument(null, null, null); + if (this.locator) { + this.document.documentURI = this.locator.systemId; + } + }, + startElement:function(namespaceURI, localName, qName, attrs) { + var doc = this.document; + var el = doc.createElementNS(namespaceURI, qName||localName); + var len = attrs.length; + appendElement(this, el); + this.currentElement = el; + + this.locator && position(this.locator,el) + for (var i = 0 ; i < len; i++) { + var namespaceURI = attrs.getURI(i); + var value = attrs.getValue(i); + var qName = attrs.getQName(i); + var attr = doc.createAttributeNS(namespaceURI, qName); + if( attr.getOffset){ + position(attr.getOffset(1),attr) + } + attr.value = attr.nodeValue = value; + el.setAttributeNode(attr) + } + }, + endElement:function(namespaceURI, localName, qName) { + var current = this.currentElement + var tagName = current.tagName; + this.currentElement = current.parentNode; + }, + startPrefixMapping:function(prefix, uri) { + }, + endPrefixMapping:function(prefix) { + }, + processingInstruction:function(target, data) { + var ins = this.document.createProcessingInstruction(target, data); + this.locator && position(this.locator,ins) + appendElement(this, ins); + }, + ignorableWhitespace:function(ch, start, length) { + }, + characters:function(chars, start, length) { + chars = _toString.apply(this,arguments) + //console.log(chars) + if(this.currentElement && chars){ + if (this.cdata) { + var charNode = this.document.createCDATASection(chars); + this.currentElement.appendChild(charNode); + } else { + var charNode = this.document.createTextNode(chars); + this.currentElement.appendChild(charNode); + } + this.locator && position(this.locator,charNode) + } + }, + skippedEntity:function(name) { + }, + endDocument:function() { + this.document.normalize(); + }, + setDocumentLocator:function (locator) { + if(this.locator = locator){// && !('lineNumber' in locator)){ + locator.lineNumber = 0; + } + }, + //LexicalHandler + comment:function(chars, start, length) { + chars = _toString.apply(this,arguments) + var comm = this.document.createComment(chars); + this.locator && position(this.locator,comm) + appendElement(this, comm); + }, + + startCDATA:function() { + //used in characters() methods + this.cdata = true; + }, + endCDATA:function() { + this.cdata = false; + }, + + startDTD:function(name, publicId, systemId) { + var impl = this.document.implementation; + if (impl && impl.createDocumentType) { + var dt = impl.createDocumentType(name, publicId, systemId); + this.locator && position(this.locator,dt) + appendElement(this, dt); + } + }, + /** + * @see org.xml.sax.ErrorHandler + * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html + */ + warning:function(error) { + console.warn(error,_locator(this.locator)); + }, + error:function(error) { + console.error(error,_locator(this.locator)); + }, + fatalError:function(error) { + console.error(error,_locator(this.locator)); + throw error; + } +} +function _locator(l){ + if(l){ + return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']' + } +} +function _toString(chars,start,length){ + if(typeof chars == 'string'){ + return chars.substr(start,length) + }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)") + if(chars.length >= start+length || start){ + return new java.lang.String(chars,start,length)+''; + } + return chars; + } +} + +/* + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html + * used method of org.xml.sax.ext.LexicalHandler: + * #comment(chars, start, length) + * #startCDATA() + * #endCDATA() + * #startDTD(name, publicId, systemId) + * + * + * IGNORED method of org.xml.sax.ext.LexicalHandler: + * #endDTD() + * #startEntity(name) + * #endEntity(name) + * + * + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html + * IGNORED method of org.xml.sax.ext.DeclHandler + * #attributeDecl(eName, aName, type, mode, value) + * #elementDecl(name, model) + * #externalEntityDecl(name, publicId, systemId) + * #internalEntityDecl(name, value) + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html + * IGNORED method of org.xml.sax.EntityResolver2 + * #resolveEntity(String name,String publicId,String baseURI,String systemId) + * #resolveEntity(publicId, systemId) + * #getExternalSubset(name, baseURI) + * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html + * IGNORED method of org.xml.sax.DTDHandler + * #notationDecl(name, publicId, systemId) {}; + * #unparsedEntityDecl(name, publicId, systemId, notationName) {}; + */ +"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){ + DOMHandler.prototype[key] = function(){return null} +}) + +/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */ +function appendElement (hander,node) { + if (!hander.currentElement) { + hander.document.appendChild(node); + } else { + hander.currentElement.appendChild(node); + } +}//appendChild and setAttributeNS are preformance key + +if(typeof require == 'function'){ + var XMLReader = require('./sax').XMLReader; + var DOMImplementation = exports.DOMImplementation = require('./dom').DOMImplementation; + exports.XMLSerializer = require('./dom').XMLSerializer ; + exports.DOMParser = DOMParser; +} + +},{"./dom":89,"./sax":90}],89:[function(require,module,exports){ +/* + * DOM Level 2 + * Object DOMException + * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html + */ + +function copy(src,dest){ + for(var p in src){ + dest[p] = src[p]; + } +} +/** +^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));? +^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));? + */ +function _extends(Class,Super){ + var pt = Class.prototype; + if(Object.create){ + var ppt = Object.create(Super.prototype) + pt.__proto__ = ppt; + } + if(!(pt instanceof Super)){ + function t(){}; + t.prototype = Super.prototype; + t = new t(); + copy(pt,t); + Class.prototype = pt = t; + } + if(pt.constructor != Class){ + if(typeof Class != 'function'){ + console.error("unknow Class:"+Class) + } + pt.constructor = Class + } +} +var htmlns = 'http://www.w3.org/1999/xhtml' ; +// Node Types +var NodeType = {} +var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1; +var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2; +var TEXT_NODE = NodeType.TEXT_NODE = 3; +var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4; +var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5; +var ENTITY_NODE = NodeType.ENTITY_NODE = 6; +var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7; +var COMMENT_NODE = NodeType.COMMENT_NODE = 8; +var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9; +var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10; +var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11; +var NOTATION_NODE = NodeType.NOTATION_NODE = 12; + +// ExceptionCode +var ExceptionCode = {} +var ExceptionMessage = {}; +var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1); +var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2); +var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3); +var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4); +var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5); +var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6); +var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7); +var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8); +var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9); +var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10); +//level2 +var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11); +var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12); +var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13); +var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14); +var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15); + + +function DOMException(code, message) { + if(message instanceof Error){ + var error = message; + }else{ + error = this; + Error.call(this, ExceptionMessage[code]); + this.message = ExceptionMessage[code]; + if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException); + } + error.code = code; + if(message) this.message = this.message + ": " + message; + return error; +}; +DOMException.prototype = Error.prototype; +copy(ExceptionCode,DOMException) +/** + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177 + * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live. + * The items in the NodeList are accessible via an integral index, starting from 0. + */ +function NodeList() { +}; +NodeList.prototype = { + /** + * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive. + * @standard level1 + */ + length:0, + /** + * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null. + * @standard level1 + * @param index unsigned long + * Index into the collection. + * @return Node + * The node at the indexth position in the NodeList, or null if that is not a valid index. + */ + item: function(index) { + return this[index] || null; + } +}; +function LiveNodeList(node,refresh){ + this._node = node; + this._refresh = refresh + _updateLiveList(this); +} +function _updateLiveList(list){ + var inc = list._node._inc || list._node.ownerDocument._inc; + if(list._inc != inc){ + var ls = list._refresh(list._node); + //console.log(ls.length) + __set__(list,'length',ls.length); + copy(ls,list); + list._inc = inc; + } +} +LiveNodeList.prototype.item = function(i){ + _updateLiveList(this); + return this[i]; +} + +_extends(LiveNodeList,NodeList); +/** + * + * Objects implementing the NamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that NamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes. + * NamedNodeMap objects in the DOM are live. + * used for attributes or DocumentType entities + */ +function NamedNodeMap() { +}; + +function _findNodeIndex(list,node){ + var i = list.length; + while(i--){ + if(list[i] === node){return i} + } +} + +function _addNamedNode(el,list,newAttr,oldAttr){ + if(oldAttr){ + list[_findNodeIndex(list,oldAttr)] = newAttr; + }else{ + list[list.length++] = newAttr; + } + if(el){ + newAttr.ownerElement = el; + var doc = el.ownerDocument; + if(doc){ + oldAttr && _onRemoveAttribute(doc,el,oldAttr); + _onAddAttribute(doc,el,newAttr); + } + } +} +function _removeNamedNode(el,list,attr){ + var i = _findNodeIndex(list,attr); + if(i>=0){ + var lastIndex = list.length-1 + while(i0 || key == 'xmlns'){ +// return null; +// } + var i = this.length; + while(i--){ + var attr = this[i]; + if(attr.nodeName == key){ + return attr; + } + } + }, + setNamedItem: function(attr) { + var el = attr.ownerElement; + if(el && el!=this._ownerElement){ + throw new DOMException(INUSE_ATTRIBUTE_ERR); + } + var oldAttr = this.getNamedItem(attr.nodeName); + _addNamedNode(this._ownerElement,this,attr,oldAttr); + return oldAttr; + }, + /* returns Node */ + setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR + var el = attr.ownerElement, oldAttr; + if(el && el!=this._ownerElement){ + throw new DOMException(INUSE_ATTRIBUTE_ERR); + } + oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName); + _addNamedNode(this._ownerElement,this,attr,oldAttr); + return oldAttr; + }, + + /* returns Node */ + removeNamedItem: function(key) { + var attr = this.getNamedItem(key); + _removeNamedNode(this._ownerElement,this,attr); + return attr; + + + },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR + + //for level2 + removeNamedItemNS:function(namespaceURI,localName){ + var attr = this.getNamedItemNS(namespaceURI,localName); + _removeNamedNode(this._ownerElement,this,attr); + return attr; + }, + getNamedItemNS: function(namespaceURI, localName) { + var i = this.length; + while(i--){ + var node = this[i]; + if(node.localName == localName && node.namespaceURI == namespaceURI){ + return node; + } + } + return null; + } +}; +/** + * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 + */ +function DOMImplementation(/* Object */ features) { + this._features = {}; + if (features) { + for (var feature in features) { + this._features = features[feature]; + } + } +}; + +DOMImplementation.prototype = { + hasFeature: function(/* string */ feature, /* string */ version) { + var versions = this._features[feature.toLowerCase()]; + if (versions && (!version || version in versions)) { + return true; + } else { + return false; + } + }, + // Introduced in DOM Level 2: + createDocument:function(namespaceURI, qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR + var doc = new Document(); + doc.doctype = doctype; + if(doctype){ + doc.appendChild(doctype); + } + doc.implementation = this; + doc.childNodes = new NodeList(); + if(qualifiedName){ + var root = doc.createElementNS(namespaceURI,qualifiedName); + doc.appendChild(root); + } + return doc; + }, + // Introduced in DOM Level 2: + createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR + var node = new DocumentType(); + node.name = qualifiedName; + node.nodeName = qualifiedName; + node.publicId = publicId; + node.systemId = systemId; + // Introduced in DOM Level 2: + //readonly attribute DOMString internalSubset; + + //TODO:.. + // readonly attribute NamedNodeMap entities; + // readonly attribute NamedNodeMap notations; + return node; + } +}; + + +/** + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 + */ + +function Node() { +}; + +Node.prototype = { + firstChild : null, + lastChild : null, + previousSibling : null, + nextSibling : null, + attributes : null, + parentNode : null, + childNodes : null, + ownerDocument : null, + nodeValue : null, + namespaceURI : null, + prefix : null, + localName : null, + // Modified in DOM Level 2: + insertBefore:function(newChild, refChild){//raises + return _insertBefore(this,newChild,refChild); + }, + replaceChild:function(newChild, oldChild){//raises + this.insertBefore(newChild,oldChild); + if(oldChild){ + this.removeChild(oldChild); + } + }, + removeChild:function(oldChild){ + return _removeChild(this,oldChild); + }, + appendChild:function(newChild){ + return this.insertBefore(newChild,null); + }, + hasChildNodes:function(){ + return this.firstChild != null; + }, + cloneNode:function(deep){ + return cloneNode(this.ownerDocument||this,this,deep); + }, + // Modified in DOM Level 2: + normalize:function(){ + var child = this.firstChild; + while(child){ + var next = child.nextSibling; + if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){ + this.removeChild(next); + child.appendData(next.data); + }else{ + child.normalize(); + child = next; + } + } + }, + // Introduced in DOM Level 2: + isSupported:function(feature, version){ + return this.ownerDocument.implementation.hasFeature(feature,version); + }, + // Introduced in DOM Level 2: + hasAttributes:function(){ + return this.attributes.length>0; + }, + lookupPrefix:function(namespaceURI){ + var el = this; + while(el){ + var map = el._nsMap; + //console.dir(map) + if(map){ + for(var n in map){ + if(map[n] == namespaceURI){ + return n; + } + } + } + el = el.nodeType == 2?el.ownerDocument : el.parentNode; + } + return null; + }, + // Introduced in DOM Level 3: + lookupNamespaceURI:function(prefix){ + var el = this; + while(el){ + var map = el._nsMap; + //console.dir(map) + if(map){ + if(prefix in map){ + return map[prefix] ; + } + } + el = el.nodeType == 2?el.ownerDocument : el.parentNode; + } + return null; + }, + // Introduced in DOM Level 3: + isDefaultNamespace:function(namespaceURI){ + var prefix = this.lookupPrefix(namespaceURI); + return prefix == null; + } +}; + + +function _xmlEncoder(c){ + return c == '<' && '<' || + c == '>' && '>' || + c == '&' && '&' || + c == '"' && '"' || + '&#'+c.charCodeAt()+';' +} + + +copy(NodeType,Node); +copy(NodeType,Node.prototype); + +/** + * @param callback return true for continue,false for break + * @return boolean true: break visit; + */ +function _visitNode(node,callback){ + if(callback(node)){ + return true; + } + if(node = node.firstChild){ + do{ + if(_visitNode(node,callback)){return true} + }while(node=node.nextSibling) + } +} + + + +function Document(){ +} +function _onAddAttribute(doc,el,newAttr){ + doc && doc._inc++; + var ns = newAttr.namespaceURI ; + if(ns == 'http://www.w3.org/2000/xmlns/'){ + //update namespace + el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value + } +} +function _onRemoveAttribute(doc,el,newAttr,remove){ + doc && doc._inc++; + var ns = newAttr.namespaceURI ; + if(ns == 'http://www.w3.org/2000/xmlns/'){ + //update namespace + delete el._nsMap[newAttr.prefix?newAttr.localName:''] + } +} +function _onUpdateChild(doc,el,newChild){ + if(doc && doc._inc){ + doc._inc++; + //update childNodes + var cs = el.childNodes; + if(newChild){ + cs[cs.length++] = newChild; + }else{ + //console.log(1) + var child = el.firstChild; + var i = 0; + while(child){ + cs[i++] = child; + child =child.nextSibling; + } + cs.length = i; + } + } +} + +/** + * attributes; + * children; + * + * writeable properties: + * nodeValue,Attr:value,CharacterData:data + * prefix + */ +function _removeChild(parentNode,child){ + var previous = child.previousSibling; + var next = child.nextSibling; + if(previous){ + previous.nextSibling = next; + }else{ + parentNode.firstChild = next + } + if(next){ + next.previousSibling = previous; + }else{ + parentNode.lastChild = previous; + } + _onUpdateChild(parentNode.ownerDocument,parentNode); + return child; +} +/** + * preformance key(refChild == null) + */ +function _insertBefore(parentNode,newChild,nextChild){ + var cp = newChild.parentNode; + if(cp){ + cp.removeChild(newChild);//remove and update + } + if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){ + var newFirst = newChild.firstChild; + if (newFirst == null) { + return newChild; + } + var newLast = newChild.lastChild; + }else{ + newFirst = newLast = newChild; + } + var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild; + + newFirst.previousSibling = pre; + newLast.nextSibling = nextChild; + + + if(pre){ + pre.nextSibling = newFirst; + }else{ + parentNode.firstChild = newFirst; + } + if(nextChild == null){ + parentNode.lastChild = newLast; + }else{ + nextChild.previousSibling = newLast; + } + do{ + newFirst.parentNode = parentNode; + }while(newFirst !== newLast && (newFirst= newFirst.nextSibling)) + _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode); + //console.log(parentNode.lastChild.nextSibling == null) + if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) { + newChild.firstChild = newChild.lastChild = null; + } + return newChild; +} +function _appendSingleChild(parentNode,newChild){ + var cp = newChild.parentNode; + if(cp){ + var pre = parentNode.lastChild; + cp.removeChild(newChild);//remove and update + var pre = parentNode.lastChild; + } + var pre = parentNode.lastChild; + newChild.parentNode = parentNode; + newChild.previousSibling = pre; + newChild.nextSibling = null; + if(pre){ + pre.nextSibling = newChild; + }else{ + parentNode.firstChild = newChild; + } + parentNode.lastChild = newChild; + _onUpdateChild(parentNode.ownerDocument,parentNode,newChild); + return newChild; + //console.log("__aa",parentNode.lastChild.nextSibling == null) +} +Document.prototype = { + //implementation : null, + nodeName : '#document', + nodeType : DOCUMENT_NODE, + doctype : null, + documentElement : null, + _inc : 1, + + insertBefore : function(newChild, refChild){//raises + if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){ + var child = newChild.firstChild; + while(child){ + var next = child.nextSibling; + this.insertBefore(child,refChild); + child = next; + } + return newChild; + } + if(this.documentElement == null && newChild.nodeType == 1){ + this.documentElement = newChild; + } + + return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild; + }, + removeChild : function(oldChild){ + if(this.documentElement == oldChild){ + this.documentElement = null; + } + return _removeChild(this,oldChild); + }, + // Introduced in DOM Level 2: + importNode : function(importedNode,deep){ + return importNode(this,importedNode,deep); + }, + // Introduced in DOM Level 2: + getElementById : function(id){ + var rtv = null; + _visitNode(this.documentElement,function(node){ + if(node.nodeType == 1){ + if(node.getAttribute('id') == id){ + rtv = node; + return true; + } + } + }) + return rtv; + }, + + //document factory method: + createElement : function(tagName){ + var node = new Element(); + node.ownerDocument = this; + node.nodeName = tagName; + node.tagName = tagName; + node.childNodes = new NodeList(); + var attrs = node.attributes = new NamedNodeMap(); + attrs._ownerElement = node; + return node; + }, + createDocumentFragment : function(){ + var node = new DocumentFragment(); + node.ownerDocument = this; + node.childNodes = new NodeList(); + return node; + }, + createTextNode : function(data){ + var node = new Text(); + node.ownerDocument = this; + node.appendData(data) + return node; + }, + createComment : function(data){ + var node = new Comment(); + node.ownerDocument = this; + node.appendData(data) + return node; + }, + createCDATASection : function(data){ + var node = new CDATASection(); + node.ownerDocument = this; + node.appendData(data) + return node; + }, + createProcessingInstruction : function(target,data){ + var node = new ProcessingInstruction(); + node.ownerDocument = this; + node.tagName = node.target = target; + node.nodeValue= node.data = data; + return node; + }, + createAttribute : function(name){ + var node = new Attr(); + node.ownerDocument = this; + node.name = name; + node.nodeName = name; + node.localName = name; + node.specified = true; + return node; + }, + createEntityReference : function(name){ + var node = new EntityReference(); + node.ownerDocument = this; + node.nodeName = name; + return node; + }, + // Introduced in DOM Level 2: + createElementNS : function(namespaceURI,qualifiedName){ + var node = new Element(); + var pl = qualifiedName.split(':'); + var attrs = node.attributes = new NamedNodeMap(); + node.childNodes = new NodeList(); + node.ownerDocument = this; + node.nodeName = qualifiedName; + node.tagName = qualifiedName; + node.namespaceURI = namespaceURI; + if(pl.length == 2){ + node.prefix = pl[0]; + node.localName = pl[1]; + }else{ + //el.prefix = null; + node.localName = qualifiedName; + } + attrs._ownerElement = node; + return node; + }, + // Introduced in DOM Level 2: + createAttributeNS : function(namespaceURI,qualifiedName){ + var node = new Attr(); + var pl = qualifiedName.split(':'); + node.ownerDocument = this; + node.nodeName = qualifiedName; + node.name = qualifiedName; + node.namespaceURI = namespaceURI; + node.specified = true; + if(pl.length == 2){ + node.prefix = pl[0]; + node.localName = pl[1]; + }else{ + //el.prefix = null; + node.localName = qualifiedName; + } + return node; + } +}; +_extends(Document,Node); + + +function Element() { + this._nsMap = {}; +}; +Element.prototype = { + nodeType : ELEMENT_NODE, + hasAttribute : function(name){ + return this.getAttributeNode(name)!=null; + }, + getAttribute : function(name){ + var attr = this.getAttributeNode(name); + return attr && attr.value || ''; + }, + getAttributeNode : function(name){ + return this.attributes.getNamedItem(name); + }, + setAttribute : function(name, value){ + var attr = this.ownerDocument.createAttribute(name); + attr.value = attr.nodeValue = "" + value; + this.setAttributeNode(attr) + }, + removeAttribute : function(name){ + var attr = this.getAttributeNode(name) + attr && this.removeAttributeNode(attr); + }, + + //four real opeartion method + appendChild:function(newChild){ + if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){ + return this.insertBefore(newChild,null); + }else{ + return _appendSingleChild(this,newChild); + } + }, + setAttributeNode : function(newAttr){ + return this.attributes.setNamedItem(newAttr); + }, + setAttributeNodeNS : function(newAttr){ + return this.attributes.setNamedItemNS(newAttr); + }, + removeAttributeNode : function(oldAttr){ + return this.attributes.removeNamedItem(oldAttr.nodeName); + }, + //get real attribute name,and remove it by removeAttributeNode + removeAttributeNS : function(namespaceURI, localName){ + var old = this.getAttributeNodeNS(namespaceURI, localName); + old && this.removeAttributeNode(old); + }, + + hasAttributeNS : function(namespaceURI, localName){ + return this.getAttributeNodeNS(namespaceURI, localName)!=null; + }, + getAttributeNS : function(namespaceURI, localName){ + var attr = this.getAttributeNodeNS(namespaceURI, localName); + return attr && attr.value || ''; + }, + setAttributeNS : function(namespaceURI, qualifiedName, value){ + var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName); + attr.value = attr.nodeValue = value; + this.setAttributeNode(attr) + }, + getAttributeNodeNS : function(namespaceURI, localName){ + return this.attributes.getNamedItemNS(namespaceURI, localName); + }, + + getElementsByTagName : function(tagName){ + return new LiveNodeList(this,function(base){ + var ls = []; + _visitNode(base,function(node){ + if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){ + ls.push(node); + } + }); + return ls; + }); + }, + getElementsByTagNameNS : function(namespaceURI, localName){ + return new LiveNodeList(this,function(base){ + var ls = []; + _visitNode(base,function(node){ + if(node !== base && node.nodeType === ELEMENT_NODE && node.namespaceURI === namespaceURI && (localName === '*' || node.localName == localName)){ + ls.push(node); + } + }); + return ls; + }); + } +}; +Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName; +Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS; + + +_extends(Element,Node); +function Attr() { +}; +Attr.prototype.nodeType = ATTRIBUTE_NODE; +_extends(Attr,Node); + + +function CharacterData() { +}; +CharacterData.prototype = { + data : '', + substringData : function(offset, count) { + return this.data.substring(offset, offset+count); + }, + appendData: function(text) { + text = this.data+text; + this.nodeValue = this.data = text; + this.length = text.length; + }, + insertData: function(offset,text) { + this.replaceData(offset,0,text); + + }, + appendChild:function(newChild){ + //if(!(newChild instanceof CharacterData)){ + throw new Error(ExceptionMessage[3]) + //} + return Node.prototype.appendChild.apply(this,arguments) + }, + deleteData: function(offset, count) { + this.replaceData(offset,count,""); + }, + replaceData: function(offset, count, text) { + var start = this.data.substring(0,offset); + var end = this.data.substring(offset+count); + text = start + text + end; + this.nodeValue = this.data = text; + this.length = text.length; + } +} +_extends(CharacterData,Node); +function Text() { +}; +Text.prototype = { + nodeName : "#text", + nodeType : TEXT_NODE, + splitText : function(offset) { + var text = this.data; + var newText = text.substring(offset); + text = text.substring(0, offset); + this.data = this.nodeValue = text; + this.length = text.length; + var newNode = this.ownerDocument.createTextNode(newText); + if(this.parentNode){ + this.parentNode.insertBefore(newNode, this.nextSibling); + } + return newNode; + } +} +_extends(Text,CharacterData); +function Comment() { +}; +Comment.prototype = { + nodeName : "#comment", + nodeType : COMMENT_NODE +} +_extends(Comment,CharacterData); + +function CDATASection() { +}; +CDATASection.prototype = { + nodeName : "#cdata-section", + nodeType : CDATA_SECTION_NODE +} +_extends(CDATASection,CharacterData); + + +function DocumentType() { +}; +DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE; +_extends(DocumentType,Node); + +function Notation() { +}; +Notation.prototype.nodeType = NOTATION_NODE; +_extends(Notation,Node); + +function Entity() { +}; +Entity.prototype.nodeType = ENTITY_NODE; +_extends(Entity,Node); + +function EntityReference() { +}; +EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE; +_extends(EntityReference,Node); + +function DocumentFragment() { +}; +DocumentFragment.prototype.nodeName = "#document-fragment"; +DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE; +_extends(DocumentFragment,Node); + + +function ProcessingInstruction() { +} +ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE; +_extends(ProcessingInstruction,Node); +function XMLSerializer(){} +XMLSerializer.prototype.serializeToString = function(node){ + var buf = []; + serializeToString(node,buf); + return buf.join(''); +} +Node.prototype.toString =function(){ + return XMLSerializer.prototype.serializeToString(this); +} +function serializeToString(node,buf){ + switch(node.nodeType){ + case ELEMENT_NODE: + var attrs = node.attributes; + var len = attrs.length; + var child = node.firstChild; + var nodeName = node.tagName; + var isHTML = htmlns === node.namespaceURI + buf.push('<',nodeName); + for(var i=0;i'); + //if is cdata child node + if(isHTML && /^script$/i.test(nodeName)){ + if(child){ + buf.push(child.data); + } + }else{ + while(child){ + serializeToString(child,buf); + child = child.nextSibling; + } + } + buf.push(''); + }else{ + buf.push('/>'); + } + return; + case DOCUMENT_NODE: + case DOCUMENT_FRAGMENT_NODE: + var child = node.firstChild; + while(child){ + serializeToString(child,buf); + child = child.nextSibling; + } + return; + case ATTRIBUTE_NODE: + return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"'); + case TEXT_NODE: + return buf.push(node.data.replace(/[<&]/g,_xmlEncoder)); + case CDATA_SECTION_NODE: + return buf.push( ''); + case COMMENT_NODE: + return buf.push( ""); + case DOCUMENT_TYPE_NODE: + var pubid = node.publicId; + var sysid = node.systemId; + buf.push(''); + }else if(sysid && sysid!='.'){ + buf.push(' SYSTEM "',sysid,'">'); + }else{ + var sub = node.internalSubset; + if(sub){ + buf.push(" [",sub,"]"); + } + buf.push(">"); + } + return; + case PROCESSING_INSTRUCTION_NODE: + return buf.push( ""); + case ENTITY_REFERENCE_NODE: + return buf.push( '&',node.nodeName,';'); + //case ENTITY_NODE: + //case NOTATION_NODE: + default: + buf.push('??',node.nodeName); + } +} +function importNode(doc,node,deep){ + var node2; + switch (node.nodeType) { + case ELEMENT_NODE: + node2 = node.cloneNode(false); + node2.ownerDocument = doc; + //var attrs = node2.attributes; + //var len = attrs.length; + //for(var i=0;i + +function XMLReader(){ + +} + +XMLReader.prototype = { + parse:function(source,defaultNSMap,entityMap){ + var domBuilder = this.domBuilder; + domBuilder.startDocument(); + _copy(defaultNSMap ,defaultNSMap = {}) + parse(source,defaultNSMap,entityMap, + domBuilder,this.errorHandler); + domBuilder.endDocument(); + } +} +function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){ + function fixedFromCharCode(code) { + // String.prototype.fromCharCode does not supports + // > 2 bytes unicode chars directly + if (code > 0xffff) { + code -= 0x10000; + var surrogate1 = 0xd800 + (code >> 10) + , surrogate2 = 0xdc00 + (code & 0x3ff); + + return String.fromCharCode(surrogate1, surrogate2); + } else { + return String.fromCharCode(code); + } + } + function entityReplacer(a){ + var k = a.slice(1,-1); + if(k in entityMap){ + return entityMap[k]; + }else if(k.charAt(0) === '#'){ + return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x'))) + }else{ + errorHandler.error('entity not found:'+a); + return a; + } + } + function appendText(end){//has some bugs + var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer); + locator&&position(start); + domBuilder.characters(xt,0,end-start); + start = end + } + function position(start,m){ + while(start>=endPos && (m = linePattern.exec(source))){ + startPos = m.index; + endPos = startPos + m[0].length; + locator.lineNumber++; + //console.log('line++:',locator,startPos,endPos) + } + locator.columnNumber = start-startPos+1; + } + var startPos = 0; + var endPos = 0; + var linePattern = /.+(?:\r\n?|\n)|.*$/g + var locator = domBuilder.locator; + + var parseStack = [{currentNSMap:defaultNSMapCopy}] + var closeMap = {}; + var start = 0; + while(true){ + var i = source.indexOf('<',start); + if(i<0){ + if(!source.substr(start).match(/^\s*$/)){ + var doc = domBuilder.document; + var text = doc.createTextNode(source.substr(start)); + doc.appendChild(text); + domBuilder.currentElement = text; + } + return; + } + if(i>start){ + appendText(i); + } + switch(source.charAt(i+1)){ + case '/': + var end = source.indexOf('>',i+3); + var tagName = source.substring(i+2,end); + var config = parseStack.pop(); + var localNSMap = config.localNSMap; + + if(config.tagName != tagName){ + errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName ); + } + domBuilder.endElement(config.uri,config.localName,tagName); + if(localNSMap){ + for(var prefix in localNSMap){ + domBuilder.endPrefixMapping(prefix) ; + } + } + end++; + break; + // end elment + case '?':// + locator&&position(i); + end = parseInstruction(source,i,domBuilder); + break; + case '!':// 0){ + value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + el.add(attrName,value,start-1); + s = S_E; + }else{ + //fatalError: no end quot match + throw new Error('attribute value no end \''+c+'\' match'); + } + }else if(s == S_V){ + value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + //console.log(attrName,value,start,p) + el.add(attrName,value,start); + //console.dir(el) + errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!'); + start = p+1; + s = S_E + }else{ + //fatalError: no equal before + throw new Error('attribute value must after "="'); + } + break; + case '/': + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p)); + case S_E: + case S_S: + case S_C: + s = S_C; + el.closed = true; + case S_V: + case S_ATTR: + case S_ATTR_S: + break; + //case S_EQ: + default: + throw new Error("attribute invalid close char('/')") + } + break; + case ''://end document + //throw new Error('unexpected end of input') + errorHandler.error('unexpected end of input'); + case '>': + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p)); + case S_E: + case S_S: + case S_C: + break;//normal + case S_V://Compatible state + case S_ATTR: + value = source.slice(start,p); + if(value.slice(-1) === '/'){ + el.closed = true; + value = value.slice(0,-1) + } + case S_ATTR_S: + if(s === S_ATTR_S){ + value = attrName; + } + if(s == S_V){ + errorHandler.warning('attribute "'+value+'" missed quot(")!!'); + el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start) + }else{ + errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!') + el.add(value,value,start) + } + break; + case S_EQ: + throw new Error('attribute value missed!!'); + } +// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName)) + return p; + /*xml space '\x20' | #x9 | #xD | #xA; */ + case '\u0080': + c = ' '; + default: + if(c<= ' '){//space + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p));//tagName + s = S_S; + break; + case S_ATTR: + attrName = source.slice(start,p) + s = S_ATTR_S; + break; + case S_V: + var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + errorHandler.warning('attribute "'+value+'" missed quot(")!!'); + el.add(attrName,value,start) + case S_E: + s = S_S; + break; + //case S_S: + //case S_EQ: + //case S_ATTR_S: + // void();break; + //case S_C: + //ignore warning + } + }else{//not space +//S_TAG, S_ATTR, S_EQ, S_V +//S_ATTR_S, S_E, S_S, S_C + switch(s){ + //case S_TAG:void();break; + //case S_ATTR:void();break; + //case S_V:void();break; + case S_ATTR_S: + errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!') + el.add(attrName,attrName,start); + start = p; + s = S_ATTR; + break; + case S_E: + errorHandler.warning('attribute space is required"'+attrName+'"!!') + case S_S: + s = S_ATTR; + start = p; + break; + case S_EQ: + s = S_V; + start = p; + break; + case S_C: + throw new Error("elements closed character '/' and '>' must be connected to"); + } + } + } + p++; + } +} +/** + * @return end of the elementStartPart(end of elementEndPart for selfClosed el) + */ +function appendElement(el,domBuilder,parseStack){ + var tagName = el.tagName; + var localNSMap = null; + var currentNSMap = parseStack[parseStack.length-1].currentNSMap; + var i = el.length; + while(i--){ + var a = el[i]; + var qName = a.qName; + var value = a.value; + var nsp = qName.indexOf(':'); + if(nsp>0){ + var prefix = a.prefix = qName.slice(0,nsp); + var localName = qName.slice(nsp+1); + var nsPrefix = prefix === 'xmlns' && localName + }else{ + localName = qName; + prefix = null + nsPrefix = qName === 'xmlns' && '' + } + //can not set prefix,because prefix !== '' + a.localName = localName ; + //prefix == null for no ns prefix attribute + if(nsPrefix !== false){//hack!! + if(localNSMap == null){ + localNSMap = {} + //console.log(currentNSMap,0) + _copy(currentNSMap,currentNSMap={}) + //console.log(currentNSMap,1) + } + currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value; + a.uri = 'http://www.w3.org/2000/xmlns/' + domBuilder.startPrefixMapping(nsPrefix, value) + } + } + var i = el.length; + while(i--){ + a = el[i]; + var prefix = a.prefix; + if(prefix){//no prefix attribute has no namespace + if(prefix === 'xml'){ + a.uri = 'http://www.w3.org/XML/1998/namespace'; + }if(prefix !== 'xmlns'){ + a.uri = currentNSMap[prefix] + + //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)} + } + } + } + var nsp = tagName.indexOf(':'); + if(nsp>0){ + prefix = el.prefix = tagName.slice(0,nsp); + localName = el.localName = tagName.slice(nsp+1); + }else{ + prefix = null;//important!! + localName = el.localName = tagName; + } + //no prefix element has default namespace + var ns = el.uri = currentNSMap[prefix || '']; + domBuilder.startElement(ns,localName,tagName,el); + //endPrefixMapping and startPrefixMapping have not any help for dom builder + //localNSMap = null + if(el.closed){ + domBuilder.endElement(ns,localName,tagName); + if(localNSMap){ + for(prefix in localNSMap){ + domBuilder.endPrefixMapping(prefix) + } + } + }else{ + el.currentNSMap = currentNSMap; + el.localNSMap = localNSMap; + parseStack.push(el); + } +} +function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){ + if(/^(?:script|textarea)$/i.test(tagName)){ + var elEndStart = source.indexOf('',elStartEnd); + var text = source.substring(elStartEnd+1,elEndStart); + if(/[&<]/.test(text)){ + if(/^script$/i.test(tagName)){ + //if(!/\]\]>/.test(text)){ + //lexHandler.startCDATA(); + domBuilder.characters(text,0,text.length); + //lexHandler.endCDATA(); + return elEndStart; + //} + }//}else{//text area + text = text.replace(/&#?\w+;/g,entityReplacer); + domBuilder.characters(text,0,text.length); + return elEndStart; + //} + + } + } + return elStartEnd+1; +} +function fixSelfClosed(source,elStartEnd,tagName,closeMap){ + //if(tagName in closeMap){ + var pos = closeMap[tagName]; + if(pos == null){ + //console.log(tagName) + pos = closeMap[tagName] = source.lastIndexOf('') + } + return pos',start+4); + //append comment source.substring(4,end)//, + * and raw CDATA nodes. + * + * @param {Element} node + * @returns {Boolean} + * @api private + */ + +function shouldIgnoreNode (node) { + return node.nodeType === 3 // text + || node.nodeType === 8 // comment + || node.nodeType === 4; // cdata +} + + +/** + * Parses a Plist XML string. Returns an Object. + * + * @param {String} xml - the XML String to decode + * @returns {Mixed} the decoded value from the Plist XML + * @api public + */ + +function parse (xml) { + var doc = new DOMParser().parseFromString(xml); + if (doc.documentElement.nodeName !== 'plist') { + throw new Error('malformed document. First element should be '); + } + var plist = parsePlistXML(doc.documentElement); + + // the root node gets interpreted as an Array, + // so pull out the inner data first + if (plist.length == 1) plist = plist[0]; + + return plist; +} + +/** + * Parses a Plist XML string. Returns an Object. Takes a `callback` function. + * + * @param {String} xml - the XML String to decode + * @param {Function} callback - callback function + * @returns {Mixed} the decoded value from the Plist XML + * @api public + * @deprecated not actually async. use parse() instead + */ + +function parseString (xml, callback) { + var doc, error, plist; + try { + doc = new DOMParser().parseFromString(xml); + plist = parsePlistXML(doc.documentElement); + } catch(e) { + error = e; + } + callback(error, plist); +} + +/** + * Parses a Plist XML string. Returns an Object. + * + * @param {String} xml - the XML String to decode + * @param {Function} callback - callback function + * @returns {Mixed} the decoded value from the Plist XML + * @api public + * @deprecated use parse() instead + */ + +function parseStringSync (xml) { + var doc = new DOMParser().parseFromString(xml); + var plist; + if (doc.documentElement.nodeName !== 'plist') { + throw new Error('malformed document. First element should be '); + } + plist = parsePlistXML(doc.documentElement); + + // if the plist is an array with 1 element, pull it out of the array + if (plist.length == 1) { + plist = plist[0]; + } + return plist; +} + +/** + * Convert an XML based plist document into a JSON representation. + * + * @param {Object} xml_node - current XML node in the plist + * @returns {Mixed} built up JSON object + * @api private + */ + +function parsePlistXML (node) { + var i, new_obj, key, val, new_arr, res, d; + + if (!node) + return null; + + if (node.nodeName === 'plist') { + new_arr = []; + for (i=0; i < node.childNodes.length; i++) { + // ignore comment nodes (text) + if (!shouldIgnoreNode(node.childNodes[i])) { + new_arr.push( parsePlistXML(node.childNodes[i])); + } + } + return new_arr; + + } else if (node.nodeName === 'dict') { + new_obj = {}; + key = null; + for (i=0; i < node.childNodes.length; i++) { + // ignore comment nodes (text) + if (!shouldIgnoreNode(node.childNodes[i])) { + if (key === null) { + key = parsePlistXML(node.childNodes[i]); + } else { + new_obj[key] = parsePlistXML(node.childNodes[i]); + key = null; + } + } + } + return new_obj; + + } else if (node.nodeName === 'array') { + new_arr = []; + for (i=0; i < node.childNodes.length; i++) { + // ignore comment nodes (text) + if (!shouldIgnoreNode(node.childNodes[i])) { + res = parsePlistXML(node.childNodes[i]); + if (null != res) new_arr.push(res); + } + } + return new_arr; + + } else if (node.nodeName === '#text') { + // TODO: what should we do with text types? (CDATA sections) + + } else if (node.nodeName === 'key') { + return node.childNodes[0].nodeValue; + + } else if (node.nodeName === 'string') { + res = ''; + for (d=0; d < node.childNodes.length; d++) { + res += node.childNodes[d].nodeValue; + } + return res; + + } else if (node.nodeName === 'integer') { + // parse as base 10 integer + return parseInt(node.childNodes[0].nodeValue, 10); + + } else if (node.nodeName === 'real') { + res = ''; + for (d=0; d < node.childNodes.length; d++) { + if (node.childNodes[d].nodeType === 3) { + res += node.childNodes[d].nodeValue; + } + } + return parseFloat(res); + + } else if (node.nodeName === 'data') { + res = ''; + for (d=0; d < node.childNodes.length; d++) { + if (node.childNodes[d].nodeType === 3) { + res += node.childNodes[d].nodeValue.replace(/\s+/g, ''); + } + } + + // decode base64 data to a Buffer instance + return new Buffer(res, 'base64'); + + } else if (node.nodeName === 'date') { + return new Date(node.childNodes[0].nodeValue); + + } else if (node.nodeName === 'true') { + return true; + + } else if (node.nodeName === 'false') { + return false; + } +} diff --git a/platforms/android/cordova/node_modules/plist/lib/plist.js b/platforms/android/cordova/node_modules/plist/lib/plist.js new file mode 100644 index 0000000..00a4167 --- /dev/null +++ b/platforms/android/cordova/node_modules/plist/lib/plist.js @@ -0,0 +1,23 @@ + +var i; + +/** + * Parser functions. + */ + +var parserFunctions = require('./parse'); +for (i in parserFunctions) exports[i] = parserFunctions[i]; + +/** + * Builder functions. + */ + +var builderFunctions = require('./build'); +for (i in builderFunctions) exports[i] = builderFunctions[i]; + +/** + * Add Node.js-specific functions (they're deprecated…). + */ + +var nodeFunctions = require('./node'); +for (i in nodeFunctions) exports[i] = nodeFunctions[i]; diff --git a/platforms/android/cordova/node_modules/plist/package.json b/platforms/android/cordova/node_modules/plist/package.json new file mode 100644 index 0000000..dddb405 --- /dev/null +++ b/platforms/android/cordova/node_modules/plist/package.json @@ -0,0 +1,117 @@ +{ + "_args": [ + [ + "plist@^1.2.0", + "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common" + ] + ], + "_from": "plist@>=1.2.0 <2.0.0", + "_id": "plist@1.2.0", + "_inCache": true, + "_installable": true, + "_location": "/plist", + "_nodeVersion": "5.0.0", + "_npmUser": { + "email": "reinstein.mike@gmail.com", + "name": "mreinstein" + }, + "_npmVersion": "3.3.11", + "_phantomChildren": {}, + "_requested": { + "name": "plist", + "raw": "plist@^1.2.0", + "rawSpec": "^1.2.0", + "scope": null, + "spec": ">=1.2.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/cordova-common" + ], + "_resolved": "http://registry.npmjs.org/plist/-/plist-1.2.0.tgz", + "_shasum": "084b5093ddc92506e259f874b8d9b1afb8c79593", + "_shrinkwrap": null, + "_spec": "plist@^1.2.0", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common", + "author": { + "email": "nathan@tootallnate.net", + "name": "Nathan Rajlich" + }, + "bugs": { + "url": "https://github.com/TooTallNate/node-plist/issues" + }, + "contributors": [ + { + "name": "Hans Huebner", + "email": "hans.huebner@gmail.com" + }, + { + "name": "Pierre Metrailler" + }, + { + "name": "Mike Reinstein", + "email": "reinstein.mike@gmail.com" + }, + { + "name": "Vladimir Tsvang" + }, + { + "name": "Mathieu D'Amours" + } + ], + "dependencies": { + "base64-js": "0.0.8", + "util-deprecate": "1.0.2", + "xmlbuilder": "4.0.0", + "xmldom": "0.1.x" + }, + "description": "Mac OS X Plist parser/builder for Node.js and browsers", + "devDependencies": { + "browserify": "12.0.1", + "mocha": "2.3.3", + "multiline": "1.0.2", + "zuul": "3.7.2" + }, + "directories": {}, + "dist": { + "shasum": "084b5093ddc92506e259f874b8d9b1afb8c79593", + "tarball": "http://registry.npmjs.org/plist/-/plist-1.2.0.tgz" + }, + "gitHead": "69520574f27864145192338b72e608fbe1bda6f7", + "homepage": "https://github.com/TooTallNate/node-plist#readme", + "keywords": [ + "apple", + "browser", + "mac", + "parser", + "plist", + "xml" + ], + "license": "MIT", + "main": "lib/plist.js", + "maintainers": [ + { + "name": "TooTallNate", + "email": "nathan@tootallnate.net" + }, + { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + }, + { + "name": "mreinstein", + "email": "reinstein.mike@gmail.com" + } + ], + "name": "plist", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/TooTallNate/node-plist.git" + }, + "scripts": { + "test": "make test" + }, + "version": "1.2.0" +} diff --git a/platforms/android/cordova/node_modules/properties-parser/README.markdown b/platforms/android/cordova/node_modules/properties-parser/README.markdown new file mode 100644 index 0000000..3a808ba --- /dev/null +++ b/platforms/android/cordova/node_modules/properties-parser/README.markdown @@ -0,0 +1,48 @@ +# node-properties-parser + +A parser for [.properties](http://en.wikipedia.org/wiki/.properties) files written in javascript. Properties files store key-value pairs. They are typically used for configuration and internationalization in Java applications as well as in Actionscript projects. Here's an example of the format: + + # You are reading the ".properties" entry. + ! The exclamation mark can also mark text as comments. + website = http://en.wikipedia.org/ + language = English + # The backslash below tells the application to continue reading + # the value onto the next line. + message = Welcome to \ + Wikipedia! + # Add spaces to the key + key\ with\ spaces = This is the value that could be looked up with the key "key with spaces". + # Unicode + tab : \u0009 +*(taken from [Wikipedia](http://en.wikipedia.org/wiki/.properties#Format))* + +Currently works with any version of node.js. + +## The API + +- `parse(text)`: Parses `text` into key-value pairs. Returns an object containing the key-value pairs. +- `read(path[, callback])`: Opens the file specified by `path` and calls `parse` on its content. If the optional `callback` parameter is provided, the result is then passed to it as the second parameter. If an error occurs, the error object is passed to `callback` as the first parameter. If `callback` is not provided, the file specified by `path` is synchronously read and calls `parse` on its contents. The resulting object is immediately returned. +- `createEditor([path[, callback]])`: If neither `path` or `callback` are provided an empty editor object is returned synchronously. If only `path` is provided, the file specified by `path` is synchronously read and parsed. An editor object with the results in then immediately returned. If both `path` and `callback` are provided, the file specified by `path` is read and parsed asynchronously. An editor object with the results are then passed to `callback` as the second parameters. If an error occurs, the error object is passed to `callback` as the first parameter. +- `Editor`: The editor object is returned by `createEditor`. Has the following API: + - `get(key)`: Returns the value currently associated with `key`. + - `set(key, [value[, comment]])`: Associates `key` with `value`. An optional comment can be provided. If `value` is not specified or is `null`, then `key` is unset. + - `unset(key)`: Unsets the specified `key`. + - `save([path][, callback]])`: Writes the current contents of this editor object to a file specified by `path`. If `path` is not provided, then it'll be defaulted to the `path` value passed to `createEditor`. The `callback` parameter is called when the file has been written to disk. + - `addHeadComment`: Added a comment to the head of the file. + - `toString`: Returns the string representation of this properties editor object. This string will be written to a file if `save` is called. + +## Getting node-properties-parser + +The easiest way to get node-properties-parser is with [npm](http://npmjs.org/): + + npm install properties-parser + +Alternatively you can clone this git repository: + + git://github.com/xavi-/node-properties-parser.git + +## Developed by +* Xavi Ramirez + +## License +This project is released under [The MIT License](http://www.opensource.org/licenses/mit-license.php). \ No newline at end of file diff --git a/platforms/android/cordova/node_modules/properties-parser/index.js b/platforms/android/cordova/node_modules/properties-parser/index.js new file mode 100644 index 0000000..b103ad0 --- /dev/null +++ b/platforms/android/cordova/node_modules/properties-parser/index.js @@ -0,0 +1,354 @@ +var fs = require("fs"); + +function Iterator(text) { + var pos = 0, length = text.length; + + this.peek = function(num) { + num = num || 0; + if(pos + num >= length) { return null; } + + return text.charAt(pos + num); + }; + this.next = function(inc) { + inc = inc || 1; + + if(pos >= length) { return null; } + + return text.charAt((pos += inc) - inc); + }; + this.pos = function() { + return pos; + }; +} + +var rWhitespace = /\s/; +function isWhitespace(chr) { + return rWhitespace.test(chr); +} +function consumeWhiteSpace(iter) { + var start = iter.pos(); + + while(isWhitespace(iter.peek())) { iter.next(); } + + return { type: "whitespace", start: start, end: iter.pos() }; +} + +function startsComment(chr) { + return chr === "!" || chr === "#"; +} +function isEOL(chr) { + return chr == null || chr === "\n" || chr === "\r"; +} +function consumeComment(iter) { + var start = iter.pos(); + + while(!isEOL(iter.peek())) { iter.next(); } + + return { type: "comment", start: start, end: iter.pos() }; +} + +function startsKeyVal(chr) { + return !isWhitespace(chr) && !startsComment(chr); +} +function startsSeparator(chr) { + return chr === "=" || chr === ":" || isWhitespace(chr); +} +function startsEscapedVal(chr) { + return chr === "\\"; +} +function consumeEscapedVal(iter) { + var start = iter.pos(); + + iter.next(); // move past "\" + var curChar = iter.next(); + if(curChar === "u") { // encoded unicode char + iter.next(4); // Read in the 4 hex values + } + + return { type: "escaped-value", start: start, end: iter.pos() }; +} +function consumeKey(iter) { + var start = iter.pos(), children = []; + + var curChar; + while((curChar = iter.peek()) !== null) { + if(startsSeparator(curChar)) { break; } + if(startsEscapedVal(curChar)) { children.push(consumeEscapedVal(iter)); continue; } + + iter.next(); + } + + return { type: "key", start: start, end: iter.pos(), children: children }; +} +function consumeKeyValSeparator(iter) { + var start = iter.pos(); + + var seenHardSep = false, curChar; + while((curChar = iter.peek()) !== null) { + if(isEOL(curChar)) { break; } + + if(isWhitespace(curChar)) { iter.next(); continue; } + + if(seenHardSep) { break; } + + seenHardSep = (curChar === ":" || curChar === "="); + if(seenHardSep) { iter.next(); continue; } + + break; // curChar is a non-separtor char + } + + return { type: "key-value-separator", start: start, end: iter.pos() }; +} +function startsLineBreak(iter) { + return iter.peek() === "\\" && isEOL(iter.peek(1)); +} +function consumeLineBreak(iter) { + var start = iter.pos(); + + iter.next(); // consume \ + if(iter.peek() === "\r") { iter.next(); } + iter.next(); // consume \n + + var curChar; + while((curChar = iter.peek()) !== null) { + if(isEOL(curChar)) { break; } + if(!isWhitespace(curChar)) { break; } + + iter.next(); + } + + return { type: "line-break", start: start, end: iter.pos() }; +} +function consumeVal(iter) { + var start = iter.pos(), children = []; + + var curChar; + while((curChar = iter.peek()) !== null) { + if(startsLineBreak(iter)) { children.push(consumeLineBreak(iter)); continue; } + if(startsEscapedVal(curChar)) { children.push(consumeEscapedVal(iter)); continue; } + if(isEOL(curChar)) { break; } + + iter.next(); + } + + return { type: "value", start: start, end: iter.pos(), children: children }; +} +function consumeKeyVal(iter) { + return { + type: "key-value", + start: iter.pos(), + children: [ + consumeKey(iter), + consumeKeyValSeparator(iter), + consumeVal(iter) + ], + end: iter.pos() + }; +} + +var renderChild = { + "escaped-value": function(child, text) { + var type = text.charAt(child.start + 1); + + if(type === "t") { return "\t"; } + if(type === "r") { return "\r"; } + if(type === "n") { return "\n"; } + if(type === "f") { return "\f"; } + if(type !== "u") { return type; } + + return String.fromCharCode(parseInt(text.substr(child.start + 2, 4), 16)); + }, + "line-break": function (child, text) { + return ""; + } +}; +function rangeToBuffer(range, text) { + var start = range.start, buffer = []; + + for(var i = 0; i < range.children.length; i++) { + var child = range.children[i]; + + buffer.push(text.substring(start, child.start)); + buffer.push(renderChild[child.type](child, text)); + start = child.end; + } + buffer.push(text.substring(start, range.end)); + + return buffer; +} +function rangesToObject(ranges, text) { + var obj = Object.create(null); // Creates to a true hash map + + for(var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + + if(range.type !== "key-value") { continue; } + + var key = rangeToBuffer(range.children[0], text).join(""); + var val = rangeToBuffer(range.children[2], text).join(""); + obj[key] = val; + } + + return obj; +} + +function stringToRanges(text) { + var iter = new Iterator(text), ranges = []; + + var curChar; + while((curChar = iter.peek()) !== null) { + if(isWhitespace(curChar)) { ranges.push(consumeWhiteSpace(iter)); continue; } + if(startsComment(curChar)) { ranges.push(consumeComment(iter)); continue; } + if(startsKeyVal(curChar)) { ranges.push(consumeKeyVal(iter)); continue; } + + throw Error("Something crazy happened. text: '" + text + "'; curChar: '" + curChar + "'"); + } + + return ranges; +} + +function isNewLineRange(range) { + if(!range) { return false; } + + if(range.type === "whitespace") { return true; } + + if(range.type === "literal") { + return isWhitespace(range.text) && range.text.indexOf("\n") > -1; + } + + return false; +} + +function Editor(text, path) { + text = text || ""; + + var ranges = stringToRanges(text); + var obj = rangesToObject(ranges, text); + var keyRange = Object.create(null); // Creates to a true hash map + + for(var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + + if(range.type !== "key-value") { continue; } + + var key = rangeToBuffer(range.children[0], text).join(""); + keyRange[key] = range; + } + + this.addHeadComment = function(comment) { + if(comment == null) { return; } + + ranges.unshift({ type: "literal", text: "# " + comment.replace(/\n/g, "\n# ") + "\n" }); + }; + + this.get = function(key) { return obj[key]; }; + this.set = function(key, val, comment) { + if(val == null) { this.unset(key); return; } + + obj[key] = val; + + var range = keyRange[key]; + if(!range) { + keyRange[key] = range = { type: "literal", text: key + "=" + val }; + + var prevRange = ranges[ranges.length - 1]; + if(prevRange != null && !isNewLineRange(prevRange)) { + ranges.push({ type: "literal", text: "\n" }); + } + ranges.push(range); + } + + // comment === null deletes comment. if comment === undefined, it's left alone + if(comment !== undefined) { + range.comment = comment && "# " + comment.replace(/\n/g, "\n# ") + "\n"; + } + + if(range.type === "literal") { + range.text = key + "=" + val; + if(range.comment != null) { range.text = range.comment + range.text; } + } else if(range.type === "key-value") { + range.children[2] = { type: "literal", text: val }; + } else { + throw "Unknown node type: " + range.type; + } + }; + this.unset = function(key) { + if(!(key in obj)) { return; } + + var range = keyRange[key]; + var idx = ranges.indexOf(range); + + ranges.splice(idx, (isNewLineRange(ranges[idx + 1]) ? 2 : 1)); + + delete keyRange[key]; + delete obj[key]; + }; + this.valueOf = this.toString = function() { + var buffer = [], stack = [].concat(ranges); + + var node; + while((node = stack.shift()) != null) { + switch(node.type) { + case "literal": + buffer.push(node.text); + break; + case "key": + case "value": + case "comment": + case "whitespace": + case "key-value-separator": + case "escaped-value": + case "line-break": + buffer.push(text.substring(node.start, node.end)); + break; + case "key-value": + Array.prototype.unshift.apply(stack, node.children); + if(node.comment) { stack.unshift({ type: "literal", text: node.comment }); } + break; + } + } + + return buffer.join(""); + }; + this.save = function(newPath, callback) { + if(typeof newPath === 'function') { + callback = newPath; + newPath = path; + } + newPath = newPath || path; + + if(!newPath) { callback("Unknown path"); } + + fs.writeFile(newPath, this.toString(), callback || function() {}); + }; +} +function createEditor(path, callback) { + if(!path) { return new Editor(); } + + if(!callback) { return new Editor(fs.readFileSync(path).toString(), path); } + + return fs.readFile(path, function(err, text) { + if(err) { return callback(err, null); } + + text = text.toString(); + return callback(null, new Editor(text, path)); + }); +} + +function parse(text) { + text = text.toString(); + var ranges = stringToRanges(text); + return rangesToObject(ranges, text); +} + +function read(path, callback) { + if(!callback) { return parse(fs.readFileSync(path)); } + + return fs.readFile(path, function(err, data) { + if(err) { return callback(err, null); } + + return callback(null, parse(data)); + }); +} + +module.exports = { parse: parse, read: read, createEditor: createEditor }; diff --git a/platforms/android/cordova/node_modules/properties-parser/package.json b/platforms/android/cordova/node_modules/properties-parser/package.json new file mode 100644 index 0000000..b089b27 --- /dev/null +++ b/platforms/android/cordova/node_modules/properties-parser/package.json @@ -0,0 +1,73 @@ +{ + "_args": [ + [ + "properties-parser@^0.2.3", + "/Users/steveng/repo/cordova/cordova-android" + ] + ], + "_from": "properties-parser@>=0.2.3 <0.3.0", + "_id": "properties-parser@0.2.3", + "_inCache": true, + "_installable": true, + "_location": "/properties-parser", + "_npmUser": { + "email": "xavi.rmz@gmail.com", + "name": "xavi" + }, + "_npmVersion": "1.3.23", + "_phantomChildren": {}, + "_requested": { + "name": "properties-parser", + "raw": "properties-parser@^0.2.3", + "rawSpec": "^0.2.3", + "scope": null, + "spec": ">=0.2.3 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "http://registry.npmjs.org/properties-parser/-/properties-parser-0.2.3.tgz", + "_shasum": "f7591255f707abbff227c7b56b637dbb0373a10f", + "_shrinkwrap": null, + "_spec": "properties-parser@^0.2.3", + "_where": "/Users/steveng/repo/cordova/cordova-android", + "bugs": { + "url": "https://github.com/xavi-/node-properties-parser/issues" + }, + "dependencies": {}, + "description": "A parser for .properties files written in javascript", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "f7591255f707abbff227c7b56b637dbb0373a10f", + "tarball": "http://registry.npmjs.org/properties-parser/-/properties-parser-0.2.3.tgz" + }, + "engines": { + "node": ">= 0.3.1" + }, + "homepage": "https://github.com/xavi-/node-properties-parser", + "keywords": [ + ".properties", + "actionscript", + "file parser", + "java", + "parser", + "properties" + ], + "main": "./index.js", + "maintainers": [ + { + "name": "xavi", + "email": "xavi.rmz@gmail.com" + } + ], + "name": "properties-parser", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/xavi-/node-properties-parser.git" + }, + "version": "0.2.3" +} diff --git a/platforms/android/cordova/node_modules/properties-parser/play-ground.js b/platforms/android/cordova/node_modules/properties-parser/play-ground.js new file mode 100644 index 0000000..ffbcf62 --- /dev/null +++ b/platforms/android/cordova/node_modules/properties-parser/play-ground.js @@ -0,0 +1,17 @@ +var parser = require("./"); +var editor = parser.createEditor(); + +editor.set("ok", "hi"); +editor.set("hi", "ok"); + +console.log(editor.toString()); + +editor.unset("hi"); + +console.log("==================="); +console.log(editor.toString()); + +editor.unset("ok"); + +console.log("==================="); +console.log(editor.toString()); diff --git a/platforms/android/cordova/node_modules/properties-parser/test/ReadProperties.class b/platforms/android/cordova/node_modules/properties-parser/test/ReadProperties.class new file mode 100755 index 0000000..f40792b Binary files /dev/null and b/platforms/android/cordova/node_modules/properties-parser/test/ReadProperties.class differ diff --git a/platforms/android/cordova/node_modules/properties-parser/test/ReadProperties.java b/platforms/android/cordova/node_modules/properties-parser/test/ReadProperties.java new file mode 100644 index 0000000..12e4472 --- /dev/null +++ b/platforms/android/cordova/node_modules/properties-parser/test/ReadProperties.java @@ -0,0 +1,61 @@ +import java.io.*; +import java.util.*; + +public class ReadProperties { + public static void main(String[] args) throws IOException { + if(args.length <= 0) { System.out.println("No file provided."); return; } + + File f = new File(args[0]); + + if(!f.exists()) { System.out.println("File not found: " + args[0]); return; } + + Properties prop = new Properties(); + prop.load(new FileInputStream(f)); + + boolean isFirst = true; // I fucking hate java, why don't they have a native string join function? + System.out.print("{"); + for (Map.Entry item : prop.entrySet()) { + String key = (String) item.getKey(); + String value = (String) item.getValue(); + + if(isFirst) { isFirst = false; } + else { System.out.print(","); } + + System.out.print("\"" + escape(key) + "\":\"" + escape(value) + "\""); + } + System.out.print("}"); + } + + static String escape(String s) { // Taken from http://code.google.com/p/json-simple/ + StringBuffer sb = new StringBuffer(); + for(int i = 0; i < s.length(); i++) { + char ch = s.charAt(i); + switch(ch) { + case '"': sb.append("\\\""); break; + case '\\': sb.append("\\\\"); break; + case '\b': sb.append("\\b"); break; + case '\f': sb.append("\\f"); break; + case '\n': sb.append("\\n"); break; + case '\r': sb.append("\\r"); break; + case '\t': sb.append("\\t"); break; + case '/': sb.append("\\/"); break; + default: + //Reference: http://www.unicode.org/versions/Unicode5.1.0/ + if (('\u0000' <= ch && ch <= '\u001F') + || ('\u007F' <= ch && ch <= '\u009F') + || ('\u2000' <= ch && ch <= '\u20FF')) { + String ss = Integer.toHexString(ch); + sb.append("\\u"); + for(int k = ss.length(); k < 4; k++) { + sb.append('0'); + } + sb.append(ss.toUpperCase()); + } else { + sb.append(ch); + } + } + } + + return sb.toString(); + } +} \ No newline at end of file diff --git a/platforms/android/cordova/node_modules/properties-parser/test/test-cases-copy.properties b/platforms/android/cordova/node_modules/properties-parser/test/test-cases-copy.properties new file mode 100644 index 0000000..04b8ecd --- /dev/null +++ b/platforms/android/cordova/node_modules/properties-parser/test/test-cases-copy.properties @@ -0,0 +1,16 @@ +# You are reading the ".properties" entry. +! The exclamation mark can also mark text as comments. +lala=whatever +website = whatever +language = whatever +# The backslash below tells the application to continue reading +# the value onto the next line. +message = whatever +# Add spaces to the key +key\ with\ spaces = whatever +# Unicode +tab : whatever +long-unicode : whatever +space\ separator key val \n three +another-test :whatever + null-prop \ No newline at end of file diff --git a/platforms/android/cordova/node_modules/properties-parser/test/test-cases.properties b/platforms/android/cordova/node_modules/properties-parser/test/test-cases.properties new file mode 100644 index 0000000..5fc5bb7 --- /dev/null +++ b/platforms/android/cordova/node_modules/properties-parser/test/test-cases.properties @@ -0,0 +1,18 @@ +# You are reading the ".properties" entry. +! The exclamation mark can also mark text as comments. +lala=\u210A the foo foo \ + lalala; +website = http://en.wikipedia.org/ +language = English +# The backslash below tells the application to continue reading +# the value onto the next line. +message = Welcome to \ + Wikipedia! +# Add spaces to the key +key\ with\ spaces = This is the value that could be looked up with the key "key with spaces". +# Unicode +tab : \u0009 +long-unicode : \u00000009 +space\ separator key val \n three +another-test ::: hihi + null-prop \ No newline at end of file diff --git a/platforms/android/cordova/node_modules/properties-parser/test/test.js b/platforms/android/cordova/node_modules/properties-parser/test/test.js new file mode 100644 index 0000000..4b7b531 --- /dev/null +++ b/platforms/android/cordova/node_modules/properties-parser/test/test.js @@ -0,0 +1,123 @@ +var fs = require("fs"); +var assert = require("assert"); +var prop = require("../index.js"); + +var syncData = prop.read("./test-cases.properties"); +prop.read("./test-cases.properties", function(err, data) { + assert.deepEqual(data, syncData); + assert.equal(data["lala"], 'ℊ the foo foo lalala;'); + assert.equal(data["website"], 'http://en.wikipedia.org/'); + assert.equal(data["language"], 'English'); + assert.equal(data["message"], 'Welcome to Wikipedia!'); + assert.equal(data["key with spaces"], 'This is the value that could be looked up with the key "key with spaces".'); + assert.equal(data["tab"], '\t'); + assert.equal(data["long-unicode"], '\u00000009'); + assert.equal(data["space separator"], 'key val \n three'); + assert.equal(data["another-test"], ':: hihi'); + assert.equal(data["null-prop"], ''); + assert.ok(data["valueOf"] == null, "Properties are set that shouldn't be (valueOf)"); + assert.ok(data["toString"] == null, "Properties are set that shouldn't be (toString)"); + + console.log("Tests all passed..."); + + if(process.argv[2] === "repl") { + var repl = require("repl").start("test-repl> "); + repl.context.data = data; + repl.context.prop = prop; + } +}); + +var editor1 = prop.createEditor(); +editor1.set("basic", "prop1"); +assert.equal(editor1.toString(), "basic=prop1"); +editor1.set("basic", "prop2", "A comment\nmulti-line1"); +assert.equal(editor1.toString(), "# A comment\n# multi-line1\nbasic=prop2"); +editor1.set("basic", "prop3", "A comment\nmulti-line2"); +assert.equal(editor1.toString(), "# A comment\n# multi-line2\nbasic=prop3"); +editor1.set("basic", "prop4"); +assert.equal(editor1.toString(), "# A comment\n# multi-line2\nbasic=prop4"); +editor1.set("basic", "prop5", null); // Delete's comment +assert.equal(editor1.toString(), "basic=prop5"); +editor1.set("basic1", "prop6"); +assert.equal(editor1.toString(), "basic=prop5\nbasic1=prop6"); +editor1.addHeadComment("Head Comment"); +assert.equal(editor1.toString(), "# Head Comment\nbasic=prop5\nbasic1=prop6"); +assert.ok(editor1.get("valueOf") == null); +assert.ok(editor1.get("toString") == null); + +var editor2 = prop.createEditor("./test-cases.properties"); +assert.equal(fs.readFileSync("./test-cases.properties").toString(), editor2.toString()); +editor2.set("lala", "prop1"); +assert.ok(editor2.toString().indexOf("lala=prop1") > -1); +editor2.set("lala", "prop2", "A comment\nmulti-line1"); +assert.ok(editor2.toString().indexOf("# A comment\n# multi-line1\nlala=prop2") > -1); +editor2.set("lala", "prop3", "A comment\nmulti-line2"); +assert.ok(editor2.toString().indexOf("# A comment\n# multi-line2\nlala=prop3") > -1); +editor2.set("lala", "prop4"); +assert.ok(editor2.toString().indexOf("# A comment\n# multi-line2\nlala=prop4") > -1); +editor2.set("lala", "prop5", null); // Delete's comment +assert.ok(editor2.toString().indexOf("! The exclamation mark can also mark text as comments.\nlala=prop5") > -1); +editor2.set("basic-non-existing", "prop6"); +assert.ok(editor2.toString().indexOf("\nbasic-non-existing=prop6") > -1); +editor2.addHeadComment("Head Comment"); +assert.equal(editor2.toString().indexOf("# Head Comment\n"), 0); +assert.ok(editor2.get("valueOf") == null); +assert.ok(editor2.get("toString") == null); + +var editor3 = prop.createEditor(); +editor3.set("stay", "ok"); + +editor3.unset("key"); +editor3.unset("key", null); +editor3.unset("key", undefined); +assert.equal(editor3.toString().trim(), "stay=ok"); + +editor3.set("key", "val"); +editor3.unset("key"); +assert.equal(editor3.toString().trim(), "stay=ok"); + +editor3.set("key", "val"); +editor3.set("key", null); +assert.equal(editor3.toString().trim(), "stay=ok"); + +editor3.set("key", "val"); +editor3.set("key", undefined); +assert.equal(editor3.toString().trim(), "stay=ok"); + +prop.createEditor("./test-cases.properties", function(err, editor) { + var properties = {}; + properties.lala = 'whatever'; + properties.website = 'whatever'; + properties.language = 'whatever'; + properties.message = 'whatever'; + properties['key with spaces'] = 'whatever'; + properties.tab = 'whatever'; + properties['long-unicode'] = 'whatever'; + properties['another-test'] = 'whatever'; + for (var item in properties) { + editor.set(item, properties[item]); + } + + assert.equal( + editor.toString(), + '# You are reading the ".properties" entry.\n' + + '! The exclamation mark can also mark text as comments.\n' + + 'lala=whatever\n' + + 'website = whatever\n' + + 'language = whatever\n' + + '# The backslash below tells the application to continue reading\n' + + '# the value onto the next line.\n' + + 'message = whatever\n' + + '# Add spaces to the key\n' + + 'key\\ with\\ spaces = whatever\n' + + '# Unicode\n' + + 'tab : whatever\n' + + 'long-unicode : whatever\n' + + 'space\\ separator key val \\n three\n' + + 'another-test :whatever\n' + + ' null-prop' + ); +}); + +// java ReadProperties test-cases.properties +// javac ReadProperties.java \ No newline at end of file diff --git a/platforms/android/cordova/node_modules/q/CHANGES.md b/platforms/android/cordova/node_modules/q/CHANGES.md new file mode 100644 index 0000000..cd351fd --- /dev/null +++ b/platforms/android/cordova/node_modules/q/CHANGES.md @@ -0,0 +1,786 @@ + +## 1.4.1 + + - Address an issue that prevented Q from being used as a ` + + diff --git a/platforms/android/cordova/node_modules/sax/examples/test.xml b/platforms/android/cordova/node_modules/sax/examples/test.xml new file mode 100644 index 0000000..801292d --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/examples/test.xml @@ -0,0 +1,1254 @@ + + +]> + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + \ No newline at end of file diff --git a/platforms/android/cordova/node_modules/sax/lib/sax.js b/platforms/android/cordova/node_modules/sax/lib/sax.js new file mode 100644 index 0000000..17fb08e --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/lib/sax.js @@ -0,0 +1,1006 @@ +// wrapper for non-node envs +;(function (sax) { + +sax.parser = function (strict, opt) { return new SAXParser(strict, opt) } +sax.SAXParser = SAXParser +sax.SAXStream = SAXStream +sax.createStream = createStream + +// When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns. +// When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)), +// since that's the earliest that a buffer overrun could occur. This way, checks are +// as rare as required, but as often as necessary to ensure never crossing this bound. +// Furthermore, buffers are only tested at most once per write(), so passing a very +// large string into write() might have undesirable effects, but this is manageable by +// the caller, so it is assumed to be safe. Thus, a call to write() may, in the extreme +// edge case, result in creating at most one complete copy of the string passed in. +// Set to Infinity to have unlimited buffers. +sax.MAX_BUFFER_LENGTH = 64 * 1024 + +var buffers = [ + "comment", "sgmlDecl", "textNode", "tagName", "doctype", + "procInstName", "procInstBody", "entity", "attribName", + "attribValue", "cdata", "script" +] + +sax.EVENTS = // for discoverability. + [ "text" + , "processinginstruction" + , "sgmldeclaration" + , "doctype" + , "comment" + , "attribute" + , "opentag" + , "closetag" + , "opencdata" + , "cdata" + , "closecdata" + , "error" + , "end" + , "ready" + , "script" + , "opennamespace" + , "closenamespace" + ] + +function SAXParser (strict, opt) { + if (!(this instanceof SAXParser)) return new SAXParser(strict, opt) + + var parser = this + clearBuffers(parser) + parser.q = parser.c = "" + parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH + parser.opt = opt || {} + parser.tagCase = parser.opt.lowercasetags ? "toLowerCase" : "toUpperCase" + parser.tags = [] + parser.closed = parser.closedRoot = parser.sawRoot = false + parser.tag = parser.error = null + parser.strict = !!strict + parser.noscript = !!(strict || parser.opt.noscript) + parser.state = S.BEGIN + parser.ENTITIES = Object.create(sax.ENTITIES) + parser.attribList = [] + + // namespaces form a prototype chain. + // it always points at the current tag, + // which protos to its parent tag. + if (parser.opt.xmlns) parser.ns = Object.create(rootNS) + + // mostly just for error reporting + parser.position = parser.line = parser.column = 0 + emit(parser, "onready") +} + +if (!Object.create) Object.create = function (o) { + function f () { this.__proto__ = o } + f.prototype = o + return new f +} + +if (!Object.getPrototypeOf) Object.getPrototypeOf = function (o) { + return o.__proto__ +} + +if (!Object.keys) Object.keys = function (o) { + var a = [] + for (var i in o) if (o.hasOwnProperty(i)) a.push(i) + return a +} + +function checkBufferLength (parser) { + var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10) + , maxActual = 0 + for (var i = 0, l = buffers.length; i < l; i ++) { + var len = parser[buffers[i]].length + if (len > maxAllowed) { + // Text/cdata nodes can get big, and since they're buffered, + // we can get here under normal conditions. + // Avoid issues by emitting the text node now, + // so at least it won't get any bigger. + switch (buffers[i]) { + case "textNode": + closeText(parser) + break + + case "cdata": + emitNode(parser, "oncdata", parser.cdata) + parser.cdata = "" + break + + case "script": + emitNode(parser, "onscript", parser.script) + parser.script = "" + break + + default: + error(parser, "Max buffer length exceeded: "+buffers[i]) + } + } + maxActual = Math.max(maxActual, len) + } + // schedule the next check for the earliest possible buffer overrun. + parser.bufferCheckPosition = (sax.MAX_BUFFER_LENGTH - maxActual) + + parser.position +} + +function clearBuffers (parser) { + for (var i = 0, l = buffers.length; i < l; i ++) { + parser[buffers[i]] = "" + } +} + +SAXParser.prototype = + { end: function () { end(this) } + , write: write + , resume: function () { this.error = null; return this } + , close: function () { return this.write(null) } + , end: function () { return this.write(null) } + } + +try { + var Stream = require("stream").Stream +} catch (ex) { + var Stream = function () {} +} + + +var streamWraps = sax.EVENTS.filter(function (ev) { + return ev !== "error" && ev !== "end" +}) + +function createStream (strict, opt) { + return new SAXStream(strict, opt) +} + +function SAXStream (strict, opt) { + if (!(this instanceof SAXStream)) return new SAXStream(strict, opt) + + Stream.apply(me) + + this._parser = new SAXParser(strict, opt) + this.writable = true + this.readable = true + + + var me = this + + this._parser.onend = function () { + me.emit("end") + } + + this._parser.onerror = function (er) { + me.emit("error", er) + + // if didn't throw, then means error was handled. + // go ahead and clear error, so we can write again. + me._parser.error = null + } + + streamWraps.forEach(function (ev) { + Object.defineProperty(me, "on" + ev, { + get: function () { return me._parser["on" + ev] }, + set: function (h) { + if (!h) { + me.removeAllListeners(ev) + return me._parser["on"+ev] = h + } + me.on(ev, h) + }, + enumerable: true, + configurable: false + }) + }) +} + +SAXStream.prototype = Object.create(Stream.prototype, + { constructor: { value: SAXStream } }) + +SAXStream.prototype.write = function (data) { + this._parser.write(data.toString()) + this.emit("data", data) + return true +} + +SAXStream.prototype.end = function (chunk) { + if (chunk && chunk.length) this._parser.write(chunk.toString()) + this._parser.end() + return true +} + +SAXStream.prototype.on = function (ev, handler) { + var me = this + if (!me._parser["on"+ev] && streamWraps.indexOf(ev) !== -1) { + me._parser["on"+ev] = function () { + var args = arguments.length === 1 ? [arguments[0]] + : Array.apply(null, arguments) + args.splice(0, 0, ev) + me.emit.apply(me, args) + } + } + + return Stream.prototype.on.call(me, ev, handler) +} + + + +// character classes and tokens +var whitespace = "\r\n\t " + // this really needs to be replaced with character classes. + // XML allows all manner of ridiculous numbers and digits. + , number = "0124356789" + , letter = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + // (Letter | "_" | ":") + , nameStart = letter+"_:" + , nameBody = nameStart+number+"-." + , quote = "'\"" + , entity = number+letter+"#" + , attribEnd = whitespace + ">" + , CDATA = "[CDATA[" + , DOCTYPE = "DOCTYPE" + , XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace" + , XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/" + , rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE } + +// turn all the string character sets into character class objects. +whitespace = charClass(whitespace) +number = charClass(number) +letter = charClass(letter) +nameStart = charClass(nameStart) +nameBody = charClass(nameBody) +quote = charClass(quote) +entity = charClass(entity) +attribEnd = charClass(attribEnd) + +function charClass (str) { + return str.split("").reduce(function (s, c) { + s[c] = true + return s + }, {}) +} + +function is (charclass, c) { + return charclass[c] +} + +function not (charclass, c) { + return !charclass[c] +} + +var S = 0 +sax.STATE = +{ BEGIN : S++ +, TEXT : S++ // general stuff +, TEXT_ENTITY : S++ // & and such. +, OPEN_WAKA : S++ // < +, SGML_DECL : S++ // +, SCRIPT : S++ // " + , expect : + [ [ "opentag", { name: "xml", attributes: {} } ] + , [ "opentag", { name: "script", attributes: {} } ] + , [ "text", "hello world" ] + , [ "closetag", "script" ] + , [ "closetag", "xml" ] + ] + , strict : false + , opt : { lowercasetags: true, noscript: true } + } + ) + +require(__dirname).test + ( { xml : "" + , expect : + [ [ "opentag", { name: "xml", attributes: {} } ] + , [ "opentag", { name: "script", attributes: {} } ] + , [ "opencdata", undefined ] + , [ "cdata", "hello world" ] + , [ "closecdata", undefined ] + , [ "closetag", "script" ] + , [ "closetag", "xml" ] + ] + , strict : false + , opt : { lowercasetags: true, noscript: true } + } + ) + diff --git a/platforms/android/cordova/node_modules/sax/test/parser-position.js b/platforms/android/cordova/node_modules/sax/test/parser-position.js new file mode 100644 index 0000000..e4a68b1 --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/parser-position.js @@ -0,0 +1,28 @@ +var sax = require("../lib/sax"), + assert = require("assert") + +function testPosition(chunks, expectedEvents) { + var parser = sax.parser(); + expectedEvents.forEach(function(expectation) { + parser['on' + expectation[0]] = function() { + for (var prop in expectation[1]) { + assert.equal(parser[prop], expectation[1][prop]); + } + } + }); + chunks.forEach(function(chunk) { + parser.write(chunk); + }); +}; + +testPosition(['
    abcdefgh
    '], + [ ['opentag', { position: 5, startTagPosition: 1 }] + , ['text', { position: 19, startTagPosition: 14 }] + , ['closetag', { position: 19, startTagPosition: 14 }] + ]); + +testPosition(['
    abcde','fgh
    '], + [ ['opentag', { position: 5, startTagPosition: 1 }] + , ['text', { position: 19, startTagPosition: 14 }] + , ['closetag', { position: 19, startTagPosition: 14 }] + ]); diff --git a/platforms/android/cordova/node_modules/sax/test/script.js b/platforms/android/cordova/node_modules/sax/test/script.js new file mode 100644 index 0000000..464c051 --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/script.js @@ -0,0 +1,12 @@ +require(__dirname).test({ + xml : "", + expect : [ + ["opentag", {"name": "HTML","attributes": {}}], + ["opentag", {"name": "HEAD","attributes": {}}], + ["opentag", {"name": "SCRIPT","attributes": {}}], + ["script", "if (1 < 0) { console.log('elo there'); }"], + ["closetag", "SCRIPT"], + ["closetag", "HEAD"], + ["closetag", "HTML"] + ] +}); diff --git a/platforms/android/cordova/node_modules/sax/test/self-closing-child-strict.js b/platforms/android/cordova/node_modules/sax/test/self-closing-child-strict.js new file mode 100644 index 0000000..ce9c045 --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/self-closing-child-strict.js @@ -0,0 +1,40 @@ + +require(__dirname).test({ + xml : + ""+ + "" + + "" + + "" + + "" + + "=(|)" + + "" + + "", + expect : [ + ["opentag", { + "name": "root", + "attributes": {} + }], + ["opentag", { + "name": "child", + "attributes": {} + }], + ["opentag", { + "name": "haha", + "attributes": {} + }], + ["closetag", "haha"], + ["closetag", "child"], + ["opentag", { + "name": "monkey", + "attributes": {} + }], + ["text", "=(|)"], + ["closetag", "monkey"], + ["closetag", "root"], + ["end"], + ["ready"] + ], + strict : true, + opt : {} +}); + diff --git a/platforms/android/cordova/node_modules/sax/test/self-closing-child.js b/platforms/android/cordova/node_modules/sax/test/self-closing-child.js new file mode 100644 index 0000000..bc6b52b --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/self-closing-child.js @@ -0,0 +1,40 @@ + +require(__dirname).test({ + xml : + ""+ + "" + + "" + + "" + + "" + + "=(|)" + + "" + + "", + expect : [ + ["opentag", { + "name": "ROOT", + "attributes": {} + }], + ["opentag", { + "name": "CHILD", + "attributes": {} + }], + ["opentag", { + "name": "HAHA", + "attributes": {} + }], + ["closetag", "HAHA"], + ["closetag", "CHILD"], + ["opentag", { + "name": "MONKEY", + "attributes": {} + }], + ["text", "=(|)"], + ["closetag", "MONKEY"], + ["closetag", "ROOT"], + ["end"], + ["ready"] + ], + strict : false, + opt : {} +}); + diff --git a/platforms/android/cordova/node_modules/sax/test/self-closing-tag.js b/platforms/android/cordova/node_modules/sax/test/self-closing-tag.js new file mode 100644 index 0000000..b2c5736 --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/self-closing-tag.js @@ -0,0 +1,25 @@ + +require(__dirname).test({ + xml : + " "+ + " "+ + " "+ + " "+ + "=(|) "+ + ""+ + " ", + expect : [ + ["opentag", {name:"ROOT", attributes:{}}], + ["opentag", {name:"HAHA", attributes:{}}], + ["closetag", "HAHA"], + ["opentag", {name:"HAHA", attributes:{}}], + ["closetag", "HAHA"], + // ["opentag", {name:"HAHA", attributes:{}}], + // ["closetag", "HAHA"], + ["opentag", {name:"MONKEY", attributes:{}}], + ["text", "=(|)"], + ["closetag", "MONKEY"], + ["closetag", "ROOT"] + ], + opt : { trim : true } +}); \ No newline at end of file diff --git a/platforms/android/cordova/node_modules/sax/test/stray-ending.js b/platforms/android/cordova/node_modules/sax/test/stray-ending.js new file mode 100644 index 0000000..6b0aa7f --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/stray-ending.js @@ -0,0 +1,17 @@ +// stray ending tags should just be ignored in non-strict mode. +// https://github.com/isaacs/sax-js/issues/32 +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "opentag", { name: "A", attributes: {} } ] + , [ "opentag", { name: "B", attributes: {} } ] + , [ "text", "" ] + , [ "closetag", "B" ] + , [ "closetag", "A" ] + ] + , strict : false + , opt : {} + } + ) + diff --git a/platforms/android/cordova/node_modules/sax/test/trailing-non-whitespace.js b/platforms/android/cordova/node_modules/sax/test/trailing-non-whitespace.js new file mode 100644 index 0000000..3e1fb2e --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/trailing-non-whitespace.js @@ -0,0 +1,17 @@ + +require(__dirname).test({ + xml : "Welcome, to monkey land", + expect : [ + ["opentag", { + "name": "SPAN", + "attributes": {} + }], + ["text", "Welcome,"], + ["closetag", "SPAN"], + ["text", " to monkey land"], + ["end"], + ["ready"] + ], + strict : false, + opt : {} +}); diff --git a/platforms/android/cordova/node_modules/sax/test/unquoted.js b/platforms/android/cordova/node_modules/sax/test/unquoted.js new file mode 100644 index 0000000..79f1d0b --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/unquoted.js @@ -0,0 +1,17 @@ +// unquoted attributes should be ok in non-strict mode +// https://github.com/isaacs/sax-js/issues/31 +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "attribute", { name: "class", value: "test" } ] + , [ "attribute", { name: "hello", value: "world" } ] + , [ "opentag", { name: "SPAN", + attributes: { class: "test", hello: "world" } } ] + , [ "closetag", "SPAN" ] + ] + , strict : false + , opt : {} + } + ) + diff --git a/platforms/android/cordova/node_modules/sax/test/xmlns-issue-41.js b/platforms/android/cordova/node_modules/sax/test/xmlns-issue-41.js new file mode 100644 index 0000000..596d82b --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/xmlns-issue-41.js @@ -0,0 +1,67 @@ +var t = require(__dirname) + + , xmls = // should be the same both ways. + [ "" + , "" ] + + , ex1 = + [ [ "opennamespace" + , { prefix: "a" + , uri: "http://ATTRIBUTE" + } + ] + , [ "attribute" + , { name: "xmlns:a" + , value: "http://ATTRIBUTE" + , prefix: "xmlns" + , local: "a" + , uri: "http://www.w3.org/2000/xmlns/" + } + ] + , [ "attribute" + , { name: "a:attr" + , local: "attr" + , prefix: "a" + , uri: "http://ATTRIBUTE" + , value: "value" + } + ] + , [ "opentag" + , { name: "parent" + , uri: "" + , prefix: "" + , local: "parent" + , attributes: + { "a:attr": + { name: "a:attr" + , local: "attr" + , prefix: "a" + , uri: "http://ATTRIBUTE" + , value: "value" + } + , "xmlns:a": + { name: "xmlns:a" + , local: "a" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "http://ATTRIBUTE" + } + } + , ns: {"a": "http://ATTRIBUTE"} + } + ] + , ["closetag", "parent"] + , ["closenamespace", { prefix: "a", uri: "http://ATTRIBUTE" }] + ] + + // swap the order of elements 2 and 1 + , ex2 = [ex1[0], ex1[2], ex1[1]].concat(ex1.slice(3)) + , expected = [ex1, ex2] + +xmls.forEach(function (x, i) { + t.test({ xml: x + , expect: expected[i] + , strict: true + , opt: { xmlns: true } + }) +}) diff --git a/platforms/android/cordova/node_modules/sax/test/xmlns-rebinding.js b/platforms/android/cordova/node_modules/sax/test/xmlns-rebinding.js new file mode 100644 index 0000000..f464876 --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/xmlns-rebinding.js @@ -0,0 +1,59 @@ + +require(__dirname).test + ( { xml : + ""+ + ""+ + ""+ + ""+ + ""+ + "" + + , expect : + [ [ "opennamespace", { prefix: "x", uri: "x1" } ] + , [ "opennamespace", { prefix: "y", uri: "y1" } ] + , [ "attribute", { name: "xmlns:x", value: "x1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } ] + , [ "attribute", { name: "xmlns:y", value: "y1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "y" } ] + , [ "attribute", { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "root", uri: "", prefix: "", local: "root", + attributes: { "xmlns:x": { name: "xmlns:x", value: "x1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } + , "xmlns:y": { name: "xmlns:y", value: "y1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "y" } + , "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x1', y: 'y1' } } ] + + , [ "opennamespace", { prefix: "x", uri: "x2" } ] + , [ "attribute", { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } ] + , [ "opentag", { name: "rebind", uri: "", prefix: "", local: "rebind", + attributes: { "xmlns:x": { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } }, + ns: { x: 'x2' } } ] + + , [ "attribute", { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "check", uri: "", prefix: "", local: "check", + attributes: { "x:a": { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x2' } } ] + + , [ "closetag", "check" ] + + , [ "closetag", "rebind" ] + , [ "closenamespace", { prefix: "x", uri: "x2" } ] + + , [ "attribute", { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "check", uri: "", prefix: "", local: "check", + attributes: { "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x1', y: 'y1' } } ] + , [ "closetag", "check" ] + + , [ "closetag", "root" ] + , [ "closenamespace", { prefix: "x", uri: "x1" } ] + , [ "closenamespace", { prefix: "y", uri: "y1" } ] + ] + , strict : true + , opt : { xmlns: true } + } + ) + diff --git a/platforms/android/cordova/node_modules/sax/test/xmlns-strict.js b/platforms/android/cordova/node_modules/sax/test/xmlns-strict.js new file mode 100644 index 0000000..4ad615b --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/xmlns-strict.js @@ -0,0 +1,71 @@ + +require(__dirname).test + ( { xml : + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + "" + + , expect : + [ [ "opentag", { name: "root", prefix: "", local: "root", uri: "", + attributes: {}, ns: {} } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "", + attributes: { "attr": { name: "attr", value: "normal", uri: "", prefix: "", local: "attr", uri: "" } }, + ns: {} } ] + , [ "closetag", "plain" ] + + , [ "opennamespace", { prefix: "", uri: "uri:default" } ] + + , [ "attribute", { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } ] + , [ "opentag", { name: "ns1", prefix: "", local: "ns1", uri: "uri:default", + attributes: { "xmlns": { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } }, + ns: { "": "uri:default" } } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "uri:default" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "uri:default", ns: { '': 'uri:default' }, + attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "uri:default" } } } ] + , [ "closetag", "plain" ] + + , [ "closetag", "ns1" ] + + , [ "closenamespace", { prefix: "", uri: "uri:default" } ] + + , [ "opennamespace", { prefix: "a", uri: "uri:nsa" } ] + + , [ "attribute", { name: "xmlns:a", value: "uri:nsa", prefix: "xmlns", local: "a", uri: "http://www.w3.org/2000/xmlns/" } ] + + , [ "opentag", { name: "ns2", prefix: "", local: "ns2", uri: "", + attributes: { "xmlns:a": { name: "xmlns:a", value: "uri:nsa", prefix: "xmlns", local: "a", uri: "http://www.w3.org/2000/xmlns/" } }, + ns: { a: "uri:nsa" } } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "", + attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } }, + ns: { a: 'uri:nsa' } } ] + , [ "closetag", "plain" ] + + , [ "attribute", { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } ] + , [ "opentag", { name: "a:ns", prefix: "a", local: "ns", uri: "uri:nsa", + attributes: { "a:attr": { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } }, + ns: { a: 'uri:nsa' } } ] + , [ "closetag", "a:ns" ] + + , [ "closetag", "ns2" ] + + , [ "closenamespace", { prefix: "a", uri: "uri:nsa" } ] + + , [ "closetag", "root" ] + ] + , strict : true + , opt : { xmlns: true } + } + ) + diff --git a/platforms/android/cordova/node_modules/sax/test/xmlns-unbound.js b/platforms/android/cordova/node_modules/sax/test/xmlns-unbound.js new file mode 100644 index 0000000..2944b87 --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/xmlns-unbound.js @@ -0,0 +1,15 @@ + +require(__dirname).test( + { strict : true + , opt : { xmlns: true } + , expect : + [ ["error", "Unbound namespace prefix: \"unbound\"\nLine: 0\nColumn: 28\nChar: >"] + + , [ "attribute", { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } ] + , [ "opentag", { name: "root", uri: "", prefix: "", local: "root", + attributes: { "unbound:attr": { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } }, + ns: {} } ] + , [ "closetag", "root" ] + ] + } +).write("") diff --git a/platforms/android/cordova/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js b/platforms/android/cordova/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js new file mode 100644 index 0000000..16da771 --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js @@ -0,0 +1,35 @@ +require(__dirname).test( + { xml : "" + , expect : + [ [ "attribute" + , { name: "xml:lang" + , local: "lang" + , prefix: "xml" + , uri: "http://www.w3.org/XML/1998/namespace" + , value: "en" + } + ] + , [ "opentag" + , { name: "root" + , uri: "" + , prefix: "" + , local: "root" + , attributes: + { "xml:lang": + { name: "xml:lang" + , local: "lang" + , prefix: "xml" + , uri: "http://www.w3.org/XML/1998/namespace" + , value: "en" + } + } + , ns: {} + } + ] + , ["closetag", "root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/platforms/android/cordova/node_modules/sax/test/xmlns-xml-default-prefix.js b/platforms/android/cordova/node_modules/sax/test/xmlns-xml-default-prefix.js new file mode 100644 index 0000000..9a1ce1b --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/xmlns-xml-default-prefix.js @@ -0,0 +1,20 @@ +require(__dirname).test( + { xml : "" + , expect : + [ + [ "opentag" + , { name: "xml:root" + , uri: "http://www.w3.org/XML/1998/namespace" + , prefix: "xml" + , local: "root" + , attributes: {} + , ns: {} + } + ] + , ["closetag", "xml:root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/platforms/android/cordova/node_modules/sax/test/xmlns-xml-default-redefine.js b/platforms/android/cordova/node_modules/sax/test/xmlns-xml-default-redefine.js new file mode 100644 index 0000000..1eba9c7 --- /dev/null +++ b/platforms/android/cordova/node_modules/sax/test/xmlns-xml-default-redefine.js @@ -0,0 +1,40 @@ +require(__dirname).test( + { xml : "" + , expect : + [ ["error" + , "xml: prefix must be bound to http://www.w3.org/XML/1998/namespace\n" + + "Actual: ERROR\n" + + "Line: 0\nColumn: 27\nChar: '" + ] + , [ "attribute" + , { name: "xmlns:xml" + , local: "xml" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "ERROR" + } + ] + , [ "opentag" + , { name: "xml:root" + , uri: "http://www.w3.org/XML/1998/namespace" + , prefix: "xml" + , local: "root" + , attributes: + { "xmlns:xml": + { name: "xmlns:xml" + , local: "xml" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "ERROR" + } + } + , ns: {} + } + ] + , ["closetag", "xml:root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/platforms/android/cordova/node_modules/semver/.npmignore b/platforms/android/cordova/node_modules/semver/.npmignore new file mode 100644 index 0000000..534108e --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/.npmignore @@ -0,0 +1,4 @@ +node_modules/ +coverage/ +.nyc_output/ +nyc_output/ diff --git a/platforms/android/cordova/node_modules/semver/.travis.yml b/platforms/android/cordova/node_modules/semver/.travis.yml new file mode 100644 index 0000000..991d04b --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - '0.10' + - '0.12' + - 'iojs' diff --git a/platforms/android/cordova/node_modules/semver/LICENSE b/platforms/android/cordova/node_modules/semver/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/platforms/android/cordova/node_modules/semver/README.md b/platforms/android/cordova/node_modules/semver/README.md new file mode 100644 index 0000000..0b14a7e --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/README.md @@ -0,0 +1,327 @@ +semver(1) -- The semantic versioner for npm +=========================================== + +## Usage + + $ npm install semver + + semver.valid('1.2.3') // '1.2.3' + semver.valid('a.b.c') // null + semver.clean(' =v1.2.3 ') // '1.2.3' + semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true + semver.gt('1.2.3', '9.8.7') // false + semver.lt('1.2.3', '9.8.7') // true + +As a command-line utility: + + $ semver -h + + Usage: semver [ [...]] [-r | -i | --preid | -l | -rv] + Test if version(s) satisfy the supplied range(s), and sort them. + + Multiple versions or ranges may be supplied, unless increment + option is specified. In that case, only a single version may + be used, and it is incremented by the specified level + + Program exits successfully if any valid version satisfies + all supplied ranges, and prints all satisfying versions. + + If no versions are valid, or ranges are not satisfied, + then exits failure. + + Versions are printed in ascending order, so supplying + multiple versions to the utility will just sort them. + +## Versions + +A "version" is described by the `v2.0.0` specification found at +. + +A leading `"="` or `"v"` character is stripped off and ignored. + +## Ranges + +A `version range` is a set of `comparators` which specify versions +that satisfy the range. + +A `comparator` is composed of an `operator` and a `version`. The set +of primitive `operators` is: + +* `<` Less than +* `<=` Less than or equal to +* `>` Greater than +* `>=` Greater than or equal to +* `=` Equal. If no operator is specified, then equality is assumed, + so this operator is optional, but MAY be included. + +For example, the comparator `>=1.2.7` would match the versions +`1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6` +or `1.1.0`. + +Comparators can be joined by whitespace to form a `comparator set`, +which is satisfied by the **intersection** of all of the comparators +it includes. + +A range is composed of one or more comparator sets, joined by `||`. A +version matches a range if and only if every comparator in at least +one of the `||`-separated comparator sets is satisfied by the version. + +For example, the range `>=1.2.7 <1.3.0` would match the versions +`1.2.7`, `1.2.8`, and `1.2.99`, but not the versions `1.2.6`, `1.3.0`, +or `1.1.0`. + +The range `1.2.7 || >=1.2.9 <2.0.0` would match the versions `1.2.7`, +`1.2.9`, and `1.4.6`, but not the versions `1.2.8` or `2.0.0`. + +### Prerelease Tags + +If a version has a prerelease tag (for example, `1.2.3-alpha.3`) then +it will only be allowed to satisfy comparator sets if at least one +comparator with the same `[major, minor, patch]` tuple also has a +prerelease tag. + +For example, the range `>1.2.3-alpha.3` would be allowed to match the +version `1.2.3-alpha.7`, but it would *not* be satisfied by +`3.4.5-alpha.9`, even though `3.4.5-alpha.9` is technically "greater +than" `1.2.3-alpha.3` according to the SemVer sort rules. The version +range only accepts prerelease tags on the `1.2.3` version. The +version `3.4.5` *would* satisfy the range, because it does not have a +prerelease flag, and `3.4.5` is greater than `1.2.3-alpha.7`. + +The purpose for this behavior is twofold. First, prerelease versions +frequently are updated very quickly, and contain many breaking changes +that are (by the author's design) not yet fit for public consumption. +Therefore, by default, they are excluded from range matching +semantics. + +Second, a user who has opted into using a prerelease version has +clearly indicated the intent to use *that specific* set of +alpha/beta/rc versions. By including a prerelease tag in the range, +the user is indicating that they are aware of the risk. However, it +is still not appropriate to assume that they have opted into taking a +similar risk on the *next* set of prerelease versions. + +#### Prerelease Identifiers + +The method `.inc` takes an additional `identifier` string argument that +will append the value of the string as a prerelease identifier: + +```javascript +> semver.inc('1.2.3', 'prerelease', 'beta') +'1.2.4-beta.0' +``` + +command-line example: + +```shell +$ semver 1.2.3 -i prerelease --preid beta +1.2.4-beta.0 +``` + +Which then can be used to increment further: + +```shell +$ semver 1.2.4-beta.0 -i prerelease +1.2.4-beta.1 +``` + +### Advanced Range Syntax + +Advanced range syntax desugars to primitive comparators in +deterministic ways. + +Advanced ranges may be combined in the same way as primitive +comparators using white space or `||`. + +#### Hyphen Ranges `X.Y.Z - A.B.C` + +Specifies an inclusive set. + +* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4` + +If a partial version is provided as the first version in the inclusive +range, then the missing pieces are replaced with zeroes. + +* `1.2 - 2.3.4` := `>=1.2.0 <=2.3.4` + +If a partial version is provided as the second version in the +inclusive range, then all versions that start with the supplied parts +of the tuple are accepted, but nothing that would be greater than the +provided tuple parts. + +* `1.2.3 - 2.3` := `>=1.2.3 <2.4.0` +* `1.2.3 - 2` := `>=1.2.3 <3.0.0` + +#### X-Ranges `1.2.x` `1.X` `1.2.*` `*` + +Any of `X`, `x`, or `*` may be used to "stand in" for one of the +numeric values in the `[major, minor, patch]` tuple. + +* `*` := `>=0.0.0` (Any version satisfies) +* `1.x` := `>=1.0.0 <2.0.0` (Matching major version) +* `1.2.x` := `>=1.2.0 <1.3.0` (Matching major and minor versions) + +A partial version range is treated as an X-Range, so the special +character is in fact optional. + +* `""` (empty string) := `*` := `>=0.0.0` +* `1` := `1.x.x` := `>=1.0.0 <2.0.0` +* `1.2` := `1.2.x` := `>=1.2.0 <1.3.0` + +#### Tilde Ranges `~1.2.3` `~1.2` `~1` + +Allows patch-level changes if a minor version is specified on the +comparator. Allows minor-level changes if not. + +* `~1.2.3` := `>=1.2.3 <1.(2+1).0` := `>=1.2.3 <1.3.0` +* `~1.2` := `>=1.2.0 <1.(2+1).0` := `>=1.2.0 <1.3.0` (Same as `1.2.x`) +* `~1` := `>=1.0.0 <(1+1).0.0` := `>=1.0.0 <2.0.0` (Same as `1.x`) +* `~0.2.3` := `>=0.2.3 <0.(2+1).0` := `>=0.2.3 <0.3.0` +* `~0.2` := `>=0.2.0 <0.(2+1).0` := `>=0.2.0 <0.3.0` (Same as `0.2.x`) +* `~0` := `>=0.0.0 <(0+1).0.0` := `>=0.0.0 <1.0.0` (Same as `0.x`) +* `~1.2.3-beta.2` := `>=1.2.3-beta.2 <1.3.0` Note that prereleases in + the `1.2.3` version will be allowed, if they are greater than or + equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but + `1.2.4-beta.2` would not, because it is a prerelease of a + different `[major, minor, patch]` tuple. + +#### Caret Ranges `^1.2.3` `^0.2.5` `^0.0.4` + +Allows changes that do not modify the left-most non-zero digit in the +`[major, minor, patch]` tuple. In other words, this allows patch and +minor updates for versions `1.0.0` and above, patch updates for +versions `0.X >=0.1.0`, and *no* updates for versions `0.0.X`. + +Many authors treat a `0.x` version as if the `x` were the major +"breaking-change" indicator. + +Caret ranges are ideal when an author may make breaking changes +between `0.2.4` and `0.3.0` releases, which is a common practice. +However, it presumes that there will *not* be breaking changes between +`0.2.4` and `0.2.5`. It allows for changes that are presumed to be +additive (but non-breaking), according to commonly observed practices. + +* `^1.2.3` := `>=1.2.3 <2.0.0` +* `^0.2.3` := `>=0.2.3 <0.3.0` +* `^0.0.3` := `>=0.0.3 <0.0.4` +* `^1.2.3-beta.2` := `>=1.2.3-beta.2 <2.0.0` Note that prereleases in + the `1.2.3` version will be allowed, if they are greater than or + equal to `beta.2`. So, `1.2.3-beta.4` would be allowed, but + `1.2.4-beta.2` would not, because it is a prerelease of a + different `[major, minor, patch]` tuple. +* `^0.0.3-beta` := `>=0.0.3-beta <0.0.4` Note that prereleases in the + `0.0.3` version *only* will be allowed, if they are greater than or + equal to `beta`. So, `0.0.3-pr.2` would be allowed. + +When parsing caret ranges, a missing `patch` value desugars to the +number `0`, but will allow flexibility within that value, even if the +major and minor versions are both `0`. + +* `^1.2.x` := `>=1.2.0 <2.0.0` +* `^0.0.x` := `>=0.0.0 <0.1.0` +* `^0.0` := `>=0.0.0 <0.1.0` + +A missing `minor` and `patch` values will desugar to zero, but also +allow flexibility within those values, even if the major version is +zero. + +* `^1.x` := `>=1.0.0 <2.0.0` +* `^0.x` := `>=0.0.0 <1.0.0` + +### Range Grammar + +Putting all this together, here is a Backus-Naur grammar for ranges, +for the benefit of parser authors: + +```bnf +range-set ::= range ( logical-or range ) * +logical-or ::= ( ' ' ) * '||' ( ' ' ) * +range ::= hyphen | simple ( ' ' simple ) * | '' +hyphen ::= partial ' - ' partial +simple ::= primitive | partial | tilde | caret +primitive ::= ( '<' | '>' | '>=' | '<=' | '=' | ) partial +partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? +xr ::= 'x' | 'X' | '*' | nr +nr ::= '0' | ['1'-'9']['0'-'9']+ +tilde ::= '~' partial +caret ::= '^' partial +qualifier ::= ( '-' pre )? ( '+' build )? +pre ::= parts +build ::= parts +parts ::= part ( '.' part ) * +part ::= nr | [-0-9A-Za-z]+ +``` + +## Functions + +All methods and classes take a final `loose` boolean argument that, if +true, will be more forgiving about not-quite-valid semver strings. +The resulting output will always be 100% strict, of course. + +Strict-mode Comparators and Ranges will be strict about the SemVer +strings that they parse. + +* `valid(v)`: Return the parsed version, or null if it's not valid. +* `inc(v, release)`: Return the version incremented by the release + type (`major`, `premajor`, `minor`, `preminor`, `patch`, + `prepatch`, or `prerelease`), or null if it's not valid + * `premajor` in one call will bump the version up to the next major + version and down to a prerelease of that major version. + `preminor`, and `prepatch` work the same way. + * If called from a non-prerelease version, the `prerelease` will work the + same as `prepatch`. It increments the patch version, then makes a + prerelease. If the input version is already a prerelease it simply + increments it. +* `major(v)`: Return the major version number. +* `minor(v)`: Return the minor version number. +* `patch(v)`: Return the patch version number. + +### Comparison + +* `gt(v1, v2)`: `v1 > v2` +* `gte(v1, v2)`: `v1 >= v2` +* `lt(v1, v2)`: `v1 < v2` +* `lte(v1, v2)`: `v1 <= v2` +* `eq(v1, v2)`: `v1 == v2` This is true if they're logically equivalent, + even if they're not the exact same string. You already know how to + compare strings. +* `neq(v1, v2)`: `v1 != v2` The opposite of `eq`. +* `cmp(v1, comparator, v2)`: Pass in a comparison string, and it'll call + the corresponding function above. `"==="` and `"!=="` do simple + string comparison, but are included for completeness. Throws if an + invalid comparison string is provided. +* `compare(v1, v2)`: Return `0` if `v1 == v2`, or `1` if `v1` is greater, or `-1` if + `v2` is greater. Sorts in ascending order if passed to `Array.sort()`. +* `rcompare(v1, v2)`: The reverse of compare. Sorts an array of versions + in descending order when passed to `Array.sort()`. +* `diff(v1, v2)`: Returns difference between two versions by the release type + (`major`, `premajor`, `minor`, `preminor`, `patch`, `prepatch`, or `prerelease`), + or null if the versions are the same. + + +### Ranges + +* `validRange(range)`: Return the valid range or null if it's not valid +* `satisfies(version, range)`: Return true if the version satisfies the + range. +* `maxSatisfying(versions, range)`: Return the highest version in the list + that satisfies the range, or `null` if none of them do. +* `gtr(version, range)`: Return `true` if version is greater than all the + versions possible in the range. +* `ltr(version, range)`: Return `true` if version is less than all the + versions possible in the range. +* `outside(version, range, hilo)`: Return true if the version is outside + the bounds of the range in either the high or low direction. The + `hilo` argument must be either the string `'>'` or `'<'`. (This is + the function called by `gtr` and `ltr`.) + +Note that, since ranges may be non-contiguous, a version might not be +greater than a range, less than a range, *or* satisfy a range! For +example, the range `1.2 <1.2.9 || >2.0.0` would have a hole from `1.2.9` +until `2.0.0`, so the version `1.2.10` would not be greater than the +range (because `2.0.1` satisfies, which is higher), nor less than the +range (since `1.2.8` satisfies, which is lower), and it also does not +satisfy the range. + +If you want to know if a version satisfies or does not satisfy a +range, use the `satisfies(version, range)` function. diff --git a/platforms/android/cordova/node_modules/semver/bin/semver b/platforms/android/cordova/node_modules/semver/bin/semver new file mode 100755 index 0000000..c5f2e85 --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/bin/semver @@ -0,0 +1,133 @@ +#!/usr/bin/env node +// Standalone semver comparison program. +// Exits successfully and prints matching version(s) if +// any supplied version is valid and passes all tests. + +var argv = process.argv.slice(2) + , versions = [] + , range = [] + , gt = [] + , lt = [] + , eq = [] + , inc = null + , version = require("../package.json").version + , loose = false + , identifier = undefined + , semver = require("../semver") + , reverse = false + +main() + +function main () { + if (!argv.length) return help() + while (argv.length) { + var a = argv.shift() + var i = a.indexOf('=') + if (i !== -1) { + a = a.slice(0, i) + argv.unshift(a.slice(i + 1)) + } + switch (a) { + case "-rv": case "-rev": case "--rev": case "--reverse": + reverse = true + break + case "-l": case "--loose": + loose = true + break + case "-v": case "--version": + versions.push(argv.shift()) + break + case "-i": case "--inc": case "--increment": + switch (argv[0]) { + case "major": case "minor": case "patch": case "prerelease": + case "premajor": case "preminor": case "prepatch": + inc = argv.shift() + break + default: + inc = "patch" + break + } + break + case "--preid": + identifier = argv.shift() + break + case "-r": case "--range": + range.push(argv.shift()) + break + case "-h": case "--help": case "-?": + return help() + default: + versions.push(a) + break + } + } + + versions = versions.filter(function (v) { + return semver.valid(v, loose) + }) + if (!versions.length) return fail() + if (inc && (versions.length !== 1 || range.length)) + return failInc() + + for (var i = 0, l = range.length; i < l ; i ++) { + versions = versions.filter(function (v) { + return semver.satisfies(v, range[i], loose) + }) + if (!versions.length) return fail() + } + return success(versions) +} + +function failInc () { + console.error("--inc can only be used on a single version with no range") + fail() +} + +function fail () { process.exit(1) } + +function success () { + var compare = reverse ? "rcompare" : "compare" + versions.sort(function (a, b) { + return semver[compare](a, b, loose) + }).map(function (v) { + return semver.clean(v, loose) + }).map(function (v) { + return inc ? semver.inc(v, inc, loose, identifier) : v + }).forEach(function (v,i,_) { console.log(v) }) +} + +function help () { + console.log(["SemVer " + version + ,"" + ,"A JavaScript implementation of the http://semver.org/ specification" + ,"Copyright Isaac Z. Schlueter" + ,"" + ,"Usage: semver [options] [ [...]]" + ,"Prints valid versions sorted by SemVer precedence" + ,"" + ,"Options:" + ,"-r --range " + ," Print versions that match the specified range." + ,"" + ,"-i --increment []" + ," Increment a version by the specified level. Level can" + ," be one of: major, minor, patch, premajor, preminor," + ," prepatch, or prerelease. Default level is 'patch'." + ," Only one version may be specified." + ,"" + ,"--preid " + ," Identifier to be used to prefix premajor, preminor," + ," prepatch or prerelease version increments." + ,"" + ,"-l --loose" + ," Interpret versions and ranges loosely" + ,"" + ,"Program exits successfully if any valid version satisfies" + ,"all supplied ranges, and prints all satisfying versions." + ,"" + ,"If no satisfying versions are found, then exits failure." + ,"" + ,"Versions are printed in ascending order, so supplying" + ,"multiple versions to the utility will just sort them." + ].join("\n")) +} diff --git a/platforms/android/cordova/node_modules/semver/package.json b/platforms/android/cordova/node_modules/semver/package.json new file mode 100644 index 0000000..0db0065 --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/package.json @@ -0,0 +1,77 @@ +{ + "_args": [ + [ + "semver@^5.0.1", + "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common" + ] + ], + "_from": "semver@>=5.0.1 <6.0.0", + "_id": "semver@5.1.0", + "_inCache": true, + "_installable": true, + "_location": "/semver", + "_nodeVersion": "4.0.0", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "3.3.2", + "_phantomChildren": {}, + "_requested": { + "name": "semver", + "raw": "semver@^5.0.1", + "rawSpec": "^5.0.1", + "scope": null, + "spec": ">=5.0.1 <6.0.0", + "type": "range" + }, + "_requiredBy": [ + "/cordova-common" + ], + "_resolved": "http://registry.npmjs.org/semver/-/semver-5.1.0.tgz", + "_shasum": "85f2cf8550465c4df000cf7d86f6b054106ab9e5", + "_shrinkwrap": null, + "_spec": "semver@^5.0.1", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common", + "bin": { + "semver": "./bin/semver" + }, + "bugs": { + "url": "https://github.com/npm/node-semver/issues" + }, + "dependencies": {}, + "description": "The semantic version parser used by npm.", + "devDependencies": { + "tap": "^2.0.0" + }, + "directories": {}, + "dist": { + "shasum": "85f2cf8550465c4df000cf7d86f6b054106ab9e5", + "tarball": "http://registry.npmjs.org/semver/-/semver-5.1.0.tgz" + }, + "gitHead": "8e33a30e62e40e4983d1c5f55e794331b861aadc", + "homepage": "https://github.com/npm/node-semver#readme", + "license": "ISC", + "main": "semver.js", + "maintainers": [ + { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + { + "name": "othiym23", + "email": "ogd@aoaioxxysz.net" + } + ], + "name": "semver", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/node-semver.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "5.1.0" +} diff --git a/platforms/android/cordova/node_modules/semver/range.bnf b/platforms/android/cordova/node_modules/semver/range.bnf new file mode 100644 index 0000000..000df92 --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/range.bnf @@ -0,0 +1,16 @@ +range-set ::= range ( logical-or range ) * +logical-or ::= ( ' ' ) * '||' ( ' ' ) * +range ::= hyphen | simple ( ' ' simple ) * | '' +hyphen ::= partial ' - ' partial +simple ::= primitive | partial | tilde | caret +primitive ::= ( '<' | '>' | '>=' | '<=' | '=' | ) partial +partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? +xr ::= 'x' | 'X' | '*' | nr +nr ::= '0' | ['1'-'9']['0'-'9']+ +tilde ::= '~' partial +caret ::= '^' partial +qualifier ::= ( '-' pre )? ( '+' build )? +pre ::= parts +build ::= parts +parts ::= part ( '.' part ) * +part ::= nr | [-0-9A-Za-z]+ diff --git a/platforms/android/cordova/node_modules/semver/semver.js b/platforms/android/cordova/node_modules/semver/semver.js new file mode 100644 index 0000000..71795f6 --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/semver.js @@ -0,0 +1,1188 @@ +exports = module.exports = SemVer; + +// The debug function is excluded entirely from the minified version. +/* nomin */ var debug; +/* nomin */ if (typeof process === 'object' && + /* nomin */ process.env && + /* nomin */ process.env.NODE_DEBUG && + /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG)) + /* nomin */ debug = function() { + /* nomin */ var args = Array.prototype.slice.call(arguments, 0); + /* nomin */ args.unshift('SEMVER'); + /* nomin */ console.log.apply(console, args); + /* nomin */ }; +/* nomin */ else + /* nomin */ debug = function() {}; + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +exports.SEMVER_SPEC_VERSION = '2.0.0'; + +var MAX_LENGTH = 256; +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; + +// The actual regexps go on exports.re +var re = exports.re = []; +var src = exports.src = []; +var R = 0; + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +var NUMERICIDENTIFIER = R++; +src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'; +var NUMERICIDENTIFIERLOOSE = R++; +src[NUMERICIDENTIFIERLOOSE] = '[0-9]+'; + + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +var NONNUMERICIDENTIFIER = R++; +src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'; + + +// ## Main Version +// Three dot-separated numeric identifiers. + +var MAINVERSION = R++; +src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')'; + +var MAINVERSIONLOOSE = R++; +src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')'; + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. + +var PRERELEASEIDENTIFIER = R++; +src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + +var PRERELEASEIDENTIFIERLOOSE = R++; +src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + + '|' + src[NONNUMERICIDENTIFIER] + ')'; + + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +var PRERELEASE = R++; +src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'; + +var PRERELEASELOOSE = R++; +src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'; + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +var BUILDIDENTIFIER = R++; +src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'; + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +var BUILD = R++; +src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))'; + + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +var FULL = R++; +var FULLPLAIN = 'v?' + src[MAINVERSION] + + src[PRERELEASE] + '?' + + src[BUILD] + '?'; + +src[FULL] = '^' + FULLPLAIN + '$'; + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + + src[PRERELEASELOOSE] + '?' + + src[BUILD] + '?'; + +var LOOSE = R++; +src[LOOSE] = '^' + LOOSEPLAIN + '$'; + +var GTLT = R++; +src[GTLT] = '((?:<|>)?=?)'; + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +var XRANGEIDENTIFIERLOOSE = R++; +src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'; +var XRANGEIDENTIFIER = R++; +src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'; + +var XRANGEPLAIN = R++; +src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:' + src[PRERELEASE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + +var XRANGEPLAINLOOSE = R++; +src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[PRERELEASELOOSE] + ')?' + + src[BUILD] + '?' + + ')?)?'; + +var XRANGE = R++; +src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'; +var XRANGELOOSE = R++; +src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'; + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +var LONETILDE = R++; +src[LONETILDE] = '(?:~>?)'; + +var TILDETRIM = R++; +src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; +re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); +var tildeTrimReplace = '$1~'; + +var TILDE = R++; +src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; +var TILDELOOSE = R++; +src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +var LONECARET = R++; +src[LONECARET] = '(?:\\^)'; + +var CARETTRIM = R++; +src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; +re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); +var caretTrimReplace = '$1^'; + +var CARET = R++; +src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; +var CARETLOOSE = R++; +src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +var COMPARATORLOOSE = R++; +src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'; +var COMPARATOR = R++; +src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'; + + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +var COMPARATORTRIM = R++; +src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'; + +// this one has to use the /g flag +re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g'); +var comparatorTrimReplace = '$1$2$3'; + + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +var HYPHENRANGE = R++; +src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAIN] + ')' + + '\\s*$'; + +var HYPHENRANGELOOSE = R++; +src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s*$'; + +// Star ranges basically just allow anything at all. +var STAR = R++; +src[STAR] = '(<|>)?=?\\s*\\*'; + +// Compile to actual regexp objects. +// All are flag-free, unless they were created above with a flag. +for (var i = 0; i < R; i++) { + debug(i, src[i]); + if (!re[i]) + re[i] = new RegExp(src[i]); +} + +exports.parse = parse; +function parse(version, loose) { + if (version instanceof SemVer) + return version; + + if (typeof version !== 'string') + return null; + + if (version.length > MAX_LENGTH) + return null; + + var r = loose ? re[LOOSE] : re[FULL]; + if (!r.test(version)) + return null; + + try { + return new SemVer(version, loose); + } catch (er) { + return null; + } +} + +exports.valid = valid; +function valid(version, loose) { + var v = parse(version, loose); + return v ? v.version : null; +} + + +exports.clean = clean; +function clean(version, loose) { + var s = parse(version.trim().replace(/^[=v]+/, ''), loose); + return s ? s.version : null; +} + +exports.SemVer = SemVer; + +function SemVer(version, loose) { + if (version instanceof SemVer) { + if (version.loose === loose) + return version; + else + version = version.version; + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version); + } + + if (version.length > MAX_LENGTH) + throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') + + if (!(this instanceof SemVer)) + return new SemVer(version, loose); + + debug('SemVer', version, loose); + this.loose = loose; + var m = version.trim().match(loose ? re[LOOSE] : re[FULL]); + + if (!m) + throw new TypeError('Invalid Version: ' + version); + + this.raw = version; + + // these are actually numbers + this.major = +m[1]; + this.minor = +m[2]; + this.patch = +m[3]; + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) + throw new TypeError('Invalid major version') + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) + throw new TypeError('Invalid minor version') + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) + throw new TypeError('Invalid patch version') + + // numberify any prerelease numeric ids + if (!m[4]) + this.prerelease = []; + else + this.prerelease = m[4].split('.').map(function(id) { + if (/^[0-9]+$/.test(id)) { + var num = +id + if (num >= 0 && num < MAX_SAFE_INTEGER) + return num + } + return id; + }); + + this.build = m[5] ? m[5].split('.') : []; + this.format(); +} + +SemVer.prototype.format = function() { + this.version = this.major + '.' + this.minor + '.' + this.patch; + if (this.prerelease.length) + this.version += '-' + this.prerelease.join('.'); + return this.version; +}; + +SemVer.prototype.toString = function() { + return this.version; +}; + +SemVer.prototype.compare = function(other) { + debug('SemVer.compare', this.version, this.loose, other); + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + return this.compareMain(other) || this.comparePre(other); +}; + +SemVer.prototype.compareMain = function(other) { + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch); +}; + +SemVer.prototype.comparePre = function(other) { + if (!(other instanceof SemVer)) + other = new SemVer(other, this.loose); + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) + return -1; + else if (!this.prerelease.length && other.prerelease.length) + return 1; + else if (!this.prerelease.length && !other.prerelease.length) + return 0; + + var i = 0; + do { + var a = this.prerelease[i]; + var b = other.prerelease[i]; + debug('prerelease compare', i, a, b); + if (a === undefined && b === undefined) + return 0; + else if (b === undefined) + return 1; + else if (a === undefined) + return -1; + else if (a === b) + continue; + else + return compareIdentifiers(a, b); + } while (++i); +}; + +// preminor will bump the version up to the next minor release, and immediately +// down to pre-release. premajor and prepatch work the same way. +SemVer.prototype.inc = function(release, identifier) { + switch (release) { + case 'premajor': + this.prerelease.length = 0; + this.patch = 0; + this.minor = 0; + this.major++; + this.inc('pre', identifier); + break; + case 'preminor': + this.prerelease.length = 0; + this.patch = 0; + this.minor++; + this.inc('pre', identifier); + break; + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0; + this.inc('patch', identifier); + this.inc('pre', identifier); + break; + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) + this.inc('patch', identifier); + this.inc('pre', identifier); + break; + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) + this.major++; + this.minor = 0; + this.patch = 0; + this.prerelease = []; + break; + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) + this.minor++; + this.patch = 0; + this.prerelease = []; + break; + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) + this.patch++; + this.prerelease = []; + break; + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) + this.prerelease = [0]; + else { + var i = this.prerelease.length; + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++; + i = -2; + } + } + if (i === -1) // didn't increment anything + this.prerelease.push(0); + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) + this.prerelease = [identifier, 0]; + } else + this.prerelease = [identifier, 0]; + } + break; + + default: + throw new Error('invalid increment argument: ' + release); + } + this.format(); + this.raw = this.version; + return this; +}; + +exports.inc = inc; +function inc(version, release, loose, identifier) { + if (typeof(loose) === 'string') { + identifier = loose; + loose = undefined; + } + + try { + return new SemVer(version, loose).inc(release, identifier).version; + } catch (er) { + return null; + } +} + +exports.diff = diff; +function diff(version1, version2) { + if (eq(version1, version2)) { + return null; + } else { + var v1 = parse(version1); + var v2 = parse(version2); + if (v1.prerelease.length || v2.prerelease.length) { + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return 'pre'+key; + } + } + } + return 'prerelease'; + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return key; + } + } + } + } +} + +exports.compareIdentifiers = compareIdentifiers; + +var numeric = /^[0-9]+$/; +function compareIdentifiers(a, b) { + var anum = numeric.test(a); + var bnum = numeric.test(b); + + if (anum && bnum) { + a = +a; + b = +b; + } + + return (anum && !bnum) ? -1 : + (bnum && !anum) ? 1 : + a < b ? -1 : + a > b ? 1 : + 0; +} + +exports.rcompareIdentifiers = rcompareIdentifiers; +function rcompareIdentifiers(a, b) { + return compareIdentifiers(b, a); +} + +exports.major = major; +function major(a, loose) { + return new SemVer(a, loose).major; +} + +exports.minor = minor; +function minor(a, loose) { + return new SemVer(a, loose).minor; +} + +exports.patch = patch; +function patch(a, loose) { + return new SemVer(a, loose).patch; +} + +exports.compare = compare; +function compare(a, b, loose) { + return new SemVer(a, loose).compare(b); +} + +exports.compareLoose = compareLoose; +function compareLoose(a, b) { + return compare(a, b, true); +} + +exports.rcompare = rcompare; +function rcompare(a, b, loose) { + return compare(b, a, loose); +} + +exports.sort = sort; +function sort(list, loose) { + return list.sort(function(a, b) { + return exports.compare(a, b, loose); + }); +} + +exports.rsort = rsort; +function rsort(list, loose) { + return list.sort(function(a, b) { + return exports.rcompare(a, b, loose); + }); +} + +exports.gt = gt; +function gt(a, b, loose) { + return compare(a, b, loose) > 0; +} + +exports.lt = lt; +function lt(a, b, loose) { + return compare(a, b, loose) < 0; +} + +exports.eq = eq; +function eq(a, b, loose) { + return compare(a, b, loose) === 0; +} + +exports.neq = neq; +function neq(a, b, loose) { + return compare(a, b, loose) !== 0; +} + +exports.gte = gte; +function gte(a, b, loose) { + return compare(a, b, loose) >= 0; +} + +exports.lte = lte; +function lte(a, b, loose) { + return compare(a, b, loose) <= 0; +} + +exports.cmp = cmp; +function cmp(a, op, b, loose) { + var ret; + switch (op) { + case '===': + if (typeof a === 'object') a = a.version; + if (typeof b === 'object') b = b.version; + ret = a === b; + break; + case '!==': + if (typeof a === 'object') a = a.version; + if (typeof b === 'object') b = b.version; + ret = a !== b; + break; + case '': case '=': case '==': ret = eq(a, b, loose); break; + case '!=': ret = neq(a, b, loose); break; + case '>': ret = gt(a, b, loose); break; + case '>=': ret = gte(a, b, loose); break; + case '<': ret = lt(a, b, loose); break; + case '<=': ret = lte(a, b, loose); break; + default: throw new TypeError('Invalid operator: ' + op); + } + return ret; +} + +exports.Comparator = Comparator; +function Comparator(comp, loose) { + if (comp instanceof Comparator) { + if (comp.loose === loose) + return comp; + else + comp = comp.value; + } + + if (!(this instanceof Comparator)) + return new Comparator(comp, loose); + + debug('comparator', comp, loose); + this.loose = loose; + this.parse(comp); + + if (this.semver === ANY) + this.value = ''; + else + this.value = this.operator + this.semver.version; + + debug('comp', this); +} + +var ANY = {}; +Comparator.prototype.parse = function(comp) { + var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var m = comp.match(r); + + if (!m) + throw new TypeError('Invalid comparator: ' + comp); + + this.operator = m[1]; + if (this.operator === '=') + this.operator = ''; + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) + this.semver = ANY; + else + this.semver = new SemVer(m[2], this.loose); +}; + +Comparator.prototype.toString = function() { + return this.value; +}; + +Comparator.prototype.test = function(version) { + debug('Comparator.test', version, this.loose); + + if (this.semver === ANY) + return true; + + if (typeof version === 'string') + version = new SemVer(version, this.loose); + + return cmp(version, this.operator, this.semver, this.loose); +}; + + +exports.Range = Range; +function Range(range, loose) { + if ((range instanceof Range) && range.loose === loose) + return range; + + if (!(this instanceof Range)) + return new Range(range, loose); + + this.loose = loose; + + // First, split based on boolean or || + this.raw = range; + this.set = range.split(/\s*\|\|\s*/).map(function(range) { + return this.parseRange(range.trim()); + }, this).filter(function(c) { + // throw out any that are not relevant for whatever reason + return c.length; + }); + + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range); + } + + this.format(); +} + +Range.prototype.format = function() { + this.range = this.set.map(function(comps) { + return comps.join(' ').trim(); + }).join('||').trim(); + return this.range; +}; + +Range.prototype.toString = function() { + return this.range; +}; + +Range.prototype.parseRange = function(range) { + var loose = this.loose; + range = range.trim(); + debug('range', range, loose); + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]; + range = range.replace(hr, hyphenReplace); + debug('hyphen replace', range); + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace); + debug('comparator trim', range, re[COMPARATORTRIM]); + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[TILDETRIM], tildeTrimReplace); + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[CARETTRIM], caretTrimReplace); + + // normalize spaces + range = range.split(/\s+/).join(' '); + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; + var set = range.split(' ').map(function(comp) { + return parseComparator(comp, loose); + }).join(' ').split(/\s+/); + if (this.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function(comp) { + return !!comp.match(compRe); + }); + } + set = set.map(function(comp) { + return new Comparator(comp, loose); + }); + + return set; +}; + +// Mostly just for testing and legacy API reasons +exports.toComparators = toComparators; +function toComparators(range, loose) { + return new Range(range, loose).set.map(function(comp) { + return comp.map(function(c) { + return c.value; + }).join(' ').trim().split(' '); + }); +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +function parseComparator(comp, loose) { + debug('comp', comp); + comp = replaceCarets(comp, loose); + debug('caret', comp); + comp = replaceTildes(comp, loose); + debug('tildes', comp); + comp = replaceXRanges(comp, loose); + debug('xrange', comp); + comp = replaceStars(comp, loose); + debug('stars', comp); + return comp; +} + +function isX(id) { + return !id || id.toLowerCase() === 'x' || id === '*'; +} + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceTilde(comp, loose); + }).join(' '); +} + +function replaceTilde(comp, loose) { + var r = loose ? re[TILDELOOSE] : re[TILDE]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + ret = ''; + else if (isX(m)) + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + else if (isX(p)) + // ~1.2 == >=1.2.0- <1.3.0- + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + else if (pr) { + debug('replaceTilde pr', pr); + if (pr.charAt(0) !== '-') + pr = '-' + pr; + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; + + debug('tilde return', ret); + return ret; + }); +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets(comp, loose) { + return comp.trim().split(/\s+/).map(function(comp) { + return replaceCaret(comp, loose); + }).join(' '); +} + +function replaceCaret(comp, loose) { + debug('caret', comp, loose); + var r = loose ? re[CARETLOOSE] : re[CARET]; + return comp.replace(r, function(_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr); + var ret; + + if (isX(M)) + ret = ''; + else if (isX(m)) + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + else if (isX(p)) { + if (M === '0') + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + else + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'; + } else if (pr) { + debug('replaceCaret pr', pr); + if (pr.charAt(0) !== '-') + pr = '-' + pr; + if (M === '0') { + if (m === '0') + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + m + '.' + (+p + 1); + else + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + ret = '>=' + M + '.' + m + '.' + p + pr + + ' <' + (+M + 1) + '.0.0'; + } else { + debug('no pr'); + if (M === '0') { + if (m === '0') + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1); + else + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0'; + } else + ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0'; + } + + debug('caret return', ret); + return ret; + }); +} + +function replaceXRanges(comp, loose) { + debug('replaceXRanges', comp, loose); + return comp.split(/\s+/).map(function(comp) { + return replaceXRange(comp, loose); + }).join(' '); +} + +function replaceXRange(comp, loose) { + comp = comp.trim(); + var r = loose ? re[XRANGELOOSE] : re[XRANGE]; + return comp.replace(r, function(ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr); + var xM = isX(M); + var xm = xM || isX(m); + var xp = xm || isX(p); + var anyX = xp; + + if (gtlt === '=' && anyX) + gtlt = ''; + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0'; + } else { + // nothing is forbidden + ret = '*'; + } + } else if (gtlt && anyX) { + // replace X with 0 + if (xm) + m = 0; + if (xp) + p = 0; + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>='; + if (xm) { + M = +M + 1; + m = 0; + p = 0; + } else if (xp) { + m = +m + 1; + p = 0; + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<' + if (xm) + M = +M + 1 + else + m = +m + 1 + } + + ret = gtlt + M + '.' + m + '.' + p; + } else if (xm) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; + } else if (xp) { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; + } + + debug('xRange return', ret); + + return ret; + }); +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars(comp, loose) { + debug('replaceStars', comp, loose); + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[STAR], ''); +} + +// This function is passed to string.replace(re[HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + + if (isX(fM)) + from = ''; + else if (isX(fm)) + from = '>=' + fM + '.0.0'; + else if (isX(fp)) + from = '>=' + fM + '.' + fm + '.0'; + else + from = '>=' + from; + + if (isX(tM)) + to = ''; + else if (isX(tm)) + to = '<' + (+tM + 1) + '.0.0'; + else if (isX(tp)) + to = '<' + tM + '.' + (+tm + 1) + '.0'; + else if (tpr) + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr; + else + to = '<=' + to; + + return (from + ' ' + to).trim(); +} + + +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function(version) { + if (!version) + return false; + + if (typeof version === 'string') + version = new SemVer(version, this.loose); + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version)) + return true; + } + return false; +}; + +function testSet(set, version) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) + return false; + } + + if (version.prerelease.length) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (var i = 0; i < set.length; i++) { + debug(set[i].semver); + if (set[i].semver === ANY) + continue; + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver; + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) + return true; + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false; + } + + return true; +} + +exports.satisfies = satisfies; +function satisfies(version, range, loose) { + try { + range = new Range(range, loose); + } catch (er) { + return false; + } + return range.test(version); +} + +exports.maxSatisfying = maxSatisfying; +function maxSatisfying(versions, range, loose) { + return versions.filter(function(version) { + return satisfies(version, range, loose); + }).sort(function(a, b) { + return rcompare(a, b, loose); + })[0] || null; +} + +exports.validRange = validRange; +function validRange(range, loose) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, loose).range || '*'; + } catch (er) { + return null; + } +} + +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr; +function ltr(version, range, loose) { + return outside(version, range, '<', loose); +} + +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr; +function gtr(version, range, loose) { + return outside(version, range, '>', loose); +} + +exports.outside = outside; +function outside(version, range, hilo, loose) { + version = new SemVer(version, loose); + range = new Range(range, loose); + + var gtfn, ltefn, ltfn, comp, ecomp; + switch (hilo) { + case '>': + gtfn = gt; + ltefn = lte; + ltfn = lt; + comp = '>'; + ecomp = '>='; + break; + case '<': + gtfn = lt; + ltefn = gte; + ltfn = gt; + comp = '<'; + ecomp = '<='; + break; + default: + throw new TypeError('Must provide a hilo val of "<" or ">"'); + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, loose)) { + return false; + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i]; + + var high = null; + var low = null; + + comparators.forEach(function(comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator; + low = low || comparator; + if (gtfn(comparator.semver, high.semver, loose)) { + high = comparator; + } else if (ltfn(comparator.semver, low.semver, loose)) { + low = comparator; + } + }); + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false; + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false; + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false; + } + } + return true; +} diff --git a/platforms/android/cordova/node_modules/semver/test/big-numbers.js b/platforms/android/cordova/node_modules/semver/test/big-numbers.js new file mode 100644 index 0000000..c051864 --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/test/big-numbers.js @@ -0,0 +1,31 @@ +var test = require('tap').test +var semver = require('../') + +test('long version is too long', function (t) { + var v = '1.2.' + new Array(256).join('1') + t.throws(function () { + new semver.SemVer(v) + }) + t.equal(semver.valid(v, false), null) + t.equal(semver.valid(v, true), null) + t.equal(semver.inc(v, 'patch'), null) + t.end() +}) + +test('big number is like too long version', function (t) { + var v = '1.2.' + new Array(100).join('1') + t.throws(function () { + new semver.SemVer(v) + }) + t.equal(semver.valid(v, false), null) + t.equal(semver.valid(v, true), null) + t.equal(semver.inc(v, 'patch'), null) + t.end() +}) + +test('parsing null does not throw', function (t) { + t.equal(semver.parse(null), null) + t.equal(semver.parse({}), null) + t.equal(semver.parse(new semver.SemVer('1.2.3')).version, '1.2.3') + t.end() +}) diff --git a/platforms/android/cordova/node_modules/semver/test/clean.js b/platforms/android/cordova/node_modules/semver/test/clean.js new file mode 100644 index 0000000..9e268de --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/test/clean.js @@ -0,0 +1,29 @@ +var tap = require('tap'); +var test = tap.test; +var semver = require('../semver.js'); +var clean = semver.clean; + +test('\nclean tests', function(t) { + // [range, version] + // Version should be detectable despite extra characters + [ + ['1.2.3', '1.2.3'], + [' 1.2.3 ', '1.2.3'], + [' 1.2.3-4 ', '1.2.3-4'], + [' 1.2.3-pre ', '1.2.3-pre'], + [' =v1.2.3 ', '1.2.3'], + ['v1.2.3', '1.2.3'], + [' v1.2.3 ', '1.2.3'], + ['\t1.2.3', '1.2.3'], + ['>1.2.3', null], + ['~1.2.3', null], + ['<=1.2.3', null], + ['1.2.x', null] + ].forEach(function(tuple) { + var range = tuple[0]; + var version = tuple[1]; + var msg = 'clean(' + range + ') = ' + version; + t.equal(clean(range), version, msg); + }); + t.end(); +}); diff --git a/platforms/android/cordova/node_modules/semver/test/gtr.js b/platforms/android/cordova/node_modules/semver/test/gtr.js new file mode 100644 index 0000000..bbb8789 --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/test/gtr.js @@ -0,0 +1,173 @@ +var tap = require('tap'); +var test = tap.test; +var semver = require('../semver.js'); +var gtr = semver.gtr; + +test('\ngtr tests', function(t) { + // [range, version, loose] + // Version should be greater than range + [ + ['~1.2.2', '1.3.0'], + ['~0.6.1-1', '0.7.1-1'], + ['1.0.0 - 2.0.0', '2.0.1'], + ['1.0.0', '1.0.1-beta1'], + ['1.0.0', '2.0.0'], + ['<=2.0.0', '2.1.1'], + ['<=2.0.0', '3.2.9'], + ['<2.0.0', '2.0.0'], + ['0.1.20 || 1.2.4', '1.2.5'], + ['2.x.x', '3.0.0'], + ['1.2.x', '1.3.0'], + ['1.2.x || 2.x', '3.0.0'], + ['2.*.*', '5.0.1'], + ['1.2.*', '1.3.3'], + ['1.2.* || 2.*', '4.0.0'], + ['2', '3.0.0'], + ['2.3', '2.4.2'], + ['~2.4', '2.5.0'], // >=2.4.0 <2.5.0 + ['~2.4', '2.5.5'], + ['~>3.2.1', '3.3.0'], // >=3.2.1 <3.3.0 + ['~1', '2.2.3'], // >=1.0.0 <2.0.0 + ['~>1', '2.2.4'], + ['~> 1', '3.2.3'], + ['~1.0', '1.1.2'], // >=1.0.0 <1.1.0 + ['~ 1.0', '1.1.0'], + ['<1.2', '1.2.0'], + ['< 1.2', '1.2.1'], + ['1', '2.0.0beta', true], + ['~v0.5.4-pre', '0.6.0'], + ['~v0.5.4-pre', '0.6.1-pre'], + ['=0.7.x', '0.8.0'], + ['=0.7.x', '0.8.0-asdf'], + ['<0.7.x', '0.7.0'], + ['~1.2.2', '1.3.0'], + ['1.0.0 - 2.0.0', '2.2.3'], + ['1.0.0', '1.0.1'], + ['<=2.0.0', '3.0.0'], + ['<=2.0.0', '2.9999.9999'], + ['<=2.0.0', '2.2.9'], + ['<2.0.0', '2.9999.9999'], + ['<2.0.0', '2.2.9'], + ['2.x.x', '3.1.3'], + ['1.2.x', '1.3.3'], + ['1.2.x || 2.x', '3.1.3'], + ['2.*.*', '3.1.3'], + ['1.2.*', '1.3.3'], + ['1.2.* || 2.*', '3.1.3'], + ['2', '3.1.2'], + ['2.3', '2.4.1'], + ['~2.4', '2.5.0'], // >=2.4.0 <2.5.0 + ['~>3.2.1', '3.3.2'], // >=3.2.1 <3.3.0 + ['~1', '2.2.3'], // >=1.0.0 <2.0.0 + ['~>1', '2.2.3'], + ['~1.0', '1.1.0'], // >=1.0.0 <1.1.0 + ['<1', '1.0.0'], + ['1', '2.0.0beta', true], + ['<1', '1.0.0beta', true], + ['< 1', '1.0.0beta', true], + ['=0.7.x', '0.8.2'], + ['<0.7.x', '0.7.2'] + ].forEach(function(tuple) { + var range = tuple[0]; + var version = tuple[1]; + var loose = tuple[2] || false; + var msg = 'gtr(' + version + ', ' + range + ', ' + loose + ')'; + t.ok(gtr(version, range, loose), msg); + }); + t.end(); +}); + +test('\nnegative gtr tests', function(t) { + // [range, version, loose] + // Version should NOT be greater than range + [ + ['~0.6.1-1', '0.6.1-1'], + ['1.0.0 - 2.0.0', '1.2.3'], + ['1.0.0 - 2.0.0', '0.9.9'], + ['1.0.0', '1.0.0'], + ['>=*', '0.2.4'], + ['', '1.0.0', true], + ['*', '1.2.3'], + ['*', 'v1.2.3-foo'], + ['>=1.0.0', '1.0.0'], + ['>=1.0.0', '1.0.1'], + ['>=1.0.0', '1.1.0'], + ['>1.0.0', '1.0.1'], + ['>1.0.0', '1.1.0'], + ['<=2.0.0', '2.0.0'], + ['<=2.0.0', '1.9999.9999'], + ['<=2.0.0', '0.2.9'], + ['<2.0.0', '1.9999.9999'], + ['<2.0.0', '0.2.9'], + ['>= 1.0.0', '1.0.0'], + ['>= 1.0.0', '1.0.1'], + ['>= 1.0.0', '1.1.0'], + ['> 1.0.0', '1.0.1'], + ['> 1.0.0', '1.1.0'], + ['<= 2.0.0', '2.0.0'], + ['<= 2.0.0', '1.9999.9999'], + ['<= 2.0.0', '0.2.9'], + ['< 2.0.0', '1.9999.9999'], + ['<\t2.0.0', '0.2.9'], + ['>=0.1.97', 'v0.1.97'], + ['>=0.1.97', '0.1.97'], + ['0.1.20 || 1.2.4', '1.2.4'], + ['0.1.20 || >1.2.4', '1.2.4'], + ['0.1.20 || 1.2.4', '1.2.3'], + ['0.1.20 || 1.2.4', '0.1.20'], + ['>=0.2.3 || <0.0.1', '0.0.0'], + ['>=0.2.3 || <0.0.1', '0.2.3'], + ['>=0.2.3 || <0.0.1', '0.2.4'], + ['||', '1.3.4'], + ['2.x.x', '2.1.3'], + ['1.2.x', '1.2.3'], + ['1.2.x || 2.x', '2.1.3'], + ['1.2.x || 2.x', '1.2.3'], + ['x', '1.2.3'], + ['2.*.*', '2.1.3'], + ['1.2.*', '1.2.3'], + ['1.2.* || 2.*', '2.1.3'], + ['1.2.* || 2.*', '1.2.3'], + ['1.2.* || 2.*', '1.2.3'], + ['*', '1.2.3'], + ['2', '2.1.2'], + ['2.3', '2.3.1'], + ['~2.4', '2.4.0'], // >=2.4.0 <2.5.0 + ['~2.4', '2.4.5'], + ['~>3.2.1', '3.2.2'], // >=3.2.1 <3.3.0 + ['~1', '1.2.3'], // >=1.0.0 <2.0.0 + ['~>1', '1.2.3'], + ['~> 1', '1.2.3'], + ['~1.0', '1.0.2'], // >=1.0.0 <1.1.0 + ['~ 1.0', '1.0.2'], + ['>=1', '1.0.0'], + ['>= 1', '1.0.0'], + ['<1.2', '1.1.1'], + ['< 1.2', '1.1.1'], + ['1', '1.0.0beta', true], + ['~v0.5.4-pre', '0.5.5'], + ['~v0.5.4-pre', '0.5.4'], + ['=0.7.x', '0.7.2'], + ['>=0.7.x', '0.7.2'], + ['=0.7.x', '0.7.0-asdf'], + ['>=0.7.x', '0.7.0-asdf'], + ['<=0.7.x', '0.6.2'], + ['>0.2.3 >0.2.4 <=0.2.5', '0.2.5'], + ['>=0.2.3 <=0.2.4', '0.2.4'], + ['1.0.0 - 2.0.0', '2.0.0'], + ['^1', '0.0.0-0'], + ['^3.0.0', '2.0.0'], + ['^1.0.0 || ~2.0.1', '2.0.0'], + ['^0.1.0 || ~3.0.1 || 5.0.0', '3.2.0'], + ['^0.1.0 || ~3.0.1 || 5.0.0', '1.0.0beta', true], + ['^0.1.0 || ~3.0.1 || 5.0.0', '5.0.0-0', true], + ['^0.1.0 || ~3.0.1 || >4 <=5.0.0', '3.5.0'] + ].forEach(function(tuple) { + var range = tuple[0]; + var version = tuple[1]; + var loose = tuple[2] || false; + var msg = '!gtr(' + version + ', ' + range + ', ' + loose + ')'; + t.notOk(gtr(version, range, loose), msg); + }); + t.end(); +}); diff --git a/platforms/android/cordova/node_modules/semver/test/index.js b/platforms/android/cordova/node_modules/semver/test/index.js new file mode 100644 index 0000000..47c3f5f --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/test/index.js @@ -0,0 +1,698 @@ +'use strict'; + +var tap = require('tap'); +var test = tap.test; +var semver = require('../semver.js'); +var eq = semver.eq; +var gt = semver.gt; +var lt = semver.lt; +var neq = semver.neq; +var cmp = semver.cmp; +var gte = semver.gte; +var lte = semver.lte; +var satisfies = semver.satisfies; +var validRange = semver.validRange; +var inc = semver.inc; +var diff = semver.diff; +var replaceStars = semver.replaceStars; +var toComparators = semver.toComparators; +var SemVer = semver.SemVer; +var Range = semver.Range; + +test('\ncomparison tests', function(t) { + // [version1, version2] + // version1 should be greater than version2 + [['0.0.0', '0.0.0-foo'], + ['0.0.1', '0.0.0'], + ['1.0.0', '0.9.9'], + ['0.10.0', '0.9.0'], + ['0.99.0', '0.10.0'], + ['2.0.0', '1.2.3'], + ['v0.0.0', '0.0.0-foo', true], + ['v0.0.1', '0.0.0', true], + ['v1.0.0', '0.9.9', true], + ['v0.10.0', '0.9.0', true], + ['v0.99.0', '0.10.0', true], + ['v2.0.0', '1.2.3', true], + ['0.0.0', 'v0.0.0-foo', true], + ['0.0.1', 'v0.0.0', true], + ['1.0.0', 'v0.9.9', true], + ['0.10.0', 'v0.9.0', true], + ['0.99.0', 'v0.10.0', true], + ['2.0.0', 'v1.2.3', true], + ['1.2.3', '1.2.3-asdf'], + ['1.2.3', '1.2.3-4'], + ['1.2.3', '1.2.3-4-foo'], + ['1.2.3-5-foo', '1.2.3-5'], + ['1.2.3-5', '1.2.3-4'], + ['1.2.3-5-foo', '1.2.3-5-Foo'], + ['3.0.0', '2.7.2+asdf'], + ['1.2.3-a.10', '1.2.3-a.5'], + ['1.2.3-a.b', '1.2.3-a.5'], + ['1.2.3-a.b', '1.2.3-a'], + ['1.2.3-a.b.c.10.d.5', '1.2.3-a.b.c.5.d.100'], + ['1.2.3-r2', '1.2.3-r100'], + ['1.2.3-r100', '1.2.3-R2'] + ].forEach(function(v) { + var v0 = v[0]; + var v1 = v[1]; + var loose = v[2]; + t.ok(gt(v0, v1, loose), "gt('" + v0 + "', '" + v1 + "')"); + t.ok(lt(v1, v0, loose), "lt('" + v1 + "', '" + v0 + "')"); + t.ok(!gt(v1, v0, loose), "!gt('" + v1 + "', '" + v0 + "')"); + t.ok(!lt(v0, v1, loose), "!lt('" + v0 + "', '" + v1 + "')"); + t.ok(eq(v0, v0, loose), "eq('" + v0 + "', '" + v0 + "')"); + t.ok(eq(v1, v1, loose), "eq('" + v1 + "', '" + v1 + "')"); + t.ok(neq(v0, v1, loose), "neq('" + v0 + "', '" + v1 + "')"); + t.ok(cmp(v1, '==', v1, loose), "cmp('" + v1 + "' == '" + v1 + "')"); + t.ok(cmp(v0, '>=', v1, loose), "cmp('" + v0 + "' >= '" + v1 + "')"); + t.ok(cmp(v1, '<=', v0, loose), "cmp('" + v1 + "' <= '" + v0 + "')"); + t.ok(cmp(v0, '!=', v1, loose), "cmp('" + v0 + "' != '" + v1 + "')"); + }); + t.end(); +}); + +test('\nequality tests', function(t) { + // [version1, version2] + // version1 should be equivalent to version2 + [['1.2.3', 'v1.2.3', true], + ['1.2.3', '=1.2.3', true], + ['1.2.3', 'v 1.2.3', true], + ['1.2.3', '= 1.2.3', true], + ['1.2.3', ' v1.2.3', true], + ['1.2.3', ' =1.2.3', true], + ['1.2.3', ' v 1.2.3', true], + ['1.2.3', ' = 1.2.3', true], + ['1.2.3-0', 'v1.2.3-0', true], + ['1.2.3-0', '=1.2.3-0', true], + ['1.2.3-0', 'v 1.2.3-0', true], + ['1.2.3-0', '= 1.2.3-0', true], + ['1.2.3-0', ' v1.2.3-0', true], + ['1.2.3-0', ' =1.2.3-0', true], + ['1.2.3-0', ' v 1.2.3-0', true], + ['1.2.3-0', ' = 1.2.3-0', true], + ['1.2.3-1', 'v1.2.3-1', true], + ['1.2.3-1', '=1.2.3-1', true], + ['1.2.3-1', 'v 1.2.3-1', true], + ['1.2.3-1', '= 1.2.3-1', true], + ['1.2.3-1', ' v1.2.3-1', true], + ['1.2.3-1', ' =1.2.3-1', true], + ['1.2.3-1', ' v 1.2.3-1', true], + ['1.2.3-1', ' = 1.2.3-1', true], + ['1.2.3-beta', 'v1.2.3-beta', true], + ['1.2.3-beta', '=1.2.3-beta', true], + ['1.2.3-beta', 'v 1.2.3-beta', true], + ['1.2.3-beta', '= 1.2.3-beta', true], + ['1.2.3-beta', ' v1.2.3-beta', true], + ['1.2.3-beta', ' =1.2.3-beta', true], + ['1.2.3-beta', ' v 1.2.3-beta', true], + ['1.2.3-beta', ' = 1.2.3-beta', true], + ['1.2.3-beta+build', ' = 1.2.3-beta+otherbuild', true], + ['1.2.3+build', ' = 1.2.3+otherbuild', true], + ['1.2.3-beta+build', '1.2.3-beta+otherbuild'], + ['1.2.3+build', '1.2.3+otherbuild'], + [' v1.2.3+build', '1.2.3+otherbuild'] + ].forEach(function(v) { + var v0 = v[0]; + var v1 = v[1]; + var loose = v[2]; + t.ok(eq(v0, v1, loose), "eq('" + v0 + "', '" + v1 + "')"); + t.ok(!neq(v0, v1, loose), "!neq('" + v0 + "', '" + v1 + "')"); + t.ok(cmp(v0, '==', v1, loose), 'cmp(' + v0 + '==' + v1 + ')'); + t.ok(!cmp(v0, '!=', v1, loose), '!cmp(' + v0 + '!=' + v1 + ')'); + t.ok(!cmp(v0, '===', v1, loose), '!cmp(' + v0 + '===' + v1 + ')'); + t.ok(cmp(v0, '!==', v1, loose), 'cmp(' + v0 + '!==' + v1 + ')'); + t.ok(!gt(v0, v1, loose), "!gt('" + v0 + "', '" + v1 + "')"); + t.ok(gte(v0, v1, loose), "gte('" + v0 + "', '" + v1 + "')"); + t.ok(!lt(v0, v1, loose), "!lt('" + v0 + "', '" + v1 + "')"); + t.ok(lte(v0, v1, loose), "lte('" + v0 + "', '" + v1 + "')"); + }); + t.end(); +}); + + +test('\nrange tests', function(t) { + // [range, version] + // version should be included by range + [['1.0.0 - 2.0.0', '1.2.3'], + ['^1.2.3+build', '1.2.3'], + ['^1.2.3+build', '1.3.0'], + ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '1.2.3'], + ['1.2.3pre+asdf - 2.4.3-pre+asdf', '1.2.3', true], + ['1.2.3-pre+asdf - 2.4.3pre+asdf', '1.2.3', true], + ['1.2.3pre+asdf - 2.4.3pre+asdf', '1.2.3', true], + ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '1.2.3-pre.2'], + ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '2.4.3-alpha'], + ['1.2.3+asdf - 2.4.3+asdf', '1.2.3'], + ['1.0.0', '1.0.0'], + ['>=*', '0.2.4'], + ['', '1.0.0'], + ['*', '1.2.3'], + ['*', 'v1.2.3', true], + ['>=1.0.0', '1.0.0'], + ['>=1.0.0', '1.0.1'], + ['>=1.0.0', '1.1.0'], + ['>1.0.0', '1.0.1'], + ['>1.0.0', '1.1.0'], + ['<=2.0.0', '2.0.0'], + ['<=2.0.0', '1.9999.9999'], + ['<=2.0.0', '0.2.9'], + ['<2.0.0', '1.9999.9999'], + ['<2.0.0', '0.2.9'], + ['>= 1.0.0', '1.0.0'], + ['>= 1.0.0', '1.0.1'], + ['>= 1.0.0', '1.1.0'], + ['> 1.0.0', '1.0.1'], + ['> 1.0.0', '1.1.0'], + ['<= 2.0.0', '2.0.0'], + ['<= 2.0.0', '1.9999.9999'], + ['<= 2.0.0', '0.2.9'], + ['< 2.0.0', '1.9999.9999'], + ['<\t2.0.0', '0.2.9'], + ['>=0.1.97', 'v0.1.97', true], + ['>=0.1.97', '0.1.97'], + ['0.1.20 || 1.2.4', '1.2.4'], + ['>=0.2.3 || <0.0.1', '0.0.0'], + ['>=0.2.3 || <0.0.1', '0.2.3'], + ['>=0.2.3 || <0.0.1', '0.2.4'], + ['||', '1.3.4'], + ['2.x.x', '2.1.3'], + ['1.2.x', '1.2.3'], + ['1.2.x || 2.x', '2.1.3'], + ['1.2.x || 2.x', '1.2.3'], + ['x', '1.2.3'], + ['2.*.*', '2.1.3'], + ['1.2.*', '1.2.3'], + ['1.2.* || 2.*', '2.1.3'], + ['1.2.* || 2.*', '1.2.3'], + ['*', '1.2.3'], + ['2', '2.1.2'], + ['2.3', '2.3.1'], + ['~2.4', '2.4.0'], // >=2.4.0 <2.5.0 + ['~2.4', '2.4.5'], + ['~>3.2.1', '3.2.2'], // >=3.2.1 <3.3.0, + ['~1', '1.2.3'], // >=1.0.0 <2.0.0 + ['~>1', '1.2.3'], + ['~> 1', '1.2.3'], + ['~1.0', '1.0.2'], // >=1.0.0 <1.1.0, + ['~ 1.0', '1.0.2'], + ['~ 1.0.3', '1.0.12'], + ['>=1', '1.0.0'], + ['>= 1', '1.0.0'], + ['<1.2', '1.1.1'], + ['< 1.2', '1.1.1'], + ['~v0.5.4-pre', '0.5.5'], + ['~v0.5.4-pre', '0.5.4'], + ['=0.7.x', '0.7.2'], + ['<=0.7.x', '0.7.2'], + ['>=0.7.x', '0.7.2'], + ['<=0.7.x', '0.6.2'], + ['~1.2.1 >=1.2.3', '1.2.3'], + ['~1.2.1 =1.2.3', '1.2.3'], + ['~1.2.1 1.2.3', '1.2.3'], + ['~1.2.1 >=1.2.3 1.2.3', '1.2.3'], + ['~1.2.1 1.2.3 >=1.2.3', '1.2.3'], + ['~1.2.1 1.2.3', '1.2.3'], + ['>=1.2.1 1.2.3', '1.2.3'], + ['1.2.3 >=1.2.1', '1.2.3'], + ['>=1.2.3 >=1.2.1', '1.2.3'], + ['>=1.2.1 >=1.2.3', '1.2.3'], + ['>=1.2', '1.2.8'], + ['^1.2.3', '1.8.1'], + ['^0.1.2', '0.1.2'], + ['^0.1', '0.1.2'], + ['^1.2', '1.4.2'], + ['^1.2 ^1', '1.4.2'], + ['^1.2.3-alpha', '1.2.3-pre'], + ['^1.2.0-alpha', '1.2.0-pre'], + ['^0.0.1-alpha', '0.0.1-beta'] + ].forEach(function(v) { + var range = v[0]; + var ver = v[1]; + var loose = v[2]; + t.ok(satisfies(ver, range, loose), range + ' satisfied by ' + ver); + }); + t.end(); +}); + +test('\nnegative range tests', function(t) { + // [range, version] + // version should not be included by range + [['1.0.0 - 2.0.0', '2.2.3'], + ['1.2.3+asdf - 2.4.3+asdf', '1.2.3-pre.2'], + ['1.2.3+asdf - 2.4.3+asdf', '2.4.3-alpha'], + ['^1.2.3+build', '2.0.0'], + ['^1.2.3+build', '1.2.0'], + ['^1.2.3', '1.2.3-pre'], + ['^1.2', '1.2.0-pre'], + ['>1.2', '1.3.0-beta'], + ['<=1.2.3', '1.2.3-beta'], + ['^1.2.3', '1.2.3-beta'], + ['=0.7.x', '0.7.0-asdf'], + ['>=0.7.x', '0.7.0-asdf'], + ['1', '1.0.0beta', true], + ['<1', '1.0.0beta', true], + ['< 1', '1.0.0beta', true], + ['1.0.0', '1.0.1'], + ['>=1.0.0', '0.0.0'], + ['>=1.0.0', '0.0.1'], + ['>=1.0.0', '0.1.0'], + ['>1.0.0', '0.0.1'], + ['>1.0.0', '0.1.0'], + ['<=2.0.0', '3.0.0'], + ['<=2.0.0', '2.9999.9999'], + ['<=2.0.0', '2.2.9'], + ['<2.0.0', '2.9999.9999'], + ['<2.0.0', '2.2.9'], + ['>=0.1.97', 'v0.1.93', true], + ['>=0.1.97', '0.1.93'], + ['0.1.20 || 1.2.4', '1.2.3'], + ['>=0.2.3 || <0.0.1', '0.0.3'], + ['>=0.2.3 || <0.0.1', '0.2.2'], + ['2.x.x', '1.1.3'], + ['2.x.x', '3.1.3'], + ['1.2.x', '1.3.3'], + ['1.2.x || 2.x', '3.1.3'], + ['1.2.x || 2.x', '1.1.3'], + ['2.*.*', '1.1.3'], + ['2.*.*', '3.1.3'], + ['1.2.*', '1.3.3'], + ['1.2.* || 2.*', '3.1.3'], + ['1.2.* || 2.*', '1.1.3'], + ['2', '1.1.2'], + ['2.3', '2.4.1'], + ['~2.4', '2.5.0'], // >=2.4.0 <2.5.0 + ['~2.4', '2.3.9'], + ['~>3.2.1', '3.3.2'], // >=3.2.1 <3.3.0 + ['~>3.2.1', '3.2.0'], // >=3.2.1 <3.3.0 + ['~1', '0.2.3'], // >=1.0.0 <2.0.0 + ['~>1', '2.2.3'], + ['~1.0', '1.1.0'], // >=1.0.0 <1.1.0 + ['<1', '1.0.0'], + ['>=1.2', '1.1.1'], + ['1', '2.0.0beta', true], + ['~v0.5.4-beta', '0.5.4-alpha'], + ['=0.7.x', '0.8.2'], + ['>=0.7.x', '0.6.2'], + ['<0.7.x', '0.7.2'], + ['<1.2.3', '1.2.3-beta'], + ['=1.2.3', '1.2.3-beta'], + ['>1.2', '1.2.8'], + ['^1.2.3', '2.0.0-alpha'], + ['^1.2.3', '1.2.2'], + ['^1.2', '1.1.9'], + ['*', 'v1.2.3-foo', true], + // invalid ranges never satisfied! + ['blerg', '1.2.3'], + ['git+https://user:password0123@github.com/foo', '123.0.0', true], + ['^1.2.3', '2.0.0-pre'] + ].forEach(function(v) { + var range = v[0]; + var ver = v[1]; + var loose = v[2]; + var found = satisfies(ver, range, loose); + t.ok(!found, ver + ' not satisfied by ' + range); + }); + t.end(); +}); + +test('\nincrement versions test', function(t) { +// [version, inc, result, identifier] +// inc(version, inc) -> result + [['1.2.3', 'major', '2.0.0'], + ['1.2.3', 'minor', '1.3.0'], + ['1.2.3', 'patch', '1.2.4'], + ['1.2.3tag', 'major', '2.0.0', true], + ['1.2.3-tag', 'major', '2.0.0'], + ['1.2.3', 'fake', null], + ['1.2.0-0', 'patch', '1.2.0'], + ['fake', 'major', null], + ['1.2.3-4', 'major', '2.0.0'], + ['1.2.3-4', 'minor', '1.3.0'], + ['1.2.3-4', 'patch', '1.2.3'], + ['1.2.3-alpha.0.beta', 'major', '2.0.0'], + ['1.2.3-alpha.0.beta', 'minor', '1.3.0'], + ['1.2.3-alpha.0.beta', 'patch', '1.2.3'], + ['1.2.4', 'prerelease', '1.2.5-0'], + ['1.2.3-0', 'prerelease', '1.2.3-1'], + ['1.2.3-alpha.0', 'prerelease', '1.2.3-alpha.1'], + ['1.2.3-alpha.1', 'prerelease', '1.2.3-alpha.2'], + ['1.2.3-alpha.2', 'prerelease', '1.2.3-alpha.3'], + ['1.2.3-alpha.0.beta', 'prerelease', '1.2.3-alpha.1.beta'], + ['1.2.3-alpha.1.beta', 'prerelease', '1.2.3-alpha.2.beta'], + ['1.2.3-alpha.2.beta', 'prerelease', '1.2.3-alpha.3.beta'], + ['1.2.3-alpha.10.0.beta', 'prerelease', '1.2.3-alpha.10.1.beta'], + ['1.2.3-alpha.10.1.beta', 'prerelease', '1.2.3-alpha.10.2.beta'], + ['1.2.3-alpha.10.2.beta', 'prerelease', '1.2.3-alpha.10.3.beta'], + ['1.2.3-alpha.10.beta.0', 'prerelease', '1.2.3-alpha.10.beta.1'], + ['1.2.3-alpha.10.beta.1', 'prerelease', '1.2.3-alpha.10.beta.2'], + ['1.2.3-alpha.10.beta.2', 'prerelease', '1.2.3-alpha.10.beta.3'], + ['1.2.3-alpha.9.beta', 'prerelease', '1.2.3-alpha.10.beta'], + ['1.2.3-alpha.10.beta', 'prerelease', '1.2.3-alpha.11.beta'], + ['1.2.3-alpha.11.beta', 'prerelease', '1.2.3-alpha.12.beta'], + ['1.2.0', 'prepatch', '1.2.1-0'], + ['1.2.0-1', 'prepatch', '1.2.1-0'], + ['1.2.0', 'preminor', '1.3.0-0'], + ['1.2.3-1', 'preminor', '1.3.0-0'], + ['1.2.0', 'premajor', '2.0.0-0'], + ['1.2.3-1', 'premajor', '2.0.0-0'], + ['1.2.0-1', 'minor', '1.2.0'], + ['1.0.0-1', 'major', '1.0.0'], + + ['1.2.3', 'major', '2.0.0', false, 'dev'], + ['1.2.3', 'minor', '1.3.0', false, 'dev'], + ['1.2.3', 'patch', '1.2.4', false, 'dev'], + ['1.2.3tag', 'major', '2.0.0', true, 'dev'], + ['1.2.3-tag', 'major', '2.0.0', false, 'dev'], + ['1.2.3', 'fake', null, false, 'dev'], + ['1.2.0-0', 'patch', '1.2.0', false, 'dev'], + ['fake', 'major', null, false, 'dev'], + ['1.2.3-4', 'major', '2.0.0', false, 'dev'], + ['1.2.3-4', 'minor', '1.3.0', false, 'dev'], + ['1.2.3-4', 'patch', '1.2.3', false, 'dev'], + ['1.2.3-alpha.0.beta', 'major', '2.0.0', false, 'dev'], + ['1.2.3-alpha.0.beta', 'minor', '1.3.0', false, 'dev'], + ['1.2.3-alpha.0.beta', 'patch', '1.2.3', false, 'dev'], + ['1.2.4', 'prerelease', '1.2.5-dev.0', false, 'dev'], + ['1.2.3-0', 'prerelease', '1.2.3-dev.0', false, 'dev'], + ['1.2.3-alpha.0', 'prerelease', '1.2.3-dev.0', false, 'dev'], + ['1.2.3-alpha.0', 'prerelease', '1.2.3-alpha.1', false, 'alpha'], + ['1.2.3-alpha.0.beta', 'prerelease', '1.2.3-dev.0', false, 'dev'], + ['1.2.3-alpha.0.beta', 'prerelease', '1.2.3-alpha.1.beta', false, 'alpha'], + ['1.2.3-alpha.10.0.beta', 'prerelease', '1.2.3-dev.0', false, 'dev'], + ['1.2.3-alpha.10.0.beta', 'prerelease', '1.2.3-alpha.10.1.beta', false, 'alpha'], + ['1.2.3-alpha.10.1.beta', 'prerelease', '1.2.3-alpha.10.2.beta', false, 'alpha'], + ['1.2.3-alpha.10.2.beta', 'prerelease', '1.2.3-alpha.10.3.beta', false, 'alpha'], + ['1.2.3-alpha.10.beta.0', 'prerelease', '1.2.3-dev.0', false, 'dev'], + ['1.2.3-alpha.10.beta.0', 'prerelease', '1.2.3-alpha.10.beta.1', false, 'alpha'], + ['1.2.3-alpha.10.beta.1', 'prerelease', '1.2.3-alpha.10.beta.2', false, 'alpha'], + ['1.2.3-alpha.10.beta.2', 'prerelease', '1.2.3-alpha.10.beta.3', false, 'alpha'], + ['1.2.3-alpha.9.beta', 'prerelease', '1.2.3-dev.0', false, 'dev'], + ['1.2.3-alpha.9.beta', 'prerelease', '1.2.3-alpha.10.beta', false, 'alpha'], + ['1.2.3-alpha.10.beta', 'prerelease', '1.2.3-alpha.11.beta', false, 'alpha'], + ['1.2.3-alpha.11.beta', 'prerelease', '1.2.3-alpha.12.beta', false, 'alpha'], + ['1.2.0', 'prepatch', '1.2.1-dev.0', false, 'dev'], + ['1.2.0-1', 'prepatch', '1.2.1-dev.0', false, 'dev'], + ['1.2.0', 'preminor', '1.3.0-dev.0', false, 'dev'], + ['1.2.3-1', 'preminor', '1.3.0-dev.0', false, 'dev'], + ['1.2.0', 'premajor', '2.0.0-dev.0', false, 'dev'], + ['1.2.3-1', 'premajor', '2.0.0-dev.0', false, 'dev'], + ['1.2.0-1', 'minor', '1.2.0', false, 'dev'], + ['1.0.0-1', 'major', '1.0.0', false, 'dev'], + ['1.2.3-dev.bar', 'prerelease', '1.2.3-dev.0', false, 'dev'] + + ].forEach(function(v) { + var pre = v[0]; + var what = v[1]; + var wanted = v[2]; + var loose = v[3]; + var id = v[4]; + var found = inc(pre, what, loose, id); + var cmd = 'inc(' + pre + ', ' + what + ', ' + id + ')'; + t.equal(found, wanted, cmd + ' === ' + wanted); + + var parsed = semver.parse(pre, loose); + if (wanted) { + parsed.inc(what, id); + t.equal(parsed.version, wanted, cmd + ' object version updated'); + t.equal(parsed.raw, wanted, cmd + ' object raw field updated'); + } else if (parsed) { + t.throws(function () { + parsed.inc(what, id) + }) + } else { + t.equal(parsed, null) + } + }); + + t.end(); +}); + +test('\ndiff versions test', function(t) { +// [version1, version2, result] +// diff(version1, version2) -> result + [['1.2.3', '0.2.3', 'major'], + ['1.4.5', '0.2.3', 'major'], + ['1.2.3', '2.0.0-pre', 'premajor'], + ['1.2.3', '1.3.3', 'minor'], + ['1.0.1', '1.1.0-pre', 'preminor'], + ['1.2.3', '1.2.4', 'patch'], + ['1.2.3', '1.2.4-pre', 'prepatch'], + ['0.0.1', '0.0.1-pre', 'prerelease'], + ['0.0.1', '0.0.1-pre-2', 'prerelease'], + ['1.1.0', '1.1.0-pre', 'prerelease'], + ['1.1.0-pre-1', '1.1.0-pre-2', 'prerelease'], + ['1.0.0', '1.0.0', null] + + ].forEach(function(v) { + var version1 = v[0]; + var version2 = v[1]; + var wanted = v[2]; + var found = diff(version1, version2); + var cmd = 'diff(' + version1 + ', ' + version2 + ')'; + t.equal(found, wanted, cmd + ' === ' + wanted); + }); + + t.end(); +}); + +test('\nvalid range test', function(t) { + // [range, result] + // validRange(range) -> result + // translate ranges into their canonical form + [['1.0.0 - 2.0.0', '>=1.0.0 <=2.0.0'], + ['1.0.0', '1.0.0'], + ['>=*', '*'], + ['', '*'], + ['*', '*'], + ['*', '*'], + ['>=1.0.0', '>=1.0.0'], + ['>1.0.0', '>1.0.0'], + ['<=2.0.0', '<=2.0.0'], + ['1', '>=1.0.0 <2.0.0'], + ['<=2.0.0', '<=2.0.0'], + ['<=2.0.0', '<=2.0.0'], + ['<2.0.0', '<2.0.0'], + ['<2.0.0', '<2.0.0'], + ['>= 1.0.0', '>=1.0.0'], + ['>= 1.0.0', '>=1.0.0'], + ['>= 1.0.0', '>=1.0.0'], + ['> 1.0.0', '>1.0.0'], + ['> 1.0.0', '>1.0.0'], + ['<= 2.0.0', '<=2.0.0'], + ['<= 2.0.0', '<=2.0.0'], + ['<= 2.0.0', '<=2.0.0'], + ['< 2.0.0', '<2.0.0'], + ['< 2.0.0', '<2.0.0'], + ['>=0.1.97', '>=0.1.97'], + ['>=0.1.97', '>=0.1.97'], + ['0.1.20 || 1.2.4', '0.1.20||1.2.4'], + ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], + ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], + ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], + ['||', '||'], + ['2.x.x', '>=2.0.0 <3.0.0'], + ['1.2.x', '>=1.2.0 <1.3.0'], + ['1.2.x || 2.x', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], + ['1.2.x || 2.x', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], + ['x', '*'], + ['2.*.*', '>=2.0.0 <3.0.0'], + ['1.2.*', '>=1.2.0 <1.3.0'], + ['1.2.* || 2.*', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], + ['*', '*'], + ['2', '>=2.0.0 <3.0.0'], + ['2.3', '>=2.3.0 <2.4.0'], + ['~2.4', '>=2.4.0 <2.5.0'], + ['~2.4', '>=2.4.0 <2.5.0'], + ['~>3.2.1', '>=3.2.1 <3.3.0'], + ['~1', '>=1.0.0 <2.0.0'], + ['~>1', '>=1.0.0 <2.0.0'], + ['~> 1', '>=1.0.0 <2.0.0'], + ['~1.0', '>=1.0.0 <1.1.0'], + ['~ 1.0', '>=1.0.0 <1.1.0'], + ['^0', '>=0.0.0 <1.0.0'], + ['^ 1', '>=1.0.0 <2.0.0'], + ['^0.1', '>=0.1.0 <0.2.0'], + ['^1.0', '>=1.0.0 <2.0.0'], + ['^1.2', '>=1.2.0 <2.0.0'], + ['^0.0.1', '>=0.0.1 <0.0.2'], + ['^0.0.1-beta', '>=0.0.1-beta <0.0.2'], + ['^0.1.2', '>=0.1.2 <0.2.0'], + ['^1.2.3', '>=1.2.3 <2.0.0'], + ['^1.2.3-beta.4', '>=1.2.3-beta.4 <2.0.0'], + ['<1', '<1.0.0'], + ['< 1', '<1.0.0'], + ['>=1', '>=1.0.0'], + ['>= 1', '>=1.0.0'], + ['<1.2', '<1.2.0'], + ['< 1.2', '<1.2.0'], + ['1', '>=1.0.0 <2.0.0'], + ['>01.02.03', '>1.2.3', true], + ['>01.02.03', null], + ['~1.2.3beta', '>=1.2.3-beta <1.3.0', true], + ['~1.2.3beta', null], + ['^ 1.2 ^ 1', '>=1.2.0 <2.0.0 >=1.0.0 <2.0.0'] + ].forEach(function(v) { + var pre = v[0]; + var wanted = v[1]; + var loose = v[2]; + var found = validRange(pre, loose); + + t.equal(found, wanted, 'validRange(' + pre + ') === ' + wanted); + }); + + t.end(); +}); + +test('\ncomparators test', function(t) { + // [range, comparators] + // turn range into a set of individual comparators + [['1.0.0 - 2.0.0', [['>=1.0.0', '<=2.0.0']]], + ['1.0.0', [['1.0.0']]], + ['>=*', [['']]], + ['', [['']]], + ['*', [['']]], + ['*', [['']]], + ['>=1.0.0', [['>=1.0.0']]], + ['>=1.0.0', [['>=1.0.0']]], + ['>=1.0.0', [['>=1.0.0']]], + ['>1.0.0', [['>1.0.0']]], + ['>1.0.0', [['>1.0.0']]], + ['<=2.0.0', [['<=2.0.0']]], + ['1', [['>=1.0.0', '<2.0.0']]], + ['<=2.0.0', [['<=2.0.0']]], + ['<=2.0.0', [['<=2.0.0']]], + ['<2.0.0', [['<2.0.0']]], + ['<2.0.0', [['<2.0.0']]], + ['>= 1.0.0', [['>=1.0.0']]], + ['>= 1.0.0', [['>=1.0.0']]], + ['>= 1.0.0', [['>=1.0.0']]], + ['> 1.0.0', [['>1.0.0']]], + ['> 1.0.0', [['>1.0.0']]], + ['<= 2.0.0', [['<=2.0.0']]], + ['<= 2.0.0', [['<=2.0.0']]], + ['<= 2.0.0', [['<=2.0.0']]], + ['< 2.0.0', [['<2.0.0']]], + ['<\t2.0.0', [['<2.0.0']]], + ['>=0.1.97', [['>=0.1.97']]], + ['>=0.1.97', [['>=0.1.97']]], + ['0.1.20 || 1.2.4', [['0.1.20'], ['1.2.4']]], + ['>=0.2.3 || <0.0.1', [['>=0.2.3'], ['<0.0.1']]], + ['>=0.2.3 || <0.0.1', [['>=0.2.3'], ['<0.0.1']]], + ['>=0.2.3 || <0.0.1', [['>=0.2.3'], ['<0.0.1']]], + ['||', [[''], ['']]], + ['2.x.x', [['>=2.0.0', '<3.0.0']]], + ['1.2.x', [['>=1.2.0', '<1.3.0']]], + ['1.2.x || 2.x', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], + ['1.2.x || 2.x', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], + ['x', [['']]], + ['2.*.*', [['>=2.0.0', '<3.0.0']]], + ['1.2.*', [['>=1.2.0', '<1.3.0']]], + ['1.2.* || 2.*', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], + ['1.2.* || 2.*', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], + ['*', [['']]], + ['2', [['>=2.0.0', '<3.0.0']]], + ['2.3', [['>=2.3.0', '<2.4.0']]], + ['~2.4', [['>=2.4.0', '<2.5.0']]], + ['~2.4', [['>=2.4.0', '<2.5.0']]], + ['~>3.2.1', [['>=3.2.1', '<3.3.0']]], + ['~1', [['>=1.0.0', '<2.0.0']]], + ['~>1', [['>=1.0.0', '<2.0.0']]], + ['~> 1', [['>=1.0.0', '<2.0.0']]], + ['~1.0', [['>=1.0.0', '<1.1.0']]], + ['~ 1.0', [['>=1.0.0', '<1.1.0']]], + ['~ 1.0.3', [['>=1.0.3', '<1.1.0']]], + ['~> 1.0.3', [['>=1.0.3', '<1.1.0']]], + ['<1', [['<1.0.0']]], + ['< 1', [['<1.0.0']]], + ['>=1', [['>=1.0.0']]], + ['>= 1', [['>=1.0.0']]], + ['<1.2', [['<1.2.0']]], + ['< 1.2', [['<1.2.0']]], + ['1', [['>=1.0.0', '<2.0.0']]], + ['1 2', [['>=1.0.0', '<2.0.0', '>=2.0.0', '<3.0.0']]], + ['1.2 - 3.4.5', [['>=1.2.0', '<=3.4.5']]], + ['1.2.3 - 3.4', [['>=1.2.3', '<3.5.0']]], + ['1.2.3 - 3', [['>=1.2.3', '<4.0.0']]], + ['>*', [['<0.0.0']]], + ['<*', [['<0.0.0']]] + ].forEach(function(v) { + var pre = v[0]; + var wanted = v[1]; + var found = toComparators(v[0]); + var jw = JSON.stringify(wanted); + t.equivalent(found, wanted, 'toComparators(' + pre + ') === ' + jw); + }); + + t.end(); +}); + +test('\ninvalid version numbers', function(t) { + ['1.2.3.4', + 'NOT VALID', + 1.2, + null, + 'Infinity.NaN.Infinity' + ].forEach(function(v) { + t.throws(function() { + new SemVer(v); + }, {name:'TypeError', message:'Invalid Version: ' + v}); + }); + + t.end(); +}); + +test('\nstrict vs loose version numbers', function(t) { + [['=1.2.3', '1.2.3'], + ['01.02.03', '1.2.3'], + ['1.2.3-beta.01', '1.2.3-beta.1'], + [' =1.2.3', '1.2.3'], + ['1.2.3foo', '1.2.3-foo'] + ].forEach(function(v) { + var loose = v[0]; + var strict = v[1]; + t.throws(function() { + new SemVer(loose); + }); + var lv = new SemVer(loose, true); + t.equal(lv.version, strict); + t.ok(eq(loose, strict, true)); + t.throws(function() { + eq(loose, strict); + }); + t.throws(function() { + new SemVer(strict).compare(loose); + }); + }); + t.end(); +}); + +test('\nstrict vs loose ranges', function(t) { + [['>=01.02.03', '>=1.2.3'], + ['~1.02.03beta', '>=1.2.3-beta <1.3.0'] + ].forEach(function(v) { + var loose = v[0]; + var comps = v[1]; + t.throws(function() { + new Range(loose); + }); + t.equal(new Range(loose, true).range, comps); + }); + t.end(); +}); + +test('\nmax satisfying', function(t) { + [[['1.2.3', '1.2.4'], '1.2', '1.2.4'], + [['1.2.4', '1.2.3'], '1.2', '1.2.4'], + [['1.2.3', '1.2.4', '1.2.5', '1.2.6'], '~1.2.3', '1.2.6'], + [['1.1.0', '1.2.0', '1.2.1', '1.3.0', '2.0.0b1', '2.0.0b2', '2.0.0b3', '2.0.0', '2.1.0'], '~2.0.0', '2.0.0', true] + ].forEach(function(v) { + var versions = v[0]; + var range = v[1]; + var expect = v[2]; + var loose = v[3]; + var actual = semver.maxSatisfying(versions, range, loose); + t.equal(actual, expect); + }); + t.end(); +}); diff --git a/platforms/android/cordova/node_modules/semver/test/ltr.js b/platforms/android/cordova/node_modules/semver/test/ltr.js new file mode 100644 index 0000000..0f7167d --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/test/ltr.js @@ -0,0 +1,181 @@ +var tap = require('tap'); +var test = tap.test; +var semver = require('../semver.js'); +var ltr = semver.ltr; + +test('\nltr tests', function(t) { + // [range, version, loose] + // Version should be less than range + [ + ['~1.2.2', '1.2.1'], + ['~0.6.1-1', '0.6.1-0'], + ['1.0.0 - 2.0.0', '0.0.1'], + ['1.0.0-beta.2', '1.0.0-beta.1'], + ['1.0.0', '0.0.0'], + ['>=2.0.0', '1.1.1'], + ['>=2.0.0', '1.2.9'], + ['>2.0.0', '2.0.0'], + ['0.1.20 || 1.2.4', '0.1.5'], + ['2.x.x', '1.0.0'], + ['1.2.x', '1.1.0'], + ['1.2.x || 2.x', '1.0.0'], + ['2.*.*', '1.0.1'], + ['1.2.*', '1.1.3'], + ['1.2.* || 2.*', '1.1.9999'], + ['2', '1.0.0'], + ['2.3', '2.2.2'], + ['~2.4', '2.3.0'], // >=2.4.0 <2.5.0 + ['~2.4', '2.3.5'], + ['~>3.2.1', '3.2.0'], // >=3.2.1 <3.3.0 + ['~1', '0.2.3'], // >=1.0.0 <2.0.0 + ['~>1', '0.2.4'], + ['~> 1', '0.2.3'], + ['~1.0', '0.1.2'], // >=1.0.0 <1.1.0 + ['~ 1.0', '0.1.0'], + ['>1.2', '1.2.0'], + ['> 1.2', '1.2.1'], + ['1', '0.0.0beta', true], + ['~v0.5.4-pre', '0.5.4-alpha'], + ['~v0.5.4-pre', '0.5.4-alpha'], + ['=0.7.x', '0.6.0'], + ['=0.7.x', '0.6.0-asdf'], + ['>=0.7.x', '0.6.0'], + ['~1.2.2', '1.2.1'], + ['1.0.0 - 2.0.0', '0.2.3'], + ['1.0.0', '0.0.1'], + ['>=2.0.0', '1.0.0'], + ['>=2.0.0', '1.9999.9999'], + ['>=2.0.0', '1.2.9'], + ['>2.0.0', '2.0.0'], + ['>2.0.0', '1.2.9'], + ['2.x.x', '1.1.3'], + ['1.2.x', '1.1.3'], + ['1.2.x || 2.x', '1.1.3'], + ['2.*.*', '1.1.3'], + ['1.2.*', '1.1.3'], + ['1.2.* || 2.*', '1.1.3'], + ['2', '1.9999.9999'], + ['2.3', '2.2.1'], + ['~2.4', '2.3.0'], // >=2.4.0 <2.5.0 + ['~>3.2.1', '2.3.2'], // >=3.2.1 <3.3.0 + ['~1', '0.2.3'], // >=1.0.0 <2.0.0 + ['~>1', '0.2.3'], + ['~1.0', '0.0.0'], // >=1.0.0 <1.1.0 + ['>1', '1.0.0'], + ['2', '1.0.0beta', true], + ['>1', '1.0.0beta', true], + ['> 1', '1.0.0beta', true], + ['=0.7.x', '0.6.2'], + ['=0.7.x', '0.7.0-asdf'], + ['^1', '1.0.0-0'], + ['>=0.7.x', '0.7.0-asdf'], + ['1', '1.0.0beta', true], + ['>=0.7.x', '0.6.2'], + ['>1.2.3', '1.3.0-alpha'] + ].forEach(function(tuple) { + var range = tuple[0]; + var version = tuple[1]; + var loose = tuple[2] || false; + var msg = 'ltr(' + version + ', ' + range + ', ' + loose + ')'; + t.ok(ltr(version, range, loose), msg); + }); + t.end(); +}); + +test('\nnegative ltr tests', function(t) { + // [range, version, loose] + // Version should NOT be less than range + [ + ['~ 1.0', '1.1.0'], + ['~0.6.1-1', '0.6.1-1'], + ['1.0.0 - 2.0.0', '1.2.3'], + ['1.0.0 - 2.0.0', '2.9.9'], + ['1.0.0', '1.0.0'], + ['>=*', '0.2.4'], + ['', '1.0.0', true], + ['*', '1.2.3'], + ['>=1.0.0', '1.0.0'], + ['>=1.0.0', '1.0.1'], + ['>=1.0.0', '1.1.0'], + ['>1.0.0', '1.0.1'], + ['>1.0.0', '1.1.0'], + ['<=2.0.0', '2.0.0'], + ['<=2.0.0', '1.9999.9999'], + ['<=2.0.0', '0.2.9'], + ['<2.0.0', '1.9999.9999'], + ['<2.0.0', '0.2.9'], + ['>= 1.0.0', '1.0.0'], + ['>= 1.0.0', '1.0.1'], + ['>= 1.0.0', '1.1.0'], + ['> 1.0.0', '1.0.1'], + ['> 1.0.0', '1.1.0'], + ['<= 2.0.0', '2.0.0'], + ['<= 2.0.0', '1.9999.9999'], + ['<= 2.0.0', '0.2.9'], + ['< 2.0.0', '1.9999.9999'], + ['<\t2.0.0', '0.2.9'], + ['>=0.1.97', 'v0.1.97'], + ['>=0.1.97', '0.1.97'], + ['0.1.20 || 1.2.4', '1.2.4'], + ['0.1.20 || >1.2.4', '1.2.4'], + ['0.1.20 || 1.2.4', '1.2.3'], + ['0.1.20 || 1.2.4', '0.1.20'], + ['>=0.2.3 || <0.0.1', '0.0.0'], + ['>=0.2.3 || <0.0.1', '0.2.3'], + ['>=0.2.3 || <0.0.1', '0.2.4'], + ['||', '1.3.4'], + ['2.x.x', '2.1.3'], + ['1.2.x', '1.2.3'], + ['1.2.x || 2.x', '2.1.3'], + ['1.2.x || 2.x', '1.2.3'], + ['x', '1.2.3'], + ['2.*.*', '2.1.3'], + ['1.2.*', '1.2.3'], + ['1.2.* || 2.*', '2.1.3'], + ['1.2.* || 2.*', '1.2.3'], + ['1.2.* || 2.*', '1.2.3'], + ['*', '1.2.3'], + ['2', '2.1.2'], + ['2.3', '2.3.1'], + ['~2.4', '2.4.0'], // >=2.4.0 <2.5.0 + ['~2.4', '2.4.5'], + ['~>3.2.1', '3.2.2'], // >=3.2.1 <3.3.0 + ['~1', '1.2.3'], // >=1.0.0 <2.0.0 + ['~>1', '1.2.3'], + ['~> 1', '1.2.3'], + ['~1.0', '1.0.2'], // >=1.0.0 <1.1.0 + ['~ 1.0', '1.0.2'], + ['>=1', '1.0.0'], + ['>= 1', '1.0.0'], + ['<1.2', '1.1.1'], + ['< 1.2', '1.1.1'], + ['~v0.5.4-pre', '0.5.5'], + ['~v0.5.4-pre', '0.5.4'], + ['=0.7.x', '0.7.2'], + ['>=0.7.x', '0.7.2'], + ['<=0.7.x', '0.6.2'], + ['>0.2.3 >0.2.4 <=0.2.5', '0.2.5'], + ['>=0.2.3 <=0.2.4', '0.2.4'], + ['1.0.0 - 2.0.0', '2.0.0'], + ['^3.0.0', '4.0.0'], + ['^1.0.0 || ~2.0.1', '2.0.0'], + ['^0.1.0 || ~3.0.1 || 5.0.0', '3.2.0'], + ['^0.1.0 || ~3.0.1 || 5.0.0', '1.0.0beta', true], + ['^0.1.0 || ~3.0.1 || 5.0.0', '5.0.0-0', true], + ['^0.1.0 || ~3.0.1 || >4 <=5.0.0', '3.5.0'], + ['^1.0.0alpha', '1.0.0beta', true], + ['~1.0.0alpha', '1.0.0beta', true], + ['^1.0.0-alpha', '1.0.0beta', true], + ['~1.0.0-alpha', '1.0.0beta', true], + ['^1.0.0-alpha', '1.0.0-beta'], + ['~1.0.0-alpha', '1.0.0-beta'], + ['=0.1.0', '1.0.0'] + ].forEach(function(tuple) { + var range = tuple[0]; + var version = tuple[1]; + var loose = tuple[2] || false; + var msg = '!ltr(' + version + ', ' + range + ', ' + loose + ')'; + t.notOk(ltr(version, range, loose), msg); + }); + t.end(); +}); diff --git a/platforms/android/cordova/node_modules/semver/test/major-minor-patch.js b/platforms/android/cordova/node_modules/semver/test/major-minor-patch.js new file mode 100644 index 0000000..e9d4039 --- /dev/null +++ b/platforms/android/cordova/node_modules/semver/test/major-minor-patch.js @@ -0,0 +1,72 @@ +var tap = require('tap'); +var test = tap.test; +var semver = require('../semver.js'); + +test('\nmajor tests', function(t) { + // [range, version] + // Version should be detectable despite extra characters + [ + ['1.2.3', 1], + [' 1.2.3 ', 1], + [' 2.2.3-4 ', 2], + [' 3.2.3-pre ', 3], + ['v5.2.3', 5], + [' v8.2.3 ', 8], + ['\t13.2.3', 13], + ['=21.2.3', 21, true], + ['v=34.2.3', 34, true] + ].forEach(function(tuple) { + var range = tuple[0]; + var version = tuple[1]; + var loose = tuple[2] || false; + var msg = 'major(' + range + ') = ' + version; + t.equal(semver.major(range, loose), version, msg); + }); + t.end(); +}); + +test('\nminor tests', function(t) { + // [range, version] + // Version should be detectable despite extra characters + [ + ['1.1.3', 1], + [' 1.1.3 ', 1], + [' 1.2.3-4 ', 2], + [' 1.3.3-pre ', 3], + ['v1.5.3', 5], + [' v1.8.3 ', 8], + ['\t1.13.3', 13], + ['=1.21.3', 21, true], + ['v=1.34.3', 34, true] + ].forEach(function(tuple) { + var range = tuple[0]; + var version = tuple[1]; + var loose = tuple[2] || false; + var msg = 'minor(' + range + ') = ' + version; + t.equal(semver.minor(range, loose), version, msg); + }); + t.end(); +}); + +test('\npatch tests', function(t) { + // [range, version] + // Version should be detectable despite extra characters + [ + ['1.2.1', 1], + [' 1.2.1 ', 1], + [' 1.2.2-4 ', 2], + [' 1.2.3-pre ', 3], + ['v1.2.5', 5], + [' v1.2.8 ', 8], + ['\t1.2.13', 13], + ['=1.2.21', 21, true], + ['v=1.2.34', 34, true] + ].forEach(function(tuple) { + var range = tuple[0]; + var version = tuple[1]; + var loose = tuple[2] || false; + var msg = 'patch(' + range + ') = ' + version; + t.equal(semver.patch(range, loose), version, msg); + }); + t.end(); +}); diff --git a/platforms/android/cordova/node_modules/shelljs/.travis.yml b/platforms/android/cordova/node_modules/shelljs/.travis.yml index 99cdc74..1b3280a 100644 --- a/platforms/android/cordova/node_modules/shelljs/.travis.yml +++ b/platforms/android/cordova/node_modules/shelljs/.travis.yml @@ -1,5 +1,6 @@ language: node_js node_js: - - "0.8" - "0.10" - "0.11" + - "0.12" + diff --git a/platforms/android/cordova/node_modules/shelljs/README.md b/platforms/android/cordova/node_modules/shelljs/README.md index 9120623..d08d13e 100644 --- a/platforms/android/cordova/node_modules/shelljs/README.md +++ b/platforms/android/cordova/node_modules/shelljs/README.md @@ -13,6 +13,8 @@ The project is [unit-tested](http://travis-ci.org/arturadib/shelljs) and battled and [many more](https://npmjs.org/browse/depended/shelljs). +Connect with [@r2r](http://twitter.com/r2r) on Twitter for questions, suggestions, etc. + ## Installing Via npm: @@ -130,15 +132,21 @@ target.docs = -> text.to 'docs/my_docs.md' ``` -To run the target `all`, call the above script without arguments: `$ node make`. To run the target `docs`: `$ node make docs`, and so on. +To run the target `all`, call the above script without arguments: `$ node make`. To run the target `docs`: `$ node make docs`. +You can also pass arguments to your targets by using the `--` separator. For example, to pass `arg1` and `arg2` to a target `bundle`, do `$ node make bundle -- arg1 arg2`: +```javascript +require('shelljs/make'); - + ## Command reference @@ -266,7 +274,7 @@ Available expression primaries: + `'-d', 'path'`: true if path is a directory + `'-e', 'path'`: true if path exists + `'-f', 'path'`: true if path is a regular file -+ `'-L', 'path'`: true if path is a symboilc link ++ `'-L', 'path'`: true if path is a symbolic link + `'-p', 'path'`: true if path is a pipe (FIFO) + `'-S', 'path'`: true if path is a socket @@ -320,7 +328,7 @@ Analogous to the redirect-and-append operator `>>` in Unix, but works with JavaS those returned by `cat`, `grep`, etc). -### sed([options ,] search_regex, replace_str, file) +### sed([options ,] search_regex, replacement, file) Available options: + `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_ @@ -333,7 +341,7 @@ sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js'); ``` Reads an input string from `file` and performs a JavaScript `replace()` on the input -using the given search regex and replacement string. Returns the new string after replacement. +using the given search regex and replacement string or function. Returns the new string after replacement. ### grep([options ,] regex_filter, file [, file ...]) @@ -439,6 +447,23 @@ Display the list of currently remembered directories. Returns an array of paths See also: pushd, popd +### ln(options, source, dest) +### ln(source, dest) +Available options: + ++ `s`: symlink ++ `f`: force + +Examples: + +```javascript +ln('file', 'newlink'); +ln('-sf', 'file', 'existing'); +``` + +Links source to dest. Use -f to force the link, should dest already exist. + + ### exit(code) Exits the current process with the given exit code. @@ -531,10 +556,11 @@ otherwise returns string explaining the error Example: ```javascript -var silentState = config.silent; // save old silent state -config.silent = true; +var sh = require('shelljs'); +var silentState = sh.config.silent; // save old silent state +sh.config.silent = true; /* ... */ -config.silent = silentState; // restore old silent state +sh.config.silent = silentState; // restore old silent state ``` Suppresses all command output if `true`, except for `echo()` calls. @@ -544,6 +570,7 @@ Default is `false`. Example: ```javascript +require('shelljs/global'); config.fatal = true; cp('this_file_does_not_exist', '/dev/null'); // dies here /* more commands... */ diff --git a/platforms/android/cordova/node_modules/shelljs/RELEASE.md b/platforms/android/cordova/node_modules/shelljs/RELEASE.md new file mode 100644 index 0000000..69ef3fb --- /dev/null +++ b/platforms/android/cordova/node_modules/shelljs/RELEASE.md @@ -0,0 +1,9 @@ +# Release steps + +* Ensure master passes CI tests +* Bump version in package.json. Any breaking change or new feature should bump minor (or even major). Non-breaking changes or fixes can just bump patch. +* Update README manually if the changes are not documented in-code. If so, run `scripts/generate-docs.js` +* Commit +* `$ git tag ` (see `git tag -l` for latest) +* `$ git push origin master --tags` +* `$ npm publish .` diff --git a/platforms/android/cordova/node_modules/shelljs/make.js b/platforms/android/cordova/node_modules/shelljs/make.js index 53e5e81..f78b4cf 100644 --- a/platforms/android/cordova/node_modules/shelljs/make.js +++ b/platforms/android/cordova/node_modules/shelljs/make.js @@ -3,9 +3,18 @@ require('./global'); global.config.fatal = true; global.target = {}; +var args = process.argv.slice(2), + targetArgs, + dashesLoc = args.indexOf('--'); + +// split args, everything after -- if only for targets +if (dashesLoc > -1) { + targetArgs = args.slice(dashesLoc + 1, args.length); + args = args.slice(0, dashesLoc); +} + // This ensures we only execute the script targets after the entire script has // been evaluated -var args = process.argv.slice(2); setTimeout(function() { var t; @@ -21,8 +30,8 @@ setTimeout(function() { (function(t, oldTarget){ // Wrap it - global.target[t] = function(force) { - if (oldTarget.done && !force) + global.target[t] = function() { + if (oldTarget.done) return; oldTarget.done = true; return oldTarget.apply(oldTarget, arguments); @@ -35,13 +44,13 @@ setTimeout(function() { if (args.length > 0) { args.forEach(function(arg) { if (arg in global.target) - global.target[arg](); + global.target[arg](targetArgs); else { console.log('no such target: ' + arg); } }); } else if ('all' in global.target) { - global.target.all(); + global.target.all(targetArgs); } }, 0); diff --git a/platforms/android/cordova/node_modules/shelljs/package.json b/platforms/android/cordova/node_modules/shelljs/package.json index fd09b45..572bd7c 100644 --- a/platforms/android/cordova/node_modules/shelljs/package.json +++ b/platforms/android/cordova/node_modules/shelljs/package.json @@ -1,48 +1,89 @@ { - "name": "shelljs", - "version": "0.2.6", - "author": { - "name": "Artur Adib", - "email": "aadib@mozilla.com" - }, - "description": "Portable Unix shell commands for Node.js", - "keywords": [ - "unix", - "shell", - "makefile", - "make", - "jake", - "synchronous" + "_args": [ + [ + "shelljs@^0.5.3", + "/Users/steveng/repo/cordova/cordova-android" + ] ], - "repository": { - "type": "git", - "url": "git://github.com/arturadib/shelljs.git" + "_from": "shelljs@>=0.5.3 <0.6.0", + "_id": "shelljs@0.5.3", + "_inCache": true, + "_installable": true, + "_location": "/shelljs", + "_nodeVersion": "1.2.0", + "_npmUser": { + "email": "arturadib@gmail.com", + "name": "artur" }, - "homepage": "http://github.com/arturadib/shelljs", - "main": "./shell.js", - "scripts": { - "test": "node scripts/run-tests" + "_npmVersion": "2.5.1", + "_phantomChildren": {}, + "_requested": { + "name": "shelljs", + "raw": "shelljs@^0.5.3", + "rawSpec": "^0.5.3", + "scope": null, + "spec": ">=0.5.3 <0.6.0", + "type": "range" + }, + "_requiredBy": [ + "/", + "/cordova-common" + ], + "_resolved": "http://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz", + "_shasum": "c54982b996c76ef0c1e6b59fbdc5825f5b713113", + "_shrinkwrap": null, + "_spec": "shelljs@^0.5.3", + "_where": "/Users/steveng/repo/cordova/cordova-android", + "author": { + "email": "arturadib@gmail.com", + "name": "Artur Adib" }, "bin": { "shjs": "./bin/shjs" }, + "bugs": { + "url": "https://github.com/arturadib/shelljs/issues" + }, "dependencies": {}, + "description": "Portable Unix shell commands for Node.js", "devDependencies": { "jshint": "~2.1.11" }, - "optionalDependencies": {}, + "directories": {}, + "dist": { + "shasum": "c54982b996c76ef0c1e6b59fbdc5825f5b713113", + "tarball": "http://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz" + }, "engines": { "node": ">=0.8.0" }, - "readme": "# ShellJS - Unix shell commands for Node.js [![Build Status](https://secure.travis-ci.org/arturadib/shelljs.png)](http://travis-ci.org/arturadib/shelljs)\n\nShellJS is a portable **(Windows/Linux/OS X)** implementation of Unix shell commands on top of the Node.js API. You can use it to eliminate your shell script's dependency on Unix while still keeping its familiar and powerful commands. You can also install it globally so you can run it from outside Node projects - say goodbye to those gnarly Bash scripts!\n\nThe project is [unit-tested](http://travis-ci.org/arturadib/shelljs) and battled-tested in projects like:\n\n+ [PDF.js](http://github.com/mozilla/pdf.js) - Firefox's next-gen PDF reader\n+ [Firebug](http://getfirebug.com/) - Firefox's infamous debugger\n+ [JSHint](http://jshint.com) - Most popular JavaScript linter\n+ [Zepto](http://zeptojs.com) - jQuery-compatible JavaScript library for modern browsers\n+ [Yeoman](http://yeoman.io/) - Web application stack and development tool\n+ [Deployd.com](http://deployd.com) - Open source PaaS for quick API backend generation\n\nand [many more](https://npmjs.org/browse/depended/shelljs).\n\n## Installing\n\nVia npm:\n\n```bash\n$ npm install [-g] shelljs\n```\n\nIf the global option `-g` is specified, the binary `shjs` will be installed. This makes it possible to\nrun ShellJS scripts much like any shell script from the command line, i.e. without requiring a `node_modules` folder:\n\n```bash\n$ shjs my_script\n```\n\nYou can also just copy `shell.js` into your project's directory, and `require()` accordingly.\n\n\n## Examples\n\n### JavaScript\n\n```javascript\nrequire('shelljs/global');\n\nif (!which('git')) {\n echo('Sorry, this script requires git');\n exit(1);\n}\n\n// Copy files to release dir\nmkdir('-p', 'out/Release');\ncp('-R', 'stuff/*', 'out/Release');\n\n// Replace macros in each .js file\ncd('lib');\nls('*.js').forEach(function(file) {\n sed('-i', 'BUILD_VERSION', 'v0.1.2', file);\n sed('-i', /.*REMOVE_THIS_LINE.*\\n/, '', file);\n sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\\n/, cat('macro.js'), file);\n});\ncd('..');\n\n// Run external tool synchronously\nif (exec('git commit -am \"Auto-commit\"').code !== 0) {\n echo('Error: Git commit failed');\n exit(1);\n}\n```\n\n### CoffeeScript\n\n```coffeescript\nrequire 'shelljs/global'\n\nif not which 'git'\n echo 'Sorry, this script requires git'\n exit 1\n\n# Copy files to release dir\nmkdir '-p', 'out/Release'\ncp '-R', 'stuff/*', 'out/Release'\n\n# Replace macros in each .js file\ncd 'lib'\nfor file in ls '*.js'\n sed '-i', 'BUILD_VERSION', 'v0.1.2', file\n sed '-i', /.*REMOVE_THIS_LINE.*\\n/, '', file\n sed '-i', /.*REPLACE_LINE_WITH_MACRO.*\\n/, cat 'macro.js', file\ncd '..'\n\n# Run external tool synchronously\nif (exec 'git commit -am \"Auto-commit\"').code != 0\n echo 'Error: Git commit failed'\n exit 1\n```\n\n## Global vs. Local\n\nThe example above uses the convenience script `shelljs/global` to reduce verbosity. If polluting your global namespace is not desirable, simply require `shelljs`.\n\nExample:\n\n```javascript\nvar shell = require('shelljs');\nshell.echo('hello world');\n```\n\n## Make tool\n\nA convenience script `shelljs/make` is also provided to mimic the behavior of a Unix Makefile. In this case all shell objects are global, and command line arguments will cause the script to execute only the corresponding function in the global `target` object. To avoid redundant calls, target functions are executed only once per script.\n\nExample (CoffeeScript):\n\n```coffeescript\nrequire 'shelljs/make'\n\ntarget.all = ->\n target.bundle()\n target.docs()\n\ntarget.bundle = ->\n cd __dirname\n mkdir 'build'\n cd 'lib'\n (cat '*.js').to '../build/output.js'\n\ntarget.docs = ->\n cd __dirname\n mkdir 'docs'\n cd 'lib'\n for file in ls '*.js'\n text = grep '//@', file # extract special comments\n text.replace '//@', '' # remove comment tags\n text.to 'docs/my_docs.md'\n```\n\nTo run the target `all`, call the above script without arguments: `$ node make`. To run the target `docs`: `$ node make docs`, and so on.\n\n\n\n\n\n\n## Command reference\n\n\nAll commands run synchronously, unless otherwise stated.\n\n\n### cd('dir')\nChanges to directory `dir` for the duration of the script\n\n\n### pwd()\nReturns the current directory.\n\n\n### ls([options ,] path [,path ...])\n### ls([options ,] path_array)\nAvailable options:\n\n+ `-R`: recursive\n+ `-A`: all files (include files beginning with `.`, except for `.` and `..`)\n\nExamples:\n\n```javascript\nls('projs/*.js');\nls('-R', '/users/me', '/tmp');\nls('-R', ['/users/me', '/tmp']); // same as above\n```\n\nReturns array of files in the given path, or in current directory if no path provided.\n\n\n### find(path [,path ...])\n### find(path_array)\nExamples:\n\n```javascript\nfind('src', 'lib');\nfind(['src', 'lib']); // same as above\nfind('.').filter(function(file) { return file.match(/\\.js$/); });\n```\n\nReturns array of all files (however deep) in the given paths.\n\nThe main difference from `ls('-R', path)` is that the resulting file names\ninclude the base directories, e.g. `lib/resources/file1` instead of just `file1`.\n\n\n### cp([options ,] source [,source ...], dest)\n### cp([options ,] source_array, dest)\nAvailable options:\n\n+ `-f`: force\n+ `-r, -R`: recursive\n\nExamples:\n\n```javascript\ncp('file1', 'dir1');\ncp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');\ncp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above\n```\n\nCopies files. The wildcard `*` is accepted.\n\n\n### rm([options ,] file [, file ...])\n### rm([options ,] file_array)\nAvailable options:\n\n+ `-f`: force\n+ `-r, -R`: recursive\n\nExamples:\n\n```javascript\nrm('-rf', '/tmp/*');\nrm('some_file.txt', 'another_file.txt');\nrm(['some_file.txt', 'another_file.txt']); // same as above\n```\n\nRemoves files. The wildcard `*` is accepted.\n\n\n### mv(source [, source ...], dest')\n### mv(source_array, dest')\nAvailable options:\n\n+ `f`: force\n\nExamples:\n\n```javascript\nmv('-f', 'file', 'dir/');\nmv('file1', 'file2', 'dir/');\nmv(['file1', 'file2'], 'dir/'); // same as above\n```\n\nMoves files. The wildcard `*` is accepted.\n\n\n### mkdir([options ,] dir [, dir ...])\n### mkdir([options ,] dir_array)\nAvailable options:\n\n+ `p`: full path (will create intermediate dirs if necessary)\n\nExamples:\n\n```javascript\nmkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g');\nmkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above\n```\n\nCreates directories.\n\n\n### test(expression)\nAvailable expression primaries:\n\n+ `'-b', 'path'`: true if path is a block device\n+ `'-c', 'path'`: true if path is a character device\n+ `'-d', 'path'`: true if path is a directory\n+ `'-e', 'path'`: true if path exists\n+ `'-f', 'path'`: true if path is a regular file\n+ `'-L', 'path'`: true if path is a symboilc link\n+ `'-p', 'path'`: true if path is a pipe (FIFO)\n+ `'-S', 'path'`: true if path is a socket\n\nExamples:\n\n```javascript\nif (test('-d', path)) { /* do something with dir */ };\nif (!test('-f', path)) continue; // skip if it's a regular file\n```\n\nEvaluates expression using the available primaries and returns corresponding value.\n\n\n### cat(file [, file ...])\n### cat(file_array)\n\nExamples:\n\n```javascript\nvar str = cat('file*.txt');\nvar str = cat('file1', 'file2');\nvar str = cat(['file1', 'file2']); // same as above\n```\n\nReturns a string containing the given file, or a concatenated string\ncontaining the files if more than one file is given (a new line character is\nintroduced between each file). Wildcard `*` accepted.\n\n\n### 'string'.to(file)\n\nExamples:\n\n```javascript\ncat('input.txt').to('output.txt');\n```\n\nAnalogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as\nthose returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_\n\n\n### 'string'.toEnd(file)\n\nExamples:\n\n```javascript\ncat('input.txt').toEnd('output.txt');\n```\n\nAnalogous to the redirect-and-append operator `>>` in Unix, but works with JavaScript strings (such as\nthose returned by `cat`, `grep`, etc).\n\n\n### sed([options ,] search_regex, replace_str, file)\nAvailable options:\n\n+ `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_\n\nExamples:\n\n```javascript\nsed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');\nsed(/.*DELETE_THIS_LINE.*\\n/, '', 'source.js');\n```\n\nReads an input string from `file` and performs a JavaScript `replace()` on the input\nusing the given search regex and replacement string. Returns the new string after replacement.\n\n\n### grep([options ,] regex_filter, file [, file ...])\n### grep([options ,] regex_filter, file_array)\nAvailable options:\n\n+ `-v`: Inverse the sense of the regex and print the lines not matching the criteria.\n\nExamples:\n\n```javascript\ngrep('-v', 'GLOBAL_VARIABLE', '*.js');\ngrep('GLOBAL_VARIABLE', '*.js');\n```\n\nReads input string from given files and returns a string containing all lines of the\nfile that match the given `regex_filter`. Wildcard `*` accepted.\n\n\n### which(command)\n\nExamples:\n\n```javascript\nvar nodeExec = which('node');\n```\n\nSearches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions.\nReturns string containing the absolute path to the command.\n\n\n### echo(string [,string ...])\n\nExamples:\n\n```javascript\necho('hello world');\nvar str = echo('hello world');\n```\n\nPrints string to stdout, and returns string with additional utility methods\nlike `.to()`.\n\n\n### pushd([options,] [dir | '-N' | '+N'])\n\nAvailable options:\n\n+ `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated.\n\nArguments:\n\n+ `dir`: Makes the current working directory be the top of the stack, and then executes the equivalent of `cd dir`.\n+ `+N`: Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.\n+ `-N`: Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack.\n\nExamples:\n\n```javascript\n// process.cwd() === '/usr'\npushd('/etc'); // Returns /etc /usr\npushd('+1'); // Returns /usr /etc\n```\n\nSave the current directory on the top of the directory stack and then cd to `dir`. With no arguments, pushd exchanges the top two directories. Returns an array of paths in the stack.\n\n### popd([options,] ['-N' | '+N'])\n\nAvailable options:\n\n+ `-n`: Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated.\n\nArguments:\n\n+ `+N`: Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero.\n+ `-N`: Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero.\n\nExamples:\n\n```javascript\necho(process.cwd()); // '/usr'\npushd('/etc'); // '/etc /usr'\necho(process.cwd()); // '/etc'\npopd(); // '/usr'\necho(process.cwd()); // '/usr'\n```\n\nWhen no arguments are given, popd removes the top directory from the stack and performs a cd to the new top directory. The elements are numbered from 0 starting at the first directory listed with dirs; i.e., popd is equivalent to popd +0. Returns an array of paths in the stack.\n\n### dirs([options | '+N' | '-N'])\n\nAvailable options:\n\n+ `-c`: Clears the directory stack by deleting all of the elements.\n\nArguments:\n\n+ `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero.\n+ `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero.\n\nDisplay the list of currently remembered directories. Returns an array of paths in the stack, or a single path if +N or -N was specified.\n\nSee also: pushd, popd\n\n\n### exit(code)\nExits the current process with the given exit code.\n\n### env['VAR_NAME']\nObject containing environment variables (both getter and setter). Shortcut to process.env.\n\n### exec(command [, options] [, callback])\nAvailable options (all `false` by default):\n\n+ `async`: Asynchronous execution. Defaults to true if a callback is provided.\n+ `silent`: Do not echo program output to console.\n\nExamples:\n\n```javascript\nvar version = exec('node --version', {silent:true}).output;\n\nvar child = exec('some_long_running_process', {async:true});\nchild.stdout.on('data', function(data) {\n /* ... do something with data ... */\n});\n\nexec('some_long_running_process', function(code, output) {\n console.log('Exit code:', code);\n console.log('Program output:', output);\n});\n```\n\nExecutes the given `command` _synchronously_, unless otherwise specified.\nWhen in synchronous mode returns the object `{ code:..., output:... }`, containing the program's\n`output` (stdout + stderr) and its exit `code`. Otherwise returns the child process object, and\nthe `callback` gets the arguments `(code, output)`.\n\n**Note:** For long-lived processes, it's best to run `exec()` asynchronously as\nthe current synchronous implementation uses a lot of CPU. This should be getting\nfixed soon.\n\n\n### chmod(octal_mode || octal_string, file)\n### chmod(symbolic_mode, file)\n\nAvailable options:\n\n+ `-v`: output a diagnostic for every file processed\n+ `-c`: like verbose but report only when a change is made\n+ `-R`: change files and directories recursively\n\nExamples:\n\n```javascript\nchmod(755, '/Users/brandon');\nchmod('755', '/Users/brandon'); // same as above\nchmod('u+x', '/Users/brandon');\n```\n\nAlters the permissions of a file or directory by either specifying the\nabsolute permissions in octal form or expressing the changes in symbols.\nThis command tries to mimic the POSIX behavior as much as possible.\nNotable exceptions:\n\n+ In symbolic modes, 'a-r' and '-r' are identical. No consideration is\n given to the umask.\n+ There is no \"quiet\" option since default behavior is to run silent.\n\n\n## Non-Unix commands\n\n\n### tempdir()\n\nExamples:\n\n```javascript\nvar tmp = tempdir(); // \"/tmp\" for most *nix platforms\n```\n\nSearches and returns string containing a writeable, platform-dependent temporary directory.\nFollows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).\n\n\n### error()\nTests if error occurred in the last command. Returns `null` if no error occurred,\notherwise returns string explaining the error\n\n\n## Configuration\n\n\n### config.silent\nExample:\n\n```javascript\nvar silentState = config.silent; // save old silent state\nconfig.silent = true;\n/* ... */\nconfig.silent = silentState; // restore old silent state\n```\n\nSuppresses all command output if `true`, except for `echo()` calls.\nDefault is `false`.\n\n### config.fatal\nExample:\n\n```javascript\nconfig.fatal = true;\ncp('this_file_does_not_exist', '/dev/null'); // dies here\n/* more commands... */\n```\n\nIf `true` the script will die on errors. Default is `false`.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/arturadib/shelljs/issues" + "gitHead": "22d0975040b9b8234755dc6e692d6869436e8485", + "homepage": "http://github.com/arturadib/shelljs", + "keywords": [ + "jake", + "make", + "makefile", + "shell", + "synchronous", + "unix" + ], + "license": "BSD*", + "main": "./shell.js", + "maintainers": [ + { + "name": "artur", + "email": "arturadib@gmail.com" + } + ], + "name": "shelljs", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/arturadib/shelljs.git" }, - "_id": "shelljs@0.2.6", - "dist": { - "shasum": "3c1e3cebca47c6819cb354ae1e1f8f8452ed71dd" + "scripts": { + "test": "node scripts/run-tests" }, - "_from": "shelljs@0.2.6", - "_resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.2.6.tgz" + "version": "0.5.3" } diff --git a/platforms/android/cordova/node_modules/shelljs/shell.js b/platforms/android/cordova/node_modules/shelljs/shell.js index e56c5de..bdeb559 100644 --- a/platforms/android/cordova/node_modules/shelljs/shell.js +++ b/platforms/android/cordova/node_modules/shelljs/shell.js @@ -85,6 +85,10 @@ exports.pushd = common.wrap('pushd', _pushd); var _popd = require('./src/dirs').popd; exports.popd = common.wrap("popd", _popd); +//@include ./src/ln +var _ln = require('./src/ln'); +exports.ln = common.wrap('ln', _ln); + //@ //@ ### exit(code) //@ Exits the current process with the given exit code. @@ -131,10 +135,11 @@ exports.config = common.config; //@ Example: //@ //@ ```javascript -//@ var silentState = config.silent; // save old silent state -//@ config.silent = true; +//@ var sh = require('shelljs'); +//@ var silentState = sh.config.silent; // save old silent state +//@ sh.config.silent = true; //@ /* ... */ -//@ config.silent = silentState; // restore old silent state +//@ sh.config.silent = silentState; // restore old silent state //@ ``` //@ //@ Suppresses all command output if `true`, except for `echo()` calls. @@ -145,6 +150,7 @@ exports.config = common.config; //@ Example: //@ //@ ```javascript +//@ require('shelljs/global'); //@ config.fatal = true; //@ cp('this_file_does_not_exist', '/dev/null'); // dies here //@ /* more commands... */ diff --git a/platforms/android/cordova/node_modules/shelljs/src/common.js b/platforms/android/cordova/node_modules/shelljs/src/common.js index fe20871..d8c2312 100644 --- a/platforms/android/cordova/node_modules/shelljs/src/common.js +++ b/platforms/android/cordova/node_modules/shelljs/src/common.js @@ -92,8 +92,22 @@ exports.parseOptions = parseOptions; function expand(list) { var expanded = []; list.forEach(function(listEl) { - // Wildcard present? - if (listEl.search(/\*/) > -1) { + // Wildcard present on directory names ? + if(listEl.search(/\*[^\/]*\//) > -1 || listEl.search(/\*\*[^\/]*\//) > -1) { + var match = listEl.match(/^([^*]+\/|)(.*)/); + var root = match[1]; + var rest = match[2]; + var restRegex = rest.replace(/\*\*/g, ".*").replace(/\*/g, "[^\\/]*"); + restRegex = new RegExp(restRegex); + + _ls('-R', root).filter(function (e) { + return restRegex.test(e); + }).forEach(function(file) { + expanded.push(file); + }); + } + // Wildcard present on file names ? + else if (listEl.search(/\*/) > -1) { _ls('', listEl).forEach(function(file) { expanded.push(file); }); diff --git a/platforms/android/cordova/node_modules/shelljs/src/cp.js b/platforms/android/cordova/node_modules/shelljs/src/cp.js index a1bc529..ef19f96 100644 --- a/platforms/android/cordova/node_modules/shelljs/src/cp.js +++ b/platforms/android/cordova/node_modules/shelljs/src/cp.js @@ -1,6 +1,7 @@ var fs = require('fs'); var path = require('path'); var common = require('./common'); +var os = require('os'); // Buffered file copy, synchronous // (Using readFileSync() + writeFileSync() could easily cause a memory overflow @@ -72,7 +73,7 @@ function cpdirSyncRecursive(sourceDir, destDir, opts) { cpdirSyncRecursive(srcFile, destFile, opts); } else if (srcFileStat.isSymbolicLink()) { var symlinkFull = fs.readlinkSync(srcFile); - fs.symlinkSync(symlinkFull, destFile); + fs.symlinkSync(symlinkFull, destFile, os.platform() === "win32" ? "junction" : null); } else { /* At this point, we've hit a file actually worth copying... so copy it on over. */ if (fs.existsSync(destFile) && !opts.force) { @@ -173,7 +174,10 @@ function _cp(options, sources, dest) { fs.mkdirSync(newDest, checkDir.mode); } catch (e) { //if the directory already exists, that's okay - if (e.code !== 'EEXIST') throw e; + if (e.code !== 'EEXIST') { + common.error('dest file no such file or directory: ' + newDest, true); + throw e; + } } cpdirSyncRecursive(src, newDest, {force: options.force}); diff --git a/platforms/android/cordova/node_modules/shelljs/src/exec.js b/platforms/android/cordova/node_modules/shelljs/src/exec.js index 7ccdbc0..d259a9f 100644 --- a/platforms/android/cordova/node_modules/shelljs/src/exec.js +++ b/platforms/android/cordova/node_modules/shelljs/src/exec.js @@ -40,32 +40,67 @@ function execSync(cmd, opts) { return (str+'').replace(/([\\"'])/g, "\\$1").replace(/\0/g, "\\0"); } - cmd += ' > '+stdoutFile+' 2>&1'; // works on both win/unix - - var script = - "var child = require('child_process')," + - " fs = require('fs');" + - "child.exec('"+escape(cmd)+"', {env: process.env, maxBuffer: 20*1024*1024}, function(err) {" + - " fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0');" + - "});"; - if (fs.existsSync(scriptFile)) common.unlinkSync(scriptFile); if (fs.existsSync(stdoutFile)) common.unlinkSync(stdoutFile); if (fs.existsSync(codeFile)) common.unlinkSync(codeFile); - fs.writeFileSync(scriptFile, script); - child.exec('"'+process.execPath+'" '+scriptFile, { + var execCommand = '"'+process.execPath+'" '+scriptFile; + var execOptions = { env: process.env, cwd: _pwd(), maxBuffer: 20*1024*1024 - }); + }; - // The wait loop - // sleepFile is used as a dummy I/O op to mitigate unnecessary CPU usage - // (tried many I/O sync ops, writeFileSync() seems to be only one that is effective in reducing - // CPU usage, though apparently not so much on Windows) - while (!fs.existsSync(codeFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); } - while (!fs.existsSync(stdoutFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); } + if (typeof child.execSync === 'function') { + var script = [ + "var child = require('child_process')", + " , fs = require('fs');", + "var childProcess = child.exec('"+escape(cmd)+"', {env: process.env, maxBuffer: 20*1024*1024}, function(err) {", + " fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0');", + "});", + "var stdoutStream = fs.createWriteStream('"+escape(stdoutFile)+"');", + "childProcess.stdout.pipe(stdoutStream, {end: false});", + "childProcess.stderr.pipe(stdoutStream, {end: false});", + "childProcess.stdout.pipe(process.stdout);", + "childProcess.stderr.pipe(process.stderr);", + "var stdoutEnded = false, stderrEnded = false;", + "function tryClosing(){ if(stdoutEnded && stderrEnded){ stdoutStream.end(); } }", + "childProcess.stdout.on('end', function(){ stdoutEnded = true; tryClosing(); });", + "childProcess.stderr.on('end', function(){ stderrEnded = true; tryClosing(); });" + ].join('\n'); + + fs.writeFileSync(scriptFile, script); + + if (options.silent) { + execOptions.stdio = 'ignore'; + } else { + execOptions.stdio = [0, 1, 2]; + } + + // Welcome to the future + child.execSync(execCommand, execOptions); + } else { + cmd += ' > '+stdoutFile+' 2>&1'; // works on both win/unix + + var script = [ + "var child = require('child_process')", + " , fs = require('fs');", + "var childProcess = child.exec('"+escape(cmd)+"', {env: process.env, maxBuffer: 20*1024*1024}, function(err) {", + " fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0');", + "});" + ].join('\n'); + + fs.writeFileSync(scriptFile, script); + + child.exec(execCommand, execOptions); + + // The wait loop + // sleepFile is used as a dummy I/O op to mitigate unnecessary CPU usage + // (tried many I/O sync ops, writeFileSync() seems to be only one that is effective in reducing + // CPU usage, though apparently not so much on Windows) + while (!fs.existsSync(codeFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); } + while (!fs.existsSync(stdoutFile)) { updateStdout(); fs.writeFileSync(sleepFile, 'a'); } + } // At this point codeFile exists, but it's not necessarily flushed yet. // Keep reading it until it is. diff --git a/platforms/android/cordova/node_modules/shelljs/src/ln.js b/platforms/android/cordova/node_modules/shelljs/src/ln.js new file mode 100644 index 0000000..a7b9701 --- /dev/null +++ b/platforms/android/cordova/node_modules/shelljs/src/ln.js @@ -0,0 +1,53 @@ +var fs = require('fs'); +var path = require('path'); +var common = require('./common'); +var os = require('os'); + +//@ +//@ ### ln(options, source, dest) +//@ ### ln(source, dest) +//@ Available options: +//@ +//@ + `s`: symlink +//@ + `f`: force +//@ +//@ Examples: +//@ +//@ ```javascript +//@ ln('file', 'newlink'); +//@ ln('-sf', 'file', 'existing'); +//@ ``` +//@ +//@ Links source to dest. Use -f to force the link, should dest already exist. +function _ln(options, source, dest) { + options = common.parseOptions(options, { + 's': 'symlink', + 'f': 'force' + }); + + if (!source || !dest) { + common.error('Missing and/or '); + } + + source = path.resolve(process.cwd(), String(source)); + dest = path.resolve(process.cwd(), String(dest)); + + if (!fs.existsSync(source)) { + common.error('Source file does not exist', true); + } + + if (fs.existsSync(dest)) { + if (!options.force) { + common.error('Destination file exists', true); + } + + fs.unlinkSync(dest); + } + + if (options.symlink) { + fs.symlinkSync(source, dest, os.platform() === "win32" ? "junction" : null); + } else { + fs.linkSync(source, dest, os.platform() === "win32" ? "junction" : null); + } +} +module.exports = _ln; diff --git a/platforms/android/cordova/node_modules/shelljs/src/rm.js b/platforms/android/cordova/node_modules/shelljs/src/rm.js index 3abe6e1..bd608cb 100644 --- a/platforms/android/cordova/node_modules/shelljs/src/rm.js +++ b/platforms/android/cordova/node_modules/shelljs/src/rm.js @@ -48,7 +48,25 @@ function rmdirSyncRecursive(dir, force) { var result; try { - result = fs.rmdirSync(dir); + // Retry on windows, sometimes it takes a little time before all the files in the directory are gone + var start = Date.now(); + while (true) { + try { + result = fs.rmdirSync(dir); + if (fs.existsSync(dir)) throw { code: "EAGAIN" } + break; + } catch(er) { + // In addition to error codes, also check if the directory still exists and loop again if true + if (process.platform === "win32" && (er.code === "ENOTEMPTY" || er.code === "EBUSY" || er.code === "EPERM" || er.code === "EAGAIN")) { + if (Date.now() - start > 1000) throw er; + } else if (er.code === "ENOENT") { + // Directory did not exist, deletion was successful + break; + } else { + throw er; + } + } + } } catch(e) { common.error('could not remove directory (code '+e.code+'): ' + dir, true); } diff --git a/platforms/android/cordova/node_modules/shelljs/src/sed.js b/platforms/android/cordova/node_modules/shelljs/src/sed.js index 9783252..65f7cb4 100644 --- a/platforms/android/cordova/node_modules/shelljs/src/sed.js +++ b/platforms/android/cordova/node_modules/shelljs/src/sed.js @@ -2,7 +2,7 @@ var common = require('./common'); var fs = require('fs'); //@ -//@ ### sed([options ,] search_regex, replace_str, file) +//@ ### sed([options ,] search_regex, replacement, file) //@ Available options: //@ //@ + `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_ @@ -15,13 +15,13 @@ var fs = require('fs'); //@ ``` //@ //@ Reads an input string from `file` and performs a JavaScript `replace()` on the input -//@ using the given search regex and replacement string. Returns the new string after replacement. +//@ using the given search regex and replacement string or function. Returns the new string after replacement. function _sed(options, regex, replacement, file) { options = common.parseOptions(options, { 'i': 'inplace' }); - if (typeof replacement === 'string') + if (typeof replacement === 'string' || typeof replacement === 'function') replacement = replacement; // no-op else if (typeof replacement === 'number') replacement = replacement.toString(); // fallback diff --git a/platforms/android/cordova/node_modules/shelljs/src/which.js b/platforms/android/cordova/node_modules/shelljs/src/which.js index fadb96c..2822ecf 100644 --- a/platforms/android/cordova/node_modules/shelljs/src/which.js +++ b/platforms/android/cordova/node_modules/shelljs/src/which.js @@ -15,6 +15,10 @@ function splitPath(p) { return p.split(':'); } +function checkPath(path) { + return fs.existsSync(path) && fs.statSync(path).isDirectory() == false; +} + //@ //@ ### which(command) //@ @@ -42,7 +46,7 @@ function _which(options, cmd) { return; // already found it var attempt = path.resolve(dir + '/' + cmd); - if (fs.existsSync(attempt)) { + if (checkPath(attempt)) { where = attempt; return; } @@ -50,17 +54,17 @@ function _which(options, cmd) { if (common.platform === 'win') { var baseAttempt = attempt; attempt = baseAttempt + '.exe'; - if (fs.existsSync(attempt)) { + if (checkPath(attempt)) { where = attempt; return; } attempt = baseAttempt + '.cmd'; - if (fs.existsSync(attempt)) { + if (checkPath(attempt)) { where = attempt; return; } attempt = baseAttempt + '.bat'; - if (fs.existsSync(attempt)) { + if (checkPath(attempt)) { where = attempt; return; } @@ -69,7 +73,7 @@ function _which(options, cmd) { } // Command not found anywhere? - if (!fs.existsSync(cmd) && !where) + if (!checkPath(cmd) && !where) return null; where = where || path.resolve(cmd); diff --git a/platforms/android/cordova/node_modules/underscore/LICENSE b/platforms/android/cordova/node_modules/underscore/LICENSE new file mode 100644 index 0000000..ad0e71b --- /dev/null +++ b/platforms/android/cordova/node_modules/underscore/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative +Reporters & Editors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/cordova/node_modules/underscore/README.md b/platforms/android/cordova/node_modules/underscore/README.md new file mode 100644 index 0000000..c2ba259 --- /dev/null +++ b/platforms/android/cordova/node_modules/underscore/README.md @@ -0,0 +1,22 @@ + __ + /\ \ __ + __ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____ + /\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\ + \ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\ + \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/ + \/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/ + \ \____/ + \/___/ + +Underscore.js is a utility-belt library for JavaScript that provides +support for the usual functional suspects (each, map, reduce, filter...) +without extending any core JavaScript objects. + +For Docs, License, Tests, and pre-packed downloads, see: +http://underscorejs.org + +Underscore is an open-sourced component of DocumentCloud: +https://github.com/documentcloud + +Many thanks to our contributors: +https://github.com/jashkenas/underscore/contributors diff --git a/platforms/android/cordova/node_modules/underscore/package.json b/platforms/android/cordova/node_modules/underscore/package.json new file mode 100644 index 0000000..3304948 --- /dev/null +++ b/platforms/android/cordova/node_modules/underscore/package.json @@ -0,0 +1,96 @@ +{ + "_args": [ + [ + "underscore@^1.8.3", + "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common" + ] + ], + "_from": "underscore@>=1.8.3 <2.0.0", + "_id": "underscore@1.8.3", + "_inCache": true, + "_installable": true, + "_location": "/underscore", + "_npmUser": { + "email": "jashkenas@gmail.com", + "name": "jashkenas" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "name": "underscore", + "raw": "underscore@^1.8.3", + "rawSpec": "^1.8.3", + "scope": null, + "spec": ">=1.8.3 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/cordova-common" + ], + "_resolved": "http://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "_shasum": "4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022", + "_shrinkwrap": null, + "_spec": "underscore@^1.8.3", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common", + "author": { + "email": "jeremy@documentcloud.org", + "name": "Jeremy Ashkenas" + }, + "bugs": { + "url": "https://github.com/jashkenas/underscore/issues" + }, + "dependencies": {}, + "description": "JavaScript's functional programming helper library.", + "devDependencies": { + "docco": "*", + "eslint": "0.6.x", + "karma": "~0.12.31", + "karma-qunit": "~0.1.4", + "qunit-cli": "~0.2.0", + "uglify-js": "2.4.x" + }, + "directories": {}, + "dist": { + "shasum": "4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022", + "tarball": "http://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz" + }, + "files": [ + "LICENSE", + "underscore-min.js", + "underscore-min.map", + "underscore.js" + ], + "gitHead": "e4743ab712b8ab42ad4ccb48b155034d02394e4d", + "homepage": "http://underscorejs.org", + "keywords": [ + "browser", + "client", + "functional", + "server", + "util" + ], + "license": "MIT", + "main": "underscore.js", + "maintainers": [ + { + "name": "jashkenas", + "email": "jashkenas@gmail.com" + } + ], + "name": "underscore", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/jashkenas/underscore.git" + }, + "scripts": { + "build": "uglifyjs underscore.js -c \"evaluate=false\" --comments \"/ .*/\" -m --source-map underscore-min.map -o underscore-min.js", + "doc": "docco underscore.js", + "lint": "eslint underscore.js test/*.js", + "test": "npm run test-node && npm run lint", + "test-browser": "npm i karma-phantomjs-launcher && ./node_modules/karma/bin/karma start", + "test-node": "qunit-cli test/*.js" + }, + "version": "1.8.3" +} diff --git a/platforms/android/cordova/node_modules/underscore/underscore-min.js b/platforms/android/cordova/node_modules/underscore/underscore-min.js new file mode 100644 index 0000000..f01025b --- /dev/null +++ b/platforms/android/cordova/node_modules/underscore/underscore-min.js @@ -0,0 +1,6 @@ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. +(function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this); +//# sourceMappingURL=underscore-min.map \ No newline at end of file diff --git a/platforms/android/cordova/node_modules/underscore/underscore-min.map b/platforms/android/cordova/node_modules/underscore/underscore-min.map new file mode 100644 index 0000000..cf356bf --- /dev/null +++ b/platforms/android/cordova/node_modules/underscore/underscore-min.map @@ -0,0 +1 @@ +{"version":3,"file":"underscore-min.js","sources":["underscore.js"],"names":["createReduce","dir","iterator","obj","iteratee","memo","keys","index","length","currentKey","context","optimizeCb","isArrayLike","_","arguments","createPredicateIndexFinder","array","predicate","cb","getLength","createIndexFinder","predicateFind","sortedIndex","item","idx","i","Math","max","min","slice","call","isNaN","collectNonEnumProps","nonEnumIdx","nonEnumerableProps","constructor","proto","isFunction","prototype","ObjProto","prop","has","contains","push","root","this","previousUnderscore","ArrayProto","Array","Object","FuncProto","Function","toString","hasOwnProperty","nativeIsArray","isArray","nativeKeys","nativeBind","bind","nativeCreate","create","Ctor","_wrapped","exports","module","VERSION","func","argCount","value","other","collection","accumulator","apply","identity","isObject","matcher","property","Infinity","createAssigner","keysFunc","undefinedOnly","source","l","key","baseCreate","result","MAX_ARRAY_INDEX","pow","each","forEach","map","collect","results","reduce","foldl","inject","reduceRight","foldr","find","detect","findIndex","findKey","filter","select","list","reject","negate","every","all","some","any","includes","include","fromIndex","guard","values","indexOf","invoke","method","args","isFunc","pluck","where","attrs","findWhere","computed","lastComputed","shuffle","rand","set","shuffled","random","sample","n","sortBy","criteria","sort","left","right","a","b","group","behavior","groupBy","indexBy","countBy","toArray","size","partition","pass","fail","first","head","take","initial","last","rest","tail","drop","compact","flatten","input","shallow","strict","startIndex","output","isArguments","j","len","without","difference","uniq","unique","isSorted","isBoolean","seen","union","intersection","argsLength","zip","unzip","object","findLastIndex","low","high","mid","floor","lastIndexOf","range","start","stop","step","ceil","executeBound","sourceFunc","boundFunc","callingContext","self","TypeError","bound","concat","partial","boundArgs","position","bindAll","Error","memoize","hasher","cache","address","delay","wait","setTimeout","defer","throttle","options","timeout","previous","later","leading","now","remaining","clearTimeout","trailing","debounce","immediate","timestamp","callNow","wrap","wrapper","compose","after","times","before","once","hasEnumBug","propertyIsEnumerable","allKeys","mapObject","pairs","invert","functions","methods","names","extend","extendOwn","assign","pick","oiteratee","omit","String","defaults","props","clone","tap","interceptor","isMatch","eq","aStack","bStack","className","areArrays","aCtor","bCtor","pop","isEqual","isEmpty","isString","isElement","nodeType","type","name","Int8Array","isFinite","parseFloat","isNumber","isNull","isUndefined","noConflict","constant","noop","propertyOf","matches","accum","Date","getTime","escapeMap","&","<",">","\"","'","`","unescapeMap","createEscaper","escaper","match","join","testRegexp","RegExp","replaceRegexp","string","test","replace","escape","unescape","fallback","idCounter","uniqueId","prefix","id","templateSettings","evaluate","interpolate","noMatch","escapes","\\","\r","\n","
","
","escapeChar","template","text","settings","oldSettings","offset","variable","render","e","data","argument","chain","instance","_chain","mixin","valueOf","toJSON","define","amd"],"mappings":"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"} \ No newline at end of file diff --git a/platforms/android/cordova/node_modules/underscore/underscore.js b/platforms/android/cordova/node_modules/underscore/underscore.js new file mode 100644 index 0000000..b29332f --- /dev/null +++ b/platforms/android/cordova/node_modules/underscore/underscore.js @@ -0,0 +1,1548 @@ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.8.3'; + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + var optimizeCb = function(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + case 2: return function(value, other) { + return func.call(context, value, other); + }; + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + }; + + // A mostly-internal function to generate callbacks that can be applied + // to each element in a collection, returning the desired result — either + // identity, an arbitrary callback, a property matcher, or a property accessor. + var cb = function(value, context, argCount) { + if (value == null) return _.identity; + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); + return _.property(value); + }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + _.each = _.forEach = function(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var keys = _.keys(obj); + for (i = 0, length = keys.length; i < length; i++) { + iteratee(obj[keys[i]], keys[i], obj); + } + } + return obj; + }; + + // Return the results of applying the iteratee to each element. + _.map = _.collect = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + _.reduce = _.foldl = _.inject = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + _.reduceRight = _.foldr = createReduce(-1); + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; + }; + + // Return all the elements that pass a truth test. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + _.each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, _.negate(cb(predicate)), context); + }; + + // Determine whether all of the elements match a truth test. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + }; + + // Determine if at least one element in the object matches a truth test. + // Aliased as `any`. + _.some = _.any = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + }; + + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matcher(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matcher(attrs)); + }; + + // Return the maximum element (or element-based computation). + _.max = function(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Shuffle a collection, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var set = isArrayLike(obj) ? obj : _.values(obj); + var length = set.length; + var shuffled = Array(length); + for (var index = 0, rand; index < length; index++) { + rand = _.random(0, index); + if (rand !== index) shuffled[index] = shuffled[rand]; + shuffled[rand] = set[index]; + } + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // Sort the object's values by a criterion produced by an iteratee. + _.sortBy = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iteratee(value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iteratee, context) { + var result = {}; + iteratee = cb(iteratee, context); + _.each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, value, key) { + if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, value, key) { + if (_.has(result, key)) result[key]++; else result[key] = 1; + }); + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (isArrayLike(obj)) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; + }; + + // Split a collection into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(obj, predicate, context) { + predicate = cb(predicate, context); + var pass = [], fail = []; + _.each(obj, function(value, key, obj) { + (predicate(value, key, obj) ? pass : fail).push(value); + }); + return [pass, fail]; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[0]; + return _.initial(array, array.length - n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + _.initial = function(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[array.length - 1]; + return _.rest(array, Math.max(0, array.length - n)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, false); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iteratee, context) { + if (!_.isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!_.contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!_.contains(result, value)) { + result.push(value); + } + } + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(flatten(arguments, true, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (_.contains(result, item)) continue; + for (var j = 1; j < argsLength; j++) { + if (!_.contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = flatten(arguments, true, true, 1); + return _.filter(array, function(value){ + return !_.contains(rest, value); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); + } + return result; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + step = step || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); + }; + return bound; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var i, length = arguments.length, key; + if (length <= 1) throw new Error('bindAll must be passed function names'); + for (i = 1; i < length; i++) { + key = arguments[i]; + obj[key] = _.bind(obj[key], obj); + } + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ + return func.apply(null, args); + }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = _.partial(_.delay, _, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a negated version of the passed-in predicate. + _.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + }; + + // Returns a function that will only be executed on and after the Nth call. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Returns a function that will only be executed up to (but not including) the Nth call. + _.before = function(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = _.partial(_.before, 2); + + // Object Functions + // ---------------- + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; + if (obj == null) return result; + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); + } else { + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj, iteratee, context) { + if (_.isFunction(iteratee)) { + iteratee = _.negate(iteratee); + } else { + var keys = _.map(flatten(arguments, false, false, 1), String); + iteratee = function(value, key) { + return !_.contains(keys, key); + }; + } + return _.pick(obj, iteratee, context); + }; + + // Fill in a given object with default properties. + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = _.keys(a), key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) === '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return _.has(obj, 'callee'); + }; + } + + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { + _.isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj !== +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iteratees. + _.identity = function(value) { + return value; + }; + + // Predicate-generating functions. Often useful outside of Underscore. + _.constant = function(value) { + return function() { + return value; + }; + }; + + _.noop = function(){}; + + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); + return function(obj) { + return _.isMatch(obj, attrs); + }; + }; + + // Run a function **n** times. + _.times = function(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { + return new Date().getTime(); + }; + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + var unescapeMap = _.invert(escapeMap); + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped + var source = '(?:' + _.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + _.escape = createEscaper(escapeMap); + _.unescape = createEscaper(unescapeMap); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + var escapeChar = function(match) { + return '\\' + escapes[match]; + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + _.template = function(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escaper, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + try { + var render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled source as a convenience for precompilation. + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function. Start chaining a wrapped Underscore object. + _.chain = function(obj) { + var instance = _(obj); + instance._chain = true; + return instance; + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + _.each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result(this, func.apply(_, args)); + }; + }); + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; + return result(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + _.each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result(this, method.apply(this._wrapped, arguments)); + }; + }); + + // Extracts the result from a wrapped and chained object. + _.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}.call(this)); diff --git a/platforms/android/cordova/node_modules/unorm/LICENSE.md b/platforms/android/cordova/node_modules/unorm/LICENSE.md new file mode 100644 index 0000000..ed1d4f3 --- /dev/null +++ b/platforms/android/cordova/node_modules/unorm/LICENSE.md @@ -0,0 +1,42 @@ +The software dual licensed under the MIT and GPL licenses. MIT license: + + Copyright (c) 2008-2013 Matsuza , Bjarke Walling + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + +GPL notice (please read the [full GPL license] online): + + Copyright (C) 2008-2013 Matsuza , Bjarke Walling + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +[full GPL license]: http://www.gnu.org/licenses/gpl-2.0-standalone.html diff --git a/platforms/android/cordova/node_modules/unorm/README.md b/platforms/android/cordova/node_modules/unorm/README.md new file mode 100644 index 0000000..6ff6420 --- /dev/null +++ b/platforms/android/cordova/node_modules/unorm/README.md @@ -0,0 +1,118 @@ +This is [Unicode Normalizer] in a Common JS module. I'm not affiliated with Matsuza, the original author of Unicode Normalizer. + +[![Build Status](https://travis-ci.org/walling/unorm.png?branch=master)](https://travis-ci.org/walling/unorm) + + +Installation +------------ + +```bash +npm install unorm +``` + +Polyfill +-------- + +You can use this module as a polyfill for [String.prototype.normalize], for example: + +```javascript +console.log('æøåäüö'.normalize('NFKD')); +``` + +The module uses some [EcmaScript 5](http://kangax.github.io/es5-compat-table/) features. Other browsers should use a compability shim, e.g. [es5-shim](https://github.com/kriskowal/es5-shim). + +Functions +--------- + +This module exports four functions: `nfc`, `nfd`, `nfkc`, and `nfkd`; one for each Unicode normalization. In the browser the functions are exported in the `unorm` global. In CommonJS environments you just require the module. Functions: + + * `unorm.nfd(str)` – Canonical Decomposition + * `unorm.nfc(str)` – Canonical Decomposition, followed by Canonical Composition + * `unorm.nfkd(str)` – Compatibility Decomposition + * `unorm.nfkc(str)` – Compatibility Decomposition, followed by Canonical Composition + + +Node.JS example +--------------- + +For a longer example, see `examples` directory. + +```javascript +var unorm = require('unorm'); + +var text = + 'The \u212B symbol invented by A. J. \u00C5ngstr\u00F6m ' + + '(1814, L\u00F6gd\u00F6, \u2013 1874) denotes the length ' + + '10\u207B\u00B9\u2070 m.'; + +var combining = /[\u0300-\u036F]/g; // Use XRegExp('\\p{M}', 'g'); see example.js. + +console.log('Regular: ' + text); +console.log('NFC: ' + unorm.nfc(text)); +console.log('NFD: ' + unorm.nfd(text)); +console.log('NFKC: ' + unorm.nfkc(text)); +console.log('NFKD: * ' + unorm.nfkd(text).replace(combining, '')); +console.log(' * = Combining characters removed from decomposed form.'); +``` + + +Road map +-------- + +As of November 2013. Longer term: + +- Look at possible optimizations (speed primarely, module size secondarily) +- Adding functions to quick check normalizations: `is_nfc`, `is_nfd`, etc. + + +Contributers +------------ + + - **Oleg Grenrus** is helping to maintain this library. He cleaned up the code base, fixed JSHint errors, created a test suite and updated the normalization data to Unicode 6.3. + + +Development notes +----------------- + +- [Unicode normalization forms report](http://www.unicode.org/reports/tr15/) +- Unicode data can be found from http://www.unicode.org/Public/UCD/latest/ucd + +To generate new unicode data, run: +```sh +cd src/data/src +javac UnormNormalizerBuilder.java +java UnormNormalizerBuilder +``` +produced `unormdata.js` contains needed table + +Execute `node benchmark/benchmark.js` to run simple benchmarks, if you do any changes which may affect performance. + +License +------- + +This project includes the software package **Unicode Normalizer 1.0.0**. The +software dual licensed under the MIT and GPL licenses. Here is the MIT license: + + Copyright (c) 2008-2013 Matsuza , Bjarke Walling + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + + +[Unicode Normalizer]: http://coderepos.org/share/browser/lang/javascript/UnicodeNormalizer +[String.prototype.normalize]: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.5.3.26 diff --git a/platforms/android/cordova/node_modules/unorm/lib/unorm.js b/platforms/android/cordova/node_modules/unorm/lib/unorm.js new file mode 100644 index 0000000..92d3699 --- /dev/null +++ b/platforms/android/cordova/node_modules/unorm/lib/unorm.js @@ -0,0 +1,442 @@ +(function (root) { + "use strict"; + +/***** unorm.js *****/ + +/* + * UnicodeNormalizer 1.0.0 + * Copyright (c) 2008 Matsuza + * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. + * $Date: 2008-06-05 16:44:17 +0200 (Thu, 05 Jun 2008) $ + * $Rev: 13309 $ + */ + + var DEFAULT_FEATURE = [null, 0, {}]; + var CACHE_THRESHOLD = 10; + var SBase = 0xAC00, LBase = 0x1100, VBase = 0x1161, TBase = 0x11A7, LCount = 19, VCount = 21, TCount = 28; + var NCount = VCount * TCount; // 588 + var SCount = LCount * NCount; // 11172 + + var UChar = function(cp, feature){ + this.codepoint = cp; + this.feature = feature; + }; + + // Strategies + var cache = {}; + var cacheCounter = []; + for (var i = 0; i <= 0xFF; ++i){ + cacheCounter[i] = 0; + } + + function fromCache(next, cp, needFeature){ + var ret = cache[cp]; + if(!ret){ + ret = next(cp, needFeature); + if(!!ret.feature && ++cacheCounter[(cp >> 8) & 0xFF] > CACHE_THRESHOLD){ + cache[cp] = ret; + } + } + return ret; + } + + function fromData(next, cp, needFeature){ + var hash = cp & 0xFF00; + var dunit = UChar.udata[hash] || {}; + var f = dunit[cp]; + return f ? new UChar(cp, f) : new UChar(cp, DEFAULT_FEATURE); + } + function fromCpOnly(next, cp, needFeature){ + return !!needFeature ? next(cp, needFeature) : new UChar(cp, null); + } + function fromRuleBasedJamo(next, cp, needFeature){ + var j; + if(cp < LBase || (LBase + LCount <= cp && cp < SBase) || (SBase + SCount < cp)){ + return next(cp, needFeature); + } + if(LBase <= cp && cp < LBase + LCount){ + var c = {}; + var base = (cp - LBase) * VCount; + for (j = 0; j < VCount; ++j){ + c[VBase + j] = SBase + TCount * (j + base); + } + return new UChar(cp, [,,c]); + } + + var SIndex = cp - SBase; + var TIndex = SIndex % TCount; + var feature = []; + if(TIndex !== 0){ + feature[0] = [SBase + SIndex - TIndex, TBase + TIndex]; + } else { + feature[0] = [LBase + Math.floor(SIndex / NCount), VBase + Math.floor((SIndex % NCount) / TCount)]; + feature[2] = {}; + for (j = 1; j < TCount; ++j){ + feature[2][TBase + j] = cp + j; + } + } + return new UChar(cp, feature); + } + function fromCpFilter(next, cp, needFeature){ + return cp < 60 || 13311 < cp && cp < 42607 ? new UChar(cp, DEFAULT_FEATURE) : next(cp, needFeature); + } + + var strategies = [fromCpFilter, fromCache, fromCpOnly, fromRuleBasedJamo, fromData]; + + UChar.fromCharCode = strategies.reduceRight(function (next, strategy) { + return function (cp, needFeature) { + return strategy(next, cp, needFeature); + }; + }, null); + + UChar.isHighSurrogate = function(cp){ + return cp >= 0xD800 && cp <= 0xDBFF; + }; + UChar.isLowSurrogate = function(cp){ + return cp >= 0xDC00 && cp <= 0xDFFF; + }; + + UChar.prototype.prepFeature = function(){ + if(!this.feature){ + this.feature = UChar.fromCharCode(this.codepoint, true).feature; + } + }; + + UChar.prototype.toString = function(){ + if(this.codepoint < 0x10000){ + return String.fromCharCode(this.codepoint); + } else { + var x = this.codepoint - 0x10000; + return String.fromCharCode(Math.floor(x / 0x400) + 0xD800, x % 0x400 + 0xDC00); + } + }; + + UChar.prototype.getDecomp = function(){ + this.prepFeature(); + return this.feature[0] || null; + }; + + UChar.prototype.isCompatibility = function(){ + this.prepFeature(); + return !!this.feature[1] && (this.feature[1] & (1 << 8)); + }; + UChar.prototype.isExclude = function(){ + this.prepFeature(); + return !!this.feature[1] && (this.feature[1] & (1 << 9)); + }; + UChar.prototype.getCanonicalClass = function(){ + this.prepFeature(); + return !!this.feature[1] ? (this.feature[1] & 0xff) : 0; + }; + UChar.prototype.getComposite = function(following){ + this.prepFeature(); + if(!this.feature[2]){ + return null; + } + var cp = this.feature[2][following.codepoint]; + return cp ? UChar.fromCharCode(cp) : null; + }; + + var UCharIterator = function(str){ + this.str = str; + this.cursor = 0; + }; + UCharIterator.prototype.next = function(){ + if(!!this.str && this.cursor < this.str.length){ + var cp = this.str.charCodeAt(this.cursor++); + var d; + if(UChar.isHighSurrogate(cp) && this.cursor < this.str.length && UChar.isLowSurrogate((d = this.str.charCodeAt(this.cursor)))){ + cp = (cp - 0xD800) * 0x400 + (d -0xDC00) + 0x10000; + ++this.cursor; + } + return UChar.fromCharCode(cp); + } else { + this.str = null; + return null; + } + }; + + var RecursDecompIterator = function(it, cano){ + this.it = it; + this.canonical = cano; + this.resBuf = []; + }; + + RecursDecompIterator.prototype.next = function(){ + function recursiveDecomp(cano, uchar){ + var decomp = uchar.getDecomp(); + if(!!decomp && !(cano && uchar.isCompatibility())){ + var ret = []; + for(var i = 0; i < decomp.length; ++i){ + var a = recursiveDecomp(cano, UChar.fromCharCode(decomp[i])); + ret = ret.concat(a); + } + return ret; + } else { + return [uchar]; + } + } + if(this.resBuf.length === 0){ + var uchar = this.it.next(); + if(!uchar){ + return null; + } + this.resBuf = recursiveDecomp(this.canonical, uchar); + } + return this.resBuf.shift(); + }; + + var DecompIterator = function(it){ + this.it = it; + this.resBuf = []; + }; + + DecompIterator.prototype.next = function(){ + var cc; + if(this.resBuf.length === 0){ + do{ + var uchar = this.it.next(); + if(!uchar){ + break; + } + cc = uchar.getCanonicalClass(); + var inspt = this.resBuf.length; + if(cc !== 0){ + for(; inspt > 0; --inspt){ + var uchar2 = this.resBuf[inspt - 1]; + var cc2 = uchar2.getCanonicalClass(); + if(cc2 <= cc){ + break; + } + } + } + this.resBuf.splice(inspt, 0, uchar); + } while(cc !== 0); + } + return this.resBuf.shift(); + }; + + var CompIterator = function(it){ + this.it = it; + this.procBuf = []; + this.resBuf = []; + this.lastClass = null; + }; + + CompIterator.prototype.next = function(){ + while(this.resBuf.length === 0){ + var uchar = this.it.next(); + if(!uchar){ + this.resBuf = this.procBuf; + this.procBuf = []; + break; + } + if(this.procBuf.length === 0){ + this.lastClass = uchar.getCanonicalClass(); + this.procBuf.push(uchar); + } else { + var starter = this.procBuf[0]; + var composite = starter.getComposite(uchar); + var cc = uchar.getCanonicalClass(); + if(!!composite && (this.lastClass < cc || this.lastClass === 0)){ + this.procBuf[0] = composite; + } else { + if(cc === 0){ + this.resBuf = this.procBuf; + this.procBuf = []; + } + this.lastClass = cc; + this.procBuf.push(uchar); + } + } + } + return this.resBuf.shift(); + }; + + var createIterator = function(mode, str){ + switch(mode){ + case "NFD": + return new DecompIterator(new RecursDecompIterator(new UCharIterator(str), true)); + case "NFKD": + return new DecompIterator(new RecursDecompIterator(new UCharIterator(str), false)); + case "NFC": + return new CompIterator(new DecompIterator(new RecursDecompIterator(new UCharIterator(str), true))); + case "NFKC": + return new CompIterator(new DecompIterator(new RecursDecompIterator(new UCharIterator(str), false))); + } + throw mode + " is invalid"; + }; + var normalize = function(mode, str){ + var it = createIterator(mode, str); + var ret = ""; + var uchar; + while(!!(uchar = it.next())){ + ret += uchar.toString(); + } + return ret; + }; + + /* API functions */ + function nfd(str){ + return normalize("NFD", str); + } + + function nfkd(str){ + return normalize("NFKD", str); + } + + function nfc(str){ + return normalize("NFC", str); + } + + function nfkc(str){ + return normalize("NFKC", str); + } + +/* Unicode data */ +UChar.udata={ +0:{60:[,,{824:8814}],61:[,,{824:8800}],62:[,,{824:8815}],65:[,,{768:192,769:193,770:194,771:195,772:256,774:258,775:550,776:196,777:7842,778:197,780:461,783:512,785:514,803:7840,805:7680,808:260}],66:[,,{775:7682,803:7684,817:7686}],67:[,,{769:262,770:264,775:266,780:268,807:199}],68:[,,{775:7690,780:270,803:7692,807:7696,813:7698,817:7694}],69:[,,{768:200,769:201,770:202,771:7868,772:274,774:276,775:278,776:203,777:7866,780:282,783:516,785:518,803:7864,807:552,808:280,813:7704,816:7706}],70:[,,{775:7710}],71:[,,{769:500,770:284,772:7712,774:286,775:288,780:486,807:290}],72:[,,{770:292,775:7714,776:7718,780:542,803:7716,807:7720,814:7722}],73:[,,{768:204,769:205,770:206,771:296,772:298,774:300,775:304,776:207,777:7880,780:463,783:520,785:522,803:7882,808:302,816:7724}],74:[,,{770:308}],75:[,,{769:7728,780:488,803:7730,807:310,817:7732}],76:[,,{769:313,780:317,803:7734,807:315,813:7740,817:7738}],77:[,,{769:7742,775:7744,803:7746}],78:[,,{768:504,769:323,771:209,775:7748,780:327,803:7750,807:325,813:7754,817:7752}],79:[,,{768:210,769:211,770:212,771:213,772:332,774:334,775:558,776:214,777:7886,779:336,780:465,783:524,785:526,795:416,803:7884,808:490}],80:[,,{769:7764,775:7766}],82:[,,{769:340,775:7768,780:344,783:528,785:530,803:7770,807:342,817:7774}],83:[,,{769:346,770:348,775:7776,780:352,803:7778,806:536,807:350}],84:[,,{775:7786,780:356,803:7788,806:538,807:354,813:7792,817:7790}],85:[,,{768:217,769:218,770:219,771:360,772:362,774:364,776:220,777:7910,778:366,779:368,780:467,783:532,785:534,795:431,803:7908,804:7794,808:370,813:7798,816:7796}],86:[,,{771:7804,803:7806}],87:[,,{768:7808,769:7810,770:372,775:7814,776:7812,803:7816}],88:[,,{775:7818,776:7820}],89:[,,{768:7922,769:221,770:374,771:7928,772:562,775:7822,776:376,777:7926,803:7924}],90:[,,{769:377,770:7824,775:379,780:381,803:7826,817:7828}],97:[,,{768:224,769:225,770:226,771:227,772:257,774:259,775:551,776:228,777:7843,778:229,780:462,783:513,785:515,803:7841,805:7681,808:261}],98:[,,{775:7683,803:7685,817:7687}],99:[,,{769:263,770:265,775:267,780:269,807:231}],100:[,,{775:7691,780:271,803:7693,807:7697,813:7699,817:7695}],101:[,,{768:232,769:233,770:234,771:7869,772:275,774:277,775:279,776:235,777:7867,780:283,783:517,785:519,803:7865,807:553,808:281,813:7705,816:7707}],102:[,,{775:7711}],103:[,,{769:501,770:285,772:7713,774:287,775:289,780:487,807:291}],104:[,,{770:293,775:7715,776:7719,780:543,803:7717,807:7721,814:7723,817:7830}],105:[,,{768:236,769:237,770:238,771:297,772:299,774:301,776:239,777:7881,780:464,783:521,785:523,803:7883,808:303,816:7725}],106:[,,{770:309,780:496}],107:[,,{769:7729,780:489,803:7731,807:311,817:7733}],108:[,,{769:314,780:318,803:7735,807:316,813:7741,817:7739}],109:[,,{769:7743,775:7745,803:7747}],110:[,,{768:505,769:324,771:241,775:7749,780:328,803:7751,807:326,813:7755,817:7753}],111:[,,{768:242,769:243,770:244,771:245,772:333,774:335,775:559,776:246,777:7887,779:337,780:466,783:525,785:527,795:417,803:7885,808:491}],112:[,,{769:7765,775:7767}],114:[,,{769:341,775:7769,780:345,783:529,785:531,803:7771,807:343,817:7775}],115:[,,{769:347,770:349,775:7777,780:353,803:7779,806:537,807:351}],116:[,,{775:7787,776:7831,780:357,803:7789,806:539,807:355,813:7793,817:7791}],117:[,,{768:249,769:250,770:251,771:361,772:363,774:365,776:252,777:7911,778:367,779:369,780:468,783:533,785:535,795:432,803:7909,804:7795,808:371,813:7799,816:7797}],118:[,,{771:7805,803:7807}],119:[,,{768:7809,769:7811,770:373,775:7815,776:7813,778:7832,803:7817}],120:[,,{775:7819,776:7821}],121:[,,{768:7923,769:253,770:375,771:7929,772:563,775:7823,776:255,777:7927,778:7833,803:7925}],122:[,,{769:378,770:7825,775:380,780:382,803:7827,817:7829}],160:[[32],256],168:[[32,776],256,{768:8173,769:901,834:8129}],170:[[97],256],175:[[32,772],256],178:[[50],256],179:[[51],256],180:[[32,769],256],181:[[956],256],184:[[32,807],256],185:[[49],256],186:[[111],256],188:[[49,8260,52],256],189:[[49,8260,50],256],190:[[51,8260,52],256],192:[[65,768]],193:[[65,769]],194:[[65,770],,{768:7846,769:7844,771:7850,777:7848}],195:[[65,771]],196:[[65,776],,{772:478}],197:[[65,778],,{769:506}],198:[,,{769:508,772:482}],199:[[67,807],,{769:7688}],200:[[69,768]],201:[[69,769]],202:[[69,770],,{768:7872,769:7870,771:7876,777:7874}],203:[[69,776]],204:[[73,768]],205:[[73,769]],206:[[73,770]],207:[[73,776],,{769:7726}],209:[[78,771]],210:[[79,768]],211:[[79,769]],212:[[79,770],,{768:7890,769:7888,771:7894,777:7892}],213:[[79,771],,{769:7756,772:556,776:7758}],214:[[79,776],,{772:554}],216:[,,{769:510}],217:[[85,768]],218:[[85,769]],219:[[85,770]],220:[[85,776],,{768:475,769:471,772:469,780:473}],221:[[89,769]],224:[[97,768]],225:[[97,769]],226:[[97,770],,{768:7847,769:7845,771:7851,777:7849}],227:[[97,771]],228:[[97,776],,{772:479}],229:[[97,778],,{769:507}],230:[,,{769:509,772:483}],231:[[99,807],,{769:7689}],232:[[101,768]],233:[[101,769]],234:[[101,770],,{768:7873,769:7871,771:7877,777:7875}],235:[[101,776]],236:[[105,768]],237:[[105,769]],238:[[105,770]],239:[[105,776],,{769:7727}],241:[[110,771]],242:[[111,768]],243:[[111,769]],244:[[111,770],,{768:7891,769:7889,771:7895,777:7893}],245:[[111,771],,{769:7757,772:557,776:7759}],246:[[111,776],,{772:555}],248:[,,{769:511}],249:[[117,768]],250:[[117,769]],251:[[117,770]],252:[[117,776],,{768:476,769:472,772:470,780:474}],253:[[121,769]],255:[[121,776]]}, +256:{256:[[65,772]],257:[[97,772]],258:[[65,774],,{768:7856,769:7854,771:7860,777:7858}],259:[[97,774],,{768:7857,769:7855,771:7861,777:7859}],260:[[65,808]],261:[[97,808]],262:[[67,769]],263:[[99,769]],264:[[67,770]],265:[[99,770]],266:[[67,775]],267:[[99,775]],268:[[67,780]],269:[[99,780]],270:[[68,780]],271:[[100,780]],274:[[69,772],,{768:7700,769:7702}],275:[[101,772],,{768:7701,769:7703}],276:[[69,774]],277:[[101,774]],278:[[69,775]],279:[[101,775]],280:[[69,808]],281:[[101,808]],282:[[69,780]],283:[[101,780]],284:[[71,770]],285:[[103,770]],286:[[71,774]],287:[[103,774]],288:[[71,775]],289:[[103,775]],290:[[71,807]],291:[[103,807]],292:[[72,770]],293:[[104,770]],296:[[73,771]],297:[[105,771]],298:[[73,772]],299:[[105,772]],300:[[73,774]],301:[[105,774]],302:[[73,808]],303:[[105,808]],304:[[73,775]],306:[[73,74],256],307:[[105,106],256],308:[[74,770]],309:[[106,770]],310:[[75,807]],311:[[107,807]],313:[[76,769]],314:[[108,769]],315:[[76,807]],316:[[108,807]],317:[[76,780]],318:[[108,780]],319:[[76,183],256],320:[[108,183],256],323:[[78,769]],324:[[110,769]],325:[[78,807]],326:[[110,807]],327:[[78,780]],328:[[110,780]],329:[[700,110],256],332:[[79,772],,{768:7760,769:7762}],333:[[111,772],,{768:7761,769:7763}],334:[[79,774]],335:[[111,774]],336:[[79,779]],337:[[111,779]],340:[[82,769]],341:[[114,769]],342:[[82,807]],343:[[114,807]],344:[[82,780]],345:[[114,780]],346:[[83,769],,{775:7780}],347:[[115,769],,{775:7781}],348:[[83,770]],349:[[115,770]],350:[[83,807]],351:[[115,807]],352:[[83,780],,{775:7782}],353:[[115,780],,{775:7783}],354:[[84,807]],355:[[116,807]],356:[[84,780]],357:[[116,780]],360:[[85,771],,{769:7800}],361:[[117,771],,{769:7801}],362:[[85,772],,{776:7802}],363:[[117,772],,{776:7803}],364:[[85,774]],365:[[117,774]],366:[[85,778]],367:[[117,778]],368:[[85,779]],369:[[117,779]],370:[[85,808]],371:[[117,808]],372:[[87,770]],373:[[119,770]],374:[[89,770]],375:[[121,770]],376:[[89,776]],377:[[90,769]],378:[[122,769]],379:[[90,775]],380:[[122,775]],381:[[90,780]],382:[[122,780]],383:[[115],256,{775:7835}],416:[[79,795],,{768:7900,769:7898,771:7904,777:7902,803:7906}],417:[[111,795],,{768:7901,769:7899,771:7905,777:7903,803:7907}],431:[[85,795],,{768:7914,769:7912,771:7918,777:7916,803:7920}],432:[[117,795],,{768:7915,769:7913,771:7919,777:7917,803:7921}],439:[,,{780:494}],452:[[68,381],256],453:[[68,382],256],454:[[100,382],256],455:[[76,74],256],456:[[76,106],256],457:[[108,106],256],458:[[78,74],256],459:[[78,106],256],460:[[110,106],256],461:[[65,780]],462:[[97,780]],463:[[73,780]],464:[[105,780]],465:[[79,780]],466:[[111,780]],467:[[85,780]],468:[[117,780]],469:[[220,772]],470:[[252,772]],471:[[220,769]],472:[[252,769]],473:[[220,780]],474:[[252,780]],475:[[220,768]],476:[[252,768]],478:[[196,772]],479:[[228,772]],480:[[550,772]],481:[[551,772]],482:[[198,772]],483:[[230,772]],486:[[71,780]],487:[[103,780]],488:[[75,780]],489:[[107,780]],490:[[79,808],,{772:492}],491:[[111,808],,{772:493}],492:[[490,772]],493:[[491,772]],494:[[439,780]],495:[[658,780]],496:[[106,780]],497:[[68,90],256],498:[[68,122],256],499:[[100,122],256],500:[[71,769]],501:[[103,769]],504:[[78,768]],505:[[110,768]],506:[[197,769]],507:[[229,769]],508:[[198,769]],509:[[230,769]],510:[[216,769]],511:[[248,769]],66045:[,220]}, +512:{512:[[65,783]],513:[[97,783]],514:[[65,785]],515:[[97,785]],516:[[69,783]],517:[[101,783]],518:[[69,785]],519:[[101,785]],520:[[73,783]],521:[[105,783]],522:[[73,785]],523:[[105,785]],524:[[79,783]],525:[[111,783]],526:[[79,785]],527:[[111,785]],528:[[82,783]],529:[[114,783]],530:[[82,785]],531:[[114,785]],532:[[85,783]],533:[[117,783]],534:[[85,785]],535:[[117,785]],536:[[83,806]],537:[[115,806]],538:[[84,806]],539:[[116,806]],542:[[72,780]],543:[[104,780]],550:[[65,775],,{772:480}],551:[[97,775],,{772:481}],552:[[69,807],,{774:7708}],553:[[101,807],,{774:7709}],554:[[214,772]],555:[[246,772]],556:[[213,772]],557:[[245,772]],558:[[79,775],,{772:560}],559:[[111,775],,{772:561}],560:[[558,772]],561:[[559,772]],562:[[89,772]],563:[[121,772]],658:[,,{780:495}],688:[[104],256],689:[[614],256],690:[[106],256],691:[[114],256],692:[[633],256],693:[[635],256],694:[[641],256],695:[[119],256],696:[[121],256],728:[[32,774],256],729:[[32,775],256],730:[[32,778],256],731:[[32,808],256],732:[[32,771],256],733:[[32,779],256],736:[[611],256],737:[[108],256],738:[[115],256],739:[[120],256],740:[[661],256],66272:[,220]}, +768:{768:[,230],769:[,230],770:[,230],771:[,230],772:[,230],773:[,230],774:[,230],775:[,230],776:[,230,{769:836}],777:[,230],778:[,230],779:[,230],780:[,230],781:[,230],782:[,230],783:[,230],784:[,230],785:[,230],786:[,230],787:[,230],788:[,230],789:[,232],790:[,220],791:[,220],792:[,220],793:[,220],794:[,232],795:[,216],796:[,220],797:[,220],798:[,220],799:[,220],800:[,220],801:[,202],802:[,202],803:[,220],804:[,220],805:[,220],806:[,220],807:[,202],808:[,202],809:[,220],810:[,220],811:[,220],812:[,220],813:[,220],814:[,220],815:[,220],816:[,220],817:[,220],818:[,220],819:[,220],820:[,1],821:[,1],822:[,1],823:[,1],824:[,1],825:[,220],826:[,220],827:[,220],828:[,220],829:[,230],830:[,230],831:[,230],832:[[768],230],833:[[769],230],834:[,230],835:[[787],230],836:[[776,769],230],837:[,240],838:[,230],839:[,220],840:[,220],841:[,220],842:[,230],843:[,230],844:[,230],845:[,220],846:[,220],848:[,230],849:[,230],850:[,230],851:[,220],852:[,220],853:[,220],854:[,220],855:[,230],856:[,232],857:[,220],858:[,220],859:[,230],860:[,233],861:[,234],862:[,234],863:[,233],864:[,234],865:[,234],866:[,233],867:[,230],868:[,230],869:[,230],870:[,230],871:[,230],872:[,230],873:[,230],874:[,230],875:[,230],876:[,230],877:[,230],878:[,230],879:[,230],884:[[697]],890:[[32,837],256],894:[[59]],900:[[32,769],256],901:[[168,769]],902:[[913,769]],903:[[183]],904:[[917,769]],905:[[919,769]],906:[[921,769]],908:[[927,769]],910:[[933,769]],911:[[937,769]],912:[[970,769]],913:[,,{768:8122,769:902,772:8121,774:8120,787:7944,788:7945,837:8124}],917:[,,{768:8136,769:904,787:7960,788:7961}],919:[,,{768:8138,769:905,787:7976,788:7977,837:8140}],921:[,,{768:8154,769:906,772:8153,774:8152,776:938,787:7992,788:7993}],927:[,,{768:8184,769:908,787:8008,788:8009}],929:[,,{788:8172}],933:[,,{768:8170,769:910,772:8169,774:8168,776:939,788:8025}],937:[,,{768:8186,769:911,787:8040,788:8041,837:8188}],938:[[921,776]],939:[[933,776]],940:[[945,769],,{837:8116}],941:[[949,769]],942:[[951,769],,{837:8132}],943:[[953,769]],944:[[971,769]],945:[,,{768:8048,769:940,772:8113,774:8112,787:7936,788:7937,834:8118,837:8115}],949:[,,{768:8050,769:941,787:7952,788:7953}],951:[,,{768:8052,769:942,787:7968,788:7969,834:8134,837:8131}],953:[,,{768:8054,769:943,772:8145,774:8144,776:970,787:7984,788:7985,834:8150}],959:[,,{768:8056,769:972,787:8000,788:8001}],961:[,,{787:8164,788:8165}],965:[,,{768:8058,769:973,772:8161,774:8160,776:971,787:8016,788:8017,834:8166}],969:[,,{768:8060,769:974,787:8032,788:8033,834:8182,837:8179}],970:[[953,776],,{768:8146,769:912,834:8151}],971:[[965,776],,{768:8162,769:944,834:8167}],972:[[959,769]],973:[[965,769]],974:[[969,769],,{837:8180}],976:[[946],256],977:[[952],256],978:[[933],256,{769:979,776:980}],979:[[978,769]],980:[[978,776]],981:[[966],256],982:[[960],256],1008:[[954],256],1009:[[961],256],1010:[[962],256],1012:[[920],256],1013:[[949],256],1017:[[931],256],66422:[,230],66423:[,230],66424:[,230],66425:[,230],66426:[,230]}, +1024:{1024:[[1045,768]],1025:[[1045,776]],1027:[[1043,769]],1030:[,,{776:1031}],1031:[[1030,776]],1036:[[1050,769]],1037:[[1048,768]],1038:[[1059,774]],1040:[,,{774:1232,776:1234}],1043:[,,{769:1027}],1045:[,,{768:1024,774:1238,776:1025}],1046:[,,{774:1217,776:1244}],1047:[,,{776:1246}],1048:[,,{768:1037,772:1250,774:1049,776:1252}],1049:[[1048,774]],1050:[,,{769:1036}],1054:[,,{776:1254}],1059:[,,{772:1262,774:1038,776:1264,779:1266}],1063:[,,{776:1268}],1067:[,,{776:1272}],1069:[,,{776:1260}],1072:[,,{774:1233,776:1235}],1075:[,,{769:1107}],1077:[,,{768:1104,774:1239,776:1105}],1078:[,,{774:1218,776:1245}],1079:[,,{776:1247}],1080:[,,{768:1117,772:1251,774:1081,776:1253}],1081:[[1080,774]],1082:[,,{769:1116}],1086:[,,{776:1255}],1091:[,,{772:1263,774:1118,776:1265,779:1267}],1095:[,,{776:1269}],1099:[,,{776:1273}],1101:[,,{776:1261}],1104:[[1077,768]],1105:[[1077,776]],1107:[[1075,769]],1110:[,,{776:1111}],1111:[[1110,776]],1116:[[1082,769]],1117:[[1080,768]],1118:[[1091,774]],1140:[,,{783:1142}],1141:[,,{783:1143}],1142:[[1140,783]],1143:[[1141,783]],1155:[,230],1156:[,230],1157:[,230],1158:[,230],1159:[,230],1217:[[1046,774]],1218:[[1078,774]],1232:[[1040,774]],1233:[[1072,774]],1234:[[1040,776]],1235:[[1072,776]],1238:[[1045,774]],1239:[[1077,774]],1240:[,,{776:1242}],1241:[,,{776:1243}],1242:[[1240,776]],1243:[[1241,776]],1244:[[1046,776]],1245:[[1078,776]],1246:[[1047,776]],1247:[[1079,776]],1250:[[1048,772]],1251:[[1080,772]],1252:[[1048,776]],1253:[[1080,776]],1254:[[1054,776]],1255:[[1086,776]],1256:[,,{776:1258}],1257:[,,{776:1259}],1258:[[1256,776]],1259:[[1257,776]],1260:[[1069,776]],1261:[[1101,776]],1262:[[1059,772]],1263:[[1091,772]],1264:[[1059,776]],1265:[[1091,776]],1266:[[1059,779]],1267:[[1091,779]],1268:[[1063,776]],1269:[[1095,776]],1272:[[1067,776]],1273:[[1099,776]]}, +1280:{1415:[[1381,1410],256],1425:[,220],1426:[,230],1427:[,230],1428:[,230],1429:[,230],1430:[,220],1431:[,230],1432:[,230],1433:[,230],1434:[,222],1435:[,220],1436:[,230],1437:[,230],1438:[,230],1439:[,230],1440:[,230],1441:[,230],1442:[,220],1443:[,220],1444:[,220],1445:[,220],1446:[,220],1447:[,220],1448:[,230],1449:[,230],1450:[,220],1451:[,230],1452:[,230],1453:[,222],1454:[,228],1455:[,230],1456:[,10],1457:[,11],1458:[,12],1459:[,13],1460:[,14],1461:[,15],1462:[,16],1463:[,17],1464:[,18],1465:[,19],1466:[,19],1467:[,20],1468:[,21],1469:[,22],1471:[,23],1473:[,24],1474:[,25],1476:[,230],1477:[,220],1479:[,18]}, +1536:{1552:[,230],1553:[,230],1554:[,230],1555:[,230],1556:[,230],1557:[,230],1558:[,230],1559:[,230],1560:[,30],1561:[,31],1562:[,32],1570:[[1575,1619]],1571:[[1575,1620]],1572:[[1608,1620]],1573:[[1575,1621]],1574:[[1610,1620]],1575:[,,{1619:1570,1620:1571,1621:1573}],1608:[,,{1620:1572}],1610:[,,{1620:1574}],1611:[,27],1612:[,28],1613:[,29],1614:[,30],1615:[,31],1616:[,32],1617:[,33],1618:[,34],1619:[,230],1620:[,230],1621:[,220],1622:[,220],1623:[,230],1624:[,230],1625:[,230],1626:[,230],1627:[,230],1628:[,220],1629:[,230],1630:[,230],1631:[,220],1648:[,35],1653:[[1575,1652],256],1654:[[1608,1652],256],1655:[[1735,1652],256],1656:[[1610,1652],256],1728:[[1749,1620]],1729:[,,{1620:1730}],1730:[[1729,1620]],1746:[,,{1620:1747}],1747:[[1746,1620]],1749:[,,{1620:1728}],1750:[,230],1751:[,230],1752:[,230],1753:[,230],1754:[,230],1755:[,230],1756:[,230],1759:[,230],1760:[,230],1761:[,230],1762:[,230],1763:[,220],1764:[,230],1767:[,230],1768:[,230],1770:[,220],1771:[,230],1772:[,230],1773:[,220]}, +1792:{1809:[,36],1840:[,230],1841:[,220],1842:[,230],1843:[,230],1844:[,220],1845:[,230],1846:[,230],1847:[,220],1848:[,220],1849:[,220],1850:[,230],1851:[,220],1852:[,220],1853:[,230],1854:[,220],1855:[,230],1856:[,230],1857:[,230],1858:[,220],1859:[,230],1860:[,220],1861:[,230],1862:[,220],1863:[,230],1864:[,220],1865:[,230],1866:[,230],2027:[,230],2028:[,230],2029:[,230],2030:[,230],2031:[,230],2032:[,230],2033:[,230],2034:[,220],2035:[,230]}, +2048:{2070:[,230],2071:[,230],2072:[,230],2073:[,230],2075:[,230],2076:[,230],2077:[,230],2078:[,230],2079:[,230],2080:[,230],2081:[,230],2082:[,230],2083:[,230],2085:[,230],2086:[,230],2087:[,230],2089:[,230],2090:[,230],2091:[,230],2092:[,230],2093:[,230],2137:[,220],2138:[,220],2139:[,220],2276:[,230],2277:[,230],2278:[,220],2279:[,230],2280:[,230],2281:[,220],2282:[,230],2283:[,230],2284:[,230],2285:[,220],2286:[,220],2287:[,220],2288:[,27],2289:[,28],2290:[,29],2291:[,230],2292:[,230],2293:[,230],2294:[,220],2295:[,230],2296:[,230],2297:[,220],2298:[,220],2299:[,230],2300:[,230],2301:[,230],2302:[,230],2303:[,230]}, +2304:{2344:[,,{2364:2345}],2345:[[2344,2364]],2352:[,,{2364:2353}],2353:[[2352,2364]],2355:[,,{2364:2356}],2356:[[2355,2364]],2364:[,7],2381:[,9],2385:[,230],2386:[,220],2387:[,230],2388:[,230],2392:[[2325,2364],512],2393:[[2326,2364],512],2394:[[2327,2364],512],2395:[[2332,2364],512],2396:[[2337,2364],512],2397:[[2338,2364],512],2398:[[2347,2364],512],2399:[[2351,2364],512],2492:[,7],2503:[,,{2494:2507,2519:2508}],2507:[[2503,2494]],2508:[[2503,2519]],2509:[,9],2524:[[2465,2492],512],2525:[[2466,2492],512],2527:[[2479,2492],512]}, +2560:{2611:[[2610,2620],512],2614:[[2616,2620],512],2620:[,7],2637:[,9],2649:[[2582,2620],512],2650:[[2583,2620],512],2651:[[2588,2620],512],2654:[[2603,2620],512],2748:[,7],2765:[,9],68109:[,220],68111:[,230],68152:[,230],68153:[,1],68154:[,220],68159:[,9],68325:[,230],68326:[,220]}, +2816:{2876:[,7],2887:[,,{2878:2891,2902:2888,2903:2892}],2888:[[2887,2902]],2891:[[2887,2878]],2892:[[2887,2903]],2893:[,9],2908:[[2849,2876],512],2909:[[2850,2876],512],2962:[,,{3031:2964}],2964:[[2962,3031]],3014:[,,{3006:3018,3031:3020}],3015:[,,{3006:3019}],3018:[[3014,3006]],3019:[[3015,3006]],3020:[[3014,3031]],3021:[,9]}, +3072:{3142:[,,{3158:3144}],3144:[[3142,3158]],3149:[,9],3157:[,84],3158:[,91],3260:[,7],3263:[,,{3285:3264}],3264:[[3263,3285]],3270:[,,{3266:3274,3285:3271,3286:3272}],3271:[[3270,3285]],3272:[[3270,3286]],3274:[[3270,3266],,{3285:3275}],3275:[[3274,3285]],3277:[,9]}, +3328:{3398:[,,{3390:3402,3415:3404}],3399:[,,{3390:3403}],3402:[[3398,3390]],3403:[[3399,3390]],3404:[[3398,3415]],3405:[,9],3530:[,9],3545:[,,{3530:3546,3535:3548,3551:3550}],3546:[[3545,3530]],3548:[[3545,3535],,{3530:3549}],3549:[[3548,3530]],3550:[[3545,3551]]}, +3584:{3635:[[3661,3634],256],3640:[,103],3641:[,103],3642:[,9],3656:[,107],3657:[,107],3658:[,107],3659:[,107],3763:[[3789,3762],256],3768:[,118],3769:[,118],3784:[,122],3785:[,122],3786:[,122],3787:[,122],3804:[[3755,3737],256],3805:[[3755,3745],256]}, +3840:{3852:[[3851],256],3864:[,220],3865:[,220],3893:[,220],3895:[,220],3897:[,216],3907:[[3906,4023],512],3917:[[3916,4023],512],3922:[[3921,4023],512],3927:[[3926,4023],512],3932:[[3931,4023],512],3945:[[3904,4021],512],3953:[,129],3954:[,130],3955:[[3953,3954],512],3956:[,132],3957:[[3953,3956],512],3958:[[4018,3968],512],3959:[[4018,3969],256],3960:[[4019,3968],512],3961:[[4019,3969],256],3962:[,130],3963:[,130],3964:[,130],3965:[,130],3968:[,130],3969:[[3953,3968],512],3970:[,230],3971:[,230],3972:[,9],3974:[,230],3975:[,230],3987:[[3986,4023],512],3997:[[3996,4023],512],4002:[[4001,4023],512],4007:[[4006,4023],512],4012:[[4011,4023],512],4025:[[3984,4021],512],4038:[,220]}, +4096:{4133:[,,{4142:4134}],4134:[[4133,4142]],4151:[,7],4153:[,9],4154:[,9],4237:[,220],4348:[[4316],256],69702:[,9],69759:[,9],69785:[,,{69818:69786}],69786:[[69785,69818]],69787:[,,{69818:69788}],69788:[[69787,69818]],69797:[,,{69818:69803}],69803:[[69797,69818]],69817:[,9],69818:[,7]}, +4352:{69888:[,230],69889:[,230],69890:[,230],69934:[[69937,69927]],69935:[[69938,69927]],69937:[,,{69927:69934}],69938:[,,{69927:69935}],69939:[,9],69940:[,9],70003:[,7],70080:[,9]}, +4608:{70197:[,9],70198:[,7],70377:[,7],70378:[,9]}, +4864:{4957:[,230],4958:[,230],4959:[,230],70460:[,7],70471:[,,{70462:70475,70487:70476}],70475:[[70471,70462]],70476:[[70471,70487]],70477:[,9],70502:[,230],70503:[,230],70504:[,230],70505:[,230],70506:[,230],70507:[,230],70508:[,230],70512:[,230],70513:[,230],70514:[,230],70515:[,230],70516:[,230]}, +5120:{70841:[,,{70832:70844,70842:70843,70845:70846}],70843:[[70841,70842]],70844:[[70841,70832]],70846:[[70841,70845]],70850:[,9],70851:[,7]}, +5376:{71096:[,,{71087:71098}],71097:[,,{71087:71099}],71098:[[71096,71087]],71099:[[71097,71087]],71103:[,9],71104:[,7]}, +5632:{71231:[,9],71350:[,9],71351:[,7]}, +5888:{5908:[,9],5940:[,9],6098:[,9],6109:[,230]}, +6144:{6313:[,228]}, +6400:{6457:[,222],6458:[,230],6459:[,220]}, +6656:{6679:[,230],6680:[,220],6752:[,9],6773:[,230],6774:[,230],6775:[,230],6776:[,230],6777:[,230],6778:[,230],6779:[,230],6780:[,230],6783:[,220],6832:[,230],6833:[,230],6834:[,230],6835:[,230],6836:[,230],6837:[,220],6838:[,220],6839:[,220],6840:[,220],6841:[,220],6842:[,220],6843:[,230],6844:[,230],6845:[,220]}, +6912:{6917:[,,{6965:6918}],6918:[[6917,6965]],6919:[,,{6965:6920}],6920:[[6919,6965]],6921:[,,{6965:6922}],6922:[[6921,6965]],6923:[,,{6965:6924}],6924:[[6923,6965]],6925:[,,{6965:6926}],6926:[[6925,6965]],6929:[,,{6965:6930}],6930:[[6929,6965]],6964:[,7],6970:[,,{6965:6971}],6971:[[6970,6965]],6972:[,,{6965:6973}],6973:[[6972,6965]],6974:[,,{6965:6976}],6975:[,,{6965:6977}],6976:[[6974,6965]],6977:[[6975,6965]],6978:[,,{6965:6979}],6979:[[6978,6965]],6980:[,9],7019:[,230],7020:[,220],7021:[,230],7022:[,230],7023:[,230],7024:[,230],7025:[,230],7026:[,230],7027:[,230],7082:[,9],7083:[,9],7142:[,7],7154:[,9],7155:[,9]}, +7168:{7223:[,7],7376:[,230],7377:[,230],7378:[,230],7380:[,1],7381:[,220],7382:[,220],7383:[,220],7384:[,220],7385:[,220],7386:[,230],7387:[,230],7388:[,220],7389:[,220],7390:[,220],7391:[,220],7392:[,230],7394:[,1],7395:[,1],7396:[,1],7397:[,1],7398:[,1],7399:[,1],7400:[,1],7405:[,220],7412:[,230],7416:[,230],7417:[,230]}, +7424:{7468:[[65],256],7469:[[198],256],7470:[[66],256],7472:[[68],256],7473:[[69],256],7474:[[398],256],7475:[[71],256],7476:[[72],256],7477:[[73],256],7478:[[74],256],7479:[[75],256],7480:[[76],256],7481:[[77],256],7482:[[78],256],7484:[[79],256],7485:[[546],256],7486:[[80],256],7487:[[82],256],7488:[[84],256],7489:[[85],256],7490:[[87],256],7491:[[97],256],7492:[[592],256],7493:[[593],256],7494:[[7426],256],7495:[[98],256],7496:[[100],256],7497:[[101],256],7498:[[601],256],7499:[[603],256],7500:[[604],256],7501:[[103],256],7503:[[107],256],7504:[[109],256],7505:[[331],256],7506:[[111],256],7507:[[596],256],7508:[[7446],256],7509:[[7447],256],7510:[[112],256],7511:[[116],256],7512:[[117],256],7513:[[7453],256],7514:[[623],256],7515:[[118],256],7516:[[7461],256],7517:[[946],256],7518:[[947],256],7519:[[948],256],7520:[[966],256],7521:[[967],256],7522:[[105],256],7523:[[114],256],7524:[[117],256],7525:[[118],256],7526:[[946],256],7527:[[947],256],7528:[[961],256],7529:[[966],256],7530:[[967],256],7544:[[1085],256],7579:[[594],256],7580:[[99],256],7581:[[597],256],7582:[[240],256],7583:[[604],256],7584:[[102],256],7585:[[607],256],7586:[[609],256],7587:[[613],256],7588:[[616],256],7589:[[617],256],7590:[[618],256],7591:[[7547],256],7592:[[669],256],7593:[[621],256],7594:[[7557],256],7595:[[671],256],7596:[[625],256],7597:[[624],256],7598:[[626],256],7599:[[627],256],7600:[[628],256],7601:[[629],256],7602:[[632],256],7603:[[642],256],7604:[[643],256],7605:[[427],256],7606:[[649],256],7607:[[650],256],7608:[[7452],256],7609:[[651],256],7610:[[652],256],7611:[[122],256],7612:[[656],256],7613:[[657],256],7614:[[658],256],7615:[[952],256],7616:[,230],7617:[,230],7618:[,220],7619:[,230],7620:[,230],7621:[,230],7622:[,230],7623:[,230],7624:[,230],7625:[,230],7626:[,220],7627:[,230],7628:[,230],7629:[,234],7630:[,214],7631:[,220],7632:[,202],7633:[,230],7634:[,230],7635:[,230],7636:[,230],7637:[,230],7638:[,230],7639:[,230],7640:[,230],7641:[,230],7642:[,230],7643:[,230],7644:[,230],7645:[,230],7646:[,230],7647:[,230],7648:[,230],7649:[,230],7650:[,230],7651:[,230],7652:[,230],7653:[,230],7654:[,230],7655:[,230],7656:[,230],7657:[,230],7658:[,230],7659:[,230],7660:[,230],7661:[,230],7662:[,230],7663:[,230],7664:[,230],7665:[,230],7666:[,230],7667:[,230],7668:[,230],7669:[,230],7676:[,233],7677:[,220],7678:[,230],7679:[,220]}, +7680:{7680:[[65,805]],7681:[[97,805]],7682:[[66,775]],7683:[[98,775]],7684:[[66,803]],7685:[[98,803]],7686:[[66,817]],7687:[[98,817]],7688:[[199,769]],7689:[[231,769]],7690:[[68,775]],7691:[[100,775]],7692:[[68,803]],7693:[[100,803]],7694:[[68,817]],7695:[[100,817]],7696:[[68,807]],7697:[[100,807]],7698:[[68,813]],7699:[[100,813]],7700:[[274,768]],7701:[[275,768]],7702:[[274,769]],7703:[[275,769]],7704:[[69,813]],7705:[[101,813]],7706:[[69,816]],7707:[[101,816]],7708:[[552,774]],7709:[[553,774]],7710:[[70,775]],7711:[[102,775]],7712:[[71,772]],7713:[[103,772]],7714:[[72,775]],7715:[[104,775]],7716:[[72,803]],7717:[[104,803]],7718:[[72,776]],7719:[[104,776]],7720:[[72,807]],7721:[[104,807]],7722:[[72,814]],7723:[[104,814]],7724:[[73,816]],7725:[[105,816]],7726:[[207,769]],7727:[[239,769]],7728:[[75,769]],7729:[[107,769]],7730:[[75,803]],7731:[[107,803]],7732:[[75,817]],7733:[[107,817]],7734:[[76,803],,{772:7736}],7735:[[108,803],,{772:7737}],7736:[[7734,772]],7737:[[7735,772]],7738:[[76,817]],7739:[[108,817]],7740:[[76,813]],7741:[[108,813]],7742:[[77,769]],7743:[[109,769]],7744:[[77,775]],7745:[[109,775]],7746:[[77,803]],7747:[[109,803]],7748:[[78,775]],7749:[[110,775]],7750:[[78,803]],7751:[[110,803]],7752:[[78,817]],7753:[[110,817]],7754:[[78,813]],7755:[[110,813]],7756:[[213,769]],7757:[[245,769]],7758:[[213,776]],7759:[[245,776]],7760:[[332,768]],7761:[[333,768]],7762:[[332,769]],7763:[[333,769]],7764:[[80,769]],7765:[[112,769]],7766:[[80,775]],7767:[[112,775]],7768:[[82,775]],7769:[[114,775]],7770:[[82,803],,{772:7772}],7771:[[114,803],,{772:7773}],7772:[[7770,772]],7773:[[7771,772]],7774:[[82,817]],7775:[[114,817]],7776:[[83,775]],7777:[[115,775]],7778:[[83,803],,{775:7784}],7779:[[115,803],,{775:7785}],7780:[[346,775]],7781:[[347,775]],7782:[[352,775]],7783:[[353,775]],7784:[[7778,775]],7785:[[7779,775]],7786:[[84,775]],7787:[[116,775]],7788:[[84,803]],7789:[[116,803]],7790:[[84,817]],7791:[[116,817]],7792:[[84,813]],7793:[[116,813]],7794:[[85,804]],7795:[[117,804]],7796:[[85,816]],7797:[[117,816]],7798:[[85,813]],7799:[[117,813]],7800:[[360,769]],7801:[[361,769]],7802:[[362,776]],7803:[[363,776]],7804:[[86,771]],7805:[[118,771]],7806:[[86,803]],7807:[[118,803]],7808:[[87,768]],7809:[[119,768]],7810:[[87,769]],7811:[[119,769]],7812:[[87,776]],7813:[[119,776]],7814:[[87,775]],7815:[[119,775]],7816:[[87,803]],7817:[[119,803]],7818:[[88,775]],7819:[[120,775]],7820:[[88,776]],7821:[[120,776]],7822:[[89,775]],7823:[[121,775]],7824:[[90,770]],7825:[[122,770]],7826:[[90,803]],7827:[[122,803]],7828:[[90,817]],7829:[[122,817]],7830:[[104,817]],7831:[[116,776]],7832:[[119,778]],7833:[[121,778]],7834:[[97,702],256],7835:[[383,775]],7840:[[65,803],,{770:7852,774:7862}],7841:[[97,803],,{770:7853,774:7863}],7842:[[65,777]],7843:[[97,777]],7844:[[194,769]],7845:[[226,769]],7846:[[194,768]],7847:[[226,768]],7848:[[194,777]],7849:[[226,777]],7850:[[194,771]],7851:[[226,771]],7852:[[7840,770]],7853:[[7841,770]],7854:[[258,769]],7855:[[259,769]],7856:[[258,768]],7857:[[259,768]],7858:[[258,777]],7859:[[259,777]],7860:[[258,771]],7861:[[259,771]],7862:[[7840,774]],7863:[[7841,774]],7864:[[69,803],,{770:7878}],7865:[[101,803],,{770:7879}],7866:[[69,777]],7867:[[101,777]],7868:[[69,771]],7869:[[101,771]],7870:[[202,769]],7871:[[234,769]],7872:[[202,768]],7873:[[234,768]],7874:[[202,777]],7875:[[234,777]],7876:[[202,771]],7877:[[234,771]],7878:[[7864,770]],7879:[[7865,770]],7880:[[73,777]],7881:[[105,777]],7882:[[73,803]],7883:[[105,803]],7884:[[79,803],,{770:7896}],7885:[[111,803],,{770:7897}],7886:[[79,777]],7887:[[111,777]],7888:[[212,769]],7889:[[244,769]],7890:[[212,768]],7891:[[244,768]],7892:[[212,777]],7893:[[244,777]],7894:[[212,771]],7895:[[244,771]],7896:[[7884,770]],7897:[[7885,770]],7898:[[416,769]],7899:[[417,769]],7900:[[416,768]],7901:[[417,768]],7902:[[416,777]],7903:[[417,777]],7904:[[416,771]],7905:[[417,771]],7906:[[416,803]],7907:[[417,803]],7908:[[85,803]],7909:[[117,803]],7910:[[85,777]],7911:[[117,777]],7912:[[431,769]],7913:[[432,769]],7914:[[431,768]],7915:[[432,768]],7916:[[431,777]],7917:[[432,777]],7918:[[431,771]],7919:[[432,771]],7920:[[431,803]],7921:[[432,803]],7922:[[89,768]],7923:[[121,768]],7924:[[89,803]],7925:[[121,803]],7926:[[89,777]],7927:[[121,777]],7928:[[89,771]],7929:[[121,771]]}, +7936:{7936:[[945,787],,{768:7938,769:7940,834:7942,837:8064}],7937:[[945,788],,{768:7939,769:7941,834:7943,837:8065}],7938:[[7936,768],,{837:8066}],7939:[[7937,768],,{837:8067}],7940:[[7936,769],,{837:8068}],7941:[[7937,769],,{837:8069}],7942:[[7936,834],,{837:8070}],7943:[[7937,834],,{837:8071}],7944:[[913,787],,{768:7946,769:7948,834:7950,837:8072}],7945:[[913,788],,{768:7947,769:7949,834:7951,837:8073}],7946:[[7944,768],,{837:8074}],7947:[[7945,768],,{837:8075}],7948:[[7944,769],,{837:8076}],7949:[[7945,769],,{837:8077}],7950:[[7944,834],,{837:8078}],7951:[[7945,834],,{837:8079}],7952:[[949,787],,{768:7954,769:7956}],7953:[[949,788],,{768:7955,769:7957}],7954:[[7952,768]],7955:[[7953,768]],7956:[[7952,769]],7957:[[7953,769]],7960:[[917,787],,{768:7962,769:7964}],7961:[[917,788],,{768:7963,769:7965}],7962:[[7960,768]],7963:[[7961,768]],7964:[[7960,769]],7965:[[7961,769]],7968:[[951,787],,{768:7970,769:7972,834:7974,837:8080}],7969:[[951,788],,{768:7971,769:7973,834:7975,837:8081}],7970:[[7968,768],,{837:8082}],7971:[[7969,768],,{837:8083}],7972:[[7968,769],,{837:8084}],7973:[[7969,769],,{837:8085}],7974:[[7968,834],,{837:8086}],7975:[[7969,834],,{837:8087}],7976:[[919,787],,{768:7978,769:7980,834:7982,837:8088}],7977:[[919,788],,{768:7979,769:7981,834:7983,837:8089}],7978:[[7976,768],,{837:8090}],7979:[[7977,768],,{837:8091}],7980:[[7976,769],,{837:8092}],7981:[[7977,769],,{837:8093}],7982:[[7976,834],,{837:8094}],7983:[[7977,834],,{837:8095}],7984:[[953,787],,{768:7986,769:7988,834:7990}],7985:[[953,788],,{768:7987,769:7989,834:7991}],7986:[[7984,768]],7987:[[7985,768]],7988:[[7984,769]],7989:[[7985,769]],7990:[[7984,834]],7991:[[7985,834]],7992:[[921,787],,{768:7994,769:7996,834:7998}],7993:[[921,788],,{768:7995,769:7997,834:7999}],7994:[[7992,768]],7995:[[7993,768]],7996:[[7992,769]],7997:[[7993,769]],7998:[[7992,834]],7999:[[7993,834]],8000:[[959,787],,{768:8002,769:8004}],8001:[[959,788],,{768:8003,769:8005}],8002:[[8000,768]],8003:[[8001,768]],8004:[[8000,769]],8005:[[8001,769]],8008:[[927,787],,{768:8010,769:8012}],8009:[[927,788],,{768:8011,769:8013}],8010:[[8008,768]],8011:[[8009,768]],8012:[[8008,769]],8013:[[8009,769]],8016:[[965,787],,{768:8018,769:8020,834:8022}],8017:[[965,788],,{768:8019,769:8021,834:8023}],8018:[[8016,768]],8019:[[8017,768]],8020:[[8016,769]],8021:[[8017,769]],8022:[[8016,834]],8023:[[8017,834]],8025:[[933,788],,{768:8027,769:8029,834:8031}],8027:[[8025,768]],8029:[[8025,769]],8031:[[8025,834]],8032:[[969,787],,{768:8034,769:8036,834:8038,837:8096}],8033:[[969,788],,{768:8035,769:8037,834:8039,837:8097}],8034:[[8032,768],,{837:8098}],8035:[[8033,768],,{837:8099}],8036:[[8032,769],,{837:8100}],8037:[[8033,769],,{837:8101}],8038:[[8032,834],,{837:8102}],8039:[[8033,834],,{837:8103}],8040:[[937,787],,{768:8042,769:8044,834:8046,837:8104}],8041:[[937,788],,{768:8043,769:8045,834:8047,837:8105}],8042:[[8040,768],,{837:8106}],8043:[[8041,768],,{837:8107}],8044:[[8040,769],,{837:8108}],8045:[[8041,769],,{837:8109}],8046:[[8040,834],,{837:8110}],8047:[[8041,834],,{837:8111}],8048:[[945,768],,{837:8114}],8049:[[940]],8050:[[949,768]],8051:[[941]],8052:[[951,768],,{837:8130}],8053:[[942]],8054:[[953,768]],8055:[[943]],8056:[[959,768]],8057:[[972]],8058:[[965,768]],8059:[[973]],8060:[[969,768],,{837:8178}],8061:[[974]],8064:[[7936,837]],8065:[[7937,837]],8066:[[7938,837]],8067:[[7939,837]],8068:[[7940,837]],8069:[[7941,837]],8070:[[7942,837]],8071:[[7943,837]],8072:[[7944,837]],8073:[[7945,837]],8074:[[7946,837]],8075:[[7947,837]],8076:[[7948,837]],8077:[[7949,837]],8078:[[7950,837]],8079:[[7951,837]],8080:[[7968,837]],8081:[[7969,837]],8082:[[7970,837]],8083:[[7971,837]],8084:[[7972,837]],8085:[[7973,837]],8086:[[7974,837]],8087:[[7975,837]],8088:[[7976,837]],8089:[[7977,837]],8090:[[7978,837]],8091:[[7979,837]],8092:[[7980,837]],8093:[[7981,837]],8094:[[7982,837]],8095:[[7983,837]],8096:[[8032,837]],8097:[[8033,837]],8098:[[8034,837]],8099:[[8035,837]],8100:[[8036,837]],8101:[[8037,837]],8102:[[8038,837]],8103:[[8039,837]],8104:[[8040,837]],8105:[[8041,837]],8106:[[8042,837]],8107:[[8043,837]],8108:[[8044,837]],8109:[[8045,837]],8110:[[8046,837]],8111:[[8047,837]],8112:[[945,774]],8113:[[945,772]],8114:[[8048,837]],8115:[[945,837]],8116:[[940,837]],8118:[[945,834],,{837:8119}],8119:[[8118,837]],8120:[[913,774]],8121:[[913,772]],8122:[[913,768]],8123:[[902]],8124:[[913,837]],8125:[[32,787],256],8126:[[953]],8127:[[32,787],256,{768:8141,769:8142,834:8143}],8128:[[32,834],256],8129:[[168,834]],8130:[[8052,837]],8131:[[951,837]],8132:[[942,837]],8134:[[951,834],,{837:8135}],8135:[[8134,837]],8136:[[917,768]],8137:[[904]],8138:[[919,768]],8139:[[905]],8140:[[919,837]],8141:[[8127,768]],8142:[[8127,769]],8143:[[8127,834]],8144:[[953,774]],8145:[[953,772]],8146:[[970,768]],8147:[[912]],8150:[[953,834]],8151:[[970,834]],8152:[[921,774]],8153:[[921,772]],8154:[[921,768]],8155:[[906]],8157:[[8190,768]],8158:[[8190,769]],8159:[[8190,834]],8160:[[965,774]],8161:[[965,772]],8162:[[971,768]],8163:[[944]],8164:[[961,787]],8165:[[961,788]],8166:[[965,834]],8167:[[971,834]],8168:[[933,774]],8169:[[933,772]],8170:[[933,768]],8171:[[910]],8172:[[929,788]],8173:[[168,768]],8174:[[901]],8175:[[96]],8178:[[8060,837]],8179:[[969,837]],8180:[[974,837]],8182:[[969,834],,{837:8183}],8183:[[8182,837]],8184:[[927,768]],8185:[[908]],8186:[[937,768]],8187:[[911]],8188:[[937,837]],8189:[[180]],8190:[[32,788],256,{768:8157,769:8158,834:8159}]}, +8192:{8192:[[8194]],8193:[[8195]],8194:[[32],256],8195:[[32],256],8196:[[32],256],8197:[[32],256],8198:[[32],256],8199:[[32],256],8200:[[32],256],8201:[[32],256],8202:[[32],256],8209:[[8208],256],8215:[[32,819],256],8228:[[46],256],8229:[[46,46],256],8230:[[46,46,46],256],8239:[[32],256],8243:[[8242,8242],256],8244:[[8242,8242,8242],256],8246:[[8245,8245],256],8247:[[8245,8245,8245],256],8252:[[33,33],256],8254:[[32,773],256],8263:[[63,63],256],8264:[[63,33],256],8265:[[33,63],256],8279:[[8242,8242,8242,8242],256],8287:[[32],256],8304:[[48],256],8305:[[105],256],8308:[[52],256],8309:[[53],256],8310:[[54],256],8311:[[55],256],8312:[[56],256],8313:[[57],256],8314:[[43],256],8315:[[8722],256],8316:[[61],256],8317:[[40],256],8318:[[41],256],8319:[[110],256],8320:[[48],256],8321:[[49],256],8322:[[50],256],8323:[[51],256],8324:[[52],256],8325:[[53],256],8326:[[54],256],8327:[[55],256],8328:[[56],256],8329:[[57],256],8330:[[43],256],8331:[[8722],256],8332:[[61],256],8333:[[40],256],8334:[[41],256],8336:[[97],256],8337:[[101],256],8338:[[111],256],8339:[[120],256],8340:[[601],256],8341:[[104],256],8342:[[107],256],8343:[[108],256],8344:[[109],256],8345:[[110],256],8346:[[112],256],8347:[[115],256],8348:[[116],256],8360:[[82,115],256],8400:[,230],8401:[,230],8402:[,1],8403:[,1],8404:[,230],8405:[,230],8406:[,230],8407:[,230],8408:[,1],8409:[,1],8410:[,1],8411:[,230],8412:[,230],8417:[,230],8421:[,1],8422:[,1],8423:[,230],8424:[,220],8425:[,230],8426:[,1],8427:[,1],8428:[,220],8429:[,220],8430:[,220],8431:[,220],8432:[,230]}, +8448:{8448:[[97,47,99],256],8449:[[97,47,115],256],8450:[[67],256],8451:[[176,67],256],8453:[[99,47,111],256],8454:[[99,47,117],256],8455:[[400],256],8457:[[176,70],256],8458:[[103],256],8459:[[72],256],8460:[[72],256],8461:[[72],256],8462:[[104],256],8463:[[295],256],8464:[[73],256],8465:[[73],256],8466:[[76],256],8467:[[108],256],8469:[[78],256],8470:[[78,111],256],8473:[[80],256],8474:[[81],256],8475:[[82],256],8476:[[82],256],8477:[[82],256],8480:[[83,77],256],8481:[[84,69,76],256],8482:[[84,77],256],8484:[[90],256],8486:[[937]],8488:[[90],256],8490:[[75]],8491:[[197]],8492:[[66],256],8493:[[67],256],8495:[[101],256],8496:[[69],256],8497:[[70],256],8499:[[77],256],8500:[[111],256],8501:[[1488],256],8502:[[1489],256],8503:[[1490],256],8504:[[1491],256],8505:[[105],256],8507:[[70,65,88],256],8508:[[960],256],8509:[[947],256],8510:[[915],256],8511:[[928],256],8512:[[8721],256],8517:[[68],256],8518:[[100],256],8519:[[101],256],8520:[[105],256],8521:[[106],256],8528:[[49,8260,55],256],8529:[[49,8260,57],256],8530:[[49,8260,49,48],256],8531:[[49,8260,51],256],8532:[[50,8260,51],256],8533:[[49,8260,53],256],8534:[[50,8260,53],256],8535:[[51,8260,53],256],8536:[[52,8260,53],256],8537:[[49,8260,54],256],8538:[[53,8260,54],256],8539:[[49,8260,56],256],8540:[[51,8260,56],256],8541:[[53,8260,56],256],8542:[[55,8260,56],256],8543:[[49,8260],256],8544:[[73],256],8545:[[73,73],256],8546:[[73,73,73],256],8547:[[73,86],256],8548:[[86],256],8549:[[86,73],256],8550:[[86,73,73],256],8551:[[86,73,73,73],256],8552:[[73,88],256],8553:[[88],256],8554:[[88,73],256],8555:[[88,73,73],256],8556:[[76],256],8557:[[67],256],8558:[[68],256],8559:[[77],256],8560:[[105],256],8561:[[105,105],256],8562:[[105,105,105],256],8563:[[105,118],256],8564:[[118],256],8565:[[118,105],256],8566:[[118,105,105],256],8567:[[118,105,105,105],256],8568:[[105,120],256],8569:[[120],256],8570:[[120,105],256],8571:[[120,105,105],256],8572:[[108],256],8573:[[99],256],8574:[[100],256],8575:[[109],256],8585:[[48,8260,51],256],8592:[,,{824:8602}],8594:[,,{824:8603}],8596:[,,{824:8622}],8602:[[8592,824]],8603:[[8594,824]],8622:[[8596,824]],8653:[[8656,824]],8654:[[8660,824]],8655:[[8658,824]],8656:[,,{824:8653}],8658:[,,{824:8655}],8660:[,,{824:8654}]}, +8704:{8707:[,,{824:8708}],8708:[[8707,824]],8712:[,,{824:8713}],8713:[[8712,824]],8715:[,,{824:8716}],8716:[[8715,824]],8739:[,,{824:8740}],8740:[[8739,824]],8741:[,,{824:8742}],8742:[[8741,824]],8748:[[8747,8747],256],8749:[[8747,8747,8747],256],8751:[[8750,8750],256],8752:[[8750,8750,8750],256],8764:[,,{824:8769}],8769:[[8764,824]],8771:[,,{824:8772}],8772:[[8771,824]],8773:[,,{824:8775}],8775:[[8773,824]],8776:[,,{824:8777}],8777:[[8776,824]],8781:[,,{824:8813}],8800:[[61,824]],8801:[,,{824:8802}],8802:[[8801,824]],8804:[,,{824:8816}],8805:[,,{824:8817}],8813:[[8781,824]],8814:[[60,824]],8815:[[62,824]],8816:[[8804,824]],8817:[[8805,824]],8818:[,,{824:8820}],8819:[,,{824:8821}],8820:[[8818,824]],8821:[[8819,824]],8822:[,,{824:8824}],8823:[,,{824:8825}],8824:[[8822,824]],8825:[[8823,824]],8826:[,,{824:8832}],8827:[,,{824:8833}],8828:[,,{824:8928}],8829:[,,{824:8929}],8832:[[8826,824]],8833:[[8827,824]],8834:[,,{824:8836}],8835:[,,{824:8837}],8836:[[8834,824]],8837:[[8835,824]],8838:[,,{824:8840}],8839:[,,{824:8841}],8840:[[8838,824]],8841:[[8839,824]],8849:[,,{824:8930}],8850:[,,{824:8931}],8866:[,,{824:8876}],8872:[,,{824:8877}],8873:[,,{824:8878}],8875:[,,{824:8879}],8876:[[8866,824]],8877:[[8872,824]],8878:[[8873,824]],8879:[[8875,824]],8882:[,,{824:8938}],8883:[,,{824:8939}],8884:[,,{824:8940}],8885:[,,{824:8941}],8928:[[8828,824]],8929:[[8829,824]],8930:[[8849,824]],8931:[[8850,824]],8938:[[8882,824]],8939:[[8883,824]],8940:[[8884,824]],8941:[[8885,824]]}, +8960:{9001:[[12296]],9002:[[12297]]}, +9216:{9312:[[49],256],9313:[[50],256],9314:[[51],256],9315:[[52],256],9316:[[53],256],9317:[[54],256],9318:[[55],256],9319:[[56],256],9320:[[57],256],9321:[[49,48],256],9322:[[49,49],256],9323:[[49,50],256],9324:[[49,51],256],9325:[[49,52],256],9326:[[49,53],256],9327:[[49,54],256],9328:[[49,55],256],9329:[[49,56],256],9330:[[49,57],256],9331:[[50,48],256],9332:[[40,49,41],256],9333:[[40,50,41],256],9334:[[40,51,41],256],9335:[[40,52,41],256],9336:[[40,53,41],256],9337:[[40,54,41],256],9338:[[40,55,41],256],9339:[[40,56,41],256],9340:[[40,57,41],256],9341:[[40,49,48,41],256],9342:[[40,49,49,41],256],9343:[[40,49,50,41],256],9344:[[40,49,51,41],256],9345:[[40,49,52,41],256],9346:[[40,49,53,41],256],9347:[[40,49,54,41],256],9348:[[40,49,55,41],256],9349:[[40,49,56,41],256],9350:[[40,49,57,41],256],9351:[[40,50,48,41],256],9352:[[49,46],256],9353:[[50,46],256],9354:[[51,46],256],9355:[[52,46],256],9356:[[53,46],256],9357:[[54,46],256],9358:[[55,46],256],9359:[[56,46],256],9360:[[57,46],256],9361:[[49,48,46],256],9362:[[49,49,46],256],9363:[[49,50,46],256],9364:[[49,51,46],256],9365:[[49,52,46],256],9366:[[49,53,46],256],9367:[[49,54,46],256],9368:[[49,55,46],256],9369:[[49,56,46],256],9370:[[49,57,46],256],9371:[[50,48,46],256],9372:[[40,97,41],256],9373:[[40,98,41],256],9374:[[40,99,41],256],9375:[[40,100,41],256],9376:[[40,101,41],256],9377:[[40,102,41],256],9378:[[40,103,41],256],9379:[[40,104,41],256],9380:[[40,105,41],256],9381:[[40,106,41],256],9382:[[40,107,41],256],9383:[[40,108,41],256],9384:[[40,109,41],256],9385:[[40,110,41],256],9386:[[40,111,41],256],9387:[[40,112,41],256],9388:[[40,113,41],256],9389:[[40,114,41],256],9390:[[40,115,41],256],9391:[[40,116,41],256],9392:[[40,117,41],256],9393:[[40,118,41],256],9394:[[40,119,41],256],9395:[[40,120,41],256],9396:[[40,121,41],256],9397:[[40,122,41],256],9398:[[65],256],9399:[[66],256],9400:[[67],256],9401:[[68],256],9402:[[69],256],9403:[[70],256],9404:[[71],256],9405:[[72],256],9406:[[73],256],9407:[[74],256],9408:[[75],256],9409:[[76],256],9410:[[77],256],9411:[[78],256],9412:[[79],256],9413:[[80],256],9414:[[81],256],9415:[[82],256],9416:[[83],256],9417:[[84],256],9418:[[85],256],9419:[[86],256],9420:[[87],256],9421:[[88],256],9422:[[89],256],9423:[[90],256],9424:[[97],256],9425:[[98],256],9426:[[99],256],9427:[[100],256],9428:[[101],256],9429:[[102],256],9430:[[103],256],9431:[[104],256],9432:[[105],256],9433:[[106],256],9434:[[107],256],9435:[[108],256],9436:[[109],256],9437:[[110],256],9438:[[111],256],9439:[[112],256],9440:[[113],256],9441:[[114],256],9442:[[115],256],9443:[[116],256],9444:[[117],256],9445:[[118],256],9446:[[119],256],9447:[[120],256],9448:[[121],256],9449:[[122],256],9450:[[48],256]}, +10752:{10764:[[8747,8747,8747,8747],256],10868:[[58,58,61],256],10869:[[61,61],256],10870:[[61,61,61],256],10972:[[10973,824],512]}, +11264:{11388:[[106],256],11389:[[86],256],11503:[,230],11504:[,230],11505:[,230]}, +11520:{11631:[[11617],256],11647:[,9],11744:[,230],11745:[,230],11746:[,230],11747:[,230],11748:[,230],11749:[,230],11750:[,230],11751:[,230],11752:[,230],11753:[,230],11754:[,230],11755:[,230],11756:[,230],11757:[,230],11758:[,230],11759:[,230],11760:[,230],11761:[,230],11762:[,230],11763:[,230],11764:[,230],11765:[,230],11766:[,230],11767:[,230],11768:[,230],11769:[,230],11770:[,230],11771:[,230],11772:[,230],11773:[,230],11774:[,230],11775:[,230]}, +11776:{11935:[[27597],256],12019:[[40863],256]}, +12032:{12032:[[19968],256],12033:[[20008],256],12034:[[20022],256],12035:[[20031],256],12036:[[20057],256],12037:[[20101],256],12038:[[20108],256],12039:[[20128],256],12040:[[20154],256],12041:[[20799],256],12042:[[20837],256],12043:[[20843],256],12044:[[20866],256],12045:[[20886],256],12046:[[20907],256],12047:[[20960],256],12048:[[20981],256],12049:[[20992],256],12050:[[21147],256],12051:[[21241],256],12052:[[21269],256],12053:[[21274],256],12054:[[21304],256],12055:[[21313],256],12056:[[21340],256],12057:[[21353],256],12058:[[21378],256],12059:[[21430],256],12060:[[21448],256],12061:[[21475],256],12062:[[22231],256],12063:[[22303],256],12064:[[22763],256],12065:[[22786],256],12066:[[22794],256],12067:[[22805],256],12068:[[22823],256],12069:[[22899],256],12070:[[23376],256],12071:[[23424],256],12072:[[23544],256],12073:[[23567],256],12074:[[23586],256],12075:[[23608],256],12076:[[23662],256],12077:[[23665],256],12078:[[24027],256],12079:[[24037],256],12080:[[24049],256],12081:[[24062],256],12082:[[24178],256],12083:[[24186],256],12084:[[24191],256],12085:[[24308],256],12086:[[24318],256],12087:[[24331],256],12088:[[24339],256],12089:[[24400],256],12090:[[24417],256],12091:[[24435],256],12092:[[24515],256],12093:[[25096],256],12094:[[25142],256],12095:[[25163],256],12096:[[25903],256],12097:[[25908],256],12098:[[25991],256],12099:[[26007],256],12100:[[26020],256],12101:[[26041],256],12102:[[26080],256],12103:[[26085],256],12104:[[26352],256],12105:[[26376],256],12106:[[26408],256],12107:[[27424],256],12108:[[27490],256],12109:[[27513],256],12110:[[27571],256],12111:[[27595],256],12112:[[27604],256],12113:[[27611],256],12114:[[27663],256],12115:[[27668],256],12116:[[27700],256],12117:[[28779],256],12118:[[29226],256],12119:[[29238],256],12120:[[29243],256],12121:[[29247],256],12122:[[29255],256],12123:[[29273],256],12124:[[29275],256],12125:[[29356],256],12126:[[29572],256],12127:[[29577],256],12128:[[29916],256],12129:[[29926],256],12130:[[29976],256],12131:[[29983],256],12132:[[29992],256],12133:[[30000],256],12134:[[30091],256],12135:[[30098],256],12136:[[30326],256],12137:[[30333],256],12138:[[30382],256],12139:[[30399],256],12140:[[30446],256],12141:[[30683],256],12142:[[30690],256],12143:[[30707],256],12144:[[31034],256],12145:[[31160],256],12146:[[31166],256],12147:[[31348],256],12148:[[31435],256],12149:[[31481],256],12150:[[31859],256],12151:[[31992],256],12152:[[32566],256],12153:[[32593],256],12154:[[32650],256],12155:[[32701],256],12156:[[32769],256],12157:[[32780],256],12158:[[32786],256],12159:[[32819],256],12160:[[32895],256],12161:[[32905],256],12162:[[33251],256],12163:[[33258],256],12164:[[33267],256],12165:[[33276],256],12166:[[33292],256],12167:[[33307],256],12168:[[33311],256],12169:[[33390],256],12170:[[33394],256],12171:[[33400],256],12172:[[34381],256],12173:[[34411],256],12174:[[34880],256],12175:[[34892],256],12176:[[34915],256],12177:[[35198],256],12178:[[35211],256],12179:[[35282],256],12180:[[35328],256],12181:[[35895],256],12182:[[35910],256],12183:[[35925],256],12184:[[35960],256],12185:[[35997],256],12186:[[36196],256],12187:[[36208],256],12188:[[36275],256],12189:[[36523],256],12190:[[36554],256],12191:[[36763],256],12192:[[36784],256],12193:[[36789],256],12194:[[37009],256],12195:[[37193],256],12196:[[37318],256],12197:[[37324],256],12198:[[37329],256],12199:[[38263],256],12200:[[38272],256],12201:[[38428],256],12202:[[38582],256],12203:[[38585],256],12204:[[38632],256],12205:[[38737],256],12206:[[38750],256],12207:[[38754],256],12208:[[38761],256],12209:[[38859],256],12210:[[38893],256],12211:[[38899],256],12212:[[38913],256],12213:[[39080],256],12214:[[39131],256],12215:[[39135],256],12216:[[39318],256],12217:[[39321],256],12218:[[39340],256],12219:[[39592],256],12220:[[39640],256],12221:[[39647],256],12222:[[39717],256],12223:[[39727],256],12224:[[39730],256],12225:[[39740],256],12226:[[39770],256],12227:[[40165],256],12228:[[40565],256],12229:[[40575],256],12230:[[40613],256],12231:[[40635],256],12232:[[40643],256],12233:[[40653],256],12234:[[40657],256],12235:[[40697],256],12236:[[40701],256],12237:[[40718],256],12238:[[40723],256],12239:[[40736],256],12240:[[40763],256],12241:[[40778],256],12242:[[40786],256],12243:[[40845],256],12244:[[40860],256],12245:[[40864],256]}, +12288:{12288:[[32],256],12330:[,218],12331:[,228],12332:[,232],12333:[,222],12334:[,224],12335:[,224],12342:[[12306],256],12344:[[21313],256],12345:[[21316],256],12346:[[21317],256],12358:[,,{12441:12436}],12363:[,,{12441:12364}],12364:[[12363,12441]],12365:[,,{12441:12366}],12366:[[12365,12441]],12367:[,,{12441:12368}],12368:[[12367,12441]],12369:[,,{12441:12370}],12370:[[12369,12441]],12371:[,,{12441:12372}],12372:[[12371,12441]],12373:[,,{12441:12374}],12374:[[12373,12441]],12375:[,,{12441:12376}],12376:[[12375,12441]],12377:[,,{12441:12378}],12378:[[12377,12441]],12379:[,,{12441:12380}],12380:[[12379,12441]],12381:[,,{12441:12382}],12382:[[12381,12441]],12383:[,,{12441:12384}],12384:[[12383,12441]],12385:[,,{12441:12386}],12386:[[12385,12441]],12388:[,,{12441:12389}],12389:[[12388,12441]],12390:[,,{12441:12391}],12391:[[12390,12441]],12392:[,,{12441:12393}],12393:[[12392,12441]],12399:[,,{12441:12400,12442:12401}],12400:[[12399,12441]],12401:[[12399,12442]],12402:[,,{12441:12403,12442:12404}],12403:[[12402,12441]],12404:[[12402,12442]],12405:[,,{12441:12406,12442:12407}],12406:[[12405,12441]],12407:[[12405,12442]],12408:[,,{12441:12409,12442:12410}],12409:[[12408,12441]],12410:[[12408,12442]],12411:[,,{12441:12412,12442:12413}],12412:[[12411,12441]],12413:[[12411,12442]],12436:[[12358,12441]],12441:[,8],12442:[,8],12443:[[32,12441],256],12444:[[32,12442],256],12445:[,,{12441:12446}],12446:[[12445,12441]],12447:[[12424,12426],256],12454:[,,{12441:12532}],12459:[,,{12441:12460}],12460:[[12459,12441]],12461:[,,{12441:12462}],12462:[[12461,12441]],12463:[,,{12441:12464}],12464:[[12463,12441]],12465:[,,{12441:12466}],12466:[[12465,12441]],12467:[,,{12441:12468}],12468:[[12467,12441]],12469:[,,{12441:12470}],12470:[[12469,12441]],12471:[,,{12441:12472}],12472:[[12471,12441]],12473:[,,{12441:12474}],12474:[[12473,12441]],12475:[,,{12441:12476}],12476:[[12475,12441]],12477:[,,{12441:12478}],12478:[[12477,12441]],12479:[,,{12441:12480}],12480:[[12479,12441]],12481:[,,{12441:12482}],12482:[[12481,12441]],12484:[,,{12441:12485}],12485:[[12484,12441]],12486:[,,{12441:12487}],12487:[[12486,12441]],12488:[,,{12441:12489}],12489:[[12488,12441]],12495:[,,{12441:12496,12442:12497}],12496:[[12495,12441]],12497:[[12495,12442]],12498:[,,{12441:12499,12442:12500}],12499:[[12498,12441]],12500:[[12498,12442]],12501:[,,{12441:12502,12442:12503}],12502:[[12501,12441]],12503:[[12501,12442]],12504:[,,{12441:12505,12442:12506}],12505:[[12504,12441]],12506:[[12504,12442]],12507:[,,{12441:12508,12442:12509}],12508:[[12507,12441]],12509:[[12507,12442]],12527:[,,{12441:12535}],12528:[,,{12441:12536}],12529:[,,{12441:12537}],12530:[,,{12441:12538}],12532:[[12454,12441]],12535:[[12527,12441]],12536:[[12528,12441]],12537:[[12529,12441]],12538:[[12530,12441]],12541:[,,{12441:12542}],12542:[[12541,12441]],12543:[[12467,12488],256]}, +12544:{12593:[[4352],256],12594:[[4353],256],12595:[[4522],256],12596:[[4354],256],12597:[[4524],256],12598:[[4525],256],12599:[[4355],256],12600:[[4356],256],12601:[[4357],256],12602:[[4528],256],12603:[[4529],256],12604:[[4530],256],12605:[[4531],256],12606:[[4532],256],12607:[[4533],256],12608:[[4378],256],12609:[[4358],256],12610:[[4359],256],12611:[[4360],256],12612:[[4385],256],12613:[[4361],256],12614:[[4362],256],12615:[[4363],256],12616:[[4364],256],12617:[[4365],256],12618:[[4366],256],12619:[[4367],256],12620:[[4368],256],12621:[[4369],256],12622:[[4370],256],12623:[[4449],256],12624:[[4450],256],12625:[[4451],256],12626:[[4452],256],12627:[[4453],256],12628:[[4454],256],12629:[[4455],256],12630:[[4456],256],12631:[[4457],256],12632:[[4458],256],12633:[[4459],256],12634:[[4460],256],12635:[[4461],256],12636:[[4462],256],12637:[[4463],256],12638:[[4464],256],12639:[[4465],256],12640:[[4466],256],12641:[[4467],256],12642:[[4468],256],12643:[[4469],256],12644:[[4448],256],12645:[[4372],256],12646:[[4373],256],12647:[[4551],256],12648:[[4552],256],12649:[[4556],256],12650:[[4558],256],12651:[[4563],256],12652:[[4567],256],12653:[[4569],256],12654:[[4380],256],12655:[[4573],256],12656:[[4575],256],12657:[[4381],256],12658:[[4382],256],12659:[[4384],256],12660:[[4386],256],12661:[[4387],256],12662:[[4391],256],12663:[[4393],256],12664:[[4395],256],12665:[[4396],256],12666:[[4397],256],12667:[[4398],256],12668:[[4399],256],12669:[[4402],256],12670:[[4406],256],12671:[[4416],256],12672:[[4423],256],12673:[[4428],256],12674:[[4593],256],12675:[[4594],256],12676:[[4439],256],12677:[[4440],256],12678:[[4441],256],12679:[[4484],256],12680:[[4485],256],12681:[[4488],256],12682:[[4497],256],12683:[[4498],256],12684:[[4500],256],12685:[[4510],256],12686:[[4513],256],12690:[[19968],256],12691:[[20108],256],12692:[[19977],256],12693:[[22235],256],12694:[[19978],256],12695:[[20013],256],12696:[[19979],256],12697:[[30002],256],12698:[[20057],256],12699:[[19993],256],12700:[[19969],256],12701:[[22825],256],12702:[[22320],256],12703:[[20154],256]}, +12800:{12800:[[40,4352,41],256],12801:[[40,4354,41],256],12802:[[40,4355,41],256],12803:[[40,4357,41],256],12804:[[40,4358,41],256],12805:[[40,4359,41],256],12806:[[40,4361,41],256],12807:[[40,4363,41],256],12808:[[40,4364,41],256],12809:[[40,4366,41],256],12810:[[40,4367,41],256],12811:[[40,4368,41],256],12812:[[40,4369,41],256],12813:[[40,4370,41],256],12814:[[40,4352,4449,41],256],12815:[[40,4354,4449,41],256],12816:[[40,4355,4449,41],256],12817:[[40,4357,4449,41],256],12818:[[40,4358,4449,41],256],12819:[[40,4359,4449,41],256],12820:[[40,4361,4449,41],256],12821:[[40,4363,4449,41],256],12822:[[40,4364,4449,41],256],12823:[[40,4366,4449,41],256],12824:[[40,4367,4449,41],256],12825:[[40,4368,4449,41],256],12826:[[40,4369,4449,41],256],12827:[[40,4370,4449,41],256],12828:[[40,4364,4462,41],256],12829:[[40,4363,4457,4364,4453,4523,41],256],12830:[[40,4363,4457,4370,4462,41],256],12832:[[40,19968,41],256],12833:[[40,20108,41],256],12834:[[40,19977,41],256],12835:[[40,22235,41],256],12836:[[40,20116,41],256],12837:[[40,20845,41],256],12838:[[40,19971,41],256],12839:[[40,20843,41],256],12840:[[40,20061,41],256],12841:[[40,21313,41],256],12842:[[40,26376,41],256],12843:[[40,28779,41],256],12844:[[40,27700,41],256],12845:[[40,26408,41],256],12846:[[40,37329,41],256],12847:[[40,22303,41],256],12848:[[40,26085,41],256],12849:[[40,26666,41],256],12850:[[40,26377,41],256],12851:[[40,31038,41],256],12852:[[40,21517,41],256],12853:[[40,29305,41],256],12854:[[40,36001,41],256],12855:[[40,31069,41],256],12856:[[40,21172,41],256],12857:[[40,20195,41],256],12858:[[40,21628,41],256],12859:[[40,23398,41],256],12860:[[40,30435,41],256],12861:[[40,20225,41],256],12862:[[40,36039,41],256],12863:[[40,21332,41],256],12864:[[40,31085,41],256],12865:[[40,20241,41],256],12866:[[40,33258,41],256],12867:[[40,33267,41],256],12868:[[21839],256],12869:[[24188],256],12870:[[25991],256],12871:[[31631],256],12880:[[80,84,69],256],12881:[[50,49],256],12882:[[50,50],256],12883:[[50,51],256],12884:[[50,52],256],12885:[[50,53],256],12886:[[50,54],256],12887:[[50,55],256],12888:[[50,56],256],12889:[[50,57],256],12890:[[51,48],256],12891:[[51,49],256],12892:[[51,50],256],12893:[[51,51],256],12894:[[51,52],256],12895:[[51,53],256],12896:[[4352],256],12897:[[4354],256],12898:[[4355],256],12899:[[4357],256],12900:[[4358],256],12901:[[4359],256],12902:[[4361],256],12903:[[4363],256],12904:[[4364],256],12905:[[4366],256],12906:[[4367],256],12907:[[4368],256],12908:[[4369],256],12909:[[4370],256],12910:[[4352,4449],256],12911:[[4354,4449],256],12912:[[4355,4449],256],12913:[[4357,4449],256],12914:[[4358,4449],256],12915:[[4359,4449],256],12916:[[4361,4449],256],12917:[[4363,4449],256],12918:[[4364,4449],256],12919:[[4366,4449],256],12920:[[4367,4449],256],12921:[[4368,4449],256],12922:[[4369,4449],256],12923:[[4370,4449],256],12924:[[4366,4449,4535,4352,4457],256],12925:[[4364,4462,4363,4468],256],12926:[[4363,4462],256],12928:[[19968],256],12929:[[20108],256],12930:[[19977],256],12931:[[22235],256],12932:[[20116],256],12933:[[20845],256],12934:[[19971],256],12935:[[20843],256],12936:[[20061],256],12937:[[21313],256],12938:[[26376],256],12939:[[28779],256],12940:[[27700],256],12941:[[26408],256],12942:[[37329],256],12943:[[22303],256],12944:[[26085],256],12945:[[26666],256],12946:[[26377],256],12947:[[31038],256],12948:[[21517],256],12949:[[29305],256],12950:[[36001],256],12951:[[31069],256],12952:[[21172],256],12953:[[31192],256],12954:[[30007],256],12955:[[22899],256],12956:[[36969],256],12957:[[20778],256],12958:[[21360],256],12959:[[27880],256],12960:[[38917],256],12961:[[20241],256],12962:[[20889],256],12963:[[27491],256],12964:[[19978],256],12965:[[20013],256],12966:[[19979],256],12967:[[24038],256],12968:[[21491],256],12969:[[21307],256],12970:[[23447],256],12971:[[23398],256],12972:[[30435],256],12973:[[20225],256],12974:[[36039],256],12975:[[21332],256],12976:[[22812],256],12977:[[51,54],256],12978:[[51,55],256],12979:[[51,56],256],12980:[[51,57],256],12981:[[52,48],256],12982:[[52,49],256],12983:[[52,50],256],12984:[[52,51],256],12985:[[52,52],256],12986:[[52,53],256],12987:[[52,54],256],12988:[[52,55],256],12989:[[52,56],256],12990:[[52,57],256],12991:[[53,48],256],12992:[[49,26376],256],12993:[[50,26376],256],12994:[[51,26376],256],12995:[[52,26376],256],12996:[[53,26376],256],12997:[[54,26376],256],12998:[[55,26376],256],12999:[[56,26376],256],13000:[[57,26376],256],13001:[[49,48,26376],256],13002:[[49,49,26376],256],13003:[[49,50,26376],256],13004:[[72,103],256],13005:[[101,114,103],256],13006:[[101,86],256],13007:[[76,84,68],256],13008:[[12450],256],13009:[[12452],256],13010:[[12454],256],13011:[[12456],256],13012:[[12458],256],13013:[[12459],256],13014:[[12461],256],13015:[[12463],256],13016:[[12465],256],13017:[[12467],256],13018:[[12469],256],13019:[[12471],256],13020:[[12473],256],13021:[[12475],256],13022:[[12477],256],13023:[[12479],256],13024:[[12481],256],13025:[[12484],256],13026:[[12486],256],13027:[[12488],256],13028:[[12490],256],13029:[[12491],256],13030:[[12492],256],13031:[[12493],256],13032:[[12494],256],13033:[[12495],256],13034:[[12498],256],13035:[[12501],256],13036:[[12504],256],13037:[[12507],256],13038:[[12510],256],13039:[[12511],256],13040:[[12512],256],13041:[[12513],256],13042:[[12514],256],13043:[[12516],256],13044:[[12518],256],13045:[[12520],256],13046:[[12521],256],13047:[[12522],256],13048:[[12523],256],13049:[[12524],256],13050:[[12525],256],13051:[[12527],256],13052:[[12528],256],13053:[[12529],256],13054:[[12530],256]}, +13056:{13056:[[12450,12497,12540,12488],256],13057:[[12450,12523,12501,12449],256],13058:[[12450,12531,12506,12450],256],13059:[[12450,12540,12523],256],13060:[[12452,12491,12531,12464],256],13061:[[12452,12531,12481],256],13062:[[12454,12457,12531],256],13063:[[12456,12473,12463,12540,12489],256],13064:[[12456,12540,12459,12540],256],13065:[[12458,12531,12473],256],13066:[[12458,12540,12512],256],13067:[[12459,12452,12522],256],13068:[[12459,12521,12483,12488],256],13069:[[12459,12525,12522,12540],256],13070:[[12460,12525,12531],256],13071:[[12460,12531,12510],256],13072:[[12462,12460],256],13073:[[12462,12491,12540],256],13074:[[12461,12517,12522,12540],256],13075:[[12462,12523,12480,12540],256],13076:[[12461,12525],256],13077:[[12461,12525,12464,12521,12512],256],13078:[[12461,12525,12513,12540,12488,12523],256],13079:[[12461,12525,12527,12483,12488],256],13080:[[12464,12521,12512],256],13081:[[12464,12521,12512,12488,12531],256],13082:[[12463,12523,12476,12452,12525],256],13083:[[12463,12525,12540,12493],256],13084:[[12465,12540,12473],256],13085:[[12467,12523,12490],256],13086:[[12467,12540,12509],256],13087:[[12469,12452,12463,12523],256],13088:[[12469,12531,12481,12540,12512],256],13089:[[12471,12522,12531,12464],256],13090:[[12475,12531,12481],256],13091:[[12475,12531,12488],256],13092:[[12480,12540,12473],256],13093:[[12487,12471],256],13094:[[12489,12523],256],13095:[[12488,12531],256],13096:[[12490,12494],256],13097:[[12494,12483,12488],256],13098:[[12495,12452,12484],256],13099:[[12497,12540,12475,12531,12488],256],13100:[[12497,12540,12484],256],13101:[[12496,12540,12524,12523],256],13102:[[12500,12450,12473,12488,12523],256],13103:[[12500,12463,12523],256],13104:[[12500,12467],256],13105:[[12499,12523],256],13106:[[12501,12449,12521,12483,12489],256],13107:[[12501,12451,12540,12488],256],13108:[[12502,12483,12471,12455,12523],256],13109:[[12501,12521,12531],256],13110:[[12504,12463,12479,12540,12523],256],13111:[[12506,12477],256],13112:[[12506,12491,12498],256],13113:[[12504,12523,12484],256],13114:[[12506,12531,12473],256],13115:[[12506,12540,12472],256],13116:[[12505,12540,12479],256],13117:[[12509,12452,12531,12488],256],13118:[[12508,12523,12488],256],13119:[[12507,12531],256],13120:[[12509,12531,12489],256],13121:[[12507,12540,12523],256],13122:[[12507,12540,12531],256],13123:[[12510,12452,12463,12525],256],13124:[[12510,12452,12523],256],13125:[[12510,12483,12495],256],13126:[[12510,12523,12463],256],13127:[[12510,12531,12471,12519,12531],256],13128:[[12511,12463,12525,12531],256],13129:[[12511,12522],256],13130:[[12511,12522,12496,12540,12523],256],13131:[[12513,12460],256],13132:[[12513,12460,12488,12531],256],13133:[[12513,12540,12488,12523],256],13134:[[12516,12540,12489],256],13135:[[12516,12540,12523],256],13136:[[12518,12450,12531],256],13137:[[12522,12483,12488,12523],256],13138:[[12522,12521],256],13139:[[12523,12500,12540],256],13140:[[12523,12540,12502,12523],256],13141:[[12524,12512],256],13142:[[12524,12531,12488,12466,12531],256],13143:[[12527,12483,12488],256],13144:[[48,28857],256],13145:[[49,28857],256],13146:[[50,28857],256],13147:[[51,28857],256],13148:[[52,28857],256],13149:[[53,28857],256],13150:[[54,28857],256],13151:[[55,28857],256],13152:[[56,28857],256],13153:[[57,28857],256],13154:[[49,48,28857],256],13155:[[49,49,28857],256],13156:[[49,50,28857],256],13157:[[49,51,28857],256],13158:[[49,52,28857],256],13159:[[49,53,28857],256],13160:[[49,54,28857],256],13161:[[49,55,28857],256],13162:[[49,56,28857],256],13163:[[49,57,28857],256],13164:[[50,48,28857],256],13165:[[50,49,28857],256],13166:[[50,50,28857],256],13167:[[50,51,28857],256],13168:[[50,52,28857],256],13169:[[104,80,97],256],13170:[[100,97],256],13171:[[65,85],256],13172:[[98,97,114],256],13173:[[111,86],256],13174:[[112,99],256],13175:[[100,109],256],13176:[[100,109,178],256],13177:[[100,109,179],256],13178:[[73,85],256],13179:[[24179,25104],256],13180:[[26157,21644],256],13181:[[22823,27491],256],13182:[[26126,27835],256],13183:[[26666,24335,20250,31038],256],13184:[[112,65],256],13185:[[110,65],256],13186:[[956,65],256],13187:[[109,65],256],13188:[[107,65],256],13189:[[75,66],256],13190:[[77,66],256],13191:[[71,66],256],13192:[[99,97,108],256],13193:[[107,99,97,108],256],13194:[[112,70],256],13195:[[110,70],256],13196:[[956,70],256],13197:[[956,103],256],13198:[[109,103],256],13199:[[107,103],256],13200:[[72,122],256],13201:[[107,72,122],256],13202:[[77,72,122],256],13203:[[71,72,122],256],13204:[[84,72,122],256],13205:[[956,8467],256],13206:[[109,8467],256],13207:[[100,8467],256],13208:[[107,8467],256],13209:[[102,109],256],13210:[[110,109],256],13211:[[956,109],256],13212:[[109,109],256],13213:[[99,109],256],13214:[[107,109],256],13215:[[109,109,178],256],13216:[[99,109,178],256],13217:[[109,178],256],13218:[[107,109,178],256],13219:[[109,109,179],256],13220:[[99,109,179],256],13221:[[109,179],256],13222:[[107,109,179],256],13223:[[109,8725,115],256],13224:[[109,8725,115,178],256],13225:[[80,97],256],13226:[[107,80,97],256],13227:[[77,80,97],256],13228:[[71,80,97],256],13229:[[114,97,100],256],13230:[[114,97,100,8725,115],256],13231:[[114,97,100,8725,115,178],256],13232:[[112,115],256],13233:[[110,115],256],13234:[[956,115],256],13235:[[109,115],256],13236:[[112,86],256],13237:[[110,86],256],13238:[[956,86],256],13239:[[109,86],256],13240:[[107,86],256],13241:[[77,86],256],13242:[[112,87],256],13243:[[110,87],256],13244:[[956,87],256],13245:[[109,87],256],13246:[[107,87],256],13247:[[77,87],256],13248:[[107,937],256],13249:[[77,937],256],13250:[[97,46,109,46],256],13251:[[66,113],256],13252:[[99,99],256],13253:[[99,100],256],13254:[[67,8725,107,103],256],13255:[[67,111,46],256],13256:[[100,66],256],13257:[[71,121],256],13258:[[104,97],256],13259:[[72,80],256],13260:[[105,110],256],13261:[[75,75],256],13262:[[75,77],256],13263:[[107,116],256],13264:[[108,109],256],13265:[[108,110],256],13266:[[108,111,103],256],13267:[[108,120],256],13268:[[109,98],256],13269:[[109,105,108],256],13270:[[109,111,108],256],13271:[[80,72],256],13272:[[112,46,109,46],256],13273:[[80,80,77],256],13274:[[80,82],256],13275:[[115,114],256],13276:[[83,118],256],13277:[[87,98],256],13278:[[86,8725,109],256],13279:[[65,8725,109],256],13280:[[49,26085],256],13281:[[50,26085],256],13282:[[51,26085],256],13283:[[52,26085],256],13284:[[53,26085],256],13285:[[54,26085],256],13286:[[55,26085],256],13287:[[56,26085],256],13288:[[57,26085],256],13289:[[49,48,26085],256],13290:[[49,49,26085],256],13291:[[49,50,26085],256],13292:[[49,51,26085],256],13293:[[49,52,26085],256],13294:[[49,53,26085],256],13295:[[49,54,26085],256],13296:[[49,55,26085],256],13297:[[49,56,26085],256],13298:[[49,57,26085],256],13299:[[50,48,26085],256],13300:[[50,49,26085],256],13301:[[50,50,26085],256],13302:[[50,51,26085],256],13303:[[50,52,26085],256],13304:[[50,53,26085],256],13305:[[50,54,26085],256],13306:[[50,55,26085],256],13307:[[50,56,26085],256],13308:[[50,57,26085],256],13309:[[51,48,26085],256],13310:[[51,49,26085],256],13311:[[103,97,108],256]}, +27136:{92912:[,1],92913:[,1],92914:[,1],92915:[,1],92916:[,1]}, +27392:{92976:[,230],92977:[,230],92978:[,230],92979:[,230],92980:[,230],92981:[,230],92982:[,230]}, +42496:{42607:[,230],42612:[,230],42613:[,230],42614:[,230],42615:[,230],42616:[,230],42617:[,230],42618:[,230],42619:[,230],42620:[,230],42621:[,230],42652:[[1098],256],42653:[[1100],256],42655:[,230],42736:[,230],42737:[,230]}, +42752:{42864:[[42863],256],43000:[[294],256],43001:[[339],256]}, +43008:{43014:[,9],43204:[,9],43232:[,230],43233:[,230],43234:[,230],43235:[,230],43236:[,230],43237:[,230],43238:[,230],43239:[,230],43240:[,230],43241:[,230],43242:[,230],43243:[,230],43244:[,230],43245:[,230],43246:[,230],43247:[,230],43248:[,230],43249:[,230]}, +43264:{43307:[,220],43308:[,220],43309:[,220],43347:[,9],43443:[,7],43456:[,9]}, +43520:{43696:[,230],43698:[,230],43699:[,230],43700:[,220],43703:[,230],43704:[,230],43710:[,230],43711:[,230],43713:[,230],43766:[,9]}, +43776:{43868:[[42791],256],43869:[[43831],256],43870:[[619],256],43871:[[43858],256],44013:[,9]}, +48128:{113822:[,1]}, +53504:{119134:[[119127,119141],512],119135:[[119128,119141],512],119136:[[119135,119150],512],119137:[[119135,119151],512],119138:[[119135,119152],512],119139:[[119135,119153],512],119140:[[119135,119154],512],119141:[,216],119142:[,216],119143:[,1],119144:[,1],119145:[,1],119149:[,226],119150:[,216],119151:[,216],119152:[,216],119153:[,216],119154:[,216],119163:[,220],119164:[,220],119165:[,220],119166:[,220],119167:[,220],119168:[,220],119169:[,220],119170:[,220],119173:[,230],119174:[,230],119175:[,230],119176:[,230],119177:[,230],119178:[,220],119179:[,220],119210:[,230],119211:[,230],119212:[,230],119213:[,230],119227:[[119225,119141],512],119228:[[119226,119141],512],119229:[[119227,119150],512],119230:[[119228,119150],512],119231:[[119227,119151],512],119232:[[119228,119151],512]}, +53760:{119362:[,230],119363:[,230],119364:[,230]}, +54272:{119808:[[65],256],119809:[[66],256],119810:[[67],256],119811:[[68],256],119812:[[69],256],119813:[[70],256],119814:[[71],256],119815:[[72],256],119816:[[73],256],119817:[[74],256],119818:[[75],256],119819:[[76],256],119820:[[77],256],119821:[[78],256],119822:[[79],256],119823:[[80],256],119824:[[81],256],119825:[[82],256],119826:[[83],256],119827:[[84],256],119828:[[85],256],119829:[[86],256],119830:[[87],256],119831:[[88],256],119832:[[89],256],119833:[[90],256],119834:[[97],256],119835:[[98],256],119836:[[99],256],119837:[[100],256],119838:[[101],256],119839:[[102],256],119840:[[103],256],119841:[[104],256],119842:[[105],256],119843:[[106],256],119844:[[107],256],119845:[[108],256],119846:[[109],256],119847:[[110],256],119848:[[111],256],119849:[[112],256],119850:[[113],256],119851:[[114],256],119852:[[115],256],119853:[[116],256],119854:[[117],256],119855:[[118],256],119856:[[119],256],119857:[[120],256],119858:[[121],256],119859:[[122],256],119860:[[65],256],119861:[[66],256],119862:[[67],256],119863:[[68],256],119864:[[69],256],119865:[[70],256],119866:[[71],256],119867:[[72],256],119868:[[73],256],119869:[[74],256],119870:[[75],256],119871:[[76],256],119872:[[77],256],119873:[[78],256],119874:[[79],256],119875:[[80],256],119876:[[81],256],119877:[[82],256],119878:[[83],256],119879:[[84],256],119880:[[85],256],119881:[[86],256],119882:[[87],256],119883:[[88],256],119884:[[89],256],119885:[[90],256],119886:[[97],256],119887:[[98],256],119888:[[99],256],119889:[[100],256],119890:[[101],256],119891:[[102],256],119892:[[103],256],119894:[[105],256],119895:[[106],256],119896:[[107],256],119897:[[108],256],119898:[[109],256],119899:[[110],256],119900:[[111],256],119901:[[112],256],119902:[[113],256],119903:[[114],256],119904:[[115],256],119905:[[116],256],119906:[[117],256],119907:[[118],256],119908:[[119],256],119909:[[120],256],119910:[[121],256],119911:[[122],256],119912:[[65],256],119913:[[66],256],119914:[[67],256],119915:[[68],256],119916:[[69],256],119917:[[70],256],119918:[[71],256],119919:[[72],256],119920:[[73],256],119921:[[74],256],119922:[[75],256],119923:[[76],256],119924:[[77],256],119925:[[78],256],119926:[[79],256],119927:[[80],256],119928:[[81],256],119929:[[82],256],119930:[[83],256],119931:[[84],256],119932:[[85],256],119933:[[86],256],119934:[[87],256],119935:[[88],256],119936:[[89],256],119937:[[90],256],119938:[[97],256],119939:[[98],256],119940:[[99],256],119941:[[100],256],119942:[[101],256],119943:[[102],256],119944:[[103],256],119945:[[104],256],119946:[[105],256],119947:[[106],256],119948:[[107],256],119949:[[108],256],119950:[[109],256],119951:[[110],256],119952:[[111],256],119953:[[112],256],119954:[[113],256],119955:[[114],256],119956:[[115],256],119957:[[116],256],119958:[[117],256],119959:[[118],256],119960:[[119],256],119961:[[120],256],119962:[[121],256],119963:[[122],256],119964:[[65],256],119966:[[67],256],119967:[[68],256],119970:[[71],256],119973:[[74],256],119974:[[75],256],119977:[[78],256],119978:[[79],256],119979:[[80],256],119980:[[81],256],119982:[[83],256],119983:[[84],256],119984:[[85],256],119985:[[86],256],119986:[[87],256],119987:[[88],256],119988:[[89],256],119989:[[90],256],119990:[[97],256],119991:[[98],256],119992:[[99],256],119993:[[100],256],119995:[[102],256],119997:[[104],256],119998:[[105],256],119999:[[106],256],120000:[[107],256],120001:[[108],256],120002:[[109],256],120003:[[110],256],120005:[[112],256],120006:[[113],256],120007:[[114],256],120008:[[115],256],120009:[[116],256],120010:[[117],256],120011:[[118],256],120012:[[119],256],120013:[[120],256],120014:[[121],256],120015:[[122],256],120016:[[65],256],120017:[[66],256],120018:[[67],256],120019:[[68],256],120020:[[69],256],120021:[[70],256],120022:[[71],256],120023:[[72],256],120024:[[73],256],120025:[[74],256],120026:[[75],256],120027:[[76],256],120028:[[77],256],120029:[[78],256],120030:[[79],256],120031:[[80],256],120032:[[81],256],120033:[[82],256],120034:[[83],256],120035:[[84],256],120036:[[85],256],120037:[[86],256],120038:[[87],256],120039:[[88],256],120040:[[89],256],120041:[[90],256],120042:[[97],256],120043:[[98],256],120044:[[99],256],120045:[[100],256],120046:[[101],256],120047:[[102],256],120048:[[103],256],120049:[[104],256],120050:[[105],256],120051:[[106],256],120052:[[107],256],120053:[[108],256],120054:[[109],256],120055:[[110],256],120056:[[111],256],120057:[[112],256],120058:[[113],256],120059:[[114],256],120060:[[115],256],120061:[[116],256],120062:[[117],256],120063:[[118],256]}, +54528:{120064:[[119],256],120065:[[120],256],120066:[[121],256],120067:[[122],256],120068:[[65],256],120069:[[66],256],120071:[[68],256],120072:[[69],256],120073:[[70],256],120074:[[71],256],120077:[[74],256],120078:[[75],256],120079:[[76],256],120080:[[77],256],120081:[[78],256],120082:[[79],256],120083:[[80],256],120084:[[81],256],120086:[[83],256],120087:[[84],256],120088:[[85],256],120089:[[86],256],120090:[[87],256],120091:[[88],256],120092:[[89],256],120094:[[97],256],120095:[[98],256],120096:[[99],256],120097:[[100],256],120098:[[101],256],120099:[[102],256],120100:[[103],256],120101:[[104],256],120102:[[105],256],120103:[[106],256],120104:[[107],256],120105:[[108],256],120106:[[109],256],120107:[[110],256],120108:[[111],256],120109:[[112],256],120110:[[113],256],120111:[[114],256],120112:[[115],256],120113:[[116],256],120114:[[117],256],120115:[[118],256],120116:[[119],256],120117:[[120],256],120118:[[121],256],120119:[[122],256],120120:[[65],256],120121:[[66],256],120123:[[68],256],120124:[[69],256],120125:[[70],256],120126:[[71],256],120128:[[73],256],120129:[[74],256],120130:[[75],256],120131:[[76],256],120132:[[77],256],120134:[[79],256],120138:[[83],256],120139:[[84],256],120140:[[85],256],120141:[[86],256],120142:[[87],256],120143:[[88],256],120144:[[89],256],120146:[[97],256],120147:[[98],256],120148:[[99],256],120149:[[100],256],120150:[[101],256],120151:[[102],256],120152:[[103],256],120153:[[104],256],120154:[[105],256],120155:[[106],256],120156:[[107],256],120157:[[108],256],120158:[[109],256],120159:[[110],256],120160:[[111],256],120161:[[112],256],120162:[[113],256],120163:[[114],256],120164:[[115],256],120165:[[116],256],120166:[[117],256],120167:[[118],256],120168:[[119],256],120169:[[120],256],120170:[[121],256],120171:[[122],256],120172:[[65],256],120173:[[66],256],120174:[[67],256],120175:[[68],256],120176:[[69],256],120177:[[70],256],120178:[[71],256],120179:[[72],256],120180:[[73],256],120181:[[74],256],120182:[[75],256],120183:[[76],256],120184:[[77],256],120185:[[78],256],120186:[[79],256],120187:[[80],256],120188:[[81],256],120189:[[82],256],120190:[[83],256],120191:[[84],256],120192:[[85],256],120193:[[86],256],120194:[[87],256],120195:[[88],256],120196:[[89],256],120197:[[90],256],120198:[[97],256],120199:[[98],256],120200:[[99],256],120201:[[100],256],120202:[[101],256],120203:[[102],256],120204:[[103],256],120205:[[104],256],120206:[[105],256],120207:[[106],256],120208:[[107],256],120209:[[108],256],120210:[[109],256],120211:[[110],256],120212:[[111],256],120213:[[112],256],120214:[[113],256],120215:[[114],256],120216:[[115],256],120217:[[116],256],120218:[[117],256],120219:[[118],256],120220:[[119],256],120221:[[120],256],120222:[[121],256],120223:[[122],256],120224:[[65],256],120225:[[66],256],120226:[[67],256],120227:[[68],256],120228:[[69],256],120229:[[70],256],120230:[[71],256],120231:[[72],256],120232:[[73],256],120233:[[74],256],120234:[[75],256],120235:[[76],256],120236:[[77],256],120237:[[78],256],120238:[[79],256],120239:[[80],256],120240:[[81],256],120241:[[82],256],120242:[[83],256],120243:[[84],256],120244:[[85],256],120245:[[86],256],120246:[[87],256],120247:[[88],256],120248:[[89],256],120249:[[90],256],120250:[[97],256],120251:[[98],256],120252:[[99],256],120253:[[100],256],120254:[[101],256],120255:[[102],256],120256:[[103],256],120257:[[104],256],120258:[[105],256],120259:[[106],256],120260:[[107],256],120261:[[108],256],120262:[[109],256],120263:[[110],256],120264:[[111],256],120265:[[112],256],120266:[[113],256],120267:[[114],256],120268:[[115],256],120269:[[116],256],120270:[[117],256],120271:[[118],256],120272:[[119],256],120273:[[120],256],120274:[[121],256],120275:[[122],256],120276:[[65],256],120277:[[66],256],120278:[[67],256],120279:[[68],256],120280:[[69],256],120281:[[70],256],120282:[[71],256],120283:[[72],256],120284:[[73],256],120285:[[74],256],120286:[[75],256],120287:[[76],256],120288:[[77],256],120289:[[78],256],120290:[[79],256],120291:[[80],256],120292:[[81],256],120293:[[82],256],120294:[[83],256],120295:[[84],256],120296:[[85],256],120297:[[86],256],120298:[[87],256],120299:[[88],256],120300:[[89],256],120301:[[90],256],120302:[[97],256],120303:[[98],256],120304:[[99],256],120305:[[100],256],120306:[[101],256],120307:[[102],256],120308:[[103],256],120309:[[104],256],120310:[[105],256],120311:[[106],256],120312:[[107],256],120313:[[108],256],120314:[[109],256],120315:[[110],256],120316:[[111],256],120317:[[112],256],120318:[[113],256],120319:[[114],256]}, +54784:{120320:[[115],256],120321:[[116],256],120322:[[117],256],120323:[[118],256],120324:[[119],256],120325:[[120],256],120326:[[121],256],120327:[[122],256],120328:[[65],256],120329:[[66],256],120330:[[67],256],120331:[[68],256],120332:[[69],256],120333:[[70],256],120334:[[71],256],120335:[[72],256],120336:[[73],256],120337:[[74],256],120338:[[75],256],120339:[[76],256],120340:[[77],256],120341:[[78],256],120342:[[79],256],120343:[[80],256],120344:[[81],256],120345:[[82],256],120346:[[83],256],120347:[[84],256],120348:[[85],256],120349:[[86],256],120350:[[87],256],120351:[[88],256],120352:[[89],256],120353:[[90],256],120354:[[97],256],120355:[[98],256],120356:[[99],256],120357:[[100],256],120358:[[101],256],120359:[[102],256],120360:[[103],256],120361:[[104],256],120362:[[105],256],120363:[[106],256],120364:[[107],256],120365:[[108],256],120366:[[109],256],120367:[[110],256],120368:[[111],256],120369:[[112],256],120370:[[113],256],120371:[[114],256],120372:[[115],256],120373:[[116],256],120374:[[117],256],120375:[[118],256],120376:[[119],256],120377:[[120],256],120378:[[121],256],120379:[[122],256],120380:[[65],256],120381:[[66],256],120382:[[67],256],120383:[[68],256],120384:[[69],256],120385:[[70],256],120386:[[71],256],120387:[[72],256],120388:[[73],256],120389:[[74],256],120390:[[75],256],120391:[[76],256],120392:[[77],256],120393:[[78],256],120394:[[79],256],120395:[[80],256],120396:[[81],256],120397:[[82],256],120398:[[83],256],120399:[[84],256],120400:[[85],256],120401:[[86],256],120402:[[87],256],120403:[[88],256],120404:[[89],256],120405:[[90],256],120406:[[97],256],120407:[[98],256],120408:[[99],256],120409:[[100],256],120410:[[101],256],120411:[[102],256],120412:[[103],256],120413:[[104],256],120414:[[105],256],120415:[[106],256],120416:[[107],256],120417:[[108],256],120418:[[109],256],120419:[[110],256],120420:[[111],256],120421:[[112],256],120422:[[113],256],120423:[[114],256],120424:[[115],256],120425:[[116],256],120426:[[117],256],120427:[[118],256],120428:[[119],256],120429:[[120],256],120430:[[121],256],120431:[[122],256],120432:[[65],256],120433:[[66],256],120434:[[67],256],120435:[[68],256],120436:[[69],256],120437:[[70],256],120438:[[71],256],120439:[[72],256],120440:[[73],256],120441:[[74],256],120442:[[75],256],120443:[[76],256],120444:[[77],256],120445:[[78],256],120446:[[79],256],120447:[[80],256],120448:[[81],256],120449:[[82],256],120450:[[83],256],120451:[[84],256],120452:[[85],256],120453:[[86],256],120454:[[87],256],120455:[[88],256],120456:[[89],256],120457:[[90],256],120458:[[97],256],120459:[[98],256],120460:[[99],256],120461:[[100],256],120462:[[101],256],120463:[[102],256],120464:[[103],256],120465:[[104],256],120466:[[105],256],120467:[[106],256],120468:[[107],256],120469:[[108],256],120470:[[109],256],120471:[[110],256],120472:[[111],256],120473:[[112],256],120474:[[113],256],120475:[[114],256],120476:[[115],256],120477:[[116],256],120478:[[117],256],120479:[[118],256],120480:[[119],256],120481:[[120],256],120482:[[121],256],120483:[[122],256],120484:[[305],256],120485:[[567],256],120488:[[913],256],120489:[[914],256],120490:[[915],256],120491:[[916],256],120492:[[917],256],120493:[[918],256],120494:[[919],256],120495:[[920],256],120496:[[921],256],120497:[[922],256],120498:[[923],256],120499:[[924],256],120500:[[925],256],120501:[[926],256],120502:[[927],256],120503:[[928],256],120504:[[929],256],120505:[[1012],256],120506:[[931],256],120507:[[932],256],120508:[[933],256],120509:[[934],256],120510:[[935],256],120511:[[936],256],120512:[[937],256],120513:[[8711],256],120514:[[945],256],120515:[[946],256],120516:[[947],256],120517:[[948],256],120518:[[949],256],120519:[[950],256],120520:[[951],256],120521:[[952],256],120522:[[953],256],120523:[[954],256],120524:[[955],256],120525:[[956],256],120526:[[957],256],120527:[[958],256],120528:[[959],256],120529:[[960],256],120530:[[961],256],120531:[[962],256],120532:[[963],256],120533:[[964],256],120534:[[965],256],120535:[[966],256],120536:[[967],256],120537:[[968],256],120538:[[969],256],120539:[[8706],256],120540:[[1013],256],120541:[[977],256],120542:[[1008],256],120543:[[981],256],120544:[[1009],256],120545:[[982],256],120546:[[913],256],120547:[[914],256],120548:[[915],256],120549:[[916],256],120550:[[917],256],120551:[[918],256],120552:[[919],256],120553:[[920],256],120554:[[921],256],120555:[[922],256],120556:[[923],256],120557:[[924],256],120558:[[925],256],120559:[[926],256],120560:[[927],256],120561:[[928],256],120562:[[929],256],120563:[[1012],256],120564:[[931],256],120565:[[932],256],120566:[[933],256],120567:[[934],256],120568:[[935],256],120569:[[936],256],120570:[[937],256],120571:[[8711],256],120572:[[945],256],120573:[[946],256],120574:[[947],256],120575:[[948],256]}, +55040:{120576:[[949],256],120577:[[950],256],120578:[[951],256],120579:[[952],256],120580:[[953],256],120581:[[954],256],120582:[[955],256],120583:[[956],256],120584:[[957],256],120585:[[958],256],120586:[[959],256],120587:[[960],256],120588:[[961],256],120589:[[962],256],120590:[[963],256],120591:[[964],256],120592:[[965],256],120593:[[966],256],120594:[[967],256],120595:[[968],256],120596:[[969],256],120597:[[8706],256],120598:[[1013],256],120599:[[977],256],120600:[[1008],256],120601:[[981],256],120602:[[1009],256],120603:[[982],256],120604:[[913],256],120605:[[914],256],120606:[[915],256],120607:[[916],256],120608:[[917],256],120609:[[918],256],120610:[[919],256],120611:[[920],256],120612:[[921],256],120613:[[922],256],120614:[[923],256],120615:[[924],256],120616:[[925],256],120617:[[926],256],120618:[[927],256],120619:[[928],256],120620:[[929],256],120621:[[1012],256],120622:[[931],256],120623:[[932],256],120624:[[933],256],120625:[[934],256],120626:[[935],256],120627:[[936],256],120628:[[937],256],120629:[[8711],256],120630:[[945],256],120631:[[946],256],120632:[[947],256],120633:[[948],256],120634:[[949],256],120635:[[950],256],120636:[[951],256],120637:[[952],256],120638:[[953],256],120639:[[954],256],120640:[[955],256],120641:[[956],256],120642:[[957],256],120643:[[958],256],120644:[[959],256],120645:[[960],256],120646:[[961],256],120647:[[962],256],120648:[[963],256],120649:[[964],256],120650:[[965],256],120651:[[966],256],120652:[[967],256],120653:[[968],256],120654:[[969],256],120655:[[8706],256],120656:[[1013],256],120657:[[977],256],120658:[[1008],256],120659:[[981],256],120660:[[1009],256],120661:[[982],256],120662:[[913],256],120663:[[914],256],120664:[[915],256],120665:[[916],256],120666:[[917],256],120667:[[918],256],120668:[[919],256],120669:[[920],256],120670:[[921],256],120671:[[922],256],120672:[[923],256],120673:[[924],256],120674:[[925],256],120675:[[926],256],120676:[[927],256],120677:[[928],256],120678:[[929],256],120679:[[1012],256],120680:[[931],256],120681:[[932],256],120682:[[933],256],120683:[[934],256],120684:[[935],256],120685:[[936],256],120686:[[937],256],120687:[[8711],256],120688:[[945],256],120689:[[946],256],120690:[[947],256],120691:[[948],256],120692:[[949],256],120693:[[950],256],120694:[[951],256],120695:[[952],256],120696:[[953],256],120697:[[954],256],120698:[[955],256],120699:[[956],256],120700:[[957],256],120701:[[958],256],120702:[[959],256],120703:[[960],256],120704:[[961],256],120705:[[962],256],120706:[[963],256],120707:[[964],256],120708:[[965],256],120709:[[966],256],120710:[[967],256],120711:[[968],256],120712:[[969],256],120713:[[8706],256],120714:[[1013],256],120715:[[977],256],120716:[[1008],256],120717:[[981],256],120718:[[1009],256],120719:[[982],256],120720:[[913],256],120721:[[914],256],120722:[[915],256],120723:[[916],256],120724:[[917],256],120725:[[918],256],120726:[[919],256],120727:[[920],256],120728:[[921],256],120729:[[922],256],120730:[[923],256],120731:[[924],256],120732:[[925],256],120733:[[926],256],120734:[[927],256],120735:[[928],256],120736:[[929],256],120737:[[1012],256],120738:[[931],256],120739:[[932],256],120740:[[933],256],120741:[[934],256],120742:[[935],256],120743:[[936],256],120744:[[937],256],120745:[[8711],256],120746:[[945],256],120747:[[946],256],120748:[[947],256],120749:[[948],256],120750:[[949],256],120751:[[950],256],120752:[[951],256],120753:[[952],256],120754:[[953],256],120755:[[954],256],120756:[[955],256],120757:[[956],256],120758:[[957],256],120759:[[958],256],120760:[[959],256],120761:[[960],256],120762:[[961],256],120763:[[962],256],120764:[[963],256],120765:[[964],256],120766:[[965],256],120767:[[966],256],120768:[[967],256],120769:[[968],256],120770:[[969],256],120771:[[8706],256],120772:[[1013],256],120773:[[977],256],120774:[[1008],256],120775:[[981],256],120776:[[1009],256],120777:[[982],256],120778:[[988],256],120779:[[989],256],120782:[[48],256],120783:[[49],256],120784:[[50],256],120785:[[51],256],120786:[[52],256],120787:[[53],256],120788:[[54],256],120789:[[55],256],120790:[[56],256],120791:[[57],256],120792:[[48],256],120793:[[49],256],120794:[[50],256],120795:[[51],256],120796:[[52],256],120797:[[53],256],120798:[[54],256],120799:[[55],256],120800:[[56],256],120801:[[57],256],120802:[[48],256],120803:[[49],256],120804:[[50],256],120805:[[51],256],120806:[[52],256],120807:[[53],256],120808:[[54],256],120809:[[55],256],120810:[[56],256],120811:[[57],256],120812:[[48],256],120813:[[49],256],120814:[[50],256],120815:[[51],256],120816:[[52],256],120817:[[53],256],120818:[[54],256],120819:[[55],256],120820:[[56],256],120821:[[57],256],120822:[[48],256],120823:[[49],256],120824:[[50],256],120825:[[51],256],120826:[[52],256],120827:[[53],256],120828:[[54],256],120829:[[55],256],120830:[[56],256],120831:[[57],256]}, +59392:{125136:[,220],125137:[,220],125138:[,220],125139:[,220],125140:[,220],125141:[,220],125142:[,220]}, +60928:{126464:[[1575],256],126465:[[1576],256],126466:[[1580],256],126467:[[1583],256],126469:[[1608],256],126470:[[1586],256],126471:[[1581],256],126472:[[1591],256],126473:[[1610],256],126474:[[1603],256],126475:[[1604],256],126476:[[1605],256],126477:[[1606],256],126478:[[1587],256],126479:[[1593],256],126480:[[1601],256],126481:[[1589],256],126482:[[1602],256],126483:[[1585],256],126484:[[1588],256],126485:[[1578],256],126486:[[1579],256],126487:[[1582],256],126488:[[1584],256],126489:[[1590],256],126490:[[1592],256],126491:[[1594],256],126492:[[1646],256],126493:[[1722],256],126494:[[1697],256],126495:[[1647],256],126497:[[1576],256],126498:[[1580],256],126500:[[1607],256],126503:[[1581],256],126505:[[1610],256],126506:[[1603],256],126507:[[1604],256],126508:[[1605],256],126509:[[1606],256],126510:[[1587],256],126511:[[1593],256],126512:[[1601],256],126513:[[1589],256],126514:[[1602],256],126516:[[1588],256],126517:[[1578],256],126518:[[1579],256],126519:[[1582],256],126521:[[1590],256],126523:[[1594],256],126530:[[1580],256],126535:[[1581],256],126537:[[1610],256],126539:[[1604],256],126541:[[1606],256],126542:[[1587],256],126543:[[1593],256],126545:[[1589],256],126546:[[1602],256],126548:[[1588],256],126551:[[1582],256],126553:[[1590],256],126555:[[1594],256],126557:[[1722],256],126559:[[1647],256],126561:[[1576],256],126562:[[1580],256],126564:[[1607],256],126567:[[1581],256],126568:[[1591],256],126569:[[1610],256],126570:[[1603],256],126572:[[1605],256],126573:[[1606],256],126574:[[1587],256],126575:[[1593],256],126576:[[1601],256],126577:[[1589],256],126578:[[1602],256],126580:[[1588],256],126581:[[1578],256],126582:[[1579],256],126583:[[1582],256],126585:[[1590],256],126586:[[1592],256],126587:[[1594],256],126588:[[1646],256],126590:[[1697],256],126592:[[1575],256],126593:[[1576],256],126594:[[1580],256],126595:[[1583],256],126596:[[1607],256],126597:[[1608],256],126598:[[1586],256],126599:[[1581],256],126600:[[1591],256],126601:[[1610],256],126603:[[1604],256],126604:[[1605],256],126605:[[1606],256],126606:[[1587],256],126607:[[1593],256],126608:[[1601],256],126609:[[1589],256],126610:[[1602],256],126611:[[1585],256],126612:[[1588],256],126613:[[1578],256],126614:[[1579],256],126615:[[1582],256],126616:[[1584],256],126617:[[1590],256],126618:[[1592],256],126619:[[1594],256],126625:[[1576],256],126626:[[1580],256],126627:[[1583],256],126629:[[1608],256],126630:[[1586],256],126631:[[1581],256],126632:[[1591],256],126633:[[1610],256],126635:[[1604],256],126636:[[1605],256],126637:[[1606],256],126638:[[1587],256],126639:[[1593],256],126640:[[1601],256],126641:[[1589],256],126642:[[1602],256],126643:[[1585],256],126644:[[1588],256],126645:[[1578],256],126646:[[1579],256],126647:[[1582],256],126648:[[1584],256],126649:[[1590],256],126650:[[1592],256],126651:[[1594],256]}, +61696:{127232:[[48,46],256],127233:[[48,44],256],127234:[[49,44],256],127235:[[50,44],256],127236:[[51,44],256],127237:[[52,44],256],127238:[[53,44],256],127239:[[54,44],256],127240:[[55,44],256],127241:[[56,44],256],127242:[[57,44],256],127248:[[40,65,41],256],127249:[[40,66,41],256],127250:[[40,67,41],256],127251:[[40,68,41],256],127252:[[40,69,41],256],127253:[[40,70,41],256],127254:[[40,71,41],256],127255:[[40,72,41],256],127256:[[40,73,41],256],127257:[[40,74,41],256],127258:[[40,75,41],256],127259:[[40,76,41],256],127260:[[40,77,41],256],127261:[[40,78,41],256],127262:[[40,79,41],256],127263:[[40,80,41],256],127264:[[40,81,41],256],127265:[[40,82,41],256],127266:[[40,83,41],256],127267:[[40,84,41],256],127268:[[40,85,41],256],127269:[[40,86,41],256],127270:[[40,87,41],256],127271:[[40,88,41],256],127272:[[40,89,41],256],127273:[[40,90,41],256],127274:[[12308,83,12309],256],127275:[[67],256],127276:[[82],256],127277:[[67,68],256],127278:[[87,90],256],127280:[[65],256],127281:[[66],256],127282:[[67],256],127283:[[68],256],127284:[[69],256],127285:[[70],256],127286:[[71],256],127287:[[72],256],127288:[[73],256],127289:[[74],256],127290:[[75],256],127291:[[76],256],127292:[[77],256],127293:[[78],256],127294:[[79],256],127295:[[80],256],127296:[[81],256],127297:[[82],256],127298:[[83],256],127299:[[84],256],127300:[[85],256],127301:[[86],256],127302:[[87],256],127303:[[88],256],127304:[[89],256],127305:[[90],256],127306:[[72,86],256],127307:[[77,86],256],127308:[[83,68],256],127309:[[83,83],256],127310:[[80,80,86],256],127311:[[87,67],256],127338:[[77,67],256],127339:[[77,68],256],127376:[[68,74],256]}, +61952:{127488:[[12411,12363],256],127489:[[12467,12467],256],127490:[[12469],256],127504:[[25163],256],127505:[[23383],256],127506:[[21452],256],127507:[[12487],256],127508:[[20108],256],127509:[[22810],256],127510:[[35299],256],127511:[[22825],256],127512:[[20132],256],127513:[[26144],256],127514:[[28961],256],127515:[[26009],256],127516:[[21069],256],127517:[[24460],256],127518:[[20877],256],127519:[[26032],256],127520:[[21021],256],127521:[[32066],256],127522:[[29983],256],127523:[[36009],256],127524:[[22768],256],127525:[[21561],256],127526:[[28436],256],127527:[[25237],256],127528:[[25429],256],127529:[[19968],256],127530:[[19977],256],127531:[[36938],256],127532:[[24038],256],127533:[[20013],256],127534:[[21491],256],127535:[[25351],256],127536:[[36208],256],127537:[[25171],256],127538:[[31105],256],127539:[[31354],256],127540:[[21512],256],127541:[[28288],256],127542:[[26377],256],127543:[[26376],256],127544:[[30003],256],127545:[[21106],256],127546:[[21942],256],127552:[[12308,26412,12309],256],127553:[[12308,19977,12309],256],127554:[[12308,20108,12309],256],127555:[[12308,23433,12309],256],127556:[[12308,28857,12309],256],127557:[[12308,25171,12309],256],127558:[[12308,30423,12309],256],127559:[[12308,21213,12309],256],127560:[[12308,25943,12309],256],127568:[[24471],256],127569:[[21487],256]}, +63488:{194560:[[20029]],194561:[[20024]],194562:[[20033]],194563:[[131362]],194564:[[20320]],194565:[[20398]],194566:[[20411]],194567:[[20482]],194568:[[20602]],194569:[[20633]],194570:[[20711]],194571:[[20687]],194572:[[13470]],194573:[[132666]],194574:[[20813]],194575:[[20820]],194576:[[20836]],194577:[[20855]],194578:[[132380]],194579:[[13497]],194580:[[20839]],194581:[[20877]],194582:[[132427]],194583:[[20887]],194584:[[20900]],194585:[[20172]],194586:[[20908]],194587:[[20917]],194588:[[168415]],194589:[[20981]],194590:[[20995]],194591:[[13535]],194592:[[21051]],194593:[[21062]],194594:[[21106]],194595:[[21111]],194596:[[13589]],194597:[[21191]],194598:[[21193]],194599:[[21220]],194600:[[21242]],194601:[[21253]],194602:[[21254]],194603:[[21271]],194604:[[21321]],194605:[[21329]],194606:[[21338]],194607:[[21363]],194608:[[21373]],194609:[[21375]],194610:[[21375]],194611:[[21375]],194612:[[133676]],194613:[[28784]],194614:[[21450]],194615:[[21471]],194616:[[133987]],194617:[[21483]],194618:[[21489]],194619:[[21510]],194620:[[21662]],194621:[[21560]],194622:[[21576]],194623:[[21608]],194624:[[21666]],194625:[[21750]],194626:[[21776]],194627:[[21843]],194628:[[21859]],194629:[[21892]],194630:[[21892]],194631:[[21913]],194632:[[21931]],194633:[[21939]],194634:[[21954]],194635:[[22294]],194636:[[22022]],194637:[[22295]],194638:[[22097]],194639:[[22132]],194640:[[20999]],194641:[[22766]],194642:[[22478]],194643:[[22516]],194644:[[22541]],194645:[[22411]],194646:[[22578]],194647:[[22577]],194648:[[22700]],194649:[[136420]],194650:[[22770]],194651:[[22775]],194652:[[22790]],194653:[[22810]],194654:[[22818]],194655:[[22882]],194656:[[136872]],194657:[[136938]],194658:[[23020]],194659:[[23067]],194660:[[23079]],194661:[[23000]],194662:[[23142]],194663:[[14062]],194664:[[14076]],194665:[[23304]],194666:[[23358]],194667:[[23358]],194668:[[137672]],194669:[[23491]],194670:[[23512]],194671:[[23527]],194672:[[23539]],194673:[[138008]],194674:[[23551]],194675:[[23558]],194676:[[24403]],194677:[[23586]],194678:[[14209]],194679:[[23648]],194680:[[23662]],194681:[[23744]],194682:[[23693]],194683:[[138724]],194684:[[23875]],194685:[[138726]],194686:[[23918]],194687:[[23915]],194688:[[23932]],194689:[[24033]],194690:[[24034]],194691:[[14383]],194692:[[24061]],194693:[[24104]],194694:[[24125]],194695:[[24169]],194696:[[14434]],194697:[[139651]],194698:[[14460]],194699:[[24240]],194700:[[24243]],194701:[[24246]],194702:[[24266]],194703:[[172946]],194704:[[24318]],194705:[[140081]],194706:[[140081]],194707:[[33281]],194708:[[24354]],194709:[[24354]],194710:[[14535]],194711:[[144056]],194712:[[156122]],194713:[[24418]],194714:[[24427]],194715:[[14563]],194716:[[24474]],194717:[[24525]],194718:[[24535]],194719:[[24569]],194720:[[24705]],194721:[[14650]],194722:[[14620]],194723:[[24724]],194724:[[141012]],194725:[[24775]],194726:[[24904]],194727:[[24908]],194728:[[24910]],194729:[[24908]],194730:[[24954]],194731:[[24974]],194732:[[25010]],194733:[[24996]],194734:[[25007]],194735:[[25054]],194736:[[25074]],194737:[[25078]],194738:[[25104]],194739:[[25115]],194740:[[25181]],194741:[[25265]],194742:[[25300]],194743:[[25424]],194744:[[142092]],194745:[[25405]],194746:[[25340]],194747:[[25448]],194748:[[25475]],194749:[[25572]],194750:[[142321]],194751:[[25634]],194752:[[25541]],194753:[[25513]],194754:[[14894]],194755:[[25705]],194756:[[25726]],194757:[[25757]],194758:[[25719]],194759:[[14956]],194760:[[25935]],194761:[[25964]],194762:[[143370]],194763:[[26083]],194764:[[26360]],194765:[[26185]],194766:[[15129]],194767:[[26257]],194768:[[15112]],194769:[[15076]],194770:[[20882]],194771:[[20885]],194772:[[26368]],194773:[[26268]],194774:[[32941]],194775:[[17369]],194776:[[26391]],194777:[[26395]],194778:[[26401]],194779:[[26462]],194780:[[26451]],194781:[[144323]],194782:[[15177]],194783:[[26618]],194784:[[26501]],194785:[[26706]],194786:[[26757]],194787:[[144493]],194788:[[26766]],194789:[[26655]],194790:[[26900]],194791:[[15261]],194792:[[26946]],194793:[[27043]],194794:[[27114]],194795:[[27304]],194796:[[145059]],194797:[[27355]],194798:[[15384]],194799:[[27425]],194800:[[145575]],194801:[[27476]],194802:[[15438]],194803:[[27506]],194804:[[27551]],194805:[[27578]],194806:[[27579]],194807:[[146061]],194808:[[138507]],194809:[[146170]],194810:[[27726]],194811:[[146620]],194812:[[27839]],194813:[[27853]],194814:[[27751]],194815:[[27926]]}, +63744:{63744:[[35912]],63745:[[26356]],63746:[[36554]],63747:[[36040]],63748:[[28369]],63749:[[20018]],63750:[[21477]],63751:[[40860]],63752:[[40860]],63753:[[22865]],63754:[[37329]],63755:[[21895]],63756:[[22856]],63757:[[25078]],63758:[[30313]],63759:[[32645]],63760:[[34367]],63761:[[34746]],63762:[[35064]],63763:[[37007]],63764:[[27138]],63765:[[27931]],63766:[[28889]],63767:[[29662]],63768:[[33853]],63769:[[37226]],63770:[[39409]],63771:[[20098]],63772:[[21365]],63773:[[27396]],63774:[[29211]],63775:[[34349]],63776:[[40478]],63777:[[23888]],63778:[[28651]],63779:[[34253]],63780:[[35172]],63781:[[25289]],63782:[[33240]],63783:[[34847]],63784:[[24266]],63785:[[26391]],63786:[[28010]],63787:[[29436]],63788:[[37070]],63789:[[20358]],63790:[[20919]],63791:[[21214]],63792:[[25796]],63793:[[27347]],63794:[[29200]],63795:[[30439]],63796:[[32769]],63797:[[34310]],63798:[[34396]],63799:[[36335]],63800:[[38706]],63801:[[39791]],63802:[[40442]],63803:[[30860]],63804:[[31103]],63805:[[32160]],63806:[[33737]],63807:[[37636]],63808:[[40575]],63809:[[35542]],63810:[[22751]],63811:[[24324]],63812:[[31840]],63813:[[32894]],63814:[[29282]],63815:[[30922]],63816:[[36034]],63817:[[38647]],63818:[[22744]],63819:[[23650]],63820:[[27155]],63821:[[28122]],63822:[[28431]],63823:[[32047]],63824:[[32311]],63825:[[38475]],63826:[[21202]],63827:[[32907]],63828:[[20956]],63829:[[20940]],63830:[[31260]],63831:[[32190]],63832:[[33777]],63833:[[38517]],63834:[[35712]],63835:[[25295]],63836:[[27138]],63837:[[35582]],63838:[[20025]],63839:[[23527]],63840:[[24594]],63841:[[29575]],63842:[[30064]],63843:[[21271]],63844:[[30971]],63845:[[20415]],63846:[[24489]],63847:[[19981]],63848:[[27852]],63849:[[25976]],63850:[[32034]],63851:[[21443]],63852:[[22622]],63853:[[30465]],63854:[[33865]],63855:[[35498]],63856:[[27578]],63857:[[36784]],63858:[[27784]],63859:[[25342]],63860:[[33509]],63861:[[25504]],63862:[[30053]],63863:[[20142]],63864:[[20841]],63865:[[20937]],63866:[[26753]],63867:[[31975]],63868:[[33391]],63869:[[35538]],63870:[[37327]],63871:[[21237]],63872:[[21570]],63873:[[22899]],63874:[[24300]],63875:[[26053]],63876:[[28670]],63877:[[31018]],63878:[[38317]],63879:[[39530]],63880:[[40599]],63881:[[40654]],63882:[[21147]],63883:[[26310]],63884:[[27511]],63885:[[36706]],63886:[[24180]],63887:[[24976]],63888:[[25088]],63889:[[25754]],63890:[[28451]],63891:[[29001]],63892:[[29833]],63893:[[31178]],63894:[[32244]],63895:[[32879]],63896:[[36646]],63897:[[34030]],63898:[[36899]],63899:[[37706]],63900:[[21015]],63901:[[21155]],63902:[[21693]],63903:[[28872]],63904:[[35010]],63905:[[35498]],63906:[[24265]],63907:[[24565]],63908:[[25467]],63909:[[27566]],63910:[[31806]],63911:[[29557]],63912:[[20196]],63913:[[22265]],63914:[[23527]],63915:[[23994]],63916:[[24604]],63917:[[29618]],63918:[[29801]],63919:[[32666]],63920:[[32838]],63921:[[37428]],63922:[[38646]],63923:[[38728]],63924:[[38936]],63925:[[20363]],63926:[[31150]],63927:[[37300]],63928:[[38584]],63929:[[24801]],63930:[[20102]],63931:[[20698]],63932:[[23534]],63933:[[23615]],63934:[[26009]],63935:[[27138]],63936:[[29134]],63937:[[30274]],63938:[[34044]],63939:[[36988]],63940:[[40845]],63941:[[26248]],63942:[[38446]],63943:[[21129]],63944:[[26491]],63945:[[26611]],63946:[[27969]],63947:[[28316]],63948:[[29705]],63949:[[30041]],63950:[[30827]],63951:[[32016]],63952:[[39006]],63953:[[20845]],63954:[[25134]],63955:[[38520]],63956:[[20523]],63957:[[23833]],63958:[[28138]],63959:[[36650]],63960:[[24459]],63961:[[24900]],63962:[[26647]],63963:[[29575]],63964:[[38534]],63965:[[21033]],63966:[[21519]],63967:[[23653]],63968:[[26131]],63969:[[26446]],63970:[[26792]],63971:[[27877]],63972:[[29702]],63973:[[30178]],63974:[[32633]],63975:[[35023]],63976:[[35041]],63977:[[37324]],63978:[[38626]],63979:[[21311]],63980:[[28346]],63981:[[21533]],63982:[[29136]],63983:[[29848]],63984:[[34298]],63985:[[38563]],63986:[[40023]],63987:[[40607]],63988:[[26519]],63989:[[28107]],63990:[[33256]],63991:[[31435]],63992:[[31520]],63993:[[31890]],63994:[[29376]],63995:[[28825]],63996:[[35672]],63997:[[20160]],63998:[[33590]],63999:[[21050]],194816:[[27966]],194817:[[28023]],194818:[[27969]],194819:[[28009]],194820:[[28024]],194821:[[28037]],194822:[[146718]],194823:[[27956]],194824:[[28207]],194825:[[28270]],194826:[[15667]],194827:[[28363]],194828:[[28359]],194829:[[147153]],194830:[[28153]],194831:[[28526]],194832:[[147294]],194833:[[147342]],194834:[[28614]],194835:[[28729]],194836:[[28702]],194837:[[28699]],194838:[[15766]],194839:[[28746]],194840:[[28797]],194841:[[28791]],194842:[[28845]],194843:[[132389]],194844:[[28997]],194845:[[148067]],194846:[[29084]],194847:[[148395]],194848:[[29224]],194849:[[29237]],194850:[[29264]],194851:[[149000]],194852:[[29312]],194853:[[29333]],194854:[[149301]],194855:[[149524]],194856:[[29562]],194857:[[29579]],194858:[[16044]],194859:[[29605]],194860:[[16056]],194861:[[16056]],194862:[[29767]],194863:[[29788]],194864:[[29809]],194865:[[29829]],194866:[[29898]],194867:[[16155]],194868:[[29988]],194869:[[150582]],194870:[[30014]],194871:[[150674]],194872:[[30064]],194873:[[139679]],194874:[[30224]],194875:[[151457]],194876:[[151480]],194877:[[151620]],194878:[[16380]],194879:[[16392]],194880:[[30452]],194881:[[151795]],194882:[[151794]],194883:[[151833]],194884:[[151859]],194885:[[30494]],194886:[[30495]],194887:[[30495]],194888:[[30538]],194889:[[16441]],194890:[[30603]],194891:[[16454]],194892:[[16534]],194893:[[152605]],194894:[[30798]],194895:[[30860]],194896:[[30924]],194897:[[16611]],194898:[[153126]],194899:[[31062]],194900:[[153242]],194901:[[153285]],194902:[[31119]],194903:[[31211]],194904:[[16687]],194905:[[31296]],194906:[[31306]],194907:[[31311]],194908:[[153980]],194909:[[154279]],194910:[[154279]],194911:[[31470]],194912:[[16898]],194913:[[154539]],194914:[[31686]],194915:[[31689]],194916:[[16935]],194917:[[154752]],194918:[[31954]],194919:[[17056]],194920:[[31976]],194921:[[31971]],194922:[[32000]],194923:[[155526]],194924:[[32099]],194925:[[17153]],194926:[[32199]],194927:[[32258]],194928:[[32325]],194929:[[17204]],194930:[[156200]],194931:[[156231]],194932:[[17241]],194933:[[156377]],194934:[[32634]],194935:[[156478]],194936:[[32661]],194937:[[32762]],194938:[[32773]],194939:[[156890]],194940:[[156963]],194941:[[32864]],194942:[[157096]],194943:[[32880]],194944:[[144223]],194945:[[17365]],194946:[[32946]],194947:[[33027]],194948:[[17419]],194949:[[33086]],194950:[[23221]],194951:[[157607]],194952:[[157621]],194953:[[144275]],194954:[[144284]],194955:[[33281]],194956:[[33284]],194957:[[36766]],194958:[[17515]],194959:[[33425]],194960:[[33419]],194961:[[33437]],194962:[[21171]],194963:[[33457]],194964:[[33459]],194965:[[33469]],194966:[[33510]],194967:[[158524]],194968:[[33509]],194969:[[33565]],194970:[[33635]],194971:[[33709]],194972:[[33571]],194973:[[33725]],194974:[[33767]],194975:[[33879]],194976:[[33619]],194977:[[33738]],194978:[[33740]],194979:[[33756]],194980:[[158774]],194981:[[159083]],194982:[[158933]],194983:[[17707]],194984:[[34033]],194985:[[34035]],194986:[[34070]],194987:[[160714]],194988:[[34148]],194989:[[159532]],194990:[[17757]],194991:[[17761]],194992:[[159665]],194993:[[159954]],194994:[[17771]],194995:[[34384]],194996:[[34396]],194997:[[34407]],194998:[[34409]],194999:[[34473]],195000:[[34440]],195001:[[34574]],195002:[[34530]],195003:[[34681]],195004:[[34600]],195005:[[34667]],195006:[[34694]],195007:[[17879]],195008:[[34785]],195009:[[34817]],195010:[[17913]],195011:[[34912]],195012:[[34915]],195013:[[161383]],195014:[[35031]],195015:[[35038]],195016:[[17973]],195017:[[35066]],195018:[[13499]],195019:[[161966]],195020:[[162150]],195021:[[18110]],195022:[[18119]],195023:[[35488]],195024:[[35565]],195025:[[35722]],195026:[[35925]],195027:[[162984]],195028:[[36011]],195029:[[36033]],195030:[[36123]],195031:[[36215]],195032:[[163631]],195033:[[133124]],195034:[[36299]],195035:[[36284]],195036:[[36336]],195037:[[133342]],195038:[[36564]],195039:[[36664]],195040:[[165330]],195041:[[165357]],195042:[[37012]],195043:[[37105]],195044:[[37137]],195045:[[165678]],195046:[[37147]],195047:[[37432]],195048:[[37591]],195049:[[37592]],195050:[[37500]],195051:[[37881]],195052:[[37909]],195053:[[166906]],195054:[[38283]],195055:[[18837]],195056:[[38327]],195057:[[167287]],195058:[[18918]],195059:[[38595]],195060:[[23986]],195061:[[38691]],195062:[[168261]],195063:[[168474]],195064:[[19054]],195065:[[19062]],195066:[[38880]],195067:[[168970]],195068:[[19122]],195069:[[169110]],195070:[[38923]],195071:[[38923]]}, +64000:{64000:[[20999]],64001:[[24230]],64002:[[25299]],64003:[[31958]],64004:[[23429]],64005:[[27934]],64006:[[26292]],64007:[[36667]],64008:[[34892]],64009:[[38477]],64010:[[35211]],64011:[[24275]],64012:[[20800]],64013:[[21952]],64016:[[22618]],64018:[[26228]],64021:[[20958]],64022:[[29482]],64023:[[30410]],64024:[[31036]],64025:[[31070]],64026:[[31077]],64027:[[31119]],64028:[[38742]],64029:[[31934]],64030:[[32701]],64032:[[34322]],64034:[[35576]],64037:[[36920]],64038:[[37117]],64042:[[39151]],64043:[[39164]],64044:[[39208]],64045:[[40372]],64046:[[37086]],64047:[[38583]],64048:[[20398]],64049:[[20711]],64050:[[20813]],64051:[[21193]],64052:[[21220]],64053:[[21329]],64054:[[21917]],64055:[[22022]],64056:[[22120]],64057:[[22592]],64058:[[22696]],64059:[[23652]],64060:[[23662]],64061:[[24724]],64062:[[24936]],64063:[[24974]],64064:[[25074]],64065:[[25935]],64066:[[26082]],64067:[[26257]],64068:[[26757]],64069:[[28023]],64070:[[28186]],64071:[[28450]],64072:[[29038]],64073:[[29227]],64074:[[29730]],64075:[[30865]],64076:[[31038]],64077:[[31049]],64078:[[31048]],64079:[[31056]],64080:[[31062]],64081:[[31069]],64082:[[31117]],64083:[[31118]],64084:[[31296]],64085:[[31361]],64086:[[31680]],64087:[[32244]],64088:[[32265]],64089:[[32321]],64090:[[32626]],64091:[[32773]],64092:[[33261]],64093:[[33401]],64094:[[33401]],64095:[[33879]],64096:[[35088]],64097:[[35222]],64098:[[35585]],64099:[[35641]],64100:[[36051]],64101:[[36104]],64102:[[36790]],64103:[[36920]],64104:[[38627]],64105:[[38911]],64106:[[38971]],64107:[[24693]],64108:[[148206]],64109:[[33304]],64112:[[20006]],64113:[[20917]],64114:[[20840]],64115:[[20352]],64116:[[20805]],64117:[[20864]],64118:[[21191]],64119:[[21242]],64120:[[21917]],64121:[[21845]],64122:[[21913]],64123:[[21986]],64124:[[22618]],64125:[[22707]],64126:[[22852]],64127:[[22868]],64128:[[23138]],64129:[[23336]],64130:[[24274]],64131:[[24281]],64132:[[24425]],64133:[[24493]],64134:[[24792]],64135:[[24910]],64136:[[24840]],64137:[[24974]],64138:[[24928]],64139:[[25074]],64140:[[25140]],64141:[[25540]],64142:[[25628]],64143:[[25682]],64144:[[25942]],64145:[[26228]],64146:[[26391]],64147:[[26395]],64148:[[26454]],64149:[[27513]],64150:[[27578]],64151:[[27969]],64152:[[28379]],64153:[[28363]],64154:[[28450]],64155:[[28702]],64156:[[29038]],64157:[[30631]],64158:[[29237]],64159:[[29359]],64160:[[29482]],64161:[[29809]],64162:[[29958]],64163:[[30011]],64164:[[30237]],64165:[[30239]],64166:[[30410]],64167:[[30427]],64168:[[30452]],64169:[[30538]],64170:[[30528]],64171:[[30924]],64172:[[31409]],64173:[[31680]],64174:[[31867]],64175:[[32091]],64176:[[32244]],64177:[[32574]],64178:[[32773]],64179:[[33618]],64180:[[33775]],64181:[[34681]],64182:[[35137]],64183:[[35206]],64184:[[35222]],64185:[[35519]],64186:[[35576]],64187:[[35531]],64188:[[35585]],64189:[[35582]],64190:[[35565]],64191:[[35641]],64192:[[35722]],64193:[[36104]],64194:[[36664]],64195:[[36978]],64196:[[37273]],64197:[[37494]],64198:[[38524]],64199:[[38627]],64200:[[38742]],64201:[[38875]],64202:[[38911]],64203:[[38923]],64204:[[38971]],64205:[[39698]],64206:[[40860]],64207:[[141386]],64208:[[141380]],64209:[[144341]],64210:[[15261]],64211:[[16408]],64212:[[16441]],64213:[[152137]],64214:[[154832]],64215:[[163539]],64216:[[40771]],64217:[[40846]],195072:[[38953]],195073:[[169398]],195074:[[39138]],195075:[[19251]],195076:[[39209]],195077:[[39335]],195078:[[39362]],195079:[[39422]],195080:[[19406]],195081:[[170800]],195082:[[39698]],195083:[[40000]],195084:[[40189]],195085:[[19662]],195086:[[19693]],195087:[[40295]],195088:[[172238]],195089:[[19704]],195090:[[172293]],195091:[[172558]],195092:[[172689]],195093:[[40635]],195094:[[19798]],195095:[[40697]],195096:[[40702]],195097:[[40709]],195098:[[40719]],195099:[[40726]],195100:[[40763]],195101:[[173568]]}, +64256:{64256:[[102,102],256],64257:[[102,105],256],64258:[[102,108],256],64259:[[102,102,105],256],64260:[[102,102,108],256],64261:[[383,116],256],64262:[[115,116],256],64275:[[1396,1398],256],64276:[[1396,1381],256],64277:[[1396,1387],256],64278:[[1406,1398],256],64279:[[1396,1389],256],64285:[[1497,1460],512],64286:[,26],64287:[[1522,1463],512],64288:[[1506],256],64289:[[1488],256],64290:[[1491],256],64291:[[1492],256],64292:[[1499],256],64293:[[1500],256],64294:[[1501],256],64295:[[1512],256],64296:[[1514],256],64297:[[43],256],64298:[[1513,1473],512],64299:[[1513,1474],512],64300:[[64329,1473],512],64301:[[64329,1474],512],64302:[[1488,1463],512],64303:[[1488,1464],512],64304:[[1488,1468],512],64305:[[1489,1468],512],64306:[[1490,1468],512],64307:[[1491,1468],512],64308:[[1492,1468],512],64309:[[1493,1468],512],64310:[[1494,1468],512],64312:[[1496,1468],512],64313:[[1497,1468],512],64314:[[1498,1468],512],64315:[[1499,1468],512],64316:[[1500,1468],512],64318:[[1502,1468],512],64320:[[1504,1468],512],64321:[[1505,1468],512],64323:[[1507,1468],512],64324:[[1508,1468],512],64326:[[1510,1468],512],64327:[[1511,1468],512],64328:[[1512,1468],512],64329:[[1513,1468],512],64330:[[1514,1468],512],64331:[[1493,1465],512],64332:[[1489,1471],512],64333:[[1499,1471],512],64334:[[1508,1471],512],64335:[[1488,1500],256],64336:[[1649],256],64337:[[1649],256],64338:[[1659],256],64339:[[1659],256],64340:[[1659],256],64341:[[1659],256],64342:[[1662],256],64343:[[1662],256],64344:[[1662],256],64345:[[1662],256],64346:[[1664],256],64347:[[1664],256],64348:[[1664],256],64349:[[1664],256],64350:[[1658],256],64351:[[1658],256],64352:[[1658],256],64353:[[1658],256],64354:[[1663],256],64355:[[1663],256],64356:[[1663],256],64357:[[1663],256],64358:[[1657],256],64359:[[1657],256],64360:[[1657],256],64361:[[1657],256],64362:[[1700],256],64363:[[1700],256],64364:[[1700],256],64365:[[1700],256],64366:[[1702],256],64367:[[1702],256],64368:[[1702],256],64369:[[1702],256],64370:[[1668],256],64371:[[1668],256],64372:[[1668],256],64373:[[1668],256],64374:[[1667],256],64375:[[1667],256],64376:[[1667],256],64377:[[1667],256],64378:[[1670],256],64379:[[1670],256],64380:[[1670],256],64381:[[1670],256],64382:[[1671],256],64383:[[1671],256],64384:[[1671],256],64385:[[1671],256],64386:[[1677],256],64387:[[1677],256],64388:[[1676],256],64389:[[1676],256],64390:[[1678],256],64391:[[1678],256],64392:[[1672],256],64393:[[1672],256],64394:[[1688],256],64395:[[1688],256],64396:[[1681],256],64397:[[1681],256],64398:[[1705],256],64399:[[1705],256],64400:[[1705],256],64401:[[1705],256],64402:[[1711],256],64403:[[1711],256],64404:[[1711],256],64405:[[1711],256],64406:[[1715],256],64407:[[1715],256],64408:[[1715],256],64409:[[1715],256],64410:[[1713],256],64411:[[1713],256],64412:[[1713],256],64413:[[1713],256],64414:[[1722],256],64415:[[1722],256],64416:[[1723],256],64417:[[1723],256],64418:[[1723],256],64419:[[1723],256],64420:[[1728],256],64421:[[1728],256],64422:[[1729],256],64423:[[1729],256],64424:[[1729],256],64425:[[1729],256],64426:[[1726],256],64427:[[1726],256],64428:[[1726],256],64429:[[1726],256],64430:[[1746],256],64431:[[1746],256],64432:[[1747],256],64433:[[1747],256],64467:[[1709],256],64468:[[1709],256],64469:[[1709],256],64470:[[1709],256],64471:[[1735],256],64472:[[1735],256],64473:[[1734],256],64474:[[1734],256],64475:[[1736],256],64476:[[1736],256],64477:[[1655],256],64478:[[1739],256],64479:[[1739],256],64480:[[1733],256],64481:[[1733],256],64482:[[1737],256],64483:[[1737],256],64484:[[1744],256],64485:[[1744],256],64486:[[1744],256],64487:[[1744],256],64488:[[1609],256],64489:[[1609],256],64490:[[1574,1575],256],64491:[[1574,1575],256],64492:[[1574,1749],256],64493:[[1574,1749],256],64494:[[1574,1608],256],64495:[[1574,1608],256],64496:[[1574,1735],256],64497:[[1574,1735],256],64498:[[1574,1734],256],64499:[[1574,1734],256],64500:[[1574,1736],256],64501:[[1574,1736],256],64502:[[1574,1744],256],64503:[[1574,1744],256],64504:[[1574,1744],256],64505:[[1574,1609],256],64506:[[1574,1609],256],64507:[[1574,1609],256],64508:[[1740],256],64509:[[1740],256],64510:[[1740],256],64511:[[1740],256]}, +64512:{64512:[[1574,1580],256],64513:[[1574,1581],256],64514:[[1574,1605],256],64515:[[1574,1609],256],64516:[[1574,1610],256],64517:[[1576,1580],256],64518:[[1576,1581],256],64519:[[1576,1582],256],64520:[[1576,1605],256],64521:[[1576,1609],256],64522:[[1576,1610],256],64523:[[1578,1580],256],64524:[[1578,1581],256],64525:[[1578,1582],256],64526:[[1578,1605],256],64527:[[1578,1609],256],64528:[[1578,1610],256],64529:[[1579,1580],256],64530:[[1579,1605],256],64531:[[1579,1609],256],64532:[[1579,1610],256],64533:[[1580,1581],256],64534:[[1580,1605],256],64535:[[1581,1580],256],64536:[[1581,1605],256],64537:[[1582,1580],256],64538:[[1582,1581],256],64539:[[1582,1605],256],64540:[[1587,1580],256],64541:[[1587,1581],256],64542:[[1587,1582],256],64543:[[1587,1605],256],64544:[[1589,1581],256],64545:[[1589,1605],256],64546:[[1590,1580],256],64547:[[1590,1581],256],64548:[[1590,1582],256],64549:[[1590,1605],256],64550:[[1591,1581],256],64551:[[1591,1605],256],64552:[[1592,1605],256],64553:[[1593,1580],256],64554:[[1593,1605],256],64555:[[1594,1580],256],64556:[[1594,1605],256],64557:[[1601,1580],256],64558:[[1601,1581],256],64559:[[1601,1582],256],64560:[[1601,1605],256],64561:[[1601,1609],256],64562:[[1601,1610],256],64563:[[1602,1581],256],64564:[[1602,1605],256],64565:[[1602,1609],256],64566:[[1602,1610],256],64567:[[1603,1575],256],64568:[[1603,1580],256],64569:[[1603,1581],256],64570:[[1603,1582],256],64571:[[1603,1604],256],64572:[[1603,1605],256],64573:[[1603,1609],256],64574:[[1603,1610],256],64575:[[1604,1580],256],64576:[[1604,1581],256],64577:[[1604,1582],256],64578:[[1604,1605],256],64579:[[1604,1609],256],64580:[[1604,1610],256],64581:[[1605,1580],256],64582:[[1605,1581],256],64583:[[1605,1582],256],64584:[[1605,1605],256],64585:[[1605,1609],256],64586:[[1605,1610],256],64587:[[1606,1580],256],64588:[[1606,1581],256],64589:[[1606,1582],256],64590:[[1606,1605],256],64591:[[1606,1609],256],64592:[[1606,1610],256],64593:[[1607,1580],256],64594:[[1607,1605],256],64595:[[1607,1609],256],64596:[[1607,1610],256],64597:[[1610,1580],256],64598:[[1610,1581],256],64599:[[1610,1582],256],64600:[[1610,1605],256],64601:[[1610,1609],256],64602:[[1610,1610],256],64603:[[1584,1648],256],64604:[[1585,1648],256],64605:[[1609,1648],256],64606:[[32,1612,1617],256],64607:[[32,1613,1617],256],64608:[[32,1614,1617],256],64609:[[32,1615,1617],256],64610:[[32,1616,1617],256],64611:[[32,1617,1648],256],64612:[[1574,1585],256],64613:[[1574,1586],256],64614:[[1574,1605],256],64615:[[1574,1606],256],64616:[[1574,1609],256],64617:[[1574,1610],256],64618:[[1576,1585],256],64619:[[1576,1586],256],64620:[[1576,1605],256],64621:[[1576,1606],256],64622:[[1576,1609],256],64623:[[1576,1610],256],64624:[[1578,1585],256],64625:[[1578,1586],256],64626:[[1578,1605],256],64627:[[1578,1606],256],64628:[[1578,1609],256],64629:[[1578,1610],256],64630:[[1579,1585],256],64631:[[1579,1586],256],64632:[[1579,1605],256],64633:[[1579,1606],256],64634:[[1579,1609],256],64635:[[1579,1610],256],64636:[[1601,1609],256],64637:[[1601,1610],256],64638:[[1602,1609],256],64639:[[1602,1610],256],64640:[[1603,1575],256],64641:[[1603,1604],256],64642:[[1603,1605],256],64643:[[1603,1609],256],64644:[[1603,1610],256],64645:[[1604,1605],256],64646:[[1604,1609],256],64647:[[1604,1610],256],64648:[[1605,1575],256],64649:[[1605,1605],256],64650:[[1606,1585],256],64651:[[1606,1586],256],64652:[[1606,1605],256],64653:[[1606,1606],256],64654:[[1606,1609],256],64655:[[1606,1610],256],64656:[[1609,1648],256],64657:[[1610,1585],256],64658:[[1610,1586],256],64659:[[1610,1605],256],64660:[[1610,1606],256],64661:[[1610,1609],256],64662:[[1610,1610],256],64663:[[1574,1580],256],64664:[[1574,1581],256],64665:[[1574,1582],256],64666:[[1574,1605],256],64667:[[1574,1607],256],64668:[[1576,1580],256],64669:[[1576,1581],256],64670:[[1576,1582],256],64671:[[1576,1605],256],64672:[[1576,1607],256],64673:[[1578,1580],256],64674:[[1578,1581],256],64675:[[1578,1582],256],64676:[[1578,1605],256],64677:[[1578,1607],256],64678:[[1579,1605],256],64679:[[1580,1581],256],64680:[[1580,1605],256],64681:[[1581,1580],256],64682:[[1581,1605],256],64683:[[1582,1580],256],64684:[[1582,1605],256],64685:[[1587,1580],256],64686:[[1587,1581],256],64687:[[1587,1582],256],64688:[[1587,1605],256],64689:[[1589,1581],256],64690:[[1589,1582],256],64691:[[1589,1605],256],64692:[[1590,1580],256],64693:[[1590,1581],256],64694:[[1590,1582],256],64695:[[1590,1605],256],64696:[[1591,1581],256],64697:[[1592,1605],256],64698:[[1593,1580],256],64699:[[1593,1605],256],64700:[[1594,1580],256],64701:[[1594,1605],256],64702:[[1601,1580],256],64703:[[1601,1581],256],64704:[[1601,1582],256],64705:[[1601,1605],256],64706:[[1602,1581],256],64707:[[1602,1605],256],64708:[[1603,1580],256],64709:[[1603,1581],256],64710:[[1603,1582],256],64711:[[1603,1604],256],64712:[[1603,1605],256],64713:[[1604,1580],256],64714:[[1604,1581],256],64715:[[1604,1582],256],64716:[[1604,1605],256],64717:[[1604,1607],256],64718:[[1605,1580],256],64719:[[1605,1581],256],64720:[[1605,1582],256],64721:[[1605,1605],256],64722:[[1606,1580],256],64723:[[1606,1581],256],64724:[[1606,1582],256],64725:[[1606,1605],256],64726:[[1606,1607],256],64727:[[1607,1580],256],64728:[[1607,1605],256],64729:[[1607,1648],256],64730:[[1610,1580],256],64731:[[1610,1581],256],64732:[[1610,1582],256],64733:[[1610,1605],256],64734:[[1610,1607],256],64735:[[1574,1605],256],64736:[[1574,1607],256],64737:[[1576,1605],256],64738:[[1576,1607],256],64739:[[1578,1605],256],64740:[[1578,1607],256],64741:[[1579,1605],256],64742:[[1579,1607],256],64743:[[1587,1605],256],64744:[[1587,1607],256],64745:[[1588,1605],256],64746:[[1588,1607],256],64747:[[1603,1604],256],64748:[[1603,1605],256],64749:[[1604,1605],256],64750:[[1606,1605],256],64751:[[1606,1607],256],64752:[[1610,1605],256],64753:[[1610,1607],256],64754:[[1600,1614,1617],256],64755:[[1600,1615,1617],256],64756:[[1600,1616,1617],256],64757:[[1591,1609],256],64758:[[1591,1610],256],64759:[[1593,1609],256],64760:[[1593,1610],256],64761:[[1594,1609],256],64762:[[1594,1610],256],64763:[[1587,1609],256],64764:[[1587,1610],256],64765:[[1588,1609],256],64766:[[1588,1610],256],64767:[[1581,1609],256]}, +64768:{64768:[[1581,1610],256],64769:[[1580,1609],256],64770:[[1580,1610],256],64771:[[1582,1609],256],64772:[[1582,1610],256],64773:[[1589,1609],256],64774:[[1589,1610],256],64775:[[1590,1609],256],64776:[[1590,1610],256],64777:[[1588,1580],256],64778:[[1588,1581],256],64779:[[1588,1582],256],64780:[[1588,1605],256],64781:[[1588,1585],256],64782:[[1587,1585],256],64783:[[1589,1585],256],64784:[[1590,1585],256],64785:[[1591,1609],256],64786:[[1591,1610],256],64787:[[1593,1609],256],64788:[[1593,1610],256],64789:[[1594,1609],256],64790:[[1594,1610],256],64791:[[1587,1609],256],64792:[[1587,1610],256],64793:[[1588,1609],256],64794:[[1588,1610],256],64795:[[1581,1609],256],64796:[[1581,1610],256],64797:[[1580,1609],256],64798:[[1580,1610],256],64799:[[1582,1609],256],64800:[[1582,1610],256],64801:[[1589,1609],256],64802:[[1589,1610],256],64803:[[1590,1609],256],64804:[[1590,1610],256],64805:[[1588,1580],256],64806:[[1588,1581],256],64807:[[1588,1582],256],64808:[[1588,1605],256],64809:[[1588,1585],256],64810:[[1587,1585],256],64811:[[1589,1585],256],64812:[[1590,1585],256],64813:[[1588,1580],256],64814:[[1588,1581],256],64815:[[1588,1582],256],64816:[[1588,1605],256],64817:[[1587,1607],256],64818:[[1588,1607],256],64819:[[1591,1605],256],64820:[[1587,1580],256],64821:[[1587,1581],256],64822:[[1587,1582],256],64823:[[1588,1580],256],64824:[[1588,1581],256],64825:[[1588,1582],256],64826:[[1591,1605],256],64827:[[1592,1605],256],64828:[[1575,1611],256],64829:[[1575,1611],256],64848:[[1578,1580,1605],256],64849:[[1578,1581,1580],256],64850:[[1578,1581,1580],256],64851:[[1578,1581,1605],256],64852:[[1578,1582,1605],256],64853:[[1578,1605,1580],256],64854:[[1578,1605,1581],256],64855:[[1578,1605,1582],256],64856:[[1580,1605,1581],256],64857:[[1580,1605,1581],256],64858:[[1581,1605,1610],256],64859:[[1581,1605,1609],256],64860:[[1587,1581,1580],256],64861:[[1587,1580,1581],256],64862:[[1587,1580,1609],256],64863:[[1587,1605,1581],256],64864:[[1587,1605,1581],256],64865:[[1587,1605,1580],256],64866:[[1587,1605,1605],256],64867:[[1587,1605,1605],256],64868:[[1589,1581,1581],256],64869:[[1589,1581,1581],256],64870:[[1589,1605,1605],256],64871:[[1588,1581,1605],256],64872:[[1588,1581,1605],256],64873:[[1588,1580,1610],256],64874:[[1588,1605,1582],256],64875:[[1588,1605,1582],256],64876:[[1588,1605,1605],256],64877:[[1588,1605,1605],256],64878:[[1590,1581,1609],256],64879:[[1590,1582,1605],256],64880:[[1590,1582,1605],256],64881:[[1591,1605,1581],256],64882:[[1591,1605,1581],256],64883:[[1591,1605,1605],256],64884:[[1591,1605,1610],256],64885:[[1593,1580,1605],256],64886:[[1593,1605,1605],256],64887:[[1593,1605,1605],256],64888:[[1593,1605,1609],256],64889:[[1594,1605,1605],256],64890:[[1594,1605,1610],256],64891:[[1594,1605,1609],256],64892:[[1601,1582,1605],256],64893:[[1601,1582,1605],256],64894:[[1602,1605,1581],256],64895:[[1602,1605,1605],256],64896:[[1604,1581,1605],256],64897:[[1604,1581,1610],256],64898:[[1604,1581,1609],256],64899:[[1604,1580,1580],256],64900:[[1604,1580,1580],256],64901:[[1604,1582,1605],256],64902:[[1604,1582,1605],256],64903:[[1604,1605,1581],256],64904:[[1604,1605,1581],256],64905:[[1605,1581,1580],256],64906:[[1605,1581,1605],256],64907:[[1605,1581,1610],256],64908:[[1605,1580,1581],256],64909:[[1605,1580,1605],256],64910:[[1605,1582,1580],256],64911:[[1605,1582,1605],256],64914:[[1605,1580,1582],256],64915:[[1607,1605,1580],256],64916:[[1607,1605,1605],256],64917:[[1606,1581,1605],256],64918:[[1606,1581,1609],256],64919:[[1606,1580,1605],256],64920:[[1606,1580,1605],256],64921:[[1606,1580,1609],256],64922:[[1606,1605,1610],256],64923:[[1606,1605,1609],256],64924:[[1610,1605,1605],256],64925:[[1610,1605,1605],256],64926:[[1576,1582,1610],256],64927:[[1578,1580,1610],256],64928:[[1578,1580,1609],256],64929:[[1578,1582,1610],256],64930:[[1578,1582,1609],256],64931:[[1578,1605,1610],256],64932:[[1578,1605,1609],256],64933:[[1580,1605,1610],256],64934:[[1580,1581,1609],256],64935:[[1580,1605,1609],256],64936:[[1587,1582,1609],256],64937:[[1589,1581,1610],256],64938:[[1588,1581,1610],256],64939:[[1590,1581,1610],256],64940:[[1604,1580,1610],256],64941:[[1604,1605,1610],256],64942:[[1610,1581,1610],256],64943:[[1610,1580,1610],256],64944:[[1610,1605,1610],256],64945:[[1605,1605,1610],256],64946:[[1602,1605,1610],256],64947:[[1606,1581,1610],256],64948:[[1602,1605,1581],256],64949:[[1604,1581,1605],256],64950:[[1593,1605,1610],256],64951:[[1603,1605,1610],256],64952:[[1606,1580,1581],256],64953:[[1605,1582,1610],256],64954:[[1604,1580,1605],256],64955:[[1603,1605,1605],256],64956:[[1604,1580,1605],256],64957:[[1606,1580,1581],256],64958:[[1580,1581,1610],256],64959:[[1581,1580,1610],256],64960:[[1605,1580,1610],256],64961:[[1601,1605,1610],256],64962:[[1576,1581,1610],256],64963:[[1603,1605,1605],256],64964:[[1593,1580,1605],256],64965:[[1589,1605,1605],256],64966:[[1587,1582,1610],256],64967:[[1606,1580,1610],256],65008:[[1589,1604,1746],256],65009:[[1602,1604,1746],256],65010:[[1575,1604,1604,1607],256],65011:[[1575,1603,1576,1585],256],65012:[[1605,1581,1605,1583],256],65013:[[1589,1604,1593,1605],256],65014:[[1585,1587,1608,1604],256],65015:[[1593,1604,1610,1607],256],65016:[[1608,1587,1604,1605],256],65017:[[1589,1604,1609],256],65018:[[1589,1604,1609,32,1575,1604,1604,1607,32,1593,1604,1610,1607,32,1608,1587,1604,1605],256],65019:[[1580,1604,32,1580,1604,1575,1604,1607],256],65020:[[1585,1740,1575,1604],256]}, +65024:{65040:[[44],256],65041:[[12289],256],65042:[[12290],256],65043:[[58],256],65044:[[59],256],65045:[[33],256],65046:[[63],256],65047:[[12310],256],65048:[[12311],256],65049:[[8230],256],65056:[,230],65057:[,230],65058:[,230],65059:[,230],65060:[,230],65061:[,230],65062:[,230],65063:[,220],65064:[,220],65065:[,220],65066:[,220],65067:[,220],65068:[,220],65069:[,220],65072:[[8229],256],65073:[[8212],256],65074:[[8211],256],65075:[[95],256],65076:[[95],256],65077:[[40],256],65078:[[41],256],65079:[[123],256],65080:[[125],256],65081:[[12308],256],65082:[[12309],256],65083:[[12304],256],65084:[[12305],256],65085:[[12298],256],65086:[[12299],256],65087:[[12296],256],65088:[[12297],256],65089:[[12300],256],65090:[[12301],256],65091:[[12302],256],65092:[[12303],256],65095:[[91],256],65096:[[93],256],65097:[[8254],256],65098:[[8254],256],65099:[[8254],256],65100:[[8254],256],65101:[[95],256],65102:[[95],256],65103:[[95],256],65104:[[44],256],65105:[[12289],256],65106:[[46],256],65108:[[59],256],65109:[[58],256],65110:[[63],256],65111:[[33],256],65112:[[8212],256],65113:[[40],256],65114:[[41],256],65115:[[123],256],65116:[[125],256],65117:[[12308],256],65118:[[12309],256],65119:[[35],256],65120:[[38],256],65121:[[42],256],65122:[[43],256],65123:[[45],256],65124:[[60],256],65125:[[62],256],65126:[[61],256],65128:[[92],256],65129:[[36],256],65130:[[37],256],65131:[[64],256],65136:[[32,1611],256],65137:[[1600,1611],256],65138:[[32,1612],256],65140:[[32,1613],256],65142:[[32,1614],256],65143:[[1600,1614],256],65144:[[32,1615],256],65145:[[1600,1615],256],65146:[[32,1616],256],65147:[[1600,1616],256],65148:[[32,1617],256],65149:[[1600,1617],256],65150:[[32,1618],256],65151:[[1600,1618],256],65152:[[1569],256],65153:[[1570],256],65154:[[1570],256],65155:[[1571],256],65156:[[1571],256],65157:[[1572],256],65158:[[1572],256],65159:[[1573],256],65160:[[1573],256],65161:[[1574],256],65162:[[1574],256],65163:[[1574],256],65164:[[1574],256],65165:[[1575],256],65166:[[1575],256],65167:[[1576],256],65168:[[1576],256],65169:[[1576],256],65170:[[1576],256],65171:[[1577],256],65172:[[1577],256],65173:[[1578],256],65174:[[1578],256],65175:[[1578],256],65176:[[1578],256],65177:[[1579],256],65178:[[1579],256],65179:[[1579],256],65180:[[1579],256],65181:[[1580],256],65182:[[1580],256],65183:[[1580],256],65184:[[1580],256],65185:[[1581],256],65186:[[1581],256],65187:[[1581],256],65188:[[1581],256],65189:[[1582],256],65190:[[1582],256],65191:[[1582],256],65192:[[1582],256],65193:[[1583],256],65194:[[1583],256],65195:[[1584],256],65196:[[1584],256],65197:[[1585],256],65198:[[1585],256],65199:[[1586],256],65200:[[1586],256],65201:[[1587],256],65202:[[1587],256],65203:[[1587],256],65204:[[1587],256],65205:[[1588],256],65206:[[1588],256],65207:[[1588],256],65208:[[1588],256],65209:[[1589],256],65210:[[1589],256],65211:[[1589],256],65212:[[1589],256],65213:[[1590],256],65214:[[1590],256],65215:[[1590],256],65216:[[1590],256],65217:[[1591],256],65218:[[1591],256],65219:[[1591],256],65220:[[1591],256],65221:[[1592],256],65222:[[1592],256],65223:[[1592],256],65224:[[1592],256],65225:[[1593],256],65226:[[1593],256],65227:[[1593],256],65228:[[1593],256],65229:[[1594],256],65230:[[1594],256],65231:[[1594],256],65232:[[1594],256],65233:[[1601],256],65234:[[1601],256],65235:[[1601],256],65236:[[1601],256],65237:[[1602],256],65238:[[1602],256],65239:[[1602],256],65240:[[1602],256],65241:[[1603],256],65242:[[1603],256],65243:[[1603],256],65244:[[1603],256],65245:[[1604],256],65246:[[1604],256],65247:[[1604],256],65248:[[1604],256],65249:[[1605],256],65250:[[1605],256],65251:[[1605],256],65252:[[1605],256],65253:[[1606],256],65254:[[1606],256],65255:[[1606],256],65256:[[1606],256],65257:[[1607],256],65258:[[1607],256],65259:[[1607],256],65260:[[1607],256],65261:[[1608],256],65262:[[1608],256],65263:[[1609],256],65264:[[1609],256],65265:[[1610],256],65266:[[1610],256],65267:[[1610],256],65268:[[1610],256],65269:[[1604,1570],256],65270:[[1604,1570],256],65271:[[1604,1571],256],65272:[[1604,1571],256],65273:[[1604,1573],256],65274:[[1604,1573],256],65275:[[1604,1575],256],65276:[[1604,1575],256]}, +65280:{65281:[[33],256],65282:[[34],256],65283:[[35],256],65284:[[36],256],65285:[[37],256],65286:[[38],256],65287:[[39],256],65288:[[40],256],65289:[[41],256],65290:[[42],256],65291:[[43],256],65292:[[44],256],65293:[[45],256],65294:[[46],256],65295:[[47],256],65296:[[48],256],65297:[[49],256],65298:[[50],256],65299:[[51],256],65300:[[52],256],65301:[[53],256],65302:[[54],256],65303:[[55],256],65304:[[56],256],65305:[[57],256],65306:[[58],256],65307:[[59],256],65308:[[60],256],65309:[[61],256],65310:[[62],256],65311:[[63],256],65312:[[64],256],65313:[[65],256],65314:[[66],256],65315:[[67],256],65316:[[68],256],65317:[[69],256],65318:[[70],256],65319:[[71],256],65320:[[72],256],65321:[[73],256],65322:[[74],256],65323:[[75],256],65324:[[76],256],65325:[[77],256],65326:[[78],256],65327:[[79],256],65328:[[80],256],65329:[[81],256],65330:[[82],256],65331:[[83],256],65332:[[84],256],65333:[[85],256],65334:[[86],256],65335:[[87],256],65336:[[88],256],65337:[[89],256],65338:[[90],256],65339:[[91],256],65340:[[92],256],65341:[[93],256],65342:[[94],256],65343:[[95],256],65344:[[96],256],65345:[[97],256],65346:[[98],256],65347:[[99],256],65348:[[100],256],65349:[[101],256],65350:[[102],256],65351:[[103],256],65352:[[104],256],65353:[[105],256],65354:[[106],256],65355:[[107],256],65356:[[108],256],65357:[[109],256],65358:[[110],256],65359:[[111],256],65360:[[112],256],65361:[[113],256],65362:[[114],256],65363:[[115],256],65364:[[116],256],65365:[[117],256],65366:[[118],256],65367:[[119],256],65368:[[120],256],65369:[[121],256],65370:[[122],256],65371:[[123],256],65372:[[124],256],65373:[[125],256],65374:[[126],256],65375:[[10629],256],65376:[[10630],256],65377:[[12290],256],65378:[[12300],256],65379:[[12301],256],65380:[[12289],256],65381:[[12539],256],65382:[[12530],256],65383:[[12449],256],65384:[[12451],256],65385:[[12453],256],65386:[[12455],256],65387:[[12457],256],65388:[[12515],256],65389:[[12517],256],65390:[[12519],256],65391:[[12483],256],65392:[[12540],256],65393:[[12450],256],65394:[[12452],256],65395:[[12454],256],65396:[[12456],256],65397:[[12458],256],65398:[[12459],256],65399:[[12461],256],65400:[[12463],256],65401:[[12465],256],65402:[[12467],256],65403:[[12469],256],65404:[[12471],256],65405:[[12473],256],65406:[[12475],256],65407:[[12477],256],65408:[[12479],256],65409:[[12481],256],65410:[[12484],256],65411:[[12486],256],65412:[[12488],256],65413:[[12490],256],65414:[[12491],256],65415:[[12492],256],65416:[[12493],256],65417:[[12494],256],65418:[[12495],256],65419:[[12498],256],65420:[[12501],256],65421:[[12504],256],65422:[[12507],256],65423:[[12510],256],65424:[[12511],256],65425:[[12512],256],65426:[[12513],256],65427:[[12514],256],65428:[[12516],256],65429:[[12518],256],65430:[[12520],256],65431:[[12521],256],65432:[[12522],256],65433:[[12523],256],65434:[[12524],256],65435:[[12525],256],65436:[[12527],256],65437:[[12531],256],65438:[[12441],256],65439:[[12442],256],65440:[[12644],256],65441:[[12593],256],65442:[[12594],256],65443:[[12595],256],65444:[[12596],256],65445:[[12597],256],65446:[[12598],256],65447:[[12599],256],65448:[[12600],256],65449:[[12601],256],65450:[[12602],256],65451:[[12603],256],65452:[[12604],256],65453:[[12605],256],65454:[[12606],256],65455:[[12607],256],65456:[[12608],256],65457:[[12609],256],65458:[[12610],256],65459:[[12611],256],65460:[[12612],256],65461:[[12613],256],65462:[[12614],256],65463:[[12615],256],65464:[[12616],256],65465:[[12617],256],65466:[[12618],256],65467:[[12619],256],65468:[[12620],256],65469:[[12621],256],65470:[[12622],256],65474:[[12623],256],65475:[[12624],256],65476:[[12625],256],65477:[[12626],256],65478:[[12627],256],65479:[[12628],256],65482:[[12629],256],65483:[[12630],256],65484:[[12631],256],65485:[[12632],256],65486:[[12633],256],65487:[[12634],256],65490:[[12635],256],65491:[[12636],256],65492:[[12637],256],65493:[[12638],256],65494:[[12639],256],65495:[[12640],256],65498:[[12641],256],65499:[[12642],256],65500:[[12643],256],65504:[[162],256],65505:[[163],256],65506:[[172],256],65507:[[175],256],65508:[[166],256],65509:[[165],256],65510:[[8361],256],65512:[[9474],256],65513:[[8592],256],65514:[[8593],256],65515:[[8594],256],65516:[[8595],256],65517:[[9632],256],65518:[[9675],256]} + +}; + + /***** Module to export */ + var unorm = { + nfc: nfc, + nfd: nfd, + nfkc: nfkc, + nfkd: nfkd + }; + + /*globals module:true,define:true*/ + + // CommonJS + if (typeof module === "object") { + module.exports = unorm; + + // AMD + } else if (typeof define === "function" && define.amd) { + define("unorm", function () { + return unorm; + }); + + // Global + } else { + root.unorm = unorm; + } + + /***** Export as shim for String::normalize method *****/ + /* + http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts#november_8_2013_draft_rev_21 + + 21.1.3.12 String.prototype.normalize(form="NFC") + When the normalize method is called with one argument form, the following steps are taken: + + 1. Let O be CheckObjectCoercible(this value). + 2. Let S be ToString(O). + 3. ReturnIfAbrupt(S). + 4. If form is not provided or undefined let form be "NFC". + 5. Let f be ToString(form). + 6. ReturnIfAbrupt(f). + 7. If f is not one of "NFC", "NFD", "NFKC", or "NFKD", then throw a RangeError Exception. + 8. Let ns be the String value is the result of normalizing S into the normalization form named by f as specified in Unicode Standard Annex #15, UnicodeNormalizatoin Forms. + 9. Return ns. + + The length property of the normalize method is 0. + + *NOTE* The normalize function is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method. + */ + unorm.shimApplied = false; + + if (!String.prototype.normalize) { + String.prototype.normalize = function(form) { + var str = "" + this; + form = form === undefined ? "NFC" : form; + + if (form === "NFC") { + return unorm.nfc(str); + } else if (form === "NFD") { + return unorm.nfd(str); + } else if (form === "NFKC") { + return unorm.nfkc(str); + } else if (form === "NFKD") { + return unorm.nfkd(str); + } else { + throw new RangeError("Invalid normalization form: " + form); + } + }; + + unorm.shimApplied = true; + } +}(this)); diff --git a/platforms/android/cordova/node_modules/unorm/package.json b/platforms/android/cordova/node_modules/unorm/package.json new file mode 100644 index 0000000..ca5fd67 --- /dev/null +++ b/platforms/android/cordova/node_modules/unorm/package.json @@ -0,0 +1,95 @@ +{ + "_args": [ + [ + "unorm@^1.3.3", + "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common" + ] + ], + "_from": "unorm@>=1.3.3 <2.0.0", + "_id": "unorm@1.4.1", + "_inCache": true, + "_installable": true, + "_location": "/unorm", + "_npmUser": { + "email": "bwp@bwp.dk", + "name": "walling" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "name": "unorm", + "raw": "unorm@^1.3.3", + "rawSpec": "^1.3.3", + "scope": null, + "spec": ">=1.3.3 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/cordova-common" + ], + "_resolved": "http://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz", + "_shasum": "364200d5f13646ca8bcd44490271335614792300", + "_shrinkwrap": null, + "_spec": "unorm@^1.3.3", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common", + "author": { + "email": "bwp@bwp.dk", + "name": "Bjarke Walling" + }, + "bugs": { + "url": "https://github.com/walling/unorm/issues" + }, + "contributors": [ + { + "name": "Bjarke Walling", + "email": "bwp@bwp.dk" + }, + { + "name": "Oleg Grenrus", + "email": "oleg.grenrus@iki.fi" + }, + { + "name": "Matsuza", + "email": "matsuza@gmail.com" + } + ], + "dependencies": {}, + "description": "JavaScript Unicode 8.0 Normalization - NFC, NFD, NFKC, NFKD. Read UAX #15 Unicode Normalization Forms.", + "devDependencies": { + "benchmark": "~1.0.0", + "grunt": "~0.4.1", + "grunt-contrib-jshint": "~0.8.0", + "grunt-contrib-watch": "~0.5.0", + "grunt-simple-mocha": "~0.4.0", + "unorm": "1.4.1" + }, + "directories": {}, + "dist": { + "shasum": "364200d5f13646ca8bcd44490271335614792300", + "tarball": "http://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz" + }, + "engines": { + "node": ">= 0.4.0" + }, + "gitHead": "e802d0d7844cf74b03742bce1147a82ace218396", + "homepage": "https://github.com/walling/unorm", + "license": "MIT or GPL-2.0", + "main": "./lib/unorm.js", + "maintainers": [ + { + "name": "walling", + "email": "bwp@bwp.dk" + } + ], + "name": "unorm", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/walling/unorm.git" + }, + "scripts": { + "test": "grunt test" + }, + "version": "1.4.1" +} diff --git a/platforms/android/cordova/node_modules/util-deprecate/History.md b/platforms/android/cordova/node_modules/util-deprecate/History.md new file mode 100644 index 0000000..acc8675 --- /dev/null +++ b/platforms/android/cordova/node_modules/util-deprecate/History.md @@ -0,0 +1,16 @@ + +1.0.2 / 2015-10-07 +================== + + * use try/catch when checking `localStorage` (#3, @kumavis) + +1.0.1 / 2014-11-25 +================== + + * browser: use `console.warn()` for deprecation calls + * browser: more jsdocs + +1.0.0 / 2014-04-30 +================== + + * initial commit diff --git a/platforms/android/cordova/node_modules/util-deprecate/LICENSE b/platforms/android/cordova/node_modules/util-deprecate/LICENSE new file mode 100644 index 0000000..6a60e8c --- /dev/null +++ b/platforms/android/cordova/node_modules/util-deprecate/LICENSE @@ -0,0 +1,24 @@ +(The MIT License) + +Copyright (c) 2014 Nathan Rajlich + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/cordova/node_modules/util-deprecate/README.md b/platforms/android/cordova/node_modules/util-deprecate/README.md new file mode 100644 index 0000000..75622fa --- /dev/null +++ b/platforms/android/cordova/node_modules/util-deprecate/README.md @@ -0,0 +1,53 @@ +util-deprecate +============== +### The Node.js `util.deprecate()` function with browser support + +In Node.js, this module simply re-exports the `util.deprecate()` function. + +In the web browser (i.e. via browserify), a browser-specific implementation +of the `util.deprecate()` function is used. + + +## API + +A `deprecate()` function is the only thing exposed by this module. + +``` javascript +// setup: +exports.foo = deprecate(foo, 'foo() is deprecated, use bar() instead'); + + +// users see: +foo(); +// foo() is deprecated, use bar() instead +foo(); +foo(); +``` + + +## License + +(The MIT License) + +Copyright (c) 2014 Nathan Rajlich + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/cordova/node_modules/util-deprecate/browser.js b/platforms/android/cordova/node_modules/util-deprecate/browser.js new file mode 100644 index 0000000..549ae2f --- /dev/null +++ b/platforms/android/cordova/node_modules/util-deprecate/browser.js @@ -0,0 +1,67 @@ + +/** + * Module exports. + */ + +module.exports = deprecate; + +/** + * Mark that a method should not be used. + * Returns a modified function which warns once by default. + * + * If `localStorage.noDeprecation = true` is set, then it is a no-op. + * + * If `localStorage.throwDeprecation = true` is set, then deprecated functions + * will throw an Error when invoked. + * + * If `localStorage.traceDeprecation = true` is set, then deprecated functions + * will invoke `console.trace()` instead of `console.error()`. + * + * @param {Function} fn - the function to deprecate + * @param {String} msg - the string to print to the console when `fn` is invoked + * @returns {Function} a new "deprecated" version of `fn` + * @api public + */ + +function deprecate (fn, msg) { + if (config('noDeprecation')) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (config('throwDeprecation')) { + throw new Error(msg); + } else if (config('traceDeprecation')) { + console.trace(msg); + } else { + console.warn(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +} + +/** + * Checks `localStorage` for boolean values for the given `name`. + * + * @param {String} name + * @returns {Boolean} + * @api private + */ + +function config (name) { + // accessing global.localStorage can trigger a DOMException in sandboxed iframes + try { + if (!global.localStorage) return false; + } catch (_) { + return false; + } + var val = global.localStorage[name]; + if (null == val) return false; + return String(val).toLowerCase() === 'true'; +} diff --git a/platforms/android/cordova/node_modules/util-deprecate/node.js b/platforms/android/cordova/node_modules/util-deprecate/node.js new file mode 100644 index 0000000..5e6fcff --- /dev/null +++ b/platforms/android/cordova/node_modules/util-deprecate/node.js @@ -0,0 +1,6 @@ + +/** + * For Node.js, simply re-export the core `util.deprecate` function. + */ + +module.exports = require('util').deprecate; diff --git a/platforms/android/cordova/node_modules/util-deprecate/package.json b/platforms/android/cordova/node_modules/util-deprecate/package.json new file mode 100644 index 0000000..4ad9893 --- /dev/null +++ b/platforms/android/cordova/node_modules/util-deprecate/package.json @@ -0,0 +1,81 @@ +{ + "_args": [ + [ + "util-deprecate@1.0.2", + "/Users/steveng/repo/cordova/cordova-android/node_modules/plist" + ] + ], + "_from": "util-deprecate@1.0.2", + "_id": "util-deprecate@1.0.2", + "_inCache": true, + "_installable": true, + "_location": "/util-deprecate", + "_nodeVersion": "4.1.2", + "_npmUser": { + "email": "nathan@tootallnate.net", + "name": "tootallnate" + }, + "_npmVersion": "2.14.4", + "_phantomChildren": {}, + "_requested": { + "name": "util-deprecate", + "raw": "util-deprecate@1.0.2", + "rawSpec": "1.0.2", + "scope": null, + "spec": "1.0.2", + "type": "version" + }, + "_requiredBy": [ + "/plist" + ], + "_resolved": "http://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "_shasum": "450d4dc9fa70de732762fbd2d4a28981419a0ccf", + "_shrinkwrap": null, + "_spec": "util-deprecate@1.0.2", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/plist", + "author": { + "email": "nathan@tootallnate.net", + "name": "Nathan Rajlich", + "url": "http://n8.io/" + }, + "browser": "browser.js", + "bugs": { + "url": "https://github.com/TooTallNate/util-deprecate/issues" + }, + "dependencies": {}, + "description": "The Node.js `util.deprecate()` function with browser support", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "450d4dc9fa70de732762fbd2d4a28981419a0ccf", + "tarball": "http://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + }, + "gitHead": "475fb6857cd23fafff20c1be846c1350abf8e6d4", + "homepage": "https://github.com/TooTallNate/util-deprecate", + "keywords": [ + "browser", + "browserify", + "deprecate", + "node", + "util" + ], + "license": "MIT", + "main": "node.js", + "maintainers": [ + { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + } + ], + "name": "util-deprecate", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/TooTallNate/util-deprecate.git" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "version": "1.0.2" +} diff --git a/platforms/android/cordova/node_modules/which/README.md b/platforms/android/cordova/node_modules/which/README.md deleted file mode 100644 index ff1eb53..0000000 --- a/platforms/android/cordova/node_modules/which/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The "which" util from npm's guts. - -Finds the first instance of a specified executable in the PATH -environment variable. Does not cache the results, so `hash -r` is not -needed when the PATH changes. diff --git a/platforms/android/cordova/node_modules/which/bin/which b/platforms/android/cordova/node_modules/which/bin/which deleted file mode 100755 index 8432ce2..0000000 --- a/platforms/android/cordova/node_modules/which/bin/which +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env node -var which = require("../") -if (process.argv.length < 3) { - console.error("Usage: which ") - process.exit(1) -} - -which(process.argv[2], function (er, thing) { - if (er) { - console.error(er.message) - process.exit(er.errno || 127) - } - console.log(thing) -}) diff --git a/platforms/android/cordova/node_modules/which/package.json b/platforms/android/cordova/node_modules/which/package.json deleted file mode 100644 index 6c5ccb3..0000000 --- a/platforms/android/cordova/node_modules/which/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "author": { - "name": "Isaac Z. Schlueter", - "email": "i@izs.me", - "url": "http://blog.izs.me" - }, - "name": "which", - "description": "Like which(1) unix command. Find the first instance of an executable in the PATH.", - "version": "1.0.5", - "repository": { - "type": "git", - "url": "git://github.com/isaacs/node-which.git" - }, - "main": "which.js", - "bin": { - "which": "./bin/which" - }, - "engines": { - "node": "*" - }, - "dependencies": {}, - "devDependencies": {}, - "readme": "The \"which\" util from npm's guts.\n\nFinds the first instance of a specified executable in the PATH\nenvironment variable. Does not cache the results, so `hash -r` is not\nneeded when the PATH changes.\n", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/isaacs/node-which/issues" - }, - "homepage": "https://github.com/isaacs/node-which", - "_id": "which@1.0.5", - "_from": "which@" -} diff --git a/platforms/android/cordova/node_modules/which/which.js b/platforms/android/cordova/node_modules/which/which.js deleted file mode 100644 index db7e8f7..0000000 --- a/platforms/android/cordova/node_modules/which/which.js +++ /dev/null @@ -1,104 +0,0 @@ -module.exports = which -which.sync = whichSync - -var path = require("path") - , fs - , COLON = process.platform === "win32" ? ";" : ":" - , isExe - -try { - fs = require("graceful-fs") -} catch (ex) { - fs = require("fs") -} - -if (process.platform == "win32") { - // On windows, there is no good way to check that a file is executable - isExe = function isExe () { return true } -} else { - isExe = function isExe (mod, uid, gid) { - //console.error(mod, uid, gid); - //console.error("isExe?", (mod & 0111).toString(8)) - var ret = (mod & 0001) - || (mod & 0010) && process.getgid && gid === process.getgid() - || (mod & 0100) && process.getuid && uid === process.getuid() - //console.error("isExe?", ret) - return ret - } -} - - - -function which (cmd, cb) { - if (isAbsolute(cmd)) return cb(null, cmd) - var pathEnv = (process.env.PATH || "").split(COLON) - , pathExt = [""] - if (process.platform === "win32") { - pathEnv.push(process.cwd()) - pathExt = (process.env.PATHEXT || ".EXE").split(COLON) - if (cmd.indexOf(".") !== -1) pathExt.unshift("") - } - //console.error("pathEnv", pathEnv) - ;(function F (i, l) { - if (i === l) return cb(new Error("not found: "+cmd)) - var p = path.resolve(pathEnv[i], cmd) - ;(function E (ii, ll) { - if (ii === ll) return F(i + 1, l) - var ext = pathExt[ii] - //console.error(p + ext) - fs.stat(p + ext, function (er, stat) { - if (!er && - stat && - stat.isFile() && - isExe(stat.mode, stat.uid, stat.gid)) { - //console.error("yes, exe!", p + ext) - return cb(null, p + ext) - } - return E(ii + 1, ll) - }) - })(0, pathExt.length) - })(0, pathEnv.length) -} - -function whichSync (cmd) { - if (isAbsolute(cmd)) return cmd - var pathEnv = (process.env.PATH || "").split(COLON) - , pathExt = [""] - if (process.platform === "win32") { - pathEnv.push(process.cwd()) - pathExt = (process.env.PATHEXT || ".EXE").split(COLON) - if (cmd.indexOf(".") !== -1) pathExt.unshift("") - } - for (var i = 0, l = pathEnv.length; i < l; i ++) { - var p = path.join(pathEnv[i], cmd) - for (var j = 0, ll = pathExt.length; j < ll; j ++) { - var cur = p + pathExt[j] - var stat - try { stat = fs.statSync(cur) } catch (ex) {} - if (stat && - stat.isFile() && - isExe(stat.mode, stat.uid, stat.gid)) return cur - } - } - throw new Error("not found: "+cmd) -} - -var isAbsolute = process.platform === "win32" ? absWin : absUnix - -function absWin (p) { - if (absUnix(p)) return true - // pull off the device/UNC bit from a windows path. - // from node's lib/path.js - var splitDeviceRe = - /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?/ - , result = splitDeviceRe.exec(p) - , device = result[1] || '' - , isUnc = device && device.charAt(1) !== ':' - , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute - - return isAbsolute -} - -function absUnix (p) { - return p.charAt(0) === "/" || p === "" -} diff --git a/platforms/android/cordova/node_modules/wrappy/LICENSE b/platforms/android/cordova/node_modules/wrappy/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/platforms/android/cordova/node_modules/wrappy/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/platforms/android/cordova/node_modules/wrappy/README.md b/platforms/android/cordova/node_modules/wrappy/README.md new file mode 100644 index 0000000..98eab25 --- /dev/null +++ b/platforms/android/cordova/node_modules/wrappy/README.md @@ -0,0 +1,36 @@ +# wrappy + +Callback wrapping utility + +## USAGE + +```javascript +var wrappy = require("wrappy") + +// var wrapper = wrappy(wrapperFunction) + +// make sure a cb is called only once +// See also: http://npm.im/once for this specific use case +var once = wrappy(function (cb) { + var called = false + return function () { + if (called) return + called = true + return cb.apply(this, arguments) + } +}) + +function printBoo () { + console.log('boo') +} +// has some rando property +printBoo.iAmBooPrinter = true + +var onlyPrintOnce = once(printBoo) + +onlyPrintOnce() // prints 'boo' +onlyPrintOnce() // does nothing + +// random property is retained! +assert.equal(onlyPrintOnce.iAmBooPrinter, true) +``` diff --git a/platforms/android/cordova/node_modules/wrappy/package.json b/platforms/android/cordova/node_modules/wrappy/package.json new file mode 100644 index 0000000..35d4cc7 --- /dev/null +++ b/platforms/android/cordova/node_modules/wrappy/package.json @@ -0,0 +1,78 @@ +{ + "_args": [ + [ + "wrappy@1", + "/Users/steveng/repo/cordova/cordova-android/node_modules/inflight" + ] + ], + "_from": "wrappy@>=1.0.0 <2.0.0", + "_id": "wrappy@1.0.1", + "_inCache": true, + "_installable": true, + "_location": "/wrappy", + "_nodeVersion": "0.10.31", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "2.0.0", + "_phantomChildren": {}, + "_requested": { + "name": "wrappy", + "raw": "wrappy@1", + "rawSpec": "1", + "scope": null, + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/inflight", + "/once" + ], + "_resolved": "http://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", + "_shasum": "1e65969965ccbc2db4548c6b84a6f2c5aedd4739", + "_shrinkwrap": null, + "_spec": "wrappy@1", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/inflight", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/npm/wrappy/issues" + }, + "dependencies": {}, + "description": "Callback wrapping utility", + "devDependencies": { + "tap": "^0.4.12" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "1e65969965ccbc2db4548c6b84a6f2c5aedd4739", + "tarball": "http://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + }, + "gitHead": "006a8cbac6b99988315834c207896eed71fd069a", + "homepage": "https://github.com/npm/wrappy", + "license": "ISC", + "main": "wrappy.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "wrappy", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/wrappy.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "1.0.1" +} diff --git a/platforms/android/cordova/node_modules/wrappy/test/basic.js b/platforms/android/cordova/node_modules/wrappy/test/basic.js new file mode 100644 index 0000000..5ed0fcd --- /dev/null +++ b/platforms/android/cordova/node_modules/wrappy/test/basic.js @@ -0,0 +1,51 @@ +var test = require('tap').test +var wrappy = require('../wrappy.js') + +test('basic', function (t) { + function onceifier (cb) { + var called = false + return function () { + if (called) return + called = true + return cb.apply(this, arguments) + } + } + onceifier.iAmOnce = {} + var once = wrappy(onceifier) + t.equal(once.iAmOnce, onceifier.iAmOnce) + + var called = 0 + function boo () { + t.equal(called, 0) + called++ + } + // has some rando property + boo.iAmBoo = true + + var onlyPrintOnce = once(boo) + + onlyPrintOnce() // prints 'boo' + onlyPrintOnce() // does nothing + t.equal(called, 1) + + // random property is retained! + t.equal(onlyPrintOnce.iAmBoo, true) + + var logs = [] + var logwrap = wrappy(function (msg, cb) { + logs.push(msg + ' wrapping cb') + return function () { + logs.push(msg + ' before cb') + var ret = cb.apply(this, arguments) + logs.push(msg + ' after cb') + } + }) + + var c = logwrap('foo', function () { + t.same(logs, [ 'foo wrapping cb', 'foo before cb' ]) + }) + c() + t.same(logs, [ 'foo wrapping cb', 'foo before cb', 'foo after cb' ]) + + t.end() +}) diff --git a/platforms/android/cordova/node_modules/wrappy/wrappy.js b/platforms/android/cordova/node_modules/wrappy/wrappy.js new file mode 100644 index 0000000..bb7e7d6 --- /dev/null +++ b/platforms/android/cordova/node_modules/wrappy/wrappy.js @@ -0,0 +1,33 @@ +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} diff --git a/platforms/android/cordova/node_modules/xmlbuilder/.npmignore b/platforms/android/cordova/node_modules/xmlbuilder/.npmignore new file mode 100644 index 0000000..b6ad1f6 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/.npmignore @@ -0,0 +1,5 @@ +.travis.yml +src +test +perf +coverage diff --git a/platforms/android/cordova/node_modules/xmlbuilder/LICENSE b/platforms/android/cordova/node_modules/xmlbuilder/LICENSE new file mode 100644 index 0000000..e7cbac9 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Ozgur Ozcitak + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/platforms/android/cordova/node_modules/xmlbuilder/README.md b/platforms/android/cordova/node_modules/xmlbuilder/README.md new file mode 100644 index 0000000..13a5b12 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/README.md @@ -0,0 +1,86 @@ +# xmlbuilder-js + +An XML builder for [node.js](https://nodejs.org/) similar to +[java-xmlbuilder](https://github.com/jmurty/java-xmlbuilder). + +[![License](http://img.shields.io/npm/l/xmlbuilder.svg?style=flat-square)](http://opensource.org/licenses/MIT) +[![NPM Version](http://img.shields.io/npm/v/xmlbuilder.svg?style=flat-square)](https://npmjs.com/package/xmlbuilder) +[![NPM Downloads](https://img.shields.io/npm/dm/xmlbuilder.svg?style=flat-square)](https://npmjs.com/package/xmlbuilder) + +[![Build Status](http://img.shields.io/travis/oozcitak/xmlbuilder-js.svg?style=flat-square)](http://travis-ci.org/oozcitak/xmlbuilder-js) +[![Dependency Status](http://img.shields.io/david/oozcitak/xmlbuilder-js.svg?style=flat-square)](https://david-dm.org/oozcitak/xmlbuilder-js) +[![Dev Dependency Status](http://img.shields.io/david/dev/oozcitak/xmlbuilder-js.svg?style=flat-square)](https://david-dm.org/oozcitak/xmlbuilder-js) +[![Code Coverage](https://img.shields.io/coveralls/oozcitak/xmlbuilder-js.svg?style=flat-square)](https://coveralls.io/github/oozcitak/xmlbuilder-js) + +### Installation: + +``` sh +npm install xmlbuilder +``` + +### Usage: + +``` js +var builder = require('xmlbuilder'); +var xml = builder.create('root') + .ele('xmlbuilder') + .ele('repo', {'type': 'git'}, 'git://github.com/oozcitak/xmlbuilder-js.git') + .end({ pretty: true}); + +console.log(xml); +``` + +will result in: + +``` xml + + + + git://github.com/oozcitak/xmlbuilder-js.git + + +``` + +It is also possible to convert objects into nodes: + +``` js +builder.create({ + root: { + xmlbuilder: { + repo: { + '@type': 'git', // attributes start with @ + '#text': 'git://github.com/oozcitak/xmlbuilder-js.git' // text node + } + } + } +}); +``` + +If you need to do some processing: + +``` js +var root = builder.create('squares'); +root.com('f(x) = x^2'); +for(var i = 1; i <= 5; i++) +{ + var item = root.ele('data'); + item.att('x', i); + item.att('y', i * i); +} +``` + +This will result in: + +``` xml + + + + + + + + + +``` + +See the [wiki](https://github.com/oozcitak/xmlbuilder-js/wiki) for details. diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLAttribute.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLAttribute.js new file mode 100644 index 0000000..247c9d1 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLAttribute.js @@ -0,0 +1,32 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLAttribute, create; + + create = require('lodash/object/create'); + + module.exports = XMLAttribute = (function() { + function XMLAttribute(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing attribute name of element " + parent.name); + } + if (value == null) { + throw new Error("Missing attribute value for attribute " + name + " of element " + parent.name); + } + this.name = this.stringify.attName(name); + this.value = this.stringify.attValue(value); + } + + XMLAttribute.prototype.clone = function() { + return create(XMLAttribute.prototype, this); + }; + + XMLAttribute.prototype.toString = function(options, level) { + return ' ' + this.name + '="' + this.value + '"'; + }; + + return XMLAttribute; + + })(); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLBuilder.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLBuilder.js new file mode 100644 index 0000000..4282833 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLBuilder.js @@ -0,0 +1,69 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLBuilder, XMLDeclaration, XMLDocType, XMLElement, XMLStringifier; + + XMLStringifier = require('./XMLStringifier'); + + XMLDeclaration = require('./XMLDeclaration'); + + XMLDocType = require('./XMLDocType'); + + XMLElement = require('./XMLElement'); + + module.exports = XMLBuilder = (function() { + function XMLBuilder(name, options) { + var root, temp; + if (name == null) { + throw new Error("Root element needs a name"); + } + if (options == null) { + options = {}; + } + this.options = options; + this.stringify = new XMLStringifier(options); + temp = new XMLElement(this, 'doc'); + root = temp.element(name); + root.isRoot = true; + root.documentObject = this; + this.rootObject = root; + if (!options.headless) { + root.declaration(options); + if ((options.pubID != null) || (options.sysID != null)) { + root.doctype(options); + } + } + } + + XMLBuilder.prototype.root = function() { + return this.rootObject; + }; + + XMLBuilder.prototype.end = function(options) { + return this.toString(options); + }; + + XMLBuilder.prototype.toString = function(options) { + var indent, newline, offset, pretty, r, ref, ref1, ref2; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + r = ''; + if (this.xmldec != null) { + r += this.xmldec.toString(options); + } + if (this.doctype != null) { + r += this.doctype.toString(options); + } + r += this.rootObject.toString(options); + if (pretty && r.slice(-newline.length) === newline) { + r = r.slice(0, -newline.length); + } + return r; + }; + + return XMLBuilder; + + })(); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLCData.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLCData.js new file mode 100644 index 0000000..00002f1 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLCData.js @@ -0,0 +1,49 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLNode, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLCData = (function(superClass) { + extend(XMLCData, superClass); + + function XMLCData(parent, text) { + XMLCData.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing CDATA text"); + } + this.text = this.stringify.cdata(text); + } + + XMLCData.prototype.clone = function() { + return create(XMLCData.prototype, this); + }; + + XMLCData.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLCData; + + })(XMLNode); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLComment.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLComment.js new file mode 100644 index 0000000..ca23e95 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLComment.js @@ -0,0 +1,49 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLComment, XMLNode, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLComment = (function(superClass) { + extend(XMLComment, superClass); + + function XMLComment(parent, text) { + XMLComment.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing comment text"); + } + this.text = this.stringify.comment(text); + } + + XMLComment.prototype.clone = function() { + return create(XMLComment.prototype, this); + }; + + XMLComment.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLComment; + + })(XMLNode); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDAttList.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDAttList.js new file mode 100644 index 0000000..62e6d8a --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDAttList.js @@ -0,0 +1,68 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDAttList, create; + + create = require('lodash/object/create'); + + module.exports = XMLDTDAttList = (function() { + function XMLDTDAttList(parent, elementName, attributeName, attributeType, defaultValueType, defaultValue) { + this.stringify = parent.stringify; + if (elementName == null) { + throw new Error("Missing DTD element name"); + } + if (attributeName == null) { + throw new Error("Missing DTD attribute name"); + } + if (!attributeType) { + throw new Error("Missing DTD attribute type"); + } + if (!defaultValueType) { + throw new Error("Missing DTD attribute default"); + } + if (defaultValueType.indexOf('#') !== 0) { + defaultValueType = '#' + defaultValueType; + } + if (!defaultValueType.match(/^(#REQUIRED|#IMPLIED|#FIXED|#DEFAULT)$/)) { + throw new Error("Invalid default value type; expected: #REQUIRED, #IMPLIED, #FIXED or #DEFAULT"); + } + if (defaultValue && !defaultValueType.match(/^(#FIXED|#DEFAULT)$/)) { + throw new Error("Default value only applies to #FIXED or #DEFAULT"); + } + this.elementName = this.stringify.eleName(elementName); + this.attributeName = this.stringify.attName(attributeName); + this.attributeType = this.stringify.dtdAttType(attributeType); + this.defaultValue = this.stringify.dtdAttDefault(defaultValue); + this.defaultValueType = defaultValueType; + } + + XMLDTDAttList.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDAttList; + + })(); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDElement.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDElement.js new file mode 100644 index 0000000..2d155e2 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDElement.js @@ -0,0 +1,46 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDElement, create; + + create = require('lodash/object/create'); + + module.exports = XMLDTDElement = (function() { + function XMLDTDElement(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing DTD element name"); + } + if (!value) { + value = '(#PCDATA)'; + } + if (Array.isArray(value)) { + value = '(' + value.join(',') + ')'; + } + this.name = this.stringify.eleName(name); + this.value = this.stringify.dtdElementValue(value); + } + + XMLDTDElement.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDElement; + + })(); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDEntity.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDEntity.js new file mode 100644 index 0000000..3201d19 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDEntity.js @@ -0,0 +1,84 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDEntity, create, isObject; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + module.exports = XMLDTDEntity = (function() { + function XMLDTDEntity(parent, pe, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing entity name"); + } + if (value == null) { + throw new Error("Missing entity value"); + } + this.pe = !!pe; + this.name = this.stringify.eleName(name); + if (!isObject(value)) { + this.value = this.stringify.dtdEntityValue(value); + } else { + if (!value.pubID && !value.sysID) { + throw new Error("Public and/or system identifiers are required for an external entity"); + } + if (value.pubID && !value.sysID) { + throw new Error("System identifier is required for a public external entity"); + } + if (value.pubID != null) { + this.pubID = this.stringify.dtdPubID(value.pubID); + } + if (value.sysID != null) { + this.sysID = this.stringify.dtdSysID(value.sysID); + } + if (value.nData != null) { + this.nData = this.stringify.dtdNData(value.nData); + } + if (this.pe && this.nData) { + throw new Error("Notation declaration is not allowed in a parameter entity"); + } + } + } + + XMLDTDEntity.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDEntity; + + })(); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDNotation.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDNotation.js new file mode 100644 index 0000000..cfbccf4 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDTDNotation.js @@ -0,0 +1,56 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDNotation, create; + + create = require('lodash/object/create'); + + module.exports = XMLDTDNotation = (function() { + function XMLDTDNotation(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing notation name"); + } + if (!value.pubID && !value.sysID) { + throw new Error("Public or system identifiers are required for an external entity"); + } + this.name = this.stringify.eleName(name); + if (value.pubID != null) { + this.pubID = this.stringify.dtdPubID(value.pubID); + } + if (value.sysID != null) { + this.sysID = this.stringify.dtdSysID(value.sysID); + } + } + + XMLDTDNotation.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDNotation; + + })(); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDeclaration.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDeclaration.js new file mode 100644 index 0000000..b2d8435 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDeclaration.js @@ -0,0 +1,65 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDeclaration, XMLNode, create, isObject, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLDeclaration = (function(superClass) { + extend(XMLDeclaration, superClass); + + function XMLDeclaration(parent, version, encoding, standalone) { + var ref; + XMLDeclaration.__super__.constructor.call(this, parent); + if (isObject(version)) { + ref = version, version = ref.version, encoding = ref.encoding, standalone = ref.standalone; + } + if (!version) { + version = '1.0'; + } + this.version = this.stringify.xmlVersion(version); + if (encoding != null) { + this.encoding = this.stringify.xmlEncoding(encoding); + } + if (standalone != null) { + this.standalone = this.stringify.xmlStandalone(standalone); + } + } + + XMLDeclaration.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDeclaration; + + })(XMLNode); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDocType.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDocType.js new file mode 100644 index 0000000..eec6f36 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLDocType.js @@ -0,0 +1,188 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLComment, XMLDTDAttList, XMLDTDElement, XMLDTDEntity, XMLDTDNotation, XMLDocType, XMLProcessingInstruction, create, isObject; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + XMLCData = require('./XMLCData'); + + XMLComment = require('./XMLComment'); + + XMLDTDAttList = require('./XMLDTDAttList'); + + XMLDTDEntity = require('./XMLDTDEntity'); + + XMLDTDElement = require('./XMLDTDElement'); + + XMLDTDNotation = require('./XMLDTDNotation'); + + XMLProcessingInstruction = require('./XMLProcessingInstruction'); + + module.exports = XMLDocType = (function() { + function XMLDocType(parent, pubID, sysID) { + var ref, ref1; + this.documentObject = parent; + this.stringify = this.documentObject.stringify; + this.children = []; + if (isObject(pubID)) { + ref = pubID, pubID = ref.pubID, sysID = ref.sysID; + } + if (sysID == null) { + ref1 = [pubID, sysID], sysID = ref1[0], pubID = ref1[1]; + } + if (pubID != null) { + this.pubID = this.stringify.dtdPubID(pubID); + } + if (sysID != null) { + this.sysID = this.stringify.dtdSysID(sysID); + } + } + + XMLDocType.prototype.element = function(name, value) { + var child; + child = new XMLDTDElement(this, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.attList = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) { + var child; + child = new XMLDTDAttList(this, elementName, attributeName, attributeType, defaultValueType, defaultValue); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.entity = function(name, value) { + var child; + child = new XMLDTDEntity(this, false, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.pEntity = function(name, value) { + var child; + child = new XMLDTDEntity(this, true, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.notation = function(name, value) { + var child; + child = new XMLDTDNotation(this, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.cdata = function(value) { + var child; + child = new XMLCData(this, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.comment = function(value) { + var child; + child = new XMLComment(this, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.instruction = function(target, value) { + var child; + child = new XMLProcessingInstruction(this, target, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.root = function() { + return this.documentObject.root(); + }; + + XMLDocType.prototype.document = function() { + return this.documentObject; + }; + + XMLDocType.prototype.toString = function(options, level) { + var child, i, indent, len, newline, offset, pretty, r, ref, ref1, ref2, ref3, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ' 0) { + r += ' ['; + if (pretty) { + r += newline; + } + ref3 = this.children; + for (i = 0, len = ref3.length; i < len; i++) { + child = ref3[i]; + r += child.toString(options, level + 1); + } + r += ']'; + } + r += '>'; + if (pretty) { + r += newline; + } + return r; + }; + + XMLDocType.prototype.ele = function(name, value) { + return this.element(name, value); + }; + + XMLDocType.prototype.att = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) { + return this.attList(elementName, attributeName, attributeType, defaultValueType, defaultValue); + }; + + XMLDocType.prototype.ent = function(name, value) { + return this.entity(name, value); + }; + + XMLDocType.prototype.pent = function(name, value) { + return this.pEntity(name, value); + }; + + XMLDocType.prototype.not = function(name, value) { + return this.notation(name, value); + }; + + XMLDocType.prototype.dat = function(value) { + return this.cdata(value); + }; + + XMLDocType.prototype.com = function(value) { + return this.comment(value); + }; + + XMLDocType.prototype.ins = function(target, value) { + return this.instruction(target, value); + }; + + XMLDocType.prototype.up = function() { + return this.root(); + }; + + XMLDocType.prototype.doc = function() { + return this.document(); + }; + + return XMLDocType; + + })(); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLElement.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLElement.js new file mode 100644 index 0000000..d5814c8 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLElement.js @@ -0,0 +1,212 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLAttribute, XMLElement, XMLNode, XMLProcessingInstruction, create, every, isFunction, isObject, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + isObject = require('lodash/lang/isObject'); + + isFunction = require('lodash/lang/isFunction'); + + every = require('lodash/collection/every'); + + XMLNode = require('./XMLNode'); + + XMLAttribute = require('./XMLAttribute'); + + XMLProcessingInstruction = require('./XMLProcessingInstruction'); + + module.exports = XMLElement = (function(superClass) { + extend(XMLElement, superClass); + + function XMLElement(parent, name, attributes) { + XMLElement.__super__.constructor.call(this, parent); + if (name == null) { + throw new Error("Missing element name"); + } + this.name = this.stringify.eleName(name); + this.children = []; + this.instructions = []; + this.attributes = {}; + if (attributes != null) { + this.attribute(attributes); + } + } + + XMLElement.prototype.clone = function() { + var att, attName, clonedSelf, i, len, pi, ref, ref1; + clonedSelf = create(XMLElement.prototype, this); + if (clonedSelf.isRoot) { + clonedSelf.documentObject = null; + } + clonedSelf.attributes = {}; + ref = this.attributes; + for (attName in ref) { + if (!hasProp.call(ref, attName)) continue; + att = ref[attName]; + clonedSelf.attributes[attName] = att.clone(); + } + clonedSelf.instructions = []; + ref1 = this.instructions; + for (i = 0, len = ref1.length; i < len; i++) { + pi = ref1[i]; + clonedSelf.instructions.push(pi.clone()); + } + clonedSelf.children = []; + this.children.forEach(function(child) { + var clonedChild; + clonedChild = child.clone(); + clonedChild.parent = clonedSelf; + return clonedSelf.children.push(clonedChild); + }); + return clonedSelf; + }; + + XMLElement.prototype.attribute = function(name, value) { + var attName, attValue; + if (name != null) { + name = name.valueOf(); + } + if (isObject(name)) { + for (attName in name) { + if (!hasProp.call(name, attName)) continue; + attValue = name[attName]; + this.attribute(attName, attValue); + } + } else { + if (isFunction(value)) { + value = value.apply(); + } + if (!this.options.skipNullAttributes || (value != null)) { + this.attributes[name] = new XMLAttribute(this, name, value); + } + } + return this; + }; + + XMLElement.prototype.removeAttribute = function(name) { + var attName, i, len; + if (name == null) { + throw new Error("Missing attribute name"); + } + name = name.valueOf(); + if (Array.isArray(name)) { + for (i = 0, len = name.length; i < len; i++) { + attName = name[i]; + delete this.attributes[attName]; + } + } else { + delete this.attributes[name]; + } + return this; + }; + + XMLElement.prototype.instruction = function(target, value) { + var i, insTarget, insValue, instruction, len; + if (target != null) { + target = target.valueOf(); + } + if (value != null) { + value = value.valueOf(); + } + if (Array.isArray(target)) { + for (i = 0, len = target.length; i < len; i++) { + insTarget = target[i]; + this.instruction(insTarget); + } + } else if (isObject(target)) { + for (insTarget in target) { + if (!hasProp.call(target, insTarget)) continue; + insValue = target[insTarget]; + this.instruction(insTarget, insValue); + } + } else { + if (isFunction(value)) { + value = value.apply(); + } + instruction = new XMLProcessingInstruction(this, target, value); + this.instructions.push(instruction); + } + return this; + }; + + XMLElement.prototype.toString = function(options, level) { + var att, child, i, indent, instruction, j, len, len1, name, newline, offset, pretty, r, ref, ref1, ref2, ref3, ref4, ref5, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + ref3 = this.instructions; + for (i = 0, len = ref3.length; i < len; i++) { + instruction = ref3[i]; + r += instruction.toString(options, level); + } + if (pretty) { + r += space; + } + r += '<' + this.name; + ref4 = this.attributes; + for (name in ref4) { + if (!hasProp.call(ref4, name)) continue; + att = ref4[name]; + r += att.toString(options); + } + if (this.children.length === 0 || every(this.children, function(e) { + return e.value === ''; + })) { + r += '/>'; + if (pretty) { + r += newline; + } + } else if (pretty && this.children.length === 1 && (this.children[0].value != null)) { + r += '>'; + r += this.children[0].value; + r += ''; + r += newline; + } else { + r += '>'; + if (pretty) { + r += newline; + } + ref5 = this.children; + for (j = 0, len1 = ref5.length; j < len1; j++) { + child = ref5[j]; + r += child.toString(options, level + 1); + } + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + } + return r; + }; + + XMLElement.prototype.att = function(name, value) { + return this.attribute(name, value); + }; + + XMLElement.prototype.ins = function(target, value) { + return this.instruction(target, value); + }; + + XMLElement.prototype.a = function(name, value) { + return this.attribute(name, value); + }; + + XMLElement.prototype.i = function(target, value) { + return this.instruction(target, value); + }; + + return XMLElement; + + })(XMLNode); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLNode.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLNode.js new file mode 100644 index 0000000..592545a --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLNode.js @@ -0,0 +1,331 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLComment, XMLDeclaration, XMLDocType, XMLElement, XMLNode, XMLRaw, XMLText, isEmpty, isFunction, isObject, + hasProp = {}.hasOwnProperty; + + isObject = require('lodash/lang/isObject'); + + isFunction = require('lodash/lang/isFunction'); + + isEmpty = require('lodash/lang/isEmpty'); + + XMLElement = null; + + XMLCData = null; + + XMLComment = null; + + XMLDeclaration = null; + + XMLDocType = null; + + XMLRaw = null; + + XMLText = null; + + module.exports = XMLNode = (function() { + function XMLNode(parent) { + this.parent = parent; + this.options = this.parent.options; + this.stringify = this.parent.stringify; + if (XMLElement === null) { + XMLElement = require('./XMLElement'); + XMLCData = require('./XMLCData'); + XMLComment = require('./XMLComment'); + XMLDeclaration = require('./XMLDeclaration'); + XMLDocType = require('./XMLDocType'); + XMLRaw = require('./XMLRaw'); + XMLText = require('./XMLText'); + } + } + + XMLNode.prototype.element = function(name, attributes, text) { + var childNode, item, j, k, key, lastChild, len, len1, ref, val; + lastChild = null; + if (attributes == null) { + attributes = {}; + } + attributes = attributes.valueOf(); + if (!isObject(attributes)) { + ref = [attributes, text], text = ref[0], attributes = ref[1]; + } + if (name != null) { + name = name.valueOf(); + } + if (Array.isArray(name)) { + for (j = 0, len = name.length; j < len; j++) { + item = name[j]; + lastChild = this.element(item); + } + } else if (isFunction(name)) { + lastChild = this.element(name.apply()); + } else if (isObject(name)) { + for (key in name) { + if (!hasProp.call(name, key)) continue; + val = name[key]; + if (isFunction(val)) { + val = val.apply(); + } + if ((isObject(val)) && (isEmpty(val))) { + val = null; + } + if (!this.options.ignoreDecorators && this.stringify.convertAttKey && key.indexOf(this.stringify.convertAttKey) === 0) { + lastChild = this.attribute(key.substr(this.stringify.convertAttKey.length), val); + } else if (!this.options.ignoreDecorators && this.stringify.convertPIKey && key.indexOf(this.stringify.convertPIKey) === 0) { + lastChild = this.instruction(key.substr(this.stringify.convertPIKey.length), val); + } else if (Array.isArray(val)) { + for (k = 0, len1 = val.length; k < len1; k++) { + item = val[k]; + childNode = {}; + childNode[key] = item; + lastChild = this.element(childNode); + } + } else if (isObject(val)) { + lastChild = this.element(key); + lastChild.element(val); + } else { + lastChild = this.element(key, val); + } + } + } else { + if (!this.options.ignoreDecorators && this.stringify.convertTextKey && name.indexOf(this.stringify.convertTextKey) === 0) { + lastChild = this.text(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertCDataKey && name.indexOf(this.stringify.convertCDataKey) === 0) { + lastChild = this.cdata(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertCommentKey && name.indexOf(this.stringify.convertCommentKey) === 0) { + lastChild = this.comment(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertRawKey && name.indexOf(this.stringify.convertRawKey) === 0) { + lastChild = this.raw(text); + } else { + lastChild = this.node(name, attributes, text); + } + } + if (lastChild == null) { + throw new Error("Could not create any elements with: " + name); + } + return lastChild; + }; + + XMLNode.prototype.insertBefore = function(name, attributes, text) { + var child, i, removed; + if (this.isRoot) { + throw new Error("Cannot insert elements at root level"); + } + i = this.parent.children.indexOf(this); + removed = this.parent.children.splice(i); + child = this.parent.element(name, attributes, text); + Array.prototype.push.apply(this.parent.children, removed); + return child; + }; + + XMLNode.prototype.insertAfter = function(name, attributes, text) { + var child, i, removed; + if (this.isRoot) { + throw new Error("Cannot insert elements at root level"); + } + i = this.parent.children.indexOf(this); + removed = this.parent.children.splice(i + 1); + child = this.parent.element(name, attributes, text); + Array.prototype.push.apply(this.parent.children, removed); + return child; + }; + + XMLNode.prototype.remove = function() { + var i, ref; + if (this.isRoot) { + throw new Error("Cannot remove the root element"); + } + i = this.parent.children.indexOf(this); + [].splice.apply(this.parent.children, [i, i - i + 1].concat(ref = [])), ref; + return this.parent; + }; + + XMLNode.prototype.node = function(name, attributes, text) { + var child, ref; + if (name != null) { + name = name.valueOf(); + } + if (attributes == null) { + attributes = {}; + } + attributes = attributes.valueOf(); + if (!isObject(attributes)) { + ref = [attributes, text], text = ref[0], attributes = ref[1]; + } + child = new XMLElement(this, name, attributes); + if (text != null) { + child.text(text); + } + this.children.push(child); + return child; + }; + + XMLNode.prototype.text = function(value) { + var child; + child = new XMLText(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.cdata = function(value) { + var child; + child = new XMLCData(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.comment = function(value) { + var child; + child = new XMLComment(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.raw = function(value) { + var child; + child = new XMLRaw(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.declaration = function(version, encoding, standalone) { + var doc, xmldec; + doc = this.document(); + xmldec = new XMLDeclaration(doc, version, encoding, standalone); + doc.xmldec = xmldec; + return doc.root(); + }; + + XMLNode.prototype.doctype = function(pubID, sysID) { + var doc, doctype; + doc = this.document(); + doctype = new XMLDocType(doc, pubID, sysID); + doc.doctype = doctype; + return doctype; + }; + + XMLNode.prototype.up = function() { + if (this.isRoot) { + throw new Error("The root node has no parent. Use doc() if you need to get the document object."); + } + return this.parent; + }; + + XMLNode.prototype.root = function() { + var child; + if (this.isRoot) { + return this; + } + child = this.parent; + while (!child.isRoot) { + child = child.parent; + } + return child; + }; + + XMLNode.prototype.document = function() { + return this.root().documentObject; + }; + + XMLNode.prototype.end = function(options) { + return this.document().toString(options); + }; + + XMLNode.prototype.prev = function() { + var i; + if (this.isRoot) { + throw new Error("Root node has no siblings"); + } + i = this.parent.children.indexOf(this); + if (i < 1) { + throw new Error("Already at the first node"); + } + return this.parent.children[i - 1]; + }; + + XMLNode.prototype.next = function() { + var i; + if (this.isRoot) { + throw new Error("Root node has no siblings"); + } + i = this.parent.children.indexOf(this); + if (i === -1 || i === this.parent.children.length - 1) { + throw new Error("Already at the last node"); + } + return this.parent.children[i + 1]; + }; + + XMLNode.prototype.importXMLBuilder = function(xmlbuilder) { + var clonedRoot; + clonedRoot = xmlbuilder.root().clone(); + clonedRoot.parent = this; + clonedRoot.isRoot = false; + this.children.push(clonedRoot); + return this; + }; + + XMLNode.prototype.ele = function(name, attributes, text) { + return this.element(name, attributes, text); + }; + + XMLNode.prototype.nod = function(name, attributes, text) { + return this.node(name, attributes, text); + }; + + XMLNode.prototype.txt = function(value) { + return this.text(value); + }; + + XMLNode.prototype.dat = function(value) { + return this.cdata(value); + }; + + XMLNode.prototype.com = function(value) { + return this.comment(value); + }; + + XMLNode.prototype.doc = function() { + return this.document(); + }; + + XMLNode.prototype.dec = function(version, encoding, standalone) { + return this.declaration(version, encoding, standalone); + }; + + XMLNode.prototype.dtd = function(pubID, sysID) { + return this.doctype(pubID, sysID); + }; + + XMLNode.prototype.e = function(name, attributes, text) { + return this.element(name, attributes, text); + }; + + XMLNode.prototype.n = function(name, attributes, text) { + return this.node(name, attributes, text); + }; + + XMLNode.prototype.t = function(value) { + return this.text(value); + }; + + XMLNode.prototype.d = function(value) { + return this.cdata(value); + }; + + XMLNode.prototype.c = function(value) { + return this.comment(value); + }; + + XMLNode.prototype.r = function(value) { + return this.raw(value); + }; + + XMLNode.prototype.u = function() { + return this.up(); + }; + + return XMLNode; + + })(); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLProcessingInstruction.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLProcessingInstruction.js new file mode 100644 index 0000000..f5d8c6c --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLProcessingInstruction.js @@ -0,0 +1,51 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLProcessingInstruction, create; + + create = require('lodash/object/create'); + + module.exports = XMLProcessingInstruction = (function() { + function XMLProcessingInstruction(parent, target, value) { + this.stringify = parent.stringify; + if (target == null) { + throw new Error("Missing instruction target"); + } + this.target = this.stringify.insTarget(target); + if (value) { + this.value = this.stringify.insValue(value); + } + } + + XMLProcessingInstruction.prototype.clone = function() { + return create(XMLProcessingInstruction.prototype, this); + }; + + XMLProcessingInstruction.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLProcessingInstruction; + + })(); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLRaw.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLRaw.js new file mode 100644 index 0000000..499d0e2 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLRaw.js @@ -0,0 +1,49 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLNode, XMLRaw, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/object/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLRaw = (function(superClass) { + extend(XMLRaw, superClass); + + function XMLRaw(parent, text) { + XMLRaw.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing raw text"); + } + this.value = this.stringify.raw(text); + } + + XMLRaw.prototype.clone = function() { + return create(XMLRaw.prototype, this); + }; + + XMLRaw.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += this.value; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLRaw; + + })(XMLNode); + +}).call(this); diff --git a/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLStringifier.js b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLStringifier.js new file mode 100644 index 0000000..f0ab1fc --- /dev/null +++ b/platforms/android/cordova/node_modules/xmlbuilder/lib/XMLStringifier.js @@ -0,0 +1,165 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLStringifier, + bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + hasProp = {}.hasOwnProperty; + + module.exports = XMLStringifier = (function() { + function XMLStringifier(options) { + this.assertLegalChar = bind(this.assertLegalChar, this); + var key, ref, value; + this.allowSurrogateChars = options != null ? options.allowSurrogateChars : void 0; + ref = (options != null ? options.stringify : void 0) || {}; + for (key in ref) { + if (!hasProp.call(ref, key)) continue; + value = ref[key]; + this[key] = value; + } + } + + XMLStringifier.prototype.eleName = function(val) { + val = '' + val || ''; + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.eleText = function(val) { + val = '' + val || ''; + return this.assertLegalChar(this.elEscape(val)); + }; + + XMLStringifier.prototype.cdata = function(val) { + val = '' + val || ''; + if (val.match(/]]>/)) { + throw new Error("Invalid CDATA text: " + val); + } + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.comment = function(val) { + val = '' + val || ''; + if (val.match(/--/)) { + throw new Error("Comment text cannot contain double-hypen: " + val); + } + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.raw = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.attName = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.attValue = function(val) { + val = '' + val || ''; + return this.attEscape(val); + }; + + XMLStringifier.prototype.insTarget = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.insValue = function(val) { + val = '' + val || ''; + if (val.match(/\?>/)) { + throw new Error("Invalid processing instruction value: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlVersion = function(val) { + val = '' + val || ''; + if (!val.match(/1\.[0-9]+/)) { + throw new Error("Invalid version number: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlEncoding = function(val) { + val = '' + val || ''; + if (!val.match(/^[A-Za-z](?:[A-Za-z0-9._-]|-)*$/)) { + throw new Error("Invalid encoding: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlStandalone = function(val) { + if (val) { + return "yes"; + } else { + return "no"; + } + }; + + XMLStringifier.prototype.dtdPubID = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdSysID = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdElementValue = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdAttType = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdAttDefault = function(val) { + if (val != null) { + return '' + val || ''; + } else { + return val; + } + }; + + XMLStringifier.prototype.dtdEntityValue = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdNData = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.convertAttKey = '@'; + + XMLStringifier.prototype.convertPIKey = '?'; + + XMLStringifier.prototype.convertTextKey = '#text'; + + XMLStringifier.prototype.convertCDataKey = '#cdata'; + + XMLStringifier.prototype.convertCommentKey = '#comment'; + + XMLStringifier.prototype.convertRawKey = '#raw'; + + XMLStringifier.prototype.assertLegalChar = function(str) { + var chars, chr; + if (this.allowSurrogateChars) { + chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uFFFE-\uFFFF]/; + } else { + chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]/; + } + chr = str.match(chars); + if (chr) { + throw new Error("Invalid character (" + chr + ") in string: " + str + " at index " + chr.index); + } + return str; + }; + + XMLStringifier.prototype.elEscape = function(str) { + return str.replace(/&/g, '&').replace(//g, '>').replace(/\r/g, ' '); + }; + + XMLStringifier.prototype.attEscape = function(str) { + return str.replace(/&/g, '&').replace(/=0.8.0" + }, + "gitHead": "ec17840a6705ef666b7d04c771de11df6091fff5", + "homepage": "http://github.com/oozcitak/xmlbuilder-js", + "keywords": [ + "xml", + "xmlbuilder" + ], + "license": "MIT", + "main": "./lib/index", + "maintainers": [ + { + "name": "oozcitak", + "email": "oozcitak@gmail.com" + } + ], + "name": "xmlbuilder", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/oozcitak/xmlbuilder-js.git" + }, + "scripts": { + "postpublish": "rm -rf lib", + "prepublish": "coffee -co lib src", + "test": "mocha && istanbul report text lcov" + }, + "version": "4.0.0" +} diff --git a/platforms/android/cordova/node_modules/xmldom/.npmignore b/platforms/android/cordova/node_modules/xmldom/.npmignore new file mode 100644 index 0000000..b094a44 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmldom/.npmignore @@ -0,0 +1,5 @@ +test +t +travis.yml +.project +changelog diff --git a/platforms/android/cordova/node_modules/xmldom/.travis.yml b/platforms/android/cordova/node_modules/xmldom/.travis.yml new file mode 100644 index 0000000..b95408e --- /dev/null +++ b/platforms/android/cordova/node_modules/xmldom/.travis.yml @@ -0,0 +1,22 @@ +language: node_js + +node_js: + - '0.10' + +branches: + only: + - master + - proof + - travis-ci + +# Not using `npm install --dev` because it is recursive. It will pull in the all +# development dependencies for CoffeeScript. Way too much spew in the Travis CI +# build output. + +before_install: + - npm install + - npm install istanbul coveralls + +env: + global: + - secure: "BxUHTsa1WVANLQoimilbZwa1MCWSdM9hOmPWBE/rsYb7uT/iiqkRXXwnWhKtN5CLvTvIQbiAzq4iyPID0S8UHrnxClYQrOuA6QkrtwgIEuDAmijao/bgxobPOremvkwXcpMGIwzYKyYQQtSEaEIQbqf6gSSKW9dBh/GZ/vfTsqo=" diff --git a/platforms/android/cordova/node_modules/xmldom/LICENSE b/platforms/android/cordova/node_modules/xmldom/LICENSE new file mode 100644 index 0000000..68a9b5e --- /dev/null +++ b/platforms/android/cordova/node_modules/xmldom/LICENSE @@ -0,0 +1,8 @@ +You can choose any one of those: + +The MIT License (MIT): + +link:http://opensource.org/licenses/MIT + +LGPL: +http://www.gnu.org/licenses/lgpl.html diff --git a/platforms/android/cordova/node_modules/xmldom/__package__.js b/platforms/android/cordova/node_modules/xmldom/__package__.js new file mode 100644 index 0000000..b4cad28 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmldom/__package__.js @@ -0,0 +1,4 @@ +this.addScript('dom.js',['DOMImplementation','XMLSerializer']); +this.addScript('dom-parser.js',['DOMHandler','DOMParser'], + ['DOMImplementation','XMLReader']); +this.addScript('sax.js','XMLReader'); \ No newline at end of file diff --git a/platforms/android/cordova/node_modules/xmldom/changelog b/platforms/android/cordova/node_modules/xmldom/changelog new file mode 100644 index 0000000..ab815bb --- /dev/null +++ b/platforms/android/cordova/node_modules/xmldom/changelog @@ -0,0 +1,14 @@ +### Version 0.1.16 + +Sat May 4 14:58:03 UTC 2013 + + * Correctly handle multibyte Unicode greater than two byts. #57. #56. + * Initial unit testing and test coverage. #53. #46. #19. + * Create Bower `component.json` #52. + +### Version 0.1.8 + + * Add: some test case from node-o3-xml(excludes xpath support) + * Fix: remove existed attribute before setting (bug introduced in v0.1.5) + * Fix: index direct access for childNodes and any NodeList collection(not w3c standard) + * Fix: remove last child bug diff --git a/platforms/android/cordova/node_modules/xmldom/component.json b/platforms/android/cordova/node_modules/xmldom/component.json new file mode 100644 index 0000000..93b4d57 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmldom/component.json @@ -0,0 +1,10 @@ +{ + "name": "xmldom", + "version": "0.1.15", + "main": "dom-parser.js", + "ignore": [ + "**/.*", + "node_modules", + "components" + ] +} diff --git a/platforms/android/cordova/node_modules/xmldom/dom-parser.js b/platforms/android/cordova/node_modules/xmldom/dom-parser.js new file mode 100644 index 0000000..08c2f70 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmldom/dom-parser.js @@ -0,0 +1,249 @@ +function DOMParser(options){ + this.options = options ||{locator:{}}; + +} +DOMParser.prototype.parseFromString = function(source,mimeType){ + var options = this.options; + var sax = new XMLReader(); + var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler + var errorHandler = options.errorHandler; + var locator = options.locator; + var defaultNSMap = options.xmlns||{}; + var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"} + if(locator){ + domBuilder.setDocumentLocator(locator) + } + + sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator); + sax.domBuilder = options.domBuilder || domBuilder; + if(/\/x?html?$/.test(mimeType)){ + entityMap.nbsp = '\xa0'; + entityMap.copy = '\xa9'; + defaultNSMap['']= 'http://www.w3.org/1999/xhtml'; + } + defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace'; + if(source){ + sax.parse(source,defaultNSMap,entityMap); + }else{ + sax.errorHandler.error("invalid document source"); + } + return domBuilder.document; +} +function buildErrorHandler(errorImpl,domBuilder,locator){ + if(!errorImpl){ + if(domBuilder instanceof DOMHandler){ + return domBuilder; + } + errorImpl = domBuilder ; + } + var errorHandler = {} + var isCallback = errorImpl instanceof Function; + locator = locator||{} + function build(key){ + var fn = errorImpl[key]; + if(!fn && isCallback){ + fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl; + } + errorHandler[key] = fn && function(msg){ + fn('[xmldom '+key+']\t'+msg+_locator(locator)); + }||function(){}; + } + build('warning'); + build('error'); + build('fatalError'); + return errorHandler; +} + +//console.log('#\n\n\n\n\n\n\n####') +/** + * +ContentHandler+ErrorHandler + * +LexicalHandler+EntityResolver2 + * -DeclHandler-DTDHandler + * + * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler + * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2 + * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html + */ +function DOMHandler() { + this.cdata = false; +} +function position(locator,node){ + node.lineNumber = locator.lineNumber; + node.columnNumber = locator.columnNumber; +} +/** + * @see org.xml.sax.ContentHandler#startDocument + * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html + */ +DOMHandler.prototype = { + startDocument : function() { + this.document = new DOMImplementation().createDocument(null, null, null); + if (this.locator) { + this.document.documentURI = this.locator.systemId; + } + }, + startElement:function(namespaceURI, localName, qName, attrs) { + var doc = this.document; + var el = doc.createElementNS(namespaceURI, qName||localName); + var len = attrs.length; + appendElement(this, el); + this.currentElement = el; + + this.locator && position(this.locator,el) + for (var i = 0 ; i < len; i++) { + var namespaceURI = attrs.getURI(i); + var value = attrs.getValue(i); + var qName = attrs.getQName(i); + var attr = doc.createAttributeNS(namespaceURI, qName); + if( attr.getOffset){ + position(attr.getOffset(1),attr) + } + attr.value = attr.nodeValue = value; + el.setAttributeNode(attr) + } + }, + endElement:function(namespaceURI, localName, qName) { + var current = this.currentElement + var tagName = current.tagName; + this.currentElement = current.parentNode; + }, + startPrefixMapping:function(prefix, uri) { + }, + endPrefixMapping:function(prefix) { + }, + processingInstruction:function(target, data) { + var ins = this.document.createProcessingInstruction(target, data); + this.locator && position(this.locator,ins) + appendElement(this, ins); + }, + ignorableWhitespace:function(ch, start, length) { + }, + characters:function(chars, start, length) { + chars = _toString.apply(this,arguments) + //console.log(chars) + if(this.currentElement && chars){ + if (this.cdata) { + var charNode = this.document.createCDATASection(chars); + this.currentElement.appendChild(charNode); + } else { + var charNode = this.document.createTextNode(chars); + this.currentElement.appendChild(charNode); + } + this.locator && position(this.locator,charNode) + } + }, + skippedEntity:function(name) { + }, + endDocument:function() { + this.document.normalize(); + }, + setDocumentLocator:function (locator) { + if(this.locator = locator){// && !('lineNumber' in locator)){ + locator.lineNumber = 0; + } + }, + //LexicalHandler + comment:function(chars, start, length) { + chars = _toString.apply(this,arguments) + var comm = this.document.createComment(chars); + this.locator && position(this.locator,comm) + appendElement(this, comm); + }, + + startCDATA:function() { + //used in characters() methods + this.cdata = true; + }, + endCDATA:function() { + this.cdata = false; + }, + + startDTD:function(name, publicId, systemId) { + var impl = this.document.implementation; + if (impl && impl.createDocumentType) { + var dt = impl.createDocumentType(name, publicId, systemId); + this.locator && position(this.locator,dt) + appendElement(this, dt); + } + }, + /** + * @see org.xml.sax.ErrorHandler + * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html + */ + warning:function(error) { + console.warn('[xmldom warning]\t'+error,_locator(this.locator)); + }, + error:function(error) { + console.error('[xmldom error]\t'+error,_locator(this.locator)); + }, + fatalError:function(error) { + console.error('[xmldom fatalError]\t'+error,_locator(this.locator)); + throw error; + } +} +function _locator(l){ + if(l){ + return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']' + } +} +function _toString(chars,start,length){ + if(typeof chars == 'string'){ + return chars.substr(start,length) + }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)") + if(chars.length >= start+length || start){ + return new java.lang.String(chars,start,length)+''; + } + return chars; + } +} + +/* + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html + * used method of org.xml.sax.ext.LexicalHandler: + * #comment(chars, start, length) + * #startCDATA() + * #endCDATA() + * #startDTD(name, publicId, systemId) + * + * + * IGNORED method of org.xml.sax.ext.LexicalHandler: + * #endDTD() + * #startEntity(name) + * #endEntity(name) + * + * + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html + * IGNORED method of org.xml.sax.ext.DeclHandler + * #attributeDecl(eName, aName, type, mode, value) + * #elementDecl(name, model) + * #externalEntityDecl(name, publicId, systemId) + * #internalEntityDecl(name, value) + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html + * IGNORED method of org.xml.sax.EntityResolver2 + * #resolveEntity(String name,String publicId,String baseURI,String systemId) + * #resolveEntity(publicId, systemId) + * #getExternalSubset(name, baseURI) + * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html + * IGNORED method of org.xml.sax.DTDHandler + * #notationDecl(name, publicId, systemId) {}; + * #unparsedEntityDecl(name, publicId, systemId, notationName) {}; + */ +"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){ + DOMHandler.prototype[key] = function(){return null} +}) + +/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */ +function appendElement (hander,node) { + if (!hander.currentElement) { + hander.document.appendChild(node); + } else { + hander.currentElement.appendChild(node); + } +}//appendChild and setAttributeNS are preformance key + +if(typeof require == 'function'){ + var XMLReader = require('./sax').XMLReader; + var DOMImplementation = exports.DOMImplementation = require('./dom').DOMImplementation; + exports.XMLSerializer = require('./dom').XMLSerializer ; + exports.DOMParser = DOMParser; +} diff --git a/platforms/android/cordova/node_modules/xmldom/dom.js b/platforms/android/cordova/node_modules/xmldom/dom.js new file mode 100644 index 0000000..460a1be --- /dev/null +++ b/platforms/android/cordova/node_modules/xmldom/dom.js @@ -0,0 +1,1147 @@ +/* + * DOM Level 2 + * Object DOMException + * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html + */ + +function copy(src,dest){ + for(var p in src){ + dest[p] = src[p]; + } +} +/** +^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));? +^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));? + */ +function _extends(Class,Super){ + var pt = Class.prototype; + if(Object.create){ + var ppt = Object.create(Super.prototype) + pt.__proto__ = ppt; + } + if(!(pt instanceof Super)){ + function t(){}; + t.prototype = Super.prototype; + t = new t(); + copy(pt,t); + Class.prototype = pt = t; + } + if(pt.constructor != Class){ + if(typeof Class != 'function'){ + console.error("unknow Class:"+Class) + } + pt.constructor = Class + } +} +var htmlns = 'http://www.w3.org/1999/xhtml' ; +// Node Types +var NodeType = {} +var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1; +var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2; +var TEXT_NODE = NodeType.TEXT_NODE = 3; +var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4; +var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5; +var ENTITY_NODE = NodeType.ENTITY_NODE = 6; +var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7; +var COMMENT_NODE = NodeType.COMMENT_NODE = 8; +var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9; +var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10; +var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11; +var NOTATION_NODE = NodeType.NOTATION_NODE = 12; + +// ExceptionCode +var ExceptionCode = {} +var ExceptionMessage = {}; +var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1); +var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2); +var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3); +var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4); +var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5); +var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6); +var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7); +var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8); +var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9); +var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10); +//level2 +var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11); +var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12); +var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13); +var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14); +var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15); + + +function DOMException(code, message) { + if(message instanceof Error){ + var error = message; + }else{ + error = this; + Error.call(this, ExceptionMessage[code]); + this.message = ExceptionMessage[code]; + if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException); + } + error.code = code; + if(message) this.message = this.message + ": " + message; + return error; +}; +DOMException.prototype = Error.prototype; +copy(ExceptionCode,DOMException) +/** + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177 + * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live. + * The items in the NodeList are accessible via an integral index, starting from 0. + */ +function NodeList() { +}; +NodeList.prototype = { + /** + * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive. + * @standard level1 + */ + length:0, + /** + * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null. + * @standard level1 + * @param index unsigned long + * Index into the collection. + * @return Node + * The node at the indexth position in the NodeList, or null if that is not a valid index. + */ + item: function(index) { + return this[index] || null; + }, + toString:function(){ + for(var buf = [], i = 0;i=0){ + var lastIndex = list.length-1 + while(i0 || key == 'xmlns'){ +// return null; +// } + var i = this.length; + while(i--){ + var attr = this[i]; + if(attr.nodeName == key){ + return attr; + } + } + }, + setNamedItem: function(attr) { + var el = attr.ownerElement; + if(el && el!=this._ownerElement){ + throw new DOMException(INUSE_ATTRIBUTE_ERR); + } + var oldAttr = this.getNamedItem(attr.nodeName); + _addNamedNode(this._ownerElement,this,attr,oldAttr); + return oldAttr; + }, + /* returns Node */ + setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR + var el = attr.ownerElement, oldAttr; + if(el && el!=this._ownerElement){ + throw new DOMException(INUSE_ATTRIBUTE_ERR); + } + oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName); + _addNamedNode(this._ownerElement,this,attr,oldAttr); + return oldAttr; + }, + + /* returns Node */ + removeNamedItem: function(key) { + var attr = this.getNamedItem(key); + _removeNamedNode(this._ownerElement,this,attr); + return attr; + + + },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR + + //for level2 + removeNamedItemNS:function(namespaceURI,localName){ + var attr = this.getNamedItemNS(namespaceURI,localName); + _removeNamedNode(this._ownerElement,this,attr); + return attr; + }, + getNamedItemNS: function(namespaceURI, localName) { + var i = this.length; + while(i--){ + var node = this[i]; + if(node.localName == localName && node.namespaceURI == namespaceURI){ + return node; + } + } + return null; + } +}; +/** + * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 + */ +function DOMImplementation(/* Object */ features) { + this._features = {}; + if (features) { + for (var feature in features) { + this._features = features[feature]; + } + } +}; + +DOMImplementation.prototype = { + hasFeature: function(/* string */ feature, /* string */ version) { + var versions = this._features[feature.toLowerCase()]; + if (versions && (!version || version in versions)) { + return true; + } else { + return false; + } + }, + // Introduced in DOM Level 2: + createDocument:function(namespaceURI, qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR + var doc = new Document(); + doc.implementation = this; + doc.childNodes = new NodeList(); + doc.doctype = doctype; + if(doctype){ + doc.appendChild(doctype); + } + if(qualifiedName){ + var root = doc.createElementNS(namespaceURI,qualifiedName); + doc.appendChild(root); + } + return doc; + }, + // Introduced in DOM Level 2: + createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR + var node = new DocumentType(); + node.name = qualifiedName; + node.nodeName = qualifiedName; + node.publicId = publicId; + node.systemId = systemId; + // Introduced in DOM Level 2: + //readonly attribute DOMString internalSubset; + + //TODO:.. + // readonly attribute NamedNodeMap entities; + // readonly attribute NamedNodeMap notations; + return node; + } +}; + + +/** + * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 + */ + +function Node() { +}; + +Node.prototype = { + firstChild : null, + lastChild : null, + previousSibling : null, + nextSibling : null, + attributes : null, + parentNode : null, + childNodes : null, + ownerDocument : null, + nodeValue : null, + namespaceURI : null, + prefix : null, + localName : null, + // Modified in DOM Level 2: + insertBefore:function(newChild, refChild){//raises + return _insertBefore(this,newChild,refChild); + }, + replaceChild:function(newChild, oldChild){//raises + this.insertBefore(newChild,oldChild); + if(oldChild){ + this.removeChild(oldChild); + } + }, + removeChild:function(oldChild){ + return _removeChild(this,oldChild); + }, + appendChild:function(newChild){ + return this.insertBefore(newChild,null); + }, + hasChildNodes:function(){ + return this.firstChild != null; + }, + cloneNode:function(deep){ + return cloneNode(this.ownerDocument||this,this,deep); + }, + // Modified in DOM Level 2: + normalize:function(){ + var child = this.firstChild; + while(child){ + var next = child.nextSibling; + if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){ + this.removeChild(next); + child.appendData(next.data); + }else{ + child.normalize(); + child = next; + } + } + }, + // Introduced in DOM Level 2: + isSupported:function(feature, version){ + return this.ownerDocument.implementation.hasFeature(feature,version); + }, + // Introduced in DOM Level 2: + hasAttributes:function(){ + return this.attributes.length>0; + }, + lookupPrefix:function(namespaceURI){ + var el = this; + while(el){ + var map = el._nsMap; + //console.dir(map) + if(map){ + for(var n in map){ + if(map[n] == namespaceURI){ + return n; + } + } + } + el = el.nodeType == 2?el.ownerDocument : el.parentNode; + } + return null; + }, + // Introduced in DOM Level 3: + lookupNamespaceURI:function(prefix){ + var el = this; + while(el){ + var map = el._nsMap; + //console.dir(map) + if(map){ + if(prefix in map){ + return map[prefix] ; + } + } + el = el.nodeType == 2?el.ownerDocument : el.parentNode; + } + return null; + }, + // Introduced in DOM Level 3: + isDefaultNamespace:function(namespaceURI){ + var prefix = this.lookupPrefix(namespaceURI); + return prefix == null; + } +}; + + +function _xmlEncoder(c){ + return c == '<' && '<' || + c == '>' && '>' || + c == '&' && '&' || + c == '"' && '"' || + '&#'+c.charCodeAt()+';' +} + + +copy(NodeType,Node); +copy(NodeType,Node.prototype); + +/** + * @param callback return true for continue,false for break + * @return boolean true: break visit; + */ +function _visitNode(node,callback){ + if(callback(node)){ + return true; + } + if(node = node.firstChild){ + do{ + if(_visitNode(node,callback)){return true} + }while(node=node.nextSibling) + } +} + + + +function Document(){ +} +function _onAddAttribute(doc,el,newAttr){ + doc && doc._inc++; + var ns = newAttr.namespaceURI ; + if(ns == 'http://www.w3.org/2000/xmlns/'){ + //update namespace + el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value + } +} +function _onRemoveAttribute(doc,el,newAttr,remove){ + doc && doc._inc++; + var ns = newAttr.namespaceURI ; + if(ns == 'http://www.w3.org/2000/xmlns/'){ + //update namespace + delete el._nsMap[newAttr.prefix?newAttr.localName:''] + } +} +function _onUpdateChild(doc,el,newChild){ + if(doc && doc._inc){ + doc._inc++; + //update childNodes + var cs = el.childNodes; + if(newChild){ + cs[cs.length++] = newChild; + }else{ + //console.log(1) + var child = el.firstChild; + var i = 0; + while(child){ + cs[i++] = child; + child =child.nextSibling; + } + cs.length = i; + } + } +} + +/** + * attributes; + * children; + * + * writeable properties: + * nodeValue,Attr:value,CharacterData:data + * prefix + */ +function _removeChild(parentNode,child){ + var previous = child.previousSibling; + var next = child.nextSibling; + if(previous){ + previous.nextSibling = next; + }else{ + parentNode.firstChild = next + } + if(next){ + next.previousSibling = previous; + }else{ + parentNode.lastChild = previous; + } + _onUpdateChild(parentNode.ownerDocument,parentNode); + return child; +} +/** + * preformance key(refChild == null) + */ +function _insertBefore(parentNode,newChild,nextChild){ + var cp = newChild.parentNode; + if(cp){ + cp.removeChild(newChild);//remove and update + } + if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){ + var newFirst = newChild.firstChild; + if (newFirst == null) { + return newChild; + } + var newLast = newChild.lastChild; + }else{ + newFirst = newLast = newChild; + } + var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild; + + newFirst.previousSibling = pre; + newLast.nextSibling = nextChild; + + + if(pre){ + pre.nextSibling = newFirst; + }else{ + parentNode.firstChild = newFirst; + } + if(nextChild == null){ + parentNode.lastChild = newLast; + }else{ + nextChild.previousSibling = newLast; + } + do{ + newFirst.parentNode = parentNode; + }while(newFirst !== newLast && (newFirst= newFirst.nextSibling)) + _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode); + //console.log(parentNode.lastChild.nextSibling == null) + if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) { + newChild.firstChild = newChild.lastChild = null; + } + return newChild; +} +function _appendSingleChild(parentNode,newChild){ + var cp = newChild.parentNode; + if(cp){ + var pre = parentNode.lastChild; + cp.removeChild(newChild);//remove and update + var pre = parentNode.lastChild; + } + var pre = parentNode.lastChild; + newChild.parentNode = parentNode; + newChild.previousSibling = pre; + newChild.nextSibling = null; + if(pre){ + pre.nextSibling = newChild; + }else{ + parentNode.firstChild = newChild; + } + parentNode.lastChild = newChild; + _onUpdateChild(parentNode.ownerDocument,parentNode,newChild); + return newChild; + //console.log("__aa",parentNode.lastChild.nextSibling == null) +} +Document.prototype = { + //implementation : null, + nodeName : '#document', + nodeType : DOCUMENT_NODE, + doctype : null, + documentElement : null, + _inc : 1, + + insertBefore : function(newChild, refChild){//raises + if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){ + var child = newChild.firstChild; + while(child){ + var next = child.nextSibling; + this.insertBefore(child,refChild); + child = next; + } + return newChild; + } + if(this.documentElement == null && newChild.nodeType == 1){ + this.documentElement = newChild; + } + + return _insertBefore(this,newChild,refChild),(newChild.ownerDocument = this),newChild; + }, + removeChild : function(oldChild){ + if(this.documentElement == oldChild){ + this.documentElement = null; + } + return _removeChild(this,oldChild); + }, + // Introduced in DOM Level 2: + importNode : function(importedNode,deep){ + return importNode(this,importedNode,deep); + }, + // Introduced in DOM Level 2: + getElementById : function(id){ + var rtv = null; + _visitNode(this.documentElement,function(node){ + if(node.nodeType == 1){ + if(node.getAttribute('id') == id){ + rtv = node; + return true; + } + } + }) + return rtv; + }, + + //document factory method: + createElement : function(tagName){ + var node = new Element(); + node.ownerDocument = this; + node.nodeName = tagName; + node.tagName = tagName; + node.childNodes = new NodeList(); + var attrs = node.attributes = new NamedNodeMap(); + attrs._ownerElement = node; + return node; + }, + createDocumentFragment : function(){ + var node = new DocumentFragment(); + node.ownerDocument = this; + node.childNodes = new NodeList(); + return node; + }, + createTextNode : function(data){ + var node = new Text(); + node.ownerDocument = this; + node.appendData(data) + return node; + }, + createComment : function(data){ + var node = new Comment(); + node.ownerDocument = this; + node.appendData(data) + return node; + }, + createCDATASection : function(data){ + var node = new CDATASection(); + node.ownerDocument = this; + node.appendData(data) + return node; + }, + createProcessingInstruction : function(target,data){ + var node = new ProcessingInstruction(); + node.ownerDocument = this; + node.tagName = node.target = target; + node.nodeValue= node.data = data; + return node; + }, + createAttribute : function(name){ + var node = new Attr(); + node.ownerDocument = this; + node.name = name; + node.nodeName = name; + node.localName = name; + node.specified = true; + return node; + }, + createEntityReference : function(name){ + var node = new EntityReference(); + node.ownerDocument = this; + node.nodeName = name; + return node; + }, + // Introduced in DOM Level 2: + createElementNS : function(namespaceURI,qualifiedName){ + var node = new Element(); + var pl = qualifiedName.split(':'); + var attrs = node.attributes = new NamedNodeMap(); + node.childNodes = new NodeList(); + node.ownerDocument = this; + node.nodeName = qualifiedName; + node.tagName = qualifiedName; + node.namespaceURI = namespaceURI; + if(pl.length == 2){ + node.prefix = pl[0]; + node.localName = pl[1]; + }else{ + //el.prefix = null; + node.localName = qualifiedName; + } + attrs._ownerElement = node; + return node; + }, + // Introduced in DOM Level 2: + createAttributeNS : function(namespaceURI,qualifiedName){ + var node = new Attr(); + var pl = qualifiedName.split(':'); + node.ownerDocument = this; + node.nodeName = qualifiedName; + node.name = qualifiedName; + node.namespaceURI = namespaceURI; + node.specified = true; + if(pl.length == 2){ + node.prefix = pl[0]; + node.localName = pl[1]; + }else{ + //el.prefix = null; + node.localName = qualifiedName; + } + return node; + } +}; +_extends(Document,Node); + + +function Element() { + this._nsMap = {}; +}; +Element.prototype = { + nodeType : ELEMENT_NODE, + hasAttribute : function(name){ + return this.getAttributeNode(name)!=null; + }, + getAttribute : function(name){ + var attr = this.getAttributeNode(name); + return attr && attr.value || ''; + }, + getAttributeNode : function(name){ + return this.attributes.getNamedItem(name); + }, + setAttribute : function(name, value){ + var attr = this.ownerDocument.createAttribute(name); + attr.value = attr.nodeValue = "" + value; + this.setAttributeNode(attr) + }, + removeAttribute : function(name){ + var attr = this.getAttributeNode(name) + attr && this.removeAttributeNode(attr); + }, + + //four real opeartion method + appendChild:function(newChild){ + if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){ + return this.insertBefore(newChild,null); + }else{ + return _appendSingleChild(this,newChild); + } + }, + setAttributeNode : function(newAttr){ + return this.attributes.setNamedItem(newAttr); + }, + setAttributeNodeNS : function(newAttr){ + return this.attributes.setNamedItemNS(newAttr); + }, + removeAttributeNode : function(oldAttr){ + return this.attributes.removeNamedItem(oldAttr.nodeName); + }, + //get real attribute name,and remove it by removeAttributeNode + removeAttributeNS : function(namespaceURI, localName){ + var old = this.getAttributeNodeNS(namespaceURI, localName); + old && this.removeAttributeNode(old); + }, + + hasAttributeNS : function(namespaceURI, localName){ + return this.getAttributeNodeNS(namespaceURI, localName)!=null; + }, + getAttributeNS : function(namespaceURI, localName){ + var attr = this.getAttributeNodeNS(namespaceURI, localName); + return attr && attr.value || ''; + }, + setAttributeNS : function(namespaceURI, qualifiedName, value){ + var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName); + attr.value = attr.nodeValue = "" + value; + this.setAttributeNode(attr) + }, + getAttributeNodeNS : function(namespaceURI, localName){ + return this.attributes.getNamedItemNS(namespaceURI, localName); + }, + + getElementsByTagName : function(tagName){ + return new LiveNodeList(this,function(base){ + var ls = []; + _visitNode(base,function(node){ + if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){ + ls.push(node); + } + }); + return ls; + }); + }, + getElementsByTagNameNS : function(namespaceURI, localName){ + return new LiveNodeList(this,function(base){ + var ls = []; + _visitNode(base,function(node){ + if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){ + ls.push(node); + } + }); + return ls; + }); + } +}; +Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName; +Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS; + + +_extends(Element,Node); +function Attr() { +}; +Attr.prototype.nodeType = ATTRIBUTE_NODE; +_extends(Attr,Node); + + +function CharacterData() { +}; +CharacterData.prototype = { + data : '', + substringData : function(offset, count) { + return this.data.substring(offset, offset+count); + }, + appendData: function(text) { + text = this.data+text; + this.nodeValue = this.data = text; + this.length = text.length; + }, + insertData: function(offset,text) { + this.replaceData(offset,0,text); + + }, + appendChild:function(newChild){ + //if(!(newChild instanceof CharacterData)){ + throw new Error(ExceptionMessage[3]) + //} + return Node.prototype.appendChild.apply(this,arguments) + }, + deleteData: function(offset, count) { + this.replaceData(offset,count,""); + }, + replaceData: function(offset, count, text) { + var start = this.data.substring(0,offset); + var end = this.data.substring(offset+count); + text = start + text + end; + this.nodeValue = this.data = text; + this.length = text.length; + } +} +_extends(CharacterData,Node); +function Text() { +}; +Text.prototype = { + nodeName : "#text", + nodeType : TEXT_NODE, + splitText : function(offset) { + var text = this.data; + var newText = text.substring(offset); + text = text.substring(0, offset); + this.data = this.nodeValue = text; + this.length = text.length; + var newNode = this.ownerDocument.createTextNode(newText); + if(this.parentNode){ + this.parentNode.insertBefore(newNode, this.nextSibling); + } + return newNode; + } +} +_extends(Text,CharacterData); +function Comment() { +}; +Comment.prototype = { + nodeName : "#comment", + nodeType : COMMENT_NODE +} +_extends(Comment,CharacterData); + +function CDATASection() { +}; +CDATASection.prototype = { + nodeName : "#cdata-section", + nodeType : CDATA_SECTION_NODE +} +_extends(CDATASection,CharacterData); + + +function DocumentType() { +}; +DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE; +_extends(DocumentType,Node); + +function Notation() { +}; +Notation.prototype.nodeType = NOTATION_NODE; +_extends(Notation,Node); + +function Entity() { +}; +Entity.prototype.nodeType = ENTITY_NODE; +_extends(Entity,Node); + +function EntityReference() { +}; +EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE; +_extends(EntityReference,Node); + +function DocumentFragment() { +}; +DocumentFragment.prototype.nodeName = "#document-fragment"; +DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE; +_extends(DocumentFragment,Node); + + +function ProcessingInstruction() { +} +ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE; +_extends(ProcessingInstruction,Node); +function XMLSerializer(){} +XMLSerializer.prototype.serializeToString = function(node,attributeSorter){ + return node.toString(attributeSorter); +} +Node.prototype.toString =function(attributeSorter){ + var buf = []; + serializeToString(this,buf,attributeSorter); + return buf.join(''); +} +function serializeToString(node,buf,attributeSorter,isHTML){ + switch(node.nodeType){ + case ELEMENT_NODE: + var attrs = node.attributes; + var len = attrs.length; + var child = node.firstChild; + var nodeName = node.tagName; + isHTML = (htmlns === node.namespaceURI) ||isHTML + buf.push('<',nodeName); + if(attributeSorter){ + buf.sort.apply(attrs, attributeSorter); + } + for(var i=0;i'); + //if is cdata child node + if(isHTML && /^script$/i.test(nodeName)){ + if(child){ + buf.push(child.data); + } + }else{ + while(child){ + serializeToString(child,buf,attributeSorter,isHTML); + child = child.nextSibling; + } + } + buf.push(''); + }else{ + buf.push('/>'); + } + return; + case DOCUMENT_NODE: + case DOCUMENT_FRAGMENT_NODE: + var child = node.firstChild; + while(child){ + serializeToString(child,buf,attributeSorter,isHTML); + child = child.nextSibling; + } + return; + case ATTRIBUTE_NODE: + return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"'); + case TEXT_NODE: + return buf.push(node.data.replace(/[<&]/g,_xmlEncoder)); + case CDATA_SECTION_NODE: + return buf.push( ''); + case COMMENT_NODE: + return buf.push( ""); + case DOCUMENT_TYPE_NODE: + var pubid = node.publicId; + var sysid = node.systemId; + buf.push(''); + }else if(sysid && sysid!='.'){ + buf.push(' SYSTEM "',sysid,'">'); + }else{ + var sub = node.internalSubset; + if(sub){ + buf.push(" [",sub,"]"); + } + buf.push(">"); + } + return; + case PROCESSING_INSTRUCTION_NODE: + return buf.push( ""); + case ENTITY_REFERENCE_NODE: + return buf.push( '&',node.nodeName,';'); + //case ENTITY_NODE: + //case NOTATION_NODE: + default: + buf.push('??',node.nodeName); + } +} +function importNode(doc,node,deep){ + var node2; + switch (node.nodeType) { + case ELEMENT_NODE: + node2 = node.cloneNode(false); + node2.ownerDocument = doc; + //var attrs = node2.attributes; + //var len = attrs.length; + //for(var i=0;i=0.1.0 <0.2.0", + "_id": "xmldom@0.1.22", + "_inCache": true, + "_installable": true, + "_location": "/xmldom", + "_nodeVersion": "5.5.0", + "_npmUser": { + "email": "jindw@xidea.org", + "name": "jindw" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "name": "xmldom", + "raw": "xmldom@0.1.x", + "rawSpec": "0.1.x", + "scope": null, + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/plist" + ], + "_resolved": "http://registry.npmjs.org/xmldom/-/xmldom-0.1.22.tgz", + "_shasum": "10de4e5e964981f03c8cc72fadc08d14b6c3aa26", + "_shrinkwrap": null, + "_spec": "xmldom@0.1.x", + "_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/plist", + "author": { + "email": "jindw@xidea.org", + "name": "jindw", + "url": "http://www.xidea.org" + }, + "bugs": { + "email": "jindw@xidea.org", + "url": "http://github.com/jindw/xmldom/issues" + }, + "contributors": [ + { + "name": "Yaron Naveh", + "email": "yaronn01@gmail.com", + "url": "http://webservices20.blogspot.com/" + }, + { + "name": "Harutyun Amirjanyan", + "email": "amirjanyan@gmail.com", + "url": "https://github.com/nightwing" + }, + { + "name": "Alan Gutierrez", + "email": "alan@prettyrobots.com", + "url": "http://www.prettyrobots.com/" + } + ], + "dependencies": {}, + "description": "A W3C Standard XML DOM(Level2 CORE) implementation and parser(DOMParser/XMLSerializer).", + "devDependencies": { + "proof": "0.0.28" + }, + "directories": {}, + "dist": { + "shasum": "10de4e5e964981f03c8cc72fadc08d14b6c3aa26", + "tarball": "http://registry.npmjs.org/xmldom/-/xmldom-0.1.22.tgz" + }, + "engines": { + "node": ">=0.1" + }, + "gitHead": "29a83b315aef56c156602286b2d884a3b4c2521f", + "homepage": "https://github.com/jindw/xmldom", + "keywords": [ + "DOMParser", + "XMLSerializer", + "dom", + "javascript", + "parser", + "w3c", + "xml" + ], + "licenses": [ + { + "type": "LGPL", + "url": "http://www.gnu.org/licenses/lgpl.html", + "MIT": "http://opensource.org/licenses/MIT" + } + ], + "main": "./dom-parser.js", + "maintainers": [ + { + "name": "jindw", + "email": "jindw@xidea.org" + }, + { + "name": "yaron", + "email": "yaronn01@gmail.com" + }, + { + "name": "bigeasy", + "email": "alan@prettyrobots.com" + }, + { + "name": "kethinov", + "email": "kethinov@gmail.com" + }, + { + "name": "jinjinyun", + "email": "jinyun.jin@gmail.com" + } + ], + "name": "xmldom", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/jindw/xmldom.git" + }, + "scripts": { + "test": "proof platform win32 && proof test */*/*.t.js || t/test" + }, + "version": "0.1.22" +} diff --git a/platforms/android/cordova/node_modules/xmldom/readme.md b/platforms/android/cordova/node_modules/xmldom/readme.md new file mode 100644 index 0000000..f832c44 --- /dev/null +++ b/platforms/android/cordova/node_modules/xmldom/readme.md @@ -0,0 +1,219 @@ +# XMLDOM [![Build Status](https://secure.travis-ci.org/bigeasy/xmldom.png?branch=master)](http://travis-ci.org/bigeasy/xmldom) [![Coverage Status](https://coveralls.io/repos/bigeasy/xmldom/badge.png?branch=master)](https://coveralls.io/r/bigeasy/xmldom) [![NPM version](https://badge.fury.io/js/xmldom.png)](http://badge.fury.io/js/xmldom) + +A JavaScript implementation of W3C DOM for Node.js, Rhino and the browser. Fully +compatible with `W3C DOM level2`; and some compatible with `level3`. Supports +`DOMParser` and `XMLSerializer` interface such as in browser. + +Install: +------- +>npm install xmldom + +Example: +==== +```javascript +var DOMParser = require('xmldom').DOMParser; +var doc = new DOMParser().parseFromString( + '\n'+ + '\ttest\n'+ + '\t\n'+ + '\t\n'+ + '' + ,'text/xml'); +doc.documentElement.setAttribute('x','y'); +doc.documentElement.setAttributeNS('./lite','c:x','y2'); +var nsAttr = doc.documentElement.getAttributeNS('./lite','x') +console.info(nsAttr) +console.info(doc) +``` +API Reference +===== + + * [DOMParser](https://developer.mozilla.org/en/DOMParser): + + ```javascript + parseFromString(xmlsource,mimeType) + ``` + * **options extension** _by xmldom_(not BOM standard!!) + + ```javascript + //added the options argument + new DOMParser(options) + + //errorHandler is supported + new DOMParser({ + /** + * locator is always need for error position info + */ + locator:{}, + /** + * you can override the errorHandler for xml parser + * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html + */ + errorHandler:{warning:function(w){console.warn(w)},error:callback,fatalError:callback} + //only callback model + //errorHandler:function(level,msg){console.log(level,msg)} + }) + + ``` + + * [XMLSerializer](https://developer.mozilla.org/en/XMLSerializer) + + ```javascript + serializeToString(node) + ``` +DOM level2 method and attribute: +------ + + * [Node](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247) + + attribute: + nodeValue|prefix + readonly attribute: + nodeName|nodeType|parentNode|childNodes|firstChild|lastChild|previousSibling|nextSibling|attributes|ownerDocument|namespaceURI|localName + method: + insertBefore(newChild, refChild) + replaceChild(newChild, oldChild) + removeChild(oldChild) + appendChild(newChild) + hasChildNodes() + cloneNode(deep) + normalize() + isSupported(feature, version) + hasAttributes() + + * [DOMImplementation](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-102161490) + + method: + hasFeature(feature, version) + createDocumentType(qualifiedName, publicId, systemId) + createDocument(namespaceURI, qualifiedName, doctype) + + * [Document](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#i-Document) : Node + + readonly attribute: + doctype|implementation|documentElement + method: + createElement(tagName) + createDocumentFragment() + createTextNode(data) + createComment(data) + createCDATASection(data) + createProcessingInstruction(target, data) + createAttribute(name) + createEntityReference(name) + getElementsByTagName(tagname) + importNode(importedNode, deep) + createElementNS(namespaceURI, qualifiedName) + createAttributeNS(namespaceURI, qualifiedName) + getElementsByTagNameNS(namespaceURI, localName) + getElementById(elementId) + + * [DocumentFragment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-B63ED1A3) : Node + * [Element](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-745549614) : Node + + readonly attribute: + tagName + method: + getAttribute(name) + setAttribute(name, value) + removeAttribute(name) + getAttributeNode(name) + setAttributeNode(newAttr) + removeAttributeNode(oldAttr) + getElementsByTagName(name) + getAttributeNS(namespaceURI, localName) + setAttributeNS(namespaceURI, qualifiedName, value) + removeAttributeNS(namespaceURI, localName) + getAttributeNodeNS(namespaceURI, localName) + setAttributeNodeNS(newAttr) + getElementsByTagNameNS(namespaceURI, localName) + hasAttribute(name) + hasAttributeNS(namespaceURI, localName) + + * [Attr](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-637646024) : Node + + attribute: + value + readonly attribute: + name|specified|ownerElement + + * [NodeList](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177) + + readonly attribute: + length + method: + item(index) + + * [NamedNodeMap](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1780488922) + + readonly attribute: + length + method: + getNamedItem(name) + setNamedItem(arg) + removeNamedItem(name) + item(index) + getNamedItemNS(namespaceURI, localName) + setNamedItemNS(arg) + removeNamedItemNS(namespaceURI, localName) + + * [CharacterData](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-FF21A306) : Node + + method: + substringData(offset, count) + appendData(arg) + insertData(offset, arg) + deleteData(offset, count) + replaceData(offset, count, arg) + + * [Text](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1312295772) : CharacterData + + method: + splitText(offset) + + * [CDATASection](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-667469212) + * [Comment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1728279322) : CharacterData + + * [DocumentType](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-412266927) + + readonly attribute: + name|entities|notations|publicId|systemId|internalSubset + + * Notation : Node + + readonly attribute: + publicId|systemId + + * Entity : Node + + readonly attribute: + publicId|systemId|notationName + + * EntityReference : Node + * ProcessingInstruction : Node + + attribute: + data + readonly attribute: + target + +DOM level 3 support: +----- + + * [Node](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-textContent) + + attribute: + textContent + method: + isDefaultNamespace(namespaceURI){ + lookupNamespaceURI(prefix) + +DOM extension by xmldom +--- + * [Node] Source position extension; + + attribute: + //Numbered starting from '1' + lineNumber + //Numbered starting from '1' + columnNumber diff --git a/platforms/android/cordova/node_modules/xmldom/sax.js b/platforms/android/cordova/node_modules/xmldom/sax.js new file mode 100644 index 0000000..e11bdfb --- /dev/null +++ b/platforms/android/cordova/node_modules/xmldom/sax.js @@ -0,0 +1,586 @@ +//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] +//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] +//[5] Name ::= NameStartChar (NameChar)* +var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF +var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\u00B7\u0300-\u036F\\u203F-\u2040]"); +var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$'); +//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/ +//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',') + +//S_TAG, S_ATTR, S_EQ, S_V +//S_ATTR_S, S_E, S_S, S_C +var S_TAG = 0;//tag name offerring +var S_ATTR = 1;//attr name offerring +var S_ATTR_S=2;//attr name end and space offer +var S_EQ = 3;//=space? +var S_V = 4;//attr value(no quot value only) +var S_E = 5;//attr value end and no space(quot end) +var S_S = 6;//(attr value end || tag end ) && (space offer) +var S_C = 7;//closed el + +function XMLReader(){ + +} + +XMLReader.prototype = { + parse:function(source,defaultNSMap,entityMap){ + var domBuilder = this.domBuilder; + domBuilder.startDocument(); + _copy(defaultNSMap ,defaultNSMap = {}) + parse(source,defaultNSMap,entityMap, + domBuilder,this.errorHandler); + domBuilder.endDocument(); + } +} +function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){ + function fixedFromCharCode(code) { + // String.prototype.fromCharCode does not supports + // > 2 bytes unicode chars directly + if (code > 0xffff) { + code -= 0x10000; + var surrogate1 = 0xd800 + (code >> 10) + , surrogate2 = 0xdc00 + (code & 0x3ff); + + return String.fromCharCode(surrogate1, surrogate2); + } else { + return String.fromCharCode(code); + } + } + function entityReplacer(a){ + var k = a.slice(1,-1); + if(k in entityMap){ + return entityMap[k]; + }else if(k.charAt(0) === '#'){ + return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x'))) + }else{ + errorHandler.error('entity not found:'+a); + return a; + } + } + function appendText(end){//has some bugs + if(end>start){ + var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer); + locator&&position(start); + domBuilder.characters(xt,0,end-start); + start = end + } + } + function position(p,m){ + while(p>=lineEnd && (m = linePattern.exec(source))){ + lineStart = m.index; + lineEnd = lineStart + m[0].length; + locator.lineNumber++; + //console.log('line++:',locator,startPos,endPos) + } + locator.columnNumber = p-lineStart+1; + } + var lineStart = 0; + var lineEnd = 0; + var linePattern = /.+(?:\r\n?|\n)|.*$/g + var locator = domBuilder.locator; + + var parseStack = [{currentNSMap:defaultNSMapCopy}] + var closeMap = {}; + var start = 0; + while(true){ + try{ + var tagStart = source.indexOf('<',start); + if(tagStart<0){ + if(!source.substr(start).match(/^\s*$/)){ + var doc = domBuilder.document; + var text = doc.createTextNode(source.substr(start)); + doc.appendChild(text); + domBuilder.currentElement = text; + } + return; + } + if(tagStart>start){ + appendText(tagStart); + } + switch(source.charAt(tagStart+1)){ + case '/': + var end = source.indexOf('>',tagStart+3); + var tagName = source.substring(tagStart+2,end); + var config = parseStack.pop(); + var localNSMap = config.localNSMap; + if(config.tagName != tagName){ + errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName ); + } + domBuilder.endElement(config.uri,config.localName,tagName); + if(localNSMap){ + for(var prefix in localNSMap){ + domBuilder.endPrefixMapping(prefix) ; + } + } + end++; + break; + // end elment + case '?':// + locator&&position(tagStart); + end = parseInstruction(source,tagStart,domBuilder); + break; + case '!':// start){ + start = end; + }else{ + //TODO: 这里有å¯èƒ½sax回退,有ä½ç½®é”™è¯¯é£Žé™© + appendText(Math.max(tagStart,start)+1); + } + } +} +function copyLocator(f,t){ + t.lineNumber = f.lineNumber; + t.columnNumber = f.columnNumber; + return t; +} + +/** + * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack); + * @return end of the elementStartPart(end of elementEndPart for selfClosed el) + */ +function parseElementStartPart(source,start,el,entityReplacer,errorHandler){ + var attrName; + var value; + var p = ++start; + var s = S_TAG;//status + while(true){ + var c = source.charAt(p); + switch(c){ + case '=': + if(s === S_ATTR){//attrName + attrName = source.slice(start,p); + s = S_EQ; + }else if(s === S_ATTR_S){ + s = S_EQ; + }else{ + //fatalError: equal must after attrName or space after attrName + throw new Error('attribute equal must after attrName'); + } + break; + case '\'': + case '"': + if(s === S_EQ){//equal + start = p+1; + p = source.indexOf(c,start) + if(p>0){ + value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + el.add(attrName,value,start-1); + s = S_E; + }else{ + //fatalError: no end quot match + throw new Error('attribute value no end \''+c+'\' match'); + } + }else if(s == S_V){ + value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + //console.log(attrName,value,start,p) + el.add(attrName,value,start); + //console.dir(el) + errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!'); + start = p+1; + s = S_E + }else{ + //fatalError: no equal before + throw new Error('attribute value must after "="'); + } + break; + case '/': + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p)); + case S_E: + case S_S: + case S_C: + s = S_C; + el.closed = true; + case S_V: + case S_ATTR: + case S_ATTR_S: + break; + //case S_EQ: + default: + throw new Error("attribute invalid close char('/')") + } + break; + case ''://end document + //throw new Error('unexpected end of input') + errorHandler.error('unexpected end of input'); + case '>': + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p)); + case S_E: + case S_S: + case S_C: + break;//normal + case S_V://Compatible state + case S_ATTR: + value = source.slice(start,p); + if(value.slice(-1) === '/'){ + el.closed = true; + value = value.slice(0,-1) + } + case S_ATTR_S: + if(s === S_ATTR_S){ + value = attrName; + } + if(s == S_V){ + errorHandler.warning('attribute "'+value+'" missed quot(")!!'); + el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start) + }else{ + errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!') + el.add(value,value,start) + } + break; + case S_EQ: + throw new Error('attribute value missed!!'); + } +// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName)) + return p; + /*xml space '\x20' | #x9 | #xD | #xA; */ + case '\u0080': + c = ' '; + default: + if(c<= ' '){//space + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p));//tagName + s = S_S; + break; + case S_ATTR: + attrName = source.slice(start,p) + s = S_ATTR_S; + break; + case S_V: + var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + errorHandler.warning('attribute "'+value+'" missed quot(")!!'); + el.add(attrName,value,start) + case S_E: + s = S_S; + break; + //case S_S: + //case S_EQ: + //case S_ATTR_S: + // void();break; + //case S_C: + //ignore warning + } + }else{//not space +//S_TAG, S_ATTR, S_EQ, S_V +//S_ATTR_S, S_E, S_S, S_C + switch(s){ + //case S_TAG:void();break; + //case S_ATTR:void();break; + //case S_V:void();break; + case S_ATTR_S: + errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!') + el.add(attrName,attrName,start); + start = p; + s = S_ATTR; + break; + case S_E: + errorHandler.warning('attribute space is required"'+attrName+'"!!') + case S_S: + s = S_ATTR; + start = p; + break; + case S_EQ: + s = S_V; + start = p; + break; + case S_C: + throw new Error("elements closed character '/' and '>' must be connected to"); + } + } + } + p++; + } +} +/** + * @return end of the elementStartPart(end of elementEndPart for selfClosed el) + */ +function appendElement(el,domBuilder,parseStack){ + var tagName = el.tagName; + var localNSMap = null; + var currentNSMap = parseStack[parseStack.length-1].currentNSMap; + var i = el.length; + while(i--){ + var a = el[i]; + var qName = a.qName; + var value = a.value; + var nsp = qName.indexOf(':'); + if(nsp>0){ + var prefix = a.prefix = qName.slice(0,nsp); + var localName = qName.slice(nsp+1); + var nsPrefix = prefix === 'xmlns' && localName + }else{ + localName = qName; + prefix = null + nsPrefix = qName === 'xmlns' && '' + } + //can not set prefix,because prefix !== '' + a.localName = localName ; + //prefix == null for no ns prefix attribute + if(nsPrefix !== false){//hack!! + if(localNSMap == null){ + localNSMap = {} + //console.log(currentNSMap,0) + _copy(currentNSMap,currentNSMap={}) + //console.log(currentNSMap,1) + } + currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value; + a.uri = 'http://www.w3.org/2000/xmlns/' + domBuilder.startPrefixMapping(nsPrefix, value) + } + } + var i = el.length; + while(i--){ + a = el[i]; + var prefix = a.prefix; + if(prefix){//no prefix attribute has no namespace + if(prefix === 'xml'){ + a.uri = 'http://www.w3.org/XML/1998/namespace'; + }if(prefix !== 'xmlns'){ + a.uri = currentNSMap[prefix] + + //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)} + } + } + } + var nsp = tagName.indexOf(':'); + if(nsp>0){ + prefix = el.prefix = tagName.slice(0,nsp); + localName = el.localName = tagName.slice(nsp+1); + }else{ + prefix = null;//important!! + localName = el.localName = tagName; + } + //no prefix element has default namespace + var ns = el.uri = currentNSMap[prefix || '']; + domBuilder.startElement(ns,localName,tagName,el); + //endPrefixMapping and startPrefixMapping have not any help for dom builder + //localNSMap = null + if(el.closed){ + domBuilder.endElement(ns,localName,tagName); + if(localNSMap){ + for(prefix in localNSMap){ + domBuilder.endPrefixMapping(prefix) + } + } + }else{ + el.currentNSMap = currentNSMap; + el.localNSMap = localNSMap; + parseStack.push(el); + } +} +function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){ + if(/^(?:script|textarea)$/i.test(tagName)){ + var elEndStart = source.indexOf('',elStartEnd); + var text = source.substring(elStartEnd+1,elEndStart); + if(/[&<]/.test(text)){ + if(/^script$/i.test(tagName)){ + //if(!/\]\]>/.test(text)){ + //lexHandler.startCDATA(); + domBuilder.characters(text,0,text.length); + //lexHandler.endCDATA(); + return elEndStart; + //} + }//}else{//text area + text = text.replace(/&#?\w+;/g,entityReplacer); + domBuilder.characters(text,0,text.length); + return elEndStart; + //} + + } + } + return elStartEnd+1; +} +function fixSelfClosed(source,elStartEnd,tagName,closeMap){ + //if(tagName in closeMap){ + var pos = closeMap[tagName]; + if(pos == null){ + //console.log(tagName) + pos = closeMap[tagName] = source.lastIndexOf('') + } + return pos',start+4); + //append comment source.substring(4,end)// + + + + + + Cordova tests + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    Log
    +
    +
    + + diff --git a/platforms/android/platform_www/cdvtests/jasmine-2.2.0/boot.js b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/boot.js new file mode 100755 index 0000000..e8ddd55 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/boot.js @@ -0,0 +1,121 @@ +/** + Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project. + + If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms. + + The location of `boot.js` can be specified and/or overridden in `jasmine.yml`. + + [jasmine-gem]: http://github.com/pivotal/jasmine-gem + */ + +(function() { + + /** + * ## Require & Instantiate + * + * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference. + */ + window.jasmine = jasmineRequire.core(jasmineRequire); + + /** + * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference. + */ + jasmineRequire.html(jasmine); + + /** + * Create the Jasmine environment. This is used to run all specs in a project. + */ + var env = jasmine.getEnv(); + + /** + * ## The Global Interface + * + * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged. + */ + var jasmineInterface = jasmineRequire.interface(jasmine, env); + + /** + * Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`. + */ + if (typeof window == "undefined" && typeof exports == "object") { + extend(exports, jasmineInterface); + } else { + extend(window, jasmineInterface); + } + + /** + * ## Runner Parameters + * + * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface. + */ + + var queryString = new jasmine.QueryString({ + getWindowLocation: function() { return window.location; } + }); + + var catchingExceptions = queryString.getParam("catch"); + env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions); + + /** + * ## Reporters + * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any). + */ + var htmlReporter = new jasmine.HtmlReporter({ + env: env, + onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); }, + addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); }, + getContainer: function() { return document.body; }, + createElement: function() { return document.createElement.apply(document, arguments); }, + createTextNode: function() { return document.createTextNode.apply(document, arguments); }, + timer: new jasmine.Timer() + }); + + /** + * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript. + */ + env.addReporter(jasmineInterface.jsApiReporter); + env.addReporter(htmlReporter); + + /** + * Filter which specs will be run by matching the start of the full name against the `spec` query param. + */ + var specFilter = new jasmine.HtmlSpecFilter({ + filterString: function() { return queryString.getParam("spec"); } + }); + + env.specFilter = function(spec) { + return specFilter.matches(spec.getFullName()); + }; + + /** + * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack. + */ + window.setTimeout = window.setTimeout; + window.setInterval = window.setInterval; + window.clearTimeout = window.clearTimeout; + window.clearInterval = window.clearInterval; + + /** + * ## Execution + * + * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded. + */ + var currentWindowOnload = window.onload; + + window.onload = function() { + if (currentWindowOnload) { + currentWindowOnload(); + } + htmlReporter.initialize(); + env.execute(); + }; + + /** + * Helper function for readability above. + */ + function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; + } + +}()); diff --git a/platforms/android/platform_www/cdvtests/jasmine-2.2.0/console.js b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/console.js new file mode 100755 index 0000000..e154806 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/console.js @@ -0,0 +1,190 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +function getJasmineRequireObj() { + if (typeof module !== 'undefined' && module.exports) { + return exports; + } else { + window.jasmineRequire = window.jasmineRequire || {}; + return window.jasmineRequire; + } +} + +getJasmineRequireObj().console = function(jRequire, j$) { + j$.ConsoleReporter = jRequire.ConsoleReporter(); +}; + +getJasmineRequireObj().ConsoleReporter = function() { + + var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } + }; + + function ConsoleReporter(options) { + var print = options.print, + showColors = options.showColors || false, + onComplete = options.onComplete || function() {}, + timer = options.timer || noopTimer, + specCount, + failureCount, + failedSpecs = [], + pendingCount, + ansi = { + green: '\x1B[32m', + red: '\x1B[31m', + yellow: '\x1B[33m', + none: '\x1B[0m' + }, + failedSuites = []; + + print('ConsoleReporter is deprecated and will be removed in a future version.'); + + this.jasmineStarted = function() { + specCount = 0; + failureCount = 0; + pendingCount = 0; + print('Started'); + printNewline(); + timer.start(); + }; + + this.jasmineDone = function() { + printNewline(); + for (var i = 0; i < failedSpecs.length; i++) { + specFailureDetails(failedSpecs[i]); + } + + if(specCount > 0) { + printNewline(); + + var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' + + failureCount + ' ' + plural('failure', failureCount); + + if (pendingCount) { + specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount); + } + + print(specCounts); + } else { + print('No specs found'); + } + + printNewline(); + var seconds = timer.elapsed() / 1000; + print('Finished in ' + seconds + ' ' + plural('second', seconds)); + printNewline(); + + for(i = 0; i < failedSuites.length; i++) { + suiteFailureDetails(failedSuites[i]); + } + + onComplete(failureCount === 0); + }; + + this.specDone = function(result) { + specCount++; + + if (result.status == 'pending') { + pendingCount++; + print(colored('yellow', '*')); + return; + } + + if (result.status == 'passed') { + print(colored('green', '.')); + return; + } + + if (result.status == 'failed') { + failureCount++; + failedSpecs.push(result); + print(colored('red', 'F')); + } + }; + + this.suiteDone = function(result) { + if (result.failedExpectations && result.failedExpectations.length > 0) { + failureCount++; + failedSuites.push(result); + } + }; + + return this; + + function printNewline() { + print('\n'); + } + + function colored(color, str) { + return showColors ? (ansi[color] + str + ansi.none) : str; + } + + function plural(str, count) { + return count == 1 ? str : str + 's'; + } + + function repeat(thing, times) { + var arr = []; + for (var i = 0; i < times; i++) { + arr.push(thing); + } + return arr; + } + + function indent(str, spaces) { + var lines = (str || '').split('\n'); + var newArr = []; + for (var i = 0; i < lines.length; i++) { + newArr.push(repeat(' ', spaces).join('') + lines[i]); + } + return newArr.join('\n'); + } + + function specFailureDetails(result) { + printNewline(); + print(result.fullName); + + for (var i = 0; i < result.failedExpectations.length; i++) { + var failedExpectation = result.failedExpectations[i]; + printNewline(); + print(indent(failedExpectation.message, 2)); + print(indent(failedExpectation.stack, 2)); + } + + printNewline(); + } + + function suiteFailureDetails(result) { + for (var i = 0; i < result.failedExpectations.length; i++) { + printNewline(); + print(colored('red', 'An error was thrown in an afterAll')); + printNewline(); + print(colored('red', 'AfterAll ' + result.failedExpectations[i].message)); + + } + printNewline(); + } + } + + return ConsoleReporter; +}; diff --git a/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine-html.js b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine-html.js new file mode 100755 index 0000000..bee5a04 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine-html.js @@ -0,0 +1,416 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +jasmineRequire.html = function(j$) { + j$.ResultsNode = jasmineRequire.ResultsNode(); + j$.HtmlReporter = jasmineRequire.HtmlReporter(j$); + j$.QueryString = jasmineRequire.QueryString(); + j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter(); +}; + +jasmineRequire.HtmlReporter = function(j$) { + + var noopTimer = { + start: function() {}, + elapsed: function() { return 0; } + }; + + function HtmlReporter(options) { + var env = options.env || {}, + getContainer = options.getContainer, + createElement = options.createElement, + createTextNode = options.createTextNode, + onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {}, + addToExistingQueryString = options.addToExistingQueryString || defaultQueryString, + timer = options.timer || noopTimer, + results = [], + specsExecuted = 0, + failureCount = 0, + pendingSpecCount = 0, + htmlReporterMain, + symbols, + failedSuites = []; + + this.initialize = function() { + clearPrior(); + htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'}, + createDom('div', {className: 'banner'}, + createDom('a', {className: 'title', href: 'http://jasmine.github.io/', target: '_blank'}), + createDom('span', {className: 'version'}, j$.version) + ), + createDom('ul', {className: 'symbol-summary'}), + createDom('div', {className: 'alert'}), + createDom('div', {className: 'results'}, + createDom('div', {className: 'failures'}) + ) + ); + getContainer().appendChild(htmlReporterMain); + + symbols = find('.symbol-summary'); + }; + + var totalSpecsDefined; + this.jasmineStarted = function(options) { + totalSpecsDefined = options.totalSpecsDefined || 0; + timer.start(); + }; + + var summary = createDom('div', {className: 'summary'}); + + var topResults = new j$.ResultsNode({}, '', null), + currentParent = topResults; + + this.suiteStarted = function(result) { + currentParent.addChild(result, 'suite'); + currentParent = currentParent.last(); + }; + + this.suiteDone = function(result) { + if (result.status == 'failed') { + failedSuites.push(result); + } + + if (currentParent == topResults) { + return; + } + + currentParent = currentParent.parent; + }; + + this.specStarted = function(result) { + currentParent.addChild(result, 'spec'); + }; + + var failures = []; + this.specDone = function(result) { + if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') { + console.error('Spec \'' + result.fullName + '\' has no expectations.'); + } + + if (result.status != 'disabled') { + specsExecuted++; + } + + symbols.appendChild(createDom('li', { + className: noExpectations(result) ? 'empty' : result.status, + id: 'spec_' + result.id, + title: result.fullName + } + )); + + if (result.status == 'failed') { + failureCount++; + + var failure = + createDom('div', {className: 'spec-detail failed'}, + createDom('div', {className: 'description'}, + createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName) + ), + createDom('div', {className: 'messages'}) + ); + var messages = failure.childNodes[1]; + + for (var i = 0; i < result.failedExpectations.length; i++) { + var expectation = result.failedExpectations[i]; + messages.appendChild(createDom('div', {className: 'result-message'}, expectation.message)); + messages.appendChild(createDom('div', {className: 'stack-trace'}, expectation.stack)); + } + + failures.push(failure); + } + + if (result.status == 'pending') { + pendingSpecCount++; + } + }; + + this.jasmineDone = function() { + var banner = find('.banner'); + banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's')); + + var alert = find('.alert'); + + alert.appendChild(createDom('span', { className: 'exceptions' }, + createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions'), + createDom('input', { + className: 'raise', + id: 'raise-exceptions', + type: 'checkbox' + }) + )); + var checkbox = find('#raise-exceptions'); + + checkbox.checked = !env.catchingExceptions(); + checkbox.onclick = onRaiseExceptionsClick; + + if (specsExecuted < totalSpecsDefined) { + var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all'; + alert.appendChild( + createDom('span', {className: 'bar skipped'}, + createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage) + ) + ); + } + var statusBarMessage = ''; + var statusBarClassName = 'bar '; + + if (totalSpecsDefined > 0) { + statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount); + if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); } + statusBarClassName += (failureCount > 0) ? 'failed' : 'passed'; + } else { + statusBarClassName += 'skipped'; + statusBarMessage += 'No specs found'; + } + + alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage)); + + for(i = 0; i < failedSuites.length; i++) { + var failedSuite = failedSuites[i]; + for(var j = 0; j < failedSuite.failedExpectations.length; j++) { + var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message; + var errorBarClassName = 'bar errored'; + alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage)); + } + } + + var results = find('.results'); + results.appendChild(summary); + + summaryList(topResults, summary); + + function summaryList(resultsTree, domParent) { + var specListNode; + for (var i = 0; i < resultsTree.children.length; i++) { + var resultNode = resultsTree.children[i]; + if (resultNode.type == 'suite') { + var suiteListNode = createDom('ul', {className: 'suite', id: 'suite-' + resultNode.result.id}, + createDom('li', {className: 'suite-detail'}, + createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description) + ) + ); + + summaryList(resultNode, suiteListNode); + domParent.appendChild(suiteListNode); + } + if (resultNode.type == 'spec') { + if (domParent.getAttribute('class') != 'specs') { + specListNode = createDom('ul', {className: 'specs'}); + domParent.appendChild(specListNode); + } + var specDescription = resultNode.result.description; + if(noExpectations(resultNode.result)) { + specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription; + } + if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') { + specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason; + } + specListNode.appendChild( + createDom('li', { + className: resultNode.result.status, + id: 'spec-' + resultNode.result.id + }, + createDom('a', {href: specHref(resultNode.result)}, specDescription) + ) + ); + } + } + } + + if (failures.length) { + alert.appendChild( + createDom('span', {className: 'menu bar spec-list'}, + createDom('span', {}, 'Spec List | '), + createDom('a', {className: 'failures-menu', href: '#'}, 'Failures'))); + alert.appendChild( + createDom('span', {className: 'menu bar failure-list'}, + createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'), + createDom('span', {}, ' | Failures '))); + + find('.failures-menu').onclick = function() { + setMenuModeTo('failure-list'); + }; + find('.spec-list-menu').onclick = function() { + setMenuModeTo('spec-list'); + }; + + setMenuModeTo('failure-list'); + + var failureNode = find('.failures'); + for (var i = 0; i < failures.length; i++) { + failureNode.appendChild(failures[i]); + } + } + }; + + return this; + + function find(selector) { + return getContainer().querySelector('.jasmine_html-reporter ' + selector); + } + + function clearPrior() { + // return the reporter + var oldReporter = find(''); + + if(oldReporter) { + getContainer().removeChild(oldReporter); + } + } + + function createDom(type, attrs, childrenVarArgs) { + var el = createElement(type); + + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i]; + + if (typeof child === 'string') { + el.appendChild(createTextNode(child)); + } else { + if (child) { + el.appendChild(child); + } + } + } + + for (var attr in attrs) { + if (attr == 'className') { + el[attr] = attrs[attr]; + } else { + el.setAttribute(attr, attrs[attr]); + } + } + + return el; + } + + function pluralize(singular, count) { + var word = (count == 1 ? singular : singular + 's'); + + return '' + count + ' ' + word; + } + + function specHref(result) { + return addToExistingQueryString('spec', result.fullName); + } + + function defaultQueryString(key, value) { + return '?' + key + '=' + value; + } + + function setMenuModeTo(mode) { + htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode); + } + + function noExpectations(result) { + return (result.failedExpectations.length + result.passedExpectations.length) === 0 && + result.status === 'passed'; + } + } + + return HtmlReporter; +}; + +jasmineRequire.HtmlSpecFilter = function() { + function HtmlSpecFilter(options) { + var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + var filterPattern = new RegExp(filterString); + + this.matches = function(specName) { + return filterPattern.test(specName); + }; + } + + return HtmlSpecFilter; +}; + +jasmineRequire.ResultsNode = function() { + function ResultsNode(result, type, parent) { + this.result = result; + this.type = type; + this.parent = parent; + + this.children = []; + + this.addChild = function(result, type) { + this.children.push(new ResultsNode(result, type, this)); + }; + + this.last = function() { + return this.children[this.children.length - 1]; + }; + } + + return ResultsNode; +}; + +jasmineRequire.QueryString = function() { + function QueryString(options) { + + this.navigateWithNewParam = function(key, value) { + options.getWindowLocation().search = this.fullStringWithNewParam(key, value); + }; + + this.fullStringWithNewParam = function(key, value) { + var paramMap = queryStringToParamMap(); + paramMap[key] = value; + return toQueryString(paramMap); + }; + + this.getParam = function(key) { + return queryStringToParamMap()[key]; + }; + + return this; + + function toQueryString(paramMap) { + var qStrPairs = []; + for (var prop in paramMap) { + qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop])); + } + return '?' + qStrPairs.join('&'); + } + + function queryStringToParamMap() { + var paramStr = options.getWindowLocation().search.substring(1), + params = [], + paramMap = {}; + + if (paramStr.length > 0) { + params = paramStr.split('&'); + for (var i = 0; i < params.length; i++) { + var p = params[i].split('='); + var value = decodeURIComponent(p[1]); + if (value === 'true' || value === 'false') { + value = JSON.parse(value); + } + paramMap[decodeURIComponent(p[0])] = value; + } + } + + return paramMap; + } + + } + + return QueryString; +}; diff --git a/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine.css b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine.css new file mode 100755 index 0000000..ecc5f5e --- /dev/null +++ b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine.css @@ -0,0 +1,62 @@ +body { overflow-y: scroll; } + +.jasmine_html-reporter { background-color: #eee; padding: 5px; margin: -8px; font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333; } +.jasmine_html-reporter a { text-decoration: none; } +.jasmine_html-reporter a:hover { text-decoration: underline; } +.jasmine_html-reporter p, .jasmine_html-reporter h1, .jasmine_html-reporter h2, .jasmine_html-reporter h3, .jasmine_html-reporter h4, .jasmine_html-reporter h5, .jasmine_html-reporter h6 { margin: 0; line-height: 14px; } +.jasmine_html-reporter .banner, .jasmine_html-reporter .symbol-summary, .jasmine_html-reporter .summary, .jasmine_html-reporter .result-message, .jasmine_html-reporter .spec .description, .jasmine_html-reporter .spec-detail .description, .jasmine_html-reporter .alert .bar, .jasmine_html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; } +.jasmine_html-reporter .banner { position: relative; } +.jasmine_html-reporter .banner .title { background: url('data:image/png;base64,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') no-repeat; background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICB3aWR0aD0iNjgxLjk2MjUyIgogICBoZWlnaHQ9IjE4Ny41IgogICBpZD0ic3ZnMiIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhOCI+PHJkZjpSREY+PGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMKICAgICBpZD0iZGVmczYiPjxjbGlwUGF0aAogICAgICAgaWQ9ImNsaXBQYXRoMTgiPjxwYXRoCiAgICAgICAgIGQ9Ik0gMCwxNTAwIDAsMCBsIDU0NTUuNzQsMCAwLDE1MDAgTCAwLDE1MDAgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgyMCIgLz48L2NsaXBQYXRoPjwvZGVmcz48ZwogICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMjUsMCwwLC0xLjI1LDAsMTg3LjUpIgogICAgIGlkPSJnMTAiPjxnCiAgICAgICB0cmFuc2Zvcm09InNjYWxlKDAuMSwwLjEpIgogICAgICAgaWQ9ImcxMiI+PGcKICAgICAgICAgaWQ9ImcxNCI+PGcKICAgICAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGgxOCkiCiAgICAgICAgICAgaWQ9ImcxNiI+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTU0NCw1OTkuNDM0IGMgMC45MiwtNDAuMzUyIDI1LjY4LC04MS42MDIgNzEuNTMsLTgxLjYwMiAyNy41MSwwIDQ3LjY4LDEyLjgzMiA2MS40NCwzNS43NTQgMTIuODMsMjIuOTMgMTIuODMsNTYuODUyIDEyLjgzLDgyLjUyNyBsIDAsMzI5LjE4NCAtNzEuNTIsMCAwLDEwNC41NDMgMjY2LjgzLDAgMCwtMTA0LjU0MyAtNzAuNiwwIDAsLTM0NC43NyBjIDAsLTU4LjY5MSAtMy42OCwtMTA0LjUzMSAtNDQuOTMsLTE1Mi4yMTggLTM2LjY4LC00Mi4xOCAtOTYuMjgsLTY2LjAyIC0xNTMuMTQsLTY2LjAyIC0xMTcuMzcsMCAtMjA3LjI0LDc3Ljk0MSAtMjAyLjY0LDE5Ny4xNDUgbCAxMzAuMiwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMjIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDIzMDEuNCw2NjIuNjk1IGMgMCw4MC43MDMgLTY2Ljk0LDE0NS44MTMgLTE0Ny42MywxNDUuODEzIC04My40NCwwIC0xNDcuNjMsLTY4Ljc4MSAtMTQ3LjYzLC0xNTEuMzAxIDAsLTc5Ljc4NSA2Ni45NCwtMTQ1LjgwMSAxNDUuOCwtMTQ1LjgwMSA4NC4zNSwwIDE0OS40Niw2Ny44NTIgMTQ5LjQ2LDE1MS4yODkgeiBtIC0xLjgzLC0xODEuNTQ3IGMgLTM1Ljc3LC01NC4wOTcgLTkzLjUzLC03OC44NTkgLTE1Ny43MiwtNzguODU5IC0xNDAuMywwIC0yNTEuMjQsMTE2LjQ0OSAtMjUxLjI0LDI1NC45MTggMCwxNDIuMTI5IDExMy43LDI2MC40MSAyNTYuNzQsMjYwLjQxIDYzLjI3LDAgMTE4LjI5LC0yOS4zMzYgMTUyLjIyLC04Mi41MjMgbCAwLDY5LjY4NyAxNzUuMTQsMCAwLC0xMDQuNTI3IC02MS40NCwwIDAsLTI4MC41OTggNjEuNDQsMCAwLC0xMDQuNTI3IC0xNzUuMTQsMCAwLDY2LjAxOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAyNjIyLjMzLDU1Ny4yNTggYyAzLjY3LC00NC4wMTYgMzMuMDEsLTczLjM0OCA3OC44NiwtNzMuMzQ4IDMzLjkzLDAgNjYuOTMsMjMuODI0IDY2LjkzLDYwLjUwNCAwLDQ4LjYwNiAtNDUuODQsNTYuODU2IC04My40NCw2Ni45NDEgLTg1LjI4LDIyLjAwNCAtMTc4LjgxLDQ4LjYwNiAtMTc4LjgxLDE1NS44NzkgMCw5My41MzYgNzguODYsMTQ3LjYzMyAxNjUuOTgsMTQ3LjYzMyA0NCwwIDgzLjQzLC05LjE3NiAxMTAuOTQsLTQ0LjAwOCBsIDAsMzMuOTIyIDgyLjUzLDAgMCwtMTMyLjk2NSAtMTA4LjIxLDAgYyAtMS44MywzNC44NTYgLTI4LjQyLDU3Ljc3NCAtNjMuMjYsNTcuNzc0IC0zMC4yNiwwIC02Mi4zNSwtMTcuNDIyIC02Mi4zNSwtNTEuMzQ4IDAsLTQ1Ljg0NyA0NC45MywtNTUuOTMgODAuNjksLTY0LjE4IDg4LjAyLC0yMC4xNzUgMTgyLjQ3LC00Ny42OTUgMTgyLjQ3LC0xNTcuNzM0IDAsLTk5LjAyNyAtODMuNDQsLTE1NC4wMzkgLTE3NS4xMywtMTU0LjAzOSAtNDkuNTMsMCAtOTQuNDYsMTUuNTgyIC0xMjYuNTUsNTMuMTggbCAwLC00MC4zNCAtODUuMjcsMCAwLDE0Mi4xMjkgMTE0LjYyLDAiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGgyNiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMjk4OC4xOCw4MDAuMjU0IC02My4yNiwwIDAsMTA0LjUyNyAxNjUuMDUsMCAwLC03My4zNTUgYyAzMS4xOCw1MS4zNDcgNzguODYsODUuMjc3IDE0MS4yMSw4NS4yNzcgNjcuODUsMCAxMjQuNzEsLTQxLjI1OCAxNTIuMjEsLTEwMi42OTkgMjYuNiw2Mi4zNTEgOTIuNjIsMTAyLjY5OSAxNjAuNDcsMTAyLjY5OSA1My4xOSwwIDEwNS40NiwtMjIgMTQxLjIxLC02Mi4zNTEgMzguNTIsLTQ0LjkzOCAzOC41MiwtOTMuNTMyIDM4LjUyLC0xNDkuNDU3IGwgMCwtMTg1LjIzOSA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40MiwwIDAsMTA0LjUyNyA2My4yOCwwIDAsMTU3LjcxNSBjIDAsMzIuMTAyIDAsNjAuNTI3IC0xNC42Nyw4OC45NTcgLTE4LjM0LDI2LjU4MiAtNDguNjEsNDAuMzQ0IC03OS43Nyw0MC4zNDQgLTMwLjI2LDAgLTYzLjI4LC0xMi44NDQgLTgyLjUzLC0zNi42NzIgLTIyLjkzLC0yOS4zNTUgLTIyLjkzLC01Ni44NjMgLTIyLjkzLC05Mi42MjkgbCAwLC0xNTcuNzE1IDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM4LjQxLDAgMCwxMDQuNTI3IDYzLjI4LDAgMCwxNTAuMzgzIGMgMCwyOS4zNDggMCw2Ni4wMjMgLTE0LjY3LDkxLjY5OSAtMTUuNTksMjkuMzM2IC00Ny42OSw0NC45MzQgLTgwLjcsNDQuOTM0IC0zMS4xOCwwIC01Ny43NywtMTEuMDA4IC03Ny45NCwtMzUuNzc0IC0yNC43NywtMzAuMjUzIC0yNi42LC02Mi4zNDMgLTI2LjYsLTk5Ljk0MSBsIDAsLTE1MS4zMDEgNjMuMjcsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNiwwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAzOTk4LjY2LDk1MS41NDcgLTExMS44NywwIDAsMTE4LjI5MyAxMTEuODcsMCAwLC0xMTguMjkzIHogbSAwLC00MzEuODkxIDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM5LjMzLDAgMCwxMDQuNTI3IDY0LjE5LDAgMCwyODAuNTk4IC02My4yNywwIDAsMTA0LjUyNyAxNzUuMTQsMCAwLC0zODUuMTI1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzAiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDQxNTkuMTIsODAwLjI1NCAtNjMuMjcsMCAwLDEwNC41MjcgMTc1LjE0LDAgMCwtNjkuNjg3IGMgMjkuMzUsNTQuMTAxIDg0LjM2LDgwLjY5OSAxNDQuODcsODAuNjk5IDUzLjE5LDAgMTA1LjQ1LC0yMi4wMTYgMTQxLjIyLC02MC41MjcgNDAuMzQsLTQ0LjkzNCA0MS4yNiwtODguMDMyIDQxLjI2LC0xNDMuOTU3IGwgMCwtMTkxLjY1MyA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40LDAgMCwxMDQuNTI3IDYzLjI2LDAgMCwxNTguNjM3IGMgMCwzMC4yNjIgMCw2MS40MzQgLTE5LjI2LDg4LjAzNSAtMjAuMTcsMjYuNTgyIC01My4xOCwzOS40MTQgLTg2LjE5LDM5LjQxNCAtMzMuOTMsMCAtNjguNzcsLTEzLjc1IC04OC45NCwtNDEuMjUgLTIxLjA5LC0yNy41IC0yMS4wOSwtNjkuNjg3IC0yMS4wOSwtMTAyLjcwNyBsIDAsLTE0Mi4xMjkgNjMuMjYsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNywwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDMyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA1MDgyLjQ4LDcwMy45NjUgYyAtMTkuMjQsNzAuNjA1IC04MS42LDExNS41NDcgLTE1NC4wNCwxMTUuNTQ3IC02Ni4wNCwwIC0xMjkuMywtNTEuMzQ4IC0xNDMuMDUsLTExNS41NDcgbCAyOTcuMDksMCB6IG0gODUuMjcsLTE0NC44ODMgYyAtMzguNTEsLTkzLjUyMyAtMTI5LjI3LC0xNTYuNzkzIC0yMzEuMDUsLTE1Ni43OTMgLTE0My4wNywwIC0yNTcuNjgsMTExLjg3MSAtMjU3LjY4LDI1NS44MzYgMCwxNDQuODgzIDEwOS4xMiwyNjEuMzI4IDI1NC45MSwyNjEuMzI4IDY3Ljg3LDAgMTM1LjcyLC0zMC4yNTggMTgzLjM5LC03OC44NjMgNDguNjIsLTUxLjM0NCA2OC43OSwtMTEzLjY5NSA2OC43OSwtMTgzLjM4MyBsIC0zLjY3LC0zOS40MzQgLTM5Ni4xMywwIGMgMTQuNjcsLTY3Ljg2MyA3Ny4wMywtMTE3LjM2MyAxNDYuNzIsLTExNy4zNjMgNDguNTksMCA5MC43NiwxOC4zMjggMTE4LjI4LDU4LjY3MiBsIDExNi40NCwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDY5MC44OTUsODUwLjcwMyA5MC43NSwwIDIyLjU0MywzMS4wMzUgMCwyNDMuMTIyIC0xMzUuODI5LDAgMCwtMjQzLjE0MSAyMi41MzYsLTMxLjAxNiIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDM2IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA2MzIuMzk1LDc0Mi4yNTggMjguMDM5LDg2LjMwNCAtMjIuNTUxLDMxLjA0IC0yMzEuMjIzLDc1LjEyOCAtNDEuOTc2LC0xMjkuMTgzIDIzMS4yNTcsLTc1LjEzNyAzNi40NTQsMTEuODQ4IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzgiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDcxNy40NDksNjUzLjEwNSAtNzMuNDEsNTMuMzYgLTM2LjQ4OCwtMTEuODc1IC0xNDIuOTAzLC0xOTYuNjkyIDEwOS44ODMsLTc5LjgyOCAxNDIuOTE4LDE5Ni43MDMgMCwzOC4zMzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0MCIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gODI4LjUyLDcwNi40NjUgLTczLjQyNiwtNTMuMzQgMC4wMTEsLTM4LjM1OSBMIDg5OC4wMDQsNDE4LjA3IDEwMDcuOSw0OTcuODk4IDg2NC45NzMsNjk0LjYwOSA4MjguNTIsNzA2LjQ2NSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA4MTIuMDg2LDgyOC41ODYgMjguMDU1LC04Ni4zMiAzNi40ODQsLTExLjgzNiAyMzEuMjI1LDc1LjExNyAtNDEuOTcsMTI5LjE4MyAtMjMxLjIzOSwtNzUuMTQgLTIyLjU1NSwtMzEuMDA0IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNDQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDczNi4zMDEsMTMzNS44OCBjIC0zMjMuMDQ3LDAgLTU4NS44NzUsLTI2Mi43OCAtNTg1Ljg3NSwtNTg1Ljc4MiAwLC0zMjMuMTE4IDI2Mi44MjgsLTU4NS45NzcgNTg1Ljg3NSwtNTg1Ljk3NyAzMjMuMDE5LDAgNTg1LjgwOSwyNjIuODU5IDU4NS44MDksNTg1Ljk3NyAwLDMyMy4wMDIgLTI2Mi43OSw1ODUuNzgyIC01ODUuODA5LDU4NS43ODIgbCAwLDAgeiBtIDAsLTExOC42MSBjIDI1Ny45NzIsMCA0NjcuMTg5LC0yMDkuMTMgNDY3LjE4OSwtNDY3LjE3MiAwLC0yNTguMTI5IC0yMDkuMjE3LC00NjcuMzQ4IC00NjcuMTg5LC00NjcuMzQ4IC0yNTguMDc0LDAgLTQ2Ny4yNTQsMjA5LjIxOSAtNDY3LjI1NCw0NjcuMzQ4IDAsMjU4LjA0MiAyMDkuMTgsNDY3LjE3MiA0NjcuMjU0LDQ2Ny4xNzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0NiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTA5MS4xMyw2MTkuODgzIC0xNzUuNzcxLDU3LjEyMSAxMS42MjksMzUuODA4IDE3NS43NjIsLTU3LjEyMSAtMTEuNjIsLTM1LjgwOCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQ4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA4NjYuOTU3LDkwMi4wNzQgODM2LjUsOTI0LjE5OSA5NDUuMTIxLDEwNzMuNzMgOTc1LjU4NiwxMDUxLjYxIDg2Ni45NTcsOTAyLjA3NCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDUwIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA2MDcuNDY1LDkwMy40NDUgNDk4Ljg1NSwxMDUyLjk3IDUyOS4zMiwxMDc1LjEgNjM3LjkzLDkyNS41NjYgNjA3LjQ2NSw5MDMuNDQ1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDM4MC42ODgsNjIyLjEyOSAtMTEuNjI2LDM1LjgwMSAxNzUuNzU4LDU3LjA5IDExLjYyMSwtMzUuODAxIC0xNzUuNzUzLC01Ny4wOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDU0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA3MTYuMjg5LDM3Ni41OSAzNy42NDA2LDAgMCwxODQuODE2IC0zNy42NDA2LDAgMCwtMTg0LjgxNiB6IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTYiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4=') no-repeat, none; -moz-background-size: 100%; -o-background-size: 100%; -webkit-background-size: 100%; background-size: 100%; display: block; float: left; width: 90px; height: 25px; } +.jasmine_html-reporter .banner .version { margin-left: 14px; position: relative; top: 6px; } +.jasmine_html-reporter .banner .duration { position: absolute; right: 14px; top: 6px; } +.jasmine_html-reporter #jasmine_content { position: fixed; right: 100%; } +.jasmine_html-reporter .version { color: #aaa; } +.jasmine_html-reporter .banner { margin-top: 14px; } +.jasmine_html-reporter .duration { color: #aaa; float: right; } +.jasmine_html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; } +.jasmine_html-reporter .symbol-summary li { display: inline-block; height: 8px; width: 14px; font-size: 16px; } +.jasmine_html-reporter .symbol-summary li.passed { font-size: 14px; } +.jasmine_html-reporter .symbol-summary li.passed:before { color: #007069; content: "\02022"; } +.jasmine_html-reporter .symbol-summary li.failed { line-height: 9px; } +.jasmine_html-reporter .symbol-summary li.failed:before { color: #ca3a11; content: "\d7"; font-weight: bold; margin-left: -1px; } +.jasmine_html-reporter .symbol-summary li.disabled { font-size: 14px; } +.jasmine_html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; } +.jasmine_html-reporter .symbol-summary li.pending { line-height: 17px; } +.jasmine_html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; } +.jasmine_html-reporter .symbol-summary li.empty { font-size: 14px; } +.jasmine_html-reporter .symbol-summary li.empty:before { color: #ba9d37; content: "\02022"; } +.jasmine_html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; } +.jasmine_html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } +.jasmine_html-reporter .bar.failed { background-color: #ca3a11; } +.jasmine_html-reporter .bar.passed { background-color: #007069; } +.jasmine_html-reporter .bar.skipped { background-color: #bababa; } +.jasmine_html-reporter .bar.errored { background-color: #ca3a11; } +.jasmine_html-reporter .bar.menu { background-color: #fff; color: #aaa; } +.jasmine_html-reporter .bar.menu a { color: #333; } +.jasmine_html-reporter .bar a { color: white; } +.jasmine_html-reporter.spec-list .bar.menu.failure-list, .jasmine_html-reporter.spec-list .results .failures { display: none; } +.jasmine_html-reporter.failure-list .bar.menu.spec-list, .jasmine_html-reporter.failure-list .summary { display: none; } +.jasmine_html-reporter .running-alert { background-color: #666; } +.jasmine_html-reporter .results { margin-top: 14px; } +.jasmine_html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; } +.jasmine_html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; } +.jasmine_html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; } +.jasmine_html-reporter.showDetails .summary { display: none; } +.jasmine_html-reporter.showDetails #details { display: block; } +.jasmine_html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; } +.jasmine_html-reporter .summary { margin-top: 14px; } +.jasmine_html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; } +.jasmine_html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; } +.jasmine_html-reporter .summary li.passed a { color: #007069; } +.jasmine_html-reporter .summary li.failed a { color: #ca3a11; } +.jasmine_html-reporter .summary li.empty a { color: #ba9d37; } +.jasmine_html-reporter .summary li.pending a { color: #ba9d37; } +.jasmine_html-reporter .description + .suite { margin-top: 0; } +.jasmine_html-reporter .suite { margin-top: 14px; } +.jasmine_html-reporter .suite a { color: #333; } +.jasmine_html-reporter .failures .spec-detail { margin-bottom: 28px; } +.jasmine_html-reporter .failures .spec-detail .description { background-color: #ca3a11; } +.jasmine_html-reporter .failures .spec-detail .description a { color: white; } +.jasmine_html-reporter .result-message { padding-top: 14px; color: #333; white-space: pre; } +.jasmine_html-reporter .result-message span.result { display: block; } +.jasmine_html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666; border: 1px solid #ddd; background: white; white-space: pre; } diff --git a/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine.js b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine.js new file mode 100755 index 0000000..6bf3f02 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine.js @@ -0,0 +1,3048 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +var getJasmineRequireObj = (function (jasmineGlobal) { + var jasmineRequire; + + if (typeof module !== 'undefined' && module.exports) { + jasmineGlobal = global; + jasmineRequire = exports; + } else { + if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') { + jasmineGlobal = window; + } + jasmineRequire = jasmineGlobal.jasmineRequire = jasmineGlobal.jasmineRequire || {}; + } + + function getJasmineRequire() { + return jasmineRequire; + } + + getJasmineRequire().core = function(jRequire) { + var j$ = {}; + + jRequire.base(j$, jasmineGlobal); + j$.util = jRequire.util(); + j$.Any = jRequire.Any(); + j$.Anything = jRequire.Anything(j$); + j$.CallTracker = jRequire.CallTracker(); + j$.MockDate = jRequire.MockDate(); + j$.Clock = jRequire.Clock(); + j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(); + j$.Env = jRequire.Env(j$); + j$.ExceptionFormatter = jRequire.ExceptionFormatter(); + j$.Expectation = jRequire.Expectation(); + j$.buildExpectationResult = jRequire.buildExpectationResult(); + j$.JsApiReporter = jRequire.JsApiReporter(); + j$.matchersUtil = jRequire.matchersUtil(j$); + j$.ObjectContaining = jRequire.ObjectContaining(j$); + j$.ArrayContaining = jRequire.ArrayContaining(j$); + j$.pp = jRequire.pp(j$); + j$.QueueRunner = jRequire.QueueRunner(j$); + j$.ReportDispatcher = jRequire.ReportDispatcher(); + j$.Spec = jRequire.Spec(j$); + j$.SpyRegistry = jRequire.SpyRegistry(j$); + j$.SpyStrategy = jRequire.SpyStrategy(); + j$.StringMatching = jRequire.StringMatching(j$); + j$.Suite = jRequire.Suite(); + j$.Timer = jRequire.Timer(); + j$.version = jRequire.version(); + + j$.matchers = jRequire.requireMatchers(jRequire, j$); + + return j$; + }; + + return getJasmineRequire; +})(this); + +getJasmineRequireObj().requireMatchers = function(jRequire, j$) { + var availableMatchers = [ + 'toBe', + 'toBeCloseTo', + 'toBeDefined', + 'toBeFalsy', + 'toBeGreaterThan', + 'toBeLessThan', + 'toBeNaN', + 'toBeNull', + 'toBeTruthy', + 'toBeUndefined', + 'toContain', + 'toEqual', + 'toHaveBeenCalled', + 'toHaveBeenCalledWith', + 'toMatch', + 'toThrow', + 'toThrowError' + ], + matchers = {}; + + for (var i = 0; i < availableMatchers.length; i++) { + var name = availableMatchers[i]; + matchers[name] = jRequire[name](j$); + } + + return matchers; +}; + +getJasmineRequireObj().base = function(j$, jasmineGlobal) { + j$.unimplementedMethod_ = function() { + throw new Error('unimplemented method'); + }; + + j$.MAX_PRETTY_PRINT_DEPTH = 40; + j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 100; + j$.DEFAULT_TIMEOUT_INTERVAL = 5000; + + j$.getGlobal = function() { + return jasmineGlobal; + }; + + j$.getEnv = function(options) { + var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options); + //jasmine. singletons in here (setTimeout blah blah). + return env; + }; + + j$.isArray_ = function(value) { + return j$.isA_('Array', value); + }; + + j$.isString_ = function(value) { + return j$.isA_('String', value); + }; + + j$.isNumber_ = function(value) { + return j$.isA_('Number', value); + }; + + j$.isA_ = function(typeName, value) { + return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; + }; + + j$.isDomNode = function(obj) { + return obj.nodeType > 0; + }; + + j$.fnNameFor = function(func) { + return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1]; + }; + + j$.any = function(clazz) { + return new j$.Any(clazz); + }; + + j$.anything = function() { + return new j$.Anything(); + }; + + j$.objectContaining = function(sample) { + return new j$.ObjectContaining(sample); + }; + + j$.stringMatching = function(expected) { + return new j$.StringMatching(expected); + }; + + j$.arrayContaining = function(sample) { + return new j$.ArrayContaining(sample); + }; + + j$.createSpy = function(name, originalFn) { + + var spyStrategy = new j$.SpyStrategy({ + name: name, + fn: originalFn, + getSpy: function() { return spy; } + }), + callTracker = new j$.CallTracker(), + spy = function() { + var callData = { + object: this, + args: Array.prototype.slice.apply(arguments) + }; + + callTracker.track(callData); + var returnValue = spyStrategy.exec.apply(this, arguments); + callData.returnValue = returnValue; + + return returnValue; + }; + + for (var prop in originalFn) { + if (prop === 'and' || prop === 'calls') { + throw new Error('Jasmine spies would overwrite the \'and\' and \'calls\' properties on the object being spied upon'); + } + + spy[prop] = originalFn[prop]; + } + + spy.and = spyStrategy; + spy.calls = callTracker; + + return spy; + }; + + j$.isSpy = function(putativeSpy) { + if (!putativeSpy) { + return false; + } + return putativeSpy.and instanceof j$.SpyStrategy && + putativeSpy.calls instanceof j$.CallTracker; + }; + + j$.createSpyObj = function(baseName, methodNames) { + if (j$.isArray_(baseName) && j$.util.isUndefined(methodNames)) { + methodNames = baseName; + baseName = 'unknown'; + } + + if (!j$.isArray_(methodNames) || methodNames.length === 0) { + throw 'createSpyObj requires a non-empty array of method names to create spies for'; + } + var obj = {}; + for (var i = 0; i < methodNames.length; i++) { + obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]); + } + return obj; + }; +}; + +getJasmineRequireObj().util = function() { + + var util = {}; + + util.inherit = function(childClass, parentClass) { + var Subclass = function() { + }; + Subclass.prototype = parentClass.prototype; + childClass.prototype = new Subclass(); + }; + + util.htmlEscape = function(str) { + if (!str) { + return str; + } + return str.replace(/&/g, '&') + .replace(//g, '>'); + }; + + util.argsToArray = function(args) { + var arrayOfArgs = []; + for (var i = 0; i < args.length; i++) { + arrayOfArgs.push(args[i]); + } + return arrayOfArgs; + }; + + util.isUndefined = function(obj) { + return obj === void 0; + }; + + util.arrayContains = function(array, search) { + var i = array.length; + while (i--) { + if (array[i] === search) { + return true; + } + } + return false; + }; + + util.clone = function(obj) { + if (Object.prototype.toString.apply(obj) === '[object Array]') { + return obj.slice(); + } + + var cloned = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + cloned[prop] = obj[prop]; + } + } + + return cloned; + }; + + return util; +}; + +getJasmineRequireObj().Spec = function(j$) { + function Spec(attrs) { + this.expectationFactory = attrs.expectationFactory; + this.resultCallback = attrs.resultCallback || function() {}; + this.id = attrs.id; + this.description = attrs.description || ''; + this.queueableFn = attrs.queueableFn; + this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; }; + this.userContext = attrs.userContext || function() { return {}; }; + this.onStart = attrs.onStart || function() {}; + this.getSpecName = attrs.getSpecName || function() { return ''; }; + this.expectationResultFactory = attrs.expectationResultFactory || function() { }; + this.queueRunnerFactory = attrs.queueRunnerFactory || function() {}; + this.catchingExceptions = attrs.catchingExceptions || function() { return true; }; + + if (!this.queueableFn.fn) { + this.pend(); + } + + this.result = { + id: this.id, + description: this.description, + fullName: this.getFullName(), + failedExpectations: [], + passedExpectations: [], + pendingReason: '' + }; + } + + Spec.prototype.addExpectationResult = function(passed, data) { + var expectationResult = this.expectationResultFactory(data); + if (passed) { + this.result.passedExpectations.push(expectationResult); + } else { + this.result.failedExpectations.push(expectationResult); + } + }; + + Spec.prototype.expect = function(actual) { + return this.expectationFactory(actual, this); + }; + + Spec.prototype.execute = function(onComplete) { + var self = this; + + this.onStart(this); + + if (this.markedPending || this.disabled) { + complete(); + return; + } + + var fns = this.beforeAndAfterFns(); + var allFns = fns.befores.concat(this.queueableFn).concat(fns.afters); + + this.queueRunnerFactory({ + queueableFns: allFns, + onException: function() { self.onException.apply(self, arguments); }, + onComplete: complete, + userContext: this.userContext() + }); + + function complete() { + self.result.status = self.status(); + self.resultCallback(self.result); + + if (onComplete) { + onComplete(); + } + } + }; + + Spec.prototype.onException = function onException(e) { + if (Spec.isPendingSpecException(e)) { + this.pend(extractCustomPendingMessage(e)); + return; + } + + this.addExpectationResult(false, { + matcherName: '', + passed: false, + expected: '', + actual: '', + error: e + }); + }; + + Spec.prototype.disable = function() { + this.disabled = true; + }; + + Spec.prototype.pend = function(message) { + this.markedPending = true; + if (message) { + this.result.pendingReason = message; + } + }; + + Spec.prototype.status = function() { + if (this.disabled) { + return 'disabled'; + } + + if (this.markedPending) { + return 'pending'; + } + + if (this.result.failedExpectations.length > 0) { + return 'failed'; + } else { + return 'passed'; + } + }; + + Spec.prototype.isExecutable = function() { + return !this.disabled && !this.markedPending; + }; + + Spec.prototype.getFullName = function() { + return this.getSpecName(this); + }; + + var extractCustomPendingMessage = function(e) { + var fullMessage = e.toString(), + boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage), + boilerplateEnd = boilerplateStart + Spec.pendingSpecExceptionMessage.length; + + return fullMessage.substr(boilerplateEnd); + }; + + Spec.pendingSpecExceptionMessage = '=> marked Pending'; + + Spec.isPendingSpecException = function(e) { + return !!(e && e.toString && e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1); + }; + + return Spec; +}; + +if (typeof window == void 0 && typeof exports == 'object') { + exports.Spec = jasmineRequire.Spec; +} + +getJasmineRequireObj().Env = function(j$) { + function Env(options) { + options = options || {}; + + var self = this; + var global = options.global || j$.getGlobal(); + + var totalSpecsDefined = 0; + + var catchExceptions = true; + + var realSetTimeout = j$.getGlobal().setTimeout; + var realClearTimeout = j$.getGlobal().clearTimeout; + this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler(), new j$.MockDate(global)); + + var runnableLookupTable = {}; + var runnableResources = {}; + + var currentSpec = null; + var currentlyExecutingSuites = []; + var currentDeclarationSuite = null; + + var currentSuite = function() { + return currentlyExecutingSuites[currentlyExecutingSuites.length - 1]; + }; + + var currentRunnable = function() { + return currentSpec || currentSuite(); + }; + + var reporter = new j$.ReportDispatcher([ + 'jasmineStarted', + 'jasmineDone', + 'suiteStarted', + 'suiteDone', + 'specStarted', + 'specDone' + ]); + + this.specFilter = function() { + return true; + }; + + this.addCustomEqualityTester = function(tester) { + if(!currentRunnable()) { + throw new Error('Custom Equalities must be added in a before function or a spec'); + } + runnableResources[currentRunnable().id].customEqualityTesters.push(tester); + }; + + this.addMatchers = function(matchersToAdd) { + if(!currentRunnable()) { + throw new Error('Matchers must be added in a before function or a spec'); + } + var customMatchers = runnableResources[currentRunnable().id].customMatchers; + for (var matcherName in matchersToAdd) { + customMatchers[matcherName] = matchersToAdd[matcherName]; + } + }; + + j$.Expectation.addCoreMatchers(j$.matchers); + + var nextSpecId = 0; + var getNextSpecId = function() { + return 'spec' + nextSpecId++; + }; + + var nextSuiteId = 0; + var getNextSuiteId = function() { + return 'suite' + nextSuiteId++; + }; + + var expectationFactory = function(actual, spec) { + return j$.Expectation.Factory({ + util: j$.matchersUtil, + customEqualityTesters: runnableResources[spec.id].customEqualityTesters, + customMatchers: runnableResources[spec.id].customMatchers, + actual: actual, + addExpectationResult: addExpectationResult + }); + + function addExpectationResult(passed, result) { + return spec.addExpectationResult(passed, result); + } + }; + + var defaultResourcesForRunnable = function(id, parentRunnableId) { + var resources = {spies: [], customEqualityTesters: [], customMatchers: {}}; + + if(runnableResources[parentRunnableId]){ + resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters); + resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers); + } + + runnableResources[id] = resources; + }; + + var clearResourcesForRunnable = function(id) { + spyRegistry.clearSpies(); + delete runnableResources[id]; + }; + + var beforeAndAfterFns = function(suite, runnablesExplictlySet) { + return function() { + var befores = [], + afters = [], + beforeAlls = [], + afterAlls = []; + + while(suite) { + befores = befores.concat(suite.beforeFns); + afters = afters.concat(suite.afterFns); + + if (runnablesExplictlySet()) { + beforeAlls = beforeAlls.concat(suite.beforeAllFns); + afterAlls = afterAlls.concat(suite.afterAllFns); + } + + suite = suite.parentSuite; + } + return { + befores: beforeAlls.reverse().concat(befores.reverse()), + afters: afters.concat(afterAlls) + }; + }; + }; + + var getSpecName = function(spec, suite) { + return suite.getFullName() + ' ' + spec.description; + }; + + // TODO: we may just be able to pass in the fn instead of wrapping here + var buildExpectationResult = j$.buildExpectationResult, + exceptionFormatter = new j$.ExceptionFormatter(), + expectationResultFactory = function(attrs) { + attrs.messageFormatter = exceptionFormatter.message; + attrs.stackFormatter = exceptionFormatter.stack; + + return buildExpectationResult(attrs); + }; + + // TODO: fix this naming, and here's where the value comes in + this.catchExceptions = function(value) { + catchExceptions = !!value; + return catchExceptions; + }; + + this.catchingExceptions = function() { + return catchExceptions; + }; + + var maximumSpecCallbackDepth = 20; + var currentSpecCallbackDepth = 0; + + function clearStack(fn) { + currentSpecCallbackDepth++; + if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) { + currentSpecCallbackDepth = 0; + realSetTimeout(fn, 0); + } else { + fn(); + } + } + + var catchException = function(e) { + return j$.Spec.isPendingSpecException(e) || catchExceptions; + }; + + var queueRunnerFactory = function(options) { + options.catchException = catchException; + options.clearStack = options.clearStack || clearStack; + options.timer = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}; + options.fail = self.fail; + + new j$.QueueRunner(options).execute(); + }; + + var topSuite = new j$.Suite({ + env: this, + id: getNextSuiteId(), + description: 'Jasmine__TopLevel__Suite', + queueRunner: queueRunnerFactory + }); + runnableLookupTable[topSuite.id] = topSuite; + defaultResourcesForRunnable(topSuite.id); + currentDeclarationSuite = topSuite; + + this.topSuite = function() { + return topSuite; + }; + + this.execute = function(runnablesToRun) { + if(runnablesToRun) { + runnablesExplictlySet = true; + } else if (focusedRunnables.length) { + runnablesExplictlySet = true; + runnablesToRun = focusedRunnables; + } else { + runnablesToRun = [topSuite.id]; + } + + var allFns = []; + for(var i = 0; i < runnablesToRun.length; i++) { + var runnable = runnableLookupTable[runnablesToRun[i]]; + allFns.push((function(runnable) { return { fn: function(done) { runnable.execute(done); } }; })(runnable)); + } + + reporter.jasmineStarted({ + totalSpecsDefined: totalSpecsDefined + }); + + queueRunnerFactory({queueableFns: allFns, onComplete: reporter.jasmineDone}); + }; + + this.addReporter = function(reporterToAdd) { + reporter.addReporter(reporterToAdd); + }; + + var spyRegistry = new j$.SpyRegistry({currentSpies: function() { + if(!currentRunnable()) { + throw new Error('Spies must be created in a before function or a spec'); + } + return runnableResources[currentRunnable().id].spies; + }}); + + this.spyOn = function() { + return spyRegistry.spyOn.apply(spyRegistry, arguments); + }; + + var suiteFactory = function(description) { + var suite = new j$.Suite({ + env: self, + id: getNextSuiteId(), + description: description, + parentSuite: currentDeclarationSuite, + queueRunner: queueRunnerFactory, + onStart: suiteStarted, + expectationFactory: expectationFactory, + expectationResultFactory: expectationResultFactory, + runnablesExplictlySetGetter: runnablesExplictlySetGetter, + resultCallback: function(attrs) { + if (!suite.disabled) { + clearResourcesForRunnable(suite.id); + } + currentlyExecutingSuites.pop(); + reporter.suiteDone(attrs); + } + }); + + runnableLookupTable[suite.id] = suite; + return suite; + + function suiteStarted(suite) { + currentlyExecutingSuites.push(suite); + defaultResourcesForRunnable(suite.id, suite.parentSuite.id); + reporter.suiteStarted(suite.result); + } + }; + + this.describe = function(description, specDefinitions) { + var suite = suiteFactory(description); + addSpecsToSuite(suite, specDefinitions); + return suite; + }; + + this.xdescribe = function(description, specDefinitions) { + var suite = this.describe(description, specDefinitions); + suite.disable(); + return suite; + }; + + var focusedRunnables = []; + + this.fdescribe = function(description, specDefinitions) { + var suite = suiteFactory(description); + suite.isFocused = true; + + focusedRunnables.push(suite.id); + unfocusAncestor(); + addSpecsToSuite(suite, specDefinitions); + + return suite; + }; + + function addSpecsToSuite(suite, specDefinitions) { + var parentSuite = currentDeclarationSuite; + parentSuite.addChild(suite); + currentDeclarationSuite = suite; + + var declarationError = null; + try { + specDefinitions.call(suite); + } catch (e) { + declarationError = e; + } + + if (declarationError) { + self.it('encountered a declaration exception', function() { + throw declarationError; + }); + } + + currentDeclarationSuite = parentSuite; + } + + function findFocusedAncestor(suite) { + while (suite) { + if (suite.isFocused) { + return suite.id; + } + suite = suite.parentSuite; + } + + return null; + } + + function unfocusAncestor() { + var focusedAncestor = findFocusedAncestor(currentDeclarationSuite); + if (focusedAncestor) { + for (var i = 0; i < focusedRunnables.length; i++) { + if (focusedRunnables[i] === focusedAncestor) { + focusedRunnables.splice(i, 1); + break; + } + } + } + } + + var runnablesExplictlySet = false; + + var runnablesExplictlySetGetter = function(){ + return runnablesExplictlySet; + }; + + var specFactory = function(description, fn, suite, timeout) { + totalSpecsDefined++; + var spec = new j$.Spec({ + id: getNextSpecId(), + beforeAndAfterFns: beforeAndAfterFns(suite, runnablesExplictlySetGetter), + expectationFactory: expectationFactory, + resultCallback: specResultCallback, + getSpecName: function(spec) { + return getSpecName(spec, suite); + }, + onStart: specStarted, + description: description, + expectationResultFactory: expectationResultFactory, + queueRunnerFactory: queueRunnerFactory, + userContext: function() { return suite.clonedSharedUserContext(); }, + queueableFn: { + fn: fn, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + } + }); + + runnableLookupTable[spec.id] = spec; + + if (!self.specFilter(spec)) { + spec.disable(); + } + + return spec; + + function specResultCallback(result) { + clearResourcesForRunnable(spec.id); + currentSpec = null; + reporter.specDone(result); + } + + function specStarted(spec) { + currentSpec = spec; + defaultResourcesForRunnable(spec.id, suite.id); + reporter.specStarted(spec.result); + } + }; + + this.it = function(description, fn, timeout) { + var spec = specFactory(description, fn, currentDeclarationSuite, timeout); + currentDeclarationSuite.addChild(spec); + return spec; + }; + + this.xit = function() { + var spec = this.it.apply(this, arguments); + spec.pend(); + return spec; + }; + + this.fit = function(){ + var spec = this.it.apply(this, arguments); + + focusedRunnables.push(spec.id); + unfocusAncestor(); + return spec; + }; + + this.expect = function(actual) { + if (!currentRunnable()) { + throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out'); + } + + return currentRunnable().expect(actual); + }; + + this.beforeEach = function(beforeEachFunction, timeout) { + currentDeclarationSuite.beforeEach({ + fn: beforeEachFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.beforeAll = function(beforeAllFunction, timeout) { + currentDeclarationSuite.beforeAll({ + fn: beforeAllFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.afterEach = function(afterEachFunction, timeout) { + currentDeclarationSuite.afterEach({ + fn: afterEachFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.afterAll = function(afterAllFunction, timeout) { + currentDeclarationSuite.afterAll({ + fn: afterAllFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.pending = function(message) { + var fullMessage = j$.Spec.pendingSpecExceptionMessage; + if(message) { + fullMessage += message; + } + throw fullMessage; + }; + + this.fail = function(error) { + var message = 'Failed'; + if (error) { + message += ': '; + message += error.message || error; + } + + currentRunnable().addExpectationResult(false, { + matcherName: '', + passed: false, + expected: '', + actual: '', + message: message, + error: error && error.message ? error : null + }); + }; + } + + return Env; +}; + +getJasmineRequireObj().JsApiReporter = function() { + + var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } + }; + + function JsApiReporter(options) { + var timer = options.timer || noopTimer, + status = 'loaded'; + + this.started = false; + this.finished = false; + + this.jasmineStarted = function() { + this.started = true; + status = 'started'; + timer.start(); + }; + + var executionTime; + + this.jasmineDone = function() { + this.finished = true; + executionTime = timer.elapsed(); + status = 'done'; + }; + + this.status = function() { + return status; + }; + + var suites = [], + suites_hash = {}; + + this.suiteStarted = function(result) { + suites_hash[result.id] = result; + }; + + this.suiteDone = function(result) { + storeSuite(result); + }; + + this.suiteResults = function(index, length) { + return suites.slice(index, index + length); + }; + + function storeSuite(result) { + suites.push(result); + suites_hash[result.id] = result; + } + + this.suites = function() { + return suites_hash; + }; + + var specs = []; + + this.specDone = function(result) { + specs.push(result); + }; + + this.specResults = function(index, length) { + return specs.slice(index, index + length); + }; + + this.specs = function() { + return specs; + }; + + this.executionTime = function() { + return executionTime; + }; + + } + + return JsApiReporter; +}; + +getJasmineRequireObj().CallTracker = function() { + + function CallTracker() { + var calls = []; + + this.track = function(context) { + calls.push(context); + }; + + this.any = function() { + return !!calls.length; + }; + + this.count = function() { + return calls.length; + }; + + this.argsFor = function(index) { + var call = calls[index]; + return call ? call.args : []; + }; + + this.all = function() { + return calls; + }; + + this.allArgs = function() { + var callArgs = []; + for(var i = 0; i < calls.length; i++){ + callArgs.push(calls[i].args); + } + + return callArgs; + }; + + this.first = function() { + return calls[0]; + }; + + this.mostRecent = function() { + return calls[calls.length - 1]; + }; + + this.reset = function() { + calls = []; + }; + } + + return CallTracker; +}; + +getJasmineRequireObj().Clock = function() { + function Clock(global, delayedFunctionScheduler, mockDate) { + var self = this, + realTimingFunctions = { + setTimeout: global.setTimeout, + clearTimeout: global.clearTimeout, + setInterval: global.setInterval, + clearInterval: global.clearInterval + }, + fakeTimingFunctions = { + setTimeout: setTimeout, + clearTimeout: clearTimeout, + setInterval: setInterval, + clearInterval: clearInterval + }, + installed = false, + timer; + + + self.install = function() { + replace(global, fakeTimingFunctions); + timer = fakeTimingFunctions; + installed = true; + + return self; + }; + + self.uninstall = function() { + delayedFunctionScheduler.reset(); + mockDate.uninstall(); + replace(global, realTimingFunctions); + + timer = realTimingFunctions; + installed = false; + }; + + self.mockDate = function(initialDate) { + mockDate.install(initialDate); + }; + + self.setTimeout = function(fn, delay, params) { + if (legacyIE()) { + if (arguments.length > 2) { + throw new Error('IE < 9 cannot support extra params to setTimeout without a polyfill'); + } + return timer.setTimeout(fn, delay); + } + return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]); + }; + + self.setInterval = function(fn, delay, params) { + if (legacyIE()) { + if (arguments.length > 2) { + throw new Error('IE < 9 cannot support extra params to setInterval without a polyfill'); + } + return timer.setInterval(fn, delay); + } + return Function.prototype.apply.apply(timer.setInterval, [global, arguments]); + }; + + self.clearTimeout = function(id) { + return Function.prototype.call.apply(timer.clearTimeout, [global, id]); + }; + + self.clearInterval = function(id) { + return Function.prototype.call.apply(timer.clearInterval, [global, id]); + }; + + self.tick = function(millis) { + if (installed) { + mockDate.tick(millis); + delayedFunctionScheduler.tick(millis); + } else { + throw new Error('Mock clock is not installed, use jasmine.clock().install()'); + } + }; + + return self; + + function legacyIE() { + //if these methods are polyfilled, apply will be present + return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply; + } + + function replace(dest, source) { + for (var prop in source) { + dest[prop] = source[prop]; + } + } + + function setTimeout(fn, delay) { + return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2)); + } + + function clearTimeout(id) { + return delayedFunctionScheduler.removeFunctionWithId(id); + } + + function setInterval(fn, interval) { + return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true); + } + + function clearInterval(id) { + return delayedFunctionScheduler.removeFunctionWithId(id); + } + + function argSlice(argsObj, n) { + return Array.prototype.slice.call(argsObj, n); + } + } + + return Clock; +}; + +getJasmineRequireObj().DelayedFunctionScheduler = function() { + function DelayedFunctionScheduler() { + var self = this; + var scheduledLookup = []; + var scheduledFunctions = {}; + var currentTime = 0; + var delayedFnCount = 0; + + self.tick = function(millis) { + millis = millis || 0; + var endTime = currentTime + millis; + + runScheduledFunctions(endTime); + currentTime = endTime; + }; + + self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) { + var f; + if (typeof(funcToCall) === 'string') { + /* jshint evil: true */ + f = function() { return eval(funcToCall); }; + /* jshint evil: false */ + } else { + f = funcToCall; + } + + millis = millis || 0; + timeoutKey = timeoutKey || ++delayedFnCount; + runAtMillis = runAtMillis || (currentTime + millis); + + var funcToSchedule = { + runAtMillis: runAtMillis, + funcToCall: f, + recurring: recurring, + params: params, + timeoutKey: timeoutKey, + millis: millis + }; + + if (runAtMillis in scheduledFunctions) { + scheduledFunctions[runAtMillis].push(funcToSchedule); + } else { + scheduledFunctions[runAtMillis] = [funcToSchedule]; + scheduledLookup.push(runAtMillis); + scheduledLookup.sort(function (a, b) { + return a - b; + }); + } + + return timeoutKey; + }; + + self.removeFunctionWithId = function(timeoutKey) { + for (var runAtMillis in scheduledFunctions) { + var funcs = scheduledFunctions[runAtMillis]; + var i = indexOfFirstToPass(funcs, function (func) { + return func.timeoutKey === timeoutKey; + }); + + if (i > -1) { + if (funcs.length === 1) { + delete scheduledFunctions[runAtMillis]; + deleteFromLookup(runAtMillis); + } else { + funcs.splice(i, 1); + } + + // intervals get rescheduled when executed, so there's never more + // than a single scheduled function with a given timeoutKey + break; + } + } + }; + + self.reset = function() { + currentTime = 0; + scheduledLookup = []; + scheduledFunctions = {}; + delayedFnCount = 0; + }; + + return self; + + function indexOfFirstToPass(array, testFn) { + var index = -1; + + for (var i = 0; i < array.length; ++i) { + if (testFn(array[i])) { + index = i; + break; + } + } + + return index; + } + + function deleteFromLookup(key) { + var value = Number(key); + var i = indexOfFirstToPass(scheduledLookup, function (millis) { + return millis === value; + }); + + if (i > -1) { + scheduledLookup.splice(i, 1); + } + } + + function reschedule(scheduledFn) { + self.scheduleFunction(scheduledFn.funcToCall, + scheduledFn.millis, + scheduledFn.params, + true, + scheduledFn.timeoutKey, + scheduledFn.runAtMillis + scheduledFn.millis); + } + + function forEachFunction(funcsToRun, callback) { + for (var i = 0; i < funcsToRun.length; ++i) { + callback(funcsToRun[i]); + } + } + + function runScheduledFunctions(endTime) { + if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) { + return; + } + + do { + currentTime = scheduledLookup.shift(); + + var funcsToRun = scheduledFunctions[currentTime]; + delete scheduledFunctions[currentTime]; + + forEachFunction(funcsToRun, function(funcToRun) { + if (funcToRun.recurring) { + reschedule(funcToRun); + } + }); + + forEachFunction(funcsToRun, function(funcToRun) { + funcToRun.funcToCall.apply(null, funcToRun.params || []); + }); + } while (scheduledLookup.length > 0 && + // checking first if we're out of time prevents setTimeout(0) + // scheduled in a funcToRun from forcing an extra iteration + currentTime !== endTime && + scheduledLookup[0] <= endTime); + } + } + + return DelayedFunctionScheduler; +}; + +getJasmineRequireObj().ExceptionFormatter = function() { + function ExceptionFormatter() { + this.message = function(error) { + var message = ''; + + if (error.name && error.message) { + message += error.name + ': ' + error.message; + } else { + message += error.toString() + ' thrown'; + } + + if (error.fileName || error.sourceURL) { + message += ' in ' + (error.fileName || error.sourceURL); + } + + if (error.line || error.lineNumber) { + message += ' (line ' + (error.line || error.lineNumber) + ')'; + } + + return message; + }; + + this.stack = function(error) { + return error ? error.stack : null; + }; + } + + return ExceptionFormatter; +}; + +getJasmineRequireObj().Expectation = function() { + + function Expectation(options) { + this.util = options.util || { buildFailureMessage: function() {} }; + this.customEqualityTesters = options.customEqualityTesters || []; + this.actual = options.actual; + this.addExpectationResult = options.addExpectationResult || function(){}; + this.isNot = options.isNot; + + var customMatchers = options.customMatchers || {}; + for (var matcherName in customMatchers) { + this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]); + } + } + + Expectation.prototype.wrapCompare = function(name, matcherFactory) { + return function() { + var args = Array.prototype.slice.call(arguments, 0), + expected = args.slice(0), + message = ''; + + args.unshift(this.actual); + + var matcher = matcherFactory(this.util, this.customEqualityTesters), + matcherCompare = matcher.compare; + + function defaultNegativeCompare() { + var result = matcher.compare.apply(null, args); + result.pass = !result.pass; + return result; + } + + if (this.isNot) { + matcherCompare = matcher.negativeCompare || defaultNegativeCompare; + } + + var result = matcherCompare.apply(null, args); + + if (!result.pass) { + if (!result.message) { + args.unshift(this.isNot); + args.unshift(name); + message = this.util.buildFailureMessage.apply(null, args); + } else { + if (Object.prototype.toString.apply(result.message) === '[object Function]') { + message = result.message(); + } else { + message = result.message; + } + } + } + + if (expected.length == 1) { + expected = expected[0]; + } + + // TODO: how many of these params are needed? + this.addExpectationResult( + result.pass, + { + matcherName: name, + passed: result.pass, + message: message, + actual: this.actual, + expected: expected // TODO: this may need to be arrayified/sliced + } + ); + }; + }; + + Expectation.addCoreMatchers = function(matchers) { + var prototype = Expectation.prototype; + for (var matcherName in matchers) { + var matcher = matchers[matcherName]; + prototype[matcherName] = prototype.wrapCompare(matcherName, matcher); + } + }; + + Expectation.Factory = function(options) { + options = options || {}; + + var expect = new Expectation(options); + + // TODO: this would be nice as its own Object - NegativeExpectation + // TODO: copy instead of mutate options + options.isNot = true; + expect.not = new Expectation(options); + + return expect; + }; + + return Expectation; +}; + +//TODO: expectation result may make more sense as a presentation of an expectation. +getJasmineRequireObj().buildExpectationResult = function() { + function buildExpectationResult(options) { + var messageFormatter = options.messageFormatter || function() {}, + stackFormatter = options.stackFormatter || function() {}; + + var result = { + matcherName: options.matcherName, + message: message(), + stack: stack(), + passed: options.passed + }; + + if(!result.passed) { + result.expected = options.expected; + result.actual = options.actual; + } + + return result; + + function message() { + if (options.passed) { + return 'Passed.'; + } else if (options.message) { + return options.message; + } else if (options.error) { + return messageFormatter(options.error); + } + return ''; + } + + function stack() { + if (options.passed) { + return ''; + } + + var error = options.error; + if (!error) { + try { + throw new Error(message()); + } catch (e) { + error = e; + } + } + return stackFormatter(error); + } + } + + return buildExpectationResult; +}; + +getJasmineRequireObj().MockDate = function() { + function MockDate(global) { + var self = this; + var currentTime = 0; + + if (!global || !global.Date) { + self.install = function() {}; + self.tick = function() {}; + self.uninstall = function() {}; + return self; + } + + var GlobalDate = global.Date; + + self.install = function(mockDate) { + if (mockDate instanceof GlobalDate) { + currentTime = mockDate.getTime(); + } else { + currentTime = new GlobalDate().getTime(); + } + + global.Date = FakeDate; + }; + + self.tick = function(millis) { + millis = millis || 0; + currentTime = currentTime + millis; + }; + + self.uninstall = function() { + currentTime = 0; + global.Date = GlobalDate; + }; + + createDateProperties(); + + return self; + + function FakeDate() { + switch(arguments.length) { + case 0: + return new GlobalDate(currentTime); + case 1: + return new GlobalDate(arguments[0]); + case 2: + return new GlobalDate(arguments[0], arguments[1]); + case 3: + return new GlobalDate(arguments[0], arguments[1], arguments[2]); + case 4: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3]); + case 5: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4]); + case 6: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4], arguments[5]); + default: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4], arguments[5], arguments[6]); + } + } + + function createDateProperties() { + FakeDate.prototype = GlobalDate.prototype; + + FakeDate.now = function() { + if (GlobalDate.now) { + return currentTime; + } else { + throw new Error('Browser does not support Date.now()'); + } + }; + + FakeDate.toSource = GlobalDate.toSource; + FakeDate.toString = GlobalDate.toString; + FakeDate.parse = GlobalDate.parse; + FakeDate.UTC = GlobalDate.UTC; + } + } + + return MockDate; +}; + +getJasmineRequireObj().pp = function(j$) { + + function PrettyPrinter() { + this.ppNestLevel_ = 0; + this.seen = []; + } + + PrettyPrinter.prototype.format = function(value) { + this.ppNestLevel_++; + try { + if (j$.util.isUndefined(value)) { + this.emitScalar('undefined'); + } else if (value === null) { + this.emitScalar('null'); + } else if (value === 0 && 1/value === -Infinity) { + this.emitScalar('-0'); + } else if (value === j$.getGlobal()) { + this.emitScalar(''); + } else if (value.jasmineToString) { + this.emitScalar(value.jasmineToString()); + } else if (typeof value === 'string') { + this.emitString(value); + } else if (j$.isSpy(value)) { + this.emitScalar('spy on ' + value.and.identity()); + } else if (value instanceof RegExp) { + this.emitScalar(value.toString()); + } else if (typeof value === 'function') { + this.emitScalar('Function'); + } else if (typeof value.nodeType === 'number') { + this.emitScalar('HTMLNode'); + } else if (value instanceof Date) { + this.emitScalar('Date(' + value + ')'); + } else if (j$.util.arrayContains(this.seen, value)) { + this.emitScalar(''); + } else if (j$.isArray_(value) || j$.isA_('Object', value)) { + this.seen.push(value); + if (j$.isArray_(value)) { + this.emitArray(value); + } else { + this.emitObject(value); + } + this.seen.pop(); + } else { + this.emitScalar(value.toString()); + } + } finally { + this.ppNestLevel_--; + } + }; + + PrettyPrinter.prototype.iterateObject = function(obj, fn) { + for (var property in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, property)) { continue; } + fn(property, obj.__lookupGetter__ ? (!j$.util.isUndefined(obj.__lookupGetter__(property)) && + obj.__lookupGetter__(property) !== null) : false); + } + }; + + PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitString = j$.unimplementedMethod_; + + function StringPrettyPrinter() { + PrettyPrinter.call(this); + + this.string = ''; + } + + j$.util.inherit(StringPrettyPrinter, PrettyPrinter); + + StringPrettyPrinter.prototype.emitScalar = function(value) { + this.append(value); + }; + + StringPrettyPrinter.prototype.emitString = function(value) { + this.append('\'' + value + '\''); + }; + + StringPrettyPrinter.prototype.emitArray = function(array) { + if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { + this.append('Array'); + return; + } + var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH); + this.append('[ '); + for (var i = 0; i < length; i++) { + if (i > 0) { + this.append(', '); + } + this.format(array[i]); + } + if(array.length > length){ + this.append(', ...'); + } + this.append(' ]'); + }; + + StringPrettyPrinter.prototype.emitObject = function(obj) { + var constructorName = obj.constructor ? j$.fnNameFor(obj.constructor) : 'null'; + this.append(constructorName); + + if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { + return; + } + + var self = this; + this.append('({ '); + var first = true; + + this.iterateObject(obj, function(property, isGetter) { + if (first) { + first = false; + } else { + self.append(', '); + } + + self.append(property); + self.append(': '); + if (isGetter) { + self.append(''); + } else { + self.format(obj[property]); + } + }); + + this.append(' })'); + }; + + StringPrettyPrinter.prototype.append = function(value) { + this.string += value; + }; + + return function(value) { + var stringPrettyPrinter = new StringPrettyPrinter(); + stringPrettyPrinter.format(value); + return stringPrettyPrinter.string; + }; +}; + +getJasmineRequireObj().QueueRunner = function(j$) { + + function once(fn) { + var called = false; + return function() { + if (!called) { + called = true; + fn(); + } + }; + } + + function QueueRunner(attrs) { + this.queueableFns = attrs.queueableFns || []; + this.onComplete = attrs.onComplete || function() {}; + this.clearStack = attrs.clearStack || function(fn) {fn();}; + this.onException = attrs.onException || function() {}; + this.catchException = attrs.catchException || function() { return true; }; + this.userContext = attrs.userContext || {}; + this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout}; + this.fail = attrs.fail || function() {}; + } + + QueueRunner.prototype.execute = function() { + this.run(this.queueableFns, 0); + }; + + QueueRunner.prototype.run = function(queueableFns, recursiveIndex) { + var length = queueableFns.length, + self = this, + iterativeIndex; + + + for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) { + var queueableFn = queueableFns[iterativeIndex]; + if (queueableFn.fn.length > 0) { + attemptAsync(queueableFn); + return; + } else { + attemptSync(queueableFn); + } + } + + var runnerDone = iterativeIndex >= length; + + if (runnerDone) { + this.clearStack(this.onComplete); + } + + function attemptSync(queueableFn) { + try { + queueableFn.fn.call(self.userContext); + } catch (e) { + handleException(e, queueableFn); + } + } + + function attemptAsync(queueableFn) { + var clearTimeout = function () { + Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeoutId]]); + }, + next = once(function () { + clearTimeout(timeoutId); + self.run(queueableFns, iterativeIndex + 1); + }), + timeoutId; + + next.fail = function() { + self.fail.apply(null, arguments); + next(); + }; + + if (queueableFn.timeout) { + timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() { + var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'); + onException(error, queueableFn); + next(); + }, queueableFn.timeout()]]); + } + + try { + queueableFn.fn.call(self.userContext, next); + } catch (e) { + handleException(e, queueableFn); + next(); + } + } + + function onException(e, queueableFn) { + self.onException(e); + } + + function handleException(e, queueableFn) { + onException(e, queueableFn); + if (!self.catchException(e)) { + //TODO: set a var when we catch an exception and + //use a finally block to close the loop in a nice way.. + throw e; + } + } + }; + + return QueueRunner; +}; + +getJasmineRequireObj().ReportDispatcher = function() { + function ReportDispatcher(methods) { + + var dispatchedMethods = methods || []; + + for (var i = 0; i < dispatchedMethods.length; i++) { + var method = dispatchedMethods[i]; + this[method] = (function(m) { + return function() { + dispatch(m, arguments); + }; + }(method)); + } + + var reporters = []; + + this.addReporter = function(reporter) { + reporters.push(reporter); + }; + + return this; + + function dispatch(method, args) { + for (var i = 0; i < reporters.length; i++) { + var reporter = reporters[i]; + if (reporter[method]) { + reporter[method].apply(reporter, args); + } + } + } + } + + return ReportDispatcher; +}; + + +getJasmineRequireObj().SpyRegistry = function(j$) { + + function SpyRegistry(options) { + options = options || {}; + var currentSpies = options.currentSpies || function() { return []; }; + + this.spyOn = function(obj, methodName) { + if (j$.util.isUndefined(obj)) { + throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()'); + } + + if (j$.util.isUndefined(methodName)) { + throw new Error('No method name supplied'); + } + + if (j$.util.isUndefined(obj[methodName])) { + throw new Error(methodName + '() method does not exist'); + } + + if (obj[methodName] && j$.isSpy(obj[methodName])) { + //TODO?: should this return the current spy? Downside: may cause user confusion about spy state + throw new Error(methodName + ' has already been spied upon'); + } + + var spy = j$.createSpy(methodName, obj[methodName]); + + currentSpies().push({ + spy: spy, + baseObj: obj, + methodName: methodName, + originalValue: obj[methodName] + }); + + obj[methodName] = spy; + + return spy; + }; + + this.clearSpies = function() { + var spies = currentSpies(); + for (var i = 0; i < spies.length; i++) { + var spyEntry = spies[i]; + spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue; + } + }; + } + + return SpyRegistry; +}; + +getJasmineRequireObj().SpyStrategy = function() { + + function SpyStrategy(options) { + options = options || {}; + + var identity = options.name || 'unknown', + originalFn = options.fn || function() {}, + getSpy = options.getSpy || function() {}, + plan = function() {}; + + this.identity = function() { + return identity; + }; + + this.exec = function() { + return plan.apply(this, arguments); + }; + + this.callThrough = function() { + plan = originalFn; + return getSpy(); + }; + + this.returnValue = function(value) { + plan = function() { + return value; + }; + return getSpy(); + }; + + this.returnValues = function() { + var values = Array.prototype.slice.call(arguments); + plan = function () { + return values.shift(); + }; + return getSpy(); + }; + + this.throwError = function(something) { + var error = (something instanceof Error) ? something : new Error(something); + plan = function() { + throw error; + }; + return getSpy(); + }; + + this.callFake = function(fn) { + plan = fn; + return getSpy(); + }; + + this.stub = function(fn) { + plan = function() {}; + return getSpy(); + }; + } + + return SpyStrategy; +}; + +getJasmineRequireObj().Suite = function() { + function Suite(attrs) { + this.env = attrs.env; + this.id = attrs.id; + this.parentSuite = attrs.parentSuite; + this.description = attrs.description; + this.onStart = attrs.onStart || function() {}; + this.resultCallback = attrs.resultCallback || function() {}; + this.clearStack = attrs.clearStack || function(fn) {fn();}; + this.expectationFactory = attrs.expectationFactory; + this.expectationResultFactory = attrs.expectationResultFactory; + this.runnablesExplictlySetGetter = attrs.runnablesExplictlySetGetter || function() {}; + + this.beforeFns = []; + this.afterFns = []; + this.beforeAllFns = []; + this.afterAllFns = []; + this.queueRunner = attrs.queueRunner || function() {}; + this.disabled = false; + + this.children = []; + + this.result = { + id: this.id, + description: this.description, + fullName: this.getFullName(), + failedExpectations: [] + }; + } + + Suite.prototype.expect = function(actual) { + return this.expectationFactory(actual, this); + }; + + Suite.prototype.getFullName = function() { + var fullName = this.description; + for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { + if (parentSuite.parentSuite) { + fullName = parentSuite.description + ' ' + fullName; + } + } + return fullName; + }; + + Suite.prototype.disable = function() { + this.disabled = true; + }; + + Suite.prototype.beforeEach = function(fn) { + this.beforeFns.unshift(fn); + }; + + Suite.prototype.beforeAll = function(fn) { + this.beforeAllFns.push(fn); + }; + + Suite.prototype.afterEach = function(fn) { + this.afterFns.unshift(fn); + }; + + Suite.prototype.afterAll = function(fn) { + this.afterAllFns.push(fn); + }; + + Suite.prototype.addChild = function(child) { + this.children.push(child); + }; + + Suite.prototype.status = function() { + if (this.disabled) { + return 'disabled'; + } + + if (this.result.failedExpectations.length > 0) { + return 'failed'; + } else { + return 'finished'; + } + }; + + Suite.prototype.execute = function(onComplete) { + var self = this; + + this.onStart(this); + + if (this.disabled) { + complete(); + return; + } + + var allFns = []; + + for (var i = 0; i < this.children.length; i++) { + allFns.push(wrapChildAsAsync(this.children[i])); + } + + if (this.isExecutable()) { + allFns = this.beforeAllFns.concat(allFns); + allFns = allFns.concat(this.afterAllFns); + } + + this.queueRunner({ + queueableFns: allFns, + onComplete: complete, + userContext: this.sharedUserContext(), + onException: function() { self.onException.apply(self, arguments); } + }); + + function complete() { + self.result.status = self.status(); + self.resultCallback(self.result); + + if (onComplete) { + onComplete(); + } + } + + function wrapChildAsAsync(child) { + return { fn: function(done) { child.execute(done); } }; + } + }; + + Suite.prototype.isExecutable = function() { + var runnablesExplicitlySet = this.runnablesExplictlySetGetter(); + return !runnablesExplicitlySet && hasExecutableChild(this.children); + }; + + Suite.prototype.sharedUserContext = function() { + if (!this.sharedContext) { + this.sharedContext = this.parentSuite ? clone(this.parentSuite.sharedUserContext()) : {}; + } + + return this.sharedContext; + }; + + Suite.prototype.clonedSharedUserContext = function() { + return clone(this.sharedUserContext()); + }; + + Suite.prototype.onException = function() { + if(isAfterAll(this.children)) { + var data = { + matcherName: '', + passed: false, + expected: '', + actual: '', + error: arguments[0] + }; + this.result.failedExpectations.push(this.expectationResultFactory(data)); + } else { + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + child.onException.apply(child, arguments); + } + } + }; + + Suite.prototype.addExpectationResult = function () { + if(isAfterAll(this.children) && isFailure(arguments)){ + var data = arguments[1]; + this.result.failedExpectations.push(this.expectationResultFactory(data)); + } else { + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + child.addExpectationResult.apply(child, arguments); + } + } + }; + + function isAfterAll(children) { + return children && children[0].result.status; + } + + function isFailure(args) { + return !args[0]; + } + + function hasExecutableChild(children) { + var foundActive = false; + for (var i = 0; i < children.length; i++) { + if (children[i].isExecutable()) { + foundActive = true; + break; + } + } + return foundActive; + } + + function clone(obj) { + var clonedObj = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + clonedObj[prop] = obj[prop]; + } + } + + return clonedObj; + } + + return Suite; +}; + +if (typeof window == void 0 && typeof exports == 'object') { + exports.Suite = jasmineRequire.Suite; +} + +getJasmineRequireObj().Timer = function() { + var defaultNow = (function(Date) { + return function() { return new Date().getTime(); }; + })(Date); + + function Timer(options) { + options = options || {}; + + var now = options.now || defaultNow, + startTime; + + this.start = function() { + startTime = now(); + }; + + this.elapsed = function() { + return now() - startTime; + }; + } + + return Timer; +}; + +getJasmineRequireObj().Any = function() { + + function Any(expectedObject) { + this.expectedObject = expectedObject; + } + + Any.prototype.asymmetricMatch = function(other) { + if (this.expectedObject == String) { + return typeof other == 'string' || other instanceof String; + } + + if (this.expectedObject == Number) { + return typeof other == 'number' || other instanceof Number; + } + + if (this.expectedObject == Function) { + return typeof other == 'function' || other instanceof Function; + } + + if (this.expectedObject == Object) { + return typeof other == 'object'; + } + + if (this.expectedObject == Boolean) { + return typeof other == 'boolean'; + } + + return other instanceof this.expectedObject; + }; + + Any.prototype.jasmineToString = function() { + return ''; + }; + + return Any; +}; + +getJasmineRequireObj().Anything = function(j$) { + + function Anything() {} + + Anything.prototype.asymmetricMatch = function(other) { + return !j$.util.isUndefined(other) && other !== null; + }; + + Anything.prototype.jasmineToString = function() { + return ''; + }; + + return Anything; +}; + +getJasmineRequireObj().ArrayContaining = function(j$) { + function ArrayContaining(sample) { + this.sample = sample; + } + + ArrayContaining.prototype.asymmetricMatch = function(other) { + var className = Object.prototype.toString.call(this.sample); + if (className !== '[object Array]') { throw new Error('You must provide an array to arrayContaining, not \'' + this.sample + '\'.'); } + + for (var i = 0; i < this.sample.length; i++) { + var item = this.sample[i]; + if (!j$.matchersUtil.contains(other, item)) { + return false; + } + } + + return true; + }; + + ArrayContaining.prototype.jasmineToString = function () { + return ''; + }; + + return ArrayContaining; +}; + +getJasmineRequireObj().ObjectContaining = function(j$) { + + function ObjectContaining(sample) { + this.sample = sample; + } + + ObjectContaining.prototype.asymmetricMatch = function(other) { + if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); } + + for (var property in this.sample) { + if (!Object.prototype.hasOwnProperty.call(other, property) || + !j$.matchersUtil.equals(this.sample[property], other[property])) { + return false; + } + } + + return true; + }; + + ObjectContaining.prototype.jasmineToString = function() { + return ''; + }; + + return ObjectContaining; +}; + +getJasmineRequireObj().StringMatching = function(j$) { + + function StringMatching(expected) { + if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { + throw new Error('Expected is not a String or a RegExp'); + } + + this.regexp = new RegExp(expected); + } + + StringMatching.prototype.asymmetricMatch = function(other) { + return this.regexp.test(other); + }; + + StringMatching.prototype.jasmineToString = function() { + return ''; + }; + + return StringMatching; +}; + +getJasmineRequireObj().matchersUtil = function(j$) { + // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter? + + return { + equals: function(a, b, customTesters) { + customTesters = customTesters || []; + + return eq(a, b, [], [], customTesters); + }, + + contains: function(haystack, needle, customTesters) { + customTesters = customTesters || []; + + if ((Object.prototype.toString.apply(haystack) === '[object Array]') || + (!!haystack && !haystack.indexOf)) + { + for (var i = 0; i < haystack.length; i++) { + if (eq(haystack[i], needle, [], [], customTesters)) { + return true; + } + } + return false; + } + + return !!haystack && haystack.indexOf(needle) >= 0; + }, + + buildFailureMessage: function() { + var args = Array.prototype.slice.call(arguments, 0), + matcherName = args[0], + isNot = args[1], + actual = args[2], + expected = args.slice(3), + englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); + + var message = 'Expected ' + + j$.pp(actual) + + (isNot ? ' not ' : ' ') + + englishyPredicate; + + if (expected.length > 0) { + for (var i = 0; i < expected.length; i++) { + if (i > 0) { + message += ','; + } + message += ' ' + j$.pp(expected[i]); + } + } + + return message + '.'; + } + }; + + function isAsymmetric(obj) { + return obj && j$.isA_('Function', obj.asymmetricMatch); + } + + function asymmetricMatch(a, b) { + var asymmetricA = isAsymmetric(a), + asymmetricB = isAsymmetric(b); + + if (asymmetricA && asymmetricB) { + return undefined; + } + + if (asymmetricA) { + return a.asymmetricMatch(b); + } + + if (asymmetricB) { + return b.asymmetricMatch(a); + } + } + + // Equality function lovingly adapted from isEqual in + // [Underscore](http://underscorejs.org) + function eq(a, b, aStack, bStack, customTesters) { + var result = true; + + var asymmetricResult = asymmetricMatch(a, b); + if (!j$.util.isUndefined(asymmetricResult)) { + return asymmetricResult; + } + + for (var i = 0; i < customTesters.length; i++) { + var customTesterResult = customTesters[i](a, b); + if (!j$.util.isUndefined(customTesterResult)) { + return customTesterResult; + } + } + + if (a instanceof Error && b instanceof Error) { + return a.message == b.message; + } + + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) { return a !== 0 || 1 / a == 1 / b; } + // A strict comparison is necessary because `null == undefined`. + if (a === null || b === null) { return a === b; } + var className = Object.prototype.toString.call(a); + if (className != Object.prototype.toString.call(b)) { return false; } + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') { return false; } + + var aIsDomNode = j$.isDomNode(a); + var bIsDomNode = j$.isDomNode(b); + if (aIsDomNode && bIsDomNode) { + // At first try to use DOM3 method isEqualNode + if (a.isEqualNode) { + return a.isEqualNode(b); + } + // IE8 doesn't support isEqualNode, try to use outerHTML && innerText + var aIsElement = a instanceof Element; + var bIsElement = b instanceof Element; + if (aIsElement && bIsElement) { + return a.outerHTML == b.outerHTML; + } + if (aIsElement || bIsElement) { + return false; + } + return a.innerText == b.innerText && a.textContent == b.textContent; + } + if (aIsDomNode || bIsDomNode) { + return false; + } + + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] == a) { return bStack[length] == b; } + } + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + var size = 0; + // Recursively compare objects and arrays. + // Compare array lengths to determine if a deep comparison is necessary. + if (className == '[object Array]' && a.length !== b.length) { + result = false; + } + + if (result) { + // Objects with different constructors are not equivalent, but `Object`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(isFunction(aCtor) && (aCtor instanceof aCtor) && + isFunction(bCtor) && (bCtor instanceof bCtor))) { + return false; + } + // Deep compare objects. + for (var key in a) { + if (has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) { break; } + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (has(b, key) && !(size--)) { break; } + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + + return result; + + function has(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); + } + + function isFunction(obj) { + return typeof obj === 'function'; + } + } +}; + +getJasmineRequireObj().toBe = function() { + function toBe() { + return { + compare: function(actual, expected) { + return { + pass: actual === expected + }; + } + }; + } + + return toBe; +}; + +getJasmineRequireObj().toBeCloseTo = function() { + + function toBeCloseTo() { + return { + compare: function(actual, expected, precision) { + if (precision !== 0) { + precision = precision || 2; + } + + return { + pass: Math.abs(expected - actual) < (Math.pow(10, -precision) / 2) + }; + } + }; + } + + return toBeCloseTo; +}; + +getJasmineRequireObj().toBeDefined = function() { + function toBeDefined() { + return { + compare: function(actual) { + return { + pass: (void 0 !== actual) + }; + } + }; + } + + return toBeDefined; +}; + +getJasmineRequireObj().toBeFalsy = function() { + function toBeFalsy() { + return { + compare: function(actual) { + return { + pass: !!!actual + }; + } + }; + } + + return toBeFalsy; +}; + +getJasmineRequireObj().toBeGreaterThan = function() { + + function toBeGreaterThan() { + return { + compare: function(actual, expected) { + return { + pass: actual > expected + }; + } + }; + } + + return toBeGreaterThan; +}; + + +getJasmineRequireObj().toBeLessThan = function() { + function toBeLessThan() { + return { + + compare: function(actual, expected) { + return { + pass: actual < expected + }; + } + }; + } + + return toBeLessThan; +}; +getJasmineRequireObj().toBeNaN = function(j$) { + + function toBeNaN() { + return { + compare: function(actual) { + var result = { + pass: (actual !== actual) + }; + + if (result.pass) { + result.message = 'Expected actual not to be NaN.'; + } else { + result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be NaN.'; }; + } + + return result; + } + }; + } + + return toBeNaN; +}; + +getJasmineRequireObj().toBeNull = function() { + + function toBeNull() { + return { + compare: function(actual) { + return { + pass: actual === null + }; + } + }; + } + + return toBeNull; +}; + +getJasmineRequireObj().toBeTruthy = function() { + + function toBeTruthy() { + return { + compare: function(actual) { + return { + pass: !!actual + }; + } + }; + } + + return toBeTruthy; +}; + +getJasmineRequireObj().toBeUndefined = function() { + + function toBeUndefined() { + return { + compare: function(actual) { + return { + pass: void 0 === actual + }; + } + }; + } + + return toBeUndefined; +}; + +getJasmineRequireObj().toContain = function() { + function toContain(util, customEqualityTesters) { + customEqualityTesters = customEqualityTesters || []; + + return { + compare: function(actual, expected) { + + return { + pass: util.contains(actual, expected, customEqualityTesters) + }; + } + }; + } + + return toContain; +}; + +getJasmineRequireObj().toEqual = function() { + + function toEqual(util, customEqualityTesters) { + customEqualityTesters = customEqualityTesters || []; + + return { + compare: function(actual, expected) { + var result = { + pass: false + }; + + result.pass = util.equals(actual, expected, customEqualityTesters); + + return result; + } + }; + } + + return toEqual; +}; + +getJasmineRequireObj().toHaveBeenCalled = function(j$) { + + function toHaveBeenCalled() { + return { + compare: function(actual) { + var result = {}; + + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + if (arguments.length > 1) { + throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); + } + + result.pass = actual.calls.any(); + + result.message = result.pass ? + 'Expected spy ' + actual.and.identity() + ' not to have been called.' : + 'Expected spy ' + actual.and.identity() + ' to have been called.'; + + return result; + } + }; + } + + return toHaveBeenCalled; +}; + +getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { + + function toHaveBeenCalledWith(util, customEqualityTesters) { + return { + compare: function() { + var args = Array.prototype.slice.call(arguments, 0), + actual = args[0], + expectedArgs = args.slice(1), + result = { pass: false }; + + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + if (!actual.calls.any()) { + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but it was never called.'; }; + return result; + } + + if (util.contains(actual.calls.allArgs(), expectedArgs, customEqualityTesters)) { + result.pass = true; + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' not to have been called with ' + j$.pp(expectedArgs) + ' but it was.'; }; + } else { + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but actual calls were ' + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + '.'; }; + } + + return result; + } + }; + } + + return toHaveBeenCalledWith; +}; + +getJasmineRequireObj().toMatch = function(j$) { + + function toMatch() { + return { + compare: function(actual, expected) { + if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { + throw new Error('Expected is not a String or a RegExp'); + } + + var regexp = new RegExp(expected); + + return { + pass: regexp.test(actual) + }; + } + }; + } + + return toMatch; +}; + +getJasmineRequireObj().toThrow = function(j$) { + + function toThrow(util) { + return { + compare: function(actual, expected) { + var result = { pass: false }, + threw = false, + thrown; + + if (typeof actual != 'function') { + throw new Error('Actual is not a Function'); + } + + try { + actual(); + } catch (e) { + threw = true; + thrown = e; + } + + if (!threw) { + result.message = 'Expected function to throw an exception.'; + return result; + } + + if (arguments.length == 1) { + result.pass = true; + result.message = function() { return 'Expected function not to throw, but it threw ' + j$.pp(thrown) + '.'; }; + + return result; + } + + if (util.equals(thrown, expected)) { + result.pass = true; + result.message = function() { return 'Expected function not to throw ' + j$.pp(expected) + '.'; }; + } else { + result.message = function() { return 'Expected function to throw ' + j$.pp(expected) + ', but it threw ' + j$.pp(thrown) + '.'; }; + } + + return result; + } + }; + } + + return toThrow; +}; + +getJasmineRequireObj().toThrowError = function(j$) { + function toThrowError (util) { + return { + compare: function(actual) { + var threw = false, + pass = {pass: true}, + fail = {pass: false}, + thrown; + + if (typeof actual != 'function') { + throw new Error('Actual is not a Function'); + } + + var errorMatcher = getMatcher.apply(null, arguments); + + try { + actual(); + } catch (e) { + threw = true; + thrown = e; + } + + if (!threw) { + fail.message = 'Expected function to throw an Error.'; + return fail; + } + + if (!(thrown instanceof Error)) { + fail.message = function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; }; + return fail; + } + + if (errorMatcher.hasNoSpecifics()) { + pass.message = 'Expected function not to throw an Error, but it threw ' + j$.fnNameFor(thrown) + '.'; + return pass; + } + + if (errorMatcher.matches(thrown)) { + pass.message = function() { + return 'Expected function not to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + '.'; + }; + return pass; + } else { + fail.message = function() { + return 'Expected function to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + + ', but it threw ' + errorMatcher.thrownDescription(thrown) + '.'; + }; + return fail; + } + } + }; + + function getMatcher() { + var expected = null, + errorType = null; + + if (arguments.length == 2) { + expected = arguments[1]; + if (isAnErrorType(expected)) { + errorType = expected; + expected = null; + } + } else if (arguments.length > 2) { + errorType = arguments[1]; + expected = arguments[2]; + if (!isAnErrorType(errorType)) { + throw new Error('Expected error type is not an Error.'); + } + } + + if (expected && !isStringOrRegExp(expected)) { + if (errorType) { + throw new Error('Expected error message is not a string or RegExp.'); + } else { + throw new Error('Expected is not an Error, string, or RegExp.'); + } + } + + function messageMatch(message) { + if (typeof expected == 'string') { + return expected == message; + } else { + return expected.test(message); + } + } + + return { + errorTypeDescription: errorType ? j$.fnNameFor(errorType) : 'an exception', + thrownDescription: function(thrown) { + var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception', + thrownMessage = ''; + + if (expected) { + thrownMessage = ' with message ' + j$.pp(thrown.message); + } + + return thrownName + thrownMessage; + }, + messageDescription: function() { + if (expected === null) { + return ''; + } else if (expected instanceof RegExp) { + return ' with a message matching ' + j$.pp(expected); + } else { + return ' with message ' + j$.pp(expected); + } + }, + hasNoSpecifics: function() { + return expected === null && errorType === null; + }, + matches: function(error) { + return (errorType === null || error.constructor === errorType) && + (expected === null || messageMatch(error.message)); + } + }; + } + + function isStringOrRegExp(potential) { + return potential instanceof RegExp || (typeof potential == 'string'); + } + + function isAnErrorType(type) { + if (typeof type !== 'function') { + return false; + } + + var Surrogate = function() {}; + Surrogate.prototype = type.prototype; + return (new Surrogate()) instanceof Error; + } + } + + return toThrowError; +}; + +getJasmineRequireObj().interface = function(jasmine, env) { + var jasmineInterface = { + describe: function(description, specDefinitions) { + return env.describe(description, specDefinitions); + }, + + xdescribe: function(description, specDefinitions) { + return env.xdescribe(description, specDefinitions); + }, + + fdescribe: function(description, specDefinitions) { + return env.fdescribe(description, specDefinitions); + }, + + it: function() { + return env.it.apply(env, arguments); + }, + + xit: function() { + return env.xit.apply(env, arguments); + }, + + fit: function() { + return env.fit.apply(env, arguments); + }, + + beforeEach: function() { + return env.beforeEach.apply(env, arguments); + }, + + afterEach: function() { + return env.afterEach.apply(env, arguments); + }, + + beforeAll: function() { + return env.beforeAll.apply(env, arguments); + }, + + afterAll: function() { + return env.afterAll.apply(env, arguments); + }, + + expect: function(actual) { + return env.expect(actual); + }, + + pending: function() { + return env.pending.apply(env, arguments); + }, + + fail: function() { + return env.fail.apply(env, arguments); + }, + + spyOn: function(obj, methodName) { + return env.spyOn(obj, methodName); + }, + + jsApiReporter: new jasmine.JsApiReporter({ + timer: new jasmine.Timer() + }), + + jasmine: jasmine + }; + + jasmine.addCustomEqualityTester = function(tester) { + env.addCustomEqualityTester(tester); + }; + + jasmine.addMatchers = function(matchers) { + return env.addMatchers(matchers); + }; + + jasmine.clock = function() { + return env.clock; + }; + + return jasmineInterface; +}; + +getJasmineRequireObj().version = function() { + return '2.2.0'; +}; diff --git a/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine_favicon.png b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine_favicon.png new file mode 100755 index 0000000..3b84583 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/jasmine-2.2.0/jasmine_favicon.png differ diff --git a/platforms/android/platform_www/cdvtests/jasmine-medic.js b/platforms/android/platform_www/cdvtests/jasmine-medic.js new file mode 100644 index 0000000..4194f3a --- /dev/null +++ b/platforms/android/platform_www/cdvtests/jasmine-medic.js @@ -0,0 +1,123 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* global device */ + +jasmineRequire.medic = function(j$) { + j$.MedicReporter = jasmineRequire.MedicReporter(j$); +}; + +jasmineRequire.MedicReporter = function(j$) { + var noopTimer = { + start: function() {}, + elapsed: function() { return 0; } + }; + + var platformMap = { + 'ipod touch':'ios', + 'iphone':'ios' + }; + + function MedicReporter(options) { + var logoptions = options.log || { logurl: 'http://127.0.0.1:5984/' }, // TODO: http://localhost:6800 + timer = options.timer || noopTimer, + results = [], + specsExecuted = 0, + failureCount = 0, + pendingSpecCount = 0; + + + var serverurl = logoptions.logurl; + + this.initialize = function() { + }; + + var totalSpecsDefined; + this.jasmineStarted = function(options) { + totalSpecsDefined = options.totalSpecsDefined || 0; + timer.start(); + }; + + this.suiteStarted = function(result) { + }; + + this.suiteDone = function(result) { + + }; + + this.specStarted = function(result) { + // Start timing this spec + }; + + this.specDone = function(result) { + if (result.status != "disabled") { + specsExecuted++; + } + if (result.status == "failed") { + failureCount++; + results.push(result); + } + if (result.status == "pending") { + pendingSpecCount++; + } + }; + + var buildResults = function(){ + var json ={specs:specsExecuted, failures:failureCount, results: results}; + return json; + }; + + this.jasmineDone = function() { + var p = 'Desktop'; + var devmodel='none'; + var version = cordova.version; + if(typeof device != 'undefined') { + p = device.platform.toLowerCase(); + devmodel=device.model || device.name; + version = device.version.toLowerCase(); + } + + this.postTests({ + mobilespec:buildResults(), + platform:(platformMap.hasOwnProperty(p) ? platformMap[p] : p), + version:version, + sha: options.sha, + timestamp:Math.round(Math.floor((new Date()).getTime() / 1000)), + model:devmodel + }); + + }; + + this.postTests = function(json) { + console.log('posting tests'); + + var xhr = new XMLHttpRequest(); + var doc_id = [options.sha, json.version, json.model].map(encodeURIComponent).join('__'); + var doc_url = serverurl + '/mobilespec_results/' + doc_id; + xhr.open("PUT", doc_url, true); + xhr.setRequestHeader("Content-Type","application/json"); + xhr.send(JSON.stringify(json)); + }; + return this; + } + + return MedicReporter; +}; diff --git a/platforms/android/platform_www/cdvtests/main-bootstrap.js b/platforms/android/platform_www/cdvtests/main-bootstrap.js new file mode 100644 index 0000000..58624b7 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/main-bootstrap.js @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +document.addEventListener("deviceready", function() { + 'use strict'; + + cordova.require('cordova-plugin-test-framework.main').init(); +}); diff --git a/platforms/android/platform_www/cdvtests/main.css b/platforms/android/platform_www/cdvtests/main.css new file mode 100644 index 0000000..9223dbd --- /dev/null +++ b/platforms/android/platform_www/cdvtests/main.css @@ -0,0 +1,148 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +*, *:before, *:after { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +html, body { + height: 100%; + width: 100%; + margin: 0; + padding: 0; +} + +#title { + position: fixed; + height: 30px; + width: 100%; + top: 0; + z-index: 1000; + + background-color: #75B2F0; + font-size: 25px; + text-align: center; + font-weight: bold; + white-space: nowrap; +} + +#middle { + position: absolute; + top: 30px; + bottom: 20px; + padding-bottom: 40%; + width: 100%; + overflow-y: auto; + overflow-x: auto; +} + +#log { + position: fixed; + height: 20px; + width: 100%; + bottom: 0; + z-index: 1000; + border-top: 2px solid #777; + transition: 0.25s ease; +} + +body.expanded-log #middle { + margin-bottom: 40%; +} + +body.expanded-log #log { + height: 40%; +} + +#log--title { + position: absolute; + top: 0; + height: 20px; + width: 100%; + background-color: #93AAC2; +} + +#log--content { + position: absolute; + top: 20px; + bottom: 0; + width: 100%; + overflow-x: none; + overflow-y: auto; + background-color: white; +} + +.log--content--line { + border-bottom: 1px solid #ccc; + white-space: pre; +} + +.log--content--line--log { + background-color: white; +} + +.log--content--line--warn { + background-color: #FCFFA6; +} + +.log--content--line--error { + background-color: #FFA6A6; +} + +#info{ + background:#ffa; + border: 1px solid #ffd324; + -webkit-border-radius: 5px; + border-radius: 5px; + clear:both; + margin:15px 6px 0; + min-width:295px; + max-width:97%; + padding:4px 0px 2px 10px; + word-wrap:break-word; + margin-bottom:10px; + display:inline-block; + min-height: 160px; + max-height: 300px; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +#test-enablers-container { + margin: 10px 5px; +} + +#test-expander { + text-decoration: underline; +} + +#test-list { + display: none; +} + +#test-list.expanded { + display: inherit; +} + +#test-list label { + display: block; +} diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/.gitignore b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/.gitignore new file mode 100755 index 0000000..f678651 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/.gitignore @@ -0,0 +1,6 @@ +node_modules +npm-debug.log +tmp +.DS_Store +src/ +.tern-port diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/Gruntfile.js b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/Gruntfile.js new file mode 100755 index 0000000..1952688 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/Gruntfile.js @@ -0,0 +1,277 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/*global module:false, require:false, process:false*/ + +var path = require('path'), + os = require('os'), + chromiumSrc = process.env.CHROMIUM_SRC || ""; + + +module.exports = function(grunt) { + 'use strict'; + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + + stylus: { + options: { + paths: grunt.file.expand(__dirname + '/node_modules/topcoat-*/src/') + /* FIXME: Utils is the last needing to be moved out of mixins + * folder + */ + .concat(grunt.file.expand(__dirname + '/node_modules/topcoat-utils/src/mixins/')), + compress: false + }, + + mobilelight: { + options: { + import: ['theme-topcoat-mobile-light', 'utils'] + }, + + files: [{ + src: 'node_modules/topcoat-*/src/**/*.styl', + dest: 'css/topcoat-mobile-light.css' + }] + }, + + mobiledark: { + options: { + import: ['theme-topcoat-mobile-dark', 'utils'] + }, + + files: [{ + src: 'node_modules/topcoat-*/src/**/*.styl', + dest: 'css/topcoat-mobile-dark.css' + }] + }, + + desktoplight: { + options: { + import: ['theme-topcoat-desktop-light', 'utils'] + }, + files: [{ + src: [ + 'node_modules/topcoat-*/src/**/*.styl', + '!node_modules/topcoat-navigation-bar/src/*.styl', + '!node_modules/topcoat-list/src/*.styl' + ], + dest: 'css/topcoat-desktop-light.css' + }] + }, + + desktopdark: { + options: { + import: ['theme-topcoat-desktop-dark', 'utils'] + }, + + files: [{ + src: [ + 'node_modules/topcoat-*/src/**/*.styl', + '!node_modules/topcoat-navigation-bar/src/*.styl', + '!node_modules/topcoat-list/src/*.styl' + ], + dest: 'css/topcoat-desktop-dark.css' + }] + } + }, + + topdoc: { + usageguides: { + options: { + source: 'css', + destination: 'demo', + template: 'node_modules/topdoc-theme/', + templateData: { + "title": "Topcoat", + "subtitle": "CSS for clean and fast web apps", + "download": { + "url": "https://github.com/topcoat/topcoat/archive/v0.7.0.zip", + "label": "Download" + }, + "homeURL": "http://topcoat.io", + "siteNav": [ + { + "url": "http://topcoat.io/topcoat", + "text": "Demo" + }, + { + "url": "http://bench.topcoat.io/", + "text": "Benchmarks" + }, + { + "url": "http://topcoat.io/blog", + "text": "Blog" + } + ] + } + } + } + }, + + autoprefixer: { + dist: { + options: { + /* + * Add target browsers here + * https://github.com/ai/autoprefixer#browsers + * browsers: ['android 4'] + */ + }, + files: [{ + src: 'css/topcoat-desktop-dark.css', + dest: 'css/topcoat-desktop-dark.css' + }, + { + src: 'css/topcoat-desktop-light.css', + dest: 'css/topcoat-desktop-light.css' + }, + { + src: 'css/topcoat-mobile-dark.css', + dest: 'css/topcoat-mobile-dark.css' + }, + { + src: 'css/topcoat-mobile-light.css', + dest: 'css/topcoat-mobile-light.css' + }] + } + + }, + + cssmin: { + minify: { + expand: true, + cwd: 'css', + src: ['*.css', '!*.min.css'], + dest: 'css', + ext: '.min.css' + } + }, + + htmlmin: { + telemetry: { + options: { + removeComments: true, + collapseWhitespace: true + }, + files: [{ + expand: true, + src: ['dev/test/**/topcoat/*.html'], + dest: '', + ext: '.test.html', + }], + }, + }, + + clean: { + release: ['css'] + }, + + copy: { + release: { + files: [{ + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/font/**', + dest: 'font' + }, { + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/img/*', + dest: 'img' + }] + }, + + telemetry: { + files: [{ + expand: true, + cwd: 'dev/test/perf/telemetry/perf/', + src: ['**'], + dest: path.join(chromiumSrc, 'tools/perf/') + }, { + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/font/**', + dest: path.join(chromiumSrc, 'tools/perf/page_sets/topcoat/release/font') + }, { + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/img/*', + dest: path.join(chromiumSrc, 'tools/perf/page_sets/topcoat/release/img') + }, { + src: ['css/**'], + dest: path.join(chromiumSrc, 'tools/perf/page_sets/topcoat/release/') + }] + } + }, + + jshint: { + options: { + curly: true, + eqeqeq: true, + immed: true, + latedef: true, + newcap: true, + noarg: true, + sub: true, + undef: true, + unused: true, + boss: true, + eqnull: true, + browser: true, + globals: { + jQuery: true + } + }, + gruntfile: { + src: 'Gruntfile.js' + }, + lib_test: { + src: ['dev/lib/**/*.js', 'dev/test/**/*.js'] + } + }, + + watch: { + files: ['src/**/*.styl'], + tasks: ['compile'] + } + + }); + + // These plugins provide necessary tasks. + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-contrib-jade'); + grunt.loadNpmTasks('grunt-contrib-stylus'); + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-exec'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-topdoc'); + grunt.loadNpmTasks('grunt-contrib-cssmin'); + grunt.loadNpmTasks('grunt-contrib-htmlmin'); + grunt.loadNpmTasks('grunt-autoprefixer'); + + //Load local tasks + grunt.loadTasks('dev/tasks'); + + // Default task. + grunt.registerTask('default', ['clean', 'stylus', 'autoprefixer', 'cssmin', 'topdoc', 'copy:release']); + grunt.registerTask('release', ['default', 'clean:src']); + grunt.registerTask('compile', ['topcoat:compile', 'topdoc', 'copy:release']); + + grunt.registerTask('telemetry', '', function(platform, theme) { + if (chromiumSrc === "") grunt.fail.warn("Set CHROMIUM_SRC to point to the correct location\n"); + grunt.task.run('check_chromium_src', 'perf:'.concat(platform || 'mobile').concat(':').concat(theme || 'light'), 'htmlmin:telemetry', 'copy:telemetry'); + }); +}; diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/LICENSE b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/LICENSE new file mode 100755 index 0000000..242fd8a --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/LICENSE @@ -0,0 +1,203 @@ +Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/NOTICE b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/NOTICE new file mode 100755 index 0000000..3c8ddfa --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/NOTICE @@ -0,0 +1,193 @@ +Topcoat is licensed under the Apache license version 2.0, January 2004 (see LICENSE file). + +Topcoat uses the following third party libraries that may have licenses +differing from that of Topcoat itself. You can find the libraries and their +respective licenses below. + + - Source Code Pro ./src/font/SourceCodePro + + https://github.com/adobe/source-code-pro + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + This Font Software is licensed under the SIL Open Font License, Version 1.1. + This license is available with a FAQ at: http://scripts.sil.org/OFL + +- Source Sans Pro ./src/font/SourceSansPro + + https://github.com/adobe/source-sans-pro + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + This Font Software is licensed under the SIL Open Font License, Version 1.1. + This license is available with a FAQ at: http://scripts.sil.org/OFL + +The following frameworks and libraries are provided just for testing and benchmarking and, as provided, should not be included as part of Topcoat output. + + - Bootstrap - ./test/third-party/bootstrap + + https://github.com/twitter/bootstrap + + Copyright 2012 Twitter, Inc + Licensed under the Apache License v2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + - jQuery - ./test/third-party/jquery-1.8.2.js + + https://github.com/jquery/jquery + + Copyright 2011, John Resig + Dual licensed under the MIT or GPL Version 2 licenses. + http://jquery.org/license + + Includes Sizzle.js + http://sizzlejs.com/ + Copyright 2011, The Dojo Foundation + Released under the MIT, BSD, and GPL Licenses. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + - Modernizr - ./test/third-party/modernizr + + https://github.com/Modernizr/Modernizr + + Modernizr is available under the MIT license + + Copyright (c) 2009–2011 + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + - Benchmark.js - ./test/third-party/benchmarkjs + + https://github.com/alexanderbeletsky/benchmark-js + + Copyright 2010-2012 Mathias Bynens + Based on JSLitmus.js, copyright Robert Kieffer + Modified by John-David Dalton + Available under MIT license + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - normalize.css - ./test/third-party/normalize + + Copyright (c) Nicolas Gallagher and Jonathan Neal + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - Foundation - ./test/third-party/foundation + + Copyright (c) 2012 Mark Hayes + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - ua-parser ./test/third-party/ua-parser + + https://github.com/faisalman/ua-parser-js + + Copyright © 2012 Faisalman + Dual licensed under GPLv2 & MIT + Copyright © 2012 Faisalman + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + - HTML5 boilerplate + + https://github.com/h5bp/html5-boilerplate + + Copyright (c) HTML5 Boilerplate + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - classList - ./test/third-party/classlist + + http://purl.eligrey.com/github/classList.js/blob/master/classList.js + + This software is dedicated to the public domain. No warranty is expressed or implied. + Use this software at your own risk. + + - fastclick - ./test/third-party/fastclick + + https://github.com/ftlabs/fastclick + + Copyright (C) 2012 The Financial Times Ltd. + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/README.md b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/README.md new file mode 100755 index 0000000..a89dad2 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/README.md @@ -0,0 +1,89 @@ +# Topcoat + +CSS for clean and fast web apps + +--- + +## Usage + +* [Download Topcoat](https://github.com/topcoat/topcoat/archive/0.7.0.zip) + +* Open index.html to view the usage guides. +* Copy your desired theme CSS from the `css/` folder into your project +* Copy the `img/` and `font/` folders into your project ( Feel free to only + copy the images and font weights you intend to use ) +* Link the CSS into your page + +```css + +``` + +_*Alternatively incorporate the css into your build process if you are so +inclined._ + +--- + +## Contributing + +Start by checking out our [Backlog](http://huboard.com/topcoat/topcoat/backlog). (Pls file issues against this repo.) + +* [Fill out the CLA here](http://topcoat.io/dev/topcoat-cla.html) +* [fork](https://help.github.com/articles/fork-a-repo) the repo +* Create a branch + + git checkout -b my_branch + +* Add your changes following the [coding guidelines](https://github.com/topcoat/topcoat/wiki/Coding-Guidelines) +* Commit your changes + + git commit -am "Added some awesome stuff" + +* Push your branch + + git push origin my_branch + +* make a [pull request](https://help.github.com/articles/using-pull-requests) + +For the details see our [Engineering Practices](https://github.com/topcoat/topcoat/wiki/Engineering-Practices). + +### Testing + +For performance tests, see [dev/test/perf/telemetry/](https://github.com/topcoat/topcoat/tree/master/dev/test/perf/telemetry). + +### Building + +Topcoat uses [Grunt](http://gruntjs.com/) to build + +* Open the terminal from the topcoat directory + + cd topcoat + +* Install [npm](http://nodejs.org/download/) +_*comes packaged with node._ +* Install its command line interface (CLI) globally + + npm install -g grunt-cli + +* Install dependencies with npm + + npm install + + +_*Topcoat uses Grunt 0.4.0. You might want to [read](http://gruntjs.com/getting-started) more on their website if you haven't upgraded since a lot has changed._ + +* Type `grunt` in the command line to build the css. +* The results will be built into the release folder. +* Alternatively type `grunt watch` to have the build run automatically when you make changes to +source files. + +--- + +## Release notes +See [Release Notes](https://github.com/topcoat/topcoat/releases/). + +--- + +## License + +[Apache license](https://raw.github.com/topcoat/topcoat/master/LICENSE) + diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/contributors.txt b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/contributors.txt new file mode 100755 index 0000000..e4cd8b7 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/contributors.txt @@ -0,0 +1,7 @@ +# Github accounts of the people who signed the TopCoat CLA (http://topcoat.io/dev/topcoat-cla.html). +# CLA needs to be signed before accepting pull requests. +@yourpalsonja +@noformnocontent +@jrowny +@aparticulate +@jlembeck diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.css new file mode 100755 index 0000000..e590e11 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.css @@ -0,0 +1,3450 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 1rem; +} + +input[type="checkbox"] { + height: 1rem; + width: 1rem; + margin-top: 0; + margin-right: -1rem; + margin-bottom: -1rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 1rem; +} + +.topcoat-checkbox__checkmark:before { + width: 1rem; + height: 1rem; + background: #595b5b; + border: 1px solid #303233; + border-radius: 3px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-checkbox__checkmark { + width: 1rem; + height: 1rem; +} + +.topcoat-checkbox__checkmark:after { + top: 2px; + left: 1px; + opacity: 0; + width: 14px; + height: 4px; + background: transparent; + border: 7px solid #fff; + border-width: 3px; + border-top: none; + border-right: none; + border-radius: 1px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.25rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: baseline; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 4px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-icon-button:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 1.688rem; + height: 1.688rem; + line-height: 1.688rem; +} + +.topcoat-icon-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 0.81406rem; + height: 0.81406rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 1.06344rem; + height: 1.06344rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
    +
    + + +
    +
    + + +
    +
    + + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.063rem; + width: 1.063rem; + margin-top: 0; + margin-right: -1.063rem; + margin-bottom: -1.063rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #c6c8c8; + line-height: 1.063rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.063rem; + height: 1.063rem; + background: #595b5b; + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.063rem; + height: 1.063rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.313rem; + height: 0.313rem; + background: #fff; + border: 1px solid rgba(255,255,255,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 0.313rem; + left: 0.313rem; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 4px; + border: 1px solid #303233; + background-color: #424546; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-moz-range-track { + border-radius: 4px; + border: 1px solid #303233; + background-color: #424546; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 4px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range::-moz-range-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 4px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 1.313rem; + font-size: 12px; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + padding: 0 0 0 1.3rem; + border-radius: 15px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 12px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 1.688rem; + font-size: 0.875rem; + font-weight: 400; + padding: 0 0 0 1.8rem; + border-radius: 25px; + background-position: 1.2em center; + background-size: 0.875rem; +} + +.topcoat-search-input--large:disabled { + color: #fff; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + +
    +
    + + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 12px; + padding: 0 0.563rem; + border-radius: 4px; + border: 1px solid #303233; + overflow: hidden; + width: 3.5rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 2.6rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #5dc1ff; + background-color: #404141; + right: 0.8rem; + padding-left: 0.75rem; +} + +.topcoat-switch__toggle { + line-height: 1.313rem; + height: 1.313rem; + width: 1rem; + border-radius: 4px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #595b5b; + border: 1px solid #303233; + margin-left: -0.6rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #727373; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #404141; + left: 0.8rem; + padding-left: 0.6rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 1.85rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
    + + + +
    + examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 0.563rem; + height: 1.313rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border-top: 1px solid #303233; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #5dc1ff; + background-color: #404141; + box-shadow: inset 0 0 2px #313231; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 1.313rem; + font-size: 12px; + letter-spacing: 0; + padding: 0 0.563rem; + border: 1px solid #303233; + border-radius: 4px; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 1.688rem; + font-size: 0.875rem; +} + +.topcoat-text-input--large:disabled { + color: #fff; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 1rem; + font-size: 1rem; + font-weight: 400; + border-radius: 4px; + line-height: 1.313rem; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + letter-spacing: 0; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 1.3rem; + line-height: 1.688rem; +} + +.topcoat-textarea--large:disabled { + color: #fff; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #fff; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #4b4d4e; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_light.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.min.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.min.css new file mode 100755 index 0000000..1623395 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-dark.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:4px;border-bottom-left-radius:4px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:4px;border-bottom-right-radius:4px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:1rem}input[type=checkbox]{height:1rem;width:1rem;margin-top:0;margin-right:-1rem;margin-bottom:-1rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:1rem}.topcoat-checkbox__checkmark:before{width:1rem;height:1rem;background:#595b5b;border:1px solid #303233;border-radius:3px;box-shadow:inset 0 1px #727373}.topcoat-checkbox__checkmark{width:1rem;height:1rem}.topcoat-checkbox__checkmark:after{top:2px;left:1px;opacity:0;width:14px;height:4px;background:transparent;border:7px solid #fff;border-width:3px;border-top:0;border-right:0;border-radius:1px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .25rem;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:baseline;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:4px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#646666}.topcoat-icon-button:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:1.688rem;height:1.688rem;line-height:1.688rem}.topcoat-icon-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:.81406rem;height:.81406rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:1.06344rem;height:1.06344rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.063rem;width:1.063rem;margin-top:0;margin-right:-1.063rem;margin-bottom:-1.063rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#c6c8c8;line-height:1.063rem}.topcoat-radio-button__checkmark:before{width:1.063rem;height:1.063rem;background:#595b5b;border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-radio-button__checkmark{position:relative;width:1.063rem;height:1.063rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.313rem;height:.313rem;background:#fff;border:1px solid rgba(255,255,255,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:.313rem;left:.313rem}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:4px;border:1px solid #303233;background-color:#424546;height:.5rem;border-radius:15px}.topcoat-range::-moz-range-track{border-radius:4px;border:1px solid #303233;background-color:#424546;height:.5rem;border-radius:15px}.topcoat-range::-webkit-slider-thumb{height:1.313rem;width:.75rem;background-color:#595b5b;border:1px solid #303233;border-radius:4px;box-shadow:inset 0 1px #727373}.topcoat-range::-moz-range-thumb{height:1.313rem;width:.75rem;background-color:#595b5b;border:1px solid #303233;border-radius:4px;box-shadow:inset 0 1px #727373}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:1.313rem;font-size:12px;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;padding:0 0 0 1.3rem;border-radius:15px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:12px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input:disabled::-moz-placeholder{color:#fff}.topcoat-search-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-search-input--large{line-height:1.688rem;font-size:.875rem;font-weight:400;padding:0 0 0 1.8rem;border-radius:25px;background-position:1.2em center;background-size:.875rem}.topcoat-search-input--large:disabled{color:#fff}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#fff}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:12px;padding:0 .563rem;border-radius:4px;border:1px solid #303233;overflow:hidden;width:3.5rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:2.6rem}.topcoat-switch__toggle:before{content:'ON';color:#5dc1ff;background-color:#404141;right:.8rem;padding-left:.75rem}.topcoat-switch__toggle{line-height:1.313rem;height:1.313rem;width:1rem;border-radius:4px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#595b5b;border:1px solid #303233;margin-left:-.6rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #727373;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#404141;left:.8rem;padding-left:.6rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:1.85rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 .563rem;height:1.313rem;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border-top:1px solid #303233}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#5dc1ff;background-color:#404141;box-shadow:inset 0 0 2px #313231}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:1.313rem;font-size:12px;letter-spacing:0;padding:0 .563rem;border:1px solid #303233;border-radius:4px;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input:disabled::-moz-placeholder{color:#fff}.topcoat-text-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:1.688rem;font-size:.875rem}.topcoat-text-input--large:disabled{color:#fff}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:1rem;font-size:1rem;font-weight:400;border-radius:4px;line-height:1.313rem;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;letter-spacing:0}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea:disabled::-moz-placeholder{color:#fff}.topcoat-textarea:disabled:-ms-input-placeholder{color:#fff}.topcoat-textarea--large{font-size:1.3rem;line-height:1.688rem}.topcoat-textarea--large:disabled{color:#fff}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea--large:disabled::-moz-placeholder{color:#fff}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#fff}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#4b4d4e;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_light.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.css new file mode 100755 index 0000000..0da42ea --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.css @@ -0,0 +1,3450 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 1rem; +} + +input[type="checkbox"] { + height: 1rem; + width: 1rem; + margin-top: 0; + margin-right: -1rem; + margin-bottom: -1rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 1rem; +} + +.topcoat-checkbox__checkmark:before { + width: 1rem; + height: 1rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 3px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-checkbox__checkmark { + width: 1rem; + height: 1rem; +} + +.topcoat-checkbox__checkmark:after { + top: 2px; + left: 1px; + opacity: 0; + width: 14px; + height: 4px; + background: transparent; + border: 7px solid #666; + border-width: 3px; + border-top: none; + border-right: none; + border-radius: 1px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.25rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: baseline; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 4px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-icon-button:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 1.688rem; + height: 1.688rem; + line-height: 1.688rem; +} + +.topcoat-icon-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 0.81406rem; + height: 0.81406rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 1.06344rem; + height: 1.06344rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
    +
    + + +
    +
    + + +
    +
    + + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.063rem; + width: 1.063rem; + margin-top: 0; + margin-right: -1.063rem; + margin-bottom: -1.063rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #454545; + line-height: 1.063rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.063rem; + height: 1.063rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.063rem; + height: 1.063rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.313rem; + height: 0.313rem; + background: #666; + border: 1px solid rgba(0,0,0,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 0.313rem; + left: 0.313rem; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 4px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-moz-range-track { + border-radius: 4px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 4px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range::-moz-range-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 4px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 1.313rem; + font-size: 12px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + padding: 0 0 0 1.3rem; + border-radius: 15px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 12px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 1.688rem; + font-size: 0.875rem; + font-weight: 400; + padding: 0 0 0 1.8rem; + border-radius: 25px; + background-position: 1.2em center; + background-size: 0.875rem; +} + +.topcoat-search-input--large:disabled { + color: #000; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + +
    +
    + + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 12px; + padding: 0 0.563rem; + border-radius: 4px; + border: 1px solid #a5a8a8; + overflow: hidden; + width: 3.5rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 2.6rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #0083e8; + background-color: #e0f0fa; + right: 0.8rem; + padding-left: 0.75rem; +} + +.topcoat-switch__toggle { + line-height: 1.313rem; + height: 1.313rem; + width: 1rem; + border-radius: 4px; + color: #454545; + text-shadow: 0 1px #fff; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + margin-left: -0.6rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #fff; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #d3d7d7; + left: 0.8rem; + padding-left: 0.6rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 1.85rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
    + + + +
    + examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 0.563rem; + height: 1.313rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border-top: 1px solid #a5a8a8; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #0083e8; + background-color: #e0f0fa; + box-shadow: inset 0 0 2px #c0ced8; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 1.313rem; + font-size: 12px; + letter-spacing: 0; + padding: 0 0.563rem; + border: 1px solid #a5a8a8; + border-radius: 4px; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 1.688rem; + font-size: 0.875rem; +} + +.topcoat-text-input--large:disabled { + color: #000; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 1rem; + font-size: 1rem; + font-weight: 400; + border-radius: 4px; + line-height: 1.313rem; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + letter-spacing: 0; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 1.3rem; + line-height: 1.688rem; +} + +.topcoat-textarea--large:disabled { + color: #000; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #000; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #dfe2e2; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_dark.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.min.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.min.css new file mode 100755 index 0000000..e682662 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-desktop-light.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:4px;border-bottom-left-radius:4px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:4px;border-bottom-right-radius:4px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:1rem}input[type=checkbox]{height:1rem;width:1rem;margin-top:0;margin-right:-1rem;margin-bottom:-1rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:1rem}.topcoat-checkbox__checkmark:before{width:1rem;height:1rem;background:#e5e9e8;border:1px solid #a5a8a8;border-radius:3px;box-shadow:inset 0 1px #fff}.topcoat-checkbox__checkmark{width:1rem;height:1rem}.topcoat-checkbox__checkmark:after{top:2px;left:1px;opacity:0;width:14px;height:4px;background:transparent;border:7px solid #666;border-width:3px;border-top:0;border-right:0;border-radius:1px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .25rem;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:baseline;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:4px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#edf1f1}.topcoat-icon-button:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:1.688rem;height:1.688rem;line-height:1.688rem}.topcoat-icon-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:.81406rem;height:.81406rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:1.06344rem;height:1.06344rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.063rem;width:1.063rem;margin-top:0;margin-right:-1.063rem;margin-bottom:-1.063rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#454545;line-height:1.063rem}.topcoat-radio-button__checkmark:before{width:1.063rem;height:1.063rem;background:#e5e9e8;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-radio-button__checkmark{position:relative;width:1.063rem;height:1.063rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.313rem;height:.313rem;background:#666;border:1px solid rgba(0,0,0,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:.313rem;left:.313rem}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:4px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:.5rem;border-radius:15px}.topcoat-range::-moz-range-track{border-radius:4px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:.5rem;border-radius:15px}.topcoat-range::-webkit-slider-thumb{height:1.313rem;width:.75rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:4px;box-shadow:inset 0 1px #fff}.topcoat-range::-moz-range-thumb{height:1.313rem;width:.75rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:4px;box-shadow:inset 0 1px #fff}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:1.313rem;font-size:12px;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;padding:0 0 0 1.3rem;border-radius:15px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:12px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input:disabled::-moz-placeholder{color:#000}.topcoat-search-input:disabled:-ms-input-placeholder{color:#000}.topcoat-search-input--large{line-height:1.688rem;font-size:.875rem;font-weight:400;padding:0 0 0 1.8rem;border-radius:25px;background-position:1.2em center;background-size:.875rem}.topcoat-search-input--large:disabled{color:#000}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input--large:disabled::-moz-placeholder{color:#000}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#000}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:12px;padding:0 .563rem;border-radius:4px;border:1px solid #a5a8a8;overflow:hidden;width:3.5rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:2.6rem}.topcoat-switch__toggle:before{content:'ON';color:#0083e8;background-color:#e0f0fa;right:.8rem;padding-left:.75rem}.topcoat-switch__toggle{line-height:1.313rem;height:1.313rem;width:1rem;border-radius:4px;color:#454545;text-shadow:0 1px #fff;background-color:#e5e9e8;border:1px solid #a5a8a8;margin-left:-.6rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #fff;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#d3d7d7;left:.8rem;padding-left:.6rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:1.85rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 .563rem;height:1.313rem;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border-top:1px solid #a5a8a8}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#0083e8;background-color:#e0f0fa;box-shadow:inset 0 0 2px #c0ced8}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:1.313rem;font-size:12px;letter-spacing:0;padding:0 .563rem;border:1px solid #a5a8a8;border-radius:4px;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input:disabled::-moz-placeholder{color:#000}.topcoat-text-input:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:1.688rem;font-size:.875rem}.topcoat-text-input--large:disabled{color:#000}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input--large:disabled::-moz-placeholder{color:#000}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:1rem;font-size:1rem;font-weight:400;border-radius:4px;line-height:1.313rem;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;letter-spacing:0}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea:disabled::-moz-placeholder{color:#000}.topcoat-textarea:disabled:-ms-input-placeholder{color:#000}.topcoat-textarea--large{font-size:1.3rem;line-height:1.688rem}.topcoat-textarea--large:disabled{color:#000}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea--large:disabled::-moz-placeholder{color:#000}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#000}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#dfe2e2;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_dark.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.css new file mode 100755 index 0000000..0d3aa5f --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.css @@ -0,0 +1,3700 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 2rem; +} + +input[type="checkbox"] { + height: 2rem; + width: 2rem; + margin-top: 0; + margin-right: -2rem; + margin-bottom: -2rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 2rem; +} + +.topcoat-checkbox__checkmark:before { + width: 2rem; + height: 2rem; + background: #595b5b; + border: 1px solid #303233; + border-radius: 3px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-checkbox__checkmark { + width: 2rem; + height: 2rem; +} + +.topcoat-checkbox__checkmark:after { + top: 1px; + left: 2px; + opacity: 0; + width: 28px; + height: 11px; + background: transparent; + border: 7px solid #fff; + border-width: 7px; + border-top: none; + border-right: none; + border-radius: 2px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.75rem; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: baseline; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 6px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-icon-button:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 4.375rem; + height: 4.375rem; + line-height: 4.375rem; +} + +.topcoat-icon-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 1.62rem; + height: 1.62rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 2.499999998125rem; + height: 2.499999998125rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list, +.topcoat-list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header, +.topcoat-list__header { + margin: 0; +} + +.list__container, +.topcoat-list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item, +.topcoat-list__item { + margin: 0; + padding: 0; +} + +/* topdoc + name: List + description: Topcoat default list skin + markup: +
    +

    Category

    +
      +
    • + Item +
    • +
    • + Item +
    • +
    • + Item +
    • +
    +
    + tags: + - mobile + - list +*/ + +.topcoat-list { + border-top: 1px solid #2f3234; + border-bottom: 1px solid #5e6061; + background-color: #444849; +} + +.topcoat-list__header { + padding: 4px 20px; + font-size: 0.9em; + font-weight: 400; + background-color: #3b3e40; + color: #868888; + text-shadow: 0 -1px 0 rgba(0,0,0,0.3); + border-top: solid 1px rgba(255,255,255,0.1); + border-bottom: solid 1px rgba(255,255,255,0.05); +} + +.topcoat-list__container { + border-top: 1px solid #2f3234; + color: #c6c8c8; +} + +.topcoat-list__item { + padding: 1.25rem; + border-top: 1px solid #5e6061; + border-bottom: 1px solid #2f3234; +} + +.topcoat-list__item:first-child { + border-top: 1px solid rgba(0,0,0,0.05); +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar, +.topcoat-navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item, +.topcoat-navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title, +.topcoat-navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* topdoc + name: Navigation Bar + description: A place where navigation goes to drink + markup: +
    +
    +

    Header

    +
    +
    + tags: + - desktop + - light + - mobile + - navigation + - bar +*/ + +.topcoat-navigation-bar { + height: 4.375rem; + padding-left: 1rem; + padding-right: 1rem; + background: #595b5b; + color: #fff; + box-shadow: inset 0 -1px #333434, 0 1px rgba(0,0,0,0.15); +} + +.topcoat-navigation-bar__item { + margin: 0; + line-height: 4.375rem; + vertical-align: top; +} + +.topcoat-navigation-bar__title { + font-size: 1.3rem; + font-weight: 400; + color: #fff; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
    +
    + + +
    +
    + + +
    +
    + + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.875rem; + width: 1.875rem; + margin-top: 0; + margin-right: -1.875rem; + margin-bottom: -1.875rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #c6c8c8; + line-height: 1.875rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.875rem; + height: 1.875rem; + background: #595b5b; + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.875rem; + height: 1.875rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.875rem; + height: 0.875rem; + background: #fff; + border: 1px solid rgba(255,255,255,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 7px; + left: 7px; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 6px; + border: 1px solid #303233; + background-color: #424546; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-moz-range-track { + border-radius: 6px; + border: 1px solid #303233; + background-color: #424546; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 3rem; + width: 2rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 6px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range::-moz-range-thumb { + height: 3rem; + width: 2rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 6px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 3rem; + font-size: 16px; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + padding: 0 0 0 2rem; + border-radius: 30px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 16px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 4.375rem; + font-size: 1.3rem; + font-weight: 200; + padding: 0 0 0 2.9rem; + border-radius: 40px; + background-position: 1.2em center; + background-size: 1.3rem; +} + +.topcoat-search-input--large:disabled { + color: #fff; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + +
    +
    + + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 16px; + padding: 0 1.25rem; + border-radius: 6px; + border: 1px solid #303233; + overflow: hidden; + width: 6rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 5rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #5dc1ff; + background-color: #404141; + right: 1rem; + padding-left: 1.5rem; +} + +.topcoat-switch__toggle { + line-height: 3rem; + height: 3rem; + width: 2rem; + border-radius: 6px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #595b5b; + border: 1px solid #303233; + margin-left: -1.3rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #727373; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #404141; + left: 1rem; + padding-left: 2rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 2.7rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
    + + + +
    + examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 1.25rem; + height: 3rem; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border-top: 1px solid #303233; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #5dc1ff; + background-color: #404141; + box-shadow: inset 0 0 2px #313231; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 3rem; + font-size: 16px; + letter-spacing: 1px; + padding: 0 1.25rem; + border: 1px solid #303233; + border-radius: 6px; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 4.375rem; + font-size: 1.3rem; +} + +.topcoat-text-input--large:disabled { + color: #fff; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 2rem; + font-size: 2.5rem; + font-weight: 200; + border-radius: 6px; + line-height: 3rem; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + letter-spacing: 1px; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 3rem; + line-height: 4.375rem; +} + +.topcoat-textarea--large:disabled { + color: #fff; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #fff; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #4b4d4e; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_light.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.min.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.min.css new file mode 100755 index 0000000..2ce6f11 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-dark.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:6px;border-bottom-left-radius:6px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:6px;border-bottom-right-radius:6px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:2rem}input[type=checkbox]{height:2rem;width:2rem;margin-top:0;margin-right:-2rem;margin-bottom:-2rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:2rem}.topcoat-checkbox__checkmark:before{width:2rem;height:2rem;background:#595b5b;border:1px solid #303233;border-radius:3px;box-shadow:inset 0 1px #727373}.topcoat-checkbox__checkmark{width:2rem;height:2rem}.topcoat-checkbox__checkmark:after{top:1px;left:2px;opacity:0;width:28px;height:11px;background:transparent;border:7px solid #fff;border-width:7px;border-top:0;border-right:0;border-radius:2px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .75rem;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:baseline;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:6px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#646666}.topcoat-icon-button:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:4.375rem;height:4.375rem;line-height:4.375rem}.topcoat-icon-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:1.62rem;height:1.62rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:2.499999998125rem;height:2.499999998125rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.list,.topcoat-list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header,.topcoat-list__header{margin:0}.list__container,.topcoat-list__container{padding:0;margin:0;list-style-type:none}.list__item,.topcoat-list__item{margin:0;padding:0}.topcoat-list{border-top:1px solid #2f3234;border-bottom:1px solid #5e6061;background-color:#444849}.topcoat-list__header{padding:4px 20px;font-size:.9em;font-weight:400;background-color:#3b3e40;color:#868888;text-shadow:0 -1px 0 rgba(0,0,0,.3);border-top:solid 1px rgba(255,255,255,.1);border-bottom:solid 1px rgba(255,255,255,.05)}.topcoat-list__container{border-top:1px solid #2f3234;color:#c6c8c8}.topcoat-list__item{padding:1.25rem;border-top:1px solid #5e6061;border-bottom:1px solid #2f3234}.topcoat-list__item:first-child{border-top:1px solid rgba(0,0,0,.05)}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.navigation-bar,.topcoat-navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item,.topcoat-navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title,.topcoat-navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.topcoat-navigation-bar{height:4.375rem;padding-left:1rem;padding-right:1rem;background:#595b5b;color:#fff;box-shadow:inset 0 -1px #333434,0 1px rgba(0,0,0,.15)}.topcoat-navigation-bar__item{margin:0;line-height:4.375rem;vertical-align:top}.topcoat-navigation-bar__title{font-size:1.3rem;font-weight:400;color:#fff}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.875rem;width:1.875rem;margin-top:0;margin-right:-1.875rem;margin-bottom:-1.875rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#c6c8c8;line-height:1.875rem}.topcoat-radio-button__checkmark:before{width:1.875rem;height:1.875rem;background:#595b5b;border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-radio-button__checkmark{position:relative;width:1.875rem;height:1.875rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.875rem;height:.875rem;background:#fff;border:1px solid rgba(255,255,255,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:7px;left:7px}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:6px;border:1px solid #303233;background-color:#424546;height:1rem;border-radius:30px}.topcoat-range::-moz-range-track{border-radius:6px;border:1px solid #303233;background-color:#424546;height:1rem;border-radius:30px}.topcoat-range::-webkit-slider-thumb{height:3rem;width:2rem;background-color:#595b5b;border:1px solid #303233;border-radius:6px;box-shadow:inset 0 1px #727373}.topcoat-range::-moz-range-thumb{height:3rem;width:2rem;background-color:#595b5b;border:1px solid #303233;border-radius:6px;box-shadow:inset 0 1px #727373}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:3rem;font-size:16px;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;padding:0 0 0 2rem;border-radius:30px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:16px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input:disabled::-moz-placeholder{color:#fff}.topcoat-search-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-search-input--large{line-height:4.375rem;font-size:1.3rem;font-weight:200;padding:0 0 0 2.9rem;border-radius:40px;background-position:1.2em center;background-size:1.3rem}.topcoat-search-input--large:disabled{color:#fff}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#fff}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:16px;padding:0 1.25rem;border-radius:6px;border:1px solid #303233;overflow:hidden;width:6rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:5rem}.topcoat-switch__toggle:before{content:'ON';color:#5dc1ff;background-color:#404141;right:1rem;padding-left:1.5rem}.topcoat-switch__toggle{line-height:3rem;height:3rem;width:2rem;border-radius:6px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#595b5b;border:1px solid #303233;margin-left:-1.3rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #727373;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#404141;left:1rem;padding-left:2rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:2.7rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 1.25rem;height:3rem;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border-top:1px solid #303233}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#5dc1ff;background-color:#404141;box-shadow:inset 0 0 2px #313231}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:3rem;font-size:16px;letter-spacing:1px;padding:0 1.25rem;border:1px solid #303233;border-radius:6px;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input:disabled::-moz-placeholder{color:#fff}.topcoat-text-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:4.375rem;font-size:1.3rem}.topcoat-text-input--large:disabled{color:#fff}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:2rem;font-size:2.5rem;font-weight:200;border-radius:6px;line-height:3rem;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;letter-spacing:1px}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea:disabled::-moz-placeholder{color:#fff}.topcoat-textarea:disabled:-ms-input-placeholder{color:#fff}.topcoat-textarea--large{font-size:3rem;line-height:4.375rem}.topcoat-textarea--large:disabled{color:#fff}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea--large:disabled::-moz-placeholder{color:#fff}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#fff}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#4b4d4e;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_light.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.css new file mode 100755 index 0000000..6735055 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.css @@ -0,0 +1,3700 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 2rem; +} + +input[type="checkbox"] { + height: 2rem; + width: 2rem; + margin-top: 0; + margin-right: -2rem; + margin-bottom: -2rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 2rem; +} + +.topcoat-checkbox__checkmark:before { + width: 2rem; + height: 2rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 3px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-checkbox__checkmark { + width: 2rem; + height: 2rem; +} + +.topcoat-checkbox__checkmark:after { + top: 1px; + left: 2px; + opacity: 0; + width: 28px; + height: 11px; + background: transparent; + border: 7px solid #666; + border-width: 7px; + border-top: none; + border-right: none; + border-radius: 2px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.75rem; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: baseline; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 6px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-icon-button:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 4.375rem; + height: 4.375rem; + line-height: 4.375rem; +} + +.topcoat-icon-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 1.62rem; + height: 1.62rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 2.499999998125rem; + height: 2.499999998125rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list, +.topcoat-list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header, +.topcoat-list__header { + margin: 0; +} + +.list__container, +.topcoat-list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item, +.topcoat-list__item { + margin: 0; + padding: 0; +} + +/* topdoc + name: List + description: Topcoat default list skin + markup: +
    +

    Category

    +
      +
    • + Item +
    • +
    • + Item +
    • +
    • + Item +
    • +
    +
    + tags: + - mobile + - list +*/ + +.topcoat-list { + border-top: 1px solid #bcbfbf; + border-bottom: 1px solid #eff1f1; + background-color: #dfe2e2; +} + +.topcoat-list__header { + padding: 4px 20px; + font-size: 0.9em; + font-weight: 400; + background-color: #cccfcf; + color: #656565; + text-shadow: 0 1px 0 rgba(255,255,255,0.5); + border-top: 1px solid rgba(255,255,255,0.5); + border-bottom: 1px solid rgba(255,255,255,0.23); +} + +.topcoat-list__container { + border-top: 1px solid #bcbfbf; + color: #454545; +} + +.topcoat-list__item { + padding: 1.25rem; + border-top: 1px solid #eff1f1; + border-bottom: 1px solid #bcbfbf; +} + +.topcoat-list__item:first-child { + border-top: 1px solid rgba(0,0,0,0.05); +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar, +.topcoat-navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item, +.topcoat-navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title, +.topcoat-navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* topdoc + name: Navigation Bar + description: A place where navigation goes to drink + markup: +
    +
    +

    Header

    +
    +
    + tags: + - desktop + - light + - mobile + - navigation + - bar +*/ + +.topcoat-navigation-bar { + height: 4.375rem; + padding-left: 1rem; + padding-right: 1rem; + background: #e5e9e8; + color: #000; + box-shadow: inset 0 -1px #b9bcbc, 0 1px #d4d6d6; +} + +.topcoat-navigation-bar__item { + margin: 0; + line-height: 4.375rem; + vertical-align: top; +} + +.topcoat-navigation-bar__title { + font-size: 1.3rem; + font-weight: 400; + color: #000; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
    +
    + + +
    +
    + + +
    +
    + + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.875rem; + width: 1.875rem; + margin-top: 0; + margin-right: -1.875rem; + margin-bottom: -1.875rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #454545; + line-height: 1.875rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.875rem; + height: 1.875rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.875rem; + height: 1.875rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.875rem; + height: 0.875rem; + background: #666; + border: 1px solid rgba(0,0,0,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 7px; + left: 7px; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 6px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-moz-range-track { + border-radius: 6px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 3rem; + width: 2rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 6px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range::-moz-range-thumb { + height: 3rem; + width: 2rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 6px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 3rem; + font-size: 16px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + padding: 0 0 0 2rem; + border-radius: 30px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 16px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 4.375rem; + font-size: 1.3rem; + font-weight: 200; + padding: 0 0 0 2.9rem; + border-radius: 40px; + background-position: 1.2em center; + background-size: 1.3rem; +} + +.topcoat-search-input--large:disabled { + color: #000; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + +
    +
    + + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 16px; + padding: 0 1.25rem; + border-radius: 6px; + border: 1px solid #a5a8a8; + overflow: hidden; + width: 6rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 5rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #0083e8; + background-color: #e0f0fa; + right: 1rem; + padding-left: 1.5rem; +} + +.topcoat-switch__toggle { + line-height: 3rem; + height: 3rem; + width: 2rem; + border-radius: 6px; + color: #454545; + text-shadow: 0 1px #fff; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + margin-left: -1.3rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #fff; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #d3d7d7; + left: 1rem; + padding-left: 2rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 2.7rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
    + + + +
    + examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 1.25rem; + height: 3rem; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border-top: 1px solid #a5a8a8; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #0083e8; + background-color: #e0f0fa; + box-shadow: inset 0 0 2px #c0ced8; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 3rem; + font-size: 16px; + letter-spacing: 1px; + padding: 0 1.25rem; + border: 1px solid #a5a8a8; + border-radius: 6px; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 4.375rem; + font-size: 1.3rem; +} + +.topcoat-text-input--large:disabled { + color: #000; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 2rem; + font-size: 2.5rem; + font-weight: 200; + border-radius: 6px; + line-height: 3rem; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + letter-spacing: 1px; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 3rem; + line-height: 4.375rem; +} + +.topcoat-textarea--large:disabled { + color: #000; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #000; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #dfe2e2; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_dark.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.min.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.min.css new file mode 100755 index 0000000..7692377 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/css/topcoat-mobile-light.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:6px;border-bottom-left-radius:6px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:6px;border-bottom-right-radius:6px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:2rem}input[type=checkbox]{height:2rem;width:2rem;margin-top:0;margin-right:-2rem;margin-bottom:-2rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:2rem}.topcoat-checkbox__checkmark:before{width:2rem;height:2rem;background:#e5e9e8;border:1px solid #a5a8a8;border-radius:3px;box-shadow:inset 0 1px #fff}.topcoat-checkbox__checkmark{width:2rem;height:2rem}.topcoat-checkbox__checkmark:after{top:1px;left:2px;opacity:0;width:28px;height:11px;background:transparent;border:7px solid #666;border-width:7px;border-top:0;border-right:0;border-radius:2px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .75rem;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:baseline;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:6px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#edf1f1}.topcoat-icon-button:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:4.375rem;height:4.375rem;line-height:4.375rem}.topcoat-icon-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:1.62rem;height:1.62rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:2.499999998125rem;height:2.499999998125rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.list,.topcoat-list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header,.topcoat-list__header{margin:0}.list__container,.topcoat-list__container{padding:0;margin:0;list-style-type:none}.list__item,.topcoat-list__item{margin:0;padding:0}.topcoat-list{border-top:1px solid #bcbfbf;border-bottom:1px solid #eff1f1;background-color:#dfe2e2}.topcoat-list__header{padding:4px 20px;font-size:.9em;font-weight:400;background-color:#cccfcf;color:#656565;text-shadow:0 1px 0 rgba(255,255,255,.5);border-top:1px solid rgba(255,255,255,.5);border-bottom:1px solid rgba(255,255,255,.23)}.topcoat-list__container{border-top:1px solid #bcbfbf;color:#454545}.topcoat-list__item{padding:1.25rem;border-top:1px solid #eff1f1;border-bottom:1px solid #bcbfbf}.topcoat-list__item:first-child{border-top:1px solid rgba(0,0,0,.05)}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.navigation-bar,.topcoat-navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item,.topcoat-navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title,.topcoat-navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.topcoat-navigation-bar{height:4.375rem;padding-left:1rem;padding-right:1rem;background:#e5e9e8;color:#000;box-shadow:inset 0 -1px #b9bcbc,0 1px #d4d6d6}.topcoat-navigation-bar__item{margin:0;line-height:4.375rem;vertical-align:top}.topcoat-navigation-bar__title{font-size:1.3rem;font-weight:400;color:#000}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.875rem;width:1.875rem;margin-top:0;margin-right:-1.875rem;margin-bottom:-1.875rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#454545;line-height:1.875rem}.topcoat-radio-button__checkmark:before{width:1.875rem;height:1.875rem;background:#e5e9e8;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-radio-button__checkmark{position:relative;width:1.875rem;height:1.875rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.875rem;height:.875rem;background:#666;border:1px solid rgba(0,0,0,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:7px;left:7px}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:6px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:1rem;border-radius:30px}.topcoat-range::-moz-range-track{border-radius:6px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:1rem;border-radius:30px}.topcoat-range::-webkit-slider-thumb{height:3rem;width:2rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:6px;box-shadow:inset 0 1px #fff}.topcoat-range::-moz-range-thumb{height:3rem;width:2rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:6px;box-shadow:inset 0 1px #fff}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:3rem;font-size:16px;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;padding:0 0 0 2rem;border-radius:30px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:16px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input:disabled::-moz-placeholder{color:#000}.topcoat-search-input:disabled:-ms-input-placeholder{color:#000}.topcoat-search-input--large{line-height:4.375rem;font-size:1.3rem;font-weight:200;padding:0 0 0 2.9rem;border-radius:40px;background-position:1.2em center;background-size:1.3rem}.topcoat-search-input--large:disabled{color:#000}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input--large:disabled::-moz-placeholder{color:#000}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#000}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:16px;padding:0 1.25rem;border-radius:6px;border:1px solid #a5a8a8;overflow:hidden;width:6rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:5rem}.topcoat-switch__toggle:before{content:'ON';color:#0083e8;background-color:#e0f0fa;right:1rem;padding-left:1.5rem}.topcoat-switch__toggle{line-height:3rem;height:3rem;width:2rem;border-radius:6px;color:#454545;text-shadow:0 1px #fff;background-color:#e5e9e8;border:1px solid #a5a8a8;margin-left:-1.3rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #fff;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#d3d7d7;left:1rem;padding-left:2rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:2.7rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 1.25rem;height:3rem;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border-top:1px solid #a5a8a8}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#0083e8;background-color:#e0f0fa;box-shadow:inset 0 0 2px #c0ced8}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:3rem;font-size:16px;letter-spacing:1px;padding:0 1.25rem;border:1px solid #a5a8a8;border-radius:6px;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input:disabled::-moz-placeholder{color:#000}.topcoat-text-input:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:4.375rem;font-size:1.3rem}.topcoat-text-input--large:disabled{color:#000}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input--large:disabled::-moz-placeholder{color:#000}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:2rem;font-size:2.5rem;font-weight:200;border-radius:6px;line-height:3rem;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;letter-spacing:1px}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea:disabled::-moz-placeholder{color:#000}.topcoat-textarea:disabled:-ms-input-placeholder{color:#000}.topcoat-textarea--large{font-size:3rem;line-height:4.375rem}.topcoat-textarea--large:disabled{color:#000}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea--large:disabled::-moz-placeholder{color:#000}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#000}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#dfe2e2;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_dark.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/css/brackets.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/css/brackets.css new file mode 100755 index 0000000..8e32479 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/css/brackets.css @@ -0,0 +1,69 @@ +/** + * Brackets theme + * + * @author Garth Braithwaite + * @version 0.0.1 + */ +pre { + word-wrap: break-word; + padding: 6px 10px; + line-height: 19px; + margin-bottom: 20px; +} + +pre, code { + font-family: source-code-pro, 'Source Code Pro', Courier, monospace; + color: #535353; +} + +pre, pre code { + font-size: 13px; +} + +pre .comment { + color: #A2A2A2; +} + +pre .support { + color: #0086B3; +} + +pre .tag, pre .tag-name { + color: #446FBD; +} + +pre .css-property { + color: #8757AD; +} + +pre .css-value, pre .support.namespace { + color: #F18900; +} +pre .vendor-prefix { + color: #535353; +} +pre .constant.numeric, pre .keyword.unit { + color: #738D00; +} +pre .hex-color { + color: #F18900; +} +pre .entity.class { + color: #5585C4; +} + +pre .entity.id, pre .entity.function { + color: #900; +} + +pre .attribute, pre .variable { + color: #738D00; +} + +pre .string, pre .support.value { + color: #8757AD; +} + +pre .regexp { + color: #535353; +} \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/css/main.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/css/main.css new file mode 100755 index 0000000..2d0bda3 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/css/main.css @@ -0,0 +1,508 @@ +html,body{ + margin:0; + padding:0; + height: 100%; +} +body { + font-family: source-sans-pro, sans-serif; + position: relative; + -webkit-font-smoothing: antialiased; +} +body.light { + background: #F4F4F4; +} +body.dark { + color: #F0F1F1; + background: #4A4D4E; +} +body.light { + color: #181919; +} + +h1 { + font-weight: 600; +} +#wrapper { + width: 100%; + overflow-x: hidden; + background: inherit; + position: relative; +} +#site { + width: 100%; + position: relative; + z-index: 10; + background: inherit; + left: 0; + transition: all 0.2s ease-out; + -webkit-transition: all 0.2s ease-out; + transform: translate3d(0, 0, 0); + -webkit-transform: translate3d(0, 0, 0); +} +#site:before{ + position: absolute; + content: ''; + left: -4px; + height: 100%; + width: 4px; + background: #3B3E3E; +} +#site.open { + transform: translate3d(250px, 0, 0); + -webkit-transform: translate3d(250px, 0, 0); +} +pre { + font-family: source-code-pro, sans-serif; + font-size: 12px; +} +/* Main Header */ +#main-header { + color: #373435; + background: #fff; + height: 98px; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 10px 20px; + position: relative; +} +#main-header hgroup { + text-align: center; +} +#main-header hgroup h1 { + font-size: 40px; + margin: 5px 0 0; + letter-spacing: -.065em; + line-height: 1.1em; +} +#main-header hgroup a { + color: #464646; + text-decoration: none; +} +#main-header hgroup a:hover { + color: #000; +} +#main-header hgroup p { + font-size: 13px; + color: #999; + margin: 0; +} +#main-header nav { + display: none; +} +#slide-menu-button { + position: absolute; + top: 20px; + left: 20px; + display: inline-block; + vertical-align: top; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-background-clip: padding; + -moz-background-clip: padding; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + padding: 0 0.5rem; + line-height: 2rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: baseline; + -webkit-box-shadow: inset 0 1px #fff; + box-shadow: inset 0 1px #fff; + -webkit-border-radius: 3px; + border-radius: 3px; + width: 2.6rem; + height: 2.6rem; + line-height: 2.6rem; + border: 1px solid transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +#slide-menu:disabled, +#slide-menu.is-disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} +#slide-menu-button:active, +#slide-menu-button.is-active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + -webkit-box-shadow: inset 0 1px rgba(0,0,0,0.12); + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} +#slide-menu-button span { + background-repeat: no-repeat; + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCIgWw0KCTwhRU5USVRZIG5zX2V4dGVuZCAiaHR0cDovL25zLmFkb2JlLmNvbS9FeHRlbnNpYmlsaXR5LzEuMC8iPg0KCTwhRU5USVRZIG5zX2FpICJodHRwOi8vbnMuYWRvYmUuY29tL0Fkb2JlSWxsdXN0cmF0b3IvMTAuMC8iPg0KCTwhRU5USVRZIG5zX2dyYXBocyAiaHR0cDovL25zLmFkb2JlLmNvbS9HcmFwaHMvMS4wLyI+DQoJPCFFTlRJVFkgbnNfdmFycyAiaHR0cDovL25zLmFkb2JlLmNvbS9WYXJpYWJsZXMvMS4wLyI+DQoJPCFFTlRJVFkgbnNfaW1yZXAgImh0dHA6Ly9ucy5hZG9iZS5jb20vSW1hZ2VSZXBsYWNlbWVudC8xLjAvIj4NCgk8IUVOVElUWSBuc19zZncgImh0dHA6Ly9ucy5hZG9iZS5jb20vU2F2ZUZvcldlYi8xLjAvIj4NCgk8IUVOVElUWSBuc19jdXN0b20gImh0dHA6Ly9ucy5hZG9iZS5jb20vR2VuZXJpY0N1c3RvbU5hbWVzcGFjZS8xLjAvIj4NCgk8IUVOVElUWSBuc19hZG9iZV94cGF0aCAiaHR0cDovL25zLmFkb2JlLmNvbS9YUGF0aC8xLjAvIj4NCl0+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOng9IiZuc19leHRlbmQ7IiB4bWxuczppPSImbnNfYWk7IiB4bWxuczpncmFwaD0iJm5zX2dyYXBoczsiDQoJIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDBweCIgaGVpZ2h0PSI0MHB4Ig0KCSB2aWV3Qm94PSIwIDAgNDAgNDAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQwIDQwIiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxzd2l0Y2g+DQoJPGZvcmVpZ25PYmplY3QgcmVxdWlyZWRFeHRlbnNpb25zPSImbnNfYWk7IiB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIj4NCgkJPGk6cGdmUmVmICB4bGluazpocmVmPSIjYWRvYmVfaWxsdXN0cmF0b3JfcGdmIj4NCgkJPC9pOnBnZlJlZj4NCgk8L2ZvcmVpZ25PYmplY3Q+DQoJPGcgaTpleHRyYW5lb3VzPSJzZWxmIj4NCgkJPGcgb3BhY2l0eT0iMC43Ij4NCgkJCTxnIG9wYWNpdHk9IjAuNzUiPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkZGRkZGIiBkPSJNMzksMTF2LTFjMC0xLjQ3LTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MQ0KCQkJCQljMCwxLjU1LDAuNTIsMiwyLDJoMzRDMzguNSwxMywzOSwxMi41MiwzOSwxMXoiLz4NCgkJCTwvZz4NCgkJCTxnPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzksMTBWOWMwLTEuNDctMC40OC0yLTItMkgzQzEuNDcsNywxLDcuNTIsMSw5djFjMCwxLjU1LDAuNTIsMiwyLDJoMzQNCgkJCQkJQzM4LjUsMTIsMzksMTEuNTIsMzksMTB6Ii8+DQoJCQk8L2c+DQoJCTwvZz4NCgkJPGcgb3BhY2l0eT0iMC43Ij4NCgkJCTxnIG9wYWNpdHk9IjAuNzUiPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkZGRkZGIiBkPSJNMzksMjJ2LTFjMC0xLjQ3LTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MQ0KCQkJCQljMCwxLjU1LDAuNTIsMiwyLDJoMzRDMzguNSwyNCwzOSwyMy41MiwzOSwyMnoiLz4NCgkJCTwvZz4NCgkJCTxnPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzksMjF2LTFjMC0xLjQ3LTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MWMwLDEuNTUsMC41MiwyLDIsMmgzNA0KCQkJCQlDMzguNSwyMywzOSwyMi41MiwzOSwyMXoiLz4NCgkJCTwvZz4NCgkJPC9nPg0KCQk8ZyBvcGFjaXR5PSIwLjciPg0KCQkJPGcgb3BhY2l0eT0iMC43NSI+DQoJCQkJPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGw9IiNGRkZGRkYiIGQ9Ik0zOSwzM3YtMWMwLTEuNDcxLTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MQ0KCQkJCQljMCwxLjU1LDAuNTIsMiwyLDJoMzRDMzguNSwzNSwzOSwzNC41MiwzOSwzM3oiLz4NCgkJCTwvZz4NCgkJCTxnPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzksMzJ2LTFjMC0xLjQ3MS0wLjQ4LTItMi0ySDNjLTEuNTMsMC0yLDAuNTItMiwydjFjMCwxLjU1LDAuNTIsMiwyLDJoMzQNCgkJCQkJQzM4LjUsMzQsMzksMzMuNTIsMzksMzJ6Ii8+DQoJCQk8L2c+DQoJCTwvZz4NCgk8L2c+DQo8L3N3aXRjaD4NCjxpOnBnZiAgaWQ9ImFkb2JlX2lsbHVzdHJhdG9yX3BnZiI+DQoJPCFbQ0RBVEFbDQoJZUp6c3ZlbVNKTG1SSnZnRTlnNitQMXFFSEprS0dnQ0RBY1lkV1pId09IbzRRM2FYa094anBXV2tKSmtWVGVaMEhpVlpXZVJ5bjM3MQorMVFWZ0xsN1pFVWVSVksySzFDVkVhNE9nNW5oVU9qeHFlTHYvbzh2Zi9QRjlkZHZmdmZ3UmJxYUQ5UGYvZDNOMjRkbjc5NjgvZm1CCjFNTXZYcjc4N3R0M2IwSDZ5YTkvZWdqcjFTeVZybjlSdjdLSy8venc5dHNYYjE3L25GOWRKZm55SGxmLzVCZmZQdnZkdzh1WEQ0ZGYKUG52OTlicy9QSHY1OFBhbmg1LzhWTDcvN1l0M0x4K2t4aCtldmZyZGQyOS8vL0QyNnRzLy92Nm5mbXRwNi9iWk8vbCsrVm44V1VpSAorUE01SHI3OEZiNSs5dnFQejc3OTlzWC8rNENicFlwN0hkOTg5L3JyRjY5L2Yzenovd2p4OEVYS2g3UWR2aWp5MVg5LzhldUhiOS96Ci9lMmI1OSs5ZW5qOTdzdTNiNTQvZlB2dHpadVhiOTUrKy9QRHpaK2Z2VDc4NnRudjVadG5oLzliM3VETm53N0hsOCtlLzhja2I1Mi8KdW4veDhrRmU4Tld6ZDRjUTBSZlh2d2p4cStOM0wxNSsvUS9mdmZyZGc3ejZ1cEdjdm1LVC8vU3R0Q1hONG0rUXkxZS9lQ1dVM3p5OApleWZQSlRkRWYvNzY3NC9qWXdpUjVTZi85dXVIMzc5ZzkwdTMvSytmV3JOdjMzeno2dG5iLzhDMWh5K1crU0QvMlIxLysvRHFtNWZTCmUzemRPRi9sd3hmOHQvOXA5ZVF0V09lTHVGYnBsYkllMGx3UEtWZjl2dmZOd3g5ZlBQenA1NGQvZVBQNlFUdmcrdTI3MytnUUxNczgKNjcvNnphKy9rekgrcDljdjNzbURyU0J0MmdPL2V2UDF3MHVwMzY2L2YvbU1MODRTK3I5YTRiZlBaRTY4azdGNzgvSzdkNXhaMWU4ZwpQZnpMWjM5K3dEQUZ2Y0UvZnZQdytyZHYvcG5QK0VVTTBrN2NyclpEWE9TTlF0eVdRNmhzUCtKUnQ3bmRNL1IvdFdrMGhHYThmY3lRCkwyV2Mvdkh0aTkrL2VQM3pMMUtWdms1eDFpSDgrN2N2dnU0akdBN1YvcGZHcitydy8rYi82OVBLaTc5NzkvRGFubDdtemMydmhua3cKWC8zcU4zTFh1OWRmMzd4NWhkNy9GaE5jSnNCcm1Sc3YzL3hldjJ0Lzh4dTUvTHR2OUEzNCtTc1pxQy9mdm5pTk5xZC80RGYxcXk5ZgpmaWRmL2YzYk45OTk4NHZYLy81bStva3U3WDkrZUM3clY4Ynk2OE0vL3U1L3l3ZFpuNXliaDkrK2ZmWmNHcERQcmM3VnN4ZmYvUFM5Cnpjbkx2WDA0NkpkeUpULzY3KysvK3ZiaDMyVlY5Y3VWZXZmNmp3OHYzM3d6Tk5zb3dsVU8vL0xzN1RmZjMvU1hMNSs5ZnZiMlFIcHIKK1pjdi9pamZQSk9lNm0xMzJoTWFsVm55alhRT0wyR1ZreHU4cDhMdzFSTnU5T3pkSDRRQlBieisrdHZXdG43Y1A3alN2cis5M3p6SApISHg3T0w3OTd0cy9ISDc3NXMzTDF1eitxOWE2a1VsRi9iK05lM3pKQzE3LzQydnRvUE03V1lYVE93bi8rWnU3aTlSKy9BN3k1ZDl5CjZ6ZlBYcjU4OGZ1M3o3NzV3NHZubDI1dzRmdDJKLzN1UXliV24xLzk3czNMRjkrKzZ2TnBvSHo1N08yN0Y4OWZQdnptejkrK2UzajEKNU1FOTNIMzlRcGpjSTh2NHZYVis4NmRuNzU3LzRaY3ZmdmYyMmRzWEQrOWRmUmlBZjMveCttdVorNy81N3NXN2g5NUJiMTU5QXlubAo4SnMvUFB2bWdhL3g3Zy8zclBtYjFtRCtTbGoveU55LytPSTlYRCtzaCtQcjRmdS9mL3ZzNnhleW9ZalE5ZmR2WG43OThQcndhN0QzCmFmZEp0cTl5T0g0OS9kczBXd2tzeStIdnZqcStuZjdiTkovK2hKTVNoNUtzTEZZeS8vZXk0djlKZm8ybHRGTG5iVmV1aDNLVWNtUGwKZGloMzgvMDAzM3ZaUGRqNEU0ZVNockxzU3RZeThWY0pxNVRDMzNVbzI2NWNoMk1yTjYwY3c2MFUvM1E3eVljN2ttN0QvVmpHcnVQRAorVThheWpLVUhGZVVTWC9GTXBRYU55bjY3L1ZRamxxbS8rdlNXRDQybW1rM25zc3dxbjFzcFV4dGVKZGhrSFZVeDlHdFV2QWJvMXAzCjQ3c05JeXovVGpiVVB0akhOc3o2RzZOOE40NjIvS3MvODhXeGp0TnVvSk9NSzM1alpESEdLMHZsS0plVEViNjJzaDliR1V2OHVtTzUKUFJsRnYybmlHUFl4UTlGQjhpSGJiTEJrZ0NZYkk0elZqWlZibGpzcjl5aStzdkF5NDFnR2p0SmlIVi9ab1VjdWtudjJUZVRMcjN5OQpqYTl5eXljTzlvUXJwNHc4d3NUNzRqNHhwYlNrTlJWUnRyWjBsSEtiN21XMHc1S1daY2xMV2VxeUxkZkxjYmxkN3BaNzZjaVlVMTd5Cm1rdmU4blUrNXB0OGwrOG5lYUFnczNSWjg3cXVkZDNXNi9XNDNxeTM2NzNNaFNEZHNKUmMxbExMVm83bHB0eVdlNWtub2NhNjFGelgKV3VwV3IrdXgzdGE3ZWkvekpVNWIycFpOMnRucXRtM0g3V2E3Mis1bDBvVHJkTDFjNSt2MXVsNXYxOWZYUnlrMzE3ZlhkNXhKVVY1ZwpPZVpqT2RiakpsOGRqemZIdStPOXpLNHdzYmZUelhLVGIrUUJicmFiNjV2anpjM043YzI5VExiQVVWaHU4KzE2S3c5M1cyKzMyK1B0CnplM2Q3ZjNkTE9PUzdwYTc5YTdjMWJ2dFR1NTFkM04zTzkzZDNkMWpSdHhMaDkzbmUzblRlM24yKzJzcGNzdDd1ZkwrNUVmR2NwYlIKYkovdmhuSTdsSnVoSEhmbGVpaWJsMG4rcVVNcFExbDNKUTlsR1VvYWlrekE2VDYyTXJLd3puem44ZEh2eHAvYlhiblJNdkhYY1NqWApROWwycFE2bERHVWRTcDd1Y2l2THJxU2h4S0dFb2N4ajBTNmZyTy9IcHg5L2JvWnkxTUtWdVJ2SC9lanR4OHhIYXo5RSsyR1JvWmlHCjBkZ1B3YjdqOTkxdDNYelN0K3pQcVhYcHZpUDN2YmZ2c1pOKzJuZk5kTklqMmh2WFZqYVdhcVZZV1ZteWxZVWxXWWtUMTU1dG1jcjYKMi9UM045TjcrYytSNWRyS3hsS3R5TnFlNUovVlNyYXlzQ1FyeW5xZDBRc0g5Ykc4NC9nZE9WNlY0NU01SUJpRW1kMSt5MjYrWnE4Vwo5dVBDZmd2c3B6dDJ6SkVkVVNlK2VlYTc0Z1ZudnRBdFgrQ2FqMXo0aEF1ZlNKNURac3VkZE9hTjhLMXI0VjlWK05ncTNHd1JyaGFGCm04K1RUS1E3NmVVYllYclh3djdxZFJGR21JVWhKdGxSZ3V5dzl6TGl0OUlkeCsxYTJHYmRpakRRTEl3MHlSWVVaRCsrbDRsd0s5MTAKRkc2NzFUb0o0MTJGQVM4MUNTc09zbkhmeXd5NWxUNDhsbXRoMWJVVVlkcFptSGNTRmg1a283K1h1WE1ySFhzVUJyOEpveS9DN3JPdwovU1RNUDZ6ekpOUDRUc2I0UmphR2E5a2dxbXdUYTg2eVlTVFpPSUxJRHZjeTNXNWxMSTZ5cVd5eXVaUmxsVzFta2UwbXlxWXp5N3kvCmsxbHhJeHZSdFd4SWRaS2RhVTFaOXFna2UxVVFXZVZlWnVpdERCOTJVV3lyMkdpemJHN1lpRU9jQTdoc0UyaXRGdXA1TGRhVEJhV2IKT3VRMzdQd2JKUU9WRkVSMjRIeDQ1SFpzaGczNDVmMWlpQjJ4TTRiN2dkVXJTOWhrVW1XWlVFRW0wNldwRkcyUDRPNkRIOTJCQXRjbApkcUhNMWVzN2tlMUYySXBrdHhFaGdQZkdmdGMydTFWbVdiMnczYVcyM1dHenU4WU5lWEdUR0pMSm9NV2xCZ29OZHhRYmdna091WWtPCjEyTzNveGNncDgzMzJxUjhvREIzeTQ5WUxicFdmRU5zdXlpLzU1dnpyWFVZcmltVjNLWGR5RklrREUzb1VRbFBCUitWNUc0b2lOOUoKMDhHRWJIMGRsNXBOU3FaYXdhYThvZDRNRzJGdjZNVVhlMElmZVJ3b0hhU2RzRUJKSWNuSUY1a0JSODZGRStuQXV5TGJCdUFjWitRNQpmYXAwdmpOeUh2SWU3ZUlMN0dqUGpiNlBGMm5YbjZ6R1QxNk14eWIrZXVtS1ROMnBPTVhVSGkxNXB4bVp0alRaSC82akF2bE9SOTJyCllMN0hOQVd0U2Zvc3gybW4yTjFRZ25hbEFMKzNrMUpQU2xjaTlhOTFjald6bGVXc3BMTVNMeFQ3bVhhYTdwbENoeFUzQ21udDkrM0YKSW54aWFwcjJqU2xqUjlYT0xwYnQwVkpkNzVzR0pWL0wrc1RTVmNvOGxtbi9zUmtiK3QvbkpUMVNPQ21tT1Q2eFhPcmdDMlY2WXNVbgovMXpTM1QvcDU3TTE2UHRpYUQycU1xcUwyYmRXVk1KeW80UWJLYXJwd203RXNKVSttZHJzeTl2TkluMzZuNjVtbDFCOTlZNEw5cWpyCjJGWDY4OVZhbWdsZ3RaS2JnYURiaHRLNFFLZnZYNW55VnpOTGRQUFV5WEwwQlhrN0RVYXQwY2gxdkxnY2p6dlQyUG1DTkdQSzZmcXMKT3l0YnQ4NjRoZWJTRW0yZnA3T1ZlYm9JenhmbGU4dDBaakM4dEZMZnQzNVBsdWMwMkNBL2VRMi9ieDMvOVpmZFoyL3drb2c2YWovbgorby9LSStmNmowc2hNM1RvTzBvYm0ybCtxOGtic1drLzk0UEVVWFlTUnh3MG9CdlJnYWdCVGFJQ1FRbFNGUWhLMEV3TlNIV2dHeHAvClZBK3FUUTlLcGdkQkU3b1JMZWhJUGFqU2xMUk1WSVVDRjhjOXRlSmIzRUd1cjZJSnFTNEViU2lxTmtSOTZOYjBvU1Axb1VwOUNCb1IKT0ZlWVRDbTZwNFlMdFVnVkk2aEdsYW9SbEtPRnlsSGdVcnFuaG5SRERRazZFclNrSW5kRlZWR0VKbEdVRXRsaG9Hbm1qdXJTcmFoTApVSmlnTWtGcGd0cFVsa3pGQ2FwVElxZWFxVDdkbTJKOTFES0ozQWJKRGJKYm9meTJvbjdDVDZEODFMazRaRm9kaXk2bHFXUldxVUNoCkxGUGoxR2RTMXlCanVTVlZmNDhNZUJTUktBOU5neEMwWTZwbmpITW51ZXg0NUk0alRqdVpCT1dFdDExa2ErK1JJTTRsaHFleGlVZloKeCtkY3g2WXRhaG5OVk9QUDNpdzNtQnIzdGpEZlZ5ZjdJKzVLMnBXOTJTMmZsSFZYeXJRejVaV2RrYTlTVWRxWDY1TnlQQzFUczNsNQp1VDByNXovMzU4WG4yRFR1MVBmaFFva1hTN3BZekpKM1h2SWpaWDIwTkZ2dXREUHNGcHFiMzFlMjd5blgwODZjZkxrY24xakkzS2VkCjVmcDk1ZlpwWmJwQXZEU0lUeTdUbzE5OTVNLzVKdnF4RFpuaFptN3FaelNQaFpiRmlwb3ozYnhackxqMWM3Tml0dEhKVEtYKzQ3eWgKTHhzZkQrZXNyaUs3Sk85V1dyWFpMaE9OUmxyV1Z0ek1XMXZackZ5M2NyekFvK1JuT21OUWwxaFROOTFmNWtZREg1b2VZVUtQY1ovSAp1TTdBYVk2MDRUek9hOTdEWTNaTXhSakw5RjZlY29HVGZCOExtZDdQTjU3QU1rNVl3elJ5aVk5bURjTjZmNHd4UEpFTm5LLzh4OWZ4Cis4dGZhQjEva0ExMVowVVZrZTFHaloxMHdrTE9Tc3N5aWFTM0RyN1lvM0FDOWNmTzVwR0ZUemJUSzF0Rm9IVFA3QzE4czdLNXFITTIKVVJTRmc3Wk1sRS9kU3dzLzdSMDl0ZXFyVFpBdTZhL0ZEM3kyMXhTQTRiZkZBbExmTGJ5M0VDenB3WjNveEsyUXRPbklQUW8zdW0zdQozRm5FUDBpUzhPa3U4bmlRa0F2RjhrMUU5R3Y2ZDIrRVg5eVpsM2UrRHBQSThaSHlQTnk5Y1BpdTE0V1Mvalk0ZnVuNmxZTHBDRUV3CjBNQ1k2QWFHSXhnQ2VhRTd1RTdIalQ1aDlRcmZrQmRoYWQvVFB6dzNsdXZNMXRtc3M5Zk9WbzJqVG8yVmRoYnFyTE16emM0ck80L3MKdkhIa2lMZFQ0NE1qLyt0OGI4L3JSaFkzc3JXQm1VMERIOXV6cmhObWRVSHlPZWRIZzB4eldXNTVqTXVjaUIxam1kN0hOYjZYVFR4eApnLy9ZZFd5RzYzK2JSbEJ4T0VUNWF6M1UrV3FSNVhJbzZVb1dTRVRWMzB4Lzk5VlRxaDYvUFcveEtrdkZQQjlxdUJJOWNIMjB1ZE42CmFPc3FyR1ZiZ253Wm9OMUdSeW5uV3VNaWY1UWM3ZXNZOHJvZFVFRWJpVmRwemt1NzJTYzN4S2VaUlRQTnE5U2FaWkd2dUU2VWExRysKMmRhMjVIa2pkbHFZNHBMbGo0amZZV2dyWGMzQ1Z2cERmYWIyOU5uV1dSZ3Eyc3Boem9YWFZXSEUycGFvaUZYYmo4SlIwWmFNVzk1MgpiZVY1M29abit6enRmZndveG5KVlU5clFVczFsKzhTaFBHM3R3a3kxSjkrMksrSG5qMDNUZlNWcDVYamJJSTZPVkx3TVh2ekh0OC8vCjhPTHJuMDcrQjREOURiSjR0YTVCOWttTVk0cWxyQVF3eXVKaTkrSnJqUHh1MmRvVkI3OUM0eERzaW9OZFljdFVIbGlVOWVHVlB1SmkKN2JDblhvaHVXdGFybERDOVArTEcrK3MvcEp0Lzh4OS9sajdHdjNMaG9oMzgzM3ovdWJkZEo5cCtrODJmV1d4M3ViWU41WFowUE50bQpzUmdXU25ZRFNrS3lGd1REZVMwVUVZRDBPbEkwdUtkVlNFV0NsY0xBTmNXQU8rNFNBSHBoMzljOS81cld2dHRUWUtPQ0dOMGpwUFp0Ck5aTmpMNTROQUtvdVhVZHcwaXZjUUhINU1hemtwWi9IMGJDajhUcWJVWVpXUWtWT0VEdlIwQk9uaHNKaUtBckZVUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJR0pLQ3BzSTdBMVBjWkhYcnZoOGVNcUJEbm9RTkdYMnpUUkFLQmgwWXdRTWRQbkNqMHM0QUlWaWFkTE01ak9CV3h3bGlyQ0VKSWIxVwpSeEZTWmxVTVlhV2NDdmtVMG1tV2ZvQkllaU9UYmFZWW1nMHdlRnZVUDQ1dU5keEZSMTdzZ0J0bU81eWIxL09HMWtFMUJ4WXoreTNtCk1RaG1DSDh5WU9aSmFCa0ZCSFR6dHpyY28yS2JETk4wMjNCTTE0WmVjbk40TnBpU3dwTm1Da1YzT3kvNkFCUnRVRkUxbjZvL1BEV3QKSWxPeldLbGRGR29ZbGRiZ2Erb1pSeG9XYmllS2xmZFVPTHJLb2VoUGpKdnFIYXA1ZE4yRDJvZmhRUlVSQ3YwREdzZzZVUW1wVkVKYwpEYm5kcVNJbnlvanBJaGg2UjQxU0gzR05aRHBSU1RBbk5nT1MzbENxdm10dzBraUZ4RUdsbzBaeVE0M2tEZ0xwWkFwSkdoU1NZc3JJCmtjcklMWlVSQlp4MlBXUVo5QkRvSUUwTG1Xamo2R3JJdVNLU1RSR2hLdEwwa0NOMUVXb2l5b2NNY0dmNDV3R2tTRS9oK2Q5MzdlODkKMWF6bWs4R281WVA1SXUrNlY5TC9Hbjgza1BVSXFsZUR2RUdzUTdQUXA0YXc3Ny9UN3ZkaTdOZmgyTG5oN3RYNEwxeHgyaUh2SFg5Zgo3Ri8xR3VpLzZzenQvMTd2ZkF5M0J0VTIvRDJCUDNBVUQxanRqdFJPNXNKWURhdTltaTlhUFIwZFZFOC95RFRncy91UzYwc3RFUkJ6CnVzdzRZd2lja2RYLy9qMW05QkdjK2dzZTh5Nll0M0owTVlUbWxoZ2RGT2NPMFhPZjZ1SmVqbE5IN1BtbjhmZnAzeU10ZThSQUR3MVoKSHNWdVBJN3NTTHUvMHpSOFdFNWNOcU1qNTdMUHVuL2ZQTmpUbWE5SCs2NjdsSHV2OWg3dWc5QTlNRHRrNnZFQ01yVVlLTFhEVVIySQphaEJVNWZUYzRXV1BuOGdicnJuUjYxWmZhTXpJNUNmSnRuemQ5UGN1MGV2bUVpMWtWdVlXblNnRmROL29MUjlPdHozZCtIenJhNXRmCjIvNThBeVJtbEp1Z2JJT1Q3WVBqVGpqdWhTTjJkSThlM2VOSEc0SjBVc0hIUEtTbkdOTEhVS1R2d1pGT0EzVHRvOEJyUWJueU9WcDgKS044UEdPK1diN09GVHcwbmZZNlVMczJvdmtkTEQzaHBLd05jZWpwRFROL3VFTk9QejhwcS9vTjFQemVuQVMwOVlxWG5ObEh2emE2awpiNmJ0SDl1YzFWbTdjYS9qM0oxcytxN2NDdnNrVGdZSlZGNnVybHlmMEhmV1hUZURyMThudDVUSlpuaXhXYjVTV2FDSW9xeVhIRnczCkN2VUw2N1MvNDlUbjVGY014Q1VuM1dsSXhHbTU3QW1NcDhiOXM2Q0ppOEVUZXp6L1dTREZkQjVOY1FMM3Z4eFVjUjVZWVhFQTA4WG8KaW5MaXNWMVAvTG1QQjFtazZkRTRpL0NlbGZQWXVwR1ZNMTFjUE1mQm1kVFh6N2lHaHBXMHM5NWRiU0prcGt6RkdlSTdyQjdDS0NwMAo2amtJczhxMGpZZ1dYVmVvMTNtTElaZWRHVU5xZHhQZjUycVBWcCs2cmx1Z2RyK0pJRnpOa0NJZm02VkdMVnpkWnJSZWlmeFUrOU44CmRBdThmMW1Tc0Q3WXBsSVIxbS9YaGxCRTdzY2I0aSs4YWwyRVp3NHZrVmU1TkhSRDVTYzNwRGF3T3FmRWZzeHBxelQ2eVQ1YlUwKzcKVUhBOWpHdmF1OWJNZHBYelBCcFJQcjJsRHpLbmZQZnExY05iV0ZUMER4ckJ6R28xU0g0dWtJMVMxUmhHV1Jwa3o3Rit4eFlFZStlaQp1NEtBSWRHNmVKMmJERjJhcE53akdUMFVkUlNGZTlncDFiMXBpRnFzRGFYWkEwb1YwYW40enNkMXpreXRrNEx3TkVqQ3FuSnVnMFI4CnRLM3N6alZQMFQySlhqSUFLTnVoOW9rTm5YcmlSTUJUSWZ4SkZWRlhSbysrUHhwdmNnK0ZDbnZSY05lbURHZHJOZWVKMmlxaFhMUkQKVkZOWnRkZ3U1Y0ZEdVczR3piUHNJS0tHSVowYVdEMjFrbHZwUDZXVjJzcDFLOGRlcHZWbUtOM2J2bmU1akRET3NDdHBLT3k3cVN5dAo1RjA1LzZrblpidFFycWR5ZlZadUhpbTM3eW5OYlRSZDlsbFR1Zi9Rd29rODFmZzV5bmtNYm8vQ0xTME85OWhYYWRqSGsxUXV5bU9QCkpzWlNuRXdkM2NXa2NKbmREL3BsZHcxdkZnZHpPMWhxRmw4ZnNNOU10aVp1NkIyY1c3QnV0bkRkU25QYnRVM25POXBpTUlFVHpZN1oKNWlZc01VZk94RnZNUUhjTFI4Nmo3aEsrcGt2WXhvOVl5VUJ0SU5FKzVyYVhTbU12YkM4UU9HaDNtYzN1a21sMVVSZncxaHpBdDJiOQpCUU9NRk9LNjFRWGkzdGJzTHZUOVR0L2ovdTBPNEcyd3Vkd3dLaGdHenp2REVUYmY3M1RpL0YwcEczZUVqVHVCVmVMdFVKb09vZW5nCkdZN1ZkT0lFWG5kUW1lME1LTE56Q0EvSW1JYUpVVzFrRDRKeHNld1U2M0tPY1RuSDA5MU1GMUF0RjlFc285eDZqbXJwWmJvZ0dWOUUKeUQwQklMZGNSdEk5aHFKN2I2R21Ic2FZWFkvVzlTaGRqOC90c2JuK0RGM3FONUYrRU5vcG91K2piM3NjczB2V1hZcnVnYlpOUUI0RQo0bHNGUmUwRGE3dVlleDVPMjFYREU3VncxQWVuQytyZ1pSUEZtU3A0b2dlYUpqaGRVQVgzeXVCZUhkd3JoTlZNb2FWdGRubHFhbUZYCkRWMDVqQzN0eGp5b2lQZURvbmpYRklNV0ZUejVqYS83ejlaS2JhWHZYWDBienEwc3ZVeW1WM2J0TWc0NlpoaDF6VUhqN0dYVXhEaWUKMDZERDNPeks4YXhjbjVSTFAzVWlPOTJYaXpzM1RUMlBseVlHVGYzUGs3SjhjT0VPTm0zcGM1UVBqOVorZjd3MlF5U25reGpKODVqdApmYVRrUG01N2pOdzI1OXpVREhhanNlN09wbWszMU8zTWRPcXJhOTQ2OTlkZCsvZ1dHeC90MEhnU3kzRFRQRlhiU1VSRDZyWTZzOWJkCmxkdUpLLzdJNmIrWkE2dFFPSFhYcFJydXV2Tnk3Nzdza1E2RnNtMmVMTnhCdlpoeEYvSndSMzYxRDN6WUtKU1VadURMSnA2M0dJZ0oKMWo3YSsrNXRrN3VsM2UvR09NVVlFcUZCRVNvT2VXaUVCa2VvV2tFM3hOU2lKTzVOLzFEdXFVenVTR3ZodFZrTVBYQmlESjFZVFpNdwpKU1dsaWJxUGg2U0dDN0Z4ajBYSGVaekZQaUoybTB6OTJnWUI5TEdnMkY2V1N3R3lIaVo3L25NZXgvWlkrTlFGSVB4MFJycjdtUEkrCmhCWEJLSFVIaXJqOHZRRXU4bHhGdVNQbVJnVGF6UUFUR2JhSDBLMFF6ZVp3Z3ZQNGlLcy94RHJ3VDY5ZlAzdjE4UFhoOTBZNmhKOU8KbDRnZDYzSWg0MDl1dXNhUTlTYzhIcmV1NGUvM0hyMCtHUXoxRklLNkQrTGZnMC9WQjZ6KzMrc2Q1bFRVaXFrQlRyZTllNnViT0pZegpKY2tmM0lQdSsrT2Z2c0J4MGpjd284VlRzeEc4QjBrNzlmZDUrZ01mN1lGN2pvQ3h0M2Y5UFZtSGg5M2pqcHJkWThrVExnTi8wOVM3CnZ5Y08ra0VTbEh5bTlDVFg5MU5QVC9LRFpsVDU4WUgxZ1FjYmQxcEtucEdJTmhhMU9rTVhMelREWHFuaDZjSWZGeG5pWjJoS3VLT20KM3lXbE5iMmpmUm9IbmVlTFBGVEkwblRlY2RGbzREQ3M1eHZDR3hLeEJ4dlhMVGhNSWhaZ282WHpUaGFvbWwwcWw2UkNtRFFWMnZYVQpFRXlSN0svUVZuZzdKRDl6QkpNRDZudnFzMkl3ZW9Mb0hhMHlOYmpLSHFwaVFKVWRjRDZieldRUG5COHRKM2ZiL2RUTUp3cGNpYWF2CkxHWkljU2o5YWtxUHEwRmR0L0FmVTU4bXM3VW8xdjdXZ0M1ajZRRWh1NUQxbml0eFg2YW0xZldTTHBibGtaTDNaVG9ockU4cTVmRXkKUGZwVi9iZ3lmVURsQzhyZmVabWVWdTNwNWNjR0wxUm9Vb0pMWVd2aklpcDdSVW9DWlpkck1SSmRWTGpwcXpHM0MxazFYVStheTZqSgpWOWpleCt5S2lRYmIxZUJ6RnNQVFFITWRNTmRDZDZhR2xmUEluWDNjVG1NNUFNbWRSZTRvVUc1dHhscmhQNVBOeEJ0enFONVpFTWRzCmNUekIxQk9IenVVV3orUEZiUS82Y3owWlovRis3WFlPdDM1MHcwaVBFdW1HbEhCYXBqRi8wTTRxazNiYzdyemtzMEplT0EyMm45TnkKd2NmeFNPazJwVHFOSDU1VXppdzgreko5WDRVUExVOXQ4TWsvMDlPci9xZHA4REVPQXAzaXp1RHBtVnJFdGZxR1dxNngxWlFHVDlJSwovbUVxMmdTaGhCN1QyREswUWplN2I3anF2TXZPcXE0ZWg5eU9icDZMSE1SNWlFTnRMMFQvWGVRaXprY0tzZ29xTTduZWNSSTFpSi95CmtzNVBvcGxjT2xmSlpvOHMwOEJZL0tmUDBUMWYyU0ZEVGdFd3ptR21NeWJ6R0xPSmo1UVRqak05a1FGOUh6dHFaWHJmbHg5UjNzdmoKUHFyODJPQmZvTUVQaVU1NThzLzdHdHpqaHRPWldhVHM3RGhtdzVtYVZXU1hPWEVNczZIZFJzMGdMaFc1ZTNzMTB4TUJJU29ZVFJaNwpVTGxPWUhlNmI5TFJRbHZ4Nk1xK3AzU1VMSUtra0dsQXhpZGFRckVRRTUzWGluUUFLNEhkVzEya3dBb2t1cTJ6Z1IzQVp0UWpCdGVwCnNxclVmTlpaZWRGa2JPakdRcGJnVzUzTmJhM0ZGN21QcGZNcmQwdDFNQnVWcDRrYVZOZVRSa1ZvMUc3MkNzbXAwRHI4S0lMNDlrSTUKejZhaW51RDV2U1ZPTi9ISlpYbEttWjVXN1daOWFwbWVYdlUvVFlOdTFybzlTejU3bERsYjdySXNPbVJqdmJYRVhTc1RkczFNMVhXawpqV3FsZlNwWWFxNmp6REs2dG1DVWdra0s5aWc0cytESVVpZVdnc3h2bVg1TG9lWFo4MjdSVTlYU0Q5ZmkwVlJUQTVFL0pmWHdhZkxoCmxuNjRZOGNuOHpLNWg4bTlTOGtnNUtFNWxXNEhJUG4xa0YycnU1SG9RcHJNZytUdW83M3J5QjFIM1duVVhVYWp3eWgxYjlFME9vdDIKanFKVE45R3BrK2dSLzlCMDRpQjZ6RDIwY3c2OXp6TTBQZVlZdXVRVWVvSWZpTEU1VHkwM1R5blQwNm85WW9tNlVLYW5WLzFQMCtDUApIT1JIRHZJakIvbmJYWjkvK3czK3lFRis1Q0EvY3BDLzNmWDV0OTlnOTNWZlBMbnU2VVM0eWt0Y2F0am91bDYyd29RcVdlWVlLS1ZrCmRYMkhHZEZURi83Z24rc0ZyL2xuYmRVYzZNZ3NFOUloaDZ0WmVOam9Sai81eHV2TFBlV0xOVndoYnYrUWxxczE5UHhPNzZteHY3NUkKcXptdU9GTTR4YTFjdVA2MFJydStsQXMrLzVIOGlXNy9lTm50SCtIMlQrNzJiOW5FN2s2Z3liY25FT1ZIQzNlczY5dXpjdk5oUlpzNQpoU0hqNTMwK2x6UHZrRVloZDZESmJIRHgyNFlUUHo5NnFaN0gyYmd4Y1R4R3JneWdzdkhreGZIVXhaUHlOOWRNVDJKejB6TDdkVHVYCnpRVWRpdjM0N01aV0sxeENRaGdXd3ZPNnRPTnk3SlNhZGk2UHAvRG9TV2Zxa0c3R2s4MThhb1dSa2FXMUtxY3BLZU1ZYk9FOTg4SmMKYVhVSmlYblI1cnhzYzd6d3gyWHN6K2RyVXFOTDh4d0RXeE5aU1p1Rml4eFF5em1zaTZFNkRjK1poSWZXaXV2NzQzemM5WHJ2ei9JcQpuNzF2UHBFRlhtU0E4Y094bzNlR1o3eHc0bEhEalJxTWNYTFk1ZmZoSnNzWmJ2SVMyUE1FcmFwN1AwN2JmRS9ybDkvaU1vaDA5ejZUCnY5TEhRQ2kvRjk0blBOWGpCVDUzVEFMdk1IbEV3dnRhL3dCNDRyNzlGdkd3NXlwMWdPbnRlTVBwRno4NHlpOWRtdXRwTjljTlp4WlAKTXI2T1NaWjBTN2hyYVY1N2t0YzhISSttR2M2T0U3TmtNNlJ2Q09mcnFWelhsc0wxMnVMMGRON1NQYVh4eHBFcVhxYTZWd3pLczlGWgpkYlJnNGp0enlYZFlUeHJpaE9IQXF0T3F3Y0F3NFNQbTk4N2llNVBoQ1RNZFdXTWNwbWRJd3l4djJWMU84N3VNR1Y0aW5lOHpYZktlCjVXWE04eklFa0V5UFJaQzBzekU4Z0tSNkFNbm5ndE5lWG0xUGg5T2V6TzBQelpXd1h3QWZjelgzSXJsdW5wSDlJSVdRbU5CUnJ4UnUKdGRaMXpKazUzTzVETHZxMGRWWXZMclM2U3c3Wk1xQjVEclF4RzdQRFJVMnE0dUNmWlg1MitHb0hjalFJcTE1dzExQ3Y4d0FONlpmNgp4ZkxEQzNaNUJHL01FNXk0Z0k3bSswMjJVdlFPajV4RGVUbDcwRi9pZ2k2Nm9oL0cyTWpUYkRtWDh1V0VDL2x5TEZmTzFBTE1YS1B3CkVFY1BhOVFkYTFmbEF4THFXRURqN1k3VENLK1o3TGdkanpMMFdMWFlZOVgwdnYwZStlS2Q0bnRTOTdTN2RjNDJuY1RGUlp0QWMyTncKT2o2MEpFWmhEWGM4WkdqajZVTHBHS1FQYjVrM2M1V25pSEpQbkI2MDBXeVlwSWs3Sm4vTXdnSm4yZ2MzbVZSWkpsZVllUFRQVVdaYwpFZmFkWkduZU04cnRta2Y2WURMb0FaR1hKYXNubks3NS9jRWhsaFArTkNQODhwL3d2bTA1RGFrY1cxNzVob3QzL05aajdHelAwQWg0Cm4zWnBCanEyZllTdmorRDBFV1BlY04zSzVOSU9kSHNoWC81NytPWXA1MFFXcTQ3OUg0RC9sNkgvYTN2VnNvT2RLZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJVUhISW5abDNHUno2OHozR29FOVpkTVA5NmhDTVdMd091K3Z3dXZNUWhRN05aU2JaUElLRVRuTEtFaDMweUU2UXovWUNRSC91Sm1KKwpNckUrTjhUNEpPSjZBT2U1STRSbklXQUhJQjFnY2hKeE54dmhOSURKQU4raVR6YWVmZnhwUngvclVhdlRwNXkxNmljUy8vaGtIL1ZrCmc1aTR5dFNQVlBERHZGSEJYK2Q1Z2NSM0pjc2paUVpIYVI2cjh6OTZucThxa3R1UXkvOHpONnVDNVRKSDVnVFBhd2pNUUNiZEoxMUwKcWJHbzhTUWgxWHU4OEVkcmNvMVhtNmpRdzVOKzFtYlZIUE5wOW5Gdk1seGg4LzFzWnZlVFpyVlBaeVFleFRzTFYrR0w1VENuamFNegpyMVZmbnNuOUwveHhVWkQvVEExK2twQy9YSkx4bDUzZG5HbVRrTDJuV3BMMmV5Wm9kK2FJOU96M2xwZ0g3Rm1USU9zZWVXZWJZaklsCkhOdmVOcG4rZmR2MDczRGpCNU12N1hnVnp5L2VEbFlaejFVWkRxV1NoVHp0VDZNNk9ZaHFmd2pWaUFQZkgwQTFIRVUxcGhwOC81bDUKVHl2MzA0Y2RhZlQ5NWEvZm9OcmxOQlh2UHY0Sk5qZFkydlNjZEpYeVhNSTd0a1JXaVZuaENwTWkzOWdHem1oczNjRWh6MW5TcXBaUApmTEhzYkc0NHVlRXVjVzlJMzBpVHlkTFNxUkh2T3pWemlhWkFtaTF0VmFUQkJJNXdUN3hXTGNkWmoxanFnTnJCWFhLU2pPejByRy9tCnU3cGM4c1d5VEhXNVdOYVBMZFBIWC9xWkd0U3AwYk91ZVNvNlQ3V3Y1MjE2WXNOaS8yOEQzVk0xdzhDYlBNdHpwTHRqVE1vOC9vdmYKWTVMcmVVaDNQUUxabjRSMy82aWZIeHQ4d2dWMkNNWXNxL0ZHQkhtY2hvdHpjR2VlZm52a3FiY1E5Q0tGUEloNEVQQWczaTA4em5ibQpRYmFRN0VhNWpvaVZ4OFM2UWJCcm90MnRJUyt1TFl1OG56M3J4MFdrYVRqRTIxUGo5NHo2NHltejQ0bmIyOW1VYnhraDkrZlZ2LzlVCitpY2RXdjE5eDh2LzhHUDUyUnRVVTh5Tm5RT2RhWklad1YzVjBoNW8wb09XOGVEOWg1cE03UUNQZFc5MDJsbTRqME9DSkxkd2U1S2sKMGNnZDZqeVpwZnZlOHVuZG1yMzd4bXpleHhiNzZSdEpUNWpaZjRhTW45TkozczNscktSSFNyeGNwa2UrQ0I5YnBvKy85RE0xcUZpSAo3aE1ZdlFMdUZ3aG5DQWpIUDR3SGovZmNlQ0kzeGwxYXZKNGsvU2taOGZZNThaajV5ME5YVWl0ajlNc2UrWFVTU0hQeHNNeTc2YkdvCm5EUHN5dFBLemZUOUlKY1BLMy85QmtjRDMxOWRLdjRoR255dmJqRTk4c1hsUXdmT3M2ZVBXZFNwRlUwWGp5Qll6N0pMN2pOTWhyT0YKNU12b09Oa2EybXp0ck9hTlczYkhHZGtCRnhkUzNJUVRiczhrLzJEM2lSYjVld1B6cWswK3lXNStMNDk5SkNkZmhYZkhxdnZLWDEwcQovcFFHTDZzSXl5TTZoV2tjMDVrS2NxYXNuR1JVSG1GaFhmdHBHdEhVMGtENzNxVlpwSFYzVVhsSGM4M2VHQmo2U0Myc1dDTEFoYUplCnBLQUZoTUx0UktudnhwTCtGUU5DTThXZlpmYURpVStCenpEd3didzNFOTE4STFxanluOXExVlBoN3pnMXVZOFNuOGw1a084ZzFVR00KZy9CMlRWMERjbGo2aTBmUy90amcyYzllUDdOQTQ2bDk4TE4zNG9uQ3QxY0VIUlNVMmxFK2UwMXptd1pWczU2b21tV25wRm94VmVVVApPK2JzNXkvUzRQdFZnOGVPSzdReVhUd1M2dlJNcDFHZGFWck9XUzlTSzVvTXVUa2VYbkF6NERidkcyQXJ0R1I2eVE0Rlc0ZVVlcFlEClVKUHF1UmR4OUNPK3o1TjRudEN3cHpQa1FRSmI4eHJ0ODNqZE1OTk9wR1VKU2ZsNURxR2VZdm5YbG9vL3BjRkhkSWRIaW1rYzA1a0sKY3E2czdKV1pRYys1ZEpEQTFNOE5zSEswckNMOWVJQzdJYi9JM0hLTXZDZkx5R1BlMDlGMzZtZU5iK1l4N1FmN1JUdGNYQS8wdTU1MgpwdXhvaHV4S3Y5OE43ZGVCbnI4c0R3eDd0VUpLL3VwUzhRL1I0SHQxaSttUkx4NVhZTzR1NlR4ZEk1cUdMUHk5akFwVlY3TThKMERYCnhWWnpJNVNlcG44eUphNGYxMzQwUmU4OFkvOTRZbnNIK2EzbVNqRG53ZVJZdjdQemNmVWs5blYzTnU3TjNlMEo2cXdJUndJK1ROZ1cKVHU1dHVERjM4VUhEejlsY1BhVmU0YURmUTFtdVFpNkRVKzdUbXFGcks4OXhJNDU2RG5IbGNUekNNMFBXM0k1TDJtSWdtaG40NnRHWApGOUpoS1ZmQ2x2dkRmSEpMZXZyUkI3MVNMWWU0WEpYZGMzeDBDNS9rVE11WG5HbDVoMHk5aUhzNTNhK2VuQXgyV1U0Uk1LY1ltRENjCnc0cjhUME9XV3o4bzBrOGc4bi83QVlmNzR5RzdpSlZPUDA4NzBXQTgyZkZVU0lEQUpjSldPN2ZYTVp3ZkR1RTBkZkVrSCtwMDNCOTUKM0pPcFAyWWZKQ0oxUEwvaGZqaG83ZndBaDIwNEpHMS9oTVBTam5DSTA2T25PSFFOL0hvd1QwSFlEUHU4clpFbmlNMnhsdUtuWnEyegpMS0RJdUFJZUdCOGV6ZFQ2NFJmck9WdXlKT2gybGpteHhHSlhWbzlaMkJUSGVobVcraEhYZnRwYXV3Z0R6ei9pd0gvRWdmK0lBLytzCk9QQjF1N1RTaEhvV1hSU2VFRjMwZUc1NjArZytzMG1tN1RSUG5HMVBTT0h0azdjZkYzUnI1Nno2a1VIOTBLRGFEZzFhaDhPTCtvR2gKT0JucGhQZC9NQ2ZkemNLUHVsclBTemc3UzJFMzRSNzcvcFBtVnJrb01wWDh2c2kxUjZPKzNuUHl3UTUzZkRta3JNc3U2NldwT3pUdgpGb3E4QzFoN05FNnROMWhQWXRST1R3NDRlOXJMNFdtUFQ5N0htZVZ1Q2ovT2ZaL0tmOSt6S3A3RzBwK1VKLy8weE5ZZ214SzFDNW16CkVOWkJtZGR0c3lsdWJMYk45ZE16UlUvV3lTZTM5YmtqM2Y3bER5L2VQZnpYdy9IbHMrZi9JY3RpOS9FdmNRckl1ZG5zSTg4Qm1jNFMKem5xNmFrODNPNmFhdlczSENlNXpWWHVPMlJ1Z3J1NHN2V3djOE9oN3JQemo2ZkhINVBqSGpvLy9GUGovelpEeG52ai82ZU1EQUt5MApGSkNlcVBIVTdISmlOZmtoejFjNXM2eCs5QWtyazZxcGo4d1V6OTJaN1NoS25TdzlQN0dMd0QxSHNZaStHME1BWFBpOXN3TlBuNURuCi9DUS9zVmtOMzJjeGZGcTh4ZmxoQ3g4YmNiRlBMZEFQV3poTklYRjdJVW5CazZiQ1I1eGNNMyt1czJ1bUN4TmhGNnBELzk4NEVjWXoKU1gwYURNbXEzemNWdmk5aDlUNWR0Wm1ScC9wcEFTNm5rK0oyK3ZnUWwyR0tEQk5sZXVSWWpuMDZpczhuUFpzTS9aZHI4SkpuNnRMQgoyR1hQM2FZTHpPMkNmbkV4OC9BKzc3QUZGRTJmR0ZGVU5LYW9oeFJOSHg5VFpKNkZveG9mYUhaSXQ4c2thMk9mZHVUdVF1S1JIK3JvCm9vOHgxVjA4dkdqNkVHTmR3L0k1a3M4VHQ5MzIxRzJUbVNXWXZhMGxiN3Q5VXZxMmZmSTJpMGFhUGkwY1NhTjZEYlhLZUtUcDR3T1MKaUZnRm5tRTFwQ3BBcXJLYzdrL1N3NVFMR1dSK25Bby9Ub1VmcDhLUFUrR3h0RkVma0ZUcExEL1VoMS83UTVtY2hQRFZQN3g1L2VYYgpGNi9mdlhqOSt5KytHSFR0OFl2cEg3N0JOMG0vK2ZMWnUzY1BiMStMRW43OThzL2ZmdnRNMUcvNzQ3QnRWOXVhRm5oT2wzVk5oN2dzClY3S055eDlodlpLNXRQSkpyL252di81SmZuM0hQOTNuK0s5LzVzZi9JWC8rYnlIK1NWNys4S3ZEdi8yditmQzFYdkpyK2VYMzhDWVAKcjRSNGRxUERMMGVxUDg4dmgrc3YwWFpYdjViL2YzYjk5dDN0aStmdlhyeDUvZXp0bnc4L3A4bmlaOGMzYjE3SzIvL0NldUtydTY5Zgp2SHZ6OXF2anMrZi9JYjMxMVc5ZnZIejQ2dGNQejkvOTlQQmY1WUwvVS82M1YvMHYzN0dCVzc3TlAzSTZSQndWcURiSUVETW54aUlUCm9sclNQenRBdGZwWmdjdFc1N1FkL3ZVWkc5cDFYQXJoYWs2cmpIdTlTaUxaYThmSXEwVVJ1QTU1dTFwRnBEcklpcitTcHZJaEZ4elcKS3U5Y3BYcU42WkR6VlpDMWRYaU95MnEra3NWYkR6bGVyUWdCRmNuL2FwRlZkVmkyS3hINmNYYnNlaFZrQVI2V2RDVnJMZHBsMjlVcwpYT0dRNU12Q3hvdmVMZGFySEdIUXIvTlYzamFab3VVcXdmakt5OHB5SlNxSTFGb1JtQ3QzVytVdTg3SWVVdFJuQWlIbHVoMlN2SVpJCnQzcVpFRU9vNVNERFhJT00vVnF1SUcvQ1A3NGhTbFMwSUJuT1hFQ0lxZHFycmZNVmxKTERzbDdoN0o5RGxLNEpzaFlQUzdoS290OGMKV28yVXJ4YS9LRnlKb0xxMng0NXJScTQwVFptRzVHVHJlcldFYlRtRUxFTXFnNkJYclZkYlNPc0JOd2gxNHdOSmk5SldYWEFlYms1WAp4Z1NFeWZoRjhqYnNzaS9DbGJBb2RIV3FWM091NGJCSUh3cjdFNEk4QmVaRElEdkplcDMwT1NDZWgxRHNOUlpoS1J1ZVdVWWNuU3VmCkY0VERZcnczRzdDRW1TLzlLYS9LMFVRclhCWnl6N3pLZTZaRngydkpWL0trTmw0cFhNbmZNb2RXNmRjZzd5V1hWMUVuRHVzaTQ1YmwKbGt1VW0waTdxOXhNaGxZdmt5a1hwT01PWlVXMGRtVW5DbmRlY0puc1NFS1FSWmx5a0haV21XV2h0RWtscTJSRlc0ajZQYVJaWG1pVApjYStMakxNTWsweDh6bUNaa3NMdmRjVGtzYTdXV2ZwY1ppQ2NUREtWY0RONXN5cFhaNWxUU1dZYnAzU0pPdXQ0bVF5d0tEYVJrZGRGCk9pQ2g5K1JlOHV4elR2Rnd0c3B3MWI5elFkOXl5Q3RUMmFFKzE4bXJrU2dUQy9rSU9WczJCRjNMdE1JYlJIYkEzRDdyNUpISGtxMjYKMTVHVkkwcmQwSWdSL0ZZK3U1VW9jM2RiVWN1YWtibkdGMnYzY2tLYnFYaWdYc3ZmbzdWejhtTCszaW1nSTJSWVNwSTFML1BxMVk2NAo2THhLTWl0bFA5NUFrTzFWT0lTdzJpeWoyQWc2YURMTGdxeU1YbXZSdS9aMm5HQjMwOHVjR0s5RVk1VkJhKzJFcTBWR2Y3aWJFZlF5CmY2Wld5NSs2dFhQeWJ2N1MvK1dmNUo5L2V2SUc4WXR2di9yVk05bFRiOTU4OCtldjN2dzdONHkvZi92bXUyOTBoN2g4eGE4ZnZubDQKOXU3aDY2L2tGcnVkWkR2ODVLZUhmLzJYQzN1S1RJeTh6c1FVQ1YvWjZQR2NTNUdld1c0aXJLakVQTzRtUmMvbDF0MWtxVmRseTdJeApZc0VzT25NN0Via0o0Q3FWQ1NKNnYweGxtU2hWZUt6MHN0WkFRbHdSOXRoRlFkaEtCRkVtaTE0bXF4RlJCNGVTdGZGRzJLd0dMM05pCm1EZTdMbUtYbHAwNWhOVW93dnZXdUEwVVhybllEdDdyeWNUVmVuUFZCMnVVcmVvbXp3dWRLRXlHODd5OWNRWEQydzVuM2JKZjcyRkIKZndnVHFWRzZWYmpLcXgxUjVBOXdyQ0RzY0JHaDF6bFd3RllqbzJJZjlRMlF2M2p0VmRDRlNYYWwxa1lqMkoxYVI1TVlaREFyN3VUTgp6THBNMjYzbXZtejc0N1JLL3NDdG1aUFgyazM4M1pSTGFhNExrR3F6N0E5MERzMjVoTlV5SGMvTTZWblZ6eTUvYkl2czJEcmhvdXlkCjdORzh3QUdibFZWaTVRSjBsNE9JRmNKdjR5emY1aXdNR1ZNSzIvVXNlNDNzQjNqV09SaXZuSVU3cjdLU3VWV0FXd1ZoMzlqc3RrVzIKMWlxYm42emtUVGFmd3lhN2dFZ1NlaGwyQUhtNVRaaURNUDREOXpYWmZUWVJla1M3a00vQ0I0S0lNYktIYkZ1MDdVaUlKVmZkUjRUcgpIQ0prRzlHWTBKc2l6SUVnMWF1SUc4STE1clRZWlVKYzVJME9zdWZCOXNtYnJWVkVCOWxFNndLSjZMUS9UbllXTEE3c3JYTGZQTXY5ClgrMkllRi9zeFBLZWVVbWNScGcxVVhoY1FKZmI1K2ZleDZYR1hrZjJlT1FvNlkwNHdXNmxWemxSUmxpMHYwTnJwcUJybDdYZnl3bDYKbVQxUXIrV1AzTm81ZWJIZFhBdUg2MjgrbWJVRlNJK3laVUx3a0wxZkYya2paaGtsR1Z4NThxdFFaYTdJc0ZYTVlQQVNVVlJySXlpUApFc2xZNXNCUVMzcHhGY21vdCtNRXU1dGU1c1J5QlFYODBOc1JrVG5MOFBlN0dVRXY4MmRxdGZ5cFd6c243OVo2VDNVcjl0NG5yOVVnClV5VkQzc1dVRWE3SURvU09nRTEzbGJFUmVUTUlLeGZobFk4V1NzUktGVFlqUTRTbHUyRmg2SHlRU1FaR0s0dzNZNWFMNUhzVnNaNWsKK3ErekxJeFE0VUplWXlPd0l5RHJ6MnV2Skt1R2ZEc2w1L2RHRUkxbDRPNUdGT0ZsWFdYMUJ3aVc1T2FMWFNiU1VDM1lGSVR0T25zUAowQnVLek5sQVhzUFdSWW9xM0hXeUNyU2RFbVg2TG41bG80cEVEQ01JZDUwTjR3S1dDbmZJQWExdklsWjJDcStVSFhhck12eTluanhqCnljdkNMWS9xeTBBUmpXRUwyYTUwS2htSWFGL29yTVRueDVyTkFUckJDaTgrbmovb0lQRktXWEdKYzFqMnlCWHlqUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJak8xVldyRGJ5R3ljWlorUVVmVjlOSlRlUTNHV01STEd5dWxIaFV3K3lBVTFzRjdCcXA2dEorYXRiNXdjZll4am1JRytBcGg0aGxKUQpPQUJsa1hVZFpIdEcyQnk0Y0oyRExSLzVzS3p5Z0tLOUpqQi8yYVNrdTRUamI3UGUvM1NHbm16VDBCMDRTUU51VTB5NjZWU0loL0xXCkt6aFlVVjVBMWgyRVhTTUhTNmY0QkZuQTRZZDZVVjUvRFVOVGpXQjMxQXNiVlRvaUNUOFltaElwZEpWbE05elNLSHBsZTdSV3J6MTkKYSt2MExiMFhSRFBWM3NHTW5uTlVLUjFqV3pPWWlGTkZEeGJCZXdaRnhuL0xPMHBSTFV2SG8xR3hzbW8rREczSmVnZ1lrWDVQbytpVgo2U29LS3gvcnlTNEwrTlhRVnFQczd0bW83ZGxhVyszNVQ5K3o5WUNzRXZhTktMTFVURi90aUVEVVo2eXdwTDI4VkZYQ2crZ0dDYlBRCkNjNk1rSFdtMTFxckRtdHJweEhzYnM5dHVpa3h5UlNCbU52YWlmWkM3VzVHMFBYdHo5UnErVk43TzZmdjlyaTA5aW5tSnVpSXM1QkgKK3hMWUd4UXROeTlCSGNpQVdMcDVLU3dpZ1ltV3RUTXZRU2lWdlc5cjVpVlZHSVFMdUhrSkl1bzhMOHZPdklTMk5naHNibDRDcitUZAozTHdVYUw0UVBqR2FsOGd0d2ZQY3ZDUnZmZ1h6ZFRNdmdSRGozcm9VNHFKU25GbVh3RjFsZXcvTnVrVFdKMHJIenJwRXZpbkNZN011ClljT1FUbHVhZGFuVjZOWWxzTXhscWYycFF4UlJhS3RyTXkrRktITi8yeG1YUUNwVk9MUWJsNW9rNE9ZbHJMQ2E2cll6TDRIeDVpUjgKdXBtWFpCRnRFVlkwc3k1aFVjbnVzVE11eWRMTE0zck9iRXV5L0dYZVJqY3R5Y2UwMENqWVRVdmdCd2tIcEpobFNacElhZDNjc0NSOApXd2FxN094S0ltWXpNNTZibFRaS3lLVlpsV1Jud0p3ZGJVcmtmVnNKemFhRXJvTVE2U1lsdWZjVlhBQTdrMUtRdTNKSnVVa3B5SFROCkFDSzc5aVhjbHJOMk5Da0ZLSytsVzVTd2ZjNTFYWnBGS2RTb3MzaTBLR0dub2xqckZpVzVyMnpLOHNodVVqcGJXQ2Q3RitOdHdySXoKS1RXaVc0TXdIV29XR2RqTVJTRXk5V0FlVFVyWXJTS0VPNjhUWUxTRXVjMGJjY0pvNU9sRU13VzFadHhZMU80MW1wVGFBL1ZhL2g3ZQp6dW1MamJ4YTVLRmxaMUxxUkRNRmdTK21MVGRia2NpY0NKdmFkaFlsY0ZTRSt3eTFacjFwYjhZSmc0Mm5FODBTMU5zeFcxRy8yMkJSCmFvL1VLdmt6dDJaTzN1eHYzYUQwOGRxOUxQQll5WVhNT1BkcXBNcFNwb0d1dVJGazR3YW9WQWhCcHd2WVVNNW1PWVpLc1VScTVtbWIKNFQyUWpoWkpFWmZsWk9aSmJzVlNRN1lOZHhDWS9SL0duU3lNcEpueFJjWGdXaFIySWs4ZFF5T29CUjRDZXVtVllGa3ZJc0xYYW40RgpKMnlidHQvczd5QmlOY3dySGxJMk0rRTRHMVVFQ2lNd3hzWjFJT2pMVmRFMnVJUzlXdXU3WUNicTg5NDhNUTZVV2UyYjJBUkVDRkk3ClZLY0tVeFFaZmxFckxqMEhNWnB6QUh4eHphRlR0T2ZnaEVqcldDK3FwMkJveXlsK1R6ZGJHN1dZUzY2MUJkMkpvOWZ1NlJTOTBwK3QKMWV0djVXMmR2ZWNQSXVvMEl6L2szSFhkbHIwdkRTb0tPWGR6cHFHZWFQT2xlOU1nbSthOHVsL00zR215VTRzSWlDdmRueWJhdmV6RAo5TERaU3NDMkl2SjkzbnZVS09NbDNxRzQwTG5xM0cwK05XZ09JaGI1bWpHbkdsVGN0V0FTdVZjTjNJM1AxdHhxMkpPNmhjdjlhdGk2CkFxWjA4NnlKdkNDRG4zSjNyY0VLSUpQZGg5QThaOURHUkJ3czNia202MEJ1empYb2RXQkJXVXk0Ynl1enZZTjcyS2d5eWExR0YxdFMKMTg3T3gwYkpNeSt4T2RuZzJscmt6czNMRmloNkxIc3ZHNVZycUNITnl3YlJVM2FqT0xqWkZuU0lTUUhkenliN21MNlJPOW9DOWxFWgpyZVpxbzdraEIzZlFtYThOTDY0K0ZYZTJRVDNmSXVhM3U5dlFnZlBpN00vOWJWUnZOcnlqTzl6aW5DQmVidDNqSmt4VUpCL2JrSnJMCkxkSkZVa1AzdWZGS3ZHOXp1c0d5Mm1hUE85M1FYQzF4N1Y0MzJDbXBwRFMvbTJ4dElxaVpnYWM1M21LRVJpZzdaUE84UlhER1FLZWEKODdVdzY5emMrZDVnRXFLWTZjNDNLSmVMOVBmaGZHRSs0bjdEOTF4V3IvYlVLaHR6M0xvRERvWU12a3h6aXpYS3pnazMxRE1IMjlCVwpvOWc5ZDQ0NE1JS2E2ZnkxdHFESTBzRGI3dGtvTzEvY1VLODlmMnZyOUQzUDNIRlJ1aXBMcCszOWNUREFjTzQxNTFjTXN0R1cwRjFrClR0ZzU1SG90MjMrR2hockZicmh6eVdHRU00VGszaFRVa2hDSEd4cGg1NVBydGRxVHQ0Wk8zL0QvdDBKVVNFSE5sU0hCS0dqVEdic2gKOVRwOExkb2hkdFlaUmpxbzM5S24wR1JwYnlaRnVCOHBybWlxZzIxRnZBNGxFV0hvQzJ3dXdpbDBMc3F0MU9EbkZOV1lrbnIwZWoyNAozQ2pHZzZQa0RRelJlRmJJWUwxK3BXZzFkcVZzU0x5blhEa25tRzFnSk1WK2RQYWFKeHBRZ2o0RkcxbWUrM1k4VUlOdU5tZ0hGbWxZClliZEE1ZzRmQTh5VVRsSE5SQlpQbXRlaG5uQ2VDald2TjlVcGMyYzBuU3F2b050M2Eyc1JkaERETXR6VEtjOXRKUGxvdlpvL2ZXdnEKN0MwZmwyMCtoNThYL2h2T2daMmpGM1pjSFYvMzlNS01QOE9EMDF5OVFRUWgyQXIydmw1YWlubWx1M0hCTkhTV05Vckt3NXhxMU1YbgpsTHQ3WTNiTzZPN2VSdG01ZTNzOTkrTkdyb0EwVWxMcGs2cFRNWlI1ZFBCaUY1dXpqZEcraHg3eCtVYUl3c2pwLzJwUGhROGdydDNyCjIzWk1kOFkyd3M3ejI2dTVWN2MzMVNsMnk1MzNseHNyRmZqV0Z1UmpXdGI4bGs3WU9ZQ0hhdTNwVzFPbmIva0QrSURCcjRRdjFMMlcKMktpdUpUWnJvR3VKbUJZMHFveGFJcmlIaVBxeGFZbFFxRUlWSnVoYUlpd090QmVPV21LejQ3bVcyTXh4cmdEQ0RGM1dXSFphSW5TLwplVkFsWVNKYlpESzdrdWlmUngzUmFVMUZoSmw2aFgrdjZYNzArS1Z0M2V1SXNHS1ZCYy9XNnJXZWN4M3h2QzlQN1VpcldpeDJPbUtuCnVsNUhzd3htVmRQOThNZWFjdG5yaUxUNnBDVU85VUpWbTE5dnExRkdmVzJnbWw3WDIzTGRyOTl6MUJIN3MvVjY3YTFhVzZmdmVkbWgKL0NtbThDVWJMQVdHWnpoOVgrMnB4WlNlWlhFbjRhb2FCRmJWREptbFVkd2VUZ3ZuVUE4N09seHp2YTFHc1hzNjh6RHFabGFFMXBacwpSTUxGMXVHZVRuRmp1cmtxVzczMi9LMnQwL2Y4UWJ6TEVldVU3bG5aQ0NqZVUyb1h0V0VyaEJoRkZSeGlvaVc3ME15ZmtDb0pYTHdVCkd2NEIzZGdjMXlHVGc3NG9HTlJqVUxhcElvZDBzR2hKa1dDRkxVWjlXZHJtSE9RUTRYekVacXkyR01JZXNPQ2djbUVxUURMVkxvZkcKMkd4TndLbHNVUkU0OHJLSnV2NmFpbDVadG5XaGQ1V0dYdlNyZEpiTmFhajRDVzhsKzc3cTNmQjBWVkxnaUlZT3Z4VzFHMEtJRXYzUQp0RHRSNFdUVENIUitLNEIycHZ6SHpVOEJ1Q0ttdzl3T0tTeTRnaEhBVm1HdkZxV2JMNENkcDlMbHVHSVJWY1Y5cmh0VTJES3JmcXhhCnN6UnJHbXlBd2hjelR5YUhaNHNXY05qVFJPcE1ORHFrNUpwdnB1MS80V05WSGNsRk1RSVVDbFdIUEowREo1cGRYQlUvZ2l1V3NoaTgKdVZQZGJJQlpRME92OUVrQnNKN2FxYnJpamFKekpDa2VaNmdubTJLb2VXeXJVZXllZW1XakpvTy85cmFpYnBYRFBXUGZQSWRuYS9YYQo4N2UyVHQvekI1RUNZM1pBd0Z5NkZOaW84S3BUR1Y2Q3dlTjhDV0tZU01oWGN6UVhCeVpVWFdGbmhTMWxVUnk5eW9Telh3ZDFrZjVBClVkcWFOQVpoczFEN2dDaW81Z2JYUHFDR3VHNGNYVG5vRWlCOEw1aW92VjdaSENxNDZSMDRLeFc2c0kwU1lEbWhnaE5xWDhpc1ZIbTEKVVdUWk5BbXdVMHR5R1pPK00vaWRrVnNtY3RvckRyR09Jbkl4R0FxTWZmcXdxeitzL0tHM3JMTzlwbE9jTjVRZFZlMkYyQ0ZnTHd5MAp3SGxiMjZBOWdmdndZU0crNjJ0dU5paUFYT2lnekI0RElHd2orVDA1ditlbHFqMUlybEsrcXlKK3RQVUxOcHBpcG9tUUJrMi9VdGxJCkVjMGNGclE1V25lczJhMHIyYlhCMlBWUzJxd1dDQVR3OE5MRUhseHJCRHVsUVFES3JzNkQ4V0VYUXdOU2g2UTFyczNzYUZQMGZLNmYKc0JaTVNRRFo4REkwbmIzYVUyVnJxWXVhUE5hbDZsZ3RzRGxpYzlDdWQ0b3VCK25vQXQ3WjZ4WDFwUTV0TlVvYXpIV2RtbkhVVlRnTQpiY0VxQkl4OHY2ZFI5TXIyYksxZWUvN1cxdWw3Tm9lYlRGdDZ0ekRmdVZXOTJsTTNOV01DckVLM0dPd0htWjZNRldoSTRsMk1va2lICm9OaWRvWjZzMTVoM2JUV0szZE92TkdveEMxZHJDLzVTbURyN1BaMmlWL3F6OVhydCtWdGJwKy9aZWtBR1pzdllja1g1SXl6eDFZNksKcmJuUVhEKzd2UVFqeWIyd0VnSFJDTDdpWjdyL2U3VUZ5ZWJTMEZTaitDMzF5a2FGK0VPZm9iY0ZLRVVKL1k3MldSbUZQNWRYNmkvawo3Wnk5b3I4ODdLMlZxQytndXBNNVhBZnFBdWxYb1hvaVRLcWpnWkkxektLeHB0SXB5bnRnMG9DSjNLa0VkZkd4dksyQll2ZlVLeHMxCm1tRFgyNElmQUs2SGZrK2pQTGVudFdkcjlkcnpXMXZuNzlsNklNRzlHeFhQSklxTCtjOGFGZlkxQ09IZ2hETm1uaXczaW1vQS82WjUKQzUzeTNNUVN1dmlIZW9CQndEdlltbW9VdjZXTENFWTFxMFZ2UzFnbjBKVDlsa1pRRjRFOW1GZnFMK1R0bkwzaUQ2RFBOd3d6ZGdwNgp2SGFnYm14VkszT0pPcW9iVzlDYTRTaHlXRGRNRXFtNi9kMkIzUkQwMWF2Z3lHN2dzRFBzYkEzYUhVVVV5RnNOYlFnQUZZS2tDZG5JCnNkM29LSFZvT3JnYk5WTjJINDJCdTJrR1dkYWxvN3NwNUFCMjB1RGQ0S2RwTzRGMzQ4MElXR3I0YnRqRjdFYW5uWE82RHhrUUduOVEKLzlwQnZLSERKRlZkREZMTm5Sclkwb2E4YnBUbjN1M2c5ME05dzNBUGJUbkY3K2xxa0ZHcjltSnJTdTVFSDJpL3BWTmNFdFJINi9YYQpTM2xUcDI5NVdUMy9ISGh2ZXIyaW96MDdWVkVhRFZ5Tk9TV1RaK3NZN0VaUmM0VkJ0WWQ2aHVidVRUV0MzVkV2YkZUWnhWZkNhbHRUCnhlekEvWlpsTUJmM1IydjEydE8zdGs3ZnNuRXptRzdoN0lQYUxwekNzQmVOS2dKVW5nTWlBa1hJS21ycEMrWkRuR2NQL3dpMnNjSm0KVzVaMUhlcWwyWUNhcmFWRzhUczZVMUlxVEd4QWVmVzJNS0dXYmJ5blUxU3MweWRydGRxenQ1Yk8zdkVITVUwMFdESFdFS0hVSS9TZApzaGhOaG81OXgwTEppVjR1QTc5RHgra2hrSTUrcHljUExLREIzeUhuYkNYR2puOXZGQlZ2RkFEZnF6bTJIY0syMmNDZHNvVlIzekVxCmVTbms0UWFDcDlDbzZvaWg0TUZDbTJ6ZFlQQndscXNLNGZCMjlENGx5RTVaWVdEd0t4dFZwSms1MHFkaE1IamdlK2ltYnpENFJsSHgKeDJEd3ZaN0QyMk14cEVHbnVObkJCU2VqaGl1Q2doMEZIK25tQVVUQVVmQkE1cXp0WVIwRkR6ZUUyc2tjQlEvM1FpcHI3aWg0NkJKZAorWEFVUE56c2hFODBGRHgxamhSVHg4R2o5YVo4TkJ3OFVBZTB0emdNSGlOQXZ0cHc4TmhJa0RqSEJDUUR3a01SWCtzQWhNZEd4V2M0Cm43SW5kbUJIaVdNUUE0SXBYdTJwb29MaDZPS0dPT2M3YndNVzNnaytTWWhmNzdVTTRqNDAxQ2gyUTcyd1VWMnhhMDBCT0JWSDlIMmoKNkpYK1lMMWVlL2pXMXVsTE5rbmZJZUtBZVMzQkF4MGR2dDZvRGVLTzJVOW55VURKUThoSHA4SndCY2RmYnd1Q05tRS83WjVHMFNzTgp2ajdVTTRqNzBGYWo3TzdacU8zWldsdnQrVS9mcy9XQXc4VXhkOHJpMXV0T0ZSWkdJSXdEejBXQXZab0pyM1o4ZXFNNGF5S012ZGR6CnBIdHZxMVBzbnMrbkFSRlAzWVNHbE43V2JHL1c3MmtVWGUzdDJWcTk5dnplMXRsN1BpN3hmZzVjL0E0czVzRDRoaFZyeVBpR0ZXdlEKK0IxV3JHSGpHMWFzZ2VNYlZxejV3M1pZc1FhUGIxaXhobzl2V0xFR2tOOWh4UnBDdm1IRkdrUytZY1VjSTcrRGlqV1FmSU9LTlpoOApnNG8xLzlvT0t0Wmc4QTBxMXBEeURTclc2NHhRc2VhZWE2L1E0UElOSzlidzhnTlNyQUhtRzFLc0krWWRLOVlnOHlOV3JFSG1HMWJNCklmTU5LdFl3OHlOU3JJSG1IU2ptcVBtR0UzUGMvQTRuNXNENUJoTno1SHhEaVRsMmZnY1NjL0I4dzRnNWVyNUJ4QT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJREQ2L0E0ZzEvSHdEaURtQXZ1SERHb0oreEljMUJIM0RoelVJZlhkak80aCtodzl6RkgyRGh6VVlmWU9ITlJ6OURoN1dnUFFOSHRhUQo5QTBmZHI0V1QzMmdCam5mNGNNR3FtRzZHbmk5NGI0YXhuMkhEMnRRK0Y3UDBmSzlyVTRac0ZvRDFUQmRyYTJHKzJyMzNPSEQyck1OCjlkcnplMXRuN3preWYzcVNkdml3Z1dxd0xvZXlPL0NyNGQxSGVGaER4ZmRhaHBzZjJtbVVBYTAxVUEzVjFac3k0RmUvNFFBUGEwL1YKS3JYbmJ1MmN2dDhsOWJKN0VtRnVFeFpoOXA1R2hTV2hxSlNWeVZBS29qZk0rbElEVjZOUlZQMTNMdC9yQ1pkS1N4amJhaFM3WnpNYwpLRlZXRkZqNTBKWnQrY005QnlGZ2VEYXYxNS9mMnpwN3o3WWVQa1hCUGtuWlJLMHVMV3FjS1ZqeHIvYlVvRkUyc01VVUlDWXhXSE5TCllaZTdmYU80RWNhVXFWWXZHTkNsTjlVb2Rzdm5ackF6YXRKZzFhR3RqTDA5ai9jMGlsN3BqOWFxdGFkdlRaMitaZS9MajljdjRRbWMKaStvY0lqT2FOTnFwc0cweGVRV1E1dGloQVRDbjRKOW5VeVdkb3BxWEorcG85UmhTbDllaHJVNnhleXBIZCtvMksvUzN0eVdVc29IUgp0SHM2UmUvcHo5YnIrZlAzdGs3ZnN6R2twWnFrZ1kwSEMrWFZub3JlTmZUWmxyT2xEZ0dDT2VnNVNGdW42SHNBRDFQaldFOTJHaHBNCmUxdU5ZdmYwUGExUjYwb0luN2NGQzFvZDdxaWY5U3AvTHE4enZJKzFjdnFHbjJVUmh0TkZLQktZK3RDU2dvdGU3YWtBUlVIZGh0MlUKbnRNbFdPS0poSEF3V0NxZDB0YlNHdU5ZVHg0Z09pQkQyMm9VdTZlYmZScFZrMlMxcGhiR3Z3eDNWSUl2ZTNzd3J6VzhrYlp6K29xOQpJejlCZ0QvaFpxcStNUXJUUWhkZjdhbUFuQ1dOYjlaWWRCbldBbTgrbFhNSzRFNVJaVzFXQ0VhclZoMy8ycHJxRkx1bE8zK05LbnBWCm9KempUY0hNYWlLQTNkRW96MDNGdFNkcjlkclR0NlpPMy9JSG1aU3drTUJQTEtJL3NqS2FZOG1KaSs1UzhQSFVMWVVEbElpcU9oTTUKclgzV2R4SlpyOGo5V3AxVlhUaTlFU2ZZclZ3NVY2SXM1SVZPY0crbWFMaEV2MWNaSXJYYkF4VVBxdkJIdG5iT1hxeTdVcVBxd0JzQwpXdHlQMklqU1cvT3F6czhVNVRFMlROaWtEbFdxc1U1UXhycXBBdHRxQVk1UVZRUFFkaHJCN3FhWE9SR1RBeXlwdFlQMXMyM0QzWXpnCnJsZDlwbGJMbjlyYk9YMjNIMkw1Y1p1RnlBSjFnMTZqVjNzcTVMdlZRbVVpSEVGUVZPYW8wb1JtUm5PSzg3RTFwVFRXdzl0dmVXeXIKVWV5ZXpzZU1XaFRTUGJSVlRhem85Nnc5c2Nid2JLMWVlLzdXMXVsN2ZnNXg0cVF2WTFZak5PVnRHRWRmN2Fnd3RzQWpEQVZ0aWJPYQp6U2hmUnpldkdFRUZUcmpRbG0yb05hdTNiR2pJS1g1RHZiQlJJOS9rMEp1aUhTZlY0WTVPMFN2OXdYcTk5a3F0cmRPWC9DRmtYRERPCjFSTEdCTWVJZEdJMFVBT2N0VVFMdG5nMm9GRFcxQW1xd3FVclpPa2ZxMkdOTWF0SGE2cFI3STZ1L0JrVnJoRmlIRnRiU0Y0YTZuQkwKSStpRjdjbGFOWC80MXRMSkszNytDVWtiekd6eDFMSkFISVBjcURBMlpaVzNwQTIxQjJyd0hqeVdXMW83UmQrSytYTzNzZDVNODhYUQpsQlBzam43ZDdCTnlKZ3JVR3hLS2FORExjRU9uZVAvcmcvVjY3ZUZiVzZjditYbTJWaUI3a29hK01pengxWTVZUFNuQmF1WkR4dm9zCmFzOUZzdjVPVWVGaThVeDhyWjVJV1VncU5MVFZLSFpMdDhNb1ZmcU11ZFI2VzNIV3dKOStUNmM4dDRmVlordjE3UEY3VXljdjZWMzMKMmNLNkhnL1grbHcrUTBBamsxbDhHNW9ad0s4RnE4N0J6UEtpY3dIT3g3SE1BR1Zsc0xvUnlsd1JlMUZ6UnpJWEdyaFNCeklYakViYQp3NWhsN29zUUVEdUtHZWtiS3h3TURtSmVrWU9CcU9ZQnc0eXdyUlhENHhCbUdFcm5VanVDR1U2SVV0SWV3QXl6OCt6SUp1YmpKVVF4CmRmaHlKZ0I5RDE2V204MGNhY2N1TXp3eXJoMjd2QUl3UU4yM1k1Y0xBVnhMaHk2WFRkWXRzY3lHWEthSVRPUGdBRnlHQ1hjcnk5cVIKeTRHUVF6cFV6WWxJcE15NmJYdnNNdEF5RWJab2h5NURGbHRTQnk2ZmpmYmU0bGhoZEFZYkdtSExuV2dXYk9SZDVDZzZHQmtoM2FtRQpQV2E1d0Erd2JwMVk1TmtxRkZadnB4TUc4SEFuR3NhNHQyTXc1SDYzQWEzY244bHJ0YWUyZHM3ZTdYSC95aWVoT2VJZXBReUNBNVFoCnpqZHdjczA3V0hKaHJFaHFxR1RoejhpQzB6REp6Q01UOTRoaytEK0M1ZGtqSUJtaWN3Y1pZMmFqaVJHS0xPdDNnOTI3RVJOU3hBMzQKWWdRZG5XQ1EwMGlaTy9CNDNpT081dzQxQmc2NFlzY3lwSEdFL25HQ000WUMzVEhHMFI3RGtjTkltclN1ZTN6eHdpeDFuWWFFNmRHdwpwUVFYTDliSUNDMDJkQU0vWiszVEJpa0daSUJaT3djM09lWmZ5VXZIRTFkN0VrY1RZeDdOS2V6QnhLWGF3allzTWZwbFJCSXozK3k2Cnh4RUxDOGtobEE0amhqRjRYVHVJdUJZYnYrSHhBZ1BiNGJweUNERm5uS09IZDlOdnY3YkJjaFp6ZmpYY2NDY2ExSmM1aG9BUmNqUXcKbVBFcFpoaHpjNmtEc1FBSEgwSnZwaE1HOEc0bkdzYTN0Mk13NEhhekFTemNuOGlJL1ptdG1iTTM4eGVIQlMzbnZBY0tkNkpqZTJtWgpIdEMvQU9LWEU0eXdDSnNsYkNORVdIYlJkV3lsRVhZQVlTYzZwdGZiYWJCZnU5a09IR3dQNUxUK3hOYksyWHY1Q3lkRy9BNGczVmNqCjBiRzhXRnRrR3c3M1RjamFXOVk5S2hoV3IxQ0hTdGloNktiMFpwd3dJblE3MFlDODNvd2hmZHV0Qmpod2V4NnYwOTdDMnpoOUxYOWYKNUdJSzg3YUhBbmVpb1hmUmoyR0UvV2JHSGc2SVgyN3h3UHBUWC9SYWNFMVNxL1IyR21FQTVIYWk0WFo3T3didDdYY2JFTUQ5bWJ4VwplMnB2NS9UZC9LVmg1c25NOXptZ2Z4dlJFYnV5T0xiRVBEWUc2b1hwcWRCelBXQi9oWmt0c1F4RXVEZDVpbmhyeHdrakVMY1REYS9iCjJqRkViN3ZaZ1BwdFQrUjEybnQ0STZjdmRza1pCcWQzWk9ENUNCZnNWQWY1SWE0MExCNGFEQ0NnN0w0NHIydVBGNFRmT1pUWWlSWHAKbGJjQmQ5Z0lJM1N2RVIzaDE5cHhFR0M3MjRnVTdBL2wxUDdnM3RMNUMzNTJyZUtqazBVODhnVEw0V2UvZVAzdXdpRWorUFhzZHk4Zgo5RUYrK2ViNVYvL3o0Yy9hZHA0UFAvdjF3N05MUjVQY3ZuajExWmNQYjU4L3ZINDMxSC9zSGwrK2ZmamppNGMvZmZYck4zLzYxbDR2Cndac2t1dTFqTitDWkovLzk0Y1h2Ly9EdTBRN3hxbSsrK1VvNjh2N3RtOWZmVy9lWEQvLys3c21WOFpMU0t5OGV2djJBZDd4NTg5TGYKVWNPNzF2ZS80Nys4K1ByZEh5Nk81WjJla1hQMyttdTc3dUtaT2YvanhSOGZmanJwTCtwWHE4N1BsVEhmVURLMnFxanBXRU9hTHA2WApvd2pwRHpzMngyN2xEVGVNMHU1MlBQZW1VZHRqL2JKZmY0bTJ1L292Y1dvT1RjbXlJOHc0ZGpndU9HVUtta1VOY2RZemlhT2ZTYnpzCmtxbGt6ZFdMVklDTFp3RUhFZUlsc25jamxTVUlBUUVKY0tHck9nNEwvMXlWNEJpa2hmaHMwR0tsSlhXMnRpdHlWS2s5Q2tkYmdkZEIKcGJtWjFNQWVxZHdGUUJJWHVoY1RzamdWWkdHQVVpL2Jjb0g1SElMdzRyWXFwTUFBbEF6RXpZNUFJQ1JMQ01haGhZQWRUd2hFQ3JYTApBSHhFcHJHY0ZiMVVlQUJLTW0wUFFnQ1F5U1NrMk41TTA3d25XSzREUmFRUTRERkJSbFB1blRRZndpa2dleXBmVFBiakxVY2lsVGErClBXQ1kwSjQycGtaTlNtREdOeWhmaXdNZ1IrcXlCcjB3TFp0U01zY2pCOHVSTmRQZzFxL01sWHRTbE02aER1ckNPK3BsQzhqU2pOSm8KZlZsdDVKQWZIRkVIT1BNcGE1Z3dqVjNJTmJGcURpOHEvOGh4c2phaEUvRVFWQVNRMVduVkJLR3NGdVlrMG1wV1ZQVUt4QzhzQ3lVNQprSDlkN2ZRSmhycXV3YXlyVEdFd3cvR21ZZGg2bGdid0RzSFRicTRPZ0E2dW5hL29DcWJXZzN1bExrWlpsQUl2Uzd0eW9TMDA0RkN4CnhZelB6QlNNL0ZrODFCNzNaR1FXS05HTkhaQ1VWdGVKbzQwMkE5QkpLQ3JMemV5S3dQTVhITThUVEVhUVd5NDBCcFZWVlM1MHh4S3AKeUsyVy8ydzJXeGpuRGhDTUplbjRwbG8xbzF4ZE1LUXp6RVVLSzAzSmp2TGdZS3N4RWI2NVJlT25Tb1FVeE1Tc20wbzdoY3V5MnRJaApaZldIQlZUT3JzdXNvMWthMFhyT0NtNWxQQVVvbEVuMEtoaUNZRUxDaUZkRE9Hb3l3aG51T0xpenEybTBHeXpwVXZmR0wxeEVLOTJZCktGNFJlbWxHbnBJTmpuVUZqeEUxaUNqL1pmV0FOc2o5U0hFQ3d4YVJkck9HMUFCd1hLTTZKWm44aExoQ2d4V1F5T1M1Z0JSR2JSdlQKa29BNGpkaWJvZUx4OCtJdWF2aUFnV09Vc1Nyb1NuajRrSWR1WTlwVVRWT29pVHZ4aFkwZHN3MGtwQkNHUGNwRGxMQzRLck56V0xCSwpLcFZLc1Bja2lVaGJCUU5mWkVqUXFtSVpMRExNSXh5Z3BraUhnckNHSHM1RUhBS0lTTElubnd1ODUyaUd3RU1RbHFSWmZaMVRhSEJNCkptZE9jektJUGhLelZXWVZEblFKVjdQa2dRUG9teVZDRUtEK3pveFhxMW9IVm9scUFMUWxiVkN2UXpJWEMybEFrWlpaRnhrSU5HTEQKdkxJQmpENzdVVlpDV0wwN1pvVFV5N2NnSnJ0TWRJRmx1S3hxaGc1ditMbDF2bXpWdEFnSERDUkdkczB5VVdEZUsxa0JDclRzbDAyVgpQWDJ6b0hjcmlGaUpodXFFcmdCblJad1YwWmxnZlFNY2YvYjhqQ0RTbWdHZ0g4NGdtMjN2RW9Md1REWDVzQjBRaHF1WXZYS0ZsMVF0ClFGUkRVQ2RWaS9xck9HNEx1NDIvR0x6TWtYMnJRTmd0Z2FGdVBHbGkwZkJsT3VIaGNGa2RoRlJ3N2dOdUJUZ09RL0ZocXlzOENhdFoKaUFQU0M4SlEyeGdYaUZIbTRySnFYOU9PSFBWNE9OSFJpMEduTnhKd2NHWmo2d1ZyRVVUYVZ0ZFY4MG5pc2hLTXdMdXRnRXZIeGw4MwpwTENVM3l1Vk9SaXB6Wklyb29vNllXS0JwU3JUa0VZR2doRkdzdUNLclhkVHY2MXM5eHpZVEIvQ3V1cThLZ3c2eXJZckY1czE0WXBKCmgyREh0ZVdoVytZaTAzTUxIRUx1MHJyL2J6QVlaUjBpeS9QRzhFV01ZU0U4QjViN2xXTVdRdW9DRWF6dm9JR0Q4Zk9zSXkyclQwRlEKekdzaGhGUWNrdDJhUWk3MHF2anBLdXVObVVyMWtUZlIrZkFLb3RzdCtsN1Nvem8vbUNtNDBMcTNJR0VpWEhMWUVDRENWYVo4WHRlVwpBMTYyTFRoYVlSU2UxYVBCWEZFRjdHSFZKQzA3NlhCdjZxTUVBTVJUZ0tYYmo0OVlORFl2RW1uS25UMXVBQTBIWktQWHdHbHVHWkg1Cm9HT1RKVFFrV0hnbHVEWUpnTVVqYVJLRkpSQVlFeHZBbFQxVUFpbytUWExZREt0NktXWWVMb1VVNWJySmg1bmF1QktlbXpDZnNNQmEKTGFUY1o1TE5ESjViTlVFZ2pLNUpYanpZbHNVMWcyaXRUUmMzd2QwTWg4VldZNEg5QkxkRktFMk82Vjh0a3hBeXFabllNVmZHUHJYUApnY0Y3aTVxblhGclJTRkhJUlVWcmFXd3F6MmhSdVNjdWpHMFJucHNkZExocUFpZ0UvWWFzdWhORlJ6cXY0dkFaWndPRTNDUlZTRm9MCnBNdW81ajZjTTR2TS95SzRhbFRhd25QL3pLeWdqNWhvZ29hbExVZXpWaUVWS2dpMFdVQk13bGpncXRsVDB5UEFEU2RVTWRlTkdibDQKWHVFQ3pxblpGTWo4MHFMN29MNVhWYjh5WmpuTldSbHhYWW5aNFkyelJIV2VZaDNYMGlXM2pkdXNlbVR3RVNPQlBLRTBsNjRRZXlzMwpTM29yL0NJKzlycjVlMFFlZW9iUGVWVmNRMFpPTFJEbUpuc1huVkxJeDB1K2duRVNNUVpwK210U3ZxSkhCVmExVHQrWXhCN1FaNWxLCmtPSlhaMGhQMENMSnhCYUQ3Qyt5V2tTRHM4dG1qZFNqWXBBTVRJbUZpOUN3T0d0V1gxMzlRZTJnejkxZWdhZ0VFQXR0VDFWRGQwSEkKbVBZSlRrcnNscGl6S2JUTFpvQlRzZlhRYmdZQ1lPV0tWOWU0a0FCeHRjejZic3JHZ3ZYMnFqckVzbWlpWlRoVTY2cm52N0dMc1BpMgo1SHpNd1ByY0hDT2RRTVVlVWZSTnkxYVhjZnFnRVhndldjZ2JRazViTGNTWFluOGk5d0dEb0swUHZwbEJMT1FwUE1KSVpXaTRPTUFPCnNKMHYyYlk5NW9TS1BPMGl1V1FDWW9GUEdjU0VaR3VJZ2VlYVFseGtVQUpqN3hHSFZ1YlNMbU5LdkdXeGtRVUIxZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJSS9aTDBDUjNqRGNGb1hvd1FWQ1pLek4zY3FZQmxUb0ZHUVJkM0ZGUHZnRXZoaExHWGhUWkVaN0ZqRk9HWm0yNkFNbTlVTnRWbTU5TQpQdDNRRzF1TWxmY0NqVXNST1JXd1BFQ29ub2t5ckhtL2ZZT0ljUVlNZUU3WmFnVVNSSWpRM0d3SURNYm42cjJJL0FMZ1o1aTUwQ2d4CnJzd2dMWE9hOGtzbklDallkOVJHcktiK01TNEFtK1ZNK1JkQld5cUI2V2Vkd0NZcXRUcW1vbENKWnk0eUovRG9Fdy8vTWlMc0VWQkkKTkZ1cE5MMUFyV01DZVp1S0N5QldwUjlic2lFMWh4RFZheWdxWVZseFVDM0VIR0JMSVRhRHdhQS9NQmp1VVpkbkJFMGtaOVhxOUlqWgpZajZZdWRxeE9BVWRWOXBWaEFtZ3FaeFVYU051QW9NUnF4RVFOdzM1cmpFcjVHaUFNQXVuN0x3YXdoWkhDU1RxUlNvSmtETXdwV1N5CldSWEJ1bVprdmI2YWJWWWg3MnMwaVJ6TGlWeUlsaGUvRjlZWTVBRllYbGEzUkZma1NDNG1nczZXa0JLWGJRNjhuemROWEFoaXBHSzYKRWIrRjlPTWJkRzljQlFzTXdzLzZhZ25ndGppMDFLM2kwSldnVFNKbjM2cjRMazFzdG5ZNUhrTk5TRklzTHBjRmxRcHhIRTNRcEtYYwpiSG5hVURJdWpEZzNhS3pZYklzbHVTTjZPTklVcFI3eEJkQU9rVm0yWlppTkdrT0VPSExXNFZnQUNMMmdWM0VSeEdHaytVN05ONTRVClRFQXBLbW5lTHoweU9xaWV4MG5PZk9LQnpFeFo4T3laQ01BanpGdkc5TzhJbWl1YTlhYXN1clBQalhzNEVkbGc2NktJLzFVVHB0dVEKTVJ5VG92b1ZqcXR2REorVENLR0lxMlZaMWJ5TnhUZ2xDSHFBbEdwVmZobWxmYzJkWWZsZ0dlcGZiTVBGM3Nma1RnV1NrMGNZVURLRApxVUoySnd0ZzVBR1ZjR3U2U0w0aStBOWhqMUQ5Zk92VWVBK2tmY3FLdEZGZEI5YkNUZkc4ekE3dkJGZHRhTG5zdFRZMWRjR1dvaDViCkl5REdLM3RZWHlQQ0pKbzFsYURzTUh4SW5Xa25JblJ6S1NOeGt5YUJTenJsTkdlN0IzU0ZsVllnaEpQektFL0MweXBQbHkvS0FaajYKczZxeXhEQjdIa3dRZzJLZWtCRlk4NmtqNHBEWitiT2RneEJydC9HQnV1YWdySDlGZjRHU0dZUWR3YkVRaDRSOG1Nd2tBTXJzUnhvdQo4RSt1eS81S1pyelhPMVM5TXVwSlRnZ0x0QVhDTy9CSUw3cXE3Q3dCUm90aDkxdXh4d0J6VEhRcldBNzJBYjVscWhhbmk0U1ZtNTQ0ClFPY2k0S0FsSVdtOGNJdEZVMWxYYllsM0JGT2gyNXh2d0JnT2c4ZVFzZ1E5OTRDSEl1SEN6WlBKQU9hQ0JVNXE1b0VKWEZuUmtvTW0KUFJkbFcycngzYlBmVWZHbXEvSjNWRXVjR1h4V0tGQUlNVTEyZWhQdEszcGxVS2xKeFlYTUNMcUVjRnV5NDhRVEJUSmtSWVY5eHR6eQpmeVl6aTJJOVlESUNSOHk4M1VoM2ptNUdWbFVhYTVGUDE4MmZpTFBUb3luQTloZkdzbTRhNlFJS2hWdUF3dFh5ek9UcmF3OTVVWE1xCnFNdHFvVEUwcGVJdDhxYXdjMEtLUUtHVzdsZFM2Z00xYjhndmlyWjRZQkl6Q0ZXTjR1UE1URHlDd1pQdDRRQ2pXVE9KeHh3dDFRNE4KM3B4anErWUYwc0FCSlBpTTdmelh0cEt3c2RCSUNHc1dQS1VCRTV6V0hNQUtvU0dGVmYwZ3o4MHNwc2Jhc0JydUI1b1JKVU9leWFmUgp4bnhXbVBCcTdOY3RtclNYWmk5V1VuQU5USFl4V3Q1SENxSlpWNExiajNSNEdZU0hidVZwa3BzeUM0TFlFSi9IblFkTFlZVWdvR2F1Cll1dUJ4d3hpR1NDUkdLTVlFTEZjR1NNY2JNV2owZGt0OXJCd01tYUduY0lnTmlna1NUZG0zWkZ4RENWRHUyYUc1dmVVaXlLQmE3MUkKT1hjek9ZcGJlc2xHNFJTR2xMNzU3Z1UvQ1RHNGNGVkE5NGw2Z2JvekNINkFrVlFHZDZWem40NXh2aWZlUGxmMVE2UjUxaXMxSC9ScwpFZzRNYXJTM1NnL1E2dGFzYkJYbmJtNDAxOEV1eUx4WUc3UFJHcUVtaG8xdnZwWm5TejZEb0JreVpiUkNDekJCWjVadGN0Rmc4N1ZOCkd6Z0YwRkpXNlFHcG9MZ1NObU13V01iVU16azJhN1ozUXdwb0pueVpaelVQWVQ0anBuSGpPWWNhU0VwbVR5U1pzemo0UWhpbEg1SHgKSzJzVXVaMGVSZTJMQkdSVVFZUitzY3d6SkJKM2dGMk5TWnV3NUMzK2ZsMDBsY3MybDZLRTBCZFR6WHBvZEt5enZoeWNGWnM1NXhqWQpnRFd6QWF4aEJoWXMxWFhORFBkUksyeWNkUVV5RGFqMUNHWmhTU3FINkpMUHFxUUJGTWk4WG9oSUxmb1p6ampHMU1OMXdwaGpQNWdLCldXZXBNU1owdzhxRVo0VFpBVHFjRnczRnA0a0JhUmFhV1RyaTNFTkNVK2VDOTRMRUNJNVF6VlRDWUppWktkZ0p1dE1oc3h6cU1GOFcKTytXYSt4a01uQ25idG9RRnpIdTUwd0tpTHhRUUVHZWVqRlBVRmtCME16OFdlRHJ3ZlV6OUlnb1loYWNNYUtML1RXWWpDTzFlUE4rQgpXWWg4ejRXcEI2dWVWbVJNdmtVejZXd01EeEk1QS9ZaWZCS0oxMC9ScVhyTVljSkprSmxWbUU4RWVTQUNSRlVRa0xkemcwSElNOUNSCldQVm9NOWdoMlF6Q2pYQW9PUUdSdUJVaXZkVWg1RGZEdDVHckpSWm02ZHJVMUVaemZxSTh3M3hBVzlJS0t2WlVOWDhqeWV2TXpNeVIKbS9oV1RRb2lSSGlqMHltN21RVEVpc1RNSUdZNFI3SmxLTjQyOVJZUkMwQm5hSEY5bGpTNCsrRkI1VjZCcHBtdWVtYWMya2JLdXRveAp2OElJL2MyQ0JaWWhXVUtraFErdVVtRjNZRG96N2dmTk1XN21pRElIR2tTNnlMQmlSSEJ4azBIZVhjbzJ6TGNFRlFQb2NUOStkcXZ0CktKM0lYQlB3U2dwdnJLeEdHQU44cjdCQWtzQXdrVUFvUVd6WDJlbWRzeHBwMlJLVFo0S1hzV3R3UjBaSGc5THVDT3VGWmpPQmZvYVYKdmJqQVFIeDUxTnphVEpXMVZiVkNxa1NYZFlyakphbkI2Q0ZTTVpxbVd6V0ZsQjBTQUVPcU0yVjR0UFVvY0lUSll2WEFaSWpnT3owRgpCZ3VJWnMyc0NTbGxoZmZ6OGJLZSs0aHpXS3VlbmFWcHYxblBLRVhUelVXRWZiUUw5UnlVZ0FRb21GNmdLT2dxS1pEdFhLeHZBais0Cjl1SUtyMldnaUE3ZkFpQVJNUWNnTU1RZ204aUdjNC9odlZnUndPazhPNmg0QnNPYmN2WkF2Q01QbUxPTHVCMkJrTmJVcmlLMEY4UmcKMndnTXMyZ2FXamsvMDAyMWRsV0ZxUWZnUTRlUkppZjFDV3E0dzZLeUZSMXdVanZ4R0dNVFEyaC9wZWtuV01UaEJ1NjN3cDVnc29XNgpyWXhBY1FENVQ4eHJxcldRdlFGOXNVTEsxZUFqQnZjai9mcnN4a3NRMGExNVZyQXJuRUdZaW5sV095M2NJMjVnODlQc1M5U3RFYUgrCk5PaVZxT1l6cTBTM0dseE5hTFRCQkpDSkRkb0hnSm0wK0RMN3JOcW9hWFpDVkN6MkN2dXNNbzZkZU9kMW1PY0dNTTFnRVMxT2dGcm4KUGRGb21QQ1dVSUI3c09nUUZGUGdyS2NPNndUdHdFUTdkcThFWVVmZUlnRmNEeE9URTNCMFc5NWFyeXNOTzNyUndDa0NTUUgyaVlxcwpwLzF4MlpxSEV6U3VidEN5T2NxWjBCUnVNNGJLZ0lBdXhqay84M0RaU2xWOE01c1Aya0ZjTmpZakluZVJ2MkhUeTdxaHVTN3FoUWVSCmJqYmtDZ3c4djdxc2tBMEw3Qmx3Y0ppcmdvWUFnSklnSVM5dUNnR2hiZ3pVS2ZRNEZRckF0TEtYNHNlcEZNcS9CejBpYzJVbDJveHoKTk1CeHNmTVFRU2d0Z2Q5bWJ0ZG8vc095cVdPTkcxTFFaeVFPQkpmTjN2bEZoWWtGY0I0SWdpMkR5YXFpSHQ2VVo5WnVDbjI1c1htNApZRElnQkZMdk5Xc3dRSXFLU0NOaFU0UDE3R0FIbU80aFZnTHZ0M3JVSVNBUnpEdFFOR2ROVXV0MDNQcEY5TXZDOGgxV0RTK2krNTFKCnZQU2pNR28yMm4xMnF5WVRTY21zUy9CSkUrbXp3UE5UdEU4NXl0QlQzZnNHNkF6U1E5RTl0Rm82R2pBcytvOFd2WnM4S1M3YjZPL3gKUjZSZ0E4OW1XdFc1UE5QS0xmMnRjQ0VMa3NRRWIyZHhnd2cyZ2ZTSmpBb0FBYUtvaHNJc1l6dVp5cUhlemR5WWNQSGxUYk4yMGVzego5K1UvR3dCbVZpdEh2dEtWeDM3RDZXK0VhU0VuTURkcEkraTZCNTlrRWtlcnRSWFZ3WkRES2xkTm9FbVZTWGFaa2p5b2tVSTNUS2ZxCkdlTm54TWtqdjFvRkQ5elV4OEF0MXAzUVc5S3NJTEJPWmp1NmsyWitaREtqcTJxemc5WVQ1WDduWnpBMzg2MW1ndmRVOHcwOGtKdUcKNUVhQXM2WDBJenVVdGhsUWtEcFE1Und1SmVpT1VQUkFTZ1dBNno2Q2ljMHNpNHI0aHBiSGhSNGRmb0dVdlp2R1E5RGE1OG9KMVF3egprT0d6bmtRQ1FZS1cyRVY5bExocWJrbEtrUU5uMDZZb3NEQXpHNjhpdStmbnhPUndNbnRyVDIzS1BRQkdGRFVxV040eDV2VW94VUJGCkdXZjZJWjR2dHplclNMR0pFS2pWY3FwU2g0SG1VSG5HQzRGbTdLRE5UNXhnSmhYVVRyb0I4cEFxb0tXaTZVdUVJa0UxNUJIcUxvSEMKOXFnbitITFdzQlk1SWV3akJDeEZneHZDWlQwbnZ4dmkxakxqTThpY296bWRSR2FqL2ZCTW9ybVpIazJ0TFdNYXFpWkt3RkhwczhhVAp0ampTTmNMSndUT2xrRFBCUXRGbE05N25TQ2dha2djWDMyeEhncE5JcitOcUdDWGE4UUpycmVDOHRNL1Y5dEcxUENKMEFJTmNGOHQ4CnpLWVRBNGMwYThKR1R5RVd1cW12UWRWK2VHY1g1cXd5SFJQUldKVFFreDI1dFl5R1Vod3FzNUMyQXFqQnBFdXpFc3lBYU9rSGw5RisKdUtpVkJpbUI0ZDlrMC9EWmd4QldKWkEza0ZDN0RaQmdNTFJOTUZiUTdIVTB6VUs4aHBjSmJoK1lwOXQ3bWN3Sk9TRkZtM3FLalNESQpBRE9CZkFsNnJyUENrWWo5Z3A5aGVPZnhZOFh5SlBESTVFMFhsRisxQXRVVHpTb1RtZTBOWjdwdUNvUWdBYndDUnNoNWRURjBNOXhECjBPVkExQnNNamN4RVVUVGRGblVvV1hmQjhRR3doOUUyU0tzbHN3QXVXZ3ZaekxkcVdTaVlNSFV3aUFLL1JkZExNcUVjK3RhcURodGQKQ0xObWN5SjJaZW5tSG1ZbjRacGNOTHRYMVJNN2RlR3pCdmhRNUVSZisyV0V6OHdHaXd4bVZFWDNMWXZkRFh3WWhPUWFGeTJDUERwRwp6WDlNdU16emUwSFE3QjF4b2ZCOTFYWUtzSjJDUXl2QkpyRHhRdEtrS29xd1NhSk9ZR1RpUTIvcXpPUldodWhpV00wd0pMQlRBUVBLCnpJTVJjRXZJSjBoblNWQlE2c1kyRU1uazBJOUVCZ0Y4dUhLR3lZNjhhZ2o5eWxSdnlPYmJRL1RwZjRocW1XQ1lQVStjVFlvSUpTRXgKcmJaMnRGOUZOekVHRml1YWFUY1pseG9Ndm9JRFkyQW5nU2RzZFZrS2x3VXlhd1VJSTgwbkRJdUlOaU40cDVobEQrdHh6aDExTjhOTQp4VVc2YXBZRldnMnh0TG1kTVN0Q1prUWNoWmwyR2JZemdLNW1WVlVJU2t6R1pFQ2dGNUlFOTB6aEZIakloUERZRWhCUVljZVR3Uk8rCkpsdUdKVU1HeW1IV2RjWVg0em5TOEYxbU5RTEJMMWF4Z3VEdGhyY2RmakVDeW9CVkMzNVVLb2haRVczcTBZUDNEQ1lwd2lJWHZZeG0KQ2RTQWdPeVhFUkVBWXJXazNCVG0xbVIrTVJBZzZSTTQ2VEpwUmhiQVRLNUxwQmloWS9BWE1TYzFVLzh0RGFIQVphN3ZWdFVwQXcyRgorb0NpNnhaRzNCUGdCSWdQdkMvQWUzZWNWcVRXc0FZREpPUHp4cytLZWxrdERuY05LcmZxUlVsZEpraEFIaFlGUFJGK1BGNG1mQ3BxCnV3M3l1REo0WDFURmpNZDJRVDlIUTNtVW9odHVKdGR5alNYb3ZmSmlBYjFBWmNKQUNLOGdnN2JYVE1WNnJicDhuOXRJYzVVQkVNeGcKLzlWMkpRQ0NpWFdEUUw0cVRxbzduUEdFVldHUnE5YWhWN0hCSkVFb0NsZk9jenZTYVRZVmZjWnkzNmpWVUVLam5ZMEtTOVUwRG5sVAoyNFFLamFwVHJXWmQxRlBqWU1OY0ZWeEpOQzRVUXpDSTFOd25XWkdyWUNQMG9PRVVKZHdkekFiVEJRUTZKRUJ3dSs4TVVLVThMMmcwCktNMW1aVWN6MVE1ald2MW1henRVYmxNUElUQmZ0TmE3alI5Mkp0ZURHVFlNRnp2ZVhUa2o1bVdnOXI0UjFLMnVESTQwYlZYY1REQ3IKOHRhZDFKRDJkTTY0M1h2Vy9HUU5JUnd0WG9OQnk5bWxscWl1eDlVUVp0anRaK0JUMXVyaUgxWlg1bHhZSGNjSElrTjVRT1ErRkZOTApCWUJRSVNVczJyRGJJSHBUT0hpQlFnQU1Ld2liNWltaUZqNEZvd21PdG9lblZVM2hhNXNoS2cvVGtWczVJU0xOVGdtcG9BTEJPWTNKClVXaURHd0pFTnA1cys4cW12WjhKZjI1WHV4QjI5Wk12bURGUFJ2Mm5oNS85NXQzYkY2OS9mL2pKOFhqOS9QbDNydz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJZnYzbTNUUFUzY1ZiMlVra2tCWUllb0JWRkZhTVYwYXRqTU1Jczh0UXhiTHVoRmxSZlJRUW1DNGFsbE1INzlCVVJyd0VxSFZSUVlJWQpWNDE1TVZ3K3BWVkd0NFFXenJBcXVnOVd4SVcyZHQ2VFVUQlFDVGN6OHFuUDBTZ3FUbmhpNGw1djArbk8zQitxTkxrakNzZVpGUmNDClZ5Z2U2b3dqMjZEYVJCYzVUbFlGcTFmRDQ2Ymh1bXVLcm00Rm5jdzhNSFpXVVl5cFRFZ0lSaUVPK2VUQ1dYZE5VSW1uSVNXdmFqVzIKSUltZ2dSdWcwQVRodXBxR00xVUZEK1BwS1h6Q0dZbFo1NThCTEFkRGNUbDNnYU8rRW8ra1dYNEpxWUZITE5zNEZzWjdsS3VtOHVyWgowSlZFNHZoQXdHRGpjN0JSWllRU3JscVczSzVLd0RreTlkNmlWeEVSQUoxK0NScmZRQTY3R1hwRzN3eWFYT0JKZzBYZkxLblJvN2pOCkdad0tIQmJiVllOeEVITTFjM0VTNk1wYTVEQlJ6WG9rSUpaanRmUWxUWXJFazRPb1V4dlltc0IyVmtyamlIeUVZUXMxZkhlanNzcTkKSVN2N0FpUU9DdVpxU1VIMHNFaDFaTkVaZStQYTYycEpYbmdjdEdYVDhCaHY5WWNHNXZsTFFLZjdWVXhVd3hRUm1MMVVjVFl5cG9WRwpBUUNqd0dIV2ViQjJKME1acjdPeFJvaDlNSUtnRmtlUi9vaUV6M1gydE1TZ3dWS0YvVzJlRnp1eE0zUDdoeVdOclVBU1hvTyttRjQxClcxOW4wMFdpaFNvV0lBTWhwRU9hWm1ZT1FJeXJPWGlBVjREd3lTMTRVNTZucHVwTndmaVJhRTdZRExlT3pzZXBHNGdQYVpXd3E2NkIKNlN6VWd3dUJCT2R6QU9UdmNremtzQXZEZ1pFOTgraU9XZ3FubWU2dHlCa1BPWmZ4WmY1aUFNbERuYTIrR2lHb2NWa1ZjMFh6UEpxTgpNZml4SFYrRlREbFlSVEJTY3c4RUFSQUJuSlNRWjIxSDB3aXRxZ2k0NTVBcDlwSDlpV1lLcE1TQTFGUm1sV3pnRXl4b0J5bldaN01SCndla21NaGJXaDd5NWVzbVdxbExDRE9nYXozRkJoRUJkMUJYTm15MUpaVWpLRWxpTndDWHprUllGbkpNQWl3ekVoSWF4V2VpcUpWSGgKUUt5MU1WRUJUZHBzZU5FMENUUXQ2R1ZaK1JyVGVLSzdnV1dEL1I2eVBGMDRUaERCa0NZWnZjeUp5WFQreFVJcmNEb0U0SStSR0d6RgpSYmY0RXNDa0tKUzFXbjcrZkNHNHRnNEVoSHU2U3VuRW10VmtIK2ttbUl1NjZ6SDdmVDdDSGJINXdiQUF3aU9lRmhZOFFyRFdXZk9pClFSUmtaQmQwQnh5NFNjM09XUSs4Y0VrSFFKY3huSENyaW1VMHI5R1ZWakxIcmNXUmNMYmpmSGEweFNxeUNEaldhOVMxUU13Z3hxeHgKSzZ6d2pUN2l4VmVWMm5CbjErY2hrbURoYmJScTM5aEFpd1FWV0FuR2pJelpGUFVpWFRGTVdhamU3NmJSZ01pejl1QVM1enNnTVhwbQpSS0ZLdW93bmluUnJ0N2pxU0tXb3Npa0Nxa2xBQWhxNHlNbTlHV0hFQ2t0Ykwram5va2V0WStMQlEwZlFsdXp6Q3Y4Q0VqMVZUWlRSCjlBVU1zd0lEWjZRaldUVVRNcVZQSE15UXNwNTB4VTBYUm1wSURNcXVOc1hjYk5WV05RQmQ2bzVHREF0Nk5qSGVWTStUYUZJUXJFb0kKQnlSVnA2TzZCK21maHA1REF1RjVjRkM3dnNiVzZxcjFvb0w3cW1xK3BQQVZrMFd5a05JQmREUnlNSW5acHNjTnAyQnlEUFlWUFpJdQpyN3FqTzRZak9kRElJQnJFblFDS3p1Zms0Q1ZHRFN2ODBJSGRQS2lJMHltbzQ0UUU5YjliaEF1dkk5QW5MRDNtbkZRT0QrelZ5NnlaCjdEY2U2QUNLOXVpc0hJK1Via1FyYW9RUGxCWTJUV1ZLVHNIOEs2b0tSUFhJV1F4RWJydXBScHJEeXNaM0FxYU51RHVBQXkwcFBUTWoKTzZHWnhHZ2M5MXF6UVJZQ0FYbkxTSUZlc05VZTFtalUxZUpWTWUwQVR3bDZXSUxLdG51NSszUEs5Z1RhODBDWnFwTlprNmtGRGZXQwpqTXM0ZHFDTUNUSkk1ZzNER1M4RXppMmFhWW5xbnNaaVlZMXB2QWlQaDZGMkE5Mnk2a25yM1BxVjBmdlpGYXNleUtLeGhKckdrSjZ1Cm1ldUdXUTJoZjJuK2c5UXUybGE2ZXZ5aW9zbi92R2tsekhUaE5FbVE5Nkx6STNxbXhhQ3dMOEFlNlE5ajRDQW5qZHJQK0dhQW0xY2UKT3FOdWMvZ2hwTW1LQ1UrRXB3Rytrcmw1ZUM4R3oyMTh4Sll4a2VkSEppN3NhSGtsNExnbTB0c0RMN0s1bzhMTUdEYW1qcU1yS3FxNwpHNFNBN2tnOWFCTDNTbkR6SlpvS1VZY29wLzZFMVZLWHpXb0U0bFhZd25oRU5mUnBUWkdta2YwZVA0ZlFGM2o2Z2JOb0VTOHczK01rCmxzMWlDb0RPd01sQ1FLZlJUb1Z6WUdnMnBybkNyMW9zRlJkcy83TW12YXpBSzh5UWl2RmVPRmNjeG0rbVUyaEJiSXRCTElEbFYzOGQKOFBBdzdzSWgyK0lWT0lteFFIcHdQcWpvU2JoQWFmZml3ZVdhRjJUbFpnZEtRUmcrOG5ndUxRUU9salBJNEYvTVYzcHVBUzN1UG84UQpSQ2kzRmNHTEFwT241ZllWZ2xES3RaaVJqY2NzV1pDYWhxVERSdGloMTNva0djOEVObE1Zb3ZXWXNpSXIrb2FFaGNjTnEvSFVMeXRRCmFLRHB1Uk9abHVxd2VpNkhhcGtuTEtWb000WnhPSXZucDRqcU1RUjhudmxBc3UxUmhlZ0d0U2N1bk9zeFdrNUxxRnF3aFFFTHFPYnUKMlk1aGpZUGRyUUp3eVVOVHpUY09WSUllbGFyUVp4S2dMc2N4WWdBZS9aWEhBeUcyU0kvOFlob1JNT3hpWjN0eGprYW1wZWdISkcvMAowRzBlSG1vcFBia3QyM0ZMeUNyaS9Qakd4b3dSTEF6aENob2hTV1JKTXNNb3Zkd3crS2JZTlY3NjFBSGVCSkZCUnZTOEp6cFg2RlpVCllNQkt3emxOQ00wNldJVUpwcWpCaFMzT083bGR0bGpLQnh4cDBHZElVR050V2kzWFY0dk5UYW90YVl3a3BEQ3pwdlBkbGszUmRqeG0KZ2FHd0NMeExCTWtraTZnbHM4WmhnL1BjczRRd3BDdDU2RGxNeE5pK2s2bG1yQUhzSmhDVHBaMzNaeG1yMDZaNFl6Yk9sSEtiNWU5QQovSzRzdUxScERvaG0zNGFFbExBRlIzMHp5a0xKWEg4TUJhL3FBaUNhU2tjdHFzZVlpejdZSWR0WWFkbGkyZ0VneE5URGtxeXpNNE5WCk5UamtqV1hBeXJJcUxDUWpoUWVHWXpHdkRXcmtHdHRsQkd1RHFORTVGbFdmMVVYR3p6QkE1S0lHQ0wwS1JneGhUSm53WVEzK1ZKQ0YKNTZGWkxDOERRbEFoaXV1WVlXWEJDYUV4S2F5RXZZbEdWdXhOYWRIbG1zdGdnNGViaFdrM2k2cThJTkJRQUFMRG5rQ0F1d1VFTjRXQgpTRUVEYlRFYUdDSElzSHVDNEhkVDdGaFJDT0Z6MndtcExpNUluVkUxU2JuT3E4cmNJZ1FjZ2w4bHk3bkFxd0x6a1NzeEdWSWYxamxtCkc5cXFmUTZNblN2TmF3VWlJaFU4b0k0RVFyYUtoNFBDMVErSFZORVZySmNWVFJDQVkrMnE1ZDZtWVk1WldSbkl1ZXFaS3d3VG5vM1AKUWNUVm1MZk1OSmR4dHMwNWVWenJxdkJyQUluY2trTEJEUlp0T0ZZM2srU1NmbGF2RlQ1elVnZDF2ZmxWUEVNQ2dYcmNITkJNcGY5MgowVTlFSXlVTGlsUFJKU2lhQ0lwRlpBeFBOZ1JRdEN4QzBjS3QzQmZtUWhuVHBqQkVwMnFjVE1vODlWcGRuMFRIenJRbURqc01zQ1E0Cnd5SzZQMmkyQS9nWWx4Y3RpTUk4dW5rZXdoMXBGV1dnbGFzMW1OUHcrMVlMV1NLU0tKb2R3OStOOHBOSVlSdDBEb3BsZElRdjVxVmgKYUhaUzNnZ0Frb3BscTA3czZObU0wV0hnc1J4TGlubFp3MW9vMExmREFqYzlhaHRTTGIxL09MR1pSNlFWZW9jMVZ4Q3owUTdDRWd5ZApWVkU2QkJ4VGRNYk90aWx1aHArWjc2anF1dk9yRnJxQUZVWFB6endCemxNL25RcmduMVc2QngvR0lvZnFuS0tmUWltekN4T0pKMkN1CjZzWGtIbHV5SjdLYURZQ2FOVXVCTXZsWjVUWFk4UmloRERNZ0pPVjEwWEJvcG5MQS9zVjBVS1duckdJWUY0aVc3NEdHWHJTZG5VRGYKV3U3cURkcW1teDhlNTNtMkF3L2dMV0F1ZUNJR2c2WnhBa1RmTVNqME5xNmFGbzN2eStNR3dURmhUNG5aY3VtcXM0MmYxUUUzTjErdgpWdHFLZFlnR2srclJMN2g1VUF1ZHUrMVV4QTYybzZBV0pqRXNkRkFHQVpCSEZCZk9FbTVTQUVEMGxnRlVzNi9EKzBlRG5OVWlBUndGCnpUaWdBWjQwS2lERjlFU2U4d2VyUkxIVUtjemJpeTJtakxsVVNsV0JwdFhDOVhDU0VaaUhTZXlFdW95WEdaRjUwNkVQVk4yK2dZZGcKNHZOcTV3TTVRV1czcXRieFZtdWIxVHlNb0J0R1NEZkMzR0ZialZnOWl5OE1vd0Q4MUdUeVZiVk1HalVPSHRxYWxFTlVwcU93dE1SYQphU21ySGxUQWNPMjZFMHVUeHRIVmFNSDUxU0JCZ0NDU3JlRm1SUzlyTm13OEVyTVhnQWhJSE1PL0VFbk1rNVpYd3djQ3hGM05EY0xwCmlDUkZLMDEwbWs5bVM1cVNOVjJwYXNjUXBVcERZNE84a0lqRmh5R2lvQXdDWE5nNEFwVU1HeW4xNEJsaW5udGZubHN5ci9GR1l4OVIKamZBSTRqTnpGbTVKc1N0b3BxVlZNakVFUGg4bVRFVzJzVVJ2VmJaZGI3UDFTdHVKSS9Rd0gydFdJNUpIaWpIcUNKTzNNR0ZVVUdOVQpOU2VYM2k2bzFhWGFoczdMQU9tQUNSMTZLd2dVQWFzRlVmdGw5QzJEQ0E4c0E4cG05blZtWEdMVUdCSm1kc3ZkU1JoaDUwSW1MNDB2ClhEU1BCM1pYWmxSZ3gvSTR2RmhVbGRWWHN4UmlvS3FDczdseUJRb01qUm9ZaDBRc01GVTRPRm9mcTI1bXdLanFKbWNlQVZJcW55SXEKREpaV2phMjV3Nkx1eVNGcUh2VkV6VkVEVXV2WVRGRTNzWTY0TzFBQlFiVGM2ZlFyY1JzMElKSzZZbzJnN3hmY0JMSnE0QUFXSVBnNQp3SEFVWWJET21DSFBLY29VaWlWbWJQWGdRb0ZLUjlHSitLQ3FhaGllc3dYY0VPeTlXREN4YXRCMDlDd2FKY3lNRTd6U0k0azd2cnIyCllHSlZJOERQNkV5RnlrWWhDTW5YR0dRYjY0QzRRYlJYc0hlazEwdlY2RTJQMEtINjNTbGhpQzNveEtnNTBvdW0rWUdEbFc5RTRITDIKQ0J4WU45aXA4R1VsbW8xTlZZRXUyUklQcWdpVExYNk5kczVTTzhySHdyMFh5eEFCdlVnVE9FS3kzelRUa3NvbnRJWDYwYzY1YUZCKwpDRXUvZzZXUnROUXJyTVB6NVlDcHlFMm5ORUFGckxtYUxtdmROTW9aa1ovY2xRbWpZdUtOZVFUWEI0WDdZL2xEaitPekJxdW1xZmVECkpqWmtoN1hEeDRMQ3BCaWFSZUVhYVU0V0U3V29wREV6Z1JvUHErTGg5RXBtZFYySC9rZDRTMUdQdDY3aWJFQksrdE5kd09ZWkJId3UKYzBVeWZSVlkzYlphMU1pcGJIVHpHUVd2Ly9KSUN1Y1BidWl2bjR6NkpOdnV4K1haUFQzUGJkWFR2OGVzdTFpcG9kU1dkRGZ5U0tyVQpjdTdDNEl0RHJzYVV1MmxUOTZLbjNNV2hvNWovbm5GMzVUa2k2NWh3RjdvMFpyRG4yNFZHS3ZkdDZYYWhRMVU5VXJCbDI0Mk1hVmxhCnNsMTh4cU42cmwxOFhqUkRiMHUxeTJ0Q2JwbDIwVzRwVzB1MEd4bXp2a3V6QzRTaXBmU2pReEYyVmxqUE5jbHVOdVRXa0dNWG1HbUsKd0paaUY0R1NNS2g0aHQzRkVGRzdCTHNqa2ZsMWwyVEpXejI5N3BMVWZMdkxycnNrUmZLMzVMckk1UDcvc2ZkdXU3NGt5WG5mRS9RNwo3QnNEdG9HaEtzK1psMUpiaG1XM1pFR3daQW1HUWRETmxrU0RQU05RbEFtL3ZkZDNpTXlzdFhvb0Nkd0NmS0VMY25yRnJxcC9IVE1qCkk3NzRCUmRSd2RhdHpuNi8wTHBNc3VVUlpOMXFoWS9CdXMzVDZNM1ZoYVJTN0ZkamRZTjF0cW02aU5qb2c3K2d1b2hhNURJT1U1ZTkKZWVZNlNGMG00MHQ1RTNXYmkwTTJVTGNWYWUwMlQ1ZUczdDQ0M1ZiTVdRaWFMbzZUNTJIcE5vdklYaWhkdE1RUnVVQWtYZWdmQzFONApCdWxpWlNhVXdzWFJaZnF6OUlQUlpjSFFPQkRkUGtQQ2RERjA0ZkVYQzVZNGQ0NGh6V2tRZERFSGkrQi9BWFE1VmZkNitMbXMzQXBVCk1UNnhxTzk2MFhPallzbjRYQlNKemNQTzVaOHV6TjNSZVhpM3ludWFuSXVPTUpwQkRjNGRsU0dpRzVzN0hLa0lhaTU2SFdDbURHZ3UKa3V3b3lMcVp1Y3VOTlFLWnV4SXpKUUhNeForY0JTNHdHblpaTldpNUsybCtNU3dYN2hOV0p6Y3JkM2JsSVFPVml5OFlxODRnNWVLOApxL2Jkb0Z5SXN4QlBDVTR1UzJMeHFRUW5sek1jSVc0M2NaalRYaDJiazh0Wno4UmJjbkl0SWlzdlRpNDFaUGpJemNtbGdpeEpDcW4xCkpBelVMODRiWHRXMU5nMU9MdTc3WTIzb293dzQ4OHNYSlhlNXkwNVFjdlVacXcwVksxQTRJeU80ZFdOeVpaeHIwdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJYkdHZ0dyeHZ1dGFqd2UzRzVQSmRvZHphbUZ4Nkt4UmtYYnN4OG5oamNwZnB6a0hKQmJzaDZaT2dDQlg2L2FZRjEyYmtycXhmQ2tTdQpGMEFCeUYzVCtxbUxqd3NiUHFiQTR5S3FnTnJ0b09QaU5GcTUyYmpJdUROV0lqUXVYdjFIQjZYdUZXSTVDbG9QR0hlaHFxMmx6Y1hsCnkxT0Rpb3U1RWl1K2k0a0xQcW5iK3pBODI1WWNyQ0RpdGtObjJ5TlFzKzR2ZUxoZ0Z1QkhBNGZicFBpN1liaE5ZYTlBNGFLK0Y3OFMKSkZ6OHpWKzVTSHBJVUVBc0hCemNIazJPbkl1QXMxREdEY0h0YnRRVEROenV4R0FnY0JIdnhpdHpFM0JaUzl0SEFIQ2hSL0pycjFrdApLWTEzNDIrclMzbUNmZ3ZPR2ZWOWh0K0tmMWRlN050cXZFaXdiNnVyVkFKOWk3K0Jjcm5KdC9zNEJ0OHl3UUhaczhDM3Rhb1kvdWJlCkZnK09nYjFGRkxxV0h0UmIrRkR0NlMvcUxWZEVxd1QwTm5jOTkyRGVmbmJOSWh3cEVUQW01MW5leUZzVVJTQTBaZUl0YUJGTmZGc0MKYjV1N0M5NjhXOElobnJseHQ4M2xTa0c3eFQ2Wkl0dFRPSXVWaHRwRGluV0wzK25zNUM2SWJjdGFGMXlnVzZJUkxocHVOUjAzTUxmSQpVeVB5ZEZGdVVXZGVSdDJRVzFSc00zNXN4bTEwRnJzUnR3QjQ0cFV5MGJhNVdldjVrMEs1bTI4TGhIRTVkTnVXbmIwMDNCWi9zNFQ1Cll0dFc1NWNEYmN2dkUwWGRJdHZ1UHkrd2JaMUt3Z1hZOW1PaHBNSlh3MXFhS3dodXJDMXkyNkI3QnRhMnVZWWdxTGJ3UW5IWGI2Z3QKM0poZU45SVdJd21URjBiYTRwK2JPTGliYUl0VElVL09RRnNreWxBQUhEemJWaG5MdTJtMk1QR0xNczRXZitPdUI4MFd3d2ZrSGpmTQpGZzRYNGFCbTJVS01oekJMc0d5QlZXbUNxdS9KQVRsSERySWkyVUtiaU1CRWdHeEp2eXoxeGJHbGt1SGpKZ1hHdGpvWUVCUmJnR2N4Ck9OOFFXeUFWTDRSdGRVNDVDTFlnVWZKRHZnQzJoZjFFOHViWEVqejU4WG9FdmhaL3AxVmU5TnE4eEc4TGVHMVc4Qy9RdFpuUThCZTQKdHJoMXNMbTFoZW1ydkxHMWhjclEvS0xXSW1XV1ZmVEVpbUpRbUhWZVV2MTB3TUxYQzFtTEZFUStGRnNvTXJpcUMyQXRKQVZFZXI2QQp0Ui92S3g2MWdiV1k0L1NFUE5XakdyKythYlVvTFdqandHcmgrai9qc0dvZnljOWZxRnFnMXNZNHBGcmNuSXRUKzNDWXV5bTFtSmhRCml4bVVXa2dlaTlvUnFpYU43ZWhmaUZxZ1pqRXZiRVF0MGhLaXlJcFF1NFFWZWdGcWtUbDd4Z2JVb2l6bTBHbXpaWGozbElvVVpoTDkKbElJQ2JsUHlRZE11ZFVCOW9XbVJOVVloVDVCcFVkSFcxZ0hUeHQ4M2x6WnNnYVZkV3N1Yk9BditKOWJZRjVRV0ZaVm9wQnhiMFBtdgpHMG03Lzc2SXRHRUxJQzNxZlhEVXphUDFhM2JqYUJmTHhldW0wYUo4SGk1S3dHZ2ZMb0VGeTlpYXhhMHJDaG90NUIyRVdRU045cUZXCnJMeHB0UGc2S1JJSkd1M3ZtRmJDV2pSd3RBOHJac1VDM2dNT3lqOTd1V2kwOEtyd2Q2RGF1ajd6bTBVTHNpRkFRa2JSZnJ3c0hBTTMKaXBZcXgvSW0wV0tXZnRJRzBRSm5NeEcvREJBdFJnaUdRRzRRTGJ1bnozbEF0QS9vejRqTUI0a1dxMklNakRlSVZoU3RkRGkwai9seApnYUZGa0tYTUY0VVdJV05FbFFKQ0M1bk0wMG93YURIdVBDTy9FTFNZVVRycVNrMmdCVlNBWlVOUk1JTlFVU2t2L214dUd2ck5uMlZsCnM0cVhtV25IMzFQYy9aMXF3bUZLR3hzK2k1eXlRRUxXYkRhRmRpNzBMUHl3cmlKY2NwdllkMm5XRFo2RnlCQkJtSnM3RzdiQXprSWEKTW1mYTFGbmVFS0kzams0Y0FpTzhLOEdjaFJRQVkyQWdaL0h2N0E1eEVXZGhtK3k5STBsTGNSMTM4R2FSWWMvdFJadEZucDFNV2NObQp5ekxjMUt4Wk1HeGR1YnlyK0twMUlVR2F4Y2pHUllRUnNxMG9WWDl6WnVHd0kxNFhOc1R2eUtBelpUYit2aUd6MjJiR0xKcnpQa3ppCjZqMzY3TEtHUTR1QXNLbGNGMkpXRFRGRzM0alpWRjFNdFJHemtDSUloM1VJczZrNGk3c0pzOWhLdUZHTGVmQzlNT0J4QTJacFRSY2wKRmdiaFJvTXZtMWdSMk1hYkx3dnBBMHV4cnoyN2FQNmJMMHZMek9YTmw4WHhLRi9jZkZuQlFsYzVmRmxwWWNvbndDemg0c1VKREdhNApTM1plSWdDelJLZU9OTitBV1ZxRkhEVmdGdi9Cbk9ZR3pQSS9tRjY2Q2JNQ3k1WjVDTE84T2tSbk5tR1cvNVNNNU4wUXF6eGRQUmVFCldXYWYrR0lFWVphUGhwQzBtekNMQkpGU1VTYk00ajQ5ZFpaRG1OV1RaK0xySXN3eUw4WklZUkJteVRaRlZYa2daZ21pWitqeVJzemkKQjFEMnNnbXpPQi9seDRJd3kwTXkvSG9UWmlsc1lwUXhDTFBFNFdmM0xaYk1NcHY0OVNMTVNoTFZEMkNXQm5ZT0NjQXNMT0lTM1lSWgp3bG1adnd6Q0xHS1ZpdnNHWVphQlAyVVlMOElzTTJQNmtFeVlaWXhuK1Q2eGVtMDFRWFplZ0Zrd0Y2UkJGbDhXREVRQ3N3TXZpMFpWCmFwVjI0V1ZYaStwUzgyVzUxVGgwV1J4bU9lMjU0YklJMmZEQkJsdVdnU2tWVlpndGkrdWdFdW5GbGwzTFgwS2daVmNTejIrVFpaRWMKU1BYTmxVV2NVTzNEakpXZFJiaXhUWldGQWV2TkYxUjI1bWlhWnFZc0RLSUNHaW1yN0VWNUUyVlJvcTN5VVFObEdUNUQxbjREWlpuUApiMk84Z2JLODVQejBBNVRsbytOWEdFQlpjREFSbDd4NXNzdTFpTWJKSWxiRjRMOXBzdmk3OXBzbEN3dGxKVWJKNGdDUG9tc2t5UksyCitmRTkzU0RaeEt4N1Nwc2txemk1a3d3c0lNRHNKNHppUlpMbElFWVljNUJrZWRPclhoVnhHbkNqTUtyZktGa0cxSWNhR3hJbFN3T2kKYllHU3BjRUUybzJTVlE2bTVZMlNWWnBram8yU1ZmNWx6UmRLRnFkTWVWaWdaRmx1dy9yYWFQU0ljbE44SHpkTGxpME9vQ0VJbGl5RwpkbjVyWnNueW5yQlc3bUxKMG9qNHVWbXl6SXdqQWgwc1dSaVlSTGhac2pBR2daWXNXUm9RVndtV0xBMXNTM2F4WkNsNXBLYkdNRmwyCkJNSFhIekJaREI5VUhOdzBXY2tnODl3MFdXNkYyU3Rvc2lrN1ozSFRaR0ZrZWlGb3Nsc3NLWnBzSXJ4bnRCZE5Ga2I2RWtHVHBRRmgKdktESjBzRG1NQmRORnFNMktibUd5WXJvdjFMUVpObmFHd1BXelpPRmtXV3lBWlJOcElhV3VZR3lOTENLK3dMS3lvaGtoWUd5UEE0TApEZzJVaFlFczl4c295MDRJeUxZSFVGYkZFbmtGVUpaOVFQa09YMEJaMWNZQXpXcWdMTnJWY05JT29peVV6eFMyM2tSWnlxR05rU1pSCk5sV2pmVTJVNWQ5OHB5K2tMSTJRQ0FSU1ZxcnFyQXdST1Z6OE5XcVRicVNzWk5UNnJpblFZT09mcFZwQUVtVzNRdm9teXRLdGExbUQKbkFTZUlQSFRtUW1pTEVUMFQvb0VsSVV4c1JneWlMS3dlSXA2b2dkOFBYbkdqWlJOcDMyQmtiSThGbnRHQkZJV29uaXFMRjlJV1Z5agovS3hBeW5JK1ZvTFdoRGE0TitNVFVaWktKNWFYQlZFVys2bWdMWWl5dUJFaUc5eEVXVWpZVFhVM1VSWXZGaitLQU1xbTVvNlJMNkFzCnkyV29DQW1nTEx0d0tUVnJvQ3g5Y1FDU2JxQnNpb3ozQnNyS2NuQ3lYMTM0N2R4akxIMmtGTjg0V1VFUzhxYkpZbXlsTk5vMFdUMzQKbFY0NFdScmhpd1ZPRm9lbWdEbDRzakJ3VnJwNXNreVR6N0Z4c3Z3YnMxVHdaR1hvNjhXVHhZOGhqUnc0V1g0UEFralNqOExNWUJUWgpscXNodjRZU2xjREpNaStaK3ViRVloU2FiYjVnc2hqUG5GbWtyVWRyVGFGa093YVlaNzVJc3JBOVpyNU9iVUpNaVRpeVVPZk9GMFdXCm5lZytibHRBWkx0ckE3MEovc1NRY0NOa3UxdTZCa0VXMktoSFFXSEVpTkFxRnRQRHhZOGxqSFhWTUxIWGErdWJIaHQvWC9EWWJUSTcKZG5yT0RTb3NXS2tzMHJuSXNhTXBhcnkzS1FLRUJEZzIvcjY0c2R0a2JPekh1VlBuYUdyc2ZBU3R1cUN4UWNzTlp1eDhOTFFGTW5ZKwpiaGgxRVdPeGo4bXZqTTFNQzBpQ0Z6c2Z2Ym8zTG5hNEJVN1FZcGtiVTRpS3RGalFCTWpOdTJDeGhJaVd1Vm14QVJVTlZDd0MwQjhECndRMktoUW1mVW9CaThUZHlvY0dKSFNLMzNwVFlZYWxYUUdLSHU1Y0VJNVpCNnR4ZmlOaHVEeUVRc2ZqY0prdkU1Y0dONkJad0VXSUQKR3hXQVdEUzhRVFl6K0xBOUszbC80V0ZwS25uVFliRUxrWVNHd3dMNnd3em9nY09DaUZYR1JzTWltWW1Vczhpd2dHR3hIMWw5NWJkWQo3Qk5jV0NSbUtWY3hGblo0VFhoVFlkbk9sQldtZ3NKMnJYRUNDZHNOL2J1SnNEeVJ1bm13YkROOWFMQ2RZYS82Z3NHeXVBdHZvbG13CjNjVE9RTUh1UXh3UWJIZCtMeml3dzBtVFozL0Vvc0NDU29GUUJDQ3dHSlBTaFh5ZDBTYmpRc0JDeDhYVlNXeXp0RndLQUN4SlYwUzcKSHY0cmlSV29JVk1xQ1g5MjNpUFJYNmYxQ2pmOWRSbzBHL0JYcU4xWnZXVDJLMUMyS05PN3lLK0xvZDJ5d2E5WWJiTEJnd3VDNCs4TAorN3BOcHI2QzY5SkY5aHRXam5HZGNUTmZsNkV3Z1h6Rk9veWZheUJmaVRkb2FoYTFrYTh3U2xHc2lCVjFIUXdlalNoZDZacktMK0lyCmdVaEQ4VWI1RTVCYlVVdHE1Q3Uzb056MFFyNWlDdU9vSGNoWE9KUmw4MTVuMFJPL2NhOVlKcUhTUDJpdlBKdEhHNm5pRjM3Q05LSjEKMXczQVZjQ1ZCdTVWYm9JZ3VXclRsZHdwOXNhOTJsVW9HL2NLQTBlendMM1N3UExsQy9kS1A0c25idHdyOFFrWWVvTDMrc1hsK1BHSAovNks4VjRiUXdQQzVlYTgwSXNvWXZGZUYxVXJlZ0ZkR3kwaDN2NGl2RElwQWVCTEVWMkllZUhBUlgxZlZ1M0FEWDNIQlhKMEg4SFV2CkJBUDRpckFYKzN2ZXdGZTFQcFREUXVJckRUam51Z042WFk1QXZlTjVvbFFFOEZVUnRkNDI4SlUxZlNTMVg4QlhCcFllSjdNa0srb1MKa0FmeGxmRUxacXN2NU90MkRJMTg1ZnRub1lEcTR1bktJa04vSVY5dkkyUHV5Ukh3UUw0UzZkQ1VwdG5JVndyTklXSUo1R3NpYkRmbgpqWHcxdEtLOGtLOVVDRklQWU9Tcm1HQ3RiT1FySGlFWE9UZnlGZVVaV0VJRzhSVmxSVVFtcTVwMXVhbkd6WHVGSnNsUWFYck44RWt4CkNnVHVsYkdqcWk1L0cvZkthRWRYUTJQeEJ4NzM2UXpjS3cxTmxYbW45b1hHMmpmdWxjZEJoRE53ci95MVBGKzBWOGJvMkJ2WnRGY3UKQnl2ckwxalB4d2dUYVlNSDlvb3dqUHMwc3pvSXpDYXNFUVAxeXRLSlhGK2tWeFFORVJwcjBPdVk0cllGNTNXNFNPdkd2TUpXVkpGSQpWZnR3dldoQVhvZS9oaHZ5Q2wzYU10TVZRa2pSTW9Qd09yb2lPVGZnZFRSWDI1dnZPb2FLVUUxM1JZaUZyUElMN29wK0RSaFRBKzdhCmw3dGJtdTNhSFd1NzBhNWdEaUZvRkdUWHJnaGVjRjNKS0JydGhYVmw4eEJrcGtSMXhSSHdoZ1hVbGYyUXgzZ3hYYnVyTDZPTUZUMHMKc2lyWFdiT0dNOGQ2K3lhNnN2OXdMUnZveWtMcm5EZlBGYXdvT0hrM3poVXViOVk1TVZtR0xvRkZsMEdZYTNVVjRNMXl4ZHJSemV2cApZTmE1QWJBTStlTnZ1T0EzeUpVTnpVZmVIRmYyeXNsbFkxd0JJSVZ5NWFhNG92NlJMcmNocnExcG0yQzRRdG1DdGZHTmNJVU5ybndnClhLR0lhVUt2Y2pVSnhZeHBiYnQ2dkZVbEpBTGcycXJrc05jK3JDQzY4YTJvQjJmSnU1a1Y0WVFIdmhXMUpKZy9iM29yUUJQNG5ZQzMKdHJsNzBuTE1SeFVNeWJvWHV4VTJmRHFCYm0yZVhvTGNpdk1vSnNSRnJoWXljSVRhREc1RlFuRWNkUitJQUVYaTJZMXB3WlV1MXdvQQpYSXJGRGN2cHpXeWRiaVIvSTF1WFZ6ZUJiRjN1MHhQRVZtaDZpWGk3Z0swUWpMS0kwYnhXbHRDc3RYR3QwQ2NqQUhmUldpVmozcXpXCjVUQjJvRnJ4ZC94S2tGb1ptSWVySGFUV0NLRUhxQlYxUGVBZzNKeFcxT2h4N1dsTTZ6TEdMeWl0eS9IY0c5S0tuSURlakFnb3UySTcKeEtxaU9lWHhnclRTU0t5dzVWT0pHTTFjTjZTVjRXejRxamVrbFEydUVmb0xTQ3NtZHNNQnlXaE4wWjdnWXJTZUk1blJDZ01STk1GbwpwWG9mUVltYjBRb3ZKbDRJcGFuZ2dMTjN0aG10VHMydUY2T1ZuaGRiUDVqUnlnd2tacDFndEg1eDJDSlk5ZjBZcmNzdFcxNklWa1JkCktmUVBRaXVpcmxHOHdQVU1wdlJrWXV1V3N5eFN5Z3h0eFhBQmd3cEJUV2ZGYmt5ZzNIQldGaVhLcXlhYWRRVmZOUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJaUtzS2wxMm9WcjIyOFAxWWNoaWJvV3ZUOU5xRWhmRW5yM09CV2VtR00xOGZZRll1ZHBoYURqQXJRM2l1NGR0NFZZYnhXQnRwTGl2UApDN1hTbTh0S0I1ZmtyYzg3OWlxZHZkb2NzeUptam04Ynkwb0xPN0hlV0ZidXdGb1lZMWw1MFpoTWpHWGRmOTlZVm9aeldhMXZMS3NxCmMyZmRXRmJtcjFoZGNHRlpHZnhtZzdnUnNyVkh5czdnc3RMenpRS3NucHBDZUU0NWJTd3JZdThzT2pLVmxmOWVoSURkVkZhZUVlNWMKVUZsVDlCRUlLaXZGK3hoRWJ5b3JqZnlvVFdXbGdVT0txYXdjekZBN2NGTlo2ZTNodklQS0NnT3JZNFBLQ2dQVjVqZVZsWXRLanYyaQpzbExac0JReTBxOWpkSmhLQ0cwcUt4ZVp1R3VCWmNWN0RkRitVRm1WV3l6MVJXVWxUd0pJZzZDeUtzR2QrcWF5SWpiUE1lV21zaExvCjBRUmQxVmdJeHQ0OFVGWkY5RFZlYlNvclZRd0lGQVdWbFlZaUNpc0NXTnlyS25Cekt0cWhpZUs5TnBXVlhMcWtZTjRRNGkzcEJ0MVUKVmdnZUVPb0xLQ3R6YmZNd1dhR0RZZERpWnJLQ3A4WDA5TjRLbmdPQkM0YXlJdTNCOStPR3NzTEk1cXlDc2dJR1JIY2dvS3hJenpCQwpkRU5aeVI3RGtqT2dyRERRWXdzb0t3MlFTdDlRVmdKNldNOXZLS3VJUFI5M002Q3MzSTIxTGhlVU5UVzdhUUZsUlYwcmx4VUJaVlh6CmJqQ0VENVNWYVN2V214akt5cE91OGdVSVpRVytqYUNBaThrS20zN0xUTlpFVWsydG04bEtBK0ltTjVNVlJtTEhnc25LclhqOVpyTHkKd0VtYytNMWtSZjVQbkFveldmRmtpYThLSnVzMjNFeldZelNURlFkblFDSm9xNG42NGp4ZlRGWmtUT2wwN2EyeUZqQ0JaTjEvWDBUVwpzQVdRTlJIU0JTbUNnYXo3WmJ5QnJNeDhvaTQ3Z0t3c0ZVWnlPb0NzVEdPWmdIKzZ1OE80NUo3cEMwWVNDNnVTQUxJeUdhVy9kNTBEClgvU3FtOTlVZ3Z5SUIwRkVBLzRWNjhlYngwcThWWk1QcWV4eENkWmJBRmtad3BrM2o1Vkl3Q2RMVWpQMGFhZ3FQbmlzL0ppY1BMNDYKVEZTNUJ1YXg0dStPQkY3d1dHR2dwM1B6V0dGa29ENTRyRFM0R1NsNXJEUThPazQ5MzBwV210UkVWbVpYS1hJS0lpdjBhaXlKZXhGWgo4Wmk3T2VzRVlyS0NmNmdmS0lHc2xHOFJHSElCV2FrVHlJS2c2NHZHK2xuWlhBTlo4ZGF4ODlPTHlBb3IrY0NieUVvTEhzbEdzdEpDClFkdU5aT1h4Mk9vOGtLeFV6TEVxTlpDc3NEQnVkU0ZaNldBeSsya2tLd2xXZytxaklJY2treUl2SnV1MmJTWXJKeVBxTW9QSnluczEKeXljb0s2eDZwUXhsaFlHTC9RMWw1U2JVek54UVZscjVoQUxLS3Z6WE1LWlZ1TTZzRWU4RlphV0k3akZycVd2bTdCb3FOcFNWakFLbAo4eThvS3dPMnJFOE9LQ3RySUtsVk0yNlZiejJ2KzRLeWN0R1NqbTFGTDdSQUFHN0RUV1E5Um9OMjBNSkMxQkR6V0wvNDJOL1ZqZis0CkUxV1lpWU5qVlZWNTJqUldlT3RjWVFXTUZaSGNYdDhzVmdTSldGNXJGR3VYdW5xVFdLZEsyRjhnMWcvYklERFZTRlhJSmhBc0RCQXIKVnMxbzBITnpXTEdPNi9jdUErckVEV0cxM3ZQRllFVXRJSW9FakdCRmV3MXhTRVJnUmJ5eXBmb0NzRUp5alFwNzgxY1Ira0xOYk5CTgpnWldGL09QR3I4STJpV1FWZlJWQnVtZHU5aXBVOVNpV3VkR3JVR2Vqd0NMUXEvaDdJY1J2OGlyK1JubnZUVjRsdlBialF3anlLclRuClVERHNVNFBJbHF1Umd4SmpNZ1J1c2JDclVGY1hmTzB1N1FLVmJ1RUdYZEJWS0crSWw5YUFXcGJHOTBDdWxzNlcyQmR2RlI1RXhuTEIKdUZYMlhudktwcTJDYWxlZitZYXRsaUk5d0dhdFFndmVpR1IxU1FRTUtDQjZrVlpoaEdRMFFLdUZoUHQ4T0tzRkViVlMzcGpWc3FRawpKV1VWbVZBeU5mMmlJTlhNRmdrWFk3V2FMUmVJVmNiQTF0aUVWU3pZdWE2OUFLdUlUcERuRXJHcXg5UUM0MVc3UlZZM1hSVTI2b3dNClY4VStTNWxKUlVvZjh3Y3V0R3F6eENuSXFzM3Q1d0tzMm1LcU9XQlZxRTRZU0RkWUZaSUl2S2ZHcXNJNUhPa0ZWVVVnbEFrdU0xV0gKRVRPQlZCMHM5SHNCVlpFQXo2S2xrcWM2alBZSm5DcDJBWUxncHFsQzZjTDhsMkdxbU0zQlh6WkxGVElzMWlsY0tGVmNIaWJwSUtuaQo4cGxCZFhnUzRVT0VXbStPS2dKdjBDMEdScFhaYXBFVG1hM3JLdFMvR2FyZFBQOUFxRWFKY0JCVXUrdi9iNEFxR3g2VXRmbXB1K2pUCitOVEMwdVQwb3FkV002OENuZ3JJSjlKalpxZTJzdkdSRzUxS2tFU3VtNXphM0ZZb3dLbk5Lc1dibXdwYkVRQ1ZxbHBTSlhyZTFOUlcKQkpxL3FhblZBdnVBcHNLTFl0YzBKODlRL2NTZWZoY3lsYUtEVVRZeEZhUU9mRGdHcHVJT1FFbDU4MUpoZTFiZnVGVGdGNmZFTjZTbApGcVkrMGd1V0dpaVZZS1VXbGwvblFLWGl6NHlydWtpcHVCdVBoRU1FcFJhOGVpS1pNTUZmV0psZlhwaFVWUDJ3N2t1RkZTVnIrZ2hJCkttcUt5SFc5R0ttc0FjaHRJMUpGdmxxYmtJbzhaUjh2UG1ydUtySU1QQ3IrQmpRazZLajQrNm5yQlVmTnlJTTg3YkJSUVJaU2grbkIKcHJDVkgvcE5SaVVnM1RhQVVTSGdRSTR2d0toNFdiTUFwNXVMMm9BMmVnNFdGWE1qbk1LZ29pSSs5SWlsdXFHb2l6WGo2VEJSS3lzdQpEeElWNDVaZW8wTkViY0xkYkNKcThwUnBJQ3BlaFpwZU9GUzhRWEEzZ29ZSzNTVFNGMEZEeGF6SXk3MWdxS0FrUVA4UUxGUUVFSldpCnhFU0RMSHNlbjBpb1VNKzBBMExGbWwwL1F2SUxXMitXL01hZ2ZyeFlnRTFzQ3FvRm94dUNDbDF2TFc4R0tzSVBwUjRFS3FhT2NnQ28KeUhDbS91YWZJdnE4NXNHZjRsVmwyd0RUVHo4bS9xcUt5QU0vTFhKZWduMmFQVE1IK3BSbHZYaUxMdklweEJWOWJPNHBGaEFrNFFYMgpGS1ZBVC9wRVBRVUF2bTdvS1JKbGoxd3FESjFjdWxBdGV6RlBKVlZnWTNaSlloRkRkS3RsS1VjZWxycktvZHpRVTBUVFJZczI5UlFHCm9lRU41L25pNTM1UEp4ckQ1dkQ2TktDblVBVkFjUlhNMDBBbkJmSVV1YXNwU3VrbW5tSWxEaGxrQUU5UjhneWhTUEJPU1J5bzY0VTcKeFNnRVg4RzAwMlpTWThCTzhmZVlMOVJwYzRZN1NLZklEaUx1SHFCVDBrTWc0NzA0cDYySk5oS0JZaUNTNEcwRXdCVEFEK2VuTnVWMApwcDBCcFEyTFpkNEJWUzBDVFlQVitJMDRoUTAzTWdpbnk1aDlBMDVCaHRTL2Jyd3BJdG1ZOVlKdWlpb1lCcmE4RFJKbnlDemRiTk01CjFkWXowS1lCOWd4bTZaaEtWOXhnVTRUWDRGK0VyVThKUVFOckduL2ZWTk93QmRSMGVIWU5YT25vV2tUZVRGTW9MSXZrVzdUTnBOQnEKRUUzMzN4ZlFOR3pCTXlXRGRkV05NeDFHS053MFUwaE1TVEl4ekJSQU13UjZBMlpLd0ZrZUw1YnBjQy9hUUprT2ExMENYSXBYdStUeApBcGtDQm1yOEtZVmUwelR2d0poQzZSYlV6cUNZSXI1V0ZDOWtMSUovbDBNeFpSd3h2UmltMDVDWlFKaE90OW9KZ3FrYjI5NzhVc1lzCld3MThLWE9jSWlkeHJsTU90Tjd3MHFEMkJMdDBUamVEQ1hUcDlNZjNJcGRPWmlPbDMzSlJFa3RjQWx5S3Y3UEN4WnRiU2x1YUcxc0sKMWl0RUMwRXRSWDBLZkxBYldycE94ekJXZGhFRk8xSXdTMW5sa1YvRVV1Q0JFQVVLWUNuZU9lbm16U3VOMXI4dlhPa01BR1BRU2xlcwpWZ0pXeXJLck50K3NVcE5vTjZrVTU3UDY0WlNpNklTVmVEZW1GR0ZCb3Fvejc1UEtFZ0pTdW85d0lVcG41QkJOS0oxT3NRU1BORDd0Cm0wOEsyYVBvcDhLVHpxUWJ0N0dqbzVwQWR0TkplNkJDdzRoTUMvR2JacE5TUFR6ckcwMDYzSlI2azBuSnhlamxnRW5IYytwUFE5bzcKbmxPQktyVGE0ODRlUVNYOU1LZ3U4NGFTZGtkN041TzBQMUU0NmJMYmJiaUlwTWNtSUdrM29HVURNVWRXZWMrTFIwckpTdjIyYWFRbwpLd21NRzUySzZ1cW5GNHUwcnFnTU5vcVUrdlFlSFpla0xJOFdUenRuaU94T0tvb0E2dGd6eUh1bWFsUW52bDhRMG1hOXdHYVFJcW5WCjJpYVFqcURnM2dCUzVBOGhJdy8rS0ZkRDNnaTFvU1FnbW9vV0tncVVBeFdEN2xoZVc3TlVUSnM5V3JONldyelFveFdMNndDWjRrYkQKb0pwb2swZXI1WHczZUJRTjczVFdUclpGcmlld281K2RreCsvbytQelg2bWpmeXQxbFAyWEtETEFTUG94eGtveVc1cTcwNUpxMTVQYgpNaTF0eDFjVUt3bkd5MmtJU1RDMFdYTzZ1enNodWs4Y2YycDFCYXl1RUwycmEwbW90VWh5ZVJqY2hxYldJOUs2Y3c3RDRJMzFYc1kvCnNhajBPYlFBZ1psQm84TnlDQlpxdk1TeWZvUUxVS3VxUlYrem5UMGZKR3lKQ2NmS2hDdEtrOHZUbUxJSTU3d2M1SXVyYkducVRDWlkKT3FRTVkvV1IrRTVqVklFT2lyd3UxT0xDSjlUeTBXMEZNZ3RiY1JjSUJ4NXErNnppelpiazZLQ1Q3V2x5ZjZ4WmdaelVYRUlKQyt2ZgptV2tsTkF1V2tzNmVoTWpSMnJwSXcrNWJnVFVwTGhnV3lqZ1JnWjRCNW0vdUtjMG1yMWoyc20zNzR0bGlQYzlBKzZOUmt3MWxJLy9lCnEvS3BiQTNIeW5rV01pVjEwUDJZaXh2YmhaUEppSDV5VWJ6RUh1T2RDMGpNSXl4cnFPSTNveXN4V2FQc3YwUGxPMUErc1ZCU201NXEKNjNCL0hTWmRZRUhva245WC9WMERza2pqVkVQdHhsWTUzYzIxWU9rdEd2NGdza3hMTDZjNXZBQnRrTkJTUzRWSHJqWk1qemlncVR1dgpyajBqSjhibFJkSjJEenRoUUJHYjJTRWJqZGZaamFvcjE0NlhvRTVEcGRCemdEQlVQaWFFcnRGMVFDZzFURC9FRjB5WGpPRVc4bkVyCndXQXhLRytzV2xRTlIwb1JqK1czT3YwcDBaTGliT0gxZVQ5a1B2QTNpMUo0ZkZiL3c0SUJIcFlVMkFCOHQ2eW14aFAzOGJzS3kvQlcKRkR3QlVOV25wTXpqa29wdzlRUDFORHNRNC9OU25XNm1wUzUyVkhaZktIdzJZM3F5aHBXQ0RWcEI5S05sOEJjNmtWVTB3S25PcktqWQpUUWNmbFVMRFNnaFRWaEcvRHNXd1gzN2M0MUtXcVBSZUx2Q0VWZG80RWsxTjExZUpPQzRJdXEwc1dZN2pGVS9Jb0hFODlZOUVySVF0CkJ6QXFaM1dsWm5OME1OMzNyYVVWekZGWSticnd2V0dPRGt2bXhaYmRybC9rTm8rakVHeUR6VzZPUTJFb2JpZTBQMzRoOFkxcmtqNm0KTWM4b3dnN09LSDVtM3djR0RPazdJRjZCcDFNNStBM0RWVUFMd09pZzZ5ekV1ckg3QW1vM3NLTTJtNGJBOGJIeU8xZ3FRTkV6V2RKdwpKUzU0a2p0U2t4Y0R6WVArbHRBTmY2ZTRPNCsxdG9tUVhlOG56RW5zNTZyNmZlU2YvVHdvZXVBM2hlZTdXMEhnUk9uM0xFdUQwMXpDCkxPa0NrMzhReTFzeW5BQ0hXQVF6c25URmJ4RllFSURuODV1UG4rUlhpUVp5S3o5Ky96anRRU2YySkwzZ090YkFnT09xV0xiWEpFb0kKVnVUOThKdHFQem1ZeVM2MHlNZWs1bXpGbnRuNERDaXgyR05zRllQNndheGxiNjVaQWl5WmxLelV1T1V1SEhqSmxLeGpzZDNRUUZjUQprTU00cithZ3JWOGpIcXhVUERaeXUvRzN6Z0h6Q2ZrbzNkSmZXa3BNMGFoZDVMcUdWaVRadXh1NzhVZ01FWEllaVY4c2dXM29XY215ClJKK1pYNFpieTdFbkMxWW1pQlFoVm9XM2xZaGlEajZqUzYzTzdpWHNGMENRYnRORC96alM0ay9xdlVQTUFQSVR6ZTNEYnhVNTZ1d0UKRVBYbncwTXhCRnNmbzZnZkwyWjcrUk5ZZWFCYWFEaU1DOHZIeUsvVEp6dUZmZDlXMThNa1FTSThrVFdUbnpuK0E0YkhiOEhIRGEyeQpKTDdzaGVITi9aTStISlE5dVBIVnhCMkFxNXZQbnFWaWliRXRYeVFFK1hwN2t1RWIxV0p3M2d6a1ErZ3Jza2RORlNMNTUzQXB1U3lCCmxYVXNzS1FzSi9OaitIQXowSmN6R2lGUVNYbnBWbVMxdENMRDcxY2JwUlNCZGVJbEl6QXhhMG1kcUdQdDdvS2QyRmYzOGxMVWh4ZFcKUWdwZ1lXMHNjQlYweG1DaDMxc0VkZk9lVFJoNnJaeVRlakdKRmZTeHRsNjl5STl3NXhOYjVGS0Jvekx6dFIxQ3FIeC9TelhkS3JvWgpraS9RUnJpT3pRMW9VWUgxdUxWRkk1bWNQYit5bTFSQmRRUkYyZWhSM2djVkpGOU02TXo0aEhxZ2FtNExrV0RhTStadzBocTdGR29mCkE1dXVxaWg4Z2ZOZmNyTVlxOFQ1TS8vMXN4M2RRc3dUeVBsdG1IREFxYWVaNDNsWnB0Qnc0U0lUVllHUGgxck5GZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJSFp1eFpxNXNwVmhVMVVIV3hneVZXSGRiRWpUaVh1eWloZi9BODRXRlZLL3Vya25jTWI0aDF0dXcvV0ZSTW9lV0lzUGlDOWRkK3FlTwpyZEVqcXdWMmkzMDBLT0lNTGo4Ri9sa3RUeGRIMHVHYzZoNmROS25YakdFQmYydENRc3FTelRxenlXV0RKSys2OTlQNWt4eis2UGg5Ckx2ZDhtZXJYU1lrcUxXMnZBWVpmT3haT1BSS29VUkNNampVMVY0MU42cW5kbldENjBhc0hpa2YxYmxVMUYyR3hPQnVwY0R4a3Q4MGwKcWVmVGg1MVZKREFmdDA1YkpEaHgzWlRWSldlaHowSmliaTFwTXVvdEpJTE12dUpMUnNkVVlpaVE3R1MzbnlPMURDb1RaTWhyQzlXbQpwVW1UMGZDa0pyL1R6VllaYU9HZUxESkdKSHQvSkRYRkkraGUyWkJ1eW04RDhWZXNRR3YyUGVzSVBBVUFwamkwdzVtNDlQaVFOVVl5CkJ3VjlGVlhNMjZMc1UxWHEvbXlIVlJWblFjQjA2cU1JbHQ2ZmZybXJGb045M08vbFR3bFJKRG9TVkZlU0cwVGRwK2dzOFRrajFjUkEKR1FBcUkzaHUxVEFXSnY5SUhFcTVCM2FsN0QybHZpTzBoUUhrYWRZMFhxUktQQXZZY0VzV092emEwOTRmbENqNWNRa29heS9BTzhpcwpIWEVkSkY0THJoWjVYeW5oS21yRFU1S09UMEtBVy84bzJNZ3laYm9IZTRoRldESjhobWF3SHFzRDZEUGszSUtLMXo3NURGUnFWSGtwCm81cTdwMGdqa2J2VGJaZndqVFRyb3JSajk2QklLY0RrODFZamVNclVlUTdiZ2dhZU1mUWM2L1NpRlZGWGptS0E4M1BhaGw1U0hxRXQKZXRIRFp6dmJlWFZGcHdsNTY4dENXWWwzREdOcm9oWVRpOGNmd0tmT0JlOStYVUVxZ1JPaEo0bGdQRTZXZlhTYk9EdWRrdGhzaU5GagpVajd2Vjl2bDd5eHMwejJMZU92eTN4UjFQY1JJVGxucXhzWGdzVlU5Sk5KZWhlTnBlclJVRmRCU3U1Mi9QZHFCOUVWbm14TDJxU29CCjl3VmJwb0VpZmxVTVRFbzFlcmdoRjA2cUc5UmsrckttdXBnVUxoMVlJc0VoREVUYkhXTEI5MGdmaEtGTkJsWWgrb1lRbUJiditlRVYKNlFkempjYXNXSnB3dUs2VVpJcWpCRkFMREE4bGNOaVJzU1d5UnZaM0JjZ1JoZkpKcEdrMk1lMTJyTkxqdVA2Z3l3dE1TeXc2S0NrZQpmai9zSWliN3FSRDBONDU5MlpNNkFrTWw2dHNRTnFha0dwMXZOUElqUU0zN0NrYm5sRitnR0RGSkJWdk1qcWlQUExLVzdJcm9FZUh0Cm0wa3V5KzdVbGtmb2dHRWQxVDRmVy9JV3Z6MTBBaC81TUlyYXdZSm5wdkg4OFRCRDRWT1ZBSnoxRFA0RUN1ZWowZTFIOUQzd2JDdXAKQlJTUkluYlFteitWNWp0V0l0VXpJc2dDZ2c3Zk1sZ2Z0MWNYdTRvNnlhVEhwU1VUOGZreHZ0WUlmN0p1R29NY0FXbGRGczNzTEpzZwpNZlRxOGNOWG5EY0dEenMxa2NONm9lb1lpd2l2SGZwangza0ZOQTdOeFpScUFacHRhSGgwbjU4cUxTbm11WjNzb0NWV1pidkptcmZiCnFaUEJzUE5sZ1pSdjlmQW50eFh4WVhvK3cwZ1hWQUx5WmZ6czVNY2FJS05PdXFJNkhzSTh2Sk5xa1lYTUUzdXhkd1hBY2hERU1xWUgKek50WjMrRGlOcHlpdVd5dnhybmxZaGxJeGdjMmliMW9lazAvdmdINUFMbk1IZDJFc1l1T2dmRUluUkdnT0N2a2xLaldFb2FLQkJBTgoxWmNQSzdYb3J4M0pRT1B4ay83T1ZLM0FiUWs5TFE3UDhuYktEeEZPd051OUdETEtVZ0hqSXVCOEkwekttWVNYQ0NqVzRHYndhSGxCCkpnaGxLcGJ3azhVdHgza0sxUnBKV0lWZzRBVWdwZ0ZHTHRzWUY0UHRZRUVyRlJwMmp5K29wL0NPOFhEb1ZseTYwcENaZmhmQ3FMQ2cKSm9BWDJhd1M0Uzh5WUY2YXBnVnN4KzVVT2xmOGI1WG1FQmZMd0pGMmRHa2JubmRMRkc3QzI2WHFjMEJOakFmZkFqR3dSSXptbmtSUgo4NUtTWHNlY3ExQUtrQXFpYzFCV0tsY1h1V08vZkxORUkxaEtSZkRKTEQ3QlIrNTBSajBFdys0WUk2dFQrckFxbGd3ckF0eXdLSTZNClBpc1FLTUhBakFBSGo1WDJqblFxYzNWREVCNEtDMGRZV0hqSW4wekxCc3V2TWpXcE9NV2FsTFptSkozQmZyNWtET1VPVlVqalRyTUIKV29UODlvYzBFTDVRbkE3Z2FDTERHWjBxVWl6RE1sWWc5b3ZEMUNpN2U1Z3VLQ0xsY1RNK3kwZmR6bUhvdWU3OUdHWnZpdVp4RzRiRgpRYUJRWUsxWWgwc21SV0RTbncyUUtPcFRvRGp4MGxpeEVFNWlGSnJ2SlI3eHNKd1BjZWNlMlFVQ1J0bHFHR0UwaEZSYlJwd0kzYTE0CnFvUWVSOStCSkJJampSQkZzdjB0c1VPd2NPS0dHSWowSXZqS0pWakswQU5CazVIcGU3UGRzUjB3V056cElQa0ZoaCsvRzBJUlJjSkcKNGxuTHJDeTI3VkNxcUxEeGVKY0tLTWRJek12RXhSTXNBdnhQemRwVGl1WEhEaEVicWo1WnFSM0dEM2UwY0E3RlRCbDlWSjlYcDRBNgovSEgxb3NXckNjOXVmOCt3RHNic3B3cGxlU3dGdkRGZ1JKUGFvUjF6dkR4cys3QVl2YVNQd2J0U0krZUVjWVl2Q0hsRmVFYVBWUjg1CkcyekdwQk5DV3JnSEJLNDgwSWJ4WVQwZThnRlZXVEhXb1lzZEk5K1BPYlE1dVZVUis4NFc3VWdTR2U5U01rT0tWbkxVY1dXTG1aUEgKc0xYSFJMYk1ibmhqMkpMUHA4VysyTHhMT1MzblYzUU9VMW1yWXNUTkE1R0UyenZoNVJKSEdpVmovQ1NReldJT2ZpNlA4Ymc5YkNSSwp2bkowNHNXSGx0ek5PV01TOUxjb0MyV1UvRjRyazBOUTBVVjdBSkMxdEU1MUVVT204cmRvTzdZZjRUYU1mS0I3NHc3RlEwQU90M2hGCmJ4VW9ZUmlhVzQ3bFlPanRqOFlETmliUW80U3NudTJ5bThCUm1WRHU0ZWd0SjdyaS9CVi9jU2R5aWpHcUNtRmpkQ3pSWWhZV3FBZGgKVVIzWExLZTZFMVo1SWxQcW1FeXR0cnRvNzU4a0NZUXRzM3ZNemhCc2N4VktPU0xlVC9oYlU0K2NpNGlNU0ZIbU5VSStxOTNRTFlkOQprNk1iSnZnZk5YdllhM2hMWVdtUHR1bWhrSmQxNnBheDB3RVBOYm9zSE9Qd2U2M29GOWY1eFNyQkp4SlRLK0c5UmNpSEl4UUtDZVVmCmRIVld4TGx6RzdsS1U1Ri9waFRnem1RU0NKMEVvdTlFTnNqU2dKSWlrZ1ByTEYzakRRdW1ZRm5QZEhLUGVUVnNzNW9ubDNoekNJU0IKLzRFRkYyY2FOc2h5VnJCandRWkw3MDVQVTZtc1BhMnZoSlZkVzNCTkpIbHh4S3FrbUdVVjR5dHA1N3dqSEVLaG5xQ201aVNGT0FsOQpJNHdreUdaa1JIN2EwR1RROCs0ZkJrMmlqV3JNeXZTK3BscjJ4WUNoTVUrN2JnMCtlcElOcGFRWmdlYVJHcWVwUjRzNC9tS21LMEk0CmdYK3hHZnlBbkNHckUra1NLczN2WmltWkRhbTZoMWVFVXVVVEdzeUNTWUVMSTdvc0hLblo1NGJ1TWpsYStNVU5mczRoNDhYQVZCQUwKd1Z1MkhuaEx1U2pmblJtWXhidU04aHZYdE1EWUpoNFRmRlZVUFdRR1psSFh3ODFzR1J3R0VBc3FWb2RsYWlpeXRtdDh5MGhnbXJKOApMQi8xays5VndWNHZZTEN2ZTJuOThTcHp2WUFxcCtxVzB1d1pCd3R4VTRqcXkrbER6cDFwbTY2S1FBM1p5UTA5Ui9lY2tGaU5oTDlaCmJBMERwek51TWNiYSt6MXdZbWh0bm9XV3MvNE1CTkNnMUYwL2F4N3NTQ0VDdzkycktYR3FoQVdiZURGZC9RaThVVjJiSXFkbVNuYkkKc0hwU0lwcjEzVWpjVVVjSkIyT244ZzUrSExKWlpadGp1MUhqM3FDTkR1SWh3eFF6Q2o5cXhGMWg1YjFHSVZqMmR1SVFFeVR6eU5JaQpGTGpkZmxnNTFhb0JkeDZSQkx1Mll5NkxHYmorNkVscXoyYWlDTVRuakdBSE1CYmhOQVhGZ0tYa2ZCTVdPVkpGenMvWmJqV0RUcUQrCjREUGNGc0JyVXNEWWp2VnhGNW5sK1ozMTVUeHQ4Qks0YUE2TDdtMVJvUDVzbHQzWG9FWnQ0N1l3Y2g3NGdHT3RiSStjU1BqMW1RMDIKdVovVEFkUTJUNHBZZVU1S2pOdzZBQloyRzJDZVFpazZrdzhSU1Q0Um9obmRjeEZmN3Q2T2ZSZGhZYU1mNXU1WERrdEUwV2Mxb2FZdApkZXBoQmh3dUFLb0IwYXdJZVFuQzh4Q0VacDZHMFFpa1FoZzJhaEdjZ1dYNlpGbUx4WHcrRXpWcVUrNjNZT2xieFlOREp6am1MeGtLCmgyd0hFMUhhL1hsUkN4Zk9XMkliWHpjOVY5SVZWQSttSDBuMktqcFhkWlhBc1dwQWxJWmNGbWFveVBKbkRoVWhwdExsYU9LcStZbVQKZStncmJGSklJeUNWOVh1UGtCL01QZkEvWUZGb0ZHOUxqay9rTWJFWERHd0lFN2dkRmR1YW9CUXVwcm9WaG5MdHFBdzNyQWdOa1ZMYwpSRkNmVlBQQXdrWXg2RDEwOHB2ZGpaQnJjUWlNRFphVFV4bFVIdTBHeCtnTGtnTzlQY3dwaGRYYmVSRkh5MHdLWkdmSmx3RjlDR0pPCkVKUnBaVFlOb1cwT0dMQ3dtcnN2QTRvU0tRMDdxTFJFUEsvUzd0QlNvc0tmYit0OXFIUnViQ1NBNGJhanlEZU55SUhSeVVqM0NCSVcKWGlhVFRtN1RrclNka1JrQ2ZDSWNpV29TRGlWaDBRaGlrTzdaYmczWHhaS3loYk9BVW1adFlsVGJnNVp4K1VXWlJGckVUY0IvUE5Jcwo2Q285dGNlT1JCR0pFYy9sWlltZU10bEphTWoxT2Rkd214aXowTUtBeXdFK2twRzlhbWRmbWNubC9qR0FEQnNkeEMvcnN1cVRqVWZtCmNKaTNhQW9hRWI5OXVtdlNNS0dKTklFUTNHaGVvSEs4S0tHSVNSdGIwQlc1akNXVk8rdzR5QWVMRVFodTRBcUxVcjNZcGg1TkZEbHAKUEJ3ZEoxaThIeWNXR2pneVpKRE12TnR1UHpRaU9sTEVVbVAwSE9velNjRndBMW1DNnA1UnVFWTFla0orSHplYnkwSGVhTWFCNGRiawpwSzRLdUYzRmJidHA1SVd6VXIzSys2UGdqUllzOWFnaG8wNUxFZmF5OTFTdGRkRWJSUU5IVjhUVEtUWExGbzlTRTFCYi9PVGpma1QxCmlRNXZ6c3NoVlBsSXpQZDJzMzc4NGI4bzVKZUJTREtYMlk3VVFBaGFsYTN0RnBVeFBKbVM1VHJGb2NoNS9vNGxxb1JVa0o0K1hkRVYKSHg5cTRhYm9sZDRRc0YreXV5YlRzU3RURXRnUEIxM0JMUzJVZTlieU9STXgwT1dMblRod1VhMFAwNFdMN0laSU5iY2RJNjEyYnRvcgpSbG9WaXFMV2lKMEI4UU1VUjZBSUZ4bTNYS0xNSHBiK25GQ25SSDJzVGs1eWUxa2pnVkwyeG9XbytsTlRackgyUllaenpNNjVqQm9rCnIvM0JKK0Nna04wTU9yR3dPODM5NXRnNk5TWFJ3b3dERkN5c0w4K1A5WFRVdEpTeDkxUVpSSEVraXVKY050b2dmWGhLbktzUmhzWGwKTTF6bUZhcVRwTStHWWtZQytWRGhrSmZjZHE3OXNNME1SVVptdlFKY1pFWnJzY0lOWUJ0MTRrd3NQTTMxTW5nTU94WU1KWjRTVXRrTApDcXlKdXhOWittUWVGUTFLVnRSUDFJbWpONHlOTDk3ajdHbnhhTUZ0T0lJUnNUMVBoTXo5eGg2cllaT2p5a3dXeithZjVJQU95NGhWCkk4T2lReWZDSUNoamFvZzAwdEladVJyR1EzRFBHTkNoeWw4Nk5SWVN3eFBtb2hvM1EwS2cxYUpkbW52YWNLWkVhU0hiaDVYb05JTlcKOGl6UEttNktxMm9CU3JqeUNUMG1Ncnk2MnFwMXlyaEk5U3lhQ3RnN01ybHFqb2FZMVhkTldISDRoUUt6NnNZdWxBVW5JYXYwMEhqegpZMDhsMzFrYVFORklFNm8zTVc5U05hdUxqZ0VKa1NWTDB5MXdhckppSENwY3d1U1JuS1dxZkRqVWlhK0dLdGhZL0R5TTFMRkxBcGVPCmpxWENvbmx5Wkl0WE1Wdms4TkJnNVR6SkZ1aGVjRW1GV21zNE01SEVoV1VuRE1ld3M0ck1ZYlpJbGUxUmtPZXM1RkNoOW5GWUV2VEUKazRUb2pUbEsvQ1JYQlZnRThYTnJydnpuZjhpVHpScFYrSk93TnNzVWxRVkZxcEZCT2NwaG5kSlg3emxZU25RSWc0YURRd2JGaTltNgpUenFZbE14YU5LQzFDU1d6b2N2R2VnTWNVNnllS2ZtakNEQS8xZ3F3S0dIVUVJYVlES1Bybkc1MmlQVVYxekRxU0Y4NXJnOXEwaURFCklwWnBwR3YxMDQzeEJMS051blVZbGd4U0krRmtPSGlpQmlESGUwYytMQVRSc0xZbW9acmFzOTE3c2hlV0RyNWxydUpnSjViQWNZWHYKdFFrenQxU05ERS9yNmxrUnk2M2tYNlMra1F0M3R3Q2hINDRwaU9FUUNzU0dQdm1mL1JMb282UmNIT2ZUWTlLalhCejVhYXdldXZWdApKNVBmdTVvTkRvY3FPRkZUemJIVnNiQU02OXBUdUNCY0xpZ3FnVEd0NkxmbEpFSjIzTGplbXBEdVJkNDVIRjh2RFlmRHJoalNKYmFZClRhcGFDclc1MG9XR1BUekp4MDNnWWVUS25Ma0luZ0paV0k4VTNzenR5TEw5M21qUGhPWUFqSzA5VGxWd08rWWdPQT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJaS9nblNRQ0trWm41Vmk2UG1mYUliRWxpU0xDcUVtck5KdWtPYjRRRzJPNENVc2hCV1F6d1JNUExuaFMvNHh6RjE2N1BMUUNBMDZrMwpxdS9FQVVJd0krVEVEc2VwUWVXWW11eC9kcVpGbGFYRFNrRzRGK3dRejZjclB4UzA3NmFIbFVPakNhdXF4c1owTVFDaWlhd0x4Uyt3CnBUQmhEejc2anJ4Y3gydnFlc3hRNGRQMERaSW5oZWsvSzNLMEpPQlNNaUZxS0dDbG84NWMrWlIrZlRJa3g0YXl5ZUtwWGZNQUQ1S2kKV0dqTStRc2xKc2Z1TU1WWGJ6VGlqOThQWVV6bnBEQU12UlMzK2RYV3FVS2ZGUjdjMFBLWWxsNGRuaWYvQ0h1R3NvcHhSS2EzOHVOVwp6K3h4dVJ4MmJxN3VvUGZNNnFtMjYyUzY5SnA2NE15a0RSY3FaZDVDaDBHYmt6MjB5R2xCZVZ2dTkzYkdJTE1BVEF1N25lbERBN0FWCkxpaW9aYzJPZVNGOHBJcDZ4WlVnNWdvRlo1M3lZOGY3SGJKOXVnTGIxTFR6M0FhOTN4SEIyT1NHQmU4OUg2YzBrM1ZOdExCUkJYTGwKcXJsSnJnZEs3RHU4RjVNdW1SdFNrUE5mMVduaFVRaDFXMWcrYUxVc2RoUW9FWmt4cmwrU2RVMU1reTQvemFFNm9xSElVenhOTHExWgpSRld6OGh4ODZEQTBQMTZWd21ISDJkUGVrVDNuYUUxT2tFaUQ4UURqclY5VXc1M0graVZkWkRGSEVDNmZMckk0cERNalVvOEJqU015CnhwSlF6bEFWOThqWWxYSmRNYTBSM0NVRGk0Tmd5UDNzS0lBaUFzMTYxNWNiRWNMQ0pRRUNOTjErejU0aHViVFduRkk5eXFXaDlrYUkKVmVra01KSlFlamJkSy96SFdHMTNWYVFtcHMyeU93MGhXakpSVTZKRXRGVURDeVVNc2FNSzVORUJpYm1yN0s2dmlUUjhOcW9vSG9JUQp1TnU1Z2hJNmMxZzVqRUpVejVET2VQeHdtZFZSZEt6V1VFN0F5UEFjNWtoOEVEQU1COUVZU2VTUjZJaWpvSCsvNk9XSisxKzlQc3BSClBndFZNbUtMMU16d2hxRVU5ekZNRktJUVJXTTU1Q2NOamc3d0w1VnZJSk9rR0U5WWxFbWlTUExhREZtZG5wUjNVQjRkM2s1MmRmSDIKa3pLWjE1alJrYjVBK0JLSG1tUG9UZFJVM1F5WlNHd2VFSmVKa2dxdXcxZDh2V0NnNlNNY0ZnZWdydysxMEtzckhCdDdLcUtOK25wTwpwckFRcW9HMmdpdnJXSHBuWVhsbS9DYjhTTlpYWWQyTEgxaEtjc0hocHUrRS9LdjRIS01yOWNRN3kzS0NLVjM0aDB1c1BLUmFxUU5jCkFibGh4dUtiMVNYd0swWUVNMUN3RUlWcVRCRkRuSzR6cXlwSW9JV2hKcm9mTWRQVklqb3RyRXlNY2pQZWpLb1VBSSt0QWFvcVVLSWQKbXhzb1l5d2puQS95UTZZL1FOMUFubXdiNWxDb1NUdHVhM2Jnb2thUkRuZzdVTFRtbW81QWZwY3VRYlVrNzI5dlYyS1ZOc25CcUxjRgpWY214L04zVzFaVHR5T3hQU0tIQlVpWDNmbVdaV2lzdDB0RlZIV1NoMTVCc3JyT3V2bk84VnBWaHAzYXE2Z2FGSnBUWnorSkhvaytmCkxXSHNBRDdhYjR5bVI3bUxrL2hOektFbndnZ3pMS3MydVp5WlVoeFlxUDJFOTdwSFBCUnEwTGZ0SVVjWUNuTXpZOG1BQk55ZHpNeXcKOHdBLytpVmdFeG5OcGtsU3lnZThIR1pFK1huaEV3eEp3bDVzd1RxclZSeXFSbFRzTE1sQ1Z4dExuNUZETXJhSnBIRHJwby9IckRJcwphMGtHd1NrZEJvNzRWUm54dUVncGg1YVZtc3hvNE1HZzhEWDdFMUY5TGFLK3NZQ2h1cEFlRERJQjFJcEIvcG5zNVM5MGc4ZWd5SmtkCmJ3VTlFdzE0SzdvekRZOEVKVGtKRHdJK2xVbUlXSFVKQWVwMnQ0b2JrTUhhOU1JcVF5dTlRSkc2a0hrSENRYnkyRHRLVFFSL1RtTE4KcWFVNi9UbGVaWEYxRkxlSnB1SDBjQkd2MFdSSHQwdk53bkRaTExhaitKRktNYm9OTWZac2E3S3FocnFoVW4xcWZKTFV5OHAxM3lMLwpUTG51SEphYWNzSnhPcHdoVm82NXJMNmpMckFlbWdLdGZFNVE1bUdsZ1B1L0VDR0NSWW92Uk1Rb21zdFhUU0Yxbml4K0p5ODM2Wjg1CnFtQU9ubHFIWk9VOEtZekZpamltYUxFVEVQYmlSWDA0WlZ6MElVZzhxVXVCakl3WEhwWWQ3bnZXWmFWU1JrclhJa0xCc2VTcE1LMzIKM05idVNtdW9idEtRZGtIdjRoZFAvM3V1SmxoNUlWalIxSHZOQWtwMnFXbWlRQXZOQUI1ZW94bzlPNzBJdlRZVkN0Z214ZEl6dTRFdApXeUJBOUlVNkM5VVdwQmFsTnQzdVJQSUV3YVU1RWNGdWQ2ejZWb3JhMVVVT21nVW1ZN2dLVERmdEF4a1prcy9QZmtNOUNQYnhaWG5VClcyNkhodm1MU2c4bExiQVJucVdtajcxcmxndFpsMG9TR0JQa05TSS93bXc3TmYyUGFralY0M2tvQ293SUtNVjg2dFFjTld6VkJjZzgKLzZ5S0U0SjYxQlN2RkVOVmtCS09wcy9hc3ptSmw1MkZMaTBTZUJ0bzB0aTFtVmM0UWxpS1gyUmxGbjZIMjBpc2RzNXpXb21DTC9uWgo4UC9IM2gxRU5ta3FYRWlPQldwVVZidFp1d1VZSU1qdmVxbEtNa3ZsOFZSd2dsWmdoV3ozSnY0azJ6Z3dLZ2xXMHpnMUMwcVVwV1J5CkFDcEx1ak94OU1rWlMyVVNJQkFpMmpNME1iRFdvUWlyUXRycFVkeVEyL0F0aHdBc25mSSsrYVpJSnpMU2loOWdIQVlXNGxOcU1sME0KSzRtZHNBWFNwamdsckZRdnlwMVMzUDdxWHQybVJJM2pqU2wxNDg4SVNGT0hEY203YWk2SlJMY21jYkxhVWQremZKUytlbzY0WHArbQp6TU5DTVFjc1BOdmNGQ21PUFlXeHg5SWtNdmNLMU9jV1BKTXA4Z3E3b0tRUWZTQ3lwMmM4Z3RDU25YbEZVUm9CT1UzVEd6OVdKQXNVCkw2MzZIdkE5alNnOVoyQVB5U21GL0I5LzdoRGE3MWdpcWp1VnZFeVNKMEFyUXRvT0cvQlpQTUo2eUhKWGtVQmNRYmtMa2FwWnRaM3EKVXg5d1hPN0pkN2d3U2hSUmMrUXF1bXFvWGIxYzFPazRFYnY3cUNxWkRXVlNET2MvK2xtcTlBa2ZrZGdIMFJ1cE9nUk1rUUhEM0RXZgo1Ym5pcWN5UFp1VmNwSDl3VG9vcFdnazF1akxIZFgvUXNMSWJBR0ZjVmIrZ01xRWFnZWhoRGdvdDUvMUpEazhEQ0V6Nndha3B6MXJECnFXZ1hqN2s0cjhEclpHMGZia045RkdaalF3d21TRkg2bjF3cnJtRWY5YnoxNXU4OEtxb2lYZ0dTR1FaOHExZU4zSVFhWHNwSm84ME0KNDlKREdqWnEwM2w4MW53QlVrQU5DYXJPVzdGaGR3Vng0UXFzS1ZWZEpCMHRmclBETmMwZlRremxqYUJpVGc4ek95M1Bpc2NpL3BFKwp6QjdzQm9oRytYSjJGTkh0WWFSN2RZbTZwY1NuM3kzaVlTVlQxWDFTZmd0N3JxRGdicDRWcktyd0NvcEVkNEtSRmtaUitsQVVSWHVpCjBSVGpsNCs3QWxSM0lHVC9FR3BJYXBCS1VOU0VsWUFlWnJTd2FLNW40bmFjOHhCVWRxa3lQL0Urcm53RThwdGNKOEU2dTc5a0JqcHcKcnF5bTQ3ZHRsa2VMS0IrczlHaG9aU0Y3cVk3dm9yR1JmdEZLd1NFWjZjK2VaYldjSlVUajhXeWsxMjVhMVlONEdBZThhdndJOTBRcwpTdFdSdy9LaXBNb1MzamQxVlFzMVNuVThMSFpVdjVLbzVKUkFxY25pV21WMENtUWViK2lyMTU3RFlBeUlwZkhDUXNiS1lRcXZ4Mk92CjU0bFhuYUpkK1V2bFQ2TE1NaTIycFhyc0FOUVM1ZGZkMm4xa3B5TXV4TTRiak9qRFNnUUNZcVkyS05tWDNER1k4OXF6TDdJTGo4OXAKa3RlR1EwMlZGeks3UXpsSFNyWkVxVWxPbG9XaEtHbWs0dm1rdWdpZVpLNGN4WHlSU0F5ZlVOd2gxbjh0MVcwWHVrY3M0OUtFSzJFOQoxazk3NXNJMERKNnJLa0xiOE1UOERGZUUxaHBUdGNrZTdhcStWUk1FTGt5bXBtcTkrRmhKa0QzMWhDUk1hNHQ5bFhMYzBKRWk1ZUk1CmJBbkdvV1FXT1FORkEreDBmWUtBRzdpYlpKVDdGQWZIYXFpWmhCRnRxcDVpWm4zUHNxd3p5aUtIS0lrS09WZHpmeWRtNEZrdnpkcGgKT0tiYlQwT1lkM28ycGpxZDdueFhHVHpkRlJvbzI0Tmw2NzlDMThIeXVFZFYya3FINTRDc2ZWa1lmTmRsaCtTYVh1TVAxVzB5Q2NzMwpEUEkwbmtTdzhaQ2RNelR1Q1pWeUZabERFOFpqWHhFaHk4ZlNZWUZYMlJ1cnFPSmQweUlzbXlzQlZBbGRJVmdEZTZMMk9qaldNdjdOCldjbDZWbUQ0QlFrc0VNT3EwaHlyMUJmdG9vY3p1cUtub1VWaWlJU1l0dTNHRTlLalE5TXpqcmpvcWRmRnI0Z3NaUW9QQjRGanBkRzkKMFJweGIxemp6SUFWNVpmcjBmb2lVcDV5K3RmaitRbmI4UjFIRkxKVTdTazhCU3piMlVCVFNrN1hLNkRvU0o4cTZPanRhT0V3aEtPSApxSVIzZ0N1azZYVXRybFY1eEdua1VHS0hPRU9YRG9TSUdPalNydTNZQ3BwbFBzdFNoRzFCZE96czJhTjg3VEg3Y01wRlVHSTJLOGVyCjVYdFk1RHRPcFEzT2RnenZONlZaV3IzL2ZvNzBibHQ1dFp6WUlQT21RZ3VpUy9wMU0rZ3lLMTk1NzJCMzAxcGNkdFM5V1lLb2h3WlMKQjliTFBTNEdBeUhhM2IyZFJGd3JtV0tBbnh6ZWN3ZjFpV2dicmtBVTRTb1pwWWI0TVZFbWtJQ3lKR0E1YWNTM2xVUm1SU0pGWkFvbQo4c29TZ1BJMTVtaEZWbnBNM3l2SVlKT05WZjIyTTdxN05PYXZBRS9QSlEvOVovK2VFL0pMSVUzZVRLWlRZVEdHUzZvaTdIZ2dadUh2CnJDa0NFSzVESEQ2MndjMjZTVXBtc1ZsQmFIVVF4bThLak8xNlJsYkJzVVFwa2RXV3JJZFpUaExxSjVQRjg4ditBdmVrdm1aUjhVK0QKL00vbCt2L1lVV2w3WkJyR1Vya2dWUnRzWnV4aUs5WXM4ZGl0bjJRcis2TWdLdVNDMkNxOERVSklwSWlJY1RxSDFZNUdBbE9jMVZqUApPN3dDVzE0RnNteU9wVW1zNDJTWlVOOXFlcDBab3YxczY3SWtReUFuZzV1VlIrTWJGZEU1bWpURm5wemxZYVZPbWhaaUlkR0phWmVZCnhyRm0zTmkwSWh0ZEg1TjNsdk54TEdTbTd4Zmp4N2JvTXBOaU9pelg1bmI0VEI4RkR1VW56ZDNjeHhZTkg4TXcxYjBkWmhnRytPR0oKMGhtbjlyOHJ3NzhydlZnandIQXJWTCtQNElTUE1tNkRrQlh1cHdMNGNVdng1Nm1DMTVvR2d4K1QwMlFXV2ZxaDJuQnVFd3Nyb0lBWQpEQzJ1S3RMS24vWGJMdjQvbG53WHF4eHJrcENWV256bnczbEoxTEczWGZyVjVsWUhFUzdEcERRNVRUMGZXS2o4b3VheVNrWnQwenFxCks1TUtxa0VvV0tXSnVsclZ3OFA0bnVWNGIwOTdUMElsYUkxZkVQazFtMFRFYmRRZXFxZ0xXY3pOaXQrbllpUWRrRUVzejRjbnhWbWQKRXJlbTJxdGRrSkdNUkNXSUUyTklNemcrcy9uaEVQNUVLRklFZGtMbXcyVWpyeDMza1k0OHdGY3FCL2Rxa1hpTlFuWEFrSHBSZXo3cQpFM21lUUh2TWJSaitvcHMxc1pRb3hJREhsVjVjZ0laK1pnbUhhekpaRC9EWnovcnhPenB4LzVXai9iZHl0S1BDNElYUlJwUXNEU1d4CkdXRkVUSnZSR0VPMEVjMW14T05tYUpmbHpHc3d0RUdGWDEzbFd5eW1nTHRMdXZ4TjBFWjVKc3VlRE5DT3psT2JuNDNsR3Z2djNQanMKdkpRdzNmUnNNbU00ODBjZCt2SVljN096dVZ0U3BRcmpjamo0c0Y5Qi9FaGVLbGE3dWRuMUNiU21zZG1JRERGYkVOVHNadjNjQzVvZApmV2syTTV0RWUyYzRxYkdwMXFPOWlObkhhR0IyZGRQTXpjc0dtcEF3aVJ1WERiUlJMV0pqY3lxdVJTdTJEY3V1Vmc2OFdObE1ObVpWCkozT2dxS0dvQ2xKMmkvbjJBbVZEQml1ZXM0UGNBUkRjbUd5V0NGUVJmcU1ndncxWFl3Y2tHOFhTSEZHRGtVMHBReWx2UkhaekFkRW0KWktPM1dyWXdINTIvaXVvV2J6NDIyNitab1UwaE13NlM1NEZqTjh2M1hteHNBdUJhT1doc3hKL1VVczlrYkt6K2hrOXdZMktaQ3k3OQpjTEZaZEtiY0hCT0lmWVppN0lKaW85OU5zVHlNTXl2b3RNOVF0US9qYXBpaXlkdStpZGljeUxzdzJRUmlzeDdRNkhIaTY2SnM4SVhECmpxcTN6Y01tWlBqYmhtSHp6NlZuczRITnFDcFRBdGdvYkpHVlJZY2dDWHRVMFZCdUR2WndtR1Jqc0Q5V05FeCtiUXIyY20rL0Z3UWIKcXdWMlJBd0c5bExUd0NCZ3I2UWw0Z3VBVFVHTjlxRjdoU1B6dFF2NjlYSS80UmY4ZW5ablpZTjlEVUJFSjU3YjZPdXh4Tng2a2EvWApWRS9qRGI1bTFWbkpxaUZnZ0pjTkpVUkN2Sm5pYkROUkpTSVdKeDBKVStHckRiNkdSZG1ORzN5ZDZFS25FSld5MDBWMGlRbndOUzBTCmxNNmI3ZGE5REE3d05kYlBUMmlHa2IzQ29vY3B5QnQ3dmFyVGFvRzlSajhPYlJiWWF6YkVZT3p0NWw3TE9sWHZxZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJaE0yVExQWWZodEE5cm5pOHVkZXdEaW5vemIxbW01RHVza2J2cDFqcHpiMWU1cmx2N0hVMEVRcnFOZW8xbXRkeUczcU4rV0o1WmMrQQpzOWRWbTNpOVpnalhMdUExakV5QkJ1OGFjWTJSODdlTnU4YlpOS24vZGlVekdqd3JiR1BXOVJvbWk0Wk9lUTBuSDI3U05kYTZUTzBFCjZIbzIxY2dHNWhwbHU0Wnlic2gxZDV1bXpiaHVTeDdiUmx5M2kzRzRoNjVtWmFZQjF3Qnk4S2VEYjkya3lIelJyWnZqY3NHMmJ0TjAKMFVCYnc3Qi9LYkt1U01kUTdoMWc2Mmo0R1Z4cjZoejFLVzJxTlhNVDFDa2FhdDBqYXhwTTZ6YjhTdDFJYXlTREZLTnlWZ1Fhc1AyRgpjSEpNVG5IZVBPc2FsVitCczY1UGFEQ2R0VWM1WkhNUng0WlpWME4zTnN5NlJnMVRzS3hoR0cxOGU2R3N6N0ZNc21iK2QraXJvdXFYCkpUS3NuRDhnYXl6cXBzVm1YRFFnbDZoaUlXT3M0YXlSZzMxanJITS9CVVNrV0dkT1pQTHhwS3Y1N0FsR0tGVmFic3o0NGl4ZkRHdlUKeDNEdEdBaHJRRkthZWRVa1dHT0daMlRoQmxpVGlQSW9qazU2U0l0aXQ4Qlh0K1k4NEUydnhpcUhTTm1BVitQWG1FOE5Kalc3K0tVMwp1WnBRa0J0d1hZTjRIZHpxNkNMN3dsWWo1YUtVcnFuVmRVVlkzTkJxSk9NWTY3eVoxWUJpODgwTFFEVk9xUm5uR0FicEdHOWdOWkRsClJZZGltU0QranBwVzVudGhVQkgrQmF1dWthY1BWald1bFpORm9LcVA0U0pWc3lLeXBrT3FidEhIUGtEVkxRcEpiazUxaTI1VndhbHUKVVVvU21Pcm1ibmczcFpvbEh6SXhFbzdWbjlJMlpsUmpBK1ZmTDBRMXpvaDNMUWpWSUV1d1NqMEExYTBxRm5uanFXSFRoMmcrTlF5YQpONHlueGlCRWljMU5weWFVaEJoZnc2a2htbVRvT2VEVUFCQ3BxdWxpVXlORnE3SGJhT3JhTEdJTk1qVSthR2JxYmpBMUZTT1BzcUtzCmRhZ09XbXdzZFlscDlxWlNJd2wvTTZsclpPY0RTVjJDVG40VHFVdG9Td0pJalFha0tsMDBqNW9kU1MwODJEanFqREtVcE4xRWNGR3IKdnMyaXprc3hvNXRFWFpqUWxEeWQza1JoWms5MU9nemVsbUp5NzRXaFJybThJdWltVU9kZFhCbHdhY0JzMHZyMllsQjM1NzNDOW5DRgptWVZ0OEpvWUdVMTNQVGdFYWk3UDJpRlE5eWpqRTMvNmNjTHVoWjkyYmVxaFR6OU9TRzM0Tk1iM21qK3hweDh4L1E1Nit2bVROM2dhCmZsVjZZNmN4QjZKbjhNWk9WelpsbFk1ZVZZOVZ1ZHViT1QwWmhHN2ZEblA2RVJicklLZVgweW92NHZSeUVqQ0kwMXkvSE53MC9od3oKdmVmeGJBMzRoazF6cTVJdjFqUzZSeHBIZlZqVGp0TnQxSFJYQ2ZraFRXL0REWnJleHVCTUw0Y21BaC9ORUdFYXg4QnpiQTYvN3EzcwpHRy9HOURFY3hQUzJCV0U2NzZyUEFFekhxM2p6cFZFTTBFZ2pGbDRhU3lXMkZ3cTY5TU5ZWktwdnVqU09rTnVZZ1pjV3BxRG1nNWZHCkI4MHV5aSs4OUVOSVl5a0hMLzA3SnQxcVQ0Y3ZEVkxCbU9aOTd4RUx6a2RuSGovdzBnWkhiTHAwRG1MMURaZkdLcHVwaW1CTEwvcXEKN1Z1d3BURVN6Zkx0alphR1o4Q0tkcE9sSC81a3Rab0JEaW5LeHovT3p6c0dXUnBlVVowenVBd2ZreUdHTHZiaTNHaHBPUVhTQW0yeQpOSW9sQVVFOFlHbmNxbVM1NHFPUGdHcnpGMVk2bTBpd3FkSm9TUDgwZ1NKSU1NQ3dKVVhSeFpTR1lLUzcxNEpHYllqcmpOVlE1Vld6ClJ1Y0dTcE0vMmkzR2xQNWJsV3liSncwRDVTQTNUaHJIS2sxdUZJVHp5TkYzcCs4bHlXMk9ZOTBzYWJpRzNiMHhpRlZoZWZqVXRiSUsKa05EWGtiKzlRTkxiR0J4cEtDSllUeHdZYWQ2aVZOOFVhV0pPeWpnUTZlS2lwTTJReGhZTStONElhUmo1VUlJZ0RTSENNK1lCU09QcwpyVTNaSlk2NEFBNU5RWTh1UzRqaURZK211bzArNVdGSDE5RG1CRG9hUlJOYy9nUVJHalFoeWlGdWNEVFdHTkVWazhiK0dCb1pzTkp0CnVLblJ4MmhvZEZ0V1h3UXorb3RUSFQ0M2hpQmo4aTVtdFByeWpINlkwZFRKc1d3dm1ORlVDRkltZnlHajhhRXlGckNSMGRoTUJPRlEKV0FGanpGalBSWXltTVYzY1o3M2NlVzFnZEdJQmFodHZZRFRlTDNJRXJoMjcrb0lZR00yL3AvbkV6OEd0RCtsUk56QWFNa2psRWdNWQpMVEZTK1VTTUp2U0JSYVZCaktha2tzSEZJRVlUNnNNYytrMk1wbFVNWVJPaitYaEdiNGNZVGVrSzgyNDNNcHBxbFZibVJrWlRxY0p3ClZDQ2p1VWt5WVB1dzR5Q3ZaN2c0a05GVXFqNnRibVEwVkRpaUZ0N0lhT3JhQlFNMk1qcVI3Y3NDQXlPajhVNktmSHNqb3lsc1pwQTAKa05Hd0VJS3dtZEZpSTVtVWZmb0ZKdlZYMnNob3FJK1VPUXhrTkhYQ2pEM2Z5R2lxeXhoaURXUTBHMll3dm1wa05BMTh6VzlrdEdScAovUkNqYWNDU2JST2pZV0hkNEFzWmpVc1MxRG1RMFJCcUsrWWR5R2pLa1pSN3ZaRFJiSzRiM3hGcnJSbTdVa2JReUdqRUpab3h0YUdXClIrQ01NZHdBUnE4bW9ldm1SYVBObnBvK0hsNzBhbEhHYkdBME54b0hGNDJqRU9oNTA2TFhqT2RxV0RRRGJvejhCaXdhbDBIUjF3c1cKaldLZ2lMS1RGWTFPN3VSckJpcWF2RjJWNGdRb0doRlJkVUUwSjNvVzRmdzJKcHJhbDZ3dzg2WkVvMCszMmo4YUVnMkRHSjFtUkdPMwphb3owUmtRallxY2laUk9pR1JTa3VpRUkwV3p5emJ6aFRZam1GZWRIU1EzbHBCNzNpTnFFYUZTOTlqcSt2UURSeTVXdG13L04xdHJPCmV4QjB5Szdmb2pkdk9EUnN4UlhOWkVQak1Bb0pDdzNOWHVDUGtKZEJoazRVSnlUakdOU0VKaWlvZ1liV1RPS09pQnNOTFE1Y2NUOVMKZGpzamIySHBXQUtMZ0pyQXNmMW1ROFBxQW1pem9XbEJzNWRnUTlNUVVPbk5ocWFWdFVuQmh1WVAxQmtrYUhqalRHaXQrZTNGaGtiQQptV0s4ellabWFZTUt1cU1BQkZYTi9HQnVPRFRMS2FoaURqZzBLaFNFN3dvNE5HK1FxaXd2T0hSUzhmdjZ0dUhRN0xmTkFIekFvVm5iCjhKZ09zK0hRckM3WldHbkFvV2xoSENqZzBMU29zK0lGaDZZU1ZTb2wwNkhaVTZpNXBsS3lEUEFpdXNzSU54NWE2bFNTMDQySDVuYmsKRXdVZUd0T1IybnZmZUdoNk5XcDFhRHowVWJFR0hocVdHcFRualllR1ZVNkg4ZEEwTURvWmVHaGExSHpxd2tNekZzZXFVTk9oMWRuRApNaUNoZXhCbTR1QjJBNks1T0tKQUpBalJpZEJmWS9ERmlXbHVoZjRpUk12S1Q5ZUVhQjVMOWFzaVJNT2diZzQzSVpvdFVpaGFDRUswCkZnRm1SbXNwWE1aaHFHOUN0SXFubW5SMVV5VTl4WE45SUtLNVlKa3UrdCtJYU1xMHhaTTNJcHBLYm4wV1JrVFRvZy9nWWtUVFN0RkYKTUtJbGxjOW1BVlF2d0V3MHVCalJFc2JyY0ZwTnd4OVpKdEVURWIwVjd5OUVOTDFDOW04T1JEUnVtUVNGZ1loV05PTVRJWm9SRGRYVwpHaEhOY0FhbnVHQkVLOERSamU4SVJuUTY3VXpNaUhaMFpCNUdOQ01xTS9BZCt6Yy9ybEorV2pDaTZRVXF1UjByVnN5dm54SFJXQXhJClNCSWNTVmJhcUFpVWlHaVMyWko3S1c5RU5BTy82dkpnUkRSZU13SW9naENkV3JUTHZRalJMSitpeWlZSTBXd05LSTJRQ2RIMDVIT3EKYjBKMDJvS0JJRVRMY3ZqUVgxY0FlMjJBMGZjSnVYL3dvWkVFWk5vdThOQ0o1SXRIb0NQNWQ4QUJrdmgyODZGcHBUVFlmR2djWDVMegpBRVRESWxuNkRZaUdWWEptODZGcFVGclFnR2habVBDNkFOSDRSYmFtQ2o0MEVwUE1Cd1FlR3BtOGdQZHRQRFR6a0N4VENqNzA2dFk3CkJ2WVpRMXdrd1RZZGVwVEl5TnJZbzhOd3NLRTdxc1Vka3Qxb2FCZ2ZzNXM1czhBZzFJN0IwSkJTVDBXd3RtdlBkcHJVV1pzSzNhUFUKTkxicTFSbXNtd25kM2Z0Nkk2Rkhjc0lxU00vb3E4MHA1Z1pDazZpODZqR3lOM2FUUHB3NDZHMjRhZERIYUJqMDlIeStJYytBT2FtQwo2MEpCaithdytONnFDSHV6U2REYmNJT2dqMUVjNk5HdFBnME1OS2dTQkx2ZEZPaU54QTRJTkVMUFRBa0ZBeG9HTmErN0VORFlMVGpPCkRCN04wTzRFQUhvK2Z0MXYvdk9JRmx1QmZ3YkVSWDBEalg4R3RVUjB5b3YrVFBTdkEzU01wMndXY0xDZlJ4SlM4U0kvdzdRc2V5TUUKQ0lZYURlSXh2UXhEbUcvczgzZ2luV3ZxODNCRHBBMTlob0Yxb1RmenVkc1AyY3huQkVCWm94SEk1eEVmN1VFK2I2UmFFSjhCWldOYQpPSURQNElSdUZuWmdpV2tzTWpJaGo5M0VBalh0K2NNZ1R1Rk5lKzVKZVYrem5oR1FaVm8vVU0rNllCbnVYS0Rxd1FMMGpIUzMrbkdaCjh6eThTbjFobnRuM2VkVkRlZTVhZVczR2N3L0k1bzE0NWluVkEzakdEV1lGalBITytMdll1MjFuSDJGK0F1N2NBNmtiYk9mcktKdnMKM0NNekdtRG5FU21rb0RqdmNlREdPZ09ZcURKZVU1MHg1cVViNFR5alYrTE5kSjdkWXZTOTFUS3lQWWpPa1BJMWs1b0Q2RXk4NWF5SAo1d3hEOTAwa3pubUdoT1RHT2MvZ1J3Zk5HWFVPVE00RnpCbkVhdmJqdkZET2k1SHNja2pPV0NvejcyV1E4Lzc3NWpnZm96SE9RTHBFCmYyRldiczFpWXQ4TmNWN0JTUXFHTTlhUyt1cUQ0WnlvYlhjenU4MXdobFVMbUlpNlVYMURrdWJPcTJONVpEanpidUVMYVJPQlZJRncKaG1Xd2ppQVl6dHlHSC9waE9HTUcxZlFRREdjMGVIZXBMdEw4V05Qd2hiajV6UitYUjY3SXhqZnpsSGgzQTkvTWd2NFp2T1ZkUkFLbgprUmNkL0daVzlFOURzTlZaTUVYWDdadmZ6R2ZKUWduem0vbEtOQU9pSlY1T1ZqTysrTTFzRXhsWG9GQTNQRDBPWlFZNGYvV0RmdnpoCnZ5akFtWEZCVXE1dWdET3RsRGdFd0ZuUndwSVBzSmxoUURXTHVCRE9ERmRSSHhRSVp6eFgvNElSenVBeDhnVzVDYzY0Y2hVWUJzSDUKckdhRDRLeHZlbW9DUFlGWmRueTFENlhNV283Nnk3WmpsdDNPU0h2RkxNVmgyUVJuR0tRYUNJSXppMGZWOGVFaU9PTXFwVTRMZ2pOZQpPMEdiQXVFTTEwNkNzcHZoZkR6WVlEano5UXlwaGdnUFpGSU1wYkEydy9teW11SE03cjBNL1FmREdSYkp3MjZHTTNFUFZCd0Z3emtSCnErMEtldlVTaDZDV3c4dk5jTVliYXpXR0djN1U1YW42MVF4blBGK1ZJOThNWjFTbmtlZ1ZDR2VVYWdtWDdnTHI1UVkvTDRBejFHWEIKbDZmSER6ZWFRMGZ3bS9HZWNIMXk4NXNaNE9Gd0hmeG1CbmpFSmZCb1FVdHpEZWlwbHFMVnJYMnA0K1N4V0NRZC9HYitaSlp3WitPYgpHYWlNWnZRcU9Yc2VSUUUzdm5uTllHd2ZlalBLYVlSWE5yeDVEcTEyTjd1WjVUVTg4d3Zkakc0d0FrR2IzQXpwSkN2MUE5dzhvdkx2CjVqYVA3dUV4c00wamlwZUQyanppNDdtb3pWallMQ09hR1JRWkp0c0dzaG5rUE03N043RjV0Q0JJR05nOGhzdWlqV3NHSW94Qm1rTnIKUnRzWURzMUJhNmFzZ2lYL2hqVjNCeDlmckdaUXVoZzNDMVJ6TDI2OVkxQXpzVjVENWRDYjA4eE9SNDl3enJ3c0hJYXZZRkNhMlgxKwpLSm04MDNJOUtvQ2p0SnBpUDBNWVdCZUpxNmlQR0FrYjBjd3U3MVdmTlFOUVNOVHhXd3BBTTZocjlFQnZQak95ZHdRakI1NFpFQUhHCnhJTE9YS1A4OUlZelF6WTFTcWp4SVBNTHJ6RFF6TVF3ckZCM1dqUU12UTlMNHdQTXpGWmZ1Und1TS9qQlZCZmRXR1pVNEdxTllDcHoKYTk0cW9NeFlGN0hFOEdZeXc4Z0ZTRENaSVYxcTVpaHoxUXh4azBpSkY1SVowd1RCOUVGa2J0V0Z0ZGR1cW1pOWVjeGNpaEhnWUc3TApYamNFanhuS0VzN1NONDRaVjhCZkN4cHptNmU3TnljVDFGV0pvSDNCbU52d2x4WXM1aGF6VjZDWWNUN0ZqTWFkQk1lc3dnS1RJREZqCktocVhxTE5OZDd1NE1jeHczclg4TjRVWnB5WkloQ0hNRURuTnRGNE01aFdMdEdBd3J4YTk5NHhnWHQycDQ0dkFEQzJ4Q21rTllGN2QKUHg3OFpVRWJ3ekMzVGxqTm5BeGZYczRGYlBZeURQRmJHNzNNUkFmWEJvRmVqbVRFSmk5RDVFWHF4dzFlbmlNNktwaTd2QUt3R2RqbApGWUh3aTdxTVJJdmVtNzRqOHNFY0NEVXoxeitVdzkvVVpWcEZFN2NNTHBHRGE4V2R2Y2RxanNsTlhZWjFzZUEvcU10a1JQbTlrQ0JpCk4wRzVvY3ZYNFF4ZGhrWG9wb0F1cCtSQ3R4ZDBXU3VmdFE1MG1mbG15azREdWl5UWdaVmxoMDhQUDVEQ3pvQXVNdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJemNzNUxhRExYejNJQ09wOVAranljck9wRjNONUxRRVdObklaVmZPc2p3bmlNcHlIWkFUejFob2hIY09VVWZDV1lWQnBzbkhMMkkwSgpxcHUyek1MWWVsakxLNERKZ1ZCV1FQRmlMK3Q5aGtpVEphK3hHYmlQNUFZSGFmbEtuRjJrWlM0TnFJc0kwaklYWkV6aEIybVpZVTZYCmtHNWNNa09kQWs4YnRNd3pVNWU4Y2FLYVJ0dDkyck1ieXF2KzhUQ282R2RFaVVkMjZjbkZXV1k5aCtxdHpGbm1aUS9XVjVtenZDMDMKWnhrN2ltd1NuR1Y4a2FUN2I4NHl2S3FxcXBXTHN3eXIydmtHWnhrV1NuazNhSmtPT0IvUkRWcW1sNWExR1JPRW9EU296RTJZWlc3QQpSM1pqbG5saWpDUUhaam50bmlTQldXWXBDQWZkQzdOTVkzVVhCdEhVWU5Gc0pjd3lCejBXbzl5WVpUcVkyVUw5b2hWRlVzbjJ4aXpECm9qS0ZHN1BNSmJEbURHT1dFd3ZoaW5TOU9nbU1IU3hkdURITFhCUlREeDJjWmF4a1dRTVNtR1VsZFV0OVk1WVpOeUdwSXpETFhDS3AKVzRReHkyU2pWY3MrVDhROWgxWTZNTXRrbzAxdnhrZWJnd0oyWTVhcEptRjB6SmhsR29xaHlnemdjVWVobmkvTU1qS1d2di9HTEVNTwpvczVOZ1ZuR05ycGhOMmFaYU1VZVF6eFRuY3ZoOGhWc3B1VVl6QTFaSmsyTGxUVjd1OVlzdEEvS010YU5lbmx1eWpMankyUTlCbVVaClBxWWNqYUFzSTNhZ09OaE5XUmJYYUk1RFdhYjJUNStnS2N1MFVFcC9VNWFscE96elVKYkZ1Q0pNeEpSbDdxa3lxNHV5ekJCNXdMWVgKcGU3SnE1MmdMSE1oS1hqNFJWbVdmSExOUTFubTZVZlJLaW5MQ0dBSmYzRkJsbUgwTHdxeXpEQ1hUc3lRWlZvWUVMb2h5N0NLOVdmSQpNamZUdlRCa21jZE9iaXV4SWN0YzNZak5Fb3pMc295R00yVDVHRzdJOG1VMVpCay9vQ2hMd0pNWkxsSUMvNElzWTZrbzcyNXZsNzIwCkNzYnlNVnlJNVcwTXdqTFhjOHJWbTdDODM5Y1hZWm1wWnhJR2dyRE1rbmVxQm9Ld3pPUmh0TTdZZWtsYWwzMUJmZlhJSG5LMUpNSXkKYzREeFp4VFBTS251cDJHdVkzT1dMUURMM0lZcjNodXdMRUh5VElldzdDREhQSVJsUnFybUo4QXlzWjFQam5ZRnlYa2hJaDhDc015dgpMekw2VnplYmFzY2pBTXV3OUdKMWdFaW9yY3FkZWdHV0dSc2ljU0FBeTdSb0hoTmdtUVlKRFM3Q01tOC9NOWFCV0dhcW00SzFRQ3dqCkVLQkt6aHV4VExTVnV6T1FhZ3VWV1ZlM1FCT1dNZGFwdmRsTldLYXVJMGZ6Qkk0Q2NIMlVYVGRobVRHVGt2SWJzUXdybWVBYnNVd0wKSDFJd2xtbWhRUEZtTFBONFZPVUVZNW1SRTVWWHI3aE1GL2E4R010MGFMTjdTVGc0WnU3T2hpd3prZEJHOUdhSW9XZGJBN0xNR1c3MQplaURMdkdmc0xYOVRsbUhWaXhhVVpWaWtsQXJLTXJlaEJPcW1MTlBLUnhXVVpSSDJSaitVWmNvSTFjdmpLbm1qTkpMMTFFRlpobktICnc4cW1MRE03UTRmMnBpd3phczJLKzZBc3M0Q1hDc1NnSjhPZFlJdXpGMldaSzZkMEdWZW9NUUxLdVEwM1l2a1lUYUpDYnh6eGNneFkKL3VMVmY5ZUZBMi8zMHc1R0RXdUd3cHVidm0yOE1wNXdtWHJFb2l0M2R4dDd3Wlc3bWF1YnJkd2RNTjVvNVdsVXc0dXNQQjBaM0lCawoxNmtmc3ZLTWQrNEdLMDlHNHU2OXhNVGRWT1hwOHBJWFZCbEZZMVErbWFuTU42VGxRQ3BETmNKSTlVMVVEdER0QmlwRHU4VWhMVURGCjJmV3ZOMDhadG1uR3Nwb3VkUEYzQXFiTVBOSXFiNVp5ZHVYTVppbkR3SFphZ1ZLbXB0NGg4UTFESTUwYXF4aWhsTkVSWTZ4MG5lQ0sKdGU4RlVrYmhBc0d3d1ZFT1BOTEdLSmRvOUh4VGxDR2NZb2c0SU1yVUI5ZDVHTXJBSjYwWFFMbTBjQ0xOVHk3UmxEZnd5VXd3T1FHNgo2Y2xJUXlzN1pYZ3lLZ0thR2NzTTZ4WFRPbTUwTW15azhRVTV1WVRRTDhESnlFa2htdkxpSnFNVUp2cm1jbnBGcWtFWlI3OUJLRG9SCklmdUNKdGRnT1FZem1WRzlOUTR5R1hvUFpvbHZZaklTT1BTNkE1Z01DVXEzSTA5SlViZDI3b1ZMN2srUUVFMUx4bTZNakFjc0dRZG0KYU81bUpUZEwxallxdVVYUHpTQWxOODlTTDFJeVd0eEZZb0drWkdoWW1Pb3pKeG41NTZGLzM3TXBWMW1QdmlHc2ZvZEpUTUZJUmxmMQpyckQ0cnBqQXNpK0hiQXNmeXpBRmEvT1JzUmY3b2R4NFpBUmNsRUUwSFJtT0FSbnNBVWVHdms0bExSY2JHZGZhWFF0QlNDb0ZLazBCCmRRYXFJRDFnZ1BrR0k2dGlySDdiWEdScUJwem1ZZWF6QzF6eGdpTDNhQWtTVE9SZC9oNUk1RzRveG91SXpBWXFQSmFCeUtkWTJUemsKNGdMWUZ3NjVCaDR5YU1nZzlETFZHRERrVmc3b05WaklCSzF3eGFLSy9CWk56NEtFM0VLdGVvT1FZU3pFR1p1RFRQWUsxeS9HSU9PMwoySmJpeGlCWEYyTnNDaks4TkhXR2RDS1N1ZXVscGRkbUlDT0x3Ynh3SUpCQnRlRjNGZ1RrRW0zWGJ3QnkyYzM3ekQ5R2hZWkltc1lmCmsyWm1odkdtSDI4WVVjQ1B5NGlwejZrNUdBaHF2ZEhIZk8wc0RlTzhBclljNWRzQlB0Njg3NXQ3akpveTFSdTZLS2RrVDB1aUhtY2sKcEl4c3Zwb0xPVTRWekdQa1padTNVaSsvTGhibkRUek9YYXIrelR1R2dSQjk0WTV6Tk1hOGFjY2YwenlyQ3cvc3VKb01HYXpqeGdGVgpOWDRiZGN6V0NtSEVYSWo1Z1VXdVFUckdPNTJOSzk2ZzQ0Wkt0NmVlc2tJTW00T2ZrREhIaUM0OTVpTnZ5dkZpTWpSOTI1RGo2azdlCm0zRThWQUw2Umh4L1RKakxnamNoanBPbjVTQWNXMmY2NGh0UExxTnN4TFFsR1o0b3lNeVNUWUo5bmJTTGRURmdJbWxKVVUyNDhmUkMKTHVER0VTZC9vNDJsK3pwazR4R3RDZ3cyenRIaTlzVTE3cXF5T0ZoakN4TTMxWmhKQUpVcEhxZ3hreDVSbFlqRnI2R2ptMmlNdHlJWgo5TENCeGlnSlcrWTZrR2VNOTlrTEVYMGxIUHUwcHRrMDQyS3ZLV0RHT1h5QVlCbXpSdDBqYnFDTVVlL1dWVzFKVHdtTEdyNlNtMk9NCmdqT2psQytNc1NYZFFURnVEQktrQXpIbXFvcGxxamZFV0FxU1VRN0VHQkhVajNWYVB4Ump5am1mc0lUc2lWclIySTQxQkxEVTZuSXgKUHJpdi92ZjM5TzR4K281WVNKdGlYS2NiVGdiRU9GaGxtMkhjY2tocEw0UXhBZ2pGMUVsNjFjQmRVTTBUQUdNU09Lb05JWlVIOGtKTgpndXRtWUFpcUd2VGlscDNKdTlqRkxiUUZSaGNqM1VxOVo1Q0xrYU9VQnZ3Q0Y3ZG1mSTlqNTFDTDBzTXhrUmo5aHlPeEY5amltU0s1CkxCc1JzWFVjYVBGS0NpQzhtTVV3c21vaWtNVXIrbmNFc1JnZ1YyK3dYZlNWUEtjR3JoakZXQXJlZVN2OEE5TnhONng0VHJkRURsYngKcHZNR2doaG9DcnFYTjZsNFBQWm93Z2loTUhOeHdTbmVoaHRUSE1aTktSNmV3VGQ5R0NKZXJuNXZTREhFdHdyazJEaVQ0YVJDRko4LwpMMEp4R0RlZ21IRGxWUStmZUFSVzVNWVRRNHdzTXBEcHhLTTVZeDEwWWhpbWVickhLNDFlMzhFbUhxRk9DaER4YU01aDNtUmljS2NDCmFZelhld2IyUDdqRStHdzJlamV3eExQWm1RNHNNUTNsd2hJemZwM2VVT0laSkNjemlhZmJnUVdTT0ZxSDMwQmljQmlWblRhUEdKcE0KSmhxTkk0YjZrdmZ3cGhGdllGYkFpSWxjWkRyTUxPTHBEL1dGSWthcFVqSWhORXJuMU1RMFNNUXdaRWZQTjRpWVJzeEV3U0VHMDRrSwpFbU9JVjdFRGVGT0kxOTBXRVI0TFVjOGpIUWd4Uys3eUcwRU1QQmREWEVFZ1J2cGVsUm9HRUVlejlSZC9lQVpITmZERHk4dXFUUjltCmxTQnh4QWMrYk5iMFJnL2poRlkvNE9GVkpObDljWWZ4dWJGWUxyRERLMHBoZ2pwOEhXWXpoMmNrWkFNNVBKMmEybnpoR0FaZXdHR28KWFVVME5tOFk1TEErTG83d3FCNUxiOXh3RC9adkdKRzFacXc3WU1QVW5NLzZaZzBqZ2ZTNDZUQkNIZmc3R1VnOEpjQncyZlFGR2taaQpLa3FuUlVOOGxIVFltR0drdUpwNzFXMHRUM2VnZTBPR2V4U1dCV040RzI3RThER2FNTndOTjlwOFd5eHBrMm0yR3pBTUtEN3h1VjZRCm9LQXAwSXYwVktxTDhsNXdZWkNqVk5SdXRqQldQQUpXR2kyTXRWQk9iN0F3VmxPcDlNTVZ4cG9yOE1QOHlxckZCQytxY0xNb1kwT0YKZ1JscTdTQ0ZSOUN0RDFFWWdpWWlKUU1vekxXWlM5dFkxa3h5YVpsdm5EQzlzZFFPVFZncjJYNWd3bHpyanZ4bUNXTlZ2SXdtNXEyRwpRUVg5UmdsWEt6TmZKR0VBcE9LOCtYMUVIbXh6aEQ4N09qOStSeWZxLzM4WTRTOTQ0RDl5NVBydDcvMmozLy8xZldBYzZBOS94Zi81CnMvL3JMMy9SRC96MGg1Ly85SC81NWYvVnNkdno3ZS85czEvKzdDOS9ZNi8vNFM5Ky9kTi8rc3RmL2Z6TDcvLzYydjZQL2NZLy9hdGYKL3ArLytPVnYvdlNmL2VGdi9yM3B4MUczOE1kKzRILzdpNDlUK3A5KytZdC84Mi8vK28veWttUFRQL3k3UC8yNFFmL2pYLzNoOS8vUgpiWC82NVYvLzlYL3l4cmpJajd2eUY3LzgrLytNYS96eEQzKzVyeEZWM1IvRDR0OTZqZi83WC96NVgvL2IzM3lXLy9DSC8rYnYvNlB5CnAvL3c5My91L2ZCM3c5OS8ray8rOFB0Lyt2R1MvZlhIZS9hNzM4bjhEMzc1TngvWGRmM0RELy9rMytGZnB2N2xIL3pWZi9qMy96YU8KODkvK2sxLys1cHYvK0piK3V4K2ViMy8vNC8vKzVkLzg4QjkrZUlHaG4yLy84OGQvL044ZnByLzVWci85NDIvL3gvLzVmUHR6YlBuUApmdmpkQktPUS8rL1gvUWZxZ3JDUS93a1cvRUZ4N2g4emYrenkwMzJjbjM3NC9jZXgvOWNmNEZ3endmVkFmNWIxSDFoK1Fwby9vTndGCkRPaGp5ZmV4OHNKL2ZJekRuUmJHNXY3bG4rR1lrTkpYMUgweGlKVSt4aG1lSmNaM2xHb2ZNNHhWMkt1SkFNTEhEOVpQeHE1MmNELy8KOERZREZmSHhDKytqb3BqbFkreDVuNEdOT3NDUU9QNjlyWU5QNzZNZTQrc01qdms2MjNQVTY3cSszSU9mZi9qWFB3Q3N0T0JrZ2lySwpmQmpVUFFWVEsybmhINjcyUkluRXgvSVhtWEFVSUMwVWNYN2MxL1I4KzhmN0VjS1BUY1FuUDM0Rk9EdTAyd3dqWk1YUUlLcHIyY2RNCjlEWW1wVDk0YVpmNUVTWGlkZFNQNldqaEpYaWRRUmgvL3UwVCs4dVBLNDUvWVAwVEpybE1rRTRjdTl4bW53V1dySk5GRkwyblQwYnIKaC9ZWjIweVFWLy8yT21yRGVxR1ViNjh6Q09QUHYzMWlQdVAvK2dMLzhSZTR6cHBOU3B1TXBIeXN1NEd3UVRGQnhidjdNUTRRQnRpZgpnZGc2NFFFWUxEUTJBSE9ITFA2blcwdEJSV3J2VTRBb2dVdWkrMlF2NDMxaGwvbmNoT3VvNTNaZFozRGYydWpmOE41MmtxdjI2YWpICitEcURZNzdPOWh6MXVxNHY5K0R2T0RiOGpxY3lRTHo3ZEY5eDJ0QnJ2SDRmRjRnby9ldE1MK045VlpmNTNJSHJxT2RlWFdkdzMxZjgKQkZ6bjk3YkladVpQcit4bGZKM0JNVjluZTQ1NlhkZVhlL0JkWGxsMjlYcmE1L0VMZ3c0cTFsN2pWMlBZcXJ6SHI4dDRqMStYK1l4Zgo1NmpYK0hYTzREVis5U3hGOW50YmxuWitQdW94M21kd21jL1pucU5lMS9YMUh2eXNvUkp6Q0pRK24yNE81cENuZkRvSXBvdktMK1FlCjNJL3hOYmdmODdtTWM5VHJnczhadkc0T1pyeUJRT0pyVy9MKzE2ZWpIdVByOFJ6ejlTajNVZStIL3VVZStPWmN6KzJlcTY5bmZPYnEKOHpaY2MvVmx2T2ZxeTN6bTZuUFVhNjQrWi9DYXE4OHp2cmZkYjhOOTFHTzh6K0F5bjdPOTNzZHpYVi92d1pjMzUzVnpybWQ4T1RMNwpiYmdkbVdOOE9UTEhmQzdqSFBXNjRITUdyNXR6bnZHOTdYNGI3cU1lNCt2eEhQUDFLTS83ZUQzMEwvZmc1ODhlU0dNZmkvYlpBd256Cnk2dG9UTEYvY2tzdzIwaVA4VFpia1BjK0trdVgxbnYrRCtNbkQrVGVkbnNWOTFHUDhYVUd4M3lkN1RucWRWMWY3c0hmZlpvOFUrL3IKdmg1SDRmcjk0MUpjWjNvWjc2dTZ6T2NPWEVjOTkrbzZnL3UrSGtmaDNuYTdGUGRSai9GMUJzZDhuZTA1Nm5WZFgrN0JkNWtteit6Nwp1clhIVjdoTzRYZ1YxOGxleHZ2Q0x2TzVDZGRSeisyNnp1Qyt0Y2RYdUxmZFhzVjkxR044bmNFeFgyZDdqbnBkMTVkNzhIZC9aYzluCmdFOW5sQzlEUVpoZm4zZEhxWW85Z21Qc2dvRjhHZ3B3cVBxTTkxREFaaGFwdmovRU1INGFDdTV0OStkOUgvVVlYdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJWjNETTE5bWVvMTdYOWVVZWZPZkZ5T3ZXbnUvMk9vWHpoVjhuZXhudkM3dk01eVpjUnoyMzZ6cUQrOWFlNy9iZWRuL2g5MUdQOFhVRwp4M3lkN1RucWRWMWY3c0gzWEl5ODd1djVhSy9mUDUvM2RhYVg4YjZxeTN6dXdIWFVjNit1TTdqdjYvbG83MjMzNTMwZjlSaGZaM0RNCjE5bWVvMTdYOWVVZWVHb0hXUWdKbkU5K3p4QSsvNVB6WklYNzI4MDZ4cGRMZHN6SFF6bEh2WHlaY3dZdnYrZnJpVGtjTXI2NDl6eHMKK2JUMjRRbG8yMnMxY1l5dmxjY3hIMGY4SFBWeTJjY1h6LzUxT2pqRmY2NVE2ei84L1orL0FxMy9LZkhYOG5lTHYvcU9mUXJDbmxncgozckEvWW94OWYvcHl0Qk9LL1RzSEMvSHVkcTNlcVh3cForN0lqUFdGMmZNQmlKVmVaNmYyeVlnMWVXMW43ckFaNi9kUnY3MlAycFQrCmY1K0JqWHZ1V0dOODJuWkk2ZjArNmpHK3p1Q1lyN005UjcydTY4czkrRzV6Qi83OTA2MmxOMUUrblFMOURyN1kxOGxleHZ2Q0x2TzUKQ2RkUnorMjZ6dUMrdGMwNjIvZTJVMEsxOTFHUDhYVUd4M3lkN1RucWRWMWY3c0YzbVR0WXRmSHB2dkswODZkWGxoZFlQcjJ5bC9HKwpxc3Q4N3NCMTFIT3Zyak80N3l0K292YithZHRwS2NQcnFNZjRPb05qdnM3MkhQVzZyaS8zNExzRnNsQVo1ZEd6ckJPT1lJdkFiZjZkClJ0dzhhZ3ptWlh3eW1oYTh3eEUyUHlvWWVSMlZnM2VhMzE1bkVNWWRqb0JvOGIxdGtScjJmZFJqdk0vZ01wK3pQVWU5cnV2clBiakMKRVUyZTczMXpPSmUyVHdmaHROblQrK2N1NDMxcWwvbGN4am5xZGNIbkRGNDNCelAvbk92VHRrVWxZZStqSHVQcjhSeno5U2ozVWUrSAovdVVlZkljVjkzNDVJbHQ1V1R6aHYxOUN1d2J2aDJYanA5ZmwzbmEvQXZkUmp6RjlmbGZIU1ZEdFJ4U25lRm5Pd2E1WDRmenNkY3Z1ClU3eHU3N1h0ZmhEM1VZOHhmWDVqZklyZjhjT1BYL3YwNFlmNWRZTjREYXQrTXZwNlA5M011RGV2bzM2S1Erb012c1FoOVNRL3hTSDEKME82akh1TjlCcGY1bk8wMW5KenIrbm9Qdm56NHI1dHpmYUxuSU9mUlhEOTNHZTlUdTh6bk1zNVJQOFVoZFFaZjRwQjZoejdGSWV2bgptM01aWDQvbm1LOUhlWWFUNjZGL3VRZmZZU0pQMGkxK3VxL1YzVHZmOTlYZDY5NzM5UmhmOS9XWXp4MDRSLzJVcU5ZWmZFbFV2MC9zClNsU1B2bGNYTVFYZzJDbmZacDlGbiszVEZIQ01yeW5nbU05Z2ZZNTZEZXZuREY1VHdOY1QrejdEd3ZhTXcrWDd0RG9JODh2anB5Zm8KNU1BeDJoUDh0RHFRMzdxRHpENnFQZHozR2RqNGFYVndiN3M5L3Z1b3gvZzZnMk8renZZYzlicXVML2ZnK3dTWjVSYS83dXR4NHEvZgpQKzcrZGFhWDhiNnF5M3p1d0hYVWM2K3VNN2p2NjNIaTcyMjN1MzhmOVJoZlozRE0xOW1lbzE3WDllVWVmSzhnc3ozajE2MDlmdngxCkNzZmp2MDcyTXQ0WGRwblBUYmlPZW03WGRRYjNyVDErL0wzdDl2anZveDdqNnd5TytUcmJjOVRydXI3Y2crOFRaTzRSaFpzajljOUQKUVpoZm56ZGpZUG5UVU1CNFdadWZod0ljQ28yRTNrZEZGTzc5R2NyMGFSZzQyKzBQK3o3ZU1iNSsrNWl2OHp6SHZLN295OVYvNXhEQgo2NmFlTC9ZNmhmTnRYeWQ3R2U4THU4em5KbHhIalp0MS9mNjVxZWRyUGR2dHIvbyszakcrZnZ1WXIvTTh4N3l1Nk12VmY4L2d3T3VPCm5nLzErdjN6U1Y5bmVobnZxN3JNNXc1Y1I0MDdkZjMrdWFQbkl6M2I3WS81UHQ0eHZuNzdtSy96UE1lOHJ1akwxZi84bngvOS9PZS8KLy8yZi9mckxuMzhicjhqbmYwYnNzK1lGYVMyazV2Z1BNR2wraFJXNE45U3pIL05Qbjh6dFk5SFRxOHpuR0w5dDNZZjRQYy90ZXdoVApYK2N5MUlKN256bmNRSnJseThrNGJIdjZyTGExNTJOaFFXTjZxRytYbWJXR05MTkYrK2NyOTYvOUJEK3pFdVVHTGdCNmxINmNlcDgrCkRkUzNmTHpxTkpQQUxDUDlRUDBrcWdwa0pMSkJQemhMbk1kZ1AwQnQybVAzanlGcCtkSlFSaVBqeHdyVXY4OWF2OWo5K2ZnUS9mc2YKYjVvdmVlMkRLdEl2bzI4TldSQnhGOWpTeDNjc04yL0ptbTM5UHFveGZMOHdubXJMUkxxbHpPUWk2cmJnZWZxazBKRlZScFRmK2FxZQpNSDQ0OXVmeTBSalo1Lzh4SHNlbWJYai9jd00rUFlBZjlXVHl3dzVpdEdmMGF2N1ZWcmFTcHJVcGxDL3JTUDQ1ZmVNeXJoWGI1dDYvCi9kWlI0OWZtbjlUMCtCK2VqNFdCZjI3dTE3R3JlNnFOV1FjQjdHcHVtMTREZzBGL2pQM0hpQzJmN0UzWnhVZkhaSmp4dDM0L1Rnek4KWVBTRTBXYWtGcDhZY0p5NnVLWWlVaHRSKzJmamFtRjhZc1BGK3h1YkxwOXY3M3QzRkJqS0JvVDJiLzcrZit6NXNORUt6ZXhuRUErSQp3RlZ2WGVOWlZML1BiTGd3LzdZSDlBQTNuUDJkZmJ4YU1kS2gyVW4zUzQxMXFXMTdhR0R2WEJqQjBXditKTmd5N01mWVArVnNNMG9DCjQ2RHhwZGFoczMzWURPTExkNzZFRHRQdkkxTm8yOXpuMVBmdTcvUDNoU1hVdHlYZmRiYUEvelhNVCt1WCtTZWJpYXlSK1dNMStzM0cKN2tmTTFoTzJvUkJkeGhUajQ5ZGY4MEFJTGdES1RmVVBZTjM5YW5NQ25rU0h3WXRnWTA3K0tqaDgyUWpJc0o3YzhnY0FhNHJ4TFkweAp2T25UWTNRaGM4REc5SGgwWUdvNURoQVBzK3RSeDdZamJnNGV4bTlld1hsMXh0TThtTEtUWGJ3NnJGV1Z1UTNQZXl6STJXYmdER3ljCmNjVWx4dU12eDQxSE9sV0FyWnUya3VlMlpCcTB6TlgzY3FvUzA4K3B0REEyRHpDRFk4RW40OHc5NzcxekdOdGEzMzd6NTMxZTZBUFMKdTZiMDUxRk14ZGJxTDRQUm1EQjZXbGdqNVczci9nUldxejR2ZHV2TVBmYlhKNlFXbmkxKzY5ci8rdms0cmUxcGdEQ2FQQVV2QUJwawpiQ3ZHRVJobjgzTm9WWGVMeHNldkNFSDhYNHhsZVdiODhsdCsvUWtnS2I1bkJYbWlYOFA4ekI3bXdXdWpjYVRmTU9ZUnhuai9VWFpaCnVzZlpqS1lETm83d3VQQ3AvT1lKK082d0VWb002dXlTK0t2Tk9SZWZCRWtZTXNhOGp6ZXNaaHViUHhaOGJUNHhTYTFHekVJbE52MVkKVmVUM3JQTDFCTTUzeFQ0akdoTFgzSjhWdTk3RWlOajhxYkFOaDQwbHZwK1AxN1Nlc1ROR1ZLNUlQWHBxZW53SVMyMnhxZWJjTDc5Lwo3dGo3Z24vOURXdjlqVnZ6TVhyOXE3amxvNGNaczhwUFlVWnJKcG5yRTNlSHpXTmtMSG4ra1Z1dXQyeXFiU2x2SlNlUlg4T2N3azFnCnRiMk1wTHZLT0hRZldQd2JiZ1lCS2ovK0VPWmNZdHVSWXR2Wi9HTk43OExYRTRneks1TEllSnpQZnBqczlWNUx2RkRObjJFQmd6S0YKZVNUOVhoRml6a2FOUlYrUDZ4OUV4ZmFZNjlyNlY1dkRKMmppSmRyWTloQ3A3K1hEMXNyK3RSYnpHOHg1blRQcnNTMGJHK2drMGd4agppZy9XbzZSL0MyT2dqeHUvVld1TGcyclErWHIrY1dHZ2J6emorckZmd3h4dUdLdWlaUHVZWDFaTTVuT0ZjV3lmc1V3UFhEQzNlQklzCkU3Y3hMbUZsVGE2d1BUR1FrTXo3NDIrZmxrZStpYTQyc1lDaDkvQ3J6ZWxKSHRXSEozNFlTN0ZuUmVLSmpSNDB3TGZ0OXF5bWNVSTYKYnRJUzRzTlllNDhmKzFqU2Yvdk5NN2g5dnZnNStORXh3SEM5ZHp3NUcvTzR2TFBmSGg5c0JZN0wxaGJ6ZTdncDJIL0ZvUE5IUEw0eAp0eU9adHNjNFJoaWY0NGUrVHYrOCtuUXFOUkd1dUs1b2R5TnppMitOMkM5TjhaT1VjZG02YjRHUDhKdUg5ZStoajBiekJYOThnZlpHCjBPOWlMMGNuOENRL2hmbXA0M29ZUHNLb05ZeHkrTDRjTmk0dmlZYjErZkt5ZUFOeUV6U0N3N2E5WjFJeFpVdzlKaEIrS3ZFQ2svUW0KTXhhQk5xNjhEMURpQVBtSjUwNmN3WSsvZlY3bkN5QSswUzl3S2VjTHVONXJyV0cvdnV6LzZtL2Y5blhjZi9IeGcvLzlmNkFmZ2llNAovQVRwcVB4cU0yTWtOc3Y1WEJoK2l1OStEQk5zNFJhL09CNnZ1OUVldWxhL2NzUjdhZE0wVXR5a3NjSklKaFYvS2NXeWNMSi9RYnlECm5uUUFYdW5KSHdJYlBNaEl1SitNTlc3eVhBcXY2SzE0dFBZaG1pVU93RmZGUm9TRS9aanJPWVB6SlgxNGFIRW5XdzczWWE0bkJxUDgKSkwrcDlrdDgxejErRHF2SlpRelBGWlRPMzN3NnNUdFYxL3FTUGFiU3VIek1qdzh0NzkvM2htbFB4YS9CN0ZrZU40ZldhdlFIZ0JtUwpMVUlzUThRLzdUKzBMS3M3cm1WanhNU2VHbGZQNXVNeWdtd1J1N01wbDNZSE52QW5tL3Z4bjNLT084QndudzVCTWY0bkk1c094WEZqCm1UTGtUc3Y0NGR2NldwTlgzOU5YbzZPMnZUdkRVSDRBK3ZweFVpc21BNzVNY2N6WVhjVE4rUGxZVVFONEdWZkZodHArVzNNY2dDdEMKais5eFRoOXJtSFZ0R0VjbHprbmZ3SGoyK2RkNFYrWlNGQVN0SWVIdzdjRkwrL2Y3dFh6OHJOSERjUHBPalRTbmphM0h3MmE4VUFkbwplOGdmNnM0dTQxbysxK0xRR1VoSkk4V1lXTUpabWVnc0VZZGx1RURHUEZNOGdPR0p0d3FPcnhONHdpdEF4OXhTWXJUSGZLd2JXLytrCjFVOURMWmxLeGMrZ3lBa0NRNzV1WDMrVnVDOVZuZjg4TmloSUFVNVRibkd1Y0VYOFF5M09kWnpIRFZ6TW5INWVYZE14anByaWpXOTEKeGxrOS9VbVhNUTdBVm1lK3J1bTVsQTJSNHoyeUl6ZEpieDZmWHMxOFhRR2ZzUTZicnhlK1o0M0UwKzNpUER3cUxEdXprTXIrcFlqcgpUaEQvWW5BaWNROUdFRnppVko4d3hWZUlTZDhmNFRDNU4zd3l4NFRHQ2Z1TlAzRlllcHlBaGRsUDNyRHVlU0E4eXc5ckhmc3I4ZzM0Clk4ZTBaem5VV0dIdlgrTXI2SzBYYjNzQzdsdzRlTXZWWTJJdXBlOERuQmhjckRySFdSTVp6Z3NqSnJWOUExTHlYUjJhQVgydTAyTWUKZXNpbEo4SVZjdnJIRUxIVkg1eEdZclNUV1BHdytabnBxSWlzeDB6UWNuRjhpQTN0NG8wamtSTkd0SnlJRXl0ZVlZeXFySnVudmVvNQorc05jZWpoTzRTdU84aWZka2VLNWwrTURYWGhqd3h4ZjEyQy90ZmhtS0xxaGtSQXgvNWFtVGRLQlp6eFpMRWgxZ0x5RDgwQnZhdHdICjRLbUhCeDNCWDlBQjkvRFFQbFk1K3dEaE8yQ0k3RzI3amdNZ2MyMDk4dHhtemlQMjBWSTlqdVp2KzUrRXV2ckYwZlNOUTZTMXg0N1MKdy9qRTlORkxPQkFmWmc3bEh2ODFKckt0eTlxdjR6ckdKKzc1TTN3QXRFR2Y4ZWFSOHZhVHpXY0VqVFV2eElNbEZnUGtVOGxJRXBzbgpDM1lvMEFIR2RpSStwb2djQjlnZmVzU1MwTW5RVXdpQXFSRkx3Z0hLZnFFMXJtUFRGZ3VYK002Nm1VSWVKMHJlKzNPNXBQMzdpbTE1CjZSNFVGRHpyVTExdy9JQ3pYeHkwTTZ3eFVueDhXbjd1NkNMZFl1RkNud3JHRGE5U0FGQm4yMVZsWm1PTUlLd3pDLzl3UFRNTzhPekoKVllNcWRpOWxSNEdxWGE3dUZKWEgyaWNlR0ZDdjhTTEVZTjNWZTZxRzEremR0eDlaKzdQMlVjTzUwT3BSTmhMci9FdDZCL0E3MitGYwpaZXpkQ1dDTGp6L3ZreW85bmxlTXk5MWtQRCtESEtmRmhoYTZWNGlBN3VQbUZ0UEZxaHdYZTFPSGFXN0xrVUxHbUxCdnB3Zm0wajIzCnNsdk5UemFIM3oyMVhJQVJoT1BoUmNLSHQ5bHRqRWtmdzBmeE5BSnozdDlvejluYlB2dkQ1UkFJSXpwaHJIQXh0VkNWdWZad01MencKak5LaTk1c0JldWJhazN0NHpwMkl1bmkyOWpyWStpL2M2VjZWaWUxWjVWa2U4Q00yakFPTVdJM0dSQTR1K2Q1MkpFM1BhTnkraC91NQo5MDg3YkFqZlh1NEZhKzduL2tBMW52VUh6YzlqS0NnUk1rRnZ6QkYrVjNPMjhjTTQrZ2x0K0t4Y1Z1YlpjZFo5Z0RialN5Z2Erc2oyCm0vdWo4YkJ4d216K05tSi9FcmM5dHpXUHlSQkE5cGdnbVdpRkVWVGZ4eTlNVEdQTmlRRVA2dUc0d0h4bVFyeTBQOWxjOGhPclZTeW0Kdy96c1lFN3ZXbTAxbjd3TzhXZ04yWEE2TVVhc0h1Tko2MmoyR1c2cElyMTlSMzA4cFA1T1lkcDZ1NmtSR1g5bThvWHBVb3VwOFR3aAp1K21rd2JjZUgwek16czNOVlR6NE55OVZBSUhmdHpEbVp4anovc0sxMUFTMTd3blhONVY5QjgrSE1HUFhlV0ljTTg3ejJkUHlUSEZHCllHK2YyNmxmZVhaQXg3RHREeU1BaWc1cFd2TEJlUXN3YzZUQlpQYmNTU1IrZklQaDhLQzliTjNSdlNlOGVZTEY0dz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJdUI5UElRSmJRK2hoMzM0Tnh1RHg1NUNkSkh0WDdEVVdRL0ZVYnNUbXNTTlFqZ3JVZHNVUGxpTjUwU1hBeHNqT1YxTmcrV001NnliVwphZ1MwN3pUL3J2dWlZbndIZUQ5dkI5ZnBPR3hiOTFRdzlhSVEwYi9kNjVUMi9vOUZMZmh0amZuc2JyeUhNRHdnR2JzanNYWU45VmkyCmN6alZhTnViOXIwcFdtVDVvRSs0T1FsQnB4OWoveDNWSVJCWXhxZEZzREdWRmNZMFkrVkdUeTBDY3ZQWmQzcHB2QVdyY2p2TlZCajgKN285SDlNRDhDbGVQcTBjWlc4cWZyd3NBOXUwNjdWaEpQUU91b3hhL1U3eDA3a1dHbzEwSTltK1p3RmxuSW80YVg4WU95ajlxa1BpYQpjcGlXeU8vWXFzeHhZZWQrbDdVWGxIWnliSXdCM3owVFphMGVnYVlXdDc5amp1WjhSVHdWR2J0ajJjQzlacDhBRUxKN2Vvc29QUkcrCjRmNVovRU1lYkd6WVl1SEVCdUF4T2JHM3ZIZmZBWXltbTFxc0x2TFB4MHFpM0Q3U2JCcEdQb3lNWHR1ZlV2UUFMZE42eExDSUs5Y0IKMEY0Z1hoZjY4RExXczU1VHhoOHQ5cmJNNm1PSkdQdlhLOXdWVThXSE1hMklBRVdTb1h5ODdqdHNUKzlZQjhCWHRGZHpVdzU4S1hJVgpkQUpacnhBeVdjOStnMklZNFA1N1JWb2o1MFVKNXZGSGJhekhHMjFuOTdiMnp6OG52M2FrV21VcXFTaVNmOGpnMm9yRHhzM3VFRDJzCmZkd1B6Mk03RFR2RmZQei94eTR0K3JLUGU2RWZhZXUrWXNBY3JVU0t1NjBZYjJPaHo3NkFFUkk1TDFaV2FrWFdPRmY0WXR2cDhPQlMKM0wzTXYxL1BBYzRhYWorWExOMmMzeXl0Zk5GUDU0bnh1WTRucmlEZEFTK0hrR0RjOFI5R0VuVFU0Mk1PYUpQaUFCeldYODRZT3Y3RQp1cWdVWi80VGN2ZzdZcHpxM2o4UyttN3I0VzFQeWp2dVMySkhLTnYydC9WZ3RvbmZ6d3BWb012ZEUyL1JJMmVTc3ExSXp1UWMzbWhlClhDTyt2b3g4Ui9LTDE3QXc3dFg4Y1lQUW4zUkZSS0dYV00xL21NdStMWFhya3ZLU1BNN20wTVNGbnN5OU9XUnNPdzFFYlVVSTVVYUoKUVkvaHRKOXNQbTRPeTNYQ2ZBSkp1WjF0VnppRFQ1UFVBai9uaSt0YXkzakwwbXc4amxLZWV3SEJsbFo4T3pJKzRkQWZ6YWw1SHUweQpaZ3dRSi9aUDg3ak5YNDBmRC9wZmVOc1dHWUZsalJyYlVLVklFL1FTUnJiVDFaYW9Zb3ZmWWxkVVhTM2NJQmtqYnNvK05TTU9zRU9CClIvbVd4M1pBaG54akdQc1ZzaXJkZWtkMG00Nmg4NFFqY3Q5KzRjbFU1SHVlS1UrSm81WTlTN2tkZ013blpzWEE0MDgyaC9CaDdLZzgKRy9SVW41anl6dG1kOVh5dU1TV3dCWEI0S3pVcFVZNmZ5aUUxWkVCRFc0WUdjbHdyYkpqM29pSWxUUjh3bnNCaGt5NkFYWU4zc21WRgpoamkzVzhNY0F0R0szNDJiK1AreDk3WHRiZHpHb3VmemZSNzlCL2EyYnB3bXBCZFlBTHNiSjIwc3lYYWR5ckZyNWNVOWJhcERrU3ViCk1VV3FKT1hFK2VQMzQ3a3pBd3dBdmk5bFN5SnA5c1VpaDhBQU13QUdnNW5Cd01WNFNHVTl5QTVyeGlRb0gzV0Vvc2N4VVpIRjJpSlYKTHJaVDJjY2xuWkR6ODFCRlpqc241L0VWbVpTM2VwbzVDTVJuQWgzS2hBV2ZsRDZPSTdNTzlDTUh6aFJIcUJvWDZDTFJsTWhIZWVVOApCUkpQeDF3L1k3c2NQdDBvZUxwUUxua0g5R0plT1pNVUFuM2tBRVhGV2dUQ1Iwc0V3eDRBcFdMaklybkI2amJhMUZ0SWhYZnR5Y1JtClhROHM1TmhVSmJKSm9aaFlvNVVGdXBnVGZDYlFtemhTTHpkRWlCak03TE1rRmtpaGFCWm9NZ2JxbkoxcjVOZndrWDNldWNaR1BIcUUKbEtNTEtiV01CZEliaTJGcVdRU1pmZi9hclRwN0doUE9VZWZZYVBWSWtVVnVZM3AxeVllRmVzcG9OK05vMHl6M3prempnaE9OalZOMAprOVk2cU9oVnk4eUoxQ0xqdVlSbGplRTRlcmRoUmpHc3h2dVRoWWtGZFNwQ3ZHcnVLQXVCNUZTV3lSWE95dzFBZXFMWmtoQWp3QVhCCnM5bnVnOEk5VGVFa2o0Y1Y3T0tqc0d5dW4yamVyNVQwbldXL0c0WWhXaE9EMFA3NGpJOWY4ekZKdUhnZnl4bkZiZ1NCd29mRk9zY2sKNFpPZ0diTUx4S2gwd05SSkRtZm9aTHpCSFVablprYkE0ZFBzVEVKZzdqY2dIMWlySXc5VllzKysrTTZKYngvV3RXMGZYN3VRdkZ1aQo4ZExXVjk1UmpmY1NiQndOdm5YcHdob1FhQmdyekh3NXhWazhmZk5oTjVXK01jRGx4WnppMEdDWVVTS2FuWXlBM2x0eGE1OE45ZlNHCnJRL1F3ZGRlR0J5V1E2cFVBUE0raWo1ZTYyY1NvSDhIRjZxd1J6aDhwOTQ1YS9FeFNNb0U0c29heGt1dk5GcWdOOEJ6aUQvQ0ZKK3IKM1B1d0RxMzNnN0NqUzZUV05PdGtuWnNJcWUyTGxmWVo3MWY4T3E5VFNtMVJhZk5jV1ozT0JVMUxlc1dROTBXT0twWTJ1TkFpZFpHVgpJdlp6K2ttUFQwejZRemdmb1FWS2NGYUoyWDJLUlROdnN5eHNGQWdDdGRjdGZFQzZqRHdvaVJ0dllSVm0yL3ZNS2tjaXNZNWNOMTBFCno2SWtzck56L0NXKzVaSDdaWkM0VzBTRnRSdTZrZVoxUVBIZU9WOUFLUXpIYzhFMFk2VUw5NXAvY0ZtdlNyRjVKSEZQUjduZFJuSnMKS3MxZVMxWWMyK29Wamx6N0tGaS9nMUVRVWQyRnJ1WFI1bUdyNTlZNzRCYUg1S0tzeDZIV2FsV2JKSThGdHpZQkFia2luRERVcmlnSgpDamQ5N0RZeDc3WkVjQUNoZmRuZHhNcDlzQ3Z1OTRhdlc4Z3NrTW9HYWdRTDlyOUk3YTltQkpkZnFxeHFnbGk5QjEvNWUwWDRzQXlqCjlYSDRXYlFoc2M2WlpKR3pqTjdIc1FqUXBzUENyQWozdzlDMHg5SFFIUEdReE1ZVjRaejFpRUJ5VUIvczNLbnZtSDErMHdzZDExdk4KeDAwaG1kM1NCR1U2Qy9YcHdVWGJBY054TzhSRzZUYWF0SmczdUc3R1NDOXlaS3FpS1ZNNEJCUXp5SmNjS0FHY2JjNmY0bkFxdTdPMAo4YzRLQkdxdmlBamg1N2V6c2hucmplRUpydDB4MEZnaDY0QStSTm80cDN0UzJIZDRDYWo4aFNrRU8rK1VzU1kzQjVRY2o4MHEvYXpiCkYyN2xLaVpCUzA5WFhyRDZIMkV0Y3U0QjN3L0RrcWxoWU02bkxSUW9obnRBandOWklNY2FHL3NNa0FVYWQydzJWZ2d4QXZLbldMRE8KM1BnS3diWmhaNG16UlRsWXlkaGJVN1lnV3hxTjlSc2V1UHJrc1NRd1Nnekd5dTV5ekNpWm1nRE8rWGpKZDUwQVNJRzh5dCtUc0VDVApGVzQ1cE9IeUVOcFU4b3g1YXhnQmgwWVpLK0FkMXN6ZnMvRDNFbEhZRytZWTM2MmhmWWxQMkh4RXArZkFEZk9yQ0pzVis4S01EY2x3Cm14VnJuc3JaTUxGNjdxZDk2alYxTkhaeCsvVE1tZHMvL1UwSXIzU2hHNGVCdEJueFhpdWRwZzdkY3Q1QWZBZzdaeDAxMVlwM2NPbWMKMGlZNmc1QmlrUHZCTFZnem9CeWxLcjZMc2VBK2xPU3JqdVF2dFVBT2hhRFhibGx0eTNtdzBpd29YWEFBWVFLODBtWVM3aE41c3B6YQphdGdZa3JENFJLZ3pXMmovbG8xVmtpVVB0MDBrTTZaUUc3c1pXS0RSR2ZkS2E1NFlicGJZTGpnN01LcjV6a0dFWGNnWnFFSVBOQjhPCjUxK1hZeFhSK0VBeVBGTW8xc2hGNms5TGlXZGhjT2NKcDdNcmUwdWdZSUtENHpHNmhrZE9UT2F0YyttSTNGOVE5QmM3SFRnVGZuNHIKUHB3RmtlWk1PaUlmVy9nY3VJZmdqT1ZrbGl0dWl3M2Z4bDdENUpiNGdpNnBraTFHSUpnSlh1L0w3ZHV3YnJkd0N6eW5KeE1kVWhOMQp3Ri9zby90S1J3NmNKaXdvS1pDVzBYcUpsdVRjRm5zRWpGV2dHRy9xVDR3eTk1ZmtWRmhoeXQ5OVU4YmZ2UEZlZUJHMGllaHlZdTZ0CmxzWjdzTEZiWHFnSDh3MGlVTXhGVnNnQWFEU1BMYXVwTSs3Wk9iQ0xJRGIybnR0NFdXTXRQUmFZdXhCb1krMmNiRThRZmd2aElEV1IKMitnY08rT1Vab09FczZXNjYxNWNuM0wvaDBWcWdieFRPS3NWQS8ya1Q5bXZobWFLY0QrVGRlcWk0YStHRmU3YUJGbytKTjhPTFRnQwpHODBrTEdRVGR6aEdJNHZNK2FxS2xteGtrZjQybnZSSENnQUxMN3pEdVE3QlJlYVhqTC9qelRKU0ZuYXJSSmdMUXpPUmpZVEFPZ2JQCkxEdXpaRUF3VnBhN2xlWGFuNW10OUpUQ3FpUmpITVRIRlhsSGtKcERWUW1hOHc2ZVNHOXRDOWZpNmJLZ0JXWUpLMTFTMm10ZUFHUjMKWVh6UlVlSWpodHdhNytzU1BibWVYenBueTZCSWVhTVEzak9HQnNQQzMrZDFZWWI0ckxTL3V3NHJLbk5BY3R3NEVyd0RJWTF1YUJYdQpEQXZBUEdmMWpQWTNMcGt3MEhzWHNhenhWNTU0enFUK1pJWjNZKzNxd2pjaEN6WWVKWkVabEk0amRzbzd1NTd5c1VQYTV6REFoOXo1CmJsYnVUNVpvbk0zODN1RUhCaDl5bHJ3dnBnVmpEVWZMeE4zNGxtamY4SHNFcmhoR1MrWWVaVy9lZXdlSzltdE9Xd1d4VG1icklLUlQKTGRqdWJkd2xMTHlSbndack9vVkcyT1lTdzZaNzZXK0lzZjBOamZ4K0VFTkFnRVM3VzhSRU8yUFE3dWN2ZithR2ZTSjhZMWpiZ0NQMgpLR2gvWTVFamdoQm9XSFJ6akw3RVFBYkRVd05uTHlNb25LVnFyQWVGUDVOd3BBbTZhaFJQWkZXd2xvM2VIczFya1I0VnQ4QndTWTdOCnhua3NqaEsyYVdHNkJwMTZpWjV3MlZUd0ZVYStaVGMvM3dNN1lMUS9SOHFjNzVGcGVvaVR5MFdUMEZmV25IK0JacjUzZGlVOGpUT1YKTWxIc2V0QStRUWMveG03SHhYdUt3bG5lWlhCWVVKK0RET0tjQWVqYmN6R3FtQmRDYzFxSmNNL1NuVzNucHBvd3prS2tmV0FnT2gxegpuNGNnRVp4cmdyWEFlRlR3eFhxdGZWOVRMbHV3R2t3M2QyMUJ0dnk1WkFOY1h4dSsvbGs0YXhRaVZTb2VBd3MwN2s2UXRpZEdSaEN1ClZYTllUaHFPYWJyaHRBU3NML2dlTG1rc3ZyN3pxbWtNOEdGWE1Qa1ZDT2p1VXdDTVVrTW92aGp1UGNrcDAwOWI0SkVEODdrY0pZYkgKQ2dzZ1k2QU51MFd2dGVadVNSMDg1TnJuUzZBWUFVYkxKMVh0cjFjQ01OTktNVEJMUGRCMWxwUis3emYzYzlCcFA0alRlQWE0S1l3RgppMEt4ZU9mcGl1NTQ3Zk1jT0w1STlwQWJObFZqTUlGa2ZZVGN6Tjd0SCs0UDI3V0tSWFBKbmRlS2d4RVNrekhReHlSUjNBSFhWKzVHCklyK2RiSUZ1TDhVK0dXWnFHdWFLOUs0RjkrcTdBL29iek01RU8rdkN2d1ZuT1NlWFlUOGhCa240MVdhY1RvdWhIMTZJMHJwbEJPR0kKeHZHaStFQzE1T1dldW1nMURCTGg1VXAzcmpoMGhHOWphT3NyY3ZVRmI4VSt6aWIxT29xMmxsTkdRRWNIVzFaN0JHSFQ0bHRWc3k2SAp1N0x1YUlHN1F5NTlVQXp0ZHVOTEhpK2Q4eW1DWFVHcGlzNWNwTUZidk1ydlpYaGU1ZXFxOE9mRGxIRVdMbjdIYnZ4Y20wM3k3c0JqCmdXem8xdmFoYVF1a3kyQ09yTUo0QlBSeXRwT0RCUmVWL3BLL3RwNC9Lc2pYd3BYM3BXRUlWUkRaN2hvZ0FqUFd3S1h6cGFYYVBtZHUKRVlTSUZPMVZsMmdRdFhYbVdtQWlHQ3NsUkhWck1OU1hJZWNRWDhKREJCbXJqMlM4WUREYjhJTktoQmdNVDI0T2NNQVlNSmM0UnR0bgp0VDI1eWllb2NOWTFCRW8rekxMMmhWajVXT0FOSGRnK0wwUDdxcUhqQ3lkd1VPNE1oZUZxR2VzTU1tSHRGY0ZlOGFFSXB5TUgxczYxCnJuMHdiR3E4ZVJFWngwRjRmUCtCUm9NSEVTM1VmbTVrZkZjaGpTTS82R2FGQmRKdEtHWk02b0JCZmZSbkU0UTZodzJnVFZ3Z0lzYWcKZXNXQnc5am1aNUF3UEk4eTNqZlFzczl5RC9iRm5JRWVRZUhQN1FET0ZmY3JrM3hvU3d0TzU2VHhxR2haVTNoUGJUamlBekQzaHp2cAo0eHNMNnd0MlN6SHpzWlFoSFFOTEtEeUsrbk9CaUNJc3M1eVhRdWJTZmlBQ3IvMFo1N0ZBWU1vSDdOeTc1MVRpVFZzaHA1WUtsNjl4Cjl0aHBPRCtoaE00SzFuVmRwRFpkNEdmYm1NZzFJK0RBRTJObERTTmdLV21zRk9leTNxeUVscVIvN00xRVVhY3cyVVR6dEpmT2VJSFoKQmdyMjFKS0gzRFltZkxTejl2ZTM4VUs5NWdPZU1vYXYzcy9NVTVGRzlza2s4U0hNS3RWZXNiZUdLWXhMVnB6anp0OXhSS2czbExCYgptNHI2ODRKTFVVVEpwN080Sll0QVJjbFVjdWxqb0lPeldtYzJya21GNkJzVEJSQUJtT05NUXNZcHhPb1RRSkd0eUFMWmRVdG5tOXdqClVJblhvS1JrQkR6bmpMMEtVS2U0ZE9sOHN0cWFnQzBDN1NOd3RZM0lPM0pndmlha3ZmVmJhVGEyaEF4ekNvZFordz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJNHhYTGI0VlRUZmw5eVlTeVh0U2prdktESzZ1OGM0UXNqWFVic1MrOGNRK2RJeGFvbkhLTWRtYjI5S25NTG0wM2E1VXJLbjNNQXp2MwpWZWFqeTdTMW8zUDlZUEpMM0kxMVJPQ042aXBKR0t2eGxramFqUmxCSmpsVlZPb1ViT1hDOGxWc25sUzV2MTZnYmRBQ0krRHJnZHE2ClhQamFBbnNGM1pIZG91Q0R1clkzV3kxUTVrSFdpM0FkUXBvZ2tyU3pJNm5jK3lhMERWRjNRTzltNDZ0MUNtV3FGd2dwWDFoVGhRMkEKY3R4MUlUeXFpSncrSnMwWmcwNjl3eUcxOFFrS1hWK1M5UnMrZkdDNmRpbjk2WmNka3pxSlVzQzVHenA0K0dHaG1EclJBY0RDRzFISQpZWHZncW1mZXI1bmtWaUFBa0ROQ09JbGlnZXdZMWRhV3p3aGtFYlpYd2JkYWd0NlRPWE1nQUhQRG94RHVmbUJacGtvSEFncldPL24rCmxvNlBkR1RwNStxNW5reG9xTVBWVTdyOTUyQWg4eUdwYXJhKzhMbWtjQnUyR3o0bDNPY3pyY3VWQjdEUWZlMTduM3FzMmtaWUlWRFoKNkRNcmQ0eFBjY1hDSDg5amZNa1Y4eGFiekNzY2ZCMHF6RmN0RmRlWFB1eFArS3RxbUF0TDhtQlRrSjhGY3U4TjV5UFRYbUNReW00cgpHNS8yUmR0SW1pTUhscEkzVUhkdXdJeG1pYzlJNXBSK0JFcldwRlVZVXVQRnNmYVplYlNKNW85MFNoQ1d6SVNiS0ltUG0wU3dZSjFQCjV0WUJnNWZKQkV2TjFLVzEwb1p2MHVNNVBhclBWKzIwdlczQWROSDFHTmJqY29laEVJWjc0QzZwWWJDTVR5eVhzLzFDWjlGSlVSVCsKVnA3TGoySkw4NDI0M01iMnVMS09Cem1lRi9pa21QTjFYZ1Jyemh2SmpuMmQrN0IzWktLMUZ1RmR2OEx2YU40d28xR1J5L2lvNkt6QgpKdkZpeU9XZnNzQ2N4U09wZ1ZRZmJ6RjZrVWNYNzQ4Y09KdytpUGQxdWtmSjdsRE52akVqdkJQTW5WMHNXc0hCTTdyaEwzRUdzNHd6CkpDUE03NGJLYjVKR2VGMUgrL1JRQmswbG5HK1M4MndZNFNNWXRKVjhqQ0FzVGZLSFc2S2t0ZXJhS2VPc05VYmF5NWRPNHRpNVpWTHIKV2JZTU5LeVpFWmpYcHQwT1Rlb3ZQbXViamF4dXI5eEtOa0dDdXNCTUNUZHh0UlVUUnc2Y3kzeGl2aGh0WTAwY1pRbGZVaGFLWjJ4MApxZHhFcDMxSzcxdW51OXVaNEFYcW9ueE1jTmRwdTh4cy9aQmhGMXZWWERRWEV4WUV2SlB1VFJBVXNzRDFNejhHOW9pRVY5cUQzOWdkCkdoQ1lDWC91WVhNTFhYL1A0elhBbC8yRkMyclEzdmxoQ3NwUzZHYTc0TGJZZGE5dHVnbEdtOHZDSDZCenpubVFSRVorVHErRWFSTzAKOFhZTmUwYktaSlNKa1NKV0NDK21idkNtUUZZK01NMkRadXNTQjR3QU1DUWJwY1hMQ0RJdlkwbFMySTZsTmlUYmtwRVduRlBDeXowWApRNWNwbTREYnpUaGVjVkNTZzI1MGRLY2NTa3QvK0JMYUpTRlJVVXBrWjU3S1VPVk8vVEdQRTNBb20rVEVpZFBDVGRtTVpLUGt5V1ZOCjE1bTJkeGpkZ05uOUtBUFJ6WjJsK0J5TEZrOEFpdXVuVms5Qm9HWlhxbklPL2N3RUJuZ0RYMmFpaEsycDA2S3pMSElyQ1plMUtzdDgKWWhSdGc0SXNnaXlLWUVoZHh0Y3M5eWx4dFUzMFo0RjhGZFVkWlN5Q1BOcm5OQWV5Wm5sa05jdGRMQkVCL2VHVGsySHdpYVZRSWJFTQpweFF4L3VvTUF2M0IxU2U4eU5tSGlTY0xsazFRTkZpR09JWXlLNkpvQk1xelpJRmFlMCtadit5RW1XRWttMmdwbTJMSWJPTXo1cnA0ClF3UjZ0ZHhaY3pPMEh2aTAwNFl2MldJYW5jemJocHdYRllBcVJMYTRTNXM1SHQ1OWVzU1FyeWZ4dVV1MFRlVmhnWm5rSUNCUldQRUUKd09DbUNxb09ndjJ4anpYdFBMSFhhQzFXbDNNRGdWNWtCTmJtd2tjZEI4TU1wUkZpTGtwM1ZzaEZISnRUOERrSXdkNmFXTGd6VXg0dQp3bW1iaHF4T09Zc1NyK21RRXNBSVFrTEozSXJZWFBpNFJEdzE1dHlCTkFuV3ZUeDBJSUJaelVDa0tXc1UybDNkeFpKZUxaTSt2UStWCjVXVkFKMnZYMmNJYmxKMUZHMU14OGRLa2JkcldsLzd5cnJaSE9nZFVYckYwbHhrcGxSTjNsT09yRVNpOVBvRm5sU01IOXJ1QmRyZHMKRWViRkk0c21BSEllRWxSKzJOMmFvNEJXdnF6aHNsbkJDNG50d1FBTWpwSW9KWnVNWEIwc3MvTTAwcjRveFlNRmh2eWxSSXRGZ0ZZWgp2Nk1uWEoram9aMVRZYksrRDdSQmFPWXpWNGVXQk0vQjNOMGZBeUEvRWVEeVhuTjk2YlUvc2gwNm9KOXFMdmxkNnFORVlpbElZSi8xCm5KTUtwdDR2UEk3QXUyOXlIMHVjcHo0bFJGUldScm82WjNqQkFmREdWUm5OaThLa1hrK3pkNWNRcVRmc2NUSXRHaFJtUU1oN2hYd3gKcktjSVRocVorbXhpSVNJRmdHeUlOWGJ6WXdSaEsrS1luRnpGeHFQY09wc3dvWnBQOTA5UG4xc0V5c2R6NHc1bHpRdDViR1ppZDIrTwpoaWpXVVh6TUFlYXY4MWRUcEJKY256SWhxZGh5ZzhBUURPR2pWQkJCTURlNnpSVGJ5dmtjeXlsdXFBTitaQVdibVhMalUxR0YzUUN6CjdSVXNYM25ud3J4OFJ2aStzcEtSWjFIb1lwSTVkcG1RY05pTFRBeVU5bFlpbnlZb056NWJGRTZ1akRQTm9VR2VsUlFPZE1mc3R6NWsKcitBc21GRjRoTC9YbnhmK0htWXdNQ05RcC83TW5qQ0M2QkVGdzJweFFVK3orRGxyVjBjaHJBRkVXVXVaMVFhS2NLNElrUmhGR3FsRAp1Wk10Q0N5OFI4YWR3UUNZaDRBL3pWWllCQWMzaFkvSExKVDN1cU9OS01rOU9OTWNXc1ZpRHpVcDd6TFVMdmtReldudkFHTDloZVFYCnN5c2NibmkxT1EzRVlxVm9LTGJSR0VlRThkZXFYVVNvUld2c25VWVZXOU9KZGN4d3VzeHFnU0Q0T1RiTU82SEkyR3ppWWJUOXdtd0sKYkh0M3I5RlljT0N2ZFBtSDZQcUVkOHk0b05JaTg5ZjF0RFZXSHpnRVJaWk02QXFZbmNjYnJsMk9Uc3cySVRsckFCMUxiWDJYQmNXcApGVzUrNUQ2aGl1R2NRcHlWMFZJbzJDZzNMMlYvbW5LR0JYNkxoakxyV0lxZEU2L0lRbUt1M0R1ajZVNlJ6OE9ZUlp4U0lSY1FaMHFtCnkwS2M1SVB5aEFlMityektxWTAvUVF3NVh3dmttdzUwcWNXbjB4UjhjNVd2cDlteTdzMkJ6TDg0RStYa3hRdGdmSW1kOWdhZUJibFAKMmVXenlaTVE0T1JIV1NKNElvSVU1cWJjL1JZc3FUZ1RRT0ZqMFFzWFFPNEl0eFlGUkJDeVdXWitkcHB3b1paVFY1QVAxRi93VnpuWApWNFZQNE9RT3VXVHQ5d2thL2MwcG1qdDhiNGZNZUE3b2N6VFFWUW9MVEhOT29oVTg0cVErZXdRdUJvYzJBbjRveFVzdTdZTXMzWXpnCmRhLzlGWEM2cE9qa2hyK09xMTAwZlRILzdRcWZTNXoxMkVJMWZBSlpUaElCc0pBQ2k2NHJIRGpCVldTY0Y0WHZpaGNxem1mcER2UUkKZEJsZzNMTnRYazRhbndEVk9TUlFKQ3UrVWxpd25FWWxKRXhPUGg4Z1dETUZWZ2tycEw5eEdsSVRJVEF0L0pwaEpiSUlJYVdaVjhJSwoxRmo1cWgyY0U1UURxcHdUUmxORU9TTlF2RzdKdEdoaDRRWS8rNDBMWVUrbGJwbjVJUlRldmg1eXJTQ0N6TThCdTMvVDVzWEpta1RtCkpRU0FDNTlvMWFXcktVU2M1MVZuRFBUWk5LbFRYRDljZGN5ZERST0JCVjlMejl6UkZZRDhva2h1azEwd2duQi96eWtnQUl1U1VMa1kKcWdJOXJueTFOZHlKS1pJb01RM2QySEJsQmFmbzVFd1NtQWZjTUsvOVUxdEZlT1lxOTJrWXB0T0wvMlB2YkUvVURwM2lHaVN5d2czeQpmQWJZOElrbUJ1YXpnRjZaazlFTmJBNnZHTXVPUzIrcTFlT3prOHZnM09MNm5yNm9xQXJKS3p6T0NRSmM2bms2S2ZLVllweEdqakswCjFQSUZaT1VQb0J4NWt6VmNBalE4RmFjc0pCUnJBWFNBOWhja25VaWtvdjd1c2JzMGhEaDk3bXE2VWVZUkpEeWJwZFBsaEErMnhUdVAKR2RlZjZEN1RsZHBKUUFLTFRLTThZa1hCYm5GMmVDQlFlL3UxTXczSXlENUhPZEVQcHVwek5wbzg5UmZldFQzTjF2bXM1RjB6bkFpVwp3TjVqVlBnekdDZlFEdFpqQXZJWmxqYWpDSUdjYnN5N2dVUkFPczRCWk0yZnZ0OUwzSnllT21PZU05aUg2ZWFhVWFYQk51dkNSeENvCnh1SnkvQkV0dkdsUzhCbVhuN0h6MFQ3elQzalN2NmpHbmg4NjR2cUQ2N0lqcWpUZUlzT3pKQ1FlZENlT21mU0haOW9tN2xnc2VVY3YKOWZmSTNEVVpCRXAyNFpJZVVGOTh5V0xtSFltUWZvVURCOGFCbkpwbnhwV1FNMmU0RHVsZ0tkWGp1UWZQU0VVc295ZllDbmF4VCtNNAo4bSt3VGVTTzREZlkwb0szWE9tQ3BNZHlSMUNpZFFmVUxLYkkyblhBQ0xSUDJzSzN0RXg0R3BMdllNeEtYc0hQc2sya1B1Qm4yYlJYCk1WS2ZVQlBBSVJrWDU2ZENvRTlBUkM2S21YaTV3ZFRlR0ozWUhCRHNjM2R4Vm5vQyt1eE1ibnJPVDNNUVV2aWxMbUNjRVBpVUFESFEKNXpOZ1BXRzZYMGZoNWFLeHZHejhjQkZmR1VhdzVyeHVRWkhtQ0V6MG9mbnNWeG1JbUphckh4SW9zQjBvRFJkZFFyNy9HWG5oN01LYgp5dnQwN3NEK1lqMWZMcE9adjdxUk5WekVrc3lpYS9uQlhJSFZNMVpPcFl0N3dLYUt4QVBkdmFDcDlxUG5aOXlwT0xjaHMrSGxKZW5CCkNiK2NGTXJ5YXhiemt5R3l1eVAzQVpzSWpFdldaNzlUTTdOYlIvNXB6cEE2bFk3Ri9EUW5CemI0WFZWbTNpU1grU3VuOHpsWkdNNlYKeFR1NHpDUEZrNU41VEhlQTN5Y2lOWXdQc2tiNHQyUHp3ajgyNHRPZ0U5Z1hkdStTRUpCbk5SK0ZreXpLZEJFZUg1aHFMVHhoTzFIYwpkOE1uMTZVem5lK0dUMnFnWE5aT0JHWWgzWWd4ODdyQkRZYUUxM1NUYUVtRG1UOHArL2VXTXA5NHlyOEdONFUxdkFMRjkwZHc1WXZ3CjhpZm5PblZKc3Z6empab2xxUmFDVTM4WTVWOEZkamxCcC9HeUNFeHNXaVA3QTZwKzV3NmNwUDZwME55L1laZjdqSytjMUIweGUxSkMKdXRMNVBRN1puL2o1QXhFbmx1ZUhnS1k3eGoyV0RjbUdaSm53VzZ4Q2VEZVQyN2c1RFVBUkxJWjgzUnZUc0hDZ1dlS3lEU0lDeFc4bwpKb2tJdC9qVGNJT04zL1FVM2lRVll2dW0raFUyR1JPaXgvaE5XN3h6WDdEN2g1MXRWSlNOLzduMk1CL1BRUWxOZUl2SWZEUWxSNTRnCnNQQldlbmNVbTJxZlpYWnExN2RpNitJNVF3VjcwQ2djNzhpQjB4RGVKMU8rM3loOVVBajNkd290TjZkdDFLamQ2WXgvMnhkVHhiR0cKRVI2ZVFMRGdrNzcwcjM5TUkyRzVhYUlRQXUySk1UNjd0YlladFRucG5uZXhrU0ovTkJQRmtYL2pMbWliZEgyQW4vZ0tGOWpDeFExTQovNXNHejdUZ21HS0tjN2VvMDR5QkUzaDV6eXA4dm1wbjVqOTM0RlJ6bUFiN25URzRVZm43SjRYbTRFWmp2SldlRFZCWU5IaDkrYlhBCndsc0JkY2hyUE5VQjFrdVR5TjFDRjRiT0hUZzhSb3ZCcHh6L0VSNEpwY2pnbzlrNGp1Z3grYUoyOTlQYXl4L0hQczE3WUY0ajhPVGIKZnUvNW9OTWJkWHF2Nm5VTHBuZm40eC8ydnIzQVgwUmlmenIrNGZHalRoZlE3TjN6SDJ0ZjdOMTcrZlRvMjM2N3hJK0huZGFvMCs4MQpCKzhXL1hDL2R2Zlg4MjRQZnFwRHR3YWQwOHRST2Z5MDl2bmV2UWVEUVhPaVJPdDFwOXNlbEQzOFhkYnVQZW1Od20vNHoramRSWW0vCjNRVk41TTZudFh2Zjl6b3RBQjhEM3Q2cjhhSnZtOTFMVy9hWFRudjBlbkhoWHZPY3lrSlhYT25QMTVtaTEyWG4xZXRSWlpLNCtJM1QKMUQvOXVXeU45dnVYdlRiMGI3Ly9hMVVDejJpK1FkSFJzREtWWTNWdW5OUUhUMDRlZEM5ZU4wOUVWUm83YlNpNWhDWXNjK09rVkorSAo3eW9QenJ1MXBtUEp2SXpvK0pYL0x1N3V1b2pKMGVYZzlMSmI5bHBsVlZiWXFoVzV3ZTNjOU1EQ0VhOHFQYWZOWWZsb1VQN25FcGhRCmZicE8xTHB4Q21WVjhucVg1ODlhbytiYnNycWNqS3ZjT0dHOS92R29NMm90Mlk0RGZVTXEvVjJudXdLQlkzVnVuRUpjY2xXcEc1VEQKeTI3MWZaeUxWNUZBYzdvdUZuUjk5bTRVYmNybGR4WEZTZWp6QXZhdjhiaDBla3NXWUx4Rlk5a2JuMldkWGxWYStoZmxvRG5xRHlvVApGQ3JjT0ZYSC9jdEJxM3c4YUY2ODdyU3FEOVlLWTNXTGkrZWdmMzdSSDNaR0s2eWQ2K2dIYWNsVnUzRHZzRHlyM2Q4ZEFkZVBvdDBSCmNBYVZhM0lFVkxzajRBeENka2ZBV3hHVFo0TW1hUHZkYi91ZDRaWWRBaXRiV2piekRGaFppdXpPZ0xzejRPNE11QT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJT3dQdXpvQzdNK0RIZGdaVVczY0dYSUdpVFRrRHdzRm92M3hiZG85Zk45djlYN2JBUTFhWDIzSkFXb1dTclQwaVZkYTBoNlAyWWZtMgowOFFPcmFDS3hwVnVmSVJQdTVkTFJQMEgwRVZ2UlVjZ1k4dTJhUWlQbTVmRFlhZloyMTg2Yk91b1lGZGVTZTNxWXJHOTFvZnZkbldwCjJQNzFGZ2pwbjUwTnk5SHkyYlI1UW1BVndiWXBxLzhaamRibXJmc3VhcFlZWGRqcWQvdURMMzU1dmZTSUUyK3E3N3JWclkydTlJM1AKdHNvQko4UEx3Vm16VlI2M21xdFFOVmJweG9rYlhwU3RaNWRMNXQxT1FveEppQnYzRFZhZWdEQ1lsOTNtNE9HdkYvMWUyYXMrVHRNVgpiNTdLVllrODZQZUdvK1lWaUF3Vk4rbWtBc2MxK0U5Vkp2MVdtU3UvM2NiUlU2eEN5NW9mby9VS3BIendjL1MxcUNMUCs1M2U2R2dWCkE5UDEyQ3JMWTdkaWo1eU9zWG5hMFpXT3F6dnZ3MjE0SDdaVUUxcVJyRTA1TGwzQm5iSXVNcUh5YnZGbWlVNFVqUVVXdmZrNGpNcUUKTExHcHhJU29kZFk5MzZUVkNVblhtcERxZTh5YjI5aGlWcFphNjc1bk5nZWQwZXZ6Y2xUZHNiMUplMmUzTTNyZTdDdzdpMjNlNXJtTApTS2k0aFc3T09YcDFxL2ltak9mVGN2Q3FSRTV1bmtxMHF2elk0aUc1dm43c0FvOCtqSTRsZG9GSDZ4OTQ5SEZkUGpubzk3djdnN0w4CnJiTHJiWDBEckZhWWpPdHVHYTVNeU5iR1Y3VTczV1oxZi9BbUhYa3EyM00zNjZ4enZaRlY2enBHSkEwckVuSWJRbEUwS3FlRkdEVGIKbmN2cVd4Y1h2ejBWdVQrNGVOM3Y5bDlWRnVicmMyelpYdWwyL1hlWTFsWVVyTGxNcTM2TGFTZlRkakx0S3ZyM3RnVHlubGIyaG15SwpFRnZoQnVPYUM3SFZMZ0t0SXNWdWFjbHZhdmp1OXVZSXFMeTdiR2FPZ01wUnlic2NBZE1FM202T2dOUHFpcyttYkV6VjVmbTY3MHlWCngyWlRkcVpOenRxd0pOd21FZ0tyM2JtNHBjc1dLMHl1dFE5b09hMDhOanNodHI1anMrNUdnZ2VWWFVFSHI1dTlYdGs5THJ0bGF4VWoKMjNURkd5ZnlSV1UzMFZXSm5LNTRhOXZSWVdkNDBXMjJ5dk95TjNyYXZOaThQZW04Q2FncXU1TTM0cXhVNC8vV3BqNktzWTlWcWFaUAoxZFZ4TG43emdyS3lzV3RqTnJIcW9uL2RON0hWY21sdWdDWitnRGVrbjFZUUgrc285cXJmejl6RVRDbVZyU2tiSXdlcXI1NTFsd09WCngrWWE1TUM2ckw2emxZSzd6anJkN2lyQmE5M2JVRHFXcUFlUmZSWWZwYXB1bDdXbGIvN0dTbVd4RnlqenpYOUwvYTlJNFVTdFd6RFEKOWlyUHhHYXJkWGwrdVR4S0lpWXZxbkx6VnZYS3M3SmRQVW1UTFh2anRBeEtPbWhWSHFwMnV6UHF2RjFob0h5RjliM25kamJvbjFlWApoRlI0ZlQwNW8zNzFrMlQvRmdocGRuOXB2cXU4Z0VBMUdqVUhLNmxTdHZ3dDNHN3JsYzNLMTRWYXpXN3JhYi82bFkrb3dpMmRUSnE5Cnp2a0tFdnFhN3Foc2R2cTdlcjR0WVRPdFhkak11aDZGcWcvTnBwaEVkbUV6OHpidzJ3cWIyZmIzRmF0blU5c0Z6c3l5MDkxbTRFeHIKNndKblZwRG82NzQzN1FKbjFtaC9xcXlOYmtiZ3pBcVRhKzBEWjFwYkZ6aXpSVUpzRnppekM1elpCYzdzQW1ldUdEZ2pQcGJBbWRiVwpCYzZzSVByWGZSUGJCYzZzazlqYjZzQ1oxdFlGenF5d2V0WmREdHhtNE13bXVJZzJKL3huaGFGY2RWTGUwbEJ1Y0xMQ0ZRTFNkb094CnVYazlObWNzcnE4ZnQ5dUhyVWtaK2VESnlTR2xDanBaemI2MFpVR3MyNXN1NldieVJLL3I1ZHVQSVQzUFRyNVZrbTltSjk5MjhtMUQKNUZ2bHVicVRienY1OW5BQWdJOWJmU3VSQlR2cHRpSFNiYWU5N2FUYml0THRvMWJlZHRKdGs2VGJUbmZiU2JmSzBpMTJHNTJzNWh6ZgpNaUZYbWZnUDRvdmVLQy9oYmhHdHNJaXlqM2tSVlNaK3Q0aDJpeWkrNTUzVWRPVkFRRXYyaXhWaUFhTWFONjZPZlZ5dmJUM3YvRnAyCm4zZWI3MDVXdTQrNVpYSndVSjczbDZXTDJPV2t3WTdjVms2YWlrSmtsNUJtTVhtM21aQkdWSitUdTR3MHQ1aVJabHR6bnd3dk1QdEoKVmJyZUsvZkpEVlBXNmJYTHMwNXY2ZnZYOGFoZGxNM1I0UXJMTEtweDg1S2pKdTdMcENZMC9KdlU0UC8zNFRQOHZROC8xSzc5UHNxdApIRnRXVG1TekxxclV6UjRwYnpwZWRvVzMxamZsbHNBV1BwYTV5akI5cEJjR05zTnpzKzRYNEpjdGhNMTBzN1g2NXhmOUlXZ1R6eTZYCnlLL05rM1lyaVlZTmliTS80UEhhUExsUTJZajRab2w5S2hvTExIcno5cGJLaEN4eFhNV0VxTnZRdFNzVHNpUXNKeVlrWFd0Q3F1OHkKYjI1ams3bVNncmJ1TzJkejBCbTlQaTlIMWJXQlRkMUJ0eTRINVZYVWc0OXhLOTBjOThlVnB1dW1ET251RnVMTy83enpQeThpZEMzOAp6NnZsWE56NW4zZis1NTMvK2NPVHVmTS9VOUdkLzNubmYvN2dkTjNnMnhzNy8vT0hWemZSQXkyVCt5dXBuanVmODg3bi9MN0U3WHpPClZ6TTNyUEV3N1h6T2ErVUFhSGZPemk2SDVVRy9CNnBCci9yeW1hcDM0NVB1WGRudDluK3BTbWUzOCtyMUNINnZ0ekFKYVdVeUo2dmQKL1BaYldieGZEczVBS1Q1ZTdTR0FzVXJyNjZheXdubzEyc2JxM0RocGJuMXMyK1oxclNFRTZ6MUVXL3dzOGM0RXQrNG11RlcycjUwZApibzN0Y0x1WGlYZDJ1SjBkYm1lSHUrSng1LzZyUVZuMjdvTWFWdDRIaWp1dit2ZmZkdnJkY25SL1VMYnY5d2ZOM2pJLys4NUFkOU01CmJpcGJUTXN1ZkZuSlBCZlZ1UG10TEs5TVdQTzN6dm5sYU1tTGxySGc1L0szWnYwNTdKQlo0d2pWcmx1T25UbTB4NVFqcHdGdTNnSUEKeWJUdFZocXgxV2FhNFVYWkFvVjVzTHNTc2RiMmpCVW1vUnZRaDc5ZXdGbHJCYXZ2ZE1WYmlHUllsY3FWYmR2VEZYZkduSjB4WjJmTQoyUmx6ZHNhY25URm5aOHpaR1hNK0FIMW91ckhHSEdmWkladk96cGl6M21mWm5USG5mWXc1dDZGbmJWdGMwaHBacG83ZE9XbHpUVk5iCmViMTRPeE56YkxFUjZncWtiY29GMUExT3oxRTloOEl1UGNlNkViTG02VG1xRTdMbTZUbFdEYUZiKzcxenUxTnpkRHVqNTgzT01rdjQKNW0yZ04vTTJ6bTRMdlQ0NXQ5dEMxMDJwV2ZNdGRHc3lYRjFKK2Q5dG8rdXdqVzVkZHF0VjlZT1BjUXZkbkVDQWxhZnBwZ3puTHF2Vgo5bVcxK3JoU1B4Mi9icmI3djN6Yzd3NVZUbnExUzF5d0h0ckJUU1F1dUtVZFpiTXYrMWQrRHJSZCtUVmFLbnJqTTZ3NklVdTJoNWlRClgyK0JrUDdaMmJBYzRXd2FsTzJWVnN5bUNJTnR6Q1gvakVidG96b2pYSDJpYnNxZ1h1R3dzQzZEczlWbTdkMGhidnNPY1VJbGQ2ck8KMDE4NjdSV0N5RnpwbXpjenA5VXBlbDJ1RXBQbGk5Kzhjdkl4SHJXdkljWHlEZE5TRjdyeVZLeXU1OStHbXI4S0pkVVYvVjgzeS94aApkdWFQelRyeDdNd2YvZlZVay9OdE1YOVVKMlJuL3RpWlAzYm1qNTM1WTJmKytJakdaV2YrV0hQengwZDJzQjQxVjRqdjJrWVA5dG1nCjJSbzF1OS8yTzlWRDRHM2xpbVBNTGQxMHRHdWpjaWFaMCthd2ZEUW8vM05aOWxyVnRldUpXamR2MWFzY3o5dTdQSDhHWS94MmhhdlYKY1pVYnA2elhQeDUxUnEwbGh0WFl1SUNsdit0MFZ5QndyTTZOVTlpcWJNbmJsTE5FNi9vQzlOWjJiSGJKdERjby85SUtRbjZYcm1neAplYmVacm1pWHJXaUZnYnE5YkVVcmFGOW5nLzU1ZGVGQmhXK0JuTW92VkkzNjFUWGovaTJRc3NzalJadjhMby9VL0R4U3QySk5Xam1iCjByVllrcjY3SEp4ZWRrRkYyRmhUNHk0UHpBWmN2bHZoakxFaHB1QXIzRTdibVdFWFduZTJMZ3B0QllwMlVXZ3pxTHgxWTNuWUhFK1cKWEt6ZmdFaTA2cE54dmVQUXF0T3h0VkZvbzRwSzI2WTVNSkl0OTJCVURoWGFPVENtQ2J4ZEJ3WXV1V3QzWWR5U0tyczdBKzdPZ0d1MgpoSGFud0pYNnNUc0Y3azZCTjBqVFIzc0tyS3lmN2s2QmEwUEgxcDRDdHplUXJYSkdpYzA4QmxZbWIzY00zQjBEZDhmQTNURndLUzI3ClkrRHVHTGhWeDBDOWRjZkFGU2phSFFOblVIbnJ4OEFmKy8zMnEwR3p1bEJlMnpOZ1hXekxLWEFWU3JiMkhGajVPTEhMU2JFZVYwZHUKNW9yc0dnL1VwcnphdDlrWk5uWUpSaGNSc3N1d2NldFNZTTBsV3I5Q1pvM05rMmtmTEYvSVRWdTd1NkIvMTF2OWJuL3d4V20zMlhwegp2MlpCL1l0bXF6TjY5OFVLWnVQaDZGMjN1aG5jbGI3NW1HbWtkZHNFeEVwRWJjcWFlb1FUY2ZPVzFQdmswZG5aVG0vRGRycjlDc1JxCjhtSE5OWWdoWlRFOTJFYVJ0OEh2RzFaTzNPRGVTVDNvOStqeDl1cG5pOGw2Tno3eGZubTl3dVhKcm5zSXZsNWg3VVZVVGxhN2NTSXIKQitNTUx3ZG56Vlo1M0dxdW92V05WYnA1ZjhGcWduMDEyc2JxM0RocEt6NC92Q2s3MXpZZGZWZDlJWHA3ODhLWXlrbW55aTU4V2NtMApIdFc0ZWZtU1ZoYWZ6ZDg2NTVjcnVGaDkrUnNuaXJhazI4eG1kQzJxMW1HSDFJaWpWWnpDMTVRdDROREtoU08zOVcrZTdyZFRqRFpkCk1ickN5OHM3RGVJVzlwZksreVlQNk1OZkwvcTljb1ZqMW5URjlkWFN1YThybnlXbksrNjBwNTMyZEgzYTAwNTV1amJsNmRndDVjM1YKbm5aUjFodmpLZGhpTmVrS3BHMXhIUG02eUliS3F0Q2JKU1dqc2NDaU4zLzlyREloUytJTllrTFVXaE95SkxsUlRFaTYxb1JVMzJ2ZQozTVpXczZwWmRlMzN6dWFnTTNwOVhxN3dvc1FtN2FIZHp1aDVzN1Bzc0xaNUcraFdQOUd6d1Z0b2RUbTMyMExYVGFsWjh5MjBPaUZyCnZvVmVTZm5mYmFPN2JmVDI2Zm9ZZDlETk1WWHZIcFZjWTgxb1c1ZmFocjRudVM3VFlsc3pJRzE5SXR6ZFUzNmJtd0twYXBxZ3pWUG8KcnVUZTJveU5acE56TzUwM0FWWGwzQ0tiSU45RkxYSC9uZlhKUTZxU1RKK3Fpdzh1ZnVOa1A0YXF3K1d4WnBzbk9GWVhpWnNpTitqdQowdE1LQzNBZEJjZFdKMGJaNWt1QVc3d1JiM1pLa1hybGM4bTY1eFNwYjAxU2tXZGJmeWQ0bTQxeW01cU80K3F6YnYzZE1kc1pFWWhtCmZSeXY3MjRpaGZHNm55dzJSVHhzY0RTRHFQNGk5aWJxMy9GeXFuemxjRlBXMDFWa3hhWXNxYzNXd0hGa1hwNlZnMGVkd2RhWlVkWkIKaXEvTE9JK2FwOVg1c0FrMlQxbXI3UE1oMm45WXphZzVWdWYyRW9GZDlsb3ZOaytvYk4xa2EyUzFwUFp4VExmSHUrbDIrOU5OZkN6QwpiZitXQTFYb1BJU1h2YjhiTkh2RHMrcXZYYXpQN0w5aTlQM09hSEpiUmhNN1lOdW9jRi9sTUxFcHg3d050cHhRTk42RGJ2ZmFwOXZtCkhJZXV0ZzQzWmE1dWFCam9kZlRoS2s5WTNYbndSQ1FuRDN0dC81UVZnalJDVHI3dDk1NERDc3JIVkxmZy9mSlZweGYvc1BmdEJlRlEKOXFmamQrZW4vZTdlM1FmdGR1MVI4MjEvZ0VKa0w2azlnUCsvL0dYdkV2NmIxSjd0SlExVFpIQ3FiUWlWcTh6RzdEU0VTYkpjd1FlVApKVHJQNFVPZUc1bnAyc3ZtWG9qeGVma092bndESDM0RzBDODFrZFNlMXY3NVUxSnJZd3N2OXVwSlF5a2o4NkltUlNQWFN0Zk85K3JDCk5FU1JLQ2pjRUZxb1dsMnFoaTdTdklhbHBjaWhqYnJVV0RHdDFZdUdFYmt3dFlPOUFCT3lZZklrcXgzdFlkVk1GMUJWSm8wa1VRVjkKa0Zyamg3U1I1QWJRaTZ5Ukdwa1NKRFdGcUxXb0R6cHpNSWRVTjNKcHBJVkFWd2tpbE5JQmd2V1NScEZMRlpVcUdsS1pCTnVURFNscQpkVUNUNU5pK3lCdENxQlI3N3JsUUY2SUJ6UnJvdW1vVXd1aFE3R2d2YjZTSTBPS0JocElpU1VORFFnRmRjY3V0UFFBVktiYnB5MmdZCnJWd0dxb0JNWlFvWmt5NEsrSVRNWnY3QTM5eGtXV0FoRG9kT1plRHp3WjRIOFhBY0VVZ1ZORUxhQ0MycFdxb05BUklGTXdZQkVzZW0KZ000ZzB3aFBrZVRZVmlOTnRDRThSYU1vbElsQktjNjFGRkRqNE9aWlVVdEZJODBLb0QwRHBoaVRJNEQ3azBvcHNZc2VCTDB1OGxSWgpQREI1TGNzSWhHeVJCQ2pzTU1EVUVCb0hENHFtS1l3YThBZG1weWdNZ1ZRS0k0VFRRSnZNQXNaR2dnR3RQZWhYWWxJZFFDbndRbVRZClVvYWpxbXZSSElBQk5pS2xpYUdnUHlyblVraGZrU1JwRWZDRVNSZ2F3OGxMREk1S1FRZUV5RUtuY1ZvbE1Lc2l3Zz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJY0sya1F1cEFmUjE1WnFRT0RLcW5NcXd4Z2tBblBZeVpEZXNPYWhwZ2dXakl4Q1FXZ1lHeFF0NklBbm5qeWVVK3d1QkRZYTJ6bXN5aApycW1waGxFNVRDQnBZTVVBd3cwc0NLVjFEWlo1a2lvSkZUd0VhRWhTYkJmNkM0c2lqU0N3SGtWUlNJbWdYQUE2WFA0UzBjS2NTZU9PCnNBUTYyRHZiKzM2UGhGZDd6OVR1ZmxwNytlUGVuWk5ab2dxZ1Z4UldVSE9HdUVMbzFRU1c3Y2xWUkJiV3ZJclFpamtTaWEwN0o5T0MKNjg3SnlxTHJ6c21WaEJkVXU0cjR1bk15UTRCWjRNb2lqS3BOQ2pFQVRvdXhPeWRYRW1SUWJWcVVFYTdWaFJudzZ5cmk3TTdKRlFVYQpUSm9yaVRRN3ZhOGcxT3lLdW9wWWc1b3pCQnRDcnlEYVlQeFhGVzUzVHFiRkd3elhsSUM3YzNJVkVYZm5wQWZhNjkwSHZYNnZWa2hECk1zNHBlMUM5S05JQ1dDMThzRGJvZElRTW1BYnp4ZVFGU2orR3dKQVdLcVhWRDNJQVZwU1lCZUo2UjZST3dtUkpaNEZ3a1Jja05MamUKTklSNGxwRnU0SG93RFFtMWFCQnhlS1lnb2ZsSjJvNW1id0hUTEFpd2lHSVlwV2syQkdCb0JJZHVpaFVSTUhRNTFKNEZDK1NIL3N5Qwp4WFduMlJKZ2NXZW1XUk5OSGVMTDl3Q0JRK05vN0d4TWdnWFdURkZUTU9FTlNFT2xZZlZSZTFKSmU0aTQ5NkpzZG0zSU5WUUFsRTlFCitoeE9vK1dnVnh4M096YnpLcHhhSGc4NjdiK1ZGRHQ1NTBTN00xZFUrQVdjWllhakFjVkhmT2VPWDhERzJyMzlmcjg3VnZKaEQrM0wKank4N2JYdllCZnFtMFdHV3pjRW9JSUpqMThsZXdiUEFuOERzMlduR2FXci9jalRxOTA3NmIrRjRGeCttL25RSmZEdDBpMnpPQVVtTgpuNCtTMnFzOWtCaEpJbkNQeFRXWDB3YzgyZmhQSUdhay9iMXVkd3FaNUxnbjRaZk1LbWcxcTVUSkd2MkkyR3dsM1BrTGxOQXdNQUpWCk1QcDd4RzNTWnl3SnV3Wjg1dnE2UmhoQnA2WVdqdmE0MlFKT2g2NDRkaWZxT1NwVkNSQ2ZDcWg0am45Z1dtall6VUVvRzQyYmVjTEYKNFpQdFNPTElkQit3WUlZOWdCNG5FcVU0NFRDNDZSQmFwRlRZRHRFSC9GWExyT2FyZ3FKVHMzeHpUZFFKdGU5bVlvOGIxQi84eGtpdwpDWXY1d0JKd3RMZC9pbXZnK3g2ZTBOdTFWNE5tdTFQQ05Fby9wVUd0RnpqQUlycnRJbXI3ci9DY2wrQi9VS21CM2hnOE5CTUFtc3NGClNQTmNBRWRlbm84VjFETUxTdEJiOWxzVk1lNVh3UWpuZWNTSXc3Uy92L2VuNzJIR3czYWl3elNOMkhRZU04OTlxTS84RkhOK2JFeVkKbjNYSDBMSGhuQnByT3dzT3duU1kvc3R6cDdzWFRha3d6OXdNNFFrU0QyMDg1QkdSclhtRExDc1BNaFFDVFcrTTB6a09pWmdjNUhSbQpRZFRlSmdaNVBzYjlLaGlGRWRFZ3o1SGNxZ1pUUVlEdWVRTkNXdHlXa0Q0WWxPM09xSGJRSExUbkN1bHJNM3RKUStzVlJzeDlza3RGCkZuVHdrMVowQ3diUUYrTUVPUjYxVWxMNTdUZjRBcnFhKzBybkZ2cmdrYmtQaUJUYWtxaFoycjhrNnZpM3FJcEZZMlY3d0Q3V3N1dVEKKzhCWW92NDdxbGpvZ3hZQXhjL3Bid1pyRGRRTjZmNktBZ3ZEdndmRUMvaUFyQWcvMXFNNmRZc0hTeFp4MzZhK1VkL09YREhiNlhQMwp6VmhXMCtIQkllVVAxSnFodjhTak9uVW0vam11NTdBZDdFV05ISTAxaVYwQU1UcFhQUUxOcUFhYXZCRGJyQXNkTmtmbG8wN1piVStyClEzYUphV0VVTFRLVkNnWDZaZlFoeWJRQzdSYktKSEJDbmZXQjFoeXN3R3FyTGlQVm8yN3NmZ01EakpNaDR6OFpEUmdneTNScWNJRnIKYVpUMmQxVkJNMDV4bjB3YVdacEpQYjNlNFF5SDJMTWFUYkhNYmpPRy85Z1pDZHJkSHU2K3RodlVNUDVGclZyN1AyYStlcUVYN2p6dwpBKzVjdWhhMkFSRDRDcVIrbHVHR2srQjVSTTh1a2NQQkVuZUdoVGoyRitPQTAwYllXNGllYzA4ZS9sV1dQaFdvdlpJV3RhQ0xaaW1aCnlWSXl6Vkl5ZFVUbUpWR0dtbmtkTFJKSUthcWpqbUwrSytiVGFvcEFySnBKYkk1VEF2K0tMTVhtbFNNU1ZhcjRoMXc1eXFZcjdNK3MKWU9MeGdsK2twVUphSWhMYmQvZEhMcWFnanROblpTSWlmVVdrRThSa2k0aFpVSEdTS0cySjBwWW9OeUR1ejRJcFNFU2w3MGVTR1M5UQpKRlZKTW90SVN0MTBFMjY2Q1RmTjB2RDNRMDIzSko1dTJUZzhGOVBVSlBGc215Zy9TWVMwTkVoTFFtSjc3djU4d01tV3pGc3h5WndWCms4eGJNYk9Jc081S083bEV6YkhmL2ZsZ2t5dFp0bDZTT2VzbFdiWmVwa2hLN055U2RncEpPNk1TLytjRHpTdVR4WU9pSnVENUZDRmMKZm45VytZbitTK28rYWJjMG14TDM3NGViVXVPOXo4YmhNMWJGZU8remhiMG5xeXJOSEZtelBMZi9mcWk1Tk43M2FIYmJ6azh2aC9ITwpUMVlZNnozSm4vTTlKMzYwLzBNV1Yvdm5ROHdkTllmN2FnNzMxUnp1cStuKzQ5elJORk0welpyVS9mc0I1NDZhTS9QVm5KbXY1c3o4CkdiM1gxSHVyUTFxZTIzOC8yTnk1TnM1Lzd3OFUvdkNkTkFvcGhmQXVDUFNzQ0kxbmNGQzdCVVdPS0s5MnhTdkZxMkRDcXZPQWpYYVoKYzk1WGVKY1IvRWZ5UVUzVUhseFEwNnJtbFhvOFFyaElsWXoxKzFpeGQrcitIUDVtaS9YMUNha3NzbkZkTTdWellsS3BJTFYwUnRGQwpXZFcyR3RaSmpXTWVWcU9YMjR0U3FDd1MvaWR0V0p2aHRoNW9CLzJMZHYrWEdlWjlzaDBsT0lsV3NQSUx0dktUcVZPamQwaVRsL3A4CkNuTGtJWFhUVVBRaEF1WGt0VlZrN3RRWnVhaVZxKzVLTU9CZ0Q3M0xOcmFnOElpOE5kVERNQ3dBaXVtQU8wQk13TVd3ME0xRklJK0sKbXl0Y0dkOG5CbEI0QnpWU2VEUk1IRU9ZZXNZNnlUSTBRTTJjc25kUmFHZEpWcGhQUTV6ZS92NkRWdXZ5L0VWLzVHL2FRdVc0WnUzZQp0LzNSaTdMVkg3UmhuZHQ1U0hvNC9ERXBuS0ZOYW5BUnBVVmlwaGJBd1lNbmo1MWsrTzZzUHpqblhFTTBDMkdPdHZ1bjVjbURKOFVKCmRQZDQ5SzVibm9TbW83bUtMYjVzbzhpUlZ6ZzZ3eXBtZnliSlJ1WjY3cWNkam5haUMrTkJNQ0ZzbWF4aDZBY1BDR3oyb0docUJoaFcKcENHM2lPR0RtMkYrSHVaK1Bwa3dvUmtSMXBOMkhpbzMzQVhYUjhUNTVMSTQyTXVuMWc1RG1BaEd5bFFhUDVVOFRaTzhxV2F2V0RBagpyTlFYTkV1RHFQVWZKSm5walNBUFJDNjBYWWkwQVdDRUM0Yk16S3VVQWxraXlhTmF1Qk9zMnRKK2haWnlNZDZJMnhwMnEyek9LdnZUCm5FMXp4NXNmcHp5TWs2djJmRzlxYVllRjdCZi9oSENZRWlEeGZoZUV5a3pZdElTYWxHRlRjbTZKN0l1MndBVWdMMW1uWk8ra0RKb3AKbGlabFZ4Q1pESm1XZnBNYlpSVmY1M0xSbHMwVE9GYWpsRTdnbUNRU2JXS3V3S0ZLS21IUnhyVkl0SzNZMG42Rmx2Smt2SkdQVXJRdApkbTZQTGQ5d2JrTlBxY3JSaTJOU2dUNVJBNmMxc3AzclBEVUNmd2ovbjNhVTBuR09GNUZ3aStoOEwrV1ZMUHk2U3ZCNFFlVzZNNm9jCnpWZjMzRkFueTBhTE9EVFBMOTdJc3d6RC9OeWZCUDFCN3M4V2U4b2ZkYnJuRXdjZGY5aFpjTWFaOUw3aElVZWtHUHdLekVNbGcxekMKY0VadHlCeGozUnpvS0lEd0EwWERIdm1LTTBDaDRoa2R2RENFTXlseVVsT2xrZVR5WXhDS1BTV290bWprR0VJOURlRnFjN1U5NVZhSQptcmxDWk43QStBQ01PaFUyK01nMHNqU25HQ1ZvQUlPSDRRQU8vUkVKbXRBSzNBSmtnWkpRWVNjeFVEblZqVlFxT2JPcVRGRFlwN0tXClM0bEIxWVpzZGhnSW5hTXpYamVVelBTY1ZnM00zRUpyYkRWdEpLbWt3S0Nza1JsUjBPYWxSWnJrczZ2cUhCRkxNalRqRm9JMUsvVlgKYUJBR1Jsc1BZMUlBZjZHN2ozeU1VUkFoYzliY3ZhZk40UnY2NUUvOFQzcHc4aDZWN1FsRHdFRzNjM0hSd2JkbXg4Q0huU0d1RVZmNgo1VmZ3enlYOG42NUh3Y3d1ditBdk5PZGZOSWQwcCtvRU9nVlM4akhKNy9KdGgyNHh2NnU5L0JZQS8vVERYU2U3Ty8zekU4Wk5wR2h6CmZ2bDZmaGtFMlhMMmYzazBmMVNON0U3WW5UdlVsOFBtcVBrRkxDT1o3YjE4OG4vKzY3My84Ly8rZCs1Ly9oLytQdi9uLy8zZm0vbDkKVHNkM3YrOSsvNjkxbUorTGYxKzJ2dDd2UHlnV1lKdEdvWUJ5N0s4c3RnRG1oZGEzYzBLTmd1WlExQjVkL3ZiYnV4cEsxVWdidUhPQwo0dGZyQkNjdlA3TUt6R0Ewb1hzY2RYcHZXSmJlSjRRbkU2aXNNSk1vUFpmcEEyUFI5ZDlQYWhJVHNmY290UDkwU1gxNWNFRUMvaG45Cit3cEJVMm9GM2hlWlVpd2lZS1JIaE9vemdYSDFNMEl4cFY1RXdLQk8yT2o4Y1JVandJS1NjZWNFMUF5a2FsVkZBM1M5SzZzYW9NdGUKWGRuQWl5bFhWamZ3NXRCVkZZNkt2WjZwY3R3NWVVVFRoYzV6WkpPWnAzRHc5WGZRQVI0OHFUMjRIUFZyZG9GMWZpdkQ2V0hxelBYcwpkRmdPM3BidEU5RHNUMnloWWJRc3dsMmJ3dDIxQ2U2Q3hNZWJKbW1HQnhyNElIV1NtK2dEZXNRVWhrSlAvbDNwdHJYQUF4cmVUSU1QClVoWTJmQ0dDSlJnRENYL3p4RTd3WE9VVUZ5M3NMd3c0c0JwMWtxb0FPeUtZRkVyRkZXVURCaWVQY0VjQTZvQkY1V0N5SVhEZ2pzWmgKYVVhdUIwWU9IN1RLTEM3YkJZWWdMdUhiSVpEMVBGaHlRa1ZQc1VjZVFhZ0xCek40WlE4WXpyMVR6ekJPMGFoUTVYd2NaaEhqM0JVNgpianhyNUhRWkxlbzBMT1BDNVBsWXIzR3RtandtdDJpSUxNdlNDSGtNNFY0SG1PLzFHTXlObzBQdUI4cDNJUnBpN21rMHdwNGNYekdRCjdIREhBQjdoS1Y1UmRLNkMzNVVSWXh5TVlaWklCZUpYNlRSaWhFSjVvTEl4RnVxR3pvdVlYVWQ3ZEdjMXlTSzJBcVRJa25qY0l3QXoKMElNQy95SVFrZWdSZXk3NDVpUDIrVzVHL1BQRStKcUJZSWM4QmpEL3BqaEYvTU9wanZjT1kvN0ZNRGUxR3lMbmxlU21QM1FpVitQcgpCcGNiYkl4ai9KTjRqem1McGlwQU1ySlBCZXd4aERrWVlJR0ZNWXpJOU1nOUozd1hZaW5EWFkybERCTVVwSXdubXFWTUJQQlNacEpiCnlFTVpNY2V4TUFZUmpiaC81anBpZy9CM29UMy9RTVRBYmpRdWVOQnNtWTd4RkdPSVpacEhTM2dNNHZnWHdUei94bUJJWWtET1hBaGQKQ1B6elBRM3M4OVF3S05Cck1jZmZIZSttdUlTc2d3MjRNT09zaTBGRW5nWU1PdWFVaGlhVUdaTitDamE5UkdZeDUxSWdKVWtqeHFVTgpvMENGQ29oamdHTmJBSG11eFNBa3plTmwybjNiZ1dXK2g0RmxuZ29HQlRvdDN2aTdZOWtVZDVCbE9VZ0VxY2UyakJoRWxPV1JxQ1RhCmMwQXBUQjZ6TEd2SU5FdGpqbVdnSjJUeFZtZ2FPV2hyT3VDTkFZNWpBZVE1Rm9PUU1vK1hTZWVtQThOOC93TERQQTBNQ2xSYXRQRjMKeDdBcDN0QnVLK3psNkloaE1ZZ0lFeUpzM1haNUN0QWM4N0h0UWVENlVXTWN3NWJUV0FoaTEraEN1MGNjQVJ6SEFzaHpMQVloYVI0dgowKzdianBZbDl6Q3d6RlBocTNrNkhkN291MlBaRkhmc3J1RFVGc3BIa1dleGhsZUF5cGc3UFlCVW9xSUJla0VlRkR6K0h1bDNESXJVCnUxRExLV2tCcndOdzI1RnlSd2NrazhXNm5aQjg3SEtJNGEvSzNJWkRqVE1nS0hZTWlmUzZVSXNwOTNnRGdObyttT1lPc1l6Vms0aGwKRFBLa3NlYmppWGZhVWNReTFxRWlsckdpNVd1eEt1YnhNaUJpbVFjRmxrVWdTeG9qOXNSejR4SExYQThqbGpFUnZwYW5uUEZHQUdiWgpKSGZHZExlSVpRenlwTEd5NDRsbmpTamlHU3RPRWM5WXUvTFZuUHJsOGJydkVjY1lFaGdXSUpZdVJ1b3A1NFlqZm5IM0lvWXhDYjZhCnA1c1JSd0JtMkNSdnhwUzFlRms2VUZnK2JwOE5DOHlwUHhIRFdFdUtHTWFxbEsvR3lwWkh6SUNJWlI0VWVCYUJMRzJNMkZQUGpjZnIKMG5VeFhwaU9qTEF3bVhhL01BUEFMOHdKL3NUYVdlQ1o5Qnl5bExFMnc2U3p3aE1ZNXRXaXdEQ3ZPekhJYTFlTTFnTUN3d0xJTXl3RwpFVjBlTVZQdUd3OE00eDRHZmpFTkRKR0JmWVExK3U2WU5jbVhXQjBMdkdJSUU4VnFERlBObWs3Z0ZhdERnVldzTVRHRU5Tckd5ZDhECm56ekVzeW1DRUQyTWsrbmxWZ09QdUdlQlI5eDNobmhxSGM3b3UrUFJKRDlpL1N2d2lDRk1UKzdGdnFXWGxadkFJdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJcHdBRkZyR0t4QkJXb1JnbGZ3OHM4aERQb2doQzVEQk9KdGMxR2pqRS9Rb2N5b1BnSm9pbjFhR012anNPVFhJalZyZ0NoeGpDNUxDaQo0bGVjMDJVQ2gxamhDU3hpbmNqWGNUcVR4K20rQnhaNWlHZFJCTEZtV1llVDZlVldvNVhtZWhaNHhIMzNkWmhheGhtK094NU44bVB4CmxkN3I4bFVtMXVMOXdWeVdwa2IvL0lSM21OTmt0c3ZTbDBHUUxXZi9yZUN5aERGOVg0K2w4NnJ3Ly80M2ZIL2ZILzlyL0gvOGFmZWYKM1gvOGYyYk1vZi82TUxOdi9vOVgvYy9IN2hja24rQXN4OFlFdExKcnczbnpKcHdiRm5vRjk0YXRPT25nbUlDdTRPTEFtbE5PRGt2cgpWZHdjczNoblUzemh2c00rcTl3eDIvbGUwUUVDRldlNFFDYWcxWjBnVUhHR0d3U2dWM1NFVU0wcFY4Z0V0TG96aE9pYWRJY1E4Q29PCmtWbThtOC8wV1k2U0NlZ0tyaEtvT2NOWlF0QXJ1RXVvM3FURFpCeFkzV1ZDUkUwNVRRaDZGYmZKTE00dDRQSU1kOG9FZEFXSENxYWQKbkhhcEVQUktUaFdxT2VWV21ZQldkNndRWVZPdUZZSmV4Ymt5aTN2ek9UM0Q2VElPck94MndWU0owNDRYU3FCNEpkY0wxcHgydmt4QQpxN3RmTUZ2bmxBTUdTVjNkQlRPRGEvTVpQTU0xTXc2czdKekJtT2NwOXd4ZStMeUNnd2FyVGJsb3hvRlZuVFJJelpTYkJvR3JPMnBtCmNHcytZMmM0Y01hQmxWMDRHQVl6NmNTaHBMcXJ1M0V3SEdmS2tUTU9yT2pLUVZxbW5Ea0lYTjJkTTROWEM3U0thVGZQT0xDeW93ZXEKVGJ0NkNMaTZzNGVxVGJwN3hvRlZIVDVFemFUTGg0QXJPMzFtY0d2Um5qYmxESXFBSzdpRElwMDRtSFVpbFhnVmwxQ2srZ2J6emppdwpzbHNvS01QQnloUHB3bUlGMTlBTWJpMWc3TFRMS0FLdTREU0sxTjR4eGw3RmNSUXB0Mk9NdllyektPaTdZNHk5aWdOcEJyY3E2THBqCmpMMktheW5TYzhjNHU3cDdLYWl6WTJ5OWdvc3BVbkRIMkhvVk45TU1YbFZRYnNjRndSVWNVSkZpTzhiV3F6aWhJdlYxakxOWGNVUkYKR3UyNEtMaUNNMm9HdjVacnN6Rm5WM2RUUlpwc3pOWXJ1YW9pZlRWbTY1WGNWVUdGamJtNnVzdHFtay9MMWRlWW82czdzNExxR2pOMApkWWRXMEZCalpxN3UxQW82YTh6SjFSMWIwL3hacnEvR25GemQ1ZVYxMVppUnE3dTlna29hTTNKbDExZFFVbU0rcnU3K211Yk9jZ1UxCjV1UHFqckdnbk1hTVhOMDVGblRRbUpHck84aUNWaHB6Y25VbjJUUi81bk55WGphRWE0KzZ6eGRkTWx6MVJ1eGYrK2ZsWk5Mb2lVaisKNjhvY25hcEdsdEtEUEtrb0tLK3hCTW1hNGhzeTlHQ09wcEFDQnVIN01pckZyTWdpblEvQ1YwRVNROG14NkpxMHZXRUJ3RFNsZ0E3YgpKdG4vVWlta0RRNHVHaExJcUZFcG0zOWFnc0lqcmRhUW9HSVN3d2diWG9FaFFKRlBBNmhXUXBlNENYZUVlWkptaWcxSmJEVjg1b0xZCndLa1VIT0JvTCtSVzhEM01YVHI1R1NCZnJVNlk4M1FHQkJXdVJORTFkTThtQVdlM3JLQkUwYTVIb2RSRUg1ZmtnOFkzblVBYWFWcFgKb3FheVJxWXhzWUxHNTVTS2JVNnA5YnpaSzdzbkI5MytzTFJQWnp5YlRxMjE2dXNaUHErV29hRkNrd1pNRWpUVTEyeEszc0lGeE5rbgpzd3I2SDM2bGQ0SHdkaEtGNHRsa3pwU2d3LzdDTmFnRUphbXEyUXdjdGhVYmpHdkxnblpTQzU4UlgyR1RPMGN0UlMxR0hlVzg2VG1sCm5NdWhsS0JEQS81Vm1NMEQ0RG4yRC84UUdReXZoOEwxbk5xMEdmbU82Qy8rSk8yYlM3YUMvYkdlRXgzMW5EcnZmNGtxNUpZZithSmsKZDVXZnZoQTJSL3hZcWpsS1lacE12b29nWmhhVWlaak1jemNmNDM0VmpBS0UzOVRURjFtWVlzUWJtOHQ2ak45MVluaGdxMk5UM2ZJcAovUEZERWczVTJBakcvNFl5b2FJZFNvdlBqV2ZVYnRRZE41anYrM0FGWmlDV3lUaWZNSnRLVmt5bUl5eG1GeXp5eVNHYWozRy9Fa2FUCnpzd1lhWk0ydm5mNkVkbkk2VjRveUc1VUpGMDhxNUpvQytYZktFUXlsNFdvMmQvb2VRRCtCTCtrTUZZVXp6ZU9hbUZTa2l6WHNCRlYKU2twU1o0VGN3TGx2YWtaL1p2UTZGSnBDdGFDUEV1OTlpa0s5WCtJVWpmZG8zVC9xZlJKRWl0dmR6YTZmd0EzWXJ2c1gzMThzZU9OcQoxUlNZUGp0TVN0bW8wRVpEMlg5c1RsSlNwTkx3VWZxUDlhaEVQYzBibVgxcHFxNHdDMm5kUDNSbHY5ckliUHhJc2M3MEtUeVVSWlhwCi9TeEVTYzlWOGFjajN5MzdCWXJpQTFqd1pReUhRMzJ3eDgwZDdVWDlRSVhYVmNRdXhvVHlYbzhNcUtjRllUbDNuOXhUVnZReFBKeUUKeVM3OWswcVdCZlNjbFhRZkhaUHNBMHlXak1TeGlDcFNQY1Nacy9MaG1zV3UrQjc0RXZoMkV1WFh0QThxTVRNU3o2T0VSeWg4c3QzdwpuVHVLaGpheFRCVCtqUzFQSFhhRnlUN2dqbnlZbDdaeS80d0Q3dEpDNWcwOTc2MnRtVVZudjdZMUYrdjBlMXV6aTg1NmNTdFNPMkttCm5jZmNqSGdjR0I4R0l4cWp3R3RtTlE4cEQzbVlhQk1qRVk5UjFKSDNWeTd3RGF1SkhWNFdsblZqNzJKaCtubDZoR05tWWRqaHAvSWQKTDhTOFh4WHorQnRaWVltZDcwMnN2WWwxNmFkdTNjL2R5WFVXcjBBM1hBZlJhbzJXY0QwYTdqa01GKy94REpreU14Z3U3TXVvY3dwTApkSjR1ZjQ0c1lONnZpbm1jNGUrbHpOSENxbU82YnpmQU9LK0ZuYjBTbjRiTEdYcm04MzA3bnVGLzNYdENNa0tvL09qUFhIWDBlL2hrCmZ6NExJMG12cFBwcVlteWtKOGY4Ykg2QzdTSlRwZ2FuRkdDSTJ1WmNjODlCd3h3dFZpaXV6N1NHWXFHUmFIeWMrWHpQcGpjeEF0OHQKQnJtUUpvSk9YRm1DRDdQaTYyRDhtUjZ0TnlZTGtDTVBRYU1wZWxnaUNLcmVNSWt4elM2KzMwdHZkS09keDAwVFkrM2RCenh0UUd2SQpETnFPOGtaU2FHdVhLMHhtRFc1VVpBckFPSTVzTXQreFZ1cVQvYWhQZHZWZ3J6NU5UejBtMkZyL3hobFNqOWxWanpuWnN1L1V3VWxECjB4RVluNWZUalRSVHRYL1lsK3B5KzNxeXg0bFpPaWtLenZESEEwZVorOHFFQnNKbmZmV0ZBeDZ5TE1adFJNMkhidG1YNzdpL01TbHYKbmFvR0RNNDB4Zk9BY3BlYWxDNFNKWXBpcVJ6a3lFTmtabTNqUjlQVjdMMHRYNHg2Zis0aE5JejJjbkRtaHpYNkhnM0hIQURqUEpwcQpoY1FmbGduTjFzZStNdzZCV1U2RmIzVGlhNHdPSCs4enhFQW44dHczTnh3WlZuU200MW5mZmVsNlFFUmZHbHFsQlVQcWFCZEdneWk5CktwNkZJYU12RFMyVkVpamxKNzlvN2txb1BvRTV0SHBRNGRrK0JZUnJZWkhsNlZZYloxOGNINC9KWTdkclhxY2d4cWZYWUwyUllhdEkKYzVjWXhvSmd1U3JjQzBIWVpLa21QMWxPUGdtMGhoV0NYTGtXMEtJbkRaUXdvVWpodkxRZUNRTzRvZGFlQndGKysvYTdRNElkeUlVSQo3VENndGVmNzRzdHdiejJTU1lwYTh3d3U5MTQrUGZyK3lXSHRpOXJkVm1mUTZwWW42Y21uTmJwU0FTTUY1ZUhIc1ZzVk1Cb2duM0pCCkxsMlRxWlRlT2trYUtlaGdxZkV3OHUwb1NiSXV3NmZvRTNLNXFBUjFWMHpVSlZFR3B6Q1k2RnBPYVZBVjBvYS9KWGgrZ0xKSjZ2aU0KVDVvRE9sRW9HMUZvTlA2VTRQclJRdHBMN0JhR3dqTXp4anFEb0M4aUo0dGFnWkVHTmZ5YlpXZzhNN1E3VFJKeU1FVWFTcG9DSDduUApaVVF1TEZ3WVVCMlZBbGxwaWdRblltNW90T3FZYWR3R1JzTnZtVWtwRHNvb2RKalZjZUVMbmJ0K1d4ak9BMGtaMmdRSVQ1UFM5TWs0CjZNRHVuZkJMU205aWozZm9ZS3FMQzNRN2dWbU8wNXFDM1N0REk1MUFucEFocVNoMHZzMlM1YmhzRGxxdloyUVd2bWJwQWxzWExuRmsKc1JJdWJWSU9lMnRCenZGQ3A0YjBMbkxpWVF3aUJUckQ1cXFFOVg0TG9hMXdFVW9sR09xY0ZETExNQ0YxQnZNWW94QndvdU1Mc0RDeApDcE1VQ0xDMkg5eHpNUGNkckMvWVJrbEd3VWNCNnhMVDFtTzRHS0tCNnRBTGxFcEt1dldTcFFtNkFWeVRXS2xBeHoyY1ptQm1rcElGClBjMEtQUFJubU9HUXVvUEpEclY5UHpkTGhNMXZXR1JBSHI1aGF5alNHeVBQSkFHQUl4YlBCSGU2TkhXbkxtVVYwZldzR1prYTdiWFYKWnphRWFiV0J4T2lycVJGQzRPcGpSTkdWazZOa3d4aFhIU2VvTlQxU0ZLdTIrbGpaWU5lSjBYTEpLVmNkcnhuY1FseTR1M3hQWTBDRApjK2NrRE05N0RBdVFBRUlON1FDWjhqR3ZlTUFRTlR3OUZOcGZja20xZFV6WmtFaE92V25TcEVDTkc1UlI1WURqS09mQnp1aE15aFI4Ckg4VjFaQzZiNHArdVcyem9oaUJIUDdJYlJqcWxiVWZyUkVZZzBBcFRlaVZDWU41TWVybElGclIxNEFOYm9JL2lsWEk4aVNsN0FOTVkKZlFSSGtqU2g0MVZTb09NZmtHRXdCbXhZV2ttVjJ5clN3SGFwOE9WcEc3Mk9FeW1qd0FDODFRQVRML3ArUUdrYmNNOWxpR3lBcGx2ZwplQmlhaXJCdlpUaFkwRzBwaFV1aGd0RStDdHJBeFVXdlp4VGFuaGxncWtsQmk4THUwaGd1ckFHUHpYVUNyQ1NER0V4VmpWT1VJdGNUCmlzQjNYSm5pM01IZUl6ck9oeDlTRzJ0OERuc3Q5TThFQ0xRTzJBci8rRGllZHh2S0dEcDZHbVZjdmhVWVdMcGtadDhBQjRnUXVhSGEKN2hZVExIK0Z2OEFjVURtdUlFbzVVdVM0VXVHb29QSFpYL2lScWtsWTlpUllwRlBXOEoyQnRDQ25BTXdscmRHM2x5clkrdUd2SUFFQwo2cDBRTXZWRHdkOVJFMGh5bUJRZWdyUGFHQnlTSkpYb2RFZ3hISWVDWnV4N1dERGNDblVRTkpuaDZjbytOYUFLVkZkTlErblVwclFGClFXUjFVNHBNZ1Vya3A3T3gvTnFHaTlrNjJHQkNsemFBOVlJZWhiT0JYSmdCUW9CaTdKTGgyZ0FnSENHaExNaFlZWWVDUm9RUm1ScTAKZytseFhCenBnbjVQR0NpQm1WQXIrQlFWdmNBM3NmM01WcVZBM1VhdEMwNW5hUUVEcXpCRVc5dUR2ZFJiL2N6NjhlcytKWlNvSFRRSApNK3huMTI0NkV3MGJZb2ltWG1kTFNJUjlqaTJSYkUxSVJIVHNsNWtOS2hObzFrM0l0WVlkS3hCaXp4VVlJb1lQU0tLYlBLRkllb1RrClpBUWpPenJPZXcvQ2JjWG1yQUZJUnRFRzBCYU12aXpjZDl4UFFCZUhobE9xZ1FDWDdNeDJqaUZIRWNUWVorc2NTRkNXNVFJUEJOYlkKVTJocGJkdnVxbVhhOE1adXJJYStBR0tOaDZCbEg1WldqZ1kxaG1FMlk0bnhHNEM1U0FraEEraVZHMUkzUFFoNmhBSWtvRUhEczBWagptK0x2MXBKbnlWQytkUWRDUzQ3N2FxOGVLYjZPQ3BLSk5obURCNUdVcUVTYWFFc3JMTWN6elYrQjNhNGJEdUM2Q1VzT3pqM0dmMDJwCjBkWWVmNGZXOFFhS3IyeG56dGcwT3JBWm9BcVprdHhPckNxQlVUaHdFc1ZBMWdiTVYyM0R1U3lFaGlpbnQzKzUzalRFWTBJaFpkeFoKbHN1ZG8vRE44a0pFTlFNRTFNczhzV2tTWFRWNm1naDBuUmptSzZKTnJHSHZiSUo4VmJpM0EvN2NZWU50TmNzb0t0Q0RRbWU1M2pTRQpNWEd1UDlxR1F2YzlDSmNWWUkzbXNxUWd4bmd4QnZSVG1Kd0VyK2R1ZFpJR3lrK3AyQVl5WnpmVytQaE9EVlpiWm1pL2NkOFZMU1U4ClVEaEF6aTA0QkRUN1NkR3dUYmp2WkhMSU1EYzZGeENvL0dLSXBzZkFnTkFHUTdnWERnVjNjb0lNdEw1QTVVeEhoRUhWSWsxOEZWU3EKWVhRWUlYL2xGdm03NnhKWGRsMTJ1RDFGNkhWQ3M2a0RwSUthNE1yOGxYSHpkOWMwVjNZZEcrOTNhNEZoQVVwSVVKZzBLRUVaR3FkZwpiOWNKMlN3em5jaHQzZzIvYTU3dU53ZjFVZk4wT2tCbGxhQVVjdDJqaS9MY2ZpU1hPR21sS1lXQm9rbEkyMWdBL0VCT0c1TFg5SlY4CmU3Ujc4RmVzcFhQN0ZjYlJGbVdrSG1Bc0t2Y1ZWcVlUM1ZMUGcxQ1Y2R3R1TjB4RUtXM01DWWFpK043UXQ2aXo5QjMzQWhsOWhxckMKZlNYdkQrT2tMN2FMZFN1NS9jNmlKNzY1YnMxeFgrdnFFUnpDZFZ3N0FvTWJQd2RsMVQwc2k5bis5V1JBQnowUmxpK3BLUk5ONjNMQwp0NzFDcS90WGFIWEdTM01UOFI5ak0rSjhiM3JHak0ybmVLNU56VVEvUjYxVE1KNjhZL05haDdFZG0yalRrMUdOVGIzM0QxRmdacWN6CldLWThzNVBwSVNaK1prdHF3aUZtMWhDdjBPcitGVnFkTWNRdVhoVWxzQ0NsdXpCMHJRKzBiMG1SeVVXQ2xpazNCdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJYkRoQ1VrelBDUjZKOHhuckxyeVh6S1duSWFIR21XMGpuVzZEYTUxUFlNVnYrUlRHYVVpb3NTQ3lBWFJ6MnB2b0w5bys4RFU5dWZXUAo2bjFYL2pwNk1DaWJKMmY5MXVWd1lvY2lEOXNMUEsvbHhnZzZwT1Y0b2NhZTJDZzBCclFiUlRjMmM1bnF0UGJ5d2V4TkRlWlRJVktRCkVWTjdXNFlPWEtYdDVoYStITGt2ZGZkdCtvdjdQS1JwWTBLVEtDNXptTHEvN0dVWVpLUGN2aG0rSExrdmRmZHQrb3Y3UEp5cjBxRHIKRmhRWWN1SFdDano2SlpRWUprOXV3Z2Q3WTVPRnNyZWRmTnZ2VVRnTTlMZGUzd3NKSCtNZjlyNjl3Rjl5Kzh2ejdpWDgrK3owNTdJMQoyck8zNUdyN2c4dmg2OXJUWnEvNXFoelVuZzNhcUE4dC9LMW1menhvZHJzZGtPUVhyenN0Vi9JN29QNWVMYTFkakJxMUYvM0xYdnZlCmRObFBhL1c5dStNVlJMS3d4bmhoWGJzZ0ZGRGhVYmM1NHZJd0daNzFnSjJ2eHdvZnZHNE9XdjFtdDFhdlBTOTdyVTZYaXhPS3RpMDYKVnFFNSttUUluM3V2TGtzdTZ3WnBFajJod0Nya2hoM2UrN1RXc0t5R3NSbGo5QWNlc0tsZXc1REUzWWF2bUhrVDl5VDcveFQzRHp3MwpZeEJNN2NHVGsvMEJUTjV1U1JpT09xZXdlazRPanFHa09VR09uaEJoei9zWWFIVkRKTTBaYktBa25ocjRGZWNLL2MvK1B5Z015YUsrClhxbnBkS0psT0lpTnRadGNVN3VhMnNXUm9HYmhnRVlORmZTL0NvMSt5SUdadGFwd3VrMHVLNENCV0t1eGZwZmRxL0YvY1h6dTFWejQKWk5pQ2hQK1VvQko0TTlUTVdjaEVrVjNFam81dnkxKzRjRTJNZjAybnZ1Si9jWm1wRkZRU1dqdTQzalI4a1JnRUFkcGhXa2pMZzJRdQpEejdzaUJiMkYzN21lYmgzNzIrOS9pODkrZ0liNWQwSDNYZkRZZlBrOGZHbnRYdmZ3b2pCcG5QdkFleWtiMHN1Y3UrZ2YzNkJVLzlSCnB3dUVZaVVZOUU2dlpndFlxRlhlNzdraW40UHVldStIenJBRCt4MGluTVp3UEdxMjNxeUFZYjg1N0xUaTZvUCttN0o2ZlVrL2RKOE4KWEVYQXVPaXA3WHUybU9OQXJiSnQyL2tlN2gyV1o3WDd0YjNhM1FnUGJ1ZjNhOVJzN2Y1ZTdkN3o1bUEwZzdLRGZxOTkyUmxWSVdvQgpGaVIyQmU0dTVBWGlDcHg0eGxQbTArbUpXL3VuUUR1VS9ZRSttU1RQUWVYQ3hGVmE2NElTTnZ4VXUxamxKV2d4emxIZkcrU250eHA5ClB5d2Z2aTE3ejlydGlteStUZ2JoTnB2a2lzTFg0Y1JXME9QeE9oUDJhVDZqOGVZdWFPTndqcVpuKy9KQ0NWQlJWL0doZkNpdUxHRFEKZnJmc3RUOFVod2paeXFzcGtCZnF6eVZrNzk3RFg4dldKZmFCZnFDNlU4S3VoKzdDZFpaejc5K0hpWEcwMjUwVGU4L096b2JsNkZNYQpnRG4xWFlVbjNlNGxuV3I2ZzBiekF0VHNlM1lud3B6eWpuMTN4NURXam9DVnRZZG5aN0JSUWVudk9xT3JDTjY3enk1SFF6Z2ZSZDdlCnc4N3dvdHQ4Wjc5K2VvM0MyUzhiQzdka1Blblo3bFFTS3B1MlpqNzBKdlRCSisrMVNta3llS1JGbmtlYTJHMEk0YTJaUlZ0RVUrWGQKcEphYWRMMTNsSjNtdkRhYTgwcTIvQThpaGNTSFVBV3RSbkE0NkYvVWpsODMyLzFmRmlzUVdOQ1dhelE3c3pXSE1WeGVWMWpJVEUvSgpSYk16Y0tTaEJiZDJGMS9OK1hTT2hQZG5GUEYrVEIyMnV0Um9sbkNyN2ViZ2paUHpGdkM2UC9pTkFHaGZjN0QrUmJNMU5neVh3L0w1CjhkRis5M0l3VnZjMEFNZ2UzQm9PV3ZIMzAyNlB4ZzJPRU01Z1RFTml0YTNhdzE4dm1pQmQ5OHV6L3FDcy9WQU9oaTRxN3BZM216RUgKNVMySTVrS2E5UmJOTzJWL3ArenZsUDJiMlhtdks1eDFkd3JZblFMYzVaTHIyMnBtaW5seVI5VU8rb01lN1BnZlNzeFBJSzJvbXpVRQpCclk2WlFZRGVpNkg4NmI1N2tDek5RZWFxM0ppWjZ4ZVJiRGs2NjNEN2xiam1xeEdWSEtTTk1NZ092Z2dkVUxPSmY2QUZnYUY5MnNtCi82NloyOG51VlBFRGs0djJOU3BuanlGemJRMlB5dWJvTmZLNTJsNkdVWmc2NTczc3hjSzk3Q09TUXNWT0N1MmswRWJwQkdzZ1NYSzgKZUx1VEpFNlM3SGN2eTlxMzVicDc0RzlabEdBb2R5b1QrOGFPeUdSV3VHajdFTWVkYVludnlZVElrWW1BYmdIREtpaWcyK2pwWUc3eAova0xvTm5paUU1TmhtSDlEWmpJM05pKzdTQXFLNWNicjY4TG1mNlRJTzJSTldraGg1ckpHYkJOcmpESDRTZ2ZNRzYwemtidnBrZ0pMCk1sUUJOWnU1c2dJL3plVUpKcGZjRnBaa3VhRzUwVkNTbmg1eEJqKzZBWUVzUVhzZnpxSE1vTVZ2TGtzd3ljclc4Q1RQMGpRWEZJK2EKRkJuZkV3SVd1WUEwV0Y1UzY3bThVQitHRVIvY0dIWXJLeTQxT3FWd2VwM1NnNzU0d2NzSzZrWnFweFJtRkRBcUl6R05VYjl5TG1PdgpaNFpkcjJNdnVnRjJEUTZLclpnajJxUjVnZk1nVFZKTWp1MFdtOTJYTUJtQXdGdHNxQ1NtbU1ocDN1d3dHemc3cE41TmoyWFRRNms4Cnh3MUs0bzBBT3pjMDc5Z0dVeVBpMU5EV1JETm5hbVNiT0RXdWRXYnNEc3M3QTNvNGNCNjhIdlRobVBuWHpxdlhYZmovYUtQT25ldmkKbFY5OFJXMmhUY1ZXb3RKWWVLNWRaUnI1MVdOSzdqMStkdnJ6QzVnTlg5VGkyM08xWlhUY2l5OWFZUTVkMTQ4UWcvV2c5NnBidmlnQgpHOHljNy9yNGs0L3pPdXdBS2NUWmlmS0g1UVhNNWVHejNsaTRGemxaZStXUXpFR0ZCMU9Oc1lJRSthRTU2UGhFWjJORTNmdSsxMm4xCjIyWDE2SmtYMVdNUTU5NFNUNlFTQmEzZzFmYWVaSkpiWTRReDJ6eHZsckJ1Wm1YR1BGYjMxdmM4bDVyM2hqYTkyOUYxdFV6b3VKMFYKQlQwWHJXQ1dpWlFDYnREbWdQcU9zOHhNZnBnLzBUQXIxZXJUN0VZT25WYWF1R0E0dkVMNm9lSXZ4bEJXc3pNclhodm4zYzQ1Y2dCegpKbUtxYmc1Q1BSdFNmQ3duRy9pNU43cW91QzUyd24rKzhKZWJLUHpkTW5NUjBYTlhYbXBrYm5ZaXZwcUlsMlNBM3F3VDcvV2RhUlprClRKc1RUckIvQ210cFJqNm9KRm1ZRVlwU0pHMVEyS1c4cG5qNGozMld1TGZrdG1lUzZCdU4vdDZBTVU3ejZ4L2lqODAyTW40RGEzUE0KSXJ2SW50dGF6dXRqckZ6UCs0alo4dnVJTjNIOWsyOHE2cW1iaXRsNzNGVFVremNWeGNSTlJiSFJOeFZ2VFF4L0ErSjJsM3RwSjRJcgo1MTdDQ1RNejh4Sm1YTUkzTStuZnBKYnFOR3VrR0JZa2lpSTFqVlFrK2lOSXZBUlN0S0JRcUtTUU5rU2pLQXkrdTBCME4zSmpNQlA2CjdlVDUrTmhrMjdOTDdQcmpidjhYVE5TNVdkNjNuWXpicVpuT3h1OW44WHRybVRHcWFrcm03YXFRNzZNZnlwMCtlQldaK1UrQU5pKzcKbzU4aWFYbmNPYi9vZW1rNUo3SEorenQyWnhFbzNOUjREdUo0RlBXYThvbys3TFZEVnRHbHFVbWZON3ZsYUZSUzM1K2ZWdTd0M1gvRworYlYvK3BTb2Z2bmIzaVI4NzNscm1pMTNmM3pkR1pYMnQrb0xCd1lUOWc3R09ETkgyTjBYai9kckw4cTJRNTBZZXNHVlNoc3RWTzdWCk15NzdqN0tMeTk0V056SXo1REFJdGl3dTkzaFFsajFYVEl1c3NJbnRHMExxMUlhNmU5S3c5TUc3SmhmTzg5UlFPR0ZtQ21HaWhMcSsKTUY2L2NJV2xLZXdWUUh6WjBtWHpGMk9GbnpaZmxiMVIwNVVIcFFvb1JPcXl2TWhJcTVLWnBMc0lpY21VdTVSZ2NncUZGWHc3UWRqNApWMEw1bFNqUzJ1T3YwcUsyLzVYU3pMWUVxaHFiZDE1SlJmaFRTYzhGSjBsU1VBTE5BcEZSNG9ZRVgrQWpoekpGeVZtMEVoajArQ3VaCkE5clUrQ0hMb0doS0kydnl6TjZIVEJKaHg1cWpuVlBmelRGOEFIcjhWWkZFK0xBdThKYWl4aE44bHhtUTVOcG9kNmx5S3RwWEVOMGUKSC9aUHdMK0FNQWtJcFZBVW9vOVBEdUk0WkNLMVVlcUFXNlgwbzRGcFdSaUtFQlFwTU4waDFOaEI3UEQrVjdwZ2hFcUwxUFVuRlhtdQpIQ1lYN1Y2aytCK2FSc1JNeGlTUmRTbnhMdVdSeGljSmM4dXdsS0pYWVdLbk5yQTU1OFNsR1haeENwMmdrWUJoak5CcHZLSWg3RjJOCjFFNmNJa2x6TzZtMXU0ZWFNZWVBV1lrdWVNS29CQWt0c0h1RzhXWEtDR3NlQjBRWlRRZDhTUU1qS0J2U3h0SGlBM0J1cGtqTFFZdFAKMDBEa0F0QmxpaGVOU2ZGVk1KeXFHcTlJVUU5VElOamVLdEdaMURSN3BNMFBZaEZSdHhUeTN6RC9nUTVhSG1tcThCVTVaQnFsd1lXRgpsaGh0eHhYRElCUnlRTnE4cnhHeUJIbW1lVlZrc05TMDdRRE0zU3kzekJjOGhwNDZPNUV0bWxSNTRvVHdpSEtsNko1TWtlVFVLNlV6ClRjRVpPQUV6MnkxL3FjaE1kY3ZnWWhVNlk2bTFXZ0lWd0tMc1ZNVmVTY21yS2M5MFNyelIwaWp2Nm9qQ1F2Z2FRdWlJU0xFamVjN2MKTG1DeDJOV3RGVFdmcEtwUU5neWZIaXJ4bWJZVGZNbE42Q3dNcHV1WkFieUs2Rk8yWXlTdVlieGdmZEdhVTFvU1JzRTNSUktlOWFuRgo2R1k5VFhvVUYraXU1RW1xSlhVQ3hJUndpNm13VTFWS2l2bFZRVHBpN0l5OWdtSm5mWUtMRWdZRWU4WURxUXF0cVE5QWVVRkJOYmlhCkVrdXd2UU1WaVIrV2ErN2FENittak1XdlVMeWFRUHdnT2lJcWt3bE5BNEZ2cU52NDlNSWtGTGhFRDZZblBEWHc3ZlBIWHlIRmhSY2EKQW1hYVphQXFwSDNmSnM4a3pZZlVyZnZBUHRzL0ZocVMrVmNrWWNmTjZPR2NCRjlXNWFVUTlnRXJYakhDQ0tkUHZBMmtOQTVTOEM0bgpjMXg3c0hxVkpQbU43OXJhWFRyajZXRndwMEQrZWZLQW16aHBjNXI3bmxNZ2xSVXRPc0NaMnRrTGROQzhNTG05YVc4c2xBU0d3a25qCmVhOXg2eE9wb3RXWmVkR1kyb0VERHRIR0RkeTJLd3prV0VGeTIyOVZMTWpUZUt2Q1o2dGhxOEloelQzU1RKTWlBc2lVSUtUQS9aeHcKd1Fhc0NKbVhhVzVBcE9ZOEFJQTB4NjdTaWpYYXM5RmtWcnJsOUZJcTNYNnhHbFFpQkYwbzhoTGNYMnBRTWhvZEZPTEFBRzFvbWJEUQpUSVV1eUVLakNwRmJ3WjNDN2tYVHA4Z0xDaWZqWE5uS2loWHNQYUR4VzRUQlpTeG95OGtsb3pVeXRmTS9Vd21oelZVQ24ybUhNSUlHCm0zZWVsUGRhdDNmRU93OXRQRjc0cGZaeFpMeGdLQkppQXJBVEh4Q25TM2ZFQkRmbXVPMjRPU1hHaHd1bktPM2JYck9BTWJJM3NnQzMKWlMxTWZhdFhBVlB3eFdkY21idzd1Z1VKU3ltd3RrQU9XTVl5WDFXV1dXR1l3VzVrN0NMTUJDMUxBMnViMkNpNXI0S1hWZUtDOFFncgo4VFVscVdzWGszWE1ramI5ZWMycXg1R3VQY3NoTzE0NDREaCs4MjVwVlN3VGFqd2J0RjUzMmtzcnVXS3VIcXUvKzYrcDBjdnpjejRlCkxtclhGcHVKNG5HLzJ5NTd0UmNVVzdVRVQxd1drYzAzMmtZSTBEaHJDMUtWUlRuMkp5cTVvbllYdS90NDBIeEgyYUNldjFycDBHUDMKV3BTZ2ZoK1QyaTVtZkMrVGtHallmbWk5dzduQkJuZWlnaVZtZkhCaUdlZVJ4Tm5wdDM5VEtDdWdVbnRmRjlZekxYa041eGVhaU9ILwpUbTlESlVLalJOSXMySTFPTTlwVU5DajZ0S0hDSGtwQnBpQ1liTWRTN3Mva0I0czBvN1dJU25ubVJTY0lYMUltdEVCaGdCK1NMQ05rCkVyWmIyczJVLzMrOFcrTy9LTmhZQXNHbXIwaVFvM0FwZFB3aHliVGI5TGxia3g4Y1lra1NrODQxOEMrdmJBbVNsOGhVV1c3Rklld2UKMm02NFJVNXFqdkgvSDl0OGREcStuOEd4alFTcmhIT1hzUW9QakxVOU4yVGNwY2tQRG1ObWQwalNKVEtXT3JDOUdPcWJRQTBzb3c4NgpkY2ZYM1AvZnpZdEUwYmFQZ2h2KzVWTk1yblJoSDAwUUtjMHpVSjR6NDg0MTNKZkpENndBSkhTWXdma3J3MEhyU3VsdzZOaEdlb25DCmdZVi9lVzM5V0o3V0R2cmQvZ0RPNmYzTEM3L0szR1FHQ2EzNDZoc2ZaaUlOdTRnVk1wTjZGVnQ2UlE4a2ZwS3hHWUhXQmVrNWJxUE8KV0EyUUZpTlBGYXRDMFo2ZGVSMEt5RXhwL3dBZW1kUVpHK1lkVXJXZU9xVGFQdGlSTEhCRXBVTWg4REViMGhUakE0aEZJWkdjTkhRQwpGbU5tdlRHcHpQQm1tOVVSN1ROMGZNMXRyQStTNW1uR1MwbkNTdGMwcTJTR3pNTG1UV2FjRXNmWDVTSkYwL0VrTDhMOEVoYlo4MzF2Cm8ySlQxQ3J2NWh4MWhxUFlQRGNlTXpEdDdJalRYY3k0aVJROHYvRUxQRk4yTldyMUtxLytpQ1IrUWhEUi9CZjA2QT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJY2pUcTk5d3p0OU1QMzA2OU0zajNlZi9pKzR2eFdrZzFVT3kvUDIvMnl1N0pRYmMvTEczQlo2NWNjMVErNnBUZE5oZDgxT21ldzU4WAp4MGp5Y2RtRTdSb1pNeWpiblJHK1JJOFBhMDI4VEgvM3I4QTBlb0N1WFh2VWZOc2ZrREh2THBINjZlUmJlSmJHK2J4eTQza0lwSjJYCnZSSDByNGtQQi9MMzJoZjBMYklSMjBlSnJWVjd2MXVXN2FQeWJQUkRFNjFvdGNrWC9wTGFXUmRmZ2VyQkhMZ1lsTU55OExhc0llRVgKMklmaDRncXRidWVpMXVxamtmZlgyZ0E2MmUrNUdsbjAzR0JjWTlBY3dteXJ2eTFiSTVCRnA4MXVzOWR5dmJyN3o2ZkEwY3Z6Mm90eQoyTzllT3FPcHo2OExpRVROMDN4Y2ppNHZLSnpjNG4yT1hSL1YwUERzdWh5aVNJQ0R0YWZsOEhYdEJUWGUrWTBNcjFFenRrYWFqTldBClpYRnhPVnBTSndsVVRuWHVxTmw3ZGRsOFZkWmdMbDVlMlBMZTJRRExEWWgvVVY1Y2RvY3h0bWpRWHVCeWkwWnQvTmZ2K2hmUmIvZGUKUGozNnR0OHVaODZGKzdXN3Y1NTNlL0J6SGRnMTZKekNnbmZEZE8vQkFKUXVXK3VhVVh3QS9GRXAwSmk3N1VIcEdNY3VHLzRWL3huNQpkeWp2L3JFM1BIbmJIQXp2UjlNcEx2bzJNSkxnd3pubGVuNTJ1WjRNeDc1dEtIZDYvVjVaZ1RIZGZ1dE4yYTdDR1M3NWdTYm1WZWs2CjdmVGEwRkZSZ1RhWUhMQm1yZkJZVGw5YytnTU4vM3R5UWl6a1JDWDZPL2pBYTVXSnYzUlVOMm1oZi9HMjhsTEhvcmM4bzVFOFVHOUcKL2ZQYmxXVFhOdysvR0RaUm1VQVZCNVpZMWVsNDdldmlHQjhqV0p1dWJNTXFIWjc5c3NhNzhTMHZneUcrNGIzaG8xeUhjN014ckxMTwpvL1NYVHB0dUN5OGRYMWZ3ZGdWd05acGVseTVqeDFLaXVPVHRVaVhSNDdHTXFIZFY2SGwzMjZUa3VwRExLUG0xa2ppNWJVcjhpWHNlCkdhZjlFZWdCZUxCL051aTg2dlNxVURWZFp3MzJmQkoyeC8zTFFhdmN4MERZVzkvMFlXdTY3UzZjbDZObUczU2c5KzFIOFo3OStIM2IKbVRTcXpLNm84T2V6dHFLeHVYUmNkdi9hSEIzMlcwZjlWck9MWjZraC9UNXIzdm15UUVzNWVISVlsNHgvL2c3MUkyelY5VjZvUnRKSQpvcTYvZWZEazBXVzN5M1lhRjdRSnY5b0t5bHRubnNNdkZ5V0ZlajhlZE5vbnVHUWVOVnVsejNTQVEreGVjWHZlNy9SR3lNMnBXc2RBCldiRGQwRUJNRnZtKzEzRzkxWGt5cjNVeUJEMzhkZVJadTZBczlqUXVxblNPd24xbTQ0KzYvZjdBaHUxUldkemRza1ZsOS8zTVdGcjAKQlJzQUZwVWt3cUlPNkxsa0VjNW5GODFXWi9SdU1VY0paK2lvTkJpdk5yc284aXB1UFM5eXNhQm9RS3JtOC8rSFR2a0x6TFhEem5BVQpMSnRHNjNRQllzK3JISk1UVVVES3NwazFJbk1rRlZqR09oTDNFNXhieEdUMzlCck44YmtMNHFEc2RnOUFXcnVDNlZ5Y1dQQzQ4eHVQCnh2eHUvclUvNlB6VzcvMDFVb21RYlhyUk1Idkd5VG1sdnZPeWJuN0RoR21TUWQ3YWJTTGJkYk0zNnRTYTNVNXpPRjB1dG5IM0wwZmQKVHErc2pjcGZlUlY2TTNIQk5tc1VTSCsvQkd5amQ3V2o4bTNaSGQ4NUFLVThPYjdvajhocDk3VGZYbUs2NXphSGRLdGl1RXlnRWRFVApFaTJwMVRXYndPZFBQYzRrUTVQbGgyYXZNM3dOcEVRemtWeCtlU3JNVWt6WWgrZmRacS9FU1JJTHJZVnJtMnBRY0h3SG1ZZExvWXlXClQxWXNYejRCejNmOWk3anJWZGRmUUxCUEtsV013MlNBQXhGVndUR0xnVm1ocXpFUVYvWnEvTHZzbGdPcitqM3B0Y3Rmajh0V3Y5ZGUKcmM2anptQzRwQm1hR3ZPSGFWNDFUODc3RGE1SGM4V3g5ZlduaGpiTFJMV2h0ZTYyNlpGbHlnOEcvUXYwVnRyTFpOT21pUW5OS1JjMApwYktwZHFPeEdXL0FKVlI2NnE1UGd5NzBZREE2N1RjSDdacVlUcjhVT2MyOHZIand3b2tRa0FvcUZncXcvci9ydjdDTld1TDd3NDdmCmpDVDNvM29WTVNIWW5neTVyODVqL2UyMHRzc2xZcFZ4Z21tcFA2ZGZOTnZ0Q1lGOVRvOXFqSUdHSUdzblFDQ2MyWnZKRzB6N290TVkKRittdGZuZmdWZEVIVDJvUExrZDk3elFzSnpDU201RFY1TnFiWHIvMUJnUjM3WlVOeVZoUXREUHNnOWd0YTZkNFdjY2x5Um9yWE5RdQptaGV3RHd3NzU1ZmRabkJReW1qbkdRMmF2ZUZGRTA0SHJYZlFacWNOcGJtTFdpcVpSMldiUEY5YUZEUWlvZVhJZXp5bldFVlVyeUtkCmExblpBVy94c1RJd282U0lPcmkwYU5TQnBXVjlCNFJKODlTWDVEUEVRYlAzdGprTUdvNFlHNy9uN0ZESCtJVGF3M1puMUxTQ2JVSVQKSTQrdWxUZVJVL2MrL3V3dmVrMU04Y2w3WUJNZWJ5RnJNQmtmY3g0YXZLcG1YZUNMbk42MjBoSHFFYkRDcUJKMWZMTFNlRXVpOXZENQo4Y3BOMlZyTDIxclZ3ODZ6OC9pSHg0LzZ2VkhRQU5Qd0F3eExxelBtZG5jUDZ2N3dHUHZ3ckdkekdFNys5ckk1dVVpcHd2bEYxKzlTCkU2M2o0VFppVzFUdCthdXpjZm9BZHZqZDRYUkJsQ2QvS3djVHl4bCtlTmdER2U1RlFkVHd3L1BUc20wbDBMaW9ndDhvTk9lN2FTdlQKMUFHak4wWHJWSkhYL1YvKzJtbFBFSDRFN2JKMGZ1TElXUjdZUWZOdVFUREh1RWFPVWhaVjhRZW9pc2NjOEdVSTN3RUdweHk0NEpRWApjWERLVk5GblRucytqclhuWkY2cDc3eGVIMGU1VUJITDlucy8yUENXL1RpOFJVd1VmVFlSWTFNbC9BV1hUR1UyWWVFbGZMSVlxekhLCmxsM0txZkZpczFsbHkxVGpsY00zUHlDcHFQWDZJV0NwMXVsUlFCSnFHS3haTFJHYnJxMTd3Zmg1NytmK2FZUFFOYnRkM2hHR2swYXoKcVFvZ2lXQ0hmVFZCd3p5OGkwc04zM1F1VG9FamI4YWx4R1N4QVp3Y0I4TVNxUmtzTGduN1dSQlRkNmVWd01ueVRIWkUwWDIvcXlHagp2K21mUHVtZDlXdkI0TGFFMGZONmR0b1puVGN4OUd4Uzd0dTlJaTUrOGVyOFRlTVVOOHYrMlZuRG1yUGRQajYzK0Rrb3djUEo0clBZClBvNzhjbGpDYmtNYnMxK2dUaUd0L1ZpZTN2c0JSRi8vM3RNKzdPZmxUNHZaaWF3dmlUTmptdlpVQjRhamJxTnRtNkJKd2tPNlpMU3cKbWlzZjdMRlY2bHkweitIbmJxOXlweTdhbFpIYk1BVmZZOWJZWDF3TVhMRUZZd0psWE90dW5JV2NPZEpRTG5JUlpzWGNVckhQVGVUegpTblhPWVRFM3VuQ09xMVp5MU9jQXYwSXRMamtJeldkNmJpOXQyWGpHM29YSkJ4SzFYVHQ5VnpzY2RON1NZMzRMQmdHeDlPS2RZYnFoCjFnVFg1aGVLbWJZQVZUK3lIUzVBTmxGc2F0Q3BGQjFXRm91MGRqbnN2T3JOT096TUZMbW56cm0wQ0NNVjdKOTFKczMyczJYNDBFcXUKeWlKMWJEaW1xZTRPR3VmZXpqZXZSS3Zmd3lSdGVGcGRRQXVXOUZ2aXFiMzBaTSt4TTBzUDJvMytBSlgzNXJUZVBWbndESlFGenNKRwo4YXd6UzEyNEUvNml1VUN0dm1vc25IeXVqQXU5RXNuY1VrUDB0VEN1cGVYZUxxWngyTHJvdHQ3TmwwcTJUS3MzYVFpYkxET0NzMTUwClZwOURINHhUdDNteG5BK3UzSUsrMHc1Vzl0QU50a2p1WXFraEoveFlPbk9wdUpYVFlXRlVxUU5UZm9TWllseFA4R21sZVhzMGlIaFUKRjhkbDBZSU5la21aMXFCL3NhUUlLbXNkVUYrV0ZCdEVtVHFXTllvR2c5UG1ZTGhnSE1kVmpMQzlWQ2c4aWtoYVZqYmFZeXJvUmFFYgpGUXI3YmxRb0czVmoxaW82NjQwYTdlNWlrV2ZMWEF6TytyMUY4ZzZMRFM5UGVUMm1zOFpvQ0lSNk44dk1VUnlDS29ySzY4SWl2ZkpWCk0xaHQ1eFRDRXdnb3RNUEZzd2JMd1hiVFc0eXJLeEJiMDN2YVpvLy9zREY4M1lSRFFMbUFTMWlvSEtIUGlIUDRSeGJmaVlManBiSloKY3Y3WGk4YlkvUTNxMnF4U2cwbmRudXhIczBxK21uRUttRlhPN1lMQndUWnJmb1Z5MWltMnVHUzNzMEJrUUFGMC9qWEhEdEp6Q3ZZdgpXZ3VrQ2hVWUxoaHhLdEMrWEdnVFdDQjVvZnBpTlFOT2RNUGxld1NWT3J2c3RSYk1FbHZHV1NONHBpelpHS2hPczlkalcvdnMwelNWClduWTBhSjFINnRMZDd4dkhqWnE5NUFpbjNIYnRYM2VQZjN6Mi9GK2YxdDdLSlllemM5RG1JcFZ2bGc0SlpmQjQ1ZjA0YzdyRDE2ZGEKNSs4V0hOdWpnbjM3SnZmMDJmb0JGNDlPMTdFdFJnZEw2UFBPcjJYM2VUbkFwR1JUMXBqajV0dnlLWnlkT2hmZDhzRzRIZU1LaC9WTwo3MDEzT0lKRjVmMyszT3NudlRjMXZNVTIzbDF2Vko4dzIxN2d4VHMzYmphbjJ2UERSODZhaFZwRC8ySmtUVkRqSnNKditxZTFaL2FuCnlPYVZaZU5HdUxoVU1NdmYyKzh3cFErT0Q1NDh5ZlZoaVRNQ2YxUi9lZmJIZjM3MjVZOWZmWEsvK2ZMemI5SS9QcXZ2ZnoxNGZQNzYKaTFlOTMzM3o2SGVmMy8za29OTnNEUDlndnYvclEvUDdMNzcrL3ZHZm42cS9mSEgwcjArZWZqMjRiR1dQSHNxbitSMmgxTytUWkhqNAo4K0dyejVNL2ZIMy8zNDAvZmYzbDV4ZkRyNGQvay9mMjdueDkvK2gzQXk3MHpXai8xVi8vZnZUMWw2bzhQdWg4OWVmV1lhUHh5YXVwCnBvN2EvNEQyc3NOSGQ3N0kvdnZ4NlBEbm4vYlZmOWMvZjNEZVB4ckM0STVlZi9abjgvdkxSNGZxRHovdS85ejk1TWU5TzRkbnlUZW4KTTVIOUlTdk9zaC8rL3M5L1BmanVvUEhEL0ViamNsLzg5UFdYYng3OTlQVVh3OGI1WjRlZjM3bDhkUGR4KzJ6dkRqSHIwZitjUExzOApQUHZweDJ5LyszWDM1UmRuKzY5SEI2K3oveFpqN1BpZlB4NjJ4TkYvdnY3eUw1LzhhUEZBbDRjSC8zNzE3ejU4K3VOL0RwKzBuL3h1CnY1Ny8vSWNIeC9YZjkyd2ZYamJibDN0M2lwL3ZmdFo2Mk5KL3YzdndXcDNjLy9MQm5mU1BuKzEvKy9uL2ZQYjF3U2ZmUHpvb0wvLzAKNXgrKytmM3IrNjFXOHcxKzZuejI4T3pvdFcxWkpQZWEyYUR6aC8vNW92UHZiOXI3M1R0LythUSsrT3hmbHcrT2p2LzRIK3ovcDEvZgovK1oxdW5mSDNQL2hwNjhmOUZxZm5ILzIxZFA3OTdMemYzM1Z5Yko3dzdQMHdhRDFSSHoyNWd2aE1iWU92eG4rQUd6TFBpbXpIOU9rCi9VWG40RjRUeGxjOC9lcHUvZk55djVzOVA3Y1UvT1BvenRjSFQ3NzgvWThQUHkvMEVNYmx5VC9ONy8rY0hmVC8vZG1YUDdULytZVTgKL2YxUGhQYlB2VHRBMEovTm4zNlBRL0pQODZQNWV3LzU5T2Y5TjUrYXVwdWFQN1NQRXZIVDc1OGUzbXQrK2NkSHYvdnN2d2ZZaXNFZgovazFZcU1qZW5lVDAvejVSOVBtelB6LzYwbjM2OHNlSGY3UEZEejUvK0Q4V21meUhmQUpUOTJYeTJaLy8vUEJ6ZWZpWFYxODVQRDkrCjllWDk5cy9mL3B0RzBuY1k4RDNiMTY0VktMVC9qZS9BVDZFRDR1NVhMN0JRcVFpbWY3ZC9lRUtzUGl5SGYxSG12ODNQclFmZkhmNzgKMmVIWnZiLzk1Mkd6K2NrZjlzM3A5Mzh2bnQ5NStmMkRad2Y3encvUGpqdi8rZm8vUDMzeGF1L08vMi92eTdmVFozSUZuNEIzQ1BzTwp0dG1Yc0dNZ1FCSUlFQ0FKTzRFRXdrNzM5UHh4bjMycXlydnhDbngzenAwejV6djlhNEtOVktXU1ZKSktLdVdDdmRhUUltWS9QT3NYCmg3aTdrd3Qyc3k5azRmZDltUC81RGZzVDMzL1dCWm4vZHVHQWdLbFJKTktjYlRsODBiZjlYelg3VW5OVnlZSnpWcVZvd3hDYTRuMncKK3FlZHIrRk9kOFo3YWtLcGNIU2NTYlJPcG16cjZYUytuSnFJc2p3Nk1BdlJQUmdaVUc5QWNsN3lKNE8xMko5WkY4UW9tUzVnNUdjbQpnRmdnT1VxU0JjQWRMbzg3dDQwTnhHc2xwQ3gvWVptRm9EZ252VHllRVpYQVhQaDBlcXFWc3NNbkhIRk0wcjFMakVqSGQ5V1h4Wkt0ClB1RzBESkxVUUlUa0NKK2JzVG5wc08yYytXVzR1U3E2YXo2UzQxUWdBTDB0MURCdnhSbmswQXdRcWo4Ym1KclptVjhzaThkSVl0cHUKWmlOOTRsMjhCcS9sZFVjQTIxUXFlajJUbU5TU3hGYnphdDVnemJicU16ZlFNS2xZSVZmcnJhUkdpOTdrdlZmcVJiNkIwQlFKakNnRgo2NWVjYzNvbG5hL3JCRmtJOVFsM3FqVHlHcXpjdk1Dc3B0OWtzUkNLNU1MZWx3NVNPRDY4M1BFZ3BBWC9hT2ZLL1o1bWY3bjFwclBOCnRwWmRDd0JSZGJNQWRrWFA5cGtnYmQ3SVI3YjV2YlNEbjMzWmNtRjNiVWxwUzJmaDIxNE9nOUZ1bDVRV0xIYTZaUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJUm9VREJOV3ZWb0RNTEI2N1VNR1BDcFBnOGozYnRrNlB3dmRzMldicll4MzlYWHVUU0tOeEd3SEF3ajNmUG1ISjNNcXgreUdUSmR6QgowKzM5cG12TXB3bllTM2pLR3NjbTU2TGpjZi9PN1RTaXA0Q1RIYWZJQWd4di9uYnhQRHB5SnlySGI2Q3hwK1pRRGordlA3SnZvNmM4Ci9UU1dIV1dTNWJ3UHZETHFBQzFRcytYdy9ubVlmVHUzZ3R4VDlETFFZK0NMdjh4aEdyZFJxOFdYVDM4dm1YN0pieUxONzRVRG53emEKMllETmFDbENuczdqcFh3dEF6K2xzS2NTL29qTkovRTA3bkhrMCt4M0tlNFhCaXYzSnZvVy9wbURxakNQZm9qK0RML1ZpQVo4K2tqOQpta0dRaDkvbEtHRFpwSmVNaEx5RkpqSHM3NHJ3bFNSNkdmNVpNRmpaNGVYZ1M4OGNIQW9MeENjRWtXRUhuMkova1VDdndORzhvaUd4CjA4MmlnUmlzYUpyVWhPR2dJcS9sZWd0K2wwREFPQ3dJaEpoRXpKREZTTkdmTEx3M0dndjdhL1NiQkh5T3BwSG1TSWxlUjhPanFMaFoKSkJvc0NkNFFQVmtzU2RIU2dkVVhMcFRFMGw2eEVLSmxvTEZRdjRIRTRtQ2phU0E2Q2NueGlHYkYvWW1Bc1poTEVtUElTTTRscGI0awoxSkRSSnhZaWhWVDRKOFVXUVBQTE1ZWXNXOENYYSt5c09GYVJKQlo2QURqNWtsaVAxRnlSNUREa2VPVG1ERjkra1NLcVNGSlpBajVTCkZCTk5FOUVrTGdTUkZvNG16MkttZUZxRUZMM01TUjNnWkc2MUJLdWE0cmdXdlE0cGtaVVFsUVE3d2xkV2VWQk1paDdRc28vQTZpZTEKTXI4Z2tpTXFJc2cwajBrcFFEUTFWalQxc1NHMUpLd01VZG9TamJFWmp1TE9GL1NKSWorY0JobzgvS2N2TlAxYzJWYW51aUV6OW5rTApXUHJmQkgvRGlHVTNZSzljMU1oUnZSY25qUzRmMk1YZ3ZLTE1idSsxQU11bHNNcThtOXVML005Z21DbE9WM3NidFpYeHpJblE2VlhlCm5lR2JIZTUzNU00QVgwem8wS0NCRmhaZVo1b3kvVjRyems5dWp4TjRXNWc1MDdFN1l2bmx1ZGt2Vkt2N0hIOUN1ZUU4Mjl3VVhqSnYKZzhNRVdMRHJ6Qjh1eE9KR3ZrUDhHVnNQazk0UnVSVS85WnVjSDhBSjdleUtVMC9Mbnd0N0NDL1BiOFJ6azBWaDdpcVdPZHNLV2twUAo1eGhIR05vSys0eSs4RnczdmhFQlhGUG8yOGJXNVBhYk1zOHVBSFNENEdmZXJiL2UvTXpDY1FGTENWanJvZjR0em9rRzF3UmFTamM2Ckp4cGNFOXJxWXpuVUM2ZEd1Y3dDMzNldzRqeVU2TnAzS05OcjBMYXVhUHVvKzVSRFppeEhKdzdVLzF1ZUJYS2tHWCtxL0ZtbzVzSjIKZ01BNXlUVXlINjVjdy9wMVF1WXdWQlVSQ1RyeGZSSEU5cWx3MVZlby9FYkdITm1BWndFSlI1TS91eWxIT3V0YUsvdlNyZ0oyQjlKSgpNU2MzRURtbmdxSm5LaHgyc1FKUXlxM0RpdzlrL1J1c25QMS9PZEQ1UzZHMHNzNkJlRFdTTUtneEJaODhwOUxPTkluRjNJbmdzeEJzClRjWkpTZG9wRFZQS3ZxMHpidkRyeFI2Zk50TXZSS1p0ak5HZWFzczFCOFJhQlZXY2ZxSy9NdWVYbjhZNEdQQnd5S3orbHc5TTF3ZGsKUDdlcXU0RWo4dm9kWkFVa0RoMkRRVzVGUEJxNUJ5eXpZL0haM3hxRHkvUWs4SkhET1RKWi9QU3hVQ0xrNE10bEpvdWJNNUJLd2hyNwppMUtjNWJINFA2S1JhZTBwMTNqTmdOMmk5L2RNRC9UY3MyWWJ6MjhkNkdzekQ5NS9BelNOdHpZc3NqcFBYckhhenJjdUhWL21CeEZtCldpcEZ1TytOMldCbFdaTE1IQTdMZGpCZWYwOGpCQWtzblJoQjd5NlBmY2Z5RlI3c2wxMnVuQXVlY3hqdWFSK05nalg0R0dSamlhcVgKZmRBSzduMC9XZVNMRlQyWmcrbXBUTHFjbmlCUVYrL0F2L0hNTm1CM2FwTGswR2xjd3BrR01zbkpZSk41YjdodDhhWDc3UWRzZnJGZgp4T2M4N1h3UndDaDdDMDhIMTRqaXNVdU9NUlpUMUp1cy9BcUFhWk5lSXB5MW9SMFF4bUhVNURmQUJSMlZwWmMzRUNpOXdCWGNmdWQvCmpqOWhHRlh3ZmpTeHArSStMNEtvd2N2bmdXMFl3YzdOU0c4QW1DL1ZOWG9samtlTndPWW5uYjNYVTdiYXcyZlVNajVXbjJlRjJWL00Kd3pDZnd3VDg5RFJXeUpmTjFHYmszUnBUUGlvUVFFWFAzaDlEOGZuSU5xZnBWSDcxNTlhK0pnNkF2bTJRMldHd1VoaWYyOUd2NG5CZwovUUNEWHhneis5ekF3ZTVZUzVidmdOWU5XNnlBRXJFSzNITVd4WW0vL3lPMFlaREcva0MrTzcxZjF4YkFVb3E4MTNkdndyMmJlak9TCkRCVG54Y0hMWkFoc2t3UlVPTi9PNHRTTmZXYURqbGdEcUwvM0tHVUwwT2dENWt3eTNiWVZLbjgvSDdsUXArdkxObHl2aTJ5ejVRYWUKUmNsYStvcmtWdmpzd0RkVnFBM2wwVitvZk5SYzBOaG9vbGVBZGs2K1NRMCsyckpaM3NpaDJkWXJmQU42NWRaUmk2Znc1SEE2a0hIRAp5ajZ5SkJiV0ZlQ0ptQ254YlhsYlNpQU5nazIwZVN5NlhlRnYvdllHMTJvM3pBMHlIY3ZweEdLdWdTVmVHTU9uR3RrRW5CeHErYnlDClIzWWpWdmtvSldrUTdQNktJclQxMysvditJKzlVUWNtblNkTEZucGxsOVRVQk8rRjNBWnI0bXY3OGFuMFVzY1ZlWjRtWGtTdkpPWUQKNXdyRjBlTFBpOFJQMGJQdDQwQXpodkRzVzRqOEt2MmRYSGI0M2krallTNjR5SHdFZTBsOVNSa3k2WEMzbEgvT2Q5SWkzcUJQTHc3RwpEMkEyNzV0Z2tUTjdublZJZzhKOGdMenZPNE1WSFlCSXJJRVB5R2MxSEg0azkrVmtZVjBMY1VZd3ZZZ0RzN0h3L1RiYTVuOU1saEJnCjdPQkxkcE9xYktWNENLNExaTHFYN1hRWHEzLzc4ZXhMdkZqTkpISTd2dVZOanl6cHlCeThzVFBVeVpsczVHdjJYUGlPamZ6Ri92eGsKRTlFejludXd0OEMrUCtobHQ4c1hGNkNZa0ZsWWN3bjkrY2tOSGd3cVhlRnhTZW94SEpCaWtOZ3FXMnhsSTdFbU1odUhoZS9HRWV6SQpsS3FnUjFzMmsvbnMxNExNWnhiTnN1VVJyMlJqL2xWVytwV3M2emZUYVZYR1pMSnc0bzBHYUdLektSTi9ueTh5MGQxaGlPS1NsMWlBClErZENhd1c0NkhXcGRhYVVtU2VFa2l5dDYzL3VWS1JVQnZ2THZwL29zUXNWQUlxeWVJUmgrZ2Jnamw5YnB2UGRPdk5ncDhKUDU0S3YKT2ZObTRzKy9LNTV4RHY1cGhVM2tKazhmdmJEaXVzOUM3elgzQjNZL0FmbnRhLzl5UGhneHBKNEgrZVFvdjV3TDVjSHhXUEJNeUdMUwphYkcyQVMvMjlybS9sMVRva2w4YUpyQjlyZnJRVWtyZ0RxRG5nbFpncXJYOGhlL1dBVGg3MlBjZlR3SXJ4NjlSeVVvYXE1bURlWEFxCmZHOFBQZ21HallGZGMrR0VaenRkTXYrZERuRGlRL3N2MERpSXdFQXNaV0tSbHU3dkQwYUVWc3RDS1dXZEF4TWpGcVppc05OTy84aUMKVFpDT3l1d2RPcGVmVUVkMEMvUGtBTG9LWnpmbkFES25QQUdYd3hrTkhSTHZ3Q29xL1daZjhGd0F1Tm5wVlNhWjJwbjVzc2lZUWVEVAp6TStqSW5iMDlNT3BkckNZRFhtckRhZ284RXNzNkNVMDBBRkp0Q1QzSkJOWjJ4U25vUTNBN1BVNUpZaGx6MGJlNmlSWWc5NXJkcHY5CmRraGpBWlN2UnVWQU9JRDFoQzNpZFhjQTdLUXRtMUdUcEFyWW5sb1hPY1puZysvWUNRaHhhNVBGaURUWkFFdzF3b3JUM2lGVXlKUjMKZStabHp4WWFkR0dLa1VxOXpCb2RITkxXaGZ2eHFmL0VvdzdZZGI1eTYwakdnbHdKK2lBekRBOFhJcTR6MUJmTnVQYzdlV0JueWc5QgoxTXRPTExkZTcwWWlCNTdqTWQ2MlBTbE9zS1NkYjhIVEVNUFVnK3g2UEllbkVtWjRXSU5sbTl2YXFlQjUyYzhZUzJsMVprZk4zMThRCkZsdHhhZ3AvQVUvR2VDQ0wwV1paYkd6c3k4MGFjcFFUMzM4MkczRGJmOE9jTFNSaEFkU0J4aTc2MEdJRExBbzJSZUs5Nkg2eHV3RUIKQjE2bDkxSjFJSVpWQzhCTStxUXdHNndzN3ZkTWNrMDYrVGE0R05pYnZOeEJFZDdubjR1eEVkcFEzS2xqUDhZcFI2QXQ0WlFlSFExbgpEM29vei80ZmN6eEpHN1RNUytSdzdROERIUmxlWnlMZFJURWJMUjFQOE9qYlN6cWV2SjA4M3Y0N0p1WngyeCtZYzlQSng1emEveUVyCkV1cms5SFF1MUpibmJIU3lXL0MyQktSdys0MXhHZGg2V3l6eGZaNGZ4S3AzNnlyNGViOWdENFlSMHhpczRUMGVld1AyOWh0SlpoYUEKeWQvT3JaazYvNGFSMDR2b0FQMkFPbUNmZHdMWUk4bDY5czJUQWV1eWNHMzRXQkJ6RnFkbjB6QWI5ZnBNMENBTWk5Z0xiRWViZVM2NAptczNDbmZaWEp4cEo1OHY1NWNmTUJEMHNVeWJaQ0F3SzFXclN4QjRXaTM4RzdERnliQ3RtRWw5dFlIWkdHbTZNOE95blFNdjNWMkRQCi9kNWxtK3ZRdTBBSmo3dVpvN05yS2xTZkFvRHR6Ym1kbEVKbFR1MWYrNUhXOEx3eFdNR2IrY2ZDSWhRMkpUM256NTl3YXU4cUFpL0kKdFNlVDVKVG1SbFkvc2FxSjBVbTBIanZTVHNXcnpmMllpWmdLS0hjQURPUXJIM21iYlpQQUd0OVpCbDR1dUJtZnphYXRPREYydmViVwpYcnhWNnZhN0c3QXVweHdYemFOZWVSNU16dVRvNjd5RTJSWjI1QnQ1TjU1V0VDMEVmN0V4ZUxNMHRScmZmdTg3V1BpMkk3dVpMSTZzCmJoTkFIQkIvYUEvazVWZ0l3SGFBOFRvNEF3TDJyRUN0TmM3Y1U0ckgzck90ZHFURjBTNjJ5dnpXd016LzNnVWhTMGpsMFR2WW9uYlkKTVlzbG4zZThtQ2dpVnM2ZWJCVmNQLzVwMHRPcjVySlJUd1hDcy8yQXVTQlpaUTBpT2NvemkwTmJlRVZnVE9XbTJaZHFHUjZYTG5xUQpEb1JnU0EwVDJCem1ING54Ky9ZWGVLLys0cStWTE1hMlA4VkJkOWtHQ3NmYmszaDlGRzYvZlB6U0dxWkdmc3JDSnAybnhMWTREVHRECnViclQrUlBaVkJwdTZJbUxvOUVOc08vWFNUdGdaMHUvNk8xRkY3bmdlOERMVy8yZmdXZVJiUldPcnZDK09rNC9BdC9ZQVp5ckpDN0UKeDBKeFBRSjVtY1JYajRXdm41Nlp4MmdzSE9UV2d6M25UdzVFb0pGZlptYmVRbVdkZnhkdCtSalIrRFNUam1vdUN0Ymx0ZS9aOHVZdgppSU9IV2Mzd0EvM1BVSEhTS29ZNHpTakEzSWVHUTNtR0F0Wk1oS1FmUXpFVjZDTUhzSmt3NWhJdmprZS9udXdtYlh3bFI0NHZBZ3JEClorSEorSTF4dzJOZ0R3ZUp5a3U1R1k1MzJ4TXdsemxKbTRpQTFXaHQ4WVF0d09vRE04OEpFSHp5WS9YaHVQbExVMnBSS0RaMEYrdnUKR0pBNnR3ZklVT3RZbktiS0FGVGJ0clBFMnNVUFMyenhEbnhrTUxJeWpNdjdCdG5XY25xQ1kveXZGSnVDSjh4N0s2Q3J3elJrK1RrKwpLdXYxR1NXNGJ3OFB2QWFlT3F2WlpMS1NOVitqTHAwUURGTUxYd3ZrRUYyQlU5aitlME5kRGl2K3NXUnlzdlpyNTZXU09Sbk1UUDArCmowcXdpQi9RSkQvZVVhWDhQL09qSWh5Q2dvTXlUQ3ViS1lDRExyNVkveWdWbUdpNTNFY3lBWjhaT0hXTEUzblkvbVVQcDM5dkQ2dWMKU3ZFajgwUFlneWZQWmEvVE54VEpaN015djJzZGZ2N2dkU01LNmVjc1VjZUxlWVZmZWlFL0RlYW1lNjJ2OG1lcE5JVG1mTUVickJJOQpHRm9BTW1vZFJKTXJlM0MwbG9DQkhzYUgrY05wT1grZ0t4a2Z3TkpBSGpvKy9IczUzendjeC8rQ1FqYmVQUENGRWZMTHcvZ0l2K1p5ClpKbjdRSHdQN1NNQ0NmNFZBdnZQOXZ5d0E5ejlBS1JzVHJFcVFrMkJXOERlNUQ4Q1JKNEhnSXo5NlFhTS8rRzBoU0NtODRjZlZFNDkKZmxpUC93T3ZLUm52ZG9CdEtRaytucWRMT0x6S3BvQ3E4RGd3RkxZTklORVpqRzc3emFIL09UNmNOeXZZTk5pbnJHSVlzUUdncDRlZgpuWEk1QUVON0VvajQrM3dDTDJCVFgxYXFLOFlQVTE2dDlDcGJlcTQrQktTb2N2d1NJRm1OMERvQWFySlhpMGkvR0VRMG9JdVF0WEpmCmphdFpWVUQvZGhwdlpyQnppVUxsQmdPMnZ0MXNwNmdMakx3T1ZzSkY3UURnTVdCY1doSENuVU9ERGhUbzRPejBzSjJNVDdYeGYrWU0KZ1lPYVJzMVRaOVVmNXJvcmdwRFpOVmd0eUUyMkFvdHhzNVB0dnpUc0dJZ0Y1QlNvUHBYTjF5UGE1SVdpZEg2N21hSGl5OG9NVVB6bgorNGVwTWRDdzA4ZzNkRkhlb29VRUUzTkhXQWZCdUNYU1gvekNxZ0wyaWoycXFFQ3lLNHpZVU5IUUlVWjE0VGtTY05NSUtoSU9zcWs4CnA4a1ZUWXAzM2ZmNXJieWlMc1pBR1lQZGhMNTNraE5kamVoNHYzN1dla2tCODF1NlhmcC91Qi9xRXlSdEtwRm1SQT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJV0RBbU50RVVyUm5xNWdXNEN0eTlPakkvVUxwTVVrbEdSRVlaeDF1S2xoeEVNejdOVzh2ejMyUXovbGxyTU0xb3dXbnhMZ3BUMzhxQQpLWUtJME9KVk94TWh0Zm1BdCtlOGE3TVVkNkMzOHdTdTZIWnpha0lPMG1iRlNzbWlWR0VvMzlJRDBFWDNjMmsxemJsU1JPV3BJeTRUCnpWM24zc3ZUa0hwRS9XSUQxcklSaXJTYVdEL3BrMFBXa0FjK0szaUIwczE1MXAwVVZhL0J1NitnNFl2dWh0Nk54ZTRhZmNNV3hSb24KbHZFU2wwNXVndTFOSit5Z0JzZEpkVmFEdHhReHp3eG8vUHh2Skl2RzNLblFLT0pPZHlaK3pPK3VlOTNwNVNrQVB4SEJaQ01lWUI4MAoyRS9vUVNLUWJwMXloZTlZYVZVMk54L0g4T3dxeFQ0bDNJL044TkxvREpRZmpWNi92V213R3QycFZkTG9mTzdIako3bEQzZzArdllaCjNlZjRtOUZUN3hhTVhxeE9ZUDdIbmdPaER4bnp6a2J3U0J6cllIQ0ZWVEQ5TWtvRmN0RkFOTndQLy9WUjRnWUtpSEJQc2ZKd25qZFkKRDRmVTR5VHIyVDAvWmFxeFl5cGFUcjc3eUcwLzJDa2VQdnRZb1UvMld1Umo5bkdLdTdLUkRZMGxZR200ODE1WEUrQ3JoZVdtUzAzSQpGNmpGTElCaUZ5L1Zqb2RENHRnQ1NEd1Z6Qjk4bzZiQmpld1lKVThkWXJCZDJiQ1pEVWVZWHppd2h5L3NtQVN3bzJkM3FtUzBvWW1qCmRTbXNmUDVqdEJTTTdoTy80TS9TR3Z5NlZ4QWkvVHg4MVQ4YjBraExrVUVvWGhuNEpKRU9MTTgxZzFXRWxrTWEvcW1Xck5KSWswYkgKNFloYkQ5SklYL0hQb0ltSXV6aWtCaXVIOW1qMzFMMHlTRU5MeDlqZUswb2pEVG8vM1VsaUlUMVRFemtJR3F6bTltNWRrNW9yUnVhcQpHUm1rWWJObGMzQSt5aUR0RFREeSsvbU5RNHFLTEZtMEpXUFNoajhOVzVKSVMyV2lKVXRlb3A5cWpSQlN3SXVUb25CTjN3RW5mNTVUCk5ZaldlYm1xamw3Z1k0MDdBZExnOW9LVmFsaU9SdnBxdDR1UWhrSi93eDJIbE9Oa0N1M3c4TFhjdEdTUVpzYmhDR25CSlpFTzBxT20KSE5LeXdXb0pPQktmMG5OTkdyK081dVc4S1kyMGtYZW05cGEvbWhSU2QySWRUM0ZJd2JvSVdjbVY3bWRlcEpFR2V6Mk1qR0hQa2toTgo1Q0ppYWY0UkwxSklEVmFNL1BvaVplWWFObHRYbTNwZUR1a1lLM2xHSFdta0pTeHJuenNpUFlUVVlCVVQrR1QycEdta1BhOURST0QwCmMvQ1JKbS94YzBVS2tQYVRXQzNpeFNGU2x3aXB3WG8wbGVmYmNIUHNKUURheUU3TXY3V1AvbGdHYWRnY1djM0lnUnpTQWxaM2ZjVVEKVXNoam9ybFc5dkhNNytHNUtZbjBMV0VQeUNLdHp0OENtQlJTcVBtREgxN3NiZWcwU2MzMWFLcVc1ODhmZmFkREVtbkh2bG5JSW4xYgpOa1lUaE5SZ3ZaenJSd25yVkhkSmFhUzFnTFZOWnBLUDBraDNUeVlwcEVBblE3U2RZY2wwa2lId3h3djJucTRXcEpIV1U4WGhvUEgxCkpZbjA2MlZWUVVqaC9uSTUxOTllYUViS0lQMk1ZbC9IdFZjYTZmUHY3dThsRmcySWtNSlVBb2gyV1BGdVpBbDhzTDY1alRKSWUyMnMKK1BQM0pJazArdXcxR1ROZlhxREhBTnI0WGl3MDUyRmtTQ09kQkp3aW9YSDJhMk1YUWtyWVU0NnljS1kxYk9TS1p5RlNENGNVWUlGbwpBZGpmUGFQMEh3OWlwTWV0N1pGR2VrcTdSVE0xZm80L25CVFNYQSt2Q0JXaDUzQnNwNHdBQzBEcnU5UktGUythSzBDYVAxMm93cklwClRDRk40MVd2U0JGNmRzRm5hcWNKV09MNUtrSUtzZEJvTFlmRGVMS0JTREVSMHNNaE85OHkvUHRrRkNFOWhuN2o5RTZUampkOEl2S2EKdHZOUnkwRGJEL1B4TUN3Y1ZMbHRHMnpqc2s5N0RmeXZJL2QwaVpWSDFqUDM5RUx6QTlWYnNNbjhHcXlCeloxbnh2VTdqNGllaHFQNApzRVUvUGE2aUYxSVozaXhOWGFubmxGSjhyY1EvWlo5R0NWZHpKUDkwT1I3WVdZcGRQczhTdHY1VTltbk52VWtUOGs4bkw5OEo3cW1JClltSHppMms2S2N2OE9scTJsWlB0SS9YMDI3NlBpWDdiZHY4d3h1azNib3BmVUt3OWVYcmJTRDJudEZ6QnZUcklQbjIzVHZ4RythZWYKaGZnalF6R0o1eVBySUdLUmZmcDdldDJWWlordU9rU3V3VDI5b05qZmlrd041SDROaHRSSWhHU2ZQaEhCVkZlZVl0YnBadkpXay91MQp6V2lyZkxwa254YXo5Y2xjOXVrVGtUYmg4aFRMR2dtTE15N3pORlRHaW84dVpzNXhSMEwwMU4xcUhOUDAwN3d2S1piS2NtdFVjbVc1CjU4RmowTk1VZW1CNWJHYi95TlA2WjJSZHc2YzcyaDBsaHlGSzllUzJ4MmZxazBDUEVTY0w5RER6UnU5VHJBYzh6TjhXL01jSHZ5T04KbmtJekQvOTVSLzRiNjcxUk9vTEdOMjdtR00xM01CSDJ4MWN2cmMrQm55T3d4MUxtZ0IzODhPa1B5UWIwZEhnUzRhOUhOM2JneDNiUApRTFdhYkFEZmQ1TEZaL2IvUEU2Y1FEdVppb2Z6eU9jVnFOdUR5V0RsMENKUFJ3WnAyQXo5bkE5cHBNRmVYeFlwMkVSK2NaRTl4cDhyCjhuUmtrY0l0YnlxSGRNWkhHbndEUGpJUGJmUTU5OFpET3JQWnpCeFNaUDJ6U0FNaThrTHJuNTFwYVMxQTZ1d2g3NVdQVmtEZ1IwSVcKS2JMK1paQUNmeEJZL3dNT0taaUxZSzVmc2tnQmdZOUJlYVRRK3BkRmFyQkMrMzhwUGRlazBhZUV0R2FYUllwc0NnNHBsSDBCV21oVAp0QVNyT284eDZORW5laUdjK2Y3c1Q4dDdnL1BmaGkvN01tK0d6ZnRCc2Z1aStsNW9TZk1kclMxeVlNNmZXVnBiWG9qdXlQRUhxZFBrCkJXaFM1UGxBS3hmYlcwWWs4VEMxMGNQOWs5bzVaaTNhV1ljNmlmTDNVenRuY3NkQ2RDQVFxVmpaOG90R2tZcVZQZ3BBY1kyTEVIT0EKVTAwMCtsVFJTdi9qcVc5cEJNZ0VaaEN3dGlVWUQ1amM0NDU2U1JSOUFtb3Y1MS9PQzFiMm55YmZZcVpqWmkvc3l3V0lwY1NmN3VncApUY2VVd0pEYnIrQUxHelJvenk2R09wVGRUcXRqM2d4ZWJVSUNzaEUzTUdEc0tXUzFvbjhnUTc0THZTU3BRYTFpRmRHZytFTWFudTJBCmRlc2V3cDdHZUhFMFVUZ1FrUnhveTY5enJxcEdkUGdQUFhqS21aZVluOTBvT3orRGxac2gra2QyQlpuMWV6T3ByNStablorTDVqR3AKR1VManRhMUFMTzNydDBYOFNYa1dHb21sQUF4MzVYNUpXVkFHTGV6T0VDdmgxY1ZaSEY4SmRtU0tzMHFmZS8yVWw2UTdNRzc2TkNmZgpUSGtpMTQ4OUtkUGRJRThzb2VweFhxcWVRVkdvZWdLeXFzZWd4cnJGejhxQlQwQjJ5QUlDMmlqVkkwMjdBYnlLaGlHd3pIZzhSUS8xCkQwMDdmQ05OdTU3WEtLdTI1YVFTeGVNa3A5WXo2WjhhZnhkRGt3dWtPNjI2R3FsTFZSdDltaUE1a0lKYk5DditMc2FiMWZ6Vlo2TlgKLzBLTkZnR1d6bGJYaEtRMERPQWQ0TTUxZWJSbHhaRFA1eU9uRFF5dVc1QlpKczhPSDF2c1pUUUdLczUvSldFdytWMTZ1WFUvTXB6RAo0MlFVMUpFR2htc0ZKZ1VLMFoxM3l1TzZsTHN4cVZYdWxLVU83SlZqVS9lc3VKWm0zTlBHUGZDZkR6ZnZrT0tDTFlCbWRCU3JVc3NKCktNWmZVUGdQV0ZBdUVIM0pHMkIrckJhODVJMlhCanNrM3JqUVhFNGx5WkdsU3BPajNDUXoyUHpVOWw5WVlaZEx3bmw4ZGZmbGtzeEsKYWxhWVZ0V3ppaDROVnRtTlNZUE55TDBNckptUGsreTJaTERxV2Q4U3BFbFp2L1VrSmZ1emtsQlBTeENydnVVMlhvVWhuZEpQc252bApTNU1lanhhVERneEozcUJqbHM1ZzFiYUN3TXRYTkN6VWJIN0JDbTZzaW9hRmp2VXJ2ZjV4b0NoT3ZnSFkyMGJEdU9CVloxcUFDVGNVCnZlTmlUbmhwWUQxbEowYlBKUGxXM2MwVUd4N3VTREdoUnRNNXJwMHdEak9LSEM0YzExUHFlS1YxTERoL0FlTXBTem1EY2dhdDVBWk4KNUxwTG80b2U0eG5ZMGxKNVNwdnVKcFc1N3Q2aXoxR216bU12VnJJTWoweHFIRzJnSjY2Zk9qMlRUYXZ6d2RxV1l1cWtqdXkyckJwRwprRFlNeXlLbElDa3Y2c3VVT2lxN2VLS0IwSng4T1JRVkxhQnBJQ0xiOGpxYXFJZzlieUNVait5VzJhSVdaUmk2L3REaGsxT0hrc0lrCkl6YTNoL2c2VG55OGdEYjRWSUU4WDlTQlFDYW9BU3hCbzRJTkk2aytaQVNrb214MkdLeDZCbVcrVWdFSXRTVVV1YStUVlhsYjFxb0EKS3B3QzBPcnZ5OC9Qcm9Ia0JtMUVGOWdLNnZFTXNTWFB4ZnArSy9CUTcvMGVURlU0NGNXdlk0blRESUpjT0VuSFI4WW5CN3kvREdqbApUL3JFU29sWTJrVmMxdTFCWGhJZ2xrNFJGeENMRlhIMGk0QWx0dklMQmZ3SnprVW80cEpldDNwMENYQ3RTVnVFUkNtVzhDUU95WXBICm94U1NGVVZJL3A2RUZyeU1VNndla2dWVDR3a1N2ZnE2d3lSUE1DK2hyalc4d1hwSjRxRThuWVhiOGhYaERjQUhld0pOQ0dXcVhLeVcKOXJVUzdha3ljUitEVlNsSzkvY0VEM2Q3TjhWOUlGblVZMzBpVlNBVHI0SFVDV3ZpWko3ZUZFUWFkZ0pUT25NV205S0FEK1NEaWJSTwoxbUJNUXlwWHhhYTBIdHBSOWhnYWoxVjVQRnJqQzRGME8ySVhjUVRQRjlPMUVWWkZsdkIxOGhKdk9KV25wczduVlc3elkvZVhLNkxSCnU2cDQzNU9ia01HcXdPbUFkNFNiM2pVS0lOMjJoZ3dxYTY2Tk1FT1ZJTDFCdE5YSjJiS0FPcUtOVG0wZjR0dXkxRng0V3gwOHJMTHoKOHpmZ3JNQjNXcGhCVnVwNG5Kd0g0L0hwaTNsZnpybjdKclhiQ1U5Rk5SOUJBbUJ5OFZhcGFDdmxXY2pGV3lFd0hjSW43UzhCb1RGWQpiejZrUUt1bXZPVVpOTU1ST3BMNlJrT2ZpVk53YnBWQUNncnJUWEpRR0oyc0I0NytmWS8xOXlXQUNVNEk5VzJpd3ZOQk83SXVQQTZoCnhabEhhYXAzT1dISW8rUlRnMVZkRERWc054QVk0ZE45eGlkalJNQmNUcGNtVXZMTXovaGVzSXVKTmRweDVielFhTWVWK0FCUGcwYVQKakpEa0FXRXkrMXMxV3B2VGFJejNxc2VDRndOVDEyZ0dqU2RJRU5qMUdvMlZ5bEpuZXdlTkJsWk5TcVBwbG4wQVI3OUd1NGhkVUhCdQoxMmdReXUxbnJ3aU93bW1RSitkZ1QzSDhCcXVVTlNEWWhEcGJKUSthZjNRb2JhTUVQVTFodmlYd2VTNWk0L0M3V3c5Z21mM2wyNzZYClYwTWFMYk04a1BPWGs1UXdVeEY0ZldvV0FPc1lkU2xaZzFWV3pWNlovU0FVNWc3eXBRV2UrRFVHQ2xnMVVWS1RuSVpSaDZQTnRKZUYKZ3VJd0FNN3RLUkFJaW94RExUcDVWNGNqUEhUWEdGNldPRTFBd080UnE2YjJRakEvTjdRdWhMc2grTlo3aTMzUFk5S3hxWG04MmVQcgp2bXVOWnZGaUY3Szc0YnN1KzE0NUJndUIzVzdmZis2bDlrSzl1eGhjTmYwaHJjdGRETUs1eGI3blFXSDN3dXQzTVFSSHdyNlhnc0o2CnJ6Snd0TzZHeW5zaDBqQ2YrNXQzUThGZU9CU2ZFeU1zNE51N3BDTkIvU09aaDBYdmxZTGtLUzROUTlZV0dCNFVsb1JQU28rRzA3ZHUKOTVaWXRTak9ENERkS3QyOGNVbkl0bkt1dFFMRk5KbTd6RXBDTEhJZUVWaExueVk1VnpnOXpRTjZkdndLa1NzTjZYU2lJY2x5Qk1ydApVUlV2OGNhVTkza3Z0cVc4ejYvSnI5U3dNUkc1N2t3MlBVOCtjMDNHM3djakk3U1JVb053VFk3M3k3WUZ3R1RQYnRob2o5YUVlZ0FzCllFbFVhL2VJa0FDS1JmU1pHREk1aUhBbGh6NU5NVmdLbUl5dzl4U1RieW1PTUREeGUwMkQwc2dSRjhKRjc4aVU2SEw3V1NwVTMwaDYKRnZRYW9HcTU0OExvM1RTR1JrOW5VRFI2czRFQnJKc3JTbFhRVVRlMzNGNUR4OS9GTGl2b1JCVkRWOWZRS1ZmUUlaMThoeG82V2FTbwpnazYyV2xCbkRaMXlCUjIvV3ZDV0dqcmxDanFCMVhkRERaMXlCWjJnV3ZDR0dqcmxDanFGYWtGZE5YVEtGWFNvV3ZBT05YVEs3OUcxCjFUZlgwRjBJcnFDQ2p2VXNicXloVTY2Z1EvYVllZzJkSUNGWm9jTHMxVTVLV2R2eU9mRHlsVUNpWkJjTlE1S005QmJVRTdkZDJ1cWwKU0pHUGZIVXliRUZzL1VvRUI3UkdlajhLd3QxZTM5THh6dmdLNG9TTnErbVVjQW5ZVlZncnl1N3hEaTNGWVBQZmVVY3RpQ0k4NDFNQwpwcHlIcFcxK0tOYW5Wam1uZVg2aXlOV2x2R2dudWwvL2tHUXFIMVVpVjBwRGtpcVpnM1BSVlRTblNkY1VSYWtnWEc2UHZnS3FrNjVVCkVDcC9URElaUkgvWVdDNW9qRzRHdXpsZTFmT2FsYWRtMEZqc0pzeUUxQnNZUkp3TTF2eldpREZWN0NaM2JDUDBrZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJMUlyZDVQMVQ1UU1IbnJZc0tpYURDRnhUTlRla0tLcG1FRlFLYXdNbVRNSENMMDlzSnNSZXJmSlJtODRhazdxY1hpU1ZjbTd2SkNDZgpRcW1yeEJUVnZ0VTFWaDJxKy9hQVdGSm4yYXc5ZGhrNlV3c2NycUk3VVpnRS9MWXRtVFI3eFlsVlNkYnNrcTBDNDFsSzRqb3dWYk5MCmN4M2ZXUzBIWGtjZDMwU3Qvc1VzQ0ZySmw2YkpGOEVvbTlLWE9mRDJ4NlZaYmxBWnFSSk4rZlZUellIWG5FVXdLd2tqbUpMcnA3V08KTDNwUXE0bFJZZ1poZGpvRWRyY0swUU4zOGlGWG1hSUhtRHJIYTZlWU1NQjZJOFZVeTBTMVQ1TFRhRmRSVEJqNEpYTGRubGVZNkZRVwpKZFpMVkhKcHMyVXZZcjZYYmhZcjZrM3B1S1Z5dlp3SWhBeUFsVW00STB1QUdCRURIUDR6VXBUdXNnWm5qL1g0Vkp5OVJWbXpzeWNIClFKeWplQVVJdGF0UndEcXp0MnBvSzVXN2FvV0dtUHIrd3BnMDBtSUJTOXpVZ3d3R3haQTByRXFUY2VJdTJGNnBSczZnVXVhczRjZ1QKVFVqNXloUERoWHVsWUVmR2p4ZXAvSTdDU1FQSmVTY2pjcHo4VzlFWDNwRndsU2hMU2FWQTdrTHJ5RmRFblNSMzh5dnNzWXBXaWVmawpYZFllKzYzb0MrL0lsOW1KTTRpdXB0TlNKZEpnRUxrUzhpeWdNeUlqR0pLZ0hoa01pdEFUL2xBWWtsQ1kxWGN4QlRvRnRRNUpPVHRkCnZTaE9hVWppdXp0OG92Z3ZWWkowajRqTUU0ckkzSmlsQml4aGk0YUlESDNHcDFLZVk0bjdiTGRFWkhqKy90UHRFUmtBd0tHUTNhR2oKRE8yYWlNeEZ0ZUR0RVJsWWhpYUt5TWhWcEtyVjV3VjFSV1FrNC94UEdzcHp0Qlhud0JJOUlIRHFuS3d0ZlErMjZzQ0V4bktWTTVibAo4OGExR011QmROdHQxc0FNeWpXSnUrcDlNaG5ndXNRYjl2c0VkY0RVNGc2Vm5GNHRaV2hYSnJEejl4ZFlRQ1lmWGRKUlBuYVJ1aUJaCkxhaFdWNmM3YWZZeVF4WFYxV25NMTFPc3ErT1ZqaXBVQ3FzSFFhdUtsMVR4cEpkbld5cW02cjFlM2tVS3Y5TzQwVEUxNzNLSlNmZXAKaDROWTdwRlRwMXdQcC8vK3NXdnE0YVN5b0YvLzdsMFBkME9kaFk1Nk9LVU0xZnZWdzhHbzlZMFNxS0VlVHVKR1VOa2lydXZyNFFUWgpVTXh2N1BldWh4UGZPMHBWeE4yN0hrNzFsb0M3MU1NSlRxdzBwRnBlVnc4bjlzWGtqblZnSmR2dGxmVndnN3RiVGlRQUpjeUpsTE10CnRlUkVkcmFhY2lMVlpQKzRDdHhxQnVSUmdzVHQxZWdJamtkdDlUWEMwVkpISWd1RnNzY1FuRHRVY2wxa01pamt3S3RyTkZoY0p4OFEKdTh4MzV2V3lrY2w0dHU5ZEZ4blA5cjNLUW9pRVVEYmEwKzNjSW9aYzhSRXZxbkNyR0FKZ2l0ZktTT2t4V1RIczdiU0tvWUkxRHVtdAp6MStVWkxUNzNBYU00T2dUSDVsNlpBRG5Mb1dRQmIrMlhVd1ZqdnlWd0RLM2FjbWxXVjllQ2F4Nkc1b3dLaTI2cmRIcHVZeGh3ZUl6CjVZdWRWQjFxdGlJVk4xMmJJTUticzl6RndsZFZwSTVOUXcxRnBCb3JVc2VtaVphUWdVcXAzMTBxVWovMzk2bEloWER1VVpFSzY4VnUKcjBpRlVPNVJrUXJoYUxzR1d1UVNTK1gxSVFHUnZ6UlZkNUtSMDB1dnZsQU11emVMb2FnVVRscVAzYnNVRHVYeksyYjAzS01VVG5KZAo3bDRLZDMzY1VrZ3haZDlkaDE5NVF5a2MvdzRpVkF6M2o1VENTVVFWL29GU09PbjRtRWIvcktka0dQSlZBZi8rWktYQ3A2VnNycXFXCkcrR0Y5bGplcCtJV2FVMzBncUJDbWlLS0dnTElFSmo4elhZNmJaaUxTNGIxSGk3d3F0RjdHbzl3bEc3bkJhcGNhc3Zqc0tnWE40dnIKNmo1bHI4TVJidzVNZEZSaWUrRGtGM2FOODBqaG85Y0F0YmhNdlN4TDY4NTRXRERQemtVeVpza015RmJxdFpqeG4reEE4NU90ZEtTSAoyb1lYK3NWREpsc090NTd5T2Q4MG44LzVxN0FKd2R1TzJZNnNhK0dRNllpVHNCWkxxdW9NZWtsMGpkS0hmTjFadEJGLzViT1hzTmd0Ck1YMnA4NFBQUEtTaHBjdWFORzdsS3V5Q3ZhNVNzZHZNTDRzVUkxczVwUW83Njh0UGZTeUhkS1NBdE9TTjhaQ0thN0hpN2lNdkNpY3UKZGd0Mmx6VzJNNkdvQk16a1VDcDJ3MzBpcE1KK2ZJay91UXE3c05tOEQ1OC81WXJkUHBTcXp2NlVLK3kyclpZc1VsdHR2cHpKSVowcgo5K05yZE9XUkZwOC9TckxrdFd3Q2lhRWMwb2F3d2c2dEtoQllldGJvRTgzbmNZM3ZKYVRlbzZJS2dqZURuelZORUlQT1YrbzlldXVzCmhTVU0wV2ZHUzBxUjU3VjRRMVdLSFd0SXVSVmFzTzROTlJmQkdkR3JiWHVmMGg3MURGVngxRVMrajlWZXc1QjQ1MklLZzFKTFRsWEwKODZDODEzdDJrcE5xT3lKeHA0cUc2SkpTSnpsZFViaVBndVlVU1pWcVNIUW5wSTY4UHJVbWNvcDVmZHI1U2FXSm5PejhwUHErcVRVYgowVG8vOVY0RG1vbXUxbWRFZEpmYURmM2p0TXRMYVM3ZmlFZzIzVlZyQXpybFNPODExWFRYeFdIMFZ0TkorUUZNTDg3N1ZkTnB2Qi9tCnhtbzZxWmlnV0Y1dXI2YVRxcVc3dHZKUnZwcE9LaFl2bldsL1N6V2RnQ3kwekVyZVAzWlROWjBVS0pVYlFxNm9wcnR5UjlaWlRTZDEKVHNQdWxYZXJwcE9xcGVQNysvZXBwcE9xcGRPWTI2T2ptazRxMXM1MFlMOWZOWjNVNnFKSTcxMnI2YVNNRzM3dTZIMnE2YVJxNldSdQptNytobXU1eVNFdXp2S1YwYlRXZGxIRnFzTjY3bWs1cS9TU3lvVzZzcGhPRFV1MHBmRlUxblp4dGVkOXFPdTBVdTZXYVRnUktmQ1orCnAycTZxeWltdTVwT3NjYnFidFYwMHJYVjk2Nm1rd0lBc055NW1rN3F0RVNVQTMrSGFqb3A5U0QwWHU5UlRhZHlNbktuYWpyMS9lVWUKMVhSU3hPQ3M4WHRWMDZsVmN0Mm5tazZxbGs2Mkg5L3REcUNYY3dBRi9jVjBYZDBrMzhYcnNrbWx1RGVIeHNLbnZZcXdDNGdmM01yMQpzcm0rWDkzRmtFN3dsT2ZlL2Vya3JRdHRkRHE1N2Jyb3hGRkprQWtKYXpKVkRRdU5MQ0FvVUpDcGVwWWJsR2hJV2xXQmh1NXl3b09wCnE0WUVLUVlHcGF2dHN0S1FwQk1wWkRXTUFwMFUyaTdMcUV5NGl3azlvalQrZEJSNVJBRkxiS2ZTMkZ3NU1zZDJ5MUpxZEhkem16dmUKUFZjYVRmSnIydHpKZHBlcmFxcFYwdGptVHE2U1Mxc2huYVlFQ2VYOFpLN1IzVzFyVmVydHRIU1pVWXhTYVdwenB4cFJoSVM1dWMwZApiY01vTjdxN3VjMGRWZnVtMHVoTzIrSFJybnFIZTY0QzZUYXV2SWphNnl5cWQwdFIybFU1ay92cVdoNHd0VWVuVnY2VVBlV0JEZXBVCmN3L1YrQk9XMFVIbldURUNyNm1RVGt0R3MwRzl3bEEraVVOemZTSEFvcEIycUNPSkRGSkhOdlFuNUdSdEhiWUFack5kWEU4RUwwMlYKbmJQVTNWQnk1ejJsMTc4ckM3c0UyVkNBcVZUeXdUVm5Rd0ZRcXZsam1yT2hBREJ0R2QzS2ljMUk5OTJsOHZIMm94RFlVVkRoT25CNgo5VFhDMGRUYlZRb0tMN1ByN1I0U2lLQmNWTEpMVmdxcjE3SWpZSm9LYStWNlFJZ0xhOTgybDRXMWI1djczUW9JZ2QybGtUSGlNVEJhCkxjcU12M2ZKa3JJbFJVclZmcTlLT2RTdXl5TmRXSWwzbVVHdDZJbkw1VkRQajZ1N1ZLYXdOeC9ydHlRdVFkWE85K3BnQ0I2OHloOFIKYTViOXRxNUcxWEtuYjdEeDJzM21CQVZGS2F0VEI1dzczQkpBd2JtMVd6VUZoUkZDcVJzTzllV3F0alVVTXVnNjRYVzZKY1N3bzZHUQpRVk1FL3VZT2QweDlwVnlQdXl2RVVDSzU0dHErMWZvNjNDbFZQdDRnaGd5ajBSM3U3dElwVDdXZVNGdW52RnZyaWRoT2ViZUxvVUtICk8yRmRrcGI2a0dzNjNDbjFlNFU5N3ZSM3VOTjZxem1zZnJxOXNQWnp6NWs1Y3Q2cjVzSmFBRXpkekRGb01YU28zblRYRmRhS0t4OUQKdDhhUFlIMWhYYkljV3Q4OVZ3ak9GWHJ6NG80SUNPY3U5WngxVEpzdnBncEh2aFpXVk1Sa1VMdG1BclhMMDFQZkxsWEV4RDhWaFFyQwpjeUdHY1lmS1FtaUlhekY5M3pTV01Xa3BZckkvRHNTZUtHOFgwMUxHSkp5a1N1eVVBOFd1aTJ3WlU5eWhxVUpkMFcxbnBUTHUwQ0tWCldvcVk3SThic2ZGOXJWL1oxVlhFSkpkQkJIc25LdXkwK2d6RExsM0RlOE90L0NMRFVPS3l4RzZQNmdGeGp4clh2RS8rVmpIb3YranQKU0tlcjNTTWlwYnc5MXJ2ZjFWUTlkUHAycHhyWG51elZWUHB0bU1sUlY3dEhsVTU1L2l0clhIbnl5YVpoYUtoNlZxOXhCVVBTWFBXcwpWT05LUjREZ1F0UWkwdmdZMHc5V3ZKVWZXNFVWbnMvNW45NEw1dm5UbThGYVNMdmZXby9ia1RzTVBwVmVVWFVmMmYwa1o0UTlaU3BRCkd3OEs3ZkppeC9RblFSSGVjN3JKUnlxb2h6TllqK1pPNzVVZnFoTDJZWXZuUDNveTlYQk8rU0s4dzNrVXg0VTZXVlNHaDdua2F2L0MKWmt1azZmeVNLOEw3bEVVSzVtSWlkd0hadVdJbGM3OHRpOVJlbWZnV2NuM1luQnhTdHBLTEkvQnJpT0FoRlphbUhlMFJHOWRITUNDcQpjblE2MGg5ckthUUdLeVN3dU9lY29BeHZMSzc5NDVPM21ueVZRUm8yVzRQUGhSRVhneFZYeEEwVmtKWXNZWG1rcFlhNUw0VVU5WDJMCmxnV2xsV0trVGFVK2d0V09QTkppc1UwS01yc0FXZ3Q4N21FLzBVV1laOWVqWDdqNk11OEY4cGpzZS96NlNtemtpbWMxUUhUSHQ2Y2kKdDAyQ09mZUNZcU9UUGF5aG96M0N6VE92RUNkbU56cU5hWk9BcUNFbk9nMFNkREZUVDV6VXNEY0QySS9pd2liVkNJbDhTZEpsYXBYcwprQ0FueXc4cXI2VzBTYjJ3Nlhpdnppd29vS3ZTbVVWckpLbWduRm9sdTNRWG5Wa0FnamM5S1doS1ZYZWlteWR2cUVwVHlkQ2txR1RRCnhrK2lReSs5ODJPajFyRHVUbmVYUlpraFhXUnBpZVZGTTlGMVpXa1pyRXFEa284VDZ4c1MwSmJ5ZVZyMGVDNXlZMFhxcXZpWmNna1AKcjR1WFBWT3VjeVVBN0lxR3E2OVZZckNENHIwdWIreDVqZHB1T05SUWphUVlYdFo2eWpNbzNuSVRMVmVUZUhGbDNGWEZidEpIMXJydQp0UjRVcjR3c0MyL1JoRldBdDE1Q0szVlhuR3k5bUpyWGNubFhuSUlESkIwZkV5YU5TQnl4amtsZC9RN2tOUXg1Tng5NVRJbzF6TFduCjNsVEJuWndjb3hNcjlmWjFncEdKNC96cUlUdlVqMDgycWhMY1h5UVFyS0lIL2ZhSVRPOG4rMk5YL25CUVh5SFpSVCtMRzlxeUtWY3kKNmFxeGl1bTY1NEEzSkZIOXk2eWtGRHRXdGNZRlErS2w2dE9uMVR5cDFWa0t1TEpvS09YazMzT2xVQXFvMXRKWVpmMjRrL2RaU2IxUQpSek16aVBvYVMzYVowUUZNcll1T1hWeGRxd0JNdEt2Y1JqSFZXaDd0a3hTZVhONUlNZFYrT3Jvb1ZndCt5Z0M3S0JlV3NnNXBpbDFaCkJhaTFCbER6UFNSeUJXS2FhZ0FWc3RNMVZBRnFyUUc4akNmcnFRTFVXZ1BJditGUWZ4V2cxaHBBRkxXK3VncFF3Q29LSHFZNEQxWmYKRmFEV0drQklzZXVyQURsNkt1c05ZWTJWM2lwQXJUV0FySTk4VlJXZ3pKQXVhZ0Q1NTVYVWVDNW5kWHRUUHUwZDJXNXB5c2VieXovWQpsTzhpcXZDUE5PVlQ2OGgybjZaOFZNMklzb0Z5ZTFNK2cxWENLcng3VTc3TC9zai9SRk0rK2Y3STkyektwNmwvNVMxTitmaFJCVGlvCnNPeWdhQktwbFFiTGQvVzcvVzZvcDN2Y0RhV3hyNSttdTZGdTd1dkhtOW9kN29hUzYrdW5MMC9wMnI1K3lsMzlycm9iU3FLdm4zSlUKU05vVDE5L1hUNXI1Rk8rR3VxS3Zuem9uMzZPdm4zSm1DQnU1dXJHdm4xb2wxNTBDdW9wZC9ReFdYUUZkMmI1K3lsTVR4UzZ1N3VzbgpHTWhGVjc4ck9vQkk5dlZUbnBCVWh1bzFmZjBreXhHVmJqWFhUaGpObGJLU2QwRmYwZGRQK2VZdjlrejh4cjUraWh0ZEh1MWlkK2pyCnB4d1cxblVEbFVKZlAyVlhWeklMK29xK2ZsSmxrcHpvM2RhUDd3NDE3N3I2K2lsRGdYSCtlL1QxVXo1UU1XaUdjMHZodTdnaTlkcSsKZmhLbUpxK3JINzg3QTNaRFh6K1JHR0xDcm42Q083dDBsNmRnYkY4LzFiclh1L1QxVSs3cXgzTHlqWDM5bEJPdWVSV3BOL1gxNCtxMwpwSGhSZE0vVjFYMzlsQW1JTE5nNzlQVlRrTFhqS25DbmZud3VaU2lhKy9HcHRKUFQzSS92cHI1K0xCUko4ZEZielhIUjEwK2g3a0UxCjIzYXV0Nitmc2lVUGJ6eTRSMTgvdVQyOGMzbVNlRjM5bGdaem5qbEpWQk5EdGI1K3l1Zk53aXlDNi92NkNha3Q5Zz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJRnEvdHg2Y3ZTVU8rSDk4ZHhJZnQ2bmQ3UHo0dFJVeHF0emRjNW1yb2E4VW5ya2k5cmErZklMQjkwZFdQcWhpNnZhOGZXeXFsMUZmMAo1cjUreW1hT0RJL3A3dXVuM05YdjVsdWI2TDUrTjhiNk5QYjEwMUQzZW9lK2ZzcGQvWFQzNDd1cUNsZWtMUy83K2wxZkRNL3I2c2ZECmNsTmZ2OHRRTXIrcm45d3RaM3I3K2ltbmQ0bDJzYXY3K2lrbk9vbGlTbGYzOVpOWUYxNVhQK1Y3NGJUMzlicytiaW1rbVA2YUp4bS8KOG9hK2ZwemlrdXJxZDNYMm9LaXZueUpIOERxQTNOYlhUOWt3cEx6WDIvdjZLUmZFMGp2eXpYMzloSk1VZC9XN3NNYzAzMlFsN09zbgpid1JSTm96S1RWWWErL3Bwc21GdTd1dkhYOG5MQXh5RjZsb1orWlR1NjZlOE9TaFdjZDZ0SUpiYTkvMFMyME5meVVaN2FVdG5mSWp2CmxWcFNOeXFLOWtyd3JYeG9Wem54WGxTMktPQW1oc2U0MDV2VTQ0NWZCMC9GcG1oVURzRU82ZHR5aE1IOEwvTXdTODluZ1NkYU84TGEKTitLNE5JSnQ1Y25vL25pMllQN3VLa0s5Qk91cGpKWjZxdUxESEJ1amYvcXhDd1lPeXljeXRmNktOZG91aC9mUGFjL3RjMWg1OFp3MQo3OCs1c1BGelBBdUFUNk9NTlJSTmxHMzFsMzB6dEYvMVBneldTTWdYbkViclpOZFg5UjJNb1ZvcE9NbzFWKzMwN0swZWZsKzI1cytoCmZjY3gvN2E4WjUzQndxK3AxYXl1NHV0a2R6dFBPemI3WVdSdlBXUTI0V2ZqKzNQYWJnazRTbUhyOTBlbDRqd3Z6Ui9CN2VjOFRzcysKcXUxTXRWdHZIYVBQUGNnWWljVys0MDRHN0JtTXpGVnpHUGs5ZmNKS1lWdnpjQmpGSElkajlMMXlOQS9DazJObzh2SEtWbHEyM0k5Kwo3N3N2VUl1Wm1MSzNYLy9oK0xtRnplWmlacXEyK2xLSENPcExFLzNhTUphZE5uYlFvV1piUU1KK2t1Y1JiblZsTTdVbktXSWhZb0RwCm5teHdYUUlXbyt4Y1VVV2pZMnlmdjVvNy9WYktzam40U1JzUlhKek42NWx4Qml0Sm41amlVT1Bac3dzK3czeTErZ2JWSkJxelpLdGwKeFN6ekdmTDNYN2RDazMwbkVoOHd0ZGM4cjJpT2k3ZnlwZ2JVbWhRZFVtRnIvbXl3RnZya3ZJc2FhT2EvU3MxdStEay9NMlg4cCtSVAp4bitjSmNpWWVmVmFmTThFQm9Cc20xUnAzZWwrWnN0aDR3VEE2ZXdac0ZUN1RBZnVYa1ZnS1dOdmtFblVqQWMwcSt6ZkZuSnl0dnIrClBuUVhPOTB5L0FRbS9McjJ3YUpkRCtYV3AwSzlBL0tjTVAvSkFiTVJoaWRLRS90RFBqdnpDWGVnMkRHZ1NHUUQvb3k0VU5VdlVEaVYKSGZqejBZTTBqTmtPZHJHUEEvZ2k3Mk4rU1BySklsR1BBckJsekYzd1dNK2tvMXlwNEI3NzhxODRYZTFqbUQ4VmNhS0J3c0Y5NGE0OApuc2ovalAwNGVQRG81ajBZVy9LUEJpdnpLTy9sSGhHNWZqdk5QS2l3K0twOGZGNUxaY2tRNXRrSlZNWjJoWmRxcGpIN25adDcyV0RGClN3UGZsSDNrNWNFcDdlSVkvTTVQMjBlaFp3eFdHZjNoNVhDTmdIOFNGT3pKd01yQ2JyaXBWeVk3SEZyb0RTOHZCbXNoN0NrSFRMZHEKK0tpWHB1RThoTlBBWUhMWUFaK1dYOUNmTk5ocC93T24xNnBIdXYzMXQxVUFQRzE1MEZQQ0dZN1BHS1F0SDRNRmMxcWlHTEYrc3hZOQpNU2ZnRHF4ajRmdjdJd2Q5TEVjeHcwWDhpQTc1QUloK2l0a2w0QW56eHJWRHhIZ1FjYi81bUhTM0U0ZHdxaDE4emthK1pnNG9kVG5DCjJYOHpJbGFCRk90OUVPekNqd0tXWkhKRURwMGZWY0o1bnEyWXFiOTd1QVVqQ3VWSHlOUHZQb3BFaFg0Rmh4dTVoU2hNWDBMMHAzV2IKb0QrZFB3YTBiVWtVbmVNaC9ZbFloQ0NJRUFWaTJNOUFpSDBmck5mWUVzTjFEYU4rUFR3M2FkZ2paNWZsdGo3Qkc4MG9NZnRGRHhERgora0ZXS2llOHVZemVqWG00MHlSZ21rSXp0L1l0WE5uWDZYZXRVSzBZM3poRndoN201Tm5nZ0kwWGMrQk9Fbk1CNjdreVo4Yno1VWZUCkNOaUlkaENOTm1CTGZJVG9UNFh4RC90ZWdINnY4NWNWaitZbDMvb2lDMnZUTk50c2Zkb04xdUxFbTNtSG0zVVM1YlBSc24vYWhTbFoKRkpvT3drTmdtMEJ2c21ydFVtOHl1eGpVbkNLOUdmOTYyVHFLNzduNlU4NjVQc0JMQ3NMbFhCSHp0UzcxcHJqdHNCMU5IS2kxS0xxaQoxc21lOFFIMVQwK2p1M0pUcTVyckRvNllmMlh5K1g5TXI3YUFKZlozd2pDSDcwanJNYUF0VVNJNGlyZUNQNE5PVk9hTUZ6OHo4TSs0Ckd3YzdSd29xUXVnak13di9DWDdUZ1NxbDdFTjJIVXk5OGFGSUJGUkNNTkpROXN2RWxNcVl4T3JEQjFVSHpIM2R3em9MYkROaUZyVHEKb25TSUoyK2RzTjk1Nk8vYU9PVHBLdUNOU0tlY0g2MnlNNEZXcldGWWFGS0ZDMUhGK2Rvd3R3OGpPM254QW5VZlFORGJvcTBGVHYwegpDNy9ER2ZPc0ZxRXBVU0s5NkJYZ3lUWDM0TSthbjRFTmRTa2NEZENsbkxLbU5CK1lDMUNwWHMyc1JGbDRGeWNNZEhSRjNLQVdOYlIrCjlQL1NjWDdFYU5qY0ZQSnpaaVg2RHQ1YTBNQm0xazBCdkg1dzg4MGNCQ0taZnVNQnFIeDZmRUlBeTFSNzZLTHkrcG9uYUdDMkJSZEoKMUk3d096UDRMbnFtckV4Ym4zamltZHFVMlpWOEtiSUFHcGNBemhRQU1CY0tSTmxXNWx1OWdPZmQ4RVlFdEFiQUVIOG1ZSGtyMkpnOApaVGY4NUdPLzg3UGZnWFh4dk8yaGZYQ2dtQjJ3ZlorM2k5azQyd3YyekI0eEp0WWp3VmhYd0NpYldKcWZ3R0FJbHNROW8ra05BMDZJCnVtNGladVI2UjhOZTVFYnFKb29lc2pQcHZ0M3I5alBmQndGYko3MHVPV2ZWemR4dFVmN3ltWDdiWUFadUVpRDFlWkZZWDE1NlFWZjQKTWhRTFJGNVd0TlZMbkhITzRFWE53cUhiWUdKR3c3c0R4TVVqd2NjaE1PRmRRY0tTd0pudnp3YW93ZzRSd2VjVkVBRVYxMUZFR1BDSgpRQ3dhaUFqd1FaOVBBbEhyY2lEeEhBbTRmdUpDSW95VHp4d1JBaDlyUE1wclp2VjFuUGo0U0duRC8wdVdCT0srMVQ2Tys3dkdyYjlJCkVlR1E2MzFvNHdOME5UOWk3TE9SSTRIQmFnd2VQMndzRWJvS2ZBQXZMR1dvK0NuRlNySUF1RHlsM2s2Wkc5VjRFVWFKNWNZQTVVWEwKTklhSEs2ZkJSRWhRT09LMmFTd2xWNE5iQzBvcWxhYngrcm03amFkZmgzdFdXNHBBYUtNRUFERS9LazhEQUhCWkVDY3pJTkw1L1ZZQQpZbXRVSDRPaWRqcVlFQUJFc2Q0ZkJ3SXIxM3RUL3B1OVQ1Wi9lN3lGeDhpdnNqRG04dnAzTTQraDY4QnY0N0g1NlJZUUFNRGFlRE9QCmRUWTM4bGh2Szhkam1rRk1EdW9NMGhmdzJNVTBsamVTOG5WMTVuanNPaEM5b1FaeDdUTFJIbWtRRTNuZHAyME1jeDRwS1lycFhZM2UKVWwzaStXTUFjN2tZeGVyRzFlaHR6aUpTTWhUVFBvMkRpbXhJalVGUW01RHFuVTIzTVhiZmJGYmZrWW5qSndmQ2FPOHMzL2dnSnBOcgo5d0IyUjU3TTkycVVVQm5EVWtZK3dSaDQybEtKRXBQVjhWWnRPZG1jTk94RUN2dlFaSDlXSG9PNnRweWNqZncvcDJhVDRFK2JtWWwwCmxpa2ZFaDdMeFhoaGI4ZUhLd2hXM3pPY2RZMmUvYTVtOU5TN0w1UVJDSDdEUmNxNjBPTUw4MXd6bEU4eFAyV2l5QzVsWXpnRG5qYzUKdHZ4OVVoRVErMk12Uk5XOVFxOTc2SUcraXBlSlZuNGU0WjlzQUs1c1p6ODVLTWR1Zmx4QmE3eE0rYnZ3NE4rRHZHNzZ6N3pQUjduYgpURTR2OUxCWmR6eVE3dXh5ak5zYmRMREJSQ2MvZUJrN3NjRzlxcHYvb09abXc0WlZyeUNpNkJsRTJCQk1sY1AzRmJBa0Zsa0czd3ZPCkVZWU9VWlFlWGR4My9PaG9LZS9oUFJCRVIwc1ZId3dPdVFEdFB0MlVyLzExL0FXOFUycmk2TTlBdW0wRWY3NW1PTmhET216eFNpSnEKdTRDL01NOGh0d0NlMDBBdm9SWUZWdnZMQWNyTDY0c2Z4alk4QU1IZUF2NXNJN0F1S2lUaWYvMElzSkZKdHp0bFRwcmhVemRBNEFORwpTNi9HaFc1SERKWVJvSEc0N3kzNHgwbGJmTEd4dHcxV01sa00vdkxDNjFUd3ZkUnQ4SS9mbVRONDlyUW9Cc2E0eVV0QmxJSkg1U21wClFHUnV1a1FRblUvUlJpeGFJalAyZWF0UW1UMGFhYSs2MThVWlZtbnhBMzdPOVJEc2xYU0VxRGNPc2xNZkF5eW5HTDFna3hjVUV2SFEKNGZWSjIwOEhlU2RkREovVUtrN3c2UU9uNDFHVEFaR0tWUWl3VnBOeGdQazBDMUlSZUErOXRLc21ndWhGUitUZ3p5NFRsRnQ5WU15bgpBY2R0RThLZXJxWG8wYXhtQWQ2RGdURXdwT09TOWIyVm5jdnFMNHk4dGtBdUdvZ201Z1BuZDM0WkpsOXk2Nmc1S2hWcG9TYkUvVU5sCmJIT2htbFBYeHlLZG9vdzd5Q3luQVlhWDhJd0RmQnJqektjWkZ3S2Uwa0drMDIvd1lqU2hVNGQwT1ZPSlNNZHJxcE9qdWpWR0JVTnQKdzJNRWV5cTVRMGoydjhLMExIWXhNM0pTbGVPRCtxT0RMTVYweEFmMVJ3ZWw3dXRUaXcvcWp3NUNpdW1ORCtxUERsS2NyQzgreUk4TwpadjhyWllqaUVmd0IvZU52bnRmenc4dmhaL0d6ZWZBWUVnWi90b0xqN2Mxc1N4N204OWI4ZjUwSzIrbjViNzQ1UGNRZi9ObTNmS1VTCkRSWG0wKzFzL29DU21VS2pDS3MydkRTMzB2ek5QOUlXaEJoUnNEeFgrSTZWVm1WejgzRmMrTVo2S1o1WVVGYktyclUzZXBhL1piQ2gKdXFjK3RLdCtHRDBFK1daMGxJOGUrR2VQMnVVcElra2VyQ0t0NURJWDVvZmN1ZWl1MTk1RnB3UW9HQk1idFVwZ2V5aSs1K2JOalArNApTUHJMMlg2MTBDYzdieG4vQ2RzeUFVRjRuaW5JSHVDZGVrc2NrZ05ENW1Rek9wUFBRYVBYYisvQXcvSUNtSXVsRVBVYlBjNU1Cbjc3ClpIUTNUTTl3ZnMvd1Fkcm96UVptMEdvb0cxMTdNekRMeHZzb1gxWFlDRGN0Y3R4V1J3Nkh6SEsvYnBHYU5WRG54N2huc1VpaFl3TmEKWDBMeFF5Y1pqUGo1MFo4d3BkRkJmL3FkSStQQVNWc0Q5ajFzSVZOMjAzL0dIVjdLa0tHQ3p2Q0dHQnJFZHp0K1lpUzVnbkduajN3OQpydU1va3p2SU5GaGxqeks1QnplYkNkUXg4SUNQK3g4d0UxQmFIbTBvL0hObWdzR3F2SzNmeDB5Z1F0dWFJVjVwSmdCRGh6VVUvamt6CkFSbzZqS0h3ejVrSllDNnNvZkRQbVFrOGVabitjMmFDd2NvWkNtSXpRVGtqaE01Q3JNWGxOZ2RhL2J1K3lETjBwWmEvd0pYcURJcEEKS2I1M2pjN252b1BXbStmNEsxU3BaYUJMMHkyajgyZWRNbm8zalUrb1MyTndYN0NJM1N0cXdSNTdsS29EUXBOMUlJSGpEalhmZHZSTAo0NzJYU2Z3SU9yakVEelpYdzA1NWYwQmJ1bWx0Q1U5WWVOcVMzc3J0aEQxai9FTExEclZsM3VkQnQwOFRYK2RreGYvVFBma293K1BICkUzZWp0QzJneDRwUFVrWG53Tzk2cm9wV0h6NW9BeXlSQTZkYUtUMzJSWXVBU0sraWJCU2dVdUhJSFBBNFk1VmJtemFrMFBuQ09CdUcKNyt5VjRrN0lHM1ZrakNBRE5FcWQ1dU9sdGlQS1dqRzBTVlJhQkNIRm5uMjBSV0xKK0F0UHlTMEc0THhnbFBMa2FleFNtMEFMQWY1eAo4NnA2MkRSVzdpUVNLSE51OTBXTWVGR2d3WjcvaTFxcVVtbHB4VUZJZERqSXBlVlI1NHRlL3ZuaU5Gb1ZuUzhhalNjSEd6ODd2bDZjCkx3WmRKVit3bkdXTzJ4NjNUT3Ntd1VHb3Q4NGRCUkdPV0M4Z09BZ05tNDNXbktYQWdKamFMazVTYzM0ZUFKenNsbkIwNEVzbk5OQmkKRHpnZG1leituMVM3aUl3RHlHZ3B4T2ZNZDUwOTgxM3Y0UDk1MmJpNVJBdkVjZ0p6bnc2dENNT09Xa04rU0lYQkNkSG5udlQxK3E3TQp1MnZNSEVFaU81bytmVE5ZeFllUTZGYjA2NDhnblZLbmJ6QWtwUG44RGI4NVZMZUs3aGdpWkFJOElxQlRZWm9JUVQ5SEJEaWFGZThJCkV0MmtKMGNDSm9TYWpxODJEQkZjb2lOSTc0MUgwWThuN25oZWU5aVZ4d2ZwK090SncxRTBuV0lvZFJoTkZ4WlRWRVRueDFLc3BIQ2EKVFpkRUFnQmc5VFZ5NHdVSTFOUk4yeGlvMUp4TEVLZ2gxUzNUUUFuOGpFanhqclIxVEtNZDkrdEtETGlVU2svczVMcUZwNkZMN1JZQgpvQ21tbFJMUUEvZXFUZVB5YUo5ZkpJTjdkbmxNY2hvYVNRbFRLSEVFNEdncWxYTnV0cFdId1FvVEh2YThONEhiNzZUZkpIOXh0MFRUCkQ1clB4MFA3alR3R0RCVEhiVHhXQy9vNEFMSThwZ2hpa01GdTVUSDcwbkViajJFYnB3eVBhUVpSYzN0VUdZUVBBQT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJVFVMSVk0T0k3NWJWQVA3OG8xOEtBT0F4clNCS05aTzZ1RW9Eb05OWW9jR25XZmRKajJIZ2t5WWxIQU82bEZ4MU5ZQ0JxU3J4U21PQQpTY3k3K0cyckFhMWFaVktpL1VWcEdtVXZxVTgyTHNZUXJ1SFFHcjlCTnNycEpxRXloa1BLai9OMjVITHc1R3NuZVNBbUErdHRlOEJrCjRYWXpPN0xpS0JUR3NNUGxtVW8wQmxyMnhhT1lXaUxlbXpoaTZuMzAzWlprQmhQY0pVVmNkZ3lzdGtRSm55SGNnWXhFcnY4WVFoLzEKR3FmQlF0bzk3QmJPNDFJdC8vVVVNOU1oZzFDR2lTUlJJZjZuUDJHZU9sVTZZYkJLRlUvY3UzUUNZcmtzbnRCZE9zR0dRNldQSmRHNgphRHFZRkI5TDhoN3M4Z3YyZ1NpbUR3T296ekNxd1B1MjdXQ1BEWjQ5L0FlTElGdVRBTDFsNENWQnZVS2x6RVAxQURrWm5RTnNrYVRDClB4c3V3ZEVwa0IxSTJ3YnRlZ01tanRQZWhxZU96c2R6a0M4aEt6WDhkQkZGdWdMSjFxREJUaHR0QkRiQWl6S1dod2Y2Z05ucERWTFcKZU12TFA3aExaeEs2ay9BdkRtRllMNTV3bHNrazVTWGREV0tqOXNpZE5ZUk9yNVo1NmFzZlhSaXMyYmV6NWFmWW43M0NrNk1XenZFdgo4WFVlWk9pWVJHOFFZRU9SUVg3QlJEckNzc3E3bDY2YWFPU2hYbm4zTTJ6L2pxR0VoaS9vY3I3alRIVHBIWjBTd05PRTl3RDdLVWlCCktDYit3dURQUGcxeE9FVUwzMmVQOGZzWSt3bm5yejY4VTV5dFNlZ0grTFVVaFpXRmlUTCtocGk1OU1PeVZTcHV1Um9WQTMzQkNWZXYKd3E5UytmSnhTQU0yNXdzazZoZjRwL2NPb3c5Zk9QdUo0TDlYWHdUaGQwRnVORUQybWZFMHlGR25seSs0bzA2U0xOWTdVU2E0K1JmQwo1cE40R0hLb2o0MVQ5S2txeVA4ZjYvc2ZHK3ZiL2xmS2tBQ1RxZUQ0c0xpWjhjOGNEVllyK09adGZqcnY0QXVoWVc2KytOblV4ditaCkh3ejRBL1VmQnY2RC8wWmlEemdSZlNCQ0lmQkhDSDVibXhnYzZOMEgzUGxRQTd2TDBKODluQW8vMDlQUGRqTSsvT2NoRHIvcTFtdnQKU3VFaC9rQzlPd1R2Smg0Y1lEVFlFTHdOSGpuaFFlY1FqSEJvd0I2eTRIL2RmeHZPNEQvczRjV0FQV0QwQU9CLzNiRUJvMGNFM3ZvUAorT01KZlBnRlgvMzdBY2NlNmc4Zlg5akRESXk4MnpRRVlnOWVISC80b3o1Z0QydjBJZW9MRVRFd2t3RDRnTWRDNEl1SFFBVCtPelVFCjRQK3REYmd2R01FSUhQNkJVKzlqR0FFL0FoaFRBNDZBcnRIL0U3NVFNQWJlb2wveDRvR0hBUG9Yd0lxZ0R3QW5BRUE5aVZHL0lCN28KZ1UwTjM0WTJuSjh2QWdrS1VhQVpnYUdqMmMwTTRRZUg4Nkg3emxBQ3ZBZkhoZm5Da1ZnNEdrQWZNSUlnd0ljWWhvZURERmxFTk9LSQpnZEhFaU5HMGlJaHBFVUcwaUZDMGlQQnBFWUVFaUhDMGlOR2t3R2hTNEdKU0VJZ1VCRU1LZ2lNRlF3Q1dGQmhOaWhnOTNiWTBIOUg4CkFjakFYLzlMYWxtSDdHU3BqM0M2MUNlRkNZTVhxQ2xiaDRxVEJvL3BhVk9mRkNZT1FESlRCeDhWSm04ZHlvbE85bkFZVXgrQnZEeGsKejZmdFEzTjhQTTBQUC85Nzduend2NTBPUDVzRkpUMUFvbWJieVh5WXJjU0dMNVBqL1BDditXeFluZjluU0wxMDVBa1pEdDdkYkRjUApnWENBNWk4dHNzYnlFZUE0aW84SW5HWWtQQVlKRytYb2lzY1FZZkVZeFVwNGpNOUw0QytjL2czOFFPQVVMeEVFeFV0RVFFUlNJZ2hKCkN2NmxlQWw4WUhnSlBvbFJ2NEJvNmNIOXR3c1d3V2daZ3RFeWVGUk1FRXJONExTZXdRV0tCa2VhQnYwR0VZVFdNd1N0WndpeG5pR1EKbmlFWVBVTndlb1lJMEVUZ0VRVC9KOFFMVFpuK2lMSHlwVGh0SkdGbzRqd1JrNW82RWl3MGVlcVR3dlFwRVVNRVlFUk1qZ1QvdzRRcwpFS0I1S2tEUVBCWEFJSEVESEhFREdDSnVBS040S29EeGVTb0F3YUxmd0hkeEJBZHhWU0JBY1ZVZ0tDSnJJQVRKQ3Y2bHVBcDhZTGdxClFKRVIvb0loYVNEdzN5OW1BVWJ2QkJpOVE4UkVKQ0VvdlVQUWVvY1E2QjBDNlIzNEc0WWt0T1lKMEpvbklOWThBYVI1QW96bUNYQ2EKSnhDa3ljQWpDZkZQQ0JxYU5QMFJad1ZOY2VKSTBJaVlVTkNrSjQ4RUxFQXdvcVpFQUVyVUVBa1lVWk1qd3Y5dFVhdmxLRnNXV0xiSQo0dlFDLzlyNk9sN01XNGZ4enhwWXRvdmorRi96aC9GbXN6Mk5UL01kZVBLd09NeVBwKzFoL25CY2J2OE52d0UvWVY0SE52SUxhZmcvCndrbmVyZz09DQoJXV0+DQo8L2k6cGdmPg0KPC9zdmc+DQo=); + -webkit-background-size: cover; + -moz-background-size: cover; + background-size: cover; + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + vertical-align: middle; + width: 1.3rem; + height: 1.3rem; +} +#download-btn { + display: none; +} +/* Content */ +#content { + width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 20px; +} +/* Code */ +#content section.code { + display: none; + background: #FFF; + border: 1px solid #E0E0E0; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 15px; + font-size: 12px; + -moz-border-radius: 1px; + -webkit-border-radius: 1px; + border-radius: 1px; + font-weight: 400; +} +article.component { + padding: 0 0 10px; +} +#content section.code h3 { + margin: 0; + font-size: 12px; + color: #000; + font-weight: 400; +} +#content header h2 { + font-weight: 300; + margin: 10px 0 25px; + font-size: 20px; + position: relative; + display: inline-block; + padding-right: 10px; +} +body.light #content header h2 { + background: #F4F4F4; +} +body.dark #content header h2 { + background: #4A4D4E; +} +#content header{ + position: relative; +} +#content header:before { + content: ''; + width: 100%; + display: block; + position: absolute; + left: 0; + top: 23px; +} +body.light #content header:before { + border-bottom: 1px solid #E0E0E0; +} +body.dark #content header:before { + border-bottom: 1px solid #58595A; +} +#content pre { + padding: 0; + margin: 2px 0 10px; +} +.showcode { + margin: 10px 0; +} +.showcode a, section.examples a { + color: #288edf; + text-decoration: none; +} +.showcode a:hover, section.examples a:hover { + text-decoration: underline; +} +section.examples ul { + margin: 0 0 20px; + padding: 0 0 0 20px; +} +section.examples h4 { + margin-bottom: 5px; +} +section.examples li { + color: #58595A; +} +/* Side Nav */ +#sideNav { + background: #4A4D4E; + position: absolute; + width: 100%; + z-index: 1; + height: 100%; + left: 0; +} +#sideNav ul { + list-style: none; + margin: 0; + padding: 0; +} +#sideNav li a { + color: #F0F1F1; + display: block; + height: 46px; + font-size: 16px; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 12px 0 0 20px; + text-decoration: none; +} +#sideNav nav.site, #sideNav .combo { + border-bottom: 1px solid #58595A; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 10px; + display: block; +} +#pageNav li { + border-bottom: 1px solid #58595A; +} + +select.docNav { + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + background: #595B5B; + background-image: none; + box-shadow: 0 0 0 1px #303233; + border: none; + border-top: 2px solid #666767; + color: #FFF; + text-shadow: 0 -1px 0 #000; + overflow: hidden; + font-size: 14px; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 20px; + -webkit-appearance: none; + -moz-appearance: button; +} +@media screen and (min-width: 650px) { + #site.open { + transform: translate3d(0, 0, 0); + -webkit-transform: translate3d(0, 0, 0); + } + #main-header nav { + display: inline-block; + position: absolute; + right: 0; + top: 40px; + } + #main-header ul { + list-style: none; + } + #main-header nav li { + display: inline-block; + margin: 0 18px; + } + #main-header nav li#download-btn { + display: none; + } + #main-header nav li a { + text-decoration: none; + font-size: 20px; + color: #7F7F7F; + } + #main-header nav li.selected a { + color: #373435; + } + #slide-menu-button{ + display: none; + } + #main-header hgroup { + text-align: left; + position: absolute; + display: inline-block; + top: 24px; + } + #main-header hgroup h1 { + font-size: 60px; + } + #main-header hgroup p { + font-size: 15px; + } + #main-header { + color: #373435; + background: #fff; + height: 148px; + } + #content { + padding-left: 240px; + } + /* Side Nav */ + #sideNav { + background: transparent; + width: 220px; + z-index: 20; + left: 10px; + top: 150px; + height: auto; + } + #sideNav nav.site { + display: none; + } + #sideNav .combo { + border-bottom: none; + padding: 36px 0; + } + #sideNav li a { + padding: 12px 0 0 10px; + } + body.light #sideNav li a { + color: #797B7B; + } + body.light #pageNav li { + border-bottom: 1px solid #E0E0E0; + } + select.docNav { + background: #595B5B; + box-shadow: 0 0 0 1px #303233; + border: none; + border-top: 2px solid #666767; + color: #FFF; + text-shadow: 0 -1px 0 #000; + padding: 3px 20px 4px 8px; + -webkit-appearance: none; + } + body.light select.docNav { + box-shadow: 0 0 0 1px #949696; + background: #DDE1E1; + border-top: 1px solid #FFF; + color: #454545; + text-shadow: 0 -1px 0 #FFF; + width: 192px; + } +} +@media screen and (min-width: 880px) { + #content { + padding-left: 300px; + } + #sideNav li a { + display: block; + height: 60px; + padding: 22px 0 0 10px; + text-decoration: none; + } + #content header h2 { + font-size: 28px; + } + #content header:before { + top: 30px; + } + section.code div { + display: inline-block; + width: 48%; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + section.code div:first-child { + padding-right: 5px; + } + section.code div:last-child { + padding-left: 5px; + } + .max-width { + max-width: 1180px; + position: relative; + margin: 0 auto; + } + header#main-header .max-width { + top: -10px; + } + #main-header nav li a { + font-size: 22px; + } + #main-header nav { + display: inline-block; + } + + #main-header nav li { + margin: 0 25px; + } + #main-header nav li:last-child { + margin-right: 0; + } +} +@media screen and (min-width: 940px) { + #main-header nav li#download-btn { + display: inline-block; + } + #main-header nav li a#download-btn{ + position:relative; + top: -15px; + display:inline-block; + box-sizing:border-box; + -moz-box-sizing:border-box; + background-clip:padding-box; + font:inherit; + background:transparent; + -webkit-user-select:none; + -moz-user-select:none; + user-select:none; + text-overflow:ellipsis; + white-space:nowrap; + overflow:hidden; + font-size:16px; + line-height:3rem; + letter-spacing:1px; + color:#454545; + text-shadow:0 1px #fff; + vertical-align:top; + background-color:#e5e9e8; + box-shadow:inset 0 1px #fff; + border:1px solid #a5a8a8; + border-radius:6px; + margin:0; + padding:0 1.25rem; + } + #main-header nav li a#download-btn, #main-header nav li a#download-btn:hover { + border:1px solid #143250; + background-color:#288edf; + box-shadow:inset 0 1px rgba(255,255,255,0.36); + color:#fff; + font-weight:500; + text-shadow:0 -1px rgba(0,0,0,0.36); + } + #main-header nav li a#download-btn:hover { + background-color:#2f9cf3; + } + #main-header nav li a#download-btn:active, #main-header nav li a#download-btn.is-active { + background-color:#0380e8; + box-shadow:inset 0 1px rgba(0,0,0,0.12); + } + #main-header nav li a#download-btn:disabled, #main-header nav li a#download-btn.is-disabled { + opacity:.3; + cursor:default; + pointer-events:none; + } +} + + + diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/css/theme.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/css/theme.css new file mode 100755 index 0000000..7f1ec6c --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/css/theme.css @@ -0,0 +1,28 @@ +pre { + padding: 0; + font-family: 'Monaco', 'Source Code Pro', monospace; + font-size: 1em; +} +.rainbow { + border-spacing: 0; + border-collapse: collapse; +} +.rainbow .line:hover { + background-color: #171b1c; +} +.rainbow .line:hover .line-number { + background-color: #101313; +} +.rainbow .line .line-number { + text-align: right; + background-color: #1b2022; + padding-left: 0.8em; + padding-right: 0.8em; +} +.rainbow .line .line-number:before { + content: attr(data-line-number); +} +.rainbow .line .line-code { + padding-left: 1em; + width: 100%; +} diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.eot b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.eot new file mode 100755 index 0000000..9e9e4de Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.eot differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.svg new file mode 100755 index 0000000..f4a1739 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.ttf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.ttf new file mode 100755 index 0000000..6eb48e7 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.ttf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.woff b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.woff new file mode 100755 index 0000000..2383f47 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.woff differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.eot b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.eot new file mode 100755 index 0000000..bda2005 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.eot differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.svg new file mode 100755 index 0000000..e031390 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.ttf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.ttf new file mode 100755 index 0000000..0959ece Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.ttf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.woff b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.woff new file mode 100755 index 0000000..522d5ab Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.woff differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.eot b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.eot new file mode 100755 index 0000000..2b75abb Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.eot differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.svg new file mode 100755 index 0000000..581a849 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.ttf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.ttf new file mode 100755 index 0000000..e166286 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.ttf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.woff b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.woff new file mode 100755 index 0000000..315c98a Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.woff differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.eot b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.eot new file mode 100755 index 0000000..ddf5d11 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.eot differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.svg new file mode 100755 index 0000000..317e536 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.ttf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.ttf new file mode 100755 index 0000000..6d97e7b Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.ttf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.woff b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.woff new file mode 100755 index 0000000..d844315 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.woff differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/stylesheet.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/stylesheet.css new file mode 100755 index 0000000..2d66502 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/fonts/stylesheet.css @@ -0,0 +1,57 @@ + +@font-face { + font-family: 'source-sans-pro'; + src: url('sourcesanspro-light-webfont.eot'); + src: url('sourcesanspro-light-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcesanspro-light-webfont.woff') format('woff'), + url('sourcesanspro-light-webfont.ttf') format('truetype'), + url('sourcesanspro-light-webfont.svg#source_sans_prolight') format('svg'); + font-weight: 300; + font-style: normal; + +} + + + + +@font-face { + font-family: 'source-sans-pro'; + src: url('sourcesanspro-regular-webfont.eot'); + src: url('sourcesanspro-regular-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcesanspro-regular-webfont.woff') format('woff'), + url('sourcesanspro-regular-webfont.ttf') format('truetype'), + url('sourcesanspro-regular-webfont.svg#source_sans_proregular') format('svg'); + font-weight: 400; + font-style: normal; + +} + + + + +@font-face { + font-family: 'source-sans-pro'; + src: url('sourcesanspro-semibold-webfont.eot'); + src: url('sourcesanspro-semibold-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcesanspro-semibold-webfont.woff') format('woff'), + url('sourcesanspro-semibold-webfont.ttf') format('truetype'), + url('sourcesanspro-semibold-webfont.svg#source_sans_prosemibold') format('svg'); + font-weight: 600; + font-style: normal; + +} + + + + +@font-face { + font-family: 'source-code-pro'; + src: url('sourcecodepro-regular-webfont.eot'); + src: url('sourcecodepro-regular-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcecodepro-regular-webfont.woff') format('woff'), + url('sourcecodepro-regular-webfont.ttf') format('truetype'), + url('sourcecodepro-regular-webfont.svg#source_code_proregular') format('svg'); + font-weight: normal; + font-style: normal; + +} \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/index.html b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/index.html new file mode 100755 index 0000000..00cf38a --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/index.html @@ -0,0 +1,3167 @@ + + + + + + Topcoat + + + + + + + +
    + +
    +
    +
    +
    +

    Topcoat

    +

    CSS for clean and fast web apps

    +
    + +
    +
    +
    +
    +
    +

    Button Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar > .topcoat-button-bar__item:first-child {
    +  border-top-left-radius: 4px;
    +  border-bottom-left-radius: 4px;
    +}
    +
    +.topcoat-button-bar > .topcoat-button-bar__item:last-child {
    +  border-top-right-radius: 4px;
    +  border-bottom-right-radius: 4px;
    +}
    +
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
    +  border-right: none;
    +}
    +
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
    +  border-left: none;
    +}
    +
    +.topcoat-button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.topcoat-button-bar__button:focus,
    +.topcoat-button-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button Bar

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar__button--large {
    +  border-radius: inherit;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-button:disabled,
    +.topcoat-button--quiet:disabled,
    +.topcoat-button--large:disabled,
    +.topcoat-button--large--quiet:disabled,
    +.topcoat-button--cta:disabled,
    +.topcoat-button--large--cta:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Button

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button">Button</button>
    <button class="topcoat-button" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  padding: 0 0.563rem;
    +  font-size: 12px;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: top;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border: 1px solid #303233;
    +  border-radius: 4px;
    +}
    +
    +.topcoat-button:hover,
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large:hover,
    +.topcoat-button--large--quiet:hover {
    +  background-color: #646666;
    +}
    +
    +.topcoat-button:active,
    +.topcoat-button--large:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +.topcoat-button:focus,
    +.topcoat-button--quiet:focus,
    +.topcoat-button--large:focus,
    +.topcoat-button--large--quiet:focus,
    +.topcoat-button--cta:focus,
    +.topcoat-button--large--cta:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--quiet">Button</button>
    <button class="topcoat-button--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large--quiet:hover {
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-button--quiet:active,
    +.topcoat-button--large--quiet:active {
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #404141;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large" >Button</button>
    <button class="topcoat-button--large" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large,
    +.topcoat-button--large--quiet {
    +  font-size: 0.875rem;
    +  font-weight: 600;
    +  line-height: 1.688rem;
    +  padding: 0 0.875rem;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--quiet" >Button</button>
    <button class="topcoat-button--large--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--cta" >Button</button>
    <button class="topcoat-button--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  border: 1px solid #143250;
    +  background-color: #288edf;
    +  box-shadow: inset 0 1px rgba(255,255,255,0.36);
    +  color: #fff;
    +  font-weight: 500;
    +  text-shadow: 0 -1px rgba(0,0,0,0.36);
    +}
    +
    +.topcoat-button--cta:hover,
    +.topcoat-button--large--cta:hover {
    +  background-color: #509bef;
    +}
    +
    +.topcoat-button--cta:active,
    +.topcoat-button--large--cta:active {
    +  background-color: #1976c3;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--cta" >Button</button>
    <button class="topcoat-button--large--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--cta {
    +  font-size: 0.875rem;
    +  font-weight: 600;
    +  line-height: 1.688rem;
    +  padding: 0 0.875rem;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox,
    +.topcoat-checkbox__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label,
    +.topcoat-checkbox {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled,
    +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after,
    +.topcoat-checkbox__checkmark:before,
    +.topcoat-checkbox__checkmark:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before,
    +.topcoat-checkbox__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Checkbox

    +
    +


    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-checkbox">
      <input type="checkbox">
      <div class="topcoat-checkbox__checkmark"></div>
      Default
    </label>
    <br>
    <br>
    <label class="topcoat-checkbox">
      <input type="checkbox" disabled>
      <div class="topcoat-checkbox__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-checkbox__checkmark {
    +  height: 1rem;
    +}
    +
    +input[type="checkbox"] {
    +  height: 1rem;
    +  width: 1rem;
    +  margin-top: 0;
    +  margin-right: -1rem;
    +  margin-bottom: -1rem;
    +  margin-left: 0;
    +}
    +
    +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-checkbox {
    +  line-height: 1rem;
    +}
    +
    +.topcoat-checkbox__checkmark:before {
    +  width: 1rem;
    +  height: 1rem;
    +  background: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 3px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-checkbox__checkmark {
    +  width: 1rem;
    +  height: 1rem;
    +}
    +
    +.topcoat-checkbox__checkmark:after {
    +  top: 2px;
    +  left: 1px;
    +  opacity: 0;
    +  width: 14px;
    +  height: 4px;
    +  background: transparent;
    +  border: 7px solid #fff;
    +  border-width: 3px;
    +  border-top: none;
    +  border-right: none;
    +  border-radius: 1px;
    +  -webkit-transform: rotate(-50deg);
    +  -ms-transform: rotate(-50deg);
    +  transform: rotate(-50deg);
    +}
    +
    +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-icon-button:disabled,
    +.topcoat-icon-button--quiet:disabled,
    +.topcoat-icon-button--large:disabled,
    +.topcoat-icon-button--large--quiet:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  padding: 0 0.25rem;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: baseline;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border: 1px solid #303233;
    +  border-radius: 4px;
    +}
    +
    +.topcoat-icon-button:hover,
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  background-color: #646666;
    +}
    +
    +.topcoat-icon-button:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +.topcoat-icon-button:focus,
    +.topcoat-icon-button--quiet:focus,
    +.topcoat-icon-button--quiet:hover:focus,
    +.topcoat-icon-button--large:focus,
    +.topcoat-icon-button--large--quiet:focus,
    +.topcoat-icon-button--large--quiet:hover:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--quiet">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--quiet" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-icon-button--quiet:active,
    +.topcoat-icon-button--large--quiet:active {
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #404141;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  width: 1.688rem;
    +  height: 1.688rem;
    +  line-height: 1.688rem;
    +}
    +
    +.topcoat-icon-button--large:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large--quiet">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large--quiet" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon,
    +.topcoat-icon--large {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  overflow: hidden;
    +  width: 0.81406rem;
    +  height: 0.81406rem;
    +  vertical-align: middle;
    +  top: -1px;
    +}
    +
    +.topcoat-icon--large {
    +  width: 1.06344rem;
    +  height: 1.06344rem;
    +  top: -2px;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header {
    +  margin: 0;
    +}
    +
    +.list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.notification {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.notification,
    +.topcoat-notification {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Notification

    +
    +
    1
    +
    + +
    +
    +

    HTML

    +
    <span class="topcoat-notification">1</span>
    +
    +
    +

    CSS

    +
    
    +.topcoat-notification {
    +  padding: 0.15em 0.5em 0.2em;
    +  border-radius: 2px;
    +  background-color: #ec514e;
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button,
    +.topcoat-radio-button__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label,
    +.topcoat-radio-button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:before,
    +.topcoat-radio-button__checkmark:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before,
    +.topcoat-radio-button__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled,
    +input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Radio Button

    +
    +






    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <!-- NO LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- LEFT LABEL -->
    <label class="topcoat-radio-button">
      Left label
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- RIGHT LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
      Right label
    </label>
    <br>
    <br>
    <!-- DISABLED -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat" Disabled>
      <div class="topcoat-radio-button__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +input[type="radio"] {
    +  height: 1.063rem;
    +  width: 1.063rem;
    +  margin-top: 0;
    +  margin-right: -1.063rem;
    +  margin-bottom: -1.063rem;
    +  margin-left: 0;
    +}
    +
    +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-radio-button {
    +  color: #c6c8c8;
    +  line-height: 1.063rem;
    +}
    +
    +.topcoat-radio-button__checkmark:before {
    +  width: 1.063rem;
    +  height: 1.063rem;
    +  background: #595b5b;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-radio-button__checkmark {
    +  position: relative;
    +  width: 1.063rem;
    +  height: 1.063rem;
    +}
    +
    +.topcoat-radio-button__checkmark:after {
    +  opacity: 0;
    +  width: 0.313rem;
    +  height: 0.313rem;
    +  background: #fff;
    +  border: 1px solid rgba(255,255,255,0.1);
    +  box-shadow: 0 1px rgba(255,255,255,0.5);
    +  -webkit-transform: none;
    +  -ms-transform: none;
    +  transform: none;
    +  top: 0.313rem;
    +  left: 0.313rem;
    +}
    +
    +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range,
    +.topcoat-range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb,
    +.topcoat-range::-moz-range-thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit,
    +.topcoat-range::-webkit-slider-thumb {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled,
    +.topcoat-range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Range

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <input type="range" class="topcoat-range">
    <input type="range" class="topcoat-range" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-range {
    +  border-radius: 4px;
    +  border: 1px solid #303233;
    +  background-color: #424546;
    +  height: 0.5rem;
    +  border-radius: 15px;
    +}
    +
    +.topcoat-range::-moz-range-track {
    +  border-radius: 4px;
    +  border: 1px solid #303233;
    +  background-color: #424546;
    +  height: 0.5rem;
    +  border-radius: 15px;
    +}
    +
    +.topcoat-range::-webkit-slider-thumb {
    +  height: 1.313rem;
    +  width: 0.75rem;
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 4px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-range::-moz-range-thumb {
    +  height: 1.313rem;
    +  width: 0.75rem;
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 4px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-range:focus::-webkit-slider-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-range:focus::-moz-range-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input,
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled,
    +.topcoat-search-input:disabled,
    +.topcoat-search-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input">
    <input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  line-height: 1.313rem;
    +  font-size: 12px;
    +  border: 1px solid #303233;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  padding: 0 0 0 1.3rem;
    +  border-radius: 15px;
    +  background-image: url("../img/search.svg");
    +  background-position: 1em center;
    +  background-repeat: no-repeat;
    +  background-size: 12px;
    +}
    +
    +.topcoat-search-input:focus,
    +.topcoat-search-input--large:focus {
    +  background-image: url("../img/search_dark.svg");
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-search-input::-webkit-search-cancel-button,
    +.topcoat-search-input::-webkit-search-decoration,
    +.topcoat-search-input--large::-webkit-search-cancel-button,
    +.topcoat-search-input--large::-webkit-search-decoration {
    +  margin-right: 5px;
    +}
    +
    +.topcoat-search-input:focus::-webkit-input-placeholder,
    +.topcoat-search-input:focus::-webkit-input-placeholder {
    +  color: #c6c8c8;
    +}
    +
    +.topcoat-search-input:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large">
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input--large {
    +  line-height: 1.688rem;
    +  font-size: 0.875rem;
    +  font-weight: 400;
    +  padding: 0 0 0 1.8rem;
    +  border-radius: 25px;
    +  background-position: 1.2em center;
    +  background-size: 0.875rem;
    +}
    +
    +.topcoat-search-input--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch,
    +.topcoat-switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input,
    +.topcoat-switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle,
    +.topcoat-switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after,
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Switch

    +
    +




    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input">
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" checked>
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" disabled>
      <div class="topcoat-switch__toggle"></div>
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-switch {
    +  font-size: 12px;
    +  padding: 0 0.563rem;
    +  border-radius: 4px;
    +  border: 1px solid #303233;
    +  overflow: hidden;
    +  width: 3.5rem;
    +}
    +
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  top: -1px;
    +  width: 2.6rem;
    +}
    +
    +.topcoat-switch__toggle:before {
    +  content: 'ON';
    +  color: #5dc1ff;
    +  background-color: #404141;
    +  right: 0.8rem;
    +  padding-left: 0.75rem;
    +}
    +
    +.topcoat-switch__toggle {
    +  line-height: 1.313rem;
    +  height: 1.313rem;
    +  width: 1rem;
    +  border-radius: 4px;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  margin-left: -0.6rem;
    +  margin-bottom: -1px;
    +  margin-top: -1px;
    +  box-shadow: inset 0 1px #727373;
    +  -webkit-transition: margin-left 0.05s ease-in-out;
    +  transition: margin-left 0.05s ease-in-out;
    +}
    +
    +.topcoat-switch__toggle:after {
    +  content: 'OFF';
    +  background-color: #404141;
    +  left: 0.8rem;
    +  padding-left: 0.6rem;
    +}
    +
    +.topcoat-switch__input:checked + .topcoat-switch__toggle {
    +  margin-left: 1.85rem;
    +}
    +
    +.topcoat-switch__input:focus + .topcoat-switch__toggle {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
    +  background: transparent;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-tab-bar__button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-tab-bar__button:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.button-bar,
    +.topcoat-tab-bar {
    +  display: table;
    +  table-layout: fixed;
    +  white-space: nowrap;
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +.button-bar__item,
    +.topcoat-tab-bar__item {
    +  display: table-cell;
    +  width: auto;
    +  border-radius: 0;
    +}
    +
    +.button-bar__item > input,
    +.topcoat-tab-bar__item > input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.button-bar__item:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Tab Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-tab-bar">
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">One</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Two</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Three</button>
      </label>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-tab-bar__button {
    +  padding: 0 0.563rem;
    +  height: 1.313rem;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: top;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border-top: 1px solid #303233;
    +}
    +
    +.topcoat-tab-bar__button:active,
    +.topcoat-tab-bar__button--large:active,
    +:checked + .topcoat-tab-bar__button {
    +  color: #5dc1ff;
    +  background-color: #404141;
    +  box-shadow: inset 0 0 2px #313231;
    +}
    +
    +.topcoat-tab-bar__button:focus,
    +.topcoat-tab-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input,
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled,
    +.topcoat-text-input:disabled,
    +.topcoat-text-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Text input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input" placeholder="text" value="">
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  line-height: 1.313rem;
    +  font-size: 12px;
    +  letter-spacing: 0;
    +  padding: 0 0.563rem;
    +  border: 1px solid #303233;
    +  border-radius: 4px;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  vertical-align: top;
    +}
    +
    +.topcoat-text-input:focus,
    +.topcoat-text-input--large:focus {
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-text-input:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Text Input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text">
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input--large {
    +  line-height: 1.688rem;
    +  font-size: 0.875rem;
    +}
    +
    +.topcoat-text-input--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea,
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled,
    +.topcoat-textarea:disabled,
    +.topcoat-textarea--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  padding: 1rem;
    +  font-size: 1rem;
    +  font-weight: 400;
    +  border-radius: 4px;
    +  line-height: 1.313rem;
    +  border: 1px solid #303233;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  letter-spacing: 0;
    +}
    +
    +.topcoat-textarea:focus,
    +.topcoat-textarea--large:focus {
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-textarea:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea--large {
    +  font-size: 1.3rem;
    +  line-height: 1.688rem;
    +}
    +
    +.topcoat-textarea--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Regular.otf");
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Light.otf");
    +  font-weight: 200;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Semibold.otf");
    +  font-weight: 600;
    +}
    +
    +body {
    +  margin: 0;
    +  padding: 0;
    +  background: #4b4d4e;
    +  color: #000;
    +  font: 16px "Source Sans", helvetica, arial, sans-serif;
    +  font-weight: 200;
    +}
    +
    +:focus {
    +  outline-color: transparent;
    +  outline-style: none;
    +}
    +
    +.topcoat-icon--menu-stack {
    +  background: url("../img/hamburger_light.svg") no-repeat;
    +  background-size: cover;
    +}
    +
    +.quarter {
    +  width: 25%;
    +}
    +
    +.half {
    +  width: 50%;
    +}
    +
    +.three-quarters {
    +  width: 75%;
    +}
    +
    +.third {
    +  width: 33.333%;
    +}
    +
    +.two-thirds {
    +  width: 66.666%;
    +}
    +
    +.full {
    +  width: 100%;
    +}
    +
    +.left {
    +  text-align: left;
    +}
    +
    +.center {
    +  text-align: center;
    +}
    +
    +.right {
    +  text-align: right;
    +}
    +
    +.reset-ui {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/* This file should include color and image variables corresponding to the dark theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* Search Input */
    +
    +/* List */
    +
    +/* Checkbox */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Textarea */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* This file should include color and image variables corresponding to the light theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* List */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Range input */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Containers */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Text Area */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* Text Input */
    +
    +/* Radio input */
    +
    +/* Overlay */
    +
    +/* Textarea */
    +
    +/* Progress bar container */
    +
    +/* Progress bar progress */
    +
    +/* Search input */
    +
    +/* Switch */
    +
    +/* Notification */
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/js/main.js b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/js/main.js new file mode 100755 index 0000000..6dcdbd8 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/js/main.js @@ -0,0 +1,44 @@ +window.onload = function(){ + var showCodeDivs = document.getElementsByClassName('showcode'); + for (var i = showCodeDivs.length - 1; i >= 0; i--) { + showCodeDivs[i].firstChild.onclick = function(e) { + var element = e.target.parentNode.nextSibling.nextSibling; + var style = window.getComputedStyle(element); + if(style.getPropertyValue('display') == 'none'){ + e.target.innerHTML = 'Hide code snippets'; + element.style.display = 'block'; + } else { + e.target.innerHTML = 'Show code snippets'; + element.style.display = 'none'; + } + return false; + }; + }; + var slideMenuButton = document.getElementById('slide-menu-button'); + slideMenuButton.onclick = function(e) { + var site = document.getElementById('site'); + var cl = site.classList; + if (cl.contains('open')) { + cl.remove('open'); + } else { + cl.add('open'); + } + }; + var docNavs = document.getElementsByClassName('docNav'); + for (var j = docNavs.length - 1; j >= 0; j--) { + docNavs[j].onchange = function(e){ + window.location.href = e.target[e.target.selectedIndex].value; + }; + }; + var pageNav = document.getElementById('pageNav'); + var pageLinks = pageNav.getElementsByTagName('a'); + for (var k = pageLinks.length - 1; k >= 0; k--) { + pageLinks[k].onclick = function(e) { + var site = document.getElementById('site'); + var cl = site.classList; + if (cl.contains('open')) { + cl.remove('open'); + } + }; + }; +} \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/js/rainbow-custom.min.js b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/js/rainbow-custom.min.js new file mode 100755 index 0000000..a25e178 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/js/rainbow-custom.min.js @@ -0,0 +1,11 @@ +/* Rainbow v1.2 rainbowco.de | included languages: html, css */ +window.Rainbow=function(){function q(a){var b,c=a.getAttribute&&a.getAttribute("data-language")||0;if(!c){a=a.attributes;for(b=0;b=f[d][c])delete f[d][c],delete j[d][c];if(a>=c&&ac&&b'+b+""}function s(a,b,c,i){var e=a.exec(c);if(e){++t;!b.name&&"string"==typeof b.matches[0]&&(b.name=b.matches[0],delete b.matches[0]);var k=e[0],g=e.index,u=e[0].length+g,h=function(){function e(){s(a,b,c,i)}t%100>0?e():setTimeout(e,0)};if(C(g,u))h();else{var m=v(b.matches),l=function(a,c,i){if(a>=c.length)i(k);else{var d=e[c[a]];if(d){var g=b.matches[c[a]],f=g.language,h=g.name&&g.matches? +g.matches:g,j=function(b,d,g){var f;f=0;var h;for(h=1;h/g,">").replace(/&(?![\w\#]+;)/g, +"&"),b,c)}function o(a,b,c){if(b + + + + + Topcoat + + + + + + + +
    + +
    +
    +
    +
    +

    Topcoat

    +

    CSS for clean and fast web apps

    +
    + +
    +
    +
    +
    +
    +

    Button Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar > .topcoat-button-bar__item:first-child {
    +  border-top-left-radius: 4px;
    +  border-bottom-left-radius: 4px;
    +}
    +
    +.topcoat-button-bar > .topcoat-button-bar__item:last-child {
    +  border-top-right-radius: 4px;
    +  border-bottom-right-radius: 4px;
    +}
    +
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
    +  border-right: none;
    +}
    +
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
    +  border-left: none;
    +}
    +
    +.topcoat-button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.topcoat-button-bar__button:focus,
    +.topcoat-button-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button Bar

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar__button--large {
    +  border-radius: inherit;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-button:disabled,
    +.topcoat-button--quiet:disabled,
    +.topcoat-button--large:disabled,
    +.topcoat-button--large--quiet:disabled,
    +.topcoat-button--cta:disabled,
    +.topcoat-button--large--cta:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Button

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button">Button</button>
    <button class="topcoat-button" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  padding: 0 0.563rem;
    +  font-size: 12px;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: top;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 4px;
    +}
    +
    +.topcoat-button:hover,
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large:hover,
    +.topcoat-button--large--quiet:hover {
    +  background-color: #edf1f1;
    +}
    +
    +.topcoat-button:active,
    +.topcoat-button--large:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +.topcoat-button:focus,
    +.topcoat-button--quiet:focus,
    +.topcoat-button--large:focus,
    +.topcoat-button--large--quiet:focus,
    +.topcoat-button--cta:focus,
    +.topcoat-button--large--cta:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--quiet">Button</button>
    <button class="topcoat-button--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large--quiet:hover {
    +  text-shadow: 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-button--quiet:active,
    +.topcoat-button--large--quiet:active {
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #d3d7d7;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large" >Button</button>
    <button class="topcoat-button--large" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large,
    +.topcoat-button--large--quiet {
    +  font-size: 0.875rem;
    +  font-weight: 600;
    +  line-height: 1.688rem;
    +  padding: 0 0.875rem;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--quiet" >Button</button>
    <button class="topcoat-button--large--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--cta" >Button</button>
    <button class="topcoat-button--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  border: 1px solid #143250;
    +  background-color: #288edf;
    +  box-shadow: inset 0 1px rgba(255,255,255,0.36);
    +  color: #fff;
    +  font-weight: 500;
    +  text-shadow: 0 -1px rgba(0,0,0,0.36);
    +}
    +
    +.topcoat-button--cta:hover,
    +.topcoat-button--large--cta:hover {
    +  background-color: #509bef;
    +}
    +
    +.topcoat-button--cta:active,
    +.topcoat-button--large--cta:active {
    +  background-color: #0380e8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--cta" >Button</button>
    <button class="topcoat-button--large--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--cta {
    +  font-size: 0.875rem;
    +  font-weight: 600;
    +  line-height: 1.688rem;
    +  padding: 0 0.875rem;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox,
    +.topcoat-checkbox__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label,
    +.topcoat-checkbox {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled,
    +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after,
    +.topcoat-checkbox__checkmark:before,
    +.topcoat-checkbox__checkmark:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before,
    +.topcoat-checkbox__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Checkbox

    +
    +


    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-checkbox">
      <input type="checkbox">
      <div class="topcoat-checkbox__checkmark"></div>
      Default
    </label>
    <br>
    <br>
    <label class="topcoat-checkbox">
      <input type="checkbox" disabled>
      <div class="topcoat-checkbox__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-checkbox__checkmark {
    +  height: 1rem;
    +}
    +
    +input[type="checkbox"] {
    +  height: 1rem;
    +  width: 1rem;
    +  margin-top: 0;
    +  margin-right: -1rem;
    +  margin-bottom: -1rem;
    +  margin-left: 0;
    +}
    +
    +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-checkbox {
    +  line-height: 1rem;
    +}
    +
    +.topcoat-checkbox__checkmark:before {
    +  width: 1rem;
    +  height: 1rem;
    +  background: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 3px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-checkbox__checkmark {
    +  width: 1rem;
    +  height: 1rem;
    +}
    +
    +.topcoat-checkbox__checkmark:after {
    +  top: 2px;
    +  left: 1px;
    +  opacity: 0;
    +  width: 14px;
    +  height: 4px;
    +  background: transparent;
    +  border: 7px solid #666;
    +  border-width: 3px;
    +  border-top: none;
    +  border-right: none;
    +  border-radius: 1px;
    +  -webkit-transform: rotate(-50deg);
    +  -ms-transform: rotate(-50deg);
    +  transform: rotate(-50deg);
    +}
    +
    +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-icon-button:disabled,
    +.topcoat-icon-button--quiet:disabled,
    +.topcoat-icon-button--large:disabled,
    +.topcoat-icon-button--large--quiet:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  padding: 0 0.25rem;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: baseline;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 4px;
    +}
    +
    +.topcoat-icon-button:hover,
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  background-color: #edf1f1;
    +}
    +
    +.topcoat-icon-button:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +.topcoat-icon-button:focus,
    +.topcoat-icon-button--quiet:focus,
    +.topcoat-icon-button--quiet:hover:focus,
    +.topcoat-icon-button--large:focus,
    +.topcoat-icon-button--large--quiet:focus,
    +.topcoat-icon-button--large--quiet:hover:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--quiet">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--quiet" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  text-shadow: 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-icon-button--quiet:active,
    +.topcoat-icon-button--large--quiet:active {
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #d3d7d7;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  width: 1.688rem;
    +  height: 1.688rem;
    +  line-height: 1.688rem;
    +}
    +
    +.topcoat-icon-button--large:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large--quiet">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large--quiet" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon,
    +.topcoat-icon--large {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  overflow: hidden;
    +  width: 0.81406rem;
    +  height: 0.81406rem;
    +  vertical-align: middle;
    +  top: -1px;
    +}
    +
    +.topcoat-icon--large {
    +  width: 1.06344rem;
    +  height: 1.06344rem;
    +  top: -2px;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header {
    +  margin: 0;
    +}
    +
    +.list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.notification {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.notification,
    +.topcoat-notification {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Notification

    +
    +
    1
    +
    + +
    +
    +

    HTML

    +
    <span class="topcoat-notification">1</span>
    +
    +
    +

    CSS

    +
    
    +.topcoat-notification {
    +  padding: 0.15em 0.5em 0.2em;
    +  border-radius: 2px;
    +  background-color: #ec514e;
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button,
    +.topcoat-radio-button__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label,
    +.topcoat-radio-button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:before,
    +.topcoat-radio-button__checkmark:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before,
    +.topcoat-radio-button__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled,
    +input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Radio Button

    +
    +






    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <!-- NO LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- LEFT LABEL -->
    <label class="topcoat-radio-button">
      Left label
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- RIGHT LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
      Right label
    </label>
    <br>
    <br>
    <!-- DISABLED -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat" Disabled>
      <div class="topcoat-radio-button__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +input[type="radio"] {
    +  height: 1.063rem;
    +  width: 1.063rem;
    +  margin-top: 0;
    +  margin-right: -1.063rem;
    +  margin-bottom: -1.063rem;
    +  margin-left: 0;
    +}
    +
    +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-radio-button {
    +  color: #454545;
    +  line-height: 1.063rem;
    +}
    +
    +.topcoat-radio-button__checkmark:before {
    +  width: 1.063rem;
    +  height: 1.063rem;
    +  background: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-radio-button__checkmark {
    +  position: relative;
    +  width: 1.063rem;
    +  height: 1.063rem;
    +}
    +
    +.topcoat-radio-button__checkmark:after {
    +  opacity: 0;
    +  width: 0.313rem;
    +  height: 0.313rem;
    +  background: #666;
    +  border: 1px solid rgba(0,0,0,0.1);
    +  box-shadow: 0 1px rgba(255,255,255,0.5);
    +  -webkit-transform: none;
    +  -ms-transform: none;
    +  transform: none;
    +  top: 0.313rem;
    +  left: 0.313rem;
    +}
    +
    +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range,
    +.topcoat-range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb,
    +.topcoat-range::-moz-range-thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit,
    +.topcoat-range::-webkit-slider-thumb {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled,
    +.topcoat-range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Range

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <input type="range" class="topcoat-range">
    <input type="range" class="topcoat-range" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-range {
    +  border-radius: 4px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  height: 0.5rem;
    +  border-radius: 15px;
    +}
    +
    +.topcoat-range::-moz-range-track {
    +  border-radius: 4px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  height: 0.5rem;
    +  border-radius: 15px;
    +}
    +
    +.topcoat-range::-webkit-slider-thumb {
    +  height: 1.313rem;
    +  width: 0.75rem;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 4px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-range::-moz-range-thumb {
    +  height: 1.313rem;
    +  width: 0.75rem;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 4px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-range:focus::-webkit-slider-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-range:focus::-moz-range-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input,
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled,
    +.topcoat-search-input:disabled,
    +.topcoat-search-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input">
    <input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  line-height: 1.313rem;
    +  font-size: 12px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  padding: 0 0 0 1.3rem;
    +  border-radius: 15px;
    +  background-image: url("../img/search.svg");
    +  background-position: 1em center;
    +  background-repeat: no-repeat;
    +  background-size: 12px;
    +}
    +
    +.topcoat-search-input:focus,
    +.topcoat-search-input--large:focus {
    +  background-image: url("../img/search_dark.svg");
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-search-input::-webkit-search-cancel-button,
    +.topcoat-search-input::-webkit-search-decoration,
    +.topcoat-search-input--large::-webkit-search-cancel-button,
    +.topcoat-search-input--large::-webkit-search-decoration {
    +  margin-right: 5px;
    +}
    +
    +.topcoat-search-input:focus::-webkit-input-placeholder,
    +.topcoat-search-input:focus::-webkit-input-placeholder {
    +  color: #c6c8c8;
    +}
    +
    +.topcoat-search-input:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large">
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input--large {
    +  line-height: 1.688rem;
    +  font-size: 0.875rem;
    +  font-weight: 400;
    +  padding: 0 0 0 1.8rem;
    +  border-radius: 25px;
    +  background-position: 1.2em center;
    +  background-size: 0.875rem;
    +}
    +
    +.topcoat-search-input--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch,
    +.topcoat-switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input,
    +.topcoat-switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle,
    +.topcoat-switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after,
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Switch

    +
    +




    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input">
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" checked>
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" disabled>
      <div class="topcoat-switch__toggle"></div>
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-switch {
    +  font-size: 12px;
    +  padding: 0 0.563rem;
    +  border-radius: 4px;
    +  border: 1px solid #a5a8a8;
    +  overflow: hidden;
    +  width: 3.5rem;
    +}
    +
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  top: -1px;
    +  width: 2.6rem;
    +}
    +
    +.topcoat-switch__toggle:before {
    +  content: 'ON';
    +  color: #0083e8;
    +  background-color: #e0f0fa;
    +  right: 0.8rem;
    +  padding-left: 0.75rem;
    +}
    +
    +.topcoat-switch__toggle {
    +  line-height: 1.313rem;
    +  height: 1.313rem;
    +  width: 1rem;
    +  border-radius: 4px;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  margin-left: -0.6rem;
    +  margin-bottom: -1px;
    +  margin-top: -1px;
    +  box-shadow: inset 0 1px #fff;
    +  -webkit-transition: margin-left 0.05s ease-in-out;
    +  transition: margin-left 0.05s ease-in-out;
    +}
    +
    +.topcoat-switch__toggle:after {
    +  content: 'OFF';
    +  background-color: #d3d7d7;
    +  left: 0.8rem;
    +  padding-left: 0.6rem;
    +}
    +
    +.topcoat-switch__input:checked + .topcoat-switch__toggle {
    +  margin-left: 1.85rem;
    +}
    +
    +.topcoat-switch__input:focus + .topcoat-switch__toggle {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
    +  background: transparent;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-tab-bar__button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-tab-bar__button:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.button-bar,
    +.topcoat-tab-bar {
    +  display: table;
    +  table-layout: fixed;
    +  white-space: nowrap;
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +.button-bar__item,
    +.topcoat-tab-bar__item {
    +  display: table-cell;
    +  width: auto;
    +  border-radius: 0;
    +}
    +
    +.button-bar__item > input,
    +.topcoat-tab-bar__item > input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.button-bar__item:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Tab Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-tab-bar">
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">One</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Two</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Three</button>
      </label>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-tab-bar__button {
    +  padding: 0 0.563rem;
    +  height: 1.313rem;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: top;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border-top: 1px solid #a5a8a8;
    +}
    +
    +.topcoat-tab-bar__button:active,
    +.topcoat-tab-bar__button--large:active,
    +:checked + .topcoat-tab-bar__button {
    +  color: #0083e8;
    +  background-color: #e0f0fa;
    +  box-shadow: inset 0 0 2px #c0ced8;
    +}
    +
    +.topcoat-tab-bar__button:focus,
    +.topcoat-tab-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input,
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled,
    +.topcoat-text-input:disabled,
    +.topcoat-text-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Text input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input" placeholder="text" value="">
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  line-height: 1.313rem;
    +  font-size: 12px;
    +  letter-spacing: 0;
    +  padding: 0 0.563rem;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 4px;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  vertical-align: top;
    +}
    +
    +.topcoat-text-input:focus,
    +.topcoat-text-input--large:focus {
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-text-input:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Text Input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text">
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input--large {
    +  line-height: 1.688rem;
    +  font-size: 0.875rem;
    +}
    +
    +.topcoat-text-input--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea,
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled,
    +.topcoat-textarea:disabled,
    +.topcoat-textarea--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  padding: 1rem;
    +  font-size: 1rem;
    +  font-weight: 400;
    +  border-radius: 4px;
    +  line-height: 1.313rem;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  letter-spacing: 0;
    +}
    +
    +.topcoat-textarea:focus,
    +.topcoat-textarea--large:focus {
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-textarea:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea--large {
    +  font-size: 1.3rem;
    +  line-height: 1.688rem;
    +}
    +
    +.topcoat-textarea--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Regular.otf");
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Light.otf");
    +  font-weight: 200;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Semibold.otf");
    +  font-weight: 600;
    +}
    +
    +body {
    +  margin: 0;
    +  padding: 0;
    +  background: #dfe2e2;
    +  color: #000;
    +  font: 16px "Source Sans", helvetica, arial, sans-serif;
    +  font-weight: 200;
    +}
    +
    +:focus {
    +  outline-color: transparent;
    +  outline-style: none;
    +}
    +
    +.topcoat-icon--menu-stack {
    +  background: url("../img/hamburger_dark.svg") no-repeat;
    +  background-size: cover;
    +}
    +
    +.quarter {
    +  width: 25%;
    +}
    +
    +.half {
    +  width: 50%;
    +}
    +
    +.three-quarters {
    +  width: 75%;
    +}
    +
    +.third {
    +  width: 33.333%;
    +}
    +
    +.two-thirds {
    +  width: 66.666%;
    +}
    +
    +.full {
    +  width: 100%;
    +}
    +
    +.left {
    +  text-align: left;
    +}
    +
    +.center {
    +  text-align: center;
    +}
    +
    +.right {
    +  text-align: right;
    +}
    +
    +.reset-ui {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/* This file should include color and image variables corresponding to the dark theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* Search Input */
    +
    +/* List */
    +
    +/* Checkbox */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Textarea */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* This file should include color and image variables corresponding to the light theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* List */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Range input */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Containers */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Text Area */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* Text Input */
    +
    +/* Radio input */
    +
    +/* Overlay */
    +
    +/* Textarea */
    +
    +/* Progress bar container */
    +
    +/* Progress bar progress */
    +
    +/* Search input */
    +
    +/* Switch */
    +
    +/* Notification */
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-dark.html b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-dark.html new file mode 100755 index 0000000..327aeae --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-dark.html @@ -0,0 +1,3417 @@ + + + + + + Topcoat + + + + + + + +
    + +
    +
    +
    +
    +

    Topcoat

    +

    CSS for clean and fast web apps

    +
    + +
    +
    +
    +
    +
    +

    Button Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar > .topcoat-button-bar__item:first-child {
    +  border-top-left-radius: 6px;
    +  border-bottom-left-radius: 6px;
    +}
    +
    +.topcoat-button-bar > .topcoat-button-bar__item:last-child {
    +  border-top-right-radius: 6px;
    +  border-bottom-right-radius: 6px;
    +}
    +
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
    +  border-right: none;
    +}
    +
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
    +  border-left: none;
    +}
    +
    +.topcoat-button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.topcoat-button-bar__button:focus,
    +.topcoat-button-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button Bar

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar__button--large {
    +  border-radius: inherit;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-button:disabled,
    +.topcoat-button--quiet:disabled,
    +.topcoat-button--large:disabled,
    +.topcoat-button--large--quiet:disabled,
    +.topcoat-button--cta:disabled,
    +.topcoat-button--large--cta:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Button

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button">Button</button>
    <button class="topcoat-button" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  padding: 0 1.25rem;
    +  font-size: 16px;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: top;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border: 1px solid #303233;
    +  border-radius: 6px;
    +}
    +
    +.topcoat-button:hover,
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large:hover,
    +.topcoat-button--large--quiet:hover {
    +  background-color: #646666;
    +}
    +
    +.topcoat-button:active,
    +.topcoat-button--large:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +.topcoat-button:focus,
    +.topcoat-button--quiet:focus,
    +.topcoat-button--large:focus,
    +.topcoat-button--large--quiet:focus,
    +.topcoat-button--cta:focus,
    +.topcoat-button--large--cta:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--quiet">Button</button>
    <button class="topcoat-button--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large--quiet:hover {
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-button--quiet:active,
    +.topcoat-button--large--quiet:active {
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #404141;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large" >Button</button>
    <button class="topcoat-button--large" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large,
    +.topcoat-button--large--quiet {
    +  font-size: 1.3rem;
    +  font-weight: 400;
    +  line-height: 4.375rem;
    +  padding: 0 1.25rem;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--quiet" >Button</button>
    <button class="topcoat-button--large--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--cta" >Button</button>
    <button class="topcoat-button--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  border: 1px solid #143250;
    +  background-color: #288edf;
    +  box-shadow: inset 0 1px rgba(255,255,255,0.36);
    +  color: #fff;
    +  font-weight: 500;
    +  text-shadow: 0 -1px rgba(0,0,0,0.36);
    +}
    +
    +.topcoat-button--cta:hover,
    +.topcoat-button--large--cta:hover {
    +  background-color: #509bef;
    +}
    +
    +.topcoat-button--cta:active,
    +.topcoat-button--large--cta:active {
    +  background-color: #1976c3;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--cta" >Button</button>
    <button class="topcoat-button--large--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--cta {
    +  font-size: 1.3rem;
    +  font-weight: 400;
    +  line-height: 4.375rem;
    +  padding: 0 1.25rem;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox,
    +.topcoat-checkbox__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label,
    +.topcoat-checkbox {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled,
    +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after,
    +.topcoat-checkbox__checkmark:before,
    +.topcoat-checkbox__checkmark:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before,
    +.topcoat-checkbox__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Checkbox

    +
    +


    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-checkbox">
      <input type="checkbox">
      <div class="topcoat-checkbox__checkmark"></div>
      Default
    </label>
    <br>
    <br>
    <label class="topcoat-checkbox">
      <input type="checkbox" disabled>
      <div class="topcoat-checkbox__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-checkbox__checkmark {
    +  height: 2rem;
    +}
    +
    +input[type="checkbox"] {
    +  height: 2rem;
    +  width: 2rem;
    +  margin-top: 0;
    +  margin-right: -2rem;
    +  margin-bottom: -2rem;
    +  margin-left: 0;
    +}
    +
    +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-checkbox {
    +  line-height: 2rem;
    +}
    +
    +.topcoat-checkbox__checkmark:before {
    +  width: 2rem;
    +  height: 2rem;
    +  background: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 3px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-checkbox__checkmark {
    +  width: 2rem;
    +  height: 2rem;
    +}
    +
    +.topcoat-checkbox__checkmark:after {
    +  top: 1px;
    +  left: 2px;
    +  opacity: 0;
    +  width: 28px;
    +  height: 11px;
    +  background: transparent;
    +  border: 7px solid #fff;
    +  border-width: 7px;
    +  border-top: none;
    +  border-right: none;
    +  border-radius: 2px;
    +  -webkit-transform: rotate(-50deg);
    +  -ms-transform: rotate(-50deg);
    +  transform: rotate(-50deg);
    +}
    +
    +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-icon-button:disabled,
    +.topcoat-icon-button--quiet:disabled,
    +.topcoat-icon-button--large:disabled,
    +.topcoat-icon-button--large--quiet:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  padding: 0 0.75rem;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: baseline;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border: 1px solid #303233;
    +  border-radius: 6px;
    +}
    +
    +.topcoat-icon-button:hover,
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  background-color: #646666;
    +}
    +
    +.topcoat-icon-button:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +.topcoat-icon-button:focus,
    +.topcoat-icon-button--quiet:focus,
    +.topcoat-icon-button--quiet:hover:focus,
    +.topcoat-icon-button--large:focus,
    +.topcoat-icon-button--large--quiet:focus,
    +.topcoat-icon-button--large--quiet:hover:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--quiet">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--quiet" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-icon-button--quiet:active,
    +.topcoat-icon-button--large--quiet:active {
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #404141;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  width: 4.375rem;
    +  height: 4.375rem;
    +  line-height: 4.375rem;
    +}
    +
    +.topcoat-icon-button--large:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large--quiet">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large--quiet" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon,
    +.topcoat-icon--large {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  overflow: hidden;
    +  width: 1.62rem;
    +  height: 1.62rem;
    +  vertical-align: middle;
    +  top: -1px;
    +}
    +
    +.topcoat-icon--large {
    +  width: 2.499999998125rem;
    +  height: 2.499999998125rem;
    +  top: -2px;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header {
    +  margin: 0;
    +}
    +
    +.list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list,
    +.topcoat-list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header,
    +.topcoat-list__header {
    +  margin: 0;
    +}
    +
    +.list__container,
    +.topcoat-list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item,
    +.topcoat-list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    List

    +
    +

    Category

    • Item
    • Item
    • Item
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-list">
      <h3 class="topcoat-list__header">Category</h3>
      <ul class="topcoat-list__container">
        <li class="topcoat-list__item">
          Item
        </li>
        <li class="topcoat-list__item">
          Item
        </li>
        <li class="topcoat-list__item">
          Item
        </li>
      </ul>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-list {
    +  border-top: 1px solid #2f3234;
    +  border-bottom: 1px solid #5e6061;
    +  background-color: #444849;
    +}
    +
    +.topcoat-list__header {
    +  padding: 4px 20px;
    +  font-size: 0.9em;
    +  font-weight: 400;
    +  background-color: #3b3e40;
    +  color: #868888;
    +  text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
    +  border-top: solid 1px rgba(255,255,255,0.1);
    +  border-bottom: solid 1px rgba(255,255,255,0.05);
    +}
    +
    +.topcoat-list__container {
    +  border-top: 1px solid #2f3234;
    +  color: #c6c8c8;
    +}
    +
    +.topcoat-list__item {
    +  padding: 1.25rem;
    +  border-top: 1px solid #5e6061;
    +  border-bottom: 1px solid #2f3234;
    +}
    +
    +.topcoat-list__item:first-child {
    +  border-top: 1px solid rgba(0,0,0,0.05);
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar,
    +.topcoat-navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item,
    +.topcoat-navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title,
    +.topcoat-navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +
    +
    +
    +
    + +
    +
    +

    Notification

    +
    +
    1
    +
    + +
    +
    +

    HTML

    +
    <span class="topcoat-notification">1</span>
    +
    +
    +

    CSS

    +
    
    +.topcoat-notification {
    +  padding: 0.15em 0.5em 0.2em;
    +  border-radius: 2px;
    +  background-color: #ec514e;
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button,
    +.topcoat-radio-button__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label,
    +.topcoat-radio-button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:before,
    +.topcoat-radio-button__checkmark:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before,
    +.topcoat-radio-button__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled,
    +input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Radio Button

    +
    +






    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <!-- NO LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- LEFT LABEL -->
    <label class="topcoat-radio-button">
      Left label
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- RIGHT LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
      Right label
    </label>
    <br>
    <br>
    <!-- DISABLED -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat" Disabled>
      <div class="topcoat-radio-button__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +input[type="radio"] {
    +  height: 1.875rem;
    +  width: 1.875rem;
    +  margin-top: 0;
    +  margin-right: -1.875rem;
    +  margin-bottom: -1.875rem;
    +  margin-left: 0;
    +}
    +
    +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-radio-button {
    +  color: #c6c8c8;
    +  line-height: 1.875rem;
    +}
    +
    +.topcoat-radio-button__checkmark:before {
    +  width: 1.875rem;
    +  height: 1.875rem;
    +  background: #595b5b;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-radio-button__checkmark {
    +  position: relative;
    +  width: 1.875rem;
    +  height: 1.875rem;
    +}
    +
    +.topcoat-radio-button__checkmark:after {
    +  opacity: 0;
    +  width: 0.875rem;
    +  height: 0.875rem;
    +  background: #fff;
    +  border: 1px solid rgba(255,255,255,0.1);
    +  box-shadow: 0 1px rgba(255,255,255,0.5);
    +  -webkit-transform: none;
    +  -ms-transform: none;
    +  transform: none;
    +  top: 7px;
    +  left: 7px;
    +}
    +
    +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range,
    +.topcoat-range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb,
    +.topcoat-range::-moz-range-thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit,
    +.topcoat-range::-webkit-slider-thumb {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled,
    +.topcoat-range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Range

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <input type="range" class="topcoat-range">
    <input type="range" class="topcoat-range" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-range {
    +  border-radius: 6px;
    +  border: 1px solid #303233;
    +  background-color: #424546;
    +  height: 1rem;
    +  border-radius: 30px;
    +}
    +
    +.topcoat-range::-moz-range-track {
    +  border-radius: 6px;
    +  border: 1px solid #303233;
    +  background-color: #424546;
    +  height: 1rem;
    +  border-radius: 30px;
    +}
    +
    +.topcoat-range::-webkit-slider-thumb {
    +  height: 3rem;
    +  width: 2rem;
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 6px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-range::-moz-range-thumb {
    +  height: 3rem;
    +  width: 2rem;
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 6px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-range:focus::-webkit-slider-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-range:focus::-moz-range-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input,
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled,
    +.topcoat-search-input:disabled,
    +.topcoat-search-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input">
    <input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  line-height: 3rem;
    +  font-size: 16px;
    +  border: 1px solid #303233;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  padding: 0 0 0 2rem;
    +  border-radius: 30px;
    +  background-image: url("../img/search.svg");
    +  background-position: 1em center;
    +  background-repeat: no-repeat;
    +  background-size: 16px;
    +}
    +
    +.topcoat-search-input:focus,
    +.topcoat-search-input--large:focus {
    +  background-image: url("../img/search_dark.svg");
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-search-input::-webkit-search-cancel-button,
    +.topcoat-search-input::-webkit-search-decoration,
    +.topcoat-search-input--large::-webkit-search-cancel-button,
    +.topcoat-search-input--large::-webkit-search-decoration {
    +  margin-right: 5px;
    +}
    +
    +.topcoat-search-input:focus::-webkit-input-placeholder,
    +.topcoat-search-input:focus::-webkit-input-placeholder {
    +  color: #c6c8c8;
    +}
    +
    +.topcoat-search-input:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large">
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input--large {
    +  line-height: 4.375rem;
    +  font-size: 1.3rem;
    +  font-weight: 200;
    +  padding: 0 0 0 2.9rem;
    +  border-radius: 40px;
    +  background-position: 1.2em center;
    +  background-size: 1.3rem;
    +}
    +
    +.topcoat-search-input--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch,
    +.topcoat-switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input,
    +.topcoat-switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle,
    +.topcoat-switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after,
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Switch

    +
    +




    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input">
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" checked>
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" disabled>
      <div class="topcoat-switch__toggle"></div>
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-switch {
    +  font-size: 16px;
    +  padding: 0 1.25rem;
    +  border-radius: 6px;
    +  border: 1px solid #303233;
    +  overflow: hidden;
    +  width: 6rem;
    +}
    +
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  top: -1px;
    +  width: 5rem;
    +}
    +
    +.topcoat-switch__toggle:before {
    +  content: 'ON';
    +  color: #5dc1ff;
    +  background-color: #404141;
    +  right: 1rem;
    +  padding-left: 1.5rem;
    +}
    +
    +.topcoat-switch__toggle {
    +  line-height: 3rem;
    +  height: 3rem;
    +  width: 2rem;
    +  border-radius: 6px;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  margin-left: -1.3rem;
    +  margin-bottom: -1px;
    +  margin-top: -1px;
    +  box-shadow: inset 0 1px #727373;
    +  -webkit-transition: margin-left 0.05s ease-in-out;
    +  transition: margin-left 0.05s ease-in-out;
    +}
    +
    +.topcoat-switch__toggle:after {
    +  content: 'OFF';
    +  background-color: #404141;
    +  left: 1rem;
    +  padding-left: 2rem;
    +}
    +
    +.topcoat-switch__input:checked + .topcoat-switch__toggle {
    +  margin-left: 2.7rem;
    +}
    +
    +.topcoat-switch__input:focus + .topcoat-switch__toggle {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
    +  background: transparent;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-tab-bar__button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-tab-bar__button:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.button-bar,
    +.topcoat-tab-bar {
    +  display: table;
    +  table-layout: fixed;
    +  white-space: nowrap;
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +.button-bar__item,
    +.topcoat-tab-bar__item {
    +  display: table-cell;
    +  width: auto;
    +  border-radius: 0;
    +}
    +
    +.button-bar__item > input,
    +.topcoat-tab-bar__item > input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.button-bar__item:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Tab Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-tab-bar">
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">One</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Two</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Three</button>
      </label>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-tab-bar__button {
    +  padding: 0 1.25rem;
    +  height: 3rem;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: top;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border-top: 1px solid #303233;
    +}
    +
    +.topcoat-tab-bar__button:active,
    +.topcoat-tab-bar__button--large:active,
    +:checked + .topcoat-tab-bar__button {
    +  color: #5dc1ff;
    +  background-color: #404141;
    +  box-shadow: inset 0 0 2px #313231;
    +}
    +
    +.topcoat-tab-bar__button:focus,
    +.topcoat-tab-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input,
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled,
    +.topcoat-text-input:disabled,
    +.topcoat-text-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Text input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input" placeholder="text" value="">
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  line-height: 3rem;
    +  font-size: 16px;
    +  letter-spacing: 1px;
    +  padding: 0 1.25rem;
    +  border: 1px solid #303233;
    +  border-radius: 6px;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  vertical-align: top;
    +}
    +
    +.topcoat-text-input:focus,
    +.topcoat-text-input--large:focus {
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-text-input:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Text Input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text">
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input--large {
    +  line-height: 4.375rem;
    +  font-size: 1.3rem;
    +}
    +
    +.topcoat-text-input--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea,
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled,
    +.topcoat-textarea:disabled,
    +.topcoat-textarea--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  padding: 2rem;
    +  font-size: 2.5rem;
    +  font-weight: 200;
    +  border-radius: 6px;
    +  line-height: 3rem;
    +  border: 1px solid #303233;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  letter-spacing: 1px;
    +}
    +
    +.topcoat-textarea:focus,
    +.topcoat-textarea--large:focus {
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-textarea:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea--large {
    +  font-size: 3rem;
    +  line-height: 4.375rem;
    +}
    +
    +.topcoat-textarea--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Regular.otf");
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Light.otf");
    +  font-weight: 200;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Semibold.otf");
    +  font-weight: 600;
    +}
    +
    +body {
    +  margin: 0;
    +  padding: 0;
    +  background: #4b4d4e;
    +  color: #000;
    +  font: 16px "Source Sans", helvetica, arial, sans-serif;
    +  font-weight: 200;
    +}
    +
    +:focus {
    +  outline-color: transparent;
    +  outline-style: none;
    +}
    +
    +.topcoat-icon--menu-stack {
    +  background: url("../img/hamburger_light.svg") no-repeat;
    +  background-size: cover;
    +}
    +
    +.quarter {
    +  width: 25%;
    +}
    +
    +.half {
    +  width: 50%;
    +}
    +
    +.three-quarters {
    +  width: 75%;
    +}
    +
    +.third {
    +  width: 33.333%;
    +}
    +
    +.two-thirds {
    +  width: 66.666%;
    +}
    +
    +.full {
    +  width: 100%;
    +}
    +
    +.left {
    +  text-align: left;
    +}
    +
    +.center {
    +  text-align: center;
    +}
    +
    +.right {
    +  text-align: right;
    +}
    +
    +.reset-ui {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/* This file should include color and image variables corresponding to the dark theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* Search Input */
    +
    +/* List */
    +
    +/* Checkbox */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Textarea */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* This file should include color and image variables corresponding to the light theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* List */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Range input */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Containers */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Text Area */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* Text Input */
    +
    +/* Radio input */
    +
    +/* Overlay */
    +
    +/* Textarea */
    +
    +/* Progress bar container */
    +
    +/* Progress bar progress */
    +
    +/* Search input */
    +
    +/* Switch */
    +
    +/* Notification */
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-light.html b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-light.html new file mode 100755 index 0000000..f67a519 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/demo/topcoat-mobile-light.html @@ -0,0 +1,3417 @@ + + + + + + Topcoat + + + + + + + +
    + +
    +
    +
    +
    +

    Topcoat

    +

    CSS for clean and fast web apps

    +
    + +
    +
    +
    +
    +
    +

    Button Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar > .topcoat-button-bar__item:first-child {
    +  border-top-left-radius: 6px;
    +  border-bottom-left-radius: 6px;
    +}
    +
    +.topcoat-button-bar > .topcoat-button-bar__item:last-child {
    +  border-top-right-radius: 6px;
    +  border-bottom-right-radius: 6px;
    +}
    +
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
    +  border-right: none;
    +}
    +
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
    +  border-left: none;
    +}
    +
    +.topcoat-button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.topcoat-button-bar__button:focus,
    +.topcoat-button-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button Bar

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar__button--large {
    +  border-radius: inherit;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-button:disabled,
    +.topcoat-button--quiet:disabled,
    +.topcoat-button--large:disabled,
    +.topcoat-button--large--quiet:disabled,
    +.topcoat-button--cta:disabled,
    +.topcoat-button--large--cta:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Button

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button">Button</button>
    <button class="topcoat-button" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  padding: 0 1.25rem;
    +  font-size: 16px;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: top;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 6px;
    +}
    +
    +.topcoat-button:hover,
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large:hover,
    +.topcoat-button--large--quiet:hover {
    +  background-color: #edf1f1;
    +}
    +
    +.topcoat-button:active,
    +.topcoat-button--large:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +.topcoat-button:focus,
    +.topcoat-button--quiet:focus,
    +.topcoat-button--large:focus,
    +.topcoat-button--large--quiet:focus,
    +.topcoat-button--cta:focus,
    +.topcoat-button--large--cta:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--quiet">Button</button>
    <button class="topcoat-button--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large--quiet:hover {
    +  text-shadow: 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-button--quiet:active,
    +.topcoat-button--large--quiet:active {
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #d3d7d7;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large" >Button</button>
    <button class="topcoat-button--large" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large,
    +.topcoat-button--large--quiet {
    +  font-size: 1.3rem;
    +  font-weight: 400;
    +  line-height: 4.375rem;
    +  padding: 0 1.25rem;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--quiet" >Button</button>
    <button class="topcoat-button--large--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--cta" >Button</button>
    <button class="topcoat-button--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  border: 1px solid #143250;
    +  background-color: #288edf;
    +  box-shadow: inset 0 1px rgba(255,255,255,0.36);
    +  color: #fff;
    +  font-weight: 500;
    +  text-shadow: 0 -1px rgba(0,0,0,0.36);
    +}
    +
    +.topcoat-button--cta:hover,
    +.topcoat-button--large--cta:hover {
    +  background-color: #509bef;
    +}
    +
    +.topcoat-button--cta:active,
    +.topcoat-button--large--cta:active {
    +  background-color: #0380e8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--cta" >Button</button>
    <button class="topcoat-button--large--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--cta {
    +  font-size: 1.3rem;
    +  font-weight: 400;
    +  line-height: 4.375rem;
    +  padding: 0 1.25rem;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox,
    +.topcoat-checkbox__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label,
    +.topcoat-checkbox {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled,
    +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after,
    +.topcoat-checkbox__checkmark:before,
    +.topcoat-checkbox__checkmark:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before,
    +.topcoat-checkbox__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Checkbox

    +
    +


    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-checkbox">
      <input type="checkbox">
      <div class="topcoat-checkbox__checkmark"></div>
      Default
    </label>
    <br>
    <br>
    <label class="topcoat-checkbox">
      <input type="checkbox" disabled>
      <div class="topcoat-checkbox__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-checkbox__checkmark {
    +  height: 2rem;
    +}
    +
    +input[type="checkbox"] {
    +  height: 2rem;
    +  width: 2rem;
    +  margin-top: 0;
    +  margin-right: -2rem;
    +  margin-bottom: -2rem;
    +  margin-left: 0;
    +}
    +
    +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-checkbox {
    +  line-height: 2rem;
    +}
    +
    +.topcoat-checkbox__checkmark:before {
    +  width: 2rem;
    +  height: 2rem;
    +  background: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 3px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-checkbox__checkmark {
    +  width: 2rem;
    +  height: 2rem;
    +}
    +
    +.topcoat-checkbox__checkmark:after {
    +  top: 1px;
    +  left: 2px;
    +  opacity: 0;
    +  width: 28px;
    +  height: 11px;
    +  background: transparent;
    +  border: 7px solid #666;
    +  border-width: 7px;
    +  border-top: none;
    +  border-right: none;
    +  border-radius: 2px;
    +  -webkit-transform: rotate(-50deg);
    +  -ms-transform: rotate(-50deg);
    +  transform: rotate(-50deg);
    +}
    +
    +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-icon-button:disabled,
    +.topcoat-icon-button--quiet:disabled,
    +.topcoat-icon-button--large:disabled,
    +.topcoat-icon-button--large--quiet:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  padding: 0 0.75rem;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: baseline;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 6px;
    +}
    +
    +.topcoat-icon-button:hover,
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  background-color: #edf1f1;
    +}
    +
    +.topcoat-icon-button:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +.topcoat-icon-button:focus,
    +.topcoat-icon-button--quiet:focus,
    +.topcoat-icon-button--quiet:hover:focus,
    +.topcoat-icon-button--large:focus,
    +.topcoat-icon-button--large--quiet:focus,
    +.topcoat-icon-button--large--quiet:hover:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--quiet">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--quiet" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  text-shadow: 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-icon-button--quiet:active,
    +.topcoat-icon-button--large--quiet:active {
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #d3d7d7;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  width: 4.375rem;
    +  height: 4.375rem;
    +  line-height: 4.375rem;
    +}
    +
    +.topcoat-icon-button--large:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large--quiet">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large--quiet" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon,
    +.topcoat-icon--large {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  overflow: hidden;
    +  width: 1.62rem;
    +  height: 1.62rem;
    +  vertical-align: middle;
    +  top: -1px;
    +}
    +
    +.topcoat-icon--large {
    +  width: 2.499999998125rem;
    +  height: 2.499999998125rem;
    +  top: -2px;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header {
    +  margin: 0;
    +}
    +
    +.list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list,
    +.topcoat-list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header,
    +.topcoat-list__header {
    +  margin: 0;
    +}
    +
    +.list__container,
    +.topcoat-list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item,
    +.topcoat-list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    List

    +
    +

    Category

    • Item
    • Item
    • Item
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-list">
      <h3 class="topcoat-list__header">Category</h3>
      <ul class="topcoat-list__container">
        <li class="topcoat-list__item">
          Item
        </li>
        <li class="topcoat-list__item">
          Item
        </li>
        <li class="topcoat-list__item">
          Item
        </li>
      </ul>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-list {
    +  border-top: 1px solid #bcbfbf;
    +  border-bottom: 1px solid #eff1f1;
    +  background-color: #dfe2e2;
    +}
    +
    +.topcoat-list__header {
    +  padding: 4px 20px;
    +  font-size: 0.9em;
    +  font-weight: 400;
    +  background-color: #cccfcf;
    +  color: #656565;
    +  text-shadow: 0 1px 0 rgba(255,255,255,0.5);
    +  border-top: 1px solid rgba(255,255,255,0.5);
    +  border-bottom: 1px solid rgba(255,255,255,0.23);
    +}
    +
    +.topcoat-list__container {
    +  border-top: 1px solid #bcbfbf;
    +  color: #454545;
    +}
    +
    +.topcoat-list__item {
    +  padding: 1.25rem;
    +  border-top: 1px solid #eff1f1;
    +  border-bottom: 1px solid #bcbfbf;
    +}
    +
    +.topcoat-list__item:first-child {
    +  border-top: 1px solid rgba(0,0,0,0.05);
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar,
    +.topcoat-navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item,
    +.topcoat-navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title,
    +.topcoat-navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +
    +
    +
    +
    + +
    +
    +

    Notification

    +
    +
    1
    +
    + +
    +
    +

    HTML

    +
    <span class="topcoat-notification">1</span>
    +
    +
    +

    CSS

    +
    
    +.topcoat-notification {
    +  padding: 0.15em 0.5em 0.2em;
    +  border-radius: 2px;
    +  background-color: #ec514e;
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button,
    +.topcoat-radio-button__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label,
    +.topcoat-radio-button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:before,
    +.topcoat-radio-button__checkmark:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before,
    +.topcoat-radio-button__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled,
    +input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Radio Button

    +
    +






    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <!-- NO LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- LEFT LABEL -->
    <label class="topcoat-radio-button">
      Left label
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- RIGHT LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
      Right label
    </label>
    <br>
    <br>
    <!-- DISABLED -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat" Disabled>
      <div class="topcoat-radio-button__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +input[type="radio"] {
    +  height: 1.875rem;
    +  width: 1.875rem;
    +  margin-top: 0;
    +  margin-right: -1.875rem;
    +  margin-bottom: -1.875rem;
    +  margin-left: 0;
    +}
    +
    +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-radio-button {
    +  color: #454545;
    +  line-height: 1.875rem;
    +}
    +
    +.topcoat-radio-button__checkmark:before {
    +  width: 1.875rem;
    +  height: 1.875rem;
    +  background: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-radio-button__checkmark {
    +  position: relative;
    +  width: 1.875rem;
    +  height: 1.875rem;
    +}
    +
    +.topcoat-radio-button__checkmark:after {
    +  opacity: 0;
    +  width: 0.875rem;
    +  height: 0.875rem;
    +  background: #666;
    +  border: 1px solid rgba(0,0,0,0.1);
    +  box-shadow: 0 1px rgba(255,255,255,0.5);
    +  -webkit-transform: none;
    +  -ms-transform: none;
    +  transform: none;
    +  top: 7px;
    +  left: 7px;
    +}
    +
    +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range,
    +.topcoat-range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb,
    +.topcoat-range::-moz-range-thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit,
    +.topcoat-range::-webkit-slider-thumb {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled,
    +.topcoat-range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Range

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <input type="range" class="topcoat-range">
    <input type="range" class="topcoat-range" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-range {
    +  border-radius: 6px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  height: 1rem;
    +  border-radius: 30px;
    +}
    +
    +.topcoat-range::-moz-range-track {
    +  border-radius: 6px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  height: 1rem;
    +  border-radius: 30px;
    +}
    +
    +.topcoat-range::-webkit-slider-thumb {
    +  height: 3rem;
    +  width: 2rem;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 6px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-range::-moz-range-thumb {
    +  height: 3rem;
    +  width: 2rem;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 6px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-range:focus::-webkit-slider-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-range:focus::-moz-range-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input,
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled,
    +.topcoat-search-input:disabled,
    +.topcoat-search-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input">
    <input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  line-height: 3rem;
    +  font-size: 16px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  padding: 0 0 0 2rem;
    +  border-radius: 30px;
    +  background-image: url("../img/search.svg");
    +  background-position: 1em center;
    +  background-repeat: no-repeat;
    +  background-size: 16px;
    +}
    +
    +.topcoat-search-input:focus,
    +.topcoat-search-input--large:focus {
    +  background-image: url("../img/search_dark.svg");
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-search-input::-webkit-search-cancel-button,
    +.topcoat-search-input::-webkit-search-decoration,
    +.topcoat-search-input--large::-webkit-search-cancel-button,
    +.topcoat-search-input--large::-webkit-search-decoration {
    +  margin-right: 5px;
    +}
    +
    +.topcoat-search-input:focus::-webkit-input-placeholder,
    +.topcoat-search-input:focus::-webkit-input-placeholder {
    +  color: #c6c8c8;
    +}
    +
    +.topcoat-search-input:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large">
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input--large {
    +  line-height: 4.375rem;
    +  font-size: 1.3rem;
    +  font-weight: 200;
    +  padding: 0 0 0 2.9rem;
    +  border-radius: 40px;
    +  background-position: 1.2em center;
    +  background-size: 1.3rem;
    +}
    +
    +.topcoat-search-input--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch,
    +.topcoat-switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input,
    +.topcoat-switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle,
    +.topcoat-switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after,
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Switch

    +
    +




    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input">
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" checked>
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" disabled>
      <div class="topcoat-switch__toggle"></div>
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-switch {
    +  font-size: 16px;
    +  padding: 0 1.25rem;
    +  border-radius: 6px;
    +  border: 1px solid #a5a8a8;
    +  overflow: hidden;
    +  width: 6rem;
    +}
    +
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  top: -1px;
    +  width: 5rem;
    +}
    +
    +.topcoat-switch__toggle:before {
    +  content: 'ON';
    +  color: #0083e8;
    +  background-color: #e0f0fa;
    +  right: 1rem;
    +  padding-left: 1.5rem;
    +}
    +
    +.topcoat-switch__toggle {
    +  line-height: 3rem;
    +  height: 3rem;
    +  width: 2rem;
    +  border-radius: 6px;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  margin-left: -1.3rem;
    +  margin-bottom: -1px;
    +  margin-top: -1px;
    +  box-shadow: inset 0 1px #fff;
    +  -webkit-transition: margin-left 0.05s ease-in-out;
    +  transition: margin-left 0.05s ease-in-out;
    +}
    +
    +.topcoat-switch__toggle:after {
    +  content: 'OFF';
    +  background-color: #d3d7d7;
    +  left: 1rem;
    +  padding-left: 2rem;
    +}
    +
    +.topcoat-switch__input:checked + .topcoat-switch__toggle {
    +  margin-left: 2.7rem;
    +}
    +
    +.topcoat-switch__input:focus + .topcoat-switch__toggle {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
    +  background: transparent;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-tab-bar__button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-tab-bar__button:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.button-bar,
    +.topcoat-tab-bar {
    +  display: table;
    +  table-layout: fixed;
    +  white-space: nowrap;
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +.button-bar__item,
    +.topcoat-tab-bar__item {
    +  display: table-cell;
    +  width: auto;
    +  border-radius: 0;
    +}
    +
    +.button-bar__item > input,
    +.topcoat-tab-bar__item > input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.button-bar__item:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Tab Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-tab-bar">
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">One</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Two</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Three</button>
      </label>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-tab-bar__button {
    +  padding: 0 1.25rem;
    +  height: 3rem;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: top;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border-top: 1px solid #a5a8a8;
    +}
    +
    +.topcoat-tab-bar__button:active,
    +.topcoat-tab-bar__button--large:active,
    +:checked + .topcoat-tab-bar__button {
    +  color: #0083e8;
    +  background-color: #e0f0fa;
    +  box-shadow: inset 0 0 2px #c0ced8;
    +}
    +
    +.topcoat-tab-bar__button:focus,
    +.topcoat-tab-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input,
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled,
    +.topcoat-text-input:disabled,
    +.topcoat-text-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Text input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input" placeholder="text" value="">
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  line-height: 3rem;
    +  font-size: 16px;
    +  letter-spacing: 1px;
    +  padding: 0 1.25rem;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 6px;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  vertical-align: top;
    +}
    +
    +.topcoat-text-input:focus,
    +.topcoat-text-input--large:focus {
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-text-input:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Text Input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text">
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input--large {
    +  line-height: 4.375rem;
    +  font-size: 1.3rem;
    +}
    +
    +.topcoat-text-input--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea,
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled,
    +.topcoat-textarea:disabled,
    +.topcoat-textarea--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  padding: 2rem;
    +  font-size: 2.5rem;
    +  font-weight: 200;
    +  border-radius: 6px;
    +  line-height: 3rem;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  letter-spacing: 1px;
    +}
    +
    +.topcoat-textarea:focus,
    +.topcoat-textarea--large:focus {
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-textarea:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea--large {
    +  font-size: 3rem;
    +  line-height: 4.375rem;
    +}
    +
    +.topcoat-textarea--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Regular.otf");
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Light.otf");
    +  font-weight: 200;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Semibold.otf");
    +  font-weight: 600;
    +}
    +
    +body {
    +  margin: 0;
    +  padding: 0;
    +  background: #dfe2e2;
    +  color: #000;
    +  font: 16px "Source Sans", helvetica, arial, sans-serif;
    +  font-weight: 200;
    +}
    +
    +:focus {
    +  outline-color: transparent;
    +  outline-style: none;
    +}
    +
    +.topcoat-icon--menu-stack {
    +  background: url("../img/hamburger_dark.svg") no-repeat;
    +  background-size: cover;
    +}
    +
    +.quarter {
    +  width: 25%;
    +}
    +
    +.half {
    +  width: 50%;
    +}
    +
    +.three-quarters {
    +  width: 75%;
    +}
    +
    +.third {
    +  width: 33.333%;
    +}
    +
    +.two-thirds {
    +  width: 66.666%;
    +}
    +
    +.full {
    +  width: 100%;
    +}
    +
    +.left {
    +  text-align: left;
    +}
    +
    +.center {
    +  text-align: center;
    +}
    +
    +.right {
    +  text-align: right;
    +}
    +
    +.reset-ui {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/* This file should include color and image variables corresponding to the dark theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* Search Input */
    +
    +/* List */
    +
    +/* Checkbox */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Textarea */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* This file should include color and image variables corresponding to the light theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* List */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Range input */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Containers */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Text Area */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* Text Input */
    +
    +/* Radio input */
    +
    +/* Overlay */
    +
    +/* Textarea */
    +
    +/* Progress bar container */
    +
    +/* Progress bar progress */
    +
    +/* Search input */
    +
    +/* Switch */
    +
    +/* Notification */
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/build/styleguide.css b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/build/styleguide.css new file mode 100755 index 0000000..bcbf2a8 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/build/styleguide.css @@ -0,0 +1,495 @@ +/*! +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +/* Styleguide CSS here pls ------------------------------------------------------------------------------- */ + +html { + height: 100%; + width: 100%; + position: absolute; +} + +body { + color: #444; + font: 14px "source-sans-pro", "source", helvetica, arial, sans-serif; + line-height: 21px; + margin: 0; + padding: 0; + -webkit-font-smoothing: subpixel-antialiased; +} + +.guides { +/* border: 1px solid red;*/ +} + +.space { + height: 90px; +} + +#container { + min-width: 600px; +} + +#test-container { + padding: 0 120px 30px 30px ; +} + +h1,h2,h3,h4,h5,h6 { + color: #000; + font-family: "source-l", helvetica, arial, sans-serif; + font-weight: normal; + margin: 0; +} + +h4 { + border-bottom: 1px solid #d7d7d7; + font-size: 30px; + margin: 20px 0; +} + +h5 { + font-size: 21px; +} + +h4 span { + background: #fff; + padding: 0 7px 0 0; + position: relative; + bottom: -10px; +} + +.tabular { + border: 1px solid rgba(0,0,0,0.09); + border-spacing: 0; + margin: 14px 0; +} + +th, td, .tabular td.var { + border-bottom: 1px solid #eee; + font-size: 15px; + font-weight: normal; + padding: 5px 10px; + text-align: left; +} + +th { + white-space: nowrap; +} + +.tabular tr:last-child td { + border: none; +} + +.tabular td { + font-size: 12px; + padding: 10px; +} + +.images { + width: 100% !important; +} + +.images td, +.images th { + border-right: 1px solid #eee !important; + padding: 18px; + text-align: center; + vertical-align: top; +} + +.images th { + padding: 9px; +} + +.images tr:last-child td, +.images tr th:last-child { + border-right: none !important; +} + +.images img { + width: 300px; +} + +header { + background: #3a3f42 url("../img/bg_dark.png") repeat-x; + bottom: 0; + cursor: default; + left: 0; + overflow-y: scroll; + padding: 0 0 30px 0; + position: absolute; + top: 0; + width: 220px; +} + +#main { + bottom: 0; + left: 220px; + margin: 0; + overflow-y: scroll; + padding: 0 100px 60px 40px; + position: absolute; + right: 0; + top: 0; +} + +header hgroup { + padding: 15px; +} + +header hgroup { + border-bottom: 1px solid rgba(0,0,0,0.36); + box-shadow: 0px 1px 0px rgba(255,255,255,0.11); +} + +header h1 { + color: #fff; + font-size: 18px; + text-shadow: 0 -1px 0 #000; +} + +header h2 { + color: #c7c7c7; + font-size: 12px; + text-shadow: 0 -1px 0 #000; +} + +header h3 { + color: #A4B4B7; + font-size: 14px; + text-shadow: 0 -1px 0 #000; + margin: 15px 0 5px 15px; +} + +header ul { + list-style: none; + margin: 0; + padding: 0; + width: 100%; +} + +header a { + box-sizing: border-box; + border-top: 1px solid rgba(0,0,0,0); + border-bottom: 1px solid rgba(0,0,0,0); + color: #bbb; + display: block; + font-size: 14px; + height: 24px; + line-height: 24px; + padding: 0 15px 0 30px; + text-shadow: 0 1px 0 #000; +} + +header a:link, +header a:visited { + color: #c7c7c7; + text-decoration: none; +} + +header .selected { + background: rgba(112,112,112,0.24); + border-top: 1px solid rgba(0,0,0,0); + border-bottom: 1px solid rgba(0,0,0,0); + color: #fff !important; +} + + +header a:hover { + background: rgba(112,112,112,0.24); + border-top: 1px solid rgba(0,0,0,0); + border-bottom: 1px solid rgba(0,0,0,0); + color: #fff !important; +} + +header a:focus { + border: 1px solid #0940fd; + -webkit-box-shadow: 0 0 4px #0088ff; + box-shadow: 0 0 4px #0088ff; + outline: none; + margin-left: 4px; + margin-right: 4px; + padding: 0 10px 0 25px; + background: rgba(112,112,112,0.24); + color: #fff !important; +} + +header a:active { + background: rgba(0,0,0,0.24); + border-top: 1px solid rgba(0,0,0,0.2); + border-bottom: 1px solid rgba(255,255,255,0.15); + color: #fff; +} + +h4:target span { + -webkit-animation: highlight 5s ease; + -moz-animation: highlight 5s ease; +} + + @-webkit-keyframes highlight { + 0% { color: #0083E8; text-shadow: 0 0 4px rgba(0,136,255,.69); } + 100% { color: #000; text-shadow: none; } + } + +.preview { + border-spacing: 0; + width: auto; +} + +.preview td { + padding: 15px 30px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.bg-light { + background: #f8f8f8; + border: 1px solid rgba(0,0,0,0.09); + font-size: 12px; +} + +.fonts.tabular { + width: 100%; +} + +.fonts.tabular th.bg-white { + border-bottom: 1px solid rgba(0,0,0,0.09); +} + +.fonts.tabular th.bg-lightgray { + border-bottom: 1px solid #bdbdbd; +} + +.fonts.tabular th.bg-slategray { + border-bottom: 1px solid #5c6061; +} + +.fonts.tabular td { + vertical-align: top; + width: 33%; +} + + +/* Selection ------------------------------------------------------------------------------- */ + +::selection { + background: #e0f0fa; + color: #000; +} + +header { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +/* Scrollbars ------------------------------------------------------------------------------- */ + +::-webkit-scrollbar { + height: 8px; + width: 8px; +} + +::-webkit-scrollbar-track { + background: rgba(0,0,0,0.1); + box-shadow: inset 0 0 6px rgba(0,0,0,0); + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0); + border-radius: 4px; + -webkit-border-radius: 4px; +} + +::-webkit-scrollbar-thumb { + border-radius: 4px; + -webkit-border-radius: 4px; + border: 1px solid rgba(255,255,255,0.15); + background: rgba(0,0,0,0.3); + box-shadow: inset 0 0 6px rgba(0,0,0,0); + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0); +} + +::-webkit-scrollbar-thumb:window-inactive { + background: rgba(0,0,0,0.1); +} + + +/* Scrollbars ------------------------------------------------------------------------------- */ + + +/* Container */ +.modal { + /* Overlay page content */ + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0,0,0,0.6); + z-index: 10000; + + /* Transition opacity on open */ + -webkit-transition: opacity 200ms ease-in; + transition: opacity 200ms ease-in; + + /* Hide for now */ + opacity: 0; + pointer-events: none; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +/* Show modal */ +.modal:target { + opacity: 1; + pointer-events: auto; +} + +/* Hide modal */ +.modal:active { + opacity: 0; +} + +/* Content */ +.modal > div { + width: 65%; + background: #fff; + position: relative; + margin: 10% auto; + + /* Default minimise animation */ + -webkit-animation: minimise 500ms linear; + + /* Prettify */ + padding: 12px 15px; + border-radius: 4px; + box-shadow: 0 15px 36px rgba(0,0,0,0.6); + background: #fff; + text-shadow: 0 1px 0 #fff; +} + +/* Override animation on modal open */ +.modal:target > div { + -webkit-animation-name: bounce; + -moz-animation-name: bounce; +} + +.modal h1 { + font-size: 24px; + padding: 0 0 10px; +} + +@-webkit-keyframes bounce { + 0% { + -webkit-transform: scale3d(1,1,1); + } + 55% { + -webkit-transform: scale3d(1,1,1); + } + 100% { + -webkit-transform: scale3d(1,1,1); + } +/* 0% { + -webkit-transform: scale3d(0.1,0.1,1); + box-shadow: 0 3px 20px rgba(0,0,0,0.9); + } + 55% { + -webkit-transform: scale3d(1,1,1); + box-shadow: 0 10px 20px rgba(0,0,0,0); + } + 75% { + -webkit-transform: scale3d(0.95,0.95,1); + box-shadow: 0 0 20px rgba(0,0,0,0.9); + } + 100% { + -webkit-transform: scale3d(1,1,1); + box-shadow: 0 3px 20px rgba(0,0,0,0.9); + } +*/ +} + +@-webkit-keyframes minimise { + 0% { + -webkit-transform: scale3d(1,1,1); + } + 100% { + -webkit-transform: scale3d(0.1,0.1,1); + } +} + +/* Modal close link */ +.modal a[href="#close"] { + position: absolute; + right: 0; + top: 0; + color: transparent; +} + +/* Reset native styles */ + .modal a[href="#close"]:focus { + outline: none; +} + +/* Create close button */ +.modal a[href="#close"]:after { + content: url("../img/close_modal.png"); + display: block; + + /* Position */ + position: absolute; + right: 15px; + top: 15px; + + /* Style */ + font-size: 12px; + text-decoration: none; + text-shadow: none; + text-align: center; + font-weight: bold; + background: #fff; +} + +.modal a[href="#close"]:focus:after, +.modal a[href="#close"]:hover:after { + +} + +.modal a[href="#close"]:focus:after { + outline: 1px solid #000; +} + +.modal a[href="#close"] { + text-shadow: none !important; +} + +/* Open modal */ +a.openmodal { + display: block; + text-align: center; +} + +a.openmodal:hover, +a.openmodal:focus { + +} \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/build/styleguide.js b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/build/styleguide.js new file mode 100755 index 0000000..67f89bf --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/build/styleguide.js @@ -0,0 +1,10 @@ +if (!document.querySelector('override')) { + var head = document.querySelector('head'); + var link = document.createElement('link'); + link.id = 'override'; + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = '../../release/css/' + location.href.split('/').pop().split('.')[0] + '.css'; + link.media = 'all'; + head.appendChild(link); +} \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/tasks/checkchromiumsrc.js b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/tasks/checkchromiumsrc.js new file mode 100755 index 0000000..6c472dd --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/tasks/checkchromiumsrc.js @@ -0,0 +1,13 @@ +var chromiumSrc = process.env.CHROMIUM_SRC; + +module.exports = function(grunt) { + + grunt.registerTask('check_chromium_src', "Internal task to store CHROMIUM_SRC env var into chromiumSrc", function() { + if (!chromiumSrc) { + grunt.fail.warn("Please set the CHROMIUM_SRC env var to the root of your chromium sources(ends in /src)"); + } else { + grunt.log.writeln("CHROMIUM_SRC points to " + chromiumSrc.cyan); + } + }); + +} diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrygentest.js b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrygentest.js new file mode 100755 index 0000000..2b0bb0c --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrygentest.js @@ -0,0 +1,98 @@ +var fs = require("fs"), + jade = require("jade"), + path = require("path"); + +module.exports = function (grunt) { + + var TELEMETRY_DIR = 'dev/test/perf/telemetry/perf/page_sets/', + MASTER_JADE = 'topcoat_telemetry.jade'; + + grunt.registerTask('perf', 'Generates performance test', function (platform, theme) { + + var perfJades = findAllPerfJadeFileInSrc(); + + var targetPlatform = platform || 'mobile', + targetTheme = theme || 'light'; + + var targetCSS = prepareCSS(targetPlatform, targetTheme); + + var jadeCompileData = {}; + + grunt.util._.forEach(perfJades, function (jadePath) { + + var jadeFileName = path.basename(jadePath).split('.')[0]; + + prepareJadeCompileData(jadeCompileData, jadePath, + jadeFileName, targetPlatform, targetTheme, targetCSS); + + createTelemetryJSON(jadeFileName); + }); + batchCompileJade(jadeCompileData); + }); + + var findAllPerfJadeFileInSrc = function () { + + var jades = grunt.file.expand('node_modules/topcoat-*/test/perf/topcoat_*.jade') + .concat('node_modules/topcoat-checkbox/test/perf/checkbox-test.jade'); + + if (jades.length === 0){ + throw new Error("ERROR: No jade file is found in src/../test/perf/"); + } + + return jades; + }; + + var prepareCSS = function(platform, theme) { + + return "release/css/topcoat-" + platform + "-" + theme + ".min.css"; + }; + + var prepareJadeCompileData = function (jadeCompileData, jadePath, + caseName, platform, theme, css) { + + var jadeContent = fs.readFileSync(jadePath, "utf8"), + getHtml = jade.compile(jadeContent); + + jadeCompileData[caseName] = { + options: { + data: { + platform: platform, + theme: theme, + css: css, + name: caseName, + componentHTML: getHtml() + } + }, + src: TELEMETRY_DIR + "topcoat/" + MASTER_JADE, + dest: TELEMETRY_DIR + "topcoat/" + caseName + ".test.html" + }; + }; + + var createTelemetryJSON = function (caseName) { + + var jsonContent = { + "description": "Test", + "archive_data_file": "../data/topcoat_buttons.json", + "pages": [ + { + "url": "file:///topcoat/" + caseName + ".test.html", + "smoothness": { + "action": "scrolling_action" + } + } + ] + }; + + var jsonFilePATH = TELEMETRY_DIR + caseName + '.test.json'; + + fs.writeFileSync( + jsonFilePATH, + JSON.stringify(jsonContent, null, 4), + 'utf8'); + }; + + var batchCompileJade = function(data){ + grunt.config('jade', data); + grunt.task.run('jade'); + }; +}; diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrysubmit.js b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrysubmit.js new file mode 100755 index 0000000..f9f6fb2 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/tasks/telemetrysubmit.js @@ -0,0 +1,101 @@ +module.exports = function(grunt) { + + grunt.registerTask('telemetry-submit', 'Submit telemetry test results', function(gitCWD) { + + var exec = require("child_process").exec, + commandToBeExecuted = 'git log --pretty=format:"%H %ci" | head -n 1', + done = this.async(); + + var part1 = { + properties: { + path: { + message: 'Path to telemetry output file', + required: true + }, + device: { + message: 'Device on which the test ran', + required: true + } + } + }; + + var part2 = { + properties: { + test: { + message: 'What is the name of the test?', + required: true, + default: '' + }, + type: { + message: 'Is it a test (nightly) ?', + required: true, + default: 'Yes' + } + } + }; + + exec(commandToBeExecuted, { cwd: gitCWD }, function(error, stdout, stderr) { + if (error) { + grunt.log.error('Error'); + console.log(error); + done(); + } else { + + var path = grunt.option('path') + , device = grunt.option('device') + , test = grunt.option('test') + // use env variables to overwrite the location + // where the test results end up, for CI example + , host = process.env.TOPCOAT_BENCHMARK_SERVER + , port = process.env.TOPCOAT_BENCHMARK_PORT + , type = grunt.option('type') + , date = grunt.option('date') + , snapshot + , submitData = require('../test/perf/telemetry/lib/submitData') + , fileName = require('../test/perf/telemetry/lib/extractFileName') + , prompt = require('prompt') + ; + + if (!path || !test || !device) { + // Dummy test to see if it was called without arguments + // in this case we request the user for data + + prompt.start(); + prompt.get(part1, function (err, result) { + var options = result; + + part2.properties.test.default = fileName(result.path); + + prompt.get(part2, function (err, result) { + for (var i in result) + options[i] = result[i]; + + if (options.type.match(/y/gi)) + options.date = 'snapshot ' + new Date().toISOString(); + else + options.date = stdout; + + submitData(options.date, options.path, { + device: options.device, + test: options.test + }, { + host : host, + port : port + }); + }); + }); + } else { + // This is in case for automated tasks that submits the data + submitData(stdout, path, { + device: device, + test: test + }, { + host : host, + port : port + }); + } + } + }); + + }); +}; \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/README.md b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/README.md new file mode 100755 index 0000000..0fc795e --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/README.md @@ -0,0 +1,79 @@ +Performance tests based on chromium telemetry (see https://github.com/topcoat/topcoat/wiki/Measuring-performance for details) + +# Preparing to run the tests +A few steps are required before you can run the telemetry tests. + +First of all, you need to download chromium source code locally, as described on http://www.chromium.org/developers/how-tos/get-the-code. No need to compile, just download it. +Then export the location for the 'src' folder in the CHROMIUM_SRC environment variable, like in +``` +export CHROMIUM_SRC = /Users/cataling/work/chromium/home/src_tarball/tarball/chromium/src/ +``` + +Then you need to manually patch a little bit two of the benchmark files (the patches are just one liners, it they get bigger we'll just duplicate the benchmarks in topcoat). Locate the files named `loading_benchmark.py` and `smoothness_benchmark.py` in `$CHROMIUM_SRC/tools/perf/perf_tools`. Inside, look for the method `MeasurePage`, and find an appropriate place to paste `results.Add("UserAgent", "", tab.EvaluateJavaScript("navigator.userAgent"));`. This makes the benchmarks include the user agent string as part of their output, and we need this info to submit the results to the server. + +NOTE: we should make a patch for these modifications + +Next you can prepare the telemetry tests: +``` +grunt telemetry +``` +This does few things: +* it generates html snippets based on grunt template from test/perf/topcoat-*.test.jade of each of Topcoat component. So make sure you build Topcoat first, by ```grunt default```, so that Topcoat components are downloaded into the src folder; +* then it uses that html snippet to generate the actual test file from topcoat/test/perf /telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade; +* last, it copies those test files to the right location in chromium telemetry tests. + +# Running performance tests locally +You can run a telemetry test with: +``` +cd $CHROMIUM_SRC/tools/perf +./run_multipage_benchmarks --browser=system loading_benchmark page_sets/topcoat_buttons-base.test.json -o /tmp/loading_benchmark_topcoat_buttons-base.txt +./run_multipage_benchmarks --browser=system smoothness_benchmark page_sets/topcoat_buttons-base.test.json -o /tmp/smoothness_benchmark_topcoat_buttons-base.txt +``` +We store the benchmark output in a file - the next script will take this output and push it to the server + +For steps of running performance tests on Android: +https://github.com/topcoat/topcoat/wiki/Running-TopCoat-Performance-Test-on-Android + +# Pushing benchmark results to the server + +There is a grunt task that automates the process `$ grunt telemetry-submit --path=test_results.txt --type=sha|snapshot [--device] [--test]` + +Device is an optional parameter and sets the device on which the test ran. +For `type snapshot` you have to send in a date param as well. You have to use: `date -u +"%Y-%m-%dT%H:%M:%SZ"` + +Type is either `sha` or `snapshot`. + + * `sha` is for running the tests on a stable version (in black) + * `snapshot` is for running custom nightly builds of topcoat (in red) + * ![x axis perf view](http://i.imgur.com/DrKxFlI.png) + +Test is an optional parameter and it overrides the default test name ( which is the name of the file from path ). + +There is a `settings.js` file located under `/test/perf/telemetry/lib/` where you can change the address where to submit. It is currently set for http://bench.topcoat.io/v2/benchmark + +If you set an `TOPCOAT_BENCHMARK_SERVER` and `TOPCOAT_BENCHMARK_PORT` env variables you can override the default settings. + +You can view the results at http://bench.topcoat.io + +# Running all tests +There's also a handy script to run all the performance tests and push the results on the server. +It's located at `https://github.com/topcoat/topcoat/blob/master/test/perf/telemetry/bin/runAll.py`. +Check out the script for details on how to run it. + +# Adding a new performance test +Before adding new tests, you should make yourself comfortable with the chromium telemetry framework and running telemetry tests in chrome. + +Topcoat performance tests are located in `test/perf/telemetry/perf/page_sets` (the folder convention matches the one from chromium telemetry tests). When building telemetry with `grunt telemetry` this folder is copied over `page_sets` in chromium src. There is one .json file that describes each test, its structure is as required by chromium telemetry framework. You will need to add a new json file to describe your test - just start from an existing ones. + +The files for the tests are located under the `topcoat` folder. You can either add html file directly, or use jade. Jade files are converted to html when you run `grunt telemetry`. The html files will be generated under `page_sets` in chromium src. Currently, if you're adding a jade file you need to manually add it to `Gruntfile.js` (just look up where topcoat_buttons.jade is added). If future we'll get rid of this. + +Inside the test files (html or jade) you can reference the topcoat assets (css, fonts, images) under "./release/". The whole `./release` folder under topcoat root and all the components are copied there by `grunt telemetry`. + +In the json file you can reference the test file to load using `file:///topcoat/` URLs. Use .html here even if you use .jade for tests - you want to reference the generated html file, not the jade template. When running the tests, telemetry will instantiate a local HTTP server and rewrite the URLs, they will not be loaded with the file protocol. + +From telemetry we're currently using loading and smoothness benchmarks. The runAll.sh script currently runs these two benchmarks on all the .json tests under page_sets. + +Note 1: runAll.py uses CEF ([chromium embedding framework](https://code.google.com/p/chromiumembedded/)) to run the tests on desktop (Win and Mac) by default. This is because the target for TopCoat are web applications, not web sites, and CEF is the preferred way to develop web applications on desktop. +We're currently using a custom CEF build because telemetry does not work in CEF by default. A patch has been submitted to CEF upstream (https://code.google.com/p/chromiumembedded/issues/detail?id=917&sort=-id) to fix this. + +Note 2: part of this will probably change when we switch to the new components/themes architecture. diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.py b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.py new file mode 100755 index 0000000..3dd8aba --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.py @@ -0,0 +1,200 @@ +# Copyright 2012 Adobe Systems Inc.; +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Runs all the telemetry tests and pushes results to the server +# +# Make sure to run in from its folder! +# +# Env vars used: +# - TestHelper.CHROMIUM_SRC: path to chromium src +# - DEVICE_NAME: a label to identify the machine running the tests when submitting results +# - CEF_HOME: path to CEF binaries (needed only if USE_CEF is set to True) +# - USE_CEF: if run with CEF, set this to 'True' +# + +import os +import sys +import shutil +import subprocess +import glob +import platform +import shutil + + +class TestHelper(): + GRUNT = "grunt" + RESULTS_DIR = "/tmp/topcoat-telemetry" + BROWSER = "system" + BROWSER_EXEC = None + SUBMIT_TYPE = "SHA" + + CHROMIUM_SRC = os.environ.get("CHROMIUM_SRC") + DEVICE_NAME = os.environ.get("DEVICE_NAME") + CEF_HOME = os.environ.get("CEF_HOME") + USE_CEF = os.environ.get("USE_CEF") + + @staticmethod + def init(targetPlatform, targetTheme): + TestHelper._checkEnvVars() + TestHelper._prepareProperties() + TestHelper._prepareResultsDir() + TestHelper._cleanTelemetryTests() + TestHelper._prepareTelemetryTests(targetPlatform, targetTheme) + + @staticmethod + def _getPlatform(): + p = platform.platform().lower() + if p.find('windows') != -1: return "Win" + if p.find('darwin') != -1: return "Mac" + if p.find('linux') != -1: return "Lin" + + @staticmethod + def _checkEnvVars(): + if not TestHelper.DEVICE_NAME: + raise RuntimeError("Please set DEVICE_NAME env var (no spaces allowed yet)") + + if not TestHelper.CHROMIUM_SRC: + raise RuntimeError("Please set CHROMIUM_SRC env var.") + + if not TestHelper.USE_CEF: + raise RuntimeError("Please set USE_CEF env var.") + + if (TestHelper.USE_CEF == 'True') and (not TestHelper.CEF_HOME): + raise RuntimeError("Please set CEF_HOME if you set USE_CEF to True") + + @staticmethod + def _prepareProperties(): + p = TestHelper._getPlatform() + + if p == "Win": + TestHelper.GRUNT = "grunt.cmd" + TestHelper.RESULTS_DIR = "C:\\tmp\\topcoat-telemetry" + TestHelper.BROWSER = "exact" + TestHelper.BROWSER_EXEC = "%s\\app\\cefclient.exe" % TestHelper.CEF_HOME + + if p == "Mac": + if TestHelper.USE_CEF: + TestHelper.BROWSER = "exact" + TestHelper.BROWSER_EXEC = "%s/app/cefclient.app/Contents/MacOS/cefclient" % TestHelper.CEF_HOME + + if p == "Lin": + TestHelper.BROWSER = "android-chrome-beta" + + @staticmethod + def _prepareResultsDir(): + print "runAll.py: Preparing results dir %s" % TestHelper.RESULTS_DIR + if os.path.isdir(TestHelper.RESULTS_DIR): + shutil.rmtree(TestHelper.RESULTS_DIR) + os.makedirs(TestHelper.RESULTS_DIR) + + @staticmethod + def _prepareTelemetryTests(targetPlatform, targetTheme): + print "runAll.py: Preparing telemetry tests" + subprocess.check_call([TestHelper.GRUNT, 'telemetry:'+targetPlatform+':'+targetTheme]) + + @staticmethod + def _cleanTelemetryTests(): + print "runAll.py: clean up CHROMIUM_SRC/tools/perf/page_sets/topcoat" + path = TestHelper.CHROMIUM_SRC + "tools/perf/page_sets/topcoat" + if os.path.exists(path): + shutil.rmtree(path) + + @staticmethod + def runTests(user_defined_test_list, how_many_rounds_to_run_the_test): + print "runAll.py: Running telemetry tests, results in %s" % TestHelper.RESULTS_DIR + + telemetry_tests = ["loading_benchmark", "smoothness_benchmark"] + + if user_defined_test_list and len(user_defined_test_list) != 0: + topcoat_test_files = user_defined_test_list + else: + topcoat_test_files = glob.glob(os.getcwd() + "/../perf/page_sets/*.json") + + def genCmd(): + cmd = [ + "python", + TestHelper.CHROMIUM_SRC + "/tools/perf/run_multipage_benchmarks", + "--browser=" + TestHelper.BROWSER, + telemetry_test, + TestHelper.CHROMIUM_SRC + "tools/perf/page_sets/%s" % topcoat_test_file, + "-o", TestHelper.RESULTS_DIR + "/%s_%s-%s.txt" % (telemetry_test, topcoat_test_name, test_round) + ] + if TestHelper.BROWSER_EXEC: + cmd.insert(3, "--browser-executable=" + TestHelper.BROWSER_EXEC) + return cmd + + for tf in topcoat_test_files: + topcoat_test_file = tf.split(os.sep)[-1] + topcoat_test_name = topcoat_test_file.split(".")[0] + print "runAll.py: Running tests for %s" % topcoat_test_name + + for telemetry_test in telemetry_tests: + for test_round in range(how_many_rounds_to_run_the_test): + cmd = genCmd() + subprocess.check_call(cmd) + + @staticmethod + def submitResults(git_cwd): + print "runAll.py: Pushing telemetry data to the server" + result_files = glob.glob(TestHelper.RESULTS_DIR + "/*.txt") + for rf in result_files: + subprocess.check_call([ + TestHelper.GRUNT, + "telemetry-submit:" + git_cwd, + "--path=" + rf, + "--device=" + TestHelper.DEVICE_NAME, + "--test=" + rf.split(os.sep)[-1][:-6], + "--type=" + TestHelper.SUBMIT_TYPE + ]) + + +if __name__ == "__main__": + + # Usage: + # ./python runAll.py --platform=VALUE --theme=VALUE [--gitCWD=VALUE] [--test=VALUE] [--round=VALUE] + # --platform= desktop or mobile + # --theme= light or dark + # [optional] --gitCWD=PATH_WHERE_YOU_WANT_TO_RUN_GIT_LOG, e.g. src/skins/button + # [optional] --test=ONE_OR_MORE_TESTS_YOU_WANT_TO_RUN, e.g. topcoat_button.test.json + # [optional] --test=HOW_MANY_ROUNDS_TO_RUN_THE_TEST, default is 1. + + platfrm = theme = git_cwd = test_list = None + test_round = 1 + + args = sys.argv[1:] + + for arg in args: + arg_key, arg_val = arg.split('=') + if arg_key == '--platform': + platfrm = arg_val + elif arg_key == '--theme': + theme = arg_val + elif arg_key == '--gitCWD': + git_cwd = arg_val + elif arg_key == '--test': + test_list = arg_val.split(',') + elif arg_key == '--round': + test_round = int(arg_val) + else: + print "%s is not recognized." + + if not platform or not theme: + raise RuntimeError("ERROR: --platform and --theme must be set.") + + if not git_cwd: + git_cwd = '' + + TestHelper.init(platfrm, theme) + TestHelper.runTests(test_list, test_round) + TestHelper.submitResults(git_cwd) \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.sh b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.sh new file mode 100755 index 0000000..aa088c0 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.sh @@ -0,0 +1,105 @@ +#!/bin/sh +# Copyright 2012 Adobe Systems Inc.; +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Runs all the telemetry tests and pushes results to the server +# +# Make sure to run in from its folder! +# +# Env vars used: +# - CHROMIUM_SRC: path to chromium src +# - DEVICE_NAME: a label to identify the machine running the tests when submitting results +# - CEF_HOME: path to CEF binaries (needed only if USE_CEF is set to True) +# + +RESULTS_DIR=/tmp/topcoat-telemetry +USE_CEF=true + +function checkEnvVars() { + if [ -z "$DEVICE_NAME" ] + then + echo "Please set DEVICE_NAME env var (no spaces allowed yet)" + exit 1 + fi + + if [ -z "$CHROMIUM_SRC" ] + then + echo "Please set CHROMIUM_SRC env var" + exit 1 + fi + + if ($USE_CEF) + then + if [ -z "$CEF_HOME" ] + then + echo "You need to set CEF_HOME if yout set USE_CEF to True" + exit 1 + fi + fi +} + +function prepareResultsDir() { + echo "runAll.sh: Preparing results dir $RESULTS_DIR" + rm -rf $RESULTS_DIR + mkdir $RESULTS_DIR +} + +function prepareTelemetryTests() { + echo "runAll.sh: Preparing telemetry tests" + grunt telemetry +} + +function runTests() { + echo "runAll.sh: Running telemetry tests, resuls in $RESULTS_DIR" + + if ($USE_CEF) + then + browserParams="--browser=exact --browser-executable=$CEF_HOME/app/cefclient.app/Contents/MacOS/cefclient" + else + browserParams="--browser=system" + fi + + testFiles=$(ls ../perf/page_sets/*.json); + + currentDir=`pwd` + cd $CHROMIUM_SRC/tools/perf + + for test in $testFiles + do + testFileBaseName=$(basename $test) #ends with .json + testName=$(echo $testFileBaseName | cut -d '.' -f 1) + echo "runAll.sh: Running tests for $testName" + ./run_multipage_benchmarks $browserParams loading_benchmark page_sets/$testFileBaseName -o $RESULTS_DIR/loading_benchmark_$testName.txt + ./run_multipage_benchmarks $browserParams smoothness_benchmark page_sets/$testFileBaseName -o $RESULTS_DIR/smoothness_benchmark_$testName.txt + done + + cd $currentDir +} + +function submitResults() { + echo "runAll.sh: Pushing telemetry data to the server" + + for resultFile in $RESULTS_DIR/* + do + grunt telemetry-submit --path=$resultFile --device $DEVICE_NAME + done +} + + +checkEnvVars +prepareResultsDir +prepareTelemetryTests +runTests +submitResults + diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/csvToJSON.js b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/csvToJSON.js new file mode 100755 index 0000000..b5d0594 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/csvToJSON.js @@ -0,0 +1,56 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +"use strict"; + +var parseCSV = function(file, cb) { + + var fs = require('fs') + , filename = file + , csv = require('csv') + ; + + var header = []; + var values = []; + var json = {}; + + csv() + .from.stream(fs.createReadStream(file)) + .transform(function(row, index){ + //in case there are blank lines in between key & value on Win7 + if (row[0] == ""){ + return null; + }else{ + return row; + } + }) + .on('record', function(row,index){ + if (index === 0) + header.push(row); + else + values.push(row); + }) + .on('end', function(count){ + header[0].forEach(function (h, idx) { + json[h] = values[0][idx]; + }); + cb(json); + }) + .on('error', function(error){ + console.log(error.message); + }); +}; + +module.exports = parseCSV; \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/extractFileName.js b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/extractFileName.js new file mode 100755 index 0000000..f3446e5 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/extractFileName.js @@ -0,0 +1,12 @@ +var extractFileName = function (path) { + if (path.split('/').length > 1) { + sep = '/'; + } else if (path.split('\\').length > 1) { + sep = '\\'; + } else { + throw new Error('ERROR: the separator in test result file path is neither "/" nor "\\".'); + } + return path.split(sep).pop().split('.')[0]; +}; + +module.exports = extractFileName; \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/settings.js b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/settings.js new file mode 100755 index 0000000..b701064 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/settings.js @@ -0,0 +1,31 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +function settings (contentLength) { + var post_options = { + host: 'localhost', + port: '3000', + path: '/v2/benchmark', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': contentLength + } + }; + + return post_options; +} + +module.exports = settings; diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/submitData.js b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/submitData.js new file mode 100755 index 0000000..d3f732d --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/lib/submitData.js @@ -0,0 +1,61 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +var submitData = function (stdout, path, args, destination) { + var querystring = require('querystring'); + var http = require('http'); + var fs = require('fs'); + var parse = require('./csvToJSON'); + var postOptions = require('./settings'); + var fileName = require('./extractFileName.js'); + + var post_data = {}; + console.log(path); + parse(path, function (j) { + post_data = { + resultName : j + }; + + var version = stdout.split(' '); + + post_data.commit = version.shift(); + post_data.date = version.join(' '); + post_data.test = args.test || fileName(path); + post_data.device = args.device || 'device?'; + post_data = querystring.stringify({data : JSON.stringify(post_data)}); + post_options = postOptions(post_data.length); + if (destination.host && destination.port) { + var location = destination.host.split('/'); + + post_options.host = location.shift(); + post_options.port = destination.port; + } + // Set up the request + var post_req = http.request(post_options, function(res) { + res.setEncoding('utf8'); + res.on('data', function(chunk) { + console.log(chunk); + }); + }); + + // post the data + post_req.write(post_data); + post_req.end(); + + }); + +}; + +module.exports = submitData; \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade new file mode 100755 index 0000000..c38b00f --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/dev/test/perf/telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade @@ -0,0 +1,17 @@ +repeats = 200 + +doctype 5 +html + head + meta(charset="utf-8") + meta(name="format-detection", content="telephone=no") + meta(name="viewport", content="user-scalable=no, initial-scale=1, maximum-scale=1, width=device-width, height=device-width, target-densitydpi=device-dpi") + + title #{name} test + | + + body + -while (repeats > 0) + -var repeats = repeats - 1 + p + | !{componentHTML} diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/LICENSE.txt b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/LICENSE.txt new file mode 100755 index 0000000..d154618 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Black.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Black.otf new file mode 100755 index 0000000..ba47f3d Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Black.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Bold.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Bold.otf new file mode 100755 index 0000000..b8a2f57 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Bold.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-ExtraLight.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-ExtraLight.otf new file mode 100755 index 0000000..5cb8e5f Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-ExtraLight.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Light.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Light.otf new file mode 100755 index 0000000..e3c0a74 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Light.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Regular.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Regular.otf new file mode 100755 index 0000000..40208be Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Regular.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Semibold.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Semibold.otf new file mode 100755 index 0000000..65b82d1 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceCodePro-Semibold.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Black.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Black.otf new file mode 100755 index 0000000..13338c2 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Black.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BlackIt.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BlackIt.otf new file mode 100755 index 0000000..f5a7490 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BlackIt.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Bold.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Bold.otf new file mode 100755 index 0000000..8998f3d Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Bold.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BoldIt.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BoldIt.otf new file mode 100755 index 0000000..071d0c3 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-BoldIt.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLight.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLight.otf new file mode 100755 index 0000000..43e0c69 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLight.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLightIt.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLightIt.otf new file mode 100755 index 0000000..01ac876 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-ExtraLightIt.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-It.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-It.otf new file mode 100755 index 0000000..51577d6 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-It.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Light.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Light.otf new file mode 100755 index 0000000..9d8fb28 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Light.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-LightIt.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-LightIt.otf new file mode 100755 index 0000000..e03c41c Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-LightIt.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Regular.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Regular.otf new file mode 100755 index 0000000..7b6fa55 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Regular.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Semibold.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Semibold.otf new file mode 100755 index 0000000..6b39aa4 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-Semibold.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-SemiboldIt.otf b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-SemiboldIt.otf new file mode 100755 index 0000000..8a668e4 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/font/SourceSansPro-SemiboldIt.otf differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/avatar.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/avatar.png new file mode 100755 index 0000000..c3a1306 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/avatar.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/bg_dark.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/bg_dark.png new file mode 100755 index 0000000..e44a7c4 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/bg_dark.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/breadcrumb.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/breadcrumb.png new file mode 100755 index 0000000..b2cf4f3 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/breadcrumb.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_checked.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_checked.png new file mode 100755 index 0000000..daaa1a8 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_checked.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_checked_dark.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_checked_dark.png new file mode 100755 index 0000000..777ddcf Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_checked_dark.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked.png new file mode 100755 index 0000000..4ef08dd Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked_dark.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked_dark.png new file mode 100755 index 0000000..3f5e6c9 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkbox_unchecked_dark.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkmark_bw.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkmark_bw.svg new file mode 100755 index 0000000..f737096 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/checkmark_bw.svg @@ -0,0 +1,15 @@ + + + + + + +]> + + + diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg.png new file mode 100755 index 0000000..9a4e92d Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg2x.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg2x.png new file mode 100755 index 0000000..7ab0c5a Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-combo-box-bg2x.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-grips.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-grips.png new file mode 100755 index 0000000..c52325d Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-grips.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-sprites2x.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-sprites2x.png new file mode 100755 index 0000000..f9a875b Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dark-sprites2x.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dialog-zone-bg.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dialog-zone-bg.png new file mode 100755 index 0000000..6dd0ff8 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/dialog-zone-bg.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/drop-down-triangle-dark.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/drop-down-triangle-dark.png new file mode 100755 index 0000000..9af2042 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/drop-down-triangle-dark.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/drop-down-triangle.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/drop-down-triangle.png new file mode 100755 index 0000000..cb1c968 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/drop-down-triangle.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/hamburger_bw.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/hamburger_bw.svg new file mode 100755 index 0000000..c08ff01 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/hamburger_bw.svg @@ -0,0 +1,1912 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + eJzsvemOJMmRJvgE9g6+PxogB1NBU1PTw7iDBcLj6OEM2V0g2ceiMSgks6LJnM6jkJVFLvfpV75P +RFTV3D2yIo8iie0KrcoIF1dTM9NDVI5PRP/u//jyN19cf/3mdw9fxKv5MP3d3928fXj27s3bnx9I +Pfzi5cvvvn33FqSf/Pqnh5CvZql0/Yv6lVX854e337548/rn/Ooqypf3uPonv/j22e8eXr58OPzy +2euv3/3h2cuHtz89/OSn8v1vX7x7+SA1/vDs1e++e/v7h7dX3/7x9z/1W0tbt8/eyffrz5afhXhY +fj7Hw5e/wtfPXv/x2bffvvh/H3CzWHGv45vvXn/94vXvj2/+HyEevojrIW6HL4p89d9f/Prh2/d8 +f/vm+XevHl6/+/Ltm+cP33578+blm7ff/vxw8+dnrw+/evZ7+ebZ4f+WN3jzp8Px5bPn/zHJW6ev +7l+8fJAXfPXs3SEs6IvrX4Tlq+N3L15+/Q/fvfrdg7x63kiOX7HJf/pW2pJm8TfI5atfvBLKbx7e +vZPnkhuiP3/998fxMYTI8pN/+/XD71+w+6Vb/tdPrdm3b7559eztf+DawxfrfJD/7I6/fXj1zUvp +Pb7uMl+lwxf8t/9p9eQtWOeLJVfplZIPca6HmKp+3/vm4Y8vHv7088M/vHn9oB1w/fbdb3QI1nWe +9V/95tffyRj/0+sX7+TBMkib9sCv3nz98FLqt+vvXz7ji7OE/q9W+O0zmRPvZOzevPzuHWdW9TtI +D//y2Z8fMExBb/CP3zy8/u2bf+YzfrEEaWfZrrbDssobhWVbD6Gy/QWPus3tnqH/q02jITTj7WOG +fCnj9I9vX/z+xeuffxGr9HVcZh3Cv3/74us+guFQ7X9p/KoO/2/+vz6tvPi7dw+v7ell3tz8apgH +89WvfiN3vXv99c2bV+j9bzHBZQK8lrnx8s3v9bv2N7+Ry7/7Rt+An7+Sgfry7YvXaHP6B35Tv/ry +5Xfy1d+/ffPdN794/e9vpp/o0v7nh+eyfmUsvz784+/+t3yQ9cm5efjt22fPpQH53OpcPXvxzU/f +25y83NuHg34pV/Kj//7+q28f/l1WVb9cqXev//jw8s03Q7ONIlzl8C/P3n7z/U1/+fLZ62dvD6S3 +ln/54o/yzTPpqd52pz2hUZkl30jn8BJWObnBeyoMXz3hRs/e/UEY0MPrr79tbevH/YMr7fvb+81z +zMG3h+Pb7779w+G3b968bM3uv2qtG5lU1P/buMeXvOD1P77WDjq/k1U4vZPwn7+5u0jtx+8gX/4t +t37z7OXLF79/++ybP7x4fukGF75vd9LvPmRi/fnV7968fPHtqz6fBsqXz96+e/H85cNv/vztu4dX +Tx7cw93XL4TJPbKM31vnN3969u75H3754ndvn7198fDe1YcB+PcXr7+Wuf+b7168e+gd9ObVN5BS +Dr/5w7NvHvga7/5wz5q/aQ2mr4T1j8z9iy/ew/VDPhxfD9///dtnX7+QDUWErr9/8/Lrh9eHX4O9 +T7tPsn2Vw/Hr6d+m2UpgWQ9/99Xx7fTfpvn0J5yUZSjRymol8X8vGf9P8msspZU6b7tyPZSjlBsr +t0O5m++n+d7L7sHGn2UocSjrriQtE3+VkKUU/q5D2XblOhxbuWnlGG6l+KfbST7ckXQb7scydh0f +zn/iUNahpCWjTPprKUOpyyZF/70eylHL9H9dGsvHRjPuxnMdRrWPrZSpDe86DLKO6ji6VQp+Y1Tr +bny3YYTl38mG2gf72IZZf2OU78bRln/1Z7441su0G+go44rfGFmMcWapHOVyMsLXVvZjK2OJX3cs +tyej6DeNHMM+Zig6SD5kmw2WDNBkY4SxurFyy3Jn5R7FVxZeZhzLwFFareMrO/TIRXLPvln48pmv +t/FVbvnEwZ4wc8rII0y8L+6zxBjXmGMRZWuLRym38V5GO6xxXde0lrWu23q9Htfb9W69l45cUkxr +yqmkLV2nY7pJd+l+kgcKMkvXnHLONW/5Oh/zTb7N9zIXgnTDWlLJpZatHMtNuS33Mk9CXepaU821 +1K1e12O9rXf1XubLMm1xWzdpZ6vbth23m+1uu5dJE67j9XqdrvN1vd6ur6+PUm6ub6/vOJMWeYH1 +mI7lWI+bfHU83hzvjvcyu8LE3o436026kQe42W6ub443Nze3N/cy2QJHYb1Nt/lWHu623m63x9ub +27vb+7tZxiXerXf5rtzVu+1O7nV3c3c73d3d3WNG3EuH3ad7edN7efb7aylyy3u58v7kR8ZyltFs +n++GcjuUm6Ecd+V6KJuXSf6pQylDybuShrIOJQ5FJuB0v7QysrDOfOfx0e/Gn9tdudEy8ddxKNdD +2XalDqUMJQ8lTXeplXVX4lCWoYShzGPRLp+s78enH39uhnLUwpW5G8f96O3HzEdrP0T7YZGhmIbR +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 + + + diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/hamburger_dark.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/hamburger_dark.svg new file mode 100755 index 0000000..e698e19 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/hamburger_dark.svg @@ -0,0 +1,1935 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + eJzsvemSJLmRJvgE9g6+P1qEHJkKGgCDAcYdWZHwOHo4Q3aXkOxjpWWkJJkVTeZ0HiVZWeRyn371 ++1QVgLl7ZEUeRVK2K1CVEa4Og5nhUOjxqeLv/o8vf/PF9ddvfvfwRbqaD9Pf/d3N24dn7968/fmB +1MMvXr787tt3b0H6ya9/egjr1SyVrn9Rv7KK//zw9tsXb17/nF9dJfnyHlf/5BffPvvdw8uXD4df +Pnv99bs/PHv58Panh5/8VL7/7Yt3Lx+kxh+evfrdd29///D26ts//v6nfmtp6/bZO/l++Vn8WUiH ++PM5Hr78Fb5+9vqPz7799sX/+4CbpYp7Hd989/rrF69/f3zz/wjx8EXKh7Qdvijy1X9/8euHb9/z +/e2b59+9enj97su3b54/fPvtzZuXb95++/PDzZ+fvT786tnv5Ztnh/9b3uDNnw7Hl8+e/8ckb52/ +un/x8kFe8NWzd4cQ0RfXvwjxq+N3L15+/Q/fvfrdg7z6upGcvmKT//SttCXN4m+Qy1e/eCWU3zy8 +eyfPJTdEf/7674/jYwiR5Sf/9uuH379g90u3/K+fWrNv33zz6tnb/8C1hy+W+SD/2R1/+/Dqm5fS +e3zdOF/lwxf8t/9p9eQtWOeLuFbplbIe0lwPKVf9vvfNwx9fPPzp54d/ePP6QTvg+u273+gQLMs8 +67/6za+/kzH+p9cv3smDrSBt2gO/evP1w0up366/f/mML84S+r9a4bfPZE68k7F78/K7d5xZ1e8g +PfzLZ39+wDAFvcE/fvPw+rdv/pnP+EUM0k7crrZDXOSNQtyWQ6hsP+JRt7ndM/R/tWk0hGa8fcyQ +L2Wc/vHti9+/eP3zL1KVvk5x1iH8+7cvvu4jGA7V/pfGr+rw/+b/69PKi7979/Danl7mzc2vhnkw +X/3qN3LXu9df37x5hd7/FhNcJsBrmRsv3/xev2t/8xu5/Ltv9A34+SsZqC/fvniNNqd/4Df1qy9f +fidf/f3bN99984vX//5m+oku7X9+eC7rV8by68M//u5/ywdZn5ybh9++ffZcGpDPrc7Vsxff/PS9 +zcnLvX046JdyJT/67++/+vbh32VV9cuVevf6jw8v33wzNNsowlUO//Ls7Tff3/SXL5+9fvb2QHpr ++Zcv/ijfPJOe6m132hMalVnyjXQOL2GVkxu8p8Lw1RNu9OzdH4QBPbz++tvWtn7cP7jSvr+93zzH +HHx7OL797ts/HH775s3L1uz+q9a6kUlF/b+Ne3zJC17/42vtoPM7WYXTOwn/+Zu7i9R+/A7y5d9y +6zfPXr588fu3z775w4vnl25w4ft2J/3uQybWn1/97s3LF9++6vNpoHz57O27F89fPvzmz9++e3j1 +5ME93H39QpjcI8v4vXV+86dn757/4Zcvfvf22dsXD+9dfRiAf3/x+muZ+7/57sW7h95Bb159Aynl +8Js/PPvmga/x7g/3rPmb1mD+Slj/yNy/+OI9XD+sh+Pr4fu/f/vs6xeyoYjQ9fdvXn798Prwa7D3 +afdJtq9yOH49/ds0Wwksy+Hvvjq+nf7bNJ/+hJMSh5KsLFYy//ey4v9Jfo2ltFLnbVeuh3KUcmPl +dih38/0033vZPdj4E4eShrLsStYy8VcJq5TC33Uo265ch2MrN60cw60U/3Q7yYc7km7D/VjGruPD ++U8ayjKUHFeUSX/FMpQaNyn67/VQjlqm/+vSWD42mmk3nsswqn1spUxteJdhkHVUx9GtUvAbo1p3 +47sNIyz/TjbUPtjHNsz6G6N8N462/Ks/88WxjtNuoJOMK35jZDHGK0vlKJeTEb62sh9bGUv8umO5 +PRlFv2niGPYxQ9FB8iHbbLBkgCYbI4zVjZVbljsr9yi+svAy41gGjtJiHV/ZoUcuknv2TeTLr3y9 +ja9yyycO9oQrp4w8wsT74j4xpbSkNRVRtrZ0lHKb7mW0w5KWZclLWeqyLdfLcbld7pZ76ciYU17y +mkve8nU+5pt8l+8neaAgs3RZ87qudd3W6/W43qy3673MhSDdsJRc1lLLVo7lptyWe5knoca61FzX +WupWr+ux3ta7ei/zJU5b2pZN2tnqtm3H7Wa72+5l0oTrdL1c5+v1ul5v19fXRyk317fXd5xJUV5g +OeZjOdbjJl8djzfHu+O9zK4wsbfTzXKTb+QBbrab65vjzc3N7c29TLbAUVhu8+16Kw93W2+32+Pt +ze3d7f3dLOOS7pa79a7c1bvtTu51d3N3O93d3d1jRtxLh93ne3nTe3n2+2spcst7ufL+5EfGcpbR +bJ/vhnI7lJuhHHfleiibl0n+qUMpQ1l3JQ9lGUoaikzA6T62MrKwznzn8dHvxp/bXbnRMvHXcSjX +Q9l2pQ6lDGUdSp7ucivLrqShxKGEocxj0S6frO/Hpx9/boZy1MKVuRvH/ejtx8xHaz9E+2GRoZiG +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 +5+8WHNujgn37Jvf02foBF49O17EtRgdL6PPOr2X3eTnApGRT1pjj5tvyKZydOhfd8sG4HeMKh/VO +7013OIJF5f3+3OsnvTc1vMU23l1vVJ8w217gxTs3bjan2vPDR86ahVpD/2JkTVDjJsJv+qe1Z/an +yOaVZeNGuLhUMMvf2+8wpQ+OD548yfVhiTMCf1R/efbHf3725Y9ffXK/+fLzb9I/Pqvvfz14fP76 +i1e9333z6Hef3/3koNNsDP9gvv/rQ/P7L77+/vGfn6q/fHH0r0+efj24bGWPHsqn+R2h1O+TZHj4 +8+Grz5M/fH3/340/ff3l5xfDr4d/k/f27nx9/+h3Ay70zWj/1V//fvT1l6o8Puh89efWYaPxyaup +po7a/4D2ssNHd77I/vvx6PDnn/bVf9c/f3DePxrC4I5ef/Zn8/vLR4fqDz/u/9z95Me9O4dnyTen +M5H9ISvOsh/+/s9/PfjuoPHD/Ebjcl/89PWXbx799PUXw8b5Z4ef37l8dPdx+2zvDjHr0f+cPLs8 +PPvpx2y/+3X35Rdn+69HB6+z/xZj7PifPx62xNF/vv7yL5/8aPFAl4cH/3717z58+uN/Dp+0n/xu +v57//IcHx/Xf92wfXjbbl3t3ip/vftZ62NJ/v3vwWp3c//LBnfSPn+1/+/n/fPb1wSffPzooL//0 +5x+++f3r+61W8w1+6nz28OzotW1ZJPea2aDzh//5ovPvb9r73Tt/+aQ++Oxflw+Ojv/4H+z/p1/f +/+Z1unfH3P/hp68f9FqfnH/21dP797Lzf33VybJ7w7P0waD1RHz25gvhMbYOvxn+AGzLPimzH9Ok +/UXn4F4Txlc8/epu/fNyv5s9P7cU/OPoztcHT778/Y8PPy/0EMblyT/N7/+cHfT//dmXP7T/+YU8 +/f1PhPbPvTtA0J/Nn36PQ/JP86P5ew/59Of9N5+aupuaP7SPEvHT758e3mt++cdHv/vsvwfYisEf +/k1YqMjeneT0/z5R9PmzPz/60n368seHf7PFDz5/+D8WmfyHfAJT92Xy2Z///PBzefiXV185PD9+ +9eX99s/f/ptG0ncY8D3b164VKLT/je/AT6ED4u5XL7BQqQimf7d/eEKsPiyHf1Hmv83PrQffHf78 +2eHZvb/952Gz+ckf9s3p938vnt95+f2DZwf7zw/Pjjv/+fo/P33xau/O/2/vy7fTZ3IFn4B3CPsO +ttmXsGMgQBIIECAJO4EEwk739Pxxn32qyrvxCnx3zp0z5zv9a4KNVKWSVJJKKuWCvdaQImY/POsX +h7i7kwt2sy9k4fd9mP/5DfsT33/WBZn/duGAgKlRJNKcbTl80bf9XzX7UnNVyYJzVqVowxCa4n2w ++qedr+FOd8Z7akKpcHScSbROpmzr6XS+nJqIsjw6MAvRPRgZUG9Acl7yJ4O12J9ZF8QomS5g5Gcm +gFggOUqSBcAdLo87t40NxGslpCx/YZmFoDgnvTyeEZXAXPh0eqqVssMnHHFM0r1LjEjHd9WXxZKt +PuG0DJLUQITkCJ+bsTnpsO2c+WW4uSq6az6S41QgAL0t1DBvxRnk0AwQqj8bmJrZmV8si8dIYtpu +ZiN94l28Bq/ldUcA21Qqej2TmNSSxFbzat5gzbbqMzfQMKlYIVfrraRGi97kvVfqRb6B0BQJjCgF +65ecc3olna/rBFkI9Ql3qjTyGqzcvMCspt9ksRCK5MLelw5SOD683PEgpAX/aOfK/Z5mf7n1prPN +tpZdCwBRdbMAdkXP9pkgbd7IR7b5vbSDn33ZcmF3bUlpS2fh214Og9Ful5QWLHa6ZQ== + + + RoUDBNWvVoDMLB67UMGPCpPg8j3btk6Pwvds2WbrYx39XXuTSKNxGwHAwj3fPmHJ3Mqx+yGTJdzB +0+39pmvMpwnYS3jKGscm56Ljcf/O7TSip4CTHafIAgxv/nbxPDpyJyrHb6Cxp+ZQDj+vP7Jvo6c8 +/TSWHWWS5bwPvDLqAC1Qs+Xw/nmYfTu3gtxT9DLQY+CLv8xhGrdRq8WXT38vmX7JbyLN74UDnwza +2YDNaClCns7jpXwtAz+lsKcS/ojNJ/E07nHk0+x3Ke4XBiv3JvoW/pmDqjCPfoj+DL/ViAZ8+kj9 +mkGQh9/lKGDZpJeMhLyFJjHs74rwlSR6Gf5ZMFjZ4eXgS88cHAoLxCcEkWEHn2J/kUCvwNG8oiGx +082igRisaJrUhOGgIq/legt+l0DAOCwIhJhEzJDFSNGfLLw3Ggv7a/SbBHyOppHmSIleR8OjqLhZ +JBosCd4QPVksSdHSgdUXLpTE0l6xEKJloLFQv4HE4mCjaSA6CcnxiGbF/YmAsZhLEmPISM4lpb4k +1JDRJxYihVT4J8UWQPPLMYYsW8CXa+ysOFaRJBZ6ADj5kliP1FyR5DDkeOTmDF9+kSKqSFJZAj5S +FBNNE9EkLgSRFo4mz2KmeFqEFL3MSR3gZG61BKua4rgWvQ4pkZUQlQQ7wldWeVBMih7Qso/A6ie1 +Mr8gkiMqIsg0j0kpQDQ1VjT1sSG1JKwMUdoSjbEZjuLOF/SJIj+cBho8/KcvNP1c2VanuiEz9nkL +WPrfBH/DiGU3YK9c1MhRvRcnjS4f2MXgvKLMbu+1AMulsMq8m9uL/M9gmClOV3sbtZXxzInQ6VXe +neGbHe535M4AX0zo0KCBFhZeZ5oy/V4rzk9ujxN4W5g507E7YvnludkvVKv7HH9CueE829wUXjJv +g8MEWLDrzB8uxOJGvkP8GVsPk94RuRU/9ZucH8AJ7eyKU0/Lnwt7CC/Pb8Rzk0Vh7iqWOdsKWkpP +5xhHGNoK+4y+8Fw3vhEBXFPo28bW5PabMs8uAHSD4Gferb/e/MzCcQFLCVjrof4tzokG1wRaSjc6 +JxpcE9rqYznUC6dGucwC33ew4jyU6Np3KNNr0LauaPuo+5RDZixHJw7U/1ueBXKkGX+q/Fmo5sJ2 +gMA5yTUyH65cw/p1QuYwVBURCTrxfRHE9qlw1Veo/EbGHNmAZwEJR5M/uylHOutaK/vSrgJ2B9JJ +MSc3EDmngqJnKhx2sQJQyq3Diw9k/RusnP1/OdD5S6G0ss6BeDWSMKgxBZ88p9LONInF3IngsxBs +TcZJSdopDVPKvq0zbvDrxR6fNtMvRKZtjNGeass1B8RaBVWcfqK/MueXn8Y4GPBwyKz+lw9M1wdk +P7equ4Ej8vodZAUkDh2DQW5FPBq5ByyzY/HZ3xqDy/Qk8JHDOTJZ/PSxUCLk4MtlJoubM5BKwhr7 +i1Kc5bH4P6KRae0p13jNgN2i9/dMD/Tcs2Ybz28d6GszD95/AzSNtzYssjpPXrHazrcuHV/mBxFm +WipFuO+N2WBlWZLMHA7LdjBef08jBAksnRhB7y6PfcfyFR7sl12unAuecxjuaR+NgjX4GGRjiaqX +fdAK7n0/WeSLFT2Zg+mpTLqcniBQV+/Av/HMNmB3apLk0GlcwpkGMsnJYJN5b7ht8aX77QdsfrFf +xOc87XwRwCh7C08H14jisUuOMRZT1Jus/AqAaZNeIpy1oR0QxmHU5DfABR2VpZc3ECi9wBXcfud/ +jj9hGFXwfjSxp+I+L4KowcvngW0Ywc7NSG8AmC/VNXoljkeNwOYnnb3XU7baw2fUMj5Wn2eF2V/M +wzCfwwT89DRWyJfN1Gbk3RpTPioQQEXP3h9D8fnINqfpVH7159a+Jg6Avm2Q2WGwUhif29Gv4nBg +/QCDXxgz+9zAwe5YS5bvgNYNW6yAErEK3HMWxYm//yO0YZDG/kC+O71f1xbAUoq813dvwr2bejOS +DBTnxcHLZAhskwRUON/O4tSNfWaDjlgDqL/3KGUL0OgD5kwy3bYVKn8/H7lQp+vLNlyvi2yz5Qae +Rcla+orkVvjswDdVqA3l0V+ofNRc0NhooleAdk6+SQ0+2rJZ3sih2dYrfAN65dZRi6fw5HA6kHHD +yj6yJBbWFeCJmCnxbXlbSiANgk20eSy6XeFv/vYG12o3zA0yHcvpxGKugSVeGMOnGtkEnBxq+byC +R3YjVvkoJWkQ7P6KIrT13+/v+I+9UQcmnSdLFnpll9TUBO+F3AZr4mv78an0UscVeZ4mXkSvJOYD +5wrF0eLPi8RP0bPt40AzhvDsW4j8Kv2dXHb43i+jYS64yHwEe0l9SRky6XC3lH/Od9Ii3qBPLw7G +D2A275tgkTN7nnVIg8J8gLzvO4MVHYBIrIEPyGc1HH4k9+VkYV0LcUYwvYgDs7Hw/Tba5n9MlhBg +7OBLdpOqbKV4CK4LZLqX7XQXq3/78exLvFjNJHI7vuVNjyzpyBy8sTPUyZls5Gv2XPiOjfzF/vxk +E9Ez9nuwt8C+P+hlt8sXF6CYkFlYcwn9+ckNHgwqXeFxSeoxHJBikNgqW2xlI7EmMhuHhe/GEezI +lKqgR1s2k/ns14LMZxbNsuURr2Rj/lVW+pWs6zfTaVXGZLJw4o0GaGKzKRN/ny8y0d1hiOKSl1iA +Q+dCawW46HWpdaaUmSeEkiyt63/uVKRUBvvLvp/osQsVAIqyeIRh+gbgjl9bpvPdOvNgp8JP54Kv +OfNm4s+/K55xDv5phU3kJk8fvbDius9C7zX3B3Y/Afnta/9yPhgxpJ4H+eQov5wL5cHxWPBMyGLS +abG2AS/29rm/l1Tokl8aJrB9rfrQUkrgDqDnglZgqrX8he/WATh72PcfTwIrx69RyUoaq5mDeXAq +fG8PPgmGjYFdc+GEZztdMv+dDnDiQ/sv0DiIwEAsZWKRlu7vD0aEVstCKWWdAxMjFqZisNNO/8iC +TZCOyuwdOpefUEd0C/PkALoKZzfnADKnPAGXwxkNHRLvwCoq/WZf8FwAuNnpVSaZ2pn5ssiYQeDT +zM+jInb09MOpdrCYDXmrDago8Ess6CU00AFJtCT3JBNZ2xSnoQ3A7PU5JYhlz0be6iRYg95rdpv9 +dkhjAZSvRuVAOID1hC3idXcA7KQtm1GTpArYnloXOcZng+/YCQhxa5PFiDTZAEw1worT3iFUyJR3 +e+ZlzxYadGGKkUq9zBodHNLWhfvxqf/Eow7Ydb5y60jGglwJ+iAzDA8XIq4z1BfNuPc7eWBnyg9B +1MtOLLde70YiB57jMd62PSlOsKSdb8HTEMPUg+x6PIenEmZ4WINlm9vaqeB52c8YS2l1ZkfN318Q +Fltxagp/AU/GeCCL0WZZbGzsy80acpQT3382G3Dbf8OcLSRhAdSBxi760GIDLAo2ReK96H6xuwEB +B16l91J1IIZVC8BM+qQwG6ws7vdMck06+Ta4GNibvNxBEd7nn4uxEdpQ3KljP8YpR6At4ZQeHQ1n +D3ooz/4fczxJG7TMS+Rw7Q8DHRleZyLdRTEbLR1P8OjbSzqevJ083v47JuZx2x+Yc9PJx5za/yEr +Eurk9HQu1JbnbHSyW/C2BKRw+41xGdh6WyzxfZ4fxKp36yr4eb9gD4YR0xis4T0eewP29htJZhaA +yd/OrZk6/4aR04voAP2AOmCfdwLYI8l69s2TAeuycG34WBBzFqdn0zAb9fpM0CAMi9gLbEebeS64 +ms3CnfZXJxpJ58v55cfMBD0sUybZCAwK1WrSxB4Wi38G7DFybCtmEl9tYHZGGm6M8OynQMv3V2DP +/d5lm+vQu0AJj7uZo7NrKlSfAoDtzbmdlEJlTu1f+5HW8LwxWMGb+cfCIhQ2JT3nz59wau8qAi/I +tSeT5JTmRlY/saqJ0Um0HjvSTsWrzf2YiZgKKHcADOQrH3mbbZPAGt9ZBl4uuBmfzaatODF2vebW +XrxV6va7G7AupxwXzaNeeR5MzuTo67yE2RZ25Bt5N55WEC0Ef7ExeLM0tRrffu87WPi2I7uZLI6s +bhNAHBB/aA/k5VgIwHaA8To4AwL2rECtNc7cU4rH3rOtdqTF0S62yvzWwMz/3gUhS0jl0TvYonbY +MYsln3e8mCgiVs6ebBVcP/5p0tOr5rJRTwXCs/2AuSBZZQ0iOcozi0NbeEVgTOWm2ZdqGR6XLnqQ +DoRgSA0T2BzmH4nx+/YXeK/+4q+VLMa2P8VBd9kGCsfbk3h9FG6/fPzSGqZGfsrCJp2nxLY4DTtD +ubrT+RPZVBpu6ImLo9ENsO/XSTtgZ0u/6O1FF7nge8DLW/2fgWeRbRWOrvC+Ok4/At/YAZyrJC7E +x0JxPQJ5mcRXj4Wvn56Zx2gsHOTWgz3nTw5EoJFfZmbeQmWdfxdt+RjR+DSTjmouCtblte/Z8uYv +iIOHWc3wA/3PUHHSKoY4zSjA3IeGQ3mGAtZMhKQfQzEV6CMHsJkw5hIvjke/nuwmbXwlR44vAgrD +Z+HJ+I1xw2NgDweJyku5GY532xMwlzlJm4iA1Wht8YQtwOoDM88JEHzyY/XhuPlLU2pRKDZ0F+vu +GJA6twfIUOtYnKbKAFTbtrPE2sUPS2zxDnxkMLIyjMv7BtnWcnqCY/yvFJuCJ8x7K6CrwzRk+Tk+ +Kuv1GSW4bw8PvAaeOqvZZLKSNV+jLp0QDFMLXwvkEF2BU9j+e0NdDiv+sWRysvZr56WSORnMTP0+ +j0qwiB/QJD/eUaX8P/OjIhyCgoMyTCubKYCDLr5Y/ygVmGi53EcyAZ8ZOHWLE3nY/mUPp39vD6uc +SvEj80PYgyfPZa/TNxTJZ7Myv2sdfv7gdSMK6ecsUceLeYVfeiE/Deame62v8mepNITmfMEbrBI9 +GFoAMmodRJMre3C0loCBHsaH+cNpOX+gKxkfwNJAHjo+/Hs53zwcx/+CQjbePPCFEfLLw/gIv+Zy +ZJn7QHwP7SMCCf4VAvvP9vywA9z9AKRsTrEqQk2BW8De5D8CRJ4HgIz96QaM/+G0hSCm84cfVE49 +fliP/wOvKRnvdoBtKQk+nqdLOLzKpoCq8DgwFLYNINEZjG77zaH/OT6cNyvYNNinrGIYsQGgp4ef +nXI5AEN7Eoj4+3wCL2BTX1aqK8YPU16t9Cpbeq4+BKSocvwSIFmN0DoAarJXi0i/GEQ0oIuQtXJf +jatZVUD/dhpvZrBziULlBgO2vt1sp6gLjLwOVsJF7QDgMWBcWhHCnUODDhTo4Oz0sJ2MT7Xxf+YM +gYOaRs1TZ9Uf5rorgpDZNVgtyE22Aotxs5PtvzTsGIgF5BSoPpXN1yPa5IWidH67maHiy8oMUPzn ++4epMdCw08g3dFHeooUEE3NHWAfBuCXSX/zCqgL2ij2qqECyK4zYUNHQIUZ14TkScNMIKhIOsqk8 +p8kVTYp33ff5rbyiLsZAGYPdhL53khNdjeh4v37WekkB81u6Xfp/uB/qEyRtKpFmRA== + + + WDAmNtEUrRnq5gW4Cty9OjI/ULpMUklGREYZx1uKlhxEMz7NW8vz32Qz/llrMM1owWnxLgpT38qA +KYKI0OJVOxMhtfmAt+e8a7MUd6C38wSu6HZzakIO0mbFSsmiVGEo39ID0EX3c2k1zblSROWpIy4T +zV3n3svTkHpE/WID1rIRirSaWD/pk0PWkAc+K3iB0s151p0UVa/Bu6+g4Yvuht6Nxe4afcMWxRon +lvESl05ugu1NJ+ygBsdJdVaDtxQxzwxo/PxvJIvG3KnQKOJOdyZ+zO+ue93p5SkAPxHBZCMeYB80 +2E/oQSKQbp1yhe9YaVU2Nx/H8OwqxT4l3I/N8NLoDJQfjV6/vWmwGt2pVdLofO7HjJ7lD3g0+vYZ +3ef4m9FT7xaMXqxOYP7HngOhDxnzzkbwSBzrYHCFVTD9MkoFctFANNwP//VR4gYKiHBPsfJwnjdY +D4fU4yTr2T0/ZaqxYypaTr77yG0/2CkePvtYoU/2WuRj9nGKu7KRDY0lYGm4815XE+CrheWmS03I +F6jFLIBiFy/VjodD4tgCSDwVzB98o6bBjewYJU8dYrBd2bCZDUeYXziwhy/smASwo2d3qmS0oYmj +dSmsfP5jtBSM7hO/4M/SGvy6VxAi/Tx81T8b0khLkUEoXhn4JJEOLM81g1WElkMa/qmWrNJIk0bH +4YhbD9JIX/HPoImIuzikBiuH9mj31L0ySENLx9jeK0ojDTo/3UliIT1TEzkIGqzm9m5dk5orRuaq +GRmkYbNlc3A+yiDtDTDy+/mNQ4qKLFm0JWPShj8NW5JIS2WiJUteop9qjRBSwIuTonBN3wEnf55T +NYjWebmqjl7gY407AdLg9oKValiORvpqt4uQhkJ/wx2HlONkCu3w8LXctGSQZsbhCGnBJZEO0qOm +HNKywWoJOBKf0nNNGr+O5uW8KY20kXem9pa/mhRSd2IdT3FIwboIWcmV7mdepJEGez2MjGHPkkhN +5CJiaf4RL1JIDVaM/PoiZeYaNltXm3peDukYK3lGHWmkJSxrnzsiPYTUYBUT+GT2pGmkPa9DROD0 +c/CRJm/xc0UKkPaTWC3ixSFSlwipwXo0lefbcHPsJQDayE7Mv7WP/lgGadgcWc3IgRzSAlZ3fcUQ +UshjorlW9vHM7+G5KYn0LWEPyCKtzt8CmBRSqPmDH17sbeg0Sc31aKqW588ffadDEmnHvlnIIn1b +NkYThNRgvZzrRwnrVHdJaaS1gLVNZpKP0kh3TyYppEAnQ7SdYcl0kiHwxwv2nq4WpJHWU8XhoPH1 +JYn062VVQUjh/nI5199eaEbKIP2MYl/HtVca6fPv7u8lFg2IkMJUAoh2WPFuZAl8sL65jTJIe22s ++PP3JIk0+uw1GTNfXqDHANr4Xiw052FkSCOdBJwioXH2a2MXQkrYU46ycKY1bOSKZyFSD4cUYIFo +AdjfPaP0Hw9ipMet7ZFGekq7RTM1fo4/nBTSXA+vCBWh53Bsp4wAC0Dru9RKFS+aK0CaP12owrIp +TCFN41WvSBF6dsFnaqcJWOL5KkIKsdBoLYfDeLKBSDER0sMhO98y/PtkFCE9hn7j9E6Tjjd8IvKa +tvNRy0DbD/PxMCwcVLltG2zjsk97DfyvI/d0iZVH1jP39ELzA9VbsMn8GqyBzZ1nxvU7j4iehqP4 +sEU/Pa6iF1IZ3ixNXannlFJ8rcQ/ZZ9GCVdzJP90OR7YWYpdPs8Stv5U9mnNvUkT8k8nL98J7qmI +YmHzi2k6Kcv8Olq2lZPtI/X0276PiX7bdv8wxuk3bopfUKw9eXrbSD2ntFzBvTrIPn23TvxG+aef +hfgjQzGJ5yPrIGKRffp7et2VZZ+uOkSuwT29oNjfikwN5H4NhtRIhGSfPhHBVFeeYtbpZvJWk/u1 +zWirfLpknxaz9clc9ukTkTbh8hTLGgmLMy7zNFTGio8uZs5xR0L01N1qHNP007wvKZbKcmtUcmW5 +58Fj0NMUemB5bGb/yNP6Z2Rdw6c72h0lhyFK9eS2x2fqk0CPEScL9DDzRu9TrAc8zN8W/McHvyON +nkIzD/95R/4b671ROoLGN27mGM13MBH2x1cvrc+BnyOwx1LmgB388OkPyQb0dHgS4a9HN3bgx3bP +QLWabADfd5LFZ/b/PE6cQDuZiofzyOcVqNuDyWDl0CJPRwZp2Az9nA9ppMFeXxYp2ER+cZE9xp8r +8nRkkcItbyqHdMZHGnwDPjIPbfQ598ZDOrPZzBxSZP2zSAMi8kLrn51paS1A6uwh75WPVkDgR0IW +KbL+ZZACfxBY/wMOKZiLYK5fskgBgY9BeaTQ+pdFarBC+38pPdek0aeEtGaXRYpsCg4plH0BWmhT +tASrOo8x6NEneiGc+f7sT8t7g/Pfhi/7Mm+GzftBsfui+l5oSfMdrS1yYM6fWVpbXojuyPEHqdPk +BWhS5PlAKxfbW0Yk8TC10cP9k9o5Zi3aWYc6ifL3UztncsdCdCAQqVjZ8otGkYqVPgpAcY2LEHOA +U000+lTRSv/jqW9pBMgEZhCwtiUYD5jc4456SRR9Amov51/OC1b2nybfYqZjZi/sywWIpcSf7ugp +TceUwJDbr+ALGzRozy6GOpTdTqtj3gxebUICshE3MGDsKWS1on8gQ74LvSSpQa1iFdGg+EManu2A +desewp7GeHE0UTgQkRxoy69zrqpGdPgPPXjKmZeYn90oOz+DlZsh+kd2BZn1ezOpr5+ZnZ+L5jGp +GULjta1ALO3rt0X8SXkWGomlAAx35X5JWVAGLezOECvh1cVZHF8JdmSKs0qfe/2Ul6Q7MG76NCff +THki1489KdPdIE8soepxXqqeQVGoegKyqsegxrrFz8qBT0B2yAIC2ijVI027AbyKhiGwzHg8RQ/1 +D007fCNNu57XKKu25aQSxeMkp9Yz6Z8afxdDkwukO626GqlLVRt9miA5kIJbNCv+Lsab1fzVZ6NX +/0KNFgGWzlbXhKQ0DOAd4M51ebRlxZDP5yOnDQyuW5BZJs8OH1vsZTQGKs5/JWEw+V16uXU/MpzD +42QU1JEGhmsFJgUK0Z13yuO6lLsxqVXulKUO7JVjU/esuJZm3NPGPfCfDzfvkOKCLYBmdBSrUssJ +KMZfUPgPWFAuEH3JG2B+rBa85I2XBjsk3rjQXE4lyZGlSpOj3CQz2PzU9l9YYZdLwnl8dfflksxK +alaYVtWzih4NVtmNSYPNyL0MrJmPk+y2ZLDqWd8SpElZv/UkJfuzklBPSxCrvuU2XoUhndJPsnvl +S5MejxaTDgxJ3qBjls5g1baCwMtXNCzUbH7BCm6sioaFjvUrvf5xoChOvgHY20bDuOBVZ1qACTcU +veNiTnhpYD1lJ0bPJPlW3c0UGx7uSDGhRtM5rp0wDjOKHC4c11PqeKV1LDh/AeMpSzmDcgat5AZN +5LpLo4oe4xnY0lJ5SpvuJpW57t6iz1GmzmMvVrIMj0xqHG2gJ66fOj2TTavzwdqWYuqkjuy2rBpG +kDYMyyKlICkv6suUOiq7eKKB0Jx8ORQVLaBpICLb8jqaqIg9byCUj+yW2aIWZRi6/tDhk1OHksIk +Iza3h/g6Tny8gDb4VIE8X9SBQCaoASxBo4INI6k+ZASkomx2GKx6BmW+UgEItSUUua+TVXlb1qoA +KpwC0Orvy8/ProHkBm1EF9gK6vEMsSXPxfp+K/BQ7/0eTFU44cWvY4nTDIJcOEnHR8YnB7y/DGjl +T/rESolY2kVc1u1BXhIglk4RFxCLFXH0i4AltvILBfwJzkUo4pJet3p0CXCtSVuERCmW8CQOyYpH +oxSSFUVI/p6EFryMU6wekgVT4wkSvfq6wyRPMC+hrjW8wXpJ4qE8nYXb8hXhDcAHewJNCGWqXKyW +9rUS7akycR+DVSlK9/cED3d7N8V9IFnUY30iVSATr4HUCWviZJ7eFEQadgJTOnMWm9KAD+SDibRO +1mBMQypXxaa0HtpR9hgaj1V5PFrjC4F0O2IXcQTPF9O1EVZFlvB18hJvOJWnps7nVW7zY/eXK6LR +u6p435ObkMGqwOmAd4Sb3jUKIN22hgwqa66NMEOVIL1BtNXJ2bKAOqKNTm0f4tuy1Fx4Wx08rLLz +8zfgrMB3WphBVup4nJwH4/Hpi3lfzrn7JrXbCU9FNR9BAmBy8VapaCvlWcjFWyEwHcIn7S8BoTFY +bz6kQKumvOUZNMMROpL6RkOfiVNwbpVACgrrTXJQGJ2sB47+fY/19yWACU4I9W2iwvNBO7IuPA6h +xZlHaap3OWHIo+RTg1VdDDVsNxAY4dN9xidjRMBcTpcmUvLMz/hesIuJNdpx5bzQaMeV+ABPg0aT +jJDkAWEy+1s1WpvTaIz3qseCFwNT12gGjSdIENj1Go2VylJneweNBlZNSqPpln0AR79Gu4hdUHBu +12gQyu1nrwiOwmmQJ+dgT3H8BquUNSDYhDpbJQ+af3QobaMEPU1hviXweS5i4/C7Ww9gmf3l276X +V0MaLbM8kPOXk5QwUxF4fWoWAOsYdSlZg1VWzV6Z/SAU5g7ypQWe+DUGClg1UVKTnIZRh6PNtJeF +guIwAM7tKRAIioxDLTp5V4cjPHTXGF6WOE1AwO4Rq6b2QjA/N7QuhLsh+NZ7i33PY9KxqXm82ePr +vmuNZvFiF7K74bsu+145BguB3W7ff+6l9kK9uxhcNf0hrctdDMK5xb7nQWH3wut3MQRHwr6XgsJ6 +rzJwtO6Gynsh0jCf+5t3Q8FeOBSfEyMs4Nu7pCNB/SOZh0XvlYLkKS4NQ9YWGB4UloRPSo+G07du +95ZYtSjOD4DdKt28cUnItnKutQLFNJm7zEpCLHIeEVhLnyY5Vzg9zQN6dvwKkSsN6XSiIclyBMrt +URUv8caU93kvtqW8z6/Jr9SwMRG57kw2PU8+c03G3wcjI7SRUoNwTY73y7YFwGTPbthoj9aEegAs +YElUa/eIkACKRfSZGDI5iHAlhz5NMVgKmIyw9xSTbymOMDDxe02D0sgRF8JF78iU6HL7WSpU30h6 +FvQaoGq548Lo3TSGRk9nUDR6s4EBrJsrSlXQUTe33F5Dx9/FLivoRBVDV9fQKVfQIZ18hxo6WaSo +gk62WlBnDZ1yBR2/WvCWGjrlCjqB1XdDDZ1yBZ2gWvCGGjrlCjqFakFdNXTKFXSoWvAONXTK79G1 +1TfX0F0IrqCCjvUsbqyhU66gQ/aYeg2dICFZocLs1U5KWdvyOfDylUCiZBcNQ5KM9BbUE7dd2uql +SJGPfHUybEFs/UoEB7RGej8Kwt1e39LxzvgK4oSNq+mUcAnYVVgryu7xDi3FYPPfeUctiCI841MC +ppyHpW1+KNanVjmneX6iyNWlvGgnul//kGQqH1UiV0pDkiqZg3PRVTSnSdcURakgXG6PvgKqk65U +ECp/TDIZRH/YWC5ojG4Guzle1fOaladm0FjsJsyE1BsYRJwM1vzWiDFV7CZ3bCP0kg== + + + 1Ird5P1T5QMHnrYsKiaDCFxTNTekKKpmEFQKawMmTMHCL09sJsRerfJRm84ak7qcXiSVcm7vJCCf +QqmrxBTVvtU1Vh2q+/aAWFJn2aw9dhk6UwscrqI7UZgE/LYtmTR7xYlVSdbskq0C41lK4jowVbNL +cx3fWS0HXkcd30St/sUsCFrJl6bJF8Eom9KXOfD2x6VZblAZqRJN+fVTzYHXnEUwKwkjmJLrp7WO +L3pQq4lRYgZhdjoEdrcK0QN38iFXmaIHmDrHa6eYMMB6I8VUy0S1T5LTaFdRTBj4JXLdnleY6FQW +JdZLVHJps2UvYr6XbhYr6k3puKVyvZwIhAyAlUm4I0uAGBEDHP4zUpTusgZnj/X4VJy9RVmzsycH +QJyjeAUItatRwDqzt2poK5W7aoWGmPr+wpg00mIBS9zUgwwGxZA0rEqTceIu2F6pRs6gUuas4cgT +TUj5yhPDhXulYEfGjxep/I7CSQPJeScjcpz8W9EX3pFwlShLSaVA7kLryFdEnSR38yvssYpWiefk +XdYe+63oC+/Il9mJM4iuptNSJdJgELkS8iygMyIjGJKgHhkMitAT/lAYklCY1XcxBToFtQ5JOTtd +vShOaUjiuzt8ovgvVZJ0j4jME4rI3JilBixhi4aIDH3Gp1KeY4n7bLdEZHj+/tPtERkAwKGQ3aGj +DO2aiMxFteDtERlYhiaKyMhVpKrV5wV1RWQk4/xPGspztBXnwBI9IHDqnKwtfQ+26sCExnKVM5bl +88a1GMuBdNtt1sAMyjWJu+p9MhngusQb9vsEdcDU4g6VnF4tZWhXJrDz9xdYQCYfXdJRPnaRuiBZ +LahWV6c7afYyQxXV1WnM11Osq+OVjipUCqsHQauKl1TxpJdnWyqm6r1e3kUKv9O40TE173KJSfep +h4NY7pFTp1wPp//+sWvq4aSyoF//7l0Pd0OdhY56OKUM1fvVw8Go9Y0SqKEeTuJGUNkiruvr4QTZ +UMxv7PeuhxPfO0pVxN27Hk71loC71MMJTqw0pFpeVw8n9sXkjnVgJdvtlfVwg7tbTiQAJcyJlLMt +teREdraaciLVZP+4CtxqBuRRgsTt1egIjkdt9TXC0VJHIguFsscQnDtUcl1kMijkwKtrNFhcJx8Q +u8x35vWykcl4tu9dFxnP9r3KQoiEUDba0+3cIoZc8REvqnCrGAJgitfKSOkxWTHs7bSKoYI1Dumt +z1+UZLT73AaM4OgTH5l6ZADnLoWQBb+2XUwVjvyVwDK3acmlWV9eCax6G5owKi26rdHpuYxhweIz +5YudVB1qtiIVN12bIMKbs9zFwldVpI5NQw1FpBorUsemiZaQgUqp310qUj/396lIhXDuUZEK68Vu +r0iFUO5RkQrhaLsGWuQSS+X1IQGRvzRVd5KR00uvvlAMuzeLoagUTlqP3bsUDuXzK2b03KMUTnJd +7l4Kd33cUkgxZd9dh195Qykc/w4iVAz3j5TCSUQV/oFSOOn4mEb/rKdkGPJVAf/+ZKXCp6VsrqqW +G+GF9ljep+IWaU30gqBCmiKKGgLIEJj8zXY6bZiLS4b1Hi7wqtF7Go9wlG7nBapcasvjsKgXN4vr +6j5lr8MRbw5MdFRie+DkF3aN80jho9cAtbhMvSxL6854WDDPzkUyZskMyFbqtZjxn+xA85OtdKSH +2oYX+sVDJlsOt57yOd80n8/5q7AJwduO2Y6sa+GQ6YiTsBZLquoMekl0jdKHfN1ZtBF/5bOXsNgt +MX2p84PPPKShpcuaNG7lKuyCva5SsdvML4sUI1s5pQo768tPfSyHdKSAtOSN8ZCKa7Hi7iMvCicu +dgt2lzW2M6GoBMzkUCp2w30ipMJ+fIk/uQq7sNm8D58/5YrdPpSqzv6UK+y2rZYsUlttvpzJIZ0r +9+NrdOWRFp8/SrLktWwCiaEc0oawwg6tKhBYetboE83ncY3vJaTeo6IKgjeDnzVNEIPOV+o9euus +hSUM0WfGS0qR57V4Q1WKHWtIuRVasO4NNRfBGdGrbXuf0h71DFVx1ES+j9Vew5B452IKg1JLTlXL +86C813t2kpNqOyJxp4qG6JJSJzldUbiPguYUSZVqSHQnpI68PrUmcop5fdr5SaWJnOz8pPq+qTUb +0To/9V4Dmomu1mdEdJfaDf3jtMtLaS7fiEg23VVrAzrlSO811XTXxWH0VtNJ+QFML877VdNpvB/m +xmo6qZigWF5ur6aTqqW7tvJRvppOKhYvnWl/SzWdgCy0zEreP3ZTNZ0UKJUbQq6oprtyR9ZZTSd1 +TsPulXerppOqpeP7+/epppOqpdOY26Ojmk4q1s50YL9fNZ3U6qJI712r6aSMG37u6H2q6aRq6WRu +m7+hmu5ySEuzvKV0bTWdlHFqsN67mk5q/SSyoW6sphODUu0pfFU1nZxted9qOu0Uu6WaTgRKfCZ+ +p2q6qyimu5pOscbqbtV00rXV966mkwIAsNy5mk7qtESUA3+Hajop9SD0Xu9RTadyMnKnajr1/eUe +1XRSxOCs8XtV06lVct2nmk6qlk62H9/tDqCXcwAF/cV0Xd0k38XrskmluDeHxsKnvYqwC4gf3Mr1 +srm+X93FkE7wlOfe/erkrQttdDq57broxFFJkAkJazJVDQuNLCAoUJCpepYblGhIWlWBhu5ywoOp +q4YEKQYGpavtstKQpBMpZDWMAp0U2i7LqEy4iwk9ojT+dBR5RAFLbKfS2Fw5Msd2y1JqdHdzmzve +PVcaTfJr2tzJdperaqpV0tjmTq6SS1shnaYECeX8ZK7R3W1rVerttHSZUYxSaWpzpxpRhIS5uc0d +bcMoN7q7uc0dVfum0uhO2+HRrnqHe64C6TauvIja6yyqd0tR2lU5k/vqWh4wtUenVv6UPeWBDepU +cw/V+BOW0UHnWTECr6mQTktGs0G9wlA+iUNzfSHAopB2qCOJDFJHNvQn5GRtHbYAZrNdXE8EL02V +nbPU3VBy5z2l178rC7sE2VCAqVTywTVnQwFQqvljmrOhADBtGd3Kic1I992l8vH2oxDYUVDhOnB6 +9TXC0dTbVQoKL7Pr7R4SiKBcVLJLVgqr17IjYJoKa+V6QIgLa982l4W1b5v73QoIgd2lkTHiMTBa +LcqMv3fJkrIlRUrVfq9KOdSuyyNdWIl3mUGt6InL5VDPj6u7VKawNx/rtyQuQdXO9+pgCB68yh8R +a5b9tq5G1XKnb7Dx2s3mBAVFKatTB5w73BJAwbm1WzUFhRFCqRsO9eWqtjUUMug64XW6JcSwo6GQ +QVME/uYOd0x9pVyPuyvEUCK54tq+1fo63ClVPt4ghgyj0R3u7tIpT7WeSFunvFvridhOebeLoUKH +O2Fdkpb6kGs63Cn1e4U97vR3uNN6qzmsfrq9sPZzz5k5ct6r5sJaAEzdzDFoMXSo3nTXFdaKKx9D +t8aPYH1hXbIcWt89VwjOFXrz4o4ICOcu9Zx1TJsvpgpHvhZWVMRkULtmArXL01PfLlXExD8VhQrC +cyGGcYfKQmiIazF93zSWMWkpYrI/DsSeKG8X01LGJJykSuyUA8Wui2wZU9yhqUJd0W1npTLu0CKV +WoqY7I8bsfF9rV/Z1VXEJJdBBHsnKuy0+gzDLl3De8Ot/CLDUOKyxG6P6gFxjxrXvE/+VjHov+jt +SKer3SMipbw91rvf1VQ9dPp2pxrXnuzVVPptmMlRV7tHlU55/itrXHnyyaZhaKh6Vq9xBUPSXPWs +VONKR4DgQtQi0vgY0w9WvJUfW4UVns/5n94L5vnTm8FaSLvfWo/bkTsMPpVeUXUf2f0kZ4Q9ZSpQ +Gw8K7fJix/QnQRHec7rJRyqohzNYj+ZO75UfqhL2YYvnP3oy9XBO+SK8w3kUx4U6WVSGh7nkav/C +Zkuk6fySK8L7lEUK5mIidwHZuWIlc78ti9RemfgWcn3YnBxStpKLI/BriOAhFZamHe0RG9dHMCCq +cnQ60h9rKaQGKySwuOecoAxvLK7945O3mnyVQRo2W4PPhREXgxVXxA0VkJYsYXmkpYa5L4UU9X2L +lgWllWKkTaU+gtWOPNJisU0KMrsAWgt87mE/0UWYZ9ejX7j6Mu8F8pjse/z6Smzkimc1QHTHt6ci +t02COfeCYqOTPayhoz3CzTOvECdmNzqNaZOAqCEnOg0SdDFTT5zUsDcD2I/iwibVCIl8SdJlapXs +kCAnyw8qr6W0Sb2w6XivziwooKvSmUVrJKmgnFolu3QXnVkAgjc9KWhKVXeimydvqEpTydCkqGTQ +xk+iQy+982Oj1rDuTneXRZkhXWRpieVFM9F1ZWkZrEqDko8T6xsS0JbyeVr0eC5yY0XqqviZcgkP +r4uXPVOucyUA7IqGq69VYrCD4r0ub+x5jdpuONRQjaQYXtZ6yjMo3nITLVeTeHFl3FXFbtJH1rru +tR4Ur4wsC2/RhFWAt15CK3VXnGy9mJrXcnlXnIIDJB0fEyaNSByxjkld/Q7kNQx5Nx95TIo1zLWn +3lTBnZwcoxMr9fZ1gpGJ4/zqITvUj082qhLcXyQQrKIH/faITO8n+2NX/nBQXyHZRT+LG9qyKVcy +6aqxium654A3JFH9y6ykFDtWtcYFQ+Kl6tOn1Typ1VkKuLJoKOXk33OlUAqo1tJYZf24k/dZSb1Q +RzMziPoaS3aZ0QFMrYuOXVxdqwBMtKvcRjHVWh7tkxSeXN5IMdV+OrooVgt+ygC7KBeWsg5pil1Z +Bai1BlDzPSRyBWKaagAVstM1VAFqrQG8jCfrqQLUWgPIv+FQfxWg1hpAFLW+ugpQwCoKHqY4D1Zf +FaDWGkBIseurADl6KusNYY2V3ipArTWArI98VRWgzJAuagD555XUeC5ndXtTPu0d2W5pysebyz/Y +lO8iqvCPNOVT68h2n6Z8VM2IsoFye1M+g1XCKrx7U77L/sj/RFM++f7I92zKp6l/5S1N+fhRBTio +sOygaBKplQbLd/W7/W6op3vcDaWxr5+mu6Fu7uvHm9od7oaS6+unL0/p2r5+yl39rrobSqKvn3JU +SNoT19/XT5r5FO+GuqKvnzon36Ovn3JmCBu5urGvn1ol150Cuopd/QxWXQFd2b5+ylMTxS6u7usn +GMhFV78rOoBI9vVTnpBUhuo1ff0kyxGVbjXXThjNlbKSd0Ff0ddP+eYv9kz8xr5+ihtdHu1id+jr +pxwW1nUDlUJfP2VXVzIL+oq+flJlkpzo3daP7w4177r6+ilDgXH+e/T1Uz5QMWiGc0vhu7gi9dq+ +fhKmJq+rH787A3ZDXz+RGGLCrn6CO7t0l6dgbF8/1brXu/T1U+7qx3LyjX39lBOueRWpN/X14+q3 +pHhRdM/V1X39lAmILNg79PVTkLXjKnCnfnwuZSia+/GptJPT3I/vpr5+LBRJ8dFbzXHR10+h7kE1 +23aut6+fsiUPbzy4R18/uT28c3mSeF39lgZznjlJVBNDtb5+yufNwiyC6/v6Cakt9g== + + + Fq/tx6cvSUO+H98dxIft6nd7Pz4tRUxqtzdc5mroa8Unrki9ra+fILB90dWPqhi6va8fWyql1Ff0 +5r5+ymaODI/p7uun3NXv5lub6L5+N8b6NPb101D3eoe+fspd/XT347uqClekLS/7+l1fDM/r6sfD +clNfv8tQMr+rn9wtZ3r7+imnd4l2sav7+iknOoliSlf39ZNYF15XP+V74bT39bs+bimkmP6aJxm/ +8oa+fpzikurqd3X2oKivnyJH8DqA3NbXT9kwpLzX2/v6KRfE0jvyzX39hJMUd/W7sMc032Ql7Osn +bwRRNozKTVYa+/ppsmFu7uvHX8nLAxyF6loZ+ZTu66e8OShWcd6tIJba9/0S20NfyUZ7aUtnfIjv +lVpSNyqK9krwrXxoVznxXlS2KOAmhse405vU445fB0/FpmhUDsEO6dtyhMH8L/MwS89ngSdaO8La +N+K4NIJt5cno/ni2YP7uKkK9BOupjJZ6quLDHBujf/qxCwYOyycytf6KNdouh/fPac/tc1h58Zw1 +78+5sPFzPAuAT6OMNRRNlG31l30ztF/1PgzWSMgXnEbrZNdX9R2MoVopOMo1V+307K0efl+25s+h +fccx/7a8Z53Bwq+p1ayu4utkdztPOzb7YWRvPWQ24Wfj+3Pabgk4SmHr90el4jwvzR/B7ec8Tss+ +qu1MtVtvHaPPPcgYicW+404G7BmMzFVzGPk9fcJKYVvzcBjFHIdj9L1yNA/Ck2No8vHKVlq23I9+ +77svUIuZmLK3X//h+LmFzeZiZqq2+lKHCOpLE/3aMJadNnbQoWZbQMJ+kucRbnVlM7UnKWIhYoDp +nmxwXQIWo+xcUUWjY2yfv5o7/VbKsjn4SRsRXJzN65lxBitJn5jiUOPZsws+w3y1+gbVJBqzZKtl +xSzzGfL3X7dCk30nEh8wtdc8r2iOi7fypgbUmhQdUmFr/mywFvrkvIsaaOa/Ss1u+Dk/M2X8p+RT +xn+cJciYefVafM8EBoBsm1Rp3el+Zsth4wTA6ewZsFT7TAfuXkVgKWNvkEnUjAc0q+zfFnJytvr+ +PnQXO90y/AQm/Lr2waJdD+XWp0K9A/KcMP/JAbMRhidKE/tDPjvzCXeg2DGgSGQD/oy4UNUvUDiV +Hfjz0YM0jNkOdrGPA/gi72N+SPrJIlGPArBlzF3wWM+ko1yp4B778q84Xe1jmD8VcaKBwsF94a48 +nsj/jP04ePDo5j0YW/KPBivzKO/lHhG5fjvNPKiw+Kp8fF5LZckQ5tkJVMZ2hZdqpjH7nZt72WDF +SwPflH3k5cEp7eIY/M5P20ehZwxWGf3h5XCNgH8SFOzJwMrCbripVyY7HFroDS8vBmsh7CkHTLdq ++KiXpuE8hNPAYHLYAZ+WX9CfNNhp/wOn16pHuv31t1UAPG150FPCGY7PGKQtH4MFc1qiGLF+sxY9 +MSfgDqxj4fv7Iwd9LEcxw0X8iA75AIh+itkl4AnzxrVDxHgQcb/5mHS3E4dwqh18zka+Zg4odTnC +2X8zIlaBFOt9EOzCjwKWZHJEDp0fVcJ5nq2Yqb97uAUjCuVHyNPvPopEhX4Fhxu5hShMX0L0p3Wb +oD+dPwa0bUkUneMh/YlYhCCIEAVi2M9AiH0frNfYEsN1DaN+PTw3adgjZ5fltj7BG80oMftFDxDF ++kFWKie8uYzejXm40yRgmkIzt/YtXNnX6XetUK0Y3zhFwh7m5NnggI0Xc+BOEnMB67kyZ8bz5UfT +CNiIdhCNNmBLfIToT4XxD/tegH6v85cVj+Yl3/oiC2vTNNtsfdoN1uLEm3mHm3US5bPRsn/ahSlZ +FJoOwkNgm0BvsmrtUm8yuxjUnCK9Gf962TqK77n6U865PsBLCsLlXBHztS71prjtsB1NHKi1KLqi +1sme8QH1T0+ju3JTq5rrDo6Yf2Xy+X9Mr7aAJfZ3wjCH70jrMaAtUSI4ireCP4NOVOaMFz8z8M+4 +Gwc7RwoqQugjMwv/CX7TgSql7EN2HUy98aFIBFRCMNJQ9svElMqYxOrDB1UHzH3dwzoLbDNiFrTq +onSIJ2+dsN956O/aOOTpKuCNSKecH62yM4FWrWFYaFKFC1HF+dowtw8jO3nxAnUfQNDboq0FTv0z +C7/DGfOsFqEpUSK96BXgyTX34M+an4ENdSkcDdClnLKmNB+YC1CpXs2sRFl4FycMdHRF3KAWNbR+ +9P/ScX7EaNjcFPJzZiX6Dt5a0MBm1k0BvH5w880cBCKZfuMBqHx6fEIAy1R76KLy+ponaGC2BRdJ +1I7wOzP4LnqmrExbn3jimdqU2ZV8KbIAGpcAzhQAMBcKRNlW5lu9gOfd8EYEtAbAEH8mYHkr2Jg8 +ZTf85GO/87PfgXXxvO2hfXCgmB2wfZ+3i9k42wv2zB4xJtYjwVhXwCibWJqfwGAIlsQ9o+kNA06I +um4iZuR6R8Ne5EbqJooesjPpvt3r9jPfBwFbJ70uOWfVzdxtUf7ymX7bYAZuEiD1eZFYX156QVf4 +MhQLRF5WtNVLnHHO4EXNwqHbYGJGw7sDxMUjwcchMOFdQcKSwJnvzwaowg4RwecVEAEV11FEGPCJ +QCwaiAjwQZ9PAlHrciDxHAm4fuJCIoyTzxwRAh9rPMprZvV1nPj4SGnD/0uWBOK+1T6O+7vGrb9I +EeGQ631o4wN0NT9i7LORI4HBagweP2wsEboKfAAvLGWo+CnFSrIAuDyl3k6ZG9V4EUaJ5cYA5UXL +NIaHK6fBREhQOOK2aSwlV4NbC0oqlabx+rm7jadfh3tWW4pAaKMEADE/Kk8DAHBZECczINL5/VYA +YmtUH4OidjqYEABEsd4fBwIr13tT/pu9T5Z/e7yFx8ivsjDm8vp3M4+h68Bv47H56RYQAMDaeDOP +dTY38lhvK8djmkFMDuoM0hfw2MU0ljeS8nV15njsOhC9oQZx7TLRHmkQE3ndp20Mcx4pKYrpXY3e +Ul3i+WMAc7kYxerG1ehtziJSMhTTPo2DimxIjUFQm5DqnU23MXbfbFbfkYnjJwfCaO8s3/ggJpNr +9wB2R57M92qUUBnDUkY+wRh42lKJEpPV8VZtOdmcNOxECvvQZH9WHoO6tpycjfw/p2aT4E+bmYl0 +likfEh7LxXhhb8eHKwhW3zOcdY2e/a5m9NS7L5QRCH7DRcq60OML81wzlE8xP2WiyC5lYzgDnjc5 +tvx9UhEQ+2MvRNW9Qq976IG+ipeJVn4e4Z9sAK5sZz85KMduflxBa7xM+bvw4N+DvG76z7zPR7nb +TE4v9LBZdzyQ7uxyjNsbdLDBRCc/eBk7scG9qpv/oOZmw4ZVryCi6BlE2BBMlcP3FbAkFlkG3wvO +EYYOUZQeXdx3/OhoKe/hPRBER0sVHwwOuQDtPt2Ur/11/AW8U2ri6M9Aum0Ef75mONhDOmzxSiJq +u4C/MM8htwCe00AvoRYFVvvLAcrL64sfxjY8AMHeAv5sI7AuKiTif/0IsJFJtztlTprhUzdA4ANG +S6/GhW5HDJYRoHG47y34x0lbfLGxtw1WMlkM/vLC61TwvdRt8I/fmTN49rQoBsa4yUtBlIJH5Smp +QGRuukQQnU/RRixaIjP2eatQmT0aaa+618UZVmnxA37O9RDslXSEqDcOslMfAyynGL1gkxcUEvHQ +4fVJ208HeSddDJ/UKk7w6QOn41GTAZGKVQiwVpNxgPk0C1IReA+9tKsmguhFR+Tgzy4TlFt9YMyn +AcdtE8KerqXo0axmAd6DgTEwpOOS9b2VncvqL4y8tkAuGogm5gPnd34ZJl9y66g5KhVpoSbE/UNl +bHOhmlPXxyKdoow7yCynAYaX8IwDfBrjzKcZFwKe0kGk02/wYjShU4d0OVOJSMdrqpOjujVGBUNt +w2MEeyq5Q0j2v8K0LHYxM3JSleOD+qODLMV0xAf1Rwel7utTiw/qjw5CiumND+qPDlKcrC8+yI8O +Zv8rZYjiEfwB/eNvntfzw8vhZ/GzefAYEgZ/toLj7c1sSx7m89b8f50K2+n5b745PcQf/Nm3fKUS +DRXm0+1s/oCSmUKjCKs2vDS30vzNP9IWhBhRsDxX+I6VVmVz83Fc+MZ6KZ5YUFbKrrU3epa/ZbCh +uqc+tKt+GD0E+WZ0lI8e+GeP2uUpIkkerCKt5DIX5ofcueiu195FpwQoGBMbtUpgeyi+5+bNjP+4 +SPrL2X610Cc7bxn/CdsyAUF4ninIHuCdeksckgND5mQzOpPPQaPXb+/Aw/ICmIulEPUbPc5MBn77 +ZHQ3TM9wfs/wQdrozQZm0GooG117MzDLxvsoX1XYCDctctxWRw6HzHK/bpGaNVDnx7hnsUihYwNa +X0LxQycZjPj50Z8wpdFBf/qdI+PASVsD9j1sIVN203/GHV7KkKGCzvCGGBrEdzt+YiS5gnGnj3w9 +ruMokzvINFhljzK5BzebCdQx8ICP+x8wE1BaHm0o/HNmgsGqvK3fx0ygQtuaIV5pJgBDhzUU/jkz +ARo6jKHwz5kJYC6sofDPmQk8eZn+c2aCwcoZCmIzQTkjhM5CrMXlNgda/bu+yDN0pZa/wJXqDIpA +Kb53jc7nvoPWm+f4K1SpZaBL0y2j82edMno3jU+oS2NwX7CI3StqwR57lKoDQpN1IIHjDjXfdvRL +472XSfwIOrjEDzZXw055f0BbumltCU9YeNqS3srthD1j/ELLDrVl3udBt08TX+dkxf/TPfkow+PH +E3ejtC2gx4pPUkXnwO96ropWHz5oAyyRA6daKT32RYuASK+ibBSgUuHIHPA4Y5Vbmzak0PnCOBuG +7+yV4k7IG3VkjCADNEqd5uOltiPKWjG0SVRaBCHFnn20RWLJ+AtPyS0G4LxglPLkaexSm0ALAf5x +86p62DRW7iQSKHNu90WMeFGgwZ7/i1qqUmlpxUFIdDjIpeVR54te/vniNFoVnS8ajScHGz87vl6c +LwZdJV+wnGWO2x63TOsmwUGot84dBRGOWC8gOAgNm43WnKXAgJjaLk5Sc34eAJzslnB04EsnNNBi +Dzgdmez+n1S7iIwDyGgpxOfMd509813v4P952bi5RAvEcgJznw6tCMOOWkN+SIXBCdHnnvT1+q7M +u2vMHEEiO5o+fTNYxYeQ6Fb0648gnVKnbzAkpPn8Db85VLeK7hgiZAI8IqBTYZoIQT9HBDiaFe8I +Et2kJ0cCJoSajq82DBFcoiNI741H0Y8n7nhee9iVxwfp+OtJw1E0nWIodRhNFxZTVETnx1KspHCa +TZdEAgBg9TVy4wUI1NRN2xio1JxLEKgh1S3TQAn8jEjxjrR1TKMd9+tKDLiUSk/s5LqFp6FL7RYB +oCmmlRLQA/eqTePyaJ9fJIN7dnlMchoaSQlTKHEE4GgqlXNutpWHwQoTHva8N4Hb76TfJH9xt0TT +D5rPx0P7jTwGDBTHbTxWC/o4ALI8pghikMFu5TH70nEbj2EbpwyPaQZRc3tUGYQPAA== + + + TULIY4OI75bVAP78o18KAOAxrSBKNZO6uEoDoNNYocGnWfdJj2HgkyYlHAO6lFx1NYCBqSrxSmOA +Scy7+G2rAa1aZVKi/UVpGmUvqU82LsYQruHQGr9BNsrpJqEyhkPKj/N25HLw5GsneSAmA+tte8Bk +4XYzO7LiKBTGsMPlmUo0Blr2xaOYWiLemzhi6n303ZZkBhPcJUVcdgystkQJnyHcgYxErv8YQh/1 +GqfBQto97BbO41It//UUM9Mhg1CGiSRRIf6nP2GeOlU6YbBKFU/cu3QCYrksntBdOsGGQ6WPJdG6 +aDqYFB9L8h7s8gv2gSimDwOozzCqwPu27WCPDZ49/AeLIFuTAL1l4CVBvUKlzEP1ADkZnQNskaTC +PxsuwdEpkB1I2wbtegMmjtPehqeOzsdzkC8hKzX8dBFFugLJ1qDBThttBDbAizKWhwf6gNnpDVLW +eMvLP7hLZxK6k/AvDmFYL55wlskk5SXdDWKj9sidNYROr5Z56asfXRis2bez5afYn73Ck6MWzvEv +8XUeZOiYRG8QYEORQX7BRDrCssq7l66aaOShXnn3M2z/jqGEhi/ocr7jTHTpHZ0SwNOE9wD7KUiB +KCb+wuDPPg1xOEUL32eP8fsY+wnnrz68U5ytSegH+LUUhZWFiTL+hpi59MOyVSpuuRoVA33BCVev +wq9S+fJxSAM25wsk6hf4p/cOow9fOPuJ4L9XXwThd0FuNED2mfE0yFGnly+4o06SLNY7USa4+RfC +5pN4GHKoj41T9KkqyP8f6/sfG+vb/lfKkACTqeD4sLiZ8c8cDVYr+OZtfjrv4AuhYW6++NnUxv+Z +Hwz4A/UfBv6D/0ZiDzgRfSBCIfBHCH5bmxgc6N0H3PlQA7vL0J89nAo/09PPdjM+/OchDr/q1mvt +SuEh/kC9OwTvJh4cYDTYELwNHjnhQecQjHBowB6y4H/dfxvO4D/s4cWAPWD0AOB/3bEBo0cE3voP ++OMJfPgFX/37Acce6g8fX9jDDIy82zQEYg9eHH/4oz5gD2v0IeoLETEwkwD4gMdC4IuHQAT+OzUE +4P+tDbgvGMEIHP6BU+9jGAE/AhhTA46ArtH/E75QMAbeol/x4oGHAPoXwIqgDwAnAEA9iVG/IB7o +gU0N34Y2nJ8vAgkKUaAZgaGj2c0M4QeH86H7zlACvAfHhfnCkVg4GkAfMIIgwIcYhoeDDFlENOKI +gdHEiNG0iIhpEUG0iFC0iPBpEYEEiHC0iNGkwGhS4GJSEIgUBEMKgiMFQwCWFBhNihg93bY0H9H8 +AcjAX/9LalmH7GSpj3C61CeFCYMXqClbh4qTBo/paVOfFCYOQDJTBx8VJm8dyolO9nAYUx+BvDxk +z6ftQ3N8PM0PP/977nzwv50OP5sFJT1AombbyXyYrcSGL5Pj/PCv+WxYnf9nSL105AkZDt7dbDcP +gXCA5i8tssbyEeA4io8InGYkPAYJG+XoiscQYfEYxUp4jM9L4C+c/g38QOAULxEExUtEQERSIghJ +Cv6leAl8YHgJPolRv4Bo6cH9twsWwWgZgtEyeFRMEErN4LSewQWKBkeaBv0GEYTWMwStZwixniGQ +niEYPUNweoYI0ETgEQT/J8QLTZn+iLHypThtJGFo4jwRk5o6Eiw0eeqTwvQpEUMEYERMjgT/w4Qs +EKB5KkDQPBXAIHEDHHEDGCJuAKN4KoDxeSoAwaLfwHdxBAdxVSBAcVUgKCJrIATJCv6luAp8YLgq +QJER/oIhaSDw3y9mAUbvBBi9Q8REJCEovUPQeocQ6B0C6R34G4YktOYJ0JonINY8AaR5AozmCXCa +JxCkycAjCfFPCBqaNP0RZwVNceJI0IiYUNCkJ48ELEAwoqZEAErUEAkYUZMjwv9tUavlKFsWWLbI +4vQC/9r6Ol7MW4fxzxpYtovj+F/zh/Fmsz2NT/MdePKwOMyPp+1h/nBcbv8NvwE/YV4HNvILafg/ +wknerg== + + + diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/hamburger_light.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/hamburger_light.svg new file mode 100755 index 0000000..27a1290 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/hamburger_light.svg @@ -0,0 +1,1936 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + eJzsvemOJMmRJvgE9g6+PxogB1NBU1PTw7iDBcLj6OEs2V1gsad70RgUklnRZG7nUcjKai736Ve+ +T0RU1dw9siKPIontCq3KCBdXUzPTQ1SOT0T/7n/78qsvrr958/uHL+LVfJj+7u9u3j48e/fm7S8P +pB5+9fLl99+9ewvSz37780PIV7NUuv5V/doq/s+Ht9+9ePP6l/zqKsqX97j6Z7/67tnvH16+fDj8 ++tnrb9798dnLh7c/P/zs5/L97168e/kgNf747NXvv3/7h4e3X7988Yc/vrt69uLnfn9p8PbZO6m0 +/mL5RYiH5ZfzevjyN/j62ev/ePbddy/+3wfcMVbc8Pjm+9ffvHj9h+Ob/0eIhy9iOsTt8EWRr/77 +i98+fPee72/fPP/+1cPrd1++ffP84bvvbt68fPP2u18ebv787PXhN8/+IN88O/xf8hpv/nQ4vnz2 +/N8nefX09f2Llw/ylq+evTuEBR1y/auwfH38/sXLb/7h+1e/f5D3zxvJ8Ws2+U/fSVvSLP4GuXz9 +q1dC+erh3Tt5LrkhOvW3f38cH0OILD/7198+/OEFx0C65X/93Jp9++bbV8/e/juuPXyxzgf5z+74 +u4dX376U3uPrLvNVOnzBf/ufVk/egnW+WHKVXin5EOd6iKnq971vHv7jxcOffnn4hzevH7QDrt++ ++0qHYF3nWf/Vb377vQz0P71+8U4eLIO0aQ/85s03Dy+lfrv+/uUzvjhL6P9qhd89k4nxTsbuzcvv +33F6Vb+D9PCvn/35AcMU9Ab/+O3D69+9+Z98xi+WIO0s29V2WFZ5o7Bs6yFUtr/gUbe53TP0f7Vp +NIRmvH3MkC9lnP7x7Ys/vHj9yy9ilb6Oy6xD+PdvX3zTRzAcqv0vjV/V4f/N/9enlRd/9+7htT29 +zJub3wzzYL76zVdy17vX39y8eYXe/w4TXCbAa5kbL9/8Qb9rf/Mbufz7b/UN+PlrGagv3754jTan +f+A39esvX34vX/392zfff/ur1//2ZvqZru//+fBcFrGM5TeHf/z9/y0fZJFybh5+9/bZc2lAPrc6 +skS//fl7m5OXe/tw0C/lSn703z989e3Dv8mq6pcr9e71fzy8fPPt0GyjCGs5/POzt9/+cNNfvnz2 ++tnbA+mt5V+/+A/55pn0VG+7057QqMySb6VzeAmrnNzgPRWGr55wo2fv/igM6OH1N9+1tvXj/sGV +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 +8xm/zlGv8eucwWv86lmK7Pe2LO38fNRjvM/gMp+zPUe9ruvrPfhZQyXmECh9Pt0czCFP+XQQTBeV +X8g9uB/ja3A/5nMZ56jXBZ8zeN0czHgDgcTXtuT9r09HPcbX4znm61Huo94P/cs98M25nts9V1/P ++MzV52245urLeM/Vl/nM1eeo11x9zuA1V59nfG+734b7qMd4n8FlPmd7vY/nur7egy9vzuvmXM/4 +cmT223A7Msf4cmSO+VzGOep1wecMXjfnPON72/023Ec9xtfjOebrUZ738XroX+7Bz589kMY+Fu2z +BxLml1fRmGL/5JZgtpEe4222IO99VJYurff8H8ZPHsi97fYq7qMe4+sMjvk623PU67q+3IO/+zR5 +pt7XfT2OwvX7x6W4zvQy3ld1mc8duI567tV1Bvd9PY7Cve12Ke6jHuPrDI75Ottz1Ou6vtyD7zJN +ntn3dWuPr3CdwvEqrpO9jPeFXeZzE66jntt1ncF9a4+vcG+7vYr7qMf4OoNjvs72HPW6ri/34O/+ +yp7PAJ/OKF+GgjC/Pu+OUhV7BMfYBQP5NBTgUPUZ76GAzSxSfX+IYfw0FNzb7s/7Pg== + + + 6jG+zuCYr7M9R72u68s9+M6LkdetPd/tdQrnC79O9jLeF3aZz024jnpu13UG96093+297f7C76Me +4+sMjvk623PU67q+3IPvuRh53dfz0V6/fz7v60wv431Vl/ncgeuo515dZ3Df1/PR3tvuz/s+6jG+ +zuCYr7M9R72u68s98NQOshASOJ/8niF8/ifnyQr3t5t1jC+X7JiPh3KOevky5wxefs/XE3M4ZHxx +73nY8mntwxPQttdq4hhfK49jPo74Oerlso8vnv3rdHCK/1yh1n/4+z9/BVr/U+Kv5e8Wf/Ud+xSE +PbFWvGF/xBj7/vTlaCcU+3cOFuLd7Vq9U/lSztyRGesLs+cDECu9zk7tkxFr8trO3GEz1u+jfnsf +tSn9/z4DG/fcscb4tO2Q0vt91GN8ncExX2d7jnpd15d78N3mDvz7p1tLb6J8OgX6HXyxr5O9jPeF +XeZzE66jntt1ncF9a5t1tu9tp4Rq76Me4+sMjvk623PU67q+3IPvMnewauPTfeVp50+vLC+wfHpl +L+N9VZf53IHrqOdeXWdw31f8RO3907bTUobXUY/xdQbHfJ3tOep1XV/uwXcLZKEyyqNnWSccwRaB +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 +3x/Wu/nN/nv9H/gN+An3OrCRH2jT/wGF4u/k + + + diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg.png new file mode 100755 index 0000000..f619677 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg2x.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg2x.png new file mode 100755 index 0000000..57663ca Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-combo-box-bg2x.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-grips.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-grips.png new file mode 100755 index 0000000..1692347 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-grips.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-sprites2x.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-sprites2x.png new file mode 100755 index 0000000..a70f5dc Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/light-sprites2x.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/pop-up-triangle-dark.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/pop-up-triangle-dark.png new file mode 100755 index 0000000..53e79bc Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/pop-up-triangle-dark.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/pop-up-triangle.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/pop-up-triangle.png new file mode 100755 index 0000000..0467cc5 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/pop-up-triangle.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search-bg.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search-bg.png new file mode 100755 index 0000000..54181ee Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search-bg.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search-bg2x.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search-bg2x.png new file mode 100755 index 0000000..f886480 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search-bg2x.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search.svg new file mode 100755 index 0000000..d18a4fa --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search.svg @@ -0,0 +1,11 @@ + + + Slice 1 + Created with Sketch (http://www.bohemiancoding.com/sketch) + + + + + + + \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search_bw.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search_bw.svg new file mode 100755 index 0000000..9ab9e71 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search_bw.svg @@ -0,0 +1,16 @@ + + + + + + +]> + + + diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search_dark.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search_dark.svg new file mode 100755 index 0000000..9ab9e71 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search_dark.svg @@ -0,0 +1,16 @@ + + + + + + +]> + + + diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search_light.svg b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search_light.svg new file mode 100755 index 0000000..0c0dff6 --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/search_light.svg @@ -0,0 +1,11 @@ + + + Slice 1 + Created with Sketch (http://www.bohemiancoding.com/sketch) + + + + + + + \ No newline at end of file diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/spinner.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/spinner.png new file mode 100755 index 0000000..ae457fa Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/spinner.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/spinner2x.png b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/spinner2x.png new file mode 100755 index 0000000..3b77ee6 Binary files /dev/null and b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/img/spinner2x.png differ diff --git a/platforms/android/platform_www/cdvtests/topcoat-0.7.5/package.json b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/package.json new file mode 100755 index 0000000..03c64ef --- /dev/null +++ b/platforms/android/platform_www/cdvtests/topcoat-0.7.5/package.json @@ -0,0 +1,85 @@ +{ + "name": "topcoat", + "version": "0.7.5", + "description": "CSS for clean and fast web apps", + "main": "Gruntfile.js", + "directories": { + "doc": "doc", + "test": "test" + }, + "dependencies": { + "topcoat-utils": "~0.1.3", + "topcoat-radio-button-base": "~0.1.1", + "topcoat-button-base": "~0.6.0", + "topcoat-radio-button": "~0.1.2", + "topcoat-navigation-bar-base": "~0.4.0", + "topcoat-navigation-bar": "~0.4.2", + "topcoat-input-base": "~0.4.1", + "topcoat-list-base": "~0.4.1", + "topcoat-list": "~0.5.0", + "topcoat-search-input": "~0.3.0", + "topcoat-search-input-base": "~0.1.2", + "topcoat-checkbox": "~0.4.0", + "topcoat-checkbox-base": "~0.1.3", + "topcoat-button": "~0.5.3", + "topcoat-icon-button": "~0.3.3", + "topcoat-button-bar-base": "~0.1.1", + "topcoat-button-bar": "~0.1.0", + "topcoat-textarea": "~0.3.0", + "topcoat-theme": "~0.5.24", + "topcoat-text-input": "~0.3.4", + "topcoat-textarea-base": "~0.3.2", + "topcoat-notification": "~0.1.1", + "topcoat-notification-base": "0.0.1", + "topcoat-tab-bar": "~0.1.0", + "topcoat-switch": "~0.1.3", + "topcoat-switch-base": "~0.1.0", + "topcoat-range-base": "0.0.3", + "topcoat-range": "~0.1.0" + }, + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-copy": "~0.4.1", + "grunt-contrib-jade": "~0.4.0", + "grunt-contrib-watch": "~0.1.4", + "grunt-contrib-clean": "~0.4.1", + "grunt-exec": "~0.4.2", + "grunt-contrib-cssmin": "~0.5.0", + "jade": "~0.28.2", + "grunt-contrib-stylus": "~0.6.0", + "grunt-contrib-htmlmin": "~0.1.3", + "prompt": "*", + "csv": "*", + "topdoc-theme": "~0.2.7", + "grunt-topdoc": "~0.1.3", + "grunt-autoprefixer": "~0.2.20130806" + }, + "scripts": { + "test": "grunt test", + "prepublish": "grunt" + }, + "repository": { + "type": "git", + "url": "git://github.com/topcoat/topcoat.git" + }, + "bugs": { + "url": "https://github.com/topcoat/topcoat/issues" + }, + "license": { + "type": "Apache", + "url": "https://github.com/topcoat/topcoat/blob/master/LICENSE" + }, + "keywords": [ + "css", + "ui", + "ux", + "pattern", + "library", + "mobile", + "desktop", + "native", + "application", + "web", + "standards" + ] +} diff --git a/platforms/android/platform_www/cordova-js-src/platform.js b/platforms/android/platform_www/cordova-js-src/platform.js index bffc675..2bfd024 100644 --- a/platforms/android/platform_www/cordova-js-src/platform.js +++ b/platforms/android/platform_www/cordova-js-src/platform.js @@ -19,6 +19,9 @@ * */ +// The last resume event that was received that had the result of a plugin call. +var lastResumeEvent = null; + module.exports = { id: 'android', bootstrap: function() { @@ -58,6 +61,19 @@ module.exports = { bindButtonChannel('volumeup'); bindButtonChannel('volumedown'); + // The resume event is not "sticky", but it is possible that the event + // will contain the result of a plugin call. We need to ensure that the + // plugin result is delivered even after the event is fired (CB-10498) + var cordovaAddEventListener = document.addEventListener; + + document.addEventListener = function(evt, handler, capture) { + cordovaAddEventListener(evt, handler, capture); + + if (evt === 'resume' && lastResumeEvent) { + handler(lastResumeEvent); + } + }; + // Let native code know we are all done on the JS side. // Native code will then un-hide the WebView. channel.onCordovaReady.subscribe(function() { @@ -79,12 +95,30 @@ function onMessageFromNative(msg) { case 'searchbutton': // App life cycle events case 'pause': - case 'resume': // Volume events case 'volumedownbutton': case 'volumeupbutton': cordova.fireDocumentEvent(action); break; + case 'resume': + if(arguments.length > 1 && msg.pendingResult) { + if(arguments.length === 2) { + msg.pendingResult.result = arguments[1]; + } else { + // The plugin returned a multipart message + var res = []; + for(var i = 1; i < arguments.length; i++) { + res.push(arguments[i]); + } + msg.pendingResult.result = res; + } + + // Save the plugin result so that it can be delivered to the js + // even if they miss the initial firing of the event + lastResumeEvent = msg; + } + cordova.fireDocumentEvent(action, msg); + break; default: throw new Error('Unknown event action ' + action); } diff --git a/platforms/android/platform_www/cordova.js b/platforms/android/platform_www/cordova.js index 23f6e47..e94e0f7 100644 --- a/platforms/android/platform_www/cordova.js +++ b/platforms/android/platform_www/cordova.js @@ -1,5 +1,5 @@ // Platform: android -// 2c29e187e4206a6a77fba940ef6f77aef5c7eb8c +// c517ca811b4948b630e0b74dbae6c9637939da24 /* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file @@ -19,7 +19,7 @@ under the License. */ ;(function() { -var PLATFORM_VERSION_BUILD_LABEL = '4.1.1'; +var PLATFORM_VERSION_BUILD_LABEL = '5.1.1'; // file: src/scripts/require.js /*jshint -W079 */ @@ -101,7 +101,9 @@ if (typeof module === "object" && typeof require === "function") { // file: src/cordova.js define("cordova", function(require, exports, module) { -if(window.cordova){ +// Workaround for Windows 10 in hosted environment case +// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object +if (window.cordova && !(window.cordova instanceof HTMLElement)) { throw new Error("cordova already defined"); } @@ -1291,10 +1293,12 @@ define("cordova/init_b", function(require, exports, module) { var channel = require('cordova/channel'); var cordova = require('cordova'); +var modulemapper = require('cordova/modulemapper'); var platform = require('cordova/platform'); +var pluginloader = require('cordova/pluginloader'); var utils = require('cordova/utils'); -var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady]; +var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady]; // setting exec cordova.exec = require('cordova/exec'); @@ -1379,10 +1383,19 @@ if (window._nativeReady) { // Call the platform-specific initialization. platform.bootstrap && platform.bootstrap(); +// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js. +// The delay allows the attached modules to be defined before the plugin loader looks for them. +setTimeout(function() { + pluginloader.load(function() { + channel.onPluginsReady.fire(); + }); +}, 0); + /** * Create all cordova objects once native side is ready. */ channel.join(function() { + modulemapper.mapModules(window); platform.initialize && platform.initialize(); @@ -1499,11 +1512,111 @@ exports.getOriginalSymbol = function(context, symbolPath) { exports.reset(); +}); + +// file: src/common/modulemapper_b.js +define("cordova/modulemapper_b", function(require, exports, module) { + +var builder = require('cordova/builder'), + symbolList = [], + deprecationMap; + +exports.reset = function() { + symbolList = []; + deprecationMap = {}; +}; + +function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) { + symbolList.push(strategy, moduleName, symbolPath); + if (opt_deprecationMessage) { + deprecationMap[symbolPath] = opt_deprecationMessage; + } +} + +// Note: Android 2.3 does have Function.bind(). +exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) { + addEntry('c', moduleName, symbolPath, opt_deprecationMessage); +}; + +exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) { + addEntry('m', moduleName, symbolPath, opt_deprecationMessage); +}; + +exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) { + addEntry('d', moduleName, symbolPath, opt_deprecationMessage); +}; + +exports.runs = function(moduleName) { + addEntry('r', moduleName, null); +}; + +function prepareNamespace(symbolPath, context) { + if (!symbolPath) { + return context; + } + var parts = symbolPath.split('.'); + var cur = context; + for (var i = 0, part; part = parts[i]; ++i) { + cur = cur[part] = cur[part] || {}; + } + return cur; +} + +exports.mapModules = function(context) { + var origSymbols = {}; + context.CDV_origSymbols = origSymbols; + for (var i = 0, len = symbolList.length; i < len; i += 3) { + var strategy = symbolList[i]; + var moduleName = symbolList[i + 1]; + var module = require(moduleName); + // + if (strategy == 'r') { + continue; + } + var symbolPath = symbolList[i + 2]; + var lastDot = symbolPath.lastIndexOf('.'); + var namespace = symbolPath.substr(0, lastDot); + var lastName = symbolPath.substr(lastDot + 1); + + var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null; + var parentObj = prepareNamespace(namespace, context); + var target = parentObj[lastName]; + + if (strategy == 'm' && target) { + builder.recursiveMerge(target, module); + } else if ((strategy == 'd' && !target) || (strategy != 'd')) { + if (!(symbolPath in origSymbols)) { + origSymbols[symbolPath] = target; + } + builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg); + } + } +}; + +exports.getOriginalSymbol = function(context, symbolPath) { + var origSymbols = context.CDV_origSymbols; + if (origSymbols && (symbolPath in origSymbols)) { + return origSymbols[symbolPath]; + } + var parts = symbolPath.split('.'); + var obj = context; + for (var i = 0; i < parts.length; ++i) { + obj = obj && obj[parts[i]]; + } + return obj; +}; + +exports.reset(); + + }); // file: /Users/steveng/repo/cordova/cordova-android/cordova-js-src/platform.js define("cordova/platform", function(require, exports, module) { +// The last resume event that was received that had the result of a plugin call. +var lastResumeEvent = null; + module.exports = { id: 'android', bootstrap: function() { @@ -1543,6 +1656,19 @@ module.exports = { bindButtonChannel('volumeup'); bindButtonChannel('volumedown'); + // The resume event is not "sticky", but it is possible that the event + // will contain the result of a plugin call. We need to ensure that the + // plugin result is delivered even after the event is fired (CB-10498) + var cordovaAddEventListener = document.addEventListener; + + document.addEventListener = function(evt, handler, capture) { + cordovaAddEventListener(evt, handler, capture); + + if (evt === 'resume' && lastResumeEvent) { + handler(lastResumeEvent); + } + }; + // Let native code know we are all done on the JS side. // Native code will then un-hide the WebView. channel.onCordovaReady.subscribe(function() { @@ -1564,12 +1690,30 @@ function onMessageFromNative(msg) { case 'searchbutton': // App life cycle events case 'pause': - case 'resume': // Volume events case 'volumedownbutton': case 'volumeupbutton': cordova.fireDocumentEvent(action); break; + case 'resume': + if(arguments.length > 1 && msg.pendingResult) { + if(arguments.length === 2) { + msg.pendingResult.result = arguments[1]; + } else { + // The plugin returned a multipart message + var res = []; + for(var i = 1; i < arguments.length; i++) { + res.push(arguments[i]); + } + msg.pendingResult.result = res; + } + + // Save the plugin result so that it can be delivered to the js + // even if they miss the initial firing of the event + lastResumeEvent = msg; + } + cordova.fireDocumentEvent(action, msg); + break; default: throw new Error('Unknown event action ' + action); } @@ -1673,10 +1817,6 @@ module.exports = { // file: src/common/pluginloader.js define("cordova/pluginloader", function(require, exports, module) { -/* - NOTE: this file is NOT used when we use the browserify workflow -*/ - var modulemapper = require('cordova/modulemapper'); var urlutil = require('cordova/urlutil'); @@ -1784,6 +1924,54 @@ exports.load = function(callback) { }; +}); + +// file: src/common/pluginloader_b.js +define("cordova/pluginloader_b", function(require, exports, module) { + +var modulemapper = require('cordova/modulemapper'); + +// Handler for the cordova_plugins.js content. +// See plugman's plugin_loader.js for the details of this object. +function handlePluginsObject(moduleList) { + // if moduleList is not defined or empty, we've nothing to do + if (!moduleList || !moduleList.length) { + return; + } + + // Loop through all the modules and then through their clobbers and merges. + for (var i = 0, module; module = moduleList[i]; i++) { + if (module.clobbers && module.clobbers.length) { + for (var j = 0; j < module.clobbers.length; j++) { + modulemapper.clobbers(module.id, module.clobbers[j]); + } + } + + if (module.merges && module.merges.length) { + for (var k = 0; k < module.merges.length; k++) { + modulemapper.merges(module.id, module.merges[k]); + } + } + + // Finally, if runs is truthy we want to simply require() the module. + if (module.runs) { + modulemapper.runs(module.id); + } + } +} + +// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle +// but the method accepts callback to be compatible with non-browserify flow. +// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are +// no plugins to load, or they are all done. +exports.load = function(callback) { + var moduleList = require("cordova/plugin_list"); + handlePluginsObject(moduleList); + + callback(); +}; + + }); // file: src/common/urlutil.js diff --git a/platforms/android/platform_www/cordova_plugins.js b/platforms/android/platform_www/cordova_plugins.js index 3d13c71..25c72bb 100644 --- a/platforms/android/platform_www/cordova_plugins.js +++ b/platforms/android/platform_www/cordova_plugins.js @@ -1,25 +1,37 @@ cordova.define('cordova/plugin_list', function(require, exports, module) { module.exports = [ + { + "file": "plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js", + "id": "at.gofg.sportscomputer.powermanagement.device", + "clobbers": [ + "window.powerManagement" + ] + }, { "file": "plugins/com.lampa.startapp/www/startApp.js", "id": "com.lampa.startapp.startapp", - "pluginId": "com.lampa.startapp", "merges": [ "navigator.startApp" ] }, { - "file": "plugins/com.shukriadams.micVolume/www/micVolume.js", - "id": "com.shukriadams.micVolume.MicVolume", - "pluginId": "com.shukriadams.micVolume", + "file": "plugins/cordova-plugin-device/www/device.js", + "id": "cordova-plugin-device.device", "clobbers": [ - "window.micVolume" + "device" + ] + }, + { + "file": "plugins/cordova-plugin-background-mode/www/background-mode.js", + "id": "cordova-plugin-background-mode.BackgroundMode", + "clobbers": [ + "cordova.plugins.backgroundMode", + "plugin.backgroundMode" ] }, { "file": "plugins/cordova-plugin-device-motion/www/Acceleration.js", "id": "cordova-plugin-device-motion.Acceleration", - "pluginId": "cordova-plugin-device-motion", "clobbers": [ "Acceleration" ] @@ -27,21 +39,13 @@ module.exports = [ { "file": "plugins/cordova-plugin-device-motion/www/accelerometer.js", "id": "cordova-plugin-device-motion.accelerometer", - "pluginId": "cordova-plugin-device-motion", "clobbers": [ "navigator.accelerometer" ] }, - { - "file": "plugins/cordova-plugin-whitelist/whitelist.js", - "id": "cordova-plugin-whitelist.whitelist", - "pluginId": "cordova-plugin-whitelist", - "runs": true - }, { "file": "plugins/cordova-plugin-dialogs/www/notification.js", "id": "cordova-plugin-dialogs.notification", - "pluginId": "cordova-plugin-dialogs", "merges": [ "navigator.notification" ] @@ -49,48 +53,87 @@ module.exports = [ { "file": "plugins/cordova-plugin-dialogs/www/android/notification.js", "id": "cordova-plugin-dialogs.notification_android", - "pluginId": "cordova-plugin-dialogs", "merges": [ "navigator.notification" ] }, { - "file": "plugins/cordova-plugin-device/www/device.js", - "id": "cordova-plugin-device.device", - "pluginId": "cordova-plugin-device", + "file": "plugins/cordova-plugin-whitelist/whitelist.js", + "id": "cordova-plugin-whitelist.whitelist", + "runs": true + }, + { + "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js", + "id": "de.appplant.cordova.plugin.local-notification.LocalNotification", "clobbers": [ - "device" + "cordova.plugins.notification.local", + "plugin.notification.local" ] }, { - "file": "plugins/cordova-plugin-background-mode/www/background-mode.js", - "id": "cordova-plugin-background-mode.BackgroundMode", - "pluginId": "cordova-plugin-background-mode", + "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js", + "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Core", "clobbers": [ - "cordova.plugins.backgroundMode", - "plugin.backgroundMode" + "cordova.plugins.notification.local.core", + "plugin.notification.local.core" ] }, { - "file": "plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js", - "id": "at.gofg.sportscomputer.powermanagement.device", - "pluginId": "at.gofg.sportscomputer.powermanagement", + "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js", + "id": "de.appplant.cordova.plugin.local-notification.LocalNotification.Util", + "merges": [ + "cordova.plugins.notification.local.core", + "plugin.notification.local.core" + ] + }, + { + "file": "plugins/cordova-plugin-device-tests/tests.js", + "id": "cordova-plugin-device-tests.tests" + }, + { + "file": "plugins/cordova-plugin-device-motion-tests/tests.js", + "id": "cordova-plugin-device-motion-tests.tests" + }, + { + "file": "plugins/cordova-plugin-test-framework/www/tests.js", + "id": "cordova-plugin-test-framework.cdvtests" + }, + { + "file": "plugins/cordova-plugin-test-framework/www/jasmine_helpers.js", + "id": "cordova-plugin-test-framework.jasmine_helpers" + }, + { + "file": "plugins/cordova-plugin-test-framework/www/medic.js", + "id": "cordova-plugin-test-framework.medic" + }, + { + "file": "plugins/cordova-plugin-test-framework/www/main.js", + "id": "cordova-plugin-test-framework.main" + }, + { + "file": "plugins/com.shukriadams.micVolume/www/micVolume.js", + "id": "com.shukriadams.micVolume.MicVolume", "clobbers": [ - "window.powerManagement" + "window.micVolume" ] } ]; module.exports.metadata = // TOP OF METADATA { + "at.gofg.sportscomputer.powermanagement": "1.1.0", "com.lampa.startapp": "0.0.5", - "com.shukriadams.micVolume": "0.1.0", - "cordova-plugin-device-motion": "1.2.0", - "cordova-plugin-whitelist": "1.2.1", - "cordova-plugin-dialogs": "1.2.0", + "cordova-plugin-app-event": "1.2.0", "cordova-plugin-device": "1.1.1", "cordova-plugin-background-mode": "0.6.5", - "at.gofg.sportscomputer.powermanagement": "1.1.0" -} + "cordova-plugin-device-motion": "1.2.0", + "cordova-plugin-dialogs": "1.2.0", + "cordova-plugin-whitelist": "1.2.1", + "de.appplant.cordova.plugin.local-notification": "0.8.4", + "cordova-plugin-device-tests": "1.1.2-dev", + "cordova-plugin-device-motion-tests": "1.2.1-dev", + "cordova-plugin-test-framework": "1.1.2-dev", + "com.shukriadams.micVolume": "0.1.0" +}; // BOTTOM OF METADATA }); \ No newline at end of file diff --git a/platforms/android/platform_www/plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js b/platforms/android/platform_www/plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js index a51c286..118dfad 100644 --- a/platforms/android/platform_www/plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js +++ b/platforms/android/platform_www/plugins/at.gofg.sportscomputer.powermanagement/www/powermanagement.js @@ -1,4 +1,5 @@ -cordova.define("at.gofg.sportscomputer.powermanagement.device", function(require, exports, module) { /* +cordova.define("at.gofg.sportscomputer.powermanagement.device", function(require, exports, module) { +/* * Copyright 2013 Wolfgang Koller * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/platforms/android/platform_www/plugins/com.lampa.startapp/www/startApp.js b/platforms/android/platform_www/plugins/com.lampa.startapp/www/startApp.js index a1c89f2..2ff7912 100644 --- a/platforms/android/platform_www/plugins/com.lampa.startapp/www/startApp.js +++ b/platforms/android/platform_www/plugins/com.lampa.startapp/www/startApp.js @@ -1,4 +1,5 @@ -cordova.define("com.lampa.startapp.startapp", function(require, exports, module) { /** +cordova.define("com.lampa.startapp.startapp", function(require, exports, module) { +/** com.lampa.startapp https://github.com/lampaa/com.lampa.startapp diff --git a/platforms/android/platform_www/plugins/com.shukriadams.micVolume/www/micVolume.js b/platforms/android/platform_www/plugins/com.shukriadams.micVolume/www/micVolume.js index 7d95be1..3479043 100644 --- a/platforms/android/platform_www/plugins/com.shukriadams.micVolume/www/micVolume.js +++ b/platforms/android/platform_www/plugins/com.shukriadams.micVolume/www/micVolume.js @@ -1,4 +1,5 @@ -cordova.define("com.shukriadams.micVolume.MicVolume", function(require, exports, module) { var micVolume = { +cordova.define("com.shukriadams.micVolume.MicVolume", function(require, exports, module) { +var micVolume = { start: function(successCallback, errorCallback) { cordova.exec( successCallback, // success callback function diff --git a/platforms/android/platform_www/plugins/cordova-plugin-background-mode/www/background-mode.js b/platforms/android/platform_www/plugins/cordova-plugin-background-mode/www/background-mode.js index 86355df..98b3645 100644 --- a/platforms/android/platform_www/plugins/cordova-plugin-background-mode/www/background-mode.js +++ b/platforms/android/platform_www/plugins/cordova-plugin-background-mode/www/background-mode.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-background-mode.BackgroundMode", function(require, exports, module) { /* +cordova.define("cordova-plugin-background-mode.BackgroundMode", function(require, exports, module) { +/* Copyright 2013-2014 appPlant UG Licensed to the Apache Software Foundation (ASF) under one diff --git a/platforms/android/platform_www/plugins/cordova-plugin-device-motion-tests/tests.js b/platforms/android/platform_www/plugins/cordova-plugin-device-motion-tests/tests.js new file mode 100644 index 0000000..892ca60 --- /dev/null +++ b/platforms/android/platform_www/plugins/cordova-plugin-device-motion-tests/tests.js @@ -0,0 +1,367 @@ +cordova.define("cordova-plugin-device-motion-tests.tests", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint jasmine: true */ +/* global Windows */ + +exports.defineAutoTests = function () { + var isWindows = (cordova.platformId === "windows") || (cordova.platformId === "windows8"), + // Checking existence of accelerometer for windows platform + // Assumed that accelerometer always exists on other platforms. Extend + // condition to support accelerometer check on other platforms + isAccelExist = isWindows ? Windows.Devices.Sensors.Accelerometer.getDefault() !== null : true; + + describe('Accelerometer (navigator.accelerometer)', function () { + var fail = function(done) { + expect(true).toBe(false); + done(); + }; + + // This timeout is here to lessen the load on native accelerometer + // intensive use of which can lead to occasional test failures + afterEach(function(done) { + setTimeout(function() { + done(); + }, 100); + }); + + it("accelerometer.spec.1 should exist", function () { + expect(navigator.accelerometer).toBeDefined(); + }); + + describe("getCurrentAcceleration", function() { + it("accelerometer.spec.2 should exist", function() { + expect(typeof navigator.accelerometer.getCurrentAcceleration).toBeDefined(); + expect(typeof navigator.accelerometer.getCurrentAcceleration == 'function').toBe(true); + }); + + it("accelerometer.spec.3 success callback should be called with an Acceleration object", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var win = function(a) { + expect(a).toBeDefined(); + expect(a.x).toBeDefined(); + expect(typeof a.x == 'number').toBe(true); + expect(a.y).toBeDefined(); + expect(typeof a.y == 'number').toBe(true); + expect(a.z).toBeDefined(); + expect(typeof a.z == 'number').toBe(true); + expect(a.timestamp).toBeDefined(); + expect(typeof a.timestamp).toBe('number'); + done(); + }; + + var onError = function(err){ + console.log(err); + console.log("Skipping gyroscope tests, marking all as pending."); + isAccelExist = false; + expect(true).toBe(true); + done(); + }; + + navigator.accelerometer.getCurrentAcceleration(win, onError); + }); + + it("accelerometer.spec.4 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var reasonableThreshold = 15; + var win = function(a) { + expect(a.x).toBeLessThan(reasonableThreshold); + expect(a.x).toBeGreaterThan(reasonableThreshold * -1); + expect(a.y).toBeLessThan(reasonableThreshold); + expect(a.y).toBeGreaterThan(reasonableThreshold * -1); + expect(a.z).toBeLessThan(reasonableThreshold); + expect(a.z).toBeGreaterThan(reasonableThreshold * -1); + done(); + }; + + navigator.accelerometer.getCurrentAcceleration(win, fail.bind(null,done)); + }); + + it("accelerometer.spec.5 success callback Acceleration object should return a recent timestamp", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var veryRecently = (new Date()).getTime(); + // Need to check that dates returned are not vastly greater than a recent time stamp. + // In case the timestamps returned are ridiculously high + var reasonableTimeLimit = veryRecently + 5000; // 5 seconds from now + var win = function(a) { + expect(a.timestamp).toBeGreaterThan(veryRecently); + expect(a.timestamp).toBeLessThan(reasonableTimeLimit); + done(); + }; + + navigator.accelerometer.getCurrentAcceleration(win, fail.bind(null,done)); + }); + }); + + describe("watchAcceleration", function() { + var id; + + afterEach(function() { + navigator.accelerometer.clearWatch(id); + }); + + it("accelerometer.spec.6 should exist", function() { + expect(navigator.accelerometer.watchAcceleration).toBeDefined(); + expect(typeof navigator.accelerometer.watchAcceleration == 'function').toBe(true); + }); + + it("accelerometer.spec.7 success callback should be called with an Acceleration object", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var win = function(a) { + expect(a).toBeDefined(); + expect(a.x).toBeDefined(); + expect(typeof a.x == 'number').toBe(true); + expect(a.y).toBeDefined(); + expect(typeof a.y == 'number').toBe(true); + expect(a.z).toBeDefined(); + expect(typeof a.z == 'number').toBe(true); + expect(a.timestamp).toBeDefined(); + expect(typeof a.timestamp).toBe('number'); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null,done), {frequency:100}); + }); + + it("accelerometer.spec.8 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var reasonableThreshold = 15; + var win = function(a) { + expect(a.x).toBeLessThan(reasonableThreshold); + expect(a.x).toBeGreaterThan(reasonableThreshold * -1); + expect(a.y).toBeLessThan(reasonableThreshold); + expect(a.y).toBeGreaterThan(reasonableThreshold * -1); + expect(a.z).toBeLessThan(reasonableThreshold); + expect(a.z).toBeGreaterThan(reasonableThreshold * -1); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null,done), {frequency:100}); + }); + + it("accelerometer.spec.9 success callback Acceleration object should return a recent timestamp", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var veryRecently = (new Date()).getTime(); + // Need to check that dates returned are not vastly greater than a recent time stamp. + // In case the timestamps returned are ridiculously high + var reasonableTimeLimit = veryRecently + 5000; // 5 seconds from now + var win = function(a) { + expect(a.timestamp).toBeGreaterThan(veryRecently); + expect(a.timestamp).toBeLessThan(reasonableTimeLimit); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null,done), {frequency:100}); + }); + + it("accelerometer.spec.12 success callback should be preserved and called several times", function (done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var callbacksCallCount = 0, + callbacksCallTestCount = 3; + + var win = function (a) { + if (callbacksCallCount++ < callbacksCallTestCount) return; + expect(typeof a).toBe('object'); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null, done), { frequency: 100 }); + }); + }); + + describe("clearWatch", function() { + it("accelerometer.spec.10 should exist", function() { + expect(navigator.accelerometer.clearWatch).toBeDefined(); + expect(typeof navigator.accelerometer.clearWatch == 'function').toBe(true); + }); + + it("accelerometer.spec.11 should clear an existing watch", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var id; + + // expect win to get called exactly once + var win = function(a) { + // clear watch on first call + navigator.accelerometer.clearWatch(id); + // if win isn't called again in 201 ms we assume success + var tid = setTimeout(function() { + expect(true).toBe(true); + done(); + }, 101); + // if win is called again, clear the timeout and fail the test + win = function() { + clearTimeout(tid); + fail(done); + }; + }; + + // wrap the success call in a closure since the value of win changes between calls + id = navigator.accelerometer.watchAcceleration(function() { win(); }, fail.bind(null, done), {frequency:100}); + }); + }); + }); +}; + +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +exports.defineManualTests = function (contentEl, createActionButton) { + function roundNumber(num) { + var dec = 3; + var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); + return result; + } + + var watchAccelId = null; + + /** + * Set accelerometer status + */ + function setAccelStatus(status) { + document.getElementById('accel_status').innerHTML = status; + } + + /** + * Stop watching the acceleration + */ + function stopAccel() { + console.log("stopAccel()"); + setAccelStatus("Stopped"); + if (watchAccelId) { + navigator.accelerometer.clearWatch(watchAccelId); + watchAccelId = null; + } + } + + /** + * Start watching acceleration + */ + var watchAccel = function () { + console.log("watchAccel()"); + + // Success callback + var success = function (a) { + document.getElementById('x').innerHTML = roundNumber(a.x); + document.getElementById('y').innerHTML = roundNumber(a.y); + document.getElementById('z').innerHTML = roundNumber(a.z); + }; + + // Fail callback + var fail = function (e) { + console.log("watchAccel fail callback with error code " + e); + stopAccel(); + setAccelStatus(e); + }; + + // Update acceleration every 1 sec + var opt = {}; + opt.frequency = 1000; + watchAccelId = navigator.accelerometer.watchAcceleration(success, fail, opt); + + setAccelStatus("Running"); + }; + + /** + * Get current acceleration + */ + var getAccel = function () { + console.log("getAccel()"); + + // Stop accel if running + stopAccel(); + + // Success callback + var success = function (a) { + document.getElementById('x').innerHTML = roundNumber(a.x); + document.getElementById('y').innerHTML = roundNumber(a.y); + document.getElementById('z').innerHTML = roundNumber(a.z); + console.log("getAccel success callback"); + }; + + // Fail callback + var fail = function (e) { + console.log("getAccel fail callback with error code " + e); + setAccelStatus(e); + }; + + // Make call + var opt = {}; + navigator.accelerometer.getCurrentAcceleration(success, fail, opt); + }; + + /******************************************************************************/ + + var accelerometer_tests = '
    ' + + 'Expected result: Will update the status box with X, Y, and Z values when pressed. Status will read "Stopped"' + + '

    ' + + 'Expected result: When pressed, will start a watch on the accelerometer and update X,Y,Z values when movement is sensed. Status will read "Running"' + + '

    ' + + 'Expected result: Will clear the accelerometer watch, so X,Y,Z values will no longer be updated. Status will read "Stopped"'; + + contentEl.innerHTML = '
    ' + + 'Status: Stopped' + + '' + + '' + + '' + + '' + + '
    X:
    Y:
    Z:
    ' + + accelerometer_tests; + + createActionButton('Get Acceleration', function () { + getAccel(); + }, 'getAcceleration'); + + createActionButton('Start Watch', function () { + watchAccel(); + }, 'watchAcceleration'); + + createActionButton('Clear Watch', function () { + stopAccel(); + }, 'clearAcceleration'); +}; + +}); diff --git a/platforms/android/platform_www/plugins/cordova-plugin-device-motion/www/Acceleration.js b/platforms/android/platform_www/plugins/cordova-plugin-device-motion/www/Acceleration.js index fd4ea4e..794476b 100644 --- a/platforms/android/platform_www/plugins/cordova-plugin-device-motion/www/Acceleration.js +++ b/platforms/android/platform_www/plugins/cordova-plugin-device-motion/www/Acceleration.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-device-motion.Acceleration", function(require, exports, module) { /* +cordova.define("cordova-plugin-device-motion.Acceleration", function(require, exports, module) { +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/platforms/android/platform_www/plugins/cordova-plugin-device-motion/www/accelerometer.js b/platforms/android/platform_www/plugins/cordova-plugin-device-motion/www/accelerometer.js index ddd7a57..01f533a 100644 --- a/platforms/android/platform_www/plugins/cordova-plugin-device-motion/www/accelerometer.js +++ b/platforms/android/platform_www/plugins/cordova-plugin-device-motion/www/accelerometer.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-device-motion.accelerometer", function(require, exports, module) { /* +cordova.define("cordova-plugin-device-motion.accelerometer", function(require, exports, module) { +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/platforms/android/platform_www/plugins/cordova-plugin-device-tests/tests.js b/platforms/android/platform_www/plugins/cordova-plugin-device-tests/tests.js new file mode 100644 index 0000000..9687554 --- /dev/null +++ b/platforms/android/platform_www/plugins/cordova-plugin-device-tests/tests.js @@ -0,0 +1,116 @@ +cordova.define("cordova-plugin-device-tests.tests", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint jasmine: true */ + +exports.defineAutoTests = function() { + describe('Device Information (window.device)', function () { + it("should exist", function() { + expect(window.device).toBeDefined(); + }); + + it("should contain a platform specification that is a string", function() { + expect(window.device.platform).toBeDefined(); + expect((String(window.device.platform)).length > 0).toBe(true); + }); + + it("should contain a version specification that is a string", function() { + expect(window.device.version).toBeDefined(); + expect((String(window.device.version)).length > 0).toBe(true); + }); + + it("should contain a UUID specification that is a string or a number", function() { + expect(window.device.uuid).toBeDefined(); + if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') { + expect((String(window.device.uuid)).length > 0).toBe(true); + } else { + expect(window.device.uuid > 0).toBe(true); + } + }); + + it("should contain a cordova specification that is a string", function() { + expect(window.device.cordova).toBeDefined(); + expect((String(window.device.cordova)).length > 0).toBe(true); + }); + + it("should depend on the presence of cordova.version string", function() { + expect(window.cordova.version).toBeDefined(); + expect((String(window.cordova.version)).length > 0).toBe(true); + }); + + it("should contain device.cordova equal to cordova.version", function() { + expect(window.device.cordova).toBe(window.cordova.version); + }); + + it("should contain a model specification that is a string", function() { + expect(window.device.model).toBeDefined(); + expect((String(window.device.model)).length > 0).toBe(true); + }); + + it("should contain a manufacturer property that is a string", function() { + expect(window.device.manufacturer).toBeDefined(); + expect((String(window.device.manufacturer)).length > 0).toBe(true); + }); + + it("should contain an isVirtual property that is a boolean", function() { + expect(window.device.isVirtual).toBeDefined(); + expect(typeof window.device.isVirtual).toBe("boolean"); + }); + + it("should contain a serial number specification that is a string", function() { + expect(window.device.serial).toBeDefined(); + expect((String(window.device.serial)).length > 0).toBe(true); + + }); + + }); +}; + +exports.defineManualTests = function(contentEl, createActionButton) { + var logMessage = function (message, color) { + var log = document.getElementById('info'); + var logLine = document.createElement('div'); + if (color) { + logLine.style.color = color; + } + logLine.innerHTML = message; + log.appendChild(logLine); + }; + + var clearLog = function () { + var log = document.getElementById('info'); + log.innerHTML = ''; + }; + + var device_tests = '

    Press Dump Device button to get device information

    ' + + '
    ' + + 'Expected result: Status box will get updated with device info. (i.e. platform, version, uuid, model, etc)'; + + contentEl.innerHTML = '
    ' + device_tests; + + createActionButton('Dump device', function() { + clearLog(); + logMessage(JSON.stringify(window.device, null, '\t')); + }, "dump_device"); +}; + +}); diff --git a/platforms/android/platform_www/plugins/cordova-plugin-device/www/device.js b/platforms/android/platform_www/plugins/cordova-plugin-device/www/device.js index ff0c5b4..977dfc0 100644 --- a/platforms/android/platform_www/plugins/cordova-plugin-device/www/device.js +++ b/platforms/android/platform_www/plugins/cordova-plugin-device/www/device.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-device.device", function(require, exports, module) { /* +cordova.define("cordova-plugin-device.device", function(require, exports, module) { +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/platforms/android/platform_www/plugins/cordova-plugin-dialogs/www/android/notification.js b/platforms/android/platform_www/plugins/cordova-plugin-dialogs/www/android/notification.js index 07b9237..69cb5a4 100644 --- a/platforms/android/platform_www/plugins/cordova-plugin-dialogs/www/android/notification.js +++ b/platforms/android/platform_www/plugins/cordova-plugin-dialogs/www/android/notification.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-dialogs.notification_android", function(require, exports, module) { /* +cordova.define("cordova-plugin-dialogs.notification_android", function(require, exports, module) { +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/platforms/android/platform_www/plugins/cordova-plugin-dialogs/www/notification.js b/platforms/android/platform_www/plugins/cordova-plugin-dialogs/www/notification.js index b7236a2..3787c0f 100644 --- a/platforms/android/platform_www/plugins/cordova-plugin-dialogs/www/notification.js +++ b/platforms/android/platform_www/plugins/cordova-plugin-dialogs/www/notification.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-dialogs.notification", function(require, exports, module) { /* +cordova.define("cordova-plugin-dialogs.notification", function(require, exports, module) { +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file diff --git a/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/jasmine_helpers.js b/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/jasmine_helpers.js new file mode 100644 index 0000000..a77be0e --- /dev/null +++ b/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/jasmine_helpers.js @@ -0,0 +1,86 @@ +cordova.define("cordova-plugin-test-framework.jasmine_helpers", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint -W097 */ +'use strict'; + +exports.setUpJasmine = function() { + // Set up jasmine + var jasmine = jasmineRequire.core(jasmineRequire); + jasmineRequire.html(jasmine); + var jasmineEnv = jasmine.currentEnv_ = new jasmine.Env(); + + jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; + jasmineEnv.catchExceptions(false); + + // Set up jasmine interface + var jasmineInterface = jasmineRequire.interface(jasmine, jasmineEnv); + + // Add Reporters + addJasmineReporters(jasmineInterface, jasmineEnv); + + // Add Spec Filter + jasmineEnv.specFilter = function(spec) { + //console.log(spec.getFullName()); + return true; + }; + + // Jasmine 2.2.0 moved this symbol, so we add a shim here. + jasmine.Expectation.addMatchers = jasmine.Expectation.addMatchers || function() { + return jasmine.addMatchers.apply(this, arguments); + }; + + return jasmineInterface; +}; + +function addJasmineReporters(jasmineInterface, jasmineEnv) { + jasmineInterface.jsApiReporter = new jasmineInterface.jasmine.JsApiReporter({ timer: new jasmineInterface.jasmine.Timer() }); + jasmineEnv.addReporter(jasmineInterface.jsApiReporter); + + jasmineInterface.htmlReporter = new jasmineInterface.jasmine.HtmlReporter({ + env: jasmineEnv, + queryString: function() { return null; }, + onRaiseExceptionsClick: function() { }, + getContainer: function() { return document.getElementById('content'); }, + createElement: function() { return document.createElement.apply(document, arguments); }, + createTextNode: function() { return document.createTextNode.apply(document, arguments); }, + timer: new jasmineInterface.jasmine.Timer() + }); + jasmineInterface.htmlReporter.initialize(); + jasmineEnv.addReporter(jasmineInterface.htmlReporter); + + var medic = require('cordova-plugin-test-framework.medic'); + + if (medic.enabled) { + jasmineRequire.medic(jasmineInterface.jasmine); + jasmineInterface.MedicReporter = new jasmineInterface.jasmine.MedicReporter({ + env: jasmineEnv, + log: { logurl: medic.logurl }, + sha: medic.sha + }); + jasmineInterface.MedicReporter.initialize(); + jasmineEnv.addReporter(jasmineInterface.MedicReporter); + } + +} + +}); diff --git a/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/main.js b/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/main.js new file mode 100644 index 0000000..c3e1aa4 --- /dev/null +++ b/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/main.js @@ -0,0 +1,449 @@ +cordova.define("cordova-plugin-test-framework.main", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* global WinJS */ +/* jshint -W097 */ +'use strict'; + +var LOG_HEADER_HEIGHT = 20, + CONTENT_TOP_OFFSET = 30; + +var isWin = cordova.platformId === "windows", + isWP8 = cordova.platformId === "windowsphone"; + +/******************************************************************************/ + +function getMode(callback) { + var mode = localStorage.getItem('cdvtests-mode') || 'main'; + callback(mode); +} + +function setMode(mode) { + var handlers = { + 'main': runMain, + 'auto': runAutoTests, + 'manual': runManualTests + }; + if (!handlers.hasOwnProperty(mode)) { + console.error("Unsupported mode: " + mode); + console.error("Defaulting to 'main'"); + mode = 'main'; + } + + localStorage.setItem('cdvtests-mode', mode); + clearContent(); + + handlers[mode](); +} + +/******************************************************************************/ + +function clearContent() { + var content = document.getElementById('content'); + content.innerHTML = ''; + var log = document.getElementById('log--content'); + log.innerHTML = ''; + var buttons = document.getElementById('buttons'); + buttons.innerHTML = ''; + + setLogVisibility(false); +} + +/******************************************************************************/ + +function setTitle(title) { + var el = document.getElementById('title'); + el.textContent = title; +} + +/******************************************************************************/ + +function setLogVisibility(visible) { + if (visible) { + document.querySelector('body').classList.add('expanded-log'); + + if (isWin || isWP8) { + var h = document.querySelector('body').offsetHeight; + + document.getElementById('middle').style.height = (h * 0.6 - LOG_HEADER_HEIGHT - CONTENT_TOP_OFFSET) + "px"; + document.getElementById('middle').style.marginBottom = (h * 0.4) + "px"; + document.getElementById('middle').style.paddingBottom = (h * 0.4) + "px"; + } + } else { + document.querySelector('body').classList.remove('expanded-log'); + + if (isWin || isWP8) { + document.getElementById('middle').style.height = ""; + document.getElementById('middle').style.marginBottom = ""; + document.getElementById('middle').style.paddingBottom = ""; + } + } +} + +window.onresize = function (event) { + // Update content and log heights + if (isWin || isWP8) { + setLogVisibility(getLogVisibility()); + } +}; + +function getLogVisibility() { + var e = document.querySelector('body'); + return e.classList.contains('expanded-log'); +} + +function toggleLogVisibility() { + if (getLogVisibility()) { + setLogVisibility(false); + } else { + setLogVisibility(true); + } +} + +/******************************************************************************/ + +function attachEvents() { + document.getElementById('log--title').addEventListener('click', toggleLogVisibility); +} + +/******************************************************************************/ + +var origConsole = window.console; + +exports.wrapConsole = function() { + function appendToOnscreenLog(type, args) { + var el = document.getElementById('log--content'); + var div = document.createElement('div'); + div.classList.add('log--content--line'); + div.classList.add('log--content--line--' + type); + div.textContent = Array.prototype.slice.apply(args).map(function(arg) { + return (typeof arg === 'string') ? arg : JSON.stringify(arg); + }).join(' '); + el.appendChild(div); + // scroll to bottom + el.scrollTop = el.scrollHeight; + } + + function createCustomLogger(type) { + var medic = require('cordova-plugin-test-framework.medic'); + return function() { + origConsole[type].apply(origConsole, arguments); + // TODO: encode log type somehow for medic logs? + medic.log.apply(medic, arguments); + appendToOnscreenLog(type, arguments); + setLogVisibility(true); + }; + } + + window.console = { + log: createCustomLogger('log'), + warn: createCustomLogger('warn'), + error: createCustomLogger('error'), + }; +}; + +exports.unwrapConsole = function() { + window.console = origConsole; +}; + +/******************************************************************************/ + +function createActionButton(title, callback, appendTo) { + appendTo = appendTo ? appendTo : 'buttons'; + var buttons = document.getElementById(appendTo); + var div = document.createElement('div'); + var button = document.createElement('a'); + button.textContent = title; + button.onclick = function(e) { + e.preventDefault(); + callback(); + }; + button.classList.add('topcoat-button'); + div.appendChild(button); + buttons.appendChild(div); +} + +/******************************************************************************/ + +function setupAutoTestsEnablers(cdvtests) { + var enablerList = createEnablerList(); + + // Iterate over all the registered test modules + iterateAutoTests(cdvtests, function(api, testModule) { + // For "standard" plugins remove the common/repetitive bits of + // the api key, for use as the title. For third-party plugins, the full + // api will be used as the title + var title = api.replace(/org\.apache\.cordova\./i, '').replace(/\.tests.tests/i, ''); + + createEnablerCheckbox(api, title, testModule.getEnabled(), enablerList.id, toggleTestHandler); + }); + + updateEnabledTestCount(); +} + +/******************************************************************************/ + +function createEnablerList() { + var buttons = document.getElementById('buttons'); + + var enablerContainer = document.createElement('div'); + enablerContainer.id = 'test-enablers-container'; + + // Create header to show count of enabled/total tests + var header = document.createElement('h3'); + header.id = 'tests-enabled'; + + // Create widget to show/hide list + var expander = document.createElement('span'); + expander.id = 'test-expander'; + expander.innerText = 'Show/hide tests to be run'; + expander.onclick = toggleEnablerVisibility; + + // Create list to contain checkboxes for each test + var enablerList = document.createElement('div'); + enablerList.id = "test-list"; + + // Create select/deselect all buttons (in button bar) + var checkButtonBar = document.createElement('ul'); + checkButtonBar.classList.add('topcoat-button-bar'); + + function createSelectToggleButton(title, selected) { + var barItem = document.createElement('li'); + barItem.classList.add('topcoat-button-bar__item'); + + var link = document.createElement('a'); + link.classList.add('topcoat-button-bar__button'); + link.innerText = title; + link.href = null; + link.onclick = function(e) { + e.preventDefault(); + toggleSelected(enablerList.id, selected); + return false; + }; + + barItem.appendChild(link); + checkButtonBar.appendChild(barItem); + } + createSelectToggleButton('Check all', true); + createSelectToggleButton('Uncheck all', false); + enablerList.appendChild(checkButtonBar); + + enablerContainer.appendChild(header); + enablerContainer.appendChild(expander); + enablerContainer.appendChild(enablerList); + + buttons.appendChild(enablerContainer); + + return enablerList; +} + +/******************************************************************************/ + +function updateEnabledTestCount() { + var enabledLabel = document.getElementById('tests-enabled'); + + // Determine how many tests are currently enabled + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + var total = 0; + var enabled = 0; + iterateAutoTests(cdvtests, function(api, testModule) { + total++; + if (testModule.getEnabled()) { + enabled++; + } + }); + + if (enabled == total) { + enabledLabel.innerText = 'Running All Tests.'; + } else { + enabledLabel.innerText = 'Running ' + enabled + ' of ' + total + ' Tests.'; + } +} + +/******************************************************************************/ + +function toggleSelected(containerId, newCheckedValue) { + [].forEach.call(document.getElementById(containerId).getElementsByTagName('input'), function(input) { + if (input.type !== 'checkbox') return; + input.checked = newCheckedValue; + toggleTestEnabled(input); + }); + updateEnabledTestCount(); +} + +/******************************************************************************/ + +function toggleEnablerVisibility() { + var enablerList = document.getElementById('test-list'); + if (enablerList.classList.contains('expanded')) { + enablerList.classList.remove('expanded'); + } else { + enablerList.classList.add('expanded'); + } +} + +/******************************************************************************/ + +function createEnablerCheckbox(api, title, isEnabled, appendTo, callback) { + var container = document.getElementById(appendTo); + + var label = document.createElement('label'); + label.classList.add('topcoat-checkbox'); + + var checkbox = document.createElement('input'); + checkbox.type = "checkbox"; + checkbox.value = api; + checkbox.checked = isEnabled; + label.htmlFor = checkbox.id = 'enable_' + api; + + checkbox.onchange = function(e) { + e.preventDefault(); + callback(e); + }; + + var div = document.createElement('div'); + div.classList.add('topcoat-checkbox__checkmark'); + + var text = document.createElement('span'); + text.innerText = title; + + label.appendChild(checkbox); + label.appendChild(div); + label.appendChild(text); + + container.appendChild(label); +} + +/******************************************************************************/ + +function toggleTestHandler(event) { + var checkbox = event.target; + + toggleTestEnabled(checkbox); + updateEnabledTestCount(); +} + +/******************************************************************************/ + +function toggleTestEnabled(checkbox) { + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + cdvtests.tests[checkbox.value].setEnabled(checkbox.checked); +} + +/******************************************************************************/ + +function iterateAutoTests(cdvtests, callback) { + Object.keys(cdvtests.tests).forEach(function(api) { + var testModule = cdvtests.tests[api]; + if (!testModule.hasOwnProperty('defineAutoTests')) { + return; + } + callback(api, testModule); + }); +} + +/******************************************************************************/ + +function runAutoTests() { + setTitle('Auto Tests'); + + createActionButton('Run', setMode.bind(null, 'auto')); + createActionButton('Reset App', location.reload.bind(location)); + createActionButton('Back', setMode.bind(null, 'main')); + + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + cdvtests.init(); + setupAutoTestsEnablers(cdvtests); + + cdvtests.defineAutoTests(); + + // Run the tests! + var jasmineEnv = window.jasmine.getEnv(); + + jasmineEnv.execute(); +} + +/******************************************************************************/ + +function runManualTests() { + setTitle('Manual Tests'); + + createActionButton('Reset App', location.reload.bind(location)); + createActionButton('Back', setMode.bind(null, 'main')); + + var contentEl = document.getElementById('content'); + var beforeEach = function(title) { + clearContent(); + setTitle(title || 'Manual Tests'); + createActionButton('Reset App', location.reload.bind(location)); + createActionButton('Back', setMode.bind(null, 'manual')); + }; + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + cdvtests.defineManualTests(contentEl, beforeEach, createActionButton); +} + +/******************************************************************************/ + +function runMain() { + setTitle('Apache Cordova Plugin Tests'); + + createActionButton('Auto Tests', setMode.bind(null, 'auto')); + createActionButton('Manual Tests', setMode.bind(null, 'manual')); + createActionButton('Reset App', location.reload.bind(location)); + if (/showBack/.exec(location.hash)) { + createActionButton('Back', function() { + history.go(-1); + }); + } + + if (isWin && typeof WinJS !== 'undefined') { + var app = WinJS.Application; + app.addEventListener("error", function (err) { + // We do not want an unhandled exception to crash the test app + // Returning true marks it as being handled + return true; + }); + } +} + +/******************************************************************************/ + +exports.init = function() { + // TODO: have a way to opt-out of console wrapping in case line numbers are important. + // ...Or find a custom way to print line numbers using stack or something. + // make sure to always wrap when using medic. + attachEvents(); + exports.wrapConsole(); + + var medic = require('cordova-plugin-test-framework.medic'); + medic.load(function() { + if (medic.enabled) { + setMode('auto'); + } else { + getMode(setMode); + } + }); +}; + +/******************************************************************************/ + +}); diff --git a/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/medic.js b/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/medic.js new file mode 100644 index 0000000..c805a25 --- /dev/null +++ b/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/medic.js @@ -0,0 +1,66 @@ +cordova.define("cordova-plugin-test-framework.medic", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint -W097 */ +'use strict'; + +exports.logurl = 'http://127.0.0.1:7800'; + +exports.enabled = false; + +exports.log = function() { + if (!exports.enabled) + return; + var xhr = new XMLHttpRequest(); + xhr.open("POST", exports.logurl, true); + xhr.setRequestHeader("Content-Type", "text/plain"); + xhr.send(Array.prototype.slice.apply(arguments)); +}; + +exports.load = function (callback) { + var cfg = null; + + try { + // attempt to synchronously load medic config + var xhr = new XMLHttpRequest(); + xhr.open("GET", "../medic.json", false); + xhr.send(null); + cfg = JSON.parse(xhr.responseText); + } catch (ex) { } + + // config is available + if (cfg) { + exports.logurl = cfg.couchdb || cfg.logurl; + exports.sha = cfg.sha; + exports.enabled = true; + console.log('Loaded Medic Config: logurl=' + exports.logurl); + } else { + // config does not exist + console.log('Did not find medic config file'); + } + + setTimeout(function () { + callback(); + }, 0); +}; + +}); diff --git a/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/tests.js b/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/tests.js new file mode 100644 index 0000000..5c861b3 --- /dev/null +++ b/platforms/android/platform_www/plugins/cordova-plugin-test-framework/www/tests.js @@ -0,0 +1,138 @@ +cordova.define("cordova-plugin-test-framework.cdvtests", function(require, exports, module) { +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint jasmine: true */ +/* jshint -W097 */ +'use strict'; + +exports.tests = Object.create(null); + +function TestModule(api) { + var name = api; + var enabled = true; + + var enabledPref = localStorage.getItem('cordova-tests-enabled-' + name); + if (enabledPref) + { + enabled = (enabledPref == true.toString()); + } + + this.getEnabled = function () { + return enabled; + }; + + this.setEnabled = function (isEnabled) { + enabled = isEnabled; + localStorage.setItem('cordova-tests-enabled-' + name, enabled); + }; +} + +function getTestsObject(api) { + exports.tests[api] = exports.tests[api] || new TestModule(api); + return exports.tests[api]; +} + +function requireAllTestModules() { + // This finds all js-modules named "tests" (regardless of plugins they came from) + var test_modules = cordova.require('cordova/plugin_list') + .map(function(jsmodule) { + return jsmodule.id; + }) + .filter(function(id) { + return /\.tests$/.test(id); + }); + + // Map auto / manual test definitions for each, but without actually running the handlers + test_modules.forEach(function(id) { + try { + var plugintests = cordova.require(id); + + if (plugintests.hasOwnProperty('defineAutoTests')) { + getTestsObject(id).defineAutoTests = function() { + describe(id + ' >>', plugintests.defineAutoTests.bind(plugintests)); + }; + } + + if (plugintests.hasOwnProperty('defineManualTests')) { + getTestsObject(id).defineManualTests = plugintests.defineManualTests.bind(plugintests); + } + } catch(ex) { + console.warn('Failed to load tests: ', id); + return; + } + }); +} + +function createJasmineInterface() { + var jasmine_helpers = require('cordova-plugin-test-framework.jasmine_helpers'); + var jasmineInterface = jasmine_helpers.setUpJasmine(); + return jasmineInterface; +} + +function attachJasmineInterfaceToGlobal() { + var jasmineInterface = createJasmineInterface(); + for (var property in jasmineInterface) { + window[property] = jasmineInterface[property]; + } +} + +function detachJasmineInterfaceFromGlobal() { + var jasmineInterface = createJasmineInterface(); + for (var property in jasmineInterface) { + delete window[property]; + } +} + +exports.defineAutoTests = function() { + requireAllTestModules(); + attachJasmineInterfaceToGlobal(); + + Object.keys(exports.tests).forEach(function(key) { + if (!exports.tests[key].getEnabled()) + return; + if (!exports.tests[key].hasOwnProperty('defineAutoTests')) + return; + exports.tests[key].defineAutoTests(); + }); +}; + +exports.defineManualTests = function(contentEl, beforeEach, createActionButton) { + requireAllTestModules(); + detachJasmineInterfaceFromGlobal(); + + Object.keys(exports.tests).forEach(function(key) { + if (!exports.tests[key].getEnabled()) + return; + if (!exports.tests[key].hasOwnProperty('defineManualTests')) + return; + createActionButton(key, function() { + beforeEach(key); + exports.tests[key].defineManualTests(contentEl, createActionButton); + }); + }); +}; + +exports.init = function() { + requireAllTestModules(); +}; + +}); diff --git a/platforms/android/platform_www/plugins/cordova-plugin-whitelist/whitelist.js b/platforms/android/platform_www/plugins/cordova-plugin-whitelist/whitelist.js index b83f579..a2ba8a3 100644 --- a/platforms/android/platform_www/plugins/cordova-plugin-whitelist/whitelist.js +++ b/platforms/android/platform_www/plugins/cordova-plugin-whitelist/whitelist.js @@ -1,4 +1,5 @@ -cordova.define("cordova-plugin-whitelist.whitelist", function(require, exports, module) { /* +cordova.define("cordova-plugin-whitelist.whitelist", function(require, exports, module) { +/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information diff --git a/platforms/android/platform_www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js b/platforms/android/platform_www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js new file mode 100644 index 0000000..d3807de --- /dev/null +++ b/platforms/android/platform_www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js @@ -0,0 +1,510 @@ +cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Core", function(require, exports, module) { +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +var exec = require('cordova/exec'); + + +/******** + * CORE * + ********/ + +/** + * Returns the default settings. + * + * @return {Object} + */ +exports.getDefaults = function () { + return this._defaults; +}; + +/** + * Overwrite default settings. + * + * @param {Object} defaults + */ +exports.setDefaults = function (newDefaults) { + var defaults = this.getDefaults(); + + for (var key in defaults) { + if (newDefaults.hasOwnProperty(key)) { + defaults[key] = newDefaults[key]; + } + } +}; + +/** + * Schedule a new local notification. + * + * @param {Object} msgs + * The notification properties + * @param {Function} callback + * A function to be called after the notification has been canceled + * @param {Object?} scope + * The scope for the callback function + * @param {Object?} args + * skipPermission:true schedules the notifications immediatly without + * registering or checking for permission + */ +exports.schedule = function (msgs, callback, scope, args) { + var fn = function(granted) { + + if (!granted) return; + + var notifications = Array.isArray(msgs) ? msgs : [msgs]; + + for (var i = 0; i < notifications.length; i++) { + var notification = notifications[i]; + + this.mergeWithDefaults(notification); + this.convertProperties(notification); + } + + this.exec('schedule', notifications, callback, scope); + }; + + if (args && args.skipPermission) { + fn.call(this, true); + } else { + this.registerPermission(fn, this); + } +}; + +/** + * Update existing notifications specified by IDs in options. + * + * @param {Object} notifications + * The notification properties to update + * @param {Function} callback + * A function to be called after the notification has been updated + * @param {Object?} scope + * The scope for the callback function + * @param {Object?} args + * skipPermission:true schedules the notifications immediatly without + * registering or checking for permission + */ +exports.update = function (msgs, callback, scope, args) { + var fn = function(granted) { + + if (!granted) return; + + var notifications = Array.isArray(msgs) ? msgs : [msgs]; + + for (var i = 0; i < notifications.length; i++) { + var notification = notifications[i]; + + this.convertProperties(notification); + } + + this.exec('update', notifications, callback, scope); + }; + + if (args && args.skipPermission) { + fn.call(this, true); + } else { + this.registerPermission(fn, this); + } +}; + +/** + * Clear the specified notification. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A function to be called after the notification has been cleared + * @param {Object?} scope + * The scope for the callback function + */ +exports.clear = function (ids, callback, scope) { + ids = Array.isArray(ids) ? ids : [ids]; + ids = this.convertIds(ids); + + this.exec('clear', ids, callback, scope); +}; + +/** + * Clear all previously sheduled notifications. + * + * @param {Function} callback + * A function to be called after all notifications have been cleared + * @param {Object?} scope + * The scope for the callback function + */ +exports.clearAll = function (callback, scope) { + this.exec('clearAll', null, callback, scope); +}; + +/** + * Cancel the specified notifications. + * + * @param {String[]} ids + * The IDs of the notifications + * @param {Function} callback + * A function to be called after the notifications has been canceled + * @param {Object?} scope + * The scope for the callback function + */ +exports.cancel = function (ids, callback, scope) { + ids = Array.isArray(ids) ? ids : [ids]; + ids = this.convertIds(ids); + + this.exec('cancel', ids, callback, scope); +}; + +/** + * Remove all previously registered notifications. + * + * @param {Function} callback + * A function to be called after all notifications have been canceled + * @param {Object?} scope + * The scope for the callback function + */ +exports.cancelAll = function (callback, scope) { + this.exec('cancelAll', null, callback, scope); +}; + +/** + * Check if a notification with an ID is present. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isPresent = function (id, callback, scope) { + this.exec('isPresent', id || 0, callback, scope); +}; + +/** + * Check if a notification with an ID is scheduled. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isScheduled = function (id, callback, scope) { + this.exec('isScheduled', id || 0, callback, scope); +}; + +/** + * Check if a notification with an ID was triggered. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isTriggered = function (id, callback, scope) { + this.exec('isTriggered', id || 0, callback, scope); +}; + +/** + * List all local notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllIds = function (callback, scope) { + this.exec('getAllIds', null, callback, scope); +}; + +/** + * Alias for `getAllIds`. + */ +exports.getIds = function () { + this.getAllIds.apply(this, arguments); +}; + +/** + * List all scheduled notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getScheduledIds = function (callback, scope) { + this.exec('getScheduledIds', null, callback, scope); +}; + +/** + * List all triggered notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getTriggeredIds = function (callback, scope) { + this.exec('getTriggeredIds', null, callback, scope); +}; + +/** + * Property list for given local notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.get = function () { + var args = Array.apply(null, arguments); + + if (typeof args[0] == 'function') { + args.unshift([]); + } + + var ids = args[0], + callback = args[1], + scope = args[2]; + + if (!Array.isArray(ids)) { + this.exec('getSingle', Number(ids), callback, scope); + return; + } + + ids = this.convertIds(ids); + + this.exec('getAll', ids, callback, scope); +}; + +/** + * Property list for all local notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAll = function (callback, scope) { + this.exec('getAll', null, callback, scope); +}; + +/** + * Property list for given scheduled notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getScheduled = function () { + var args = Array.apply(null, arguments); + + if (typeof args[0] == 'function') { + args.unshift([]); + } + + var ids = args[0], + callback = args[1], + scope = args[2]; + + if (!Array.isArray(ids)) { + ids = [ids]; + } + + if (!Array.isArray(ids)) { + this.exec('getSingleScheduled', Number(ids), callback, scope); + return; + } + + ids = this.convertIds(ids); + + this.exec('getScheduled', ids, callback, scope); +}; + +/** + * Property list for all scheduled notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllScheduled = function (callback, scope) { + this.exec('getScheduled', null, callback, scope); +}; + +/** + * Property list for given triggered notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getTriggered = function () { + var args = Array.apply(null, arguments); + + if (typeof args[0] == 'function') { + args.unshift([]); + } + + var ids = args[0], + callback = args[1], + scope = args[2]; + + if (!Array.isArray(ids)) { + ids = [ids]; + } + + if (!Array.isArray(ids)) { + this.exec('getSingleTriggered', Number(ids), callback, scope); + return; + } + + ids = this.convertIds(ids); + + this.exec('getTriggered', ids, callback, scope); +}; + +/** + * Property list for all triggered notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllTriggered = function (callback, scope) { + this.exec('getTriggered', null, callback, scope); +}; + +/** + * Informs if the app has the permission to show notifications. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.hasPermission = function (callback, scope) { + var fn = this.createCallbackFn(callback, scope); + + if (device.platform != 'iOS') { + fn(true); + return; + } + + exec(fn, null, 'LocalNotification', 'hasPermission', []); +}; + +/** + * Register permission to show notifications if not already granted. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.registerPermission = function (callback, scope) { + + if (this._registered) { + return this.hasPermission(callback, scope); + } else { + this._registered = true; + } + + var fn = this.createCallbackFn(callback, scope); + + if (device.platform != 'iOS') { + fn(true); + return; + } + + exec(fn, null, 'LocalNotification', 'registerPermission', []); +}; + + +/********** + * EVENTS * + **********/ + +/** + * Register callback for given event. + * + * @param {String} event + * The event's name + * @param {Function} callback + * The function to be exec as callback + * @param {Object?} scope + * The callback function's scope + */ +exports.on = function (event, callback, scope) { + + if (typeof callback !== "function") + return; + + if (!this._listener[event]) { + this._listener[event] = []; + } + + var item = [callback, scope || window]; + + this._listener[event].push(item); +}; + +/** + * Unregister callback for given event. + * + * @param {String} event + * The event's name + * @param {Function} callback + * The function to be exec as callback + */ +exports.un = function (event, callback) { + var listener = this._listener[event]; + + if (!listener) + return; + + for (var i = 0; i < listener.length; i++) { + var fn = listener[i][0]; + + if (fn == callback) { + listener.splice(i, 1); + break; + } + } +}; + +}); diff --git a/platforms/android/platform_www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js b/platforms/android/platform_www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js new file mode 100644 index 0000000..b206de9 --- /dev/null +++ b/platforms/android/platform_www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js @@ -0,0 +1,316 @@ +cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification.Util", function(require, exports, module) { +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +var exec = require('cordova/exec'), + channel = require('cordova/channel'); + + +/*********** + * MEMBERS * + ***********/ + +// Default values +exports._defaults = { + text: '', + title: '', + sound: 'res://platform_default', + badge: 0, + id: 0, + data: undefined, + every: undefined, + at: undefined +}; + +// listener +exports._listener = {}; + +// Registered permission flag +exports._registered = false; + + +/******** + * UTIL * + ********/ + +/** + * Merge platform specific properties into the default ones. + * + * @return {Object} + * The default properties for the platform + */ +exports.applyPlatformSpecificOptions = function () { + var defaults = this._defaults; + + switch (device.platform) { + case 'Android': + defaults.icon = 'res://ic_popup_reminder'; + defaults.smallIcon = undefined; + defaults.ongoing = false; + defaults.autoClear = true; + defaults.led = 'FF0000'; + defaults.color = undefined; + break; + } + + return defaults; +}; + +/** + * Merge custom properties with the default values. + * + * @param {Object} options + * Set of custom values + * + * @retrun {Object} + * The merged property list + */ +exports.mergeWithDefaults = function (options) { + var defaults = this.getDefaults(); + + options.at = this.getValueFor(options, 'at', 'firstAt', 'date'); + options.text = this.getValueFor(options, 'text', 'message'); + options.data = this.getValueFor(options, 'data', 'json'); + + if (defaults.hasOwnProperty('autoClear')) { + options.autoClear = this.getValueFor(options, 'autoClear', 'autoCancel'); + } + + if (options.autoClear !== true && options.ongoing) { + options.autoClear = false; + } + + if (options.at === undefined || options.at === null) { + options.at = new Date(); + } + + for (var key in defaults) { + if (options[key] === null || options[key] === undefined) { + if (options.hasOwnProperty(key) && ['data','sound'].indexOf(key) > -1) { + options[key] = undefined; + } else { + options[key] = defaults[key]; + } + } + } + + for (key in options) { + if (!defaults.hasOwnProperty(key)) { + delete options[key]; + console.warn('Unknown property: ' + key); + } + } + + return options; +}; + +/** + * Convert the passed values to their required type. + * + * @param {Object} options + * Set of custom values + * + * @retrun {Object} + * The converted property list + */ +exports.convertProperties = function (options) { + + if (options.id) { + if (isNaN(options.id)) { + options.id = this.getDefaults().id; + console.warn('Id is not a number: ' + options.id); + } else { + options.id = Number(options.id); + } + } + + if (options.title) { + options.title = options.title.toString(); + } + + if (options.text) { + options.text = options.text.toString(); + } + + if (options.badge) { + if (isNaN(options.badge)) { + options.badge = this.getDefaults().badge; + console.warn('Badge number is not a number: ' + options.id); + } else { + options.badge = Number(options.badge); + } + } + + if (options.at) { + if (typeof options.at == 'object') { + options.at = options.at.getTime(); + } + + options.at = Math.round(options.at/1000); + } + + if (typeof options.data == 'object') { + options.data = JSON.stringify(options.data); + } + + if (options.every) { + if (device.platform == 'iOS' && typeof options.every != 'string') { + options.every = this.getDefaults().every; + var warning = 'Every option is not a string: ' + options.id; + warning += '. Expects one of: second, minute, hour, day, week, '; + warning += 'month, year on iOS.'; + console.warn(warning); + } + } + + return options; +}; + +/** + * Create callback, which will be executed within a specific scope. + * + * @param {Function} callbackFn + * The callback function + * @param {Object} scope + * The scope for the function + * + * @return {Function} + * The new callback function + */ +exports.createCallbackFn = function (callbackFn, scope) { + + if (typeof callbackFn != 'function') + return; + + return function () { + callbackFn.apply(scope || this, arguments); + }; +}; + +/** + * Convert the IDs to numbers. + * + * @param {String/Number[]} ids + * + * @return Array of Numbers + */ +exports.convertIds = function (ids) { + var convertedIds = []; + + for (var i = 0; i < ids.length; i++) { + convertedIds.push(Number(ids[i])); + } + + return convertedIds; +}; + +/** + * First found value for the given keys. + * + * @param {Object} options + * Object with key-value properties + * @param {String[]} keys* + * Key list + */ +exports.getValueFor = function (options) { + var keys = Array.apply(null, arguments).slice(1); + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + + if (options.hasOwnProperty(key)) { + return options[key]; + } + } +}; + +/** + * Fire event with given arguments. + * + * @param {String} event + * The event's name + * @param {args*} + * The callback's arguments + */ +exports.fireEvent = function (event) { + var args = Array.apply(null, arguments).slice(1), + listener = this._listener[event]; + + if (!listener) + return; + + for (var i = 0; i < listener.length; i++) { + var fn = listener[i][0], + scope = listener[i][1]; + + fn.apply(scope, args); + } +}; + +/** + * Execute the native counterpart. + * + * @param {String} action + * The name of the action + * @param args[] + * Array of arguments + * @param {Function} callback + * The callback function + * @param {Object} scope + * The scope for the function + */ +exports.exec = function (action, args, callback, scope) { + var fn = this.createCallbackFn(callback, scope), + params = []; + + if (Array.isArray(args)) { + params = args; + } else if (args) { + params.push(args); + } + + exec(fn, null, 'LocalNotification', action, params); +}; + + +/********* + * HOOKS * + *********/ + +// Called after 'deviceready' event +channel.deviceready.subscribe(function () { + // Device is ready now, the listeners are registered + // and all queued events can be executed. + exec(null, null, 'LocalNotification', 'deviceready', []); +}); + +// Called before 'deviceready' event +channel.onCordovaReady.subscribe(function () { + // Device plugin is ready now + channel.onCordovaInfoReady.subscribe(function () { + // Merge platform specifics into defaults + exports.applyPlatformSpecificOptions(); + }); +}); + +}); diff --git a/platforms/android/platform_www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js b/platforms/android/platform_www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js new file mode 100644 index 0000000..69b159b --- /dev/null +++ b/platforms/android/platform_www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js @@ -0,0 +1,379 @@ +cordova.define("de.appplant.cordova.plugin.local-notification.LocalNotification", function(require, exports, module) { +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + + +/************* + * INTERFACE * + *************/ + +/** + * Returns the default settings. + * + * @return {Object} + */ +exports.getDefaults = function () { + return this.core.getDefaults(); +}; + +/** + * Overwrite default settings. + * + * @param {Object} defaults + */ +exports.setDefaults = function (defaults) { + this.core.setDefaults(defaults); +}; + +/** + * Schedule a new local notification. + * + * @param {Object} notifications + * The notification properties + * @param {Function} callback + * A function to be called after the notification has been canceled + * @param {Object?} scope + * The scope for the callback function + * @param {Object?} args + * skipPermission:true schedules the notifications immediatly without + * registering or checking for permission + */ +exports.schedule = function (notifications, callback, scope, args) { + this.core.schedule(notifications, callback, scope, args); +}; + +/** + * Update existing notifications specified by IDs in options. + * + * @param {Object} notifications + * The notification properties to update + * @param {Function} callback + * A function to be called after the notification has been updated + * @param {Object?} scope + * The scope for the callback function + * @param {Object?} args + * skipPermission:true schedules the notifications immediatly without + * registering or checking for permission + */ +exports.update = function (notifications, callback, scope, args) { + this.core.update(notifications, callback, scope, args); +}; + +/** + * Clear the specified notification. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A function to be called after the notification has been cleared + * @param {Object?} scope + * The scope for the callback function + */ +exports.clear = function (ids, callback, scope) { + this.core.clear(ids, callback, scope); +}; + +/** + * Clear all previously sheduled notifications. + * + * @param {Function} callback + * A function to be called after all notifications have been cleared + * @param {Object?} scope + * The scope for the callback function + */ +exports.clearAll = function (callback, scope) { + this.core.clearAll(callback, scope); +}; + +/** + * Cancel the specified notifications. + * + * @param {String[]} ids + * The IDs of the notifications + * @param {Function} callback + * A function to be called after the notifications has been canceled + * @param {Object?} scope + * The scope for the callback function + */ +exports.cancel = function (ids, callback, scope) { + this.core.cancel(ids, callback, scope); +}; + +/** + * Remove all previously registered notifications. + * + * @param {Function} callback + * A function to be called after all notifications have been canceled + * @param {Object?} scope + * The scope for the callback function + */ +exports.cancelAll = function (callback, scope) { + this.core.cancelAll(callback, scope); +}; + +/** + * Check if a notification with an ID is present. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isPresent = function (id, callback, scope) { + this.core.isPresent(id, callback, scope); +}; + +/** + * Check if a notification with an ID is scheduled. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isScheduled = function (id, callback, scope) { + this.core.isScheduled(id, callback, scope); +}; + +/** + * Check if a notification with an ID was triggered. + * + * @param {String} id + * The ID of the notification + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.isTriggered = function (id, callback, scope) { + this.core.isTriggered(id, callback, scope); +}; + +/** + * List all local notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllIds = function (callback, scope) { + this.core.getAllIds(callback, scope); +}; + +/** + * Alias for `getAllIds`. + */ +exports.getIds = function () { + this.getAllIds.apply(this, arguments); +}; + +/** + * List all scheduled notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getScheduledIds = function (callback, scope) { + this.core.getScheduledIds(callback, scope); +}; + +/** + * List all triggered notification IDs. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getTriggeredIds = function (callback, scope) { + this.core.getTriggeredIds(callback, scope); +}; + +/** + * Property list for given local notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.get = function () { + this.core.get.apply(this.core, arguments); +}; + +/** + * Property list for all local notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAll = function (callback, scope) { + this.core.getAll(callback, scope); +}; + +/** + * Property list for given scheduled notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getScheduled = function () { + this.core.getScheduled.apply(this.core, arguments); +}; + +/** + * Property list for all scheduled notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllScheduled = function (callback, scope) { + this.core.getAllScheduled(callback, scope); +}; + +/** + * Property list for given triggered notifications. + * If called without IDs, all notification will be returned. + * + * @param {Number[]?} ids + * Set of notification IDs + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getTriggered = function () { + this.core.getTriggered.apply(this.core, arguments); +}; + +/** + * Property list for all triggered notifications. + * + * @param {Function} callback + * A callback function to be called with the list + * @param {Object?} scope + * The scope for the callback function + */ +exports.getAllTriggered = function (callback, scope) { + this.core.getAllTriggered(callback, scope); +}; + +/** + * Informs if the app has the permission to show notifications. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.hasPermission = function (callback, scope) { + this.core.hasPermission(callback, scope); +}; + +/** + * Register permission to show notifications if not already granted. + * + * @param {Function} callback + * The function to be exec as the callback + * @param {Object?} scope + * The callback function's scope + */ +exports.registerPermission = function (callback, scope) { + this.core.registerPermission(callback, scope); +}; + + +/**************** + * DEPRECATIONS * + ****************/ + +/** + * Schedule a new local notification. + */ +exports.add = function () { + console.warn('Depreated: Please use `notification.local.schedule` instead.'); + + this.schedule.apply(this, arguments); +}; + +/** + * Register permission to show notifications + * if not already granted. + */ +exports.promptForPermission = function () { + console.warn('Depreated: Please use `notification.local.registerPermission` instead.'); + + this.registerPermission.apply(this, arguments); +}; + + +/********** + * EVENTS * + **********/ + +/** + * Register callback for given event. + * + * @param {String} event + * The event's name + * @param {Function} callback + * The function to be exec as callback + * @param {Object?} scope + * The callback function's scope + */ +exports.on = function (event, callback, scope) { + this.core.on(event, callback, scope); +}; + +/** + * Unregister callback for given event. + * + * @param {String} event + * The event's name + * @param {Function} callback + * The function to be exec as callback + */ +exports.un = function (event, callback) { + this.core.un(event, callback, scope); +}; + +}); diff --git a/platforms/android/project.properties b/platforms/android/project.properties index b06f0fa..333f9de 100644 --- a/platforms/android/project.properties +++ b/platforms/android/project.properties @@ -10,5 +10,6 @@ # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. -target=android-22 +target=android-23 android.library.reference.1=CordovaLib +cordova.system.library.1=com.android.support:support-v4:+ \ No newline at end of file diff --git a/platforms/android/res/xml/config.xml b/platforms/android/res/xml/config.xml index 8931dbe..1009481 100644 --- a/platforms/android/res/xml/config.xml +++ b/platforms/android/res/xml/config.xml @@ -1,31 +1,34 @@ - + + + + - - + + + + + + - - - - - - + + + - - + + - - - + + StudyWell @@ -40,6 +43,7 @@ + diff --git a/platforms/android/src/com/shukriadams/micVolume/MicVolumePlugin.java b/platforms/android/src/com/shukriadams/micVolume/MicVolumePlugin.java index e54c3eb..aac3302 100644 --- a/platforms/android/src/com/shukriadams/micVolume/MicVolumePlugin.java +++ b/platforms/android/src/com/shukriadams/micVolume/MicVolumePlugin.java @@ -89,4 +89,9 @@ private void stop(CallbackContext callbackContext) { callbackContext.success(); } -} \ No newline at end of file +} + + + + + diff --git a/platforms/android/src/de/appplant/cordova/plugin/localnotification/ClearReceiver.java b/platforms/android/src/de/appplant/cordova/plugin/localnotification/ClearReceiver.java new file mode 100644 index 0000000..e0892e3 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/localnotification/ClearReceiver.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.localnotification; + +import de.appplant.cordova.plugin.notification.Notification; + + +/** + * The clear intent receiver is triggered when the user clears a + * notification manually. It un-persists the cleared notification from the + * shared preferences. + */ +public class ClearReceiver extends de.appplant.cordova.plugin.notification.ClearReceiver { + + /** + * Called when a local notification was cleared from outside of the app. + * + * @param notification + * Wrapper around the local notification + */ + @Override + public void onClear (Notification notification) { + super.onClear(notification); + LocalNotification.fireEvent("clear", notification); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/localnotification/ClickActivity.java b/platforms/android/src/de/appplant/cordova/plugin/localnotification/ClickActivity.java new file mode 100644 index 0000000..85a5355 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/localnotification/ClickActivity.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.localnotification; + +import de.appplant.cordova.plugin.notification.Builder; +import de.appplant.cordova.plugin.notification.Notification; +import de.appplant.cordova.plugin.notification.TriggerReceiver; + +/** + * The receiver activity is triggered when a notification is clicked by a user. + * The activity calls the background callback and brings the launch intent + * up to foreground. + */ +public class ClickActivity extends de.appplant.cordova.plugin.notification.ClickActivity { + + /** + * Called when local notification was clicked by the user. + * + * @param notification + * Wrapper around the local notification + */ + @Override + public void onClick(Notification notification) { + LocalNotification.fireEvent("click", notification); + + super.onClick(notification); + + if (notification.getOptions().isOngoing()) + return; + + String event = notification.isRepeating() ? "clear" : "cancel"; + LocalNotification.fireEvent(event, notification); + } + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + @Override + public Notification buildNotification (Builder builder) { + return builder + .setTriggerReceiver(TriggerReceiver.class) + .build(); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/localnotification/LocalNotification.java b/platforms/android/src/de/appplant/cordova/plugin/localnotification/LocalNotification.java new file mode 100644 index 0000000..b4be09f --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/localnotification/LocalNotification.java @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.localnotification; + +import android.app.Activity; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaInterface; +import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.PluginResult; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import de.appplant.cordova.plugin.notification.Manager; +import de.appplant.cordova.plugin.notification.Notification; + +/** + * This plugin utilizes the Android AlarmManager in combination with local + * notifications. When a local notification is scheduled the alarm manager takes + * care of firing the event. When the event is processed, a notification is put + * in the Android notification center and status bar. + */ +public class LocalNotification extends CordovaPlugin { + + // Reference to the web view for static access + private static CordovaWebView webView = null; + + // Indicates if the device is ready (to receive events) + private static Boolean deviceready = false; + + // To inform the user about the state of the app in callbacks + protected static Boolean isInBackground = true; + + // Queues all events before deviceready + private static ArrayList eventQueue = new ArrayList(); + + /** + * Called after plugin construction and fields have been initialized. + * Prefer to use pluginInitialize instead since there is no value in + * having parameters on the initialize() function. + * + * pluginInitialize is not available for cordova 3.0-3.5 ! + */ + @Override + public void initialize (CordovaInterface cordova, CordovaWebView webView) { + LocalNotification.webView = super.webView; + } + + /** + * Called when the system is about to start resuming a previous activity. + * + * @param multitasking + * Flag indicating if multitasking is turned on for app + */ + @Override + public void onPause(boolean multitasking) { + super.onPause(multitasking); + isInBackground = true; + } + + /** + * Called when the activity will start interacting with the user. + * + * @param multitasking + * Flag indicating if multitasking is turned on for app + */ + @Override + public void onResume(boolean multitasking) { + super.onResume(multitasking); + isInBackground = false; + deviceready(); + } + + /** + * The final call you receive before your activity is destroyed. + */ + @Override + public void onDestroy() { + deviceready = false; + isInBackground = true; + } + + /** + * Executes the request. + * + * This method is called from the WebView thread. To do a non-trivial + * amount of work, use: + * cordova.getThreadPool().execute(runnable); + * + * To run on the UI thread, use: + * cordova.getActivity().runOnUiThread(runnable); + * + * @param action + * The action to execute. + * @param args + * The exec() arguments in JSON form. + * @param command + * The callback context used when calling back into JavaScript. + * @return + * Whether the action was valid. + */ + @Override + public boolean execute (final String action, final JSONArray args, + final CallbackContext command) throws JSONException { + + Notification.setDefaultTriggerReceiver(TriggerReceiver.class); + + cordova.getThreadPool().execute(new Runnable() { + public void run() { + if (action.equals("schedule")) { + schedule(args); + command.success(); + } + else if (action.equals("update")) { + update(args); + command.success(); + } + else if (action.equals("cancel")) { + cancel(args); + command.success(); + } + else if (action.equals("cancelAll")) { + cancelAll(); + command.success(); + } + else if (action.equals("clear")) { + clear(args); + command.success(); + } + else if (action.equals("clearAll")) { + clearAll(); + command.success(); + } + else if (action.equals("isPresent")) { + isPresent(args.optInt(0), command); + } + else if (action.equals("isScheduled")) { + isScheduled(args.optInt(0), command); + } + else if (action.equals("isTriggered")) { + isTriggered(args.optInt(0), command); + } + else if (action.equals("getAllIds")) { + getAllIds(command); + } + else if (action.equals("getScheduledIds")) { + getScheduledIds(command); + } + else if (action.equals("getTriggeredIds")) { + getTriggeredIds(command); + } + else if (action.equals("getSingle")) { + getSingle(args, command); + } + else if (action.equals("getSingleScheduled")) { + getSingleScheduled(args, command); + } + else if (action.equals("getSingleTriggered")) { + getSingleTriggered(args, command); + } + else if (action.equals("getAll")) { + getAll(args, command); + } + else if (action.equals("getScheduled")) { + getScheduled(args, command); + } + else if (action.equals("getTriggered")) { + getTriggered(args, command); + } + else if (action.equals("deviceready")) { + deviceready(); + } + } + }); + + return true; + } + + /** + * Schedule multiple local notifications. + * + * @param notifications + * Properties for each local notification + */ + private void schedule (JSONArray notifications) { + for (int i = 0; i < notifications.length(); i++) { + JSONObject options = notifications.optJSONObject(i); + + Notification notification = + getNotificationMgr().schedule(options, TriggerReceiver.class); + + fireEvent("schedule", notification); + } + } + + /** + * Update multiple local notifications. + * + * @param updates + * Notification properties including their IDs + */ + private void update (JSONArray updates) { + for (int i = 0; i < updates.length(); i++) { + JSONObject update = updates.optJSONObject(i); + int id = update.optInt("id", 0); + + Notification notification = + getNotificationMgr().update(id, update, TriggerReceiver.class); + + if (notification == null) + continue; + + fireEvent("update", notification); + } + } + + /** + * Cancel multiple local notifications. + * + * @param ids + * Set of local notification IDs + */ + private void cancel (JSONArray ids) { + for (int i = 0; i < ids.length(); i++) { + int id = ids.optInt(i, 0); + + Notification notification = + getNotificationMgr().cancel(id); + + if (notification == null) + continue; + + fireEvent("cancel", notification); + } + } + + /** + * Cancel all scheduled notifications. + */ + private void cancelAll() { + getNotificationMgr().cancelAll(); + fireEvent("cancelall"); + } + + /** + * Clear multiple local notifications without canceling them. + * + * @param ids + * Set of local notification IDs + */ + private void clear(JSONArray ids){ + for (int i = 0; i < ids.length(); i++) { + int id = ids.optInt(i, 0); + + Notification notification = + getNotificationMgr().clear(id); + + if (notification == null) + continue; + + fireEvent("clear", notification); + } + } + + /** + * Clear all triggered notifications without canceling them. + */ + private void clearAll() { + getNotificationMgr().clearAll(); + fireEvent("clearall"); + } + + /** + * If a notification with an ID is present. + * + * @param id + * Notification ID + * @param command + * The callback context used when calling back into JavaScript. + */ + private void isPresent (int id, CallbackContext command) { + boolean exist = getNotificationMgr().exist(id); + + PluginResult result = new PluginResult( + PluginResult.Status.OK, exist); + + command.sendPluginResult(result); + } + + /** + * If a notification with an ID is scheduled. + * + * @param id + * Notification ID + * @param command + * The callback context used when calling back into JavaScript. + */ + private void isScheduled (int id, CallbackContext command) { + boolean exist = getNotificationMgr().exist( + id, Notification.Type.SCHEDULED); + + PluginResult result = new PluginResult( + PluginResult.Status.OK, exist); + + command.sendPluginResult(result); + } + + /** + * If a notification with an ID is triggered. + * + * @param id + * Notification ID + * @param command + * The callback context used when calling back into JavaScript. + */ + private void isTriggered (int id, CallbackContext command) { + boolean exist = getNotificationMgr().exist( + id, Notification.Type.TRIGGERED); + + PluginResult result = new PluginResult( + PluginResult.Status.OK, exist); + + command.sendPluginResult(result); + } + + /** + * Set of IDs from all existent notifications. + * + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getAllIds (CallbackContext command) { + List ids = getNotificationMgr().getIds(); + + command.success(new JSONArray(ids)); + } + + /** + * Set of IDs from all scheduled notifications. + * + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getScheduledIds (CallbackContext command) { + List ids = getNotificationMgr().getIdsByType( + Notification.Type.SCHEDULED); + + command.success(new JSONArray(ids)); + } + + /** + * Set of IDs from all triggered notifications. + * + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getTriggeredIds (CallbackContext command) { + List ids = getNotificationMgr().getIdsByType( + Notification.Type.TRIGGERED); + + command.success(new JSONArray(ids)); + } + + /** + * Options from local notification. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getSingle (JSONArray ids, CallbackContext command) { + getOptions(ids.optString(0), Notification.Type.ALL, command); + } + + /** + * Options from scheduled notification. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getSingleScheduled (JSONArray ids, CallbackContext command) { + getOptions(ids.optString(0), Notification.Type.SCHEDULED, command); + } + + /** + * Options from triggered notification. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getSingleTriggered (JSONArray ids, CallbackContext command) { + getOptions(ids.optString(0), Notification.Type.TRIGGERED, command); + } + + /** + * Set of options from local notification. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getAll (JSONArray ids, CallbackContext command) { + getOptions(ids, Notification.Type.ALL, command); + } + + /** + * Set of options from scheduled notifications. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getScheduled (JSONArray ids, CallbackContext command) { + getOptions(ids, Notification.Type.SCHEDULED, command); + } + + /** + * Set of options from triggered notifications. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getTriggered (JSONArray ids, CallbackContext command) { + getOptions(ids, Notification.Type.TRIGGERED, command); + } + + /** + * Options from local notification. + * + * @param id + * Set of local notification IDs + * @param type + * The local notification life cycle type + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getOptions (String id, Notification.Type type, + CallbackContext command) { + + JSONArray ids = new JSONArray().put(id); + PluginResult result; + + List options = + getNotificationMgr().getOptionsBy(type, toList(ids)); + + if (options.isEmpty()) { + // Status.NO_RESULT led to no callback invocation :( + // Status.OK led to no NPE and crash + result = new PluginResult(PluginResult.Status.NO_RESULT); + } else { + result = new PluginResult(PluginResult.Status.OK, options.get(0)); + } + + command.sendPluginResult(result); + } + + /** + * Set of options from local notifications. + * + * @param ids + * Set of local notification IDs + * @param type + * The local notification life cycle type + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getOptions (JSONArray ids, Notification.Type type, + CallbackContext command) { + + List options; + + if (ids.length() == 0) { + options = getNotificationMgr().getOptionsByType(type); + } else { + options = getNotificationMgr().getOptionsBy(type, toList(ids)); + } + + command.success(new JSONArray(options)); + } + + /** + * Call all pending callbacks after the deviceready event has been fired. + */ + private static synchronized void deviceready () { + isInBackground = false; + deviceready = true; + + for (String js : eventQueue) { + sendJavascript(js); + } + + eventQueue.clear(); + } + + /** + * Fire given event on JS side. Does inform all event listeners. + * + * @param event + * The event name + */ + private void fireEvent (String event) { + fireEvent(event, null); + } + + /** + * Fire given event on JS side. Does inform all event listeners. + * + * @param event + * The event name + * @param notification + * Optional local notification to pass the id and properties. + */ + static void fireEvent (String event, Notification notification) { + String state = getApplicationState(); + String params = "\"" + state + "\""; + + if (notification != null) { + params = notification.toString() + "," + params; + } + + String js = "cordova.plugins.notification.local.core.fireEvent(" + + "\"" + event + "\"," + params + ")"; + + sendJavascript(js); + } + + /** + * Use this instead of deprecated sendJavascript + * + * @param js + * JS code snippet as string + */ + private static synchronized void sendJavascript(final String js) { + + if (!deviceready) { + eventQueue.add(js); + return; + } + Runnable jsLoader = new Runnable() { + public void run() { + webView.loadUrl("javascript:" + js); + } + }; + try { + Method post = webView.getClass().getMethod("post",Runnable.class); + post.invoke(webView,jsLoader); + } catch(Exception e) { + + ((Activity)(webView.getContext())).runOnUiThread(jsLoader); + } + } + + /** + * Convert JSON array of integers to List. + * + * @param ary + * Array of integers + */ + private List toList (JSONArray ary) { + ArrayList list = new ArrayList(); + + for (int i = 0; i < ary.length(); i++) { + list.add(ary.optInt(i)); + } + + return list; + } + + /** + * Current application state. + * + * @return + * "background" or "foreground" + */ + static String getApplicationState () { + return isInBackground ? "background" : "foreground"; + } + + /** + * Notification manager instance. + */ + private Manager getNotificationMgr() { + return Manager.getInstance(cordova.getActivity()); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/localnotification/RestoreReceiver.java b/platforms/android/src/de/appplant/cordova/plugin/localnotification/RestoreReceiver.java new file mode 100644 index 0000000..675ea7c --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/localnotification/RestoreReceiver.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.localnotification; + +import de.appplant.cordova.plugin.notification.AbstractRestoreReceiver; +import de.appplant.cordova.plugin.notification.Builder; +import de.appplant.cordova.plugin.notification.Notification; + +/** + * This class is triggered upon reboot of the device. It needs to re-register + * the alarms with the AlarmManager since these alarms are lost in case of + * reboot. + */ +public class RestoreReceiver extends AbstractRestoreReceiver { + + /** + * Called when a local notification need to be restored. + * + * @param notification + * Wrapper around the local notification + */ + @Override + public void onRestore (Notification notification) { + if (notification.isScheduled()) { + notification.schedule(); + } else { + notification.cancel(); + } + } + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + @Override + public Notification buildNotification (Builder builder) { + return builder + .setTriggerReceiver(TriggerReceiver.class) + .setClearReceiver(ClearReceiver.class) + .setClickActivity(ClickActivity.class) + .build(); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/localnotification/TriggerReceiver.java b/platforms/android/src/de/appplant/cordova/plugin/localnotification/TriggerReceiver.java new file mode 100644 index 0000000..3c423c0 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/localnotification/TriggerReceiver.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.localnotification; + +import de.appplant.cordova.plugin.notification.Builder; +import de.appplant.cordova.plugin.notification.Notification; + +/** + * The alarm receiver is triggered when a scheduled alarm is fired. This class + * reads the information in the intent and displays this information in the + * Android notification bar. The notification uses the default notification + * sound and it vibrates the phone. + */ +public class TriggerReceiver extends de.appplant.cordova.plugin.notification.TriggerReceiver { + + /** + * Called when a local notification was triggered. Does present the local + * notification, re-schedule the alarm if necessary and fire trigger event. + * + * @param notification + * Wrapper around the local notification + * @param updated + * If an update has triggered or the original + */ + @Override + public void onTrigger (Notification notification, boolean updated) { + super.onTrigger(notification, updated); + + if (!updated) { + LocalNotification.fireEvent("trigger", notification); + } + } + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + @Override + public Notification buildNotification (Builder builder) { + return builder + .setTriggerReceiver(TriggerReceiver.class) + .setClickActivity(ClickActivity.class) + .setClearReceiver(ClearReceiver.class) + .build(); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractClearReceiver.java b/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractClearReceiver.java new file mode 100644 index 0000000..94d2a19 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractClearReceiver.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Abstract delete receiver for local notifications. Creates the local + * notification and calls the event functions for further proceeding. + */ +abstract public class AbstractClearReceiver extends BroadcastReceiver { + + /** + * Called when the notification was cleared from the notification center. + * + * @param context + * Application context + * @param intent + * Received intent with content data + */ + @Override + public void onReceive(Context context, Intent intent) { + Bundle bundle = intent.getExtras(); + JSONObject options; + + try { + String data = bundle.getString(Options.EXTRA); + options = new JSONObject(data); + } catch (JSONException e) { + e.printStackTrace(); + return; + } + + Notification notification = + new Builder(context, options).build(); + + onClear(notification); + } + + /** + * Called when a local notification was cleared from outside of the app. + * + * @param notification + * Wrapper around the local notification + */ + abstract public void onClear (Notification notification); + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractClickActivity.java b/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractClickActivity.java new file mode 100644 index 0000000..5b70e14 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractClickActivity.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Abstract content receiver activity for local notifications. Creates the + * local notification and calls the event functions for further proceeding. + */ +abstract public class AbstractClickActivity extends Activity { + + /** + * Called when local notification was clicked to launch the main intent. + * + * @param state + * Saved instance state + */ + @Override + public void onCreate (Bundle state) { + super.onCreate(state); + + Intent intent = getIntent(); + Bundle bundle = intent.getExtras(); + Context context = getApplicationContext(); + + try { + String data = bundle.getString(Options.EXTRA); + JSONObject options = new JSONObject(data); + + Builder builder = + new Builder(context, options); + + Notification notification = + buildNotification(builder); + + onClick(notification); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + /** + * Fixes "Unable to resume activity" error. + * Theme_NoDisplay: Activities finish themselves before being resumed. + */ + @Override + protected void onResume() { + super.onResume(); + finish(); + } + + /** + * Called when local notification was clicked by the user. + * + * @param notification + * Wrapper around the local notification + */ + abstract public void onClick (Notification notification); + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + abstract public Notification buildNotification (Builder builder); + + /** + * Launch main intent from package. + */ + public void launchApp() { + Context context = getApplicationContext(); + String pkgName = context.getPackageName(); + + Intent intent = context + .getPackageManager() + .getLaunchIntentForPackage(pkgName); + + intent.addFlags( + Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); + + context.startActivity(intent); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractRestoreReceiver.java b/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractRestoreReceiver.java new file mode 100644 index 0000000..8a1f365 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractRestoreReceiver.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import org.json.JSONObject; + +import java.util.List; + +/** + * This class is triggered upon reboot of the device. It needs to re-register + * the alarms with the AlarmManager since these alarms are lost in case of + * reboot. + */ +abstract public class AbstractRestoreReceiver extends BroadcastReceiver { + + /** + * Called on device reboot. + * + * @param context + * Application context + * @param intent + * Received intent with content data + */ + @Override + public void onReceive (Context context, Intent intent) { + Manager notificationMgr = + Manager.getInstance(context); + + List options = + notificationMgr.getOptions(); + + for (JSONObject data : options) { + Builder builder = new Builder(context, data); + + Notification notification = + buildNotification(builder); + + onRestore(notification); + } + } + + /** + * Called when a local notification need to be restored. + * + * @param notification + * Wrapper around the local notification + */ + abstract public void onRestore (Notification notification); + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + abstract public Notification buildNotification (Builder builder); + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractTriggerReceiver.java b/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractTriggerReceiver.java new file mode 100644 index 0000000..459e6d8 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/AbstractTriggerReceiver.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Calendar; + +/** + * Abstract broadcast receiver for local notifications. Creates the + * notification options and calls the event functions for further proceeding. + */ +abstract public class AbstractTriggerReceiver extends BroadcastReceiver { + + /** + * Called when an alarm was triggered. + * + * @param context + * Application context + * @param intent + * Received intent with content data + */ + @Override + public void onReceive(Context context, Intent intent) { + Bundle bundle = intent.getExtras(); + Options options; + + try { + String data = bundle.getString(Options.EXTRA); + JSONObject dict = new JSONObject(data); + + options = new Options(context).parse(dict); + } catch (JSONException e) { + e.printStackTrace(); + return; + } + + if (options == null) + return; + + if (isFirstAlarmInFuture(options)) + return; + + Builder builder = new Builder(options); + Notification notification = buildNotification(builder); + boolean updated = notification.isUpdate(false); + + onTrigger(notification, updated); + } + + /** + * Called when a local notification was triggered. + * + * @param notification + * Wrapper around the local notification + * @param updated + * If an update has triggered or the original + */ + abstract public void onTrigger (Notification notification, boolean updated); + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + abstract public Notification buildNotification (Builder builder); + + /* + * If you set a repeating alarm at 11:00 in the morning and it + * should trigger every morning at 08:00 o'clock, it will + * immediately fire. E.g. Android tries to make up for the + * 'forgotten' reminder for that day. Therefore we ignore the event + * if Android tries to 'catch up'. + */ + private Boolean isFirstAlarmInFuture (Options options) { + Notification notification = new Builder(options).build(); + + if (!notification.isRepeating()) + return false; + + Calendar now = Calendar.getInstance(); + Calendar alarm = Calendar.getInstance(); + + alarm.setTime(notification.getOptions().getTriggerDate()); + + int alarmHour = alarm.get(Calendar.HOUR_OF_DAY); + int alarmMin = alarm.get(Calendar.MINUTE); + int currentHour = now.get(Calendar.HOUR_OF_DAY); + int currentMin = now.get(Calendar.MINUTE); + + return (currentHour != alarmHour && currentMin != alarmMin); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/AssetUtil.java b/platforms/android/src/de/appplant/cordova/plugin/notification/AssetUtil.java new file mode 100644 index 0000000..66662e5 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/AssetUtil.java @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.content.Context; +import android.content.res.AssetManager; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.StrictMode; +import android.util.Log; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.UUID; + +/** + * Util class to map unified asset URIs to native URIs. URIs like file:/// + * map to absolute paths while file:// point relatively to the www folder + * within the asset resources. And res:// means a resource from the native + * res folder. Remote assets are accessible via http:// for example. + */ +class AssetUtil { + + // Name of the storage folder + private static final String STORAGE_FOLDER = "/localnotification"; + + // Placeholder URI for default sound + private static final String DEFAULT_SOUND = "res://platform_default"; + + // Ref to the context passed through the constructor to access the + // resources and app directory. + private final Context context; + + /** + * Constructor + * + * @param context + * Application context + */ + private AssetUtil(Context context) { + this.context = context; + } + + /** + * Static method to retrieve class instance. + * + * @param context + * Application context + */ + static AssetUtil getInstance(Context context) { + return new AssetUtil(context); + } + + /** + * Parse path path to native URI. + * + * @param path + * Path to path file + */ + Uri parseSound (String path) { + + if (path == null || path.isEmpty()) + return Uri.EMPTY; + + if (path.equalsIgnoreCase(DEFAULT_SOUND)) { + return RingtoneManager.getDefaultUri(RingtoneManager + .TYPE_NOTIFICATION); + } + + return parse(path); + } + + /** + * The URI for a path. + * + * @param path + * The given path + */ + Uri parse (String path) { + + if (path.startsWith("res:")) { + return getUriForResourcePath(path); + } else if (path.startsWith("file:///")) { + return getUriFromPath(path); + } else if (path.startsWith("file://")) { + return getUriFromAsset(path); + } else if (path.startsWith("http")){ + return getUriFromRemote(path); + } + + return Uri.EMPTY; + } + + /** + * URI for a file. + * + * @param path + * Absolute path like file:///... + * + * @return + * URI pointing to the given path + */ + private Uri getUriFromPath(String path) { + String absPath = path.replaceFirst("file://", ""); + File file = new File(absPath); + + if (!file.exists()) { + Log.e("Asset", "File not found: " + file.getAbsolutePath()); + return Uri.EMPTY; + } + + return Uri.fromFile(file); + } + + /** + * URI for an asset. + * + * @param path + * Asset path like file://... + * + * @return + * URI pointing to the given path + */ + private Uri getUriFromAsset(String path) { + String resPath = path.replaceFirst("file:/", "www"); + String fileName = resPath.substring(resPath.lastIndexOf('/') + 1); + File file = getTmpFile(fileName); + + if (file == null) { + Log.e("Asset", "Missing external cache dir"); + return Uri.EMPTY; + } + + try { + AssetManager assets = context.getAssets(); + FileOutputStream outStream = new FileOutputStream(file); + InputStream inputStream = assets.open(resPath); + + copyFile(inputStream, outStream); + + outStream.flush(); + outStream.close(); + + return Uri.fromFile(file); + + } catch (Exception e) { + Log.e("Asset", "File not found: assets/" + resPath); + e.printStackTrace(); + } + + return Uri.EMPTY; + } + + /** + * The URI for a resource. + * + * @param path + * The given relative path + * + * @return + * URI pointing to the given path + */ + private Uri getUriForResourcePath(String path) { + String resPath = path.replaceFirst("res://", ""); + int resId = getResIdForDrawable(resPath); + File file = getTmpFile(); + + if (resId == 0) { + Log.e("Asset", "File not found: " + resPath); + return Uri.EMPTY; + } + + if (file == null) { + Log.e("Asset", "Missing external cache dir"); + return Uri.EMPTY; + } + + try { + Resources res = context.getResources(); + FileOutputStream outStream = new FileOutputStream(file); + InputStream inputStream = res.openRawResource(resId); + copyFile(inputStream, outStream); + + outStream.flush(); + outStream.close(); + + return Uri.fromFile(file); + + } catch (Exception e) { + e.printStackTrace(); + } + + return Uri.EMPTY; + } + + /** + * Uri from remote located content. + * + * @param path + * Remote address + * + * @return + * Uri of the downloaded file + */ + private Uri getUriFromRemote(String path) { + File file = getTmpFile(); + + if (file == null) { + Log.e("Asset", "Missing external cache dir"); + return Uri.EMPTY; + } + + try { + URL url = new URL(path); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + + StrictMode.ThreadPolicy policy = + new StrictMode.ThreadPolicy.Builder().permitAll().build(); + + StrictMode.setThreadPolicy(policy); + + connection.setRequestProperty("Connection", "close"); + connection.setConnectTimeout(5000); + connection.connect(); + + InputStream input = connection.getInputStream(); + FileOutputStream outStream = new FileOutputStream(file); + + copyFile(input, outStream); + + outStream.flush(); + outStream.close(); + + return Uri.fromFile(file); + + } catch (MalformedURLException e) { + Log.e("Asset", "Incorrect URL"); + e.printStackTrace(); + } catch (FileNotFoundException e) { + Log.e("Asset", "Failed to create new File from HTTP Content"); + e.printStackTrace(); + } catch (IOException e) { + Log.e("Asset", "No Input can be created from http Stream"); + e.printStackTrace(); + } + + return Uri.EMPTY; + } + + /** + * Copy content from input stream into output stream. + * + * @param in + * The input stream + * @param out + * The output stream + */ + private void copyFile(InputStream in, OutputStream out) throws IOException { + byte[] buffer = new byte[1024]; + int read; + + while ((read = in.read(buffer)) != -1) { + out.write(buffer, 0, read); + } + } + + /** + * Resource ID for drawable. + * + * @param resPath + * Resource path as string + */ + int getResIdForDrawable(String resPath) { + int resId = getResIdForDrawable(getPkgName(), resPath); + + if (resId == 0) { + resId = getResIdForDrawable("android", resPath); + } + + return resId; + } + + /** + * Resource ID for drawable. + * + * @param clsName + * Relative package or global android name space + * @param resPath + * Resource path as string + */ + int getResIdForDrawable(String clsName, String resPath) { + String drawable = getBaseName(resPath); + int resId = 0; + + try { + Class cls = Class.forName(clsName + ".R$drawable"); + + resId = (Integer) cls.getDeclaredField(drawable).get(Integer.class); + } catch (Exception ignore) {} + + return resId; + } + + /** + * Convert drawable resource to bitmap. + * + * @param drawable + * Drawable resource name + */ + Bitmap getIconFromDrawable (String drawable) { + Resources res = context.getResources(); + int iconId; + + iconId = getResIdForDrawable(getPkgName(), drawable); + + if (iconId == 0) { + iconId = getResIdForDrawable("android", drawable); + } + + if (iconId == 0) { + iconId = android.R.drawable.screen_background_dark_transparent; + } + + return BitmapFactory.decodeResource(res, iconId); + } + + /** + * Convert URI to Bitmap. + * + * @param uri + * Internal image URI + */ + Bitmap getIconFromUri (Uri uri) throws IOException { + InputStream input = context.getContentResolver().openInputStream(uri); + + return BitmapFactory.decodeStream(input); + } + + /** + * Extract name of drawable resource from path. + * + * @param resPath + * Resource path as string + */ + private String getBaseName (String resPath) { + String drawable = resPath; + + if (drawable.contains("/")) { + drawable = drawable.substring(drawable.lastIndexOf('/') + 1); + } + + if (resPath.contains(".")) { + drawable = drawable.substring(0, drawable.lastIndexOf('.')); + } + + return drawable; + } + + /** + * Returns a file located under the external cache dir of that app. + * + * @return + * File with a random UUID name + */ + private File getTmpFile () { + // If random UUID is not be enough see + // https://github.com/LukePulverenti/cordova-plugin-local-notifications/blob/267170db14044cbeff6f4c3c62d9b766b7a1dd62/src/android/notification/AssetUtil.java#L255 + return getTmpFile(UUID.randomUUID().toString()); + } + + /** + * Returns a file located under the external cache dir of that app. + * + * @param name + * The name of the file + * @return + * File with the provided name + */ + private File getTmpFile (String name) { + File dir = context.getExternalCacheDir(); + + if (dir == null) { + Log.e("Asset", "Missing external cache dir"); + return null; + } + + String storage = dir.toString() + STORAGE_FOLDER; + + //noinspection ResultOfMethodCallIgnored + new File(storage).mkdir(); + + return new File(storage, name); + } + + /** + * Package name specified by context. + */ + private String getPkgName () { + return context.getPackageName(); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/Builder.java b/platforms/android/src/de/appplant/cordova/plugin/notification/Builder.java new file mode 100644 index 0000000..55eb1d3 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/Builder.java @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.support.v4.app.NotificationCompat; + +import org.json.JSONObject; + +import java.util.Random; + +/** + * Builder class for local notifications. Build fully configured local + * notification specified by JSON object passed from JS side. + */ +public class Builder { + + // Application context passed by constructor + private final Context context; + + // Notification options passed by JS + private final Options options; + + // Receiver to handle the trigger event + private Class triggerReceiver; + + // Receiver to handle the clear event + private Class clearReceiver = ClearReceiver.class; + + // Activity to handle the click event + private Class clickActivity = ClickActivity.class; + + /** + * Constructor + * + * @param context + * Application context + * @param options + * Notification options + */ + public Builder(Context context, JSONObject options) { + this.context = context; + this.options = new Options(context).parse(options); + } + + /** + * Constructor + * + * @param options + * Notification options + */ + public Builder(Options options) { + this.context = options.getContext(); + this.options = options; + } + + /** + * Set trigger receiver. + * + * @param receiver + * Broadcast receiver + */ + public Builder setTriggerReceiver(Class receiver) { + this.triggerReceiver = receiver; + return this; + } + + /** + * Set clear receiver. + * + * @param receiver + * Broadcast receiver + */ + public Builder setClearReceiver(Class receiver) { + this.clearReceiver = receiver; + return this; + } + + /** + * Set click activity. + * + * @param activity + * Activity + */ + public Builder setClickActivity(Class activity) { + this.clickActivity = activity; + return this; + } + + /** + * Creates the notification with all its options passed through JS. + */ + public Notification build() { + Uri sound = options.getSoundUri(); + int smallIcon = options.getSmallIcon(); + NotificationCompat.Builder builder; + + builder = new NotificationCompat.Builder(context) + .setDefaults(0) + .setContentTitle(options.getTitle()) + .setContentText(options.getText()) + .setNumber(options.getBadgeNumber()) + .setTicker(options.getText()) + .setAutoCancel(options.isAutoClear()) + .setOngoing(options.isOngoing()) + .setColor(options.getColor()) + .setLights(options.getLedColor(), 100, 100); + + if (sound != null) { + builder.setSound(sound); + } + + if (smallIcon == 0) { + builder.setSmallIcon(options.getIcon()); + } else { + builder.setSmallIcon(options.getSmallIcon()); + builder.setLargeIcon(options.getIconBitmap()); + } + + applyDeleteReceiver(builder); + applyContentReceiver(builder); + + return new Notification(context, options, builder, triggerReceiver); + } + + /** + * Set intent to handle the delete event. Will clean up some persisted + * preferences. + * + * @param builder + * Local notification builder instance + */ + private void applyDeleteReceiver(NotificationCompat.Builder builder) { + + if (clearReceiver == null) + return; + + Intent intent = new Intent(context, clearReceiver) + .setAction(options.getIdStr()) + .putExtra(Options.EXTRA, options.toString()); + + PendingIntent deleteIntent = PendingIntent.getBroadcast( + context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + + builder.setDeleteIntent(deleteIntent); + } + + /** + * Set intent to handle the click event. Will bring the app to + * foreground. + * + * @param builder + * Local notification builder instance + */ + private void applyContentReceiver(NotificationCompat.Builder builder) { + + if (clickActivity == null) + return; + + Intent intent = new Intent(context, clickActivity) + .putExtra(Options.EXTRA, options.toString()) + .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); + + int reqCode = new Random().nextInt(); + + PendingIntent contentIntent = PendingIntent.getActivity( + context, reqCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); + + builder.setContentIntent(contentIntent); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/ClearReceiver.java b/platforms/android/src/de/appplant/cordova/plugin/notification/ClearReceiver.java new file mode 100644 index 0000000..761b6c5 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/ClearReceiver.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +/** + * The clear intent receiver is triggered when the user clears a + * notification manually. It un-persists the cleared notification from the + * shared preferences. + */ +public class ClearReceiver extends AbstractClearReceiver { + + /** + * Called when a local notification was cleared from outside of the app. + * + * @param notification + * Wrapper around the local notification + */ + @Override + public void onClear (Notification notification) { + notification.clear(); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/ClickActivity.java b/platforms/android/src/de/appplant/cordova/plugin/notification/ClickActivity.java new file mode 100644 index 0000000..dcc0390 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/ClickActivity.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +/** + * The receiver activity is triggered when a notification is clicked by a user. + * The activity calls the background callback and brings the launch intent + * up to foreground. + */ +public class ClickActivity extends AbstractClickActivity { + + /** + * Called when local notification was clicked by the user. Will + * move the app to foreground. + * + * @param notification + * Wrapper around the local notification + */ + @Override + public void onClick(Notification notification) { + launchApp(); + + if (notification.isRepeating()) { + notification.clear(); + } else { + notification.cancel(); + } + } + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + public Notification buildNotification (Builder builder) { + return builder.build(); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/Manager.java b/platforms/android/src/de/appplant/cordova/plugin/notification/Manager.java new file mode 100644 index 0000000..9af3c94 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/Manager.java @@ -0,0 +1,458 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.app.NotificationManager; +import android.content.Context; +import android.content.SharedPreferences; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static de.appplant.cordova.plugin.notification.Notification.PREF_KEY; + +/** + * Central way to access all or single local notifications set by specific + * state like triggered or scheduled. Offers shortcut ways to schedule, + * cancel or clear local notifications. + */ +public class Manager { + + // Context passed through constructor and used for notification builder. + private Context context; + + /** + * Constructor + * + * @param context + * Application context + */ + private Manager(Context context){ + this.context = context; + } + + /** + * Static method to retrieve class instance. + * + * @param context + * Application context + */ + public static Manager getInstance(Context context) { + return new Manager(context); + } + + /** + * Schedule local notification specified by JSON object. + * + * @param options + * JSON object with set of options + * @param receiver + * Receiver to handle the trigger event + */ + public Notification schedule (JSONObject options, Class receiver) { + return schedule(new Options(context).parse(options), receiver); + } + + /** + * Schedule local notification specified by options object. + * + * @param options + * Set of notification options + * @param receiver + * Receiver to handle the trigger event + */ + public Notification schedule (Options options, Class receiver) { + Notification notification = new Builder(options) + .setTriggerReceiver(receiver) + .build(); + + notification.schedule(); + + return notification; + } + + /** + * Clear local notification specified by ID. + * + * @param id + * The notification ID + * @param updates + * JSON object with notification options + * @param receiver + * Receiver to handle the trigger event + */ + public Notification update (int id, JSONObject updates, Class receiver) { + Notification notification = get(id); + + if (notification == null) + return null; + + notification.cancel(); + + JSONObject options = mergeJSONObjects( + notification.getOptions().getDict(), updates); + + try { + options.put("updated", true); + } catch (JSONException ignore) {} + + return schedule(options, receiver); + } + + /** + * Clear local notification specified by ID. + * + * @param id + * The notification ID + */ + public Notification clear (int id) { + Notification notification = get(id); + + if (notification != null) { + notification.clear(); + } + + return notification; + } + + /** + * Clear local notification specified by ID. + * + * @param id + * The notification ID + */ + public Notification cancel (int id) { + Notification notification = get(id); + + if (notification != null) { + notification.cancel(); + } + + return notification; + } + + /** + * Clear all local notifications. + */ + public void clearAll () { + List notifications = getAll(); + + for (Notification notification : notifications) { + notification.clear(); + } + + getNotMgr().cancelAll(); + } + + /** + * Cancel all local notifications. + */ + public void cancelAll () { + List notifications = getAll(); + + for (Notification notification : notifications) { + notification.cancel(); + } + + getNotMgr().cancelAll(); + } + + /** + * All local notifications IDs. + */ + public List getIds() { + Set keys = getPrefs().getAll().keySet(); + ArrayList ids = new ArrayList(); + + for (String key : keys) { + try { + ids.add(Integer.parseInt(key)); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + + return ids; + } + + /** + * All local notification IDs for given type. + * + * @param type + * The notification life cycle type + */ + public List getIdsByType(Notification.Type type) { + List notifications = getAll(); + ArrayList ids = new ArrayList(); + + for (Notification notification : notifications) { + if (notification.getType() == type) { + ids.add(notification.getId()); + } + } + + return ids; + } + + /** + * List of local notifications with matching ID. + * + * @param ids + * Set of notification IDs + */ + public List getByIds(List ids) { + ArrayList notifications = new ArrayList(); + + for (int id : ids) { + Notification notification = get(id); + + if (notification != null) { + notifications.add(notification); + } + } + + return notifications; + } + + /** + * List of all local notification. + */ + public List getAll() { + return getByIds(getIds()); + } + + /** + * List of local notifications from given type. + * + * @param type + * The notification life cycle type + */ + public List getByType(Notification.Type type) { + List notifications = getAll(); + ArrayList list = new ArrayList(); + + if (type == Notification.Type.ALL) + return notifications; + + for (Notification notification : notifications) { + if (notification.getType() == type) { + list.add(notification); + } + } + + return list; + } + + /** + * List of local notifications with matching ID from given type. + * + * @param type + * The notification life cycle type + * @param ids + * Set of notification IDs + */ + @SuppressWarnings("UnusedDeclaration") + public List getBy(Notification.Type type, List ids) { + ArrayList notifications = new ArrayList(); + + for (int id : ids) { + Notification notification = get(id); + + if (notification != null && notification.isScheduled()) { + notifications.add(notification); + } + } + + return notifications; + } + + /** + * If a notification with an ID exists. + * + * @param id + * Notification ID + */ + public boolean exist (int id) { + return get(id) != null; + } + + /** + * If a notification with an ID and type exists. + * + * @param id + * Notification ID + * @param type + * Notification type + */ + public boolean exist (int id, Notification.Type type) { + Notification notification = get(id); + + return notification != null && notification.getType() == type; + } + + /** + * List of properties from all local notifications. + */ + public List getOptions() { + return getOptionsById(getIds()); + } + + /** + * List of properties from local notifications with matching ID. + * + * @param ids + * Set of notification IDs + */ + public List getOptionsById(List ids) { + ArrayList options = new ArrayList(); + + for (int id : ids) { + Notification notification = get(id); + + if (notification != null) { + options.add(notification.getOptions().getDict()); + } + } + + return options; + } + + /** + * List of properties from all local notifications from given type. + * + * @param type + * The notification life cycle type + */ + public List getOptionsByType(Notification.Type type) { + ArrayList options = new ArrayList(); + List notifications = getByType(type); + + for (Notification notification : notifications) { + options.add(notification.getOptions().getDict()); + } + + return options; + } + + /** + * List of properties from local notifications with matching ID from + * given type. + * + * @param type + * The notification life cycle type + * @param ids + * Set of notification IDs + */ + public List getOptionsBy(Notification.Type type, + List ids) { + + if (type == Notification.Type.ALL) + return getOptionsById(ids); + + ArrayList options = new ArrayList(); + List notifications = getByIds(ids); + + for (Notification notification : notifications) { + if (notification.getType() == type) { + options.add(notification.getOptions().getDict()); + } + } + + return options; + } + + /** + * Get existent local notification. + * + * @param id + * Notification ID + */ + public Notification get(int id) { + Map alarms = getPrefs().getAll(); + String notId = Integer.toString(id); + JSONObject options; + + if (!alarms.containsKey(notId)) + return null; + + + try { + String json = alarms.get(notId).toString(); + options = new JSONObject(json); + } catch (JSONException e) { + e.printStackTrace(); + return null; + } + + Builder builder = new Builder(context, options); + + return builder.build(); + } + + /** + * Merge two JSON objects. + * + * @param obj1 + * JSON object + * @param obj2 + * JSON object with new options + */ + private JSONObject mergeJSONObjects (JSONObject obj1, JSONObject obj2) { + Iterator it = obj2.keys(); + + while (it.hasNext()) { + try { + String key = (String)it.next(); + + obj1.put(key, obj2.opt(key)); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + return obj1; + } + + /** + * Shared private preferences for the application. + */ + private SharedPreferences getPrefs () { + return context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE); + } + + /** + * Notification manager for the application. + */ + private NotificationManager getNotMgr () { + return (NotificationManager) context + .getSystemService(Context.NOTIFICATION_SERVICE); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/Notification.java b/platforms/android/src/de/appplant/cordova/plugin/notification/Notification.java new file mode 100644 index 0000000..ad36378 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/Notification.java @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + + +import android.app.AlarmManager; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.support.v4.app.NotificationCompat; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Date; + +/** + * Wrapper class around OS notification class. Handles basic operations + * like show, delete, cancel for a single local notification instance. + */ +public class Notification { + + // Used to differ notifications by their life cycle state + public enum Type { + ALL, SCHEDULED, TRIGGERED + } + + // Default receiver to handle the trigger event + private static Class defaultReceiver = TriggerReceiver.class; + + // Key for private preferences + static final String PREF_KEY = "LocalNotification"; + + // Application context passed by constructor + private final Context context; + + // Notification options passed by JS + private final Options options; + + // Builder with full configuration + private final NotificationCompat.Builder builder; + + // Receiver to handle the trigger event + private Class receiver = defaultReceiver; + + /** + * Constructor + * + * @param context + * Application context + * @param options + * Parsed notification options + * @param builder + * Pre-configured notification builder + */ + protected Notification (Context context, Options options, + NotificationCompat.Builder builder, Class receiver) { + + this.context = context; + this.options = options; + this.builder = builder; + + this.receiver = receiver != null ? receiver : defaultReceiver; + } + + /** + * Get application context. + */ + public Context getContext () { + return context; + } + + /** + * Get notification options. + */ + public Options getOptions () { + return options; + } + + /** + * Get notification ID. + */ + public int getId () { + return options.getId(); + } + + /** + * If it's a repeating notification. + */ + public boolean isRepeating () { + return getOptions().getRepeatInterval() > 0; + } + + /** + * If the notification was in the past. + */ + public boolean wasInThePast () { + return new Date().after(options.getTriggerDate()); + } + + /** + * If the notification is scheduled. + */ + public boolean isScheduled () { + return isRepeating() || !wasInThePast(); + } + + /** + * If the notification is triggered. + */ + public boolean isTriggered () { + return wasInThePast(); + } + + /** + * If the notification is an update. + * + * @param keepFlag + * Set to false to remove the flag from the option map + */ + protected boolean isUpdate (boolean keepFlag) { + boolean updated = options.getDict().optBoolean("updated", false); + + if (!keepFlag) { + options.getDict().remove("updated"); + } + + return updated; + } + + /** + * Notification type can be one of pending or scheduled. + */ + public Type getType () { + return isScheduled() ? Type.SCHEDULED : Type.TRIGGERED; + } + + /** + * Schedule the local notification. + */ + public void schedule() { + long triggerTime = options.getTriggerTime(); + + persist(); + + // Intent gets called when the Notification gets fired + Intent intent = new Intent(context, receiver) + .setAction(options.getIdStr()) + .putExtra(Options.EXTRA, options.toString()); + + PendingIntent pi = PendingIntent.getBroadcast( + context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); + + if (isRepeating()) { + getAlarmMgr().setRepeating(AlarmManager.RTC_WAKEUP, + triggerTime, options.getRepeatInterval(), pi); + } else { + getAlarmMgr().set(AlarmManager.RTC_WAKEUP, triggerTime, pi); + } + } + + /** + * Clear the local notification without canceling repeating alarms. + */ + public void clear () { + + if (!isRepeating() && wasInThePast()) + unpersist(); + + if (!isRepeating()) + getNotMgr().cancel(getId()); + } + + /** + * Cancel the local notification. + * + * Create an intent that looks similar, to the one that was registered + * using schedule. Making sure the notification id in the action is the + * same. Now we can search for such an intent using the 'getService' + * method and cancel it. + */ + public void cancel() { + Intent intent = new Intent(context, receiver) + .setAction(options.getIdStr()); + + PendingIntent pi = PendingIntent. + getBroadcast(context, 0, intent, 0); + + getAlarmMgr().cancel(pi); + getNotMgr().cancel(options.getId()); + + unpersist(); + } + + /** + * Present the local notification to user. + */ + public void show () { + // TODO Show dialog when in foreground + showNotification(); + } + + /** + * Show as local notification when in background. + */ + @SuppressWarnings("deprecation") + private void showNotification () { + int id = getOptions().getId(); + + if (Build.VERSION.SDK_INT <= 15) { + // Notification for HoneyComb to ICS + getNotMgr().notify(id, builder.getNotification()); + } else { + // Notification for Jellybean and above + getNotMgr().notify(id, builder.build()); + } + } + + /** + * Count of triggers since schedule. + */ + public int getTriggerCountSinceSchedule() { + long now = System.currentTimeMillis(); + long triggerTime = options.getTriggerTime(); + + if (!wasInThePast()) + return 0; + + if (!isRepeating()) + return 1; + + return (int) ((now - triggerTime) / options.getRepeatInterval()); + } + + /** + * Encode options to JSON. + */ + public String toString() { + JSONObject dict = options.getDict(); + JSONObject json = new JSONObject(); + + try { + json = new JSONObject(dict.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + + json.remove("firstAt"); + json.remove("updated"); + json.remove("soundUri"); + json.remove("iconUri"); + + return json.toString(); + } + + /** + * Persist the information of this notification to the Android Shared + * Preferences. This will allow the application to restore the notification + * upon device reboot, app restart, retrieve notifications, aso. + */ + private void persist () { + SharedPreferences.Editor editor = getPrefs().edit(); + + editor.putString(options.getIdStr(), options.toString()); + + if (Build.VERSION.SDK_INT < 9) { + editor.commit(); + } else { + editor.apply(); + } + } + + /** + * Remove the notification from the Android shared Preferences. + */ + private void unpersist () { + SharedPreferences.Editor editor = getPrefs().edit(); + + editor.remove(options.getIdStr()); + + if (Build.VERSION.SDK_INT < 9) { + editor.commit(); + } else { + editor.apply(); + } + } + + /** + * Shared private preferences for the application. + */ + private SharedPreferences getPrefs () { + return context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE); + } + + /** + * Notification manager for the application. + */ + private NotificationManager getNotMgr () { + return (NotificationManager) context + .getSystemService(Context.NOTIFICATION_SERVICE); + } + + /** + * Alarm manager for the application. + */ + private AlarmManager getAlarmMgr () { + return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + } + + /** + * Set default receiver to handle the trigger event. + * + * @param receiver + * broadcast receiver + */ + public static void setDefaultTriggerReceiver (Class receiver) { + defaultReceiver = receiver; + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/Options.java b/platforms/android/src/de/appplant/cordova/plugin/notification/Options.java new file mode 100644 index 0000000..9d380d7 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/Options.java @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.app.AlarmManager; +import android.content.Context; +import android.graphics.Bitmap; +import android.net.Uri; +import android.support.v4.app.NotificationCompat; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Date; + +/** + * Wrapper around the JSON object passed through JS which contains all + * possible option values. Class provides simple readers and more advanced + * methods to convert independent values into platform specific values. + */ +public class Options { + + // Key name for bundled extras + static final String EXTRA = "NOTIFICATION_OPTIONS"; + + // The original JSON object + private JSONObject options = new JSONObject(); + + // Repeat interval + private long interval = 0; + + // Application context + private final Context context; + + // Asset util instance + private final AssetUtil assets; + + + /** + * Constructor + * + * @param context + * Application context + */ + public Options(Context context){ + this.context = context; + this.assets = AssetUtil.getInstance(context); + } + + /** + * Parse given JSON properties. + * + * @param options + * JSON properties + */ + public Options parse (JSONObject options) { + this.options = options; + + parseInterval(); + parseAssets(); + + return this; + } + + /** + * Parse repeat interval. + */ + private void parseInterval() { + String every = options.optString("every").toLowerCase(); + + if (every.isEmpty()) { + interval = 0; + } else + if (every.equals("second")) { + interval = 1000; + } else + if (every.equals("minute")) { + interval = AlarmManager.INTERVAL_FIFTEEN_MINUTES / 15; + } else + if (every.equals("hour")) { + interval = AlarmManager.INTERVAL_HOUR; + } else + if (every.equals("day")) { + interval = AlarmManager.INTERVAL_DAY; + } else + if (every.equals("week")) { + interval = AlarmManager.INTERVAL_DAY * 7; + } else + if (every.equals("month")) { + interval = AlarmManager.INTERVAL_DAY * 31; + } else + if (every.equals("quarter")) { + interval = AlarmManager.INTERVAL_HOUR * 2190; + } else + if (every.equals("year")) { + interval = AlarmManager.INTERVAL_DAY * 365; + } else { + try { + interval = Integer.parseInt(every) * 60000; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * Parse asset URIs. + */ + private void parseAssets() { + + if (options.has("iconUri") && !options.optBoolean("updated")) + return; + + Uri iconUri = assets.parse(options.optString("icon", "icon")); + Uri soundUri = assets.parseSound(options.optString("sound", null)); + + try { + options.put("iconUri", iconUri.toString()); + options.put("soundUri", soundUri.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + /** + * Application context. + */ + public Context getContext () { + return context; + } + + /** + * Wrapped JSON object. + */ + JSONObject getDict () { + return options; + } + + /** + * Text for the local notification. + */ + public String getText() { + return options.optString("text", ""); + } + + /** + * Repeat interval (day, week, month, year, aso.) + */ + public long getRepeatInterval() { + return interval; + } + + /** + * Badge number for the local notification. + */ + public int getBadgeNumber() { + return options.optInt("badge", 0); + } + + /** + * ongoing flag for local notifications. + */ + public Boolean isOngoing() { + return options.optBoolean("ongoing", false); + } + + /** + * autoClear flag for local notifications. + */ + public Boolean isAutoClear() { + return options.optBoolean("autoClear", false); + } + + /** + * ID for the local notification as a number. + */ + public Integer getId() { + return options.optInt("id", 0); + } + + /** + * ID for the local notification as a string. + */ + public String getIdStr() { + return getId().toString(); + } + + /** + * Trigger date. + */ + public Date getTriggerDate() { + return new Date(getTriggerTime()); + } + + /** + * Trigger date in milliseconds. + */ + public long getTriggerTime() { + return options.optLong("at", 0) * 1000; + } + + /** + * Title for the local notification. + */ + public String getTitle() { + String title = options.optString("title", ""); + + if (title.isEmpty()) { + title = context.getApplicationInfo().loadLabel( + context.getPackageManager()).toString(); + } + + return title; + } + + /** + * @return + * The notification color for LED + */ + public int getLedColor() { + String hex = options.optString("led", null); + + if (hex == null) { + return NotificationCompat.DEFAULT_LIGHTS; + } + + int aRGB = Integer.parseInt(hex, 16); + + return aRGB + 0xFF000000; + } + + /** + * @return + * The notification background color for the small icon + * Returns null, if no color is given. + */ + public int getColor() { + String hex = options.optString("color", null); + + if (hex == null) { + return NotificationCompat.COLOR_DEFAULT; + } + + int aRGB = Integer.parseInt(hex, 16); + + return aRGB + 0xFF000000; + } + + /** + * Sound file path for the local notification. + */ + public Uri getSoundUri() { + Uri uri = null; + + try{ + uri = Uri.parse(options.optString("soundUri")); + } catch (Exception e){ + e.printStackTrace(); + } + + return uri; + } + + /** + * Icon bitmap for the local notification. + */ + public Bitmap getIconBitmap() { + Bitmap bmp; + + try { + Uri uri = Uri.parse(options.optString("iconUri")); + bmp = assets.getIconFromUri(uri); + } catch (Exception e){ + e.printStackTrace(); + bmp = assets.getIconFromDrawable("icon"); + } + + return bmp; + } + + /** + * Icon resource ID for the local notification. + */ + public int getIcon () { + String icon = options.optString("icon", ""); + + int resId = assets.getResIdForDrawable(icon); + + if (resId == 0) { + resId = getSmallIcon(); + } + + if (resId == 0) { + resId = android.R.drawable.ic_popup_reminder; + } + + return resId; + } + + /** + * Small icon resource ID for the local notification. + */ + public int getSmallIcon () { + String icon = options.optString("smallIcon", ""); + + return assets.getResIdForDrawable(icon); + } + + /** + * JSON object as string. + */ + public String toString() { + return options.toString(); + } + +} diff --git a/platforms/android/src/de/appplant/cordova/plugin/notification/TriggerReceiver.java b/platforms/android/src/de/appplant/cordova/plugin/notification/TriggerReceiver.java new file mode 100644 index 0000000..9427e31 --- /dev/null +++ b/platforms/android/src/de/appplant/cordova/plugin/notification/TriggerReceiver.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +/** + * The alarm receiver is triggered when a scheduled alarm is fired. This class + * reads the information in the intent and displays this information in the + * Android notification bar. The notification uses the default notification + * sound and it vibrates the phone. + */ +public class TriggerReceiver extends AbstractTriggerReceiver { + + /** + * Called when a local notification was triggered. Does present the local + * notification and re-schedule the alarm if necessary. + * + * @param notification + * Wrapper around the local notification + * @param updated + * If an update has triggered or the original + */ + @Override + public void onTrigger (Notification notification, boolean updated) { + notification.show(); + } + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + @Override + public Notification buildNotification (Builder builder) { + return builder.build(); + } + +} diff --git a/platforms/platforms.json b/platforms/platforms.json index 54f14bd..caf2115 100644 --- a/platforms/platforms.json +++ b/platforms/platforms.json @@ -1,3 +1,3 @@ { - "android": "4.1.1" + "android": "5.1.1" } \ No newline at end of file diff --git a/plugins/android.json b/plugins/android.json index 8e94e6c..5f1904f 100644 --- a/plugins/android.json +++ b/plugins/android.json @@ -7,31 +7,45 @@ "files": {} }, "installed_plugins": { + "at.gofg.sportscomputer.powermanagement": { + "PACKAGE_NAME": "com.adamdon.sw" + }, "com.lampa.startapp": { "PACKAGE_NAME": "com.adamdon.sw" }, - "com.shukriadams.micVolume": { + "cordova-plugin-app-event": { + "PACKAGE_NAME": "com.adamdon.sw" + }, + "cordova-plugin-background-mode": { + "PACKAGE_NAME": "com.adamdon.sw" + }, + "cordova-plugin-device": { "PACKAGE_NAME": "com.adamdon.sw" }, "cordova-plugin-device-motion": { "PACKAGE_NAME": "com.adamdon.sw" }, + "cordova-plugin-dialogs": { + "PACKAGE_NAME": "com.adamdon.sw" + }, "cordova-plugin-whitelist": { "PACKAGE_NAME": "com.adamdon.sw" }, - "cordova-plugin-dialogs": { + "de.appplant.cordova.plugin.local-notification": { "PACKAGE_NAME": "com.adamdon.sw" }, - "cordova-plugin-background-mode": { + "cordova-plugin-device-tests": { "PACKAGE_NAME": "com.adamdon.sw" }, - "at.gofg.sportscomputer.powermanagement": { + "cordova-plugin-device-motion-tests": { "PACKAGE_NAME": "com.adamdon.sw" - } - }, - "dependent_plugins": { - "cordova-plugin-device": { + }, + "cordova-plugin-test-framework": { + "PACKAGE_NAME": "com.adamdon.sw" + }, + "com.shukriadams.micVolume": { "PACKAGE_NAME": "com.adamdon.sw" } - } + }, + "dependent_plugins": {} } \ No newline at end of file diff --git a/plugins/com.shukriadams.micVolume/src/android/MicVolumePlugin.java b/plugins/com.shukriadams.micVolume/src/android/MicVolumePlugin.java index e54c3eb..aac3302 100644 --- a/plugins/com.shukriadams.micVolume/src/android/MicVolumePlugin.java +++ b/plugins/com.shukriadams.micVolume/src/android/MicVolumePlugin.java @@ -89,4 +89,9 @@ private void stop(CallbackContext callbackContext) { callbackContext.success(); } -} \ No newline at end of file +} + + + + + diff --git a/plugins/com.shukriadams.micVolume/src/android/MicVolumePluginAlgorithmOne.js b/plugins/com.shukriadams.micVolume/src/android/MicVolumePluginAlgorithmOne.js deleted file mode 100644 index 8c95d6e..0000000 --- a/plugins/com.shukriadams.micVolume/src/android/MicVolumePluginAlgorithmOne.js +++ /dev/null @@ -1,99 +0,0 @@ -package com.shukriadams.micVolume; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; -import org.json.JSONObject; -import org.json.JSONArray; -import org.json.JSONException; -import android.app.Activity; -import android.content.Intent; - -// used by audio -import android.os.Bundle; -import android.media.AudioFormat; -import android.media.AudioRecord; -import android.media.MediaRecorder; - -public class MicVolumePlugin extends CordovaPlugin -{ - @Override - public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - try - { - if (action.equals("start")){ - start(callbackContext); - } else if (action.equals("read")){ - read(callbackContext); - } else if (action.equals("stop")){ - stop(callbackContext); - } else { - callbackContext.error("Unsupported action"); - } - - /* - JSONObject returnObj = new JSONObject(); - returnObj.put("title", "you should still be seeing this"); - callbackContext.success(returnObj); // pass return object back here - */ - return true; - } - catch(Exception e) - { - System.err.println("Exception: " + e.getMessage()); - callbackContext.error(e.getMessage()); - return false; - } - } - - private short[] buffer = null; - private AudioRecord audioRecord = null; - private int bufferSize= 1024; - private float volume = 0; - private int buflen; - - private void start(CallbackContext callbackContext) { - int freq =44100; - int chan = AudioFormat.CHANNEL_IN_MONO; - int enc = AudioFormat.ENCODING_PCM_16BIT; - int src = MediaRecorder.AudioSource.MIC; - buflen = AudioRecord.getMinBufferSize(freq, chan, enc); - audioRecord = new AudioRecord(src,freq,chan,enc,buflen); - - audioRecord.startRecording(); - - callbackContext.success(); - } - - private void read(CallbackContext callbackContext) throws JSONException - { - - JSONObject returnObj = new JSONObject(); - - double amplitude = 0; - buffer = new short[buflen]; - int bufferReadResult = audioRecord.read(buffer, 0, buflen); - double sumLevel = 0; - for (int i = 0; i < bufferReadResult; i++) { - sumLevel += buffer[i]; - } - amplitude = Math.abs((sumLevel / bufferReadResult)); - - returnObj.put("volume", Math.sqrt(amplitude)); - callbackContext.success(returnObj); - } - - private void stop(CallbackContext callbackContext) { - if (audioRecord != null) { - audioRecord.stop(); - audioRecord.release(); - audioRecord = null; - } - - callbackContext.success(); - } -} - - - - - diff --git a/plugins/com.shukriadams.micVolume/src/android/MicVolumePluginMessy.java b/plugins/com.shukriadams.micVolume/src/android/MicVolumePluginMessy.java deleted file mode 100644 index bfc7aa1..0000000 --- a/plugins/com.shukriadams.micVolume/src/android/MicVolumePluginMessy.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.shukriadams.micVolume; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; -import org.json.JSONObject; -import org.json.JSONArray; -import org.json.JSONException; -import android.app.Activity; -import android.content.Intent; - -// used by audio -import android.os.Bundle; -import android.media.AudioFormat; -import android.media.AudioRecord; -import android.media.MediaRecorder; -import android.util.Log; - -public class MicVolumePlugin extends CordovaPlugin -{ - @Override - public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - try - { - if (action.equals("start")){ - start(callbackContext); - } else if (action.equals("read")){ - read(callbackContext); - } else if (action.equals("stop")){ - stop(callbackContext); - } else { - callbackContext.error("Unsupported action"); - } - - /* - JSONObject returnObj = new JSONObject(); - returnObj.put("title", "you should still be seeing this"); - callbackContext.success(returnObj); // pass return object back here - */ - return true; - } - catch(Exception e) - { - System.err.println("Exception: " + e.getMessage()); - callbackContext.error(e.getMessage()); - return false; - } - } - - private short[] buffer = null; - private AudioRecord audioRecord = null; - private int bufferSize= 1024; - private float volume = 0; - private int buflen; - private boolean isRecording; - private boolean isPausing; - private double baseValue; - - - private void start(CallbackContext callbackContext) { - int freq =8000; - int chan = AudioFormat.CHANNEL_IN_MONO; - int enc = AudioFormat.ENCODING_PCM_16BIT; - int src = MediaRecorder.AudioSource.MIC; - buflen = AudioRecord.getMinBufferSize(freq, chan, enc); - audioRecord = new AudioRecord(src,freq,chan,enc,buflen); - - audioRecord.startRecording(); - isRecording = true; - isPausing = false; - baseValue = 12.0; - callbackContext.success(); - } - - private void read(CallbackContext callbackContext) throws JSONException - { - resume(); - - if (!isPausing) { - JSONObject returnObj = new JSONObject(); - - double amplitude = 0; - buffer = new short[buflen]; - int bufferReadResult = audioRecord.read(buffer, 0, buflen); - double max = 0; - for (short s : buffer) - { - if(Math.abs(s) > max) - { - max = Math.abs(s); - } - } - - returnObj.put("volum", max); - callbackContext.success(returnObj); - } - } - - private void stop(CallbackContext callbackContext) { - if (isRecording = true) { - audioRecord.stop(); - audioRecord.release(); - audioRecord = null; - isPaused = true; - } - - callbackContext.success(); - } - - public void stopRec() { - isRecording = false; - } - - public void pause() { - if (!isPausing) - audioRecord.stop(); - isPausing = true; - } - - public void resume() { - if (audioRecord = null) { - start(); - } - if (isPausing) - audioRecord.startRecording(); - isPausing = false; - } -} - - - - - diff --git a/plugins/com.shukriadams.micVolume/src/android/MicVolumePluginWorking.java b/plugins/com.shukriadams.micVolume/src/android/MicVolumePluginWorking.java deleted file mode 100644 index 7685255..0000000 --- a/plugins/com.shukriadams.micVolume/src/android/MicVolumePluginWorking.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.shukriadams.micVolume; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; -import org.json.JSONObject; -import org.json.JSONArray; -import org.json.JSONException; -import android.app.Activity; - -// used by audio -import android.os.Bundle; -import android.media.AudioFormat; -import android.media.AudioRecord; -import android.media.MediaRecorder; - -public class MicVolumePlugin extends CordovaPlugin -{ - @Override - public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - try - { - if (action.equals("start")){ - start(callbackContext); - } else if (action.equals("read")){ - read(callbackContext); - } else if (action.equals("stop")){ - stop(callbackContext); - } else { - callbackContext.error("Unsupported action"); - } - - /* - JSONObject returnObj = new JSONObject(); - returnObj.put("title", "you should still be seeing this"); - callbackContext.success(returnObj); // pass return object back here - */ - return true; - } - catch(Exception e) - { - System.err.println("Exception: " + e.getMessage()); - callbackContext.error(e.getMessage()); - return false; - } - } - - private short[] buffer = null; - private AudioRecord audioRecord = null; - private int bufferSize= 1024; - private float volum = 0; - private int buflen; - - int freq =8000; - int chan = AudioFormat.CHANNEL_IN_MONO; - int enc = AudioFormat.ENCODING_PCM_16BIT; - int src = MediaRecorder.AudioSource.MIC; - - private void start(CallbackContext callbackContext) { - - buflen = AudioRecord.getMinBufferSize(freq, chan, enc); - audioRecord = new AudioRecord(src,freq,chan,enc,buflen); - - audioRecord.startRecording(); - callbackContext.success(); - } - - private void stop(CallbackContext callbackContext) { - - audioRecord.stop(); - audioRecord.release(); - audioRecord = null; - - callbackContext.success(); - } - - private void read(CallbackContext callbackContext) throws JSONException { - - - - returnObj.put("volum", max); - callbackContext.success(returnObj); - } - - - -} - - - - - diff --git a/plugins/cordova-plugin-app-event/CHANGELOG.md b/plugins/cordova-plugin-app-event/CHANGELOG.md new file mode 100644 index 0000000..87e271a --- /dev/null +++ b/plugins/cordova-plugin-app-event/CHANGELOG.md @@ -0,0 +1,13 @@ +ChangeLog +--------- + +#### Version 1.2.0 (17.02.2016) +- White-list swizzling through APPAppEventDelegate protocol (#5) +- Finally fixed `EXC_BAD_ACCESS error` (#4) +- Removed usage of `nullable` to prevent build failures + +#### Version 1.1.0 (02.01.2016) +- Fixed `EXC_BAD_ACCESS error` + +#### Version 1.0.0 (01.01.2016) +- Initial version diff --git a/plugins/cordova-plugin-app-event/LICENSE b/plugins/cordova-plugin-app-event/LICENSE new file mode 100644 index 0000000..0d3f5ce --- /dev/null +++ b/plugins/cordova-plugin-app-event/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2013-2016 appPlant UG, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/plugins/cordova-plugin-app-event/README.md b/plugins/cordova-plugin-app-event/README.md new file mode 100644 index 0000000..6217360 --- /dev/null +++ b/plugins/cordova-plugin-app-event/README.md @@ -0,0 +1,88 @@ +[![npm version](https://badge.fury.io/js/cordova-plugin-app-event.svg)](http://badge.fury.io/js/cordova-plugin-app-event) + +Cordova App-Event Plugin +======================== + +The essential purpose of that plugin is to broadcast iOS-specific application events, so that 3rd party plugins can listen to them. + +Its mainly used as an internal dependency for the [LocalNotification][local_notification_plugin] and [Badge][badge_plugin] plugin. But can be used by any other plugin also. Feel free to submit an PR to broadcast additional events. + +As of right now its possible to add observers for these events: +- [didFinishLaunchingWithOptions][didFinishLaunchingWithOptions] +- [didRegisterUserNotificationSettings][didRegisterUserNotificationSettings] +- [didReceiveLocalNotification][didReceiveLocalNotification] + + +## Usage + +#### 1. Add and install the plugin as an dependency +Once you have added the plugin as an dependency you can add observers for them. + +```xml + + + +``` + +#### 2. Add the protocol to the plugin's interface +As first the plugin needs to indicate interest to receivce app events by adding the `APPAppEventDelegate` protocol. + +__Note:__ Required for version 1.2.0 or newer! + +```obj-c +// MyCordovaPlugin.h + +#import "APPAppEventDelegate.h" +#import + +@interface APPLocalNotification : CDVPlugin + +@implementation MyCordovaPlugin + +... + +@end +``` + +#### 3. Add implementations for the delegated events +To add an observer you need to implement the [UIApplicationDelegate Protocol][app_delegate_protocol]. Implementations from your _AppDelegate_ class don't get overwritten! + +For the `didReceiveLocalNotification` event you would need to add that method. + +```obj-c +// MyCordovaPlugin.m + +@implementation MyCordovaPlugin + +- (void) didReceiveLocalNotification:(NSNotification*)localNotification +{ + ... +} + +@end +``` + + +## Contributing + +1. Fork it +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create new Pull Request + + +## License + +This software is released under the [Apache 2.0 License][apache2_license]. + +© 2013-2016 appPlant UG, Inc. All rights reserved + + +[local_notification_plugin]: https://github.com/katzer/cordova-plugin-local-notifications +[badge_plugin]: https://github.com/katzer/cordova-plugin-badge +[didFinishLaunchingWithOptions]: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html?hl=ar#//apple_ref/occ/intfm/UIApplicationDelegate/application:didFinishLaunchingWithOptions: +[didRegisterUserNotificationSettings]: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html?hl=ar#//apple_ref/occ/intfm/UIApplicationDelegate/application:didRegisterUserNotificationSettings: +[didReceiveLocalNotification]: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html?hl=ar#//apple_ref/occ/intfm/UIApplicationDelegate/application:didReceiveLocalNotification: +[app_delegate_protocol]: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/ +[apache2_license]: http://opensource.org/licenses/Apache-2.0 diff --git a/plugins/cordova-plugin-app-event/package.json b/plugins/cordova-plugin-app-event/package.json new file mode 100644 index 0000000..2f5af6d --- /dev/null +++ b/plugins/cordova-plugin-app-event/package.json @@ -0,0 +1,37 @@ +{ + "name": "cordova-plugin-app-event", + "version": "1.2.0", + "description": "Broadcasts UIApplicationDelegate events", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/katzer/cordova-plugin-app-event.git" + }, + "keywords": [ + "appplant", + "UIApplicationDelegate", + "didRegisterUserNotificationSettings", + "didReceiveLocalNotification", + "didFinishLaunchingWithOptions", + "cordova", + "ecosystem:cordova" + ], + "platforms": [ + "ios" + ], + "engines": [ + { + "name": "cordova", + "version": ">=3.6.0" + } + ], + "author": "Sebastián Katzer", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/katzer/cordova-plugin-app-event/issues" + }, + "homepage": "https://github.com/katzer/cordova-plugin-app-event#readme" +} diff --git a/plugins/cordova-plugin-app-event/plugin.xml b/plugins/cordova-plugin-app-event/plugin.xml new file mode 100644 index 0000000..92cef92 --- /dev/null +++ b/plugins/cordova-plugin-app-event/plugin.xml @@ -0,0 +1,54 @@ + + + + + + + Application Events + Broadcasts various events to make them available for 3rd parties + appplant UIApplicationDelegate didRegisterUserNotificationSettings didReceiveLocalNotification didFinishLaunchingWithOptions + https://github.com/katzer/cordova-plugin-app-delegate.git + Apache 2.0 + Sebastián Katzer + + + + + + + + + + + + + + + + + + diff --git a/plugins/cordova-plugin-app-event/src/ios/APPAppEventDelegate.h b/plugins/cordova-plugin-app-event/src/ios/APPAppEventDelegate.h new file mode 100644 index 0000000..78e2f40 --- /dev/null +++ b/plugins/cordova-plugin-app-event/src/ios/APPAppEventDelegate.h @@ -0,0 +1,29 @@ +/* + Copyright 2013-2016 appPlant UG + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +@protocol APPAppEventDelegate + +/* + By implementing the interface the plugin indicates interest + to receive app events. + */ + +@end diff --git a/plugins/cordova-plugin-app-event/src/ios/AppDelegate+APPAppEvent.h b/plugins/cordova-plugin-app-event/src/ios/AppDelegate+APPAppEvent.h new file mode 100644 index 0000000..1158896 --- /dev/null +++ b/plugins/cordova-plugin-app-event/src/ios/AppDelegate+APPAppEvent.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013-2016 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "AppDelegate.h" + +extern NSString* const UIApplicationRegisterUserNotificationSettings; + +@interface AppDelegate (APPAppEvent) + +@end diff --git a/plugins/cordova-plugin-app-event/src/ios/AppDelegate+APPAppEvent.m b/plugins/cordova-plugin-app-event/src/ios/AppDelegate+APPAppEvent.m new file mode 100644 index 0000000..e1b7cc3 --- /dev/null +++ b/plugins/cordova-plugin-app-event/src/ios/AppDelegate+APPAppEvent.m @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2016 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "AppDelegate+APPAppEvent.h" +#import +#import + +NSString* const UIApplicationRegisterUserNotificationSettings = @"UIApplicationRegisterUserNotificationSettings"; + +@implementation AppDelegate (APPAppEvent) + +#pragma mark - +#pragma mark Life Cycle + +/** + * Its dangerous to override a method from within a category. + * Instead we will use method swizzling. + */ ++ (void) load +{ +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 + [self exchange_methods:@selector(application:didRegisterUserNotificationSettings:) + swizzled:@selector(swizzled_application:didRegisterUserNotificationSettings:)]; +#endif + +#if CORDOVA_VERSION_MIN_REQUIRED >= 40000 + [self exchange_methods:@selector(application:didReceiveLocalNotification:) + swizzled:@selector(swizzled_application:didReceiveLocalNotification:)]; +#endif +} + +#pragma mark - +#pragma mark Delegate + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 +/** + * Tells the delegate what types of notifications may be used + * to get the user’s attention. + */ +- (void) swizzled_application:(UIApplication*)application + didRegisterUserNotificationSettings:(UIUserNotificationSettings*)settings +{ + // re-post (broadcast) + [self postNotificationName:UIApplicationRegisterUserNotificationSettings object:settings]; + // This actually calls the original method over in AppDelegate + [self swizzled_application:application didRegisterUserNotificationSettings:settings]; +} +#endif + +#if CORDOVA_VERSION_MIN_REQUIRED >= 40000 +/** + * Repost all local notification using the default NSNotificationCenter so + * multiple plugins may respond. + */ +- (void) swizzled_application:(UIApplication*)application + didReceiveLocalNotification:(UILocalNotification*)notification +{ + // re-post (broadcast) + [self postNotificationName:CDVLocalNotification object:notification]; + // This actually calls the original method over in AppDelegate + [self swizzled_application:application didReceiveLocalNotification:notification]; +} +#endif + +#pragma mark - +#pragma mark Core + +/** + * Exchange the method implementations. + */ ++ (void) exchange_methods:(SEL)original swizzled:(SEL)swizzled +{ + class_addMethod(self, original, (IMP) defaultMethodIMP, "v@:"); + + Method original_method = class_getInstanceMethod(self, original); + Method swizzled_method = class_getInstanceMethod(self, swizzled); + + method_exchangeImplementations(original_method, swizzled_method); +} + +#pragma mark - +#pragma mark Helper + +void defaultMethodIMP (id self, SEL _cmd) { /* nothing to do here */ } + +/** + * Broadcasts the notification to all listeners. + */ +- (void) postNotificationName:(NSString*)aName object:(id)anObject +{ + [[NSNotificationCenter defaultCenter] postNotificationName:aName + object:anObject]; +} + +@end diff --git a/plugins/cordova-plugin-app-event/src/ios/CDVPlugin+APPAppEvent.h b/plugins/cordova-plugin-app-event/src/ios/CDVPlugin+APPAppEvent.h new file mode 100644 index 0000000..571f268 --- /dev/null +++ b/plugins/cordova-plugin-app-event/src/ios/CDVPlugin+APPAppEvent.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013-2016 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "Cordova/CDVPlugin.h" + +@interface CDVPlugin (APPAppEvent) + +@end diff --git a/plugins/cordova-plugin-app-event/src/ios/CDVPlugin+APPAppEvent.m b/plugins/cordova-plugin-app-event/src/ios/CDVPlugin+APPAppEvent.m new file mode 100644 index 0000000..1a9c4de --- /dev/null +++ b/plugins/cordova-plugin-app-event/src/ios/CDVPlugin+APPAppEvent.m @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2016 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "APPAppEventDelegate.h" +#import "CDVPlugin+APPAppEvent.h" +#import "AppDelegate+APPAppEvent.h" + +#import + +@implementation CDVPlugin (APPAppEvent) + +static IMP orig_pluginInitialize; + +#pragma mark - +#pragma mark Life Cycle + +/** + * Its dangerous to override a method from within a category. + * Instead we will use method swizzling. + */ ++ (void) initialize +{ + // To keep compatibility with local-notifiations v0.8.4 + if ([NSStringFromClass(self) isEqualToString:@"APPLocalNotification"] + || [self conformsToProtocol:@protocol(APPAppEventDelegate)]) { + + orig_pluginInitialize = [self exchange_init_methods]; + } +} + +#pragma mark - +#pragma mark Delegate + +/** + * Registers obervers after plugin was initialized. + */ +void swizzled_pluginInitialize(id self, SEL _cmd) +{ + if (orig_pluginInitialize != NULL) { + ((void(*)(id, SEL))orig_pluginInitialize)(self, _cmd); + orig_pluginInitialize = NULL; + } + + [self addObserver:NSSelectorFromString(@"didReceiveLocalNotification:") + name:CDVLocalNotification + object:NULL]; + + [self addObserver:NSSelectorFromString(@"didFinishLaunchingWithOptions:") + name:UIApplicationDidFinishLaunchingNotification + object:NULL]; + + [self addObserver:NSSelectorFromString(@"didRegisterUserNotificationSettings:") + name:UIApplicationRegisterUserNotificationSettings + object:NULL]; +} + +#pragma mark - +#pragma mark Core + +/** + * Exchange the method implementations for pluginInitialize + * and return the original implementation. + */ ++ (IMP) exchange_init_methods +{ + IMP swizzleImp = (IMP) swizzled_pluginInitialize; + Method origImp = class_getInstanceMethod(self, @selector(pluginInitialize)); + + if (method_getImplementation(origImp) != swizzleImp) { + return method_setImplementation(origImp, swizzleImp); + } + + return NULL; +} + +/** + * Register an observer if the caller responds to it. + */ +- (void) addObserver:(SEL)selector + name:(NSString*)event + object:(id)object +{ + if (![self respondsToSelector:selector]) + return; + + NSNotificationCenter* center = [NSNotificationCenter + defaultCenter]; + + [center addObserver:self + selector:selector + name:event + object:object]; +} + +@end diff --git a/plugins/cordova-plugin-device-motion-tests/plugin.xml b/plugins/cordova-plugin-device-motion-tests/plugin.xml new file mode 100644 index 0000000..40463ea --- /dev/null +++ b/plugins/cordova-plugin-device-motion-tests/plugin.xml @@ -0,0 +1,29 @@ + + + + + Cordova Device Motion Plugin Tests + Apache 2.0 + + + + diff --git a/plugins/cordova-plugin-device-motion-tests/tests.js b/plugins/cordova-plugin-device-motion-tests/tests.js new file mode 100644 index 0000000..73587e7 --- /dev/null +++ b/plugins/cordova-plugin-device-motion-tests/tests.js @@ -0,0 +1,364 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint jasmine: true */ +/* global Windows */ + +exports.defineAutoTests = function () { + var isWindows = (cordova.platformId === "windows") || (cordova.platformId === "windows8"), + // Checking existence of accelerometer for windows platform + // Assumed that accelerometer always exists on other platforms. Extend + // condition to support accelerometer check on other platforms + isAccelExist = isWindows ? Windows.Devices.Sensors.Accelerometer.getDefault() !== null : true; + + describe('Accelerometer (navigator.accelerometer)', function () { + var fail = function(done) { + expect(true).toBe(false); + done(); + }; + + // This timeout is here to lessen the load on native accelerometer + // intensive use of which can lead to occasional test failures + afterEach(function(done) { + setTimeout(function() { + done(); + }, 100); + }); + + it("accelerometer.spec.1 should exist", function () { + expect(navigator.accelerometer).toBeDefined(); + }); + + describe("getCurrentAcceleration", function() { + it("accelerometer.spec.2 should exist", function() { + expect(typeof navigator.accelerometer.getCurrentAcceleration).toBeDefined(); + expect(typeof navigator.accelerometer.getCurrentAcceleration == 'function').toBe(true); + }); + + it("accelerometer.spec.3 success callback should be called with an Acceleration object", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var win = function(a) { + expect(a).toBeDefined(); + expect(a.x).toBeDefined(); + expect(typeof a.x == 'number').toBe(true); + expect(a.y).toBeDefined(); + expect(typeof a.y == 'number').toBe(true); + expect(a.z).toBeDefined(); + expect(typeof a.z == 'number').toBe(true); + expect(a.timestamp).toBeDefined(); + expect(typeof a.timestamp).toBe('number'); + done(); + }; + + var onError = function(err){ + console.log(err); + console.log("Skipping gyroscope tests, marking all as pending."); + isAccelExist = false; + expect(true).toBe(true); + done(); + }; + + navigator.accelerometer.getCurrentAcceleration(win, onError); + }); + + it("accelerometer.spec.4 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var reasonableThreshold = 15; + var win = function(a) { + expect(a.x).toBeLessThan(reasonableThreshold); + expect(a.x).toBeGreaterThan(reasonableThreshold * -1); + expect(a.y).toBeLessThan(reasonableThreshold); + expect(a.y).toBeGreaterThan(reasonableThreshold * -1); + expect(a.z).toBeLessThan(reasonableThreshold); + expect(a.z).toBeGreaterThan(reasonableThreshold * -1); + done(); + }; + + navigator.accelerometer.getCurrentAcceleration(win, fail.bind(null,done)); + }); + + it("accelerometer.spec.5 success callback Acceleration object should return a recent timestamp", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var veryRecently = (new Date()).getTime(); + // Need to check that dates returned are not vastly greater than a recent time stamp. + // In case the timestamps returned are ridiculously high + var reasonableTimeLimit = veryRecently + 5000; // 5 seconds from now + var win = function(a) { + expect(a.timestamp).toBeGreaterThan(veryRecently); + expect(a.timestamp).toBeLessThan(reasonableTimeLimit); + done(); + }; + + navigator.accelerometer.getCurrentAcceleration(win, fail.bind(null,done)); + }); + }); + + describe("watchAcceleration", function() { + var id; + + afterEach(function() { + navigator.accelerometer.clearWatch(id); + }); + + it("accelerometer.spec.6 should exist", function() { + expect(navigator.accelerometer.watchAcceleration).toBeDefined(); + expect(typeof navigator.accelerometer.watchAcceleration == 'function').toBe(true); + }); + + it("accelerometer.spec.7 success callback should be called with an Acceleration object", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var win = function(a) { + expect(a).toBeDefined(); + expect(a.x).toBeDefined(); + expect(typeof a.x == 'number').toBe(true); + expect(a.y).toBeDefined(); + expect(typeof a.y == 'number').toBe(true); + expect(a.z).toBeDefined(); + expect(typeof a.z == 'number').toBe(true); + expect(a.timestamp).toBeDefined(); + expect(typeof a.timestamp).toBe('number'); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null,done), {frequency:100}); + }); + + it("accelerometer.spec.8 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var reasonableThreshold = 15; + var win = function(a) { + expect(a.x).toBeLessThan(reasonableThreshold); + expect(a.x).toBeGreaterThan(reasonableThreshold * -1); + expect(a.y).toBeLessThan(reasonableThreshold); + expect(a.y).toBeGreaterThan(reasonableThreshold * -1); + expect(a.z).toBeLessThan(reasonableThreshold); + expect(a.z).toBeGreaterThan(reasonableThreshold * -1); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null,done), {frequency:100}); + }); + + it("accelerometer.spec.9 success callback Acceleration object should return a recent timestamp", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var veryRecently = (new Date()).getTime(); + // Need to check that dates returned are not vastly greater than a recent time stamp. + // In case the timestamps returned are ridiculously high + var reasonableTimeLimit = veryRecently + 5000; // 5 seconds from now + var win = function(a) { + expect(a.timestamp).toBeGreaterThan(veryRecently); + expect(a.timestamp).toBeLessThan(reasonableTimeLimit); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null,done), {frequency:100}); + }); + + it("accelerometer.spec.12 success callback should be preserved and called several times", function (done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var callbacksCallCount = 0, + callbacksCallTestCount = 3; + + var win = function (a) { + if (callbacksCallCount++ < callbacksCallTestCount) return; + expect(typeof a).toBe('object'); + done(); + }; + + id = navigator.accelerometer.watchAcceleration(win, fail.bind(null, done), { frequency: 100 }); + }); + }); + + describe("clearWatch", function() { + it("accelerometer.spec.10 should exist", function() { + expect(navigator.accelerometer.clearWatch).toBeDefined(); + expect(typeof navigator.accelerometer.clearWatch == 'function').toBe(true); + }); + + it("accelerometer.spec.11 should clear an existing watch", function(done) { + // skip the test if Accelerometer doesn't exist on this device + if (!isAccelExist) { + pending(); + } + var id; + + // expect win to get called exactly once + var win = function(a) { + // clear watch on first call + navigator.accelerometer.clearWatch(id); + // if win isn't called again in 201 ms we assume success + var tid = setTimeout(function() { + expect(true).toBe(true); + done(); + }, 101); + // if win is called again, clear the timeout and fail the test + win = function() { + clearTimeout(tid); + fail(done); + }; + }; + + // wrap the success call in a closure since the value of win changes between calls + id = navigator.accelerometer.watchAcceleration(function() { win(); }, fail.bind(null, done), {frequency:100}); + }); + }); + }); +}; + +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ + +exports.defineManualTests = function (contentEl, createActionButton) { + function roundNumber(num) { + var dec = 3; + var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); + return result; + } + + var watchAccelId = null; + + /** + * Set accelerometer status + */ + function setAccelStatus(status) { + document.getElementById('accel_status').innerHTML = status; + } + + /** + * Stop watching the acceleration + */ + function stopAccel() { + console.log("stopAccel()"); + setAccelStatus("Stopped"); + if (watchAccelId) { + navigator.accelerometer.clearWatch(watchAccelId); + watchAccelId = null; + } + } + + /** + * Start watching acceleration + */ + var watchAccel = function () { + console.log("watchAccel()"); + + // Success callback + var success = function (a) { + document.getElementById('x').innerHTML = roundNumber(a.x); + document.getElementById('y').innerHTML = roundNumber(a.y); + document.getElementById('z').innerHTML = roundNumber(a.z); + }; + + // Fail callback + var fail = function (e) { + console.log("watchAccel fail callback with error code " + e); + stopAccel(); + setAccelStatus(e); + }; + + // Update acceleration every 1 sec + var opt = {}; + opt.frequency = 1000; + watchAccelId = navigator.accelerometer.watchAcceleration(success, fail, opt); + + setAccelStatus("Running"); + }; + + /** + * Get current acceleration + */ + var getAccel = function () { + console.log("getAccel()"); + + // Stop accel if running + stopAccel(); + + // Success callback + var success = function (a) { + document.getElementById('x').innerHTML = roundNumber(a.x); + document.getElementById('y').innerHTML = roundNumber(a.y); + document.getElementById('z').innerHTML = roundNumber(a.z); + console.log("getAccel success callback"); + }; + + // Fail callback + var fail = function (e) { + console.log("getAccel fail callback with error code " + e); + setAccelStatus(e); + }; + + // Make call + var opt = {}; + navigator.accelerometer.getCurrentAcceleration(success, fail, opt); + }; + + /******************************************************************************/ + + var accelerometer_tests = '
    ' + + 'Expected result: Will update the status box with X, Y, and Z values when pressed. Status will read "Stopped"' + + '

    ' + + 'Expected result: When pressed, will start a watch on the accelerometer and update X,Y,Z values when movement is sensed. Status will read "Running"' + + '

    ' + + 'Expected result: Will clear the accelerometer watch, so X,Y,Z values will no longer be updated. Status will read "Stopped"'; + + contentEl.innerHTML = '
    ' + + 'Status: Stopped' + + '' + + '' + + '' + + '' + + '
    X:
    Y:
    Z:
    ' + + accelerometer_tests; + + createActionButton('Get Acceleration', function () { + getAccel(); + }, 'getAcceleration'); + + createActionButton('Start Watch', function () { + watchAccel(); + }, 'watchAcceleration'); + + createActionButton('Clear Watch', function () { + stopAccel(); + }, 'clearAcceleration'); +}; diff --git a/plugins/cordova-plugin-device-tests/plugin.xml b/plugins/cordova-plugin-device-tests/plugin.xml new file mode 100644 index 0000000..89c75a0 --- /dev/null +++ b/plugins/cordova-plugin-device-tests/plugin.xml @@ -0,0 +1,31 @@ + + + + + Cordova Device Plugin Tests + Apache 2.0 + + + + diff --git a/plugins/cordova-plugin-device-tests/tests.js b/plugins/cordova-plugin-device-tests/tests.js new file mode 100644 index 0000000..ac9a281 --- /dev/null +++ b/plugins/cordova-plugin-device-tests/tests.js @@ -0,0 +1,113 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint jasmine: true */ + +exports.defineAutoTests = function() { + describe('Device Information (window.device)', function () { + it("should exist", function() { + expect(window.device).toBeDefined(); + }); + + it("should contain a platform specification that is a string", function() { + expect(window.device.platform).toBeDefined(); + expect((String(window.device.platform)).length > 0).toBe(true); + }); + + it("should contain a version specification that is a string", function() { + expect(window.device.version).toBeDefined(); + expect((String(window.device.version)).length > 0).toBe(true); + }); + + it("should contain a UUID specification that is a string or a number", function() { + expect(window.device.uuid).toBeDefined(); + if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') { + expect((String(window.device.uuid)).length > 0).toBe(true); + } else { + expect(window.device.uuid > 0).toBe(true); + } + }); + + it("should contain a cordova specification that is a string", function() { + expect(window.device.cordova).toBeDefined(); + expect((String(window.device.cordova)).length > 0).toBe(true); + }); + + it("should depend on the presence of cordova.version string", function() { + expect(window.cordova.version).toBeDefined(); + expect((String(window.cordova.version)).length > 0).toBe(true); + }); + + it("should contain device.cordova equal to cordova.version", function() { + expect(window.device.cordova).toBe(window.cordova.version); + }); + + it("should contain a model specification that is a string", function() { + expect(window.device.model).toBeDefined(); + expect((String(window.device.model)).length > 0).toBe(true); + }); + + it("should contain a manufacturer property that is a string", function() { + expect(window.device.manufacturer).toBeDefined(); + expect((String(window.device.manufacturer)).length > 0).toBe(true); + }); + + it("should contain an isVirtual property that is a boolean", function() { + expect(window.device.isVirtual).toBeDefined(); + expect(typeof window.device.isVirtual).toBe("boolean"); + }); + + it("should contain a serial number specification that is a string", function() { + expect(window.device.serial).toBeDefined(); + expect((String(window.device.serial)).length > 0).toBe(true); + + }); + + }); +}; + +exports.defineManualTests = function(contentEl, createActionButton) { + var logMessage = function (message, color) { + var log = document.getElementById('info'); + var logLine = document.createElement('div'); + if (color) { + logLine.style.color = color; + } + logLine.innerHTML = message; + log.appendChild(logLine); + }; + + var clearLog = function () { + var log = document.getElementById('info'); + log.innerHTML = ''; + }; + + var device_tests = '

    Press Dump Device button to get device information

    ' + + '
    ' + + 'Expected result: Status box will get updated with device info. (i.e. platform, version, uuid, model, etc)'; + + contentEl.innerHTML = '
    ' + device_tests; + + createActionButton('Dump device', function() { + clearLog(); + logMessage(JSON.stringify(window.device, null, '\t')); + }, "dump_device"); +}; diff --git a/plugins/cordova-plugin-test-framework/LICENSE b/plugins/cordova-plugin-test-framework/LICENSE new file mode 100644 index 0000000..37ec93a --- /dev/null +++ b/plugins/cordova-plugin-test-framework/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/plugins/cordova-plugin-test-framework/NOTICE b/plugins/cordova-plugin-test-framework/NOTICE new file mode 100755 index 0000000..f961b33 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/NOTICE @@ -0,0 +1,199 @@ +Apache Cordova +Copyright 2014 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +Topcoat is licensed under the Apache license version 2.0, January 2004 (see LICENSE file). + +Topcoat uses the following third party libraries that may have licenses +differing from that of Topcoat itself. You can find the libraries and their +respective licenses below. + + - Source Code Pro ./src/font/SourceCodePro + + https://github.com/adobe/source-code-pro + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + This Font Software is licensed under the SIL Open Font License, Version 1.1. + This license is available with a FAQ at: http://scripts.sil.org/OFL + +- Source Sans Pro ./src/font/SourceSansPro + + https://github.com/adobe/source-sans-pro + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + This Font Software is licensed under the SIL Open Font License, Version 1.1. + This license is available with a FAQ at: http://scripts.sil.org/OFL + +The following frameworks and libraries are provided just for testing and benchmarking and, as provided, should not be included as part of Topcoat output. + + - Bootstrap - ./test/third-party/bootstrap + + https://github.com/twitter/bootstrap + + Copyright 2012 Twitter, Inc + Licensed under the Apache License v2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + - jQuery - ./test/third-party/jquery-1.8.2.js + + https://github.com/jquery/jquery + + Copyright 2011, John Resig + Dual licensed under the MIT or GPL Version 2 licenses. + http://jquery.org/license + + Includes Sizzle.js + http://sizzlejs.com/ + Copyright 2011, The Dojo Foundation + Released under the MIT, BSD, and GPL Licenses. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + - Modernizr - ./test/third-party/modernizr + + https://github.com/Modernizr/Modernizr + + Modernizr is available under the MIT license + + Copyright (c) 2009–2011 + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + - Benchmark.js - ./test/third-party/benchmarkjs + + https://github.com/alexanderbeletsky/benchmark-js + + Copyright 2010-2012 Mathias Bynens + Based on JSLitmus.js, copyright Robert Kieffer + Modified by John-David Dalton + Available under MIT license + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - normalize.css - ./test/third-party/normalize + + Copyright (c) Nicolas Gallagher and Jonathan Neal + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - Foundation - ./test/third-party/foundation + + Copyright (c) 2012 Mark Hayes + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - ua-parser ./test/third-party/ua-parser + + https://github.com/faisalman/ua-parser-js + + Copyright © 2012 Faisalman + Dual licensed under GPLv2 & MIT + Copyright © 2012 Faisalman + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + - HTML5 boilerplate + + https://github.com/h5bp/html5-boilerplate + + Copyright (c) HTML5 Boilerplate + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - classList - ./test/third-party/classlist + + http://purl.eligrey.com/github/classList.js/blob/master/classList.js + + This software is dedicated to the public domain. No warranty is expressed or implied. + Use this software at your own risk. + + - fastclick - ./test/third-party/fastclick + + https://github.com/ftlabs/fastclick + + Copyright (C) 2012 The Financial Times Ltd. + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/cordova-plugin-test-framework/README.md b/plugins/cordova-plugin-test-framework/README.md new file mode 100644 index 0000000..7da78d8 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/README.md @@ -0,0 +1,145 @@ + + +[![Build Status](https://travis-ci.org/apache/cordova-plugin-test-framework.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-test-framework) + +# Cordova Plugin Test Framework + +The `cordova-plugin-test-framework` plugin does two things: + +1. [Defines the interface for cordova plugins to write tests](#interface) +2. [Provides a test harness for actually running those tests](#harness) + +Tests run directly inside existing cordova projects, so you can rapidly switch between testing and development. You can also be sure that your test suite is testing the exact versions of plugins and platforms that your app is using. + +# TLDR; Try it + +1. Use your existing cordova app, or create a new one. +2. Plugins bundle their tests using a nested plugin in a `/tests` directory. To make this interesting, add some of these plugins and their respective tests. Here are a few examples: + + cordova plugin add http://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git + cordova plugin add http://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git#:/tests + + cordova plugin add http://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion.git + cordova plugin add http://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion.git#:/tests + + cordova plugin add http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation.git + cordova plugin add http://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation#:/tests + +3. Follow the docs for [Setting up the test harness](#harness). + + + +## Writing Plugin Tests + +### Where do tests live? + +Add a directory named `tests` to the root of your plugin. Within this directory, create a nested `plugin.xml` for the tests plugin. It should have a plugin id with the form `plugin-id-tests` (e.g. the `cordova-plugin-device` plugin has the nested id `cordova-plugin-device-tests`) and should contain a `` named `tests`. E.g: + +``` + + +``` + +For example, the `cordova-plugin-device` plugin has this nested [`plugin.xml`](https://github.com/apache/cordova-plugin-device/blob/master/tests/plugin.xml). + +The `cordova-plugin-test-framework` plugin will automatically find all `tests` modules across all plugins for which the nested tests plugin is installed. + +### Defining Auto Tests + +Simply export a function named `defineAutoTests`, which (gasp!) defines your auto-tests when run. Use the [`jasmine-2.0`](http://jasmine.github.io/2.0/introduction.html) format. E.g.: + +``` +exports.defineAutoTests = function() { + + describe('awesome tests', function() { + it('do something sync', function() { + expect(1).toBe(1); + ... + }); + + it('do something async', function(done) { + setTimeout(function() { + expect(1).toBe(1); + ... + done(); + }, 100); + }); + }); + + describe('more awesome tests', function() { + ... + }); + +}; +``` + +Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions. + + +### Defining Manual Tests + +Simply export a function named `defineManualTests`, which (gasp!) defines your manual-tests when run. Manual tests do *not* use jasmine-2.0, and success/failure results are not officially reported in any standard way. Instead, create buttons to run arbitrary javascript when clicked, and display output to user using `console` or by manipulating a provided DOM element. E.g.: + +``` +exports.defineManualTests = function(contentEl, createActionButton) { + + createActionButton('Simple Test', function() { + console.log(JSON.stringify(foo, null, '\t')); + }); + + createActionButton('Complex Test', function() { + contentEl.innerHTML = ...; + }); + +}; +``` + +Note: Your tests will automatically be labeled with your plugin id, so do not prefix your test descriptions. + + + +### Example + +See: [`cordova-plugin-device` tests](https://github.com/apache/cordova-plugin-device/blob/master/tests/tests.js). + + +## Running Plugin Tests + +1. Use your existing cordova app, or create a new one. +2. Add this plugin: + + cordova plugin add http://git-wip-us.apache.org/repos/asf/cordova-plugin-test-framework.git + +3. Change the start page in `config.xml` with `` or navigate to `cdvtests/index.html` from within your app. +4. Thats it! + + +## FAQ + +* Q: Should I add `cordova-plugin-test-framework` as a `` of my plugin? + * A: No. The end-user should decide if they want to install the test framework, not your plugin (most users won't). + +* Q: What do I do if my plugin tests must have very large assets? + * A: Don't bundle those assets with your plugin. If you can, have your tests fail gracefully if those assets don't don't exist (perhaps log a warning, perhaps fail a single asset-checking test, and skip the rest). Then, ideally download those assets automatically into local storage the first time tests run. Or create a manual test step to download and install assets. As a final alternative, split those test assets into a separate plugin, and instruct users to install that plugin to run your full test suite. + +* Q: Should I ship my app with the test framework plugin installed? + * A: Not likely. If you want, you can. Then your app could even embed a link to the test page (`cdvtests/index.html`) from a help section of your app, to give end users a way to run your test suite out in the feild. That may help diagnose causes of issues within your app. Maybe. diff --git a/plugins/cordova-plugin-test-framework/RELEASENOTES.md b/plugins/cordova-plugin-test-framework/RELEASENOTES.md new file mode 100644 index 0000000..a13efd9 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/RELEASENOTES.md @@ -0,0 +1,45 @@ + +# Release Notes + +### 1.1.1 (Jan 15, 2016) +* CB-10318 Do not wrap test title + +### 1.1.0 (Nov 18, 2015) +* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated `RELEASENOTES` to be newest to oldest +* [CB-8973](https://issues.apache.org/jira/browse/CB-8973): Changed the functionality of making the `log` appear and disappear +* Ensure `WinJS` is available when adding **Windows** unhandled error hook + +### 1.0.1 (Jun 17, 2015) +* added ratignore file + +### 1.0.0 (Apr 15, 2015) +* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) gave plugin major version bump +* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) changed plugin-id to pacakge-name +* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) Updated Readme +* [CB-8528](https://issues.apache.org/jira/browse/CB-8528) Add a shim for `jasmine.Expectation.addMatchers` being moved in jasmine 2.2.0 +* [CB-8528](https://issues.apache.org/jira/browse/CB-8528) Update test framework plugin to use Jasmine 2.2.0 (close #11) +* Close already merged PR (close #10) +* [CB-8538](https://issues.apache.org/jira/browse/CB-8538) Added package.json file +* [CB-8385](https://issues.apache.org/jira/browse/CB-8385) Ensure plugin-test-framework trigger tests only once + +### 0.0.1 (Feb 04, 2015) +* Initial release diff --git a/plugins/cordova-plugin-test-framework/package.json b/plugins/cordova-plugin-test-framework/package.json new file mode 100644 index 0000000..7460f62 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/package.json @@ -0,0 +1,27 @@ +{ + "name": "cordova-plugin-test-framework", + "version": "1.1.2-dev", + "description": "Cordova Test Framework Plugin", + "cordova": { + "id": "cordova-plugin-test-framework", + "platforms": [] + }, + "repository": { + "type": "git", + "url": "https://github.com/apache/cordova-plugin-test-framework" + }, + "keywords": [ + "cordova", + "test", + "ecosystem:cordova" + ], + "scripts": { + "test": "npm run jshint", + "jshint": "jshint www" + }, + "author": "Apache Software Foundation", + "license": "Apache 2.0", + "devDependencies": { + "jshint": "^2.6.0" + } +} diff --git a/plugins/cordova-plugin-test-framework/plugin.xml b/plugins/cordova-plugin-test-framework/plugin.xml new file mode 100644 index 0000000..b5a4029 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/plugin.xml @@ -0,0 +1,40 @@ + + + + + Test Framework + Cordova Test Framework Plugin + Apache 2.0 + cordova,test + + + + + + + + + + + diff --git a/plugins/cordova-plugin-test-framework/www/assets/index.html b/plugins/cordova-plugin-test-framework/www/assets/index.html new file mode 100644 index 0000000..68460bc --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/index.html @@ -0,0 +1,63 @@ + + + + + + + + Cordova tests + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    Log
    +
    +
    + + diff --git a/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/boot.js b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/boot.js new file mode 100755 index 0000000..e8ddd55 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/boot.js @@ -0,0 +1,121 @@ +/** + Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project. + + If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms. + + The location of `boot.js` can be specified and/or overridden in `jasmine.yml`. + + [jasmine-gem]: http://github.com/pivotal/jasmine-gem + */ + +(function() { + + /** + * ## Require & Instantiate + * + * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference. + */ + window.jasmine = jasmineRequire.core(jasmineRequire); + + /** + * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference. + */ + jasmineRequire.html(jasmine); + + /** + * Create the Jasmine environment. This is used to run all specs in a project. + */ + var env = jasmine.getEnv(); + + /** + * ## The Global Interface + * + * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged. + */ + var jasmineInterface = jasmineRequire.interface(jasmine, env); + + /** + * Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`. + */ + if (typeof window == "undefined" && typeof exports == "object") { + extend(exports, jasmineInterface); + } else { + extend(window, jasmineInterface); + } + + /** + * ## Runner Parameters + * + * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface. + */ + + var queryString = new jasmine.QueryString({ + getWindowLocation: function() { return window.location; } + }); + + var catchingExceptions = queryString.getParam("catch"); + env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions); + + /** + * ## Reporters + * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any). + */ + var htmlReporter = new jasmine.HtmlReporter({ + env: env, + onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); }, + addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); }, + getContainer: function() { return document.body; }, + createElement: function() { return document.createElement.apply(document, arguments); }, + createTextNode: function() { return document.createTextNode.apply(document, arguments); }, + timer: new jasmine.Timer() + }); + + /** + * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript. + */ + env.addReporter(jasmineInterface.jsApiReporter); + env.addReporter(htmlReporter); + + /** + * Filter which specs will be run by matching the start of the full name against the `spec` query param. + */ + var specFilter = new jasmine.HtmlSpecFilter({ + filterString: function() { return queryString.getParam("spec"); } + }); + + env.specFilter = function(spec) { + return specFilter.matches(spec.getFullName()); + }; + + /** + * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack. + */ + window.setTimeout = window.setTimeout; + window.setInterval = window.setInterval; + window.clearTimeout = window.clearTimeout; + window.clearInterval = window.clearInterval; + + /** + * ## Execution + * + * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded. + */ + var currentWindowOnload = window.onload; + + window.onload = function() { + if (currentWindowOnload) { + currentWindowOnload(); + } + htmlReporter.initialize(); + env.execute(); + }; + + /** + * Helper function for readability above. + */ + function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; + } + +}()); diff --git a/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/console.js b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/console.js new file mode 100755 index 0000000..e154806 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/console.js @@ -0,0 +1,190 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +function getJasmineRequireObj() { + if (typeof module !== 'undefined' && module.exports) { + return exports; + } else { + window.jasmineRequire = window.jasmineRequire || {}; + return window.jasmineRequire; + } +} + +getJasmineRequireObj().console = function(jRequire, j$) { + j$.ConsoleReporter = jRequire.ConsoleReporter(); +}; + +getJasmineRequireObj().ConsoleReporter = function() { + + var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } + }; + + function ConsoleReporter(options) { + var print = options.print, + showColors = options.showColors || false, + onComplete = options.onComplete || function() {}, + timer = options.timer || noopTimer, + specCount, + failureCount, + failedSpecs = [], + pendingCount, + ansi = { + green: '\x1B[32m', + red: '\x1B[31m', + yellow: '\x1B[33m', + none: '\x1B[0m' + }, + failedSuites = []; + + print('ConsoleReporter is deprecated and will be removed in a future version.'); + + this.jasmineStarted = function() { + specCount = 0; + failureCount = 0; + pendingCount = 0; + print('Started'); + printNewline(); + timer.start(); + }; + + this.jasmineDone = function() { + printNewline(); + for (var i = 0; i < failedSpecs.length; i++) { + specFailureDetails(failedSpecs[i]); + } + + if(specCount > 0) { + printNewline(); + + var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' + + failureCount + ' ' + plural('failure', failureCount); + + if (pendingCount) { + specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount); + } + + print(specCounts); + } else { + print('No specs found'); + } + + printNewline(); + var seconds = timer.elapsed() / 1000; + print('Finished in ' + seconds + ' ' + plural('second', seconds)); + printNewline(); + + for(i = 0; i < failedSuites.length; i++) { + suiteFailureDetails(failedSuites[i]); + } + + onComplete(failureCount === 0); + }; + + this.specDone = function(result) { + specCount++; + + if (result.status == 'pending') { + pendingCount++; + print(colored('yellow', '*')); + return; + } + + if (result.status == 'passed') { + print(colored('green', '.')); + return; + } + + if (result.status == 'failed') { + failureCount++; + failedSpecs.push(result); + print(colored('red', 'F')); + } + }; + + this.suiteDone = function(result) { + if (result.failedExpectations && result.failedExpectations.length > 0) { + failureCount++; + failedSuites.push(result); + } + }; + + return this; + + function printNewline() { + print('\n'); + } + + function colored(color, str) { + return showColors ? (ansi[color] + str + ansi.none) : str; + } + + function plural(str, count) { + return count == 1 ? str : str + 's'; + } + + function repeat(thing, times) { + var arr = []; + for (var i = 0; i < times; i++) { + arr.push(thing); + } + return arr; + } + + function indent(str, spaces) { + var lines = (str || '').split('\n'); + var newArr = []; + for (var i = 0; i < lines.length; i++) { + newArr.push(repeat(' ', spaces).join('') + lines[i]); + } + return newArr.join('\n'); + } + + function specFailureDetails(result) { + printNewline(); + print(result.fullName); + + for (var i = 0; i < result.failedExpectations.length; i++) { + var failedExpectation = result.failedExpectations[i]; + printNewline(); + print(indent(failedExpectation.message, 2)); + print(indent(failedExpectation.stack, 2)); + } + + printNewline(); + } + + function suiteFailureDetails(result) { + for (var i = 0; i < result.failedExpectations.length; i++) { + printNewline(); + print(colored('red', 'An error was thrown in an afterAll')); + printNewline(); + print(colored('red', 'AfterAll ' + result.failedExpectations[i].message)); + + } + printNewline(); + } + } + + return ConsoleReporter; +}; diff --git a/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine-html.js b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine-html.js new file mode 100755 index 0000000..bee5a04 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine-html.js @@ -0,0 +1,416 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +jasmineRequire.html = function(j$) { + j$.ResultsNode = jasmineRequire.ResultsNode(); + j$.HtmlReporter = jasmineRequire.HtmlReporter(j$); + j$.QueryString = jasmineRequire.QueryString(); + j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter(); +}; + +jasmineRequire.HtmlReporter = function(j$) { + + var noopTimer = { + start: function() {}, + elapsed: function() { return 0; } + }; + + function HtmlReporter(options) { + var env = options.env || {}, + getContainer = options.getContainer, + createElement = options.createElement, + createTextNode = options.createTextNode, + onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {}, + addToExistingQueryString = options.addToExistingQueryString || defaultQueryString, + timer = options.timer || noopTimer, + results = [], + specsExecuted = 0, + failureCount = 0, + pendingSpecCount = 0, + htmlReporterMain, + symbols, + failedSuites = []; + + this.initialize = function() { + clearPrior(); + htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'}, + createDom('div', {className: 'banner'}, + createDom('a', {className: 'title', href: 'http://jasmine.github.io/', target: '_blank'}), + createDom('span', {className: 'version'}, j$.version) + ), + createDom('ul', {className: 'symbol-summary'}), + createDom('div', {className: 'alert'}), + createDom('div', {className: 'results'}, + createDom('div', {className: 'failures'}) + ) + ); + getContainer().appendChild(htmlReporterMain); + + symbols = find('.symbol-summary'); + }; + + var totalSpecsDefined; + this.jasmineStarted = function(options) { + totalSpecsDefined = options.totalSpecsDefined || 0; + timer.start(); + }; + + var summary = createDom('div', {className: 'summary'}); + + var topResults = new j$.ResultsNode({}, '', null), + currentParent = topResults; + + this.suiteStarted = function(result) { + currentParent.addChild(result, 'suite'); + currentParent = currentParent.last(); + }; + + this.suiteDone = function(result) { + if (result.status == 'failed') { + failedSuites.push(result); + } + + if (currentParent == topResults) { + return; + } + + currentParent = currentParent.parent; + }; + + this.specStarted = function(result) { + currentParent.addChild(result, 'spec'); + }; + + var failures = []; + this.specDone = function(result) { + if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') { + console.error('Spec \'' + result.fullName + '\' has no expectations.'); + } + + if (result.status != 'disabled') { + specsExecuted++; + } + + symbols.appendChild(createDom('li', { + className: noExpectations(result) ? 'empty' : result.status, + id: 'spec_' + result.id, + title: result.fullName + } + )); + + if (result.status == 'failed') { + failureCount++; + + var failure = + createDom('div', {className: 'spec-detail failed'}, + createDom('div', {className: 'description'}, + createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName) + ), + createDom('div', {className: 'messages'}) + ); + var messages = failure.childNodes[1]; + + for (var i = 0; i < result.failedExpectations.length; i++) { + var expectation = result.failedExpectations[i]; + messages.appendChild(createDom('div', {className: 'result-message'}, expectation.message)); + messages.appendChild(createDom('div', {className: 'stack-trace'}, expectation.stack)); + } + + failures.push(failure); + } + + if (result.status == 'pending') { + pendingSpecCount++; + } + }; + + this.jasmineDone = function() { + var banner = find('.banner'); + banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's')); + + var alert = find('.alert'); + + alert.appendChild(createDom('span', { className: 'exceptions' }, + createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions'), + createDom('input', { + className: 'raise', + id: 'raise-exceptions', + type: 'checkbox' + }) + )); + var checkbox = find('#raise-exceptions'); + + checkbox.checked = !env.catchingExceptions(); + checkbox.onclick = onRaiseExceptionsClick; + + if (specsExecuted < totalSpecsDefined) { + var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all'; + alert.appendChild( + createDom('span', {className: 'bar skipped'}, + createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage) + ) + ); + } + var statusBarMessage = ''; + var statusBarClassName = 'bar '; + + if (totalSpecsDefined > 0) { + statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount); + if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); } + statusBarClassName += (failureCount > 0) ? 'failed' : 'passed'; + } else { + statusBarClassName += 'skipped'; + statusBarMessage += 'No specs found'; + } + + alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage)); + + for(i = 0; i < failedSuites.length; i++) { + var failedSuite = failedSuites[i]; + for(var j = 0; j < failedSuite.failedExpectations.length; j++) { + var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message; + var errorBarClassName = 'bar errored'; + alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage)); + } + } + + var results = find('.results'); + results.appendChild(summary); + + summaryList(topResults, summary); + + function summaryList(resultsTree, domParent) { + var specListNode; + for (var i = 0; i < resultsTree.children.length; i++) { + var resultNode = resultsTree.children[i]; + if (resultNode.type == 'suite') { + var suiteListNode = createDom('ul', {className: 'suite', id: 'suite-' + resultNode.result.id}, + createDom('li', {className: 'suite-detail'}, + createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description) + ) + ); + + summaryList(resultNode, suiteListNode); + domParent.appendChild(suiteListNode); + } + if (resultNode.type == 'spec') { + if (domParent.getAttribute('class') != 'specs') { + specListNode = createDom('ul', {className: 'specs'}); + domParent.appendChild(specListNode); + } + var specDescription = resultNode.result.description; + if(noExpectations(resultNode.result)) { + specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription; + } + if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') { + specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason; + } + specListNode.appendChild( + createDom('li', { + className: resultNode.result.status, + id: 'spec-' + resultNode.result.id + }, + createDom('a', {href: specHref(resultNode.result)}, specDescription) + ) + ); + } + } + } + + if (failures.length) { + alert.appendChild( + createDom('span', {className: 'menu bar spec-list'}, + createDom('span', {}, 'Spec List | '), + createDom('a', {className: 'failures-menu', href: '#'}, 'Failures'))); + alert.appendChild( + createDom('span', {className: 'menu bar failure-list'}, + createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'), + createDom('span', {}, ' | Failures '))); + + find('.failures-menu').onclick = function() { + setMenuModeTo('failure-list'); + }; + find('.spec-list-menu').onclick = function() { + setMenuModeTo('spec-list'); + }; + + setMenuModeTo('failure-list'); + + var failureNode = find('.failures'); + for (var i = 0; i < failures.length; i++) { + failureNode.appendChild(failures[i]); + } + } + }; + + return this; + + function find(selector) { + return getContainer().querySelector('.jasmine_html-reporter ' + selector); + } + + function clearPrior() { + // return the reporter + var oldReporter = find(''); + + if(oldReporter) { + getContainer().removeChild(oldReporter); + } + } + + function createDom(type, attrs, childrenVarArgs) { + var el = createElement(type); + + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i]; + + if (typeof child === 'string') { + el.appendChild(createTextNode(child)); + } else { + if (child) { + el.appendChild(child); + } + } + } + + for (var attr in attrs) { + if (attr == 'className') { + el[attr] = attrs[attr]; + } else { + el.setAttribute(attr, attrs[attr]); + } + } + + return el; + } + + function pluralize(singular, count) { + var word = (count == 1 ? singular : singular + 's'); + + return '' + count + ' ' + word; + } + + function specHref(result) { + return addToExistingQueryString('spec', result.fullName); + } + + function defaultQueryString(key, value) { + return '?' + key + '=' + value; + } + + function setMenuModeTo(mode) { + htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode); + } + + function noExpectations(result) { + return (result.failedExpectations.length + result.passedExpectations.length) === 0 && + result.status === 'passed'; + } + } + + return HtmlReporter; +}; + +jasmineRequire.HtmlSpecFilter = function() { + function HtmlSpecFilter(options) { + var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + var filterPattern = new RegExp(filterString); + + this.matches = function(specName) { + return filterPattern.test(specName); + }; + } + + return HtmlSpecFilter; +}; + +jasmineRequire.ResultsNode = function() { + function ResultsNode(result, type, parent) { + this.result = result; + this.type = type; + this.parent = parent; + + this.children = []; + + this.addChild = function(result, type) { + this.children.push(new ResultsNode(result, type, this)); + }; + + this.last = function() { + return this.children[this.children.length - 1]; + }; + } + + return ResultsNode; +}; + +jasmineRequire.QueryString = function() { + function QueryString(options) { + + this.navigateWithNewParam = function(key, value) { + options.getWindowLocation().search = this.fullStringWithNewParam(key, value); + }; + + this.fullStringWithNewParam = function(key, value) { + var paramMap = queryStringToParamMap(); + paramMap[key] = value; + return toQueryString(paramMap); + }; + + this.getParam = function(key) { + return queryStringToParamMap()[key]; + }; + + return this; + + function toQueryString(paramMap) { + var qStrPairs = []; + for (var prop in paramMap) { + qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop])); + } + return '?' + qStrPairs.join('&'); + } + + function queryStringToParamMap() { + var paramStr = options.getWindowLocation().search.substring(1), + params = [], + paramMap = {}; + + if (paramStr.length > 0) { + params = paramStr.split('&'); + for (var i = 0; i < params.length; i++) { + var p = params[i].split('='); + var value = decodeURIComponent(p[1]); + if (value === 'true' || value === 'false') { + value = JSON.parse(value); + } + paramMap[decodeURIComponent(p[0])] = value; + } + } + + return paramMap; + } + + } + + return QueryString; +}; diff --git a/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine.css b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine.css new file mode 100755 index 0000000..ecc5f5e --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine.css @@ -0,0 +1,62 @@ +body { overflow-y: scroll; } + +.jasmine_html-reporter { background-color: #eee; padding: 5px; margin: -8px; font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333; } +.jasmine_html-reporter a { text-decoration: none; } +.jasmine_html-reporter a:hover { text-decoration: underline; } +.jasmine_html-reporter p, .jasmine_html-reporter h1, .jasmine_html-reporter h2, .jasmine_html-reporter h3, .jasmine_html-reporter h4, .jasmine_html-reporter h5, .jasmine_html-reporter h6 { margin: 0; line-height: 14px; } +.jasmine_html-reporter .banner, .jasmine_html-reporter .symbol-summary, .jasmine_html-reporter .summary, .jasmine_html-reporter .result-message, .jasmine_html-reporter .spec .description, .jasmine_html-reporter .spec-detail .description, .jasmine_html-reporter .alert .bar, .jasmine_html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; } +.jasmine_html-reporter .banner { position: relative; } +.jasmine_html-reporter .banner .title { background: url('data:image/png;base64,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') no-repeat; background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICB3aWR0aD0iNjgxLjk2MjUyIgogICBoZWlnaHQ9IjE4Ny41IgogICBpZD0ic3ZnMiIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhOCI+PHJkZjpSREY+PGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMKICAgICBpZD0iZGVmczYiPjxjbGlwUGF0aAogICAgICAgaWQ9ImNsaXBQYXRoMTgiPjxwYXRoCiAgICAgICAgIGQ9Ik0gMCwxNTAwIDAsMCBsIDU0NTUuNzQsMCAwLDE1MDAgTCAwLDE1MDAgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgyMCIgLz48L2NsaXBQYXRoPjwvZGVmcz48ZwogICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMjUsMCwwLC0xLjI1LDAsMTg3LjUpIgogICAgIGlkPSJnMTAiPjxnCiAgICAgICB0cmFuc2Zvcm09InNjYWxlKDAuMSwwLjEpIgogICAgICAgaWQ9ImcxMiI+PGcKICAgICAgICAgaWQ9ImcxNCI+PGcKICAgICAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGgxOCkiCiAgICAgICAgICAgaWQ9ImcxNiI+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTU0NCw1OTkuNDM0IGMgMC45MiwtNDAuMzUyIDI1LjY4LC04MS42MDIgNzEuNTMsLTgxLjYwMiAyNy41MSwwIDQ3LjY4LDEyLjgzMiA2MS40NCwzNS43NTQgMTIuODMsMjIuOTMgMTIuODMsNTYuODUyIDEyLjgzLDgyLjUyNyBsIDAsMzI5LjE4NCAtNzEuNTIsMCAwLDEwNC41NDMgMjY2LjgzLDAgMCwtMTA0LjU0MyAtNzAuNiwwIDAsLTM0NC43NyBjIDAsLTU4LjY5MSAtMy42OCwtMTA0LjUzMSAtNDQuOTMsLTE1Mi4yMTggLTM2LjY4LC00Mi4xOCAtOTYuMjgsLTY2LjAyIC0xNTMuMTQsLTY2LjAyIC0xMTcuMzcsMCAtMjA3LjI0LDc3Ljk0MSAtMjAyLjY0LDE5Ny4xNDUgbCAxMzAuMiwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMjIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDIzMDEuNCw2NjIuNjk1IGMgMCw4MC43MDMgLTY2Ljk0LDE0NS44MTMgLTE0Ny42MywxNDUuODEzIC04My40NCwwIC0xNDcuNjMsLTY4Ljc4MSAtMTQ3LjYzLC0xNTEuMzAxIDAsLTc5Ljc4NSA2Ni45NCwtMTQ1LjgwMSAxNDUuOCwtMTQ1LjgwMSA4NC4zNSwwIDE0OS40Niw2Ny44NTIgMTQ5LjQ2LDE1MS4yODkgeiBtIC0xLjgzLC0xODEuNTQ3IGMgLTM1Ljc3LC01NC4wOTcgLTkzLjUzLC03OC44NTkgLTE1Ny43MiwtNzguODU5IC0xNDAuMywwIC0yNTEuMjQsMTE2LjQ0OSAtMjUxLjI0LDI1NC45MTggMCwxNDIuMTI5IDExMy43LDI2MC40MSAyNTYuNzQsMjYwLjQxIDYzLjI3LDAgMTE4LjI5LC0yOS4zMzYgMTUyLjIyLC04Mi41MjMgbCAwLDY5LjY4NyAxNzUuMTQsMCAwLC0xMDQuNTI3IC02MS40NCwwIDAsLTI4MC41OTggNjEuNDQsMCAwLC0xMDQuNTI3IC0xNzUuMTQsMCAwLDY2LjAxOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAyNjIyLjMzLDU1Ny4yNTggYyAzLjY3LC00NC4wMTYgMzMuMDEsLTczLjM0OCA3OC44NiwtNzMuMzQ4IDMzLjkzLDAgNjYuOTMsMjMuODI0IDY2LjkzLDYwLjUwNCAwLDQ4LjYwNiAtNDUuODQsNTYuODU2IC04My40NCw2Ni45NDEgLTg1LjI4LDIyLjAwNCAtMTc4LjgxLDQ4LjYwNiAtMTc4LjgxLDE1NS44NzkgMCw5My41MzYgNzguODYsMTQ3LjYzMyAxNjUuOTgsMTQ3LjYzMyA0NCwwIDgzLjQzLC05LjE3NiAxMTAuOTQsLTQ0LjAwOCBsIDAsMzMuOTIyIDgyLjUzLDAgMCwtMTMyLjk2NSAtMTA4LjIxLDAgYyAtMS44MywzNC44NTYgLTI4LjQyLDU3Ljc3NCAtNjMuMjYsNTcuNzc0IC0zMC4yNiwwIC02Mi4zNSwtMTcuNDIyIC02Mi4zNSwtNTEuMzQ4IDAsLTQ1Ljg0NyA0NC45MywtNTUuOTMgODAuNjksLTY0LjE4IDg4LjAyLC0yMC4xNzUgMTgyLjQ3LC00Ny42OTUgMTgyLjQ3LC0xNTcuNzM0IDAsLTk5LjAyNyAtODMuNDQsLTE1NC4wMzkgLTE3NS4xMywtMTU0LjAzOSAtNDkuNTMsMCAtOTQuNDYsMTUuNTgyIC0xMjYuNTUsNTMuMTggbCAwLC00MC4zNCAtODUuMjcsMCAwLDE0Mi4xMjkgMTE0LjYyLDAiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGgyNiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMjk4OC4xOCw4MDAuMjU0IC02My4yNiwwIDAsMTA0LjUyNyAxNjUuMDUsMCAwLC03My4zNTUgYyAzMS4xOCw1MS4zNDcgNzguODYsODUuMjc3IDE0MS4yMSw4NS4yNzcgNjcuODUsMCAxMjQuNzEsLTQxLjI1OCAxNTIuMjEsLTEwMi42OTkgMjYuNiw2Mi4zNTEgOTIuNjIsMTAyLjY5OSAxNjAuNDcsMTAyLjY5OSA1My4xOSwwIDEwNS40NiwtMjIgMTQxLjIxLC02Mi4zNTEgMzguNTIsLTQ0LjkzOCAzOC41MiwtOTMuNTMyIDM4LjUyLC0xNDkuNDU3IGwgMCwtMTg1LjIzOSA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40MiwwIDAsMTA0LjUyNyA2My4yOCwwIDAsMTU3LjcxNSBjIDAsMzIuMTAyIDAsNjAuNTI3IC0xNC42Nyw4OC45NTcgLTE4LjM0LDI2LjU4MiAtNDguNjEsNDAuMzQ0IC03OS43Nyw0MC4zNDQgLTMwLjI2LDAgLTYzLjI4LC0xMi44NDQgLTgyLjUzLC0zNi42NzIgLTIyLjkzLC0yOS4zNTUgLTIyLjkzLC01Ni44NjMgLTIyLjkzLC05Mi42MjkgbCAwLC0xNTcuNzE1IDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM4LjQxLDAgMCwxMDQuNTI3IDYzLjI4LDAgMCwxNTAuMzgzIGMgMCwyOS4zNDggMCw2Ni4wMjMgLTE0LjY3LDkxLjY5OSAtMTUuNTksMjkuMzM2IC00Ny42OSw0NC45MzQgLTgwLjcsNDQuOTM0IC0zMS4xOCwwIC01Ny43NywtMTEuMDA4IC03Ny45NCwtMzUuNzc0IC0yNC43NywtMzAuMjUzIC0yNi42LC02Mi4zNDMgLTI2LjYsLTk5Ljk0MSBsIDAsLTE1MS4zMDEgNjMuMjcsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNiwwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAzOTk4LjY2LDk1MS41NDcgLTExMS44NywwIDAsMTE4LjI5MyAxMTEuODcsMCAwLC0xMTguMjkzIHogbSAwLC00MzEuODkxIDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM5LjMzLDAgMCwxMDQuNTI3IDY0LjE5LDAgMCwyODAuNTk4IC02My4yNywwIDAsMTA0LjUyNyAxNzUuMTQsMCAwLC0zODUuMTI1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzAiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDQxNTkuMTIsODAwLjI1NCAtNjMuMjcsMCAwLDEwNC41MjcgMTc1LjE0LDAgMCwtNjkuNjg3IGMgMjkuMzUsNTQuMTAxIDg0LjM2LDgwLjY5OSAxNDQuODcsODAuNjk5IDUzLjE5LDAgMTA1LjQ1LC0yMi4wMTYgMTQxLjIyLC02MC41MjcgNDAuMzQsLTQ0LjkzNCA0MS4yNiwtODguMDMyIDQxLjI2LC0xNDMuOTU3IGwgMCwtMTkxLjY1MyA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40LDAgMCwxMDQuNTI3IDYzLjI2LDAgMCwxNTguNjM3IGMgMCwzMC4yNjIgMCw2MS40MzQgLTE5LjI2LDg4LjAzNSAtMjAuMTcsMjYuNTgyIC01My4xOCwzOS40MTQgLTg2LjE5LDM5LjQxNCAtMzMuOTMsMCAtNjguNzcsLTEzLjc1IC04OC45NCwtNDEuMjUgLTIxLjA5LC0yNy41IC0yMS4wOSwtNjkuNjg3IC0yMS4wOSwtMTAyLjcwNyBsIDAsLTE0Mi4xMjkgNjMuMjYsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNywwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDMyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA1MDgyLjQ4LDcwMy45NjUgYyAtMTkuMjQsNzAuNjA1IC04MS42LDExNS41NDcgLTE1NC4wNCwxMTUuNTQ3IC02Ni4wNCwwIC0xMjkuMywtNTEuMzQ4IC0xNDMuMDUsLTExNS41NDcgbCAyOTcuMDksMCB6IG0gODUuMjcsLTE0NC44ODMgYyAtMzguNTEsLTkzLjUyMyAtMTI5LjI3LC0xNTYuNzkzIC0yMzEuMDUsLTE1Ni43OTMgLTE0My4wNywwIC0yNTcuNjgsMTExLjg3MSAtMjU3LjY4LDI1NS44MzYgMCwxNDQuODgzIDEwOS4xMiwyNjEuMzI4IDI1NC45MSwyNjEuMzI4IDY3Ljg3LDAgMTM1LjcyLC0zMC4yNTggMTgzLjM5LC03OC44NjMgNDguNjIsLTUxLjM0NCA2OC43OSwtMTEzLjY5NSA2OC43OSwtMTgzLjM4MyBsIC0zLjY3LC0zOS40MzQgLTM5Ni4xMywwIGMgMTQuNjcsLTY3Ljg2MyA3Ny4wMywtMTE3LjM2MyAxNDYuNzIsLTExNy4zNjMgNDguNTksMCA5MC43NiwxOC4zMjggMTE4LjI4LDU4LjY3MiBsIDExNi40NCwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDY5MC44OTUsODUwLjcwMyA5MC43NSwwIDIyLjU0MywzMS4wMzUgMCwyNDMuMTIyIC0xMzUuODI5LDAgMCwtMjQzLjE0MSAyMi41MzYsLTMxLjAxNiIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDM2IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA2MzIuMzk1LDc0Mi4yNTggMjguMDM5LDg2LjMwNCAtMjIuNTUxLDMxLjA0IC0yMzEuMjIzLDc1LjEyOCAtNDEuOTc2LC0xMjkuMTgzIDIzMS4yNTcsLTc1LjEzNyAzNi40NTQsMTEuODQ4IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzgiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDcxNy40NDksNjUzLjEwNSAtNzMuNDEsNTMuMzYgLTM2LjQ4OCwtMTEuODc1IC0xNDIuOTAzLC0xOTYuNjkyIDEwOS44ODMsLTc5LjgyOCAxNDIuOTE4LDE5Ni43MDMgMCwzOC4zMzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0MCIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gODI4LjUyLDcwNi40NjUgLTczLjQyNiwtNTMuMzQgMC4wMTEsLTM4LjM1OSBMIDg5OC4wMDQsNDE4LjA3IDEwMDcuOSw0OTcuODk4IDg2NC45NzMsNjk0LjYwOSA4MjguNTIsNzA2LjQ2NSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA4MTIuMDg2LDgyOC41ODYgMjguMDU1LC04Ni4zMiAzNi40ODQsLTExLjgzNiAyMzEuMjI1LDc1LjExNyAtNDEuOTcsMTI5LjE4MyAtMjMxLjIzOSwtNzUuMTQgLTIyLjU1NSwtMzEuMDA0IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNDQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDczNi4zMDEsMTMzNS44OCBjIC0zMjMuMDQ3LDAgLTU4NS44NzUsLTI2Mi43OCAtNTg1Ljg3NSwtNTg1Ljc4MiAwLC0zMjMuMTE4IDI2Mi44MjgsLTU4NS45NzcgNTg1Ljg3NSwtNTg1Ljk3NyAzMjMuMDE5LDAgNTg1LjgwOSwyNjIuODU5IDU4NS44MDksNTg1Ljk3NyAwLDMyMy4wMDIgLTI2Mi43OSw1ODUuNzgyIC01ODUuODA5LDU4NS43ODIgbCAwLDAgeiBtIDAsLTExOC42MSBjIDI1Ny45NzIsMCA0NjcuMTg5LC0yMDkuMTMgNDY3LjE4OSwtNDY3LjE3MiAwLC0yNTguMTI5IC0yMDkuMjE3LC00NjcuMzQ4IC00NjcuMTg5LC00NjcuMzQ4IC0yNTguMDc0LDAgLTQ2Ny4yNTQsMjA5LjIxOSAtNDY3LjI1NCw0NjcuMzQ4IDAsMjU4LjA0MiAyMDkuMTgsNDY3LjE3MiA0NjcuMjU0LDQ2Ny4xNzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0NiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTA5MS4xMyw2MTkuODgzIC0xNzUuNzcxLDU3LjEyMSAxMS42MjksMzUuODA4IDE3NS43NjIsLTU3LjEyMSAtMTEuNjIsLTM1LjgwOCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQ4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA4NjYuOTU3LDkwMi4wNzQgODM2LjUsOTI0LjE5OSA5NDUuMTIxLDEwNzMuNzMgOTc1LjU4NiwxMDUxLjYxIDg2Ni45NTcsOTAyLjA3NCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDUwIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA2MDcuNDY1LDkwMy40NDUgNDk4Ljg1NSwxMDUyLjk3IDUyOS4zMiwxMDc1LjEgNjM3LjkzLDkyNS41NjYgNjA3LjQ2NSw5MDMuNDQ1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDM4MC42ODgsNjIyLjEyOSAtMTEuNjI2LDM1LjgwMSAxNzUuNzU4LDU3LjA5IDExLjYyMSwtMzUuODAxIC0xNzUuNzUzLC01Ny4wOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDU0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA3MTYuMjg5LDM3Ni41OSAzNy42NDA2LDAgMCwxODQuODE2IC0zNy42NDA2LDAgMCwtMTg0LjgxNiB6IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTYiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4=') no-repeat, none; -moz-background-size: 100%; -o-background-size: 100%; -webkit-background-size: 100%; background-size: 100%; display: block; float: left; width: 90px; height: 25px; } +.jasmine_html-reporter .banner .version { margin-left: 14px; position: relative; top: 6px; } +.jasmine_html-reporter .banner .duration { position: absolute; right: 14px; top: 6px; } +.jasmine_html-reporter #jasmine_content { position: fixed; right: 100%; } +.jasmine_html-reporter .version { color: #aaa; } +.jasmine_html-reporter .banner { margin-top: 14px; } +.jasmine_html-reporter .duration { color: #aaa; float: right; } +.jasmine_html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; } +.jasmine_html-reporter .symbol-summary li { display: inline-block; height: 8px; width: 14px; font-size: 16px; } +.jasmine_html-reporter .symbol-summary li.passed { font-size: 14px; } +.jasmine_html-reporter .symbol-summary li.passed:before { color: #007069; content: "\02022"; } +.jasmine_html-reporter .symbol-summary li.failed { line-height: 9px; } +.jasmine_html-reporter .symbol-summary li.failed:before { color: #ca3a11; content: "\d7"; font-weight: bold; margin-left: -1px; } +.jasmine_html-reporter .symbol-summary li.disabled { font-size: 14px; } +.jasmine_html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; } +.jasmine_html-reporter .symbol-summary li.pending { line-height: 17px; } +.jasmine_html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; } +.jasmine_html-reporter .symbol-summary li.empty { font-size: 14px; } +.jasmine_html-reporter .symbol-summary li.empty:before { color: #ba9d37; content: "\02022"; } +.jasmine_html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; } +.jasmine_html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } +.jasmine_html-reporter .bar.failed { background-color: #ca3a11; } +.jasmine_html-reporter .bar.passed { background-color: #007069; } +.jasmine_html-reporter .bar.skipped { background-color: #bababa; } +.jasmine_html-reporter .bar.errored { background-color: #ca3a11; } +.jasmine_html-reporter .bar.menu { background-color: #fff; color: #aaa; } +.jasmine_html-reporter .bar.menu a { color: #333; } +.jasmine_html-reporter .bar a { color: white; } +.jasmine_html-reporter.spec-list .bar.menu.failure-list, .jasmine_html-reporter.spec-list .results .failures { display: none; } +.jasmine_html-reporter.failure-list .bar.menu.spec-list, .jasmine_html-reporter.failure-list .summary { display: none; } +.jasmine_html-reporter .running-alert { background-color: #666; } +.jasmine_html-reporter .results { margin-top: 14px; } +.jasmine_html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; } +.jasmine_html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; } +.jasmine_html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; } +.jasmine_html-reporter.showDetails .summary { display: none; } +.jasmine_html-reporter.showDetails #details { display: block; } +.jasmine_html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; } +.jasmine_html-reporter .summary { margin-top: 14px; } +.jasmine_html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; } +.jasmine_html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; } +.jasmine_html-reporter .summary li.passed a { color: #007069; } +.jasmine_html-reporter .summary li.failed a { color: #ca3a11; } +.jasmine_html-reporter .summary li.empty a { color: #ba9d37; } +.jasmine_html-reporter .summary li.pending a { color: #ba9d37; } +.jasmine_html-reporter .description + .suite { margin-top: 0; } +.jasmine_html-reporter .suite { margin-top: 14px; } +.jasmine_html-reporter .suite a { color: #333; } +.jasmine_html-reporter .failures .spec-detail { margin-bottom: 28px; } +.jasmine_html-reporter .failures .spec-detail .description { background-color: #ca3a11; } +.jasmine_html-reporter .failures .spec-detail .description a { color: white; } +.jasmine_html-reporter .result-message { padding-top: 14px; color: #333; white-space: pre; } +.jasmine_html-reporter .result-message span.result { display: block; } +.jasmine_html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666; border: 1px solid #ddd; background: white; white-space: pre; } diff --git a/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine.js b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine.js new file mode 100755 index 0000000..6bf3f02 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine.js @@ -0,0 +1,3048 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +var getJasmineRequireObj = (function (jasmineGlobal) { + var jasmineRequire; + + if (typeof module !== 'undefined' && module.exports) { + jasmineGlobal = global; + jasmineRequire = exports; + } else { + if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') { + jasmineGlobal = window; + } + jasmineRequire = jasmineGlobal.jasmineRequire = jasmineGlobal.jasmineRequire || {}; + } + + function getJasmineRequire() { + return jasmineRequire; + } + + getJasmineRequire().core = function(jRequire) { + var j$ = {}; + + jRequire.base(j$, jasmineGlobal); + j$.util = jRequire.util(); + j$.Any = jRequire.Any(); + j$.Anything = jRequire.Anything(j$); + j$.CallTracker = jRequire.CallTracker(); + j$.MockDate = jRequire.MockDate(); + j$.Clock = jRequire.Clock(); + j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(); + j$.Env = jRequire.Env(j$); + j$.ExceptionFormatter = jRequire.ExceptionFormatter(); + j$.Expectation = jRequire.Expectation(); + j$.buildExpectationResult = jRequire.buildExpectationResult(); + j$.JsApiReporter = jRequire.JsApiReporter(); + j$.matchersUtil = jRequire.matchersUtil(j$); + j$.ObjectContaining = jRequire.ObjectContaining(j$); + j$.ArrayContaining = jRequire.ArrayContaining(j$); + j$.pp = jRequire.pp(j$); + j$.QueueRunner = jRequire.QueueRunner(j$); + j$.ReportDispatcher = jRequire.ReportDispatcher(); + j$.Spec = jRequire.Spec(j$); + j$.SpyRegistry = jRequire.SpyRegistry(j$); + j$.SpyStrategy = jRequire.SpyStrategy(); + j$.StringMatching = jRequire.StringMatching(j$); + j$.Suite = jRequire.Suite(); + j$.Timer = jRequire.Timer(); + j$.version = jRequire.version(); + + j$.matchers = jRequire.requireMatchers(jRequire, j$); + + return j$; + }; + + return getJasmineRequire; +})(this); + +getJasmineRequireObj().requireMatchers = function(jRequire, j$) { + var availableMatchers = [ + 'toBe', + 'toBeCloseTo', + 'toBeDefined', + 'toBeFalsy', + 'toBeGreaterThan', + 'toBeLessThan', + 'toBeNaN', + 'toBeNull', + 'toBeTruthy', + 'toBeUndefined', + 'toContain', + 'toEqual', + 'toHaveBeenCalled', + 'toHaveBeenCalledWith', + 'toMatch', + 'toThrow', + 'toThrowError' + ], + matchers = {}; + + for (var i = 0; i < availableMatchers.length; i++) { + var name = availableMatchers[i]; + matchers[name] = jRequire[name](j$); + } + + return matchers; +}; + +getJasmineRequireObj().base = function(j$, jasmineGlobal) { + j$.unimplementedMethod_ = function() { + throw new Error('unimplemented method'); + }; + + j$.MAX_PRETTY_PRINT_DEPTH = 40; + j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 100; + j$.DEFAULT_TIMEOUT_INTERVAL = 5000; + + j$.getGlobal = function() { + return jasmineGlobal; + }; + + j$.getEnv = function(options) { + var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options); + //jasmine. singletons in here (setTimeout blah blah). + return env; + }; + + j$.isArray_ = function(value) { + return j$.isA_('Array', value); + }; + + j$.isString_ = function(value) { + return j$.isA_('String', value); + }; + + j$.isNumber_ = function(value) { + return j$.isA_('Number', value); + }; + + j$.isA_ = function(typeName, value) { + return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; + }; + + j$.isDomNode = function(obj) { + return obj.nodeType > 0; + }; + + j$.fnNameFor = function(func) { + return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1]; + }; + + j$.any = function(clazz) { + return new j$.Any(clazz); + }; + + j$.anything = function() { + return new j$.Anything(); + }; + + j$.objectContaining = function(sample) { + return new j$.ObjectContaining(sample); + }; + + j$.stringMatching = function(expected) { + return new j$.StringMatching(expected); + }; + + j$.arrayContaining = function(sample) { + return new j$.ArrayContaining(sample); + }; + + j$.createSpy = function(name, originalFn) { + + var spyStrategy = new j$.SpyStrategy({ + name: name, + fn: originalFn, + getSpy: function() { return spy; } + }), + callTracker = new j$.CallTracker(), + spy = function() { + var callData = { + object: this, + args: Array.prototype.slice.apply(arguments) + }; + + callTracker.track(callData); + var returnValue = spyStrategy.exec.apply(this, arguments); + callData.returnValue = returnValue; + + return returnValue; + }; + + for (var prop in originalFn) { + if (prop === 'and' || prop === 'calls') { + throw new Error('Jasmine spies would overwrite the \'and\' and \'calls\' properties on the object being spied upon'); + } + + spy[prop] = originalFn[prop]; + } + + spy.and = spyStrategy; + spy.calls = callTracker; + + return spy; + }; + + j$.isSpy = function(putativeSpy) { + if (!putativeSpy) { + return false; + } + return putativeSpy.and instanceof j$.SpyStrategy && + putativeSpy.calls instanceof j$.CallTracker; + }; + + j$.createSpyObj = function(baseName, methodNames) { + if (j$.isArray_(baseName) && j$.util.isUndefined(methodNames)) { + methodNames = baseName; + baseName = 'unknown'; + } + + if (!j$.isArray_(methodNames) || methodNames.length === 0) { + throw 'createSpyObj requires a non-empty array of method names to create spies for'; + } + var obj = {}; + for (var i = 0; i < methodNames.length; i++) { + obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]); + } + return obj; + }; +}; + +getJasmineRequireObj().util = function() { + + var util = {}; + + util.inherit = function(childClass, parentClass) { + var Subclass = function() { + }; + Subclass.prototype = parentClass.prototype; + childClass.prototype = new Subclass(); + }; + + util.htmlEscape = function(str) { + if (!str) { + return str; + } + return str.replace(/&/g, '&') + .replace(//g, '>'); + }; + + util.argsToArray = function(args) { + var arrayOfArgs = []; + for (var i = 0; i < args.length; i++) { + arrayOfArgs.push(args[i]); + } + return arrayOfArgs; + }; + + util.isUndefined = function(obj) { + return obj === void 0; + }; + + util.arrayContains = function(array, search) { + var i = array.length; + while (i--) { + if (array[i] === search) { + return true; + } + } + return false; + }; + + util.clone = function(obj) { + if (Object.prototype.toString.apply(obj) === '[object Array]') { + return obj.slice(); + } + + var cloned = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + cloned[prop] = obj[prop]; + } + } + + return cloned; + }; + + return util; +}; + +getJasmineRequireObj().Spec = function(j$) { + function Spec(attrs) { + this.expectationFactory = attrs.expectationFactory; + this.resultCallback = attrs.resultCallback || function() {}; + this.id = attrs.id; + this.description = attrs.description || ''; + this.queueableFn = attrs.queueableFn; + this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; }; + this.userContext = attrs.userContext || function() { return {}; }; + this.onStart = attrs.onStart || function() {}; + this.getSpecName = attrs.getSpecName || function() { return ''; }; + this.expectationResultFactory = attrs.expectationResultFactory || function() { }; + this.queueRunnerFactory = attrs.queueRunnerFactory || function() {}; + this.catchingExceptions = attrs.catchingExceptions || function() { return true; }; + + if (!this.queueableFn.fn) { + this.pend(); + } + + this.result = { + id: this.id, + description: this.description, + fullName: this.getFullName(), + failedExpectations: [], + passedExpectations: [], + pendingReason: '' + }; + } + + Spec.prototype.addExpectationResult = function(passed, data) { + var expectationResult = this.expectationResultFactory(data); + if (passed) { + this.result.passedExpectations.push(expectationResult); + } else { + this.result.failedExpectations.push(expectationResult); + } + }; + + Spec.prototype.expect = function(actual) { + return this.expectationFactory(actual, this); + }; + + Spec.prototype.execute = function(onComplete) { + var self = this; + + this.onStart(this); + + if (this.markedPending || this.disabled) { + complete(); + return; + } + + var fns = this.beforeAndAfterFns(); + var allFns = fns.befores.concat(this.queueableFn).concat(fns.afters); + + this.queueRunnerFactory({ + queueableFns: allFns, + onException: function() { self.onException.apply(self, arguments); }, + onComplete: complete, + userContext: this.userContext() + }); + + function complete() { + self.result.status = self.status(); + self.resultCallback(self.result); + + if (onComplete) { + onComplete(); + } + } + }; + + Spec.prototype.onException = function onException(e) { + if (Spec.isPendingSpecException(e)) { + this.pend(extractCustomPendingMessage(e)); + return; + } + + this.addExpectationResult(false, { + matcherName: '', + passed: false, + expected: '', + actual: '', + error: e + }); + }; + + Spec.prototype.disable = function() { + this.disabled = true; + }; + + Spec.prototype.pend = function(message) { + this.markedPending = true; + if (message) { + this.result.pendingReason = message; + } + }; + + Spec.prototype.status = function() { + if (this.disabled) { + return 'disabled'; + } + + if (this.markedPending) { + return 'pending'; + } + + if (this.result.failedExpectations.length > 0) { + return 'failed'; + } else { + return 'passed'; + } + }; + + Spec.prototype.isExecutable = function() { + return !this.disabled && !this.markedPending; + }; + + Spec.prototype.getFullName = function() { + return this.getSpecName(this); + }; + + var extractCustomPendingMessage = function(e) { + var fullMessage = e.toString(), + boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage), + boilerplateEnd = boilerplateStart + Spec.pendingSpecExceptionMessage.length; + + return fullMessage.substr(boilerplateEnd); + }; + + Spec.pendingSpecExceptionMessage = '=> marked Pending'; + + Spec.isPendingSpecException = function(e) { + return !!(e && e.toString && e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1); + }; + + return Spec; +}; + +if (typeof window == void 0 && typeof exports == 'object') { + exports.Spec = jasmineRequire.Spec; +} + +getJasmineRequireObj().Env = function(j$) { + function Env(options) { + options = options || {}; + + var self = this; + var global = options.global || j$.getGlobal(); + + var totalSpecsDefined = 0; + + var catchExceptions = true; + + var realSetTimeout = j$.getGlobal().setTimeout; + var realClearTimeout = j$.getGlobal().clearTimeout; + this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler(), new j$.MockDate(global)); + + var runnableLookupTable = {}; + var runnableResources = {}; + + var currentSpec = null; + var currentlyExecutingSuites = []; + var currentDeclarationSuite = null; + + var currentSuite = function() { + return currentlyExecutingSuites[currentlyExecutingSuites.length - 1]; + }; + + var currentRunnable = function() { + return currentSpec || currentSuite(); + }; + + var reporter = new j$.ReportDispatcher([ + 'jasmineStarted', + 'jasmineDone', + 'suiteStarted', + 'suiteDone', + 'specStarted', + 'specDone' + ]); + + this.specFilter = function() { + return true; + }; + + this.addCustomEqualityTester = function(tester) { + if(!currentRunnable()) { + throw new Error('Custom Equalities must be added in a before function or a spec'); + } + runnableResources[currentRunnable().id].customEqualityTesters.push(tester); + }; + + this.addMatchers = function(matchersToAdd) { + if(!currentRunnable()) { + throw new Error('Matchers must be added in a before function or a spec'); + } + var customMatchers = runnableResources[currentRunnable().id].customMatchers; + for (var matcherName in matchersToAdd) { + customMatchers[matcherName] = matchersToAdd[matcherName]; + } + }; + + j$.Expectation.addCoreMatchers(j$.matchers); + + var nextSpecId = 0; + var getNextSpecId = function() { + return 'spec' + nextSpecId++; + }; + + var nextSuiteId = 0; + var getNextSuiteId = function() { + return 'suite' + nextSuiteId++; + }; + + var expectationFactory = function(actual, spec) { + return j$.Expectation.Factory({ + util: j$.matchersUtil, + customEqualityTesters: runnableResources[spec.id].customEqualityTesters, + customMatchers: runnableResources[spec.id].customMatchers, + actual: actual, + addExpectationResult: addExpectationResult + }); + + function addExpectationResult(passed, result) { + return spec.addExpectationResult(passed, result); + } + }; + + var defaultResourcesForRunnable = function(id, parentRunnableId) { + var resources = {spies: [], customEqualityTesters: [], customMatchers: {}}; + + if(runnableResources[parentRunnableId]){ + resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters); + resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers); + } + + runnableResources[id] = resources; + }; + + var clearResourcesForRunnable = function(id) { + spyRegistry.clearSpies(); + delete runnableResources[id]; + }; + + var beforeAndAfterFns = function(suite, runnablesExplictlySet) { + return function() { + var befores = [], + afters = [], + beforeAlls = [], + afterAlls = []; + + while(suite) { + befores = befores.concat(suite.beforeFns); + afters = afters.concat(suite.afterFns); + + if (runnablesExplictlySet()) { + beforeAlls = beforeAlls.concat(suite.beforeAllFns); + afterAlls = afterAlls.concat(suite.afterAllFns); + } + + suite = suite.parentSuite; + } + return { + befores: beforeAlls.reverse().concat(befores.reverse()), + afters: afters.concat(afterAlls) + }; + }; + }; + + var getSpecName = function(spec, suite) { + return suite.getFullName() + ' ' + spec.description; + }; + + // TODO: we may just be able to pass in the fn instead of wrapping here + var buildExpectationResult = j$.buildExpectationResult, + exceptionFormatter = new j$.ExceptionFormatter(), + expectationResultFactory = function(attrs) { + attrs.messageFormatter = exceptionFormatter.message; + attrs.stackFormatter = exceptionFormatter.stack; + + return buildExpectationResult(attrs); + }; + + // TODO: fix this naming, and here's where the value comes in + this.catchExceptions = function(value) { + catchExceptions = !!value; + return catchExceptions; + }; + + this.catchingExceptions = function() { + return catchExceptions; + }; + + var maximumSpecCallbackDepth = 20; + var currentSpecCallbackDepth = 0; + + function clearStack(fn) { + currentSpecCallbackDepth++; + if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) { + currentSpecCallbackDepth = 0; + realSetTimeout(fn, 0); + } else { + fn(); + } + } + + var catchException = function(e) { + return j$.Spec.isPendingSpecException(e) || catchExceptions; + }; + + var queueRunnerFactory = function(options) { + options.catchException = catchException; + options.clearStack = options.clearStack || clearStack; + options.timer = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}; + options.fail = self.fail; + + new j$.QueueRunner(options).execute(); + }; + + var topSuite = new j$.Suite({ + env: this, + id: getNextSuiteId(), + description: 'Jasmine__TopLevel__Suite', + queueRunner: queueRunnerFactory + }); + runnableLookupTable[topSuite.id] = topSuite; + defaultResourcesForRunnable(topSuite.id); + currentDeclarationSuite = topSuite; + + this.topSuite = function() { + return topSuite; + }; + + this.execute = function(runnablesToRun) { + if(runnablesToRun) { + runnablesExplictlySet = true; + } else if (focusedRunnables.length) { + runnablesExplictlySet = true; + runnablesToRun = focusedRunnables; + } else { + runnablesToRun = [topSuite.id]; + } + + var allFns = []; + for(var i = 0; i < runnablesToRun.length; i++) { + var runnable = runnableLookupTable[runnablesToRun[i]]; + allFns.push((function(runnable) { return { fn: function(done) { runnable.execute(done); } }; })(runnable)); + } + + reporter.jasmineStarted({ + totalSpecsDefined: totalSpecsDefined + }); + + queueRunnerFactory({queueableFns: allFns, onComplete: reporter.jasmineDone}); + }; + + this.addReporter = function(reporterToAdd) { + reporter.addReporter(reporterToAdd); + }; + + var spyRegistry = new j$.SpyRegistry({currentSpies: function() { + if(!currentRunnable()) { + throw new Error('Spies must be created in a before function or a spec'); + } + return runnableResources[currentRunnable().id].spies; + }}); + + this.spyOn = function() { + return spyRegistry.spyOn.apply(spyRegistry, arguments); + }; + + var suiteFactory = function(description) { + var suite = new j$.Suite({ + env: self, + id: getNextSuiteId(), + description: description, + parentSuite: currentDeclarationSuite, + queueRunner: queueRunnerFactory, + onStart: suiteStarted, + expectationFactory: expectationFactory, + expectationResultFactory: expectationResultFactory, + runnablesExplictlySetGetter: runnablesExplictlySetGetter, + resultCallback: function(attrs) { + if (!suite.disabled) { + clearResourcesForRunnable(suite.id); + } + currentlyExecutingSuites.pop(); + reporter.suiteDone(attrs); + } + }); + + runnableLookupTable[suite.id] = suite; + return suite; + + function suiteStarted(suite) { + currentlyExecutingSuites.push(suite); + defaultResourcesForRunnable(suite.id, suite.parentSuite.id); + reporter.suiteStarted(suite.result); + } + }; + + this.describe = function(description, specDefinitions) { + var suite = suiteFactory(description); + addSpecsToSuite(suite, specDefinitions); + return suite; + }; + + this.xdescribe = function(description, specDefinitions) { + var suite = this.describe(description, specDefinitions); + suite.disable(); + return suite; + }; + + var focusedRunnables = []; + + this.fdescribe = function(description, specDefinitions) { + var suite = suiteFactory(description); + suite.isFocused = true; + + focusedRunnables.push(suite.id); + unfocusAncestor(); + addSpecsToSuite(suite, specDefinitions); + + return suite; + }; + + function addSpecsToSuite(suite, specDefinitions) { + var parentSuite = currentDeclarationSuite; + parentSuite.addChild(suite); + currentDeclarationSuite = suite; + + var declarationError = null; + try { + specDefinitions.call(suite); + } catch (e) { + declarationError = e; + } + + if (declarationError) { + self.it('encountered a declaration exception', function() { + throw declarationError; + }); + } + + currentDeclarationSuite = parentSuite; + } + + function findFocusedAncestor(suite) { + while (suite) { + if (suite.isFocused) { + return suite.id; + } + suite = suite.parentSuite; + } + + return null; + } + + function unfocusAncestor() { + var focusedAncestor = findFocusedAncestor(currentDeclarationSuite); + if (focusedAncestor) { + for (var i = 0; i < focusedRunnables.length; i++) { + if (focusedRunnables[i] === focusedAncestor) { + focusedRunnables.splice(i, 1); + break; + } + } + } + } + + var runnablesExplictlySet = false; + + var runnablesExplictlySetGetter = function(){ + return runnablesExplictlySet; + }; + + var specFactory = function(description, fn, suite, timeout) { + totalSpecsDefined++; + var spec = new j$.Spec({ + id: getNextSpecId(), + beforeAndAfterFns: beforeAndAfterFns(suite, runnablesExplictlySetGetter), + expectationFactory: expectationFactory, + resultCallback: specResultCallback, + getSpecName: function(spec) { + return getSpecName(spec, suite); + }, + onStart: specStarted, + description: description, + expectationResultFactory: expectationResultFactory, + queueRunnerFactory: queueRunnerFactory, + userContext: function() { return suite.clonedSharedUserContext(); }, + queueableFn: { + fn: fn, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + } + }); + + runnableLookupTable[spec.id] = spec; + + if (!self.specFilter(spec)) { + spec.disable(); + } + + return spec; + + function specResultCallback(result) { + clearResourcesForRunnable(spec.id); + currentSpec = null; + reporter.specDone(result); + } + + function specStarted(spec) { + currentSpec = spec; + defaultResourcesForRunnable(spec.id, suite.id); + reporter.specStarted(spec.result); + } + }; + + this.it = function(description, fn, timeout) { + var spec = specFactory(description, fn, currentDeclarationSuite, timeout); + currentDeclarationSuite.addChild(spec); + return spec; + }; + + this.xit = function() { + var spec = this.it.apply(this, arguments); + spec.pend(); + return spec; + }; + + this.fit = function(){ + var spec = this.it.apply(this, arguments); + + focusedRunnables.push(spec.id); + unfocusAncestor(); + return spec; + }; + + this.expect = function(actual) { + if (!currentRunnable()) { + throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out'); + } + + return currentRunnable().expect(actual); + }; + + this.beforeEach = function(beforeEachFunction, timeout) { + currentDeclarationSuite.beforeEach({ + fn: beforeEachFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.beforeAll = function(beforeAllFunction, timeout) { + currentDeclarationSuite.beforeAll({ + fn: beforeAllFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.afterEach = function(afterEachFunction, timeout) { + currentDeclarationSuite.afterEach({ + fn: afterEachFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.afterAll = function(afterAllFunction, timeout) { + currentDeclarationSuite.afterAll({ + fn: afterAllFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.pending = function(message) { + var fullMessage = j$.Spec.pendingSpecExceptionMessage; + if(message) { + fullMessage += message; + } + throw fullMessage; + }; + + this.fail = function(error) { + var message = 'Failed'; + if (error) { + message += ': '; + message += error.message || error; + } + + currentRunnable().addExpectationResult(false, { + matcherName: '', + passed: false, + expected: '', + actual: '', + message: message, + error: error && error.message ? error : null + }); + }; + } + + return Env; +}; + +getJasmineRequireObj().JsApiReporter = function() { + + var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } + }; + + function JsApiReporter(options) { + var timer = options.timer || noopTimer, + status = 'loaded'; + + this.started = false; + this.finished = false; + + this.jasmineStarted = function() { + this.started = true; + status = 'started'; + timer.start(); + }; + + var executionTime; + + this.jasmineDone = function() { + this.finished = true; + executionTime = timer.elapsed(); + status = 'done'; + }; + + this.status = function() { + return status; + }; + + var suites = [], + suites_hash = {}; + + this.suiteStarted = function(result) { + suites_hash[result.id] = result; + }; + + this.suiteDone = function(result) { + storeSuite(result); + }; + + this.suiteResults = function(index, length) { + return suites.slice(index, index + length); + }; + + function storeSuite(result) { + suites.push(result); + suites_hash[result.id] = result; + } + + this.suites = function() { + return suites_hash; + }; + + var specs = []; + + this.specDone = function(result) { + specs.push(result); + }; + + this.specResults = function(index, length) { + return specs.slice(index, index + length); + }; + + this.specs = function() { + return specs; + }; + + this.executionTime = function() { + return executionTime; + }; + + } + + return JsApiReporter; +}; + +getJasmineRequireObj().CallTracker = function() { + + function CallTracker() { + var calls = []; + + this.track = function(context) { + calls.push(context); + }; + + this.any = function() { + return !!calls.length; + }; + + this.count = function() { + return calls.length; + }; + + this.argsFor = function(index) { + var call = calls[index]; + return call ? call.args : []; + }; + + this.all = function() { + return calls; + }; + + this.allArgs = function() { + var callArgs = []; + for(var i = 0; i < calls.length; i++){ + callArgs.push(calls[i].args); + } + + return callArgs; + }; + + this.first = function() { + return calls[0]; + }; + + this.mostRecent = function() { + return calls[calls.length - 1]; + }; + + this.reset = function() { + calls = []; + }; + } + + return CallTracker; +}; + +getJasmineRequireObj().Clock = function() { + function Clock(global, delayedFunctionScheduler, mockDate) { + var self = this, + realTimingFunctions = { + setTimeout: global.setTimeout, + clearTimeout: global.clearTimeout, + setInterval: global.setInterval, + clearInterval: global.clearInterval + }, + fakeTimingFunctions = { + setTimeout: setTimeout, + clearTimeout: clearTimeout, + setInterval: setInterval, + clearInterval: clearInterval + }, + installed = false, + timer; + + + self.install = function() { + replace(global, fakeTimingFunctions); + timer = fakeTimingFunctions; + installed = true; + + return self; + }; + + self.uninstall = function() { + delayedFunctionScheduler.reset(); + mockDate.uninstall(); + replace(global, realTimingFunctions); + + timer = realTimingFunctions; + installed = false; + }; + + self.mockDate = function(initialDate) { + mockDate.install(initialDate); + }; + + self.setTimeout = function(fn, delay, params) { + if (legacyIE()) { + if (arguments.length > 2) { + throw new Error('IE < 9 cannot support extra params to setTimeout without a polyfill'); + } + return timer.setTimeout(fn, delay); + } + return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]); + }; + + self.setInterval = function(fn, delay, params) { + if (legacyIE()) { + if (arguments.length > 2) { + throw new Error('IE < 9 cannot support extra params to setInterval without a polyfill'); + } + return timer.setInterval(fn, delay); + } + return Function.prototype.apply.apply(timer.setInterval, [global, arguments]); + }; + + self.clearTimeout = function(id) { + return Function.prototype.call.apply(timer.clearTimeout, [global, id]); + }; + + self.clearInterval = function(id) { + return Function.prototype.call.apply(timer.clearInterval, [global, id]); + }; + + self.tick = function(millis) { + if (installed) { + mockDate.tick(millis); + delayedFunctionScheduler.tick(millis); + } else { + throw new Error('Mock clock is not installed, use jasmine.clock().install()'); + } + }; + + return self; + + function legacyIE() { + //if these methods are polyfilled, apply will be present + return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply; + } + + function replace(dest, source) { + for (var prop in source) { + dest[prop] = source[prop]; + } + } + + function setTimeout(fn, delay) { + return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2)); + } + + function clearTimeout(id) { + return delayedFunctionScheduler.removeFunctionWithId(id); + } + + function setInterval(fn, interval) { + return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true); + } + + function clearInterval(id) { + return delayedFunctionScheduler.removeFunctionWithId(id); + } + + function argSlice(argsObj, n) { + return Array.prototype.slice.call(argsObj, n); + } + } + + return Clock; +}; + +getJasmineRequireObj().DelayedFunctionScheduler = function() { + function DelayedFunctionScheduler() { + var self = this; + var scheduledLookup = []; + var scheduledFunctions = {}; + var currentTime = 0; + var delayedFnCount = 0; + + self.tick = function(millis) { + millis = millis || 0; + var endTime = currentTime + millis; + + runScheduledFunctions(endTime); + currentTime = endTime; + }; + + self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) { + var f; + if (typeof(funcToCall) === 'string') { + /* jshint evil: true */ + f = function() { return eval(funcToCall); }; + /* jshint evil: false */ + } else { + f = funcToCall; + } + + millis = millis || 0; + timeoutKey = timeoutKey || ++delayedFnCount; + runAtMillis = runAtMillis || (currentTime + millis); + + var funcToSchedule = { + runAtMillis: runAtMillis, + funcToCall: f, + recurring: recurring, + params: params, + timeoutKey: timeoutKey, + millis: millis + }; + + if (runAtMillis in scheduledFunctions) { + scheduledFunctions[runAtMillis].push(funcToSchedule); + } else { + scheduledFunctions[runAtMillis] = [funcToSchedule]; + scheduledLookup.push(runAtMillis); + scheduledLookup.sort(function (a, b) { + return a - b; + }); + } + + return timeoutKey; + }; + + self.removeFunctionWithId = function(timeoutKey) { + for (var runAtMillis in scheduledFunctions) { + var funcs = scheduledFunctions[runAtMillis]; + var i = indexOfFirstToPass(funcs, function (func) { + return func.timeoutKey === timeoutKey; + }); + + if (i > -1) { + if (funcs.length === 1) { + delete scheduledFunctions[runAtMillis]; + deleteFromLookup(runAtMillis); + } else { + funcs.splice(i, 1); + } + + // intervals get rescheduled when executed, so there's never more + // than a single scheduled function with a given timeoutKey + break; + } + } + }; + + self.reset = function() { + currentTime = 0; + scheduledLookup = []; + scheduledFunctions = {}; + delayedFnCount = 0; + }; + + return self; + + function indexOfFirstToPass(array, testFn) { + var index = -1; + + for (var i = 0; i < array.length; ++i) { + if (testFn(array[i])) { + index = i; + break; + } + } + + return index; + } + + function deleteFromLookup(key) { + var value = Number(key); + var i = indexOfFirstToPass(scheduledLookup, function (millis) { + return millis === value; + }); + + if (i > -1) { + scheduledLookup.splice(i, 1); + } + } + + function reschedule(scheduledFn) { + self.scheduleFunction(scheduledFn.funcToCall, + scheduledFn.millis, + scheduledFn.params, + true, + scheduledFn.timeoutKey, + scheduledFn.runAtMillis + scheduledFn.millis); + } + + function forEachFunction(funcsToRun, callback) { + for (var i = 0; i < funcsToRun.length; ++i) { + callback(funcsToRun[i]); + } + } + + function runScheduledFunctions(endTime) { + if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) { + return; + } + + do { + currentTime = scheduledLookup.shift(); + + var funcsToRun = scheduledFunctions[currentTime]; + delete scheduledFunctions[currentTime]; + + forEachFunction(funcsToRun, function(funcToRun) { + if (funcToRun.recurring) { + reschedule(funcToRun); + } + }); + + forEachFunction(funcsToRun, function(funcToRun) { + funcToRun.funcToCall.apply(null, funcToRun.params || []); + }); + } while (scheduledLookup.length > 0 && + // checking first if we're out of time prevents setTimeout(0) + // scheduled in a funcToRun from forcing an extra iteration + currentTime !== endTime && + scheduledLookup[0] <= endTime); + } + } + + return DelayedFunctionScheduler; +}; + +getJasmineRequireObj().ExceptionFormatter = function() { + function ExceptionFormatter() { + this.message = function(error) { + var message = ''; + + if (error.name && error.message) { + message += error.name + ': ' + error.message; + } else { + message += error.toString() + ' thrown'; + } + + if (error.fileName || error.sourceURL) { + message += ' in ' + (error.fileName || error.sourceURL); + } + + if (error.line || error.lineNumber) { + message += ' (line ' + (error.line || error.lineNumber) + ')'; + } + + return message; + }; + + this.stack = function(error) { + return error ? error.stack : null; + }; + } + + return ExceptionFormatter; +}; + +getJasmineRequireObj().Expectation = function() { + + function Expectation(options) { + this.util = options.util || { buildFailureMessage: function() {} }; + this.customEqualityTesters = options.customEqualityTesters || []; + this.actual = options.actual; + this.addExpectationResult = options.addExpectationResult || function(){}; + this.isNot = options.isNot; + + var customMatchers = options.customMatchers || {}; + for (var matcherName in customMatchers) { + this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]); + } + } + + Expectation.prototype.wrapCompare = function(name, matcherFactory) { + return function() { + var args = Array.prototype.slice.call(arguments, 0), + expected = args.slice(0), + message = ''; + + args.unshift(this.actual); + + var matcher = matcherFactory(this.util, this.customEqualityTesters), + matcherCompare = matcher.compare; + + function defaultNegativeCompare() { + var result = matcher.compare.apply(null, args); + result.pass = !result.pass; + return result; + } + + if (this.isNot) { + matcherCompare = matcher.negativeCompare || defaultNegativeCompare; + } + + var result = matcherCompare.apply(null, args); + + if (!result.pass) { + if (!result.message) { + args.unshift(this.isNot); + args.unshift(name); + message = this.util.buildFailureMessage.apply(null, args); + } else { + if (Object.prototype.toString.apply(result.message) === '[object Function]') { + message = result.message(); + } else { + message = result.message; + } + } + } + + if (expected.length == 1) { + expected = expected[0]; + } + + // TODO: how many of these params are needed? + this.addExpectationResult( + result.pass, + { + matcherName: name, + passed: result.pass, + message: message, + actual: this.actual, + expected: expected // TODO: this may need to be arrayified/sliced + } + ); + }; + }; + + Expectation.addCoreMatchers = function(matchers) { + var prototype = Expectation.prototype; + for (var matcherName in matchers) { + var matcher = matchers[matcherName]; + prototype[matcherName] = prototype.wrapCompare(matcherName, matcher); + } + }; + + Expectation.Factory = function(options) { + options = options || {}; + + var expect = new Expectation(options); + + // TODO: this would be nice as its own Object - NegativeExpectation + // TODO: copy instead of mutate options + options.isNot = true; + expect.not = new Expectation(options); + + return expect; + }; + + return Expectation; +}; + +//TODO: expectation result may make more sense as a presentation of an expectation. +getJasmineRequireObj().buildExpectationResult = function() { + function buildExpectationResult(options) { + var messageFormatter = options.messageFormatter || function() {}, + stackFormatter = options.stackFormatter || function() {}; + + var result = { + matcherName: options.matcherName, + message: message(), + stack: stack(), + passed: options.passed + }; + + if(!result.passed) { + result.expected = options.expected; + result.actual = options.actual; + } + + return result; + + function message() { + if (options.passed) { + return 'Passed.'; + } else if (options.message) { + return options.message; + } else if (options.error) { + return messageFormatter(options.error); + } + return ''; + } + + function stack() { + if (options.passed) { + return ''; + } + + var error = options.error; + if (!error) { + try { + throw new Error(message()); + } catch (e) { + error = e; + } + } + return stackFormatter(error); + } + } + + return buildExpectationResult; +}; + +getJasmineRequireObj().MockDate = function() { + function MockDate(global) { + var self = this; + var currentTime = 0; + + if (!global || !global.Date) { + self.install = function() {}; + self.tick = function() {}; + self.uninstall = function() {}; + return self; + } + + var GlobalDate = global.Date; + + self.install = function(mockDate) { + if (mockDate instanceof GlobalDate) { + currentTime = mockDate.getTime(); + } else { + currentTime = new GlobalDate().getTime(); + } + + global.Date = FakeDate; + }; + + self.tick = function(millis) { + millis = millis || 0; + currentTime = currentTime + millis; + }; + + self.uninstall = function() { + currentTime = 0; + global.Date = GlobalDate; + }; + + createDateProperties(); + + return self; + + function FakeDate() { + switch(arguments.length) { + case 0: + return new GlobalDate(currentTime); + case 1: + return new GlobalDate(arguments[0]); + case 2: + return new GlobalDate(arguments[0], arguments[1]); + case 3: + return new GlobalDate(arguments[0], arguments[1], arguments[2]); + case 4: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3]); + case 5: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4]); + case 6: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4], arguments[5]); + default: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4], arguments[5], arguments[6]); + } + } + + function createDateProperties() { + FakeDate.prototype = GlobalDate.prototype; + + FakeDate.now = function() { + if (GlobalDate.now) { + return currentTime; + } else { + throw new Error('Browser does not support Date.now()'); + } + }; + + FakeDate.toSource = GlobalDate.toSource; + FakeDate.toString = GlobalDate.toString; + FakeDate.parse = GlobalDate.parse; + FakeDate.UTC = GlobalDate.UTC; + } + } + + return MockDate; +}; + +getJasmineRequireObj().pp = function(j$) { + + function PrettyPrinter() { + this.ppNestLevel_ = 0; + this.seen = []; + } + + PrettyPrinter.prototype.format = function(value) { + this.ppNestLevel_++; + try { + if (j$.util.isUndefined(value)) { + this.emitScalar('undefined'); + } else if (value === null) { + this.emitScalar('null'); + } else if (value === 0 && 1/value === -Infinity) { + this.emitScalar('-0'); + } else if (value === j$.getGlobal()) { + this.emitScalar(''); + } else if (value.jasmineToString) { + this.emitScalar(value.jasmineToString()); + } else if (typeof value === 'string') { + this.emitString(value); + } else if (j$.isSpy(value)) { + this.emitScalar('spy on ' + value.and.identity()); + } else if (value instanceof RegExp) { + this.emitScalar(value.toString()); + } else if (typeof value === 'function') { + this.emitScalar('Function'); + } else if (typeof value.nodeType === 'number') { + this.emitScalar('HTMLNode'); + } else if (value instanceof Date) { + this.emitScalar('Date(' + value + ')'); + } else if (j$.util.arrayContains(this.seen, value)) { + this.emitScalar(''); + } else if (j$.isArray_(value) || j$.isA_('Object', value)) { + this.seen.push(value); + if (j$.isArray_(value)) { + this.emitArray(value); + } else { + this.emitObject(value); + } + this.seen.pop(); + } else { + this.emitScalar(value.toString()); + } + } finally { + this.ppNestLevel_--; + } + }; + + PrettyPrinter.prototype.iterateObject = function(obj, fn) { + for (var property in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, property)) { continue; } + fn(property, obj.__lookupGetter__ ? (!j$.util.isUndefined(obj.__lookupGetter__(property)) && + obj.__lookupGetter__(property) !== null) : false); + } + }; + + PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitString = j$.unimplementedMethod_; + + function StringPrettyPrinter() { + PrettyPrinter.call(this); + + this.string = ''; + } + + j$.util.inherit(StringPrettyPrinter, PrettyPrinter); + + StringPrettyPrinter.prototype.emitScalar = function(value) { + this.append(value); + }; + + StringPrettyPrinter.prototype.emitString = function(value) { + this.append('\'' + value + '\''); + }; + + StringPrettyPrinter.prototype.emitArray = function(array) { + if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { + this.append('Array'); + return; + } + var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH); + this.append('[ '); + for (var i = 0; i < length; i++) { + if (i > 0) { + this.append(', '); + } + this.format(array[i]); + } + if(array.length > length){ + this.append(', ...'); + } + this.append(' ]'); + }; + + StringPrettyPrinter.prototype.emitObject = function(obj) { + var constructorName = obj.constructor ? j$.fnNameFor(obj.constructor) : 'null'; + this.append(constructorName); + + if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { + return; + } + + var self = this; + this.append('({ '); + var first = true; + + this.iterateObject(obj, function(property, isGetter) { + if (first) { + first = false; + } else { + self.append(', '); + } + + self.append(property); + self.append(': '); + if (isGetter) { + self.append(''); + } else { + self.format(obj[property]); + } + }); + + this.append(' })'); + }; + + StringPrettyPrinter.prototype.append = function(value) { + this.string += value; + }; + + return function(value) { + var stringPrettyPrinter = new StringPrettyPrinter(); + stringPrettyPrinter.format(value); + return stringPrettyPrinter.string; + }; +}; + +getJasmineRequireObj().QueueRunner = function(j$) { + + function once(fn) { + var called = false; + return function() { + if (!called) { + called = true; + fn(); + } + }; + } + + function QueueRunner(attrs) { + this.queueableFns = attrs.queueableFns || []; + this.onComplete = attrs.onComplete || function() {}; + this.clearStack = attrs.clearStack || function(fn) {fn();}; + this.onException = attrs.onException || function() {}; + this.catchException = attrs.catchException || function() { return true; }; + this.userContext = attrs.userContext || {}; + this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout}; + this.fail = attrs.fail || function() {}; + } + + QueueRunner.prototype.execute = function() { + this.run(this.queueableFns, 0); + }; + + QueueRunner.prototype.run = function(queueableFns, recursiveIndex) { + var length = queueableFns.length, + self = this, + iterativeIndex; + + + for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) { + var queueableFn = queueableFns[iterativeIndex]; + if (queueableFn.fn.length > 0) { + attemptAsync(queueableFn); + return; + } else { + attemptSync(queueableFn); + } + } + + var runnerDone = iterativeIndex >= length; + + if (runnerDone) { + this.clearStack(this.onComplete); + } + + function attemptSync(queueableFn) { + try { + queueableFn.fn.call(self.userContext); + } catch (e) { + handleException(e, queueableFn); + } + } + + function attemptAsync(queueableFn) { + var clearTimeout = function () { + Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeoutId]]); + }, + next = once(function () { + clearTimeout(timeoutId); + self.run(queueableFns, iterativeIndex + 1); + }), + timeoutId; + + next.fail = function() { + self.fail.apply(null, arguments); + next(); + }; + + if (queueableFn.timeout) { + timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() { + var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'); + onException(error, queueableFn); + next(); + }, queueableFn.timeout()]]); + } + + try { + queueableFn.fn.call(self.userContext, next); + } catch (e) { + handleException(e, queueableFn); + next(); + } + } + + function onException(e, queueableFn) { + self.onException(e); + } + + function handleException(e, queueableFn) { + onException(e, queueableFn); + if (!self.catchException(e)) { + //TODO: set a var when we catch an exception and + //use a finally block to close the loop in a nice way.. + throw e; + } + } + }; + + return QueueRunner; +}; + +getJasmineRequireObj().ReportDispatcher = function() { + function ReportDispatcher(methods) { + + var dispatchedMethods = methods || []; + + for (var i = 0; i < dispatchedMethods.length; i++) { + var method = dispatchedMethods[i]; + this[method] = (function(m) { + return function() { + dispatch(m, arguments); + }; + }(method)); + } + + var reporters = []; + + this.addReporter = function(reporter) { + reporters.push(reporter); + }; + + return this; + + function dispatch(method, args) { + for (var i = 0; i < reporters.length; i++) { + var reporter = reporters[i]; + if (reporter[method]) { + reporter[method].apply(reporter, args); + } + } + } + } + + return ReportDispatcher; +}; + + +getJasmineRequireObj().SpyRegistry = function(j$) { + + function SpyRegistry(options) { + options = options || {}; + var currentSpies = options.currentSpies || function() { return []; }; + + this.spyOn = function(obj, methodName) { + if (j$.util.isUndefined(obj)) { + throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()'); + } + + if (j$.util.isUndefined(methodName)) { + throw new Error('No method name supplied'); + } + + if (j$.util.isUndefined(obj[methodName])) { + throw new Error(methodName + '() method does not exist'); + } + + if (obj[methodName] && j$.isSpy(obj[methodName])) { + //TODO?: should this return the current spy? Downside: may cause user confusion about spy state + throw new Error(methodName + ' has already been spied upon'); + } + + var spy = j$.createSpy(methodName, obj[methodName]); + + currentSpies().push({ + spy: spy, + baseObj: obj, + methodName: methodName, + originalValue: obj[methodName] + }); + + obj[methodName] = spy; + + return spy; + }; + + this.clearSpies = function() { + var spies = currentSpies(); + for (var i = 0; i < spies.length; i++) { + var spyEntry = spies[i]; + spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue; + } + }; + } + + return SpyRegistry; +}; + +getJasmineRequireObj().SpyStrategy = function() { + + function SpyStrategy(options) { + options = options || {}; + + var identity = options.name || 'unknown', + originalFn = options.fn || function() {}, + getSpy = options.getSpy || function() {}, + plan = function() {}; + + this.identity = function() { + return identity; + }; + + this.exec = function() { + return plan.apply(this, arguments); + }; + + this.callThrough = function() { + plan = originalFn; + return getSpy(); + }; + + this.returnValue = function(value) { + plan = function() { + return value; + }; + return getSpy(); + }; + + this.returnValues = function() { + var values = Array.prototype.slice.call(arguments); + plan = function () { + return values.shift(); + }; + return getSpy(); + }; + + this.throwError = function(something) { + var error = (something instanceof Error) ? something : new Error(something); + plan = function() { + throw error; + }; + return getSpy(); + }; + + this.callFake = function(fn) { + plan = fn; + return getSpy(); + }; + + this.stub = function(fn) { + plan = function() {}; + return getSpy(); + }; + } + + return SpyStrategy; +}; + +getJasmineRequireObj().Suite = function() { + function Suite(attrs) { + this.env = attrs.env; + this.id = attrs.id; + this.parentSuite = attrs.parentSuite; + this.description = attrs.description; + this.onStart = attrs.onStart || function() {}; + this.resultCallback = attrs.resultCallback || function() {}; + this.clearStack = attrs.clearStack || function(fn) {fn();}; + this.expectationFactory = attrs.expectationFactory; + this.expectationResultFactory = attrs.expectationResultFactory; + this.runnablesExplictlySetGetter = attrs.runnablesExplictlySetGetter || function() {}; + + this.beforeFns = []; + this.afterFns = []; + this.beforeAllFns = []; + this.afterAllFns = []; + this.queueRunner = attrs.queueRunner || function() {}; + this.disabled = false; + + this.children = []; + + this.result = { + id: this.id, + description: this.description, + fullName: this.getFullName(), + failedExpectations: [] + }; + } + + Suite.prototype.expect = function(actual) { + return this.expectationFactory(actual, this); + }; + + Suite.prototype.getFullName = function() { + var fullName = this.description; + for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { + if (parentSuite.parentSuite) { + fullName = parentSuite.description + ' ' + fullName; + } + } + return fullName; + }; + + Suite.prototype.disable = function() { + this.disabled = true; + }; + + Suite.prototype.beforeEach = function(fn) { + this.beforeFns.unshift(fn); + }; + + Suite.prototype.beforeAll = function(fn) { + this.beforeAllFns.push(fn); + }; + + Suite.prototype.afterEach = function(fn) { + this.afterFns.unshift(fn); + }; + + Suite.prototype.afterAll = function(fn) { + this.afterAllFns.push(fn); + }; + + Suite.prototype.addChild = function(child) { + this.children.push(child); + }; + + Suite.prototype.status = function() { + if (this.disabled) { + return 'disabled'; + } + + if (this.result.failedExpectations.length > 0) { + return 'failed'; + } else { + return 'finished'; + } + }; + + Suite.prototype.execute = function(onComplete) { + var self = this; + + this.onStart(this); + + if (this.disabled) { + complete(); + return; + } + + var allFns = []; + + for (var i = 0; i < this.children.length; i++) { + allFns.push(wrapChildAsAsync(this.children[i])); + } + + if (this.isExecutable()) { + allFns = this.beforeAllFns.concat(allFns); + allFns = allFns.concat(this.afterAllFns); + } + + this.queueRunner({ + queueableFns: allFns, + onComplete: complete, + userContext: this.sharedUserContext(), + onException: function() { self.onException.apply(self, arguments); } + }); + + function complete() { + self.result.status = self.status(); + self.resultCallback(self.result); + + if (onComplete) { + onComplete(); + } + } + + function wrapChildAsAsync(child) { + return { fn: function(done) { child.execute(done); } }; + } + }; + + Suite.prototype.isExecutable = function() { + var runnablesExplicitlySet = this.runnablesExplictlySetGetter(); + return !runnablesExplicitlySet && hasExecutableChild(this.children); + }; + + Suite.prototype.sharedUserContext = function() { + if (!this.sharedContext) { + this.sharedContext = this.parentSuite ? clone(this.parentSuite.sharedUserContext()) : {}; + } + + return this.sharedContext; + }; + + Suite.prototype.clonedSharedUserContext = function() { + return clone(this.sharedUserContext()); + }; + + Suite.prototype.onException = function() { + if(isAfterAll(this.children)) { + var data = { + matcherName: '', + passed: false, + expected: '', + actual: '', + error: arguments[0] + }; + this.result.failedExpectations.push(this.expectationResultFactory(data)); + } else { + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + child.onException.apply(child, arguments); + } + } + }; + + Suite.prototype.addExpectationResult = function () { + if(isAfterAll(this.children) && isFailure(arguments)){ + var data = arguments[1]; + this.result.failedExpectations.push(this.expectationResultFactory(data)); + } else { + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + child.addExpectationResult.apply(child, arguments); + } + } + }; + + function isAfterAll(children) { + return children && children[0].result.status; + } + + function isFailure(args) { + return !args[0]; + } + + function hasExecutableChild(children) { + var foundActive = false; + for (var i = 0; i < children.length; i++) { + if (children[i].isExecutable()) { + foundActive = true; + break; + } + } + return foundActive; + } + + function clone(obj) { + var clonedObj = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + clonedObj[prop] = obj[prop]; + } + } + + return clonedObj; + } + + return Suite; +}; + +if (typeof window == void 0 && typeof exports == 'object') { + exports.Suite = jasmineRequire.Suite; +} + +getJasmineRequireObj().Timer = function() { + var defaultNow = (function(Date) { + return function() { return new Date().getTime(); }; + })(Date); + + function Timer(options) { + options = options || {}; + + var now = options.now || defaultNow, + startTime; + + this.start = function() { + startTime = now(); + }; + + this.elapsed = function() { + return now() - startTime; + }; + } + + return Timer; +}; + +getJasmineRequireObj().Any = function() { + + function Any(expectedObject) { + this.expectedObject = expectedObject; + } + + Any.prototype.asymmetricMatch = function(other) { + if (this.expectedObject == String) { + return typeof other == 'string' || other instanceof String; + } + + if (this.expectedObject == Number) { + return typeof other == 'number' || other instanceof Number; + } + + if (this.expectedObject == Function) { + return typeof other == 'function' || other instanceof Function; + } + + if (this.expectedObject == Object) { + return typeof other == 'object'; + } + + if (this.expectedObject == Boolean) { + return typeof other == 'boolean'; + } + + return other instanceof this.expectedObject; + }; + + Any.prototype.jasmineToString = function() { + return ''; + }; + + return Any; +}; + +getJasmineRequireObj().Anything = function(j$) { + + function Anything() {} + + Anything.prototype.asymmetricMatch = function(other) { + return !j$.util.isUndefined(other) && other !== null; + }; + + Anything.prototype.jasmineToString = function() { + return ''; + }; + + return Anything; +}; + +getJasmineRequireObj().ArrayContaining = function(j$) { + function ArrayContaining(sample) { + this.sample = sample; + } + + ArrayContaining.prototype.asymmetricMatch = function(other) { + var className = Object.prototype.toString.call(this.sample); + if (className !== '[object Array]') { throw new Error('You must provide an array to arrayContaining, not \'' + this.sample + '\'.'); } + + for (var i = 0; i < this.sample.length; i++) { + var item = this.sample[i]; + if (!j$.matchersUtil.contains(other, item)) { + return false; + } + } + + return true; + }; + + ArrayContaining.prototype.jasmineToString = function () { + return ''; + }; + + return ArrayContaining; +}; + +getJasmineRequireObj().ObjectContaining = function(j$) { + + function ObjectContaining(sample) { + this.sample = sample; + } + + ObjectContaining.prototype.asymmetricMatch = function(other) { + if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); } + + for (var property in this.sample) { + if (!Object.prototype.hasOwnProperty.call(other, property) || + !j$.matchersUtil.equals(this.sample[property], other[property])) { + return false; + } + } + + return true; + }; + + ObjectContaining.prototype.jasmineToString = function() { + return ''; + }; + + return ObjectContaining; +}; + +getJasmineRequireObj().StringMatching = function(j$) { + + function StringMatching(expected) { + if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { + throw new Error('Expected is not a String or a RegExp'); + } + + this.regexp = new RegExp(expected); + } + + StringMatching.prototype.asymmetricMatch = function(other) { + return this.regexp.test(other); + }; + + StringMatching.prototype.jasmineToString = function() { + return ''; + }; + + return StringMatching; +}; + +getJasmineRequireObj().matchersUtil = function(j$) { + // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter? + + return { + equals: function(a, b, customTesters) { + customTesters = customTesters || []; + + return eq(a, b, [], [], customTesters); + }, + + contains: function(haystack, needle, customTesters) { + customTesters = customTesters || []; + + if ((Object.prototype.toString.apply(haystack) === '[object Array]') || + (!!haystack && !haystack.indexOf)) + { + for (var i = 0; i < haystack.length; i++) { + if (eq(haystack[i], needle, [], [], customTesters)) { + return true; + } + } + return false; + } + + return !!haystack && haystack.indexOf(needle) >= 0; + }, + + buildFailureMessage: function() { + var args = Array.prototype.slice.call(arguments, 0), + matcherName = args[0], + isNot = args[1], + actual = args[2], + expected = args.slice(3), + englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); + + var message = 'Expected ' + + j$.pp(actual) + + (isNot ? ' not ' : ' ') + + englishyPredicate; + + if (expected.length > 0) { + for (var i = 0; i < expected.length; i++) { + if (i > 0) { + message += ','; + } + message += ' ' + j$.pp(expected[i]); + } + } + + return message + '.'; + } + }; + + function isAsymmetric(obj) { + return obj && j$.isA_('Function', obj.asymmetricMatch); + } + + function asymmetricMatch(a, b) { + var asymmetricA = isAsymmetric(a), + asymmetricB = isAsymmetric(b); + + if (asymmetricA && asymmetricB) { + return undefined; + } + + if (asymmetricA) { + return a.asymmetricMatch(b); + } + + if (asymmetricB) { + return b.asymmetricMatch(a); + } + } + + // Equality function lovingly adapted from isEqual in + // [Underscore](http://underscorejs.org) + function eq(a, b, aStack, bStack, customTesters) { + var result = true; + + var asymmetricResult = asymmetricMatch(a, b); + if (!j$.util.isUndefined(asymmetricResult)) { + return asymmetricResult; + } + + for (var i = 0; i < customTesters.length; i++) { + var customTesterResult = customTesters[i](a, b); + if (!j$.util.isUndefined(customTesterResult)) { + return customTesterResult; + } + } + + if (a instanceof Error && b instanceof Error) { + return a.message == b.message; + } + + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) { return a !== 0 || 1 / a == 1 / b; } + // A strict comparison is necessary because `null == undefined`. + if (a === null || b === null) { return a === b; } + var className = Object.prototype.toString.call(a); + if (className != Object.prototype.toString.call(b)) { return false; } + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') { return false; } + + var aIsDomNode = j$.isDomNode(a); + var bIsDomNode = j$.isDomNode(b); + if (aIsDomNode && bIsDomNode) { + // At first try to use DOM3 method isEqualNode + if (a.isEqualNode) { + return a.isEqualNode(b); + } + // IE8 doesn't support isEqualNode, try to use outerHTML && innerText + var aIsElement = a instanceof Element; + var bIsElement = b instanceof Element; + if (aIsElement && bIsElement) { + return a.outerHTML == b.outerHTML; + } + if (aIsElement || bIsElement) { + return false; + } + return a.innerText == b.innerText && a.textContent == b.textContent; + } + if (aIsDomNode || bIsDomNode) { + return false; + } + + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] == a) { return bStack[length] == b; } + } + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + var size = 0; + // Recursively compare objects and arrays. + // Compare array lengths to determine if a deep comparison is necessary. + if (className == '[object Array]' && a.length !== b.length) { + result = false; + } + + if (result) { + // Objects with different constructors are not equivalent, but `Object`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(isFunction(aCtor) && (aCtor instanceof aCtor) && + isFunction(bCtor) && (bCtor instanceof bCtor))) { + return false; + } + // Deep compare objects. + for (var key in a) { + if (has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) { break; } + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (has(b, key) && !(size--)) { break; } + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + + return result; + + function has(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); + } + + function isFunction(obj) { + return typeof obj === 'function'; + } + } +}; + +getJasmineRequireObj().toBe = function() { + function toBe() { + return { + compare: function(actual, expected) { + return { + pass: actual === expected + }; + } + }; + } + + return toBe; +}; + +getJasmineRequireObj().toBeCloseTo = function() { + + function toBeCloseTo() { + return { + compare: function(actual, expected, precision) { + if (precision !== 0) { + precision = precision || 2; + } + + return { + pass: Math.abs(expected - actual) < (Math.pow(10, -precision) / 2) + }; + } + }; + } + + return toBeCloseTo; +}; + +getJasmineRequireObj().toBeDefined = function() { + function toBeDefined() { + return { + compare: function(actual) { + return { + pass: (void 0 !== actual) + }; + } + }; + } + + return toBeDefined; +}; + +getJasmineRequireObj().toBeFalsy = function() { + function toBeFalsy() { + return { + compare: function(actual) { + return { + pass: !!!actual + }; + } + }; + } + + return toBeFalsy; +}; + +getJasmineRequireObj().toBeGreaterThan = function() { + + function toBeGreaterThan() { + return { + compare: function(actual, expected) { + return { + pass: actual > expected + }; + } + }; + } + + return toBeGreaterThan; +}; + + +getJasmineRequireObj().toBeLessThan = function() { + function toBeLessThan() { + return { + + compare: function(actual, expected) { + return { + pass: actual < expected + }; + } + }; + } + + return toBeLessThan; +}; +getJasmineRequireObj().toBeNaN = function(j$) { + + function toBeNaN() { + return { + compare: function(actual) { + var result = { + pass: (actual !== actual) + }; + + if (result.pass) { + result.message = 'Expected actual not to be NaN.'; + } else { + result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be NaN.'; }; + } + + return result; + } + }; + } + + return toBeNaN; +}; + +getJasmineRequireObj().toBeNull = function() { + + function toBeNull() { + return { + compare: function(actual) { + return { + pass: actual === null + }; + } + }; + } + + return toBeNull; +}; + +getJasmineRequireObj().toBeTruthy = function() { + + function toBeTruthy() { + return { + compare: function(actual) { + return { + pass: !!actual + }; + } + }; + } + + return toBeTruthy; +}; + +getJasmineRequireObj().toBeUndefined = function() { + + function toBeUndefined() { + return { + compare: function(actual) { + return { + pass: void 0 === actual + }; + } + }; + } + + return toBeUndefined; +}; + +getJasmineRequireObj().toContain = function() { + function toContain(util, customEqualityTesters) { + customEqualityTesters = customEqualityTesters || []; + + return { + compare: function(actual, expected) { + + return { + pass: util.contains(actual, expected, customEqualityTesters) + }; + } + }; + } + + return toContain; +}; + +getJasmineRequireObj().toEqual = function() { + + function toEqual(util, customEqualityTesters) { + customEqualityTesters = customEqualityTesters || []; + + return { + compare: function(actual, expected) { + var result = { + pass: false + }; + + result.pass = util.equals(actual, expected, customEqualityTesters); + + return result; + } + }; + } + + return toEqual; +}; + +getJasmineRequireObj().toHaveBeenCalled = function(j$) { + + function toHaveBeenCalled() { + return { + compare: function(actual) { + var result = {}; + + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + if (arguments.length > 1) { + throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); + } + + result.pass = actual.calls.any(); + + result.message = result.pass ? + 'Expected spy ' + actual.and.identity() + ' not to have been called.' : + 'Expected spy ' + actual.and.identity() + ' to have been called.'; + + return result; + } + }; + } + + return toHaveBeenCalled; +}; + +getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { + + function toHaveBeenCalledWith(util, customEqualityTesters) { + return { + compare: function() { + var args = Array.prototype.slice.call(arguments, 0), + actual = args[0], + expectedArgs = args.slice(1), + result = { pass: false }; + + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + if (!actual.calls.any()) { + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but it was never called.'; }; + return result; + } + + if (util.contains(actual.calls.allArgs(), expectedArgs, customEqualityTesters)) { + result.pass = true; + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' not to have been called with ' + j$.pp(expectedArgs) + ' but it was.'; }; + } else { + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but actual calls were ' + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + '.'; }; + } + + return result; + } + }; + } + + return toHaveBeenCalledWith; +}; + +getJasmineRequireObj().toMatch = function(j$) { + + function toMatch() { + return { + compare: function(actual, expected) { + if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { + throw new Error('Expected is not a String or a RegExp'); + } + + var regexp = new RegExp(expected); + + return { + pass: regexp.test(actual) + }; + } + }; + } + + return toMatch; +}; + +getJasmineRequireObj().toThrow = function(j$) { + + function toThrow(util) { + return { + compare: function(actual, expected) { + var result = { pass: false }, + threw = false, + thrown; + + if (typeof actual != 'function') { + throw new Error('Actual is not a Function'); + } + + try { + actual(); + } catch (e) { + threw = true; + thrown = e; + } + + if (!threw) { + result.message = 'Expected function to throw an exception.'; + return result; + } + + if (arguments.length == 1) { + result.pass = true; + result.message = function() { return 'Expected function not to throw, but it threw ' + j$.pp(thrown) + '.'; }; + + return result; + } + + if (util.equals(thrown, expected)) { + result.pass = true; + result.message = function() { return 'Expected function not to throw ' + j$.pp(expected) + '.'; }; + } else { + result.message = function() { return 'Expected function to throw ' + j$.pp(expected) + ', but it threw ' + j$.pp(thrown) + '.'; }; + } + + return result; + } + }; + } + + return toThrow; +}; + +getJasmineRequireObj().toThrowError = function(j$) { + function toThrowError (util) { + return { + compare: function(actual) { + var threw = false, + pass = {pass: true}, + fail = {pass: false}, + thrown; + + if (typeof actual != 'function') { + throw new Error('Actual is not a Function'); + } + + var errorMatcher = getMatcher.apply(null, arguments); + + try { + actual(); + } catch (e) { + threw = true; + thrown = e; + } + + if (!threw) { + fail.message = 'Expected function to throw an Error.'; + return fail; + } + + if (!(thrown instanceof Error)) { + fail.message = function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; }; + return fail; + } + + if (errorMatcher.hasNoSpecifics()) { + pass.message = 'Expected function not to throw an Error, but it threw ' + j$.fnNameFor(thrown) + '.'; + return pass; + } + + if (errorMatcher.matches(thrown)) { + pass.message = function() { + return 'Expected function not to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + '.'; + }; + return pass; + } else { + fail.message = function() { + return 'Expected function to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + + ', but it threw ' + errorMatcher.thrownDescription(thrown) + '.'; + }; + return fail; + } + } + }; + + function getMatcher() { + var expected = null, + errorType = null; + + if (arguments.length == 2) { + expected = arguments[1]; + if (isAnErrorType(expected)) { + errorType = expected; + expected = null; + } + } else if (arguments.length > 2) { + errorType = arguments[1]; + expected = arguments[2]; + if (!isAnErrorType(errorType)) { + throw new Error('Expected error type is not an Error.'); + } + } + + if (expected && !isStringOrRegExp(expected)) { + if (errorType) { + throw new Error('Expected error message is not a string or RegExp.'); + } else { + throw new Error('Expected is not an Error, string, or RegExp.'); + } + } + + function messageMatch(message) { + if (typeof expected == 'string') { + return expected == message; + } else { + return expected.test(message); + } + } + + return { + errorTypeDescription: errorType ? j$.fnNameFor(errorType) : 'an exception', + thrownDescription: function(thrown) { + var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception', + thrownMessage = ''; + + if (expected) { + thrownMessage = ' with message ' + j$.pp(thrown.message); + } + + return thrownName + thrownMessage; + }, + messageDescription: function() { + if (expected === null) { + return ''; + } else if (expected instanceof RegExp) { + return ' with a message matching ' + j$.pp(expected); + } else { + return ' with message ' + j$.pp(expected); + } + }, + hasNoSpecifics: function() { + return expected === null && errorType === null; + }, + matches: function(error) { + return (errorType === null || error.constructor === errorType) && + (expected === null || messageMatch(error.message)); + } + }; + } + + function isStringOrRegExp(potential) { + return potential instanceof RegExp || (typeof potential == 'string'); + } + + function isAnErrorType(type) { + if (typeof type !== 'function') { + return false; + } + + var Surrogate = function() {}; + Surrogate.prototype = type.prototype; + return (new Surrogate()) instanceof Error; + } + } + + return toThrowError; +}; + +getJasmineRequireObj().interface = function(jasmine, env) { + var jasmineInterface = { + describe: function(description, specDefinitions) { + return env.describe(description, specDefinitions); + }, + + xdescribe: function(description, specDefinitions) { + return env.xdescribe(description, specDefinitions); + }, + + fdescribe: function(description, specDefinitions) { + return env.fdescribe(description, specDefinitions); + }, + + it: function() { + return env.it.apply(env, arguments); + }, + + xit: function() { + return env.xit.apply(env, arguments); + }, + + fit: function() { + return env.fit.apply(env, arguments); + }, + + beforeEach: function() { + return env.beforeEach.apply(env, arguments); + }, + + afterEach: function() { + return env.afterEach.apply(env, arguments); + }, + + beforeAll: function() { + return env.beforeAll.apply(env, arguments); + }, + + afterAll: function() { + return env.afterAll.apply(env, arguments); + }, + + expect: function(actual) { + return env.expect(actual); + }, + + pending: function() { + return env.pending.apply(env, arguments); + }, + + fail: function() { + return env.fail.apply(env, arguments); + }, + + spyOn: function(obj, methodName) { + return env.spyOn(obj, methodName); + }, + + jsApiReporter: new jasmine.JsApiReporter({ + timer: new jasmine.Timer() + }), + + jasmine: jasmine + }; + + jasmine.addCustomEqualityTester = function(tester) { + env.addCustomEqualityTester(tester); + }; + + jasmine.addMatchers = function(matchers) { + return env.addMatchers(matchers); + }; + + jasmine.clock = function() { + return env.clock; + }; + + return jasmineInterface; +}; + +getJasmineRequireObj().version = function() { + return '2.2.0'; +}; diff --git a/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine_favicon.png b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine_favicon.png new file mode 100755 index 0000000..3b84583 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/jasmine-2.2.0/jasmine_favicon.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/jasmine-medic.js b/plugins/cordova-plugin-test-framework/www/assets/jasmine-medic.js new file mode 100644 index 0000000..4194f3a --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/jasmine-medic.js @@ -0,0 +1,123 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* global device */ + +jasmineRequire.medic = function(j$) { + j$.MedicReporter = jasmineRequire.MedicReporter(j$); +}; + +jasmineRequire.MedicReporter = function(j$) { + var noopTimer = { + start: function() {}, + elapsed: function() { return 0; } + }; + + var platformMap = { + 'ipod touch':'ios', + 'iphone':'ios' + }; + + function MedicReporter(options) { + var logoptions = options.log || { logurl: 'http://127.0.0.1:5984/' }, // TODO: http://localhost:6800 + timer = options.timer || noopTimer, + results = [], + specsExecuted = 0, + failureCount = 0, + pendingSpecCount = 0; + + + var serverurl = logoptions.logurl; + + this.initialize = function() { + }; + + var totalSpecsDefined; + this.jasmineStarted = function(options) { + totalSpecsDefined = options.totalSpecsDefined || 0; + timer.start(); + }; + + this.suiteStarted = function(result) { + }; + + this.suiteDone = function(result) { + + }; + + this.specStarted = function(result) { + // Start timing this spec + }; + + this.specDone = function(result) { + if (result.status != "disabled") { + specsExecuted++; + } + if (result.status == "failed") { + failureCount++; + results.push(result); + } + if (result.status == "pending") { + pendingSpecCount++; + } + }; + + var buildResults = function(){ + var json ={specs:specsExecuted, failures:failureCount, results: results}; + return json; + }; + + this.jasmineDone = function() { + var p = 'Desktop'; + var devmodel='none'; + var version = cordova.version; + if(typeof device != 'undefined') { + p = device.platform.toLowerCase(); + devmodel=device.model || device.name; + version = device.version.toLowerCase(); + } + + this.postTests({ + mobilespec:buildResults(), + platform:(platformMap.hasOwnProperty(p) ? platformMap[p] : p), + version:version, + sha: options.sha, + timestamp:Math.round(Math.floor((new Date()).getTime() / 1000)), + model:devmodel + }); + + }; + + this.postTests = function(json) { + console.log('posting tests'); + + var xhr = new XMLHttpRequest(); + var doc_id = [options.sha, json.version, json.model].map(encodeURIComponent).join('__'); + var doc_url = serverurl + '/mobilespec_results/' + doc_id; + xhr.open("PUT", doc_url, true); + xhr.setRequestHeader("Content-Type","application/json"); + xhr.send(JSON.stringify(json)); + }; + return this; + } + + return MedicReporter; +}; diff --git a/plugins/cordova-plugin-test-framework/www/assets/main-bootstrap.js b/plugins/cordova-plugin-test-framework/www/assets/main-bootstrap.js new file mode 100644 index 0000000..58624b7 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/main-bootstrap.js @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +document.addEventListener("deviceready", function() { + 'use strict'; + + cordova.require('cordova-plugin-test-framework.main').init(); +}); diff --git a/plugins/cordova-plugin-test-framework/www/assets/main.css b/plugins/cordova-plugin-test-framework/www/assets/main.css new file mode 100644 index 0000000..9223dbd --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/main.css @@ -0,0 +1,148 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +*, *:before, *:after { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +html, body { + height: 100%; + width: 100%; + margin: 0; + padding: 0; +} + +#title { + position: fixed; + height: 30px; + width: 100%; + top: 0; + z-index: 1000; + + background-color: #75B2F0; + font-size: 25px; + text-align: center; + font-weight: bold; + white-space: nowrap; +} + +#middle { + position: absolute; + top: 30px; + bottom: 20px; + padding-bottom: 40%; + width: 100%; + overflow-y: auto; + overflow-x: auto; +} + +#log { + position: fixed; + height: 20px; + width: 100%; + bottom: 0; + z-index: 1000; + border-top: 2px solid #777; + transition: 0.25s ease; +} + +body.expanded-log #middle { + margin-bottom: 40%; +} + +body.expanded-log #log { + height: 40%; +} + +#log--title { + position: absolute; + top: 0; + height: 20px; + width: 100%; + background-color: #93AAC2; +} + +#log--content { + position: absolute; + top: 20px; + bottom: 0; + width: 100%; + overflow-x: none; + overflow-y: auto; + background-color: white; +} + +.log--content--line { + border-bottom: 1px solid #ccc; + white-space: pre; +} + +.log--content--line--log { + background-color: white; +} + +.log--content--line--warn { + background-color: #FCFFA6; +} + +.log--content--line--error { + background-color: #FFA6A6; +} + +#info{ + background:#ffa; + border: 1px solid #ffd324; + -webkit-border-radius: 5px; + border-radius: 5px; + clear:both; + margin:15px 6px 0; + min-width:295px; + max-width:97%; + padding:4px 0px 2px 10px; + word-wrap:break-word; + margin-bottom:10px; + display:inline-block; + min-height: 160px; + max-height: 300px; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +#test-enablers-container { + margin: 10px 5px; +} + +#test-expander { + text-decoration: underline; +} + +#test-list { + display: none; +} + +#test-list.expanded { + display: inherit; +} + +#test-list label { + display: block; +} diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/.gitignore b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/.gitignore new file mode 100755 index 0000000..f678651 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/.gitignore @@ -0,0 +1,6 @@ +node_modules +npm-debug.log +tmp +.DS_Store +src/ +.tern-port diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/Gruntfile.js b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/Gruntfile.js new file mode 100755 index 0000000..1952688 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/Gruntfile.js @@ -0,0 +1,277 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/*global module:false, require:false, process:false*/ + +var path = require('path'), + os = require('os'), + chromiumSrc = process.env.CHROMIUM_SRC || ""; + + +module.exports = function(grunt) { + 'use strict'; + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + + stylus: { + options: { + paths: grunt.file.expand(__dirname + '/node_modules/topcoat-*/src/') + /* FIXME: Utils is the last needing to be moved out of mixins + * folder + */ + .concat(grunt.file.expand(__dirname + '/node_modules/topcoat-utils/src/mixins/')), + compress: false + }, + + mobilelight: { + options: { + import: ['theme-topcoat-mobile-light', 'utils'] + }, + + files: [{ + src: 'node_modules/topcoat-*/src/**/*.styl', + dest: 'css/topcoat-mobile-light.css' + }] + }, + + mobiledark: { + options: { + import: ['theme-topcoat-mobile-dark', 'utils'] + }, + + files: [{ + src: 'node_modules/topcoat-*/src/**/*.styl', + dest: 'css/topcoat-mobile-dark.css' + }] + }, + + desktoplight: { + options: { + import: ['theme-topcoat-desktop-light', 'utils'] + }, + files: [{ + src: [ + 'node_modules/topcoat-*/src/**/*.styl', + '!node_modules/topcoat-navigation-bar/src/*.styl', + '!node_modules/topcoat-list/src/*.styl' + ], + dest: 'css/topcoat-desktop-light.css' + }] + }, + + desktopdark: { + options: { + import: ['theme-topcoat-desktop-dark', 'utils'] + }, + + files: [{ + src: [ + 'node_modules/topcoat-*/src/**/*.styl', + '!node_modules/topcoat-navigation-bar/src/*.styl', + '!node_modules/topcoat-list/src/*.styl' + ], + dest: 'css/topcoat-desktop-dark.css' + }] + } + }, + + topdoc: { + usageguides: { + options: { + source: 'css', + destination: 'demo', + template: 'node_modules/topdoc-theme/', + templateData: { + "title": "Topcoat", + "subtitle": "CSS for clean and fast web apps", + "download": { + "url": "https://github.com/topcoat/topcoat/archive/v0.7.0.zip", + "label": "Download" + }, + "homeURL": "http://topcoat.io", + "siteNav": [ + { + "url": "http://topcoat.io/topcoat", + "text": "Demo" + }, + { + "url": "http://bench.topcoat.io/", + "text": "Benchmarks" + }, + { + "url": "http://topcoat.io/blog", + "text": "Blog" + } + ] + } + } + } + }, + + autoprefixer: { + dist: { + options: { + /* + * Add target browsers here + * https://github.com/ai/autoprefixer#browsers + * browsers: ['android 4'] + */ + }, + files: [{ + src: 'css/topcoat-desktop-dark.css', + dest: 'css/topcoat-desktop-dark.css' + }, + { + src: 'css/topcoat-desktop-light.css', + dest: 'css/topcoat-desktop-light.css' + }, + { + src: 'css/topcoat-mobile-dark.css', + dest: 'css/topcoat-mobile-dark.css' + }, + { + src: 'css/topcoat-mobile-light.css', + dest: 'css/topcoat-mobile-light.css' + }] + } + + }, + + cssmin: { + minify: { + expand: true, + cwd: 'css', + src: ['*.css', '!*.min.css'], + dest: 'css', + ext: '.min.css' + } + }, + + htmlmin: { + telemetry: { + options: { + removeComments: true, + collapseWhitespace: true + }, + files: [{ + expand: true, + src: ['dev/test/**/topcoat/*.html'], + dest: '', + ext: '.test.html', + }], + }, + }, + + clean: { + release: ['css'] + }, + + copy: { + release: { + files: [{ + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/font/**', + dest: 'font' + }, { + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/img/*', + dest: 'img' + }] + }, + + telemetry: { + files: [{ + expand: true, + cwd: 'dev/test/perf/telemetry/perf/', + src: ['**'], + dest: path.join(chromiumSrc, 'tools/perf/') + }, { + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/font/**', + dest: path.join(chromiumSrc, 'tools/perf/page_sets/topcoat/release/font') + }, { + expand: true, + flatten: true, + src: 'node_modules/topcoat-theme/img/*', + dest: path.join(chromiumSrc, 'tools/perf/page_sets/topcoat/release/img') + }, { + src: ['css/**'], + dest: path.join(chromiumSrc, 'tools/perf/page_sets/topcoat/release/') + }] + } + }, + + jshint: { + options: { + curly: true, + eqeqeq: true, + immed: true, + latedef: true, + newcap: true, + noarg: true, + sub: true, + undef: true, + unused: true, + boss: true, + eqnull: true, + browser: true, + globals: { + jQuery: true + } + }, + gruntfile: { + src: 'Gruntfile.js' + }, + lib_test: { + src: ['dev/lib/**/*.js', 'dev/test/**/*.js'] + } + }, + + watch: { + files: ['src/**/*.styl'], + tasks: ['compile'] + } + + }); + + // These plugins provide necessary tasks. + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-contrib-jade'); + grunt.loadNpmTasks('grunt-contrib-stylus'); + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-exec'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-topdoc'); + grunt.loadNpmTasks('grunt-contrib-cssmin'); + grunt.loadNpmTasks('grunt-contrib-htmlmin'); + grunt.loadNpmTasks('grunt-autoprefixer'); + + //Load local tasks + grunt.loadTasks('dev/tasks'); + + // Default task. + grunt.registerTask('default', ['clean', 'stylus', 'autoprefixer', 'cssmin', 'topdoc', 'copy:release']); + grunt.registerTask('release', ['default', 'clean:src']); + grunt.registerTask('compile', ['topcoat:compile', 'topdoc', 'copy:release']); + + grunt.registerTask('telemetry', '', function(platform, theme) { + if (chromiumSrc === "") grunt.fail.warn("Set CHROMIUM_SRC to point to the correct location\n"); + grunt.task.run('check_chromium_src', 'perf:'.concat(platform || 'mobile').concat(':').concat(theme || 'light'), 'htmlmin:telemetry', 'copy:telemetry'); + }); +}; diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/LICENSE b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/LICENSE new file mode 100755 index 0000000..242fd8a --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/LICENSE @@ -0,0 +1,203 @@ +Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/NOTICE b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/NOTICE new file mode 100755 index 0000000..3c8ddfa --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/NOTICE @@ -0,0 +1,193 @@ +Topcoat is licensed under the Apache license version 2.0, January 2004 (see LICENSE file). + +Topcoat uses the following third party libraries that may have licenses +differing from that of Topcoat itself. You can find the libraries and their +respective licenses below. + + - Source Code Pro ./src/font/SourceCodePro + + https://github.com/adobe/source-code-pro + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + This Font Software is licensed under the SIL Open Font License, Version 1.1. + This license is available with a FAQ at: http://scripts.sil.org/OFL + +- Source Sans Pro ./src/font/SourceSansPro + + https://github.com/adobe/source-sans-pro + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + This Font Software is licensed under the SIL Open Font License, Version 1.1. + This license is available with a FAQ at: http://scripts.sil.org/OFL + +The following frameworks and libraries are provided just for testing and benchmarking and, as provided, should not be included as part of Topcoat output. + + - Bootstrap - ./test/third-party/bootstrap + + https://github.com/twitter/bootstrap + + Copyright 2012 Twitter, Inc + Licensed under the Apache License v2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + - jQuery - ./test/third-party/jquery-1.8.2.js + + https://github.com/jquery/jquery + + Copyright 2011, John Resig + Dual licensed under the MIT or GPL Version 2 licenses. + http://jquery.org/license + + Includes Sizzle.js + http://sizzlejs.com/ + Copyright 2011, The Dojo Foundation + Released under the MIT, BSD, and GPL Licenses. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + - Modernizr - ./test/third-party/modernizr + + https://github.com/Modernizr/Modernizr + + Modernizr is available under the MIT license + + Copyright (c) 2009–2011 + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + - Benchmark.js - ./test/third-party/benchmarkjs + + https://github.com/alexanderbeletsky/benchmark-js + + Copyright 2010-2012 Mathias Bynens + Based on JSLitmus.js, copyright Robert Kieffer + Modified by John-David Dalton + Available under MIT license + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - normalize.css - ./test/third-party/normalize + + Copyright (c) Nicolas Gallagher and Jonathan Neal + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - Foundation - ./test/third-party/foundation + + Copyright (c) 2012 Mark Hayes + + MIT License + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - ua-parser ./test/third-party/ua-parser + + https://github.com/faisalman/ua-parser-js + + Copyright © 2012 Faisalman + Dual licensed under GPLv2 & MIT + Copyright © 2012 Faisalman + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + - HTML5 boilerplate + + https://github.com/h5bp/html5-boilerplate + + Copyright (c) HTML5 Boilerplate + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + - classList - ./test/third-party/classlist + + http://purl.eligrey.com/github/classList.js/blob/master/classList.js + + This software is dedicated to the public domain. No warranty is expressed or implied. + Use this software at your own risk. + + - fastclick - ./test/third-party/fastclick + + https://github.com/ftlabs/fastclick + + Copyright (C) 2012 The Financial Times Ltd. + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/README.md b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/README.md new file mode 100755 index 0000000..a89dad2 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/README.md @@ -0,0 +1,89 @@ +# Topcoat + +CSS for clean and fast web apps + +--- + +## Usage + +* [Download Topcoat](https://github.com/topcoat/topcoat/archive/0.7.0.zip) + +* Open index.html to view the usage guides. +* Copy your desired theme CSS from the `css/` folder into your project +* Copy the `img/` and `font/` folders into your project ( Feel free to only + copy the images and font weights you intend to use ) +* Link the CSS into your page + +```css + +``` + +_*Alternatively incorporate the css into your build process if you are so +inclined._ + +--- + +## Contributing + +Start by checking out our [Backlog](http://huboard.com/topcoat/topcoat/backlog). (Pls file issues against this repo.) + +* [Fill out the CLA here](http://topcoat.io/dev/topcoat-cla.html) +* [fork](https://help.github.com/articles/fork-a-repo) the repo +* Create a branch + + git checkout -b my_branch + +* Add your changes following the [coding guidelines](https://github.com/topcoat/topcoat/wiki/Coding-Guidelines) +* Commit your changes + + git commit -am "Added some awesome stuff" + +* Push your branch + + git push origin my_branch + +* make a [pull request](https://help.github.com/articles/using-pull-requests) + +For the details see our [Engineering Practices](https://github.com/topcoat/topcoat/wiki/Engineering-Practices). + +### Testing + +For performance tests, see [dev/test/perf/telemetry/](https://github.com/topcoat/topcoat/tree/master/dev/test/perf/telemetry). + +### Building + +Topcoat uses [Grunt](http://gruntjs.com/) to build + +* Open the terminal from the topcoat directory + + cd topcoat + +* Install [npm](http://nodejs.org/download/) +_*comes packaged with node._ +* Install its command line interface (CLI) globally + + npm install -g grunt-cli + +* Install dependencies with npm + + npm install + + +_*Topcoat uses Grunt 0.4.0. You might want to [read](http://gruntjs.com/getting-started) more on their website if you haven't upgraded since a lot has changed._ + +* Type `grunt` in the command line to build the css. +* The results will be built into the release folder. +* Alternatively type `grunt watch` to have the build run automatically when you make changes to +source files. + +--- + +## Release notes +See [Release Notes](https://github.com/topcoat/topcoat/releases/). + +--- + +## License + +[Apache license](https://raw.github.com/topcoat/topcoat/master/LICENSE) + diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/contributors.txt b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/contributors.txt new file mode 100755 index 0000000..e4cd8b7 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/contributors.txt @@ -0,0 +1,7 @@ +# Github accounts of the people who signed the TopCoat CLA (http://topcoat.io/dev/topcoat-cla.html). +# CLA needs to be signed before accepting pull requests. +@yourpalsonja +@noformnocontent +@jrowny +@aparticulate +@jlembeck diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-dark.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-dark.css new file mode 100755 index 0000000..e590e11 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-dark.css @@ -0,0 +1,3450 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 1rem; +} + +input[type="checkbox"] { + height: 1rem; + width: 1rem; + margin-top: 0; + margin-right: -1rem; + margin-bottom: -1rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 1rem; +} + +.topcoat-checkbox__checkmark:before { + width: 1rem; + height: 1rem; + background: #595b5b; + border: 1px solid #303233; + border-radius: 3px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-checkbox__checkmark { + width: 1rem; + height: 1rem; +} + +.topcoat-checkbox__checkmark:after { + top: 2px; + left: 1px; + opacity: 0; + width: 14px; + height: 4px; + background: transparent; + border: 7px solid #fff; + border-width: 3px; + border-top: none; + border-right: none; + border-radius: 1px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.25rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: baseline; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 4px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-icon-button:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 1.688rem; + height: 1.688rem; + line-height: 1.688rem; +} + +.topcoat-icon-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 0.81406rem; + height: 0.81406rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 1.06344rem; + height: 1.06344rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
    +
    + + +
    +
    + + +
    +
    + + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.063rem; + width: 1.063rem; + margin-top: 0; + margin-right: -1.063rem; + margin-bottom: -1.063rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #c6c8c8; + line-height: 1.063rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.063rem; + height: 1.063rem; + background: #595b5b; + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.063rem; + height: 1.063rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.313rem; + height: 0.313rem; + background: #fff; + border: 1px solid rgba(255,255,255,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 0.313rem; + left: 0.313rem; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 4px; + border: 1px solid #303233; + background-color: #424546; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-moz-range-track { + border-radius: 4px; + border: 1px solid #303233; + background-color: #424546; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 4px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range::-moz-range-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 4px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 1.313rem; + font-size: 12px; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + padding: 0 0 0 1.3rem; + border-radius: 15px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 12px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 1.688rem; + font-size: 0.875rem; + font-weight: 400; + padding: 0 0 0 1.8rem; + border-radius: 25px; + background-position: 1.2em center; + background-size: 0.875rem; +} + +.topcoat-search-input--large:disabled { + color: #fff; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + +
    +
    + + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 12px; + padding: 0 0.563rem; + border-radius: 4px; + border: 1px solid #303233; + overflow: hidden; + width: 3.5rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 2.6rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #5dc1ff; + background-color: #404141; + right: 0.8rem; + padding-left: 0.75rem; +} + +.topcoat-switch__toggle { + line-height: 1.313rem; + height: 1.313rem; + width: 1rem; + border-radius: 4px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #595b5b; + border: 1px solid #303233; + margin-left: -0.6rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #727373; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #404141; + left: 0.8rem; + padding-left: 0.6rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 1.85rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
    + + + +
    + examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 0.563rem; + height: 1.313rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border-top: 1px solid #303233; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #5dc1ff; + background-color: #404141; + box-shadow: inset 0 0 2px #313231; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 1.313rem; + font-size: 12px; + letter-spacing: 0; + padding: 0 0.563rem; + border: 1px solid #303233; + border-radius: 4px; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 1.688rem; + font-size: 0.875rem; +} + +.topcoat-text-input--large:disabled { + color: #fff; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 1rem; + font-size: 1rem; + font-weight: 400; + border-radius: 4px; + line-height: 1.313rem; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + letter-spacing: 0; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 1.3rem; + line-height: 1.688rem; +} + +.topcoat-textarea--large:disabled { + color: #fff; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #fff; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #4b4d4e; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_light.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-dark.min.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-dark.min.css new file mode 100755 index 0000000..1623395 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-dark.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:4px;border-bottom-left-radius:4px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:4px;border-bottom-right-radius:4px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:1rem}input[type=checkbox]{height:1rem;width:1rem;margin-top:0;margin-right:-1rem;margin-bottom:-1rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:1rem}.topcoat-checkbox__checkmark:before{width:1rem;height:1rem;background:#595b5b;border:1px solid #303233;border-radius:3px;box-shadow:inset 0 1px #727373}.topcoat-checkbox__checkmark{width:1rem;height:1rem}.topcoat-checkbox__checkmark:after{top:2px;left:1px;opacity:0;width:14px;height:4px;background:transparent;border:7px solid #fff;border-width:3px;border-top:0;border-right:0;border-radius:1px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .25rem;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:baseline;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:4px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#646666}.topcoat-icon-button:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:1.688rem;height:1.688rem;line-height:1.688rem}.topcoat-icon-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:.81406rem;height:.81406rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:1.06344rem;height:1.06344rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.063rem;width:1.063rem;margin-top:0;margin-right:-1.063rem;margin-bottom:-1.063rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#c6c8c8;line-height:1.063rem}.topcoat-radio-button__checkmark:before{width:1.063rem;height:1.063rem;background:#595b5b;border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-radio-button__checkmark{position:relative;width:1.063rem;height:1.063rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.313rem;height:.313rem;background:#fff;border:1px solid rgba(255,255,255,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:.313rem;left:.313rem}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:4px;border:1px solid #303233;background-color:#424546;height:.5rem;border-radius:15px}.topcoat-range::-moz-range-track{border-radius:4px;border:1px solid #303233;background-color:#424546;height:.5rem;border-radius:15px}.topcoat-range::-webkit-slider-thumb{height:1.313rem;width:.75rem;background-color:#595b5b;border:1px solid #303233;border-radius:4px;box-shadow:inset 0 1px #727373}.topcoat-range::-moz-range-thumb{height:1.313rem;width:.75rem;background-color:#595b5b;border:1px solid #303233;border-radius:4px;box-shadow:inset 0 1px #727373}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:1.313rem;font-size:12px;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;padding:0 0 0 1.3rem;border-radius:15px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:12px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input:disabled::-moz-placeholder{color:#fff}.topcoat-search-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-search-input--large{line-height:1.688rem;font-size:.875rem;font-weight:400;padding:0 0 0 1.8rem;border-radius:25px;background-position:1.2em center;background-size:.875rem}.topcoat-search-input--large:disabled{color:#fff}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#fff}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:12px;padding:0 .563rem;border-radius:4px;border:1px solid #303233;overflow:hidden;width:3.5rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:2.6rem}.topcoat-switch__toggle:before{content:'ON';color:#5dc1ff;background-color:#404141;right:.8rem;padding-left:.75rem}.topcoat-switch__toggle{line-height:1.313rem;height:1.313rem;width:1rem;border-radius:4px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#595b5b;border:1px solid #303233;margin-left:-.6rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #727373;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#404141;left:.8rem;padding-left:.6rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:1.85rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 .563rem;height:1.313rem;line-height:1.313rem;letter-spacing:0;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border-top:1px solid #303233}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#5dc1ff;background-color:#404141;box-shadow:inset 0 0 2px #313231}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:1.313rem;font-size:12px;letter-spacing:0;padding:0 .563rem;border:1px solid #303233;border-radius:4px;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input:disabled::-moz-placeholder{color:#fff}.topcoat-text-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:1.688rem;font-size:.875rem}.topcoat-text-input--large:disabled{color:#fff}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:1rem;font-size:1rem;font-weight:400;border-radius:4px;line-height:1.313rem;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;letter-spacing:0}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea:disabled::-moz-placeholder{color:#fff}.topcoat-textarea:disabled:-ms-input-placeholder{color:#fff}.topcoat-textarea--large{font-size:1.3rem;line-height:1.688rem}.topcoat-textarea--large:disabled{color:#fff}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea--large:disabled::-moz-placeholder{color:#fff}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#fff}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#4b4d4e;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_light.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-light.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-light.css new file mode 100755 index 0000000..0da42ea --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-light.css @@ -0,0 +1,3450 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 0.563rem; + font-size: 12px; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 4px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 0.875rem; + font-weight: 600; + line-height: 1.688rem; + padding: 0 0.875rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 1rem; +} + +input[type="checkbox"] { + height: 1rem; + width: 1rem; + margin-top: 0; + margin-right: -1rem; + margin-bottom: -1rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 1rem; +} + +.topcoat-checkbox__checkmark:before { + width: 1rem; + height: 1rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 3px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-checkbox__checkmark { + width: 1rem; + height: 1rem; +} + +.topcoat-checkbox__checkmark:after { + top: 2px; + left: 1px; + opacity: 0; + width: 14px; + height: 4px; + background: transparent; + border: 7px solid #666; + border-width: 3px; + border-top: none; + border-right: none; + border-radius: 1px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.25rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: baseline; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 4px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-icon-button:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 1.688rem; + height: 1.688rem; + line-height: 1.688rem; +} + +.topcoat-icon-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 0.81406rem; + height: 0.81406rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 1.06344rem; + height: 1.06344rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
    +
    + + +
    +
    + + +
    +
    + + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.063rem; + width: 1.063rem; + margin-top: 0; + margin-right: -1.063rem; + margin-bottom: -1.063rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #454545; + line-height: 1.063rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.063rem; + height: 1.063rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.063rem; + height: 1.063rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.313rem; + height: 0.313rem; + background: #666; + border: 1px solid rgba(0,0,0,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 0.313rem; + left: 0.313rem; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 4px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-moz-range-track { + border-radius: 4px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 0.5rem; + border-radius: 15px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 4px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range::-moz-range-thumb { + height: 1.313rem; + width: 0.75rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 4px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 1.313rem; + font-size: 12px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + padding: 0 0 0 1.3rem; + border-radius: 15px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 12px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 1.688rem; + font-size: 0.875rem; + font-weight: 400; + padding: 0 0 0 1.8rem; + border-radius: 25px; + background-position: 1.2em center; + background-size: 0.875rem; +} + +.topcoat-search-input--large:disabled { + color: #000; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + +
    +
    + + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 12px; + padding: 0 0.563rem; + border-radius: 4px; + border: 1px solid #a5a8a8; + overflow: hidden; + width: 3.5rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 2.6rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #0083e8; + background-color: #e0f0fa; + right: 0.8rem; + padding-left: 0.75rem; +} + +.topcoat-switch__toggle { + line-height: 1.313rem; + height: 1.313rem; + width: 1rem; + border-radius: 4px; + color: #454545; + text-shadow: 0 1px #fff; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + margin-left: -0.6rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #fff; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #d3d7d7; + left: 0.8rem; + padding-left: 0.6rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 1.85rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
    + + + +
    + examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 0.563rem; + height: 1.313rem; + line-height: 1.313rem; + letter-spacing: 0; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border-top: 1px solid #a5a8a8; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #0083e8; + background-color: #e0f0fa; + box-shadow: inset 0 0 2px #c0ced8; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 1.313rem; + font-size: 12px; + letter-spacing: 0; + padding: 0 0.563rem; + border: 1px solid #a5a8a8; + border-radius: 4px; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 1.688rem; + font-size: 0.875rem; +} + +.topcoat-text-input--large:disabled { + color: #000; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 1rem; + font-size: 1rem; + font-weight: 400; + border-radius: 4px; + line-height: 1.313rem; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + letter-spacing: 0; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 1.3rem; + line-height: 1.688rem; +} + +.topcoat-textarea--large:disabled { + color: #000; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #000; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #dfe2e2; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_dark.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-light.min.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-light.min.css new file mode 100755 index 0000000..e682662 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-desktop-light.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:4px;border-bottom-left-radius:4px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:4px;border-bottom-right-radius:4px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 .563rem;font-size:12px;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:4px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:.875rem;font-weight:600;line-height:1.688rem;padding:0 .875rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:1rem}input[type=checkbox]{height:1rem;width:1rem;margin-top:0;margin-right:-1rem;margin-bottom:-1rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:1rem}.topcoat-checkbox__checkmark:before{width:1rem;height:1rem;background:#e5e9e8;border:1px solid #a5a8a8;border-radius:3px;box-shadow:inset 0 1px #fff}.topcoat-checkbox__checkmark{width:1rem;height:1rem}.topcoat-checkbox__checkmark:after{top:2px;left:1px;opacity:0;width:14px;height:4px;background:transparent;border:7px solid #666;border-width:3px;border-top:0;border-right:0;border-radius:1px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .25rem;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:baseline;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:4px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#edf1f1}.topcoat-icon-button:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:1.688rem;height:1.688rem;line-height:1.688rem}.topcoat-icon-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:.81406rem;height:.81406rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:1.06344rem;height:1.06344rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.063rem;width:1.063rem;margin-top:0;margin-right:-1.063rem;margin-bottom:-1.063rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#454545;line-height:1.063rem}.topcoat-radio-button__checkmark:before{width:1.063rem;height:1.063rem;background:#e5e9e8;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-radio-button__checkmark{position:relative;width:1.063rem;height:1.063rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.313rem;height:.313rem;background:#666;border:1px solid rgba(0,0,0,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:.313rem;left:.313rem}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:4px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:.5rem;border-radius:15px}.topcoat-range::-moz-range-track{border-radius:4px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:.5rem;border-radius:15px}.topcoat-range::-webkit-slider-thumb{height:1.313rem;width:.75rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:4px;box-shadow:inset 0 1px #fff}.topcoat-range::-moz-range-thumb{height:1.313rem;width:.75rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:4px;box-shadow:inset 0 1px #fff}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:1.313rem;font-size:12px;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;padding:0 0 0 1.3rem;border-radius:15px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:12px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input:disabled::-moz-placeholder{color:#000}.topcoat-search-input:disabled:-ms-input-placeholder{color:#000}.topcoat-search-input--large{line-height:1.688rem;font-size:.875rem;font-weight:400;padding:0 0 0 1.8rem;border-radius:25px;background-position:1.2em center;background-size:.875rem}.topcoat-search-input--large:disabled{color:#000}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input--large:disabled::-moz-placeholder{color:#000}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#000}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:12px;padding:0 .563rem;border-radius:4px;border:1px solid #a5a8a8;overflow:hidden;width:3.5rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:2.6rem}.topcoat-switch__toggle:before{content:'ON';color:#0083e8;background-color:#e0f0fa;right:.8rem;padding-left:.75rem}.topcoat-switch__toggle{line-height:1.313rem;height:1.313rem;width:1rem;border-radius:4px;color:#454545;text-shadow:0 1px #fff;background-color:#e5e9e8;border:1px solid #a5a8a8;margin-left:-.6rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #fff;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#d3d7d7;left:.8rem;padding-left:.6rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:1.85rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 .563rem;height:1.313rem;line-height:1.313rem;letter-spacing:0;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border-top:1px solid #a5a8a8}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#0083e8;background-color:#e0f0fa;box-shadow:inset 0 0 2px #c0ced8}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:1.313rem;font-size:12px;letter-spacing:0;padding:0 .563rem;border:1px solid #a5a8a8;border-radius:4px;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input:disabled::-moz-placeholder{color:#000}.topcoat-text-input:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:1.688rem;font-size:.875rem}.topcoat-text-input--large:disabled{color:#000}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input--large:disabled::-moz-placeholder{color:#000}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:1rem;font-size:1rem;font-weight:400;border-radius:4px;line-height:1.313rem;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;letter-spacing:0}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea:disabled::-moz-placeholder{color:#000}.topcoat-textarea:disabled:-ms-input-placeholder{color:#000}.topcoat-textarea--large{font-size:1.3rem;line-height:1.688rem}.topcoat-textarea--large:disabled{color:#000}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea--large:disabled::-moz-placeholder{color:#000}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#000}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#dfe2e2;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_dark.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-dark.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-dark.css new file mode 100755 index 0000000..0d3aa5f --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-dark.css @@ -0,0 +1,3700 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #1976c3; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 2rem; +} + +input[type="checkbox"] { + height: 2rem; + width: 2rem; + margin-top: 0; + margin-right: -2rem; + margin-bottom: -2rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 2rem; +} + +.topcoat-checkbox__checkmark:before { + width: 2rem; + height: 2rem; + background: #595b5b; + border: 1px solid #303233; + border-radius: 3px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-checkbox__checkmark { + width: 2rem; + height: 2rem; +} + +.topcoat-checkbox__checkmark:after { + top: 1px; + left: 2px; + opacity: 0; + width: 28px; + height: 11px; + background: transparent; + border: 7px solid #fff; + border-width: 7px; + border-top: none; + border-right: none; + border-radius: 2px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.75rem; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: baseline; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border: 1px solid #303233; + border-radius: 6px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #646666; +} + +.topcoat-icon-button:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 -1px rgba(0,0,0,0.69); + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #404141; + border: 1px solid #303233; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 4.375rem; + height: 4.375rem; + line-height: 4.375rem; +} + +.topcoat-icon-button--large:active { + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 1.62rem; + height: 1.62rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 2.499999998125rem; + height: 2.499999998125rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list, +.topcoat-list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header, +.topcoat-list__header { + margin: 0; +} + +.list__container, +.topcoat-list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item, +.topcoat-list__item { + margin: 0; + padding: 0; +} + +/* topdoc + name: List + description: Topcoat default list skin + markup: +
    +

    Category

    +
      +
    • + Item +
    • +
    • + Item +
    • +
    • + Item +
    • +
    +
    + tags: + - mobile + - list +*/ + +.topcoat-list { + border-top: 1px solid #2f3234; + border-bottom: 1px solid #5e6061; + background-color: #444849; +} + +.topcoat-list__header { + padding: 4px 20px; + font-size: 0.9em; + font-weight: 400; + background-color: #3b3e40; + color: #868888; + text-shadow: 0 -1px 0 rgba(0,0,0,0.3); + border-top: solid 1px rgba(255,255,255,0.1); + border-bottom: solid 1px rgba(255,255,255,0.05); +} + +.topcoat-list__container { + border-top: 1px solid #2f3234; + color: #c6c8c8; +} + +.topcoat-list__item { + padding: 1.25rem; + border-top: 1px solid #5e6061; + border-bottom: 1px solid #2f3234; +} + +.topcoat-list__item:first-child { + border-top: 1px solid rgba(0,0,0,0.05); +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar, +.topcoat-navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item, +.topcoat-navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title, +.topcoat-navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* topdoc + name: Navigation Bar + description: A place where navigation goes to drink + markup: +
    +
    +

    Header

    +
    +
    + tags: + - desktop + - light + - mobile + - navigation + - bar +*/ + +.topcoat-navigation-bar { + height: 4.375rem; + padding-left: 1rem; + padding-right: 1rem; + background: #595b5b; + color: #fff; + box-shadow: inset 0 -1px #333434, 0 1px rgba(0,0,0,0.15); +} + +.topcoat-navigation-bar__item { + margin: 0; + line-height: 4.375rem; + vertical-align: top; +} + +.topcoat-navigation-bar__title { + font-size: 1.3rem; + font-weight: 400; + color: #fff; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
    +
    + + +
    +
    + + +
    +
    + + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.875rem; + width: 1.875rem; + margin-top: 0; + margin-right: -1.875rem; + margin-bottom: -1.875rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #c6c8c8; + line-height: 1.875rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.875rem; + height: 1.875rem; + background: #595b5b; + border: 1px solid #303233; + box-shadow: inset 0 1px #727373; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.875rem; + height: 1.875rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.875rem; + height: 0.875rem; + background: #fff; + border: 1px solid rgba(255,255,255,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 7px; + left: 7px; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 6px; + border: 1px solid #303233; + background-color: #424546; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-moz-range-track { + border-radius: 6px; + border: 1px solid #303233; + background-color: #424546; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 3rem; + width: 2rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 6px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range::-moz-range-thumb { + height: 3rem; + width: 2rem; + background-color: #595b5b; + border: 1px solid #303233; + border-radius: 6px; + box-shadow: inset 0 1px #727373; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 3rem; + font-size: 16px; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + padding: 0 0 0 2rem; + border-radius: 30px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 16px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 4.375rem; + font-size: 1.3rem; + font-weight: 200; + padding: 0 0 0 2.9rem; + border-radius: 40px; + background-position: 1.2em center; + background-size: 1.3rem; +} + +.topcoat-search-input--large:disabled { + color: #fff; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + +
    +
    + + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 16px; + padding: 0 1.25rem; + border-radius: 6px; + border: 1px solid #303233; + overflow: hidden; + width: 6rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 5rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #5dc1ff; + background-color: #404141; + right: 1rem; + padding-left: 1.5rem; +} + +.topcoat-switch__toggle { + line-height: 3rem; + height: 3rem; + width: 2rem; + border-radius: 6px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + background-color: #595b5b; + border: 1px solid #303233; + margin-left: -1.3rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #727373; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #404141; + left: 1rem; + padding-left: 2rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 2.7rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
    + + + +
    + examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 1.25rem; + height: 3rem; + line-height: 3rem; + letter-spacing: 1px; + color: #c6c8c8; + text-shadow: 0 -1px rgba(0,0,0,0.69); + vertical-align: top; + background-color: #595b5b; + box-shadow: inset 0 1px #727373; + border-top: 1px solid #303233; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #5dc1ff; + background-color: #404141; + box-shadow: inset 0 0 2px #313231; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 3rem; + font-size: 16px; + letter-spacing: 1px; + padding: 0 1.25rem; + border: 1px solid #303233; + border-radius: 6px; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 4.375rem; + font-size: 1.3rem; +} + +.topcoat-text-input--large:disabled { + color: #fff; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #fff; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 2rem; + font-size: 2.5rem; + font-weight: 200; + border-radius: 6px; + line-height: 3rem; + border: 1px solid #303233; + background-color: #404141; + box-shadow: inset 0 1px rgba(0,0,0,0.18); + color: #c6c8c8; + letter-spacing: 1px; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #646666; + color: #fff; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #fff; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 3rem; + line-height: 4.375rem; +} + +.topcoat-textarea--large:disabled { + color: #fff; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #fff; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #fff; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #4b4d4e; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_light.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-dark.min.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-dark.min.css new file mode 100755 index 0000000..2ce6f11 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-dark.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:6px;border-bottom-left-radius:6px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:6px;border-bottom-right-radius:6px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#646666}.topcoat-button:active,.topcoat-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#1976c3;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:2rem}input[type=checkbox]{height:2rem;width:2rem;margin-top:0;margin-right:-2rem;margin-bottom:-2rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:2rem}.topcoat-checkbox__checkmark:before{width:2rem;height:2rem;background:#595b5b;border:1px solid #303233;border-radius:3px;box-shadow:inset 0 1px #727373}.topcoat-checkbox__checkmark{width:2rem;height:2rem}.topcoat-checkbox__checkmark:after{top:1px;left:2px;opacity:0;width:28px;height:11px;background:transparent;border:7px solid #fff;border-width:7px;border-top:0;border-right:0;border-radius:2px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .75rem;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:baseline;background-color:#595b5b;box-shadow:inset 0 1px #727373;border:1px solid #303233;border-radius:6px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#646666}.topcoat-icon-button:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 -1px rgba(0,0,0,.69);border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#404141;border:1px solid #303233;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:4.375rem;height:4.375rem;line-height:4.375rem}.topcoat-icon-button--large:active{background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:1.62rem;height:1.62rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:2.499999998125rem;height:2.499999998125rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.list,.topcoat-list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header,.topcoat-list__header{margin:0}.list__container,.topcoat-list__container{padding:0;margin:0;list-style-type:none}.list__item,.topcoat-list__item{margin:0;padding:0}.topcoat-list{border-top:1px solid #2f3234;border-bottom:1px solid #5e6061;background-color:#444849}.topcoat-list__header{padding:4px 20px;font-size:.9em;font-weight:400;background-color:#3b3e40;color:#868888;text-shadow:0 -1px 0 rgba(0,0,0,.3);border-top:solid 1px rgba(255,255,255,.1);border-bottom:solid 1px rgba(255,255,255,.05)}.topcoat-list__container{border-top:1px solid #2f3234;color:#c6c8c8}.topcoat-list__item{padding:1.25rem;border-top:1px solid #5e6061;border-bottom:1px solid #2f3234}.topcoat-list__item:first-child{border-top:1px solid rgba(0,0,0,.05)}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.navigation-bar,.topcoat-navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item,.topcoat-navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title,.topcoat-navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.topcoat-navigation-bar{height:4.375rem;padding-left:1rem;padding-right:1rem;background:#595b5b;color:#fff;box-shadow:inset 0 -1px #333434,0 1px rgba(0,0,0,.15)}.topcoat-navigation-bar__item{margin:0;line-height:4.375rem;vertical-align:top}.topcoat-navigation-bar__title{font-size:1.3rem;font-weight:400;color:#fff}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.875rem;width:1.875rem;margin-top:0;margin-right:-1.875rem;margin-bottom:-1.875rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#c6c8c8;line-height:1.875rem}.topcoat-radio-button__checkmark:before{width:1.875rem;height:1.875rem;background:#595b5b;border:1px solid #303233;box-shadow:inset 0 1px #727373}.topcoat-radio-button__checkmark{position:relative;width:1.875rem;height:1.875rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.875rem;height:.875rem;background:#fff;border:1px solid rgba(255,255,255,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:7px;left:7px}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:6px;border:1px solid #303233;background-color:#424546;height:1rem;border-radius:30px}.topcoat-range::-moz-range-track{border-radius:6px;border:1px solid #303233;background-color:#424546;height:1rem;border-radius:30px}.topcoat-range::-webkit-slider-thumb{height:3rem;width:2rem;background-color:#595b5b;border:1px solid #303233;border-radius:6px;box-shadow:inset 0 1px #727373}.topcoat-range::-moz-range-thumb{height:3rem;width:2rem;background-color:#595b5b;border:1px solid #303233;border-radius:6px;box-shadow:inset 0 1px #727373}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:3rem;font-size:16px;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;padding:0 0 0 2rem;border-radius:30px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:16px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input:disabled::-moz-placeholder{color:#fff}.topcoat-search-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-search-input--large{line-height:4.375rem;font-size:1.3rem;font-weight:200;padding:0 0 0 2.9rem;border-radius:40px;background-position:1.2em center;background-size:1.3rem}.topcoat-search-input--large:disabled{color:#fff}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-search-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#fff}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:16px;padding:0 1.25rem;border-radius:6px;border:1px solid #303233;overflow:hidden;width:6rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:5rem}.topcoat-switch__toggle:before{content:'ON';color:#5dc1ff;background-color:#404141;right:1rem;padding-left:1.5rem}.topcoat-switch__toggle{line-height:3rem;height:3rem;width:2rem;border-radius:6px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);background-color:#595b5b;border:1px solid #303233;margin-left:-1.3rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #727373;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#404141;left:1rem;padding-left:2rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:2.7rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 1.25rem;height:3rem;line-height:3rem;letter-spacing:1px;color:#c6c8c8;text-shadow:0 -1px rgba(0,0,0,.69);vertical-align:top;background-color:#595b5b;box-shadow:inset 0 1px #727373;border-top:1px solid #303233}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#5dc1ff;background-color:#404141;box-shadow:inset 0 0 2px #313231}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:3rem;font-size:16px;letter-spacing:1px;padding:0 1.25rem;border:1px solid #303233;border-radius:6px;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input:disabled::-moz-placeholder{color:#fff}.topcoat-text-input:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:4.375rem;font-size:1.3rem}.topcoat-text-input--large:disabled{color:#fff}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-text-input--large:disabled::-moz-placeholder{color:#fff}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#fff}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:2rem;font-size:2.5rem;font-weight:200;border-radius:6px;line-height:3rem;border:1px solid #303233;background-color:#404141;box-shadow:inset 0 1px rgba(0,0,0,.18);color:#c6c8c8;letter-spacing:1px}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#646666;color:#fff;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea:disabled::-moz-placeholder{color:#fff}.topcoat-textarea:disabled:-ms-input-placeholder{color:#fff}.topcoat-textarea--large{font-size:3rem;line-height:4.375rem}.topcoat-textarea--large:disabled{color:#fff}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#fff}.topcoat-textarea--large:disabled::-moz-placeholder{color:#fff}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#fff}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#4b4d4e;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_light.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-light.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-light.css new file mode 100755 index 0000000..6735055 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-light.css @@ -0,0 +1,3700 @@ +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled, +.topcoat-button-bar__button:disabled, +.topcoat-button-bar__button--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta, +.topcoat-button-bar__button, +.topcoat-button-bar__button--large { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover, +.topcoat-button-bar__button:hover, +.topcoat-button-bar__button--large:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active, +.topcoat-button-bar__button:active, +.topcoat-button-bar__button--large:active, +:checked + .topcoat-button-bar__button { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus, +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button-bar__button--large { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +.button-bar, +.topcoat-button-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-button-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-button-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button Bar + description: Component of grouped buttons + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + examples: + mobile button bar: http://codepen.io/Topcoat/pen/kdKyg + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar +*/ + +.topcoat-button-bar > .topcoat-button-bar__item:first-child { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} + +.topcoat-button-bar > .topcoat-button-bar__item:last-child { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} + +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large { + border-right: none; +} + +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button, +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large { + border-left: none; +} + +.topcoat-button-bar__button { + border-radius: inherit; +} + +.topcoat-button-bar__button:focus, +.topcoat-button-bar__button--large:focus { + z-index: 1; +} + +/* topdoc + name: Large Button Bar + description: A button bar, only larger + modifiers: + :disabled: Disabled state + markup: +
    +
    + +
    +
    + +
    +
    + +
    +
    + tags: + - desktop + - light + - dark + - mobile + - button + - group + - bar + - large +*/ + +.topcoat-button-bar__button--large { + border-radius: inherit; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-button:disabled, +.topcoat-button--quiet:disabled, +.topcoat-button--large:disabled, +.topcoat-button--large--quiet:disabled, +.topcoat-button--cta:disabled, +.topcoat-button--large--cta:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Button + description: A simple button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile button: http://codepen.io/Topcoat/pen/DpKtf + tags: + - desktop + - light + - mobile + - button +*/ + +.topcoat-button, +.topcoat-button--quiet, +.topcoat-button--large, +.topcoat-button--large--quiet, +.topcoat-button--cta, +.topcoat-button--large--cta { + padding: 0 1.25rem; + font-size: 16px; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 6px; +} + +.topcoat-button:hover, +.topcoat-button--quiet:hover, +.topcoat-button--large:hover, +.topcoat-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-button:active, +.topcoat-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-button:focus, +.topcoat-button--quiet:focus, +.topcoat-button--large:focus, +.topcoat-button--large--quiet:focus, +.topcoat-button--cta:focus, +.topcoat-button--large--cta:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Button + description: A simple, yet quiet button + modifiers: + :active: Quiet button active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - quiet +*/ + +.topcoat-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-button--quiet:hover, +.topcoat-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-button--quiet:active, +.topcoat-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Button + description: A big ol button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large +*/ + +.topcoat-button--large, +.topcoat-button--large--quiet { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/* topdoc + name: Large Quiet Button + description: A large, yet quiet button + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - quiet +*/ + +.topcoat-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +/* topdoc + name: Call To Action Button + description: A CALL TO ARMS, er, ACTION! + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - call to action +*/ + +.topcoat-button--cta, +.topcoat-button--large--cta { + border: 1px solid #143250; + background-color: #288edf; + box-shadow: inset 0 1px rgba(255,255,255,0.36); + color: #fff; + font-weight: 500; + text-shadow: 0 -1px rgba(0,0,0,0.36); +} + +.topcoat-button--cta:hover, +.topcoat-button--large--cta:hover { + background-color: #509bef; +} + +.topcoat-button--cta:active, +.topcoat-button--large--cta:active { + background-color: #0380e8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Call To Action Button + description: Like call to action, but bigger + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - large + - call to action +*/ + +.topcoat-button--large--cta { + font-size: 1.3rem; + font-weight: 400; + line-height: 4.375rem; + padding: 0 1.25rem; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after { + content: ''; + position: absolute; +} + +.checkbox:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="checkbox"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.checkbox, +.topcoat-checkbox__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox__label, +.topcoat-checkbox { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.checkbox--disabled, +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.checkbox:before, +.checkbox:after, +.topcoat-checkbox__checkmark:before, +.topcoat-checkbox__checkmark:after { + content: ''; + position: absolute; +} + +.checkbox:before, +.topcoat-checkbox__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +/* topdoc + name: Checkbox + description: Default skin for Topcoat checkbox + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + + examples: + mobile checkbox: http://codepen.io/Topcoat/pen/piHcs + tags: + - desktop + - light + - mobile + - checkbox +*/ + +.topcoat-checkbox__checkmark { + height: 2rem; +} + +input[type="checkbox"] { + height: 2rem; + width: 2rem; + margin-top: 0; + margin-right: -2rem; + margin-bottom: -2rem; + margin-left: 0; +} + +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after { + opacity: 1; +} + +.topcoat-checkbox { + line-height: 2rem; +} + +.topcoat-checkbox__checkmark:before { + width: 2rem; + height: 2rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 3px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-checkbox__checkmark { + width: 2rem; + height: 2rem; +} + +.topcoat-checkbox__checkmark:after { + top: 1px; + left: 2px; + opacity: 0; + width: 28px; + height: 11px; + background: transparent; + border: 7px solid #666; + border-width: 7px; + border-top: none; + border-right: none; + border-radius: 2px; + -webkit-transform: rotate(-50deg); + -ms-transform: rotate(-50deg); + transform: rotate(-50deg); +} + +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-icon-button:disabled, +.topcoat-icon-button--quiet:disabled, +.topcoat-icon-button--large:disabled, +.topcoat-icon-button--large--quiet:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Icon Button + description: Like button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon +*/ + +.topcoat-icon-button, +.topcoat-icon-button--quiet, +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + padding: 0 0.75rem; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: baseline; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border: 1px solid #a5a8a8; + border-radius: 6px; +} + +.topcoat-icon-button:hover, +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large:hover, +.topcoat-icon-button--large--quiet:hover { + background-color: #edf1f1; +} + +.topcoat-icon-button:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +.topcoat-icon-button:focus, +.topcoat-icon-button--quiet:focus, +.topcoat-icon-button--quiet:hover:focus, +.topcoat-icon-button--large:focus, +.topcoat-icon-button--large--quiet:focus, +.topcoat-icon-button--large--quiet:hover:focus { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; + outline: 0; +} + +/* topdoc + name: Quiet Icon Button + description: Like quiet button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - quiet +*/ + +.topcoat-icon-button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon-button--quiet:hover, +.topcoat-icon-button--large--quiet:hover { + text-shadow: 0 1px #fff; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-icon-button--quiet:active, +.topcoat-icon-button--large--quiet:active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Icon Button + description: Like large button, but it has an icon. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large +*/ + +.topcoat-icon-button--large, +.topcoat-icon-button--large--quiet { + width: 4.375rem; + height: 4.375rem; + line-height: 4.375rem; +} + +.topcoat-icon-button--large:active { + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} + +/* topdoc + name: Large Quiet Icon Button + description: Like large button, but it has an icon and this one is quiet. + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + markup: + + + tags: + - desktop + - light + - mobile + - button + - icon + - large + - quiet +*/ + +.topcoat-icon-button--large--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.topcoat-icon, +.topcoat-icon--large { + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + width: 1.62rem; + height: 1.62rem; + vertical-align: middle; + top: -1px; +} + +.topcoat-icon--large { + width: 2.499999998125rem; + height: 2.499999998125rem; + top: -2px; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header { + margin: 0; +} + +.list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item { + margin: 0; + padding: 0; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.list, +.topcoat-list { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + overflow: auto; + -webkit-overflow-scrolling: touch; +} + +.list__header, +.topcoat-list__header { + margin: 0; +} + +.list__container, +.topcoat-list__container { + padding: 0; + margin: 0; + list-style-type: none; +} + +.list__item, +.topcoat-list__item { + margin: 0; + padding: 0; +} + +/* topdoc + name: List + description: Topcoat default list skin + markup: +
    +

    Category

    +
      +
    • + Item +
    • +
    • + Item +
    • +
    • + Item +
    • +
    +
    + tags: + - mobile + - list +*/ + +.topcoat-list { + border-top: 1px solid #bcbfbf; + border-bottom: 1px solid #eff1f1; + background-color: #dfe2e2; +} + +.topcoat-list__header { + padding: 4px 20px; + font-size: 0.9em; + font-weight: 400; + background-color: #cccfcf; + color: #656565; + text-shadow: 0 1px 0 rgba(255,255,255,0.5); + border-top: 1px solid rgba(255,255,255,0.5); + border-bottom: 1px solid rgba(255,255,255,0.23); +} + +.topcoat-list__container { + border-top: 1px solid #bcbfbf; + color: #454545; +} + +.topcoat-list__item { + padding: 1.25rem; + border-top: 1px solid #eff1f1; + border-bottom: 1px solid #bcbfbf; +} + +.topcoat-list__item:first-child { + border-top: 1px solid rgba(0,0,0,0.05); +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.navigation-bar, +.topcoat-navigation-bar { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + white-space: nowrap; + overflow: hidden; + word-spacing: 0; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.navigation-bar__item, +.topcoat-navigation-bar__item { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; +} + +.navigation-bar__title, +.topcoat-navigation-bar__title { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* topdoc + name: Navigation Bar + description: A place where navigation goes to drink + markup: +
    +
    +

    Header

    +
    +
    + tags: + - desktop + - light + - mobile + - navigation + - bar +*/ + +.topcoat-navigation-bar { + height: 4.375rem; + padding-left: 1rem; + padding-right: 1rem; + background: #e5e9e8; + color: #000; + box-shadow: inset 0 -1px #b9bcbc, 0 1px #d4d6d6; +} + +.topcoat-navigation-bar__item { + margin: 0; + line-height: 4.375rem; + vertical-align: top; +} + +.topcoat-navigation-bar__title { + font-size: 1.3rem; + font-weight: 400; + color: #000; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.notification, +.topcoat-notification { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +/* topdoc + name: Notification + description: Notification badge + markup: + 1 + tags: + - desktop + - light + - mobile + - notification +*/ + +.topcoat-notification { + padding: 0.15em 0.5em 0.2em; + border-radius: 2px; + background-color: #ec514e; + color: #fff; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +input[type="radio"] { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.radio-button, +.topcoat-radio-button__checkmark { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button__label, +.topcoat-radio-button { + position: relative; + display: inline-block; + vertical-align: top; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.radio-button:before, +.radio-button:after, +.topcoat-radio-button__checkmark:before, +.topcoat-radio-button__checkmark:after { + content: ''; + position: absolute; + border-radius: 100%; +} + +.radio-button:after, +.topcoat-radio-button__checkmark:after { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.radio-button:before, +.topcoat-radio-button__checkmark:before { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.radio-button--disabled, +input[type="radio"]:disabled + .topcoat-radio-button__checkmark { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Radio Button + description: A button that can play music, but usually just plays ads. + modifiers: + markup: + + +
    +
    + + +
    +
    + + +
    +
    + + + examples: + Mobile Radio Button: http://codepen.io/Topcoat/pen/HDcJj + tags: + - desktop + - light + - mobile + - Radio +*/ + +input[type="radio"] { + height: 1.875rem; + width: 1.875rem; + margin-top: 0; + margin-right: -1.875rem; + margin-bottom: -1.875rem; + margin-left: 0; +} + +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after { + opacity: 1; +} + +.topcoat-radio-button { + color: #454545; + line-height: 1.875rem; +} + +.topcoat-radio-button__checkmark:before { + width: 1.875rem; + height: 1.875rem; + background: #e5e9e8; + border: 1px solid #a5a8a8; + box-shadow: inset 0 1px #fff; +} + +.topcoat-radio-button__checkmark { + position: relative; + width: 1.875rem; + height: 1.875rem; +} + +.topcoat-radio-button__checkmark:after { + opacity: 0; + width: 0.875rem; + height: 0.875rem; + background: #666; + border: 1px solid rgba(0,0,0,0.1); + box-shadow: 0 1px rgba(255,255,255,0.5); + -webkit-transform: none; + -ms-transform: none; + transform: none; + top: 7px; + left: 7px; +} + +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb { + cursor: pointer; +} + +.range__thumb--webkit { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.range, +.topcoat-range { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +.range__thumb, +.topcoat-range::-moz-range-thumb { + cursor: pointer; +} + +.range__thumb--webkit, +.topcoat-range::-webkit-slider-thumb { + cursor: pointer; + -webkit-appearance: none; +} + +.range:disabled, +.topcoat-range:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Range + description: Range input + modifiers: + :active: Active state + :disabled: Disabled state + :hover: Hover state + :focus: Focused + markup: + + + examples: + mobile range: http://codepen.io/Topcoat/pen/BskEn + tags: + - desktop + - mobile + - range +*/ + +.topcoat-range { + border-radius: 6px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-moz-range-track { + border-radius: 6px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + height: 1rem; + border-radius: 30px; +} + +.topcoat-range::-webkit-slider-thumb { + height: 3rem; + width: 2rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 6px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range::-moz-range-thumb { + height: 3rem; + width: 2rem; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + border-radius: 6px; + box-shadow: inset 0 1px #fff; +} + +.topcoat-range:focus::-webkit-slider-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-range:focus::-moz-range-thumb { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.search-input, +.topcoat-search-input, +.topcoat-search-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; + -webkit-appearance: none; +} + +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +.search-input:disabled, +.topcoat-search-input:disabled, +.topcoat-search-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Search Input + description: A text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form +*/ + +.topcoat-search-input, +.topcoat-search-input--large { + line-height: 3rem; + font-size: 16px; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + padding: 0 0 0 2rem; + border-radius: 30px; + background-image: url("../img/search.svg"); + background-position: 1em center; + background-repeat: no-repeat; + background-size: 16px; +} + +.topcoat-search-input:focus, +.topcoat-search-input--large:focus { + background-image: url("../img/search_dark.svg"); + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-search-input::-webkit-search-cancel-button, +.topcoat-search-input::-webkit-search-decoration, +.topcoat-search-input--large::-webkit-search-cancel-button, +.topcoat-search-input--large::-webkit-search-decoration { + margin-right: 5px; +} + +.topcoat-search-input:focus::-webkit-input-placeholder, +.topcoat-search-input:focus::-webkit-input-placeholder { + color: #c6c8c8; +} + +.topcoat-search-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Search Input + description: A large text input designed for searching. + modifiers: + :disabled: Disabled state + markup: + + + tags: + - desktop + - light + - mobile + - text + - input + - search + - form + - large +*/ + +.topcoat-search-input--large { + line-height: 4.375rem; + font-size: 1.3rem; + font-weight: 200; + padding: 0 0 0 2.9rem; + border-radius: 40px; + background-position: 1.2em center; + background-size: 1.3rem; +} + +.topcoat-search-input--large:disabled { + color: #000; +} + +.topcoat-search-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-search-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.switch, +.topcoat-switch { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch__input, +.topcoat-switch__input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.switch__toggle, +.topcoat-switch__toggle { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch__toggle:before, +.switch__toggle:after, +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + content: ''; + position: absolute; + z-index: -1; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; +} + +.switch--disabled, +.topcoat-switch__input:disabled + .topcoat-switch__toggle { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Switch + description: Default skin for Topcoat switch + modifiers: + :focus: Focus state + :disabled: Disabled state + markup: + +
    +
    + +
    +
    + + examples: + mobile switch: http://codepen.io/Topcoat/pen/upxds + tags: + - desktop + - light + - mobile + - switch +*/ + +.topcoat-switch { + font-size: 16px; + padding: 0 1.25rem; + border-radius: 6px; + border: 1px solid #a5a8a8; + overflow: hidden; + width: 6rem; +} + +.topcoat-switch__toggle:before, +.topcoat-switch__toggle:after { + top: -1px; + width: 5rem; +} + +.topcoat-switch__toggle:before { + content: 'ON'; + color: #0083e8; + background-color: #e0f0fa; + right: 1rem; + padding-left: 1.5rem; +} + +.topcoat-switch__toggle { + line-height: 3rem; + height: 3rem; + width: 2rem; + border-radius: 6px; + color: #454545; + text-shadow: 0 1px #fff; + background-color: #e5e9e8; + border: 1px solid #a5a8a8; + margin-left: -1.3rem; + margin-bottom: -1px; + margin-top: -1px; + box-shadow: inset 0 1px #fff; + -webkit-transition: margin-left 0.05s ease-in-out; + transition: margin-left 0.05s ease-in-out; +} + +.topcoat-switch__toggle:after { + content: 'OFF'; + background-color: #d3d7d7; + left: 1rem; + padding-left: 2rem; +} + +.topcoat-switch__input:checked + .topcoat-switch__toggle { + margin-left: 2.7rem; +} + +.topcoat-switch__input:focus + .topcoat-switch__toggle { + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after, +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before { + background: transparent; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.button, +.topcoat-tab-bar__button { + position: relative; + display: inline-block; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-decoration: none; +} + +.button--quiet { + background: transparent; + border: 1px solid transparent; + box-shadow: none; +} + +.button--disabled, +.topcoat-tab-bar__button:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +.button-bar, +.topcoat-tab-bar { + display: table; + table-layout: fixed; + white-space: nowrap; + margin: 0; + padding: 0; +} + +.button-bar__item, +.topcoat-tab-bar__item { + display: table-cell; + width: auto; + border-radius: 0; +} + +.button-bar__item > input, +.topcoat-tab-bar__item > input { + position: absolute; + overflow: hidden; + padding: 0; + border: 0; + opacity: 0.001; + z-index: 1; + vertical-align: top; + outline: none; +} + +.button-bar__button { + border-radius: inherit; +} + +.button-bar__item:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Tab Bar + description: Component of tab buttons + modifiers: + :disabled: Disabled state + markup: +
    + + + +
    + examples: + mobile tab bar: http://codepen.io/Topcoat/pen/rJICF + tags: + - desktop + - light + - dark + - mobile + - tab + - group + - bar +*/ + +.topcoat-tab-bar__button { + padding: 0 1.25rem; + height: 3rem; + line-height: 3rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: top; + background-color: #e5e9e8; + box-shadow: inset 0 1px #fff; + border-top: 1px solid #a5a8a8; +} + +.topcoat-tab-bar__button:active, +.topcoat-tab-bar__button--large:active, +:checked + .topcoat-tab-bar__button { + color: #0083e8; + background-color: #e0f0fa; + box-shadow: inset 0 0 2px #c0ced8; +} + +.topcoat-tab-bar__button:focus, +.topcoat-tab-bar__button--large:focus { + z-index: 1; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.input, +.topcoat-text-input, +.topcoat-text-input--large { + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + vertical-align: top; + outline: none; +} + +.input:disabled, +.topcoat-text-input:disabled, +.topcoat-text-input--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Text input + description: Topdoc text input + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - mobile + - text + - input +*/ + +.topcoat-text-input, +.topcoat-text-input--large { + line-height: 3rem; + font-size: 16px; + letter-spacing: 1px; + padding: 0 1.25rem; + border: 1px solid #a5a8a8; + border-radius: 6px; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + vertical-align: top; +} + +.topcoat-text-input:focus, +.topcoat-text-input--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-text-input:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input:invalid { + border: 1px solid #d83b75; +} + +/* topdoc + name: Large Text Input + description: A bigger input, still for text. + modifiers: + :disabled: Disabled state + :focus: Focused + :invalid: Hover state + markup: + +
    +
    + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - large +*/ + +.topcoat-text-input--large { + line-height: 4.375rem; + font-size: 1.3rem; +} + +.topcoat-text-input--large:disabled { + color: #000; +} + +.topcoat-text-input--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-text-input--large:disabled:-ms-input-placeholder { + color: #000; +} + +.topcoat-text-input--large:invalid { + border: 1px solid #d83b75; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +/** +* +* Copyright 2012 Adobe Systems Inc.; +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*/ + +.textarea, +.topcoat-textarea, +.topcoat-textarea--large { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + vertical-align: top; + resize: none; + outline: none; +} + +.textarea:disabled, +.topcoat-textarea:disabled, +.topcoat-textarea--large:disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} + +/* topdoc + name: Textarea + description: A whole area, just for text. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea, +.topcoat-textarea--large { + padding: 2rem; + font-size: 2.5rem; + font-weight: 200; + border-radius: 6px; + line-height: 3rem; + border: 1px solid #a5a8a8; + background-color: #d3d7d7; + box-shadow: inset 0 1px rgba(0,0,0,0.12); + color: #454545; + letter-spacing: 1px; +} + +.topcoat-textarea:focus, +.topcoat-textarea--large:focus { + background-color: #edf1f1; + color: #000; + border: 1px solid #0940fd; + box-shadow: 0 0 0 2px #6fb5f1; +} + +.topcoat-textarea:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea:disabled:-ms-input-placeholder { + color: #000; +} + +/* topdoc + name: Large Textarea + description: A whole area, just for text; now available in large. + modifiers: + :disabled: Disabled state + markup: + +
    +
    + + tags: + - desktop + - light + - mobile + - form + - input + - textarea +*/ + +.topcoat-textarea--large { + font-size: 3rem; + line-height: 4.375rem; +} + +.topcoat-textarea--large:disabled { + color: #000; +} + +.topcoat-textarea--large:disabled::-webkit-input-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled::-moz-placeholder { + color: #000; +} + +.topcoat-textarea--large:disabled:-ms-input-placeholder { + color: #000; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Regular.otf"); +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Light.otf"); + font-weight: 200; +} + +@font-face { + font-family: "Source Sans"; + src: url("../font/SourceSansPro-Semibold.otf"); + font-weight: 600; +} + +body { + margin: 0; + padding: 0; + background: #dfe2e2; + color: #000; + font: 16px "Source Sans", helvetica, arial, sans-serif; + font-weight: 200; +} + +:focus { + outline-color: transparent; + outline-style: none; +} + +.topcoat-icon--menu-stack { + background: url("../img/hamburger_dark.svg") no-repeat; + background-size: cover; +} + +.quarter { + width: 25%; +} + +.half { + width: 50%; +} + +.three-quarters { + width: 75%; +} + +.third { + width: 33.333%; +} + +.two-thirds { + width: 66.666%; +} + +.full { + width: 100%; +} + +.left { + text-align: left; +} + +.center { + text-align: center; +} + +.right { + text-align: right; +} + +.reset-ui { + -moz-box-sizing: border-box; + box-sizing: border-box; + background-clip: padding-box; + position: relative; + display: inline-block; + vertical-align: top; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + border: none; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +/* This file should include color and image variables corresponding to the dark theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* Search Input */ + +/* List */ + +/* Checkbox */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Textarea */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* This file should include color and image variables corresponding to the light theme */ + +/* Call To Action */ + +/* Icons */ + +/* Navigation Bar */ + +/* Text Input */ + +/* List */ + +/* Overlay */ + +/* Progress bar */ + +/* Checkbox */ + +/* Range input */ + +/* Radio Button */ + +/* Tab bar */ + +/* Switch */ + +/* Containers */ + +/* Icon Button */ + +/* Navigation bar */ + +/* List */ + +/* Search Input */ + +/* Text Area */ + +/* Checkbox */ + +/* Radio */ + +/* Range input */ + +/* Search Input */ + +/* Switch */ + +/* Text Input */ + +/* Radio input */ + +/* Overlay */ + +/* Textarea */ + +/* Progress bar container */ + +/* Progress bar progress */ + +/* Search input */ + +/* Switch */ + +/* Notification */ \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-light.min.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-light.min.css new file mode 100755 index 0000000..7692377 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/css/topcoat-mobile-light.min.css @@ -0,0 +1 @@ +.button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled,.topcoat-button-bar__button:disabled,.topcoat-button-bar__button--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta,.topcoat-button-bar__button,.topcoat-button-bar__button--large{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover,.topcoat-button-bar__button:hover,.topcoat-button-bar__button--large:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active,.topcoat-button-bar__button:active,.topcoat-button-bar__button--large:active,:checked+.topcoat-button-bar__button{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus,.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button-bar__button--large{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.button-bar,.topcoat-button-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-button-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-button-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button-bar>.topcoat-button-bar__item:first-child{border-top-left-radius:6px;border-bottom-left-radius:6px}.topcoat-button-bar>.topcoat-button-bar__item:last-child{border-top-right-radius:6px;border-bottom-right-radius:6px}.topcoat-button-bar__item:first-child>.topcoat-button-bar__button,.topcoat-button-bar__item:first-child>.topcoat-button-bar__button--large{border-right:0}.topcoat-button-bar__item:last-child>.topcoat-button-bar__button,.topcoat-button-bar__item:last-child>.topcoat-button-bar__button--large{border-left:0}.topcoat-button-bar__button{border-radius:inherit}.topcoat-button-bar__button:focus,.topcoat-button-bar__button--large:focus{z-index:1}.topcoat-button-bar__button--large{border-radius:inherit}.button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled{opacity:.3;cursor:default;pointer-events:none}.button,.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-button:disabled,.topcoat-button--quiet:disabled,.topcoat-button--large:disabled,.topcoat-button--large--quiet:disabled,.topcoat-button--cta:disabled,.topcoat-button--large--cta:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-button,.topcoat-button--quiet,.topcoat-button--large,.topcoat-button--large--quiet,.topcoat-button--cta,.topcoat-button--large--cta{padding:0 1.25rem;font-size:16px;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:6px}.topcoat-button:hover,.topcoat-button--quiet:hover,.topcoat-button--large:hover,.topcoat-button--large--quiet:hover{background-color:#edf1f1}.topcoat-button:active,.topcoat-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button:focus,.topcoat-button--quiet:focus,.topcoat-button--large:focus,.topcoat-button--large--quiet:focus,.topcoat-button--cta:focus,.topcoat-button--large--cta:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--quiet:hover,.topcoat-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-button--quiet:active,.topcoat-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large,.topcoat-button--large--quiet{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}.topcoat-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-button--cta,.topcoat-button--large--cta{border:1px solid #143250;background-color:#288edf;box-shadow:inset 0 1px rgba(255,255,255,.36);color:#fff;font-weight:500;text-shadow:0 -1px rgba(0,0,0,.36)}.topcoat-button--cta:hover,.topcoat-button--large--cta:hover{background-color:#509bef}.topcoat-button--cta:active,.topcoat-button--large--cta:active{background-color:#0380e8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-button--large--cta{font-size:1.3rem;font-weight:400;line-height:4.375rem;padding:0 1.25rem}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after{content:'';position:absolute}.checkbox:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}input[type=checkbox]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.checkbox,.topcoat-checkbox__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox__label,.topcoat-checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.checkbox--disabled,input[type=checkbox]:disabled+.topcoat-checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}.checkbox:before,.checkbox:after,.topcoat-checkbox__checkmark:before,.topcoat-checkbox__checkmark:after{content:'';position:absolute}.checkbox:before,.topcoat-checkbox__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.topcoat-checkbox__checkmark{height:2rem}input[type=checkbox]{height:2rem;width:2rem;margin-top:0;margin-right:-2rem;margin-bottom:-2rem;margin-left:0}input[type=checkbox]:checked+.topcoat-checkbox__checkmark:after{opacity:1}.topcoat-checkbox{line-height:2rem}.topcoat-checkbox__checkmark:before{width:2rem;height:2rem;background:#e5e9e8;border:1px solid #a5a8a8;border-radius:3px;box-shadow:inset 0 1px #fff}.topcoat-checkbox__checkmark{width:2rem;height:2rem}.topcoat-checkbox__checkmark:after{top:1px;left:2px;opacity:0;width:28px;height:11px;background:transparent;border:7px solid #666;border-width:7px;border-top:0;border-right:0;border-radius:2px;-webkit-transform:rotate(-50deg);-ms-transform:rotate(-50deg);transform:rotate(-50deg)}input[type=checkbox]:focus+.topcoat-checkbox__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.button,.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-icon-button:disabled,.topcoat-icon-button--quiet:disabled,.topcoat-icon-button--large:disabled,.topcoat-icon-button--large--quiet:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-icon-button,.topcoat-icon-button--quiet,.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{padding:0 .75rem;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:baseline;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border:1px solid #a5a8a8;border-radius:6px}.topcoat-icon-button:hover,.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large:hover,.topcoat-icon-button--large--quiet:hover{background-color:#edf1f1}.topcoat-icon-button:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button:focus,.topcoat-icon-button--quiet:focus,.topcoat-icon-button--quiet:hover:focus,.topcoat-icon-button--large:focus,.topcoat-icon-button--large--quiet:focus,.topcoat-icon-button--large--quiet:hover:focus{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1;outline:0}.topcoat-icon-button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon-button--quiet:hover,.topcoat-icon-button--large--quiet:hover{text-shadow:0 1px #fff;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-icon-button--quiet:active,.topcoat-icon-button--large--quiet:active{color:#454545;text-shadow:0 1px #fff;background-color:#d3d7d7;border:1px solid #a5a8a8;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large,.topcoat-icon-button--large--quiet{width:4.375rem;height:4.375rem;line-height:4.375rem}.topcoat-icon-button--large:active{background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12)}.topcoat-icon-button--large--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.topcoat-icon,.topcoat-icon--large{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:1.62rem;height:1.62rem;vertical-align:middle;top:-1px}.topcoat-icon--large{width:2.499999998125rem;height:2.499999998125rem;top:-2px}.input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled{opacity:.3;cursor:default;pointer-events:none}.list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header{margin:0}.list__container{padding:0;margin:0;list-style-type:none}.list__item{margin:0;padding:0}.list,.topcoat-list{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:auto;-webkit-overflow-scrolling:touch}.list__header,.topcoat-list__header{margin:0}.list__container,.topcoat-list__container{padding:0;margin:0;list-style-type:none}.list__item,.topcoat-list__item{margin:0;padding:0}.topcoat-list{border-top:1px solid #bcbfbf;border-bottom:1px solid #eff1f1;background-color:#dfe2e2}.topcoat-list__header{padding:4px 20px;font-size:.9em;font-weight:400;background-color:#cccfcf;color:#656565;text-shadow:0 1px 0 rgba(255,255,255,.5);border-top:1px solid rgba(255,255,255,.5);border-bottom:1px solid rgba(255,255,255,.23)}.topcoat-list__container{border-top:1px solid #bcbfbf;color:#454545}.topcoat-list__item{padding:1.25rem;border-top:1px solid #eff1f1;border-bottom:1px solid #bcbfbf}.topcoat-list__item:first-child{border-top:1px solid rgba(0,0,0,.05)}.navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.navigation-bar,.topcoat-navigation-bar{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;white-space:nowrap;overflow:hidden;word-spacing:0;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navigation-bar__item,.topcoat-navigation-bar__item{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0}.navigation-bar__title,.topcoat-navigation-bar__title{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.topcoat-navigation-bar{height:4.375rem;padding-left:1rem;padding-right:1rem;background:#e5e9e8;color:#000;box-shadow:inset 0 -1px #b9bcbc,0 1px #d4d6d6}.topcoat-navigation-bar__item{margin:0;line-height:4.375rem;vertical-align:top}.topcoat-navigation-bar__title{font-size:1.3rem;font-weight:400;color:#000}.notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.notification,.topcoat-notification{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.topcoat-notification{padding:.15em .5em .2em;border-radius:2px;background-color:#ec514e;color:#fff}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after{content:'';position:absolute;border-radius:100%}.radio-button:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.radio-button,.topcoat-radio-button__checkmark{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button__label,.topcoat-radio-button{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.radio-button:before,.radio-button:after,.topcoat-radio-button__checkmark:before,.topcoat-radio-button__checkmark:after{content:'';position:absolute;border-radius:100%}.radio-button:after,.topcoat-radio-button__checkmark:after{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.radio-button:before,.topcoat-radio-button__checkmark:before{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.radio-button--disabled,input[type=radio]:disabled+.topcoat-radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}input[type=radio]{height:1.875rem;width:1.875rem;margin-top:0;margin-right:-1.875rem;margin-bottom:-1.875rem;margin-left:0}input[type=radio]:checked+.topcoat-radio-button__checkmark:after{opacity:1}.topcoat-radio-button{color:#454545;line-height:1.875rem}.topcoat-radio-button__checkmark:before{width:1.875rem;height:1.875rem;background:#e5e9e8;border:1px solid #a5a8a8;box-shadow:inset 0 1px #fff}.topcoat-radio-button__checkmark{position:relative;width:1.875rem;height:1.875rem}.topcoat-radio-button__checkmark:after{opacity:0;width:.875rem;height:.875rem;background:#666;border:1px solid rgba(0,0,0,.1);box-shadow:0 1px rgba(255,255,255,.5);-webkit-transform:none;-ms-transform:none;transform:none;top:7px;left:7px}input[type=radio]:focus+.topcoat-radio-button__checkmark:before{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb{cursor:pointer}.range__thumb--webkit{cursor:pointer;-webkit-appearance:none}.range:disabled{opacity:.3;cursor:default;pointer-events:none}.range,.topcoat-range{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}.range__thumb,.topcoat-range::-moz-range-thumb{cursor:pointer}.range__thumb--webkit,.topcoat-range::-webkit-slider-thumb{cursor:pointer;-webkit-appearance:none}.range:disabled,.topcoat-range:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-range{border-radius:6px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:1rem;border-radius:30px}.topcoat-range::-moz-range-track{border-radius:6px;border:1px solid #a5a8a8;background-color:#d3d7d7;height:1rem;border-radius:30px}.topcoat-range::-webkit-slider-thumb{height:3rem;width:2rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:6px;box-shadow:inset 0 1px #fff}.topcoat-range::-moz-range-thumb{height:3rem;width:2rem;background-color:#e5e9e8;border:1px solid #a5a8a8;border-radius:6px;box-shadow:inset 0 1px #fff}.topcoat-range:focus::-webkit-slider-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-range:focus::-moz-range-thumb{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.search-input{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input,.topcoat-search-input,.topcoat-search-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0;-webkit-appearance:none}input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}.search-input:disabled,.topcoat-search-input:disabled,.topcoat-search-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-search-input,.topcoat-search-input--large{line-height:3rem;font-size:16px;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;padding:0 0 0 2rem;border-radius:30px;background-image:url(../img/search.svg);background-position:1em center;background-repeat:no-repeat;background-size:16px}.topcoat-search-input:focus,.topcoat-search-input--large:focus{background-image:url(../img/search_dark.svg);background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-search-input::-webkit-search-cancel-button,.topcoat-search-input::-webkit-search-decoration,.topcoat-search-input--large::-webkit-search-cancel-button,.topcoat-search-input--large::-webkit-search-decoration{margin-right:5px}.topcoat-search-input:focus::-webkit-input-placeholder,.topcoat-search-input:focus::-webkit-input-placeholder{color:#c6c8c8}.topcoat-search-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input:disabled::-moz-placeholder{color:#000}.topcoat-search-input:disabled:-ms-input-placeholder{color:#000}.topcoat-search-input--large{line-height:4.375rem;font-size:1.3rem;font-weight:200;padding:0 0 0 2.9rem;border-radius:40px;background-position:1.2em center;background-size:1.3rem}.topcoat-search-input--large:disabled{color:#000}.topcoat-search-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-search-input--large:disabled::-moz-placeholder{color:#000}.topcoat-search-input--large:disabled:-ms-input-placeholder{color:#000}.switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled{opacity:.3;cursor:default;pointer-events:none}.switch,.topcoat-switch{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch__input,.topcoat-switch__input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.switch__toggle,.topcoat-switch__toggle{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch__toggle:before,.switch__toggle:after,.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{content:'';position:absolute;z-index:-1;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box}.switch--disabled,.topcoat-switch__input:disabled+.topcoat-switch__toggle{opacity:.3;cursor:default;pointer-events:none}.topcoat-switch{font-size:16px;padding:0 1.25rem;border-radius:6px;border:1px solid #a5a8a8;overflow:hidden;width:6rem}.topcoat-switch__toggle:before,.topcoat-switch__toggle:after{top:-1px;width:5rem}.topcoat-switch__toggle:before{content:'ON';color:#0083e8;background-color:#e0f0fa;right:1rem;padding-left:1.5rem}.topcoat-switch__toggle{line-height:3rem;height:3rem;width:2rem;border-radius:6px;color:#454545;text-shadow:0 1px #fff;background-color:#e5e9e8;border:1px solid #a5a8a8;margin-left:-1.3rem;margin-bottom:-1px;margin-top:-1px;box-shadow:inset 0 1px #fff;-webkit-transition:margin-left .05s ease-in-out;transition:margin-left .05s ease-in-out}.topcoat-switch__toggle:after{content:'OFF';background-color:#d3d7d7;left:1rem;padding-left:2rem}.topcoat-switch__input:checked+.topcoat-switch__toggle{margin-left:2.7rem}.topcoat-switch__input:focus+.topcoat-switch__toggle{border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-switch__input:disabled+.topcoat-switch__toggle:after,.topcoat-switch__input:disabled+.topcoat-switch__toggle:before{background:transparent}.button,.topcoat-tab-bar__button{position:relative;display:inline-block;vertical-align:top;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none}.button--quiet{background:transparent;border:1px solid transparent;box-shadow:none}.button--disabled,.topcoat-tab-bar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar,.topcoat-tab-bar{display:table;table-layout:fixed;white-space:nowrap;margin:0;padding:0}.button-bar__item,.topcoat-tab-bar__item{display:table-cell;width:auto;border-radius:0}.button-bar__item>input,.topcoat-tab-bar__item>input{position:absolute;overflow:hidden;padding:0;border:0;opacity:.001;z-index:1;vertical-align:top;outline:0}.button-bar__button{border-radius:inherit}.button-bar__item:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-tab-bar__button{padding:0 1.25rem;height:3rem;line-height:3rem;letter-spacing:1px;color:#454545;text-shadow:0 1px #fff;vertical-align:top;background-color:#e5e9e8;box-shadow:inset 0 1px #fff;border-top:1px solid #a5a8a8}.topcoat-tab-bar__button:active,.topcoat-tab-bar__button--large:active,:checked+.topcoat-tab-bar__button{color:#0083e8;background-color:#e0f0fa;box-shadow:inset 0 0 2px #c0ced8}.topcoat-tab-bar__button:focus,.topcoat-tab-bar__button--large:focus{z-index:1}.input,.topcoat-text-input,.topcoat-text-input--large{padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;vertical-align:top;outline:0}.input:disabled,.topcoat-text-input:disabled,.topcoat-text-input--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-text-input,.topcoat-text-input--large{line-height:3rem;font-size:16px;letter-spacing:1px;padding:0 1.25rem;border:1px solid #a5a8a8;border-radius:6px;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;vertical-align:top}.topcoat-text-input:focus,.topcoat-text-input--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-text-input:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input:disabled::-moz-placeholder{color:#000}.topcoat-text-input:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input:invalid{border:1px solid #d83b75}.topcoat-text-input--large{line-height:4.375rem;font-size:1.3rem}.topcoat-text-input--large:disabled{color:#000}.topcoat-text-input--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-text-input--large:disabled::-moz-placeholder{color:#000}.topcoat-text-input--large:disabled:-ms-input-placeholder{color:#000}.topcoat-text-input--large:invalid{border:1px solid #d83b75}.textarea{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea,.topcoat-textarea,.topcoat-textarea--large{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;vertical-align:top;resize:none;outline:0}.textarea:disabled,.topcoat-textarea:disabled,.topcoat-textarea--large:disabled{opacity:.3;cursor:default;pointer-events:none}.topcoat-textarea,.topcoat-textarea--large{padding:2rem;font-size:2.5rem;font-weight:200;border-radius:6px;line-height:3rem;border:1px solid #a5a8a8;background-color:#d3d7d7;box-shadow:inset 0 1px rgba(0,0,0,.12);color:#454545;letter-spacing:1px}.topcoat-textarea:focus,.topcoat-textarea--large:focus{background-color:#edf1f1;color:#000;border:1px solid #0940fd;box-shadow:0 0 0 2px #6fb5f1}.topcoat-textarea:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea:disabled::-moz-placeholder{color:#000}.topcoat-textarea:disabled:-ms-input-placeholder{color:#000}.topcoat-textarea--large{font-size:3rem;line-height:4.375rem}.topcoat-textarea--large:disabled{color:#000}.topcoat-textarea--large:disabled::-webkit-input-placeholder{color:#000}.topcoat-textarea--large:disabled::-moz-placeholder{color:#000}.topcoat-textarea--large:disabled:-ms-input-placeholder{color:#000}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Regular.otf)}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Light.otf);font-weight:200}@font-face{font-family:"Source Sans";src:url(../font/SourceSansPro-Semibold.otf);font-weight:600}body{margin:0;padding:0;background:#dfe2e2;color:#000;font:16px "Source Sans",helvetica,arial,sans-serif;font-weight:200}:focus{outline-color:transparent;outline-style:none}.topcoat-icon--menu-stack{background:url(../img/hamburger_dark.svg) no-repeat;background-size:cover}.quarter{width:25%}.half{width:50%}.three-quarters{width:75%}.third{width:33.333%}.two-thirds{width:66.666%}.full{width:100%}.left{text-align:left}.center{text-align:center}.right{text-align:right}.reset-ui{-moz-box-sizing:border-box;box-sizing:border-box;background-clip:padding-box;position:relative;display:inline-block;vertical-align:top;padding:0;margin:0;font:inherit;color:inherit;background:transparent;border:0;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden} \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/css/brackets.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/css/brackets.css new file mode 100755 index 0000000..8e32479 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/css/brackets.css @@ -0,0 +1,69 @@ +/** + * Brackets theme + * + * @author Garth Braithwaite + * @version 0.0.1 + */ +pre { + word-wrap: break-word; + padding: 6px 10px; + line-height: 19px; + margin-bottom: 20px; +} + +pre, code { + font-family: source-code-pro, 'Source Code Pro', Courier, monospace; + color: #535353; +} + +pre, pre code { + font-size: 13px; +} + +pre .comment { + color: #A2A2A2; +} + +pre .support { + color: #0086B3; +} + +pre .tag, pre .tag-name { + color: #446FBD; +} + +pre .css-property { + color: #8757AD; +} + +pre .css-value, pre .support.namespace { + color: #F18900; +} +pre .vendor-prefix { + color: #535353; +} +pre .constant.numeric, pre .keyword.unit { + color: #738D00; +} +pre .hex-color { + color: #F18900; +} +pre .entity.class { + color: #5585C4; +} + +pre .entity.id, pre .entity.function { + color: #900; +} + +pre .attribute, pre .variable { + color: #738D00; +} + +pre .string, pre .support.value { + color: #8757AD; +} + +pre .regexp { + color: #535353; +} \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/css/main.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/css/main.css new file mode 100755 index 0000000..2d0bda3 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/css/main.css @@ -0,0 +1,508 @@ +html,body{ + margin:0; + padding:0; + height: 100%; +} +body { + font-family: source-sans-pro, sans-serif; + position: relative; + -webkit-font-smoothing: antialiased; +} +body.light { + background: #F4F4F4; +} +body.dark { + color: #F0F1F1; + background: #4A4D4E; +} +body.light { + color: #181919; +} + +h1 { + font-weight: 600; +} +#wrapper { + width: 100%; + overflow-x: hidden; + background: inherit; + position: relative; +} +#site { + width: 100%; + position: relative; + z-index: 10; + background: inherit; + left: 0; + transition: all 0.2s ease-out; + -webkit-transition: all 0.2s ease-out; + transform: translate3d(0, 0, 0); + -webkit-transform: translate3d(0, 0, 0); +} +#site:before{ + position: absolute; + content: ''; + left: -4px; + height: 100%; + width: 4px; + background: #3B3E3E; +} +#site.open { + transform: translate3d(250px, 0, 0); + -webkit-transform: translate3d(250px, 0, 0); +} +pre { + font-family: source-code-pro, sans-serif; + font-size: 12px; +} +/* Main Header */ +#main-header { + color: #373435; + background: #fff; + height: 98px; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 10px 20px; + position: relative; +} +#main-header hgroup { + text-align: center; +} +#main-header hgroup h1 { + font-size: 40px; + margin: 5px 0 0; + letter-spacing: -.065em; + line-height: 1.1em; +} +#main-header hgroup a { + color: #464646; + text-decoration: none; +} +#main-header hgroup a:hover { + color: #000; +} +#main-header hgroup p { + font-size: 13px; + color: #999; + margin: 0; +} +#main-header nav { + display: none; +} +#slide-menu-button { + position: absolute; + top: 20px; + left: 20px; + display: inline-block; + vertical-align: top; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-background-clip: padding; + -moz-background-clip: padding; + background-clip: padding-box; + padding: 0; + margin: 0; + font: inherit; + color: inherit; + background: transparent; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + padding: 0 0.5rem; + line-height: 2rem; + letter-spacing: 1px; + color: #454545; + text-shadow: 0 1px #fff; + vertical-align: baseline; + -webkit-box-shadow: inset 0 1px #fff; + box-shadow: inset 0 1px #fff; + -webkit-border-radius: 3px; + border-radius: 3px; + width: 2.6rem; + height: 2.6rem; + line-height: 2.6rem; + border: 1px solid transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +#slide-menu:disabled, +#slide-menu.is-disabled { + opacity: 0.3; + cursor: default; + pointer-events: none; +} +#slide-menu-button:active, +#slide-menu-button.is-active { + color: #454545; + text-shadow: 0 1px #fff; + background-color: #d3d7d7; + border: 1px solid #a5a8a8; + -webkit-box-shadow: inset 0 1px rgba(0,0,0,0.12); + box-shadow: inset 0 1px rgba(0,0,0,0.12); +} +#slide-menu-button span { + background-repeat: no-repeat; + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjMsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCIgWw0KCTwhRU5USVRZIG5zX2V4dGVuZCAiaHR0cDovL25zLmFkb2JlLmNvbS9FeHRlbnNpYmlsaXR5LzEuMC8iPg0KCTwhRU5USVRZIG5zX2FpICJodHRwOi8vbnMuYWRvYmUuY29tL0Fkb2JlSWxsdXN0cmF0b3IvMTAuMC8iPg0KCTwhRU5USVRZIG5zX2dyYXBocyAiaHR0cDovL25zLmFkb2JlLmNvbS9HcmFwaHMvMS4wLyI+DQoJPCFFTlRJVFkgbnNfdmFycyAiaHR0cDovL25zLmFkb2JlLmNvbS9WYXJpYWJsZXMvMS4wLyI+DQoJPCFFTlRJVFkgbnNfaW1yZXAgImh0dHA6Ly9ucy5hZG9iZS5jb20vSW1hZ2VSZXBsYWNlbWVudC8xLjAvIj4NCgk8IUVOVElUWSBuc19zZncgImh0dHA6Ly9ucy5hZG9iZS5jb20vU2F2ZUZvcldlYi8xLjAvIj4NCgk8IUVOVElUWSBuc19jdXN0b20gImh0dHA6Ly9ucy5hZG9iZS5jb20vR2VuZXJpY0N1c3RvbU5hbWVzcGFjZS8xLjAvIj4NCgk8IUVOVElUWSBuc19hZG9iZV94cGF0aCAiaHR0cDovL25zLmFkb2JlLmNvbS9YUGF0aC8xLjAvIj4NCl0+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zOng9IiZuc19leHRlbmQ7IiB4bWxuczppPSImbnNfYWk7IiB4bWxuczpncmFwaD0iJm5zX2dyYXBoczsiDQoJIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDBweCIgaGVpZ2h0PSI0MHB4Ig0KCSB2aWV3Qm94PSIwIDAgNDAgNDAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQwIDQwIiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxzd2l0Y2g+DQoJPGZvcmVpZ25PYmplY3QgcmVxdWlyZWRFeHRlbnNpb25zPSImbnNfYWk7IiB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIj4NCgkJPGk6cGdmUmVmICB4bGluazpocmVmPSIjYWRvYmVfaWxsdXN0cmF0b3JfcGdmIj4NCgkJPC9pOnBnZlJlZj4NCgk8L2ZvcmVpZ25PYmplY3Q+DQoJPGcgaTpleHRyYW5lb3VzPSJzZWxmIj4NCgkJPGcgb3BhY2l0eT0iMC43Ij4NCgkJCTxnIG9wYWNpdHk9IjAuNzUiPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkZGRkZGIiBkPSJNMzksMTF2LTFjMC0xLjQ3LTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MQ0KCQkJCQljMCwxLjU1LDAuNTIsMiwyLDJoMzRDMzguNSwxMywzOSwxMi41MiwzOSwxMXoiLz4NCgkJCTwvZz4NCgkJCTxnPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzksMTBWOWMwLTEuNDctMC40OC0yLTItMkgzQzEuNDcsNywxLDcuNTIsMSw5djFjMCwxLjU1LDAuNTIsMiwyLDJoMzQNCgkJCQkJQzM4LjUsMTIsMzksMTEuNTIsMzksMTB6Ii8+DQoJCQk8L2c+DQoJCTwvZz4NCgkJPGcgb3BhY2l0eT0iMC43Ij4NCgkJCTxnIG9wYWNpdHk9IjAuNzUiPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkZGRkZGIiBkPSJNMzksMjJ2LTFjMC0xLjQ3LTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MQ0KCQkJCQljMCwxLjU1LDAuNTIsMiwyLDJoMzRDMzguNSwyNCwzOSwyMy41MiwzOSwyMnoiLz4NCgkJCTwvZz4NCgkJCTxnPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzksMjF2LTFjMC0xLjQ3LTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MWMwLDEuNTUsMC41MiwyLDIsMmgzNA0KCQkJCQlDMzguNSwyMywzOSwyMi41MiwzOSwyMXoiLz4NCgkJCTwvZz4NCgkJPC9nPg0KCQk8ZyBvcGFjaXR5PSIwLjciPg0KCQkJPGcgb3BhY2l0eT0iMC43NSI+DQoJCQkJPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGw9IiNGRkZGRkYiIGQ9Ik0zOSwzM3YtMWMwLTEuNDcxLTAuNDgtMi0yLTJIM2MtMS41MywwLTIsMC41Mi0yLDJ2MQ0KCQkJCQljMCwxLjU1LDAuNTIsMiwyLDJoMzRDMzguNSwzNSwzOSwzNC41MiwzOSwzM3oiLz4NCgkJCTwvZz4NCgkJCTxnPg0KCQkJCTxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzksMzJ2LTFjMC0xLjQ3MS0wLjQ4LTItMi0ySDNjLTEuNTMsMC0yLDAuNTItMiwydjFjMCwxLjU1LDAuNTIsMiwyLDJoMzQNCgkJCQkJQzM4LjUsMzQsMzksMzMuNTIsMzksMzJ6Ii8+DQoJCQk8L2c+DQoJCTwvZz4NCgk8L2c+DQo8L3N3aXRjaD4NCjxpOnBnZiAgaWQ9ImFkb2JlX2lsbHVzdHJhdG9yX3BnZiI+DQoJPCFbQ0RBVEFbDQoJZUp6c3ZlbVNKTG1SSnZnRTlnNitQMXFFSEprS0dnQ0RBY1lkV1pId09IbzRRM2FYa094anBXV2tKSmtWVGVaMEhpVlpXZVJ5bjM3MQorMVFWZ0xsN1pFVWVSVksySzFDVkVhNE9nNW5oVU9qeHFlTHYvbzh2Zi9QRjlkZHZmdmZ3UmJxYUQ5UGYvZDNOMjRkbjc5NjgvZm1CCjFNTXZYcjc4N3R0M2IwSDZ5YTkvZWdqcjFTeVZybjlSdjdLSy8venc5dHNYYjE3L25GOWRKZm55SGxmLzVCZmZQdnZkdzh1WEQ0ZGYKUG52OTlicy9QSHY1OFBhbmg1LzhWTDcvN1l0M0x4K2t4aCtldmZyZGQyOS8vL0QyNnRzLy92Nm5mbXRwNi9iWk8vbCsrVm44V1VpSAorUE01SHI3OEZiNSs5dnFQejc3OTlzWC8rNENicFlwN0hkOTg5L3JyRjY5L2Yzenovd2p4OEVYS2g3UWR2aWp5MVg5LzhldUhiOS96Ci9lMmI1OSs5ZW5qOTdzdTNiNTQvZlB2dHpadVhiOTUrKy9QRHpaK2Z2VDc4NnRudjVadG5oLzliM3VETm53N0hsOCtlLzhja2I1Mi8KdW4veDhrRmU4Tld6ZDRjUTBSZlh2d2p4cStOM0wxNSsvUS9mdmZyZGc3ejZ1cEdjdm1LVC8vU3R0Q1hONG0rUXkxZS9lQ1dVM3p5OApleWZQSlRkRWYvNzY3NC9qWXdpUjVTZi85dXVIMzc5ZzkwdTMvSytmV3JOdjMzeno2dG5iLzhDMWh5K1crU0QvMlIxLysvRHFtNWZTCmUzemRPRi9sd3hmOHQvOXA5ZVF0V09lTHVGYnBsYkllMGx3UEtWZjl2dmZOd3g5ZlBQenA1NGQvZVBQNlFUdmcrdTI3MytnUUxNczgKNjcvNnphKy9rekgrcDljdjNzbURyU0J0MmdPL2V2UDF3MHVwMzY2L2YvbU1MODRTK3I5YTRiZlBaRTY4azdGNzgvSzdkNXhaMWU4ZwpQZnpMWjM5K3dEQUZ2Y0UvZnZQdytyZHYvcG5QK0VVTTBrN2NyclpEWE9TTlF0eVdRNmhzUCtKUnQ3bmRNL1IvdFdrMGhHYThmY3lRCkwyV2Mvdkh0aTkrL2VQM3pMMUtWdms1eDFpSDgrN2N2dnU0akdBN1YvcGZHcitydy8rYi82OVBLaTc5NzkvRGFubDdtemMydmhua3cKWC8zcU4zTFh1OWRmMzd4NWhkNy9GaE5jSnNCcm1Sc3YzL3hldjJ0Lzh4dTUvTHR2OUEzNCtTc1pxQy9mdm5pTk5xZC80RGYxcXk5ZgpmaWRmL2YzYk45OTk4NHZYLy81bStva3U3WDkrZUM3clY4Ynk2OE0vL3U1L3l3ZFpuNXliaDkrK2ZmWmNHcERQcmM3VnN4ZmYvUFM5Cnpjbkx2WDA0NkpkeUpULzY3KysvK3ZiaDMyVlY5Y3VWZXZmNmp3OHYzM3d6Tk5zb3dsVU8vL0xzN1RmZjMvU1hMNSs5ZnZiMlFIcHIKK1pjdi9pamZQSk9lNm0xMzJoTWFsVm55alhRT0wyR1ZreHU4cDhMdzFSTnU5T3pkSDRRQlBieisrdHZXdG43Y1A3alN2cis5M3p6SApISHg3T0w3OTd0cy9ISDc3NXMzTDF1eitxOWE2a1VsRi9iK05lM3pKQzE3LzQydnRvUE03V1lYVE93bi8rWnU3aTlSKy9BN3k1ZDl5CjZ6ZlBYcjU4OGZ1M3o3NzV3NHZubDI1dzRmdDJKLzN1UXliV24xLzk3czNMRjkrKzZ2TnBvSHo1N08yN0Y4OWZQdnptejkrK2UzajEKNU1FOTNIMzlRcGpjSTh2NHZYVis4NmRuNzU3LzRaY3ZmdmYyMmRzWEQrOWRmUmlBZjMveCttdVorNy81N3NXN2g5NUJiMTU5QXlubAo4SnMvUFB2bWdhL3g3Zy8zclBtYjFtRCtTbGoveU55LytPSTlYRCtzaCtQcjRmdS9mL3ZzNnhleW9ZalE5ZmR2WG43OThQcndhN0QzCmFmZEp0cTl5T0g0OS9kczBXd2tzeStIdnZqcStuZjdiTkovK2hKTVNoNUtzTEZZeS8vZXk0djlKZm8ybHRGTG5iVmV1aDNLVWNtUGwKZGloMzgvMDAzM3ZaUGRqNEU0ZVNockxzU3RZeThWY0pxNVRDMzNVbzI2NWNoMk1yTjYwY3c2MFUvM1E3eVljN2ttN0QvVmpHcnVQRAorVThheWpLVUhGZVVTWC9GTXBRYU55bjY3L1ZRamxxbS8rdlNXRDQybW1rM25zc3dxbjFzcFV4dGVKZGhrSFZVeDlHdFV2QWJvMXAzCjQ3c05JeXovVGpiVVB0akhOc3o2RzZOOE40NjIvS3MvODhXeGp0TnVvSk9NSzM1alpESEdLMHZsS0plVEViNjJzaDliR1V2OHVtTzUKUFJsRnYybmlHUFl4UTlGQjhpSGJiTEJrZ0NZYkk0elZqWlZibGpzcjl5aStzdkF5NDFnR2p0SmlIVi9ab1VjdWtudjJUZVRMcjN5OQpqYTl5eXljTzlvUXJwNHc4d3NUNzRqNHhwYlNrTlJWUnRyWjBsSEtiN21XMHc1S1daY2xMV2VxeUxkZkxjYmxkN3BaNzZjaVlVMTd5Cm1rdmU4blUrNXB0OGwrOG5lYUFnczNSWjg3cXVkZDNXNi9XNDNxeTM2NzNNaFNEZHNKUmMxbExMVm83bHB0eVdlNWtub2NhNjFGelgKV3VwV3IrdXgzdGE3ZWkvekpVNWIycFpOMnRucXRtM0g3V2E3Mis1bDBvVHJkTDFjNSt2MXVsNXYxOWZYUnlrMzE3ZlhkNXhKVVY1ZwpPZVpqT2RiakpsOGRqemZIdStPOXpLNHdzYmZUelhLVGIrUUJicmFiNjV2anpjM043YzI5VExiQVVWaHU4KzE2S3c5M1cyKzMyK1B0CnplM2Q3ZjNkTE9PUzdwYTc5YTdjMWJ2dFR1NTFkM04zTzkzZDNkMWpSdHhMaDkzbmUzblRlM24yKzJzcGNzdDd1ZkwrNUVmR2NwYlIKYkovdmhuSTdsSnVoSEhmbGVpaWJsMG4rcVVNcFExbDNKUTlsR1VvYWlrekE2VDYyTXJLd3puem44ZEh2eHAvYlhiblJNdkhYY1NqWApROWwycFE2bERHVWRTcDd1Y2l2THJxU2h4S0dFb2N4ajBTNmZyTy9IcHg5L2JvWnkxTUtWdVJ2SC9lanR4OHhIYXo5RSsyR1JvWmlHCjBkZ1B3YjdqOTkxdDNYelN0K3pQcVhYcHZpUDN2YmZ2c1pOKzJuZk5kTklqMmh2WFZqYVdhcVZZV1ZteWxZVWxXWWtUMTU1dG1jcjYKMi9UM045TjcrYytSNWRyS3hsS3R5TnFlNUovVlNyYXlzQ1FyeW5xZDBRc0g5Ykc4NC9nZE9WNlY0NU01SUJpRW1kMSt5MjYrWnE4Vwo5dVBDZmd2c3B6dDJ6SkVkVVNlK2VlYTc0Z1ZudnRBdFgrQ2FqMXo0aEF1ZlNKNURac3VkZE9hTjhLMXI0VjlWK05ncTNHd1JyaGFGCm04K1RUS1E3NmVVYllYclh3djdxZFJGR21JVWhKdGxSZ3V5dzl6TGl0OUlkeCsxYTJHYmRpakRRTEl3MHlSWVVaRCsrbDRsd0s5MTAKRkc2NzFUb0o0MTJGQVM4MUNTc09zbkhmeXd5NWxUNDhsbXRoMWJVVVlkcFptSGNTRmg1a283K1h1WE1ySFhzVUJyOEpveS9DN3JPdwovU1RNUDZ6ekpOUDRUc2I0UmphR2E5a2dxbXdUYTg2eVlTVFpPSUxJRHZjeTNXNWxMSTZ5cVd5eXVaUmxsVzFta2UwbXlxWXp5N3kvCmsxbHhJeHZSdFd4SWRaS2RhVTFaOXFna2UxVVFXZVZlWnVpdERCOTJVV3lyMkdpemJHN1lpRU9jQTdoc0UyaXRGdXA1TGRhVEJhV2IKT3VRMzdQd2JKUU9WRkVSMjRIeDQ1SFpzaGczNDVmMWlpQjJ4TTRiN2dkVXJTOWhrVW1XWlVFRW0wNldwRkcyUDRPNkRIOTJCQXRjbApkcUhNMWVzN2tlMUYySXBrdHhFaGdQZkdmdGMydTFWbVdiMnczYVcyM1dHenU4WU5lWEdUR0pMSm9NV2xCZ29OZHhRYmdna091WWtPCjEyTzNveGNncDgzMzJxUjhvREIzeTQ5WUxicFdmRU5zdXlpLzU1dnpyWFVZcmltVjNLWGR5RklrREUzb1VRbFBCUitWNUc0b2lOOUoKMDhHRWJIMGRsNXBOU3FaYXdhYThvZDRNRzJGdjZNVVhlMElmZVJ3b0hhU2RzRUJKSWNuSUY1a0JSODZGRStuQXV5TGJCdUFjWitRNQpmYXAwdmpOeUh2SWU3ZUlMN0dqUGpiNlBGMm5YbjZ6R1QxNk14eWIrZXVtS1ROMnBPTVhVSGkxNXB4bVp0alRaSC82akF2bE9SOTJyCllMN0hOQVd0U2Zvc3gybW4yTjFRZ25hbEFMKzNrMUpQU2xjaTlhOTFjald6bGVXc3BMTVNMeFQ3bVhhYTdwbENoeFUzQ21udDkrM0YKSW54aWFwcjJqU2xqUjlYT0xwYnQwVkpkNzVzR0pWL0wrc1RTVmNvOGxtbi9zUmtiK3QvbkpUMVNPQ21tT1Q2eFhPcmdDMlY2WXNVbgovMXpTM1QvcDU3TTE2UHRpYUQycU1xcUwyYmRXVk1KeW80UWJLYXJwd203RXNKVSttZHJzeTl2TkluMzZuNjVtbDFCOTlZNEw5cWpyCjJGWDY4OVZhbWdsZ3RaS2JnYURiaHRLNFFLZnZYNW55VnpOTGRQUFV5WEwwQlhrN0RVYXQwY2gxdkxnY2p6dlQyUG1DTkdQSzZmcXMKT3l0YnQ4NjRoZWJTRW0yZnA3T1ZlYm9JenhmbGU4dDBaakM4dEZMZnQzNVBsdWMwMkNBL2VRMi9ieDMvOVpmZFoyL3drb2c2YWovbgorby9LSStmNmowc2hNM1RvTzBvYm0ybCtxOGtic1drLzk0UEVVWFlTUnh3MG9CdlJnYWdCVGFJQ1FRbFNGUWhLMEV3TlNIV2dHeHAvClZBK3FUUTlLcGdkQkU3b1JMZWhJUGFqU2xMUk1WSVVDRjhjOXRlSmIzRUd1cjZJSnFTNEViU2lxTmtSOTZOYjBvU1Axb1VwOUNCb1IKT0ZlWVRDbTZwNFlMdFVnVkk2aEdsYW9SbEtPRnlsSGdVcnFuaG5SRERRazZFclNrSW5kRlZWR0VKbEdVRXRsaG9Hbm1qdXJTcmFoTApVSmlnTWtGcGd0cFVsa3pGQ2FwVElxZWFxVDdkbTJKOTFES0ozQWJKRGJKYm9meTJvbjdDVDZEODFMazRaRm9kaXk2bHFXUldxVUNoCkxGUGoxR2RTMXlCanVTVlZmNDhNZUJTUktBOU5neEMwWTZwbmpITW51ZXg0NUk0alRqdVpCT1dFdDExa2ErK1JJTTRsaHFleGlVZloKeCtkY3g2WXRhaG5OVk9QUDNpdzNtQnIzdGpEZlZ5ZjdJKzVLMnBXOTJTMmZsSFZYeXJRejVaV2RrYTlTVWRxWDY1TnlQQzFUczNsNQp1VDByNXovMzU4WG4yRFR1MVBmaFFva1hTN3BZekpKM1h2SWpaWDIwTkZ2dXREUHNGcHFiMzFlMjd5blgwODZjZkxrY24xakkzS2VkCjVmcDk1ZlpwWmJwQXZEU0lUeTdUbzE5OTVNLzVKdnF4RFpuaFptN3FaelNQaFpiRmlwb3ozYnhackxqMWM3Tml0dEhKVEtYKzQ3eWgKTHhzZkQrZXNyaUs3Sk85V1dyWFpMaE9OUmxyV1Z0ek1XMXZackZ5M2NyekFvK1JuT21OUWwxaFROOTFmNWtZREg1b2VZVUtQY1ovSAp1TTdBYVk2MDRUek9hOTdEWTNaTXhSakw5RjZlY29HVGZCOExtZDdQTjU3QU1rNVl3elJ5aVk5bURjTjZmNHd4UEpFTm5LLzh4OWZ4Cis4dGZhQjEva0ExMVowVVZrZTFHaloxMHdrTE9Tc3N5aWFTM0RyN1lvM0FDOWNmTzVwR0ZUemJUSzF0Rm9IVFA3QzE4czdLNXFITTIKVVJTRmc3Wk1sRS9kU3dzLzdSMDl0ZXFyVFpBdTZhL0ZEM3kyMXhTQTRiZkZBbExmTGJ5M0VDenB3WjNveEsyUXRPbklQUW8zdW0zdQozRm5FUDBpUzhPa3U4bmlRa0F2RjhrMUU5R3Y2ZDIrRVg5eVpsM2UrRHBQSThaSHlQTnk5Y1BpdTE0V1Mvalk0ZnVuNmxZTHBDRUV3CjBNQ1k2QWFHSXhnQ2VhRTd1RTdIalQ1aDlRcmZrQmRoYWQvVFB6dzNsdXZNMXRtc3M5Zk9WbzJqVG8yVmRoYnFyTE16emM0ck80L3MKdkhIa2lMZFQ0NE1qLyt0OGI4L3JSaFkzc3JXQm1VMERIOXV6cmhObWRVSHlPZWRIZzB4eldXNTVqTXVjaUIxam1kN0hOYjZYVFR4eApnLy9ZZFd5RzYzK2JSbEJ4T0VUNWF6M1UrV3FSNVhJbzZVb1dTRVRWMzB4Lzk5VlRxaDYvUFcveEtrdkZQQjlxdUJJOWNIMjB1ZE42CmFPc3FyR1ZiZ253Wm9OMUdSeW5uV3VNaWY1UWM3ZXNZOHJvZFVFRWJpVmRwemt1NzJTYzN4S2VaUlRQTnE5U2FaWkd2dUU2VWExRysKMmRhMjVIa2pkbHFZNHBMbGo0amZZV2dyWGMzQ1Z2cERmYWIyOU5uV1dSZ3Eyc3Boem9YWFZXSEUycGFvaUZYYmo4SlIwWmFNVzk1MgpiZVY1M29abit6enRmZndveG5KVlU5clFVczFsKzhTaFBHM3R3a3kxSjkrMksrSG5qMDNUZlNWcDVYamJJSTZPVkx3TVh2ekh0OC8vCjhPTHJuMDcrQjREOURiSjR0YTVCOWttTVk0cWxyQVF3eXVKaTkrSnJqUHh1MmRvVkI3OUM0eERzaW9OZFljdFVIbGlVOWVHVlB1SmkKN2JDblhvaHVXdGFybERDOVArTEcrK3MvcEp0Lzh4OS9sajdHdjNMaG9oMzgzM3ovdWJkZEo5cCtrODJmV1d4M3ViWU41WFowUE50bQpzUmdXU25ZRFNrS3lGd1REZVMwVUVZRDBPbEkwdUtkVlNFV0NsY0xBTmNXQU8rNFNBSHBoMzljOS81cld2dHRUWUtPQ0dOMGpwUFp0Ck5aTmpMNTROQUtvdVhVZHcwaXZjUUhINU1hemtwWi9IMGJDajhUcWJVWVpXUWtWT0VEdlIwQk9uaHNKaUtBckZVUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJR0pLQ3BzSTdBMVBjWkhYcnZoOGVNcUJEbm9RTkdYMnpUUkFLQmgwWXdRTWRQbkNqMHM0QUlWaWFkTE01ak9CV3h3bGlyQ0VKSWIxVwpSeEZTWmxVTVlhV2NDdmtVMG1tV2ZvQkllaU9UYmFZWW1nMHdlRnZVUDQ1dU5keEZSMTdzZ0J0bU81eWIxL09HMWtFMUJ4WXoreTNtCk1RaG1DSDh5WU9aSmFCa0ZCSFR6dHpyY28yS2JETk4wMjNCTTE0WmVjbk40TnBpU3dwTm1Da1YzT3kvNkFCUnRVRkUxbjZvL1BEV3QKSWxPeldLbGRGR29ZbGRiZ2Erb1pSeG9XYmllS2xmZFVPTHJLb2VoUGpKdnFIYXA1ZE4yRDJvZmhRUlVSQ3YwREdzZzZVUW1wVkVKYwpEYm5kcVNJbnlvanBJaGg2UjQxU0gzR05aRHBSU1RBbk5nT1MzbENxdm10dzBraUZ4RUdsbzBaeVE0M2tEZ0xwWkFwSkdoU1NZc3JJCmtjcklMWlVSQlp4MlBXUVo5QkRvSUUwTG1Xamo2R3JJdVNLU1RSR2hLdEwwa0NOMUVXb2l5b2NNY0dmNDV3R2tTRS9oK2Q5MzdlODkKMWF6bWs4R281WVA1SXUrNlY5TC9Hbjgza1BVSXFsZUR2RUdzUTdQUXA0YXc3Ny9UN3ZkaTdOZmgyTG5oN3RYNEwxeHgyaUh2SFg5Zgo3Ri8xR3VpLzZzenQvMTd2ZkF5M0J0VTIvRDJCUDNBVUQxanRqdFJPNXNKWURhdTltaTlhUFIwZFZFOC95RFRncy91UzYwc3RFUkJ6CnVzdzRZd2lja2RYLy9qMW05QkdjK2dzZTh5Nll0M0owTVlUbWxoZ2RGT2NPMFhPZjZ1SmVqbE5IN1BtbjhmZnAzeU10ZThSQUR3MVoKSHNWdVBJN3NTTHUvMHpSOFdFNWNOcU1qNTdMUHVuL2ZQTmpUbWE5SCs2NjdsSHV2OWg3dWc5QTlNRHRrNnZFQ01yVVlLTFhEVVIySQphaEJVNWZUYzRXV1BuOGdicnJuUjYxWmZhTXpJNUNmSnRuemQ5UGN1MGV2bUVpMWtWdVlXblNnRmROL29MUjlPdHozZCtIenJhNXRmCjIvNThBeVJtbEp1Z2JJT1Q3WVBqVGpqdWhTTjJkSThlM2VOSEc0SjBVc0hIUEtTbkdOTEhVS1R2d1pGT0EzVHRvOEJyUWJueU9WcDgKS044UEdPK1diN09GVHcwbmZZNlVMczJvdmtkTEQzaHBLd05jZWpwRFROL3VFTk9QejhwcS9vTjFQemVuQVMwOVlxWG5ObEh2emE2awpiNmJ0SDl1YzFWbTdjYS9qM0oxcytxN2NDdnNrVGdZSlZGNnVybHlmMEhmV1hUZURyMThudDVUSlpuaXhXYjVTV2FDSW9xeVhIRnczCkN2VUw2N1MvNDlUbjVGY014Q1VuM1dsSXhHbTU3QW1NcDhiOXM2Q0ppOEVUZXp6L1dTREZkQjVOY1FMM3Z4eFVjUjVZWVhFQTA4WG8KaW5MaXNWMVAvTG1QQjFtazZkRTRpL0NlbGZQWXVwR1ZNMTFjUE1mQm1kVFh6N2lHaHBXMHM5NWRiU0prcGt6RkdlSTdyQjdDS0NwMAo2amtJczhxMGpZZ1dYVmVvMTNtTElaZWRHVU5xZHhQZjUycVBWcCs2cmx1Z2RyK0pJRnpOa0NJZm02VkdMVnpkWnJSZWlmeFUrOU44CmRBdThmMW1Tc0Q3WXBsSVIxbS9YaGxCRTdzY2I0aSs4YWwyRVp3NHZrVmU1TkhSRDVTYzNwRGF3T3FmRWZzeHBxelQ2eVQ1YlUwKzcKVUhBOWpHdmF1OWJNZHBYelBCcFJQcjJsRHpLbmZQZnExY05iV0ZUMER4ckJ6R28xU0g0dWtJMVMxUmhHV1Jwa3o3Rit4eFlFZStlaQp1NEtBSWRHNmVKMmJERjJhcE53akdUMFVkUlNGZTlncDFiMXBpRnFzRGFYWkEwb1YwYW40enNkMXpreXRrNEx3TkVqQ3FuSnVnMFI4CnRLM3N6alZQMFQySlhqSUFLTnVoOW9rTm5YcmlSTUJUSWZ4SkZWRlhSbysrUHhwdmNnK0ZDbnZSY05lbURHZHJOZWVKMmlxaFhMUkQKVkZOWnRkZ3U1Y0ZEdVczR3piUHNJS0tHSVowYVdEMjFrbHZwUDZXVjJzcDFLOGRlcHZWbUtOM2J2bmU1akRET3NDdHBLT3k3cVN5dAo1RjA1LzZrblpidFFycWR5ZlZadUhpbTM3eW5OYlRSZDlsbFR1Zi9Rd29rODFmZzV5bmtNYm8vQ0xTME85OWhYYWRqSGsxUXV5bU9QCkpzWlNuRXdkM2NXa2NKbmREL3BsZHcxdkZnZHpPMWhxRmw4ZnNNOU10aVp1NkIyY1c3QnV0bkRkU25QYnRVM25POXBpTUlFVHpZN1oKNWlZc01VZk94RnZNUUhjTFI4Nmo3aEsrcGt2WXhvOVl5VUJ0SU5FKzVyYVhTbU12YkM4UU9HaDNtYzN1a21sMVVSZncxaHpBdDJiOQpCUU9NRk9LNjFRWGkzdGJzTHZUOVR0L2ovdTBPNEcyd3Vkd3dLaGdHenp2REVUYmY3M1RpL0YwcEczZUVqVHVCVmVMdFVKb09vZW5nCkdZN1ZkT0lFWG5kUW1lME1LTE56Q0EvSW1JYUpVVzFrRDRKeHNld1U2M0tPY1RuSDA5MU1GMUF0RjlFc285eDZqbXJwWmJvZ0dWOUUKeUQwQklMZGNSdEk5aHFKN2I2R21Ic2FZWFkvVzlTaGRqOC90c2JuK0RGM3FONUYrRU5vcG91K2piM3NjczB2V1hZcnVnYlpOUUI0RQo0bHNGUmUwRGE3dVlleDVPMjFYREU3VncxQWVuQytyZ1pSUEZtU3A0b2dlYUpqaGRVQVgzeXVCZUhkd3JoTlZNb2FWdGRubHFhbUZYCkRWMDVqQzN0eGp5b2lQZURvbmpYRklNV0ZUejVqYS83ejlaS2JhWHZYWDBienEwc3ZVeW1WM2J0TWc0NlpoaDF6VUhqN0dYVXhEaWUKMDZERDNPeks4YXhjbjVSTFAzVWlPOTJYaXpzM1RUMlBseVlHVGYzUGs3SjhjT0VPTm0zcGM1UVBqOVorZjd3MlF5U25reGpKODVqdApmYVRrUG01N2pOdzI1OXpVREhhanNlN09wbWszMU8zTWRPcXJhOTQ2OTlkZCsvZ1dHeC90MEhnU3kzRFRQRlhiU1VSRDZyWTZzOWJkCmxkdUpLLzdJNmIrWkE2dFFPSFhYcFJydXV2Tnk3Nzdza1E2RnNtMmVMTnhCdlpoeEYvSndSMzYxRDN6WUtKU1VadURMSnA2M0dJZ0oKMWo3YSsrNXRrN3VsM2UvR09NVVlFcUZCRVNvT2VXaUVCa2VvV2tFM3hOU2lKTzVOLzFEdXFVenVTR3ZodFZrTVBYQmlESjFZVFpNdwpKU1dsaWJxUGg2U0dDN0Z4ajBYSGVaekZQaUoybTB6OTJnWUI5TEdnMkY2V1N3R3lIaVo3L25NZXgvWlkrTlFGSVB4MFJycjdtUEkrCmhCWEJLSFVIaXJqOHZRRXU4bHhGdVNQbVJnVGF6UUFUR2JhSDBLMFF6ZVp3Z3ZQNGlLcy94RHJ3VDY5ZlAzdjE4UFhoOTBZNmhKOU8KbDRnZDYzSWg0MDl1dXNhUTlTYzhIcmV1NGUvM0hyMCtHUXoxRklLNkQrTGZnMC9WQjZ6KzMrc2Q1bFRVaXFrQlRyZTllNnViT0pZegpKY2tmM0lQdSsrT2Z2c0J4MGpjd284VlRzeEc4QjBrNzlmZDUrZ01mN1lGN2pvQ3h0M2Y5UFZtSGg5M2pqcHJkWThrVExnTi8wOVM3CnZ5Y08ra0VTbEh5bTlDVFg5MU5QVC9LRFpsVDU4WUgxZ1FjYmQxcEtucEdJTmhhMU9rTVhMelREWHFuaDZjSWZGeG5pWjJoS3VLT20KM3lXbE5iMmpmUm9IbmVlTFBGVEkwblRlY2RGbzREQ3M1eHZDR3hLeEJ4dlhMVGhNSWhaZ282WHpUaGFvbWwwcWw2UkNtRFFWMnZYVQpFRXlSN0svUVZuZzdKRDl6QkpNRDZudnFzMkl3ZW9Mb0hhMHlOYmpLSHFwaVFKVWRjRDZieldRUG5COHRKM2ZiL2RUTUp3cGNpYWF2CkxHWkljU2o5YWtxUHEwRmR0L0FmVTU4bXM3VW8xdjdXZ0M1ajZRRWh1NUQxbml0eFg2YW0xZldTTHBibGtaTDNaVG9ockU4cTVmRXkKUGZwVi9iZ3lmVURsQzhyZmVabWVWdTNwNWNjR0wxUm9Vb0pMWVd2aklpcDdSVW9DWlpkck1SSmRWTGpwcXpHM0MxazFYVStheTZqSgpWOWpleCt5S2lRYmIxZUJ6RnNQVFFITWRNTmRDZDZhR2xmUEluWDNjVG1NNUFNbWRSZTRvVUc1dHhscmhQNVBOeEJ0enFONVpFTWRzCmNUekIxQk9IenVVV3orUEZiUS82Y3owWlovRis3WFlPdDM1MHcwaVBFdW1HbEhCYXBqRi8wTTRxazNiYzdyemtzMEplT0EyMm45TnkKd2NmeFNPazJwVHFOSDU1VXppdzgreko5WDRVUExVOXQ4TWsvMDlPci9xZHA4REVPQXAzaXp1RHBtVnJFdGZxR1dxNngxWlFHVDlJSwovbUVxMmdTaGhCN1QyREswUWplN2I3anF2TXZPcXE0ZWg5eU9icDZMSE1SNWlFTnRMMFQvWGVRaXprY0tzZ29xTTduZWNSSTFpSi95CmtzNVBvcGxjT2xmSlpvOHMwOEJZL0tmUDBUMWYyU0ZEVGdFd3ptR21NeWJ6R0xPSmo1UVRqak05a1FGOUh6dHFaWHJmbHg5UjNzdmoKUHFyODJPQmZvTUVQaVU1NThzLzdHdHpqaHRPWldhVHM3RGhtdzVtYVZXU1hPWEVNczZIZFJzMGdMaFc1ZTNzMTB4TUJJU29ZVFJaNwpVTGxPWUhlNmI5TFJRbHZ4Nk1xK3AzU1VMSUtra0dsQXhpZGFRckVRRTUzWGluUUFLNEhkVzEya3dBb2t1cTJ6Z1IzQVp0UWpCdGVwCnNxclVmTlpaZWRGa2JPakdRcGJnVzUzTmJhM0ZGN21QcGZNcmQwdDFNQnVWcDRrYVZOZVRSa1ZvMUc3MkNzbXAwRHI4S0lMNDlrSTUKejZhaW51RDV2U1ZPTi9ISlpYbEttWjVXN1daOWFwbWVYdlUvVFlOdTFybzlTejU3bERsYjdySXNPbVJqdmJYRVhTc1RkczFNMVhXawpqV3FsZlNwWWFxNmp6REs2dG1DVWdra0s5aWc0cytESVVpZVdnc3h2bVg1TG9lWFo4MjdSVTlYU0Q5ZmkwVlJUQTVFL0pmWHdhZkxoCmxuNjRZOGNuOHpLNWg4bTlTOGtnNUtFNWxXNEhJUG4xa0YycnU1SG9RcHJNZytUdW83M3J5QjFIM1duVVhVYWp3eWgxYjlFME9vdDIKanFKVE45R3BrK2dSLzlCMDRpQjZ6RDIwY3c2OXp6TTBQZVlZdXVRVWVvSWZpTEU1VHkwM1R5blQwNm85WW9tNlVLYW5WLzFQMCtDUApIT1JIRHZJakIvbmJYWjkvK3czK3lFRis1Q0EvY3BDLzNmWDV0OTlnOTNWZlBMbnU2VVM0eWt0Y2F0am91bDYyd29RcVdlWVlLS1ZrCmRYMkhHZEZURi83Z24rc0ZyL2xuYmRVYzZNZ3NFOUloaDZ0WmVOam9Sai81eHV2TFBlV0xOVndoYnYrUWxxczE5UHhPNzZteHY3NUkKcXptdU9GTTR4YTFjdVA2MFJydStsQXMrLzVIOGlXNy9lTm50SCtIMlQrNzJiOW5FN2s2Z3liY25FT1ZIQzNlczY5dXpjdk5oUlpzNQpoU0hqNTMwK2x6UHZrRVloZDZESmJIRHgyNFlUUHo5NnFaN0gyYmd4Y1R4R3JneWdzdkhreGZIVXhaUHlOOWRNVDJKejB6TDdkVHVYCnpRVWRpdjM0N01aV0sxeENRaGdXd3ZPNnRPTnk3SlNhZGk2UHAvRG9TV2Zxa0c3R2s4MThhb1dSa2FXMUtxY3BLZU1ZYk9FOTg4SmMKYVhVSmlYblI1cnhzYzd6d3gyWHN6K2RyVXFOTDh4d0RXeE5aU1p1Rml4eFF5em1zaTZFNkRjK1poSWZXaXV2NzQzemM5WHJ2ei9JcQpuNzF2UHBFRlhtU0E4Y094bzNlR1o3eHc0bEhEalJxTWNYTFk1ZmZoSnNzWmJ2SVMyUE1FcmFwN1AwN2JmRS9ybDkvaU1vaDA5ejZUCnY5TEhRQ2kvRjk0blBOWGpCVDUzVEFMdk1IbEV3dnRhL3dCNDRyNzlGdkd3NXlwMWdPbnRlTVBwRno4NHlpOWRtdXRwTjljTlp4WlAKTXI2T1NaWjBTN2hyYVY1N2t0YzhISSttR2M2T0U3TmtNNlJ2Q09mcnFWelhsc0wxMnVMMGRON1NQYVh4eHBFcVhxYTZWd3pLczlGWgpkYlJnNGp0enlYZFlUeHJpaE9IQXF0T3F3Y0F3NFNQbTk4N2llNVBoQ1RNZFdXTWNwbWRJd3l4djJWMU84N3VNR1Y0aW5lOHpYZktlCjVXWE04eklFa0V5UFJaQzBzekU4Z0tSNkFNbm5ndE5lWG0xUGg5T2V6TzBQelpXd1h3QWZjelgzSXJsdW5wSDlJSVdRbU5CUnJ4UnUKdGRaMXpKazUzTzVETHZxMGRWWXZMclM2U3c3Wk1xQjVEclF4RzdQRFJVMnE0dUNmWlg1MitHb0hjalFJcTE1dzExQ3Y4d0FONlpmNgp4ZkxEQzNaNUJHL01FNXk0Z0k3bSswMjJVdlFPajV4RGVUbDcwRi9pZ2k2Nm9oL0cyTWpUYkRtWDh1V0VDL2x5TEZmTzFBTE1YS1B3CkVFY1BhOVFkYTFmbEF4THFXRURqN1k3VENLK1o3TGdkanpMMFdMWFlZOVgwdnYwZStlS2Q0bnRTOTdTN2RjNDJuY1RGUlp0QWMyTncKT2o2MEpFWmhEWGM4WkdqajZVTHBHS1FQYjVrM2M1V25pSEpQbkI2MDBXeVlwSWs3Sm4vTXdnSm4yZ2MzbVZSWkpsZVllUFRQVVdaYwpFZmFkWkduZU04cnRta2Y2WURMb0FaR1hKYXNubks3NS9jRWhsaFArTkNQODhwL3d2bTA1RGFrY1cxNzVob3QzL05aajdHelAwQWg0Cm4zWnBCanEyZllTdmorRDBFV1BlY04zSzVOSU9kSHNoWC81NytPWXA1MFFXcTQ3OUg0RC9sNkgvYTN2VnNvT2RLZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJVUhISW5abDNHUno2OHozR29FOVpkTVA5NmhDTVdMd091K3Z3dXZNUWhRN05aU2JaUElLRVRuTEtFaDMweUU2UXovWUNRSC91Sm1KKwpNckUrTjhUNEpPSjZBT2U1STRSbklXQUhJQjFnY2hKeE54dmhOSURKQU4raVR6YWVmZnhwUngvclVhdlRwNXkxNmljUy8vaGtIL1ZrCmc1aTR5dFNQVlBERHZGSEJYK2Q1Z2NSM0pjc2paUVpIYVI2cjh6OTZucThxa3R1UXkvOHpONnVDNVRKSDVnVFBhd2pNUUNiZEoxMUwKcWJHbzhTUWgxWHU4OEVkcmNvMVhtNmpRdzVOKzFtYlZIUE5wOW5Gdk1seGg4LzFzWnZlVFpyVlBaeVFleFRzTFYrR0w1VENuamFNegpyMVZmbnNuOUwveHhVWkQvVEExK2twQy9YSkx4bDUzZG5HbVRrTDJuV3BMMmV5Wm9kK2FJOU96M2xwZ0g3Rm1USU9zZWVXZWJZaklsCkhOdmVOcG4rZmR2MDczRGpCNU12N1hnVnp5L2VEbFlaejFVWkRxV1NoVHp0VDZNNk9ZaHFmd2pWaUFQZkgwQTFIRVUxcGhwOC81bDUKVHl2MzA0Y2RhZlQ5NWEvZm9OcmxOQlh2UHY0Sk5qZFkydlNjZEpYeVhNSTd0a1JXaVZuaENwTWkzOWdHem1oczNjRWh6MW5TcXBaUApmTEhzYkc0NHVlRXVjVzlJMzBpVHlkTFNxUkh2T3pWemlhWkFtaTF0VmFUQkJJNXdUN3hXTGNkWmoxanFnTnJCWFhLU2pPejByRy9tCnU3cGM4c1d5VEhXNVdOYVBMZFBIWC9xWkd0U3AwYk91ZVNvNlQ3V3Y1MjE2WXNOaS8yOEQzVk0xdzhDYlBNdHpwTHRqVE1vOC9vdmYKWTVMcmVVaDNQUUxabjRSMy82aWZIeHQ4d2dWMkNNWXNxL0ZHQkhtY2hvdHpjR2VlZm52a3FiY1E5Q0tGUEloNEVQQWczaTA4em5ibQpRYmFRN0VhNWpvaVZ4OFM2UWJCcm90MnRJUyt1TFl1OG56M3J4MFdrYVRqRTIxUGo5NHo2NHltejQ0bmIyOW1VYnhraDkrZlZ2LzlVCitpY2RXdjE5eDh2LzhHUDUyUnRVVTh5Tm5RT2RhWklad1YzVjBoNW8wb09XOGVEOWg1cE03UUNQZFc5MDJsbTRqME9DSkxkd2U1S2sKMGNnZDZqeVpwZnZlOHVuZG1yMzd4bXpleHhiNzZSdEpUNWpaZjRhTW45TkozczNscktSSFNyeGNwa2UrQ0I5YnBvKy85RE0xcUZpSAo3aE1ZdlFMdUZ3aG5DQWpIUDR3SGovZmNlQ0kzeGwxYXZKNGsvU2taOGZZNThaajV5ME5YVWl0ajlNc2UrWFVTU0hQeHNNeTc2YkdvCm5EUHN5dFBLemZUOUlKY1BLMy85QmtjRDMxOWRLdjRoR255dmJqRTk4c1hsUXdmT3M2ZVBXZFNwRlUwWGp5Qll6N0pMN2pOTWhyT0YKNU12b09Oa2EybXp0ck9hTlczYkhHZGtCRnhkUzNJUVRiczhrLzJEM2lSYjVld1B6cWswK3lXNStMNDk5SkNkZmhYZkhxdnZLWDEwcQovcFFHTDZzSXl5TTZoV2tjMDVrS2NxYXNuR1JVSG1GaFhmdHBHdEhVMGtENzNxVlpwSFYzVVhsSGM4M2VHQmo2U0Myc1dDTEFoYUplCnBLQUZoTUx0UktudnhwTCtGUU5DTThXZlpmYURpVStCenpEd3didzNFOTE4STFxanluOXExVlBoN3pnMXVZOFNuOGw1a084ZzFVR00KZy9CMlRWMERjbGo2aTBmUy90amcyYzllUDdOQTQ2bDk4TE4zNG9uQ3QxY0VIUlNVMmxFK2UwMXptd1pWczU2b21tV25wRm94VmVVVApPK2JzNXkvUzRQdFZnOGVPSzdReVhUd1M2dlJNcDFHZGFWck9XUzlTSzVvTXVUa2VYbkF6NERidkcyQXJ0R1I2eVE0Rlc0ZVVlcFlEClVKUHF1UmR4OUNPK3o1TjRudEN3cHpQa1FRSmI4eHJ0ODNqZE1OTk9wR1VKU2ZsNURxR2VZdm5YbG9vL3BjRkhkSWRIaW1rYzA1a0sKY3E2czdKV1pRYys1ZEpEQTFNOE5zSEswckNMOWVJQzdJYi9JM0hLTXZDZkx5R1BlMDlGMzZtZU5iK1l4N1FmN1JUdGNYQS8wdTU1MgpwdXhvaHV4S3Y5OE43ZGVCbnI4c0R3eDd0VUpLL3VwUzhRL1I0SHQxaSttUkx4NVhZTzR1NlR4ZEk1cUdMUHk5akFwVlY3TThKMERYCnhWWnpJNVNlcG44eUphNGYxMzQwUmU4OFkvOTRZbnNIK2EzbVNqRG53ZVJZdjdQemNmVWs5blYzTnU3TjNlMEo2cXdJUndJK1ROZ1cKVHU1dHVERjM4VUhEejlsY1BhVmU0YURmUTFtdVFpNkRVKzdUbXFGcks4OXhJNDU2RG5IbGNUekNNMFBXM0k1TDJtSWdtaG40NnRHWApGOUpoS1ZmQ2x2dkRmSEpMZXZyUkI3MVNMWWU0WEpYZGMzeDBDNS9rVE11WG5HbDVoMHk5aUhzNTNhK2VuQXgyV1U0Uk1LY1ltRENjCnc0cjhUME9XV3o4bzBrOGc4bi83QVlmNzR5RzdpSlZPUDA4NzBXQTgyZkZVU0lEQUpjSldPN2ZYTVp3ZkR1RTBkZkVrSCtwMDNCOTUKM0pPcFAyWWZKQ0oxUEwvaGZqaG83ZndBaDIwNEpHMS9oTVBTam5DSTA2T25PSFFOL0hvd1QwSFlEUHU4clpFbmlNMnhsdUtuWnEyegpMS0RJdUFJZUdCOGV6ZFQ2NFJmck9WdXlKT2gybGpteHhHSlhWbzlaMkJUSGVobVcraEhYZnRwYXV3Z0R6ei9pd0gvRWdmK0lBLytzCk9QQjF1N1RTaEhvV1hSU2VFRjMwZUc1NjArZytzMG1tN1RSUG5HMVBTT0h0azdjZkYzUnI1Nno2a1VIOTBLRGFEZzFhaDhPTCtvR2gKT0JucGhQZC9NQ2ZkemNLUHVsclBTemc3UzJFMzRSNzcvcFBtVnJrb01wWDh2c2kxUjZPKzNuUHl3UTUzZkRta3JNc3U2NldwT3pUdgpGb3E4QzFoN05FNnROMWhQWXRST1R3NDRlOXJMNFdtUFQ5N0htZVZ1Q2ovT2ZaL0tmOSt6S3A3RzBwK1VKLy8weE5ZZ214SzFDNW16CkVOWkJtZGR0c3lsdWJMYk45ZE16UlUvV3lTZTM5YmtqM2Y3bER5L2VQZnpYdy9IbHMrZi9JY3RpOS9FdmNRckl1ZG5zSTg4Qm1jNFMKem5xNmFrODNPNmFhdlczSENlNXpWWHVPMlJ1Z3J1NHN2V3djOE9oN3JQemo2ZkhINVBqSGpvLy9GUGovelpEeG52ai82ZU1EQUt5MApGSkNlcVBIVTdISmlOZmtoejFjNXM2eCs5QWtyazZxcGo4d1V6OTJaN1NoS25TdzlQN0dMd0QxSHNZaStHME1BWFBpOXN3TlBuNURuCi9DUS9zVmtOMzJjeGZGcTh4ZmxoQ3g4YmNiRlBMZEFQV3poTklYRjdJVW5CazZiQ1I1eGNNMyt1czJ1bUN4TmhGNnBELzk4NEVjWXoKU1gwYURNbXEzemNWdmk5aDlUNWR0Wm1ScC9wcEFTNm5rK0oyK3ZnUWwyR0tEQk5sZXVSWWpuMDZpczhuUFpzTS9aZHI4SkpuNnRMQgoyR1hQM2FZTHpPMkNmbkV4OC9BKzc3QUZGRTJmR0ZGVU5LYW9oeFJOSHg5VFpKNkZveG9mYUhaSXQ4c2thMk9mZHVUdVF1S1JIK3JvCm9vOHgxVjA4dkdqNkVHTmR3L0k1a3M4VHQ5MzIxRzJUbVNXWXZhMGxiN3Q5VXZxMmZmSTJpMGFhUGkwY1NhTjZEYlhLZUtUcDR3T1MKaUZnRm5tRTFwQ3BBcXJLYzdrL1N3NVFMR1dSK25Bby9Ub1VmcDhLUFUrR3h0RkVma0ZUcExEL1VoMS83UTVtY2hQRFZQN3g1L2VYYgpGNi9mdlhqOSt5KytHSFR0OFl2cEg3N0JOMG0vK2ZMWnUzY1BiMStMRW43OThzL2ZmdnRNMUcvNzQ3QnRWOXVhRm5oT2wzVk5oN2dzClY3S055eDlodlpLNXRQSkpyL252di81SmZuM0hQOTNuK0s5LzVzZi9JWC8rYnlIK1NWNys4S3ZEdi8yditmQzFYdkpyK2VYMzhDWVAKcjRSNGRxUERMMGVxUDg4dmgrc3YwWFpYdjViL2YzYjk5dDN0aStmdlhyeDUvZXp0bnc4L3A4bmlaOGMzYjE3SzIvL0NldUtydTY5Zgp2SHZ6OXF2anMrZi9JYjMxMVc5ZnZIejQ2dGNQejkvOTlQQmY1WUwvVS82M1YvMHYzN0dCVzc3TlAzSTZSQndWcURiSUVETW54aUlUCm9sclNQenRBdGZwWmdjdFc1N1FkL3ZVWkc5cDFYQXJoYWs2cmpIdTlTaUxaYThmSXEwVVJ1QTU1dTFwRnBEcklpcitTcHZJaEZ4elcKS3U5Y3BYcU42WkR6VlpDMWRYaU95MnEra3NWYkR6bGVyUWdCRmNuL2FwRlZkVmkyS3hINmNYYnNlaFZrQVI2V2RDVnJMZHBsMjlVcwpYT0dRNU12Q3hvdmVMZGFySEdIUXIvTlYzamFab3VVcXdmakt5OHB5SlNxSTFGb1JtQ3QzVytVdTg3SWVVdFJuQWlIbHVoMlN2SVpJCnQzcVpFRU9vNVNERFhJT00vVnF1SUcvQ1A3NGhTbFMwSUJuT1hFQ0lxZHFycmZNVmxKTERzbDdoN0o5RGxLNEpzaFlQUzdoS290OGMKV28yVXJ4YS9LRnlKb0xxMng0NXJScTQwVFptRzVHVHJlcldFYlRtRUxFTXFnNkJYclZkYlNPc0JOd2gxNHdOSmk5SldYWEFlYms1WAp4Z1NFeWZoRjhqYnNzaS9DbGJBb2RIV3FWM091NGJCSUh3cjdFNEk4QmVaRElEdkplcDMwT1NDZWgxRHNOUlpoS1J1ZVdVWWNuU3VmCkY0VERZcnczRzdDRW1TLzlLYS9LMFVRclhCWnl6N3pLZTZaRngydkpWL0trTmw0cFhNbmZNb2RXNmRjZzd5V1hWMUVuRHVzaTQ1YmwKbGt1VW0waTdxOXhNaGxZdmt5a1hwT01PWlVXMGRtVW5DbmRlY0puc1NFS1FSWmx5a0haV21XV2h0RWtscTJSRlc0ajZQYVJaWG1pVApjYStMakxNTWsweDh6bUNaa3NMdmRjVGtzYTdXV2ZwY1ppQ2NUREtWY0RONXN5cFhaNWxUU1dZYnAzU0pPdXQ0bVF5d0tEYVJrZGRGCk9pQ2g5K1JlOHV4elR2Rnd0c3B3MWI5elFkOXl5Q3RUMmFFKzE4bXJrU2dUQy9rSU9WczJCRjNMdE1JYlJIYkEzRDdyNUpISGtxMjYKMTVHVkkwcmQwSWdSL0ZZK3U1VW9jM2RiVWN1YWtibkdGMnYzY2tLYnFYaWdYc3ZmbzdWejhtTCszaW1nSTJSWVNwSTFML1BxMVk2NAo2THhLTWl0bFA5NUFrTzFWT0lTdzJpeWoyQWc2YURMTGdxeU1YbXZSdS9aMm5HQjMwOHVjR0s5RVk1VkJhKzJFcTBWR2Y3aWJFZlF5CmY2Wld5NSs2dFhQeWJ2N1MvK1dmNUo5L2V2SUc4WXR2di9yVk05bFRiOTU4OCtldjN2dzdONHkvZi92bXUyOTBoN2g4eGE4ZnZubDQKOXU3aDY2L2tGcnVkWkR2ODVLZUhmLzJYQzN1S1RJeTh6c1FVQ1YvWjZQR2NTNUdld1c0aXJLakVQTzRtUmMvbDF0MWtxVmRseTdJeApZc0VzT25NN0Via0o0Q3FWQ1NKNnYweGxtU2hWZUt6MHN0WkFRbHdSOXRoRlFkaEtCRkVtaTE0bXF4RlJCNGVTdGZGRzJLd0dMM05pCm1EZTdMbUtYbHAwNWhOVW93dnZXdUEwVVhybllEdDdyeWNUVmVuUFZCMnVVcmVvbXp3dWRLRXlHODd5OWNRWEQydzVuM2JKZjcyRkIKZndnVHFWRzZWYmpLcXgxUjVBOXdyQ0RzY0JHaDF6bFd3RllqbzJJZjlRMlF2M2p0VmRDRlNYYWwxa1lqMkoxYVI1TVlaREFyN3VUTgp6THBNMjYzbXZtejc0N1JLL3NDdG1aUFgyazM4M1pSTGFhNExrR3F6N0E5MERzMjVoTlV5SGMvTTZWblZ6eTUvYkl2czJEcmhvdXlkCjdORzh3QUdibFZWaTVRSjBsNE9JRmNKdjR5emY1aXdNR1ZNSzIvVXNlNDNzQjNqV09SaXZuSVU3cjdLU3VWV0FXd1ZoMzlqc3RrVzIKMWlxYm42emtUVGFmd3lhN2dFZ1NlaGwyQUhtNVRaaURNUDREOXpYWmZUWVJla1M3a00vQ0I0S0lNYktIYkZ1MDdVaUlKVmZkUjRUcgpIQ0prRzlHWTBKc2l6SUVnMWF1SUc4STE1clRZWlVKYzVJME9zdWZCOXNtYnJWVkVCOWxFNndLSjZMUS9UbllXTEE3c3JYTGZQTXY5ClgrMkllRi9zeFBLZWVVbWNScGcxVVhoY1FKZmI1K2ZleDZYR1hrZjJlT1FvNlkwNHdXNmxWemxSUmxpMHYwTnJwcUJybDdYZnl3bDYKbVQxUXIrV1AzTm81ZWJIZFhBdUg2MjgrbWJVRlNJK3laVUx3a0wxZkYya2paaGtsR1Z4NThxdFFaYTdJc0ZYTVlQQVNVVlJySXlpUApFc2xZNXNCUVMzcHhGY21vdCtNRXU1dGU1c1J5QlFYODBOc1JrVG5MOFBlN0dVRXY4MmRxdGZ5cFd6c243OVo2VDNVcjl0NG5yOVVnClV5VkQzc1dVRWE3SURvU09nRTEzbGJFUmVUTUlLeGZobFk4V1NzUktGVFlqUTRTbHUyRmg2SHlRU1FaR0s0dzNZNWFMNUhzVnNaNWsKK3ErekxJeFE0VUplWXlPd0l5RHJ6MnV2Skt1R2ZEc2w1L2RHRUkxbDRPNUdGT0ZsWFdYMUJ3aVc1T2FMWFNiU1VDM1lGSVR0T25zUAowQnVLek5sQVhzUFdSWW9xM0hXeUNyU2RFbVg2TG41bG80cEVEQ01JZDUwTjR3S1dDbmZJQWExdklsWjJDcStVSFhhck12eTluanhqCnljdkNMWS9xeTBBUmpXRUwyYTUwS2htSWFGL29yTVRueDVyTkFUckJDaTgrbmovb0lQRktXWEdKYzFqMnlCWHlqUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJak8xVldyRGJ5R3ljWlorUVVmVjlOSlRlUTNHV01STEd5dWxIaFV3K3lBVTFzRjdCcXA2dEorYXRiNXdjZll4am1JRytBcGg0aGxKUQpPQUJsa1hVZFpIdEcyQnk0Y0oyRExSLzVzS3p5Z0tLOUpqQi8yYVNrdTRUamI3UGUvM1NHbm16VDBCMDRTUU51VTB5NjZWU0loL0xXCkt6aFlVVjVBMWgyRVhTTUhTNmY0QkZuQTRZZDZVVjUvRFVOVGpXQjMxQXNiVlRvaUNUOFltaElwZEpWbE05elNLSHBsZTdSV3J6MTkKYSt2MExiMFhSRFBWM3NHTW5uTlVLUjFqV3pPWWlGTkZEeGJCZXdaRnhuL0xPMHBSTFV2SG8xR3hzbW8rREczSmVnZ1lrWDVQbytpVgo2U29LS3gvcnlTNEwrTlhRVnFQczd0bW83ZGxhVyszNVQ5K3o5WUNzRXZhTktMTFVURi90aUVEVVo2eXdwTDI4VkZYQ2crZ0dDYlBRCkNjNk1rSFdtMTFxckRtdHJweEhzYnM5dHVpa3h5UlNCbU52YWlmWkM3VzVHMFBYdHo5UnErVk43TzZmdjlyaTA5aW5tSnVpSXM1QkgKK3hMWUd4UXROeTlCSGNpQVdMcDVLU3dpZ1ltV3RUTXZRU2lWdlc5cjVpVlZHSVFMdUhrSkl1bzhMOHZPdklTMk5naHNibDRDcitUZAozTHdVYUw0UVBqR2FsOGd0d2ZQY3ZDUnZmZ1h6ZFRNdmdSRGozcm9VNHFKU25GbVh3RjFsZXcvTnVrVFdKMHJIenJwRXZpbkNZN011ClljT1FUbHVhZGFuVjZOWWxzTXhscWYycFF4UlJhS3RyTXkrRktITi8yeG1YUUNwVk9MUWJsNW9rNE9ZbHJMQ2E2cll6TDRIeDVpUjgKdXBtWFpCRnRFVlkwc3k1aFVjbnVzVE11eWRMTE0zck9iRXV5L0dYZVJqY3R5Y2UwMENqWVRVdmdCd2tIcEpobFNacElhZDNjc0NSOApXd2FxN094S0ltWXpNNTZibFRaS3lLVlpsV1Jud0p3ZGJVcmtmVnNKemFhRXJvTVE2U1lsdWZjVlhBQTdrMUtRdTNKSnVVa3B5SFROCkFDSzc5aVhjbHJOMk5Da0ZLSytsVzVTd2ZjNTFYWnBGS2RTb3MzaTBLR0dub2xqckZpVzVyMnpLOHNodVVqcGJXQ2Q3RitOdHdySXoKS1RXaVc0TXdIV29XR2RqTVJTRXk5V0FlVFVyWXJTS0VPNjhUWUxTRXVjMGJjY0pvNU9sRU13VzFadHhZMU80MW1wVGFBL1ZhL2g3ZQp6dW1MamJ4YTVLRmxaMUxxUkRNRmdTK21MVGRia2NpY0NKdmFkaFlsY0ZTRSt3eTFacjFwYjhZSmc0Mm5FODBTMU5zeFcxRy8yMkJSCmFvL1VLdmt6dDJaTzN1eHYzYUQwOGRxOUxQQll5WVhNT1BkcXBNcFNwb0d1dVJGazR3YW9WQWhCcHd2WVVNNW1PWVpLc1VScTVtbWIKNFQyUWpoWkpFWmZsWk9aSmJzVlNRN1lOZHhDWS9SL0duU3lNcEpueFJjWGdXaFIySWs4ZFF5T29CUjRDZXVtVllGa3ZJc0xYYW40RgpKMnlidHQvczd5QmlOY3dySGxJMk0rRTRHMVVFQ2lNd3hzWjFJT2pMVmRFMnVJUzlXdXU3WUNicTg5NDhNUTZVV2UyYjJBUkVDRkk3ClZLY0tVeFFaZmxFckxqMEhNWnB6QUh4eHphRlR0T2ZnaEVqcldDK3FwMkJveXlsK1R6ZGJHN1dZUzY2MUJkMkpvOWZ1NlJTOTBwK3QKMWV0djVXMmR2ZWNQSXVvMEl6L2szSFhkbHIwdkRTb0tPWGR6cHFHZWFQT2xlOU1nbSthOHVsL00zR215VTRzSWlDdmRueWJhdmV6RAo5TERaU3NDMkl2SjkzbnZVS09NbDNxRzQwTG5xM0cwK05XZ09JaGI1bWpHbkdsVGN0V0FTdVZjTjNJM1AxdHhxMkpPNmhjdjlhdGk2CkFxWjA4NnlKdkNDRG4zSjNyY0VLSUpQZGg5QThaOURHUkJ3czNia202MEJ1empYb2RXQkJXVXk0Ynl1enZZTjcyS2d5eWExR0YxdFMKMTg3T3gwYkpNeSt4T2RuZzJscmt6czNMRmloNkxIc3ZHNVZycUNITnl3YlJVM2FqT0xqWkZuU0lTUUhkenliN21MNlJPOW9DOWxFWgpyZVpxbzdraEIzZlFtYThOTDY0K0ZYZTJRVDNmSXVhM3U5dlFnZlBpN00vOWJWUnZOcnlqTzl6aW5DQmVidDNqSmt4VUpCL2JrSnJMCkxkSkZVa1AzdWZGS3ZHOXp1c0d5Mm1hUE85M1FYQzF4N1Y0MzJDbXBwRFMvbTJ4dElxaVpnYWM1M21LRVJpZzdaUE84UlhER1FLZWEKODdVdzY5emMrZDVnRXFLWTZjNDNLSmVMOVBmaGZHRSs0bjdEOTF4V3IvYlVLaHR6M0xvRERvWU12a3h6aXpYS3pnazMxRE1IMjlCVwpvOWc5ZDQ0NE1JS2E2ZnkxdHFESTBzRGI3dGtvTzEvY1VLODlmMnZyOUQzUDNIRlJ1aXBMcCszOWNUREFjTzQxNTFjTXN0R1cwRjFrClR0ZzU1SG90MjMrR2hockZicmh6eVdHRU00VGszaFRVa2hDSEd4cGg1NVBydGRxVHQ0Wk8zL0QvdDBKVVNFSE5sU0hCS0dqVEdic2gKOVRwOExkb2hkdFlaUmpxbzM5S24wR1JwYnlaRnVCOHBybWlxZzIxRnZBNGxFV0hvQzJ3dXdpbDBMc3F0MU9EbkZOV1lrbnIwZWoyNAozQ2pHZzZQa0RRelJlRmJJWUwxK3BXZzFkcVZzU0x5blhEa25tRzFnSk1WK2RQYWFKeHBRZ2o0RkcxbWUrM1k4VUlOdU5tZ0hGbWxZClliZEE1ZzRmQTh5VVRsSE5SQlpQbXRlaG5uQ2VDald2TjlVcGMyYzBuU3F2b050M2Eyc1JkaERETXR6VEtjOXRKUGxvdlpvL2ZXdnEKN0MwZmwyMCtoNThYL2h2T2daMmpGM1pjSFYvMzlNS01QOE9EMDF5OVFRUWgyQXIydmw1YWlubWx1M0hCTkhTV05Vckt3NXhxMU1YbgpsTHQ3WTNiTzZPN2VSdG01ZTNzOTkrTkdyb0EwVWxMcGs2cFRNWlI1ZFBCaUY1dXpqZEcraHg3eCtVYUl3c2pwLzJwUGhROGdydDNyCjIzWk1kOFkyd3M3ejI2dTVWN2MzMVNsMnk1MzNseHNyRmZqV0Z1UmpXdGI4bGs3WU9ZQ0hhdTNwVzFPbmIva0QrSURCcjRRdjFMMlcKMktpdUpUWnJvR3VKbUJZMHFveGFJcmlIaVBxeGFZbFFxRUlWSnVoYUlpd090QmVPV21LejQ3bVcyTXh4cmdEQ0RGM1dXSFphSW5TLwplVkFsWVNKYlpESzdrdWlmUngzUmFVMUZoSmw2aFgrdjZYNzArS1Z0M2V1SXNHS1ZCYy9XNnJXZWN4M3h2QzlQN1VpcldpeDJPbUtuCnVsNUhzd3htVmRQOThNZWFjdG5yaUxUNnBDVU85VUpWbTE5dnExRkdmVzJnbWw3WDIzTGRyOTl6MUJIN3MvVjY3YTFhVzZmdmVkbWgKL0NtbThDVWJMQVdHWnpoOVgrMnB4WlNlWlhFbjRhb2FCRmJWREptbFVkd2VUZ3ZuVUE4N09seHp2YTFHc1hzNjh6RHFabGFFMXBacwpSTUxGMXVHZVRuRmp1cmtxVzczMi9LMnQwL2Y4UWJ6TEVldVU3bG5aQ0NqZVUyb1h0V0VyaEJoRkZSeGlvaVc3ME15ZmtDb0pYTHdVCkd2NEIzZGdjMXlHVGc3NG9HTlJqVUxhcElvZDBzR2hKa1dDRkxVWjlXZHJtSE9RUTRYekVacXkyR01JZXNPQ2djbUVxUURMVkxvZkcKMkd4TndLbHNVUkU0OHJLSnV2NmFpbDVadG5XaGQ1V0dYdlNyZEpiTmFhajRDVzhsKzc3cTNmQjBWVkxnaUlZT3Z4VzFHMEtJRXYzUQp0RHRSNFdUVENIUitLNEIycHZ6SHpVOEJ1Q0ttdzl3T0tTeTRnaEhBVm1HdkZxV2JMNENkcDlMbHVHSVJWY1Y5cmh0VTJES3JmcXhhCnN6UnJHbXlBd2hjelR5YUhaNHNXY05qVFJPcE1ORHFrNUpwdnB1MS80V05WSGNsRk1RSVVDbFdIUEowREo1cGRYQlUvZ2l1V3NoaTgKdVZQZGJJQlpRME92OUVrQnNKN2FxYnJpamFKekpDa2VaNmdubTJLb2VXeXJVZXllZW1XakpvTy85cmFpYnBYRFBXUGZQSWRuYS9YYQo4N2UyVHQvekI1RUNZM1pBd0Z5NkZOaW84S3BUR1Y2Q3dlTjhDV0tZU01oWGN6UVhCeVpVWFdGbmhTMWxVUnk5eW9Telh3ZDFrZjVBClVkcWFOQVpoczFEN2dDaW81Z2JYUHFDR3VHNGNYVG5vRWlCOEw1aW92VjdaSENxNDZSMDRLeFc2c0kwU1lEbWhnaE5xWDhpc1ZIbTEKVVdUWk5BbXdVMHR5R1pPK00vaWRrVnNtY3RvckRyR09Jbkl4R0FxTWZmcXdxeitzL0tHM3JMTzlwbE9jTjVRZFZlMkYyQ0ZnTHd5MAp3SGxiMjZBOWdmdndZU0crNjJ0dU5paUFYT2lnekI0RElHd2orVDA1ditlbHFqMUlybEsrcXlKK3RQVUxOcHBpcG9tUUJrMi9VdGxJCkVjMGNGclE1V25lczJhMHIyYlhCMlBWUzJxd1dDQVR3OE5MRUhseHJCRHVsUVFES3JzNkQ4V0VYUXdOU2g2UTFyczNzYUZQMGZLNmYKc0JaTVNRRFo4REkwbmIzYVUyVnJxWXVhUE5hbDZsZ3RzRGxpYzlDdWQ0b3VCK25vQXQ3WjZ4WDFwUTV0TlVvYXpIV2RtbkhVVlRnTQpiY0VxQkl4OHY2ZFI5TXIyYksxZWUvN1cxdWw3Tm9lYlRGdDZ0ekRmdVZXOTJsTTNOV01DckVLM0dPd0htWjZNRldoSTRsMk1va2lICm9OaWRvWjZzMTVoM2JUV0szZE92TkdveEMxZHJDLzVTbURyN1BaMmlWL3F6OVhydCtWdGJwKy9aZWtBR1pzdllja1g1SXl6eDFZNksKcmJuUVhEKzd2UVFqeWIyd0VnSFJDTDdpWjdyL2U3VUZ5ZWJTMEZTaitDMzF5a2FGK0VPZm9iY0ZLRVVKL1k3MldSbUZQNWRYNmkvawo3Wnk5b3I4ODdLMlZxQytndXBNNVhBZnFBdWxYb1hvaVRLcWpnWkkxektLeHB0SXB5bnRnMG9DSjNLa0VkZkd4dksyQll2ZlVLeHMxCm1tRFgyNElmQUs2SGZrK2pQTGVudFdkcjlkcnpXMXZuNzlsNklNRzlHeFhQSklxTCtjOGFGZlkxQ09IZ2hETm1uaXczaW1vQS82WjUKQzUzeTNNUVN1dmlIZW9CQndEdlltbW9VdjZXTENFWTFxMFZ2UzFnbjBKVDlsa1pRRjRFOW1GZnFMK1R0bkwzaUQ2RFBOd3d6ZGdwNgp2SGFnYm14VkszT0pPcW9iVzlDYTRTaHlXRGRNRXFtNi9kMkIzUkQwMWF2Z3lHN2dzRFBzYkEzYUhVVVV5RnNOYlFnQUZZS2tDZG5JCnNkM29LSFZvT3JnYk5WTjJINDJCdTJrR1dkYWxvN3NwNUFCMjB1RGQ0S2RwTzRGMzQ4MElXR3I0YnRqRjdFYW5uWE82RHhrUUduOVEKLzlwQnZLSERKRlZkREZMTm5Sclkwb2E4YnBUbjN1M2c5ME05dzNBUGJUbkY3K2xxa0ZHcjltSnJTdTVFSDJpL3BWTmNFdFJINi9YYQpTM2xUcDI5NVdUMy9ISGh2ZXIyaW96MDdWVkVhRFZ5Tk9TV1RaK3NZN0VaUmM0VkJ0WWQ2aHVidVRUV0MzVkV2YkZUWnhWZkNhbHRUCnhlekEvWlpsTUJmM1IydjEydE8zdGs3ZnNuRXptRzdoN0lQYUxwekNzQmVOS2dKVW5nTWlBa1hJS21ycEMrWkRuR2NQL3dpMnNjSm0KVzVaMUhlcWwyWUNhcmFWRzhUczZVMUlxVEd4QWVmVzJNS0dXYmJ5blUxU3MweWRydGRxenQ1Yk8zdkVITVUwMFdESFdFS0hVSS9TZApzaGhOaG81OXgwTEppVjR1QTc5RHgra2hrSTUrcHljUExLREIzeUhuYkNYR2puOXZGQlZ2RkFEZnF6bTJIY0syMmNDZHNvVlIzekVxCmVTbms0UWFDcDlDbzZvaWg0TUZDbTJ6ZFlQQndscXNLNGZCMjlENGx5RTVaWVdEd0t4dFZwSms1MHFkaE1IamdlK2ltYnpENFJsSHgKeDJEd3ZaN0QyMk14cEVHbnVObkJCU2VqaGl1Q2doMEZIK25tQVVUQVVmQkE1cXp0WVIwRkR6ZUUyc2tjQlEvM1FpcHI3aWg0NkJKZAorWEFVUE56c2hFODBGRHgxamhSVHg4R2o5YVo4TkJ3OFVBZTB0emdNSGlOQXZ0cHc4TmhJa0RqSEJDUUR3a01SWCtzQWhNZEd4V2M0Cm43SW5kbUJIaVdNUUE0SXBYdTJwb29MaDZPS0dPT2M3YndNVzNnaytTWWhmNzdVTTRqNDAxQ2gyUTcyd1VWMnhhMDBCT0JWSDlIMmoKNkpYK1lMMWVlL2pXMXVsTE5rbmZJZUtBZVMzQkF4MGR2dDZvRGVLTzJVOW55VURKUThoSHA4SndCY2RmYnd1Q05tRS83WjVHMFNzTgp2ajdVTTRqNzBGYWo3TzdacU8zWldsdnQrVS9mcy9XQXc4VXhkOHJpMXV0T0ZSWkdJSXdEejBXQXZab0pyM1o4ZXFNNGF5S012ZGR6CnBIdHZxMVBzbnMrbkFSRlAzWVNHbE43V2JHL1c3MmtVWGUzdDJWcTk5dnplMXRsN1BpN3hmZzVjL0E0czVzRDRoaFZyeVBpR0ZXdlEKK0IxV3JHSGpHMWFzZ2VNYlZxejV3M1pZc1FhUGIxaXhobzl2V0xFR2tOOWh4UnBDdm1IRkdrUytZY1VjSTcrRGlqV1FmSU9LTlpoOApnNG8xLzlvT0t0Wmc4QTBxMXBEeURTclc2NHhRc2VhZWE2L1E0UElOSzlidzhnTlNyQUhtRzFLc0krWWRLOVlnOHlOV3JFSG1HMWJNCklmTU5LdFl3OHlOU3JJSG1IU2ptcVBtR0UzUGMvQTRuNXNENUJoTno1SHhEaVRsMmZnY1NjL0I4dzRnNWVyNUJ4QT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJREQ2L0E0ZzEvSHdEaURtQXZ1SERHb0oreEljMUJIM0RoelVJZlhkak80aCtodzl6RkgyRGh6VVlmWU9ITlJ6OURoN1dnUFFOSHRhUQo5QTBmZHI0V1QzMmdCam5mNGNNR3FtRzZHbmk5NGI0YXhuMkhEMnRRK0Y3UDBmSzlyVTRac0ZvRDFUQmRyYTJHKzJyMzNPSEQyck1OCjlkcnplMXRuN3preWYzcVNkdml3Z1dxd0xvZXlPL0NyNGQxSGVGaER4ZmRhaHBzZjJtbVVBYTAxVUEzVjFac3k0RmUvNFFBUGEwL1YKS3JYbmJ1MmN2dDhsOWJKN0VtRnVFeFpoOXA1R2hTV2hxSlNWeVZBS29qZk0rbElEVjZOUlZQMTNMdC9yQ1pkS1N4amJhaFM3WnpNYwpLRlZXRkZqNTBKWnQrY005QnlGZ2VEYXYxNS9mMnpwN3o3WWVQa1hCUGtuWlJLMHVMV3FjS1ZqeHIvYlVvRkUyc01VVUlDWXhXSE5TCllaZTdmYU80RWNhVXFWWXZHTkNsTjlVb2Rzdm5ackF6YXRKZzFhR3RqTDA5ai9jMGlsN3BqOWFxdGFkdlRaMitaZS9MajljdjRRbWMKaStvY0lqT2FOTnFwc0cweGVRV1E1dGloQVRDbjRKOW5VeVdkb3BxWEorcG85UmhTbDllaHJVNnhleXBIZCtvMksvUzN0eVdVc29IUgp0SHM2UmUvcHo5YnIrZlAzdGs3ZnN6R2twWnFrZ1kwSEMrWFZub3JlTmZUWmxyT2xEZ0dDT2VnNVNGdW42SHNBRDFQaldFOTJHaHBNCmUxdU5ZdmYwUGExUjYwb0luN2NGQzFvZDdxaWY5U3AvTHE4enZJKzFjdnFHbjJVUmh0TkZLQktZK3RDU2dvdGU3YWtBUlVIZGh0MlUKbnRNbFdPS0poSEF3V0NxZDB0YlNHdU5ZVHg0Z09pQkQyMm9VdTZlYmZScFZrMlMxcGhiR3Z3eDNWSUl2ZTNzd3J6VzhrYlp6K29xOQpJejlCZ0QvaFpxcStNUXJUUWhkZjdhbUFuQ1dOYjlaWWRCbldBbTgrbFhNSzRFNVJaVzFXQ0VhclZoMy8ycHJxRkx1bE8zK05LbnBWCm9KempUY0hNYWlLQTNkRW96MDNGdFNkcjlkclR0NlpPMy9JSG1aU3drTUJQTEtJL3NqS2FZOG1KaSs1UzhQSFVMWVVEbElpcU9oTTUKclgzV2R4SlpyOGo5V3AxVlhUaTlFU2ZZclZ3NVY2SXM1SVZPY0crbWFMaEV2MWNaSXJYYkF4VVBxdkJIdG5iT1hxeTdVcVBxd0JzQwpXdHlQMklqU1cvT3F6czhVNVRFMlROaWtEbFdxc1U1UXhycXBBdHRxQVk1UVZRUFFkaHJCN3FhWE9SR1RBeXlwdFlQMXMyM0QzWXpnCnJsZDlwbGJMbjlyYk9YMjNIMkw1Y1p1RnlBSjFnMTZqVjNzcTVMdlZRbVVpSEVGUVZPYW8wb1JtUm5PSzg3RTFwVFRXdzl0dmVXeXIKVWV5ZXpzZU1XaFRTUGJSVlRhem85Nnc5c2Nid2JLMWVlLzdXMXVsN2ZnNXg0cVF2WTFZak5PVnRHRWRmN2Fnd3RzQWpEQVZ0aWJPYQp6U2hmUnpldkdFRUZUcmpRbG0yb05hdTNiR2pJS1g1RHZiQlJJOS9rMEp1aUhTZlY0WTVPMFN2OXdYcTk5a3F0cmRPWC9DRmtYRERPCjFSTEdCTWVJZEdJMFVBT2N0VVFMdG5nMm9GRFcxQW1xd3FVclpPa2ZxMkdOTWF0SGE2cFI3STZ1L0JrVnJoRmlIRnRiU0Y0YTZuQkwKSStpRjdjbGFOWC80MXRMSkszNytDVWtiekd6eDFMSkFISVBjcURBMlpaVzNwQTIxQjJyd0hqeVdXMW83UmQrSytYTzNzZDVNODhYUQpsQlBzam43ZDdCTnlKZ3JVR3hLS2FORExjRU9uZVAvcmcvVjY3ZUZiVzZjditYbTJWaUI3a29hK01pengxWTVZUFNuQmF1WkR4dm9zCmFzOUZzdjVPVWVGaThVeDhyWjVJV1VncU5MVFZLSFpMdDhNb1ZmcU11ZFI2VzNIV3dKOStUNmM4dDRmVlordjE3UEY3VXljdjZWMzMKMmNLNkhnL1grbHcrUTBBamsxbDhHNW9ad0s4RnE4N0J6UEtpY3dIT3g3SE1BR1Zsc0xvUnlsd1JlMUZ6UnpJWEdyaFNCeklYakViYQp3NWhsN29zUUVEdUtHZWtiS3h3TURtSmVrWU9CcU9ZQnc0eXdyUlhENHhCbUdFcm5VanVDR1U2SVV0SWV3QXl6OCt6SUp1YmpKVVF4CmRmaHlKZ0I5RDE2V204MGNhY2N1TXp3eXJoMjd2QUl3UU4yM1k1Y0xBVnhMaHk2WFRkWXRzY3lHWEthSVRPUGdBRnlHQ1hjcnk5cVIKeTRHUVF6cFV6WWxJcE15NmJYdnNNdEF5RWJab2h5NURGbHRTQnk2ZmpmYmU0bGhoZEFZYkdtSExuV2dXYk9SZDVDZzZHQmtoM2FtRQpQV2E1d0Erd2JwMVk1TmtxRkZadnB4TUc4SEFuR3NhNHQyTXc1SDYzQWEzY244bHJ0YWUyZHM3ZTdYSC95aWVoT2VJZXBReUNBNVFoCnpqZHdjczA3V0hKaHJFaHFxR1RoejhpQzB6REp6Q01UOTRoaytEK0M1ZGtqSUJtaWN3Y1pZMmFqaVJHS0xPdDNnOTI3RVJOU3hBMzQKWWdRZG5XQ1EwMGlaTy9CNDNpT081dzQxQmc2NFlzY3lwSEdFL25HQ000WUMzVEhHMFI3RGtjTkltclN1ZTN6eHdpeDFuWWFFNmRHdwpwUVFYTDliSUNDMDJkQU0vWiszVEJpa0daSUJaT3djM09lWmZ5VXZIRTFkN0VrY1RZeDdOS2V6QnhLWGF3allzTWZwbFJCSXozK3k2Cnh4RUxDOGtobEE0amhqRjRYVHVJdUJZYnYrSHhBZ1BiNGJweUNERm5uS09IZDlOdnY3YkJjaFp6ZmpYY2NDY2ExSmM1aG9BUmNqUXcKbVBFcFpoaHpjNmtEc1FBSEgwSnZwaE1HOEc0bkdzYTN0Mk13NEhhekFTemNuOGlJL1ptdG1iTTM4eGVIQlMzbnZBY0tkNkpqZTJtWgpIdEMvQU9LWEU0eXdDSnNsYkNORVdIYlJkV3lsRVhZQVlTYzZwdGZiYWJCZnU5a09IR3dQNUxUK3hOYksyWHY1Q3lkRy9BNGczVmNqCjBiRzhXRnRrR3c3M1RjamFXOVk5S2hoV3IxQ0hTdGloNktiMFpwd3dJblE3MFlDODNvd2hmZHV0Qmpod2V4NnYwOTdDMnpoOUxYOWYKNUdJSzg3YUhBbmVpb1hmUmoyR0UvV2JHSGc2SVgyN3h3UHBUWC9SYWNFMVNxL1IyR21FQTVIYWk0WFo3T3didDdYY2JFTUQ5bWJ4VwplMnB2NS9UZC9LVmg1c25NOXptZ2Z4dlJFYnV5T0xiRVBEWUc2b1hwcWRCelBXQi9oWmt0c1F4RXVEZDVpbmhyeHdrakVMY1REYS9iCjJqRkViN3ZaZ1BwdFQrUjEybnQ0STZjdmRza1pCcWQzWk9ENUNCZnNWQWY1SWE0MExCNGFEQ0NnN0w0NHIydVBGNFRmT1pUWWlSWHAKbGJjQmQ5Z0lJM1N2RVIzaDE5cHhFR0M3MjRnVTdBL2wxUDdnM3RMNUMzNTJyZUtqazBVODhnVEw0V2UvZVAzdXdpRWorUFhzZHk4Zgo5RUYrK2ViNVYvL3o0Yy9hZHA0UFAvdjF3N05MUjVQY3ZuajExWmNQYjU4L3ZINDMxSC9zSGwrK2ZmamppNGMvZmZYck4zLzYxbDR2Cndac2t1dTFqTitDWkovLzk0Y1h2Ly9EdTBRN3hxbSsrK1VvNjh2N3RtOWZmVy9lWEQvLys3c21WOFpMU0t5OGV2djJBZDd4NTg5TGYKVWNPNzF2ZS80Nys4K1ByZEh5Nk81WjJla1hQMyttdTc3dUtaT2YvanhSOGZmanJwTCtwWHE4N1BsVEhmVURLMnFxanBXRU9hTHA2WApvd2pwRHpzMngyN2xEVGVNMHU1MlBQZW1VZHRqL2JKZmY0bTJ1L292Y1dvT1RjbXlJOHc0ZGpndU9HVUtta1VOY2RZemlhT2ZTYnpzCmtxbGt6ZFdMVklDTFp3RUhFZUlsc25jamxTVUlBUUVKY0tHck9nNEwvMXlWNEJpa2hmaHMwR0tsSlhXMnRpdHlWS2s5Q2tkYmdkZEIKcGJtWjFNQWVxZHdGUUJJWHVoY1RzamdWWkdHQVVpL2Jjb0g1SElMdzRyWXFwTUFBbEF6RXpZNUFJQ1JMQ01haGhZQWRUd2hFQ3JYTApBSHhFcHJHY0ZiMVVlQUJLTW0wUFFnQ1F5U1NrMk41TTA3d25XSzREUmFRUTRERkJSbFB1blRRZndpa2dleXBmVFBiakxVY2lsVGErClBXQ1kwSjQycGtaTlNtREdOeWhmaXdNZ1IrcXlCcjB3TFp0U01zY2pCOHVSTmRQZzFxL01sWHRTbE02aER1ckNPK3BsQzhqU2pOSm8KZlZsdDVKQWZIRkVIT1BNcGE1Z3dqVjNJTmJGcURpOHEvOGh4c2phaEUvRVFWQVNRMVduVkJLR3NGdVlrMG1wV1ZQVUt4QzhzQ3lVNQprSDlkN2ZRSmhycXV3YXlyVEdFd3cvR21ZZGg2bGdid0RzSFRicTRPZ0E2dW5hL29DcWJXZzN1bExrWlpsQUl2Uzd0eW9TMDA0RkN4CnhZelB6QlNNL0ZrODFCNzNaR1FXS05HTkhaQ1VWdGVKbzQwMkE5QkpLQ3JMemV5S3dQTVhITThUVEVhUVd5NDBCcFZWVlM1MHh4S3AKeUsyVy8ydzJXeGpuRGhDTUplbjRwbG8xbzF4ZE1LUXp6RVVLSzAzSmp2TGdZS3N4RWI2NVJlT25Tb1FVeE1Tc20wbzdoY3V5MnRJaApaZldIQlZUT3JzdXNvMWthMFhyT0NtNWxQQVVvbEVuMEtoaUNZRUxDaUZkRE9Hb3l3aG51T0xpenEybTBHeXpwVXZmR0wxeEVLOTJZCktGNFJlbWxHbnBJTmpuVUZqeEUxaUNqL1pmV0FOc2o5U0hFQ3d4YVJkck9HMUFCd1hLTTZKWm44aExoQ2d4V1F5T1M1Z0JSR2JSdlQKa29BNGpkaWJvZUx4OCtJdWF2aUFnV09Vc1Nyb1NuajRrSWR1WTlwVVRWT29pVHZ4aFkwZHN3MGtwQkNHUGNwRGxMQzRLck56V0xCSwpLcFZLc1Bja2lVaGJCUU5mWkVqUXFtSVpMRExNSXh5Z3BraUhnckNHSHM1RUhBS0lTTElubnd1ODUyaUd3RU1RbHFSWmZaMVRhSEJNCkptZE9jektJUGhLelZXWVZEblFKVjdQa2dRUG9teVZDRUtEK3pveFhxMW9IVm9scUFMUWxiVkN2UXpJWEMybEFrWlpaRnhrSU5HTEQKdkxJQmpENzdVVlpDV0wwN1pvVFV5N2NnSnJ0TWRJRmx1S3hxaGc1ditMbDF2bXpWdEFnSERDUkdkczB5VVdEZUsxa0JDclRzbDAyVgpQWDJ6b0hjcmlGaUpodXFFcmdCblJad1YwWmxnZlFNY2YvYjhqQ0RTbWdHZ0g4NGdtMjN2RW9Md1REWDVzQjBRaHF1WXZYS0ZsMVF0ClFGUkRVQ2RWaS9xck9HNEx1NDIvR0x6TWtYMnJRTmd0Z2FGdVBHbGkwZkJsT3VIaGNGa2RoRlJ3N2dOdUJUZ09RL0ZocXlzOENhdFoKaUFQU0M4SlEyeGdYaUZIbTRySnFYOU9PSFBWNE9OSFJpMEduTnhKd2NHWmo2d1ZyRVVUYVZ0ZFY4MG5pc2hLTXdMdXRnRXZIeGw4MwpwTENVM3l1Vk9SaXB6Wklyb29vNllXS0JwU3JUa0VZR2doRkdzdUNLclhkVHY2MXM5eHpZVEIvQ3V1cThLZ3c2eXJZckY1czE0WXBKCmgyREh0ZVdoVytZaTAzTUxIRUx1MHJyL2J6QVlaUjBpeS9QRzhFV01ZU0U4QjViN2xXTVdRdW9DRWF6dm9JR0Q4Zk9zSXkyclQwRlEKekdzaGhGUWNrdDJhUWk3MHF2anBLdXVObVVyMWtUZlIrZkFLb3RzdCtsN1Nvem8vbUNtNDBMcTNJR0VpWEhMWUVDRENWYVo4WHRlVwpBMTYyTFRoYVlSU2UxYVBCWEZFRjdHSFZKQzA3NlhCdjZxTUVBTVJUZ0tYYmo0OVlORFl2RW1uS25UMXVBQTBIWktQWHdHbHVHWkg1Cm9HT1RKVFFrV0hnbHVEWUpnTVVqYVJLRkpSQVlFeHZBbFQxVUFpbytUWExZREt0NktXWWVMb1VVNWJySmg1bmF1QktlbXpDZnNNQmEKTGFUY1o1TE5ESjViTlVFZ2pLNUpYanpZbHNVMWcyaXRUUmMzd2QwTWg4VldZNEg5QkxkRktFMk82Vjh0a3hBeXFabllNVmZHUHJYUApnY0Y3aTVxblhGclJTRkhJUlVWcmFXd3F6MmhSdVNjdWpHMFJucHNkZExocUFpZ0UvWWFzdWhORlJ6cXY0dkFaWndPRTNDUlZTRm9MCnBNdW81ajZjTTR2TS95SzRhbFRhd25QL3pLeWdqNWhvZ29hbExVZXpWaUVWS2dpMFdVQk13bGpncXRsVDB5UEFEU2RVTWRlTkdibDQKWHVFQ3pxblpGTWo4MHFMN29MNVhWYjh5WmpuTldSbHhYWW5aNFkyelJIV2VZaDNYMGlXM2pkdXNlbVR3RVNPQlBLRTBsNjRRZXlzMwpTM29yL0NJKzlycjVlMFFlZW9iUGVWVmNRMFpPTFJEbUpuc1huVkxJeDB1K2duRVNNUVpwK210U3ZxSkhCVmExVHQrWXhCN1FaNWxLCmtPSlhaMGhQMENMSnhCYUQ3Qyt5V2tTRHM4dG1qZFNqWXBBTVRJbUZpOUN3T0d0V1gxMzlRZTJnejkxZWdhZ0VFQXR0VDFWRGQwSEkKbVBZSlRrcnNscGl6S2JUTFpvQlRzZlhRYmdZQ1lPV0tWOWU0a0FCeHRjejZic3JHZ3ZYMnFqckVzbWlpWlRoVTY2cm52N0dMc1BpMgo1SHpNd1ByY0hDT2RRTVVlVWZSTnkxYVhjZnFnRVhndldjZ2JRazViTGNTWFluOGk5d0dEb0swUHZwbEJMT1FwUE1KSVpXaTRPTUFPCnNKMHYyYlk5NW9TS1BPMGl1V1FDWW9GUEdjU0VaR3VJZ2VlYVFseGtVQUpqN3hHSFZ1YlNMbU5LdkdXeGtRVUIxZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJSS9aTDBDUjNqRGNGb1hvd1FWQ1pLek4zY3FZQmxUb0ZHUVJkM0ZGUHZnRXZoaExHWGhUWkVaN0ZqRk9HWm0yNkFNbTlVTnRWbTU5TQpQdDNRRzF1TWxmY0NqVXNST1JXd1BFQ29ub2t5ckhtL2ZZT0ljUVlNZUU3WmFnVVNSSWpRM0d3SURNYm42cjJJL0FMZ1o1aTUwQ2d4CnJzd2dMWE9hOGtzbklDallkOVJHcktiK01TNEFtK1ZNK1JkQld5cUI2V2Vkd0NZcXRUcW1vbENKWnk0eUovRG9Fdy8vTWlMc0VWQkkKTkZ1cE5MMUFyV01DZVp1S0N5QldwUjlic2lFMWh4RFZheWdxWVZseFVDM0VIR0JMSVRhRHdhQS9NQmp1VVpkbkJFMGtaOVhxOUlqWgpZajZZdWRxeE9BVWRWOXBWaEFtZ3FaeFVYU051QW9NUnF4RVFOdzM1cmpFcjVHaUFNQXVuN0x3YXdoWkhDU1RxUlNvSmtETXdwV1N5CldSWEJ1bVprdmI2YWJWWWg3MnMwaVJ6TGlWeUlsaGUvRjlZWTVBRllYbGEzUkZma1NDNG1nczZXa0JLWGJRNjhuemROWEFoaXBHSzYKRWIrRjlPTWJkRzljQlFzTXdzLzZhZ25ndGppMDFLM2kwSldnVFNKbjM2cjRMazFzdG5ZNUhrTk5TRklzTHBjRmxRcHhIRTNRcEtYYwpiSG5hVURJdWpEZzNhS3pZYklzbHVTTjZPTklVcFI3eEJkQU9rVm0yWlppTkdrT0VPSExXNFZnQUNMMmdWM0VSeEdHaytVN05ONTRVClRFQXBLbW5lTHoweU9xaWV4MG5PZk9LQnpFeFo4T3laQ01BanpGdkc5TzhJbWl1YTlhYXN1clBQalhzNEVkbGc2NktJLzFVVHB0dVEKTVJ5VG92b1ZqcXR2REorVENLR0lxMlZaMWJ5TnhUZ2xDSHFBbEdwVmZobWxmYzJkWWZsZ0dlcGZiTVBGM3Nma1RnV1NrMGNZVURLRApxVUoySnd0ZzVBR1ZjR3U2U0w0aStBOWhqMUQ5Zk92VWVBK2tmY3FLdEZGZEI5YkNUZkc4ekE3dkJGZHRhTG5zdFRZMWRjR1dvaDViCkl5REdLM3RZWHlQQ0pKbzFsYURzTUh4SW5Xa25JblJ6S1NOeGt5YUJTenJsTkdlN0IzU0ZsVllnaEpQektFL0MweXBQbHkvS0FaajYKczZxeXhEQjdIa3dRZzJLZWtCRlk4NmtqNHBEWitiT2RneEJydC9HQnV1YWdySDlGZjRHU0dZUWR3YkVRaDRSOG1Nd2tBTXJzUnhvdQo4RSt1eS81S1pyelhPMVM5TXVwSlRnZ0x0QVhDTy9CSUw3cXE3Q3dCUm90aDkxdXh4d0J6VEhRcldBNzJBYjVscWhhbmk0U1ZtNTQ0ClFPY2k0S0FsSVdtOGNJdEZVMWxYYllsM0JGT2gyNXh2d0JnT2c4ZVFzZ1E5OTRDSEl1SEN6WlBKQU9hQ0JVNXE1b0VKWEZuUmtvTW0KUFJkbFcycngzYlBmVWZHbXEvSjNWRXVjR1h4V0tGQUlNVTEyZWhQdEszcGxVS2xKeFlYTUNMcUVjRnV5NDhRVEJUSmtSWVY5eHR6eQpmeVl6aTJJOVlESUNSOHk4M1VoM2ptNUdWbFVhYTVGUDE4MmZpTFBUb3luQTloZkdzbTRhNlFJS2hWdUF3dFh5ek9UcmF3OTVVWE1xCnFNdHFvVEUwcGVJdDhxYXdjMEtLUUtHVzdsZFM2Z00xYjhndmlyWjRZQkl6Q0ZXTjR1UE1URHlDd1pQdDRRQ2pXVE9KeHh3dDFRNE4KM3B4anErWUYwc0FCSlBpTTdmelh0cEt3c2RCSUNHc1dQS1VCRTV6V0hNQUtvU0dGVmYwZ3o4MHNwc2Jhc0JydUI1b1JKVU9leWFmUgp4bnhXbVBCcTdOY3RtclNYWmk5V1VuQU5USFl4V3Q1SENxSlpWNExiajNSNEdZU0hidVZwa3BzeUM0TFlFSi9IblFkTFlZVWdvR2F1Cll1dUJ4d3hpR1NDUkdLTVlFTEZjR1NNY2JNV2owZGt0OXJCd01tYUduY0lnTmlna1NUZG0zWkZ4RENWRHUyYUc1dmVVaXlLQmE3MUkKT1hjek9ZcGJlc2xHNFJTR2xMNzU3Z1UvQ1RHNGNGVkE5NGw2Z2JvekNINkFrVlFHZDZWem40NXh2aWZlUGxmMVE2UjUxaXMxSC9ScwpFZzRNYXJTM1NnL1E2dGFzYkJYbmJtNDAxOEV1eUx4WUc3UFJHcUVtaG8xdnZwWm5TejZEb0JreVpiUkNDekJCWjVadGN0Rmc4N1ZOCkd6Z0YwRkpXNlFHcG9MZ1NObU13V01iVU16azJhN1ozUXdwb0pueVpaelVQWVQ0anBuSGpPWWNhU0VwbVR5U1pzemo0UWhpbEg1SHgKSzJzVXVaMGVSZTJMQkdSVVFZUitzY3d6SkJKM2dGMk5TWnV3NUMzK2ZsMDBsY3MybDZLRTBCZFR6WHBvZEt5enZoeWNGWnM1NXhqWQpnRFd6QWF4aEJoWXMxWFhORFBkUksyeWNkUVV5RGFqMUNHWmhTU3FINkpMUHFxUUJGTWk4WG9oSUxmb1p6ampHMU1OMXdwaGpQNWdLCldXZXBNU1owdzhxRVo0VFpBVHFjRnczRnA0a0JhUmFhV1RyaTNFTkNVK2VDOTRMRUNJNVF6VlRDWUppWktkZ0p1dE1oc3h6cU1GOFcKTytXYSt4a01uQ25idG9RRnpIdTUwd0tpTHhRUUVHZWVqRlBVRmtCME16OFdlRHJ3ZlV6OUlnb1loYWNNYUtML1RXWWpDTzFlUE4rQgpXWWg4ejRXcEI2dWVWbVJNdmtVejZXd01EeEk1QS9ZaWZCS0oxMC9ScVhyTVljSkprSmxWbUU4RWVTQUNSRlVRa0xkemcwSElNOUNSCldQVm9NOWdoMlF6Q2pYQW9PUUdSdUJVaXZkVWg1RGZEdDVHckpSWm02ZHJVMUVaemZxSTh3M3hBVzlJS0t2WlVOWDhqeWV2TXpNeVIKbS9oV1RRb2lSSGlqMHltN21RVEVpc1RNSUdZNFI3SmxLTjQyOVJZUkMwQm5hSEY5bGpTNCsrRkI1VjZCcHBtdWVtYWMya2JLdXRveAp2OElJL2MyQ0JaWWhXVUtraFErdVVtRjNZRG96N2dmTk1XN21pRElIR2tTNnlMQmlSSEJ4azBIZVhjbzJ6TGNFRlFQb2NUOStkcXZ0CktKM0lYQlB3U2dwdnJLeEdHQU44cjdCQWtzQXdrVUFvUVd6WDJlbWRzeHBwMlJLVFo0S1hzV3R3UjBaSGc5THVDT3VGWmpPQmZvYVYKdmJqQVFIeDUxTnphVEpXMVZiVkNxa1NYZFlyakphbkI2Q0ZTTVpxbVd6V0ZsQjBTQUVPcU0yVjR0UFVvY0lUSll2WEFaSWpnT3owRgpCZ3VJWnMyc0NTbGxoZmZ6OGJLZSs0aHpXS3VlbmFWcHYxblBLRVhUelVXRWZiUUw5UnlVZ0FRb21GNmdLT2dxS1pEdFhLeHZBais0Cjl1SUtyMldnaUE3ZkFpQVJNUWNnTU1RZ204aUdjNC9odlZnUndPazhPNmg0QnNPYmN2WkF2Q01QbUxPTHVCMkJrTmJVcmlLMEY4UmcKMndnTXMyZ2FXamsvMDAyMWRsV0ZxUWZnUTRlUkppZjFDV3E0dzZLeUZSMXdVanZ4R0dNVFEyaC9wZWtuV01UaEJ1NjN3cDVnc29XNgpyWXhBY1FENVQ4eHJxcldRdlFGOXNVTEsxZUFqQnZjai9mcnN4a3NRMGExNVZyQXJuRUdZaW5sV095M2NJMjVnODlQc1M5U3RFYUgrCk5PaVZxT1l6cTBTM0dseE5hTFRCQkpDSkRkb0hnSm0wK0RMN3JOcW9hWFpDVkN6MkN2dXNNbzZkZU9kMW1PY0dNTTFnRVMxT2dGcm4KUGRGb21QQ1dVSUI3c09nUUZGUGdyS2NPNndUdHdFUTdkcThFWVVmZUlnRmNEeE9URTNCMFc5NWFyeXNOTzNyUndDa0NTUUgyaVlxcwpwLzF4MlpxSEV6U3VidEN5T2NxWjBCUnVNNGJLZ0lBdXhqay84M0RaU2xWOE01c1Aya0ZjTmpZakluZVJ2MkhUeTdxaHVTN3FoUWVSCmJqYmtDZ3c4djdxc2tBMEw3Qmx3Y0ppcmdvWUFnSklnSVM5dUNnR2hiZ3pVS2ZRNEZRckF0TEtYNHNlcEZNcS9CejBpYzJVbDJveHoKTk1CeHNmTVFRU2d0Z2Q5bWJ0ZG8vc095cVdPTkcxTFFaeVFPQkpmTjN2bEZoWWtGY0I0SWdpMkR5YXFpSHQ2VVo5WnVDbjI1c1htNApZRElnQkZMdk5Xc3dRSXFLU0NOaFU0UDE3R0FIbU80aFZnTHZ0M3JVSVNBUnpEdFFOR2ROVXV0MDNQcEY5TXZDOGgxV0RTK2krNTFKCnZQU2pNR28yMm4xMnF5WVRTY21zUy9CSkUrbXp3UE5UdEU4NXl0QlQzZnNHNkF6U1E5RTl0Rm82R2pBcytvOFd2WnM4S1M3YjZPL3gKUjZSZ0E4OW1XdFc1UE5QS0xmMnRjQ0VMa3NRRWIyZHhnd2cyZ2ZTSmpBb0FBYUtvaHNJc1l6dVp5cUhlemR5WWNQSGxUYk4yMGVzego5K1UvR3dCbVZpdEh2dEtWeDM3RDZXK0VhU0VuTURkcEkraTZCNTlrRWtlcnRSWFZ3WkRES2xkTm9FbVZTWGFaa2p5b2tVSTNUS2ZxCkdlTm54TWtqdjFvRkQ5elV4OEF0MXAzUVc5S3NJTEJPWmp1NmsyWitaREtqcTJxemc5WVQ1WDduWnpBMzg2MW1ndmRVOHcwOGtKdUcKNUVhQXM2WDBJenVVdGhsUWtEcFE1Und1SmVpT1VQUkFTZ1dBNno2Q2ljMHNpNHI0aHBiSGhSNGRmb0dVdlp2R1E5RGE1OG9KMVF3egprT0d6bmtRQ1FZS1cyRVY5bExocWJrbEtrUU5uMDZZb3NEQXpHNjhpdStmbnhPUndNbnRyVDIzS1BRQkdGRFVxV040eDV2VW94VUJGCkdXZjZJWjR2dHplclNMR0pFS2pWY3FwU2g0SG1VSG5HQzRGbTdLRE5UNXhnSmhYVVRyb0I4cEFxb0tXaTZVdUVJa0UxNUJIcUxvSEMKOXFnbitITFdzQlk1SWV3akJDeEZneHZDWlQwbnZ4dmkxakxqTThpY296bWRSR2FqL2ZCTW9ybVpIazJ0TFdNYXFpWkt3RkhwczhhVAp0ampTTmNMSndUT2xrRFBCUXRGbE05N25TQ2dha2djWDMyeEhncE5JcitOcUdDWGE4UUpycmVDOHRNL1Y5dEcxUENKMEFJTmNGOHQ4CnpLWVRBNGMwYThKR1R5RVd1cW12UWRWK2VHY1g1cXd5SFJQUldKVFFreDI1dFl5R1Vod3FzNUMyQXFqQnBFdXpFc3lBYU9rSGw5RisKdUtpVkJpbUI0ZDlrMC9EWmd4QldKWkEza0ZDN0RaQmdNTFJOTUZiUTdIVTB6VUs4aHBjSmJoK1lwOXQ3bWN3Sk9TRkZtM3FLalNESQpBRE9CZkFsNnJyUENrWWo5Z3A5aGVPZnhZOFh5SlBESTVFMFhsRisxQXRVVHpTb1RtZTBOWjdwdUNvUWdBYndDUnNoNWRURjBNOXhECjBPVkExQnNNamN4RVVUVGRGblVvV1hmQjhRR3doOUUyU0tzbHN3QXVXZ3ZaekxkcVdTaVlNSFV3aUFLL1JkZExNcUVjK3RhcURodGQKQ0xObWN5SjJaZW5tSG1ZbjRacGNOTHRYMVJNN2RlR3pCdmhRNUVSZisyV0V6OHdHaXd4bVZFWDNMWXZkRFh3WWhPUWFGeTJDUERwRwp6WDlNdU16emUwSFE3QjF4b2ZCOTFYWUtzSjJDUXl2QkpyRHhRdEtrS29xd1NhSk9ZR1RpUTIvcXpPUldodWhpV00wd0pMQlRBUVBLCnpJTVJjRXZJSjBoblNWQlE2c1kyRU1uazBJOUVCZ0Y4dUhLR3lZNjhhZ2o5eWxSdnlPYmJRL1RwZjRocW1XQ1lQVStjVFlvSUpTRXgKcmJaMnRGOUZOekVHRml1YWFUY1pseG9Ndm9JRFkyQW5nU2RzZFZrS2x3VXlhd1VJSTgwbkRJdUlOaU40cDVobEQrdHh6aDExTjhOTQp4VVc2YXBZRldnMnh0TG1kTVN0Q1prUWNoWmwyR2JZemdLNW1WVlVJU2t6R1pFQ2dGNUlFOTB6aEZIakloUERZRWhCUVljZVR3Uk8rCkpsdUdKVU1HeW1IV2RjWVg0em5TOEYxbU5RTEJMMWF4Z3VEdGhyY2RmakVDeW9CVkMzNVVLb2haRVczcTBZUDNEQ1lwd2lJWHZZeG0KQ2RTQWdPeVhFUkVBWXJXazNCVG0xbVIrTVJBZzZSTTQ2VEpwUmhiQVRLNUxwQmloWS9BWE1TYzFVLzh0RGFIQVphN3ZWdFVwQXcyRgorb0NpNnhaRzNCUGdCSWdQdkMvQWUzZWNWcVRXc0FZREpPUHp4cytLZWxrdERuY05LcmZxUlVsZEpraEFIaFlGUFJGK1BGNG1mQ3BxCnV3M3l1REo0WDFURmpNZDJRVDlIUTNtVW9odHVKdGR5alNYb3ZmSmlBYjFBWmNKQUNLOGdnN2JYVE1WNnJicDhuOXRJYzVVQkVNeGcKLzlWMkpRQ0NpWFdEUUw0cVRxbzduUEdFVldHUnE5YWhWN0hCSkVFb0NsZk9jenZTYVRZVmZjWnkzNmpWVUVLam5ZMEtTOVUwRG5sVAoyNFFLamFwVHJXWmQxRlBqWU1OY0ZWeEpOQzRVUXpDSTFOd25XWkdyWUNQMG9PRVVKZHdkekFiVEJRUTZKRUJ3dSs4TVVLVThMMmcwCktNMW1aVWN6MVE1ald2MW1henRVYmxNUElUQmZ0TmE3alI5Mkp0ZURHVFlNRnp2ZVhUa2o1bVdnOXI0UjFLMnVESTQwYlZYY1REQ3IKOHRhZDFKRDJkTTY0M1h2Vy9HUU5JUnd0WG9OQnk5bWxscWl1eDlVUVp0anRaK0JUMXVyaUgxWlg1bHhZSGNjSElrTjVRT1ErRkZOTApCWUJRSVNVczJyRGJJSHBUT0hpQlFnQU1Ld2liNWltaUZqNEZvd21PdG9lblZVM2hhNXNoS2cvVGtWczVJU0xOVGdtcG9BTEJPWTNKClVXaURHd0pFTnA1cys4cW12WjhKZjI1WHV4QjI5Wk12bURGUFJ2Mm5oNS85NXQzYkY2OS9mL2pKOFhqOS9QbDNydz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJZnYzbTNUUFUzY1ZiMlVra2tCWUllb0JWRkZhTVYwYXRqTU1Jczh0UXhiTHVoRmxSZlJRUW1DNGFsbE1INzlCVVJyd0VxSFZSUVlJWQpWNDE1TVZ3K3BWVkd0NFFXenJBcXVnOVd4SVcyZHQ2VFVUQlFDVGN6OHFuUDBTZ3FUbmhpNGw1djArbk8zQitxTkxrakNzZVpGUmNDClZ5Z2U2b3dqMjZEYVJCYzVUbFlGcTFmRDQ2Ymh1bXVLcm00Rm5jdzhNSFpXVVl5cFRFZ0lSaUVPK2VUQ1dYZE5VSW1uSVNXdmFqVzIKSUltZ2dSdWcwQVRodXBxR00xVUZEK1BwS1h6Q0dZbFo1NThCTEFkRGNUbDNnYU8rRW8ra1dYNEpxWUZITE5zNEZzWjdsS3VtOHVyWgowSlZFNHZoQXdHRGpjN0JSWllRU3JscVczSzVLd0RreTlkNmlWeEVSQUoxK0NScmZRQTY3R1hwRzN3eWFYT0JKZzBYZkxLblJvN2pOCkdad0tIQmJiVllOeEVITTFjM0VTNk1wYTVEQlJ6WG9rSUpaanRmUWxUWXJFazRPb1V4dlltc0IyVmtyamlIeUVZUXMxZkhlanNzcTkKSVN2N0FpUU9DdVpxU1VIMHNFaDFaTkVaZStQYTYycEpYbmdjdEdYVDhCaHY5WWNHNXZsTFFLZjdWVXhVd3hRUm1MMVVjVFl5cG9WRwpBUUNqd0dIV2ViQjJKME1acjdPeFJvaDlNSUtnRmtlUi9vaUV6M1gydE1TZ3dWS0YvVzJlRnp1eE0zUDdoeVdOclVBU1hvTyttRjQxClcxOW4wMFdpaFNvV0lBTWhwRU9hWm1ZT1FJeXJPWGlBVjREd3lTMTRVNTZucHVwTndmaVJhRTdZRExlT3pzZXBHNGdQYVpXd3E2NkIKNlN6VWd3dUJCT2R6QU9UdmNremtzQXZEZ1pFOTgraU9XZ3FubWU2dHlCa1BPWmZ4WmY1aUFNbERuYTIrR2lHb2NWa1ZjMFh6UEpxTgpNZml4SFYrRlREbFlSVEJTY3c4RUFSQUJuSlNRWjIxSDB3aXRxZ2k0NTVBcDlwSDlpV1lLcE1TQTFGUm1sV3pnRXl4b0J5bldaN01SCndla21NaGJXaDd5NWVzbVdxbExDRE9nYXozRkJoRUJkMUJYTm15MUpaVWpLRWxpTndDWHprUllGbkpNQWl3ekVoSWF4V2VpcUpWSGgKUUt5MU1WRUJUZHBzZU5FMENUUXQ2R1ZaK1JyVGVLSzdnV1dEL1I2eVBGMDRUaERCa0NZWnZjeUp5WFQreFVJcmNEb0U0SStSR0d6RgpSYmY0RXNDa0tKUzFXbjcrZkNHNHRnNEVoSHU2U3VuRW10VmtIK2ttbUl1NjZ6SDdmVDdDSGJINXdiQUF3aU9lRmhZOFFyRFdXZk9pClFSUmtaQmQwQnh5NFNjM09XUSs4Y0VrSFFKY3huSENyaW1VMHI5R1ZWakxIcmNXUmNMYmpmSGEweFNxeUNEaldhOVMxUU13Z3hxeHgKSzZ6d2pUN2l4VmVWMm5CbjErY2hrbURoYmJScTM5aEFpd1FWV0FuR2pJelpGUFVpWFRGTVdhamU3NmJSZ01pejl1QVM1enNnTVhwbQpSS0ZLdW93bmluUnJ0N2pxU0tXb3Npa0Nxa2xBQWhxNHlNbTlHV0hFQ2t0Ykwram5va2V0WStMQlEwZlFsdXp6Q3Y4Q0VqMVZUWlRSCjlBVU1zd0lEWjZRaldUVVRNcVZQSE15UXNwNTB4VTBYUm1wSURNcXVOc1hjYk5WV05RQmQ2bzVHREF0Nk5qSGVWTStUYUZJUXJFb0kKQnlSVnA2TzZCK21maHA1REF1RjVjRkM3dnNiVzZxcjFvb0w3cW1xK3BQQVZrMFd5a05JQmREUnlNSW5acHNjTnAyQnlEUFlWUFpJdQpyN3FqTzRZak9kRElJQnJFblFDS3p1Zms0Q1ZHRFN2ODBJSGRQS2lJMHltbzQ0UUU5YjliaEF1dkk5QW5MRDNtbkZRT0QrelZ5NnlaCjdEY2U2QUNLOXVpc0hJK1Via1FyYW9RUGxCWTJUV1ZLVHNIOEs2b0tSUFhJV1F4RWJydXBScHJEeXNaM0FxYU51RHVBQXkwcFBUTWoKTzZHWnhHZ2M5MXF6UVJZQ0FYbkxTSUZlc05VZTFtalUxZUpWTWUwQVR3bDZXSUxLdG51NSszUEs5Z1RhODBDWnFwTlprNmtGRGZXQwpqTXM0ZHFDTUNUSkk1ZzNER1M4RXppMmFhWW5xbnNaaVlZMXB2QWlQaDZGMkE5Mnk2a25yM1BxVjBmdlpGYXNleUtLeGhKckdrSjZ1Cm1ldUdXUTJoZjJuK2c5UXUybGE2ZXZ5aW9zbi92R2tsekhUaE5FbVE5Nkx6STNxbXhhQ3dMOEFlNlE5ajRDQW5qZHJQK0dhQW0xY2UKT3FOdWMvZ2hwTW1LQ1UrRXB3Rytrcmw1ZUM4R3oyMTh4Sll4a2VkSEppN3NhSGtsNExnbTB0c0RMN0s1bzhMTUdEYW1qcU1yS3FxNwpHNFNBN2tnOWFCTDNTbkR6SlpvS1VZY29wLzZFMVZLWHpXb0U0bFhZd25oRU5mUnBUWkdta2YwZVA0ZlFGM2o2Z2JOb0VTOHczK01rCmxzMWlDb0RPd01sQ1FLZlJUb1Z6WUdnMnBybkNyMW9zRlJkcy83TW12YXpBSzh5UWl2RmVPRmNjeG0rbVUyaEJiSXRCTElEbFYzOGQKOFBBdzdzSWgyK0lWT0lteFFIcHdQcWpvU2JoQWFmZml3ZVdhRjJUbFpnZEtRUmcrOG5ndUxRUU9salBJNEYvTVYzcHVBUzN1UG84UQpSQ2kzRmNHTEFwT241ZllWZ2xES3RaaVJqY2NzV1pDYWhxVERSdGloMTNva0djOEVObE1Zb3ZXWXNpSXIrb2FFaGNjTnEvSFVMeXRRCmFLRHB1Uk9abHVxd2VpNkhhcGtuTEtWb000WnhPSXZucDRqcU1RUjhudmxBc3UxUmhlZ0d0U2N1bk9zeFdrNUxxRnF3aFFFTHFPYnUKMlk1aGpZUGRyUUp3eVVOVHpUY09WSUllbGFyUVp4S2dMc2N4WWdBZS9aWEhBeUcyU0kvOFlob1JNT3hpWjN0eGprYW1wZWdISkcvMAowRzBlSG1vcFBia3QyM0ZMeUNyaS9Qakd4b3dSTEF6aENob2hTV1JKTXNNb3Zkd3crS2JZTlY3NjFBSGVCSkZCUnZTOEp6cFg2RlpVCllNQkt3emxOQ00wNldJVUpwcWpCaFMzT083bGR0bGpLQnh4cDBHZElVR050V2kzWFY0dk5UYW90YVl3a3BEQ3pwdlBkbGszUmRqeG0KZ2FHd0NMeExCTWtraTZnbHM4WmhnL1BjczRRd3BDdDU2RGxNeE5pK2s2bG1yQUhzSmhDVHBaMzNaeG1yMDZaNFl6Yk9sSEtiNWU5QQovSzRzdUxScERvaG0zNGFFbExBRlIzMHp5a0xKWEg4TUJhL3FBaUNhU2tjdHFzZVlpejdZSWR0WWFkbGkyZ0VneE5URGtxeXpNNE5WCk5UamtqV1hBeXJJcUxDUWpoUWVHWXpHdkRXcmtHdHRsQkd1RHFORTVGbFdmMVVYR3p6QkE1S0lHQ0wwS1JneGhUSm53WVEzK1ZKQ0YKNTZGWkxDOERRbEFoaXV1WVlXWEJDYUV4S2F5RXZZbEdWdXhOYWRIbG1zdGdnNGViaFdrM2k2cThJTkJRQUFMRG5rQ0F1d1VFTjRXQgpTRUVEYlRFYUdDSElzSHVDNEhkVDdGaFJDT0Z6MndtcExpNUluVkUxU2JuT3E4cmNJZ1FjZ2w4bHk3bkFxd0x6a1NzeEdWSWYxamxtCkc5cXFmUTZNblN2TmF3VWlJaFU4b0k0RVFyYUtoNFBDMVErSFZORVZySmNWVFJDQVkrMnE1ZDZtWVk1WldSbkl1ZXFaS3d3VG5vM1AKUWNUVm1MZk1OSmR4dHMwNWVWenJxdkJyQUluY2trTEJEUlp0T0ZZM2srU1NmbGF2RlQ1elVnZDF2ZmxWUEVNQ2dYcmNITkJNcGY5MgowVTlFSXlVTGlsUFJKU2lhQ0lwRlpBeFBOZ1JRdEN4QzBjS3QzQmZtUWhuVHBqQkVwMnFjVE1vODlWcGRuMFRIenJRbURqc01zQ1E0Cnd5SzZQMmkyQS9nWWx4Y3RpTUk4dW5rZXdoMXBGV1dnbGFzMW1OUHcrMVlMV1NLU0tKb2R3OStOOHBOSVlSdDBEb3BsZElRdjVxVmgKYUhaUzNnZ0Frb3BscTA3czZObU0wV0hnc1J4TGlubFp3MW9vMExmREFqYzlhaHRTTGIxL09MR1pSNlFWZW9jMVZ4Q3owUTdDRWd5ZApWVkU2QkJ4VGRNYk90aWx1aHArWjc2anF1dk9yRnJxQUZVWFB6endCemxNL25RcmduMVc2QngvR0lvZnFuS0tmUWltekN4T0pKMkN1CjZzWGtIbHV5SjdLYURZQ2FOVXVCTXZsWjVUWFk4UmloRERNZ0pPVjEwWEJvcG5MQS9zVjBVS1duckdJWUY0aVc3NEdHWHJTZG5VRGYKV3U3cURkcW1teDhlNTNtMkF3L2dMV0F1ZUNJR2c2WnhBa1RmTVNqME5xNmFGbzN2eStNR3dURmhUNG5aY3VtcXM0MmYxUUUzTjErdgpWdHFLZFlnR2srclJMN2g1VUF1ZHUrMVV4QTYybzZBV0pqRXNkRkFHQVpCSEZCZk9FbTVTQUVEMGxnRlVzNi9EKzBlRG5OVWlBUndGCnpUaWdBWjQwS2lERjlFU2U4d2VyUkxIVUtjemJpeTJtakxsVVNsV0JwdFhDOVhDU0VaaUhTZXlFdW95WEdaRjUwNkVQVk4yK2dZZGcKNHZOcTV3TTVRV1czcXRieFZtdWIxVHlNb0J0R1NEZkMzR0ZialZnOWl5OE1vd0Q4MUdUeVZiVk1HalVPSHRxYWxFTlVwcU93dE1SYQphU21ySGxUQWNPMjZFMHVUeHRIVmFNSDUxU0JCZ0NDU3JlRm1SUzlyTm13OEVyTVhnQWhJSE1PL0VFbk1rNVpYd3djQ3hGM05EY0xwCmlDUkZLMDEwbWs5bVM1cVNOVjJwYXNjUXBVcERZNE84a0lqRmh5R2lvQXdDWE5nNEFwVU1HeW4xNEJsaW5udGZubHN5ci9GR1l4OVIKamZBSTRqTnpGbTVKc1N0b3BxVlZNakVFUGg4bVRFVzJzVVJ2VmJaZGI3UDFTdHVKSS9Rd0gydFdJNUpIaWpIcUNKTzNNR0ZVVUdOVQpOU2VYM2k2bzFhWGFoczdMQU9tQUNSMTZLd2dVQWFzRlVmdGw5QzJEQ0E4c0E4cG05blZtWEdMVUdCSm1kc3ZkU1JoaDUwSW1MNDB2ClhEU1BCM1pYWmxSZ3gvSTR2RmhVbGRWWHN4UmlvS3FDczdseUJRb01qUm9ZaDBRc01GVTRPRm9mcTI1bXdLanFKbWNlQVZJcW55SXEKREpaV2phMjV3Nkx1eVNGcUh2VkV6VkVEVXV2WVRGRTNzWTY0TzFBQlFiVGM2ZlFyY1JzMElKSzZZbzJnN3hmY0JMSnE0QUFXSVBnNQp3SEFVWWJET21DSFBLY29VaWlWbWJQWGdRb0ZLUjlHSitLQ3FhaGllc3dYY0VPeTlXREN4YXRCMDlDd2FKY3lNRTd6U0k0azd2cnIyCllHSlZJOERQNkV5RnlrWWhDTW5YR0dRYjY0QzRRYlJYc0hlazEwdlY2RTJQMEtINjNTbGhpQzNveEtnNTBvdW0rWUdEbFc5RTRITDIKQ0J4WU45aXA4R1VsbW8xTlZZRXUyUklQcWdpVExYNk5kczVTTzhySHdyMFh5eEFCdlVnVE9FS3kzelRUa3NvbnRJWDYwYzY1YUZCKwpDRXUvZzZXUnROUXJyTVB6NVlDcHlFMm5ORUFGckxtYUxtdmROTW9aa1ovY2xRbWpZdUtOZVFUWEI0WDdZL2xEaitPekJxdW1xZmVECkpqWmtoN1hEeDRMQ3BCaWFSZUVhYVU0V0U3V29wREV6Z1JvUHErTGg5RXBtZFYySC9rZDRTMUdQdDY3aWJFQksrdE5kd09ZWkJId3UKYzBVeWZSVlkzYlphMU1pcGJIVHpHUVd2Ly9KSUN1Y1BidWl2bjR6NkpOdnV4K1haUFQzUGJkWFR2OGVzdTFpcG9kU1dkRGZ5U0tyVQpjdTdDNEl0RHJzYVV1MmxUOTZLbjNNV2hvNWovbm5GMzVUa2k2NWh3RjdvMFpyRG4yNFZHS3ZkdDZYYWhRMVU5VXJCbDI0Mk1hVmxhCnNsMTh4cU42cmwxOFhqUkRiMHUxeTJ0Q2JwbDIwVzRwVzB1MEd4bXp2a3V6QzRTaXBmU2pReEYyVmxqUE5jbHVOdVRXa0dNWG1HbUsKd0paaUY0R1NNS2g0aHQzRkVGRzdCTHNqa2ZsMWwyVEpXejI5N3BMVWZMdkxycnNrUmZLMzVMckk1UDcvc2ZkdXU3NGt5WG5mRS9RNwo3QnNEdG9HaEtzK1psMUpiaG1XM1pFR3daQW1HUWRETmxrU0RQU05RbEFtL3ZkZDNpTXlzdFhvb0Nkd0NmS0VMY25yRnJxcC9IVE1qCkk3NzRCUmRSd2RhdHpuNi8wTHBNc3VVUlpOMXFoWS9CdXMzVDZNM1ZoYVJTN0ZkamRZTjF0cW02aU5qb2c3K2d1b2hhNURJT1U1ZTkKZWVZNlNGMG00MHQ1RTNXYmkwTTJVTGNWYWUwMlQ1ZUczdDQ0M1ZiTVdRaWFMbzZUNTJIcE5vdklYaWhkdE1RUnVVQWtYZWdmQzFONApCdWxpWlNhVXdzWFJaZnF6OUlQUlpjSFFPQkRkUGtQQ2RERjA0ZkVYQzVZNGQ0NGh6V2tRZERFSGkrQi9BWFE1VmZkNitMbXMzQXBVCk1UNnhxTzk2MFhPallzbjRYQlNKemNQTzVaOHV6TjNSZVhpM3ludWFuSXVPTUpwQkRjNGRsU0dpRzVzN0hLa0lhaTU2SFdDbURHZ3UKa3V3b3lMcVp1Y3VOTlFLWnV4SXpKUUhNeForY0JTNHdHblpaTldpNUsybCtNU3dYN2hOV0p6Y3JkM2JsSVFPVml5OFlxODRnNWVLOApxL2Jkb0Z5SXN4QlBDVTR1UzJMeHFRUW5sek1jSVc0M2NaalRYaDJiazh0Wno4UmJjbkl0SWlzdlRpNDFaUGpJemNtbGdpeEpDcW4xCkpBelVMODRiWHRXMU5nMU9MdTc3WTIzb293dzQ4OHNYSlhlNXkwNVFjdlVacXcwVksxQTRJeU80ZFdOeVpaeHIwdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJYkdHZ0dyeHZ1dGFqd2UzRzVQSmRvZHphbUZ4Nkt4UmtYYnN4OG5oamNwZnB6a0hKQmJzaDZaT2dDQlg2L2FZRjEyYmtycXhmQ2tTdQpGMEFCeUYzVCtxbUxqd3NiUHFiQTR5S3FnTnJ0b09QaU5GcTUyYmpJdUROV0lqUXVYdjFIQjZYdUZXSTVDbG9QR0hlaHFxMmx6Y1hsCnkxT0Rpb3U1RWl1K2k0a0xQcW5iK3pBODI1WWNyQ0RpdGtObjJ5TlFzKzR2ZUxoZ0Z1QkhBNGZicFBpN1liaE5ZYTlBNGFLK0Y3OFMKSkZ6OHpWKzVTSHBJVUVBc0hCemNIazJPbkl1QXMxREdEY0h0YnRRVEROenV4R0FnY0JIdnhpdHpFM0JaUzl0SEFIQ2hSL0pycjFrdApLWTEzNDIrclMzbUNmZ3ZPR2ZWOWh0K0tmMWRlN050cXZFaXdiNnVyVkFKOWk3K0Jjcm5KdC9zNEJ0OHl3UUhaczhDM3Rhb1kvdWJlCkZnK09nYjFGRkxxV0h0UmIrRkR0NlMvcUxWZEVxd1QwTm5jOTkyRGVmbmJOSWh3cEVUQW01MW5leUZzVVJTQTBaZUl0YUJGTmZGc0MKYjV1N0M5NjhXOElobnJseHQ4M2xTa0c3eFQ2Wkl0dFRPSXVWaHRwRGluV0wzK25zNUM2SWJjdGFGMXlnVzZJUkxocHVOUjAzTUxmSQpVeVB5ZEZGdVVXZGVSdDJRVzFSc00zNXN4bTEwRnJzUnR3QjQ0cFV5MGJhNVdldjVrMEs1bTI4TGhIRTVkTnVXbmIwMDNCWi9zNFQ1Cll0dFc1NWNEYmN2dkUwWGRJdHZ1UHkrd2JaMUt3Z1hZOW1PaHBNSlh3MXFhS3dodXJDMXkyNkI3QnRhMnVZWWdxTGJ3UW5IWGI2Z3QKM0poZU45SVdJd21URjBiYTRwK2JPTGliYUl0VElVL09RRnNreWxBQUhEemJWaG5MdTJtMk1QR0xNczRXZitPdUI4MFd3d2ZrSGpmTQpGZzRYNGFCbTJVS01oekJMc0d5QlZXbUNxdS9KQVRsSERySWkyVUtiaU1CRWdHeEp2eXoxeGJHbGt1SGpKZ1hHdGpvWUVCUmJnR2N4Ck9OOFFXeUFWTDRSdGRVNDVDTFlnVWZKRHZnQzJoZjFFOHViWEVqejU4WG9FdmhaL3AxVmU5TnE4eEc4TGVHMVc4Qy9RdFpuUThCZTQKdHJoMXNMbTFoZW1ydkxHMWhjclEvS0xXSW1XV1ZmVEVpbUpRbUhWZVV2MTB3TUxYQzFtTEZFUStGRnNvTXJpcUMyQXRKQVZFZXI2QQp0Ui92S3g2MWdiV1k0L1NFUE5XakdyKythYlVvTFdqandHcmgrai9qc0dvZnljOWZxRnFnMXNZNHBGcmNuSXRUKzNDWXV5bTFtSmhRCml4bVVXa2dlaTlvUnFpYU43ZWhmaUZxZ1pqRXZiRVF0MGhLaXlJcFF1NFFWZWdGcWtUbDd4Z2JVb2l6bTBHbXpaWGozbElvVVpoTDkKbElJQ2JsUHlRZE11ZFVCOW9XbVJOVVloVDVCcFVkSFcxZ0hUeHQ4M2x6WnNnYVZkV3N1Yk9BditKOWJZRjVRV0ZaVm9wQnhiMFBtdgpHMG03Lzc2SXRHRUxJQzNxZlhEVXphUDFhM2JqYUJmTHhldW0wYUo4SGk1S3dHZ2ZMb0VGeTlpYXhhMHJDaG90NUIyRVdRU045cUZXCnJMeHB0UGc2S1JJSkd1M3ZtRmJDV2pSd3RBOHJac1VDM2dNT3lqOTd1V2kwOEtyd2Q2RGF1ajd6bTBVTHNpRkFRa2JSZnJ3c0hBTTMKaXBZcXgvSW0wV0tXZnRJRzBRSm5NeEcvREJBdFJnaUdRRzRRTGJ1bnozbEF0QS9vejRqTUI0a1dxMklNakRlSVZoU3RkRGkwai9seApnYUZGa0tYTUY0VVdJV05FbFFKQ0M1bk0wMG93YURIdVBDTy9FTFNZVVRycVNrMmdCVlNBWlVOUk1JTlFVU2t2L214dUd2ck5uMlZsCnM0cVhtV25IMzFQYy9aMXF3bUZLR3hzK2k1eXlRRUxXYkRhRmRpNzBMUHl3cmlKY2NwdllkMm5XRFo2RnlCQkJtSnM3RzdiQXprSWEKTW1mYTFGbmVFS0kzams0Y0FpTzhLOEdjaFJRQVkyQWdaL0h2N0E1eEVXZGhtK3k5STBsTGNSMTM4R2FSWWMvdFJadEZucDFNV2NObQp5ekxjMUt4Wk1HeGR1YnlyK0twMUlVR2F4Y2pHUllRUnNxMG9WWDl6WnVHd0kxNFhOc1R2eUtBelpUYit2aUd6MjJiR0xKcnpQa3ppCjZqMzY3TEtHUTR1QXNLbGNGMkpXRFRGRzM0alpWRjFNdFJHemtDSUloM1VJczZrNGk3c0pzOWhLdUZHTGVmQzlNT0J4QTJacFRSY2wKRmdiaFJvTXZtMWdSMk1hYkx3dnBBMHV4cnoyN2FQNmJMMHZMek9YTmw4WHhLRi9jZkZuQlFsYzVmRmxwWWNvbndDemg0c1VKREdhNApTM1plSWdDelJLZU9OTitBV1ZxRkhEVmdGdi9Cbk9ZR3pQSS9tRjY2Q2JNQ3k1WjVDTE84T2tSbk5tR1cvNVNNNU4wUXF6eGRQUmVFCldXYWYrR0lFWVphUGhwQzBtekNMQkpGU1VTYk00ajQ5ZFpaRG1OV1RaK0xySXN3eUw4WklZUkJteVRaRlZYa2daZ21pWitqeVJzemkKQjFEMnNnbXpPQi9seDRJd3kwTXkvSG9UWmlsc1lwUXhDTFBFNFdmM0xaYk1NcHY0OVNMTVNoTFZEMkNXQm5ZT0NjQXNMT0lTM1lSWgp3bG1adnd6Q0xHS1ZpdnNHWVphQlAyVVlMOElzTTJQNmtFeVlaWXhuK1Q2eGVtMDFRWFplZ0Zrd0Y2UkJGbDhXREVRQ3N3TXZpMFpWCmFwVjI0V1ZYaStwUzgyVzUxVGgwV1J4bU9lMjU0YklJMmZEQkJsdVdnU2tWVlpndGkrdWdFdW5GbGwzTFgwS2daVmNTejIrVFpaRWMKU1BYTmxVV2NVTzNEakpXZFJiaXhUWldGQWV2TkYxUjI1bWlhWnFZc0RLSUNHaW1yN0VWNUUyVlJvcTN5VVFObEdUNUQxbjREWlpuUApiMk84Z2JLODVQejBBNVRsbytOWEdFQlpjREFSbDd4NXNzdTFpTWJKSWxiRjRMOXBzdmk3OXBzbEN3dGxKVWJKNGdDUG9tc2t5UksyCitmRTkzU0RaeEt4N1Nwc2txemk1a3d3c0lNRHNKNHppUlpMbElFWVljNUJrZWRPclhoVnhHbkNqTUtyZktGa0cxSWNhR3hJbFN3T2kKYllHU3BjRUUybzJTVlE2bTVZMlNWWnBram8yU1ZmNWx6UmRLRnFkTWVWaWdaRmx1dy9yYWFQU0ljbE44SHpkTGxpME9vQ0VJbGl5RwpkbjVyWnNueW5yQlc3bUxKMG9qNHVWbXl6SXdqQWgwc1dSaVlSTGhac2pBR2daWXNXUm9RVndtV0xBMXNTM2F4WkNsNXBLYkdNRmwyCkJNSFhIekJaREI5VUhOdzBXY2tnODl3MFdXNkYyU3Rvc2lrN1ozSFRaR0ZrZWlGb3Nsc3NLWnBzSXJ4bnRCZE5Ga2I2RWtHVHBRRmgKdktESjBzRG1NQmRORnFNMktibUd5WXJvdjFMUVpObmFHd1BXelpPRmtXV3lBWlJOcElhV3VZR3lOTENLK3dMS3lvaGtoWUd5UEE0TApEZzJVaFlFczl4c295MDRJeUxZSFVGYkZFbmtGVUpaOVFQa09YMEJaMWNZQXpXcWdMTnJWY05JT29peVV6eFMyM2tSWnlxR05rU1pSCk5sV2pmVTJVNWQ5OHB5K2tMSTJRQ0FSU1ZxcnFyQXdST1Z6OE5XcVRicVNzWk5UNnJpblFZT09mcFZwQUVtVzNRdm9teXRLdGExbUQKbkFTZUlQSFRtUW1pTEVUMFQvb0VsSVV4c1JneWlMS3dlSXA2b2dkOFBYbkdqWlJOcDMyQmtiSThGbnRHQkZJV29uaXFMRjlJV1Z5agovS3hBeW5JK1ZvTFdoRGE0TitNVFVaWktKNWFYQlZFVys2bWdMWWl5dUJFaUc5eEVXVWpZVFhVM1VSWXZGaitLQU1xbTVvNlJMNkFzCnkyV29DQW1nTEx0d0tUVnJvQ3g5Y1FDU2JxQnNpb3ozQnNyS2NuQ3lYMTM0N2R4akxIMmtGTjg0V1VFUzhxYkpZbXlsTk5vMFdUMzQKbFY0NFdScmhpd1ZPRm9lbWdEbDRzakJ3VnJwNXNreVR6N0Z4c3Z3YnMxVHdaR1hvNjhXVHhZOGhqUnc0V1g0UEFralNqOExNWUJUWgpscXNodjRZU2xjREpNaStaK3ViRVloU2FiYjVnc2hqUG5GbWtyVWRyVGFGa093YVlaNzVJc3JBOVpyNU9iVUpNaVRpeVVPZk9GMFdXCm5lZytibHRBWkx0ckE3MEovc1NRY0NOa3UxdTZCa0VXMktoSFFXSEVpTkFxRnRQRHhZOGxqSFhWTUxIWGErdWJIaHQvWC9EWWJUSTcKZG5yT0RTb3NXS2tzMHJuSXNhTXBhcnkzS1FLRUJEZzIvcjY0c2R0a2JPekh1VlBuYUdyc2ZBU3R1cUN4UWNzTlp1eDhOTFFGTW5ZKwpiaGgxRVdPeGo4bXZqTTFNQzBpQ0Z6c2Z2Ym8zTG5hNEJVN1FZcGtiVTRpS3RGalFCTWpOdTJDeGhJaVd1Vm14QVJVTlZDd0MwQjhECndRMktoUW1mVW9CaThUZHlvY0dKSFNLMzNwVFlZYWxYUUdLSHU1Y0VJNVpCNnR4ZmlOaHVEeUVRc2ZqY0prdkU1Y0dONkJad0VXSUQKR3hXQVdEUzhRVFl6K0xBOUszbC80V0ZwS25uVFliRUxrWVNHd3dMNnd3em9nY09DaUZYR1JzTWltWW1Vczhpd2dHR3hIMWw5NWJkWQo3Qk5jV0NSbUtWY3hGblo0VFhoVFlkbk9sQldtZ3NKMnJYRUNDZHNOL2J1SnNEeVJ1bm13YkROOWFMQ2RZYS82Z3NHeXVBdHZvbG13CjNjVE9RTUh1UXh3UWJIZCtMeml3dzBtVFozL0Vvc0NDU29GUUJDQ3dHSlBTaFh5ZDBTYmpRc0JDeDhYVlNXeXp0RndLQUN4SlYwUzcKSHY0cmlSV29JVk1xQ1g5MjNpUFJYNmYxQ2pmOWRSbzBHL0JYcU4xWnZXVDJLMUMyS05PN3lLK0xvZDJ5d2E5WWJiTEJnd3VDNCs4TAorN3BOcHI2QzY5SkY5aHRXam5HZGNUTmZsNkV3Z1h6Rk9veWZheUJmaVRkb2FoYTFrYTh3U2xHc2lCVjFIUXdlalNoZDZacktMK0lyCmdVaEQ4VWI1RTVCYlVVdHE1Q3Uzb056MFFyNWlDdU9vSGNoWE9KUmw4MTVuMFJPL2NhOVlKcUhTUDJpdlBKdEhHNm5pRjM3Q05LSjEKMXczQVZjQ1ZCdTVWYm9JZ3VXclRsZHdwOXNhOTJsVW9HL2NLQTBlendMM1N3UExsQy9kS1A0c25idHdyOFFrWWVvTDMrc1hsK1BHSAovNks4VjRiUXdQQzVlYTgwSXNvWXZGZUYxVXJlZ0ZkR3kwaDN2NGl2RElwQWVCTEVWMkllZUhBUlgxZlZ1M0FEWDNIQlhKMEg4SFV2CkJBUDRpckFYKzN2ZXdGZTFQcFREUXVJckRUam51Z042WFk1QXZlTjVvbFFFOEZVUnRkNDI4SlUxZlNTMVg4QlhCcFllSjdNa0srb1MKa0FmeGxmRUxacXN2NU90MkRJMTg1ZnRub1lEcTR1bktJa04vSVY5dkkyUHV5Ukh3UUw0UzZkQ1VwdG5JVndyTklXSUo1R3NpYkRmbgpqWHcxdEtLOGtLOVVDRklQWU9Tcm1HQ3RiT1FySGlFWE9UZnlGZVVaV0VJRzhSVmxSVVFtcTVwMXVhbkd6WHVGSnNsUWFYck44RWt4CkNnVHVsYkdqcWk1L0cvZkthRWRYUTJQeEJ4NzM2UXpjS3cxTmxYbW45b1hHMmpmdWxjZEJoRE53ci95MVBGKzBWOGJvMkJ2WnRGY3UKQnl2ckwxalB4d2dUYVlNSDlvb3dqUHMwc3pvSXpDYXNFUVAxeXRLSlhGK2tWeFFORVJwcjBPdVk0cllGNTNXNFNPdkd2TUpXVkpGSQpWZnR3dldoQVhvZS9oaHZ5Q2wzYU10TVZRa2pSTW9Qd09yb2lPVGZnZFRSWDI1dnZPb2FLVUUxM1JZaUZyUElMN29wK0RSaFRBKzdhCmw3dGJtdTNhSFd1NzBhNWdEaUZvRkdUWHJnaGVjRjNKS0JydGhYVmw4eEJrcGtSMXhSSHdoZ1hVbGYyUXgzZ3hYYnVyTDZPTUZUMHMKc2lyWFdiT0dNOGQ2K3lhNnN2OXdMUnZveWtMcm5EZlBGYXdvT0hrM3poVXViOVk1TVZtR0xvRkZsMEdZYTNVVjRNMXl4ZHJSemV2cApZTmE1QWJBTStlTnZ1T0EzeUpVTnpVZmVIRmYyeXNsbFkxd0JJSVZ5NWFhNG92NlJMcmNocnExcG0yQzRRdG1DdGZHTmNJVU5ybndnClhLR0lhVUt2Y2pVSnhZeHBiYnQ2dkZVbEpBTGcycXJrc05jK3JDQzY4YTJvQjJmSnU1a1Y0WVFIdmhXMUpKZy9iM29yUUJQNG5ZQzMKdHJsNzBuTE1SeFVNeWJvWHV4VTJmRHFCYm0yZVhvTGNpdk1vSnNSRnJoWXljSVRhREc1RlFuRWNkUitJQUVYaTJZMXB3WlV1MXdvQQpYSXJGRGN2cHpXeWRiaVIvSTF1WFZ6ZUJiRjN1MHhQRVZtaDZpWGk3Z0swUWpMS0kwYnhXbHRDc3RYR3QwQ2NqQUhmUldpVmozcXpXCjVUQjJvRnJ4ZC94S2tGb1ptSWVySGFUV0NLRUhxQlYxUGVBZzNKeFcxT2h4N1dsTTZ6TEdMeWl0eS9IY0c5S0tuSURlakFnb3UySTcKeEtxaU9lWHhnclRTU0t5dzVWT0pHTTFjTjZTVjRXejRxamVrbFEydUVmb0xTQ3NtZHNNQnlXaE4wWjdnWXJTZUk1blJDZ01STk1GbwpwWG9mUVltYjBRb3ZKbDRJcGFuZ2dMTjN0aG10VHMydUY2T1ZuaGRiUDVqUnlnd2tacDFndEg1eDJDSlk5ZjBZcmNzdFcxNklWa1JkCktmUVBRaXVpcmxHOHdQVU1wdlJrWXV1V3N5eFN5Z3h0eFhBQmd3cEJUV2ZGYmt5ZzNIQldGaVhLcXlhYWRRVmZOUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJaUtzS2wxMm9WcjIyOFAxWWNoaWJvV3ZUOU5xRWhmRW5yM09CV2VtR00xOGZZRll1ZHBoYURqQXJRM2l1NGR0NFZZYnhXQnRwTGl2UApDN1hTbTh0S0I1ZmtyYzg3OWlxZHZkb2NzeUptam04Ynkwb0xPN0hlV0ZidXdGb1lZMWw1MFpoTWpHWGRmOTlZVm9aeldhMXZMS3NxCmMyZmRXRmJtcjFoZGNHRlpHZnhtZzdnUnNyVkh5czdnc3RMenpRS3NucHBDZUU0NWJTd3JZdThzT2pLVmxmOWVoSURkVkZhZUVlNWMKVUZsVDlCRUlLaXZGK3hoRWJ5b3JqZnlvVFdXbGdVT0txYXdjekZBN2NGTlo2ZTNodklQS0NnT3JZNFBLQ2dQVjVqZVZsWXRLanYyaQpzbExac0JReTBxOWpkSmhLQ0cwcUt4ZVp1R3VCWmNWN0RkRitVRm1WV3l6MVJXVWxUd0pJZzZDeUtzR2QrcWF5SWpiUE1lV21zaExvCjBRUmQxVmdJeHQ0OFVGWkY5RFZlYlNvclZRd0lGQVdWbFlZaUNpc0NXTnlyS25Cekt0cWhpZUs5TnBXVlhMcWtZTjRRNGkzcEJ0MVUKVmdnZUVPb0xLQ3R6YmZNd1dhR0RZZERpWnJLQ3A4WDA5TjRLbmdPQkM0YXlJdTNCOStPR3NzTEk1cXlDc2dJR1JIY2dvS3hJenpCQwpkRU5aeVI3RGtqT2dyRERRWXdzb0t3MlFTdDlRVmdKNldNOXZLS3VJUFI5M002Q3MzSTIxTGhlVU5UVzdhUUZsUlYwcmx4VUJaVlh6CmJqQ0VENVNWYVN2V214akt5cE91OGdVSVpRVytqYUNBaThrS20zN0xUTlpFVWsydG04bEtBK0ltTjVNVlJtTEhnc25LclhqOVpyTHkKd0VtYytNMWtSZjVQbkFveldmRmtpYThLSnVzMjNFeldZelNURlFkblFDSm9xNG42NGp4ZlRGWmtUT2wwN2EyeUZqQ0JaTjEvWDBUVwpzQVdRTlJIU0JTbUNnYXo3WmJ5QnJNeDhvaTQ3Z0t3c0ZVWnlPb0NzVEdPWmdIKzZ1OE80NUo3cEMwWVNDNnVTQUxJeUdhVy9kNTBEClgvU3FtOTlVZ3Z5SUIwRkVBLzRWNjhlYngwcThWWk1QcWV4eENkWmJBRmtad3BrM2o1Vkl3Q2RMVWpQMGFhZ3FQbmlzL0ppY1BMNDYKVEZTNUJ1YXg0dStPQkY3d1dHR2dwM1B6V0dGa29ENTRyRFM0R1NsNXJEUThPazQ5MzBwV210UkVWbVpYS1hJS0lpdjBhaXlKZXhGWgo4Wmk3T2VzRVlyS0NmNmdmS0lHc2xHOFJHSElCV2FrVHlJS2c2NHZHK2xuWlhBTlo4ZGF4ODlPTHlBb3IrY0NieUVvTEhzbEdzdEpDClFkdU5aT1h4Mk9vOGtLeFV6TEVxTlpDc3NEQnVkU0ZaNldBeSsya2tLd2xXZytxaklJY2treUl2SnV1MmJTWXJKeVBxTW9QSnluczEKeXljb0s2eDZwUXhsaFlHTC9RMWw1U2JVek54UVZscjVoQUxLS3Z6WE1LWlZ1TTZzRWU4RlphV0k3akZycVd2bTdCb3FOcFNWakFLbAo4eThvS3dPMnJFOE9LQ3RySUtsVk0yNlZiejJ2KzRLeWN0R1NqbTFGTDdSQUFHN0RUV1E5Um9OMjBNSkMxQkR6V0wvNDJOL1ZqZis0CkUxV1lpWU5qVlZWNTJqUldlT3RjWVFXTUZaSGNYdDhzVmdTSldGNXJGR3VYdW5xVFdLZEsyRjhnMWcvYklERFZTRlhJSmhBc0RCQXIKVnMxbzBITnpXTEdPNi9jdUErckVEV0cxM3ZQRllFVXRJSW9FakdCRmV3MXhTRVJnUmJ5eXBmb0NzRUp5alFwNzgxY1Ira0xOYk5CTgpnWldGL09QR3I4STJpV1FWZlJWQnVtZHU5aXBVOVNpV3VkR3JVR2Vqd0NMUXEvaDdJY1J2OGlyK1JubnZUVjRsdlBialF3anlLclRuClVERHNVNFBJbHF1Umd4SmpNZ1J1c2JDclVGY1hmTzB1N1FLVmJ1RUdYZEJWS0crSWw5YUFXcGJHOTBDdWxzNlcyQmR2RlI1RXhuTEIKdUZYMlhudktwcTJDYWxlZitZYXRsaUk5d0dhdFFndmVpR1IxU1FRTUtDQjZrVlpoaEdRMFFLdUZoUHQ4T0tzRkViVlMzcGpWc3FRawpKV1VWbVZBeU5mMmlJTlhNRmdrWFk3V2FMUmVJVmNiQTF0aUVWU3pZdWE2OUFLdUlUcERuRXJHcXg5UUM0MVc3UlZZM1hSVTI2b3dNClY4VStTNWxKUlVvZjh3Y3V0R3F6eENuSXFzM3Q1d0tzMm1LcU9XQlZxRTRZU0RkWUZaSUl2S2ZHcXNJNUhPa0ZWVVVnbEFrdU0xV0gKRVRPQlZCMHM5SHNCVlpFQXo2S2xrcWM2alBZSm5DcDJBWUxncHFsQzZjTDhsMkdxbU0zQlh6WkxGVElzMWlsY0tGVmNIaWJwSUtuaQo4cGxCZFhnUzRVT0VXbStPS2dKdjBDMEdScFhaYXBFVG1hM3JLdFMvR2FyZFBQOUFxRWFKY0JCVXUrdi9iNEFxR3g2VXRmbXB1K2pUCitOVEMwdVQwb3FkV002OENuZ3JJSjlKalpxZTJzdkdSRzUxS2tFU3VtNXphM0ZZb3dLbk5Lc1dibXdwYkVRQ1ZxbHBTSlhyZTFOUlcKQkpxL3FhblZBdnVBcHNLTFl0YzBKODlRL2NTZWZoY3lsYUtEVVRZeEZhUU9mRGdHcHVJT1FFbDU4MUpoZTFiZnVGVGdGNmZFTjZTbApGcVkrMGd1V0dpaVZZS1VXbGwvblFLWGl6NHlydWtpcHVCdVBoRU1FcFJhOGVpS1pNTUZmV0psZlhwaFVWUDJ3N2t1RkZTVnIrZ2hJCkttcUt5SFc5R0ttc0FjaHRJMUpGdmxxYmtJbzhaUjh2UG1ydUtySU1QQ3IrQmpRazZLajQrNm5yQlVmTnlJTTg3YkJSUVJaU2grbkIKcHJDVkgvcE5SaVVnM1RhQVVTSGdRSTR2d0toNFdiTUFwNXVMMm9BMmVnNFdGWE1qbk1LZ29pSSs5SWlsdXFHb2l6WGo2VEJSS3lzdQpEeElWNDVaZW8wTkViY0xkYkNKcThwUnBJQ3BlaFpwZU9GUzhRWEEzZ29ZSzNTVFNGMEZEeGF6SXk3MWdxS0FrUVA4UUxGUUVFSldpCnhFU0RMSHNlbjBpb1VNKzBBMExGbWwwL1F2SUxXMitXL01hZ2ZyeFlnRTFzQ3FvRm94dUNDbDF2TFc4R0tzSVBwUjRFS3FhT2NnQ28KeUhDbS91YWZJdnE4NXNHZjRsVmwyd0RUVHo4bS9xcUt5QU0vTFhKZWduMmFQVE1IK3BSbHZYaUxMdklweEJWOWJPNHBGaEFrNFFYMgpGS1ZBVC9wRVBRVUF2bTdvS1JKbGoxd3FESjFjdWxBdGV6RlBKVlZnWTNaSlloRkRkS3RsS1VjZWxycktvZHpRVTBUVFJZczI5UlFHCm9lRU41L25pNTM1UEp4ckQ1dkQ2TktDblVBVkFjUlhNMDBBbkJmSVV1YXNwU3VrbW5tSWxEaGxrQUU5UjhneWhTUEJPU1J5bzY0VTcKeFNnRVg4RzAwMlpTWThCTzhmZVlMOVJwYzRZN1NLZklEaUx1SHFCVDBrTWc0NzA0cDYySk5oS0JZaUNTNEcwRXdCVEFEK2VuTnVWMApwcDBCcFEyTFpkNEJWUzBDVFlQVitJMDRoUTAzTWdpbnk1aDlBMDVCaHRTL2Jyd3BJdG1ZOVlKdWlpb1lCcmE4RFJKbnlDemRiTk01CjFkWXowS1lCOWd4bTZaaEtWOXhnVTRUWDRGK0VyVThKUVFOckduL2ZWTk93QmRSMGVIWU5YT25vV2tUZVRGTW9MSXZrVzdUTnBOQnEKRUUzMzN4ZlFOR3pCTXlXRGRkV05NeDFHS053MFUwaE1TVEl4ekJSQU13UjZBMlpLd0ZrZUw1YnBjQy9hUUprT2ExMENYSXBYdStUeApBcGtDQm1yOEtZVmUwelR2d0poQzZSYlV6cUNZSXI1V0ZDOWtMSUovbDBNeFpSd3h2UmltMDVDWlFKaE90OW9KZ3FrYjI5NzhVc1lzCld3MThLWE9jSWlkeHJsTU90Tjd3MHFEMkJMdDBUamVEQ1hUcDlNZjNJcGRPWmlPbDMzSlJFa3RjQWx5S3Y3UEN4WnRiU2x1YUcxc0sKMWl0RUMwRXRSWDBLZkxBYldycE94ekJXZGhFRk8xSXdTMW5sa1YvRVV1Q0JFQVVLWUNuZU9lbm16U3VOMXI4dlhPa01BR1BRU2xlcwpWZ0pXeXJLck50K3NVcE5vTjZrVTU3UDY0WlNpNklTVmVEZW1GR0ZCb3Fvejc1UEtFZ0pTdW85d0lVcG41QkJOS0oxT3NRU1BORDd0Cm0wOEsyYVBvcDhLVHpxUWJ0N0dqbzVwQWR0TkplNkJDdzRoTUMvR2JacE5TUFR6ckcwMDYzSlI2azBuSnhlamxnRW5IYytwUFE5bzcKbmxPQktyVGE0ODRlUVNYOU1LZ3U4NGFTZGtkN041TzBQMUU0NmJMYmJiaUlwTWNtSUdrM29HVURNVWRXZWMrTFIwckpTdjIyYWFRbwpLd21NRzUySzZ1cW5GNHUwcnFnTU5vcVUrdlFlSFpla0xJOFdUenRuaU94T0tvb0E2dGd6eUh1bWFsUW52bDhRMG1hOXdHYVFJcW5WCjJpYVFqcURnM2dCUzVBOGhJdy8rS0ZkRDNnaTFvU1FnbW9vV0tncVVBeFdEN2xoZVc3TlVUSnM5V3JONldyelFveFdMNndDWjRrYkQKb0pwb2swZXI1WHczZUJRTjczVFdUclpGcmlld281K2RreCsvbytQelg2bWpmeXQxbFAyWEtETEFTUG94eGtveVc1cTcwNUpxMTVQYgpNaTF0eDFjVUt3bkd5MmtJU1RDMFdYTzZ1enNodWs4Y2YycDFCYXl1RUwycmEwbW90VWh5ZVJqY2hxYldJOUs2Y3c3RDRJMzFYc1kvCnNhajBPYlFBZ1psQm84TnlDQlpxdk1TeWZvUUxVS3VxUlYrem5UMGZKR3lKQ2NmS2hDdEtrOHZUbUxJSTU3d2M1SXVyYkducVRDWlkKT3FRTVkvV1IrRTVqVklFT2lyd3UxT0xDSjlUeTBXMEZNZ3RiY1JjSUJ4NXErNnppelpiazZLQ1Q3V2x5ZjZ4WmdaelVYRUlKQyt2ZgptV2tsTkF1V2tzNmVoTWpSMnJwSXcrNWJnVFVwTGhnV3lqZ1JnWjRCNW0vdUtjMG1yMWoyc20zNzR0bGlQYzlBKzZOUmt3MWxJLy9lCnEvS3BiQTNIeW5rV01pVjEwUDJZaXh2YmhaUEppSDV5VWJ6RUh1T2RDMGpNSXl4cnFPSTNveXN4V2FQc3YwUGxPMUErc1ZCU201NXEKNjNCL0hTWmRZRUhva245WC9WMERza2pqVkVQdHhsWTUzYzIxWU9rdEd2NGdza3hMTDZjNXZBQnRrTkJTUzRWSHJqWk1qemlncVR1dgpyajBqSjhibFJkSjJEenRoUUJHYjJTRWJqZGZaamFvcjE0NlhvRTVEcGRCemdEQlVQaWFFcnRGMVFDZzFURC9FRjB5WGpPRVc4bkVyCndXQXhLRytzV2xRTlIwb1JqK1czT3YwcDBaTGliT0gxZVQ5a1B2QTNpMUo0ZkZiL3c0SUJIcFlVMkFCOHQ2eW14aFAzOGJzS3kvQlcKRkR3QlVOV25wTXpqa29wdzlRUDFORHNRNC9OU25XNm1wUzUyVkhaZktIdzJZM3F5aHBXQ0RWcEI5S05sOEJjNmtWVTB3S25PcktqWQpUUWNmbFVMRFNnaFRWaEcvRHNXd1gzN2M0MUtXcVBSZUx2Q0VWZG80RWsxTjExZUpPQzRJdXEwc1dZN2pGVS9Jb0hFODlZOUVySVF0CkJ6QXFaM1dsWm5OME1OMzNyYVVWekZGWSticnd2V0dPRGt2bXhaYmRybC9rTm8rakVHeUR6VzZPUTJFb2JpZTBQMzRoOFkxcmtqNm0KTWM4b3dnN09LSDVtM3djR0RPazdJRjZCcDFNNStBM0RWVUFMd09pZzZ5ekV1ckg3QW1vM3NLTTJtNGJBOGJIeU8xZ3FRTkV6V2RKdwpKUzU0a2p0U2t4Y0R6WVArbHRBTmY2ZTRPNCsxdG9tUVhlOG56RW5zNTZyNmZlU2YvVHdvZXVBM2hlZTdXMEhnUk9uM0xFdUQwMXpDCkxPa0NrMzhReTFzeW5BQ0hXQVF6c25URmJ4RllFSURuODV1UG4rUlhpUVp5S3o5Ky96anRRU2YySkwzZ090YkFnT09xV0xiWEpFb0kKVnVUOThKdHFQem1ZeVM2MHlNZWs1bXpGbnRuNERDaXgyR05zRllQNndheGxiNjVaQWl5WmxLelV1T1V1SEhqSmxLeGpzZDNRUUZjUQprTU00cithZ3JWOGpIcXhVUERaeXUvRzN6Z0h6Q2ZrbzNkSmZXa3BNMGFoZDVMcUdWaVRadXh1NzhVZ01FWEllaVY4c2dXM29XY215ClJKK1pYNFpieTdFbkMxWW1pQlFoVm9XM2xZaGlEajZqUzYzTzdpWHNGMENRYnRORC96alM0ay9xdlVQTUFQSVR6ZTNEYnhVNTZ1d0UKRVBYbncwTXhCRnNmbzZnZkwyWjcrUk5ZZWFCYWFEaU1DOHZIeUsvVEp6dUZmZDlXMThNa1FTSThrVFdUbnpuK0E0YkhiOEhIRGEyeQpKTDdzaGVITi9aTStISlE5dVBIVnhCMkFxNXZQbnFWaWliRXRYeVFFK1hwN2t1RWIxV0p3M2d6a1ErZ3Jza2RORlNMNTUzQXB1U3lCCmxYVXNzS1FzSi9OaitIQXowSmN6R2lGUVNYbnBWbVMxdENMRDcxY2JwUlNCZGVJbEl6QXhhMG1kcUdQdDdvS2QyRmYzOGxMVWh4ZFcKUWdwZ1lXMHNjQlYweG1DaDMxc0VkZk9lVFJoNnJaeVRlakdKRmZTeHRsNjl5STl3NXhOYjVGS0Jvekx6dFIxQ3FIeC9TelhkS3JvWgpraS9RUnJpT3pRMW9VWUgxdUxWRkk1bWNQYit5bTFSQmRRUkYyZWhSM2djVkpGOU02TXo0aEhxZ2FtNExrV0RhTStadzBocTdGR29mCkE1dXVxaWg4Z2ZOZmNyTVlxOFQ1TS8vMXN4M2RRc3dUeVBsdG1IREFxYWVaNDNsWnB0Qnc0U0lUVllHUGgxck5GZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJSFp1eFpxNXNwVmhVMVVIV3hneVZXSGRiRWpUaVh1eWloZi9BODRXRlZLL3Vya25jTWI0aDF0dXcvV0ZSTW9lV0lzUGlDOWRkK3FlTwpyZEVqcXdWMmkzMDBLT0lNTGo4Ri9sa3RUeGRIMHVHYzZoNmROS25YakdFQmYydENRc3FTelRxenlXV0RKSys2OTlQNWt4eis2UGg5Ckx2ZDhtZXJYU1lrcUxXMnZBWVpmT3haT1BSS29VUkNNampVMVY0MU42cW5kbldENjBhc0hpa2YxYmxVMUYyR3hPQnVwY0R4a3Q4MGwKcWVmVGg1MVZKREFmdDA1YkpEaHgzWlRWSldlaHowSmliaTFwTXVvdEpJTE12dUpMUnNkVVlpaVE3R1MzbnlPMURDb1RaTWhyQzlXbQpwVW1UMGZDa0pyL1R6VllaYU9HZUxESkdKSHQvSkRYRkkraGUyWkJ1eW04RDhWZXNRR3YyUGVzSVBBVUFwamkwdzVtNDlQaVFOVVl5CkJ3VjlGVlhNMjZMc1UxWHEvbXlIVlJWblFjQjA2cU1JbHQ2ZmZybXJGb045M08vbFR3bFJKRG9TVkZlU0cwVGRwK2dzOFRrajFjUkEKR1FBcUkzaHUxVEFXSnY5SUhFcTVCM2FsN0QybHZpTzBoUUhrYWRZMFhxUktQQXZZY0VzV092emEwOTRmbENqNWNRa29heS9BTzhpcwpIWEVkSkY0THJoWjVYeW5oS21yRFU1S09UMEtBVy84bzJNZ3laYm9IZTRoRldESjhobWF3SHFzRDZEUGszSUtLMXo3NURGUnFWSGtwCm81cTdwMGdqa2J2VGJaZndqVFRyb3JSajk2QklLY0RrODFZamVNclVlUTdiZ2dhZU1mUWM2L1NpRlZGWGptS0E4M1BhaGw1U0hxRXQKZXRIRFp6dmJlWFZGcHdsNTY4dENXWWwzREdOcm9oWVRpOGNmd0tmT0JlOStYVUVxZ1JPaEo0bGdQRTZXZlhTYk9EdWRrdGhzaU5GagpVajd2Vjl2bDd5eHMwejJMZU92eTN4UjFQY1JJVGxucXhzWGdzVlU5Sk5KZWhlTnBlclJVRmRCU3U1Mi9QZHFCOUVWbm14TDJxU29CCjl3VmJwb0VpZmxVTVRFbzFlcmdoRjA2cUc5UmsrckttdXBnVUxoMVlJc0VoREVUYkhXTEI5MGdmaEtGTkJsWWgrb1lRbUJiditlRVYKNlFkempjYXNXSnB3dUs2VVpJcWpCRkFMREE4bGNOaVJzU1d5UnZaM0JjZ1JoZkpKcEdrMk1lMTJyTkxqdVA2Z3l3dE1TeXc2S0NrZQpmai9zSWliN3FSRDBONDU5MlpNNkFrTWw2dHNRTnFha0dwMXZOUElqUU0zN0NrYm5sRitnR0RGSkJWdk1qcWlQUExLVzdJcm9FZUh0Cm0wa3V5KzdVbGtmb2dHRWQxVDRmVy9JV3Z6MTBBaC81TUlyYXdZSm5wdkg4OFRCRDRWT1ZBSnoxRFA0RUN1ZWowZTFIOUQzd2JDdXAKQlJTUkluYlFteitWNWp0V0l0VXpJc2dDZ2c3Zk1sZ2Z0MWNYdTRvNnlhVEhwU1VUOGZreHZ0WUlmN0p1R29NY0FXbGRGczNzTEpzZwpNZlRxOGNOWG5EY0dEenMxa2NONm9lb1lpd2l2SGZwangza0ZOQTdOeFpScUFacHRhSGgwbjU4cUxTbm11WjNzb0NWV1pidkptcmZiCnFaUEJzUE5sZ1pSdjlmQW50eFh4WVhvK3cwZ1hWQUx5WmZ6czVNY2FJS05PdXFJNkhzSTh2Sk5xa1lYTUUzdXhkd1hBY2hERU1xWUgKek50WjMrRGlOcHlpdVd5dnhybmxZaGxJeGdjMmliMW9lazAvdmdINUFMbk1IZDJFc1l1T2dmRUluUkdnT0N2a2xLaldFb2FLQkJBTgoxWmNQSzdYb3J4M0pRT1B4ay83T1ZLM0FiUWs5TFE3UDhuYktEeEZPd051OUdETEtVZ0hqSXVCOEkwekttWVNYQ0NqVzRHYndhSGxCCkpnaGxLcGJ3azhVdHgza0sxUnBKV0lWZzRBVWdwZ0ZHTHRzWUY0UHRZRUVyRlJwMmp5K29wL0NPOFhEb1ZseTYwcENaZmhmQ3FMQ2cKSm9BWDJhd1M0Uzh5WUY2YXBnVnN4KzVVT2xmOGI1WG1FQmZMd0pGMmRHa2JubmRMRkc3QzI2WHFjMEJOakFmZkFqR3dSSXptbmtSUgo4NUtTWHNlY3ExQUtrQXFpYzFCV0tsY1h1V08vZkxORUkxaEtSZkRKTEQ3QlIrNTBSajBFdys0WUk2dFQrckFxbGd3ckF0eXdLSTZNClBpc1FLTUhBakFBSGo1WDJqblFxYzNWREVCNEtDMGRZV0hqSW4wekxCc3V2TWpXcE9NV2FsTFptSkozQmZyNWtET1VPVlVqalRyTUIKV29UODlvYzBFTDVRbkE3Z2FDTERHWjBxVWl6RE1sWWc5b3ZEMUNpN2U1Z3VLQ0xsY1RNK3kwZmR6bUhvdWU3OUdHWnZpdVp4RzRiRgpRYUJRWUsxWWgwc21SV0RTbncyUUtPcFRvRGp4MGxpeEVFNWlGSnJ2SlI3eHNKd1BjZWNlMlFVQ1J0bHFHR0UwaEZSYlJwd0kzYTE0CnFvUWVSOStCSkJJampSQkZzdjB0c1VPd2NPS0dHSWowSXZqS0pWakswQU5CazVIcGU3UGRzUjB3V056cElQa0ZoaCsvRzBJUlJjSkcKNGxuTHJDeTI3VkNxcUxEeGVKY0tLTWRJek12RXhSTXNBdnhQemRwVGl1WEhEaEVicWo1WnFSM0dEM2UwY0E3RlRCbDlWSjlYcDRBNgovSEgxb3NXckNjOXVmOCt3RHNic3B3cGxlU3dGdkRGZ1JKUGFvUjF6dkR4cys3QVl2YVNQd2J0U0krZUVjWVl2Q0hsRmVFYVBWUjg1CkcyekdwQk5DV3JnSEJLNDgwSWJ4WVQwZThnRlZXVEhXb1lzZEk5K1BPYlE1dVZVUis4NFc3VWdTR2U5U01rT0tWbkxVY1dXTG1aUEgKc0xYSFJMYk1ibmhqMkpMUHA4VysyTHhMT1MzblYzUU9VMW1yWXNUTkE1R0UyenZoNVJKSEdpVmovQ1NReldJT2ZpNlA4Ymc5YkNSSwp2bkowNHNXSGx0ek5PV01TOUxjb0MyV1UvRjRyazBOUTBVVjdBSkMxdEU1MUVVT204cmRvTzdZZjRUYU1mS0I3NHc3RlEwQU90M2hGCmJ4VW9ZUmlhVzQ3bFlPanRqOFlETmliUW80U3NudTJ5bThCUm1WRHU0ZWd0SjdyaS9CVi9jU2R5aWpHcUNtRmpkQ3pSWWhZV3FBZGgKVVIzWExLZTZFMVo1SWxQcW1FeXR0cnRvNzU4a0NZUXRzM3ZNemhCc2N4VktPU0xlVC9oYlU0K2NpNGlNU0ZIbU5VSStxOTNRTFlkOQprNk1iSnZnZk5YdllhM2hMWVdtUHR1bWhrSmQxNnBheDB3RVBOYm9zSE9Qd2U2M29GOWY1eFNyQkp4SlRLK0c5UmNpSEl4UUtDZVVmCmRIVld4TGx6RzdsS1U1Ri9waFRnem1RU0NKMEVvdTlFTnNqU2dKSWlrZ1ByTEYzakRRdW1ZRm5QZEhLUGVUVnNzNW9ubDNoekNJU0IKLzRFRkYyY2FOc2h5VnJCandRWkw3MDVQVTZtc1BhMnZoSlZkVzNCTkpIbHh4S3FrbUdVVjR5dHA1N3dqSEVLaG5xQ201aVNGT0FsOQpJNHdreUdaa1JIN2EwR1RROCs0ZkJrMmlqV3JNeXZTK3BscjJ4WUNoTVUrN2JnMCtlcElOcGFRWmdlYVJHcWVwUjRzNC9tS21LMEk0CmdYK3hHZnlBbkNHckUra1NLczN2WmltWkRhbTZoMWVFVXVVVEdzeUNTWUVMSTdvc0hLblo1NGJ1TWpsYStNVU5mczRoNDhYQVZCQUwKd1Z1MkhuaEx1U2pmblJtWXhidU04aHZYdE1EWUpoNFRmRlZVUFdRR1psSFh3ODFzR1J3R0VBc3FWb2RsYWlpeXRtdDh5MGhnbXJKOApMQi8xays5VndWNHZZTEN2ZTJuOThTcHp2WUFxcCtxVzB1d1pCd3R4VTRqcXkrbER6cDFwbTY2S1FBM1p5UTA5Ui9lY2tGaU5oTDlaCmJBMERwek51TWNiYSt6MXdZbWh0bm9XV3MvNE1CTkNnMUYwL2F4N3NTQ0VDdzkycktYR3FoQVdiZURGZC9RaThVVjJiSXFkbVNuYkkKc0hwU0lwcjEzVWpjVVVjSkIyT244ZzUrSExKWlpadGp1MUhqM3FDTkR1SWh3eFF6Q2o5cXhGMWg1YjFHSVZqMmR1SVFFeVR6eU5JaQpGTGpkZmxnNTFhb0JkeDZSQkx1Mll5NkxHYmorNkVscXoyYWlDTVRuakdBSE1CYmhOQVhGZ0tYa2ZCTVdPVkpGenMvWmJqV0RUcUQrCjREUGNGc0JyVXNEWWp2VnhGNW5sK1ozMTVUeHQ4Qks0YUE2TDdtMVJvUDVzbHQzWG9FWnQ0N1l3Y2g3NGdHT3RiSStjU1BqMW1RMDIKdVovVEFkUTJUNHBZZVU1S2pOdzZBQloyRzJDZVFpazZrdzhSU1Q0Um9obmRjeEZmN3Q2T2ZSZGhZYU1mNXU1WERrdEUwV2Mxb2FZdApkZXBoQmh3dUFLb0IwYXdJZVFuQzh4Q0VacDZHMFFpa1FoZzJhaEdjZ1dYNlpGbUx4WHcrRXpWcVUrNjNZT2xieFlOREp6am1MeGtLCmgyd0hFMUhhL1hsUkN4Zk9XMkliWHpjOVY5SVZWQSttSDBuMktqcFhkWlhBc1dwQWxJWmNGbWFveVBKbkRoVWhwdExsYU9LcStZbVQKZStncmJGSklJeUNWOVh1UGtCL01QZkEvWUZGb0ZHOUxqay9rTWJFWERHd0lFN2dkRmR1YW9CUXVwcm9WaG5MdHFBdzNyQWdOa1ZMYwpSRkNmVlBQQXdrWXg2RDEwOHB2ZGpaQnJjUWlNRFphVFV4bFVIdTBHeCtnTGtnTzlQY3dwaGRYYmVSRkh5MHdLWkdmSmx3RjlDR0pPCkVKUnBaVFlOb1cwT0dMQ3dtcnN2QTRvU0tRMDdxTFJFUEsvUzd0QlNvc0tmYit0OXFIUnViQ1NBNGJhanlEZU55SUhSeVVqM0NCSVcKWGlhVFRtN1RrclNka1JrQ2ZDSWNpV29TRGlWaDBRaGlrTzdaYmczWHhaS3loYk9BVW1adFlsVGJnNVp4K1VXWlJGckVUY0IvUE5Jcwo2Q285dGNlT1JCR0pFYy9sWlltZU10bEphTWoxT2Rkd214aXowTUtBeXdFK2twRzlhbWRmbWNubC9qR0FEQnNkeEMvcnN1cVRqVWZtCmNKaTNhQW9hRWI5OXVtdlNNS0dKTklFUTNHaGVvSEs4S0tHSVNSdGIwQlc1akNXVk8rdzR5QWVMRVFodTRBcUxVcjNZcGg1TkZEbHAKUEJ3ZEoxaThIeWNXR2pneVpKRE12TnR1UHpRaU9sTEVVbVAwSE9velNjRndBMW1DNnA1UnVFWTFla0orSHplYnkwSGVhTWFCNGRiawpwSzRLdUYzRmJidHA1SVd6VXIzSys2UGdqUllzOWFnaG8wNUxFZmF5OTFTdGRkRWJSUU5IVjhUVEtUWExGbzlTRTFCYi9PVGpma1QxCmlRNXZ6c3NoVlBsSXpQZDJzMzc4NGI4bzVKZUJTREtYMlk3VVFBaGFsYTN0RnBVeFBKbVM1VHJGb2NoNS9vNGxxb1JVa0o0K1hkRVYKSHg5cTRhYm9sZDRRc0YreXV5YlRzU3RURXRnUEIxM0JMUzJVZTlieU9STXgwT1dMblRod1VhMFAwNFdMN0laSU5iY2RJNjEyYnRvcgpSbG9WaXFMV2lKMEI4UU1VUjZBSUZ4bTNYS0xNSHBiK25GQ25SSDJzVGs1eWUxa2pnVkwyeG9XbytsTlRackgyUllaenpNNjVqQm9rCnIvM0JKK0Nna04wTU9yR3dPODM5NXRnNk5TWFJ3b3dERkN5c0w4K1A5WFRVdEpTeDkxUVpSSEVraXVKY050b2dmWGhLbktzUmhzWGwKTTF6bUZhcVRwTStHWWtZQytWRGhrSmZjZHE3OXNNME1SVVptdlFKY1pFWnJzY0lOWUJ0MTRrd3NQTTMxTW5nTU94WU1KWjRTVXRrTApDcXlKdXhOWittUWVGUTFLVnRSUDFJbWpONHlOTDk3ajdHbnhhTUZ0T0lJUnNUMVBoTXo5eGg2cllaT2p5a3dXeithZjVJQU95NGhWCkk4T2lReWZDSUNoamFvZzAwdEladVJyR1EzRFBHTkNoeWw4Nk5SWVN3eFBtb2hvM1EwS2cxYUpkbW52YWNLWkVhU0hiaDVYb05JTlcKOGl6UEttNktxMm9CU3JqeUNUMG1Ncnk2MnFwMXlyaEk5U3lhQ3RnN01ybHFqb2FZMVhkTldISDRoUUt6NnNZdWxBVW5JYXYwMEhqegpZMDhsMzFrYVFORklFNm8zTVc5U05hdUxqZ0VKa1NWTDB5MXdhckppSENwY3d1U1JuS1dxZkRqVWlhK0dLdGhZL0R5TTFMRkxBcGVPCmpxWENvbmx5Wkl0WE1Wdms4TkJnNVR6SkZ1aGVjRW1GV21zNE01SEVoV1VuRE1ld3M0ck1ZYlpJbGUxUmtPZXM1RkNoOW5GWUV2VEUKazRUb2pUbEsvQ1JYQlZnRThYTnJydnpuZjhpVHpScFYrSk93TnNzVWxRVkZxcEZCT2NwaG5kSlg3emxZU25RSWc0YURRd2JGaTltNgpUenFZbE14YU5LQzFDU1d6b2N2R2VnTWNVNnllS2ZtakNEQS8xZ3F3S0dIVUVJYVlES1Bybkc1MmlQVVYxekRxU0Y4NXJnOXEwaURFCklwWnBwR3YxMDQzeEJMS051blVZbGd4U0krRmtPSGlpQmlESGUwYytMQVRSc0xZbW9acmFzOTE3c2hlV0RyNWxydUpnSjViQWNZWHYKdFFrenQxU05ERS9yNmxrUnk2M2tYNlMra1F0M3R3Q2hINDRwaU9FUUNzU0dQdm1mL1JMb282UmNIT2ZUWTlLalhCejVhYXdldXZWdApKNVBmdTVvTkRvY3FPRkZUemJIVnNiQU02OXBUdUNCY0xpZ3FnVEd0NkxmbEpFSjIzTGplbXBEdVJkNDVIRjh2RFlmRHJoalNKYmFZClRhcGFDclc1MG9XR1BUekp4MDNnWWVUS25Ma0luZ0paV0k4VTNzenR5TEw5M21qUGhPWUFqSzA5VGxWd08rWWdPQT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJaS9nblNRQ0trWm41Vmk2UG1mYUliRWxpU0xDcUVtck5KdWtPYjRRRzJPNENVc2hCV1F6d1JNUExuaFMvNHh6RjE2N1BMUUNBMDZrMwpxdS9FQVVJd0krVEVEc2VwUWVXWW11eC9kcVpGbGFYRFNrRzRGK3dRejZjclB4UzA3NmFIbFVPakNhdXF4c1owTVFDaWlhd0x4Uyt3CnBUQmhEejc2anJ4Y3gydnFlc3hRNGRQMERaSW5oZWsvSzNLMEpPQlNNaUZxS0dDbG84NWMrWlIrZlRJa3g0YXl5ZUtwWGZNQUQ1S2kKV0dqTStRc2xKc2Z1TU1WWGJ6VGlqOThQWVV6bnBEQU12UlMzK2RYV3FVS2ZGUjdjMFBLWWxsNGRuaWYvQ0h1R3NvcHhSS2EzOHVOVwp6K3h4dVJ4MmJxN3VvUGZNNnFtMjYyUzY5SnA2NE15a0RSY3FaZDVDaDBHYmt6MjB5R2xCZVZ2dTkzYkdJTE1BVEF1N25lbERBN0FWCkxpaW9aYzJPZVNGOHBJcDZ4WlVnNWdvRlo1M3lZOGY3SGJKOXVnTGIxTFR6M0FhOTN4SEIyT1NHQmU4OUg2YzBrM1ZOdExCUkJYTGwKcXJsSnJnZEs3RHU4RjVNdW1SdFNrUE5mMVduaFVRaDFXMWcrYUxVc2RoUW9FWmt4cmwrU2RVMU1reTQvemFFNm9xSElVenhOTHExWgpSRld6OGh4ODZEQTBQMTZWd21ISDJkUGVrVDNuYUUxT2tFaUQ4UURqclY5VXc1M0graVZkWkRGSEVDNmZMckk0cERNalVvOEJqU015CnhwSlF6bEFWOThqWWxYSmRNYTBSM0NVRGk0Tmd5UDNzS0lBaUFzMTYxNWNiRWNMQ0pRRUNOTjErejU0aHViVFduRkk5eXFXaDlrYUkKVmVra01KSlFlamJkSy96SFdHMTNWYVFtcHMyeU93MGhXakpSVTZKRXRGVURDeVVNc2FNSzVORUJpYm1yN0s2dmlUUjhOcW9vSG9JUQp1TnU1Z2hJNmMxZzVqRUpVejVET2VQeHdtZFZSZEt6V1VFN0F5UEFjNWtoOEVEQU1COUVZU2VTUjZJaWpvSCsvNk9XSisxKzlQc3BSClBndFZNbUtMMU16d2hxRVU5ekZNRktJUVJXTTU1Q2NOamc3d0w1VnZJSk9rR0U5WWxFbWlTUExhREZtZG5wUjNVQjRkM2s1MmRmSDIKa3pLWjE1alJrYjVBK0JLSG1tUG9UZFJVM1F5WlNHd2VFSmVKa2dxdXcxZDh2V0NnNlNNY0ZnZWdydysxMEtzckhCdDdLcUtOK25wTwpwckFRcW9HMmdpdnJXSHBuWVhsbS9DYjhTTlpYWWQyTEgxaEtjc0hocHUrRS9LdjRIS01yOWNRN3kzS0NLVjM0aDB1c1BLUmFxUU5jCkFibGh4dUtiMVNYd0swWUVNMUN3RUlWcVRCRkRuSzR6cXlwSW9JV2hKcm9mTWRQVklqb3RyRXlNY2pQZWpLb1VBSSt0QWFvcVVLSWQKbXhzb1l5d2puQS95UTZZL1FOMUFubXdiNWxDb1NUdHVhM2Jnb2thUkRuZzdVTFRtbW81QWZwY3VRYlVrNzI5dlYyS1ZOc25CcUxjRgpWY214L04zVzFaVHR5T3hQU0tIQlVpWDNmbVdaV2lzdDB0RlZIV1NoMTVCc3JyT3V2bk84VnBWaHAzYXE2Z2FGSnBUWnorSkhvaytmCkxXSHNBRDdhYjR5bVI3bUxrL2hOektFbndnZ3pMS3MydVp5WlVoeFlxUDJFOTdwSFBCUnEwTGZ0SVVjWUNuTXpZOG1BQk55ZHpNeXcKOHdBLytpVmdFeG5OcGtsU3lnZThIR1pFK1huaEV3eEp3bDVzd1RxclZSeXFSbFRzTE1sQ1Z4dExuNUZETXJhSnBIRHJwby9IckRJcwphMGtHd1NrZEJvNzRWUm54dUVncGg1YVZtc3hvNE1HZzhEWDdFMUY5TGFLK3NZQ2h1cEFlRERJQjFJcEIvcG5zNVM5MGc4ZWd5SmtkCmJ3VTlFdzE0SzdvekRZOEVKVGtKRHdJK2xVbUlXSFVKQWVwMnQ0b2JrTUhhOU1JcVF5dTlRSkc2a0hrSENRYnkyRHRLVFFSL1RtTE4KcWFVNi9UbGVaWEYxRkxlSnB1SDBjQkd2MFdSSHQwdk53bkRaTExhaitKRktNYm9OTWZac2E3S3FocnFoVW4xcWZKTFV5OHAxM3lMLwpUTG51SEphYWNzSnhPcHdoVm82NXJMNmpMckFlbWdLdGZFNVE1bUdsZ1B1L0VDR0NSWW92Uk1Rb21zdFhUU0Yxbml4K0p5ODM2Wjg1CnFtQU9ubHFIWk9VOEtZekZpamltYUxFVEVQYmlSWDA0WlZ6MElVZzhxVXVCakl3WEhwWWQ3bnZXWmFWU1JrclhJa0xCc2VTcE1LMzIKM05idVNtdW9idEtRZGtIdjRoZFAvM3V1SmxoNUlWalIxSHZOQWtwMnFXbWlRQXZOQUI1ZW94bzlPNzBJdlRZVkN0Z214ZEl6dTRFdApXeUJBOUlVNkM5VVdwQmFsTnQzdVJQSUV3YVU1RWNGdWQ2ejZWb3JhMVVVT21nVW1ZN2dLVERmdEF4a1prcy9QZmtNOUNQYnhaWG5VClcyNkhodm1MU2c4bExiQVJucVdtajcxcmxndFpsMG9TR0JQa05TSS93bXc3TmYyUGFralY0M2tvQ293SUtNVjg2dFFjTld6VkJjZzgKLzZ5S0U0SjYxQlN2RkVOVmtCS09wcy9hc3ptSmw1MkZMaTBTZUJ0bzB0aTFtVmM0UWxpS1gyUmxGbjZIMjBpc2RzNXpXb21DTC9uWgo4UC9IM2gxRU5ta3FYRWlPQldwVVZidFp1d1VZSU1qdmVxbEtNa3ZsOFZSd2dsWmdoV3ozSnY0azJ6Z3dLZ2xXMHpnMUMwcVVwV1J5CkFDcEx1ak94OU1rWlMyVVNJQkFpMmpNME1iRFdvUWlyUXRycFVkeVEyL0F0aHdBc25mSSsrYVpJSnpMU2loOWdIQVlXNGxOcU1sME0KSzRtZHNBWFNwamdsckZRdnlwMVMzUDdxWHQybVJJM2pqU2wxNDg4SVNGT0hEY203YWk2SlJMY21jYkxhVWQremZKUytlbzY0WHArbQp6TU5DTVFjc1BOdmNGQ21PUFlXeHg5SWtNdmNLMU9jV1BKTXA4Z3E3b0tRUWZTQ3lwMmM4Z3RDU25YbEZVUm9CT1UzVEd6OVdKQXNVCkw2MzZIdkE5alNnOVoyQVB5U21GL0I5LzdoRGE3MWdpcWp1VnZFeVNKMEFyUXRvT0cvQlpQTUo2eUhKWGtVQmNRYmtMa2FwWnRaM3EKVXg5d1hPN0pkN2d3U2hSUmMrUXF1bXFvWGIxYzFPazRFYnY3cUNxWkRXVlNET2MvK2xtcTlBa2ZrZGdIMFJ1cE9nUk1rUUhEM0RXZgo1Ym5pcWN5UFp1VmNwSDl3VG9vcFdnazF1akxIZFgvUXNMSWJBR0ZjVmIrZ01xRWFnZWhoRGdvdDUvMUpEazhEQ0V6Nndha3B6MXJECnFXZ1hqN2s0cjhEclpHMGZia045RkdaalF3d21TRkg2bjF3cnJtRWY5YnoxNXU4OEtxb2lYZ0dTR1FaOHExZU4zSVFhWHNwSm84ME0KNDlKREdqWnEwM2w4MW53QlVrQU5DYXJPVzdGaGR3Vng0UXFzS1ZWZEpCMHRmclBETmMwZlRremxqYUJpVGc4ek95M1Bpc2NpL3BFKwp6QjdzQm9oRytYSjJGTkh0WWFSN2RZbTZwY1NuM3kzaVlTVlQxWDFTZmd0N3JxRGdicDRWcktyd0NvcEVkNEtSRmtaUitsQVVSWHVpCjBSVGpsNCs3QWxSM0lHVC9FR3BJYXBCS1VOU0VsWUFlWnJTd2FLNW40bmFjOHhCVWRxa3lQL0Urcm53RThwdGNKOEU2dTc5a0JqcHcKcnF5bTQ3ZHRsa2VMS0IrczlHaG9aU0Y3cVk3dm9yR1JmdEZLd1NFWjZjK2VaYldjSlVUajhXeWsxMjVhMVlONEdBZThhdndJOTBRcwpTdFdSdy9LaXBNb1MzamQxVlFzMVNuVThMSFpVdjVLbzVKUkFxY25pV21WMENtUWViK2lyMTU3RFlBeUlwZkhDUXNiS1lRcXZ4Mk92CjU0bFhuYUpkK1V2bFQ2TE1NaTIycFhyc0FOUVM1ZGZkMm4xa3B5TXV4TTRiak9qRFNnUUNZcVkyS05tWDNER1k4OXF6TDdJTGo4OXAKa3RlR1EwMlZGeks3UXpsSFNyWkVxVWxPbG9XaEtHbWs0dm1rdWdpZVpLNGN4WHlSU0F5ZlVOd2gxbjh0MVcwWHVrY3M0OUtFSzJFOQoxazk3NXNJMERKNnJLa0xiOE1UOERGZUUxaHBUdGNrZTdhcStWUk1FTGt5bXBtcTkrRmhKa0QzMWhDUk1hNHQ5bFhMYzBKRWk1ZUk1CmJBbkdvV1FXT1FORkEreDBmWUtBRzdpYlpKVDdGQWZIYXFpWmhCRnRxcDVpWm4zUHNxd3p5aUtIS0lrS09WZHpmeWRtNEZrdnpkcGgKT0tiYlQwT1lkM28ycGpxZDdueFhHVHpkRlJvbzI0Tmw2NzlDMThIeXVFZFYya3FINTRDc2ZWa1lmTmRsaCtTYVh1TVAxVzB5Q2NzMwpEUEkwbmtTdzhaQ2RNelR1Q1pWeUZabERFOFpqWHhFaHk4ZlNZWUZYMlJ1cnFPSmQweUlzbXlzQlZBbGRJVmdEZTZMMk9qaldNdjdOCldjbDZWbUQ0QlFrc0VNT3EwaHlyMUJmdG9vY3p1cUtub1VWaWlJU1l0dTNHRTlLalE5TXpqcmpvcWRmRnI0Z3NaUW9QQjRGanBkRzkKMFJweGIxemp6SUFWNVpmcjBmb2lVcDV5K3RmaitRbmI4UjFIRkxKVTdTazhCU3piMlVCVFNrN1hLNkRvU0o4cTZPanRhT0V3aEtPSApxSVIzZ0N1azZYVXRybFY1eEdua1VHS0hPRU9YRG9TSUdPalNydTNZQ3BwbFBzdFNoRzFCZE96czJhTjg3VEg3Y01wRlVHSTJLOGVyCjVYdFk1RHRPcFEzT2RnenZONlZaV3IzL2ZvNzBibHQ1dFp6WUlQT21RZ3VpUy9wMU0rZ3lLMTk1NzJCMzAxcGNkdFM5V1lLb2h3WlMKQjliTFBTNEdBeUhhM2IyZFJGd3JtV0tBbnh6ZWN3ZjFpV2dicmtBVTRTb1pwWWI0TVZFbWtJQ3lKR0E1YWNTM2xVUm1SU0pGWkFvbQo4c29TZ1BJMTVtaEZWbnBNM3l2SVlKT05WZjIyTTdxN05PYXZBRS9QSlEvOVovK2VFL0pMSVUzZVRLWlRZVEdHUzZvaTdIZ2dadUh2CnJDa0NFSzVESEQ2MndjMjZTVXBtc1ZsQmFIVVF4bThLak8xNlJsYkJzVVFwa2RXV3JJZFpUaExxSjVQRjg4ditBdmVrdm1aUjhVK0QKL00vbCt2L1lVV2w3WkJyR1Vya2dWUnRzWnV4aUs5WXM4ZGl0bjJRcis2TWdLdVNDMkNxOERVSklwSWlJY1RxSDFZNUdBbE9jMVZqUApPN3dDVzE0RnNteU9wVW1zNDJTWlVOOXFlcDBab3YxczY3SWtReUFuZzV1VlIrTWJGZEU1bWpURm5wemxZYVZPbWhaaUlkR0phWmVZCnhyRm0zTmkwSWh0ZEg1TjNsdk54TEdTbTd4Zmp4N2JvTXBOaU9pelg1bmI0VEI4RkR1VW56ZDNjeHhZTkg4TXcxYjBkWmhnRytPR0oKMGhtbjlyOHJ3NzhydlZnandIQXJWTCtQNElTUE1tNkRrQlh1cHdMNGNVdng1Nm1DMTVvR2d4K1QwMlFXV2ZxaDJuQnVFd3Nyb0lBWQpEQzJ1S3RMS24vWGJMdjQvbG53WHF4eHJrcENWV256bnczbEoxTEczWGZyVjVsWUhFUzdEcERRNVRUMGZXS2o4b3VheVNrWnQwenFxCks1TUtxa0VvV0tXSnVsclZ3OFA0bnVWNGIwOTdUMElsYUkxZkVQazFtMFRFYmRRZXFxZ0xXY3pOaXQrbllpUWRrRUVzejRjbnhWbWQKRXJlbTJxdGRrSkdNUkNXSUUyTklNemcrcy9uaEVQNUVLRklFZGtMbXcyVWpyeDMza1k0OHdGY3FCL2Rxa1hpTlFuWEFrSHBSZXo3cQpFM21lUUh2TWJSaitvcHMxc1pRb3hJREhsVjVjZ0laK1pnbUhhekpaRC9EWnovcnhPenB4LzVXai9iZHl0S1BDNElYUlJwUXNEU1d4CkdXRkVUSnZSR0VPMEVjMW14T05tYUpmbHpHc3d0RUdGWDEzbFd5eW1nTHRMdXZ4TjBFWjVKc3VlRE5DT3psT2JuNDNsR3Z2djNQanMKdkpRdzNmUnNNbU00ODBjZCt2SVljN096dVZ0U3BRcmpjamo0c0Y5Qi9FaGVLbGE3dWRuMUNiU21zZG1JRERGYkVOVHNadjNjQzVvZApmV2syTTV0RWUyYzRxYkdwMXFPOWlObkhhR0IyZGRQTXpjc0dtcEF3aVJ1WERiUlJMV0pqY3lxdVJTdTJEY3V1Vmc2OFdObE1ObVpWCkozT2dxS0dvQ2xKMmkvbjJBbVZEQml1ZXM0UGNBUkRjbUd5V0NGUVJmcU1ndncxWFl3Y2tHOFhTSEZHRGtVMHBReWx2UkhaekFkRW0KWktPM1dyWXdINTIvaXVvV2J6NDIyNitab1UwaE13NlM1NEZqTjh2M1hteHNBdUJhT1doc3hKL1VVczlrYkt6K2hrOXdZMktaQ3k3OQpjTEZaZEtiY0hCT0lmWVppN0lKaW85OU5zVHlNTXl2b3RNOVF0US9qYXBpaXlkdStpZGljeUxzdzJRUmlzeDdRNkhIaTY2SnM4SVhECmpxcTN6Y01tWlBqYmhtSHp6NlZuczRITnFDcFRBdGdvYkpHVlJZY2dDWHRVMFZCdUR2WndtR1Jqc0Q5V05FeCtiUXIyY20rL0Z3UWIKcXdWMlJBd0c5bExUd0NCZ3I2UWw0Z3VBVFVHTjlxRjdoU1B6dFF2NjlYSS80UmY4ZW5ablpZTjlEVUJFSjU3YjZPdXh4Tng2a2EvWApWRS9qRGI1bTFWbkpxaUZnZ0pjTkpVUkN2Sm5pYkROUkpTSVdKeDBKVStHckRiNkdSZG1ORzN5ZDZFS25FSld5MDBWMGlRbndOUzBTCmxNNmI3ZGE5REE3d05kYlBUMmlHa2IzQ29vY3B5QnQ3dmFyVGFvRzlSajhPYlJiWWF6YkVZT3p0NWw3TE9sWHZxZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJaE0yVExQWWZodEE5cm5pOHVkZXdEaW5vemIxbW01RHVza2J2cDFqcHpiMWU1cmx2N0hVMEVRcnFOZW8xbXRkeUczcU4rV0o1WmMrQQpzOWRWbTNpOVpnalhMdUExakV5QkJ1OGFjWTJSODdlTnU4YlpOS24vZGlVekdqd3JiR1BXOVJvbWk0Wk9lUTBuSDI3U05kYTZUTzBFCjZIbzIxY2dHNWhwbHU0Wnlic2gxZDV1bXpiaHVTeDdiUmx5M2kzRzRoNjVtWmFZQjF3Qnk4S2VEYjkya3lIelJyWnZqY3NHMmJ0TjAKMFVCYnc3Qi9LYkt1U01kUTdoMWc2Mmo0R1Z4cjZoejFLVzJxTlhNVDFDa2FhdDBqYXhwTTZ6YjhTdDFJYXlTREZLTnlWZ1Fhc1AyRgpjSEpNVG5IZVBPc2FsVitCczY1UGFEQ2R0VWM1WkhNUng0WlpWME4zTnN5NlJnMVRzS3hoR0cxOGU2R3N6N0ZNc21iK2QraXJvdXFYCkpUS3NuRDhnYXl6cXBzVm1YRFFnbDZoaUlXT3M0YXlSZzMxanJITS9CVVNrV0dkT1pQTHhwS3Y1N0FsR0tGVmFic3o0NGl4ZkRHdlUKeDNEdEdBaHJRRkthZWRVa1dHT0daMlRoQmxpVGlQSW9qazU2U0l0aXQ4Qlh0K1k4NEUydnhpcUhTTm1BVitQWG1FOE5Kalc3K0tVMwp1WnBRa0J0d1hZTjRIZHpxNkNMN3dsWWo1YUtVcnFuVmRVVlkzTkJxSk9NWTY3eVoxWUJpODgwTFFEVk9xUm5uR0FicEdHOWdOWkRsClJZZGltU0QranBwVzVudGhVQkgrQmF1dWthY1BWald1bFpORm9LcVA0U0pWc3lLeXBrT3FidEhIUGtEVkxRcEpiazUxaTI1VndhbHUKVVVvU21Pcm1ibmczcFpvbEh6SXhFbzdWbjlJMlpsUmpBK1ZmTDBRMXpvaDNMUWpWSUV1d1NqMEExYTBxRm5uanFXSFRoMmcrTlF5YQpONHlueGlCRWljMU5weWFVaEJoZnc2a2htbVRvT2VEVUFCQ3BxdWxpVXlORnE3SGJhT3JhTEdJTk1qVSthR2JxYmpBMUZTT1BzcUtzCmRhZ09XbXdzZFlscDlxWlNJd2wvTTZsclpPY0RTVjJDVG40VHFVdG9Td0pJalFha0tsMDBqNW9kU1MwODJEanFqREtVcE4xRWNGR3IKdnMyaXprc3hvNXRFWFpqUWxEeWQza1JoWms5MU9nemVsbUp5NzRXaFJybThJdWltVU9kZFhCbHdhY0JzMHZyMllsQjM1NzNDOW5DRgptWVZ0OEpvWUdVMTNQVGdFYWk3UDJpRlE5eWpqRTMvNmNjTHVoWjkyYmVxaFR6OU9TRzM0Tk1iM21qK3hweDh4L1E1Nit2bVROM2dhCmZsVjZZNmN4QjZKbjhNWk9WelpsbFk1ZVZZOVZ1ZHViT1QwWmhHN2ZEblA2RVJicklLZVgweW92NHZSeUVqQ0kwMXkvSE53MC9od3oKdmVmeGJBMzRoazF6cTVJdjFqUzZSeHBIZlZqVGp0TnQxSFJYQ2ZraFRXL0REWnJleHVCTUw0Y21BaC9ORUdFYXg4QnpiQTYvN3EzcwpHRy9HOURFY3hQUzJCV0U2NzZyUEFFekhxM2p6cFZFTTBFZ2pGbDRhU3lXMkZ3cTY5TU5ZWktwdnVqU09rTnVZZ1pjV3BxRG1nNWZHCkI4MHV5aSs4OUVOSVl5a0hMLzA3SnQxcVQ0Y3ZEVkxCbU9aOTd4RUx6a2RuSGovdzBnWkhiTHAwRG1MMURaZkdLcHVwaW1CTEwvcXEKN1Z1d3BURVN6Zkx0alphR1o4Q0tkcE9sSC81a3Rab0JEaW5LeHovT3p6c0dXUnBlVVowenVBd2ZreUdHTHZiaTNHaHBPUVhTQW0yeQpOSW9sQVVFOFlHbmNxbVM1NHFPUGdHcnpGMVk2bTBpd3FkSm9TUDgwZ1NKSU1NQ3dKVVhSeFpTR1lLUzcxNEpHYllqcmpOVlE1Vld6ClJ1Y0dTcE0vMmkzR2xQNWJsV3liSncwRDVTQTNUaHJIS2sxdUZJVHp5TkYzcCs4bHlXMk9ZOTBzYWJpRzNiMHhpRlZoZWZqVXRiSUsKa05EWGtiKzlRTkxiR0J4cEtDSllUeHdZYWQ2aVZOOFVhV0pPeWpnUTZlS2lwTTJReGhZTStONElhUmo1VUlJZ0RTSENNK1lCU09QcwpyVTNaSlk2NEFBNU5RWTh1UzRqaURZK211bzArNVdGSDE5RG1CRG9hUlJOYy9nUVJHalFoeWlGdWNEVFdHTkVWazhiK0dCb1pzTkp0CnVLblJ4MmhvZEZ0V1h3UXorb3RUSFQ0M2hpQmo4aTVtdFByeWpINlkwZFRKc1d3dm1ORlVDRkltZnlHajhhRXlGckNSMGRoTUJPRlEKV0FGanpGalBSWXltTVYzY1o3M2NlVzFnZEdJQmFodHZZRFRlTDNJRXJoMjcrb0lZR00yL3AvbkV6OEd0RCtsUk56QWFNa2psRWdNWQpMVEZTK1VTTUp2U0JSYVZCaktha2tzSEZJRVlUNnNNYytrMk1wbFVNWVJPaitYaEdiNGNZVGVrSzgyNDNNcHBxbFZibVJrWlRxY0p3ClZDQ2p1VWt5WVB1dzR5Q3ZaN2c0a05GVXFqNnRibVEwVkRpaUZ0N0lhT3JhQlFNMk1qcVI3Y3NDQXlPajhVNktmSHNqb3lsc1pwQTAKa05Hd0VJS3dtZEZpSTVtVWZmb0ZKdlZYMnNob3FJK1VPUXhrTkhYQ2pEM2Z5R2lxeXhoaURXUTBHMll3dm1wa05BMTh6VzlrdEdScAovUkNqYWNDU2JST2pZV0hkNEFzWmpVc1MxRG1RMFJCcUsrWWR5R2pLa1pSN3ZaRFJiSzRiM3hGcnJSbTdVa2JReUdqRUpab3h0YUdXClIrQ01NZHdBUnE4bW9ldm1SYVBObnBvK0hsNzBhbEhHYkdBME54b0hGNDJqRU9oNTA2TFhqT2RxV0RRRGJvejhCaXdhbDBIUjF3c1cKaldLZ2lMS1RGWTFPN3VSckJpcWF2RjJWNGdRb0doRlJkVUUwSjNvVzRmdzJKcHJhbDZ3dzg2WkVvMCszMmo4YUVnMkRHSjFtUkdPMwphb3owUmtRallxY2laUk9pR1JTa3VpRUkwV3p5emJ6aFRZam1GZWRIU1EzbHBCNzNpTnFFYUZTOTlqcSt2UURSeTVXdG13L04xdHJPCmV4QjB5Szdmb2pkdk9EUnN4UlhOWkVQak1Bb0pDdzNOWHVDUGtKZEJoazRVSnlUakdOU0VKaWlvZ1liV1RPS09pQnNOTFE1Y2NUOVMKZGpzamIySHBXQUtMZ0pyQXNmMW1ROFBxQW1pem9XbEJzNWRnUTlNUVVPbk5ocWFWdFVuQmh1WVAxQmtrYUhqalRHaXQrZTNGaGtiQQptV0s4ellabWFZTUt1cU1BQkZYTi9HQnVPRFRMS2FoaURqZzBLaFNFN3dvNE5HK1FxaXd2T0hSUzhmdjZ0dUhRN0xmTkFIekFvVm5iCjhKZ09zK0hRckM3WldHbkFvV2xoSENqZzBMU29zK0lGaDZZU1ZTb2wwNkhaVTZpNXBsS3lEUEFpdXNzSU54NWE2bFNTMDQySDVuYmsKRXdVZUd0T1IybnZmZUdoNk5XcDFhRHowVWJFR0hocVdHcFRualllR1ZVNkg4ZEEwTURvWmVHaGExSHpxd2tNekZzZXFVTk9oMWRuRApNaUNoZXhCbTR1QjJBNks1T0tKQUpBalJpZEJmWS9ERmlXbHVoZjRpUk12S1Q5ZUVhQjVMOWFzaVJNT2diZzQzSVpvdFVpaGFDRUswCkZnRm1SbXNwWE1aaHFHOUN0SXFubW5SMVV5VTl4WE45SUtLNVlKa3UrdCtJYU1xMHhaTTNJcHBLYm4wV1JrVFRvZy9nWWtUVFN0RkYKTUtJbGxjOW1BVlF2d0V3MHVCalJFc2JyY0ZwTnd4OVpKdEVURWIwVjd5OUVOTDFDOW04T1JEUnVtUVNGZ1loV05PTVRJWm9SRGRYVwpHaEhOY0FhbnVHQkVLOERSamU4SVJuUTY3VXpNaUhaMFpCNUdOQ01xTS9BZCt6Yy9ybEorV2pDaTZRVXF1UjByVnN5dm54SFJXQXhJClNCSWNTVmJhcUFpVWlHaVMyWko3S1c5RU5BTy82dkpnUkRSZU13SW9naENkV3JUTHZRalJMSitpeWlZSTBXd05LSTJRQ2RIMDVIT3EKYjBKMDJvS0JJRVRMY3ZqUVgxY0FlMjJBMGZjSnVYL3dvWkVFWk5vdThOQ0o1SXRIb0NQNWQ4QUJrdmgyODZGcHBUVFlmR2djWDVMegpBRVRESWxuNkRZaUdWWEptODZGcFVGclFnR2habVBDNkFOSDRSYmFtQ2o0MEVwUE1Cd1FlR3BtOGdQZHRQRFR6a0N4VENqNzA2dFk3CkJ2WVpRMXdrd1RZZGVwVEl5TnJZbzhOd3NLRTdxc1Vka3Qxb2FCZ2ZzNXM1czhBZzFJN0IwSkJTVDBXd3RtdlBkcHJVV1pzSzNhUFUKTkxicTFSbXNtd25kM2Z0Nkk2Rkhjc0lxU00vb3E4MHA1Z1pDazZpODZqR3lOM2FUUHB3NDZHMjRhZERIYUJqMDlIeStJYytBT2FtQwo2MEpCaithdytONnFDSHV6U2REYmNJT2dqMUVjNk5HdFBnME1OS2dTQkx2ZEZPaU54QTRJTkVMUFRBa0ZBeG9HTmErN0VORFlMVGpPCkRCN04wTzRFQUhvK2Z0MXYvdk9JRmx1QmZ3YkVSWDBEalg4R3RVUjB5b3YrVFBTdkEzU01wMndXY0xDZlJ4SlM4U0kvdzdRc2V5TUUKQ0lZYURlSXh2UXhEbUcvczgzZ2luV3ZxODNCRHBBMTlob0Yxb1RmenVkc1AyY3huQkVCWm94SEk1eEVmN1VFK2I2UmFFSjhCWldOYQpPSURQNElSdUZuWmdpV2tzTWpJaGo5M0VBalh0K2NNZ1R1Rk5lKzVKZVYrem5oR1FaVm8vVU0rNllCbnVYS0Rxd1FMMGpIUzMrbkdaCjh6eThTbjFobnRuM2VkVkRlZTVhZVczR2N3L0k1bzE0NWluVkEzakdEV1lGalBITytMdll1MjFuSDJGK0F1N2NBNmtiYk9mcktKdnMKM0NNekdtRG5FU21rb0RqdmNlREdPZ09ZcURKZVU1MHg1cVViNFR5alYrTE5kSjdkWXZTOTFUS3lQWWpPa1BJMWs1b0Q2RXk4NWF5SAo1d3hEOTAwa3pubUdoT1RHT2MvZ1J3Zk5HWFVPVE00RnpCbkVhdmJqdkZET2k1SHNja2pPV0NvejcyV1E4Lzc3NWpnZm96SE9RTHBFCmYyRldiczFpWXQ4TmNWN0JTUXFHTTlhUyt1cUQ0WnlvYlhjenU4MXdobFVMbUlpNlVYMURrdWJPcTJONVpEanpidUVMYVJPQlZJRncKaG1Xd2ppQVl6dHlHSC9waE9HTUcxZlFRREdjMGVIZXBMdEw4V05Qd2hiajV6UitYUjY3SXhqZnpsSGgzQTkvTWd2NFp2T1ZkUkFLbgprUmNkL0daVzlFOURzTlZaTUVYWDdadmZ6R2ZKUWduem0vbEtOQU9pSlY1T1ZqTysrTTFzRXhsWG9GQTNQRDBPWlFZNGYvV0RmdnpoCnZ5akFtWEZCVXE1dWdET3RsRGdFd0ZuUndwSVBzSmxoUURXTHVCRE9ERmRSSHhRSVp6eFgvNElSenVBeDhnVzVDYzY0Y2hVWUJzSDUKckdhRDRLeHZlbW9DUFlGWmRueTFENlhNV283Nnk3WmpsdDNPU0h2RkxNVmgyUVJuR0tRYUNJSXppMGZWOGVFaU9PTXFwVTRMZ2pOZQpPMEdiQXVFTTEwNkNzcHZoZkR6WVlEano5UXlwaGdnUFpGSU1wYkEydy9teW11SE03cjBNL1FmREdSYkp3MjZHTTNFUFZCd0Z3emtSCnErMEtldlVTaDZDV3c4dk5jTVliYXpXR0djN1U1YW42MVF4blBGK1ZJOThNWjFTbmtlZ1ZDR2VVYWdtWDdnTHI1UVkvTDRBejFHWEIKbDZmSER6ZWFRMGZ3bS9HZWNIMXk4NXNaNE9Gd0hmeG1CbmpFSmZCb1FVdHpEZWlwbHFMVnJYMnA0K1N4V0NRZC9HYitaSlp3WitPYgpHYWlNWnZRcU9Yc2VSUUUzdm5uTllHd2ZlalBLYVlSWE5yeDVEcTEyTjd1WjVUVTg4d3Zkakc0d0FrR2IzQXpwSkN2MUE5dzhvdkx2CjVqYVA3dUV4c00wamlwZUQyanppNDdtb3pWallMQ09hR1JRWkp0c0dzaG5rUE03N043RjV0Q0JJR05nOGhzdWlqV3NHSW94Qm1rTnIKUnRzWURzMUJhNmFzZ2lYL2hqVjNCeDlmckdaUXVoZzNDMVJ6TDI2OVkxQXpzVjVENWRDYjA4eE9SNDl3enJ3c0hJYXZZRkNhMlgxKwpLSm04MDNJOUtvQ2p0SnBpUDBNWVdCZUpxNmlQR0FrYjBjd3U3MVdmTlFOUVNOVHhXd3BBTTZocjlFQnZQak95ZHdRakI1NFpFQUhHCnhJTE9YS1A4OUlZelF6WTFTcWp4SVBNTHJ6RFF6TVF3ckZCM1dqUU12UTlMNHdQTXpGWmZ1Und1TS9qQlZCZmRXR1pVNEdxTllDcHoKYTk0cW9NeFlGN0hFOEdZeXc4Z0ZTRENaSVYxcTVpaHoxUXh4azBpSkY1SVowd1RCOUVGa2J0V0Z0ZGR1cW1pOWVjeGNpaEhnWUc3TApYamNFanhuS0VzN1NONDRaVjhCZkN4cHptNmU3TnljVDFGV0pvSDNCbU52d2x4WXM1aGF6VjZDWWNUN0ZqTWFkQk1lc3dnS1RJREZqCktocVhxTE5OZDd1NE1jeHczclg4TjRVWnB5WkloQ0hNRURuTnRGNE01aFdMdEdBd3J4YTk5NHhnWHQycDQ0dkFEQzJ4Q21rTllGN2QKUHg3OFpVRWJ3ekMzVGxqTm5BeGZYczRGYlBZeURQRmJHNzNNUkFmWEJvRmVqbVRFSmk5RDVFWHF4dzFlbmlNNktwaTd2QUt3R2RqbApGWUh3aTdxTVJJdmVtNzRqOHNFY0NEVXoxeitVdzkvVVpWcEZFN2NNTHBHRGE4V2R2Y2RxanNsTlhZWjFzZUEvcU10a1JQbTlrQ0JpCk4wRzVvY3ZYNFF4ZGhrWG9wb0F1cCtSQ3R4ZDBXU3VmdFE1MG1mbG15azREdWl5UWdaVmxoMDhQUDVEQ3pvQXVNdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJemNzNUxhRExYejNJQ09wOVAranljck9wRjNONUxRRVdObklaVmZPc2p3bmlNcHlIWkFUejFob2hIY09VVWZDV1lWQnBzbkhMMkkwSgpxcHUyek1MWWVsakxLNERKZ1ZCV1FQRmlMK3Q5aGtpVEphK3hHYmlQNUFZSGFmbEtuRjJrWlM0TnFJc0kwaklYWkV6aEIybVpZVTZYCmtHNWNNa09kQWs4YnRNd3pVNWU4Y2FLYVJ0dDkyck1ieXF2KzhUQ282R2RFaVVkMjZjbkZXV1k5aCtxdHpGbm1aUS9XVjVtenZDMDMKWnhrN2ltd1NuR1Y4a2FUN2I4NHl2S3FxcXBXTHN3eXIydmtHWnhrV1NuazNhSmtPT0IvUkRWcW1sNWExR1JPRW9EU296RTJZWlc3QQpSM1pqbG5saWpDUUhaam50bmlTQldXWXBDQWZkQzdOTVkzVVhCdEhVWU5Gc0pjd3lCejBXbzl5WVpUcVkyVUw5b2hWRlVzbjJ4aXpECm9qS0ZHN1BNSmJEbURHT1dFd3ZoaW5TOU9nbU1IU3hkdURITFhCUlREeDJjWmF4a1dRTVNtR1VsZFV0OVk1WVpOeUdwSXpETFhDS3AKVzRReHkyU2pWY3MrVDhROWgxWTZNTXRrbzAxdnhrZWJnd0oyWTVhcEptRjB6SmhsR29xaHlnemdjVWVobmkvTU1qS1d2di9HTEVNTwpvczVOZ1ZuR05ycGhOMmFaYU1VZVF6eFRuY3ZoOGhWc3B1VVl6QTFaSmsyTGxUVjd1OVlzdEEvS010YU5lbmx1eWpMankyUTlCbVVaClBxWWNqYUFzSTNhZ09OaE5XUmJYYUk1RFdhYjJUNStnS2N1MFVFcC9VNWFscE96elVKYkZ1Q0pNeEpSbDdxa3lxNHV5ekJCNXdMWVgKcGU3SnE1MmdMSE1oS1hqNFJWbVdmSExOUTFubTZVZlJLaW5MQ0dBSmYzRkJsbUgwTHdxeXpEQ1hUc3lRWlZvWUVMb2h5N0NLOVdmSQpNamZUdlRCa21jZE9iaXV4SWN0YzNZak5Fb3pMc295R00yVDVHRzdJOG1VMVpCay9vQ2hMd0pNWkxsSUMvNElzWTZrbzcyNXZsNzIwCkNzYnlNVnlJNVcwTXdqTFhjOHJWbTdDODM5Y1hZWm1wWnhJR2dyRE1rbmVxQm9Ld3pPUmh0TTdZZWtsYWwzMUJmZlhJSG5LMUpNSXkKYzREeFp4VFBTS251cDJHdVkzT1dMUURMM0lZcjNodXdMRUh5VElldzdDREhQSVJsUnFybUo4QXlzWjFQam5ZRnlYa2hJaDhDc015dgpMekw2VnplYmFzY2pBTXV3OUdKMWdFaW9yY3FkZWdHV0dSc2ljU0FBeTdSb0hoTmdtUVlKRFM3Q01tOC9NOWFCV0dhcW00SzFRQ3dqCkVLQkt6aHV4VExTVnV6T1FhZ3VWV1ZlM1FCT1dNZGFwdmRsTldLYXVJMGZ6Qkk0Q2NIMlVYVGRobVRHVGt2SWJzUXdybWVBYnNVd0wKSDFJd2xtbWhRUEZtTFBONFZPVUVZNW1SRTVWWHI3aE1GL2E4R010MGFMTjdTVGc0WnU3T2hpd3prZEJHOUdhSW9XZGJBN0xNR1c3MQplaURMdkdmc0xYOVRsbUhWaXhhVVpWaWtsQXJLTXJlaEJPcW1MTlBLUnhXVVpSSDJSaitVWmNvSTFjdmpLbm1qTkpMMTFFRlpobktICnc4cW1MRE03UTRmMnBpd3phczJLKzZBc3M0Q1hDc1NnSjhPZFlJdXpGMldaSzZkMEdWZW9NUUxLdVEwM1l2a1lUYUpDYnh6eGNneFkKL3VMVmY5ZUZBMi8zMHc1R0RXdUd3cHVidm0yOE1wNXdtWHJFb2l0M2R4dDd3Wlc3bWF1YnJkd2RNTjVvNVdsVXc0dXNQQjBaM0lCawoxNmtmc3ZLTWQrNEdLMDlHNHU2OXhNVGRWT1hwOHBJWFZCbEZZMVErbWFuTU42VGxRQ3BETmNKSTlVMVVEdER0QmlwRHU4VWhMVURGCjJmV3ZOMDhadG1uR3Nwb3VkUEYzQXFiTVBOSXFiNVp5ZHVYTVppbkR3SFphZ1ZLbXB0NGg4UTFESTUwYXF4aWhsTkVSWTZ4MG5lQ0sKdGU4RlVrYmhBc0d3d1ZFT1BOTEdLSmRvOUh4VGxDR2NZb2c0SU1yVUI5ZDVHTXJBSjYwWFFMbTBjQ0xOVHk3UmxEZnd5VXd3T1FHNgo2Y2xJUXlzN1pYZ3lLZ0thR2NzTTZ4WFRPbTUwTW15azhRVTV1WVRRTDhESnlFa2htdkxpSnFNVUp2cm1jbnBGcWtFWlI3OUJLRG9SCklmdUNKdGRnT1FZem1WRzlOUTR5R1hvUFpvbHZZaklTT1BTNkE1Z01DVXEzSTA5SlViZDI3b1ZMN2srUUVFMUx4bTZNakFjc0dRZG0KYU81bUpUZEwxallxdVVYUHpTQWxOODlTTDFJeVd0eEZZb0drWkdoWW1Pb3pKeG41NTZGLzM3TXBWMW1QdmlHc2ZvZEpUTUZJUmxmMQpyckQ0cnBqQXNpK0hiQXNmeXpBRmEvT1JzUmY3b2R4NFpBUmNsRUUwSFJtT0FSbnNBVWVHdms0bExSY2JHZGZhWFF0QlNDb0ZLazBCCmRRYXFJRDFnZ1BrR0k2dGlySDdiWEdScUJwem1ZZWF6QzF6eGdpTDNhQWtTVE9SZC9oNUk1RzRveG91SXpBWXFQSmFCeUtkWTJUemsKNGdMWUZ3NjVCaDR5YU1nZzlETFZHRERrVmc3b05WaklCSzF3eGFLSy9CWk56NEtFM0VLdGVvT1FZU3pFR1p1RFRQWUsxeS9HSU9PMwoySmJpeGlCWEYyTnNDaks4TkhXR2RDS1N1ZXVscGRkbUlDT0x3Ynh3SUpCQnRlRjNGZ1RrRW0zWGJ3QnkyYzM3ekQ5R2hZWkltc1lmCmsyWm1odkdtSDI4WVVjQ1B5NGlwejZrNUdBaHF2ZEhIZk8wc0RlTzhBclljNWRzQlB0Njg3NXQ3akpveTFSdTZLS2RrVDB1aUhtY2sKcEl4c3Zwb0xPVTRWekdQa1padTNVaSsvTGhibkRUek9YYXIrelR1R2dSQjk0WTV6Tk1hOGFjY2YwenlyQ3cvc3VKb01HYXpqeGdGVgpOWDRiZGN6V0NtSEVYSWo1Z1VXdVFUckdPNTJOSzk2ZzQ0Wkt0NmVlc2tJTW00T2ZrREhIaUM0OTVpTnZ5dkZpTWpSOTI1RGo2azdlCm0zRThWQUw2Umh4L1RKakxnamNoanBPbjVTQWNXMmY2NGh0UExxTnN4TFFsR1o0b3lNeVNUWUo5bmJTTGRURmdJbWxKVVUyNDhmUkMKTHVER0VTZC9vNDJsK3pwazR4R3RDZ3cyenRIaTlzVTE3cXF5T0ZoakN4TTMxWmhKQUpVcEhxZ3hreDVSbFlqRnI2R2ptMmlNdHlJWgo5TENCeGlnSlcrWTZrR2VNOTlrTEVYMGxIUHUwcHRrMDQyS3ZLV0RHT1h5QVlCbXpSdDBqYnFDTVVlL1dWVzFKVHdtTEdyNlNtMk9NCmdqT2psQytNc1NYZFFURnVEQktrQXpIbXFvcGxxamZFV0FxU1VRN0VHQkhVajNWYVB4Ump5am1mc0lUc2lWclIySTQxQkxEVTZuSXgKUHJpdi92ZjM5TzR4K281WVNKdGlYS2NiVGdiRU9GaGxtMkhjY2tocEw0UXhBZ2pGMUVsNjFjQmRVTTBUQUdNU09Lb05JWlVIOGtKTgpndXRtWUFpcUd2VGlscDNKdTlqRkxiUUZSaGNqM1VxOVo1Q0xrYU9VQnZ3Q0Y3ZG1mSTlqNTFDTDBzTXhrUmo5aHlPeEY5amltU0s1CkxCc1JzWFVjYVBGS0NpQzhtTVV3c21vaWtNVXIrbmNFc1JnZ1YyK3dYZlNWUEtjR3JoakZXQXJlZVN2OEE5TnhONng0VHJkRURsYngKcHZNR2doaG9DcnFYTjZsNFBQWm93Z2loTUhOeHdTbmVoaHRUSE1aTktSNmV3VGQ5R0NKZXJuNXZTREhFdHdyazJEaVQ0YVJDRko4LwpMMEp4R0RlZ21IRGxWUStmZUFSVzVNWVRRNHdzTXBEcHhLTTVZeDEwWWhpbWVickhLNDFlMzhFbUhxRk9DaER4YU01aDNtUmljS2NDCmFZelhld2IyUDdqRStHdzJlamV3eExQWm1RNHNNUTNsd2hJemZwM2VVT0laSkNjemlhZmJnUVdTT0ZxSDMwQmljQmlWblRhUEdKcE0KSmhxTkk0YjZrdmZ3cGhGdllGYkFpSWxjWkRyTUxPTHBEL1dGSWthcFVqSWhORXJuMU1RMFNNUXdaRWZQTjRpWVJzeEV3U0VHMDRrSwpFbU9JVjdFRGVGT0kxOTBXRVI0TFVjOGpIUWd4Uys3eUcwRU1QQmREWEVFZ1J2cGVsUm9HRUVlejlSZC9lQVpITmZERHk4dXFUUjltCmxTQnh4QWMrYk5iMFJnL2poRlkvNE9GVkpObDljWWZ4dWJGWUxyRERLMHBoZ2pwOEhXWXpoMmNrWkFNNVBKMmEybnpoR0FaZXdHR28KWFVVME5tOFk1TEErTG83d3FCNUxiOXh3RC9adkdKRzFacXc3WU1QVW5NLzZaZzBqZ2ZTNDZUQkNIZmc3R1VnOEpjQncyZlFGR2taaQpLa3FuUlVOOGxIVFltR0drdUpwNzFXMHRUM2VnZTBPR2V4U1dCV040RzI3RThER2FNTndOTjlwOFd5eHBrMm0yR3pBTUtEN3h1VjZRCm9LQXAwSXYwVktxTDhsNXdZWkNqVk5SdXRqQldQQUpXR2kyTXRWQk9iN0F3VmxPcDlNTVZ4cG9yOE1QOHlxckZCQytxY0xNb1kwT0YKZ1JscTdTQ0ZSOUN0RDFFWWdpWWlKUU1vekxXWlM5dFkxa3h5YVpsdm5EQzlzZFFPVFZncjJYNWd3bHpyanZ4bUNXTlZ2SXdtNXEyRwpRUVg5UmdsWEt6TmZKR0VBcE9LOCtYMUVIbXh6aEQ4N09qOStSeWZxLzM4WTRTOTQ0RDl5NVBydDcvMmozLy8xZldBYzZBOS94Zi81CnMvL3JMMy9SRC96MGg1Ly85SC81NWYvVnNkdno3ZS85czEvKzdDOS9ZNi8vNFM5Ky9kTi8rc3RmL2Z6TDcvLzYydjZQL2NZLy9hdGYKL3ArLytPVnYvdlNmL2VGdi9yM3B4MUczOE1kKzRILzdpNDlUK3A5KytZdC84Mi8vK28veWttUFRQL3k3UC8yNFFmL2pYLzNoOS8vUgpiWC82NVYvLzlYL3l4cmpJajd2eUY3LzgrLytNYS96eEQzKzVyeEZWM1IvRDR0OTZqZi83WC96NVgvL2IzM3lXLy9DSC8rYnYvNlB5CnAvL3c5My91L2ZCM3c5OS8ray8rOFB0Lyt2R1MvZlhIZS9hNzM4bjhEMzc1TngvWGRmM0RELy9rMytGZnB2N2xIL3pWZi9qMy96YU8KODkvK2sxLys1cHYvK0piK3V4K2ViMy8vNC8vKzVkLzg4QjkrZUlHaG4yLy84OGQvL044ZnByLzVWci85NDIvL3gvLzVmUHR6YlBuUApmdmpkQktPUS8rL1gvUWZxZ3JDUS93a1cvRUZ4N2g4emYrenkwMzJjbjM3NC9jZXgvOWNmNEZ3endmVkFmNWIxSDFoK1Fwby9vTndGCkRPaGp5ZmV4OHNKL2ZJekRuUmJHNXY3bG4rR1lrTkpYMUgweGlKVSt4aG1lSmNaM2xHb2ZNNHhWMkt1SkFNTEhEOVpQeHE1MmNELy8KOERZREZmSHhDKytqb3BqbFkreDVuNEdOT3NDUU9QNjlyWU5QNzZNZTQrc01qdms2MjNQVTY3cSszSU9mZi9qWFB3Q3N0T0JrZ2lySwpmQmpVUFFWVEsybmhINjcyUkluRXgvSVhtWEFVSUMwVWNYN2MxL1I4KzhmN0VjS1BUY1FuUDM0Rk9EdTAyd3dqWk1YUUlLcHIyY2RNCjlEWW1wVDk0YVpmNUVTWGlkZFNQNldqaEpYaWRRUmgvL3UwVCs4dVBLNDUvWVAwVEpybE1rRTRjdTl4bW53V1dySk5GRkwyblQwYnIKaC9ZWjIweVFWLy8yT21yRGVxR1ViNjh6Q09QUHYzMWlQdVAvK2dMLzhSZTR6cHBOU3B1TXBIeXN1NEd3UVRGQnhidjdNUTRRQnRpZgpnZGc2NFFFWUxEUTJBSE9ITFA2blcwdEJSV3J2VTRBb2dVdWkrMlF2NDMxaGwvbmNoT3VvNTNaZFozRGYydWpmOE41MmtxdjI2YWpICitEcURZNzdPOWh6MXVxNHY5K0R2T0RiOGpxY3lRTHo3ZEY5eDJ0QnJ2SDRmRjRnby9ldE1MK045VlpmNTNJSHJxT2RlWFdkdzMxZjgKQkZ6bjk3YkladVpQcit4bGZKM0JNVjluZTQ1NlhkZVhlL0JkWGxsMjlYcmE1L0VMZ3c0cTFsN2pWMlBZcXJ6SHI4dDRqMStYK1l4Zgo1NmpYK0hYTzREVis5U3hGOW50YmxuWitQdW94M21kd21jL1pucU5lMS9YMUh2eXNvUkp6Q0pRK24yNE81cENuZkRvSXBvdktMK1FlCjNJL3hOYmdmODdtTWM5VHJnczhadkc0T1pyeUJRT0pyVy9MKzE2ZWpIdVByOFJ6ejlTajNVZStIL3VVZStPWmN6KzJlcTY5bmZPYnEKOHpaY2MvVmx2T2ZxeTN6bTZuUFVhNjQrWi9DYXE4OHp2cmZkYjhOOTFHTzh6K0F5bjdPOTNzZHpYVi92d1pjMzUzVnpybWQ4T1RMNwpiYmdkbVdOOE9UTEhmQzdqSFBXNjRITUdyNXR6bnZHOTdYNGI3cU1lNCt2eEhQUDFLTS83ZUQzMEwvZmc1ODhlU0dNZmkvYlpBd256Cnk2dG9UTEYvY2tzdzIwaVA4VFpia1BjK0trdVgxbnYrRCtNbkQrVGVkbnNWOTFHUDhYVUd4M3lkN1RucWRWMWY3c0hmZlpvOFUrL3IKdmg1SDRmcjk0MUpjWjNvWjc2dTZ6T2NPWEVjOTkrbzZnL3UrSGtmaDNuYTdGUGRSai9GMUJzZDhuZTA1Nm5WZFgrN0JkNWtteit6Nwp1clhIVjdoTzRYZ1YxOGxleHZ2Q0x2TzVDZGRSeisyNnp1Qyt0Y2RYdUxmZFhzVjkxR044bmNFeFgyZDdqbnBkMTVkNzhIZC9aYzluCmdFOW5sQzlEUVpoZm4zZEhxWW85Z21Qc2dvRjhHZ3B3cVBxTTkxREFaaGFwdmovRU1INGFDdTV0OStkOUgvVVlYdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJWjNETTE5bWVvMTdYOWVVZWZPZkZ5T3ZXbnUvMk9vWHpoVjhuZXhudkM3dk01eVpjUnoyMzZ6cUQrOWFlNy9iZWRuL2g5MUdQOFhVRwp4M3lkN1RucWRWMWY3c0gzWEl5ODd1djVhSy9mUDUvM2RhYVg4YjZxeTN6dXdIWFVjNit1TTdqdjYvbG83MjMzNTMwZjlSaGZaM0RNCjE5bWVvMTdYOWVVZWVHb0hXUWdKbkU5K3p4QSsvNVB6WklYNzI4MDZ4cGRMZHN6SFF6bEh2WHlaY3dZdnYrZnJpVGtjTXI2NDl6eHMKK2JUMjRRbG8yMnMxY1l5dmxjY3hIMGY4SFBWeTJjY1h6LzUxT2pqRmY2NVE2ei84L1orL0FxMy9LZkhYOG5lTHYvcU9mUXJDbmxncgozckEvWW94OWYvcHl0Qk9LL1RzSEMvSHVkcTNlcVh3cForN0lqUFdGMmZNQmlKVmVaNmYyeVlnMWVXMW43ckFaNi9kUnY3MlAycFQrCmY1K0JqWHZ1V0dOODJuWkk2ZjArNmpHK3p1Q1lyN005UjcydTY4czkrRzV6Qi83OTA2MmxOMUUrblFMOURyN1kxOGxleHZ2Q0x2TzUKQ2RkUnorMjZ6dUMrdGMwNjIvZTJVMEsxOTFHUDhYVUd4M3lkN1RucWRWMWY3c0YzbVR0WXRmSHB2dkswODZkWGxoZFlQcjJ5bC9HKwpxc3Q4N3NCMTFIT3Zyak80N3l0K292YithZHRwS2NQcnFNZjRPb05qdnM3MkhQVzZyaS8zNExzRnNsQVo1ZEd6ckJPT1lJdkFiZjZkClJ0dzhhZ3ptWlh3eW1oYTh3eEUyUHlvWWVSMlZnM2VhMzE1bkVNWWRqb0JvOGIxdGtScjJmZFJqdk0vZ01wK3pQVWU5cnV2clBiakMKRVUyZTczMXpPSmUyVHdmaHROblQrK2N1NDMxcWwvbGN4am5xZGNIbkRGNDNCelAvbk92VHRrVWxZZStqSHVQcjhSeno5U2ozVWUrSAovdVVlZkljVjkzNDVJbHQ1V1R6aHYxOUN1d2J2aDJYanA5ZmwzbmEvQXZkUmp6RjlmbGZIU1ZEdFJ4U25lRm5Pd2E1WDRmenNkY3Z1ClU3eHU3N1h0ZmhEM1VZOHhmWDVqZklyZjhjT1BYL3YwNFlmNWRZTjREYXQrTXZwNlA5M011RGV2bzM2S1Erb012c1FoOVNRL3hTSDEKME82akh1TjlCcGY1bk8wMW5KenIrbm9Qdm56NHI1dHpmYUxuSU9mUlhEOTNHZTlUdTh6bk1zNVJQOFVoZFFaZjRwQjZoejdGSWV2bgptM01aWDQvbm1LOUhlWWFUNjZGL3VRZmZZU0pQMGkxK3VxL1YzVHZmOTlYZDY5NzM5UmhmOS9XWXp4MDRSLzJVcU5ZWmZFbFV2MC9zClNsU1B2bGNYTVFYZzJDbmZacDlGbiszVEZIQ01yeW5nbU05Z2ZZNTZEZXZuREY1VHdOY1QrejdEd3ZhTXcrWDd0RG9JODh2anB5Zm8KNU1BeDJoUDh0RHFRMzdxRHpENnFQZHozR2RqNGFYVndiN3M5L3Z1b3gvZzZnMk8renZZYzlicXVML2ZnK3dTWjVSYS83dXR4NHEvZgpQKzcrZGFhWDhiNnF5M3p1d0hYVWM2K3VNN2p2NjNIaTcyMjN1MzhmOVJoZlozRE0xOW1lbzE3WDllVWVmSzhnc3ozajE2MDlmdngxCkNzZmp2MDcyTXQ0WGRwblBUYmlPZW03WGRRYjNyVDErL0wzdDl2anZveDdqNnd5TytUcmJjOVRydXI3Y2crOFRaTzRSaFpzajljOUQKUVpoZm56ZGpZUG5UVU1CNFdadWZod0ljQ28yRTNrZEZGTzc5R2NyMGFSZzQyKzBQK3o3ZU1iNSsrNWl2OHp6SHZLN295OVYvNXhEQgo2NmFlTC9ZNmhmTnRYeWQ3R2U4THU4em5KbHhIalp0MS9mNjVxZWRyUGR2dHIvbyszakcrZnZ1WXIvTTh4N3l1Nk12VmY4L2d3T3VPCm5nLzErdjN6U1Y5bmVobnZxN3JNNXc1Y1I0MDdkZjMrdWFQbkl6M2I3WS81UHQ0eHZuNzdtSy96UE1lOHJ1akwxZi84bngvOS9PZS8KLy8yZi9mckxuMzhicjhqbmYwYnNzK1lGYVMyazV2Z1BNR2wraFJXNE45U3pIL05Qbjh6dFk5SFRxOHpuR0w5dDNZZjRQYy90ZXdoVApYK2N5MUlKN256bmNRSnJseThrNGJIdjZyTGExNTJOaFFXTjZxRytYbWJXR05MTkYrK2NyOTYvOUJEK3pFdVVHTGdCNmxINmNlcDgrCkRkUzNmTHpxTkpQQUxDUDlRUDBrcWdwa0pMSkJQemhMbk1kZ1AwQnQybVAzanlGcCtkSlFSaVBqeHdyVXY4OWF2OWo5K2ZnUS9mc2YKYjVvdmVlMkRLdEl2bzI4TldSQnhGOWpTeDNjc04yL0ptbTM5UHFveGZMOHdubXJMUkxxbHpPUWk2cmJnZWZxazBKRlZScFRmK2FxZQpNSDQ0OXVmeTBSalo1Lzh4SHNlbWJYai9jd00rUFlBZjlXVHl3dzVpdEdmMGF2N1ZWcmFTcHJVcGxDL3JTUDQ1ZmVNeXJoWGI1dDYvCi9kWlI0OWZtbjlUMCtCK2VqNFdCZjI3dTE3R3JlNnFOV1FjQjdHcHVtMTREZzBGL2pQM0hpQzJmN0UzWnhVZkhaSmp4dDM0L1Rnek4KWVBTRTBXYWtGcDhZY0p5NnVLWWlVaHRSKzJmamFtRjhZc1BGK3h1YkxwOXY3M3QzRkJqS0JvVDJiLzcrZit6NXNORUt6ZXhuRUErSQp3RlZ2WGVOWlZML1BiTGd3LzdZSDlBQTNuUDJkZmJ4YU1kS2gyVW4zUzQxMXFXMTdhR0R2WEJqQjBXditKTmd5N01mWVArVnNNMG9DCjQ2RHhwZGFoczMzWURPTExkNzZFRHRQdkkxTm8yOXpuMVBmdTcvUDNoU1hVdHlYZmRiYUEvelhNVCt1WCtTZWJpYXlSK1dNMStzM0cKN2tmTTFoTzJvUkJkeGhUajQ5ZGY4MEFJTGdES1RmVVBZTjM5YW5NQ25rU0h3WXRnWTA3K0tqaDgyUWpJc0o3YzhnY0FhNHJ4TFkweAp2T25UWTNRaGM4REc5SGgwWUdvNURoQVBzK3RSeDdZamJnNGV4bTlld1hsMXh0TThtTEtUWGJ3NnJGV1Z1UTNQZXl6STJXYmdER3ljCmNjVWx4dU12eDQxSE9sV0FyWnUya3VlMlpCcTB6TlgzY3FvUzA4K3B0REEyRHpDRFk4RW40OHc5NzcxekdOdGEzMzd6NTMxZTZBUFMKdTZiMDUxRk14ZGJxTDRQUm1EQjZXbGdqNVczci9nUldxejR2ZHV2TVBmYlhKNlFXbmkxKzY5ci8rdms0cmUxcGdEQ2FQQVV2QUJwawpiQ3ZHRVJobjgzTm9WWGVMeHNldkNFSDhYNHhsZVdiODhsdCsvUWtnS2I1bkJYbWlYOFA4ekI3bXdXdWpjYVRmTU9ZUnhuai9VWFpaCnVzZlpqS1lETm83d3VQQ3AvT1lKK082d0VWb002dXlTK0t2Tk9SZWZCRWtZTXNhOGp6ZXNaaHViUHhaOGJUNHhTYTFHekVJbE52MVkKVmVUM3JQTDFCTTUzeFQ0akdoTFgzSjhWdTk3RWlOajhxYkFOaDQwbHZwK1AxN1Nlc1ROR1ZLNUlQWHBxZW53SVMyMnhxZWJjTDc5Lwo3dGo3Z24vOURXdjlqVnZ6TVhyOXE3amxvNGNaczhwUFlVWnJKcG5yRTNlSHpXTmtMSG4ra1Z1dXQyeXFiU2x2SlNlUlg4T2N3azFnCnRiMk1wTHZLT0hRZldQd2JiZ1lCS2ovK0VPWmNZdHVSWXR2Wi9HTk43OExYRTRneks1TEllSnpQZnBqczlWNUx2RkRObjJFQmd6S0YKZVNUOVhoRml6a2FOUlYrUDZ4OUV4ZmFZNjlyNlY1dkRKMmppSmRyWTloQ3A3K1hEMXNyK3RSYnpHOHg1blRQcnNTMGJHK2drMGd4agppZy9XbzZSL0MyT2dqeHUvVld1TGcyclErWHIrY1dHZ2J6emorckZmd3h4dUdLdWlaUHVZWDFaTTVuT0ZjV3lmc1V3UFhEQzNlQklzCkU3Y3hMbUZsVGE2d1BUR1FrTXo3NDIrZmxrZStpYTQyc1lDaDkvQ3J6ZWxKSHRXSEozNFlTN0ZuUmVLSmpSNDB3TGZ0OXF5bWNVSTYKYnRJUzRzTlllNDhmKzFqU2Yvdk5NN2g5dnZnNStORXh3SEM5ZHp3NUcvTzR2TFBmSGg5c0JZN0wxaGJ6ZTdncDJIL0ZvUE5IUEw0eAp0eU9adHNjNFJoaWY0NGUrVHYrOCtuUXFOUkd1dUs1b2R5TnppMitOMkM5TjhaT1VjZG02YjRHUDhKdUg5ZStoajBiekJYOThnZlpHCjBPOWlMMGNuOENRL2hmbXA0M29ZUHNLb05ZeHkrTDRjTmk0dmlZYjErZkt5ZUFOeUV6U0N3N2E5WjFJeFpVdzlKaEIrS3ZFQ2svUW0KTXhhQk5xNjhEMURpQVBtSjUwNmN3WSsvZlY3bkN5QSswUzl3S2VjTHVONXJyV0cvdnV6LzZtL2Y5blhjZi9IeGcvLzlmNkFmZ2llNAovQVRwcVB4cU0yTWtOc3Y1WEJoK2l1OStEQk5zNFJhL09CNnZ1OUVldWxhL2NzUjdhZE0wVXR5a3NjSklKaFYvS2NXeWNMSi9RYnlECm5uUUFYdW5KSHdJYlBNaEl1SitNTlc3eVhBcXY2SzE0dFBZaG1pVU93RmZGUm9TRS9aanJPWVB6SlgxNGFIRW5XdzczWWE0bkJxUDgKSkwrcDlrdDgxejErRHF2SlpRelBGWlRPMzN3NnNUdFYxL3FTUGFiU3VIek1qdzh0NzkvM2htbFB4YS9CN0ZrZU40ZldhdlFIZ0JtUwpMVUlzUThRLzdUKzBMS3M3cm1WanhNU2VHbGZQNXVNeWdtd1J1N01wbDNZSE52QW5tL3Z4bjNLT084QndudzVCTWY0bkk1c094WEZqCm1UTGtUc3Y0NGR2NldwTlgzOU5YbzZPMnZUdkRVSDRBK3ZweFVpc21BNzVNY2N6WVhjVE4rUGxZVVFONEdWZkZodHArVzNNY2dDdEMKais5eFRoOXJtSFZ0R0VjbHprbmZ3SGoyK2RkNFYrWlNGQVN0SWVIdzdjRkwrL2Y3dFh6OHJOSERjUHBPalRTbmphM0h3MmE4VUFkbwplOGdmNnM0dTQxbysxK0xRR1VoSkk4V1lXTUpabWVnc0VZZGx1RURHUEZNOGdPR0p0d3FPcnhONHdpdEF4OXhTWXJUSGZLd2JXLytrCjFVOURMWmxLeGMrZ3lBa0NRNzV1WDMrVnVDOVZuZjg4TmloSUFVNVRibkd1Y0VYOFF5M09kWnpIRFZ6TW5INWVYZE14anByaWpXOTEKeGxrOS9VbVhNUTdBVm1lK3J1bTVsQTJSNHoyeUl6ZEpieDZmWHMxOFhRR2ZzUTZicnhlK1o0M0UwKzNpUER3cUxEdXprTXIrcFlqcgpUaEQvWW5BaWNROUdFRnppVko4d3hWZUlTZDhmNFRDNU4zd3l4NFRHQ2Z1TlAzRlllcHlBaGRsUDNyRHVlU0E4eXc5ckhmc3I4ZzM0Clk4ZTBaem5VV0dIdlgrTXI2SzBYYjNzQzdsdzRlTXZWWTJJdXBlOERuQmhjckRySFdSTVp6Z3NqSnJWOUExTHlYUjJhQVgydTAyTWUKZXNpbEo4SVZjdnJIRUxIVkg1eEdZclNUV1BHdytabnBxSWlzeDB6UWNuRjhpQTN0NG8wamtSTkd0SnlJRXl0ZVlZeXFySnVudmVvNQorc05jZWpoTzRTdU84aWZka2VLNWwrTURYWGhqd3h4ZjEyQy90ZmhtS0xxaGtSQXgvNWFtVGRLQlp6eFpMRWgxZ0x5RDgwQnZhdHdICjRLbUhCeDNCWDlBQjkvRFFQbFk1K3dEaE8yQ0k3RzI3amdNZ2MyMDk4dHhtemlQMjBWSTlqdVp2KzUrRXV2ckYwZlNOUTZTMXg0N1MKdy9qRTlORkxPQkFmWmc3bEh2ODFKckt0eTlxdjR6ckdKKzc1TTN3QXRFR2Y4ZWFSOHZhVHpXY0VqVFV2eElNbEZnUGtVOGxJRXBzbgpDM1lvMEFIR2RpSStwb2djQjlnZmVzU1MwTW5RVXdpQXFSRkx3Z0hLZnFFMXJtUFRGZ3VYK002Nm1VSWVKMHJlKzNPNXBQMzdpbTE1CjZSNFVGRHpyVTExdy9JQ3pYeHkwTTZ3eFVueDhXbjd1NkNMZFl1RkNud3JHRGE5U0FGQm4yMVZsWm1PTUlLd3pDLzl3UFRNTzhPekoKVllNcWRpOWxSNEdxWGE3dUZKWEgyaWNlR0ZDdjhTTEVZTjNWZTZxRzEremR0eDlaKzdQMlVjTzUwT3BSTmhMci9FdDZCL0E3MitGYwpaZXpkQ1dDTGp6L3ZreW85bmxlTXk5MWtQRCtESEtmRmhoYTZWNGlBN3VQbUZ0UEZxaHdYZTFPSGFXN0xrVUxHbUxCdnB3Zm0wajIzCnNsdk5UemFIM3oyMVhJQVJoT1BoUmNLSHQ5bHRqRWtmdzBmeE5BSnozdDlvejluYlB2dkQ1UkFJSXpwaHJIQXh0VkNWdWZad01MencKak5LaTk1c0JldWJhazN0NHpwMkl1bmkyOWpyWStpL2M2VjZWaWUxWjVWa2U4Q00yakFPTVdJM0dSQTR1K2Q1MkpFM1BhTnkraC91NQo5MDg3YkFqZlh1NEZhKzduL2tBMW52VUh6YzlqS0NnUk1rRnZ6QkYrVjNPMjhjTTQrZ2x0K0t4Y1Z1YlpjZFo5Z0RialN5Z2Erc2oyCm0vdWo4YkJ4d216K05tSi9FcmM5dHpXUHlSQkE5cGdnbVdpRkVWVGZ4eTlNVEdQTmlRRVA2dUc0d0h4bVFyeTBQOWxjOGhPclZTeW0Kdy96c1lFN3ZXbTAxbjd3TzhXZ04yWEE2TVVhc0h1Tko2MmoyR1c2cElyMTlSMzA4cFA1T1lkcDZ1NmtSR1g5bThvWHBVb3VwOFR3aAp1K21rd2JjZUgwek16czNOVlR6NE55OVZBSUhmdHpEbVp4anovc0sxMUFTMTd3blhONVY5QjgrSE1HUFhlV0ljTTg3ejJkUHlUSEZHCllHK2YyNmxmZVhaQXg3RHREeU1BaWc1cFd2TEJlUXN3YzZUQlpQYmNTU1IrZklQaDhLQzliTjNSdlNlOGVZTEY0dz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJdUI5UElRSmJRK2hoMzM0Tnh1RHg1NUNkSkh0WDdEVVdRL0ZVYnNUbXNTTlFqZ3JVZHNVUGxpTjUwU1hBeHNqT1YxTmcrV001NnliVwphZ1MwN3pUL3J2dWlZbndIZUQ5dkI5ZnBPR3hiOTFRdzlhSVEwYi9kNjVUMi9vOUZMZmh0amZuc2JyeUhNRHdnR2JzanNYWU45VmkyCmN6alZhTnViOXIwcFdtVDVvRSs0T1FsQnB4OWoveDNWSVJCWXhxZEZzREdWRmNZMFkrVkdUeTBDY3ZQWmQzcHB2QVdyY2p2TlZCajgKN285SDlNRDhDbGVQcTBjWlc4cWZyd3NBOXUwNjdWaEpQUU91b3hhL1U3eDA3a1dHbzEwSTltK1p3RmxuSW80YVg4WU95ajlxa1BpYQpjcGlXeU8vWXFzeHhZZWQrbDdVWGxIWnliSXdCM3owVFphMGVnYVlXdDc5amp1WjhSVHdWR2J0ajJjQzlacDhBRUxKN2Vvc29QUkcrCjRmNVovRU1lYkd6WVl1SEVCdUF4T2JHM3ZIZmZBWXltbTFxc0x2TFB4MHFpM0Q3U2JCcEdQb3lNWHR1ZlV2UUFMZE42eExDSUs5Y0IKMEY0Z1hoZjY4RExXczU1VHhoOHQ5cmJNNm1PSkdQdlhLOXdWVThXSE1hMklBRVdTb1h5ODdqdHNUKzlZQjhCWHRGZHpVdzU4S1hJVgpkQUpacnhBeVdjOStnMklZNFA1N1JWb2o1MFVKNXZGSGJhekhHMjFuOTdiMnp6OG52M2FrV21VcXFTaVNmOGpnMm9yRHhzM3VFRDJzCmZkd1B6Mk03RFR2RmZQei94eTR0K3JLUGU2RWZhZXUrWXNBY3JVU0t1NjBZYjJPaHo3NkFFUkk1TDFaV2FrWFdPRmY0WXR2cDhPQlMKM0wzTXYxL1BBYzRhYWorWExOMmMzeXl0Zk5GUDU0bnh1WTRucmlEZEFTK0hrR0RjOFI5R0VuVFU0Mk1PYUpQaUFCeldYODRZT3Y3RQp1cWdVWi80VGN2ZzdZcHpxM2o4UyttN3I0VzFQeWp2dVMySkhLTnYydC9WZ3RvbmZ6d3BWb012ZEUyL1JJMmVTc3ExSXp1UWMzbWhlClhDTyt2b3g4Ui9LTDE3QXc3dFg4Y1lQUW4zUkZSS0dYV00xL21NdStMWFhya3ZLU1BNN20wTVNGbnN5OU9XUnNPdzFFYlVVSTVVYUoKUVkvaHRKOXNQbTRPeTNYQ2ZBSkp1WjF0VnppRFQ1UFVBai9uaSt0YXkzakwwbXc4amxLZWV3SEJsbFo4T3pJKzRkQWZ6YWw1SHUweQpaZ3dRSi9aUDg3ak5YNDBmRC9wZmVOc1dHWUZsalJyYlVLVklFL1FTUnJiVDFaYW9Zb3ZmWWxkVVhTM2NJQmtqYnNvK05TTU9zRU9CClIvbVd4M1pBaG54akdQc1ZzaXJkZWtkMG00Nmg4NFFqY3Q5KzRjbFU1SHVlS1UrSm81WTlTN2tkZ013blpzWEE0MDgyaC9CaDdLZzgKRy9SVW41anl6dG1kOVh5dU1TV3dCWEI0S3pVcFVZNmZ5aUUxWkVCRFc0WUdjbHdyYkpqM29pSWxUUjh3bnNCaGt5NkFYWU4zc21WRgpoamkzVzhNY0F0R0szNDJiK1AreDk3WHRiZHpHb3VmemZSNzlCL2EyYnB3bXBCZFlBTHNiSjIwc3lYYWR5ckZyNWNVOWJhcERrU3ViCk1VV3FKT1hFK2VQMzQ3a3pBd3dBdmk5bFN5SnA5c1VpaDhBQU13QUdnNW5Cd01WNFNHVTl5QTVyeGlRb0gzV0Vvc2N4VVpIRjJpSlYKTHJaVDJjY2xuWkR6ODFCRlpqc241L0VWbVpTM2VwbzVDTVJuQWgzS2hBV2ZsRDZPSTdNTzlDTUh6aFJIcUJvWDZDTFJsTWhIZWVVOApCUkpQeDF3L1k3c2NQdDBvZUxwUUxua0g5R0plT1pNVUFuM2tBRVhGV2dUQ1Iwc0V3eDRBcFdMaklybkI2amJhMUZ0SWhYZnR5Y1JtClhROHM1TmhVSmJKSm9aaFlvNVVGdXBnVGZDYlFtemhTTHpkRWlCak03TE1rRmtpaGFCWm9NZ2JxbkoxcjVOZndrWDNldWNaR1BIcUUKbEtNTEtiV01CZEliaTJGcVdRU1pmZi9hclRwN0doUE9VZWZZYVBWSWtVVnVZM3AxeVllRmVzcG9OK05vMHl6M3prempnaE9OalZOMAprOVk2cU9oVnk4eUoxQ0xqdVlSbGplRTRlcmRoUmpHc3h2dVRoWWtGZFNwQ3ZHcnVLQXVCNUZTV3lSWE95dzFBZXFMWmtoQWp3QVhCCnM5bnVnOEk5VGVFa2o0Y1Y3T0tqc0d5dW4yamVyNVQwbldXL0c0WWhXaE9EMFA3NGpJOWY4ekZKdUhnZnl4bkZiZ1NCd29mRk9zY2sKNFpPZ0diTUx4S2gwd05SSkRtZm9aTHpCSFVablprYkE0ZFBzVEVKZzdqY2dIMWlySXc5VllzKysrTTZKYngvV3RXMGZYN3VRdkZ1aQo4ZExXVjk1UmpmY1NiQndOdm5YcHdob1FhQmdyekh3NXhWazhmZk5oTjVXK01jRGx4WnppMEdDWVVTS2FuWXlBM2x0eGE1OE45ZlNHCnJRL1F3ZGRlR0J5V1E2cFVBUE0raWo1ZTYyY1NvSDhIRjZxd1J6aDhwOTQ1YS9FeFNNb0U0c29heGt1dk5GcWdOOEJ6aUQvQ0ZKK3IKM1B1d0RxMzNnN0NqUzZUV05PdGtuWnNJcWUyTGxmWVo3MWY4T3E5VFNtMVJhZk5jV1ozT0JVMUxlc1dROTBXT0twWTJ1TkFpZFpHVgpJdlp6K2ttUFQwejZRemdmb1FWS2NGYUoyWDJLUlROdnN5eHNGQWdDdGRjdGZFQzZqRHdvaVJ0dllSVm0yL3ZNS2tjaXNZNWNOMTBFCno2SWtzck56L0NXKzVaSDdaWkM0VzBTRnRSdTZrZVoxUVBIZU9WOUFLUXpIYzhFMFk2VUw5NXAvY0ZtdlNyRjVKSEZQUjduZFJuSnMKS3MxZVMxWWMyK29Wamx6N0tGaS9nMUVRVWQyRnJ1WFI1bUdyNTlZNzRCYUg1S0tzeDZIV2FsV2JKSThGdHpZQkFia2luRERVcmlnSgpDamQ5N0RZeDc3WkVjQUNoZmRuZHhNcDlzQ3Z1OTRhdlc4Z3NrTW9HYWdRTDlyOUk3YTltQkpkZnFxeHFnbGk5QjEvNWUwWDRzQXlqCjlYSDRXYlFoc2M2WlpKR3pqTjdIc1FqUXBzUENyQWozdzlDMHg5SFFIUEdReE1ZVjRaejFpRUJ5VUIvczNLbnZtSDErMHdzZDExdk4KeDAwaG1kM1NCR1U2Qy9YcHdVWGJBY054TzhSRzZUYWF0SmczdUc3R1NDOXlaS3FpS1ZNNEJCUXp5SmNjS0FHY2JjNmY0bkFxdTdPMAo4YzRLQkdxdmlBamg1N2V6c2hucmplRUpydDB4MEZnaDY0QStSTm80cDN0UzJIZDRDYWo4aFNrRU8rK1VzU1kzQjVRY2o4MHEvYXpiCkYyN2xLaVpCUzA5WFhyRDZIMkV0Y3U0QjN3L0RrcWxoWU02bkxSUW9obnRBandOWklNY2FHL3NNa0FVYWQydzJWZ2d4QXZLbldMRE8KM1BnS3diWmhaNG16UlRsWXlkaGJVN1lnV3hxTjlSc2V1UHJrc1NRd1Nnekd5dTV5ekNpWm1nRE8rWGpKZDUwQVNJRzh5dCtUc0VDVApGVzQ1cE9IeUVOcFU4b3g1YXhnQmgwWVpLK0FkMXN6ZnMvRDNFbEhZRytZWTM2MmhmWWxQMkh4RXArZkFEZk9yQ0pzVis4S01EY2x3Cm14VnJuc3JaTUxGNjdxZDk2alYxTkhaeCsvVE1tZHMvL1UwSXIzU2hHNGVCdEJueFhpdWRwZzdkY3Q1QWZBZzdaeDAxMVlwM2NPbWMKMGlZNmc1QmlrUHZCTFZnem9CeWxLcjZMc2VBK2xPU3JqdVF2dFVBT2hhRFhibGx0eTNtdzBpd29YWEFBWVFLODBtWVM3aE41c3B6YQphdGdZa3JENFJLZ3pXMmovbG8xVmtpVVB0MDBrTTZaUUc3c1pXS0RSR2ZkS2E1NFlicGJZTGpnN01LcjV6a0dFWGNnWnFFSVBOQjhPCjUxK1hZeFhSK0VBeVBGTW8xc2hGNms5TGlXZGhjT2NKcDdNcmUwdWdZSUtENHpHNmhrZE9UT2F0YyttSTNGOVE5QmM3SFRnVGZuNHIKUHB3RmtlWk1PaUlmVy9nY3VJZmdqT1ZrbGl0dWl3M2Z4bDdENUpiNGdpNnBraTFHSUpnSlh1L0w3ZHV3YnJkd0N6eW5KeE1kVWhOMQp3Ri9zby90S1J3NmNKaXdvS1pDVzBYcUpsdVRjRm5zRWpGV2dHRy9xVDR3eTk1ZmtWRmhoeXQ5OVU4YmZ2UEZlZUJHMGllaHlZdTZ0CmxzWjdzTEZiWHFnSDh3MGlVTXhGVnNnQWFEU1BMYXVwTSs3Wk9iQ0xJRGIybnR0NFdXTXRQUmFZdXhCb1krMmNiRThRZmd2aElEV1IKMitnY08rT1Vab09FczZXNjYxNWNuM0wvaDBWcWdieFRPS3NWQS8ya1Q5bXZobWFLY0QrVGRlcWk0YStHRmU3YUJGbytKTjhPTFRnQwpHODBrTEdRVGR6aEdJNHZNK2FxS2xteGtrZjQybnZSSENnQUxMN3pEdVE3QlJlYVhqTC9qelRKU0ZuYXJSSmdMUXpPUmpZVEFPZ2JQCkxEdXpaRUF3VnBhN2xlWGFuNW10OUpUQ3FpUmpITVRIRlhsSGtKcERWUW1hOHc2ZVNHOXRDOWZpNmJLZ0JXWUpLMTFTMm10ZUFHUjMKWVh6UlVlSWpodHdhNytzU1BibWVYenBueTZCSWVhTVEzak9HQnNQQzMrZDFZWWI0ckxTL3V3NHJLbk5BY3R3NEVyd0RJWTF1YUJYdQpEQXZBUEdmMWpQWTNMcGt3MEhzWHNhenhWNTU0enFUK1pJWjNZKzNxd2pjaEN6WWVKWkVabEk0amRzbzd1NTd5c1VQYTV6REFoOXo1CmJsYnVUNVpvbk0zODN1RUhCaDl5bHJ3dnBnVmpEVWZMeE4zNGxtamY4SHNFcmhoR1MrWWVaVy9lZXdlSzltdE9Xd1d4VG1icklLUlQKTGRqdWJkd2xMTHlSbndack9vVkcyT1lTdzZaNzZXK0lzZjBOamZ4K0VFTkFnRVM3VzhSRU8yUFE3dWN2ZithR2ZTSjhZMWpiZ0NQMgpLR2gvWTVFamdoQm9XSFJ6akw3RVFBYkRVd05uTHlNb25LVnFyQWVGUDVOd3BBbTZhaFJQWkZXd2xvM2VIczFya1I0VnQ4QndTWTdOCnhua3NqaEsyYVdHNkJwMTZpWjV3MlZUd0ZVYStaVGMvM3dNN1lMUS9SOHFjNzVGcGVvaVR5MFdUMEZmV25IK0JacjUzZGlVOGpUT1YKTWxIc2V0QStRUWMveG03SHhYdUt3bG5lWlhCWVVKK0RET0tjQWVqYmN6R3FtQmRDYzFxSmNNL1NuVzNucHBvd3prS2tmV0FnT2gxegpuNGNnRVp4cmdyWEFlRlR3eFhxdGZWOVRMbHV3R2t3M2QyMUJ0dnk1WkFOY1h4dSsvbGs0YXhRaVZTb2VBd3MwN2s2UXRpZEdSaEN1ClZYTllUaHFPYWJyaHRBU3NML2dlTG1rc3ZyN3pxbWtNOEdGWE1Qa1ZDT2p1VXdDTVVrTW92aGp1UGNrcDAwOWI0SkVEODdrY0pZYkgKQ2dzZ1k2QU51MFd2dGVadVNSMDg1TnJuUzZBWUFVYkxKMVh0cjFjQ01OTktNVEJMUGRCMWxwUis3emYzYzlCcFA0alRlQWE0S1l3RgppMEt4ZU9mcGl1NTQ3Zk1jT0w1STlwQWJObFZqTUlGa2ZZVGN6Tjd0SCs0UDI3V0tSWFBKbmRlS2d4RVNrekhReHlSUjNBSFhWKzVHCklyK2RiSUZ1TDhVK0dXWnFHdWFLOUs0RjkrcTdBL29iek01RU8rdkN2d1ZuT1NlWFlUOGhCa240MVdhY1RvdWhIMTZJMHJwbEJPR0kKeHZHaStFQzE1T1dldW1nMURCTGg1VXAzcmpoMGhHOWphT3NyY3ZVRmI4VSt6aWIxT29xMmxsTkdRRWNIVzFaN0JHSFQ0bHRWc3k2SAp1N0x1YUlHN1F5NTlVQXp0ZHVOTEhpK2Q4eW1DWFVHcGlzNWNwTUZidk1ydlpYaGU1ZXFxOE9mRGxIRVdMbjdIYnZ4Y20wM3k3c0JqCmdXem8xdmFoYVF1a3kyQ09yTUo0QlBSeXRwT0RCUmVWL3BLL3RwNC9Lc2pYd3BYM3BXRUlWUkRaN2hvZ0FqUFd3S1h6cGFYYVBtZHUKRVlTSUZPMVZsMmdRdFhYbVdtQWlHQ3NsUkhWck1OU1hJZWNRWDhKREJCbXJqMlM4WUREYjhJTktoQmdNVDI0T2NNQVlNSmM0UnR0bgp0VDI1eWllb2NOWTFCRW8rekxMMmhWajVXT0FOSGRnK0wwUDdxcUhqQ3lkd1VPNE1oZUZxR2VzTU1tSHRGY0ZlOGFFSXB5TUgxczYxCnJuMHdiR3E4ZVJFWngwRjRmUCtCUm9NSEVTM1VmbTVrZkZjaGpTTS82R2FGQmRKdEtHWk02b0JCZmZSbkU0UTZodzJnVFZ3Z0lzYWcKZXNXQnc5am1aNUF3UEk4eTNqZlFzczl5RC9iRm5JRWVRZUhQN1FET0ZmY3JrM3hvU3d0TzU2VHhxR2haVTNoUGJUamlBekQzaHp2cAo0eHNMNnd0MlN6SHpzWlFoSFFOTEtEeUsrbk9CaUNJc3M1eVhRdWJTZmlBQ3IvMFo1N0ZBWU1vSDdOeTc1MVRpVFZzaHA1WUtsNjl4Cjl0aHBPRCtoaE00SzFuVmRwRFpkNEdmYm1NZzFJK0RBRTJObERTTmdLV21zRk9leTNxeUVscVIvN00xRVVhY3cyVVR6dEpmT2VJSFoKQmdyMjFKS0gzRFltZkxTejl2ZTM4VUs5NWdPZU1vYXYzcy9NVTVGRzlza2s4U0hNS3RWZXNiZUdLWXhMVnB6anp0OXhSS2czbExCYgptNHI2ODRKTFVVVEpwN080Sll0QVJjbFVjdWxqb0lPeldtYzJya21GNkJzVEJSQUJtT05NUXNZcHhPb1RRSkd0eUFMWmRVdG5tOXdqClVJblhvS1JrQkR6bmpMMEtVS2U0ZE9sOHN0cWFnQzBDN1NOd3RZM0lPM0pndmlha3ZmVmJhVGEyaEF4ekNvZFordz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJNHhYTGI0VlRUZmw5eVlTeVh0U2prdktESzZ1OGM0UXNqWFVic1MrOGNRK2RJeGFvbkhLTWRtYjI5S25NTG0wM2E1VXJLbjNNQXp2MwpWZWFqeTdTMW8zUDlZUEpMM0kxMVJPQ042aXBKR0t2eGxramFqUmxCSmpsVlZPb1ViT1hDOGxWc25sUzV2MTZnYmRBQ0krRHJnZHE2ClhQamFBbnNGM1pIZG91Q0R1clkzV3kxUTVrSFdpM0FkUXBvZ2tyU3pJNm5jK3lhMERWRjNRTzltNDZ0MUNtV3FGd2dwWDFoVGhRMkEKY3R4MUlUeXFpSncrSnMwWmcwNjl3eUcxOFFrS1hWK1M5UnMrZkdDNmRpbjk2WmNka3pxSlVzQzVHenA0K0dHaG1EclJBY0RDRzFISQpZWHZncW1mZXI1bmtWaUFBa0ROQ09JbGlnZXdZMWRhV3p3aGtFYlpYd2JkYWd0NlRPWE1nQUhQRG94RHVmbUJacGtvSEFncldPL24rCmxvNlBkR1RwNStxNW5reG9xTVBWVTdyOTUyQWg4eUdwYXJhKzhMbWtjQnUyR3o0bDNPY3pyY3VWQjdEUWZlMTduM3FzMmtaWUlWRFoKNkRNcmQ0eFBjY1hDSDg5amZNa1Y4eGFiekNzY2ZCMHF6RmN0RmRlWFB1eFArS3RxbUF0TDhtQlRrSjhGY3U4TjV5UFRYbUNReW00cgpHNS8yUmR0SW1pTUhscEkzVUhkdXdJeG1pYzlJNXBSK0JFcldwRlVZVXVQRnNmYVplYlNKNW85MFNoQ1d6SVNiS0ltUG0wU3dZSjFQCjV0WUJnNWZKQkV2TjFLVzEwb1p2MHVNNVBhclBWKzIwdlczQWROSDFHTmJqY29laEVJWjc0QzZwWWJDTVR5eVhzLzFDWjlGSlVSVCsKVnA3TGoySkw4NDI0M01iMnVMS09Cem1lRi9pa21QTjFYZ1Jyemh2SmpuMmQrN0IzWktLMUZ1RmR2OEx2YU40d28xR1J5L2lvNkt6QgpKdkZpeU9XZnNzQ2N4U09wZ1ZRZmJ6RjZrVWNYNzQ4Y09KdytpUGQxdWtmSjdsRE52akVqdkJQTW5WMHNXc0hCTTdyaEwzRUdzNHd6CkpDUE03NGJLYjVKR2VGMUgrL1JRQmswbG5HK1M4MndZNFNNWXRKVjhqQ0FzVGZLSFc2S2t0ZXJhS2VPc05VYmF5NWRPNHRpNVpWTHIKV2JZTU5LeVpFWmpYcHQwT1Rlb3ZQbXViamF4dXI5eEtOa0dDdXNCTUNUZHh0UlVUUnc2Y3kzeGl2aGh0WTAwY1pRbGZVaGFLWjJ4MApxZHhFcDMxSzcxdW51OXVaNEFYcW9ueE1jTmRwdTh4cy9aQmhGMXZWWERRWEV4WUV2SlB1VFJBVXNzRDFNejhHOW9pRVY5cUQzOWdkCkdoQ1lDWC91WVhNTFhYL1A0elhBbC8yRkMyclEzdmxoQ3NwUzZHYTc0TGJZZGE5dHVnbEdtOHZDSDZCenpubVFSRVorVHErRWFSTzAKOFhZTmUwYktaSlNKa1NKV0NDK21idkNtUUZZK01NMkRadXNTQjR3QU1DUWJwY1hMQ0RJdlkwbFMySTZsTmlUYmtwRVduRlBDeXowWApRNWNwbTREYnpUaGVjVkNTZzI1MGRLY2NTa3QvK0JMYUpTRlJVVXBrWjU3S1VPVk8vVEdQRTNBb20rVEVpZFBDVGRtTVpLUGt5V1ZOCjE1bTJkeGpkZ05uOUtBUFJ6WjJsK0J5TEZrOEFpdXVuVms5Qm9HWlhxbklPL2N3RUJuZ0RYMmFpaEsycDA2S3pMSElyQ1plMUtzdDgKWWhSdGc0SXNnaXlLWUVoZHh0Y3M5eWx4dFUzMFo0RjhGZFVkWlN5Q1BOcm5OQWV5Wm5sa05jdGRMQkVCL2VHVGsySHdpYVZRSWJFTQpweFF4L3VvTUF2M0IxU2U4eU5tSGlTY0xsazFRTkZpR09JWXlLNkpvQk1xelpJRmFlMCtadit5RW1XRWttMmdwbTJMSWJPTXo1cnA0ClF3UjZ0ZHhaY3pPMEh2aTAwNFl2MldJYW5jemJocHdYRllBcVJMYTRTNXM1SHQ1OWVzU1FyeWZ4dVV1MFRlVmhnWm5rSUNCUldQRUUKd09DbUNxb09ndjJ4anpYdFBMSFhhQzFXbDNNRGdWNWtCTmJtd2tjZEI4TU1wUkZpTGtwM1ZzaEZISnRUOERrSXdkNmFXTGd6VXg0dQp3bW1iaHF4T09Zc1NyK21RRXNBSVFrTEozSXJZWFBpNFJEdzE1dHlCTkFuV3ZUeDBJSUJaelVDa0tXc1UybDNkeFpKZUxaTSt2UStWCjVXVkFKMnZYMmNJYmxKMUZHMU14OGRLa2JkcldsLzd5cnJaSE9nZFVYckYwbHhrcGxSTjNsT09yRVNpOVBvRm5sU01IOXJ1QmRyZHMKRWViRkk0c21BSEllRWxSKzJOMmFvNEJXdnF6aHNsbkJDNG50d1FBTWpwSW9KWnVNWEIwc3MvTTAwcjRveFlNRmh2eWxSSXRGZ0ZZWgp2Nk1uWEoram9aMVRZYksrRDdSQmFPWXpWNGVXQk0vQjNOMGZBeUEvRWVEeVhuTjk2YlUvc2gwNm9KOXFMdmxkNnFORVlpbElZSi8xCm5KTUtwdDR2UEk3QXUyOXlIMHVjcHo0bFJGUldScm82WjNqQkFmREdWUm5OaThLa1hrK3pkNWNRcVRmc2NUSXRHaFJtUU1oN2hYd3gKcktjSVRocVorbXhpSVNJRmdHeUlOWGJ6WXdSaEsrS1luRnpGeHFQY09wc3dvWnBQOTA5UG4xc0V5c2R6NHc1bHpRdDViR1ppZDIrTwpoaWpXVVh6TUFlYXY4MWRUcEJKY256SWhxZGh5ZzhBUURPR2pWQkJCTURlNnpSVGJ5dmtjeXlsdXFBTitaQVdibVhMalUxR0YzUUN6CjdSVXNYM25ud3J4OFJ2aStzcEtSWjFIb1lwSTVkcG1RY05pTFRBeVU5bFlpbnlZb056NWJGRTZ1akRQTm9VR2VsUlFPZE1mc3R6NWsKcitBc21GRjRoTC9YbnhmK0htWXdNQ05RcC83TW5qQ0M2QkVGdzJweFFVK3orRGxyVjBjaHJBRkVXVXVaMVFhS2NLNElrUmhGR3FsRAp1Wk10Q0N5OFI4YWR3UUNZaDRBL3pWWllCQWMzaFkvSExKVDN1cU9OS01rOU9OTWNXc1ZpRHpVcDd6TFVMdmtReldudkFHTDloZVFYCnN5c2NibmkxT1EzRVlxVm9LTGJSR0VlRThkZXFYVVNvUld2c25VWVZXOU9KZGN4d3VzeHFnU0Q0T1RiTU82SEkyR3ppWWJUOXdtd0sKYkh0M3I5RlljT0N2ZFBtSDZQcUVkOHk0b05JaTg5ZjF0RFZXSHpnRVJaWk02QXFZbmNjYnJsMk9Uc3cySVRsckFCMUxiWDJYQmNXcApGVzUrNUQ2aGl1R2NRcHlWMFZJbzJDZzNMMlYvbW5LR0JYNkxoakxyV0lxZEU2L0lRbUt1M0R1ajZVNlJ6OE9ZUlp4U0lSY1FaMHFtCnkwS2M1SVB5aEFlMityektxWTAvUVF3NVh3dmttdzUwcWNXbjB4UjhjNVd2cDlteTdzMkJ6TDg0RStYa3hRdGdmSW1kOWdhZUJibFAKMmVXenlaTVE0T1JIV1NKNElvSVU1cWJjL1JZc3FUZ1RRT0ZqMFFzWFFPNEl0eFlGUkJDeVdXWitkcHB3b1paVFY1QVAxRi93VnpuWApWNFZQNE9RT3VXVHQ5d2thL2MwcG1qdDhiNGZNZUE3b2N6VFFWUW9MVEhOT29oVTg0cVErZXdRdUJvYzJBbjRveFVzdTdZTXMzWXpnCmRhLzlGWEM2cE9qa2hyK09xMTAwZlRILzdRcWZTNXoxMkVJMWZBSlpUaElCc0pBQ2k2NHJIRGpCVldTY0Y0WHZpaGNxem1mcER2UUkKZEJsZzNMTnRYazRhbndEVk9TUlFKQ3UrVWxpd25FWWxKRXhPUGg4Z1dETUZWZ2tycEw5eEdsSVRJVEF0L0pwaEpiSUlJYVdaVjhJSwoxRmo1cWgyY0U1UURxcHdUUmxORU9TTlF2RzdKdEdoaDRRWS8rNDBMWVUrbGJwbjVJUlRldmg1eXJTQ0N6TThCdTMvVDVzWEpta1RtCkpRU0FDNTlvMWFXcktVU2M1MVZuRFBUWk5LbFRYRDljZGN5ZERST0JCVjlMejl6UkZZRDhva2h1azEwd2duQi96eWtnQUl1U1VMa1kKcWdJOXJueTFOZHlKS1pJb01RM2QySEJsQmFmbzVFd1NtQWZjTUsvOVUxdEZlT1lxOTJrWXB0T0wvMlB2YkUvVURwM2lHaVN5d2czeQpmQWJZOElrbUJ1YXpnRjZaazlFTmJBNnZHTXVPUzIrcTFlT3prOHZnM09MNm5yNm9xQXJKS3p6T0NRSmM2bms2S2ZLVllweEdqakswCjFQSUZaT1VQb0J4NWt6VmNBalE4RmFjc0pCUnJBWFNBOWhja25VaWtvdjd1c2JzMGhEaDk3bXE2VWVZUkpEeWJwZFBsaEErMnhUdVAKR2RlZjZEN1RsZHBKUUFLTFRLTThZa1hCYm5GMmVDQlFlL3UxTXczSXlENUhPZEVQcHVwek5wbzg5UmZldFQzTjF2bXM1RjB6bkFpVwp3TjVqVlBnekdDZlFEdFpqQXZJWmxqYWpDSUdjYnN5N2dVUkFPczRCWk0yZnZ0OUwzSnllT21PZU05aUg2ZWFhVWFYQk51dkNSeENvCnh1SnkvQkV0dkdsUzhCbVhuN0h6MFQ3elQzalN2NmpHbmg4NjR2cUQ2N0lqcWpUZUlzT3pKQ1FlZENlT21mU0haOW9tN2xnc2VVY3YKOWZmSTNEVVpCRXAyNFpJZVVGOTh5V0xtSFltUWZvVURCOGFCbkpwbnhwV1FNMmU0RHVsZ0tkWGp1UWZQU0VVc295ZllDbmF4VCtNNAo4bSt3VGVTTzREZlkwb0szWE9tQ3BNZHlSMUNpZFFmVUxLYkkyblhBQ0xSUDJzSzN0RXg0R3BMdllNeEtYc0hQc2sya1B1Qm4yYlJYCk1WS2ZVQlBBSVJrWDU2ZENvRTlBUkM2S21YaTV3ZFRlR0ozWUhCRHNjM2R4Vm5vQyt1eE1ibnJPVDNNUVV2aWxMbUNjRVBpVUFESFEKNXpOZ1BXRzZYMGZoNWFLeHZHejhjQkZmR1VhdzVyeHVRWkhtQ0V6MG9mbnNWeG1JbUphckh4SW9zQjBvRFJkZFFyNy9HWG5oN01LYgp5dnQwN3NEK1lqMWZMcE9adjdxUk5WekVrc3lpYS9uQlhJSFZNMVpPcFl0N3dLYUt4QVBkdmFDcDlxUG5aOXlwT0xjaHMrSGxKZW5CCkNiK2NGTXJ5YXhiemt5R3l1eVAzQVpzSWpFdldaNzlUTTdOYlIvNXB6cEE2bFk3Ri9EUW5CemI0WFZWbTNpU1grU3VuOHpsWkdNNlYKeFR1NHpDUEZrNU41VEhlQTN5Y2lOWXdQc2tiNHQyUHp3ajgyNHRPZ0U5Z1hkdStTRUpCbk5SK0ZreXpLZEJFZUg1aHFMVHhoTzFIYwpkOE1uMTZVem5lK0dUMnFnWE5aT0JHWWgzWWd4ODdyQkRZYUUxM1NUYUVtRG1UOHArL2VXTXA5NHlyOEdONFUxdkFMRjkwZHc1WXZ3CjhpZm5PblZKc3Z6empab2xxUmFDVTM4WTVWOEZkamxCcC9HeUNFeHNXaVA3QTZwKzV3NmNwUDZwME55L1laZjdqSytjMUIweGUxSkMKdXRMNVBRN1puL2o1QXhFbmx1ZUhnS1k3eGoyV0RjbUdaSm53VzZ4Q2VEZVQyN2c1RFVBUkxJWjgzUnZUc0hDZ1dlS3lEU0lDeFc4bwpKb2tJdC9qVGNJT04zL1FVM2lRVll2dW0raFUyR1JPaXgvaE5XN3h6WDdEN2g1MXRWSlNOLzduMk1CL1BRUWxOZUl2SWZEUWxSNTRnCnNQQldlbmNVbTJxZlpYWnExN2RpNitJNVF3VjcwQ2djNzhpQjB4RGVKMU8rM3loOVVBajNkd290TjZkdDFLamQ2WXgvMnhkVHhiR0cKRVI2ZVFMRGdrNzcwcjM5TUkyRzVhYUlRQXUySk1UNjd0YlladFRucG5uZXhrU0ovTkJQRmtYL2pMbWliZEgyQW4vZ0tGOWpDeFExTQovNXNHejdUZ21HS0tjN2VvMDR5QkUzaDV6eXA4dm1wbjVqOTM0RlJ6bUFiN25URzRVZm43SjRYbTRFWmp2SldlRFZCWU5IaDkrYlhBCndsc0JkY2hyUE5VQjFrdVR5TjFDRjRiT0hUZzhSb3ZCcHh6L0VSNEpwY2pnbzlrNGp1Z3grYUoyOTlQYXl4L0hQczE3WUY0ajhPVGIKZnUvNW9OTWJkWHF2Nm5VTHBuZm40eC8ydnIzQVgwUmlmenIrNGZHalRoZlE3TjN6SDJ0ZjdOMTcrZlRvMjM2N3hJK0huZGFvMCs4MQpCKzhXL1hDL2R2Zlg4MjRQZnFwRHR3YWQwOHRST2Z5MDl2bmV2UWVEUVhPaVJPdDFwOXNlbEQzOFhkYnVQZW1Od20vNHoramRSWW0vCjNRVk41TTZudFh2Zjl6b3RBQjhEM3Q2cjhhSnZtOTFMVy9hWFRudjBlbkhoWHZPY3lrSlhYT25QMTVtaTEyWG4xZXRSWlpLNCtJM1QKMUQvOXVXeU45dnVYdlRiMGI3Ly9hMVVDejJpK1FkSFJzREtWWTNWdW5OUUhUMDRlZEM5ZU4wOUVWUm83YlNpNWhDWXNjK09rVkorSAo3eW9QenJ1MXBtUEp2SXpvK0pYL0x1N3V1b2pKMGVYZzlMSmI5bHBsVlZiWXFoVzV3ZTNjOU1EQ0VhOHFQYWZOWWZsb1VQN25FcGhRCmZicE8xTHB4Q21WVjhucVg1ODlhbytiYnNycWNqS3ZjT0dHOS92R29NMm90Mlk0RGZVTXEvVjJudXdLQlkzVnVuRUpjY2xXcEc1VEQKeTI3MWZaeUxWNUZBYzdvdUZuUjk5bTRVYmNybGR4WEZTZWp6QXZhdjhiaDBla3NXWUx4Rlk5a2JuMldkWGxWYStoZmxvRG5xRHlvVApGQ3JjT0ZYSC9jdEJxM3c4YUY2ODdyU3FEOVlLWTNXTGkrZWdmMzdSSDNaR0s2eWQ2K2dIYWNsVnUzRHZzRHlyM2Q4ZEFkZVBvdDBSCmNBYVZhM0lFVkxzajRBeENka2ZBV3hHVFo0TW1hUHZkYi91ZDRaWWRBaXRiV2piekRGaFppdXpPZ0xzejRPNE11QT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJT3dQdXpvQzdNK0RIZGdaVVczY0dYSUdpVFRrRHdzRm92M3hiZG85Zk45djlYN2JBUTFhWDIzSkFXb1dTclQwaVZkYTBoNlAyWWZtMgowOFFPcmFDS3hwVnVmSVJQdTVkTFJQMEgwRVZ2UlVjZ1k4dTJhUWlQbTVmRFlhZloyMTg2Yk91b1lGZGVTZTNxWXJHOTFvZnZkbldwCjJQNzFGZ2pwbjUwTnk5SHkyYlI1UW1BVndiWXBxLzhaamRibXJmc3VhcFlZWGRqcWQvdURMMzU1dmZTSUUyK3E3N3JWclkydTlJM1AKdHNvQko4UEx3Vm16VlI2M21xdFFOVmJweG9rYlhwU3RaNWRMNXQxT1FveEppQnYzRFZhZWdEQ1lsOTNtNE9HdkYvMWUyYXMrVHRNVgpiNTdLVllrODZQZUdvK1lWaUF3Vk4rbWtBc2MxK0U5Vkp2MVdtU3UvM2NiUlU2eEN5NW9mby9VS3BIendjL1MxcUNMUCs1M2U2R2dWCkE5UDEyQ3JMWTdkaWo1eU9zWG5hMFpXT3F6dnZ3MjE0SDdaVUUxcVJyRTA1TGwzQm5iSXVNcUh5YnZGbWlVNFVqUVVXdmZrNGpNcUUKTExHcHhJU29kZFk5MzZUVkNVblhtcERxZTh5YjI5aGlWcFphNjc1bk5nZWQwZXZ6Y2xUZHNiMUplMmUzTTNyZTdDdzdpMjNlNXJtTApTS2k0aFc3T09YcDFxL2ltak9mVGN2Q3FSRTV1bmtxMHF2elk0aUc1dm43c0FvOCtqSTRsZG9GSDZ4OTQ5SEZkUGpubzk3djdnN0w4CnJiTHJiWDBEckZhWWpPdHVHYTVNeU5iR1Y3VTczV1oxZi9BbUhYa3EyM00zNjZ4enZaRlY2enBHSkEwckVuSWJRbEUwS3FlRkdEVGIKbmN2cVd4Y1h2ejBWdVQrNGVOM3Y5bDlWRnVicmMyelpYdWwyL1hlWTFsWVVyTGxNcTM2TGFTZlRkakx0S3ZyM3RnVHlubGIyaG15SwpFRnZoQnVPYUM3SFZMZ0t0SXNWdWFjbHZhdmp1OXVZSXFMeTdiR2FPZ01wUnlic2NBZE1FM202T2dOUHFpcyttYkV6VjVmbTY3MHlWCngyWlRkcVpOenRxd0pOd21FZ0tyM2JtNHBjc1dLMHl1dFE5b09hMDhOanNodHI1anMrNUdnZ2VWWFVFSHI1dTlYdGs5THJ0bGF4VWoKMjNURkd5ZnlSV1UzMFZXSm5LNTRhOXZSWVdkNDBXMjJ5dk95TjNyYXZOaThQZW04Q2FncXU1TTM0cXhVNC8vV3BqNktzWTlWcWFaUAoxZFZ4TG43emdyS3lzV3RqTnJIcW9uL2RON0hWY21sdWdDWitnRGVrbjFZUUgrc285cXJmejl6RVRDbVZyU2tiSXdlcXI1NTFsd09WCngrWWE1TUM2ckw2emxZSzd6anJkN2lyQmE5M2JVRHFXcUFlUmZSWWZwYXB1bDdXbGIvN0dTbVd4RnlqenpYOUwvYTlJNFVTdFd6RFEKOWlyUHhHYXJkWGwrdVR4S0lpWXZxbkx6VnZYS3M3SmRQVW1UTFh2anRBeEtPbWhWSHFwMnV6UHF2RjFob0h5RjliM25kamJvbjFlWApoRlI0ZlQwNW8zNzFrMlQvRmdocGRuOXB2cXU4Z0VBMUdqVUhLNmxTdHZ3dDNHN3JsYzNLMTRWYXpXN3JhYi82bFkrb3dpMmRUSnE5Cnp2a0tFdnFhN3Foc2R2cTdlcjR0WVRPdFhkak11aDZGcWcvTnBwaEVkbUV6OHpidzJ3cWIyZmIzRmF0blU5c0Z6c3l5MDkxbTRFeHIKNndKblZwRG82NzQzN1FKbjFtaC9xcXlOYmtiZ3pBcVRhKzBEWjFwYkZ6aXpSVUpzRnppekM1elpCYzdzQW1ldUdEZ2pQcGJBbWRiVwpCYzZzSVByWGZSUGJCYzZzazlqYjZzQ1oxdFlGenF5d2V0WmREdHhtNE13bXVJZzJKL3huaGFGY2RWTGUwbEJ1Y0xMQ0ZRTFNkb094CnVYazlObWNzcnE4ZnQ5dUhyVWtaK2VESnlTR2xDanBaemI2MFpVR3MyNXN1NldieVJLL3I1ZHVQSVQzUFRyNVZrbTltSjk5MjhtMUQKNUZ2bHVicVRienY1OW5BQWdJOWJmU3VSQlR2cHRpSFNiYWU5N2FUYml0THRvMWJlZHRKdGs2VGJUbmZiU2JmSzBpMTJHNTJzNWh6ZgpNaUZYbWZnUDRvdmVLQy9oYmhHdHNJaXlqM2tSVlNaK3Q0aDJpeWkrNTUzVWRPVkFRRXYyaXhWaUFhTWFONjZPZlZ5dmJUM3YvRnAyCm4zZWI3MDVXdTQrNVpYSndVSjczbDZXTDJPV2t3WTdjVms2YWlrSmtsNUJtTVhtM21aQkdWSitUdTR3MHQ1aVJabHR6bnd3dk1QdEoKVmJyZUsvZkpEVlBXNmJYTHMwNXY2ZnZYOGFoZGxNM1I0UXJMTEtweDg1S2pKdTdMcENZMC9KdlU0UC8zNFRQOHZROC8xSzc5UHNxdApIRnRXVG1TekxxclV6UjRwYnpwZWRvVzMxamZsbHNBV1BwYTV5akI5cEJjR05zTnpzKzRYNEpjdGhNMTBzN1g2NXhmOUlXZ1R6eTZYCnlLL05rM1lyaVlZTmliTS80UEhhUExsUTJZajRab2w5S2hvTExIcno5cGJLaEN4eFhNV0VxTnZRdFNzVHNpUXNKeVlrWFd0Q3F1OHkKYjI1ams3bVNncmJ1TzJkejBCbTlQaTlIMWJXQlRkMUJ0eTRINVZYVWc0OXhLOTBjOThlVnB1dW1ET251RnVMTy83enpQeThpZEMzOAp6NnZsWE56NW4zZis1NTMvK2NPVHVmTS9VOUdkLzNubmYvN2dkTjNnMnhzNy8vT0hWemZSQXkyVCt5dXBuanVmODg3bi9MN0U3WHpPClZ6TTNyUEV3N1h6T2ErVUFhSGZPemk2SDVVRy9CNnBCci9yeW1hcDM0NVB1WGRudDluK3BTbWUzOCtyMUNINnZ0ekFKYVdVeUo2dmQKL1BaYldieGZEczVBS1Q1ZTdTR0FzVXJyNjZheXdubzEyc2JxM0RocGJuMXMyK1oxclNFRTZ6MUVXL3dzOGM0RXQrNG11RlcycjUwZApibzN0Y0x1WGlYZDJ1SjBkYm1lSHUrSng1LzZyUVZuMjdvTWFWdDRIaWp1dit2ZmZkdnJkY25SL1VMYnY5d2ZOM2pJLys4NUFkOU01CmJpcGJUTXN1ZkZuSlBCZlZ1UG10TEs5TVdQTzN6dm5sYU1tTGxySGc1L0szWnYwNTdKQlo0d2pWcmx1T25UbTB4NVFqcHdGdTNnSUEKeWJUdFZocXgxV2FhNFVYWkFvVjVzTHNTc2RiMmpCVW1vUnZRaDc5ZXdGbHJCYXZ2ZE1WYmlHUllsY3FWYmR2VEZYZkduSjB4WjJmTQoyUmx6ZHNhY25URm5aOHpaR1hNK0FIMW91ckhHSEdmWkladk96cGl6M21mWm5USG5mWXc1dDZGbmJWdGMwaHBacG83ZE9XbHpUVk5iCmViMTRPeE56YkxFUjZncWtiY29GMUExT3oxRTloOEl1UGNlNkViTG02VG1xRTdMbTZUbFdEYUZiKzcxenUxTnpkRHVqNTgzT01rdjQKNW0yZ04vTTJ6bTRMdlQ0NXQ5dEMxMDJwV2ZNdGRHc3lYRjFKK2Q5dG8rdXdqVzVkZHF0VjlZT1BjUXZkbkVDQWxhZnBwZ3puTHF2Vgo5bVcxK3JoU1B4Mi9icmI3djN6Yzd3NVZUbnExUzF5d0h0ckJUU1F1dUtVZFpiTXYrMWQrRHJSZCtUVmFLbnJqTTZ3NklVdTJoNWlRClgyK0JrUDdaMmJBYzRXd2FsTzJWVnN5bUNJTnR6Q1gvakVidG96b2pYSDJpYnNxZ1h1R3dzQzZEczlWbTdkMGhidnNPY1VJbGQ2ck8KMDE4NjdSV0N5RnpwbXpjenA5VXBlbDJ1RXBQbGk5Kzhjdkl4SHJXdkljWHlEZE5TRjdyeVZLeXU1OStHbXI4S0pkVVYvVjgzeS94aApkdWFQelRyeDdNd2YvZlZVay9OdE1YOVVKMlJuL3RpWlAzYm1qNTM1WTJmKytJakdaV2YrV0hQengwZDJzQjQxVjRqdjJrWVA5dG1nCjJSbzF1OS8yTzlWRDRHM2xpbVBNTGQxMHRHdWpjaWFaMCthd2ZEUW8vM05aOWxyVnRldUpXamR2MWFzY3o5dTdQSDhHWS94MmhhdlYKY1pVYnA2elhQeDUxUnEwbGh0WFl1SUNsdit0MFZ5QndyTTZOVTlpcWJNbmJsTE5FNi9vQzlOWjJiSGJKdERjby85SUtRbjZYcm1neAplYmVacm1pWHJXaUZnYnE5YkVVcmFGOW5nLzU1ZGVGQmhXK0JuTW92VkkzNjFUWGovaTJRc3NzalJadjhMby9VL0R4U3QySk5Xam1iCjByVllrcjY3SEp4ZWRrRkYyRmhUNHk0UHpBWmN2bHZoakxFaHB1QXIzRTdibVdFWFduZTJMZ3B0QllwMlVXZ3pxTHgxWTNuWUhFK1cKWEt6ZmdFaTA2cE54dmVQUXF0T3h0VkZvbzRwSzI2WTVNSkl0OTJCVURoWGFPVENtQ2J4ZEJ3WXV1V3QzWWR5U0tyczdBKzdPZ0d1MgpoSGFud0pYNnNUc0Y3azZCTjBqVFIzc0tyS3lmN2s2QmEwUEgxcDRDdHplUXJYSkdpYzA4QmxZbWIzY00zQjBEZDhmQTNURndLUzI3ClkrRHVHTGhWeDBDOWRjZkFGU2phSFFOblVIbnJ4OEFmKy8zMnEwR3p1bEJlMnpOZ1hXekxLWEFWU3JiMkhGajVPTEhMU2JFZVYwZHUKNW9yc0dnL1VwcnphdDlrWk5uWUpSaGNSc3N1d2NldFNZTTBsV3I5Q1pvM05rMmtmTEYvSVRWdTd1NkIvMTF2OWJuL3d4V20zMlhwegp2MlpCL1l0bXF6TjY5OFVLWnVQaDZGMjN1aG5jbGI3NW1HbWtkZHNFeEVwRWJjcWFlb1FUY2ZPVzFQdmswZG5aVG0vRGRycjlDc1JxCjhtSE5OWWdoWlRFOTJFYVJ0OEh2RzFaTzNPRGVTVDNvOStqeDl1cG5pOGw2Tno3eGZubTl3dVhKcm5zSXZsNWg3VVZVVGxhN2NTSXIKQitNTUx3ZG56Vlo1M0dxdW92V05WYnA1ZjhGcWduMDEyc2JxM0RocEt6NC92Q2s3MXpZZGZWZDlJWHA3ODhLWXlrbW55aTU4V2NtMApIdFc0ZWZtU1ZoYWZ6ZDg2NTVjcnVGaDkrUnNuaXJhazI4eG1kQzJxMW1HSDFJaWpWWnpDMTVRdDROREtoU08zOVcrZTdyZFRqRFpkCk1ickN5OHM3RGVJVzlwZksreVlQNk1OZkwvcTljb1ZqMW5URjlkWFN1YThybnlXbksrNjBwNTMyZEgzYTAwNTV1amJsNmRndDVjM1YKbm5aUjFodmpLZGhpTmVrS3BHMXhIUG02eUliS3F0Q2JKU1dqc2NDaU4zLzlyREloUytJTllrTFVXaE95SkxsUlRFaTYxb1JVMzJ2ZQozTVpXczZwWmRlMzN6dWFnTTNwOVhxN3dvc1FtN2FIZHp1aDVzN1Bzc0xaNUcraFdQOUd6d1Z0b2RUbTMyMExYVGFsWjh5MjBPaUZyCnZvVmVTZm5mYmFPN2JmVDI2Zm9ZZDlETk1WWHZIcFZjWTgxb1c1ZmFocjRudVM3VFlsc3pJRzE5SXR6ZFUzNmJtd0twYXBxZ3pWUG8KcnVUZTJveU5acE56TzUwM0FWWGwzQ0tiSU45RkxYSC9uZlhKUTZxU1RKK3Fpdzh1ZnVOa1A0YXF3K1d4WnBzbk9GWVhpWnNpTitqdQowdE1LQzNBZEJjZFdKMGJaNWt1QVc3d1JiM1pLa1hybGM4bTY1eFNwYjAxU2tXZGJmeWQ0bTQxeW01cU80K3F6YnYzZE1kc1pFWWhtCmZSeXY3MjRpaGZHNm55dzJSVHhzY0RTRHFQNGk5aWJxMy9GeXFuemxjRlBXMDFWa3hhWXNxYzNXd0hGa1hwNlZnMGVkd2RhWlVkWkIKaXEvTE9JK2FwOVg1c0FrMlQxbXI3UE1oMm45WXphZzVWdWYyRW9GZDlsb3ZOaytvYk4xa2EyUzFwUFp4VExmSHUrbDIrOU5OZkN6QwpiZitXQTFYb1BJU1h2YjhiTkh2RHMrcXZYYXpQN0w5aTlQM09hSEpiUmhNN1lOdW9jRi9sTUxFcHg3d050cHhRTk42RGJ2ZmFwOXZtCkhJZXV0ZzQzWmE1dWFCam9kZlRoS2s5WTNYbndSQ1FuRDN0dC81UVZnalJDVHI3dDk1NERDc3JIVkxmZy9mSlZweGYvc1BmdEJlRlEKOXFmamQrZW4vZTdlM1FmdGR1MVI4MjEvZ0VKa0w2azlnUCsvL0dYdkV2NmIxSjd0SlExVFpIQ3FiUWlWcTh6RzdEU0VTYkpjd1FlVApKVHJQNFVPZUc1bnAyc3ZtWG9qeGVma092bndESDM0RzBDODFrZFNlMXY3NVUxSnJZd3N2OXVwSlF5a2o4NkltUlNQWFN0Zk85K3JDCk5FU1JLQ2pjRUZxb1dsMnFoaTdTdklhbHBjaWhqYnJVV0RHdDFZdUdFYmt3dFlPOUFCT3lZZklrcXgzdFlkVk1GMUJWSm8wa1VRVjkKa0Zyamg3U1I1QWJRaTZ5Ukdwa1NKRFdGcUxXb0R6cHpNSWRVTjNKcHBJVkFWd2tpbE5JQmd2V1NScEZMRlpVcUdsS1pCTnVURFNscQpkVUNUNU5pK3lCdENxQlI3N3JsUUY2SUJ6UnJvdW1vVXd1aFE3R2d2YjZTSTBPS0JocElpU1VORFFnRmRjY3V0UFFBVktiYnB5MmdZCnJWd0dxb0JNWlFvWmt5NEsrSVRNWnY3QTM5eGtXV0FoRG9kT1plRHp3WjRIOFhBY0VVZ1ZORUxhQ0MycFdxb05BUklGTXdZQkVzZW0KZ000ZzB3aFBrZVRZVmlOTnRDRThSYU1vbElsQktjNjFGRkRqNE9aWlVVdEZJODBLb0QwRHBoaVRJNEQ3azBvcHNZc2VCTDB1OGxSWgpQREI1TGNzSWhHeVJCQ2pzTU1EVUVCb0hENHFtS1l3YThBZG1weWdNZ1ZRS0k0VFRRSnZNQXNaR2dnR3RQZWhYWWxJZFFDbndRbVRZClVvYWpxbXZSSElBQk5pS2xpYUdnUHlyblVraGZrU1JwRWZDRVNSZ2F3OGxMREk1S1FRZUV5RUtuY1ZvbE1Lc2l3Zz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJY0sya1F1cEFmUjE1WnFRT0RLcW5NcXd4Z2tBblBZeVpEZXNPYWhwZ2dXakl4Q1FXZ1lHeFF0NklBbm5qeWVVK3d1QkRZYTJ6bXN5aApycW1waGxFNVRDQnBZTVVBd3cwc0NLVjFEWlo1a2lvSkZUd0VhRWhTYkJmNkM0c2lqU0N3SGtWUlNJbWdYQUE2WFA0UzBjS2NTZU9PCnNBUTYyRHZiKzM2UGhGZDd6OVR1ZmxwNytlUGVuWk5ab2dxZ1Z4UldVSE9HdUVMbzFRU1c3Y2xWUkJiV3ZJclFpamtTaWEwN0o5T0MKNjg3SnlxTHJ6c21WaEJkVXU0cjR1bk15UTRCWjRNb2lqS3BOQ2pFQVRvdXhPeWRYRW1SUWJWcVVFYTdWaFJudzZ5cmk3TTdKRlFVYQpUSm9yaVRRN3ZhOGcxT3lLdW9wWWc1b3pCQnRDcnlEYVlQeFhGVzUzVHFiRkd3elhsSUM3YzNJVkVYZm5wQWZhNjkwSHZYNnZWa2hECk1zNHBlMUM5S05JQ1dDMThzRGJvZElRTW1BYnp4ZVFGU2orR3dKQVdLcVhWRDNJQVZwU1lCZUo2UjZST3dtUkpaNEZ3a1Jja05MamUKTklSNGxwRnU0SG93RFFtMWFCQnhlS1lnb2ZsSjJvNW1id0hUTEFpd2lHSVlwV2syQkdCb0JJZHVpaFVSTUhRNTFKNEZDK1NIL3N5Qwp4WFduMlJKZ2NXZW1XUk5OSGVMTDl3Q0JRK05vN0d4TWdnWFdURkZUTU9FTlNFT2xZZlZSZTFKSmU0aTQ5NkpzZG0zSU5WUUFsRTlFCitoeE9vK1dnVnh4M096YnpLcHhhSGc4NjdiK1ZGRHQ1NTBTN00xZFUrQVdjWllhakFjVkhmT2VPWDhERzJyMzlmcjg3VnZKaEQrM0wKank4N2JYdllCZnFtMFdHV3pjRW9JSUpqMThsZXdiUEFuOERzMlduR2FXci9jalRxOTA3NmIrRjRGeCttL25RSmZEdDBpMnpPQVVtTgpuNCtTMnFzOWtCaEpJbkNQeFRXWDB3YzgyZmhQSUdhay9iMXVkd3FaNUxnbjRaZk1LbWcxcTVUSkd2MkkyR3dsM1BrTGxOQXdNQUpWCk1QcDd4RzNTWnl3SnV3Wjg1dnE2UmhoQnA2WVdqdmE0MlFKT2g2NDRkaWZxT1NwVkNSQ2ZDcWg0am45Z1dtall6VUVvRzQyYmVjTEYKNFpQdFNPTElkQit3WUlZOWdCNG5FcVU0NFRDNDZSQmFwRlRZRHRFSC9GWExyT2FyZ3FKVHMzeHpUZFFKdGU5bVlvOGIxQi84eGtpdwpDWXY1d0JKd3RMZC9pbXZnK3g2ZTBOdTFWNE5tdTFQQ05Fby9wVUd0RnpqQUlycnRJbXI3ci9DY2wrQi9VS21CM2hnOE5CTUFtc3NGClNQTmNBRWRlbm84VjFETUxTdEJiOWxzVk1lNVh3UWpuZWNTSXc3Uy92L2VuNzJIR3czYWl3elNOMkhRZU04OTlxTS84RkhOK2JFeVkKbjNYSDBMSGhuQnByT3dzT3duU1kvc3R6cDdzWFRha3d6OXdNNFFrU0QyMDg1QkdSclhtRExDc1BNaFFDVFcrTTB6a09pWmdjNUhSbQpRZFRlSmdaNVBzYjlLaGlGRWRFZ3o1SGNxZ1pUUVlEdWVRTkNXdHlXa0Q0WWxPM09xSGJRSExUbkN1bHJNM3RKUStzVlJzeDlza3RGCkZuVHdrMVowQ3diUUYrTUVPUjYxVWxMNTdUZjRBcnFhKzBybkZ2cmdrYmtQaUJUYWtxaFoycjhrNnZpM3FJcEZZMlY3d0Q3V3N1dVEKKzhCWW92NDdxbGpvZ3hZQXhjL3Bid1pyRGRRTjZmNktBZ3ZEdndmRUMvaUFyQWcvMXFNNmRZc0hTeFp4MzZhK1VkL09YREhiNlhQMwp6VmhXMCtIQkllVVAxSnFodjhTak9uVW0vam11NTdBZDdFV05ISTAxaVYwQU1UcFhQUUxOcUFhYXZCRGJyQXNkTmtmbG8wN1piVStyClEzYUphV0VVTFRLVkNnWDZaZlFoeWJRQzdSYktKSEJDbmZXQjFoeXN3R3FyTGlQVm8yN3NmZ01EakpNaDR6OFpEUmdneTNScWNJRnIKYVpUMmQxVkJNMDV4bjB3YVdacEpQYjNlNFF5SDJMTWFUYkhNYmpPRy85Z1pDZHJkSHU2K3RodlVNUDVGclZyN1AyYStlcUVYN2p6dwpBKzVjdWhhMkFSRDRDcVIrbHVHR2srQjVSTTh1a2NQQkVuZUdoVGoyRitPQTAwYllXNGllYzA4ZS9sV1dQaFdvdlpJV3RhQ0xaaW1aCnlWSXl6Vkl5ZFVUbUpWR0dtbmtkTFJKSUthcWpqbUwrSytiVGFvcEFySnBKYkk1VEF2K0tMTVhtbFNNU1ZhcjRoMXc1eXFZcjdNK3MKWU9MeGdsK2twVUphSWhMYmQvZEhMcWFnanROblpTSWlmVVdrRThSa2k0aFpVSEdTS0cySjBwWW9OeUR1ejRJcFNFU2w3MGVTR1M5UQpKRlZKTW90SVN0MTBFMjY2Q1RmTjB2RDNRMDIzSko1dTJUZzhGOVBVSlBGc215Zy9TWVMwTkVoTFFtSjc3djU4d01tV3pGc3h5WndWCms4eGJNYk9Jc081S083bEV6YkhmL2ZsZ2t5dFp0bDZTT2VzbFdiWmVwa2hLN055U2RncEpPNk1TLytjRHpTdVR4WU9pSnVENUZDRmMKZm45VytZbitTK28rYWJjMG14TDM3NGViVXVPOXo4YmhNMWJGZU8remhiMG5xeXJOSEZtelBMZi9mcWk1Tk43M2FIYmJ6azh2aC9ITwpUMVlZNnozSm4vTTlKMzYwLzBNV1Yvdm5ROHdkTllmN2FnNzMxUnp1cStuKzQ5elJORk0welpyVS9mc0I1NDZhTS9QVm5KbXY1c3o4CkdiM1gxSHVyUTFxZTIzOC8yTnk1TnM1Lzd3OFUvdkNkTkFvcGhmQXVDUFNzQ0kxbmNGQzdCVVdPS0s5MnhTdkZxMkRDcXZPQWpYYVoKYzk1WGVKY1IvRWZ5UVUzVUhseFEwNnJtbFhvOFFyaElsWXoxKzFpeGQrcitIUDVtaS9YMUNha3NzbkZkTTdWellsS3BJTFYwUnRGQwpXZFcyR3RaSmpXTWVWcU9YMjR0U3FDd1MvaWR0V0p2aHRoNW9CLzJMZHYrWEdlWjlzaDBsT0lsV3NQSUx0dktUcVZPamQwaVRsL3A4CkNuTGtJWFhUVVBRaEF1WGt0VlZrN3RRWnVhaVZxKzVLTU9CZ0Q3M0xOcmFnOElpOE5kVERNQ3dBaXVtQU8wQk13TVd3ME0xRklJK0sKbXl0Y0dkOG5CbEI0QnpWU2VEUk1IRU9ZZXNZNnlUSTBRTTJjc25kUmFHZEpWcGhQUTV6ZS92NkRWdXZ5L0VWLzVHL2FRdVc0WnUzZQp0LzNSaTdMVkg3UmhuZHQ1U0hvNC9ERXBuS0ZOYW5BUnBVVmlwaGJBd1lNbmo1MWsrTzZzUHpqblhFTTBDMkdPdHZ1bjVjbURKOFVKCmRQZDQ5SzVibm9TbW83bUtMYjVzbzhpUlZ6ZzZ3eXBtZnliSlJ1WjY3cWNkam5haUMrTkJNQ0ZzbWF4aDZBY1BDR3oyb0docUJoaFcKcENHM2lPR0RtMkYrSHVaK1Bwa3dvUmtSMXBOMkhpbzMzQVhYUjhUNTVMSTQyTXVuMWc1RG1BaEd5bFFhUDVVOFRaTzhxV2F2V0RBagpyTlFYTkV1RHFQVWZKSm5walNBUFJDNjBYWWkwQVdDRUM0Yk16S3VVQWxraXlhTmF1Qk9zMnRKK2haWnlNZDZJMnhwMnEyek9LdnZUCm5FMXp4NXNmcHp5TWs2djJmRzlxYVllRjdCZi9oSENZRWlEeGZoZUV5a3pZdElTYWxHRlRjbTZKN0l1MndBVWdMMW1uWk8ra0RKb3AKbGlabFZ4Q1pESm1XZnBNYlpSVmY1M0xSbHMwVE9GYWpsRTdnbUNRU2JXS3V3S0ZLS21IUnhyVkl0SzNZMG42Rmx2Smt2SkdQVXJRdApkbTZQTGQ5d2JrTlBxY3JSaTJOU2dUNVJBNmMxc3AzclBEVUNmd2ovbjNhVTBuR09GNUZ3aStoOEwrV1ZMUHk2U3ZCNFFlVzZNNm9jCnpWZjMzRkFueTBhTE9EVFBMOTdJc3d6RC9OeWZCUDFCN3M4V2U4b2ZkYnJuRXdjZGY5aFpjTWFaOUw3aElVZWtHUHdLekVNbGcxekMKY0VadHlCeGozUnpvS0lEd0EwWERIdm1LTTBDaDRoa2R2RENFTXlseVVsT2xrZVR5WXhDS1BTV290bWprR0VJOURlRnFjN1U5NVZhSQptcmxDWk43QStBQ01PaFUyK01nMHNqU25HQ1ZvQUlPSDRRQU8vUkVKbXRBSzNBSmtnWkpRWVNjeFVEblZqVlFxT2JPcVRGRFlwN0tXClM0bEIxWVpzZGhnSW5hTXpYamVVelBTY1ZnM00zRUpyYkRWdEpLbWt3S0Nza1JsUjBPYWxSWnJrczZ2cUhCRkxNalRqRm9JMUsvVlgKYUJBR1Jsc1BZMUlBZjZHN2ozeU1VUkFoYzliY3ZhZk40UnY2NUUvOFQzcHc4aDZWN1FsRHdFRzNjM0hSd2JkbXg4Q0huU0d1RVZmNgo1VmZ3enlYOG42NUh3Y3d1ditBdk5PZGZOSWQwcCtvRU9nVlM4akhKNy9KdGgyNHh2NnU5L0JZQS8vVERYU2U3Ty8zekU4Wk5wR2h6CmZ2bDZmaGtFMlhMMmYzazBmMVNON0U3WW5UdlVsOFBtcVBrRkxDT1o3YjE4OG4vKzY3My84Ly8rZCs1Ly9oLytQdi9uLy8zZm0vbDkKVHNkM3YrOSsvNjkxbUorTGYxKzJ2dDd2UHlnV1lKdEdvWUJ5N0s4c3RnRG1oZGEzYzBLTmd1WlExQjVkL3ZiYnV4cEsxVWdidUhPQwo0dGZyQkNjdlA3TUt6R0Ewb1hzY2RYcHZXSmJlSjRRbkU2aXNNSk1vUFpmcEEyUFI5ZDlQYWhJVHNmY290UDkwU1gxNWNFRUMvaG45Cit3cEJVMm9GM2hlWlVpd2lZS1JIaE9vemdYSDFNMEl4cFY1RXdLQk8yT2o4Y1JVandJS1NjZWNFMUF5a2FsVkZBM1M5SzZzYW9NdGUKWGRuQWl5bFhWamZ3NXRCVkZZNkt2WjZwY3R3NWVVVFRoYzV6WkpPWnAzRHc5WGZRQVI0OHFUMjRIUFZyZG9GMWZpdkQ2V0hxelBYcwpkRmdPM3BidEU5RHNUMnloWWJRc3dsMmJ3dDIxQ2U2Q3hNZWJKbW1HQnhyNElIV1NtK2dEZXNRVWhrSlAvbDNwdHJYQUF4cmVUSU1QClVoWTJmQ0dDSlJnRENYL3p4RTd3WE9VVUZ5M3NMd3c0c0JwMWtxb0FPeUtZRkVyRkZXVURCaWVQY0VjQTZvQkY1V0N5SVhEZ2pzWmgKYVVhdUIwWU9IN1RLTEM3YkJZWWdMdUhiSVpEMVBGaHlRa1ZQc1VjZVFhZ0xCek40WlE4WXpyMVR6ekJPMGFoUTVYd2NaaEhqM0JVNgpianhyNUhRWkxlbzBMT1BDNVBsWXIzR3RtandtdDJpSUxNdlNDSGtNNFY0SG1PLzFHTXlObzBQdUI4cDNJUnBpN21rMHdwNGNYekdRCjdIREhBQjdoS1Y1UmRLNkMzNVVSWXh5TVlaWklCZUpYNlRSaWhFSjVvTEl4RnVxR3pvdVlYVWQ3ZEdjMXlTSzJBcVRJa25qY0l3QXoKMElNQy95SVFrZWdSZXk3NDVpUDIrVzVHL1BQRStKcUJZSWM4QmpEL3BqaEYvTU9wanZjT1kvN0ZNRGUxR3lMbmxlU21QM1FpVitQcgpCcGNiYkl4ai9KTjRqem1McGlwQU1ySlBCZXd4aERrWVlJR0ZNWXpJOU1nOUozd1hZaW5EWFkybERCTVVwSXdubXFWTUJQQlNacEpiCnlFTVpNY2V4TUFZUmpiaC81anBpZy9CM29UMy9RTVRBYmpRdWVOQnNtWTd4RkdPSVpacEhTM2dNNHZnWHdUei94bUJJWWtET1hBaGQKQ1B6elBRM3M4OVF3S05Cck1jZmZIZSttdUlTc2d3MjRNT09zaTBGRW5nWU1PdWFVaGlhVUdaTitDamE5UkdZeDUxSWdKVWtqeHFVTgpvMENGQ29oamdHTmJBSG11eFNBa3plTmwybjNiZ1dXK2g0RmxuZ29HQlRvdDN2aTdZOWtVZDVCbE9VZ0VxY2UyakJoRWxPV1JxQ1RhCmMwQXBUQjZ6TEd2SU5FdGpqbVdnSjJUeFZtZ2FPV2hyT3VDTkFZNWpBZVE1Rm9PUU1vK1hTZWVtQThOOC93TERQQTBNQ2xSYXRQRjMKeDdBcDN0QnVLK3psNkloaE1ZZ0lFeUpzM1haNUN0QWM4N0h0UWVENlVXTWN3NWJUV0FoaTEraEN1MGNjQVJ6SEFzaHpMQVloYVI0dgowKzdianBZbDl6Q3d6RlBocTNrNkhkN291MlBaRkhmc3J1RFVGc3BIa1dleGhsZUF5cGc3UFlCVW9xSUJla0VlRkR6K0h1bDNESXJVCnUxRExLV2tCcndOdzI1RnlSd2NrazhXNm5aQjg3SEtJNGEvSzNJWkRqVE1nS0hZTWlmUzZVSXNwOTNnRGdObyttT1lPc1l6Vms0aGwKRFBLa3NlYmppWGZhVWNReTFxRWlsckdpNVd1eEt1YnhNaUJpbVFjRmxrVWdTeG9qOXNSejR4SExYQThqbGpFUnZwYW5uUEZHQUdiWgpKSGZHZExlSVpRenlwTEd5NDRsbmpTamlHU3RPRWM5WXUvTFZuUHJsOGJydkVjY1lFaGdXSUpZdVJ1b3A1NFlqZm5IM0lvWXhDYjZhCnA1c1JSd0JtMkNSdnhwUzFlRms2VUZnK2JwOE5DOHlwUHhIRFdFdUtHTWFxbEsvR3lwWkh6SUNJWlI0VWVCYUJMRzJNMkZQUGpjZnIKMG5VeFhwaU9qTEF3bVhhL01BUEFMOHdKL3NUYVdlQ1o5Qnl5bExFMnc2U3p3aE1ZNXRXaXdEQ3ZPekhJYTFlTTFnTUN3d0xJTXl3RwpFVjBlTVZQdUd3OE00eDRHZmpFTkRKR0JmWVExK3U2WU5jbVhXQjBMdkdJSUU4VnFERlBObWs3Z0ZhdERnVldzTVRHRU5Tckd5ZDhECm56ekVzeW1DRUQyTWsrbmxWZ09QdUdlQlI5eDNobmhxSGM3b3UrUFJKRDlpL1N2d2lDRk1UKzdGdnFXWGxadkFJdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJcHdBRkZyR0t4QkJXb1JnbGZ3OHM4aERQb2doQzVEQk9KdGMxR2pqRS9Rb2N5b1BnSm9pbjFhR012anNPVFhJalZyZ0NoeGpDNUxDaQo0bGVjMDJVQ2gxamhDU3hpbmNqWGNUcVR4K20rQnhaNWlHZFJCTEZtV1llVDZlVldvNVhtZWhaNHhIMzNkWmhheGhtK094NU44bVB4CmxkN3I4bFVtMXVMOXdWeVdwa2IvL0lSM21OTmt0c3ZTbDBHUUxXZi9yZUN5aERGOVg0K2w4NnJ3Ly80M2ZIL2ZILzlyL0gvOGFmZWYKM1gvOGYyYk1vZi82TUxOdi9vOVgvYy9IN2hja24rQXN4OFlFdExKcnczbnpKcHdiRm5vRjk0YXRPT25nbUlDdTRPTEFtbE5PRGt2cgpWZHdjczNoblUzemh2c00rcTl3eDIvbGUwUUVDRldlNFFDYWcxWjBnVUhHR0d3U2dWM1NFVU0wcFY4Z0V0TG96aE9pYWRJY1E4Q29PCmtWbThtOC8wV1k2U0NlZ0tyaEtvT2NOWlF0QXJ1RXVvM3FURFpCeFkzV1ZDUkUwNVRRaDZGYmZKTE00dDRQSU1kOG9FZEFXSENxYWQKbkhhcEVQUktUaFdxT2VWV21ZQldkNndRWVZPdUZZSmV4Ymt5aTN2ek9UM0Q2VElPck94MndWU0owNDRYU3FCNEpkY0wxcHgydmt4QQpxN3RmTUZ2bmxBTUdTVjNkQlRPRGEvTVpQTU0xTXc2czdKekJtT2NwOXd4ZStMeUNnd2FyVGJsb3hvRlZuVFJJelpTYkJvR3JPMnBtCmNHcytZMmM0Y01hQmxWMDRHQVl6NmNTaHBMcXJ1M0V3SEdmS2tUTU9yT2pLUVZxbW5Ea0lYTjJkTTROWEM3U0thVGZQT0xDeW93ZXEKVGJ0NkNMaTZzNGVxVGJwN3hvRlZIVDVFemFUTGg0QXJPMzFtY0d2Um5qYmxESXFBSzdpRElwMDRtSFVpbFhnVmwxQ2srZ2J6emppdwpzbHNvS01QQnloUHB3bUlGMTlBTWJpMWc3TFRMS0FLdTREU0sxTjR4eGw3RmNSUXB0Mk9NdllyektPaTdZNHk5aWdOcEJyY3E2THBqCmpMMktheW5TYzhjNHU3cDdLYWl6WTJ5OWdvc3BVbkRIMkhvVk45TU1YbFZRYnNjRndSVWNVSkZpTzhiV3F6aWhJdlYxakxOWGNVUkYKR3UyNEtMaUNNMm9HdjVacnN6Rm5WM2RUUlpwc3pOWXJ1YW9pZlRWbTY1WGNWVUdGamJtNnVzdHFtay9MMWRlWW82czdzNExxR2pOMApkWWRXMEZCalpxN3UxQW82YTh6SjFSMWIwL3hacnEvR25GemQ1ZVYxMVppUnE3dTlna29hTTNKbDExZFFVbU0rcnU3K211Yk9jZ1UxCjV1UHFqckdnbk1hTVhOMDVGblRRbUpHck84aUNWaHB6Y25VbjJUUi81bk55WGphRWE0KzZ6eGRkTWx6MVJ1eGYrK2ZsWk5Mb2lVaisKNjhvY25hcEdsdEtEUEtrb0tLK3hCTW1hNGhzeTlHQ09wcEFDQnVIN01pckZyTWdpblEvQ1YwRVNROG14NkpxMHZXRUJ3RFNsZ0E3YgpKdG4vVWlta0RRNHVHaExJcUZFcG0zOWFnc0lqcmRhUW9HSVN3d2diWG9FaFFKRlBBNmhXUXBlNENYZUVlWkptaWcxSmJEVjg1b0xZCndLa1VIT0JvTCtSVzhEM01YVHI1R1NCZnJVNlk4M1FHQkJXdVJORTFkTThtQVdlM3JLQkUwYTVIb2RSRUg1ZmtnOFkzblVBYWFWcFgKb3FheVJxWXhzWUxHNTVTS2JVNnA5YnpaSzdzbkI5MytzTFJQWnp5YlRxMjE2dXNaUHErV29hRkNrd1pNRWpUVTEyeEszc0lGeE5rbgpzd3I2SDM2bGQ0SHdkaEtGNHRsa3pwU2d3LzdDTmFnRUphbXEyUXdjdGhVYmpHdkxnblpTQzU4UlgyR1RPMGN0UlMxR0hlVzg2VG1sCm5NdWhsS0JEQS81Vm1NMEQ0RG4yRC84UUdReXZoOEwxbk5xMEdmbU82Qy8rSk8yYlM3YUMvYkdlRXgzMW5EcnZmNGtxNUpZZithSmsKZDVXZnZoQTJSL3hZcWpsS1lacE12b29nWmhhVWlaak1jemNmNDM0VmpBS0UzOVRURjFtWVlzUWJtOHQ2ak45MVluaGdxMk5UM2ZJcAovUEZERWczVTJBakcvNFl5b2FJZFNvdlBqV2ZVYnRRZE41anYrM0FGWmlDV3lUaWZNSnRLVmt5bUl5eG1GeXp5eVNHYWozRy9Fa2FUCnpzd1lhWk0ydm5mNkVkbkk2VjRveUc1VUpGMDhxNUpvQytYZktFUXlsNFdvMmQvb2VRRCtCTCtrTUZZVXp6ZU9hbUZTa2l6WHNCRlYKU2twU1o0VGN3TGx2YWtaL1p2UTZGSnBDdGFDUEV1OTlpa0s5WCtJVWpmZG8zVC9xZlJKRWl0dmR6YTZmd0EzWXJ2c1gzMThzZU9OcQoxUlNZUGp0TVN0bW8wRVpEMlg5c1RsSlNwTkx3VWZxUDlhaEVQYzBibVgxcHFxNHdDMm5kUDNSbHY5ckliUHhJc2M3MEtUeVVSWlhwCi9TeEVTYzlWOGFjajN5MzdCWXJpQTFqd1pReUhRMzJ3eDgwZDdVWDlRSVhYVmNRdXhvVHlYbzhNcUtjRllUbDNuOXhUVnZReFBKeUUKeVM3OWswcVdCZlNjbFhRZkhaUHNBMHlXak1TeGlDcFNQY1Nacy9MaG1zV3UrQjc0RXZoMkV1WFh0QThxTVRNU3o2T0VSeWg4c3QzdwpuVHVLaGpheFRCVCtqUzFQSFhhRnlUN2dqbnlZbDdaeS80d0Q3dEpDNWcwOTc2MnRtVVZudjdZMUYrdjBlMXV6aTg1NmNTdFNPMkttCm5jZmNqSGdjR0I4R0l4cWp3R3RtTlE4cEQzbVlhQk1qRVk5UjFKSDNWeTd3RGF1SkhWNFdsblZqNzJKaCtubDZoR05tWWRqaHAvSWQKTDhTOFh4WHorQnRaWVltZDcwMnN2WWwxNmFkdTNjL2R5WFVXcjBBM1hBZlJhbzJXY0QwYTdqa01GKy94REpreU14Z3U3TXVvY3dwTApkSjR1ZjQ0c1lONnZpbm1jNGUrbHpOSENxbU82YnpmQU9LK0ZuYjBTbjRiTEdYcm04MzA3bnVGLzNYdENNa0tvL09qUFhIWDBlL2hrCmZ6NExJMG12cFBwcVlteWtKOGY4Ykg2QzdTSlRwZ2FuRkdDSTJ1WmNjODlCd3h3dFZpaXV6N1NHWXFHUmFIeWMrWHpQcGpjeEF0OHQKQnJtUUpvSk9YRm1DRDdQaTYyRDhtUjZ0TnlZTGtDTVBRYU1wZWxnaUNLcmVNSWt4elM2KzMwdHZkS09keDAwVFkrM2RCenh0UUd2SQpETnFPOGtaU2FHdVhLMHhtRFc1VVpBckFPSTVzTXQreFZ1cVQvYWhQZHZWZ3J6NU5UejBtMkZyL3hobFNqOWxWanpuWnN1L1V3VWxECjB4RVluNWZUalRSVHRYL1lsK3B5KzNxeXg0bFpPaWtLenZESEEwZVorOHFFQnNKbmZmV0ZBeDZ5TE1adFJNMkhidG1YNzdpL01TbHYKbmFvR0RNNDB4Zk9BY3BlYWxDNFNKWXBpcVJ6a3lFTmtabTNqUjlQVjdMMHRYNHg2Zis0aE5JejJjbkRtaHpYNkhnM0hIQURqUEpwcQpoY1FmbGduTjFzZStNdzZCV1U2RmIzVGlhNHdPSCs4enhFQW44dHczTnh3WlZuU200MW5mZmVsNlFFUmZHbHFsQlVQcWFCZEdneWk5CktwNkZJYU12RFMyVkVpamxKNzlvN2txb1BvRTV0SHBRNGRrK0JZUnJZWkhsNlZZYloxOGNINC9KWTdkclhxY2d4cWZYWUwyUllhdEkKYzVjWXhvSmd1U3JjQzBIWVpLa21QMWxPUGdtMGhoV0NYTGtXMEtJbkRaUXdvVWpodkxRZUNRTzRvZGFlQndGKysvYTdRNElkeUlVSQo3VENndGVmNzRzdHdiejJTU1lwYTh3d3U5MTQrUGZyK3lXSHRpOXJkVm1mUTZwWW42Y21uTmJwU0FTTUY1ZUhIc1ZzVk1Cb2duM0pCCkxsMlRxWlRlT2trYUtlaGdxZkV3OHUwb1NiSXV3NmZvRTNLNXFBUjFWMHpVSlZFR3B6Q1k2RnBPYVZBVjBvYS9KWGgrZ0xKSjZ2aU0KVDVvRE9sRW9HMUZvTlA2VTRQclJRdHBMN0JhR3dqTXp4anFEb0M4aUo0dGFnWkVHTmZ5YlpXZzhNN1E3VFJKeU1FVWFTcG9DSDduUApaVVF1TEZ3WVVCMlZBbGxwaWdRblltNW90T3FZYWR3R1JzTnZtVWtwRHNvb2RKalZjZUVMbmJ0K1d4ak9BMGtaMmdRSVQ1UFM5TWs0CjZNRHVuZkJMU205aWozZm9ZS3FMQzNRN2dWbU8wNXFDM1N0REk1MUFucEFocVNoMHZzMlM1YmhzRGxxdloyUVd2bWJwQWxzWExuRmsKc1JJdWJWSU9lMnRCenZGQ3A0YjBMbkxpWVF3aUJUckQ1cXFFOVg0TG9hMXdFVW9sR09xY0ZETExNQ0YxQnZNWW94QndvdU1Mc0RDeApDcE1VQ0xDMkg5eHpNUGNkckMvWVJrbEd3VWNCNnhMVDFtTzRHS0tCNnRBTGxFcEt1dldTcFFtNkFWeVRXS2xBeHoyY1ptQm1rcElGClBjMEtQUFJubU9HUXVvUEpEclY5UHpkTGhNMXZXR1JBSHI1aGF5alNHeVBQSkFHQUl4YlBCSGU2TkhXbkxtVVYwZldzR1prYTdiWFYKWnphRWFiV0J4T2lycVJGQzRPcGpSTkdWazZOa3d4aFhIU2VvTlQxU0ZLdTIrbGpaWU5lSjBYTEpLVmNkcnhuY1FseTR1M3hQWTBDRApjK2NrRE05N0RBdVFBRUlON1FDWjhqR3ZlTUFRTlR3OUZOcGZja20xZFV6WmtFaE92V25TcEVDTkc1UlI1WURqS09mQnp1aE15aFI4Ckg4VjFaQzZiNHArdVcyem9oaUJIUDdJYlJqcWxiVWZyUkVZZzBBcFRlaVZDWU41TWVybElGclIxNEFOYm9JL2lsWEk4aVNsN0FOTVkKZlFSSGtqU2g0MVZTb09NZmtHRXdCbXhZV2ttVjJ5clN3SGFwOE9WcEc3Mk9FeW1qd0FDODFRQVRML3ArUUdrYmNNOWxpR3lBcGx2ZwplQmlhaXJCdlpUaFkwRzBwaFV1aGd0RStDdHJBeFVXdlp4VGFuaGxncWtsQmk4THUwaGd1ckFHUHpYVUNyQ1NER0V4VmpWT1VJdGNUCmlzQjNYSm5pM01IZUl6ck9oeDlTRzJ0OERuc3Q5TThFQ0xRTzJBci8rRGllZHh2S0dEcDZHbVZjdmhVWVdMcGtadDhBQjRnUXVhSGEKN2hZVExIK0Z2OEFjVURtdUlFbzVVdVM0VXVHb29QSFpYL2lScWtsWTlpUllwRlBXOEoyQnRDQ25BTXdscmRHM2x5clkrdUd2SUFFQwo2cDBRTXZWRHdkOVJFMGh5bUJRZWdyUGFHQnlTSkpYb2RFZ3hISWVDWnV4N1dERGNDblVRTkpuaDZjbytOYUFLVkZkTlErblVwclFGClFXUjFVNHBNZ1Vya3A3T3gvTnFHaTlrNjJHQkNsemFBOVlJZWhiT0JYSmdCUW9CaTdKTGgyZ0FnSENHaExNaFlZWWVDUm9RUm1ScTAKZytseFhCenBnbjVQR0NpQm1WQXIrQlFWdmNBM3NmM01WcVZBM1VhdEMwNW5hUUVEcXpCRVc5dUR2ZFJiL2N6NjhlcytKWlNvSFRRSApNK3huMTI0NkV3MGJZb2ltWG1kTFNJUjlqaTJSYkUxSVJIVHNsNWtOS2hObzFrM0l0WVlkS3hCaXp4VVlJb1lQU0tLYlBLRkllb1RrClpBUWpPenJPZXcvQ2JjWG1yQUZJUnRFRzBCYU12aXpjZDl4UFFCZUhobE9xZ1FDWDdNeDJqaUZIRWNUWVorc2NTRkNXNVFJUEJOYlkKVTJocGJkdnVxbVhhOE1adXJJYStBR0tOaDZCbEg1WldqZ1kxaG1FMlk0bnhHNEM1U0FraEEraVZHMUkzUFFoNmhBSWtvRUhEczBWagptK0x2MXBKbnlWQytkUWRDUzQ3N2FxOGVLYjZPQ3BLSk5obURCNUdVcUVTYWFFc3JMTWN6elYrQjNhNGJEdUM2Q1VzT3pqM0dmMDJwCjBkWWVmNGZXOFFhS3IyeG56dGcwT3JBWm9BcVprdHhPckNxQlVUaHdFc1ZBMWdiTVYyM0R1U3lFaGlpbnQzKzUzalRFWTBJaFpkeFoKbHN1ZG8vRE44a0pFTlFNRTFNczhzV2tTWFRWNm1naDBuUmptSzZKTnJHSHZiSUo4VmJpM0EvN2NZWU50TmNzb0t0Q0RRbWU1M2pTRQpNWEd1UDlxR1F2YzlDSmNWWUkzbXNxUWd4bmd4QnZSVG1Kd0VyK2R1ZFpJR3lrK3AyQVl5WnpmVytQaE9EVlpiWm1pL2NkOFZMU1U4ClVEaEF6aTA0QkRUN1NkR3dUYmp2WkhMSU1EYzZGeENvL0dLSXBzZkFnTkFHUTdnWERnVjNjb0lNdEw1QTVVeEhoRUhWSWsxOEZWU3EKWVhRWUlYL2xGdm03NnhKWGRsMTJ1RDFGNkhWQ3M2a0RwSUthNE1yOGxYSHpkOWMwVjNZZEcrOTNhNEZoQVVwSVVKZzBLRUVaR3FkZwpiOWNKMlN3em5jaHQzZzIvYTU3dU53ZjFVZk4wT2tCbGxhQVVjdDJqaS9MY2ZpU1hPR21sS1lXQm9rbEkyMWdBL0VCT0c1TFg5SlY4CmU3Ujc4RmVzcFhQN0ZjYlJGbVdrSG1Bc0t2Y1ZWcVlUM1ZMUGcxQ1Y2R3R1TjB4RUtXM01DWWFpK043UXQ2aXo5QjMzQWhsOWhxckMKZlNYdkQrT2tMN2FMZFN1NS9jNmlKNzY1YnMxeFgrdnFFUnpDZFZ3N0FvTWJQd2RsMVQwc2k5bis5V1JBQnowUmxpK3BLUk5ONjNMQwp0NzFDcS90WGFIWEdTM01UOFI5ak0rSjhiM3JHak0ybmVLNU56VVEvUjYxVE1KNjhZL05haDdFZG0yalRrMUdOVGIzM0QxRmdacWN6CldLWThzNVBwSVNaK1prdHF3aUZtMWhDdjBPcitGVnFkTWNRdVhoVWxzQ0NsdXpCMHJRKzBiMG1SeVVXQ2xpazNCdz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJYkRoQ1VrelBDUjZKOHhuckxyeVh6S1duSWFIR21XMGpuVzZEYTUxUFlNVnYrUlRHYVVpb3NTQ3lBWFJ6MnB2b0w5bys4RFU5dWZXUAo2bjFYL2pwNk1DaWJKMmY5MXVWd1lvY2lEOXNMUEsvbHhnZzZwT1Y0b2NhZTJDZzBCclFiUlRjMmM1bnF0UGJ5d2V4TkRlWlRJVktRCkVWTjdXNFlPWEtYdDVoYStITGt2ZGZkdCtvdjdQS1JwWTBLVEtDNXptTHEvN0dVWVpLUGN2aG0rSExrdmRmZHQrb3Y3UEp5cjBxRHIKRmhRWWN1SFdDano2SlpRWUprOXV3Z2Q3WTVPRnNyZWRmTnZ2VVRnTTlMZGUzd3NKSCtNZjlyNjl3Rjl5Kzh2ejdpWDgrK3owNTdJMQoyck8zNUdyN2c4dmg2OXJUWnEvNXFoelVuZzNhcUE4dC9LMW1menhvZHJzZGtPUVhyenN0Vi9JN29QNWVMYTFkakJxMUYvM0xYdnZlCmRObFBhL1c5dStNVlJMS3d4bmhoWGJzZ0ZGRGhVYmM1NHZJd0daNzFnSjJ2eHdvZnZHNE9XdjFtdDFhdlBTOTdyVTZYaXhPS3RpMDYKVnFFNSttUUluM3V2TGtzdTZ3WnBFajJod0Nya2hoM2UrN1RXc0t5R3NSbGo5QWNlc0tsZXc1REUzWWF2bUhrVDl5VDcveFQzRHp3MwpZeEJNN2NHVGsvMEJUTjV1U1JpT09xZXdlazRPanFHa09VR09uaEJoei9zWWFIVkRKTTBaYktBa25ocjRGZWNLL2MvK1B5Z015YUsrClhxbnBkS0psT0lpTnRadGNVN3VhMnNXUm9HYmhnRVlORmZTL0NvMSt5SUdadGFwd3VrMHVLNENCV0t1eGZwZmRxL0YvY1h6dTFWejQKWk5pQ2hQK1VvQko0TTlUTVdjaEVrVjNFam81dnkxKzRjRTJNZjAybnZ1Si9jWm1wRkZRU1dqdTQzalI4a1JnRUFkcGhXa2pMZzJRdQpEejdzaUJiMkYzN21lYmgzNzIrOS9pODkrZ0liNWQwSDNYZkRZZlBrOGZHbnRYdmZ3b2pCcG5QdkFleWtiMHN1Y3UrZ2YzNkJVLzlSCnB3dUVZaVVZOUU2dlpndFlxRlhlNzdraW40UHVldStIenJBRCt4MGluTVp3UEdxMjNxeUFZYjg1N0xUaTZvUCttN0o2ZlVrL2RKOE4KWEVYQXVPaXA3WHUybU9OQXJiSnQyL2tlN2gyV1o3WDd0YjNhM1FnUGJ1ZjNhOVJzN2Y1ZTdkN3o1bUEwZzdLRGZxOTkyUmxWSVdvQgpGaVIyQmU0dTVBWGlDcHg0eGxQbTArbUpXL3VuUUR1VS9ZRSttU1RQUWVYQ3hGVmE2NElTTnZ4VXUxamxKV2d4emxIZkcrU250eHA5ClB5d2Z2aTE3ejlydGlteStUZ2JoTnB2a2lzTFg0Y1JXME9QeE9oUDJhVDZqOGVZdWFPTndqcVpuKy9KQ0NWQlJWL0doZkNpdUxHRFEKZnJmc3RUOFVod2paeXFzcGtCZnF6eVZrNzk3RFg4dldKZmFCZnFDNlU4S3VoKzdDZFpaejc5K0hpWEcwMjUwVGU4L096b2JsNkZNYQpnRG4xWFlVbjNlNGxuV3I2ZzBiekF0VHNlM1lud3B6eWpuMTN4NURXam9DVnRZZG5aN0JSUWVudk9xT3JDTjY3enk1SFF6Z2ZSZDdlCnc4N3dvdHQ4Wjc5K2VvM0MyUzhiQzdka1Blblo3bFFTS3B1MlpqNzBKdlRCSisrMVNta3llS1JGbmtlYTJHMEk0YTJaUlZ0RVUrWGQKcEphYWRMMTNsSjNtdkRhYTgwcTIvQThpaGNTSFVBV3RSbkE0NkYvVWpsODMyLzFmRmlzUVdOQ1dhelE3c3pXSE1WeGVWMWpJVEUvSgpSYk16Y0tTaEJiZDJGMS9OK1hTT2hQZG5GUEYrVEIyMnV0Um9sbkNyN2ViZ2paUHpGdkM2UC9pTkFHaGZjN0QrUmJNMU5neVh3L0w1CjhkRis5M0l3VnZjMEFNZ2UzQm9PV3ZIMzAyNlB4ZzJPRU01Z1RFTml0YTNhdzE4dm1pQmQ5OHV6L3FDcy9WQU9oaTRxN3BZM216RUgKNVMySTVrS2E5UmJOTzJWL3ArenZsUDJiMlhtdks1eDFkd3JZblFMYzVaTHIyMnBtaW5seVI5VU8rb01lN1BnZlNzeFBJSzJvbXpVRQpCclk2WlFZRGVpNkg4NmI1N2tDek5RZWFxM0ppWjZ4ZVJiRGs2NjNEN2xiam1xeEdWSEtTTk1NZ092Z2dkVUxPSmY2QUZnYUY5MnNtCi82NloyOG51VlBFRGs0djJOU3BuanlGemJRMlB5dWJvTmZLNTJsNkdVWmc2NTczc3hjSzk3Q09TUXNWT0N1MmswRWJwQkdzZ1NYSzgKZUx1VEpFNlM3SGN2eTlxMzVicDc0RzlabEdBb2R5b1QrOGFPeUdSV3VHajdFTWVkYVludnlZVElrWW1BYmdIREtpaWcyK2pwWUc3eAova0xvTm5paUU1TmhtSDlEWmpJM05pKzdTQXFLNWNicjY4TG1mNlRJTzJSTldraGg1ckpHYkJOcmpESDRTZ2ZNRzYwemtidnBrZ0pMCk1sUUJOWnU1c2dJL3plVUpKcGZjRnBaa3VhRzUwVkNTbmg1eEJqKzZBWUVzUVhzZnpxSE1vTVZ2TGtzd3ljclc4Q1RQMGpRWEZJK2EKRkJuZkV3SVd1WUEwV0Y1UzY3bThVQitHRVIvY0dIWXJLeTQxT3FWd2VwM1NnNzU0d2NzSzZrWnFweFJtRkRBcUl6R05VYjl5TG1PdgpaNFpkcjJNdnVnRjJEUTZLclpnajJxUjVnZk1nVFZKTWp1MFdtOTJYTUJtQXdGdHNxQ1NtbU1ocDN1d3dHemc3cE41TmoyWFRRNms4Cnh3MUs0bzBBT3pjMDc5Z0dVeVBpMU5EV1JETm5hbVNiT0RXdWRXYnNEc3M3QTNvNGNCNjhIdlRobVBuWHpxdlhYZmovYUtQT25ldmkKbFY5OFJXMmhUY1ZXb3RKWWVLNWRaUnI1MVdOSzdqMStkdnJ6QzVnTlg5VGkyM08xWlhUY2l5OWFZUTVkMTQ4UWcvV2c5NnBidmlnQgpHOHljNy9yNGs0L3pPdXdBS2NUWmlmS0g1UVhNNWVHejNsaTRGemxaZStXUXpFR0ZCMU9Oc1lJRSthRTU2UGhFWjJORTNmdSsxMm4xCjIyWDE2SmtYMVdNUTU5NFNUNlFTQmEzZzFmYWVaSkpiWTRReDJ6eHZsckJ1Wm1YR1BGYjMxdmM4bDVyM2hqYTkyOUYxdFV6b3VKMFYKQlQwWHJXQ1dpWlFDYnREbWdQcU9zOHhNZnBnLzBUQXIxZXJUN0VZT25WYWF1R0E0dkVMNm9lSXZ4bEJXc3pNclhodm4zYzQ1Y2dCegpKbUtxYmc1Q1BSdFNmQ3duRy9pNU43cW91QzUyd24rKzhKZWJLUHpkTW5NUjBYTlhYbXBrYm5ZaXZwcUlsMlNBM3F3VDcvV2RhUlprClRKc1RUckIvQ210cFJqNm9KRm1ZRVlwU0pHMVEyS1c4cG5qNGozMld1TGZrdG1lUzZCdU4vdDZBTVU3ejZ4L2lqODAyTW40RGEzUE0KSXJ2SW50dGF6dXRqckZ6UCs0alo4dnVJTjNIOWsyOHE2cW1iaXRsNzNGVFVremNWeGNSTlJiSFJOeFZ2VFF4L0ErSjJsM3RwSjRJcgo1MTdDQ1RNejh4Sm1YTUkzTStuZnBKYnFOR3VrR0JZa2lpSTFqVlFrK2lOSXZBUlN0S0JRcUtTUU5rU2pLQXkrdTBCME4zSmpNQlA2CjdlVDUrTmhrMjdOTDdQcmpidjhYVE5TNVdkNjNuWXpicVpuT3h1OW44WHRybVRHcWFrcm03YXFRNzZNZnlwMCtlQldaK1UrQU5pKzcKbzU4aWFYbmNPYi9vZW1rNUo3SEorenQyWnhFbzNOUjREdUo0RlBXYThvbys3TFZEVnRHbHFVbWZON3ZsYUZSUzM1K2ZWdTd0M1gvRworYlYvK3BTb2Z2bmIzaVI4NzNscm1pMTNmM3pkR1pYMnQrb0xCd1lUOWc3R09ETkgyTjBYai9kckw4cTJRNTBZZXNHVlNoc3RWTzdWCk15NzdqN0tMeTk0V056SXo1REFJdGl3dTkzaFFsajFYVEl1c3NJbnRHMExxMUlhNmU5S3c5TUc3SmhmTzg5UlFPR0ZtQ21HaWhMcSsKTUY2L2NJV2xLZXdWUUh6WjBtWHpGMk9GbnpaZmxiMVIwNVVIcFFvb1JPcXl2TWhJcTVLWnBMc0lpY21VdTVSZ2NncUZGWHc3UWRqNApWMEw1bFNqUzJ1T3YwcUsyLzVYU3pMWUVxaHFiZDE1SlJmaFRTYzhGSjBsU1VBTE5BcEZSNG9ZRVgrQWpoekpGeVZtMEVoajArQ3VaCkE5clUrQ0hMb0doS0kydnl6TjZIVEJKaHg1cWpuVlBmelRGOEFIcjhWWkZFK0xBdThKYWl4aE44bHhtUTVOcG9kNmx5S3RwWEVOMGUKSC9aUHdMK0FNQWtJcFZBVW9vOVBEdUk0WkNLMVVlcUFXNlgwbzRGcFdSaUtFQlFwTU4waDFOaEI3UEQrVjdwZ2hFcUwxUFVuRlhtdQpIQ1lYN1Y2aytCK2FSc1JNeGlTUmRTbnhMdVdSeGljSmM4dXdsS0pYWVdLbk5yQTU1OFNsR1haeENwMmdrWUJoak5CcHZLSWg3RjJOCjFFNmNJa2x6TzZtMXU0ZWFNZWVBV1lrdWVNS29CQWt0c0h1RzhXWEtDR3NlQjBRWlRRZDhTUU1qS0J2U3h0SGlBM0J1cGtqTFFZdFAKMDBEa0F0QmxpaGVOU2ZGVk1KeXFHcTlJVUU5VElOamVLdEdaMURSN3BNMFBZaEZSdHhUeTN6RC9nUTVhSG1tcThCVTVaQnFsd1lXRgpsaGh0eHhYRElCUnlRTnE4cnhHeUJIbW1lVlZrc05TMDdRRE0zU3kzekJjOGhwNDZPNUV0bWxSNTRvVHdpSEtsNko1TWtlVFVLNlV6ClRjRVpPQUV6MnkxL3FjaE1kY3ZnWWhVNlk2bTFXZ0lWd0tMc1ZNVmVTY21yS2M5MFNyelIwaWp2Nm9qQ1F2Z2FRdWlJU0xFamVjN2MKTG1DeDJOV3RGVFdmcEtwUU5neWZIaXJ4bWJZVGZNbE42Q3dNcHV1WkFieUs2Rk8yWXlTdVlieGdmZEdhVTFvU1JzRTNSUktlOWFuRgo2R1k5VFhvVUYraXU1RW1xSlhVQ3hJUndpNm13VTFWS2l2bFZRVHBpN0l5OWdtSm5mWUtMRWdZRWU4WURxUXF0cVE5QWVVRkJOYmlhCkVrdXd2UU1WaVIrV2ErN2FENittak1XdlVMeWFRUHdnT2lJcWt3bE5BNEZ2cU52NDlNSWtGTGhFRDZZblBEWHc3ZlBIWHlIRmhSY2EKQW1hYVphQXFwSDNmSnM4a3pZZlVyZnZBUHRzL0ZocVMrVmNrWWNmTjZPR2NCRjlXNWFVUTlnRXJYakhDQ0tkUHZBMmtOQTVTOEM0bgpjMXg3c0hxVkpQbU43OXJhWFRyajZXRndwMEQrZWZLQW16aHBjNXI3bmxNZ2xSVXRPc0NaMnRrTGROQzhNTG05YVc4c2xBU0d3a25qCmVhOXg2eE9wb3RXWmVkR1kyb0VERHRIR0RkeTJLd3prV0VGeTIyOVZMTWpUZUt2Q1o2dGhxOEloelQzU1RKTWlBc2lVSUtUQS9aeHcKd1Fhc0NKbVhhVzVBcE9ZOEFJQTB4NjdTaWpYYXM5RmtWcnJsOUZJcTNYNnhHbFFpQkYwbzhoTGNYMnBRTWhvZEZPTEFBRzFvbWJEUQpUSVV1eUVLakNwRmJ3WjNDN2tYVHA4Z0xDaWZqWE5uS2loWHNQYUR4VzRUQlpTeG95OGtsb3pVeXRmTS9Vd21oelZVQ24ybUhNSUlHCm0zZWVsUGRhdDNmRU93OXRQRjc0cGZaeFpMeGdLQkppQXJBVEh4Q25TM2ZFQkRmbXVPMjRPU1hHaHd1bktPM2JYck9BTWJJM3NnQzMKWlMxTWZhdFhBVlB3eFdkY21idzd1Z1VKU3ltd3RrQU9XTVl5WDFXV1dXR1l3VzVrN0NMTUJDMUxBMnViMkNpNXI0S1hWZUtDOFFncgo4VFVscVdzWGszWE1ramI5ZWMycXg1R3VQY3NoTzE0NDREaCs4MjVwVlN3VGFqd2J0RjUzMmtzcnVXS3VIcXUvKzYrcDBjdnpjejRlCkxtclhGcHVKNG5HLzJ5NTd0UmNVVzdVRVQxd1drYzAzMmtZSTBEaHJDMUtWUlRuMkp5cTVvbllYdS90NDBIeEgyYUNldjFycDBHUDMKV3BTZ2ZoK1QyaTVtZkMrVGtHallmbWk5dzduQkJuZWlnaVZtZkhCaUdlZVJ4Tm5wdDM5VEtDdWdVbnRmRjlZekxYa041eGVhaU9ILwpUbTlESlVLalJOSXMySTFPTTlwVU5DajZ0S0hDSGtwQnBpQ1liTWRTN3Mva0I0czBvN1dJU25ubVJTY0lYMUltdEVCaGdCK1NMQ05rCkVyWmIyczJVLzMrOFcrTy9LTmhZQXNHbXIwaVFvM0FwZFB3aHliVGI5TGxia3g4Y1lra1NrODQxOEMrdmJBbVNsOGhVV1c3Rklld2UKMm02NFJVNXFqdkgvSDl0OGREcStuOEd4alFTcmhIT1hzUW9QakxVOU4yVGNwY2tQRG1ObWQwalNKVEtXT3JDOUdPcWJRQTBzb3c4NgpkY2ZYM1AvZnpZdEUwYmFQZ2h2KzVWTk1yblJoSDAwUUtjMHpVSjR6NDg0MTNKZkpENndBSkhTWXdma3J3MEhyU3VsdzZOaEdlb25DCmdZVi9lVzM5V0o3V0R2cmQvZ0RPNmYzTEM3L0szR1FHQ2EzNDZoc2ZaaUlOdTRnVk1wTjZGVnQ2UlE4a2ZwS3hHWUhXQmVrNWJxUE8KV0EyUUZpTlBGYXRDMFo2ZGVSMEt5RXhwL3dBZW1kUVpHK1lkVXJXZU9xVGFQdGlSTEhCRXBVTWg4REViMGhUakE0aEZJWkdjTkhRQwpGbU5tdlRHcHpQQm1tOVVSN1ROMGZNMXRyQStTNW1uR1MwbkNTdGMwcTJTR3pNTG1UV2FjRXNmWDVTSkYwL0VrTDhMOEVoYlo4MzF2Cm8ySlQxQ3J2NWh4MWhxUFlQRGNlTXpEdDdJalRYY3k0aVJROHYvRUxQRk4yTldyMUtxLytpQ1IrUWhEUi9CZjA2QT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJY2pUcTk5d3p0OU1QMzA2OU0zajNlZi9pKzR2eFdrZzFVT3kvUDIvMnl1N0pRYmMvTEczQlo2NWNjMVErNnBUZE5oZDgxT21ldzU4WAp4MGp5Y2RtRTdSb1pNeWpiblJHK1JJOFBhMDI4VEgvM3I4QTBlb0N1WFh2VWZOc2ZrREh2THBINjZlUmJlSmJHK2J4eTQza0lwSjJYCnZSSDByNGtQQi9MMzJoZjBMYklSMjBlSnJWVjd2MXVXN2FQeWJQUkRFNjFvdGNrWC9wTGFXUmRmZ2VyQkhMZ1lsTU55OExhc0llRVgKMklmaDRncXRidWVpMXVxamtmZlgyZ0E2MmUrNUdsbjAzR0JjWTlBY3dteXJ2eTFiSTVCRnA4MXVzOWR5dmJyN3o2ZkEwY3Z6Mm90eQoyTzllT3FPcHo2OExpRVROMDN4Y2ppNHZLSnpjNG4yT1hSL1YwUERzdWh5aVNJQ0R0YWZsOEhYdEJUWGUrWTBNcjFFenRrYWFqTldBClpYRnhPVnBTSndsVVRuWHVxTmw3ZGRsOFZkWmdMbDVlMlBMZTJRRExEWWgvVVY1Y2RvY3h0bWpRWHVCeWkwWnQvTmZ2K2hmUmIvZGUKUGozNnR0OHVaODZGKzdXN3Y1NTNlL0J6SGRnMTZKekNnbmZEZE8vQkFKUXVXK3VhVVh3QS9GRXAwSmk3N1VIcEdNY3VHLzRWL3huNQpkeWp2L3JFM1BIbmJIQXp2UjlNcEx2bzJNSkxnd3pubGVuNTJ1WjRNeDc1dEtIZDYvVjVaZ1RIZGZ1dE4yYTdDR1M3NWdTYm1WZWs2CjdmVGEwRkZSZ1RhWUhMQm1yZkJZVGw5YytnTU4vM3R5UWl6a1JDWDZPL2pBYTVXSnYzUlVOMm1oZi9HMjhsTEhvcmM4bzVFOFVHOUcKL2ZQYmxXVFhOdysvR0RaUm1VQVZCNVpZMWVsNDdldmlHQjhqV0p1dWJNTXFIWjc5c3NhNzhTMHZneUcrNGIzaG8xeUhjN014ckxMTwpvL1NYVHB0dUN5OGRYMWZ3ZGdWd05acGVseTVqeDFLaXVPVHRVaVhSNDdHTXFIZFY2SGwzMjZUa3VwRExLUG0xa2ppNWJVcjhpWHNlCkdhZjlFZWdCZUxCL051aTg2dlNxVURWZFp3MzJmQkoyeC8zTFFhdmN4MERZVzkvMFlXdTY3UzZjbDZObUczU2c5KzFIOFo3OStIM2IKbVRTcXpLNm84T2V6dHFLeHVYUmNkdi9hSEIzMlcwZjlWck9MWjZraC9UNXIzdm15UUVzNWVISVlsNHgvL2c3MUkyelY5VjZvUnRKSQpvcTYvZWZEazBXVzN5M1lhRjdRSnY5b0t5bHRubnNNdkZ5V0ZlajhlZE5vbnVHUWVOVnVsejNTQVEreGVjWHZlNy9SR3lNMnBXc2RBCldiRGQwRUJNRnZtKzEzRzkxWGt5cjNVeUJEMzhkZVJadTZBczlqUXVxblNPd24xbTQ0KzYvZjdBaHUxUldkemRza1ZsOS8zTVdGcjAKQlJzQUZwVWt3cUlPNkxsa0VjNW5GODFXWi9SdU1VY0paK2lvTkJpdk5yc284aXB1UFM5eXNhQm9RS3JtOC8rSFR2a0x6TFhEem5BVQpMSnRHNjNRQllzK3JISk1UVVVES3NwazFJbk1rRlZqR09oTDNFNXhieEdUMzlCck44YmtMNHFEc2RnOUFXcnVDNlZ5Y1dQQzQ4eHVQCnh2eHUvclUvNlB6VzcvMDFVb21RYlhyUk1Idkd5VG1sdnZPeWJuN0RoR21TUWQ3YWJTTGJkYk0zNnRTYTNVNXpPRjB1dG5IM0wwZmQKVHErc2pjcGZlUlY2TTNIQk5tc1VTSCsvQkd5amQ3V2o4bTNaSGQ4NUFLVThPYjdvajhocDk3VGZYbUs2NXphSGRLdGl1RXlnRWRFVApFaTJwMVRXYndPZFBQYzRrUTVQbGgyYXZNM3dOcEVRemtWeCtlU3JNVWt6WWgrZmRacS9FU1JJTHJZVnJtMnBRY0h3SG1ZZExvWXlXClQxWXNYejRCejNmOWk3anJWZGRmUUxCUEtsV013MlNBQXhGVndUR0xnVm1ocXpFUVYvWnEvTHZzbGdPcitqM3B0Y3Rmajh0V3Y5ZGUKcmM2anptQzRwQm1hR3ZPSGFWNDFUODc3RGE1SGM4V3g5ZlduaGpiTFJMV2h0ZTYyNlpGbHlnOEcvUXYwVnRyTFpOT21pUW5OS1JjMApwYktwZHFPeEdXL0FKVlI2NnE1UGd5NzBZREE2N1RjSDdacVlUcjhVT2MyOHZIand3b2tRa0FvcUZncXcvci9ydjdDTld1TDd3NDdmCmpDVDNvM29WTVNIWW5neTVyODVqL2UyMHRzc2xZcFZ4Z21tcFA2ZGZOTnZ0Q1lGOVRvOXFqSUdHSUdzblFDQ2MyWnZKRzB6N290TVkKRittdGZuZmdWZEVIVDJvUExrZDk3elFzSnpDU201RFY1TnFiWHIvMUJnUjM3WlVOeVZoUXREUHNnOWd0YTZkNFdjY2x5Um9yWE5RdQptaGV3RHd3NzU1ZmRabkJReW1qbkdRMmF2ZUZGRTA0SHJYZlFacWNOcGJtTFdpcVpSMldiUEY5YUZEUWlvZVhJZXp5bldFVlVyeUtkCmExblpBVy94c1RJd282U0lPcmkwYU5TQnBXVjlCNFJKODlTWDVEUEVRYlAzdGprTUdvNFlHNy9uN0ZESCtJVGF3M1puMUxTQ2JVSVQKSTQrdWxUZVJVL2MrL3V3dmVrMU04Y2w3WUJNZWJ5RnJNQmtmY3g0YXZLcG1YZUNMbk42MjBoSHFFYkRDcUJKMWZMTFNlRXVpOXZENQo4Y3BOMlZyTDIxclZ3ODZ6OC9pSHg0LzZ2VkhRQU5Qd0F3eExxelBtZG5jUDZ2N3dHUHZ3ckdkekdFNys5ckk1dVVpcHd2bEYxKzlTCkU2M2o0VFppVzFUdCthdXpjZm9BZHZqZDRYUkJsQ2QvS3djVHl4bCtlTmdER2U1RlFkVHd3L1BUc20wbDBMaW9ndDhvTk9lN2FTdlQKMUFHak4wWHJWSkhYL1YvKzJtbFBFSDRFN2JKMGZ1TElXUjdZUWZOdVFUREh1RWFPVWhaVjhRZW9pc2NjOEdVSTN3RUdweHk0NEpRWApjWERLVk5GblRucytqclhuWkY2cDc3eGVIMGU1VUJITDlucy8yUENXL1RpOFJVd1VmVFlSWTFNbC9BV1hUR1UyWWVFbGZMSVlxekhLCmxsM0txZkZpczFsbHkxVGpsY00zUHlDcHFQWDZJV0NwMXVsUlFCSnFHS3haTFJHYnJxMTd3Zmg1NytmK2FZUFFOYnRkM2hHR2swYXoKcVFvZ2lXQ0hmVFZCd3p5OGkwc04zM1F1VG9FamI4YWx4R1N4QVp3Y0I4TVNxUmtzTGduN1dSQlRkNmVWd01ueVRIWkUwWDIvcXlHagp2K21mUHVtZDlXdkI0TGFFMGZONmR0b1puVGN4OUd4Uzd0dTlJaTUrOGVyOFRlTVVOOHYrMlZuRG1yUGRQajYzK0Rrb3djUEo0clBZClBvNzhjbGpDYmtNYnMxK2dUaUd0L1ZpZTN2c0JSRi8vM3RNKzdPZmxUNHZaaWF3dmlUTmptdlpVQjRhamJxTnRtNkJKd2tPNlpMU3cKbWlzZjdMRlY2bHkweitIbmJxOXlweTdhbFpIYk1BVmZZOWJZWDF3TVhMRUZZd0psWE90dW5JV2NPZEpRTG5JUlpzWGNVckhQVGVUegpTblhPWVRFM3VuQ09xMVp5MU9jQXYwSXRMamtJeldkNmJpOXQyWGpHM29YSkJ4SzFYVHQ5VnpzY2RON1NZMzRMQmdHeDlPS2RZYnFoCjFnVFg1aGVLbWJZQVZUK3lIUzVBTmxGc2F0Q3BGQjFXRm91MGRqbnN2T3JOT096TUZMbW56cm0wQ0NNVjdKOTFKczMyczJYNDBFcXUKeWlKMWJEaW1xZTRPR3VmZXpqZXZSS3Zmd3lSdGVGcGRRQXVXOUZ2aXFiMzBaTSt4TTBzUDJvMytBSlgzNXJUZVBWbndESlFGenNKRwo4YXd6UzEyNEUvNml1VUN0dm1vc25IeXVqQXU5RXNuY1VrUDB0VEN1cGVYZUxxWngyTHJvdHQ3TmwwcTJUS3MzYVFpYkxET0NzMTUwClZwOURINHhUdDNteG5BK3UzSUsrMHc1Vzl0QU50a2p1WXFraEoveFlPbk9wdUpYVFlXRlVxUU5UZm9TWllseFA4R21sZVhzMGlIaFUKRjhkbDBZSU5la21aMXFCL3NhUUlLbXNkVUYrV0ZCdEVtVHFXTllvR2c5UG1ZTGhnSE1kVmpMQzlWQ2c4aWtoYVZqYmFZeXJvUmFFYgpGUXI3YmxRb0czVmoxaW82NjQwYTdlNWlrV2ZMWEF6TytyMUY4ZzZMRFM5UGVUMm1zOFpvQ0lSNk44dk1VUnlDS29ySzY4SWl2ZkpWCk0xaHQ1eFRDRXdnb3RNUEZzd2JMd1hiVFc0eXJLeEJiMDN2YVpvLy9zREY4M1lSRFFMbUFTMWlvSEtIUGlIUDRSeGJmaVlManBiSloKY3Y3WGk4YlkvUTNxMnF4U2cwbmRudXhIczBxK21uRUttRlhPN1lMQndUWnJmb1Z5MWltMnVHUzNzMEJrUUFGMC9qWEhEdEp6Q3ZZdgpXZ3VrQ2hVWUxoaHhLdEMrWEdnVFdDQjVvZnBpTlFOT2RNUGxld1NWT3J2c3RSYk1FbHZHV1NONHBpelpHS2hPczlkalcvdnMwelNWClduWTBhSjFINnRMZDd4dkhqWnE5NUFpbjNIYnRYM2VQZjN6Mi9GK2YxdDdLSlllemM5RG1JcFZ2bGc0SlpmQjQ1ZjA0YzdyRDE2ZGEKNSs4V0hOdWpnbjM3SnZmMDJmb0JGNDlPMTdFdFJnZEw2UFBPcjJYM2VUbkFwR1JUMXBqajV0dnlLWnlkT2hmZDhzRzRIZU1LaC9WTwo3MDEzT0lKRjVmMyszT3NudlRjMXZNVTIzbDF2Vko4dzIxN2d4VHMzYmphbjJ2UERSODZhaFZwRC8ySmtUVkRqSnNKditxZTFaL2FuCnlPYVZaZU5HdUxoVU1NdmYyKzh3cFErT0Q1NDh5ZlZoaVRNQ2YxUi9lZmJIZjM3MjVZOWZmWEsvK2ZMemI5SS9QcXZ2ZnoxNGZQNzYKaTFlOTMzM3o2SGVmMy8za29OTnNEUDlndnYvclEvUDdMNzcrL3ZHZm42cS9mSEgwcjArZWZqMjRiR1dQSHNxbitSMmgxTytUWkhqNAo4K0dyejVNL2ZIMy8zNDAvZmYzbDV4ZkRyNGQvay9mMjdueDkvK2gzQXk3MHpXai8xVi8vZnZUMWw2bzhQdWg4OWVmV1lhUHh5YXVwCnBvN2EvNEQyc3NOSGQ3N0kvdnZ4NlBEbm4vYlZmOWMvZjNEZVB4ckM0STVlZi9abjgvdkxSNGZxRHovdS85ejk1TWU5TzRkbnlUZW4KTTVIOUlTdk9zaC8rL3M5L1BmanVvUEhEL0ViamNsLzg5UFdYYng3OTlQVVh3OGI1WjRlZjM3bDhkUGR4KzJ6dkRqSHIwZitjUExzOApQUHZweDJ5LyszWDM1UmRuKzY5SEI2K3oveFpqN1BpZlB4NjJ4TkYvdnY3eUw1LzhhUEZBbDRjSC8zNzE3ejU4K3VOL0RwKzBuL3h1CnY1Ny8vSWNIeC9YZjkyd2ZYamJibDN0M2lwL3ZmdFo2Mk5KL3YzdndXcDNjLy9MQm5mU1BuKzEvKy9uL2ZQYjF3U2ZmUHpvb0wvLzAKNXgrKytmM3IrNjFXOHcxKzZuejI4T3pvdFcxWkpQZWEyYUR6aC8vNW92UHZiOXI3M1R0LythUSsrT3hmbHcrT2p2LzRIK3ovcDEvZgovK1oxdW5mSDNQL2hwNjhmOUZxZm5ILzIxZFA3OTdMemYzM1Z5Yko3dzdQMHdhRDFSSHoyNWd2aE1iWU92eG4rQUd6TFBpbXpIOU9rCi9VWG40RjRUeGxjOC9lcHUvZk55djVzOVA3Y1UvT1BvenRjSFQ3NzgvWThQUHkvMEVNYmx5VC9ONy8rY0hmVC8vZG1YUDdULytZVTgKL2YxUGhQYlB2VHRBMEovTm4zNlBRL0pQODZQNWV3LzU5T2Y5TjUrYXVwdWFQN1NQRXZIVDc1OGUzbXQrK2NkSHYvdnN2d2ZZaXNFZgovazFZcU1qZW5lVDAvejVSOVBtelB6LzYwbjM2OHNlSGY3UEZEejUvK0Q4V21meUhmQUpUOTJYeTJaLy8vUEJ6ZWZpWFYxODVQRDkrCjllWDk5cy9mL3B0RzBuY1k4RDNiMTY0VktMVC9qZS9BVDZFRDR1NVhMN0JRcVFpbWY3ZC9lRUtzUGl5SGYxSG12ODNQclFmZkhmNzgKMmVIWnZiLzk1Mkd6K2NrZjlzM3A5Mzh2bnQ5NStmMkRad2Y3encvUGpqdi8rZm8vUDMzeGF1L08vMi92eTdmVFozSUZuNEIzQ1BzTwp0dG1Yc0dNZ1FCSUlFQ0FKTzRFRXdrNzM5UHh4bjMycXlydnhDbngzenAwejV6djlhNEtOVktXU1ZKSktLdVdDdmRhUUltWS9QT3NYCmg3aTdrd3Qyc3k5azRmZDltUC81RGZzVDMzL1dCWm4vZHVHQWdLbFJKTktjYlRsODBiZjlYelg3VW5OVnlZSnpWcVZvd3hDYTRuMncKK3FlZHIrRk9kOFo3YWtLcGNIU2NTYlJPcG16cjZYUytuSnFJc2p3Nk1BdlJQUmdaVUc5QWNsN3lKNE8xMko5WkY4UW9tUzVnNUdjbQpnRmdnT1VxU0JjQWRMbzg3dDQwTnhHc2xwQ3gvWVptRm9EZ252VHllRVpYQVhQaDBlcXFWc3NNbkhIRk0wcjFMakVqSGQ5V1h4Wkt0ClB1RzBESkxVUUlUa0NKK2JzVG5wc08yYytXVzR1U3E2YXo2UzQxUWdBTDB0MURCdnhSbmswQXdRcWo4Ym1KclptVjhzaThkSVl0cHUKWmlOOTRsMjhCcS9sZFVjQTIxUXFlajJUbU5TU3hGYnphdDVnemJicU16ZlFNS2xZSVZmcnJhUkdpOTdrdlZmcVJiNkIwQlFKakNnRgo2NWVjYzNvbG5hL3JCRmtJOVFsM3FqVHlHcXpjdk1Dc3B0OWtzUkNLNU1MZWx3NVNPRDY4M1BFZ3BBWC9hT2ZLL1o1bWY3bjFwclBOCnRwWmRDd0JSZGJNQWRrWFA5cGtnYmQ3SVI3YjV2YlNEbjMzWmNtRjNiVWxwUzJmaDIxNE9nOUZ1bDVRV0xIYTZaUT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJUm9VREJOV3ZWb0RNTEI2N1VNR1BDcFBnOGozYnRrNlB3dmRzMldicll4MzlYWHVUU0tOeEd3SEF3ajNmUG1ISjNNcXgreUdUSmR6QgowKzM5cG12TXB3bllTM2pLR3NjbTU2TGpjZi9PN1RTaXA0Q1RIYWZJQWd4di9uYnhQRHB5SnlySGI2Q3hwK1pRRGordlA3SnZvNmM4Ci9UU1dIV1dTNWJ3UHZETHFBQzFRcytYdy9ubVlmVHUzZ3R4VDlETFFZK0NMdjh4aEdyZFJxOFdYVDM4dm1YN0pieUxONzRVRG53emEKMllETmFDbENuczdqcFh3dEF6K2xzS2NTL29qTkovRTA3bkhrMCt4M0tlNFhCaXYzSnZvVy9wbURxakNQZm9qK0RML1ZpQVo4K2tqOQpta0dRaDkvbEtHRFpwSmVNaEx5RkpqSHM3NHJ3bFNSNkdmNVpNRmpaNGVYZ1M4OGNIQW9MeENjRWtXRUhuMkova1VDdndORzhvaUd4CjA4MmlnUmlzYUpyVWhPR2dJcS9sZWd0K2wwREFPQ3dJaEpoRXpKREZTTkdmTEx3M0dndjdhL1NiQkh5T3BwSG1TSWxlUjhPanFMaFoKSkJvc0NkNFFQVmtzU2RIU2dkVVhMcFRFMGw2eEVLSmxvTEZRdjRIRTRtQ2phU0E2Q2NueGlHYkYvWW1Bc1poTEVtUElTTTRscGI0awoxSkRSSnhZaWhWVDRKOFVXUVBQTE1ZWXNXOENYYSt5c09GYVJKQlo2QURqNWtsaVAxRnlSNUREa2VPVG1ERjkra1NLcVNGSlpBajVTCkZCTk5FOUVrTGdTUkZvNG16MkttZUZxRUZMM01TUjNnWkc2MUJLdWE0cmdXdlE0cGtaVVFsUVE3d2xkV2VWQk1paDdRc28vQTZpZTEKTXI4Z2tpTXFJc2cwajBrcFFEUTFWalQxc1NHMUpLd01VZG9TamJFWmp1TE9GL1NKSWorY0JobzgvS2N2TlAxYzJWYW51aUV6OW5rTApXUHJmQkgvRGlHVTNZSzljMU1oUnZSY25qUzRmMk1YZ3ZLTE1idSsxQU11bHNNcThtOXVML005Z21DbE9WM3NidFpYeHpJblE2VlhlCm5lR2JIZTUzNU00QVgwem8wS0NCRmhaZVo1b3kvVjRyems5dWp4TjRXNWc1MDdFN1l2bmx1ZGt2Vkt2N0hIOUN1ZUU4Mjl3VVhqSnYKZzhNRVdMRHJ6Qjh1eE9KR3ZrUDhHVnNQazk0UnVSVS85WnVjSDhBSjdleUtVMC9Mbnd0N0NDL1BiOFJ6azBWaDdpcVdPZHNLV2twUAo1eGhIR05vSys0eSs4RnczdmhFQlhGUG8yOGJXNVBhYk1zOHVBSFNENEdmZXJiL2UvTXpDY1FGTENWanJvZjR0em9rRzF3UmFTamM2Ckp4cGNFOXJxWXpuVUM2ZEd1Y3dDMzNldzRqeVU2TnAzS05OcjBMYXVhUHVvKzVSRFppeEhKdzdVLzF1ZUJYS2tHWCtxL0ZtbzVzSjIKZ01BNXlUVXlINjVjdy9wMVF1WXdWQlVSQ1RyeGZSSEU5cWx3MVZlby9FYkdITm1BWndFSlI1TS91eWxIT3V0YUsvdlNyZ0oyQjlKSgpNU2MzRURtbmdxSm5LaHgyc1FKUXlxM0RpdzlrL1J1c25QMS9PZEQ1UzZHMHNzNkJlRFdTTUtneEJaODhwOUxPTkluRjNJbmdzeEJzClRjWkpTZG9wRFZQS3ZxMHpidkRyeFI2Zk50TXZSS1p0ak5HZWFzczFCOFJhQlZXY2ZxSy9NdWVYbjhZNEdQQnd5S3orbHc5TTF3ZGsKUDdlcXU0RWo4dm9kWkFVa0RoMkRRVzVGUEJxNUJ5eXpZL0haM3hxRHkvUWs4SkhET1RKWi9QU3hVQ0xrNE10bEpvdWJNNUJLd2hyNwppMUtjNWJINFA2S1JhZTBwMTNqTmdOMmk5L2RNRC9UY3MyWWJ6MjhkNkdzekQ5NS9BelNOdHpZc3NqcFBYckhhenJjdUhWL21CeEZtCldpcEZ1TytOMldCbFdaTE1IQTdMZGpCZWYwOGpCQWtzblJoQjd5NlBmY2Z5RlI3c2wxMnVuQXVlY3hqdWFSK05nalg0R0dSamlhcVgKZmRBSzduMC9XZVNMRlQyWmcrbXBUTHFjbmlCUVYrL0F2L0hNTm1CM2FwTGswR2xjd3BrR01zbkpZSk41YjdodDhhWDc3UWRzZnJGZgp4T2M4N1h3UndDaDdDMDhIMTRqaXNVdU9NUlpUMUp1cy9BcUFhWk5lSXB5MW9SMFF4bUhVNURmQUJSMlZwWmMzRUNpOXdCWGNmdWQvCmpqOWhHRlh3ZmpTeHArSStMNEtvd2N2bmdXMFl3YzdOU0c4QW1DL1ZOWG9samtlTndPWW5uYjNYVTdiYXcyZlVNajVXbjJlRjJWL00Kd3pDZnd3VDg5RFJXeUpmTjFHYmszUnBUUGlvUVFFWFAzaDlEOGZuSU5xZnBWSDcxNTlhK0pnNkF2bTJRMldHd1VoaWYyOUd2NG5CZwovUUNEWHhneis5ekF3ZTVZUzVidmdOWU5XNnlBRXJFSzNITVd4WW0vL3lPMFlaREcva0MrTzcxZjF4YkFVb3E4MTNkdndyMmJlak9TCkRCVG54Y0hMWkFoc2t3UlVPTi9PNHRTTmZXYURqbGdEcUwvM0tHVUwwT2dENWt3eTNiWVZLbjgvSDdsUXArdkxObHl2aTJ5ejVRYWUKUmNsYStvcmtWdmpzd0RkVnFBM2wwVitvZk5SYzBOaG9vbGVBZGs2K1NRMCsyckpaM3NpaDJkWXJmQU42NWRaUmk2Znc1SEE2a0hIRAp5ajZ5SkJiV0ZlQ0ptQ254YlhsYlNpQU5nazIwZVN5NlhlRnYvdllHMTJvM3pBMHlIY3ZweEdLdWdTVmVHTU9uR3RrRW5CeHErYnlDClIzWWpWdmtvSldrUTdQNktJclQxMysvditJKzlVUWNtblNkTEZucGxsOVRVQk8rRjNBWnI0bXY3OGFuMFVzY1ZlWjRtWGtTdkpPWUQKNXdyRjBlTFBpOFJQMGJQdDQwQXpodkRzVzRqOEt2MmRYSGI0M2krallTNjR5SHdFZTBsOVNSa3k2WEMzbEgvT2Q5SWkzcUJQTHc3RwpEMkEyNzV0Z2tUTjdublZJZzhKOGdMenZPNE1WSFlCSXJJRVB5R2MxSEg0azkrVmtZVjBMY1VZd3ZZZ0RzN0h3L1RiYTVuOU1saEJnCjdPQkxkcE9xYktWNENLNExaTHFYN1hRWHEzLzc4ZXhMdkZqTkpISTd2dVZOanl6cHlCeThzVFBVeVpsczVHdjJYUGlPamZ6Ri92eGsKRTlFejludXd0OEMrUCtobHQ4c1hGNkNZa0ZsWWN3bjkrY2tOSGd3cVhlRnhTZW94SEpCaWtOZ3FXMnhsSTdFbU1odUhoZS9HRWV6SQpsS3FnUjFzMmsvbnMxNExNWnhiTnN1VVJyMlJqL2xWVytwV3M2emZUYVZYR1pMSnc0bzBHYUdLektSTi9ueTh5MGQxaGlPS1NsMWlBClErZENhd1c0NkhXcGRhYVVtU2VFa2l5dDYzL3VWS1JVQnZ2THZwL29zUXNWQUlxeWVJUmgrZ2Jnamw5YnB2UGRPdk5ncDhKUDU0S3YKT2ZObTRzKy9LNTV4RHY1cGhVM2tKazhmdmJEaXVzOUM3elgzQjNZL0FmbnRhLzl5UGhneHBKNEgrZVFvdjV3TDVjSHhXUEJNeUdMUwphYkcyQVMvMjlybS9sMVRva2w4YUpyQjlyZnJRVWtyZ0RxRG5nbFpncXJYOGhlL1dBVGg3MlBjZlR3SXJ4NjlSeVVvYXE1bURlWEFxCmZHOFBQZ21HallGZGMrR0VaenRkTXYrZERuRGlRL3N2MERpSXdFQXNaV0tSbHU3dkQwYUVWc3RDS1dXZEF4TWpGcVppc05OTy84aUMKVFpDT3l1d2RPcGVmVUVkMEMvUGtBTG9LWnpmbkFES25QQUdYd3hrTkhSTHZ3Q29xL1daZjhGd0F1Tm5wVlNhWjJwbjVzc2lZUWVEVAp6TStqSW5iMDlNT3BkckNZRFhtckRhZ284RXNzNkNVMDBBRkp0Q1QzSkJOWjJ4U25vUTNBN1BVNUpZaGx6MGJlNmlSWWc5NXJkcHY5CmRraGpBWlN2UnVWQU9JRDFoQzNpZFhjQTdLUXRtMUdUcEFyWW5sb1hPY1puZysvWUNRaHhhNVBGaURUWkFFdzF3b3JUM2lGVXlKUjMKZStabHp4WWFkR0dLa1VxOXpCb2RITkxXaGZ2eHFmL0VvdzdZZGI1eTYwakdnbHdKK2lBekRBOFhJcTR6MUJmTnVQYzdlV0JueWc5QgoxTXRPTExkZTcwWWlCNTdqTWQ2MlBTbE9zS1NkYjhIVEVNUFVnK3g2UEllbkVtWjRXSU5sbTl2YXFlQjUyYzhZUzJsMVprZk4zMThRCkZsdHhhZ3AvQVUvR2VDQ0wwV1paYkd6c3k4MGFjcFFUMzM4MkczRGJmOE9jTFNSaEFkU0J4aTc2MEdJRExBbzJSZUs5Nkg2eHV3RUIKQjE2bDkxSjFJSVpWQzhCTStxUXdHNndzN3ZkTWNrMDYrVGE0R05pYnZOeEJFZDdubjR1eEVkcFEzS2xqUDhZcFI2QXQ0WlFlSFExbgpEM29vei80ZmN6eEpHN1RNUytSdzdROERIUmxlWnlMZFJURWJMUjFQOE9qYlN6cWV2SjA4M3Y0N0p1WngyeCtZYzlQSng1emEveUVyCkV1cms5SFF1MUpibmJIU3lXL0MyQktSdys0MXhHZGg2V3l6eGZaNGZ4S3AzNnlyNGViOWdENFlSMHhpczRUMGVld1AyOWh0SlpoYUEKeWQvT3JaazYvNGFSMDR2b0FQMkFPbUNmZHdMWUk4bDY5czJUQWV1eWNHMzRXQkJ6RnFkbjB6QWI5ZnBNMENBTWk5Z0xiRWViZVM2NAptczNDbmZaWEp4cEo1OHY1NWNmTUJEMHNVeWJaQ0F3SzFXclN4QjRXaTM4RzdERnliQ3RtRWw5dFlIWkdHbTZNOE95blFNdjNWMkRQCi9kNWxtK3ZRdTBBSmo3dVpvN05yS2xTZkFvRHR6Ym1kbEVKbFR1MWYrNUhXOEx3eFdNR2IrY2ZDSWhRMkpUM256NTl3YXU4cUFpL0kKdFNlVDVKVG1SbFkvc2FxSjBVbTBIanZTVHNXcnpmMllpWmdLS0hjQURPUXJIM21iYlpQQUd0OVpCbDR1dUJtZnphYXRPREYydmViVwpYcnhWNnZhN0c3QXVweHdYemFOZWVSNU16dVRvNjd5RTJSWjI1QnQ1TjU1V0VDMEVmN0V4ZUxNMHRScmZmdTg3V1BpMkk3dVpMSTZzCmJoTkFIQkIvYUEvazVWZ0l3SGFBOFRvNEF3TDJyRUN0TmM3Y1U0ckgzck90ZHFURjBTNjJ5dnpXd016LzNnVWhTMGpsMFR2WW9uYlkKTVlzbG4zZThtQ2dpVnM2ZWJCVmNQLzVwMHRPcjVySlJUd1hDcy8yQXVTQlpaUTBpT2NvemkwTmJlRVZnVE9XbTJaZHFHUjZYTG5xUQpEb1JnU0EwVDJCem1ING54Ky9ZWGVLLys0cStWTE1hMlA4VkJkOWtHQ3NmYmszaDlGRzYvZlB6U0dxWkdmc3JDSnAybnhMWTREVHRECnViclQrUlBaVkJwdTZJbUxvOUVOc08vWFNUdGdaMHUvNk8xRkY3bmdlOERMVy8yZmdXZVJiUldPcnZDK09rNC9BdC9ZQVp5ckpDN0UKeDBKeFBRSjVtY1JYajRXdm41Nlp4MmdzSE9UV2d6M25UdzVFb0pGZlptYmVRbVdkZnhkdCtSalIrRFNUam1vdUN0Ymx0ZS9aOHVZdgppSU9IV2Mzd0EvM1BVSEhTS29ZNHpTakEzSWVHUTNtR0F0Wk1oS1FmUXpFVjZDTUhzSmt3NWhJdmprZS9udXdtYlh3bFI0NHZBZ3JEClorSEorSTF4dzJOZ0R3ZUp5a3U1R1k1MzJ4TXdsemxKbTRpQTFXaHQ4WVF0d09vRE04OEpFSHp5WS9YaHVQbExVMnBSS0RaMEYrdnUKR0pBNnR3ZklVT3RZbktiS0FGVGJ0clBFMnNVUFMyenhEbnhrTUxJeWpNdjdCdG5XY25xQ1kveXZGSnVDSjh4N0s2Q3J3elJrK1RrKwpLdXYxR1NXNGJ3OFB2QWFlT3F2WlpMS1NOVitqTHAwUURGTUxYd3ZrRUYyQlU5aitlME5kRGl2K3NXUnlzdlpyNTZXU09Sbk1UUDArCmowcXdpQi9RSkQvZVVhWDhQL09qSWh5Q2dvTXlUQ3ViS1lDRExyNVkveWdWbUdpNTNFY3lBWjhaT0hXTEUzblkvbVVQcDM5dkQ2dWMKU3ZFajgwUFlneWZQWmEvVE54VEpaN015djJzZGZ2N2dkU01LNmVjc1VjZUxlWVZmZWlFL0RlYW1lNjJ2OG1lcE5JVG1mTUVickJJOQpHRm9BTW1vZFJKTXJlM0MwbG9DQkhzYUgrY05wT1grZ0t4a2Z3TkpBSGpvKy9IczUzendjeC8rQ1FqYmVQUENGRWZMTHcvZ0l2K1p5ClpKbjdRSHdQN1NNQ0NmNFZBdnZQOXZ5d0E5ejlBS1JzVHJFcVFrMkJXOERlNUQ4Q1JKNEhnSXo5NlFhTS8rRzBoU0NtODRjZlZFNDkKZmxpUC93T3ZLUm52ZG9CdEtRaytucWRMT0x6S3BvQ3E4RGd3RkxZTklORVpqRzc3emFIL09UNmNOeXZZTk5pbnJHSVlzUUdncDRlZgpuWEk1QUVON0VvajQrM3dDTDJCVFgxYXFLOFlQVTE2dDlDcGJlcTQrQktTb2N2d1NJRm1OMERvQWFySlhpMGkvR0VRMG9JdVF0WEpmCmphdFpWVUQvZGhwdlpyQnppVUxsQmdPMnZ0MXNwNmdMakx3T1ZzSkY3UURnTVdCY1doSENuVU9ERGhUbzRPejBzSjJNVDdYeGYrWU0KZ1lPYVJzMVRaOVVmNXJvcmdwRFpOVmd0eUUyMkFvdHhzNVB0dnpUc0dJZ0Y1QlNvUHBYTjF5UGE1SVdpZEg2N21hSGl5OG9NVVB6bgorNGVwTWRDdzA4ZzNkRkhlb29VRUUzTkhXQWZCdUNYU1gvekNxZ0wyaWoycXFFQ3lLNHpZVU5IUUlVWjE0VGtTY05NSUtoSU9zcWs4CnA4a1ZUWXAzM2ZmNXJieWlMc1pBR1lQZGhMNTNraE5kamVoNHYzN1dla2tCODF1NlhmcC91Qi9xRXlSdEtwRm1SQT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJV0RBbU50RVVyUm5xNWdXNEN0eTlPakkvVUxwTVVrbEdSRVlaeDF1S2xoeEVNejdOVzh2ejMyUXovbGxyTU0xb3dXbnhMZ3BUMzhxQQpLWUtJME9KVk94TWh0Zm1BdCtlOGE3TVVkNkMzOHdTdTZIWnpha0lPMG1iRlNzbWlWR0VvMzlJRDBFWDNjMmsxemJsU1JPV3BJeTRUCnpWM24zc3ZUa0hwRS9XSUQxcklSaXJTYVdEL3BrMFBXa0FjK0szaUIwczE1MXAwVVZhL0J1NitnNFl2dWh0Nk54ZTRhZmNNV3hSb24KbHZFU2wwNXVndTFOSit5Z0JzZEpkVmFEdHhReHp3eG8vUHh2Skl2RzNLblFLT0pPZHlaK3pPK3VlOTNwNVNrQVB4SEJaQ01lWUI4MAoyRS9vUVNLUWJwMXloZTlZYVZVMk54L0g4T3dxeFQ0bDNJL044TkxvREpRZmpWNi92V213R3QycFZkTG9mTzdIako3bEQzZzArdllaCjNlZjRtOUZUN3hhTVhxeE9ZUDdIbmdPaER4bnp6a2J3U0J6cllIQ0ZWVEQ5TWtvRmN0RkFOTndQLy9WUjRnWUtpSEJQc2ZKd25qZFkKRDRmVTR5VHIyVDAvWmFxeFl5cGFUcjc3eUcwLzJDa2VQdnRZb1UvMld1Umo5bkdLdTdLUkRZMGxZR200ODE1WEUrQ3JoZVdtUzAzSQpGNmpGTElCaUZ5L1Zqb2RENHRnQ1NEd1Z6Qjk4bzZiQmpld1lKVThkWXJCZDJiQ1pEVWVZWHppd2h5L3NtQVN3bzJkM3FtUzBvWW1qCmRTbXNmUDVqdEJTTTdoTy80TS9TR3Z5NlZ4QWkvVHg4MVQ4YjBraExrVUVvWGhuNEpKRU9MTTgxZzFXRWxrTWEvcW1Xck5KSWswYkgKNFloYkQ5SklYL0hQb0ltSXV6aWtCaXVIOW1qMzFMMHlTRU5MeDlqZUswb2pEVG8vM1VsaUlUMVRFemtJR3F6bTltNWRrNW9yUnVhcQpHUm1rWWJObGMzQSt5aUR0RFREeSsvbU5RNHFLTEZtMEpXUFNoajhOVzVKSVMyV2lKVXRlb3A5cWpSQlN3SXVUb25CTjN3RW5mNTVUCk5ZaldlYm1xamw3Z1k0MDdBZExnOW9LVmFsaU9SdnBxdDR1UWhrSi93eDJIbE9Oa0N1M3c4TFhjdEdTUVpzYmhDR25CSlpFTzBxT20KSE5LeXdXb0pPQktmMG5OTkdyK081dVc4S1kyMGtYZW05cGEvbWhSU2QySWRUM0ZJd2JvSVdjbVY3bWRlcEpFR2V6Mk1qR0hQa2toTgo1Q0ppYWY0UkwxSklEVmFNL1BvaVplWWFObHRYbTNwZUR1a1lLM2xHSFdta0pTeHJuenNpUFlUVVlCVVQrR1QycEdta1BhOURST0QwCmMvQ1JKbS94YzBVS2tQYVRXQzNpeFNGU2x3aXB3WG8wbGVmYmNIUHNKUURheUU3TXY3V1AvbGdHYWRnY1djM0lnUnpTQWxaM2ZjVVEKVXNoam9ybFc5dkhNNytHNUtZbjBMV0VQeUNLdHp0OENtQlJTcVBtREgxN3NiZWcwU2MzMWFLcVc1ODhmZmFkREVtbkh2bG5JSW4xYgpOa1lUaE5SZ3ZaenJSd25yVkhkSmFhUzFnTFZOWnBLUDBraDNUeVlwcEVBblE3U2RZY2wwa2lId3h3djJucTRXcEpIV1U4WGhvUEgxCkpZbjA2MlZWUVVqaC9uSTUxOTllYUViS0lQMk1ZbC9IdFZjYTZmUHY3dThsRmcySWtNSlVBb2gyV1BGdVpBbDhzTDY1alRKSWUyMnMKK1BQM0pJazArdXcxR1ROZlhxREhBTnI0WGl3MDUyRmtTQ09kQkp3aW9YSDJhMk1YUWtyWVU0NnljS1kxYk9TS1p5RlNENGNVWUlGbwpBZGpmUGFQMEh3OWlwTWV0N1pGR2VrcTdSVE0xZm80L25CVFNYQSt2Q0JXaDUzQnNwNHdBQzBEcnU5UktGUythSzBDYVAxMm93cklwClRDRk40MVd2U0JGNmRzRm5hcWNKV09MNUtrSUtzZEJvTFlmRGVMS0JTREVSMHNNaE85OHkvUHRrRkNFOWhuN2o5RTZUampkOEl2S2EKdHZOUnkwRGJEL1B4TUN3Y1ZMbHRHMnpqc2s5N0RmeXZJL2QwaVpWSDFqUDM5RUx6QTlWYnNNbjhHcXlCeloxbnh2VTdqNGllaHFQNApzRVUvUGE2aUYxSVozaXhOWGFubmxGSjhyY1EvWlo5R0NWZHpKUDkwT1I3WVdZcGRQczhTdHY1VTltbk52VWtUOGs4bkw5OEo3cW1JClltSHppMms2S2N2OE9scTJsWlB0SS9YMDI3NlBpWDdiZHY4d3h1azNib3BmVUt3OWVYcmJTRDJudEZ6QnZUcklQbjIzVHZ4RythZWYKaGZnalF6R0o1eVBySUdLUmZmcDdldDJWWlordU9rU3V3VDI5b05qZmlrd041SDROaHRSSWhHU2ZQaEhCVkZlZVl0YnBadkpXay91MQp6V2lyZkxwa254YXo5Y2xjOXVrVGtUYmg4aFRMR2dtTE15N3pORlRHaW84dVpzNXhSMEwwMU4xcUhOUDAwN3d2S1piS2NtdFVjbVc1CjU4RmowTk1VZW1CNWJHYi95TlA2WjJSZHc2YzcyaDBsaHlGSzllUzJ4MmZxazBDUEVTY0w5RER6UnU5VHJBYzh6TjhXL01jSHZ5T04KbmtJekQvOTVSLzRiNjcxUk9vTEdOMjdtR00xM01CSDJ4MWN2cmMrQm55T3d4MUxtZ0IzODhPa1B5UWIwZEhnUzRhOUhOM2JneDNiUApRTFdhYkFEZmQ1TEZaL2IvUEU2Y1FEdVppb2Z6eU9jVnFOdUR5V0RsMENKUFJ3WnAyQXo5bkE5cHBNRmVYeFlwMkVSK2NaRTl4cDhyCjhuUmtrY0l0YnlxSGRNWkhHbndEUGpJUGJmUTU5OFpET3JQWnpCeFNaUDJ6U0FNaThrTHJuNTFwYVMxQTZ1d2g3NVdQVmtEZ1IwSVcKS2JMK1paQUNmeEJZL3dNT0taaUxZSzVmc2tnQmdZOUJlYVRRK3BkRmFyQkMrMzhwUGRlazBhZUV0R2FYUllwc0NnNHBsSDBCV21oVAp0QVNyT284eDZORW5laUdjK2Y3c1Q4dDdnL1BmaGkvN01tK0d6ZnRCc2Z1aStsNW9TZk1kclMxeVlNNmZXVnBiWG9qdXlQRUhxZFBrCkJXaFM1UGxBS3hmYlcwWWs4VEMxMGNQOWs5bzVaaTNhV1ljNmlmTDNVenRuY3NkQ2RDQVFxVmpaOG90R2tZcVZQZ3BBY1kyTEVIT0EKVTAwMCtsVFJTdi9qcVc5cEJNZ0VaaEN3dGlVWUQ1amM0NDU2U1JSOUFtb3Y1MS9PQzFiMm55YmZZcVpqWmkvc3l3V0lwY1NmN3VncApUY2VVd0pEYnIrQUxHelJvenk2R09wVGRUcXRqM2d4ZWJVSUNzaEUzTUdEc0tXUzFvbjhnUTc0THZTU3BRYTFpRmRHZytFTWFudTJBCmRlc2V3cDdHZUhFMFVUZ1FrUnhveTY5enJxcEdkUGdQUFhqS21aZVluOTBvT3orRGxac2gra2QyQlpuMWV6T3ByNStablorTDVqR3AKR1VManRhMUFMTzNydDBYOFNYa1dHb21sQUF4MzVYNUpXVkFHTGV6T0VDdmgxY1ZaSEY4SmRtU0tzMHFmZS8yVWw2UTdNRzc2TkNmZgpUSGtpMTQ4OUtkUGRJRThzb2VweFhxcWVRVkdvZWdLeXFzZWd4cnJGejhxQlQwQjJ5QUlDMmlqVkkwMjdBYnlLaGlHd3pIZzhSUS8xCkQwMDdmQ05OdTU3WEtLdTI1YVFTeGVNa3A5WXo2WjhhZnhkRGt3dWtPNjI2R3FsTFZSdDltaUE1a0lKYk5DditMc2FiMWZ6Vlo2TlgKLzBLTkZnR1d6bGJYaEtRMERPQWQ0TTUxZWJSbHhaRFA1eU9uRFF5dVc1QlpKczhPSDF2c1pUUUdLczUvSldFdytWMTZ1WFUvTXB6RAo0MlFVMUpFR2htc0ZKZ1VLMFoxM3l1TzZsTHN4cVZYdWxLVU83SlZqVS9lc3VKWm0zTlBHUGZDZkR6ZnZrT0tDTFlCbWRCU3JVc3NKCktNWmZVUGdQV0ZBdUVIM0pHMkIrckJhODVJMlhCanNrM3JqUVhFNGx5WkdsU3BPajNDUXoyUHpVOWw5WVlaZEx3bmw4ZGZmbGtzeEsKYWxhWVZ0V3ppaDROVnRtTlNZUE55TDBNckptUGsreTJaTERxV2Q4U3BFbFp2L1VrSmZ1emtsQlBTeENydnVVMlhvVWhuZEpQc252bApTNU1lanhhVERneEozcUJqbHM1ZzFiYUN3TXRYTkN6VWJIN0JDbTZzaW9hRmp2VXJ2ZjV4b0NoT3ZnSFkyMGJEdU9CVloxcUFDVGNVCnZlTmlUbmhwWUQxbEowYlBKUGxXM2MwVUd4N3VTREdoUnRNNXJwMHdEak9LSEM0YzExUHFlS1YxTERoL0FlTXBTem1EY2dhdDVBWk4KNUxwTG80b2U0eG5ZMGxKNVNwdnVKcFc1N3Q2aXoxR216bU12VnJJTWoweHFIRzJnSjY2Zk9qMlRUYXZ6d2RxV1l1cWtqdXkyckJwRwprRFlNeXlLbElDa3Y2c3VVT2lxN2VLS0IwSng4T1JRVkxhQnBJQ0xiOGpxYXFJZzlieUNVait5VzJhSVdaUmk2L3REaGsxT0hrc0lrCkl6YTNoL2c2VG55OGdEYjRWSUU4WDlTQlFDYW9BU3hCbzRJTkk2aytaQVNrb214MkdLeDZCbVcrVWdFSXRTVVV1YStUVlhsYjFxb0EKS3B3QzBPcnZ5OC9Qcm9Ia0JtMUVGOWdLNnZFTXNTWFB4ZnArSy9CUTcvMGVURlU0NGNXdlk0blRESUpjT0VuSFI4WW5CN3kvREdqbApUL3JFU29sWTJrVmMxdTFCWGhJZ2xrNFJGeENMRlhIMGk0QWx0dklMQmZ3SnprVW80cEpldDNwMENYQ3RTVnVFUkNtVzhDUU95WXBICm94U1NGVVZJL3A2RUZyeU1VNndla2dWVDR3a1N2ZnE2d3lSUE1DK2hyalc4d1hwSjRxRThuWVhiOGhYaERjQUhld0pOQ0dXcVhLeVcKOXJVUzdha3ljUitEVlNsSzkvY0VEM2Q3TjhWOUlGblVZMzBpVlNBVHI0SFVDV3ZpWko3ZUZFUWFkZ0pUT25NV205S0FEK1NEaWJSTwoxbUJNUXlwWHhhYTBIdHBSOWhnYWoxVjVQRnJqQzRGME8ySVhjUVRQRjlPMUVWWkZsdkIxOGhKdk9KV25wczduVlc3elkvZVhLNkxSCnU2cDQzNU9ia01HcXdPbUFkNFNiM2pVS0lOMjJoZ3dxYTY2Tk1FT1ZJTDFCdE5YSjJiS0FPcUtOVG0wZjR0dXkxRng0V3gwOHJMTHoKOHpmZ3JNQjNXcGhCVnVwNG5Kd0g0L0hwaTNsZnpybjdKclhiQ1U5Rk5SOUJBbUJ5OFZhcGFDdmxXY2pGV3lFd0hjSW43UzhCb1RGWQpiejZrUUt1bXZPVVpOTU1ST3BMNlJrT2ZpVk53YnBWQUNncnJUWEpRR0oyc0I0NytmWS8xOXlXQUNVNEk5VzJpd3ZOQk83SXVQQTZoCnhabEhhYXAzT1dISW8rUlRnMVZkRERWc054QVk0ZE45eGlkalJNQmNUcGNtVXZMTXovaGVzSXVKTmRweDVielFhTWVWK0FCUGcwYVQKakpEa0FXRXkrMXMxV3B2VGFJejNxc2VDRndOVDEyZ0dqU2RJRU5qMUdvMlZ5bEpuZXdlTkJsWk5TcVBwbG4wQVI3OUd1NGhkVUhCdQoxMmdReXUxbnJ3aU93bW1RSitkZ1QzSDhCcXVVTlNEWWhEcGJKUSthZjNRb2JhTUVQVTFodmlYd2VTNWk0L0M3V3c5Z21mM2wyNzZYClYwTWFMYk04a1BPWGs1UXdVeEY0ZldvV0FPc1lkU2xaZzFWV3pWNlovU0FVNWc3eXBRV2UrRFVHQ2xnMVVWS1RuSVpSaDZQTnRKZUYKZ3VJd0FNN3RLUkFJaW94RExUcDVWNGNqUEhUWEdGNldPRTFBd080UnE2YjJRakEvTjdRdWhMc2grTlo3aTMzUFk5S3hxWG04MmVQcgp2bXVOWnZGaUY3Szc0YnN1KzE0NUJndUIzVzdmZis2bDlrSzl1eGhjTmYwaHJjdGRETUs1eGI3blFXSDN3dXQzTVFSSHdyNlhnc0o2CnJ6Snd0TzZHeW5zaDBqQ2YrNXQzUThGZU9CU2ZFeU1zNE51N3BDTkIvU09aaDBYdmxZTGtLUzROUTlZV0dCNFVsb1JQU28rRzA3ZHUKOTVaWXRTak9ENERkS3QyOGNVbkl0bkt1dFFMRk5KbTd6RXBDTEhJZUVWaExueVk1VnpnOXpRTjZkdndLa1NzTjZYU2lJY2x5Qk1ydApVUlV2OGNhVTkza3Z0cVc4ejYvSnI5U3dNUkc1N2t3MlBVOCtjMDNHM3djakk3U1JVb053VFk3M3k3WUZ3R1RQYnRob2o5YUVlZ0FzCllFbFVhL2VJa0FDS1JmU1pHREk1aUhBbGh6NU5NVmdLbUl5dzl4U1RieW1PTUREeGUwMkQwc2dSRjhKRjc4aVU2SEw3V1NwVTMwaDYKRnZRYW9HcTU0OExvM1RTR1JrOW5VRFI2czRFQnJKc3JTbFhRVVRlMzNGNUR4OS9GTGl2b1JCVkRWOWZRS1ZmUUlaMThoeG82V2FTbwpnazYyV2xCbkRaMXlCUjIvV3ZDV0dqcmxDanFCMVhkRERaMXlCWjJnV3ZDR0dqcmxDanFGYWtGZE5YVEtGWFNvV3ZBT05YVEs3OUcxCjFUZlgwRjBJcnFDQ2p2VXNicXloVTY2Z1EvYVllZzJkSUNGWm9jTHMxVTVLV2R2eU9mRHlsVUNpWkJjTlE1S005QmJVRTdkZDJ1cWwKU0pHUGZIVXliRUZzL1VvRUI3UkdlajhLd3QxZTM5THh6dmdLNG9TTnErbVVjQW5ZVlZncnl1N3hEaTNGWVBQZmVVY3RpQ0k4NDFNQwpwcHlIcFcxK0tOYW5Wam1uZVg2aXlOV2x2R2dudWwvL2tHUXFIMVVpVjBwRGtpcVpnM1BSVlRTblNkY1VSYWtnWEc2UHZnS3FrNjVVCkVDcC9URElaUkgvWVdDNW9qRzRHdXpsZTFmT2FsYWRtMEZqc0pzeUUxQnNZUkp3TTF2eldpREZWN0NaM2JDUDBrZz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJMUlyZDVQMVQ1UU1IbnJZc0tpYURDRnhUTlRla0tLcG1FRlFLYXdNbVRNSENMMDlzSnNSZXJmSlJtODRhazdxY1hpU1ZjbTd2SkNDZgpRcW1yeEJUVnZ0VTFWaDJxKy9hQVdGSm4yYXc5ZGhrNlV3c2NycUk3VVpnRS9MWXRtVFI3eFlsVlNkYnNrcTBDNDFsSzRqb3dWYk5MCmN4M2ZXUzBIWGtjZDMwU3Qvc1VzQ0ZySmw2YkpGOEVvbTlLWE9mRDJ4NlZaYmxBWnFSSk4rZlZUellIWG5FVXdLd2tqbUpMcnA3V08KTDNwUXE0bFJZZ1poZGpvRWRyY0swUU4zOGlGWG1hSUhtRHJIYTZlWU1NQjZJOFZVeTBTMVQ1TFRhRmRSVEJqNEpYTGRubGVZNkZRVwpKZFpMVkhKcHMyVXZZcjZYYmhZcjZrM3B1S1Z5dlp3SWhBeUFsVW00STB1QUdCRURIUDR6VXBUdXNnWm5qL1g0Vkp5OVJWbXpzeWNIClFKeWplQVVJdGF0UndEcXp0MnBvSzVXN2FvV0dtUHIrd3BnMDBtSUJTOXpVZ3d3R3haQTByRXFUY2VJdTJGNnBSczZnVXVhczRjZ1QKVFVqNXloUERoWHVsWUVmR2p4ZXAvSTdDU1FQSmVTY2pjcHo4VzlFWDNwRndsU2hMU2FWQTdrTHJ5RmRFblNSMzh5dnNzWXBXaWVmawpYZFllKzYzb0MrL0lsOW1KTTRpdXB0TlNKZEpnRUxrUzhpeWdNeUlqR0pLZ0hoa01pdEFUL2xBWWtsQ1kxWGN4QlRvRnRRNUpPVHRkCnZTaE9hVWppdXp0OG92Z3ZWWkowajRqTUU0ckkzSmlsQml4aGk0YUlESDNHcDFLZVk0bjdiTGRFWkhqKy90UHRFUmtBd0tHUTNhR2oKRE8yYWlNeEZ0ZUR0RVJsWWhpYUt5TWhWcEtyVjV3VjFSV1FrNC94UEdzcHp0Qlhud0JJOUlIRHFuS3d0ZlErMjZzQ0V4bktWTTVibAo4OGExR011QmROdHQxc0FNeWpXSnUrcDlNaG5ndXNRYjl2c0VkY0RVNGc2Vm5GNHRaV2hYSnJEejl4ZFlRQ1lmWGRKUlBuYVJ1aUJaCkxhaFdWNmM3YWZZeVF4WFYxV25NMTFPc3ErT1ZqaXBVQ3FzSFFhdUtsMVR4cEpkbld5cW02cjFlM2tVS3Y5TzQwVEUxNzNLSlNmZXAKaDROWTdwRlRwMXdQcC8vK3NXdnE0YVN5b0YvLzdsMFBkME9kaFk1Nk9LVU0xZnZWdzhHbzlZMFNxS0VlVHVKR1VOa2lydXZyNFFUWgpVTXh2N1BldWh4UGZPMHBWeE4yN0hrNzFsb0M3MU1NSlRxdzBwRnBlVnc4bjlzWGtqblZnSmR2dGxmVndnN3RiVGlRQUpjeUpsTE10CnRlUkVkcmFhY2lMVlpQKzRDdHhxQnVSUmdzVHQxZWdJamtkdDlUWEMwVkpISWd1RnNzY1FuRHRVY2wxa01pamt3S3RyTkZoY0p4OFEKdTh4MzV2V3lrY2w0dHU5ZEZ4blA5cjNLUW9pRVVEYmEwKzNjSW9aYzhSRXZxbkNyR0FKZ2l0ZktTT2t4V1RIczdiU0tvWUkxRHVtdAp6MStVWkxUNzNBYU00T2dUSDVsNlpBRG5Mb1dRQmIrMlhVd1ZqdnlWd0RLM2FjbWxXVjllQ2F4Nkc1b3dLaTI2cmRIcHVZeGh3ZUl6CjVZdWRWQjFxdGlJVk4xMmJJTUticzl6RndsZFZwSTVOUXcxRnBCb3JVc2VtaVphUWdVcXAzMTBxVWovMzk2bEloWER1VVpFSzY4VnUKcjBpRlVPNVJrUXJoYUxzR1d1UVNTK1gxSVFHUnZ6UlZkNUtSMDB1dnZsQU11emVMb2FnVVRscVAzYnNVRHVYeksyYjAzS01VVG5KZAo3bDRLZDMzY1VrZ3haZDlkaDE5NVF5a2MvdzRpVkF6M2o1VENTVVFWL29GU09PbjRtRWIvcktka0dQSlZBZi8rWktYQ3A2VnNycXFXCkcrR0Y5bGplcCtJV2FVMzBncUJDbWlLS0dnTElFSmo4elhZNmJaaUxTNGIxSGk3d3F0RjdHbzl3bEc3bkJhcGNhc3Zqc0tnWE40dnIKNmo1bHI4TVJidzVNZEZSaWUrRGtGM2FOODBqaG85Y0F0YmhNdlN4TDY4NTRXRERQemtVeVpza015RmJxdFpqeG4reEE4NU90ZEtTSAoyb1lYK3NWREpsc090NTd5T2Q4MG44LzVxN0FKd2R1TzJZNnNhK0dRNllpVHNCWkxxdW9NZWtsMGpkS0hmTjFadEJGLzViT1hzTmd0Ck1YMnA4NFBQUEtTaHBjdWFORzdsS3V5Q3ZhNVNzZHZNTDRzVUkxczVwUW83Njh0UGZTeUhkS1NBdE9TTjhaQ0thN0hpN2lNdkNpY3UKZGd0Mmx6VzJNNkdvQk16a1VDcDJ3MzBpcE1KK2ZJay91UXE3c05tOEQ1OC81WXJkUHBTcXp2NlVLK3kyclpZc1VsdHR2cHpKSVowcgo5K05yZE9XUkZwOC9TckxrdFd3Q2lhRWMwb2F3d2c2dEtoQllldGJvRTgzbmNZM3ZKYVRlbzZJS2dqZURuelZORUlQT1YrbzlldXVzCmhTVU0wV2ZHUzBxUjU3VjRRMVdLSFd0SXVSVmFzTzROTlJmQkdkR3JiWHVmMGg3MURGVngxRVMrajlWZXc1QjQ1MklLZzFKTFRsWEwKODZDODEzdDJrcE5xT3lKeHA0cUc2SkpTSnpsZFViaVBndVlVU1pWcVNIUW5wSTY4UHJVbWNvcDVmZHI1U2FXSm5PejhwUHErcVRVYgowVG8vOVY0RG1vbXUxbWRFZEpmYURmM2p0TXRMYVM3ZmlFZzIzVlZyQXpybFNPODExWFRYeFdIMFZ0TkorUUZNTDg3N1ZkTnB2Qi9tCnhtbzZxWmlnV0Y1dXI2YVRxcVc3dHZKUnZwcE9LaFl2bldsL1N6V2RnQ3kwekVyZVAzWlROWjBVS0pVYlFxNm9wcnR5UjlaWlRTZDEKVHNQdWxYZXJwcE9xcGVQNysvZXBwcE9xcGRPWTI2T2ptazRxMXM1MFlMOWZOWjNVNnFKSTcxMnI2YVNNRzM3dTZIMnE2YVJxNldSdQptNytobXU1eVNFdXp2S1YwYlRXZGxIRnFzTjY3bWs1cS9TU3lvVzZzcGhPRFV1MHBmRlUxblp4dGVkOXFPdTBVdTZXYVRnUktmQ1orCnAycTZxeWltdTVwT3NjYnFidFYwMHJYVjk2Nm1rd0lBc055NW1rN3F0RVNVQTMrSGFqb3A5U0QwWHU5UlRhZHlNbktuYWpyMS9lVWUKMVhSU3hPQ3M4WHRWMDZsVmN0Mm5tazZxbGs2Mkg5L3REcUNYY3dBRi9jVjBYZDBrMzhYcnNrbWx1RGVIeHNLbnZZcXdDNGdmM01yMQpzcm0rWDkzRmtFN3dsT2ZlL2Vya3JRdHRkRHE1N2Jyb3hGRkprQWtKYXpKVkRRdU5MQ0FvVUpDcGVwWWJsR2hJV2xXQmh1NXl3b09wCnE0WUVLUVlHcGF2dHN0S1FwQk1wWkRXTUFwMFUyaTdMcUV5NGl3azlvalQrZEJSNVJBRkxiS2ZTMkZ3NU1zZDJ5MUpxZEhkem16dmUKUFZjYVRmSnIydHpKZHBlcmFxcFYwdGptVHE2U1Mxc2huYVlFQ2VYOFpLN1IzVzFyVmVydHRIU1pVWXhTYVdwenB4cFJoSVM1dWMwZApiY01vTjdxN3VjMGRWZnVtMHVoTzIrSFJybnFIZTY0QzZUYXV2SWphNnl5cWQwdFIybFU1ay92cVdoNHd0VWVuVnY2VVBlV0JEZXBVCmN3L1YrQk9XMFVIbldURUNyNm1RVGt0R3MwRzl3bEEraVVOemZTSEFvcEIycUNPSkRGSkhOdlFuNUdSdEhiWUFack5kWEU4RUwwMlYKbmJQVTNWQnk1ejJsMTc4ckM3c0UyVkNBcVZUeXdUVm5Rd0ZRcXZsam1yT2hBREJ0R2QzS2ljMUk5OTJsOHZIMm94RFlVVkRoT25CNgo5VFhDMGRUYlZRb0tMN1ByN1I0U2lLQmNWTEpMVmdxcjE3SWpZSm9LYStWNlFJZ0xhOTgybDRXMWI1djczUW9JZ2QybGtUSGlNVEJhCkxjcU12M2ZKa3JJbFJVclZmcTlLT2RTdXl5TmRXSWwzbVVHdDZJbkw1VkRQajZ1N1ZLYXdOeC9ydHlRdVFkWE85K3BnQ0I2OHloOFIKYTViOXRxNUcxWEtuYjdEeDJzM21CQVZGS2F0VEI1dzczQkpBd2JtMVd6VUZoUkZDcVJzTzllV3F0alVVTXVnNjRYVzZKY1N3bzZHUQpRVk1FL3VZT2QweDlwVnlQdXl2RVVDSzU0dHErMWZvNjNDbFZQdDRnaGd5ajBSM3U3dElwVDdXZVNGdW52RnZyaWRoT2ViZUxvVUtICk8yRmRrcGI2a0dzNjNDbjFlNFU5N3ZSM3VOTjZxem1zZnJxOXNQWnp6NWs1Y3Q2cjVzSmFBRXpkekRGb01YU28zblRYRmRhS0t4OUQKdDhhUFlIMWhYYkljV3Q4OVZ3ak9GWHJ6NG80SUNPY3U5WngxVEpzdnBncEh2aFpXVk1Sa1VMdG1BclhMMDFQZkxsWEV4RDhWaFFyQwpjeUdHY1lmS1FtaUlhekY5M3pTV01Xa3BZckkvRHNTZUtHOFgwMUxHSkp5a1N1eVVBOFd1aTJ3WlU5eWhxVUpkMFcxbnBUTHUwQ0tWCldvcVk3SThic2ZGOXJWL1oxVlhFSkpkQkJIc25LdXkwK2d6RExsM0RlOE90L0NMRFVPS3l4RzZQNmdGeGp4clh2RS8rVmpIb3YranQKU0tlcjNTTWlwYnc5MXJ2ZjFWUTlkUHAycHhyWG51elZWUHB0bU1sUlY3dEhsVTU1L2l0clhIbnl5YVpoYUtoNlZxOXhCVVBTWFBXcwpWT05LUjREZ1F0UWkwdmdZMHc5V3ZKVWZXNFVWbnMvNW45NEw1dm5UbThGYVNMdmZXby9ia1RzTVBwVmVVWFVmMmYwa1o0UTlaU3BRCkd3OEs3ZkppeC9RblFSSGVjN3JKUnlxb2h6TllqK1pPNzVVZnFoTDJZWXZuUDNveTlYQk8rU0s4dzNrVXg0VTZXVlNHaDdua2F2L0MKWmt1azZmeVNLOEw3bEVVSzVtSWlkd0hadVdJbGM3OHRpOVJlbWZnV2NuM1luQnhTdHBLTEkvQnJpT0FoRlphbUhlMFJHOWRITUNDcQpjblE2MGg5ckthUUdLeVN3dU9lY29BeHZMSzc5NDVPM21ueVZRUm8yVzRQUGhSRVhneFZYeEEwVmtKWXNZWG1rcFlhNUw0VVU5WDJMCmxnV2xsV0trVGFVK2d0V09QTkppc1UwS01yc0FXZ3Q4N21FLzBVV1laOWVqWDdqNk11OEY4cGpzZS96NlNtemtpbWMxUUhUSHQ2Y2kKdDAyQ09mZUNZcU9UUGF5aG96M0N6VE92RUNkbU56cU5hWk9BcUNFbk9nMFNkREZUVDV6VXNEY0QySS9pd2liVkNJbDhTZEpsYXBYcwprQ0FueXc4cXI2VzBTYjJ3Nlhpdnppd29vS3ZTbVVWckpLbWduRm9sdTNRWG5Wa0FnamM5S1doS1ZYZWlteWR2cUVwVHlkQ2txR1RRCnhrK2lReSs5ODJPajFyRHVUbmVYUlpraFhXUnBpZVZGTTlGMVpXa1pyRXFEa284VDZ4c1MwSmJ5ZVZyMGVDNXlZMFhxcXZpWmNna1AKcjR1WFBWT3VjeVVBN0lxR3E2OVZZckNENHIwdWIreDVqZHB1T05SUWphUVlYdFo2eWpNbzNuSVRMVmVUZUhGbDNGWEZidEpIMXJydQp0UjRVcjR3c0MyL1JoRldBdDE1Q0szVlhuR3k5bUpyWGNubFhuSUlESkIwZkV5YU5TQnl4amtsZC9RN2tOUXg1Tng5NVRJbzF6TFduCjNsVEJuWndjb3hNcjlmWjFncEdKNC96cUlUdlVqMDgycWhMY1h5UVFyS0lIL2ZhSVRPOG4rMk5YL25CUVh5SFpSVCtMRzlxeUtWY3kKNmFxeGl1bTY1NEEzSkZIOXk2eWtGRHRXdGNZRlErS2w2dE9uMVR5cDFWa0t1TEpvS09YazMzT2xVQXFvMXRKWVpmMjRrL2RaU2IxUQpSek16aVBvYVMzYVowUUZNcll1T1hWeGRxd0JNdEt2Y1JqSFZXaDd0a3hTZVhONUlNZFYrT3Jvb1ZndCt5Z0M3S0JlV3NnNXBpbDFaCkJhaTFCbER6UFNSeUJXS2FhZ0FWc3RNMVZBRnFyUUc4akNmcnFRTFVXZ1BJditGUWZ4V2cxaHBBRkxXK3VncFF3Q29LSHFZNEQxWmYKRmFEV0drQklzZXVyQURsNkt1c05ZWTJWM2lwQXJUV0FySTk4VlJXZ3pKQXVhZ0Q1NTVYVWVDNW5kWHRUUHUwZDJXNXB5c2VieXovWQpsTzhpcXZDUE5PVlQ2OGgybjZaOFZNMklzb0Z5ZTFNK2cxWENLcng3VTc3TC9zai9SRk0rK2Y3STkyektwNmwvNVMxTitmaFJCVGlvCnNPeWdhQktwbFFiTGQvVzcvVzZvcDN2Y0RhV3hyNSttdTZGdTd1dkhtOW9kN29hUzYrdW5MMC9wMnI1K3lsMzlycm9iU3FLdm4zSlUKU05vVDE5L1hUNXI1Rk8rR3VxS3Zuem9uMzZPdm4zSm1DQnU1dXJHdm4xb2wxNTBDdW9wZC9ReFdYUUZkMmI1K3lsTVR4UzZ1N3VzbgpHTWhGVjc4ck9vQkk5dlZUbnBCVWh1bzFmZjBreXhHVmJqWFhUaGpObGJLU2QwRmYwZGRQK2VZdjlrejh4cjUraWh0ZEh1MWlkK2pyCnB4d1cxblVEbFVKZlAyVlhWeklMK29xK2ZsSmxrcHpvM2RhUDd3NDE3N3I2K2lsRGdYSCtlL1QxVXo1UU1XaUdjMHZodTdnaTlkcSsKZmhLbUpxK3JINzg3QTNaRFh6K1JHR0xDcm42Q083dDBsNmRnYkY4LzFiclh1L1QxVSs3cXgzTHlqWDM5bEJPdWVSV3BOL1gxNCtxMwpwSGhSZE0vVjFYMzlsQW1JTE5nNzlQVlRrTFhqS25DbmZud3VaU2lhKy9HcHRKUFQzSS92cHI1K0xCUko4ZEZielhIUjEwK2g3a0UxCjIzYXV0Nitmc2lVUGJ6eTRSMTgvdVQyOGMzbVNlRjM5bGdaem5qbEpWQk5EdGI1K3l1Zk53aXlDNi92NkNha3Q5Zz09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJRnEvdHg2Y3ZTVU8rSDk4ZHhJZnQ2bmQ3UHo0dFJVeHF0emRjNW1yb2E4VW5ya2k5cmErZklMQjkwZFdQcWhpNnZhOGZXeXFsMUZmMAo1cjUreW1hT0RJL3A3dXVuM05YdjVsdWI2TDUrTjhiNk5QYjEwMUQzZW9lK2ZzcGQvWFQzNDd1cUNsZWtMUy83K2wxZkRNL3I2c2ZECmNsTmZ2OHRRTXIrcm45d3RaM3I3K2ltbmQ0bDJzYXY3K2lrbk9vbGlTbGYzOVpOWUYxNVhQK1Y3NGJUMzlicytiaW1rbVA2YUp4bS8KOG9hK2ZwemlrdXJxZDNYMm9LaXZueUpIOERxQTNOYlhUOWt3cEx6WDIvdjZLUmZFMGp2eXpYMzloSk1VZC9XN3NNYzAzMlFsN09zbgpid1JSTm96S1RWWWErL3Bwc21GdTd1dkhYOG5MQXh5RjZsb1orWlR1NjZlOE9TaFdjZDZ0SUpiYTkvMFMyME5meVVaN2FVdG5mSWp2CmxWcFNOeXFLOWtyd3JYeG9Wem54WGxTMktPQW1oc2U0MDV2VTQ0NWZCMC9GcG1oVURzRU82ZHR5aE1IOEwvTXdTODluZ1NkYU84TGEKTitLNE5JSnQ1Y25vL25pMllQN3VLa0s5Qk91cGpKWjZxdUxESEJ1amYvcXhDd1lPeXljeXRmNktOZG91aC9mUGFjL3RjMWg1OFp3MQo3OCs1c1BGelBBdUFUNk9NTlJSTmxHMzFsMzB6dEYvMVBneldTTWdYbkViclpOZFg5UjJNb1ZvcE9NbzFWKzMwN0swZWZsKzI1cytoCmZjY3gvN2E4WjUzQndxK3AxYXl1NHV0a2R6dFBPemI3WVdSdlBXUTI0V2ZqKzNQYWJnazRTbUhyOTBlbDRqd3Z6Ui9CN2VjOFRzcysKcXUxTXRWdHZIYVBQUGNnWWljVys0MDRHN0JtTXpGVnpHUGs5ZmNKS1lWdnpjQmpGSElkajlMMXlOQS9DazJObzh2SEtWbHEyM0k5Kwo3N3N2VUl1Wm1MSzNYLy9oK0xtRnplWmlacXEyK2xLSENPcExFLzNhTUphZE5uYlFvV1piUU1KK2t1Y1JiblZsTTdVbktXSWhZb0RwCm5teHdYUUlXbyt4Y1VVV2pZMnlmdjVvNy9WYktzam40U1JzUlhKek42NWx4Qml0Sm41amlVT1Bac3dzK3czeTErZ2JWSkJxelpLdGwKeFN6ekdmTDNYN2RDazMwbkVoOHd0ZGM4cjJpT2k3ZnlwZ2JVbWhRZFVtRnIvbXl3RnZya3ZJc2FhT2EvU3MxdStEay9NMlg4cCtSVAp4bitjSmNpWWVmVmFmTThFQm9Cc20xUnAzZWwrWnN0aDR3VEE2ZXdac0ZUN1RBZnVYa1ZnS1dOdmtFblVqQWMwcSt6ZkZuSnl0dnIrClBuUVhPOTB5L0FRbS9McjJ3YUpkRCtYV3AwSzlBL0tjTVAvSkFiTVJoaWRLRS90RFBqdnpDWGVnMkRHZ1NHUUQvb3k0VU5VdlVEaVYKSGZqejBZTTBqTmtPZHJHUEEvZ2k3Mk4rU1BySklsR1BBckJsekYzd1dNK2tvMXlwNEI3NzhxODRYZTFqbUQ4VmNhS0J3c0Y5NGE0OApuc2ovalAwNGVQRG81ajBZVy9LUEJpdnpLTy9sSGhHNWZqdk5QS2l3K0twOGZGNUxaY2tRNXRrSlZNWjJoWmRxcGpIN25adDcyV0RGClN3UGZsSDNrNWNFcDdlSVkvTTVQMjBlaFp3eFdHZjNoNVhDTmdIOFNGT3pKd01yQ2JyaXBWeVk3SEZyb0RTOHZCbXNoN0NrSFRMZHEKK0tpWHB1RThoTlBBWUhMWUFaK1dYOUNmTk5ocC93T24xNnBIdXYzMXQxVUFQRzE1MEZQQ0dZN1BHS1F0SDRNRmMxcWlHTEYrc3hZOQpNU2ZnRHF4ajRmdjdJd2Q5TEVjeHcwWDhpQTc1QUloK2l0a2w0QW56eHJWRHhIZ1FjYi81bUhTM0U0ZHdxaDE4emthK1pnNG9kVG5DCjJYOHpJbGFCRk90OUVPekNqd0tXWkhKRURwMGZWY0o1bnEyWXFiOTd1QVVqQ3VWSHlOUHZQb3BFaFg0Rmh4dTVoU2hNWDBMMHAzV2IKb0QrZFB3YTBiVWtVbmVNaC9ZbFloQ0NJRUFWaTJNOUFpSDBmck5mWUVzTjFEYU4rUFR3M2FkZ2paNWZsdGo3Qkc4MG9NZnRGRHhERgora0ZXS2llOHVZemVqWG00MHlSZ21rSXp0L1l0WE5uWDZYZXRVSzBZM3poRndoN201Tm5nZ0kwWGMrQk9Fbk1CNjdreVo4Yno1VWZUCkNOaUlkaENOTm1CTGZJVG9UNFh4RC90ZWdINnY4NWNWaitZbDMvb2lDMnZUTk50c2Zkb04xdUxFbTNtSG0zVVM1YlBSc24vYWhTbFoKRkpvT3drTmdtMEJ2c21ydFVtOHl1eGpVbkNLOUdmOTYyVHFLNzduNlU4NjVQc0JMQ3NMbFhCSHp0UzcxcHJqdHNCMU5IS2kxS0xxaQoxc21lOFFIMVQwK2p1M0pUcTVyckRvNllmMlh5K1g5TXI3YUFKZlozd2pDSDcwanJNYUF0VVNJNGlyZUNQNE5PVk9hTUZ6OHo4TSs0Ckd3YzdSd29xUXVnak13di9DWDdUZ1NxbDdFTjJIVXk5OGFGSUJGUkNNTkpROXN2RWxNcVl4T3JEQjFVSHpIM2R3em9MYkROaUZyVHEKb25TSUoyK2RzTjk1Nk8vYU9PVHBLdUNOU0tlY0g2MnlNNEZXcldGWWFGS0ZDMUhGK2Rvd3R3OGpPM254QW5VZlFORGJvcTBGVHYwegpDNy9ER2ZPc0ZxRXBVU0s5NkJYZ3lUWDM0TSthbjRFTmRTa2NEZENsbkxLbU5CK1lDMUNwWHMyc1JGbDRGeWNNZEhSRjNLQVdOYlIrCjlQL1NjWDdFYU5qY0ZQSnpaaVg2RHQ1YTBNQm0xazBCdkg1dzg4MGNCQ0taZnVNQnFIeDZmRUlBeTFSNzZLTHkrcG9uYUdDMkJSZEoKMUk3d096UDRMbnFtckV4Ym4zamltZHFVMlpWOEtiSUFHcGNBemhRQU1CY0tSTmxXNWx1OWdPZmQ4RVlFdEFiQUVIOG1ZSGtyMkpnOApaVGY4NUdPLzg3UGZnWFh4dk8yaGZYQ2dtQjJ3ZlorM2k5azQyd3YyekI0eEp0WWp3VmhYd0NpYldKcWZ3R0FJbHNROW8ra05BMDZJCnVtNGladVI2UjhOZTVFYnFKb29lc2pQcHZ0M3I5alBmQndGYko3MHVPV2ZWemR4dFVmN3ltWDdiWUFadUVpRDFlWkZZWDE1NlFWZjQKTWhRTFJGNVd0TlZMbkhITzRFWE53cUhiWUdKR3c3c0R4TVVqd2NjaE1PRmRRY0tTd0pudnp3YW93ZzRSd2VjVkVBRVYxMUZFR1BDSgpRQ3dhaUFqd1FaOVBBbEhyY2lEeEhBbTRmdUpDSW95VHp4d1JBaDlyUE1wclp2VjFuUGo0U0duRC8wdVdCT0srMVQ2Tys3dkdyYjlJCkVlR1E2MzFvNHdOME5UOWk3TE9SSTRIQmFnd2VQMndzRWJvS2ZBQXZMR1dvK0NuRlNySUF1RHlsM2s2Wkc5VjRFVWFKNWNZQTVVWEwKTklhSEs2ZkJSRWhRT09LMmFTd2xWNE5iQzBvcWxhYngrcm03amFkZmgzdFdXNHBBYUtNRUFERS9LazhEQUhCWkVDY3pJTkw1L1ZZQQpZbXRVSDRPaWRqcVlFQUJFc2Q0ZkJ3SXIxM3RUL3B1OVQ1Wi9lN3lGeDhpdnNqRG04dnAzTTQraDY4QnY0N0g1NlJZUUFNRGFlRE9QCmRUWTM4bGh2Szhkam1rRk1EdW9NMGhmdzJNVTBsamVTOG5WMTVuanNPaEM5b1FaeDdUTFJIbWtRRTNuZHAyME1jeDRwS1lycFhZM2UKVWwzaStXTUFjN2tZeGVyRzFlaHR6aUpTTWhUVFBvMkRpbXhJalVGUW01RHFuVTIzTVhiZmJGYmZrWW5qSndmQ2FPOHMzL2dnSnBOcgo5d0IyUjU3TTkycVVVQm5EVWtZK3dSaDQybEtKRXBQVjhWWnRPZG1jTk94RUN2dlFaSDlXSG9PNnRweWNqZncvcDJhVDRFK2JtWWwwCmxpa2ZFaDdMeFhoaGI4ZUhLd2hXM3pPY2RZMmUvYTVtOU5TN0w1UVJDSDdEUmNxNjBPTUw4MXd6bEU4eFAyV2l5QzVsWXpnRG5qYzUKdHZ4OVVoRVErMk12Uk5XOVFxOTc2SUcraXBlSlZuNGU0WjlzQUs1c1p6ODVLTWR1Zmx4QmE3eE0rYnZ3NE4rRHZHNzZ6N3pQUjduYgpURTR2OUxCWmR6eVE3dXh5ak5zYmRMREJSQ2MvZUJrN3NjRzlxcHYvb09abXc0WlZyeUNpNkJsRTJCQk1sY1AzRmJBa0Zsa0czd3ZPCkVZWU9VWlFlWGR4My9PaG9LZS9oUFJCRVIwc1ZId3dPdVFEdFB0MlVyLzExL0FXOFUycmk2TTlBdW0wRWY3NW1PTmhET216eFNpSnEKdTRDL01NOGh0d0NlMDBBdm9SWUZWdnZMQWNyTDY0c2Z4alk4QU1IZUF2NXNJN0F1S2lUaWYvMElzSkZKdHp0bFRwcmhVemRBNEFORwpTNi9HaFc1SERKWVJvSEc0N3kzNHgwbGJmTEd4dHcxV01sa00vdkxDNjFUd3ZkUnQ4SS9mbVRONDlyUW9Cc2E0eVV0QmxJSkg1U21wClFHUnV1a1FRblUvUlJpeGFJalAyZWF0UW1UMGFhYSs2MThVWlZtbnhBMzdPOVJEc2xYU0VxRGNPc2xNZkF5eW5HTDFna3hjVUV2SFEKNGZWSjIwOEhlU2RkREovVUtrN3c2UU9uNDFHVEFaR0tWUWl3VnBOeGdQazBDMUlSZUErOXRLc21ndWhGUitUZ3p5NFRsRnQ5WU15bgpBY2R0RThLZXJxWG8wYXhtQWQ2RGdURXdwT09TOWIyVm5jdnFMNHk4dGtBdUdvZ201Z1BuZDM0WkpsOXk2Nmc1S2hWcG9TYkUvVU5sCmJIT2htbFBYeHlLZG9vdzd5Q3luQVlhWDhJd0RmQnJqektjWkZ3S2Uwa0drMDIvd1lqU2hVNGQwT1ZPSlNNZHJxcE9qdWpWR0JVTnQKdzJNRWV5cTVRMGoydjhLMExIWXhNM0pTbGVPRCtxT0RMTVYweEFmMVJ3ZWw3dXRUaXcvcWp3NUNpdW1ORCtxUERsS2NyQzgreUk4TwpadjhyWllqaUVmd0IvZU52bnRmenc4dmhaL0d6ZWZBWUVnWi90b0xqN2Mxc1N4N204OWI4ZjUwSzIrbjViNzQ1UGNRZi9ObTNmS1VTCkRSWG0wKzFzL29DU21VS2pDS3MydkRTMzB2ek5QOUlXaEJoUnNEeFgrSTZWVm1WejgzRmMrTVo2S1o1WVVGYktyclUzZXBhL1piQ2gKdXFjK3RLdCtHRDBFK1daMGxJOGUrR2VQMnVVcElra2VyQ0t0NURJWDVvZmN1ZWl1MTk1RnB3UW9HQk1idFVwZ2V5aSs1K2JOalArNApTUHJMMlg2MTBDYzdieG4vQ2RzeUFVRjRuaW5JSHVDZGVrc2NrZ05ENW1Rek9wUFBRYVBYYisvQXcvSUNtSXVsRVBVYlBjNU1Cbjc3ClpIUTNUTTl3ZnMvd1Fkcm96UVptMEdvb0cxMTdNekRMeHZzb1gxWFlDRGN0Y3R4V1J3Nkh6SEsvYnBHYU5WRG54N2huc1VpaFl3TmEKWDBMeFF5Y1pqUGo1MFo4d3BkRkJmL3FkSStQQVNWc0Q5ajFzSVZOMjAzL0dIVjdLa0tHQ3p2Q0dHQnJFZHp0K1lpUzVnbkduajN3OQpydU1va3p2SU5GaGxqeks1QnplYkNkUXg4SUNQK3g4d0UxQmFIbTBvL0hObWdzR3F2SzNmeDB5Z1F0dWFJVjVwSmdCRGh6VVUvamt6CkFSbzZqS0h3ejVrSllDNnNvZkRQbVFrOGVabitjMmFDd2NvWkNtSXpRVGtqaE01Q3JNWGxOZ2RhL2J1K3lETjBwWmEvd0pYcURJcEEKS2I1M2pjN252b1BXbStmNEsxU3BaYUJMMHkyajgyZWRNbm8zalUrb1MyTndYN0NJM1N0cXdSNTdsS29EUXBOMUlJSGpEalhmZHZSTAo0NzJYU2Z3SU9yakVEelpYdzA1NWYwQmJ1bWx0Q1U5WWVOcVMzc3J0aEQxai9FTExEclZsM3VkQnQwOFRYK2RreGYvVFBma293K1BICkUzZWp0QzJneDRwUFVrWG53Tzk2cm9wV0h6NW9BeXlSQTZkYUtUMzJSWXVBU0sraWJCU2dVdUhJSFBBNFk1VmJtemFrMFBuQ09CdUcKNyt5VjRrN0lHM1ZrakNBRE5FcWQ1dU9sdGlQS1dqRzBTVlJhQkNIRm5uMjBSV0xKK0F0UHlTMEc0THhnbFBMa2FleFNtMEFMQWY1eAo4NnA2MkRSVzdpUVNLSE51OTBXTWVGR2d3WjcvaTFxcVVtbHB4VUZJZERqSXBlVlI1NHRlL3ZuaU5Gb1ZuUzhhalNjSEd6ODd2bDZjCkx3WmRKVit3bkdXTzJ4NjNUT3Ntd1VHb3Q4NGRCUkdPV0M4Z09BZ05tNDNXbktYQWdKamFMazVTYzM0ZUFKenNsbkIwNEVzbk5OQmkKRHpnZG1leituMVM3aUl3RHlHZ3B4T2ZNZDUwOTgxM3Y0UDk1MmJpNVJBdkVjZ0p6bnc2dENNT09Xa04rU0lYQkNkSG5udlQxK3E3TQp1MnZNSEVFaU81bytmVE5ZeFllUTZGYjA2NDhnblZLbmJ6QWtwUG44RGI4NVZMZUs3aGdpWkFJOElxQlRZWm9JUVQ5SEJEaWFGZThJCkV0MmtKMGNDSm9TYWpxODJEQkZjb2lOSTc0MUgwWThuN25oZWU5aVZ4d2ZwK090SncxRTBuV0lvZFJoTkZ4WlRWRVRueDFLc3BIQ2EKVFpkRUFnQmc5VFZ5NHdVSTFOUk4yeGlvMUp4TEVLZ2gxUzNUUUFuOGpFanhqclIxVEtNZDkrdEtETGlVU2svczVMcUZwNkZMN1JZQgpvQ21tbFJMUUEvZXFUZVB5YUo5ZkpJTjdkbmxNY2hvYVNRbFRLSEVFNEdncWxYTnV0cFdId1FvVEh2YThONEhiNzZUZkpIOXh0MFRUCkQ1clB4MFA3alR3R0RCVEhiVHhXQy9vNEFMSThwZ2hpa01GdTVUSDcwbkViajJFYnB3eVBhUVpSYzN0VUdZUVBBQT09DQoJXV0+DQoJPCFbQ0RBVEFbDQoJVFVMSVk0T0k3NWJWQVA3OG8xOEtBT0F4clNCS05aTzZ1RW9Eb05OWW9jR25XZmRKajJIZ2t5WWxIQU82bEZ4MU5ZQ0JxU3J4U21PQQpTY3k3K0cyckFhMWFaVktpL1VWcEdtVXZxVTgyTHNZUXJ1SFFHcjlCTnNycEpxRXloa1BLai9OMjVITHc1R3NuZVNBbUErdHRlOEJrCjRYWXpPN0xpS0JUR3NNUGxtVW8wQmxyMnhhT1lXaUxlbXpoaTZuMzAzWlprQmhQY0pVVmNkZ3lzdGtRSm55SGNnWXhFcnY4WVFoLzEKR3FmQlF0bzk3QmJPNDFJdC8vVVVNOU1oZzFDR2lTUlJJZjZuUDJHZU9sVTZZYkJLRlUvY3UzUUNZcmtzbnRCZE9zR0dRNldQSmRHNgphRHFZRkI5TDhoN3M4Z3YyZ1NpbUR3T296ekNxd1B1MjdXQ1BEWjQ5L0FlTElGdVRBTDFsNENWQnZVS2x6RVAxQURrWm5RTnNrYVRDClB4c3V3ZEVwa0IxSTJ3YnRlZ01tanRQZWhxZU96c2R6a0M4aEt6WDhkQkZGdWdMSjFxREJUaHR0QkRiQWl6S1dod2Y2Z05ucERWTFcKZU12TFA3aExaeEs2ay9BdkRtRllMNTV3bHNrazVTWGREV0tqOXNpZE5ZUk9yNVo1NmFzZlhSaXMyYmV6NWFmWW43M0NrNk1XenZFdgo4WFVlWk9pWVJHOFFZRU9SUVg3QlJEckNzc3E3bDY2YWFPU2hYbm4zTTJ6L2pxR0VoaS9vY3I3alRIVHBIWjBTd05PRTl3RDdLVWlCCktDYit3dURQUGcxeE9FVUwzMmVQOGZzWSt3bm5yejY4VTV5dFNlZ0grTFVVaFpXRmlUTCtocGk1OU1PeVZTcHV1Um9WQTMzQkNWZXYKd3E5UytmSnhTQU0yNXdzazZoZjRwL2NPb3c5Zk9QdUo0TDlYWHdUaGQwRnVORUQybWZFMHlGR25seSs0bzA2U0xOWTdVU2E0K1JmQwo1cE40R0hLb2o0MVQ5S2txeVA4ZjYvc2ZHK3ZiL2xmS2tBQ1RxZUQ0c0xpWjhjOGNEVllyK09adGZqcnY0QXVoWVc2KytOblV4ditaCkh3ejRBL1VmQnY2RC8wWmlEemdSZlNCQ0lmQkhDSDVibXhnYzZOMEgzUGxRQTd2TDBKODluQW8vMDlQUGRqTSsvT2NoRHIvcTFtdnQKU3VFaC9rQzlPd1R2Smg0Y1lEVFlFTHdOSGpuaFFlY1FqSEJvd0I2eTRIL2RmeHZPNEQvczRjV0FQV0QwQU9CLzNiRUJvMGNFM3ZvUAorT01KZlBnRlgvMzdBY2NlNmc4Zlg5akRESXk4MnpRRVlnOWVISC80b3o1Z0QydjBJZW9MRVRFd2t3RDRnTWRDNEl1SFFBVCtPelVFCjRQK3REYmd2R01FSUhQNkJVKzlqR0FFL0FoaFRBNDZBcnRIL0U3NVFNQWJlb2wveDRvR0hBUG9Yd0lxZ0R3QW5BRUE5aVZHL0lCN28KZ1UwTjM0WTJuSjh2QWdrS1VhQVpnYUdqMmMwTTRRZUg4Nkg3emxBQ3ZBZkhoZm5Da1ZnNEdrQWZNSUlnd0ljWWhvZURERmxFTk9LSQpnZEhFaU5HMGlJaHBFVUcwaUZDMGlQQnBFWUVFaUhDMGlOR2t3R2hTNEdKU0VJZ1VCRU1LZ2lNRlF3Q1dGQmhOaWhnOTNiWTBIOUg4CkFjakFYLzlMYWxtSDdHU3BqM0M2MUNlRkNZTVhxQ2xiaDRxVEJvL3BhVk9mRkNZT1FESlRCeDhWSm04ZHlvbE85bkFZVXgrQnZEeGsKejZmdFEzTjhQTTBQUC85Nzduend2NTBPUDVzRkpUMUFvbWJieVh5WXJjU0dMNVBqL1BDditXeFluZjluU0wxMDVBa1pEdDdkYkRjUApnWENBNWk4dHNzYnlFZUE0aW84SW5HWWtQQVlKRytYb2lzY1FZZkVZeFVwNGpNOUw0QytjL2czOFFPQVVMeEVFeFV0RVFFUlNJZ2hKCkN2NmxlQWw4WUhnSlBvbFJ2NEJvNmNIOXR3c1d3V2daZ3RFeWVGUk1FRXJONExTZXdRV0tCa2VhQnYwR0VZVFdNd1N0WndpeG5pR1EKbmlFWVBVTndlb1lJMEVUZ0VRVC9KOFFMVFpuK2lMSHlwVGh0SkdGbzRqd1JrNW82RWl3MGVlcVR3dlFwRVVNRVlFUk1qZ1QvdzRRcwpFS0I1S2tEUVBCWEFJSEVESEhFREdDSnVBS040S29EeGVTb0F3YUxmd0hkeEJBZHhWU0JBY1ZVZ0tDSnJJQVRKQ3Y2bHVBcDhZTGdxClFKRVIvb0loYVNEdzN5OW1BVWJ2QkJpOVE4UkVKQ0VvdlVQUWVvY1E2QjBDNlIzNEc0WWt0T1lKMEpvbklOWThBYVI1QW96bUNYQ2EKSnhDa3ljQWpDZkZQQ0JxYU5QMFJad1ZOY2VKSTBJaVlVTkNrSjQ4RUxFQXdvcVpFQUVyVUVBa1lVWk1qd3Y5dFVhdmxLRnNXV0xiSQo0dlFDLzlyNk9sN01XNGZ4enhwWXRvdmorRi96aC9GbXN6Mk5UL01kZVBLd09NeVBwKzFoL25CY2J2OE52d0UvWVY0SE52SUxhZmcvCndrbmVyZz09DQoJXV0+DQo8L2k6cGdmPg0KPC9zdmc+DQo=); + -webkit-background-size: cover; + -moz-background-size: cover; + background-size: cover; + position: relative; + display: inline-block; + vertical-align: top; + overflow: hidden; + vertical-align: middle; + width: 1.3rem; + height: 1.3rem; +} +#download-btn { + display: none; +} +/* Content */ +#content { + width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 20px; +} +/* Code */ +#content section.code { + display: none; + background: #FFF; + border: 1px solid #E0E0E0; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 15px; + font-size: 12px; + -moz-border-radius: 1px; + -webkit-border-radius: 1px; + border-radius: 1px; + font-weight: 400; +} +article.component { + padding: 0 0 10px; +} +#content section.code h3 { + margin: 0; + font-size: 12px; + color: #000; + font-weight: 400; +} +#content header h2 { + font-weight: 300; + margin: 10px 0 25px; + font-size: 20px; + position: relative; + display: inline-block; + padding-right: 10px; +} +body.light #content header h2 { + background: #F4F4F4; +} +body.dark #content header h2 { + background: #4A4D4E; +} +#content header{ + position: relative; +} +#content header:before { + content: ''; + width: 100%; + display: block; + position: absolute; + left: 0; + top: 23px; +} +body.light #content header:before { + border-bottom: 1px solid #E0E0E0; +} +body.dark #content header:before { + border-bottom: 1px solid #58595A; +} +#content pre { + padding: 0; + margin: 2px 0 10px; +} +.showcode { + margin: 10px 0; +} +.showcode a, section.examples a { + color: #288edf; + text-decoration: none; +} +.showcode a:hover, section.examples a:hover { + text-decoration: underline; +} +section.examples ul { + margin: 0 0 20px; + padding: 0 0 0 20px; +} +section.examples h4 { + margin-bottom: 5px; +} +section.examples li { + color: #58595A; +} +/* Side Nav */ +#sideNav { + background: #4A4D4E; + position: absolute; + width: 100%; + z-index: 1; + height: 100%; + left: 0; +} +#sideNav ul { + list-style: none; + margin: 0; + padding: 0; +} +#sideNav li a { + color: #F0F1F1; + display: block; + height: 46px; + font-size: 16px; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 12px 0 0 20px; + text-decoration: none; +} +#sideNav nav.site, #sideNav .combo { + border-bottom: 1px solid #58595A; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 10px; + display: block; +} +#pageNav li { + border-bottom: 1px solid #58595A; +} + +select.docNav { + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + background: #595B5B; + background-image: none; + box-shadow: 0 0 0 1px #303233; + border: none; + border-top: 2px solid #666767; + color: #FFF; + text-shadow: 0 -1px 0 #000; + overflow: hidden; + font-size: 14px; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 20px; + -webkit-appearance: none; + -moz-appearance: button; +} +@media screen and (min-width: 650px) { + #site.open { + transform: translate3d(0, 0, 0); + -webkit-transform: translate3d(0, 0, 0); + } + #main-header nav { + display: inline-block; + position: absolute; + right: 0; + top: 40px; + } + #main-header ul { + list-style: none; + } + #main-header nav li { + display: inline-block; + margin: 0 18px; + } + #main-header nav li#download-btn { + display: none; + } + #main-header nav li a { + text-decoration: none; + font-size: 20px; + color: #7F7F7F; + } + #main-header nav li.selected a { + color: #373435; + } + #slide-menu-button{ + display: none; + } + #main-header hgroup { + text-align: left; + position: absolute; + display: inline-block; + top: 24px; + } + #main-header hgroup h1 { + font-size: 60px; + } + #main-header hgroup p { + font-size: 15px; + } + #main-header { + color: #373435; + background: #fff; + height: 148px; + } + #content { + padding-left: 240px; + } + /* Side Nav */ + #sideNav { + background: transparent; + width: 220px; + z-index: 20; + left: 10px; + top: 150px; + height: auto; + } + #sideNav nav.site { + display: none; + } + #sideNav .combo { + border-bottom: none; + padding: 36px 0; + } + #sideNav li a { + padding: 12px 0 0 10px; + } + body.light #sideNav li a { + color: #797B7B; + } + body.light #pageNav li { + border-bottom: 1px solid #E0E0E0; + } + select.docNav { + background: #595B5B; + box-shadow: 0 0 0 1px #303233; + border: none; + border-top: 2px solid #666767; + color: #FFF; + text-shadow: 0 -1px 0 #000; + padding: 3px 20px 4px 8px; + -webkit-appearance: none; + } + body.light select.docNav { + box-shadow: 0 0 0 1px #949696; + background: #DDE1E1; + border-top: 1px solid #FFF; + color: #454545; + text-shadow: 0 -1px 0 #FFF; + width: 192px; + } +} +@media screen and (min-width: 880px) { + #content { + padding-left: 300px; + } + #sideNav li a { + display: block; + height: 60px; + padding: 22px 0 0 10px; + text-decoration: none; + } + #content header h2 { + font-size: 28px; + } + #content header:before { + top: 30px; + } + section.code div { + display: inline-block; + width: 48%; + vertical-align: top; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + section.code div:first-child { + padding-right: 5px; + } + section.code div:last-child { + padding-left: 5px; + } + .max-width { + max-width: 1180px; + position: relative; + margin: 0 auto; + } + header#main-header .max-width { + top: -10px; + } + #main-header nav li a { + font-size: 22px; + } + #main-header nav { + display: inline-block; + } + + #main-header nav li { + margin: 0 25px; + } + #main-header nav li:last-child { + margin-right: 0; + } +} +@media screen and (min-width: 940px) { + #main-header nav li#download-btn { + display: inline-block; + } + #main-header nav li a#download-btn{ + position:relative; + top: -15px; + display:inline-block; + box-sizing:border-box; + -moz-box-sizing:border-box; + background-clip:padding-box; + font:inherit; + background:transparent; + -webkit-user-select:none; + -moz-user-select:none; + user-select:none; + text-overflow:ellipsis; + white-space:nowrap; + overflow:hidden; + font-size:16px; + line-height:3rem; + letter-spacing:1px; + color:#454545; + text-shadow:0 1px #fff; + vertical-align:top; + background-color:#e5e9e8; + box-shadow:inset 0 1px #fff; + border:1px solid #a5a8a8; + border-radius:6px; + margin:0; + padding:0 1.25rem; + } + #main-header nav li a#download-btn, #main-header nav li a#download-btn:hover { + border:1px solid #143250; + background-color:#288edf; + box-shadow:inset 0 1px rgba(255,255,255,0.36); + color:#fff; + font-weight:500; + text-shadow:0 -1px rgba(0,0,0,0.36); + } + #main-header nav li a#download-btn:hover { + background-color:#2f9cf3; + } + #main-header nav li a#download-btn:active, #main-header nav li a#download-btn.is-active { + background-color:#0380e8; + box-shadow:inset 0 1px rgba(0,0,0,0.12); + } + #main-header nav li a#download-btn:disabled, #main-header nav li a#download-btn.is-disabled { + opacity:.3; + cursor:default; + pointer-events:none; + } +} + + + diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/css/theme.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/css/theme.css new file mode 100755 index 0000000..7f1ec6c --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/css/theme.css @@ -0,0 +1,28 @@ +pre { + padding: 0; + font-family: 'Monaco', 'Source Code Pro', monospace; + font-size: 1em; +} +.rainbow { + border-spacing: 0; + border-collapse: collapse; +} +.rainbow .line:hover { + background-color: #171b1c; +} +.rainbow .line:hover .line-number { + background-color: #101313; +} +.rainbow .line .line-number { + text-align: right; + background-color: #1b2022; + padding-left: 0.8em; + padding-right: 0.8em; +} +.rainbow .line .line-number:before { + content: attr(data-line-number); +} +.rainbow .line .line-code { + padding-left: 1em; + width: 100%; +} diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.eot b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.eot new file mode 100755 index 0000000..9e9e4de Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.eot differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.svg new file mode 100755 index 0000000..f4a1739 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.ttf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.ttf new file mode 100755 index 0000000..6eb48e7 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.ttf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.woff b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.woff new file mode 100755 index 0000000..2383f47 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcecodepro-regular-webfont.woff differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.eot b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.eot new file mode 100755 index 0000000..bda2005 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.eot differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.svg new file mode 100755 index 0000000..e031390 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.ttf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.ttf new file mode 100755 index 0000000..0959ece Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.ttf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.woff b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.woff new file mode 100755 index 0000000..522d5ab Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-light-webfont.woff differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.eot b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.eot new file mode 100755 index 0000000..2b75abb Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.eot differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.svg new file mode 100755 index 0000000..581a849 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.ttf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.ttf new file mode 100755 index 0000000..e166286 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.ttf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.woff b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.woff new file mode 100755 index 0000000..315c98a Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-regular-webfont.woff differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.eot b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.eot new file mode 100755 index 0000000..ddf5d11 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.eot differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.svg new file mode 100755 index 0000000..317e536 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.ttf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.ttf new file mode 100755 index 0000000..6d97e7b Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.ttf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.woff b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.woff new file mode 100755 index 0000000..d844315 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/sourcesanspro-semibold-webfont.woff differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/stylesheet.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/stylesheet.css new file mode 100755 index 0000000..2d66502 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/fonts/stylesheet.css @@ -0,0 +1,57 @@ + +@font-face { + font-family: 'source-sans-pro'; + src: url('sourcesanspro-light-webfont.eot'); + src: url('sourcesanspro-light-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcesanspro-light-webfont.woff') format('woff'), + url('sourcesanspro-light-webfont.ttf') format('truetype'), + url('sourcesanspro-light-webfont.svg#source_sans_prolight') format('svg'); + font-weight: 300; + font-style: normal; + +} + + + + +@font-face { + font-family: 'source-sans-pro'; + src: url('sourcesanspro-regular-webfont.eot'); + src: url('sourcesanspro-regular-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcesanspro-regular-webfont.woff') format('woff'), + url('sourcesanspro-regular-webfont.ttf') format('truetype'), + url('sourcesanspro-regular-webfont.svg#source_sans_proregular') format('svg'); + font-weight: 400; + font-style: normal; + +} + + + + +@font-face { + font-family: 'source-sans-pro'; + src: url('sourcesanspro-semibold-webfont.eot'); + src: url('sourcesanspro-semibold-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcesanspro-semibold-webfont.woff') format('woff'), + url('sourcesanspro-semibold-webfont.ttf') format('truetype'), + url('sourcesanspro-semibold-webfont.svg#source_sans_prosemibold') format('svg'); + font-weight: 600; + font-style: normal; + +} + + + + +@font-face { + font-family: 'source-code-pro'; + src: url('sourcecodepro-regular-webfont.eot'); + src: url('sourcecodepro-regular-webfont.eot?#iefix') format('embedded-opentype'), + url('sourcecodepro-regular-webfont.woff') format('woff'), + url('sourcecodepro-regular-webfont.ttf') format('truetype'), + url('sourcecodepro-regular-webfont.svg#source_code_proregular') format('svg'); + font-weight: normal; + font-style: normal; + +} \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/index.html b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/index.html new file mode 100755 index 0000000..00cf38a --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/index.html @@ -0,0 +1,3167 @@ + + + + + + Topcoat + + + + + + + +
    + +
    +
    +
    +
    +

    Topcoat

    +

    CSS for clean and fast web apps

    +
    + +
    +
    +
    +
    +
    +

    Button Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar > .topcoat-button-bar__item:first-child {
    +  border-top-left-radius: 4px;
    +  border-bottom-left-radius: 4px;
    +}
    +
    +.topcoat-button-bar > .topcoat-button-bar__item:last-child {
    +  border-top-right-radius: 4px;
    +  border-bottom-right-radius: 4px;
    +}
    +
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
    +  border-right: none;
    +}
    +
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
    +  border-left: none;
    +}
    +
    +.topcoat-button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.topcoat-button-bar__button:focus,
    +.topcoat-button-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button Bar

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar__button--large {
    +  border-radius: inherit;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-button:disabled,
    +.topcoat-button--quiet:disabled,
    +.topcoat-button--large:disabled,
    +.topcoat-button--large--quiet:disabled,
    +.topcoat-button--cta:disabled,
    +.topcoat-button--large--cta:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Button

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button">Button</button>
    <button class="topcoat-button" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  padding: 0 0.563rem;
    +  font-size: 12px;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: top;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border: 1px solid #303233;
    +  border-radius: 4px;
    +}
    +
    +.topcoat-button:hover,
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large:hover,
    +.topcoat-button--large--quiet:hover {
    +  background-color: #646666;
    +}
    +
    +.topcoat-button:active,
    +.topcoat-button--large:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +.topcoat-button:focus,
    +.topcoat-button--quiet:focus,
    +.topcoat-button--large:focus,
    +.topcoat-button--large--quiet:focus,
    +.topcoat-button--cta:focus,
    +.topcoat-button--large--cta:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--quiet">Button</button>
    <button class="topcoat-button--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large--quiet:hover {
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-button--quiet:active,
    +.topcoat-button--large--quiet:active {
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #404141;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large" >Button</button>
    <button class="topcoat-button--large" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large,
    +.topcoat-button--large--quiet {
    +  font-size: 0.875rem;
    +  font-weight: 600;
    +  line-height: 1.688rem;
    +  padding: 0 0.875rem;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--quiet" >Button</button>
    <button class="topcoat-button--large--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--cta" >Button</button>
    <button class="topcoat-button--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  border: 1px solid #143250;
    +  background-color: #288edf;
    +  box-shadow: inset 0 1px rgba(255,255,255,0.36);
    +  color: #fff;
    +  font-weight: 500;
    +  text-shadow: 0 -1px rgba(0,0,0,0.36);
    +}
    +
    +.topcoat-button--cta:hover,
    +.topcoat-button--large--cta:hover {
    +  background-color: #509bef;
    +}
    +
    +.topcoat-button--cta:active,
    +.topcoat-button--large--cta:active {
    +  background-color: #1976c3;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--cta" >Button</button>
    <button class="topcoat-button--large--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--cta {
    +  font-size: 0.875rem;
    +  font-weight: 600;
    +  line-height: 1.688rem;
    +  padding: 0 0.875rem;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox,
    +.topcoat-checkbox__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label,
    +.topcoat-checkbox {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled,
    +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after,
    +.topcoat-checkbox__checkmark:before,
    +.topcoat-checkbox__checkmark:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before,
    +.topcoat-checkbox__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Checkbox

    +
    +


    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-checkbox">
      <input type="checkbox">
      <div class="topcoat-checkbox__checkmark"></div>
      Default
    </label>
    <br>
    <br>
    <label class="topcoat-checkbox">
      <input type="checkbox" disabled>
      <div class="topcoat-checkbox__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-checkbox__checkmark {
    +  height: 1rem;
    +}
    +
    +input[type="checkbox"] {
    +  height: 1rem;
    +  width: 1rem;
    +  margin-top: 0;
    +  margin-right: -1rem;
    +  margin-bottom: -1rem;
    +  margin-left: 0;
    +}
    +
    +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-checkbox {
    +  line-height: 1rem;
    +}
    +
    +.topcoat-checkbox__checkmark:before {
    +  width: 1rem;
    +  height: 1rem;
    +  background: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 3px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-checkbox__checkmark {
    +  width: 1rem;
    +  height: 1rem;
    +}
    +
    +.topcoat-checkbox__checkmark:after {
    +  top: 2px;
    +  left: 1px;
    +  opacity: 0;
    +  width: 14px;
    +  height: 4px;
    +  background: transparent;
    +  border: 7px solid #fff;
    +  border-width: 3px;
    +  border-top: none;
    +  border-right: none;
    +  border-radius: 1px;
    +  -webkit-transform: rotate(-50deg);
    +  -ms-transform: rotate(-50deg);
    +  transform: rotate(-50deg);
    +}
    +
    +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-icon-button:disabled,
    +.topcoat-icon-button--quiet:disabled,
    +.topcoat-icon-button--large:disabled,
    +.topcoat-icon-button--large--quiet:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  padding: 0 0.25rem;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: baseline;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border: 1px solid #303233;
    +  border-radius: 4px;
    +}
    +
    +.topcoat-icon-button:hover,
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  background-color: #646666;
    +}
    +
    +.topcoat-icon-button:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +.topcoat-icon-button:focus,
    +.topcoat-icon-button--quiet:focus,
    +.topcoat-icon-button--quiet:hover:focus,
    +.topcoat-icon-button--large:focus,
    +.topcoat-icon-button--large--quiet:focus,
    +.topcoat-icon-button--large--quiet:hover:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--quiet">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--quiet" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-icon-button--quiet:active,
    +.topcoat-icon-button--large--quiet:active {
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #404141;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  width: 1.688rem;
    +  height: 1.688rem;
    +  line-height: 1.688rem;
    +}
    +
    +.topcoat-icon-button--large:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large--quiet">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large--quiet" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon,
    +.topcoat-icon--large {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  overflow: hidden;
    +  width: 0.81406rem;
    +  height: 0.81406rem;
    +  vertical-align: middle;
    +  top: -1px;
    +}
    +
    +.topcoat-icon--large {
    +  width: 1.06344rem;
    +  height: 1.06344rem;
    +  top: -2px;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header {
    +  margin: 0;
    +}
    +
    +.list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.notification {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.notification,
    +.topcoat-notification {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Notification

    +
    +
    1
    +
    + +
    +
    +

    HTML

    +
    <span class="topcoat-notification">1</span>
    +
    +
    +

    CSS

    +
    
    +.topcoat-notification {
    +  padding: 0.15em 0.5em 0.2em;
    +  border-radius: 2px;
    +  background-color: #ec514e;
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button,
    +.topcoat-radio-button__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label,
    +.topcoat-radio-button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:before,
    +.topcoat-radio-button__checkmark:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before,
    +.topcoat-radio-button__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled,
    +input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Radio Button

    +
    +






    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <!-- NO LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- LEFT LABEL -->
    <label class="topcoat-radio-button">
      Left label
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- RIGHT LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
      Right label
    </label>
    <br>
    <br>
    <!-- DISABLED -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat" Disabled>
      <div class="topcoat-radio-button__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +input[type="radio"] {
    +  height: 1.063rem;
    +  width: 1.063rem;
    +  margin-top: 0;
    +  margin-right: -1.063rem;
    +  margin-bottom: -1.063rem;
    +  margin-left: 0;
    +}
    +
    +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-radio-button {
    +  color: #c6c8c8;
    +  line-height: 1.063rem;
    +}
    +
    +.topcoat-radio-button__checkmark:before {
    +  width: 1.063rem;
    +  height: 1.063rem;
    +  background: #595b5b;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-radio-button__checkmark {
    +  position: relative;
    +  width: 1.063rem;
    +  height: 1.063rem;
    +}
    +
    +.topcoat-radio-button__checkmark:after {
    +  opacity: 0;
    +  width: 0.313rem;
    +  height: 0.313rem;
    +  background: #fff;
    +  border: 1px solid rgba(255,255,255,0.1);
    +  box-shadow: 0 1px rgba(255,255,255,0.5);
    +  -webkit-transform: none;
    +  -ms-transform: none;
    +  transform: none;
    +  top: 0.313rem;
    +  left: 0.313rem;
    +}
    +
    +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range,
    +.topcoat-range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb,
    +.topcoat-range::-moz-range-thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit,
    +.topcoat-range::-webkit-slider-thumb {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled,
    +.topcoat-range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Range

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <input type="range" class="topcoat-range">
    <input type="range" class="topcoat-range" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-range {
    +  border-radius: 4px;
    +  border: 1px solid #303233;
    +  background-color: #424546;
    +  height: 0.5rem;
    +  border-radius: 15px;
    +}
    +
    +.topcoat-range::-moz-range-track {
    +  border-radius: 4px;
    +  border: 1px solid #303233;
    +  background-color: #424546;
    +  height: 0.5rem;
    +  border-radius: 15px;
    +}
    +
    +.topcoat-range::-webkit-slider-thumb {
    +  height: 1.313rem;
    +  width: 0.75rem;
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 4px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-range::-moz-range-thumb {
    +  height: 1.313rem;
    +  width: 0.75rem;
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 4px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-range:focus::-webkit-slider-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-range:focus::-moz-range-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input,
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled,
    +.topcoat-search-input:disabled,
    +.topcoat-search-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input">
    <input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  line-height: 1.313rem;
    +  font-size: 12px;
    +  border: 1px solid #303233;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  padding: 0 0 0 1.3rem;
    +  border-radius: 15px;
    +  background-image: url("../img/search.svg");
    +  background-position: 1em center;
    +  background-repeat: no-repeat;
    +  background-size: 12px;
    +}
    +
    +.topcoat-search-input:focus,
    +.topcoat-search-input--large:focus {
    +  background-image: url("../img/search_dark.svg");
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-search-input::-webkit-search-cancel-button,
    +.topcoat-search-input::-webkit-search-decoration,
    +.topcoat-search-input--large::-webkit-search-cancel-button,
    +.topcoat-search-input--large::-webkit-search-decoration {
    +  margin-right: 5px;
    +}
    +
    +.topcoat-search-input:focus::-webkit-input-placeholder,
    +.topcoat-search-input:focus::-webkit-input-placeholder {
    +  color: #c6c8c8;
    +}
    +
    +.topcoat-search-input:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large">
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input--large {
    +  line-height: 1.688rem;
    +  font-size: 0.875rem;
    +  font-weight: 400;
    +  padding: 0 0 0 1.8rem;
    +  border-radius: 25px;
    +  background-position: 1.2em center;
    +  background-size: 0.875rem;
    +}
    +
    +.topcoat-search-input--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch,
    +.topcoat-switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input,
    +.topcoat-switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle,
    +.topcoat-switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after,
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Switch

    +
    +




    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input">
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" checked>
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" disabled>
      <div class="topcoat-switch__toggle"></div>
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-switch {
    +  font-size: 12px;
    +  padding: 0 0.563rem;
    +  border-radius: 4px;
    +  border: 1px solid #303233;
    +  overflow: hidden;
    +  width: 3.5rem;
    +}
    +
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  top: -1px;
    +  width: 2.6rem;
    +}
    +
    +.topcoat-switch__toggle:before {
    +  content: 'ON';
    +  color: #5dc1ff;
    +  background-color: #404141;
    +  right: 0.8rem;
    +  padding-left: 0.75rem;
    +}
    +
    +.topcoat-switch__toggle {
    +  line-height: 1.313rem;
    +  height: 1.313rem;
    +  width: 1rem;
    +  border-radius: 4px;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  margin-left: -0.6rem;
    +  margin-bottom: -1px;
    +  margin-top: -1px;
    +  box-shadow: inset 0 1px #727373;
    +  -webkit-transition: margin-left 0.05s ease-in-out;
    +  transition: margin-left 0.05s ease-in-out;
    +}
    +
    +.topcoat-switch__toggle:after {
    +  content: 'OFF';
    +  background-color: #404141;
    +  left: 0.8rem;
    +  padding-left: 0.6rem;
    +}
    +
    +.topcoat-switch__input:checked + .topcoat-switch__toggle {
    +  margin-left: 1.85rem;
    +}
    +
    +.topcoat-switch__input:focus + .topcoat-switch__toggle {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
    +  background: transparent;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-tab-bar__button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-tab-bar__button:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.button-bar,
    +.topcoat-tab-bar {
    +  display: table;
    +  table-layout: fixed;
    +  white-space: nowrap;
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +.button-bar__item,
    +.topcoat-tab-bar__item {
    +  display: table-cell;
    +  width: auto;
    +  border-radius: 0;
    +}
    +
    +.button-bar__item > input,
    +.topcoat-tab-bar__item > input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.button-bar__item:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Tab Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-tab-bar">
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">One</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Two</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Three</button>
      </label>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-tab-bar__button {
    +  padding: 0 0.563rem;
    +  height: 1.313rem;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: top;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border-top: 1px solid #303233;
    +}
    +
    +.topcoat-tab-bar__button:active,
    +.topcoat-tab-bar__button--large:active,
    +:checked + .topcoat-tab-bar__button {
    +  color: #5dc1ff;
    +  background-color: #404141;
    +  box-shadow: inset 0 0 2px #313231;
    +}
    +
    +.topcoat-tab-bar__button:focus,
    +.topcoat-tab-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input,
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled,
    +.topcoat-text-input:disabled,
    +.topcoat-text-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Text input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input" placeholder="text" value="">
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  line-height: 1.313rem;
    +  font-size: 12px;
    +  letter-spacing: 0;
    +  padding: 0 0.563rem;
    +  border: 1px solid #303233;
    +  border-radius: 4px;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  vertical-align: top;
    +}
    +
    +.topcoat-text-input:focus,
    +.topcoat-text-input--large:focus {
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-text-input:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Text Input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text">
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input--large {
    +  line-height: 1.688rem;
    +  font-size: 0.875rem;
    +}
    +
    +.topcoat-text-input--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea,
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled,
    +.topcoat-textarea:disabled,
    +.topcoat-textarea--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  padding: 1rem;
    +  font-size: 1rem;
    +  font-weight: 400;
    +  border-radius: 4px;
    +  line-height: 1.313rem;
    +  border: 1px solid #303233;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  letter-spacing: 0;
    +}
    +
    +.topcoat-textarea:focus,
    +.topcoat-textarea--large:focus {
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-textarea:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea--large {
    +  font-size: 1.3rem;
    +  line-height: 1.688rem;
    +}
    +
    +.topcoat-textarea--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Regular.otf");
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Light.otf");
    +  font-weight: 200;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Semibold.otf");
    +  font-weight: 600;
    +}
    +
    +body {
    +  margin: 0;
    +  padding: 0;
    +  background: #4b4d4e;
    +  color: #000;
    +  font: 16px "Source Sans", helvetica, arial, sans-serif;
    +  font-weight: 200;
    +}
    +
    +:focus {
    +  outline-color: transparent;
    +  outline-style: none;
    +}
    +
    +.topcoat-icon--menu-stack {
    +  background: url("../img/hamburger_light.svg") no-repeat;
    +  background-size: cover;
    +}
    +
    +.quarter {
    +  width: 25%;
    +}
    +
    +.half {
    +  width: 50%;
    +}
    +
    +.three-quarters {
    +  width: 75%;
    +}
    +
    +.third {
    +  width: 33.333%;
    +}
    +
    +.two-thirds {
    +  width: 66.666%;
    +}
    +
    +.full {
    +  width: 100%;
    +}
    +
    +.left {
    +  text-align: left;
    +}
    +
    +.center {
    +  text-align: center;
    +}
    +
    +.right {
    +  text-align: right;
    +}
    +
    +.reset-ui {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/* This file should include color and image variables corresponding to the dark theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* Search Input */
    +
    +/* List */
    +
    +/* Checkbox */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Textarea */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* This file should include color and image variables corresponding to the light theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* List */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Range input */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Containers */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Text Area */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* Text Input */
    +
    +/* Radio input */
    +
    +/* Overlay */
    +
    +/* Textarea */
    +
    +/* Progress bar container */
    +
    +/* Progress bar progress */
    +
    +/* Search input */
    +
    +/* Switch */
    +
    +/* Notification */
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/js/main.js b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/js/main.js new file mode 100755 index 0000000..6dcdbd8 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/js/main.js @@ -0,0 +1,44 @@ +window.onload = function(){ + var showCodeDivs = document.getElementsByClassName('showcode'); + for (var i = showCodeDivs.length - 1; i >= 0; i--) { + showCodeDivs[i].firstChild.onclick = function(e) { + var element = e.target.parentNode.nextSibling.nextSibling; + var style = window.getComputedStyle(element); + if(style.getPropertyValue('display') == 'none'){ + e.target.innerHTML = 'Hide code snippets'; + element.style.display = 'block'; + } else { + e.target.innerHTML = 'Show code snippets'; + element.style.display = 'none'; + } + return false; + }; + }; + var slideMenuButton = document.getElementById('slide-menu-button'); + slideMenuButton.onclick = function(e) { + var site = document.getElementById('site'); + var cl = site.classList; + if (cl.contains('open')) { + cl.remove('open'); + } else { + cl.add('open'); + } + }; + var docNavs = document.getElementsByClassName('docNav'); + for (var j = docNavs.length - 1; j >= 0; j--) { + docNavs[j].onchange = function(e){ + window.location.href = e.target[e.target.selectedIndex].value; + }; + }; + var pageNav = document.getElementById('pageNav'); + var pageLinks = pageNav.getElementsByTagName('a'); + for (var k = pageLinks.length - 1; k >= 0; k--) { + pageLinks[k].onclick = function(e) { + var site = document.getElementById('site'); + var cl = site.classList; + if (cl.contains('open')) { + cl.remove('open'); + } + }; + }; +} \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/js/rainbow-custom.min.js b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/js/rainbow-custom.min.js new file mode 100755 index 0000000..a25e178 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/js/rainbow-custom.min.js @@ -0,0 +1,11 @@ +/* Rainbow v1.2 rainbowco.de | included languages: html, css */ +window.Rainbow=function(){function q(a){var b,c=a.getAttribute&&a.getAttribute("data-language")||0;if(!c){a=a.attributes;for(b=0;b=f[d][c])delete f[d][c],delete j[d][c];if(a>=c&&ac&&b'+b+""}function s(a,b,c,i){var e=a.exec(c);if(e){++t;!b.name&&"string"==typeof b.matches[0]&&(b.name=b.matches[0],delete b.matches[0]);var k=e[0],g=e.index,u=e[0].length+g,h=function(){function e(){s(a,b,c,i)}t%100>0?e():setTimeout(e,0)};if(C(g,u))h();else{var m=v(b.matches),l=function(a,c,i){if(a>=c.length)i(k);else{var d=e[c[a]];if(d){var g=b.matches[c[a]],f=g.language,h=g.name&&g.matches? +g.matches:g,j=function(b,d,g){var f;f=0;var h;for(h=1;h/g,">").replace(/&(?![\w\#]+;)/g, +"&"),b,c)}function o(a,b,c){if(b + + + + + Topcoat + + + + + + + +
    + +
    +
    +
    +
    +

    Topcoat

    +

    CSS for clean and fast web apps

    +
    + +
    +
    +
    +
    +
    +

    Button Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar > .topcoat-button-bar__item:first-child {
    +  border-top-left-radius: 4px;
    +  border-bottom-left-radius: 4px;
    +}
    +
    +.topcoat-button-bar > .topcoat-button-bar__item:last-child {
    +  border-top-right-radius: 4px;
    +  border-bottom-right-radius: 4px;
    +}
    +
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
    +  border-right: none;
    +}
    +
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
    +  border-left: none;
    +}
    +
    +.topcoat-button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.topcoat-button-bar__button:focus,
    +.topcoat-button-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button Bar

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar__button--large {
    +  border-radius: inherit;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-button:disabled,
    +.topcoat-button--quiet:disabled,
    +.topcoat-button--large:disabled,
    +.topcoat-button--large--quiet:disabled,
    +.topcoat-button--cta:disabled,
    +.topcoat-button--large--cta:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Button

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button">Button</button>
    <button class="topcoat-button" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  padding: 0 0.563rem;
    +  font-size: 12px;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: top;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 4px;
    +}
    +
    +.topcoat-button:hover,
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large:hover,
    +.topcoat-button--large--quiet:hover {
    +  background-color: #edf1f1;
    +}
    +
    +.topcoat-button:active,
    +.topcoat-button--large:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +.topcoat-button:focus,
    +.topcoat-button--quiet:focus,
    +.topcoat-button--large:focus,
    +.topcoat-button--large--quiet:focus,
    +.topcoat-button--cta:focus,
    +.topcoat-button--large--cta:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--quiet">Button</button>
    <button class="topcoat-button--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large--quiet:hover {
    +  text-shadow: 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-button--quiet:active,
    +.topcoat-button--large--quiet:active {
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #d3d7d7;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large" >Button</button>
    <button class="topcoat-button--large" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large,
    +.topcoat-button--large--quiet {
    +  font-size: 0.875rem;
    +  font-weight: 600;
    +  line-height: 1.688rem;
    +  padding: 0 0.875rem;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--quiet" >Button</button>
    <button class="topcoat-button--large--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--cta" >Button</button>
    <button class="topcoat-button--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  border: 1px solid #143250;
    +  background-color: #288edf;
    +  box-shadow: inset 0 1px rgba(255,255,255,0.36);
    +  color: #fff;
    +  font-weight: 500;
    +  text-shadow: 0 -1px rgba(0,0,0,0.36);
    +}
    +
    +.topcoat-button--cta:hover,
    +.topcoat-button--large--cta:hover {
    +  background-color: #509bef;
    +}
    +
    +.topcoat-button--cta:active,
    +.topcoat-button--large--cta:active {
    +  background-color: #0380e8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--cta" >Button</button>
    <button class="topcoat-button--large--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--cta {
    +  font-size: 0.875rem;
    +  font-weight: 600;
    +  line-height: 1.688rem;
    +  padding: 0 0.875rem;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox,
    +.topcoat-checkbox__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label,
    +.topcoat-checkbox {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled,
    +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after,
    +.topcoat-checkbox__checkmark:before,
    +.topcoat-checkbox__checkmark:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before,
    +.topcoat-checkbox__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Checkbox

    +
    +


    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-checkbox">
      <input type="checkbox">
      <div class="topcoat-checkbox__checkmark"></div>
      Default
    </label>
    <br>
    <br>
    <label class="topcoat-checkbox">
      <input type="checkbox" disabled>
      <div class="topcoat-checkbox__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-checkbox__checkmark {
    +  height: 1rem;
    +}
    +
    +input[type="checkbox"] {
    +  height: 1rem;
    +  width: 1rem;
    +  margin-top: 0;
    +  margin-right: -1rem;
    +  margin-bottom: -1rem;
    +  margin-left: 0;
    +}
    +
    +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-checkbox {
    +  line-height: 1rem;
    +}
    +
    +.topcoat-checkbox__checkmark:before {
    +  width: 1rem;
    +  height: 1rem;
    +  background: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 3px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-checkbox__checkmark {
    +  width: 1rem;
    +  height: 1rem;
    +}
    +
    +.topcoat-checkbox__checkmark:after {
    +  top: 2px;
    +  left: 1px;
    +  opacity: 0;
    +  width: 14px;
    +  height: 4px;
    +  background: transparent;
    +  border: 7px solid #666;
    +  border-width: 3px;
    +  border-top: none;
    +  border-right: none;
    +  border-radius: 1px;
    +  -webkit-transform: rotate(-50deg);
    +  -ms-transform: rotate(-50deg);
    +  transform: rotate(-50deg);
    +}
    +
    +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-icon-button:disabled,
    +.topcoat-icon-button--quiet:disabled,
    +.topcoat-icon-button--large:disabled,
    +.topcoat-icon-button--large--quiet:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  padding: 0 0.25rem;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: baseline;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 4px;
    +}
    +
    +.topcoat-icon-button:hover,
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  background-color: #edf1f1;
    +}
    +
    +.topcoat-icon-button:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +.topcoat-icon-button:focus,
    +.topcoat-icon-button--quiet:focus,
    +.topcoat-icon-button--quiet:hover:focus,
    +.topcoat-icon-button--large:focus,
    +.topcoat-icon-button--large--quiet:focus,
    +.topcoat-icon-button--large--quiet:hover:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--quiet">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--quiet" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  text-shadow: 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-icon-button--quiet:active,
    +.topcoat-icon-button--large--quiet:active {
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #d3d7d7;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  width: 1.688rem;
    +  height: 1.688rem;
    +  line-height: 1.688rem;
    +}
    +
    +.topcoat-icon-button--large:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large--quiet">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large--quiet" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon,
    +.topcoat-icon--large {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  overflow: hidden;
    +  width: 0.81406rem;
    +  height: 0.81406rem;
    +  vertical-align: middle;
    +  top: -1px;
    +}
    +
    +.topcoat-icon--large {
    +  width: 1.06344rem;
    +  height: 1.06344rem;
    +  top: -2px;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header {
    +  margin: 0;
    +}
    +
    +.list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.notification {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.notification,
    +.topcoat-notification {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Notification

    +
    +
    1
    +
    + +
    +
    +

    HTML

    +
    <span class="topcoat-notification">1</span>
    +
    +
    +

    CSS

    +
    
    +.topcoat-notification {
    +  padding: 0.15em 0.5em 0.2em;
    +  border-radius: 2px;
    +  background-color: #ec514e;
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button,
    +.topcoat-radio-button__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label,
    +.topcoat-radio-button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:before,
    +.topcoat-radio-button__checkmark:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before,
    +.topcoat-radio-button__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled,
    +input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Radio Button

    +
    +






    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <!-- NO LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- LEFT LABEL -->
    <label class="topcoat-radio-button">
      Left label
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- RIGHT LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
      Right label
    </label>
    <br>
    <br>
    <!-- DISABLED -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat" Disabled>
      <div class="topcoat-radio-button__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +input[type="radio"] {
    +  height: 1.063rem;
    +  width: 1.063rem;
    +  margin-top: 0;
    +  margin-right: -1.063rem;
    +  margin-bottom: -1.063rem;
    +  margin-left: 0;
    +}
    +
    +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-radio-button {
    +  color: #454545;
    +  line-height: 1.063rem;
    +}
    +
    +.topcoat-radio-button__checkmark:before {
    +  width: 1.063rem;
    +  height: 1.063rem;
    +  background: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-radio-button__checkmark {
    +  position: relative;
    +  width: 1.063rem;
    +  height: 1.063rem;
    +}
    +
    +.topcoat-radio-button__checkmark:after {
    +  opacity: 0;
    +  width: 0.313rem;
    +  height: 0.313rem;
    +  background: #666;
    +  border: 1px solid rgba(0,0,0,0.1);
    +  box-shadow: 0 1px rgba(255,255,255,0.5);
    +  -webkit-transform: none;
    +  -ms-transform: none;
    +  transform: none;
    +  top: 0.313rem;
    +  left: 0.313rem;
    +}
    +
    +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range,
    +.topcoat-range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb,
    +.topcoat-range::-moz-range-thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit,
    +.topcoat-range::-webkit-slider-thumb {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled,
    +.topcoat-range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Range

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <input type="range" class="topcoat-range">
    <input type="range" class="topcoat-range" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-range {
    +  border-radius: 4px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  height: 0.5rem;
    +  border-radius: 15px;
    +}
    +
    +.topcoat-range::-moz-range-track {
    +  border-radius: 4px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  height: 0.5rem;
    +  border-radius: 15px;
    +}
    +
    +.topcoat-range::-webkit-slider-thumb {
    +  height: 1.313rem;
    +  width: 0.75rem;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 4px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-range::-moz-range-thumb {
    +  height: 1.313rem;
    +  width: 0.75rem;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 4px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-range:focus::-webkit-slider-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-range:focus::-moz-range-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input,
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled,
    +.topcoat-search-input:disabled,
    +.topcoat-search-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input">
    <input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  line-height: 1.313rem;
    +  font-size: 12px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  padding: 0 0 0 1.3rem;
    +  border-radius: 15px;
    +  background-image: url("../img/search.svg");
    +  background-position: 1em center;
    +  background-repeat: no-repeat;
    +  background-size: 12px;
    +}
    +
    +.topcoat-search-input:focus,
    +.topcoat-search-input--large:focus {
    +  background-image: url("../img/search_dark.svg");
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-search-input::-webkit-search-cancel-button,
    +.topcoat-search-input::-webkit-search-decoration,
    +.topcoat-search-input--large::-webkit-search-cancel-button,
    +.topcoat-search-input--large::-webkit-search-decoration {
    +  margin-right: 5px;
    +}
    +
    +.topcoat-search-input:focus::-webkit-input-placeholder,
    +.topcoat-search-input:focus::-webkit-input-placeholder {
    +  color: #c6c8c8;
    +}
    +
    +.topcoat-search-input:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large">
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input--large {
    +  line-height: 1.688rem;
    +  font-size: 0.875rem;
    +  font-weight: 400;
    +  padding: 0 0 0 1.8rem;
    +  border-radius: 25px;
    +  background-position: 1.2em center;
    +  background-size: 0.875rem;
    +}
    +
    +.topcoat-search-input--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch,
    +.topcoat-switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input,
    +.topcoat-switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle,
    +.topcoat-switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after,
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Switch

    +
    +




    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input">
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" checked>
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" disabled>
      <div class="topcoat-switch__toggle"></div>
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-switch {
    +  font-size: 12px;
    +  padding: 0 0.563rem;
    +  border-radius: 4px;
    +  border: 1px solid #a5a8a8;
    +  overflow: hidden;
    +  width: 3.5rem;
    +}
    +
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  top: -1px;
    +  width: 2.6rem;
    +}
    +
    +.topcoat-switch__toggle:before {
    +  content: 'ON';
    +  color: #0083e8;
    +  background-color: #e0f0fa;
    +  right: 0.8rem;
    +  padding-left: 0.75rem;
    +}
    +
    +.topcoat-switch__toggle {
    +  line-height: 1.313rem;
    +  height: 1.313rem;
    +  width: 1rem;
    +  border-radius: 4px;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  margin-left: -0.6rem;
    +  margin-bottom: -1px;
    +  margin-top: -1px;
    +  box-shadow: inset 0 1px #fff;
    +  -webkit-transition: margin-left 0.05s ease-in-out;
    +  transition: margin-left 0.05s ease-in-out;
    +}
    +
    +.topcoat-switch__toggle:after {
    +  content: 'OFF';
    +  background-color: #d3d7d7;
    +  left: 0.8rem;
    +  padding-left: 0.6rem;
    +}
    +
    +.topcoat-switch__input:checked + .topcoat-switch__toggle {
    +  margin-left: 1.85rem;
    +}
    +
    +.topcoat-switch__input:focus + .topcoat-switch__toggle {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
    +  background: transparent;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-tab-bar__button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-tab-bar__button:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.button-bar,
    +.topcoat-tab-bar {
    +  display: table;
    +  table-layout: fixed;
    +  white-space: nowrap;
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +.button-bar__item,
    +.topcoat-tab-bar__item {
    +  display: table-cell;
    +  width: auto;
    +  border-radius: 0;
    +}
    +
    +.button-bar__item > input,
    +.topcoat-tab-bar__item > input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.button-bar__item:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Tab Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-tab-bar">
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">One</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Two</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Three</button>
      </label>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-tab-bar__button {
    +  padding: 0 0.563rem;
    +  height: 1.313rem;
    +  line-height: 1.313rem;
    +  letter-spacing: 0;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: top;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border-top: 1px solid #a5a8a8;
    +}
    +
    +.topcoat-tab-bar__button:active,
    +.topcoat-tab-bar__button--large:active,
    +:checked + .topcoat-tab-bar__button {
    +  color: #0083e8;
    +  background-color: #e0f0fa;
    +  box-shadow: inset 0 0 2px #c0ced8;
    +}
    +
    +.topcoat-tab-bar__button:focus,
    +.topcoat-tab-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input,
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled,
    +.topcoat-text-input:disabled,
    +.topcoat-text-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Text input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input" placeholder="text" value="">
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  line-height: 1.313rem;
    +  font-size: 12px;
    +  letter-spacing: 0;
    +  padding: 0 0.563rem;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 4px;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  vertical-align: top;
    +}
    +
    +.topcoat-text-input:focus,
    +.topcoat-text-input--large:focus {
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-text-input:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Text Input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text">
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input--large {
    +  line-height: 1.688rem;
    +  font-size: 0.875rem;
    +}
    +
    +.topcoat-text-input--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea,
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled,
    +.topcoat-textarea:disabled,
    +.topcoat-textarea--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  padding: 1rem;
    +  font-size: 1rem;
    +  font-weight: 400;
    +  border-radius: 4px;
    +  line-height: 1.313rem;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  letter-spacing: 0;
    +}
    +
    +.topcoat-textarea:focus,
    +.topcoat-textarea--large:focus {
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-textarea:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea--large {
    +  font-size: 1.3rem;
    +  line-height: 1.688rem;
    +}
    +
    +.topcoat-textarea--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Regular.otf");
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Light.otf");
    +  font-weight: 200;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Semibold.otf");
    +  font-weight: 600;
    +}
    +
    +body {
    +  margin: 0;
    +  padding: 0;
    +  background: #dfe2e2;
    +  color: #000;
    +  font: 16px "Source Sans", helvetica, arial, sans-serif;
    +  font-weight: 200;
    +}
    +
    +:focus {
    +  outline-color: transparent;
    +  outline-style: none;
    +}
    +
    +.topcoat-icon--menu-stack {
    +  background: url("../img/hamburger_dark.svg") no-repeat;
    +  background-size: cover;
    +}
    +
    +.quarter {
    +  width: 25%;
    +}
    +
    +.half {
    +  width: 50%;
    +}
    +
    +.three-quarters {
    +  width: 75%;
    +}
    +
    +.third {
    +  width: 33.333%;
    +}
    +
    +.two-thirds {
    +  width: 66.666%;
    +}
    +
    +.full {
    +  width: 100%;
    +}
    +
    +.left {
    +  text-align: left;
    +}
    +
    +.center {
    +  text-align: center;
    +}
    +
    +.right {
    +  text-align: right;
    +}
    +
    +.reset-ui {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/* This file should include color and image variables corresponding to the dark theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* Search Input */
    +
    +/* List */
    +
    +/* Checkbox */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Textarea */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* This file should include color and image variables corresponding to the light theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* List */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Range input */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Containers */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Text Area */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* Text Input */
    +
    +/* Radio input */
    +
    +/* Overlay */
    +
    +/* Textarea */
    +
    +/* Progress bar container */
    +
    +/* Progress bar progress */
    +
    +/* Search input */
    +
    +/* Switch */
    +
    +/* Notification */
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/topcoat-mobile-dark.html b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/topcoat-mobile-dark.html new file mode 100755 index 0000000..327aeae --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/topcoat-mobile-dark.html @@ -0,0 +1,3417 @@ + + + + + + Topcoat + + + + + + + +
    + +
    +
    +
    +
    +

    Topcoat

    +

    CSS for clean and fast web apps

    +
    + +
    +
    +
    +
    +
    +

    Button Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar > .topcoat-button-bar__item:first-child {
    +  border-top-left-radius: 6px;
    +  border-bottom-left-radius: 6px;
    +}
    +
    +.topcoat-button-bar > .topcoat-button-bar__item:last-child {
    +  border-top-right-radius: 6px;
    +  border-bottom-right-radius: 6px;
    +}
    +
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
    +  border-right: none;
    +}
    +
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
    +  border-left: none;
    +}
    +
    +.topcoat-button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.topcoat-button-bar__button:focus,
    +.topcoat-button-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button Bar

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar__button--large {
    +  border-radius: inherit;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-button:disabled,
    +.topcoat-button--quiet:disabled,
    +.topcoat-button--large:disabled,
    +.topcoat-button--large--quiet:disabled,
    +.topcoat-button--cta:disabled,
    +.topcoat-button--large--cta:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Button

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button">Button</button>
    <button class="topcoat-button" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  padding: 0 1.25rem;
    +  font-size: 16px;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: top;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border: 1px solid #303233;
    +  border-radius: 6px;
    +}
    +
    +.topcoat-button:hover,
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large:hover,
    +.topcoat-button--large--quiet:hover {
    +  background-color: #646666;
    +}
    +
    +.topcoat-button:active,
    +.topcoat-button--large:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +.topcoat-button:focus,
    +.topcoat-button--quiet:focus,
    +.topcoat-button--large:focus,
    +.topcoat-button--large--quiet:focus,
    +.topcoat-button--cta:focus,
    +.topcoat-button--large--cta:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--quiet">Button</button>
    <button class="topcoat-button--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large--quiet:hover {
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-button--quiet:active,
    +.topcoat-button--large--quiet:active {
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #404141;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large" >Button</button>
    <button class="topcoat-button--large" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large,
    +.topcoat-button--large--quiet {
    +  font-size: 1.3rem;
    +  font-weight: 400;
    +  line-height: 4.375rem;
    +  padding: 0 1.25rem;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--quiet" >Button</button>
    <button class="topcoat-button--large--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--cta" >Button</button>
    <button class="topcoat-button--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  border: 1px solid #143250;
    +  background-color: #288edf;
    +  box-shadow: inset 0 1px rgba(255,255,255,0.36);
    +  color: #fff;
    +  font-weight: 500;
    +  text-shadow: 0 -1px rgba(0,0,0,0.36);
    +}
    +
    +.topcoat-button--cta:hover,
    +.topcoat-button--large--cta:hover {
    +  background-color: #509bef;
    +}
    +
    +.topcoat-button--cta:active,
    +.topcoat-button--large--cta:active {
    +  background-color: #1976c3;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--cta" >Button</button>
    <button class="topcoat-button--large--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--cta {
    +  font-size: 1.3rem;
    +  font-weight: 400;
    +  line-height: 4.375rem;
    +  padding: 0 1.25rem;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox,
    +.topcoat-checkbox__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label,
    +.topcoat-checkbox {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled,
    +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after,
    +.topcoat-checkbox__checkmark:before,
    +.topcoat-checkbox__checkmark:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before,
    +.topcoat-checkbox__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Checkbox

    +
    +


    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-checkbox">
      <input type="checkbox">
      <div class="topcoat-checkbox__checkmark"></div>
      Default
    </label>
    <br>
    <br>
    <label class="topcoat-checkbox">
      <input type="checkbox" disabled>
      <div class="topcoat-checkbox__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-checkbox__checkmark {
    +  height: 2rem;
    +}
    +
    +input[type="checkbox"] {
    +  height: 2rem;
    +  width: 2rem;
    +  margin-top: 0;
    +  margin-right: -2rem;
    +  margin-bottom: -2rem;
    +  margin-left: 0;
    +}
    +
    +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-checkbox {
    +  line-height: 2rem;
    +}
    +
    +.topcoat-checkbox__checkmark:before {
    +  width: 2rem;
    +  height: 2rem;
    +  background: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 3px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-checkbox__checkmark {
    +  width: 2rem;
    +  height: 2rem;
    +}
    +
    +.topcoat-checkbox__checkmark:after {
    +  top: 1px;
    +  left: 2px;
    +  opacity: 0;
    +  width: 28px;
    +  height: 11px;
    +  background: transparent;
    +  border: 7px solid #fff;
    +  border-width: 7px;
    +  border-top: none;
    +  border-right: none;
    +  border-radius: 2px;
    +  -webkit-transform: rotate(-50deg);
    +  -ms-transform: rotate(-50deg);
    +  transform: rotate(-50deg);
    +}
    +
    +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-icon-button:disabled,
    +.topcoat-icon-button--quiet:disabled,
    +.topcoat-icon-button--large:disabled,
    +.topcoat-icon-button--large--quiet:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  padding: 0 0.75rem;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: baseline;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border: 1px solid #303233;
    +  border-radius: 6px;
    +}
    +
    +.topcoat-icon-button:hover,
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  background-color: #646666;
    +}
    +
    +.topcoat-icon-button:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +.topcoat-icon-button:focus,
    +.topcoat-icon-button--quiet:focus,
    +.topcoat-icon-button--quiet:hover:focus,
    +.topcoat-icon-button--large:focus,
    +.topcoat-icon-button--large--quiet:focus,
    +.topcoat-icon-button--large--quiet:hover:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--quiet">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--quiet" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-icon-button--quiet:active,
    +.topcoat-icon-button--large--quiet:active {
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #404141;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  width: 4.375rem;
    +  height: 4.375rem;
    +  line-height: 4.375rem;
    +}
    +
    +.topcoat-icon-button--large:active {
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large--quiet">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large--quiet" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon,
    +.topcoat-icon--large {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  overflow: hidden;
    +  width: 1.62rem;
    +  height: 1.62rem;
    +  vertical-align: middle;
    +  top: -1px;
    +}
    +
    +.topcoat-icon--large {
    +  width: 2.499999998125rem;
    +  height: 2.499999998125rem;
    +  top: -2px;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header {
    +  margin: 0;
    +}
    +
    +.list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list,
    +.topcoat-list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header,
    +.topcoat-list__header {
    +  margin: 0;
    +}
    +
    +.list__container,
    +.topcoat-list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item,
    +.topcoat-list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    List

    +
    +

    Category

    • Item
    • Item
    • Item
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-list">
      <h3 class="topcoat-list__header">Category</h3>
      <ul class="topcoat-list__container">
        <li class="topcoat-list__item">
          Item
        </li>
        <li class="topcoat-list__item">
          Item
        </li>
        <li class="topcoat-list__item">
          Item
        </li>
      </ul>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-list {
    +  border-top: 1px solid #2f3234;
    +  border-bottom: 1px solid #5e6061;
    +  background-color: #444849;
    +}
    +
    +.topcoat-list__header {
    +  padding: 4px 20px;
    +  font-size: 0.9em;
    +  font-weight: 400;
    +  background-color: #3b3e40;
    +  color: #868888;
    +  text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
    +  border-top: solid 1px rgba(255,255,255,0.1);
    +  border-bottom: solid 1px rgba(255,255,255,0.05);
    +}
    +
    +.topcoat-list__container {
    +  border-top: 1px solid #2f3234;
    +  color: #c6c8c8;
    +}
    +
    +.topcoat-list__item {
    +  padding: 1.25rem;
    +  border-top: 1px solid #5e6061;
    +  border-bottom: 1px solid #2f3234;
    +}
    +
    +.topcoat-list__item:first-child {
    +  border-top: 1px solid rgba(0,0,0,0.05);
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar,
    +.topcoat-navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item,
    +.topcoat-navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title,
    +.topcoat-navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +
    +
    +
    +
    + +
    +
    +

    Notification

    +
    +
    1
    +
    + +
    +
    +

    HTML

    +
    <span class="topcoat-notification">1</span>
    +
    +
    +

    CSS

    +
    
    +.topcoat-notification {
    +  padding: 0.15em 0.5em 0.2em;
    +  border-radius: 2px;
    +  background-color: #ec514e;
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button,
    +.topcoat-radio-button__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label,
    +.topcoat-radio-button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:before,
    +.topcoat-radio-button__checkmark:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before,
    +.topcoat-radio-button__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled,
    +input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Radio Button

    +
    +






    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <!-- NO LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- LEFT LABEL -->
    <label class="topcoat-radio-button">
      Left label
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- RIGHT LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
      Right label
    </label>
    <br>
    <br>
    <!-- DISABLED -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat" Disabled>
      <div class="topcoat-radio-button__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +input[type="radio"] {
    +  height: 1.875rem;
    +  width: 1.875rem;
    +  margin-top: 0;
    +  margin-right: -1.875rem;
    +  margin-bottom: -1.875rem;
    +  margin-left: 0;
    +}
    +
    +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-radio-button {
    +  color: #c6c8c8;
    +  line-height: 1.875rem;
    +}
    +
    +.topcoat-radio-button__checkmark:before {
    +  width: 1.875rem;
    +  height: 1.875rem;
    +  background: #595b5b;
    +  border: 1px solid #303233;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-radio-button__checkmark {
    +  position: relative;
    +  width: 1.875rem;
    +  height: 1.875rem;
    +}
    +
    +.topcoat-radio-button__checkmark:after {
    +  opacity: 0;
    +  width: 0.875rem;
    +  height: 0.875rem;
    +  background: #fff;
    +  border: 1px solid rgba(255,255,255,0.1);
    +  box-shadow: 0 1px rgba(255,255,255,0.5);
    +  -webkit-transform: none;
    +  -ms-transform: none;
    +  transform: none;
    +  top: 7px;
    +  left: 7px;
    +}
    +
    +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range,
    +.topcoat-range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb,
    +.topcoat-range::-moz-range-thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit,
    +.topcoat-range::-webkit-slider-thumb {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled,
    +.topcoat-range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Range

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <input type="range" class="topcoat-range">
    <input type="range" class="topcoat-range" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-range {
    +  border-radius: 6px;
    +  border: 1px solid #303233;
    +  background-color: #424546;
    +  height: 1rem;
    +  border-radius: 30px;
    +}
    +
    +.topcoat-range::-moz-range-track {
    +  border-radius: 6px;
    +  border: 1px solid #303233;
    +  background-color: #424546;
    +  height: 1rem;
    +  border-radius: 30px;
    +}
    +
    +.topcoat-range::-webkit-slider-thumb {
    +  height: 3rem;
    +  width: 2rem;
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 6px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-range::-moz-range-thumb {
    +  height: 3rem;
    +  width: 2rem;
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  border-radius: 6px;
    +  box-shadow: inset 0 1px #727373;
    +}
    +
    +.topcoat-range:focus::-webkit-slider-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-range:focus::-moz-range-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input,
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled,
    +.topcoat-search-input:disabled,
    +.topcoat-search-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input">
    <input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  line-height: 3rem;
    +  font-size: 16px;
    +  border: 1px solid #303233;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  padding: 0 0 0 2rem;
    +  border-radius: 30px;
    +  background-image: url("../img/search.svg");
    +  background-position: 1em center;
    +  background-repeat: no-repeat;
    +  background-size: 16px;
    +}
    +
    +.topcoat-search-input:focus,
    +.topcoat-search-input--large:focus {
    +  background-image: url("../img/search_dark.svg");
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-search-input::-webkit-search-cancel-button,
    +.topcoat-search-input::-webkit-search-decoration,
    +.topcoat-search-input--large::-webkit-search-cancel-button,
    +.topcoat-search-input--large::-webkit-search-decoration {
    +  margin-right: 5px;
    +}
    +
    +.topcoat-search-input:focus::-webkit-input-placeholder,
    +.topcoat-search-input:focus::-webkit-input-placeholder {
    +  color: #c6c8c8;
    +}
    +
    +.topcoat-search-input:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large">
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input--large {
    +  line-height: 4.375rem;
    +  font-size: 1.3rem;
    +  font-weight: 200;
    +  padding: 0 0 0 2.9rem;
    +  border-radius: 40px;
    +  background-position: 1.2em center;
    +  background-size: 1.3rem;
    +}
    +
    +.topcoat-search-input--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-search-input--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch,
    +.topcoat-switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input,
    +.topcoat-switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle,
    +.topcoat-switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after,
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Switch

    +
    +




    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input">
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" checked>
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" disabled>
      <div class="topcoat-switch__toggle"></div>
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-switch {
    +  font-size: 16px;
    +  padding: 0 1.25rem;
    +  border-radius: 6px;
    +  border: 1px solid #303233;
    +  overflow: hidden;
    +  width: 6rem;
    +}
    +
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  top: -1px;
    +  width: 5rem;
    +}
    +
    +.topcoat-switch__toggle:before {
    +  content: 'ON';
    +  color: #5dc1ff;
    +  background-color: #404141;
    +  right: 1rem;
    +  padding-left: 1.5rem;
    +}
    +
    +.topcoat-switch__toggle {
    +  line-height: 3rem;
    +  height: 3rem;
    +  width: 2rem;
    +  border-radius: 6px;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  background-color: #595b5b;
    +  border: 1px solid #303233;
    +  margin-left: -1.3rem;
    +  margin-bottom: -1px;
    +  margin-top: -1px;
    +  box-shadow: inset 0 1px #727373;
    +  -webkit-transition: margin-left 0.05s ease-in-out;
    +  transition: margin-left 0.05s ease-in-out;
    +}
    +
    +.topcoat-switch__toggle:after {
    +  content: 'OFF';
    +  background-color: #404141;
    +  left: 1rem;
    +  padding-left: 2rem;
    +}
    +
    +.topcoat-switch__input:checked + .topcoat-switch__toggle {
    +  margin-left: 2.7rem;
    +}
    +
    +.topcoat-switch__input:focus + .topcoat-switch__toggle {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
    +  background: transparent;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-tab-bar__button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-tab-bar__button:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.button-bar,
    +.topcoat-tab-bar {
    +  display: table;
    +  table-layout: fixed;
    +  white-space: nowrap;
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +.button-bar__item,
    +.topcoat-tab-bar__item {
    +  display: table-cell;
    +  width: auto;
    +  border-radius: 0;
    +}
    +
    +.button-bar__item > input,
    +.topcoat-tab-bar__item > input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.button-bar__item:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Tab Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-tab-bar">
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">One</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Two</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Three</button>
      </label>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-tab-bar__button {
    +  padding: 0 1.25rem;
    +  height: 3rem;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #c6c8c8;
    +  text-shadow: 0 -1px rgba(0,0,0,0.69);
    +  vertical-align: top;
    +  background-color: #595b5b;
    +  box-shadow: inset 0 1px #727373;
    +  border-top: 1px solid #303233;
    +}
    +
    +.topcoat-tab-bar__button:active,
    +.topcoat-tab-bar__button--large:active,
    +:checked + .topcoat-tab-bar__button {
    +  color: #5dc1ff;
    +  background-color: #404141;
    +  box-shadow: inset 0 0 2px #313231;
    +}
    +
    +.topcoat-tab-bar__button:focus,
    +.topcoat-tab-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input,
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled,
    +.topcoat-text-input:disabled,
    +.topcoat-text-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Text input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input" placeholder="text" value="">
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  line-height: 3rem;
    +  font-size: 16px;
    +  letter-spacing: 1px;
    +  padding: 0 1.25rem;
    +  border: 1px solid #303233;
    +  border-radius: 6px;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  vertical-align: top;
    +}
    +
    +.topcoat-text-input:focus,
    +.topcoat-text-input--large:focus {
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-text-input:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Text Input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text">
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input--large {
    +  line-height: 4.375rem;
    +  font-size: 1.3rem;
    +}
    +
    +.topcoat-text-input--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-text-input--large:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea,
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled,
    +.topcoat-textarea:disabled,
    +.topcoat-textarea--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  padding: 2rem;
    +  font-size: 2.5rem;
    +  font-weight: 200;
    +  border-radius: 6px;
    +  line-height: 3rem;
    +  border: 1px solid #303233;
    +  background-color: #404141;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.18);
    +  color: #c6c8c8;
    +  letter-spacing: 1px;
    +}
    +
    +.topcoat-textarea:focus,
    +.topcoat-textarea--large:focus {
    +  background-color: #646666;
    +  color: #fff;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-textarea:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea--large {
    +  font-size: 3rem;
    +  line-height: 4.375rem;
    +}
    +
    +.topcoat-textarea--large:disabled {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled::-webkit-input-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled::-moz-placeholder {
    +  color: #fff;
    +}
    +
    +.topcoat-textarea--large:disabled:-ms-input-placeholder {
    +  color: #fff;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Regular.otf");
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Light.otf");
    +  font-weight: 200;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Semibold.otf");
    +  font-weight: 600;
    +}
    +
    +body {
    +  margin: 0;
    +  padding: 0;
    +  background: #4b4d4e;
    +  color: #000;
    +  font: 16px "Source Sans", helvetica, arial, sans-serif;
    +  font-weight: 200;
    +}
    +
    +:focus {
    +  outline-color: transparent;
    +  outline-style: none;
    +}
    +
    +.topcoat-icon--menu-stack {
    +  background: url("../img/hamburger_light.svg") no-repeat;
    +  background-size: cover;
    +}
    +
    +.quarter {
    +  width: 25%;
    +}
    +
    +.half {
    +  width: 50%;
    +}
    +
    +.three-quarters {
    +  width: 75%;
    +}
    +
    +.third {
    +  width: 33.333%;
    +}
    +
    +.two-thirds {
    +  width: 66.666%;
    +}
    +
    +.full {
    +  width: 100%;
    +}
    +
    +.left {
    +  text-align: left;
    +}
    +
    +.center {
    +  text-align: center;
    +}
    +
    +.right {
    +  text-align: right;
    +}
    +
    +.reset-ui {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/* This file should include color and image variables corresponding to the dark theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* Search Input */
    +
    +/* List */
    +
    +/* Checkbox */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Textarea */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* This file should include color and image variables corresponding to the light theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* List */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Range input */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Containers */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Text Area */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* Text Input */
    +
    +/* Radio input */
    +
    +/* Overlay */
    +
    +/* Textarea */
    +
    +/* Progress bar container */
    +
    +/* Progress bar progress */
    +
    +/* Search input */
    +
    +/* Switch */
    +
    +/* Notification */
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/topcoat-mobile-light.html b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/topcoat-mobile-light.html new file mode 100755 index 0000000..f67a519 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/demo/topcoat-mobile-light.html @@ -0,0 +1,3417 @@ + + + + + + Topcoat + + + + + + + +
    + +
    +
    +
    +
    +

    Topcoat

    +

    CSS for clean and fast web apps

    +
    + +
    +
    +
    +
    +
    +

    Button Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar > .topcoat-button-bar__item:first-child {
    +  border-top-left-radius: 6px;
    +  border-bottom-left-radius: 6px;
    +}
    +
    +.topcoat-button-bar > .topcoat-button-bar__item:last-child {
    +  border-top-right-radius: 6px;
    +  border-bottom-right-radius: 6px;
    +}
    +
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:first-child > .topcoat-button-bar__button--large {
    +  border-right: none;
    +}
    +
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button,
    +.topcoat-button-bar__item:last-child > .topcoat-button-bar__button--large {
    +  border-left: none;
    +}
    +
    +.topcoat-button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.topcoat-button-bar__button:focus,
    +.topcoat-button-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button Bar

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-button-bar">
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">One</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Two</button>
      </div>
      <div class="topcoat-button-bar__item">
        <button class="topcoat-button-bar__button--large">Three</button>
      </div>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button-bar__button--large {
    +  border-radius: inherit;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-button:disabled,
    +.topcoat-button--quiet:disabled,
    +.topcoat-button--large:disabled,
    +.topcoat-button--large--quiet:disabled,
    +.topcoat-button--cta:disabled,
    +.topcoat-button--large--cta:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Button

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button">Button</button>
    <button class="topcoat-button" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button,
    +.topcoat-button--quiet,
    +.topcoat-button--large,
    +.topcoat-button--large--quiet,
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  padding: 0 1.25rem;
    +  font-size: 16px;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: top;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 6px;
    +}
    +
    +.topcoat-button:hover,
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large:hover,
    +.topcoat-button--large--quiet:hover {
    +  background-color: #edf1f1;
    +}
    +
    +.topcoat-button:active,
    +.topcoat-button--large:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +.topcoat-button:focus,
    +.topcoat-button--quiet:focus,
    +.topcoat-button--large:focus,
    +.topcoat-button--large--quiet:focus,
    +.topcoat-button--cta:focus,
    +.topcoat-button--large--cta:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--quiet">Button</button>
    <button class="topcoat-button--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-button--quiet:hover,
    +.topcoat-button--large--quiet:hover {
    +  text-shadow: 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-button--quiet:active,
    +.topcoat-button--large--quiet:active {
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #d3d7d7;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large" >Button</button>
    <button class="topcoat-button--large" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large,
    +.topcoat-button--large--quiet {
    +  font-size: 1.3rem;
    +  font-weight: 400;
    +  line-height: 4.375rem;
    +  padding: 0 1.25rem;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--quiet" >Button</button>
    <button class="topcoat-button--large--quiet" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--cta" >Button</button>
    <button class="topcoat-button--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--cta,
    +.topcoat-button--large--cta {
    +  border: 1px solid #143250;
    +  background-color: #288edf;
    +  box-shadow: inset 0 1px rgba(255,255,255,0.36);
    +  color: #fff;
    +  font-weight: 500;
    +  text-shadow: 0 -1px rgba(0,0,0,0.36);
    +}
    +
    +.topcoat-button--cta:hover,
    +.topcoat-button--large--cta:hover {
    +  background-color: #509bef;
    +}
    +
    +.topcoat-button--cta:active,
    +.topcoat-button--large--cta:active {
    +  background-color: #0380e8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Call To Action Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-button--large--cta" >Button</button>
    <button class="topcoat-button--large--cta" disabled>Button</button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-button--large--cta {
    +  font-size: 1.3rem;
    +  font-weight: 400;
    +  line-height: 4.375rem;
    +  padding: 0 1.25rem;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="checkbox"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.checkbox,
    +.topcoat-checkbox__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox__label,
    +.topcoat-checkbox {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.checkbox--disabled,
    +input[type="checkbox"]:disabled + .topcoat-checkbox__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.checkbox:before,
    +.checkbox:after,
    +.topcoat-checkbox__checkmark:before,
    +.topcoat-checkbox__checkmark:after {
    +  content: '';
    +  position: absolute;
    +}
    +
    +.checkbox:before,
    +.topcoat-checkbox__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Checkbox

    +
    +


    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-checkbox">
      <input type="checkbox">
      <div class="topcoat-checkbox__checkmark"></div>
      Default
    </label>
    <br>
    <br>
    <label class="topcoat-checkbox">
      <input type="checkbox" disabled>
      <div class="topcoat-checkbox__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-checkbox__checkmark {
    +  height: 2rem;
    +}
    +
    +input[type="checkbox"] {
    +  height: 2rem;
    +  width: 2rem;
    +  margin-top: 0;
    +  margin-right: -2rem;
    +  margin-bottom: -2rem;
    +  margin-left: 0;
    +}
    +
    +input[type="checkbox"]:checked + .topcoat-checkbox__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-checkbox {
    +  line-height: 2rem;
    +}
    +
    +.topcoat-checkbox__checkmark:before {
    +  width: 2rem;
    +  height: 2rem;
    +  background: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 3px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-checkbox__checkmark {
    +  width: 2rem;
    +  height: 2rem;
    +}
    +
    +.topcoat-checkbox__checkmark:after {
    +  top: 1px;
    +  left: 2px;
    +  opacity: 0;
    +  width: 28px;
    +  height: 11px;
    +  background: transparent;
    +  border: 7px solid #666;
    +  border-width: 7px;
    +  border-top: none;
    +  border-right: none;
    +  border-radius: 2px;
    +  -webkit-transform: rotate(-50deg);
    +  -ms-transform: rotate(-50deg);
    +  transform: rotate(-50deg);
    +}
    +
    +input[type="checkbox"]:focus + .topcoat-checkbox__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-icon-button:disabled,
    +.topcoat-icon-button--quiet:disabled,
    +.topcoat-icon-button--large:disabled,
    +.topcoat-icon-button--large--quiet:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button,
    +.topcoat-icon-button--quiet,
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  padding: 0 0.75rem;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: baseline;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 6px;
    +}
    +
    +.topcoat-icon-button:hover,
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  background-color: #edf1f1;
    +}
    +
    +.topcoat-icon-button:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +.topcoat-icon-button:focus,
    +.topcoat-icon-button--quiet:focus,
    +.topcoat-icon-button--quiet:hover:focus,
    +.topcoat-icon-button--large:focus,
    +.topcoat-icon-button--large--quiet:focus,
    +.topcoat-icon-button--large--quiet:hover:focus {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +  outline: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--quiet">
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--quiet" disabled>
      <span class="topcoat-icon" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon-button--quiet:hover,
    +.topcoat-icon-button--large--quiet:hover {
    +  text-shadow: 0 1px #fff;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-icon-button--quiet:active,
    +.topcoat-icon-button--large--quiet:active {
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #d3d7d7;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large,
    +.topcoat-icon-button--large--quiet {
    +  width: 4.375rem;
    +  height: 4.375rem;
    +  line-height: 4.375rem;
    +}
    +
    +.topcoat-icon-button--large:active {
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Quiet Icon Button

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <button class="topcoat-icon-button--large--quiet">
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    <button class="topcoat-icon-button--large--quiet" disabled>
      <span class="topcoat-icon--large" style="background-color:#A5A7A7;"></span>
    </button>
    +
    +
    +

    CSS

    +
    
    +.topcoat-icon-button--large--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.topcoat-icon,
    +.topcoat-icon--large {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  overflow: hidden;
    +  width: 1.62rem;
    +  height: 1.62rem;
    +  vertical-align: middle;
    +  top: -1px;
    +}
    +
    +.topcoat-icon--large {
    +  width: 2.499999998125rem;
    +  height: 2.499999998125rem;
    +  top: -2px;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header {
    +  margin: 0;
    +}
    +
    +.list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.list,
    +.topcoat-list {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  overflow: auto;
    +  -webkit-overflow-scrolling: touch;
    +}
    +
    +.list__header,
    +.topcoat-list__header {
    +  margin: 0;
    +}
    +
    +.list__container,
    +.topcoat-list__container {
    +  padding: 0;
    +  margin: 0;
    +  list-style-type: none;
    +}
    +
    +.list__item,
    +.topcoat-list__item {
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    List

    +
    +

    Category

    • Item
    • Item
    • Item
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-list">
      <h3 class="topcoat-list__header">Category</h3>
      <ul class="topcoat-list__container">
        <li class="topcoat-list__item">
          Item
        </li>
        <li class="topcoat-list__item">
          Item
        </li>
        <li class="topcoat-list__item">
          Item
        </li>
      </ul>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-list {
    +  border-top: 1px solid #bcbfbf;
    +  border-bottom: 1px solid #eff1f1;
    +  background-color: #dfe2e2;
    +}
    +
    +.topcoat-list__header {
    +  padding: 4px 20px;
    +  font-size: 0.9em;
    +  font-weight: 400;
    +  background-color: #cccfcf;
    +  color: #656565;
    +  text-shadow: 0 1px 0 rgba(255,255,255,0.5);
    +  border-top: 1px solid rgba(255,255,255,0.5);
    +  border-bottom: 1px solid rgba(255,255,255,0.23);
    +}
    +
    +.topcoat-list__container {
    +  border-top: 1px solid #bcbfbf;
    +  color: #454545;
    +}
    +
    +.topcoat-list__item {
    +  padding: 1.25rem;
    +  border-top: 1px solid #eff1f1;
    +  border-bottom: 1px solid #bcbfbf;
    +}
    +
    +.topcoat-list__item:first-child {
    +  border-top: 1px solid rgba(0,0,0,0.05);
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.navigation-bar,
    +.topcoat-navigation-bar {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  word-spacing: 0;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.navigation-bar__item,
    +.topcoat-navigation-bar__item {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +}
    +
    +.navigation-bar__title,
    +.topcoat-navigation-bar__title {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +
    +
    +
    +
    + +
    +
    +

    Notification

    +
    +
    1
    +
    + +
    +
    +

    HTML

    +
    <span class="topcoat-notification">1</span>
    +
    +
    +

    CSS

    +
    
    +.topcoat-notification {
    +  padding: 0.15em 0.5em 0.2em;
    +  border-radius: 2px;
    +  background-color: #ec514e;
    +  color: #fff;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +input[type="radio"] {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.radio-button,
    +.topcoat-radio-button__checkmark {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button__label,
    +.topcoat-radio-button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.radio-button:before,
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:before,
    +.topcoat-radio-button__checkmark:after {
    +  content: '';
    +  position: absolute;
    +  border-radius: 100%;
    +}
    +
    +.radio-button:after,
    +.topcoat-radio-button__checkmark:after {
    +  top: 50%;
    +  left: 50%;
    +  -webkit-transform: translate(-50%, -50%);
    +  -ms-transform: translate(-50%, -50%);
    +  transform: translate(-50%, -50%);
    +}
    +
    +.radio-button:before,
    +.topcoat-radio-button__checkmark:before {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.radio-button--disabled,
    +input[type="radio"]:disabled + .topcoat-radio-button__checkmark {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Radio Button

    +
    +






    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <!-- NO LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- LEFT LABEL -->
    <label class="topcoat-radio-button">
      Left label
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
    </label>
    <br>
    <br>
    <!-- RIGHT LABEL -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat">
      <div class="topcoat-radio-button__checkmark"></div>
      Right label
    </label>
    <br>
    <br>
    <!-- DISABLED -->
    <label class="topcoat-radio-button">
      <input type="radio" name="topcoat" Disabled>
      <div class="topcoat-radio-button__checkmark"></div>
      Disabled
    </label>
    +
    +
    +

    CSS

    +
    
    +input[type="radio"] {
    +  height: 1.875rem;
    +  width: 1.875rem;
    +  margin-top: 0;
    +  margin-right: -1.875rem;
    +  margin-bottom: -1.875rem;
    +  margin-left: 0;
    +}
    +
    +input[type="radio"]:checked + .topcoat-radio-button__checkmark:after {
    +  opacity: 1;
    +}
    +
    +.topcoat-radio-button {
    +  color: #454545;
    +  line-height: 1.875rem;
    +}
    +
    +.topcoat-radio-button__checkmark:before {
    +  width: 1.875rem;
    +  height: 1.875rem;
    +  background: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-radio-button__checkmark {
    +  position: relative;
    +  width: 1.875rem;
    +  height: 1.875rem;
    +}
    +
    +.topcoat-radio-button__checkmark:after {
    +  opacity: 0;
    +  width: 0.875rem;
    +  height: 0.875rem;
    +  background: #666;
    +  border: 1px solid rgba(0,0,0,0.1);
    +  box-shadow: 0 1px rgba(255,255,255,0.5);
    +  -webkit-transform: none;
    +  -ms-transform: none;
    +  transform: none;
    +  top: 7px;
    +  left: 7px;
    +}
    +
    +input[type="radio"]:focus + .topcoat-radio-button__checkmark:before {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +/*
    +Copyright 2012 Adobe Systems Inc.;
    +Licensed under the Apache License, Version 2.0 (the "License");
    +you may not use this file except in compliance with the License.
    +You may obtain a copy of the License at
    +
    +http://www.apache.org/licenses/LICENSE-2.0
    +
    +Unless required by applicable law or agreed to in writing, software
    +distributed under the License is distributed on an "AS IS" BASIS,
    +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +See the License for the specific language governing permissions and
    +limitations under the License.
    +*/
    +
    +.range,
    +.topcoat-range {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +.range__thumb,
    +.topcoat-range::-moz-range-thumb {
    +  cursor: pointer;
    +}
    +
    +.range__thumb--webkit,
    +.topcoat-range::-webkit-slider-thumb {
    +  cursor: pointer;
    +  -webkit-appearance: none;
    +}
    +
    +.range:disabled,
    +.topcoat-range:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Range

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <input type="range" class="topcoat-range">
    <input type="range" class="topcoat-range" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-range {
    +  border-radius: 6px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  height: 1rem;
    +  border-radius: 30px;
    +}
    +
    +.topcoat-range::-moz-range-track {
    +  border-radius: 6px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  height: 1rem;
    +  border-radius: 30px;
    +}
    +
    +.topcoat-range::-webkit-slider-thumb {
    +  height: 3rem;
    +  width: 2rem;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 6px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-range::-moz-range-thumb {
    +  height: 3rem;
    +  width: 2rem;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 6px;
    +  box-shadow: inset 0 1px #fff;
    +}
    +
    +.topcoat-range:focus::-webkit-slider-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-range:focus::-moz-range-thumb {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.search-input,
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +  -webkit-appearance: none;
    +}
    +
    +input[type="search"]::-webkit-search-cancel-button {
    +  -webkit-appearance: none;
    +}
    +
    +.search-input:disabled,
    +.topcoat-search-input:disabled,
    +.topcoat-search-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input">
    <input type="search" value="" placeholder="search" class="topcoat-search-input" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input,
    +.topcoat-search-input--large {
    +  line-height: 3rem;
    +  font-size: 16px;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  padding: 0 0 0 2rem;
    +  border-radius: 30px;
    +  background-image: url("../img/search.svg");
    +  background-position: 1em center;
    +  background-repeat: no-repeat;
    +  background-size: 16px;
    +}
    +
    +.topcoat-search-input:focus,
    +.topcoat-search-input--large:focus {
    +  background-image: url("../img/search_dark.svg");
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-search-input::-webkit-search-cancel-button,
    +.topcoat-search-input::-webkit-search-decoration,
    +.topcoat-search-input--large::-webkit-search-cancel-button,
    +.topcoat-search-input--large::-webkit-search-decoration {
    +  margin-right: 5px;
    +}
    +
    +.topcoat-search-input:focus::-webkit-input-placeholder,
    +.topcoat-search-input:focus::-webkit-input-placeholder {
    +  color: #c6c8c8;
    +}
    +
    +.topcoat-search-input:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Search Input

    +
    +
    +
    + +
    +
    +

    HTML

    +
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large">
    <input type="search" value="" placeholder="search" class="topcoat-search-input--large" disabled>
    +
    +
    +

    CSS

    +
    
    +.topcoat-search-input--large {
    +  line-height: 4.375rem;
    +  font-size: 1.3rem;
    +  font-weight: 200;
    +  padding: 0 0 0 2.9rem;
    +  border-radius: 40px;
    +  background-position: 1.2em center;
    +  background-size: 1.3rem;
    +}
    +
    +.topcoat-search-input--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-search-input--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.switch,
    +.topcoat-switch {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch__input,
    +.topcoat-switch__input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.switch__toggle,
    +.topcoat-switch__toggle {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +}
    +
    +.switch__toggle:before,
    +.switch__toggle:after,
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  content: '';
    +  position: absolute;
    +  z-index: -1;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +}
    +
    +.switch--disabled,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Switch

    +
    +




    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input">
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" checked>
      <div class="topcoat-switch__toggle"></div>
    </label>
    <br>
    <br>
    <label class="topcoat-switch">
      <input type="checkbox" class="topcoat-switch__input" disabled>
      <div class="topcoat-switch__toggle"></div>
    </label>
    +
    +
    +

    CSS

    +
    
    +.topcoat-switch {
    +  font-size: 16px;
    +  padding: 0 1.25rem;
    +  border-radius: 6px;
    +  border: 1px solid #a5a8a8;
    +  overflow: hidden;
    +  width: 6rem;
    +}
    +
    +.topcoat-switch__toggle:before,
    +.topcoat-switch__toggle:after {
    +  top: -1px;
    +  width: 5rem;
    +}
    +
    +.topcoat-switch__toggle:before {
    +  content: 'ON';
    +  color: #0083e8;
    +  background-color: #e0f0fa;
    +  right: 1rem;
    +  padding-left: 1.5rem;
    +}
    +
    +.topcoat-switch__toggle {
    +  line-height: 3rem;
    +  height: 3rem;
    +  width: 2rem;
    +  border-radius: 6px;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  background-color: #e5e9e8;
    +  border: 1px solid #a5a8a8;
    +  margin-left: -1.3rem;
    +  margin-bottom: -1px;
    +  margin-top: -1px;
    +  box-shadow: inset 0 1px #fff;
    +  -webkit-transition: margin-left 0.05s ease-in-out;
    +  transition: margin-left 0.05s ease-in-out;
    +}
    +
    +.topcoat-switch__toggle:after {
    +  content: 'OFF';
    +  background-color: #d3d7d7;
    +  left: 1rem;
    +  padding-left: 2rem;
    +}
    +
    +.topcoat-switch__input:checked + .topcoat-switch__toggle {
    +  margin-left: 2.7rem;
    +}
    +
    +.topcoat-switch__input:focus + .topcoat-switch__toggle {
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:after,
    +.topcoat-switch__input:disabled + .topcoat-switch__toggle:before {
    +  background: transparent;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.button,
    +.topcoat-tab-bar__button {
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-decoration: none;
    +}
    +
    +.button--quiet {
    +  background: transparent;
    +  border: 1px solid transparent;
    +  box-shadow: none;
    +}
    +
    +.button--disabled,
    +.topcoat-tab-bar__button:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +.button-bar,
    +.topcoat-tab-bar {
    +  display: table;
    +  table-layout: fixed;
    +  white-space: nowrap;
    +  margin: 0;
    +  padding: 0;
    +}
    +
    +.button-bar__item,
    +.topcoat-tab-bar__item {
    +  display: table-cell;
    +  width: auto;
    +  border-radius: 0;
    +}
    +
    +.button-bar__item > input,
    +.topcoat-tab-bar__item > input {
    +  position: absolute;
    +  overflow: hidden;
    +  padding: 0;
    +  border: 0;
    +  opacity: 0.001;
    +  z-index: 1;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.button-bar__button {
    +  border-radius: inherit;
    +}
    +
    +.button-bar__item:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Tab Bar

    +
    +
    +
    +

    Examples

    + +
    +
    + +
    +
    +

    HTML

    +
    <div class="topcoat-tab-bar">
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">One</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Two</button>
      </label>
      <label class="topcoat-tab-bar__item">
        <input type="radio" name="tab-bar">
        <button class="topcoat-tab-bar__button">Three</button>
      </label>
    </div>
    +
    +
    +

    CSS

    +
    
    +.topcoat-tab-bar__button {
    +  padding: 0 1.25rem;
    +  height: 3rem;
    +  line-height: 3rem;
    +  letter-spacing: 1px;
    +  color: #454545;
    +  text-shadow: 0 1px #fff;
    +  vertical-align: top;
    +  background-color: #e5e9e8;
    +  box-shadow: inset 0 1px #fff;
    +  border-top: 1px solid #a5a8a8;
    +}
    +
    +.topcoat-tab-bar__button:active,
    +.topcoat-tab-bar__button--large:active,
    +:checked + .topcoat-tab-bar__button {
    +  color: #0083e8;
    +  background-color: #e0f0fa;
    +  box-shadow: inset 0 0 2px #c0ced8;
    +}
    +
    +.topcoat-tab-bar__button:focus,
    +.topcoat-tab-bar__button--large:focus {
    +  z-index: 1;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.input,
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  vertical-align: top;
    +  outline: none;
    +}
    +
    +.input:disabled,
    +.topcoat-text-input:disabled,
    +.topcoat-text-input--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Text input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input" placeholder="text" value="">
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input,
    +.topcoat-text-input--large {
    +  line-height: 3rem;
    +  font-size: 16px;
    +  letter-spacing: 1px;
    +  padding: 0 1.25rem;
    +  border: 1px solid #a5a8a8;
    +  border-radius: 6px;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  vertical-align: top;
    +}
    +
    +.topcoat-text-input:focus,
    +.topcoat-text-input--large:focus {
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-text-input:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Text Input

    +
    +




    +
    + +
    +
    +

    HTML

    +
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text">
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" value="" placeholder="text" disabled>
    <br>
    <br>
    <input type="text" class="topcoat-text-input--large" placeholder="text" value="fail" pattern="not-fail">
    +
    +
    +

    CSS

    +
    
    +.topcoat-text-input--large {
    +  line-height: 4.375rem;
    +  font-size: 1.3rem;
    +}
    +
    +.topcoat-text-input--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-text-input--large:invalid {
    +  border: 1px solid #d83b75;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +/**
    +*
    +* Copyright 2012 Adobe Systems Inc.;
    +*
    +* Licensed under the Apache License, Version 2.0 (the "License");
    +* you may not use this file except in compliance with the License.
    +* You may obtain a copy of the License at
    +*
    +* http://www.apache.org/licenses/LICENSE-2.0
    +*
    +* Unless required by applicable law or agreed to in writing, software
    +* distributed under the License is distributed on an "AS IS" BASIS,
    +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +* See the License for the specific language governing permissions and
    +* limitations under the License.
    +*
    +*/
    +
    +.textarea,
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  vertical-align: top;
    +  resize: none;
    +  outline: none;
    +}
    +
    +.textarea:disabled,
    +.topcoat-textarea:disabled,
    +.topcoat-textarea--large:disabled {
    +  opacity: 0.3;
    +  cursor: default;
    +  pointer-events: none;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea,
    +.topcoat-textarea--large {
    +  padding: 2rem;
    +  font-size: 2.5rem;
    +  font-weight: 200;
    +  border-radius: 6px;
    +  line-height: 3rem;
    +  border: 1px solid #a5a8a8;
    +  background-color: #d3d7d7;
    +  box-shadow: inset 0 1px rgba(0,0,0,0.12);
    +  color: #454545;
    +  letter-spacing: 1px;
    +}
    +
    +.topcoat-textarea:focus,
    +.topcoat-textarea--large:focus {
    +  background-color: #edf1f1;
    +  color: #000;
    +  border: 1px solid #0940fd;
    +  box-shadow: 0 0 0 2px #6fb5f1;
    +}
    +
    +.topcoat-textarea:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +
    +
    +
    +
    +
    +
    +

    Large Textarea

    +
    +


    +
    + +
    +
    +

    HTML

    +
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea"></textarea>
    <br>
    <br>
    <textarea class="topcoat-textarea--large" rows="6" cols="36" placeholder="Textarea" disabled></textarea>
    +
    +
    +

    CSS

    +
    
    +.topcoat-textarea--large {
    +  font-size: 3rem;
    +  line-height: 4.375rem;
    +}
    +
    +.topcoat-textarea--large:disabled {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled::-webkit-input-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled::-moz-placeholder {
    +  color: #000;
    +}
    +
    +.topcoat-textarea--large:disabled:-ms-input-placeholder {
    +  color: #000;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Regular.otf");
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Light.otf");
    +  font-weight: 200;
    +}
    +
    +@font-face {
    +  font-family: "Source Sans";
    +  src: url("../font/SourceSansPro-Semibold.otf");
    +  font-weight: 600;
    +}
    +
    +body {
    +  margin: 0;
    +  padding: 0;
    +  background: #dfe2e2;
    +  color: #000;
    +  font: 16px "Source Sans", helvetica, arial, sans-serif;
    +  font-weight: 200;
    +}
    +
    +:focus {
    +  outline-color: transparent;
    +  outline-style: none;
    +}
    +
    +.topcoat-icon--menu-stack {
    +  background: url("../img/hamburger_dark.svg") no-repeat;
    +  background-size: cover;
    +}
    +
    +.quarter {
    +  width: 25%;
    +}
    +
    +.half {
    +  width: 50%;
    +}
    +
    +.three-quarters {
    +  width: 75%;
    +}
    +
    +.third {
    +  width: 33.333%;
    +}
    +
    +.two-thirds {
    +  width: 66.666%;
    +}
    +
    +.full {
    +  width: 100%;
    +}
    +
    +.left {
    +  text-align: left;
    +}
    +
    +.center {
    +  text-align: center;
    +}
    +
    +.right {
    +  text-align: right;
    +}
    +
    +.reset-ui {
    +  -moz-box-sizing: border-box;
    +  box-sizing: border-box;
    +  background-clip: padding-box;
    +  position: relative;
    +  display: inline-block;
    +  vertical-align: top;
    +  padding: 0;
    +  margin: 0;
    +  font: inherit;
    +  color: inherit;
    +  background: transparent;
    +  border: none;
    +  cursor: default;
    +  -webkit-user-select: none;
    +  -moz-user-select: none;
    +  -ms-user-select: none;
    +  user-select: none;
    +  text-overflow: ellipsis;
    +  white-space: nowrap;
    +  overflow: hidden;
    +}
    +
    +/* This file should include color and image variables corresponding to the dark theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* Search Input */
    +
    +/* List */
    +
    +/* Checkbox */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Textarea */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* This file should include color and image variables corresponding to the light theme */
    +
    +/* Call To Action */
    +
    +/* Icons */
    +
    +/* Navigation Bar */
    +
    +/* Text Input */
    +
    +/* List */
    +
    +/* Overlay */
    +
    +/* Progress bar */
    +
    +/* Checkbox */
    +
    +/* Range input */
    +
    +/* Radio Button */
    +
    +/* Tab bar */
    +
    +/* Switch */
    +
    +/* Containers */
    +
    +/* Icon Button */
    +
    +/* Navigation bar */
    +
    +/* List */
    +
    +/* Search Input */
    +
    +/* Text Area */
    +
    +/* Checkbox */
    +
    +/* Radio */
    +
    +/* Range input */
    +
    +/* Search Input */
    +
    +/* Switch */
    +
    +/* Text Input */
    +
    +/* Radio input */
    +
    +/* Overlay */
    +
    +/* Textarea */
    +
    +/* Progress bar container */
    +
    +/* Progress bar progress */
    +
    +/* Search input */
    +
    +/* Switch */
    +
    +/* Notification */
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/build/styleguide.css b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/build/styleguide.css new file mode 100755 index 0000000..bcbf2a8 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/build/styleguide.css @@ -0,0 +1,495 @@ +/*! +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +/* Styleguide CSS here pls ------------------------------------------------------------------------------- */ + +html { + height: 100%; + width: 100%; + position: absolute; +} + +body { + color: #444; + font: 14px "source-sans-pro", "source", helvetica, arial, sans-serif; + line-height: 21px; + margin: 0; + padding: 0; + -webkit-font-smoothing: subpixel-antialiased; +} + +.guides { +/* border: 1px solid red;*/ +} + +.space { + height: 90px; +} + +#container { + min-width: 600px; +} + +#test-container { + padding: 0 120px 30px 30px ; +} + +h1,h2,h3,h4,h5,h6 { + color: #000; + font-family: "source-l", helvetica, arial, sans-serif; + font-weight: normal; + margin: 0; +} + +h4 { + border-bottom: 1px solid #d7d7d7; + font-size: 30px; + margin: 20px 0; +} + +h5 { + font-size: 21px; +} + +h4 span { + background: #fff; + padding: 0 7px 0 0; + position: relative; + bottom: -10px; +} + +.tabular { + border: 1px solid rgba(0,0,0,0.09); + border-spacing: 0; + margin: 14px 0; +} + +th, td, .tabular td.var { + border-bottom: 1px solid #eee; + font-size: 15px; + font-weight: normal; + padding: 5px 10px; + text-align: left; +} + +th { + white-space: nowrap; +} + +.tabular tr:last-child td { + border: none; +} + +.tabular td { + font-size: 12px; + padding: 10px; +} + +.images { + width: 100% !important; +} + +.images td, +.images th { + border-right: 1px solid #eee !important; + padding: 18px; + text-align: center; + vertical-align: top; +} + +.images th { + padding: 9px; +} + +.images tr:last-child td, +.images tr th:last-child { + border-right: none !important; +} + +.images img { + width: 300px; +} + +header { + background: #3a3f42 url("../img/bg_dark.png") repeat-x; + bottom: 0; + cursor: default; + left: 0; + overflow-y: scroll; + padding: 0 0 30px 0; + position: absolute; + top: 0; + width: 220px; +} + +#main { + bottom: 0; + left: 220px; + margin: 0; + overflow-y: scroll; + padding: 0 100px 60px 40px; + position: absolute; + right: 0; + top: 0; +} + +header hgroup { + padding: 15px; +} + +header hgroup { + border-bottom: 1px solid rgba(0,0,0,0.36); + box-shadow: 0px 1px 0px rgba(255,255,255,0.11); +} + +header h1 { + color: #fff; + font-size: 18px; + text-shadow: 0 -1px 0 #000; +} + +header h2 { + color: #c7c7c7; + font-size: 12px; + text-shadow: 0 -1px 0 #000; +} + +header h3 { + color: #A4B4B7; + font-size: 14px; + text-shadow: 0 -1px 0 #000; + margin: 15px 0 5px 15px; +} + +header ul { + list-style: none; + margin: 0; + padding: 0; + width: 100%; +} + +header a { + box-sizing: border-box; + border-top: 1px solid rgba(0,0,0,0); + border-bottom: 1px solid rgba(0,0,0,0); + color: #bbb; + display: block; + font-size: 14px; + height: 24px; + line-height: 24px; + padding: 0 15px 0 30px; + text-shadow: 0 1px 0 #000; +} + +header a:link, +header a:visited { + color: #c7c7c7; + text-decoration: none; +} + +header .selected { + background: rgba(112,112,112,0.24); + border-top: 1px solid rgba(0,0,0,0); + border-bottom: 1px solid rgba(0,0,0,0); + color: #fff !important; +} + + +header a:hover { + background: rgba(112,112,112,0.24); + border-top: 1px solid rgba(0,0,0,0); + border-bottom: 1px solid rgba(0,0,0,0); + color: #fff !important; +} + +header a:focus { + border: 1px solid #0940fd; + -webkit-box-shadow: 0 0 4px #0088ff; + box-shadow: 0 0 4px #0088ff; + outline: none; + margin-left: 4px; + margin-right: 4px; + padding: 0 10px 0 25px; + background: rgba(112,112,112,0.24); + color: #fff !important; +} + +header a:active { + background: rgba(0,0,0,0.24); + border-top: 1px solid rgba(0,0,0,0.2); + border-bottom: 1px solid rgba(255,255,255,0.15); + color: #fff; +} + +h4:target span { + -webkit-animation: highlight 5s ease; + -moz-animation: highlight 5s ease; +} + + @-webkit-keyframes highlight { + 0% { color: #0083E8; text-shadow: 0 0 4px rgba(0,136,255,.69); } + 100% { color: #000; text-shadow: none; } + } + +.preview { + border-spacing: 0; + width: auto; +} + +.preview td { + padding: 15px 30px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.bg-light { + background: #f8f8f8; + border: 1px solid rgba(0,0,0,0.09); + font-size: 12px; +} + +.fonts.tabular { + width: 100%; +} + +.fonts.tabular th.bg-white { + border-bottom: 1px solid rgba(0,0,0,0.09); +} + +.fonts.tabular th.bg-lightgray { + border-bottom: 1px solid #bdbdbd; +} + +.fonts.tabular th.bg-slategray { + border-bottom: 1px solid #5c6061; +} + +.fonts.tabular td { + vertical-align: top; + width: 33%; +} + + +/* Selection ------------------------------------------------------------------------------- */ + +::selection { + background: #e0f0fa; + color: #000; +} + +header { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +/* Scrollbars ------------------------------------------------------------------------------- */ + +::-webkit-scrollbar { + height: 8px; + width: 8px; +} + +::-webkit-scrollbar-track { + background: rgba(0,0,0,0.1); + box-shadow: inset 0 0 6px rgba(0,0,0,0); + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0); + border-radius: 4px; + -webkit-border-radius: 4px; +} + +::-webkit-scrollbar-thumb { + border-radius: 4px; + -webkit-border-radius: 4px; + border: 1px solid rgba(255,255,255,0.15); + background: rgba(0,0,0,0.3); + box-shadow: inset 0 0 6px rgba(0,0,0,0); + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0); +} + +::-webkit-scrollbar-thumb:window-inactive { + background: rgba(0,0,0,0.1); +} + + +/* Scrollbars ------------------------------------------------------------------------------- */ + + +/* Container */ +.modal { + /* Overlay page content */ + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0,0,0,0.6); + z-index: 10000; + + /* Transition opacity on open */ + -webkit-transition: opacity 200ms ease-in; + transition: opacity 200ms ease-in; + + /* Hide for now */ + opacity: 0; + pointer-events: none; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +/* Show modal */ +.modal:target { + opacity: 1; + pointer-events: auto; +} + +/* Hide modal */ +.modal:active { + opacity: 0; +} + +/* Content */ +.modal > div { + width: 65%; + background: #fff; + position: relative; + margin: 10% auto; + + /* Default minimise animation */ + -webkit-animation: minimise 500ms linear; + + /* Prettify */ + padding: 12px 15px; + border-radius: 4px; + box-shadow: 0 15px 36px rgba(0,0,0,0.6); + background: #fff; + text-shadow: 0 1px 0 #fff; +} + +/* Override animation on modal open */ +.modal:target > div { + -webkit-animation-name: bounce; + -moz-animation-name: bounce; +} + +.modal h1 { + font-size: 24px; + padding: 0 0 10px; +} + +@-webkit-keyframes bounce { + 0% { + -webkit-transform: scale3d(1,1,1); + } + 55% { + -webkit-transform: scale3d(1,1,1); + } + 100% { + -webkit-transform: scale3d(1,1,1); + } +/* 0% { + -webkit-transform: scale3d(0.1,0.1,1); + box-shadow: 0 3px 20px rgba(0,0,0,0.9); + } + 55% { + -webkit-transform: scale3d(1,1,1); + box-shadow: 0 10px 20px rgba(0,0,0,0); + } + 75% { + -webkit-transform: scale3d(0.95,0.95,1); + box-shadow: 0 0 20px rgba(0,0,0,0.9); + } + 100% { + -webkit-transform: scale3d(1,1,1); + box-shadow: 0 3px 20px rgba(0,0,0,0.9); + } +*/ +} + +@-webkit-keyframes minimise { + 0% { + -webkit-transform: scale3d(1,1,1); + } + 100% { + -webkit-transform: scale3d(0.1,0.1,1); + } +} + +/* Modal close link */ +.modal a[href="#close"] { + position: absolute; + right: 0; + top: 0; + color: transparent; +} + +/* Reset native styles */ + .modal a[href="#close"]:focus { + outline: none; +} + +/* Create close button */ +.modal a[href="#close"]:after { + content: url("../img/close_modal.png"); + display: block; + + /* Position */ + position: absolute; + right: 15px; + top: 15px; + + /* Style */ + font-size: 12px; + text-decoration: none; + text-shadow: none; + text-align: center; + font-weight: bold; + background: #fff; +} + +.modal a[href="#close"]:focus:after, +.modal a[href="#close"]:hover:after { + +} + +.modal a[href="#close"]:focus:after { + outline: 1px solid #000; +} + +.modal a[href="#close"] { + text-shadow: none !important; +} + +/* Open modal */ +a.openmodal { + display: block; + text-align: center; +} + +a.openmodal:hover, +a.openmodal:focus { + +} \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/build/styleguide.js b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/build/styleguide.js new file mode 100755 index 0000000..67f89bf --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/build/styleguide.js @@ -0,0 +1,10 @@ +if (!document.querySelector('override')) { + var head = document.querySelector('head'); + var link = document.createElement('link'); + link.id = 'override'; + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = '../../release/css/' + location.href.split('/').pop().split('.')[0] + '.css'; + link.media = 'all'; + head.appendChild(link); +} \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/tasks/checkchromiumsrc.js b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/tasks/checkchromiumsrc.js new file mode 100755 index 0000000..6c472dd --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/tasks/checkchromiumsrc.js @@ -0,0 +1,13 @@ +var chromiumSrc = process.env.CHROMIUM_SRC; + +module.exports = function(grunt) { + + grunt.registerTask('check_chromium_src', "Internal task to store CHROMIUM_SRC env var into chromiumSrc", function() { + if (!chromiumSrc) { + grunt.fail.warn("Please set the CHROMIUM_SRC env var to the root of your chromium sources(ends in /src)"); + } else { + grunt.log.writeln("CHROMIUM_SRC points to " + chromiumSrc.cyan); + } + }); + +} diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/tasks/telemetrygentest.js b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/tasks/telemetrygentest.js new file mode 100755 index 0000000..2b0bb0c --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/tasks/telemetrygentest.js @@ -0,0 +1,98 @@ +var fs = require("fs"), + jade = require("jade"), + path = require("path"); + +module.exports = function (grunt) { + + var TELEMETRY_DIR = 'dev/test/perf/telemetry/perf/page_sets/', + MASTER_JADE = 'topcoat_telemetry.jade'; + + grunt.registerTask('perf', 'Generates performance test', function (platform, theme) { + + var perfJades = findAllPerfJadeFileInSrc(); + + var targetPlatform = platform || 'mobile', + targetTheme = theme || 'light'; + + var targetCSS = prepareCSS(targetPlatform, targetTheme); + + var jadeCompileData = {}; + + grunt.util._.forEach(perfJades, function (jadePath) { + + var jadeFileName = path.basename(jadePath).split('.')[0]; + + prepareJadeCompileData(jadeCompileData, jadePath, + jadeFileName, targetPlatform, targetTheme, targetCSS); + + createTelemetryJSON(jadeFileName); + }); + batchCompileJade(jadeCompileData); + }); + + var findAllPerfJadeFileInSrc = function () { + + var jades = grunt.file.expand('node_modules/topcoat-*/test/perf/topcoat_*.jade') + .concat('node_modules/topcoat-checkbox/test/perf/checkbox-test.jade'); + + if (jades.length === 0){ + throw new Error("ERROR: No jade file is found in src/../test/perf/"); + } + + return jades; + }; + + var prepareCSS = function(platform, theme) { + + return "release/css/topcoat-" + platform + "-" + theme + ".min.css"; + }; + + var prepareJadeCompileData = function (jadeCompileData, jadePath, + caseName, platform, theme, css) { + + var jadeContent = fs.readFileSync(jadePath, "utf8"), + getHtml = jade.compile(jadeContent); + + jadeCompileData[caseName] = { + options: { + data: { + platform: platform, + theme: theme, + css: css, + name: caseName, + componentHTML: getHtml() + } + }, + src: TELEMETRY_DIR + "topcoat/" + MASTER_JADE, + dest: TELEMETRY_DIR + "topcoat/" + caseName + ".test.html" + }; + }; + + var createTelemetryJSON = function (caseName) { + + var jsonContent = { + "description": "Test", + "archive_data_file": "../data/topcoat_buttons.json", + "pages": [ + { + "url": "file:///topcoat/" + caseName + ".test.html", + "smoothness": { + "action": "scrolling_action" + } + } + ] + }; + + var jsonFilePATH = TELEMETRY_DIR + caseName + '.test.json'; + + fs.writeFileSync( + jsonFilePATH, + JSON.stringify(jsonContent, null, 4), + 'utf8'); + }; + + var batchCompileJade = function(data){ + grunt.config('jade', data); + grunt.task.run('jade'); + }; +}; diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/tasks/telemetrysubmit.js b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/tasks/telemetrysubmit.js new file mode 100755 index 0000000..f9f6fb2 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/tasks/telemetrysubmit.js @@ -0,0 +1,101 @@ +module.exports = function(grunt) { + + grunt.registerTask('telemetry-submit', 'Submit telemetry test results', function(gitCWD) { + + var exec = require("child_process").exec, + commandToBeExecuted = 'git log --pretty=format:"%H %ci" | head -n 1', + done = this.async(); + + var part1 = { + properties: { + path: { + message: 'Path to telemetry output file', + required: true + }, + device: { + message: 'Device on which the test ran', + required: true + } + } + }; + + var part2 = { + properties: { + test: { + message: 'What is the name of the test?', + required: true, + default: '' + }, + type: { + message: 'Is it a test (nightly) ?', + required: true, + default: 'Yes' + } + } + }; + + exec(commandToBeExecuted, { cwd: gitCWD }, function(error, stdout, stderr) { + if (error) { + grunt.log.error('Error'); + console.log(error); + done(); + } else { + + var path = grunt.option('path') + , device = grunt.option('device') + , test = grunt.option('test') + // use env variables to overwrite the location + // where the test results end up, for CI example + , host = process.env.TOPCOAT_BENCHMARK_SERVER + , port = process.env.TOPCOAT_BENCHMARK_PORT + , type = grunt.option('type') + , date = grunt.option('date') + , snapshot + , submitData = require('../test/perf/telemetry/lib/submitData') + , fileName = require('../test/perf/telemetry/lib/extractFileName') + , prompt = require('prompt') + ; + + if (!path || !test || !device) { + // Dummy test to see if it was called without arguments + // in this case we request the user for data + + prompt.start(); + prompt.get(part1, function (err, result) { + var options = result; + + part2.properties.test.default = fileName(result.path); + + prompt.get(part2, function (err, result) { + for (var i in result) + options[i] = result[i]; + + if (options.type.match(/y/gi)) + options.date = 'snapshot ' + new Date().toISOString(); + else + options.date = stdout; + + submitData(options.date, options.path, { + device: options.device, + test: options.test + }, { + host : host, + port : port + }); + }); + }); + } else { + // This is in case for automated tasks that submits the data + submitData(stdout, path, { + device: device, + test: test + }, { + host : host, + port : port + }); + } + } + }); + + }); +}; \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/README.md b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/README.md new file mode 100755 index 0000000..0fc795e --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/README.md @@ -0,0 +1,79 @@ +Performance tests based on chromium telemetry (see https://github.com/topcoat/topcoat/wiki/Measuring-performance for details) + +# Preparing to run the tests +A few steps are required before you can run the telemetry tests. + +First of all, you need to download chromium source code locally, as described on http://www.chromium.org/developers/how-tos/get-the-code. No need to compile, just download it. +Then export the location for the 'src' folder in the CHROMIUM_SRC environment variable, like in +``` +export CHROMIUM_SRC = /Users/cataling/work/chromium/home/src_tarball/tarball/chromium/src/ +``` + +Then you need to manually patch a little bit two of the benchmark files (the patches are just one liners, it they get bigger we'll just duplicate the benchmarks in topcoat). Locate the files named `loading_benchmark.py` and `smoothness_benchmark.py` in `$CHROMIUM_SRC/tools/perf/perf_tools`. Inside, look for the method `MeasurePage`, and find an appropriate place to paste `results.Add("UserAgent", "", tab.EvaluateJavaScript("navigator.userAgent"));`. This makes the benchmarks include the user agent string as part of their output, and we need this info to submit the results to the server. + +NOTE: we should make a patch for these modifications + +Next you can prepare the telemetry tests: +``` +grunt telemetry +``` +This does few things: +* it generates html snippets based on grunt template from test/perf/topcoat-*.test.jade of each of Topcoat component. So make sure you build Topcoat first, by ```grunt default```, so that Topcoat components are downloaded into the src folder; +* then it uses that html snippet to generate the actual test file from topcoat/test/perf /telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade; +* last, it copies those test files to the right location in chromium telemetry tests. + +# Running performance tests locally +You can run a telemetry test with: +``` +cd $CHROMIUM_SRC/tools/perf +./run_multipage_benchmarks --browser=system loading_benchmark page_sets/topcoat_buttons-base.test.json -o /tmp/loading_benchmark_topcoat_buttons-base.txt +./run_multipage_benchmarks --browser=system smoothness_benchmark page_sets/topcoat_buttons-base.test.json -o /tmp/smoothness_benchmark_topcoat_buttons-base.txt +``` +We store the benchmark output in a file - the next script will take this output and push it to the server + +For steps of running performance tests on Android: +https://github.com/topcoat/topcoat/wiki/Running-TopCoat-Performance-Test-on-Android + +# Pushing benchmark results to the server + +There is a grunt task that automates the process `$ grunt telemetry-submit --path=test_results.txt --type=sha|snapshot [--device] [--test]` + +Device is an optional parameter and sets the device on which the test ran. +For `type snapshot` you have to send in a date param as well. You have to use: `date -u +"%Y-%m-%dT%H:%M:%SZ"` + +Type is either `sha` or `snapshot`. + + * `sha` is for running the tests on a stable version (in black) + * `snapshot` is for running custom nightly builds of topcoat (in red) + * ![x axis perf view](http://i.imgur.com/DrKxFlI.png) + +Test is an optional parameter and it overrides the default test name ( which is the name of the file from path ). + +There is a `settings.js` file located under `/test/perf/telemetry/lib/` where you can change the address where to submit. It is currently set for http://bench.topcoat.io/v2/benchmark + +If you set an `TOPCOAT_BENCHMARK_SERVER` and `TOPCOAT_BENCHMARK_PORT` env variables you can override the default settings. + +You can view the results at http://bench.topcoat.io + +# Running all tests +There's also a handy script to run all the performance tests and push the results on the server. +It's located at `https://github.com/topcoat/topcoat/blob/master/test/perf/telemetry/bin/runAll.py`. +Check out the script for details on how to run it. + +# Adding a new performance test +Before adding new tests, you should make yourself comfortable with the chromium telemetry framework and running telemetry tests in chrome. + +Topcoat performance tests are located in `test/perf/telemetry/perf/page_sets` (the folder convention matches the one from chromium telemetry tests). When building telemetry with `grunt telemetry` this folder is copied over `page_sets` in chromium src. There is one .json file that describes each test, its structure is as required by chromium telemetry framework. You will need to add a new json file to describe your test - just start from an existing ones. + +The files for the tests are located under the `topcoat` folder. You can either add html file directly, or use jade. Jade files are converted to html when you run `grunt telemetry`. The html files will be generated under `page_sets` in chromium src. Currently, if you're adding a jade file you need to manually add it to `Gruntfile.js` (just look up where topcoat_buttons.jade is added). If future we'll get rid of this. + +Inside the test files (html or jade) you can reference the topcoat assets (css, fonts, images) under "./release/". The whole `./release` folder under topcoat root and all the components are copied there by `grunt telemetry`. + +In the json file you can reference the test file to load using `file:///topcoat/` URLs. Use .html here even if you use .jade for tests - you want to reference the generated html file, not the jade template. When running the tests, telemetry will instantiate a local HTTP server and rewrite the URLs, they will not be loaded with the file protocol. + +From telemetry we're currently using loading and smoothness benchmarks. The runAll.sh script currently runs these two benchmarks on all the .json tests under page_sets. + +Note 1: runAll.py uses CEF ([chromium embedding framework](https://code.google.com/p/chromiumembedded/)) to run the tests on desktop (Win and Mac) by default. This is because the target for TopCoat are web applications, not web sites, and CEF is the preferred way to develop web applications on desktop. +We're currently using a custom CEF build because telemetry does not work in CEF by default. A patch has been submitted to CEF upstream (https://code.google.com/p/chromiumembedded/issues/detail?id=917&sort=-id) to fix this. + +Note 2: part of this will probably change when we switch to the new components/themes architecture. diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.py b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.py new file mode 100755 index 0000000..3dd8aba --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.py @@ -0,0 +1,200 @@ +# Copyright 2012 Adobe Systems Inc.; +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Runs all the telemetry tests and pushes results to the server +# +# Make sure to run in from its folder! +# +# Env vars used: +# - TestHelper.CHROMIUM_SRC: path to chromium src +# - DEVICE_NAME: a label to identify the machine running the tests when submitting results +# - CEF_HOME: path to CEF binaries (needed only if USE_CEF is set to True) +# - USE_CEF: if run with CEF, set this to 'True' +# + +import os +import sys +import shutil +import subprocess +import glob +import platform +import shutil + + +class TestHelper(): + GRUNT = "grunt" + RESULTS_DIR = "/tmp/topcoat-telemetry" + BROWSER = "system" + BROWSER_EXEC = None + SUBMIT_TYPE = "SHA" + + CHROMIUM_SRC = os.environ.get("CHROMIUM_SRC") + DEVICE_NAME = os.environ.get("DEVICE_NAME") + CEF_HOME = os.environ.get("CEF_HOME") + USE_CEF = os.environ.get("USE_CEF") + + @staticmethod + def init(targetPlatform, targetTheme): + TestHelper._checkEnvVars() + TestHelper._prepareProperties() + TestHelper._prepareResultsDir() + TestHelper._cleanTelemetryTests() + TestHelper._prepareTelemetryTests(targetPlatform, targetTheme) + + @staticmethod + def _getPlatform(): + p = platform.platform().lower() + if p.find('windows') != -1: return "Win" + if p.find('darwin') != -1: return "Mac" + if p.find('linux') != -1: return "Lin" + + @staticmethod + def _checkEnvVars(): + if not TestHelper.DEVICE_NAME: + raise RuntimeError("Please set DEVICE_NAME env var (no spaces allowed yet)") + + if not TestHelper.CHROMIUM_SRC: + raise RuntimeError("Please set CHROMIUM_SRC env var.") + + if not TestHelper.USE_CEF: + raise RuntimeError("Please set USE_CEF env var.") + + if (TestHelper.USE_CEF == 'True') and (not TestHelper.CEF_HOME): + raise RuntimeError("Please set CEF_HOME if you set USE_CEF to True") + + @staticmethod + def _prepareProperties(): + p = TestHelper._getPlatform() + + if p == "Win": + TestHelper.GRUNT = "grunt.cmd" + TestHelper.RESULTS_DIR = "C:\\tmp\\topcoat-telemetry" + TestHelper.BROWSER = "exact" + TestHelper.BROWSER_EXEC = "%s\\app\\cefclient.exe" % TestHelper.CEF_HOME + + if p == "Mac": + if TestHelper.USE_CEF: + TestHelper.BROWSER = "exact" + TestHelper.BROWSER_EXEC = "%s/app/cefclient.app/Contents/MacOS/cefclient" % TestHelper.CEF_HOME + + if p == "Lin": + TestHelper.BROWSER = "android-chrome-beta" + + @staticmethod + def _prepareResultsDir(): + print "runAll.py: Preparing results dir %s" % TestHelper.RESULTS_DIR + if os.path.isdir(TestHelper.RESULTS_DIR): + shutil.rmtree(TestHelper.RESULTS_DIR) + os.makedirs(TestHelper.RESULTS_DIR) + + @staticmethod + def _prepareTelemetryTests(targetPlatform, targetTheme): + print "runAll.py: Preparing telemetry tests" + subprocess.check_call([TestHelper.GRUNT, 'telemetry:'+targetPlatform+':'+targetTheme]) + + @staticmethod + def _cleanTelemetryTests(): + print "runAll.py: clean up CHROMIUM_SRC/tools/perf/page_sets/topcoat" + path = TestHelper.CHROMIUM_SRC + "tools/perf/page_sets/topcoat" + if os.path.exists(path): + shutil.rmtree(path) + + @staticmethod + def runTests(user_defined_test_list, how_many_rounds_to_run_the_test): + print "runAll.py: Running telemetry tests, results in %s" % TestHelper.RESULTS_DIR + + telemetry_tests = ["loading_benchmark", "smoothness_benchmark"] + + if user_defined_test_list and len(user_defined_test_list) != 0: + topcoat_test_files = user_defined_test_list + else: + topcoat_test_files = glob.glob(os.getcwd() + "/../perf/page_sets/*.json") + + def genCmd(): + cmd = [ + "python", + TestHelper.CHROMIUM_SRC + "/tools/perf/run_multipage_benchmarks", + "--browser=" + TestHelper.BROWSER, + telemetry_test, + TestHelper.CHROMIUM_SRC + "tools/perf/page_sets/%s" % topcoat_test_file, + "-o", TestHelper.RESULTS_DIR + "/%s_%s-%s.txt" % (telemetry_test, topcoat_test_name, test_round) + ] + if TestHelper.BROWSER_EXEC: + cmd.insert(3, "--browser-executable=" + TestHelper.BROWSER_EXEC) + return cmd + + for tf in topcoat_test_files: + topcoat_test_file = tf.split(os.sep)[-1] + topcoat_test_name = topcoat_test_file.split(".")[0] + print "runAll.py: Running tests for %s" % topcoat_test_name + + for telemetry_test in telemetry_tests: + for test_round in range(how_many_rounds_to_run_the_test): + cmd = genCmd() + subprocess.check_call(cmd) + + @staticmethod + def submitResults(git_cwd): + print "runAll.py: Pushing telemetry data to the server" + result_files = glob.glob(TestHelper.RESULTS_DIR + "/*.txt") + for rf in result_files: + subprocess.check_call([ + TestHelper.GRUNT, + "telemetry-submit:" + git_cwd, + "--path=" + rf, + "--device=" + TestHelper.DEVICE_NAME, + "--test=" + rf.split(os.sep)[-1][:-6], + "--type=" + TestHelper.SUBMIT_TYPE + ]) + + +if __name__ == "__main__": + + # Usage: + # ./python runAll.py --platform=VALUE --theme=VALUE [--gitCWD=VALUE] [--test=VALUE] [--round=VALUE] + # --platform= desktop or mobile + # --theme= light or dark + # [optional] --gitCWD=PATH_WHERE_YOU_WANT_TO_RUN_GIT_LOG, e.g. src/skins/button + # [optional] --test=ONE_OR_MORE_TESTS_YOU_WANT_TO_RUN, e.g. topcoat_button.test.json + # [optional] --test=HOW_MANY_ROUNDS_TO_RUN_THE_TEST, default is 1. + + platfrm = theme = git_cwd = test_list = None + test_round = 1 + + args = sys.argv[1:] + + for arg in args: + arg_key, arg_val = arg.split('=') + if arg_key == '--platform': + platfrm = arg_val + elif arg_key == '--theme': + theme = arg_val + elif arg_key == '--gitCWD': + git_cwd = arg_val + elif arg_key == '--test': + test_list = arg_val.split(',') + elif arg_key == '--round': + test_round = int(arg_val) + else: + print "%s is not recognized." + + if not platform or not theme: + raise RuntimeError("ERROR: --platform and --theme must be set.") + + if not git_cwd: + git_cwd = '' + + TestHelper.init(platfrm, theme) + TestHelper.runTests(test_list, test_round) + TestHelper.submitResults(git_cwd) \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.sh b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.sh new file mode 100755 index 0000000..aa088c0 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/bin/runAll.sh @@ -0,0 +1,105 @@ +#!/bin/sh +# Copyright 2012 Adobe Systems Inc.; +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Runs all the telemetry tests and pushes results to the server +# +# Make sure to run in from its folder! +# +# Env vars used: +# - CHROMIUM_SRC: path to chromium src +# - DEVICE_NAME: a label to identify the machine running the tests when submitting results +# - CEF_HOME: path to CEF binaries (needed only if USE_CEF is set to True) +# + +RESULTS_DIR=/tmp/topcoat-telemetry +USE_CEF=true + +function checkEnvVars() { + if [ -z "$DEVICE_NAME" ] + then + echo "Please set DEVICE_NAME env var (no spaces allowed yet)" + exit 1 + fi + + if [ -z "$CHROMIUM_SRC" ] + then + echo "Please set CHROMIUM_SRC env var" + exit 1 + fi + + if ($USE_CEF) + then + if [ -z "$CEF_HOME" ] + then + echo "You need to set CEF_HOME if yout set USE_CEF to True" + exit 1 + fi + fi +} + +function prepareResultsDir() { + echo "runAll.sh: Preparing results dir $RESULTS_DIR" + rm -rf $RESULTS_DIR + mkdir $RESULTS_DIR +} + +function prepareTelemetryTests() { + echo "runAll.sh: Preparing telemetry tests" + grunt telemetry +} + +function runTests() { + echo "runAll.sh: Running telemetry tests, resuls in $RESULTS_DIR" + + if ($USE_CEF) + then + browserParams="--browser=exact --browser-executable=$CEF_HOME/app/cefclient.app/Contents/MacOS/cefclient" + else + browserParams="--browser=system" + fi + + testFiles=$(ls ../perf/page_sets/*.json); + + currentDir=`pwd` + cd $CHROMIUM_SRC/tools/perf + + for test in $testFiles + do + testFileBaseName=$(basename $test) #ends with .json + testName=$(echo $testFileBaseName | cut -d '.' -f 1) + echo "runAll.sh: Running tests for $testName" + ./run_multipage_benchmarks $browserParams loading_benchmark page_sets/$testFileBaseName -o $RESULTS_DIR/loading_benchmark_$testName.txt + ./run_multipage_benchmarks $browserParams smoothness_benchmark page_sets/$testFileBaseName -o $RESULTS_DIR/smoothness_benchmark_$testName.txt + done + + cd $currentDir +} + +function submitResults() { + echo "runAll.sh: Pushing telemetry data to the server" + + for resultFile in $RESULTS_DIR/* + do + grunt telemetry-submit --path=$resultFile --device $DEVICE_NAME + done +} + + +checkEnvVars +prepareResultsDir +prepareTelemetryTests +runTests +submitResults + diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/csvToJSON.js b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/csvToJSON.js new file mode 100755 index 0000000..b5d0594 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/csvToJSON.js @@ -0,0 +1,56 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +"use strict"; + +var parseCSV = function(file, cb) { + + var fs = require('fs') + , filename = file + , csv = require('csv') + ; + + var header = []; + var values = []; + var json = {}; + + csv() + .from.stream(fs.createReadStream(file)) + .transform(function(row, index){ + //in case there are blank lines in between key & value on Win7 + if (row[0] == ""){ + return null; + }else{ + return row; + } + }) + .on('record', function(row,index){ + if (index === 0) + header.push(row); + else + values.push(row); + }) + .on('end', function(count){ + header[0].forEach(function (h, idx) { + json[h] = values[0][idx]; + }); + cb(json); + }) + .on('error', function(error){ + console.log(error.message); + }); +}; + +module.exports = parseCSV; \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/extractFileName.js b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/extractFileName.js new file mode 100755 index 0000000..f3446e5 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/extractFileName.js @@ -0,0 +1,12 @@ +var extractFileName = function (path) { + if (path.split('/').length > 1) { + sep = '/'; + } else if (path.split('\\').length > 1) { + sep = '\\'; + } else { + throw new Error('ERROR: the separator in test result file path is neither "/" nor "\\".'); + } + return path.split(sep).pop().split('.')[0]; +}; + +module.exports = extractFileName; \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/settings.js b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/settings.js new file mode 100755 index 0000000..b701064 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/settings.js @@ -0,0 +1,31 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +function settings (contentLength) { + var post_options = { + host: 'localhost', + port: '3000', + path: '/v2/benchmark', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': contentLength + } + }; + + return post_options; +} + +module.exports = settings; diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/submitData.js b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/submitData.js new file mode 100755 index 0000000..d3f732d --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/lib/submitData.js @@ -0,0 +1,61 @@ +/* +Copyright 2012 Adobe Systems Inc.; +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +var submitData = function (stdout, path, args, destination) { + var querystring = require('querystring'); + var http = require('http'); + var fs = require('fs'); + var parse = require('./csvToJSON'); + var postOptions = require('./settings'); + var fileName = require('./extractFileName.js'); + + var post_data = {}; + console.log(path); + parse(path, function (j) { + post_data = { + resultName : j + }; + + var version = stdout.split(' '); + + post_data.commit = version.shift(); + post_data.date = version.join(' '); + post_data.test = args.test || fileName(path); + post_data.device = args.device || 'device?'; + post_data = querystring.stringify({data : JSON.stringify(post_data)}); + post_options = postOptions(post_data.length); + if (destination.host && destination.port) { + var location = destination.host.split('/'); + + post_options.host = location.shift(); + post_options.port = destination.port; + } + // Set up the request + var post_req = http.request(post_options, function(res) { + res.setEncoding('utf8'); + res.on('data', function(chunk) { + console.log(chunk); + }); + }); + + // post the data + post_req.write(post_data); + post_req.end(); + + }); + +}; + +module.exports = submitData; \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade new file mode 100755 index 0000000..c38b00f --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/dev/test/perf/telemetry/perf/page_sets/topcoat/topcoat_telemetry.jade @@ -0,0 +1,17 @@ +repeats = 200 + +doctype 5 +html + head + meta(charset="utf-8") + meta(name="format-detection", content="telephone=no") + meta(name="viewport", content="user-scalable=no, initial-scale=1, maximum-scale=1, width=device-width, height=device-width, target-densitydpi=device-dpi") + + title #{name} test + | + + body + -while (repeats > 0) + -var repeats = repeats - 1 + p + | !{componentHTML} diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/LICENSE.txt b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/LICENSE.txt new file mode 100755 index 0000000..d154618 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Black.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Black.otf new file mode 100755 index 0000000..ba47f3d Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Black.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Bold.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Bold.otf new file mode 100755 index 0000000..b8a2f57 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Bold.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-ExtraLight.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-ExtraLight.otf new file mode 100755 index 0000000..5cb8e5f Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-ExtraLight.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Light.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Light.otf new file mode 100755 index 0000000..e3c0a74 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Light.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Regular.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Regular.otf new file mode 100755 index 0000000..40208be Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Regular.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Semibold.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Semibold.otf new file mode 100755 index 0000000..65b82d1 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceCodePro-Semibold.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Black.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Black.otf new file mode 100755 index 0000000..13338c2 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Black.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-BlackIt.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-BlackIt.otf new file mode 100755 index 0000000..f5a7490 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-BlackIt.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Bold.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Bold.otf new file mode 100755 index 0000000..8998f3d Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Bold.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-BoldIt.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-BoldIt.otf new file mode 100755 index 0000000..071d0c3 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-BoldIt.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-ExtraLight.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-ExtraLight.otf new file mode 100755 index 0000000..43e0c69 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-ExtraLight.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-ExtraLightIt.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-ExtraLightIt.otf new file mode 100755 index 0000000..01ac876 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-ExtraLightIt.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-It.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-It.otf new file mode 100755 index 0000000..51577d6 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-It.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Light.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Light.otf new file mode 100755 index 0000000..9d8fb28 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Light.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-LightIt.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-LightIt.otf new file mode 100755 index 0000000..e03c41c Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-LightIt.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Regular.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Regular.otf new file mode 100755 index 0000000..7b6fa55 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Regular.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Semibold.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Semibold.otf new file mode 100755 index 0000000..6b39aa4 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-Semibold.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-SemiboldIt.otf b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-SemiboldIt.otf new file mode 100755 index 0000000..8a668e4 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/font/SourceSansPro-SemiboldIt.otf differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/avatar.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/avatar.png new file mode 100755 index 0000000..c3a1306 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/avatar.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/bg_dark.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/bg_dark.png new file mode 100755 index 0000000..e44a7c4 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/bg_dark.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/breadcrumb.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/breadcrumb.png new file mode 100755 index 0000000..b2cf4f3 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/breadcrumb.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_checked.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_checked.png new file mode 100755 index 0000000..daaa1a8 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_checked.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_checked_dark.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_checked_dark.png new file mode 100755 index 0000000..777ddcf Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_checked_dark.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_unchecked.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_unchecked.png new file mode 100755 index 0000000..4ef08dd Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_unchecked.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_unchecked_dark.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_unchecked_dark.png new file mode 100755 index 0000000..3f5e6c9 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkbox_unchecked_dark.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkmark_bw.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkmark_bw.svg new file mode 100755 index 0000000..f737096 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/checkmark_bw.svg @@ -0,0 +1,15 @@ + + + + + + +]> + + + diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-combo-box-bg.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-combo-box-bg.png new file mode 100755 index 0000000..9a4e92d Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-combo-box-bg.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-combo-box-bg2x.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-combo-box-bg2x.png new file mode 100755 index 0000000..7ab0c5a Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-combo-box-bg2x.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-grips.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-grips.png new file mode 100755 index 0000000..c52325d Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-grips.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-sprites2x.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-sprites2x.png new file mode 100755 index 0000000..f9a875b Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dark-sprites2x.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dialog-zone-bg.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dialog-zone-bg.png new file mode 100755 index 0000000..6dd0ff8 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/dialog-zone-bg.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/drop-down-triangle-dark.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/drop-down-triangle-dark.png new file mode 100755 index 0000000..9af2042 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/drop-down-triangle-dark.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/drop-down-triangle.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/drop-down-triangle.png new file mode 100755 index 0000000..cb1c968 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/drop-down-triangle.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/hamburger_bw.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/hamburger_bw.svg new file mode 100755 index 0000000..c08ff01 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/hamburger_bw.svg @@ -0,0 +1,1912 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + eJzsvemOJMmRJvgE9g6+PxogB1NBU1PTw7iDBcLj6OEM2V0g2ceiMSgks6LJnM6jkJVFLvfpV75P +RFTV3D2yIo8iie0KrcoIF1dTM9NDVI5PRP/u//jyN19cf/3mdw9fxKv5MP3d3928fXj27s3bnx9I +Pfzi5cvvvn33FqSf/Pqnh5CvZql0/Yv6lVX854e337548/rn/Ooqypf3uPonv/j22e8eXr58OPzy +2euv3/3h2cuHtz89/OSn8v1vX7x7+SA1/vDs1e++e/v7h7dX3/7x9z/1W0tbt8/eyffrz5afhXhY +fj7Hw5e/wtfPXv/x2bffvvh/H3CzWHGv45vvXn/94vXvj2/+HyEevojrIW6HL4p89d9f/Prh2/d8 +f/vm+XevHl6/+/Ltm+cP33578+blm7ff/vxw8+dnrw+/evZ7+ebZ4f+WN3jzp8Px5bPn/zHJW6ev +7l+8fJAXfPXs3SEs6IvrX4Tlq+N3L15+/Q/fvfrdg7x63kiOX7HJf/pW2pJm8TfI5atfvBLKbx7e +vZPnkhuiP3/998fxMYTI8pN/+/XD71+w+6Vb/tdPrdm3b7559eztf+DawxfrfJD/7I6/fXj1zUvp +Pb7uMl+lwxf8t/9p9eQtWOeLJVfplZIPca6HmKp+3/vm4Y8vHv7088M/vHn9oB1w/fbdb3QI1nWe +9V/95tffyRj/0+sX7+TBMkib9sCv3nz98FLqt+vvXz7ji7OE/q9W+O0zmRPvZOzevPzuHWdW9TtI +D//y2Z8fMExBb/CP3zy8/u2bf+YzfrEEaWfZrrbDssobhWVbD6Gy/QWPus3tnqH/q02jITTj7WOG +fCnj9I9vX/z+xeuffxGr9HVcZh3Cv3/74us+guFQ7X9p/KoO/2/+vz6tvPi7dw+v7ell3tz8apgH +89WvfiN3vXv99c2bV+j9bzHBZQK8lrnx8s3v9bv2N7+Ry7/7Rt+An7+Sgfry7YvXaHP6B35Tv/ry +5Xfy1d+/ffPdN794/e9vpp/o0v7nh+eyfmUsvz784+/+t3yQ9cm5efjt22fPpQH53OpcPXvxzU/f +25y83NuHg34pV/Kj//7+q28f/l1WVb9cqXev//jw8s03Q7ONIlzl8C/P3n7z/U1/+fLZ62dvD6S3 +ln/54o/yzTPpqd52pz2hUZkl30jn8BJWObnBeyoMXz3hRs/e/UEY0MPrr79tbevH/YMr7fvb+81z +zMG3h+Pb7779w+G3b968bM3uv2qtG5lU1P/buMeXvOD1P77WDjq/k1U4vZPwn7+5u0jtx+8gX/4t +t37z7OXLF79/++ybP7x4fukGF75vd9LvPmRi/fnV7968fPHtqz6fBsqXz96+e/H85cNv/vztu4dX +Tx7cw93XL4TJPbKM31vnN3969u75H3754ndvn7198fDe1YcB+PcXr7+Wuf+b7168e+gd9ObVN5BS +Dr/5w7NvHvga7/5wz5q/aQ2mr4T1j8z9iy/ew/VDPhxfD9///dtnX7+QDUWErr9/8/Lrh9eHX4O9 +T7tPsn2Vw/Hr6d+m2UpgWQ9/99Xx7fTfpvn0J5yUZSjRymol8X8vGf9P8msspZU6b7tyPZSjlBsr +t0O5m++n+d7L7sHGn2UocSjrriQtE3+VkKUU/q5D2XblOhxbuWnlGG6l+KfbST7ckXQb7scydh0f +zn/iUNahpCWjTPprKUOpyyZF/70eylHL9H9dGsvHRjPuxnMdRrWPrZSpDe86DLKO6ji6VQp+Y1Tr +bny3YYTl38mG2gf72IZZf2OU78bRln/1Z7441su0G+go44rfGFmMcWapHOVyMsLXVvZjK2OJX3cs +tyej6DeNHMM+Zig6SD5kmw2WDNBkY4SxurFyy3Jn5R7FVxZeZhzLwFFareMrO/TIRXLPvln48pmv +t/FVbvnEwZ4wc8rII0y8L+6zxBjXmGMRZWuLRym38V5GO6xxXde0lrWu23q9Htfb9W69l45cUkxr +yqmkLV2nY7pJd+l+kgcKMkvXnHLONW/5Oh/zTb7N9zIXgnTDWlLJpZatHMtNuS33Mk9CXepaU821 +1K1e12O9rXf1XubLMm1xWzdpZ6vbth23m+1uu5dJE67j9XqdrvN1vd6ur6+PUm6ub6/vOJMWeYH1 +mI7lWI+bfHU83hzvjvcyu8LE3o436026kQe42W6ub443Nze3N/cy2QJHYb1Nt/lWHu623m63x9ub +27vb+7tZxiXerXf5rtzVu+1O7nV3c3c73d3d3WNG3EuH3ad7edN7efb7aylyy3u58v7kR8ZyltFs +n++GcjuUm6Ecd+V6KJuXSf6pQylDybuShrIOJQ5FJuB0v7QysrDOfOfx0e/Gn9tdudEy8ddxKNdD +2XalDqUMJQ8lTXeplXVX4lCWoYShzGPRLp+s78enH39uhnLUwpW5G8f96O3HzEdrP0T7YZGhmIbR +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 + + + diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/hamburger_dark.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/hamburger_dark.svg new file mode 100755 index 0000000..e698e19 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/hamburger_dark.svg @@ -0,0 +1,1935 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + eJzsvemSJLmRJvgE9g6+P1qEHJkKGgCDAcYdWZHwOHo4Q3aXkOxjpWWkJJkVTeZ0HiVZWeRyn371 ++1QVgLl7ZEUeRVK2K1CVEa4Og5nhUOjxqeLv/o8vf/PF9ddvfvfwRbqaD9Pf/d3N24dn7968/fmB +1MMvXr787tt3b0H6ya9/egjr1SyVrn9Rv7KK//zw9tsXb17/nF9dJfnyHlf/5BffPvvdw8uXD4df +Pnv99bs/PHv58Panh5/8VL7/7Yt3Lx+kxh+evfrdd29///D26ts//v6nfmtp6/bZO/l++Vn8WUiH ++PM5Hr78Fb5+9vqPz7799sX/+4CbpYp7Hd989/rrF69/f3zz/wjx8EXKh7Qdvijy1X9/8euHb9/z +/e2b59+9enj97su3b54/fPvtzZuXb95++/PDzZ+fvT786tnv5Ztnh/9b3uDNnw7Hl8+e/8ckb52/ +un/x8kFe8NWzd4cQ0RfXvwjxq+N3L15+/Q/fvfrdg7z6upGcvmKT//SttCXN4m+Qy1e/eCWU3zy8 +eyfPJTdEf/7674/jYwiR5Sf/9uuH379g90u3/K+fWrNv33zz6tnb/8C1hy+W+SD/2R1/+/Dqm5fS +e3zdOF/lwxf8t/9p9eQtWOeLuFbplbIe0lwPKVf9vvfNwx9fPPzp54d/ePP6QTvg+u273+gQLMs8 +67/6za+/kzH+p9cv3smDrSBt2gO/evP1w0up366/f/mML84S+r9a4bfPZE68k7F78/K7d5xZ1e8g +PfzLZ39+wDAFvcE/fvPw+rdv/pnP+EUM0k7crrZDXOSNQtyWQ6hsP+JRt7ndM/R/tWk0hGa8fcyQ +L2Wc/vHti9+/eP3zL1KVvk5x1iH8+7cvvu4jGA7V/pfGr+rw/+b/69PKi7979/Danl7mzc2vhnkw +X/3qN3LXu9df37x5hd7/FhNcJsBrmRsv3/xev2t/8xu5/Ltv9A34+SsZqC/fvniNNqd/4Df1qy9f +fidf/f3bN99984vX//5m+oku7X9+eC7rV8by68M//u5/ywdZn5ybh9++ffZcGpDPrc7Vsxff/PS9 +zcnLvX046JdyJT/67++/+vbh32VV9cuVevf6jw8v33wzNNsowlUO//Ls7Tff3/SXL5+9fvb2QHpr ++Zcv/ijfPJOe6m132hMalVnyjXQOL2GVkxu8p8Lw1RNu9OzdH4QBPbz++tvWtn7cP7jSvr+93zzH +HHx7OL797ts/HH775s3L1uz+q9a6kUlF/b+Ne3zJC17/42vtoPM7WYXTOwn/+Zu7i9R+/A7y5d9y +6zfPXr588fu3z775w4vnl25w4ft2J/3uQybWn1/97s3LF9++6vNpoHz57O27F89fPvzmz9++e3j1 +5ME93H39QpjcI8v4vXV+86dn757/4Zcvfvf22dsXD+9dfRiAf3/x+muZ+7/57sW7h95Bb159Aynl +8Js/PPvmga/x7g/3rPmb1mD+Slj/yNy/+OI9XD+sh+Pr4fu/f/vs6xeyoYjQ9fdvXn798Prwa7D3 +afdJtq9yOH49/ds0Wwksy+Hvvjq+nf7bNJ/+hJMSh5KsLFYy//ey4v9Jfo2ltFLnbVeuh3KUcmPl +dih38/0033vZPdj4E4eShrLsStYy8VcJq5TC33Uo265ch2MrN60cw60U/3Q7yYc7km7D/VjGruPD ++U8ayjKUHFeUSX/FMpQaNyn67/VQjlqm/+vSWD42mmk3nsswqn1spUxteJdhkHVUx9GtUvAbo1p3 +47sNIyz/TjbUPtjHNsz6G6N8N462/Ks/88WxjtNuoJOMK35jZDHGK0vlKJeTEb62sh9bGUv8umO5 +PRlFv2niGPYxQ9FB8iHbbLBkgCYbI4zVjZVbljsr9yi+svAy41gGjtJiHV/ZoUcuknv2TeTLr3y9 +ja9yyycO9oQrp4w8wsT74j4xpbSkNRVRtrZ0lHKb7mW0w5KWZclLWeqyLdfLcbld7pZ76ciYU17y +mkve8nU+5pt8l+8neaAgs3RZ87qudd3W6/W43qy3673MhSDdsJRc1lLLVo7lptyWe5knoca61FzX +WupWr+ux3ta7ei/zJU5b2pZN2tnqtm3H7Wa72+5l0oTrdL1c5+v1ul5v19fXRyk317fXd5xJUV5g +OeZjOdbjJl8djzfHu+O9zK4wsbfTzXKTb+QBbrab65vjzc3N7c29TLbAUVhu8+16Kw93W2+32+Pt +ze3d7f3dLOOS7pa79a7c1bvtTu51d3N3O93d3d1jRtxLh93ne3nTe3n2+2spcst7ufL+5EfGcpbR +bJ/vhnI7lJuhHHfleiibl0n+qUMpQ1l3JQ9lGUoaikzA6T62MrKwznzn8dHvxp/bXbnRMvHXcSjX +Q9l2pQ6lDGUdSp7ucivLrqShxKGEocxj0S6frO/Hpx9/boZy1MKVuRvH/ejtx8xHaz9E+2GRoZiG +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 +5+8WHNujgn37Jvf02foBF49O17EtRgdL6PPOr2X3eTnApGRT1pjj5tvyKZydOhfd8sG4HeMKh/VO +7013OIJF5f3+3OsnvTc1vMU23l1vVJ8w217gxTs3bjan2vPDR86ahVpD/2JkTVDjJsJv+qe1Z/an +yOaVZeNGuLhUMMvf2+8wpQ+OD548yfVhiTMCf1R/efbHf3725Y9ffXK/+fLzb9I/Pqvvfz14fP76 +i1e9333z6Hef3/3koNNsDP9gvv/rQ/P7L77+/vGfn6q/fHH0r0+efj24bGWPHsqn+R2h1O+TZHj4 +8+Grz5M/fH3/340/ff3l5xfDr4d/k/f27nx9/+h3Ay70zWj/1V//fvT1l6o8Puh89efWYaPxyaup +po7a/4D2ssNHd77I/vvx6PDnn/bVf9c/f3DePxrC4I5ef/Zn8/vLR4fqDz/u/9z95Me9O4dnyTen +M5H9ISvOsh/+/s9/PfjuoPHD/Ebjcl/89PWXbx799PUXw8b5Z4ef37l8dPdx+2zvDjHr0f+cPLs8 +PPvpx2y/+3X35Rdn+69HB6+z/xZj7PifPx62xNF/vv7yL5/8aPFAl4cH/3717z58+uN/Dp+0n/xu +v57//IcHx/Xf92wfXjbbl3t3ip/vftZ62NJ/v3vwWp3c//LBnfSPn+1/+/n/fPb1wSffPzooL//0 +5x+++f3r+61W8w1+6nz28OzotW1ZJPea2aDzh//5ovPvb9r73Tt/+aQ++Oxflw+Ojv/4H+z/p1/f +/+Z1unfH3P/hp68f9FqfnH/21dP797Lzf33VybJ7w7P0waD1RHz25gvhMbYOvxn+AGzLPimzH9Ok +/UXn4F4Txlc8/epu/fNyv5s9P7cU/OPoztcHT778/Y8PPy/0EMblyT/N7/+cHfT//dmXP7T/+YU8 +/f1PhPbPvTtA0J/Nn36PQ/JP86P5ew/59Of9N5+aupuaP7SPEvHT758e3mt++cdHv/vsvwfYisEf +/k1YqMjeneT0/z5R9PmzPz/60n368seHf7PFDz5/+D8WmfyHfAJT92Xy2Z///PBzefiXV185PD9+ +9eX99s/f/ptG0ncY8D3b164VKLT/je/AT6ED4u5XL7BQqQimf7d/eEKsPiyHf1Hmv83PrQffHf78 +2eHZvb/952Gz+ckf9s3p938vnt95+f2DZwf7zw/Pjjv/+fo/P33xau/O/2/vy7fTZ3IFn4B3CPsO +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 +wknerg== + + + diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/hamburger_light.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/hamburger_light.svg new file mode 100755 index 0000000..27a1290 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/hamburger_light.svg @@ -0,0 +1,1936 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + eJzsvemOJMmRJvgE9g6+PxogB1NBU1PTw7iDBcLj6OEs2V1gsad70RgUklnRZG7nUcjKai736Ve+ +T0RU1dw9siKPIontCq3KCBdXUzPTQ1SOT0T/7n/78qsvrr958/uHL+LVfJj+7u9u3j48e/fm7S8P +pB5+9fLl99+9ewvSz37780PIV7NUuv5V/doq/s+Ht9+9ePP6l/zqKsqX97j6Z7/67tnvH16+fDj8 ++tnrb9798dnLh7c/P/zs5/L97168e/kgNf747NXvv3/7h4e3X7988Yc/vrt69uLnfn9p8PbZO6m0 +/mL5RYiH5ZfzevjyN/j62ev/ePbddy/+3wfcMVbc8Pjm+9ffvHj9h+Ob/0eIhy9iOsTt8EWRr/77 +i98+fPee72/fPP/+1cPrd1++ffP84bvvbt68fPP2u18ebv787PXhN8/+IN88O/xf8hpv/nQ4vnz2 +/N8nefX09f2Llw/ylq+evTuEBR1y/auwfH38/sXLb/7h+1e/f5D3zxvJ8Ws2+U/fSVvSLP4GuXz9 +q1dC+erh3Tt5LrkhOvW3f38cH0OILD/7198+/OEFx0C65X/93Jp9++bbV8/e/juuPXyxzgf5z+74 +u4dX376U3uPrLvNVOnzBf/ufVk/egnW+WHKVXin5EOd6iKnq971vHv7jxcOffnn4hzevH7QDrt++ ++0qHYF3nWf/Vb377vQz0P71+8U4eLIO0aQ/85s03Dy+lfrv+/uUzvjhL6P9qhd89k4nxTsbuzcvv +33F6Vb+D9PCvn/35AcMU9Ab/+O3D69+9+Z98xi+WIO0s29V2WFZ5o7Bs6yFUtr/gUbe53TP0f7Vp +NIRmvH3MkC9lnP7x7Ys/vHj9yy9ilb6Oy6xD+PdvX3zTRzAcqv0vjV/V4f/N/9enlRd/9+7htT29 +zJub3wzzYL76zVdy17vX39y8eYXe/w4TXCbAa5kbL9/8Qb9rf/Mbufz7b/UN+PlrGagv3754jTan +f+A39esvX34vX/392zfff/ur1//2ZvqZru//+fBcFrGM5TeHf/z9/y0fZJFybh5+9/bZc2lAPrc6 +skS//fl7m5OXe/tw0C/lSn703z989e3Dv8mq6pcr9e71fzy8fPPt0GyjCGs5/POzt9/+cNNfvnz2 ++tnbA+mt5V+/+A/55pn0VG+7057QqMySb6VzeAmrnNzgPRWGr55wo2fv/igM6OH1N9+1tvXj/sGV +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 +8xm/zlGv8eucwWv86lmK7Pe2LO38fNRjvM/gMp+zPUe9ruvrPfhZQyXmECh9Pt0czCFP+XQQTBeV +X8g9uB/ja3A/5nMZ56jXBZ8zeN0czHgDgcTXtuT9r09HPcbX4znm61Huo94P/cs98M25nts9V1/P ++MzV52245urLeM/Vl/nM1eeo11x9zuA1V59nfG+734b7qMd4n8FlPmd7vY/nur7egy9vzuvmXM/4 +cmT223A7Msf4cmSO+VzGOep1wecMXjfnPON72/023Ec9xtfjOebrUZ738XroX+7Bz589kMY+Fu2z +BxLml1fRmGL/5JZgtpEe4222IO99VJYurff8H8ZPHsi97fYq7qMe4+sMjvk623PU67q+3IO/+zR5 +pt7XfT2OwvX7x6W4zvQy3ld1mc8duI567tV1Bvd9PY7Cve12Ke6jHuPrDI75Ottz1Ou6vtyD7zJN +ntn3dWuPr3CdwvEqrpO9jPeFXeZzE66jntt1ncF9a4+vcG+7vYr7qMf4OoNjvs72HPW6ri/34O/+ +yp7PAJ/OKF+GgjC/Pu+OUhV7BMfYBQP5NBTgUPUZ76GAzSxSfX+IYfw0FNzb7s/7Pg== + + + 6jG+zuCYr7M9R72u68s9+M6LkdetPd/tdQrnC79O9jLeF3aZz024jnpu13UG96093+297f7C76Me +4+sMjvk623PU67q+3IPvuRh53dfz0V6/fz7v60wv431Vl/ncgeuo515dZ3Df1/PR3tvuz/s+6jG+ +zuCYr7M9R72u68s98NQOshASOJ/8niF8/ifnyQr3t5t1jC+X7JiPh3KOevky5wxefs/XE3M4ZHxx +73nY8mntwxPQttdq4hhfK49jPo74Oerlso8vnv3rdHCK/1yh1n/4+z9/BVr/U+Kv5e8Wf/Ud+xSE +PbFWvGF/xBj7/vTlaCcU+3cOFuLd7Vq9U/lSztyRGesLs+cDECu9zk7tkxFr8trO3GEz1u+jfnsf +tSn9/z4DG/fcscb4tO2Q0vt91GN8ncExX2d7jnpd15d78N3mDvz7p1tLb6J8OgX6HXyxr5O9jPeF +XeZzE66jntt1ncF9a5t1tu9tp4Rq76Me4+sMjvk623PU67q+3IPvMnewauPTfeVp50+vLC+wfHpl +L+N9VZf53IHrqOdeXWdw31f8RO3907bTUobXUY/xdQbHfJ3tOep1XV/uwXcLZKEyyqNnWSccwRaB +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 +3x/Wu/nN/nv9H/gN+An3OrCRH2jT/wGF4u/k + + + diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-combo-box-bg.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-combo-box-bg.png new file mode 100755 index 0000000..f619677 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-combo-box-bg.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-combo-box-bg2x.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-combo-box-bg2x.png new file mode 100755 index 0000000..57663ca Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-combo-box-bg2x.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-grips.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-grips.png new file mode 100755 index 0000000..1692347 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-grips.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-sprites2x.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-sprites2x.png new file mode 100755 index 0000000..a70f5dc Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/light-sprites2x.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/pop-up-triangle-dark.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/pop-up-triangle-dark.png new file mode 100755 index 0000000..53e79bc Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/pop-up-triangle-dark.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/pop-up-triangle.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/pop-up-triangle.png new file mode 100755 index 0000000..0467cc5 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/pop-up-triangle.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search-bg.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search-bg.png new file mode 100755 index 0000000..54181ee Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search-bg.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search-bg2x.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search-bg2x.png new file mode 100755 index 0000000..f886480 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search-bg2x.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search.svg new file mode 100755 index 0000000..d18a4fa --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search.svg @@ -0,0 +1,11 @@ + + + Slice 1 + Created with Sketch (http://www.bohemiancoding.com/sketch) + + + + + + + \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search_bw.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search_bw.svg new file mode 100755 index 0000000..9ab9e71 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search_bw.svg @@ -0,0 +1,16 @@ + + + + + + +]> + + + diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search_dark.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search_dark.svg new file mode 100755 index 0000000..9ab9e71 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search_dark.svg @@ -0,0 +1,16 @@ + + + + + + +]> + + + diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search_light.svg b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search_light.svg new file mode 100755 index 0000000..0c0dff6 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/search_light.svg @@ -0,0 +1,11 @@ + + + Slice 1 + Created with Sketch (http://www.bohemiancoding.com/sketch) + + + + + + + \ No newline at end of file diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/spinner.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/spinner.png new file mode 100755 index 0000000..ae457fa Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/spinner.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/spinner2x.png b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/spinner2x.png new file mode 100755 index 0000000..3b77ee6 Binary files /dev/null and b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/img/spinner2x.png differ diff --git a/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/package.json b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/package.json new file mode 100755 index 0000000..03c64ef --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/assets/topcoat-0.7.5/package.json @@ -0,0 +1,85 @@ +{ + "name": "topcoat", + "version": "0.7.5", + "description": "CSS for clean and fast web apps", + "main": "Gruntfile.js", + "directories": { + "doc": "doc", + "test": "test" + }, + "dependencies": { + "topcoat-utils": "~0.1.3", + "topcoat-radio-button-base": "~0.1.1", + "topcoat-button-base": "~0.6.0", + "topcoat-radio-button": "~0.1.2", + "topcoat-navigation-bar-base": "~0.4.0", + "topcoat-navigation-bar": "~0.4.2", + "topcoat-input-base": "~0.4.1", + "topcoat-list-base": "~0.4.1", + "topcoat-list": "~0.5.0", + "topcoat-search-input": "~0.3.0", + "topcoat-search-input-base": "~0.1.2", + "topcoat-checkbox": "~0.4.0", + "topcoat-checkbox-base": "~0.1.3", + "topcoat-button": "~0.5.3", + "topcoat-icon-button": "~0.3.3", + "topcoat-button-bar-base": "~0.1.1", + "topcoat-button-bar": "~0.1.0", + "topcoat-textarea": "~0.3.0", + "topcoat-theme": "~0.5.24", + "topcoat-text-input": "~0.3.4", + "topcoat-textarea-base": "~0.3.2", + "topcoat-notification": "~0.1.1", + "topcoat-notification-base": "0.0.1", + "topcoat-tab-bar": "~0.1.0", + "topcoat-switch": "~0.1.3", + "topcoat-switch-base": "~0.1.0", + "topcoat-range-base": "0.0.3", + "topcoat-range": "~0.1.0" + }, + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-copy": "~0.4.1", + "grunt-contrib-jade": "~0.4.0", + "grunt-contrib-watch": "~0.1.4", + "grunt-contrib-clean": "~0.4.1", + "grunt-exec": "~0.4.2", + "grunt-contrib-cssmin": "~0.5.0", + "jade": "~0.28.2", + "grunt-contrib-stylus": "~0.6.0", + "grunt-contrib-htmlmin": "~0.1.3", + "prompt": "*", + "csv": "*", + "topdoc-theme": "~0.2.7", + "grunt-topdoc": "~0.1.3", + "grunt-autoprefixer": "~0.2.20130806" + }, + "scripts": { + "test": "grunt test", + "prepublish": "grunt" + }, + "repository": { + "type": "git", + "url": "git://github.com/topcoat/topcoat.git" + }, + "bugs": { + "url": "https://github.com/topcoat/topcoat/issues" + }, + "license": { + "type": "Apache", + "url": "https://github.com/topcoat/topcoat/blob/master/LICENSE" + }, + "keywords": [ + "css", + "ui", + "ux", + "pattern", + "library", + "mobile", + "desktop", + "native", + "application", + "web", + "standards" + ] +} diff --git a/plugins/cordova-plugin-test-framework/www/jasmine_helpers.js b/plugins/cordova-plugin-test-framework/www/jasmine_helpers.js new file mode 100644 index 0000000..c007104 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/jasmine_helpers.js @@ -0,0 +1,83 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint -W097 */ +'use strict'; + +exports.setUpJasmine = function() { + // Set up jasmine + var jasmine = jasmineRequire.core(jasmineRequire); + jasmineRequire.html(jasmine); + var jasmineEnv = jasmine.currentEnv_ = new jasmine.Env(); + + jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; + jasmineEnv.catchExceptions(false); + + // Set up jasmine interface + var jasmineInterface = jasmineRequire.interface(jasmine, jasmineEnv); + + // Add Reporters + addJasmineReporters(jasmineInterface, jasmineEnv); + + // Add Spec Filter + jasmineEnv.specFilter = function(spec) { + //console.log(spec.getFullName()); + return true; + }; + + // Jasmine 2.2.0 moved this symbol, so we add a shim here. + jasmine.Expectation.addMatchers = jasmine.Expectation.addMatchers || function() { + return jasmine.addMatchers.apply(this, arguments); + }; + + return jasmineInterface; +}; + +function addJasmineReporters(jasmineInterface, jasmineEnv) { + jasmineInterface.jsApiReporter = new jasmineInterface.jasmine.JsApiReporter({ timer: new jasmineInterface.jasmine.Timer() }); + jasmineEnv.addReporter(jasmineInterface.jsApiReporter); + + jasmineInterface.htmlReporter = new jasmineInterface.jasmine.HtmlReporter({ + env: jasmineEnv, + queryString: function() { return null; }, + onRaiseExceptionsClick: function() { }, + getContainer: function() { return document.getElementById('content'); }, + createElement: function() { return document.createElement.apply(document, arguments); }, + createTextNode: function() { return document.createTextNode.apply(document, arguments); }, + timer: new jasmineInterface.jasmine.Timer() + }); + jasmineInterface.htmlReporter.initialize(); + jasmineEnv.addReporter(jasmineInterface.htmlReporter); + + var medic = require('cordova-plugin-test-framework.medic'); + + if (medic.enabled) { + jasmineRequire.medic(jasmineInterface.jasmine); + jasmineInterface.MedicReporter = new jasmineInterface.jasmine.MedicReporter({ + env: jasmineEnv, + log: { logurl: medic.logurl }, + sha: medic.sha + }); + jasmineInterface.MedicReporter.initialize(); + jasmineEnv.addReporter(jasmineInterface.MedicReporter); + } + +} diff --git a/plugins/cordova-plugin-test-framework/www/main.js b/plugins/cordova-plugin-test-framework/www/main.js new file mode 100644 index 0000000..954af80 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/main.js @@ -0,0 +1,446 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* global WinJS */ +/* jshint -W097 */ +'use strict'; + +var LOG_HEADER_HEIGHT = 20, + CONTENT_TOP_OFFSET = 30; + +var isWin = cordova.platformId === "windows", + isWP8 = cordova.platformId === "windowsphone"; + +/******************************************************************************/ + +function getMode(callback) { + var mode = localStorage.getItem('cdvtests-mode') || 'main'; + callback(mode); +} + +function setMode(mode) { + var handlers = { + 'main': runMain, + 'auto': runAutoTests, + 'manual': runManualTests + }; + if (!handlers.hasOwnProperty(mode)) { + console.error("Unsupported mode: " + mode); + console.error("Defaulting to 'main'"); + mode = 'main'; + } + + localStorage.setItem('cdvtests-mode', mode); + clearContent(); + + handlers[mode](); +} + +/******************************************************************************/ + +function clearContent() { + var content = document.getElementById('content'); + content.innerHTML = ''; + var log = document.getElementById('log--content'); + log.innerHTML = ''; + var buttons = document.getElementById('buttons'); + buttons.innerHTML = ''; + + setLogVisibility(false); +} + +/******************************************************************************/ + +function setTitle(title) { + var el = document.getElementById('title'); + el.textContent = title; +} + +/******************************************************************************/ + +function setLogVisibility(visible) { + if (visible) { + document.querySelector('body').classList.add('expanded-log'); + + if (isWin || isWP8) { + var h = document.querySelector('body').offsetHeight; + + document.getElementById('middle').style.height = (h * 0.6 - LOG_HEADER_HEIGHT - CONTENT_TOP_OFFSET) + "px"; + document.getElementById('middle').style.marginBottom = (h * 0.4) + "px"; + document.getElementById('middle').style.paddingBottom = (h * 0.4) + "px"; + } + } else { + document.querySelector('body').classList.remove('expanded-log'); + + if (isWin || isWP8) { + document.getElementById('middle').style.height = ""; + document.getElementById('middle').style.marginBottom = ""; + document.getElementById('middle').style.paddingBottom = ""; + } + } +} + +window.onresize = function (event) { + // Update content and log heights + if (isWin || isWP8) { + setLogVisibility(getLogVisibility()); + } +}; + +function getLogVisibility() { + var e = document.querySelector('body'); + return e.classList.contains('expanded-log'); +} + +function toggleLogVisibility() { + if (getLogVisibility()) { + setLogVisibility(false); + } else { + setLogVisibility(true); + } +} + +/******************************************************************************/ + +function attachEvents() { + document.getElementById('log--title').addEventListener('click', toggleLogVisibility); +} + +/******************************************************************************/ + +var origConsole = window.console; + +exports.wrapConsole = function() { + function appendToOnscreenLog(type, args) { + var el = document.getElementById('log--content'); + var div = document.createElement('div'); + div.classList.add('log--content--line'); + div.classList.add('log--content--line--' + type); + div.textContent = Array.prototype.slice.apply(args).map(function(arg) { + return (typeof arg === 'string') ? arg : JSON.stringify(arg); + }).join(' '); + el.appendChild(div); + // scroll to bottom + el.scrollTop = el.scrollHeight; + } + + function createCustomLogger(type) { + var medic = require('cordova-plugin-test-framework.medic'); + return function() { + origConsole[type].apply(origConsole, arguments); + // TODO: encode log type somehow for medic logs? + medic.log.apply(medic, arguments); + appendToOnscreenLog(type, arguments); + setLogVisibility(true); + }; + } + + window.console = { + log: createCustomLogger('log'), + warn: createCustomLogger('warn'), + error: createCustomLogger('error'), + }; +}; + +exports.unwrapConsole = function() { + window.console = origConsole; +}; + +/******************************************************************************/ + +function createActionButton(title, callback, appendTo) { + appendTo = appendTo ? appendTo : 'buttons'; + var buttons = document.getElementById(appendTo); + var div = document.createElement('div'); + var button = document.createElement('a'); + button.textContent = title; + button.onclick = function(e) { + e.preventDefault(); + callback(); + }; + button.classList.add('topcoat-button'); + div.appendChild(button); + buttons.appendChild(div); +} + +/******************************************************************************/ + +function setupAutoTestsEnablers(cdvtests) { + var enablerList = createEnablerList(); + + // Iterate over all the registered test modules + iterateAutoTests(cdvtests, function(api, testModule) { + // For "standard" plugins remove the common/repetitive bits of + // the api key, for use as the title. For third-party plugins, the full + // api will be used as the title + var title = api.replace(/org\.apache\.cordova\./i, '').replace(/\.tests.tests/i, ''); + + createEnablerCheckbox(api, title, testModule.getEnabled(), enablerList.id, toggleTestHandler); + }); + + updateEnabledTestCount(); +} + +/******************************************************************************/ + +function createEnablerList() { + var buttons = document.getElementById('buttons'); + + var enablerContainer = document.createElement('div'); + enablerContainer.id = 'test-enablers-container'; + + // Create header to show count of enabled/total tests + var header = document.createElement('h3'); + header.id = 'tests-enabled'; + + // Create widget to show/hide list + var expander = document.createElement('span'); + expander.id = 'test-expander'; + expander.innerText = 'Show/hide tests to be run'; + expander.onclick = toggleEnablerVisibility; + + // Create list to contain checkboxes for each test + var enablerList = document.createElement('div'); + enablerList.id = "test-list"; + + // Create select/deselect all buttons (in button bar) + var checkButtonBar = document.createElement('ul'); + checkButtonBar.classList.add('topcoat-button-bar'); + + function createSelectToggleButton(title, selected) { + var barItem = document.createElement('li'); + barItem.classList.add('topcoat-button-bar__item'); + + var link = document.createElement('a'); + link.classList.add('topcoat-button-bar__button'); + link.innerText = title; + link.href = null; + link.onclick = function(e) { + e.preventDefault(); + toggleSelected(enablerList.id, selected); + return false; + }; + + barItem.appendChild(link); + checkButtonBar.appendChild(barItem); + } + createSelectToggleButton('Check all', true); + createSelectToggleButton('Uncheck all', false); + enablerList.appendChild(checkButtonBar); + + enablerContainer.appendChild(header); + enablerContainer.appendChild(expander); + enablerContainer.appendChild(enablerList); + + buttons.appendChild(enablerContainer); + + return enablerList; +} + +/******************************************************************************/ + +function updateEnabledTestCount() { + var enabledLabel = document.getElementById('tests-enabled'); + + // Determine how many tests are currently enabled + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + var total = 0; + var enabled = 0; + iterateAutoTests(cdvtests, function(api, testModule) { + total++; + if (testModule.getEnabled()) { + enabled++; + } + }); + + if (enabled == total) { + enabledLabel.innerText = 'Running All Tests.'; + } else { + enabledLabel.innerText = 'Running ' + enabled + ' of ' + total + ' Tests.'; + } +} + +/******************************************************************************/ + +function toggleSelected(containerId, newCheckedValue) { + [].forEach.call(document.getElementById(containerId).getElementsByTagName('input'), function(input) { + if (input.type !== 'checkbox') return; + input.checked = newCheckedValue; + toggleTestEnabled(input); + }); + updateEnabledTestCount(); +} + +/******************************************************************************/ + +function toggleEnablerVisibility() { + var enablerList = document.getElementById('test-list'); + if (enablerList.classList.contains('expanded')) { + enablerList.classList.remove('expanded'); + } else { + enablerList.classList.add('expanded'); + } +} + +/******************************************************************************/ + +function createEnablerCheckbox(api, title, isEnabled, appendTo, callback) { + var container = document.getElementById(appendTo); + + var label = document.createElement('label'); + label.classList.add('topcoat-checkbox'); + + var checkbox = document.createElement('input'); + checkbox.type = "checkbox"; + checkbox.value = api; + checkbox.checked = isEnabled; + label.htmlFor = checkbox.id = 'enable_' + api; + + checkbox.onchange = function(e) { + e.preventDefault(); + callback(e); + }; + + var div = document.createElement('div'); + div.classList.add('topcoat-checkbox__checkmark'); + + var text = document.createElement('span'); + text.innerText = title; + + label.appendChild(checkbox); + label.appendChild(div); + label.appendChild(text); + + container.appendChild(label); +} + +/******************************************************************************/ + +function toggleTestHandler(event) { + var checkbox = event.target; + + toggleTestEnabled(checkbox); + updateEnabledTestCount(); +} + +/******************************************************************************/ + +function toggleTestEnabled(checkbox) { + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + cdvtests.tests[checkbox.value].setEnabled(checkbox.checked); +} + +/******************************************************************************/ + +function iterateAutoTests(cdvtests, callback) { + Object.keys(cdvtests.tests).forEach(function(api) { + var testModule = cdvtests.tests[api]; + if (!testModule.hasOwnProperty('defineAutoTests')) { + return; + } + callback(api, testModule); + }); +} + +/******************************************************************************/ + +function runAutoTests() { + setTitle('Auto Tests'); + + createActionButton('Run', setMode.bind(null, 'auto')); + createActionButton('Reset App', location.reload.bind(location)); + createActionButton('Back', setMode.bind(null, 'main')); + + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + cdvtests.init(); + setupAutoTestsEnablers(cdvtests); + + cdvtests.defineAutoTests(); + + // Run the tests! + var jasmineEnv = window.jasmine.getEnv(); + + jasmineEnv.execute(); +} + +/******************************************************************************/ + +function runManualTests() { + setTitle('Manual Tests'); + + createActionButton('Reset App', location.reload.bind(location)); + createActionButton('Back', setMode.bind(null, 'main')); + + var contentEl = document.getElementById('content'); + var beforeEach = function(title) { + clearContent(); + setTitle(title || 'Manual Tests'); + createActionButton('Reset App', location.reload.bind(location)); + createActionButton('Back', setMode.bind(null, 'manual')); + }; + var cdvtests = cordova.require('cordova-plugin-test-framework.cdvtests'); + cdvtests.defineManualTests(contentEl, beforeEach, createActionButton); +} + +/******************************************************************************/ + +function runMain() { + setTitle('Apache Cordova Plugin Tests'); + + createActionButton('Auto Tests', setMode.bind(null, 'auto')); + createActionButton('Manual Tests', setMode.bind(null, 'manual')); + createActionButton('Reset App', location.reload.bind(location)); + if (/showBack/.exec(location.hash)) { + createActionButton('Back', function() { + history.go(-1); + }); + } + + if (isWin && typeof WinJS !== 'undefined') { + var app = WinJS.Application; + app.addEventListener("error", function (err) { + // We do not want an unhandled exception to crash the test app + // Returning true marks it as being handled + return true; + }); + } +} + +/******************************************************************************/ + +exports.init = function() { + // TODO: have a way to opt-out of console wrapping in case line numbers are important. + // ...Or find a custom way to print line numbers using stack or something. + // make sure to always wrap when using medic. + attachEvents(); + exports.wrapConsole(); + + var medic = require('cordova-plugin-test-framework.medic'); + medic.load(function() { + if (medic.enabled) { + setMode('auto'); + } else { + getMode(setMode); + } + }); +}; + +/******************************************************************************/ diff --git a/plugins/cordova-plugin-test-framework/www/medic.js b/plugins/cordova-plugin-test-framework/www/medic.js new file mode 100644 index 0000000..47f261f --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/medic.js @@ -0,0 +1,63 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint -W097 */ +'use strict'; + +exports.logurl = 'http://127.0.0.1:7800'; + +exports.enabled = false; + +exports.log = function() { + if (!exports.enabled) + return; + var xhr = new XMLHttpRequest(); + xhr.open("POST", exports.logurl, true); + xhr.setRequestHeader("Content-Type", "text/plain"); + xhr.send(Array.prototype.slice.apply(arguments)); +}; + +exports.load = function (callback) { + var cfg = null; + + try { + // attempt to synchronously load medic config + var xhr = new XMLHttpRequest(); + xhr.open("GET", "../medic.json", false); + xhr.send(null); + cfg = JSON.parse(xhr.responseText); + } catch (ex) { } + + // config is available + if (cfg) { + exports.logurl = cfg.couchdb || cfg.logurl; + exports.sha = cfg.sha; + exports.enabled = true; + console.log('Loaded Medic Config: logurl=' + exports.logurl); + } else { + // config does not exist + console.log('Did not find medic config file'); + } + + setTimeout(function () { + callback(); + }, 0); +}; diff --git a/plugins/cordova-plugin-test-framework/www/tests.js b/plugins/cordova-plugin-test-framework/www/tests.js new file mode 100644 index 0000000..cea8898 --- /dev/null +++ b/plugins/cordova-plugin-test-framework/www/tests.js @@ -0,0 +1,135 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* jshint jasmine: true */ +/* jshint -W097 */ +'use strict'; + +exports.tests = Object.create(null); + +function TestModule(api) { + var name = api; + var enabled = true; + + var enabledPref = localStorage.getItem('cordova-tests-enabled-' + name); + if (enabledPref) + { + enabled = (enabledPref == true.toString()); + } + + this.getEnabled = function () { + return enabled; + }; + + this.setEnabled = function (isEnabled) { + enabled = isEnabled; + localStorage.setItem('cordova-tests-enabled-' + name, enabled); + }; +} + +function getTestsObject(api) { + exports.tests[api] = exports.tests[api] || new TestModule(api); + return exports.tests[api]; +} + +function requireAllTestModules() { + // This finds all js-modules named "tests" (regardless of plugins they came from) + var test_modules = cordova.require('cordova/plugin_list') + .map(function(jsmodule) { + return jsmodule.id; + }) + .filter(function(id) { + return /\.tests$/.test(id); + }); + + // Map auto / manual test definitions for each, but without actually running the handlers + test_modules.forEach(function(id) { + try { + var plugintests = cordova.require(id); + + if (plugintests.hasOwnProperty('defineAutoTests')) { + getTestsObject(id).defineAutoTests = function() { + describe(id + ' >>', plugintests.defineAutoTests.bind(plugintests)); + }; + } + + if (plugintests.hasOwnProperty('defineManualTests')) { + getTestsObject(id).defineManualTests = plugintests.defineManualTests.bind(plugintests); + } + } catch(ex) { + console.warn('Failed to load tests: ', id); + return; + } + }); +} + +function createJasmineInterface() { + var jasmine_helpers = require('cordova-plugin-test-framework.jasmine_helpers'); + var jasmineInterface = jasmine_helpers.setUpJasmine(); + return jasmineInterface; +} + +function attachJasmineInterfaceToGlobal() { + var jasmineInterface = createJasmineInterface(); + for (var property in jasmineInterface) { + window[property] = jasmineInterface[property]; + } +} + +function detachJasmineInterfaceFromGlobal() { + var jasmineInterface = createJasmineInterface(); + for (var property in jasmineInterface) { + delete window[property]; + } +} + +exports.defineAutoTests = function() { + requireAllTestModules(); + attachJasmineInterfaceToGlobal(); + + Object.keys(exports.tests).forEach(function(key) { + if (!exports.tests[key].getEnabled()) + return; + if (!exports.tests[key].hasOwnProperty('defineAutoTests')) + return; + exports.tests[key].defineAutoTests(); + }); +}; + +exports.defineManualTests = function(contentEl, beforeEach, createActionButton) { + requireAllTestModules(); + detachJasmineInterfaceFromGlobal(); + + Object.keys(exports.tests).forEach(function(key) { + if (!exports.tests[key].getEnabled()) + return; + if (!exports.tests[key].hasOwnProperty('defineManualTests')) + return; + createActionButton(key, function() { + beforeEach(key); + exports.tests[key].defineManualTests(contentEl, createActionButton); + }); + }); +}; + +exports.init = function() { + requireAllTestModules(); +}; diff --git a/plugins/de.appplant.cordova.plugin.local-notification/CHANGELOG.md b/plugins/de.appplant.cordova.plugin.local-notification/CHANGELOG.md new file mode 100644 index 0000000..8771655 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/CHANGELOG.md @@ -0,0 +1,100 @@ +ChangeLog +--------- + +Please also read the [Upgrade Guide](https://github.com/katzer/cordova-plugin-local-notifications/wiki/Upgrade-Guide) for more information. + +#### Version 0.8.4 (04.01.2016) +- Bug fixes + - SyntaxError: missing ) after argument list + +#### Version 0.8.3 (03.01.2016) +- Platform enhancements + - Support for the `Crosswalk Engine` + - Support for `cordova-ios@4` and the `WKWebView Engine` + - Support for `cordova-windows@4` and `Windows 10` without using hooks +- Enhancements + - New `color` attribute for Android (Thanks to @Eusebius1920) + - New `quarter` intervall for iOS & Android + - `smallIcon` is optional (Android) + - `update` checks for permission like _schedule_ + - Decreased time-frame for trigger event (iOS) + - Force `every:` to be a string on iOS +- Bug fixes + - Fixed #634 option to skip permission check + - Fixed #588 crash when basename & extension can't be extracted (Android) + - Fixed #732 loop between update and trigger (Android) + - Fixed #710 crash due to >500 notifications (Android) + - Fixed #682 crash while resuming app from notification (Android 6) + - Fixed #612 cannot update icon or sound (Android) + - Fixed crashing get(ID) if notification doesn't exist + - Fixed #569 getScheduled returns two items per notification + - Fixed #700 notifications appears on bootup + +#### Version 0.8.2 (08.11.2015) +- Submitted to npm +- Initial support for the `windows` platform +- Re-add autoCancel option on Android +- Warn about unknown properties +- Fix crash on iOS 9 +- Fixed webView-Problems with cordova-android 4.0 +- Fix get* with single id +- Fix issue when passing data in milliseconds +- Update device plugin id +- Several other fixes + +#### Version 0.8.1 (08.03.2015) + +- Fix incompatibility with cordova version 3.5-3.0 +- Fire `clear` instead of `cancel` event when clicked on repeating notifications +- Do not fire `clear` or `cancel` event when clicked on persistent notifications + +### Version 0.8.0 (05.03.2015) + +- Support for iOS 8, Android 2 (SDK >= 7) and Android 5 + - Windows Phone 8.1 will be added soon +- New interfaces to ask for / register permissions required to schedule local notifications + - `hasPermission()` and `registerPermission()` + - _schedule()_ will register the permission automatically and schedule the notification if granted. +- New interface to update already scheduled|triggered local notifications + - `update()` +- New interfaces to clear the notification center + - `clear()` and `clearAll()` +- New interfaces to query for local notifications, their properties, their IDs and their existence depend on their state + - `isPresent()`, `isScheduled()`, `isTriggered()` + - `getIds()`, `getAllIds()`, `getScheduledIds()`, `getTriggeredIds()` + - `get()`, `getAll()`, `getScheduled()`, `getTriggered()` +- Schedule multiple local notifications at once + - `schedule( [{...},{...}] )` +- Update multiple local notifications at once + - `update( [{...},{...}] )` +- Clear multiple local notifications at once + - `clear( [1, 2] )` +- Cancel multiple local notifications at once + - `cancel( [1, 2] )` +- New URI format to specify sound and image resources + - `http(s):` for remote resources _(Android)_ + - `file:` for local resources relative to the _www_ folder + - `res:` for native resources +- New events + - `schedule`, `update`, `clear`, `clearall` and `cancelall` +- Enhanced event informations + - Listener will get called with the local notification object instead of only the ID +- Multiple listener for one event + - `on(event, callback, scope)` +- Unregister event listener + - `un(event, callback)` +- New Android specific properties + - `led` properties + - `sound` and `image` accepts remote resources +- Callback function and scope for all interface methods + - `schedule( notification, callback, scope )` +- Renamed `add()` to `schedule()` +- `autoCancel` property has been removed + - Use `ongoing: true` for persistent local notifications on Android +- Renamed repeat intervals + - `second`, `minute`, `hour`, `day`, `week`, `month` and `year` +- Renamed some local notification properties + - `date`, `json`, `message` and `repeat` + - Scheduling local notifications with the deprecated properties is still possible +- [Kitchen Sink sample app](https://github.com/katzer/cordova-plugin-local-notifications/tree/example) +- [Wiki](https://github.com/katzer/cordova-plugin-local-notifications/wiki) diff --git a/plugins/de.appplant.cordova.plugin.local-notification/LICENSE b/plugins/de.appplant.cordova.plugin.local-notification/LICENSE new file mode 100644 index 0000000..28974b7 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2013-2015 appPlant UG, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/plugins/de.appplant.cordova.plugin.local-notification/README.md b/plugins/de.appplant.cordova.plugin.local-notification/README.md new file mode 100644 index 0000000..20f853d --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/README.md @@ -0,0 +1,132 @@ + +[![npm version](https://badge.fury.io/js/de.appplant.cordova.plugin.local-notification.svg)](http://badge.fury.io/js/de.appplant.cordova.plugin.local-notification) +[![PayPayl donate button](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=L3HKQCD9UA35A "Donate once-off to this project using Paypal") + +Cordova Local-Notification Plugin +================================= + +The essential purpose of local notifications is to enable an application to inform its users that it has something for them — for example, a message or an upcoming appointment — when the application isn’t running in the foreground.
    +They are scheduled by an application and delivered on the same device. + + + +### How they appear to the user +Users see notifications in the following ways: +- Displaying an alert or banner +- Badging the app’s icon +- Playing a sound + + +### Examples of Notification Usage +Local notifications are ideally suited for applications with time-based behaviors, such as calendar and to-do list applications. Applications that run in the background for the limited period allowed by iOS might also find local notifications useful.
    +For example, applications that depend on servers for messages or data can poll their servers for incoming items while running in the background; if a message is ready to view or an update is ready to download, they can then present a local notification immediately to inform their users. + + +## Supported Platforms +The current 0.8 branch supports the following platforms: +- __iOS__ _(>= 8)_
    +- __Android__ _(SDK >=7)_ +- __Windows 8.1__ _(added with v0.8.2)_ +- __Windows Phone 8.1__ _(added with v0.8.2)_ +- __Windows 10__ _(added with v0.8.3)_ + +Find out more informations [here][wiki_platforms] in our wiki. + + +## Installation +The plugin is installable from source and available on Cordova Plugin Registry and PhoneGap Build. + +Find out more informations [here][wiki_installation] in our wiki. + + +## I want to get a quick overview +All wiki pages contain samples, but for a quick overview the sample section may be the fastest way. + +Find out more informations [here][wiki_samples] in our wiki. + + +## I want to get a deep overview +The plugin supports scheduling local notifications in various ways with a single interface. It also allows you to update, clear or cancel them. There are different interfaces to query for local notifications and a complete set of events to hook into the life cycle of local notifications. + +Find out more about how to schedule single, multiple, delayed or repeating local notifications [here][wiki_schedule].
    +Informations about events like _click_ or _trigger_ can be found [here][wiki_events]. + +To get a deep overview we recommend to read about all the topics in our [wiki][wiki] and try out the [Kitchen Sink App][wiki_kitchensink] + + +## I want to see the plugin in action +The plugin offers a kitchen sink sample app. Check out the cordova project and run the app directly from your command line or preferred IDE. + +Find out more informations [here][wiki_kitchensink] in our wiki. + + +## What's new +We are proud to announce our newest release version 0.8.x. Beside the hard work at the office and at the weekends it contains a lot of goodies, new features and easy to use APIs. + +Find out more informations [here][wiki_changelog] in our wiki. + + +## Sample +The sample demonstrates how to schedule a local notification which repeats every week. The listener will be called when the user has clicked on the local notification. + +```javascript +cordova.plugins.notification.local.schedule({ + id: 1, + title: "Production Jour fixe", + text: "Duration 1h", + firstAt: monday_9_am, + every: "week", + sound: "file://sounds/reminder.mp3", + icon: "http://icons.com/?cal_id=1", + data: { meetingId:"123#fg8" } +}); + +cordova.plugins.notification.local.on("click", function (notification) { + joinMeeting(notification.data.meetingId); +}); +``` + +Find out more informations [here][wiki_samples] in our wiki. + + +## I would like to propose new features +We appricate any feature proposal and support for their development. Please describe them [here][feature_proposal_issue]. + +Find out more informations [here][wiki_next] in our wiki. + +## Supporting +Your support is needed. If you use the plugin please send us a drop through the donation button. + +Thank you! + +[![PayPayl donate button](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=L3HKQCD9UA35A "Donate once-off to this project using Paypal") + + +## Contributing + +1. Fork it +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create new Pull Request + + +## License + +This software is released under the [Apache 2.0 License][apache2_license]. + +© 2013-2016 appPlant UG, Inc. All rights reserved + + +[cordova]: https://cordova.apache.org +[wiki]: https://github.com/katzer/cordova-plugin-local-notifications/wiki +[wiki_platforms]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/02.-Platforms +[wiki_installation]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/03.-Installation +[wiki_kitchensink]: https://github.com/katzer/cordova-plugin-local-notifications/tree/example +[wiki_schedule]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/04.-Scheduling +[wiki_events]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/09.-Events +[wiki_samples]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/11.-Samples +[wiki_changelog]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/Upgrade-Guide +[wiki_next]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/Feature-Requests +[feature_proposal_issue]: https://github.com/katzer/cordova-plugin-local-notifications/issues/451 +[apache2_license]: http://opensource.org/licenses/Apache-2.0 diff --git a/plugins/de.appplant.cordova.plugin.local-notification/package.json b/plugins/de.appplant.cordova.plugin.local-notification/package.json new file mode 100644 index 0000000..f4d685d --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/package.json @@ -0,0 +1,52 @@ +{ + "name": "de.appplant.cordova.plugin.local-notification", + "cordova_name": "Cordova LocalNotification Plugin", + "version": "0.8.4", + "description": "Schedules and queries for local notifications", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/katzer/cordova-plugin-local-notifications.git" + }, + "keywords": [ + "appplant", + "notification", + "local notification", + "cordova", + "ecosystem:cordova", + "cordova-android", + "cordova-ios", + "cordova-windows" + ], + "platforms": [ + "ios", + "android", + "windows" + ], + "engines": [ + { + "name": "cordova", + "version": ">=3.6.0" + }, + { + "name": "cordova-plugman", + "version": ">=4.3.0" + }, + { + "name": "cordova-windows", + "version": ">=4.2.0" + } + ], + "dependencies": { + "cordova-plugin-device": "*", + "cordova-plugin-app-event": ">=1.1.0" + }, + "author": "Sebastián Katzer", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/katzer/cordova-plugin-local-notifications/issues" + }, + "homepage": "https://github.com/katzer/cordova-plugin-local-notifications#readme" +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/plugin.xml b/plugins/de.appplant.cordova.plugin.local-notification/plugin.xml new file mode 100644 index 0000000..7536568 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/plugin.xml @@ -0,0 +1,224 @@ + + + + + LocalNotification + + The plugin supports scheduling local notifications in various ways with a single interface. It also allows you to update, clear or cancel them. There are different interfaces to query for local notifications and a complete set of events to hook into the life cycle of local notifications. To get a deep overview we recommend to read about all the topics in our wiki and try out the Kitchen Sink App + + https://github.com/katzer/cordova-plugin-local-notifications.git + + appplant, notification, local notification + + Apache 2.0 + + Sebastián Katzer + + + + + + + + + + + + + + + Your support is needed. If you use the local-notification plugin please support us in order to ensure further development. + https://github.com/katzer/cordova-plugin-local-notifications#supporting + + Thank you! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClearReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClearReceiver.java new file mode 100644 index 0000000..e0892e3 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClearReceiver.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.localnotification; + +import de.appplant.cordova.plugin.notification.Notification; + + +/** + * The clear intent receiver is triggered when the user clears a + * notification manually. It un-persists the cleared notification from the + * shared preferences. + */ +public class ClearReceiver extends de.appplant.cordova.plugin.notification.ClearReceiver { + + /** + * Called when a local notification was cleared from outside of the app. + * + * @param notification + * Wrapper around the local notification + */ + @Override + public void onClear (Notification notification) { + super.onClear(notification); + LocalNotification.fireEvent("clear", notification); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClickActivity.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClickActivity.java new file mode 100644 index 0000000..85a5355 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClickActivity.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.localnotification; + +import de.appplant.cordova.plugin.notification.Builder; +import de.appplant.cordova.plugin.notification.Notification; +import de.appplant.cordova.plugin.notification.TriggerReceiver; + +/** + * The receiver activity is triggered when a notification is clicked by a user. + * The activity calls the background callback and brings the launch intent + * up to foreground. + */ +public class ClickActivity extends de.appplant.cordova.plugin.notification.ClickActivity { + + /** + * Called when local notification was clicked by the user. + * + * @param notification + * Wrapper around the local notification + */ + @Override + public void onClick(Notification notification) { + LocalNotification.fireEvent("click", notification); + + super.onClick(notification); + + if (notification.getOptions().isOngoing()) + return; + + String event = notification.isRepeating() ? "clear" : "cancel"; + LocalNotification.fireEvent(event, notification); + } + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + @Override + public Notification buildNotification (Builder builder) { + return builder + .setTriggerReceiver(TriggerReceiver.class) + .build(); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/LocalNotification.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/LocalNotification.java new file mode 100644 index 0000000..b4be09f --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/LocalNotification.java @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.localnotification; + +import android.app.Activity; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaInterface; +import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.PluginResult; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import de.appplant.cordova.plugin.notification.Manager; +import de.appplant.cordova.plugin.notification.Notification; + +/** + * This plugin utilizes the Android AlarmManager in combination with local + * notifications. When a local notification is scheduled the alarm manager takes + * care of firing the event. When the event is processed, a notification is put + * in the Android notification center and status bar. + */ +public class LocalNotification extends CordovaPlugin { + + // Reference to the web view for static access + private static CordovaWebView webView = null; + + // Indicates if the device is ready (to receive events) + private static Boolean deviceready = false; + + // To inform the user about the state of the app in callbacks + protected static Boolean isInBackground = true; + + // Queues all events before deviceready + private static ArrayList eventQueue = new ArrayList(); + + /** + * Called after plugin construction and fields have been initialized. + * Prefer to use pluginInitialize instead since there is no value in + * having parameters on the initialize() function. + * + * pluginInitialize is not available for cordova 3.0-3.5 ! + */ + @Override + public void initialize (CordovaInterface cordova, CordovaWebView webView) { + LocalNotification.webView = super.webView; + } + + /** + * Called when the system is about to start resuming a previous activity. + * + * @param multitasking + * Flag indicating if multitasking is turned on for app + */ + @Override + public void onPause(boolean multitasking) { + super.onPause(multitasking); + isInBackground = true; + } + + /** + * Called when the activity will start interacting with the user. + * + * @param multitasking + * Flag indicating if multitasking is turned on for app + */ + @Override + public void onResume(boolean multitasking) { + super.onResume(multitasking); + isInBackground = false; + deviceready(); + } + + /** + * The final call you receive before your activity is destroyed. + */ + @Override + public void onDestroy() { + deviceready = false; + isInBackground = true; + } + + /** + * Executes the request. + * + * This method is called from the WebView thread. To do a non-trivial + * amount of work, use: + * cordova.getThreadPool().execute(runnable); + * + * To run on the UI thread, use: + * cordova.getActivity().runOnUiThread(runnable); + * + * @param action + * The action to execute. + * @param args + * The exec() arguments in JSON form. + * @param command + * The callback context used when calling back into JavaScript. + * @return + * Whether the action was valid. + */ + @Override + public boolean execute (final String action, final JSONArray args, + final CallbackContext command) throws JSONException { + + Notification.setDefaultTriggerReceiver(TriggerReceiver.class); + + cordova.getThreadPool().execute(new Runnable() { + public void run() { + if (action.equals("schedule")) { + schedule(args); + command.success(); + } + else if (action.equals("update")) { + update(args); + command.success(); + } + else if (action.equals("cancel")) { + cancel(args); + command.success(); + } + else if (action.equals("cancelAll")) { + cancelAll(); + command.success(); + } + else if (action.equals("clear")) { + clear(args); + command.success(); + } + else if (action.equals("clearAll")) { + clearAll(); + command.success(); + } + else if (action.equals("isPresent")) { + isPresent(args.optInt(0), command); + } + else if (action.equals("isScheduled")) { + isScheduled(args.optInt(0), command); + } + else if (action.equals("isTriggered")) { + isTriggered(args.optInt(0), command); + } + else if (action.equals("getAllIds")) { + getAllIds(command); + } + else if (action.equals("getScheduledIds")) { + getScheduledIds(command); + } + else if (action.equals("getTriggeredIds")) { + getTriggeredIds(command); + } + else if (action.equals("getSingle")) { + getSingle(args, command); + } + else if (action.equals("getSingleScheduled")) { + getSingleScheduled(args, command); + } + else if (action.equals("getSingleTriggered")) { + getSingleTriggered(args, command); + } + else if (action.equals("getAll")) { + getAll(args, command); + } + else if (action.equals("getScheduled")) { + getScheduled(args, command); + } + else if (action.equals("getTriggered")) { + getTriggered(args, command); + } + else if (action.equals("deviceready")) { + deviceready(); + } + } + }); + + return true; + } + + /** + * Schedule multiple local notifications. + * + * @param notifications + * Properties for each local notification + */ + private void schedule (JSONArray notifications) { + for (int i = 0; i < notifications.length(); i++) { + JSONObject options = notifications.optJSONObject(i); + + Notification notification = + getNotificationMgr().schedule(options, TriggerReceiver.class); + + fireEvent("schedule", notification); + } + } + + /** + * Update multiple local notifications. + * + * @param updates + * Notification properties including their IDs + */ + private void update (JSONArray updates) { + for (int i = 0; i < updates.length(); i++) { + JSONObject update = updates.optJSONObject(i); + int id = update.optInt("id", 0); + + Notification notification = + getNotificationMgr().update(id, update, TriggerReceiver.class); + + if (notification == null) + continue; + + fireEvent("update", notification); + } + } + + /** + * Cancel multiple local notifications. + * + * @param ids + * Set of local notification IDs + */ + private void cancel (JSONArray ids) { + for (int i = 0; i < ids.length(); i++) { + int id = ids.optInt(i, 0); + + Notification notification = + getNotificationMgr().cancel(id); + + if (notification == null) + continue; + + fireEvent("cancel", notification); + } + } + + /** + * Cancel all scheduled notifications. + */ + private void cancelAll() { + getNotificationMgr().cancelAll(); + fireEvent("cancelall"); + } + + /** + * Clear multiple local notifications without canceling them. + * + * @param ids + * Set of local notification IDs + */ + private void clear(JSONArray ids){ + for (int i = 0; i < ids.length(); i++) { + int id = ids.optInt(i, 0); + + Notification notification = + getNotificationMgr().clear(id); + + if (notification == null) + continue; + + fireEvent("clear", notification); + } + } + + /** + * Clear all triggered notifications without canceling them. + */ + private void clearAll() { + getNotificationMgr().clearAll(); + fireEvent("clearall"); + } + + /** + * If a notification with an ID is present. + * + * @param id + * Notification ID + * @param command + * The callback context used when calling back into JavaScript. + */ + private void isPresent (int id, CallbackContext command) { + boolean exist = getNotificationMgr().exist(id); + + PluginResult result = new PluginResult( + PluginResult.Status.OK, exist); + + command.sendPluginResult(result); + } + + /** + * If a notification with an ID is scheduled. + * + * @param id + * Notification ID + * @param command + * The callback context used when calling back into JavaScript. + */ + private void isScheduled (int id, CallbackContext command) { + boolean exist = getNotificationMgr().exist( + id, Notification.Type.SCHEDULED); + + PluginResult result = new PluginResult( + PluginResult.Status.OK, exist); + + command.sendPluginResult(result); + } + + /** + * If a notification with an ID is triggered. + * + * @param id + * Notification ID + * @param command + * The callback context used when calling back into JavaScript. + */ + private void isTriggered (int id, CallbackContext command) { + boolean exist = getNotificationMgr().exist( + id, Notification.Type.TRIGGERED); + + PluginResult result = new PluginResult( + PluginResult.Status.OK, exist); + + command.sendPluginResult(result); + } + + /** + * Set of IDs from all existent notifications. + * + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getAllIds (CallbackContext command) { + List ids = getNotificationMgr().getIds(); + + command.success(new JSONArray(ids)); + } + + /** + * Set of IDs from all scheduled notifications. + * + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getScheduledIds (CallbackContext command) { + List ids = getNotificationMgr().getIdsByType( + Notification.Type.SCHEDULED); + + command.success(new JSONArray(ids)); + } + + /** + * Set of IDs from all triggered notifications. + * + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getTriggeredIds (CallbackContext command) { + List ids = getNotificationMgr().getIdsByType( + Notification.Type.TRIGGERED); + + command.success(new JSONArray(ids)); + } + + /** + * Options from local notification. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getSingle (JSONArray ids, CallbackContext command) { + getOptions(ids.optString(0), Notification.Type.ALL, command); + } + + /** + * Options from scheduled notification. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getSingleScheduled (JSONArray ids, CallbackContext command) { + getOptions(ids.optString(0), Notification.Type.SCHEDULED, command); + } + + /** + * Options from triggered notification. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getSingleTriggered (JSONArray ids, CallbackContext command) { + getOptions(ids.optString(0), Notification.Type.TRIGGERED, command); + } + + /** + * Set of options from local notification. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getAll (JSONArray ids, CallbackContext command) { + getOptions(ids, Notification.Type.ALL, command); + } + + /** + * Set of options from scheduled notifications. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getScheduled (JSONArray ids, CallbackContext command) { + getOptions(ids, Notification.Type.SCHEDULED, command); + } + + /** + * Set of options from triggered notifications. + * + * @param ids + * Set of local notification IDs + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getTriggered (JSONArray ids, CallbackContext command) { + getOptions(ids, Notification.Type.TRIGGERED, command); + } + + /** + * Options from local notification. + * + * @param id + * Set of local notification IDs + * @param type + * The local notification life cycle type + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getOptions (String id, Notification.Type type, + CallbackContext command) { + + JSONArray ids = new JSONArray().put(id); + PluginResult result; + + List options = + getNotificationMgr().getOptionsBy(type, toList(ids)); + + if (options.isEmpty()) { + // Status.NO_RESULT led to no callback invocation :( + // Status.OK led to no NPE and crash + result = new PluginResult(PluginResult.Status.NO_RESULT); + } else { + result = new PluginResult(PluginResult.Status.OK, options.get(0)); + } + + command.sendPluginResult(result); + } + + /** + * Set of options from local notifications. + * + * @param ids + * Set of local notification IDs + * @param type + * The local notification life cycle type + * @param command + * The callback context used when calling back into JavaScript. + */ + private void getOptions (JSONArray ids, Notification.Type type, + CallbackContext command) { + + List options; + + if (ids.length() == 0) { + options = getNotificationMgr().getOptionsByType(type); + } else { + options = getNotificationMgr().getOptionsBy(type, toList(ids)); + } + + command.success(new JSONArray(options)); + } + + /** + * Call all pending callbacks after the deviceready event has been fired. + */ + private static synchronized void deviceready () { + isInBackground = false; + deviceready = true; + + for (String js : eventQueue) { + sendJavascript(js); + } + + eventQueue.clear(); + } + + /** + * Fire given event on JS side. Does inform all event listeners. + * + * @param event + * The event name + */ + private void fireEvent (String event) { + fireEvent(event, null); + } + + /** + * Fire given event on JS side. Does inform all event listeners. + * + * @param event + * The event name + * @param notification + * Optional local notification to pass the id and properties. + */ + static void fireEvent (String event, Notification notification) { + String state = getApplicationState(); + String params = "\"" + state + "\""; + + if (notification != null) { + params = notification.toString() + "," + params; + } + + String js = "cordova.plugins.notification.local.core.fireEvent(" + + "\"" + event + "\"," + params + ")"; + + sendJavascript(js); + } + + /** + * Use this instead of deprecated sendJavascript + * + * @param js + * JS code snippet as string + */ + private static synchronized void sendJavascript(final String js) { + + if (!deviceready) { + eventQueue.add(js); + return; + } + Runnable jsLoader = new Runnable() { + public void run() { + webView.loadUrl("javascript:" + js); + } + }; + try { + Method post = webView.getClass().getMethod("post",Runnable.class); + post.invoke(webView,jsLoader); + } catch(Exception e) { + + ((Activity)(webView.getContext())).runOnUiThread(jsLoader); + } + } + + /** + * Convert JSON array of integers to List. + * + * @param ary + * Array of integers + */ + private List toList (JSONArray ary) { + ArrayList list = new ArrayList(); + + for (int i = 0; i < ary.length(); i++) { + list.add(ary.optInt(i)); + } + + return list; + } + + /** + * Current application state. + * + * @return + * "background" or "foreground" + */ + static String getApplicationState () { + return isInBackground ? "background" : "foreground"; + } + + /** + * Notification manager instance. + */ + private Manager getNotificationMgr() { + return Manager.getInstance(cordova.getActivity()); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/RestoreReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/RestoreReceiver.java new file mode 100644 index 0000000..675ea7c --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/RestoreReceiver.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.localnotification; + +import de.appplant.cordova.plugin.notification.AbstractRestoreReceiver; +import de.appplant.cordova.plugin.notification.Builder; +import de.appplant.cordova.plugin.notification.Notification; + +/** + * This class is triggered upon reboot of the device. It needs to re-register + * the alarms with the AlarmManager since these alarms are lost in case of + * reboot. + */ +public class RestoreReceiver extends AbstractRestoreReceiver { + + /** + * Called when a local notification need to be restored. + * + * @param notification + * Wrapper around the local notification + */ + @Override + public void onRestore (Notification notification) { + if (notification.isScheduled()) { + notification.schedule(); + } else { + notification.cancel(); + } + } + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + @Override + public Notification buildNotification (Builder builder) { + return builder + .setTriggerReceiver(TriggerReceiver.class) + .setClearReceiver(ClearReceiver.class) + .setClickActivity(ClickActivity.class) + .build(); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/TriggerReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/TriggerReceiver.java new file mode 100644 index 0000000..3c423c0 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/TriggerReceiver.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.localnotification; + +import de.appplant.cordova.plugin.notification.Builder; +import de.appplant.cordova.plugin.notification.Notification; + +/** + * The alarm receiver is triggered when a scheduled alarm is fired. This class + * reads the information in the intent and displays this information in the + * Android notification bar. The notification uses the default notification + * sound and it vibrates the phone. + */ +public class TriggerReceiver extends de.appplant.cordova.plugin.notification.TriggerReceiver { + + /** + * Called when a local notification was triggered. Does present the local + * notification, re-schedule the alarm if necessary and fire trigger event. + * + * @param notification + * Wrapper around the local notification + * @param updated + * If an update has triggered or the original + */ + @Override + public void onTrigger (Notification notification, boolean updated) { + super.onTrigger(notification, updated); + + if (!updated) { + LocalNotification.fireEvent("trigger", notification); + } + } + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + @Override + public Notification buildNotification (Builder builder) { + return builder + .setTriggerReceiver(TriggerReceiver.class) + .setClickActivity(ClickActivity.class) + .setClearReceiver(ClearReceiver.class) + .build(); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClearReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClearReceiver.java new file mode 100644 index 0000000..94d2a19 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClearReceiver.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Abstract delete receiver for local notifications. Creates the local + * notification and calls the event functions for further proceeding. + */ +abstract public class AbstractClearReceiver extends BroadcastReceiver { + + /** + * Called when the notification was cleared from the notification center. + * + * @param context + * Application context + * @param intent + * Received intent with content data + */ + @Override + public void onReceive(Context context, Intent intent) { + Bundle bundle = intent.getExtras(); + JSONObject options; + + try { + String data = bundle.getString(Options.EXTRA); + options = new JSONObject(data); + } catch (JSONException e) { + e.printStackTrace(); + return; + } + + Notification notification = + new Builder(context, options).build(); + + onClear(notification); + } + + /** + * Called when a local notification was cleared from outside of the app. + * + * @param notification + * Wrapper around the local notification + */ + abstract public void onClear (Notification notification); + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClickActivity.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClickActivity.java new file mode 100644 index 0000000..5b70e14 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClickActivity.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Abstract content receiver activity for local notifications. Creates the + * local notification and calls the event functions for further proceeding. + */ +abstract public class AbstractClickActivity extends Activity { + + /** + * Called when local notification was clicked to launch the main intent. + * + * @param state + * Saved instance state + */ + @Override + public void onCreate (Bundle state) { + super.onCreate(state); + + Intent intent = getIntent(); + Bundle bundle = intent.getExtras(); + Context context = getApplicationContext(); + + try { + String data = bundle.getString(Options.EXTRA); + JSONObject options = new JSONObject(data); + + Builder builder = + new Builder(context, options); + + Notification notification = + buildNotification(builder); + + onClick(notification); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + /** + * Fixes "Unable to resume activity" error. + * Theme_NoDisplay: Activities finish themselves before being resumed. + */ + @Override + protected void onResume() { + super.onResume(); + finish(); + } + + /** + * Called when local notification was clicked by the user. + * + * @param notification + * Wrapper around the local notification + */ + abstract public void onClick (Notification notification); + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + abstract public Notification buildNotification (Builder builder); + + /** + * Launch main intent from package. + */ + public void launchApp() { + Context context = getApplicationContext(); + String pkgName = context.getPackageName(); + + Intent intent = context + .getPackageManager() + .getLaunchIntentForPackage(pkgName); + + intent.addFlags( + Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); + + context.startActivity(intent); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractRestoreReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractRestoreReceiver.java new file mode 100644 index 0000000..8a1f365 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractRestoreReceiver.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import org.json.JSONObject; + +import java.util.List; + +/** + * This class is triggered upon reboot of the device. It needs to re-register + * the alarms with the AlarmManager since these alarms are lost in case of + * reboot. + */ +abstract public class AbstractRestoreReceiver extends BroadcastReceiver { + + /** + * Called on device reboot. + * + * @param context + * Application context + * @param intent + * Received intent with content data + */ + @Override + public void onReceive (Context context, Intent intent) { + Manager notificationMgr = + Manager.getInstance(context); + + List options = + notificationMgr.getOptions(); + + for (JSONObject data : options) { + Builder builder = new Builder(context, data); + + Notification notification = + buildNotification(builder); + + onRestore(notification); + } + } + + /** + * Called when a local notification need to be restored. + * + * @param notification + * Wrapper around the local notification + */ + abstract public void onRestore (Notification notification); + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + abstract public Notification buildNotification (Builder builder); + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractTriggerReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractTriggerReceiver.java new file mode 100644 index 0000000..459e6d8 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractTriggerReceiver.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Calendar; + +/** + * Abstract broadcast receiver for local notifications. Creates the + * notification options and calls the event functions for further proceeding. + */ +abstract public class AbstractTriggerReceiver extends BroadcastReceiver { + + /** + * Called when an alarm was triggered. + * + * @param context + * Application context + * @param intent + * Received intent with content data + */ + @Override + public void onReceive(Context context, Intent intent) { + Bundle bundle = intent.getExtras(); + Options options; + + try { + String data = bundle.getString(Options.EXTRA); + JSONObject dict = new JSONObject(data); + + options = new Options(context).parse(dict); + } catch (JSONException e) { + e.printStackTrace(); + return; + } + + if (options == null) + return; + + if (isFirstAlarmInFuture(options)) + return; + + Builder builder = new Builder(options); + Notification notification = buildNotification(builder); + boolean updated = notification.isUpdate(false); + + onTrigger(notification, updated); + } + + /** + * Called when a local notification was triggered. + * + * @param notification + * Wrapper around the local notification + * @param updated + * If an update has triggered or the original + */ + abstract public void onTrigger (Notification notification, boolean updated); + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + abstract public Notification buildNotification (Builder builder); + + /* + * If you set a repeating alarm at 11:00 in the morning and it + * should trigger every morning at 08:00 o'clock, it will + * immediately fire. E.g. Android tries to make up for the + * 'forgotten' reminder for that day. Therefore we ignore the event + * if Android tries to 'catch up'. + */ + private Boolean isFirstAlarmInFuture (Options options) { + Notification notification = new Builder(options).build(); + + if (!notification.isRepeating()) + return false; + + Calendar now = Calendar.getInstance(); + Calendar alarm = Calendar.getInstance(); + + alarm.setTime(notification.getOptions().getTriggerDate()); + + int alarmHour = alarm.get(Calendar.HOUR_OF_DAY); + int alarmMin = alarm.get(Calendar.MINUTE); + int currentHour = now.get(Calendar.HOUR_OF_DAY); + int currentMin = now.get(Calendar.MINUTE); + + return (currentHour != alarmHour && currentMin != alarmMin); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AssetUtil.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AssetUtil.java new file mode 100644 index 0000000..66662e5 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AssetUtil.java @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.content.Context; +import android.content.res.AssetManager; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.StrictMode; +import android.util.Log; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.UUID; + +/** + * Util class to map unified asset URIs to native URIs. URIs like file:/// + * map to absolute paths while file:// point relatively to the www folder + * within the asset resources. And res:// means a resource from the native + * res folder. Remote assets are accessible via http:// for example. + */ +class AssetUtil { + + // Name of the storage folder + private static final String STORAGE_FOLDER = "/localnotification"; + + // Placeholder URI for default sound + private static final String DEFAULT_SOUND = "res://platform_default"; + + // Ref to the context passed through the constructor to access the + // resources and app directory. + private final Context context; + + /** + * Constructor + * + * @param context + * Application context + */ + private AssetUtil(Context context) { + this.context = context; + } + + /** + * Static method to retrieve class instance. + * + * @param context + * Application context + */ + static AssetUtil getInstance(Context context) { + return new AssetUtil(context); + } + + /** + * Parse path path to native URI. + * + * @param path + * Path to path file + */ + Uri parseSound (String path) { + + if (path == null || path.isEmpty()) + return Uri.EMPTY; + + if (path.equalsIgnoreCase(DEFAULT_SOUND)) { + return RingtoneManager.getDefaultUri(RingtoneManager + .TYPE_NOTIFICATION); + } + + return parse(path); + } + + /** + * The URI for a path. + * + * @param path + * The given path + */ + Uri parse (String path) { + + if (path.startsWith("res:")) { + return getUriForResourcePath(path); + } else if (path.startsWith("file:///")) { + return getUriFromPath(path); + } else if (path.startsWith("file://")) { + return getUriFromAsset(path); + } else if (path.startsWith("http")){ + return getUriFromRemote(path); + } + + return Uri.EMPTY; + } + + /** + * URI for a file. + * + * @param path + * Absolute path like file:///... + * + * @return + * URI pointing to the given path + */ + private Uri getUriFromPath(String path) { + String absPath = path.replaceFirst("file://", ""); + File file = new File(absPath); + + if (!file.exists()) { + Log.e("Asset", "File not found: " + file.getAbsolutePath()); + return Uri.EMPTY; + } + + return Uri.fromFile(file); + } + + /** + * URI for an asset. + * + * @param path + * Asset path like file://... + * + * @return + * URI pointing to the given path + */ + private Uri getUriFromAsset(String path) { + String resPath = path.replaceFirst("file:/", "www"); + String fileName = resPath.substring(resPath.lastIndexOf('/') + 1); + File file = getTmpFile(fileName); + + if (file == null) { + Log.e("Asset", "Missing external cache dir"); + return Uri.EMPTY; + } + + try { + AssetManager assets = context.getAssets(); + FileOutputStream outStream = new FileOutputStream(file); + InputStream inputStream = assets.open(resPath); + + copyFile(inputStream, outStream); + + outStream.flush(); + outStream.close(); + + return Uri.fromFile(file); + + } catch (Exception e) { + Log.e("Asset", "File not found: assets/" + resPath); + e.printStackTrace(); + } + + return Uri.EMPTY; + } + + /** + * The URI for a resource. + * + * @param path + * The given relative path + * + * @return + * URI pointing to the given path + */ + private Uri getUriForResourcePath(String path) { + String resPath = path.replaceFirst("res://", ""); + int resId = getResIdForDrawable(resPath); + File file = getTmpFile(); + + if (resId == 0) { + Log.e("Asset", "File not found: " + resPath); + return Uri.EMPTY; + } + + if (file == null) { + Log.e("Asset", "Missing external cache dir"); + return Uri.EMPTY; + } + + try { + Resources res = context.getResources(); + FileOutputStream outStream = new FileOutputStream(file); + InputStream inputStream = res.openRawResource(resId); + copyFile(inputStream, outStream); + + outStream.flush(); + outStream.close(); + + return Uri.fromFile(file); + + } catch (Exception e) { + e.printStackTrace(); + } + + return Uri.EMPTY; + } + + /** + * Uri from remote located content. + * + * @param path + * Remote address + * + * @return + * Uri of the downloaded file + */ + private Uri getUriFromRemote(String path) { + File file = getTmpFile(); + + if (file == null) { + Log.e("Asset", "Missing external cache dir"); + return Uri.EMPTY; + } + + try { + URL url = new URL(path); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + + StrictMode.ThreadPolicy policy = + new StrictMode.ThreadPolicy.Builder().permitAll().build(); + + StrictMode.setThreadPolicy(policy); + + connection.setRequestProperty("Connection", "close"); + connection.setConnectTimeout(5000); + connection.connect(); + + InputStream input = connection.getInputStream(); + FileOutputStream outStream = new FileOutputStream(file); + + copyFile(input, outStream); + + outStream.flush(); + outStream.close(); + + return Uri.fromFile(file); + + } catch (MalformedURLException e) { + Log.e("Asset", "Incorrect URL"); + e.printStackTrace(); + } catch (FileNotFoundException e) { + Log.e("Asset", "Failed to create new File from HTTP Content"); + e.printStackTrace(); + } catch (IOException e) { + Log.e("Asset", "No Input can be created from http Stream"); + e.printStackTrace(); + } + + return Uri.EMPTY; + } + + /** + * Copy content from input stream into output stream. + * + * @param in + * The input stream + * @param out + * The output stream + */ + private void copyFile(InputStream in, OutputStream out) throws IOException { + byte[] buffer = new byte[1024]; + int read; + + while ((read = in.read(buffer)) != -1) { + out.write(buffer, 0, read); + } + } + + /** + * Resource ID for drawable. + * + * @param resPath + * Resource path as string + */ + int getResIdForDrawable(String resPath) { + int resId = getResIdForDrawable(getPkgName(), resPath); + + if (resId == 0) { + resId = getResIdForDrawable("android", resPath); + } + + return resId; + } + + /** + * Resource ID for drawable. + * + * @param clsName + * Relative package or global android name space + * @param resPath + * Resource path as string + */ + int getResIdForDrawable(String clsName, String resPath) { + String drawable = getBaseName(resPath); + int resId = 0; + + try { + Class cls = Class.forName(clsName + ".R$drawable"); + + resId = (Integer) cls.getDeclaredField(drawable).get(Integer.class); + } catch (Exception ignore) {} + + return resId; + } + + /** + * Convert drawable resource to bitmap. + * + * @param drawable + * Drawable resource name + */ + Bitmap getIconFromDrawable (String drawable) { + Resources res = context.getResources(); + int iconId; + + iconId = getResIdForDrawable(getPkgName(), drawable); + + if (iconId == 0) { + iconId = getResIdForDrawable("android", drawable); + } + + if (iconId == 0) { + iconId = android.R.drawable.screen_background_dark_transparent; + } + + return BitmapFactory.decodeResource(res, iconId); + } + + /** + * Convert URI to Bitmap. + * + * @param uri + * Internal image URI + */ + Bitmap getIconFromUri (Uri uri) throws IOException { + InputStream input = context.getContentResolver().openInputStream(uri); + + return BitmapFactory.decodeStream(input); + } + + /** + * Extract name of drawable resource from path. + * + * @param resPath + * Resource path as string + */ + private String getBaseName (String resPath) { + String drawable = resPath; + + if (drawable.contains("/")) { + drawable = drawable.substring(drawable.lastIndexOf('/') + 1); + } + + if (resPath.contains(".")) { + drawable = drawable.substring(0, drawable.lastIndexOf('.')); + } + + return drawable; + } + + /** + * Returns a file located under the external cache dir of that app. + * + * @return + * File with a random UUID name + */ + private File getTmpFile () { + // If random UUID is not be enough see + // https://github.com/LukePulverenti/cordova-plugin-local-notifications/blob/267170db14044cbeff6f4c3c62d9b766b7a1dd62/src/android/notification/AssetUtil.java#L255 + return getTmpFile(UUID.randomUUID().toString()); + } + + /** + * Returns a file located under the external cache dir of that app. + * + * @param name + * The name of the file + * @return + * File with the provided name + */ + private File getTmpFile (String name) { + File dir = context.getExternalCacheDir(); + + if (dir == null) { + Log.e("Asset", "Missing external cache dir"); + return null; + } + + String storage = dir.toString() + STORAGE_FOLDER; + + //noinspection ResultOfMethodCallIgnored + new File(storage).mkdir(); + + return new File(storage, name); + } + + /** + * Package name specified by context. + */ + private String getPkgName () { + return context.getPackageName(); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Builder.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Builder.java new file mode 100644 index 0000000..55eb1d3 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Builder.java @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.support.v4.app.NotificationCompat; + +import org.json.JSONObject; + +import java.util.Random; + +/** + * Builder class for local notifications. Build fully configured local + * notification specified by JSON object passed from JS side. + */ +public class Builder { + + // Application context passed by constructor + private final Context context; + + // Notification options passed by JS + private final Options options; + + // Receiver to handle the trigger event + private Class triggerReceiver; + + // Receiver to handle the clear event + private Class clearReceiver = ClearReceiver.class; + + // Activity to handle the click event + private Class clickActivity = ClickActivity.class; + + /** + * Constructor + * + * @param context + * Application context + * @param options + * Notification options + */ + public Builder(Context context, JSONObject options) { + this.context = context; + this.options = new Options(context).parse(options); + } + + /** + * Constructor + * + * @param options + * Notification options + */ + public Builder(Options options) { + this.context = options.getContext(); + this.options = options; + } + + /** + * Set trigger receiver. + * + * @param receiver + * Broadcast receiver + */ + public Builder setTriggerReceiver(Class receiver) { + this.triggerReceiver = receiver; + return this; + } + + /** + * Set clear receiver. + * + * @param receiver + * Broadcast receiver + */ + public Builder setClearReceiver(Class receiver) { + this.clearReceiver = receiver; + return this; + } + + /** + * Set click activity. + * + * @param activity + * Activity + */ + public Builder setClickActivity(Class activity) { + this.clickActivity = activity; + return this; + } + + /** + * Creates the notification with all its options passed through JS. + */ + public Notification build() { + Uri sound = options.getSoundUri(); + int smallIcon = options.getSmallIcon(); + NotificationCompat.Builder builder; + + builder = new NotificationCompat.Builder(context) + .setDefaults(0) + .setContentTitle(options.getTitle()) + .setContentText(options.getText()) + .setNumber(options.getBadgeNumber()) + .setTicker(options.getText()) + .setAutoCancel(options.isAutoClear()) + .setOngoing(options.isOngoing()) + .setColor(options.getColor()) + .setLights(options.getLedColor(), 100, 100); + + if (sound != null) { + builder.setSound(sound); + } + + if (smallIcon == 0) { + builder.setSmallIcon(options.getIcon()); + } else { + builder.setSmallIcon(options.getSmallIcon()); + builder.setLargeIcon(options.getIconBitmap()); + } + + applyDeleteReceiver(builder); + applyContentReceiver(builder); + + return new Notification(context, options, builder, triggerReceiver); + } + + /** + * Set intent to handle the delete event. Will clean up some persisted + * preferences. + * + * @param builder + * Local notification builder instance + */ + private void applyDeleteReceiver(NotificationCompat.Builder builder) { + + if (clearReceiver == null) + return; + + Intent intent = new Intent(context, clearReceiver) + .setAction(options.getIdStr()) + .putExtra(Options.EXTRA, options.toString()); + + PendingIntent deleteIntent = PendingIntent.getBroadcast( + context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + + builder.setDeleteIntent(deleteIntent); + } + + /** + * Set intent to handle the click event. Will bring the app to + * foreground. + * + * @param builder + * Local notification builder instance + */ + private void applyContentReceiver(NotificationCompat.Builder builder) { + + if (clickActivity == null) + return; + + Intent intent = new Intent(context, clickActivity) + .putExtra(Options.EXTRA, options.toString()) + .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); + + int reqCode = new Random().nextInt(); + + PendingIntent contentIntent = PendingIntent.getActivity( + context, reqCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); + + builder.setContentIntent(contentIntent); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClearReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClearReceiver.java new file mode 100644 index 0000000..761b6c5 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClearReceiver.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +/** + * The clear intent receiver is triggered when the user clears a + * notification manually. It un-persists the cleared notification from the + * shared preferences. + */ +public class ClearReceiver extends AbstractClearReceiver { + + /** + * Called when a local notification was cleared from outside of the app. + * + * @param notification + * Wrapper around the local notification + */ + @Override + public void onClear (Notification notification) { + notification.clear(); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClickActivity.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClickActivity.java new file mode 100644 index 0000000..dcc0390 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClickActivity.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +/** + * The receiver activity is triggered when a notification is clicked by a user. + * The activity calls the background callback and brings the launch intent + * up to foreground. + */ +public class ClickActivity extends AbstractClickActivity { + + /** + * Called when local notification was clicked by the user. Will + * move the app to foreground. + * + * @param notification + * Wrapper around the local notification + */ + @Override + public void onClick(Notification notification) { + launchApp(); + + if (notification.isRepeating()) { + notification.clear(); + } else { + notification.cancel(); + } + } + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + public Notification buildNotification (Builder builder) { + return builder.build(); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Manager.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Manager.java new file mode 100644 index 0000000..9af3c94 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Manager.java @@ -0,0 +1,458 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.app.NotificationManager; +import android.content.Context; +import android.content.SharedPreferences; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static de.appplant.cordova.plugin.notification.Notification.PREF_KEY; + +/** + * Central way to access all or single local notifications set by specific + * state like triggered or scheduled. Offers shortcut ways to schedule, + * cancel or clear local notifications. + */ +public class Manager { + + // Context passed through constructor and used for notification builder. + private Context context; + + /** + * Constructor + * + * @param context + * Application context + */ + private Manager(Context context){ + this.context = context; + } + + /** + * Static method to retrieve class instance. + * + * @param context + * Application context + */ + public static Manager getInstance(Context context) { + return new Manager(context); + } + + /** + * Schedule local notification specified by JSON object. + * + * @param options + * JSON object with set of options + * @param receiver + * Receiver to handle the trigger event + */ + public Notification schedule (JSONObject options, Class receiver) { + return schedule(new Options(context).parse(options), receiver); + } + + /** + * Schedule local notification specified by options object. + * + * @param options + * Set of notification options + * @param receiver + * Receiver to handle the trigger event + */ + public Notification schedule (Options options, Class receiver) { + Notification notification = new Builder(options) + .setTriggerReceiver(receiver) + .build(); + + notification.schedule(); + + return notification; + } + + /** + * Clear local notification specified by ID. + * + * @param id + * The notification ID + * @param updates + * JSON object with notification options + * @param receiver + * Receiver to handle the trigger event + */ + public Notification update (int id, JSONObject updates, Class receiver) { + Notification notification = get(id); + + if (notification == null) + return null; + + notification.cancel(); + + JSONObject options = mergeJSONObjects( + notification.getOptions().getDict(), updates); + + try { + options.put("updated", true); + } catch (JSONException ignore) {} + + return schedule(options, receiver); + } + + /** + * Clear local notification specified by ID. + * + * @param id + * The notification ID + */ + public Notification clear (int id) { + Notification notification = get(id); + + if (notification != null) { + notification.clear(); + } + + return notification; + } + + /** + * Clear local notification specified by ID. + * + * @param id + * The notification ID + */ + public Notification cancel (int id) { + Notification notification = get(id); + + if (notification != null) { + notification.cancel(); + } + + return notification; + } + + /** + * Clear all local notifications. + */ + public void clearAll () { + List notifications = getAll(); + + for (Notification notification : notifications) { + notification.clear(); + } + + getNotMgr().cancelAll(); + } + + /** + * Cancel all local notifications. + */ + public void cancelAll () { + List notifications = getAll(); + + for (Notification notification : notifications) { + notification.cancel(); + } + + getNotMgr().cancelAll(); + } + + /** + * All local notifications IDs. + */ + public List getIds() { + Set keys = getPrefs().getAll().keySet(); + ArrayList ids = new ArrayList(); + + for (String key : keys) { + try { + ids.add(Integer.parseInt(key)); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + + return ids; + } + + /** + * All local notification IDs for given type. + * + * @param type + * The notification life cycle type + */ + public List getIdsByType(Notification.Type type) { + List notifications = getAll(); + ArrayList ids = new ArrayList(); + + for (Notification notification : notifications) { + if (notification.getType() == type) { + ids.add(notification.getId()); + } + } + + return ids; + } + + /** + * List of local notifications with matching ID. + * + * @param ids + * Set of notification IDs + */ + public List getByIds(List ids) { + ArrayList notifications = new ArrayList(); + + for (int id : ids) { + Notification notification = get(id); + + if (notification != null) { + notifications.add(notification); + } + } + + return notifications; + } + + /** + * List of all local notification. + */ + public List getAll() { + return getByIds(getIds()); + } + + /** + * List of local notifications from given type. + * + * @param type + * The notification life cycle type + */ + public List getByType(Notification.Type type) { + List notifications = getAll(); + ArrayList list = new ArrayList(); + + if (type == Notification.Type.ALL) + return notifications; + + for (Notification notification : notifications) { + if (notification.getType() == type) { + list.add(notification); + } + } + + return list; + } + + /** + * List of local notifications with matching ID from given type. + * + * @param type + * The notification life cycle type + * @param ids + * Set of notification IDs + */ + @SuppressWarnings("UnusedDeclaration") + public List getBy(Notification.Type type, List ids) { + ArrayList notifications = new ArrayList(); + + for (int id : ids) { + Notification notification = get(id); + + if (notification != null && notification.isScheduled()) { + notifications.add(notification); + } + } + + return notifications; + } + + /** + * If a notification with an ID exists. + * + * @param id + * Notification ID + */ + public boolean exist (int id) { + return get(id) != null; + } + + /** + * If a notification with an ID and type exists. + * + * @param id + * Notification ID + * @param type + * Notification type + */ + public boolean exist (int id, Notification.Type type) { + Notification notification = get(id); + + return notification != null && notification.getType() == type; + } + + /** + * List of properties from all local notifications. + */ + public List getOptions() { + return getOptionsById(getIds()); + } + + /** + * List of properties from local notifications with matching ID. + * + * @param ids + * Set of notification IDs + */ + public List getOptionsById(List ids) { + ArrayList options = new ArrayList(); + + for (int id : ids) { + Notification notification = get(id); + + if (notification != null) { + options.add(notification.getOptions().getDict()); + } + } + + return options; + } + + /** + * List of properties from all local notifications from given type. + * + * @param type + * The notification life cycle type + */ + public List getOptionsByType(Notification.Type type) { + ArrayList options = new ArrayList(); + List notifications = getByType(type); + + for (Notification notification : notifications) { + options.add(notification.getOptions().getDict()); + } + + return options; + } + + /** + * List of properties from local notifications with matching ID from + * given type. + * + * @param type + * The notification life cycle type + * @param ids + * Set of notification IDs + */ + public List getOptionsBy(Notification.Type type, + List ids) { + + if (type == Notification.Type.ALL) + return getOptionsById(ids); + + ArrayList options = new ArrayList(); + List notifications = getByIds(ids); + + for (Notification notification : notifications) { + if (notification.getType() == type) { + options.add(notification.getOptions().getDict()); + } + } + + return options; + } + + /** + * Get existent local notification. + * + * @param id + * Notification ID + */ + public Notification get(int id) { + Map alarms = getPrefs().getAll(); + String notId = Integer.toString(id); + JSONObject options; + + if (!alarms.containsKey(notId)) + return null; + + + try { + String json = alarms.get(notId).toString(); + options = new JSONObject(json); + } catch (JSONException e) { + e.printStackTrace(); + return null; + } + + Builder builder = new Builder(context, options); + + return builder.build(); + } + + /** + * Merge two JSON objects. + * + * @param obj1 + * JSON object + * @param obj2 + * JSON object with new options + */ + private JSONObject mergeJSONObjects (JSONObject obj1, JSONObject obj2) { + Iterator it = obj2.keys(); + + while (it.hasNext()) { + try { + String key = (String)it.next(); + + obj1.put(key, obj2.opt(key)); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + return obj1; + } + + /** + * Shared private preferences for the application. + */ + private SharedPreferences getPrefs () { + return context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE); + } + + /** + * Notification manager for the application. + */ + private NotificationManager getNotMgr () { + return (NotificationManager) context + .getSystemService(Context.NOTIFICATION_SERVICE); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Notification.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Notification.java new file mode 100644 index 0000000..ad36378 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Notification.java @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + + +import android.app.AlarmManager; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.support.v4.app.NotificationCompat; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Date; + +/** + * Wrapper class around OS notification class. Handles basic operations + * like show, delete, cancel for a single local notification instance. + */ +public class Notification { + + // Used to differ notifications by their life cycle state + public enum Type { + ALL, SCHEDULED, TRIGGERED + } + + // Default receiver to handle the trigger event + private static Class defaultReceiver = TriggerReceiver.class; + + // Key for private preferences + static final String PREF_KEY = "LocalNotification"; + + // Application context passed by constructor + private final Context context; + + // Notification options passed by JS + private final Options options; + + // Builder with full configuration + private final NotificationCompat.Builder builder; + + // Receiver to handle the trigger event + private Class receiver = defaultReceiver; + + /** + * Constructor + * + * @param context + * Application context + * @param options + * Parsed notification options + * @param builder + * Pre-configured notification builder + */ + protected Notification (Context context, Options options, + NotificationCompat.Builder builder, Class receiver) { + + this.context = context; + this.options = options; + this.builder = builder; + + this.receiver = receiver != null ? receiver : defaultReceiver; + } + + /** + * Get application context. + */ + public Context getContext () { + return context; + } + + /** + * Get notification options. + */ + public Options getOptions () { + return options; + } + + /** + * Get notification ID. + */ + public int getId () { + return options.getId(); + } + + /** + * If it's a repeating notification. + */ + public boolean isRepeating () { + return getOptions().getRepeatInterval() > 0; + } + + /** + * If the notification was in the past. + */ + public boolean wasInThePast () { + return new Date().after(options.getTriggerDate()); + } + + /** + * If the notification is scheduled. + */ + public boolean isScheduled () { + return isRepeating() || !wasInThePast(); + } + + /** + * If the notification is triggered. + */ + public boolean isTriggered () { + return wasInThePast(); + } + + /** + * If the notification is an update. + * + * @param keepFlag + * Set to false to remove the flag from the option map + */ + protected boolean isUpdate (boolean keepFlag) { + boolean updated = options.getDict().optBoolean("updated", false); + + if (!keepFlag) { + options.getDict().remove("updated"); + } + + return updated; + } + + /** + * Notification type can be one of pending or scheduled. + */ + public Type getType () { + return isScheduled() ? Type.SCHEDULED : Type.TRIGGERED; + } + + /** + * Schedule the local notification. + */ + public void schedule() { + long triggerTime = options.getTriggerTime(); + + persist(); + + // Intent gets called when the Notification gets fired + Intent intent = new Intent(context, receiver) + .setAction(options.getIdStr()) + .putExtra(Options.EXTRA, options.toString()); + + PendingIntent pi = PendingIntent.getBroadcast( + context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); + + if (isRepeating()) { + getAlarmMgr().setRepeating(AlarmManager.RTC_WAKEUP, + triggerTime, options.getRepeatInterval(), pi); + } else { + getAlarmMgr().set(AlarmManager.RTC_WAKEUP, triggerTime, pi); + } + } + + /** + * Clear the local notification without canceling repeating alarms. + */ + public void clear () { + + if (!isRepeating() && wasInThePast()) + unpersist(); + + if (!isRepeating()) + getNotMgr().cancel(getId()); + } + + /** + * Cancel the local notification. + * + * Create an intent that looks similar, to the one that was registered + * using schedule. Making sure the notification id in the action is the + * same. Now we can search for such an intent using the 'getService' + * method and cancel it. + */ + public void cancel() { + Intent intent = new Intent(context, receiver) + .setAction(options.getIdStr()); + + PendingIntent pi = PendingIntent. + getBroadcast(context, 0, intent, 0); + + getAlarmMgr().cancel(pi); + getNotMgr().cancel(options.getId()); + + unpersist(); + } + + /** + * Present the local notification to user. + */ + public void show () { + // TODO Show dialog when in foreground + showNotification(); + } + + /** + * Show as local notification when in background. + */ + @SuppressWarnings("deprecation") + private void showNotification () { + int id = getOptions().getId(); + + if (Build.VERSION.SDK_INT <= 15) { + // Notification for HoneyComb to ICS + getNotMgr().notify(id, builder.getNotification()); + } else { + // Notification for Jellybean and above + getNotMgr().notify(id, builder.build()); + } + } + + /** + * Count of triggers since schedule. + */ + public int getTriggerCountSinceSchedule() { + long now = System.currentTimeMillis(); + long triggerTime = options.getTriggerTime(); + + if (!wasInThePast()) + return 0; + + if (!isRepeating()) + return 1; + + return (int) ((now - triggerTime) / options.getRepeatInterval()); + } + + /** + * Encode options to JSON. + */ + public String toString() { + JSONObject dict = options.getDict(); + JSONObject json = new JSONObject(); + + try { + json = new JSONObject(dict.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + + json.remove("firstAt"); + json.remove("updated"); + json.remove("soundUri"); + json.remove("iconUri"); + + return json.toString(); + } + + /** + * Persist the information of this notification to the Android Shared + * Preferences. This will allow the application to restore the notification + * upon device reboot, app restart, retrieve notifications, aso. + */ + private void persist () { + SharedPreferences.Editor editor = getPrefs().edit(); + + editor.putString(options.getIdStr(), options.toString()); + + if (Build.VERSION.SDK_INT < 9) { + editor.commit(); + } else { + editor.apply(); + } + } + + /** + * Remove the notification from the Android shared Preferences. + */ + private void unpersist () { + SharedPreferences.Editor editor = getPrefs().edit(); + + editor.remove(options.getIdStr()); + + if (Build.VERSION.SDK_INT < 9) { + editor.commit(); + } else { + editor.apply(); + } + } + + /** + * Shared private preferences for the application. + */ + private SharedPreferences getPrefs () { + return context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE); + } + + /** + * Notification manager for the application. + */ + private NotificationManager getNotMgr () { + return (NotificationManager) context + .getSystemService(Context.NOTIFICATION_SERVICE); + } + + /** + * Alarm manager for the application. + */ + private AlarmManager getAlarmMgr () { + return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + } + + /** + * Set default receiver to handle the trigger event. + * + * @param receiver + * broadcast receiver + */ + public static void setDefaultTriggerReceiver (Class receiver) { + defaultReceiver = receiver; + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Options.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Options.java new file mode 100644 index 0000000..9d380d7 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Options.java @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +import android.app.AlarmManager; +import android.content.Context; +import android.graphics.Bitmap; +import android.net.Uri; +import android.support.v4.app.NotificationCompat; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Date; + +/** + * Wrapper around the JSON object passed through JS which contains all + * possible option values. Class provides simple readers and more advanced + * methods to convert independent values into platform specific values. + */ +public class Options { + + // Key name for bundled extras + static final String EXTRA = "NOTIFICATION_OPTIONS"; + + // The original JSON object + private JSONObject options = new JSONObject(); + + // Repeat interval + private long interval = 0; + + // Application context + private final Context context; + + // Asset util instance + private final AssetUtil assets; + + + /** + * Constructor + * + * @param context + * Application context + */ + public Options(Context context){ + this.context = context; + this.assets = AssetUtil.getInstance(context); + } + + /** + * Parse given JSON properties. + * + * @param options + * JSON properties + */ + public Options parse (JSONObject options) { + this.options = options; + + parseInterval(); + parseAssets(); + + return this; + } + + /** + * Parse repeat interval. + */ + private void parseInterval() { + String every = options.optString("every").toLowerCase(); + + if (every.isEmpty()) { + interval = 0; + } else + if (every.equals("second")) { + interval = 1000; + } else + if (every.equals("minute")) { + interval = AlarmManager.INTERVAL_FIFTEEN_MINUTES / 15; + } else + if (every.equals("hour")) { + interval = AlarmManager.INTERVAL_HOUR; + } else + if (every.equals("day")) { + interval = AlarmManager.INTERVAL_DAY; + } else + if (every.equals("week")) { + interval = AlarmManager.INTERVAL_DAY * 7; + } else + if (every.equals("month")) { + interval = AlarmManager.INTERVAL_DAY * 31; + } else + if (every.equals("quarter")) { + interval = AlarmManager.INTERVAL_HOUR * 2190; + } else + if (every.equals("year")) { + interval = AlarmManager.INTERVAL_DAY * 365; + } else { + try { + interval = Integer.parseInt(every) * 60000; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * Parse asset URIs. + */ + private void parseAssets() { + + if (options.has("iconUri") && !options.optBoolean("updated")) + return; + + Uri iconUri = assets.parse(options.optString("icon", "icon")); + Uri soundUri = assets.parseSound(options.optString("sound", null)); + + try { + options.put("iconUri", iconUri.toString()); + options.put("soundUri", soundUri.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + /** + * Application context. + */ + public Context getContext () { + return context; + } + + /** + * Wrapped JSON object. + */ + JSONObject getDict () { + return options; + } + + /** + * Text for the local notification. + */ + public String getText() { + return options.optString("text", ""); + } + + /** + * Repeat interval (day, week, month, year, aso.) + */ + public long getRepeatInterval() { + return interval; + } + + /** + * Badge number for the local notification. + */ + public int getBadgeNumber() { + return options.optInt("badge", 0); + } + + /** + * ongoing flag for local notifications. + */ + public Boolean isOngoing() { + return options.optBoolean("ongoing", false); + } + + /** + * autoClear flag for local notifications. + */ + public Boolean isAutoClear() { + return options.optBoolean("autoClear", false); + } + + /** + * ID for the local notification as a number. + */ + public Integer getId() { + return options.optInt("id", 0); + } + + /** + * ID for the local notification as a string. + */ + public String getIdStr() { + return getId().toString(); + } + + /** + * Trigger date. + */ + public Date getTriggerDate() { + return new Date(getTriggerTime()); + } + + /** + * Trigger date in milliseconds. + */ + public long getTriggerTime() { + return options.optLong("at", 0) * 1000; + } + + /** + * Title for the local notification. + */ + public String getTitle() { + String title = options.optString("title", ""); + + if (title.isEmpty()) { + title = context.getApplicationInfo().loadLabel( + context.getPackageManager()).toString(); + } + + return title; + } + + /** + * @return + * The notification color for LED + */ + public int getLedColor() { + String hex = options.optString("led", null); + + if (hex == null) { + return NotificationCompat.DEFAULT_LIGHTS; + } + + int aRGB = Integer.parseInt(hex, 16); + + return aRGB + 0xFF000000; + } + + /** + * @return + * The notification background color for the small icon + * Returns null, if no color is given. + */ + public int getColor() { + String hex = options.optString("color", null); + + if (hex == null) { + return NotificationCompat.COLOR_DEFAULT; + } + + int aRGB = Integer.parseInt(hex, 16); + + return aRGB + 0xFF000000; + } + + /** + * Sound file path for the local notification. + */ + public Uri getSoundUri() { + Uri uri = null; + + try{ + uri = Uri.parse(options.optString("soundUri")); + } catch (Exception e){ + e.printStackTrace(); + } + + return uri; + } + + /** + * Icon bitmap for the local notification. + */ + public Bitmap getIconBitmap() { + Bitmap bmp; + + try { + Uri uri = Uri.parse(options.optString("iconUri")); + bmp = assets.getIconFromUri(uri); + } catch (Exception e){ + e.printStackTrace(); + bmp = assets.getIconFromDrawable("icon"); + } + + return bmp; + } + + /** + * Icon resource ID for the local notification. + */ + public int getIcon () { + String icon = options.optString("icon", ""); + + int resId = assets.getResIdForDrawable(icon); + + if (resId == 0) { + resId = getSmallIcon(); + } + + if (resId == 0) { + resId = android.R.drawable.ic_popup_reminder; + } + + return resId; + } + + /** + * Small icon resource ID for the local notification. + */ + public int getSmallIcon () { + String icon = options.optString("smallIcon", ""); + + return assets.getResIdForDrawable(icon); + } + + /** + * JSON object as string. + */ + public String toString() { + return options.toString(); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/TriggerReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/TriggerReceiver.java new file mode 100644 index 0000000..9427e31 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/TriggerReceiver.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +package de.appplant.cordova.plugin.notification; + +/** + * The alarm receiver is triggered when a scheduled alarm is fired. This class + * reads the information in the intent and displays this information in the + * Android notification bar. The notification uses the default notification + * sound and it vibrates the phone. + */ +public class TriggerReceiver extends AbstractTriggerReceiver { + + /** + * Called when a local notification was triggered. Does present the local + * notification and re-schedule the alarm if necessary. + * + * @param notification + * Wrapper around the local notification + * @param updated + * If an update has triggered or the original + */ + @Override + public void onTrigger (Notification notification, boolean updated) { + notification.show(); + } + + /** + * Build notification specified by options. + * + * @param builder + * Notification builder + */ + @Override + public Notification buildNotification (Builder builder) { + return builder.build(); + } + +} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.h b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.h new file mode 100644 index 0000000..f86bf49 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import +#import + +@interface APPLocalNotification : CDVPlugin + +// Execute all queued events +- (void) deviceready:(CDVInvokedUrlCommand*)command; + +// Inform if the app has the permission to show notifications +- (void) hasPermission:(CDVInvokedUrlCommand*)command; +// Register permission to show notifications +- (void) registerPermission:(CDVInvokedUrlCommand*)command; + +// Schedule set of notifications +- (void) schedule:(CDVInvokedUrlCommand*)command; +// Update set of notifications +- (void) update:(CDVInvokedUrlCommand*)command; +// Cancel set of notifications +- (void) cancel:(CDVInvokedUrlCommand*)command; +// Cancel all notifications +- (void) cancelAll:(CDVInvokedUrlCommand*)command; +// Clear set of notifications +- (void) clear:(CDVInvokedUrlCommand*)command; +// Clear all notifications +- (void) clearAll:(CDVInvokedUrlCommand*)command; + +// If a notification with an ID is present +- (void) isPresent:(CDVInvokedUrlCommand*)command; +// If a notification with an ID is scheduled +- (void) isScheduled:(CDVInvokedUrlCommand*)command; +// If a notification with an ID is triggered +- (void) isTriggered:(CDVInvokedUrlCommand*)command; + +// List all ids from all local notifications +- (void) getAllIds:(CDVInvokedUrlCommand*)command; +// List all ids from all pending notifications +- (void) getScheduledIds:(CDVInvokedUrlCommand*)command; +// List all ids from all triggered notifications +- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command; + +// Propertys for given local notification +- (void) getSingle:(CDVInvokedUrlCommand*)command; +// Propertya for given scheduled notification +- (void) getSingleScheduled:(CDVInvokedUrlCommand*)command; +// Propertys for given triggered notification +- (void) getSingleTriggered:(CDVInvokedUrlCommand*)command; + +// Property list for given local notifications +- (void) getAll:(CDVInvokedUrlCommand*)command; +// Property list for given scheduled notifications +- (void) getScheduled:(CDVInvokedUrlCommand*)command; +// Property list for given triggered notifications +- (void) getTriggered:(CDVInvokedUrlCommand*)command; + +@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.m b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.m new file mode 100644 index 0000000..03a2d23 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.m @@ -0,0 +1,717 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "APPLocalNotification.h" +#import "APPLocalNotificationOptions.h" +#import "UIApplication+APPLocalNotification.h" +#import "UILocalNotification+APPLocalNotification.h" + +@interface APPLocalNotification () + +// Retrieves the application state +@property (readonly, getter=applicationState) NSString* applicationState; +// All events will be queued until deviceready has been fired +@property (readwrite, assign) BOOL deviceready; +// Event queue +@property (readonly, nonatomic, retain) NSMutableArray* eventQueue; +// Needed when calling `registerPermission` +@property (nonatomic, retain) CDVInvokedUrlCommand* command; + +@end + +@implementation APPLocalNotification + +@synthesize deviceready, eventQueue; + +#pragma mark - +#pragma mark Interface + +/** + * Execute all queued events. + */ +- (void) deviceready:(CDVInvokedUrlCommand*)command +{ + deviceready = YES; + + for (NSString* js in eventQueue) { + [self.commandDelegate evalJs:js]; + } + + [eventQueue removeAllObjects]; +} + +/** + * Schedule a set of notifications. + * + * @param properties + * A dict of properties for each notification + */ +- (void) schedule:(CDVInvokedUrlCommand*)command +{ + NSArray* notifications = command.arguments; + + [self.commandDelegate runInBackground:^{ + for (NSDictionary* options in notifications) { + UILocalNotification* notification; + + notification = [[UILocalNotification alloc] + initWithOptions:options]; + + [self scheduleLocalNotification:[notification copy]]; + [self fireEvent:@"schedule" notification:notification]; + + if (notifications.count > 1) { + [NSThread sleepForTimeInterval:0.01]; + } + } + + [self execCallback:command]; + }]; +} + +/** + * Update a set of notifications. + * + * @param properties + * A dict of properties for each notification + */ +- (void) update:(CDVInvokedUrlCommand*)command +{ + NSArray* notifications = command.arguments; + + [self.commandDelegate runInBackground:^{ + for (NSDictionary* options in notifications) { + NSNumber* id = [options objectForKey:@"id"]; + UILocalNotification* notification; + + notification = [self.app localNotificationWithId:id]; + + if (!notification) + continue; + + [self updateLocalNotification:[notification copy] + withOptions:options]; + + [self fireEvent:@"update" notification:notification]; + + if (notifications.count > 1) { + [NSThread sleepForTimeInterval:0.01]; + } + } + + [self execCallback:command]; + }]; +} + +/** + * Cancel a set of notifications. + * + * @param ids + * The IDs of the notifications + */ +- (void) cancel:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + for (NSNumber* id in command.arguments) { + UILocalNotification* notification; + + notification = [self.app localNotificationWithId:id]; + + if (!notification) + continue; + + [self.app cancelLocalNotification:notification]; + [self fireEvent:@"cancel" notification:notification]; + } + + [self execCallback:command]; + }]; +} + +/** + * Cancel all local notifications. + */ +- (void) cancelAll:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + [self cancelAllLocalNotifications]; + [self fireEvent:@"cancelall"]; + [self execCallback:command]; + }]; +} + +/** + * Clear a set of notifications. + * + * @param ids + * The IDs of the notifications + */ +- (void) clear:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + for (NSNumber* id in command.arguments) { + UILocalNotification* notification; + + notification = [self.app localNotificationWithId:id]; + + if (!notification) + continue; + + [self.app clearLocalNotification:notification]; + [self fireEvent:@"clear" notification:notification]; + } + + [self execCallback:command]; + }]; +} + +/** + * Clear all local notifications. + */ +- (void) clearAll:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + [self clearAllLocalNotifications]; + [self fireEvent:@"clearall"]; + [self execCallback:command]; + }]; +} + +/** + * If a notification by ID is present. + * + * @param id + * The ID of the notification + */ +- (void) isPresent:(CDVInvokedUrlCommand *)command +{ + [self isPresent:command type:NotifcationTypeAll]; +} + +/** + * If a notification by ID is scheduled. + * + * @param id + * The ID of the notification + */ +- (void) isScheduled:(CDVInvokedUrlCommand*)command +{ + [self isPresent:command type:NotifcationTypeScheduled]; +} + +/** + * Check if a notification with an ID is triggered. + * + * @param id + * The ID of the notification + */ +- (void) isTriggered:(CDVInvokedUrlCommand*)command +{ + [self isPresent:command type:NotifcationTypeTriggered]; +} + +/** + * Check if a notification with an ID exists. + * + * @param type + * The notification life cycle type + */ +- (void) isPresent:(CDVInvokedUrlCommand*)command + type:(APPLocalNotificationType)type; +{ + [self.commandDelegate runInBackground:^{ + NSNumber* id = [command argumentAtIndex:0]; + BOOL exist; + + CDVPluginResult* result; + + if (type == NotifcationTypeAll) { + exist = [self.app localNotificationExist:id]; + } else { + exist = [self.app localNotificationExist:id type:type]; + } + + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK + messageAsBool:exist]; + + [self.commandDelegate sendPluginResult:result + callbackId:command.callbackId]; + }]; +} + +/** + * List all ids from all local notifications. + */ +- (void) getAllIds:(CDVInvokedUrlCommand*)command +{ + [self getIds:command byType:NotifcationTypeAll]; +} + +/** + * List all ids from all pending notifications. + */ +- (void) getScheduledIds:(CDVInvokedUrlCommand*)command +{ + [self getIds:command byType:NotifcationTypeScheduled]; +} + +/** + * List all ids from all triggered notifications. + */ +- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command +{ + [self getIds:command byType:NotifcationTypeTriggered]; +} + +/** + * List of ids for given local notifications. + * + * @param type + * Notification life cycle type + * @param ids + * The IDs of the notifications + */ +- (void) getIds:(CDVInvokedUrlCommand*)command + byType:(APPLocalNotificationType)type; +{ + [self.commandDelegate runInBackground:^{ + CDVPluginResult* result; + NSArray* ids; + + if (type == NotifcationTypeAll) { + ids = [self.app localNotificationIds]; + } else { + ids = [self.app localNotificationIdsByType:type]; + } + + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK + messageAsArray:ids]; + + [self.commandDelegate sendPluginResult:result + callbackId:command.callbackId]; + }]; +} + +/** + * Propertys for given local notification. + */ +- (void) getSingle:(CDVInvokedUrlCommand*)command +{ + [self getOption:command byType:NotifcationTypeAll]; +} + +/** + * Propertya for given scheduled notification. + */ +- (void) getSingleScheduled:(CDVInvokedUrlCommand*)command +{ + [self getOption:command byType:NotifcationTypeScheduled]; +} + +// Propertys for given triggered notification +- (void) getSingleTriggered:(CDVInvokedUrlCommand*)command +{ + [self getOption:command byType:NotifcationTypeTriggered]; +} + +/** + * Property list for given local notifications. + * + * @param ids + * The IDs of the notifications + */ +- (void) getAll:(CDVInvokedUrlCommand*)command +{ + [self getOptions:command byType:NotifcationTypeAll]; +} + +/** + * Property list for given scheduled notifications. + * + * @param ids + * The IDs of the notifications + */ +- (void) getScheduled:(CDVInvokedUrlCommand*)command +{ + [self getOptions:command byType:NotifcationTypeScheduled]; +} + +/** + * Property list for given triggered notifications. + * + * @param ids + * The IDs of the notifications + */ +- (void) getTriggered:(CDVInvokedUrlCommand *)command +{ + [self getOptions:command byType:NotifcationTypeTriggered]; +} + +/** + * Propertys for given triggered notification. + * + * @param type + * Notification life cycle type + * @param ids + * The ID of the notification + */ +- (void) getOption:(CDVInvokedUrlCommand*)command + byType:(APPLocalNotificationType)type; +{ + [self.commandDelegate runInBackground:^{ + NSArray* ids = command.arguments; + NSArray* notifications; + CDVPluginResult* result; + + if (type == NotifcationTypeAll) { + notifications = [self.app localNotificationOptionsById:ids]; + } + else { + notifications = [self.app localNotificationOptionsByType:type + andId:ids]; + } + + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK + messageAsDictionary:[notifications firstObject]]; + + [self.commandDelegate sendPluginResult:result + callbackId:command.callbackId]; + }]; +} + +/** + * Property list for given triggered notifications. + * + * @param type + * Notification life cycle type + * @param ids + * The IDs of the notifications + */ +- (void) getOptions:(CDVInvokedUrlCommand*)command + byType:(APPLocalNotificationType)type; +{ + [self.commandDelegate runInBackground:^{ + NSArray* ids = command.arguments; + NSArray* notifications; + CDVPluginResult* result; + + if (type == NotifcationTypeAll && ids.count == 0) { + notifications = [self.app localNotificationOptions]; + } + else if (type == NotifcationTypeAll) { + notifications = [self.app localNotificationOptionsById:ids]; + } + else if (ids.count == 0) { + notifications = [self.app localNotificationOptionsByType:type]; + } + else { + notifications = [self.app localNotificationOptionsByType:type + andId:ids]; + } + + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK + messageAsArray:notifications]; + + [self.commandDelegate sendPluginResult:result + callbackId:command.callbackId]; + }]; +} + +/** + * Inform if the app has the permission to show + * badges and local notifications. + */ +- (void) hasPermission:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + CDVPluginResult* result; + BOOL hasPermission; + + hasPermission = [self.app hasPermissionToScheduleLocalNotifications]; + + result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK + messageAsBool:hasPermission]; + + [self.commandDelegate sendPluginResult:result + callbackId:command.callbackId]; + }]; +} + +/** + * Ask for permission to show badges. + */ +- (void) registerPermission:(CDVInvokedUrlCommand*)command +{ + if ([[UIApplication sharedApplication] + respondsToSelector:@selector(registerUserNotificationSettings:)]) + { + _command = command; + + [self.commandDelegate runInBackground:^{ + [self.app registerPermissionToScheduleLocalNotifications]; + }]; + } else { + [self hasPermission:command]; + } +} + +#pragma mark - +#pragma mark Core Logic + +/** + * Schedule the local notification. + */ +- (void) scheduleLocalNotification:(UILocalNotification*)notification +{ + [self cancelForerunnerLocalNotification:notification]; + [self.app scheduleLocalNotification:notification]; +} + +/** + * Update the local notification. + */ +- (void) updateLocalNotification:(UILocalNotification*)notification + withOptions:(NSDictionary*)newOptions +{ + NSMutableDictionary* options = [notification.userInfo mutableCopy]; + + [options addEntriesFromDictionary:newOptions]; + [options setObject:[NSDate date] forKey:@"updatedAt"]; + + notification = [[UILocalNotification alloc] + initWithOptions:options]; + + [self scheduleLocalNotification:notification]; +} + +/** + * Cancel all local notifications. + */ +- (void) cancelAllLocalNotifications +{ + [self.app cancelAllLocalNotifications]; + [self.app setApplicationIconBadgeNumber:0]; +} + +/** + * Clear all local notifications. + */ +- (void) clearAllLocalNotifications +{ + [self.app clearAllLocalNotifications]; + [self.app setApplicationIconBadgeNumber:0]; +} + +/** + * Cancel a maybe given forerunner with the same ID. + */ +- (void) cancelForerunnerLocalNotification:(UILocalNotification*)notification +{ + NSNumber* id = notification.options.id; + UILocalNotification* forerunner; + + forerunner = [self.app localNotificationWithId:id]; + + if (!forerunner) + return; + + [self.app cancelLocalNotification:forerunner]; +} + +/** + * Cancels all non-repeating local notification older then + * a specific amount of seconds + */ +- (void) cancelAllNotificationsWhichAreOlderThen:(float)seconds +{ + NSArray* notifications; + + notifications = [self.app localNotifications]; + + for (UILocalNotification* notification in notifications) + { + if (![notification isRepeating] + && notification.timeIntervalSinceFireDate > seconds) + { + [self.app cancelLocalNotification:notification]; + [self fireEvent:@"cancel" notification:notification]; + } + } +} + +#pragma mark - +#pragma mark Delegates + +/** + * Calls the cancel or trigger event after a local notification was received. + * Cancels the local notification if autoCancel was set to true. + */ +- (void) didReceiveLocalNotification:(NSNotification*)localNotification +{ + UILocalNotification* notification = [localNotification object]; + + if ([notification userInfo] == NULL || [notification wasUpdated]) + return; + + NSTimeInterval timeInterval = [notification timeIntervalSinceLastTrigger]; + NSString* event = timeInterval < 0.2 && deviceready ? @"trigger" : @"click"; + + [self fireEvent:event notification:notification]; + + if (![event isEqualToString:@"click"]) + return; + + if ([notification isRepeating]) { + [self fireEvent:@"clear" notification:notification]; + } else { + [self.app cancelLocalNotification:notification]; + [self fireEvent:@"cancel" notification:notification]; + } +} + +/** + * Called when app has started + * (by clicking on a local notification). + */ +- (void) didFinishLaunchingWithOptions:(NSNotification*)notification +{ + NSDictionary* launchOptions = [notification userInfo]; + + UILocalNotification* localNotification; + + localNotification = [launchOptions objectForKey: + UIApplicationLaunchOptionsLocalNotificationKey]; + + if (localNotification) { + [self didReceiveLocalNotification: + [NSNotification notificationWithName:CDVLocalNotification + object:localNotification]]; + } +} + +/** + * Called on otification settings registration is completed. + */ +- (void) didRegisterUserNotificationSettings:(UIUserNotificationSettings*)settings +{ + if (_command) { + [self hasPermission:_command]; + _command = NULL; + } +} + +#pragma mark - +#pragma mark Life Cycle + +/** + * Registers obervers after plugin was initialized. + */ +- (void) pluginInitialize +{ + eventQueue = [[NSMutableArray alloc] init]; +} + +/** + * Clears all single repeating notifications which are older then 5 days + * before the app terminates. + */ +- (void) onAppTerminate +{ + [self cancelAllNotificationsWhichAreOlderThen:432000]; +} + +#pragma mark - +#pragma mark Helper + +/** + * Retrieves the application state + * + * @return + * Either "background" or "foreground" + */ +- (NSString*) applicationState +{ + UIApplicationState state = [self.app applicationState]; + + bool isActive = state == UIApplicationStateActive; + + return isActive ? @"foreground" : @"background"; +} + +/** + * Simply invokes the callback without any parameter. + */ +- (void) execCallback:(CDVInvokedUrlCommand*)command +{ + CDVPluginResult *result = [CDVPluginResult + resultWithStatus:CDVCommandStatus_OK]; + + [self.commandDelegate sendPluginResult:result + callbackId:command.callbackId]; +} + +/** + * Short hand for shared application instance. + */ +- (UIApplication*) app +{ + return [UIApplication sharedApplication]; +} + +/** + * Fire general event. + */ +- (void) fireEvent:(NSString*)event +{ + [self fireEvent:event notification:NULL]; +} + +/** + * Fire event for local notification. + */ +- (void) fireEvent:(NSString*)event notification:(UILocalNotification*)notification +{ + NSString* js; + NSString* params = [NSString stringWithFormat: + @"\"%@\"", self.applicationState]; + + if (notification) { + NSString* args = [notification encodeToJSON]; + + params = [NSString stringWithFormat: + @"%@,'%@'", + args, self.applicationState]; + } + + js = [NSString stringWithFormat: + @"cordova.plugins.notification.local.core.fireEvent('%@', %@)", + event, params]; + + if (deviceready) { + [self.commandDelegate evalJs:js]; + } else { + [self.eventQueue addObject:js]; + } +} + +@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.h b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.h new file mode 100644 index 0000000..73c3ef7 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +@interface APPLocalNotificationOptions : NSObject + +- (id) initWithDict:(NSDictionary*)dict; + +@property (readonly, getter=id) NSNumber* id; +@property (readonly, getter=badgeNumber) NSInteger badgeNumber; +@property (readonly, getter=alertBody) NSString* alertBody; +@property (readonly, getter=soundName) NSString* soundName; +@property (readonly, getter=fireDate) NSDate* fireDate; +@property (readonly, getter=repeatInterval) NSCalendarUnit repeatInterval; +@property (readonly, getter=userInfo) NSDictionary* userInfo; + +// If it's a repeating notification +- (BOOL) isRepeating; + +@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.m b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.m new file mode 100644 index 0000000..6918919 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.m @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "APPLocalNotificationOptions.h" + +// Default sound ressource path +NSString* const DEFAULT_SOUND = @"res://platform_default"; + +@interface APPLocalNotificationOptions () + +// The dictionary which contains all notification properties +@property(nonatomic, retain) NSDictionary* dict; + +@end + +@implementation APPLocalNotificationOptions + +@synthesize dict; + +#pragma mark - +#pragma mark Initialization + +/** + * Initialize the object with the given options when calling on JS side: + * notification.local.add(options) + */ +- (id) initWithDict:(NSDictionary*)dictionary +{ + self = [self init]; + + self.dict = dictionary; + + return self; +} + +#pragma mark - +#pragma mark Attributes + +/** + * The notification's ID. + */ +- (NSNumber*) id +{ + NSInteger id = [[dict objectForKey:@"id"] integerValue]; + + return [NSNumber numberWithInteger:id]; +} + +/** + * The notification's title. + */ +- (NSString*) title +{ + return [dict objectForKey:@"title"]; +} + +/** + * The notification's message. + */ +- (NSString*) text +{ + return [dict objectForKey:@"text"]; +} + +/** + * The notification's badge number. + */ +- (NSInteger) badgeNumber +{ + return [[dict objectForKey:@"badge"] intValue]; +} + +#pragma mark - +#pragma mark Complex Attributes + +/** + * The notification's alert body. + */ +- (NSString*) alertBody +{ + NSString* title = [self title]; + NSString* msg = [self text]; + + NSString* alertBody = msg; + + if (![self stringIsNullOrEmpty:title]) + { + alertBody = [NSString stringWithFormat:@"%@\n%@", + title, msg]; + } + + return alertBody; +} + +/** + * The notification's sound path. + */ +- (NSString*) soundName +{ + NSString* path = [dict objectForKey:@"sound"]; + + if ([self stringIsNullOrEmpty:path]) + return NULL; + + if ([path isEqualToString:DEFAULT_SOUND]) + return UILocalNotificationDefaultSoundName; + + if ([path hasPrefix:@"file:/"]) + return [self soundNameForAsset:path]; + + if ([path hasPrefix:@"res:"]) + return [self soundNameForResource:path]; + + return NULL; +} + +/** + * The notification's fire date. + */ +- (NSDate*) fireDate +{ + double timestamp = [[dict objectForKey:@"at"] + doubleValue]; + + return [NSDate dateWithTimeIntervalSince1970:timestamp]; +} + +/** + * The notification's repeat interval. + */ +- (NSCalendarUnit) repeatInterval +{ + NSString* interval = [dict objectForKey:@"every"]; + + if ([self stringIsNullOrEmpty:interval]) { + return NSCalendarUnitEra; + } + else if ([interval isEqualToString:@"second"]) { + return NSCalendarUnitSecond; + } + else if ([interval isEqualToString:@"minute"]) { + return NSCalendarUnitMinute; + } + else if ([interval isEqualToString:@"hour"]) { + return NSCalendarUnitHour; + } + else if ([interval isEqualToString:@"day"]) { + return NSCalendarUnitDay; + } + else if ([interval isEqualToString:@"week"]) { + return NSCalendarUnitWeekOfYear; + } + else if ([interval isEqualToString:@"month"]) { + return NSCalendarUnitMonth; + } + else if ([interval isEqualToString:@"quarter"]) { + return NSCalendarUnitQuarter; + } + else if ([interval isEqualToString:@"year"]) { + return NSCalendarUnitYear; + } + + return NSCalendarUnitEra; +} + +#pragma mark - +#pragma mark Methods + +/** + * The notification's user info dict. + */ +- (NSDictionary*) userInfo +{ + if ([dict objectForKey:@"updatedAt"]) { + NSMutableDictionary* data = [dict mutableCopy]; + + [data removeObjectForKey:@"updatedAt"]; + + return data; + } + + return dict; +} + +/** + * If it's a repeating notification. + */ +- (BOOL) isRepeating +{ + NSCalendarUnit interval = self.repeatInterval; + + return !(interval == NSCalendarUnitEra || interval == 0); +} + +#pragma mark - +#pragma mark Helpers + +/** + * Convert relative path to valid sound name attribute. + */ +- (NSString*) soundNameForAsset:(NSString*)path +{ + return [path stringByReplacingOccurrencesOfString:@"file:/" + withString:@"www"]; +} + +/** + * Convert resource path to valid sound name attribute. + */ +- (NSString*) soundNameForResource:(NSString*)path +{ + return [path pathComponents].lastObject; +} + +/** + * If the string is empty. + */ +- (BOOL) stringIsNullOrEmpty:(NSString*)str +{ + if (str == (NSString*)[NSNull null]) + return YES; + + if ([str isEqualToString:@""]) + return YES; + + return NO; +} + +@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.h b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.h new file mode 100644 index 0000000..a18568e --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "UILocalNotification+APPLocalNotification.h" + +@interface UIApplication (APPLocalNotification) + +@property (readonly, getter=localNotifications) NSArray* localNotifications; +@property (readonly, getter=localNotificationIds) NSArray* localNotificationIds; + +// If the app has the permission to schedule local notifications +- (BOOL) hasPermissionToScheduleLocalNotifications; +// Ask for permission to schedule local notifications +- (void) registerPermissionToScheduleLocalNotifications; + +// List of all local notification IDs from given type +- (NSArray*) localNotificationIdsByType:(APPLocalNotificationType)type; + +// If local notification with ID exists +- (BOOL) localNotificationExist:(NSNumber*)id; +// If local notification with ID and type exists +- (BOOL) localNotificationExist:(NSNumber*)id type:(APPLocalNotificationType)type; + +// Local notification by ID +- (UILocalNotification*) localNotificationWithId:(NSNumber*)id; +// Local notification by ID and type +- (UILocalNotification*) localNotificationWithId:(NSNumber*)id andType:(APPLocalNotificationType)type; + +// Property list from all local notifications +- (NSArray*) localNotificationOptions; +// Property list from given local notifications +- (NSArray*) localNotificationOptionsById:(NSArray*)ids; +// Property list from all local notifications with type constraint +- (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type; +// Property list from given local notifications with type constraint +- (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type andId:(NSArray*)ids; + +// Clear single local notfications +- (void) clearLocalNotification:(UILocalNotification*)notification; +// Clear all local notfications +- (void) clearAllLocalNotifications; + +@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.m b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.m new file mode 100644 index 0000000..21fab31 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.m @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "UIApplication+APPLocalNotification.h" +#import "UILocalNotification+APPLocalNotification.h" + +@implementation UIApplication (APPLocalNotification) + +#pragma mark - +#pragma mark Permissions + +/** + * If the app has the permission to schedule local notifications. + */ +- (BOOL) hasPermissionToScheduleLocalNotifications +{ + if ([[UIApplication sharedApplication] + respondsToSelector:@selector(registerUserNotificationSettings:)]) + { + UIUserNotificationType types; + UIUserNotificationSettings *settings; + + settings = [[UIApplication sharedApplication] + currentUserNotificationSettings]; + + types = UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound; + + return (settings.types & types); + } else { + return YES; + } +} + +/** + * Ask for permission to schedule local notifications. + */ +- (void) registerPermissionToScheduleLocalNotifications +{ + if ([[UIApplication sharedApplication] + respondsToSelector:@selector(registerUserNotificationSettings:)]) + { + UIUserNotificationType types; + UIUserNotificationSettings *settings; + + settings = [[UIApplication sharedApplication] + currentUserNotificationSettings]; + + types = settings.types|UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound; + + settings = [UIUserNotificationSettings settingsForTypes:types + categories:nil]; + + [[UIApplication sharedApplication] + registerUserNotificationSettings:settings]; + } +} + +#pragma mark - +#pragma mark LocalNotifications + +/** + * List of all local notifications which have been added + * but not yet removed from the notification center. + */ +- (NSArray*) localNotifications +{ + NSArray* scheduledNotifications = self.scheduledLocalNotifications; + NSMutableArray* notifications = [[NSMutableArray alloc] init]; + + for (UILocalNotification* notification in scheduledNotifications) + { + if (notification) { + [notifications addObject:notification]; + } + } + + return notifications; +} + +/** + * List of all triggered local notifications which have been scheduled + * and not yet removed the notification center. + */ +- (NSArray*) triggeredLocalNotifications +{ + NSArray* notifications = self.localNotifications; + NSMutableArray* triggeredNotifications = [[NSMutableArray alloc] init]; + + for (UILocalNotification* notification in notifications) + { + if ([notification isTriggered]) { + [triggeredNotifications addObject:notification]; + } + } + + return triggeredNotifications; +} + +/** + * List of all local notifications IDs. + */ +- (NSArray*) localNotificationIds +{ + NSArray* notifications = self.localNotifications; + NSMutableArray* ids = [[NSMutableArray alloc] init]; + + for (UILocalNotification* notification in notifications) + { + [ids addObject:notification.options.id]; + } + + return ids; +} + +/** + * List of all local notifications IDs from given type. + * + * @param type + * Notification life cycle type + */ +- (NSArray*) localNotificationIdsByType:(APPLocalNotificationType)type +{ + NSArray* notifications = self.localNotifications; + NSMutableArray* ids = [[NSMutableArray alloc] init]; + + for (UILocalNotification* notification in notifications) + { + if (notification.type == type) { + [ids addObject:notification.options.id]; + } + } + + return ids; +} + +/* + * If local notification with ID exists. + * + * @param id + * Notification ID + */ +- (BOOL) localNotificationExist:(NSNumber*)id +{ + return [self localNotificationWithId:id] != NULL; +} + +/* If local notification with ID and type exists + * + * @param id + * Notification ID + * @param type + * Notification life cycle type + */ +- (BOOL) localNotificationExist:(NSNumber*)id type:(APPLocalNotificationType)type +{ + return [self localNotificationWithId:id andType:type] != NULL; +} + +/** + * Get local notification with ID. + * + * @param id + * Notification ID + */ +- (UILocalNotification*) localNotificationWithId:(NSNumber*)id +{ + NSArray* notifications = self.localNotifications; + + for (UILocalNotification* notification in notifications) + { + NSString* fid = [NSString stringWithFormat:@"%@", notification.options.id]; + + if ([fid isEqualToString:[id stringValue]]) { + return notification; + } + } + + return NULL; +} + +/* + * Get local notification with ID and type. + * + * @param id + * Notification ID + * @param type + * Notification life cycle type + */ +- (UILocalNotification*) localNotificationWithId:(NSNumber*)id andType:(APPLocalNotificationType)type +{ + UILocalNotification* notification = [self localNotificationWithId:id]; + + if (notification && notification.type == type) + return notification; + + return NULL; +} + +/** + * List of properties from all notifications. + */ +- (NSArray*) localNotificationOptions +{ + NSArray* notifications = self.localNotifications; + NSMutableArray* options = [[NSMutableArray alloc] init]; + + for (UILocalNotification* notification in notifications) + { + [options addObject:notification.options.userInfo]; + } + + return options; +} + +/** + * List of properties from all local notifications from given type. + * + * @param type + * Notification life cycle type + */ +- (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type +{ + NSArray* notifications = self.localNotifications; + NSMutableArray* options = [[NSMutableArray alloc] init]; + + for (UILocalNotification* notification in notifications) + { + if (notification.type == type) { + [options addObject:notification.options.userInfo]; + } + } + + return options; +} + +/** + * List of properties from given local notifications. + * + * @param ids + * Notification IDs + */ +- (NSArray*) localNotificationOptionsById:(NSArray*)ids +{ + UILocalNotification* notification; + NSMutableArray* options = [[NSMutableArray alloc] init]; + + for (NSNumber* id in ids) + { + notification = [self localNotificationWithId:id]; + + if (notification) { + [options addObject:notification.options.userInfo]; + } + } + + return options; +} + +/** + * List of properties from given local notifications. + * + * @param type + * Notification life cycle type + * @param ids + * Notification IDs + */ +- (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type andId:(NSArray*)ids +{ + UILocalNotification* notification; + NSMutableArray* options = [[NSMutableArray alloc] init]; + + for (NSNumber* id in ids) + { + notification = [self localNotificationWithId:id]; + + if (notification && notification.type == type) { + [options addObject:notification.options.userInfo]; + } + } + + return options; +} + +/* + * Clear all local notfications. + */ +- (void) clearAllLocalNotifications +{ + NSArray* notifications = self.triggeredLocalNotifications; + + for (UILocalNotification* notification in notifications) { + [self clearLocalNotification:notification]; + } +} + +/* + * Clear single local notfication. + * + * @param notification + * The local notification object + */ +- (void) clearLocalNotification:(UILocalNotification*)notification +{ + [self cancelLocalNotification:notification]; + + if ([notification isRepeating]) { + notification.fireDate = notification.options.fireDate; + + [self scheduleLocalNotification:notification]; + }; +} + +@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.h b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.h new file mode 100644 index 0000000..ac0fdc2 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "APPLocalNotificationOptions.h" + +typedef NS_ENUM(NSUInteger, APPLocalNotificationType) { + NotifcationTypeAll = 0, + NotifcationTypeScheduled = 1, + NotifcationTypeTriggered = 2 +}; + +@interface UILocalNotification (APPLocalNotification) + +// Initialize a new local notification +- (id) initWithOptions:(NSDictionary*)dict; +// The options provided by the plug-in +- (APPLocalNotificationOptions*) options; +// Timeinterval since last trigger date +- (double) timeIntervalSinceLastTrigger; +// Timeinterval since fire date +- (double) timeIntervalSinceFireDate; +// If the fire date was in the past +- (BOOL) wasInThePast; +// If the notification was already scheduled +- (BOOL) isScheduled; +// If the notification was already triggered +- (BOOL) isTriggered; +// If the notification was updated +- (BOOL) wasUpdated; +// If it's a repeating notification +- (BOOL) isRepeating; +// Notifciation type +- (APPLocalNotificationType) type; +// Encode the user info dict to JSON +- (NSString*) encodeToJSON; + +@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.m b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.m new file mode 100644 index 0000000..3837253 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.m @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. + * + * @APPPLANT_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apache License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://opensource.org/licenses/Apache-2.0/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPPLANT_LICENSE_HEADER_END@ + */ + +#import "UILocalNotification+APPLocalNotification.h" +#import "APPLocalNotificationOptions.h" +#import + +static char optionsKey; + +NSInteger const APPLocalNotificationTypeScheduled = 1; +NSInteger const APPLocalNotificationTypeTriggered = 2; + +@implementation UILocalNotification (APPLocalNotification) + +#pragma mark - +#pragma mark Init + +/** + * Initialize a local notification with the given options when calling on JS side: + * notification.local.add(options) + */ +- (id) initWithOptions:(NSDictionary*)dict +{ + self = [self init]; + + [self setUserInfo:dict]; + [self __init]; + + return self; +} + +/** + * Applies the given options when calling on JS side: + * notification.local.add(options) + + */ +- (void) __init +{ + APPLocalNotificationOptions* options = self.options; + + self.fireDate = options.fireDate; + self.timeZone = [NSTimeZone defaultTimeZone]; + self.applicationIconBadgeNumber = options.badgeNumber; + self.repeatInterval = options.repeatInterval; + self.alertBody = options.alertBody; + self.soundName = options.soundName; + + if ([self wasInThePast]) { + self.fireDate = [NSDate date]; + } +} + +#pragma mark - +#pragma mark Methods + +/** + * The options provided by the plug-in. + */ +- (APPLocalNotificationOptions*) options +{ + APPLocalNotificationOptions* options = [self getOptions]; + + if (!options) { + options = [[APPLocalNotificationOptions alloc] + initWithDict:[self userInfo]]; + + [self setOptions:options]; + } + + return options; +} + +/** + * Get associated option object + */ +- (APPLocalNotificationOptions*) getOptions +{ + return objc_getAssociatedObject(self, &optionsKey); +} + +/** + * Set associated option object + */ +- (void) setOptions:(APPLocalNotificationOptions*)options +{ + objc_setAssociatedObject(self, &optionsKey, + options, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +/** + * The repeating interval in seconds. + */ +- (int) repeatIntervalInSeconds +{ + switch (self.repeatInterval) { + case NSCalendarUnitMinute: + return 60; + + case NSCalendarUnitHour: + return 60000; + + case NSCalendarUnitDay: + case NSCalendarUnitWeekOfYear: + case NSCalendarUnitMonth: + case NSCalendarUnitYear: + return 86400; + + default: + return 1; + } +} + +/** + * Timeinterval since fire date. + */ +- (double) timeIntervalSinceFireDate +{ + NSDate* now = [NSDate date]; + NSDate* fireDate = self.fireDate; + + int timespan = [now timeIntervalSinceDate:fireDate]; + + return timespan; +} + +/** + * Timeinterval since last trigger date. + */ +- (double) timeIntervalSinceLastTrigger +{ + int timespan = [self timeIntervalSinceFireDate]; + + if ([self isRepeating]) { + timespan = timespan % [self repeatIntervalInSeconds]; + } + + return timespan; +} + +/** + * Encode the user info dict to JSON. + */ +- (NSString*) encodeToJSON +{ + NSString* json; + NSData* data; + NSMutableDictionary* obj = [self.userInfo mutableCopy]; + + [obj removeObjectForKey:@"updatedAt"]; + + if (obj == NULL || obj.count == 0) + return json; + + data = [NSJSONSerialization dataWithJSONObject:obj + options:NSJSONWritingPrettyPrinted + error:NULL]; + + json = [[NSString alloc] initWithData:data + encoding:NSUTF8StringEncoding]; + + return [json stringByReplacingOccurrencesOfString:@"\n" + withString:@""]; +} + +#pragma mark - +#pragma mark State + +/** + * If the fire date was in the past. + */ +- (BOOL) wasInThePast +{ + return [self timeIntervalSinceLastTrigger] > 0; +} + +// If the notification was already scheduled +- (BOOL) isScheduled +{ + return [self isRepeating] || ![self wasInThePast]; +} + +/** + * If the notification was already triggered. + */ +- (BOOL) isTriggered +{ + NSDate* now = [NSDate date]; + NSDate* fireDate = self.fireDate; + + bool isLaterThanFireDate = !([now compare:fireDate] == NSOrderedAscending); + + return isLaterThanFireDate; +} + +/** + * If the notification was updated. + */ +- (BOOL) wasUpdated +{ + NSDate* now = [NSDate date]; + NSDate* updatedAt = [self.userInfo objectForKey:@"updatedAt"]; + + if (updatedAt == NULL) + return NO; + + int timespan = [now timeIntervalSinceDate:updatedAt]; + + return timespan < 1; +} + +/** + * If it's a repeating notification. + */ +- (BOOL) isRepeating +{ + return [self.options isRepeating]; +} + +/** + * Process state type of the local notification. + */ +- (APPLocalNotificationType) type +{ + return [self isTriggered] ? NotifcationTypeTriggered : NotifcationTypeScheduled; +} + +@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationCore.js b/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationCore.js new file mode 100644 index 0000000..beb1814 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationCore.js @@ -0,0 +1,437 @@ +/* + Copyright 2013-2015 appPlant UG + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + + +var proxy = require('de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy'); + +var Notifications = Windows.UI.Notifications; + + +proxy.core = { + + /** + * Executes all queued events. + */ + deviceready: function () { + var plugin = cordova.plugins.notification.local, + events = this.eventQueue; + + this.isReady = true; + + for (var i = 0; i < events.length; i++) { + plugin.fireEvent.apply(plugin, events[i]); + } + + this.eventQueue = []; + }, + + /** + * Schedules new local notifications. + * + * @param {Object[]} notifications + * Array of local notifications + * @param {String} event + * 'schedule' or 'update' + */ + schedule: function (notifications) { + var triggerFn = function (notification) { + this.updateBadge(notification.badge); + this.fireEvent('trigger', notification); + }; + + for (var i = 0; i < notifications.length; i++) { + var options = notifications[i], + notification = this.build(options); + + this.cancelLocalNotification(options.id); + this.scheduleLocalNotification(notification, options); + this.scheduleBackupNotification(notification, options); + this.fireEvent('schedule', options); + this.callOnTrigger(options, triggerFn); + } + }, + + /** + * Schedules a single local notification. + * + * @param {Windows.Data.Xml.Dom.XmlDocument} notification + * The local notification + * @param {Object} options + * Local notification properties + */ + scheduleLocalNotification: function (notification, options) { + var interval = this.getRepeatInterval(options.every), + triggerTime = new Date((options.at * 1000)), + now = new Date().getTime(), + toast; + + if (triggerTime <= now) { + triggerTime = new Date(now + 10); + } + + try { + if (interval !== 0 && interval < 360001 && interval > 59999) { + toast = new Notifications.ScheduledToastNotification( + notification, triggerTime, interval, 5); + } else { + toast = new Notifications.ScheduledToastNotification( + notification, triggerTime); + } + } catch (e) { + console.error(e); + return; + } + + toast.id = options.id; + toast.tag = 'Toast' + toast.id; + + this.getToastNotifier().addToSchedule(toast); + }, + + /** + * Schedules a backup local notification 10 years later. + * + * @param {Object} notification + * The local notification + */ + scheduleBackupNotification: function (notification, options) { + var properties = Object.create(options); + + properties.id = options.id + '-2'; + properties.at = options.at + 315360000; // 10 years later + + this.scheduleLocalNotification(notification, properties); + }, + + /** + * Updates the badge number of the active tile. + * + * @param {Number} badge + * The badge number. Zero will clean the badge. + */ + updateBadge: function (badge) { + var notifications = Windows.UI.Notifications, + type = notifications.BadgeTemplateType.badgeNumber, + xml = notifications.BadgeUpdateManager.getTemplateContent(type), + attrs = xml.getElementsByTagName('badge'), + notification = new notifications.BadgeNotification(xml); + + attrs[0].setAttribute('value', badge); + + notifications.BadgeUpdateManager.createBadgeUpdaterForApplication() + .update(notification); + }, + + /** + * Updates existing notifications specified by IDs in options. + * + * @param {Object[]} notifications + * Array of local notifications + */ + update: function (notifications) { + for (var i = 0; i < notifications.length; i++) { + var updates = notifications[i], + options = getAll(updates.id || '0')[0]; + + this.updateLocalNotification(options, updates); + this.fireEvent('update', options); + } + }, + + /** + * Updates a single local notification. + * + * @param {Object} notification + * The local notification + * @param {Object} updates + * Updated properties + */ + updateLocalNotification: function (notification, updates) { + for (var key in updates) { + notification[key] = updates[key]; + } + + this.cancelLocalNotification(notification.id); + this.scheduleLocalNotification(notification); + }, + + /** + * Clears the specified notifications. + * + * @param {int[]} ids + * List of local notification IDs + */ + clear: function (ids) { + for (var i = 0; i < ids.length; i++) { + var id = ids[i], + notification = this.getAll([id])[0]; + + this.clearLocalNotification(id); + this.fireEvent('clear', notification); + } + }, + + /** + * Clears the local notification with the given ID. + * + * @param {String} id + * Local notification ID + */ + clearLocalNotification: function (id) { + var notification = this.getAll([id])[0]; + + try { + this.getToastHistory().remove('Toast' + id); + } catch (e) {/*Only Phones support the NotificationHistory*/ } + + if (this.isRepeating(notification)) + return; + + if (this.isTriggered(id) && !this.isScheduled(id)) { + this.cancelLocalNotification(id); + } + }, + + /** + * Clears all notifications. + */ + clearAll: function () { + var ids = this.getTriggeredIds(); + + for (var i = 0; i < ids.length; i++) { + this.clearLocalNotification(ids[i]); + } + + try { + this.getToastHistory().clear(); + } catch (e) {/*Only Phones support the NotificationHistory*/ } + this.fireEvent('clearall'); + }, + + /** + * Cancels all specified notifications. + * + * @param {int[]} ids + * List of local notification IDs + */ + cancel: function (ids) { + for (var i = 0; i < ids.length; i++) { + var id = ids[i], + notification = this.getAll([id])[0]; + + this.cancelLocalNotification(ids[i]); + this.fireEvent('cancel', notification); + } + }, + + /** + * Cancels the local notification with the given ID. + * + * @param {String} id + * Local notification ID + */ + cancelLocalNotification: function (id) { + var notifier = this.getToastNotifier(), + history = this.getToastHistory(), + toasts = this.getScheduledToasts(); + + try { + history.remove('Toast' + id); + } catch (e) {/*Only Phones support the NotificationHistory*/ } + + for (var i = 0; i < toasts.length; i++) { + var toast = toasts[i]; + + if (toast.id == id || toast.id == id + '-2') { + notifier.removeFromSchedule(toast); + } + } + }, + + /** + * Cancels all notifications. + */ + cancelAll: function () { + var ids = this.getAllIds(); + + for (var i = 0; i < ids.length; i++) { + this.cancelLocalNotification(ids[i]); + } + + try { + this.getToastHistory().clear(); + } catch (e) {/*Only Phones support the NotificationHistory*/ } + this.fireEvent('cancelall'); + }, + + /** + * Checks if a notification with an ID is present. + * + * @param {int} id + * Local notification ID + */ + isPresent: function (id) { + return !!this.findToastById(id); + }, + + /** + * Checks if a notification with an ID was scheduled. + * + * @param {int} id + * Local notification ID + */ + isScheduled: function (id) { + var toast = this.findToastById(id); + + return toast && this.isToastScheduled(toast); + }, + + /** + * Checks if a notification with an ID was triggered. + * + * @param {int} id + * Local notification ID + */ + isTriggered: function (id) { + var toast = this.findToastById(id); + + return toast && this.isToastTriggered(toast); + }, + + /** + * Lists all local notification IDs. + */ + getAllIds: function () { + var toasts = this.getScheduledToasts(), + ids = []; + + for (var i = 0; i < toasts.length; i++) { + var toast = toasts[i], + toastId = this.getToastId(toast); + + if (ids.indexOf(toastId) == -1) { + ids.push(toastId); + } + } + + return ids; + }, + + /** + * Lists all scheduled notification IDs. + */ + getScheduledIds: function () { + var toasts = this.getScheduledToasts(), + ids = []; + + for (var i = 0; i < toasts.length; i++) { + var toast = toasts[i]; + + if (!this.isToastScheduled(toast)) + continue; + + ids.push(this.getToastId(toast)); + } + + return ids; + }, + + /** + * Lists all scheduled notification IDs. + */ + getTriggeredIds: function () { + var toasts = this.getScheduledToasts(), + ids = []; + + for (var i = 0; i < toasts.length; i++) { + var toast = toasts[i]; + + if (!this.isToastTriggered(toast)) + continue; + + ids.push(this.getToastId(toast)); + } + + return ids; + }, + + /** + * Property list for given notifications. + * If called without IDs, all notification will be returned. + * + * @param {int[]} ids + * List of local notification IDs. + * @param {String?} type + * Local notification life cycle type + */ + getAll: function (ids, type) { + var toasts = this.getScheduledToasts(), + notifications = []; + + if (!ids || ids.length === 0) { + ids = this.getAllIds(); + } + + for (var index = 0; index < ids.length; index++) { + var id = ids[index], + toast = this.findToastById(id); + + if (!toast || type && this.getToastType(toast) != type) + continue; + + var json = toast.content.lastChild.lastChild.innerText; + + notifications.push(JSON.parse(json)); + } + + return notifications; + }, + + /** + * Property list for given notifications. + * If called without IDs, all notification will be returned. + * + * @param {int[]} ids + * List of local notification IDs + */ + getScheduled: function (ids) { + if (!ids || ids.length === 0) { + ids = this.getAllIds(); + } + + return this.getAll(ids, 'scheduled'); + }, + + /** + * Property list for given notifications. + * If called without IDs, all notification will be returned. + * + * @param {int[]} ids + * List of local notification IDs + */ + getTriggered: function (ids) { + if (!ids || ids.length === 0) { + ids = this.getAllIds(); + } + + return this.getAll(ids, 'triggered'); + }, +}; diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationProxy.js b/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationProxy.js new file mode 100644 index 0000000..2f7ed3d --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationProxy.js @@ -0,0 +1,311 @@ +/* + Copyright 2013-2015 appPlant UG + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +/** + * Executes all queued events. + */ +exports.deviceready = function () { + exports.core.deviceready(); +}; + +/** + * Schedule a new local notification. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {Object[]} notifications + * Array of local notifications + */ +exports.schedule = function (success, error, notifications) { + exports.core.schedule(notifications, 'schedule'); + + success(); +}; + +/** + * Update existing notifications specified by IDs in options. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {Object[]} notifications + * Array of local notifications + */ +exports.update = function (success, error, notifications) { + exports.core.update(notifications); + + success(); +}; + +/** + * Clear the specified notification. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {int[]} ids + * List of local notification IDs + */ +exports.clear = function (success, error, ids) { + exports.core.clear(ids, true); + + success(); +}; + +/** + * Clear all previously sheduled notifications. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.clearAll = function (success, error) { + exports.core.clearAll(); + + success(); +}; + +/** + * Cancel the specified notifications. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {int[]} ids + * List of local notification IDs + */ +exports.cancel = function (success, error, ids) { + exports.core.cancel(ids, true); + + success(); +}; + +/** + * Remove all previously registered notifications. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.cancelAll = function (success, error) { + exports.core.cancelAll(); + + success(); +}; + +/** + * Check if a notification with an ID is present. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {int} id + * Local notification ID + */ +exports.isPresent = function (success, error, args) { + var found = exports.core.isPresent(args[0]); + + success(found); +}; + +/** + * Check if a notification with an ID is scheduled. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {int} id + * Local notification ID + */ +exports.isScheduled = function (success, error, args) { + var found = exports.core.isScheduled(args[0]); + + success(found); +}; + +/** + * Check if a notification with an ID was triggered. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {int} id + * Local notification ID + */ +exports.isTriggered = function (success, error, args) { + var found = exports.core.isTriggered(args[0]); + + success(found); +}; + +/** + * List all local notification IDs. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.getAllIds = function (success, error) { + var ids = exports.core.getAllIds(); + + success(ids); +}; + +/** + * List all scheduled notification IDs. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.getScheduledIds = function (success, error) { + var ids = exports.core.getScheduledIds(); + + success(ids); +}; + +/** + * List all triggered notification IDs. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + */ +exports.getTriggeredIds = function (success, error) { + var ids = exports.core.getTriggeredIds(); + + success(ids); +}; + +/** + * Propertys for given notification. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {int[]} ids + * List of local notification IDs + */ +exports.getSingle = function (success, error, ids) { + var notification = exports.core.getAll(ids)[0]; + + success(notification); +}; + +/** + * Propertys for given scheduled notification. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {int[]} ids + * List of local notification IDs + */ +exports.getSingleScheduled = function (success, error, ids) { + var notification = exports.core.getScheduled(ids)[0]; + + success(notification); +}; + +/** + * Propertys for given triggered notification. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {int[]} ids + * List of local notification IDs + */ +exports.getSingleTriggered = function (success, error, ids) { + var notification = exports.core.getTriggered(ids)[0]; + + success(notification); +}; + +/** + * Property list for given notifications. + * If called without IDs, all notification will be returned. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {int[]} ids + * List of local notification IDs + */ +exports.getAll = function (success, error, ids) { + var notifications = exports.core.getAll(ids); + + success(notifications); +}; + +/** + * Property list for given triggered notifications. + * If called without IDs, all notification will be returned. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {int[]} ids + * List of local notification IDs + */ +exports.getScheduled = function (success, error, ids) { + var notifications = exports.core.getScheduled(ids); + + success(notifications); +}; + +/** + * Property list for given triggered notifications. + * If called without IDs, all notification will be returned. + * + * @param {Function} success + * Success callback + * @param {Function} error + * Error callback + * @param {int[]} ids + * List of local notification IDs + */ +exports.getTriggered = function (success, error, ids) { + var notifications = exports.core.getTriggered(ids); + + success(notifications); +}; + + +cordova.commandProxy.add('LocalNotification', exports); diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationUtil.js b/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationUtil.js new file mode 100644 index 0000000..5679254 --- /dev/null +++ b/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationUtil.js @@ -0,0 +1,443 @@ +/* + Copyright 2013-2015 appPlant UG + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + + +exports = require('de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy').core; + +var channel = require('cordova/channel'); + + +/*********** + * MEMBERS * + ***********/ + +// True if App is running, false if suspended +exports.isInBackground = true; + +// Indicates if the device is ready (to receive events) +exports.isReady = false; + +// Queues all events before deviceready +exports.eventQueue = []; + +/******** + * UTIL * + ********/ + +/** + * The repeating interval in milliseconds. + * + * @param {String} interval + * A number or a placeholder like `minute`. + * + * @return {Number} + * Interval in milliseconds + */ +exports.getRepeatInterval = function (every) { + + if (!every) + return 0; + + if (every == 'minute') + return 60000; + + if (every == 'hour') + return 360000; + + if (!NaN(every)) + return parseInt(every) * 60000; + + return 0; +}; + +/** + * If the notification is repeating. + * + * @param {Object} notification + * Local notification object + * + * @return Boolean + */ +exports.isRepeating = function (notification) { + return this.getRepeatInterval(notification.every) !== 0; +}; + +/** + * Parses sound file path. + * + * @param {String} path + * Relative path to sound resource + * + * @return {String} XML Tag for Sound-File + */ +exports.parseSound = function (path) { + if (!path.match(/^file/)) + return ''; + + var uri = this.parseUri(path), + audio = "
    @@ -49,11 +48,11 @@ @@ -72,7 +71,9 @@

    -

    +
    +

    +


    @@ -93,5 +94,27 @@

    + // Test the navigation bar by clicking on the 'REVIEW' link and checking the URL changes to '/review' + it('Has a working nav', function(done) { + var currentURL = this.driver.getCurrentUrl(); + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + setTimeout(restTest, 2000); + var currentURL = this.driver.getCurrentUrl(); + + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + diff --git a/www/node_modules/.bin/jasmine b/www/node_modules/.bin/jasmine new file mode 120000 index 0000000..d2c1bff --- /dev/null +++ b/www/node_modules/.bin/jasmine @@ -0,0 +1 @@ +../jasmine/bin/jasmine.js \ No newline at end of file diff --git a/www/node_modules/.bin/rimraf b/www/node_modules/.bin/rimraf new file mode 120000 index 0000000..4cd49a4 --- /dev/null +++ b/www/node_modules/.bin/rimraf @@ -0,0 +1 @@ +../rimraf/bin.js \ No newline at end of file diff --git a/www/node_modules/adm-zip/.idea/scopes/scope_settings.xml b/www/node_modules/adm-zip/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000..0d5175c --- /dev/null +++ b/www/node_modules/adm-zip/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/www/node_modules/adm-zip/MIT-LICENSE.txt b/www/node_modules/adm-zip/MIT-LICENSE.txt new file mode 100644 index 0000000..14c3ee5 --- /dev/null +++ b/www/node_modules/adm-zip/MIT-LICENSE.txt @@ -0,0 +1,21 @@ +Copyright (c) 2012 Another-D-Mention Software and other contributors, +http://www.another-d-mention.ro/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/www/node_modules/adm-zip/README.md b/www/node_modules/adm-zip/README.md new file mode 100644 index 0000000..030fab8 --- /dev/null +++ b/www/node_modules/adm-zip/README.md @@ -0,0 +1,64 @@ +# ADM-ZIP for NodeJS + +ADM-ZIP is a pure JavaScript implementation for zip data compression for [NodeJS](http://nodejs.org/). + +# Installation + +With [npm](http://npmjs.org) do: + + $ npm install adm-zip + +## What is it good for? +The library allows you to: + +* decompress zip files directly to disk or in memory buffers +* compress files and store them to disk in .zip format or in compressed buffers +* update content of/add new/delete files from an existing .zip + +# Dependencies +There are no other nodeJS libraries that ADM-ZIP is dependent of + +# Examples + +## Basic usage +```javascript + + var AdmZip = require('adm-zip'); + + // reading archives + var zip = new AdmZip("./my_file.zip"); + var zipEntries = zip.getEntries(); // an array of ZipEntry records + + zipEntries.forEach(function(zipEntry) { + console.log(zipEntry.toString()); // outputs zip entries information + if (zipEntry.entryName == "my_file.txt") { + console.log(zipEntry.data.toString('utf8')); + } + }); + // outputs the content of some_folder/my_file.txt + console.log(zip.readAsText("some_folder/my_file.txt")); + // extracts the specified file to the specified location + zip.extractEntryTo(/*entry name*/"some_folder/my_file.txt", /*target path*/"/home/me/tempfolder", /*maintainEntryPath*/false, /*overwrite*/true); + // extracts everything + zip.extractAllTo(/*target path*/"/home/me/zipcontent/", /*overwrite*/true); + + + // creating archives + var zip = new AdmZip(); + + // add file directly + zip.addFile("test.txt", new Buffer("inner content of the file"), "entry comment goes here"); + // add local file + zip.addLocalFile("/home/me/some_picture.png"); + // get everything as a buffer + var willSendthis = zip.toBuffer(); + // or write everything to disk + zip.writeZip(/*target file name*/"/home/me/files.zip"); + + + // ... more examples in the wiki +``` + +For more detailed information please check out the [wiki](https://github.com/cthackers/adm-zip/wiki). + +[![build status](https://secure.travis-ci.org/cthackers/adm-zip.png)](http://travis-ci.org/cthackers/adm-zip) diff --git a/www/node_modules/adm-zip/adm-zip.js b/www/node_modules/adm-zip/adm-zip.js new file mode 100644 index 0000000..46595fc --- /dev/null +++ b/www/node_modules/adm-zip/adm-zip.js @@ -0,0 +1,404 @@ +var fs = require("fs"), + pth = require("path"); + +fs.existsSync = fs.existsSync || pth.existsSync; + +var ZipEntry = require("./zipEntry"), + ZipFile = require("./zipFile"), + Utils = require("./util"); + +module.exports = function(/*String*/input) { + var _zip = undefined, + _filename = ""; + + if (input && typeof input === "string") { // load zip file + if (fs.existsSync(input)) { + _filename = input; + _zip = new ZipFile(input, Utils.Constants.FILE); + } else { + throw Utils.Errors.INVALID_FILENAME; + } + } else if(input && Buffer.isBuffer(input)) { // load buffer + _zip = new ZipFile(input, Utils.Constants.BUFFER); + } else { // create new zip file + _zip = new ZipFile(null, Utils.Constants.NONE); + } + + function getEntry(/*Object*/entry) { + if (entry && _zip) { + var item; + // If entry was given as a file name + if (typeof entry === "string") + item = _zip.getEntry(entry); + // if entry was given as a ZipEntry object + if (typeof entry === "object" && entry.entryName != undefined && entry.header != undefined) + item = _zip.getEntry(entry.entryName); + + if (item) { + return item; + } + } + return null; + } + + return { + /** + * Extracts the given entry from the archive and returns the content as a Buffer object + * @param entry ZipEntry object or String with the full path of the entry + * + * @return Buffer or Null in case of error + */ + readFile : function(/*Object*/entry) { + var item = getEntry(entry); + return item && item.getData() || null; + }, + + /** + * Asynchronous readFile + * @param entry ZipEntry object or String with the full path of the entry + * @param callback + * + * @return Buffer or Null in case of error + */ + readFileAsync : function(/*Object*/entry, /*Function*/callback) { + var item = getEntry(entry); + if (item) { + item.getDataAsync(callback); + } else { + callback(null,"getEntry failed for:" + entry) + } + }, + + /** + * Extracts the given entry from the archive and returns the content as plain text in the given encoding + * @param entry ZipEntry object or String with the full path of the entry + * @param encoding Optional. If no encoding is specified utf8 is used + * + * @return String + */ + readAsText : function(/*Object*/entry, /*String - Optional*/encoding) { + var item = getEntry(entry); + if (item) { + var data = item.getData(); + if (data && data.length) { + return data.toString(encoding || "utf8"); + } + } + return ""; + }, + + /** + * Asynchronous readAsText + * @param entry ZipEntry object or String with the full path of the entry + * @param callback + * @param encoding Optional. If no encoding is specified utf8 is used + * + * @return String + */ + readAsTextAsync : function(/*Object*/entry, /*Function*/callback, /*String - Optional*/encoding) { + var item = getEntry(entry); + if (item) { + item.getDataAsync(function(data) { + if (data && data.length) { + callback(data.toString(encoding || "utf8")); + } else { + callback(""); + } + }) + } else { + callback(""); + } + }, + + /** + * Remove the entry from the file or the entry and all it's nested directories and files if the given entry is a directory + * + * @param entry + */ + deleteFile : function(/*Object*/entry) { // @TODO: test deleteFile + var item = getEntry(entry); + if (item) { + _zip.deleteEntry(item.entryName); + } + }, + + /** + * Adds a comment to the zip. The zip must be rewritten after adding the comment. + * + * @param comment + */ + addZipComment : function(/*String*/comment) { // @TODO: test addZipComment + _zip.comment = comment; + }, + + /** + * Returns the zip comment + * + * @return String + */ + getZipComment : function() { + return _zip.comment || ''; + }, + + /** + * Adds a comment to a specified zipEntry. The zip must be rewritten after adding the comment + * The comment cannot exceed 65535 characters in length + * + * @param entry + * @param comment + */ + addZipEntryComment : function(/*Object*/entry,/*String*/comment) { + var item = getEntry(entry); + if (item) { + item.comment = comment; + } + }, + + /** + * Returns the comment of the specified entry + * + * @param entry + * @return String + */ + getZipEntryComment : function(/*Object*/entry) { + var item = getEntry(entry); + if (item) { + return item.comment || ''; + } + return '' + }, + + /** + * Updates the content of an existing entry inside the archive. The zip must be rewritten after updating the content + * + * @param entry + * @param content + */ + updateFile : function(/*Object*/entry, /*Buffer*/content) { + var item = getEntry(entry); + if (item) { + item.setData(content); + } + }, + + /** + * Adds a file from the disk to the archive + * + * @param localPath + */ + addLocalFile : function(/*String*/localPath, /*String*/zipPath) { + if (fs.existsSync(localPath)) { + if(zipPath){ + zipPath=zipPath.split("\\").join("/"); + if(zipPath.charAt(zipPath.length - 1) != "/"){ + zipPath += "/"; + } + }else{ + zipPath=""; + } + var p = localPath.split("\\").join("/").split("/").pop(); + + this.addFile(zipPath+p, fs.readFileSync(localPath), "", 0) + } else { + throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath); + } + }, + + /** + * Adds a local directory and all its nested files and directories to the archive + * + * @param localPath + */ + addLocalFolder : function(/*String*/localPath, /*String*/zipPath) { + if(zipPath){ + zipPath=zipPath.split("\\").join("/"); + if(zipPath.charAt(zipPath.length - 1) != "/"){ + zipPath += "/"; + } + }else{ + zipPath=""; + } + localPath = localPath.split("\\").join("/"); //windows fix + if (localPath.charAt(localPath.length - 1) != "/") + localPath += "/"; + + if (fs.existsSync(localPath)) { + + var items = Utils.findFiles(localPath), + self = this; + + if (items.length) { + items.forEach(function(path) { + var p = path.split("\\").join("/").replace(localPath, ""); //windows fix + if (p.charAt(p.length - 1) !== "/") { + self.addFile(zipPath+p, fs.readFileSync(path), "", 0) + } else { + self.addFile(zipPath+p, new Buffer(0), "", 0) + } + }); + } + } else { + throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath); + } + }, + + /** + * Allows you to create a entry (file or directory) in the zip file. + * If you want to create a directory the entryName must end in / and a null buffer should be provided. + * Comment and attributes are optional + * + * @param entryName + * @param content + * @param comment + * @param attr + */ + addFile : function(/*String*/entryName, /*Buffer*/content, /*String*/comment, /*Number*/attr) { + var entry = new ZipEntry(); + entry.entryName = entryName; + entry.comment = comment || ""; + entry.attr = attr || 438; //0666; + if (entry.isDirectory && content.length) { + // throw Utils.Errors.DIRECTORY_CONTENT_ERROR; + } + entry.setData(content); + _zip.setEntry(entry); + }, + + /** + * Returns an array of ZipEntry objects representing the files and folders inside the archive + * + * @return Array + */ + getEntries : function() { + if (_zip) { + return _zip.entries; + } else { + return []; + } + }, + + /** + * Returns a ZipEntry object representing the file or folder specified by ``name``. + * + * @param name + * @return ZipEntry + */ + getEntry : function(/*String*/name) { + return getEntry(name); + }, + + /** + * Extracts the given entry to the given targetPath + * If the entry is a directory inside the archive, the entire directory and it's subdirectories will be extracted + * + * @param entry ZipEntry object or String with the full path of the entry + * @param targetPath Target folder where to write the file + * @param maintainEntryPath If maintainEntryPath is true and the entry is inside a folder, the entry folder + * will be created in targetPath as well. Default is TRUE + * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true. + * Default is FALSE + * + * @return Boolean + */ + extractEntryTo : function(/*Object*/entry, /*String*/targetPath, /*Boolean*/maintainEntryPath, /*Boolean*/overwrite) { + overwrite = overwrite || false; + maintainEntryPath = typeof maintainEntryPath == "undefined" ? true : maintainEntryPath; + + var item = getEntry(entry); + if (!item) { + throw Utils.Errors.NO_ENTRY; + } + + var target = pth.resolve(targetPath, maintainEntryPath ? item.entryName : pth.basename(item.entryName)); + + if (item.isDirectory) { + target = pth.resolve(target, ".."); + var children = _zip.getEntryChildren(item); + children.forEach(function(child) { + if (child.isDirectory) return; + var content = child.getData(); + if (!content) { + throw Utils.Errors.CANT_EXTRACT_FILE; + } + Utils.writeFileTo(pth.resolve(targetPath, maintainEntryPath ? child.entryName : child.entryName.substr(item.entryName.length)), content, overwrite); + }); + return true; + } + + var content = item.getData(); + if (!content) throw Utils.Errors.CANT_EXTRACT_FILE; + + if (fs.existsSync(targetPath) && !overwrite) { + throw Utils.Errors.CANT_OVERRIDE; + } + Utils.writeFileTo(target, content, overwrite); + + return true; + }, + + /** + * Extracts the entire archive to the given location + * + * @param targetPath Target location + * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true. + * Default is FALSE + */ + extractAllTo : function(/*String*/targetPath, /*Boolean*/overwrite) { + overwrite = overwrite || false; + if (!_zip) { + throw Utils.Errors.NO_ZIP; + } + + _zip.entries.forEach(function(entry) { + if (entry.isDirectory) { + Utils.makeDir(pth.resolve(targetPath, entry.entryName.toString())); + return; + } + var content = entry.getData(); + if (!content) { + throw Utils.Errors.CANT_EXTRACT_FILE + "2"; + } + Utils.writeFileTo(pth.resolve(targetPath, entry.entryName.toString()), content, overwrite); + }) + }, + + /** + * Writes the newly created zip file to disk at the specified location or if a zip was opened and no ``targetFileName`` is provided, it will overwrite the opened zip + * + * @param targetFileName + * @param callback + */ + writeZip : function(/*String*/targetFileName, /*Function*/callback) { + if (arguments.length == 1) { + if (typeof targetFileName == "function") { + callback = targetFileName; + targetFileName = ""; + } + } + + if (!targetFileName && _filename) { + targetFileName = _filename; + } + if (!targetFileName) return; + + var zipData = _zip.compressToBuffer(); + if (zipData) { + Utils.writeFileTo(targetFileName, zipData, true); + } + }, + + /** + * Returns the content of the entire zip file as a Buffer object + * + * @return Buffer + */ + toBuffer : function(/*Function*/onSuccess,/*Function*/onFail,/*Function*/onItemStart,/*Function*/onItemEnd) { + this.valueOf = 2; + if (typeof onSuccess == "function") { + _zip.toAsyncBuffer(onSuccess,onFail,onItemStart,onItemEnd); + return null; + } + return _zip.compressToBuffer() + } + } +}; diff --git a/www/node_modules/adm-zip/headers/entryHeader.js b/www/node_modules/adm-zip/headers/entryHeader.js new file mode 100644 index 0000000..a29c70f --- /dev/null +++ b/www/node_modules/adm-zip/headers/entryHeader.js @@ -0,0 +1,261 @@ +var Utils = require("../util"), + Constants = Utils.Constants; + +/* The central directory file header */ +module.exports = function () { + var _verMade = 0x0A, + _version = 0x0A, + _flags = 0, + _method = 0, + _time = 0, + _crc = 0, + _compressedSize = 0, + _size = 0, + _fnameLen = 0, + _extraLen = 0, + + _comLen = 0, + _diskStart = 0, + _inattr = 0, + _attr = 0, + _offset = 0; + + var _dataHeader = {}; + + function setTime(val) { + var val = new Date(val); + _time = (val.getFullYear() - 1980 & 0x7f) << 25 // b09-16 years from 1980 + | (val.getMonth() + 1) << 21 // b05-08 month + | val.getDay() << 16 // b00-04 hour + + // 2 bytes time + | val.getHours() << 11 // b11-15 hour + | val.getMinutes() << 5 // b05-10 minute + | val.getSeconds() >> 1; // b00-04 seconds divided by 2 + } + + setTime(+new Date()); + + return { + get made () { return _verMade; }, + set made (val) { _verMade = val; }, + + get version () { return _version; }, + set version (val) { _version = val }, + + get flags () { return _flags }, + set flags (val) { _flags = val; }, + + get method () { return _method; }, + set method (val) { _method = val; }, + + get time () { return new Date( + ((_time >> 25) & 0x7f) + 1980, + ((_time >> 21) & 0x0f) - 1, + (_time >> 16) & 0x1f, + (_time >> 11) & 0x1f, + (_time >> 5) & 0x3f, + (_time & 0x1f) << 1 + ); + }, + set time (val) { + setTime(val); + }, + + get crc () { return _crc; }, + set crc (val) { _crc = val; }, + + get compressedSize () { return _compressedSize; }, + set compressedSize (val) { _compressedSize = val; }, + + get size () { return _size; }, + set size (val) { _size = val; }, + + get fileNameLength () { return _fnameLen; }, + set fileNameLength (val) { _fnameLen = val; }, + + get extraLength () { return _extraLen }, + set extraLength (val) { _extraLen = val; }, + + get commentLength () { return _comLen }, + set commentLength (val) { _comLen = val }, + + get diskNumStart () { return _diskStart }, + set diskNumStart (val) { _diskStart = val }, + + get inAttr () { return _inattr }, + set inAttr (val) { _inattr = val }, + + get attr () { return _attr }, + set attr (val) { _attr = val }, + + get offset () { return _offset }, + set offset (val) { _offset = val }, + + get encripted () { return (_flags & 1) == 1 }, + + get entryHeaderSize () { + return Constants.CENHDR + _fnameLen + _extraLen + _comLen; + }, + + get realDataOffset () { + return _offset + Constants.LOCHDR + _dataHeader.fnameLen + _dataHeader.extraLen; + }, + + get dataHeader () { + return _dataHeader; + }, + + loadDataHeaderFromBinary : function(/*Buffer*/input) { + var data = input.slice(_offset, _offset + Constants.LOCHDR); + // 30 bytes and should start with "PK\003\004" + if (data.readUInt32LE(0) != Constants.LOCSIG) { + throw Utils.Errors.INVALID_LOC; + } + _dataHeader = { + // version needed to extract + version : data.readUInt16LE(Constants.LOCVER), + // general purpose bit flag + flags : data.readUInt16LE(Constants.LOCFLG), + // compression method + method : data.readUInt16LE(Constants.LOCHOW), + // modification time (2 bytes time, 2 bytes date) + time : data.readUInt32LE(Constants.LOCTIM), + // uncompressed file crc-32 value + crc : data.readUInt32LE(Constants.LOCCRC), + // compressed size + compressedSize : data.readUInt32LE(Constants.LOCSIZ), + // uncompressed size + size : data.readUInt32LE(Constants.LOCLEN), + // filename length + fnameLen : data.readUInt16LE(Constants.LOCNAM), + // extra field length + extraLen : data.readUInt16LE(Constants.LOCEXT) + } + }, + + loadFromBinary : function(/*Buffer*/data) { + // data should be 46 bytes and start with "PK 01 02" + if (data.length != Constants.CENHDR || data.readUInt32LE(0) != Constants.CENSIG) { + throw Utils.Errors.INVALID_CEN; + } + // version made by + _verMade = data.readUInt16LE(Constants.CENVEM); + // version needed to extract + _version = data.readUInt16LE(Constants.CENVER); + // encrypt, decrypt flags + _flags = data.readUInt16LE(Constants.CENFLG); + // compression method + _method = data.readUInt16LE(Constants.CENHOW); + // modification time (2 bytes time, 2 bytes date) + _time = data.readUInt32LE(Constants.CENTIM); + // uncompressed file crc-32 value + _crc = data.readUInt32LE(Constants.CENCRC); + // compressed size + _compressedSize = data.readUInt32LE(Constants.CENSIZ); + // uncompressed size + _size = data.readUInt32LE(Constants.CENLEN); + // filename length + _fnameLen = data.readUInt16LE(Constants.CENNAM); + // extra field length + _extraLen = data.readUInt16LE(Constants.CENEXT); + // file comment length + _comLen = data.readUInt16LE(Constants.CENCOM); + // volume number start + _diskStart = data.readUInt16LE(Constants.CENDSK); + // internal file attributes + _inattr = data.readUInt16LE(Constants.CENATT); + // external file attributes + _attr = data.readUInt32LE(Constants.CENATX); + // LOC header offset + _offset = data.readUInt32LE(Constants.CENOFF); + }, + + dataHeaderToBinary : function() { + // LOC header size (30 bytes) + var data = new Buffer(Constants.LOCHDR); + // "PK\003\004" + data.writeUInt32LE(Constants.LOCSIG, 0); + // version needed to extract + data.writeUInt16LE(_version, Constants.LOCVER); + // general purpose bit flag + data.writeUInt16LE(_flags, Constants.LOCFLG); + // compression method + data.writeUInt16LE(_method, Constants.LOCHOW); + // modification time (2 bytes time, 2 bytes date) + data.writeUInt32LE(_time, Constants.LOCTIM); + // uncompressed file crc-32 value + data.writeUInt32LE(_crc, Constants.LOCCRC); + // compressed size + data.writeUInt32LE(_compressedSize, Constants.LOCSIZ); + // uncompressed size + data.writeUInt32LE(_size, Constants.LOCLEN); + // filename length + data.writeUInt16LE(_fnameLen, Constants.LOCNAM); + // extra field length + data.writeUInt16LE(_extraLen, Constants.LOCEXT); + return data; + }, + + entryHeaderToBinary : function() { + // CEN header size (46 bytes) + var data = new Buffer(Constants.CENHDR + _fnameLen + _extraLen + _comLen); + // "PK\001\002" + data.writeUInt32LE(Constants.CENSIG, 0); + // version made by + data.writeUInt16LE(_verMade, Constants.CENVEM); + // version needed to extract + data.writeUInt16LE(_version, Constants.CENVER); + // encrypt, decrypt flags + data.writeUInt16LE(_flags, Constants.CENFLG); + // compression method + data.writeUInt16LE(_method, Constants.CENHOW); + // modification time (2 bytes time, 2 bytes date) + data.writeUInt32LE(_time, Constants.CENTIM); + // uncompressed file crc-32 value + data.writeInt32LE(_crc, Constants.CENCRC, true); + // compressed size + data.writeUInt32LE(_compressedSize, Constants.CENSIZ); + // uncompressed size + data.writeUInt32LE(_size, Constants.CENLEN); + // filename length + data.writeUInt16LE(_fnameLen, Constants.CENNAM); + // extra field length + data.writeUInt16LE(_extraLen, Constants.CENEXT); + // file comment length + data.writeUInt16LE(_comLen, Constants.CENCOM); + // volume number start + data.writeUInt16LE(_diskStart, Constants.CENDSK); + // internal file attributes + data.writeUInt16LE(_inattr, Constants.CENATT); + // external file attributes + data.writeUInt32LE(_attr, Constants.CENATX); + // LOC header offset + data.writeUInt32LE(_offset, Constants.CENOFF); + // fill all with + data.fill(0x00, Constants.CENHDR); + return data; + }, + + toString : function() { + return '{\n' + + '\t"made" : ' + _verMade + ",\n" + + '\t"version" : ' + _version + ",\n" + + '\t"flags" : ' + _flags + ",\n" + + '\t"method" : ' + Utils.methodToString(_method) + ",\n" + + '\t"time" : ' + _time + ",\n" + + '\t"crc" : 0x' + _crc.toString(16).toUpperCase() + ",\n" + + '\t"compressedSize" : ' + _compressedSize + " bytes,\n" + + '\t"size" : ' + _size + " bytes,\n" + + '\t"fileNameLength" : ' + _fnameLen + ",\n" + + '\t"extraLength" : ' + _extraLen + " bytes,\n" + + '\t"commentLength" : ' + _comLen + " bytes,\n" + + '\t"diskNumStart" : ' + _diskStart + ",\n" + + '\t"inAttr" : ' + _inattr + ",\n" + + '\t"attr" : ' + _attr + ",\n" + + '\t"offset" : ' + _offset + ",\n" + + '\t"entryHeaderSize" : ' + (Constants.CENHDR + _fnameLen + _extraLen + _comLen) + " bytes\n" + + '}'; + } + } +}; diff --git a/www/node_modules/adm-zip/headers/index.js b/www/node_modules/adm-zip/headers/index.js new file mode 100644 index 0000000..b8c67b9 --- /dev/null +++ b/www/node_modules/adm-zip/headers/index.js @@ -0,0 +1,2 @@ +exports.EntryHeader = require("./entryHeader"); +exports.MainHeader = require("./mainHeader"); diff --git a/www/node_modules/adm-zip/headers/mainHeader.js b/www/node_modules/adm-zip/headers/mainHeader.js new file mode 100644 index 0000000..002bc8a --- /dev/null +++ b/www/node_modules/adm-zip/headers/mainHeader.js @@ -0,0 +1,80 @@ +var Utils = require("../util"), + Constants = Utils.Constants; + +/* The entries in the end of central directory */ +module.exports = function () { + var _volumeEntries = 0, + _totalEntries = 0, + _size = 0, + _offset = 0, + _commentLength = 0; + + return { + get diskEntries () { return _volumeEntries }, + set diskEntries (/*Number*/val) { _volumeEntries = _totalEntries = val; }, + + get totalEntries () { return _totalEntries }, + set totalEntries (/*Number*/val) { _totalEntries = _volumeEntries = val; }, + + get size () { return _size }, + set size (/*Number*/val) { _size = val; }, + + get offset () { return _offset }, + set offset (/*Number*/val) { _offset = val; }, + + get commentLength () { return _commentLength }, + set commentLength (/*Number*/val) { _commentLength = val; }, + + get mainHeaderSize () { + return Constants.ENDHDR + _commentLength; + }, + + loadFromBinary : function(/*Buffer*/data) { + // data should be 22 bytes and start with "PK 05 06" + if (data.length != Constants.ENDHDR || data.readUInt32LE(0) != Constants.ENDSIG) + throw Utils.Errors.INVALID_END; + + // number of entries on this volume + _volumeEntries = data.readUInt16LE(Constants.ENDSUB); + // total number of entries + _totalEntries = data.readUInt16LE(Constants.ENDTOT); + // central directory size in bytes + _size = data.readUInt32LE(Constants.ENDSIZ); + // offset of first CEN header + _offset = data.readUInt32LE(Constants.ENDOFF); + // zip file comment length + _commentLength = data.readUInt16LE(Constants.ENDCOM); + }, + + toBinary : function() { + var b = new Buffer(Constants.ENDHDR + _commentLength); + // "PK 05 06" signature + b.writeUInt32LE(Constants.ENDSIG, 0); + b.writeUInt32LE(0, 4); + // number of entries on this volume + b.writeUInt16LE(_volumeEntries, Constants.ENDSUB); + // total number of entries + b.writeUInt16LE(_totalEntries, Constants.ENDTOT); + // central directory size in bytes + b.writeUInt32LE(_size, Constants.ENDSIZ); + // offset of first CEN header + b.writeUInt32LE(_offset, Constants.ENDOFF); + // zip file comment length + b.writeUInt16LE(_commentLength, Constants.ENDCOM); + // fill comment memory with spaces so no garbage is left there + b.fill(" ", Constants.ENDHDR); + + return b; + }, + + toString : function() { + return '{\n' + + '\t"diskEntries" : ' + _volumeEntries + ",\n" + + '\t"totalEntries" : ' + _totalEntries + ",\n" + + '\t"size" : ' + _size + " bytes,\n" + + '\t"offset" : 0x' + _offset.toString(16).toUpperCase() + ",\n" + + '\t"commentLength" : 0x' + _commentLength + "\n" + + '}'; + } + } +}; \ No newline at end of file diff --git a/www/node_modules/adm-zip/methods/deflater.js b/www/node_modules/adm-zip/methods/deflater.js new file mode 100644 index 0000000..3267943 --- /dev/null +++ b/www/node_modules/adm-zip/methods/deflater.js @@ -0,0 +1,1578 @@ +/* + * $Id: rawdeflate.js,v 0.5 2013/04/09 14:25:38 dankogai Exp dankogai $ + * + * GNU General Public License, version 2 (GPL-2.0) + * http://opensource.org/licenses/GPL-2.0 + * Original: + * http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt + */ +function JSDeflater(/*inbuff*/inbuf) { + + /* Copyright (C) 1999 Masanao Izumo + * Version: 1.0.1 + * LastModified: Dec 25 1999 + */ + + var WSIZE = 32768, // Sliding Window size + zip_STORED_BLOCK = 0, + zip_STATIC_TREES = 1, + zip_DYN_TREES = 2, + zip_DEFAULT_LEVEL = 6, + zip_FULL_SEARCH = true, + zip_INBUFSIZ = 32768, // Input buffer size + zip_INBUF_EXTRA = 64, // Extra buffer + zip_OUTBUFSIZ = 1024 * 8, + zip_window_size = 2 * WSIZE, + MIN_MATCH = 3, + MAX_MATCH = 258, + zip_BITS = 16, + LIT_BUFSIZE = 0x2000, + zip_HASH_BITS = 13, + zip_DIST_BUFSIZE = LIT_BUFSIZE, + zip_HASH_SIZE = 1 << zip_HASH_BITS, + zip_HASH_MASK = zip_HASH_SIZE - 1, + zip_WMASK = WSIZE - 1, + zip_NIL = 0, // Tail of hash chains + zip_TOO_FAR = 4096, + zip_MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1, + zip_MAX_DIST = WSIZE - zip_MIN_LOOKAHEAD, + zip_SMALLEST = 1, + zip_MAX_BITS = 15, + zip_MAX_BL_BITS = 7, + zip_LENGTH_CODES = 29, + zip_LITERALS = 256, + zip_END_BLOCK = 256, + zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES, + zip_D_CODES = 30, + zip_BL_CODES = 19, + zip_REP_3_6 = 16, + zip_REPZ_3_10 = 17, + zip_REPZ_11_138 = 18, + zip_HEAP_SIZE = 2 * zip_L_CODES + 1, + zip_H_SHIFT = parseInt((zip_HASH_BITS + MIN_MATCH - 1) / MIN_MATCH); + + var zip_free_queue, zip_qhead, zip_qtail, zip_initflag, zip_outbuf = null, zip_outcnt, zip_outoff, zip_complete, + zip_window, zip_d_buf, zip_l_buf, zip_prev, zip_bi_buf, zip_bi_valid, zip_block_start, zip_ins_h, zip_hash_head, + zip_prev_match, zip_match_available, zip_match_length, zip_prev_length, zip_strstart, zip_match_start, zip_eofile, + zip_lookahead, zip_max_chain_length, zip_max_lazy_match, zip_compr_level, zip_good_match, zip_nice_match, + zip_dyn_ltree, zip_dyn_dtree, zip_static_ltree, zip_static_dtree, zip_bl_tree, zip_l_desc, zip_d_desc, zip_bl_desc, + zip_bl_count, zip_heap, zip_heap_len, zip_heap_max, zip_depth, zip_length_code, zip_dist_code, zip_base_length, + zip_base_dist, zip_flag_buf, zip_last_lit, zip_last_dist, zip_last_flags, zip_flags, zip_flag_bit, zip_opt_len, + zip_static_len, zip_deflate_data, zip_deflate_pos; + + var zip_DeflateCT = function () { + this.fc = 0; // frequency count or bit string + this.dl = 0; // father node in Huffman tree or length of bit string + }; + + var zip_DeflateTreeDesc = function () { + this.dyn_tree = null; // the dynamic tree + this.static_tree = null; // corresponding static tree or NULL + this.extra_bits = null; // extra bits for each code or NULL + this.extra_base = 0; // base index for extra_bits + this.elems = 0; // max number of elements in the tree + this.max_length = 0; // max bit length for the codes + this.max_code = 0; // largest code with non zero frequency + }; + + /* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ + var zip_DeflateConfiguration = function (a, b, c, d) { + this.good_length = a; // reduce lazy search above this match length + this.max_lazy = b; // do not perform lazy search above this match length + this.nice_length = c; // quit search above this match length + this.max_chain = d; + }; + + var zip_DeflateBuffer = function () { + this.next = null; + this.len = 0; + this.ptr = new Array(zip_OUTBUFSIZ); + this.off = 0; + }; + + /* constant tables */ + var zip_extra_lbits = new Array( + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0); + var zip_extra_dbits = new Array( + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13); + var zip_extra_blbits = new Array( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7); + var zip_bl_order = new Array( + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15); + var zip_configuration_table = new Array( + new zip_DeflateConfiguration(0, 0, 0, 0), + new zip_DeflateConfiguration(4, 4, 8, 4), + new zip_DeflateConfiguration(4, 5, 16, 8), + new zip_DeflateConfiguration(4, 6, 32, 32), + new zip_DeflateConfiguration(4, 4, 16, 16), + new zip_DeflateConfiguration(8, 16, 32, 32), + new zip_DeflateConfiguration(8, 16, 128, 128), + new zip_DeflateConfiguration(8, 32, 128, 256), + new zip_DeflateConfiguration(32, 128, 258, 1024), + new zip_DeflateConfiguration(32, 258, 258, 4096)); + + + /* routines (deflate) */ + + var zip_deflate_start = function (level) { + var i; + + if (!level) + level = zip_DEFAULT_LEVEL; + else if (level < 1) + level = 1; + else if (level > 9) + level = 9; + + zip_compr_level = level; + zip_initflag = false; + zip_eofile = false; + if (zip_outbuf != null) + return; + + zip_free_queue = zip_qhead = zip_qtail = null; + zip_outbuf = new Array(zip_OUTBUFSIZ); + zip_window = new Array(zip_window_size); + zip_d_buf = new Array(zip_DIST_BUFSIZE); + zip_l_buf = new Array(zip_INBUFSIZ + zip_INBUF_EXTRA); + zip_prev = new Array(1 << zip_BITS); + zip_dyn_ltree = new Array(zip_HEAP_SIZE); + for (i = 0; i < zip_HEAP_SIZE; i++) zip_dyn_ltree[i] = new zip_DeflateCT(); + zip_dyn_dtree = new Array(2 * zip_D_CODES + 1); + for (i = 0; i < 2 * zip_D_CODES + 1; i++) zip_dyn_dtree[i] = new zip_DeflateCT(); + zip_static_ltree = new Array(zip_L_CODES + 2); + for (i = 0; i < zip_L_CODES + 2; i++) zip_static_ltree[i] = new zip_DeflateCT(); + zip_static_dtree = new Array(zip_D_CODES); + for (i = 0; i < zip_D_CODES; i++) zip_static_dtree[i] = new zip_DeflateCT(); + zip_bl_tree = new Array(2 * zip_BL_CODES + 1); + for (i = 0; i < 2 * zip_BL_CODES + 1; i++) zip_bl_tree[i] = new zip_DeflateCT(); + zip_l_desc = new zip_DeflateTreeDesc(); + zip_d_desc = new zip_DeflateTreeDesc(); + zip_bl_desc = new zip_DeflateTreeDesc(); + zip_bl_count = new Array(zip_MAX_BITS + 1); + zip_heap = new Array(2 * zip_L_CODES + 1); + zip_depth = new Array(2 * zip_L_CODES + 1); + zip_length_code = new Array(MAX_MATCH - MIN_MATCH + 1); + zip_dist_code = new Array(512); + zip_base_length = new Array(zip_LENGTH_CODES); + zip_base_dist = new Array(zip_D_CODES); + zip_flag_buf = new Array(parseInt(LIT_BUFSIZE / 8)); + }; + + var zip_deflate_end = function () { + zip_free_queue = zip_qhead = zip_qtail = null; + zip_outbuf = null; + zip_window = null; + zip_d_buf = null; + zip_l_buf = null; + zip_prev = null; + zip_dyn_ltree = null; + zip_dyn_dtree = null; + zip_static_ltree = null; + zip_static_dtree = null; + zip_bl_tree = null; + zip_l_desc = null; + zip_d_desc = null; + zip_bl_desc = null; + zip_bl_count = null; + zip_heap = null; + zip_depth = null; + zip_length_code = null; + zip_dist_code = null; + zip_base_length = null; + zip_base_dist = null; + zip_flag_buf = null; + }; + + var zip_reuse_queue = function (p) { + p.next = zip_free_queue; + zip_free_queue = p; + }; + + var zip_new_queue = function () { + var p; + + if (zip_free_queue != null) { + p = zip_free_queue; + zip_free_queue = zip_free_queue.next; + } + else + p = new zip_DeflateBuffer(); + p.next = null; + p.len = p.off = 0; + + return p; + }; + + var zip_head1 = function (i) { + return zip_prev[WSIZE + i]; + }; + + var zip_head2 = function (i, val) { + return zip_prev[WSIZE + i] = val; + }; + + /* put_byte is used for the compressed output, put_ubyte for the + * uncompressed output. However unlzw() uses window for its + * suffix table instead of its output buffer, so it does not use put_ubyte + * (to be cleaned up). + */ + var zip_put_byte = function (c) { + zip_outbuf[zip_outoff + zip_outcnt++] = c; + if (zip_outoff + zip_outcnt == zip_OUTBUFSIZ) + zip_qoutbuf(); + }; + + /* Output a 16 bit value, lsb first */ + var zip_put_short = function (w) { + w &= 0xffff; + if (zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) { + zip_outbuf[zip_outoff + zip_outcnt++] = (w & 0xff); + zip_outbuf[zip_outoff + zip_outcnt++] = (w >>> 8); + } else { + zip_put_byte(w & 0xff); + zip_put_byte(w >>> 8); + } + }; + + /* ========================================================================== + * Insert string s in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of s are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ + var zip_INSERT_STRING = function () { + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) + ^ (zip_window[zip_strstart + MIN_MATCH - 1] & 0xff)) + & zip_HASH_MASK; + zip_hash_head = zip_head1(zip_ins_h); + zip_prev[zip_strstart & zip_WMASK] = zip_hash_head; + zip_head2(zip_ins_h, zip_strstart); + }; + + /* Send a code of the given tree. c and tree must not have side effects */ + var zip_SEND_CODE = function (c, tree) { + zip_send_bits(tree[c].fc, tree[c].dl); + }; + + /* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. dist_code[256] and dist_code[257] are never + * used. + */ + var zip_D_CODE = function (dist) { + return (dist < 256 ? zip_dist_code[dist] + : zip_dist_code[256 + (dist >> 7)]) & 0xff; + }; + + /* ========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ + var zip_SMALLER = function (tree, n, m) { + return tree[n].fc < tree[m].fc || + (tree[n].fc == tree[m].fc && zip_depth[n] <= zip_depth[m]); + }; + + /* ========================================================================== + * read string data + */ + var zip_read_buff = function (buff, offset, n) { + var i; + for (i = 0; i < n && zip_deflate_pos < zip_deflate_data.length; i++) + buff[offset + i] = + zip_deflate_data[zip_deflate_pos++] & 0xff; + return i; + }; + + /* ========================================================================== + * Initialize the "longest match" routines for a new file + */ + var zip_lm_init = function () { + var j; + + /* Initialize the hash table. */ + for (j = 0; j < zip_HASH_SIZE; j++) + zip_prev[WSIZE + j] = 0; + zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy; + zip_good_match = zip_configuration_table[zip_compr_level].good_length; + if (!zip_FULL_SEARCH) + zip_nice_match = zip_configuration_table[zip_compr_level].nice_length; + zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain; + + zip_strstart = 0; + zip_block_start = 0; + + zip_lookahead = zip_read_buff(zip_window, 0, 2 * WSIZE); + if (zip_lookahead <= 0) { + zip_eofile = true; + zip_lookahead = 0; + return; + } + zip_eofile = false; + /* Make sure that we always have enough lookahead. This is important + * if input comes from a device such as a tty. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + + /* If lookahead < MIN_MATCH, ins_h is garbage, but this is + * not important since only literal bytes will be emitted. + */ + zip_ins_h = 0; + for (j = 0; j < MIN_MATCH - 1; j++) { + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[j] & 0xff)) & zip_HASH_MASK; + } + }; + + /* ========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + */ + var zip_longest_match = function (cur_match) { + var chain_length = zip_max_chain_length; // max hash chain length + var scanp = zip_strstart; // current string + var matchp; // matched string + var len; // length of current match + var best_len = zip_prev_length; // best match length so far + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + var limit = (zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL); + + var strendp = zip_strstart + MAX_MATCH; + var scan_end1 = zip_window[scanp + best_len - 1]; + var scan_end = zip_window[scanp + best_len]; + + /* Do not waste too much time if we already have a good match: */ + if (zip_prev_length >= zip_good_match) + chain_length >>= 2; + + do { + matchp = cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ + if (zip_window[matchp + best_len] != scan_end || + zip_window[matchp + best_len - 1] != scan_end1 || + zip_window[matchp] != zip_window[scanp] || + zip_window[++matchp] != zip_window[scanp + 1]) { + continue; + } + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scanp += 2; + matchp++; + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + scanp < strendp); + + len = MAX_MATCH - (strendp - scanp); + scanp = strendp - MAX_MATCH; + + if (len > best_len) { + zip_match_start = cur_match; + best_len = len; + if (zip_FULL_SEARCH) { + if (len >= MAX_MATCH) break; + } else { + if (len >= zip_nice_match) break; + } + + scan_end1 = zip_window[scanp + best_len - 1]; + scan_end = zip_window[scanp + best_len]; + } + } while ((cur_match = zip_prev[cur_match & zip_WMASK]) > limit + && --chain_length != 0); + + return best_len; + }; + + /* ========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead, and sets eofile if end of input file. + * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 + * OUT assertions: at least one byte has been read, or eofile is set; + * file reads are performed for at least two bytes (required for the + * translate_eol option). + */ + var zip_fill_window = function () { + var n, m; + + // Amount of free space at the end of the window. + var more = zip_window_size - zip_lookahead - zip_strstart; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (more == -1) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + } else if (zip_strstart >= WSIZE + zip_MAX_DIST) { + /* By the IN assertion, the window is not empty so we can't confuse + * more == 0 with more == 64K on a 16 bit machine. + */ + for (n = 0; n < WSIZE; n++) + zip_window[n] = zip_window[n + WSIZE]; + + zip_match_start -= WSIZE; + zip_strstart -= WSIZE; + /* we now have strstart >= MAX_DIST: */ + zip_block_start -= WSIZE; + + for (n = 0; n < zip_HASH_SIZE; n++) { + m = zip_head1(n); + zip_head2(n, m >= WSIZE ? m - WSIZE : zip_NIL); + } + for (n = 0; n < WSIZE; n++) { + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + m = zip_prev[n]; + zip_prev[n] = (m >= WSIZE ? m - WSIZE : zip_NIL); + } + more += WSIZE; + } + // At this point, more >= 2 + if (!zip_eofile) { + n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more); + if (n <= 0) + zip_eofile = true; + else + zip_lookahead += n; + } + }; + + /* ========================================================================== + * Processes a new input file and return its compressed length. This + * function does not perform lazy evaluationof matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ + var zip_deflate_fast = function () { + while (zip_lookahead != 0 && zip_qhead == null) { + var flush; // set if current block must be flushed + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + zip_INSERT_STRING(); + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (zip_hash_head != zip_NIL && + zip_strstart - zip_hash_head <= zip_MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + zip_match_length = zip_longest_match(zip_hash_head); + /* longest_match() sets match_start */ + if (zip_match_length > zip_lookahead) + zip_match_length = zip_lookahead; + } + if (zip_match_length >= MIN_MATCH) { + flush = zip_ct_tally(zip_strstart - zip_match_start, + zip_match_length - MIN_MATCH); + zip_lookahead -= zip_match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (zip_match_length <= zip_max_lazy_match) { + zip_match_length--; // string at strstart already in hash table + do { + zip_strstart++; + zip_INSERT_STRING(); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since + * the next lookahead bytes will be emitted as literals. + */ + } while (--zip_match_length != 0); + zip_strstart++; + } else { + zip_strstart += zip_match_length; + zip_match_length = 0; + zip_ins_h = zip_window[zip_strstart] & 0xff; + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[zip_strstart + 1] & 0xff)) & zip_HASH_MASK; + } + } else { + /* No match, output a literal byte */ + flush = zip_ct_tally(0, zip_window[zip_strstart] & 0xff); + zip_lookahead--; + zip_strstart++; + } + if (flush) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + } + }; + + var zip_deflate_better = function () { + /* Process the input block. */ + while (zip_lookahead != 0 && zip_qhead == null) { + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + zip_INSERT_STRING(); + + /* Find the longest match, discarding those <= prev_length. + */ + zip_prev_length = zip_match_length; + zip_prev_match = zip_match_start; + zip_match_length = MIN_MATCH - 1; + + if (zip_hash_head != zip_NIL && + zip_prev_length < zip_max_lazy_match && + zip_strstart - zip_hash_head <= zip_MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + zip_match_length = zip_longest_match(zip_hash_head); + /* longest_match() sets match_start */ + if (zip_match_length > zip_lookahead) + zip_match_length = zip_lookahead; + + /* Ignore a length 3 match if it is too distant: */ + if (zip_match_length == MIN_MATCH && + zip_strstart - zip_match_start > zip_TOO_FAR) { + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + zip_match_length--; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (zip_prev_length >= MIN_MATCH && + zip_match_length <= zip_prev_length) { + var flush; // set if current block must be flushed + flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match, + zip_prev_length - MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. + */ + zip_lookahead -= zip_prev_length - 1; + zip_prev_length -= 2; + do { + zip_strstart++; + zip_INSERT_STRING(); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since the + * next lookahead bytes will always be emitted as literals. + */ + } while (--zip_prev_length != 0); + zip_match_available = 0; + zip_match_length = MIN_MATCH - 1; + zip_strstart++; + if (flush) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + } else if (zip_match_available != 0) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + if (zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff)) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + zip_strstart++; + zip_lookahead--; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + zip_match_available = 1; + zip_strstart++; + zip_lookahead--; + } + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + } + }; + + var zip_init_deflate = function () { + if (zip_eofile) + return; + zip_bi_buf = 0; + zip_bi_valid = 0; + zip_ct_init(); + zip_lm_init(); + + zip_qhead = null; + zip_outcnt = 0; + zip_outoff = 0; + zip_match_available = 0; + + if (zip_compr_level <= 3) { + zip_prev_length = MIN_MATCH - 1; + zip_match_length = 0; + } + else { + zip_match_length = MIN_MATCH - 1; + zip_match_available = 0; + zip_match_available = 0; + } + + zip_complete = false; + }; + + /* ========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ + var zip_deflate_internal = function (buff, off, buff_size) { + var n; + + if (!zip_initflag) { + zip_init_deflate(); + zip_initflag = true; + if (zip_lookahead == 0) { // empty + zip_complete = true; + return 0; + } + } + + if ((n = zip_qcopy(buff, off, buff_size)) == buff_size) + return buff_size; + + if (zip_complete) + return n; + + if (zip_compr_level <= 3) // optimized for speed + zip_deflate_fast(); + else + zip_deflate_better(); + if (zip_lookahead == 0) { + if (zip_match_available != 0) + zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff); + zip_flush_block(1); + zip_complete = true; + } + return n + zip_qcopy(buff, n + off, buff_size - n); + }; + + var zip_qcopy = function (buff, off, buff_size) { + var n, i, j; + + n = 0; + while (zip_qhead != null && n < buff_size) { + i = buff_size - n; + if (i > zip_qhead.len) + i = zip_qhead.len; + for (j = 0; j < i; j++) + buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j]; + + zip_qhead.off += i; + zip_qhead.len -= i; + n += i; + if (zip_qhead.len == 0) { + var p; + p = zip_qhead; + zip_qhead = zip_qhead.next; + zip_reuse_queue(p); + } + } + + if (n == buff_size) + return n; + + if (zip_outoff < zip_outcnt) { + i = buff_size - n; + if (i > zip_outcnt - zip_outoff) + i = zip_outcnt - zip_outoff; + // System.arraycopy(outbuf, outoff, buff, off + n, i); + for (j = 0; j < i; j++) + buff[off + n + j] = zip_outbuf[zip_outoff + j]; + zip_outoff += i; + n += i; + if (zip_outcnt == zip_outoff) + zip_outcnt = zip_outoff = 0; + } + return n; + }; + + /* ========================================================================== + * Allocate the match buffer, initialize the various tables and save the + * location of the internal file attribute (ascii/binary) and method + * (DEFLATE/STORE). + */ + var zip_ct_init = function () { + var n; // iterates over tree elements + var bits; // bit counter + var length; // length value + var code; // code value + var dist; // distance index + + if (zip_static_dtree[0].dl != 0) return; // ct_init already called + + zip_l_desc.dyn_tree = zip_dyn_ltree; + zip_l_desc.static_tree = zip_static_ltree; + zip_l_desc.extra_bits = zip_extra_lbits; + zip_l_desc.extra_base = zip_LITERALS + 1; + zip_l_desc.elems = zip_L_CODES; + zip_l_desc.max_length = zip_MAX_BITS; + zip_l_desc.max_code = 0; + + zip_d_desc.dyn_tree = zip_dyn_dtree; + zip_d_desc.static_tree = zip_static_dtree; + zip_d_desc.extra_bits = zip_extra_dbits; + zip_d_desc.extra_base = 0; + zip_d_desc.elems = zip_D_CODES; + zip_d_desc.max_length = zip_MAX_BITS; + zip_d_desc.max_code = 0; + + zip_bl_desc.dyn_tree = zip_bl_tree; + zip_bl_desc.static_tree = null; + zip_bl_desc.extra_bits = zip_extra_blbits; + zip_bl_desc.extra_base = 0; + zip_bl_desc.elems = zip_BL_CODES; + zip_bl_desc.max_length = zip_MAX_BL_BITS; + zip_bl_desc.max_code = 0; + + // Initialize the mapping length (0..255) -> length code (0..28) + length = 0; + for (code = 0; code < zip_LENGTH_CODES - 1; code++) { + zip_base_length[code] = length; + for (n = 0; n < (1 << zip_extra_lbits[code]); n++) + zip_length_code[length++] = code; + } + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + zip_length_code[length - 1] = code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + zip_base_dist[code] = dist; + for (n = 0; n < (1 << zip_extra_dbits[code]); n++) { + zip_dist_code[dist++] = code; + } + } + dist >>= 7; // from now on, all distances are divided by 128 + for (; code < zip_D_CODES; code++) { + zip_base_dist[code] = dist << 7; + for (n = 0; n < (1 << (zip_extra_dbits[code] - 7)); n++) + zip_dist_code[256 + dist++] = code; + } + // Construct the codes of the static literal tree + for (bits = 0; bits <= zip_MAX_BITS; bits++) + zip_bl_count[bits] = 0; + n = 0; + while (n <= 143) { + zip_static_ltree[n++].dl = 8; + zip_bl_count[8]++; + } + while (n <= 255) { + zip_static_ltree[n++].dl = 9; + zip_bl_count[9]++; + } + while (n <= 279) { + zip_static_ltree[n++].dl = 7; + zip_bl_count[7]++; + } + while (n <= 287) { + zip_static_ltree[n++].dl = 8; + zip_bl_count[8]++; + } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + zip_gen_codes(zip_static_ltree, zip_L_CODES + 1); + + /* The static distance tree is trivial: */ + for (n = 0; n < zip_D_CODES; n++) { + zip_static_dtree[n].dl = 5; + zip_static_dtree[n].fc = zip_bi_reverse(n, 5); + } + + // Initialize the first block of the first file: + zip_init_block(); + }; + + /* ========================================================================== + * Initialize a new block. + */ + var zip_init_block = function () { + var n; // iterates over tree elements + + // Initialize the trees. + for (n = 0; n < zip_L_CODES; n++) zip_dyn_ltree[n].fc = 0; + for (n = 0; n < zip_D_CODES; n++) zip_dyn_dtree[n].fc = 0; + for (n = 0; n < zip_BL_CODES; n++) zip_bl_tree[n].fc = 0; + + zip_dyn_ltree[zip_END_BLOCK].fc = 1; + zip_opt_len = zip_static_len = 0; + zip_last_lit = zip_last_dist = zip_last_flags = 0; + zip_flags = 0; + zip_flag_bit = 1; + }; + + /* ========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ + var zip_pqdownheap = function (tree, // the tree to restore + k) { // node to move down + var v = zip_heap[k]; + var j = k << 1; // left son of k + + while (j <= zip_heap_len) { + // Set j to the smallest of the two sons: + if (j < zip_heap_len && + zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j])) + j++; + + // Exit if v is smaller than both sons + if (zip_SMALLER(tree, v, zip_heap[j])) + break; + + // Exchange v with the smallest son + zip_heap[k] = zip_heap[j]; + k = j; + + // And continue down the tree, setting j to the left son of k + j <<= 1; + } + zip_heap[k] = v; + }; + + /* ========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ + var zip_gen_bitlen = function (desc) { // the tree descriptor + var tree = desc.dyn_tree; + var extra = desc.extra_bits; + var base = desc.extra_base; + var max_code = desc.max_code; + var max_length = desc.max_length; + var stree = desc.static_tree; + var h; // heap index + var n, m; // iterate over the tree elements + var bits; // bit length + var xbits; // extra bits + var f; // frequency + var overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= zip_MAX_BITS; bits++) + zip_bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[zip_heap[zip_heap_max]].dl = 0; // root of the heap + + for (h = zip_heap_max + 1; h < zip_HEAP_SIZE; h++) { + n = zip_heap[h]; + bits = tree[tree[n].dl].dl + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n].dl = bits; + // We overwrite tree[n].dl which is no longer needed + + if (n > max_code) + continue; // not a leaf node + + zip_bl_count[bits]++; + xbits = 0; + if (n >= base) + xbits = extra[n - base]; + f = tree[n].fc; + zip_opt_len += f * (bits + xbits); + if (stree != null) + zip_static_len += f * (stree[n].dl + xbits); + } + if (overflow == 0) + return; + + // This happens for example on obj2 and pic of the Calgary corpus + + // Find the first bit length which could increase: + do { + bits = max_length - 1; + while (zip_bl_count[bits] == 0) + bits--; + zip_bl_count[bits]--; // move one leaf down the tree + zip_bl_count[bits + 1] += 2; // move one overflow item as its brother + zip_bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = zip_bl_count[bits]; + while (n != 0) { + m = zip_heap[--h]; + if (m > max_code) + continue; + if (tree[m].dl != bits) { + zip_opt_len += (bits - tree[m].dl) * tree[m].fc; + tree[m].fc = bits; + } + n--; + } + } + }; + + /* ========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ + var zip_gen_codes = function (tree, // the tree to decorate + max_code) { // largest code with non zero frequency + var next_code = new Array(zip_MAX_BITS + 1); // next code value for each bit length + var code = 0; // running code value + var bits; // bit index + var n; // code index + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= zip_MAX_BITS; bits++) { + code = ((code + zip_bl_count[bits - 1]) << 1); + next_code[bits] = code; + } + + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + for (n = 0; n <= max_code; n++) { + var len = tree[n].dl; + if (len == 0) + continue; + // Now reverse the bits + tree[n].fc = zip_bi_reverse(next_code[len]++, len); + } + }; + + /* ========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ + var zip_build_tree = function (desc) { // the tree descriptor + var tree = desc.dyn_tree; + var stree = desc.static_tree; + var elems = desc.elems; + var n, m; // iterate over heap elements + var max_code = -1; // largest code with non zero frequency + var node = elems; // next internal node of the tree + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + zip_heap_len = 0; + zip_heap_max = zip_HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].fc != 0) { + zip_heap[++zip_heap_len] = max_code = n; + zip_depth[n] = 0; + } else + tree[n].dl = 0; + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (zip_heap_len < 2) { + var xnew = zip_heap[++zip_heap_len] = (max_code < 2 ? ++max_code : 0); + tree[xnew].fc = 1; + zip_depth[xnew] = 0; + zip_opt_len--; + if (stree != null) + zip_static_len -= stree[xnew].dl; + // new is 0 or 1 so it does not have extra bits + } + desc.max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = zip_heap_len >> 1; n >= 1; n--) + zip_pqdownheap(tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + do { + n = zip_heap[zip_SMALLEST]; + zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--]; + zip_pqdownheap(tree, zip_SMALLEST); + + m = zip_heap[zip_SMALLEST]; // m = node of next least frequency + + // keep the nodes sorted by frequency + zip_heap[--zip_heap_max] = n; + zip_heap[--zip_heap_max] = m; + + // Create a new node father of n and m + tree[node].fc = tree[n].fc + tree[m].fc; + if (zip_depth[n] > zip_depth[m] + 1) + zip_depth[node] = zip_depth[n]; + else + zip_depth[node] = zip_depth[m] + 1; + tree[n].dl = tree[m].dl = node; + + // and insert the new node in the heap + zip_heap[zip_SMALLEST] = node++; + zip_pqdownheap(tree, zip_SMALLEST); + + } while (zip_heap_len >= 2); + + zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + zip_gen_bitlen(desc); + + // The field len is now set, we can generate the bit codes + zip_gen_codes(tree, max_code); + }; + + /* ========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. Updates opt_len to take into account the repeat + * counts. (The contribution of the bit length codes will be added later + * during the construction of bl_tree.) + */ + var zip_scan_tree = function (tree,// the tree to be scanned + max_code) { // and its largest code of non zero frequency + var n; // iterates over all tree elements + var prevlen = -1; // last emitted length + var curlen; // length of current code + var nextlen = tree[0].dl; // length of next code + var count = 0; // repeat count of the current code + var max_count = 7; // max repeat count + var min_count = 4; // min repeat count + + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } + tree[max_code + 1].dl = 0xffff; // guard + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n + 1].dl; + if (++count < max_count && curlen == nextlen) + continue; + else if (count < min_count) + zip_bl_tree[curlen].fc += count; + else if (curlen != 0) { + if (curlen != prevlen) + zip_bl_tree[curlen].fc++; + zip_bl_tree[zip_REP_3_6].fc++; + } else if (count <= 10) + zip_bl_tree[zip_REPZ_3_10].fc++; + else + zip_bl_tree[zip_REPZ_11_138].fc++; + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } else if (curlen == nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + }; + + /* ========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ + var zip_send_tree = function (tree, // the tree to be scanned + max_code) { // and its largest code of non zero frequency + var n; // iterates over all tree elements + var prevlen = -1; // last emitted length + var curlen; // length of current code + var nextlen = tree[0].dl; // length of next code + var count = 0; // repeat count of the current code + var max_count = 7; // max repeat count + var min_count = 4; // min repeat count + + /* tree[max_code+1].dl = -1; */ + /* guard already set */ + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n + 1].dl; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { + zip_SEND_CODE(curlen, zip_bl_tree); + } while (--count != 0); + } else if (curlen != 0) { + if (curlen != prevlen) { + zip_SEND_CODE(curlen, zip_bl_tree); + count--; + } + // Assert(count >= 3 && count <= 6, " 3_6?"); + zip_SEND_CODE(zip_REP_3_6, zip_bl_tree); + zip_send_bits(count - 3, 2); + } else if (count <= 10) { + zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree); + zip_send_bits(count - 3, 3); + } else { + zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree); + zip_send_bits(count - 11, 7); + } + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } else if (curlen == nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + }; + + /* ========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ + var zip_build_bl_tree = function () { + var max_blindex; // index of last bit length code of non zero freq + + // Determine the bit length frequencies for literal and distance trees + zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code); + zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code); + + // Build the bit length tree: + zip_build_tree(zip_bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = zip_BL_CODES - 1; max_blindex >= 3; max_blindex--) { + if (zip_bl_tree[zip_bl_order[max_blindex]].dl != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + zip_opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + return max_blindex; + }; + + /* ========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ + var zip_send_all_trees = function (lcodes, dcodes, blcodes) { // number of codes for each tree + var rank; // index in bl_order + zip_send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt + zip_send_bits(dcodes - 1, 5); + zip_send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) { + zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3); + } + + // send the literal tree + zip_send_tree(zip_dyn_ltree, lcodes - 1); + + // send the distance tree + zip_send_tree(zip_dyn_dtree, dcodes - 1); + }; + + /* ========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ + var zip_flush_block = function (eof) { // true if this is the last block for a file + var opt_lenb, static_lenb; // opt_len and static_len in bytes + var max_blindex; // index of last bit length code of non zero freq + var stored_len; // length of input block + + stored_len = zip_strstart - zip_block_start; + zip_flag_buf[zip_last_flags] = zip_flags; // Save the flags for the last 8 items + + // Construct the literal and distance trees + zip_build_tree(zip_l_desc); + zip_build_tree(zip_d_desc); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = zip_build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb = (zip_opt_len + 3 + 7) >> 3; + static_lenb = (zip_static_len + 3 + 7) >> 3; + if (static_lenb <= opt_lenb) + opt_lenb = static_lenb; + if (stored_len + 4 <= opt_lenb // 4: two words for the lengths + && zip_block_start >= 0) { + var i; + + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + zip_send_bits((zip_STORED_BLOCK << 1) + eof, 3); + /* send block type */ + zip_bi_windup(); + /* align on byte boundary */ + zip_put_short(stored_len); + zip_put_short(~stored_len); + + // copy block + for (i = 0; i < stored_len; i++) + zip_put_byte(zip_window[zip_block_start + i]); + + } else if (static_lenb == opt_lenb) { + zip_send_bits((zip_STATIC_TREES << 1) + eof, 3); + zip_compress_block(zip_static_ltree, zip_static_dtree); + } else { + zip_send_bits((zip_DYN_TREES << 1) + eof, 3); + zip_send_all_trees(zip_l_desc.max_code + 1, + zip_d_desc.max_code + 1, + max_blindex + 1); + zip_compress_block(zip_dyn_ltree, zip_dyn_dtree); + } + + zip_init_block(); + + if (eof != 0) + zip_bi_windup(); + }; + + /* ========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ + var zip_ct_tally = function (dist, // distance of matched string + lc) { // match length-MIN_MATCH or unmatched char (if dist==0) + zip_l_buf[zip_last_lit++] = lc; + if (dist == 0) { + // lc is the unmatched char + zip_dyn_ltree[lc].fc++; + } else { + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + zip_dyn_ltree[zip_length_code[lc] + zip_LITERALS + 1].fc++; + zip_dyn_dtree[zip_D_CODE(dist)].fc++; + + zip_d_buf[zip_last_dist++] = dist; + zip_flags |= zip_flag_bit; + } + zip_flag_bit <<= 1; + + // Output the flags if they fill a byte + if ((zip_last_lit & 7) == 0) { + zip_flag_buf[zip_last_flags++] = zip_flags; + zip_flags = 0; + zip_flag_bit = 1; + } + // Try to guess if it is profitable to stop the current block here + if (zip_compr_level > 2 && (zip_last_lit & 0xfff) == 0) { + // Compute an upper bound for the compressed length + var out_length = zip_last_lit * 8; + var in_length = zip_strstart - zip_block_start; + var dcode; + + for (dcode = 0; dcode < zip_D_CODES; dcode++) { + out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]); + } + out_length >>= 3; + if (zip_last_dist < parseInt(zip_last_lit / 2) && + out_length < parseInt(in_length / 2)) + return true; + } + return (zip_last_lit == LIT_BUFSIZE - 1 || + zip_last_dist == zip_DIST_BUFSIZE); + /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + }; + + /* ========================================================================== + * Send the block data compressed using the given Huffman trees + */ + var zip_compress_block = function (ltree, // literal tree + dtree) { // distance tree + var dist; // distance of matched string + var lc; // match length or unmatched char (if dist == 0) + var lx = 0; // running index in l_buf + var dx = 0; // running index in d_buf + var fx = 0; // running index in flag_buf + var flag = 0; // current flags + var code; // the code to send + var extra; // number of extra bits to send + + if (zip_last_lit != 0) do { + if ((lx & 7) == 0) + flag = zip_flag_buf[fx++]; + lc = zip_l_buf[lx++] & 0xff; + if ((flag & 1) == 0) { + zip_SEND_CODE(lc, ltree); + /* send a literal byte */ + } else { + // Here, lc is the match length - MIN_MATCH + code = zip_length_code[lc]; + zip_SEND_CODE(code + zip_LITERALS + 1, ltree); // send the length code + extra = zip_extra_lbits[code]; + if (extra != 0) { + lc -= zip_base_length[code]; + zip_send_bits(lc, extra); // send the extra length bits + } + dist = zip_d_buf[dx++]; + // Here, dist is the match distance - 1 + code = zip_D_CODE(dist); + zip_SEND_CODE(code, dtree); // send the distance code + extra = zip_extra_dbits[code]; + if (extra != 0) { + dist -= zip_base_dist[code]; + zip_send_bits(dist, extra); // send the extra distance bits + } + } // literal or match pair ? + flag >>= 1; + } while (lx < zip_last_lit); + + zip_SEND_CODE(zip_END_BLOCK, ltree); + }; + + /* ========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ + var zip_Buf_size = 16; // bit size of bi_buf + var zip_send_bits = function (value, // value to send + length) { // number of bits + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (zip_bi_valid > zip_Buf_size - length) { + zip_bi_buf |= (value << zip_bi_valid); + zip_put_short(zip_bi_buf); + zip_bi_buf = (value >> (zip_Buf_size - zip_bi_valid)); + zip_bi_valid += length - zip_Buf_size; + } else { + zip_bi_buf |= value << zip_bi_valid; + zip_bi_valid += length; + } + }; + + /* ========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ + var zip_bi_reverse = function (code, // the value to invert + len) { // its bit length + var res = 0; + do { + res |= code & 1; + code >>= 1; + res <<= 1; + } while (--len > 0); + return res >> 1; + }; + + /* ========================================================================== + * Write out any remaining bits in an incomplete byte. + */ + var zip_bi_windup = function () { + if (zip_bi_valid > 8) { + zip_put_short(zip_bi_buf); + } else if (zip_bi_valid > 0) { + zip_put_byte(zip_bi_buf); + } + zip_bi_buf = 0; + zip_bi_valid = 0; + }; + + var zip_qoutbuf = function () { + if (zip_outcnt != 0) { + var q, i; + q = zip_new_queue(); + if (zip_qhead == null) + zip_qhead = zip_qtail = q; + else + zip_qtail = zip_qtail.next = q; + q.len = zip_outcnt - zip_outoff; + for (i = 0; i < q.len; i++) + q.ptr[i] = zip_outbuf[zip_outoff + i]; + zip_outcnt = zip_outoff = 0; + } + }; + + function deflate(buffData, level) { + zip_deflate_data = buffData; + zip_deflate_pos = 0; + zip_deflate_start(level); + + var buff = new Array(1024), + pages = [], + totalSize = 0, + i; + + for (i = 0; i < 1024; i++) buff[i] = 0; + while ((i = zip_deflate_internal(buff, 0, buff.length)) > 0) { + var buf = new Buffer(buff.slice(0, i)); + pages.push(buf); + totalSize += buf.length; + } + + if (pages.length == 1) { + return pages[0]; + } + + var result = new Buffer(totalSize), + index = 0; + + for (i = 0; i < pages.length; i++) { + pages[i].copy(result, index); + index = index + pages[i].length + } + + return result; + } + + return { + deflate: function () { + return deflate(inbuf, 8); + } + } +} + +module.exports = function (/*Buffer*/inbuf) { + + var zlib = require("zlib"); + + return { + deflate: function () { + return new JSDeflater(inbuf).deflate(); + }, + + deflateAsync: function (/*Function*/callback) { + var tmp = zlib.createDeflateRaw({chunkSize:(parseInt(inbuf.length / 1024) + 1)*1024}), + parts = [], total = 0; + tmp.on('data', function(data) { + parts.push(data); + total += data.length; + }); + tmp.on('end', function() { + var buf = new Buffer(total), written = 0; + buf.fill(0); + + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + part.copy(buf, written); + written += part.length; + } + callback && callback(buf); + }); + tmp.end(inbuf); + } + } +}; diff --git a/www/node_modules/adm-zip/methods/index.js b/www/node_modules/adm-zip/methods/index.js new file mode 100644 index 0000000..ddcbba6 --- /dev/null +++ b/www/node_modules/adm-zip/methods/index.js @@ -0,0 +1,2 @@ +exports.Deflater = require("./deflater"); +exports.Inflater = require("./inflater"); \ No newline at end of file diff --git a/www/node_modules/adm-zip/methods/inflater.js b/www/node_modules/adm-zip/methods/inflater.js new file mode 100644 index 0000000..59536c9 --- /dev/null +++ b/www/node_modules/adm-zip/methods/inflater.js @@ -0,0 +1,448 @@ +var Buffer = require("buffer").Buffer; + +function JSInflater(/*Buffer*/input) { + + var WSIZE = 0x8000, + slide = new Buffer(0x10000), + windowPos = 0, + fixedTableList = null, + fixedTableDist, + fixedLookup, + bitBuf = 0, + bitLen = 0, + method = -1, + eof = false, + copyLen = 0, + copyDist = 0, + tblList, tblDist, bitList, bitdist, + + inputPosition = 0, + + MASK_BITS = [0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff], + LENS = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0], + LEXT = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99], + DISTS = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577], + DEXT = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13], + BITORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; + + function HuffTable(clen, cnum, cval, blist, elist, lookupm) { + + this.status = 0; + this.root = null; + this.maxbit = 0; + + var el, f, tail, + offsets = [], + countTbl = [], + sTbl = [], + values = [], + tentry = {extra: 0, bitcnt: 0, lbase: 0, next: null}; + + tail = this.root = null; + for(var i = 0; i < 0x11; i++) { countTbl[i] = 0; sTbl[i] = 0; offsets[i] = 0; } + for(i = 0; i < 0x120; i++) values[i] = 0; + + el = cnum > 256 ? clen[256] : 16; + + var pidx = -1; + while (++pidx < cnum) countTbl[clen[pidx]]++; + + if(countTbl[0] == cnum) return; + + for(var j = 1; j <= 16; j++) if(countTbl[j] != 0) break; + var bitLen = j; + for(i = 16; i != 0; i--) if(countTbl[i] != 0) break; + var maxLen = i; + + lookupm < j && (lookupm = j); + + var dCodes = 1 << j; + for(; j < i; j++, dCodes <<= 1) + if((dCodes -= countTbl[j]) < 0) { + this.status = 2; + this.maxbit = lookupm; + return; + } + + if((dCodes -= countTbl[i]) < 0) { + this.status = 2; + this.maxbit = lookupm; + return; + } + + countTbl[i] += dCodes; + offsets[1] = j = 0; + pidx = 1; + var xp = 2; + while(--i > 0) offsets[xp++] = (j += countTbl[pidx++]); + pidx = 0; + i = 0; + do { + (j = clen[pidx++]) && (values[offsets[j]++] = i); + } while(++i < cnum); + cnum = offsets[maxLen]; + offsets[0] = i = 0; + pidx = 0; + + var level = -1, + w = sTbl[0] = 0, + cnode = null, + tblCnt = 0, + tblStack = []; + + for(; bitLen <= maxLen; bitLen++) { + var kccnt = countTbl[bitLen]; + while(kccnt-- > 0) { + while(bitLen > w + sTbl[1 + level]) { + w += sTbl[1 + level]; + level++; + tblCnt = (tblCnt = maxLen - w) > lookupm ? lookupm : tblCnt; + if((f = 1 << (j = bitLen - w)) > kccnt + 1) { + f -= kccnt + 1; + xp = bitLen; + while(++j < tblCnt) { + if((f <<= 1) <= countTbl[++xp]) break; + f -= countTbl[xp]; + } + } + if(w + j > el && w < el) j = el - w; + tblCnt = 1 << j; + sTbl[1 + level] = j; + cnode = []; + while (cnode.length < tblCnt) cnode.push({extra: 0, bitcnt: 0, lbase: 0, next: null}); + if (tail == null) { + tail = this.root = {next:null, list:null}; + } else { + tail = tail.next = {next:null, list:null} + } + tail.next = null; + tail.list = cnode; + + tblStack[level] = cnode; + + if(level > 0) { + offsets[level] = i; + tentry.bitcnt = sTbl[level]; + tentry.extra = 16 + j; + tentry.next = cnode; + j = (i & ((1 << w) - 1)) >> (w - sTbl[level]); + + tblStack[level-1][j].extra = tentry.extra; + tblStack[level-1][j].bitcnt = tentry.bitcnt; + tblStack[level-1][j].lbase = tentry.lbase; + tblStack[level-1][j].next = tentry.next; + } + } + tentry.bitcnt = bitLen - w; + if(pidx >= cnum) + tentry.extra = 99; + else if(values[pidx] < cval) { + tentry.extra = (values[pidx] < 256 ? 16 : 15); + tentry.lbase = values[pidx++]; + } else { + tentry.extra = elist[values[pidx] - cval]; + tentry.lbase = blist[values[pidx++] - cval]; + } + + f = 1 << (bitLen - w); + for(j = i >> w; j < tblCnt; j += f) { + cnode[j].extra = tentry.extra; + cnode[j].bitcnt = tentry.bitcnt; + cnode[j].lbase = tentry.lbase; + cnode[j].next = tentry.next; + } + for(j = 1 << (bitLen - 1); (i & j) != 0; j >>= 1) + i ^= j; + i ^= j; + while((i & ((1 << w) - 1)) != offsets[level]) { + w -= sTbl[level]; + level--; + } + } + } + + this.maxbit = sTbl[1]; + this.status = ((dCodes != 0 && maxLen != 1) ? 1 : 0); + } + + function addBits(n) { + while(bitLen < n) { + bitBuf |= input[inputPosition++] << bitLen; + bitLen += 8; + } + return bitBuf; + } + + function cutBits(n) { + bitLen -= n; + return bitBuf >>= n; + } + + function maskBits(n) { + while(bitLen < n) { + bitBuf |= input[inputPosition++] << bitLen; + bitLen += 8; + } + var res = bitBuf & MASK_BITS[n]; + bitBuf >>= n; + bitLen -= n; + return res; + } + + function codes(buff, off, size) { + var e, t; + if(size == 0) return 0; + + var n = 0; + for(;;) { + t = tblList.list[addBits(bitList) & MASK_BITS[bitList]]; + e = t.extra; + while(e > 16) { + if(e == 99) return -1; + cutBits(t.bitcnt); + e -= 16; + t = t.next[addBits(e) & MASK_BITS[e]]; + e = t.extra; + } + cutBits(t.bitcnt); + if(e == 16) { + windowPos &= WSIZE - 1; + buff[off + n++] = slide[windowPos++] = t.lbase; + if(n == size) return size; + continue; + } + if(e == 15) break; + + copyLen = t.lbase + maskBits(e); + t = tblDist.list[addBits(bitdist) & MASK_BITS[bitdist]]; + e = t.extra; + + while(e > 16) { + if(e == 99) return -1; + cutBits(t.bitcnt); + e -= 16; + t = t.next[addBits(e) & MASK_BITS[e]]; + e = t.extra + } + cutBits(t.bitcnt); + copyDist = windowPos - t.lbase - maskBits(e); + + while(copyLen > 0 && n < size) { + copyLen--; + copyDist &= WSIZE - 1; + windowPos &= WSIZE - 1; + buff[off + n++] = slide[windowPos++] = slide[copyDist++]; + } + + if(n == size) return size; + } + + method = -1; // done + return n; + } + + function stored(buff, off, size) { + cutBits(bitLen & 7); + var n = maskBits(0x10); + if(n != ((~maskBits(0x10)) & 0xffff)) return -1; + copyLen = n; + + n = 0; + while(copyLen > 0 && n < size) { + copyLen--; + windowPos &= WSIZE - 1; + buff[off + n++] = slide[windowPos++] = maskBits(8); + } + + if(copyLen == 0) method = -1; + return n; + } + + function fixed(buff, off, size) { + var fixed_bd = 0; + if(fixedTableList == null) { + var lengths = []; + + for(var symbol = 0; symbol < 144; symbol++) lengths[symbol] = 8; + for(; symbol < 256; symbol++) lengths[symbol] = 9; + for(; symbol < 280; symbol++) lengths[symbol] = 7; + for(; symbol < 288; symbol++) lengths[symbol] = 8; + + fixedLookup = 7; + + var htbl = new HuffTable(lengths, 288, 257, LENS, LEXT, fixedLookup); + + if(htbl.status != 0) return -1; + + fixedTableList = htbl.root; + fixedLookup = htbl.maxbit; + + for(symbol = 0; symbol < 30; symbol++) lengths[symbol] = 5; + fixed_bd = 5; + + htbl = new HuffTable(lengths, 30, 0, DISTS, DEXT, fixed_bd); + if(htbl.status > 1) { + fixedTableList = null; + return -1; + } + fixedTableDist = htbl.root; + fixed_bd = htbl.maxbit; + } + + tblList = fixedTableList; + tblDist = fixedTableDist; + bitList = fixedLookup; + bitdist = fixed_bd; + return codes(buff, off, size); + } + + function dynamic(buff, off, size) { + var ll = new Array(0x023C); + + for (var m = 0; m < 0x023C; m++) ll[m] = 0; + + var llencnt = 257 + maskBits(5), + dcodescnt = 1 + maskBits(5), + bitlencnt = 4 + maskBits(4); + + if(llencnt > 286 || dcodescnt > 30) return -1; + + for(var j = 0; j < bitlencnt; j++) ll[BITORDER[j]] = maskBits(3); + for(; j < 19; j++) ll[BITORDER[j]] = 0; + + // build decoding table for trees--single level, 7 bit lookup + bitList = 7; + var hufTable = new HuffTable(ll, 19, 19, null, null, bitList); + if(hufTable.status != 0) + return -1; // incomplete code set + + tblList = hufTable.root; + bitList = hufTable.maxbit; + var lencnt = llencnt + dcodescnt, + i = 0, + lastLen = 0; + while(i < lencnt) { + var hufLcode = tblList.list[addBits(bitList) & MASK_BITS[bitList]]; + j = hufLcode.bitcnt; + cutBits(j); + j = hufLcode.lbase; + if(j < 16) + ll[i++] = lastLen = j; + else if(j == 16) { + j = 3 + maskBits(2); + if(i + j > lencnt) return -1; + while(j-- > 0) ll[i++] = lastLen; + } else if(j == 17) { + j = 3 + maskBits(3); + if(i + j > lencnt) return -1; + while(j-- > 0) ll[i++] = 0; + lastLen = 0; + } else { + j = 11 + maskBits(7); + if(i + j > lencnt) return -1; + while(j-- > 0) ll[i++] = 0; + lastLen = 0; + } + } + bitList = 9; + hufTable = new HuffTable(ll, llencnt, 257, LENS, LEXT, bitList); + bitList == 0 && (hufTable.status = 1); + + if (hufTable.status != 0) return -1; + + tblList = hufTable.root; + bitList = hufTable.maxbit; + + for(i = 0; i < dcodescnt; i++) ll[i] = ll[i + llencnt]; + bitdist = 6; + hufTable = new HuffTable(ll, dcodescnt, 0, DISTS, DEXT, bitdist); + tblDist = hufTable.root; + bitdist = hufTable.maxbit; + + if((bitdist == 0 && llencnt > 257) || hufTable.status != 0) return -1; + + return codes(buff, off, size); + } + + return { + inflate : function(/*Buffer*/outputBuffer) { + tblList = null; + + var size = outputBuffer.length, + offset = 0, i; + + while(offset < size) { + if(eof && method == -1) return; + if(copyLen > 0) { + if(method != 0) { + while(copyLen > 0 && offset < size) { + copyLen--; + copyDist &= WSIZE - 1; + windowPos &= WSIZE - 1; + outputBuffer[offset++] = (slide[windowPos++] = slide[copyDist++]); + } + } else { + while(copyLen > 0 && offset < size) { + copyLen--; + windowPos &= WSIZE - 1; + outputBuffer[offset++] = (slide[windowPos++] = maskBits(8)); + } + copyLen == 0 && (method = -1); // done + } + if (offset == size) return; + } + + if(method == -1) { + if(eof) break; + eof = maskBits(1) != 0; + method = maskBits(2); + tblList = null; + copyLen = 0; + } + switch(method) { + case 0: i = stored(outputBuffer, offset, size - offset); break; + case 1: i = tblList != null ? codes(outputBuffer, offset, size - offset) : fixed(outputBuffer, offset, size - offset); break; + case 2: i = tblList != null ? codes(outputBuffer, offset, size - offset) : dynamic(outputBuffer, offset, size - offset); break; + default: i = -1; break; + } + + if(i == -1) return; + offset += i; + } + } + }; +} + +module.exports = function(/*Buffer*/inbuf) { + var zlib = require("zlib"); + return { + inflateAsync : function(/*Function*/callback) { + var tmp = zlib.createInflateRaw(), + parts = [], total = 0; + tmp.on('data', function(data) { + parts.push(data); + total += data.length; + }); + tmp.on('end', function() { + var buf = new Buffer(total), written = 0; + buf.fill(0); + + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + part.copy(buf, written); + written += part.length; + } + callback && callback(buf); + }); + tmp.end(inbuf) + }, + + inflate : function(/*Buffer*/outputBuffer) { + var x = { + x: new JSInflater(inbuf) + }; + x.x.inflate(outputBuffer); + delete(x.x); + } + } +}; diff --git a/www/node_modules/adm-zip/package.json b/www/node_modules/adm-zip/package.json new file mode 100644 index 0000000..d1f56d4 --- /dev/null +++ b/www/node_modules/adm-zip/package.json @@ -0,0 +1,83 @@ +{ + "_args": [ + [ + "adm-zip@0.4.4", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver" + ] + ], + "_from": "adm-zip@0.4.4", + "_id": "adm-zip@0.4.4", + "_inCache": true, + "_installable": true, + "_location": "/adm-zip", + "_npmUser": { + "email": "iacob.campia@gmail.com", + "name": "cthackers" + }, + "_npmVersion": "1.3.24", + "_phantomChildren": {}, + "_requested": { + "name": "adm-zip", + "raw": "adm-zip@0.4.4", + "rawSpec": "0.4.4", + "scope": null, + "spec": "0.4.4", + "type": "version" + }, + "_requiredBy": [ + "/selenium-webdriver" + ], + "_resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz", + "_shasum": "a61ed5ae6905c3aea58b3a657d25033091052736", + "_shrinkwrap": null, + "_spec": "adm-zip@0.4.4", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver", + "author": { + "email": "sy@another-d-mention.ro", + "name": "Nasca Iacob", + "url": "https://github.com/cthackers" + }, + "bugs": { + "email": "sy@another-d-mention.ro", + "url": "https://github.com/cthackers/adm-zip/issues" + }, + "dependencies": {}, + "description": "A Javascript implementation of zip for nodejs. Allows user to create or extract zip files both in memory or to/from disk", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "a61ed5ae6905c3aea58b3a657d25033091052736", + "tarball": "http://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz" + }, + "engines": { + "node": ">=0.3.0" + }, + "homepage": "http://github.com/cthackers/adm-zip", + "keywords": [ + "zip", + "methods", + "archive", + "unzip" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://raw.github.com/cthackers/adm-zip/master/MIT-LICENSE.txt" + } + ], + "main": "adm-zip.js", + "maintainers": [ + { + "email": "iacob.campia@gmail.com", + "name": "cthackers" + } + ], + "name": "adm-zip", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/cthackers/adm-zip.git" + }, + "version": "0.4.4" +} diff --git a/www/node_modules/adm-zip/test/assets/attributes_test.zip b/www/node_modules/adm-zip/test/assets/attributes_test.zip new file mode 100644 index 0000000..d57bfc0 Binary files /dev/null and b/www/node_modules/adm-zip/test/assets/attributes_test.zip differ diff --git a/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden.txt b/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden.txt new file mode 100644 index 0000000..3c3ca55 --- /dev/null +++ b/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden.txt @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden_readonly.txt b/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden_readonly.txt new file mode 100644 index 0000000..3c3ca55 --- /dev/null +++ b/www/node_modules/adm-zip/test/assets/attributes_test/New folder/hidden_readonly.txt @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/www/node_modules/adm-zip/test/assets/attributes_test/New folder/readonly.txt b/www/node_modules/adm-zip/test/assets/attributes_test/New folder/readonly.txt new file mode 100644 index 0000000..3c3ca55 --- /dev/null +++ b/www/node_modules/adm-zip/test/assets/attributes_test/New folder/readonly.txt @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/www/node_modules/adm-zip/test/assets/attributes_test/New folder/somefile.txt b/www/node_modules/adm-zip/test/assets/attributes_test/New folder/somefile.txt new file mode 100644 index 0000000..3c3ca55 --- /dev/null +++ b/www/node_modules/adm-zip/test/assets/attributes_test/New folder/somefile.txt @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/www/node_modules/adm-zip/test/assets/attributes_test/asd/New Text Document.txt b/www/node_modules/adm-zip/test/assets/attributes_test/asd/New Text Document.txt new file mode 100644 index 0000000..e69de29 diff --git a/www/node_modules/adm-zip/test/assets/attributes_test/blank file.txt b/www/node_modules/adm-zip/test/assets/attributes_test/blank file.txt new file mode 100644 index 0000000..e69de29 diff --git a/www/node_modules/adm-zip/test/assets/fast.zip b/www/node_modules/adm-zip/test/assets/fast.zip new file mode 100644 index 0000000..f4ed17b Binary files /dev/null and b/www/node_modules/adm-zip/test/assets/fast.zip differ diff --git a/www/node_modules/adm-zip/test/assets/fastest.zip b/www/node_modules/adm-zip/test/assets/fastest.zip new file mode 100644 index 0000000..f4ed17b Binary files /dev/null and b/www/node_modules/adm-zip/test/assets/fastest.zip differ diff --git a/www/node_modules/adm-zip/test/assets/linux_arc.zip b/www/node_modules/adm-zip/test/assets/linux_arc.zip new file mode 100644 index 0000000..188eccb Binary files /dev/null and b/www/node_modules/adm-zip/test/assets/linux_arc.zip differ diff --git a/www/node_modules/adm-zip/test/assets/maximum.zip b/www/node_modules/adm-zip/test/assets/maximum.zip new file mode 100644 index 0000000..86a8ec7 Binary files /dev/null and b/www/node_modules/adm-zip/test/assets/maximum.zip differ diff --git a/www/node_modules/adm-zip/test/assets/normal.zip b/www/node_modules/adm-zip/test/assets/normal.zip new file mode 100644 index 0000000..b4602c9 Binary files /dev/null and b/www/node_modules/adm-zip/test/assets/normal.zip differ diff --git a/www/node_modules/adm-zip/test/assets/store.zip b/www/node_modules/adm-zip/test/assets/store.zip new file mode 100644 index 0000000..e2add30 Binary files /dev/null and b/www/node_modules/adm-zip/test/assets/store.zip differ diff --git a/www/node_modules/adm-zip/test/assets/ultra.zip b/www/node_modules/adm-zip/test/assets/ultra.zip new file mode 100644 index 0000000..86a8ec7 Binary files /dev/null and b/www/node_modules/adm-zip/test/assets/ultra.zip differ diff --git a/www/node_modules/adm-zip/test/index.js b/www/node_modules/adm-zip/test/index.js new file mode 100644 index 0000000..70acb51 --- /dev/null +++ b/www/node_modules/adm-zip/test/index.js @@ -0,0 +1,5 @@ +var Attr = require("../util").FileAttr, + Zip = require("../adm-zip"), + fs = require("fs"); + +//zip.addLocalFile("./test/readonly.txt"); diff --git a/www/node_modules/adm-zip/util/constants.js b/www/node_modules/adm-zip/util/constants.js new file mode 100644 index 0000000..0548054 --- /dev/null +++ b/www/node_modules/adm-zip/util/constants.js @@ -0,0 +1,84 @@ +module.exports = { + /* The local file header */ + LOCHDR : 30, // LOC header size + LOCSIG : 0x04034b50, // "PK\003\004" + LOCVER : 4, // version needed to extract + LOCFLG : 6, // general purpose bit flag + LOCHOW : 8, // compression method + LOCTIM : 10, // modification time (2 bytes time, 2 bytes date) + LOCCRC : 14, // uncompressed file crc-32 value + LOCSIZ : 18, // compressed size + LOCLEN : 22, // uncompressed size + LOCNAM : 26, // filename length + LOCEXT : 28, // extra field length + + /* The Data descriptor */ + EXTSIG : 0x08074b50, // "PK\007\008" + EXTHDR : 16, // EXT header size + EXTCRC : 4, // uncompressed file crc-32 value + EXTSIZ : 8, // compressed size + EXTLEN : 12, // uncompressed size + + /* The central directory file header */ + CENHDR : 46, // CEN header size + CENSIG : 0x02014b50, // "PK\001\002" + CENVEM : 4, // version made by + CENVER : 6, // version needed to extract + CENFLG : 8, // encrypt, decrypt flags + CENHOW : 10, // compression method + CENTIM : 12, // modification time (2 bytes time, 2 bytes date) + CENCRC : 16, // uncompressed file crc-32 value + CENSIZ : 20, // compressed size + CENLEN : 24, // uncompressed size + CENNAM : 28, // filename length + CENEXT : 30, // extra field length + CENCOM : 32, // file comment length + CENDSK : 34, // volume number start + CENATT : 36, // internal file attributes + CENATX : 38, // external file attributes (host system dependent) + CENOFF : 42, // LOC header offset + + /* The entries in the end of central directory */ + ENDHDR : 22, // END header size + ENDSIG : 0x06054b50, // "PK\005\006" + ENDSUB : 8, // number of entries on this disk + ENDTOT : 10, // total number of entries + ENDSIZ : 12, // central directory size in bytes + ENDOFF : 16, // offset of first CEN header + ENDCOM : 20, // zip file comment length + + /* Compression methods */ + STORED : 0, // no compression + SHRUNK : 1, // shrunk + REDUCED1 : 2, // reduced with compression factor 1 + REDUCED2 : 3, // reduced with compression factor 2 + REDUCED3 : 4, // reduced with compression factor 3 + REDUCED4 : 5, // reduced with compression factor 4 + IMPLODED : 6, // imploded + // 7 reserved + DEFLATED : 8, // deflated + ENHANCED_DEFLATED: 9, // enhanced deflated + PKWARE : 10,// PKWare DCL imploded + // 11 reserved + BZIP2 : 12, // compressed using BZIP2 + // 13 reserved + LZMA : 14, // LZMA + // 15-17 reserved + IBM_TERSE : 18, // compressed using IBM TERSE + IBM_LZ77 : 19, //IBM LZ77 z + + /* General purpose bit flag */ + FLG_ENC : 0, // encripted file + FLG_COMP1 : 1, // compression option + FLG_COMP2 : 2, // compression option + FLG_DESC : 4, // data descriptor + FLG_ENH : 8, // enhanced deflation + FLG_STR : 16, // strong encryption + FLG_LNG : 1024, // language encoding + FLG_MSK : 4096, // mask header values + + /* Load type */ + FILE : 0, + BUFFER : 1, + NONE : 2 +}; diff --git a/www/node_modules/adm-zip/util/errors.js b/www/node_modules/adm-zip/util/errors.js new file mode 100644 index 0000000..db5d69e --- /dev/null +++ b/www/node_modules/adm-zip/util/errors.js @@ -0,0 +1,35 @@ +module.exports = { + /* Header error messages */ + "INVALID_LOC" : "Invalid LOC header (bad signature)", + "INVALID_CEN" : "Invalid CEN header (bad signature)", + "INVALID_END" : "Invalid END header (bad signature)", + + /* ZipEntry error messages*/ + "NO_DATA" : "Nothing to decompress", + "BAD_CRC" : "CRC32 checksum failed", + "FILE_IN_THE_WAY" : "There is a file in the way: %s", + "UNKNOWN_METHOD" : "Invalid/unsupported compression method", + + /* Inflater error messages */ + "AVAIL_DATA" : "inflate::Available inflate data did not terminate", + "INVALID_DISTANCE" : "inflate::Invalid literal/length or distance code in fixed or dynamic block", + "TO_MANY_CODES" : "inflate::Dynamic block code description: too many length or distance codes", + "INVALID_REPEAT_LEN" : "inflate::Dynamic block code description: repeat more than specified lengths", + "INVALID_REPEAT_FIRST" : "inflate::Dynamic block code description: repeat lengths with no first length", + "INCOMPLETE_CODES" : "inflate::Dynamic block code description: code lengths codes incomplete", + "INVALID_DYN_DISTANCE": "inflate::Dynamic block code description: invalid distance code lengths", + "INVALID_CODES_LEN": "inflate::Dynamic block code description: invalid literal/length code lengths", + "INVALID_STORE_BLOCK" : "inflate::Stored block length did not match one's complement", + "INVALID_BLOCK_TYPE" : "inflate::Invalid block type (type == 3)", + + /* ADM-ZIP error messages */ + "CANT_EXTRACT_FILE" : "Could not extract the file", + "CANT_OVERRIDE" : "Target file already exists", + "NO_ZIP" : "No zip file was loaded", + "NO_ENTRY" : "Entry doesn't exist", + "DIRECTORY_CONTENT_ERROR" : "A directory cannot have content", + "FILE_NOT_FOUND" : "File not found: %s", + "NOT_IMPLEMENTED" : "Not implemented", + "INVALID_FILENAME" : "Invalid filename", + "INVALID_FORMAT" : "Invalid or unsupported zip format. No END header found" +}; \ No newline at end of file diff --git a/www/node_modules/adm-zip/util/fattr.js b/www/node_modules/adm-zip/util/fattr.js new file mode 100644 index 0000000..2191ec1 --- /dev/null +++ b/www/node_modules/adm-zip/util/fattr.js @@ -0,0 +1,84 @@ +var fs = require("fs"), + pth = require("path"); + +fs.existsSync = fs.existsSync || pth.existsSync; + +module.exports = function(/*String*/path) { + + var _path = path || "", + _permissions = 0, + _obj = newAttr(), + _stat = null; + + function newAttr() { + return { + directory : false, + readonly : false, + hidden : false, + executable : false, + mtime : 0, + atime : 0 + } + } + + if (_path && fs.existsSync(_path)) { + _stat = fs.statSync(_path); + _obj.directory = _stat.isDirectory(); + _obj.mtime = _stat.mtime; + _obj.atime = _stat.atime; + _obj.executable = !!(1 & parseInt ((_stat.mode & parseInt ("777", 8)).toString (8)[0])); + _obj.readonly = !!(2 & parseInt ((_stat.mode & parseInt ("777", 8)).toString (8)[0])); + _obj.hidden = pth.basename(_path)[0] === "."; + } else { + console.warn("Invalid path: " + _path) + } + + return { + + get directory () { + return _obj.directory; + }, + + get readOnly () { + return _obj.readonly; + }, + + get hidden () { + return _obj.hidden; + }, + + get mtime () { + return _obj.mtime; + }, + + get atime () { + return _obj.atime; + }, + + + get executable () { + return _obj.executable; + }, + + decodeAttributes : function(val) { + + }, + + encodeAttributes : function (val) { + + }, + + toString : function() { + return '{\n' + + '\t"path" : "' + _path + ",\n" + + '\t"isDirectory" : ' + _obj.directory + ",\n" + + '\t"isReadOnly" : ' + _obj.readonly + ",\n" + + '\t"isHidden" : ' + _obj.hidden + ",\n" + + '\t"isExecutable" : ' + _obj.executable + ",\n" + + '\t"mTime" : ' + _obj.mtime + "\n" + + '\t"aTime" : ' + _obj.atime + "\n" + + '}'; + } + } + +}; diff --git a/www/node_modules/adm-zip/util/index.js b/www/node_modules/adm-zip/util/index.js new file mode 100644 index 0000000..935fc1a --- /dev/null +++ b/www/node_modules/adm-zip/util/index.js @@ -0,0 +1,4 @@ +module.exports = require("./utils"); +module.exports.Constants = require("./constants"); +module.exports.Errors = require("./errors"); +module.exports.FileAttr = require("./fattr"); \ No newline at end of file diff --git a/www/node_modules/adm-zip/util/utils.js b/www/node_modules/adm-zip/util/utils.js new file mode 100644 index 0000000..b14db8c --- /dev/null +++ b/www/node_modules/adm-zip/util/utils.js @@ -0,0 +1,145 @@ +var fs = require("fs"), + pth = require('path'); + +fs.existsSync = fs.existsSync || pth.existsSync; + +module.exports = (function() { + + var crcTable = [], + Constants = require('./constants'), + Errors = require('./errors'), + + PATH_SEPARATOR = pth.normalize("/"); + + + function mkdirSync(/*String*/path) { + var resolvedPath = path.split(PATH_SEPARATOR)[0]; + path.split(PATH_SEPARATOR).forEach(function(name) { + if (!name || name.substr(-1,1) == ":") return; + resolvedPath += PATH_SEPARATOR + name; + var stat; + try { + stat = fs.statSync(resolvedPath); + } catch (e) { + fs.mkdirSync(resolvedPath); + } + if (stat && stat.isFile()) + throw Errors.FILE_IN_THE_WAY.replace("%s", resolvedPath); + }); + } + + function findSync(/*String*/root, /*RegExp*/pattern, /*Boolean*/recoursive) { + if (typeof pattern === 'boolean') { + recoursive = pattern; + pattern = undefined; + } + var files = []; + fs.readdirSync(root).forEach(function(file) { + var path = pth.join(root, file); + + if (fs.statSync(path).isDirectory() && recoursive) + files = files.concat(findSync(path, pattern, recoursive)); + + if (!pattern || pattern.test(path)) { + files.push(pth.normalize(path) + (fs.statSync(path).isDirectory() ? PATH_SEPARATOR : "")); + } + + }); + return files; + } + + return { + makeDir : function(/*String*/path) { + mkdirSync(path); + }, + + crc32 : function(buf) { + var b = new Buffer(4); + if (!crcTable.length) { + for (var n = 0; n < 256; n++) { + var c = n; + for (var k = 8; --k >= 0;) // + if ((c & 1) != 0) { c = 0xedb88320 ^ (c >>> 1); } else { c = c >>> 1; } + if (c < 0) { + b.writeInt32LE(c, 0); + c = b.readUInt32LE(0); + } + crcTable[n] = c; + } + } + var crc = 0, off = 0, len = buf.length, c1 = ~crc; + while(--len >= 0) c1 = crcTable[(c1 ^ buf[off++]) & 0xff] ^ (c1 >>> 8); + crc = ~c1; + b.writeInt32LE(crc & 0xffffffff, 0); + return b.readUInt32LE(0); + }, + + methodToString : function(/*Number*/method) { + switch (method) { + case Constants.STORED: + return 'STORED (' + method + ')'; + case Constants.DEFLATED: + return 'DEFLATED (' + method + ')'; + default: + return 'UNSUPPORTED (' + method + ')' + } + + }, + + writeFileTo : function(/*String*/path, /*Buffer*/content, /*Boolean*/overwrite, /*Number*/attr) { + if (fs.existsSync(path)) { + if (!overwrite) + return false; // cannot overwite + + var stat = fs.statSync(path); + if (stat.isDirectory()) { + return false; + } + } + var folder = pth.dirname(path); + if (!fs.existsSync(folder)) { + mkdirSync(folder); + } + + var fd; + try { + fd = fs.openSync(path, 'w', 438); // 0666 + } catch(e) { + fs.chmodSync(path, 438); + fd = fs.openSync(path, 'w', 438); + } + if (fd) { + fs.writeSync(fd, content, 0, content.length, 0); + fs.closeSync(fd); + } + fs.chmodSync(path, attr || 438); + return true; + }, + + findFiles : function(/*String*/path) { + return findSync(path, true); + }, + + getAttributes : function(/*String*/path) { + + }, + + setAttributes : function(/*String*/path) { + + }, + + toBuffer : function(input) { + if (Buffer.isBuffer(input)) { + return input; + } else { + if (input.length == 0) { + return new Buffer(0) + } + return new Buffer(input, 'utf8'); + } + }, + + Constants : Constants, + Errors : Errors + } +})(); diff --git a/www/node_modules/adm-zip/zipEntry.js b/www/node_modules/adm-zip/zipEntry.js new file mode 100644 index 0000000..02c3172 --- /dev/null +++ b/www/node_modules/adm-zip/zipEntry.js @@ -0,0 +1,224 @@ +var Utils = require("./util"), + Headers = require("./headers"), + Constants = Utils.Constants, + Methods = require("./methods"); + +module.exports = function (/*Buffer*/input) { + + var _entryHeader = new Headers.EntryHeader(), + _entryName = new Buffer(0), + _comment = new Buffer(0), + _isDirectory = false, + uncompressedData = null, + _extra = new Buffer(0); + + function getCompressedDataFromZip() { + if (!input || !Buffer.isBuffer(input)) { + return new Buffer(0); + } + _entryHeader.loadDataHeaderFromBinary(input); + return input.slice(_entryHeader.realDataOffset, _entryHeader.realDataOffset + _entryHeader.compressedSize) + } + + function crc32OK(data) { + // if bit 3 (0x08) of the general-purpose flags field is set, then the CRC-32 and file sizes are not known when the header is written + if (_entryHeader.flags & 0x8 != 0x8) { + if (Utils.crc32(data) != _entryHeader.crc) { + return false; + } + } else { + // @TODO: load and check data descriptor header + // The fields in the local header are filled with zero, and the CRC-32 and size are appended in a 12-byte structure + // (optionally preceded by a 4-byte signature) immediately after the compressed data: + } + return true; + } + + function decompress(/*Boolean*/async, /*Function*/callback) { + if (_isDirectory) { + if (async && callback) { + callback(new Buffer(0), Utils.Errors.DIRECTORY_CONTENT_ERROR); //si added error. + } + return new Buffer(0); + } + + var compressedData = getCompressedDataFromZip(); + if (compressedData.length == 0) { + if (async && callback) callback(compressedData, Utils.Errors.NO_DATA);//si added error. + return compressedData; + } + + var data = new Buffer(_entryHeader.size); + data.fill(0); + + switch (_entryHeader.method) { + case Utils.Constants.STORED: + compressedData.copy(data); + if (!crc32OK(data)) { + if (async && callback) callback(data, Utils.Errors.BAD_CRC);//si added error + return Utils.Errors.BAD_CRC; + } else {//si added otherwise did not seem to return data. + if (async && callback) callback(data); + return data; + } + break; + case Utils.Constants.DEFLATED: + var inflater = new Methods.Inflater(compressedData); + if (!async) { + inflater.inflate(data); + if (!crc32OK(data)) { + console.warn(Utils.Errors.BAD_CRC + " " + _entryName.toString()) + } + return data; + } else { + inflater.inflateAsync(function(result) { + result.copy(data, 0); + if (crc32OK(data)) { + if (callback) callback(data, Utils.Errors.BAD_CRC); //si added error + } else { //si added otherwise did not seem to return data. + if (callback) callback(data); + } + }) + } + break; + default: + if (async && callback) callback(new Buffer(0), Utils.Errors.UNKNOWN_METHOD); + return Utils.Errors.UNKNOWN_METHOD; + } + } + + function compress(/*Boolean*/async, /*Function*/callback) { + if ((!uncompressedData || !uncompressedData.length) && Buffer.isBuffer(input)) { + // no data set or the data wasn't changed to require recompression + if (async && callback) callback(getCompressedDataFromZip()); + return getCompressedDataFromZip(); + } + + if (uncompressedData.length && !_isDirectory) { + var compressedData; + // Local file header + switch (_entryHeader.method) { + case Utils.Constants.STORED: + _entryHeader.compressedSize = _entryHeader.size; + + compressedData = new Buffer(uncompressedData.length); + uncompressedData.copy(compressedData); + + if (async && callback) callback(compressedData); + return compressedData; + + break; + default: + case Utils.Constants.DEFLATED: + + var deflater = new Methods.Deflater(uncompressedData); + if (!async) { + var deflated = deflater.deflate(); + _entryHeader.compressedSize = deflated.length; + return deflated; + } else { + deflater.deflateAsync(function(data) { + compressedData = new Buffer(data.length); + _entryHeader.compressedSize = data.length; + data.copy(compressedData); + callback && callback(compressedData); + }) + } + deflater = null; + break; + } + } else { + if (async && callback) { + callback(new Buffer(0)); + } else { + return new Buffer(0); + } + } + } + + return { + get entryName () { return _entryName.toString(); }, + get rawEntryName() { return _entryName; }, + set entryName (val) { + _entryName = Utils.toBuffer(val); + var lastChar = _entryName[_entryName.length - 1]; + _isDirectory = (lastChar == 47) || (lastChar == 92); + _entryHeader.fileNameLength = _entryName.length; + }, + + get extra () { return _extra; }, + set extra (val) { + _extra = val; + _entryHeader.extraLength = val.length; + }, + + get comment () { return _comment.toString(); }, + set comment (val) { + _comment = Utils.toBuffer(val); + _entryHeader.commentLength = _comment.length; + }, + + get name () { var n = _entryName.toString(); return _isDirectory ? n.substr(n.length - 1).split("/").pop() : n.split("/").pop(); }, + get isDirectory () { return _isDirectory }, + + getCompressedData : function() { + return compress(false, null) + }, + + getCompressedDataAsync : function(/*Function*/callback) { + compress(true, callback) + }, + + setData : function(value) { + uncompressedData = Utils.toBuffer(value); + if (!_isDirectory && uncompressedData.length) { + _entryHeader.size = uncompressedData.length; + _entryHeader.method = Utils.Constants.DEFLATED; + _entryHeader.crc = Utils.crc32(value); + } else { // folders and blank files should be stored + _entryHeader.method = Utils.Constants.STORED; + } + }, + + getData : function() { + return decompress(false, null); + }, + + getDataAsync : function(/*Function*/callback) { + decompress(true, callback) + }, + + set header(/*Buffer*/data) { + _entryHeader.loadFromBinary(data); + }, + + get header() { + return _entryHeader; + }, + + packHeader : function() { + var header = _entryHeader.entryHeaderToBinary(); + // add + _entryName.copy(header, Utils.Constants.CENHDR); + if (_entryHeader.extraLength) { + _extra.copy(header, Utils.Constants.CENHDR + _entryName.length) + } + if (_entryHeader.commentLength) { + _comment.copy(header, Utils.Constants.CENHDR + _entryName.length + _entryHeader.extraLength, _comment.length); + } + return header; + }, + + toString : function() { + return '{\n' + + '\t"entryName" : "' + _entryName.toString() + "\",\n" + + '\t"name" : "' + _entryName.toString().split("/").pop() + "\",\n" + + '\t"comment" : "' + _comment.toString() + "\",\n" + + '\t"isDirectory" : ' + _isDirectory + ",\n" + + '\t"header" : ' + _entryHeader.toString().replace(/\t/mg, "\t\t") + ",\n" + + '\t"compressedData" : <' + (input && input.length + " bytes buffer" || "null") + ">\n" + + '\t"data" : <' + (uncompressedData && uncompressedData.length + " bytes buffer" || "null") + ">\n" + + '}'; + } + } +}; diff --git a/www/node_modules/adm-zip/zipFile.js b/www/node_modules/adm-zip/zipFile.js new file mode 100644 index 0000000..f066d7e --- /dev/null +++ b/www/node_modules/adm-zip/zipFile.js @@ -0,0 +1,311 @@ +var ZipEntry = require("./zipEntry"), + Headers = require("./headers"), + Utils = require("./util"); + +module.exports = function(/*String|Buffer*/input, /*Number*/inputType) { + var entryList = [], + entryTable = {}, + _comment = new Buffer(0), + filename = "", + fs = require("fs"), + inBuffer = null, + mainHeader = new Headers.MainHeader(); + + if (inputType == Utils.Constants.FILE) { + // is a filename + filename = input; + inBuffer = fs.readFileSync(filename); + readMainHeader(); + } else if (inputType == Utils.Constants.BUFFER) { + // is a memory buffer + inBuffer = input; + readMainHeader(); + } else { + // none. is a new file + } + + function readEntries() { + entryTable = {}; + entryList = new Array(mainHeader.diskEntries); // total number of entries + var index = mainHeader.offset; // offset of first CEN header + for(var i = 0; i < entryList.length; i++) { + + var tmp = index, + entry = new ZipEntry(inBuffer); + entry.header = inBuffer.slice(tmp, tmp += Utils.Constants.CENHDR); + + entry.entryName = inBuffer.slice(tmp, tmp += entry.header.fileNameLength); + + if (entry.header.extraLength) { + entry.extra = inBuffer.slice(tmp, tmp += entry.header.extraLength); + } + + if (entry.header.commentLength) + entry.comment = inBuffer.slice(tmp, tmp + entry.header.commentLength); + + index += entry.header.entryHeaderSize; + + entryList[i] = entry; + entryTable[entry.entryName] = entry; + } + } + + function readMainHeader() { + var i = inBuffer.length - Utils.Constants.ENDHDR, // END header size + n = Math.max(0, i - 0xFFFF), // 0xFFFF is the max zip file comment length + endOffset = 0; // Start offset of the END header + + for (i; i >= n; i--) { + if (inBuffer[i] != 0x50) continue; // quick check that the byte is 'P' + if (inBuffer.readUInt32LE(i) == Utils.Constants.ENDSIG) { // "PK\005\006" + endOffset = i; + break; + } + } + if (!endOffset) + throw Utils.Errors.INVALID_FORMAT; + + mainHeader.loadFromBinary(inBuffer.slice(endOffset, endOffset + Utils.Constants.ENDHDR)); + if (mainHeader.commentLength) { + _comment = inBuffer.slice(endOffset + Utils.Constants.ENDHDR); + } + readEntries(); + } + + return { + /** + * Returns an array of ZipEntry objects existent in the current opened archive + * @return Array + */ + get entries () { + return entryList; + }, + + /** + * Archive comment + * @return {String} + */ + get comment () { return _comment.toString(); }, + set comment(val) { + mainHeader.commentLength = val.length; + _comment = val; + }, + + /** + * Returns a reference to the entry with the given name or null if entry is inexistent + * + * @param entryName + * @return ZipEntry + */ + getEntry : function(/*String*/entryName) { + return entryTable[entryName] || null; + }, + + /** + * Adds the given entry to the entry list + * + * @param entry + */ + setEntry : function(/*ZipEntry*/entry) { + entryList.push(entry); + entryTable[entry.entryName] = entry; + mainHeader.totalEntries = entryList.length; + }, + + /** + * Removes the entry with the given name from the entry list. + * + * If the entry is a directory, then all nested files and directories will be removed + * @param entryName + */ + deleteEntry : function(/*String*/entryName) { + var entry = entryTable[entryName]; + if (entry && entry.isDirectory) { + var _self = this; + this.getEntryChildren(entry).forEach(function(child) { + if (child.entryName != entryName) { + _self.deleteEntry(child.entryName) + } + }) + } + entryList.splice(entryList.indexOf(entry), 1); + delete(entryTable[entryName]); + mainHeader.totalEntries = entryList.length; + }, + + /** + * Iterates and returns all nested files and directories of the given entry + * + * @param entry + * @return Array + */ + getEntryChildren : function(/*ZipEntry*/entry) { + if (entry.isDirectory) { + var list = [], + name = entry.entryName, + len = name.length; + + entryList.forEach(function(zipEntry) { + if (zipEntry.entryName.substr(0, len) == name) { + list.push(zipEntry); + } + }); + return list; + } + return [] + }, + + /** + * Returns the zip file + * + * @return Buffer + */ + compressToBuffer : function() { + if (entryList.length > 1) { + entryList.sort(function(a, b) { + var nameA = a.entryName.toLowerCase(); + var nameB = b.entryName.toLowerCase(); + if (nameA < nameB) {return -1} + if (nameA > nameB) {return 1} + return 0; + }); + } + + var totalSize = 0, + dataBlock = [], + entryHeaders = [], + dindex = 0; + + mainHeader.size = 0; + mainHeader.offset = 0; + + entryList.forEach(function(entry) { + entry.header.offset = dindex; + + // compress data and set local and entry header accordingly. Reason why is called first + var compressedData = entry.getCompressedData(); + // data header + var dataHeader = entry.header.dataHeaderToBinary(); + var postHeader = new Buffer(entry.entryName + entry.extra.toString()); + var dataLength = dataHeader.length + postHeader.length + compressedData.length; + + dindex += dataLength; + + dataBlock.push(dataHeader); + dataBlock.push(postHeader); + dataBlock.push(compressedData); + + var entryHeader = entry.packHeader(); + entryHeaders.push(entryHeader); + mainHeader.size += entryHeader.length; + totalSize += (dataLength + entryHeader.length); + }); + + totalSize += mainHeader.mainHeaderSize; // also includes zip file comment length + // point to end of data and begining of central directory first record + mainHeader.offset = dindex; + + dindex = 0; + var outBuffer = new Buffer(totalSize); + dataBlock.forEach(function(content) { + content.copy(outBuffer, dindex); // write data blocks + dindex += content.length; + }); + entryHeaders.forEach(function(content) { + content.copy(outBuffer, dindex); // write central directory entries + dindex += content.length; + }); + + var mh = mainHeader.toBinary(); + if (_comment) { + _comment.copy(mh, Utils.Constants.ENDHDR); // add zip file comment + } + + mh.copy(outBuffer, dindex); // write main header + + return outBuffer + }, + + toAsyncBuffer : function(/*Function*/onSuccess,/*Function*/onFail,/*Function*/onItemStart,/*Function*/onItemEnd) { + if (entryList.length > 1) { + entryList.sort(function(a, b) { + var nameA = a.entryName.toLowerCase(); + var nameB = b.entryName.toLowerCase(); + if (nameA > nameB) {return -1} + if (nameA < nameB) {return 1} + return 0; + }); + } + + var totalSize = 0, + dataBlock = [], + entryHeaders = [], + dindex = 0; + + mainHeader.size = 0; + mainHeader.offset = 0; + + var compress=function(entryList){ + var self=arguments.callee; + var entry; + if(entryList.length){ + var entry=entryList.pop(); + var name=entry.entryName + entry.extra.toString(); + if(onItemStart)onItemStart(name); + entry.getCompressedDataAsync(function(compressedData){ + if(onItemEnd)onItemEnd(name); + + entry.header.offset = dindex; + // data header + var dataHeader = entry.header.dataHeaderToBinary(); + var postHeader = new Buffer(name); + var dataLength = dataHeader.length + postHeader.length + compressedData.length; + + dindex += dataLength; + + dataBlock.push(dataHeader); + dataBlock.push(postHeader); + dataBlock.push(compressedData); + + var entryHeader = entry.packHeader(); + entryHeaders.push(entryHeader); + mainHeader.size += entryHeader.length; + totalSize += (dataLength + entryHeader.length); + + if(entryList.length){ + self(entryList); + }else{ + + + totalSize += mainHeader.mainHeaderSize; // also includes zip file comment length + // point to end of data and begining of central directory first record + mainHeader.offset = dindex; + + dindex = 0; + var outBuffer = new Buffer(totalSize); + dataBlock.forEach(function(content) { + content.copy(outBuffer, dindex); // write data blocks + dindex += content.length; + }); + entryHeaders.forEach(function(content) { + content.copy(outBuffer, dindex); // write central directory entries + dindex += content.length; + }); + + var mh = mainHeader.toBinary(); + if (_comment) { + _comment.copy(mh, Utils.Constants.ENDHDR); // add zip file comment + } + + mh.copy(outBuffer, dindex); // write main header + + onSuccess(outBuffer); + } + }); + } + }; + + compress(entryList); + } + } +}; diff --git a/www/node_modules/balanced-match/.npmignore b/www/node_modules/balanced-match/.npmignore new file mode 100644 index 0000000..fd4f2b0 --- /dev/null +++ b/www/node_modules/balanced-match/.npmignore @@ -0,0 +1,2 @@ +node_modules +.DS_Store diff --git a/www/node_modules/balanced-match/.travis.yml b/www/node_modules/balanced-match/.travis.yml new file mode 100644 index 0000000..6e5919d --- /dev/null +++ b/www/node_modules/balanced-match/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" diff --git a/www/node_modules/balanced-match/LICENSE.md b/www/node_modules/balanced-match/LICENSE.md new file mode 100644 index 0000000..2cdc8e4 --- /dev/null +++ b/www/node_modules/balanced-match/LICENSE.md @@ -0,0 +1,21 @@ +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/www/node_modules/balanced-match/Makefile b/www/node_modules/balanced-match/Makefile new file mode 100644 index 0000000..fa5da71 --- /dev/null +++ b/www/node_modules/balanced-match/Makefile @@ -0,0 +1,6 @@ + +test: + @node_modules/.bin/tape test/*.js + +.PHONY: test + diff --git a/www/node_modules/balanced-match/README.md b/www/node_modules/balanced-match/README.md new file mode 100644 index 0000000..421f3aa --- /dev/null +++ b/www/node_modules/balanced-match/README.md @@ -0,0 +1,89 @@ +# balanced-match + +Match balanced string pairs, like `{` and `}` or `` and ``. + +[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) +[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) + +[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) + +## Example + +Get the first matching pair of braces: + +```js +var balanced = require('balanced-match'); + +console.log(balanced('{', '}', 'pre{in{nested}}post')); +console.log(balanced('{', '}', 'pre{first}between{second}post')); +``` + +The matches are: + +```bash +$ node example.js +{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } +{ start: 3, + end: 9, + pre: 'pre', + body: 'first', + post: 'between{second}post' } +``` + +## API + +### var m = balanced(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +object with those keys: + +* **start** the index of the first match of `a` +* **end** the index of the matching `b` +* **pre** the preamble, `a` and `b` not included +* **body** the match, `a` and `b` not included +* **post** the postscript, `a` and `b` not included + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']`. + +### var r = balanced.range(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +array with indexes: `[ , ]`. + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]`. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install balanced-match +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/www/node_modules/balanced-match/example.js b/www/node_modules/balanced-match/example.js new file mode 100644 index 0000000..c02ad34 --- /dev/null +++ b/www/node_modules/balanced-match/example.js @@ -0,0 +1,5 @@ +var balanced = require('./'); + +console.log(balanced('{', '}', 'pre{in{nested}}post')); +console.log(balanced('{', '}', 'pre{first}between{second}post')); + diff --git a/www/node_modules/balanced-match/index.js b/www/node_modules/balanced-match/index.js new file mode 100644 index 0000000..75f3d71 --- /dev/null +++ b/www/node_modules/balanced-match/index.js @@ -0,0 +1,50 @@ +module.exports = balanced; +function balanced(a, b, str) { + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i < str.length && i >= 0 && ! result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} diff --git a/www/node_modules/balanced-match/package.json b/www/node_modules/balanced-match/package.json new file mode 100644 index 0000000..6ae13e8 --- /dev/null +++ b/www/node_modules/balanced-match/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + "balanced-match@^0.3.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/brace-expansion" + ] + ], + "_from": "balanced-match@>=0.3.0 <0.4.0", + "_id": "balanced-match@0.3.0", + "_inCache": true, + "_installable": true, + "_location": "/balanced-match", + "_nodeVersion": "4.2.1", + "_npmUser": { + "email": "julian@juliangruber.com", + "name": "juliangruber" + }, + "_npmVersion": "2.14.7", + "_phantomChildren": {}, + "_requested": { + "name": "balanced-match", + "raw": "balanced-match@^0.3.0", + "rawSpec": "^0.3.0", + "scope": null, + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/brace-expansion" + ], + "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.3.0.tgz", + "_shasum": "a91cdd1ebef1a86659e70ff4def01625fc2d6756", + "_shrinkwrap": null, + "_spec": "balanced-match@^0.3.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/brace-expansion", + "author": { + "email": "mail@juliangruber.com", + "name": "Julian Gruber", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/balanced-match/issues" + }, + "dependencies": {}, + "description": "Match balanced character pairs, like \"{\" and \"}\"", + "devDependencies": { + "tape": "~4.2.2" + }, + "directories": {}, + "dist": { + "shasum": "a91cdd1ebef1a86659e70ff4def01625fc2d6756", + "tarball": "http://registry.npmjs.org/balanced-match/-/balanced-match-0.3.0.tgz" + }, + "gitHead": "a7114b0986554787e90b7ac595a043ca75ea77e5", + "homepage": "https://github.com/juliangruber/balanced-match", + "keywords": [ + "match", + "regexp", + "test", + "balanced", + "parse" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "email": "julian@juliangruber.com", + "name": "juliangruber" + } + ], + "name": "balanced-match", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/balanced-match.git" + }, + "scripts": { + "test": "make test" + }, + "testling": { + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ], + "files": "test/*.js" + }, + "version": "0.3.0" +} diff --git a/www/node_modules/balanced-match/test/balanced.js b/www/node_modules/balanced-match/test/balanced.js new file mode 100644 index 0000000..f5e98e3 --- /dev/null +++ b/www/node_modules/balanced-match/test/balanced.js @@ -0,0 +1,84 @@ +var test = require('tape'); +var balanced = require('..'); + +test('balanced', function(t) { + t.deepEqual(balanced('{', '}', 'pre{in{nest}}post'), { + start: 3, + end: 12, + pre: 'pre', + body: 'in{nest}', + post: 'post' + }); + t.deepEqual(balanced('{', '}', '{{{{{{{{{in}post'), { + start: 8, + end: 11, + pre: '{{{{{{{{', + body: 'in', + post: 'post' + }); + t.deepEqual(balanced('{', '}', 'pre{body{in}post'), { + start: 8, + end: 11, + pre: 'pre{body', + body: 'in', + post: 'post' + }); + t.deepEqual(balanced('{', '}', 'pre}{in{nest}}post'), { + start: 4, + end: 13, + pre: 'pre}', + body: 'in{nest}', + post: 'post' + }); + t.deepEqual(balanced('{', '}', 'pre{body}between{body2}post'), { + start: 3, + end: 8, + pre: 'pre', + body: 'body', + post: 'between{body2}post' + }); + t.notOk(balanced('{', '}', 'nope'), 'should be notOk'); + t.deepEqual(balanced('', '', 'preinnestpost'), { + start: 3, + end: 19, + pre: 'pre', + body: 'innest', + post: 'post' + }); + t.deepEqual(balanced('', '', 'preinnestpost'), { + start: 7, + end: 23, + pre: 'pre
    ', + body: 'innest', + post: 'post' + }); + t.deepEqual(balanced('{{', '}}', 'pre{{{in}}}post'), { + start: 3, + end: 9, + pre: 'pre', + body: '{in}', + post: 'post' + }); + t.deepEqual(balanced('{{{', '}}', 'pre{{{in}}}post'), { + start: 3, + end: 8, + pre: 'pre', + body: 'in', + post: '}post' + }); + t.deepEqual(balanced('{', '}', 'pre{{first}in{second}post'), { + start: 4, + end: 10, + pre: 'pre{', + body: 'first', + post: 'in{second}post' + }); + t.deepEqual(balanced('', 'prepost'), { + start: 3, + end: 4, + pre: 'pre', + body: '', + post: 'post' + }); + t.end(); +}); diff --git a/www/node_modules/brace-expansion/.npmignore b/www/node_modules/brace-expansion/.npmignore new file mode 100644 index 0000000..353546a --- /dev/null +++ b/www/node_modules/brace-expansion/.npmignore @@ -0,0 +1,3 @@ +test +.gitignore +.travis.yml diff --git a/www/node_modules/brace-expansion/README.md b/www/node_modules/brace-expansion/README.md new file mode 100644 index 0000000..1793929 --- /dev/null +++ b/www/node_modules/brace-expansion/README.md @@ -0,0 +1,122 @@ +# brace-expansion + +[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), +as known from sh/bash, in JavaScript. + +[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) +[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) + +[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) + +## Example + +```js +var expand = require('brace-expansion'); + +expand('file-{a,b,c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('-v{,,}') +// => ['-v', '-v', '-v'] + +expand('file{0..2}.jpg') +// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] + +expand('file-{a..c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('file{2..0}.jpg') +// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] + +expand('file{0..4..2}.jpg') +// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] + +expand('file-{a..e..2}.jpg') +// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] + +expand('file{00..10..5}.jpg') +// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] + +expand('{{A..C},{a..c}}') +// => ['A', 'B', 'C', 'a', 'b', 'c'] + +expand('ppp{,config,oe{,conf}}') +// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] +``` + +## API + +```js +var expand = require('brace-expansion'); +``` + +### var expanded = expand(str) + +Return an array of all possible and valid expansions of `str`. If none are +found, `[str]` is returned. + +Valid expansions are: + +```js +/^(.*,)+(.+)?$/ +// {a,b,...} +``` + +A comma seperated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +A numeric sequence from `x` to `y` inclusive, with optional increment. +If `x` or `y` start with a leading `0`, all the numbers will be padded +to have equal length. Negative numbers and backwards iteration work too. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +An alphabetic sequence from `x` to `y` inclusive, with optional increment. +`x` and `y` must be exactly one character, and if given, `incr` must be a +number. + +For compatibility reasons, the string `${` is not eligible for brace expansion. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install brace-expansion +``` + +## Contributors + +- [Julian Gruber](https://github.com/juliangruber) +- [Isaac Z. Schlueter](https://github.com/isaacs) + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/www/node_modules/brace-expansion/example.js b/www/node_modules/brace-expansion/example.js new file mode 100644 index 0000000..60ecfc7 --- /dev/null +++ b/www/node_modules/brace-expansion/example.js @@ -0,0 +1,8 @@ +var expand = require('./'); + +console.log(expand('http://any.org/archive{1996..1999}/vol{1..4}/part{a,b,c}.html')); +console.log(expand('http://www.numericals.com/file{1..100..10}.txt')); +console.log(expand('http://www.letters.com/file{a..z..2}.txt')); +console.log(expand('mkdir /usr/local/src/bash/{old,new,dist,bugs}')); +console.log(expand('chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}')); + diff --git a/www/node_modules/brace-expansion/index.js b/www/node_modules/brace-expansion/index.js new file mode 100644 index 0000000..932718f --- /dev/null +++ b/www/node_modules/brace-expansion/index.js @@ -0,0 +1,191 @@ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = /^(.*,)+(.+)?$/.test(m.body); + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + diff --git a/www/node_modules/brace-expansion/package.json b/www/node_modules/brace-expansion/package.json new file mode 100644 index 0000000..034c59e --- /dev/null +++ b/www/node_modules/brace-expansion/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + "brace-expansion@^1.0.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/minimatch" + ] + ], + "_from": "brace-expansion@>=1.0.0 <2.0.0", + "_id": "brace-expansion@1.1.3", + "_inCache": true, + "_installable": true, + "_location": "/brace-expansion", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-6-west.internal.npmjs.com", + "tmp": "tmp/brace-expansion-1.1.3.tgz_1455216688668_0.948847763473168" + }, + "_npmUser": { + "email": "julian@juliangruber.com", + "name": "juliangruber" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "name": "brace-expansion", + "raw": "brace-expansion@^1.0.0", + "rawSpec": "^1.0.0", + "scope": null, + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/minimatch" + ], + "_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.3.tgz", + "_shasum": "46bff50115d47fc9ab89854abb87d98078a10991", + "_shrinkwrap": null, + "_spec": "brace-expansion@^1.0.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/minimatch", + "author": { + "email": "mail@juliangruber.com", + "name": "Julian Gruber", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/brace-expansion/issues" + }, + "dependencies": { + "balanced-match": "^0.3.0", + "concat-map": "0.0.1" + }, + "description": "Brace expansion as known from sh/bash", + "devDependencies": { + "tape": "4.4.0" + }, + "directories": {}, + "dist": { + "shasum": "46bff50115d47fc9ab89854abb87d98078a10991", + "tarball": "http://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.3.tgz" + }, + "gitHead": "f0da1bb668e655f67b6b2d660c6e1c19e2a6f231", + "homepage": "https://github.com/juliangruber/brace-expansion", + "keywords": [], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "email": "julian@juliangruber.com", + "name": "juliangruber" + }, + { + "email": "isaacs@npmjs.com", + "name": "isaacs" + } + ], + "name": "brace-expansion", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + }, + "scripts": { + "gentest": "bash test/generate.sh", + "test": "tape test/*.js" + }, + "testling": { + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ], + "files": "test/*.js" + }, + "version": "1.1.3" +} diff --git a/www/node_modules/concat-map/.travis.yml b/www/node_modules/concat-map/.travis.yml new file mode 100644 index 0000000..f1d0f13 --- /dev/null +++ b/www/node_modules/concat-map/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.4 + - 0.6 diff --git a/www/node_modules/concat-map/LICENSE b/www/node_modules/concat-map/LICENSE new file mode 100644 index 0000000..ee27ba4 --- /dev/null +++ b/www/node_modules/concat-map/LICENSE @@ -0,0 +1,18 @@ +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/www/node_modules/concat-map/README.markdown b/www/node_modules/concat-map/README.markdown new file mode 100644 index 0000000..408f70a --- /dev/null +++ b/www/node_modules/concat-map/README.markdown @@ -0,0 +1,62 @@ +concat-map +========== + +Concatenative mapdashery. + +[![browser support](http://ci.testling.com/substack/node-concat-map.png)](http://ci.testling.com/substack/node-concat-map) + +[![build status](https://secure.travis-ci.org/substack/node-concat-map.png)](http://travis-ci.org/substack/node-concat-map) + +example +======= + +``` js +var concatMap = require('concat-map'); +var xs = [ 1, 2, 3, 4, 5, 6 ]; +var ys = concatMap(xs, function (x) { + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; +}); +console.dir(ys); +``` + +*** + +``` +[ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ] +``` + +methods +======= + +``` js +var concatMap = require('concat-map') +``` + +concatMap(xs, fn) +----------------- + +Return an array of concatenated elements by calling `fn(x, i)` for each element +`x` and each index `i` in the array `xs`. + +When `fn(x, i)` returns an array, its result will be concatenated with the +result array. If `fn(x, i)` returns anything else, that value will be pushed +onto the end of the result array. + +install +======= + +With [npm](http://npmjs.org) do: + +``` +npm install concat-map +``` + +license +======= + +MIT + +notes +===== + +This module was written while sitting high above the ground in a tree. diff --git a/www/node_modules/concat-map/example/map.js b/www/node_modules/concat-map/example/map.js new file mode 100644 index 0000000..3365621 --- /dev/null +++ b/www/node_modules/concat-map/example/map.js @@ -0,0 +1,6 @@ +var concatMap = require('../'); +var xs = [ 1, 2, 3, 4, 5, 6 ]; +var ys = concatMap(xs, function (x) { + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; +}); +console.dir(ys); diff --git a/www/node_modules/concat-map/index.js b/www/node_modules/concat-map/index.js new file mode 100644 index 0000000..b29a781 --- /dev/null +++ b/www/node_modules/concat-map/index.js @@ -0,0 +1,13 @@ +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; diff --git a/www/node_modules/concat-map/package.json b/www/node_modules/concat-map/package.json new file mode 100644 index 0000000..a9ec9a4 --- /dev/null +++ b/www/node_modules/concat-map/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + "concat-map@0.0.1", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/brace-expansion" + ] + ], + "_from": "concat-map@0.0.1", + "_id": "concat-map@0.0.1", + "_inCache": true, + "_installable": true, + "_location": "/concat-map", + "_npmUser": { + "email": "mail@substack.net", + "name": "substack" + }, + "_npmVersion": "1.3.21", + "_phantomChildren": {}, + "_requested": { + "name": "concat-map", + "raw": "concat-map@0.0.1", + "rawSpec": "0.0.1", + "scope": null, + "spec": "0.0.1", + "type": "version" + }, + "_requiredBy": [ + "/brace-expansion" + ], + "_resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "_shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b", + "_shrinkwrap": null, + "_spec": "concat-map@0.0.1", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/brace-expansion", + "author": { + "email": "mail@substack.net", + "name": "James Halliday", + "url": "http://substack.net" + }, + "bugs": { + "url": "https://github.com/substack/node-concat-map/issues" + }, + "dependencies": {}, + "description": "concatenative mapdashery", + "devDependencies": { + "tape": "~2.4.0" + }, + "directories": { + "example": "example", + "test": "test" + }, + "dist": { + "shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b", + "tarball": "http://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + }, + "homepage": "https://github.com/substack/node-concat-map", + "keywords": [ + "concat", + "concatMap", + "map", + "functional", + "higher-order" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "email": "mail@substack.net", + "name": "substack" + } + ], + "name": "concat-map", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/substack/node-concat-map.git" + }, + "scripts": { + "test": "tape test/*.js" + }, + "testling": { + "browsers": { + "chrome": [ + 10, + 22 + ], + "ff": [ + 3.5, + 10, + 15 + ], + "ie": [ + 6, + 7, + 8, + 9 + ], + "opera": [ + 12 + ], + "safari": [ + 5.1 + ] + }, + "files": "test/*.js" + }, + "version": "0.0.1" +} diff --git a/www/node_modules/concat-map/test/map.js b/www/node_modules/concat-map/test/map.js new file mode 100644 index 0000000..fdbd702 --- /dev/null +++ b/www/node_modules/concat-map/test/map.js @@ -0,0 +1,39 @@ +var concatMap = require('../'); +var test = require('tape'); + +test('empty or not', function (t) { + var xs = [ 1, 2, 3, 4, 5, 6 ]; + var ixes = []; + var ys = concatMap(xs, function (x, ix) { + ixes.push(ix); + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; + }); + t.same(ys, [ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]); + t.same(ixes, [ 0, 1, 2, 3, 4, 5 ]); + t.end(); +}); + +test('always something', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function (x) { + return x === 'b' ? [ 'B', 'B', 'B' ] : [ x ]; + }); + t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); + t.end(); +}); + +test('scalars', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function (x) { + return x === 'b' ? [ 'B', 'B', 'B' ] : x; + }); + t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); + t.end(); +}); + +test('undefs', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function () {}); + t.same(ys, [ undefined, undefined, undefined, undefined ]); + t.end(); +}); diff --git a/www/node_modules/exit/.jshintrc b/www/node_modules/exit/.jshintrc new file mode 100644 index 0000000..2b7e39b --- /dev/null +++ b/www/node_modules/exit/.jshintrc @@ -0,0 +1,14 @@ +{ + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": "nofunc", + "newcap": true, + "noarg": true, + "sub": true, + "undef": true, + "unused": true, + "boss": true, + "eqnull": true, + "node": true +} diff --git a/www/node_modules/exit/.npmignore b/www/node_modules/exit/.npmignore new file mode 100644 index 0000000..e69de29 diff --git a/www/node_modules/exit/.travis.yml b/www/node_modules/exit/.travis.yml new file mode 100644 index 0000000..42d4302 --- /dev/null +++ b/www/node_modules/exit/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - 0.8 + - '0.10' +before_script: + - npm install -g grunt-cli diff --git a/www/node_modules/exit/Gruntfile.js b/www/node_modules/exit/Gruntfile.js new file mode 100644 index 0000000..ff37751 --- /dev/null +++ b/www/node_modules/exit/Gruntfile.js @@ -0,0 +1,48 @@ +'use strict'; + +module.exports = function(grunt) { + + // Project configuration. + grunt.initConfig({ + nodeunit: { + files: ['test/**/*_test.js'], + }, + jshint: { + options: { + jshintrc: '.jshintrc' + }, + gruntfile: { + src: 'Gruntfile.js' + }, + lib: { + src: ['lib/**/*.js'] + }, + test: { + src: ['test/**/*.js'] + }, + }, + watch: { + gruntfile: { + files: '<%= jshint.gruntfile.src %>', + tasks: ['jshint:gruntfile'] + }, + lib: { + files: '<%= jshint.lib.src %>', + tasks: ['jshint:lib', 'nodeunit'] + }, + test: { + files: '<%= jshint.test.src %>', + tasks: ['jshint:test', 'nodeunit'] + }, + }, + }); + + // These plugins provide necessary tasks. + grunt.loadNpmTasks('grunt-contrib-nodeunit'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-watch'); + + // Default task. + grunt.registerTask('default', ['jshint', 'nodeunit']); + +}; diff --git a/www/node_modules/exit/LICENSE-MIT b/www/node_modules/exit/LICENSE-MIT new file mode 100644 index 0000000..bb2aad6 --- /dev/null +++ b/www/node_modules/exit/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2013 "Cowboy" Ben Alman + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/www/node_modules/exit/README.md b/www/node_modules/exit/README.md new file mode 100644 index 0000000..20c364e --- /dev/null +++ b/www/node_modules/exit/README.md @@ -0,0 +1,75 @@ +# exit [![Build Status](https://secure.travis-ci.org/cowboy/node-exit.png?branch=master)](http://travis-ci.org/cowboy/node-exit) + +A replacement for process.exit that ensures stdio are fully drained before exiting. + +To make a long story short, if `process.exit` is called on Windows, script output is often truncated when pipe-redirecting `stdout` or `stderr`. This module attempts to work around this issue by waiting until those streams have been completely drained before actually calling `process.exit`. + +See [Node.js issue #3584](https://github.com/joyent/node/issues/3584) for further reference. + +Tested in OS X 10.8, Windows 7 on Node.js 0.8.25 and 0.10.18. + +Based on some code by [@vladikoff](https://github.com/vladikoff). + +## Getting Started +Install the module with: `npm install exit` + +```javascript +var exit = require('exit'); + +// These lines should appear in the output, EVEN ON WINDOWS. +console.log("omg"); +console.error("yay"); + +// process.exit(5); +exit(5); + +// These lines shouldn't appear in the output. +console.log("wtf"); +console.error("bro"); +``` + +## Don't believe me? Try it for yourself. + +In Windows, clone the repo and cd to the `test\fixtures` directory. The only difference between [log.js](test/fixtures/log.js) and [log-broken.js](test/fixtures/log-broken.js) is that the former uses `exit` while the latter calls `process.exit` directly. + +This test was done using cmd.exe, but you can see the same results using `| grep "std"` in either PowerShell or git-bash. + +``` +C:\node-exit\test\fixtures>node log.js 0 10 stdout stderr 2>&1 | find "std" +stdout 0 +stderr 0 +stdout 1 +stderr 1 +stdout 2 +stderr 2 +stdout 3 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 + +C:\node-exit\test\fixtures>node log-broken.js 0 10 stdout stderr 2>&1 | find "std" + +C:\node-exit\test\fixtures> +``` + +## Contributing +In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/). + +## Release History +2013-11-26 - v0.1.2 - Fixed a bug with hanging processes. +2013-09-26 - v0.1.1 - Fixed some bugs. It seems to actually work now! +2013-09-20 - v0.1.0 - Initial release. + +## License +Copyright (c) 2013 "Cowboy" Ben Alman +Licensed under the MIT license. diff --git a/www/node_modules/exit/lib/exit.js b/www/node_modules/exit/lib/exit.js new file mode 100644 index 0000000..2883e05 --- /dev/null +++ b/www/node_modules/exit/lib/exit.js @@ -0,0 +1,41 @@ +/* + * exit + * https://github.com/cowboy/node-exit + * + * Copyright (c) 2013 "Cowboy" Ben Alman + * Licensed under the MIT license. + */ + +'use strict'; + +module.exports = function exit(exitCode, streams) { + if (!streams) { streams = [process.stdout, process.stderr]; } + var drainCount = 0; + // Actually exit if all streams are drained. + function tryToExit() { + if (drainCount === streams.length) { + process.exit(exitCode); + } + } + streams.forEach(function(stream) { + // Count drained streams now, but monitor non-drained streams. + if (stream.bufferSize === 0) { + drainCount++; + } else { + stream.write('', 'utf-8', function() { + drainCount++; + tryToExit(); + }); + } + // Prevent further writing. + stream.write = function() {}; + }); + // If all streams were already drained, exit now. + tryToExit(); + // In Windows, when run as a Node.js child process, a script utilizing + // this library might just exit with a 0 exit code, regardless. This code, + // despite the fact that it looks a bit crazy, appears to fix that. + process.on('exit', function() { + process.exit(exitCode); + }); +}; diff --git a/www/node_modules/exit/package.json b/www/node_modules/exit/package.json new file mode 100644 index 0000000..ea2795d --- /dev/null +++ b/www/node_modules/exit/package.json @@ -0,0 +1,95 @@ +{ + "_args": [ + [ + "exit@^0.1.2", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine" + ] + ], + "_from": "exit@>=0.1.2 <0.2.0", + "_id": "exit@0.1.2", + "_inCache": true, + "_installable": true, + "_location": "/exit", + "_npmUser": { + "email": "cowboy@rj3.net", + "name": "cowboy" + }, + "_npmVersion": "1.3.11", + "_phantomChildren": {}, + "_requested": { + "name": "exit", + "raw": "exit@^0.1.2", + "rawSpec": "^0.1.2", + "scope": null, + "spec": ">=0.1.2 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine" + ], + "_resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "_shasum": "0632638f8d877cc82107d30a0fff1a17cba1cd0c", + "_shrinkwrap": null, + "_spec": "exit@^0.1.2", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine", + "author": { + "name": "\"Cowboy\" Ben Alman", + "url": "http://benalman.com/" + }, + "bugs": { + "url": "https://github.com/cowboy/node-exit/issues" + }, + "dependencies": {}, + "description": "A replacement for process.exit that ensures stdio are fully drained before exiting.", + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-jshint": "~0.6.4", + "grunt-contrib-nodeunit": "~0.2.0", + "grunt-contrib-watch": "~0.5.3", + "which": "~1.0.5" + }, + "directories": {}, + "dist": { + "shasum": "0632638f8d877cc82107d30a0fff1a17cba1cd0c", + "tarball": "http://registry.npmjs.org/exit/-/exit-0.1.2.tgz" + }, + "engines": { + "node": ">= 0.8.0" + }, + "homepage": "https://github.com/cowboy/node-exit", + "keywords": [ + "exit", + "process", + "stdio", + "stdout", + "stderr", + "drain", + "flush", + "3584" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/cowboy/node-exit/blob/master/LICENSE-MIT" + } + ], + "main": "lib/exit", + "maintainers": [ + { + "email": "cowboy@rj3.net", + "name": "cowboy" + } + ], + "name": "exit", + "optionalDependencies": {}, + "readme": "# exit [![Build Status](https://secure.travis-ci.org/cowboy/node-exit.png?branch=master)](http://travis-ci.org/cowboy/node-exit)\n\nA replacement for process.exit that ensures stdio are fully drained before exiting.\n\nTo make a long story short, if `process.exit` is called on Windows, script output is often truncated when pipe-redirecting `stdout` or `stderr`. This module attempts to work around this issue by waiting until those streams have been completely drained before actually calling `process.exit`.\n\nSee [Node.js issue #3584](https://github.com/joyent/node/issues/3584) for further reference.\n\nTested in OS X 10.8, Windows 7 on Node.js 0.8.25 and 0.10.18.\n\nBased on some code by [@vladikoff](https://github.com/vladikoff).\n\n## Getting Started\nInstall the module with: `npm install exit`\n\n```javascript\nvar exit = require('exit');\n\n// These lines should appear in the output, EVEN ON WINDOWS.\nconsole.log(\"omg\");\nconsole.error(\"yay\");\n\n// process.exit(5);\nexit(5);\n\n// These lines shouldn't appear in the output.\nconsole.log(\"wtf\");\nconsole.error(\"bro\");\n```\n\n## Don't believe me? Try it for yourself.\n\nIn Windows, clone the repo and cd to the `test\\fixtures` directory. The only difference between [log.js](test/fixtures/log.js) and [log-broken.js](test/fixtures/log-broken.js) is that the former uses `exit` while the latter calls `process.exit` directly.\n\nThis test was done using cmd.exe, but you can see the same results using `| grep \"std\"` in either PowerShell or git-bash.\n\n```\nC:\\node-exit\\test\\fixtures>node log.js 0 10 stdout stderr 2>&1 | find \"std\"\nstdout 0\nstderr 0\nstdout 1\nstderr 1\nstdout 2\nstderr 2\nstdout 3\nstderr 3\nstdout 4\nstderr 4\nstdout 5\nstderr 5\nstdout 6\nstderr 6\nstdout 7\nstderr 7\nstdout 8\nstderr 8\nstdout 9\nstderr 9\n\nC:\\node-exit\\test\\fixtures>node log-broken.js 0 10 stdout stderr 2>&1 | find \"std\"\n\nC:\\node-exit\\test\\fixtures>\n```\n\n## Contributing\nIn lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).\n\n## Release History\n2013-11-26 - v0.1.2 - Fixed a bug with hanging processes. \n2013-09-26 - v0.1.1 - Fixed some bugs. It seems to actually work now! \n2013-09-20 - v0.1.0 - Initial release.\n\n## License\nCopyright (c) 2013 \"Cowboy\" Ben Alman \nLicensed under the MIT license.\n", + "readmeFilename": "README.md", + "repository": { + "type": "git", + "url": "git://github.com/cowboy/node-exit.git" + }, + "scripts": { + "test": "grunt nodeunit" + }, + "version": "0.1.2" +} diff --git a/www/node_modules/exit/test/exit_test.js b/www/node_modules/exit/test/exit_test.js new file mode 100644 index 0000000..a91afb9 --- /dev/null +++ b/www/node_modules/exit/test/exit_test.js @@ -0,0 +1,121 @@ +'use strict'; + +/* + ======== A Handy Little Nodeunit Reference ======== + https://github.com/caolan/nodeunit + + Test methods: + test.expect(numAssertions) + test.done() + Test assertions: + test.ok(value, [message]) + test.equal(actual, expected, [message]) + test.notEqual(actual, expected, [message]) + test.deepEqual(actual, expected, [message]) + test.notDeepEqual(actual, expected, [message]) + test.strictEqual(actual, expected, [message]) + test.notStrictEqual(actual, expected, [message]) + test.throws(block, [error], [message]) + test.doesNotThrow(block, [error], [message]) + test.ifError(value) +*/ + +var fs = require('fs'); +var exec = require('child_process').exec; + +var _which = require('which').sync; +function which(command) { + try { + _which(command); + return command; + } catch (err) { + return false; + } +} + +// Look for grep first (any OS). If not found (but on Windows) look for find, +// which is Windows' horribly crippled grep alternative. +var grep = which('grep') || process.platform === 'win32' && which('find'); + +exports['exit'] = { + setUp: function(done) { + this.origCwd = process.cwd(); + process.chdir('test/fixtures'); + done(); + }, + tearDown: function(done) { + process.chdir(this.origCwd); + done(); + }, + 'grep': function(test) { + test.expect(1); + // Many unit tests depend on this. + test.ok(grep, 'A suitable "grep" or "find" program was not found in the PATH.'); + test.done(); + }, + // The rest of the tests are built dynamically, to keep things sane. +}; + +// A few helper functions. +function normalizeLineEndings(s) { + return s.replace(/\r?\n/g, '\n'); +} + +// Capture command output, normalizing captured stdout to unix file endings. +function run(command, callback) { + exec(command, function(error, stdout) { + callback(error ? error.code : 0, normalizeLineEndings(stdout)); + }); +} + +// Read a fixture file, normalizing file contents to unix file endings. +function fixture(filename) { + return normalizeLineEndings(String(fs.readFileSync(filename))); +} + +function buildTests() { + // Build individual unit tests for command output. + var counts = [10, 100, 1000]; + var outputs = [' stdout stderr', ' stdout', ' stderr']; + var pipes = ['', ' | ' + grep + ' "std"']; + counts.forEach(function(count) { + outputs.forEach(function(output) { + pipes.forEach(function(pipe) { + var command = 'node log.js 0 ' + count + output + ' 2>&1' + pipe; + exports['exit']['output (' + command + ')'] = function(test) { + test.expect(2); + run(command, function(code, actual) { + var expected = fixture(count + output.replace(/ /g, '-') + '.txt'); + // Sometimes, the actual file lines are out of order on Windows. + // But since the point of this lib is to drain the buffer and not + // guarantee output order, we only test the length. + test.equal(actual.length, expected.length, 'should be the same length.'); + // The "fail" lines in log.js should NOT be output! + test.ok(actual.indexOf('fail') === -1, 'should not output after exit is called.'); + test.done(); + }); + }; + }); + }); + }); + + // Build individual unit tests for exit codes. + var codes = [0, 1, 123]; + codes.forEach(function(code) { + var command = 'node log.js ' + code + ' 10 stdout stderr'; + exports['exit']['exit code (' + command + ')'] = function(test) { + test.expect(1); + run(command, function(actual) { + // The specified exit code should be passed through. + test.equal(actual, code, 'should exit with ' + code + ' error code.'); + test.done(); + }); + }; + }); +} + +// Don't bother building tests if grep wasn't found, otherwise everything will +// fail and the error will get lost. +if (grep) { + buildTests(); +} diff --git a/www/node_modules/exit/test/fixtures/10-stderr.txt b/www/node_modules/exit/test/fixtures/10-stderr.txt new file mode 100644 index 0000000..2859200 --- /dev/null +++ b/www/node_modules/exit/test/fixtures/10-stderr.txt @@ -0,0 +1,10 @@ +stderr 0 +stderr 1 +stderr 2 +stderr 3 +stderr 4 +stderr 5 +stderr 6 +stderr 7 +stderr 8 +stderr 9 diff --git a/www/node_modules/exit/test/fixtures/10-stdout-stderr.txt b/www/node_modules/exit/test/fixtures/10-stdout-stderr.txt new file mode 100644 index 0000000..9de8616 --- /dev/null +++ b/www/node_modules/exit/test/fixtures/10-stdout-stderr.txt @@ -0,0 +1,20 @@ +stdout 0 +stderr 0 +stdout 1 +stdout 2 +stderr 1 +stdout 3 +stderr 2 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 diff --git a/www/node_modules/exit/test/fixtures/10-stdout.txt b/www/node_modules/exit/test/fixtures/10-stdout.txt new file mode 100644 index 0000000..1ce90dc --- /dev/null +++ b/www/node_modules/exit/test/fixtures/10-stdout.txt @@ -0,0 +1,10 @@ +stdout 0 +stdout 1 +stdout 2 +stdout 3 +stdout 4 +stdout 5 +stdout 6 +stdout 7 +stdout 8 +stdout 9 diff --git a/www/node_modules/exit/test/fixtures/100-stderr.txt b/www/node_modules/exit/test/fixtures/100-stderr.txt new file mode 100644 index 0000000..3a78c85 --- /dev/null +++ b/www/node_modules/exit/test/fixtures/100-stderr.txt @@ -0,0 +1,100 @@ +stderr 0 +stderr 1 +stderr 2 +stderr 3 +stderr 4 +stderr 5 +stderr 6 +stderr 7 +stderr 8 +stderr 9 +stderr 10 +stderr 11 +stderr 12 +stderr 13 +stderr 14 +stderr 15 +stderr 16 +stderr 17 +stderr 18 +stderr 19 +stderr 20 +stderr 21 +stderr 22 +stderr 23 +stderr 24 +stderr 25 +stderr 26 +stderr 27 +stderr 28 +stderr 29 +stderr 30 +stderr 31 +stderr 32 +stderr 33 +stderr 34 +stderr 35 +stderr 36 +stderr 37 +stderr 38 +stderr 39 +stderr 40 +stderr 41 +stderr 42 +stderr 43 +stderr 44 +stderr 45 +stderr 46 +stderr 47 +stderr 48 +stderr 49 +stderr 50 +stderr 51 +stderr 52 +stderr 53 +stderr 54 +stderr 55 +stderr 56 +stderr 57 +stderr 58 +stderr 59 +stderr 60 +stderr 61 +stderr 62 +stderr 63 +stderr 64 +stderr 65 +stderr 66 +stderr 67 +stderr 68 +stderr 69 +stderr 70 +stderr 71 +stderr 72 +stderr 73 +stderr 74 +stderr 75 +stderr 76 +stderr 77 +stderr 78 +stderr 79 +stderr 80 +stderr 81 +stderr 82 +stderr 83 +stderr 84 +stderr 85 +stderr 86 +stderr 87 +stderr 88 +stderr 89 +stderr 90 +stderr 91 +stderr 92 +stderr 93 +stderr 94 +stderr 95 +stderr 96 +stderr 97 +stderr 98 +stderr 99 diff --git a/www/node_modules/exit/test/fixtures/100-stdout-stderr.txt b/www/node_modules/exit/test/fixtures/100-stdout-stderr.txt new file mode 100644 index 0000000..65f35f4 --- /dev/null +++ b/www/node_modules/exit/test/fixtures/100-stdout-stderr.txt @@ -0,0 +1,200 @@ +stdout 0 +stderr 0 +stdout 1 +stderr 1 +stdout 2 +stderr 2 +stdout 3 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 +stdout 10 +stderr 10 +stdout 11 +stderr 11 +stdout 12 +stderr 12 +stdout 13 +stderr 13 +stdout 14 +stderr 14 +stdout 15 +stderr 15 +stdout 16 +stderr 16 +stdout 17 +stderr 17 +stdout 18 +stderr 18 +stdout 19 +stderr 19 +stdout 20 +stderr 20 +stdout 21 +stderr 21 +stdout 22 +stderr 22 +stdout 23 +stderr 23 +stdout 24 +stderr 24 +stdout 25 +stderr 25 +stdout 26 +stderr 26 +stdout 27 +stderr 27 +stdout 28 +stderr 28 +stdout 29 +stderr 29 +stdout 30 +stderr 30 +stdout 31 +stderr 31 +stdout 32 +stderr 32 +stdout 33 +stderr 33 +stdout 34 +stderr 34 +stdout 35 +stderr 35 +stdout 36 +stderr 36 +stdout 37 +stderr 37 +stdout 38 +stderr 38 +stdout 39 +stderr 39 +stdout 40 +stderr 40 +stdout 41 +stderr 41 +stdout 42 +stderr 42 +stdout 43 +stderr 43 +stdout 44 +stderr 44 +stdout 45 +stderr 45 +stdout 46 +stderr 46 +stdout 47 +stderr 47 +stdout 48 +stderr 48 +stdout 49 +stderr 49 +stdout 50 +stderr 50 +stdout 51 +stderr 51 +stdout 52 +stderr 52 +stdout 53 +stderr 53 +stdout 54 +stderr 54 +stdout 55 +stderr 55 +stdout 56 +stderr 56 +stdout 57 +stderr 57 +stdout 58 +stderr 58 +stdout 59 +stderr 59 +stdout 60 +stderr 60 +stdout 61 +stderr 61 +stdout 62 +stderr 62 +stdout 63 +stderr 63 +stdout 64 +stderr 64 +stdout 65 +stderr 65 +stdout 66 +stderr 66 +stdout 67 +stderr 67 +stdout 68 +stderr 68 +stdout 69 +stderr 69 +stdout 70 +stderr 70 +stdout 71 +stderr 71 +stdout 72 +stderr 72 +stdout 73 +stderr 73 +stdout 74 +stderr 74 +stdout 75 +stderr 75 +stdout 76 +stderr 76 +stdout 77 +stderr 77 +stdout 78 +stderr 78 +stdout 79 +stderr 79 +stdout 80 +stderr 80 +stdout 81 +stderr 81 +stdout 82 +stderr 82 +stdout 83 +stderr 83 +stdout 84 +stderr 84 +stdout 85 +stderr 85 +stdout 86 +stderr 86 +stdout 87 +stderr 87 +stdout 88 +stderr 88 +stdout 89 +stderr 89 +stdout 90 +stderr 90 +stdout 91 +stderr 91 +stdout 92 +stderr 92 +stdout 93 +stderr 93 +stdout 94 +stderr 94 +stdout 95 +stderr 95 +stdout 96 +stderr 96 +stdout 97 +stderr 97 +stdout 98 +stderr 98 +stdout 99 +stderr 99 diff --git a/www/node_modules/exit/test/fixtures/100-stdout.txt b/www/node_modules/exit/test/fixtures/100-stdout.txt new file mode 100644 index 0000000..5d9cac2 --- /dev/null +++ b/www/node_modules/exit/test/fixtures/100-stdout.txt @@ -0,0 +1,100 @@ +stdout 0 +stdout 1 +stdout 2 +stdout 3 +stdout 4 +stdout 5 +stdout 6 +stdout 7 +stdout 8 +stdout 9 +stdout 10 +stdout 11 +stdout 12 +stdout 13 +stdout 14 +stdout 15 +stdout 16 +stdout 17 +stdout 18 +stdout 19 +stdout 20 +stdout 21 +stdout 22 +stdout 23 +stdout 24 +stdout 25 +stdout 26 +stdout 27 +stdout 28 +stdout 29 +stdout 30 +stdout 31 +stdout 32 +stdout 33 +stdout 34 +stdout 35 +stdout 36 +stdout 37 +stdout 38 +stdout 39 +stdout 40 +stdout 41 +stdout 42 +stdout 43 +stdout 44 +stdout 45 +stdout 46 +stdout 47 +stdout 48 +stdout 49 +stdout 50 +stdout 51 +stdout 52 +stdout 53 +stdout 54 +stdout 55 +stdout 56 +stdout 57 +stdout 58 +stdout 59 +stdout 60 +stdout 61 +stdout 62 +stdout 63 +stdout 64 +stdout 65 +stdout 66 +stdout 67 +stdout 68 +stdout 69 +stdout 70 +stdout 71 +stdout 72 +stdout 73 +stdout 74 +stdout 75 +stdout 76 +stdout 77 +stdout 78 +stdout 79 +stdout 80 +stdout 81 +stdout 82 +stdout 83 +stdout 84 +stdout 85 +stdout 86 +stdout 87 +stdout 88 +stdout 89 +stdout 90 +stdout 91 +stdout 92 +stdout 93 +stdout 94 +stdout 95 +stdout 96 +stdout 97 +stdout 98 +stdout 99 diff --git a/www/node_modules/exit/test/fixtures/1000-stderr.txt b/www/node_modules/exit/test/fixtures/1000-stderr.txt new file mode 100644 index 0000000..d637510 --- /dev/null +++ b/www/node_modules/exit/test/fixtures/1000-stderr.txt @@ -0,0 +1,1000 @@ +stderr 0 +stderr 1 +stderr 2 +stderr 3 +stderr 4 +stderr 5 +stderr 6 +stderr 7 +stderr 8 +stderr 9 +stderr 10 +stderr 11 +stderr 12 +stderr 13 +stderr 14 +stderr 15 +stderr 16 +stderr 17 +stderr 18 +stderr 19 +stderr 20 +stderr 21 +stderr 22 +stderr 23 +stderr 24 +stderr 25 +stderr 26 +stderr 27 +stderr 28 +stderr 29 +stderr 30 +stderr 31 +stderr 32 +stderr 33 +stderr 34 +stderr 35 +stderr 36 +stderr 37 +stderr 38 +stderr 39 +stderr 40 +stderr 41 +stderr 42 +stderr 43 +stderr 44 +stderr 45 +stderr 46 +stderr 47 +stderr 48 +stderr 49 +stderr 50 +stderr 51 +stderr 52 +stderr 53 +stderr 54 +stderr 55 +stderr 56 +stderr 57 +stderr 58 +stderr 59 +stderr 60 +stderr 61 +stderr 62 +stderr 63 +stderr 64 +stderr 65 +stderr 66 +stderr 67 +stderr 68 +stderr 69 +stderr 70 +stderr 71 +stderr 72 +stderr 73 +stderr 74 +stderr 75 +stderr 76 +stderr 77 +stderr 78 +stderr 79 +stderr 80 +stderr 81 +stderr 82 +stderr 83 +stderr 84 +stderr 85 +stderr 86 +stderr 87 +stderr 88 +stderr 89 +stderr 90 +stderr 91 +stderr 92 +stderr 93 +stderr 94 +stderr 95 +stderr 96 +stderr 97 +stderr 98 +stderr 99 +stderr 100 +stderr 101 +stderr 102 +stderr 103 +stderr 104 +stderr 105 +stderr 106 +stderr 107 +stderr 108 +stderr 109 +stderr 110 +stderr 111 +stderr 112 +stderr 113 +stderr 114 +stderr 115 +stderr 116 +stderr 117 +stderr 118 +stderr 119 +stderr 120 +stderr 121 +stderr 122 +stderr 123 +stderr 124 +stderr 125 +stderr 126 +stderr 127 +stderr 128 +stderr 129 +stderr 130 +stderr 131 +stderr 132 +stderr 133 +stderr 134 +stderr 135 +stderr 136 +stderr 137 +stderr 138 +stderr 139 +stderr 140 +stderr 141 +stderr 142 +stderr 143 +stderr 144 +stderr 145 +stderr 146 +stderr 147 +stderr 148 +stderr 149 +stderr 150 +stderr 151 +stderr 152 +stderr 153 +stderr 154 +stderr 155 +stderr 156 +stderr 157 +stderr 158 +stderr 159 +stderr 160 +stderr 161 +stderr 162 +stderr 163 +stderr 164 +stderr 165 +stderr 166 +stderr 167 +stderr 168 +stderr 169 +stderr 170 +stderr 171 +stderr 172 +stderr 173 +stderr 174 +stderr 175 +stderr 176 +stderr 177 +stderr 178 +stderr 179 +stderr 180 +stderr 181 +stderr 182 +stderr 183 +stderr 184 +stderr 185 +stderr 186 +stderr 187 +stderr 188 +stderr 189 +stderr 190 +stderr 191 +stderr 192 +stderr 193 +stderr 194 +stderr 195 +stderr 196 +stderr 197 +stderr 198 +stderr 199 +stderr 200 +stderr 201 +stderr 202 +stderr 203 +stderr 204 +stderr 205 +stderr 206 +stderr 207 +stderr 208 +stderr 209 +stderr 210 +stderr 211 +stderr 212 +stderr 213 +stderr 214 +stderr 215 +stderr 216 +stderr 217 +stderr 218 +stderr 219 +stderr 220 +stderr 221 +stderr 222 +stderr 223 +stderr 224 +stderr 225 +stderr 226 +stderr 227 +stderr 228 +stderr 229 +stderr 230 +stderr 231 +stderr 232 +stderr 233 +stderr 234 +stderr 235 +stderr 236 +stderr 237 +stderr 238 +stderr 239 +stderr 240 +stderr 241 +stderr 242 +stderr 243 +stderr 244 +stderr 245 +stderr 246 +stderr 247 +stderr 248 +stderr 249 +stderr 250 +stderr 251 +stderr 252 +stderr 253 +stderr 254 +stderr 255 +stderr 256 +stderr 257 +stderr 258 +stderr 259 +stderr 260 +stderr 261 +stderr 262 +stderr 263 +stderr 264 +stderr 265 +stderr 266 +stderr 267 +stderr 268 +stderr 269 +stderr 270 +stderr 271 +stderr 272 +stderr 273 +stderr 274 +stderr 275 +stderr 276 +stderr 277 +stderr 278 +stderr 279 +stderr 280 +stderr 281 +stderr 282 +stderr 283 +stderr 284 +stderr 285 +stderr 286 +stderr 287 +stderr 288 +stderr 289 +stderr 290 +stderr 291 +stderr 292 +stderr 293 +stderr 294 +stderr 295 +stderr 296 +stderr 297 +stderr 298 +stderr 299 +stderr 300 +stderr 301 +stderr 302 +stderr 303 +stderr 304 +stderr 305 +stderr 306 +stderr 307 +stderr 308 +stderr 309 +stderr 310 +stderr 311 +stderr 312 +stderr 313 +stderr 314 +stderr 315 +stderr 316 +stderr 317 +stderr 318 +stderr 319 +stderr 320 +stderr 321 +stderr 322 +stderr 323 +stderr 324 +stderr 325 +stderr 326 +stderr 327 +stderr 328 +stderr 329 +stderr 330 +stderr 331 +stderr 332 +stderr 333 +stderr 334 +stderr 335 +stderr 336 +stderr 337 +stderr 338 +stderr 339 +stderr 340 +stderr 341 +stderr 342 +stderr 343 +stderr 344 +stderr 345 +stderr 346 +stderr 347 +stderr 348 +stderr 349 +stderr 350 +stderr 351 +stderr 352 +stderr 353 +stderr 354 +stderr 355 +stderr 356 +stderr 357 +stderr 358 +stderr 359 +stderr 360 +stderr 361 +stderr 362 +stderr 363 +stderr 364 +stderr 365 +stderr 366 +stderr 367 +stderr 368 +stderr 369 +stderr 370 +stderr 371 +stderr 372 +stderr 373 +stderr 374 +stderr 375 +stderr 376 +stderr 377 +stderr 378 +stderr 379 +stderr 380 +stderr 381 +stderr 382 +stderr 383 +stderr 384 +stderr 385 +stderr 386 +stderr 387 +stderr 388 +stderr 389 +stderr 390 +stderr 391 +stderr 392 +stderr 393 +stderr 394 +stderr 395 +stderr 396 +stderr 397 +stderr 398 +stderr 399 +stderr 400 +stderr 401 +stderr 402 +stderr 403 +stderr 404 +stderr 405 +stderr 406 +stderr 407 +stderr 408 +stderr 409 +stderr 410 +stderr 411 +stderr 412 +stderr 413 +stderr 414 +stderr 415 +stderr 416 +stderr 417 +stderr 418 +stderr 419 +stderr 420 +stderr 421 +stderr 422 +stderr 423 +stderr 424 +stderr 425 +stderr 426 +stderr 427 +stderr 428 +stderr 429 +stderr 430 +stderr 431 +stderr 432 +stderr 433 +stderr 434 +stderr 435 +stderr 436 +stderr 437 +stderr 438 +stderr 439 +stderr 440 +stderr 441 +stderr 442 +stderr 443 +stderr 444 +stderr 445 +stderr 446 +stderr 447 +stderr 448 +stderr 449 +stderr 450 +stderr 451 +stderr 452 +stderr 453 +stderr 454 +stderr 455 +stderr 456 +stderr 457 +stderr 458 +stderr 459 +stderr 460 +stderr 461 +stderr 462 +stderr 463 +stderr 464 +stderr 465 +stderr 466 +stderr 467 +stderr 468 +stderr 469 +stderr 470 +stderr 471 +stderr 472 +stderr 473 +stderr 474 +stderr 475 +stderr 476 +stderr 477 +stderr 478 +stderr 479 +stderr 480 +stderr 481 +stderr 482 +stderr 483 +stderr 484 +stderr 485 +stderr 486 +stderr 487 +stderr 488 +stderr 489 +stderr 490 +stderr 491 +stderr 492 +stderr 493 +stderr 494 +stderr 495 +stderr 496 +stderr 497 +stderr 498 +stderr 499 +stderr 500 +stderr 501 +stderr 502 +stderr 503 +stderr 504 +stderr 505 +stderr 506 +stderr 507 +stderr 508 +stderr 509 +stderr 510 +stderr 511 +stderr 512 +stderr 513 +stderr 514 +stderr 515 +stderr 516 +stderr 517 +stderr 518 +stderr 519 +stderr 520 +stderr 521 +stderr 522 +stderr 523 +stderr 524 +stderr 525 +stderr 526 +stderr 527 +stderr 528 +stderr 529 +stderr 530 +stderr 531 +stderr 532 +stderr 533 +stderr 534 +stderr 535 +stderr 536 +stderr 537 +stderr 538 +stderr 539 +stderr 540 +stderr 541 +stderr 542 +stderr 543 +stderr 544 +stderr 545 +stderr 546 +stderr 547 +stderr 548 +stderr 549 +stderr 550 +stderr 551 +stderr 552 +stderr 553 +stderr 554 +stderr 555 +stderr 556 +stderr 557 +stderr 558 +stderr 559 +stderr 560 +stderr 561 +stderr 562 +stderr 563 +stderr 564 +stderr 565 +stderr 566 +stderr 567 +stderr 568 +stderr 569 +stderr 570 +stderr 571 +stderr 572 +stderr 573 +stderr 574 +stderr 575 +stderr 576 +stderr 577 +stderr 578 +stderr 579 +stderr 580 +stderr 581 +stderr 582 +stderr 583 +stderr 584 +stderr 585 +stderr 586 +stderr 587 +stderr 588 +stderr 589 +stderr 590 +stderr 591 +stderr 592 +stderr 593 +stderr 594 +stderr 595 +stderr 596 +stderr 597 +stderr 598 +stderr 599 +stderr 600 +stderr 601 +stderr 602 +stderr 603 +stderr 604 +stderr 605 +stderr 606 +stderr 607 +stderr 608 +stderr 609 +stderr 610 +stderr 611 +stderr 612 +stderr 613 +stderr 614 +stderr 615 +stderr 616 +stderr 617 +stderr 618 +stderr 619 +stderr 620 +stderr 621 +stderr 622 +stderr 623 +stderr 624 +stderr 625 +stderr 626 +stderr 627 +stderr 628 +stderr 629 +stderr 630 +stderr 631 +stderr 632 +stderr 633 +stderr 634 +stderr 635 +stderr 636 +stderr 637 +stderr 638 +stderr 639 +stderr 640 +stderr 641 +stderr 642 +stderr 643 +stderr 644 +stderr 645 +stderr 646 +stderr 647 +stderr 648 +stderr 649 +stderr 650 +stderr 651 +stderr 652 +stderr 653 +stderr 654 +stderr 655 +stderr 656 +stderr 657 +stderr 658 +stderr 659 +stderr 660 +stderr 661 +stderr 662 +stderr 663 +stderr 664 +stderr 665 +stderr 666 +stderr 667 +stderr 668 +stderr 669 +stderr 670 +stderr 671 +stderr 672 +stderr 673 +stderr 674 +stderr 675 +stderr 676 +stderr 677 +stderr 678 +stderr 679 +stderr 680 +stderr 681 +stderr 682 +stderr 683 +stderr 684 +stderr 685 +stderr 686 +stderr 687 +stderr 688 +stderr 689 +stderr 690 +stderr 691 +stderr 692 +stderr 693 +stderr 694 +stderr 695 +stderr 696 +stderr 697 +stderr 698 +stderr 699 +stderr 700 +stderr 701 +stderr 702 +stderr 703 +stderr 704 +stderr 705 +stderr 706 +stderr 707 +stderr 708 +stderr 709 +stderr 710 +stderr 711 +stderr 712 +stderr 713 +stderr 714 +stderr 715 +stderr 716 +stderr 717 +stderr 718 +stderr 719 +stderr 720 +stderr 721 +stderr 722 +stderr 723 +stderr 724 +stderr 725 +stderr 726 +stderr 727 +stderr 728 +stderr 729 +stderr 730 +stderr 731 +stderr 732 +stderr 733 +stderr 734 +stderr 735 +stderr 736 +stderr 737 +stderr 738 +stderr 739 +stderr 740 +stderr 741 +stderr 742 +stderr 743 +stderr 744 +stderr 745 +stderr 746 +stderr 747 +stderr 748 +stderr 749 +stderr 750 +stderr 751 +stderr 752 +stderr 753 +stderr 754 +stderr 755 +stderr 756 +stderr 757 +stderr 758 +stderr 759 +stderr 760 +stderr 761 +stderr 762 +stderr 763 +stderr 764 +stderr 765 +stderr 766 +stderr 767 +stderr 768 +stderr 769 +stderr 770 +stderr 771 +stderr 772 +stderr 773 +stderr 774 +stderr 775 +stderr 776 +stderr 777 +stderr 778 +stderr 779 +stderr 780 +stderr 781 +stderr 782 +stderr 783 +stderr 784 +stderr 785 +stderr 786 +stderr 787 +stderr 788 +stderr 789 +stderr 790 +stderr 791 +stderr 792 +stderr 793 +stderr 794 +stderr 795 +stderr 796 +stderr 797 +stderr 798 +stderr 799 +stderr 800 +stderr 801 +stderr 802 +stderr 803 +stderr 804 +stderr 805 +stderr 806 +stderr 807 +stderr 808 +stderr 809 +stderr 810 +stderr 811 +stderr 812 +stderr 813 +stderr 814 +stderr 815 +stderr 816 +stderr 817 +stderr 818 +stderr 819 +stderr 820 +stderr 821 +stderr 822 +stderr 823 +stderr 824 +stderr 825 +stderr 826 +stderr 827 +stderr 828 +stderr 829 +stderr 830 +stderr 831 +stderr 832 +stderr 833 +stderr 834 +stderr 835 +stderr 836 +stderr 837 +stderr 838 +stderr 839 +stderr 840 +stderr 841 +stderr 842 +stderr 843 +stderr 844 +stderr 845 +stderr 846 +stderr 847 +stderr 848 +stderr 849 +stderr 850 +stderr 851 +stderr 852 +stderr 853 +stderr 854 +stderr 855 +stderr 856 +stderr 857 +stderr 858 +stderr 859 +stderr 860 +stderr 861 +stderr 862 +stderr 863 +stderr 864 +stderr 865 +stderr 866 +stderr 867 +stderr 868 +stderr 869 +stderr 870 +stderr 871 +stderr 872 +stderr 873 +stderr 874 +stderr 875 +stderr 876 +stderr 877 +stderr 878 +stderr 879 +stderr 880 +stderr 881 +stderr 882 +stderr 883 +stderr 884 +stderr 885 +stderr 886 +stderr 887 +stderr 888 +stderr 889 +stderr 890 +stderr 891 +stderr 892 +stderr 893 +stderr 894 +stderr 895 +stderr 896 +stderr 897 +stderr 898 +stderr 899 +stderr 900 +stderr 901 +stderr 902 +stderr 903 +stderr 904 +stderr 905 +stderr 906 +stderr 907 +stderr 908 +stderr 909 +stderr 910 +stderr 911 +stderr 912 +stderr 913 +stderr 914 +stderr 915 +stderr 916 +stderr 917 +stderr 918 +stderr 919 +stderr 920 +stderr 921 +stderr 922 +stderr 923 +stderr 924 +stderr 925 +stderr 926 +stderr 927 +stderr 928 +stderr 929 +stderr 930 +stderr 931 +stderr 932 +stderr 933 +stderr 934 +stderr 935 +stderr 936 +stderr 937 +stderr 938 +stderr 939 +stderr 940 +stderr 941 +stderr 942 +stderr 943 +stderr 944 +stderr 945 +stderr 946 +stderr 947 +stderr 948 +stderr 949 +stderr 950 +stderr 951 +stderr 952 +stderr 953 +stderr 954 +stderr 955 +stderr 956 +stderr 957 +stderr 958 +stderr 959 +stderr 960 +stderr 961 +stderr 962 +stderr 963 +stderr 964 +stderr 965 +stderr 966 +stderr 967 +stderr 968 +stderr 969 +stderr 970 +stderr 971 +stderr 972 +stderr 973 +stderr 974 +stderr 975 +stderr 976 +stderr 977 +stderr 978 +stderr 979 +stderr 980 +stderr 981 +stderr 982 +stderr 983 +stderr 984 +stderr 985 +stderr 986 +stderr 987 +stderr 988 +stderr 989 +stderr 990 +stderr 991 +stderr 992 +stderr 993 +stderr 994 +stderr 995 +stderr 996 +stderr 997 +stderr 998 +stderr 999 diff --git a/www/node_modules/exit/test/fixtures/1000-stdout-stderr.txt b/www/node_modules/exit/test/fixtures/1000-stdout-stderr.txt new file mode 100644 index 0000000..4fde2b4 --- /dev/null +++ b/www/node_modules/exit/test/fixtures/1000-stdout-stderr.txt @@ -0,0 +1,2000 @@ +stdout 0 +stderr 0 +stdout 1 +stderr 1 +stdout 2 +stderr 2 +stdout 3 +stderr 3 +stdout 4 +stderr 4 +stdout 5 +stderr 5 +stdout 6 +stderr 6 +stdout 7 +stderr 7 +stdout 8 +stderr 8 +stdout 9 +stderr 9 +stdout 10 +stderr 10 +stdout 11 +stderr 11 +stdout 12 +stderr 12 +stdout 13 +stderr 13 +stdout 14 +stderr 14 +stdout 15 +stderr 15 +stdout 16 +stderr 16 +stdout 17 +stderr 17 +stdout 18 +stderr 18 +stdout 19 +stderr 19 +stdout 20 +stderr 20 +stdout 21 +stderr 21 +stdout 22 +stderr 22 +stdout 23 +stderr 23 +stdout 24 +stderr 24 +stdout 25 +stderr 25 +stdout 26 +stderr 26 +stdout 27 +stderr 27 +stdout 28 +stderr 28 +stdout 29 +stderr 29 +stdout 30 +stderr 30 +stdout 31 +stderr 31 +stdout 32 +stderr 32 +stdout 33 +stderr 33 +stdout 34 +stderr 34 +stdout 35 +stderr 35 +stdout 36 +stderr 36 +stdout 37 +stderr 37 +stdout 38 +stderr 38 +stdout 39 +stderr 39 +stdout 40 +stderr 40 +stdout 41 +stderr 41 +stdout 42 +stderr 42 +stdout 43 +stderr 43 +stdout 44 +stderr 44 +stdout 45 +stderr 45 +stdout 46 +stderr 46 +stdout 47 +stderr 47 +stdout 48 +stderr 48 +stdout 49 +stderr 49 +stdout 50 +stderr 50 +stdout 51 +stderr 51 +stdout 52 +stderr 52 +stdout 53 +stderr 53 +stdout 54 +stderr 54 +stdout 55 +stderr 55 +stdout 56 +stderr 56 +stdout 57 +stderr 57 +stdout 58 +stderr 58 +stdout 59 +stderr 59 +stdout 60 +stderr 60 +stdout 61 +stderr 61 +stdout 62 +stderr 62 +stdout 63 +stderr 63 +stdout 64 +stderr 64 +stdout 65 +stderr 65 +stdout 66 +stderr 66 +stdout 67 +stderr 67 +stdout 68 +stderr 68 +stdout 69 +stderr 69 +stdout 70 +stderr 70 +stdout 71 +stderr 71 +stdout 72 +stderr 72 +stdout 73 +stderr 73 +stdout 74 +stderr 74 +stdout 75 +stderr 75 +stdout 76 +stderr 76 +stdout 77 +stderr 77 +stdout 78 +stderr 78 +stdout 79 +stderr 79 +stdout 80 +stderr 80 +stdout 81 +stderr 81 +stdout 82 +stderr 82 +stdout 83 +stderr 83 +stdout 84 +stderr 84 +stdout 85 +stderr 85 +stdout 86 +stderr 86 +stdout 87 +stderr 87 +stdout 88 +stderr 88 +stdout 89 +stderr 89 +stdout 90 +stderr 90 +stdout 91 +stderr 91 +stdout 92 +stderr 92 +stdout 93 +stderr 93 +stdout 94 +stderr 94 +stdout 95 +stderr 95 +stdout 96 +stderr 96 +stdout 97 +stderr 97 +stdout 98 +stderr 98 +stdout 99 +stderr 99 +stdout 100 +stderr 100 +stdout 101 +stderr 101 +stdout 102 +stderr 102 +stdout 103 +stderr 103 +stdout 104 +stderr 104 +stdout 105 +stderr 105 +stdout 106 +stderr 106 +stdout 107 +stderr 107 +stdout 108 +stderr 108 +stdout 109 +stderr 109 +stdout 110 +stderr 110 +stdout 111 +stderr 111 +stdout 112 +stderr 112 +stdout 113 +stderr 113 +stdout 114 +stderr 114 +stdout 115 +stderr 115 +stdout 116 +stderr 116 +stdout 117 +stderr 117 +stdout 118 +stderr 118 +stdout 119 +stderr 119 +stdout 120 +stderr 120 +stdout 121 +stderr 121 +stdout 122 +stderr 122 +stdout 123 +stderr 123 +stdout 124 +stderr 124 +stdout 125 +stderr 125 +stdout 126 +stderr 126 +stdout 127 +stderr 127 +stdout 128 +stderr 128 +stdout 129 +stderr 129 +stdout 130 +stderr 130 +stdout 131 +stderr 131 +stdout 132 +stderr 132 +stdout 133 +stderr 133 +stdout 134 +stderr 134 +stdout 135 +stderr 135 +stdout 136 +stderr 136 +stdout 137 +stderr 137 +stdout 138 +stderr 138 +stdout 139 +stderr 139 +stdout 140 +stderr 140 +stdout 141 +stderr 141 +stdout 142 +stderr 142 +stdout 143 +stderr 143 +stdout 144 +stderr 144 +stdout 145 +stderr 145 +stdout 146 +stderr 146 +stdout 147 +stderr 147 +stdout 148 +stderr 148 +stdout 149 +stderr 149 +stdout 150 +stderr 150 +stdout 151 +stderr 151 +stdout 152 +stderr 152 +stdout 153 +stderr 153 +stdout 154 +stderr 154 +stdout 155 +stderr 155 +stdout 156 +stderr 156 +stdout 157 +stderr 157 +stdout 158 +stderr 158 +stdout 159 +stderr 159 +stdout 160 +stderr 160 +stdout 161 +stderr 161 +stdout 162 +stderr 162 +stdout 163 +stderr 163 +stdout 164 +stderr 164 +stdout 165 +stderr 165 +stdout 166 +stderr 166 +stdout 167 +stderr 167 +stdout 168 +stderr 168 +stdout 169 +stderr 169 +stdout 170 +stderr 170 +stdout 171 +stderr 171 +stdout 172 +stderr 172 +stdout 173 +stderr 173 +stdout 174 +stderr 174 +stdout 175 +stderr 175 +stdout 176 +stderr 176 +stdout 177 +stderr 177 +stdout 178 +stderr 178 +stdout 179 +stderr 179 +stdout 180 +stderr 180 +stdout 181 +stderr 181 +stdout 182 +stderr 182 +stdout 183 +stderr 183 +stdout 184 +stderr 184 +stdout 185 +stderr 185 +stdout 186 +stderr 186 +stdout 187 +stderr 187 +stdout 188 +stderr 188 +stdout 189 +stderr 189 +stdout 190 +stderr 190 +stdout 191 +stderr 191 +stdout 192 +stderr 192 +stdout 193 +stderr 193 +stdout 194 +stderr 194 +stdout 195 +stderr 195 +stdout 196 +stderr 196 +stdout 197 +stderr 197 +stdout 198 +stderr 198 +stdout 199 +stderr 199 +stdout 200 +stderr 200 +stdout 201 +stderr 201 +stdout 202 +stderr 202 +stdout 203 +stderr 203 +stdout 204 +stderr 204 +stdout 205 +stderr 205 +stdout 206 +stderr 206 +stdout 207 +stderr 207 +stdout 208 +stderr 208 +stdout 209 +stderr 209 +stdout 210 +stderr 210 +stdout 211 +stderr 211 +stdout 212 +stderr 212 +stdout 213 +stderr 213 +stdout 214 +stderr 214 +stdout 215 +stderr 215 +stdout 216 +stderr 216 +stdout 217 +stderr 217 +stdout 218 +stderr 218 +stdout 219 +stderr 219 +stdout 220 +stderr 220 +stdout 221 +stderr 221 +stdout 222 +stderr 222 +stdout 223 +stderr 223 +stdout 224 +stderr 224 +stdout 225 +stderr 225 +stdout 226 +stderr 226 +stdout 227 +stderr 227 +stdout 228 +stderr 228 +stdout 229 +stderr 229 +stdout 230 +stderr 230 +stdout 231 +stderr 231 +stdout 232 +stderr 232 +stdout 233 +stderr 233 +stdout 234 +stderr 234 +stdout 235 +stderr 235 +stdout 236 +stderr 236 +stdout 237 +stderr 237 +stdout 238 +stderr 238 +stdout 239 +stderr 239 +stdout 240 +stderr 240 +stdout 241 +stderr 241 +stdout 242 +stderr 242 +stdout 243 +stderr 243 +stdout 244 +stderr 244 +stdout 245 +stderr 245 +stdout 246 +stderr 246 +stdout 247 +stderr 247 +stdout 248 +stderr 248 +stdout 249 +stderr 249 +stdout 250 +stderr 250 +stdout 251 +stderr 251 +stdout 252 +stderr 252 +stdout 253 +stderr 253 +stdout 254 +stderr 254 +stdout 255 +stderr 255 +stdout 256 +stderr 256 +stdout 257 +stderr 257 +stdout 258 +stderr 258 +stdout 259 +stderr 259 +stdout 260 +stderr 260 +stdout 261 +stderr 261 +stdout 262 +stderr 262 +stdout 263 +stderr 263 +stdout 264 +stderr 264 +stdout 265 +stderr 265 +stdout 266 +stderr 266 +stdout 267 +stderr 267 +stdout 268 +stderr 268 +stdout 269 +stderr 269 +stdout 270 +stderr 270 +stdout 271 +stderr 271 +stdout 272 +stderr 272 +stdout 273 +stderr 273 +stdout 274 +stderr 274 +stdout 275 +stderr 275 +stdout 276 +stderr 276 +stdout 277 +stderr 277 +stdout 278 +stderr 278 +stdout 279 +stderr 279 +stdout 280 +stderr 280 +stdout 281 +stderr 281 +stdout 282 +stderr 282 +stdout 283 +stderr 283 +stdout 284 +stderr 284 +stdout 285 +stderr 285 +stdout 286 +stderr 286 +stdout 287 +stderr 287 +stdout 288 +stderr 288 +stdout 289 +stderr 289 +stdout 290 +stderr 290 +stdout 291 +stderr 291 +stdout 292 +stderr 292 +stdout 293 +stderr 293 +stdout 294 +stderr 294 +stdout 295 +stderr 295 +stdout 296 +stderr 296 +stdout 297 +stderr 297 +stdout 298 +stderr 298 +stdout 299 +stderr 299 +stdout 300 +stderr 300 +stdout 301 +stderr 301 +stdout 302 +stderr 302 +stdout 303 +stderr 303 +stdout 304 +stderr 304 +stdout 305 +stderr 305 +stdout 306 +stderr 306 +stdout 307 +stderr 307 +stdout 308 +stderr 308 +stdout 309 +stderr 309 +stdout 310 +stderr 310 +stdout 311 +stderr 311 +stdout 312 +stderr 312 +stdout 313 +stderr 313 +stdout 314 +stderr 314 +stdout 315 +stderr 315 +stdout 316 +stderr 316 +stdout 317 +stderr 317 +stdout 318 +stderr 318 +stdout 319 +stderr 319 +stdout 320 +stderr 320 +stdout 321 +stderr 321 +stdout 322 +stderr 322 +stdout 323 +stderr 323 +stdout 324 +stderr 324 +stdout 325 +stderr 325 +stdout 326 +stderr 326 +stdout 327 +stderr 327 +stdout 328 +stderr 328 +stdout 329 +stderr 329 +stdout 330 +stderr 330 +stdout 331 +stderr 331 +stdout 332 +stderr 332 +stdout 333 +stderr 333 +stdout 334 +stderr 334 +stdout 335 +stderr 335 +stdout 336 +stderr 336 +stdout 337 +stderr 337 +stdout 338 +stderr 338 +stdout 339 +stderr 339 +stdout 340 +stderr 340 +stdout 341 +stderr 341 +stdout 342 +stderr 342 +stdout 343 +stderr 343 +stdout 344 +stderr 344 +stdout 345 +stderr 345 +stdout 346 +stderr 346 +stdout 347 +stderr 347 +stdout 348 +stderr 348 +stdout 349 +stderr 349 +stdout 350 +stderr 350 +stdout 351 +stderr 351 +stdout 352 +stderr 352 +stdout 353 +stderr 353 +stdout 354 +stderr 354 +stdout 355 +stderr 355 +stdout 356 +stderr 356 +stdout 357 +stderr 357 +stdout 358 +stderr 358 +stdout 359 +stderr 359 +stdout 360 +stderr 360 +stdout 361 +stderr 361 +stdout 362 +stderr 362 +stdout 363 +stderr 363 +stdout 364 +stderr 364 +stdout 365 +stderr 365 +stdout 366 +stderr 366 +stdout 367 +stderr 367 +stdout 368 +stderr 368 +stdout 369 +stderr 369 +stdout 370 +stderr 370 +stdout 371 +stderr 371 +stdout 372 +stderr 372 +stdout 373 +stderr 373 +stdout 374 +stderr 374 +stdout 375 +stderr 375 +stdout 376 +stderr 376 +stdout 377 +stderr 377 +stdout 378 +stderr 378 +stdout 379 +stderr 379 +stdout 380 +stderr 380 +stdout 381 +stderr 381 +stdout 382 +stderr 382 +stdout 383 +stderr 383 +stdout 384 +stderr 384 +stdout 385 +stderr 385 +stdout 386 +stderr 386 +stdout 387 +stderr 387 +stdout 388 +stderr 388 +stdout 389 +stderr 389 +stdout 390 +stderr 390 +stdout 391 +stderr 391 +stdout 392 +stderr 392 +stdout 393 +stderr 393 +stdout 394 +stderr 394 +stdout 395 +stderr 395 +stdout 396 +stderr 396 +stdout 397 +stderr 397 +stdout 398 +stderr 398 +stdout 399 +stderr 399 +stdout 400 +stderr 400 +stdout 401 +stderr 401 +stdout 402 +stderr 402 +stdout 403 +stderr 403 +stdout 404 +stderr 404 +stdout 405 +stderr 405 +stdout 406 +stderr 406 +stdout 407 +stderr 407 +stdout 408 +stderr 408 +stdout 409 +stderr 409 +stdout 410 +stderr 410 +stdout 411 +stderr 411 +stdout 412 +stderr 412 +stdout 413 +stderr 413 +stdout 414 +stderr 414 +stdout 415 +stderr 415 +stdout 416 +stderr 416 +stdout 417 +stderr 417 +stdout 418 +stderr 418 +stdout 419 +stderr 419 +stdout 420 +stderr 420 +stdout 421 +stderr 421 +stdout 422 +stderr 422 +stdout 423 +stderr 423 +stdout 424 +stderr 424 +stdout 425 +stderr 425 +stdout 426 +stderr 426 +stdout 427 +stderr 427 +stdout 428 +stderr 428 +stdout 429 +stderr 429 +stdout 430 +stderr 430 +stdout 431 +stderr 431 +stdout 432 +stderr 432 +stdout 433 +stderr 433 +stdout 434 +stderr 434 +stdout 435 +stderr 435 +stdout 436 +stderr 436 +stdout 437 +stderr 437 +stdout 438 +stderr 438 +stdout 439 +stderr 439 +stdout 440 +stderr 440 +stdout 441 +stderr 441 +stdout 442 +stderr 442 +stdout 443 +stderr 443 +stdout 444 +stderr 444 +stdout 445 +stderr 445 +stdout 446 +stderr 446 +stdout 447 +stderr 447 +stdout 448 +stderr 448 +stdout 449 +stderr 449 +stdout 450 +stderr 450 +stdout 451 +stderr 451 +stdout 452 +stderr 452 +stdout 453 +stderr 453 +stdout 454 +stderr 454 +stdout 455 +stderr 455 +stdout 456 +stderr 456 +stdout 457 +stderr 457 +stdout 458 +stderr 458 +stdout 459 +stderr 459 +stdout 460 +stderr 460 +stdout 461 +stderr 461 +stdout 462 +stderr 462 +stdout 463 +stderr 463 +stdout 464 +stderr 464 +stdout 465 +stderr 465 +stdout 466 +stderr 466 +stdout 467 +stderr 467 +stdout 468 +stderr 468 +stdout 469 +stderr 469 +stdout 470 +stderr 470 +stdout 471 +stderr 471 +stdout 472 +stderr 472 +stdout 473 +stderr 473 +stdout 474 +stderr 474 +stdout 475 +stderr 475 +stdout 476 +stderr 476 +stdout 477 +stderr 477 +stdout 478 +stderr 478 +stdout 479 +stderr 479 +stdout 480 +stderr 480 +stdout 481 +stderr 481 +stdout 482 +stderr 482 +stdout 483 +stderr 483 +stdout 484 +stderr 484 +stdout 485 +stderr 485 +stdout 486 +stderr 486 +stdout 487 +stderr 487 +stdout 488 +stderr 488 +stdout 489 +stderr 489 +stdout 490 +stderr 490 +stdout 491 +stderr 491 +stdout 492 +stderr 492 +stdout 493 +stderr 493 +stdout 494 +stderr 494 +stdout 495 +stderr 495 +stdout 496 +stderr 496 +stdout 497 +stderr 497 +stdout 498 +stderr 498 +stdout 499 +stderr 499 +stdout 500 +stderr 500 +stdout 501 +stderr 501 +stdout 502 +stderr 502 +stdout 503 +stderr 503 +stdout 504 +stderr 504 +stdout 505 +stderr 505 +stdout 506 +stderr 506 +stdout 507 +stderr 507 +stdout 508 +stderr 508 +stdout 509 +stderr 509 +stdout 510 +stderr 510 +stdout 511 +stderr 511 +stdout 512 +stderr 512 +stdout 513 +stderr 513 +stdout 514 +stderr 514 +stdout 515 +stderr 515 +stdout 516 +stderr 516 +stdout 517 +stderr 517 +stdout 518 +stderr 518 +stdout 519 +stderr 519 +stdout 520 +stderr 520 +stdout 521 +stderr 521 +stdout 522 +stderr 522 +stdout 523 +stderr 523 +stdout 524 +stderr 524 +stdout 525 +stderr 525 +stdout 526 +stderr 526 +stdout 527 +stderr 527 +stdout 528 +stderr 528 +stdout 529 +stderr 529 +stdout 530 +stderr 530 +stdout 531 +stderr 531 +stdout 532 +stderr 532 +stdout 533 +stderr 533 +stdout 534 +stderr 534 +stdout 535 +stderr 535 +stdout 536 +stderr 536 +stdout 537 +stderr 537 +stdout 538 +stderr 538 +stdout 539 +stderr 539 +stdout 540 +stderr 540 +stdout 541 +stderr 541 +stdout 542 +stderr 542 +stdout 543 +stderr 543 +stdout 544 +stderr 544 +stdout 545 +stderr 545 +stdout 546 +stderr 546 +stdout 547 +stderr 547 +stdout 548 +stderr 548 +stdout 549 +stderr 549 +stdout 550 +stderr 550 +stdout 551 +stderr 551 +stdout 552 +stderr 552 +stdout 553 +stderr 553 +stdout 554 +stderr 554 +stdout 555 +stderr 555 +stdout 556 +stderr 556 +stdout 557 +stderr 557 +stdout 558 +stderr 558 +stdout 559 +stderr 559 +stdout 560 +stderr 560 +stdout 561 +stderr 561 +stdout 562 +stderr 562 +stdout 563 +stderr 563 +stdout 564 +stderr 564 +stdout 565 +stderr 565 +stdout 566 +stderr 566 +stdout 567 +stderr 567 +stdout 568 +stderr 568 +stdout 569 +stderr 569 +stdout 570 +stderr 570 +stdout 571 +stderr 571 +stdout 572 +stderr 572 +stdout 573 +stderr 573 +stdout 574 +stderr 574 +stdout 575 +stderr 575 +stdout 576 +stderr 576 +stdout 577 +stderr 577 +stdout 578 +stderr 578 +stdout 579 +stderr 579 +stdout 580 +stderr 580 +stdout 581 +stderr 581 +stdout 582 +stderr 582 +stdout 583 +stderr 583 +stdout 584 +stderr 584 +stdout 585 +stderr 585 +stdout 586 +stderr 586 +stdout 587 +stderr 587 +stdout 588 +stderr 588 +stdout 589 +stderr 589 +stdout 590 +stderr 590 +stdout 591 +stderr 591 +stdout 592 +stderr 592 +stdout 593 +stderr 593 +stdout 594 +stderr 594 +stdout 595 +stderr 595 +stdout 596 +stderr 596 +stdout 597 +stderr 597 +stdout 598 +stderr 598 +stdout 599 +stderr 599 +stdout 600 +stderr 600 +stdout 601 +stderr 601 +stdout 602 +stderr 602 +stdout 603 +stderr 603 +stdout 604 +stderr 604 +stdout 605 +stderr 605 +stdout 606 +stderr 606 +stdout 607 +stderr 607 +stdout 608 +stderr 608 +stdout 609 +stderr 609 +stdout 610 +stderr 610 +stdout 611 +stderr 611 +stdout 612 +stderr 612 +stdout 613 +stderr 613 +stdout 614 +stderr 614 +stdout 615 +stderr 615 +stdout 616 +stderr 616 +stdout 617 +stderr 617 +stdout 618 +stderr 618 +stdout 619 +stderr 619 +stdout 620 +stderr 620 +stdout 621 +stderr 621 +stdout 622 +stderr 622 +stdout 623 +stderr 623 +stdout 624 +stderr 624 +stdout 625 +stderr 625 +stdout 626 +stderr 626 +stdout 627 +stderr 627 +stdout 628 +stderr 628 +stdout 629 +stderr 629 +stdout 630 +stderr 630 +stdout 631 +stderr 631 +stdout 632 +stderr 632 +stdout 633 +stderr 633 +stdout 634 +stderr 634 +stdout 635 +stderr 635 +stdout 636 +stderr 636 +stdout 637 +stderr 637 +stdout 638 +stderr 638 +stdout 639 +stderr 639 +stdout 640 +stderr 640 +stdout 641 +stderr 641 +stdout 642 +stderr 642 +stdout 643 +stderr 643 +stdout 644 +stderr 644 +stdout 645 +stderr 645 +stdout 646 +stderr 646 +stdout 647 +stderr 647 +stdout 648 +stderr 648 +stdout 649 +stderr 649 +stdout 650 +stderr 650 +stdout 651 +stderr 651 +stdout 652 +stderr 652 +stdout 653 +stderr 653 +stdout 654 +stderr 654 +stdout 655 +stderr 655 +stdout 656 +stderr 656 +stdout 657 +stderr 657 +stdout 658 +stderr 658 +stdout 659 +stderr 659 +stdout 660 +stderr 660 +stdout 661 +stderr 661 +stdout 662 +stderr 662 +stdout 663 +stderr 663 +stdout 664 +stderr 664 +stdout 665 +stderr 665 +stdout 666 +stderr 666 +stdout 667 +stderr 667 +stdout 668 +stderr 668 +stdout 669 +stderr 669 +stdout 670 +stderr 670 +stdout 671 +stderr 671 +stdout 672 +stderr 672 +stdout 673 +stderr 673 +stdout 674 +stderr 674 +stdout 675 +stderr 675 +stdout 676 +stderr 676 +stdout 677 +stderr 677 +stdout 678 +stderr 678 +stdout 679 +stderr 679 +stdout 680 +stderr 680 +stdout 681 +stderr 681 +stdout 682 +stderr 682 +stdout 683 +stderr 683 +stdout 684 +stderr 684 +stdout 685 +stderr 685 +stdout 686 +stderr 686 +stdout 687 +stderr 687 +stdout 688 +stderr 688 +stdout 689 +stderr 689 +stdout 690 +stderr 690 +stdout 691 +stderr 691 +stdout 692 +stderr 692 +stdout 693 +stderr 693 +stdout 694 +stderr 694 +stdout 695 +stderr 695 +stdout 696 +stderr 696 +stdout 697 +stderr 697 +stdout 698 +stderr 698 +stdout 699 +stderr 699 +stdout 700 +stderr 700 +stdout 701 +stderr 701 +stdout 702 +stderr 702 +stdout 703 +stderr 703 +stdout 704 +stderr 704 +stdout 705 +stderr 705 +stdout 706 +stderr 706 +stdout 707 +stderr 707 +stdout 708 +stderr 708 +stdout 709 +stderr 709 +stdout 710 +stderr 710 +stdout 711 +stderr 711 +stdout 712 +stderr 712 +stdout 713 +stderr 713 +stdout 714 +stderr 714 +stdout 715 +stderr 715 +stdout 716 +stderr 716 +stdout 717 +stderr 717 +stdout 718 +stderr 718 +stdout 719 +stderr 719 +stdout 720 +stderr 720 +stdout 721 +stderr 721 +stdout 722 +stderr 722 +stdout 723 +stderr 723 +stdout 724 +stderr 724 +stdout 725 +stderr 725 +stdout 726 +stderr 726 +stdout 727 +stderr 727 +stdout 728 +stderr 728 +stdout 729 +stderr 729 +stdout 730 +stderr 730 +stdout 731 +stderr 731 +stdout 732 +stderr 732 +stdout 733 +stderr 733 +stdout 734 +stderr 734 +stdout 735 +stderr 735 +stdout 736 +stderr 736 +stdout 737 +stderr 737 +stdout 738 +stderr 738 +stdout 739 +stderr 739 +stdout 740 +stderr 740 +stdout 741 +stderr 741 +stdout 742 +stderr 742 +stdout 743 +stderr 743 +stdout 744 +stderr 744 +stdout 745 +stderr 745 +stdout 746 +stderr 746 +stdout 747 +stderr 747 +stdout 748 +stderr 748 +stdout 749 +stderr 749 +stdout 750 +stderr 750 +stdout 751 +stderr 751 +stdout 752 +stderr 752 +stdout 753 +stderr 753 +stdout 754 +stderr 754 +stdout 755 +stderr 755 +stdout 756 +stderr 756 +stdout 757 +stderr 757 +stdout 758 +stderr 758 +stdout 759 +stderr 759 +stdout 760 +stderr 760 +stdout 761 +stderr 761 +stdout 762 +stderr 762 +stdout 763 +stderr 763 +stdout 764 +stderr 764 +stdout 765 +stderr 765 +stdout 766 +stderr 766 +stdout 767 +stderr 767 +stdout 768 +stderr 768 +stdout 769 +stderr 769 +stdout 770 +stderr 770 +stdout 771 +stderr 771 +stdout 772 +stderr 772 +stdout 773 +stderr 773 +stdout 774 +stderr 774 +stdout 775 +stderr 775 +stdout 776 +stderr 776 +stdout 777 +stderr 777 +stdout 778 +stderr 778 +stdout 779 +stderr 779 +stdout 780 +stderr 780 +stdout 781 +stderr 781 +stdout 782 +stderr 782 +stdout 783 +stderr 783 +stdout 784 +stderr 784 +stdout 785 +stderr 785 +stdout 786 +stderr 786 +stdout 787 +stderr 787 +stdout 788 +stderr 788 +stdout 789 +stderr 789 +stdout 790 +stderr 790 +stdout 791 +stderr 791 +stdout 792 +stderr 792 +stdout 793 +stderr 793 +stdout 794 +stderr 794 +stdout 795 +stderr 795 +stdout 796 +stderr 796 +stdout 797 +stderr 797 +stdout 798 +stderr 798 +stdout 799 +stderr 799 +stdout 800 +stderr 800 +stdout 801 +stderr 801 +stdout 802 +stderr 802 +stdout 803 +stderr 803 +stdout 804 +stderr 804 +stdout 805 +stderr 805 +stdout 806 +stderr 806 +stdout 807 +stderr 807 +stdout 808 +stderr 808 +stdout 809 +stderr 809 +stdout 810 +stderr 810 +stdout 811 +stderr 811 +stdout 812 +stderr 812 +stdout 813 +stderr 813 +stdout 814 +stderr 814 +stdout 815 +stderr 815 +stdout 816 +stderr 816 +stdout 817 +stderr 817 +stdout 818 +stderr 818 +stdout 819 +stderr 819 +stdout 820 +stderr 820 +stdout 821 +stderr 821 +stdout 822 +stderr 822 +stdout 823 +stderr 823 +stdout 824 +stderr 824 +stdout 825 +stderr 825 +stdout 826 +stderr 826 +stdout 827 +stderr 827 +stdout 828 +stderr 828 +stdout 829 +stderr 829 +stdout 830 +stderr 830 +stdout 831 +stderr 831 +stdout 832 +stderr 832 +stdout 833 +stderr 833 +stdout 834 +stderr 834 +stdout 835 +stderr 835 +stdout 836 +stderr 836 +stdout 837 +stderr 837 +stdout 838 +stderr 838 +stdout 839 +stderr 839 +stdout 840 +stderr 840 +stdout 841 +stderr 841 +stdout 842 +stderr 842 +stdout 843 +stderr 843 +stdout 844 +stderr 844 +stdout 845 +stderr 845 +stdout 846 +stderr 846 +stdout 847 +stderr 847 +stdout 848 +stderr 848 +stdout 849 +stderr 849 +stdout 850 +stderr 850 +stdout 851 +stderr 851 +stdout 852 +stderr 852 +stdout 853 +stderr 853 +stdout 854 +stderr 854 +stdout 855 +stderr 855 +stdout 856 +stderr 856 +stdout 857 +stderr 857 +stdout 858 +stderr 858 +stdout 859 +stderr 859 +stdout 860 +stderr 860 +stdout 861 +stderr 861 +stdout 862 +stderr 862 +stdout 863 +stderr 863 +stdout 864 +stderr 864 +stdout 865 +stderr 865 +stdout 866 +stderr 866 +stdout 867 +stderr 867 +stdout 868 +stderr 868 +stdout 869 +stderr 869 +stdout 870 +stderr 870 +stdout 871 +stderr 871 +stdout 872 +stderr 872 +stdout 873 +stderr 873 +stdout 874 +stderr 874 +stdout 875 +stderr 875 +stdout 876 +stderr 876 +stdout 877 +stderr 877 +stdout 878 +stderr 878 +stdout 879 +stderr 879 +stdout 880 +stderr 880 +stdout 881 +stderr 881 +stdout 882 +stderr 882 +stdout 883 +stderr 883 +stdout 884 +stderr 884 +stdout 885 +stderr 885 +stdout 886 +stderr 886 +stdout 887 +stderr 887 +stdout 888 +stderr 888 +stdout 889 +stderr 889 +stdout 890 +stderr 890 +stdout 891 +stderr 891 +stdout 892 +stderr 892 +stdout 893 +stderr 893 +stdout 894 +stderr 894 +stdout 895 +stderr 895 +stdout 896 +stderr 896 +stdout 897 +stderr 897 +stdout 898 +stderr 898 +stdout 899 +stderr 899 +stdout 900 +stderr 900 +stdout 901 +stderr 901 +stdout 902 +stderr 902 +stdout 903 +stderr 903 +stdout 904 +stderr 904 +stdout 905 +stderr 905 +stdout 906 +stderr 906 +stdout 907 +stderr 907 +stdout 908 +stderr 908 +stdout 909 +stderr 909 +stdout 910 +stderr 910 +stdout 911 +stderr 911 +stdout 912 +stderr 912 +stdout 913 +stderr 913 +stdout 914 +stderr 914 +stdout 915 +stderr 915 +stdout 916 +stderr 916 +stdout 917 +stderr 917 +stdout 918 +stderr 918 +stdout 919 +stderr 919 +stdout 920 +stderr 920 +stdout 921 +stderr 921 +stdout 922 +stderr 922 +stdout 923 +stderr 923 +stdout 924 +stderr 924 +stdout 925 +stderr 925 +stdout 926 +stderr 926 +stdout 927 +stderr 927 +stdout 928 +stderr 928 +stdout 929 +stderr 929 +stdout 930 +stderr 930 +stdout 931 +stderr 931 +stdout 932 +stderr 932 +stdout 933 +stderr 933 +stdout 934 +stderr 934 +stdout 935 +stderr 935 +stdout 936 +stderr 936 +stdout 937 +stderr 937 +stdout 938 +stderr 938 +stdout 939 +stderr 939 +stdout 940 +stderr 940 +stdout 941 +stderr 941 +stdout 942 +stderr 942 +stdout 943 +stderr 943 +stdout 944 +stderr 944 +stdout 945 +stderr 945 +stdout 946 +stderr 946 +stdout 947 +stderr 947 +stdout 948 +stderr 948 +stdout 949 +stderr 949 +stdout 950 +stderr 950 +stdout 951 +stderr 951 +stdout 952 +stderr 952 +stdout 953 +stderr 953 +stdout 954 +stderr 954 +stdout 955 +stderr 955 +stdout 956 +stderr 956 +stdout 957 +stderr 957 +stdout 958 +stderr 958 +stdout 959 +stderr 959 +stdout 960 +stderr 960 +stdout 961 +stderr 961 +stdout 962 +stderr 962 +stdout 963 +stderr 963 +stdout 964 +stderr 964 +stdout 965 +stderr 965 +stdout 966 +stderr 966 +stdout 967 +stderr 967 +stdout 968 +stderr 968 +stdout 969 +stderr 969 +stdout 970 +stderr 970 +stdout 971 +stderr 971 +stdout 972 +stderr 972 +stdout 973 +stderr 973 +stdout 974 +stderr 974 +stdout 975 +stderr 975 +stdout 976 +stderr 976 +stdout 977 +stderr 977 +stdout 978 +stderr 978 +stdout 979 +stderr 979 +stdout 980 +stderr 980 +stdout 981 +stderr 981 +stdout 982 +stderr 982 +stdout 983 +stderr 983 +stdout 984 +stderr 984 +stdout 985 +stderr 985 +stdout 986 +stderr 986 +stdout 987 +stderr 987 +stdout 988 +stderr 988 +stdout 989 +stderr 989 +stdout 990 +stderr 990 +stdout 991 +stderr 991 +stdout 992 +stderr 992 +stdout 993 +stderr 993 +stdout 994 +stderr 994 +stdout 995 +stderr 995 +stdout 996 +stderr 996 +stdout 997 +stderr 997 +stdout 998 +stderr 998 +stdout 999 +stderr 999 diff --git a/www/node_modules/exit/test/fixtures/1000-stdout.txt b/www/node_modules/exit/test/fixtures/1000-stdout.txt new file mode 100644 index 0000000..d3649d0 --- /dev/null +++ b/www/node_modules/exit/test/fixtures/1000-stdout.txt @@ -0,0 +1,1000 @@ +stdout 0 +stdout 1 +stdout 2 +stdout 3 +stdout 4 +stdout 5 +stdout 6 +stdout 7 +stdout 8 +stdout 9 +stdout 10 +stdout 11 +stdout 12 +stdout 13 +stdout 14 +stdout 15 +stdout 16 +stdout 17 +stdout 18 +stdout 19 +stdout 20 +stdout 21 +stdout 22 +stdout 23 +stdout 24 +stdout 25 +stdout 26 +stdout 27 +stdout 28 +stdout 29 +stdout 30 +stdout 31 +stdout 32 +stdout 33 +stdout 34 +stdout 35 +stdout 36 +stdout 37 +stdout 38 +stdout 39 +stdout 40 +stdout 41 +stdout 42 +stdout 43 +stdout 44 +stdout 45 +stdout 46 +stdout 47 +stdout 48 +stdout 49 +stdout 50 +stdout 51 +stdout 52 +stdout 53 +stdout 54 +stdout 55 +stdout 56 +stdout 57 +stdout 58 +stdout 59 +stdout 60 +stdout 61 +stdout 62 +stdout 63 +stdout 64 +stdout 65 +stdout 66 +stdout 67 +stdout 68 +stdout 69 +stdout 70 +stdout 71 +stdout 72 +stdout 73 +stdout 74 +stdout 75 +stdout 76 +stdout 77 +stdout 78 +stdout 79 +stdout 80 +stdout 81 +stdout 82 +stdout 83 +stdout 84 +stdout 85 +stdout 86 +stdout 87 +stdout 88 +stdout 89 +stdout 90 +stdout 91 +stdout 92 +stdout 93 +stdout 94 +stdout 95 +stdout 96 +stdout 97 +stdout 98 +stdout 99 +stdout 100 +stdout 101 +stdout 102 +stdout 103 +stdout 104 +stdout 105 +stdout 106 +stdout 107 +stdout 108 +stdout 109 +stdout 110 +stdout 111 +stdout 112 +stdout 113 +stdout 114 +stdout 115 +stdout 116 +stdout 117 +stdout 118 +stdout 119 +stdout 120 +stdout 121 +stdout 122 +stdout 123 +stdout 124 +stdout 125 +stdout 126 +stdout 127 +stdout 128 +stdout 129 +stdout 130 +stdout 131 +stdout 132 +stdout 133 +stdout 134 +stdout 135 +stdout 136 +stdout 137 +stdout 138 +stdout 139 +stdout 140 +stdout 141 +stdout 142 +stdout 143 +stdout 144 +stdout 145 +stdout 146 +stdout 147 +stdout 148 +stdout 149 +stdout 150 +stdout 151 +stdout 152 +stdout 153 +stdout 154 +stdout 155 +stdout 156 +stdout 157 +stdout 158 +stdout 159 +stdout 160 +stdout 161 +stdout 162 +stdout 163 +stdout 164 +stdout 165 +stdout 166 +stdout 167 +stdout 168 +stdout 169 +stdout 170 +stdout 171 +stdout 172 +stdout 173 +stdout 174 +stdout 175 +stdout 176 +stdout 177 +stdout 178 +stdout 179 +stdout 180 +stdout 181 +stdout 182 +stdout 183 +stdout 184 +stdout 185 +stdout 186 +stdout 187 +stdout 188 +stdout 189 +stdout 190 +stdout 191 +stdout 192 +stdout 193 +stdout 194 +stdout 195 +stdout 196 +stdout 197 +stdout 198 +stdout 199 +stdout 200 +stdout 201 +stdout 202 +stdout 203 +stdout 204 +stdout 205 +stdout 206 +stdout 207 +stdout 208 +stdout 209 +stdout 210 +stdout 211 +stdout 212 +stdout 213 +stdout 214 +stdout 215 +stdout 216 +stdout 217 +stdout 218 +stdout 219 +stdout 220 +stdout 221 +stdout 222 +stdout 223 +stdout 224 +stdout 225 +stdout 226 +stdout 227 +stdout 228 +stdout 229 +stdout 230 +stdout 231 +stdout 232 +stdout 233 +stdout 234 +stdout 235 +stdout 236 +stdout 237 +stdout 238 +stdout 239 +stdout 240 +stdout 241 +stdout 242 +stdout 243 +stdout 244 +stdout 245 +stdout 246 +stdout 247 +stdout 248 +stdout 249 +stdout 250 +stdout 251 +stdout 252 +stdout 253 +stdout 254 +stdout 255 +stdout 256 +stdout 257 +stdout 258 +stdout 259 +stdout 260 +stdout 261 +stdout 262 +stdout 263 +stdout 264 +stdout 265 +stdout 266 +stdout 267 +stdout 268 +stdout 269 +stdout 270 +stdout 271 +stdout 272 +stdout 273 +stdout 274 +stdout 275 +stdout 276 +stdout 277 +stdout 278 +stdout 279 +stdout 280 +stdout 281 +stdout 282 +stdout 283 +stdout 284 +stdout 285 +stdout 286 +stdout 287 +stdout 288 +stdout 289 +stdout 290 +stdout 291 +stdout 292 +stdout 293 +stdout 294 +stdout 295 +stdout 296 +stdout 297 +stdout 298 +stdout 299 +stdout 300 +stdout 301 +stdout 302 +stdout 303 +stdout 304 +stdout 305 +stdout 306 +stdout 307 +stdout 308 +stdout 309 +stdout 310 +stdout 311 +stdout 312 +stdout 313 +stdout 314 +stdout 315 +stdout 316 +stdout 317 +stdout 318 +stdout 319 +stdout 320 +stdout 321 +stdout 322 +stdout 323 +stdout 324 +stdout 325 +stdout 326 +stdout 327 +stdout 328 +stdout 329 +stdout 330 +stdout 331 +stdout 332 +stdout 333 +stdout 334 +stdout 335 +stdout 336 +stdout 337 +stdout 338 +stdout 339 +stdout 340 +stdout 341 +stdout 342 +stdout 343 +stdout 344 +stdout 345 +stdout 346 +stdout 347 +stdout 348 +stdout 349 +stdout 350 +stdout 351 +stdout 352 +stdout 353 +stdout 354 +stdout 355 +stdout 356 +stdout 357 +stdout 358 +stdout 359 +stdout 360 +stdout 361 +stdout 362 +stdout 363 +stdout 364 +stdout 365 +stdout 366 +stdout 367 +stdout 368 +stdout 369 +stdout 370 +stdout 371 +stdout 372 +stdout 373 +stdout 374 +stdout 375 +stdout 376 +stdout 377 +stdout 378 +stdout 379 +stdout 380 +stdout 381 +stdout 382 +stdout 383 +stdout 384 +stdout 385 +stdout 386 +stdout 387 +stdout 388 +stdout 389 +stdout 390 +stdout 391 +stdout 392 +stdout 393 +stdout 394 +stdout 395 +stdout 396 +stdout 397 +stdout 398 +stdout 399 +stdout 400 +stdout 401 +stdout 402 +stdout 403 +stdout 404 +stdout 405 +stdout 406 +stdout 407 +stdout 408 +stdout 409 +stdout 410 +stdout 411 +stdout 412 +stdout 413 +stdout 414 +stdout 415 +stdout 416 +stdout 417 +stdout 418 +stdout 419 +stdout 420 +stdout 421 +stdout 422 +stdout 423 +stdout 424 +stdout 425 +stdout 426 +stdout 427 +stdout 428 +stdout 429 +stdout 430 +stdout 431 +stdout 432 +stdout 433 +stdout 434 +stdout 435 +stdout 436 +stdout 437 +stdout 438 +stdout 439 +stdout 440 +stdout 441 +stdout 442 +stdout 443 +stdout 444 +stdout 445 +stdout 446 +stdout 447 +stdout 448 +stdout 449 +stdout 450 +stdout 451 +stdout 452 +stdout 453 +stdout 454 +stdout 455 +stdout 456 +stdout 457 +stdout 458 +stdout 459 +stdout 460 +stdout 461 +stdout 462 +stdout 463 +stdout 464 +stdout 465 +stdout 466 +stdout 467 +stdout 468 +stdout 469 +stdout 470 +stdout 471 +stdout 472 +stdout 473 +stdout 474 +stdout 475 +stdout 476 +stdout 477 +stdout 478 +stdout 479 +stdout 480 +stdout 481 +stdout 482 +stdout 483 +stdout 484 +stdout 485 +stdout 486 +stdout 487 +stdout 488 +stdout 489 +stdout 490 +stdout 491 +stdout 492 +stdout 493 +stdout 494 +stdout 495 +stdout 496 +stdout 497 +stdout 498 +stdout 499 +stdout 500 +stdout 501 +stdout 502 +stdout 503 +stdout 504 +stdout 505 +stdout 506 +stdout 507 +stdout 508 +stdout 509 +stdout 510 +stdout 511 +stdout 512 +stdout 513 +stdout 514 +stdout 515 +stdout 516 +stdout 517 +stdout 518 +stdout 519 +stdout 520 +stdout 521 +stdout 522 +stdout 523 +stdout 524 +stdout 525 +stdout 526 +stdout 527 +stdout 528 +stdout 529 +stdout 530 +stdout 531 +stdout 532 +stdout 533 +stdout 534 +stdout 535 +stdout 536 +stdout 537 +stdout 538 +stdout 539 +stdout 540 +stdout 541 +stdout 542 +stdout 543 +stdout 544 +stdout 545 +stdout 546 +stdout 547 +stdout 548 +stdout 549 +stdout 550 +stdout 551 +stdout 552 +stdout 553 +stdout 554 +stdout 555 +stdout 556 +stdout 557 +stdout 558 +stdout 559 +stdout 560 +stdout 561 +stdout 562 +stdout 563 +stdout 564 +stdout 565 +stdout 566 +stdout 567 +stdout 568 +stdout 569 +stdout 570 +stdout 571 +stdout 572 +stdout 573 +stdout 574 +stdout 575 +stdout 576 +stdout 577 +stdout 578 +stdout 579 +stdout 580 +stdout 581 +stdout 582 +stdout 583 +stdout 584 +stdout 585 +stdout 586 +stdout 587 +stdout 588 +stdout 589 +stdout 590 +stdout 591 +stdout 592 +stdout 593 +stdout 594 +stdout 595 +stdout 596 +stdout 597 +stdout 598 +stdout 599 +stdout 600 +stdout 601 +stdout 602 +stdout 603 +stdout 604 +stdout 605 +stdout 606 +stdout 607 +stdout 608 +stdout 609 +stdout 610 +stdout 611 +stdout 612 +stdout 613 +stdout 614 +stdout 615 +stdout 616 +stdout 617 +stdout 618 +stdout 619 +stdout 620 +stdout 621 +stdout 622 +stdout 623 +stdout 624 +stdout 625 +stdout 626 +stdout 627 +stdout 628 +stdout 629 +stdout 630 +stdout 631 +stdout 632 +stdout 633 +stdout 634 +stdout 635 +stdout 636 +stdout 637 +stdout 638 +stdout 639 +stdout 640 +stdout 641 +stdout 642 +stdout 643 +stdout 644 +stdout 645 +stdout 646 +stdout 647 +stdout 648 +stdout 649 +stdout 650 +stdout 651 +stdout 652 +stdout 653 +stdout 654 +stdout 655 +stdout 656 +stdout 657 +stdout 658 +stdout 659 +stdout 660 +stdout 661 +stdout 662 +stdout 663 +stdout 664 +stdout 665 +stdout 666 +stdout 667 +stdout 668 +stdout 669 +stdout 670 +stdout 671 +stdout 672 +stdout 673 +stdout 674 +stdout 675 +stdout 676 +stdout 677 +stdout 678 +stdout 679 +stdout 680 +stdout 681 +stdout 682 +stdout 683 +stdout 684 +stdout 685 +stdout 686 +stdout 687 +stdout 688 +stdout 689 +stdout 690 +stdout 691 +stdout 692 +stdout 693 +stdout 694 +stdout 695 +stdout 696 +stdout 697 +stdout 698 +stdout 699 +stdout 700 +stdout 701 +stdout 702 +stdout 703 +stdout 704 +stdout 705 +stdout 706 +stdout 707 +stdout 708 +stdout 709 +stdout 710 +stdout 711 +stdout 712 +stdout 713 +stdout 714 +stdout 715 +stdout 716 +stdout 717 +stdout 718 +stdout 719 +stdout 720 +stdout 721 +stdout 722 +stdout 723 +stdout 724 +stdout 725 +stdout 726 +stdout 727 +stdout 728 +stdout 729 +stdout 730 +stdout 731 +stdout 732 +stdout 733 +stdout 734 +stdout 735 +stdout 736 +stdout 737 +stdout 738 +stdout 739 +stdout 740 +stdout 741 +stdout 742 +stdout 743 +stdout 744 +stdout 745 +stdout 746 +stdout 747 +stdout 748 +stdout 749 +stdout 750 +stdout 751 +stdout 752 +stdout 753 +stdout 754 +stdout 755 +stdout 756 +stdout 757 +stdout 758 +stdout 759 +stdout 760 +stdout 761 +stdout 762 +stdout 763 +stdout 764 +stdout 765 +stdout 766 +stdout 767 +stdout 768 +stdout 769 +stdout 770 +stdout 771 +stdout 772 +stdout 773 +stdout 774 +stdout 775 +stdout 776 +stdout 777 +stdout 778 +stdout 779 +stdout 780 +stdout 781 +stdout 782 +stdout 783 +stdout 784 +stdout 785 +stdout 786 +stdout 787 +stdout 788 +stdout 789 +stdout 790 +stdout 791 +stdout 792 +stdout 793 +stdout 794 +stdout 795 +stdout 796 +stdout 797 +stdout 798 +stdout 799 +stdout 800 +stdout 801 +stdout 802 +stdout 803 +stdout 804 +stdout 805 +stdout 806 +stdout 807 +stdout 808 +stdout 809 +stdout 810 +stdout 811 +stdout 812 +stdout 813 +stdout 814 +stdout 815 +stdout 816 +stdout 817 +stdout 818 +stdout 819 +stdout 820 +stdout 821 +stdout 822 +stdout 823 +stdout 824 +stdout 825 +stdout 826 +stdout 827 +stdout 828 +stdout 829 +stdout 830 +stdout 831 +stdout 832 +stdout 833 +stdout 834 +stdout 835 +stdout 836 +stdout 837 +stdout 838 +stdout 839 +stdout 840 +stdout 841 +stdout 842 +stdout 843 +stdout 844 +stdout 845 +stdout 846 +stdout 847 +stdout 848 +stdout 849 +stdout 850 +stdout 851 +stdout 852 +stdout 853 +stdout 854 +stdout 855 +stdout 856 +stdout 857 +stdout 858 +stdout 859 +stdout 860 +stdout 861 +stdout 862 +stdout 863 +stdout 864 +stdout 865 +stdout 866 +stdout 867 +stdout 868 +stdout 869 +stdout 870 +stdout 871 +stdout 872 +stdout 873 +stdout 874 +stdout 875 +stdout 876 +stdout 877 +stdout 878 +stdout 879 +stdout 880 +stdout 881 +stdout 882 +stdout 883 +stdout 884 +stdout 885 +stdout 886 +stdout 887 +stdout 888 +stdout 889 +stdout 890 +stdout 891 +stdout 892 +stdout 893 +stdout 894 +stdout 895 +stdout 896 +stdout 897 +stdout 898 +stdout 899 +stdout 900 +stdout 901 +stdout 902 +stdout 903 +stdout 904 +stdout 905 +stdout 906 +stdout 907 +stdout 908 +stdout 909 +stdout 910 +stdout 911 +stdout 912 +stdout 913 +stdout 914 +stdout 915 +stdout 916 +stdout 917 +stdout 918 +stdout 919 +stdout 920 +stdout 921 +stdout 922 +stdout 923 +stdout 924 +stdout 925 +stdout 926 +stdout 927 +stdout 928 +stdout 929 +stdout 930 +stdout 931 +stdout 932 +stdout 933 +stdout 934 +stdout 935 +stdout 936 +stdout 937 +stdout 938 +stdout 939 +stdout 940 +stdout 941 +stdout 942 +stdout 943 +stdout 944 +stdout 945 +stdout 946 +stdout 947 +stdout 948 +stdout 949 +stdout 950 +stdout 951 +stdout 952 +stdout 953 +stdout 954 +stdout 955 +stdout 956 +stdout 957 +stdout 958 +stdout 959 +stdout 960 +stdout 961 +stdout 962 +stdout 963 +stdout 964 +stdout 965 +stdout 966 +stdout 967 +stdout 968 +stdout 969 +stdout 970 +stdout 971 +stdout 972 +stdout 973 +stdout 974 +stdout 975 +stdout 976 +stdout 977 +stdout 978 +stdout 979 +stdout 980 +stdout 981 +stdout 982 +stdout 983 +stdout 984 +stdout 985 +stdout 986 +stdout 987 +stdout 988 +stdout 989 +stdout 990 +stdout 991 +stdout 992 +stdout 993 +stdout 994 +stdout 995 +stdout 996 +stdout 997 +stdout 998 +stdout 999 diff --git a/www/node_modules/exit/test/fixtures/create-files.sh b/www/node_modules/exit/test/fixtures/create-files.sh new file mode 100755 index 0000000..6a526de --- /dev/null +++ b/www/node_modules/exit/test/fixtures/create-files.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +rm 10*.txt +for n in 10 100 1000; do + node log.js 0 $n stdout stderr &> $n-stdout-stderr.txt + node log.js 0 $n stdout &> $n-stdout.txt + node log.js 0 $n stderr &> $n-stderr.txt +done diff --git a/www/node_modules/exit/test/fixtures/log-broken.js b/www/node_modules/exit/test/fixtures/log-broken.js new file mode 100644 index 0000000..74c8f12 --- /dev/null +++ b/www/node_modules/exit/test/fixtures/log-broken.js @@ -0,0 +1,23 @@ +var errorCode = process.argv[2]; +var max = process.argv[3]; +var modes = process.argv.slice(4); + +function stdout(message) { + if (modes.indexOf('stdout') === -1) { return; } + process.stdout.write('stdout ' + message + '\n'); +} + +function stderr(message) { + if (modes.indexOf('stderr') === -1) { return; } + process.stderr.write('stderr ' + message + '\n'); +} + +for (var i = 0; i < max; i++) { + stdout(i); + stderr(i); +} + +process.exit(errorCode); + +stdout('fail'); +stderr('fail'); diff --git a/www/node_modules/exit/test/fixtures/log.js b/www/node_modules/exit/test/fixtures/log.js new file mode 100644 index 0000000..8a9ed9a --- /dev/null +++ b/www/node_modules/exit/test/fixtures/log.js @@ -0,0 +1,25 @@ +var exit = require('../../lib/exit'); + +var errorCode = process.argv[2]; +var max = process.argv[3]; +var modes = process.argv.slice(4); + +function stdout(message) { + if (modes.indexOf('stdout') === -1) { return; } + process.stdout.write('stdout ' + message + '\n'); +} + +function stderr(message) { + if (modes.indexOf('stderr') === -1) { return; } + process.stderr.write('stderr ' + message + '\n'); +} + +for (var i = 0; i < max; i++) { + stdout(i); + stderr(i); +} + +exit(errorCode); + +stdout('fail'); +stderr('fail'); diff --git a/www/node_modules/glob/LICENSE b/www/node_modules/glob/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/www/node_modules/glob/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/www/node_modules/glob/README.md b/www/node_modules/glob/README.md new file mode 100644 index 0000000..9dd9384 --- /dev/null +++ b/www/node_modules/glob/README.md @@ -0,0 +1,365 @@ +# Glob + +Match files using the patterns the shell uses, like stars and stuff. + +[![Build Status](https://travis-ci.org/isaacs/node-glob.svg?branch=master)](https://travis-ci.org/isaacs/node-glob/) [![Build Status](https://ci.appveyor.com/api/projects/status/kd7f3yftf7unxlsx?svg=true)](https://ci.appveyor.com/project/isaacs/node-glob) [![Coverage Status](https://coveralls.io/repos/isaacs/node-glob/badge.svg?branch=master&service=github)](https://coveralls.io/github/isaacs/node-glob?branch=master) + +This is a glob implementation in JavaScript. It uses the `minimatch` +library to do its matching. + +![](oh-my-glob.gif) + +## Usage + +Install with npm + +``` +npm i glob +``` + +```javascript +var glob = require("glob") + +// options is optional +glob("**/*.js", options, function (er, files) { + // files is an array of filenames. + // If the `nonull` option is set, and nothing + // was found, then files is ["**/*.js"] + // er is an error object or null. +}) +``` + +## Glob Primer + +"Globs" are the patterns you type when you do stuff like `ls *.js` on +the command line, or put `build/*` in a `.gitignore` file. + +Before parsing the path part patterns, braced sections are expanded +into a set. Braced sections start with `{` and end with `}`, with any +number of comma-delimited sections within. Braced sections may contain +slash characters, so `a{/b/c,bcd}` would expand into `a/b/c` and `abcd`. + +The following characters have special magic meaning when used in a +path portion: + +* `*` Matches 0 or more characters in a single path portion +* `?` Matches 1 character +* `[...]` Matches a range of characters, similar to a RegExp range. + If the first character of the range is `!` or `^` then it matches + any character not in the range. +* `!(pattern|pattern|pattern)` Matches anything that does not match + any of the patterns provided. +* `?(pattern|pattern|pattern)` Matches zero or one occurrence of the + patterns provided. +* `+(pattern|pattern|pattern)` Matches one or more occurrences of the + patterns provided. +* `*(a|b|c)` Matches zero or more occurrences of the patterns provided +* `@(pattern|pat*|pat?erN)` Matches exactly one of the patterns + provided +* `**` If a "globstar" is alone in a path portion, then it matches + zero or more directories and subdirectories searching for matches. + It does not crawl symlinked directories. + +### Dots + +If a file or directory path portion has a `.` as the first character, +then it will not match any glob pattern unless that pattern's +corresponding path part also has a `.` as its first character. + +For example, the pattern `a/.*/c` would match the file at `a/.b/c`. +However the pattern `a/*/c` would not, because `*` does not start with +a dot character. + +You can make glob treat dots as normal characters by setting +`dot:true` in the options. + +### Basename Matching + +If you set `matchBase:true` in the options, and the pattern has no +slashes in it, then it will seek for any file anywhere in the tree +with a matching basename. For example, `*.js` would match +`test/simple/basic.js`. + +### Empty Sets + +If no matching files are found, then an empty array is returned. This +differs from the shell, where the pattern itself is returned. For +example: + + $ echo a*s*d*f + a*s*d*f + +To get the bash-style behavior, set the `nonull:true` in the options. + +### See Also: + +* `man sh` +* `man bash` (Search for "Pattern Matching") +* `man 3 fnmatch` +* `man 5 gitignore` +* [minimatch documentation](https://github.com/isaacs/minimatch) + +## glob.hasMagic(pattern, [options]) + +Returns `true` if there are any special characters in the pattern, and +`false` otherwise. + +Note that the options affect the results. If `noext:true` is set in +the options object, then `+(a|b)` will not be considered a magic +pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}` +then that is considered magical, unless `nobrace:true` is set in the +options. + +## glob(pattern, [options], cb) + +* `pattern` `{String}` Pattern to be matched +* `options` `{Object}` +* `cb` `{Function}` + * `err` `{Error | null}` + * `matches` `{Array}` filenames found matching the pattern + +Perform an asynchronous glob search. + +## glob.sync(pattern, [options]) + +* `pattern` `{String}` Pattern to be matched +* `options` `{Object}` +* return: `{Array}` filenames found matching the pattern + +Perform a synchronous glob search. + +## Class: glob.Glob + +Create a Glob object by instantiating the `glob.Glob` class. + +```javascript +var Glob = require("glob").Glob +var mg = new Glob(pattern, options, cb) +``` + +It's an EventEmitter, and starts walking the filesystem to find matches +immediately. + +### new glob.Glob(pattern, [options], [cb]) + +* `pattern` `{String}` pattern to search for +* `options` `{Object}` +* `cb` `{Function}` Called when an error occurs, or matches are found + * `err` `{Error | null}` + * `matches` `{Array}` filenames found matching the pattern + +Note that if the `sync` flag is set in the options, then matches will +be immediately available on the `g.found` member. + +### Properties + +* `minimatch` The minimatch object that the glob uses. +* `options` The options object passed in. +* `aborted` Boolean which is set to true when calling `abort()`. There + is no way at this time to continue a glob search after aborting, but + you can re-use the statCache to avoid having to duplicate syscalls. +* `cache` Convenience object. Each field has the following possible + values: + * `false` - Path does not exist + * `true` - Path exists + * `'FILE'` - Path exists, and is not a directory + * `'DIR'` - Path exists, and is a directory + * `[file, entries, ...]` - Path exists, is a directory, and the + array value is the results of `fs.readdir` +* `statCache` Cache of `fs.stat` results, to prevent statting the same + path multiple times. +* `symlinks` A record of which paths are symbolic links, which is + relevant in resolving `**` patterns. +* `realpathCache` An optional object which is passed to `fs.realpath` + to minimize unnecessary syscalls. It is stored on the instantiated + Glob object, and may be re-used. + +### Events + +* `end` When the matching is finished, this is emitted with all the + matches found. If the `nonull` option is set, and no match was found, + then the `matches` list contains the original pattern. The matches + are sorted, unless the `nosort` flag is set. +* `match` Every time a match is found, this is emitted with the specific + thing that matched. It is not deduplicated or resolved to a realpath. +* `error` Emitted when an unexpected error is encountered, or whenever + any fs error occurs if `options.strict` is set. +* `abort` When `abort()` is called, this event is raised. + +### Methods + +* `pause` Temporarily stop the search +* `resume` Resume the search +* `abort` Stop the search forever + +### Options + +All the options that can be passed to Minimatch can also be passed to +Glob to change pattern matching behavior. Also, some have been added, +or have glob-specific ramifications. + +All options are false by default, unless otherwise noted. + +All options are added to the Glob object, as well. + +If you are running many `glob` operations, you can pass a Glob object +as the `options` argument to a subsequent operation to shortcut some +`stat` and `readdir` calls. At the very least, you may pass in shared +`symlinks`, `statCache`, `realpathCache`, and `cache` options, so that +parallel glob operations will be sped up by sharing information about +the filesystem. + +* `cwd` The current working directory in which to search. Defaults + to `process.cwd()`. +* `root` The place where patterns starting with `/` will be mounted + onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix + systems, and `C:\` or some such on Windows.) +* `dot` Include `.dot` files in normal matches and `globstar` matches. + Note that an explicit dot in a portion of the pattern will always + match dot files. +* `nomount` By default, a pattern starting with a forward-slash will be + "mounted" onto the root setting, so that a valid filesystem path is + returned. Set this flag to disable that behavior. +* `mark` Add a `/` character to directory matches. Note that this + requires additional stat calls. +* `nosort` Don't sort the results. +* `stat` Set to true to stat *all* results. This reduces performance + somewhat, and is completely unnecessary, unless `readdir` is presumed + to be an untrustworthy indicator of file existence. +* `silent` When an unusual error is encountered when attempting to + read a directory, a warning will be printed to stderr. Set the + `silent` option to true to suppress these warnings. +* `strict` When an unusual error is encountered when attempting to + read a directory, the process will just continue on in search of + other matches. Set the `strict` option to raise an error in these + cases. +* `cache` See `cache` property above. Pass in a previously generated + cache object to save some fs calls. +* `statCache` A cache of results of filesystem information, to prevent + unnecessary stat calls. While it should not normally be necessary + to set this, you may pass the statCache from one glob() call to the + options object of another, if you know that the filesystem will not + change between calls. (See "Race Conditions" below.) +* `symlinks` A cache of known symbolic links. You may pass in a + previously generated `symlinks` object to save `lstat` calls when + resolving `**` matches. +* `sync` DEPRECATED: use `glob.sync(pattern, opts)` instead. +* `nounique` In some cases, brace-expanded patterns can result in the + same file showing up multiple times in the result set. By default, + this implementation prevents duplicates in the result set. Set this + flag to disable that behavior. +* `nonull` Set to never return an empty set, instead returning a set + containing the pattern itself. This is the default in glob(3). +* `debug` Set to enable debug logging in minimatch and glob. +* `nobrace` Do not expand `{a,b}` and `{1..3}` brace sets. +* `noglobstar` Do not match `**` against multiple filenames. (Ie, + treat it as a normal `*` instead.) +* `noext` Do not match `+(a|b)` "extglob" patterns. +* `nocase` Perform a case-insensitive match. Note: on + case-insensitive filesystems, non-magic patterns will match by + default, since `stat` and `readdir` will not raise errors. +* `matchBase` Perform a basename-only match if the pattern does not + contain any slash characters. That is, `*.js` would be treated as + equivalent to `**/*.js`, matching all js files in all directories. +* `nodir` Do not match directories, only files. (Note: to match + *only* directories, simply put a `/` at the end of the pattern.) +* `ignore` Add a pattern or an array of glob patterns to exclude matches. + Note: `ignore` patterns are *always* in `dot:true` mode, regardless + of any other settings. +* `follow` Follow symlinked directories when expanding `**` patterns. + Note that this can result in a lot of duplicate references in the + presence of cyclic links. +* `realpath` Set to true to call `fs.realpath` on all of the results. + In the case of a symlink that cannot be resolved, the full absolute + path to the matched entry is returned (though it will usually be a + broken symlink) + +## Comparisons to other fnmatch/glob implementations + +While strict compliance with the existing standards is a worthwhile +goal, some discrepancies exist between node-glob and other +implementations, and are intentional. + +The double-star character `**` is supported by default, unless the +`noglobstar` flag is set. This is supported in the manner of bsdglob +and bash 4.3, where `**` only has special significance if it is the only +thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but +`a/**b` will not. + +Note that symlinked directories are not crawled as part of a `**`, +though their contents may match against subsequent portions of the +pattern. This prevents infinite loops and duplicates and the like. + +If an escaped pattern has no matches, and the `nonull` flag is set, +then glob returns the pattern as-provided, rather than +interpreting the character escapes. For example, +`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than +`"*a?"`. This is akin to setting the `nullglob` option in bash, except +that it does not resolve escaped pattern characters. + +If brace expansion is not disabled, then it is performed before any +other interpretation of the glob pattern. Thus, a pattern like +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are +checked for validity. Since those two are valid, matching proceeds. + +### Comments and Negation + +Previously, this module let you mark a pattern as a "comment" if it +started with a `#` character, or a "negated" pattern if it started +with a `!` character. + +These options were deprecated in version 5, and removed in version 6. + +To specify things that should not match, use the `ignore` option. + +## Windows + +**Please only use forward-slashes in glob expressions.** + +Though windows uses either `/` or `\` as its path separator, only `/` +characters are used by this glob implementation. You must use +forward-slashes **only** in glob expressions. Back-slashes will always +be interpreted as escape characters, not path separators. + +Results from absolute patterns such as `/foo/*` are mounted onto the +root setting using `path.join`. On windows, this will by default result +in `/foo/*` matching `C:\foo\bar.txt`. + +## Race Conditions + +Glob searching, by its very nature, is susceptible to race conditions, +since it relies on directory walking and such. + +As a result, it is possible that a file that exists when glob looks for +it may have been deleted or modified by the time it returns the result. + +As part of its internal implementation, this program caches all stat +and readdir calls that it makes, in order to cut down on system +overhead. However, this also makes it even more susceptible to races, +especially if the cache or statCache objects are reused between glob +calls. + +Users are thus advised not to use a glob result as a guarantee of +filesystem state in the face of rapid changes. For the vast majority +of operations, this is never a problem. + +## Contributing + +Any change to behavior (including bugfixes) must come with a test. + +Patches that fail tests or reduce performance will be rejected. + +``` +# to run tests +npm test + +# to re-generate test fixtures +npm run test-regen + +# to benchmark against bash/zsh +npm run bench + +# to profile javascript +npm run prof +``` diff --git a/www/node_modules/glob/changelog.md b/www/node_modules/glob/changelog.md new file mode 100644 index 0000000..4163677 --- /dev/null +++ b/www/node_modules/glob/changelog.md @@ -0,0 +1,67 @@ +## 7.0 + +- Raise error if `options.cwd` is specified, and not a directory + +## 6.0 + +- Remove comment and negation pattern support +- Ignore patterns are always in `dot:true` mode + +## 5.0 + +- Deprecate comment and negation patterns +- Fix regression in `mark` and `nodir` options from making all cache + keys absolute path. +- Abort if `fs.readdir` returns an error that's unexpected +- Don't emit `match` events for ignored items +- Treat ENOTSUP like ENOTDIR in readdir + +## 4.5 + +- Add `options.follow` to always follow directory symlinks in globstar +- Add `options.realpath` to call `fs.realpath` on all results +- Always cache based on absolute path + +## 4.4 + +- Add `options.ignore` +- Fix handling of broken symlinks + +## 4.3 + +- Bump minimatch to 2.x +- Pass all tests on Windows + +## 4.2 + +- Add `glob.hasMagic` function +- Add `options.nodir` flag + +## 4.1 + +- Refactor sync and async implementations for performance +- Throw if callback provided to sync glob function +- Treat symbolic links in globstar results the same as Bash 4.3 + +## 4.0 + +- Use `^` for dependency versions (bumped major because this breaks + older npm versions) +- Ensure callbacks are only ever called once +- switch to ISC license + +## 3.x + +- Rewrite in JavaScript +- Add support for setting root, cwd, and windows support +- Cache many fs calls +- Add globstar support +- emit match events + +## 2.x + +- Use `glob.h` and `fnmatch.h` from NetBSD + +## 1.x + +- `glob.h` static binding. diff --git a/www/node_modules/glob/common.js b/www/node_modules/glob/common.js new file mode 100644 index 0000000..58dc41e --- /dev/null +++ b/www/node_modules/glob/common.js @@ -0,0 +1,235 @@ +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } + + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = path.resolve(options.cwd) + self.changedCwd = self.cwd !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + self.cwdAbs = makeAbs(self, self.cwd) + self.nomount = !!options.nomount + + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + var notDir = !(/\/$/.test(e)) + var c = self.cache[e] || self.cache[makeAbs(self, e)] + if (notDir && c) + notDir = c !== 'DIR' && !Array.isArray(c) + return notDir + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + + if (process.platform === 'win32') + abs = abs.replace(/\\/g, '/') + + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} diff --git a/www/node_modules/glob/glob.js b/www/node_modules/glob/glob.js new file mode 100644 index 0000000..4dba04a --- /dev/null +++ b/www/node_modules/glob/glob.js @@ -0,0 +1,782 @@ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin + } + + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin +} + +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + var n = this.minimatch.set.length + this._processing = 0 + this.matches = new Array(n) + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + var sync = true + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + sync = false + + function done () { + --self._processing + if (self._processing <= 0) { + if (sync) { + process.nextTick(function () { + self._finish() + }) + } else { + self._finish() + } + } + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + fs.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (this.matches[index][e]) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = this._makeAbs(e) + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + if (this.mark) + e = this._mark(e) + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er) + return cb() + + var isSym = lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + this.emit('error', error) + this.abort() + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && !stat.isDirectory()) + return cb(null, false, stat) + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return cb() + + return cb(null, c, stat) +} diff --git a/www/node_modules/glob/package.json b/www/node_modules/glob/package.json new file mode 100644 index 0000000..3638792 --- /dev/null +++ b/www/node_modules/glob/package.json @@ -0,0 +1,102 @@ +{ + "_args": [ + [ + "glob@^7.0.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/rimraf" + ] + ], + "_from": "glob@>=7.0.0 <8.0.0", + "_id": "glob@7.0.3", + "_inCache": true, + "_installable": true, + "_location": "/glob", + "_nodeVersion": "5.6.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/glob-7.0.3.tgz_1457166529288_0.7840580905321985" + }, + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "3.7.3", + "_phantomChildren": {}, + "_requested": { + "name": "glob", + "raw": "glob@^7.0.0", + "rawSpec": "^7.0.0", + "scope": null, + "spec": ">=7.0.0 <8.0.0", + "type": "range" + }, + "_requiredBy": [ + "/rimraf" + ], + "_resolved": "https://registry.npmjs.org/glob/-/glob-7.0.3.tgz", + "_shasum": "0aa235931a4a96ac13d60ffac2fb877bd6ed4f58", + "_shrinkwrap": null, + "_spec": "glob@^7.0.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/rimraf", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/node-glob/issues" + }, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "description": "a little globber", + "devDependencies": { + "mkdirp": "0", + "rimraf": "^2.2.8", + "tap": "^5.7.0", + "tick": "0.0.6" + }, + "directories": {}, + "dist": { + "shasum": "0aa235931a4a96ac13d60ffac2fb877bd6ed4f58", + "tarball": "http://registry.npmjs.org/glob/-/glob-7.0.3.tgz" + }, + "engines": { + "node": "*" + }, + "files": [ + "glob.js", + "sync.js", + "common.js" + ], + "gitHead": "2fc2278ab857c7df117213a2fb431de090be6353", + "homepage": "https://github.com/isaacs/node-glob#readme", + "license": "ISC", + "main": "glob.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "glob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "scripts": { + "bench": "bash benchmark.sh", + "benchclean": "node benchclean.js", + "prepublish": "npm run benchclean", + "prof": "bash prof.sh && cat profile.txt", + "profclean": "rm -f v8.log profile.txt", + "test": "tap test/*.js --cov", + "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js" + }, + "version": "7.0.3" +} diff --git a/www/node_modules/glob/sync.js b/www/node_modules/glob/sync.js new file mode 100644 index 0000000..301577a --- /dev/null +++ b/www/node_modules/glob/sync.js @@ -0,0 +1,467 @@ +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = fs.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this.matches[index][e] = true + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + var abs = this._makeAbs(e) + if (this.mark) + e = this._mark(e) + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[this._makeAbs(e)] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + // lstat failed, doesn't exist + return null + } + + var isSym = lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + throw error + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this.matches[index][prefix] = true +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + return false + } + + if (lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} diff --git a/www/node_modules/inflight/.eslintrc b/www/node_modules/inflight/.eslintrc new file mode 100644 index 0000000..b7a1550 --- /dev/null +++ b/www/node_modules/inflight/.eslintrc @@ -0,0 +1,17 @@ +{ + "env" : { + "node" : true + }, + "rules" : { + "semi": [2, "never"], + "strict": 0, + "quotes": [1, "single", "avoid-escape"], + "no-use-before-define": 0, + "curly": 0, + "no-underscore-dangle": 0, + "no-lonely-if": 1, + "no-unused-vars": [2, {"vars" : "all", "args" : "after-used"}], + "no-mixed-requires": 0, + "space-infix-ops": 0 + } +} diff --git a/www/node_modules/inflight/LICENSE b/www/node_modules/inflight/LICENSE new file mode 100644 index 0000000..05eeeb8 --- /dev/null +++ b/www/node_modules/inflight/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/www/node_modules/inflight/README.md b/www/node_modules/inflight/README.md new file mode 100644 index 0000000..6dc8929 --- /dev/null +++ b/www/node_modules/inflight/README.md @@ -0,0 +1,37 @@ +# inflight + +Add callbacks to requests in flight to avoid async duplication + +## USAGE + +```javascript +var inflight = require('inflight') + +// some request that does some stuff +function req(key, callback) { + // key is any random string. like a url or filename or whatever. + // + // will return either a falsey value, indicating that the + // request for this key is already in flight, or a new callback + // which when called will call all callbacks passed to inflightk + // with the same key + callback = inflight(key, callback) + + // If we got a falsey value back, then there's already a req going + if (!callback) return + + // this is where you'd fetch the url or whatever + // callback is also once()-ified, so it can safely be assigned + // to multiple events etc. First call wins. + setTimeout(function() { + callback(null, key) + }, 100) +} + +// only assigns a single setTimeout +// when it dings, all cbs get called +req('foo', cb1) +req('foo', cb2) +req('foo', cb3) +req('foo', cb4) +``` diff --git a/www/node_modules/inflight/inflight.js b/www/node_modules/inflight/inflight.js new file mode 100644 index 0000000..8bc96cb --- /dev/null +++ b/www/node_modules/inflight/inflight.js @@ -0,0 +1,44 @@ +var wrappy = require('wrappy') +var reqs = Object.create(null) +var once = require('once') + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} diff --git a/www/node_modules/inflight/package.json b/www/node_modules/inflight/package.json new file mode 100644 index 0000000..90db3b2 --- /dev/null +++ b/www/node_modules/inflight/package.json @@ -0,0 +1,86 @@ +{ + "_args": [ + [ + "inflight@^1.0.4", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/glob" + ] + ], + "_from": "inflight@>=1.0.4 <2.0.0", + "_id": "inflight@1.0.4", + "_inCache": true, + "_installable": true, + "_location": "/inflight", + "_nodeVersion": "0.10.32", + "_npmUser": { + "email": "ogd@aoaioxxysz.net", + "name": "othiym23" + }, + "_npmVersion": "2.1.3", + "_phantomChildren": {}, + "_requested": { + "name": "inflight", + "raw": "inflight@^1.0.4", + "rawSpec": "^1.0.4", + "scope": null, + "spec": ">=1.0.4 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob" + ], + "_resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", + "_shasum": "6cbb4521ebd51ce0ec0a936bfd7657ef7e9b172a", + "_shrinkwrap": null, + "_spec": "inflight@^1.0.4", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/glob", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/inflight/issues" + }, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + }, + "description": "Add callbacks to requests in flight to avoid async duplication", + "devDependencies": { + "tap": "^0.4.10" + }, + "directories": {}, + "dist": { + "shasum": "6cbb4521ebd51ce0ec0a936bfd7657ef7e9b172a", + "tarball": "http://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz" + }, + "gitHead": "c7b5531d572a867064d4a1da9e013e8910b7d1ba", + "homepage": "https://github.com/isaacs/inflight", + "license": "ISC", + "main": "inflight.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + }, + { + "email": "ogd@aoaioxxysz.net", + "name": "othiym23" + }, + { + "email": "me@re-becca.org", + "name": "iarna" + } + ], + "name": "inflight", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/inflight.git" + }, + "scripts": { + "test": "tap test.js" + }, + "version": "1.0.4" +} diff --git a/www/node_modules/inflight/test.js b/www/node_modules/inflight/test.js new file mode 100644 index 0000000..2bb75b3 --- /dev/null +++ b/www/node_modules/inflight/test.js @@ -0,0 +1,97 @@ +var test = require('tap').test +var inf = require('./inflight.js') + + +function req (key, cb) { + cb = inf(key, cb) + if (cb) setTimeout(function () { + cb(key) + cb(key) + }) + return cb +} + +test('basic', function (t) { + var calleda = false + var a = req('key', function (k) { + t.notOk(calleda) + calleda = true + t.equal(k, 'key') + if (calledb) t.end() + }) + t.ok(a, 'first returned cb function') + + var calledb = false + var b = req('key', function (k) { + t.notOk(calledb) + calledb = true + t.equal(k, 'key') + if (calleda) t.end() + }) + + t.notOk(b, 'second should get falsey inflight response') +}) + +test('timing', function (t) { + var expect = [ + 'method one', + 'start one', + 'end one', + 'two', + 'tick', + 'three' + ] + var i = 0 + + function log (m) { + t.equal(m, expect[i], m + ' === ' + expect[i]) + ++i + if (i === expect.length) + t.end() + } + + function method (name, cb) { + log('method ' + name) + process.nextTick(cb) + } + + var one = inf('foo', function () { + log('start one') + var three = inf('foo', function () { + log('three') + }) + if (three) method('three', three) + log('end one') + }) + + method('one', one) + + var two = inf('foo', function () { + log('two') + }) + if (two) method('one', two) + + process.nextTick(log.bind(null, 'tick')) +}) + +test('parameters', function (t) { + t.plan(8) + + var a = inf('key', function (first, second, third) { + t.equal(first, 1) + t.equal(second, 2) + t.equal(third, 3) + }) + t.ok(a, 'first returned cb function') + + var b = inf('key', function (first, second, third) { + t.equal(first, 1) + t.equal(second, 2) + t.equal(third, 3) + }) + t.notOk(b, 'second should get falsey inflight response') + + setTimeout(function () { + a(1, 2, 3) + }) +}) diff --git a/www/node_modules/inherits/LICENSE b/www/node_modules/inherits/LICENSE new file mode 100644 index 0000000..dea3013 --- /dev/null +++ b/www/node_modules/inherits/LICENSE @@ -0,0 +1,16 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/www/node_modules/inherits/README.md b/www/node_modules/inherits/README.md new file mode 100644 index 0000000..b1c5665 --- /dev/null +++ b/www/node_modules/inherits/README.md @@ -0,0 +1,42 @@ +Browser-friendly inheritance fully compatible with standard node.js +[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). + +This package exports standard `inherits` from node.js `util` module in +node environment, but also provides alternative browser-friendly +implementation through [browser +field](https://gist.github.com/shtylman/4339901). Alternative +implementation is a literal copy of standard one located in standalone +module to avoid requiring of `util`. It also has a shim for old +browsers with no `Object.create` support. + +While keeping you sure you are using standard `inherits` +implementation in node.js environment, it allows bundlers such as +[browserify](https://github.com/substack/node-browserify) to not +include full `util` package to your client code if all you need is +just `inherits` function. It worth, because browser shim for `util` +package is large and `inherits` is often the single function you need +from it. + +It's recommended to use this package instead of +`require('util').inherits` for any code that has chances to be used +not only in node.js but in browser too. + +## usage + +```js +var inherits = require('inherits'); +// then use exactly as the standard one +``` + +## note on version ~1.0 + +Version ~1.0 had completely different motivation and is not compatible +neither with 2.0 nor with standard node.js `inherits`. + +If you are using version ~1.0 and planning to switch to ~2.0, be +careful: + +* new version uses `super_` instead of `super` for referencing + superclass +* new version overwrites current prototype while old one preserves any + existing fields on it diff --git a/www/node_modules/inherits/inherits.js b/www/node_modules/inherits/inherits.js new file mode 100644 index 0000000..29f5e24 --- /dev/null +++ b/www/node_modules/inherits/inherits.js @@ -0,0 +1 @@ +module.exports = require('util').inherits diff --git a/www/node_modules/inherits/inherits_browser.js b/www/node_modules/inherits/inherits_browser.js new file mode 100644 index 0000000..c1e78a7 --- /dev/null +++ b/www/node_modules/inherits/inherits_browser.js @@ -0,0 +1,23 @@ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} diff --git a/www/node_modules/inherits/package.json b/www/node_modules/inherits/package.json new file mode 100644 index 0000000..722bcd1 --- /dev/null +++ b/www/node_modules/inherits/package.json @@ -0,0 +1,77 @@ +{ + "_args": [ + [ + "inherits@2", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/glob" + ] + ], + "_from": "inherits@>=2.0.0 <3.0.0", + "_id": "inherits@2.0.1", + "_inCache": true, + "_installable": true, + "_location": "/inherits", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "1.3.8", + "_phantomChildren": {}, + "_requested": { + "name": "inherits", + "raw": "inherits@2", + "rawSpec": "2", + "scope": null, + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob" + ], + "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "_shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", + "_shrinkwrap": null, + "_spec": "inherits@2", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/glob", + "browser": "./inherits_browser.js", + "bugs": { + "url": "https://github.com/isaacs/inherits/issues" + }, + "dependencies": {}, + "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "b17d08d326b4423e568eff719f91b0b1cbdf69f1", + "tarball": "http://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "homepage": "https://github.com/isaacs/inherits#readme", + "keywords": [ + "inheritance", + "class", + "klass", + "oop", + "object-oriented", + "inherits", + "browser", + "browserify" + ], + "license": "ISC", + "main": "./inherits.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "inherits", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/inherits.git" + }, + "scripts": { + "test": "node test" + }, + "version": "2.0.1" +} diff --git a/www/node_modules/inherits/test.js b/www/node_modules/inherits/test.js new file mode 100644 index 0000000..fc53012 --- /dev/null +++ b/www/node_modules/inherits/test.js @@ -0,0 +1,25 @@ +var inherits = require('./inherits.js') +var assert = require('assert') + +function test(c) { + assert(c.constructor === Child) + assert(c.constructor.super_ === Parent) + assert(Object.getPrototypeOf(c) === Child.prototype) + assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype) + assert(c instanceof Child) + assert(c instanceof Parent) +} + +function Child() { + Parent.call(this) + test(this) +} + +function Parent() {} + +inherits(Child, Parent) + +var c = new Child +test(c) + +console.log('ok') diff --git a/www/node_modules/jasmine-core/.npmignore b/www/node_modules/jasmine-core/.npmignore new file mode 100644 index 0000000..82d86f3 --- /dev/null +++ b/www/node_modules/jasmine-core/.npmignore @@ -0,0 +1,28 @@ +dist/ +grunt/ +node_modules +pkg/ +release_notes/ +spec/ +src/ +Gemfile +Gemfile.lock +Rakefile +jasmine-core.gemspec +.bundle/ +.gitignore +.gitmodules +.idea +.jshintrc +.rspec +.sass-cache/ +.travis.yml +*.sh +*.py +Gruntfile.js +lib/jasmine-core.rb +lib/jasmine-core/boot/ +lib/jasmine-core/spec +lib/jasmine-core/version.rb +lib/jasmine-core/*.py +sauce_connect.log diff --git a/www/node_modules/jasmine-core/CONTRIBUTING.md b/www/node_modules/jasmine-core/CONTRIBUTING.md new file mode 100644 index 0000000..8d990ff --- /dev/null +++ b/www/node_modules/jasmine-core/CONTRIBUTING.md @@ -0,0 +1,130 @@ +# Developing for Jasmine Core + +We welcome your contributions! Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists before starting work. What you're looking for may already have been done. If it hasn't, the community can help make your contribution better. If you want to contribute but don't know what to work on, [issues tagged ready for work](https://github.com/jasmine/jasmine/labels/ready%20for%20work) should have enough detail to get started. + +## Links + +- [Jasmine Google Group](http://groups.google.com/group/jasmine-js) +- [Jasmine-dev Google Group](http://groups.google.com/group/jasmine-js-dev) +- [Jasmine on PivotalTracker](https://www.pivotaltracker.com/n/projects/10606) + +## General Workflow + +Please submit pull requests via feature branches using the semi-standard workflow of: + +```bash +git clone git@github.com:yourUserName/jasmine.git # Clone your fork +cd jasmine # Change directory +git remote add upstream https://github.com/jasmine/jasmine.git # Assign original repository to a remote named 'upstream' +git fetch upstream # Pull in changes not present in your local repository +git checkout -b my-new-feature # Create your feature branch +git commit -am 'Add some feature' # Commit your changes +git push origin my-new-feature # Push to the branch +``` + +Once you've pushed a feature branch to your forked repo, you're ready to open a pull request. We favor pull requests with very small, single commits with a single purpose. + +## Background + +### Directory Structure + +* `/src` contains all of the source files + * `/src/console` - Node.js-specific files + * `/src/core` - generic source files + * `/src/html` - browser-specific files +* `/spec` contains all of the tests + * mirrors the source directory + * there are some additional files +* `/dist` contains the standalone distributions as zip files +* `/lib` contains the generated files for distribution as the Jasmine Rubygem and the Python package + +### Self-testing + +Note that Jasmine tests itself. The files in `lib` are loaded first, defining the reference `jasmine`. Then the files in `src` are loaded, defining the reference `j$`. So there are two copies of the code loaded under test. + +The tests should always use `j$` to refer to the objects and functions that are being tested. But the tests can use functions on `jasmine` as needed. _Be careful how you structure any new test code_. Copy the patterns you see in the existing code - this ensures that the code you're testing is not leaking into the `jasmine` reference and vice-versa. + +### `boot.js` + +__This is new for Jasmine 2.0.__ + +This file does all of the setup necessary for Jasmine to work. It loads all of the code, creates an `Env`, attaches the global functions, and builds the reporter. It also sets up the execution of the `Env` - for browsers this is in `window.onload`. While the default in `lib` is appropriate for browsers, projects may wish to customize this file. + +For example, for Jasmine development there is a different `dev_boot.js` for Jasmine development that does more work. + +### Compatibility + +* Browser Minimum + * IE8 + * Firefox 3.x + * Chrome ?? + * Safari 5 + +## Development + +All source code belongs in `src/`. The `core/` directory contains the bulk of Jasmine's functionality. This code should remain browser- and environment-agnostic. If your feature or fix cannot be, as mentioned above, please degrade gracefully. Any code that should only be in a non-browser environment should live in `src/console/`. Any code that depends on a browser (specifically, it expects `window` to be the global or `document` is present) should live in `src/html/`. + +### Install Dependencies + +Jasmine Core relies on Ruby and Node.js. + +To install the Ruby dependencies, you will need Ruby, Rubygems, and Bundler available. Then: + + $ bundle + +...will install all of the Ruby dependencies. If the ffi gem fails to build its native extensions, you may need to manually install some system dependencies. On Ubuntu: + + $ apt-get install gcc ruby ruby-dev libxml2 libxml2-dev libxslt1-dev + +...should get you to the point that `bundle` can install everything. + +To install the Node dependencies, you will need Node.js, Npm, and [Grunt](http://gruntjs.com/), the [grunt-cli](https://github.com/gruntjs/grunt-cli) and ensure that `grunt` is on your path. + + $ npm install --local + +...will install all of the node modules locally. Now run + + $ grunt + +...if you see that JSHint runs, your system is ready. + +### How to write new Jasmine code + +Or, How to make a successful pull request + +* _Do not change the public interface_. Lots of projects depend on Jasmine and if you aren't careful you'll break them +* _Be environment agnostic_ - server-side developers are just as important as browser developers +* _Be browser agnostic_ - if you must rely on browser-specific functionality, please write it in a way that degrades gracefully +* _Write specs_ - Jasmine's a testing framework; don't add functionality without test-driving it +* _Write code in the style of the rest of the repo_ - Jasmine should look like a cohesive whole +* _Ensure the *entire* test suite is green_ in all the big browsers, Node, and JSHint - your contribution shouldn't break Jasmine for other users + +Follow these tips and your pull request, patch, or suggestion is much more likely to be integrated. + +### Running Specs + +Jasmine uses the [Jasmine Ruby gem](http://github.com/jasmine/jasmine-gem) to test itself in browser. + + $ bundle exec rake jasmine + +...and then visit `http://localhost:8888` to run specs. + +Jasmine uses the [Jasmine NPM package](http://github.com/jasmine/jasmine-npm) to test itself in a Node.js/npm environment. + + $ grunt execSpecsInNode + +...and then the results will print to the console. All specs run except those that expect a browser (the specs in `spec/html` are ignored). + +## Before Committing or Submitting a Pull Request + +1. Ensure all specs are green in browser *and* node +1. Ensure JSHint is green with `grunt jshint` +1. Build `jasmine.js` with `grunt buildDistribution` and run all specs again - this ensures that your changes self-test well + +## Submitting a Pull Request +1. Revert your changes to `jasmine.js` and `jasmine-html.js` + * We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches +1. When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into master + +Note that we use Travis for Continuous Integration. We only accept green pull requests. + diff --git a/www/node_modules/jasmine-core/MANIFEST.in b/www/node_modules/jasmine-core/MANIFEST.in new file mode 100644 index 0000000..4d58eed --- /dev/null +++ b/www/node_modules/jasmine-core/MANIFEST.in @@ -0,0 +1,5 @@ +recursive-include . *.py +include lib/jasmine-core/*.js +include lib/jasmine-core/*.css +include images/*.png +include package.json diff --git a/www/node_modules/jasmine-core/MIT.LICENSE b/www/node_modules/jasmine-core/MIT.LICENSE new file mode 100644 index 0000000..aff8ed4 --- /dev/null +++ b/www/node_modules/jasmine-core/MIT.LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008-2014 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/www/node_modules/jasmine-core/README.md b/www/node_modules/jasmine-core/README.md new file mode 100644 index 0000000..74d90d4 --- /dev/null +++ b/www/node_modules/jasmine-core/README.md @@ -0,0 +1,76 @@ +[](http://jasmine.github.io) + +[![Build Status](https://travis-ci.org/jasmine/jasmine.svg?branch=master)](https://travis-ci.org/jasmine/jasmine) +[![Code Climate](https://codeclimate.com/github/pivotal/jasmine.svg)](https://codeclimate.com/github/pivotal/jasmine) + +======= + +**A JavaScript Testing Framework** + +Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, [Node.js](http://nodejs.org) projects, or anywhere that JavaScript can run. + +Documentation & guides live here: [http://jasmine.github.io](http://jasmine.github.io/) +For a quick start guide of Jasmine 2.0, see the beginning of [http://jasmine.github.io/2.0/introduction.html](http://jasmine.github.io/2.0/introduction.html) + +Upgrading from Jasmine 1.x? Check out the [2.0 release notes](https://github.com/jasmine/jasmine/blob/v2.0.0/release_notes/20.md) for a list of what's new (including breaking interface changes). You can also read the [upgrade guide](http://jasmine.github.io/2.0/upgrading.html). + +## Contributing + +Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/master/CONTRIBUTING.md) + +## Installation + +For the Jasmine NPM module:
    +[https://github.com/jasmine/jasmine-npm](https://github.com/jasmine/jasmine-npm) + +For the Jasmine Ruby Gem:
    +[https://github.com/jasmine/jasmine-gem](https://github.com/jasmine/jasmine-gem) + +For the Jasmine Python Egg:
    +[https://github.com/jasmine/jasmine-py](https://github.com/jasmine/jasmine-py) + +To install Jasmine standalone on your local box: + +* Download the standalone distribution for your desired release from the [releases page](https://github.com/jasmine/jasmine/releases) +* Create a Jasmine directory in your project - `mkdir my-project/jasmine` +* Move the dist to your project directory - `mv jasmine/dist/jasmine-standalone-2.0.0.zip my-project/jasmine` +* Change directory - `cd my-project/jasmine` +* Unzip the dist - `unzip jasmine-standalone-2.0.0.zip` + +Add the following to your HTML file: + +```html + + + + + + +``` + +## Supported environments + +Jasmine tests itself across many browsers (Safari, Chrome, Firefox, PhantomJS, and new Internet Explorer) as well as node. To see the exact version tests are run against look at our [.travis.yml](https://github.com/jasmine/jasmine/blob/master/.travis.yml) + + +## Support + +* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js) +* Send an email to the list: [jasmine-js@googlegroups.com](mailto:jasmine-js@googlegroups.com) +* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606) +* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD) + +## Maintainers + +* [Davis W. Frank](mailto:dwfrank@pivotal.io), Pivotal Labs +* [Rajan Agaskar](mailto:rajan@pivotal.io), Pivotal Labs +* [Gregg Van Hove](mailto:gvanhove@pivotal.io), Pivotal Labs +* [Greg Cobb](mailto:gcobb@pivotal.io), Pivotal Labs +* [Chris Amavisca](mailto:camavisca@pivotal.io), Pivotal Labs + +### Maintainers Emeritus + +* [Christian Williams](mailto:antixian666@gmail.com), Cloud Foundry +* Sheel Choksi + +Copyright (c) 2008-2015 Pivotal Labs. This software is licensed under the MIT License. diff --git a/www/node_modules/jasmine-core/RELEASE.md b/www/node_modules/jasmine-core/RELEASE.md new file mode 100644 index 0000000..e5273b0 --- /dev/null +++ b/www/node_modules/jasmine-core/RELEASE.md @@ -0,0 +1,73 @@ +# How to work on a Jasmine Release + +## Development +___Jasmine Core Maintainers Only___ + +Follow the instructions in `CONTRIBUTING.md` during development. + +### Git Rules + +Please work on feature branches. + +Please attempt to keep commits to `master` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits or small work), please squash them when merging back to `master`. + +### Version + +We attempt to stick to [Semantic Versioning](http://semver.org/). Most of the time, development should be against a new minor version - fixing bugs and adding new features that are backwards compatible. + +The current version lives in the file `/package.json`. This version will be the version number that is currently released. When releasing a new version, update `package.json` with the new version and `grunt build:copyVersionToGem` to update the gem version number. + +This version is used by both `jasmine.js` and the `jasmine-core` Ruby gem. + +Note that Jasmine should only use the "patch" version number in the following cases: + +* Changes related to packaging for a specific platform (npm, gem, or pip). +* Fixes for regressions. + +When jasmine-core revs its major or minor version, the binding libraries should also rev to that version. + +## Release + +When ready to release - specs are all green and the stories are done: + +1. Update the release notes in `release_notes` - use the Anchorman gem to generate the markdown file and edit accordingly +1. Update the version in `package.json` to a release candidate +1. Update any links or top-level landing page for the Github Pages + +### Build standalone distribution + +1. Build the standalone distribution with `grunt buildStandaloneDist` + +### Release the Python egg + +1. `python setup.py register sdist upload` You will need pypi credentials to upload the egg. + +### Release the Ruby gem + +1. Copy version to the Ruby gem with `grunt build:copyVersionToGem` +1. __NOTE__: You will likely need to point to a local jasmine gem in order to run tests locally. _Do not_ push this version of the Gemfile. +1. __NOTE__: You will likely need to push a new jasmine gem with a dependent version right after this release. +1. Push these changes to GitHub and verify that this SHA is green +1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org. In order to release you will have to ensure you have rubygems creds locally. + +### Release the NPM + +1. `npm adduser` to save your credentials locally +1. `npm publish .` to publish what's in `package.json` + +### Release the docs + +Probably only need to do this when releasing a minor version, and not a patch version. + +1. `cp -R edge ${version}` to copy the current edge docs to the new version +1. Add a link to the new version in `index.html` + +### Finally + +1. Visit the [Releases page for Jasmine](https://github.com/jasmine/jasmine/releases), find the tag just pushed. + 1. Paste in a link to the correct release notes for this release. The link should reference the blob and tag correctly, and the markdown file for the notes. + 1. If it is a pre-release, mark it as such. + 1. Attach the standalone zipfile + + +There should be a post to Pivotal Labs blog and a tweet to that link. diff --git a/www/node_modules/jasmine-core/bower.json b/www/node_modules/jasmine-core/bower.json new file mode 100644 index 0000000..c69673f --- /dev/null +++ b/www/node_modules/jasmine-core/bower.json @@ -0,0 +1,40 @@ +{ + "name": "jasmine-core", + "homepage": "http://jasmine.github.io", + "authors": [ + "slackersoft " + ], + "description": "Official packaging of Jasmine's core files", + "keywords": [ + "test", + "jasmine", + "tdd", + "bdd" + ], + "license": "MIT", + "moduleType": "globals", + "main": "lib/jasmine-core/jasmine.js", + "ignore": [ + "**/.*", + "dist", + "grunt", + "node_modules", + "pkg", + "release_notes", + "spec", + "src", + "Gemfile", + "Gemfile.lock", + "Rakefile", + "jasmine-core.gemspec", + "*.sh", + "*.py", + "Gruntfile.js", + "lib/jasmine-core.rb", + "lib/jasmine-core/boot/", + "lib/jasmine-core/spec", + "lib/jasmine-core/version.rb", + "lib/jasmine-core/*.py", + "sauce_connect.log" + ] +} diff --git a/www/node_modules/jasmine-core/images/jasmine-horizontal.png b/www/node_modules/jasmine-core/images/jasmine-horizontal.png new file mode 100644 index 0000000..ca287ff Binary files /dev/null and b/www/node_modules/jasmine-core/images/jasmine-horizontal.png differ diff --git a/www/node_modules/jasmine-core/images/jasmine-horizontal.svg b/www/node_modules/jasmine-core/images/jasmine-horizontal.svg new file mode 100644 index 0000000..ba8990e --- /dev/null +++ b/www/node_modules/jasmine-core/images/jasmine-horizontal.svg @@ -0,0 +1,102 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/www/node_modules/jasmine-core/images/jasmine_favicon.png b/www/node_modules/jasmine-core/images/jasmine_favicon.png new file mode 100644 index 0000000..3b84583 Binary files /dev/null and b/www/node_modules/jasmine-core/images/jasmine_favicon.png differ diff --git a/www/node_modules/jasmine-core/jasmine_core.egg-info/PKG-INFO b/www/node_modules/jasmine-core/jasmine_core.egg-info/PKG-INFO new file mode 100644 index 0000000..fe5901a --- /dev/null +++ b/www/node_modules/jasmine-core/jasmine_core.egg-info/PKG-INFO @@ -0,0 +1,30 @@ +Metadata-Version: 1.1 +Name: jasmine-core +Version: 2.2.1 +Summary: Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, Node.js (http://nodejs.org) projects, or anywhere that JavaScript can run. +Home-page: http://jasmine.github.io +Author: Pivotal Labs +Author-email: jasmine-js@googlegroups.com +License: MIT +Description: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Environment :: Web Environment +Classifier: Framework :: Django +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Build Tools +Classifier: Topic :: Software Development :: Quality Assurance +Classifier: Topic :: Software Development :: Testing diff --git a/www/node_modules/jasmine-core/jasmine_core.egg-info/SOURCES.txt b/www/node_modules/jasmine-core/jasmine_core.egg-info/SOURCES.txt new file mode 100644 index 0000000..cf3dcc8 --- /dev/null +++ b/www/node_modules/jasmine-core/jasmine_core.egg-info/SOURCES.txt @@ -0,0 +1,18 @@ +MANIFEST.in +package.json +images/__init__.py +images/jasmine-horizontal.png +images/jasmine_favicon.png +jasmine_core.egg-info/PKG-INFO +jasmine_core.egg-info/SOURCES.txt +jasmine_core.egg-info/dependency_links.txt +jasmine_core.egg-info/requires.txt +jasmine_core.egg-info/top_level.txt +lib/jasmine-core/__init__.py +lib/jasmine-core/boot.js +lib/jasmine-core/core.py +lib/jasmine-core/jasmine-html.js +lib/jasmine-core/jasmine.css +lib/jasmine-core/jasmine.js +lib/jasmine-core/json2.js +lib/jasmine-core/node_boot.js \ No newline at end of file diff --git a/www/node_modules/jasmine-core/jasmine_core.egg-info/dependency_links.txt b/www/node_modules/jasmine-core/jasmine_core.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/www/node_modules/jasmine-core/jasmine_core.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/www/node_modules/jasmine-core/jasmine_core.egg-info/requires.txt b/www/node_modules/jasmine-core/jasmine_core.egg-info/requires.txt new file mode 100644 index 0000000..119bcbe --- /dev/null +++ b/www/node_modules/jasmine-core/jasmine_core.egg-info/requires.txt @@ -0,0 +1,2 @@ +glob2>=0.4.1 +ordereddict==1.1 diff --git a/www/node_modules/jasmine-core/jasmine_core.egg-info/top_level.txt b/www/node_modules/jasmine-core/jasmine_core.egg-info/top_level.txt new file mode 100644 index 0000000..fb7d8b2 --- /dev/null +++ b/www/node_modules/jasmine-core/jasmine_core.egg-info/top_level.txt @@ -0,0 +1 @@ +jasmine_core diff --git a/www/node_modules/jasmine-core/lib/console/console.js b/www/node_modules/jasmine-core/lib/console/console.js new file mode 100644 index 0000000..e154806 --- /dev/null +++ b/www/node_modules/jasmine-core/lib/console/console.js @@ -0,0 +1,190 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +function getJasmineRequireObj() { + if (typeof module !== 'undefined' && module.exports) { + return exports; + } else { + window.jasmineRequire = window.jasmineRequire || {}; + return window.jasmineRequire; + } +} + +getJasmineRequireObj().console = function(jRequire, j$) { + j$.ConsoleReporter = jRequire.ConsoleReporter(); +}; + +getJasmineRequireObj().ConsoleReporter = function() { + + var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } + }; + + function ConsoleReporter(options) { + var print = options.print, + showColors = options.showColors || false, + onComplete = options.onComplete || function() {}, + timer = options.timer || noopTimer, + specCount, + failureCount, + failedSpecs = [], + pendingCount, + ansi = { + green: '\x1B[32m', + red: '\x1B[31m', + yellow: '\x1B[33m', + none: '\x1B[0m' + }, + failedSuites = []; + + print('ConsoleReporter is deprecated and will be removed in a future version.'); + + this.jasmineStarted = function() { + specCount = 0; + failureCount = 0; + pendingCount = 0; + print('Started'); + printNewline(); + timer.start(); + }; + + this.jasmineDone = function() { + printNewline(); + for (var i = 0; i < failedSpecs.length; i++) { + specFailureDetails(failedSpecs[i]); + } + + if(specCount > 0) { + printNewline(); + + var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' + + failureCount + ' ' + plural('failure', failureCount); + + if (pendingCount) { + specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount); + } + + print(specCounts); + } else { + print('No specs found'); + } + + printNewline(); + var seconds = timer.elapsed() / 1000; + print('Finished in ' + seconds + ' ' + plural('second', seconds)); + printNewline(); + + for(i = 0; i < failedSuites.length; i++) { + suiteFailureDetails(failedSuites[i]); + } + + onComplete(failureCount === 0); + }; + + this.specDone = function(result) { + specCount++; + + if (result.status == 'pending') { + pendingCount++; + print(colored('yellow', '*')); + return; + } + + if (result.status == 'passed') { + print(colored('green', '.')); + return; + } + + if (result.status == 'failed') { + failureCount++; + failedSpecs.push(result); + print(colored('red', 'F')); + } + }; + + this.suiteDone = function(result) { + if (result.failedExpectations && result.failedExpectations.length > 0) { + failureCount++; + failedSuites.push(result); + } + }; + + return this; + + function printNewline() { + print('\n'); + } + + function colored(color, str) { + return showColors ? (ansi[color] + str + ansi.none) : str; + } + + function plural(str, count) { + return count == 1 ? str : str + 's'; + } + + function repeat(thing, times) { + var arr = []; + for (var i = 0; i < times; i++) { + arr.push(thing); + } + return arr; + } + + function indent(str, spaces) { + var lines = (str || '').split('\n'); + var newArr = []; + for (var i = 0; i < lines.length; i++) { + newArr.push(repeat(' ', spaces).join('') + lines[i]); + } + return newArr.join('\n'); + } + + function specFailureDetails(result) { + printNewline(); + print(result.fullName); + + for (var i = 0; i < result.failedExpectations.length; i++) { + var failedExpectation = result.failedExpectations[i]; + printNewline(); + print(indent(failedExpectation.message, 2)); + print(indent(failedExpectation.stack, 2)); + } + + printNewline(); + } + + function suiteFailureDetails(result) { + for (var i = 0; i < result.failedExpectations.length; i++) { + printNewline(); + print(colored('red', 'An error was thrown in an afterAll')); + printNewline(); + print(colored('red', 'AfterAll ' + result.failedExpectations[i].message)); + + } + printNewline(); + } + } + + return ConsoleReporter; +}; diff --git a/www/node_modules/jasmine-core/lib/jasmine-core.js b/www/node_modules/jasmine-core/lib/jasmine-core.js new file mode 100644 index 0000000..fe0ecd8 --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core.js @@ -0,0 +1,37 @@ +module.exports = require("./jasmine-core/jasmine.js"); +module.exports.boot = require('./jasmine-core/node_boot.js'); + +var path = require('path'), + fs = require('fs'); + +var rootPath = path.join(__dirname, "jasmine-core"), + bootFiles = ['boot.js'], + nodeBootFiles = ['node_boot.js'], + cssFiles = [], + jsFiles = [], + jsFilesToSkip = ['jasmine.js'].concat(bootFiles, nodeBootFiles); + +fs.readdirSync(rootPath).forEach(function(file) { + if(fs.statSync(path.join(rootPath, file)).isFile()) { + switch(path.extname(file)) { + case '.css': + cssFiles.push(file); + break; + case '.js': + if (jsFilesToSkip.indexOf(file) < 0) { + jsFiles.push(file); + } + break; + } + } +}); + +module.exports.files = { + path: rootPath, + bootDir: rootPath, + bootFiles: bootFiles, + nodeBootFiles: nodeBootFiles, + cssFiles: cssFiles, + jsFiles: ['jasmine.js'].concat(jsFiles), + imagesDir: path.join(__dirname, '../images') +}; diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/boot.js b/www/node_modules/jasmine-core/lib/jasmine-core/boot.js new file mode 100644 index 0000000..a1002de --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/boot.js @@ -0,0 +1,152 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +/** + Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project. + + If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms. + + The location of `boot.js` can be specified and/or overridden in `jasmine.yml`. + + [jasmine-gem]: http://github.com/pivotal/jasmine-gem + */ + +(function() { + + /** + * ## Require & Instantiate + * + * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference. + */ + window.jasmine = jasmineRequire.core(jasmineRequire); + + /** + * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference. + */ + jasmineRequire.html(jasmine); + + /** + * Create the Jasmine environment. This is used to run all specs in a project. + */ + var env = jasmine.getEnv(); + + /** + * ## The Global Interface + * + * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged. + */ + var jasmineInterface = jasmineRequire.interface(jasmine, env); + + /** + * Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`. + */ + extend(window, jasmineInterface); + + /** + * ## Runner Parameters + * + * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface. + */ + + var queryString = new jasmine.QueryString({ + getWindowLocation: function() { return window.location; } + }); + + var catchingExceptions = queryString.getParam("catch"); + env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions); + + var throwingExpectationFailures = queryString.getParam("throwFailures"); + env.throwOnExpectationFailure(throwingExpectationFailures); + + var random = queryString.getParam("random"); + env.randomizeTests(random); + + var seed = queryString.getParam("seed"); + if (seed) { + env.seed(seed); + } + + /** + * ## Reporters + * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any). + */ + var htmlReporter = new jasmine.HtmlReporter({ + env: env, + onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); }, + onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); }, + onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); }, + addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); }, + getContainer: function() { return document.body; }, + createElement: function() { return document.createElement.apply(document, arguments); }, + createTextNode: function() { return document.createTextNode.apply(document, arguments); }, + timer: new jasmine.Timer() + }); + + /** + * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript. + */ + env.addReporter(jasmineInterface.jsApiReporter); + env.addReporter(htmlReporter); + + /** + * Filter which specs will be run by matching the start of the full name against the `spec` query param. + */ + var specFilter = new jasmine.HtmlSpecFilter({ + filterString: function() { return queryString.getParam("spec"); } + }); + + env.specFilter = function(spec) { + return specFilter.matches(spec.getFullName()); + }; + + /** + * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack. + */ + window.setTimeout = window.setTimeout; + window.setInterval = window.setInterval; + window.clearTimeout = window.clearTimeout; + window.clearInterval = window.clearInterval; + + /** + * ## Execution + * + * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded. + */ + var currentWindowOnload = window.onload; + + window.onload = function() { + if (currentWindowOnload) { + currentWindowOnload(); + } + htmlReporter.initialize(); + env.execute(); + }; + + /** + * Helper function for readability above. + */ + function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; + } + +}()); diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Player.js b/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Player.js new file mode 100644 index 0000000..fe95f89 --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Player.js @@ -0,0 +1,24 @@ +function Player() { +} +Player.prototype.play = function(song) { + this.currentlyPlayingSong = song; + this.isPlaying = true; +}; + +Player.prototype.pause = function() { + this.isPlaying = false; +}; + +Player.prototype.resume = function() { + if (this.isPlaying) { + throw new Error("song is already playing"); + } + + this.isPlaying = true; +}; + +Player.prototype.makeFavorite = function() { + this.currentlyPlayingSong.persistFavoriteStatus(true); +}; + +module.exports = Player; diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Song.js b/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Song.js new file mode 100644 index 0000000..3415bb8 --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/lib/jasmine_examples/Song.js @@ -0,0 +1,9 @@ +function Song() { +} + +Song.prototype.persistFavoriteStatus = function(value) { + // something complicated + throw new Error("not yet implemented"); +}; + +module.exports = Song; diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/helpers/jasmine_examples/SpecHelper.js b/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/helpers/jasmine_examples/SpecHelper.js new file mode 100644 index 0000000..578b3e8 --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/helpers/jasmine_examples/SpecHelper.js @@ -0,0 +1,15 @@ +beforeEach(function () { + jasmine.addMatchers({ + toBePlaying: function () { + return { + compare: function (actual, expected) { + var player = actual; + + return { + pass: player.currentlyPlayingSong === expected && player.isPlaying + } + } + }; + } + }); +}); diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/jasmine_examples/PlayerSpec.js b/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/jasmine_examples/PlayerSpec.js new file mode 100644 index 0000000..80f149e --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/example/node_example/spec/jasmine_examples/PlayerSpec.js @@ -0,0 +1,60 @@ +describe("Player", function() { + var Player = require('../../lib/jasmine_examples/Player'); + var Song = require('../../lib/jasmine_examples/Song'); + var player; + var song; + + beforeEach(function() { + player = new Player(); + song = new Song(); + }); + + it("should be able to play a Song", function() { + player.play(song); + expect(player.currentlyPlayingSong).toEqual(song); + + //demonstrates use of custom matcher + expect(player).toBePlaying(song); + }); + + describe("when song has been paused", function() { + beforeEach(function() { + player.play(song); + player.pause(); + }); + + it("should indicate that the song is currently paused", function() { + expect(player.isPlaying).toBeFalsy(); + + // demonstrates use of 'not' with a custom matcher + expect(player).not.toBePlaying(song); + }); + + it("should be possible to resume", function() { + player.resume(); + expect(player.isPlaying).toBeTruthy(); + expect(player.currentlyPlayingSong).toEqual(song); + }); + }); + + // demonstrates use of spies to intercept and test method calls + it("tells the current song if the user has made it a favorite", function() { + spyOn(song, 'persistFavoriteStatus'); + + player.play(song); + player.makeFavorite(); + + expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true); + }); + + //demonstrates use of expected exceptions + describe("#resume", function() { + it("should throw an exception if song is already playing", function() { + player.play(song); + + expect(function() { + player.resume(); + }).toThrowError("song is already playing"); + }); + }); +}); diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/PlayerSpec.js b/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/PlayerSpec.js new file mode 100644 index 0000000..f17521f --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/PlayerSpec.js @@ -0,0 +1,58 @@ +describe("Player", function() { + var player; + var song; + + beforeEach(function() { + player = new Player(); + song = new Song(); + }); + + it("should be able to play a Song", function() { + player.play(song); + expect(player.currentlyPlayingSong).toEqual(song); + + //demonstrates use of custom matcher + expect(player).toBePlaying(song); + }); + + describe("when song has been paused", function() { + beforeEach(function() { + player.play(song); + player.pause(); + }); + + it("should indicate that the song is currently paused", function() { + expect(player.isPlaying).toBeFalsy(); + + // demonstrates use of 'not' with a custom matcher + expect(player).not.toBePlaying(song); + }); + + it("should be possible to resume", function() { + player.resume(); + expect(player.isPlaying).toBeTruthy(); + expect(player.currentlyPlayingSong).toEqual(song); + }); + }); + + // demonstrates use of spies to intercept and test method calls + it("tells the current song if the user has made it a favorite", function() { + spyOn(song, 'persistFavoriteStatus'); + + player.play(song); + player.makeFavorite(); + + expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true); + }); + + //demonstrates use of expected exceptions + describe("#resume", function() { + it("should throw an exception if song is already playing", function() { + player.play(song); + + expect(function() { + player.resume(); + }).toThrowError("song is already playing"); + }); + }); +}); diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/SpecHelper.js b/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/SpecHelper.js new file mode 100644 index 0000000..126752d --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/example/spec/SpecHelper.js @@ -0,0 +1,15 @@ +beforeEach(function () { + jasmine.addMatchers({ + toBePlaying: function () { + return { + compare: function (actual, expected) { + var player = actual; + + return { + pass: player.currentlyPlayingSong === expected && player.isPlaying + }; + } + }; + } + }); +}); diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Player.js b/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Player.js new file mode 100644 index 0000000..fcce826 --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Player.js @@ -0,0 +1,22 @@ +function Player() { +} +Player.prototype.play = function(song) { + this.currentlyPlayingSong = song; + this.isPlaying = true; +}; + +Player.prototype.pause = function() { + this.isPlaying = false; +}; + +Player.prototype.resume = function() { + if (this.isPlaying) { + throw new Error("song is already playing"); + } + + this.isPlaying = true; +}; + +Player.prototype.makeFavorite = function() { + this.currentlyPlayingSong.persistFavoriteStatus(true); +}; \ No newline at end of file diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Song.js b/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Song.js new file mode 100644 index 0000000..a8a3f2d --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/example/src/Song.js @@ -0,0 +1,7 @@ +function Song() { +} + +Song.prototype.persistFavoriteStatus = function(value) { + // something complicated + throw new Error("not yet implemented"); +}; \ No newline at end of file diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js b/www/node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js new file mode 100644 index 0000000..da23532 --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js @@ -0,0 +1,473 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +jasmineRequire.html = function(j$) { + j$.ResultsNode = jasmineRequire.ResultsNode(); + j$.HtmlReporter = jasmineRequire.HtmlReporter(j$); + j$.QueryString = jasmineRequire.QueryString(); + j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter(); +}; + +jasmineRequire.HtmlReporter = function(j$) { + + var noopTimer = { + start: function() {}, + elapsed: function() { return 0; } + }; + + function HtmlReporter(options) { + var env = options.env || {}, + getContainer = options.getContainer, + createElement = options.createElement, + createTextNode = options.createTextNode, + onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {}, + onThrowExpectationsClick = options.onThrowExpectationsClick || function() {}, + onRandomClick = options.onRandomClick || function() {}, + addToExistingQueryString = options.addToExistingQueryString || defaultQueryString, + timer = options.timer || noopTimer, + results = [], + specsExecuted = 0, + failureCount = 0, + pendingSpecCount = 0, + htmlReporterMain, + symbols, + failedSuites = []; + + this.initialize = function() { + clearPrior(); + htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'}, + createDom('div', {className: 'jasmine-banner'}, + createDom('a', {className: 'jasmine-title', href: 'http://jasmine.github.io/', target: '_blank'}), + createDom('span', {className: 'jasmine-version'}, j$.version) + ), + createDom('ul', {className: 'jasmine-symbol-summary'}), + createDom('div', {className: 'jasmine-alert'}), + createDom('div', {className: 'jasmine-results'}, + createDom('div', {className: 'jasmine-failures'}) + ) + ); + getContainer().appendChild(htmlReporterMain); + }; + + var totalSpecsDefined; + this.jasmineStarted = function(options) { + totalSpecsDefined = options.totalSpecsDefined || 0; + timer.start(); + }; + + var summary = createDom('div', {className: 'jasmine-summary'}); + + var topResults = new j$.ResultsNode({}, '', null), + currentParent = topResults; + + this.suiteStarted = function(result) { + currentParent.addChild(result, 'suite'); + currentParent = currentParent.last(); + }; + + this.suiteDone = function(result) { + if (result.status == 'failed') { + failedSuites.push(result); + } + + if (currentParent == topResults) { + return; + } + + currentParent = currentParent.parent; + }; + + this.specStarted = function(result) { + currentParent.addChild(result, 'spec'); + }; + + var failures = []; + this.specDone = function(result) { + if(noExpectations(result) && typeof console !== 'undefined' && typeof console.error !== 'undefined') { + console.error('Spec \'' + result.fullName + '\' has no expectations.'); + } + + if (result.status != 'disabled') { + specsExecuted++; + } + + if (!symbols){ + symbols = find('.jasmine-symbol-summary'); + } + + symbols.appendChild(createDom('li', { + className: noExpectations(result) ? 'jasmine-empty' : 'jasmine-' + result.status, + id: 'spec_' + result.id, + title: result.fullName + } + )); + + if (result.status == 'failed') { + failureCount++; + + var failure = + createDom('div', {className: 'jasmine-spec-detail jasmine-failed'}, + createDom('div', {className: 'jasmine-description'}, + createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName) + ), + createDom('div', {className: 'jasmine-messages'}) + ); + var messages = failure.childNodes[1]; + + for (var i = 0; i < result.failedExpectations.length; i++) { + var expectation = result.failedExpectations[i]; + messages.appendChild(createDom('div', {className: 'jasmine-result-message'}, expectation.message)); + messages.appendChild(createDom('div', {className: 'jasmine-stack-trace'}, expectation.stack)); + } + + failures.push(failure); + } + + if (result.status == 'pending') { + pendingSpecCount++; + } + }; + + this.jasmineDone = function(doneResult) { + var banner = find('.jasmine-banner'); + var alert = find('.jasmine-alert'); + var order = doneResult && doneResult.order; + alert.appendChild(createDom('span', {className: 'jasmine-duration'}, 'finished in ' + timer.elapsed() / 1000 + 's')); + + banner.appendChild( + createDom('div', { className: 'jasmine-run-options' }, + createDom('span', { className: 'jasmine-trigger' }, 'Options'), + createDom('div', { className: 'jasmine-payload' }, + createDom('div', { className: 'jasmine-exceptions' }, + createDom('input', { + className: 'jasmine-raise', + id: 'jasmine-raise-exceptions', + type: 'checkbox' + }), + createDom('label', { className: 'jasmine-label', 'for': 'jasmine-raise-exceptions' }, 'raise exceptions')), + createDom('div', { className: 'jasmine-throw-failures' }, + createDom('input', { + className: 'jasmine-throw', + id: 'jasmine-throw-failures', + type: 'checkbox' + }), + createDom('label', { className: 'jasmine-label', 'for': 'jasmine-throw-failures' }, 'stop spec on expectation failure')), + createDom('div', { className: 'jasmine-random-order' }, + createDom('input', { + className: 'jasmine-random', + id: 'jasmine-random-order', + type: 'checkbox' + }), + createDom('label', { className: 'jasmine-label', 'for': 'jasmine-random-order' }, 'run tests in random order')) + ) + )); + + var raiseCheckbox = find('#jasmine-raise-exceptions'); + + raiseCheckbox.checked = !env.catchingExceptions(); + raiseCheckbox.onclick = onRaiseExceptionsClick; + + var throwCheckbox = find('#jasmine-throw-failures'); + throwCheckbox.checked = env.throwingExpectationFailures(); + throwCheckbox.onclick = onThrowExpectationsClick; + + var randomCheckbox = find('#jasmine-random-order'); + randomCheckbox.checked = env.randomTests(); + randomCheckbox.onclick = onRandomClick; + + var optionsMenu = find('.jasmine-run-options'), + optionsTrigger = optionsMenu.querySelector('.jasmine-trigger'), + optionsPayload = optionsMenu.querySelector('.jasmine-payload'), + isOpen = /\bjasmine-open\b/; + + optionsTrigger.onclick = function() { + if (isOpen.test(optionsPayload.className)) { + optionsPayload.className = optionsPayload.className.replace(isOpen, ''); + } else { + optionsPayload.className += ' jasmine-open'; + } + }; + + if (specsExecuted < totalSpecsDefined) { + var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all'; + alert.appendChild( + createDom('span', {className: 'jasmine-bar jasmine-skipped'}, + createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage) + ) + ); + } + var statusBarMessage = ''; + var statusBarClassName = 'jasmine-bar '; + + if (totalSpecsDefined > 0) { + statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount); + if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); } + statusBarClassName += (failureCount > 0) ? 'jasmine-failed' : 'jasmine-passed'; + } else { + statusBarClassName += 'jasmine-skipped'; + statusBarMessage += 'No specs found'; + } + + var seedBar; + if (order && order.random) { + seedBar = createDom('span', {className: 'jasmine-seed-bar'}, + ', randomized with seed ', + createDom('a', {title: 'randomized with seed ' + order.seed, href: seedHref(order.seed)}, order.seed) + ); + } + + alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage, seedBar)); + + for(i = 0; i < failedSuites.length; i++) { + var failedSuite = failedSuites[i]; + for(var j = 0; j < failedSuite.failedExpectations.length; j++) { + var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message; + var errorBarClassName = 'jasmine-bar jasmine-errored'; + alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage)); + } + } + + var results = find('.jasmine-results'); + results.appendChild(summary); + + summaryList(topResults, summary); + + function summaryList(resultsTree, domParent) { + var specListNode; + for (var i = 0; i < resultsTree.children.length; i++) { + var resultNode = resultsTree.children[i]; + if (resultNode.type == 'suite') { + var suiteListNode = createDom('ul', {className: 'jasmine-suite', id: 'suite-' + resultNode.result.id}, + createDom('li', {className: 'jasmine-suite-detail'}, + createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description) + ) + ); + + summaryList(resultNode, suiteListNode); + domParent.appendChild(suiteListNode); + } + if (resultNode.type == 'spec') { + if (domParent.getAttribute('class') != 'jasmine-specs') { + specListNode = createDom('ul', {className: 'jasmine-specs'}); + domParent.appendChild(specListNode); + } + var specDescription = resultNode.result.description; + if(noExpectations(resultNode.result)) { + specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription; + } + if(resultNode.result.status === 'pending' && resultNode.result.pendingReason !== '') { + specDescription = specDescription + ' PENDING WITH MESSAGE: ' + resultNode.result.pendingReason; + } + specListNode.appendChild( + createDom('li', { + className: 'jasmine-' + resultNode.result.status, + id: 'spec-' + resultNode.result.id + }, + createDom('a', {href: specHref(resultNode.result)}, specDescription) + ) + ); + } + } + } + + if (failures.length) { + alert.appendChild( + createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-spec-list'}, + createDom('span', {}, 'Spec List | '), + createDom('a', {className: 'jasmine-failures-menu', href: '#'}, 'Failures'))); + alert.appendChild( + createDom('span', {className: 'jasmine-menu jasmine-bar jasmine-failure-list'}, + createDom('a', {className: 'jasmine-spec-list-menu', href: '#'}, 'Spec List'), + createDom('span', {}, ' | Failures '))); + + find('.jasmine-failures-menu').onclick = function() { + setMenuModeTo('jasmine-failure-list'); + }; + find('.jasmine-spec-list-menu').onclick = function() { + setMenuModeTo('jasmine-spec-list'); + }; + + setMenuModeTo('jasmine-failure-list'); + + var failureNode = find('.jasmine-failures'); + for (var i = 0; i < failures.length; i++) { + failureNode.appendChild(failures[i]); + } + } + }; + + return this; + + function find(selector) { + return getContainer().querySelector('.jasmine_html-reporter ' + selector); + } + + function clearPrior() { + // return the reporter + var oldReporter = find(''); + + if(oldReporter) { + getContainer().removeChild(oldReporter); + } + } + + function createDom(type, attrs, childrenVarArgs) { + var el = createElement(type); + + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i]; + + if (typeof child === 'string') { + el.appendChild(createTextNode(child)); + } else { + if (child) { + el.appendChild(child); + } + } + } + + for (var attr in attrs) { + if (attr == 'className') { + el[attr] = attrs[attr]; + } else { + el.setAttribute(attr, attrs[attr]); + } + } + + return el; + } + + function pluralize(singular, count) { + var word = (count == 1 ? singular : singular + 's'); + + return '' + count + ' ' + word; + } + + function specHref(result) { + return addToExistingQueryString('spec', result.fullName); + } + + function seedHref(seed) { + return addToExistingQueryString('seed', seed); + } + + function defaultQueryString(key, value) { + return '?' + key + '=' + value; + } + + function setMenuModeTo(mode) { + htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode); + } + + function noExpectations(result) { + return (result.failedExpectations.length + result.passedExpectations.length) === 0 && + result.status === 'passed'; + } + } + + return HtmlReporter; +}; + +jasmineRequire.HtmlSpecFilter = function() { + function HtmlSpecFilter(options) { + var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + var filterPattern = new RegExp(filterString); + + this.matches = function(specName) { + return filterPattern.test(specName); + }; + } + + return HtmlSpecFilter; +}; + +jasmineRequire.ResultsNode = function() { + function ResultsNode(result, type, parent) { + this.result = result; + this.type = type; + this.parent = parent; + + this.children = []; + + this.addChild = function(result, type) { + this.children.push(new ResultsNode(result, type, this)); + }; + + this.last = function() { + return this.children[this.children.length - 1]; + }; + } + + return ResultsNode; +}; + +jasmineRequire.QueryString = function() { + function QueryString(options) { + + this.navigateWithNewParam = function(key, value) { + options.getWindowLocation().search = this.fullStringWithNewParam(key, value); + }; + + this.fullStringWithNewParam = function(key, value) { + var paramMap = queryStringToParamMap(); + paramMap[key] = value; + return toQueryString(paramMap); + }; + + this.getParam = function(key) { + return queryStringToParamMap()[key]; + }; + + return this; + + function toQueryString(paramMap) { + var qStrPairs = []; + for (var prop in paramMap) { + qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop])); + } + return '?' + qStrPairs.join('&'); + } + + function queryStringToParamMap() { + var paramStr = options.getWindowLocation().search.substring(1), + params = [], + paramMap = {}; + + if (paramStr.length > 0) { + params = paramStr.split('&'); + for (var i = 0; i < params.length; i++) { + var p = params[i].split('='); + var value = decodeURIComponent(p[1]); + if (value === 'true' || value === 'false') { + value = JSON.parse(value); + } + paramMap[decodeURIComponent(p[0])] = value; + } + } + + return paramMap; + } + + } + + return QueryString; +}; diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.css b/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.css new file mode 100644 index 0000000..6319982 --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.css @@ -0,0 +1,58 @@ +body { overflow-y: scroll; } + +.jasmine_html-reporter { background-color: #eee; padding: 5px; margin: -8px; font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333; } +.jasmine_html-reporter a { text-decoration: none; } +.jasmine_html-reporter a:hover { text-decoration: underline; } +.jasmine_html-reporter p, .jasmine_html-reporter h1, .jasmine_html-reporter h2, .jasmine_html-reporter h3, .jasmine_html-reporter h4, .jasmine_html-reporter h5, .jasmine_html-reporter h6 { margin: 0; line-height: 14px; } +.jasmine_html-reporter .jasmine-banner, .jasmine_html-reporter .jasmine-symbol-summary, .jasmine_html-reporter .jasmine-summary, .jasmine_html-reporter .jasmine-result-message, .jasmine_html-reporter .jasmine-spec .jasmine-description, .jasmine_html-reporter .jasmine-spec-detail .jasmine-description, .jasmine_html-reporter .jasmine-alert .jasmine-bar, .jasmine_html-reporter .jasmine-stack-trace { padding-left: 9px; padding-right: 9px; } +.jasmine_html-reporter .jasmine-banner { position: relative; } +.jasmine_html-reporter .jasmine-banner .jasmine-title { background: url('data:image/png;base64,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') no-repeat; background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICB3aWR0aD0iNjgxLjk2MjUyIgogICBoZWlnaHQ9IjE4Ny41IgogICBpZD0ic3ZnMiIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhOCI+PHJkZjpSREY+PGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMKICAgICBpZD0iZGVmczYiPjxjbGlwUGF0aAogICAgICAgaWQ9ImNsaXBQYXRoMTgiPjxwYXRoCiAgICAgICAgIGQ9Ik0gMCwxNTAwIDAsMCBsIDU0NTUuNzQsMCAwLDE1MDAgTCAwLDE1MDAgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgyMCIgLz48L2NsaXBQYXRoPjwvZGVmcz48ZwogICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMjUsMCwwLC0xLjI1LDAsMTg3LjUpIgogICAgIGlkPSJnMTAiPjxnCiAgICAgICB0cmFuc2Zvcm09InNjYWxlKDAuMSwwLjEpIgogICAgICAgaWQ9ImcxMiI+PGcKICAgICAgICAgaWQ9ImcxNCI+PGcKICAgICAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGgxOCkiCiAgICAgICAgICAgaWQ9ImcxNiI+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTU0NCw1OTkuNDM0IGMgMC45MiwtNDAuMzUyIDI1LjY4LC04MS42MDIgNzEuNTMsLTgxLjYwMiAyNy41MSwwIDQ3LjY4LDEyLjgzMiA2MS40NCwzNS43NTQgMTIuODMsMjIuOTMgMTIuODMsNTYuODUyIDEyLjgzLDgyLjUyNyBsIDAsMzI5LjE4NCAtNzEuNTIsMCAwLDEwNC41NDMgMjY2LjgzLDAgMCwtMTA0LjU0MyAtNzAuNiwwIDAsLTM0NC43NyBjIDAsLTU4LjY5MSAtMy42OCwtMTA0LjUzMSAtNDQuOTMsLTE1Mi4yMTggLTM2LjY4LC00Mi4xOCAtOTYuMjgsLTY2LjAyIC0xNTMuMTQsLTY2LjAyIC0xMTcuMzcsMCAtMjA3LjI0LDc3Ljk0MSAtMjAyLjY0LDE5Ny4xNDUgbCAxMzAuMiwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMjIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDIzMDEuNCw2NjIuNjk1IGMgMCw4MC43MDMgLTY2Ljk0LDE0NS44MTMgLTE0Ny42MywxNDUuODEzIC04My40NCwwIC0xNDcuNjMsLTY4Ljc4MSAtMTQ3LjYzLC0xNTEuMzAxIDAsLTc5Ljc4NSA2Ni45NCwtMTQ1LjgwMSAxNDUuOCwtMTQ1LjgwMSA4NC4zNSwwIDE0OS40Niw2Ny44NTIgMTQ5LjQ2LDE1MS4yODkgeiBtIC0xLjgzLC0xODEuNTQ3IGMgLTM1Ljc3LC01NC4wOTcgLTkzLjUzLC03OC44NTkgLTE1Ny43MiwtNzguODU5IC0xNDAuMywwIC0yNTEuMjQsMTE2LjQ0OSAtMjUxLjI0LDI1NC45MTggMCwxNDIuMTI5IDExMy43LDI2MC40MSAyNTYuNzQsMjYwLjQxIDYzLjI3LDAgMTE4LjI5LC0yOS4zMzYgMTUyLjIyLC04Mi41MjMgbCAwLDY5LjY4NyAxNzUuMTQsMCAwLC0xMDQuNTI3IC02MS40NCwwIDAsLTI4MC41OTggNjEuNDQsMCAwLC0xMDQuNTI3IC0xNzUuMTQsMCAwLDY2LjAxOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAyNjIyLjMzLDU1Ny4yNTggYyAzLjY3LC00NC4wMTYgMzMuMDEsLTczLjM0OCA3OC44NiwtNzMuMzQ4IDMzLjkzLDAgNjYuOTMsMjMuODI0IDY2LjkzLDYwLjUwNCAwLDQ4LjYwNiAtNDUuODQsNTYuODU2IC04My40NCw2Ni45NDEgLTg1LjI4LDIyLjAwNCAtMTc4LjgxLDQ4LjYwNiAtMTc4LjgxLDE1NS44NzkgMCw5My41MzYgNzguODYsMTQ3LjYzMyAxNjUuOTgsMTQ3LjYzMyA0NCwwIDgzLjQzLC05LjE3NiAxMTAuOTQsLTQ0LjAwOCBsIDAsMzMuOTIyIDgyLjUzLDAgMCwtMTMyLjk2NSAtMTA4LjIxLDAgYyAtMS44MywzNC44NTYgLTI4LjQyLDU3Ljc3NCAtNjMuMjYsNTcuNzc0IC0zMC4yNiwwIC02Mi4zNSwtMTcuNDIyIC02Mi4zNSwtNTEuMzQ4IDAsLTQ1Ljg0NyA0NC45MywtNTUuOTMgODAuNjksLTY0LjE4IDg4LjAyLC0yMC4xNzUgMTgyLjQ3LC00Ny42OTUgMTgyLjQ3LC0xNTcuNzM0IDAsLTk5LjAyNyAtODMuNDQsLTE1NC4wMzkgLTE3NS4xMywtMTU0LjAzOSAtNDkuNTMsMCAtOTQuNDYsMTUuNTgyIC0xMjYuNTUsNTMuMTggbCAwLC00MC4zNCAtODUuMjcsMCAwLDE0Mi4xMjkgMTE0LjYyLDAiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGgyNiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMjk4OC4xOCw4MDAuMjU0IC02My4yNiwwIDAsMTA0LjUyNyAxNjUuMDUsMCAwLC03My4zNTUgYyAzMS4xOCw1MS4zNDcgNzguODYsODUuMjc3IDE0MS4yMSw4NS4yNzcgNjcuODUsMCAxMjQuNzEsLTQxLjI1OCAxNTIuMjEsLTEwMi42OTkgMjYuNiw2Mi4zNTEgOTIuNjIsMTAyLjY5OSAxNjAuNDcsMTAyLjY5OSA1My4xOSwwIDEwNS40NiwtMjIgMTQxLjIxLC02Mi4zNTEgMzguNTIsLTQ0LjkzOCAzOC41MiwtOTMuNTMyIDM4LjUyLC0xNDkuNDU3IGwgMCwtMTg1LjIzOSA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40MiwwIDAsMTA0LjUyNyA2My4yOCwwIDAsMTU3LjcxNSBjIDAsMzIuMTAyIDAsNjAuNTI3IC0xNC42Nyw4OC45NTcgLTE4LjM0LDI2LjU4MiAtNDguNjEsNDAuMzQ0IC03OS43Nyw0MC4zNDQgLTMwLjI2LDAgLTYzLjI4LC0xMi44NDQgLTgyLjUzLC0zNi42NzIgLTIyLjkzLC0yOS4zNTUgLTIyLjkzLC01Ni44NjMgLTIyLjkzLC05Mi42MjkgbCAwLC0xNTcuNzE1IDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM4LjQxLDAgMCwxMDQuNTI3IDYzLjI4LDAgMCwxNTAuMzgzIGMgMCwyOS4zNDggMCw2Ni4wMjMgLTE0LjY3LDkxLjY5OSAtMTUuNTksMjkuMzM2IC00Ny42OSw0NC45MzQgLTgwLjcsNDQuOTM0IC0zMS4xOCwwIC01Ny43NywtMTEuMDA4IC03Ny45NCwtMzUuNzc0IC0yNC43NywtMzAuMjUzIC0yNi42LC02Mi4zNDMgLTI2LjYsLTk5Ljk0MSBsIDAsLTE1MS4zMDEgNjMuMjcsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNiwwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAzOTk4LjY2LDk1MS41NDcgLTExMS44NywwIDAsMTE4LjI5MyAxMTEuODcsMCAwLC0xMTguMjkzIHogbSAwLC00MzEuODkxIDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM5LjMzLDAgMCwxMDQuNTI3IDY0LjE5LDAgMCwyODAuNTk4IC02My4yNywwIDAsMTA0LjUyNyAxNzUuMTQsMCAwLC0zODUuMTI1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzAiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDQxNTkuMTIsODAwLjI1NCAtNjMuMjcsMCAwLDEwNC41MjcgMTc1LjE0LDAgMCwtNjkuNjg3IGMgMjkuMzUsNTQuMTAxIDg0LjM2LDgwLjY5OSAxNDQuODcsODAuNjk5IDUzLjE5LDAgMTA1LjQ1LC0yMi4wMTYgMTQxLjIyLC02MC41MjcgNDAuMzQsLTQ0LjkzNCA0MS4yNiwtODguMDMyIDQxLjI2LC0xNDMuOTU3IGwgMCwtMTkxLjY1MyA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40LDAgMCwxMDQuNTI3IDYzLjI2LDAgMCwxNTguNjM3IGMgMCwzMC4yNjIgMCw2MS40MzQgLTE5LjI2LDg4LjAzNSAtMjAuMTcsMjYuNTgyIC01My4xOCwzOS40MTQgLTg2LjE5LDM5LjQxNCAtMzMuOTMsMCAtNjguNzcsLTEzLjc1IC04OC45NCwtNDEuMjUgLTIxLjA5LC0yNy41IC0yMS4wOSwtNjkuNjg3IC0yMS4wOSwtMTAyLjcwNyBsIDAsLTE0Mi4xMjkgNjMuMjYsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNywwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDMyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA1MDgyLjQ4LDcwMy45NjUgYyAtMTkuMjQsNzAuNjA1IC04MS42LDExNS41NDcgLTE1NC4wNCwxMTUuNTQ3IC02Ni4wNCwwIC0xMjkuMywtNTEuMzQ4IC0xNDMuMDUsLTExNS41NDcgbCAyOTcuMDksMCB6IG0gODUuMjcsLTE0NC44ODMgYyAtMzguNTEsLTkzLjUyMyAtMTI5LjI3LC0xNTYuNzkzIC0yMzEuMDUsLTE1Ni43OTMgLTE0My4wNywwIC0yNTcuNjgsMTExLjg3MSAtMjU3LjY4LDI1NS44MzYgMCwxNDQuODgzIDEwOS4xMiwyNjEuMzI4IDI1NC45MSwyNjEuMzI4IDY3Ljg3LDAgMTM1LjcyLC0zMC4yNTggMTgzLjM5LC03OC44NjMgNDguNjIsLTUxLjM0NCA2OC43OSwtMTEzLjY5NSA2OC43OSwtMTgzLjM4MyBsIC0zLjY3LC0zOS40MzQgLTM5Ni4xMywwIGMgMTQuNjcsLTY3Ljg2MyA3Ny4wMywtMTE3LjM2MyAxNDYuNzIsLTExNy4zNjMgNDguNTksMCA5MC43NiwxOC4zMjggMTE4LjI4LDU4LjY3MiBsIDExNi40NCwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDY5MC44OTUsODUwLjcwMyA5MC43NSwwIDIyLjU0MywzMS4wMzUgMCwyNDMuMTIyIC0xMzUuODI5LDAgMCwtMjQzLjE0MSAyMi41MzYsLTMxLjAxNiIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDM2IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA2MzIuMzk1LDc0Mi4yNTggMjguMDM5LDg2LjMwNCAtMjIuNTUxLDMxLjA0IC0yMzEuMjIzLDc1LjEyOCAtNDEuOTc2LC0xMjkuMTgzIDIzMS4yNTcsLTc1LjEzNyAzNi40NTQsMTEuODQ4IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzgiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDcxNy40NDksNjUzLjEwNSAtNzMuNDEsNTMuMzYgLTM2LjQ4OCwtMTEuODc1IC0xNDIuOTAzLC0xOTYuNjkyIDEwOS44ODMsLTc5LjgyOCAxNDIuOTE4LDE5Ni43MDMgMCwzOC4zMzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0MCIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gODI4LjUyLDcwNi40NjUgLTczLjQyNiwtNTMuMzQgMC4wMTEsLTM4LjM1OSBMIDg5OC4wMDQsNDE4LjA3IDEwMDcuOSw0OTcuODk4IDg2NC45NzMsNjk0LjYwOSA4MjguNTIsNzA2LjQ2NSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA4MTIuMDg2LDgyOC41ODYgMjguMDU1LC04Ni4zMiAzNi40ODQsLTExLjgzNiAyMzEuMjI1LDc1LjExNyAtNDEuOTcsMTI5LjE4MyAtMjMxLjIzOSwtNzUuMTQgLTIyLjU1NSwtMzEuMDA0IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNDQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDczNi4zMDEsMTMzNS44OCBjIC0zMjMuMDQ3LDAgLTU4NS44NzUsLTI2Mi43OCAtNTg1Ljg3NSwtNTg1Ljc4MiAwLC0zMjMuMTE4IDI2Mi44MjgsLTU4NS45NzcgNTg1Ljg3NSwtNTg1Ljk3NyAzMjMuMDE5LDAgNTg1LjgwOSwyNjIuODU5IDU4NS44MDksNTg1Ljk3NyAwLDMyMy4wMDIgLTI2Mi43OSw1ODUuNzgyIC01ODUuODA5LDU4NS43ODIgbCAwLDAgeiBtIDAsLTExOC42MSBjIDI1Ny45NzIsMCA0NjcuMTg5LC0yMDkuMTMgNDY3LjE4OSwtNDY3LjE3MiAwLC0yNTguMTI5IC0yMDkuMjE3LC00NjcuMzQ4IC00NjcuMTg5LC00NjcuMzQ4IC0yNTguMDc0LDAgLTQ2Ny4yNTQsMjA5LjIxOSAtNDY3LjI1NCw0NjcuMzQ4IDAsMjU4LjA0MiAyMDkuMTgsNDY3LjE3MiA0NjcuMjU0LDQ2Ny4xNzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0NiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTA5MS4xMyw2MTkuODgzIC0xNzUuNzcxLDU3LjEyMSAxMS42MjksMzUuODA4IDE3NS43NjIsLTU3LjEyMSAtMTEuNjIsLTM1LjgwOCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQ4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA4NjYuOTU3LDkwMi4wNzQgODM2LjUsOTI0LjE5OSA5NDUuMTIxLDEwNzMuNzMgOTc1LjU4NiwxMDUxLjYxIDg2Ni45NTcsOTAyLjA3NCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDUwIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA2MDcuNDY1LDkwMy40NDUgNDk4Ljg1NSwxMDUyLjk3IDUyOS4zMiwxMDc1LjEgNjM3LjkzLDkyNS41NjYgNjA3LjQ2NSw5MDMuNDQ1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDM4MC42ODgsNjIyLjEyOSAtMTEuNjI2LDM1LjgwMSAxNzUuNzU4LDU3LjA5IDExLjYyMSwtMzUuODAxIC0xNzUuNzUzLC01Ny4wOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDU0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA3MTYuMjg5LDM3Ni41OSAzNy42NDA2LDAgMCwxODQuODE2IC0zNy42NDA2LDAgMCwtMTg0LjgxNiB6IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTYiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4=') no-repeat, none; -moz-background-size: 100%; -o-background-size: 100%; -webkit-background-size: 100%; background-size: 100%; display: block; float: left; width: 90px; height: 25px; } +.jasmine_html-reporter .jasmine-banner .jasmine-version { margin-left: 14px; position: relative; top: 6px; } +.jasmine_html-reporter #jasmine_content { position: fixed; right: 100%; } +.jasmine_html-reporter .jasmine-version { color: #aaa; } +.jasmine_html-reporter .jasmine-banner { margin-top: 14px; } +.jasmine_html-reporter .jasmine-duration { color: #fff; float: right; line-height: 28px; padding-right: 9px; } +.jasmine_html-reporter .jasmine-symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; } +.jasmine_html-reporter .jasmine-symbol-summary li { display: inline-block; height: 10px; width: 14px; font-size: 16px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-passed { font-size: 14px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-passed:before { color: #007069; content: "\02022"; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-failed { line-height: 9px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-failed:before { color: #ca3a11; content: "\d7"; font-weight: bold; margin-left: -1px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-disabled { font-size: 14px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-disabled:before { color: #bababa; content: "\02022"; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-pending { line-height: 17px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-pending:before { color: #ba9d37; content: "*"; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-empty { font-size: 14px; } +.jasmine_html-reporter .jasmine-symbol-summary li.jasmine-empty:before { color: #ba9d37; content: "\02022"; } +.jasmine_html-reporter .jasmine-run-options { float: right; margin-right: 5px; border: 1px solid #8a4182; color: #8a4182; position: relative; line-height: 20px; } +.jasmine_html-reporter .jasmine-run-options .jasmine-trigger { cursor: pointer; padding: 8px 16px; } +.jasmine_html-reporter .jasmine-run-options .jasmine-payload { position: absolute; display: none; right: -1px; border: 1px solid #8a4182; background-color: #eee; white-space: nowrap; padding: 4px 8px; } +.jasmine_html-reporter .jasmine-run-options .jasmine-payload.jasmine-open { display: block; } +.jasmine_html-reporter .jasmine-bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } +.jasmine_html-reporter .jasmine-bar.jasmine-failed { background-color: #ca3a11; } +.jasmine_html-reporter .jasmine-bar.jasmine-passed { background-color: #007069; } +.jasmine_html-reporter .jasmine-bar.jasmine-skipped { background-color: #bababa; } +.jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; } +.jasmine_html-reporter .jasmine-bar.jasmine-menu { background-color: #fff; color: #aaa; } +.jasmine_html-reporter .jasmine-bar.jasmine-menu a { color: #333; } +.jasmine_html-reporter .jasmine-bar a { color: white; } +.jasmine_html-reporter.jasmine-spec-list .jasmine-bar.jasmine-menu.jasmine-failure-list, .jasmine_html-reporter.jasmine-spec-list .jasmine-results .jasmine-failures { display: none; } +.jasmine_html-reporter.jasmine-failure-list .jasmine-bar.jasmine-menu.jasmine-spec-list, .jasmine_html-reporter.jasmine-failure-list .jasmine-summary { display: none; } +.jasmine_html-reporter .jasmine-results { margin-top: 14px; } +.jasmine_html-reporter .jasmine-summary { margin-top: 14px; } +.jasmine_html-reporter .jasmine-summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; } +.jasmine_html-reporter .jasmine-summary ul.jasmine-suite { margin-top: 7px; margin-bottom: 7px; } +.jasmine_html-reporter .jasmine-summary li.jasmine-passed a { color: #007069; } +.jasmine_html-reporter .jasmine-summary li.jasmine-failed a { color: #ca3a11; } +.jasmine_html-reporter .jasmine-summary li.jasmine-empty a { color: #ba9d37; } +.jasmine_html-reporter .jasmine-summary li.jasmine-pending a { color: #ba9d37; } +.jasmine_html-reporter .jasmine-summary li.jasmine-disabled a { color: #bababa; } +.jasmine_html-reporter .jasmine-description + .jasmine-suite { margin-top: 0; } +.jasmine_html-reporter .jasmine-suite { margin-top: 14px; } +.jasmine_html-reporter .jasmine-suite a { color: #333; } +.jasmine_html-reporter .jasmine-failures .jasmine-spec-detail { margin-bottom: 28px; } +.jasmine_html-reporter .jasmine-failures .jasmine-spec-detail .jasmine-description { background-color: #ca3a11; } +.jasmine_html-reporter .jasmine-failures .jasmine-spec-detail .jasmine-description a { color: white; } +.jasmine_html-reporter .jasmine-result-message { padding-top: 14px; color: #333; white-space: pre; } +.jasmine_html-reporter .jasmine-result-message span.jasmine-result { display: block; } +.jasmine_html-reporter .jasmine-stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666; border: 1px solid #ddd; background: white; white-space: pre; } diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.js b/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.js new file mode 100644 index 0000000..bea469d --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/jasmine.js @@ -0,0 +1,3454 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +var getJasmineRequireObj = (function (jasmineGlobal) { + var jasmineRequire; + + if (typeof module !== 'undefined' && module.exports) { + if (typeof global !== 'undefined') { + jasmineGlobal = global; + } else { + jasmineGlobal = {}; + } + jasmineRequire = exports; + } else { + if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') { + jasmineGlobal = window; + } + jasmineRequire = jasmineGlobal.jasmineRequire = jasmineGlobal.jasmineRequire || {}; + } + + function getJasmineRequire() { + return jasmineRequire; + } + + getJasmineRequire().core = function(jRequire) { + var j$ = {}; + + jRequire.base(j$, jasmineGlobal); + j$.util = jRequire.util(); + j$.errors = jRequire.errors(); + j$.Any = jRequire.Any(j$); + j$.Anything = jRequire.Anything(j$); + j$.CallTracker = jRequire.CallTracker(); + j$.MockDate = jRequire.MockDate(); + j$.Clock = jRequire.Clock(); + j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(); + j$.Env = jRequire.Env(j$); + j$.ExceptionFormatter = jRequire.ExceptionFormatter(); + j$.Expectation = jRequire.Expectation(); + j$.buildExpectationResult = jRequire.buildExpectationResult(); + j$.JsApiReporter = jRequire.JsApiReporter(); + j$.matchersUtil = jRequire.matchersUtil(j$); + j$.ObjectContaining = jRequire.ObjectContaining(j$); + j$.ArrayContaining = jRequire.ArrayContaining(j$); + j$.pp = jRequire.pp(j$); + j$.QueueRunner = jRequire.QueueRunner(j$); + j$.ReportDispatcher = jRequire.ReportDispatcher(); + j$.Spec = jRequire.Spec(j$); + j$.SpyRegistry = jRequire.SpyRegistry(j$); + j$.SpyStrategy = jRequire.SpyStrategy(); + j$.StringMatching = jRequire.StringMatching(j$); + j$.Suite = jRequire.Suite(j$); + j$.Timer = jRequire.Timer(); + j$.TreeProcessor = jRequire.TreeProcessor(); + j$.version = jRequire.version(); + j$.Order = jRequire.Order(); + + j$.matchers = jRequire.requireMatchers(jRequire, j$); + + return j$; + }; + + return getJasmineRequire; +})(this); + +getJasmineRequireObj().requireMatchers = function(jRequire, j$) { + var availableMatchers = [ + 'toBe', + 'toBeCloseTo', + 'toBeDefined', + 'toBeFalsy', + 'toBeGreaterThan', + 'toBeLessThan', + 'toBeNaN', + 'toBeNull', + 'toBeTruthy', + 'toBeUndefined', + 'toContain', + 'toEqual', + 'toHaveBeenCalled', + 'toHaveBeenCalledWith', + 'toHaveBeenCalledTimes', + 'toMatch', + 'toThrow', + 'toThrowError' + ], + matchers = {}; + + for (var i = 0; i < availableMatchers.length; i++) { + var name = availableMatchers[i]; + matchers[name] = jRequire[name](j$); + } + + return matchers; +}; + +getJasmineRequireObj().base = function(j$, jasmineGlobal) { + j$.unimplementedMethod_ = function() { + throw new Error('unimplemented method'); + }; + + j$.MAX_PRETTY_PRINT_DEPTH = 40; + j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 100; + j$.DEFAULT_TIMEOUT_INTERVAL = 5000; + + j$.getGlobal = function() { + return jasmineGlobal; + }; + + j$.getEnv = function(options) { + var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options); + //jasmine. singletons in here (setTimeout blah blah). + return env; + }; + + j$.isArray_ = function(value) { + return j$.isA_('Array', value); + }; + + j$.isString_ = function(value) { + return j$.isA_('String', value); + }; + + j$.isNumber_ = function(value) { + return j$.isA_('Number', value); + }; + + j$.isA_ = function(typeName, value) { + return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; + }; + + j$.isDomNode = function(obj) { + return obj.nodeType > 0; + }; + + j$.fnNameFor = function(func) { + return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1]; + }; + + j$.any = function(clazz) { + return new j$.Any(clazz); + }; + + j$.anything = function() { + return new j$.Anything(); + }; + + j$.objectContaining = function(sample) { + return new j$.ObjectContaining(sample); + }; + + j$.stringMatching = function(expected) { + return new j$.StringMatching(expected); + }; + + j$.arrayContaining = function(sample) { + return new j$.ArrayContaining(sample); + }; + + j$.createSpy = function(name, originalFn) { + + var spyStrategy = new j$.SpyStrategy({ + name: name, + fn: originalFn, + getSpy: function() { return spy; } + }), + callTracker = new j$.CallTracker(), + spy = function() { + var callData = { + object: this, + args: Array.prototype.slice.apply(arguments) + }; + + callTracker.track(callData); + var returnValue = spyStrategy.exec.apply(this, arguments); + callData.returnValue = returnValue; + + return returnValue; + }; + + for (var prop in originalFn) { + if (prop === 'and' || prop === 'calls') { + throw new Error('Jasmine spies would overwrite the \'and\' and \'calls\' properties on the object being spied upon'); + } + + spy[prop] = originalFn[prop]; + } + + spy.and = spyStrategy; + spy.calls = callTracker; + + return spy; + }; + + j$.isSpy = function(putativeSpy) { + if (!putativeSpy) { + return false; + } + return putativeSpy.and instanceof j$.SpyStrategy && + putativeSpy.calls instanceof j$.CallTracker; + }; + + j$.createSpyObj = function(baseName, methodNames) { + if (j$.isArray_(baseName) && j$.util.isUndefined(methodNames)) { + methodNames = baseName; + baseName = 'unknown'; + } + + if (!j$.isArray_(methodNames) || methodNames.length === 0) { + throw 'createSpyObj requires a non-empty array of method names to create spies for'; + } + var obj = {}; + for (var i = 0; i < methodNames.length; i++) { + obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]); + } + return obj; + }; +}; + +getJasmineRequireObj().util = function() { + + var util = {}; + + util.inherit = function(childClass, parentClass) { + var Subclass = function() { + }; + Subclass.prototype = parentClass.prototype; + childClass.prototype = new Subclass(); + }; + + util.htmlEscape = function(str) { + if (!str) { + return str; + } + return str.replace(/&/g, '&') + .replace(//g, '>'); + }; + + util.argsToArray = function(args) { + var arrayOfArgs = []; + for (var i = 0; i < args.length; i++) { + arrayOfArgs.push(args[i]); + } + return arrayOfArgs; + }; + + util.isUndefined = function(obj) { + return obj === void 0; + }; + + util.arrayContains = function(array, search) { + var i = array.length; + while (i--) { + if (array[i] === search) { + return true; + } + } + return false; + }; + + util.clone = function(obj) { + if (Object.prototype.toString.apply(obj) === '[object Array]') { + return obj.slice(); + } + + var cloned = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + cloned[prop] = obj[prop]; + } + } + + return cloned; + }; + + return util; +}; + +getJasmineRequireObj().Spec = function(j$) { + function Spec(attrs) { + this.expectationFactory = attrs.expectationFactory; + this.resultCallback = attrs.resultCallback || function() {}; + this.id = attrs.id; + this.description = attrs.description || ''; + this.queueableFn = attrs.queueableFn; + this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; }; + this.userContext = attrs.userContext || function() { return {}; }; + this.onStart = attrs.onStart || function() {}; + this.getSpecName = attrs.getSpecName || function() { return ''; }; + this.expectationResultFactory = attrs.expectationResultFactory || function() { }; + this.queueRunnerFactory = attrs.queueRunnerFactory || function() {}; + this.catchingExceptions = attrs.catchingExceptions || function() { return true; }; + this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure; + + if (!this.queueableFn.fn) { + this.pend(); + } + + this.result = { + id: this.id, + description: this.description, + fullName: this.getFullName(), + failedExpectations: [], + passedExpectations: [], + pendingReason: '' + }; + } + + Spec.prototype.addExpectationResult = function(passed, data, isError) { + var expectationResult = this.expectationResultFactory(data); + if (passed) { + this.result.passedExpectations.push(expectationResult); + } else { + this.result.failedExpectations.push(expectationResult); + + if (this.throwOnExpectationFailure && !isError) { + throw new j$.errors.ExpectationFailed(); + } + } + }; + + Spec.prototype.expect = function(actual) { + return this.expectationFactory(actual, this); + }; + + Spec.prototype.execute = function(onComplete, enabled) { + var self = this; + + this.onStart(this); + + if (!this.isExecutable() || this.markedPending || enabled === false) { + complete(enabled); + return; + } + + var fns = this.beforeAndAfterFns(); + var allFns = fns.befores.concat(this.queueableFn).concat(fns.afters); + + this.queueRunnerFactory({ + queueableFns: allFns, + onException: function() { self.onException.apply(self, arguments); }, + onComplete: complete, + userContext: this.userContext() + }); + + function complete(enabledAgain) { + self.result.status = self.status(enabledAgain); + self.resultCallback(self.result); + + if (onComplete) { + onComplete(); + } + } + }; + + Spec.prototype.onException = function onException(e) { + if (Spec.isPendingSpecException(e)) { + this.pend(extractCustomPendingMessage(e)); + return; + } + + if (e instanceof j$.errors.ExpectationFailed) { + return; + } + + this.addExpectationResult(false, { + matcherName: '', + passed: false, + expected: '', + actual: '', + error: e + }, true); + }; + + Spec.prototype.disable = function() { + this.disabled = true; + }; + + Spec.prototype.pend = function(message) { + this.markedPending = true; + if (message) { + this.result.pendingReason = message; + } + }; + + Spec.prototype.getResult = function() { + this.result.status = this.status(); + return this.result; + }; + + Spec.prototype.status = function(enabled) { + if (this.disabled || enabled === false) { + return 'disabled'; + } + + if (this.markedPending) { + return 'pending'; + } + + if (this.result.failedExpectations.length > 0) { + return 'failed'; + } else { + return 'passed'; + } + }; + + Spec.prototype.isExecutable = function() { + return !this.disabled; + }; + + Spec.prototype.getFullName = function() { + return this.getSpecName(this); + }; + + var extractCustomPendingMessage = function(e) { + var fullMessage = e.toString(), + boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage), + boilerplateEnd = boilerplateStart + Spec.pendingSpecExceptionMessage.length; + + return fullMessage.substr(boilerplateEnd); + }; + + Spec.pendingSpecExceptionMessage = '=> marked Pending'; + + Spec.isPendingSpecException = function(e) { + return !!(e && e.toString && e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1); + }; + + return Spec; +}; + +if (typeof window == void 0 && typeof exports == 'object') { + exports.Spec = jasmineRequire.Spec; +} + +/*jshint bitwise: false*/ + +getJasmineRequireObj().Order = function() { + function Order(options) { + this.random = 'random' in options ? options.random : true; + var seed = this.seed = options.seed || generateSeed(); + this.sort = this.random ? randomOrder : naturalOrder; + + function naturalOrder(items) { + return items; + } + + function randomOrder(items) { + var copy = items.slice(); + copy.sort(function(a, b) { + return jenkinsHash(seed + a.id) - jenkinsHash(seed + b.id); + }); + return copy; + } + + function generateSeed() { + return String(Math.random()).slice(-5); + } + + // Bob Jenkins One-at-a-Time Hash algorithm is a non-cryptographic hash function + // used to get a different output when the key changes slighly. + // We use your return to sort the children randomly in a consistent way when + // used in conjunction with a seed + + function jenkinsHash(key) { + var hash, i; + for(hash = i = 0; i < key.length; ++i) { + hash += key.charCodeAt(i); + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return hash; + } + + } + + return Order; +}; + +getJasmineRequireObj().Env = function(j$) { + function Env(options) { + options = options || {}; + + var self = this; + var global = options.global || j$.getGlobal(); + + var totalSpecsDefined = 0; + + var catchExceptions = true; + + var realSetTimeout = j$.getGlobal().setTimeout; + var realClearTimeout = j$.getGlobal().clearTimeout; + this.clock = new j$.Clock(global, function () { return new j$.DelayedFunctionScheduler(); }, new j$.MockDate(global)); + + var runnableLookupTable = {}; + var runnableResources = {}; + + var currentSpec = null; + var currentlyExecutingSuites = []; + var currentDeclarationSuite = null; + var throwOnExpectationFailure = false; + var random = false; + var seed = null; + + var currentSuite = function() { + return currentlyExecutingSuites[currentlyExecutingSuites.length - 1]; + }; + + var currentRunnable = function() { + return currentSpec || currentSuite(); + }; + + var reporter = new j$.ReportDispatcher([ + 'jasmineStarted', + 'jasmineDone', + 'suiteStarted', + 'suiteDone', + 'specStarted', + 'specDone' + ]); + + this.specFilter = function() { + return true; + }; + + this.addCustomEqualityTester = function(tester) { + if(!currentRunnable()) { + throw new Error('Custom Equalities must be added in a before function or a spec'); + } + runnableResources[currentRunnable().id].customEqualityTesters.push(tester); + }; + + this.addMatchers = function(matchersToAdd) { + if(!currentRunnable()) { + throw new Error('Matchers must be added in a before function or a spec'); + } + var customMatchers = runnableResources[currentRunnable().id].customMatchers; + for (var matcherName in matchersToAdd) { + customMatchers[matcherName] = matchersToAdd[matcherName]; + } + }; + + j$.Expectation.addCoreMatchers(j$.matchers); + + var nextSpecId = 0; + var getNextSpecId = function() { + return 'spec' + nextSpecId++; + }; + + var nextSuiteId = 0; + var getNextSuiteId = function() { + return 'suite' + nextSuiteId++; + }; + + var expectationFactory = function(actual, spec) { + return j$.Expectation.Factory({ + util: j$.matchersUtil, + customEqualityTesters: runnableResources[spec.id].customEqualityTesters, + customMatchers: runnableResources[spec.id].customMatchers, + actual: actual, + addExpectationResult: addExpectationResult + }); + + function addExpectationResult(passed, result) { + return spec.addExpectationResult(passed, result); + } + }; + + var defaultResourcesForRunnable = function(id, parentRunnableId) { + var resources = {spies: [], customEqualityTesters: [], customMatchers: {}}; + + if(runnableResources[parentRunnableId]){ + resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters); + resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers); + } + + runnableResources[id] = resources; + }; + + var clearResourcesForRunnable = function(id) { + spyRegistry.clearSpies(); + delete runnableResources[id]; + }; + + var beforeAndAfterFns = function(suite) { + return function() { + var befores = [], + afters = []; + + while(suite) { + befores = befores.concat(suite.beforeFns); + afters = afters.concat(suite.afterFns); + + suite = suite.parentSuite; + } + + return { + befores: befores.reverse(), + afters: afters + }; + }; + }; + + var getSpecName = function(spec, suite) { + return suite.getFullName() + ' ' + spec.description; + }; + + // TODO: we may just be able to pass in the fn instead of wrapping here + var buildExpectationResult = j$.buildExpectationResult, + exceptionFormatter = new j$.ExceptionFormatter(), + expectationResultFactory = function(attrs) { + attrs.messageFormatter = exceptionFormatter.message; + attrs.stackFormatter = exceptionFormatter.stack; + + return buildExpectationResult(attrs); + }; + + // TODO: fix this naming, and here's where the value comes in + this.catchExceptions = function(value) { + catchExceptions = !!value; + return catchExceptions; + }; + + this.catchingExceptions = function() { + return catchExceptions; + }; + + var maximumSpecCallbackDepth = 20; + var currentSpecCallbackDepth = 0; + + function clearStack(fn) { + currentSpecCallbackDepth++; + if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) { + currentSpecCallbackDepth = 0; + realSetTimeout(fn, 0); + } else { + fn(); + } + } + + var catchException = function(e) { + return j$.Spec.isPendingSpecException(e) || catchExceptions; + }; + + this.throwOnExpectationFailure = function(value) { + throwOnExpectationFailure = !!value; + }; + + this.throwingExpectationFailures = function() { + return throwOnExpectationFailure; + }; + + this.randomizeTests = function(value) { + random = !!value; + }; + + this.randomTests = function() { + return random; + }; + + this.seed = function(value) { + if (value) { + seed = value; + } + return seed; + }; + + var queueRunnerFactory = function(options) { + options.catchException = catchException; + options.clearStack = options.clearStack || clearStack; + options.timeout = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}; + options.fail = self.fail; + + new j$.QueueRunner(options).execute(); + }; + + var topSuite = new j$.Suite({ + env: this, + id: getNextSuiteId(), + description: 'Jasmine__TopLevel__Suite', + queueRunner: queueRunnerFactory + }); + runnableLookupTable[topSuite.id] = topSuite; + defaultResourcesForRunnable(topSuite.id); + currentDeclarationSuite = topSuite; + + this.topSuite = function() { + return topSuite; + }; + + this.execute = function(runnablesToRun) { + if(!runnablesToRun) { + if (focusedRunnables.length) { + runnablesToRun = focusedRunnables; + } else { + runnablesToRun = [topSuite.id]; + } + } + + var order = new j$.Order({ + random: random, + seed: seed + }); + + var processor = new j$.TreeProcessor({ + tree: topSuite, + runnableIds: runnablesToRun, + queueRunnerFactory: queueRunnerFactory, + nodeStart: function(suite) { + currentlyExecutingSuites.push(suite); + defaultResourcesForRunnable(suite.id, suite.parentSuite.id); + reporter.suiteStarted(suite.result); + }, + nodeComplete: function(suite, result) { + if (!suite.disabled) { + clearResourcesForRunnable(suite.id); + } + currentlyExecutingSuites.pop(); + reporter.suiteDone(result); + }, + orderChildren: function(node) { + return order.sort(node.children); + } + }); + + if(!processor.processTree().valid) { + throw new Error('Invalid order: would cause a beforeAll or afterAll to be run multiple times'); + } + + reporter.jasmineStarted({ + totalSpecsDefined: totalSpecsDefined + }); + + processor.execute(function() { + reporter.jasmineDone({ + order: order + }); + }); + }; + + this.addReporter = function(reporterToAdd) { + reporter.addReporter(reporterToAdd); + }; + + var spyRegistry = new j$.SpyRegistry({currentSpies: function() { + if(!currentRunnable()) { + throw new Error('Spies must be created in a before function or a spec'); + } + return runnableResources[currentRunnable().id].spies; + }}); + + this.spyOn = function() { + return spyRegistry.spyOn.apply(spyRegistry, arguments); + }; + + var suiteFactory = function(description) { + var suite = new j$.Suite({ + env: self, + id: getNextSuiteId(), + description: description, + parentSuite: currentDeclarationSuite, + expectationFactory: expectationFactory, + expectationResultFactory: expectationResultFactory, + throwOnExpectationFailure: throwOnExpectationFailure + }); + + runnableLookupTable[suite.id] = suite; + return suite; + }; + + this.describe = function(description, specDefinitions) { + var suite = suiteFactory(description); + if (specDefinitions.length > 0) { + throw new Error('describe does not expect a done parameter'); + } + if (currentDeclarationSuite.markedPending) { + suite.pend(); + } + addSpecsToSuite(suite, specDefinitions); + return suite; + }; + + this.xdescribe = function(description, specDefinitions) { + var suite = suiteFactory(description); + suite.pend(); + addSpecsToSuite(suite, specDefinitions); + return suite; + }; + + var focusedRunnables = []; + + this.fdescribe = function(description, specDefinitions) { + var suite = suiteFactory(description); + suite.isFocused = true; + + focusedRunnables.push(suite.id); + unfocusAncestor(); + addSpecsToSuite(suite, specDefinitions); + + return suite; + }; + + function addSpecsToSuite(suite, specDefinitions) { + var parentSuite = currentDeclarationSuite; + parentSuite.addChild(suite); + currentDeclarationSuite = suite; + + var declarationError = null; + try { + specDefinitions.call(suite); + } catch (e) { + declarationError = e; + } + + if (declarationError) { + self.it('encountered a declaration exception', function() { + throw declarationError; + }); + } + + currentDeclarationSuite = parentSuite; + } + + function findFocusedAncestor(suite) { + while (suite) { + if (suite.isFocused) { + return suite.id; + } + suite = suite.parentSuite; + } + + return null; + } + + function unfocusAncestor() { + var focusedAncestor = findFocusedAncestor(currentDeclarationSuite); + if (focusedAncestor) { + for (var i = 0; i < focusedRunnables.length; i++) { + if (focusedRunnables[i] === focusedAncestor) { + focusedRunnables.splice(i, 1); + break; + } + } + } + } + + var specFactory = function(description, fn, suite, timeout) { + totalSpecsDefined++; + var spec = new j$.Spec({ + id: getNextSpecId(), + beforeAndAfterFns: beforeAndAfterFns(suite), + expectationFactory: expectationFactory, + resultCallback: specResultCallback, + getSpecName: function(spec) { + return getSpecName(spec, suite); + }, + onStart: specStarted, + description: description, + expectationResultFactory: expectationResultFactory, + queueRunnerFactory: queueRunnerFactory, + userContext: function() { return suite.clonedSharedUserContext(); }, + queueableFn: { + fn: fn, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }, + throwOnExpectationFailure: throwOnExpectationFailure + }); + + runnableLookupTable[spec.id] = spec; + + if (!self.specFilter(spec)) { + spec.disable(); + } + + return spec; + + function specResultCallback(result) { + clearResourcesForRunnable(spec.id); + currentSpec = null; + reporter.specDone(result); + } + + function specStarted(spec) { + currentSpec = spec; + defaultResourcesForRunnable(spec.id, suite.id); + reporter.specStarted(spec.result); + } + }; + + this.it = function(description, fn, timeout) { + var spec = specFactory(description, fn, currentDeclarationSuite, timeout); + if (currentDeclarationSuite.markedPending) { + spec.pend(); + } + currentDeclarationSuite.addChild(spec); + return spec; + }; + + this.xit = function() { + var spec = this.it.apply(this, arguments); + spec.pend('Temporarily disabled with xit'); + return spec; + }; + + this.fit = function(description, fn, timeout){ + var spec = specFactory(description, fn, currentDeclarationSuite, timeout); + currentDeclarationSuite.addChild(spec); + focusedRunnables.push(spec.id); + unfocusAncestor(); + return spec; + }; + + this.expect = function(actual) { + if (!currentRunnable()) { + throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out'); + } + + return currentRunnable().expect(actual); + }; + + this.beforeEach = function(beforeEachFunction, timeout) { + currentDeclarationSuite.beforeEach({ + fn: beforeEachFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.beforeAll = function(beforeAllFunction, timeout) { + currentDeclarationSuite.beforeAll({ + fn: beforeAllFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.afterEach = function(afterEachFunction, timeout) { + currentDeclarationSuite.afterEach({ + fn: afterEachFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.afterAll = function(afterAllFunction, timeout) { + currentDeclarationSuite.afterAll({ + fn: afterAllFunction, + timeout: function() { return timeout || j$.DEFAULT_TIMEOUT_INTERVAL; } + }); + }; + + this.pending = function(message) { + var fullMessage = j$.Spec.pendingSpecExceptionMessage; + if(message) { + fullMessage += message; + } + throw fullMessage; + }; + + this.fail = function(error) { + var message = 'Failed'; + if (error) { + message += ': '; + message += error.message || error; + } + + currentRunnable().addExpectationResult(false, { + matcherName: '', + passed: false, + expected: '', + actual: '', + message: message, + error: error && error.message ? error : null + }); + }; + } + + return Env; +}; + +getJasmineRequireObj().JsApiReporter = function() { + + var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } + }; + + function JsApiReporter(options) { + var timer = options.timer || noopTimer, + status = 'loaded'; + + this.started = false; + this.finished = false; + this.runDetails = {}; + + this.jasmineStarted = function() { + this.started = true; + status = 'started'; + timer.start(); + }; + + var executionTime; + + this.jasmineDone = function(runDetails) { + this.finished = true; + this.runDetails = runDetails; + executionTime = timer.elapsed(); + status = 'done'; + }; + + this.status = function() { + return status; + }; + + var suites = [], + suites_hash = {}; + + this.suiteStarted = function(result) { + suites_hash[result.id] = result; + }; + + this.suiteDone = function(result) { + storeSuite(result); + }; + + this.suiteResults = function(index, length) { + return suites.slice(index, index + length); + }; + + function storeSuite(result) { + suites.push(result); + suites_hash[result.id] = result; + } + + this.suites = function() { + return suites_hash; + }; + + var specs = []; + + this.specDone = function(result) { + specs.push(result); + }; + + this.specResults = function(index, length) { + return specs.slice(index, index + length); + }; + + this.specs = function() { + return specs; + }; + + this.executionTime = function() { + return executionTime; + }; + + } + + return JsApiReporter; +}; + +getJasmineRequireObj().CallTracker = function() { + + function CallTracker() { + var calls = []; + + this.track = function(context) { + calls.push(context); + }; + + this.any = function() { + return !!calls.length; + }; + + this.count = function() { + return calls.length; + }; + + this.argsFor = function(index) { + var call = calls[index]; + return call ? call.args : []; + }; + + this.all = function() { + return calls; + }; + + this.allArgs = function() { + var callArgs = []; + for(var i = 0; i < calls.length; i++){ + callArgs.push(calls[i].args); + } + + return callArgs; + }; + + this.first = function() { + return calls[0]; + }; + + this.mostRecent = function() { + return calls[calls.length - 1]; + }; + + this.reset = function() { + calls = []; + }; + } + + return CallTracker; +}; + +getJasmineRequireObj().Clock = function() { + function Clock(global, delayedFunctionSchedulerFactory, mockDate) { + var self = this, + realTimingFunctions = { + setTimeout: global.setTimeout, + clearTimeout: global.clearTimeout, + setInterval: global.setInterval, + clearInterval: global.clearInterval + }, + fakeTimingFunctions = { + setTimeout: setTimeout, + clearTimeout: clearTimeout, + setInterval: setInterval, + clearInterval: clearInterval + }, + installed = false, + delayedFunctionScheduler, + timer; + + + self.install = function() { + if(!originalTimingFunctionsIntact()) { + throw new Error('Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?'); + } + replace(global, fakeTimingFunctions); + timer = fakeTimingFunctions; + delayedFunctionScheduler = delayedFunctionSchedulerFactory(); + installed = true; + + return self; + }; + + self.uninstall = function() { + delayedFunctionScheduler = null; + mockDate.uninstall(); + replace(global, realTimingFunctions); + + timer = realTimingFunctions; + installed = false; + }; + + self.withMock = function(closure) { + this.install(); + try { + closure(); + } finally { + this.uninstall(); + } + }; + + self.mockDate = function(initialDate) { + mockDate.install(initialDate); + }; + + self.setTimeout = function(fn, delay, params) { + if (legacyIE()) { + if (arguments.length > 2) { + throw new Error('IE < 9 cannot support extra params to setTimeout without a polyfill'); + } + return timer.setTimeout(fn, delay); + } + return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]); + }; + + self.setInterval = function(fn, delay, params) { + if (legacyIE()) { + if (arguments.length > 2) { + throw new Error('IE < 9 cannot support extra params to setInterval without a polyfill'); + } + return timer.setInterval(fn, delay); + } + return Function.prototype.apply.apply(timer.setInterval, [global, arguments]); + }; + + self.clearTimeout = function(id) { + return Function.prototype.call.apply(timer.clearTimeout, [global, id]); + }; + + self.clearInterval = function(id) { + return Function.prototype.call.apply(timer.clearInterval, [global, id]); + }; + + self.tick = function(millis) { + if (installed) { + mockDate.tick(millis); + delayedFunctionScheduler.tick(millis); + } else { + throw new Error('Mock clock is not installed, use jasmine.clock().install()'); + } + }; + + return self; + + function originalTimingFunctionsIntact() { + return global.setTimeout === realTimingFunctions.setTimeout && + global.clearTimeout === realTimingFunctions.clearTimeout && + global.setInterval === realTimingFunctions.setInterval && + global.clearInterval === realTimingFunctions.clearInterval; + } + + function legacyIE() { + //if these methods are polyfilled, apply will be present + return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply; + } + + function replace(dest, source) { + for (var prop in source) { + dest[prop] = source[prop]; + } + } + + function setTimeout(fn, delay) { + return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2)); + } + + function clearTimeout(id) { + return delayedFunctionScheduler.removeFunctionWithId(id); + } + + function setInterval(fn, interval) { + return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true); + } + + function clearInterval(id) { + return delayedFunctionScheduler.removeFunctionWithId(id); + } + + function argSlice(argsObj, n) { + return Array.prototype.slice.call(argsObj, n); + } + } + + return Clock; +}; + +getJasmineRequireObj().DelayedFunctionScheduler = function() { + function DelayedFunctionScheduler() { + var self = this; + var scheduledLookup = []; + var scheduledFunctions = {}; + var currentTime = 0; + var delayedFnCount = 0; + + self.tick = function(millis) { + millis = millis || 0; + var endTime = currentTime + millis; + + runScheduledFunctions(endTime); + currentTime = endTime; + }; + + self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) { + var f; + if (typeof(funcToCall) === 'string') { + /* jshint evil: true */ + f = function() { return eval(funcToCall); }; + /* jshint evil: false */ + } else { + f = funcToCall; + } + + millis = millis || 0; + timeoutKey = timeoutKey || ++delayedFnCount; + runAtMillis = runAtMillis || (currentTime + millis); + + var funcToSchedule = { + runAtMillis: runAtMillis, + funcToCall: f, + recurring: recurring, + params: params, + timeoutKey: timeoutKey, + millis: millis + }; + + if (runAtMillis in scheduledFunctions) { + scheduledFunctions[runAtMillis].push(funcToSchedule); + } else { + scheduledFunctions[runAtMillis] = [funcToSchedule]; + scheduledLookup.push(runAtMillis); + scheduledLookup.sort(function (a, b) { + return a - b; + }); + } + + return timeoutKey; + }; + + self.removeFunctionWithId = function(timeoutKey) { + for (var runAtMillis in scheduledFunctions) { + var funcs = scheduledFunctions[runAtMillis]; + var i = indexOfFirstToPass(funcs, function (func) { + return func.timeoutKey === timeoutKey; + }); + + if (i > -1) { + if (funcs.length === 1) { + delete scheduledFunctions[runAtMillis]; + deleteFromLookup(runAtMillis); + } else { + funcs.splice(i, 1); + } + + // intervals get rescheduled when executed, so there's never more + // than a single scheduled function with a given timeoutKey + break; + } + } + }; + + return self; + + function indexOfFirstToPass(array, testFn) { + var index = -1; + + for (var i = 0; i < array.length; ++i) { + if (testFn(array[i])) { + index = i; + break; + } + } + + return index; + } + + function deleteFromLookup(key) { + var value = Number(key); + var i = indexOfFirstToPass(scheduledLookup, function (millis) { + return millis === value; + }); + + if (i > -1) { + scheduledLookup.splice(i, 1); + } + } + + function reschedule(scheduledFn) { + self.scheduleFunction(scheduledFn.funcToCall, + scheduledFn.millis, + scheduledFn.params, + true, + scheduledFn.timeoutKey, + scheduledFn.runAtMillis + scheduledFn.millis); + } + + function forEachFunction(funcsToRun, callback) { + for (var i = 0; i < funcsToRun.length; ++i) { + callback(funcsToRun[i]); + } + } + + function runScheduledFunctions(endTime) { + if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) { + return; + } + + do { + currentTime = scheduledLookup.shift(); + + var funcsToRun = scheduledFunctions[currentTime]; + delete scheduledFunctions[currentTime]; + + forEachFunction(funcsToRun, function(funcToRun) { + if (funcToRun.recurring) { + reschedule(funcToRun); + } + }); + + forEachFunction(funcsToRun, function(funcToRun) { + funcToRun.funcToCall.apply(null, funcToRun.params || []); + }); + } while (scheduledLookup.length > 0 && + // checking first if we're out of time prevents setTimeout(0) + // scheduled in a funcToRun from forcing an extra iteration + currentTime !== endTime && + scheduledLookup[0] <= endTime); + } + } + + return DelayedFunctionScheduler; +}; + +getJasmineRequireObj().ExceptionFormatter = function() { + function ExceptionFormatter() { + this.message = function(error) { + var message = ''; + + if (error.name && error.message) { + message += error.name + ': ' + error.message; + } else { + message += error.toString() + ' thrown'; + } + + if (error.fileName || error.sourceURL) { + message += ' in ' + (error.fileName || error.sourceURL); + } + + if (error.line || error.lineNumber) { + message += ' (line ' + (error.line || error.lineNumber) + ')'; + } + + return message; + }; + + this.stack = function(error) { + return error ? error.stack : null; + }; + } + + return ExceptionFormatter; +}; + +getJasmineRequireObj().Expectation = function() { + + function Expectation(options) { + this.util = options.util || { buildFailureMessage: function() {} }; + this.customEqualityTesters = options.customEqualityTesters || []; + this.actual = options.actual; + this.addExpectationResult = options.addExpectationResult || function(){}; + this.isNot = options.isNot; + + var customMatchers = options.customMatchers || {}; + for (var matcherName in customMatchers) { + this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]); + } + } + + Expectation.prototype.wrapCompare = function(name, matcherFactory) { + return function() { + var args = Array.prototype.slice.call(arguments, 0), + expected = args.slice(0), + message = ''; + + args.unshift(this.actual); + + var matcher = matcherFactory(this.util, this.customEqualityTesters), + matcherCompare = matcher.compare; + + function defaultNegativeCompare() { + var result = matcher.compare.apply(null, args); + result.pass = !result.pass; + return result; + } + + if (this.isNot) { + matcherCompare = matcher.negativeCompare || defaultNegativeCompare; + } + + var result = matcherCompare.apply(null, args); + + if (!result.pass) { + if (!result.message) { + args.unshift(this.isNot); + args.unshift(name); + message = this.util.buildFailureMessage.apply(null, args); + } else { + if (Object.prototype.toString.apply(result.message) === '[object Function]') { + message = result.message(); + } else { + message = result.message; + } + } + } + + if (expected.length == 1) { + expected = expected[0]; + } + + // TODO: how many of these params are needed? + this.addExpectationResult( + result.pass, + { + matcherName: name, + passed: result.pass, + message: message, + actual: this.actual, + expected: expected // TODO: this may need to be arrayified/sliced + } + ); + }; + }; + + Expectation.addCoreMatchers = function(matchers) { + var prototype = Expectation.prototype; + for (var matcherName in matchers) { + var matcher = matchers[matcherName]; + prototype[matcherName] = prototype.wrapCompare(matcherName, matcher); + } + }; + + Expectation.Factory = function(options) { + options = options || {}; + + var expect = new Expectation(options); + + // TODO: this would be nice as its own Object - NegativeExpectation + // TODO: copy instead of mutate options + options.isNot = true; + expect.not = new Expectation(options); + + return expect; + }; + + return Expectation; +}; + +//TODO: expectation result may make more sense as a presentation of an expectation. +getJasmineRequireObj().buildExpectationResult = function() { + function buildExpectationResult(options) { + var messageFormatter = options.messageFormatter || function() {}, + stackFormatter = options.stackFormatter || function() {}; + + var result = { + matcherName: options.matcherName, + message: message(), + stack: stack(), + passed: options.passed + }; + + if(!result.passed) { + result.expected = options.expected; + result.actual = options.actual; + } + + return result; + + function message() { + if (options.passed) { + return 'Passed.'; + } else if (options.message) { + return options.message; + } else if (options.error) { + return messageFormatter(options.error); + } + return ''; + } + + function stack() { + if (options.passed) { + return ''; + } + + var error = options.error; + if (!error) { + try { + throw new Error(message()); + } catch (e) { + error = e; + } + } + return stackFormatter(error); + } + } + + return buildExpectationResult; +}; + +getJasmineRequireObj().MockDate = function() { + function MockDate(global) { + var self = this; + var currentTime = 0; + + if (!global || !global.Date) { + self.install = function() {}; + self.tick = function() {}; + self.uninstall = function() {}; + return self; + } + + var GlobalDate = global.Date; + + self.install = function(mockDate) { + if (mockDate instanceof GlobalDate) { + currentTime = mockDate.getTime(); + } else { + currentTime = new GlobalDate().getTime(); + } + + global.Date = FakeDate; + }; + + self.tick = function(millis) { + millis = millis || 0; + currentTime = currentTime + millis; + }; + + self.uninstall = function() { + currentTime = 0; + global.Date = GlobalDate; + }; + + createDateProperties(); + + return self; + + function FakeDate() { + switch(arguments.length) { + case 0: + return new GlobalDate(currentTime); + case 1: + return new GlobalDate(arguments[0]); + case 2: + return new GlobalDate(arguments[0], arguments[1]); + case 3: + return new GlobalDate(arguments[0], arguments[1], arguments[2]); + case 4: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3]); + case 5: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4]); + case 6: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4], arguments[5]); + default: + return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3], + arguments[4], arguments[5], arguments[6]); + } + } + + function createDateProperties() { + FakeDate.prototype = GlobalDate.prototype; + + FakeDate.now = function() { + if (GlobalDate.now) { + return currentTime; + } else { + throw new Error('Browser does not support Date.now()'); + } + }; + + FakeDate.toSource = GlobalDate.toSource; + FakeDate.toString = GlobalDate.toString; + FakeDate.parse = GlobalDate.parse; + FakeDate.UTC = GlobalDate.UTC; + } + } + + return MockDate; +}; + +getJasmineRequireObj().pp = function(j$) { + + function PrettyPrinter() { + this.ppNestLevel_ = 0; + this.seen = []; + } + + PrettyPrinter.prototype.format = function(value) { + this.ppNestLevel_++; + try { + if (j$.util.isUndefined(value)) { + this.emitScalar('undefined'); + } else if (value === null) { + this.emitScalar('null'); + } else if (value === 0 && 1/value === -Infinity) { + this.emitScalar('-0'); + } else if (value === j$.getGlobal()) { + this.emitScalar(''); + } else if (value.jasmineToString) { + this.emitScalar(value.jasmineToString()); + } else if (typeof value === 'string') { + this.emitString(value); + } else if (j$.isSpy(value)) { + this.emitScalar('spy on ' + value.and.identity()); + } else if (value instanceof RegExp) { + this.emitScalar(value.toString()); + } else if (typeof value === 'function') { + this.emitScalar('Function'); + } else if (typeof value.nodeType === 'number') { + this.emitScalar('HTMLNode'); + } else if (value instanceof Date) { + this.emitScalar('Date(' + value + ')'); + } else if (value.toString && typeof value === 'object' && !(value instanceof Array) && value.toString !== Object.prototype.toString) { + this.emitScalar(value.toString()); + } else if (j$.util.arrayContains(this.seen, value)) { + this.emitScalar(''); + } else if (j$.isArray_(value) || j$.isA_('Object', value)) { + this.seen.push(value); + if (j$.isArray_(value)) { + this.emitArray(value); + } else { + this.emitObject(value); + } + this.seen.pop(); + } else { + this.emitScalar(value.toString()); + } + } finally { + this.ppNestLevel_--; + } + }; + + PrettyPrinter.prototype.iterateObject = function(obj, fn) { + for (var property in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, property)) { continue; } + fn(property, obj.__lookupGetter__ ? (!j$.util.isUndefined(obj.__lookupGetter__(property)) && + obj.__lookupGetter__(property) !== null) : false); + } + }; + + PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_; + PrettyPrinter.prototype.emitString = j$.unimplementedMethod_; + + function StringPrettyPrinter() { + PrettyPrinter.call(this); + + this.string = ''; + } + + j$.util.inherit(StringPrettyPrinter, PrettyPrinter); + + StringPrettyPrinter.prototype.emitScalar = function(value) { + this.append(value); + }; + + StringPrettyPrinter.prototype.emitString = function(value) { + this.append('\'' + value + '\''); + }; + + StringPrettyPrinter.prototype.emitArray = function(array) { + if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { + this.append('Array'); + return; + } + var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH); + this.append('[ '); + for (var i = 0; i < length; i++) { + if (i > 0) { + this.append(', '); + } + this.format(array[i]); + } + if(array.length > length){ + this.append(', ...'); + } + + var self = this; + var first = array.length === 0; + this.iterateObject(array, function(property, isGetter) { + if (property.match(/^\d+$/)) { + return; + } + + if (first) { + first = false; + } else { + self.append(', '); + } + + self.formatProperty(array, property, isGetter); + }); + + this.append(' ]'); + }; + + StringPrettyPrinter.prototype.emitObject = function(obj) { + var constructorName = obj.constructor ? j$.fnNameFor(obj.constructor) : 'null'; + this.append(constructorName); + + if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) { + return; + } + + var self = this; + this.append('({ '); + var first = true; + + this.iterateObject(obj, function(property, isGetter) { + if (first) { + first = false; + } else { + self.append(', '); + } + + self.formatProperty(obj, property, isGetter); + }); + + this.append(' })'); + }; + + StringPrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) { + this.append(property); + this.append(': '); + if (isGetter) { + this.append(''); + } else { + this.format(obj[property]); + } + }; + + StringPrettyPrinter.prototype.append = function(value) { + this.string += value; + }; + + return function(value) { + var stringPrettyPrinter = new StringPrettyPrinter(); + stringPrettyPrinter.format(value); + return stringPrettyPrinter.string; + }; +}; + +getJasmineRequireObj().QueueRunner = function(j$) { + + function once(fn) { + var called = false; + return function() { + if (!called) { + called = true; + fn(); + } + }; + } + + function QueueRunner(attrs) { + this.queueableFns = attrs.queueableFns || []; + this.onComplete = attrs.onComplete || function() {}; + this.clearStack = attrs.clearStack || function(fn) {fn();}; + this.onException = attrs.onException || function() {}; + this.catchException = attrs.catchException || function() { return true; }; + this.userContext = attrs.userContext || {}; + this.timeout = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout}; + this.fail = attrs.fail || function() {}; + } + + QueueRunner.prototype.execute = function() { + this.run(this.queueableFns, 0); + }; + + QueueRunner.prototype.run = function(queueableFns, recursiveIndex) { + var length = queueableFns.length, + self = this, + iterativeIndex; + + + for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) { + var queueableFn = queueableFns[iterativeIndex]; + if (queueableFn.fn.length > 0) { + attemptAsync(queueableFn); + return; + } else { + attemptSync(queueableFn); + } + } + + var runnerDone = iterativeIndex >= length; + + if (runnerDone) { + this.clearStack(this.onComplete); + } + + function attemptSync(queueableFn) { + try { + queueableFn.fn.call(self.userContext); + } catch (e) { + handleException(e, queueableFn); + } + } + + function attemptAsync(queueableFn) { + var clearTimeout = function () { + Function.prototype.apply.apply(self.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]); + }, + next = once(function () { + clearTimeout(timeoutId); + self.run(queueableFns, iterativeIndex + 1); + }), + timeoutId; + + next.fail = function() { + self.fail.apply(null, arguments); + next(); + }; + + if (queueableFn.timeout) { + timeoutId = Function.prototype.apply.apply(self.timeout.setTimeout, [j$.getGlobal(), [function() { + var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'); + onException(error); + next(); + }, queueableFn.timeout()]]); + } + + try { + queueableFn.fn.call(self.userContext, next); + } catch (e) { + handleException(e, queueableFn); + next(); + } + } + + function onException(e) { + self.onException(e); + } + + function handleException(e, queueableFn) { + onException(e); + if (!self.catchException(e)) { + //TODO: set a var when we catch an exception and + //use a finally block to close the loop in a nice way.. + throw e; + } + } + }; + + return QueueRunner; +}; + +getJasmineRequireObj().ReportDispatcher = function() { + function ReportDispatcher(methods) { + + var dispatchedMethods = methods || []; + + for (var i = 0; i < dispatchedMethods.length; i++) { + var method = dispatchedMethods[i]; + this[method] = (function(m) { + return function() { + dispatch(m, arguments); + }; + }(method)); + } + + var reporters = []; + + this.addReporter = function(reporter) { + reporters.push(reporter); + }; + + return this; + + function dispatch(method, args) { + for (var i = 0; i < reporters.length; i++) { + var reporter = reporters[i]; + if (reporter[method]) { + reporter[method].apply(reporter, args); + } + } + } + } + + return ReportDispatcher; +}; + + +getJasmineRequireObj().SpyRegistry = function(j$) { + + function SpyRegistry(options) { + options = options || {}; + var currentSpies = options.currentSpies || function() { return []; }; + + this.spyOn = function(obj, methodName) { + if (j$.util.isUndefined(obj)) { + throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()'); + } + + if (j$.util.isUndefined(methodName)) { + throw new Error('No method name supplied'); + } + + if (j$.util.isUndefined(obj[methodName])) { + throw new Error(methodName + '() method does not exist'); + } + + if (obj[methodName] && j$.isSpy(obj[methodName])) { + //TODO?: should this return the current spy? Downside: may cause user confusion about spy state + throw new Error(methodName + ' has already been spied upon'); + } + + var descriptor; + try { + descriptor = Object.getOwnPropertyDescriptor(obj, methodName); + } catch(e) { + // IE 8 doesn't support `definePropery` on non-DOM nodes + } + + if (descriptor && !(descriptor.writable || descriptor.set)) { + throw new Error(methodName + ' is not declared writable or has no setter'); + } + + var spy = j$.createSpy(methodName, obj[methodName]); + + currentSpies().push({ + spy: spy, + baseObj: obj, + methodName: methodName, + originalValue: obj[methodName] + }); + + obj[methodName] = spy; + + return spy; + }; + + this.clearSpies = function() { + var spies = currentSpies(); + for (var i = 0; i < spies.length; i++) { + var spyEntry = spies[i]; + spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue; + } + }; + } + + return SpyRegistry; +}; + +getJasmineRequireObj().SpyStrategy = function() { + + function SpyStrategy(options) { + options = options || {}; + + var identity = options.name || 'unknown', + originalFn = options.fn || function() {}, + getSpy = options.getSpy || function() {}, + plan = function() {}; + + this.identity = function() { + return identity; + }; + + this.exec = function() { + return plan.apply(this, arguments); + }; + + this.callThrough = function() { + plan = originalFn; + return getSpy(); + }; + + this.returnValue = function(value) { + plan = function() { + return value; + }; + return getSpy(); + }; + + this.returnValues = function() { + var values = Array.prototype.slice.call(arguments); + plan = function () { + return values.shift(); + }; + return getSpy(); + }; + + this.throwError = function(something) { + var error = (something instanceof Error) ? something : new Error(something); + plan = function() { + throw error; + }; + return getSpy(); + }; + + this.callFake = function(fn) { + plan = fn; + return getSpy(); + }; + + this.stub = function(fn) { + plan = function() {}; + return getSpy(); + }; + } + + return SpyStrategy; +}; + +getJasmineRequireObj().Suite = function(j$) { + function Suite(attrs) { + this.env = attrs.env; + this.id = attrs.id; + this.parentSuite = attrs.parentSuite; + this.description = attrs.description; + this.expectationFactory = attrs.expectationFactory; + this.expectationResultFactory = attrs.expectationResultFactory; + this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure; + + this.beforeFns = []; + this.afterFns = []; + this.beforeAllFns = []; + this.afterAllFns = []; + this.disabled = false; + + this.children = []; + + this.result = { + id: this.id, + description: this.description, + fullName: this.getFullName(), + failedExpectations: [] + }; + } + + Suite.prototype.expect = function(actual) { + return this.expectationFactory(actual, this); + }; + + Suite.prototype.getFullName = function() { + var fullName = this.description; + for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { + if (parentSuite.parentSuite) { + fullName = parentSuite.description + ' ' + fullName; + } + } + return fullName; + }; + + Suite.prototype.disable = function() { + this.disabled = true; + }; + + Suite.prototype.pend = function(message) { + this.markedPending = true; + }; + + Suite.prototype.beforeEach = function(fn) { + this.beforeFns.unshift(fn); + }; + + Suite.prototype.beforeAll = function(fn) { + this.beforeAllFns.push(fn); + }; + + Suite.prototype.afterEach = function(fn) { + this.afterFns.unshift(fn); + }; + + Suite.prototype.afterAll = function(fn) { + this.afterAllFns.push(fn); + }; + + Suite.prototype.addChild = function(child) { + this.children.push(child); + }; + + Suite.prototype.status = function() { + if (this.disabled) { + return 'disabled'; + } + + if (this.markedPending) { + return 'pending'; + } + + if (this.result.failedExpectations.length > 0) { + return 'failed'; + } else { + return 'finished'; + } + }; + + Suite.prototype.isExecutable = function() { + return !this.disabled; + }; + + Suite.prototype.canBeReentered = function() { + return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0; + }; + + Suite.prototype.getResult = function() { + this.result.status = this.status(); + return this.result; + }; + + Suite.prototype.sharedUserContext = function() { + if (!this.sharedContext) { + this.sharedContext = this.parentSuite ? clone(this.parentSuite.sharedUserContext()) : {}; + } + + return this.sharedContext; + }; + + Suite.prototype.clonedSharedUserContext = function() { + return clone(this.sharedUserContext()); + }; + + Suite.prototype.onException = function() { + if (arguments[0] instanceof j$.errors.ExpectationFailed) { + return; + } + + if(isAfterAll(this.children)) { + var data = { + matcherName: '', + passed: false, + expected: '', + actual: '', + error: arguments[0] + }; + this.result.failedExpectations.push(this.expectationResultFactory(data)); + } else { + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + child.onException.apply(child, arguments); + } + } + }; + + Suite.prototype.addExpectationResult = function () { + if(isAfterAll(this.children) && isFailure(arguments)){ + var data = arguments[1]; + this.result.failedExpectations.push(this.expectationResultFactory(data)); + if(this.throwOnExpectationFailure) { + throw new j$.errors.ExpectationFailed(); + } + } else { + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + try { + child.addExpectationResult.apply(child, arguments); + } catch(e) { + // keep going + } + } + } + }; + + function isAfterAll(children) { + return children && children[0].result.status; + } + + function isFailure(args) { + return !args[0]; + } + + function clone(obj) { + var clonedObj = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + clonedObj[prop] = obj[prop]; + } + } + + return clonedObj; + } + + return Suite; +}; + +if (typeof window == void 0 && typeof exports == 'object') { + exports.Suite = jasmineRequire.Suite; +} + +getJasmineRequireObj().Timer = function() { + var defaultNow = (function(Date) { + return function() { return new Date().getTime(); }; + })(Date); + + function Timer(options) { + options = options || {}; + + var now = options.now || defaultNow, + startTime; + + this.start = function() { + startTime = now(); + }; + + this.elapsed = function() { + return now() - startTime; + }; + } + + return Timer; +}; + +getJasmineRequireObj().TreeProcessor = function() { + function TreeProcessor(attrs) { + var tree = attrs.tree, + runnableIds = attrs.runnableIds, + queueRunnerFactory = attrs.queueRunnerFactory, + nodeStart = attrs.nodeStart || function() {}, + nodeComplete = attrs.nodeComplete || function() {}, + orderChildren = attrs.orderChildren || function(node) { return node.children; }, + stats = { valid: true }, + processed = false, + defaultMin = Infinity, + defaultMax = 1 - Infinity; + + this.processTree = function() { + processNode(tree, false); + processed = true; + return stats; + }; + + this.execute = function(done) { + if (!processed) { + this.processTree(); + } + + if (!stats.valid) { + throw 'invalid order'; + } + + var childFns = wrapChildren(tree, 0); + + queueRunnerFactory({ + queueableFns: childFns, + userContext: tree.sharedUserContext(), + onException: function() { + tree.onException.apply(tree, arguments); + }, + onComplete: done + }); + }; + + function runnableIndex(id) { + for (var i = 0; i < runnableIds.length; i++) { + if (runnableIds[i] === id) { + return i; + } + } + } + + function processNode(node, parentEnabled) { + var executableIndex = runnableIndex(node.id); + + if (executableIndex !== undefined) { + parentEnabled = true; + } + + parentEnabled = parentEnabled && node.isExecutable(); + + if (!node.children) { + stats[node.id] = { + executable: parentEnabled && node.isExecutable(), + segments: [{ + index: 0, + owner: node, + nodes: [node], + min: startingMin(executableIndex), + max: startingMax(executableIndex) + }] + }; + } else { + var hasExecutableChild = false; + + var orderedChildren = orderChildren(node); + + for (var i = 0; i < orderedChildren.length; i++) { + var child = orderedChildren[i]; + + processNode(child, parentEnabled); + + if (!stats.valid) { + return; + } + + var childStats = stats[child.id]; + + hasExecutableChild = hasExecutableChild || childStats.executable; + } + + stats[node.id] = { + executable: hasExecutableChild + }; + + segmentChildren(node, orderedChildren, stats[node.id], executableIndex); + + if (!node.canBeReentered() && stats[node.id].segments.length > 1) { + stats = { valid: false }; + } + } + } + + function startingMin(executableIndex) { + return executableIndex === undefined ? defaultMin : executableIndex; + } + + function startingMax(executableIndex) { + return executableIndex === undefined ? defaultMax : executableIndex; + } + + function segmentChildren(node, orderedChildren, nodeStats, executableIndex) { + var currentSegment = { index: 0, owner: node, nodes: [], min: startingMin(executableIndex), max: startingMax(executableIndex) }, + result = [currentSegment], + lastMax = defaultMax, + orderedChildSegments = orderChildSegments(orderedChildren); + + function isSegmentBoundary(minIndex) { + return lastMax !== defaultMax && minIndex !== defaultMin && lastMax < minIndex - 1; + } + + for (var i = 0; i < orderedChildSegments.length; i++) { + var childSegment = orderedChildSegments[i], + maxIndex = childSegment.max, + minIndex = childSegment.min; + + if (isSegmentBoundary(minIndex)) { + currentSegment = {index: result.length, owner: node, nodes: [], min: defaultMin, max: defaultMax}; + result.push(currentSegment); + } + + currentSegment.nodes.push(childSegment); + currentSegment.min = Math.min(currentSegment.min, minIndex); + currentSegment.max = Math.max(currentSegment.max, maxIndex); + lastMax = maxIndex; + } + + nodeStats.segments = result; + } + + function orderChildSegments(children) { + var specifiedOrder = [], + unspecifiedOrder = []; + + for (var i = 0; i < children.length; i++) { + var child = children[i], + segments = stats[child.id].segments; + + for (var j = 0; j < segments.length; j++) { + var seg = segments[j]; + + if (seg.min === defaultMin) { + unspecifiedOrder.push(seg); + } else { + specifiedOrder.push(seg); + } + } + } + + specifiedOrder.sort(function(a, b) { + return a.min - b.min; + }); + + return specifiedOrder.concat(unspecifiedOrder); + } + + function executeNode(node, segmentNumber) { + if (node.children) { + return { + fn: function(done) { + nodeStart(node); + + queueRunnerFactory({ + onComplete: function() { + nodeComplete(node, node.getResult()); + done(); + }, + queueableFns: wrapChildren(node, segmentNumber), + userContext: node.sharedUserContext(), + onException: function() { + node.onException.apply(node, arguments); + } + }); + } + }; + } else { + return { + fn: function(done) { node.execute(done, stats[node.id].executable); } + }; + } + } + + function wrapChildren(node, segmentNumber) { + var result = [], + segmentChildren = stats[node.id].segments[segmentNumber].nodes; + + for (var i = 0; i < segmentChildren.length; i++) { + result.push(executeNode(segmentChildren[i].owner, segmentChildren[i].index)); + } + + if (!stats[node.id].executable) { + return result; + } + + return node.beforeAllFns.concat(result).concat(node.afterAllFns); + } + } + + return TreeProcessor; +}; + +getJasmineRequireObj().Any = function(j$) { + + function Any(expectedObject) { + if (typeof expectedObject === 'undefined') { + throw new TypeError( + 'jasmine.any() expects to be passed a constructor function. ' + + 'Please pass one or use jasmine.anything() to match any object.' + ); + } + this.expectedObject = expectedObject; + } + + Any.prototype.asymmetricMatch = function(other) { + if (this.expectedObject == String) { + return typeof other == 'string' || other instanceof String; + } + + if (this.expectedObject == Number) { + return typeof other == 'number' || other instanceof Number; + } + + if (this.expectedObject == Function) { + return typeof other == 'function' || other instanceof Function; + } + + if (this.expectedObject == Object) { + return typeof other == 'object'; + } + + if (this.expectedObject == Boolean) { + return typeof other == 'boolean'; + } + + return other instanceof this.expectedObject; + }; + + Any.prototype.jasmineToString = function() { + return ''; + }; + + return Any; +}; + +getJasmineRequireObj().Anything = function(j$) { + + function Anything() {} + + Anything.prototype.asymmetricMatch = function(other) { + return !j$.util.isUndefined(other) && other !== null; + }; + + Anything.prototype.jasmineToString = function() { + return ''; + }; + + return Anything; +}; + +getJasmineRequireObj().ArrayContaining = function(j$) { + function ArrayContaining(sample) { + this.sample = sample; + } + + ArrayContaining.prototype.asymmetricMatch = function(other) { + var className = Object.prototype.toString.call(this.sample); + if (className !== '[object Array]') { throw new Error('You must provide an array to arrayContaining, not \'' + this.sample + '\'.'); } + + for (var i = 0; i < this.sample.length; i++) { + var item = this.sample[i]; + if (!j$.matchersUtil.contains(other, item)) { + return false; + } + } + + return true; + }; + + ArrayContaining.prototype.jasmineToString = function () { + return ''; + }; + + return ArrayContaining; +}; + +getJasmineRequireObj().ObjectContaining = function(j$) { + + function ObjectContaining(sample) { + this.sample = sample; + } + + function getPrototype(obj) { + if (Object.getPrototypeOf) { + return Object.getPrototypeOf(obj); + } + + if (obj.constructor.prototype == obj) { + return null; + } + + return obj.constructor.prototype; + } + + function hasProperty(obj, property) { + if (!obj) { + return false; + } + + if (Object.prototype.hasOwnProperty.call(obj, property)) { + return true; + } + + return hasProperty(getPrototype(obj), property); + } + + ObjectContaining.prototype.asymmetricMatch = function(other) { + if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); } + + for (var property in this.sample) { + if (!hasProperty(other, property) || + !j$.matchersUtil.equals(this.sample[property], other[property])) { + return false; + } + } + + return true; + }; + + ObjectContaining.prototype.jasmineToString = function() { + return ''; + }; + + return ObjectContaining; +}; + +getJasmineRequireObj().StringMatching = function(j$) { + + function StringMatching(expected) { + if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { + throw new Error('Expected is not a String or a RegExp'); + } + + this.regexp = new RegExp(expected); + } + + StringMatching.prototype.asymmetricMatch = function(other) { + return this.regexp.test(other); + }; + + StringMatching.prototype.jasmineToString = function() { + return ''; + }; + + return StringMatching; +}; + +getJasmineRequireObj().errors = function() { + function ExpectationFailed() {} + + ExpectationFailed.prototype = new Error(); + ExpectationFailed.prototype.constructor = ExpectationFailed; + + return { + ExpectationFailed: ExpectationFailed + }; +}; +getJasmineRequireObj().matchersUtil = function(j$) { + // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter? + + return { + equals: function(a, b, customTesters) { + customTesters = customTesters || []; + + return eq(a, b, [], [], customTesters); + }, + + contains: function(haystack, needle, customTesters) { + customTesters = customTesters || []; + + if ((Object.prototype.toString.apply(haystack) === '[object Array]') || + (!!haystack && !haystack.indexOf)) + { + for (var i = 0; i < haystack.length; i++) { + if (eq(haystack[i], needle, [], [], customTesters)) { + return true; + } + } + return false; + } + + return !!haystack && haystack.indexOf(needle) >= 0; + }, + + buildFailureMessage: function() { + var args = Array.prototype.slice.call(arguments, 0), + matcherName = args[0], + isNot = args[1], + actual = args[2], + expected = args.slice(3), + englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); + + var message = 'Expected ' + + j$.pp(actual) + + (isNot ? ' not ' : ' ') + + englishyPredicate; + + if (expected.length > 0) { + for (var i = 0; i < expected.length; i++) { + if (i > 0) { + message += ','; + } + message += ' ' + j$.pp(expected[i]); + } + } + + return message + '.'; + } + }; + + function isAsymmetric(obj) { + return obj && j$.isA_('Function', obj.asymmetricMatch); + } + + function asymmetricMatch(a, b) { + var asymmetricA = isAsymmetric(a), + asymmetricB = isAsymmetric(b); + + if (asymmetricA && asymmetricB) { + return undefined; + } + + if (asymmetricA) { + return a.asymmetricMatch(b); + } + + if (asymmetricB) { + return b.asymmetricMatch(a); + } + } + + // Equality function lovingly adapted from isEqual in + // [Underscore](http://underscorejs.org) + function eq(a, b, aStack, bStack, customTesters) { + var result = true; + + var asymmetricResult = asymmetricMatch(a, b); + if (!j$.util.isUndefined(asymmetricResult)) { + return asymmetricResult; + } + + for (var i = 0; i < customTesters.length; i++) { + var customTesterResult = customTesters[i](a, b); + if (!j$.util.isUndefined(customTesterResult)) { + return customTesterResult; + } + } + + if (a instanceof Error && b instanceof Error) { + return a.message == b.message; + } + + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) { return a !== 0 || 1 / a == 1 / b; } + // A strict comparison is necessary because `null == undefined`. + if (a === null || b === null) { return a === b; } + var className = Object.prototype.toString.call(a); + if (className != Object.prototype.toString.call(b)) { return false; } + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') { return false; } + + var aIsDomNode = j$.isDomNode(a); + var bIsDomNode = j$.isDomNode(b); + if (aIsDomNode && bIsDomNode) { + // At first try to use DOM3 method isEqualNode + if (a.isEqualNode) { + return a.isEqualNode(b); + } + // IE8 doesn't support isEqualNode, try to use outerHTML && innerText + var aIsElement = a instanceof Element; + var bIsElement = b instanceof Element; + if (aIsElement && bIsElement) { + return a.outerHTML == b.outerHTML; + } + if (aIsElement || bIsElement) { + return false; + } + return a.innerText == b.innerText && a.textContent == b.textContent; + } + if (aIsDomNode || bIsDomNode) { + return false; + } + + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] == a) { return bStack[length] == b; } + } + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + var size = 0; + // Recursively compare objects and arrays. + // Compare array lengths to determine if a deep comparison is necessary. + if (className == '[object Array]' && a.length !== b.length) { + result = false; + } + + if (result) { + // Objects with different constructors are not equivalent, but `Object`s + // or `Array`s from different frames are. + if (className !== '[object Array]') { + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(isFunction(aCtor) && aCtor instanceof aCtor && + isFunction(bCtor) && bCtor instanceof bCtor)) { + return false; + } + } + // Deep compare objects. + for (var key in a) { + if (has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) { break; } + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (has(b, key) && !(size--)) { break; } + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + + return result; + + function has(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); + } + + function isFunction(obj) { + return typeof obj === 'function'; + } + } +}; + +getJasmineRequireObj().toBe = function() { + function toBe() { + return { + compare: function(actual, expected) { + return { + pass: actual === expected + }; + } + }; + } + + return toBe; +}; + +getJasmineRequireObj().toBeCloseTo = function() { + + function toBeCloseTo() { + return { + compare: function(actual, expected, precision) { + if (precision !== 0) { + precision = precision || 2; + } + + return { + pass: Math.abs(expected - actual) < (Math.pow(10, -precision) / 2) + }; + } + }; + } + + return toBeCloseTo; +}; + +getJasmineRequireObj().toBeDefined = function() { + function toBeDefined() { + return { + compare: function(actual) { + return { + pass: (void 0 !== actual) + }; + } + }; + } + + return toBeDefined; +}; + +getJasmineRequireObj().toBeFalsy = function() { + function toBeFalsy() { + return { + compare: function(actual) { + return { + pass: !!!actual + }; + } + }; + } + + return toBeFalsy; +}; + +getJasmineRequireObj().toBeGreaterThan = function() { + + function toBeGreaterThan() { + return { + compare: function(actual, expected) { + return { + pass: actual > expected + }; + } + }; + } + + return toBeGreaterThan; +}; + + +getJasmineRequireObj().toBeLessThan = function() { + function toBeLessThan() { + return { + + compare: function(actual, expected) { + return { + pass: actual < expected + }; + } + }; + } + + return toBeLessThan; +}; +getJasmineRequireObj().toBeNaN = function(j$) { + + function toBeNaN() { + return { + compare: function(actual) { + var result = { + pass: (actual !== actual) + }; + + if (result.pass) { + result.message = 'Expected actual not to be NaN.'; + } else { + result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be NaN.'; }; + } + + return result; + } + }; + } + + return toBeNaN; +}; + +getJasmineRequireObj().toBeNull = function() { + + function toBeNull() { + return { + compare: function(actual) { + return { + pass: actual === null + }; + } + }; + } + + return toBeNull; +}; + +getJasmineRequireObj().toBeTruthy = function() { + + function toBeTruthy() { + return { + compare: function(actual) { + return { + pass: !!actual + }; + } + }; + } + + return toBeTruthy; +}; + +getJasmineRequireObj().toBeUndefined = function() { + + function toBeUndefined() { + return { + compare: function(actual) { + return { + pass: void 0 === actual + }; + } + }; + } + + return toBeUndefined; +}; + +getJasmineRequireObj().toContain = function() { + function toContain(util, customEqualityTesters) { + customEqualityTesters = customEqualityTesters || []; + + return { + compare: function(actual, expected) { + + return { + pass: util.contains(actual, expected, customEqualityTesters) + }; + } + }; + } + + return toContain; +}; + +getJasmineRequireObj().toEqual = function() { + + function toEqual(util, customEqualityTesters) { + customEqualityTesters = customEqualityTesters || []; + + return { + compare: function(actual, expected) { + var result = { + pass: false + }; + + result.pass = util.equals(actual, expected, customEqualityTesters); + + return result; + } + }; + } + + return toEqual; +}; + +getJasmineRequireObj().toHaveBeenCalled = function(j$) { + + function toHaveBeenCalled() { + return { + compare: function(actual) { + var result = {}; + + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + if (arguments.length > 1) { + throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); + } + + result.pass = actual.calls.any(); + + result.message = result.pass ? + 'Expected spy ' + actual.and.identity() + ' not to have been called.' : + 'Expected spy ' + actual.and.identity() + ' to have been called.'; + + return result; + } + }; + } + + return toHaveBeenCalled; +}; + +getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) { + + function toHaveBeenCalledTimes() { + return { + compare: function(actual, expected) { + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + var args = Array.prototype.slice.call(arguments, 0), + result = { pass: false }; + + if(!expected){ + throw new Error('Expected times failed is required as an argument.'); + } + + actual = args[0]; + var calls = actual.calls.count(); + var timesMessage = expected === 1 ? 'once' : expected + ' times'; + result.pass = calls === expected; + result.message = result.pass ? + 'Expected spy ' + actual.and.identity() + ' not to have been called ' + timesMessage + '. It was called ' + calls + ' times.' : + 'Expected spy ' + actual.and.identity() + ' to have been called ' + timesMessage + '. It was called ' + calls + ' times.'; + return result; + } + }; + } + + return toHaveBeenCalledTimes; +}; + +getJasmineRequireObj().toHaveBeenCalledWith = function(j$) { + + function toHaveBeenCalledWith(util, customEqualityTesters) { + return { + compare: function() { + var args = Array.prototype.slice.call(arguments, 0), + actual = args[0], + expectedArgs = args.slice(1), + result = { pass: false }; + + if (!j$.isSpy(actual)) { + throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.'); + } + + if (!actual.calls.any()) { + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but it was never called.'; }; + return result; + } + + if (util.contains(actual.calls.allArgs(), expectedArgs, customEqualityTesters)) { + result.pass = true; + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' not to have been called with ' + j$.pp(expectedArgs) + ' but it was.'; }; + } else { + result.message = function() { return 'Expected spy ' + actual.and.identity() + ' to have been called with ' + j$.pp(expectedArgs) + ' but actual calls were ' + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + '.'; }; + } + + return result; + } + }; + } + + return toHaveBeenCalledWith; +}; + +getJasmineRequireObj().toMatch = function(j$) { + + function toMatch() { + return { + compare: function(actual, expected) { + if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { + throw new Error('Expected is not a String or a RegExp'); + } + + var regexp = new RegExp(expected); + + return { + pass: regexp.test(actual) + }; + } + }; + } + + return toMatch; +}; + +getJasmineRequireObj().toThrow = function(j$) { + + function toThrow(util) { + return { + compare: function(actual, expected) { + var result = { pass: false }, + threw = false, + thrown; + + if (typeof actual != 'function') { + throw new Error('Actual is not a Function'); + } + + try { + actual(); + } catch (e) { + threw = true; + thrown = e; + } + + if (!threw) { + result.message = 'Expected function to throw an exception.'; + return result; + } + + if (arguments.length == 1) { + result.pass = true; + result.message = function() { return 'Expected function not to throw, but it threw ' + j$.pp(thrown) + '.'; }; + + return result; + } + + if (util.equals(thrown, expected)) { + result.pass = true; + result.message = function() { return 'Expected function not to throw ' + j$.pp(expected) + '.'; }; + } else { + result.message = function() { return 'Expected function to throw ' + j$.pp(expected) + ', but it threw ' + j$.pp(thrown) + '.'; }; + } + + return result; + } + }; + } + + return toThrow; +}; + +getJasmineRequireObj().toThrowError = function(j$) { + function toThrowError () { + return { + compare: function(actual) { + var threw = false, + pass = {pass: true}, + fail = {pass: false}, + thrown; + + if (typeof actual != 'function') { + throw new Error('Actual is not a Function'); + } + + var errorMatcher = getMatcher.apply(null, arguments); + + try { + actual(); + } catch (e) { + threw = true; + thrown = e; + } + + if (!threw) { + fail.message = 'Expected function to throw an Error.'; + return fail; + } + + if (!(thrown instanceof Error)) { + fail.message = function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; }; + return fail; + } + + if (errorMatcher.hasNoSpecifics()) { + pass.message = 'Expected function not to throw an Error, but it threw ' + j$.fnNameFor(thrown) + '.'; + return pass; + } + + if (errorMatcher.matches(thrown)) { + pass.message = function() { + return 'Expected function not to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + '.'; + }; + return pass; + } else { + fail.message = function() { + return 'Expected function to throw ' + errorMatcher.errorTypeDescription + errorMatcher.messageDescription() + + ', but it threw ' + errorMatcher.thrownDescription(thrown) + '.'; + }; + return fail; + } + } + }; + + function getMatcher() { + var expected = null, + errorType = null; + + if (arguments.length == 2) { + expected = arguments[1]; + if (isAnErrorType(expected)) { + errorType = expected; + expected = null; + } + } else if (arguments.length > 2) { + errorType = arguments[1]; + expected = arguments[2]; + if (!isAnErrorType(errorType)) { + throw new Error('Expected error type is not an Error.'); + } + } + + if (expected && !isStringOrRegExp(expected)) { + if (errorType) { + throw new Error('Expected error message is not a string or RegExp.'); + } else { + throw new Error('Expected is not an Error, string, or RegExp.'); + } + } + + function messageMatch(message) { + if (typeof expected == 'string') { + return expected == message; + } else { + return expected.test(message); + } + } + + return { + errorTypeDescription: errorType ? j$.fnNameFor(errorType) : 'an exception', + thrownDescription: function(thrown) { + var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception', + thrownMessage = ''; + + if (expected) { + thrownMessage = ' with message ' + j$.pp(thrown.message); + } + + return thrownName + thrownMessage; + }, + messageDescription: function() { + if (expected === null) { + return ''; + } else if (expected instanceof RegExp) { + return ' with a message matching ' + j$.pp(expected); + } else { + return ' with message ' + j$.pp(expected); + } + }, + hasNoSpecifics: function() { + return expected === null && errorType === null; + }, + matches: function(error) { + return (errorType === null || error instanceof errorType) && + (expected === null || messageMatch(error.message)); + } + }; + } + + function isStringOrRegExp(potential) { + return potential instanceof RegExp || (typeof potential == 'string'); + } + + function isAnErrorType(type) { + if (typeof type !== 'function') { + return false; + } + + var Surrogate = function() {}; + Surrogate.prototype = type.prototype; + return (new Surrogate()) instanceof Error; + } + } + + return toThrowError; +}; + +getJasmineRequireObj().interface = function(jasmine, env) { + var jasmineInterface = { + describe: function(description, specDefinitions) { + return env.describe(description, specDefinitions); + }, + + xdescribe: function(description, specDefinitions) { + return env.xdescribe(description, specDefinitions); + }, + + fdescribe: function(description, specDefinitions) { + return env.fdescribe(description, specDefinitions); + }, + + it: function() { + return env.it.apply(env, arguments); + }, + + xit: function() { + return env.xit.apply(env, arguments); + }, + + fit: function() { + return env.fit.apply(env, arguments); + }, + + beforeEach: function() { + return env.beforeEach.apply(env, arguments); + }, + + afterEach: function() { + return env.afterEach.apply(env, arguments); + }, + + beforeAll: function() { + return env.beforeAll.apply(env, arguments); + }, + + afterAll: function() { + return env.afterAll.apply(env, arguments); + }, + + expect: function(actual) { + return env.expect(actual); + }, + + pending: function() { + return env.pending.apply(env, arguments); + }, + + fail: function() { + return env.fail.apply(env, arguments); + }, + + spyOn: function(obj, methodName) { + return env.spyOn(obj, methodName); + }, + + jsApiReporter: new jasmine.JsApiReporter({ + timer: new jasmine.Timer() + }), + + jasmine: jasmine + }; + + jasmine.addCustomEqualityTester = function(tester) { + env.addCustomEqualityTester(tester); + }; + + jasmine.addMatchers = function(matchers) { + return env.addMatchers(matchers); + }; + + jasmine.clock = function() { + return env.clock; + }; + + return jasmineInterface; +}; + +getJasmineRequireObj().version = function() { + return '2.4.1'; +}; diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/json2.js b/www/node_modules/jasmine-core/lib/jasmine-core/json2.js new file mode 100644 index 0000000..deb88ec --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/json2.js @@ -0,0 +1,489 @@ +/* + json2.js + 2014-02-04 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function () { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function () { + return this.valueOf(); + }; + } + + var cx, + escapable, + gap, + indent, + meta, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }; + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); diff --git a/www/node_modules/jasmine-core/lib/jasmine-core/node_boot.js b/www/node_modules/jasmine-core/lib/jasmine-core/node_boot.js new file mode 100644 index 0000000..a0fc4a2 --- /dev/null +++ b/www/node_modules/jasmine-core/lib/jasmine-core/node_boot.js @@ -0,0 +1,41 @@ +/* +Copyright (c) 2008-2015 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +module.exports = function(jasmineRequire) { + var jasmine = jasmineRequire.core(jasmineRequire); + + var consoleFns = require('../console/console.js'); + consoleFns.console(consoleFns, jasmine); + + var env = jasmine.getEnv(); + + var jasmineInterface = jasmineRequire.interface(jasmine, env); + + extend(global, jasmineInterface); + + function extend(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; + } + + return jasmine; +}; diff --git a/www/node_modules/jasmine-core/package.json b/www/node_modules/jasmine-core/package.json new file mode 100644 index 0000000..5ca02ee --- /dev/null +++ b/www/node_modules/jasmine-core/package.json @@ -0,0 +1,90 @@ +{ + "_args": [ + [ + "jasmine-core@~2.4.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine" + ] + ], + "_from": "jasmine-core@>=2.4.0 <2.5.0", + "_id": "jasmine-core@2.4.1", + "_inCache": true, + "_installable": true, + "_location": "/jasmine-core", + "_nodeVersion": "0.12.7", + "_npmUser": { + "email": "gregg@slackersoft.net", + "name": "slackersoft" + }, + "_npmVersion": "2.12.1", + "_phantomChildren": {}, + "_requested": { + "name": "jasmine-core", + "raw": "jasmine-core@~2.4.0", + "rawSpec": "~2.4.0", + "scope": null, + "spec": ">=2.4.0 <2.5.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine" + ], + "_resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.4.1.tgz", + "_shasum": "6f83ab3a0f16951722ce07d206c773d57cc838be", + "_shrinkwrap": null, + "_spec": "jasmine-core@~2.4.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine", + "bugs": { + "url": "https://github.com/jasmine/jasmine/issues" + }, + "dependencies": {}, + "description": "Official packaging of Jasmine's core files for use by Node.js projects.", + "devDependencies": { + "glob": "~5.0.13", + "grunt": "~0.4.1", + "grunt-cli": "^0.1.13", + "grunt-contrib-compass": "~0.6.0", + "grunt-contrib-compress": "~0.5.2", + "grunt-contrib-concat": "~0.3.0", + "grunt-contrib-jshint": "~0.7.0", + "jasmine": "git://github.com/jasmine/jasmine-npm.git", + "load-grunt-tasks": "^0.4.0", + "shelljs": "~0.1.4", + "temp": "~0.8.1" + }, + "directories": {}, + "dist": { + "shasum": "6f83ab3a0f16951722ce07d206c773d57cc838be", + "tarball": "http://registry.npmjs.org/jasmine-core/-/jasmine-core-2.4.1.tgz" + }, + "gitHead": "a95c2cfe3f80921ec6bc061d5fcc0b2368586666", + "homepage": "http://jasmine.github.io", + "keywords": [ + "test", + "jasmine", + "tdd", + "bdd" + ], + "license": "MIT", + "main": "./lib/jasmine-core.js", + "maintainers": [ + { + "email": "dwfrank@pivotallabs.com", + "name": "dwfrank" + }, + { + "email": "gregg@slackersoft.net", + "name": "slackersoft" + } + ], + "name": "jasmine-core", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jasmine/jasmine.git" + }, + "scripts": { + "test": "grunt jshint execSpecsInNode" + }, + "version": "2.4.1" +} diff --git a/www/node_modules/jasmine-core/requirements.txt b/www/node_modules/jasmine-core/requirements.txt new file mode 100644 index 0000000..591279c --- /dev/null +++ b/www/node_modules/jasmine-core/requirements.txt @@ -0,0 +1 @@ +ordereddict==1.1 diff --git a/www/node_modules/jasmine/.travis.yml b/www/node_modules/jasmine/.travis.yml new file mode 100644 index 0000000..ba260f3 --- /dev/null +++ b/www/node_modules/jasmine/.travis.yml @@ -0,0 +1,5 @@ +--- +language: node_js +sudo: false +before_script: + - npm install git+https://github.com/jasmine/jasmine.git diff --git a/www/node_modules/jasmine/Gruntfile.js b/www/node_modules/jasmine/Gruntfile.js new file mode 100644 index 0000000..f5af99e --- /dev/null +++ b/www/node_modules/jasmine/Gruntfile.js @@ -0,0 +1,44 @@ +module.exports = function(grunt) { + var pkg = require("./package.json"); + global.jasmineVersion = pkg.version; + var versionString = 'v' + pkg.version; + + grunt.initConfig({ + pkg: pkg, + jshint: {all: ['lib/**/*.js', 'spec/**/*.js']} + }); + + var shell = require('shelljs'); + function runCommands(commands, done) { + var command = commands.shift(); + + if (command) { + shell.exec(command, function(exitCode) { + if (exitCode !== 0) { + grunt.fail.fatal("Command `" + command + "` failed", exitCode); + done(); + } else { + runCommands(commands, done); + } + }); + } else { + done(); + } + } + + // depend on jshint:all, specs? + grunt.registerTask('release', + 'Create tag ' + versionString + ' and push jasmine-' + pkg.version + ' to NPM', + function() { + var done = this.async(), + commands = ['git tag ' + versionString, 'git push origin master --tags', 'npm publish']; + + runCommands(commands, done); + }); + + grunt.loadNpmTasks('grunt-contrib-jshint'); + + grunt.loadTasks('tasks'); + + grunt.registerTask('default', ['jshint:all', 'specs']); +}; diff --git a/www/node_modules/jasmine/README.md b/www/node_modules/jasmine/README.md new file mode 100644 index 0000000..26a517a --- /dev/null +++ b/www/node_modules/jasmine/README.md @@ -0,0 +1,48 @@ +[![Build Status](https://travis-ci.org/jasmine/jasmine-npm.png?branch=master)](https://travis-ci.org/jasmine/jasmine-npm) + +# The Jasmine Module + +The [Jasmine](https://github.com/jasmine/jasmine) module is a package of helper code for developing Jasmine projects for Node.js. + +## Contents + +This module allows you to run Jasmine specs for your Node.js code. The output will be displayed in your terminal. + +## Installation + +`npm install -g jasmine` + +## Initializing + +To initialize a project for Jasmine + +`jasmine init` + +To seed your project with some examples + +`jasmine examples` + +## Usage + +To run your test suite + +`jasmine` + +## Configuration + +Customize `spec/support/jasmine.json` to enumerate the source and spec files you would like the Jasmine runner to include. +You may use dir glob strings. +More information on the format of `jasmine.json` can be found in [the documentation](http://jasmine.github.io/2.3/node.html#section-Configuration) + +Alternatively, you may specify the path to your `jasmine.json` by setting an environment variable: + +`jasmine JASMINE_CONFIG_PATH=relative/path/to/your/jasmine.json` + +## Support + +Jasmine Mailing list: [jasmine-js@googlegroups.com](mailto:jasmine-js@googlegroups.com) +Twitter: [@jasminebdd](http://twitter.com/jasminebdd) + +Please file issues here at Github + +Copyright (c) 2008-2013 Pivotal Labs. This software is licensed under the MIT License. diff --git a/www/node_modules/jasmine/bin/jasmine.js b/www/node_modules/jasmine/bin/jasmine.js new file mode 100755 index 0000000..5b514ea --- /dev/null +++ b/www/node_modules/jasmine/bin/jasmine.js @@ -0,0 +1,11 @@ +#!/usr/bin/env node + +var path = require('path'), + Command = require('../lib/command.js'), + Jasmine = require('../lib/jasmine.js'); + +var jasmine = new Jasmine({ projectBaseDir: path.resolve() }); +var examplesDir = path.join(__dirname, '..', 'node_modules', 'jasmine-core', 'lib', 'jasmine-core', 'example', 'node_example'); +var command = new Command(path.resolve(), examplesDir, console.log); + +command.run(jasmine, process.argv.slice(2)); \ No newline at end of file diff --git a/www/node_modules/jasmine/lib/command.js b/www/node_modules/jasmine/lib/command.js new file mode 100644 index 0000000..700a2f9 --- /dev/null +++ b/www/node_modules/jasmine/lib/command.js @@ -0,0 +1,220 @@ +var path = require('path'), + fs = require('fs'); + +exports = module.exports = Command; + +var subCommands = { + init: { + description: 'initialize jasmine', + action: initJasmine + }, + examples: { + description: 'install examples', + action: installExamples + }, + help: { + description: 'show help', + action: help, + alias: '-h' + }, + version: { + description: 'show jasmine and jasmine-core versions', + action: version, + alias: '-v' + } +}; + +function Command(projectBaseDir, examplesDir, print) { + this.projectBaseDir = projectBaseDir; + this.specDir = path.join(projectBaseDir, 'spec'); + + var command = this; + + this.run = function(jasmine, commands) { + setEnvironmentVariables(commands); + + var commandToRun; + Object.keys(subCommands).forEach(function(cmd) { + var commandObject = subCommands[cmd]; + if (commands.indexOf(cmd) >= 0) { + commandToRun = commandObject; + } else if(commandObject.alias && commands.indexOf(commandObject.alias) >= 0) { + commandToRun = commandObject; + } + }); + + if (commandToRun) { + commandToRun.action({projectBaseDir: command.projectBaseDir, specDir: command.specDir, examplesDir: examplesDir, print: print}); + } else { + runJasmine(jasmine, parseOptions(commands)); + } + }; +} + +function isFileArg(arg) { + return arg.indexOf('--') !== 0 && !isEnvironmentVariable(arg); +} + +function parseOptions(argv) { + var files = [], + color = process.stdout.isTTY || false, + filter, + stopOnFailure, + random = false, + seed; + + argv.forEach(function(arg) { + if (arg === '--no-color') { + color = false; + } else if (arg.match("^--filter=")) { + filter = arg.match("^--filter=(.*)")[1]; + } else if (arg.match("^--stop-on-failure=")) { + stopOnFailure = arg.match("^--stop-on-failure=(.*)")[1] === 'true'; + } else if (arg.match("^--random=")) { + random = arg.match("^--random=(.*)")[1] === 'true'; + } else if (arg.match("^--seed=")) { + seed = arg.match("^--seed=(.*)")[1]; + } else if (isFileArg(arg)) { + files.push(arg); + } + }); + return { + color: color, + filter: filter, + stopOnFailure: stopOnFailure, + files: files, + random: random, + seed: seed + }; +} + +function runJasmine(jasmine, env) { + jasmine.loadConfigFile(process.env.JASMINE_CONFIG_PATH); + if (env.stopOnFailure !== undefined) { + jasmine.stopSpecOnExpectationFailure(env.stopOnFailure); + } + if (env.seed !== undefined) { + jasmine.seed(env.seed); + } + + jasmine.randomizeTests(env.random); + jasmine.showColors(env.color); + jasmine.execute(env.files, env.filter); +} + +function initJasmine(options) { + var print = options.print; + var specDir = options.specDir; + makeDirStructure(path.join(specDir, 'support/')); + if(!fs.existsSync(path.join(specDir, 'support/jasmine.json'))) { + fs.writeFileSync(path.join(specDir, 'support/jasmine.json'), fs.readFileSync(path.join(__dirname, '../lib/examples/jasmine.json'), 'utf-8')); + } + else { + print('spec/support/jasmine.json already exists in your project.'); + } +} + +function installExamples(options) { + var specDir = options.specDir; + var projectBaseDir = options.projectBaseDir; + var examplesDir = options.examplesDir; + + makeDirStructure(path.join(specDir, 'support')); + makeDirStructure(path.join(specDir, 'jasmine_examples')); + makeDirStructure(path.join(specDir, 'helpers', 'jasmine_examples')); + makeDirStructure(path.join(projectBaseDir, 'lib', 'jasmine_examples')); + + copyFiles( + path.join(examplesDir, 'spec', 'helpers', 'jasmine_examples'), + path.join(specDir, 'helpers', 'jasmine_examples'), + new RegExp(/[Hh]elper\.js/) + ); + + copyFiles( + path.join(examplesDir, 'lib', 'jasmine_examples'), + path.join(projectBaseDir, 'lib', 'jasmine_examples'), + new RegExp(/\.js/) + ); + + copyFiles( + path.join(examplesDir, 'spec', 'jasmine_examples'), + path.join(specDir, 'jasmine_examples'), + new RegExp(/[Ss]pec.js/) + ); +} + +function help(options) { + var print = options.print; + print('Usage: jasmine [command] [options] [files]'); + print(''); + print('Commands:'); + Object.keys(subCommands).forEach(function(cmd) { + var commandNameText = cmd; + if(subCommands[cmd].alias) { + commandNameText = commandNameText + ',' + subCommands[cmd].alias; + } + print('%s\t%s', lPad(commandNameText, 10), subCommands[cmd].description); + }); + print(''); + print('If no command is given, jasmine specs will be run'); + print(''); + print(''); + + print('Options:'); + print('%s\tturn off color in spec output', lPad('--no-color', 18)); + print('%s\tfilter specs to run only those that match the given string', lPad('--filter=', 18)); + print('%s\t[true|false] stop spec execution on expectation failure. This takes precedence over the stopSpecOnExpectationFailure option in jasmine.json', lPad('--stop-on-failure=', 18)); + print(''); + print('The path to your jasmine.json can be configured by setting the JASMINE_CONFIG_PATH environment variable'); +} + +function version(options) { + var print = options.print; + print('jasmine v' + require('../package.json').version); + print('jasmine-core v' + require('../node_modules/jasmine-core/package.json').version); +} + +function lPad(str, length) { + if (str.length >= length) { + return str; + } else { + return lPad(' ' + str, length); + } +} + +function copyFiles(srcDir, destDir, pattern) { + var srcDirFiles = fs.readdirSync(srcDir); + srcDirFiles.forEach(function(file) { + if (file.search(pattern) !== -1) { + fs.writeFileSync(path.join(destDir, file), fs.readFileSync(path.join(srcDir, file))); + } + }); +} + +function makeDirStructure(absolutePath) { + var splitPath = absolutePath.split(path.sep); + splitPath.forEach(function(dir, index) { + if(index > 1) { + var fullPath = path.join(splitPath.slice(0, index).join('/'), dir); + if (!fs.existsSync(fullPath)) { + fs.mkdirSync(fullPath); + } + } + }); +} + +function isEnvironmentVariable(command) { + var envRegExp = /(.*)=(.*)/; + return command.match(envRegExp); +} + +function setEnvironmentVariables(commands) { + commands.forEach(function (command) { + var regExpMatch = isEnvironmentVariable(command); + if(regExpMatch) { + var key = regExpMatch[1]; + var value = regExpMatch[2]; + process.env[key] = value; + } + }); +} diff --git a/www/node_modules/jasmine/lib/examples/jasmine.json b/www/node_modules/jasmine/lib/examples/jasmine.json new file mode 100644 index 0000000..3ea3166 --- /dev/null +++ b/www/node_modules/jasmine/lib/examples/jasmine.json @@ -0,0 +1,11 @@ +{ + "spec_dir": "spec", + "spec_files": [ + "**/*[sS]pec.js" + ], + "helpers": [ + "helpers/**/*.js" + ], + "stopSpecOnExpectationFailure": false, + "random": false +} diff --git a/www/node_modules/jasmine/lib/exit.js b/www/node_modules/jasmine/lib/exit.js new file mode 100644 index 0000000..d2a6de6 --- /dev/null +++ b/www/node_modules/jasmine/lib/exit.js @@ -0,0 +1,17 @@ +module.exports = function(exitCode, platform, nodeVersion, exit, nodeExit) { + if(isWindows(platform) && olderThan12(nodeVersion)) { + nodeExit(exitCode); + } + else { + exit(exitCode); + } +}; + +function isWindows(platform) { + return /^win/.test(platform); +} + +function olderThan12(nodeVersion) { + var version = nodeVersion.split('.'); + return parseInt(version[0].substr(1), 10) <= 0 && parseInt(version[1], 10) < 12; +} \ No newline at end of file diff --git a/www/node_modules/jasmine/lib/filters/console_spec_filter.js b/www/node_modules/jasmine/lib/filters/console_spec_filter.js new file mode 100644 index 0000000..e3cf6bd --- /dev/null +++ b/www/node_modules/jasmine/lib/filters/console_spec_filter.js @@ -0,0 +1,10 @@ +module.exports = exports = ConsoleSpecFilter; + +function ConsoleSpecFilter(options) { + var filterString = options && options.filterString && options.filterString.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + var filterPattern = new RegExp(filterString); + + this.matches = function(specName) { + return filterPattern.test(specName); + }; +} \ No newline at end of file diff --git a/www/node_modules/jasmine/lib/jasmine.js b/www/node_modules/jasmine/lib/jasmine.js new file mode 100644 index 0000000..67ffeb3 --- /dev/null +++ b/www/node_modules/jasmine/lib/jasmine.js @@ -0,0 +1,170 @@ +var path = require('path'), + util = require('util'), + glob = require('glob'), + exit = require('./exit'), + ExitCodeReporter = require('./reporters/exit_code_reporter'), + ConsoleSpecFilter = require('./filters/console_spec_filter'); + +module.exports = Jasmine; +module.exports.ConsoleReporter = require('./reporters/console_reporter'); + +function Jasmine(options) { + options = options || {}; + var jasmineCore = options.jasmineCore || require('jasmine-core'); + this.jasmineCorePath = path.join(jasmineCore.files.path, 'jasmine.js'); + this.jasmine = jasmineCore.boot(jasmineCore); + this.projectBaseDir = options.projectBaseDir || path.resolve(); + this.printDeprecation = options.printDeprecation || require('./printDeprecation'); + this.specFiles = []; + this.helperFiles = []; + this.env = this.jasmine.getEnv(); + this.reportersCount = 0; + this.exitCodeReporter = new ExitCodeReporter(); + this.onCompleteCallbackAdded = false; + this.exit = exit; + this.showingColors = true; +} + +Jasmine.prototype.randomizeTests = function(value) { + this.env.randomizeTests(value); +}; + +Jasmine.prototype.seed = function(value) { + this.env.seed(value); +}; + +Jasmine.prototype.showColors = function(value) { + this.showingColors = value; +}; + +Jasmine.prototype.addSpecFile = function(filePath) { + this.specFiles.push(filePath); +}; + +Jasmine.prototype.addReporter = function(reporter) { + this.env.addReporter(reporter); + this.reportersCount++; +}; + +Jasmine.prototype.configureDefaultReporter = function(options) { + options.timer = options.timer || new this.jasmine.Timer(); + options.print = options.print || function() { + process.stdout.write(util.format.apply(this, arguments)); + }; + options.showColors = options.hasOwnProperty('showColors') ? options.showColors : true; + options.jasmineCorePath = options.jasmineCorePath || this.jasmineCorePath; + + if(options.onComplete) { + this.printDeprecation('Passing in an onComplete function to configureDefaultReporter is deprecated.'); + } + var consoleReporter = new module.exports.ConsoleReporter(options); + this.addReporter(consoleReporter); + this.defaultReporterAdded = true; +}; + +Jasmine.prototype.addMatchers = function(matchers) { + this.jasmine.Expectation.addMatchers(matchers); +}; + +Jasmine.prototype.loadSpecs = function() { + this.specFiles.forEach(function(file) { + require(file); + }); +}; + +Jasmine.prototype.loadHelpers = function() { + this.helperFiles.forEach(function(file) { + require(file); + }); +}; + +Jasmine.prototype.loadConfigFile = function(configFilePath) { + var absoluteConfigFilePath = path.resolve(this.projectBaseDir, configFilePath || 'spec/support/jasmine.json'); + var config = require(absoluteConfigFilePath); + this.loadConfig(config); +}; + +Jasmine.prototype.loadConfig = function(config) { + var jasmineRunner = this; + jasmineRunner.specDir = config.spec_dir; + + if(config.helpers) { + config.helpers.forEach(function(helperFile) { + var filePaths = glob.sync(path.join(jasmineRunner.projectBaseDir, jasmineRunner.specDir, helperFile)); + filePaths.forEach(function(filePath) { + if(jasmineRunner.helperFiles.indexOf(filePath) === -1) { + jasmineRunner.helperFiles.push(filePath); + } + }); + }); + } + + this.env.throwOnExpectationFailure(config.stopSpecOnExpectationFailure); + this.env.randomizeTests(config.random); + + if(config.spec_files) { + jasmineRunner.addSpecFiles(config.spec_files); + } +}; + +Jasmine.prototype.addSpecFiles = function(files) { + var jasmineRunner = this; + + files.forEach(function(specFile) { + var filePaths = glob.sync(path.join(jasmineRunner.projectBaseDir, jasmineRunner.specDir, specFile)); + filePaths.forEach(function(filePath) { + if(jasmineRunner.specFiles.indexOf(filePath) === -1) { + jasmineRunner.specFiles.push(filePath); + } + }); + }); +}; + +Jasmine.prototype.onComplete = function(onCompleteCallback) { + this.exitCodeReporter.onComplete(onCompleteCallback); + this.onCompleteCallbackAdded = true; +}; + +Jasmine.prototype.stopSpecOnExpectationFailure = function(value) { + this.env.throwOnExpectationFailure(value); +}; + +Jasmine.prototype.execute = function(files, filterString) { + this.loadHelpers(); + + if(this.reportersCount === 0) { + this.configureDefaultReporter({ showColors: this.showingColors }); + } + + if(filterString) { + var specFilter = new ConsoleSpecFilter({ + filterString: filterString + }); + this.env.specFilter = function(spec) { + return specFilter.matches(spec.getFullName()); + }; + } + + if (files && files.length > 0) { + this.specDir = ''; + this.specFiles = []; + this.addSpecFiles(files); + } + + this.loadSpecs(); + + if(!this.onCompleteCallbackAdded && this.defaultReporterAdded) { + var jasmineRunner = this; + this.exitCodeReporter.onComplete(function(passed) { + if(passed) { + jasmineRunner.exit(0, process.platform, process.version, process.exit, require('exit')); + } + else { + jasmineRunner.exit(1, process.platform, process.version, process.exit, require('exit')); + } + }); + } + + this.addReporter(this.exitCodeReporter); + this.env.execute(); +}; diff --git a/www/node_modules/jasmine/lib/printDeprecation.js b/www/node_modules/jasmine/lib/printDeprecation.js new file mode 100644 index 0000000..0755b2e --- /dev/null +++ b/www/node_modules/jasmine/lib/printDeprecation.js @@ -0,0 +1,3 @@ +module.exports = function(message) { + console.warn('Deprecation warning: ' + message); +}; \ No newline at end of file diff --git a/www/node_modules/jasmine/lib/reporters/console_reporter.js b/www/node_modules/jasmine/lib/reporters/console_reporter.js new file mode 100644 index 0000000..f1ac0c6 --- /dev/null +++ b/www/node_modules/jasmine/lib/reporters/console_reporter.js @@ -0,0 +1,208 @@ +module.exports = exports = ConsoleReporter; + +var noopTimer = { + start: function(){}, + elapsed: function(){ return 0; } +}; + +function ConsoleReporter(options) { + var print = options.print, + showColors = options.showColors || false, + timer = options.timer || noopTimer, + jasmineCorePath = options.jasmineCorePath, + printDeprecation = options.printDeprecation || require('../printDeprecation'), + specCount, + executableSpecCount, + failureCount, + failedSpecs = [], + pendingSpecs = [], + ansi = { + green: '\x1B[32m', + red: '\x1B[31m', + yellow: '\x1B[33m', + none: '\x1B[0m' + }, + failedSuites = [], + stackFilter = options.stackFilter || defaultStackFilter; + + if(options.onComplete) { + printDeprecation('Passing in an onComplete function to the ConsoleReporter is deprecated.'); + } + var onComplete = options.onComplete || function() {}; + + this.jasmineStarted = function() { + specCount = 0; + executableSpecCount = 0; + failureCount = 0; + print('Started'); + printNewline(); + timer.start(); + }; + + this.jasmineDone = function(result) { + printNewline(); + printNewline(); + if(failedSpecs.length > 0) { + print('Failures:'); + } + for (var i = 0; i < failedSpecs.length; i++) { + specFailureDetails(failedSpecs[i], i + 1); + } + + if (pendingSpecs.length > 0) { + print("Pending:"); + } + for(i = 0; i < pendingSpecs.length; i++) { + pendingSpecDetails(pendingSpecs[i], i + 1); + } + + if(specCount > 0) { + printNewline(); + + if(executableSpecCount !== specCount) { + print('Ran ' + executableSpecCount + ' of ' + specCount + plural(' spec', specCount)); + printNewline(); + } + var specCounts = executableSpecCount + ' ' + plural('spec', executableSpecCount) + ', ' + + failureCount + ' ' + plural('failure', failureCount); + + if (pendingSpecs.length) { + specCounts += ', ' + pendingSpecs.length + ' pending ' + plural('spec', pendingSpecs.length); + } + + print(specCounts); + } else { + print('No specs found'); + } + + printNewline(); + var seconds = timer.elapsed() / 1000; + print('Finished in ' + seconds + ' ' + plural('second', seconds)); + printNewline(); + + for(i = 0; i < failedSuites.length; i++) { + suiteFailureDetails(failedSuites[i]); + } + + if (result && result.order && result.order.random) { + print('Randomized with seed ' + result.order.seed); + printNewline(); + } + + onComplete(failureCount === 0); + }; + + this.specDone = function(result) { + specCount++; + + if (result.status == 'pending') { + pendingSpecs.push(result); + executableSpecCount++; + print(colored('yellow', '*')); + return; + } + + if (result.status == 'passed') { + executableSpecCount++; + print(colored('green', '.')); + return; + } + + if (result.status == 'failed') { + failureCount++; + failedSpecs.push(result); + executableSpecCount++; + print(colored('red', 'F')); + } + }; + + this.suiteDone = function(result) { + if (result.failedExpectations && result.failedExpectations.length > 0) { + failureCount++; + failedSuites.push(result); + } + }; + + return this; + + function printNewline() { + print('\n'); + } + + function colored(color, str) { + return showColors ? (ansi[color] + str + ansi.none) : str; + } + + function plural(str, count) { + return count == 1 ? str : str + 's'; + } + + function repeat(thing, times) { + var arr = []; + for (var i = 0; i < times; i++) { + arr.push(thing); + } + return arr; + } + + function indent(str, spaces) { + var lines = (str || '').split('\n'); + var newArr = []; + for (var i = 0; i < lines.length; i++) { + newArr.push(repeat(' ', spaces).join('') + lines[i]); + } + return newArr.join('\n'); + } + + function defaultStackFilter(stack) { + var filteredStack = stack.split('\n').filter(function(stackLine) { + return stackLine.indexOf(jasmineCorePath) === -1; + }).join('\n'); + return filteredStack; + } + + function specFailureDetails(result, failedSpecNumber) { + printNewline(); + print(failedSpecNumber + ') '); + print(result.fullName); + + for (var i = 0; i < result.failedExpectations.length; i++) { + var failedExpectation = result.failedExpectations[i]; + printNewline(); + print(indent('Message:', 2)); + printNewline(); + print(colored('red', indent(failedExpectation.message, 4))); + printNewline(); + print(indent('Stack:', 2)); + printNewline(); + print(indent(stackFilter(failedExpectation.stack), 4)); + } + + printNewline(); + } + + function suiteFailureDetails(result) { + for (var i = 0; i < result.failedExpectations.length; i++) { + printNewline(); + print(colored('red', 'An error was thrown in an afterAll')); + printNewline(); + print(colored('red', 'AfterAll ' + result.failedExpectations[i].message)); + + } + printNewline(); + } + + function pendingSpecDetails(result, pendingSpecNumber) { + printNewline(); + printNewline(); + print(pendingSpecNumber + ') '); + print(result.fullName); + printNewline(); + var pendingReason = "No reason given"; + if (result.pendingReason && result.pendingReason !== '') { + pendingReason = result.pendingReason; + } + print(indent(colored('yellow', pendingReason), 2)); + printNewline(); + } +} diff --git a/www/node_modules/jasmine/lib/reporters/exit_code_reporter.js b/www/node_modules/jasmine/lib/reporters/exit_code_reporter.js new file mode 100644 index 0000000..354a83e --- /dev/null +++ b/www/node_modules/jasmine/lib/reporters/exit_code_reporter.js @@ -0,0 +1,24 @@ +module.exports = function() { + var results = true; + var onCompleteCallback = function() {}; + + this.onComplete = function(callback) { + onCompleteCallback = callback; + }; + + this.jasmineDone = function() { + onCompleteCallback(results); + }; + + this.specDone = function(result) { + if(result.status === 'failed') { + results = false; + } + }; + + this.suiteDone = function(result) { + if (result.failedExpectations && result.failedExpectations.length > 0) { + results = false; + } + }; +}; \ No newline at end of file diff --git a/www/node_modules/jasmine/node_modules/glob/.npmignore b/www/node_modules/jasmine/node_modules/glob/.npmignore new file mode 100644 index 0000000..2af4b71 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/.npmignore @@ -0,0 +1,2 @@ +.*.swp +test/a/ diff --git a/www/node_modules/jasmine/node_modules/glob/.travis.yml b/www/node_modules/jasmine/node_modules/glob/.travis.yml new file mode 100644 index 0000000..baa0031 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - 0.8 diff --git a/www/node_modules/jasmine/node_modules/glob/LICENSE b/www/node_modules/jasmine/node_modules/glob/LICENSE new file mode 100644 index 0000000..0c44ae7 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) Isaac Z. Schlueter ("Author") +All rights reserved. + +The BSD License + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/www/node_modules/jasmine/node_modules/glob/README.md b/www/node_modules/jasmine/node_modules/glob/README.md new file mode 100644 index 0000000..cc69164 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/README.md @@ -0,0 +1,250 @@ +# Glob + +Match files using the patterns the shell uses, like stars and stuff. + +This is a glob implementation in JavaScript. It uses the `minimatch` +library to do its matching. + +## Attention: node-glob users! + +The API has changed dramatically between 2.x and 3.x. This library is +now 100% JavaScript, and the integer flags have been replaced with an +options object. + +Also, there's an event emitter class, proper tests, and all the other +things you've come to expect from node modules. + +And best of all, no compilation! + +## Usage + +```javascript +var glob = require("glob") + +// options is optional +glob("**/*.js", options, function (er, files) { + // files is an array of filenames. + // If the `nonull` option is set, and nothing + // was found, then files is ["**/*.js"] + // er is an error object or null. +}) +``` + +## Features + +Please see the [minimatch +documentation](https://github.com/isaacs/minimatch) for more details. + +Supports these glob features: + +* Brace Expansion +* Extended glob matching +* "Globstar" `**` matching + +See: + +* `man sh` +* `man bash` +* `man 3 fnmatch` +* `man 5 gitignore` +* [minimatch documentation](https://github.com/isaacs/minimatch) + +## glob(pattern, [options], cb) + +* `pattern` {String} Pattern to be matched +* `options` {Object} +* `cb` {Function} + * `err` {Error | null} + * `matches` {Array} filenames found matching the pattern + +Perform an asynchronous glob search. + +## glob.sync(pattern, [options]) + +* `pattern` {String} Pattern to be matched +* `options` {Object} +* return: {Array} filenames found matching the pattern + +Perform a synchronous glob search. + +## Class: glob.Glob + +Create a Glob object by instanting the `glob.Glob` class. + +```javascript +var Glob = require("glob").Glob +var mg = new Glob(pattern, options, cb) +``` + +It's an EventEmitter, and starts walking the filesystem to find matches +immediately. + +### new glob.Glob(pattern, [options], [cb]) + +* `pattern` {String} pattern to search for +* `options` {Object} +* `cb` {Function} Called when an error occurs, or matches are found + * `err` {Error | null} + * `matches` {Array} filenames found matching the pattern + +Note that if the `sync` flag is set in the options, then matches will +be immediately available on the `g.found` member. + +### Properties + +* `minimatch` The minimatch object that the glob uses. +* `options` The options object passed in. +* `error` The error encountered. When an error is encountered, the + glob object is in an undefined state, and should be discarded. +* `aborted` Boolean which is set to true when calling `abort()`. There + is no way at this time to continue a glob search after aborting, but + you can re-use the statCache to avoid having to duplicate syscalls. +* `statCache` Collection of all the stat results the glob search + performed. +* `cache` Convenience object. Each field has the following possible + values: + * `false` - Path does not exist + * `true` - Path exists + * `1` - Path exists, and is not a directory + * `2` - Path exists, and is a directory + * `[file, entries, ...]` - Path exists, is a directory, and the + array value is the results of `fs.readdir` + +### Events + +* `end` When the matching is finished, this is emitted with all the + matches found. If the `nonull` option is set, and no match was found, + then the `matches` list contains the original pattern. The matches + are sorted, unless the `nosort` flag is set. +* `match` Every time a match is found, this is emitted with the matched. +* `error` Emitted when an unexpected error is encountered, or whenever + any fs error occurs if `options.strict` is set. +* `abort` When `abort()` is called, this event is raised. + +### Methods + +* `abort` Stop the search. + +### Options + +All the options that can be passed to Minimatch can also be passed to +Glob to change pattern matching behavior. Also, some have been added, +or have glob-specific ramifications. + +All options are false by default, unless otherwise noted. + +All options are added to the glob object, as well. + +* `cwd` The current working directory in which to search. Defaults + to `process.cwd()`. +* `root` The place where patterns starting with `/` will be mounted + onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix + systems, and `C:\` or some such on Windows.) +* `dot` Include `.dot` files in normal matches and `globstar` matches. + Note that an explicit dot in a portion of the pattern will always + match dot files. +* `nomount` By default, a pattern starting with a forward-slash will be + "mounted" onto the root setting, so that a valid filesystem path is + returned. Set this flag to disable that behavior. +* `mark` Add a `/` character to directory matches. Note that this + requires additional stat calls. +* `nosort` Don't sort the results. +* `stat` Set to true to stat *all* results. This reduces performance + somewhat, and is completely unnecessary, unless `readdir` is presumed + to be an untrustworthy indicator of file existence. It will cause + ELOOP to be triggered one level sooner in the case of cyclical + symbolic links. +* `silent` When an unusual error is encountered + when attempting to read a directory, a warning will be printed to + stderr. Set the `silent` option to true to suppress these warnings. +* `strict` When an unusual error is encountered + when attempting to read a directory, the process will just continue on + in search of other matches. Set the `strict` option to raise an error + in these cases. +* `cache` See `cache` property above. Pass in a previously generated + cache object to save some fs calls. +* `statCache` A cache of results of filesystem information, to prevent + unnecessary stat calls. While it should not normally be necessary to + set this, you may pass the statCache from one glob() call to the + options object of another, if you know that the filesystem will not + change between calls. (See "Race Conditions" below.) +* `sync` Perform a synchronous glob search. +* `nounique` In some cases, brace-expanded patterns can result in the + same file showing up multiple times in the result set. By default, + this implementation prevents duplicates in the result set. + Set this flag to disable that behavior. +* `nonull` Set to never return an empty set, instead returning a set + containing the pattern itself. This is the default in glob(3). +* `nocase` Perform a case-insensitive match. Note that case-insensitive + filesystems will sometimes result in glob returning results that are + case-insensitively matched anyway, since readdir and stat will not + raise an error. +* `debug` Set to enable debug logging in minimatch and glob. +* `globDebug` Set to enable debug logging in glob, but not minimatch. + +## Comparisons to other fnmatch/glob implementations + +While strict compliance with the existing standards is a worthwhile +goal, some discrepancies exist between node-glob and other +implementations, and are intentional. + +If the pattern starts with a `!` character, then it is negated. Set the +`nonegate` flag to suppress this behavior, and treat leading `!` +characters normally. This is perhaps relevant if you wish to start the +pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` +characters at the start of a pattern will negate the pattern multiple +times. + +If a pattern starts with `#`, then it is treated as a comment, and +will not match anything. Use `\#` to match a literal `#` at the +start of a line, or set the `nocomment` flag to suppress this behavior. + +The double-star character `**` is supported by default, unless the +`noglobstar` flag is set. This is supported in the manner of bsdglob +and bash 4.1, where `**` only has special significance if it is the only +thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but +`a/**b` will not. + +If an escaped pattern has no matches, and the `nonull` flag is set, +then glob returns the pattern as-provided, rather than +interpreting the character escapes. For example, +`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than +`"*a?"`. This is akin to setting the `nullglob` option in bash, except +that it does not resolve escaped pattern characters. + +If brace expansion is not disabled, then it is performed before any +other interpretation of the glob pattern. Thus, a pattern like +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are +checked for validity. Since those two are valid, matching proceeds. + +## Windows + +**Please only use forward-slashes in glob expressions.** + +Though windows uses either `/` or `\` as its path separator, only `/` +characters are used by this glob implementation. You must use +forward-slashes **only** in glob expressions. Back-slashes will always +be interpreted as escape characters, not path separators. + +Results from absolute patterns such as `/foo/*` are mounted onto the +root setting using `path.join`. On windows, this will by default result +in `/foo/*` matching `C:\foo\bar.txt`. + +## Race Conditions + +Glob searching, by its very nature, is susceptible to race conditions, +since it relies on directory walking and such. + +As a result, it is possible that a file that exists when glob looks for +it may have been deleted or modified by the time it returns the result. + +As part of its internal implementation, this program caches all stat +and readdir calls that it makes, in order to cut down on system +overhead. However, this also makes it even more susceptible to races, +especially if the cache or statCache objects are reused between glob +calls. + +Users are thus advised not to use a glob result as a guarantee of +filesystem state in the face of rapid changes. For the vast majority +of operations, this is never a problem. diff --git a/www/node_modules/jasmine/node_modules/glob/examples/g.js b/www/node_modules/jasmine/node_modules/glob/examples/g.js new file mode 100644 index 0000000..be122df --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/examples/g.js @@ -0,0 +1,9 @@ +var Glob = require("../").Glob + +var pattern = "test/a/**/[cg]/../[cg]" +console.log(pattern) + +var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) { + console.log("matches", matches) +}) +console.log("after") diff --git a/www/node_modules/jasmine/node_modules/glob/examples/usr-local.js b/www/node_modules/jasmine/node_modules/glob/examples/usr-local.js new file mode 100644 index 0000000..327a425 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/examples/usr-local.js @@ -0,0 +1,9 @@ +var Glob = require("../").Glob + +var pattern = "{./*/*,/*,/usr/local/*}" +console.log(pattern) + +var mg = new Glob(pattern, {mark: true}, function (er, matches) { + console.log("matches", matches) +}) +console.log("after") diff --git a/www/node_modules/jasmine/node_modules/glob/glob.js b/www/node_modules/jasmine/node_modules/glob/glob.js new file mode 100644 index 0000000..f646c44 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/glob.js @@ -0,0 +1,728 @@ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// readdir(PREFIX) as ENTRIES +// If fails, END +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $]) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $]) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + + + +module.exports = glob + +var fs = require("fs") +, minimatch = require("minimatch") +, Minimatch = minimatch.Minimatch +, inherits = require("inherits") +, EE = require("events").EventEmitter +, path = require("path") +, isDir = {} +, assert = require("assert").ok + +function glob (pattern, options, cb) { + if (typeof options === "function") cb = options, options = {} + if (!options) options = {} + + if (typeof options === "number") { + deprecated() + return + } + + var g = new Glob(pattern, options, cb) + return g.sync ? g.found : g +} + +glob.fnmatch = deprecated + +function deprecated () { + throw new Error("glob's interface has changed. Please see the docs.") +} + +glob.sync = globSync +function globSync (pattern, options) { + if (typeof options === "number") { + deprecated() + return + } + + options = options || {} + options.sync = true + return glob(pattern, options) +} + +this._processingEmitQueue = false + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (!(this instanceof Glob)) { + return new Glob(pattern, options, cb) + } + + if (typeof options === "function") { + cb = options + options = null + } + + if (typeof cb === "function") { + this.on("error", cb) + this.on("end", function (matches) { + cb(null, matches) + }) + } + + options = options || {} + + this._endEmitted = false + this.EOF = {} + this._emitQueue = [] + + this.paused = false + this._processingEmitQueue = false + + this.maxDepth = options.maxDepth || 1000 + this.maxLength = options.maxLength || Infinity + this.cache = options.cache || {} + this.statCache = options.statCache || {} + + this.changedCwd = false + var cwd = process.cwd() + if (!options.hasOwnProperty("cwd")) this.cwd = cwd + else { + this.cwd = options.cwd + this.changedCwd = path.resolve(options.cwd) !== cwd + } + + this.root = options.root || path.resolve(this.cwd, "/") + this.root = path.resolve(this.root) + if (process.platform === "win32") + this.root = this.root.replace(/\\/g, "/") + + this.nomount = !!options.nomount + + if (!pattern) { + throw new Error("must provide pattern") + } + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + this.strict = options.strict !== false + this.dot = !!options.dot + this.mark = !!options.mark + this.sync = !!options.sync + this.nounique = !!options.nounique + this.nonull = !!options.nonull + this.nosort = !!options.nosort + this.nocase = !!options.nocase + this.stat = !!options.stat + + this.debug = !!options.debug || !!options.globDebug + if (this.debug) + this.log = console.error + + this.silent = !!options.silent + + var mm = this.minimatch = new Minimatch(pattern, options) + this.options = mm.options + pattern = this.pattern = mm.pattern + + this.error = null + this.aborted = false + + // list of all the patterns that ** has resolved do, so + // we can avoid visiting multiple times. + this._globstars = {} + + EE.call(this) + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + this.minimatch.set.forEach(iterator.bind(this)) + function iterator (pattern, i, set) { + this._process(pattern, 0, i, function (er) { + if (er) this.emit("error", er) + if (-- n <= 0) this._finish() + }) + } +} + +Glob.prototype.log = function () {} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + + var nou = this.nounique + , all = nou ? [] : {} + + for (var i = 0, l = this.matches.length; i < l; i ++) { + var matches = this.matches[i] + this.log("matches[%d] =", i, matches) + // do like the shell, and spit out the literal glob + if (!matches) { + if (this.nonull) { + var literal = this.minimatch.globSet[i] + if (nou) all.push(literal) + else all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) all.push.apply(all, m) + else m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) all = Object.keys(all) + + if (!this.nosort) { + all = all.sort(this.nocase ? alphasorti : alphasort) + } + + if (this.mark) { + // at *some* point we statted all of these + all = all.map(this._mark, this) + } + + this.log("emitting end", all) + + this.EOF = this.found = all + this.emitMatch(this.EOF) +} + +function alphasorti (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return alphasort(a, b) +} + +function alphasort (a, b) { + return a > b ? 1 : a < b ? -1 : 0 +} + +Glob.prototype._mark = function (p) { + var c = this.cache[p] + var m = p + if (c) { + var isDir = c === 2 || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + this.statCache[m] = this.statCache[p] + this.cache[m] = this.cache[p] + } + } + + return m +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit("abort") +} + +Glob.prototype.pause = function () { + if (this.paused) return + if (this.sync) + this.emit("error", new Error("Can't pause/resume sync glob")) + this.paused = true + this.emit("pause") +} + +Glob.prototype.resume = function () { + if (!this.paused) return + if (this.sync) + this.emit("error", new Error("Can't pause/resume sync glob")) + this.paused = false + this.emit("resume") + this._processEmitQueue() + //process.nextTick(this.emit.bind(this, "resume")) +} + +Glob.prototype.emitMatch = function (m) { + this.log('emitMatch', m) + this._emitQueue.push(m) + this._processEmitQueue() +} + +Glob.prototype._processEmitQueue = function (m) { + this.log("pEQ paused=%j processing=%j m=%j", this.paused, + this._processingEmitQueue, m) + var done = false + while (!this._processingEmitQueue && + !this.paused) { + this._processingEmitQueue = true + var m = this._emitQueue.shift() + this.log(">processEmitQueue", m === this.EOF ? ":EOF:" : m) + if (!m) { + this.log(">processEmitQueue, falsey m") + this._processingEmitQueue = false + break + } + + if (m === this.EOF || !(this.mark && !this.stat)) { + this.log("peq: unmarked, or eof") + next.call(this, 0, false) + } else if (this.statCache[m]) { + var sc = this.statCache[m] + var exists + if (sc) + exists = sc.isDirectory() ? 2 : 1 + this.log("peq: stat cached") + next.call(this, exists, exists === 2) + } else { + this.log("peq: _stat, then next") + this._stat(m, next) + } + + function next(exists, isDir) { + this.log("next", m, exists, isDir) + var ev = m === this.EOF ? "end" : "match" + + // "end" can only happen once. + assert(!this._endEmitted) + if (ev === "end") + this._endEmitted = true + + if (exists) { + // Doesn't mean it necessarily doesn't exist, it's possible + // we just didn't check because we don't care that much, or + // this is EOF anyway. + if (isDir && !m.match(/\/$/)) { + m = m + "/" + } else if (!isDir && m.match(/\/$/)) { + m = m.replace(/\/+$/, "") + } + } + this.log("emit", ev, m) + this.emit(ev, m) + this._processingEmitQueue = false + if (done && m !== this.EOF && !this.paused) + this._processEmitQueue() + } + } + done = true +} + +Glob.prototype._process = function (pattern, depth, index, cb_) { + assert(this instanceof Glob) + + var cb = function cb (er, res) { + assert(this instanceof Glob) + if (this.paused) { + if (!this._processQueue) { + this._processQueue = [] + this.once("resume", function () { + var q = this._processQueue + this._processQueue = null + q.forEach(function (cb) { cb() }) + }) + } + this._processQueue.push(cb_.bind(this, er, res)) + } else { + cb_.call(this, er, res) + } + }.bind(this) + + if (this.aborted) return cb() + + if (depth > this.maxDepth) return cb() + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === "string") { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + prefix = pattern.join("/") + this._stat(prefix, function (exists, isDir) { + // either it's there, or it isn't. + // nothing more to do, either way. + if (exists) { + if (prefix && isAbsolute(prefix) && !this.nomount) { + if (prefix.charAt(0) === "/") { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + } + } + + if (process.platform === "win32") + prefix = prefix.replace(/\\/g, "/") + + this.matches[index] = this.matches[index] || {} + this.matches[index][prefix] = true + this.emitMatch(prefix) + } + return cb() + }) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's "absolute" like /foo/bar, + // or "relative" like "../baz" + prefix = pattern.slice(0, n) + prefix = prefix.join("/") + break + } + + // get the list of entries. + var read + if (prefix === null) read = "." + else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) { + if (!prefix || !isAbsolute(prefix)) { + prefix = path.join("/", prefix) + } + read = prefix = path.resolve(prefix) + + // if (process.platform === "win32") + // read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/") + + this.log('absolute: ', prefix, this.root, pattern, read) + } else { + read = prefix + } + + this.log('readdir(%j)', read, this.cwd, this.root) + + return this._readdir(read, function (er, entries) { + if (er) { + // not a directory! + // this means that, whatever else comes after this, it can never match + return cb() + } + + // globstar is special + if (pattern[n] === minimatch.GLOBSTAR) { + // test without the globstar, and with every child both below + // and replacing the globstar. + var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ] + entries.forEach(function (e) { + if (e.charAt(0) === "." && !this.dot) return + // instead of the globstar + s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))) + // below the globstar + s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n))) + }, this) + + s = s.filter(function (pattern) { + var key = gsKey(pattern) + var seen = !this._globstars[key] + this._globstars[key] = true + return seen + }, this) + + if (!s.length) + return cb() + + // now asyncForEach over this + var l = s.length + , errState = null + s.forEach(function (gsPattern) { + this._process(gsPattern, depth + 1, index, function (er) { + if (errState) return + if (er) return cb(errState = er) + if (--l <= 0) return cb() + }) + }, this) + + return + } + + // not a globstar + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = pattern[n] + var rawGlob = pattern[n]._glob + , dotOk = this.dot || rawGlob.charAt(0) === "." + + entries = entries.filter(function (e) { + return (e.charAt(0) !== "." || dotOk) && + e.match(pattern[n]) + }) + + // If n === pattern.length - 1, then there's no need for the extra stat + // *unless* the user has specified "mark" or "stat" explicitly. + // We know that they exist, since the readdir returned them. + if (n === pattern.length - 1 && + !this.mark && + !this.stat) { + entries.forEach(function (e) { + if (prefix) { + if (prefix !== "/") e = prefix + "/" + e + else e = prefix + e + } + if (e.charAt(0) === "/" && !this.nomount) { + e = path.join(this.root, e) + } + + if (process.platform === "win32") + e = e.replace(/\\/g, "/") + + this.matches[index] = this.matches[index] || {} + this.matches[index][e] = true + this.emitMatch(e) + }, this) + return cb.call(this) + } + + + // now test all the remaining entries as stand-ins for that part + // of the pattern. + var l = entries.length + , errState = null + if (l === 0) return cb() // no matches possible + entries.forEach(function (e) { + var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)) + this._process(p, depth + 1, index, function (er) { + if (errState) return + if (er) return cb(errState = er) + if (--l === 0) return cb.call(this) + }) + }, this) + }) + +} + +function gsKey (pattern) { + return '**' + pattern.map(function (p) { + return (p === minimatch.GLOBSTAR) ? '**' : (''+p) + }).join('/') +} + +Glob.prototype._stat = function (f, cb) { + assert(this instanceof Glob) + var abs = f + if (f.charAt(0) === "/") { + abs = path.join(this.root, f) + } else if (this.changedCwd) { + abs = path.resolve(this.cwd, f) + } + + if (f.length > this.maxLength) { + var er = new Error("Path name too long") + er.code = "ENAMETOOLONG" + er.path = f + return this._afterStat(f, abs, cb, er) + } + + this.log('stat', [this.cwd, f, '=', abs]) + + if (!this.stat && this.cache.hasOwnProperty(f)) { + var exists = this.cache[f] + , isDir = exists && (Array.isArray(exists) || exists === 2) + if (this.sync) return cb.call(this, !!exists, isDir) + return process.nextTick(cb.bind(this, !!exists, isDir)) + } + + var stat = this.statCache[abs] + if (this.sync || stat) { + var er + try { + stat = fs.statSync(abs) + } catch (e) { + er = e + } + this._afterStat(f, abs, cb, er, stat) + } else { + fs.stat(abs, this._afterStat.bind(this, f, abs, cb)) + } +} + +Glob.prototype._afterStat = function (f, abs, cb, er, stat) { + var exists + assert(this instanceof Glob) + + if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) { + this.log("should be ENOTDIR, fake it") + + er = new Error("ENOTDIR, not a directory '" + abs + "'") + er.path = abs + er.code = "ENOTDIR" + stat = null + } + + var emit = !this.statCache[abs] + this.statCache[abs] = stat + + if (er || !stat) { + exists = false + } else { + exists = stat.isDirectory() ? 2 : 1 + if (emit) + this.emit('stat', f, stat) + } + this.cache[f] = this.cache[f] || exists + cb.call(this, !!exists, exists === 2) +} + +Glob.prototype._readdir = function (f, cb) { + assert(this instanceof Glob) + var abs = f + if (f.charAt(0) === "/") { + abs = path.join(this.root, f) + } else if (isAbsolute(f)) { + abs = f + } else if (this.changedCwd) { + abs = path.resolve(this.cwd, f) + } + + if (f.length > this.maxLength) { + var er = new Error("Path name too long") + er.code = "ENAMETOOLONG" + er.path = f + return this._afterReaddir(f, abs, cb, er) + } + + this.log('readdir', [this.cwd, f, abs]) + if (this.cache.hasOwnProperty(f)) { + var c = this.cache[f] + if (Array.isArray(c)) { + if (this.sync) return cb.call(this, null, c) + return process.nextTick(cb.bind(this, null, c)) + } + + if (!c || c === 1) { + // either ENOENT or ENOTDIR + var code = c ? "ENOTDIR" : "ENOENT" + , er = new Error((c ? "Not a directory" : "Not found") + ": " + f) + er.path = f + er.code = code + this.log(f, er) + if (this.sync) return cb.call(this, er) + return process.nextTick(cb.bind(this, er)) + } + + // at this point, c === 2, meaning it's a dir, but we haven't + // had to read it yet, or c === true, meaning it's *something* + // but we don't have any idea what. Need to read it, either way. + } + + if (this.sync) { + var er, entries + try { + entries = fs.readdirSync(abs) + } catch (e) { + er = e + } + return this._afterReaddir(f, abs, cb, er, entries) + } + + fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb)) +} + +Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) { + assert(this instanceof Glob) + if (entries && !er) { + this.cache[f] = entries + // if we haven't asked to stat everything for suresies, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. This also gets us one step + // further into ELOOP territory. + if (!this.mark && !this.stat) { + entries.forEach(function (e) { + if (f === "/") e = f + e + else e = f + "/" + e + this.cache[e] = true + }, this) + } + + return cb.call(this, er, entries) + } + + // now handle errors, and cache the information + if (er) switch (er.code) { + case "ENOTDIR": // totally normal. means it *does* exist. + this.cache[f] = 1 + return cb.call(this, er) + case "ENOENT": // not terribly unusual + case "ELOOP": + case "ENAMETOOLONG": + case "UNKNOWN": + this.cache[f] = false + return cb.call(this, er) + default: // some unusual error. Treat as failure. + this.cache[f] = false + if (this.strict) this.emit("error", er) + if (!this.silent) console.error("glob error", er) + return cb.call(this, er) + } +} + +var isAbsolute = process.platform === "win32" ? absWin : absUnix + +function absWin (p) { + if (absUnix(p)) return true + // pull off the device/UNC bit from a windows path. + // from node's lib/path.js + var splitDeviceRe = + /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/ + , result = splitDeviceRe.exec(p) + , device = result[1] || '' + , isUnc = device && device.charAt(1) !== ':' + , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute + + return isAbsolute +} + +function absUnix (p) { + return p.charAt(0) === "/" || p === "" +} diff --git a/www/node_modules/jasmine/node_modules/glob/package.json b/www/node_modules/jasmine/node_modules/glob/package.json new file mode 100644 index 0000000..93bb56a --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/package.json @@ -0,0 +1,83 @@ +{ + "_args": [ + [ + "glob@^3.2.11", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine" + ] + ], + "_from": "glob@>=3.2.11 <4.0.0", + "_id": "glob@3.2.11", + "_inCache": true, + "_installable": true, + "_location": "/jasmine/glob", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "1.4.10", + "_phantomChildren": {}, + "_requested": { + "name": "glob", + "raw": "glob@^3.2.11", + "rawSpec": "^3.2.11", + "scope": null, + "spec": ">=3.2.11 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine" + ], + "_resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "_shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", + "_shrinkwrap": null, + "_spec": "glob@^3.2.11", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/node-glob/issues" + }, + "dependencies": { + "inherits": "2", + "minimatch": "0.3" + }, + "description": "a little globber", + "devDependencies": { + "mkdirp": "0", + "rimraf": "1", + "tap": "~0.4.0" + }, + "directories": {}, + "dist": { + "shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d", + "tarball": "http://registry.npmjs.org/glob/-/glob-3.2.11.tgz" + }, + "engines": { + "node": "*" + }, + "gitHead": "73f57e99510582b2024b762305970ebcf9b70aa2", + "homepage": "https://github.com/isaacs/node-glob", + "license": "BSD", + "main": "glob.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "glob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "scripts": { + "test": "tap test/*.js", + "test-regen": "TEST_REGEN=1 node test/00-setup.js" + }, + "version": "3.2.11" +} diff --git a/www/node_modules/jasmine/node_modules/glob/test/00-setup.js b/www/node_modules/jasmine/node_modules/glob/test/00-setup.js new file mode 100644 index 0000000..245afaf --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/00-setup.js @@ -0,0 +1,176 @@ +// just a little pre-run script to set up the fixtures. +// zz-finish cleans it up + +var mkdirp = require("mkdirp") +var path = require("path") +var i = 0 +var tap = require("tap") +var fs = require("fs") +var rimraf = require("rimraf") + +var files = +[ "a/.abcdef/x/y/z/a" +, "a/abcdef/g/h" +, "a/abcfed/g/h" +, "a/b/c/d" +, "a/bc/e/f" +, "a/c/d/c/b" +, "a/cb/e/f" +] + +var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c") +var symlinkFrom = "../.." + +files = files.map(function (f) { + return path.resolve(__dirname, f) +}) + +tap.test("remove fixtures", function (t) { + rimraf(path.resolve(__dirname, "a"), function (er) { + t.ifError(er, "remove fixtures") + t.end() + }) +}) + +files.forEach(function (f) { + tap.test(f, function (t) { + var d = path.dirname(f) + mkdirp(d, 0755, function (er) { + if (er) { + t.fail(er) + return t.bailout() + } + fs.writeFile(f, "i like tests", function (er) { + t.ifError(er, "make file") + t.end() + }) + }) + }) +}) + +if (process.platform !== "win32") { + tap.test("symlinky", function (t) { + var d = path.dirname(symlinkTo) + console.error("mkdirp", d) + mkdirp(d, 0755, function (er) { + t.ifError(er) + fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) { + t.ifError(er, "make symlink") + t.end() + }) + }) + }) +} + +;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) { + w = "/tmp/glob-test/" + w + tap.test("create " + w, function (t) { + mkdirp(w, function (er) { + if (er) + throw er + t.pass(w) + t.end() + }) + }) +}) + + +// generate the bash pattern test-fixtures if possible +if (process.platform === "win32" || !process.env.TEST_REGEN) { + console.error("Windows, or TEST_REGEN unset. Using cached fixtures.") + return +} + +var spawn = require("child_process").spawn; +var globs = + // put more patterns here. + // anything that would be directly in / should be in /tmp/glob-test + ["test/a/*/+(c|g)/./d" + ,"test/a/**/[cg]/../[cg]" + ,"test/a/{b,c,d,e,f}/**/g" + ,"test/a/b/**" + ,"test/**/g" + ,"test/a/abc{fed,def}/g/h" + ,"test/a/abc{fed/g,def}/**/" + ,"test/a/abc{fed/g,def}/**///**/" + ,"test/**/a/**/" + ,"test/+(a|b|c)/a{/,bc*}/**" + ,"test/*/*/*/f" + ,"test/**/f" + ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**" + ,"{./*/*,/tmp/glob-test/*}" + ,"{/tmp/glob-test/*,*}" // evil owl face! how you taunt me! + ,"test/a/!(symlink)/**" + ] +var bashOutput = {} +var fs = require("fs") + +globs.forEach(function (pattern) { + tap.test("generate fixture " + pattern, function (t) { + var cmd = "shopt -s globstar && " + + "shopt -s extglob && " + + "shopt -s nullglob && " + + // "shopt >&2; " + + "eval \'for i in " + pattern + "; do echo $i; done\'" + var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) }) + var out = [] + cp.stdout.on("data", function (c) { + out.push(c) + }) + cp.stderr.pipe(process.stderr) + cp.on("close", function (code) { + out = flatten(out) + if (!out) + out = [] + else + out = cleanResults(out.split(/\r*\n/)) + + bashOutput[pattern] = out + t.notOk(code, "bash test should finish nicely") + t.end() + }) + }) +}) + +tap.test("save fixtures", function (t) { + var fname = path.resolve(__dirname, "bash-results.json") + var data = JSON.stringify(bashOutput, null, 2) + "\n" + fs.writeFile(fname, data, function (er) { + t.ifError(er) + t.end() + }) +}) + +function cleanResults (m) { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m.map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort).map(function (f) { + // de-windows + return (process.platform !== 'win32') ? f + : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') + }) +} + +function flatten (chunks) { + var s = 0 + chunks.forEach(function (c) { s += c.length }) + var out = new Buffer(s) + s = 0 + chunks.forEach(function (c) { + c.copy(out, s) + s += c.length + }) + + return out.toString().trim() +} + +function alphasort (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 +} diff --git a/www/node_modules/jasmine/node_modules/glob/test/bash-comparison.js b/www/node_modules/jasmine/node_modules/glob/test/bash-comparison.js new file mode 100644 index 0000000..239ed1a --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/bash-comparison.js @@ -0,0 +1,63 @@ +// basic test +// show that it does the same thing by default as the shell. +var tap = require("tap") +, child_process = require("child_process") +, bashResults = require("./bash-results.json") +, globs = Object.keys(bashResults) +, glob = require("../") +, path = require("path") + +// run from the root of the project +// this is usually where you're at anyway, but be sure. +process.chdir(path.resolve(__dirname, "..")) + +function alphasort (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 +} + +globs.forEach(function (pattern) { + var expect = bashResults[pattern] + // anything regarding the symlink thing will fail on windows, so just skip it + if (process.platform === "win32" && + expect.some(function (m) { + return /\/symlink\//.test(m) + })) + return + + tap.test(pattern, function (t) { + glob(pattern, function (er, matches) { + if (er) + throw er + + // sort and unmark, just to match the shell results + matches = cleanResults(matches) + + t.deepEqual(matches, expect, pattern) + t.end() + }) + }) + + tap.test(pattern + " sync", function (t) { + var matches = cleanResults(glob.sync(pattern)) + + t.deepEqual(matches, expect, "should match shell") + t.end() + }) +}) + +function cleanResults (m) { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m.map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort).map(function (f) { + // de-windows + return (process.platform !== 'win32') ? f + : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/') + }) +} diff --git a/www/node_modules/jasmine/node_modules/glob/test/bash-results.json b/www/node_modules/jasmine/node_modules/glob/test/bash-results.json new file mode 100644 index 0000000..8051c72 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/bash-results.json @@ -0,0 +1,351 @@ +{ + "test/a/*/+(c|g)/./d": [ + "test/a/b/c/./d" + ], + "test/a/**/[cg]/../[cg]": [ + "test/a/abcdef/g/../g", + "test/a/abcfed/g/../g", + "test/a/b/c/../c", + "test/a/c/../c", + "test/a/c/d/c/../c", + "test/a/symlink/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c" + ], + "test/a/{b,c,d,e,f}/**/g": [], + "test/a/b/**": [ + "test/a/b", + "test/a/b/c", + "test/a/b/c/d" + ], + "test/**/g": [ + "test/a/abcdef/g", + "test/a/abcfed/g" + ], + "test/a/abc{fed,def}/g/h": [ + "test/a/abcdef/g/h", + "test/a/abcfed/g/h" + ], + "test/a/abc{fed/g,def}/**/": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcfed/g" + ], + "test/a/abc{fed/g,def}/**///**/": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcfed/g" + ], + "test/**/a/**/": [ + "test/a", + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcfed", + "test/a/abcfed/g", + "test/a/b", + "test/a/b/c", + "test/a/bc", + "test/a/bc/e", + "test/a/c", + "test/a/c/d", + "test/a/c/d/c", + "test/a/cb", + "test/a/cb/e", + "test/a/symlink", + "test/a/symlink/a", + "test/a/symlink/a/b", + "test/a/symlink/a/b/c", + "test/a/symlink/a/b/c/a", + "test/a/symlink/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b" + ], + "test/+(a|b|c)/a{/,bc*}/**": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcdef/g/h", + "test/a/abcfed", + "test/a/abcfed/g", + "test/a/abcfed/g/h" + ], + "test/*/*/*/f": [ + "test/a/bc/e/f", + "test/a/cb/e/f" + ], + "test/**/f": [ + "test/a/bc/e/f", + "test/a/cb/e/f" + ], + "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [ + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", + "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c" + ], + "{./*/*,/tmp/glob-test/*}": [ + "./examples/g.js", + "./examples/usr-local.js", + "./node_modules/inherits", + "./node_modules/minimatch", + "./node_modules/mkdirp", + "./node_modules/rimraf", + "./node_modules/tap", + "./test/00-setup.js", + "./test/a", + "./test/bash-comparison.js", + "./test/bash-results.json", + "./test/cwd-test.js", + "./test/globstar-match.js", + "./test/mark.js", + "./test/new-glob-optional-options.js", + "./test/nocase-nomagic.js", + "./test/pause-resume.js", + "./test/readme-issue.js", + "./test/root-nomount.js", + "./test/root.js", + "./test/stat.js", + "./test/zz-cleanup.js", + "/tmp/glob-test/asdf", + "/tmp/glob-test/bar", + "/tmp/glob-test/baz", + "/tmp/glob-test/foo", + "/tmp/glob-test/quux", + "/tmp/glob-test/qwer", + "/tmp/glob-test/rewq" + ], + "{/tmp/glob-test/*,*}": [ + "/tmp/glob-test/asdf", + "/tmp/glob-test/bar", + "/tmp/glob-test/baz", + "/tmp/glob-test/foo", + "/tmp/glob-test/quux", + "/tmp/glob-test/qwer", + "/tmp/glob-test/rewq", + "examples", + "glob.js", + "LICENSE", + "node_modules", + "package.json", + "README.md", + "test" + ], + "test/a/!(symlink)/**": [ + "test/a/abcdef", + "test/a/abcdef/g", + "test/a/abcdef/g/h", + "test/a/abcfed", + "test/a/abcfed/g", + "test/a/abcfed/g/h", + "test/a/b", + "test/a/b/c", + "test/a/b/c/d", + "test/a/bc", + "test/a/bc/e", + "test/a/bc/e/f", + "test/a/c", + "test/a/c/d", + "test/a/c/d/c", + "test/a/c/d/c/b", + "test/a/cb", + "test/a/cb/e", + "test/a/cb/e/f" + ] +} diff --git a/www/node_modules/jasmine/node_modules/glob/test/cwd-test.js b/www/node_modules/jasmine/node_modules/glob/test/cwd-test.js new file mode 100644 index 0000000..352c27e --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/cwd-test.js @@ -0,0 +1,55 @@ +var tap = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +tap.test("changing cwd and searching for **/d", function (t) { + var glob = require('../') + var path = require('path') + t.test('.', function (t) { + glob('**/d', function (er, matches) { + t.ifError(er) + t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) + t.end() + }) + }) + + t.test('a', function (t) { + glob('**/d', {cwd:path.resolve('a')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'b/c/d', 'c/d' ]) + t.end() + }) + }) + + t.test('a/b', function (t) { + glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'c/d' ]) + t.end() + }) + }) + + t.test('a/b/', function (t) { + glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'c/d' ]) + t.end() + }) + }) + + t.test('.', function (t) { + glob('**/d', {cwd: process.cwd()}, function (er, matches) { + t.ifError(er) + t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) + t.end() + }) + }) + + t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() + }) + + t.end() +}) diff --git a/www/node_modules/jasmine/node_modules/glob/test/globstar-match.js b/www/node_modules/jasmine/node_modules/glob/test/globstar-match.js new file mode 100644 index 0000000..9b234fa --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/globstar-match.js @@ -0,0 +1,19 @@ +var Glob = require("../glob.js").Glob +var test = require('tap').test + +test('globstar should not have dupe matches', function(t) { + var pattern = 'a/**/[gh]' + var g = new Glob(pattern, { cwd: __dirname }) + var matches = [] + g.on('match', function(m) { + console.error('match %j', m) + matches.push(m) + }) + g.on('end', function(set) { + console.error('set', set) + matches = matches.sort() + set = set.sort() + t.same(matches, set, 'should have same set of matches') + t.end() + }) +}) diff --git a/www/node_modules/jasmine/node_modules/glob/test/mark.js b/www/node_modules/jasmine/node_modules/glob/test/mark.js new file mode 100644 index 0000000..bf411c0 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/mark.js @@ -0,0 +1,118 @@ +var test = require("tap").test +var glob = require('../') +process.chdir(__dirname) + +// expose timing issues +var lag = 5 +glob.Glob.prototype._stat = function(o) { return function(f, cb) { + var args = arguments + setTimeout(function() { + o.call(this, f, cb) + }.bind(this), lag += 5) +}}(glob.Glob.prototype._stat) + + +test("mark, with **", function (t) { + glob("a/*b*/**", {mark: true}, function (er, results) { + if (er) + throw er + var expect = + [ 'a/abcdef/', + 'a/abcdef/g/', + 'a/abcdef/g/h', + 'a/abcfed/', + 'a/abcfed/g/', + 'a/abcfed/g/h', + 'a/b/', + 'a/b/c/', + 'a/b/c/d', + 'a/bc/', + 'a/bc/e/', + 'a/bc/e/f', + 'a/cb/', + 'a/cb/e/', + 'a/cb/e/f' ] + + t.same(results, expect) + t.end() + }) +}) + +test("mark, no / on pattern", function (t) { + glob("a/*", {mark: true}, function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/' ] + + if (process.platform !== "win32") + expect.push('a/symlink/') + + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /\/$/) + }) +}) + +test("mark=false, no / on pattern", function (t) { + glob("a/*", function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef', + 'a/abcfed', + 'a/b', + 'a/bc', + 'a/c', + 'a/cb' ] + + if (process.platform !== "win32") + expect.push('a/symlink') + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /[^\/]$/) + }) +}) + +test("mark=true, / on pattern", function (t) { + glob("a/*/", {mark: true}, function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/' ] + if (process.platform !== "win32") + expect.push('a/symlink/') + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /\/$/) + }) +}) + +test("mark=false, / on pattern", function (t) { + glob("a/*/", function (er, results) { + if (er) + throw er + var expect = [ 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/' ] + if (process.platform !== "win32") + expect.push('a/symlink/') + t.same(results, expect) + t.end() + }).on('match', function(m) { + t.similar(m, /\/$/) + }) +}) diff --git a/www/node_modules/jasmine/node_modules/glob/test/new-glob-optional-options.js b/www/node_modules/jasmine/node_modules/glob/test/new-glob-optional-options.js new file mode 100644 index 0000000..3e7dc5a --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/new-glob-optional-options.js @@ -0,0 +1,10 @@ +var Glob = require('../glob.js').Glob; +var test = require('tap').test; + +test('new glob, with cb, and no options', function (t) { + new Glob(__filename, function(er, results) { + if (er) throw er; + t.same(results, [__filename]); + t.end(); + }); +}); diff --git a/www/node_modules/jasmine/node_modules/glob/test/nocase-nomagic.js b/www/node_modules/jasmine/node_modules/glob/test/nocase-nomagic.js new file mode 100644 index 0000000..2503f23 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/nocase-nomagic.js @@ -0,0 +1,113 @@ +var fs = require('fs'); +var test = require('tap').test; +var glob = require('../'); + +test('mock fs', function(t) { + var stat = fs.stat + var statSync = fs.statSync + var readdir = fs.readdir + var readdirSync = fs.readdirSync + + function fakeStat(path) { + var ret + switch (path.toLowerCase()) { + case '/tmp': case '/tmp/': + ret = { isDirectory: function() { return true } } + break + case '/tmp/a': + ret = { isDirectory: function() { return false } } + break + } + return ret + } + + fs.stat = function(path, cb) { + var f = fakeStat(path); + if (f) { + process.nextTick(function() { + cb(null, f) + }) + } else { + stat.call(fs, path, cb) + } + } + + fs.statSync = function(path) { + return fakeStat(path) || statSync.call(fs, path) + } + + function fakeReaddir(path) { + var ret + switch (path.toLowerCase()) { + case '/tmp': case '/tmp/': + ret = [ 'a', 'A' ] + break + case '/': + ret = ['tmp', 'tMp', 'tMP', 'TMP'] + } + return ret + } + + fs.readdir = function(path, cb) { + var f = fakeReaddir(path) + if (f) + process.nextTick(function() { + cb(null, f) + }) + else + readdir.call(fs, path, cb) + } + + fs.readdirSync = function(path) { + return fakeReaddir(path) || readdirSync.call(fs, path) + } + + t.pass('mocked') + t.end() +}) + +test('nocase, nomagic', function(t) { + var n = 2 + var want = [ '/TMP/A', + '/TMP/a', + '/tMP/A', + '/tMP/a', + '/tMp/A', + '/tMp/a', + '/tmp/A', + '/tmp/a' ] + glob('/tmp/a', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + if (--n === 0) t.end() + }) + glob('/tmp/A', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + if (--n === 0) t.end() + }) +}) + +test('nocase, with some magic', function(t) { + t.plan(2) + var want = [ '/TMP/A', + '/TMP/a', + '/tMP/A', + '/tMP/a', + '/tMp/A', + '/tMp/a', + '/tmp/A', + '/tmp/a' ] + glob('/tmp/*', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + }) + glob('/tmp/*', { nocase: true }, function(er, res) { + if (er) + throw er + t.same(res.sort(), want) + }) +}) diff --git a/www/node_modules/jasmine/node_modules/glob/test/pause-resume.js b/www/node_modules/jasmine/node_modules/glob/test/pause-resume.js new file mode 100644 index 0000000..e1ffbab --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/pause-resume.js @@ -0,0 +1,73 @@ +// show that no match events happen while paused. +var tap = require("tap") +, child_process = require("child_process") +// just some gnarly pattern with lots of matches +, pattern = "test/a/!(symlink)/**" +, bashResults = require("./bash-results.json") +, patterns = Object.keys(bashResults) +, glob = require("../") +, Glob = glob.Glob +, path = require("path") + +// run from the root of the project +// this is usually where you're at anyway, but be sure. +process.chdir(path.resolve(__dirname, "..")) + +function alphasort (a, b) { + a = a.toLowerCase() + b = b.toLowerCase() + return a > b ? 1 : a < b ? -1 : 0 +} + +function cleanResults (m) { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m.map(function (m) { + return m.replace(/\/+/g, "/").replace(/\/$/, "") + }).sort(alphasort).reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []).sort(alphasort).map(function (f) { + // de-windows + return (process.platform !== 'win32') ? f + : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') + }) +} + +var globResults = [] +tap.test("use a Glob object, and pause/resume it", function (t) { + var g = new Glob(pattern) + , paused = false + , res = [] + , expect = bashResults[pattern] + + g.on("pause", function () { + console.error("pause") + }) + + g.on("resume", function () { + console.error("resume") + }) + + g.on("match", function (m) { + t.notOk(g.paused, "must not be paused") + globResults.push(m) + g.pause() + t.ok(g.paused, "must be paused") + setTimeout(g.resume.bind(g), 10) + }) + + g.on("end", function (matches) { + t.pass("reached glob end") + globResults = cleanResults(globResults) + matches = cleanResults(matches) + t.deepEqual(matches, globResults, + "end event matches should be the same as match events") + + t.deepEqual(matches, expect, + "glob matches should be the same as bash results") + + t.end() + }) +}) + diff --git a/www/node_modules/jasmine/node_modules/glob/test/readme-issue.js b/www/node_modules/jasmine/node_modules/glob/test/readme-issue.js new file mode 100644 index 0000000..0b4e0be --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/readme-issue.js @@ -0,0 +1,36 @@ +var test = require("tap").test +var glob = require("../") + +var mkdirp = require("mkdirp") +var fs = require("fs") +var rimraf = require("rimraf") +var dir = __dirname + "/package" + +test("setup", function (t) { + mkdirp.sync(dir) + fs.writeFileSync(dir + "/package.json", "{}", "ascii") + fs.writeFileSync(dir + "/README", "x", "ascii") + t.pass("setup done") + t.end() +}) + +test("glob", function (t) { + var opt = { + cwd: dir, + nocase: true, + mark: true + } + + glob("README?(.*)", opt, function (er, files) { + if (er) + throw er + t.same(files, ["README"]) + t.end() + }) +}) + +test("cleanup", function (t) { + rimraf.sync(dir) + t.pass("clean") + t.end() +}) diff --git a/www/node_modules/jasmine/node_modules/glob/test/root-nomount.js b/www/node_modules/jasmine/node_modules/glob/test/root-nomount.js new file mode 100644 index 0000000..3ac5979 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/root-nomount.js @@ -0,0 +1,39 @@ +var tap = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +tap.test("changing root and searching for /b*/**", function (t) { + var glob = require('../') + var path = require('path') + t.test('.', function (t) { + glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, []) + t.end() + }) + }) + + t.test('a', function (t) { + glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) + t.end() + }) + }) + + t.test('root=a, cwd=a/b', function (t) { + glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) + t.end() + }) + }) + + t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() + }) + + t.end() +}) diff --git a/www/node_modules/jasmine/node_modules/glob/test/root.js b/www/node_modules/jasmine/node_modules/glob/test/root.js new file mode 100644 index 0000000..95c23f9 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/root.js @@ -0,0 +1,46 @@ +var t = require("tap") + +var origCwd = process.cwd() +process.chdir(__dirname) + +var glob = require('../') +var path = require('path') + +t.test('.', function (t) { + glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) { + t.ifError(er) + t.like(matches, []) + t.end() + }) +}) + + +t.test('a', function (t) { + console.error("root=" + path.resolve('a')) + glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) { + t.ifError(er) + var wanted = [ + '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' + ].map(function (m) { + return path.join(path.resolve('a'), m).replace(/\\/g, '/') + }) + + t.like(matches, wanted) + t.end() + }) +}) + +t.test('root=a, cwd=a/b', function (t) { + glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) { + t.ifError(er) + t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { + return path.join(path.resolve('a'), m).replace(/\\/g, '/') + })) + t.end() + }) +}) + +t.test('cd -', function (t) { + process.chdir(origCwd) + t.end() +}) diff --git a/www/node_modules/jasmine/node_modules/glob/test/stat.js b/www/node_modules/jasmine/node_modules/glob/test/stat.js new file mode 100644 index 0000000..6291711 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/stat.js @@ -0,0 +1,32 @@ +var glob = require('../') +var test = require('tap').test +var path = require('path') + +test('stat all the things', function(t) { + var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: __dirname }) + var matches = [] + g.on('match', function(m) { + matches.push(m) + }) + var stats = [] + g.on('stat', function(m) { + stats.push(m) + }) + g.on('end', function(eof) { + stats = stats.sort() + matches = matches.sort() + eof = eof.sort() + t.same(stats, matches) + t.same(eof, matches) + var cache = Object.keys(this.statCache) + t.same(cache.map(function (f) { + return path.relative(__dirname, f) + }).sort(), matches) + + cache.forEach(function(c) { + t.equal(typeof this.statCache[c], 'object') + }, this) + + t.end() + }) +}) diff --git a/www/node_modules/jasmine/node_modules/glob/test/zz-cleanup.js b/www/node_modules/jasmine/node_modules/glob/test/zz-cleanup.js new file mode 100644 index 0000000..e085f0f --- /dev/null +++ b/www/node_modules/jasmine/node_modules/glob/test/zz-cleanup.js @@ -0,0 +1,11 @@ +// remove the fixtures +var tap = require("tap") +, rimraf = require("rimraf") +, path = require("path") + +tap.test("cleanup fixtures", function (t) { + rimraf(path.resolve(__dirname, "a"), function (er) { + t.ifError(er, "removed") + t.end() + }) +}) diff --git a/www/node_modules/jasmine/node_modules/minimatch/.npmignore b/www/node_modules/jasmine/node_modules/minimatch/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/www/node_modules/jasmine/node_modules/minimatch/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/www/node_modules/jasmine/node_modules/minimatch/LICENSE b/www/node_modules/jasmine/node_modules/minimatch/LICENSE new file mode 100644 index 0000000..05a4010 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/minimatch/LICENSE @@ -0,0 +1,23 @@ +Copyright 2009, 2010, 2011 Isaac Z. Schlueter. +All rights reserved. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/www/node_modules/jasmine/node_modules/minimatch/README.md b/www/node_modules/jasmine/node_modules/minimatch/README.md new file mode 100644 index 0000000..5b3967e --- /dev/null +++ b/www/node_modules/jasmine/node_modules/minimatch/README.md @@ -0,0 +1,218 @@ +# minimatch + +A minimal matching utility. + +[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch) + + +This is the matching library used internally by npm. + +Eventually, it will replace the C binding in node-glob. + +It works by converting glob expressions into JavaScript `RegExp` +objects. + +## Usage + +```javascript +var minimatch = require("minimatch") + +minimatch("bar.foo", "*.foo") // true! +minimatch("bar.foo", "*.bar") // false! +minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy! +``` + +## Features + +Supports these glob features: + +* Brace Expansion +* Extended glob matching +* "Globstar" `**` matching + +See: + +* `man sh` +* `man bash` +* `man 3 fnmatch` +* `man 5 gitignore` + +## Minimatch Class + +Create a minimatch object by instanting the `minimatch.Minimatch` class. + +```javascript +var Minimatch = require("minimatch").Minimatch +var mm = new Minimatch(pattern, options) +``` + +### Properties + +* `pattern` The original pattern the minimatch object represents. +* `options` The options supplied to the constructor. +* `set` A 2-dimensional array of regexp or string expressions. + Each row in the + array corresponds to a brace-expanded pattern. Each item in the row + corresponds to a single path-part. For example, the pattern + `{a,b/c}/d` would expand to a set of patterns like: + + [ [ a, d ] + , [ b, c, d ] ] + + If a portion of the pattern doesn't have any "magic" in it + (that is, it's something like `"foo"` rather than `fo*o?`), then it + will be left as a string rather than converted to a regular + expression. + +* `regexp` Created by the `makeRe` method. A single regular expression + expressing the entire pattern. This is useful in cases where you wish + to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled. +* `negate` True if the pattern is negated. +* `comment` True if the pattern is a comment. +* `empty` True if the pattern is `""`. + +### Methods + +* `makeRe` Generate the `regexp` member if necessary, and return it. + Will return `false` if the pattern is invalid. +* `match(fname)` Return true if the filename matches the pattern, or + false otherwise. +* `matchOne(fileArray, patternArray, partial)` Take a `/`-split + filename, and match it against a single row in the `regExpSet`. This + method is mainly for internal use, but is exposed so that it can be + used by a glob-walker that needs to avoid excessive filesystem calls. + +All other methods are internal, and will be called as necessary. + +## Functions + +The top-level exported function has a `cache` property, which is an LRU +cache set to store 100 items. So, calling these methods repeatedly +with the same pattern and options will use the same Minimatch object, +saving the cost of parsing it multiple times. + +### minimatch(path, pattern, options) + +Main export. Tests a path against the pattern using the options. + +```javascript +var isJS = minimatch(file, "*.js", { matchBase: true }) +``` + +### minimatch.filter(pattern, options) + +Returns a function that tests its +supplied argument, suitable for use with `Array.filter`. Example: + +```javascript +var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true})) +``` + +### minimatch.match(list, pattern, options) + +Match against the list of +files, in the style of fnmatch or glob. If nothing is matched, and +options.nonull is set, then return a list containing the pattern itself. + +```javascript +var javascripts = minimatch.match(fileList, "*.js", {matchBase: true})) +``` + +### minimatch.makeRe(pattern, options) + +Make a regular expression object from the pattern. + +## Options + +All options are `false` by default. + +### debug + +Dump a ton of stuff to stderr. + +### nobrace + +Do not expand `{a,b}` and `{1..3}` brace sets. + +### noglobstar + +Disable `**` matching against multiple folder names. + +### dot + +Allow patterns to match filenames starting with a period, even if +the pattern does not explicitly have a period in that spot. + +Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot` +is set. + +### noext + +Disable "extglob" style patterns like `+(a|b)`. + +### nocase + +Perform a case-insensitive match. + +### nonull + +When a match is not found by `minimatch.match`, return a list containing +the pattern itself if this option is set. When not set, an empty list +is returned if there are no matches. + +### matchBase + +If set, then patterns without slashes will be matched +against the basename of the path if it contains slashes. For example, +`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. + +### nocomment + +Suppress the behavior of treating `#` at the start of a pattern as a +comment. + +### nonegate + +Suppress the behavior of treating a leading `!` character as negation. + +### flipNegate + +Returns from negate expressions the same as if they were not negated. +(Ie, true on a hit, false on a miss.) + + +## Comparisons to other fnmatch/glob implementations + +While strict compliance with the existing standards is a worthwhile +goal, some discrepancies exist between minimatch and other +implementations, and are intentional. + +If the pattern starts with a `!` character, then it is negated. Set the +`nonegate` flag to suppress this behavior, and treat leading `!` +characters normally. This is perhaps relevant if you wish to start the +pattern with a negative extglob pattern like `!(a|B)`. Multiple `!` +characters at the start of a pattern will negate the pattern multiple +times. + +If a pattern starts with `#`, then it is treated as a comment, and +will not match anything. Use `\#` to match a literal `#` at the +start of a line, or set the `nocomment` flag to suppress this behavior. + +The double-star character `**` is supported by default, unless the +`noglobstar` flag is set. This is supported in the manner of bsdglob +and bash 4.1, where `**` only has special significance if it is the only +thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but +`a/**b` will not. + +If an escaped pattern has no matches, and the `nonull` flag is set, +then minimatch.match returns the pattern as-provided, rather than +interpreting the character escapes. For example, +`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than +`"*a?"`. This is akin to setting the `nullglob` option in bash, except +that it does not resolve escaped pattern characters. + +If brace expansion is not disabled, then it is performed before any +other interpretation of the glob pattern. Thus, a pattern like +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are +checked for validity. Since those two are valid, matching proceeds. diff --git a/www/node_modules/jasmine/node_modules/minimatch/minimatch.js b/www/node_modules/jasmine/node_modules/minimatch/minimatch.js new file mode 100644 index 0000000..4539678 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/minimatch/minimatch.js @@ -0,0 +1,1061 @@ +;(function (require, exports, module, platform) { + +if (module) module.exports = minimatch +else exports.minimatch = minimatch + +if (!require) { + require = function (id) { + switch (id) { + case "sigmund": return function sigmund (obj) { + return JSON.stringify(obj) + } + case "path": return { basename: function (f) { + f = f.split(/[\/\\]/) + var e = f.pop() + if (!e) e = f.pop() + return e + }} + case "lru-cache": return function LRUCache () { + // not quite an LRU, but still space-limited. + var cache = {} + var cnt = 0 + this.set = function (k, v) { + cnt ++ + if (cnt >= 100) cache = {} + cache[k] = v + } + this.get = function (k) { return cache[k] } + } + } + } +} + +minimatch.Minimatch = Minimatch + +var LRU = require("lru-cache") + , cache = minimatch.cache = new LRU({max: 100}) + , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} + , sigmund = require("sigmund") + +var path = require("path") + // any single thing other than / + // don't need to escape / when using new RegExp() + , qmark = "[^/]" + + // * => any number of characters + , star = qmark + "*?" + + // ** when dots are allowed. Anything goes, except .. and . + // not (^ or / followed by one or two dots followed by $ or /), + // followed by anything, any number of times. + , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?" + + // not a ^ or / followed by a dot, + // followed by anything, any number of times. + , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?" + + // characters that need to be escaped in RegExp. + , reSpecials = charSet("().*{}+?[]^$\\!") + +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split("").reduce(function (set, c) { + set[c] = true + return set + }, {}) +} + +// normalizes slashes. +var slashSplit = /\/+/ + +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} + +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t +} + +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch + + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) + } + + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } + + return m +} + +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} + + +function minimatch (p, pattern, options) { + if (typeof pattern !== "string") { + throw new TypeError("glob pattern string required") + } + + if (!options) options = {} + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === "#") { + return false + } + + // "" only matches "" + if (pattern.trim() === "") return p === "" + + return new Minimatch(pattern, options).match(p) +} + +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options, cache) + } + + if (typeof pattern !== "string") { + throw new TypeError("glob pattern string required") + } + + if (!options) options = {} + pattern = pattern.trim() + + // windows: need to use /, not \ + // On other platforms, \ is a valid (albeit bad) filename char. + if (platform === "win32") { + pattern = pattern.split("\\").join("/") + } + + // lru storage. + // these things aren't particularly big, but walking down the string + // and turning it into a regexp can get pretty costly. + var cacheKey = pattern + "\n" + sigmund(options) + var cached = minimatch.cache.get(cacheKey) + if (cached) return cached + minimatch.cache.set(cacheKey, this) + + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false + + // make the set of regexps etc. + this.make() +} + +Minimatch.prototype.debug = function() {} + +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return + + var pattern = this.pattern + var options = this.options + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === "#") { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } + + // step 1: figure out negation, etc. + this.parseNegate() + + // step 2: expand braces + var set = this.globSet = this.braceExpand() + + if (options.debug) this.debug = console.error + + this.debug(this.pattern, set) + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) + + this.debug(this.pattern, set) + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) + + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return -1 === s.indexOf(false) + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + , negate = false + , options = this.options + , negateOffset = 0 + + if (options.nonegate) return + + for ( var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === "!" + ; i ++) { + negate = !negate + negateOffset ++ + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} + +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return new Minimatch(pattern, options).braceExpand() +} + +Minimatch.prototype.braceExpand = braceExpand +function braceExpand (pattern, options) { + options = options || this.options + pattern = typeof pattern === "undefined" + ? this.pattern : pattern + + if (typeof pattern === "undefined") { + throw new Error("undefined pattern") + } + + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] + } + + var escaping = false + + // examples and comments refer to this crazy pattern: + // a{b,c{d,e},{f,g}h}x{y,z} + // expected: + // abxy + // abxz + // acdxy + // acdxz + // acexy + // acexz + // afhxy + // afhxz + // aghxy + // aghxz + + // everything before the first \{ is just a prefix. + // So, we pluck that off, and work with the rest, + // and then prepend it to everything we find. + if (pattern.charAt(0) !== "{") { + this.debug(pattern) + var prefix = null + for (var i = 0, l = pattern.length; i < l; i ++) { + var c = pattern.charAt(i) + this.debug(i, c) + if (c === "\\") { + escaping = !escaping + } else if (c === "{" && !escaping) { + prefix = pattern.substr(0, i) + break + } + } + + // actually no sets, all { were escaped. + if (prefix === null) { + this.debug("no sets") + return [pattern] + } + + var tail = braceExpand.call(this, pattern.substr(i), options) + return tail.map(function (t) { + return prefix + t + }) + } + + // now we have something like: + // {b,c{d,e},{f,g}h}x{y,z} + // walk through the set, expanding each part, until + // the set ends. then, we'll expand the suffix. + // If the set only has a single member, then'll put the {} back + + // first, handle numeric sets, since they're easier + var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/) + if (numset) { + this.debug("numset", numset[1], numset[2]) + var suf = braceExpand.call(this, pattern.substr(numset[0].length), options) + , start = +numset[1] + , end = +numset[2] + , inc = start > end ? -1 : 1 + , set = [] + for (var i = start; i != (end + inc); i += inc) { + // append all the suffixes + for (var ii = 0, ll = suf.length; ii < ll; ii ++) { + set.push(i + suf[ii]) + } + } + return set + } + + // ok, walk through the set + // We hope, somewhat optimistically, that there + // will be a } at the end. + // If the closing brace isn't found, then the pattern is + // interpreted as braceExpand("\\" + pattern) so that + // the leading \{ will be interpreted literally. + var i = 1 // skip the \{ + , depth = 1 + , set = [] + , member = "" + , sawEnd = false + , escaping = false + + function addMember () { + set.push(member) + member = "" + } + + this.debug("Entering for") + FOR: for (i = 1, l = pattern.length; i < l; i ++) { + var c = pattern.charAt(i) + this.debug("", i, c) + + if (escaping) { + escaping = false + member += "\\" + c + } else { + switch (c) { + case "\\": + escaping = true + continue + + case "{": + depth ++ + member += "{" + continue + + case "}": + depth -- + // if this closes the actual set, then we're done + if (depth === 0) { + addMember() + // pluck off the close-brace + i ++ + break FOR + } else { + member += c + continue + } + + case ",": + if (depth === 1) { + addMember() + } else { + member += c + } + continue + + default: + member += c + continue + } // switch + } // else + } // for + + // now we've either finished the set, and the suffix is + // pattern.substr(i), or we have *not* closed the set, + // and need to escape the leading brace + if (depth !== 0) { + this.debug("didn't close", pattern) + return braceExpand.call(this, "\\" + pattern, options) + } + + // x{y,z} -> ["xy", "xz"] + this.debug("set", set) + this.debug("suffix", pattern.substr(i)) + var suf = braceExpand.call(this, pattern.substr(i), options) + // ["b", "c{d,e}","{f,g}h"] -> + // [["b"], ["cd", "ce"], ["fh", "gh"]] + var addBraces = set.length === 1 + this.debug("set pre-expanded", set) + set = set.map(function (p) { + return braceExpand.call(this, p, options) + }, this) + this.debug("set expanded", set) + + + // [["b"], ["cd", "ce"], ["fh", "gh"]] -> + // ["b", "cd", "ce", "fh", "gh"] + set = set.reduce(function (l, r) { + return l.concat(r) + }) + + if (addBraces) { + set = set.map(function (s) { + return "{" + s + "}" + }) + } + + // now attach the suffixes. + var ret = [] + for (var i = 0, l = set.length; i < l; i ++) { + for (var ii = 0, ll = suf.length; ii < ll; ii ++) { + ret.push(set[i] + suf[ii]) + } + } + return ret +} + +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + var options = this.options + + // shortcuts + if (!options.noglobstar && pattern === "**") return GLOBSTAR + if (pattern === "") return "" + + var re = "" + , hasMagic = !!options.nocase + , escaping = false + // ? => one single character + , patternListStack = [] + , plType + , stateChar + , inClass = false + , reClassStart = -1 + , classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + , patternStart = pattern.charAt(0) === "." ? "" // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))" + : "(?!\\.)" + , self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case "*": + re += star + hasMagic = true + break + case "?": + re += qmark + hasMagic = true + break + default: + re += "\\"+stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } + + for ( var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i ++ ) { + + this.debug("%s\t%s %s %j", pattern, i, re, c) + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += "\\" + c + escaping = false + continue + } + + SWITCH: switch (c) { + case "/": + // completely not allowed, even escaped. + // Should already be path-split by now. + return false + + case "\\": + clearStateChar() + escaping = true + continue + + // the various stateChar values + // for the "extglob" stuff. + case "?": + case "*": + case "+": + case "@": + case "!": + this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c) + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === "!" && i === classStart + 1) c = "^" + re += c + continue + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + + case "(": + if (inClass) { + re += "(" + continue + } + + if (!stateChar) { + re += "\\(" + continue + } + + plType = stateChar + patternListStack.push({ type: plType + , start: i - 1 + , reStart: re.length }) + // negation is (?:(?!js)[^/]*) + re += stateChar === "!" ? "(?:(?!" : "(?:" + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + + case ")": + if (inClass || !patternListStack.length) { + re += "\\)" + continue + } + + clearStateChar() + hasMagic = true + re += ")" + plType = patternListStack.pop().type + // negation is (?:(?!js)[^/]*) + // The others are (?:) + switch (plType) { + case "!": + re += "[^/]*?)" + break + case "?": + case "+": + case "*": re += plType + case "@": break // the default anyway + } + continue + + case "|": + if (inClass || !patternListStack.length || escaping) { + re += "\\|" + escaping = false + continue + } + + clearStateChar() + re += "|" + continue + + // these are mostly the same in regexp and glob + case "[": + // swallow any state-tracking char before the [ + clearStateChar() + + if (inClass) { + re += "\\" + c + continue + } + + inClass = true + classStart = i + reClassStart = re.length + re += c + continue + + case "]": + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += "\\" + c + escaping = false + continue + } + + // finish up the class. + hasMagic = true + inClass = false + re += c + continue + + default: + // swallow any state char that wasn't consumed + clearStateChar() + + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === "^" && inClass)) { + re += "\\" + } + + re += c + + } // switch + } // for + + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + var cs = pattern.substr(classStart + 1) + , sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + "\\[" + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + var pl + while (pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + 3) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = "\\" + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + "|" + }) + + this.debug("tail=%j\n %s", tail, tail) + var t = pl.type === "*" ? star + : pl.type === "?" ? qmark + : "\\" + pl.type + + hasMagic = true + re = re.slice(0, pl.reStart) + + t + "\\(" + + tail + } + + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += "\\\\" + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case ".": + case "[": + case "(": addPatternStart = true + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== "" && hasMagic) re = "(?=.)" + re + + if (addPatternStart) re = patternStart + re + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [ re, hasMagic ] + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } + + var flags = options.nocase ? "i" : "" + , regExp = new RegExp("^" + re + "$", flags) + + regExp._glob = pattern + regExp._src = re + + return regExp +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} + +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) return this.regexp = false + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + , flags = options.nocase ? "i" : "" + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === "string") ? regExpEscape(p) + : p._src + }).join("\\\/") + }).join("|") + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = "^(?:" + re + ")$" + + // can match anything, as long as it's not this. + if (this.negate) re = "^(?!" + re + ").*$" + + try { + return this.regexp = new RegExp(re, flags) + } catch (ex) { + return this.regexp = false + } +} + +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} + +Minimatch.prototype.match = match +function match (f, partial) { + this.debug("match", f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === "" + + if (f === "/" && partial) return true + + var options = this.options + + // windows: need to use /, not \ + // On other platforms, \ is a valid (albeit bad) filename char. + if (platform === "win32") { + f = f.split("\\").join("/") + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, "split", f) + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set + this.debug(this.pattern, "set", set) + + // Find the basename of the path by looking for the last non-empty segment + var filename; + for (var i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (var i = 0, l = set.length; i < l; i ++) { + var pattern = set[i], file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} + +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + + this.debug("matchOne", + { "this": this + , file: file + , pattern: pattern }) + + this.debug("matchOne", file.length, pattern.length) + + for ( var fi = 0 + , pi = 0 + , fl = file.length + , pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi ++, pi ++ ) { + + this.debug("matchOne loop") + var p = pattern[pi] + , f = file[fi] + + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + , pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for ( ; fi < fl; fi ++) { + if (file[fi] === "." || file[fi] === ".." || + (!options.dot && file[fi].charAt(0) === ".")) return false + } + return true + } + + // ok, let's see if we can swallow whatever we can. + WHILE: while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', + file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === "." || swallowee === ".." || + (!options.dot && swallowee.charAt(0) === ".")) { + this.debug("dot detected!", file, fr, pattern, pr) + break WHILE + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr ++ + } + } + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug("\n>>> no match, partial?", file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === "string") { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug("string match", p, f, hit) + } else { + hit = f.match(p) + this.debug("pattern match", p, f, hit) + } + + if (!hit) return false + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === "") + return emptyFileEnd + } + + // should be unreachable. + throw new Error("wtf?") +} + + +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, "$1") +} + + +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") +} + +})( typeof require === "function" ? require : null, + this, + typeof module === "object" ? module : null, + typeof process === "object" ? process.platform : "win32" + ) diff --git a/www/node_modules/jasmine/node_modules/minimatch/package.json b/www/node_modules/jasmine/node_modules/minimatch/package.json new file mode 100644 index 0000000..ac23beb --- /dev/null +++ b/www/node_modules/jasmine/node_modules/minimatch/package.json @@ -0,0 +1,82 @@ +{ + "_args": [ + [ + "minimatch@0.3", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine/node_modules/glob" + ] + ], + "_from": "minimatch@>=0.3.0 <0.4.0", + "_id": "minimatch@0.3.0", + "_inCache": true, + "_installable": true, + "_location": "/jasmine/minimatch", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "1.4.10", + "_phantomChildren": {}, + "_requested": { + "name": "minimatch", + "raw": "minimatch@0.3", + "rawSpec": "0.3", + "scope": null, + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine/glob" + ], + "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "_shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", + "_shrinkwrap": null, + "_spec": "minimatch@0.3", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine/node_modules/glob", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me" + }, + "bugs": { + "url": "https://github.com/isaacs/minimatch/issues" + }, + "dependencies": { + "lru-cache": "2", + "sigmund": "~1.0.0" + }, + "description": "a glob matcher in javascript", + "devDependencies": { + "tap": "" + }, + "directories": {}, + "dist": { + "shasum": "275d8edaac4f1bb3326472089e7949c8394699dd", + "tarball": "http://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/isaacs/minimatch", + "license": { + "type": "MIT", + "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE" + }, + "main": "minimatch.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "minimatch", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/minimatch.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "0.3.0" +} diff --git a/www/node_modules/jasmine/node_modules/minimatch/test/basic.js b/www/node_modules/jasmine/node_modules/minimatch/test/basic.js new file mode 100644 index 0000000..ae7ac73 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/minimatch/test/basic.js @@ -0,0 +1,399 @@ +// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test +// +// TODO: Some of these tests do very bad things with backslashes, and will +// most likely fail badly on windows. They should probably be skipped. + +var tap = require("tap") + , globalBefore = Object.keys(global) + , mm = require("../") + , files = [ "a", "b", "c", "d", "abc" + , "abd", "abe", "bb", "bcd" + , "ca", "cb", "dd", "de" + , "bdir/", "bdir/cfile"] + , next = files.concat([ "a-b", "aXb" + , ".x", ".y" ]) + + +var patterns = + [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test" + , ["a*", ["a", "abc", "abd", "abe"]] + , ["X*", ["X*"], {nonull: true}] + + // allow null glob expansion + , ["X*", []] + + // isaacs: Slightly different than bash/sh/ksh + // \\* is not un-escaped to literal "*" in a failed match, + // but it does make it get treated as a literal star + , ["\\*", ["\\*"], {nonull: true}] + , ["\\**", ["\\**"], {nonull: true}] + , ["\\*\\*", ["\\*\\*"], {nonull: true}] + + , ["b*/", ["bdir/"]] + , ["c*", ["c", "ca", "cb"]] + , ["**", files] + + , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] + , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] + + , "legendary larry crashes bashes" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] + + , "character classes" + , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] + , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", + "bdir/", "ca", "cb", "dd", "de"]] + , ["a*[^c]", ["abd", "abe"]] + , function () { files.push("a-b", "aXb") } + , ["a[X-]b", ["a-b", "aXb"]] + , function () { files.push(".x", ".y") } + , ["[^a-c]*", ["d", "dd", "de"]] + , function () { files.push("a*b/", "a*b/ooo") } + , ["a\\*b/*", ["a*b/ooo"]] + , ["a\\*?/*", ["a*b/ooo"]] + , ["*\\\\!*", [], {null: true}, ["echo !7"]] + , ["*\\!*", ["echo !7"], null, ["echo !7"]] + , ["*.\\*", ["r.*"], null, ["r.*"]] + , ["a[b]c", ["abc"]] + , ["a[\\b]c", ["abc"]] + , ["a?c", ["abc"]] + , ["a\\*c", [], {null: true}, ["abc"]] + , ["", [""], { null: true }, [""]] + + , "http://www.opensource.apple.com/source/bash/bash-23/" + + "bash/tests/glob-test" + , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } + , ["*/man*/bash.*", ["man/man1/bash.1"]] + , ["man/man1/bash.1", ["man/man1/bash.1"]] + , ["a***c", ["abc"], null, ["abc"]] + , ["a*****?c", ["abc"], null, ["abc"]] + , ["?*****??", ["abc"], null, ["abc"]] + , ["*****??", ["abc"], null, ["abc"]] + , ["?*****?c", ["abc"], null, ["abc"]] + , ["?***?****c", ["abc"], null, ["abc"]] + , ["?***?****?", ["abc"], null, ["abc"]] + , ["?***?****", ["abc"], null, ["abc"]] + , ["*******c", ["abc"], null, ["abc"]] + , ["*******?", ["abc"], null, ["abc"]] + , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["[-abc]", ["-"], null, ["-"]] + , ["[abc-]", ["-"], null, ["-"]] + , ["\\", ["\\"], null, ["\\"]] + , ["[\\\\]", ["\\"], null, ["\\"]] + , ["[[]", ["["], null, ["["]] + , ["[", ["["], null, ["["]] + , ["[*", ["[abc"], null, ["[abc"]] + , "a right bracket shall lose its special meaning and\n" + + "represent itself in a bracket expression if it occurs\n" + + "first in the list. -- POSIX.2 2.8.3.2" + , ["[]]", ["]"], null, ["]"]] + , ["[]-]", ["]"], null, ["]"]] + , ["[a-\z]", ["p"], null, ["p"]] + , ["??**********?****?", [], { null: true }, ["abc"]] + , ["??**********?****c", [], { null: true }, ["abc"]] + , ["?************c****?****", [], { null: true }, ["abc"]] + , ["*c*?**", [], { null: true }, ["abc"]] + , ["a*****c*?**", [], { null: true }, ["abc"]] + , ["a********???*******", [], { null: true }, ["abc"]] + , ["[]", [], { null: true }, ["a"]] + , ["[abc", [], { null: true }, ["["]] + + , "nocase tests" + , ["XYZ", ["xYz"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["ab*", ["ABC"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + + // [ pattern, [matches], MM opts, files, TAP opts] + , "onestar/twostar" + , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] + , ["{/?,*}", ["/a", "bb"], {null: true} + , ["/a", "/b/b", "/a/b/c", "bb"]] + + , "dots should not match unless requested" + , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] + + // .. and . can only match patterns starting with ., + // even when options.dot is set. + , function () { + files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] + } + , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] + , ["a/*/b", ["a/c/b"], {dot:false}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] + + + // this also tests that changing the options needs + // to change the cache key, even if the pattern is + // the same! + , ["**", ["a/b","a/.d",".a/.d"], { dot: true } + , [ ".a/.d", "a/.d", "a/b"]] + + , "paren sets cannot contain slashes" + , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] + + // brace sets trump all else. + // + // invalid glob pattern. fails on bash4 and bsdglob. + // however, in this implementation, it's easier just + // to do the intuitive thing, and let brace-expansion + // actually come before parsing any extglob patterns, + // like the documentation seems to say. + // + // XXX: if anyone complains about this, either fix it + // or tell them to grow up and stop complaining. + // + // bash/bsdglob says this: + // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] + // but we do this instead: + , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] + + // test partial parsing in the presence of comment/negation chars + , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] + , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] + + // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. + , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] + , {} + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] + + + // crazy nested {,,} and *(||) tests. + , function () { + files = [ "a", "b", "c", "d" + , "ab", "ac", "ad" + , "bc", "cb" + , "bc,d", "c,db", "c,d" + , "d)", "(b|c", "*(b|c" + , "b|c", "b|cc", "cb|c" + , "x(a|b|c)", "x(a|c)" + , "(a|b|c)", "(a|c)"] + } + , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] + , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] + // a + // *(b|c) + // *(b|d) + , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] + , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] + + + // test various flag settings. + , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] + , { noext: true } ] + , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} + , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] + , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] + + + // begin channelling Boole and deMorgan... + , "negation tests" + , function () { + files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] + } + + // anything that is NOT a* matches. + , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] + + // anything that IS !a* matches. + , ["!a*", ["!ab", "!abc"], {nonegate: true}] + + // anything that IS a* matches + , ["!!a*", ["a!b"]] + + // anything that is NOT !a* matches + , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] + + // negation nestled within a pattern + , function () { + files = [ "foo.js" + , "foo.bar" + // can't match this one without negative lookbehind. + , "foo.js.js" + , "blar.js" + , "foo." + , "boo.js.boo" ] + } + , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] + + // https://github.com/isaacs/minimatch/issues/5 + , function () { + files = [ 'a/b/.x/c' + , 'a/b/.x/c/d' + , 'a/b/.x/c/d/e' + , 'a/b/.x' + , 'a/b/.x/' + , 'a/.x/b' + , '.x' + , '.x/' + , '.x/a' + , '.x/a/b' + , 'a/.x/b/.x/c' + , '.x/.x' ] + } + , ["**/.x/**", [ '.x/' + , '.x/a' + , '.x/a/b' + , 'a/.x/b' + , 'a/b/.x/' + , 'a/b/.x/c' + , 'a/b/.x/c/d' + , 'a/b/.x/c/d/e' ] ] + + ] + +var regexps = + [ '/^(?:(?=.)a[^/]*?)$/', + '/^(?:(?=.)X[^/]*?)$/', + '/^(?:(?=.)X[^/]*?)$/', + '/^(?:\\*)$/', + '/^(?:(?=.)\\*[^/]*?)$/', + '/^(?:\\*\\*)$/', + '/^(?:(?=.)b[^/]*?\\/)$/', + '/^(?:(?=.)c[^/]*?)$/', + '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/', + '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/', + '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/', + '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/', + '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/', + '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/', + '/^(?:(?=.)a[^/]*?[^c])$/', + '/^(?:(?=.)a[X-]b)$/', + '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/', + '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/', + '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/', + '/^(?:(?=.)a[b]c)$/', + '/^(?:(?=.)a[b]c)$/', + '/^(?:(?=.)a[^/]c)$/', + '/^(?:a\\*c)$/', + 'false', + '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/', + '/^(?:man\\/man1\\/bash\\.1)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/', + '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/', + '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', + '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[-abc])$/', + '/^(?:(?!\\.)(?=.)[abc-])$/', + '/^(?:\\\\)$/', + '/^(?:(?!\\.)(?=.)[\\\\])$/', + '/^(?:(?!\\.)(?=.)[\\[])$/', + '/^(?:\\[)$/', + '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[\\]])$/', + '/^(?:(?!\\.)(?=.)[\\]-])$/', + '/^(?:(?!\\.)(?=.)[a-z])$/', + '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/', + '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/', + '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/', + '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/', + '/^(?:\\[\\])$/', + '/^(?:\\[abc)$/', + '/^(?:(?=.)XYZ)$/i', + '/^(?:(?=.)ab[^/]*?)$/i', + '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i', + '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/', + '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/', + '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/', + '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/', + '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/', + '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/', + '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/', + '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/', + '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/', + '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/', + '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/', + '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/', + '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/', + '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/', + '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/', + '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/', + '/^(?:(?=.)a[^/]b)$/', + '/^(?:(?=.)#[^/]*?)$/', + '/^(?!^(?:(?=.)a[^/]*?)$).*$/', + '/^(?:(?=.)\\!a[^/]*?)$/', + '/^(?:(?=.)a[^/]*?)$/', + '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/', + '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/', + '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ] +var re = 0; + +tap.test("basic tests", function (t) { + var start = Date.now() + + // [ pattern, [matches], MM opts, files, TAP opts] + patterns.forEach(function (c) { + if (typeof c === "function") return c() + if (typeof c === "string") return t.comment(c) + + var pattern = c[0] + , expect = c[1].sort(alpha) + , options = c[2] || {} + , f = c[3] || files + , tapOpts = c[4] || {} + + // options.debug = true + var m = new mm.Minimatch(pattern, options) + var r = m.makeRe() + var expectRe = regexps[re++] + tapOpts.re = String(r) || JSON.stringify(r) + tapOpts.files = JSON.stringify(f) + tapOpts.pattern = pattern + tapOpts.set = m.set + tapOpts.negated = m.negate + + var actual = mm.match(f, pattern, options) + actual.sort(alpha) + + t.equivalent( actual, expect + , JSON.stringify(pattern) + " " + JSON.stringify(expect) + , tapOpts ) + + t.equal(tapOpts.re, expectRe, tapOpts) + }) + + t.comment("time=" + (Date.now() - start) + "ms") + t.end() +}) + +tap.test("global leak test", function (t) { + var globalAfter = Object.keys(global) + t.equivalent(globalAfter, globalBefore, "no new globals, please") + t.end() +}) + +function alpha (a, b) { + return a > b ? 1 : -1 +} diff --git a/www/node_modules/jasmine/node_modules/minimatch/test/brace-expand.js b/www/node_modules/jasmine/node_modules/minimatch/test/brace-expand.js new file mode 100644 index 0000000..7ee278a --- /dev/null +++ b/www/node_modules/jasmine/node_modules/minimatch/test/brace-expand.js @@ -0,0 +1,33 @@ +var tap = require("tap") + , minimatch = require("../") + +tap.test("brace expansion", function (t) { + // [ pattern, [expanded] ] + ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}" + , [ "abxy" + , "abxz" + , "acdxy" + , "acdxz" + , "acexy" + , "acexz" + , "afhxy" + , "afhxz" + , "aghxy" + , "aghxz" ] ] + , [ "a{1..5}b" + , [ "a1b" + , "a2b" + , "a3b" + , "a4b" + , "a5b" ] ] + , [ "a{b}c", ["a{b}c"] ] + ].forEach(function (tc) { + var p = tc[0] + , expect = tc[1] + t.equivalent(minimatch.braceExpand(p), expect, p) + }) + console.error("ending") + t.end() +}) + + diff --git a/www/node_modules/jasmine/node_modules/minimatch/test/caching.js b/www/node_modules/jasmine/node_modules/minimatch/test/caching.js new file mode 100644 index 0000000..0fec4b0 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/minimatch/test/caching.js @@ -0,0 +1,14 @@ +var Minimatch = require("../minimatch.js").Minimatch +var tap = require("tap") +tap.test("cache test", function (t) { + var mm1 = new Minimatch("a?b") + var mm2 = new Minimatch("a?b") + t.equal(mm1, mm2, "should get the same object") + // the lru should drop it after 100 entries + for (var i = 0; i < 100; i ++) { + new Minimatch("a"+i) + } + mm2 = new Minimatch("a?b") + t.notEqual(mm1, mm2, "cache should have dropped") + t.end() +}) diff --git a/www/node_modules/jasmine/node_modules/minimatch/test/defaults.js b/www/node_modules/jasmine/node_modules/minimatch/test/defaults.js new file mode 100644 index 0000000..75e0571 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/minimatch/test/defaults.js @@ -0,0 +1,274 @@ +// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test +// +// TODO: Some of these tests do very bad things with backslashes, and will +// most likely fail badly on windows. They should probably be skipped. + +var tap = require("tap") + , globalBefore = Object.keys(global) + , mm = require("../") + , files = [ "a", "b", "c", "d", "abc" + , "abd", "abe", "bb", "bcd" + , "ca", "cb", "dd", "de" + , "bdir/", "bdir/cfile"] + , next = files.concat([ "a-b", "aXb" + , ".x", ".y" ]) + +tap.test("basic tests", function (t) { + var start = Date.now() + + // [ pattern, [matches], MM opts, files, TAP opts] + ; [ "http://www.bashcookbook.com/bashinfo" + + "/source/bash-1.14.7/tests/glob-test" + , ["a*", ["a", "abc", "abd", "abe"]] + , ["X*", ["X*"], {nonull: true}] + + // allow null glob expansion + , ["X*", []] + + // isaacs: Slightly different than bash/sh/ksh + // \\* is not un-escaped to literal "*" in a failed match, + // but it does make it get treated as a literal star + , ["\\*", ["\\*"], {nonull: true}] + , ["\\**", ["\\**"], {nonull: true}] + , ["\\*\\*", ["\\*\\*"], {nonull: true}] + + , ["b*/", ["bdir/"]] + , ["c*", ["c", "ca", "cb"]] + , ["**", files] + + , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}] + , ["s/\\..*//", ["s/\\..*//"], {nonull: true}] + + , "legendary larry crashes bashes" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}] + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/" + , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}] + + , "character classes" + , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]] + , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd", + "bdir/", "ca", "cb", "dd", "de"]] + , ["a*[^c]", ["abd", "abe"]] + , function () { files.push("a-b", "aXb") } + , ["a[X-]b", ["a-b", "aXb"]] + , function () { files.push(".x", ".y") } + , ["[^a-c]*", ["d", "dd", "de"]] + , function () { files.push("a*b/", "a*b/ooo") } + , ["a\\*b/*", ["a*b/ooo"]] + , ["a\\*?/*", ["a*b/ooo"]] + , ["*\\\\!*", [], {null: true}, ["echo !7"]] + , ["*\\!*", ["echo !7"], null, ["echo !7"]] + , ["*.\\*", ["r.*"], null, ["r.*"]] + , ["a[b]c", ["abc"]] + , ["a[\\b]c", ["abc"]] + , ["a?c", ["abc"]] + , ["a\\*c", [], {null: true}, ["abc"]] + , ["", [""], { null: true }, [""]] + + , "http://www.opensource.apple.com/source/bash/bash-23/" + + "bash/tests/glob-test" + , function () { files.push("man/", "man/man1/", "man/man1/bash.1") } + , ["*/man*/bash.*", ["man/man1/bash.1"]] + , ["man/man1/bash.1", ["man/man1/bash.1"]] + , ["a***c", ["abc"], null, ["abc"]] + , ["a*****?c", ["abc"], null, ["abc"]] + , ["?*****??", ["abc"], null, ["abc"]] + , ["*****??", ["abc"], null, ["abc"]] + , ["?*****?c", ["abc"], null, ["abc"]] + , ["?***?****c", ["abc"], null, ["abc"]] + , ["?***?****?", ["abc"], null, ["abc"]] + , ["?***?****", ["abc"], null, ["abc"]] + , ["*******c", ["abc"], null, ["abc"]] + , ["*******?", ["abc"], null, ["abc"]] + , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]] + , ["[-abc]", ["-"], null, ["-"]] + , ["[abc-]", ["-"], null, ["-"]] + , ["\\", ["\\"], null, ["\\"]] + , ["[\\\\]", ["\\"], null, ["\\"]] + , ["[[]", ["["], null, ["["]] + , ["[", ["["], null, ["["]] + , ["[*", ["[abc"], null, ["[abc"]] + , "a right bracket shall lose its special meaning and\n" + + "represent itself in a bracket expression if it occurs\n" + + "first in the list. -- POSIX.2 2.8.3.2" + , ["[]]", ["]"], null, ["]"]] + , ["[]-]", ["]"], null, ["]"]] + , ["[a-\z]", ["p"], null, ["p"]] + , ["??**********?****?", [], { null: true }, ["abc"]] + , ["??**********?****c", [], { null: true }, ["abc"]] + , ["?************c****?****", [], { null: true }, ["abc"]] + , ["*c*?**", [], { null: true }, ["abc"]] + , ["a*****c*?**", [], { null: true }, ["abc"]] + , ["a********???*******", [], { null: true }, ["abc"]] + , ["[]", [], { null: true }, ["a"]] + , ["[abc", [], { null: true }, ["["]] + + , "nocase tests" + , ["XYZ", ["xYz"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["ab*", ["ABC"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true } + , ["xYz", "ABC", "IjK"]] + + // [ pattern, [matches], MM opts, files, TAP opts] + , "onestar/twostar" + , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]] + , ["{/?,*}", ["/a", "bb"], {null: true} + , ["/a", "/b/b", "/a/b/c", "bb"]] + + , "dots should not match unless requested" + , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]] + + // .. and . can only match patterns starting with ., + // even when options.dot is set. + , function () { + files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"] + } + , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}] + , ["a/*/b", ["a/c/b"], {dot:false}] + , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}] + + + // this also tests that changing the options needs + // to change the cache key, even if the pattern is + // the same! + , ["**", ["a/b","a/.d",".a/.d"], { dot: true } + , [ ".a/.d", "a/.d", "a/b"]] + + , "paren sets cannot contain slashes" + , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]] + + // brace sets trump all else. + // + // invalid glob pattern. fails on bash4 and bsdglob. + // however, in this implementation, it's easier just + // to do the intuitive thing, and let brace-expansion + // actually come before parsing any extglob patterns, + // like the documentation seems to say. + // + // XXX: if anyone complains about this, either fix it + // or tell them to grow up and stop complaining. + // + // bash/bsdglob says this: + // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]] + // but we do this instead: + , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]] + + // test partial parsing in the presence of comment/negation chars + , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]] + , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]] + + // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped. + , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g" + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"] + , {} + , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]] + + + // crazy nested {,,} and *(||) tests. + , function () { + files = [ "a", "b", "c", "d" + , "ab", "ac", "ad" + , "bc", "cb" + , "bc,d", "c,db", "c,d" + , "d)", "(b|c", "*(b|c" + , "b|c", "b|cc", "cb|c" + , "x(a|b|c)", "x(a|c)" + , "(a|b|c)", "(a|c)"] + } + , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]] + , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]] + // a + // *(b|c) + // *(b|d) + , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]] + , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]] + + + // test various flag settings. + , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"] + , { noext: true } ] + , ["a?b", ["x/y/acb", "acb/"], {matchBase: true} + , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ] + , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]] + + + // begin channelling Boole and deMorgan... + , "negation tests" + , function () { + files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"] + } + + // anything that is NOT a* matches. + , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]] + + // anything that IS !a* matches. + , ["!a*", ["!ab", "!abc"], {nonegate: true}] + + // anything that IS a* matches + , ["!!a*", ["a!b"]] + + // anything that is NOT !a* matches + , ["!\\!a*", ["a!b", "d", "e", "\\!a"]] + + // negation nestled within a pattern + , function () { + files = [ "foo.js" + , "foo.bar" + // can't match this one without negative lookbehind. + , "foo.js.js" + , "blar.js" + , "foo." + , "boo.js.boo" ] + } + , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ] + + ].forEach(function (c) { + if (typeof c === "function") return c() + if (typeof c === "string") return t.comment(c) + + var pattern = c[0] + , expect = c[1].sort(alpha) + , options = c[2] + , f = c[3] || files + , tapOpts = c[4] || {} + + // options.debug = true + var Class = mm.defaults(options).Minimatch + var m = new Class(pattern, {}) + var r = m.makeRe() + tapOpts.re = String(r) || JSON.stringify(r) + tapOpts.files = JSON.stringify(f) + tapOpts.pattern = pattern + tapOpts.set = m.set + tapOpts.negated = m.negate + + var actual = mm.match(f, pattern, options) + actual.sort(alpha) + + t.equivalent( actual, expect + , JSON.stringify(pattern) + " " + JSON.stringify(expect) + , tapOpts ) + }) + + t.comment("time=" + (Date.now() - start) + "ms") + t.end() +}) + +tap.test("global leak test", function (t) { + var globalAfter = Object.keys(global) + t.equivalent(globalAfter, globalBefore, "no new globals, please") + t.end() +}) + +function alpha (a, b) { + return a > b ? 1 : -1 +} diff --git a/www/node_modules/jasmine/node_modules/minimatch/test/extglob-ending-with-state-char.js b/www/node_modules/jasmine/node_modules/minimatch/test/extglob-ending-with-state-char.js new file mode 100644 index 0000000..6676e26 --- /dev/null +++ b/www/node_modules/jasmine/node_modules/minimatch/test/extglob-ending-with-state-char.js @@ -0,0 +1,8 @@ +var test = require('tap').test +var minimatch = require('../') + +test('extglob ending with statechar', function(t) { + t.notOk(minimatch('ax', 'a?(b*)')) + t.ok(minimatch('ax', '?(a*|b)')) + t.end() +}) diff --git a/www/node_modules/jasmine/package.json b/www/node_modules/jasmine/package.json new file mode 100644 index 0000000..5b20c3a --- /dev/null +++ b/www/node_modules/jasmine/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + "jasmine", + "/Users/adamdon/Desktop/studywell/studywell/sw/www" + ] + ], + "_from": "jasmine@latest", + "_id": "jasmine@2.4.1", + "_inCache": true, + "_installable": true, + "_location": "/jasmine", + "_nodeVersion": "0.12.7", + "_npmUser": { + "email": "gregg@slackersoft.net", + "name": "slackersoft" + }, + "_npmVersion": "2.12.1", + "_phantomChildren": { + "inherits": "2.0.1", + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + }, + "_requested": { + "name": "jasmine", + "raw": "jasmine", + "rawSpec": "", + "scope": null, + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.4.1.tgz", + "_shasum": "9016dda453213d27ac6d43dc4ea97315a189085e", + "_shrinkwrap": null, + "_spec": "jasmine", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www", + "bin": { + "jasmine": "./bin/jasmine.js" + }, + "bugs": { + "url": "https://github.com/jasmine/jasmine-npm/issues" + }, + "dependencies": { + "exit": "^0.1.2", + "glob": "^3.2.11", + "jasmine-core": "~2.4.0" + }, + "description": "Command line jasmine", + "devDependencies": { + "grunt": "^0.4.2", + "grunt-cli": "^0.1.13", + "grunt-contrib-jshint": "^0.11.0", + "shelljs": "^0.3.0" + }, + "directories": {}, + "dist": { + "shasum": "9016dda453213d27ac6d43dc4ea97315a189085e", + "tarball": "http://registry.npmjs.org/jasmine/-/jasmine-2.4.1.tgz" + }, + "gitHead": "17344da242f81c61e4d19a895960bf9414fae07d", + "homepage": "http://jasmine.github.io/", + "keywords": [ + "test", + "jasmine", + "tdd", + "bdd" + ], + "license": "MIT", + "main": "./lib/jasmine.js", + "maintainers": [ + { + "email": "gregg@slackersoft.net", + "name": "slackersoft" + }, + { + "email": "dwfrank@pivotallabs.com", + "name": "dwfrank" + }, + { + "email": "chris.amavisca@gmail.com", + "name": "amavisca" + } + ], + "name": "jasmine", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jasmine/jasmine-npm.git" + }, + "scripts": { + "test": "grunt && ./bin/jasmine.js" + }, + "version": "2.4.1" +} diff --git a/www/node_modules/jasmine/tasks/jasmine.js b/www/node_modules/jasmine/tasks/jasmine.js new file mode 100644 index 0000000..b137c18 --- /dev/null +++ b/www/node_modules/jasmine/tasks/jasmine.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = function(grunt) { + var Jasmine = require('../lib/jasmine'); + + grunt.registerTask('specs', function() { + var jasmine = new Jasmine(); + var done = this.async(); + + jasmine.loadConfigFile(process.env.JASMINE_CONFIG_PATH || './spec/support/jasmine.json'); + jasmine.onComplete(done); + jasmine.execute(); + }); +}; diff --git a/www/node_modules/lodash/LICENSE b/www/node_modules/lodash/LICENSE new file mode 100644 index 0000000..bcbe13d --- /dev/null +++ b/www/node_modules/lodash/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright 2012-2016 The Dojo Foundation +Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/www/node_modules/lodash/README.md b/www/node_modules/lodash/README.md new file mode 100644 index 0000000..56a419b --- /dev/null +++ b/www/node_modules/lodash/README.md @@ -0,0 +1,40 @@ +# lodash v4.6.1 + +The [lodash](https://lodash.com/) library exported as [Node.js](https://nodejs.org/) modules. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash +``` + +In Node.js: +```js +// Load the full build. +var _ = require('lodash'); +// Load the core build. +var _ = require('lodash/core'); +// Load the fp build for immutable auto-curried iteratee-first data-last methods. +var _ = require('lodash/fp'); + +// Load a method category. +var array = require('lodash/array'); +var object = require('lodash/fp/object'); + +// Load a single method for smaller builds with browserify/rollup/webpack. +var chunk = require('lodash/chunk'); +var extend = require('lodash/fp/extend'); +``` + +See the [package source](https://github.com/lodash/lodash/tree/4.6.1-npm) for more details. + +**Note:**
    +Don’t assign values to the [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL.
    +Install [n_](https://www.npmjs.com/package/n_) for a REPL that includes lodash by default. + +## Support + +Tested in Chrome 47-48, Firefox 43-44, IE 9-11, Edge 13, Safari 8-9, Node.js 0.10, 0.12, 4, & 5, & PhantomJS 1.9.8.
    +Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available. diff --git a/www/node_modules/lodash/_Hash.js b/www/node_modules/lodash/_Hash.js new file mode 100644 index 0000000..8647d16 --- /dev/null +++ b/www/node_modules/lodash/_Hash.js @@ -0,0 +1,18 @@ +var nativeCreate = require('./_nativeCreate'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Creates an hash object. + * + * @private + * @constructor + * @returns {Object} Returns the new hash object. + */ +function Hash() {} + +// Avoid inheriting from `Object.prototype` when possible. +Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto; + +module.exports = Hash; diff --git a/www/node_modules/lodash/_LazyWrapper.js b/www/node_modules/lodash/_LazyWrapper.js new file mode 100644 index 0000000..ad01ef8 --- /dev/null +++ b/www/node_modules/lodash/_LazyWrapper.js @@ -0,0 +1,27 @@ +var baseCreate = require('./_baseCreate'), + baseLodash = require('./_baseLodash'); + +/** Used as references for the maximum length and index of an array. */ +var MAX_ARRAY_LENGTH = 4294967295; + +/** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @constructor + * @param {*} value The value to wrap. + */ +function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = MAX_ARRAY_LENGTH; + this.__views__ = []; +} + +LazyWrapper.prototype = baseCreate(baseLodash.prototype); +LazyWrapper.prototype.constructor = LazyWrapper; + +module.exports = LazyWrapper; diff --git a/www/node_modules/lodash/_LodashWrapper.js b/www/node_modules/lodash/_LodashWrapper.js new file mode 100644 index 0000000..7c255b2 --- /dev/null +++ b/www/node_modules/lodash/_LodashWrapper.js @@ -0,0 +1,22 @@ +var baseCreate = require('./_baseCreate'), + baseLodash = require('./_baseLodash'); + +/** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + */ +function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined; +} + +LodashWrapper.prototype = baseCreate(baseLodash.prototype); +LodashWrapper.prototype.constructor = LodashWrapper; + +module.exports = LodashWrapper; diff --git a/www/node_modules/lodash/_Map.js b/www/node_modules/lodash/_Map.js new file mode 100644 index 0000000..b73f29a --- /dev/null +++ b/www/node_modules/lodash/_Map.js @@ -0,0 +1,7 @@ +var getNative = require('./_getNative'), + root = require('./_root'); + +/* Built-in method references that are verified to be native. */ +var Map = getNative(root, 'Map'); + +module.exports = Map; diff --git a/www/node_modules/lodash/_MapCache.js b/www/node_modules/lodash/_MapCache.js new file mode 100644 index 0000000..2652843 --- /dev/null +++ b/www/node_modules/lodash/_MapCache.js @@ -0,0 +1,32 @@ +var mapClear = require('./_mapClear'), + mapDelete = require('./_mapDelete'), + mapGet = require('./_mapGet'), + mapHas = require('./_mapHas'), + mapSet = require('./_mapSet'); + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function MapCache(values) { + var index = -1, + length = values ? values.length : 0; + + this.clear(); + while (++index < length) { + var entry = values[index]; + this.set(entry[0], entry[1]); + } +} + +// Add functions to the `MapCache`. +MapCache.prototype.clear = mapClear; +MapCache.prototype['delete'] = mapDelete; +MapCache.prototype.get = mapGet; +MapCache.prototype.has = mapHas; +MapCache.prototype.set = mapSet; + +module.exports = MapCache; diff --git a/www/node_modules/lodash/_Reflect.js b/www/node_modules/lodash/_Reflect.js new file mode 100644 index 0000000..1de7475 --- /dev/null +++ b/www/node_modules/lodash/_Reflect.js @@ -0,0 +1,6 @@ +var root = require('./_root'); + +/** Built-in value references. */ +var Reflect = root.Reflect; + +module.exports = Reflect; diff --git a/www/node_modules/lodash/_Set.js b/www/node_modules/lodash/_Set.js new file mode 100644 index 0000000..b3c8dcb --- /dev/null +++ b/www/node_modules/lodash/_Set.js @@ -0,0 +1,7 @@ +var getNative = require('./_getNative'), + root = require('./_root'); + +/* Built-in method references that are verified to be native. */ +var Set = getNative(root, 'Set'); + +module.exports = Set; diff --git a/www/node_modules/lodash/_SetCache.js b/www/node_modules/lodash/_SetCache.js new file mode 100644 index 0000000..5d9d620 --- /dev/null +++ b/www/node_modules/lodash/_SetCache.js @@ -0,0 +1,25 @@ +var MapCache = require('./_MapCache'), + cachePush = require('./_cachePush'); + +/** + * + * Creates a set cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values ? values.length : 0; + + this.__data__ = new MapCache; + while (++index < length) { + this.push(values[index]); + } +} + +// Add functions to the `SetCache`. +SetCache.prototype.push = cachePush; + +module.exports = SetCache; diff --git a/www/node_modules/lodash/_Stack.js b/www/node_modules/lodash/_Stack.js new file mode 100644 index 0000000..345577e --- /dev/null +++ b/www/node_modules/lodash/_Stack.js @@ -0,0 +1,32 @@ +var stackClear = require('./_stackClear'), + stackDelete = require('./_stackDelete'), + stackGet = require('./_stackGet'), + stackHas = require('./_stackHas'), + stackSet = require('./_stackSet'); + +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function Stack(values) { + var index = -1, + length = values ? values.length : 0; + + this.clear(); + while (++index < length) { + var entry = values[index]; + this.set(entry[0], entry[1]); + } +} + +// Add functions to the `Stack` cache. +Stack.prototype.clear = stackClear; +Stack.prototype['delete'] = stackDelete; +Stack.prototype.get = stackGet; +Stack.prototype.has = stackHas; +Stack.prototype.set = stackSet; + +module.exports = Stack; diff --git a/www/node_modules/lodash/_Symbol.js b/www/node_modules/lodash/_Symbol.js new file mode 100644 index 0000000..a013f7c --- /dev/null +++ b/www/node_modules/lodash/_Symbol.js @@ -0,0 +1,6 @@ +var root = require('./_root'); + +/** Built-in value references. */ +var Symbol = root.Symbol; + +module.exports = Symbol; diff --git a/www/node_modules/lodash/_Uint8Array.js b/www/node_modules/lodash/_Uint8Array.js new file mode 100644 index 0000000..2fb30e1 --- /dev/null +++ b/www/node_modules/lodash/_Uint8Array.js @@ -0,0 +1,6 @@ +var root = require('./_root'); + +/** Built-in value references. */ +var Uint8Array = root.Uint8Array; + +module.exports = Uint8Array; diff --git a/www/node_modules/lodash/_WeakMap.js b/www/node_modules/lodash/_WeakMap.js new file mode 100644 index 0000000..567f86c --- /dev/null +++ b/www/node_modules/lodash/_WeakMap.js @@ -0,0 +1,7 @@ +var getNative = require('./_getNative'), + root = require('./_root'); + +/* Built-in method references that are verified to be native. */ +var WeakMap = getNative(root, 'WeakMap'); + +module.exports = WeakMap; diff --git a/www/node_modules/lodash/_addMapEntry.js b/www/node_modules/lodash/_addMapEntry.js new file mode 100644 index 0000000..0112ef7 --- /dev/null +++ b/www/node_modules/lodash/_addMapEntry.js @@ -0,0 +1,15 @@ +/** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ +function addMapEntry(map, pair) { + // Don't return `Map#set` because it doesn't return the map instance in IE 11. + map.set(pair[0], pair[1]); + return map; +} + +module.exports = addMapEntry; diff --git a/www/node_modules/lodash/_addSetEntry.js b/www/node_modules/lodash/_addSetEntry.js new file mode 100644 index 0000000..7b75c13 --- /dev/null +++ b/www/node_modules/lodash/_addSetEntry.js @@ -0,0 +1,14 @@ +/** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ +function addSetEntry(set, value) { + set.add(value); + return set; +} + +module.exports = addSetEntry; diff --git a/www/node_modules/lodash/_apply.js b/www/node_modules/lodash/_apply.js new file mode 100644 index 0000000..22d4f8a --- /dev/null +++ b/www/node_modules/lodash/_apply.js @@ -0,0 +1,22 @@ +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + var length = args.length; + switch (length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); +} + +module.exports = apply; diff --git a/www/node_modules/lodash/_arrayAggregator.js b/www/node_modules/lodash/_arrayAggregator.js new file mode 100644 index 0000000..562eeb3 --- /dev/null +++ b/www/node_modules/lodash/_arrayAggregator.js @@ -0,0 +1,22 @@ +/** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ +function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); + } + return accumulator; +} + +module.exports = arrayAggregator; diff --git a/www/node_modules/lodash/_arrayConcat.js b/www/node_modules/lodash/_arrayConcat.js new file mode 100644 index 0000000..96e7741 --- /dev/null +++ b/www/node_modules/lodash/_arrayConcat.js @@ -0,0 +1,25 @@ +/** + * Creates a new array concatenating `array` with `other`. + * + * @private + * @param {Array} array The first array to concatenate. + * @param {Array} other The second array to concatenate. + * @returns {Array} Returns the new concatenated array. + */ +function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; +} + +module.exports = arrayConcat; diff --git a/www/node_modules/lodash/_arrayEach.js b/www/node_modules/lodash/_arrayEach.js new file mode 100644 index 0000000..c302e63 --- /dev/null +++ b/www/node_modules/lodash/_arrayEach.js @@ -0,0 +1,22 @@ +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +module.exports = arrayEach; diff --git a/www/node_modules/lodash/_arrayEachRight.js b/www/node_modules/lodash/_arrayEachRight.js new file mode 100644 index 0000000..5318585 --- /dev/null +++ b/www/node_modules/lodash/_arrayEachRight.js @@ -0,0 +1,21 @@ +/** + * A specialized version of `_.forEachRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; +} + +module.exports = arrayEachRight; diff --git a/www/node_modules/lodash/_arrayEvery.js b/www/node_modules/lodash/_arrayEvery.js new file mode 100644 index 0000000..d3ba018 --- /dev/null +++ b/www/node_modules/lodash/_arrayEvery.js @@ -0,0 +1,22 @@ +/** + * A specialized version of `_.every` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. + */ +function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; +} + +module.exports = arrayEvery; diff --git a/www/node_modules/lodash/_arrayFilter.js b/www/node_modules/lodash/_arrayFilter.js new file mode 100644 index 0000000..7b61ba6 --- /dev/null +++ b/www/node_modules/lodash/_arrayFilter.js @@ -0,0 +1,25 @@ +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +module.exports = arrayFilter; diff --git a/www/node_modules/lodash/_arrayIncludes.js b/www/node_modules/lodash/_arrayIncludes.js new file mode 100644 index 0000000..9574f5d --- /dev/null +++ b/www/node_modules/lodash/_arrayIncludes.js @@ -0,0 +1,16 @@ +var baseIndexOf = require('./_baseIndexOf'); + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} array The array to search. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + return !!array.length && baseIndexOf(array, value, 0) > -1; +} + +module.exports = arrayIncludes; diff --git a/www/node_modules/lodash/_arrayIncludesWith.js b/www/node_modules/lodash/_arrayIncludesWith.js new file mode 100644 index 0000000..88ea237 --- /dev/null +++ b/www/node_modules/lodash/_arrayIncludesWith.js @@ -0,0 +1,22 @@ +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to search. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +module.exports = arrayIncludesWith; diff --git a/www/node_modules/lodash/_arrayMap.js b/www/node_modules/lodash/_arrayMap.js new file mode 100644 index 0000000..73b29cf --- /dev/null +++ b/www/node_modules/lodash/_arrayMap.js @@ -0,0 +1,21 @@ +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +module.exports = arrayMap; diff --git a/www/node_modules/lodash/_arrayPush.js b/www/node_modules/lodash/_arrayPush.js new file mode 100644 index 0000000..7d742b3 --- /dev/null +++ b/www/node_modules/lodash/_arrayPush.js @@ -0,0 +1,20 @@ +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +module.exports = arrayPush; diff --git a/www/node_modules/lodash/_arrayReduce.js b/www/node_modules/lodash/_arrayReduce.js new file mode 100644 index 0000000..6a355bc --- /dev/null +++ b/www/node_modules/lodash/_arrayReduce.js @@ -0,0 +1,25 @@ +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +module.exports = arrayReduce; diff --git a/www/node_modules/lodash/_arrayReduceRight.js b/www/node_modules/lodash/_arrayReduceRight.js new file mode 100644 index 0000000..b33a2d0 --- /dev/null +++ b/www/node_modules/lodash/_arrayReduceRight.js @@ -0,0 +1,23 @@ +/** + * A specialized version of `_.reduceRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduceRight(array, iteratee, accumulator, initAccum) { + var length = array.length; + if (initAccum && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; +} + +module.exports = arrayReduceRight; diff --git a/www/node_modules/lodash/_arraySome.js b/www/node_modules/lodash/_arraySome.js new file mode 100644 index 0000000..b93d531 --- /dev/null +++ b/www/node_modules/lodash/_arraySome.js @@ -0,0 +1,22 @@ +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +module.exports = arraySome; diff --git a/www/node_modules/lodash/_assignInDefaults.js b/www/node_modules/lodash/_assignInDefaults.js new file mode 100644 index 0000000..ea6b0e3 --- /dev/null +++ b/www/node_modules/lodash/_assignInDefaults.js @@ -0,0 +1,27 @@ +var eq = require('./eq'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used by `_.defaults` to customize its `_.assignIn` use. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. + */ +function assignInDefaults(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; +} + +module.exports = assignInDefaults; diff --git a/www/node_modules/lodash/_assignMergeValue.js b/www/node_modules/lodash/_assignMergeValue.js new file mode 100644 index 0000000..61dd583 --- /dev/null +++ b/www/node_modules/lodash/_assignMergeValue.js @@ -0,0 +1,19 @@ +var eq = require('./eq'); + +/** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (typeof key == 'number' && value === undefined && !(key in object))) { + object[key] = value; + } +} + +module.exports = assignMergeValue; diff --git a/www/node_modules/lodash/_assignValue.js b/www/node_modules/lodash/_assignValue.js new file mode 100644 index 0000000..35d49f0 --- /dev/null +++ b/www/node_modules/lodash/_assignValue.js @@ -0,0 +1,27 @@ +var eq = require('./eq'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } +} + +module.exports = assignValue; diff --git a/www/node_modules/lodash/_assocDelete.js b/www/node_modules/lodash/_assocDelete.js new file mode 100644 index 0000000..709a04a --- /dev/null +++ b/www/node_modules/lodash/_assocDelete.js @@ -0,0 +1,31 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * Removes `key` and its value from the associative array. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function assocDelete(array, key) { + var index = assocIndexOf(array, key); + if (index < 0) { + return false; + } + var lastIndex = array.length - 1; + if (index == lastIndex) { + array.pop(); + } else { + splice.call(array, index, 1); + } + return true; +} + +module.exports = assocDelete; diff --git a/www/node_modules/lodash/_assocGet.js b/www/node_modules/lodash/_assocGet.js new file mode 100644 index 0000000..e53d332 --- /dev/null +++ b/www/node_modules/lodash/_assocGet.js @@ -0,0 +1,16 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** + * Gets the associative array value for `key`. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function assocGet(array, key) { + var index = assocIndexOf(array, key); + return index < 0 ? undefined : array[index][1]; +} + +module.exports = assocGet; diff --git a/www/node_modules/lodash/_assocHas.js b/www/node_modules/lodash/_assocHas.js new file mode 100644 index 0000000..a74bd39 --- /dev/null +++ b/www/node_modules/lodash/_assocHas.js @@ -0,0 +1,15 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** + * Checks if an associative array value for `key` exists. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function assocHas(array, key) { + return assocIndexOf(array, key) > -1; +} + +module.exports = assocHas; diff --git a/www/node_modules/lodash/_assocIndexOf.js b/www/node_modules/lodash/_assocIndexOf.js new file mode 100644 index 0000000..958c8d8 --- /dev/null +++ b/www/node_modules/lodash/_assocIndexOf.js @@ -0,0 +1,22 @@ +var eq = require('./eq'); + +/** + * Gets the index at which the first occurrence of `key` is found in `array` + * of key-value pairs. + * + * @private + * @param {Array} array The array to search. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +module.exports = assocIndexOf; diff --git a/www/node_modules/lodash/_assocSet.js b/www/node_modules/lodash/_assocSet.js new file mode 100644 index 0000000..524f341 --- /dev/null +++ b/www/node_modules/lodash/_assocSet.js @@ -0,0 +1,20 @@ +var assocIndexOf = require('./_assocIndexOf'); + +/** + * Sets the associative array `key` to `value`. + * + * @private + * @param {Array} array The array to modify. + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + */ +function assocSet(array, key, value) { + var index = assocIndexOf(array, key); + if (index < 0) { + array.push([key, value]); + } else { + array[index][1] = value; + } +} + +module.exports = assocSet; diff --git a/www/node_modules/lodash/_baseAggregator.js b/www/node_modules/lodash/_baseAggregator.js new file mode 100644 index 0000000..4bc9e91 --- /dev/null +++ b/www/node_modules/lodash/_baseAggregator.js @@ -0,0 +1,21 @@ +var baseEach = require('./_baseEach'); + +/** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ +function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function(value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; +} + +module.exports = baseAggregator; diff --git a/www/node_modules/lodash/_baseAssign.js b/www/node_modules/lodash/_baseAssign.js new file mode 100644 index 0000000..e5c4a1a --- /dev/null +++ b/www/node_modules/lodash/_baseAssign.js @@ -0,0 +1,17 @@ +var copyObject = require('./_copyObject'), + keys = require('./keys'); + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); +} + +module.exports = baseAssign; diff --git a/www/node_modules/lodash/_baseAt.js b/www/node_modules/lodash/_baseAt.js new file mode 100644 index 0000000..a077cb9 --- /dev/null +++ b/www/node_modules/lodash/_baseAt.js @@ -0,0 +1,23 @@ +var get = require('./get'); + +/** + * The base implementation of `_.at` without support for individual paths. + * + * @private + * @param {Object} object The object to iterate over. + * @param {string[]} paths The property paths of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ +function baseAt(object, paths) { + var index = -1, + isNil = object == null, + length = paths.length, + result = Array(length); + + while (++index < length) { + result[index] = isNil ? undefined : get(object, paths[index]); + } + return result; +} + +module.exports = baseAt; diff --git a/www/node_modules/lodash/_baseCastArrayLikeObject.js b/www/node_modules/lodash/_baseCastArrayLikeObject.js new file mode 100644 index 0000000..17c0c86 --- /dev/null +++ b/www/node_modules/lodash/_baseCastArrayLikeObject.js @@ -0,0 +1,14 @@ +var isArrayLikeObject = require('./isArrayLikeObject'); + +/** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ +function baseCastArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; +} + +module.exports = baseCastArrayLikeObject; diff --git a/www/node_modules/lodash/_baseCastFunction.js b/www/node_modules/lodash/_baseCastFunction.js new file mode 100644 index 0000000..b3d0f72 --- /dev/null +++ b/www/node_modules/lodash/_baseCastFunction.js @@ -0,0 +1,14 @@ +var identity = require('./identity'); + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ +function baseCastFunction(value) { + return typeof value == 'function' ? value : identity; +} + +module.exports = baseCastFunction; diff --git a/www/node_modules/lodash/_baseCastPath.js b/www/node_modules/lodash/_baseCastPath.js new file mode 100644 index 0000000..7634e5b --- /dev/null +++ b/www/node_modules/lodash/_baseCastPath.js @@ -0,0 +1,15 @@ +var isArray = require('./isArray'), + stringToPath = require('./_stringToPath'); + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast property path array. + */ +function baseCastPath(value) { + return isArray(value) ? value : stringToPath(value); +} + +module.exports = baseCastPath; diff --git a/www/node_modules/lodash/_baseClamp.js b/www/node_modules/lodash/_baseClamp.js new file mode 100644 index 0000000..ceadeef --- /dev/null +++ b/www/node_modules/lodash/_baseClamp.js @@ -0,0 +1,22 @@ +/** + * The base implementation of `_.clamp` which doesn't coerce arguments to numbers. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ +function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined) { + number = number <= upper ? number : upper; + } + if (lower !== undefined) { + number = number >= lower ? number : lower; + } + } + return number; +} + +module.exports = baseClamp; diff --git a/www/node_modules/lodash/_baseClone.js b/www/node_modules/lodash/_baseClone.js new file mode 100644 index 0000000..b3f106e --- /dev/null +++ b/www/node_modules/lodash/_baseClone.js @@ -0,0 +1,131 @@ +var Stack = require('./_Stack'), + arrayEach = require('./_arrayEach'), + assignValue = require('./_assignValue'), + baseAssign = require('./_baseAssign'), + baseForOwn = require('./_baseForOwn'), + cloneBuffer = require('./_cloneBuffer'), + copyArray = require('./_copyArray'), + copySymbols = require('./_copySymbols'), + getTag = require('./_getTag'), + initCloneArray = require('./_initCloneArray'), + initCloneByTag = require('./_initCloneByTag'), + initCloneObject = require('./_initCloneObject'), + isArray = require('./isArray'), + isBuffer = require('./isBuffer'), + isHostObject = require('./_isHostObject'), + isObject = require('./isObject'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = +cloneableTags[dateTag] = cloneableTags[float32Tag] = +cloneableTags[float64Tag] = cloneableTags[int8Tag] = +cloneableTags[int16Tag] = cloneableTags[int32Tag] = +cloneableTags[mapTag] = cloneableTags[numberTag] = +cloneableTags[objectTag] = cloneableTags[regexpTag] = +cloneableTags[setTag] = cloneableTags[stringTag] = +cloneableTags[symbolTag] = cloneableTags[uint8Tag] = +cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = +cloneableTags[uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + result = baseAssign(result, value); + return isFull ? copySymbols(value, result) : result; + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return (isFull && !isArr) ? copySymbols(value, result) : result; +} + +module.exports = baseClone; diff --git a/www/node_modules/lodash/_baseConforms.js b/www/node_modules/lodash/_baseConforms.js new file mode 100644 index 0000000..888434d --- /dev/null +++ b/www/node_modules/lodash/_baseConforms.js @@ -0,0 +1,32 @@ +var keys = require('./keys'); + +/** + * The base implementation of `_.conforms` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new function. + */ +function baseConforms(source) { + var props = keys(source), + length = props.length; + + return function(object) { + if (object == null) { + return !length; + } + var index = length; + while (index--) { + var key = props[index], + predicate = source[key], + value = object[key]; + + if ((value === undefined && !(key in Object(object))) || !predicate(value)) { + return false; + } + } + return true; + }; +} + +module.exports = baseConforms; diff --git a/www/node_modules/lodash/_baseCreate.js b/www/node_modules/lodash/_baseCreate.js new file mode 100644 index 0000000..4372cad --- /dev/null +++ b/www/node_modules/lodash/_baseCreate.js @@ -0,0 +1,18 @@ +var isObject = require('./isObject'); + +/** Built-in value references. */ +var objectCreate = Object.create; + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ +function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; +} + +module.exports = baseCreate; diff --git a/www/node_modules/lodash/_baseDelay.js b/www/node_modules/lodash/_baseDelay.js new file mode 100644 index 0000000..c397562 --- /dev/null +++ b/www/node_modules/lodash/_baseDelay.js @@ -0,0 +1,21 @@ +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * The base implementation of `_.delay` and `_.defer` which accepts an array + * of `func` arguments. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments to provide to `func`. + * @returns {number} Returns the timer id. + */ +function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); +} + +module.exports = baseDelay; diff --git a/www/node_modules/lodash/_baseDifference.js b/www/node_modules/lodash/_baseDifference.js new file mode 100644 index 0000000..b266d7e --- /dev/null +++ b/www/node_modules/lodash/_baseDifference.js @@ -0,0 +1,66 @@ +var SetCache = require('./_SetCache'), + arrayIncludes = require('./_arrayIncludes'), + arrayIncludesWith = require('./_arrayIncludesWith'), + arrayMap = require('./_arrayMap'), + baseUnary = require('./_baseUnary'), + cacheHas = require('./_cacheHas'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of methods like `_.difference` without support for + * excluding multiple arrays or iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + */ +function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; + + if (!length) { + return result; + } + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } + else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; + isCommon = false; + values = new SetCache(values); + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (isCommon && computed === computed) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === computed) { + continue outer; + } + } + result.push(value); + } + else if (!includes(values, computed, comparator)) { + result.push(value); + } + } + return result; +} + +module.exports = baseDifference; diff --git a/www/node_modules/lodash/_baseEach.js b/www/node_modules/lodash/_baseEach.js new file mode 100644 index 0000000..512c067 --- /dev/null +++ b/www/node_modules/lodash/_baseEach.js @@ -0,0 +1,14 @@ +var baseForOwn = require('./_baseForOwn'), + createBaseEach = require('./_createBaseEach'); + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = createBaseEach(baseForOwn); + +module.exports = baseEach; diff --git a/www/node_modules/lodash/_baseEachRight.js b/www/node_modules/lodash/_baseEachRight.js new file mode 100644 index 0000000..0a8feec --- /dev/null +++ b/www/node_modules/lodash/_baseEachRight.js @@ -0,0 +1,14 @@ +var baseForOwnRight = require('./_baseForOwnRight'), + createBaseEach = require('./_createBaseEach'); + +/** + * The base implementation of `_.forEachRight` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEachRight = createBaseEach(baseForOwnRight, true); + +module.exports = baseEachRight; diff --git a/www/node_modules/lodash/_baseEvery.js b/www/node_modules/lodash/_baseEvery.js new file mode 100644 index 0000000..aafa00d --- /dev/null +++ b/www/node_modules/lodash/_baseEvery.js @@ -0,0 +1,20 @@ +var baseEach = require('./_baseEach'); + +/** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false` + */ +function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; +} + +module.exports = baseEvery; diff --git a/www/node_modules/lodash/_baseExtremum.js b/www/node_modules/lodash/_baseExtremum.js new file mode 100644 index 0000000..c6cb804 --- /dev/null +++ b/www/node_modules/lodash/_baseExtremum.js @@ -0,0 +1,30 @@ +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? current === current + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +module.exports = baseExtremum; diff --git a/www/node_modules/lodash/_baseFill.js b/www/node_modules/lodash/_baseFill.js new file mode 100644 index 0000000..46ef9c7 --- /dev/null +++ b/www/node_modules/lodash/_baseFill.js @@ -0,0 +1,32 @@ +var toInteger = require('./toInteger'), + toLength = require('./toLength'); + +/** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ +function baseFill(array, value, start, end) { + var length = array.length; + + start = toInteger(start); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : toInteger(end); + if (end < 0) { + end += length; + } + end = start > end ? 0 : toLength(end); + while (start < end) { + array[start++] = value; + } + return array; +} + +module.exports = baseFill; diff --git a/www/node_modules/lodash/_baseFilter.js b/www/node_modules/lodash/_baseFilter.js new file mode 100644 index 0000000..4678477 --- /dev/null +++ b/www/node_modules/lodash/_baseFilter.js @@ -0,0 +1,21 @@ +var baseEach = require('./_baseEach'); + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +module.exports = baseFilter; diff --git a/www/node_modules/lodash/_baseFind.js b/www/node_modules/lodash/_baseFind.js new file mode 100644 index 0000000..535f7f3 --- /dev/null +++ b/www/node_modules/lodash/_baseFind.js @@ -0,0 +1,24 @@ +/** + * The base implementation of methods like `_.find` and `_.findKey`, without + * support for iteratee shorthands, which iterates over `collection` using + * `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ +function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; +} + +module.exports = baseFind; diff --git a/www/node_modules/lodash/_baseFindIndex.js b/www/node_modules/lodash/_baseFindIndex.js new file mode 100644 index 0000000..61428f6 --- /dev/null +++ b/www/node_modules/lodash/_baseFindIndex.js @@ -0,0 +1,23 @@ +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +module.exports = baseFindIndex; diff --git a/www/node_modules/lodash/_baseFlatten.js b/www/node_modules/lodash/_baseFlatten.js new file mode 100644 index 0000000..7d024dd --- /dev/null +++ b/www/node_modules/lodash/_baseFlatten.js @@ -0,0 +1,39 @@ +var arrayPush = require('./_arrayPush'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isArrayLikeObject = require('./isArrayLikeObject'); + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, isStrict, result) { + result || (result = []); + + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + if (depth > 0 && isArrayLikeObject(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +module.exports = baseFlatten; diff --git a/www/node_modules/lodash/_baseFor.js b/www/node_modules/lodash/_baseFor.js new file mode 100644 index 0000000..97b70c9 --- /dev/null +++ b/www/node_modules/lodash/_baseFor.js @@ -0,0 +1,17 @@ +var createBaseFor = require('./_createBaseFor'); + +/** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ +var baseFor = createBaseFor(); + +module.exports = baseFor; diff --git a/www/node_modules/lodash/_baseForIn.js b/www/node_modules/lodash/_baseForIn.js new file mode 100644 index 0000000..4dcfdaf --- /dev/null +++ b/www/node_modules/lodash/_baseForIn.js @@ -0,0 +1,16 @@ +var baseFor = require('./_baseFor'), + keysIn = require('./keysIn'); + +/** + * The base implementation of `_.forIn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForIn(object, iteratee) { + return object == null ? object : baseFor(object, iteratee, keysIn); +} + +module.exports = baseForIn; diff --git a/www/node_modules/lodash/_baseForOwn.js b/www/node_modules/lodash/_baseForOwn.js new file mode 100644 index 0000000..503d523 --- /dev/null +++ b/www/node_modules/lodash/_baseForOwn.js @@ -0,0 +1,16 @@ +var baseFor = require('./_baseFor'), + keys = require('./keys'); + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); +} + +module.exports = baseForOwn; diff --git a/www/node_modules/lodash/_baseForOwnRight.js b/www/node_modules/lodash/_baseForOwnRight.js new file mode 100644 index 0000000..a4b10e6 --- /dev/null +++ b/www/node_modules/lodash/_baseForOwnRight.js @@ -0,0 +1,16 @@ +var baseForRight = require('./_baseForRight'), + keys = require('./keys'); + +/** + * The base implementation of `_.forOwnRight` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwnRight(object, iteratee) { + return object && baseForRight(object, iteratee, keys); +} + +module.exports = baseForOwnRight; diff --git a/www/node_modules/lodash/_baseForRight.js b/www/node_modules/lodash/_baseForRight.js new file mode 100644 index 0000000..32842cd --- /dev/null +++ b/www/node_modules/lodash/_baseForRight.js @@ -0,0 +1,15 @@ +var createBaseFor = require('./_createBaseFor'); + +/** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ +var baseForRight = createBaseFor(true); + +module.exports = baseForRight; diff --git a/www/node_modules/lodash/_baseFunctions.js b/www/node_modules/lodash/_baseFunctions.js new file mode 100644 index 0000000..6e1090f --- /dev/null +++ b/www/node_modules/lodash/_baseFunctions.js @@ -0,0 +1,19 @@ +var arrayFilter = require('./_arrayFilter'), + isFunction = require('./isFunction'); + +/** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ +function baseFunctions(object, props) { + return arrayFilter(props, function(key) { + return isFunction(object[key]); + }); +} + +module.exports = baseFunctions; diff --git a/www/node_modules/lodash/_baseGet.js b/www/node_modules/lodash/_baseGet.js new file mode 100644 index 0000000..ef9623a --- /dev/null +++ b/www/node_modules/lodash/_baseGet.js @@ -0,0 +1,24 @@ +var baseCastPath = require('./_baseCastPath'), + isKey = require('./_isKey'); + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[path[index++]]; + } + return (index && index == length) ? object : undefined; +} + +module.exports = baseGet; diff --git a/www/node_modules/lodash/_baseHas.js b/www/node_modules/lodash/_baseHas.js new file mode 100644 index 0000000..b393206 --- /dev/null +++ b/www/node_modules/lodash/_baseHas.js @@ -0,0 +1,26 @@ +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Built-in value references. */ +var getPrototypeOf = Object.getPrototypeOf; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`, + // that are composed entirely of index properties, return `false` for + // `hasOwnProperty` checks of them. + return hasOwnProperty.call(object, key) || + (typeof object == 'object' && key in object && getPrototypeOf(object) === null); +} + +module.exports = baseHas; diff --git a/www/node_modules/lodash/_baseHasIn.js b/www/node_modules/lodash/_baseHasIn.js new file mode 100644 index 0000000..4a36558 --- /dev/null +++ b/www/node_modules/lodash/_baseHasIn.js @@ -0,0 +1,13 @@ +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return key in Object(object); +} + +module.exports = baseHasIn; diff --git a/www/node_modules/lodash/_baseInRange.js b/www/node_modules/lodash/_baseInRange.js new file mode 100644 index 0000000..16d53f2 --- /dev/null +++ b/www/node_modules/lodash/_baseInRange.js @@ -0,0 +1,18 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * The base implementation of `_.inRange` which doesn't coerce arguments to numbers. + * + * @private + * @param {number} number The number to check. + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + */ +function baseInRange(number, start, end) { + return number >= nativeMin(start, end) && number < nativeMax(start, end); +} + +module.exports = baseInRange; diff --git a/www/node_modules/lodash/_baseIndexOf.js b/www/node_modules/lodash/_baseIndexOf.js new file mode 100644 index 0000000..6cda802 --- /dev/null +++ b/www/node_modules/lodash/_baseIndexOf.js @@ -0,0 +1,27 @@ +var indexOfNaN = require('./_indexOfNaN'); + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); + } + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +module.exports = baseIndexOf; diff --git a/www/node_modules/lodash/_baseIndexOfWith.js b/www/node_modules/lodash/_baseIndexOfWith.js new file mode 100644 index 0000000..8be568a --- /dev/null +++ b/www/node_modules/lodash/_baseIndexOfWith.js @@ -0,0 +1,23 @@ +/** + * This function is like `baseIndexOf` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @param {Function} comparator The comparator invoked per element. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOfWith(array, value, fromIndex, comparator) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (comparator(array[index], value)) { + return index; + } + } + return -1; +} + +module.exports = baseIndexOfWith; diff --git a/www/node_modules/lodash/_baseIntersection.js b/www/node_modules/lodash/_baseIntersection.js new file mode 100644 index 0000000..7d12926 --- /dev/null +++ b/www/node_modules/lodash/_baseIntersection.js @@ -0,0 +1,73 @@ +var SetCache = require('./_SetCache'), + arrayIncludes = require('./_arrayIncludes'), + arrayIncludesWith = require('./_arrayIncludesWith'), + arrayMap = require('./_arrayMap'), + baseUnary = require('./_baseUnary'), + cacheHas = require('./_cacheHas'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ +function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + maxLength = Infinity, + result = []; + + while (othIndex--) { + var array = arrays[othIndex]; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) + ? new SetCache(othIndex && array) + : undefined; + } + array = arrays[0]; + + var index = -1, + seen = caches[0]; + + outer: + while (++index < length && result.length < maxLength) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { + othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { + continue outer; + } + } + if (seen) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +module.exports = baseIntersection; diff --git a/www/node_modules/lodash/_baseInverter.js b/www/node_modules/lodash/_baseInverter.js new file mode 100644 index 0000000..fbc337f --- /dev/null +++ b/www/node_modules/lodash/_baseInverter.js @@ -0,0 +1,21 @@ +var baseForOwn = require('./_baseForOwn'); + +/** + * The base implementation of `_.invert` and `_.invertBy` which inverts + * `object` with values transformed by `iteratee` and set by `setter`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform values. + * @param {Object} accumulator The initial inverted object. + * @returns {Function} Returns `accumulator`. + */ +function baseInverter(object, setter, iteratee, accumulator) { + baseForOwn(object, function(value, key, object) { + setter(accumulator, iteratee(value), key, object); + }); + return accumulator; +} + +module.exports = baseInverter; diff --git a/www/node_modules/lodash/_baseInvoke.js b/www/node_modules/lodash/_baseInvoke.js new file mode 100644 index 0000000..7a94a3f --- /dev/null +++ b/www/node_modules/lodash/_baseInvoke.js @@ -0,0 +1,27 @@ +var apply = require('./_apply'), + baseCastPath = require('./_baseCastPath'), + isKey = require('./_isKey'), + last = require('./last'), + parent = require('./_parent'); + +/** + * The base implementation of `_.invoke` without support for individual + * method arguments. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ +function baseInvoke(object, path, args) { + if (!isKey(path, object)) { + path = baseCastPath(path); + object = parent(object, path); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : apply(func, object, args); +} + +module.exports = baseInvoke; diff --git a/www/node_modules/lodash/_baseIsEqual.js b/www/node_modules/lodash/_baseIsEqual.js new file mode 100644 index 0000000..3772dab --- /dev/null +++ b/www/node_modules/lodash/_baseIsEqual.js @@ -0,0 +1,30 @@ +var baseIsEqualDeep = require('./_baseIsEqualDeep'), + isObject = require('./isObject'), + isObjectLike = require('./isObjectLike'); + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @param {boolean} [bitmask] The bitmask of comparison flags. + * The bitmask may be composed of the following flags: + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, customizer, bitmask, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack); +} + +module.exports = baseIsEqual; diff --git a/www/node_modules/lodash/_baseIsEqualDeep.js b/www/node_modules/lodash/_baseIsEqualDeep.js new file mode 100644 index 0000000..50bb411 --- /dev/null +++ b/www/node_modules/lodash/_baseIsEqualDeep.js @@ -0,0 +1,78 @@ +var Stack = require('./_Stack'), + equalArrays = require('./_equalArrays'), + equalByTag = require('./_equalByTag'), + equalObjects = require('./_equalObjects'), + getTag = require('./_getTag'), + isArray = require('./isArray'), + isHostObject = require('./_isHostObject'), + isTypedArray = require('./isTypedArray'); + +/** Used to compose bitmasks for comparison styles. */ +var PARTIAL_COMPARE_FLAG = 2; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparisons. + * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = getTag(object); + objTag = objTag == argsTag ? objectTag : objTag; + } + if (!othIsArr) { + othTag = getTag(other); + othTag = othTag == argsTag ? objectTag : othTag; + } + var objIsObj = objTag == objectTag && !isHostObject(object), + othIsObj = othTag == objectTag && !isHostObject(other), + isSameTag = objTag == othTag; + + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, equalFunc, customizer, bitmask, stack) + : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack); + } + if (!(bitmask & PARTIAL_COMPARE_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + stack || (stack = new Stack); + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, equalFunc, customizer, bitmask, stack); +} + +module.exports = baseIsEqualDeep; diff --git a/www/node_modules/lodash/_baseIsMatch.js b/www/node_modules/lodash/_baseIsMatch.js new file mode 100644 index 0000000..c1dcafc --- /dev/null +++ b/www/node_modules/lodash/_baseIsMatch.js @@ -0,0 +1,61 @@ +var Stack = require('./_Stack'), + baseIsEqual = require('./_baseIsEqual'); + +/** Used to compose bitmasks for comparison styles. */ +var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack, + result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined; + + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) + : result + )) { + return false; + } + } + } + return true; +} + +module.exports = baseIsMatch; diff --git a/www/node_modules/lodash/_baseIteratee.js b/www/node_modules/lodash/_baseIteratee.js new file mode 100644 index 0000000..19531af --- /dev/null +++ b/www/node_modules/lodash/_baseIteratee.js @@ -0,0 +1,30 @@ +var baseMatches = require('./_baseMatches'), + baseMatchesProperty = require('./_baseMatchesProperty'), + identity = require('./identity'), + isArray = require('./isArray'), + property = require('./property'); + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + var type = typeof value; + if (type == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (type == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); +} + +module.exports = baseIteratee; diff --git a/www/node_modules/lodash/_baseKeys.js b/www/node_modules/lodash/_baseKeys.js new file mode 100644 index 0000000..2c8ccb9 --- /dev/null +++ b/www/node_modules/lodash/_baseKeys.js @@ -0,0 +1,16 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeKeys = Object.keys; + +/** + * The base implementation of `_.keys` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + return nativeKeys(Object(object)); +} + +module.exports = baseKeys; diff --git a/www/node_modules/lodash/_baseKeysIn.js b/www/node_modules/lodash/_baseKeysIn.js new file mode 100644 index 0000000..7455fd8 --- /dev/null +++ b/www/node_modules/lodash/_baseKeysIn.js @@ -0,0 +1,36 @@ +var Reflect = require('./_Reflect'), + iteratorToArray = require('./_iteratorToArray'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var enumerate = Reflect ? Reflect.enumerate : undefined, + propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** + * The base implementation of `_.keysIn` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeysIn(object) { + object = object == null ? object : Object(object); + + var result = []; + for (var key in object) { + result.push(key); + } + return result; +} + +// Fallback for IE < 9 with es6-shim. +if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) { + baseKeysIn = function(object) { + return iteratorToArray(enumerate(object)); + }; +} + +module.exports = baseKeysIn; diff --git a/www/node_modules/lodash/_baseLodash.js b/www/node_modules/lodash/_baseLodash.js new file mode 100644 index 0000000..15b79d3 --- /dev/null +++ b/www/node_modules/lodash/_baseLodash.js @@ -0,0 +1,10 @@ +/** + * The function whose prototype all chaining wrappers inherit from. + * + * @private + */ +function baseLodash() { + // No operation performed. +} + +module.exports = baseLodash; diff --git a/www/node_modules/lodash/_baseMap.js b/www/node_modules/lodash/_baseMap.js new file mode 100644 index 0000000..0bf5cea --- /dev/null +++ b/www/node_modules/lodash/_baseMap.js @@ -0,0 +1,22 @@ +var baseEach = require('./_baseEach'), + isArrayLike = require('./isArrayLike'); + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +module.exports = baseMap; diff --git a/www/node_modules/lodash/_baseMatches.js b/www/node_modules/lodash/_baseMatches.js new file mode 100644 index 0000000..56c72e6 --- /dev/null +++ b/www/node_modules/lodash/_baseMatches.js @@ -0,0 +1,30 @@ +var baseIsMatch = require('./_baseIsMatch'), + getMatchData = require('./_getMatchData'); + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ +function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; + + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && + (value !== undefined || (key in Object(object))); + }; + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; +} + +module.exports = baseMatches; diff --git a/www/node_modules/lodash/_baseMatchesProperty.js b/www/node_modules/lodash/_baseMatchesProperty.js new file mode 100644 index 0000000..256ad65 --- /dev/null +++ b/www/node_modules/lodash/_baseMatchesProperty.js @@ -0,0 +1,26 @@ +var baseIsEqual = require('./_baseIsEqual'), + get = require('./get'), + hasIn = require('./hasIn'); + +/** Used to compose bitmasks for comparison styles. */ +var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new function. + */ +function baseMatchesProperty(path, srcValue) { + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG); + }; +} + +module.exports = baseMatchesProperty; diff --git a/www/node_modules/lodash/_baseMerge.js b/www/node_modules/lodash/_baseMerge.js new file mode 100644 index 0000000..04cda58 --- /dev/null +++ b/www/node_modules/lodash/_baseMerge.js @@ -0,0 +1,50 @@ +var Stack = require('./_Stack'), + arrayEach = require('./_arrayEach'), + assignMergeValue = require('./_assignMergeValue'), + baseMergeDeep = require('./_baseMergeDeep'), + isArray = require('./isArray'), + isObject = require('./isObject'), + isTypedArray = require('./isTypedArray'), + keysIn = require('./keysIn'); + +/** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + */ +function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + var props = (isArray(source) || isTypedArray(source)) + ? undefined + : keysIn(source); + + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; + } + if (isObject(srcValue)) { + stack || (stack = new Stack); + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(object[key], srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }); +} + +module.exports = baseMerge; diff --git a/www/node_modules/lodash/_baseMergeDeep.js b/www/node_modules/lodash/_baseMergeDeep.js new file mode 100644 index 0000000..1b8130a --- /dev/null +++ b/www/node_modules/lodash/_baseMergeDeep.js @@ -0,0 +1,82 @@ +var assignMergeValue = require('./_assignMergeValue'), + baseClone = require('./_baseClone'), + copyArray = require('./_copyArray'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isArrayLikeObject = require('./isArrayLikeObject'), + isFunction = require('./isFunction'), + isObject = require('./isObject'), + isPlainObject = require('./isPlainObject'), + isTypedArray = require('./isTypedArray'), + toPlainObject = require('./toPlainObject'); + +/** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + */ +function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = object[key], + srcValue = source[key], + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + newValue = srcValue; + if (isArray(srcValue) || isTypedArray(srcValue)) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else { + isCommon = false; + newValue = baseClone(srcValue, !customizer); + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { + isCommon = false; + newValue = baseClone(srcValue, !customizer); + } + else { + newValue = objValue; + } + } + else { + isCommon = false; + } + } + stack.set(srcValue, newValue); + + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + } + stack['delete'](srcValue); + assignMergeValue(object, key, newValue); +} + +module.exports = baseMergeDeep; diff --git a/www/node_modules/lodash/_baseOrderBy.js b/www/node_modules/lodash/_baseOrderBy.js new file mode 100644 index 0000000..4dcbe38 --- /dev/null +++ b/www/node_modules/lodash/_baseOrderBy.js @@ -0,0 +1,32 @@ +var arrayMap = require('./_arrayMap'), + baseIteratee = require('./_baseIteratee'), + baseMap = require('./_baseMap'), + baseSortBy = require('./_baseSortBy'), + compareMultiple = require('./_compareMultiple'); + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + var index = -1; + iteratees = arrayMap(iteratees.length ? iteratees : Array(1), baseIteratee); + + var result = baseMap(collection, function(value, key, collection) { + var criteria = arrayMap(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); +} + +module.exports = baseOrderBy; diff --git a/www/node_modules/lodash/_basePick.js b/www/node_modules/lodash/_basePick.js new file mode 100644 index 0000000..e2ce722 --- /dev/null +++ b/www/node_modules/lodash/_basePick.js @@ -0,0 +1,22 @@ +var arrayReduce = require('./_arrayReduce'); + +/** + * The base implementation of `_.pick` without support for individual + * property names. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, props) { + object = Object(object); + return arrayReduce(props, function(result, key) { + if (key in object) { + result[key] = object[key]; + } + return result; + }, {}); +} + +module.exports = basePick; diff --git a/www/node_modules/lodash/_basePickBy.js b/www/node_modules/lodash/_basePickBy.js new file mode 100644 index 0000000..37c4943 --- /dev/null +++ b/www/node_modules/lodash/_basePickBy.js @@ -0,0 +1,21 @@ +var baseForIn = require('./_baseForIn'); + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, predicate) { + var result = {}; + baseForIn(object, function(value, key) { + if (predicate(value, key)) { + result[key] = value; + } + }); + return result; +} + +module.exports = basePickBy; diff --git a/www/node_modules/lodash/_baseProperty.js b/www/node_modules/lodash/_baseProperty.js new file mode 100644 index 0000000..e515941 --- /dev/null +++ b/www/node_modules/lodash/_baseProperty.js @@ -0,0 +1,14 @@ +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +module.exports = baseProperty; diff --git a/www/node_modules/lodash/_basePropertyDeep.js b/www/node_modules/lodash/_basePropertyDeep.js new file mode 100644 index 0000000..acc2009 --- /dev/null +++ b/www/node_modules/lodash/_basePropertyDeep.js @@ -0,0 +1,16 @@ +var baseGet = require('./_baseGet'); + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ +function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; +} + +module.exports = basePropertyDeep; diff --git a/www/node_modules/lodash/_basePullAll.js b/www/node_modules/lodash/_basePullAll.js new file mode 100644 index 0000000..3c07c99 --- /dev/null +++ b/www/node_modules/lodash/_basePullAll.js @@ -0,0 +1,47 @@ +var arrayMap = require('./_arrayMap'), + baseIndexOf = require('./_baseIndexOf'), + baseIndexOfWith = require('./_baseIndexOfWith'), + baseUnary = require('./_baseUnary'); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * The base implementation of `_.pullAllBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + */ +function basePullAll(array, values, iteratee, comparator) { + var indexOf = comparator ? baseIndexOfWith : baseIndexOf, + index = -1, + length = values.length, + seen = array; + + if (iteratee) { + seen = arrayMap(array, baseUnary(iteratee)); + } + while (++index < length) { + var fromIndex = 0, + value = values[index], + computed = iteratee ? iteratee(value) : value; + + while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { + if (seen !== array) { + splice.call(seen, fromIndex, 1); + } + splice.call(array, fromIndex, 1); + } + } + return array; +} + +module.exports = basePullAll; diff --git a/www/node_modules/lodash/_basePullAt.js b/www/node_modules/lodash/_basePullAt.js new file mode 100644 index 0000000..eb9ed21 --- /dev/null +++ b/www/node_modules/lodash/_basePullAt.js @@ -0,0 +1,49 @@ +var baseCastPath = require('./_baseCastPath'), + isIndex = require('./_isIndex'), + isKey = require('./_isKey'), + last = require('./last'), + parent = require('./_parent'); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * The base implementation of `_.pullAt` without support for individual + * indexes or capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ +function basePullAt(array, indexes) { + var length = array ? indexes.length : 0, + lastIndex = length - 1; + + while (length--) { + var index = indexes[length]; + if (lastIndex == length || index != previous) { + var previous = index; + if (isIndex(index)) { + splice.call(array, index, 1); + } + else if (!isKey(index, array)) { + var path = baseCastPath(index), + object = parent(array, path); + + if (object != null) { + delete object[last(path)]; + } + } + else { + delete array[index]; + } + } + } + return array; +} + +module.exports = basePullAt; diff --git a/www/node_modules/lodash/_baseRandom.js b/www/node_modules/lodash/_baseRandom.js new file mode 100644 index 0000000..94f76a7 --- /dev/null +++ b/www/node_modules/lodash/_baseRandom.js @@ -0,0 +1,18 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeFloor = Math.floor, + nativeRandom = Math.random; + +/** + * The base implementation of `_.random` without support for returning + * floating-point numbers. + * + * @private + * @param {number} lower The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the random number. + */ +function baseRandom(lower, upper) { + return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); +} + +module.exports = baseRandom; diff --git a/www/node_modules/lodash/_baseRange.js b/www/node_modules/lodash/_baseRange.js new file mode 100644 index 0000000..2b39dd4 --- /dev/null +++ b/www/node_modules/lodash/_baseRange.js @@ -0,0 +1,28 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments to numbers. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the new array of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +module.exports = baseRange; diff --git a/www/node_modules/lodash/_baseReduce.js b/www/node_modules/lodash/_baseReduce.js new file mode 100644 index 0000000..6ec5442 --- /dev/null +++ b/www/node_modules/lodash/_baseReduce.js @@ -0,0 +1,22 @@ +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +module.exports = baseReduce; diff --git a/www/node_modules/lodash/_baseSet.js b/www/node_modules/lodash/_baseSet.js new file mode 100644 index 0000000..0596d89 --- /dev/null +++ b/www/node_modules/lodash/_baseSet.js @@ -0,0 +1,45 @@ +var assignValue = require('./_assignValue'), + baseCastPath = require('./_baseCastPath'), + isIndex = require('./_isIndex'), + isKey = require('./_isKey'), + isObject = require('./isObject'); + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + var newValue = value; + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = objValue == null + ? (isIndex(path[index + 1]) ? [] : {}) + : objValue; + } + } + assignValue(nested, key, newValue); + } + nested = nested[key]; + } + return object; +} + +module.exports = baseSet; diff --git a/www/node_modules/lodash/_baseSetData.js b/www/node_modules/lodash/_baseSetData.js new file mode 100644 index 0000000..e689df2 --- /dev/null +++ b/www/node_modules/lodash/_baseSetData.js @@ -0,0 +1,17 @@ +var identity = require('./identity'), + metaMap = require('./_metaMap'); + +/** + * The base implementation of `setData` without support for hot loop detection. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ +var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; +}; + +module.exports = baseSetData; diff --git a/www/node_modules/lodash/_baseSlice.js b/www/node_modules/lodash/_baseSlice.js new file mode 100644 index 0000000..786f6c9 --- /dev/null +++ b/www/node_modules/lodash/_baseSlice.js @@ -0,0 +1,31 @@ +/** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ +function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; +} + +module.exports = baseSlice; diff --git a/www/node_modules/lodash/_baseSome.js b/www/node_modules/lodash/_baseSome.js new file mode 100644 index 0000000..8b6aa0a --- /dev/null +++ b/www/node_modules/lodash/_baseSome.js @@ -0,0 +1,21 @@ +var baseEach = require('./_baseEach'); + +/** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + */ +function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; +} + +module.exports = baseSome; diff --git a/www/node_modules/lodash/_baseSortBy.js b/www/node_modules/lodash/_baseSortBy.js new file mode 100644 index 0000000..a25c92e --- /dev/null +++ b/www/node_modules/lodash/_baseSortBy.js @@ -0,0 +1,21 @@ +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +module.exports = baseSortBy; diff --git a/www/node_modules/lodash/_baseSortedIndex.js b/www/node_modules/lodash/_baseSortedIndex.js new file mode 100644 index 0000000..3961063 --- /dev/null +++ b/www/node_modules/lodash/_baseSortedIndex.js @@ -0,0 +1,40 @@ +var baseSortedIndexBy = require('./_baseSortedIndexBy'), + identity = require('./identity'); + +/** Used as references for the maximum length and index of an array. */ +var MAX_ARRAY_LENGTH = 4294967295, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + +/** + * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which + * performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ +function baseSortedIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return baseSortedIndexBy(array, value, identity, retHighest); +} + +module.exports = baseSortedIndex; diff --git a/www/node_modules/lodash/_baseSortedIndexBy.js b/www/node_modules/lodash/_baseSortedIndexBy.js new file mode 100644 index 0000000..6e295f9 --- /dev/null +++ b/www/node_modules/lodash/_baseSortedIndexBy.js @@ -0,0 +1,56 @@ +/** Used as references for the maximum length and index of an array. */ +var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeFloor = Math.floor, + nativeMin = Math.min; + +/** + * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` + * which invokes `iteratee` for `value` and each element of `array` to compute + * their sort ranking. The iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The iteratee invoked per element. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + */ +function baseSortedIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); + + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsNull = value === null, + valIsUndef = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + isDef = computed !== undefined, + isReflexive = computed === computed; + + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); +} + +module.exports = baseSortedIndexBy; diff --git a/www/node_modules/lodash/_baseSortedUniq.js b/www/node_modules/lodash/_baseSortedUniq.js new file mode 100644 index 0000000..bf1eb2e --- /dev/null +++ b/www/node_modules/lodash/_baseSortedUniq.js @@ -0,0 +1,14 @@ +var baseSortedUniqBy = require('./_baseSortedUniqBy'); + +/** + * The base implementation of `_.sortedUniq`. + * + * @private + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + */ +function baseSortedUniq(array) { + return baseSortedUniqBy(array); +} + +module.exports = baseSortedUniq; diff --git a/www/node_modules/lodash/_baseSortedUniqBy.js b/www/node_modules/lodash/_baseSortedUniqBy.js new file mode 100644 index 0000000..81e7ae1 --- /dev/null +++ b/www/node_modules/lodash/_baseSortedUniqBy.js @@ -0,0 +1,33 @@ +var eq = require('./eq'); + +/** + * The base implementation of `_.sortedUniqBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseSortedUniqBy(array, iteratee) { + var index = 0, + length = array.length, + value = array[0], + computed = iteratee ? iteratee(value) : value, + seen = computed, + resIndex = 1, + result = [value]; + + while (++index < length) { + value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!eq(computed, seen)) { + seen = computed; + result[resIndex++] = value; + } + } + return result; +} + +module.exports = baseSortedUniqBy; diff --git a/www/node_modules/lodash/_baseSum.js b/www/node_modules/lodash/_baseSum.js new file mode 100644 index 0000000..348b5e8 --- /dev/null +++ b/www/node_modules/lodash/_baseSum.js @@ -0,0 +1,23 @@ +/** + * The base implementation of `_.sum` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ +function baseSum(array, iteratee) { + var result, + index = -1, + length = array.length; + + while (++index < length) { + var current = iteratee(array[index]); + if (current !== undefined) { + result = result === undefined ? current : (result + current); + } + } + return result; +} + +module.exports = baseSum; diff --git a/www/node_modules/lodash/_baseTimes.js b/www/node_modules/lodash/_baseTimes.js new file mode 100644 index 0000000..0603fc3 --- /dev/null +++ b/www/node_modules/lodash/_baseTimes.js @@ -0,0 +1,20 @@ +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +module.exports = baseTimes; diff --git a/www/node_modules/lodash/_baseToPairs.js b/www/node_modules/lodash/_baseToPairs.js new file mode 100644 index 0000000..d80b402 --- /dev/null +++ b/www/node_modules/lodash/_baseToPairs.js @@ -0,0 +1,18 @@ +var arrayMap = require('./_arrayMap'); + +/** + * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array + * of key-value pairs for `object` corresponding to the property names of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the new array of key-value pairs. + */ +function baseToPairs(object, props) { + return arrayMap(props, function(key) { + return [key, object[key]]; + }); +} + +module.exports = baseToPairs; diff --git a/www/node_modules/lodash/_baseUnary.js b/www/node_modules/lodash/_baseUnary.js new file mode 100644 index 0000000..e584a99 --- /dev/null +++ b/www/node_modules/lodash/_baseUnary.js @@ -0,0 +1,14 @@ +/** + * The base implementation of `_.unary` without support for storing wrapper metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new function. + */ +function baseUnary(func) { + return function(value) { + return func(value); + }; +} + +module.exports = baseUnary; diff --git a/www/node_modules/lodash/_baseUniq.js b/www/node_modules/lodash/_baseUniq.js new file mode 100644 index 0000000..ecb6fe4 --- /dev/null +++ b/www/node_modules/lodash/_baseUniq.js @@ -0,0 +1,71 @@ +var SetCache = require('./_SetCache'), + arrayIncludes = require('./_arrayIncludes'), + arrayIncludesWith = require('./_arrayIncludesWith'), + cacheHas = require('./_cacheHas'), + createSet = require('./_createSet'), + setToArray = require('./_setToArray'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +module.exports = baseUniq; diff --git a/www/node_modules/lodash/_baseUnset.js b/www/node_modules/lodash/_baseUnset.js new file mode 100644 index 0000000..02b5640 --- /dev/null +++ b/www/node_modules/lodash/_baseUnset.js @@ -0,0 +1,22 @@ +var baseCastPath = require('./_baseCastPath'), + has = require('./has'), + isKey = require('./_isKey'), + last = require('./last'), + parent = require('./_parent'); + +/** + * The base implementation of `_.unset`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + */ +function baseUnset(object, path) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + object = parent(object, path); + var key = last(path); + return (object != null && has(object, key)) ? delete object[key] : true; +} + +module.exports = baseUnset; diff --git a/www/node_modules/lodash/_baseUpdate.js b/www/node_modules/lodash/_baseUpdate.js new file mode 100644 index 0000000..ec1b338 --- /dev/null +++ b/www/node_modules/lodash/_baseUpdate.js @@ -0,0 +1,18 @@ +var baseGet = require('./_baseGet'), + baseSet = require('./_baseSet'); + +/** + * The base implementation of `_.update`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to update. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseUpdate(object, path, updater, customizer) { + return baseSet(object, path, updater(baseGet(object, path)), customizer); +} + +module.exports = baseUpdate; diff --git a/www/node_modules/lodash/_baseValues.js b/www/node_modules/lodash/_baseValues.js new file mode 100644 index 0000000..b95faad --- /dev/null +++ b/www/node_modules/lodash/_baseValues.js @@ -0,0 +1,19 @@ +var arrayMap = require('./_arrayMap'); + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); +} + +module.exports = baseValues; diff --git a/www/node_modules/lodash/_baseWhile.js b/www/node_modules/lodash/_baseWhile.js new file mode 100644 index 0000000..07eac61 --- /dev/null +++ b/www/node_modules/lodash/_baseWhile.js @@ -0,0 +1,26 @@ +var baseSlice = require('./_baseSlice'); + +/** + * The base implementation of methods like `_.dropWhile` and `_.takeWhile` + * without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ +function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && + predicate(array[index], index, array)) {} + + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); +} + +module.exports = baseWhile; diff --git a/www/node_modules/lodash/_baseWrapperValue.js b/www/node_modules/lodash/_baseWrapperValue.js new file mode 100644 index 0000000..443e0df --- /dev/null +++ b/www/node_modules/lodash/_baseWrapperValue.js @@ -0,0 +1,25 @@ +var LazyWrapper = require('./_LazyWrapper'), + arrayPush = require('./_arrayPush'), + arrayReduce = require('./_arrayReduce'); + +/** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ +function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + return arrayReduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); +} + +module.exports = baseWrapperValue; diff --git a/www/node_modules/lodash/_baseXor.js b/www/node_modules/lodash/_baseXor.js new file mode 100644 index 0000000..7e62d1b --- /dev/null +++ b/www/node_modules/lodash/_baseXor.js @@ -0,0 +1,30 @@ +var arrayPush = require('./_arrayPush'), + baseDifference = require('./_baseDifference'), + baseUniq = require('./_baseUniq'); + +/** + * The base implementation of methods like `_.xor`, without support for + * iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + */ +function baseXor(arrays, iteratee, comparator) { + var index = -1, + length = arrays.length; + + while (++index < length) { + var result = result + ? arrayPush( + baseDifference(result, arrays[index], iteratee, comparator), + baseDifference(arrays[index], result, iteratee, comparator) + ) + : arrays[index]; + } + return (result && result.length) ? baseUniq(result, iteratee, comparator) : []; +} + +module.exports = baseXor; diff --git a/www/node_modules/lodash/_baseZipObject.js b/www/node_modules/lodash/_baseZipObject.js new file mode 100644 index 0000000..c8a3e83 --- /dev/null +++ b/www/node_modules/lodash/_baseZipObject.js @@ -0,0 +1,22 @@ +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property names. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + assignFunc(result, props[index], index < valsLength ? values[index] : undefined); + } + return result; +} + +module.exports = baseZipObject; diff --git a/www/node_modules/lodash/_cacheHas.js b/www/node_modules/lodash/_cacheHas.js new file mode 100644 index 0000000..7f2ac48 --- /dev/null +++ b/www/node_modules/lodash/_cacheHas.js @@ -0,0 +1,25 @@ +var isKeyable = require('./_isKeyable'); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Checks if `value` is in `cache`. + * + * @private + * @param {Object} cache The set cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function cacheHas(cache, value) { + var map = cache.__data__; + if (isKeyable(value)) { + var data = map.__data__, + hash = typeof value == 'string' ? data.string : data.hash; + + return hash[value] === HASH_UNDEFINED; + } + return map.has(value); +} + +module.exports = cacheHas; diff --git a/www/node_modules/lodash/_cachePush.js b/www/node_modules/lodash/_cachePush.js new file mode 100644 index 0000000..638383b --- /dev/null +++ b/www/node_modules/lodash/_cachePush.js @@ -0,0 +1,27 @@ +var isKeyable = require('./_isKeyable'); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the set cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ +function cachePush(value) { + var map = this.__data__; + if (isKeyable(value)) { + var data = map.__data__, + hash = typeof value == 'string' ? data.string : data.hash; + + hash[value] = HASH_UNDEFINED; + } + else { + map.set(value, HASH_UNDEFINED); + } +} + +module.exports = cachePush; diff --git a/www/node_modules/lodash/_charsEndIndex.js b/www/node_modules/lodash/_charsEndIndex.js new file mode 100644 index 0000000..07908ff --- /dev/null +++ b/www/node_modules/lodash/_charsEndIndex.js @@ -0,0 +1,19 @@ +var baseIndexOf = require('./_baseIndexOf'); + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ +function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; +} + +module.exports = charsEndIndex; diff --git a/www/node_modules/lodash/_charsStartIndex.js b/www/node_modules/lodash/_charsStartIndex.js new file mode 100644 index 0000000..b17afd2 --- /dev/null +++ b/www/node_modules/lodash/_charsStartIndex.js @@ -0,0 +1,20 @@ +var baseIndexOf = require('./_baseIndexOf'); + +/** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ +function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; +} + +module.exports = charsStartIndex; diff --git a/www/node_modules/lodash/_checkGlobal.js b/www/node_modules/lodash/_checkGlobal.js new file mode 100644 index 0000000..b0ea47e --- /dev/null +++ b/www/node_modules/lodash/_checkGlobal.js @@ -0,0 +1,12 @@ +/** + * Checks if `value` is a global object. + * + * @private + * @param {*} value The value to check. + * @returns {null|Object} Returns `value` if it's a global object, else `null`. + */ +function checkGlobal(value) { + return (value && value.Object === Object) ? value : null; +} + +module.exports = checkGlobal; diff --git a/www/node_modules/lodash/_cloneArrayBuffer.js b/www/node_modules/lodash/_cloneArrayBuffer.js new file mode 100644 index 0000000..c3d8f6e --- /dev/null +++ b/www/node_modules/lodash/_cloneArrayBuffer.js @@ -0,0 +1,16 @@ +var Uint8Array = require('./_Uint8Array'); + +/** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ +function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; +} + +module.exports = cloneArrayBuffer; diff --git a/www/node_modules/lodash/_cloneBuffer.js b/www/node_modules/lodash/_cloneBuffer.js new file mode 100644 index 0000000..247d410 --- /dev/null +++ b/www/node_modules/lodash/_cloneBuffer.js @@ -0,0 +1,18 @@ +/** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ +function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; +} + +module.exports = cloneBuffer; diff --git a/www/node_modules/lodash/_cloneMap.js b/www/node_modules/lodash/_cloneMap.js new file mode 100644 index 0000000..a42cbf3 --- /dev/null +++ b/www/node_modules/lodash/_cloneMap.js @@ -0,0 +1,16 @@ +var addMapEntry = require('./_addMapEntry'), + arrayReduce = require('./_arrayReduce'), + mapToArray = require('./_mapToArray'); + +/** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @returns {Object} Returns the cloned map. + */ +function cloneMap(map) { + return arrayReduce(mapToArray(map), addMapEntry, new map.constructor); +} + +module.exports = cloneMap; diff --git a/www/node_modules/lodash/_cloneRegExp.js b/www/node_modules/lodash/_cloneRegExp.js new file mode 100644 index 0000000..64a30df --- /dev/null +++ b/www/node_modules/lodash/_cloneRegExp.js @@ -0,0 +1,17 @@ +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +module.exports = cloneRegExp; diff --git a/www/node_modules/lodash/_cloneSet.js b/www/node_modules/lodash/_cloneSet.js new file mode 100644 index 0000000..0575c0a --- /dev/null +++ b/www/node_modules/lodash/_cloneSet.js @@ -0,0 +1,16 @@ +var addSetEntry = require('./_addSetEntry'), + arrayReduce = require('./_arrayReduce'), + setToArray = require('./_setToArray'); + +/** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @returns {Object} Returns the cloned set. + */ +function cloneSet(set) { + return arrayReduce(setToArray(set), addSetEntry, new set.constructor); +} + +module.exports = cloneSet; diff --git a/www/node_modules/lodash/_cloneSymbol.js b/www/node_modules/lodash/_cloneSymbol.js new file mode 100644 index 0000000..bede39f --- /dev/null +++ b/www/node_modules/lodash/_cloneSymbol.js @@ -0,0 +1,18 @@ +var Symbol = require('./_Symbol'); + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +module.exports = cloneSymbol; diff --git a/www/node_modules/lodash/_cloneTypedArray.js b/www/node_modules/lodash/_cloneTypedArray.js new file mode 100644 index 0000000..7aad84d --- /dev/null +++ b/www/node_modules/lodash/_cloneTypedArray.js @@ -0,0 +1,16 @@ +var cloneArrayBuffer = require('./_cloneArrayBuffer'); + +/** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ +function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); +} + +module.exports = cloneTypedArray; diff --git a/www/node_modules/lodash/_compareAscending.js b/www/node_modules/lodash/_compareAscending.js new file mode 100644 index 0000000..532866c --- /dev/null +++ b/www/node_modules/lodash/_compareAscending.js @@ -0,0 +1,33 @@ +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; +} + +module.exports = compareAscending; diff --git a/www/node_modules/lodash/_compareMultiple.js b/www/node_modules/lodash/_compareMultiple.js new file mode 100644 index 0000000..a3f2d8b --- /dev/null +++ b/www/node_modules/lodash/_compareMultiple.js @@ -0,0 +1,44 @@ +var compareAscending = require('./_compareAscending'); + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +module.exports = compareMultiple; diff --git a/www/node_modules/lodash/_composeArgs.js b/www/node_modules/lodash/_composeArgs.js new file mode 100644 index 0000000..07398e7 --- /dev/null +++ b/www/node_modules/lodash/_composeArgs.js @@ -0,0 +1,39 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ +function composeArgs(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersLength = holders.length, + leftIndex = -1, + leftLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(leftLength + rangeLength), + isUncurried = !isCurried; + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + } + while (rangeLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; +} + +module.exports = composeArgs; diff --git a/www/node_modules/lodash/_composeArgsRight.js b/www/node_modules/lodash/_composeArgsRight.js new file mode 100644 index 0000000..18cfae0 --- /dev/null +++ b/www/node_modules/lodash/_composeArgsRight.js @@ -0,0 +1,41 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ +function composeArgsRight(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersIndex = -1, + holdersLength = holders.length, + rightIndex = -1, + rightLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(rangeLength + rightLength), + isUncurried = !isCurried; + + while (++argsIndex < rangeLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + } + return result; +} + +module.exports = composeArgsRight; diff --git a/www/node_modules/lodash/_copyArray.js b/www/node_modules/lodash/_copyArray.js new file mode 100644 index 0000000..cd94d5d --- /dev/null +++ b/www/node_modules/lodash/_copyArray.js @@ -0,0 +1,20 @@ +/** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ +function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; +} + +module.exports = copyArray; diff --git a/www/node_modules/lodash/_copyObject.js b/www/node_modules/lodash/_copyObject.js new file mode 100644 index 0000000..f8406b6 --- /dev/null +++ b/www/node_modules/lodash/_copyObject.js @@ -0,0 +1,16 @@ +var copyObjectWith = require('./_copyObjectWith'); + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object) { + return copyObjectWith(source, props, object); +} + +module.exports = copyObject; diff --git a/www/node_modules/lodash/_copyObjectWith.js b/www/node_modules/lodash/_copyObjectWith.js new file mode 100644 index 0000000..c4c1f45 --- /dev/null +++ b/www/node_modules/lodash/_copyObjectWith.js @@ -0,0 +1,32 @@ +var assignValue = require('./_assignValue'); + +/** + * This function is like `copyObject` except that it accepts a function to + * customize copied values. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObjectWith(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : source[key]; + + assignValue(object, key, newValue); + } + return object; +} + +module.exports = copyObjectWith; diff --git a/www/node_modules/lodash/_copySymbols.js b/www/node_modules/lodash/_copySymbols.js new file mode 100644 index 0000000..1fac3c8 --- /dev/null +++ b/www/node_modules/lodash/_copySymbols.js @@ -0,0 +1,16 @@ +var copyObject = require('./_copyObject'), + getSymbols = require('./_getSymbols'); + +/** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); +} + +module.exports = copySymbols; diff --git a/www/node_modules/lodash/_countHolders.js b/www/node_modules/lodash/_countHolders.js new file mode 100644 index 0000000..8cc95e6 --- /dev/null +++ b/www/node_modules/lodash/_countHolders.js @@ -0,0 +1,21 @@ +/** + * Gets the number of `placeholder` occurrences in `array`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} placeholder The placeholder to search for. + * @returns {number} Returns the placeholder count. + */ +function countHolders(array, placeholder) { + var length = array.length, + result = 0; + + while (length--) { + if (array[length] === placeholder) { + result++; + } + } + return result; +} + +module.exports = countHolders; diff --git a/www/node_modules/lodash/_createAggregator.js b/www/node_modules/lodash/_createAggregator.js new file mode 100644 index 0000000..7f7afd2 --- /dev/null +++ b/www/node_modules/lodash/_createAggregator.js @@ -0,0 +1,23 @@ +var arrayAggregator = require('./_arrayAggregator'), + baseAggregator = require('./_baseAggregator'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'); + +/** + * Creates a function like `_.groupBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ +function createAggregator(setter, initializer) { + return function(collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; + + return func(collection, setter, baseIteratee(iteratee), accumulator); + }; +} + +module.exports = createAggregator; diff --git a/www/node_modules/lodash/_createAssigner.js b/www/node_modules/lodash/_createAssigner.js new file mode 100644 index 0000000..1e81db9 --- /dev/null +++ b/www/node_modules/lodash/_createAssigner.js @@ -0,0 +1,37 @@ +var isIterateeCall = require('./_isIterateeCall'), + rest = require('./rest'); + +/** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return rest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = typeof customizer == 'function' + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); +} + +module.exports = createAssigner; diff --git a/www/node_modules/lodash/_createBaseEach.js b/www/node_modules/lodash/_createBaseEach.js new file mode 100644 index 0000000..d24fdd1 --- /dev/null +++ b/www/node_modules/lodash/_createBaseEach.js @@ -0,0 +1,32 @@ +var isArrayLike = require('./isArrayLike'); + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +module.exports = createBaseEach; diff --git a/www/node_modules/lodash/_createBaseFor.js b/www/node_modules/lodash/_createBaseFor.js new file mode 100644 index 0000000..bc84c03 --- /dev/null +++ b/www/node_modules/lodash/_createBaseFor.js @@ -0,0 +1,25 @@ +/** + * Creates a base function for methods like `_.forIn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; +} + +module.exports = createBaseFor; diff --git a/www/node_modules/lodash/_createBaseWrapper.js b/www/node_modules/lodash/_createBaseWrapper.js new file mode 100644 index 0000000..fd3bb9a --- /dev/null +++ b/www/node_modules/lodash/_createBaseWrapper.js @@ -0,0 +1,28 @@ +var createCtorWrapper = require('./_createCtorWrapper'), + root = require('./_root'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1; + +/** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createBaseWrapper(func, bitmask, thisArg) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, arguments); + } + return wrapper; +} + +module.exports = createBaseWrapper; diff --git a/www/node_modules/lodash/_createCaseFirst.js b/www/node_modules/lodash/_createCaseFirst.js new file mode 100644 index 0000000..a6f7054 --- /dev/null +++ b/www/node_modules/lodash/_createCaseFirst.js @@ -0,0 +1,38 @@ +var stringToArray = require('./_stringToArray'), + toString = require('./toString'); + +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); + +/** + * Creates a function like `_.lowerFirst`. + * + * @private + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new function. + */ +function createCaseFirst(methodName) { + return function(string) { + string = toString(string); + + var strSymbols = reHasComplexSymbol.test(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols ? strSymbols[0] : string.charAt(0), + trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1); + + return chr[methodName]() + trailing; + }; +} + +module.exports = createCaseFirst; diff --git a/www/node_modules/lodash/_createCompounder.js b/www/node_modules/lodash/_createCompounder.js new file mode 100644 index 0000000..bfa4ee5 --- /dev/null +++ b/www/node_modules/lodash/_createCompounder.js @@ -0,0 +1,18 @@ +var arrayReduce = require('./_arrayReduce'), + deburr = require('./deburr'), + words = require('./words'); + +/** + * Creates a function like `_.camelCase`. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ +function createCompounder(callback) { + return function(string) { + return arrayReduce(words(deburr(string)), callback, ''); + }; +} + +module.exports = createCompounder; diff --git a/www/node_modules/lodash/_createCtorWrapper.js b/www/node_modules/lodash/_createCtorWrapper.js new file mode 100644 index 0000000..a0a7f83 --- /dev/null +++ b/www/node_modules/lodash/_createCtorWrapper.js @@ -0,0 +1,37 @@ +var baseCreate = require('./_baseCreate'), + isObject = require('./isObject'); + +/** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ +function createCtorWrapper(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; +} + +module.exports = createCtorWrapper; diff --git a/www/node_modules/lodash/_createCurryWrapper.js b/www/node_modules/lodash/_createCurryWrapper.js new file mode 100644 index 0000000..af6f320 --- /dev/null +++ b/www/node_modules/lodash/_createCurryWrapper.js @@ -0,0 +1,46 @@ +var apply = require('./_apply'), + createCtorWrapper = require('./_createCtorWrapper'), + createHybridWrapper = require('./_createHybridWrapper'), + createRecurryWrapper = require('./_createRecurryWrapper'), + getPlaceholder = require('./_getPlaceholder'), + replaceHolders = require('./_replaceHolders'), + root = require('./_root'); + +/** + * Creates a function that wraps `func` to enable currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {number} arity The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createCurryWrapper(func, bitmask, arity) { + var Ctor = createCtorWrapper(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length, + placeholder = getPlaceholder(wrapper); + + while (index--) { + args[index] = arguments[index]; + } + var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) + ? [] + : replaceHolders(args, placeholder); + + length -= holders.length; + if (length < arity) { + return createRecurryWrapper( + func, bitmask, createHybridWrapper, wrapper.placeholder, undefined, + args, holders, undefined, undefined, arity - length); + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return apply(fn, this, args); + } + return wrapper; +} + +module.exports = createCurryWrapper; diff --git a/www/node_modules/lodash/_createFlow.js b/www/node_modules/lodash/_createFlow.js new file mode 100644 index 0000000..8a5e60d --- /dev/null +++ b/www/node_modules/lodash/_createFlow.js @@ -0,0 +1,83 @@ +var LodashWrapper = require('./_LodashWrapper'), + baseFlatten = require('./_baseFlatten'), + getData = require('./_getData'), + getFuncName = require('./_getFuncName'), + isArray = require('./isArray'), + isLaziable = require('./_isLaziable'), + rest = require('./rest'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** Used to compose bitmasks for wrapper metadata. */ +var CURRY_FLAG = 8, + PARTIAL_FLAG = 32, + ARY_FLAG = 128, + REARG_FLAG = 256; + +/** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ +function createFlow(fromRight) { + return rest(function(funcs) { + funcs = baseFlatten(funcs, 1); + + var length = funcs.length, + index = length, + prereq = LodashWrapper.prototype.thru; + + if (fromRight) { + funcs.reverse(); + } + while (index--) { + var func = funcs[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (prereq && !wrapper && getFuncName(func) == 'wrapper') { + var wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? index : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && + data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && + isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }); +} + +module.exports = createFlow; diff --git a/www/node_modules/lodash/_createHybridWrapper.js b/www/node_modules/lodash/_createHybridWrapper.js new file mode 100644 index 0000000..eaf8c81 --- /dev/null +++ b/www/node_modules/lodash/_createHybridWrapper.js @@ -0,0 +1,90 @@ +var composeArgs = require('./_composeArgs'), + composeArgsRight = require('./_composeArgsRight'), + countHolders = require('./_countHolders'), + createCtorWrapper = require('./_createCtorWrapper'), + createRecurryWrapper = require('./_createRecurryWrapper'), + getPlaceholder = require('./_getPlaceholder'), + reorder = require('./_reorder'), + replaceHolders = require('./_replaceHolders'), + root = require('./_root'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + ARY_FLAG = 128, + FLIP_FLAG = 512; + +/** + * Creates a function that wraps `func` to invoke it with optional `this` + * binding of `thisArg`, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG), + isFlip = bitmask & FLIP_FLAG, + Ctor = isBindKey ? undefined : createCtorWrapper(func); + + function wrapper() { + var length = arguments.length, + index = length, + args = Array(length); + + while (index--) { + args[index] = arguments[index]; + } + if (isCurried) { + var placeholder = getPlaceholder(wrapper), + holdersCount = countHolders(args, placeholder); + } + if (partials) { + args = composeArgs(args, partials, holders, isCurried); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight, isCurried); + } + length -= holdersCount; + if (isCurried && length < arity) { + var newHolders = replaceHolders(args, placeholder); + return createRecurryWrapper( + func, bitmask, createHybridWrapper, wrapper.placeholder, thisArg, + args, newHolders, argPos, ary, arity - length + ); + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + length = args.length; + if (argPos) { + args = reorder(args, argPos); + } else if (isFlip && length > 1) { + args.reverse(); + } + if (isAry && ary < length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtorWrapper(fn); + } + return fn.apply(thisBinding, args); + } + return wrapper; +} + +module.exports = createHybridWrapper; diff --git a/www/node_modules/lodash/_createInverter.js b/www/node_modules/lodash/_createInverter.js new file mode 100644 index 0000000..6c0c562 --- /dev/null +++ b/www/node_modules/lodash/_createInverter.js @@ -0,0 +1,17 @@ +var baseInverter = require('./_baseInverter'); + +/** + * Creates a function like `_.invertBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} toIteratee The function to resolve iteratees. + * @returns {Function} Returns the new inverter function. + */ +function createInverter(setter, toIteratee) { + return function(object, iteratee) { + return baseInverter(object, setter, toIteratee(iteratee), {}); + }; +} + +module.exports = createInverter; diff --git a/www/node_modules/lodash/_createOver.js b/www/node_modules/lodash/_createOver.js new file mode 100644 index 0000000..f0a99c3 --- /dev/null +++ b/www/node_modules/lodash/_createOver.js @@ -0,0 +1,26 @@ +var apply = require('./_apply'), + arrayMap = require('./_arrayMap'), + baseFlatten = require('./_baseFlatten'), + baseIteratee = require('./_baseIteratee'), + rest = require('./rest'); + +/** + * Creates a function like `_.over`. + * + * @private + * @param {Function} arrayFunc The function to iterate over iteratees. + * @returns {Function} Returns the new invoker function. + */ +function createOver(arrayFunc) { + return rest(function(iteratees) { + iteratees = arrayMap(baseFlatten(iteratees, 1), baseIteratee); + return rest(function(args) { + var thisArg = this; + return arrayFunc(iteratees, function(iteratee) { + return apply(iteratee, thisArg, args); + }); + }); + }); +} + +module.exports = createOver; diff --git a/www/node_modules/lodash/_createPadding.js b/www/node_modules/lodash/_createPadding.js new file mode 100644 index 0000000..e59cc52 --- /dev/null +++ b/www/node_modules/lodash/_createPadding.js @@ -0,0 +1,47 @@ +var repeat = require('./repeat'), + stringSize = require('./_stringSize'), + stringToArray = require('./_stringToArray'), + toInteger = require('./toInteger'); + +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil; + +/** + * Creates the padding for `string` based on `length`. The `chars` string + * is truncated if the number of characters exceeds `length`. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padding for `string`. + */ +function createPadding(string, length, chars) { + length = toInteger(length); + + var strLength = stringSize(string); + if (!length || strLength >= length) { + return ''; + } + var padLength = length - strLength; + chars = chars === undefined ? ' ' : (chars + ''); + + var result = repeat(chars, nativeCeil(padLength / stringSize(chars))); + return reHasComplexSymbol.test(chars) + ? stringToArray(result).slice(0, padLength).join('') + : result.slice(0, padLength); +} + +module.exports = createPadding; diff --git a/www/node_modules/lodash/_createPartialWrapper.js b/www/node_modules/lodash/_createPartialWrapper.js new file mode 100644 index 0000000..1fc3a9b --- /dev/null +++ b/www/node_modules/lodash/_createPartialWrapper.js @@ -0,0 +1,43 @@ +var apply = require('./_apply'), + createCtorWrapper = require('./_createCtorWrapper'), + root = require('./_root'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1; + +/** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new wrapped function. + */ +function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return apply(fn, isBind ? thisArg : this, args); + } + return wrapper; +} + +module.exports = createPartialWrapper; diff --git a/www/node_modules/lodash/_createRange.js b/www/node_modules/lodash/_createRange.js new file mode 100644 index 0000000..9728563 --- /dev/null +++ b/www/node_modules/lodash/_createRange.js @@ -0,0 +1,31 @@ +var baseRange = require('./_baseRange'), + isIterateeCall = require('./_isIterateeCall'), + toNumber = require('./toNumber'); + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = toNumber(start); + start = start === start ? start : 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = toNumber(end) || 0; + } + step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0); + return baseRange(start, end, step, fromRight); + }; +} + +module.exports = createRange; diff --git a/www/node_modules/lodash/_createRecurryWrapper.js b/www/node_modules/lodash/_createRecurryWrapper.js new file mode 100644 index 0000000..027424e --- /dev/null +++ b/www/node_modules/lodash/_createRecurryWrapper.js @@ -0,0 +1,56 @@ +var copyArray = require('./_copyArray'), + isLaziable = require('./_isLaziable'), + setData = require('./_setData'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64; + +/** + * Creates a function that wraps `func` to continue currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {Function} wrapFunc The function to create the `func` wrapper. + * @param {*} placeholder The placeholder value. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { + var isCurry = bitmask & CURRY_FLAG, + newArgPos = argPos ? copyArray(argPos) : undefined, + newHolders = isCurry ? holders : undefined, + newHoldersRight = isCurry ? undefined : holders, + newPartials = isCurry ? partials : undefined, + newPartialsRight = isCurry ? undefined : partials; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!(bitmask & CURRY_BOUND_FLAG)) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [ + func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, + newHoldersRight, newArgPos, ary, arity + ]; + + var result = wrapFunc.apply(undefined, newData); + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; +} + +module.exports = createRecurryWrapper; diff --git a/www/node_modules/lodash/_createRound.js b/www/node_modules/lodash/_createRound.js new file mode 100644 index 0000000..cb42ba2 --- /dev/null +++ b/www/node_modules/lodash/_createRound.js @@ -0,0 +1,30 @@ +var toInteger = require('./toInteger'), + toNumber = require('./toNumber'), + toString = require('./toString'); + +/** + * Creates a function like `_.round`. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ +function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + number = toNumber(number); + precision = toInteger(precision); + if (precision) { + // Shift with exponential notation to avoid floating-point issues. + // See [MDN](https://mdn.io/round#Examples) for more details. + var pair = (toString(number) + 'e').split('e'), + value = func(pair[0] + 'e' + (+pair[1] + precision)); + + pair = (toString(value) + 'e').split('e'); + return +(pair[0] + 'e' + (+pair[1] - precision)); + } + return func(number); + }; +} + +module.exports = createRound; diff --git a/www/node_modules/lodash/_createSet.js b/www/node_modules/lodash/_createSet.js new file mode 100644 index 0000000..c67128f --- /dev/null +++ b/www/node_modules/lodash/_createSet.js @@ -0,0 +1,15 @@ +var Set = require('./_Set'), + noop = require('./noop'); + +/** + * Creates a set of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) { + return new Set(values); +}; + +module.exports = createSet; diff --git a/www/node_modules/lodash/_createWrapper.js b/www/node_modules/lodash/_createWrapper.js new file mode 100644 index 0000000..7b573b2 --- /dev/null +++ b/www/node_modules/lodash/_createWrapper.js @@ -0,0 +1,105 @@ +var baseSetData = require('./_baseSetData'), + createBaseWrapper = require('./_createBaseWrapper'), + createCurryWrapper = require('./_createCurryWrapper'), + createHybridWrapper = require('./_createHybridWrapper'), + createPartialWrapper = require('./_createPartialWrapper'), + getData = require('./_getData'), + mergeData = require('./_mergeData'), + setData = require('./_setData'), + toInteger = require('./toInteger'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask of wrapper flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ +function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); + arity = arity === undefined ? arity : toInteger(arity); + length -= holders ? holders.length : 0; + + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; + + if (data) { + mergeData(newData, data); + } + func = newData[0]; + bitmask = newData[1]; + thisArg = newData[2]; + partials = newData[3]; + holders = newData[4]; + arity = newData[9] = newData[9] == null + ? (isBindKey ? 0 : func.length) + : nativeMax(newData[9] - length, 0); + + if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) { + bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG); + } + if (!bitmask || bitmask == BIND_FLAG) { + var result = createBaseWrapper(func, bitmask, thisArg); + } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) { + result = createCurryWrapper(func, bitmask, arity); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) { + result = createPartialWrapper(func, bitmask, thisArg, partials); + } else { + result = createHybridWrapper.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); +} + +module.exports = createWrapper; diff --git a/www/node_modules/lodash/_deburrLetter.js b/www/node_modules/lodash/_deburrLetter.js new file mode 100644 index 0000000..e559dbe --- /dev/null +++ b/www/node_modules/lodash/_deburrLetter.js @@ -0,0 +1,33 @@ +/** Used to map latin-1 supplementary letters to basic latin letters. */ +var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' +}; + +/** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ +function deburrLetter(letter) { + return deburredLetters[letter]; +} + +module.exports = deburrLetter; diff --git a/www/node_modules/lodash/_equalArrays.js b/www/node_modules/lodash/_equalArrays.js new file mode 100644 index 0000000..eb39015 --- /dev/null +++ b/www/node_modules/lodash/_equalArrays.js @@ -0,0 +1,72 @@ +var arraySome = require('./_arraySome'); + +/** Used to compose bitmasks for comparison styles. */ +var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { + var index = -1, + isPartial = bitmask & PARTIAL_COMPARE_FLAG, + isUnordered = bitmask & UNORDERED_COMPARE_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked) { + return stacked == other; + } + var result = true; + stack.set(array, other); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isUnordered) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack); + })) { + result = false; + break; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { + result = false; + break; + } + } + stack['delete'](array); + return result; +} + +module.exports = equalArrays; diff --git a/www/node_modules/lodash/_equalByTag.js b/www/node_modules/lodash/_equalByTag.js new file mode 100644 index 0000000..15b3860 --- /dev/null +++ b/www/node_modules/lodash/_equalByTag.js @@ -0,0 +1,99 @@ +var Symbol = require('./_Symbol'), + Uint8Array = require('./_Uint8Array'), + equalArrays = require('./_equalArrays'), + mapToArray = require('./_mapToArray'), + setToArray = require('./_setToArray'); + +/** Used to compose bitmasks for comparison styles. */ +var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) { + switch (tag) { + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) ? other != +other : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & PARTIAL_COMPARE_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + // Recursively compare objects (susceptible to call stack limits). + return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask | UNORDERED_COMPARE_FLAG, stack.set(object, other)); + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +module.exports = equalByTag; diff --git a/www/node_modules/lodash/_equalObjects.js b/www/node_modules/lodash/_equalObjects.js new file mode 100644 index 0000000..103f435 --- /dev/null +++ b/www/node_modules/lodash/_equalObjects.js @@ -0,0 +1,82 @@ +var baseHas = require('./_baseHas'), + keys = require('./keys'); + +/** Used to compose bitmasks for comparison styles. */ +var PARTIAL_COMPARE_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { + var isPartial = bitmask & PARTIAL_COMPARE_FLAG, + objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : baseHas(other, key))) { + return false; + } + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + var result = true; + stack.set(object, other); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + return result; +} + +module.exports = equalObjects; diff --git a/www/node_modules/lodash/_escapeHtmlChar.js b/www/node_modules/lodash/_escapeHtmlChar.js new file mode 100644 index 0000000..b21e452 --- /dev/null +++ b/www/node_modules/lodash/_escapeHtmlChar.js @@ -0,0 +1,22 @@ +/** Used to map characters to HTML entities. */ +var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' +}; + +/** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ +function escapeHtmlChar(chr) { + return htmlEscapes[chr]; +} + +module.exports = escapeHtmlChar; diff --git a/www/node_modules/lodash/_escapeStringChar.js b/www/node_modules/lodash/_escapeStringChar.js new file mode 100644 index 0000000..44eca96 --- /dev/null +++ b/www/node_modules/lodash/_escapeStringChar.js @@ -0,0 +1,22 @@ +/** Used to escape characters for inclusion in compiled string literals. */ +var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' +}; + +/** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ +function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; +} + +module.exports = escapeStringChar; diff --git a/www/node_modules/lodash/_getData.js b/www/node_modules/lodash/_getData.js new file mode 100644 index 0000000..a1fe7b7 --- /dev/null +++ b/www/node_modules/lodash/_getData.js @@ -0,0 +1,15 @@ +var metaMap = require('./_metaMap'), + noop = require('./noop'); + +/** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ +var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); +}; + +module.exports = getData; diff --git a/www/node_modules/lodash/_getFuncName.js b/www/node_modules/lodash/_getFuncName.js new file mode 100644 index 0000000..21e15b3 --- /dev/null +++ b/www/node_modules/lodash/_getFuncName.js @@ -0,0 +1,31 @@ +var realNames = require('./_realNames'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ +function getFuncName(func) { + var result = (func.name + ''), + array = realNames[result], + length = hasOwnProperty.call(realNames, result) ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; +} + +module.exports = getFuncName; diff --git a/www/node_modules/lodash/_getLength.js b/www/node_modules/lodash/_getLength.js new file mode 100644 index 0000000..1848d49 --- /dev/null +++ b/www/node_modules/lodash/_getLength.js @@ -0,0 +1,15 @@ +var baseProperty = require('./_baseProperty'); + +/** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ +var getLength = baseProperty('length'); + +module.exports = getLength; diff --git a/www/node_modules/lodash/_getMatchData.js b/www/node_modules/lodash/_getMatchData.js new file mode 100644 index 0000000..a1456d2 --- /dev/null +++ b/www/node_modules/lodash/_getMatchData.js @@ -0,0 +1,21 @@ +var isStrictComparable = require('./_isStrictComparable'), + toPairs = require('./toPairs'); + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = toPairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; +} + +module.exports = getMatchData; diff --git a/www/node_modules/lodash/_getNative.js b/www/node_modules/lodash/_getNative.js new file mode 100644 index 0000000..f6ff7f1 --- /dev/null +++ b/www/node_modules/lodash/_getNative.js @@ -0,0 +1,16 @@ +var isNative = require('./isNative'); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = object[key]; + return isNative(value) ? value : undefined; +} + +module.exports = getNative; diff --git a/www/node_modules/lodash/_getPlaceholder.js b/www/node_modules/lodash/_getPlaceholder.js new file mode 100644 index 0000000..4bbcda2 --- /dev/null +++ b/www/node_modules/lodash/_getPlaceholder.js @@ -0,0 +1,13 @@ +/** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ +function getPlaceholder(func) { + var object = func; + return object.placeholder; +} + +module.exports = getPlaceholder; diff --git a/www/node_modules/lodash/_getSymbols.js b/www/node_modules/lodash/_getSymbols.js new file mode 100644 index 0000000..266906a --- /dev/null +++ b/www/node_modules/lodash/_getSymbols.js @@ -0,0 +1,15 @@ +/** Built-in value references. */ +var getOwnPropertySymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = getOwnPropertySymbols || function() { + return []; +}; + +module.exports = getSymbols; diff --git a/www/node_modules/lodash/_getTag.js b/www/node_modules/lodash/_getTag.js new file mode 100644 index 0000000..1516eca --- /dev/null +++ b/www/node_modules/lodash/_getTag.js @@ -0,0 +1,59 @@ +var Map = require('./_Map'), + Set = require('./_Set'), + WeakMap = require('./_WeakMap'); + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + objectTag = '[object Object]', + setTag = '[object Set]', + weakMapTag = '[object WeakMap]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = Function.prototype.toString; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Used to detect maps, sets, and weakmaps. */ +var mapCtorString = Map ? funcToString.call(Map) : '', + setCtorString = Set ? funcToString.call(Set) : '', + weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : ''; + +/** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function getTag(value) { + return objectToString.call(value); +} + +// Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps. +if ((Map && getTag(new Map) != mapTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : null, + ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case mapCtorString: return mapTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; +} + +module.exports = getTag; diff --git a/www/node_modules/lodash/_getView.js b/www/node_modules/lodash/_getView.js new file mode 100644 index 0000000..df1e5d4 --- /dev/null +++ b/www/node_modules/lodash/_getView.js @@ -0,0 +1,33 @@ +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ +function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; +} + +module.exports = getView; diff --git a/www/node_modules/lodash/_hasPath.js b/www/node_modules/lodash/_hasPath.js new file mode 100644 index 0000000..ed4f1a1 --- /dev/null +++ b/www/node_modules/lodash/_hasPath.js @@ -0,0 +1,40 @@ +var baseCastPath = require('./_baseCastPath'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isIndex = require('./_isIndex'), + isKey = require('./_isKey'), + isLength = require('./isLength'), + isString = require('./isString'), + last = require('./last'), + parent = require('./_parent'); + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + if (object == null) { + return false; + } + var result = hasFunc(object, path); + if (!result && !isKey(path)) { + path = baseCastPath(path); + object = parent(object, path); + if (object != null) { + path = last(path); + result = hasFunc(object, path); + } + } + var length = object ? object.length : undefined; + return result || ( + !!length && isLength(length) && isIndex(path, length) && + (isArray(object) || isString(object) || isArguments(object)) + ); +} + +module.exports = hasPath; diff --git a/www/node_modules/lodash/_hashDelete.js b/www/node_modules/lodash/_hashDelete.js new file mode 100644 index 0000000..b562317 --- /dev/null +++ b/www/node_modules/lodash/_hashDelete.js @@ -0,0 +1,15 @@ +var hashHas = require('./_hashHas'); + +/** + * Removes `key` and its value from the hash. + * + * @private + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(hash, key) { + return hashHas(hash, key) && delete hash[key]; +} + +module.exports = hashDelete; diff --git a/www/node_modules/lodash/_hashGet.js b/www/node_modules/lodash/_hashGet.js new file mode 100644 index 0000000..ba509b6 --- /dev/null +++ b/www/node_modules/lodash/_hashGet.js @@ -0,0 +1,28 @@ +var nativeCreate = require('./_nativeCreate'); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Gets the hash value for `key`. + * + * @private + * @param {Object} hash The hash to query. + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(hash, key) { + if (nativeCreate) { + var result = hash[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(hash, key) ? hash[key] : undefined; +} + +module.exports = hashGet; diff --git a/www/node_modules/lodash/_hashHas.js b/www/node_modules/lodash/_hashHas.js new file mode 100644 index 0000000..3bbff48 --- /dev/null +++ b/www/node_modules/lodash/_hashHas.js @@ -0,0 +1,21 @@ +var nativeCreate = require('./_nativeCreate'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @param {Object} hash The hash to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(hash, key) { + return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key); +} + +module.exports = hashHas; diff --git a/www/node_modules/lodash/_hashSet.js b/www/node_modules/lodash/_hashSet.js new file mode 100644 index 0000000..f7c3307 --- /dev/null +++ b/www/node_modules/lodash/_hashSet.js @@ -0,0 +1,18 @@ +var nativeCreate = require('./_nativeCreate'); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Sets the hash `key` to `value`. + * + * @private + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + */ +function hashSet(hash, key, value) { + hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; +} + +module.exports = hashSet; diff --git a/www/node_modules/lodash/_indexKeys.js b/www/node_modules/lodash/_indexKeys.js new file mode 100644 index 0000000..0e2fc10 --- /dev/null +++ b/www/node_modules/lodash/_indexKeys.js @@ -0,0 +1,24 @@ +var baseTimes = require('./_baseTimes'), + isArguments = require('./isArguments'), + isArray = require('./isArray'), + isLength = require('./isLength'), + isString = require('./isString'); + +/** + * Creates an array of index keys for `object` values of arrays, + * `arguments` objects, and strings, otherwise `null` is returned. + * + * @private + * @param {Object} object The object to query. + * @returns {Array|null} Returns index keys, else `null`. + */ +function indexKeys(object) { + var length = object ? object.length : undefined; + if (isLength(length) && + (isArray(object) || isString(object) || isArguments(object))) { + return baseTimes(length, String); + } + return null; +} + +module.exports = indexKeys; diff --git a/www/node_modules/lodash/_indexOfNaN.js b/www/node_modules/lodash/_indexOfNaN.js new file mode 100644 index 0000000..05b8207 --- /dev/null +++ b/www/node_modules/lodash/_indexOfNaN.js @@ -0,0 +1,23 @@ +/** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * + * @private + * @param {Array} array The array to search. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched `NaN`, else `-1`. + */ +function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 0 : -1); + + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; + } + } + return -1; +} + +module.exports = indexOfNaN; diff --git a/www/node_modules/lodash/_initCloneArray.js b/www/node_modules/lodash/_initCloneArray.js new file mode 100644 index 0000000..aef0212 --- /dev/null +++ b/www/node_modules/lodash/_initCloneArray.js @@ -0,0 +1,26 @@ +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +module.exports = initCloneArray; diff --git a/www/node_modules/lodash/_initCloneByTag.js b/www/node_modules/lodash/_initCloneByTag.js new file mode 100644 index 0000000..5d21cda --- /dev/null +++ b/www/node_modules/lodash/_initCloneByTag.js @@ -0,0 +1,74 @@ +var cloneArrayBuffer = require('./_cloneArrayBuffer'), + cloneMap = require('./_cloneMap'), + cloneRegExp = require('./_cloneRegExp'), + cloneSet = require('./_cloneSet'), + cloneSymbol = require('./_cloneSymbol'), + cloneTypedArray = require('./_cloneTypedArray'); + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object); + + case symbolTag: + return cloneSymbol(object); + } +} + +module.exports = initCloneByTag; diff --git a/www/node_modules/lodash/_initCloneObject.js b/www/node_modules/lodash/_initCloneObject.js new file mode 100644 index 0000000..14d2dc4 --- /dev/null +++ b/www/node_modules/lodash/_initCloneObject.js @@ -0,0 +1,20 @@ +var baseCreate = require('./_baseCreate'), + isPrototype = require('./_isPrototype'); + +/** Built-in value references. */ +var getPrototypeOf = Object.getPrototypeOf; + +/** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototypeOf(object)) + : {}; +} + +module.exports = initCloneObject; diff --git a/www/node_modules/lodash/_isHostObject.js b/www/node_modules/lodash/_isHostObject.js new file mode 100644 index 0000000..e598c10 --- /dev/null +++ b/www/node_modules/lodash/_isHostObject.js @@ -0,0 +1,20 @@ +/** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ +function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; +} + +module.exports = isHostObject; diff --git a/www/node_modules/lodash/_isIndex.js b/www/node_modules/lodash/_isIndex.js new file mode 100644 index 0000000..c7ff607 --- /dev/null +++ b/www/node_modules/lodash/_isIndex.js @@ -0,0 +1,21 @@ +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; +} + +module.exports = isIndex; diff --git a/www/node_modules/lodash/_isIterateeCall.js b/www/node_modules/lodash/_isIterateeCall.js new file mode 100644 index 0000000..b422b48 --- /dev/null +++ b/www/node_modules/lodash/_isIterateeCall.js @@ -0,0 +1,28 @@ +var eq = require('./eq'), + isArrayLike = require('./isArrayLike'), + isIndex = require('./_isIndex'), + isObject = require('./isObject'); + +/** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + return eq(object[index], value); + } + return false; +} + +module.exports = isIterateeCall; diff --git a/www/node_modules/lodash/_isKey.js b/www/node_modules/lodash/_isKey.js new file mode 100644 index 0000000..0e34576 --- /dev/null +++ b/www/node_modules/lodash/_isKey.js @@ -0,0 +1,24 @@ +var isArray = require('./isArray'); + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if (typeof value == 'number') { + return true; + } + return !isArray(value) && + (reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object))); +} + +module.exports = isKey; diff --git a/www/node_modules/lodash/_isKeyable.js b/www/node_modules/lodash/_isKeyable.js new file mode 100644 index 0000000..5df83c0 --- /dev/null +++ b/www/node_modules/lodash/_isKeyable.js @@ -0,0 +1,14 @@ +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return type == 'number' || type == 'boolean' || + (type == 'string' && value != '__proto__') || value == null; +} + +module.exports = isKeyable; diff --git a/www/node_modules/lodash/_isLaziable.js b/www/node_modules/lodash/_isLaziable.js new file mode 100644 index 0000000..faa17b9 --- /dev/null +++ b/www/node_modules/lodash/_isLaziable.js @@ -0,0 +1,27 @@ +var LazyWrapper = require('./_LazyWrapper'), + getData = require('./_getData'), + getFuncName = require('./_getFuncName'), + lodash = require('./wrapperLodash'); + +/** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + */ +function isLaziable(func) { + var funcName = getFuncName(func), + other = lodash[funcName]; + + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { + return false; + } + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; +} + +module.exports = isLaziable; diff --git a/www/node_modules/lodash/_isPrototype.js b/www/node_modules/lodash/_isPrototype.js new file mode 100644 index 0000000..0f29498 --- /dev/null +++ b/www/node_modules/lodash/_isPrototype.js @@ -0,0 +1,18 @@ +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +module.exports = isPrototype; diff --git a/www/node_modules/lodash/_isStrictComparable.js b/www/node_modules/lodash/_isStrictComparable.js new file mode 100644 index 0000000..b59f40b --- /dev/null +++ b/www/node_modules/lodash/_isStrictComparable.js @@ -0,0 +1,15 @@ +var isObject = require('./isObject'); + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !isObject(value); +} + +module.exports = isStrictComparable; diff --git a/www/node_modules/lodash/_iteratorToArray.js b/www/node_modules/lodash/_iteratorToArray.js new file mode 100644 index 0000000..4768566 --- /dev/null +++ b/www/node_modules/lodash/_iteratorToArray.js @@ -0,0 +1,18 @@ +/** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ +function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; +} + +module.exports = iteratorToArray; diff --git a/www/node_modules/lodash/_lazyClone.js b/www/node_modules/lodash/_lazyClone.js new file mode 100644 index 0000000..d8a51f8 --- /dev/null +++ b/www/node_modules/lodash/_lazyClone.js @@ -0,0 +1,23 @@ +var LazyWrapper = require('./_LazyWrapper'), + copyArray = require('./_copyArray'); + +/** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ +function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = copyArray(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = copyArray(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = copyArray(this.__views__); + return result; +} + +module.exports = lazyClone; diff --git a/www/node_modules/lodash/_lazyReverse.js b/www/node_modules/lodash/_lazyReverse.js new file mode 100644 index 0000000..c5b5219 --- /dev/null +++ b/www/node_modules/lodash/_lazyReverse.js @@ -0,0 +1,23 @@ +var LazyWrapper = require('./_LazyWrapper'); + +/** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ +function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; +} + +module.exports = lazyReverse; diff --git a/www/node_modules/lodash/_lazyValue.js b/www/node_modules/lodash/_lazyValue.js new file mode 100644 index 0000000..09bf14b --- /dev/null +++ b/www/node_modules/lodash/_lazyValue.js @@ -0,0 +1,73 @@ +var baseWrapperValue = require('./_baseWrapperValue'), + getView = require('./_getView'), + isArray = require('./isArray'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** Used to indicate the type of lazy iteratees. */ +var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ +function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || + (arrLength == length && takeCount == length)) { + return baseWrapperValue(array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; +} + +module.exports = lazyValue; diff --git a/www/node_modules/lodash/_mapClear.js b/www/node_modules/lodash/_mapClear.js new file mode 100644 index 0000000..296f417 --- /dev/null +++ b/www/node_modules/lodash/_mapClear.js @@ -0,0 +1,19 @@ +var Hash = require('./_Hash'), + Map = require('./_Map'); + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapClear() { + this.__data__ = { + 'hash': new Hash, + 'map': Map ? new Map : [], + 'string': new Hash + }; +} + +module.exports = mapClear; diff --git a/www/node_modules/lodash/_mapDelete.js b/www/node_modules/lodash/_mapDelete.js new file mode 100644 index 0000000..640eb0a --- /dev/null +++ b/www/node_modules/lodash/_mapDelete.js @@ -0,0 +1,23 @@ +var Map = require('./_Map'), + assocDelete = require('./_assocDelete'), + hashDelete = require('./_hashDelete'), + isKeyable = require('./_isKeyable'); + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapDelete(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashDelete(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map['delete'](key) : assocDelete(data.map, key); +} + +module.exports = mapDelete; diff --git a/www/node_modules/lodash/_mapGet.js b/www/node_modules/lodash/_mapGet.js new file mode 100644 index 0000000..8f33854 --- /dev/null +++ b/www/node_modules/lodash/_mapGet.js @@ -0,0 +1,23 @@ +var Map = require('./_Map'), + assocGet = require('./_assocGet'), + hashGet = require('./_hashGet'), + isKeyable = require('./_isKeyable'); + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapGet(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashGet(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map.get(key) : assocGet(data.map, key); +} + +module.exports = mapGet; diff --git a/www/node_modules/lodash/_mapHas.js b/www/node_modules/lodash/_mapHas.js new file mode 100644 index 0000000..9225537 --- /dev/null +++ b/www/node_modules/lodash/_mapHas.js @@ -0,0 +1,23 @@ +var Map = require('./_Map'), + assocHas = require('./_assocHas'), + hashHas = require('./_hashHas'), + isKeyable = require('./_isKeyable'); + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapHas(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashHas(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map.has(key) : assocHas(data.map, key); +} + +module.exports = mapHas; diff --git a/www/node_modules/lodash/_mapSet.js b/www/node_modules/lodash/_mapSet.js new file mode 100644 index 0000000..7a58786 --- /dev/null +++ b/www/node_modules/lodash/_mapSet.js @@ -0,0 +1,28 @@ +var Map = require('./_Map'), + assocSet = require('./_assocSet'), + hashSet = require('./_hashSet'), + isKeyable = require('./_isKeyable'); + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache object. + */ +function mapSet(key, value) { + var data = this.__data__; + if (isKeyable(key)) { + hashSet(typeof key == 'string' ? data.string : data.hash, key, value); + } else if (Map) { + data.map.set(key, value); + } else { + assocSet(data.map, key, value); + } + return this; +} + +module.exports = mapSet; diff --git a/www/node_modules/lodash/_mapToArray.js b/www/node_modules/lodash/_mapToArray.js new file mode 100644 index 0000000..e2e8a24 --- /dev/null +++ b/www/node_modules/lodash/_mapToArray.js @@ -0,0 +1,18 @@ +/** + * Converts `map` to an array. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the converted array. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +module.exports = mapToArray; diff --git a/www/node_modules/lodash/_mergeData.js b/www/node_modules/lodash/_mergeData.js new file mode 100644 index 0000000..ac6fa4c --- /dev/null +++ b/www/node_modules/lodash/_mergeData.js @@ -0,0 +1,90 @@ +var composeArgs = require('./_composeArgs'), + composeArgsRight = require('./_composeArgsRight'), + copyArray = require('./_copyArray'), + replaceHolders = require('./_replaceHolders'); + +/** Used as the internal argument placeholder. */ +var PLACEHOLDER = '__lodash_placeholder__'; + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + ARY_FLAG = 128, + REARG_FLAG = 256; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers used to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` + * modify function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * combined case where curried functions have `_.ary` and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ +function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG); + + var isCombo = + ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) || + ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) || + ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG)); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = copyArray(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; +} + +module.exports = mergeData; diff --git a/www/node_modules/lodash/_mergeDefaults.js b/www/node_modules/lodash/_mergeDefaults.js new file mode 100644 index 0000000..263836b --- /dev/null +++ b/www/node_modules/lodash/_mergeDefaults.js @@ -0,0 +1,23 @@ +var baseMerge = require('./_baseMerge'), + isObject = require('./isObject'); + +/** + * Used by `_.defaultsDeep` to customize its `_.merge` use. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to merge. + * @param {Object} object The parent object of `objValue`. + * @param {Object} source The parent object of `srcValue`. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + * @returns {*} Returns the value to assign. + */ +function mergeDefaults(objValue, srcValue, key, object, source, stack) { + if (isObject(objValue) && isObject(srcValue)) { + baseMerge(objValue, srcValue, undefined, mergeDefaults, stack.set(srcValue, objValue)); + } + return objValue; +} + +module.exports = mergeDefaults; diff --git a/www/node_modules/lodash/_metaMap.js b/www/node_modules/lodash/_metaMap.js new file mode 100644 index 0000000..0157a0b --- /dev/null +++ b/www/node_modules/lodash/_metaMap.js @@ -0,0 +1,6 @@ +var WeakMap = require('./_WeakMap'); + +/** Used to store function metadata. */ +var metaMap = WeakMap && new WeakMap; + +module.exports = metaMap; diff --git a/www/node_modules/lodash/_nativeCreate.js b/www/node_modules/lodash/_nativeCreate.js new file mode 100644 index 0000000..c7aede8 --- /dev/null +++ b/www/node_modules/lodash/_nativeCreate.js @@ -0,0 +1,6 @@ +var getNative = require('./_getNative'); + +/* Built-in method references that are verified to be native. */ +var nativeCreate = getNative(Object, 'create'); + +module.exports = nativeCreate; diff --git a/www/node_modules/lodash/_parent.js b/www/node_modules/lodash/_parent.js new file mode 100644 index 0000000..e04ff6e --- /dev/null +++ b/www/node_modules/lodash/_parent.js @@ -0,0 +1,16 @@ +var baseSlice = require('./_baseSlice'), + get = require('./get'); + +/** + * Gets the parent value at `path` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. + */ +function parent(object, path) { + return path.length == 1 ? object : get(object, baseSlice(path, 0, -1)); +} + +module.exports = parent; diff --git a/www/node_modules/lodash/_reEscape.js b/www/node_modules/lodash/_reEscape.js new file mode 100644 index 0000000..7f47eda --- /dev/null +++ b/www/node_modules/lodash/_reEscape.js @@ -0,0 +1,4 @@ +/** Used to match template delimiters. */ +var reEscape = /<%-([\s\S]+?)%>/g; + +module.exports = reEscape; diff --git a/www/node_modules/lodash/_reEvaluate.js b/www/node_modules/lodash/_reEvaluate.js new file mode 100644 index 0000000..6adfc31 --- /dev/null +++ b/www/node_modules/lodash/_reEvaluate.js @@ -0,0 +1,4 @@ +/** Used to match template delimiters. */ +var reEvaluate = /<%([\s\S]+?)%>/g; + +module.exports = reEvaluate; diff --git a/www/node_modules/lodash/_reInterpolate.js b/www/node_modules/lodash/_reInterpolate.js new file mode 100644 index 0000000..d02ff0b --- /dev/null +++ b/www/node_modules/lodash/_reInterpolate.js @@ -0,0 +1,4 @@ +/** Used to match template delimiters. */ +var reInterpolate = /<%=([\s\S]+?)%>/g; + +module.exports = reInterpolate; diff --git a/www/node_modules/lodash/_realNames.js b/www/node_modules/lodash/_realNames.js new file mode 100644 index 0000000..aa0d529 --- /dev/null +++ b/www/node_modules/lodash/_realNames.js @@ -0,0 +1,4 @@ +/** Used to lookup unminified function names. */ +var realNames = {}; + +module.exports = realNames; diff --git a/www/node_modules/lodash/_reorder.js b/www/node_modules/lodash/_reorder.js new file mode 100644 index 0000000..a3502b0 --- /dev/null +++ b/www/node_modules/lodash/_reorder.js @@ -0,0 +1,29 @@ +var copyArray = require('./_copyArray'), + isIndex = require('./_isIndex'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMin = Math.min; + +/** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ +function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = copyArray(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; +} + +module.exports = reorder; diff --git a/www/node_modules/lodash/_replaceHolders.js b/www/node_modules/lodash/_replaceHolders.js new file mode 100644 index 0000000..74360ec --- /dev/null +++ b/www/node_modules/lodash/_replaceHolders.js @@ -0,0 +1,29 @@ +/** Used as the internal argument placeholder. */ +var PLACEHOLDER = '__lodash_placeholder__'; + +/** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ +function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value === placeholder || value === PLACEHOLDER) { + array[index] = PLACEHOLDER; + result[resIndex++] = index; + } + } + return result; +} + +module.exports = replaceHolders; diff --git a/www/node_modules/lodash/_root.js b/www/node_modules/lodash/_root.js new file mode 100644 index 0000000..d2cfd31 --- /dev/null +++ b/www/node_modules/lodash/_root.js @@ -0,0 +1,41 @@ +var checkGlobal = require('./_checkGlobal'); + +/** Used to determine if values are of the language type `Object`. */ +var objectTypes = { + 'function': true, + 'object': true +}; + +/** Detect free variable `exports`. */ +var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; + +/** Detect free variable `module`. */ +var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); + +/** Detect free variable `self`. */ +var freeSelf = checkGlobal(objectTypes[typeof self] && self); + +/** Detect free variable `window`. */ +var freeWindow = checkGlobal(objectTypes[typeof window] && window); + +/** Detect `this` as the global object. */ +var thisGlobal = checkGlobal(objectTypes[typeof this] && this); + +/** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ +var root = freeGlobal || + ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || + freeSelf || thisGlobal || Function('return this')(); + +module.exports = root; diff --git a/www/node_modules/lodash/_setData.js b/www/node_modules/lodash/_setData.js new file mode 100644 index 0000000..8b2efca --- /dev/null +++ b/www/node_modules/lodash/_setData.js @@ -0,0 +1,41 @@ +var baseSetData = require('./_baseSetData'), + now = require('./now'); + +/** Used to detect hot functions by number of calls within a span of milliseconds. */ +var HOT_COUNT = 150, + HOT_SPAN = 16; + +/** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity function + * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ +var setData = (function() { + var count = 0, + lastCalled = 0; + + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; + } + return baseSetData(key, value); + }; +}()); + +module.exports = setData; diff --git a/www/node_modules/lodash/_setToArray.js b/www/node_modules/lodash/_setToArray.js new file mode 100644 index 0000000..6b24f30 --- /dev/null +++ b/www/node_modules/lodash/_setToArray.js @@ -0,0 +1,18 @@ +/** + * Converts `set` to an array. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the converted array. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +module.exports = setToArray; diff --git a/www/node_modules/lodash/_stackClear.js b/www/node_modules/lodash/_stackClear.js new file mode 100644 index 0000000..8255536 --- /dev/null +++ b/www/node_modules/lodash/_stackClear.js @@ -0,0 +1,12 @@ +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ +function stackClear() { + this.__data__ = { 'array': [], 'map': null }; +} + +module.exports = stackClear; diff --git a/www/node_modules/lodash/_stackDelete.js b/www/node_modules/lodash/_stackDelete.js new file mode 100644 index 0000000..7e38a13 --- /dev/null +++ b/www/node_modules/lodash/_stackDelete.js @@ -0,0 +1,19 @@ +var assocDelete = require('./_assocDelete'); + +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + var data = this.__data__, + array = data.array; + + return array ? assocDelete(array, key) : data.map['delete'](key); +} + +module.exports = stackDelete; diff --git a/www/node_modules/lodash/_stackGet.js b/www/node_modules/lodash/_stackGet.js new file mode 100644 index 0000000..20b9d9a --- /dev/null +++ b/www/node_modules/lodash/_stackGet.js @@ -0,0 +1,19 @@ +var assocGet = require('./_assocGet'); + +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + var data = this.__data__, + array = data.array; + + return array ? assocGet(array, key) : data.map.get(key); +} + +module.exports = stackGet; diff --git a/www/node_modules/lodash/_stackHas.js b/www/node_modules/lodash/_stackHas.js new file mode 100644 index 0000000..7a3b0b9 --- /dev/null +++ b/www/node_modules/lodash/_stackHas.js @@ -0,0 +1,19 @@ +var assocHas = require('./_assocHas'); + +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + var data = this.__data__, + array = data.array; + + return array ? assocHas(array, key) : data.map.has(key); +} + +module.exports = stackHas; diff --git a/www/node_modules/lodash/_stackSet.js b/www/node_modules/lodash/_stackSet.js new file mode 100644 index 0000000..0194d10 --- /dev/null +++ b/www/node_modules/lodash/_stackSet.js @@ -0,0 +1,36 @@ +var MapCache = require('./_MapCache'), + assocSet = require('./_assocSet'); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache object. + */ +function stackSet(key, value) { + var data = this.__data__, + array = data.array; + + if (array) { + if (array.length < (LARGE_ARRAY_SIZE - 1)) { + assocSet(array, key, value); + } else { + data.array = null; + data.map = new MapCache(array); + } + } + var map = data.map; + if (map) { + map.set(key, value); + } + return this; +} + +module.exports = stackSet; diff --git a/www/node_modules/lodash/_stringSize.js b/www/node_modules/lodash/_stringSize.js new file mode 100644 index 0000000..7aa9f41 --- /dev/null +++ b/www/node_modules/lodash/_stringSize.js @@ -0,0 +1,48 @@ +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + rsAstralRange + ']', + rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + if (!(string && reHasComplexSymbol.test(string))) { + return string.length; + } + var result = reComplexSymbol.lastIndex = 0; + while (reComplexSymbol.test(string)) { + result++; + } + return result; +} + +module.exports = stringSize; diff --git a/www/node_modules/lodash/_stringToArray.js b/www/node_modules/lodash/_stringToArray.js new file mode 100644 index 0000000..90986f0 --- /dev/null +++ b/www/node_modules/lodash/_stringToArray.js @@ -0,0 +1,38 @@ +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + rsAstralRange + ']', + rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ +function stringToArray(string) { + return string.match(reComplexSymbol); +} + +module.exports = stringToArray; diff --git a/www/node_modules/lodash/_stringToPath.js b/www/node_modules/lodash/_stringToPath.js new file mode 100644 index 0000000..a8fd82a --- /dev/null +++ b/www/node_modules/lodash/_stringToPath.js @@ -0,0 +1,24 @@ +var toString = require('./toString'); + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +function stringToPath(string) { + var result = []; + toString(string).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +} + +module.exports = stringToPath; diff --git a/www/node_modules/lodash/_unescapeHtmlChar.js b/www/node_modules/lodash/_unescapeHtmlChar.js new file mode 100644 index 0000000..28b3454 --- /dev/null +++ b/www/node_modules/lodash/_unescapeHtmlChar.js @@ -0,0 +1,22 @@ +/** Used to map HTML entities to characters. */ +var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' +}; + +/** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ +function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; +} + +module.exports = unescapeHtmlChar; diff --git a/www/node_modules/lodash/_wrapperClone.js b/www/node_modules/lodash/_wrapperClone.js new file mode 100644 index 0000000..7bb58a2 --- /dev/null +++ b/www/node_modules/lodash/_wrapperClone.js @@ -0,0 +1,23 @@ +var LazyWrapper = require('./_LazyWrapper'), + LodashWrapper = require('./_LodashWrapper'), + copyArray = require('./_copyArray'); + +/** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ +function wrapperClone(wrapper) { + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; +} + +module.exports = wrapperClone; diff --git a/www/node_modules/lodash/add.js b/www/node_modules/lodash/add.js new file mode 100644 index 0000000..d097850 --- /dev/null +++ b/www/node_modules/lodash/add.js @@ -0,0 +1,29 @@ +/** + * Adds two numbers. + * + * @static + * @memberOf _ + * @category Math + * @param {number} augend The first number in an addition. + * @param {number} addend The second number in an addition. + * @returns {number} Returns the total. + * @example + * + * _.add(6, 4); + * // => 10 + */ +function add(augend, addend) { + var result; + if (augend === undefined && addend === undefined) { + return 0; + } + if (augend !== undefined) { + result = augend; + } + if (addend !== undefined) { + result = result === undefined ? addend : (result + addend); + } + return result; +} + +module.exports = add; diff --git a/www/node_modules/lodash/after.js b/www/node_modules/lodash/after.js new file mode 100644 index 0000000..41b0146 --- /dev/null +++ b/www/node_modules/lodash/after.js @@ -0,0 +1,41 @@ +var toInteger = require('./toInteger'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ +function after(n, func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; +} + +module.exports = after; diff --git a/www/node_modules/lodash/array.js b/www/node_modules/lodash/array.js new file mode 100644 index 0000000..bfded5c --- /dev/null +++ b/www/node_modules/lodash/array.js @@ -0,0 +1,65 @@ +module.exports = { + 'chunk': require('./chunk'), + 'compact': require('./compact'), + 'concat': require('./concat'), + 'difference': require('./difference'), + 'differenceBy': require('./differenceBy'), + 'differenceWith': require('./differenceWith'), + 'drop': require('./drop'), + 'dropRight': require('./dropRight'), + 'dropRightWhile': require('./dropRightWhile'), + 'dropWhile': require('./dropWhile'), + 'fill': require('./fill'), + 'findIndex': require('./findIndex'), + 'findLastIndex': require('./findLastIndex'), + 'flatten': require('./flatten'), + 'flattenDeep': require('./flattenDeep'), + 'flattenDepth': require('./flattenDepth'), + 'fromPairs': require('./fromPairs'), + 'head': require('./head'), + 'indexOf': require('./indexOf'), + 'initial': require('./initial'), + 'intersection': require('./intersection'), + 'intersectionBy': require('./intersectionBy'), + 'intersectionWith': require('./intersectionWith'), + 'join': require('./join'), + 'last': require('./last'), + 'lastIndexOf': require('./lastIndexOf'), + 'pull': require('./pull'), + 'pullAll': require('./pullAll'), + 'pullAllBy': require('./pullAllBy'), + 'pullAllWith': require('./pullAllWith'), + 'pullAt': require('./pullAt'), + 'remove': require('./remove'), + 'reverse': require('./reverse'), + 'slice': require('./slice'), + 'sortedIndex': require('./sortedIndex'), + 'sortedIndexBy': require('./sortedIndexBy'), + 'sortedIndexOf': require('./sortedIndexOf'), + 'sortedLastIndex': require('./sortedLastIndex'), + 'sortedLastIndexBy': require('./sortedLastIndexBy'), + 'sortedLastIndexOf': require('./sortedLastIndexOf'), + 'sortedUniq': require('./sortedUniq'), + 'sortedUniqBy': require('./sortedUniqBy'), + 'tail': require('./tail'), + 'take': require('./take'), + 'takeRight': require('./takeRight'), + 'takeRightWhile': require('./takeRightWhile'), + 'takeWhile': require('./takeWhile'), + 'union': require('./union'), + 'unionBy': require('./unionBy'), + 'unionWith': require('./unionWith'), + 'uniq': require('./uniq'), + 'uniqBy': require('./uniqBy'), + 'uniqWith': require('./uniqWith'), + 'unzip': require('./unzip'), + 'unzipWith': require('./unzipWith'), + 'without': require('./without'), + 'xor': require('./xor'), + 'xorBy': require('./xorBy'), + 'xorWith': require('./xorWith'), + 'zip': require('./zip'), + 'zipObject': require('./zipObject'), + 'zipObjectDeep': require('./zipObjectDeep'), + 'zipWith': require('./zipWith') +}; diff --git a/www/node_modules/lodash/ary.js b/www/node_modules/lodash/ary.js new file mode 100644 index 0000000..b3906ac --- /dev/null +++ b/www/node_modules/lodash/ary.js @@ -0,0 +1,28 @@ +var createWrapper = require('./_createWrapper'); + +/** Used to compose bitmasks for wrapper metadata. */ +var ARY_FLAG = 128; + +/** + * Creates a function that accepts up to `n` arguments, ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ +function ary(func, n, guard) { + n = guard ? undefined : n; + n = (func && n == null) ? func.length : n; + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); +} + +module.exports = ary; diff --git a/www/node_modules/lodash/assign.js b/www/node_modules/lodash/assign.js new file mode 100644 index 0000000..123ff49 --- /dev/null +++ b/www/node_modules/lodash/assign.js @@ -0,0 +1,62 @@ +var assignValue = require('./_assignValue'), + copyObject = require('./_copyObject'), + createAssigner = require('./_createAssigner'), + isArrayLike = require('./isArrayLike'), + isPrototype = require('./_isPrototype'), + keys = require('./keys'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ +var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); + +/** + * Assigns own enumerable properties of source objects to the destination + * object. Source objects are applied from left to right. Subsequent sources + * overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.c = 3; + * } + * + * function Bar() { + * this.e = 5; + * } + * + * Foo.prototype.d = 4; + * Bar.prototype.f = 6; + * + * _.assign({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3, 'e': 5 } + */ +var assign = createAssigner(function(object, source) { + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } +}); + +module.exports = assign; diff --git a/www/node_modules/lodash/assignIn.js b/www/node_modules/lodash/assignIn.js new file mode 100644 index 0000000..0315ffe --- /dev/null +++ b/www/node_modules/lodash/assignIn.js @@ -0,0 +1,56 @@ +var assignValue = require('./_assignValue'), + copyObject = require('./_copyObject'), + createAssigner = require('./_createAssigner'), + isArrayLike = require('./isArrayLike'), + isPrototype = require('./_isPrototype'), + keysIn = require('./keysIn'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ +var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); + +/** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * function Bar() { + * this.d = 4; + * } + * + * Foo.prototype.c = 3; + * Bar.prototype.e = 5; + * + * _.assignIn({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 } + */ +var assignIn = createAssigner(function(object, source) { + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keysIn(source), object); + return; + } + for (var key in source) { + assignValue(object, key, source[key]); + } +}); + +module.exports = assignIn; diff --git a/www/node_modules/lodash/assignInWith.js b/www/node_modules/lodash/assignInWith.js new file mode 100644 index 0000000..da73ef7 --- /dev/null +++ b/www/node_modules/lodash/assignInWith.js @@ -0,0 +1,36 @@ +var copyObjectWith = require('./_copyObjectWith'), + createAssigner = require('./_createAssigner'), + keysIn = require('./keysIn'); + +/** + * This method is like `_.assignIn` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keysIn(source), object, customizer); +}); + +module.exports = assignInWith; diff --git a/www/node_modules/lodash/assignWith.js b/www/node_modules/lodash/assignWith.js new file mode 100644 index 0000000..eb7915b --- /dev/null +++ b/www/node_modules/lodash/assignWith.js @@ -0,0 +1,35 @@ +var copyObjectWith = require('./_copyObjectWith'), + createAssigner = require('./_createAssigner'), + keys = require('./keys'); + +/** + * This method is like `_.assign` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keys(source), object, customizer); +}); + +module.exports = assignWith; diff --git a/www/node_modules/lodash/at.js b/www/node_modules/lodash/at.js new file mode 100644 index 0000000..cb35a54 --- /dev/null +++ b/www/node_modules/lodash/at.js @@ -0,0 +1,29 @@ +var baseAt = require('./_baseAt'), + baseFlatten = require('./_baseFlatten'), + rest = require('./rest'); + +/** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths of elements to pick, + * specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + * + * _.at(['a', 'b', 'c'], 0, 2); + * // => ['a', 'c'] + */ +var at = rest(function(object, paths) { + return baseAt(object, baseFlatten(paths, 1)); +}); + +module.exports = at; diff --git a/www/node_modules/lodash/attempt.js b/www/node_modules/lodash/attempt.js new file mode 100644 index 0000000..52bc3e3 --- /dev/null +++ b/www/node_modules/lodash/attempt.js @@ -0,0 +1,33 @@ +var apply = require('./_apply'), + isError = require('./isError'), + rest = require('./rest'); + +/** + * Attempts to invoke `func`, returning either the result or the caught error + * object. Any additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Util + * @param {Function} func The function to attempt. + * @returns {*} Returns the `func` result or error object. + * @example + * + * // Avoid throwing errors for invalid selectors. + * var elements = _.attempt(function(selector) { + * return document.querySelectorAll(selector); + * }, '>_>'); + * + * if (_.isError(elements)) { + * elements = []; + * } + */ +var attempt = rest(function(func, args) { + try { + return apply(func, undefined, args); + } catch (e) { + return isError(e) ? e : new Error(e); + } +}); + +module.exports = attempt; diff --git a/www/node_modules/lodash/before.js b/www/node_modules/lodash/before.js new file mode 100644 index 0000000..47148b1 --- /dev/null +++ b/www/node_modules/lodash/before.js @@ -0,0 +1,39 @@ +var toInteger = require('./toInteger'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ +function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; +} + +module.exports = before; diff --git a/www/node_modules/lodash/bind.js b/www/node_modules/lodash/bind.js new file mode 100644 index 0000000..a594063 --- /dev/null +++ b/www/node_modules/lodash/bind.js @@ -0,0 +1,57 @@ +var createWrapper = require('./_createWrapper'), + getPlaceholder = require('./_getPlaceholder'), + replaceHolders = require('./_replaceHolders'), + rest = require('./rest'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ +var bind = rest(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getPlaceholder(bind)); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); +}); + +// Assign default placeholders. +bind.placeholder = {}; + +module.exports = bind; diff --git a/www/node_modules/lodash/bindAll.js b/www/node_modules/lodash/bindAll.js new file mode 100644 index 0000000..ddbc2ff --- /dev/null +++ b/www/node_modules/lodash/bindAll.js @@ -0,0 +1,39 @@ +var arrayEach = require('./_arrayEach'), + baseFlatten = require('./_baseFlatten'), + bind = require('./bind'), + rest = require('./rest'); + +/** + * Binds methods of an object to the object itself, overwriting the existing + * method. + * + * **Note:** This method doesn't set the "length" property of bound functions. + * + * @static + * @memberOf _ + * @category Util + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} methodNames The object method names to bind, + * specified individually or in arrays. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view, 'onClick'); + * jQuery(element).on('click', view.onClick); + * // => logs 'clicked docs' when clicked + */ +var bindAll = rest(function(object, methodNames) { + arrayEach(baseFlatten(methodNames, 1), function(key) { + object[key] = bind(object[key], object); + }); + return object; +}); + +module.exports = bindAll; diff --git a/www/node_modules/lodash/bindKey.js b/www/node_modules/lodash/bindKey.js new file mode 100644 index 0000000..5f5c982 --- /dev/null +++ b/www/node_modules/lodash/bindKey.js @@ -0,0 +1,67 @@ +var createWrapper = require('./_createWrapper'), + getPlaceholder = require('./_getPlaceholder'), + replaceHolders = require('./_replaceHolders'), + rest = require('./rest'); + +/** Used to compose bitmasks for wrapper metadata. */ +var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + PARTIAL_FLAG = 32; + +/** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to invoke the method on. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // Bound with placeholders. + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ +var bindKey = rest(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getPlaceholder(bindKey)); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); +}); + +// Assign default placeholders. +bindKey.placeholder = {}; + +module.exports = bindKey; diff --git a/www/node_modules/lodash/camelCase.js b/www/node_modules/lodash/camelCase.js new file mode 100644 index 0000000..00239e3 --- /dev/null +++ b/www/node_modules/lodash/camelCase.js @@ -0,0 +1,28 @@ +var capitalize = require('./capitalize'), + createCompounder = require('./_createCompounder'); + +/** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar'); + * // => 'fooBar' + * + * _.camelCase('__foo_bar__'); + * // => 'fooBar' + */ +var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); +}); + +module.exports = camelCase; diff --git a/www/node_modules/lodash/capitalize.js b/www/node_modules/lodash/capitalize.js new file mode 100644 index 0000000..4daec03 --- /dev/null +++ b/www/node_modules/lodash/capitalize.js @@ -0,0 +1,22 @@ +var toString = require('./toString'), + upperFirst = require('./upperFirst'); + +/** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ +function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); +} + +module.exports = capitalize; diff --git a/www/node_modules/lodash/castArray.js b/www/node_modules/lodash/castArray.js new file mode 100644 index 0000000..4ea96fc --- /dev/null +++ b/www/node_modules/lodash/castArray.js @@ -0,0 +1,43 @@ +var isArray = require('./isArray'); + +/** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ +function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; +} + +module.exports = castArray; diff --git a/www/node_modules/lodash/ceil.js b/www/node_modules/lodash/ceil.js new file mode 100644 index 0000000..ecf2f12 --- /dev/null +++ b/www/node_modules/lodash/ceil.js @@ -0,0 +1,25 @@ +var createRound = require('./_createRound'); + +/** + * Computes `number` rounded up to `precision`. + * + * @static + * @memberOf _ + * @category Math + * @param {number} number The number to round up. + * @param {number} [precision=0] The precision to round up to. + * @returns {number} Returns the rounded up number. + * @example + * + * _.ceil(4.006); + * // => 5 + * + * _.ceil(6.004, 2); + * // => 6.01 + * + * _.ceil(6040, -2); + * // => 6100 + */ +var ceil = createRound('ceil'); + +module.exports = ceil; diff --git a/www/node_modules/lodash/chain.js b/www/node_modules/lodash/chain.js new file mode 100644 index 0000000..3300933 --- /dev/null +++ b/www/node_modules/lodash/chain.js @@ -0,0 +1,36 @@ +var lodash = require('./wrapperLodash'); + +/** + * Creates a `lodash` object that wraps `value` with explicit method chaining enabled. + * The result of such method chaining must be unwrapped with `_#value`. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ +function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; +} + +module.exports = chain; diff --git a/www/node_modules/lodash/chunk.js b/www/node_modules/lodash/chunk.js new file mode 100644 index 0000000..429a371 --- /dev/null +++ b/www/node_modules/lodash/chunk.js @@ -0,0 +1,44 @@ +var baseSlice = require('./_baseSlice'), + toInteger = require('./toInteger'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * Creates an array of elements split into groups the length of `size`. + * If `array` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=0] The length of each chunk. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ +function chunk(array, size) { + size = nativeMax(toInteger(size), 0); + + var length = array ? array.length : 0; + if (!length || size < 1) { + return []; + } + var index = 0, + resIndex = 0, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[resIndex++] = baseSlice(array, index, (index += size)); + } + return result; +} + +module.exports = chunk; diff --git a/www/node_modules/lodash/clamp.js b/www/node_modules/lodash/clamp.js new file mode 100644 index 0000000..9e186d8 --- /dev/null +++ b/www/node_modules/lodash/clamp.js @@ -0,0 +1,38 @@ +var baseClamp = require('./_baseClamp'), + toNumber = require('./toNumber'); + +/** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ +function clamp(number, lower, upper) { + if (upper === undefined) { + upper = lower; + lower = undefined; + } + if (upper !== undefined) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); +} + +module.exports = clamp; diff --git a/www/node_modules/lodash/clone.js b/www/node_modules/lodash/clone.js new file mode 100644 index 0000000..fb83952 --- /dev/null +++ b/www/node_modules/lodash/clone.js @@ -0,0 +1,31 @@ +var baseClone = require('./_baseClone'); + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return baseClone(value, false, true); +} + +module.exports = clone; diff --git a/www/node_modules/lodash/cloneDeep.js b/www/node_modules/lodash/cloneDeep.js new file mode 100644 index 0000000..b8e95d3 --- /dev/null +++ b/www/node_modules/lodash/cloneDeep.js @@ -0,0 +1,23 @@ +var baseClone = require('./_baseClone'); + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return baseClone(value, true, true); +} + +module.exports = cloneDeep; diff --git a/www/node_modules/lodash/cloneDeepWith.js b/www/node_modules/lodash/cloneDeepWith.js new file mode 100644 index 0000000..4d04b22 --- /dev/null +++ b/www/node_modules/lodash/cloneDeepWith.js @@ -0,0 +1,33 @@ +var baseClone = require('./_baseClone'); + +/** + * This method is like `_.cloneWith` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * } + * + * var el = _.cloneDeepWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 20 + */ +function cloneDeepWith(value, customizer) { + return baseClone(value, true, true, customizer); +} + +module.exports = cloneDeepWith; diff --git a/www/node_modules/lodash/cloneWith.js b/www/node_modules/lodash/cloneWith.js new file mode 100644 index 0000000..e689231 --- /dev/null +++ b/www/node_modules/lodash/cloneWith.js @@ -0,0 +1,36 @@ +var baseClone = require('./_baseClone'); + +/** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * } + * + * var el = _.cloneWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 0 + */ +function cloneWith(value, customizer) { + return baseClone(value, false, true, customizer); +} + +module.exports = cloneWith; diff --git a/www/node_modules/lodash/collection.js b/www/node_modules/lodash/collection.js new file mode 100644 index 0000000..6d37b3f --- /dev/null +++ b/www/node_modules/lodash/collection.js @@ -0,0 +1,29 @@ +module.exports = { + 'at': require('./at'), + 'countBy': require('./countBy'), + 'each': require('./each'), + 'eachRight': require('./eachRight'), + 'every': require('./every'), + 'filter': require('./filter'), + 'find': require('./find'), + 'findLast': require('./findLast'), + 'flatMap': require('./flatMap'), + 'forEach': require('./forEach'), + 'forEachRight': require('./forEachRight'), + 'groupBy': require('./groupBy'), + 'includes': require('./includes'), + 'invokeMap': require('./invokeMap'), + 'keyBy': require('./keyBy'), + 'map': require('./map'), + 'orderBy': require('./orderBy'), + 'partition': require('./partition'), + 'reduce': require('./reduce'), + 'reduceRight': require('./reduceRight'), + 'reject': require('./reject'), + 'sample': require('./sample'), + 'sampleSize': require('./sampleSize'), + 'shuffle': require('./shuffle'), + 'size': require('./size'), + 'some': require('./some'), + 'sortBy': require('./sortBy') +}; diff --git a/www/node_modules/lodash/commit.js b/www/node_modules/lodash/commit.js new file mode 100644 index 0000000..1f87f50 --- /dev/null +++ b/www/node_modules/lodash/commit.js @@ -0,0 +1,32 @@ +var LodashWrapper = require('./_LodashWrapper'); + +/** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ +function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); +} + +module.exports = wrapperCommit; diff --git a/www/node_modules/lodash/compact.js b/www/node_modules/lodash/compact.js new file mode 100644 index 0000000..e872c20 --- /dev/null +++ b/www/node_modules/lodash/compact.js @@ -0,0 +1,30 @@ +/** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ +function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[resIndex++] = value; + } + } + return result; +} + +module.exports = compact; diff --git a/www/node_modules/lodash/concat.js b/www/node_modules/lodash/concat.js new file mode 100644 index 0000000..1d2b846 --- /dev/null +++ b/www/node_modules/lodash/concat.js @@ -0,0 +1,35 @@ +var arrayConcat = require('./_arrayConcat'), + baseFlatten = require('./_baseFlatten'), + isArray = require('./isArray'), + rest = require('./rest'); + +/** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ +var concat = rest(function(array, values) { + if (!isArray(array)) { + array = array == null ? [] : [Object(array)]; + } + values = baseFlatten(values, 1); + return arrayConcat(array, values); +}); + +module.exports = concat; diff --git a/www/node_modules/lodash/cond.js b/www/node_modules/lodash/cond.js new file mode 100644 index 0000000..593ac9e --- /dev/null +++ b/www/node_modules/lodash/cond.js @@ -0,0 +1,58 @@ +var apply = require('./_apply'), + arrayMap = require('./_arrayMap'), + baseIteratee = require('./_baseIteratee'), + rest = require('./rest'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** + * Creates a function that iterates over `pairs` invoking the corresponding + * function of the first predicate to return truthy. The predicate-function + * pairs are invoked with the `this` binding and arguments of the created + * function. + * + * @static + * @memberOf _ + * @category Util + * @param {Array} pairs The predicate-function pairs. + * @returns {Function} Returns the new function. + * @example + * + * var func = _.cond([ + * [_.matches({ 'a': 1 }), _.constant('matches A')], + * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')], + * [_.constant(true), _.constant('no match')] + * ]); + * + * func({ 'a': 1, 'b': 2 }); + * // => 'matches A' + * + * func({ 'a': 0, 'b': 1 }); + * // => 'matches B' + * + * func({ 'a': '1', 'b': '2' }); + * // => 'no match' + */ +function cond(pairs) { + var length = pairs ? pairs.length : 0; + + pairs = !length ? [] : arrayMap(pairs, function(pair) { + if (typeof pair[1] != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return [baseIteratee(pair[0]), pair[1]]; + }); + + return rest(function(args) { + var index = -1; + while (++index < length) { + var pair = pairs[index]; + if (apply(pair[0], this, args)) { + return apply(pair[1], this, args); + } + } + }); +} + +module.exports = cond; diff --git a/www/node_modules/lodash/conforms.js b/www/node_modules/lodash/conforms.js new file mode 100644 index 0000000..2bfeca2 --- /dev/null +++ b/www/node_modules/lodash/conforms.js @@ -0,0 +1,28 @@ +var baseClone = require('./_baseClone'), + baseConforms = require('./_baseConforms'); + +/** + * Creates a function that invokes the predicate properties of `source` with + * the corresponding property values of a given object, returning `true` if + * all predicates return truthy, else `false`. + * + * @static + * @memberOf _ + * @category Util + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new function. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) })); + * // => [{ 'user': 'fred', 'age': 40 }] + */ +function conforms(source) { + return baseConforms(baseClone(source, true)); +} + +module.exports = conforms; diff --git a/www/node_modules/lodash/constant.js b/www/node_modules/lodash/constant.js new file mode 100644 index 0000000..5844804 --- /dev/null +++ b/www/node_modules/lodash/constant.js @@ -0,0 +1,23 @@ +/** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @category Util + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new function. + * @example + * + * var object = { 'user': 'fred' }; + * var getter = _.constant(object); + * + * getter() === object; + * // => true + */ +function constant(value) { + return function() { + return value; + }; +} + +module.exports = constant; diff --git a/www/node_modules/lodash/core.js b/www/node_modules/lodash/core.js new file mode 100644 index 0000000..d8ba4fd --- /dev/null +++ b/www/node_modules/lodash/core.js @@ -0,0 +1,3826 @@ +/** + * @license + * lodash 4.6.1 (Custom Build) + * Build: `lodash core -o ./dist/lodash.core.js` + * Copyright 2012-2016 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '4.6.1'; + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + PARTIAL_FLAG = 32; + + /** Used to compose bitmasks for comparison styles. */ + var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + stringTag = '[object String]'; + + /** Used to match HTML entities and HTML characters. */ + var reUnescapedHtml = /[&<>"'`]/g, + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Detect free variable `exports`. */ + var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; + + /** Detect free variable `module`. */ + var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = (freeModule && freeModule.exports === freeExports) + ? freeExports + : undefined; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); + + /** Detect free variable `self`. */ + var freeSelf = checkGlobal(objectTypes[typeof self] && self); + + /** Detect free variable `window`. */ + var freeWindow = checkGlobal(objectTypes[typeof window] && window); + + /** Detect `this` as the global object. */ + var thisGlobal = checkGlobal(objectTypes[typeof this] && this); + + /** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || + ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || + freeSelf || thisGlobal || Function('return this')(); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a new array concatenating `array` with `other`. + * + * @private + * @param {Array} array The first array to concatenate. + * @param {Array} other The second array to concatenate. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + return arrayPush(copyArray(array), values); + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? current === current + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; + } + + /** + * The base implementation of methods like `_.find` and `_.findKey`, without + * support for iteratee shorthands, which iterates over `collection` using + * `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + return baseMap(props, function(key) { + return object[key]; + }); + } + + /** + * Checks if `value` is a global object. + * + * @private + * @param {*} value The value to check. + * @returns {null|Object} Returns `value` if it's a global object, else `null`. + */ + function checkGlobal(value) { + return (value && value.Object === Object) ? value : null; + } + + /** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function compareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; + } + + /** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ + function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Built-in value references. */ + var Reflect = root.Reflect, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + enumerate = Reflect ? Reflect.enumerate : undefined, + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeIsFinite = root.isFinite, + nativeKeys = Object.keys, + nativeMax = Math.max; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit method + * chaining. Methods that operate on and return arrays, collections, and + * functions can be chained together. Methods that retrieve a single value or + * may return a primitive value will automatically end the chain sequence and + * return the unwrapped value. Otherwise, the value must be unwrapped with + * `_#value`. + * + * Explicit chaining, which must be unwrapped with `_#value` in all cases, + * may be enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization to merge iteratee calls; this avoids the creation + * of intermediate arrays and can greatly reduce the number of iteratee executions. + * Sections of a chain sequence qualify for shortcut fusion if the section is + * applied to an array of at least two hundred elements and any iteratees + * accept only one argument. The heuristic for whether a section qualifies + * for shortcut fusion is subject to change. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatten`, `flattenDeep`, `flattenDepth`, `flip`, `flow`, `flowRight`, + * `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`, `intersection`, + * `intersectionBy`, `intersectionWith`, `invert`, `invertBy`, `invokeMap`, + * `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, + * `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`, + * `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, + * `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`, + * `partition`, `pick`, `pickBy`, `plant`, `property`, `propertyOf`, `pull`, + * `pullAll`, `pullAllBy`, `pullAllWith`, `pullAt`, `push`, `range`, + * `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`, + * `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, + * `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, + * `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, + * `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `update`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, + * `zipObjectDeep`, and `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `each`, `eachRight`, + * `endsWith`, `eq`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `first`, `floor`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`, `includes`, + * `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`, `isArrayBuffer`, + * `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`, `isDate`, + * `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`, `isFinite`, + * `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`, `isMatchWith`, + * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`, + * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isSet`, `isString`, + * `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, + * `maxBy`, `mean`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toInteger`, `toJSON`, `toLength`, `toLower`, + * `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, `trimEnd`, + * `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, `upperFirst`, + * `value`, and `words` + * + * @name _ + * @constructor + * @category Seq + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2, 3]); + * + * // Returns an unwrapped value. + * wrapped.reduce(_.add); + * // => 6 + * + * // Returns a wrapped value. + * var squares = wrapped.map(square); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + */ + function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + } + + /*------------------------------------------------------------------------*/ + + /** + * Used by `_.defaults` to customize its `_.assignIn` use. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. + */ + function assignInDefaults(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastFunction(value) { + return typeof value == 'function' ? value : identity; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `_.delay` and `_.defer` which accepts an array + * of `func` arguments. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments to provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, depth, isStrict, result) { + result || (result = []); + + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + if (depth > 0 && isArrayLikeObject(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ + function baseFunctions(object, props) { + return baseFilter(props, function(key) { + return isFunction(object[key]); + }); + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @param {boolean} [bitmask] The bitmask of comparison flags. + * The bitmask may be composed of the following flags: + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, customizer, bitmask, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparisons. + * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objectToString.call(object); + objTag = objTag == argsTag ? objectTag : objTag; + } + if (!othIsArr) { + othTag = objectToString.call(other); + othTag = othTag == argsTag ? objectTag : othTag; + } + var objIsObj = objTag == objectTag && !isHostObject(object), + othIsObj = othTag == objectTag && !isHostObject(other), + isSameTag = objTag == othTag; + + stack || (stack = []); + var stacked = find(stack, function(entry) { + return entry[0] === object; + }); + if (stacked && stacked[1]) { + return stacked[1] == other; + } + stack.push([object, other]); + if (isSameTag && !objIsObj) { + var result = (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, equalFunc, customizer, bitmask, stack) + : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack); + stack.pop(); + return result; + } + if (!(bitmask & PARTIAL_COMPARE_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var result = equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack); + stack.pop(); + return result; + } + } + if (!isSameTag) { + return false; + } + var result = equalObjects(object, other, equalFunc, customizer, bitmask, stack); + stack.pop(); + return result; + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(func) { + var type = typeof func; + if (type == 'function') { + return func; + } + return func == null + ? identity + : (type == 'object' ? baseMatches : baseProperty)(func); + } + + /** + * The base implementation of `_.keys` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + return nativeKeys(Object(object)); + } + + /** + * The base implementation of `_.keysIn` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + object = object == null ? object : Object(object); + + var result = []; + for (var key in object) { + result.push(key); + } + return result; + } + + // Fallback for IE < 9 with es6-shim. + if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) { + baseKeysIn = function(object) { + return iteratorToArray(enumerate(object)); + }; + } + + /** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var props = keys(source); + return function(object) { + var length = props.length; + if (object == null) { + return !length; + } + object = Object(object); + while (length--) { + var key = props[length]; + if (!(key in object && + baseIsEqual(source[key], object[key], undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG) + )) { + return false; + } + } + return true; + }; + } + + /** + * The base implementation of `_.pick` without support for individual + * property names. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function basePick(object, props) { + object = Object(object); + return reduce(props, function(result, key) { + if (key in object) { + result[key] = object[key]; + } + return result; + }, {}); + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source) { + return baseSlice(source, 0, source.length); + } + + /** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + return reduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + var copyObject = copyObjectWith; + + /** + * This function is like `copyObject` except that it accepts a function to + * customize copied values. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObjectWith(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : source[key]; + + assignValue(object, key, newValue); + } + return object; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return rest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined; + + customizer = typeof customizer == 'function' + ? (length--, customizer) + : undefined; + + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for methods like `_.forIn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtorWrapper(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new wrapped function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return fn.apply(isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { + var index = -1, + isPartial = bitmask & PARTIAL_COMPARE_FLAG, + isUnordered = bitmask & UNORDERED_COMPARE_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + var result = true; + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + var compared; + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isUnordered) { + if (!baseSome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack); + })) { + result = false; + break; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { + result = false; + break; + } + } + return result; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) { + switch (tag) { + + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) ? other != +other : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { + var isPartial = bitmask & PARTIAL_COMPARE_FLAG, + objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + var result = true; + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + var compared; + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + return result; + } + + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Creates an array of index keys for `object` values of arrays, + * `arguments` objects, and strings, otherwise `null` is returned. + * + * @private + * @param {Object} object The object to query. + * @returns {Array|null} Returns index keys, else `null`. + */ + function indexKeys(object) { + var length = object ? object.length : undefined; + if (isLength(length) && + (isArray(object) || isString(object) || isArguments(object))) { + return baseTimes(length, String); + } + return null; + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + return baseFilter(array, Boolean); + } + + /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var concat = rest(function(array, values) { + if (!isArray(array)) { + array = array == null ? [] : [Object(array)]; + } + values = baseFlatten(values, 1); + return arrayConcat(array, values); + }); + + /** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ + function flatten(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, 1) : []; + } + + /** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, INFINITY) : []; + } + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ + function head(array) { + return array ? array[0] : undefined; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else { + fromIndex = 0; + } + var index = (fromIndex || 0) - 1, + isReflexive = value === value; + + while (++index < length) { + var other = array[index]; + if ((isReflexive ? other === value : other !== other)) { + return index; + } + } + return -1; + } + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice) + * to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array ? array.length : 0; + start = start == null ? 0 : +start; + end = end === undefined ? length : +end; + return length ? baseSlice(array, start, end) : []; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps `value` with explicit method chaining enabled. + * The result of such method chaining must be unwrapped with `_#value`. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor + * is invoked with one argument; (value). The purpose of this method is to + * "tap into" a method chain in order to modify intermediate results. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * // Mutate input array. + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * The purpose of this method is to "pass thru" values replacing intermediate + * results in a method chain. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor) { + return interceptor(value); + } + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // A sequence without explicit chaining. + * _(users).head(); + * // => { 'user': 'barney', 'age': 36 } + * + * // A sequence with explicit chaining. + * _(users) + * .chain() + * .head() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias toJSON, valueOf + * @category Seq + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, guard) { + predicate = guard ? undefined : predicate; + return baseEvery(collection, baseIteratee(predicate)); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + */ + function filter(collection, predicate) { + return baseFilter(collection, baseIteratee(predicate)); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ + function find(collection, predicate) { + return baseFind(collection, baseIteratee(predicate), baseEach); + } + + /** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn` + * for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(value) { + * console.log(value); + * }); + * // => logs `1` then `2` + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' then 'b' (iteration order is not guaranteed) + */ + function forEach(collection, iteratee) { + return baseEach(collection, baseCastFunction(iteratee)); + } + + /** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`, + * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`, + * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`, + * and `words` + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee) { + return baseMap(collection, baseIteratee(iteratee)); + } + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ + function reduce(collection, iteratee, accumulator) { + return baseReduce(collection, baseIteratee(iteratee), accumulator, arguments.length < 3, baseEach); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + if (collection == null) { + return 0; + } + collection = isArrayLike(collection) ? collection : keys(collection); + return collection.length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.some(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, guard) { + predicate = guard ? undefined : predicate; + return baseSome(collection, baseIteratee(predicate)); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]] + * The iteratees to sort by, specified individually or in arrays. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, function(o) { return o.user; }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.sortBy(users, 'user', function(o) { + * return Math.floor(o.age / 10); + * }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + function sortBy(collection, iteratee) { + var index = 0; + iteratee = baseIteratee(iteratee); + + return baseMap(baseMap(collection, function(value, key, collection) { + return { 'value': value, 'index': index++, 'criteria': iteratee(value, key, collection) }; + }).sort(function(object, other) { + return compareAscending(object.criteria, other.criteria) || (object.index - other.index); + }), baseProperty('value')); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = rest(function(func, thisArg, partials) { + return createPartialWrapper(func, BIND_FLAG | PARTIAL_FLAG, thisArg, partials); + }); + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => logs 'deferred' after one or more milliseconds + */ + var defer = rest(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ + var delay = rest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); + }); + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.rest(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function rest(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = array; + return func.apply(this, otherArgs); + }; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone(value) { + if (!isObject(value)) { + return value; + } + return isArray(value) ? copyArray(value) : copyObject(value, keys(value)); + } + + /** + * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + function gt(value, other) { + return value > other; + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @type {Function} + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && objectToString.call(value) == boolTag); + } + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + function isDate(value) { + return isObjectLike(value) && objectToString.call(value) == dateTag; + } + + /** + * Checks if `value` is an empty collection or object. A value is considered + * empty if it's an `arguments` object, array, string, or jQuery-like collection + * with a length of `0` or has no own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (isArrayLike(value) && + (isArray(value) || isString(value) || + isFunction(value.splice) || isArguments(value))) { + return !value.length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are **not** supported. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MAX_VALUE); + * // => true + * + * _.isFinite(3.14); + * // => true + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8 which returns 'object' for typed array and weak map constructors, + // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && objectToString.call(value) == numberTag); + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + function isRegExp(value) { + return isObject(value) && objectToString.call(value) == regexpTag; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + function lt(value, other) { + return value < other; + } + + /** + * Converts `value` to an array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!isArrayLike(value)) { + return values(value); + } + return value.length ? copyArray(value) : []; + } + + /** + * Converts `value` to an integer. + * + * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3'); + * // => 3 + */ + var toInteger = Number; + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3); + * // => 3 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3'); + * // => 3 + */ + var toNumber = Number; + + /** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to process. + * @returns {string} Returns the string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + if (typeof value == 'string') { + return value; + } + return value == null ? '' : (value + ''); + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source objects to the destination + * object. Source objects are applied from left to right. Subsequent sources + * overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.c = 3; + * } + * + * function Bar() { + * this.e = 5; + * } + * + * Foo.prototype.d = 4; + * Bar.prototype.f = 6; + * + * _.assign({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3, 'e': 5 } + */ + var assign = createAssigner(function(object, source) { + copyObject(source, keys(source), object); + }); + + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * function Bar() { + * this.d = 4; + * } + * + * Foo.prototype.c = 3; + * Bar.prototype.e = 5; + * + * _.assignIn({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 } + */ + var assignIn = createAssigner(function(object, source) { + copyObject(source, keysIn(source), object); + }); + + /** + * This method is like `_.assignIn` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keysIn(source), object, customizer); + }); + + /** + * Creates an object that inherits from the `prototype` object. If a `properties` + * object is given its own enumerable properties are assigned to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? assign(result, properties) : result; + } + + /** + * Assigns own and inherited enumerable properties of source objects to the + * destination object for all destination properties that resolve to `undefined`. + * Source objects are applied from left to right. Once a property is set, + * additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var defaults = rest(function(args) { + args.push(undefined, assignInDefaults); + return assignInWith.apply(undefined, args); + }); + + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + function has(object, path) { + return object != null && hasOwnProperty.call(object, path); + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + var isProto = isPrototype(object); + if (!(isProto || isArrayLike(object))) { + return baseKeys(object); + } + var indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + for (var key in object) { + if (hasOwnProperty.call(object, key) && + !(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(isProto && key == 'constructor')) { + result.push(key); + } + } + return result; + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + var index = -1, + isProto = isPrototype(object), + props = baseKeysIn(object), + propsLength = props.length, + indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + while (++index < propsLength) { + var key = props[index]; + if (!(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [props] The property names to pick, specified + * individually or in arrays. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + var pick = rest(function(object, props) { + return object == null ? {} : basePick(object, baseFlatten(props, 1)); + }); + + /** + * This method is like `_.get` except that if the resolved value is a function + * it's invoked with the `this` binding of its parent object and its result + * is returned. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + var value = object == null ? undefined : object[path]; + if (value === undefined) { + value = defaultValue; + } + return isFunction(value) ? value.call(object) : value; + } + + /** + * Creates an array of the own enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object ? baseValues(object, keys(object)) : []; + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in IE < 9, they can break out of + * attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /*------------------------------------------------------------------------*/ + + /** + * This method returns the first argument given to it. + * + * @static + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'user': 'fred' }; + * + * _.identity(object) === object; + * // => true + */ + function identity(value) { + return value; + } + + /** + * Creates a function that invokes `func` with the arguments of the created + * function. If `func` is a property name the created callback returns the + * property value for a given element. If `func` is an object the created + * callback returns `true` for elements that contain the equivalent object + * properties, otherwise it returns `false`. + * + * @static + * @memberOf _ + * @category Util + * @param {*} [func=_.identity] The value to convert to a callback. + * @returns {Function} Returns the callback. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // Create custom iteratee shorthands. + * _.iteratee = _.wrap(_.iteratee, function(callback, func) { + * var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func); + * return !p ? callback(func) : function(object) { + * return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]); + * }; + * }); + * + * _.filter(users, 'age > 36'); + * // => [{ 'user': 'fred', 'age': 40 }] + */ + var iteratee = baseIteratee; + + /** + * Creates a function that performs a partial deep comparison between a given + * object and `source`, returning `true` if the given object has equivalent + * property values, else `false`. The created function is equivalent to + * `_.isMatch` with a `source` partially applied. + * + * **Note:** This method supports comparing the same values as `_.isEqual`. + * + * @static + * @memberOf _ + * @category Util + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, _.matches({ 'age': 40, 'active': false })); + * // => [{ 'user': 'fred', 'age': 40, 'active': false }] + */ + function matches(source) { + return baseMatches(assign({}, source)); + } + + /** + * Adds all own enumerable function properties of a source object to the + * destination object. If `object` is a function then methods are added to + * its prototype as well. + * + * **Note:** Use `_.runInContext` to create a pristine `lodash` function to + * avoid conflicts caused by modifying the original. + * + * @static + * @memberOf _ + * @category Util + * @param {Function|Object} [object=lodash] The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options] The options object. + * @param {boolean} [options.chain=true] Specify whether the functions added + * are chainable. + * @returns {Function|Object} Returns `object`. + * @example + * + * function vowels(string) { + * return _.filter(string, function(v) { + * return /[aeiou]/i.test(v); + * }); + * } + * + * _.mixin({ 'vowels': vowels }); + * _.vowels('fred'); + * // => ['e'] + * + * _('fred').vowels().value(); + * // => ['e'] + * + * _.mixin({ 'vowels': vowels }, { 'chain': false }); + * _('fred').vowels(); + * // => ['e'] + */ + function mixin(object, source, options) { + var props = keys(source), + methodNames = baseFunctions(source, props); + + if (options == null && + !(isObject(source) && (methodNames.length || !props.length))) { + options = source; + source = object; + object = this; + methodNames = baseFunctions(source, keys(source)); + } + var chain = (isObject(options) && 'chain' in options) ? options.chain : true, + isFunc = isFunction(object); + + baseEach(methodNames, function(methodName) { + var func = source[methodName]; + object[methodName] = func; + if (isFunc) { + object.prototype[methodName] = function() { + var chainAll = this.__chain__; + if (chain || chainAll) { + var result = object(this.__wrapped__), + actions = result.__actions__ = copyArray(this.__actions__); + + actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); + result.__chain__ = chainAll; + return result; + } + return func.apply(object, arrayPush([this.value()], arguments)); + }; + } + }); + + return object; + } + + /** + * Reverts the `_` variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Util + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + if (root._ === this) { + root._ = oldDash; + } + return this; + } + + /** + * A no-operation function that returns `undefined` regardless of the + * arguments it receives. + * + * @static + * @memberOf _ + * @category Util + * @example + * + * var object = { 'user': 'fred' }; + * + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // No operation performed. + } + + /** + * Generates a unique ID. If `prefix` is given the ID is appended to it. + * + * @static + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ + function uniqueId(prefix) { + var id = ++idCounter; + return toString(prefix) + id; + } + + /*------------------------------------------------------------------------*/ + + /** + * Computes the maximum value of `array`. If `array` is empty or falsey + * `undefined` is returned. + * + * @static + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ + function max(array) { + return (array && array.length) + ? baseExtremum(array, identity, gt) + : undefined; + } + + /** + * Computes the minimum value of `array`. If `array` is empty or falsey + * `undefined` is returned. + * + * @static + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ + function min(array) { + return (array && array.length) + ? baseExtremum(array, identity, lt) + : undefined; + } + + /*------------------------------------------------------------------------*/ + + LodashWrapper.prototype = baseCreate(lodash.prototype); + LodashWrapper.prototype.constructor = LodashWrapper; + + // Add functions that return wrapped values when chaining. + lodash.assignIn = assignIn; + lodash.before = before; + lodash.bind = bind; + lodash.chain = chain; + lodash.compact = compact; + lodash.concat = concat; + lodash.create = create; + lodash.defaults = defaults; + lodash.defer = defer; + lodash.delay = delay; + lodash.filter = filter; + lodash.flatten = flatten; + lodash.flattenDeep = flattenDeep; + lodash.iteratee = iteratee; + lodash.keys = keys; + lodash.map = map; + lodash.matches = matches; + lodash.mixin = mixin; + lodash.negate = negate; + lodash.once = once; + lodash.pick = pick; + lodash.slice = slice; + lodash.sortBy = sortBy; + lodash.tap = tap; + lodash.thru = thru; + lodash.toArray = toArray; + lodash.values = values; + + // Add aliases. + lodash.extend = assignIn; + + // Add functions to `lodash.prototype`. + mixin(lodash, lodash); + + /*------------------------------------------------------------------------*/ + + // Add functions that return unwrapped values when chaining. + lodash.clone = clone; + lodash.escape = escape; + lodash.every = every; + lodash.find = find; + lodash.forEach = forEach; + lodash.has = has; + lodash.head = head; + lodash.identity = identity; + lodash.indexOf = indexOf; + lodash.isArguments = isArguments; + lodash.isArray = isArray; + lodash.isBoolean = isBoolean; + lodash.isDate = isDate; + lodash.isEmpty = isEmpty; + lodash.isEqual = isEqual; + lodash.isFinite = isFinite; + lodash.isFunction = isFunction; + lodash.isNaN = isNaN; + lodash.isNull = isNull; + lodash.isNumber = isNumber; + lodash.isObject = isObject; + lodash.isRegExp = isRegExp; + lodash.isString = isString; + lodash.isUndefined = isUndefined; + lodash.last = last; + lodash.max = max; + lodash.min = min; + lodash.noConflict = noConflict; + lodash.noop = noop; + lodash.reduce = reduce; + lodash.result = result; + lodash.size = size; + lodash.some = some; + lodash.uniqueId = uniqueId; + + // Add aliases. + lodash.each = forEach; + lodash.first = head; + + mixin(lodash, (function() { + var source = {}; + baseForOwn(lodash, function(func, methodName) { + if (!hasOwnProperty.call(lodash.prototype, methodName)) { + source[methodName] = func; + } + }); + return source; + }()), { 'chain': false }); + + /*------------------------------------------------------------------------*/ + + /** + * The semantic version number. + * + * @static + * @memberOf _ + * @type {string} + */ + lodash.VERSION = VERSION; + + // Add `Array` and `String` methods to `lodash.prototype`. + baseEach(['pop', 'join', 'replace', 'reverse', 'split', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { + var func = (/^(?:replace|split)$/.test(methodName) ? String.prototype : arrayProto)[methodName], + chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', + retUnwrapped = /^(?:pop|join|replace|shift)$/.test(methodName); + + lodash.prototype[methodName] = function() { + var args = arguments; + if (retUnwrapped && !this.__chain__) { + return func.apply(this.value(), args); + } + return this[chainName](function(value) { + return func.apply(value, args); + }); + }; + }); + + // Add chaining functions to the `lodash` wrapper. + lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue; + + /*--------------------------------------------------------------------------*/ + + // Expose lodash on the free variable `window` or `self` when available. This + // prevents errors in cases where lodash is loaded by a script tag in the presence + // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details. + (freeWindow || freeSelf || {})._ = lodash; + + // Some AMD build optimizers like r.js check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Define as an anonymous module so, through path mapping, it can be + // referenced as the "underscore" module. + define(function() { + return lodash; + }); + } + // Check for `exports` after `define` in case a build optimizer adds an `exports` object. + else if (freeExports && freeModule) { + // Export for Node.js. + if (moduleExports) { + (freeModule.exports = lodash)._ = lodash; + } + // Export for CommonJS support. + freeExports._ = lodash; + } + else { + // Export to the global object. + root._ = lodash; + } +}.call(this)); diff --git a/www/node_modules/lodash/core.min.js b/www/node_modules/lodash/core.min.js new file mode 100644 index 0000000..d6a4405 --- /dev/null +++ b/www/node_modules/lodash/core.min.js @@ -0,0 +1,29 @@ +/** + * @license + * lodash 4.6.1 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + * Build: `lodash core -o ./dist/lodash.core.js` + */ +;(function(){function n(n,t){for(var r=-1,e=t.length,u=n.length;++r-1&&0==n%1&&(null==t?9007199254740991:t)>n}function a(n){if(Y(n)&&!Pn(n)){if(n instanceof l)return n;if(An.call(n,"__wrapped__")){var t=new l(n.__wrapped__,n.__chain__);return t.__actions__=N(n.__actions__),t}}return new l(n)}function l(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t}function p(n,t,r,e){var u;return(u=n===an)||(u=xn[r], +u=(n===u||n!==n&&u!==u)&&!An.call(e,r)),u?t:n}function s(n){return X(n)?Fn(n):{}}function h(n,t,r){if(typeof n!="function")throw new TypeError("Expected a function");return setTimeout(function(){n.apply(an,r)},t)}function v(n,t){var r=true;return $n(n,function(n,e,u){return r=!!t(n,e,u)}),r}function y(n,t){var r=[];return $n(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function _(t,r,e,u){u||(u=[]);for(var o=-1,i=t.length;++o0&&Y(c)&&L(c)&&(e||Pn(c)||K(c))?r>1?_(c,r-1,e,u):n(u,c):e||(u[u.length]=c); +}return u}function b(n,t){return n&&qn(n,t,en)}function g(n,t){return y(t,function(t){return Q(n[t])})}function j(n,t,r,e,u){return n===t?true:null==n||null==t||!X(n)&&!Y(t)?n!==n&&t!==t:d(n,t,j,r,e,u)}function d(n,t,r,e,u,o){var i=Pn(n),f=Pn(t),a="[object Array]",l="[object Array]";i||(a=kn.call(n),a="[object Arguments]"==a?"[object Object]":a),f||(l=kn.call(t),l="[object Arguments]"==l?"[object Object]":l);var p="[object Object]"==a&&!c(n),f="[object Object]"==l&&!c(t),l=a==l;o||(o=[]);var s=J(o,function(t){ +return t[0]===n});return s&&s[1]?s[1]==t:(o.push([n,t]),l&&!p?(t=i||isTypedArray(n)?I(n,t,r,e,u,o):$(n,t,a),o.pop(),t):2&u||(i=p&&An.call(n,"__wrapped__"),a=f&&An.call(t,"__wrapped__"),!i&&!a)?l?(t=q(n,t,r,e,u,o),o.pop(),t):false:(t=r(i?n.value():n,a?t.value():t,e,u,o),o.pop(),t))}function m(n){var t=typeof n;return"function"==t?n:null==n?cn:("object"==t?x:E)(n)}function w(n){n=null==n?n:Object(n);var t,r=[];for(t in n)r.push(t);return r}function O(n,t){var r=-1,e=L(n)?Array(n.length):[];return $n(n,function(n,u,o){ +e[++r]=t(n,u,o)}),e}function x(n){var t=en(n);return function(r){var e=t.length;if(null==r)return!e;for(r=Object(r);e--;){var u=t[e];if(!(u in r&&j(n[u],r[u],an,3)))return false}return true}}function A(n,t){return n=Object(n),P(t,function(t,r){return r in n&&(t[r]=n[r]),t},{})}function E(n){return function(t){return null==t?an:t[n]}}function k(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Array(u);++e1?r[u-1]:an,o=typeof o=="function"?(u--,o):an;for(t=Object(t);++ef))return false;for(a=true;++iarguments.length,$n)}function U(n,t){var r;if(typeof t!="function")throw new TypeError("Expected a function");return n=Un(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=an),r}}function V(n){var t;if(typeof n!="function")throw new TypeError("Expected a function"); +return t=In(t===an?n.length-1:Un(t),0),function(){for(var r=arguments,e=-1,u=In(r.length-t,0),o=Array(u);++et}function K(n){return Y(n)&&L(n)&&An.call(n,"callee")&&(!Rn.call(n,"callee")||"[object Arguments]"==kn.call(n))}function L(n){return null!=n&&W(zn(n))&&!Q(n)}function Q(n){return n=X(n)?kn.call(n):"","[object Function]"==n||"[object GeneratorFunction]"==n}function W(n){return typeof n=="number"&&n>-1&&0==n%1&&9007199254740991>=n; +}function X(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function Y(n){return!!n&&typeof n=="object"}function Z(n){return typeof n=="number"||Y(n)&&"[object Number]"==kn.call(n)}function nn(n){return typeof n=="string"||!Pn(n)&&Y(n)&&"[object String]"==kn.call(n)}function tn(n,t){return t>n}function rn(n){return typeof n=="string"?n:null==n?"":n+""}function en(n){var t=C(n);if(!t&&!L(n))return Dn(Object(n));var r,e=z(n),u=!!e,e=e||[],o=e.length;for(r in n)!An.call(n,r)||u&&("length"==r||f(r,o))||t&&"constructor"==r||e.push(r); +return e}function un(n){for(var t=-1,r=C(n),e=w(n),u=e.length,o=z(n),i=!!o,o=o||[],c=o.length;++t"'`]/g,sn=RegExp(pn.source),hn=/^(?:0|[1-9]\d*)$/,vn={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},yn={"function":true,object:true},_n=yn[typeof exports]&&exports&&!exports.nodeType?exports:an,bn=yn[typeof module]&&module&&!module.nodeType?module:an,gn=bn&&bn.exports===_n?_n:an,jn=o(yn[typeof self]&&self),dn=o(yn[typeof window]&&window),mn=o(yn[typeof this]&&this),wn=o(_n&&bn&&typeof global=="object"&&global)||dn!==(mn&&mn.window)&&dn||jn||mn||Function("return this")(),On=Array.prototype,xn=Object.prototype,An=xn.hasOwnProperty,En=0,kn=xn.toString,Nn=wn._,Sn=wn.Reflect,Tn=Sn?Sn.f:an,Fn=Object.create,Rn=xn.propertyIsEnumerable,Bn=wn.isFinite,Dn=Object.keys,In=Math.max,$n=function(n,t){ +return function(r,e){if(null==r)return r;if(!L(r))return n(r,e);for(var u=r.length,o=t?u:-1,i=Object(r);(t?o--:++oe&&!c||!i||u&&!f&&a||o&&a){r=1;break n}if(e>r&&!u||!a||c&&!o&&i||f&&i){r=-1;break n}}r=0}return r||n.b-t.b; +}),E("c"))},a.tap=function(n,t){return t(n),n},a.thru=function(n,t){return t(n)},a.toArray=function(n){return L(n)?n.length?N(n):[]:on(n)},a.values=on,a.extend=Kn,fn(a,a),a.clone=function(n){return X(n)?Pn(n)?N(n):F(n,en(n)):n},a.escape=function(n){return(n=rn(n))&&sn.test(n)?n.replace(pn,i):n},a.every=function(n,t,r){return t=r?an:t,v(n,m(t))},a.find=J,a.forEach=M,a.has=function(n,t){return null!=n&&An.call(n,t)},a.head=G,a.identity=cn,a.indexOf=function(n,t,r){var e=n?n.length:0;r=typeof r=="number"?0>r?In(e+r,0):r:0, +r=(r||0)-1;for(var u=t===t;++r { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ +var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); +}); + +module.exports = countBy; diff --git a/www/node_modules/lodash/create.js b/www/node_modules/lodash/create.js new file mode 100644 index 0000000..dddbd29 --- /dev/null +++ b/www/node_modules/lodash/create.js @@ -0,0 +1,41 @@ +var baseAssign = require('./_baseAssign'), + baseCreate = require('./_baseCreate'); + +/** + * Creates an object that inherits from the `prototype` object. If a `properties` + * object is given its own enumerable properties are assigned to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ +function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? baseAssign(result, properties) : result; +} + +module.exports = create; diff --git a/www/node_modules/lodash/curry.js b/www/node_modules/lodash/curry.js new file mode 100644 index 0000000..1c5e8a5 --- /dev/null +++ b/www/node_modules/lodash/curry.js @@ -0,0 +1,56 @@ +var createWrapper = require('./_createWrapper'); + +/** Used to compose bitmasks for wrapper metadata. */ +var CURRY_FLAG = 8; + +/** + * Creates a function that accepts arguments of `func` and either invokes + * `func` returning its result, if at least `arity` number of arguments have + * been provided, or returns a function that accepts the remaining `func` + * arguments, and so on. The arity of `func` may be specified if `func.length` + * is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ +function curry(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curry.placeholder; + return result; +} + +// Assign default placeholders. +curry.placeholder = {}; + +module.exports = curry; diff --git a/www/node_modules/lodash/curryRight.js b/www/node_modules/lodash/curryRight.js new file mode 100644 index 0000000..8521fdc --- /dev/null +++ b/www/node_modules/lodash/curryRight.js @@ -0,0 +1,53 @@ +var createWrapper = require('./_createWrapper'); + +/** Used to compose bitmasks for wrapper metadata. */ +var CURRY_RIGHT_FLAG = 16; + +/** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ +function curryRight(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryRight.placeholder; + return result; +} + +// Assign default placeholders. +curryRight.placeholder = {}; + +module.exports = curryRight; diff --git a/www/node_modules/lodash/date.js b/www/node_modules/lodash/date.js new file mode 100644 index 0000000..cbf5b41 --- /dev/null +++ b/www/node_modules/lodash/date.js @@ -0,0 +1,3 @@ +module.exports = { + 'now': require('./now') +}; diff --git a/www/node_modules/lodash/debounce.js b/www/node_modules/lodash/debounce.js new file mode 100644 index 0000000..45f52ce --- /dev/null +++ b/www/node_modules/lodash/debounce.js @@ -0,0 +1,177 @@ +var isObject = require('./isObject'), + now = require('./now'), + toNumber = require('./toNumber'); + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide an options object to indicate whether `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent calls + * to the debounced function return the result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it's invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ +function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + leading = false, + maxWait = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait); + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + lastCalled = 0; + args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined; + } + + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function flush() { + if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) { + result = func.apply(thisArg, args); + } + cancel(); + return result; + } + + function maxDelayed() { + complete(trailing, timeoutId); + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!lastCalled && !maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled); + + var isCalled = (remaining <= 0 || remaining > maxWait) && + (leading || maxTimeoutId); + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; +} + +module.exports = debounce; diff --git a/www/node_modules/lodash/deburr.js b/www/node_modules/lodash/deburr.js new file mode 100644 index 0000000..7e75034 --- /dev/null +++ b/www/node_modules/lodash/deburr.js @@ -0,0 +1,39 @@ +var deburrLetter = require('./_deburrLetter'), + toString = require('./toString'); + +/** Used to match latin-1 supplementary letters (excluding mathematical operators). */ +var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + +/** Used to compose unicode character classes. */ +var rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0'; + +/** Used to compose unicode capture groups. */ +var rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']'; + +/** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ +var reComboMark = RegExp(rsCombo, 'g'); + +/** + * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ +function deburr(string) { + string = toString(string); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); +} + +module.exports = deburr; diff --git a/www/node_modules/lodash/defaults.js b/www/node_modules/lodash/defaults.js new file mode 100644 index 0000000..eded284 --- /dev/null +++ b/www/node_modules/lodash/defaults.js @@ -0,0 +1,30 @@ +var apply = require('./_apply'), + assignInDefaults = require('./_assignInDefaults'), + assignInWith = require('./assignInWith'), + rest = require('./rest'); + +/** + * Assigns own and inherited enumerable properties of source objects to the + * destination object for all destination properties that resolve to `undefined`. + * Source objects are applied from left to right. Once a property is set, + * additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ +var defaults = rest(function(args) { + args.push(undefined, assignInDefaults); + return apply(assignInWith, undefined, args); +}); + +module.exports = defaults; diff --git a/www/node_modules/lodash/defaultsDeep.js b/www/node_modules/lodash/defaultsDeep.js new file mode 100644 index 0000000..c495aee --- /dev/null +++ b/www/node_modules/lodash/defaultsDeep.js @@ -0,0 +1,29 @@ +var apply = require('./_apply'), + mergeDefaults = require('./_mergeDefaults'), + mergeWith = require('./mergeWith'), + rest = require('./rest'); + +/** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } + * + */ +var defaultsDeep = rest(function(args) { + args.push(undefined, mergeDefaults); + return apply(mergeWith, undefined, args); +}); + +module.exports = defaultsDeep; diff --git a/www/node_modules/lodash/defer.js b/www/node_modules/lodash/defer.js new file mode 100644 index 0000000..f492b3d --- /dev/null +++ b/www/node_modules/lodash/defer.js @@ -0,0 +1,25 @@ +var baseDelay = require('./_baseDelay'), + rest = require('./rest'); + +/** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => logs 'deferred' after one or more milliseconds + */ +var defer = rest(function(func, args) { + return baseDelay(func, 1, args); +}); + +module.exports = defer; diff --git a/www/node_modules/lodash/delay.js b/www/node_modules/lodash/delay.js new file mode 100644 index 0000000..28d070c --- /dev/null +++ b/www/node_modules/lodash/delay.js @@ -0,0 +1,27 @@ +var baseDelay = require('./_baseDelay'), + rest = require('./rest'), + toNumber = require('./toNumber'); + +/** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ +var delay = rest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); +}); + +module.exports = delay; diff --git a/www/node_modules/lodash/difference.js b/www/node_modules/lodash/difference.js new file mode 100644 index 0000000..34c26e8 --- /dev/null +++ b/www/node_modules/lodash/difference.js @@ -0,0 +1,29 @@ +var baseDifference = require('./_baseDifference'), + baseFlatten = require('./_baseFlatten'), + isArrayLikeObject = require('./isArrayLikeObject'), + rest = require('./rest'); + +/** + * Creates an array of unique `array` values not included in the other + * given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. The order of result values is determined by the + * order they occur in the first array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([3, 2, 1], [4, 2]); + * // => [3, 1] + */ +var difference = rest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true)) + : []; +}); + +module.exports = difference; diff --git a/www/node_modules/lodash/differenceBy.js b/www/node_modules/lodash/differenceBy.js new file mode 100644 index 0000000..8c5831e --- /dev/null +++ b/www/node_modules/lodash/differenceBy.js @@ -0,0 +1,40 @@ +var baseDifference = require('./_baseDifference'), + baseFlatten = require('./_baseFlatten'), + baseIteratee = require('./_baseIteratee'), + isArrayLikeObject = require('./isArrayLikeObject'), + last = require('./last'), + rest = require('./rest'); + +/** + * This method is like `_.difference` except that it accepts `iteratee` which + * is invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. Result values are chosen from the first array. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor); + * // => [3.1, 1.3] + * + * // The `_.property` iteratee shorthand. + * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ +var differenceBy = rest(function(array, values) { + var iteratee = last(values); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true), baseIteratee(iteratee)) + : []; +}); + +module.exports = differenceBy; diff --git a/www/node_modules/lodash/differenceWith.js b/www/node_modules/lodash/differenceWith.js new file mode 100644 index 0000000..88a4a0b --- /dev/null +++ b/www/node_modules/lodash/differenceWith.js @@ -0,0 +1,37 @@ +var baseDifference = require('./_baseDifference'), + baseFlatten = require('./_baseFlatten'), + isArrayLikeObject = require('./isArrayLikeObject'), + last = require('./last'), + rest = require('./rest'); + +/** + * This method is like `_.difference` except that it accepts `comparator` + * which is invoked to compare elements of `array` to `values`. Result values + * are chosen from the first array. The comparator is invoked with two arguments: + * (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * + * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); + * // => [{ 'x': 2, 'y': 1 }] + */ +var differenceWith = rest(function(array, values) { + var comparator = last(values); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true), undefined, comparator) + : []; +}); + +module.exports = differenceWith; diff --git a/www/node_modules/lodash/drop.js b/www/node_modules/lodash/drop.js new file mode 100644 index 0000000..3094995 --- /dev/null +++ b/www/node_modules/lodash/drop.js @@ -0,0 +1,37 @@ +var baseSlice = require('./_baseSlice'), + toInteger = require('./toInteger'); + +/** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ +function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, n < 0 ? 0 : n, length); +} + +module.exports = drop; diff --git a/www/node_modules/lodash/dropRight.js b/www/node_modules/lodash/dropRight.js new file mode 100644 index 0000000..61e1268 --- /dev/null +++ b/www/node_modules/lodash/dropRight.js @@ -0,0 +1,38 @@ +var baseSlice = require('./_baseSlice'), + toInteger = require('./toInteger'); + +/** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ +function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, 0, n < 0 ? 0 : n); +} + +module.exports = dropRight; diff --git a/www/node_modules/lodash/dropRightWhile.js b/www/node_modules/lodash/dropRightWhile.js new file mode 100644 index 0000000..0c04ed2 --- /dev/null +++ b/www/node_modules/lodash/dropRightWhile.js @@ -0,0 +1,44 @@ +var baseIteratee = require('./_baseIteratee'), + baseWhile = require('./_baseWhile'); + +/** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.dropRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney'] + * + * // The `_.matches` iteratee shorthand. + * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropRightWhile(users, ['active', false]); + * // => objects for ['barney'] + * + * // The `_.property` iteratee shorthand. + * _.dropRightWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ +function dropRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, baseIteratee(predicate, 3), true, true) + : []; +} + +module.exports = dropRightWhile; diff --git a/www/node_modules/lodash/dropWhile.js b/www/node_modules/lodash/dropWhile.js new file mode 100644 index 0000000..72f9448 --- /dev/null +++ b/www/node_modules/lodash/dropWhile.js @@ -0,0 +1,44 @@ +var baseIteratee = require('./_baseIteratee'), + baseWhile = require('./_baseWhile'); + +/** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.dropWhile(users, function(o) { return !o.active; }); + * // => objects for ['pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.dropWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropWhile(users, ['active', false]); + * // => objects for ['pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.dropWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ +function dropWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, baseIteratee(predicate, 3), true) + : []; +} + +module.exports = dropWhile; diff --git a/www/node_modules/lodash/each.js b/www/node_modules/lodash/each.js new file mode 100644 index 0000000..8800f42 --- /dev/null +++ b/www/node_modules/lodash/each.js @@ -0,0 +1 @@ +module.exports = require('./forEach'); diff --git a/www/node_modules/lodash/eachRight.js b/www/node_modules/lodash/eachRight.js new file mode 100644 index 0000000..3252b2a --- /dev/null +++ b/www/node_modules/lodash/eachRight.js @@ -0,0 +1 @@ +module.exports = require('./forEachRight'); diff --git a/www/node_modules/lodash/endsWith.js b/www/node_modules/lodash/endsWith.js new file mode 100644 index 0000000..5da6b5e --- /dev/null +++ b/www/node_modules/lodash/endsWith.js @@ -0,0 +1,39 @@ +var baseClamp = require('./_baseClamp'), + toInteger = require('./toInteger'), + toString = require('./toString'); + +/** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search from. + * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ +function endsWith(string, target, position) { + string = toString(string); + target = typeof target == 'string' ? target : (target + ''); + + var length = string.length; + position = position === undefined + ? length + : baseClamp(toInteger(position), 0, length); + + position -= target.length; + return position >= 0 && string.indexOf(target, position) == position; +} + +module.exports = endsWith; diff --git a/www/node_modules/lodash/eq.js b/www/node_modules/lodash/eq.js new file mode 100644 index 0000000..5df222d --- /dev/null +++ b/www/node_modules/lodash/eq.js @@ -0,0 +1,35 @@ +/** + * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +module.exports = eq; diff --git a/www/node_modules/lodash/escape.js b/www/node_modules/lodash/escape.js new file mode 100644 index 0000000..62857ed --- /dev/null +++ b/www/node_modules/lodash/escape.js @@ -0,0 +1,47 @@ +var escapeHtmlChar = require('./_escapeHtmlChar'), + toString = require('./toString'); + +/** Used to match HTML entities and HTML characters. */ +var reUnescapedHtml = /[&<>"'`]/g, + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + +/** + * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in IE < 9, they can break out of + * attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ +function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; +} + +module.exports = escape; diff --git a/www/node_modules/lodash/escapeRegExp.js b/www/node_modules/lodash/escapeRegExp.js new file mode 100644 index 0000000..52878c1 --- /dev/null +++ b/www/node_modules/lodash/escapeRegExp.js @@ -0,0 +1,28 @@ +var toString = require('./toString'); + +/** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, + reHasRegExpChar = RegExp(reRegExpChar.source); + +/** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ +function escapeRegExp(string) { + string = toString(string); + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string; +} + +module.exports = escapeRegExp; diff --git a/www/node_modules/lodash/every.js b/www/node_modules/lodash/every.js new file mode 100644 index 0000000..d100d0d --- /dev/null +++ b/www/node_modules/lodash/every.js @@ -0,0 +1,49 @@ +var arrayEvery = require('./_arrayEvery'), + baseEvery = require('./_baseEvery'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'), + isIterateeCall = require('./_isIterateeCall'); + +/** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ +function every(collection, predicate, guard) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, baseIteratee(predicate, 3)); +} + +module.exports = every; diff --git a/www/node_modules/lodash/extend.js b/www/node_modules/lodash/extend.js new file mode 100644 index 0000000..e00166c --- /dev/null +++ b/www/node_modules/lodash/extend.js @@ -0,0 +1 @@ +module.exports = require('./assignIn'); diff --git a/www/node_modules/lodash/extendWith.js b/www/node_modules/lodash/extendWith.js new file mode 100644 index 0000000..dbdcb3b --- /dev/null +++ b/www/node_modules/lodash/extendWith.js @@ -0,0 +1 @@ +module.exports = require('./assignInWith'); diff --git a/www/node_modules/lodash/fill.js b/www/node_modules/lodash/fill.js new file mode 100644 index 0000000..4c0119f --- /dev/null +++ b/www/node_modules/lodash/fill.js @@ -0,0 +1,44 @@ +var baseFill = require('./_baseFill'), + isIterateeCall = require('./_isIterateeCall'); + +/** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8, 10], '*', 1, 3); + * // => [4, '*', '*', 10] + */ +function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); +} + +module.exports = fill; diff --git a/www/node_modules/lodash/filter.js b/www/node_modules/lodash/filter.js new file mode 100644 index 0000000..1df81c4 --- /dev/null +++ b/www/node_modules/lodash/filter.js @@ -0,0 +1,44 @@ +var arrayFilter = require('./_arrayFilter'), + baseFilter = require('./_baseFilter'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'); + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + */ +function filter(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, baseIteratee(predicate, 3)); +} + +module.exports = filter; diff --git a/www/node_modules/lodash/find.js b/www/node_modules/lodash/find.js new file mode 100644 index 0000000..c2ba356 --- /dev/null +++ b/www/node_modules/lodash/find.js @@ -0,0 +1,50 @@ +var baseEach = require('./_baseEach'), + baseFind = require('./_baseFind'), + baseFindIndex = require('./_baseFindIndex'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'); + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +function find(collection, predicate) { + predicate = baseIteratee(predicate, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, baseEach); +} + +module.exports = find; diff --git a/www/node_modules/lodash/findIndex.js b/www/node_modules/lodash/findIndex.js new file mode 100644 index 0000000..5343fd1 --- /dev/null +++ b/www/node_modules/lodash/findIndex.js @@ -0,0 +1,43 @@ +var baseFindIndex = require('./_baseFindIndex'), + baseIteratee = require('./_baseIteratee'); + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate) { + return (array && array.length) + ? baseFindIndex(array, baseIteratee(predicate, 3)) + : -1; +} + +module.exports = findIndex; diff --git a/www/node_modules/lodash/findKey.js b/www/node_modules/lodash/findKey.js new file mode 100644 index 0000000..95d01f3 --- /dev/null +++ b/www/node_modules/lodash/findKey.js @@ -0,0 +1,42 @@ +var baseFind = require('./_baseFind'), + baseForOwn = require('./_baseForOwn'), + baseIteratee = require('./_baseIteratee'); + +/** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ +function findKey(object, predicate) { + return baseFind(object, baseIteratee(predicate, 3), baseForOwn, true); +} + +module.exports = findKey; diff --git a/www/node_modules/lodash/findLast.js b/www/node_modules/lodash/findLast.js new file mode 100644 index 0000000..0e5d593 --- /dev/null +++ b/www/node_modules/lodash/findLast.js @@ -0,0 +1,33 @@ +var baseEachRight = require('./_baseEachRight'), + baseFind = require('./_baseFind'), + baseFindIndex = require('./_baseFindIndex'), + baseIteratee = require('./_baseIteratee'), + isArray = require('./isArray'); + +/** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ +function findLast(collection, predicate) { + predicate = baseIteratee(predicate, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, true); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, baseEachRight); +} + +module.exports = findLast; diff --git a/www/node_modules/lodash/findLastIndex.js b/www/node_modules/lodash/findLastIndex.js new file mode 100644 index 0000000..2e62b36 --- /dev/null +++ b/www/node_modules/lodash/findLastIndex.js @@ -0,0 +1,43 @@ +var baseFindIndex = require('./_baseFindIndex'), + baseIteratee = require('./_baseIteratee'); + +/** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); + * // => 2 + * + * // The `_.matches` iteratee shorthand. + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastIndex(users, ['active', false]); + * // => 2 + * + * // The `_.property` iteratee shorthand. + * _.findLastIndex(users, 'active'); + * // => 0 + */ +function findLastIndex(array, predicate) { + return (array && array.length) + ? baseFindIndex(array, baseIteratee(predicate, 3), true) + : -1; +} + +module.exports = findLastIndex; diff --git a/www/node_modules/lodash/findLastKey.js b/www/node_modules/lodash/findLastKey.js new file mode 100644 index 0000000..0380b07 --- /dev/null +++ b/www/node_modules/lodash/findLastKey.js @@ -0,0 +1,42 @@ +var baseFind = require('./_baseFind'), + baseForOwnRight = require('./_baseForOwnRight'), + baseIteratee = require('./_baseIteratee'); + +/** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ +function findLastKey(object, predicate) { + return baseFind(object, baseIteratee(predicate, 3), baseForOwnRight, true); +} + +module.exports = findLastKey; diff --git a/www/node_modules/lodash/flatMap.js b/www/node_modules/lodash/flatMap.js new file mode 100644 index 0000000..0117bb4 --- /dev/null +++ b/www/node_modules/lodash/flatMap.js @@ -0,0 +1,28 @@ +var baseFlatten = require('./_baseFlatten'), + map = require('./map'); + +/** + * Creates an array of flattened values by running each element in `collection` + * through `iteratee` and concating its result to the other mapped values. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [n, n]; + * } + * + * _.flatMap([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ +function flatMap(collection, iteratee) { + return baseFlatten(map(collection, iteratee), 1); +} + +module.exports = flatMap; diff --git a/www/node_modules/lodash/flatten.js b/www/node_modules/lodash/flatten.js new file mode 100644 index 0000000..b8f701d --- /dev/null +++ b/www/node_modules/lodash/flatten.js @@ -0,0 +1,21 @@ +var baseFlatten = require('./_baseFlatten'); + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, 1) : []; +} + +module.exports = flatten; diff --git a/www/node_modules/lodash/flattenDeep.js b/www/node_modules/lodash/flattenDeep.js new file mode 100644 index 0000000..b96cd56 --- /dev/null +++ b/www/node_modules/lodash/flattenDeep.js @@ -0,0 +1,24 @@ +var baseFlatten = require('./_baseFlatten'); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ +function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, INFINITY) : []; +} + +module.exports = flattenDeep; diff --git a/www/node_modules/lodash/flattenDepth.js b/www/node_modules/lodash/flattenDepth.js new file mode 100644 index 0000000..e045711 --- /dev/null +++ b/www/node_modules/lodash/flattenDepth.js @@ -0,0 +1,32 @@ +var baseFlatten = require('./_baseFlatten'), + toInteger = require('./toInteger'); + +/** + * Recursively flatten `array` up to `depth` times. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * var array = [1, [2, [3, [4]], 5]]; + * + * _.flattenDepth(array, 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth(array, 2); + * // => [1, 2, 3, [4], 5] + */ +function flattenDepth(array, depth) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(array, depth); +} + +module.exports = flattenDepth; diff --git a/www/node_modules/lodash/flip.js b/www/node_modules/lodash/flip.js new file mode 100644 index 0000000..6e14896 --- /dev/null +++ b/www/node_modules/lodash/flip.js @@ -0,0 +1,27 @@ +var createWrapper = require('./_createWrapper'); + +/** Used to compose bitmasks for wrapper metadata. */ +var FLIP_FLAG = 512; + +/** + * Creates a function that invokes `func` with arguments reversed. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to flip arguments for. + * @returns {Function} Returns the new function. + * @example + * + * var flipped = _.flip(function() { + * return _.toArray(arguments); + * }); + * + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] + */ +function flip(func) { + return createWrapper(func, FLIP_FLAG); +} + +module.exports = flip; diff --git a/www/node_modules/lodash/floor.js b/www/node_modules/lodash/floor.js new file mode 100644 index 0000000..9bbf097 --- /dev/null +++ b/www/node_modules/lodash/floor.js @@ -0,0 +1,25 @@ +var createRound = require('./_createRound'); + +/** + * Computes `number` rounded down to `precision`. + * + * @static + * @memberOf _ + * @category Math + * @param {number} number The number to round down. + * @param {number} [precision=0] The precision to round down to. + * @returns {number} Returns the rounded down number. + * @example + * + * _.floor(4.006); + * // => 4 + * + * _.floor(0.046, 2); + * // => 0.04 + * + * _.floor(4060, -2); + * // => 4000 + */ +var floor = createRound('floor'); + +module.exports = floor; diff --git a/www/node_modules/lodash/flow.js b/www/node_modules/lodash/flow.js new file mode 100644 index 0000000..b773405 --- /dev/null +++ b/www/node_modules/lodash/flow.js @@ -0,0 +1,25 @@ +var createFlow = require('./_createFlow'); + +/** + * Creates a function that returns the result of invoking the given functions + * with the `this` binding of the created function, where each successive + * invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @category Util + * @param {...(Function|Function[])} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 + */ +var flow = createFlow(); + +module.exports = flow; diff --git a/www/node_modules/lodash/flowRight.js b/www/node_modules/lodash/flowRight.js new file mode 100644 index 0000000..e844822 --- /dev/null +++ b/www/node_modules/lodash/flowRight.js @@ -0,0 +1,24 @@ +var createFlow = require('./_createFlow'); + +/** + * This method is like `_.flow` except that it creates a function that + * invokes the given functions from right to left. + * + * @static + * @memberOf _ + * @category Util + * @param {...(Function|Function[])} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 + */ +var flowRight = createFlow(true); + +module.exports = flowRight; diff --git a/www/node_modules/lodash/forEach.js b/www/node_modules/lodash/forEach.js new file mode 100644 index 0000000..a11eb22 --- /dev/null +++ b/www/node_modules/lodash/forEach.js @@ -0,0 +1,40 @@ +var arrayEach = require('./_arrayEach'), + baseCastFunction = require('./_baseCastFunction'), + baseEach = require('./_baseEach'), + isArray = require('./isArray'); + +/** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn` + * for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(value) { + * console.log(value); + * }); + * // => logs `1` then `2` + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' then 'b' (iteration order is not guaranteed) + */ +function forEach(collection, iteratee) { + return (typeof iteratee == 'function' && isArray(collection)) + ? arrayEach(collection, iteratee) + : baseEach(collection, baseCastFunction(iteratee)); +} + +module.exports = forEach; diff --git a/www/node_modules/lodash/forEachRight.js b/www/node_modules/lodash/forEachRight.js new file mode 100644 index 0000000..ea58e7c --- /dev/null +++ b/www/node_modules/lodash/forEachRight.js @@ -0,0 +1,30 @@ +var arrayEachRight = require('./_arrayEachRight'), + baseCastFunction = require('./_baseCastFunction'), + baseEachRight = require('./_baseEachRight'), + isArray = require('./isArray'); + +/** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @example + * + * _.forEachRight([1, 2], function(value) { + * console.log(value); + * }); + * // => logs `2` then `1` + */ +function forEachRight(collection, iteratee) { + return (typeof iteratee == 'function' && isArray(collection)) + ? arrayEachRight(collection, iteratee) + : baseEachRight(collection, baseCastFunction(iteratee)); +} + +module.exports = forEachRight; diff --git a/www/node_modules/lodash/forIn.js b/www/node_modules/lodash/forIn.js new file mode 100644 index 0000000..747175f --- /dev/null +++ b/www/node_modules/lodash/forIn.js @@ -0,0 +1,37 @@ +var baseCastFunction = require('./_baseCastFunction'), + baseFor = require('./_baseFor'), + keysIn = require('./keysIn'); + +/** + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The iteratee is invoked with three arguments: + * (value, key, object). Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed) + */ +function forIn(object, iteratee) { + return object == null + ? object + : baseFor(object, baseCastFunction(iteratee), keysIn); +} + +module.exports = forIn; diff --git a/www/node_modules/lodash/forInRight.js b/www/node_modules/lodash/forInRight.js new file mode 100644 index 0000000..fa74e9e --- /dev/null +++ b/www/node_modules/lodash/forInRight.js @@ -0,0 +1,35 @@ +var baseCastFunction = require('./_baseCastFunction'), + baseForRight = require('./_baseForRight'), + keysIn = require('./keysIn'); + +/** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c' + */ +function forInRight(object, iteratee) { + return object == null + ? object + : baseForRight(object, baseCastFunction(iteratee), keysIn); +} + +module.exports = forInRight; diff --git a/www/node_modules/lodash/forOwn.js b/www/node_modules/lodash/forOwn.js new file mode 100644 index 0000000..ac5ddc6 --- /dev/null +++ b/www/node_modules/lodash/forOwn.js @@ -0,0 +1,34 @@ +var baseCastFunction = require('./_baseCastFunction'), + baseForOwn = require('./_baseForOwn'); + +/** + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The iteratee is invoked with three arguments: + * (value, key, object). Iteratee functions may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' then 'b' (iteration order is not guaranteed) + */ +function forOwn(object, iteratee) { + return object && baseForOwn(object, baseCastFunction(iteratee)); +} + +module.exports = forOwn; diff --git a/www/node_modules/lodash/forOwnRight.js b/www/node_modules/lodash/forOwnRight.js new file mode 100644 index 0000000..7bda5de --- /dev/null +++ b/www/node_modules/lodash/forOwnRight.js @@ -0,0 +1,32 @@ +var baseCastFunction = require('./_baseCastFunction'), + baseForOwnRight = require('./_baseForOwnRight'); + +/** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b' + */ +function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, baseCastFunction(iteratee)); +} + +module.exports = forOwnRight; diff --git a/www/node_modules/lodash/fp.js b/www/node_modules/lodash/fp.js new file mode 100644 index 0000000..e372dbb --- /dev/null +++ b/www/node_modules/lodash/fp.js @@ -0,0 +1,2 @@ +var _ = require('./lodash.min').runInContext(); +module.exports = require('./fp/_baseConvert')(_, _); diff --git a/www/node_modules/lodash/fp/_baseConvert.js b/www/node_modules/lodash/fp/_baseConvert.js new file mode 100644 index 0000000..b074100 --- /dev/null +++ b/www/node_modules/lodash/fp/_baseConvert.js @@ -0,0 +1,319 @@ +var mapping = require('./_mapping'), + mutateMap = mapping.mutate, + fallbackHolder = {}; + +/** + * The base implementation of `convert` which accepts a `util` object of methods + * required to perform conversions. + * + * @param {Object} util The util object. + * @param {string} name The name of the function to wrap. + * @param {Function} func The function to wrap. + * @param {Object} [options] The options object. + * @param {boolean} [options.cap=true] Specify capping iteratee arguments. + * @param {boolean} [options.curry=true] Specify currying. + * @param {boolean} [options.fixed=true] Specify fixed arity. + * @param {boolean} [options.immutable=true] Specify immutable operations. + * @param {boolean} [options.rearg=true] Specify rearranging arguments. + * @returns {Function|Object} Returns the converted function or object. + */ +function baseConvert(util, name, func, options) { + var setPlaceholder, + isLib = typeof name == 'function', + isObj = name === Object(name); + + if (isObj) { + options = func; + func = name; + name = undefined; + } + if (func == null) { + throw new TypeError; + } + options || (options = {}); + + var config = { + 'cap': 'cap' in options ? options.cap : true, + 'curry': 'curry' in options ? options.curry : true, + 'fixed': 'fixed' in options ? options.fixed : true, + 'immutable': 'immutable' in options ? options.immutable : true, + 'rearg': 'rearg' in options ? options.rearg : true + }; + + var forceRearg = ('rearg' in options) && options.rearg, + placeholder = isLib ? func : fallbackHolder; + + var helpers = isLib ? func : { + 'ary': util.ary, + 'clone': util.clone, + 'curry': util.curry, + 'forEach': util.forEach, + 'isArray': util.isArray, + 'isFunction': util.isFunction, + 'iteratee': util.iteratee, + 'keys': util.keys, + 'rearg': util.rearg, + 'spread': util.spread, + 'toPath': util.toPath + }; + + var ary = helpers.ary, + clone = helpers.clone, + curry = helpers.curry, + each = helpers.forEach, + isArray = helpers.isArray, + isFunction = helpers.isFunction, + keys = helpers.keys, + rearg = helpers.rearg, + spread = helpers.spread, + toPath = helpers.toPath; + + var aryMethodKeys = keys(mapping.aryMethod); + + var baseArity = function(func, n) { + return n == 2 + ? function(a, b) { return func.apply(undefined, arguments); } + : function(a) { return func.apply(undefined, arguments); }; + }; + + var baseAry = function(func, n) { + return n == 2 + ? function(a, b) { return func(a, b); } + : function(a) { return func(a); }; + }; + + var cloneArray = function(array) { + var length = array ? array.length : 0, + result = Array(length); + + while (length--) { + result[length] = array[length]; + } + return result; + }; + + var cloneByPath = function(object, path) { + path = toPath(path); + + var index = -1, + length = path.length, + result = clone(Object(object)), + nested = result; + + while (nested != null && ++index < length) { + var key = path[index], + value = nested[key]; + + if (value != null) { + nested[key] = clone(Object(value)); + } + nested = nested[key]; + } + return result; + }; + + var createCloner = function(func) { + return function(object) { + return func({}, object); + }; + }; + + var immutWrap = function(func, cloner) { + return function() { + var length = arguments.length; + if (!length) { + return result; + } + var args = Array(length); + while (length--) { + args[length] = arguments[length]; + } + var result = args[0] = cloner.apply(undefined, args); + func.apply(undefined, args); + return result; + }; + }; + + var iterateeAry = function(func, n) { + return overArg(func, function(func) { + return typeof func == 'function' ? baseAry(func, n) : func; + }); + }; + + var iterateeRearg = function(func, indexes) { + return overArg(func, function(func) { + var n = indexes.length; + return baseArity(rearg(baseAry(func, n), indexes), n); + }); + }; + + var overArg = function(func, iteratee, retArg) { + return function() { + var length = arguments.length; + if (!length) { + return func(); + } + var args = Array(length); + while (length--) { + args[length] = arguments[length]; + } + var index = config.rearg ? 0 : (length - 1); + args[index] = iteratee(args[index]); + return func.apply(undefined, args); + }; + }; + + var wrappers = { + 'castArray': function(castArray) { + return function() { + var value = arguments[0]; + return isArray(value) + ? castArray(cloneArray(value)) + : castArray.apply(undefined, arguments); + }; + }, + 'iteratee': function(iteratee) { + return function() { + var func = arguments[0], + arity = arguments[1], + result = iteratee(func, arity), + length = result.length; + + if (config.cap && typeof arity == 'number') { + arity = arity > 2 ? (arity - 2) : 1; + return (length && length <= arity) ? result : baseAry(result, arity); + } + return result; + }; + }, + 'mixin': function(mixin) { + return function(source) { + var func = this; + if (!isFunction(func)) { + return mixin(func, Object(source)); + } + var methods = [], + methodNames = []; + + each(keys(source), function(key) { + var value = source[key]; + if (isFunction(value)) { + methodNames.push(key); + methods.push(func.prototype[key]); + } + }); + + mixin(func, Object(source)); + + each(methodNames, function(methodName, index) { + var method = methods[index]; + if (isFunction(method)) { + func.prototype[methodName] = method; + } else { + delete func.prototype[methodName]; + } + }); + return func; + }; + }, + 'runInContext': function(runInContext) { + return function(context) { + return baseConvert(util, runInContext(context), options); + }; + } + }; + + var wrap = function(name, func) { + name = mapping.aliasToReal[name] || name; + var wrapper = wrappers[name]; + if (wrapper) { + return wrapper(func); + } + var wrapped = func; + if (config.immutable) { + if (mutateMap.array[name]) { + wrapped = immutWrap(func, cloneArray); + } + else if (mutateMap.object[name]) { + wrapped = immutWrap(func, createCloner(func)); + } + else if (mutateMap.set[name]) { + wrapped = immutWrap(func, cloneByPath); + } + } + var result; + each(aryMethodKeys, function(aryKey) { + each(mapping.aryMethod[aryKey], function(otherName) { + if (name == otherName) { + var aryN = !isLib && mapping.iterateeAry[name], + reargIndexes = mapping.iterateeRearg[name], + spreadStart = mapping.methodSpread[name]; + + result = wrapped; + if (config.fixed) { + result = spreadStart === undefined + ? ary(result, aryKey) + : spread(result, spreadStart); + } + if (config.rearg && aryKey > 1 && (forceRearg || !mapping.skipRearg[name])) { + result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[aryKey]); + } + if (config.cap) { + if (reargIndexes) { + result = iterateeRearg(result, reargIndexes); + } else if (aryN) { + result = iterateeAry(result, aryN); + } + } + if (config.curry && aryKey > 1) { + result = curry(result, aryKey); + } + return false; + } + }); + return !result; + }); + + result || (result = wrapped); + if (mapping.placeholder[name]) { + setPlaceholder = true; + func.placeholder = result.placeholder = placeholder; + } + return result; + }; + + if (!isObj) { + return wrap(name, func); + } + var _ = func; + + // Iterate over methods for the current ary cap. + var pairs = []; + each(aryMethodKeys, function(aryKey) { + each(mapping.aryMethod[aryKey], function(key) { + var func = _[mapping.remap[key] || key]; + if (func) { + pairs.push([key, wrap(key, func)]); + } + }); + }); + + // Assign to `_` leaving `_.prototype` unchanged to allow chaining. + each(pairs, function(pair) { + _[pair[0]] = pair[1]; + }); + + if (setPlaceholder) { + _.placeholder = placeholder; + } + // Wrap the lodash method and its aliases. + each(keys(_), function(key) { + each(mapping.realToAlias[key] || [], function(alias) { + _[alias] = _[key]; + }); + }); + + return _; +} + +module.exports = baseConvert; diff --git a/www/node_modules/lodash/fp/_convertBrowser.js b/www/node_modules/lodash/fp/_convertBrowser.js new file mode 100644 index 0000000..fbd2174 --- /dev/null +++ b/www/node_modules/lodash/fp/_convertBrowser.js @@ -0,0 +1,17 @@ +var baseConvert = require('./_baseConvert'); + +/** + * Converts `lodash` to an immutable auto-curried iteratee-first data-last version. + * + * @param {Function} lodash The lodash function. + * @param {Object} [options] The options object. See `baseConvert` for more details. + * @returns {Function} Returns the converted `lodash`. + */ +function browserConvert(lodash, options) { + return baseConvert(lodash, lodash, options); +} + +if (typeof _ == 'function') { + _ = browserConvert(_.runInContext()); +} +module.exports = browserConvert; diff --git a/www/node_modules/lodash/fp/_mapping.js b/www/node_modules/lodash/fp/_mapping.js new file mode 100644 index 0000000..1d33d4b --- /dev/null +++ b/www/node_modules/lodash/fp/_mapping.js @@ -0,0 +1,243 @@ +/** Used to map aliases to their real names. */ +exports.aliasToReal = { + '__': 'placeholder', + 'all': 'some', + 'allPass': 'overEvery', + 'apply': 'spread', + 'assoc': 'set', + 'assocPath': 'set', + 'compose': 'flowRight', + 'contains': 'includes', + 'dissoc': 'unset', + 'dissocPath': 'unset', + 'each': 'forEach', + 'eachRight': 'forEachRight', + 'equals': 'isEqual', + 'extend': 'assignIn', + 'extendWith': 'assignInWith', + 'first': 'head', + 'init': 'initial', + 'mapObj': 'mapValues', + 'omitAll': 'omit', + 'nAry': 'ary', + 'path': 'get', + 'pathEq': 'matchesProperty', + 'pathOr': 'getOr', + 'pickAll': 'pick', + 'pipe': 'flow', + 'prop': 'get', + 'propOf': 'propertyOf', + 'propOr': 'getOr', + 'somePass': 'overSome', + 'unapply': 'rest', + 'unnest': 'flatten', + 'useWith': 'overArgs', + 'whereEq': 'filter', + 'zipObj': 'zipObject' +}; + +/** Used to map ary to method names. */ +exports.aryMethod = { + '1': [ + 'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor', + 'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', + 'over', 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext', + 'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words' + ], + '2': [ + 'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey', + 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN', + 'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference', + 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every', + 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', + 'findLastKey', 'flatMap', 'flattenDepth', 'forEach', 'forEachRight', 'forIn', + 'forInRight', 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has', + 'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap', + 'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', + 'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit', + 'omitBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', 'partial', + 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll', 'pullAt', + 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove', 'repeat', 'result', + 'sampleSize', 'some', 'sortBy', 'sortedIndex', 'sortedIndexOf', 'sortedLastIndex', + 'sortedLastIndexOf', 'sortedUniqBy', 'split', 'startsWith', 'subtract', 'sumBy', + 'take', 'takeRight', 'takeRightWhile', 'takeWhile', 'tap', 'throttle', 'thru', + 'times', 'trimChars', 'trimCharsEnd', 'trimCharsStart', 'truncate', 'union', + 'uniqBy', 'uniqWith', 'unset', 'unzipWith', 'without', 'wrap', 'xor', 'zip', + 'zipObject', 'zipObjectDeep' + ], + '3': [ + 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith', + 'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith', + 'isMatchWith', 'mergeWith', 'orderBy', 'pullAllBy', 'pullAllWith', 'reduce', + 'reduceRight', 'replace', 'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', + 'transform', 'unionBy', 'unionWith', 'update', 'xorBy', 'xorWith', 'zipWith' + ], + '4': [ + 'fill', 'setWith', 'updateWith' + ] +}; + +/** Used to map ary to rearg configs. */ +exports.aryRearg = { + '2': [1, 0], + '3': [2, 0, 1], + '4': [3, 2, 0, 1] +}; + +/** Used to map method names to their iteratee ary. */ +exports.iterateeAry = { + 'assignWith': 2, + 'assignInWith': 2, + 'cloneDeepWith': 1, + 'cloneWith': 1, + 'dropRightWhile': 1, + 'dropWhile': 1, + 'every': 1, + 'filter': 1, + 'find': 1, + 'findIndex': 1, + 'findKey': 1, + 'findLast': 1, + 'findLastIndex': 1, + 'findLastKey': 1, + 'flatMap': 1, + 'forEach': 1, + 'forEachRight': 1, + 'forIn': 1, + 'forInRight': 1, + 'forOwn': 1, + 'forOwnRight': 1, + 'isEqualWith': 2, + 'isMatchWith': 2, + 'map': 1, + 'mapKeys': 1, + 'mapValues': 1, + 'partition': 1, + 'reduce': 2, + 'reduceRight': 2, + 'reject': 1, + 'remove': 1, + 'some': 1, + 'takeRightWhile': 1, + 'takeWhile': 1, + 'times': 1, + 'transform': 2 +}; + +/** Used to map method names to iteratee rearg configs. */ +exports.iterateeRearg = { + 'mapKeys': [1] +}; + +/** Used to map method names to rearg configs. */ +exports.methodRearg = { + 'assignInWith': [1, 2, 0], + 'assignWith': [1, 2, 0], + 'getOr': [2, 1, 0], + 'isMatchWith': [2, 1, 0], + 'mergeWith': [1, 2, 0], + 'pullAllBy': [2, 1, 0], + 'pullAllWith': [2, 1, 0], + 'setWith': [3, 1, 2, 0], + 'sortedIndexBy': [2, 1, 0], + 'sortedLastIndexBy': [2, 1, 0], + 'updateWith': [3, 1, 2, 0], + 'zipWith': [1, 2, 0] +}; + +/** Used to map method names to spread configs. */ +exports.methodSpread = { + 'partial': 1, + 'partialRight': 1 +}; + +/** Used to identify methods which mutate arrays or objects. */ +exports.mutate = { + 'array': { + 'fill': true, + 'pull': true, + 'pullAll': true, + 'pullAllBy': true, + 'pullAllWith': true, + 'pullAt': true, + 'remove': true, + 'reverse': true + }, + 'object': { + 'assign': true, + 'assignIn': true, + 'assignInWith': true, + 'assignWith': true, + 'defaults': true, + 'defaultsDeep': true, + 'merge': true, + 'mergeWith': true + }, + 'set': { + 'set': true, + 'setWith': true, + 'unset': true, + 'update': true, + 'updateWith': true + } +}; + +/** Used to track methods with placeholder support */ +exports.placeholder = { + 'bind': true, + 'bindKey': true, + 'curry': true, + 'curryRight': true, + 'partial': true, + 'partialRight': true +}; + +/** Used to map real names to their aliases. */ +exports.realToAlias = (function() { + var hasOwnProperty = Object.prototype.hasOwnProperty, + object = exports.aliasToReal, + result = {}; + + for (var key in object) { + var value = object[key]; + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + } + return result; +}()); + +/** Used to map method names to other names. */ +exports.remap = { + 'curryN': 'curry', + 'curryRightN': 'curryRight', + 'getOr': 'get', + 'trimChars': 'trim', + 'trimCharsEnd': 'trimEnd', + 'trimCharsStart': 'trimStart' +}; + +/** Used to track methods that skip `_.rearg`. */ +exports.skipRearg = { + 'add': true, + 'assign': true, + 'assignIn': true, + 'concat': true, + 'difference': true, + 'gt': true, + 'gte': true, + 'lt': true, + 'lte': true, + 'matchesProperty': true, + 'merge': true, + 'partial': true, + 'partialRight': true, + 'random': true, + 'range': true, + 'rangeRight': true, + 'subtract': true, + 'zip': true, + 'zipObject': true +}; diff --git a/www/node_modules/lodash/fp/_util.js b/www/node_modules/lodash/fp/_util.js new file mode 100644 index 0000000..afa811b --- /dev/null +++ b/www/node_modules/lodash/fp/_util.js @@ -0,0 +1,13 @@ +module.exports = { + 'ary': require('../ary'), + 'clone': require('../clone'), + 'curry': require('../curry'), + 'forEach': require('../_arrayEach'), + 'isArray': require('../isArray'), + 'isFunction': require('../isFunction'), + 'iteratee': require('../iteratee'), + 'keys': require('../_baseKeys'), + 'rearg': require('../rearg'), + 'spread': require('../spread'), + 'toPath': require('../toPath') +}; diff --git a/www/node_modules/lodash/fp/add.js b/www/node_modules/lodash/fp/add.js new file mode 100644 index 0000000..c51b8fa --- /dev/null +++ b/www/node_modules/lodash/fp/add.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('add', require('../add')); diff --git a/www/node_modules/lodash/fp/after.js b/www/node_modules/lodash/fp/after.js new file mode 100644 index 0000000..83691b7 --- /dev/null +++ b/www/node_modules/lodash/fp/after.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('after', require('../after')); diff --git a/www/node_modules/lodash/fp/all.js b/www/node_modules/lodash/fp/all.js new file mode 100644 index 0000000..900ac25 --- /dev/null +++ b/www/node_modules/lodash/fp/all.js @@ -0,0 +1 @@ +module.exports = require('./some'); diff --git a/www/node_modules/lodash/fp/allPass.js b/www/node_modules/lodash/fp/allPass.js new file mode 100644 index 0000000..79b73ef --- /dev/null +++ b/www/node_modules/lodash/fp/allPass.js @@ -0,0 +1 @@ +module.exports = require('./overEvery'); diff --git a/www/node_modules/lodash/fp/apply.js b/www/node_modules/lodash/fp/apply.js new file mode 100644 index 0000000..2b75712 --- /dev/null +++ b/www/node_modules/lodash/fp/apply.js @@ -0,0 +1 @@ +module.exports = require('./spread'); diff --git a/www/node_modules/lodash/fp/array.js b/www/node_modules/lodash/fp/array.js new file mode 100644 index 0000000..fe939c2 --- /dev/null +++ b/www/node_modules/lodash/fp/array.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../array')); diff --git a/www/node_modules/lodash/fp/ary.js b/www/node_modules/lodash/fp/ary.js new file mode 100644 index 0000000..0f75d18 --- /dev/null +++ b/www/node_modules/lodash/fp/ary.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('ary', require('../ary')); diff --git a/www/node_modules/lodash/fp/assign.js b/www/node_modules/lodash/fp/assign.js new file mode 100644 index 0000000..ad02bcb --- /dev/null +++ b/www/node_modules/lodash/fp/assign.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('assign', require('../assign')); diff --git a/www/node_modules/lodash/fp/assignIn.js b/www/node_modules/lodash/fp/assignIn.js new file mode 100644 index 0000000..1ed4f0d --- /dev/null +++ b/www/node_modules/lodash/fp/assignIn.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('assignIn', require('../assignIn')); diff --git a/www/node_modules/lodash/fp/assignInWith.js b/www/node_modules/lodash/fp/assignInWith.js new file mode 100644 index 0000000..882145d --- /dev/null +++ b/www/node_modules/lodash/fp/assignInWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('assignInWith', require('../assignInWith')); diff --git a/www/node_modules/lodash/fp/assignWith.js b/www/node_modules/lodash/fp/assignWith.js new file mode 100644 index 0000000..1ff0527 --- /dev/null +++ b/www/node_modules/lodash/fp/assignWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('assignWith', require('../assignWith')); diff --git a/www/node_modules/lodash/fp/assoc.js b/www/node_modules/lodash/fp/assoc.js new file mode 100644 index 0000000..7648820 --- /dev/null +++ b/www/node_modules/lodash/fp/assoc.js @@ -0,0 +1 @@ +module.exports = require('./set'); diff --git a/www/node_modules/lodash/fp/assocPath.js b/www/node_modules/lodash/fp/assocPath.js new file mode 100644 index 0000000..7648820 --- /dev/null +++ b/www/node_modules/lodash/fp/assocPath.js @@ -0,0 +1 @@ +module.exports = require('./set'); diff --git a/www/node_modules/lodash/fp/at.js b/www/node_modules/lodash/fp/at.js new file mode 100644 index 0000000..5da3525 --- /dev/null +++ b/www/node_modules/lodash/fp/at.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('at', require('../at')); diff --git a/www/node_modules/lodash/fp/attempt.js b/www/node_modules/lodash/fp/attempt.js new file mode 100644 index 0000000..d8a3be5 --- /dev/null +++ b/www/node_modules/lodash/fp/attempt.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('attempt', require('../attempt')); diff --git a/www/node_modules/lodash/fp/before.js b/www/node_modules/lodash/fp/before.js new file mode 100644 index 0000000..f2954a6 --- /dev/null +++ b/www/node_modules/lodash/fp/before.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('before', require('../before')); diff --git a/www/node_modules/lodash/fp/bind.js b/www/node_modules/lodash/fp/bind.js new file mode 100644 index 0000000..e054a48 --- /dev/null +++ b/www/node_modules/lodash/fp/bind.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('bind', require('../bind')); diff --git a/www/node_modules/lodash/fp/bindAll.js b/www/node_modules/lodash/fp/bindAll.js new file mode 100644 index 0000000..495b75c --- /dev/null +++ b/www/node_modules/lodash/fp/bindAll.js @@ -0,0 +1 @@ +module.exports = require('../bindAll'); diff --git a/www/node_modules/lodash/fp/bindKey.js b/www/node_modules/lodash/fp/bindKey.js new file mode 100644 index 0000000..0b588c7 --- /dev/null +++ b/www/node_modules/lodash/fp/bindKey.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('bindKey', require('../bindKey')); diff --git a/www/node_modules/lodash/fp/camelCase.js b/www/node_modules/lodash/fp/camelCase.js new file mode 100644 index 0000000..328041e --- /dev/null +++ b/www/node_modules/lodash/fp/camelCase.js @@ -0,0 +1 @@ +module.exports = require('../camelCase'); diff --git a/www/node_modules/lodash/fp/capitalize.js b/www/node_modules/lodash/fp/capitalize.js new file mode 100644 index 0000000..186e6d9 --- /dev/null +++ b/www/node_modules/lodash/fp/capitalize.js @@ -0,0 +1 @@ +module.exports = require('../capitalize'); diff --git a/www/node_modules/lodash/fp/castArray.js b/www/node_modules/lodash/fp/castArray.js new file mode 100644 index 0000000..2a75bb9 --- /dev/null +++ b/www/node_modules/lodash/fp/castArray.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('castArray', require('../castArray')); diff --git a/www/node_modules/lodash/fp/ceil.js b/www/node_modules/lodash/fp/ceil.js new file mode 100644 index 0000000..7c3774b --- /dev/null +++ b/www/node_modules/lodash/fp/ceil.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('ceil', require('../ceil')); diff --git a/www/node_modules/lodash/fp/chain.js b/www/node_modules/lodash/fp/chain.js new file mode 100644 index 0000000..2f139cc --- /dev/null +++ b/www/node_modules/lodash/fp/chain.js @@ -0,0 +1 @@ +module.exports = require('../chain'); diff --git a/www/node_modules/lodash/fp/chunk.js b/www/node_modules/lodash/fp/chunk.js new file mode 100644 index 0000000..9d32b8a --- /dev/null +++ b/www/node_modules/lodash/fp/chunk.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('chunk', require('../chunk')); diff --git a/www/node_modules/lodash/fp/clamp.js b/www/node_modules/lodash/fp/clamp.js new file mode 100644 index 0000000..8ec3d9d --- /dev/null +++ b/www/node_modules/lodash/fp/clamp.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('clamp', require('../clamp')); diff --git a/www/node_modules/lodash/fp/clone.js b/www/node_modules/lodash/fp/clone.js new file mode 100644 index 0000000..afd2c15 --- /dev/null +++ b/www/node_modules/lodash/fp/clone.js @@ -0,0 +1 @@ +module.exports = require('../clone'); diff --git a/www/node_modules/lodash/fp/cloneDeep.js b/www/node_modules/lodash/fp/cloneDeep.js new file mode 100644 index 0000000..a17a6f8 --- /dev/null +++ b/www/node_modules/lodash/fp/cloneDeep.js @@ -0,0 +1 @@ +module.exports = require('../cloneDeep'); diff --git a/www/node_modules/lodash/fp/cloneDeepWith.js b/www/node_modules/lodash/fp/cloneDeepWith.js new file mode 100644 index 0000000..01c7fef --- /dev/null +++ b/www/node_modules/lodash/fp/cloneDeepWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('cloneDeepWith', require('../cloneDeepWith')); diff --git a/www/node_modules/lodash/fp/cloneWith.js b/www/node_modules/lodash/fp/cloneWith.js new file mode 100644 index 0000000..9e9d783 --- /dev/null +++ b/www/node_modules/lodash/fp/cloneWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('cloneWith', require('../cloneWith')); diff --git a/www/node_modules/lodash/fp/collection.js b/www/node_modules/lodash/fp/collection.js new file mode 100644 index 0000000..fc8b328 --- /dev/null +++ b/www/node_modules/lodash/fp/collection.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../collection')); diff --git a/www/node_modules/lodash/fp/commit.js b/www/node_modules/lodash/fp/commit.js new file mode 100644 index 0000000..04e9eb9 --- /dev/null +++ b/www/node_modules/lodash/fp/commit.js @@ -0,0 +1 @@ +module.exports = require('../commit'); diff --git a/www/node_modules/lodash/fp/compact.js b/www/node_modules/lodash/fp/compact.js new file mode 100644 index 0000000..b2ed9c7 --- /dev/null +++ b/www/node_modules/lodash/fp/compact.js @@ -0,0 +1 @@ +module.exports = require('../compact'); diff --git a/www/node_modules/lodash/fp/compose.js b/www/node_modules/lodash/fp/compose.js new file mode 100644 index 0000000..1954e94 --- /dev/null +++ b/www/node_modules/lodash/fp/compose.js @@ -0,0 +1 @@ +module.exports = require('./flowRight'); diff --git a/www/node_modules/lodash/fp/concat.js b/www/node_modules/lodash/fp/concat.js new file mode 100644 index 0000000..c13a92a --- /dev/null +++ b/www/node_modules/lodash/fp/concat.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('concat', require('../concat')); diff --git a/www/node_modules/lodash/fp/cond.js b/www/node_modules/lodash/fp/cond.js new file mode 100644 index 0000000..a150a89 --- /dev/null +++ b/www/node_modules/lodash/fp/cond.js @@ -0,0 +1 @@ +module.exports = require('../cond'); diff --git a/www/node_modules/lodash/fp/conforms.js b/www/node_modules/lodash/fp/conforms.js new file mode 100644 index 0000000..387dde1 --- /dev/null +++ b/www/node_modules/lodash/fp/conforms.js @@ -0,0 +1 @@ +module.exports = require('../conforms'); diff --git a/www/node_modules/lodash/fp/constant.js b/www/node_modules/lodash/fp/constant.js new file mode 100644 index 0000000..3bcd276 --- /dev/null +++ b/www/node_modules/lodash/fp/constant.js @@ -0,0 +1 @@ +module.exports = require('../constant'); diff --git a/www/node_modules/lodash/fp/contains.js b/www/node_modules/lodash/fp/contains.js new file mode 100644 index 0000000..594722a --- /dev/null +++ b/www/node_modules/lodash/fp/contains.js @@ -0,0 +1 @@ +module.exports = require('./includes'); diff --git a/www/node_modules/lodash/fp/convert.js b/www/node_modules/lodash/fp/convert.js new file mode 100644 index 0000000..a1d266f --- /dev/null +++ b/www/node_modules/lodash/fp/convert.js @@ -0,0 +1,17 @@ +var baseConvert = require('./_baseConvert'), + util = require('./_util'); + +/** + * Converts `func` of `name` to an immutable auto-curried iteratee-first data-last + * version. If `name` is an object its methods will be converted. + * + * @param {string} name The name of the function to wrap. + * @param {Function} [func] The function to wrap. + * @param {Object} [options] The options object. See `baseConvert` for more details. + * @returns {Function|Object} Returns the converted function or object. + */ +function convert(name, func, options) { + return baseConvert(util, name, func, options); +} + +module.exports = convert; diff --git a/www/node_modules/lodash/fp/countBy.js b/www/node_modules/lodash/fp/countBy.js new file mode 100644 index 0000000..ee4b942 --- /dev/null +++ b/www/node_modules/lodash/fp/countBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('countBy', require('../countBy')); diff --git a/www/node_modules/lodash/fp/create.js b/www/node_modules/lodash/fp/create.js new file mode 100644 index 0000000..bdad771 --- /dev/null +++ b/www/node_modules/lodash/fp/create.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('create', require('../create')); diff --git a/www/node_modules/lodash/fp/curry.js b/www/node_modules/lodash/fp/curry.js new file mode 100644 index 0000000..d64722c --- /dev/null +++ b/www/node_modules/lodash/fp/curry.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('curry', require('../curry')); diff --git a/www/node_modules/lodash/fp/curryN.js b/www/node_modules/lodash/fp/curryN.js new file mode 100644 index 0000000..f33f7fc --- /dev/null +++ b/www/node_modules/lodash/fp/curryN.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('curryN', require('../curry')); diff --git a/www/node_modules/lodash/fp/curryRight.js b/www/node_modules/lodash/fp/curryRight.js new file mode 100644 index 0000000..2e04709 --- /dev/null +++ b/www/node_modules/lodash/fp/curryRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('curryRight', require('../curryRight')); diff --git a/www/node_modules/lodash/fp/curryRightN.js b/www/node_modules/lodash/fp/curryRightN.js new file mode 100644 index 0000000..510e4e4 --- /dev/null +++ b/www/node_modules/lodash/fp/curryRightN.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('curryRightN', require('../curryRight')); diff --git a/www/node_modules/lodash/fp/date.js b/www/node_modules/lodash/fp/date.js new file mode 100644 index 0000000..82cb952 --- /dev/null +++ b/www/node_modules/lodash/fp/date.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../date')); diff --git a/www/node_modules/lodash/fp/debounce.js b/www/node_modules/lodash/fp/debounce.js new file mode 100644 index 0000000..a6b0407 --- /dev/null +++ b/www/node_modules/lodash/fp/debounce.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('debounce', require('../debounce')); diff --git a/www/node_modules/lodash/fp/deburr.js b/www/node_modules/lodash/fp/deburr.js new file mode 100644 index 0000000..f8e1a49 --- /dev/null +++ b/www/node_modules/lodash/fp/deburr.js @@ -0,0 +1 @@ +module.exports = require('../deburr'); diff --git a/www/node_modules/lodash/fp/defaults.js b/www/node_modules/lodash/fp/defaults.js new file mode 100644 index 0000000..7c3b3ab --- /dev/null +++ b/www/node_modules/lodash/fp/defaults.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('defaults', require('../defaults')); diff --git a/www/node_modules/lodash/fp/defaultsDeep.js b/www/node_modules/lodash/fp/defaultsDeep.js new file mode 100644 index 0000000..c7480e2 --- /dev/null +++ b/www/node_modules/lodash/fp/defaultsDeep.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('defaultsDeep', require('../defaultsDeep')); diff --git a/www/node_modules/lodash/fp/defer.js b/www/node_modules/lodash/fp/defer.js new file mode 100644 index 0000000..4126727 --- /dev/null +++ b/www/node_modules/lodash/fp/defer.js @@ -0,0 +1 @@ +module.exports = require('../defer'); diff --git a/www/node_modules/lodash/fp/delay.js b/www/node_modules/lodash/fp/delay.js new file mode 100644 index 0000000..cd3b1c3 --- /dev/null +++ b/www/node_modules/lodash/fp/delay.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('delay', require('../delay')); diff --git a/www/node_modules/lodash/fp/difference.js b/www/node_modules/lodash/fp/difference.js new file mode 100644 index 0000000..aea9ab8 --- /dev/null +++ b/www/node_modules/lodash/fp/difference.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('difference', require('../difference')); diff --git a/www/node_modules/lodash/fp/differenceBy.js b/www/node_modules/lodash/fp/differenceBy.js new file mode 100644 index 0000000..ab65554 --- /dev/null +++ b/www/node_modules/lodash/fp/differenceBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('differenceBy', require('../differenceBy')); diff --git a/www/node_modules/lodash/fp/differenceWith.js b/www/node_modules/lodash/fp/differenceWith.js new file mode 100644 index 0000000..f932a2e --- /dev/null +++ b/www/node_modules/lodash/fp/differenceWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('differenceWith', require('../differenceWith')); diff --git a/www/node_modules/lodash/fp/dissoc.js b/www/node_modules/lodash/fp/dissoc.js new file mode 100644 index 0000000..7ec7be1 --- /dev/null +++ b/www/node_modules/lodash/fp/dissoc.js @@ -0,0 +1 @@ +module.exports = require('./unset'); diff --git a/www/node_modules/lodash/fp/dissocPath.js b/www/node_modules/lodash/fp/dissocPath.js new file mode 100644 index 0000000..7ec7be1 --- /dev/null +++ b/www/node_modules/lodash/fp/dissocPath.js @@ -0,0 +1 @@ +module.exports = require('./unset'); diff --git a/www/node_modules/lodash/fp/drop.js b/www/node_modules/lodash/fp/drop.js new file mode 100644 index 0000000..ccca2d0 --- /dev/null +++ b/www/node_modules/lodash/fp/drop.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('drop', require('../drop')); diff --git a/www/node_modules/lodash/fp/dropRight.js b/www/node_modules/lodash/fp/dropRight.js new file mode 100644 index 0000000..bd9a2bd --- /dev/null +++ b/www/node_modules/lodash/fp/dropRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('dropRight', require('../dropRight')); diff --git a/www/node_modules/lodash/fp/dropRightWhile.js b/www/node_modules/lodash/fp/dropRightWhile.js new file mode 100644 index 0000000..2dbb2a3 --- /dev/null +++ b/www/node_modules/lodash/fp/dropRightWhile.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('dropRightWhile', require('../dropRightWhile')); diff --git a/www/node_modules/lodash/fp/dropWhile.js b/www/node_modules/lodash/fp/dropWhile.js new file mode 100644 index 0000000..17e46ff --- /dev/null +++ b/www/node_modules/lodash/fp/dropWhile.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('dropWhile', require('../dropWhile')); diff --git a/www/node_modules/lodash/fp/each.js b/www/node_modules/lodash/fp/each.js new file mode 100644 index 0000000..8800f42 --- /dev/null +++ b/www/node_modules/lodash/fp/each.js @@ -0,0 +1 @@ +module.exports = require('./forEach'); diff --git a/www/node_modules/lodash/fp/eachRight.js b/www/node_modules/lodash/fp/eachRight.js new file mode 100644 index 0000000..3252b2a --- /dev/null +++ b/www/node_modules/lodash/fp/eachRight.js @@ -0,0 +1 @@ +module.exports = require('./forEachRight'); diff --git a/www/node_modules/lodash/fp/endsWith.js b/www/node_modules/lodash/fp/endsWith.js new file mode 100644 index 0000000..cbe8f8c --- /dev/null +++ b/www/node_modules/lodash/fp/endsWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('endsWith', require('../endsWith')); diff --git a/www/node_modules/lodash/fp/eq.js b/www/node_modules/lodash/fp/eq.js new file mode 100644 index 0000000..518a54d --- /dev/null +++ b/www/node_modules/lodash/fp/eq.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('eq', require('../eq')); diff --git a/www/node_modules/lodash/fp/equals.js b/www/node_modules/lodash/fp/equals.js new file mode 100644 index 0000000..e6a5ce0 --- /dev/null +++ b/www/node_modules/lodash/fp/equals.js @@ -0,0 +1 @@ +module.exports = require('./isEqual'); diff --git a/www/node_modules/lodash/fp/escape.js b/www/node_modules/lodash/fp/escape.js new file mode 100644 index 0000000..e5de9f2 --- /dev/null +++ b/www/node_modules/lodash/fp/escape.js @@ -0,0 +1 @@ +module.exports = require('../escape'); diff --git a/www/node_modules/lodash/fp/escapeRegExp.js b/www/node_modules/lodash/fp/escapeRegExp.js new file mode 100644 index 0000000..ab18963 --- /dev/null +++ b/www/node_modules/lodash/fp/escapeRegExp.js @@ -0,0 +1 @@ +module.exports = require('../escapeRegExp'); diff --git a/www/node_modules/lodash/fp/every.js b/www/node_modules/lodash/fp/every.js new file mode 100644 index 0000000..965f889 --- /dev/null +++ b/www/node_modules/lodash/fp/every.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('every', require('../every')); diff --git a/www/node_modules/lodash/fp/extend.js b/www/node_modules/lodash/fp/extend.js new file mode 100644 index 0000000..e00166c --- /dev/null +++ b/www/node_modules/lodash/fp/extend.js @@ -0,0 +1 @@ +module.exports = require('./assignIn'); diff --git a/www/node_modules/lodash/fp/extendWith.js b/www/node_modules/lodash/fp/extendWith.js new file mode 100644 index 0000000..dbdcb3b --- /dev/null +++ b/www/node_modules/lodash/fp/extendWith.js @@ -0,0 +1 @@ +module.exports = require('./assignInWith'); diff --git a/www/node_modules/lodash/fp/fill.js b/www/node_modules/lodash/fp/fill.js new file mode 100644 index 0000000..e16f8bf --- /dev/null +++ b/www/node_modules/lodash/fp/fill.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('fill', require('../fill')); diff --git a/www/node_modules/lodash/fp/filter.js b/www/node_modules/lodash/fp/filter.js new file mode 100644 index 0000000..7191a82 --- /dev/null +++ b/www/node_modules/lodash/fp/filter.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('filter', require('../filter')); diff --git a/www/node_modules/lodash/fp/find.js b/www/node_modules/lodash/fp/find.js new file mode 100644 index 0000000..5915bbd --- /dev/null +++ b/www/node_modules/lodash/fp/find.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('find', require('../find')); diff --git a/www/node_modules/lodash/fp/findIndex.js b/www/node_modules/lodash/fp/findIndex.js new file mode 100644 index 0000000..6bf435c --- /dev/null +++ b/www/node_modules/lodash/fp/findIndex.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('findIndex', require('../findIndex')); diff --git a/www/node_modules/lodash/fp/findKey.js b/www/node_modules/lodash/fp/findKey.js new file mode 100644 index 0000000..3ff9844 --- /dev/null +++ b/www/node_modules/lodash/fp/findKey.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('findKey', require('../findKey')); diff --git a/www/node_modules/lodash/fp/findLast.js b/www/node_modules/lodash/fp/findLast.js new file mode 100644 index 0000000..31e169b --- /dev/null +++ b/www/node_modules/lodash/fp/findLast.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('findLast', require('../findLast')); diff --git a/www/node_modules/lodash/fp/findLastIndex.js b/www/node_modules/lodash/fp/findLastIndex.js new file mode 100644 index 0000000..db41e88 --- /dev/null +++ b/www/node_modules/lodash/fp/findLastIndex.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('findLastIndex', require('../findLastIndex')); diff --git a/www/node_modules/lodash/fp/findLastKey.js b/www/node_modules/lodash/fp/findLastKey.js new file mode 100644 index 0000000..ffe9e2a --- /dev/null +++ b/www/node_modules/lodash/fp/findLastKey.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('findLastKey', require('../findLastKey')); diff --git a/www/node_modules/lodash/fp/first.js b/www/node_modules/lodash/fp/first.js new file mode 100644 index 0000000..53f4ad1 --- /dev/null +++ b/www/node_modules/lodash/fp/first.js @@ -0,0 +1 @@ +module.exports = require('./head'); diff --git a/www/node_modules/lodash/fp/flatMap.js b/www/node_modules/lodash/fp/flatMap.js new file mode 100644 index 0000000..da249a8 --- /dev/null +++ b/www/node_modules/lodash/fp/flatMap.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('flatMap', require('../flatMap')); diff --git a/www/node_modules/lodash/fp/flatten.js b/www/node_modules/lodash/fp/flatten.js new file mode 100644 index 0000000..f1c1a62 --- /dev/null +++ b/www/node_modules/lodash/fp/flatten.js @@ -0,0 +1 @@ +module.exports = require('../flatten'); diff --git a/www/node_modules/lodash/fp/flattenDeep.js b/www/node_modules/lodash/fp/flattenDeep.js new file mode 100644 index 0000000..c2ff987 --- /dev/null +++ b/www/node_modules/lodash/fp/flattenDeep.js @@ -0,0 +1 @@ +module.exports = require('../flattenDeep'); diff --git a/www/node_modules/lodash/fp/flattenDepth.js b/www/node_modules/lodash/fp/flattenDepth.js new file mode 100644 index 0000000..731e27a --- /dev/null +++ b/www/node_modules/lodash/fp/flattenDepth.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('flattenDepth', require('../flattenDepth')); diff --git a/www/node_modules/lodash/fp/flip.js b/www/node_modules/lodash/fp/flip.js new file mode 100644 index 0000000..730bbd1 --- /dev/null +++ b/www/node_modules/lodash/fp/flip.js @@ -0,0 +1 @@ +module.exports = require('../flip'); diff --git a/www/node_modules/lodash/fp/floor.js b/www/node_modules/lodash/fp/floor.js new file mode 100644 index 0000000..f130f8b --- /dev/null +++ b/www/node_modules/lodash/fp/floor.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('floor', require('../floor')); diff --git a/www/node_modules/lodash/fp/flow.js b/www/node_modules/lodash/fp/flow.js new file mode 100644 index 0000000..d9943c6 --- /dev/null +++ b/www/node_modules/lodash/fp/flow.js @@ -0,0 +1 @@ +module.exports = require('../flow'); diff --git a/www/node_modules/lodash/fp/flowRight.js b/www/node_modules/lodash/fp/flowRight.js new file mode 100644 index 0000000..556dc37 --- /dev/null +++ b/www/node_modules/lodash/fp/flowRight.js @@ -0,0 +1 @@ +module.exports = require('../flowRight'); diff --git a/www/node_modules/lodash/fp/forEach.js b/www/node_modules/lodash/fp/forEach.js new file mode 100644 index 0000000..d715ea6 --- /dev/null +++ b/www/node_modules/lodash/fp/forEach.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forEach', require('../forEach')); diff --git a/www/node_modules/lodash/fp/forEachRight.js b/www/node_modules/lodash/fp/forEachRight.js new file mode 100644 index 0000000..90dd8dd --- /dev/null +++ b/www/node_modules/lodash/fp/forEachRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forEachRight', require('../forEachRight')); diff --git a/www/node_modules/lodash/fp/forIn.js b/www/node_modules/lodash/fp/forIn.js new file mode 100644 index 0000000..90a8f07 --- /dev/null +++ b/www/node_modules/lodash/fp/forIn.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forIn', require('../forIn')); diff --git a/www/node_modules/lodash/fp/forInRight.js b/www/node_modules/lodash/fp/forInRight.js new file mode 100644 index 0000000..505258f --- /dev/null +++ b/www/node_modules/lodash/fp/forInRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forInRight', require('../forInRight')); diff --git a/www/node_modules/lodash/fp/forOwn.js b/www/node_modules/lodash/fp/forOwn.js new file mode 100644 index 0000000..6fef1e3 --- /dev/null +++ b/www/node_modules/lodash/fp/forOwn.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forOwn', require('../forOwn')); diff --git a/www/node_modules/lodash/fp/forOwnRight.js b/www/node_modules/lodash/fp/forOwnRight.js new file mode 100644 index 0000000..11ff1fd --- /dev/null +++ b/www/node_modules/lodash/fp/forOwnRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('forOwnRight', require('../forOwnRight')); diff --git a/www/node_modules/lodash/fp/fromPairs.js b/www/node_modules/lodash/fp/fromPairs.js new file mode 100644 index 0000000..f5c3cb8 --- /dev/null +++ b/www/node_modules/lodash/fp/fromPairs.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('fromPairs', require('../fromPairs')); diff --git a/www/node_modules/lodash/fp/function.js b/www/node_modules/lodash/fp/function.js new file mode 100644 index 0000000..dfe69b1 --- /dev/null +++ b/www/node_modules/lodash/fp/function.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../function')); diff --git a/www/node_modules/lodash/fp/functions.js b/www/node_modules/lodash/fp/functions.js new file mode 100644 index 0000000..bb1cb93 --- /dev/null +++ b/www/node_modules/lodash/fp/functions.js @@ -0,0 +1 @@ +module.exports = require('../functions'); diff --git a/www/node_modules/lodash/fp/functionsIn.js b/www/node_modules/lodash/fp/functionsIn.js new file mode 100644 index 0000000..d375213 --- /dev/null +++ b/www/node_modules/lodash/fp/functionsIn.js @@ -0,0 +1 @@ +module.exports = require('../functionsIn'); diff --git a/www/node_modules/lodash/fp/get.js b/www/node_modules/lodash/fp/get.js new file mode 100644 index 0000000..a054c9d --- /dev/null +++ b/www/node_modules/lodash/fp/get.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('get', require('../get')); diff --git a/www/node_modules/lodash/fp/getOr.js b/www/node_modules/lodash/fp/getOr.js new file mode 100644 index 0000000..c46f2e9 --- /dev/null +++ b/www/node_modules/lodash/fp/getOr.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('getOr', require('../get')); diff --git a/www/node_modules/lodash/fp/groupBy.js b/www/node_modules/lodash/fp/groupBy.js new file mode 100644 index 0000000..6588856 --- /dev/null +++ b/www/node_modules/lodash/fp/groupBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('groupBy', require('../groupBy')); diff --git a/www/node_modules/lodash/fp/gt.js b/www/node_modules/lodash/fp/gt.js new file mode 100644 index 0000000..5b92de9 --- /dev/null +++ b/www/node_modules/lodash/fp/gt.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('gt', require('../gt')); diff --git a/www/node_modules/lodash/fp/gte.js b/www/node_modules/lodash/fp/gte.js new file mode 100644 index 0000000..3a40250 --- /dev/null +++ b/www/node_modules/lodash/fp/gte.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('gte', require('../gte')); diff --git a/www/node_modules/lodash/fp/has.js b/www/node_modules/lodash/fp/has.js new file mode 100644 index 0000000..e37db9a --- /dev/null +++ b/www/node_modules/lodash/fp/has.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('has', require('../has')); diff --git a/www/node_modules/lodash/fp/hasIn.js b/www/node_modules/lodash/fp/hasIn.js new file mode 100644 index 0000000..84d7815 --- /dev/null +++ b/www/node_modules/lodash/fp/hasIn.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('hasIn', require('../hasIn')); diff --git a/www/node_modules/lodash/fp/head.js b/www/node_modules/lodash/fp/head.js new file mode 100644 index 0000000..bd97a7b --- /dev/null +++ b/www/node_modules/lodash/fp/head.js @@ -0,0 +1 @@ +module.exports = require('../head'); diff --git a/www/node_modules/lodash/fp/identity.js b/www/node_modules/lodash/fp/identity.js new file mode 100644 index 0000000..6d007dc --- /dev/null +++ b/www/node_modules/lodash/fp/identity.js @@ -0,0 +1 @@ +module.exports = require('../identity'); diff --git a/www/node_modules/lodash/fp/inRange.js b/www/node_modules/lodash/fp/inRange.js new file mode 100644 index 0000000..fc55e1c --- /dev/null +++ b/www/node_modules/lodash/fp/inRange.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('inRange', require('../inRange')); diff --git a/www/node_modules/lodash/fp/includes.js b/www/node_modules/lodash/fp/includes.js new file mode 100644 index 0000000..91f1eec --- /dev/null +++ b/www/node_modules/lodash/fp/includes.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('includes', require('../includes')); diff --git a/www/node_modules/lodash/fp/indexOf.js b/www/node_modules/lodash/fp/indexOf.js new file mode 100644 index 0000000..65345ce --- /dev/null +++ b/www/node_modules/lodash/fp/indexOf.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('indexOf', require('../indexOf')); diff --git a/www/node_modules/lodash/fp/init.js b/www/node_modules/lodash/fp/init.js new file mode 100644 index 0000000..2f88d8b --- /dev/null +++ b/www/node_modules/lodash/fp/init.js @@ -0,0 +1 @@ +module.exports = require('./initial'); diff --git a/www/node_modules/lodash/fp/initial.js b/www/node_modules/lodash/fp/initial.js new file mode 100644 index 0000000..9fc94e0 --- /dev/null +++ b/www/node_modules/lodash/fp/initial.js @@ -0,0 +1 @@ +module.exports = require('../initial'); diff --git a/www/node_modules/lodash/fp/intersection.js b/www/node_modules/lodash/fp/intersection.js new file mode 100644 index 0000000..784f4d1 --- /dev/null +++ b/www/node_modules/lodash/fp/intersection.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('intersection', require('../intersection')); diff --git a/www/node_modules/lodash/fp/intersectionBy.js b/www/node_modules/lodash/fp/intersectionBy.js new file mode 100644 index 0000000..4aa93b6 --- /dev/null +++ b/www/node_modules/lodash/fp/intersectionBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('intersectionBy', require('../intersectionBy')); diff --git a/www/node_modules/lodash/fp/intersectionWith.js b/www/node_modules/lodash/fp/intersectionWith.js new file mode 100644 index 0000000..879fe9d --- /dev/null +++ b/www/node_modules/lodash/fp/intersectionWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('intersectionWith', require('../intersectionWith')); diff --git a/www/node_modules/lodash/fp/invert.js b/www/node_modules/lodash/fp/invert.js new file mode 100644 index 0000000..231d5ca --- /dev/null +++ b/www/node_modules/lodash/fp/invert.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('invert', require('../invert')); diff --git a/www/node_modules/lodash/fp/invertBy.js b/www/node_modules/lodash/fp/invertBy.js new file mode 100644 index 0000000..90820e6 --- /dev/null +++ b/www/node_modules/lodash/fp/invertBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('invertBy', require('../invertBy')); diff --git a/www/node_modules/lodash/fp/invoke.js b/www/node_modules/lodash/fp/invoke.js new file mode 100644 index 0000000..a8635e8 --- /dev/null +++ b/www/node_modules/lodash/fp/invoke.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('invoke', require('../invoke')); diff --git a/www/node_modules/lodash/fp/invokeMap.js b/www/node_modules/lodash/fp/invokeMap.js new file mode 100644 index 0000000..2691ae3 --- /dev/null +++ b/www/node_modules/lodash/fp/invokeMap.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('invokeMap', require('../invokeMap')); diff --git a/www/node_modules/lodash/fp/isArguments.js b/www/node_modules/lodash/fp/isArguments.js new file mode 100644 index 0000000..093aa35 --- /dev/null +++ b/www/node_modules/lodash/fp/isArguments.js @@ -0,0 +1 @@ +module.exports = require('../isArguments'); diff --git a/www/node_modules/lodash/fp/isArray.js b/www/node_modules/lodash/fp/isArray.js new file mode 100644 index 0000000..ec7fad3 --- /dev/null +++ b/www/node_modules/lodash/fp/isArray.js @@ -0,0 +1 @@ +module.exports = require('../isArray'); diff --git a/www/node_modules/lodash/fp/isArrayBuffer.js b/www/node_modules/lodash/fp/isArrayBuffer.js new file mode 100644 index 0000000..655e85b --- /dev/null +++ b/www/node_modules/lodash/fp/isArrayBuffer.js @@ -0,0 +1 @@ +module.exports = require('../isArrayBuffer'); diff --git a/www/node_modules/lodash/fp/isArrayLike.js b/www/node_modules/lodash/fp/isArrayLike.js new file mode 100644 index 0000000..1595b2f --- /dev/null +++ b/www/node_modules/lodash/fp/isArrayLike.js @@ -0,0 +1 @@ +module.exports = require('../isArrayLike'); diff --git a/www/node_modules/lodash/fp/isArrayLikeObject.js b/www/node_modules/lodash/fp/isArrayLikeObject.js new file mode 100644 index 0000000..4d1d202 --- /dev/null +++ b/www/node_modules/lodash/fp/isArrayLikeObject.js @@ -0,0 +1 @@ +module.exports = require('../isArrayLikeObject'); diff --git a/www/node_modules/lodash/fp/isBoolean.js b/www/node_modules/lodash/fp/isBoolean.js new file mode 100644 index 0000000..30d4a4a --- /dev/null +++ b/www/node_modules/lodash/fp/isBoolean.js @@ -0,0 +1 @@ +module.exports = require('../isBoolean'); diff --git a/www/node_modules/lodash/fp/isBuffer.js b/www/node_modules/lodash/fp/isBuffer.js new file mode 100644 index 0000000..15af9b6 --- /dev/null +++ b/www/node_modules/lodash/fp/isBuffer.js @@ -0,0 +1 @@ +module.exports = require('../isBuffer'); diff --git a/www/node_modules/lodash/fp/isDate.js b/www/node_modules/lodash/fp/isDate.js new file mode 100644 index 0000000..ac002f4 --- /dev/null +++ b/www/node_modules/lodash/fp/isDate.js @@ -0,0 +1 @@ +module.exports = require('../isDate'); diff --git a/www/node_modules/lodash/fp/isElement.js b/www/node_modules/lodash/fp/isElement.js new file mode 100644 index 0000000..458a348 --- /dev/null +++ b/www/node_modules/lodash/fp/isElement.js @@ -0,0 +1 @@ +module.exports = require('../isElement'); diff --git a/www/node_modules/lodash/fp/isEmpty.js b/www/node_modules/lodash/fp/isEmpty.js new file mode 100644 index 0000000..b1a04cd --- /dev/null +++ b/www/node_modules/lodash/fp/isEmpty.js @@ -0,0 +1 @@ +module.exports = require('../isEmpty'); diff --git a/www/node_modules/lodash/fp/isEqual.js b/www/node_modules/lodash/fp/isEqual.js new file mode 100644 index 0000000..91b7d66 --- /dev/null +++ b/www/node_modules/lodash/fp/isEqual.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('isEqual', require('../isEqual')); diff --git a/www/node_modules/lodash/fp/isEqualWith.js b/www/node_modules/lodash/fp/isEqualWith.js new file mode 100644 index 0000000..37a6e35 --- /dev/null +++ b/www/node_modules/lodash/fp/isEqualWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('isEqualWith', require('../isEqualWith')); diff --git a/www/node_modules/lodash/fp/isError.js b/www/node_modules/lodash/fp/isError.js new file mode 100644 index 0000000..da2710c --- /dev/null +++ b/www/node_modules/lodash/fp/isError.js @@ -0,0 +1 @@ +module.exports = require('../isError'); diff --git a/www/node_modules/lodash/fp/isFinite.js b/www/node_modules/lodash/fp/isFinite.js new file mode 100644 index 0000000..a71e53d --- /dev/null +++ b/www/node_modules/lodash/fp/isFinite.js @@ -0,0 +1 @@ +module.exports = require('../isFinite'); diff --git a/www/node_modules/lodash/fp/isFunction.js b/www/node_modules/lodash/fp/isFunction.js new file mode 100644 index 0000000..1fc73f6 --- /dev/null +++ b/www/node_modules/lodash/fp/isFunction.js @@ -0,0 +1 @@ +module.exports = require('../isFunction'); diff --git a/www/node_modules/lodash/fp/isInteger.js b/www/node_modules/lodash/fp/isInteger.js new file mode 100644 index 0000000..f990b01 --- /dev/null +++ b/www/node_modules/lodash/fp/isInteger.js @@ -0,0 +1 @@ +module.exports = require('../isInteger'); diff --git a/www/node_modules/lodash/fp/isLength.js b/www/node_modules/lodash/fp/isLength.js new file mode 100644 index 0000000..f40c362 --- /dev/null +++ b/www/node_modules/lodash/fp/isLength.js @@ -0,0 +1 @@ +module.exports = require('../isLength'); diff --git a/www/node_modules/lodash/fp/isMap.js b/www/node_modules/lodash/fp/isMap.js new file mode 100644 index 0000000..51fb7e2 --- /dev/null +++ b/www/node_modules/lodash/fp/isMap.js @@ -0,0 +1 @@ +module.exports = require('../isMap'); diff --git a/www/node_modules/lodash/fp/isMatch.js b/www/node_modules/lodash/fp/isMatch.js new file mode 100644 index 0000000..749c903 --- /dev/null +++ b/www/node_modules/lodash/fp/isMatch.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('isMatch', require('../isMatch')); diff --git a/www/node_modules/lodash/fp/isMatchWith.js b/www/node_modules/lodash/fp/isMatchWith.js new file mode 100644 index 0000000..b1311fc --- /dev/null +++ b/www/node_modules/lodash/fp/isMatchWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('isMatchWith', require('../isMatchWith')); diff --git a/www/node_modules/lodash/fp/isNaN.js b/www/node_modules/lodash/fp/isNaN.js new file mode 100644 index 0000000..74daf0a --- /dev/null +++ b/www/node_modules/lodash/fp/isNaN.js @@ -0,0 +1 @@ +module.exports = require('../isNaN'); diff --git a/www/node_modules/lodash/fp/isNative.js b/www/node_modules/lodash/fp/isNative.js new file mode 100644 index 0000000..9eeded4 --- /dev/null +++ b/www/node_modules/lodash/fp/isNative.js @@ -0,0 +1 @@ +module.exports = require('../isNative'); diff --git a/www/node_modules/lodash/fp/isNil.js b/www/node_modules/lodash/fp/isNil.js new file mode 100644 index 0000000..beace9d --- /dev/null +++ b/www/node_modules/lodash/fp/isNil.js @@ -0,0 +1 @@ +module.exports = require('../isNil'); diff --git a/www/node_modules/lodash/fp/isNull.js b/www/node_modules/lodash/fp/isNull.js new file mode 100644 index 0000000..44689a7 --- /dev/null +++ b/www/node_modules/lodash/fp/isNull.js @@ -0,0 +1 @@ +module.exports = require('../isNull'); diff --git a/www/node_modules/lodash/fp/isNumber.js b/www/node_modules/lodash/fp/isNumber.js new file mode 100644 index 0000000..d7e8615 --- /dev/null +++ b/www/node_modules/lodash/fp/isNumber.js @@ -0,0 +1 @@ +module.exports = require('../isNumber'); diff --git a/www/node_modules/lodash/fp/isObject.js b/www/node_modules/lodash/fp/isObject.js new file mode 100644 index 0000000..bb48630 --- /dev/null +++ b/www/node_modules/lodash/fp/isObject.js @@ -0,0 +1 @@ +module.exports = require('../isObject'); diff --git a/www/node_modules/lodash/fp/isObjectLike.js b/www/node_modules/lodash/fp/isObjectLike.js new file mode 100644 index 0000000..5ef6f62 --- /dev/null +++ b/www/node_modules/lodash/fp/isObjectLike.js @@ -0,0 +1 @@ +module.exports = require('../isObjectLike'); diff --git a/www/node_modules/lodash/fp/isPlainObject.js b/www/node_modules/lodash/fp/isPlainObject.js new file mode 100644 index 0000000..2d34d86 --- /dev/null +++ b/www/node_modules/lodash/fp/isPlainObject.js @@ -0,0 +1 @@ +module.exports = require('../isPlainObject'); diff --git a/www/node_modules/lodash/fp/isRegExp.js b/www/node_modules/lodash/fp/isRegExp.js new file mode 100644 index 0000000..4d0727b --- /dev/null +++ b/www/node_modules/lodash/fp/isRegExp.js @@ -0,0 +1 @@ +module.exports = require('../isRegExp'); diff --git a/www/node_modules/lodash/fp/isSafeInteger.js b/www/node_modules/lodash/fp/isSafeInteger.js new file mode 100644 index 0000000..ed08cab --- /dev/null +++ b/www/node_modules/lodash/fp/isSafeInteger.js @@ -0,0 +1 @@ +module.exports = require('../isSafeInteger'); diff --git a/www/node_modules/lodash/fp/isSet.js b/www/node_modules/lodash/fp/isSet.js new file mode 100644 index 0000000..f8a0a49 --- /dev/null +++ b/www/node_modules/lodash/fp/isSet.js @@ -0,0 +1 @@ +module.exports = require('../isSet'); diff --git a/www/node_modules/lodash/fp/isString.js b/www/node_modules/lodash/fp/isString.js new file mode 100644 index 0000000..2f22d0e --- /dev/null +++ b/www/node_modules/lodash/fp/isString.js @@ -0,0 +1 @@ +module.exports = require('../isString'); diff --git a/www/node_modules/lodash/fp/isSymbol.js b/www/node_modules/lodash/fp/isSymbol.js new file mode 100644 index 0000000..9ce6731 --- /dev/null +++ b/www/node_modules/lodash/fp/isSymbol.js @@ -0,0 +1 @@ +module.exports = require('../isSymbol'); diff --git a/www/node_modules/lodash/fp/isTypedArray.js b/www/node_modules/lodash/fp/isTypedArray.js new file mode 100644 index 0000000..72349c5 --- /dev/null +++ b/www/node_modules/lodash/fp/isTypedArray.js @@ -0,0 +1 @@ +module.exports = require('../isTypedArray'); diff --git a/www/node_modules/lodash/fp/isUndefined.js b/www/node_modules/lodash/fp/isUndefined.js new file mode 100644 index 0000000..a65c5be --- /dev/null +++ b/www/node_modules/lodash/fp/isUndefined.js @@ -0,0 +1 @@ +module.exports = require('../isUndefined'); diff --git a/www/node_modules/lodash/fp/isWeakMap.js b/www/node_modules/lodash/fp/isWeakMap.js new file mode 100644 index 0000000..dc62201 --- /dev/null +++ b/www/node_modules/lodash/fp/isWeakMap.js @@ -0,0 +1 @@ +module.exports = require('../isWeakMap'); diff --git a/www/node_modules/lodash/fp/isWeakSet.js b/www/node_modules/lodash/fp/isWeakSet.js new file mode 100644 index 0000000..7646ca8 --- /dev/null +++ b/www/node_modules/lodash/fp/isWeakSet.js @@ -0,0 +1 @@ +module.exports = require('../isWeakSet'); diff --git a/www/node_modules/lodash/fp/iteratee.js b/www/node_modules/lodash/fp/iteratee.js new file mode 100644 index 0000000..2884465 --- /dev/null +++ b/www/node_modules/lodash/fp/iteratee.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('iteratee', require('../iteratee')); diff --git a/www/node_modules/lodash/fp/join.js b/www/node_modules/lodash/fp/join.js new file mode 100644 index 0000000..fdaa488 --- /dev/null +++ b/www/node_modules/lodash/fp/join.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('join', require('../join')); diff --git a/www/node_modules/lodash/fp/kebabCase.js b/www/node_modules/lodash/fp/kebabCase.js new file mode 100644 index 0000000..f251a4d --- /dev/null +++ b/www/node_modules/lodash/fp/kebabCase.js @@ -0,0 +1 @@ +module.exports = require('../kebabCase'); diff --git a/www/node_modules/lodash/fp/keyBy.js b/www/node_modules/lodash/fp/keyBy.js new file mode 100644 index 0000000..ad9abac --- /dev/null +++ b/www/node_modules/lodash/fp/keyBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('keyBy', require('../keyBy')); diff --git a/www/node_modules/lodash/fp/keys.js b/www/node_modules/lodash/fp/keys.js new file mode 100644 index 0000000..23dc6b7 --- /dev/null +++ b/www/node_modules/lodash/fp/keys.js @@ -0,0 +1 @@ +module.exports = require('../keys'); diff --git a/www/node_modules/lodash/fp/keysIn.js b/www/node_modules/lodash/fp/keysIn.js new file mode 100644 index 0000000..2b738b9 --- /dev/null +++ b/www/node_modules/lodash/fp/keysIn.js @@ -0,0 +1 @@ +module.exports = require('../keysIn'); diff --git a/www/node_modules/lodash/fp/lang.js b/www/node_modules/lodash/fp/lang.js new file mode 100644 index 0000000..08cc9c1 --- /dev/null +++ b/www/node_modules/lodash/fp/lang.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../lang')); diff --git a/www/node_modules/lodash/fp/last.js b/www/node_modules/lodash/fp/last.js new file mode 100644 index 0000000..222be23 --- /dev/null +++ b/www/node_modules/lodash/fp/last.js @@ -0,0 +1 @@ +module.exports = require('../last'); diff --git a/www/node_modules/lodash/fp/lastIndexOf.js b/www/node_modules/lodash/fp/lastIndexOf.js new file mode 100644 index 0000000..e27480e --- /dev/null +++ b/www/node_modules/lodash/fp/lastIndexOf.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('lastIndexOf', require('../lastIndexOf')); diff --git a/www/node_modules/lodash/fp/lowerCase.js b/www/node_modules/lodash/fp/lowerCase.js new file mode 100644 index 0000000..4da15ce --- /dev/null +++ b/www/node_modules/lodash/fp/lowerCase.js @@ -0,0 +1 @@ +module.exports = require('../lowerCase'); diff --git a/www/node_modules/lodash/fp/lowerFirst.js b/www/node_modules/lodash/fp/lowerFirst.js new file mode 100644 index 0000000..afd1ba5 --- /dev/null +++ b/www/node_modules/lodash/fp/lowerFirst.js @@ -0,0 +1 @@ +module.exports = require('../lowerFirst'); diff --git a/www/node_modules/lodash/fp/lt.js b/www/node_modules/lodash/fp/lt.js new file mode 100644 index 0000000..dd4cba0 --- /dev/null +++ b/www/node_modules/lodash/fp/lt.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('lt', require('../lt')); diff --git a/www/node_modules/lodash/fp/lte.js b/www/node_modules/lodash/fp/lte.js new file mode 100644 index 0000000..f9bf725 --- /dev/null +++ b/www/node_modules/lodash/fp/lte.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('lte', require('../lte')); diff --git a/www/node_modules/lodash/fp/map.js b/www/node_modules/lodash/fp/map.js new file mode 100644 index 0000000..b74c1a1 --- /dev/null +++ b/www/node_modules/lodash/fp/map.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('map', require('../map')); diff --git a/www/node_modules/lodash/fp/mapKeys.js b/www/node_modules/lodash/fp/mapKeys.js new file mode 100644 index 0000000..a8156c1 --- /dev/null +++ b/www/node_modules/lodash/fp/mapKeys.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('mapKeys', require('../mapKeys')); diff --git a/www/node_modules/lodash/fp/mapObj.js b/www/node_modules/lodash/fp/mapObj.js new file mode 100644 index 0000000..9f1872d --- /dev/null +++ b/www/node_modules/lodash/fp/mapObj.js @@ -0,0 +1 @@ +module.exports = require('./mapValues'); diff --git a/www/node_modules/lodash/fp/mapValues.js b/www/node_modules/lodash/fp/mapValues.js new file mode 100644 index 0000000..9375d73 --- /dev/null +++ b/www/node_modules/lodash/fp/mapValues.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('mapValues', require('../mapValues')); diff --git a/www/node_modules/lodash/fp/matches.js b/www/node_modules/lodash/fp/matches.js new file mode 100644 index 0000000..eea5916 --- /dev/null +++ b/www/node_modules/lodash/fp/matches.js @@ -0,0 +1 @@ +module.exports = require('../matches'); diff --git a/www/node_modules/lodash/fp/matchesProperty.js b/www/node_modules/lodash/fp/matchesProperty.js new file mode 100644 index 0000000..c4343a1 --- /dev/null +++ b/www/node_modules/lodash/fp/matchesProperty.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('matchesProperty', require('../matchesProperty')); diff --git a/www/node_modules/lodash/fp/math.js b/www/node_modules/lodash/fp/math.js new file mode 100644 index 0000000..e8f50f7 --- /dev/null +++ b/www/node_modules/lodash/fp/math.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../math')); diff --git a/www/node_modules/lodash/fp/max.js b/www/node_modules/lodash/fp/max.js new file mode 100644 index 0000000..f7258c6 --- /dev/null +++ b/www/node_modules/lodash/fp/max.js @@ -0,0 +1 @@ +module.exports = require('../max'); diff --git a/www/node_modules/lodash/fp/maxBy.js b/www/node_modules/lodash/fp/maxBy.js new file mode 100644 index 0000000..b81243f --- /dev/null +++ b/www/node_modules/lodash/fp/maxBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('maxBy', require('../maxBy')); diff --git a/www/node_modules/lodash/fp/mean.js b/www/node_modules/lodash/fp/mean.js new file mode 100644 index 0000000..b78e427 --- /dev/null +++ b/www/node_modules/lodash/fp/mean.js @@ -0,0 +1 @@ +module.exports = require('../mean'); diff --git a/www/node_modules/lodash/fp/memoize.js b/www/node_modules/lodash/fp/memoize.js new file mode 100644 index 0000000..1a45e09 --- /dev/null +++ b/www/node_modules/lodash/fp/memoize.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('memoize', require('../memoize')); diff --git a/www/node_modules/lodash/fp/merge.js b/www/node_modules/lodash/fp/merge.js new file mode 100644 index 0000000..3dca641 --- /dev/null +++ b/www/node_modules/lodash/fp/merge.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('merge', require('../merge')); diff --git a/www/node_modules/lodash/fp/mergeWith.js b/www/node_modules/lodash/fp/mergeWith.js new file mode 100644 index 0000000..ba45644 --- /dev/null +++ b/www/node_modules/lodash/fp/mergeWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('mergeWith', require('../mergeWith')); diff --git a/www/node_modules/lodash/fp/method.js b/www/node_modules/lodash/fp/method.js new file mode 100644 index 0000000..c2f95c3 --- /dev/null +++ b/www/node_modules/lodash/fp/method.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('method', require('../method')); diff --git a/www/node_modules/lodash/fp/methodOf.js b/www/node_modules/lodash/fp/methodOf.js new file mode 100644 index 0000000..223f651 --- /dev/null +++ b/www/node_modules/lodash/fp/methodOf.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('methodOf', require('../methodOf')); diff --git a/www/node_modules/lodash/fp/min.js b/www/node_modules/lodash/fp/min.js new file mode 100644 index 0000000..10db02c --- /dev/null +++ b/www/node_modules/lodash/fp/min.js @@ -0,0 +1 @@ +module.exports = require('../min'); diff --git a/www/node_modules/lodash/fp/minBy.js b/www/node_modules/lodash/fp/minBy.js new file mode 100644 index 0000000..10edfd4 --- /dev/null +++ b/www/node_modules/lodash/fp/minBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('minBy', require('../minBy')); diff --git a/www/node_modules/lodash/fp/mixin.js b/www/node_modules/lodash/fp/mixin.js new file mode 100644 index 0000000..965f180 --- /dev/null +++ b/www/node_modules/lodash/fp/mixin.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('mixin', require('../mixin')); diff --git a/www/node_modules/lodash/fp/nAry.js b/www/node_modules/lodash/fp/nAry.js new file mode 100644 index 0000000..f262a76 --- /dev/null +++ b/www/node_modules/lodash/fp/nAry.js @@ -0,0 +1 @@ +module.exports = require('./ary'); diff --git a/www/node_modules/lodash/fp/negate.js b/www/node_modules/lodash/fp/negate.js new file mode 100644 index 0000000..345b425 --- /dev/null +++ b/www/node_modules/lodash/fp/negate.js @@ -0,0 +1 @@ +module.exports = require('../negate'); diff --git a/www/node_modules/lodash/fp/next.js b/www/node_modules/lodash/fp/next.js new file mode 100644 index 0000000..5cad70e --- /dev/null +++ b/www/node_modules/lodash/fp/next.js @@ -0,0 +1 @@ +module.exports = require('../next'); diff --git a/www/node_modules/lodash/fp/noop.js b/www/node_modules/lodash/fp/noop.js new file mode 100644 index 0000000..ca10050 --- /dev/null +++ b/www/node_modules/lodash/fp/noop.js @@ -0,0 +1 @@ +module.exports = require('../noop'); diff --git a/www/node_modules/lodash/fp/now.js b/www/node_modules/lodash/fp/now.js new file mode 100644 index 0000000..aa5ed67 --- /dev/null +++ b/www/node_modules/lodash/fp/now.js @@ -0,0 +1 @@ +module.exports = require('../now'); diff --git a/www/node_modules/lodash/fp/nthArg.js b/www/node_modules/lodash/fp/nthArg.js new file mode 100644 index 0000000..dd47ac6 --- /dev/null +++ b/www/node_modules/lodash/fp/nthArg.js @@ -0,0 +1 @@ +module.exports = require('../nthArg'); diff --git a/www/node_modules/lodash/fp/number.js b/www/node_modules/lodash/fp/number.js new file mode 100644 index 0000000..5c10b88 --- /dev/null +++ b/www/node_modules/lodash/fp/number.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../number')); diff --git a/www/node_modules/lodash/fp/object.js b/www/node_modules/lodash/fp/object.js new file mode 100644 index 0000000..ae39a13 --- /dev/null +++ b/www/node_modules/lodash/fp/object.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../object')); diff --git a/www/node_modules/lodash/fp/omit.js b/www/node_modules/lodash/fp/omit.js new file mode 100644 index 0000000..404b551 --- /dev/null +++ b/www/node_modules/lodash/fp/omit.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('omit', require('../omit')); diff --git a/www/node_modules/lodash/fp/omitAll.js b/www/node_modules/lodash/fp/omitAll.js new file mode 100644 index 0000000..144cf4b --- /dev/null +++ b/www/node_modules/lodash/fp/omitAll.js @@ -0,0 +1 @@ +module.exports = require('./omit'); diff --git a/www/node_modules/lodash/fp/omitBy.js b/www/node_modules/lodash/fp/omitBy.js new file mode 100644 index 0000000..745efa5 --- /dev/null +++ b/www/node_modules/lodash/fp/omitBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('omitBy', require('../omitBy')); diff --git a/www/node_modules/lodash/fp/once.js b/www/node_modules/lodash/fp/once.js new file mode 100644 index 0000000..6bd0beb --- /dev/null +++ b/www/node_modules/lodash/fp/once.js @@ -0,0 +1 @@ +module.exports = require('../once'); diff --git a/www/node_modules/lodash/fp/orderBy.js b/www/node_modules/lodash/fp/orderBy.js new file mode 100644 index 0000000..b32244f --- /dev/null +++ b/www/node_modules/lodash/fp/orderBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('orderBy', require('../orderBy')); diff --git a/www/node_modules/lodash/fp/over.js b/www/node_modules/lodash/fp/over.js new file mode 100644 index 0000000..0a5a797 --- /dev/null +++ b/www/node_modules/lodash/fp/over.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('over', require('../over')); diff --git a/www/node_modules/lodash/fp/overArgs.js b/www/node_modules/lodash/fp/overArgs.js new file mode 100644 index 0000000..8188387 --- /dev/null +++ b/www/node_modules/lodash/fp/overArgs.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('overArgs', require('../overArgs')); diff --git a/www/node_modules/lodash/fp/overEvery.js b/www/node_modules/lodash/fp/overEvery.js new file mode 100644 index 0000000..36dc552 --- /dev/null +++ b/www/node_modules/lodash/fp/overEvery.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('overEvery', require('../overEvery')); diff --git a/www/node_modules/lodash/fp/overSome.js b/www/node_modules/lodash/fp/overSome.js new file mode 100644 index 0000000..b02d464 --- /dev/null +++ b/www/node_modules/lodash/fp/overSome.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('overSome', require('../overSome')); diff --git a/www/node_modules/lodash/fp/pad.js b/www/node_modules/lodash/fp/pad.js new file mode 100644 index 0000000..e59cfc9 --- /dev/null +++ b/www/node_modules/lodash/fp/pad.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pad', require('../pad')); diff --git a/www/node_modules/lodash/fp/padEnd.js b/www/node_modules/lodash/fp/padEnd.js new file mode 100644 index 0000000..0b6dbb7 --- /dev/null +++ b/www/node_modules/lodash/fp/padEnd.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('padEnd', require('../padEnd')); diff --git a/www/node_modules/lodash/fp/padStart.js b/www/node_modules/lodash/fp/padStart.js new file mode 100644 index 0000000..c97f098 --- /dev/null +++ b/www/node_modules/lodash/fp/padStart.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('padStart', require('../padStart')); diff --git a/www/node_modules/lodash/fp/parseInt.js b/www/node_modules/lodash/fp/parseInt.js new file mode 100644 index 0000000..35be713 --- /dev/null +++ b/www/node_modules/lodash/fp/parseInt.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('parseInt', require('../parseInt')); diff --git a/www/node_modules/lodash/fp/partial.js b/www/node_modules/lodash/fp/partial.js new file mode 100644 index 0000000..a687d0c --- /dev/null +++ b/www/node_modules/lodash/fp/partial.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('partial', require('../partial')); diff --git a/www/node_modules/lodash/fp/partialRight.js b/www/node_modules/lodash/fp/partialRight.js new file mode 100644 index 0000000..28428c0 --- /dev/null +++ b/www/node_modules/lodash/fp/partialRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('partialRight', require('../partialRight')); diff --git a/www/node_modules/lodash/fp/partition.js b/www/node_modules/lodash/fp/partition.js new file mode 100644 index 0000000..b1495e6 --- /dev/null +++ b/www/node_modules/lodash/fp/partition.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('partition', require('../partition')); diff --git a/www/node_modules/lodash/fp/path.js b/www/node_modules/lodash/fp/path.js new file mode 100644 index 0000000..b29cfb2 --- /dev/null +++ b/www/node_modules/lodash/fp/path.js @@ -0,0 +1 @@ +module.exports = require('./get'); diff --git a/www/node_modules/lodash/fp/pathEq.js b/www/node_modules/lodash/fp/pathEq.js new file mode 100644 index 0000000..36c027a --- /dev/null +++ b/www/node_modules/lodash/fp/pathEq.js @@ -0,0 +1 @@ +module.exports = require('./matchesProperty'); diff --git a/www/node_modules/lodash/fp/pathOr.js b/www/node_modules/lodash/fp/pathOr.js new file mode 100644 index 0000000..4ab5820 --- /dev/null +++ b/www/node_modules/lodash/fp/pathOr.js @@ -0,0 +1 @@ +module.exports = require('./getOr'); diff --git a/www/node_modules/lodash/fp/pick.js b/www/node_modules/lodash/fp/pick.js new file mode 100644 index 0000000..e84b366 --- /dev/null +++ b/www/node_modules/lodash/fp/pick.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pick', require('../pick')); diff --git a/www/node_modules/lodash/fp/pickAll.js b/www/node_modules/lodash/fp/pickAll.js new file mode 100644 index 0000000..a8ecd46 --- /dev/null +++ b/www/node_modules/lodash/fp/pickAll.js @@ -0,0 +1 @@ +module.exports = require('./pick'); diff --git a/www/node_modules/lodash/fp/pickBy.js b/www/node_modules/lodash/fp/pickBy.js new file mode 100644 index 0000000..4d14a0b --- /dev/null +++ b/www/node_modules/lodash/fp/pickBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pickBy', require('../pickBy')); diff --git a/www/node_modules/lodash/fp/pipe.js b/www/node_modules/lodash/fp/pipe.js new file mode 100644 index 0000000..b2e1e2c --- /dev/null +++ b/www/node_modules/lodash/fp/pipe.js @@ -0,0 +1 @@ +module.exports = require('./flow'); diff --git a/www/node_modules/lodash/fp/plant.js b/www/node_modules/lodash/fp/plant.js new file mode 100644 index 0000000..c85596a --- /dev/null +++ b/www/node_modules/lodash/fp/plant.js @@ -0,0 +1 @@ +module.exports = require('../plant'); diff --git a/www/node_modules/lodash/fp/prop.js b/www/node_modules/lodash/fp/prop.js new file mode 100644 index 0000000..b29cfb2 --- /dev/null +++ b/www/node_modules/lodash/fp/prop.js @@ -0,0 +1 @@ +module.exports = require('./get'); diff --git a/www/node_modules/lodash/fp/propOf.js b/www/node_modules/lodash/fp/propOf.js new file mode 100644 index 0000000..cf0d197 --- /dev/null +++ b/www/node_modules/lodash/fp/propOf.js @@ -0,0 +1 @@ +module.exports = require('./propertyOf'); diff --git a/www/node_modules/lodash/fp/propOr.js b/www/node_modules/lodash/fp/propOr.js new file mode 100644 index 0000000..4ab5820 --- /dev/null +++ b/www/node_modules/lodash/fp/propOr.js @@ -0,0 +1 @@ +module.exports = require('./getOr'); diff --git a/www/node_modules/lodash/fp/property.js b/www/node_modules/lodash/fp/property.js new file mode 100644 index 0000000..fab6f23 --- /dev/null +++ b/www/node_modules/lodash/fp/property.js @@ -0,0 +1 @@ +module.exports = require('../property'); diff --git a/www/node_modules/lodash/fp/propertyOf.js b/www/node_modules/lodash/fp/propertyOf.js new file mode 100644 index 0000000..d941cdb --- /dev/null +++ b/www/node_modules/lodash/fp/propertyOf.js @@ -0,0 +1 @@ +module.exports = require('../propertyOf'); diff --git a/www/node_modules/lodash/fp/pull.js b/www/node_modules/lodash/fp/pull.js new file mode 100644 index 0000000..47f49ae --- /dev/null +++ b/www/node_modules/lodash/fp/pull.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pull', require('../pull')); diff --git a/www/node_modules/lodash/fp/pullAll.js b/www/node_modules/lodash/fp/pullAll.js new file mode 100644 index 0000000..ffb663b --- /dev/null +++ b/www/node_modules/lodash/fp/pullAll.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pullAll', require('../pullAll')); diff --git a/www/node_modules/lodash/fp/pullAllBy.js b/www/node_modules/lodash/fp/pullAllBy.js new file mode 100644 index 0000000..23b11b7 --- /dev/null +++ b/www/node_modules/lodash/fp/pullAllBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pullAllBy', require('../pullAllBy')); diff --git a/www/node_modules/lodash/fp/pullAllWith.js b/www/node_modules/lodash/fp/pullAllWith.js new file mode 100644 index 0000000..495d574 --- /dev/null +++ b/www/node_modules/lodash/fp/pullAllWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pullAllWith', require('../pullAllWith')); diff --git a/www/node_modules/lodash/fp/pullAt.js b/www/node_modules/lodash/fp/pullAt.js new file mode 100644 index 0000000..5836d2d --- /dev/null +++ b/www/node_modules/lodash/fp/pullAt.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('pullAt', require('../pullAt')); diff --git a/www/node_modules/lodash/fp/random.js b/www/node_modules/lodash/fp/random.js new file mode 100644 index 0000000..607d63a --- /dev/null +++ b/www/node_modules/lodash/fp/random.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('random', require('../random')); diff --git a/www/node_modules/lodash/fp/range.js b/www/node_modules/lodash/fp/range.js new file mode 100644 index 0000000..1142304 --- /dev/null +++ b/www/node_modules/lodash/fp/range.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('range', require('../range')); diff --git a/www/node_modules/lodash/fp/rangeRight.js b/www/node_modules/lodash/fp/rangeRight.js new file mode 100644 index 0000000..2248287 --- /dev/null +++ b/www/node_modules/lodash/fp/rangeRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('rangeRight', require('../rangeRight')); diff --git a/www/node_modules/lodash/fp/rearg.js b/www/node_modules/lodash/fp/rearg.js new file mode 100644 index 0000000..b2753e9 --- /dev/null +++ b/www/node_modules/lodash/fp/rearg.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('rearg', require('../rearg')); diff --git a/www/node_modules/lodash/fp/reduce.js b/www/node_modules/lodash/fp/reduce.js new file mode 100644 index 0000000..2f1b425 --- /dev/null +++ b/www/node_modules/lodash/fp/reduce.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('reduce', require('../reduce')); diff --git a/www/node_modules/lodash/fp/reduceRight.js b/www/node_modules/lodash/fp/reduceRight.js new file mode 100644 index 0000000..b110e9e --- /dev/null +++ b/www/node_modules/lodash/fp/reduceRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('reduceRight', require('../reduceRight')); diff --git a/www/node_modules/lodash/fp/reject.js b/www/node_modules/lodash/fp/reject.js new file mode 100644 index 0000000..30bd3bc --- /dev/null +++ b/www/node_modules/lodash/fp/reject.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('reject', require('../reject')); diff --git a/www/node_modules/lodash/fp/remove.js b/www/node_modules/lodash/fp/remove.js new file mode 100644 index 0000000..4b67a94 --- /dev/null +++ b/www/node_modules/lodash/fp/remove.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('remove', require('../remove')); diff --git a/www/node_modules/lodash/fp/repeat.js b/www/node_modules/lodash/fp/repeat.js new file mode 100644 index 0000000..bc0704b --- /dev/null +++ b/www/node_modules/lodash/fp/repeat.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('repeat', require('../repeat')); diff --git a/www/node_modules/lodash/fp/replace.js b/www/node_modules/lodash/fp/replace.js new file mode 100644 index 0000000..a4462e7 --- /dev/null +++ b/www/node_modules/lodash/fp/replace.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('replace', require('../replace')); diff --git a/www/node_modules/lodash/fp/rest.js b/www/node_modules/lodash/fp/rest.js new file mode 100644 index 0000000..69dfc18 --- /dev/null +++ b/www/node_modules/lodash/fp/rest.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('rest', require('../rest')); diff --git a/www/node_modules/lodash/fp/result.js b/www/node_modules/lodash/fp/result.js new file mode 100644 index 0000000..1d3fb58 --- /dev/null +++ b/www/node_modules/lodash/fp/result.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('result', require('../result')); diff --git a/www/node_modules/lodash/fp/reverse.js b/www/node_modules/lodash/fp/reverse.js new file mode 100644 index 0000000..a6d960d --- /dev/null +++ b/www/node_modules/lodash/fp/reverse.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('reverse', require('../reverse')); diff --git a/www/node_modules/lodash/fp/round.js b/www/node_modules/lodash/fp/round.js new file mode 100644 index 0000000..9eb69b1 --- /dev/null +++ b/www/node_modules/lodash/fp/round.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('round', require('../round')); diff --git a/www/node_modules/lodash/fp/sample.js b/www/node_modules/lodash/fp/sample.js new file mode 100644 index 0000000..008cb06 --- /dev/null +++ b/www/node_modules/lodash/fp/sample.js @@ -0,0 +1 @@ +module.exports = require('../sample'); diff --git a/www/node_modules/lodash/fp/sampleSize.js b/www/node_modules/lodash/fp/sampleSize.js new file mode 100644 index 0000000..920c075 --- /dev/null +++ b/www/node_modules/lodash/fp/sampleSize.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sampleSize', require('../sampleSize')); diff --git a/www/node_modules/lodash/fp/seq.js b/www/node_modules/lodash/fp/seq.js new file mode 100644 index 0000000..d8f42b0 --- /dev/null +++ b/www/node_modules/lodash/fp/seq.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../seq')); diff --git a/www/node_modules/lodash/fp/set.js b/www/node_modules/lodash/fp/set.js new file mode 100644 index 0000000..fc2a75b --- /dev/null +++ b/www/node_modules/lodash/fp/set.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('set', require('../set')); diff --git a/www/node_modules/lodash/fp/setWith.js b/www/node_modules/lodash/fp/setWith.js new file mode 100644 index 0000000..fd836ea --- /dev/null +++ b/www/node_modules/lodash/fp/setWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('setWith', require('../setWith')); diff --git a/www/node_modules/lodash/fp/shuffle.js b/www/node_modules/lodash/fp/shuffle.js new file mode 100644 index 0000000..85d5699 --- /dev/null +++ b/www/node_modules/lodash/fp/shuffle.js @@ -0,0 +1 @@ +module.exports = require('../shuffle'); diff --git a/www/node_modules/lodash/fp/size.js b/www/node_modules/lodash/fp/size.js new file mode 100644 index 0000000..efba2ca --- /dev/null +++ b/www/node_modules/lodash/fp/size.js @@ -0,0 +1 @@ +module.exports = require('../size'); diff --git a/www/node_modules/lodash/fp/slice.js b/www/node_modules/lodash/fp/slice.js new file mode 100644 index 0000000..6fb1898 --- /dev/null +++ b/www/node_modules/lodash/fp/slice.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('slice', require('../slice')); diff --git a/www/node_modules/lodash/fp/snakeCase.js b/www/node_modules/lodash/fp/snakeCase.js new file mode 100644 index 0000000..2893f7b --- /dev/null +++ b/www/node_modules/lodash/fp/snakeCase.js @@ -0,0 +1 @@ +module.exports = require('../snakeCase'); diff --git a/www/node_modules/lodash/fp/some.js b/www/node_modules/lodash/fp/some.js new file mode 100644 index 0000000..64727fe --- /dev/null +++ b/www/node_modules/lodash/fp/some.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('some', require('../some')); diff --git a/www/node_modules/lodash/fp/somePass.js b/www/node_modules/lodash/fp/somePass.js new file mode 100644 index 0000000..2774ab3 --- /dev/null +++ b/www/node_modules/lodash/fp/somePass.js @@ -0,0 +1 @@ +module.exports = require('./overSome'); diff --git a/www/node_modules/lodash/fp/sortBy.js b/www/node_modules/lodash/fp/sortBy.js new file mode 100644 index 0000000..80fe4dd --- /dev/null +++ b/www/node_modules/lodash/fp/sortBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortBy', require('../sortBy')); diff --git a/www/node_modules/lodash/fp/sortedIndex.js b/www/node_modules/lodash/fp/sortedIndex.js new file mode 100644 index 0000000..509dcb8 --- /dev/null +++ b/www/node_modules/lodash/fp/sortedIndex.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedIndex', require('../sortedIndex')); diff --git a/www/node_modules/lodash/fp/sortedIndexBy.js b/www/node_modules/lodash/fp/sortedIndexBy.js new file mode 100644 index 0000000..aa2d219 --- /dev/null +++ b/www/node_modules/lodash/fp/sortedIndexBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedIndexBy', require('../sortedIndexBy')); diff --git a/www/node_modules/lodash/fp/sortedIndexOf.js b/www/node_modules/lodash/fp/sortedIndexOf.js new file mode 100644 index 0000000..c127420 --- /dev/null +++ b/www/node_modules/lodash/fp/sortedIndexOf.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedIndexOf', require('../sortedIndexOf')); diff --git a/www/node_modules/lodash/fp/sortedLastIndex.js b/www/node_modules/lodash/fp/sortedLastIndex.js new file mode 100644 index 0000000..7ec9e33 --- /dev/null +++ b/www/node_modules/lodash/fp/sortedLastIndex.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedLastIndex', require('../sortedLastIndex')); diff --git a/www/node_modules/lodash/fp/sortedLastIndexBy.js b/www/node_modules/lodash/fp/sortedLastIndexBy.js new file mode 100644 index 0000000..e03f185 --- /dev/null +++ b/www/node_modules/lodash/fp/sortedLastIndexBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedLastIndexBy', require('../sortedLastIndexBy')); diff --git a/www/node_modules/lodash/fp/sortedLastIndexOf.js b/www/node_modules/lodash/fp/sortedLastIndexOf.js new file mode 100644 index 0000000..0130801 --- /dev/null +++ b/www/node_modules/lodash/fp/sortedLastIndexOf.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedLastIndexOf', require('../sortedLastIndexOf')); diff --git a/www/node_modules/lodash/fp/sortedUniq.js b/www/node_modules/lodash/fp/sortedUniq.js new file mode 100644 index 0000000..c0df750 --- /dev/null +++ b/www/node_modules/lodash/fp/sortedUniq.js @@ -0,0 +1 @@ +module.exports = require('../sortedUniq'); diff --git a/www/node_modules/lodash/fp/sortedUniqBy.js b/www/node_modules/lodash/fp/sortedUniqBy.js new file mode 100644 index 0000000..f5c65ad --- /dev/null +++ b/www/node_modules/lodash/fp/sortedUniqBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sortedUniqBy', require('../sortedUniqBy')); diff --git a/www/node_modules/lodash/fp/split.js b/www/node_modules/lodash/fp/split.js new file mode 100644 index 0000000..79f2693 --- /dev/null +++ b/www/node_modules/lodash/fp/split.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('split', require('../split')); diff --git a/www/node_modules/lodash/fp/spread.js b/www/node_modules/lodash/fp/spread.js new file mode 100644 index 0000000..0348df2 --- /dev/null +++ b/www/node_modules/lodash/fp/spread.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('spread', require('../spread')); diff --git a/www/node_modules/lodash/fp/startCase.js b/www/node_modules/lodash/fp/startCase.js new file mode 100644 index 0000000..2a6a66e --- /dev/null +++ b/www/node_modules/lodash/fp/startCase.js @@ -0,0 +1 @@ +module.exports = require('../startCase'); diff --git a/www/node_modules/lodash/fp/startsWith.js b/www/node_modules/lodash/fp/startsWith.js new file mode 100644 index 0000000..730a141 --- /dev/null +++ b/www/node_modules/lodash/fp/startsWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('startsWith', require('../startsWith')); diff --git a/www/node_modules/lodash/fp/string.js b/www/node_modules/lodash/fp/string.js new file mode 100644 index 0000000..773b037 --- /dev/null +++ b/www/node_modules/lodash/fp/string.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../string')); diff --git a/www/node_modules/lodash/fp/subtract.js b/www/node_modules/lodash/fp/subtract.js new file mode 100644 index 0000000..46b83db --- /dev/null +++ b/www/node_modules/lodash/fp/subtract.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('subtract', require('../subtract')); diff --git a/www/node_modules/lodash/fp/sum.js b/www/node_modules/lodash/fp/sum.js new file mode 100644 index 0000000..e8a59c5 --- /dev/null +++ b/www/node_modules/lodash/fp/sum.js @@ -0,0 +1 @@ +module.exports = require('../sum'); diff --git a/www/node_modules/lodash/fp/sumBy.js b/www/node_modules/lodash/fp/sumBy.js new file mode 100644 index 0000000..2692dc1 --- /dev/null +++ b/www/node_modules/lodash/fp/sumBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('sumBy', require('../sumBy')); diff --git a/www/node_modules/lodash/fp/tail.js b/www/node_modules/lodash/fp/tail.js new file mode 100644 index 0000000..36c6494 --- /dev/null +++ b/www/node_modules/lodash/fp/tail.js @@ -0,0 +1 @@ +module.exports = require('../tail'); diff --git a/www/node_modules/lodash/fp/take.js b/www/node_modules/lodash/fp/take.js new file mode 100644 index 0000000..e0984a4 --- /dev/null +++ b/www/node_modules/lodash/fp/take.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('take', require('../take')); diff --git a/www/node_modules/lodash/fp/takeRight.js b/www/node_modules/lodash/fp/takeRight.js new file mode 100644 index 0000000..7b7c3ce --- /dev/null +++ b/www/node_modules/lodash/fp/takeRight.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('takeRight', require('../takeRight')); diff --git a/www/node_modules/lodash/fp/takeRightWhile.js b/www/node_modules/lodash/fp/takeRightWhile.js new file mode 100644 index 0000000..305b254 --- /dev/null +++ b/www/node_modules/lodash/fp/takeRightWhile.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('takeRightWhile', require('../takeRightWhile')); diff --git a/www/node_modules/lodash/fp/takeWhile.js b/www/node_modules/lodash/fp/takeWhile.js new file mode 100644 index 0000000..a90126d --- /dev/null +++ b/www/node_modules/lodash/fp/takeWhile.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('takeWhile', require('../takeWhile')); diff --git a/www/node_modules/lodash/fp/tap.js b/www/node_modules/lodash/fp/tap.js new file mode 100644 index 0000000..3bec2bd --- /dev/null +++ b/www/node_modules/lodash/fp/tap.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('tap', require('../tap')); diff --git a/www/node_modules/lodash/fp/template.js b/www/node_modules/lodash/fp/template.js new file mode 100644 index 0000000..0130d14 --- /dev/null +++ b/www/node_modules/lodash/fp/template.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('template', require('../template')); diff --git a/www/node_modules/lodash/fp/templateSettings.js b/www/node_modules/lodash/fp/templateSettings.js new file mode 100644 index 0000000..ddbbb58 --- /dev/null +++ b/www/node_modules/lodash/fp/templateSettings.js @@ -0,0 +1 @@ +module.exports = require('../templateSettings'); diff --git a/www/node_modules/lodash/fp/throttle.js b/www/node_modules/lodash/fp/throttle.js new file mode 100644 index 0000000..36f76d6 --- /dev/null +++ b/www/node_modules/lodash/fp/throttle.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('throttle', require('../throttle')); diff --git a/www/node_modules/lodash/fp/thru.js b/www/node_modules/lodash/fp/thru.js new file mode 100644 index 0000000..05ddaef --- /dev/null +++ b/www/node_modules/lodash/fp/thru.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('thru', require('../thru')); diff --git a/www/node_modules/lodash/fp/times.js b/www/node_modules/lodash/fp/times.js new file mode 100644 index 0000000..02fd3b7 --- /dev/null +++ b/www/node_modules/lodash/fp/times.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('times', require('../times')); diff --git a/www/node_modules/lodash/fp/toArray.js b/www/node_modules/lodash/fp/toArray.js new file mode 100644 index 0000000..1ea0b52 --- /dev/null +++ b/www/node_modules/lodash/fp/toArray.js @@ -0,0 +1 @@ +module.exports = require('../toArray'); diff --git a/www/node_modules/lodash/fp/toInteger.js b/www/node_modules/lodash/fp/toInteger.js new file mode 100644 index 0000000..17e59a3 --- /dev/null +++ b/www/node_modules/lodash/fp/toInteger.js @@ -0,0 +1 @@ +module.exports = require('../toInteger'); diff --git a/www/node_modules/lodash/fp/toIterator.js b/www/node_modules/lodash/fp/toIterator.js new file mode 100644 index 0000000..13bf21c --- /dev/null +++ b/www/node_modules/lodash/fp/toIterator.js @@ -0,0 +1 @@ +module.exports = require('../toIterator'); diff --git a/www/node_modules/lodash/fp/toJSON.js b/www/node_modules/lodash/fp/toJSON.js new file mode 100644 index 0000000..5f6cb92 --- /dev/null +++ b/www/node_modules/lodash/fp/toJSON.js @@ -0,0 +1 @@ +module.exports = require('../toJSON'); diff --git a/www/node_modules/lodash/fp/toLength.js b/www/node_modules/lodash/fp/toLength.js new file mode 100644 index 0000000..38529fb --- /dev/null +++ b/www/node_modules/lodash/fp/toLength.js @@ -0,0 +1 @@ +module.exports = require('../toLength'); diff --git a/www/node_modules/lodash/fp/toLower.js b/www/node_modules/lodash/fp/toLower.js new file mode 100644 index 0000000..01d3432 --- /dev/null +++ b/www/node_modules/lodash/fp/toLower.js @@ -0,0 +1 @@ +module.exports = require('../toLower'); diff --git a/www/node_modules/lodash/fp/toNumber.js b/www/node_modules/lodash/fp/toNumber.js new file mode 100644 index 0000000..071e320 --- /dev/null +++ b/www/node_modules/lodash/fp/toNumber.js @@ -0,0 +1 @@ +module.exports = require('../toNumber'); diff --git a/www/node_modules/lodash/fp/toPairs.js b/www/node_modules/lodash/fp/toPairs.js new file mode 100644 index 0000000..4b4dcb7 --- /dev/null +++ b/www/node_modules/lodash/fp/toPairs.js @@ -0,0 +1 @@ +module.exports = require('../toPairs'); diff --git a/www/node_modules/lodash/fp/toPairsIn.js b/www/node_modules/lodash/fp/toPairsIn.js new file mode 100644 index 0000000..53076cc --- /dev/null +++ b/www/node_modules/lodash/fp/toPairsIn.js @@ -0,0 +1 @@ +module.exports = require('../toPairsIn'); diff --git a/www/node_modules/lodash/fp/toPath.js b/www/node_modules/lodash/fp/toPath.js new file mode 100644 index 0000000..62762ec --- /dev/null +++ b/www/node_modules/lodash/fp/toPath.js @@ -0,0 +1 @@ +module.exports = require('../toPath'); diff --git a/www/node_modules/lodash/fp/toPlainObject.js b/www/node_modules/lodash/fp/toPlainObject.js new file mode 100644 index 0000000..6a6aebd --- /dev/null +++ b/www/node_modules/lodash/fp/toPlainObject.js @@ -0,0 +1 @@ +module.exports = require('../toPlainObject'); diff --git a/www/node_modules/lodash/fp/toSafeInteger.js b/www/node_modules/lodash/fp/toSafeInteger.js new file mode 100644 index 0000000..3f5b817 --- /dev/null +++ b/www/node_modules/lodash/fp/toSafeInteger.js @@ -0,0 +1 @@ +module.exports = require('../toSafeInteger'); diff --git a/www/node_modules/lodash/fp/toString.js b/www/node_modules/lodash/fp/toString.js new file mode 100644 index 0000000..c309058 --- /dev/null +++ b/www/node_modules/lodash/fp/toString.js @@ -0,0 +1 @@ +module.exports = require('../[object Object]'); diff --git a/www/node_modules/lodash/fp/toUpper.js b/www/node_modules/lodash/fp/toUpper.js new file mode 100644 index 0000000..428eb33 --- /dev/null +++ b/www/node_modules/lodash/fp/toUpper.js @@ -0,0 +1 @@ +module.exports = require('../toUpper'); diff --git a/www/node_modules/lodash/fp/transform.js b/www/node_modules/lodash/fp/transform.js new file mode 100644 index 0000000..30bed49 --- /dev/null +++ b/www/node_modules/lodash/fp/transform.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('transform', require('../transform')); diff --git a/www/node_modules/lodash/fp/trim.js b/www/node_modules/lodash/fp/trim.js new file mode 100644 index 0000000..b7cafe9 --- /dev/null +++ b/www/node_modules/lodash/fp/trim.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trim', require('../trim')); diff --git a/www/node_modules/lodash/fp/trimChars.js b/www/node_modules/lodash/fp/trimChars.js new file mode 100644 index 0000000..051ea1e --- /dev/null +++ b/www/node_modules/lodash/fp/trimChars.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trimChars', require('../trim')); diff --git a/www/node_modules/lodash/fp/trimCharsEnd.js b/www/node_modules/lodash/fp/trimCharsEnd.js new file mode 100644 index 0000000..54c5cff --- /dev/null +++ b/www/node_modules/lodash/fp/trimCharsEnd.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trimCharsEnd', require('../trimEnd')); diff --git a/www/node_modules/lodash/fp/trimCharsStart.js b/www/node_modules/lodash/fp/trimCharsStart.js new file mode 100644 index 0000000..44f9866 --- /dev/null +++ b/www/node_modules/lodash/fp/trimCharsStart.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trimCharsStart', require('../trimStart')); diff --git a/www/node_modules/lodash/fp/trimEnd.js b/www/node_modules/lodash/fp/trimEnd.js new file mode 100644 index 0000000..1666596 --- /dev/null +++ b/www/node_modules/lodash/fp/trimEnd.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trimEnd', require('../trimEnd')); diff --git a/www/node_modules/lodash/fp/trimStart.js b/www/node_modules/lodash/fp/trimStart.js new file mode 100644 index 0000000..4921b03 --- /dev/null +++ b/www/node_modules/lodash/fp/trimStart.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('trimStart', require('../trimStart')); diff --git a/www/node_modules/lodash/fp/truncate.js b/www/node_modules/lodash/fp/truncate.js new file mode 100644 index 0000000..0c4d158 --- /dev/null +++ b/www/node_modules/lodash/fp/truncate.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('truncate', require('../truncate')); diff --git a/www/node_modules/lodash/fp/unapply.js b/www/node_modules/lodash/fp/unapply.js new file mode 100644 index 0000000..c5dfe77 --- /dev/null +++ b/www/node_modules/lodash/fp/unapply.js @@ -0,0 +1 @@ +module.exports = require('./rest'); diff --git a/www/node_modules/lodash/fp/unary.js b/www/node_modules/lodash/fp/unary.js new file mode 100644 index 0000000..3bc6483 --- /dev/null +++ b/www/node_modules/lodash/fp/unary.js @@ -0,0 +1 @@ +module.exports = require('../unary'); diff --git a/www/node_modules/lodash/fp/unescape.js b/www/node_modules/lodash/fp/unescape.js new file mode 100644 index 0000000..4233b15 --- /dev/null +++ b/www/node_modules/lodash/fp/unescape.js @@ -0,0 +1 @@ +module.exports = require('../unescape'); diff --git a/www/node_modules/lodash/fp/union.js b/www/node_modules/lodash/fp/union.js new file mode 100644 index 0000000..9deef12 --- /dev/null +++ b/www/node_modules/lodash/fp/union.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('union', require('../union')); diff --git a/www/node_modules/lodash/fp/unionBy.js b/www/node_modules/lodash/fp/unionBy.js new file mode 100644 index 0000000..029b359 --- /dev/null +++ b/www/node_modules/lodash/fp/unionBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('unionBy', require('../unionBy')); diff --git a/www/node_modules/lodash/fp/unionWith.js b/www/node_modules/lodash/fp/unionWith.js new file mode 100644 index 0000000..631eda0 --- /dev/null +++ b/www/node_modules/lodash/fp/unionWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('unionWith', require('../unionWith')); diff --git a/www/node_modules/lodash/fp/uniq.js b/www/node_modules/lodash/fp/uniq.js new file mode 100644 index 0000000..c64510f --- /dev/null +++ b/www/node_modules/lodash/fp/uniq.js @@ -0,0 +1 @@ +module.exports = require('../uniq'); diff --git a/www/node_modules/lodash/fp/uniqBy.js b/www/node_modules/lodash/fp/uniqBy.js new file mode 100644 index 0000000..1b6c03f --- /dev/null +++ b/www/node_modules/lodash/fp/uniqBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('uniqBy', require('../uniqBy')); diff --git a/www/node_modules/lodash/fp/uniqWith.js b/www/node_modules/lodash/fp/uniqWith.js new file mode 100644 index 0000000..be4c48d --- /dev/null +++ b/www/node_modules/lodash/fp/uniqWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('uniqWith', require('../uniqWith')); diff --git a/www/node_modules/lodash/fp/uniqueId.js b/www/node_modules/lodash/fp/uniqueId.js new file mode 100644 index 0000000..daa41cb --- /dev/null +++ b/www/node_modules/lodash/fp/uniqueId.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('uniqueId', require('../uniqueId')); diff --git a/www/node_modules/lodash/fp/unnest.js b/www/node_modules/lodash/fp/unnest.js new file mode 100644 index 0000000..5d34060 --- /dev/null +++ b/www/node_modules/lodash/fp/unnest.js @@ -0,0 +1 @@ +module.exports = require('./flatten'); diff --git a/www/node_modules/lodash/fp/unset.js b/www/node_modules/lodash/fp/unset.js new file mode 100644 index 0000000..0c4c1a6 --- /dev/null +++ b/www/node_modules/lodash/fp/unset.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('unset', require('../unset')); diff --git a/www/node_modules/lodash/fp/unzip.js b/www/node_modules/lodash/fp/unzip.js new file mode 100644 index 0000000..e0ac2db --- /dev/null +++ b/www/node_modules/lodash/fp/unzip.js @@ -0,0 +1 @@ +module.exports = require('../unzip'); diff --git a/www/node_modules/lodash/fp/unzipWith.js b/www/node_modules/lodash/fp/unzipWith.js new file mode 100644 index 0000000..de25cf7 --- /dev/null +++ b/www/node_modules/lodash/fp/unzipWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('unzipWith', require('../unzipWith')); diff --git a/www/node_modules/lodash/fp/update.js b/www/node_modules/lodash/fp/update.js new file mode 100644 index 0000000..93e0d57 --- /dev/null +++ b/www/node_modules/lodash/fp/update.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('update', require('../update')); diff --git a/www/node_modules/lodash/fp/updateWith.js b/www/node_modules/lodash/fp/updateWith.js new file mode 100644 index 0000000..a6ed49e --- /dev/null +++ b/www/node_modules/lodash/fp/updateWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('updateWith', require('../updateWith')); diff --git a/www/node_modules/lodash/fp/upperCase.js b/www/node_modules/lodash/fp/upperCase.js new file mode 100644 index 0000000..ddcb369 --- /dev/null +++ b/www/node_modules/lodash/fp/upperCase.js @@ -0,0 +1 @@ +module.exports = require('../upperCase'); diff --git a/www/node_modules/lodash/fp/upperFirst.js b/www/node_modules/lodash/fp/upperFirst.js new file mode 100644 index 0000000..34f1e20 --- /dev/null +++ b/www/node_modules/lodash/fp/upperFirst.js @@ -0,0 +1 @@ +module.exports = require('../upperFirst'); diff --git a/www/node_modules/lodash/fp/useWith.js b/www/node_modules/lodash/fp/useWith.js new file mode 100644 index 0000000..d8b3df5 --- /dev/null +++ b/www/node_modules/lodash/fp/useWith.js @@ -0,0 +1 @@ +module.exports = require('./overArgs'); diff --git a/www/node_modules/lodash/fp/util.js b/www/node_modules/lodash/fp/util.js new file mode 100644 index 0000000..18c00ba --- /dev/null +++ b/www/node_modules/lodash/fp/util.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert(require('../util')); diff --git a/www/node_modules/lodash/fp/value.js b/www/node_modules/lodash/fp/value.js new file mode 100644 index 0000000..4dc0e7e --- /dev/null +++ b/www/node_modules/lodash/fp/value.js @@ -0,0 +1 @@ +module.exports = require('../value'); diff --git a/www/node_modules/lodash/fp/valueOf.js b/www/node_modules/lodash/fp/valueOf.js new file mode 100644 index 0000000..c309058 --- /dev/null +++ b/www/node_modules/lodash/fp/valueOf.js @@ -0,0 +1 @@ +module.exports = require('../[object Object]'); diff --git a/www/node_modules/lodash/fp/values.js b/www/node_modules/lodash/fp/values.js new file mode 100644 index 0000000..3843170 --- /dev/null +++ b/www/node_modules/lodash/fp/values.js @@ -0,0 +1 @@ +module.exports = require('../values'); diff --git a/www/node_modules/lodash/fp/valuesIn.js b/www/node_modules/lodash/fp/valuesIn.js new file mode 100644 index 0000000..f81c171 --- /dev/null +++ b/www/node_modules/lodash/fp/valuesIn.js @@ -0,0 +1 @@ +module.exports = require('../valuesIn'); diff --git a/www/node_modules/lodash/fp/whereEq.js b/www/node_modules/lodash/fp/whereEq.js new file mode 100644 index 0000000..ade80f6 --- /dev/null +++ b/www/node_modules/lodash/fp/whereEq.js @@ -0,0 +1 @@ +module.exports = require('./filter'); diff --git a/www/node_modules/lodash/fp/without.js b/www/node_modules/lodash/fp/without.js new file mode 100644 index 0000000..5238e94 --- /dev/null +++ b/www/node_modules/lodash/fp/without.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('without', require('../without')); diff --git a/www/node_modules/lodash/fp/words.js b/www/node_modules/lodash/fp/words.js new file mode 100644 index 0000000..b58a485 --- /dev/null +++ b/www/node_modules/lodash/fp/words.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('words', require('../words')); diff --git a/www/node_modules/lodash/fp/wrap.js b/www/node_modules/lodash/fp/wrap.js new file mode 100644 index 0000000..56465a2 --- /dev/null +++ b/www/node_modules/lodash/fp/wrap.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('wrap', require('../wrap')); diff --git a/www/node_modules/lodash/fp/wrapperAt.js b/www/node_modules/lodash/fp/wrapperAt.js new file mode 100644 index 0000000..f8d37a1 --- /dev/null +++ b/www/node_modules/lodash/fp/wrapperAt.js @@ -0,0 +1 @@ +module.exports = require('../wrapperAt'); diff --git a/www/node_modules/lodash/fp/wrapperChain.js b/www/node_modules/lodash/fp/wrapperChain.js new file mode 100644 index 0000000..964a846 --- /dev/null +++ b/www/node_modules/lodash/fp/wrapperChain.js @@ -0,0 +1 @@ +module.exports = require('../wrapperChain'); diff --git a/www/node_modules/lodash/fp/wrapperFlatMap.js b/www/node_modules/lodash/fp/wrapperFlatMap.js new file mode 100644 index 0000000..fa030c0 --- /dev/null +++ b/www/node_modules/lodash/fp/wrapperFlatMap.js @@ -0,0 +1 @@ +module.exports = require('../wrapperFlatMap'); diff --git a/www/node_modules/lodash/fp/wrapperLodash.js b/www/node_modules/lodash/fp/wrapperLodash.js new file mode 100644 index 0000000..d62a996 --- /dev/null +++ b/www/node_modules/lodash/fp/wrapperLodash.js @@ -0,0 +1 @@ +module.exports = require('../wrapperLodash'); diff --git a/www/node_modules/lodash/fp/wrapperReverse.js b/www/node_modules/lodash/fp/wrapperReverse.js new file mode 100644 index 0000000..cf70388 --- /dev/null +++ b/www/node_modules/lodash/fp/wrapperReverse.js @@ -0,0 +1 @@ +module.exports = require('../wrapperReverse'); diff --git a/www/node_modules/lodash/fp/wrapperValue.js b/www/node_modules/lodash/fp/wrapperValue.js new file mode 100644 index 0000000..494dfb1 --- /dev/null +++ b/www/node_modules/lodash/fp/wrapperValue.js @@ -0,0 +1 @@ +module.exports = require('../wrapperValue'); diff --git a/www/node_modules/lodash/fp/xor.js b/www/node_modules/lodash/fp/xor.js new file mode 100644 index 0000000..0f3e025 --- /dev/null +++ b/www/node_modules/lodash/fp/xor.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('xor', require('../xor')); diff --git a/www/node_modules/lodash/fp/xorBy.js b/www/node_modules/lodash/fp/xorBy.js new file mode 100644 index 0000000..e48fc41 --- /dev/null +++ b/www/node_modules/lodash/fp/xorBy.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('xorBy', require('../xorBy')); diff --git a/www/node_modules/lodash/fp/xorWith.js b/www/node_modules/lodash/fp/xorWith.js new file mode 100644 index 0000000..5c2eebe --- /dev/null +++ b/www/node_modules/lodash/fp/xorWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('xorWith', require('../xorWith')); diff --git a/www/node_modules/lodash/fp/zip.js b/www/node_modules/lodash/fp/zip.js new file mode 100644 index 0000000..0cae73b --- /dev/null +++ b/www/node_modules/lodash/fp/zip.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('zip', require('../zip')); diff --git a/www/node_modules/lodash/fp/zipObj.js b/www/node_modules/lodash/fp/zipObj.js new file mode 100644 index 0000000..f4a3453 --- /dev/null +++ b/www/node_modules/lodash/fp/zipObj.js @@ -0,0 +1 @@ +module.exports = require('./zipObject'); diff --git a/www/node_modules/lodash/fp/zipObject.js b/www/node_modules/lodash/fp/zipObject.js new file mode 100644 index 0000000..8c2ff3b --- /dev/null +++ b/www/node_modules/lodash/fp/zipObject.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('zipObject', require('../zipObject')); diff --git a/www/node_modules/lodash/fp/zipObjectDeep.js b/www/node_modules/lodash/fp/zipObjectDeep.js new file mode 100644 index 0000000..a0ee4e3 --- /dev/null +++ b/www/node_modules/lodash/fp/zipObjectDeep.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('zipObjectDeep', require('../zipObjectDeep')); diff --git a/www/node_modules/lodash/fp/zipWith.js b/www/node_modules/lodash/fp/zipWith.js new file mode 100644 index 0000000..da75f3d --- /dev/null +++ b/www/node_modules/lodash/fp/zipWith.js @@ -0,0 +1,2 @@ +var convert = require('./convert'); +module.exports = convert('zipWith', require('../zipWith')); diff --git a/www/node_modules/lodash/fromPairs.js b/www/node_modules/lodash/fromPairs.js new file mode 100644 index 0000000..c18c1e3 --- /dev/null +++ b/www/node_modules/lodash/fromPairs.js @@ -0,0 +1,27 @@ +/** + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. + * @example + * + * _.fromPairs([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + */ +function fromPairs(pairs) { + var index = -1, + length = pairs ? pairs.length : 0, + result = {}; + + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } + return result; +} + +module.exports = fromPairs; diff --git a/www/node_modules/lodash/function.js b/www/node_modules/lodash/function.js new file mode 100644 index 0000000..b0fc6d9 --- /dev/null +++ b/www/node_modules/lodash/function.js @@ -0,0 +1,25 @@ +module.exports = { + 'after': require('./after'), + 'ary': require('./ary'), + 'before': require('./before'), + 'bind': require('./bind'), + 'bindKey': require('./bindKey'), + 'curry': require('./curry'), + 'curryRight': require('./curryRight'), + 'debounce': require('./debounce'), + 'defer': require('./defer'), + 'delay': require('./delay'), + 'flip': require('./flip'), + 'memoize': require('./memoize'), + 'negate': require('./negate'), + 'once': require('./once'), + 'overArgs': require('./overArgs'), + 'partial': require('./partial'), + 'partialRight': require('./partialRight'), + 'rearg': require('./rearg'), + 'rest': require('./rest'), + 'spread': require('./spread'), + 'throttle': require('./throttle'), + 'unary': require('./unary'), + 'wrap': require('./wrap') +}; diff --git a/www/node_modules/lodash/functions.js b/www/node_modules/lodash/functions.js new file mode 100644 index 0000000..b50a197 --- /dev/null +++ b/www/node_modules/lodash/functions.js @@ -0,0 +1,29 @@ +var baseFunctions = require('./_baseFunctions'), + keys = require('./keys'); + +/** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ +function functions(object) { + return object == null ? [] : baseFunctions(object, keys(object)); +} + +module.exports = functions; diff --git a/www/node_modules/lodash/functionsIn.js b/www/node_modules/lodash/functionsIn.js new file mode 100644 index 0000000..b48e5a6 --- /dev/null +++ b/www/node_modules/lodash/functionsIn.js @@ -0,0 +1,29 @@ +var baseFunctions = require('./_baseFunctions'), + keysIn = require('./keysIn'); + +/** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ +function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); +} + +module.exports = functionsIn; diff --git a/www/node_modules/lodash/get.js b/www/node_modules/lodash/get.js new file mode 100644 index 0000000..755fa05 --- /dev/null +++ b/www/node_modules/lodash/get.js @@ -0,0 +1,32 @@ +var baseGet = require('./_baseGet'); + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; +} + +module.exports = get; diff --git a/www/node_modules/lodash/groupBy.js b/www/node_modules/lodash/groupBy.js new file mode 100644 index 0000000..728a6da --- /dev/null +++ b/www/node_modules/lodash/groupBy.js @@ -0,0 +1,38 @@ +var createAggregator = require('./_createAggregator'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of elements responsible for generating the key. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } + * + * // The `_.property` iteratee shorthand. + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ +var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } +}); + +module.exports = groupBy; diff --git a/www/node_modules/lodash/gt.js b/www/node_modules/lodash/gt.js new file mode 100644 index 0000000..ddaf5ea --- /dev/null +++ b/www/node_modules/lodash/gt.js @@ -0,0 +1,25 @@ +/** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ +function gt(value, other) { + return value > other; +} + +module.exports = gt; diff --git a/www/node_modules/lodash/gte.js b/www/node_modules/lodash/gte.js new file mode 100644 index 0000000..4a5ffb5 --- /dev/null +++ b/www/node_modules/lodash/gte.js @@ -0,0 +1,25 @@ +/** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ +function gte(value, other) { + return value >= other; +} + +module.exports = gte; diff --git a/www/node_modules/lodash/has.js b/www/node_modules/lodash/has.js new file mode 100644 index 0000000..d66d2de --- /dev/null +++ b/www/node_modules/lodash/has.js @@ -0,0 +1,34 @@ +var baseHas = require('./_baseHas'), + hasPath = require('./_hasPath'); + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return hasPath(object, path, baseHas); +} + +module.exports = has; diff --git a/www/node_modules/lodash/hasIn.js b/www/node_modules/lodash/hasIn.js new file mode 100644 index 0000000..7da6b7d --- /dev/null +++ b/www/node_modules/lodash/hasIn.js @@ -0,0 +1,33 @@ +var baseHasIn = require('./_baseHasIn'), + hasPath = require('./_hasPath'); + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b.c'); + * // => true + * + * _.hasIn(object, ['a', 'b', 'c']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return hasPath(object, path, baseHasIn); +} + +module.exports = hasIn; diff --git a/www/node_modules/lodash/head.js b/www/node_modules/lodash/head.js new file mode 100644 index 0000000..30b47b0 --- /dev/null +++ b/www/node_modules/lodash/head.js @@ -0,0 +1,22 @@ +/** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ +function head(array) { + return array ? array[0] : undefined; +} + +module.exports = head; diff --git a/www/node_modules/lodash/identity.js b/www/node_modules/lodash/identity.js new file mode 100644 index 0000000..da7dea1 --- /dev/null +++ b/www/node_modules/lodash/identity.js @@ -0,0 +1,20 @@ +/** + * This method returns the first argument given to it. + * + * @static + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'user': 'fred' }; + * + * _.identity(object) === object; + * // => true + */ +function identity(value) { + return value; +} + +module.exports = identity; diff --git a/www/node_modules/lodash/inRange.js b/www/node_modules/lodash/inRange.js new file mode 100644 index 0000000..69c6110 --- /dev/null +++ b/www/node_modules/lodash/inRange.js @@ -0,0 +1,52 @@ +var baseInRange = require('./_baseInRange'), + toNumber = require('./toNumber'); + +/** + * Checks if `n` is between `start` and up to but not including, `end`. If + * `end` is not specified it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. + * + * @static + * @memberOf _ + * @category Number + * @param {number} number The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + * + * _.inRange(-3, -2, -6); + * // => true + */ +function inRange(number, start, end) { + start = toNumber(start) || 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = toNumber(end) || 0; + } + number = toNumber(number); + return baseInRange(number, start, end); +} + +module.exports = inRange; diff --git a/www/node_modules/lodash/includes.js b/www/node_modules/lodash/includes.js new file mode 100644 index 0000000..01d6844 --- /dev/null +++ b/www/node_modules/lodash/includes.js @@ -0,0 +1,51 @@ +var baseIndexOf = require('./_baseIndexOf'), + isArrayLike = require('./isArrayLike'), + isString = require('./isString'), + toInteger = require('./toInteger'), + values = require('./values'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Checks if `value` is in `collection`. If `collection` is a string it's checked + * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ +function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return isString(collection) + ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) + : (!!length && baseIndexOf(collection, value, fromIndex) > -1); +} + +module.exports = includes; diff --git a/www/node_modules/lodash/index.js b/www/node_modules/lodash/index.js new file mode 100644 index 0000000..5d063e2 --- /dev/null +++ b/www/node_modules/lodash/index.js @@ -0,0 +1 @@ +module.exports = require('./lodash'); \ No newline at end of file diff --git a/www/node_modules/lodash/indexOf.js b/www/node_modules/lodash/indexOf.js new file mode 100644 index 0000000..4474d0c --- /dev/null +++ b/www/node_modules/lodash/indexOf.js @@ -0,0 +1,41 @@ +var baseIndexOf = require('./_baseIndexOf'), + toInteger = require('./toInteger'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ +function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + fromIndex = toInteger(fromIndex); + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return baseIndexOf(array, value, fromIndex); +} + +module.exports = indexOf; diff --git a/www/node_modules/lodash/initial.js b/www/node_modules/lodash/initial.js new file mode 100644 index 0000000..59b7a7d --- /dev/null +++ b/www/node_modules/lodash/initial.js @@ -0,0 +1,20 @@ +var dropRight = require('./dropRight'); + +/** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ +function initial(array) { + return dropRight(array, 1); +} + +module.exports = initial; diff --git a/www/node_modules/lodash/intersection.js b/www/node_modules/lodash/intersection.js new file mode 100644 index 0000000..25495fe --- /dev/null +++ b/www/node_modules/lodash/intersection.js @@ -0,0 +1,29 @@ +var arrayMap = require('./_arrayMap'), + baseCastArrayLikeObject = require('./_baseCastArrayLikeObject'), + baseIntersection = require('./_baseIntersection'), + rest = require('./rest'); + +/** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. The order of result values is determined by the + * order they occur in the first array. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersection([2, 1], [4, 2], [1, 2]); + * // => [2] + */ +var intersection = rest(function(arrays) { + var mapped = arrayMap(arrays, baseCastArrayLikeObject); + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped) + : []; +}); + +module.exports = intersection; diff --git a/www/node_modules/lodash/intersectionBy.js b/www/node_modules/lodash/intersectionBy.js new file mode 100644 index 0000000..41bcec5 --- /dev/null +++ b/www/node_modules/lodash/intersectionBy.js @@ -0,0 +1,43 @@ +var arrayMap = require('./_arrayMap'), + baseCastArrayLikeObject = require('./_baseCastArrayLikeObject'), + baseIntersection = require('./_baseIntersection'), + baseIteratee = require('./_baseIteratee'), + last = require('./last'), + rest = require('./rest'); + +/** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which they're compared. Result values are chosen from the first array. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [2.1] + * + * // The `_.property` iteratee shorthand. + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ +var intersectionBy = rest(function(arrays) { + var iteratee = last(arrays), + mapped = arrayMap(arrays, baseCastArrayLikeObject); + + if (iteratee === last(mapped)) { + iteratee = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, baseIteratee(iteratee)) + : []; +}); + +module.exports = intersectionBy; diff --git a/www/node_modules/lodash/intersectionWith.js b/www/node_modules/lodash/intersectionWith.js new file mode 100644 index 0000000..c24c25a --- /dev/null +++ b/www/node_modules/lodash/intersectionWith.js @@ -0,0 +1,41 @@ +var arrayMap = require('./_arrayMap'), + baseCastArrayLikeObject = require('./_baseCastArrayLikeObject'), + baseIntersection = require('./_baseIntersection'), + last = require('./last'), + rest = require('./rest'); + +/** + * This method is like `_.intersection` except that it accepts `comparator` + * which is invoked to compare elements of `arrays`. Result values are chosen + * from the first array. The comparator is invoked with two arguments: + * (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.intersectionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }] + */ +var intersectionWith = rest(function(arrays) { + var comparator = last(arrays), + mapped = arrayMap(arrays, baseCastArrayLikeObject); + + if (comparator === last(mapped)) { + comparator = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, undefined, comparator) + : []; +}); + +module.exports = intersectionWith; diff --git a/www/node_modules/lodash/invert.js b/www/node_modules/lodash/invert.js new file mode 100644 index 0000000..11628b1 --- /dev/null +++ b/www/node_modules/lodash/invert.js @@ -0,0 +1,26 @@ +var constant = require('./constant'), + createInverter = require('./_createInverter'), + identity = require('./identity'); + +/** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite property + * assignments of previous values. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ +var invert = createInverter(function(result, value, key) { + result[value] = key; +}, constant(identity)); + +module.exports = invert; diff --git a/www/node_modules/lodash/invertBy.js b/www/node_modules/lodash/invertBy.js new file mode 100644 index 0000000..513f62b --- /dev/null +++ b/www/node_modules/lodash/invertBy.js @@ -0,0 +1,43 @@ +var baseIteratee = require('./_baseIteratee'), + createInverter = require('./_createInverter'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` through `iteratee`. + * The corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ +var invertBy = createInverter(function(result, value, key) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } +}, baseIteratee); + +module.exports = invertBy; diff --git a/www/node_modules/lodash/invoke.js b/www/node_modules/lodash/invoke.js new file mode 100644 index 0000000..f090a72 --- /dev/null +++ b/www/node_modules/lodash/invoke.js @@ -0,0 +1,23 @@ +var baseInvoke = require('./_baseInvoke'), + rest = require('./rest'); + +/** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ +var invoke = rest(baseInvoke); + +module.exports = invoke; diff --git a/www/node_modules/lodash/invokeMap.js b/www/node_modules/lodash/invokeMap.js new file mode 100644 index 0000000..42c8fbe --- /dev/null +++ b/www/node_modules/lodash/invokeMap.js @@ -0,0 +1,43 @@ +var apply = require('./_apply'), + baseEach = require('./_baseEach'), + baseInvoke = require('./_baseInvoke'), + isArrayLike = require('./isArrayLike'), + isKey = require('./_isKey'), + rest = require('./rest'); + +/** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it's + * invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke each method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invokeMap([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ +var invokeMap = rest(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args); + }); + return result; +}); + +module.exports = invokeMap; diff --git a/www/node_modules/lodash/isArguments.js b/www/node_modules/lodash/isArguments.js new file mode 100644 index 0000000..73fbafe --- /dev/null +++ b/www/node_modules/lodash/isArguments.js @@ -0,0 +1,43 @@ +var isArrayLikeObject = require('./isArrayLikeObject'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +module.exports = isArguments; diff --git a/www/node_modules/lodash/isArray.js b/www/node_modules/lodash/isArray.js new file mode 100644 index 0000000..fa9b055 --- /dev/null +++ b/www/node_modules/lodash/isArray.js @@ -0,0 +1,26 @@ +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @type {Function} + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +module.exports = isArray; diff --git a/www/node_modules/lodash/isArrayBuffer.js b/www/node_modules/lodash/isArrayBuffer.js new file mode 100644 index 0000000..a22a9ee --- /dev/null +++ b/www/node_modules/lodash/isArrayBuffer.js @@ -0,0 +1,34 @@ +var isObjectLike = require('./isObjectLike'); + +var arrayBufferTag = '[object ArrayBuffer]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ +function isArrayBuffer(value) { + return isObjectLike(value) && objectToString.call(value) == arrayBufferTag; +} + +module.exports = isArrayBuffer; diff --git a/www/node_modules/lodash/isArrayLike.js b/www/node_modules/lodash/isArrayLike.js new file mode 100644 index 0000000..3e809f4 --- /dev/null +++ b/www/node_modules/lodash/isArrayLike.js @@ -0,0 +1,33 @@ +var getLength = require('./_getLength'), + isFunction = require('./isFunction'), + isLength = require('./isLength'); + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(getLength(value)) && !isFunction(value); +} + +module.exports = isArrayLike; diff --git a/www/node_modules/lodash/isArrayLikeObject.js b/www/node_modules/lodash/isArrayLikeObject.js new file mode 100644 index 0000000..0b8b2ca --- /dev/null +++ b/www/node_modules/lodash/isArrayLikeObject.js @@ -0,0 +1,31 @@ +var isArrayLike = require('./isArrayLike'), + isObjectLike = require('./isObjectLike'); + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +module.exports = isArrayLikeObject; diff --git a/www/node_modules/lodash/isBoolean.js b/www/node_modules/lodash/isBoolean.js new file mode 100644 index 0000000..53ec5d6 --- /dev/null +++ b/www/node_modules/lodash/isBoolean.js @@ -0,0 +1,36 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ +function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && objectToString.call(value) == boolTag); +} + +module.exports = isBoolean; diff --git a/www/node_modules/lodash/isBuffer.js b/www/node_modules/lodash/isBuffer.js new file mode 100644 index 0000000..cee6b22 --- /dev/null +++ b/www/node_modules/lodash/isBuffer.js @@ -0,0 +1,48 @@ +var constant = require('./constant'), + root = require('./_root'); + +/** Used to determine if values are of the language type `Object`. */ +var objectTypes = { + 'function': true, + 'object': true +}; + +/** Detect free variable `exports`. */ +var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; + +/** Detect free variable `module`. */ +var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = (freeModule && freeModule.exports === freeExports) + ? freeExports + : undefined; + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined; + +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = !Buffer ? constant(false) : function(value) { + return value instanceof Buffer; +}; + +module.exports = isBuffer; diff --git a/www/node_modules/lodash/isDate.js b/www/node_modules/lodash/isDate.js new file mode 100644 index 0000000..6e3611a --- /dev/null +++ b/www/node_modules/lodash/isDate.js @@ -0,0 +1,35 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var dateTag = '[object Date]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ +function isDate(value) { + return isObjectLike(value) && objectToString.call(value) == dateTag; +} + +module.exports = isDate; diff --git a/www/node_modules/lodash/isElement.js b/www/node_modules/lodash/isElement.js new file mode 100644 index 0000000..447d6bc --- /dev/null +++ b/www/node_modules/lodash/isElement.js @@ -0,0 +1,24 @@ +var isObjectLike = require('./isObjectLike'), + isPlainObject = require('./isPlainObject'); + +/** + * Checks if `value` is likely a DOM element. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ +function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); +} + +module.exports = isElement; diff --git a/www/node_modules/lodash/isEmpty.js b/www/node_modules/lodash/isEmpty.js new file mode 100644 index 0000000..f81838d --- /dev/null +++ b/www/node_modules/lodash/isEmpty.js @@ -0,0 +1,54 @@ +var isArguments = require('./isArguments'), + isArray = require('./isArray'), + isArrayLike = require('./isArrayLike'), + isFunction = require('./isFunction'), + isString = require('./isString'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Checks if `value` is an empty collection or object. A value is considered + * empty if it's an `arguments` object, array, string, or jQuery-like collection + * with a length of `0` or has no own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ +function isEmpty(value) { + if (isArrayLike(value) && + (isArray(value) || isString(value) || + isFunction(value.splice) || isArguments(value))) { + return !value.length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; +} + +module.exports = isEmpty; diff --git a/www/node_modules/lodash/isEqual.js b/www/node_modules/lodash/isEqual.js new file mode 100644 index 0000000..43a3a2b --- /dev/null +++ b/www/node_modules/lodash/isEqual.js @@ -0,0 +1,34 @@ +var baseIsEqual = require('./_baseIsEqual'); + +/** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are **not** supported. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ +function isEqual(value, other) { + return baseIsEqual(value, other); +} + +module.exports = isEqual; diff --git a/www/node_modules/lodash/isEqualWith.js b/www/node_modules/lodash/isEqualWith.js new file mode 100644 index 0000000..4643a35 --- /dev/null +++ b/www/node_modules/lodash/isEqualWith.js @@ -0,0 +1,40 @@ +var baseIsEqual = require('./_baseIsEqual'); + +/** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ +function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; +} + +module.exports = isEqualWith; diff --git a/www/node_modules/lodash/isError.js b/www/node_modules/lodash/isError.js new file mode 100644 index 0000000..6065453 --- /dev/null +++ b/www/node_modules/lodash/isError.js @@ -0,0 +1,40 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var errorTag = '[object Error]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ +function isError(value) { + if (!isObjectLike(value)) { + return false; + } + return (objectToString.call(value) == errorTag) || + (typeof value.message == 'string' && typeof value.name == 'string'); +} + +module.exports = isError; diff --git a/www/node_modules/lodash/isFinite.js b/www/node_modules/lodash/isFinite.js new file mode 100644 index 0000000..44be4bc --- /dev/null +++ b/www/node_modules/lodash/isFinite.js @@ -0,0 +1,34 @@ +var root = require('./_root'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeIsFinite = root.isFinite; + +/** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MAX_VALUE); + * // => true + * + * _.isFinite(3.14); + * // => true + * + * _.isFinite(Infinity); + * // => false + */ +function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); +} + +module.exports = isFinite; diff --git a/www/node_modules/lodash/isFunction.js b/www/node_modules/lodash/isFunction.js new file mode 100644 index 0000000..fd8c4ad --- /dev/null +++ b/www/node_modules/lodash/isFunction.js @@ -0,0 +1,40 @@ +var isObject = require('./isObject'); + +/** `Object#toString` result references. */ +var funcTag = '[object Function]', + genTag = '[object GeneratorFunction]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8 which returns 'object' for typed array and weak map constructors, + // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +module.exports = isFunction; diff --git a/www/node_modules/lodash/isInteger.js b/www/node_modules/lodash/isInteger.js new file mode 100644 index 0000000..1bfcc65 --- /dev/null +++ b/www/node_modules/lodash/isInteger.js @@ -0,0 +1,31 @@ +var toInteger = require('./toInteger'); + +/** + * Checks if `value` is an integer. + * + * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ +function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); +} + +module.exports = isInteger; diff --git a/www/node_modules/lodash/isLength.js b/www/node_modules/lodash/isLength.js new file mode 100644 index 0000000..b095123 --- /dev/null +++ b/www/node_modules/lodash/isLength.js @@ -0,0 +1,33 @@ +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +module.exports = isLength; diff --git a/www/node_modules/lodash/isMap.js b/www/node_modules/lodash/isMap.js new file mode 100644 index 0000000..bc92def --- /dev/null +++ b/www/node_modules/lodash/isMap.js @@ -0,0 +1,27 @@ +var getTag = require('./_getTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var mapTag = '[object Map]'; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +function isMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; +} + +module.exports = isMap; diff --git a/www/node_modules/lodash/isMatch.js b/www/node_modules/lodash/isMatch.js new file mode 100644 index 0000000..faf0898 --- /dev/null +++ b/www/node_modules/lodash/isMatch.js @@ -0,0 +1,31 @@ +var baseIsMatch = require('./_baseIsMatch'), + getMatchData = require('./_getMatchData'); + +/** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. This method is + * equivalent to a `_.matches` function when `source` is partially applied. + * + * **Note:** This method supports comparing the same values as `_.isEqual`. + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + */ +function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); +} + +module.exports = isMatch; diff --git a/www/node_modules/lodash/isMatchWith.js b/www/node_modules/lodash/isMatchWith.js new file mode 100644 index 0000000..2460eb3 --- /dev/null +++ b/www/node_modules/lodash/isMatchWith.js @@ -0,0 +1,40 @@ +var baseIsMatch = require('./_baseIsMatch'), + getMatchData = require('./_getMatchData'); + +/** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ +function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseIsMatch(object, source, getMatchData(source), customizer); +} + +module.exports = isMatchWith; diff --git a/www/node_modules/lodash/isNaN.js b/www/node_modules/lodash/isNaN.js new file mode 100644 index 0000000..5b757b1 --- /dev/null +++ b/www/node_modules/lodash/isNaN.js @@ -0,0 +1,34 @@ +var isNumber = require('./isNumber'); + +/** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ +function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE. + return isNumber(value) && value != +value; +} + +module.exports = isNaN; diff --git a/www/node_modules/lodash/isNative.js b/www/node_modules/lodash/isNative.js new file mode 100644 index 0000000..616a832 --- /dev/null +++ b/www/node_modules/lodash/isNative.js @@ -0,0 +1,53 @@ +var isFunction = require('./isFunction'), + isHostObject = require('./_isHostObject'), + isObjectLike = require('./isObjectLike'); + +/** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to detect host constructors (Safari > 5). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = Function.prototype.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ +function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(funcToString.call(value)); + } + return isObjectLike(value) && + (isHostObject(value) ? reIsNative : reIsHostCtor).test(value); +} + +module.exports = isNative; diff --git a/www/node_modules/lodash/isNil.js b/www/node_modules/lodash/isNil.js new file mode 100644 index 0000000..c4197fb --- /dev/null +++ b/www/node_modules/lodash/isNil.js @@ -0,0 +1,24 @@ +/** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ +function isNil(value) { + return value == null; +} + +module.exports = isNil; diff --git a/www/node_modules/lodash/isNull.js b/www/node_modules/lodash/isNull.js new file mode 100644 index 0000000..ec66c4d --- /dev/null +++ b/www/node_modules/lodash/isNull.js @@ -0,0 +1,21 @@ +/** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ +function isNull(value) { + return value === null; +} + +module.exports = isNull; diff --git a/www/node_modules/lodash/isNumber.js b/www/node_modules/lodash/isNumber.js new file mode 100644 index 0000000..0c8fb9a --- /dev/null +++ b/www/node_modules/lodash/isNumber.js @@ -0,0 +1,45 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var numberTag = '[object Number]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ +function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && objectToString.call(value) == numberTag); +} + +module.exports = isNumber; diff --git a/www/node_modules/lodash/isObject.js b/www/node_modules/lodash/isObject.js new file mode 100644 index 0000000..41993db --- /dev/null +++ b/www/node_modules/lodash/isObject.js @@ -0,0 +1,29 @@ +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +module.exports = isObject; diff --git a/www/node_modules/lodash/isObjectLike.js b/www/node_modules/lodash/isObjectLike.js new file mode 100644 index 0000000..240167a --- /dev/null +++ b/www/node_modules/lodash/isObjectLike.js @@ -0,0 +1,28 @@ +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +module.exports = isObjectLike; diff --git a/www/node_modules/lodash/isPlainObject.js b/www/node_modules/lodash/isPlainObject.js new file mode 100644 index 0000000..5491848 --- /dev/null +++ b/www/node_modules/lodash/isPlainObject.js @@ -0,0 +1,66 @@ +var isHostObject = require('./_isHostObject'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = Function.prototype.toString; + +/** Used to infer the `Object` constructor. */ +var objectCtorString = funcToString.call(Object); + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var getPrototypeOf = Object.getPrototypeOf; + +/** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ +function isPlainObject(value) { + if (!isObjectLike(value) || + objectToString.call(value) != objectTag || isHostObject(value)) { + return false; + } + var proto = getPrototypeOf(value); + if (proto === null) { + return true; + } + var Ctor = proto.constructor; + return (typeof Ctor == 'function' && + Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); +} + +module.exports = isPlainObject; diff --git a/www/node_modules/lodash/isRegExp.js b/www/node_modules/lodash/isRegExp.js new file mode 100644 index 0000000..e127e5a --- /dev/null +++ b/www/node_modules/lodash/isRegExp.js @@ -0,0 +1,35 @@ +var isObject = require('./isObject'); + +/** `Object#toString` result references. */ +var regexpTag = '[object RegExp]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ +function isRegExp(value) { + return isObject(value) && objectToString.call(value) == regexpTag; +} + +module.exports = isRegExp; diff --git a/www/node_modules/lodash/isSafeInteger.js b/www/node_modules/lodash/isSafeInteger.js new file mode 100644 index 0000000..f601243 --- /dev/null +++ b/www/node_modules/lodash/isSafeInteger.js @@ -0,0 +1,35 @@ +var isInteger = require('./isInteger'); + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ +function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; +} + +module.exports = isSafeInteger; diff --git a/www/node_modules/lodash/isSet.js b/www/node_modules/lodash/isSet.js new file mode 100644 index 0000000..e1d50be --- /dev/null +++ b/www/node_modules/lodash/isSet.js @@ -0,0 +1,27 @@ +var getTag = require('./_getTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var setTag = '[object Set]'; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +function isSet(value) { + return isObjectLike(value) && getTag(value) == setTag; +} + +module.exports = isSet; diff --git a/www/node_modules/lodash/isString.js b/www/node_modules/lodash/isString.js new file mode 100644 index 0000000..5ed392e --- /dev/null +++ b/www/node_modules/lodash/isString.js @@ -0,0 +1,37 @@ +var isArray = require('./isArray'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); +} + +module.exports = isString; diff --git a/www/node_modules/lodash/isSymbol.js b/www/node_modules/lodash/isSymbol.js new file mode 100644 index 0000000..5e11a00 --- /dev/null +++ b/www/node_modules/lodash/isSymbol.js @@ -0,0 +1,36 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +module.exports = isSymbol; diff --git a/www/node_modules/lodash/isTypedArray.js b/www/node_modules/lodash/isTypedArray.js new file mode 100644 index 0000000..1283322 --- /dev/null +++ b/www/node_modules/lodash/isTypedArray.js @@ -0,0 +1,75 @@ +var isLength = require('./isLength'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dateTag] = typedArrayTags[errorTag] = +typedArrayTags[funcTag] = typedArrayTags[mapTag] = +typedArrayTags[numberTag] = typedArrayTags[objectTag] = +typedArrayTags[regexpTag] = typedArrayTags[setTag] = +typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ +function isTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; +} + +module.exports = isTypedArray; diff --git a/www/node_modules/lodash/isUndefined.js b/www/node_modules/lodash/isUndefined.js new file mode 100644 index 0000000..d64e560 --- /dev/null +++ b/www/node_modules/lodash/isUndefined.js @@ -0,0 +1,21 @@ +/** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +module.exports = isUndefined; diff --git a/www/node_modules/lodash/isWeakMap.js b/www/node_modules/lodash/isWeakMap.js new file mode 100644 index 0000000..d934a9f --- /dev/null +++ b/www/node_modules/lodash/isWeakMap.js @@ -0,0 +1,27 @@ +var getTag = require('./_getTag'), + isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var weakMapTag = '[object WeakMap]'; + +/** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ +function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; +} + +module.exports = isWeakMap; diff --git a/www/node_modules/lodash/isWeakSet.js b/www/node_modules/lodash/isWeakSet.js new file mode 100644 index 0000000..40674f4 --- /dev/null +++ b/www/node_modules/lodash/isWeakSet.js @@ -0,0 +1,35 @@ +var isObjectLike = require('./isObjectLike'); + +/** `Object#toString` result references. */ +var weakSetTag = '[object WeakSet]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ +function isWeakSet(value) { + return isObjectLike(value) && objectToString.call(value) == weakSetTag; +} + +module.exports = isWeakSet; diff --git a/www/node_modules/lodash/iteratee.js b/www/node_modules/lodash/iteratee.js new file mode 100644 index 0000000..e9d2f8a --- /dev/null +++ b/www/node_modules/lodash/iteratee.js @@ -0,0 +1,38 @@ +var baseClone = require('./_baseClone'), + baseIteratee = require('./_baseIteratee'); + +/** + * Creates a function that invokes `func` with the arguments of the created + * function. If `func` is a property name the created callback returns the + * property value for a given element. If `func` is an object the created + * callback returns `true` for elements that contain the equivalent object + * properties, otherwise it returns `false`. + * + * @static + * @memberOf _ + * @category Util + * @param {*} [func=_.identity] The value to convert to a callback. + * @returns {Function} Returns the callback. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // Create custom iteratee shorthands. + * _.iteratee = _.wrap(_.iteratee, function(callback, func) { + * var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func); + * return !p ? callback(func) : function(object) { + * return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]); + * }; + * }); + * + * _.filter(users, 'age > 36'); + * // => [{ 'user': 'fred', 'age': 40 }] + */ +function iteratee(func) { + return baseIteratee(typeof func == 'function' ? func : baseClone(func, true)); +} + +module.exports = iteratee; diff --git a/www/node_modules/lodash/join.js b/www/node_modules/lodash/join.js new file mode 100644 index 0000000..79d308d --- /dev/null +++ b/www/node_modules/lodash/join.js @@ -0,0 +1,25 @@ +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeJoin = arrayProto.join; + +/** + * Converts all elements in `array` into a string separated by `separator`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to convert. + * @param {string} [separator=','] The element separator. + * @returns {string} Returns the joined string. + * @example + * + * _.join(['a', 'b', 'c'], '~'); + * // => 'a~b~c' + */ +function join(array, separator) { + return array ? nativeJoin.call(array, separator) : ''; +} + +module.exports = join; diff --git a/www/node_modules/lodash/kebabCase.js b/www/node_modules/lodash/kebabCase.js new file mode 100644 index 0000000..f29124f --- /dev/null +++ b/www/node_modules/lodash/kebabCase.js @@ -0,0 +1,26 @@ +var createCompounder = require('./_createCompounder'); + +/** + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' + */ +var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); +}); + +module.exports = kebabCase; diff --git a/www/node_modules/lodash/keyBy.js b/www/node_modules/lodash/keyBy.js new file mode 100644 index 0000000..febc86b --- /dev/null +++ b/www/node_modules/lodash/keyBy.js @@ -0,0 +1,34 @@ +var createAggregator = require('./_createAggregator'); + +/** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var array = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.keyBy(array, function(o) { + * return String.fromCharCode(o.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.keyBy(array, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + */ +var keyBy = createAggregator(function(result, value, key) { + result[key] = value; +}); + +module.exports = keyBy; diff --git a/www/node_modules/lodash/keys.js b/www/node_modules/lodash/keys.js new file mode 100644 index 0000000..eac239f --- /dev/null +++ b/www/node_modules/lodash/keys.js @@ -0,0 +1,55 @@ +var baseHas = require('./_baseHas'), + baseKeys = require('./_baseKeys'), + indexKeys = require('./_indexKeys'), + isArrayLike = require('./isArrayLike'), + isIndex = require('./_isIndex'), + isPrototype = require('./_isPrototype'); + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + var isProto = isPrototype(object); + if (!(isProto || isArrayLike(object))) { + return baseKeys(object); + } + var indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + for (var key in object) { + if (baseHas(object, key) && + !(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(isProto && key == 'constructor')) { + result.push(key); + } + } + return result; +} + +module.exports = keys; diff --git a/www/node_modules/lodash/keysIn.js b/www/node_modules/lodash/keysIn.js new file mode 100644 index 0000000..e327b87 --- /dev/null +++ b/www/node_modules/lodash/keysIn.js @@ -0,0 +1,54 @@ +var baseKeysIn = require('./_baseKeysIn'), + indexKeys = require('./_indexKeys'), + isIndex = require('./_isIndex'), + isPrototype = require('./_isPrototype'); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + var index = -1, + isProto = isPrototype(object), + props = baseKeysIn(object), + propsLength = props.length, + indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + while (++index < propsLength) { + var key = props[index]; + if (!(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} + +module.exports = keysIn; diff --git a/www/node_modules/lodash/lang.js b/www/node_modules/lodash/lang.js new file mode 100644 index 0000000..665f5c6 --- /dev/null +++ b/www/node_modules/lodash/lang.js @@ -0,0 +1,56 @@ +module.exports = { + 'castArray': require('./castArray'), + 'clone': require('./clone'), + 'cloneDeep': require('./cloneDeep'), + 'cloneDeepWith': require('./cloneDeepWith'), + 'cloneWith': require('./cloneWith'), + 'eq': require('./eq'), + 'gt': require('./gt'), + 'gte': require('./gte'), + 'isArguments': require('./isArguments'), + 'isArray': require('./isArray'), + 'isArrayBuffer': require('./isArrayBuffer'), + 'isArrayLike': require('./isArrayLike'), + 'isArrayLikeObject': require('./isArrayLikeObject'), + 'isBoolean': require('./isBoolean'), + 'isBuffer': require('./isBuffer'), + 'isDate': require('./isDate'), + 'isElement': require('./isElement'), + 'isEmpty': require('./isEmpty'), + 'isEqual': require('./isEqual'), + 'isEqualWith': require('./isEqualWith'), + 'isError': require('./isError'), + 'isFinite': require('./isFinite'), + 'isFunction': require('./isFunction'), + 'isInteger': require('./isInteger'), + 'isLength': require('./isLength'), + 'isMap': require('./isMap'), + 'isMatch': require('./isMatch'), + 'isMatchWith': require('./isMatchWith'), + 'isNaN': require('./isNaN'), + 'isNative': require('./isNative'), + 'isNil': require('./isNil'), + 'isNull': require('./isNull'), + 'isNumber': require('./isNumber'), + 'isObject': require('./isObject'), + 'isObjectLike': require('./isObjectLike'), + 'isPlainObject': require('./isPlainObject'), + 'isRegExp': require('./isRegExp'), + 'isSafeInteger': require('./isSafeInteger'), + 'isSet': require('./isSet'), + 'isString': require('./isString'), + 'isSymbol': require('./isSymbol'), + 'isTypedArray': require('./isTypedArray'), + 'isUndefined': require('./isUndefined'), + 'isWeakMap': require('./isWeakMap'), + 'isWeakSet': require('./isWeakSet'), + 'lt': require('./lt'), + 'lte': require('./lte'), + 'toArray': require('./toArray'), + 'toInteger': require('./toInteger'), + 'toLength': require('./toLength'), + 'toNumber': require('./toNumber'), + 'toPlainObject': require('./toPlainObject'), + 'toSafeInteger': require('./toSafeInteger'), + 'toString': require('./toString') +}; diff --git a/www/node_modules/lodash/last.js b/www/node_modules/lodash/last.js new file mode 100644 index 0000000..299af31 --- /dev/null +++ b/www/node_modules/lodash/last.js @@ -0,0 +1,19 @@ +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; +} + +module.exports = last; diff --git a/www/node_modules/lodash/lastIndexOf.js b/www/node_modules/lodash/lastIndexOf.js new file mode 100644 index 0000000..1eb2f28 --- /dev/null +++ b/www/node_modules/lodash/lastIndexOf.js @@ -0,0 +1,49 @@ +var indexOfNaN = require('./_indexOfNaN'), + toInteger = require('./toInteger'); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max, + nativeMin = Math.min; + +/** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // Search from the `fromIndex`. + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + */ +function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +module.exports = lastIndexOf; diff --git a/www/node_modules/lodash/lodash.js b/www/node_modules/lodash/lodash.js new file mode 100644 index 0000000..0fc4b1c --- /dev/null +++ b/www/node_modules/lodash/lodash.js @@ -0,0 +1,15073 @@ +/** + * @license + * lodash 4.6.1 (Custom Build) + * Build: `lodash -d -o ./foo/lodash.js` + * Copyright 2012-2016 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '4.6.1'; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64, + ARY_FLAG = 128, + REARG_FLAG = 256, + FLIP_FLAG = 512; + + /** Used to compose bitmasks for comparison styles. */ + var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + + /** Used as default options for `_.truncate`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect hot functions by number of calls within a span of milliseconds. */ + var HOT_COUNT = 150, + HOT_SPAN = 16; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2, + LAZY_WHILE_FLAG = 3; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]', + weakSetTag = '[object WeakSet]'; + + var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, + reUnescapedHtml = /[&<>"'`]/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g; + + /** Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, + reHasRegExpChar = RegExp(reRegExpChar.source); + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g, + reTrimStart = /^\s+/, + reTrimEnd = /\s+$/; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect hexadecimal string values. */ + var reHasHexPrefix = /^0x/i; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; + + /** Used to detect host constructors (Safari > 5). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect octal string values. */ + var reIsOctal = /^0o[0-7]+$/i; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ + var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; + + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsDingbatRange = '\\u2700-\\u27bf', + rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', + rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', + rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', + rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d', + rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', + rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', + rsVarRange = '\\ufe0e\\ufe0f', + rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange; + + /** Used to compose unicode capture groups. */ + var rsAstral = '[' + rsAstralRange + ']', + rsBreak = '[' + rsBreakRange + ']', + rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', + rsDigits = '\\d+', + rsDingbat = '[' + rsDingbatRange + ']', + rsLower = '[' + rsLowerRange + ']', + rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsUpper = '[' + rsUpperRange + ']', + rsZWJ = '\\u200d'; + + /** Used to compose unicode regexes. */ + var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')', + rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')', + reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ + var reComboMark = RegExp(rsCombo, 'g'); + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); + + /** Used to match non-compound words composed of alphanumeric characters. */ + var reBasicWord = /[a-zA-Z0-9]+/g; + + /** Used to match complex or compound words. */ + var reComplexWord = RegExp([ + rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', + rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')', + rsUpper + '?' + rsLowerMisc + '+', + rsUpper + '+', + rsDigits, + rsEmoji + ].join('|'), 'g'); + + /** Used to detect strings that need a more robust regexp to match words. */ + var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; + + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'Buffer', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', + 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', '_', + 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' + ]; + + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dateTag] = typedArrayTags[errorTag] = + typedArrayTags[funcTag] = typedArrayTags[mapTag] = + typedArrayTags[numberTag] = typedArrayTags[objectTag] = + typedArrayTags[regexpTag] = typedArrayTags[setTag] = + typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = + cloneableTags[dateTag] = cloneableTags[float32Tag] = + cloneableTags[float64Tag] = cloneableTags[int8Tag] = + cloneableTags[int16Tag] = cloneableTags[int32Tag] = + cloneableTags[mapTag] = cloneableTags[numberTag] = + cloneableTags[objectTag] = cloneableTags[regexpTag] = + cloneableTags[setTag] = cloneableTags[stringTag] = + cloneableTags[symbolTag] = cloneableTags[uint8Tag] = + cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = + cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Used to map latin-1 supplementary letters to basic latin letters. */ + var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' + }; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' + }; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Built-in method references without a dependency on `root`. */ + var freeParseFloat = parseFloat, + freeParseInt = parseInt; + + /** Detect free variable `exports`. */ + var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; + + /** Detect free variable `module`. */ + var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = (freeModule && freeModule.exports === freeExports) + ? freeExports + : undefined; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); + + /** Detect free variable `self`. */ + var freeSelf = checkGlobal(objectTypes[typeof self] && self); + + /** Detect free variable `window`. */ + var freeWindow = checkGlobal(objectTypes[typeof window] && window); + + /** Detect `this` as the global object. */ + var thisGlobal = checkGlobal(objectTypes[typeof this] && this); + + /** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || + ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || + freeSelf || thisGlobal || Function('return this')(); + + /*--------------------------------------------------------------------------*/ + + /** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ + function addMapEntry(map, pair) { + // Don't return `Map#set` because it doesn't return the map instance in IE 11. + map.set(pair[0], pair[1]); + return map; + } + + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + set.add(value); + return set; + } + + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + var length = args.length; + switch (length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /** + * A specialized version of `baseAggregator` for arrays. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function arrayAggregator(array, setter, iteratee, accumulator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + setter(accumulator, value, iteratee(value), array); + } + return accumulator; + } + + /** + * Creates a new array concatenating `array` with `other`. + * + * @private + * @param {Array} array The first array to concatenate. + * @param {Array} other The second array to concatenate. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); + + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} array The array to search. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludes(array, value) { + return !!array.length && baseIndexOf(array, value, 0) > -1; + } + + /** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to search. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; + } + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initAccum) { + var length = array.length; + if (initAccum && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? current === current + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; + } + + /** + * The base implementation of methods like `_.find` and `_.findKey`, without + * support for iteratee shorthands, which iterates over `collection` using + * `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); + } + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * This function is like `baseIndexOf` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @param {Function} comparator The comparator invoked per element. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOfWith(array, value, fromIndex, comparator) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (comparator(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * The base implementation of `_.sum` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(array, iteratee) { + var result, + index = -1, + length = array.length; + + while (++index < length) { + var current = iteratee(array[index]); + if (current !== undefined) { + result = result === undefined ? current : (result + current); + } + } + return result; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array + * of key-value pairs for `object` corresponding to the property names of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the new array of key-value pairs. + */ + function baseToPairs(object, props) { + return arrayMap(props, function(key) { + return [key, object[key]]; + }); + } + + /** + * The base implementation of `_.unary` without support for storing wrapper metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new function. + */ + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); + } + + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; + + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; + + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } + + /** + * Checks if `value` is a global object. + * + * @private + * @param {*} value The value to check. + * @returns {null|Object} Returns `value` if it's a global object, else `null`. + */ + function checkGlobal(value) { + return (value && value.Object === Object) ? value : null; + } + + /** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function compareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; + } + + /** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Gets the number of `placeholder` occurrences in `array`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} placeholder The placeholder to search for. + * @returns {number} Returns the placeholder count. + */ + function countHolders(array, placeholder) { + var length = array.length, + result = 0; + + while (length--) { + if (array[length] === placeholder) { + result++; + } + } + return result; + } + + /** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + function deburrLetter(letter) { + return deburredLetters[letter]; + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * + * @private + * @param {Array} array The array to search. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched `NaN`, else `-1`. + */ + function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 0 : -1); + + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; + } + } + return -1; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; + } + + /** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ + function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; + } + + /** + * Converts `map` to an array. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the converted array. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value === placeholder || value === PLACEHOLDER) { + array[index] = PLACEHOLDER; + result[resIndex++] = index; + } + } + return result; + } + + /** + * Converts `set` to an array. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the converted array. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ + function stringSize(string) { + if (!(string && reHasComplexSymbol.test(string))) { + return string.length; + } + var result = reComplexSymbol.lastIndex = 0; + while (reComplexSymbol.test(string)) { + result++; + } + return result; + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return string.match(reComplexSymbol); + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new pristine `lodash` function using the `context` object. + * + * @static + * @memberOf _ + * @category Util + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // Use `context` to mock `Date#getTime` use in `_.now`. + * var mock = _.runInContext({ + * 'Date': function() { + * return { 'getTime': getTimeMock }; + * } + * }); + * + * // Create a suped-up `defer` in Node.js. + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + function runInContext(context) { + context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root; + + /** Built-in constructor references. */ + var Date = context.Date, + Error = context.Error, + Math = context.Math, + RegExp = context.RegExp, + TypeError = context.TypeError; + + /** Used for built-in method references. */ + var arrayProto = context.Array.prototype, + objectProto = context.Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = context.Function.prototype.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + + /** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? context.Buffer : undefined, + Reflect = context.Reflect, + Symbol = context.Symbol, + Uint8Array = context.Uint8Array, + clearTimeout = context.clearTimeout, + enumerate = Reflect ? Reflect.enumerate : undefined, + getPrototypeOf = Object.getPrototypeOf, + getOwnPropertySymbols = Object.getOwnPropertySymbols, + iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined, + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + setTimeout = context.setTimeout, + splice = arrayProto.splice; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeFloor = Math.floor, + nativeIsFinite = context.isFinite, + nativeJoin = arrayProto.join, + nativeKeys = Object.keys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeParseInt = context.parseInt, + nativeRandom = Math.random, + nativeReverse = arrayProto.reverse; + + /* Built-in method references that are verified to be native. */ + var Map = getNative(context, 'Map'), + Set = getNative(context, 'Set'), + WeakMap = getNative(context, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ + var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); + + /** Used to lookup unminified function names. */ + var realNames = {}; + + /** Used to detect maps, sets, and weakmaps. */ + var mapCtorString = Map ? funcToString.call(Map) : '', + setCtorString = Set ? funcToString.call(Set) : '', + weakMapCtorString = WeakMap ? funcToString.call(WeakMap) : ''; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable implicit method + * chaining. Methods that operate on and return arrays, collections, and + * functions can be chained together. Methods that retrieve a single value or + * may return a primitive value will automatically end the chain sequence and + * return the unwrapped value. Otherwise, the value must be unwrapped with + * `_#value`. + * + * Explicit chaining, which must be unwrapped with `_#value` in all cases, + * may be enabled using `_.chain`. + * + * The execution of chained methods is lazy, that is, it's deferred until + * `_#value` is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization to merge iteratee calls; this avoids the creation + * of intermediate arrays and can greatly reduce the number of iteratee executions. + * Sections of a chain sequence qualify for shortcut fusion if the section is + * applied to an array of at least two hundred elements and any iteratees + * accept only one argument. The heuristic for whether a section qualifies + * for shortcut fusion is subject to change. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, + * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, + * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, + * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, + * `flatten`, `flattenDeep`, `flattenDepth`, `flip`, `flow`, `flowRight`, + * `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`, `intersection`, + * `intersectionBy`, `intersectionWith`, `invert`, `invertBy`, `invokeMap`, + * `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, + * `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`, + * `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, + * `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`, + * `partition`, `pick`, `pickBy`, `plant`, `property`, `propertyOf`, `pull`, + * `pullAll`, `pullAllBy`, `pullAllWith`, `pullAt`, `push`, `range`, + * `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`, + * `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, + * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, + * `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, + * `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, + * `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `update`, `values`, + * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, + * `zipObjectDeep`, and `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, + * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `each`, `eachRight`, + * `endsWith`, `eq`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `first`, `floor`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`, `includes`, + * `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`, `isArrayBuffer`, + * `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`, `isDate`, + * `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`, `isFinite`, + * `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`, `isMatchWith`, + * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`, + * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isSet`, `isString`, + * `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, + * `maxBy`, `mean`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, + * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, + * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, + * `sortedLastIndexBy`, `startCase`, `startsWith`, `subtract`, `sum`, `sumBy`, + * `template`, `times`, `toInteger`, `toJSON`, `toLength`, `toLower`, + * `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, `trimEnd`, + * `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, `upperFirst`, + * `value`, and `words` + * + * @name _ + * @constructor + * @category Seq + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2, 3]); + * + * // Returns an unwrapped value. + * wrapped.reduce(_.add); + * // => 6 + * + * // Returns a wrapped value. + * var squares = wrapped.map(square); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } + + /** + * The function whose prototype all chaining wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + */ + function LodashWrapper(value, chainAll) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__chain__ = !!chainAll; + this.__index__ = 0; + this.__values__ = undefined; + } + + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB). Change the following template settings to use + * alternative delimiters. + * + * @static + * @memberOf _ + * @type {Object} + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type {RegExp} + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type {string} + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type {Object} + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type {Function} + */ + '_': lodash + } + }; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @constructor + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = MAX_ARRAY_LENGTH; + this.__views__ = []; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = copyArray(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = copyArray(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = copyArray(this.__views__); + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || + (arrLength == length && takeCount == length)) { + return baseWrapperValue(array, this.__actions__); + } + var result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an hash object. + * + * @private + * @constructor + * @returns {Object} Returns the new hash object. + */ + function Hash() {} + + /** + * Removes `key` and its value from the hash. + * + * @private + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(hash, key) { + return hashHas(hash, key) && delete hash[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @param {Object} hash The hash to query. + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(hash, key) { + if (nativeCreate) { + var result = hash[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(hash, key) ? hash[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @param {Object} hash The hash to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(hash, key) { + return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + */ + function hashSet(hash, key, value) { + hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function MapCache(values) { + var index = -1, + length = values ? values.length : 0; + + this.clear(); + while (++index < length) { + var entry = values[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapClear() { + this.__data__ = { + 'hash': new Hash, + 'map': Map ? new Map : [], + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapDelete(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashDelete(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map['delete'](key) : assocDelete(data.map, key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapGet(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashGet(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map.get(key) : assocGet(data.map, key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapHas(key) { + var data = this.__data__; + if (isKeyable(key)) { + return hashHas(typeof key == 'string' ? data.string : data.hash, key); + } + return Map ? data.map.has(key) : assocHas(data.map, key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache object. + */ + function mapSet(key, value) { + var data = this.__data__; + if (isKeyable(key)) { + hashSet(typeof key == 'string' ? data.string : data.hash, key, value); + } else if (Map) { + data.map.set(key, value); + } else { + assocSet(data.map, key, value); + } + return this; + } + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates a set cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var index = -1, + length = values ? values.length : 0; + + this.__data__ = new MapCache; + while (++index < length) { + this.push(values[index]); + } + } + + /** + * Checks if `value` is in `cache`. + * + * @private + * @param {Object} cache The set cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ + function cacheHas(cache, value) { + var map = cache.__data__; + if (isKeyable(value)) { + var data = map.__data__, + hash = typeof value == 'string' ? data.string : data.hash; + + return hash[value] === HASH_UNDEFINED; + } + return map.has(value); + } + + /** + * Adds `value` to the set cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ + function cachePush(value) { + var map = this.__data__; + if (isKeyable(value)) { + var data = map.__data__, + hash = typeof value == 'string' ? data.string : data.hash; + + hash[value] = HASH_UNDEFINED; + } + else { + map.set(value, HASH_UNDEFINED); + } + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function Stack(values) { + var index = -1, + length = values ? values.length : 0; + + this.clear(); + while (++index < length) { + var entry = values[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = { 'array': [], 'map': null }; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + var data = this.__data__, + array = data.array; + + return array ? assocDelete(array, key) : data.map['delete'](key); + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + var data = this.__data__, + array = data.array; + + return array ? assocGet(array, key) : data.map.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + var data = this.__data__, + array = data.array; + + return array ? assocHas(array, key) : data.map.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache object. + */ + function stackSet(key, value) { + var data = this.__data__, + array = data.array; + + if (array) { + if (array.length < (LARGE_ARRAY_SIZE - 1)) { + assocSet(array, key, value); + } else { + data.array = null; + data.map = new MapCache(array); + } + } + var map = data.map; + if (map) { + map.set(key, value); + } + return this; + } + + /*------------------------------------------------------------------------*/ + + /** + * Removes `key` and its value from the associative array. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function assocDelete(array, key) { + var index = assocIndexOf(array, key); + if (index < 0) { + return false; + } + var lastIndex = array.length - 1; + if (index == lastIndex) { + array.pop(); + } else { + splice.call(array, index, 1); + } + return true; + } + + /** + * Gets the associative array value for `key`. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function assocGet(array, key) { + var index = assocIndexOf(array, key); + return index < 0 ? undefined : array[index][1]; + } + + /** + * Checks if an associative array value for `key` exists. + * + * @private + * @param {Array} array The array to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function assocHas(array, key) { + return assocIndexOf(array, key) > -1; + } + + /** + * Gets the index at which the first occurrence of `key` is found in `array` + * of key-value pairs. + * + * @private + * @param {Array} array The array to search. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * Sets the associative array `key` to `value`. + * + * @private + * @param {Array} array The array to modify. + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + */ + function assocSet(array, key, value) { + var index = assocIndexOf(array, key); + if (index < 0) { + array.push([key, value]); + } else { + array[index][1] = value; + } + } + + /*------------------------------------------------------------------------*/ + + /** + * Used by `_.defaults` to customize its `_.assignIn` use. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to assign. + * @param {Object} object The parent object of `objValue`. + * @returns {*} Returns the value to assign. + */ + function assignInDefaults(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; + } + + /** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (typeof key == 'number' && value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Aggregates elements of `collection` on `accumulator` with keys transformed + * by `iteratee` and values set by `setter`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform keys. + * @param {Object} accumulator The initial aggregated object. + * @returns {Function} Returns `accumulator`. + */ + function baseAggregator(collection, setter, iteratee, accumulator) { + baseEach(collection, function(value, key, collection) { + setter(accumulator, value, iteratee(value), collection); + }); + return accumulator; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.at` without support for individual paths. + * + * @private + * @param {Object} object The object to iterate over. + * @param {string[]} paths The property paths of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ + function baseAt(object, paths) { + var index = -1, + isNil = object == null, + length = paths.length, + result = Array(length); + + while (++index < length) { + result[index] = isNil ? undefined : get(object, paths[index]); + } + return result; + } + + /** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; + } + + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastFunction(value) { + return typeof value == 'function' ? value : identity; + } + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast property path array. + */ + function baseCastPath(value) { + return isArray(value) ? value : stringToPath(value); + } + + /** + * The base implementation of `_.clamp` which doesn't coerce arguments to numbers. + * + * @private + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + */ + function baseClamp(number, lower, upper) { + if (number === number) { + if (upper !== undefined) { + number = number <= upper ? number : upper; + } + if (lower !== undefined) { + number = number >= lower ? number : lower; + } + } + return number; + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + result = baseAssign(result, value); + return isFull ? copySymbols(value, result) : result; + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return (isFull && !isArr) ? copySymbols(value, result) : result; + } + + /** + * The base implementation of `_.conforms` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property predicates to conform to. + * @returns {Function} Returns the new function. + */ + function baseConforms(source) { + var props = keys(source), + length = props.length; + + return function(object) { + if (object == null) { + return !length; + } + var index = length; + while (index--) { + var key = props[index], + predicate = source[key], + value = object[key]; + + if ((value === undefined && !(key in Object(object))) || !predicate(value)) { + return false; + } + } + return true; + }; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `_.delay` and `_.defer` which accepts an array + * of `func` arguments. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments to provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * The base implementation of methods like `_.difference` without support for + * excluding multiple arrays or iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + isCommon = true, + length = array.length, + result = [], + valuesLength = values.length; + + if (!length) { + return result; + } + if (iteratee) { + values = arrayMap(values, baseUnary(iteratee)); + } + if (comparator) { + includes = arrayIncludesWith; + isCommon = false; + } + else if (values.length >= LARGE_ARRAY_SIZE) { + includes = cacheHas; + isCommon = false; + values = new SetCache(values); + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (isCommon && computed === computed) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === computed) { + continue outer; + } + } + result.push(value); + } + else if (!includes(values, computed, comparator)) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `_.forEachRight` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); + + /** + * The base implementation of `_.every` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ + function baseFill(array, value, start, end) { + var length = array.length; + + start = toInteger(start); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : toInteger(end); + if (end < 0) { + end += length; + } + end = start > end ? 0 : toLength(end); + while (start < end) { + array[start++] = value; + } + return array; + } + + /** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, depth, isStrict, result) { + result || (result = []); + + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index]; + if (depth > 0 && isArrayLikeObject(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); + + /** + * The base implementation of `_.forIn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForIn(object, iteratee) { + return object == null ? object : baseFor(object, iteratee, keysIn); + } + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return object && baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from `props`. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ + function baseFunctions(object, props) { + return arrayFilter(props, function(key) { + return isFunction(object[key]); + }); + } + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[path[index++]]; + } + return (index && index == length) ? object : undefined; + } + + /** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHas(object, key) { + // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`, + // that are composed entirely of index properties, return `false` for + // `hasOwnProperty` checks of them. + return hasOwnProperty.call(object, key) || + (typeof object == 'object' && key in object && getPrototypeOf(object) === null); + } + + /** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHasIn(object, key) { + return key in Object(object); + } + + /** + * The base implementation of `_.inRange` which doesn't coerce arguments to numbers. + * + * @private + * @param {number} number The number to check. + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + */ + function baseInRange(number, start, end) { + return number >= nativeMin(start, end) && number < nativeMax(start, end); + } + + /** + * The base implementation of methods like `_.intersection`, without support + * for iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of shared values. + */ + function baseIntersection(arrays, iteratee, comparator) { + var includes = comparator ? arrayIncludesWith : arrayIncludes, + length = arrays[0].length, + othLength = arrays.length, + othIndex = othLength, + caches = Array(othLength), + maxLength = Infinity, + result = []; + + while (othIndex--) { + var array = arrays[othIndex]; + if (othIndex && iteratee) { + array = arrayMap(array, baseUnary(iteratee)); + } + maxLength = nativeMin(array.length, maxLength); + caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) + ? new SetCache(othIndex && array) + : undefined; + } + array = arrays[0]; + + var index = -1, + seen = caches[0]; + + outer: + while (++index < length && result.length < maxLength) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { + othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { + continue outer; + } + } + if (seen) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.invert` and `_.invertBy` which inverts + * `object` with values transformed by `iteratee` and set by `setter`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} setter The function to set `accumulator` values. + * @param {Function} iteratee The iteratee to transform values. + * @param {Object} accumulator The initial inverted object. + * @returns {Function} Returns `accumulator`. + */ + function baseInverter(object, setter, iteratee, accumulator) { + baseForOwn(object, function(value, key, object) { + setter(accumulator, iteratee(value), key, object); + }); + return accumulator; + } + + /** + * The base implementation of `_.invoke` without support for individual + * method arguments. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function baseInvoke(object, path, args) { + if (!isKey(path, object)) { + path = baseCastPath(path); + object = parent(object, path); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : apply(func, object, args); + } + + /** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @param {boolean} [bitmask] The bitmask of comparison flags. + * The bitmask may be composed of the following flags: + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, customizer, bitmask, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparisons. + * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = getTag(object); + objTag = objTag == argsTag ? objectTag : objTag; + } + if (!othIsArr) { + othTag = getTag(other); + othTag = othTag == argsTag ? objectTag : othTag; + } + var objIsObj = objTag == objectTag && !isHostObject(object), + othIsObj = othTag == objectTag && !isHostObject(other), + isSameTag = objTag == othTag; + + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, equalFunc, customizer, bitmask, stack) + : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack); + } + if (!(bitmask & PARTIAL_COMPARE_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + stack || (stack = new Stack); + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, equalFunc, customizer, bitmask, stack); + } + + /** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack, + result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined; + + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) + : result + )) { + return false; + } + } + } + return true; + } + + /** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ + function baseIteratee(value) { + var type = typeof value; + if (type == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (type == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); + } + + /** + * The base implementation of `_.keys` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + return nativeKeys(Object(object)); + } + + /** + * The base implementation of `_.keysIn` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + object = object == null ? object : Object(object); + + var result = []; + for (var key in object) { + result.push(key); + } + return result; + } + + // Fallback for IE < 9 with es6-shim. + if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) { + baseKeysIn = function(object) { + return iteratorToArray(enumerate(object)); + }; + } + + /** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } + + /** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; + + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && + (value !== undefined || (key in Object(object))); + }; + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; + } + + /** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new function. + */ + function baseMatchesProperty(path, srcValue) { + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG); + }; + } + + /** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + */ + function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + var props = (isArray(source) || isTypedArray(source)) + ? undefined + : keysIn(source); + + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; + } + if (isObject(srcValue)) { + stack || (stack = new Stack); + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(object[key], srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }); + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + */ + function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = object[key], + srcValue = source[key], + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + newValue = srcValue; + if (isArray(srcValue) || isTypedArray(srcValue)) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else { + isCommon = false; + newValue = baseClone(srcValue, !customizer); + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { + isCommon = false; + newValue = baseClone(srcValue, !customizer); + } + else { + newValue = objValue; + } + } + else { + isCommon = false; + } + } + stack.set(srcValue, newValue); + + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + } + stack['delete'](srcValue); + assignMergeValue(object, key, newValue); + } + + /** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseOrderBy(collection, iteratees, orders) { + var index = -1; + iteratees = arrayMap(iteratees.length ? iteratees : Array(1), getIteratee()); + + var result = baseMap(collection, function(value, key, collection) { + var criteria = arrayMap(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } + + /** + * The base implementation of `_.pick` without support for individual + * property names. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function basePick(object, props) { + object = Object(object); + return arrayReduce(props, function(result, key) { + if (key in object) { + result[key] = object[key]; + } + return result; + }, {}); + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, predicate) { + var result = {}; + baseForIn(object, function(value, key) { + if (predicate(value, key)) { + result[key] = value; + } + }); + return result; + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ + function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; + } + + /** + * The base implementation of `_.pullAllBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + */ + function basePullAll(array, values, iteratee, comparator) { + var indexOf = comparator ? baseIndexOfWith : baseIndexOf, + index = -1, + length = values.length, + seen = array; + + if (iteratee) { + seen = arrayMap(array, baseUnary(iteratee)); + } + while (++index < length) { + var fromIndex = 0, + value = values[index], + computed = iteratee ? iteratee(value) : value; + + while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { + if (seen !== array) { + splice.call(seen, fromIndex, 1); + } + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * indexes or capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0, + lastIndex = length - 1; + + while (length--) { + var index = indexes[length]; + if (lastIndex == length || index != previous) { + var previous = index; + if (isIndex(index)) { + splice.call(array, index, 1); + } + else if (!isKey(index, array)) { + var path = baseCastPath(index), + object = parent(array, path); + + if (object != null) { + delete object[last(path)]; + } + } + else { + delete array[index]; + } + } + } + return array; + } + + /** + * The base implementation of `_.random` without support for returning + * floating-point numbers. + * + * @private + * @param {number} lower The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the random number. + */ + function baseRandom(lower, upper) { + return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); + } + + /** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments to numbers. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the new array of numbers. + */ + function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; + } + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + var newValue = value; + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = objValue == null + ? (isIndex(path[index + 1]) ? [] : {}) + : objValue; + } + } + assignValue(nested, key, newValue); + } + nested = nested[key]; + } + return object; + } + + /** + * The base implementation of `setData` without support for hot loop detection. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which + * performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function baseSortedIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return baseSortedIndexBy(array, value, identity, retHighest); + } + + /** + * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` + * which invokes `iteratee` for `value` and each element of `array` to compute + * their sort ranking. The iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The iteratee invoked per element. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + */ + function baseSortedIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); + + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsNull = value === null, + valIsUndef = value === undefined; + + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + isDef = computed !== undefined, + isReflexive = computed === computed; + + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } + + /** + * The base implementation of `_.sortedUniq`. + * + * @private + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + */ + function baseSortedUniq(array) { + return baseSortedUniqBy(array); + } + + /** + * The base implementation of `_.sortedUniqBy` without support for iteratee + * shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseSortedUniqBy(array, iteratee) { + var index = 0, + length = array.length, + value = array[0], + computed = iteratee ? iteratee(value) : value, + seen = computed, + resIndex = 1, + result = [value]; + + while (++index < length) { + value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (!eq(computed, seen)) { + seen = computed; + result[resIndex++] = value; + } + } + return result; + } + + /** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.unset`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + */ + function baseUnset(object, path) { + path = isKey(path, object) ? [path + ''] : baseCastPath(path); + object = parent(object, path); + var key = last(path); + return (object != null && has(object, key)) ? delete object[key] : true; + } + + /** + * The base implementation of `_.update`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to update. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseUpdate(object, path, updater, customizer) { + return baseSet(object, path, updater(baseGet(object, path)), customizer); + } + + /** + * The base implementation of methods like `_.dropWhile` and `_.takeWhile` + * without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length) && + predicate(array[index], index, array)) {} + + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to perform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + return arrayReduce(actions, function(result, action) { + return action.func.apply(action.thisArg, arrayPush([result], action.args)); + }, result); + } + + /** + * The base implementation of methods like `_.xor`, without support for + * iteratee shorthands, that accepts an array of arrays to inspect. + * + * @private + * @param {Array} arrays The arrays to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + */ + function baseXor(arrays, iteratee, comparator) { + var index = -1, + length = arrays.length; + + while (++index < length) { + var result = result + ? arrayPush( + baseDifference(result, arrays[index], iteratee, comparator), + baseDifference(arrays[index], result, iteratee, comparator) + ) + : arrays[index]; + } + return (result && result.length) ? baseUniq(result, iteratee, comparator) : []; + } + + /** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property names. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ + function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + assignFunc(result, props[index], index < valsLength ? values[index] : undefined); + } + return result; + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @returns {Object} Returns the cloned map. + */ + function cloneMap(map) { + return arrayReduce(mapToArray(map), addMapEntry, new map.constructor); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set) { + return arrayReduce(setToArray(set), addSetEntry, new set.constructor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersLength = holders.length, + leftIndex = -1, + leftLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(leftLength + rangeLength), + isUncurried = !isCurried; + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + } + while (rangeLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @params {boolean} [isCurried] Specify composing for a curried function. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders, isCurried) { + var argsIndex = -1, + argsLength = args.length, + holdersIndex = -1, + holdersLength = holders.length, + rightIndex = -1, + rightLength = partials.length, + rangeLength = nativeMax(argsLength - holdersLength, 0), + result = Array(rangeLength + rightLength), + isUncurried = !isCurried; + + while (++argsIndex < rangeLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + if (isUncurried || argsIndex < argsLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object) { + return copyObjectWith(source, props, object); + } + + /** + * This function is like `copyObject` except that it accepts a function to + * customize copied values. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObjectWith(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : source[key]; + + assignValue(object, key, newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates a function like `_.groupBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} [initializer] The accumulator object initializer. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee) { + var func = isArray(collection) ? arrayAggregator : baseAggregator, + accumulator = initializer ? initializer() : {}; + + return func(collection, setter, getIteratee(iteratee), accumulator); + }; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return rest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = typeof customizer == 'function' + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for methods like `_.forIn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createBaseWrapper(func, bitmask, thisArg) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, arguments); + } + return wrapper; + } + + /** + * Creates a function like `_.lowerFirst`. + * + * @private + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new function. + */ + function createCaseFirst(methodName) { + return function(string) { + string = toString(string); + + var strSymbols = reHasComplexSymbol.test(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols ? strSymbols[0] : string.charAt(0), + trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1); + + return chr[methodName]() + trailing; + }; + } + + /** + * Creates a function like `_.camelCase`. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + return arrayReduce(words(deburr(string)), callback, ''); + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtorWrapper(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a function that wraps `func` to enable currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {number} arity The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createCurryWrapper(func, bitmask, arity) { + var Ctor = createCtorWrapper(func); + + function wrapper() { + var length = arguments.length, + args = Array(length), + index = length, + placeholder = getPlaceholder(wrapper); + + while (index--) { + args[index] = arguments[index]; + } + var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) + ? [] + : replaceHolders(args, placeholder); + + length -= holders.length; + if (length < arity) { + return createRecurryWrapper( + func, bitmask, createHybridWrapper, wrapper.placeholder, undefined, + args, holders, undefined, undefined, arity - length); + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return apply(fn, this, args); + } + return wrapper; + } + + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return rest(function(funcs) { + funcs = baseFlatten(funcs, 1); + + var length = funcs.length, + index = length, + prereq = LodashWrapper.prototype.thru; + + if (fromRight) { + funcs.reverse(); + } + while (index--) { + var func = funcs[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (prereq && !wrapper && getFuncName(func) == 'wrapper') { + var wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? index : length; + while (++index < length) { + func = funcs[index]; + + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; + + if (data && isLaziable(data[0]) && + data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; + + if (wrapper && args.length == 1 && + isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }); + } + + /** + * Creates a function that wraps `func` to invoke it with optional `this` + * binding of `thisArg`, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG), + isFlip = bitmask & FLIP_FLAG, + Ctor = isBindKey ? undefined : createCtorWrapper(func); + + function wrapper() { + var length = arguments.length, + index = length, + args = Array(length); + + while (index--) { + args[index] = arguments[index]; + } + if (isCurried) { + var placeholder = getPlaceholder(wrapper), + holdersCount = countHolders(args, placeholder); + } + if (partials) { + args = composeArgs(args, partials, holders, isCurried); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight, isCurried); + } + length -= holdersCount; + if (isCurried && length < arity) { + var newHolders = replaceHolders(args, placeholder); + return createRecurryWrapper( + func, bitmask, createHybridWrapper, wrapper.placeholder, thisArg, + args, newHolders, argPos, ary, arity - length + ); + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; + + length = args.length; + if (argPos) { + args = reorder(args, argPos); + } else if (isFlip && length > 1) { + args.reverse(); + } + if (isAry && ary < length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtorWrapper(fn); + } + return fn.apply(thisBinding, args); + } + return wrapper; + } + + /** + * Creates a function like `_.invertBy`. + * + * @private + * @param {Function} setter The function to set accumulator values. + * @param {Function} toIteratee The function to resolve iteratees. + * @returns {Function} Returns the new inverter function. + */ + function createInverter(setter, toIteratee) { + return function(object, iteratee) { + return baseInverter(object, setter, toIteratee(iteratee), {}); + }; + } + + /** + * Creates a function like `_.over`. + * + * @private + * @param {Function} arrayFunc The function to iterate over iteratees. + * @returns {Function} Returns the new invoker function. + */ + function createOver(arrayFunc) { + return rest(function(iteratees) { + iteratees = arrayMap(baseFlatten(iteratees, 1), getIteratee()); + return rest(function(args) { + var thisArg = this; + return arrayFunc(iteratees, function(iteratee) { + return apply(iteratee, thisArg, args); + }); + }); + }); + } + + /** + * Creates the padding for `string` based on `length`. The `chars` string + * is truncated if the number of characters exceeds `length`. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padding for `string`. + */ + function createPadding(string, length, chars) { + length = toInteger(length); + + var strLength = stringSize(string); + if (!length || strLength >= length) { + return ''; + } + var padLength = length - strLength; + chars = chars === undefined ? ' ' : (chars + ''); + + var result = repeat(chars, nativeCeil(padLength / stringSize(chars))); + return reHasComplexSymbol.test(chars) + ? stringToArray(result).slice(0, padLength).join('') + : result.slice(0, padLength); + } + + /** + * Creates a function that wraps `func` to invoke it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new wrapped function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength), + fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return apply(fn, isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ + function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = toNumber(start); + start = start === start ? start : 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = toNumber(end) || 0; + } + step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0); + return baseRange(start, end, step, fromRight); + }; + } + + /** + * Creates a function that wraps `func` to continue currying. + * + * @private + * @param {Function} func The function to wrap. + * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details. + * @param {Function} wrapFunc The function to create the `func` wrapper. + * @param {*} placeholder The placeholder value. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { + var isCurry = bitmask & CURRY_FLAG, + newArgPos = argPos ? copyArray(argPos) : undefined, + newHolders = isCurry ? holders : undefined, + newHoldersRight = isCurry ? undefined : holders, + newPartials = isCurry ? partials : undefined, + newPartialsRight = isCurry ? undefined : partials; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!(bitmask & CURRY_BOUND_FLAG)) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [ + func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, + newHoldersRight, newArgPos, ary, arity + ]; + + var result = wrapFunc.apply(undefined, newData); + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; + } + + /** + * Creates a function like `_.round`. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + number = toNumber(number); + precision = toInteger(precision); + if (precision) { + // Shift with exponential notation to avoid floating-point issues. + // See [MDN](https://mdn.io/round#Examples) for more details. + var pair = (toString(number) + 'e').split('e'), + value = func(pair[0] + 'e' + (+pair[1] + precision)); + + pair = (toString(value) + 'e').split('e'); + return +(pair[0] + 'e' + (+pair[1] - precision)); + } + return func(number); + }; + } + + /** + * Creates a set of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ + var createSet = !(Set && new Set([1, 2]).size === 2) ? noop : function(values) { + return new Set(values); + }; + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to wrap. + * @param {number} bitmask The bitmask of wrapper flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); + arity = arity === undefined ? arity : toInteger(arity); + length -= holders ? holders.length : 0; + + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; + + if (data) { + mergeData(newData, data); + } + func = newData[0]; + bitmask = newData[1]; + thisArg = newData[2]; + partials = newData[3]; + holders = newData[4]; + arity = newData[9] = newData[9] == null + ? (isBindKey ? 0 : func.length) + : nativeMax(newData[9] - length, 0); + + if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) { + bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG); + } + if (!bitmask || bitmask == BIND_FLAG) { + var result = createBaseWrapper(func, bitmask, thisArg); + } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) { + result = createCurryWrapper(func, bitmask, arity); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) { + result = createPartialWrapper(func, bitmask, thisArg, partials); + } else { + result = createHybridWrapper.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { + var index = -1, + isPartial = bitmask & PARTIAL_COMPARE_FLAG, + isUnordered = bitmask & UNORDERED_COMPARE_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked) { + return stacked == other; + } + var result = true; + stack.set(array, other); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isUnordered) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack); + })) { + result = false; + break; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { + result = false; + break; + } + } + stack['delete'](array); + return result; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) { + switch (tag) { + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) ? other != +other : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & PARTIAL_COMPARE_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + // Recursively compare objects (susceptible to call stack limits). + return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask | UNORDERED_COMPARE_FLAG, stack.set(object, other)); + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { + var isPartial = bitmask & PARTIAL_COMPARE_FLAG, + objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : baseHas(other, key))) { + return false; + } + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + var result = true; + stack.set(object, other); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + return result; + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; + + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = (func.name + ''), + array = realNames[result], + length = hasOwnProperty.call(realNames, result) ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } + + /** + * Gets the appropriate "iteratee" function. If the `_.iteratee` method is + * customized this function returns the custom method, otherwise it returns + * `baseIteratee`. If arguments are provided the chosen function is invoked + * with them and its result is returned. + * + * @private + * @param {*} [value] The value to convert to an iteratee. + * @param {number} [arity] The arity of the created iteratee. + * @returns {Function} Returns the chosen function or its result. + */ + function getIteratee() { + var result = lodash.iteratee || iteratee; + result = result === iteratee ? baseIteratee : result; + return arguments.length ? result(arguments[0], arguments[1]) : result; + } + + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = toPairs(object), + length = result.length; + + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = object[key]; + return isNative(value) ? value : undefined; + } + + /** + * Gets the argument placeholder value for `func`. + * + * @private + * @param {Function} func The function to inspect. + * @returns {*} Returns the placeholder value. + */ + function getPlaceholder(func) { + var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; + return object.placeholder; + } + + /** + * Creates an array of the own symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = getOwnPropertySymbols || function() { + return []; + }; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function getTag(value) { + return objectToString.call(value); + } + + // Fallback for IE 11 providing `toStringTag` values for maps, sets, and weakmaps. + if ((Map && getTag(new Map) != mapTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : null, + ctorString = typeof Ctor == 'function' ? funcToString.call(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case mapCtorString: return mapTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ + function hasPath(object, path, hasFunc) { + if (object == null) { + return false; + } + var result = hasFunc(object, path); + if (!result && !isKey(path)) { + path = baseCastPath(path); + object = parent(object, path); + if (object != null) { + path = last(path); + result = hasFunc(object, path); + } + } + var length = object ? object.length : undefined; + return result || ( + !!length && isLength(length) && isIndex(path, length) && + (isArray(object) || isString(object) || isArguments(object)) + ); + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototypeOf(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object); + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Creates an array of index keys for `object` values of arrays, + * `arguments` objects, and strings, otherwise `null` is returned. + * + * @private + * @param {Object} object The object to query. + * @returns {Array|null} Returns index keys, else `null`. + */ + function indexKeys(object) { + var length = object ? object.length : undefined; + if (isLength(length) && + (isArray(object) || isString(object) || isArguments(object))) { + return baseTimes(length, String); + } + return null; + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + return eq(object[index], value); + } + return false; + } + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (typeof value == 'number') { + return true; + } + return !isArray(value) && + (reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object))); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return type == 'number' || type == 'boolean' || + (type == 'string' && value != '__proto__') || value == null; + } + + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func), + other = lodash[funcName]; + + if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { + return false; + } + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers used to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` + * modify function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * combined case where curried functions have `_.ary` and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG); + + var isCombo = + ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) || + ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) || + ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG)); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : copyArray(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : copyArray(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : copyArray(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : copyArray(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = copyArray(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use. + * + * @private + * @param {*} objValue The destination value. + * @param {*} srcValue The source value. + * @param {string} key The key of the property to merge. + * @param {Object} object The parent object of `objValue`. + * @param {Object} source The parent object of `srcValue`. + * @param {Object} [stack] Tracks traversed source values and their merged counterparts. + * @returns {*} Returns the value to assign. + */ + function mergeDefaults(objValue, srcValue, key, object, source, stack) { + if (isObject(objValue) && isObject(srcValue)) { + baseMerge(objValue, srcValue, undefined, mergeDefaults, stack.set(srcValue, objValue)); + } + return objValue; + } + + /** + * Gets the parent value at `path` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path to get the parent value of. + * @returns {*} Returns the parent value. + */ + function parent(object, path) { + return path.length == 1 ? object : get(object, baseSlice(path, 0, -1)); + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = copyArray(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity function + * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = (function() { + var count = 0, + lastCalled = 0; + + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; + } + return baseSetData(key, value); + }; + }()); + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + function stringToPath(string) { + var result = []; + toString(string).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + } + + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + if (wrapper instanceof LazyWrapper) { + return wrapper.clone(); + } + var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); + result.__actions__ = copyArray(wrapper.__actions__); + result.__index__ = wrapper.__index__; + result.__values__ = wrapper.__values__; + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `array` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=0] The length of each chunk. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size) { + size = nativeMax(toInteger(size), 0); + + var length = array ? array.length : 0; + if (!length || size < 1) { + return []; + } + var index = 0, + resIndex = 0, + result = Array(nativeCeil(length / size)); + + while (index < length) { + result[resIndex++] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[resIndex++] = value; + } + } + return result; + } + + /** + * Creates a new array concatenating `array` with any additional arrays + * and/or values. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to concatenate. + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var other = _.concat(array, 2, [3], [[4]]); + * + * console.log(other); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var concat = rest(function(array, values) { + if (!isArray(array)) { + array = array == null ? [] : [Object(array)]; + } + values = baseFlatten(values, 1); + return arrayConcat(array, values); + }); + + /** + * Creates an array of unique `array` values not included in the other + * given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. The order of result values is determined by the + * order they occur in the first array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([3, 2, 1], [4, 2]); + * // => [3, 1] + */ + var difference = rest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `iteratee` which + * is invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. Result values are chosen from the first array. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor); + * // => [3.1, 1.3] + * + * // The `_.property` iteratee shorthand. + * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var differenceBy = rest(function(array, values) { + var iteratee = last(values); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true), getIteratee(iteratee)) + : []; + }); + + /** + * This method is like `_.difference` except that it accepts `comparator` + * which is invoked to compare elements of `array` to `values`. Result values + * are chosen from the first array. The comparator is invoked with two arguments: + * (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The values to exclude. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * + * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); + * // => [{ 'x': 2, 'y': 1 }] + */ + var differenceWith = rest(function(array, values) { + var comparator = last(values); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return isArrayLikeObject(array) + ? baseDifference(array, baseFlatten(values, 1, true), undefined, comparator) + : []; + }); + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.dropRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney'] + * + * // The `_.matches` iteratee shorthand. + * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropRightWhile(users, ['active', false]); + * // => objects for ['barney'] + * + * // The `_.property` iteratee shorthand. + * _.dropRightWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ + function dropRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), true, true) + : []; + } + + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.dropWhile(users, function(o) { return !o.active; }); + * // => objects for ['pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.dropWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.dropWhile(users, ['active', false]); + * // => objects for ['pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.dropWhile(users, 'active'); + * // => objects for ['barney', 'fred', 'pebbles'] + */ + function dropWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), true) + : []; + } + + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8, 10], '*', 1, 3); + * // => [4, '*', '*', 10] + */ + function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ + function findIndex(array, predicate) { + return (array && array.length) + ? baseFindIndex(array, getIteratee(predicate, 3)) + : -1; + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); + * // => 2 + * + * // The `_.matches` iteratee shorthand. + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastIndex(users, ['active', false]); + * // => 2 + * + * // The `_.property` iteratee shorthand. + * _.findLastIndex(users, 'active'); + * // => 0 + */ + function findLastIndex(array, predicate) { + return (array && array.length) + ? baseFindIndex(array, getIteratee(predicate, 3), true) + : -1; + } + + /** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ + function flatten(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, 1) : []; + } + + /** + * Recursively flattens `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, INFINITY) : []; + } + + /** + * Recursively flatten `array` up to `depth` times. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * var array = [1, [2, [3, [4]], 5]]; + * + * _.flattenDepth(array, 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth(array, 2); + * // => [1, 2, 3, [4], 5] + */ + function flattenDepth(array, depth) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(array, depth); + } + + /** + * The inverse of `_.toPairs`; this method returns an object composed + * from key-value `pairs`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} pairs The key-value pairs. + * @returns {Object} Returns the new object. + * @example + * + * _.fromPairs([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + */ + function fromPairs(pairs) { + var index = -1, + length = pairs ? pairs.length : 0, + result = {}; + + while (++index < length) { + var pair = pairs[index]; + result[pair[0]] = pair[1]; + } + return result; + } + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias first + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.head([1, 2, 3]); + * // => 1 + * + * _.head([]); + * // => undefined + */ + function head(array) { + return array ? array[0] : undefined; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it's used as the offset + * from the end of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // Search from the `fromIndex`. + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + */ + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + fromIndex = toInteger(fromIndex); + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + return dropRight(array, 1); + } + + /** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. The order of result values is determined by the + * order they occur in the first array. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersection([2, 1], [4, 2], [1, 2]); + * // => [2] + */ + var intersection = rest(function(arrays) { + var mapped = arrayMap(arrays, baseCastArrayLikeObject); + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped) + : []; + }); + + /** + * This method is like `_.intersection` except that it accepts `iteratee` + * which is invoked for each element of each `arrays` to generate the criterion + * by which they're compared. Result values are chosen from the first array. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [2.1] + * + * // The `_.property` iteratee shorthand. + * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }] + */ + var intersectionBy = rest(function(arrays) { + var iteratee = last(arrays), + mapped = arrayMap(arrays, baseCastArrayLikeObject); + + if (iteratee === last(mapped)) { + iteratee = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, getIteratee(iteratee)) + : []; + }); + + /** + * This method is like `_.intersection` except that it accepts `comparator` + * which is invoked to compare elements of `arrays`. Result values are chosen + * from the first array. The comparator is invoked with two arguments: + * (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of intersecting values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.intersectionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }] + */ + var intersectionWith = rest(function(arrays) { + var comparator = last(arrays), + mapped = arrayMap(arrays, baseCastArrayLikeObject); + + if (comparator === last(mapped)) { + comparator = undefined; + } else { + mapped.pop(); + } + return (mapped.length && mapped[0] === arrays[0]) + ? baseIntersection(mapped, undefined, comparator) + : []; + }); + + /** + * Converts all elements in `array` into a string separated by `separator`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to convert. + * @param {string} [separator=','] The element separator. + * @returns {string} Returns the joined string. + * @example + * + * _.join(['a', 'b', 'c'], '~'); + * // => 'a~b~c' + */ + function join(array, separator) { + return array ? nativeJoin.call(array, separator) : ''; + } + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } + + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // Search from the `fromIndex`. + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = (index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1)) + 1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all given values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` + * to remove elements from an array by predicate. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + var pull = rest(pullAll); + + /** + * This method is like `_.pull` except that it accepts an array of values to remove. + * + * **Note:** Unlike `_.difference`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pullAll(array, [2, 3]); + * console.log(array); + * // => [1, 1] + */ + function pullAll(array, values) { + return (array && array.length && values && values.length) + ? basePullAll(array, values) + : array; + } + + /** + * This method is like `_.pullAll` except that it accepts `iteratee` which is + * invoked for each element of `array` and `values` to generate the criterion + * by which they're compared. The iteratee is invoked with one argument: (value). + * + * **Note:** Unlike `_.differenceBy`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; + * + * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); + * console.log(array); + * // => [{ 'x': 2 }] + */ + function pullAllBy(array, values, iteratee) { + return (array && array.length && values && values.length) + ? basePullAll(array, values, getIteratee(iteratee)) + : array; + } + + /** + * This method is like `_.pullAll` except that it accepts `comparator` which + * is invoked to compare elements of `array` to `values`. The comparator is + * invoked with two arguments: (arrVal, othVal). + * + * **Note:** Unlike `_.differenceWith`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Array} values The values to remove. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns `array`. + * @example + * + * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; + * + * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); + * console.log(array); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] + */ + function pullAllWith(array, values, comparator) { + return (array && array.length && values && values.length) + ? basePullAll(array, values, undefined, comparator) + : array; + } + + /** + * Removes elements from `array` corresponding to `indexes` and returns an + * array of removed elements. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified individually or in arrays. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, 1, 3); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] + */ + var pullAt = rest(function(array, indexes) { + indexes = arrayMap(baseFlatten(indexes, 1), String); + + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(compareAscending)); + return result; + }); + + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is invoked + * with three arguments: (value, index, array). + * + * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` + * to pull elements from an array by value. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; + + predicate = getIteratee(predicate, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; + } + + /** + * Reverses `array` so that the first element becomes the last, the second + * element becomes the second to last, and so on. + * + * **Note:** This method mutates `array` and is based on + * [`Array#reverse`](https://mdn.io/Array/reverse). + * + * @static + * @memberOf _ + * @category Array + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.reverse(array); + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function reverse(array) { + return array ? nativeReverse.call(array) : array; + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice) + * to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + else { + start = start == null ? 0 : toInteger(start); + end = end === undefined ? length : toInteger(end); + } + return baseSlice(array, start, end); + } + + /** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 5], 4); + * // => 0 + */ + function sortedIndex(array, value) { + return baseSortedIndex(array, value); + } + + /** + * This method is like `_.sortedIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + * @example + * + * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 }; + * + * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict)); + * // => 1 + * + * // The `_.property` iteratee shorthand. + * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); + * // => 0 + */ + function sortedIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee)); + } + + /** + * This method is like `_.indexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedIndexOf([1, 1, 2, 2], 2); + * // => 2 + */ + function sortedIndexOf(array, value) { + var length = array ? array.length : 0; + if (length) { + var index = baseSortedIndex(array, value); + if (index < length && eq(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + * @example + * + * _.sortedLastIndex([4, 5], 4); + * // => 1 + */ + function sortedLastIndex(array, value) { + return baseSortedIndex(array, value, true); + } + + /** + * This method is like `_.sortedLastIndex` except that it accepts `iteratee` + * which is invoked for `value` and each element of `array` to compute their + * sort ranking. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {number} Returns the index at which `value` should be inserted into `array`. + * @example + * + * // The `_.property` iteratee shorthand. + * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); + * // => 1 + */ + function sortedLastIndexBy(array, value, iteratee) { + return baseSortedIndexBy(array, value, getIteratee(iteratee), true); + } + + /** + * This method is like `_.lastIndexOf` except that it performs a binary + * search on a sorted `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.sortedLastIndexOf([1, 1, 2, 2], 2); + * // => 3 + */ + function sortedLastIndexOf(array, value) { + var length = array ? array.length : 0; + if (length) { + var index = baseSortedIndex(array, value, true) - 1; + if (eq(array[index], value)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.uniq` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniq([1, 1, 2]); + * // => [1, 2] + */ + function sortedUniq(array) { + return (array && array.length) + ? baseSortedUniq(array) + : []; + } + + /** + * This method is like `_.uniqBy` except that it's designed and optimized + * for sorted arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); + * // => [1.1, 2.3] + */ + function sortedUniqBy(array, iteratee) { + return (array && array.length) + ? baseSortedUniqBy(array, getIteratee(iteratee)) + : []; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.tail([1, 2, 3]); + * // => [2, 3] + */ + function tail(array) { + return drop(array, 1); + } + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + if (!(array && array.length)) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + n = (guard || n === undefined) ? 1 : toInteger(n); + n = length - n; + return baseSlice(array, n < 0 ? 0 : n, length); + } + + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is invoked with three + * arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.takeRightWhile(users, function(o) { return !o.active; }); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.matches` iteratee shorthand. + * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); + * // => objects for ['pebbles'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeRightWhile(users, ['active', false]); + * // => objects for ['fred', 'pebbles'] + * + * // The `_.property` iteratee shorthand. + * _.takeRightWhile(users, 'active'); + * // => [] + */ + function takeRightWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3), false, true) + : []; + } + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is invoked with + * three arguments: (value, index, array). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the slice of `array`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.takeWhile(users, function(o) { return !o.active; }); + * // => objects for ['barney', 'fred'] + * + * // The `_.matches` iteratee shorthand. + * _.takeWhile(users, { 'user': 'barney', 'active': false }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.takeWhile(users, ['active', false]); + * // => objects for ['barney', 'fred'] + * + * // The `_.property` iteratee shorthand. + * _.takeWhile(users, 'active'); + * // => [] + */ + function takeWhile(array, predicate) { + return (array && array.length) + ? baseWhile(array, getIteratee(predicate, 3)) + : []; + } + + /** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2, 1], [4, 2], [1, 2]); + * // => [2, 1, 4] + */ + var union = rest(function(arrays) { + return baseUniq(baseFlatten(arrays, 1, true)); + }); + + /** + * This method is like `_.union` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by which + * uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [2.1, 1.2, 4.3] + * + * // The `_.property` iteratee shorthand. + * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + var unionBy = rest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return baseUniq(baseFlatten(arrays, 1, true), getIteratee(iteratee)); + }); + + /** + * This method is like `_.union` except that it accepts `comparator` which + * is invoked to compare elements of `arrays`. The comparator is invoked + * with two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of combined values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.unionWith(objects, others, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var unionWith = rest(function(arrays) { + var comparator = last(arrays); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return baseUniq(baseFlatten(arrays, 1, true), undefined, comparator); + }); + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + */ + function uniq(array) { + return (array && array.length) + ? baseUniq(array) + : []; + } + + /** + * This method is like `_.uniq` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * uniqueness is computed. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniqBy([2.1, 1.2, 2.3], Math.floor); + * // => [2.1, 1.2] + * + * // The `_.property` iteratee shorthand. + * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniqBy(array, iteratee) { + return (array && array.length) + ? baseUniq(array, getIteratee(iteratee)) + : []; + } + + /** + * This method is like `_.uniq` except that it accepts `comparator` which + * is invoked to compare elements of `array`. The comparator is invoked with + * two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.uniqWith(objects, _.isEqual); + * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] + */ + function uniqWith(array, comparator) { + return (array && array.length) + ? baseUniq(array, undefined, comparator) + : []; + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ + function unzip(array) { + if (!(array && array.length)) { + return []; + } + var length = 0; + array = arrayFilter(array, function(group) { + if (isArrayLikeObject(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + return baseTimes(length, function(index) { + return arrayMap(array, baseProperty(index)); + }); + } + + /** + * This method is like `_.unzip` except that it accepts `iteratee` to specify + * how regrouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee=_.identity] The function to combine regrouped values. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ + function unzipWith(array, iteratee) { + if (!(array && array.length)) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + return arrayMap(result, function(group) { + return apply(iteratee, undefined, group); + }); + } + + /** + * Creates an array excluding all given values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 3], 1, 2); + * // => [3] + */ + var without = rest(function(array, values) { + return isArrayLikeObject(array) + ? baseDifference(array, values) + : []; + }); + + /** + * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the given arrays. The order of result values is determined by the order + * they occur in the arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([2, 1], [4, 2]); + * // => [1, 4] + */ + var xor = rest(function(arrays) { + return baseXor(arrayFilter(arrays, isArrayLikeObject)); + }); + + /** + * This method is like `_.xor` except that it accepts `iteratee` which is + * invoked for each element of each `arrays` to generate the criterion by which + * by which they're compared. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor); + * // => [1.2, 4.3] + * + * // The `_.property` iteratee shorthand. + * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 2 }] + */ + var xorBy = rest(function(arrays) { + var iteratee = last(arrays); + if (isArrayLikeObject(iteratee)) { + iteratee = undefined; + } + return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee)); + }); + + /** + * This method is like `_.xor` except that it accepts `comparator` which is + * invoked to compare elements of `arrays`. The comparator is invoked with + * two arguments: (arrVal, othVal). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new array of values. + * @example + * + * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; + * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; + * + * _.xorWith(objects, others, _.isEqual); + * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] + */ + var xorWith = rest(function(arrays) { + var comparator = last(arrays); + if (isArrayLikeObject(comparator)) { + comparator = undefined; + } + return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); + }); + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second elements + * of the given arrays, and so on. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + var zip = rest(unzip); + + /** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property names and one of corresponding values. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} [props=[]] The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ + function zipObject(props, values) { + return baseZipObject(props || [], values || [], assignValue); + } + + /** + * This method is like `_.zipObject` except that it supports property paths. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} [props=[]] The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); + * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } + */ + function zipObjectDeep(props, values) { + return baseZipObject(props || [], values || [], baseSet); + } + + /** + * This method is like `_.zip` except that it accepts `iteratee` to specify + * how grouped values should be combined. The iteratee is invoked with the + * elements of each group: (...group). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee=_.identity] The function to combine grouped values. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { + * return a + b + c; + * }); + * // => [111, 222] + */ + var zipWith = rest(function(arrays) { + var length = arrays.length, + iteratee = length > 1 ? arrays[length - 1] : undefined; + + iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; + return unzipWith(arrays, iteratee); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps `value` with explicit method chaining enabled. + * The result of such method chaining must be unwrapped with `_#value`. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _ + * .chain(users) + * .sortBy('age') + * .map(function(o) { + * return o.user + ' is ' + o.age; + * }) + * .head() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor + * is invoked with one argument; (value). The purpose of this method is to + * "tap into" a method chain in order to modify intermediate results. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * // Mutate input array. + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * The purpose of this method is to "pass thru" values replacing intermediate + * results in a method chain. + * + * @static + * @memberOf _ + * @category Seq + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor) { + return interceptor(value); + } + + /** + * This method is the wrapper version of `_.at`. + * + * @name at + * @memberOf _ + * @category Seq + * @param {...(string|string[])} [paths] The property paths of elements to pick, + * specified individually or in arrays. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _(object).at(['a[0].b.c', 'a[1]']).value(); + * // => [3, 4] + * + * _(['a', 'b', 'c']).at(0, 2).value(); + * // => ['a', 'c'] + */ + var wrapperAt = rest(function(paths) { + paths = baseFlatten(paths, 1); + var length = paths.length, + start = length ? paths[0] : 0, + value = this.__wrapped__, + interceptor = function(object) { return baseAt(object, paths); }; + + if (length > 1 || this.__actions__.length || + !(value instanceof LazyWrapper) || !isIndex(start)) { + return this.thru(interceptor); + } + value = value.slice(start, +start + (length ? 1 : 0)); + value.__actions__.push({ + 'func': thru, + 'args': [interceptor], + 'thisArg': undefined + }); + return new LodashWrapper(value, this.__chain__).thru(function(array) { + if (length && !array.length) { + array.push(undefined); + } + return array; + }); + }); + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // A sequence without explicit chaining. + * _(users).head(); + * // => { 'user': 'barney', 'age': 36 } + * + * // A sequence with explicit chaining. + * _(users) + * .chain() + * .head() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } + + /** + * This method is the wrapper version of `_.flatMap`. + * + * @name flatMap + * @memberOf _ + * @category Seq + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function duplicate(n) { + * return [n, n]; + * } + * + * _([1, 2]).flatMap(duplicate).value(); + * // => [1, 1, 2, 2] + */ + function wrapperFlatMap(iteratee) { + return this.map(iteratee).flatten(); + } + + /** + * Gets the next value on a wrapped object following the + * [iterator protocol](https://mdn.io/iteration_protocols#iterator). + * + * @name next + * @memberOf _ + * @category Seq + * @returns {Object} Returns the next iterator value. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped.next(); + * // => { 'done': false, 'value': 1 } + * + * wrapped.next(); + * // => { 'done': false, 'value': 2 } + * + * wrapped.next(); + * // => { 'done': true, 'value': undefined } + */ + function wrapperNext() { + if (this.__values__ === undefined) { + this.__values__ = toArray(this.value()); + } + var done = this.__index__ >= this.__values__.length, + value = done ? undefined : this.__values__[this.__index__++]; + + return { 'done': done, 'value': value }; + } + + /** + * Enables the wrapper to be iterable. + * + * @name Symbol.iterator + * @memberOf _ + * @category Seq + * @returns {Object} Returns the wrapper object. + * @example + * + * var wrapped = _([1, 2]); + * + * wrapped[Symbol.iterator]() === wrapped; + * // => true + * + * Array.from(wrapped); + * // => [1, 2] + */ + function wrapperToIterator() { + return this; + } + + /** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Seq + * @param {*} value The value to plant. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * function square(n) { + * return n * n; + * } + * + * var wrapped = _([1, 2]).map(square); + * var other = wrapped.plant([3, 4]); + * + * other.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + clone.__index__ = 0; + clone.__values__ = undefined; + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } + + /** + * This method is the wrapper version of `_.reverse`. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Seq + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ + 'func': thru, + 'args': [reverse], + 'thisArg': undefined + }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(reverse); + } + + /** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias toJSON, valueOf + * @category Seq + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * Iteration is stopped once `predicate` returns falsey. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.every(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, guard) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + */ + function filter(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three arguments: + * (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ + function find(collection, predicate) { + predicate = getIteratee(predicate, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, baseEach); + } + + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ + function findLast(collection, predicate) { + predicate = getIteratee(predicate, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, true); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, baseEachRight); + } + + /** + * Creates an array of flattened values by running each element in `collection` + * through `iteratee` and concating its result to the other mapped values. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new flattened array. + * @example + * + * function duplicate(n) { + * return [n, n]; + * } + * + * _.flatMap([1, 2], duplicate); + * // => [1, 1, 2, 2] + */ + function flatMap(collection, iteratee) { + return baseFlatten(map(collection, iteratee), 1); + } + + /** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn` + * for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @example + * + * _([1, 2]).forEach(function(value) { + * console.log(value); + * }); + * // => logs `1` then `2` + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' then 'b' (iteration order is not guaranteed) + */ + function forEach(collection, iteratee) { + return (typeof iteratee == 'function' && isArray(collection)) + ? arrayEach(collection, iteratee) + : baseEach(collection, baseCastFunction(iteratee)); + } + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @example + * + * _.forEachRight([1, 2], function(value) { + * console.log(value); + * }); + * // => logs `2` then `1` + */ + function forEachRight(collection, iteratee) { + return (typeof iteratee == 'function' && isArray(collection)) + ? arrayEachRight(collection, iteratee) + : baseEachRight(collection, baseCastFunction(iteratee)); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of elements responsible for generating the key. + * The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([6.1, 4.2, 6.3], Math.floor); + * // => { '4': [4.2], '6': [6.1, 6.3] } + * + * // The `_.property` iteratee shorthand. + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } + }); + + /** + * Checks if `value` is in `collection`. If `collection` is a string it's checked + * for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * is used for equality comparisons. If `fromIndex` is negative, it's used as + * the offset from the end of `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`. + * @returns {boolean} Returns `true` if `value` is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ + function includes(collection, value, fromIndex, guard) { + collection = isArrayLike(collection) ? collection : values(collection); + fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; + + var length = collection.length; + if (fromIndex < 0) { + fromIndex = nativeMax(length + fromIndex, 0); + } + return isString(collection) + ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) + : (!!length && baseIndexOf(collection, value, fromIndex) > -1); + } + + /** + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it's + * invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke each method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invokeMap([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + var invokeMap = rest(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args); + }); + return result; + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var array = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.keyBy(array, function(o) { + * return String.fromCharCode(o.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.keyBy(array, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + */ + var keyBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`, + * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`, + * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`, + * and `words` + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee) { + var func = isArray(collection) ? arrayMap : baseMap; + return func(collection, getIteratee(iteratee, 3)); + } + + /** + * This method is like `_.sortBy` except that it allows specifying the sort + * orders of the iteratees to sort by. If `orders` is unspecified, all values + * are sorted in ascending order. Otherwise, specify an order of "desc" for + * descending or "asc" for ascending sort order of corresponding values. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} [iteratees=[_.identity]] The iteratees to sort by. + * @param {string[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // Sort by `user` in ascending order and by `age` in descending order. + * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + function orderBy(collection, iteratees, orders, guard) { + if (collection == null) { + return []; + } + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; + } + orders = guard ? undefined : orders; + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseOrderBy(collection, iteratees, orders); + } + + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, the second of which + * contains elements `predicate` returns falsey for. The predicate is + * invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * _.partition(users, function(o) { return o.active; }); + * // => objects for [['fred'], ['barney', 'pebbles']] + * + * // The `_.matches` iteratee shorthand. + * _.partition(users, { 'age': 1, 'active': false }); + * // => objects for [['pebbles'], ['barney', 'fred']] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.partition(users, ['active', false]); + * // => objects for [['barney', 'pebbles'], ['fred']] + * + * // The `_.property` iteratee shorthand. + * _.partition(users, 'active'); + * // => objects for [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ + function reduce(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduce : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); + } + + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, iteratee, accumulator) { + var func = isArray(collection) ? arrayReduceRight : baseReduce, + initAccum = arguments.length < 3; + + return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); + } + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * _.reject(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.reject(users, { 'age': 40, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.reject(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.reject(users, 'active'); + * // => objects for ['barney'] + */ + function reject(collection, predicate) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getIteratee(predicate, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); + } + + /** + * Gets a random element from `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + */ + function sample(collection) { + var array = isArrayLike(collection) ? collection : values(collection), + length = array.length; + + return length > 0 ? array[baseRandom(0, length - 1)] : undefined; + } + + /** + * Gets `n` random elements at unique keys from `collection` up to the + * size of `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to sample. + * @param {number} [n=0] The number of elements to sample. + * @returns {Array} Returns the random elements. + * @example + * + * _.sampleSize([1, 2, 3], 2); + * // => [3, 1] + * + * _.sampleSize([1, 2, 3], 4); + * // => [2, 3, 1] + */ + function sampleSize(collection, n) { + var index = -1, + result = toArray(collection), + length = result.length, + lastIndex = length - 1; + + n = baseClamp(toInteger(n), 0, length); + while (++index < n) { + var rand = baseRandom(index, lastIndex), + value = result[rand]; + + result[rand] = result[index]; + result[index] = value; + } + result.length = n; + return result; + } + + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + return sampleSize(collection, MAX_ARRAY_LENGTH); + } + + /** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + if (collection == null) { + return 0; + } + if (isArrayLike(collection)) { + var result = collection.length; + return (result && isString(collection)) ? stringSize(collection) : result; + } + return keys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * Iteration is stopped once `predicate` returns truthy. The predicate is + * invoked with three arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // The `_.matches` iteratee shorthand. + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // The `_.matchesProperty` iteratee shorthand. + * _.some(users, ['active', false]); + * // => true + * + * // The `_.property` iteratee shorthand. + * _.some(users, 'active'); + * // => true + */ + function some(collection, predicate, guard) { + var func = isArray(collection) ? arraySome : baseSome; + if (guard && isIterateeCall(collection, predicate, guard)) { + predicate = undefined; + } + return func(collection, getIteratee(predicate, 3)); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]] + * The iteratees to sort by, specified individually or in arrays. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, function(o) { return o.user; }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.sortBy(users, 'user', function(o) { + * return Math.floor(o.age / 10); + * }); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + */ + var sortBy = rest(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { + iteratees.length = 1; + } + return baseOrderBy(collection, baseFlatten(iteratees, 1), []); + }); + + /*------------------------------------------------------------------------*/ + + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @type {Function} + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked + */ + var now = Date.now; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it's called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ + function after(n, func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that accepts up to `n` arguments, ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ + function ary(func, n, guard) { + n = guard ? undefined : n; + n = (func && n == null) ? func.length : n; + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it's called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery(element).on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ + function before(n, func) { + var result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + n = toInteger(n); + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = undefined; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method doesn't set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // Bound with placeholders. + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = rest(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getPlaceholder(bind)); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); + }); + + /** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to invoke the method on. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // Bound with placeholders. + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + var bindKey = rest(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getPlaceholder(bindKey)); + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); + }); + + /** + * Creates a function that accepts arguments of `func` and either invokes + * `func` returning its result, if at least `arity` number of arguments have + * been provided, or returns a function that accepts the remaining `func` + * arguments, and so on. The arity of `func` may be specified if `func.length` + * is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + function curry(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curry.placeholder; + return result; + } + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method doesn't set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // Curried with placeholders. + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ + function curryRight(func, arity, guard) { + arity = guard ? undefined : arity; + var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryRight.placeholder; + return result; + } + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide an options object to indicate whether `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent calls + * to the debounced function return the result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it's invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + leading = false, + maxWait = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait); + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + lastCalled = 0; + args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined; + } + + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + } + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function flush() { + if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) { + result = func.apply(thisArg, args); + } + cancel(); + return result; + } + + function maxDelayed() { + complete(trailing, timeoutId); + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!lastCalled && !maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled); + + var isCalled = (remaining <= 0 || remaining > maxWait) && + (leading || maxTimeoutId); + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // => logs 'deferred' after one or more milliseconds + */ + var defer = rest(function(func, args) { + return baseDelay(func, 1, args); + }); + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it's invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke `func` with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second + */ + var delay = rest(function(func, wait, args) { + return baseDelay(func, toNumber(wait) || 0, args); + }); + + /** + * Creates a function that invokes `func` with arguments reversed. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to flip arguments for. + * @returns {Function} Returns the new function. + * @example + * + * var flipped = _.flip(function() { + * return _.toArray(arguments); + * }); + * + * flipped('a', 'b', 'c', 'd'); + * // => ['d', 'c', 'b', 'a'] + */ + function flip(func) { + return createWrapper(func, FLIP_FLAG); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) + * method interface of `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; + } + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first invocation. The `func` is + * invoked with the `this` binding and arguments of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ + function once(func) { + return before(2, func); + } + + /** + * Creates a function that invokes `func` with arguments transformed by + * corresponding `transforms`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified individually or in arrays. + * @returns {Function} Returns the new function. + * @example + * + * function doubled(n) { + * return n * 2; + * } + * + * function square(n) { + * return n * n; + * } + * + * var func = _.overArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); + * + * func(9, 3); + * // => [81, 6] + * + * func(10, 5); + * // => [100, 10] + */ + var overArgs = rest(function(func, transforms) { + transforms = arrayMap(baseFlatten(transforms, 1), getIteratee()); + + var funcsLength = transforms.length; + return rest(function(args) { + var index = -1, + length = nativeMin(args.length, funcsLength); + + while (++index < length) { + args[index] = transforms[index].call(this, args[index]); + } + return apply(func, this, args); + }); + }); + + /** + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. This method is like `_.bind` except + * it does **not** alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // Partially applied with placeholders. + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ + var partial = rest(function(func, partials) { + var holders = replaceHolders(partials, getPlaceholder(partial)); + return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders); + }); + + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method doesn't set the "length" property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // Partially applied with placeholders. + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ + var partialRight = rest(function(func, partials) { + var holders = replaceHolders(partials, getPlaceholder(partialRight)); + return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders); + }); + + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified indexes where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, + * specified individually or in arrays. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + */ + var rearg = rest(function(func, indexes) { + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1)); + }); + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.rest(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function rest(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, array); + case 1: return func.call(this, args[0], array); + case 2: return func.call(this, args[0], args[1], array); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = array; + return apply(func, this, otherArgs); + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). + * + * **Note:** This method is based on the [spread operator](https://mdn.io/spread_operator). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to spread arguments over. + * @param {number} [start=0] The start position of the spread. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 + */ + function spread(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = start === undefined ? 0 : nativeMax(toInteger(start), 0); + return rest(function(args) { + var array = args[start], + otherArgs = args.slice(0, start); + + if (array) { + arrayPush(otherArgs, array); + } + return apply(func, this, otherArgs); + }); + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide an options object to indicate whether + * `func` should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the throttled function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify invoking on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); + } + + /** + * Creates a function that accepts up to one argument, ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.unary(parseInt)); + * // => [6, 8, 10] + */ + function unary(func) { + return ary(func, 1); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {*} value The value to wrap. + * @param {Function} [wrapper=identity] The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

    ' + func(text) + '

    '; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

    fred, barney, & pebbles

    ' + */ + function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return partial(wrapper, value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone(value) { + return baseClone(value, false, true); + } + + /** + * This method is like `_.clone` except that it accepts `customizer` which + * is invoked to produce the cloned value. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is invoked with + * up to four arguments; (value [, index|key, object, stack]). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the cloned value. + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * } + * + * var el = _.cloneWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 0 + */ + function cloneWith(value, customizer) { + return baseClone(value, false, true, customizer); + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, true, true); + } + + /** + * This method is like `_.cloneWith` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to recursively clone. + * @param {Function} [customizer] The function to customize cloning. + * @returns {*} Returns the deep cloned value. + * @example + * + * function customizer(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * } + * + * var el = _.cloneDeepWith(document.body, customizer); + * + * console.log(el === document.body); + * // => false + * console.log(el.nodeName); + * // => 'BODY' + * console.log(el.childNodes.length); + * // => 20 + */ + function cloneDeepWith(value, customizer) { + return baseClone(value, true, true, customizer); + } + + /** + * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is greater than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. + * @example + * + * _.gt(3, 1); + * // => true + * + * _.gt(3, 3); + * // => false + * + * _.gt(1, 3); + * // => false + */ + function gt(value, other) { + return value > other; + } + + /** + * Checks if `value` is greater than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. + * @example + * + * _.gte(3, 1); + * // => true + * + * _.gte(3, 3); + * // => true + * + * _.gte(1, 3); + * // => false + */ + function gte(value, other) { + return value >= other; + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @type {Function} + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is classified as an `ArrayBuffer` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArrayBuffer(new ArrayBuffer(2)); + * // => true + * + * _.isArrayBuffer(new Array(2)); + * // => false + */ + function isArrayBuffer(value) { + return isObjectLike(value) && objectToString.call(value) == arrayBufferTag; + } + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + (isObjectLike(value) && objectToString.call(value) == boolTag); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = !Buffer ? constant(false) : function(value) { + return value instanceof Buffer; + }; + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + function isDate(value) { + return isObjectLike(value) && objectToString.call(value) == dateTag; + } + + /** + * Checks if `value` is likely a DOM element. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); + } + + /** + * Checks if `value` is an empty collection or object. A value is considered + * empty if it's an `arguments` object, array, string, or jQuery-like collection + * with a length of `0` or has no own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (isArrayLike(value) && + (isArray(value) || isString(value) || + isFunction(value.splice) || isArguments(value))) { + return !value.length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are **not** supported. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ + function isEqual(value, other) { + return baseIsEqual(value, other); + } + + /** + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, othValue) { + * if (isGreeting(objValue) && isGreeting(othValue)) { + * return true; + * } + * } + * + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqualWith(array, other, customizer); + * // => true + */ + function isEqualWith(value, other, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + if (!isObjectLike(value)) { + return false; + } + return (objectToString.call(value) == errorTag) || + (typeof value.message == 'string' && typeof value.name == 'string'); + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(3); + * // => true + * + * _.isFinite(Number.MAX_VALUE); + * // => true + * + * _.isFinite(3.14); + * // => true + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8 which returns 'object' for typed array and weak map constructors, + // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is an integer. + * + * **Note:** This method is based on [`Number.isInteger`](https://mdn.io/Number/isInteger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an integer, else `false`. + * @example + * + * _.isInteger(3); + * // => true + * + * _.isInteger(Number.MIN_VALUE); + * // => false + * + * _.isInteger(Infinity); + * // => false + * + * _.isInteger('3'); + * // => false + */ + function isInteger(value) { + return typeof value == 'number' && value == toInteger(value); + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ + function isMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; + } + + /** + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. This method is + * equivalent to a `_.matches` function when `source` is partially applied. + * + * **Note:** This method supports comparing the same values as `_.isEqual`. + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + */ + function isMatch(object, source) { + return object === source || baseIsMatch(object, source, getMatchData(source)); + } + + /** + * This method is like `_.isMatch` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with five + * arguments: (objValue, srcValue, index|key, object, source). + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * function isGreeting(value) { + * return /^h(?:i|ello)$/.test(value); + * } + * + * function customizer(objValue, srcValue) { + * if (isGreeting(objValue) && isGreeting(srcValue)) { + * return true; + * } + * } + * + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatchWith(object, source, customizer); + * // => true + */ + function isMatchWith(object, source, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseIsMatch(object, source, getMatchData(source), customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(funcToString.call(value)); + } + return isObjectLike(value) && + (isHostObject(value) ? reIsNative : reIsHostCtor).test(value); + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is `null` or `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is nullish, else `false`. + * @example + * + * _.isNil(null); + * // => true + * + * _.isNil(void 0); + * // => true + * + * _.isNil(NaN); + * // => false + */ + function isNil(value) { + return value == null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(3); + * // => true + * + * _.isNumber(Number.MIN_VALUE); + * // => true + * + * _.isNumber(Infinity); + * // => true + * + * _.isNumber('3'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || + (isObjectLike(value) && objectToString.call(value) == numberTag); + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || + objectToString.call(value) != objectTag || isHostObject(value)) { + return false; + } + var proto = getPrototypeOf(value); + if (proto === null) { + return true; + } + var Ctor = proto.constructor; + return (typeof Ctor == 'function' && + Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); + } + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + function isRegExp(value) { + return isObject(value) && objectToString.call(value) == regexpTag; + } + + /** + * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 + * double precision number which isn't the result of a rounded unsafe integer. + * + * **Note:** This method is based on [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`. + * @example + * + * _.isSafeInteger(3); + * // => true + * + * _.isSafeInteger(Number.MIN_VALUE); + * // => false + * + * _.isSafeInteger(Infinity); + * // => false + * + * _.isSafeInteger('3'); + * // => false + */ + function isSafeInteger(value) { + return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ + function isSet(value) { + return isObjectLike(value) && getTag(value) == setTag; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + function isTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Checks if `value` is classified as a `WeakMap` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isWeakMap(new WeakMap); + * // => true + * + * _.isWeakMap(new Map); + * // => false + */ + function isWeakMap(value) { + return isObjectLike(value) && getTag(value) == weakMapTag; + } + + /** + * Checks if `value` is classified as a `WeakSet` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isWeakSet(new WeakSet); + * // => true + * + * _.isWeakSet(new Set); + * // => false + */ + function isWeakSet(value) { + return isObjectLike(value) && objectToString.call(value) == weakSetTag; + } + + /** + * Checks if `value` is less than `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. + * @example + * + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false + */ + function lt(value, other) { + return value < other; + } + + /** + * Checks if `value` is less than or equal to `other`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. + * @example + * + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true + * + * _.lte(3, 1); + * // => false + */ + function lte(value, other) { + return value <= other; + } + + /** + * Converts `value` to an array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!value) { + return []; + } + if (isArrayLike(value)) { + return isString(value) ? stringToArray(value) : copyArray(value); + } + if (iteratorSymbol && value[iteratorSymbol]) { + return iteratorToArray(value[iteratorSymbol]()); + } + var tag = getTag(value), + func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); + + return func(value); + } + + /** + * Converts `value` to an integer. + * + * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3'); + * // => 3 + */ + function toInteger(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + var remainder = value % 1; + return value === value ? (remainder ? value - remainder : value) : 0; + } + + /** + * Converts `value` to an integer suitable for use as the length of an + * array-like object. + * + * **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toLength(3); + * // => 3 + * + * _.toLength(Number.MIN_VALUE); + * // => 0 + * + * _.toLength(Infinity); + * // => 4294967295 + * + * _.toLength('3'); + * // => 3 + */ + function toLength(value) { + return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3); + * // => 3 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3'); + * // => 3 + */ + function toNumber(value) { + if (isObject(value)) { + var other = isFunction(value.valueOf) ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable + * properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return copyObject(value, keysIn(value)); + } + + /** + * Converts `value` to a safe integer. A safe integer can be compared and + * represented correctly. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toSafeInteger(3); + * // => 3 + * + * _.toSafeInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toSafeInteger(Infinity); + * // => 9007199254740991 + * + * _.toSafeInteger('3'); + * // => 3 + */ + function toSafeInteger(value) { + return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER); + } + + /** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to process. + * @returns {string} Returns the string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (value == null) { + return ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source objects to the destination + * object. Source objects are applied from left to right. Subsequent sources + * overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.c = 3; + * } + * + * function Bar() { + * this.e = 5; + * } + * + * Foo.prototype.d = 4; + * Bar.prototype.f = 6; + * + * _.assign({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3, 'e': 5 } + */ + var assign = createAssigner(function(object, source) { + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } + }); + + /** + * This method is like `_.assign` except that it iterates over own and + * inherited source properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * function Bar() { + * this.d = 4; + * } + * + * Foo.prototype.c = 3; + * Bar.prototype.e = 5; + * + * _.assignIn({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 } + */ + var assignIn = createAssigner(function(object, source) { + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keysIn(source), object); + return; + } + for (var key in source) { + assignValue(object, key, source[key]); + } + }); + + /** + * This method is like `_.assignIn` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @alias extendWith + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignInWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keysIn(source), object, customizer); + }); + + /** + * This method is like `_.assign` except that it accepts `customizer` which + * is invoked to produce the assigned values. If `customizer` returns `undefined` + * assignment is handled by the method instead. The `customizer` is invoked + * with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ + var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObjectWith(source, keys(source), object, customizer); + }); + + /** + * Creates an array of values corresponding to `paths` of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {...(string|string[])} [paths] The property paths of elements to pick, + * specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; + * + * _.at(object, ['a[0].b.c', 'a[1]']); + * // => [3, 4] + * + * _.at(['a', 'b', 'c'], 0, 2); + * // => ['a', 'c'] + */ + var at = rest(function(object, paths) { + return baseAt(object, baseFlatten(paths, 1)); + }); + + /** + * Creates an object that inherits from the `prototype` object. If a `properties` + * object is given its own enumerable properties are assigned to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? baseAssign(result, properties) : result; + } + + /** + * Assigns own and inherited enumerable properties of source objects to the + * destination object for all destination properties that resolve to `undefined`. + * Source objects are applied from left to right. Once a property is set, + * additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var defaults = rest(function(args) { + args.push(undefined, assignInDefaults); + return apply(assignInWith, undefined, args); + }); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } + * + */ + var defaultsDeep = rest(function(args) { + args.push(undefined, mergeDefaults); + return apply(mergeWith, undefined, args); + }); + + /** + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(o) { return o.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // The `_.matches` iteratee shorthand. + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate) { + return baseFind(object, getIteratee(predicate, 3), baseForOwn, true); + } + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(o) { return o.age < 40; }); + * // => returns 'pebbles' assuming `_.findKey` returns 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findLastKey(users, ['active', false]); + * // => 'fred' + * + * // The `_.property` iteratee shorthand. + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + function findLastKey(object, predicate) { + return baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true); + } + + /** + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The iteratee is invoked with three arguments: + * (value, key, object). Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed) + */ + function forIn(object, iteratee) { + return object == null + ? object + : baseFor(object, baseCastFunction(iteratee), keysIn); + } + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c' + */ + function forInRight(object, iteratee) { + return object == null + ? object + : baseForRight(object, baseCastFunction(iteratee), keysIn); + } + + /** + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The iteratee is invoked with three arguments: + * (value, key, object). Iteratee functions may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' then 'b' (iteration order is not guaranteed) + */ + function forOwn(object, iteratee) { + return object && baseForOwn(object, baseCastFunction(iteratee)); + } + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b' + */ + function forOwnRight(object, iteratee) { + return object && baseForOwnRight(object, baseCastFunction(iteratee)); + } + + /** + * Creates an array of function property names from own enumerable properties + * of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functions(new Foo); + * // => ['a', 'b'] + */ + function functions(object) { + return object == null ? [] : baseFunctions(object, keys(object)); + } + + /** + * Creates an array of function property names from own and inherited + * enumerable properties of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * function Foo() { + * this.a = _.constant('a'); + * this.b = _.constant('b'); + * } + * + * Foo.prototype.c = _.constant('c'); + * + * _.functionsIn(new Foo); + * // => ['a', 'b', 'c'] + */ + function functionsIn(object) { + return object == null ? [] : baseFunctions(object, keysIn(object)); + } + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + /** + * Checks if `path` is a direct property of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': { 'c': 3 } } }; + * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ + function has(object, path) { + return hasPath(object, path, baseHas); + } + + /** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b.c'); + * // => true + * + * _.hasIn(object, ['a', 'b', 'c']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ + function hasIn(object, path) { + return hasPath(object, path, baseHasIn); + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite property + * assignments of previous values. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + */ + var invert = createInverter(function(result, value, key) { + result[value] = key; + }, constant(identity)); + + /** + * This method is like `_.invert` except that the inverted object is generated + * from the results of running each element of `object` through `iteratee`. + * The corresponding inverted value of each inverted key is an array of keys + * responsible for generating the inverted value. The iteratee is invoked + * with one argument: (value). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element. + * @returns {Object} Returns the new inverted object. + * @example + * + * var object = { 'a': 1, 'b': 2, 'c': 1 }; + * + * _.invertBy(object); + * // => { '1': ['a', 'c'], '2': ['b'] } + * + * _.invertBy(object, function(value) { + * return 'group' + value; + * }); + * // => { 'group1': ['a', 'c'], 'group2': ['b'] } + */ + var invertBy = createInverter(function(result, value, key) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + }, getIteratee); + + /** + * Invokes the method at `path` of `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + * @example + * + * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; + * + * _.invoke(object, 'a[0].b.c.slice', 1, 3); + * // => [2, 3] + */ + var invoke = rest(baseInvoke); + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + var isProto = isPrototype(object); + if (!(isProto || isArrayLike(object))) { + return baseKeys(object); + } + var indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + for (var key in object) { + if (baseHas(object, key) && + !(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(isProto && key == 'constructor')) { + result.push(key); + } + } + return result; + } + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + var index = -1, + isProto = isPrototype(object), + props = baseKeysIn(object), + propsLength = props.length, + indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + while (++index < propsLength) { + var key = props[index]; + if (!(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * property of `object` through `iteratee`. The iteratee is invoked with + * three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } + */ + function mapKeys(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + result[iteratee(value, key, object)] = value; + }); + return result; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through `iteratee`. The + * iteratee is invoked with three arguments: (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee) { + var result = {}; + iteratee = getIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + result[key] = iteratee(value, key, object); + }); + return result; + } + + /** + * This method is like `_.assign` except that it recursively merges own and + * inherited enumerable properties of source objects into the destination + * object. Source properties that resolve to `undefined` are skipped if a + * destination value exists. Array and plain object properties are merged + * recursively.Other objects and value types are overridden by assignment. + * Source objects are applied from left to right. Subsequent sources + * overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + */ + var merge = createAssigner(function(object, source, srcIndex) { + baseMerge(object, source, srcIndex); + }); + + /** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined` merging is handled by the + * method instead. The `customizer` is invoked with seven arguments: + * (objValue, srcValue, key, object, source, stack). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.mergeWith(object, other, customizer); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { + baseMerge(object, source, srcIndex, customizer); + }); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [props] The property names to omit, specified + * individually or in arrays. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omit(object, ['a', 'c']); + * // => { 'b': '2' } + */ + var omit = rest(function(object, props) { + if (object == null) { + return {}; + } + props = arrayMap(baseFlatten(props, 1), String); + return basePick(object, baseDifference(keysIn(object), props)); + }); + + /** + * The opposite of `_.pickBy`; this method creates an object composed of + * the own and inherited enumerable properties of `object` that `predicate` + * doesn't return truthy for. The predicate is invoked with two arguments: + * (value, key). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.omitBy(object, _.isNumber); + * // => { 'b': '2' } + */ + function omitBy(object, predicate) { + predicate = getIteratee(predicate); + return basePickBy(object, function(value, key) { + return !predicate(value, key); + }); + } + + /** + * Creates an object composed of the picked `object` properties. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [props] The property names to pick, specified + * individually or in arrays. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ + var pick = rest(function(object, props) { + return object == null ? {} : basePick(object, baseFlatten(props, 1)); + }); + + /** + * Creates an object composed of the `object` properties `predicate` returns + * truthy for. The predicate is invoked with two arguments: (value, key). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|Object|string} [predicate=_.identity] The function invoked per property. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pickBy(object, _.isNumber); + * // => { 'a': 1, 'c': 3 } + */ + function pickBy(object, predicate) { + return object == null ? {} : basePickBy(object, getIteratee(predicate)); + } + + /** + * This method is like `_.get` except that if the resolved value is a function + * it's invoked with the `this` binding of its parent object and its result + * is returned. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ + function result(object, path, defaultValue) { + if (!isKey(path, object)) { + path = baseCastPath(path); + var result = get(object, path); + object = parent(object, path); + } else { + result = object == null ? undefined : object[path]; + } + if (result === undefined) { + result = defaultValue; + } + return isFunction(result) ? result.call(object) : result; + } + + /** + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, 'x[0].y.z', 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + return object == null ? object : baseSet(object, path, value); + } + + /** + * This method is like `_.set` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.setWith(object, '[0][1]', 'a', Object); + * // => { '0': { '1': 'a' } } + */ + function setWith(object, path, value, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseSet(object, path, value, customizer); + } + + /** + * Creates an array of own enumerable key-value pairs for `object` which + * can be consumed by `_.fromPairs`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairs(new Foo); + * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) + */ + function toPairs(object) { + return baseToPairs(object, keys(object)); + } + + /** + * Creates an array of own and inherited enumerable key-value pairs for + * `object` which can be consumed by `_.fromPairs`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.toPairsIn(new Foo); + * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed) + */ + function toPairsIn(object) { + return baseToPairs(object, keysIn(object)); + } + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own enumerable + * properties through `iteratee`, with each invocation potentially mutating + * the `accumulator` object. The iteratee is invoked with four arguments: + * (accumulator, value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Array|Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @returns {*} Returns the accumulated value. + * @example + * + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }, []); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } + */ + function transform(object, iteratee, accumulator) { + var isArr = isArray(object) || isTypedArray(object); + iteratee = getIteratee(iteratee, 4); + + if (accumulator == null) { + if (isArr || isObject(object)) { + var Ctor = object.constructor; + if (isArr) { + accumulator = isArray(object) ? new Ctor : []; + } else { + accumulator = isFunction(Ctor) ? baseCreate(getPrototypeOf(object)) : {}; + } + } else { + accumulator = {}; + } + } + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Removes the property at `path` of `object`. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 7 } }] }; + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + * + * _.unset(object, 'a[0].b.c'); + * // => true + * + * console.log(object); + * // => { 'a': [{ 'b': {} }] }; + */ + function unset(object, path) { + return object == null ? true : baseUnset(object, path); + } + + /** + * This method is like `_.set` except that accepts `updater` to produce the + * value to set. Use `_.updateWith` to customize `path` creation. The `updater` + * is invoked with one argument: (value). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.update(object, 'a[0].b.c', function(n) { return n * n; }); + * console.log(object.a[0].b.c); + * // => 9 + * + * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); + * console.log(object.x[0].y.z); + * // => 0 + */ + function update(object, path, updater) { + return object == null ? object : baseUpdate(object, path, baseCastFunction(updater)); + } + + /** + * This method is like `_.update` except that it accepts `customizer` which is + * invoked to produce the objects of `path`. If `customizer` returns `undefined` + * path creation is handled by the method instead. The `customizer` is invoked + * with three arguments: (nsValue, key, nsObject). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {Function} updater The function to produce the updated value. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * var object = {}; + * + * _.updateWith(object, '[0][1]', _.constant('a'), Object); + * // => { '0': { '1': 'a' } } + */ + function updateWith(object, path, updater, customizer) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return object == null ? object : baseUpdate(object, path, baseCastFunction(updater), customizer); + } + + /** + * Creates an array of the own enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object ? baseValues(object, keys(object)) : []; + } + + /** + * Creates an array of the own and inherited enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return object == null ? [] : baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Clamps `number` within the inclusive `lower` and `upper` bounds. + * + * @static + * @memberOf _ + * @category Number + * @param {number} number The number to clamp. + * @param {number} [lower] The lower bound. + * @param {number} upper The upper bound. + * @returns {number} Returns the clamped number. + * @example + * + * _.clamp(-10, -5, 5); + * // => -5 + * + * _.clamp(10, -5, 5); + * // => 5 + */ + function clamp(number, lower, upper) { + if (upper === undefined) { + upper = lower; + lower = undefined; + } + if (upper !== undefined) { + upper = toNumber(upper); + upper = upper === upper ? upper : 0; + } + if (lower !== undefined) { + lower = toNumber(lower); + lower = lower === lower ? lower : 0; + } + return baseClamp(toNumber(number), lower, upper); + } + + /** + * Checks if `n` is between `start` and up to but not including, `end`. If + * `end` is not specified it's set to `start` with `start` then set to `0`. + * If `start` is greater than `end` the params are swapped to support + * negative ranges. + * + * @static + * @memberOf _ + * @category Number + * @param {number} number The number to check. + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @returns {boolean} Returns `true` if `number` is in the range, else `false`. + * @example + * + * _.inRange(3, 2, 4); + * // => true + * + * _.inRange(4, 8); + * // => true + * + * _.inRange(4, 2); + * // => false + * + * _.inRange(2, 2); + * // => false + * + * _.inRange(1.2, 2); + * // => true + * + * _.inRange(5.2, 4); + * // => false + * + * _.inRange(-3, -2, -6); + * // => true + */ + function inRange(number, start, end) { + start = toNumber(start) || 0; + if (end === undefined) { + end = start; + start = 0; + } else { + end = toNumber(end) || 0; + } + number = toNumber(number); + return baseInRange(number, start, end); + } + + /** + * Produces a random number between the inclusive `lower` and `upper` bounds. + * If only one argument is provided a number between `0` and the given number + * is returned. If `floating` is `true`, or either `lower` or `upper` are floats, + * a floating-point number is returned instead of an integer. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @memberOf _ + * @category Number + * @param {number} [lower=0] The lower bound. + * @param {number} [upper=1] The upper bound. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(lower, upper, floating) { + if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { + upper = floating = undefined; + } + if (floating === undefined) { + if (typeof upper == 'boolean') { + floating = upper; + upper = undefined; + } + else if (typeof lower == 'boolean') { + floating = lower; + lower = undefined; + } + } + if (lower === undefined && upper === undefined) { + lower = 0; + upper = 1; + } + else { + lower = toNumber(lower) || 0; + if (upper === undefined) { + upper = lower; + lower = 0; + } else { + upper = toNumber(upper) || 0; + } + } + if (lower > upper) { + var temp = lower; + lower = upper; + upper = temp; + } + if (floating || lower % 1 || upper % 1) { + var rand = nativeRandom(); + return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); + } + return baseRandom(lower, upper); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar'); + * // => 'fooBar' + * + * _.camelCase('__foo_bar__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); + }); + + /** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ + function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); + } + + /** + * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = toString(string); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search from. + * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = toString(string); + target = typeof target == 'string' ? target : (target + ''); + + var length = string.length; + position = position === undefined + ? length + : baseClamp(toInteger(position), 0, length); + + position -= target.length; + return position >= 0 && string.indexOf(target, position) == position; + } + + /** + * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in IE < 9, they can break out of + * attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", + * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ + function escapeRegExp(string) { + string = toString(string); + return (string && reHasRegExpChar.test(string)) + ? string.replace(reRegExpChar, '\\$&') + : string; + } + + /** + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Converts `string`, as space separated words, to lower case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the lower cased string. + * @example + * + * _.lowerCase('--Foo-Bar'); + * // => 'foo bar' + * + * _.lowerCase('fooBar'); + * // => 'foo bar' + * + * _.lowerCase('__FOO_BAR__'); + * // => 'foo bar' + */ + var lowerCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + word.toLowerCase(); + }); + + /** + * Converts the first character of `string` to lower case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.lowerFirst('Fred'); + * // => 'fred' + * + * _.lowerFirst('FRED'); + * // => 'fRED' + */ + var lowerFirst = createCaseFirst('toLowerCase'); + + /** + * Converts the first character of `string` to upper case. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.upperFirst('fred'); + * // => 'Fred' + * + * _.upperFirst('FRED'); + * // => 'FRED' + */ + var upperFirst = createCaseFirst('toUpperCase'); + + /** + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = toString(string); + length = toInteger(length); + + var strLength = stringSize(string); + if (!length || strLength >= length) { + return string; + } + var mid = (length - strLength) / 2, + leftLength = nativeFloor(mid), + rightLength = nativeCeil(mid); + + return createPadding('', leftLength, chars) + string + createPadding('', rightLength, chars); + } + + /** + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padEnd('abc', 6); + * // => 'abc ' + * + * _.padEnd('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padEnd('abc', 3); + * // => 'abc' + */ + function padEnd(string, length, chars) { + string = toString(string); + return string + createPadding(string, length, chars); + } + + /** + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padStart('abc', 6); + * // => ' abc' + * + * _.padStart('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padStart('abc', 3); + * // => 'abc' + */ + function padStart(string, length, chars) { + string = toString(string); + return createPadding(string, length, chars) + string; + } + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, + * in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2) + * of `parseInt`. + * + * @static + * @memberOf _ + * @category String + * @param {string} string The string to convert. + * @param {number} [radix=10] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + // Chrome fails to trim leading whitespace characters. + // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. + if (guard || radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + string = toString(string).replace(reTrim, ''); + return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=0] The number of times to repeat the string. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n) { + string = toString(string); + n = toInteger(n); + + var result = ''; + if (!string || n < 1 || n > MAX_SAFE_INTEGER) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + string += string; + } while (n); + + return result; + } + + /** + * Replaces matches for `pattern` in `string` with `replacement`. + * + * **Note:** This method is based on [`String#replace`](https://mdn.io/String/replace). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to modify. + * @param {RegExp|string} pattern The pattern to replace. + * @param {Function|string} replacement The match replacement. + * @returns {string} Returns the modified string. + * @example + * + * _.replace('Hi Fred', 'Fred', 'Barney'); + * // => 'Hi Barney' + */ + function replace() { + var args = arguments, + string = toString(args[0]); + + return args.length < 3 ? string : string.replace(args[1], args[2]); + } + + /** + * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--foo-bar'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Splits `string` by `separator`. + * + * **Note:** This method is based on [`String#split`](https://mdn.io/String/split). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to split. + * @param {RegExp|string} separator The separator pattern to split by. + * @param {number} [limit] The length to truncate results to. + * @returns {Array} Returns the new array of string segments. + * @example + * + * _.split('a-b-c', '-', 2); + * // => ['a', 'b'] + */ + function split(string, separator, limit) { + return toString(string).split(separator, limit); + } + + /** + * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + capitalize(word); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = toString(string); + position = baseClamp(toInteger(position), 0, string.length); + return string.lastIndexOf(target, position) == position; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is given it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as free variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. + * @param {string} [options.variable] The data object variable name. + * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. + * @returns {Function} Returns the compiled template function. + * @example + * + * // Use the "interpolate" delimiter to create a compiled template. + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // Use the HTML "escape" delimiter to escape data property values. + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': ' +
    diff --git a/www/node_modules/sax/README.md b/www/node_modules/sax/README.md new file mode 100644 index 0000000..c965242 --- /dev/null +++ b/www/node_modules/sax/README.md @@ -0,0 +1,216 @@ +# sax js + +A sax-style parser for XML and HTML. + +Designed with [node](http://nodejs.org/) in mind, but should work fine in +the browser or other CommonJS implementations. + +## What This Is + +* A very simple tool to parse through an XML string. +* A stepping stone to a streaming HTML parser. +* A handy way to deal with RSS and other mostly-ok-but-kinda-broken XML + docs. + +## What This Is (probably) Not + +* An HTML Parser - That's a fine goal, but this isn't it. It's just + XML. +* A DOM Builder - You can use it to build an object model out of XML, + but it doesn't do that out of the box. +* XSLT - No DOM = no querying. +* 100% Compliant with (some other SAX implementation) - Most SAX + implementations are in Java and do a lot more than this does. +* An XML Validator - It does a little validation when in strict mode, but + not much. +* A Schema-Aware XSD Thing - Schemas are an exercise in fetishistic + masochism. +* A DTD-aware Thing - Fetching DTDs is a much bigger job. + +## Regarding `Hello, world!').close(); + + // stream usage + // takes the same options as the parser + var saxStream = require("sax").createStream(strict, options) + saxStream.on("error", function (e) { + // unhandled errors will throw, since this is a proper node + // event emitter. + console.error("error!", e) + // clear the error + this._parser.error = null + this._parser.resume() + }) + saxStream.on("opentag", function (node) { + // same object as above + }) + // pipe is supported, and it's readable/writable + // same chunks coming in also go out. + fs.createReadStream("file.xml") + .pipe(saxStream) + .pipe(fs.createWriteStream("file-copy.xml")) + + + +## Arguments + +Pass the following arguments to the parser function. All are optional. + +`strict` - Boolean. Whether or not to be a jerk. Default: `false`. + +`opt` - Object bag of settings regarding string formatting. All default to `false`. + +Settings supported: + +* `trim` - Boolean. Whether or not to trim text and comment nodes. +* `normalize` - Boolean. If true, then turn any whitespace into a single + space. +* `lowercase` - Boolean. If true, then lowercase tag names and attribute names + in loose mode, rather than uppercasing them. +* `xmlns` - Boolean. If true, then namespaces are supported. +* `position` - Boolean. If false, then don't track line/col/position. + +## Methods + +`write` - Write bytes onto the stream. You don't have to do this all at +once. You can keep writing as much as you want. + +`close` - Close the stream. Once closed, no more data may be written until +it is done processing the buffer, which is signaled by the `end` event. + +`resume` - To gracefully handle errors, assign a listener to the `error` +event. Then, when the error is taken care of, you can call `resume` to +continue parsing. Otherwise, the parser will not continue while in an error +state. + +## Members + +At all times, the parser object will have the following members: + +`line`, `column`, `position` - Indications of the position in the XML +document where the parser currently is looking. + +`startTagPosition` - Indicates the position where the current tag starts. + +`closed` - Boolean indicating whether or not the parser can be written to. +If it's `true`, then wait for the `ready` event to write again. + +`strict` - Boolean indicating whether or not the parser is a jerk. + +`opt` - Any options passed into the constructor. + +`tag` - The current tag being dealt with. + +And a bunch of other stuff that you probably shouldn't touch. + +## Events + +All events emit with a single argument. To listen to an event, assign a +function to `on`. Functions get executed in the this-context of +the parser object. The list of supported events are also in the exported +`EVENTS` array. + +When using the stream interface, assign handlers using the EventEmitter +`on` function in the normal fashion. + +`error` - Indication that something bad happened. The error will be hanging +out on `parser.error`, and must be deleted before parsing can continue. By +listening to this event, you can keep an eye on that kind of stuff. Note: +this happens *much* more in strict mode. Argument: instance of `Error`. + +`text` - Text node. Argument: string of text. + +`doctype` - The ``. Argument: +object with `name` and `body` members. Attributes are not parsed, as +processing instructions have implementation dependent semantics. + +`sgmldeclaration` - Random SGML declarations. Stuff like `` +would trigger this kind of event. This is a weird thing to support, so it +might go away at some point. SAX isn't intended to be used to parse SGML, +after all. + +`opentag` - An opening tag. Argument: object with `name` and `attributes`. +In non-strict mode, tag names are uppercased, unless the `lowercase` +option is set. If the `xmlns` option is set, then it will contain +namespace binding information on the `ns` member, and will have a +`local`, `prefix`, and `uri` member. + +`closetag` - A closing tag. In loose mode, tags are auto-closed if their +parent closes. In strict mode, well-formedness is enforced. Note that +self-closing tags will have `closeTag` emitted immediately after `openTag`. +Argument: tag name. + +`attribute` - An attribute node. Argument: object with `name` and `value`. +In non-strict mode, attribute names are uppercased, unless the `lowercase` +option is set. If the `xmlns` option is set, it will also contains namespace +information. + +`comment` - A comment node. Argument: the string of the comment. + +`opencdata` - The opening tag of a ``) of a `` tags trigger a `"script"` +event, and their contents are not checked for special xml characters. +If you pass `noscript: true`, then this behavior is suppressed. + +## Reporting Problems + +It's best to write a failing test if you find an issue. I will always +accept pull requests with failing tests if they demonstrate intended +behavior, but it is very hard to figure out what issue you're describing +without a test. Writing a test is also the best way for you yourself +to figure out if you really understand the issue you think you have with +sax-js. diff --git a/www/node_modules/sax/examples/big-not-pretty.xml b/www/node_modules/sax/examples/big-not-pretty.xml new file mode 100644 index 0000000..fb5265d --- /dev/null +++ b/www/node_modules/sax/examples/big-not-pretty.xml @@ -0,0 +1,8002 @@ + + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + + something blerm a bit down here + diff --git a/www/node_modules/sax/examples/example.js b/www/node_modules/sax/examples/example.js new file mode 100644 index 0000000..7b0246e --- /dev/null +++ b/www/node_modules/sax/examples/example.js @@ -0,0 +1,29 @@ + +var fs = require("fs"), + util = require("util"), + path = require("path"), + xml = fs.readFileSync(path.join(__dirname, "test.xml"), "utf8"), + sax = require("../lib/sax"), + strict = sax.parser(true), + loose = sax.parser(false, {trim:true}), + inspector = function (ev) { return function (data) { + console.error("%s %s %j", this.line+":"+this.column, ev, data); + }}; + +sax.EVENTS.forEach(function (ev) { + loose["on"+ev] = inspector(ev); +}); +loose.onend = function () { + console.error("end"); + console.error(loose); +}; + +// do this in random bits at a time to verify that it works. +(function () { + if (xml) { + var c = Math.ceil(Math.random() * 1000) + loose.write(xml.substr(0,c)); + xml = xml.substr(c); + process.nextTick(arguments.callee); + } else loose.close(); +})(); diff --git a/www/node_modules/sax/examples/get-products.js b/www/node_modules/sax/examples/get-products.js new file mode 100644 index 0000000..9e8d74a --- /dev/null +++ b/www/node_modules/sax/examples/get-products.js @@ -0,0 +1,58 @@ +// pull out /GeneralSearchResponse/categories/category/items/product tags +// the rest we don't care about. + +var sax = require("../lib/sax.js") +var fs = require("fs") +var path = require("path") +var xmlFile = path.resolve(__dirname, "shopping.xml") +var util = require("util") +var http = require("http") + +fs.readFile(xmlFile, function (er, d) { + http.createServer(function (req, res) { + if (er) throw er + var xmlstr = d.toString("utf8") + + var parser = sax.parser(true) + var products = [] + var product = null + var currentTag = null + + parser.onclosetag = function (tagName) { + if (tagName === "product") { + products.push(product) + currentTag = product = null + return + } + if (currentTag && currentTag.parent) { + var p = currentTag.parent + delete currentTag.parent + currentTag = p + } + } + + parser.onopentag = function (tag) { + if (tag.name !== "product" && !product) return + if (tag.name === "product") { + product = tag + } + tag.parent = currentTag + tag.children = [] + tag.parent && tag.parent.children.push(tag) + currentTag = tag + } + + parser.ontext = function (text) { + if (currentTag) currentTag.children.push(text) + } + + parser.onend = function () { + var out = util.inspect(products, false, 3, true) + res.writeHead(200, {"content-type":"application/json"}) + res.end("{\"ok\":true}") + // res.end(JSON.stringify(products)) + } + + parser.write(xmlstr).end() + }).listen(1337) +}) diff --git a/www/node_modules/sax/examples/hello-world.js b/www/node_modules/sax/examples/hello-world.js new file mode 100644 index 0000000..cbfa518 --- /dev/null +++ b/www/node_modules/sax/examples/hello-world.js @@ -0,0 +1,4 @@ +require("http").createServer(function (req, res) { + res.writeHead(200, {"content-type":"application/json"}) + res.end(JSON.stringify({ok: true})) +}).listen(1337) diff --git a/www/node_modules/sax/examples/not-pretty.xml b/www/node_modules/sax/examples/not-pretty.xml new file mode 100644 index 0000000..9592852 --- /dev/null +++ b/www/node_modules/sax/examples/not-pretty.xml @@ -0,0 +1,8 @@ + + something blerm a bit down here diff --git a/www/node_modules/sax/examples/pretty-print.js b/www/node_modules/sax/examples/pretty-print.js new file mode 100644 index 0000000..cd6aca9 --- /dev/null +++ b/www/node_modules/sax/examples/pretty-print.js @@ -0,0 +1,74 @@ +var sax = require("../lib/sax") + , printer = sax.createStream(false, {lowercasetags:true, trim:true}) + , fs = require("fs") + +function entity (str) { + return str.replace('"', '"') +} + +printer.tabstop = 2 +printer.level = 0 +printer.indent = function () { + print("\n") + for (var i = this.level; i > 0; i --) { + for (var j = this.tabstop; j > 0; j --) { + print(" ") + } + } +} +printer.on("opentag", function (tag) { + this.indent() + this.level ++ + print("<"+tag.name) + for (var i in tag.attributes) { + print(" "+i+"=\""+entity(tag.attributes[i])+"\"") + } + print(">") +}) + +printer.on("text", ontext) +printer.on("doctype", ontext) +function ontext (text) { + this.indent() + print(text) +} + +printer.on("closetag", function (tag) { + this.level -- + this.indent() + print("") +}) + +printer.on("cdata", function (data) { + this.indent() + print("") +}) + +printer.on("comment", function (comment) { + this.indent() + print("") +}) + +printer.on("error", function (error) { + console.error(error) + throw error +}) + +if (!process.argv[2]) { + throw new Error("Please provide an xml file to prettify\n"+ + "TODO: read from stdin or take a file") +} +var xmlfile = require("path").join(process.cwd(), process.argv[2]) +var fstr = fs.createReadStream(xmlfile, { encoding: "utf8" }) + +function print (c) { + if (!process.stdout.write(c)) { + fstr.pause() + } +} + +process.stdout.on("drain", function () { + fstr.resume() +}) + +fstr.pipe(printer) diff --git a/www/node_modules/sax/examples/shopping.xml b/www/node_modules/sax/examples/shopping.xml new file mode 100644 index 0000000..223c6c6 --- /dev/null +++ b/www/node_modules/sax/examples/shopping.xml @@ -0,0 +1,2 @@ + +sandbox3.1 r31.Kadu4DC.phase357782011.10.06 15:37:23 PSTp2.a121bc2aaf029435dce62011-10-21T18:38:45.982-04:00P0Y0M0DT0H0M0.169S1112You are currently using the SDC API sandbox environment! No clicks to merchant URLs from this response will be paid. Please change the host of your API requests to 'publisher.api.shopping.com' when you have finished development and testinghttp://statTest.dealtime.com/pixel/noscript?PV_EvnTyp=APPV&APPV_APITSP=10%2F21%2F11_06%3A38%3A45_PM&APPV_DSPRQSID=p2.a121bc2aaf029435dce6&APPV_IMGURL=http://img.shopping.com/sc/glb/sdc_logo_106x19.gif&APPV_LI_LNKINID=7000610&APPV_LI_SBMKYW=nikon&APPV_MTCTYP=1000&APPV_PRTID=2002&APPV_BrnID=14804http://www.shopping.com/digital-cameras/productsDigital CamerasDigital CamerasElectronicshttp://www.shopping.com/xCH-electronics-nikon~linkin_id-7000610?oq=nikonCameras and Photographyhttp://www.shopping.com/xCH-cameras_and_photography-nikon~linkin_id-7000610?oq=nikonDigital Camerashttp://www.shopping.com/digital-cameras/nikon/products?oq=nikon&linkin_id=7000610nikonnikonDigital Camerashttp://www.shopping.com/digital-cameras/nikon/products?oq=nikon&linkin_id=7000610Nikon D3100 Digital Camera14.2 Megapixel, SLR Camera, 3 in. LCD Screen, With High Definition Video, Weight: 1 lb.The Nikon D3100 digital SLR camera speaks to the growing ranks of enthusiastic D-SLR users and aspiring photographers by providing an easy-to-use and affordable entrance to the world of Nikon D-SLR’s. The 14.2-megapixel D3100 has powerful features, such as the enhanced Guide Mode that makes it easy to unleash creative potential and capture memories with still images and full HD video. Like having a personal photo tutor at your fingertips, this unique feature provides a simple graphical interface on the camera’s LCD that guides users by suggesting and/or adjusting camera settings to achieve the desired end result images. The D3100 is also the world’s first D-SLR to introduce full time auto focus (AF) in Live View and D-Movie mode to effortlessly achieve the critical focus needed when shooting Full HD 1080p video.http://di1.shopping.com/images/pi/93/bc/04/101677489-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=1http://di1.shopping.com/images/pi/93/bc/04/101677489-606x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=194.56http://img.shopping.com/sc/pr/sdc_stars_sm_4.5.gifhttp://www.shopping.com/Nikon-D3100/reviews~linkin_id-7000610429.001360.00http://www.shopping.com/Nikon-D3100/prices~linkin_id-7000610http://www.shopping.com/Nikon-D3100/info~linkin_id-7000610Nikon D3100 Digital SLR Camera with 18-55mm NIKKOR VR LensThe Nikon D3100 Digital SLR Camera is an affordable compact and lightweight photographic power-house. It features the all-purpose 18-55mm VR lens a high-resolution 14.2 MP CMOS sensor along with a feature set that's comprehensive yet easy to navigate - the intuitive onboard learn-as-you grow guide mode allows the photographer to understand what the 3100 can do quickly and easily. Capture beautiful pictures and amazing Full HD 1080p movies with sound and full-time autofocus. Availabilty: In Stock!7185Nikonhttp://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-350x350-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stockFree Shipping with Any Purchase!529.000.00799.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=647&BEFID=7185&aon=%5E1&MerchantID=475674&crawler_id=475674&dealId=-ZW6BMZqz6fbS-aULwga_g%3D%3D&url=http%3A%2F%2Fwww.fumfie.com%2Fproduct%2F343.5%2Fshopping-com%3F&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D3100+Digital+SLR+Camera+with+18-55mm+NIKKOR+VR+Lens&dlprc=529.0&crn=&istrsmrc=1&isathrsl=0&AR=1&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=1&cid=&semid1=&semid2=&IsLps=0&CC=1&SL=1&FS=1&code=&acode=658&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=FumFiehttp://img.shopping.com/cctool/merch_logos/475674.gif866 666 91985604.27http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_fumfie~MRD-475674~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSF343C5Nikon Nikon D3100 14.2MP Digital SLR Camera with 18-55mm f/3.5-5.6 AF-S DX VR, CamerasNikon D3100 14.2MP Digital SLR Camera with 18-55mm f/3.5-5.6 AF-S DX VR7185Nikonhttp://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-385x352-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stock549.000.00549.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=779&BEFID=7185&aon=%5E1&MerchantID=305814&crawler_id=305814&dealId=md1e9lD8vdOu4FHQfJqKng%3D%3D&url=http%3A%2F%2Fwww.electronics-expo.com%2Findex.php%3Fpage%3Ditem%26id%3DNIKD3100%26source%3DSideCar%26scpid%3D8%26scid%3Dscsho318727%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+Nikon+D3100+14.2MP+Digital+SLR+Camera+with+18-55mm+f%2F3.5-5.6+AF-S+DX+VR%2C+Cameras&dlprc=549.0&crn=&istrsmrc=1&isathrsl=0&AR=9&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=9&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=771&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Electronics Expohttp://img.shopping.com/cctool/merch_logos/305814.gif1-888-707-EXPO3713.90http://img.shopping.com/sc/mr/sdc_checks_4.gifhttp://www.shopping.com/xMR-store_electronics_expo~MRD-305814~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSNIKD3100Nikon D3100 14.2-Megapixel Digital SLR Camera With 18-55mm Zoom-Nikkor Lens, BlackSplit-second shutter response captures shots other cameras may have missed Helps eliminate the frustration of shutter delay! 14.2-megapixels for enlargements worth framing and hanging. Takes breathtaking 1080p HD movies. ISO sensitivity from 100-1600 for bright or dimly lit settings. 3.0in. color LCD for beautiful, wide-angle framing and viewing. In-camera image editing lets you retouch with no PC. Automatic scene modes include Child, Sports, Night Portrait and more. Accepts SDHC memory cards. Nikon D3100 14.2-Megapixel Digital SLR Camera With 18-55mm Zoom-Nikkor Lens, Black is one of many Digital SLR Cameras available through Office Depot. Made by Nikon.7185Nikonhttp://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-250x250-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stock549.990.00699.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=698&BEFID=7185&aon=%5E1&MerchantID=467671&crawler_id=467671&dealId=yYuaXnDFtCY7rDUjkY2aaw%3D%3D&url=http%3A%2F%2Flink.mercent.com%2Fredirect.ashx%3Fmr%3AmerchantID%3DOfficeDepot%26mr%3AtrackingCode%3DCEC9669E-6ABC-E011-9F24-0019B9C043EB%26mr%3AtargetUrl%3Dhttp%3A%2F%2Fwww.officedepot.com%2Fa%2Fproducts%2F486292%2FNikon-D3100-142-Megapixel-Digital-SLR%2F%253fcm_mmc%253dMercent-_-Shopping-_-Cameras_and_Camcorders-_-486292&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D3100+14.2-Megapixel+Digital+SLR+Camera+With+18-55mm+Zoom-Nikkor+Lens%2C+Black&dlprc=549.99&crn=&istrsmrc=1&isathrsl=0&AR=10&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=10&cid=&semid1=&semid2=&IsLps=0&CC=1&SL=1&FS=1&code=&acode=690&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Office Depothttp://img.shopping.com/cctool/merch_logos/467671.gif1-800-GO-DEPOT1352.37http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_office_depot_4158555~MRD-467671~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS486292Nikon® D3100™ 14.2MP Digital SLR with 18-55mm LensThe Nikon D3100 DSLR will surprise you with its simplicity and impress you with superb results.7185Nikonhttp://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stock549.996.05549.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=Rl56U7CuiTYsH4MGZ02lxQ%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D903483107%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C2%AE+D3100%E2%84%A2+14.2MP+Digital+SLR+with+18-55mm+Lens&dlprc=549.99&crn=&istrsmrc=0&isathrsl=0&AR=11&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=11&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=496&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS9614867Nikon D3100 SLR w/Nikon 18-55mm VR & 55-200mm VR Lenses14.2 Megapixels3" LCDLive ViewHD 1080p Video w/ Sound & Autofocus11-point Autofocus3 Frames per Second ShootingISO 100 to 3200 (Expand to 12800-Hi2)Self Cleaning SensorEXPEED 2, Image Processing EngineScene Recognition System7185Nikonhttp://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-345x345-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stock695.000.00695.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&BEFID=7185&aon=%5E1&MerchantID=487342&crawler_id=487342&dealId=huS6xZKDKaKMTMP71eI6DA%3D%3D&url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D32983%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D3100+SLR+w%2FNikon+18-55mm+VR+%26+55-200mm+VR+Lenses&dlprc=695.0&crn=&istrsmrc=0&isathrsl=0&AR=15&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=101677489&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=15&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=379&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RytherCamera.comhttp://img.shopping.com/cctool/merch_logos/487342.gif1-877-644-75930http://img.shopping.com/sc/glb/flag/US.gifUS32983Nikon COOLPIX S203 Digital Camera10 Megapixel, Ultra-Compact Camera, 2.5 in. LCD Screen, 3x Optical Zoom, With Video Capability, Weight: 0.23 lb.With 10.34 mega pixel, electronic VR vibration reduction, 5-level brightness adjustment, 3x optical zoom, and TFT LCD, Nikon Coolpix s203 fulfills all the demands of any photographer. The digital camera has an inbuilt memory of 44MB and an external memory slot made for all kinds of SD (Secure Digital) cards.http://di1.shopping.com/images/pi/c4/ef/1b/95397883-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=2http://di1.shopping.com/images/pi/c4/ef/1b/95397883-500x499-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=20139.00139.00http://www.shopping.com/Nikon-Coolpix-S203/prices~linkin_id-7000610http://www.shopping.com/Nikon-Coolpix-S203/info~linkin_id-7000610Nikon Coolpix S203 Digital Camera (Red)With 10.34 mega pixel, electronic VR vibration reduction, 5-level brightness adjustment, 3x optical zoom, and TFT LCD, Nikon Coolpix s203 fulfills all the demands of any photographer. The digital camera has an inbuilt memory of 44MB and an external memory slot made for all kinds of SD (Secure Digital) cards.7185Nikonhttp://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stockFantastic prices with ease & comfort of Amazon.com!139.009.50139.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=566&BEFID=7185&aon=%5E1&MerchantID=301531&crawler_id=1903313&dealId=sBd2JnIEPM-A_lBAM1RZgQ%3D%3D&url=http%3A%2F%2Fwww.amazon.com%2Fdp%2FB002T964IM%2Fref%3Dasc_df_B002T964IM1751618%3Fsmid%3DA22UHVNXG98FAT%26tag%3Ddealtime-ce-mp01feed-20%26linkCode%3Dasn%26creative%3D395105%26creativeASIN%3DB002T964IM&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+Coolpix+S203+Digital+Camera+%28Red%29&dlprc=139.0&crn=&istrsmrc=0&isathrsl=0&AR=63&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=95397883&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=63&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=518&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Amazon Marketplacehttp://img.shopping.com/cctool/merch_logos/301531.gif2132.73http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_amazon_marketplace_9689~MRD-301531~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSB002T964IMNikon S3100 Digital Camera14.5 Megapixel, Compact Camera, 2.7 in. LCD Screen, 5x Optical Zoom, With High Definition Video, Weight: 0.23 lb.This digital camera features a wide-angle optical Zoom-NIKKOR glass lens that allows you to capture anything from landscapes to portraits to action shots. The high-definition movie mode with one-touch recording makes it easy to capture video clips.http://di1.shopping.com/images/pi/66/2d/33/106834268-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=3http://di1.shopping.com/images/pi/66/2d/33/106834268-507x387-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=312.00http://img.shopping.com/sc/pr/sdc_stars_sm_2.gifhttp://www.shopping.com/nikon-s3100/reviews~linkin_id-700061099.95134.95http://www.shopping.com/nikon-s3100/prices~linkin_id-7000610http://www.shopping.com/nikon-s3100/info~linkin_id-7000610CoolPix S3100 14 Megapixel Compact Digital Camera- RedNikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - red7185Nikonhttp://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stockGet 30 days FREE SHIPPING w/ ShipVantage119.956.95139.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=UUyGoqV8r0-xrkn-rnGNbg%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJ3Yx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmDAJeU1oyGG0GcBdhGwUGCAVqYF9SO0xSN1sZdmA7dmMdBQAJB24qX1NbQxI6AjA2ME5dVFULPDsGPFcQTTdaLTA6SR0OFlQvPAwMDxYcYlxIVkcoLTcCDA%3D%3D%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=CoolPix+S3100+14+Megapixel+Compact+Digital+Camera-+Red&dlprc=119.95&crn=&istrsmrc=1&isathrsl=0&AR=28&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=28&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=0&code=&acode=583&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00337013000COOLPIX S3100 PinkNikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - pink7185Nikonhttp://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stockGet 30 days FREE SHIPPING w/ ShipVantage119.956.95139.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=X87AwXlW1dXoMXk4QQDToQ%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJxYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcUFxDEGsPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=COOLPIX+S3100+Pink&dlprc=119.95&crn=&istrsmrc=1&isathrsl=0&AR=31&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=31&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=0&code=&acode=583&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00337015000Nikon Coolpix S3100 14.0 MP Digital Camera - SilverNikon Coolpix S3100 14.0 MP Digital Camera - Silver7185Nikonhttp://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-270x270-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stock109.970.00109.97http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=803&BEFID=7185&aon=%5E&MerchantID=475774&crawler_id=475774&dealId=nvFwnpfA4rlA1Dbksdsa0w%3D%3D&url=http%3A%2F%2Fwww.thewiz.com%2Fcatalog%2Fproduct.jsp%3FmodelNo%3DS3100SILVER%26gdftrk%3DgdfV2677_a_7c996_a_7c4049_a_7c26262&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+Coolpix+S3100+14.0+MP+Digital+Camera+-+Silver&dlprc=109.97&crn=&istrsmrc=0&isathrsl=0&AR=33&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=33&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=797&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=TheWiz.comhttp://img.shopping.com/cctool/merch_logos/475774.gif877-542-69880http://img.shopping.com/sc/glb/flag/US.gifUS26262Nikon� COOLPIX� S3100 14MP Digital Camera (Silver)The Nikon COOLPIX S3100 is the easy way to share your life and stay connected.7185Nikonhttp://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stock119.996.05119.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=5GtaN2NeryKwps-Se2l-4g%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D848064082%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C3%AF%C2%BF%C2%BD+COOLPIX%C3%AF%C2%BF%C2%BD+S3100+14MP+Digital+Camera+%28Silver%29&dlprc=119.99&crn=&istrsmrc=0&isathrsl=0&AR=37&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=37&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=509&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS10101095COOLPIX S3100 YellowNikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - yellow7185Nikonhttp://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stockGet 30 days FREE SHIPPING w/ ShipVantage119.956.95139.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=a43m0RXulX38zCnQjU59jw%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJwYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcUFxDEGoPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=COOLPIX+S3100+Yellow&dlprc=119.95&crn=&istrsmrc=1&isathrsl=0&AR=38&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=106834268&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=38&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=0&code=&acode=583&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00337014000Nikon D90 Digital Camera12.3 Megapixel, Point and Shoot Camera, 3 in. LCD Screen, With Video Capability, Weight: 1.36 lb.Untitled Document Nikon D90 SLR Digital Camera With 28-80mm 75-300mm Lens Kit The Nikon D90 SLR Digital Camera, with its 12.3-megapixel DX-format CMOS, 3" High resolution LCD display, Scene Recognition System, Picture Control, Active D-Lighting, and one-button Live View, provides photo enthusiasts with the image quality and performance they need to pursue their own vision while still being intuitive enough for use as an everyday camera.http://di1.shopping.com/images/pi/52/fb/d3/99671132-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=4http://di1.shopping.com/images/pi/52/fb/d3/99671132-499x255-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=475.00http://img.shopping.com/sc/pr/sdc_stars_sm_5.gifhttp://www.shopping.com/Nikon-D90-with-18-270mm-Lens/reviews~linkin_id-7000610689.002299.00http://www.shopping.com/Nikon-D90-with-18-270mm-Lens/prices~linkin_id-7000610http://www.shopping.com/Nikon-D90-with-18-270mm-Lens/info~linkin_id-7000610Nikon® D90 12.3MP Digital SLR Camera (Body Only)The Nikon D90 will make you rethink what a digital SLR camera can achieve.7185Nikonhttp://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stock1015.996.051015.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=GU5JJkpUAxe5HujB7fkwAA%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D851830266%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C2%AE+D90+12.3MP+Digital+SLR+Camera+%28Body+Only%29&dlprc=1015.99&crn=&istrsmrc=0&isathrsl=0&AR=14&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=14&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=496&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS10148659Nikon D90 SLR Digital Camera (Camera Body)The Nikon D90 SLR Digital Camera with its 12.3-megapixel DX-format CCD 3" High resolution LCD display Scene Recognition System Picture Control Active D-Lighting and one-button Live View provides photo enthusiasts with the image quality and performance they need to pursue their own vision while still being intuitive enough for use as an everyday camera. In addition the D90 introduces the D-Movie mode allowing for the first time an interchangeable lens SLR camera that is capable of recording 720p HD movie clips. Availabilty: In Stock7185Nikonhttp://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-350x350-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stockFree Shipping with Any Purchase!689.000.00900.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=647&BEFID=7185&aon=%5E1&MerchantID=475674&crawler_id=475674&dealId=XhURuSC-spBbTIDfo4qfzQ%3D%3D&url=http%3A%2F%2Fwww.fumfie.com%2Fproduct%2F169.5%2Fshopping-com%3F&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+SLR+Digital+Camera+%28Camera+Body%29&dlprc=689.0&crn=&istrsmrc=1&isathrsl=0&AR=16&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=16&cid=&semid1=&semid2=&IsLps=0&CC=1&SL=1&FS=1&code=&acode=658&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=FumFiehttp://img.shopping.com/cctool/merch_logos/475674.gif866 666 91985604.27http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_fumfie~MRD-475674~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSF169C5Nikon D90 SLR w/Nikon 18-105mm VR & 55-200mm VR Lenses12.3 MegapixelDX Format CMOS Sensor3" VGA LCD DisplayLive ViewSelf Cleaning SensorD-Movie ModeHigh Sensitivity (ISO 3200)4.5 fps BurstIn-Camera Image Editing7185Nikonhttp://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stock1189.000.001189.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&BEFID=7185&aon=%5E1&MerchantID=487342&crawler_id=487342&dealId=o0Px_XLWDbrxAYRy3rCmyQ%3D%3D&url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D30619%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+SLR+w%2FNikon+18-105mm+VR+%26+55-200mm+VR+Lenses&dlprc=1189.0&crn=&istrsmrc=0&isathrsl=0&AR=20&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=20&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=379&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RytherCamera.comhttp://img.shopping.com/cctool/merch_logos/487342.gif1-877-644-75930http://img.shopping.com/sc/glb/flag/US.gifUS30619Nikon D90 12.3 Megapixel Digital SLR Camera (Body Only)Fusing 12.3 megapixel image quality and a cinematic 24fps D-Movie Mode, the Nikon D90 exceeds the demands of passionate photographers. Coupled with Nikon's EXPEED image processing technologies and NIKKOR optics, breathtaking image fidelity is assured. Combined with fast 0.15ms power-up and split-second 65ms shooting lag, dramatic action and decisive moments are captured easily. Effective 4-frequency, ultrasonic sensor cleaning frees image degrading dust particles from the sensor's optical low pass filter.7185Nikonhttp://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stockFREE FEDEX 2-3 DAY DELIVERY899.950.00899.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=269&BEFID=7185&aon=%5E&MerchantID=9296&crawler_id=811558&dealId=4HgbWJSJ8ssgIf8B0MXIwA%3D%3D&url=http%3A%2F%2Fwww.pcnation.com%2Foptics-gallery%2Fdetails.asp%3Faffid%3D305%26item%3D2N145P&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+12.3+Megapixel+Digital+SLR+Camera+%28Body+Only%29&dlprc=899.95&crn=&istrsmrc=1&isathrsl=0&AR=21&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=21&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=257&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=PCNationhttp://img.shopping.com/cctool/merch_logos/9296.gif800-470-707916224.43http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_pcnation_9689~MRD-9296~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS2N145PNikon D90 12.3MP Digital SLR Camera (Body Only)Fusing 12.3-megapixel image quality inherited from the award-winning D300 with groundbreaking features, the D90's breathtaking, low-noise image quality is further advanced with EXPEED image processing. Split-second shutter response and continuous shooting at up to 4.5 frames-per-second provide the power to capture fast action and precise moments perfectly, while Nikon's exclusive Scene Recognition System contributes to faster 11-area autofocus performance, finer white balance detection and more. The D90 delivers the control passionate photographers demand, utilizing comprehensive exposure functions and the intelligence of 3D Color Matrix Metering II. Stunning results come to life on a 3-inch 920,000-dot color LCD monitor, providing accurate image review, Live View composition and brilliant playback of the D90's cinematic-quality 24-fps HD D-Movie mode.7185Nikonhttp://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stockFantastic prices with ease & comfort of Amazon.com!780.000.00780.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=566&BEFID=7185&aon=%5E1&MerchantID=301531&crawler_id=1903313&dealId=UNDa3uMDZXOnvD_7sTILYg%3D%3D&url=http%3A%2F%2Fwww.amazon.com%2Fdp%2FB001ET5U92%2Fref%3Dasc_df_B001ET5U921751618%3Fsmid%3DAHF4SYKP09WBH%26tag%3Ddealtime-ce-mp01feed-20%26linkCode%3Dasn%26creative%3D395105%26creativeASIN%3DB001ET5U92&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+12.3MP+Digital+SLR+Camera+%28Body+Only%29&dlprc=780.0&crn=&istrsmrc=0&isathrsl=0&AR=29&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=99671132&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=29&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=520&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Amazon Marketplacehttp://img.shopping.com/cctool/merch_logos/301531.gif2132.73http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_amazon_marketplace_9689~MRD-301531~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUSB001ET5U92Nikon D90 Digital Camera with 18-105mm lens12.9 Megapixel, SLR Camera, 3 in. LCD Screen, 5.8x Optical Zoom, With Video Capability, Weight: 2.3 lb.Its 12.3 megapixel DX-format CMOS image sensor and EXPEED image processing system offer outstanding image quality across a wide ISO light sensitivity range. Live View mode lets you compose and shoot via the high-resolution 3-inch LCD monitor, and an advanced Scene Recognition System and autofocus performance help capture images with astounding accuracy. Movies can be shot in Motion JPEG format using the D-Movie function. The camera’s large image sensor ensures exceptional movie image quality and you can create dramatic effects by shooting with a wide range of interchangeable NIKKOR lenses, from wide-angle to macro to fisheye, or by adjusting the lens aperture and experimenting with depth-of-field. The D90 – designed to fuel your passion for photography.http://di1.shopping.com/images/pi/57/6a/4f/70621646-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5http://di1.shopping.com/images/pi/57/6a/4f/70621646-490x489-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=2&c=1&l=7000610&t=111021183845&r=5324.81http://img.shopping.com/sc/pr/sdc_stars_sm_5.gifhttp://www.shopping.com/Nikon-D90-with-18-105mm-lens/reviews~linkin_id-7000610849.951599.95http://www.shopping.com/Nikon-D90-with-18-105mm-lens/prices~linkin_id-7000610http://www.shopping.com/Nikon-D90-with-18-105mm-lens/info~linkin_id-7000610Nikon D90 18-105mm VR LensThe Nikon D90 SLR Digital Camera with its 12.3-megapixel DX-format CMOS 3" High resolution LCD display Scene Recognition System Picture Control Active D-Lighting and one-button Live View prov7185Nikonhttp://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1http://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-260x260-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=1in-stock849.950.00849.95http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=419&BEFID=7185&aon=%5E1&MerchantID=9390&crawler_id=1905054&dealId=3o5e1VghgJPfhLvT1JFKTA%3D%3D&url=http%3A%2F%2Fwww.ajrichard.com%2FNikon-D90-18-105mm-VR-Lens%2Fp-292%3Frefid%3DShopping%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+18-105mm+VR+Lens&dlprc=849.95&crn=&istrsmrc=0&isathrsl=0&AR=2&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=2&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=425&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=AJRichardhttp://img.shopping.com/cctool/merch_logos/9390.gif1-888-871-125631244.48http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_ajrichard~MRD-9390~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS292Nikon D90 SLR w/Nikon 18-105mm VR Lens12.3 MegapixelDX Format CMOS Sensor3" VGA LCD DisplayLive ViewSelf Cleaning SensorD-Movie ModeHigh Sensitivity (ISO 3200)4.5 fps BurstIn-Camera Image Editing7185Nikonhttp://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=2in-stock909.000.00909.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&BEFID=7185&aon=%5E1&MerchantID=487342&crawler_id=487342&dealId=_lYWj_jbwfsSkfcwUcDuww%3D%3D&url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D30971%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+SLR+w%2FNikon+18-105mm+VR+Lens&dlprc=909.0&crn=&istrsmrc=0&isathrsl=0&AR=3&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=3&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=1&code=&acode=379&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RytherCamera.comhttp://img.shopping.com/cctool/merch_logos/487342.gif1-877-644-75930http://img.shopping.com/sc/glb/flag/US.gifUS3097125448/D90 12.3 Megapixel Digital Camera 18-105mm Zoom Lens w/ 3" Screen - BlackNikon D90 - Digital camera - SLR - 12.3 Mpix - Nikon AF-S DX 18-105mm lens - optical zoom: 5.8 x - supported memory: SD, SDHC7185Nikonhttp://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=3in-stockGet 30 days FREE SHIPPING w/ ShipVantage1199.008.201199.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&BEFID=7185&aon=%5E1&MerchantID=485615&crawler_id=485615&dealId=1KCclCGuWvty2XKU9skadg%3D%3D&url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBRtFXpzYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcVlhCGGkPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=25448%2FD90+12.3+Megapixel+Digital+Camera+18-105mm+Zoom+Lens+w%2F+3%22+Screen+-+Black&dlprc=1199.0&crn=&istrsmrc=1&isathrsl=0&AR=4&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=4&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=586&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=Searshttp://img.shopping.com/cctool/merch_logos/485615.gif1-800-349-43588882.85http://img.shopping.com/sc/mr/sdc_checks_3.gifhttp://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS00353197000Nikon® D90 12.3MP Digital SLR with 18-105mm LensThe Nikon D90 will make you rethink what a digital SLR camera can achieve.7185Nikonhttp://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4http://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=4in-stock1350.996.051350.99http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&BEFID=7185&aon=%5E1&MerchantID=332477&crawler_id=332477&dealId=3-VOSfVV5Jo7HlA4kJtanA%3D%3D&url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D982673361%26&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon%C2%AE+D90+12.3MP+Digital+SLR+with+18-105mm+Lens&dlprc=1350.99&crn=&istrsmrc=0&isathrsl=0&AR=5&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=5&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=0&FS=0&code=&acode=496&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=RadioShackhttp://img.shopping.com/cctool/merch_logos/332477.gif242.25http://img.shopping.com/sc/mr/sdc_checks_25.gifhttp://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS11148905Nikon D90 Kit 12.3-megapixel Digital SLR with 18-105mm VR LensPhotographers, take your passion further!Now is the time for new creativity, and to rethink what a digital SLR camera can achieve. It's time for the D90, a camera with everything you would expect from Nikon's next-generation D-SLRs, and some unexpected surprises, as well. The stunning image quality is inherited from the D300, Nikon's DX-format flagship. The D90 also has Nikon's unmatched ergonomics and high performance, and now takes high-quality movies with beautifully cinematic results. The world of photography has changed, and with the D90 in your hands, it's time to make your own rules.AF-S DX NIKKOR 18-105mm f/3.5-5.6G ED VR LensWide-ratio 5.8x zoom Compact, versatile and ideal for a broad range of shooting situations, ranging from interiors and landscapes to beautiful portraits� a perfect everyday zoom. Nikon VR (Vibration Reduction) image stabilization Vibration Reduction is engineered specifically for each VR NIKKOR lens and enables handheld shooting at up to 3 shutter speeds slower than would7185Nikonhttp://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-300x232-0-0.jpg?p=p2.a121bc2aaf029435dce6&a=1&c=1&l=7000610&t=111021183845&r=5in-stockShipping Included!1050.000.001199.00http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=135&BEFID=7185&aon=%5E1&MerchantID=313162&crawler_id=313162&dealId=kQnB6rS4AjN5dx5h2_631g%3D%3D&url=http%3A%2F%2Fonecall.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1pZSxNoWHFwLx8GTAICa2ZeH1sPXTZLNzRpAh1HR0BxPQEGCBJNMhFHUElsFCFCVkVTTHAcBggEHQ4aHXNpGERGH3RQODsbAgdechJtbBt8fx8JAwhtZFAzJj1oGgIWCxRlNyFOUV9UUGIxBgo0T0IyTSYqJ0RWHw4QPCIBAAQXRGMDICg6TllZVBhh%26nAID%3D13736960&linkin_id=7000610&Issdt=111021183845&searchID=p2.a121bc2aaf029435dce6&DealName=Nikon+D90+Kit+12.3-megapixel+Digital+SLR+with+18-105mm+VR+Lens&dlprc=1050.0&crn=&istrsmrc=1&isathrsl=0&AR=6&NG=20&NDP=200&PN=1&ST=7&DB=sdcprod&MT=phx-pkadudc2&FPT=DSP&NDS=&NMS=&MRS=&PD=70621646&brnId=14804&IsFtr=0&IsSmart=0&DMT=&op=&CM=&DlLng=1&RR=6&cid=&semid1=&semid2=&IsLps=0&CC=0&SL=1&FS=1&code=&acode=143&category=&HasLink=&frameId=&ND=&MN=&PT=&prjID=&GR=&lnkId=&VK=OneCallhttp://img.shopping.com/cctool/merch_logos/313162.gif1.800.398.07661804.44http://img.shopping.com/sc/mr/sdc_checks_45.gifhttp://www.shopping.com/xMR-store_onecall_9689~MRD-313162~S-1~linkin_id-7000610http://img.shopping.com/sc/glb/flag/US.gifUS92826Price rangehttp://www.shopping.com/digital-cameras/nikon/products?oq=nikon&linkin_id=7000610$24 - $4012http://www.shopping.com/digital-cameras/nikon/products?minPrice=24&maxPrice=4012&linkin_id=7000610$4012 - $7999http://www.shopping.com/digital-cameras/nikon/products?minPrice=4012&maxPrice=7999&linkin_id=7000610Brandhttp://www.shopping.com/digital-cameras/nikon/products~all-9688-brand~MS-1?oq=nikon&linkin_id=7000610Nikonhttp://www.shopping.com/digital-cameras/nikon+brand-nikon/products~linkin_id-7000610Cranehttp://www.shopping.com/digital-cameras/nikon+9688-brand-crane/products~linkin_id-7000610Ikelitehttp://www.shopping.com/digital-cameras/nikon+ikelite/products~linkin_id-7000610Bowerhttp://www.shopping.com/digital-cameras/nikon+bower/products~linkin_id-7000610FUJIFILMhttp://www.shopping.com/digital-cameras/nikon+brand-fuji/products~linkin_id-7000610Storehttp://www.shopping.com/digital-cameras/nikon/products~all-store~MS-1?oq=nikon&linkin_id=7000610Amazon Marketplacehttp://www.shopping.com/digital-cameras/nikon+store-amazon-marketplace-9689/products~linkin_id-7000610Amazonhttp://www.shopping.com/digital-cameras/nikon+store-amazon/products~linkin_id-7000610Adoramahttp://www.shopping.com/digital-cameras/nikon+store-adorama/products~linkin_id-7000610J&R Music and Computer Worldhttp://www.shopping.com/digital-cameras/nikon+store-j-r-music-and-computer-world/products~linkin_id-7000610RytherCamera.comhttp://www.shopping.com/digital-cameras/nikon+store-rythercamera-com/products~linkin_id-7000610Resolutionhttp://www.shopping.com/digital-cameras/nikon/products~all-21885-resolution~MS-1?oq=nikon&linkin_id=7000610Under 4 Megapixelhttp://www.shopping.com/digital-cameras/nikon+under-4-megapixel/products~linkin_id-7000610At least 5 Megapixelhttp://www.shopping.com/digital-cameras/nikon+5-megapixel-digital-cameras/products~linkin_id-7000610At least 6 Megapixelhttp://www.shopping.com/digital-cameras/nikon+6-megapixel-digital-cameras/products~linkin_id-7000610At least 7 Megapixelhttp://www.shopping.com/digital-cameras/nikon+7-megapixel-digital-cameras/products~linkin_id-7000610At least 8 Megapixelhttp://www.shopping.com/digital-cameras/nikon+8-megapixel-digital-cameras/products~linkin_id-7000610Featureshttp://www.shopping.com/digital-cameras/nikon/products~all-32804-features~MS-1?oq=nikon&linkin_id=7000610Shockproofhttp://www.shopping.com/digital-cameras/nikon+32804-features-shockproof/products~linkin_id-7000610Waterproofhttp://www.shopping.com/digital-cameras/nikon+32804-features-waterproof/products~linkin_id-7000610Freezeproofhttp://www.shopping.com/digital-cameras/nikon+32804-features-freezeproof/products~linkin_id-7000610Dust proofhttp://www.shopping.com/digital-cameras/nikon+32804-features-dust-proof/products~linkin_id-7000610Image Stabilizationhttp://www.shopping.com/digital-cameras/nikon+32804-features-image-stabilization/products~linkin_id-7000610hybriddigital camerag1sonycameracanonnikonkodak digital camerakodaksony cybershotkodak easyshare digital cameranikon coolpixolympuspink digital cameracanon powershot \ No newline at end of file diff --git a/www/node_modules/sax/examples/strict.dtd b/www/node_modules/sax/examples/strict.dtd new file mode 100644 index 0000000..b274559 --- /dev/null +++ b/www/node_modules/sax/examples/strict.dtd @@ -0,0 +1,870 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%HTMLlat1; + + +%HTMLsymbol; + + +%HTMLspecial; + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/www/node_modules/sax/examples/test.html b/www/node_modules/sax/examples/test.html new file mode 100644 index 0000000..61f8f1a --- /dev/null +++ b/www/node_modules/sax/examples/test.html @@ -0,0 +1,15 @@ + + + + + testing the parser + + + +

    hello + + + + diff --git a/www/node_modules/sax/examples/test.xml b/www/node_modules/sax/examples/test.xml new file mode 100644 index 0000000..801292d --- /dev/null +++ b/www/node_modules/sax/examples/test.xml @@ -0,0 +1,1254 @@ + + +]> + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + + Some Text + + + + + + + are ok in here. ]]> + + Pre-Text & Inlined text Post-text. +  + + \ No newline at end of file diff --git a/www/node_modules/sax/lib/sax.js b/www/node_modules/sax/lib/sax.js new file mode 100644 index 0000000..410a507 --- /dev/null +++ b/www/node_modules/sax/lib/sax.js @@ -0,0 +1,1410 @@ +// wrapper for non-node envs +;(function (sax) { + +sax.parser = function (strict, opt) { return new SAXParser(strict, opt) } +sax.SAXParser = SAXParser +sax.SAXStream = SAXStream +sax.createStream = createStream + +// When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns. +// When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)), +// since that's the earliest that a buffer overrun could occur. This way, checks are +// as rare as required, but as often as necessary to ensure never crossing this bound. +// Furthermore, buffers are only tested at most once per write(), so passing a very +// large string into write() might have undesirable effects, but this is manageable by +// the caller, so it is assumed to be safe. Thus, a call to write() may, in the extreme +// edge case, result in creating at most one complete copy of the string passed in. +// Set to Infinity to have unlimited buffers. +sax.MAX_BUFFER_LENGTH = 64 * 1024 + +var buffers = [ + "comment", "sgmlDecl", "textNode", "tagName", "doctype", + "procInstName", "procInstBody", "entity", "attribName", + "attribValue", "cdata", "script" +] + +sax.EVENTS = // for discoverability. + [ "text" + , "processinginstruction" + , "sgmldeclaration" + , "doctype" + , "comment" + , "attribute" + , "opentag" + , "closetag" + , "opencdata" + , "cdata" + , "closecdata" + , "error" + , "end" + , "ready" + , "script" + , "opennamespace" + , "closenamespace" + ] + +function SAXParser (strict, opt) { + if (!(this instanceof SAXParser)) return new SAXParser(strict, opt) + + var parser = this + clearBuffers(parser) + parser.q = parser.c = "" + parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH + parser.opt = opt || {} + parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags + parser.looseCase = parser.opt.lowercase ? "toLowerCase" : "toUpperCase" + parser.tags = [] + parser.closed = parser.closedRoot = parser.sawRoot = false + parser.tag = parser.error = null + parser.strict = !!strict + parser.noscript = !!(strict || parser.opt.noscript) + parser.state = S.BEGIN + parser.ENTITIES = Object.create(sax.ENTITIES) + parser.attribList = [] + + // namespaces form a prototype chain. + // it always points at the current tag, + // which protos to its parent tag. + if (parser.opt.xmlns) parser.ns = Object.create(rootNS) + + // mostly just for error reporting + parser.trackPosition = parser.opt.position !== false + if (parser.trackPosition) { + parser.position = parser.line = parser.column = 0 + } + emit(parser, "onready") +} + +if (!Object.create) Object.create = function (o) { + function f () { this.__proto__ = o } + f.prototype = o + return new f +} + +if (!Object.getPrototypeOf) Object.getPrototypeOf = function (o) { + return o.__proto__ +} + +if (!Object.keys) Object.keys = function (o) { + var a = [] + for (var i in o) if (o.hasOwnProperty(i)) a.push(i) + return a +} + +function checkBufferLength (parser) { + var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10) + , maxActual = 0 + for (var i = 0, l = buffers.length; i < l; i ++) { + var len = parser[buffers[i]].length + if (len > maxAllowed) { + // Text/cdata nodes can get big, and since they're buffered, + // we can get here under normal conditions. + // Avoid issues by emitting the text node now, + // so at least it won't get any bigger. + switch (buffers[i]) { + case "textNode": + closeText(parser) + break + + case "cdata": + emitNode(parser, "oncdata", parser.cdata) + parser.cdata = "" + break + + case "script": + emitNode(parser, "onscript", parser.script) + parser.script = "" + break + + default: + error(parser, "Max buffer length exceeded: "+buffers[i]) + } + } + maxActual = Math.max(maxActual, len) + } + // schedule the next check for the earliest possible buffer overrun. + parser.bufferCheckPosition = (sax.MAX_BUFFER_LENGTH - maxActual) + + parser.position +} + +function clearBuffers (parser) { + for (var i = 0, l = buffers.length; i < l; i ++) { + parser[buffers[i]] = "" + } +} + +function flushBuffers (parser) { + closeText(parser) + if (parser.cdata !== "") { + emitNode(parser, "oncdata", parser.cdata) + parser.cdata = "" + } + if (parser.script !== "") { + emitNode(parser, "onscript", parser.script) + parser.script = "" + } +} + +SAXParser.prototype = + { end: function () { end(this) } + , write: write + , resume: function () { this.error = null; return this } + , close: function () { return this.write(null) } + , flush: function () { flushBuffers(this) } + } + +try { + var Stream = require("stream").Stream +} catch (ex) { + var Stream = function () {} +} + + +var streamWraps = sax.EVENTS.filter(function (ev) { + return ev !== "error" && ev !== "end" +}) + +function createStream (strict, opt) { + return new SAXStream(strict, opt) +} + +function SAXStream (strict, opt) { + if (!(this instanceof SAXStream)) return new SAXStream(strict, opt) + + Stream.apply(this) + + this._parser = new SAXParser(strict, opt) + this.writable = true + this.readable = true + + + var me = this + + this._parser.onend = function () { + me.emit("end") + } + + this._parser.onerror = function (er) { + me.emit("error", er) + + // if didn't throw, then means error was handled. + // go ahead and clear error, so we can write again. + me._parser.error = null + } + + this._decoder = null; + + streamWraps.forEach(function (ev) { + Object.defineProperty(me, "on" + ev, { + get: function () { return me._parser["on" + ev] }, + set: function (h) { + if (!h) { + me.removeAllListeners(ev) + return me._parser["on"+ev] = h + } + me.on(ev, h) + }, + enumerable: true, + configurable: false + }) + }) +} + +SAXStream.prototype = Object.create(Stream.prototype, + { constructor: { value: SAXStream } }) + +SAXStream.prototype.write = function (data) { + if (typeof Buffer === 'function' && + typeof Buffer.isBuffer === 'function' && + Buffer.isBuffer(data)) { + if (!this._decoder) { + var SD = require('string_decoder').StringDecoder + this._decoder = new SD('utf8') + } + data = this._decoder.write(data); + } + + this._parser.write(data.toString()) + this.emit("data", data) + return true +} + +SAXStream.prototype.end = function (chunk) { + if (chunk && chunk.length) this.write(chunk) + this._parser.end() + return true +} + +SAXStream.prototype.on = function (ev, handler) { + var me = this + if (!me._parser["on"+ev] && streamWraps.indexOf(ev) !== -1) { + me._parser["on"+ev] = function () { + var args = arguments.length === 1 ? [arguments[0]] + : Array.apply(null, arguments) + args.splice(0, 0, ev) + me.emit.apply(me, args) + } + } + + return Stream.prototype.on.call(me, ev, handler) +} + + + +// character classes and tokens +var whitespace = "\r\n\t " + // this really needs to be replaced with character classes. + // XML allows all manner of ridiculous numbers and digits. + , number = "0124356789" + , letter = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + // (Letter | "_" | ":") + , quote = "'\"" + , entity = number+letter+"#" + , attribEnd = whitespace + ">" + , CDATA = "[CDATA[" + , DOCTYPE = "DOCTYPE" + , XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace" + , XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/" + , rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE } + +// turn all the string character sets into character class objects. +whitespace = charClass(whitespace) +number = charClass(number) +letter = charClass(letter) + +// http://www.w3.org/TR/REC-xml/#NT-NameStartChar +// This implementation works on strings, a single character at a time +// as such, it cannot ever support astral-plane characters (10000-EFFFF) +// without a significant breaking change to either this parser, or the +// JavaScript language. Implementation of an emoji-capable xml parser +// is left as an exercise for the reader. +var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/ + +var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040\.\d-]/ + +quote = charClass(quote) +entity = charClass(entity) +attribEnd = charClass(attribEnd) + +function charClass (str) { + return str.split("").reduce(function (s, c) { + s[c] = true + return s + }, {}) +} + +function isRegExp (c) { + return Object.prototype.toString.call(c) === '[object RegExp]' +} + +function is (charclass, c) { + return isRegExp(charclass) ? !!c.match(charclass) : charclass[c] +} + +function not (charclass, c) { + return !is(charclass, c) +} + +var S = 0 +sax.STATE = +{ BEGIN : S++ +, TEXT : S++ // general stuff +, TEXT_ENTITY : S++ // & and such. +, OPEN_WAKA : S++ // < +, SGML_DECL : S++ // +, SCRIPT : S++ // " + , expect : + [ [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ] + , [ "opentag", { name: "script", attributes: {}, isSelfClosing: false } ] + , [ "text", "hello world" ] + , [ "closetag", "script" ] + , [ "closetag", "xml" ] + ] + , strict : false + , opt : { lowercasetags: true, noscript: true } + } + ) + +require(__dirname).test + ( { xml : "" + , expect : + [ [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ] + , [ "opentag", { name: "script", attributes: {}, isSelfClosing: false } ] + , [ "opencdata", undefined ] + , [ "cdata", "hello world" ] + , [ "closecdata", undefined ] + , [ "closetag", "script" ] + , [ "closetag", "xml" ] + ] + , strict : false + , opt : { lowercasetags: true, noscript: true } + } + ) + diff --git a/www/node_modules/sax/test/issue-84.js b/www/node_modules/sax/test/issue-84.js new file mode 100644 index 0000000..0e7ee69 --- /dev/null +++ b/www/node_modules/sax/test/issue-84.js @@ -0,0 +1,13 @@ +// https://github.com/isaacs/sax-js/issues/49 +require(__dirname).test + ( { xml : "body" + , expect : + [ [ "processinginstruction", { name: "has", body: "unbalanced \"quotes" } ], + [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ] + , [ "text", "body" ] + , [ "closetag", "xml" ] + ] + , strict : false + , opt : { lowercasetags: true, noscript: true } + } + ) diff --git a/www/node_modules/sax/test/parser-position.js b/www/node_modules/sax/test/parser-position.js new file mode 100644 index 0000000..e4a68b1 --- /dev/null +++ b/www/node_modules/sax/test/parser-position.js @@ -0,0 +1,28 @@ +var sax = require("../lib/sax"), + assert = require("assert") + +function testPosition(chunks, expectedEvents) { + var parser = sax.parser(); + expectedEvents.forEach(function(expectation) { + parser['on' + expectation[0]] = function() { + for (var prop in expectation[1]) { + assert.equal(parser[prop], expectation[1][prop]); + } + } + }); + chunks.forEach(function(chunk) { + parser.write(chunk); + }); +}; + +testPosition(['

    abcdefgh
    '], + [ ['opentag', { position: 5, startTagPosition: 1 }] + , ['text', { position: 19, startTagPosition: 14 }] + , ['closetag', { position: 19, startTagPosition: 14 }] + ]); + +testPosition(['
    abcde','fgh
    '], + [ ['opentag', { position: 5, startTagPosition: 1 }] + , ['text', { position: 19, startTagPosition: 14 }] + , ['closetag', { position: 19, startTagPosition: 14 }] + ]); diff --git a/www/node_modules/sax/test/script-close-better.js b/www/node_modules/sax/test/script-close-better.js new file mode 100644 index 0000000..f4887b9 --- /dev/null +++ b/www/node_modules/sax/test/script-close-better.js @@ -0,0 +1,12 @@ +require(__dirname).test({ + xml : "", + expect : [ + ["opentag", {"name": "HTML","attributes": {}, isSelfClosing: false}], + ["opentag", {"name": "HEAD","attributes": {}, isSelfClosing: false}], + ["opentag", {"name": "SCRIPT","attributes": {}, isSelfClosing: false}], + ["script", "'
    foo
    ", + expect : [ + ["opentag", {"name": "HTML","attributes": {}, "isSelfClosing": false}], + ["opentag", {"name": "HEAD","attributes": {}, "isSelfClosing": false}], + ["opentag", {"name": "SCRIPT","attributes": {}, "isSelfClosing": false}], + ["script", "if (1 < 0) { console.log('elo there'); }"], + ["closetag", "SCRIPT"], + ["closetag", "HEAD"], + ["closetag", "HTML"] + ] +}); diff --git a/www/node_modules/sax/test/self-closing-child-strict.js b/www/node_modules/sax/test/self-closing-child-strict.js new file mode 100644 index 0000000..3d6e985 --- /dev/null +++ b/www/node_modules/sax/test/self-closing-child-strict.js @@ -0,0 +1,44 @@ + +require(__dirname).test({ + xml : + ""+ + "" + + "" + + "" + + "" + + "=(|)" + + "" + + "", + expect : [ + ["opentag", { + "name": "root", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "child", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "haha", + "attributes": {}, + "isSelfClosing": true + }], + ["closetag", "haha"], + ["closetag", "child"], + ["opentag", { + "name": "monkey", + "attributes": {}, + "isSelfClosing": false + }], + ["text", "=(|)"], + ["closetag", "monkey"], + ["closetag", "root"], + ["end"], + ["ready"] + ], + strict : true, + opt : {} +}); + diff --git a/www/node_modules/sax/test/self-closing-child.js b/www/node_modules/sax/test/self-closing-child.js new file mode 100644 index 0000000..f31c366 --- /dev/null +++ b/www/node_modules/sax/test/self-closing-child.js @@ -0,0 +1,44 @@ + +require(__dirname).test({ + xml : + ""+ + "" + + "" + + "" + + "" + + "=(|)" + + "" + + "", + expect : [ + ["opentag", { + "name": "ROOT", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "CHILD", + "attributes": {}, + "isSelfClosing": false + }], + ["opentag", { + "name": "HAHA", + "attributes": {}, + "isSelfClosing": true + }], + ["closetag", "HAHA"], + ["closetag", "CHILD"], + ["opentag", { + "name": "MONKEY", + "attributes": {}, + "isSelfClosing": false + }], + ["text", "=(|)"], + ["closetag", "MONKEY"], + ["closetag", "ROOT"], + ["end"], + ["ready"] + ], + strict : false, + opt : {} +}); + diff --git a/www/node_modules/sax/test/self-closing-tag.js b/www/node_modules/sax/test/self-closing-tag.js new file mode 100644 index 0000000..d1d8b7c --- /dev/null +++ b/www/node_modules/sax/test/self-closing-tag.js @@ -0,0 +1,25 @@ + +require(__dirname).test({ + xml : + " "+ + " "+ + " "+ + " "+ + "=(|) "+ + ""+ + " ", + expect : [ + ["opentag", {name:"ROOT", attributes:{}, isSelfClosing: false}], + ["opentag", {name:"HAHA", attributes:{}, isSelfClosing: true}], + ["closetag", "HAHA"], + ["opentag", {name:"HAHA", attributes:{}, isSelfClosing: true}], + ["closetag", "HAHA"], + // ["opentag", {name:"HAHA", attributes:{}}], + // ["closetag", "HAHA"], + ["opentag", {name:"MONKEY", attributes:{}, isSelfClosing: false}], + ["text", "=(|)"], + ["closetag", "MONKEY"], + ["closetag", "ROOT"] + ], + opt : { trim : true } +}); \ No newline at end of file diff --git a/www/node_modules/sax/test/stray-ending.js b/www/node_modules/sax/test/stray-ending.js new file mode 100644 index 0000000..bec467b --- /dev/null +++ b/www/node_modules/sax/test/stray-ending.js @@ -0,0 +1,17 @@ +// stray ending tags should just be ignored in non-strict mode. +// https://github.com/isaacs/sax-js/issues/32 +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "opentag", { name: "A", attributes: {}, isSelfClosing: false } ] + , [ "opentag", { name: "B", attributes: {}, isSelfClosing: false } ] + , [ "text", "" ] + , [ "closetag", "B" ] + , [ "closetag", "A" ] + ] + , strict : false + , opt : {} + } + ) + diff --git a/www/node_modules/sax/test/trailing-attribute-no-value.js b/www/node_modules/sax/test/trailing-attribute-no-value.js new file mode 100644 index 0000000..222837f --- /dev/null +++ b/www/node_modules/sax/test/trailing-attribute-no-value.js @@ -0,0 +1,10 @@ + +require(__dirname).test({ + xml : + "", + expect : [ + ["attribute", {name:"ATTRIB", value:"attrib"}], + ["opentag", {name:"ROOT", attributes:{"ATTRIB":"attrib"}, isSelfClosing: false}] + ], + opt : { trim : true } +}); diff --git a/www/node_modules/sax/test/trailing-non-whitespace.js b/www/node_modules/sax/test/trailing-non-whitespace.js new file mode 100644 index 0000000..619578b --- /dev/null +++ b/www/node_modules/sax/test/trailing-non-whitespace.js @@ -0,0 +1,18 @@ + +require(__dirname).test({ + xml : "Welcome, to monkey land", + expect : [ + ["opentag", { + "name": "SPAN", + "attributes": {}, + isSelfClosing: false + }], + ["text", "Welcome,"], + ["closetag", "SPAN"], + ["text", " to monkey land"], + ["end"], + ["ready"] + ], + strict : false, + opt : {} +}); diff --git a/www/node_modules/sax/test/unclosed-root.js b/www/node_modules/sax/test/unclosed-root.js new file mode 100644 index 0000000..f4eeac6 --- /dev/null +++ b/www/node_modules/sax/test/unclosed-root.js @@ -0,0 +1,11 @@ +require(__dirname).test + ( { xml : "" + + , expect : + [ [ "opentag", { name: "root", attributes: {}, isSelfClosing: false } ] + , [ "error", "Unclosed root tag\nLine: 0\nColumn: 6\nChar: " ] + ] + , strict : true + , opt : {} + } + ) diff --git a/www/node_modules/sax/test/unquoted.js b/www/node_modules/sax/test/unquoted.js new file mode 100644 index 0000000..b3a9a81 --- /dev/null +++ b/www/node_modules/sax/test/unquoted.js @@ -0,0 +1,18 @@ +// unquoted attributes should be ok in non-strict mode +// https://github.com/isaacs/sax-js/issues/31 +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "attribute", { name: "CLASS", value: "test" } ] + , [ "attribute", { name: "HELLO", value: "world" } ] + , [ "opentag", { name: "SPAN", + attributes: { CLASS: "test", HELLO: "world" }, + isSelfClosing: false } ] + , [ "closetag", "SPAN" ] + ] + , strict : false + , opt : {} + } + ) + diff --git a/www/node_modules/sax/test/utf8-split.js b/www/node_modules/sax/test/utf8-split.js new file mode 100644 index 0000000..e22bc10 --- /dev/null +++ b/www/node_modules/sax/test/utf8-split.js @@ -0,0 +1,32 @@ +var assert = require('assert') +var saxStream = require('../lib/sax').createStream() + +var b = new Buffer('误') + +saxStream.on('text', function(text) { + assert.equal(text, b.toString()) +}) + +saxStream.write(new Buffer('')) +saxStream.write(b.slice(0, 1)) +saxStream.write(b.slice(1)) +saxStream.write(new Buffer('')) +saxStream.write(b.slice(0, 2)) +saxStream.write(b.slice(2)) +saxStream.write(new Buffer('')) +saxStream.write(b) +saxStream.write(new Buffer('')) +saxStream.write(Buffer.concat([new Buffer(''), b.slice(0, 1)])) +saxStream.end(Buffer.concat([b.slice(1), new Buffer('')])) + +var saxStream2 = require('../lib/sax').createStream() + +saxStream2.on('text', function(text) { + assert.equal(text, '�') +}); + +saxStream2.write(new Buffer('')); +saxStream2.write(new Buffer([0xC0])); +saxStream2.write(new Buffer('')); +saxStream2.write(Buffer.concat([new Buffer(''), b.slice(0,1)])); +saxStream2.end(); diff --git a/www/node_modules/sax/test/xmlns-as-tag-name.js b/www/node_modules/sax/test/xmlns-as-tag-name.js new file mode 100644 index 0000000..99142ca --- /dev/null +++ b/www/node_modules/sax/test/xmlns-as-tag-name.js @@ -0,0 +1,15 @@ + +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "opentag", { name: "xmlns", uri: "", prefix: "", local: "xmlns", + attributes: {}, ns: {}, + isSelfClosing: true} + ], + ["closetag", "xmlns"] + ] + , strict : true + , opt : { xmlns: true } + } + ); diff --git a/www/node_modules/sax/test/xmlns-issue-41.js b/www/node_modules/sax/test/xmlns-issue-41.js new file mode 100644 index 0000000..17ab45a --- /dev/null +++ b/www/node_modules/sax/test/xmlns-issue-41.js @@ -0,0 +1,68 @@ +var t = require(__dirname) + + , xmls = // should be the same both ways. + [ "" + , "" ] + + , ex1 = + [ [ "opennamespace" + , { prefix: "a" + , uri: "http://ATTRIBUTE" + } + ] + , [ "attribute" + , { name: "xmlns:a" + , value: "http://ATTRIBUTE" + , prefix: "xmlns" + , local: "a" + , uri: "http://www.w3.org/2000/xmlns/" + } + ] + , [ "attribute" + , { name: "a:attr" + , local: "attr" + , prefix: "a" + , uri: "http://ATTRIBUTE" + , value: "value" + } + ] + , [ "opentag" + , { name: "parent" + , uri: "" + , prefix: "" + , local: "parent" + , attributes: + { "a:attr": + { name: "a:attr" + , local: "attr" + , prefix: "a" + , uri: "http://ATTRIBUTE" + , value: "value" + } + , "xmlns:a": + { name: "xmlns:a" + , local: "a" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "http://ATTRIBUTE" + } + } + , ns: {"a": "http://ATTRIBUTE"} + , isSelfClosing: true + } + ] + , ["closetag", "parent"] + , ["closenamespace", { prefix: "a", uri: "http://ATTRIBUTE" }] + ] + + // swap the order of elements 2 and 1 + , ex2 = [ex1[0], ex1[2], ex1[1]].concat(ex1.slice(3)) + , expected = [ex1, ex2] + +xmls.forEach(function (x, i) { + t.test({ xml: x + , expect: expected[i] + , strict: true + , opt: { xmlns: true } + }) +}) diff --git a/www/node_modules/sax/test/xmlns-rebinding.js b/www/node_modules/sax/test/xmlns-rebinding.js new file mode 100644 index 0000000..07e0425 --- /dev/null +++ b/www/node_modules/sax/test/xmlns-rebinding.js @@ -0,0 +1,63 @@ + +require(__dirname).test + ( { xml : + ""+ + ""+ + ""+ + ""+ + ""+ + "" + + , expect : + [ [ "opennamespace", { prefix: "x", uri: "x1" } ] + , [ "opennamespace", { prefix: "y", uri: "y1" } ] + , [ "attribute", { name: "xmlns:x", value: "x1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } ] + , [ "attribute", { name: "xmlns:y", value: "y1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "y" } ] + , [ "attribute", { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "root", uri: "", prefix: "", local: "root", + attributes: { "xmlns:x": { name: "xmlns:x", value: "x1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } + , "xmlns:y": { name: "xmlns:y", value: "y1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "y" } + , "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x1', y: 'y1' }, + isSelfClosing: false } ] + + , [ "opennamespace", { prefix: "x", uri: "x2" } ] + , [ "attribute", { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } ] + , [ "opentag", { name: "rebind", uri: "", prefix: "", local: "rebind", + attributes: { "xmlns:x": { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } }, + ns: { x: 'x2' }, + isSelfClosing: false } ] + + , [ "attribute", { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "check", uri: "", prefix: "", local: "check", + attributes: { "x:a": { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x2' }, + isSelfClosing: true } ] + + , [ "closetag", "check" ] + + , [ "closetag", "rebind" ] + , [ "closenamespace", { prefix: "x", uri: "x2" } ] + + , [ "attribute", { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } ] + , [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ] + , [ "opentag", { name: "check", uri: "", prefix: "", local: "check", + attributes: { "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } + , "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } }, + ns: { x: 'x1', y: 'y1' }, + isSelfClosing: true } ] + , [ "closetag", "check" ] + + , [ "closetag", "root" ] + , [ "closenamespace", { prefix: "x", uri: "x1" } ] + , [ "closenamespace", { prefix: "y", uri: "y1" } ] + ] + , strict : true + , opt : { xmlns: true } + } + ) + diff --git a/www/node_modules/sax/test/xmlns-strict.js b/www/node_modules/sax/test/xmlns-strict.js new file mode 100644 index 0000000..b5e3e51 --- /dev/null +++ b/www/node_modules/sax/test/xmlns-strict.js @@ -0,0 +1,74 @@ + +require(__dirname).test + ( { xml : + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + ""+ + "" + + , expect : + [ [ "opentag", { name: "root", prefix: "", local: "root", uri: "", + attributes: {}, ns: {}, isSelfClosing: false } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "", + attributes: { "attr": { name: "attr", value: "normal", uri: "", prefix: "", local: "attr", uri: "" } }, + ns: {}, isSelfClosing: true } ] + , [ "closetag", "plain" ] + + , [ "opennamespace", { prefix: "", uri: "uri:default" } ] + + , [ "attribute", { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } ] + , [ "opentag", { name: "ns1", prefix: "", local: "ns1", uri: "uri:default", + attributes: { "xmlns": { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } }, + ns: { "": "uri:default" }, isSelfClosing: false } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "uri:default", ns: { '': 'uri:default' }, + attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } }, + isSelfClosing: true } ] + , [ "closetag", "plain" ] + + , [ "closetag", "ns1" ] + + , [ "closenamespace", { prefix: "", uri: "uri:default" } ] + + , [ "opennamespace", { prefix: "a", uri: "uri:nsa" } ] + + , [ "attribute", { name: "xmlns:a", value: "uri:nsa", prefix: "xmlns", local: "a", uri: "http://www.w3.org/2000/xmlns/" } ] + + , [ "opentag", { name: "ns2", prefix: "", local: "ns2", uri: "", + attributes: { "xmlns:a": { name: "xmlns:a", value: "uri:nsa", prefix: "xmlns", local: "a", uri: "http://www.w3.org/2000/xmlns/" } }, + ns: { a: "uri:nsa" }, isSelfClosing: false } ] + + , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ] + , [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "", + attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } }, + ns: { a: 'uri:nsa' }, + isSelfClosing: true } ] + , [ "closetag", "plain" ] + + , [ "attribute", { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } ] + , [ "opentag", { name: "a:ns", prefix: "a", local: "ns", uri: "uri:nsa", + attributes: { "a:attr": { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } }, + ns: { a: 'uri:nsa' }, + isSelfClosing: true } ] + , [ "closetag", "a:ns" ] + + , [ "closetag", "ns2" ] + + , [ "closenamespace", { prefix: "a", uri: "uri:nsa" } ] + + , [ "closetag", "root" ] + ] + , strict : true + , opt : { xmlns: true } + } + ) + diff --git a/www/node_modules/sax/test/xmlns-unbound-element.js b/www/node_modules/sax/test/xmlns-unbound-element.js new file mode 100644 index 0000000..9d031a2 --- /dev/null +++ b/www/node_modules/sax/test/xmlns-unbound-element.js @@ -0,0 +1,33 @@ +require(__dirname).test( + { strict : true + , opt : { xmlns: true } + , expect : + [ [ "error", "Unbound namespace prefix: \"unbound:root\"\nLine: 0\nColumn: 15\nChar: >"] + , [ "opentag", { name: "unbound:root", uri: "unbound", prefix: "unbound", local: "root" + , attributes: {}, ns: {}, isSelfClosing: true } ] + , [ "closetag", "unbound:root" ] + ] + } +).write(""); + +require(__dirname).test( + { strict : true + , opt : { xmlns: true } + , expect : + [ [ "opennamespace", { prefix: "unbound", uri: "someuri" } ] + , [ "attribute", { name: 'xmlns:unbound', value: 'someuri' + , prefix: 'xmlns', local: 'unbound' + , uri: 'http://www.w3.org/2000/xmlns/' } ] + , [ "opentag", { name: "unbound:root", uri: "someuri", prefix: "unbound", local: "root" + , attributes: { 'xmlns:unbound': { + name: 'xmlns:unbound' + , value: 'someuri' + , prefix: 'xmlns' + , local: 'unbound' + , uri: 'http://www.w3.org/2000/xmlns/' } } + , ns: { "unbound": "someuri" }, isSelfClosing: true } ] + , [ "closetag", "unbound:root" ] + , [ "closenamespace", { prefix: 'unbound', uri: 'someuri' }] + ] + } +).write(""); diff --git a/www/node_modules/sax/test/xmlns-unbound.js b/www/node_modules/sax/test/xmlns-unbound.js new file mode 100644 index 0000000..b740e26 --- /dev/null +++ b/www/node_modules/sax/test/xmlns-unbound.js @@ -0,0 +1,15 @@ + +require(__dirname).test( + { strict : true + , opt : { xmlns: true } + , expect : + [ ["error", "Unbound namespace prefix: \"unbound\"\nLine: 0\nColumn: 28\nChar: >"] + + , [ "attribute", { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } ] + , [ "opentag", { name: "root", uri: "", prefix: "", local: "root", + attributes: { "unbound:attr": { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } }, + ns: {}, isSelfClosing: true } ] + , [ "closetag", "root" ] + ] + } +).write("") diff --git a/www/node_modules/sax/test/xmlns-xml-default-ns.js b/www/node_modules/sax/test/xmlns-xml-default-ns.js new file mode 100644 index 0000000..b1984d2 --- /dev/null +++ b/www/node_modules/sax/test/xmlns-xml-default-ns.js @@ -0,0 +1,31 @@ +var xmlns_attr = +{ + name: "xmlns", value: "http://foo", prefix: "xmlns", + local: "", uri : "http://www.w3.org/2000/xmlns/" +}; + +var attr_attr = +{ + name: "attr", value: "bar", prefix: "", + local : "attr", uri : "" +}; + + +require(__dirname).test + ( { xml : + "" + , expect : + [ [ "opennamespace", { prefix: "", uri: "http://foo" } ] + , [ "attribute", xmlns_attr ] + , [ "attribute", attr_attr ] + , [ "opentag", { name: "elm", prefix: "", local: "elm", uri : "http://foo", + ns : { "" : "http://foo" }, + attributes: { xmlns: xmlns_attr, attr: attr_attr }, + isSelfClosing: true } ] + , [ "closetag", "elm" ] + , [ "closenamespace", { prefix: "", uri: "http://foo"} ] + ] + , strict : true + , opt : {xmlns: true} + } + ) diff --git a/www/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js b/www/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js new file mode 100644 index 0000000..e41f218 --- /dev/null +++ b/www/node_modules/sax/test/xmlns-xml-default-prefix-attribute.js @@ -0,0 +1,36 @@ +require(__dirname).test( + { xml : "" + , expect : + [ [ "attribute" + , { name: "xml:lang" + , local: "lang" + , prefix: "xml" + , uri: "http://www.w3.org/XML/1998/namespace" + , value: "en" + } + ] + , [ "opentag" + , { name: "root" + , uri: "" + , prefix: "" + , local: "root" + , attributes: + { "xml:lang": + { name: "xml:lang" + , local: "lang" + , prefix: "xml" + , uri: "http://www.w3.org/XML/1998/namespace" + , value: "en" + } + } + , ns: {} + , isSelfClosing: true + } + ] + , ["closetag", "root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/www/node_modules/sax/test/xmlns-xml-default-prefix.js b/www/node_modules/sax/test/xmlns-xml-default-prefix.js new file mode 100644 index 0000000..a85b478 --- /dev/null +++ b/www/node_modules/sax/test/xmlns-xml-default-prefix.js @@ -0,0 +1,21 @@ +require(__dirname).test( + { xml : "" + , expect : + [ + [ "opentag" + , { name: "xml:root" + , uri: "http://www.w3.org/XML/1998/namespace" + , prefix: "xml" + , local: "root" + , attributes: {} + , ns: {} + , isSelfClosing: true + } + ] + , ["closetag", "xml:root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/www/node_modules/sax/test/xmlns-xml-default-redefine.js b/www/node_modules/sax/test/xmlns-xml-default-redefine.js new file mode 100644 index 0000000..d35d5a0 --- /dev/null +++ b/www/node_modules/sax/test/xmlns-xml-default-redefine.js @@ -0,0 +1,41 @@ +require(__dirname).test( + { xml : "" + , expect : + [ ["error" + , "xml: prefix must be bound to http://www.w3.org/XML/1998/namespace\n" + + "Actual: ERROR\n" + + "Line: 0\nColumn: 27\nChar: '" + ] + , [ "attribute" + , { name: "xmlns:xml" + , local: "xml" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "ERROR" + } + ] + , [ "opentag" + , { name: "xml:root" + , uri: "http://www.w3.org/XML/1998/namespace" + , prefix: "xml" + , local: "root" + , attributes: + { "xmlns:xml": + { name: "xmlns:xml" + , local: "xml" + , prefix: "xmlns" + , uri: "http://www.w3.org/2000/xmlns/" + , value: "ERROR" + } + } + , ns: {} + , isSelfClosing: true + } + ] + , ["closetag", "xml:root"] + ] + , strict : true + , opt : { xmlns: true } + } +) + diff --git a/www/node_modules/selenium-webdriver/.npmignore b/www/node_modules/selenium-webdriver/.npmignore new file mode 100644 index 0000000..d570088 --- /dev/null +++ b/www/node_modules/selenium-webdriver/.npmignore @@ -0,0 +1,2 @@ +node_modules/ + diff --git a/www/node_modules/selenium-webdriver/CHANGES.md b/www/node_modules/selenium-webdriver/CHANGES.md new file mode 100644 index 0000000..5d40b1b --- /dev/null +++ b/www/node_modules/selenium-webdriver/CHANGES.md @@ -0,0 +1,490 @@ +## v2.52.0 + +### Notice + +Starting with v2.52.0, each release of selenium-webdriver will support the +latest _minor_ LTS and stable Node releases. All releases between the LTS and +stable release will have best effort support. Further details are available in +the selenium-webdriver package README. + +### Change Summary + +* Add support for Microsoft's Edge web browser +* Added `webdriver.Builder#buildAsync()`, which returns a promise that will be + fulfilled with the newly created WebDriver instance once the associated + browser has been full initialized. This is purely a convenient alternative + to the existing build() method as the WebDriver class will always defer + commands until it has a fully created browser. +* Added `firefox.Profile#setHost()` which may be used to set the host that + the FirefoxDriver's server listens for commands on. The server uses + "localhost" by default. +* Added `promise.Promise#catch()` for API compatibility with native Promises. + `promise.Promise#thenCatch()` is not yet deprecated, but it simply + delegates to `catch`. +* Changed some `io` operations to use native promises. +* Changed `command.Executor#execute()` and `HttpClient#send()` to return + promises instead of using callback passing. +* Replaced the `Serializable` class with an internal, Symbol-defined method. +* Changed the `Capabilities` class to extend the native `Map` type. +* Changed the `Capabilities.has(key)` to only test if a capability has been set + (Map semantics). To check whether the value is true, use `get(key)`. +* Deprecated `executors.DeferredExecutor` in favor of + `lib/command.DeferredExecutor`. +* API documentation is no longer distributed with the npm package, but remains + available at +* Rewrote the `error` module to export an Error subtype for each type of error + defined in the [W3C WebDriver spec](https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors). +* Changed the `http.Request` and `http.Response` classes to store headers in + maps instead of object literals. +* Updated `ws` dependency to version `1.0.1`. +* Removed fluent predicates "is" and "not" from the experimental + `testing/assert` module. +* Wait conditions that locate an element, or that wait on an element's state, + will return a WebElementPromise. +* Lots of internal clean-up to break selenium-webdriver's long standing + dependency on Google's Closure library. + +### Changes for W3C WebDriver Spec Compliance + +* Updated the `By` locators that are not in the W3C spec to delegated to using + CSS selectors: `By.className`, `By.id`, `By.name`, and `By.tagName`. + + +## v2.49-51 + +* _Releases skipped to stay in sync with the rest of the Selenium project_ + + +## v2.48.2 + +* Added `WebElement#takeScreenshot()`. +* More adjustments to promise callback tracking. + +## v2.48.1 + +* FIXED: Adjusted how the control flow tracks promise callbacks to avoid a + potential deadlock. + +## v2.48.0 + +* Node v0.12.x users must run with --harmony. _This is the last release that + will support v0.12.x_ +* FIXED: (Promise/A+ compliance) When a promise is rejected with a thenable, + the promise adopts the thenable as its rejection reason instead of waiting + for it to settle. The previous (incorrect) behavior was hidden by bugs in + the `promises-aplus-tests` compliance test suite that were fixed in version + `2.1.1`. +* FIXED: the `webdriver.promise.ControlFlow` now has a consistent execution + order for tasks/callbacks scheduled in different turns of the JS event loop. + Refer to the `webdriver.promise` documentation for more details. +* FIXED: do not drop user auth from the WebDriver server URL. +* FIXED: a single `firefox.Binary` instance may be used to configure and + launch multiple FirefoxDriver sessions. + + var binary = new firefox.Binary(); + var options = new firefox.Options().setBinary(binary); + var builder = new Builder().setFirefoxOptions(options); + + var driver1 = builder.build(); + var driver2 = builder.build(); + +* FIXED: zip files created for transfer to a remote WebDriver server are no + longer compressed. If the zip contained a file that was already compressed, + the server would return an "invalid code lengths set" error. +* FIXED: Surfaced the `loopback` option to `remote/SeleniumServer`. When set, + the server will be accessed using the current host's loopback address. + +## v2.47.0 + +### Notice + +This is the last release for `selenium-webdriver` that will support ES5. +Subsequent releases will depend on ES6 features that are enabled by +[default](https://nodejs.org/en/docs/es6/) in Node v4.0.0. Node v0.12.x will +continue to be supported, but will require setting the `--harmony` flag. + +### Change Summary + +* Add support for [Node v4.0.0](https://nodejs.org/en/blog/release/v4.0.0/) + * Updated `ws` dependency from `0.7.1` to `0.8.0` +* Bumped the minimum supported version of Node from `0.10.x` to `0.12.x`. This + is in accordance with the Node support policy established in `v2.45.0`. + +## v2.46.1 + +* Fixed internal module loading on Windows. +* Fixed error message format on timeouts for `until.elementLocated()` + and `until.elementsLocated()`. + +## v2.46.0 + +* Exposed a new logging API via the `webdriver.logging` module. For usage, see + `example/logging.js`. +* Added support for using a proxy server for WebDriver commands. + See `Builder#usingWebDriverProxy()` for more info. +* Removed deprecated functions: + * Capabilities#toJSON() + * UnhandledAlertError#getAlert() + * chrome.createDriver() + * phantomjs.createDriver() + * promise.ControlFlow#annotateError() + * promise.ControlFlow#await() + * promise.ControlFlow#clearHistory() + * promise.ControlFlow#getHistory() +* Removed deprecated enum values: `ErrorCode.NO_MODAL_DIALOG_OPEN` and + `ErrorCode.MODAL_DIALOG_OPENED`. Use `ErrorCode.NO_SUCH_ALERT` and + `ErrorCode.UNEXPECTED_ALERT_OPEN`, respectively. +* FIXED: The `promise.ControlFlow` will maintain state for promise chains + generated in a loop. +* FIXED: Correct serialize target elements used in an action sequence. +* FIXED: `promise.ControlFlow#wait()` now has consistent semantics for an + omitted or 0-timeout: it will wait indefinitely. +* FIXED: `remote.DriverService#start()` will now fail if the child process dies + while waiting for the server to start accepting requests. Previously, start + would continue to poll the server address until the timeout expired. +* FIXED: Skip launching Firefox with the `-silent` flag to preheat the profile. + Starting with Firefox 38, this would cause the browser to crash. This step, + which was first introduced for Selenium's java client back with Firefox 2, + no longer appears to be required. +* FIXED: 8564: `firefox.Driver#quit()` will wait for the Firefox process to + terminate before deleting the temporary webdriver profile. This eliminates a + race condition where Firefox would write profile data during shutdown, + causing the `rm -rf` operation on the profile directory to fail. + +## v2.45.1 + +* FIXED: 8548: Task callbacks are once again dropped if the task was cancelled + due to a previously uncaught error within the frame. +* FIXED: 8496: Extended the `chrome.Options` API to cover all configuration + options (e.g. mobile emulation and performance logging) documented on the + ChromeDriver [project site](https://sites.google.com/a/chromium.org/chromedriver/capabilities). + +## v2.45.0 + +### Important Policy Change + +Starting with the 2.45.0 release, selenium-webdriver will support the last +two stable minor releases for Node. For 2.45.0, this means Selenium will +support Node 0.10.x and 0.12.x. Support for the intermediate, un-stable release +(0.11.x) is "best-effort". This policy will be re-evaluated once Node has a +major version release (i.e. 1.0.0). + +### Change Summary + +* Added native browser support for Internet Explorer, Opera 26+, and Safari +* With the release of [Node 0.12.0](http://blog.nodejs.org/2015/02/06/node-v0-12-0-stable/) + (finally!), the minimum supported version of Node is now `0.10.x`. +* The `promise` module is now [Promises/A+](https://promisesaplus.com/) + compliant. The biggest compliance change is that promise callbacks are now + invoked in a future turn of the JS event loop. For example: + + var promise = require('selenium-webdriver').promise; + console.log('start'); + promise.fulfilled().then(function() { + console.log('middle'); + }); + console.log('end'); + + // Output in selenium-webdriver@2.44.0 + // start + // middle + // end + // + // Output in selenium-webdriver@2.45.0 + // start + // end + // middle + + The `promise.ControlFlow` class has been updated to track the asynchronous + breaks required by Promises/A+, so there are no changes to task execution + order. +* Updated how errors are annotated on failures. When a task fails, the + stacktrace from when that task was scheduled is appended to the rejection + reason with a `From: ` prefix (if it is an Error object). For example: + + var driver = new webdriver.Builder().forBrowser('chrome').build(); + driver.get('http://www.google.com/ncr'); + driver.call(function() { + driver.wait(function() { + return driver.isElementPresent(webdriver.By.id('not-there')); + }, 2000, 'element not found'); + }); + + This code will fail an error like: + + Error: element not found + Wait timed out after 2002ms + at + From: Task: element not found + at + From: Task: WebDriver.call(function) + at + +* Changed the format of strings returned by `promise.ControlFlow#getSchedule`. + This function now accepts a boolean to control whether the returned string + should include the stacktraces for when each task was scheduled. +* Deprecating `promise.ControlFlow#getHistory`, + `promise.ControlFlow#clearHistory`, and `promise.ControlFlow#annotateError`. + These functions were all intended for internal use and are no longer + necessary, so they have been made no-ops. +* `WebDriver.wait()` may now be used to wait for a promise to resolve, with + an optional timeout. Refer to the API documentation for more information. +* Added support for copying files to a remote Selenium via `sendKeys` to test + file uploads. Refer to the API documentation for more information. Sample + usage included in `test/upload_test.js` +* Expanded the interactions API to include touch actions. + See `WebDriver.touchActions()`. +* FIXED: 8380: `firefox.Driver` will delete its temporary profile on `quit`. +* FIXED: 8306: Stack overflow in promise callbacks eliminated. +* FIXED: 8221: Added support for defining custom command mappings. Includes + support for PhantomJS's `executePhantomJS` (requires PhantomJS 1.9.7 or + GhostDriver 1.1.0). +* FIXED: 8128: When the FirefoxDriver marshals an object to the page for + `executeScript`, it defines additional properties (required by the driver's + implementation). These properties will no longer be enumerable and should + be omitted (i.e. they won't show up in JSON.stringify output). +* FIXED: 8094: The control flow will no longer deadlock when a task returns + a promise that depends on the completion of sub-tasks. + +## v2.44.0 + +* Added the `until` module, which defines common explicit wait conditions. + Sample usage: + + var firefox = require('selenium-webdriver/firefox'), + until = require('selenium-webdriver/until'); + + var driver = new firefox.Driver(); + driver.get('http://www.google.com/ncr'); + driver.wait(until.titleIs('Google Search'), 1000); + +* FIXED: 8000: `Builder.forBrowser()` now accepts an empty string since some + WebDriver implementations ignore the value. A value must still be specified, + however, since it is a required field in WebDriver's wire protocol. +* FIXED: 7994: The `stacktrace` module will not modify stack traces if the + initial parse fails (e.g. the user defined `Error.prepareStackTrace`) +* FIXED: 5855: Added a module (`until`) that defines several common conditions + for use with explicit waits. See updated examples for usage. + +## v2.43.5 + +* FIXED: 7905: `Builder.usingServer(url)` once again returns `this` for + chaining. + +## v2.43.2-4 + +* No changes; version bumps while attempting to work around an issue with + publishing to npm (a version string may only be used once). + +## v2.43.1 + +* Fixed an issue with flakiness when setting up the Firefox profile that could + prevent the driver from initializing properly. + +## v2.43.0 + +* Added native support for Firefox - the Java Selenium server is no longer + required. +* Added support for generator functions to `ControlFlow#execute` and + `ControlFlow#wait`. For more information, see documentation on + `webdriver.promise.consume`. Requires harmony support (run with + `node --harmony-generators` in `v0.11.x`). +* Various improvements to the `Builder` API. Notably, the `build()` function + will no longer default to attempting to use a server at + `http://localhost:4444/wd/hub` if it cannot start a browser directly - + you must specify the WebDriver server with `usingServer(url)`. You can + also set the target browser and WebDriver server through a pair of + environment variables. See the documentation on the `Builder` constructor + for more information. +* For consistency with the other language bindings, added browser specific + classes that can be used to start a browser without the builder. + + var webdriver = require('selenium-webdriver') + chrome = require('selenium-webdriver/chrome'); + + // The following are equivalent. + var driver1 = new webdriver.Builder().forBrowser('chrome').build(); + var driver2 = new chrome.Driver(); + +* Promise A+ compliance: a promise may no longer resolve to itself. +* For consistency with other language bindings, deprecated + `UnhandledAlertError#getAlert` and added `#getAlertText`. + `getAlert` will be removed in `2.45.0`. +* FIXED: 7641: Deprecated `ErrorCode.NO_MODAL_DIALOG_OPEN` and + `ErrorCode.MODAL_DIALOG_OPENED` in favor of the new + `ErrorCode.NO_SUCH_ALERT` and `ErrorCode.UNEXPECTED_ALERT_OPEN`, + respectively. +* FIXED: 7563: Mocha integration no longer disables timeouts. Default Mocha + timeouts apply (2000 ms) and may be changed using `this.timeout(ms)`. +* FIXED: 7470: Make it easier to create WebDriver instances in custom flows for + parallel execution. + +## v2.42.1 + +* FIXED: 7465: Fixed `net.getLoopbackAddress` on Windows +* FIXED: 7277: Support `done` callback in Mocha's BDD interface +* FIXED: 7156: `Promise#thenFinally` should not suppress original error + +## v2.42.0 + +* Removed deprecated functions `Promise#addCallback()`, + `Promise#addCallbacks()`, `Promise#addErrback()`, and `Promise#addBoth()`. +* Fail with a more descriptive error if the server returns a malformed redirect +* FIXED: 7300: Connect to ChromeDriver using the loopback address since + ChromeDriver 2.10.267517 binds to localhost by default. +* FIXED: 7339: Preserve wrapped test function's string representation for + Mocha's BDD interface. + +## v2.41.0 + +* FIXED: 7138: export logging API from webdriver module. +* FIXED: 7105: beforeEach/it/afterEach properly bind `this` for Mocha tests. + +## v2.40.0 + +* API documentation is now included in the docs directory. +* Added utility functions for working with an array of promises: + `promise.all`, `promise.map`, and `promise.filter` +* Introduced `Promise#thenCatch()` and `Promise#thenFinally()`. +* Deprecated `Promise#addCallback()`, `Promise#addCallbacks()`, + `Promise#addErrback()`, and `Promise#addBoth()`. +* Removed deprecated function `webdriver.WebDriver#getCapability`. +* FIXED: 6826: Added support for custom locators. + +## v2.39.0 + +* Version bump to stay in sync with the Selenium project. + +## v2.38.1 + +* FIXED: 6686: Changed `webdriver.promise.Deferred#cancel()` to silently no-op + if the deferred has already been resolved. + +## v2.38.0 + +* When a promise is rejected, always annotate the stacktrace with the parent + flow state so users can identify the source of an error. +* Updated tests to reflect features not working correctly in the SafariDriver + (cookie management and proxy support; see issues 5051, 5212, and 5503) +* FIXED: 6284: For mouse moves, correctly omit the x/y offsets if not + specified as a function argument (instead of passing (0,0)). +* FIXED: 6471: Updated documentation on `webdriver.WebElement#getAttribute` +* FIXED: 6612: On Unix, use the default IANA ephemeral port range if unable to + retrieve the current system's port range. +* FIXED: 6617: Avoid triggering the node debugger when initializing the + stacktrace module. +* FIXED: 6627: Safely rebuild chrome.Options from a partial JSON spec. + +## v2.37.0 + +* FIXED: 6346: The remote.SeleniumServer class now accepts JVM arguments using + the `jvmArgs` option. + +## v2.36.0 + +* _Release skipped to stay in sync with main Selenium project._ + +## v2.35.2 + +* FIXED: 6200: Pass arguments to the Selenium server instead of to the JVM. + +## v2.35.1 + +* FIXED: 6090: Changed example scripts to use chromedriver. + +## v2.35.0 + +* Version bump to stay in sync with the Selenium project. + +## v2.34.1 + +* FIXED: 6079: The parent process should not wait for spawn driver service + processes (chromedriver, phantomjs, etc.) + +## v2.34.0 + +* Added the `selenium-webdriver/testing/assert` module. This module + simplifies writing assertions against promised values (see + example in module documentation). +* Added the `webdriver.Capabilities` class. +* Added native support for the ChromeDriver. When using the `Builder`, + requesting chrome without specifying a remote server URL will default to + the native ChromeDriver implementation. The + [ChromeDriver server](https://code.google.com/p/chromedriver/downloads/list) + must be downloaded separately. + + // Will start ChromeDriver locally. + var driver = new webdriver.Builder(). + withCapabilities(webdriver.Capabilities.chrome()). + build(); + + // Will start ChromeDriver using the remote server. + var driver = new webdriver.Builder(). + withCapabilities(webdriver.Capabilities.chrome()). + usingServer('http://server:1234/wd/hub'). + build(); + +* Added support for configuring proxies through the builder. For examples, see + `selenium-webdriver/test/proxy_test`. +* Added native support for PhantomJS. +* Changed signature of `SeleniumServer` to `SeleniumServer(jar, options)`. +* Tests are now included in the npm published package. See `README.md` for + execution instructions +* Removed the deprecated `webdriver.Deferred#resolve` and + `webdriver.promise.resolved` functions. +* Removed the ability to connect to an existing session from the Builder. This + feature is intended for use with the browser-based client. + +## v2.33.0 + +* Added support for WebDriver's logging API +* FIXED: 5511: Added webdriver.manage().timeouts().pageLoadTimeout(ms) + +## v2.32.1 + +* FIXED: 5541: Added missing return statement for windows in + `portprober.findFreePort()` + +## v2.32.0 + +* Added the `selenium-webdriver/testing` package, which provides a basic + framework for writing tests using Mocha. See + `selenium-webdriver/example/google_search_test.js` for usage. +* For Promises/A+ compatibility, backing out the change in 2.30.0 that ensured + rejections were always Error objects. Rejection reasons are now left as is. +* Removed deprecated functions originally scheduled for removal in 2.31.0 + * promise.Application.getInstance() + * promise.ControlFlow#schedule() + * promise.ControlFlow#scheduleTimeout() + * promise.ControlFlow#scheduleWait() +* Renamed some functions for consistency with Promises/A+ terminology. The + original functions have been deprecated and will be removed in 2.34.0: + * promise.resolved() -> promise.fulfilled() + * promise.Deferred#resolve() -> promise.Deferred#fulfill() +* FIXED: remote.SeleniumServer#stop now shuts down within the active control + flow, allowing scripts to finish. Use #kill to shutdown immediately. +* FIXED: 5321: cookie deletion commands + +## v2.31.0 + +* Added an example script. +* Added a class for controlling the standalone Selenium server (server +available separately) +* Added a portprober for finding free ports +* FIXED: WebElements now belong to the same flow as their parent driver. + +## v2.30.0 + +* Ensures promise rejections are always Error values. +* Version bump to keep in sync with the Selenium project. + +## v2.29.1 + +* Fixed a bug that could lead to an infinite loop. +* Added a README.md + +## v2.29.0 + +* Initial release for npm: + + npm install selenium-webdriver diff --git a/www/node_modules/selenium-webdriver/LICENSE b/www/node_modules/selenium-webdriver/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/www/node_modules/selenium-webdriver/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/www/node_modules/selenium-webdriver/NOTICE b/www/node_modules/selenium-webdriver/NOTICE new file mode 100644 index 0000000..2744503 --- /dev/null +++ b/www/node_modules/selenium-webdriver/NOTICE @@ -0,0 +1,2 @@ +Copyright 2011-2016 Software Freedom Conservancy +Copyright 2004-2011 Selenium committers diff --git a/www/node_modules/selenium-webdriver/README.md b/www/node_modules/selenium-webdriver/README.md new file mode 100644 index 0000000..0b446ba --- /dev/null +++ b/www/node_modules/selenium-webdriver/README.md @@ -0,0 +1,226 @@ +# selenium-webdriver + +Selenium is a browser automation library. Most often used for testing +web-applications, Selenium may be used for any task that requires automating +interaction with the browser. + +## Installation + +Selenium may be installed via npm with + + npm install selenium-webdriver + +Out of the box, Selenium includes everything you need to work with Firefox. You +will need to download additional components to work with the other major +browsers. The drivers for Chrome, PhantomJS, Opera, and Microsoft's IE and Edge +web browsers are all standalone executables that should be available on your +[PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). The SafariDriver +browser extension should be installed in your browser before using Selenium; we +recommend disabling the extension when using the browser without Selenium or +installing the extension in a profile only used for testing. + +| Browser | Component | +| ----------------- | ---------------------------------- | +| Chrome | [chromedriver(.exe)][chrome] | +| Internet Explorer | [IEDriverServer.exe][release] | +| Edge | [MicrosoftWebDriver.msi][edge] | +| PhantomJS | [phantomjs(.exe)][phantomjs] | +| Opera | [operadriver(.exe)][opera] | +| Safari | [SafariDriver.safariextz][release] | + +## Usage + +The sample below and others are included in the `example` directory. You may +also find the tests for selenium-webdriver informative. + + var webdriver = require('selenium-webdriver'), + By = require('selenium-webdriver').By, + until = require('selenium-webdriver').until; + + var driver = new webdriver.Builder() + .forBrowser('firefox') + .build(); + + driver.get('http://www.google.com/ncr'); + driver.findElement(By.name('q')).sendKeys('webdriver'); + driver.findElement(By.name('btnG')).click(); + driver.wait(until.titleIs('webdriver - Google Search'), 1000); + driver.quit(); + +### Using the Builder API + +The `Builder` class is your one-stop shop for configuring new WebDriver +instances. Rather than clutter your code with branches for the various browsers, +the builder lets you set all options in one flow. When you call +`Builder#build()`, all options irrelevant to the selected browser are dropped: + + var webdriver = require('selenium-webdriver'), + chrome = require('selenium-webdriver/chrome'), + firefox = require('selenium-webdriver/firefox'); + + var driver = new webdriver.Builder() + .forBrowser('firefox') + .setChromeOptions(/* ... */) + .setFirefoxOptions(/* ... */) + .build(); + +Why would you want to configure options irrelevant to the target browser? The +`Builder`'s API defines your _default_ configuration. You can change the target +browser at runtime through the `SELENIUM_BROWSER` environment variable. For +example, the `example/google_search.js` script is configured to run against +Firefox. You can run the example against other browsers just by changing the +runtime environment + + # cd node_modules/selenium-webdriver + node example/google_search + SELENIUM_BROWSER=chrome node example/google_search + SELENIUM_BROWSER=safari node example/google_search + +### The Standalone Selenium Server + +The standalone Selenium Server acts as a proxy between your script and the +browser-specific drivers. The server may be used when running locally, but it's +not recommend as it introduces an extra hop for each request and will slow +things down. The server is required, however, to use a browser on a remote host +(most browser drivers, like the IEDriverServer, do not accept remote +connections). + +To use the Selenium Server, you will need to install the +[JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html) and +download the latest server from [Selenium][release]. Once downloaded, run the +server with + + java -jar selenium-server-standalone-2.45.0.jar + +You may configure your tests to run against a remote server through the Builder +API: + + var driver = new webdriver.Builder() + .forBrowser('firefox') + .usingServer('http://localhost:4444/wd/hub') + .build(); + +Or change the Builder's configuration at runtime with the `SELENIUM_REMOTE_URL` +environment variable: + + SELENIUM_REMOTE_URL="http://localhost:4444/wd/hub" node script.js + +You can experiment with these options using the `example/google_search.js` +script provided with `selenium-webdriver`. + +## Documentation + +API documentation is available online from the [Selenium project][api]. +Addition resources include + +- the #selenium channel on freenode IRC +- the [selenium-users@googlegroups.com][users] list +- [SeleniumHQ](http://www.seleniumhq.org/docs/) documentation + +## Contributing + +Contributions are accepted either through [GitHub][gh] pull requests or patches +via the [Selenium issue tracker][issues]. You must sign our +[Contributor License Agreement][cla] before your changes will be accepted. + +## Node Support Policy + +Each version of selenium-webdriver will support the latest _semver-minor_ +version of the [LTS] and stable Node releases. All _semver-major_ & +_semver-minor_ versions between the LTS and stable release will have "best +effort" support. Following a Selenium release, any _semver-minor_ Node releases +will also have "best effort" support. Releases older than the latest LTS, +_semver-major_ releases, and all unstable release branches (e.g. "v.Next") +are considered strictly unsupported. + +For example, suppose the current LTS and stable releases are v4.2.4 and v5.4.1, +respectively. Then a Selenium release would have the following support levels: + +| Version | Support | +| ------- | ------------- | +| <= 4.1 | _unsupported_ | +| 4.2 | supported | +| 5.0-3 | best effort | +| 5.4 | supported | +| >= 5.5 | best effort | +| v.Next | _unsupported_ | + +### Support Level Definitions + +- _supported:_ A selenium-webdriver release will be API compatible with the + platform API, without the use of runtime flags. + +- _best effort:_ Bugs will be investigated as time permits. API compatibility is + only guaranteed where required by a _supported_ release. This effectively + means the adoption of new JS features, such as ES2015 modules, will depend + on what is supported in Node's LTS. + +- _unsupported:_ Bug submissions will be closed as will-not-fix and API + compatibility is not guaranteed. + +### Projected Support Schedule + +If Node releases a new [LTS] each October and a new major version every 6 +months, the support window for selenium-webdriver will be roughly: + +| Date | LTS | Stable | +| --------- | ---: | -----: | +| (current) | 4.2 | 5.0 | +| 2016-04 | 4.2 | 6.0 | +| 2016-10 | 6.0 | 7.0 | +| 2017-04 | 6.0 | 8.0 | +| 2017-10 | 8.0 | 9.0 | + +## Issues + +Please report any issues using the [Selenium issue tracker][issues]. When using +the issue tracker + +- __Do__ include a detailed description of the problem. +- __Do__ include a link to a [gist](http://gist.github.com/) with any + interesting stack traces/logs (you may also attach these directly to the bug + report). +- __Do__ include a [reduced test case][reduction]. Reporting "unable to find + element on the page" is _not_ a valid report - there's nothing for us to + look into. Expect your bug report to be closed if you do not provide enough + information for us to investigate. +- __Do not__ use the issue tracker to submit basic help requests. All help + inquiries should be directed to the [user forum][users] or #selenium IRC + channel. +- __Do not__ post empty "I see this too" or "Any updates?" comments. These + provide no additional information and clutter the log. +- __Do not__ report regressions on closed bugs as they are not actively + monitored for upates (especially bugs that are >6 months old). Please open a + new issue and reference the original bug in your report. + +## License + +Licensed to the Software Freedom Conservancy (SFC) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The SFC licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. + +[LTS]: https://github.com/nodejs/LTS +[api]: http://seleniumhq.github.io/selenium/docs/api/javascript/ +[cla]: http://goo.gl/qC50R +[chrome]: http://chromedriver.storage.googleapis.com/index.html +[gh]: https://github.com/SeleniumHQ/selenium/ +[issues]: https://github.com/SeleniumHQ/selenium/issues +[opera]: https://github.com/operasoftware/operachromiumdriver/releases +[phantomjs]: http://phantomjs.org/ +[edge]: http://go.microsoft.com/fwlink/?LinkId=619687 +[reduction]: http://www.webkit.org/quality/reduction.html +[release]: http://selenium-release.storage.googleapis.com/index.html +[users]: https://groups.google.com/forum/#!forum/selenium-users diff --git a/www/node_modules/selenium-webdriver/builder.js b/www/node_modules/selenium-webdriver/builder.js new file mode 100644 index 0000000..64968e1 --- /dev/null +++ b/www/node_modules/selenium-webdriver/builder.js @@ -0,0 +1,513 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const chrome = require('./chrome'); +const edge = require('./edge'); +const executors = require('./executors'); +const firefox = require('./firefox'); +const ie = require('./ie'); +const capabilities = require('./lib/capabilities'); +const webdriver = require('./lib/webdriver'); +const promise = require('./lib/promise'); +const opera = require('./opera'); +const phantomjs = require('./phantomjs'); +const safari = require('./safari'); + +const Browser = capabilities.Browser; +const Capabilities = capabilities.Capabilities; +const Capability = capabilities.Capability; +const WebDriver = webdriver.WebDriver; + + + +var seleniumServer; + +/** + * Starts an instance of the Selenium server if not yet running. + * @param {string} jar Path to the server jar to use. + * @return {!promise.Promise} A promise for the server's + * addrss once started. + */ +function startSeleniumServer(jar) { + if (!seleniumServer) { + // Requiring 'chrome' above would create a cycle: + // index -> builder -> chrome -> index + var remote = require('./remote'); + seleniumServer = new remote.SeleniumServer(jar); + } + return seleniumServer.start(); +} + + +/** + * Creates new {@link webdriver.WebDriver WebDriver} instances. The environment + * variables listed below may be used to override a builder's configuration, + * allowing quick runtime changes. + * + * - {@code SELENIUM_BROWSER}: defines the target browser in the form + * {@code browser[:version][:platform]}. + * + * - {@code SELENIUM_REMOTE_URL}: defines the remote URL for all builder + * instances. This environment variable should be set to a fully qualified + * URL for a WebDriver server (e.g. http://localhost:4444/wd/hub). This + * option always takes precedence over {@code SELENIUM_SERVER_JAR}. + * + * - {@code SELENIUM_SERVER_JAR}: defines the path to the + * + * standalone Selenium server jar to use. The server will be started the + * first time a WebDriver instance and be killed when the process exits. + * + * Suppose you had mytest.js that created WebDriver with + * + * var driver = new webdriver.Builder() + * .forBrowser('chrome') + * .build(); + * + * This test could be made to use Firefox on the local machine by running with + * `SELENIUM_BROWSER=firefox node mytest.js`. Rather than change the code to + * target Google Chrome on a remote machine, you can simply set the + * `SELENIUM_BROWSER` and `SELENIUM_REMOTE_URL` environment variables: + * + * SELENIUM_BROWSER=chrome:36:LINUX \ + * SELENIUM_REMOTE_URL=http://www.example.com:4444/wd/hub \ + * node mytest.js + * + * You could also use a local copy of the standalone Selenium server: + * + * SELENIUM_BROWSER=chrome:36:LINUX \ + * SELENIUM_SERVER_JAR=/path/to/selenium-server-standalone.jar \ + * node mytest.js + */ +class Builder { + constructor() { + /** @private {promise.ControlFlow} */ + this.flow_ = null; + + /** @private {string} */ + this.url_ = ''; + + /** @private {?string} */ + this.proxy_ = null; + + /** @private {!Capabilities} */ + this.capabilities_ = new Capabilities(); + + /** @private {chrome.Options} */ + this.chromeOptions_ = null; + + /** @private {firefox.Options} */ + this.firefoxOptions_ = null; + + /** @private {opera.Options} */ + this.operaOptions_ = null; + + /** @private {ie.Options} */ + this.ieOptions_ = null; + + /** @private {safari.Options} */ + this.safariOptions_ = null; + + /** @private {edge.Options} */ + this.edgeOptions_ = null; + + /** @private {boolean} */ + this.ignoreEnv_ = false; + } + + /** + * Configures this builder to ignore any environment variable overrides and to + * only use the configuration specified through this instance's API. + * + * @return {!Builder} A self reference. + */ + disableEnvironmentOverrides() { + this.ignoreEnv_ = true; + return this; + } + + /** + * Sets the URL of a remote WebDriver server to use. Once a remote URL has + * been specified, the builder direct all new clients to that server. If this + * method is never called, the Builder will attempt to create all clients + * locally. + * + * As an alternative to this method, you may also set the + * `SELENIUM_REMOTE_URL` environment variable. + * + * @param {string} url The URL of a remote server to use. + * @return {!Builder} A self reference. + */ + usingServer(url) { + this.url_ = url; + return this; + } + + /** + * @return {string} The URL of the WebDriver server this instance is + * configured to use. + */ + getServerUrl() { + return this.url_; + } + + /** + * Sets the URL of the proxy to use for the WebDriver's HTTP connections. + * If this method is never called, the Builder will create a connection + * without a proxy. + * + * @param {string} proxy The URL of a proxy to use. + * @return {!Builder} A self reference. + */ + usingWebDriverProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * @return {?string} The URL of the proxy server to use for the WebDriver's + * HTTP connections, or `null` if not set. + */ + getWebDriverProxy() { + return this.proxy_; + } + + /** + * Sets the desired capabilities when requesting a new session. This will + * overwrite any previously set capabilities. + * @param {!(Object|Capabilities)} capabilities The desired capabilities for + * a new session. + * @return {!Builder} A self reference. + */ + withCapabilities(capabilities) { + this.capabilities_ = new Capabilities(capabilities); + return this; + } + + /** + * Returns the base set of capabilities this instance is currently configured + * to use. + * @return {!Capabilities} The current capabilities for this builder. + */ + getCapabilities() { + return this.capabilities_; + } + + /** + * Configures the target browser for clients created by this instance. + * Any calls to {@link #withCapabilities} after this function will + * overwrite these settings. + * + * You may also define the target browser using the {@code SELENIUM_BROWSER} + * environment variable. If set, this environment variable should be of the + * form `browser[:[version][:platform]]`. + * + * @param {(string|Browser)} name The name of the target browser; + * common defaults are available on the {@link webdriver.Browser} enum. + * @param {string=} opt_version A desired version; may be omitted if any + * version should be used. + * @param {string=} opt_platform The desired platform; may be omitted if any + * version may be used. + * @return {!Builder} A self reference. + */ + forBrowser(name, opt_version, opt_platform) { + this.capabilities_.set(Capability.BROWSER_NAME, name); + this.capabilities_.set(Capability.VERSION, opt_version || null); + this.capabilities_.set(Capability.PLATFORM, opt_platform || null); + return this; + } + + /** + * Sets the proxy configuration to use for WebDriver clients created by this + * builder. Any calls to {@link #withCapabilities} after this function will + * overwrite these settings. + * @param {!capabilities.ProxyConfig} config The configuration to use. + * @return {!Builder} A self reference. + */ + setProxy(config) { + this.capabilities_.setProxy(config); + return this; + } + + /** + * Sets the logging preferences for the created session. Preferences may be + * changed by repeated calls, or by calling {@link #withCapabilities}. + * @param {!(./lib/logging.Preferences|Object)} prefs The + * desired logging preferences. + * @return {!Builder} A self reference. + */ + setLoggingPrefs(prefs) { + this.capabilities_.setLoggingPrefs(prefs); + return this; + } + + /** + * Sets whether native events should be used. + * @param {boolean} enabled Whether to enable native events. + * @return {!Builder} A self reference. + */ + setEnableNativeEvents(enabled) { + this.capabilities_.setEnableNativeEvents(enabled); + return this; + } + + /** + * Sets how elements should be scrolled into view for interaction. + * @param {number} behavior The desired scroll behavior: either 0 to align + * with the top of the viewport or 1 to align with the bottom. + * @return {!Builder} A self reference. + */ + setScrollBehavior(behavior) { + this.capabilities_.setScrollBehavior(behavior); + return this; + } + + /** + * Sets the default action to take with an unexpected alert before returning + * an error. + * @param {string} behavior The desired behavior; should be "accept", + * "dismiss", or "ignore". Defaults to "dismiss". + * @return {!Builder} A self reference. + */ + setAlertBehavior(behavior) { + this.capabilities_.setAlertBehavior(behavior); + return this; + } + + /** + * Sets Chrome specific {@linkplain chrome.Options options} for drivers + * created by this builder. Any logging or proxy settings defined on the given + * options will take precedence over those set through + * {@link #setLoggingPrefs} and {@link #setProxy}, respectively. + * + * @param {!chrome.Options} options The ChromeDriver options to use. + * @return {!Builder} A self reference. + */ + setChromeOptions(options) { + this.chromeOptions_ = options; + return this; + } + + /** + * Sets Firefox specific {@linkplain firefox.Options options} for drivers + * created by this builder. Any logging or proxy settings defined on the given + * options will take precedence over those set through + * {@link #setLoggingPrefs} and {@link #setProxy}, respectively. + * + * @param {!firefox.Options} options The FirefoxDriver options to use. + * @return {!Builder} A self reference. + */ + setFirefoxOptions(options) { + this.firefoxOptions_ = options; + return this; + } + + /** + * Sets Opera specific {@linkplain opera.Options options} for drivers created + * by this builder. Any logging or proxy settings defined on the given options + * will take precedence over those set through {@link #setLoggingPrefs} and + * {@link #setProxy}, respectively. + * + * @param {!opera.Options} options The OperaDriver options to use. + * @return {!Builder} A self reference. + */ + setOperaOptions(options) { + this.operaOptions_ = options; + return this; + } + + /** + * Set Internet Explorer specific {@linkplain ie.Options options} for drivers + * created by this builder. Any proxy settings defined on the given options + * will take precedence over those set through {@link #setProxy}. + * + * @param {!ie.Options} options The IEDriver options to use. + * @return {!Builder} A self reference. + */ + setIeOptions(options) { + this.ieOptions_ = options; + return this; + } + + /** + * Set {@linkplain edge.Options options} specific to Microsoft's Edge browser + * for drivers created by this builder. Any proxy settings defined on the + * given options will take precedence over those set through + * {@link #setProxy}. + * + * @param {!edge.Options} options The MicrosoftEdgeDriver options to use. + * @return {!Builder} A self reference. + */ + setEdgeOptions(options) { + this.edgeOptions_ = options; + return this; + } + + /** + * Sets Safari specific {@linkplain safari.Options options} for drivers + * created by this builder. Any logging settings defined on the given options + * will take precedence over those set through {@link #setLoggingPrefs}. + * + * @param {!safari.Options} options The Safari options to use. + * @return {!Builder} A self reference. + */ + setSafariOptions(options) { + this.safariOptions_ = options; + return this; + } + + /** + * Sets the control flow that created drivers should execute actions in. If + * the flow is never set, or is set to {@code null}, it will use the active + * flow at the time {@link #build()} is called. + * @param {promise.ControlFlow} flow The control flow to use, or + * {@code null} to + * @return {!Builder} A self reference. + */ + setControlFlow(flow) { + this.flow_ = flow; + return this; + } + + /** + * Creates a new WebDriver client based on this builder's current + * configuration. + * + * While this method will immediately return a new WebDriver instance, any + * commands issued against it will be deferred until the associated browser + * has been fully initialized. Users may call {@link #buildAsync()} to obtain + * a promise that will not be fulfilled until the browser has been created + * (the difference is purely in style). + * + * @return {!webdriver.WebDriver} A new WebDriver instance. + * @throws {Error} If the current configuration is invalid. + * @see #buildAsync() + */ + build() { + // Create a copy for any changes we may need to make based on the current + // environment. + var capabilities = new Capabilities(this.capabilities_); + + var browser; + if (!this.ignoreEnv_ && process.env.SELENIUM_BROWSER) { + browser = process.env.SELENIUM_BROWSER.split(/:/, 3); + capabilities.set(Capability.BROWSER_NAME, browser[0]); + capabilities.set(Capability.VERSION, browser[1] || null); + capabilities.set(Capability.PLATFORM, browser[2] || null); + } + + browser = capabilities.get(Capability.BROWSER_NAME); + + if (typeof browser !== 'string') { + throw TypeError( + `Target browser must be a string, but is <${typeof browser}>;` + + ' did you forget to call forBrowser()?'); + } + + if (browser === 'ie') { + browser = Browser.INTERNET_EXPLORER; + } + + // Apply browser specific overrides. + if (browser === Browser.CHROME && this.chromeOptions_) { + capabilities.merge(this.chromeOptions_.toCapabilities()); + + } else if (browser === Browser.FIREFOX && this.firefoxOptions_) { + capabilities.merge(this.firefoxOptions_.toCapabilities()); + + } else if (browser === Browser.INTERNET_EXPLORER && this.ieOptions_) { + capabilities.merge(this.ieOptions_.toCapabilities()); + + } else if (browser === Browser.OPERA && this.operaOptions_) { + capabilities.merge(this.operaOptions_.toCapabilities()); + + } else if (browser === Browser.SAFARI && this.safariOptions_) { + capabilities.merge(this.safariOptions_.toCapabilities()); + + } else if (browser === Browser.EDGE && this.edgeOptions_) { + capabilities.merge(this.edgeOptions_.toCapabilities()); + } + + // Check for a remote browser. + var url = this.url_; + if (!this.ignoreEnv_) { + if (process.env.SELENIUM_REMOTE_URL) { + url = process.env.SELENIUM_REMOTE_URL; + } else if (process.env.SELENIUM_SERVER_JAR) { + url = startSeleniumServer(process.env.SELENIUM_SERVER_JAR); + } + } + + if (url) { + var executor = executors.createExecutor(url, this.proxy_); + return WebDriver.createSession(executor, capabilities, this.flow_); + } + + // Check for a native browser. + switch (browser) { + case Browser.CHROME: + return new chrome.Driver(capabilities, null, this.flow_); + + case Browser.FIREFOX: + return new firefox.Driver(capabilities, this.flow_); + + case Browser.INTERNET_EXPLORER: + return new ie.Driver(capabilities, this.flow_); + + case Browser.EDGE: + return new edge.Driver(capabilities, null, this.flow_); + + case Browser.OPERA: + return new opera.Driver(capabilities, null, this.flow_); + + case Browser.PHANTOM_JS: + return new phantomjs.Driver(capabilities, this.flow_); + + case Browser.SAFARI: + return new safari.Driver(capabilities, this.flow_); + + default: + throw new Error('Do not know how to build driver: ' + browser + + '; did you forget to call usingServer(url)?'); + } + } + + /** + * Creates a new WebDriver client based on this builder's current + * configuration. This method returns a promise that will not be fulfilled + * until the new browser session has been fully initialized. + * + * __Note:__ this method is purely a convenience wrapper around + * {@link #build()}. + * + * @return {!promise.Promise} A promise that will be + * fulfilled with the newly created WebDriver instance once the browser + * has been fully initialized. + * @see #build() + */ + buildAsync() { + let driver = this.build(); + return driver.getSession().then(() => driver); + } +} + + +// PUBLIC API + + +exports.Builder = Builder; diff --git a/www/node_modules/selenium-webdriver/chrome.js b/www/node_modules/selenium-webdriver/chrome.js new file mode 100644 index 0000000..2731d90 --- /dev/null +++ b/www/node_modules/selenium-webdriver/chrome.js @@ -0,0 +1,811 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a {@linkplain Driver WebDriver} client for the Chrome + * web browser. Before using this module, you must download the latest + * [ChromeDriver release] and ensure it can be found on your system [PATH]. + * + * There are three primary classes exported by this module: + * + * 1. {@linkplain ServiceBuilder}: configures the + * {@link selenium-webdriver/remote.DriverService remote.DriverService} + * that manages the [ChromeDriver] child process. + * + * 2. {@linkplain Options}: defines configuration options for each new Chrome + * session, such as which {@linkplain Options#setProxy proxy} to use, + * what {@linkplain Options#addExtensions extensions} to install, or + * what {@linkplain Options#addArguments command-line switches} to use when + * starting the browser. + * + * 3. {@linkplain Driver}: the WebDriver client; each new instance will control + * a unique browser session with a clean user profile (unless otherwise + * configured through the {@link Options} class). + * + * __Customizing the ChromeDriver Server__ + * + * By default, every Chrome session will use a single driver service, which is + * started the first time a {@link Driver} instance is created and terminated + * when this process exits. The default service will inherit its environment + * from the current process and direct all output to /dev/null. You may obtain + * a handle to this default service using + * {@link #getDefaultService getDefaultService()} and change its configuration + * with {@link #setDefaultService setDefaultService()}. + * + * You may also create a {@link Driver} with its own driver service. This is + * useful if you need to capture the server's log output for a specific session: + * + * let chrome = require('selenium-webdriver/chrome'); + * + * let service = new chrome.ServiceBuilder() + * .loggingTo('/my/log/file.txt') + * .enableVerboseLogging() + * .build(); + * + * let options = new chrome.Options(); + * // configure browser options ... + * + * let driver = new chrome.Driver(options, service); + * + * Users should only instantiate the {@link Driver} class directly when they + * need a custom driver service configuration (as shown above). For normal + * operation, users should start Chrome using the + * {@link selenium-webdriver.Builder}. + * + * __Working with Android__ + * + * The [ChromeDriver][android] supports running tests on the Chrome browser as + * well as [WebView apps][webview] starting in Android 4.4 (KitKat). In order to + * work with Android, you must first start the adb + * + * adb start-server + * + * By default, adb will start on port 5037. You may change this port, but this + * will require configuring a [custom server](#custom-server) that will connect + * to adb on the {@linkplain ServiceBuilder#setAdbPort correct port}: + * + * let service = new chrome.ServiceBuilder() + * .setAdbPort(1234) + * build(); + * // etc. + * + * The ChromeDriver may be configured to launch Chrome on Android using + * {@link Options#androidChrome()}: + * + * let driver = new Builder() + * .forBrowser('chrome') + * .setChromeOptions(new chrome.Options().androidChrome()) + * .build(); + * + * Alternatively, you can configure the ChromeDriver to launch an app with a + * Chrome-WebView by setting the {@linkplain Options#androidActivity + * androidActivity} option: + * + * let driver = new Builder() + * .forBrowser('chrome') + * .setChromeOptions(new chrome.Options() + * .androidPackage('com.example') + * .androidActivity('com.example.Activity')) + * .build(); + * + * [Refer to the ChromeDriver site] for more information on using the + * [ChromeDriver with Android][android]. + * + * [ChromeDriver]: https://sites.google.com/a/chromium.org/chromedriver/ + * [ChromeDriver release]: http://chromedriver.storage.googleapis.com/index.html + * [PATH]: http://en.wikipedia.org/wiki/PATH_%28variable%29 + * [android]: https://sites.google.com/a/chromium.org/chromedriver/getting-started/getting-started---android + * [webview]: https://developer.chrome.com/multidevice/webview/overview + */ + +'use strict'; + +const fs = require('fs'), + util = require('util'); + +const executors = require('./executors'), + http = require('./http'), + io = require('./io'), + Capabilities = require('./lib/capabilities').Capabilities, + Capability = require('./lib/capabilities').Capability, + command = require('./lib/command'), + logging = require('./lib/logging'), + promise = require('./lib/promise'), + Symbols = require('./lib/symbols'), + webdriver = require('./lib/webdriver'), + portprober = require('./net/portprober'), + remote = require('./remote'); + + +/** + * Name of the ChromeDriver executable. + * @type {string} + * @const + */ +const CHROMEDRIVER_EXE = + process.platform === 'win32' ? 'chromedriver.exe' : 'chromedriver'; + + +/** + * Custom command names supported by ChromeDriver. + * @enum {string} + */ +const Command = { + LAUNCH_APP: 'launchApp' +}; + + +/** + * Creates a command executor with support for ChromeDriver's custom commands. + * @param {!promise.Promise} url The server's URL. + * @return {!command.Executor} The new command executor. + */ +function createExecutor(url) { + return new executors.DeferredExecutor(url.then(function(url) { + let client = new http.HttpClient(url); + let executor = new http.Executor(client); + executor.defineCommand( + Command.LAUNCH_APP, + 'POST', '/session/:sessionId/chromium/launch_app'); + return executor; + })); +} + + +/** + * Creates {@link selenium-webdriver/remote.DriverService} instances that manage + * a [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/) + * server in a child process. + */ +class ServiceBuilder { + /** + * @param {string=} opt_exe Path to the server executable to use. If omitted, + * the builder will attempt to locate the chromedriver on the current + * PATH. + * @throws {Error} If provided executable does not exist, or the chromedriver + * cannot be found on the PATH. + */ + constructor(opt_exe) { + let exe = opt_exe || io.findInPath(CHROMEDRIVER_EXE, true); + if (!exe) { + throw Error( + 'The ChromeDriver could not be found on the current PATH. Please ' + + 'download the latest version of the ChromeDriver from ' + + 'http://chromedriver.storage.googleapis.com/index.html and ensure ' + + 'it can be found on your PATH.'); + } + + if (!fs.existsSync(exe)) { + throw Error('File does not exist: ' + exe); + } + /** @private {string} */ + this.exe_ = exe; + + /** @private {!Array} */ + this.args_ = []; + + /** + * @private {(string|!Array)} + */ + this.stdio_ = 'ignore'; + + /** @private {?string} */ + this.path_ = null; + + /** @private {number} */ + this.port_ = 0; + + /** @private {Object} */ + this.env_ = null; + } + + /** + * Sets the port to start the ChromeDriver on. + * @param {number} port The port to use, or 0 for any free port. + * @return {!ServiceBuilder} A self reference. + * @throws {Error} If the port is invalid. + */ + usingPort(port) { + if (port < 0) { + throw Error('port must be >= 0: ' + port); + } + this.port_ = port; + return this; + } + + /** + * Sets which port adb is listening to. _The ChromeDriver will connect to adb + * if an {@linkplain Options#androidPackage Android session} is requested, but + * adb **must** be started beforehand._ + * + * @param {number} port Which port adb is running on. + * @return {!ServiceBuilder} A self reference. + */ + setAdbPort(port) { + this.args_.push('--adb-port=' + port); + return this; + } + + /** + * Sets the path of the log file the driver should log to. If a log file is + * not specified, the driver will log to stderr. + * @param {string} path Path of the log file to use. + * @return {!ServiceBuilder} A self reference. + */ + loggingTo(path) { + this.args_.push('--log-path=' + path); + return this; + } + + /** + * Enables verbose logging. + * @return {!ServiceBuilder} A self reference. + */ + enableVerboseLogging() { + this.args_.push('--verbose'); + return this; + } + + /** + * Sets the number of threads the driver should use to manage HTTP requests. + * By default, the driver will use 4 threads. + * @param {number} n The number of threads to use. + * @return {!ServiceBuilder} A self reference. + */ + setNumHttpThreads(n) { + this.args_.push('--http-threads=' + n); + return this; + } + + /** + * Sets the base path for WebDriver REST commands (e.g. "/wd/hub"). + * By default, the driver will accept commands relative to "/". + * @param {string} path The base path to use. + * @return {!ServiceBuilder} A self reference. + */ + setUrlBasePath(path) { + this.args_.push('--url-base=' + path); + this.path_ = path; + return this; + } + + /** + * Defines the stdio configuration for the driver service. See + * {@code child_process.spawn} for more information. + * @param {(string|!Array)} + * config The configuration to use. + * @return {!ServiceBuilder} A self reference. + */ + setStdio(config) { + this.stdio_ = config; + return this; + } + + /** + * Defines the environment to start the server under. This settings will be + * inherited by every browser session started by the server. + * @param {!Object} env The environment to use. + * @return {!ServiceBuilder} A self reference. + */ + withEnvironment(env) { + this.env_ = env; + return this; + } + + /** + * Creates a new DriverService using this instance's current configuration. + * @return {!remote.DriverService} A new driver service using this instance's + * current configuration. + * @throws {Error} If the driver exectuable was not specified and a default + * could not be found on the current PATH. + */ + build() { + let port = this.port_ || portprober.findFreePort(); + let args = this.args_.concat(); // Defensive copy. + + return new remote.DriverService(this.exe_, { + loopback: true, + path: this.path_, + port: port, + args: promise.when(port, function(port) { + return args.concat('--port=' + port); + }), + env: this.env_, + stdio: this.stdio_ + }); + } +} + + + +/** @type {remote.DriverService} */ +let defaultService = null; + + +/** + * Sets the default service to use for new ChromeDriver instances. + * @param {!remote.DriverService} service The service to use. + * @throws {Error} If the default service is currently running. + */ +function setDefaultService(service) { + if (defaultService && defaultService.isRunning()) { + throw Error( + 'The previously configured ChromeDriver service is still running. ' + + 'You must shut it down before you may adjust its configuration.'); + } + defaultService = service; +} + + +/** + * Returns the default ChromeDriver service. If such a service has not been + * configured, one will be constructed using the default configuration for + * a ChromeDriver executable found on the system PATH. + * @return {!remote.DriverService} The default ChromeDriver service. + */ +function getDefaultService() { + if (!defaultService) { + defaultService = new ServiceBuilder().build(); + } + return defaultService; +} + + +/** + * @type {string} + * @const + */ +let OPTIONS_CAPABILITY_KEY = 'chromeOptions'; + + +/** + * Class for managing ChromeDriver specific options. + */ +class Options { + constructor() { + /** @private {!Object} */ + this.options_ = {}; + + /** @private {!Array<(string|!Buffer)>} */ + this.extensions_ = []; + + /** @private {?logging.Preferences} */ + this.logPrefs_ = null; + + /** @private {?./lib/capabilities.ProxyConfig} */ + this.proxy_ = null; + } + + /** + * Extracts the ChromeDriver specific options from the given capabilities + * object. + * @param {!Capabilities} caps The capabilities object. + * @return {!Options} The ChromeDriver options. + */ + static fromCapabilities(caps) { + let options = new Options(); + + let o = caps.get(OPTIONS_CAPABILITY_KEY); + if (o instanceof Options) { + options = o; + } else if (o) { + options. + addArguments(o.args || []). + addExtensions(o.extensions || []). + detachDriver(o.detach). + excludeSwitches(o.excludeSwitches || []). + setChromeBinaryPath(o.binary). + setChromeLogFile(o.logPath). + setChromeMinidumpPath(o.minidumpPath). + setLocalState(o.localState). + setMobileEmulation(o.mobileEmulation). + setUserPreferences(o.prefs). + setPerfLoggingPrefs(o.perfLoggingPrefs); + } + + if (caps.has(Capability.PROXY)) { + options.setProxy(caps.get(Capability.PROXY)); + } + + if (caps.has(Capability.LOGGING_PREFS)) { + options.setLoggingPrefs( + caps.get(Capability.LOGGING_PREFS)); + } + + return options; + } + + /** + * Add additional command line arguments to use when launching the Chrome + * browser. Each argument may be specified with or without the "--" prefix + * (e.g. "--foo" and "foo"). Arguments with an associated value should be + * delimited by an "=": "foo=bar". + * @param {...(string|!Array)} var_args The arguments to add. + * @return {!Options} A self reference. + */ + addArguments(var_args) { + let args = this.options_.args || []; + args = args.concat.apply(args, arguments); + if (args.length) { + this.options_.args = args; + } + return this; + } + + /** + * List of Chrome command line switches to exclude that ChromeDriver by default + * passes when starting Chrome. Do not prefix switches with "--". + * + * @param {...(string|!Array)} var_args The switches to exclude. + * @return {!Options} A self reference. + */ + excludeSwitches(var_args) { + let switches = this.options_.excludeSwitches || []; + switches = switches.concat.apply(switches, arguments); + if (switches.length) { + this.options_.excludeSwitches = switches; + } + return this; + } + + /** + * Add additional extensions to install when launching Chrome. Each extension + * should be specified as the path to the packed CRX file, or a Buffer for an + * extension. + * @param {...(string|!Buffer|!Array<(string|!Buffer)>)} var_args The + * extensions to add. + * @return {!Options} A self reference. + */ + addExtensions(var_args) { + this.extensions_ = + this.extensions_.concat.apply(this.extensions_, arguments); + return this; + } + + /** + * Sets the path to the Chrome binary to use. On Mac OS X, this path should + * reference the actual Chrome executable, not just the application binary + * (e.g. "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"). + * + * The binary path be absolute or relative to the chromedriver server + * executable, but it must exist on the machine that will launch Chrome. + * + * @param {string} path The path to the Chrome binary to use. + * @return {!Options} A self reference. + */ + setChromeBinaryPath(path) { + this.options_.binary = path; + return this; + } + + /** + * Sets whether to leave the started Chrome browser running if the controlling + * ChromeDriver service is killed before {@link webdriver.WebDriver#quit()} is + * called. + * @param {boolean} detach Whether to leave the browser running if the + * chromedriver service is killed before the session. + * @return {!Options} A self reference. + */ + detachDriver(detach) { + this.options_.detach = detach; + return this; + } + + /** + * Sets the user preferences for Chrome's user profile. See the "Preferences" + * file in Chrome's user data directory for examples. + * @param {!Object} prefs Dictionary of user preferences to use. + * @return {!Options} A self reference. + */ + setUserPreferences(prefs) { + this.options_.prefs = prefs; + return this; + } + + /** + * Sets the logging preferences for the new session. + * @param {!logging.Preferences} prefs The logging preferences. + * @return {!Options} A self reference. + */ + setLoggingPrefs(prefs) { + this.logPrefs_ = prefs; + return this; + } + + /** + * Sets the performance logging preferences. Options include: + * + * - `enableNetwork`: Whether or not to collect events from Network domain. + * - `enablePage`: Whether or not to collect events from Page domain. + * - `enableTimeline`: Whether or not to collect events from Timeline domain. + * Note: when tracing is enabled, Timeline domain is implicitly disabled, + * unless `enableTimeline` is explicitly set to true. + * - `tracingCategories`: A comma-separated string of Chrome tracing + * categories for which trace events should be collected. An unspecified + * or empty string disables tracing. + * - `bufferUsageReportingInterval`: The requested number of milliseconds + * between DevTools trace buffer usage events. For example, if 1000, then + * once per second, DevTools will report how full the trace buffer is. If + * a report indicates the buffer usage is 100%, a warning will be issued. + * + * @param {{enableNetwork: boolean, + * enablePage: boolean, + * enableTimeline: boolean, + * tracingCategories: string, + * bufferUsageReportingInterval: number}} prefs The performance + * logging preferences. + * @return {!Options} A self reference. + */ + setPerfLoggingPrefs(prefs) { + this.options_.perfLoggingPrefs = prefs; + return this; + } + + /** + * Sets preferences for the "Local State" file in Chrome's user data + * directory. + * @param {!Object} state Dictionary of local state preferences. + * @return {!Options} A self reference. + */ + setLocalState(state) { + this.options_.localState = state; + return this; + } + + /** + * Sets the name of the activity hosting a Chrome-based Android WebView. This + * option must be set to connect to an [Android WebView]( + * https://sites.google.com/a/chromium.org/chromedriver/getting-started/getting-started---android) + * + * @param {string} name The activity name. + * @return {!Options} A self reference. + */ + androidActivity(name) { + this.options_.androidActivity = name; + return this; + } + + /** + * Sets the device serial number to connect to via ADB. If not specified, the + * ChromeDriver will select an unused device at random. An error will be + * returned if all devices already have active sessions. + * + * @param {string} serial The device serial number to connect to. + * @return {!Options} A self reference. + */ + androidDeviceSerial(serial) { + this.options_.androidDeviceSerial = serial; + return this; + } + + /** + * Configures the ChromeDriver to launch Chrome on Android via adb. This + * function is shorthand for + * {@link #androidPackage options.androidPackage('com.android.chrome')}. + * @return {!Options} A self reference. + */ + androidChrome() { + return this.androidPackage('com.android.chrome'); + } + + /** + * Sets the package name of the Chrome or WebView app. + * + * @param {?string} pkg The package to connect to, or `null` to disable Android + * and switch back to using desktop Chrome. + * @return {!Options} A self reference. + */ + androidPackage(pkg) { + this.options_.androidPackage = pkg; + return this; + } + + /** + * Sets the process name of the Activity hosting the WebView (as given by + * `ps`). If not specified, the process name is assumed to be the same as + * {@link #androidPackage}. + * + * @param {string} processName The main activity name. + * @return {!Options} A self reference. + */ + androidProcess(processName) { + this.options_.androidProcess = processName; + return this; + } + + /** + * Sets whether to connect to an already-running instead of the specified + * {@linkplain #androidProcess app} instead of launching the app with a clean + * data directory. + * + * @param {boolean} useRunning Whether to connect to a running instance. + * @return {!Options} A self reference. + */ + androidUseRunningApp(useRunning) { + this.options_.androidUseRunningApp = useRunning; + return this; + } + + /** + * Sets the path to Chrome's log file. This path should exist on the machine + * that will launch Chrome. + * @param {string} path Path to the log file to use. + * @return {!Options} A self reference. + */ + setChromeLogFile(path) { + this.options_.logPath = path; + return this; + } + + /** + * Sets the directory to store Chrome minidumps in. This option is only + * supported when ChromeDriver is running on Linux. + * @param {string} path The directory path. + * @return {!Options} A self reference. + */ + setChromeMinidumpPath(path) { + this.options_.minidumpPath = path; + return this; + } + + /** + * Configures Chrome to emulate a mobile device. For more information, refer + * to the ChromeDriver project page on [mobile emulation][em]. Configuration + * options include: + * + * - `deviceName`: The name of a pre-configured [emulated device][devem] + * - `width`: screen width, in pixels + * - `height`: screen height, in pixels + * - `pixelRatio`: screen pixel ratio + * + * __Example 1: Using a Pre-configured Device__ + * + * let options = new chrome.Options().setMobileEmulation( + * {deviceName: 'Google Nexus 5'}); + * + * let driver = new chrome.Driver(options); + * + * __Example 2: Using Custom Screen Configuration__ + * + * let options = new chrome.Options().setMobileEmulation({ + * width: 360, + * height: 640, + * pixelRatio: 3.0 + * }); + * + * let driver = new chrome.Driver(options); + * + * + * [em]: https://sites.google.com/a/chromium.org/chromedriver/mobile-emulation + * [devem]: https://developer.chrome.com/devtools/docs/device-mode + * + * @param {?({deviceName: string}| + * {width: number, height: number, pixelRatio: number})} config The + * mobile emulation configuration, or `null` to disable emulation. + * @return {!Options} A self reference. + */ + setMobileEmulation(config) { + this.options_.mobileEmulation = config; + return this; + } + + /** + * Sets the proxy settings for the new session. + * @param {./lib/capabilities.ProxyConfig} proxy The proxy configuration to + * use. + * @return {!Options} A self reference. + */ + setProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * Converts this options instance to a {@link Capabilities} object. + * @param {Capabilities=} opt_capabilities The capabilities to merge + * these options into, if any. + * @return {!Capabilities} The capabilities. + */ + toCapabilities(opt_capabilities) { + let caps = opt_capabilities || Capabilities.chrome(); + caps. + set(Capability.PROXY, this.proxy_). + set(Capability.LOGGING_PREFS, this.logPrefs_). + set(OPTIONS_CAPABILITY_KEY, this); + return caps; + } + + /** + * Converts this instance to its JSON wire protocol representation. Note this + * function is an implementation not intended for general use. + * @return {!Object} The JSON wire protocol representation of this instance. + */ + [Symbols.serialize]() { + let json = {}; + for (let key in this.options_) { + if (this.options_[key] != null) { + json[key] = this.options_[key]; + } + } + if (this.extensions_.length) { + json.extensions = this.extensions_.map(function(extension) { + if (Buffer.isBuffer(extension)) { + return extension.toString('base64'); + } + return promise.checkedNodeCall( + fs.readFile, extension, 'base64'); + }); + } + return json; + } +} + + +/** + * Creates a new WebDriver client for Chrome. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(Capabilities|Options)=} opt_config The configuration + * options. + * @param {remote.DriverService=} opt_service The session to use; will use + * the {@linkplain #getDefaultService default service} by default. + * @param {promise.ControlFlow=} opt_flow The control flow to use, + * or {@code null} to use the currently active flow. + */ + constructor(opt_config, opt_service, opt_flow) { + let service = opt_service || getDefaultService(); + let executor = createExecutor(service.start()); + + let caps = + opt_config instanceof Options ? opt_config.toCapabilities() : + (opt_config || Capabilities.chrome()); + + let driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + + super(driver.getSession(), executor, driver.controlFlow()); + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() {} + + /** + * Schedules a command to launch Chrome App with given ID. + * @param {string} id ID of the App to launch. + * @return {!promise.Promise} A promise that will be resolved + * when app is launched. + */ + launchApp(id) { + return this.schedule( + new command.Command(Command.LAUNCH_APP).setParameter('id', id), + 'Driver.launchApp()'); + } +} + + +// PUBLIC API + + +exports.Driver = Driver; +exports.Options = Options; +exports.ServiceBuilder = ServiceBuilder; +exports.getDefaultService = getDefaultService; +exports.setDefaultService = setDefaultService; diff --git a/www/node_modules/selenium-webdriver/edge.js b/www/node_modules/selenium-webdriver/edge.js new file mode 100644 index 0000000..676637a --- /dev/null +++ b/www/node_modules/selenium-webdriver/edge.js @@ -0,0 +1,378 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a {@linkplain Driver WebDriver} client for + * Microsoft's Edge web browser. Before using this module, + * you must download and install the latest + * [MicrosoftEdgeDriver](http://go.microsoft.com/fwlink/?LinkId=619687) server. + * Ensure that the MicrosoftEdgeDriver is on your + * [PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). + * + * There are three primary classes exported by this module: + * + * 1. {@linkplain ServiceBuilder}: configures the + * {@link ./remote.DriverService remote.DriverService} + * that manages the [MicrosoftEdgeDriver] child process. + * + * 2. {@linkplain Options}: defines configuration options for each new + * MicrosoftEdgeDriver session, such as which + * {@linkplain Options#setProxy proxy} to use when starting the browser. + * + * 3. {@linkplain Driver}: the WebDriver client; each new instance will control + * a unique browser session. + * + * __Customizing the MicrosoftEdgeDriver Server__ + * + * By default, every MicrosoftEdge session will use a single driver service, + * which is started the first time a {@link Driver} instance is created and + * terminated when this process exits. The default service will inherit its + * environment from the current process. + * You may obtain a handle to this default service using + * {@link #getDefaultService getDefaultService()} and change its configuration + * with {@link #setDefaultService setDefaultService()}. + * + * You may also create a {@link Driver} with its own driver service. This is + * useful if you need to capture the server's log output for a specific session: + * + * var edge = require('selenium-webdriver/edge'); + * + * var service = new edge.ServiceBuilder() + * .usingPort(55555) + * .build(); + * + * var options = new edge.Options(); + * // configure browser options ... + * + * var driver = new edge.Driver(options, service); + * + * Users should only instantiate the {@link Driver} class directly when they + * need a custom driver service configuration (as shown above). For normal + * operation, users should start MicrosoftEdge using the + * {@link ./builder.Builder selenium-webdriver.Builder}. + * + * [MicrosoftEdgeDriver]: https://msdn.microsoft.com/en-us/library/mt188085(v=vs.85).aspx + */ + +'use strict'; + +const fs = require('fs'), + util = require('util'); + +const executors = require('./executors'), + io = require('./io'), + capabilities = require('./lib/capabilities'), + promise = require('./lib/promise'), + Symbols = require('./lib/symbols'), + webdriver = require('./lib/webdriver'), + portprober = require('./net/portprober'), + remote = require('./remote'); + +const EDGEDRIVER_EXE = 'MicrosoftWebDriver.exe'; + + +/** + * Option keys. + * @enum {string} + */ +const CAPABILITY_KEY = { + PAGE_LOAD_STRATEGY: 'pageLoadStrategy' +}; + + +/** + * Class for managing MicrosoftEdgeDriver specific options. + */ +class Options { + constructor() { + /** @private {!Object} */ + this.options_ = {}; + + /** @private {?capabilities.ProxyConfig} */ + this.proxy_ = null; + } + + /** + * Extracts the MicrosoftEdgeDriver specific options from the given + * capabilities object. + * @param {!capabilities.Capabilities} caps The capabilities object. + * @return {!Options} The MicrosoftEdgeDriver options. + */ + static fromCapabilities(caps) { + var options = new Options(); + var map = options.options_; + + Object.keys(CAPABILITY_KEY).forEach(function(key) { + key = CAPABILITY_KEY[key]; + if (caps.has(key)) { + map[key] = caps.get(key); + } + }); + + if (caps.has(capabilities.Capability.PROXY)) { + options.setProxy(caps.get(capabilities.Capability.PROXY)); + } + + return options; + } + + /** + * Sets the proxy settings for the new session. + * @param {capabilities.ProxyConfig} proxy The proxy configuration to use. + * @return {!Options} A self reference. + */ + setProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * Sets the page load strategy for Edge. + * Supported values are "normal", "eager", and "none"; + * + * @param {string} pageLoadStrategy The page load strategy to use. + * @return {!Options} A self reference. + */ + setPageLoadStrategy(pageLoadStrategy) { + this.options_[CAPABILITY_KEY.PAGE_LOAD_STRATEGY] = + pageLoadStrategy.toLowerCase(); + return this; + } + + /** + * Converts this options instance to a {@link capabilities.Capabilities} + * object. + * @param {capabilities.Capabilities=} opt_capabilities The capabilities to + * merge these options into, if any. + * @return {!capabilities.Capabilities} The capabilities. + */ + toCapabilities(opt_capabilities) { + var caps = opt_capabilities || capabilities.Capabilities.edge(); + if (this.proxy_) { + caps.set(capabilities.Capability.PROXY, this.proxy_); + } + Object.keys(this.options_).forEach(function(key) { + caps.set(key, this.options_[key]); + }, this); + return caps; + } + + /** + * Converts this instance to its JSON wire protocol representation. Note this + * function is an implementation not intended for general use. + * @return {{pageLoadStrategy: (string|undefined)}} + * The JSON wire protocol representation of this instance. + */ + [Symbols.serialize]() { + var json = {}; + for (var key in this.options_) { + if (this.options_[key] != null) { + json[key] = this.options_[key]; + } + } + return json; + } +} + + +/** + * Creates {@link remote.DriverService} instances that manage a + * MicrosoftEdgeDriver server in a child process. + */ +class ServiceBuilder { + /** + * @param {string=} opt_exe Path to the server executable to use. If omitted, + * the builder will attempt to locate the MicrosoftEdgeDriver on the current + * PATH. + * @throws {Error} If provided executable does not exist, or the + * MicrosoftEdgeDriver cannot be found on the PATH. + */ + constructor(opt_exe) { + let exe = opt_exe || io.findInPath(EDGEDRIVER_EXE, true); + if (!exe) { + throw Error( + 'The ' + EDGEDRIVER_EXE + ' could not be found on the current PATH. ' + + 'Please download the latest version of the MicrosoftEdgeDriver from ' + + 'https://www.microsoft.com/en-us/download/details.aspx?id=48212 and ' + + 'ensure it can be found on your PATH.'); + } else if (!fs.existsSync(exe)) { + throw Error('File does not exist: ' + exe); + } + + /** @private {string} */ + this.exe_ = /** @type {string} */(exe); + + /** @private {!Array.} */ + this.args_ = []; + + /** @private {number} */ + this.port_ = 0; + + /** + * @private {(string|!Array.)} + */ + this.stdio_ = 'ignore'; + + /** @private {Object.} */ + this.env_ = null; + } + + /** + * Defines the stdio configuration for the driver service. See + * {@code child_process.spawn} for more information. + * @param {(string|!Array.)} + * config The configuration to use. + * @return {!ServiceBuilder} A self reference. + */ + setStdio(config) { + this.stdio_ = config; + return this; + } + + /** + * Sets the port to start the MicrosoftEdgeDriver on. + * @param {number} port The port to use, or 0 for any free port. + * @return {!ServiceBuilder} A self reference. + * @throws {Error} If the port is invalid. + */ + usingPort(port) { + if (port < 0) { + throw Error('port must be >= 0: ' + port); + } + this.port_ = port; + return this; + } + + /** + * Defines the environment to start the server under. This settings will be + * inherited by every browser session started by the server. + * @param {!Object.} env The environment to use. + * @return {!ServiceBuilder} A self reference. + */ + withEnvironment(env) { + this.env_ = env; + return this; + } + + /** + * Creates a new DriverService using this instance's current configuration. + * @return {!remote.DriverService} A new driver service using this instance's + * current configuration. + * @throws {Error} If the driver exectuable was not specified and a default + * could not be found on the current PATH. + */ + build() { + var port = this.port_ || portprober.findFreePort(); + var args = this.args_.concat(); // Defensive copy. + + return new remote.DriverService(this.exe_, { + // Binding to the loopback address will fail if not running with + // administrator privileges. Since we cannot test for that in script + // (or can we?), force the DriverService to use "localhost". + hostname: 'localhost', + port: port, + args: promise.fulfilled(port).then(function(port) { + return args.concat('--port=' + port); + }), + env: this.env_, + stdio: this.stdio_ + }); + } +} + + +/** @type {remote.DriverService} */ +var defaultService = null; + + +/** + * Sets the default service to use for new MicrosoftEdgeDriver instances. + * @param {!remote.DriverService} service The service to use. + * @throws {Error} If the default service is currently running. + */ +function setDefaultService(service) { + if (defaultService && defaultService.isRunning()) { + throw Error( + 'The previously configured EdgeDriver service is still running. ' + + 'You must shut it down before you may adjust its configuration.'); + } + defaultService = service; +} + + +/** + * Returns the default MicrosoftEdgeDriver service. If such a service has + * not been configured, one will be constructed using the default configuration + * for an MicrosoftEdgeDriver executable found on the system PATH. + * @return {!remote.DriverService} The default MicrosoftEdgeDriver service. + */ +function getDefaultService() { + if (!defaultService) { + defaultService = new ServiceBuilder().build(); + } + return defaultService; +} + + +/** + * Creates a new WebDriver client for Microsoft's Edge. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(capabilities.Capabilities|Options)=} opt_config The configuration + * options. + * @param {remote.DriverService=} opt_service The session to use; will use + * the {@linkplain #getDefaultService default service} by default. + * @param {promise.ControlFlow=} opt_flow The control flow to use, or + * {@code null} to use the currently active flow. + */ + constructor(opt_config, opt_service, opt_flow) { + var service = opt_service || getDefaultService(); + var executor = executors.createExecutor(service.start()); + + var caps = + opt_config instanceof Options ? opt_config.toCapabilities() : + (opt_config || capabilities.Capabilities.edge()); + + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + super(driver.getSession(), executor, driver.controlFlow()); + + var boundQuit = this.quit.bind(this); + + /** @override */ + this.quit = function() { + return boundQuit().thenFinally(service.kill.bind(service)); + }; + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() {} +} + + +// PUBLIC API + + +exports.Driver = Driver; +exports.Options = Options; +exports.ServiceBuilder = ServiceBuilder; +exports.getDefaultService = getDefaultService; +exports.setDefaultService = setDefaultService; diff --git a/www/node_modules/selenium-webdriver/error.js b/www/node_modules/selenium-webdriver/error.js new file mode 100644 index 0000000..32af633 --- /dev/null +++ b/www/node_modules/selenium-webdriver/error.js @@ -0,0 +1,619 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * The base WebDriver error type. This error type is only used directly when a + * more appropriate category is not defined for the offending error. + */ +class WebDriverError extends Error { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + + /** @override */ + this.name = this.constructor.name; + } + + /** + * @return {number} the legacy numeric code for this class of error. + * @deprecated + */ + static get code() { + return ErrorCode.UNKNOWN_ERROR; + } + + /** + * @return {number} the legacy numeric code for this class of error. + * @deprecated + */ + get code() { + return this.constructor.code; + } +} + + +/** + * An attempt was made to select an element that cannot be selected. + */ +class ElementNotSelectableError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.ELEMENT_NOT_SELECTABLE; + } +} + + +/** + * An element command could not be completed because the element is not visible + * on the page. + */ +class ElementNotVisibleError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.ELEMENT_NOT_VISIBLE; + } +} + + +/** + * The arguments passed to a command are either invalid or malformed. + */ +class InvalidArgumentError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } +} + + +/** + * An illegal attempt was made to set a cookie under a different domain than + * the current page. + */ +class InvalidCookieDomainError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.INVALID_COOKIE_DOMAIN; + } +} + + +/** + * The coordinates provided to an interactions operation are invalid. + */ +class InvalidElementCoordinatesError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.INVALID_ELEMENT_COORDINATES; + } +} + + +/** + * An element command could not be completed because the element is in an + * invalid state, e.g. attempting to click an element that is no longer attached + * to the document. + */ +class InvalidElementStateError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.INVALID_ELEMENT_STATE; + } +} + + +/** + * Argument was an invalid selector. + */ +class InvalidSelectorError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.INVALID_SELECTOR_ERROR; + } +} + + +/** + * Occurs if the given session id is not in the list of active sessions, meaning + * the session either does not exist or that it’s not active. + */ +class InvalidSessionIdError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } +} + + +/** + * An error occurred while executing JavaScript supplied by the user. + */ +class JavascriptError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.JAVASCRIPT_ERROR; + } +} + + +/** + * The target for mouse interaction is not in the browser’s viewport and cannot + * be brought into that viewport. + */ +class MoveTargetOutOfBoundsError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS; + } +} + + +/** + * An attempt was made to operate on a modal dialog when one was not open. + */ +class NoSuchAlertError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.NO_SUCH_ALERT; + } +} + + +/** + * An element could not be located on the page using the given search + * parameters. + */ +class NoSuchElementError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.NO_SUCH_ELEMENT; + } +} + + +/** + * A request to switch to a frame could not be satisfied because the frame + * could not be found. + */ +class NoSuchFrameError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.NO_SUCH_FRAME; + } +} + + +/** + * A request to switch to a window could not be satisfied because the window + * could not be found. + */ +class NoSuchWindowError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.NO_SUCH_WINDOW; + } +} + + +/** + * A script did not complete before its timeout expired. + */ +class ScriptTimeoutError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.SCRIPT_TIMEOUT; + } +} + + +/** + * A new session could not be created. + */ +class SessionNotCreatedError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.SESSION_NOT_CREATED; + } +} + + + +/** + * An element command failed because the referenced element is no longer + * attached to the DOM. + */ +class StaleElementReferenceError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.STALE_ELEMENT_REFERENCE; + } +} + + +/** + * An operation did not complete before its timeout expired. + */ +class TimeoutError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.TIMEOUT; + } +} + + +/** + * A request to set a cookie’s value could not be satisfied. + */ +class UnableToSetCookieError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.UNABLE_TO_SET_COOKIE; + } +} + + +/** + * A screen capture operation was not possible. + */ +class UnableToCaptureScreenError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } +} + + +/** + * A modal dialog was open, blocking this operation. + */ +class UnexpectedAlertOpenError extends WebDriverError { + /** + * @param {string=} opt_error the error message, if any. + * @param {string=} opt_text the text of the open dialog, if available. + */ + constructor(opt_error, opt_text) { + super(opt_error); + + /** @private {(string|undefined)} */ + this.text_ = opt_text; + } + + /** @override */ + static get code() { + return ErrorCode.UNEXPECTED_ALERT_OPEN; + } + + /** + * @return {(string|undefined)} The text displayed with the unhandled alert, + * if available. + */ + getAlertText() { + return this.text_; + } +} + + +/** + * A command could not be executed because the remote end is not aware of it. + */ +class UnknownCommandError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.UNSUPPORTED_OPERATION; + } +} + + +/** + * The requested command matched a known URL but did not match an method for + * that URL. + */ +class UnknownMethodError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.UNSUPPORTED_OPERATION; + } +} + + +/** + * Reports an unsupport operation. + */ +class UnsupportedOperationError extends WebDriverError { + /** @param {string=} opt_error the error message, if any. */ + constructor(opt_error) { + super(opt_error); + } + + /** @override */ + static get code() { + return ErrorCode.UNSUPPORTED_OPERATION; + } +} + +// TODO(jleyba): Define UnknownError as an alias of WebDriverError? + + +/** + * Enum of legacy error codes. + * TODO: remove this when all code paths have been switched to the new error + * types. + * @deprecated + * @enum {number} + */ +const ErrorCode = { + SUCCESS: 0, + NO_SUCH_ELEMENT: 7, + NO_SUCH_FRAME: 8, + UNKNOWN_COMMAND: 9, + UNSUPPORTED_OPERATION: 9, + STALE_ELEMENT_REFERENCE: 10, + ELEMENT_NOT_VISIBLE: 11, + INVALID_ELEMENT_STATE: 12, + UNKNOWN_ERROR: 13, + ELEMENT_NOT_SELECTABLE: 15, + JAVASCRIPT_ERROR: 17, + XPATH_LOOKUP_ERROR: 19, + TIMEOUT: 21, + NO_SUCH_WINDOW: 23, + INVALID_COOKIE_DOMAIN: 24, + UNABLE_TO_SET_COOKIE: 25, + UNEXPECTED_ALERT_OPEN: 26, + NO_SUCH_ALERT: 27, + SCRIPT_TIMEOUT: 28, + INVALID_ELEMENT_COORDINATES: 29, + IME_NOT_AVAILABLE: 30, + IME_ENGINE_ACTIVATION_FAILED: 31, + INVALID_SELECTOR_ERROR: 32, + SESSION_NOT_CREATED: 33, + MOVE_TARGET_OUT_OF_BOUNDS: 34, + SQL_DATABASE_ERROR: 35, + INVALID_XPATH_SELECTOR: 51, + INVALID_XPATH_SELECTOR_RETURN_TYPE: 52, + METHOD_NOT_ALLOWED: 405 +}; + + +const LEGACY_ERROR_CODE_TO_TYPE = new Map([ + [ErrorCode.NO_SUCH_ELEMENT, NoSuchElementError], + [ErrorCode.NO_SUCH_FRAME, NoSuchFrameError], + [ErrorCode.UNSUPPORTED_OPERATION, UnsupportedOperationError], + [ErrorCode.STALE_ELEMENT_REFERENCE, StaleElementReferenceError], + [ErrorCode.ELEMENT_NOT_VISIBLE, ElementNotVisibleError], + [ErrorCode.INVALID_ELEMENT_STATE, InvalidElementStateError], + [ErrorCode.UNKNOWN_ERROR, WebDriverError], + [ErrorCode.ELEMENT_NOT_SELECTABLE, ElementNotSelectableError], + [ErrorCode.JAVASCRIPT_ERROR, JavascriptError], + [ErrorCode.XPATH_LOOKUP_ERROR, InvalidSelectorError], + [ErrorCode.TIMEOUT, TimeoutError], + [ErrorCode.NO_SUCH_WINDOW, NoSuchWindowError], + [ErrorCode.INVALID_COOKIE_DOMAIN, InvalidCookieDomainError], + [ErrorCode.UNABLE_TO_SET_COOKIE, UnableToSetCookieError], + [ErrorCode.UNEXPECTED_ALERT_OPEN, UnexpectedAlertOpenError], + [ErrorCode.NO_SUCH_ALERT, NoSuchAlertError], + [ErrorCode.SCRIPT_TIMEOUT, ScriptTimeoutError], + [ErrorCode.INVALID_ELEMENT_COORDINATES, InvalidElementCoordinatesError], + [ErrorCode.INVALID_SELECTOR_ERROR, InvalidSelectorError], + [ErrorCode.SESSION_NOT_CREATED, SessionNotCreatedError], + [ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS, MoveTargetOutOfBoundsError], + [ErrorCode.INVALID_XPATH_SELECTOR, InvalidSelectorError], + [ErrorCode.INVALID_XPATH_SELECTOR_RETURN_TYPE, InvalidSelectorError], + [ErrorCode.METHOD_NOT_ALLOWED, UnsupportedOperationError]]); + + +const ERROR_CODE_TO_TYPE = new Map([ + ['unknown error', WebDriverError], + ['element not selectable', ElementNotSelectableError], + ['element not visible', ElementNotVisibleError], + ['invalid argument', InvalidArgumentError], + ['invalid cookie domain', InvalidCookieDomainError], + ['invalid element coordinates', InvalidElementCoordinatesError], + ['invalid element state', InvalidElementStateError], + ['invalid selector', InvalidSelectorError], + ['invalid session id', InvalidSessionIdError], + ['javascript error', JavascriptError], + ['move target out of bounds', MoveTargetOutOfBoundsError], + ['no such alert', NoSuchAlertError], + ['no such element', NoSuchElementError], + ['no such frame', NoSuchFrameError], + ['no such window', NoSuchWindowError], + ['script timeout', ScriptTimeoutError], + ['session not created', SessionNotCreatedError], + ['stale element reference', StaleElementReferenceError], + ['timeout', TimeoutError], + ['unable to set cookie', UnableToSetCookieError], + ['unable to capture screen', UnableToCaptureScreenError], + ['unexpected alert open', UnexpectedAlertOpenError], + ['unknown command', UnknownCommandError], + ['unknown method', UnknownMethodError], + ['unsupported operation', UnsupportedOperationError]]); + + +/** + * Checks a response object from a server that adheres to the W3C WebDriver + * protocol. + * @param {*} data The response data to check. + * @return {*} The response data if it was not an encoded error. + * @throws {WebDriverError} the decoded error, if present in the data object. + * @see https://w3c.github.io/webdriver/webdriver-spec.html#protocol + */ +function checkResponse(data) { + if (data && typeof data.error === 'string') { + let ctor = ERROR_CODE_TO_TYPE.get(data.error) || WebDriverError; + throw new ctor(data.message); + } + return data; +} + + +/** + * Checks a legacy response from the Selenium 2.0 wire protocol for an error. + * @param {*} responseObj the response object to check. + * @return {*} responseObj the original response if it does not define an error. + * @throws {WebDriverError} if the response object defines an error. + */ +function checkLegacyResponse(responseObj) { + // Handle the legacy Selenium error response format. + if (responseObj + && typeof responseObj === 'object' + && typeof responseObj['status'] === 'number' + && responseObj['status'] !== 0) { + let status = responseObj['status']; + let ctor = LEGACY_ERROR_CODE_TO_TYPE.get(status) || WebDriverError; + + let value = responseObj['value']; + + if (!value || typeof value !== 'object') { + throw new ctor(value + ''); + } else { + throw new ctor(value['message'] + ''); + } + } + return responseObj; +} + + +// PUBLIC API + + +exports.ErrorCode = ErrorCode; + +exports.WebDriverError = WebDriverError; +exports.ElementNotSelectableError = ElementNotSelectableError; +exports.ElementNotVisibleError = ElementNotVisibleError; +exports.InvalidArgumentError = InvalidArgumentError; +exports.InvalidCookieDomainError = InvalidCookieDomainError; +exports.InvalidElementCoordinatesError = InvalidElementCoordinatesError; +exports.InvalidElementStateError = InvalidElementStateError; +exports.InvalidSelectorError = InvalidSelectorError; +exports.InvalidSessionIdError = InvalidSessionIdError; +exports.JavascriptError = JavascriptError; +exports.MoveTargetOutOfBoundsError = MoveTargetOutOfBoundsError; +exports.NoSuchAlertError = NoSuchAlertError; +exports.NoSuchElementError = NoSuchElementError; +exports.NoSuchFrameError = NoSuchFrameError; +exports.NoSuchWindowError = NoSuchWindowError; +exports.ScriptTimeoutError = ScriptTimeoutError; +exports.SessionNotCreatedError = SessionNotCreatedError; +exports.StaleElementReferenceError = StaleElementReferenceError; +exports.TimeoutError = TimeoutError; +exports.UnableToSetCookieError = UnableToSetCookieError; +exports.UnableToCaptureScreenError = UnableToCaptureScreenError; +exports.UnexpectedAlertOpenError = UnexpectedAlertOpenError; +exports.UnknownCommandError = UnknownCommandError; +exports.UnknownMethodError = UnknownMethodError; +exports.UnsupportedOperationError = UnsupportedOperationError; + +exports.checkResponse = checkResponse; +exports.checkLegacyResponse = checkLegacyResponse; diff --git a/www/node_modules/selenium-webdriver/example/chrome_android.js b/www/node_modules/selenium-webdriver/example/chrome_android.js new file mode 100644 index 0000000..990a4c4 --- /dev/null +++ b/www/node_modules/selenium-webdriver/example/chrome_android.js @@ -0,0 +1,38 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview A basic example of working with Chrome on Android. Before + * running this example, you must start adb and connect a device (or start an + * AVD). + */ + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until, + chrome = require('../chrome'); + +var driver = new webdriver.Builder() + .forBrowser('chrome') + .setChromeOptions(new chrome.Options().androidChrome()) + .build(); + +driver.get('http://www.google.com/ncr'); +driver.findElement(By.name('q')).sendKeys('webdriver'); +driver.findElement(By.name('btnG')).click(); +driver.wait(until.titleIs('webdriver - Google Search'), 1000); +driver.quit(); diff --git a/www/node_modules/selenium-webdriver/example/chrome_mobile_emulation.js b/www/node_modules/selenium-webdriver/example/chrome_mobile_emulation.js new file mode 100644 index 0000000..d308112 --- /dev/null +++ b/www/node_modules/selenium-webdriver/example/chrome_mobile_emulation.js @@ -0,0 +1,39 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview This is an example of emulating a mobile device using the + * ChromeDriver. + */ + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until, + chrome = require('../chrome'); + + +var driver = new webdriver.Builder() + .forBrowser('chrome') + .setChromeOptions(new chrome.Options() + .setMobileEmulation({deviceName: 'Google Nexus 5'})) + .build(); + +driver.get('http://www.google.com/ncr'); +driver.findElement(By.name('q')).sendKeys('webdriver'); +driver.findElement(By.name('btnG')).click(); +driver.wait(until.titleIs('webdriver - Google Search'), 1000); +driver.quit(); diff --git a/www/node_modules/selenium-webdriver/example/google_search.js b/www/node_modules/selenium-webdriver/example/google_search.js new file mode 100644 index 0000000..c624fa2 --- /dev/null +++ b/www/node_modules/selenium-webdriver/example/google_search.js @@ -0,0 +1,50 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview An example WebDriver script. This requires the chromedriver + * to be present on the system PATH. + * + * Usage: + * // Default behavior + * node selenium-webdriver/example/google_search.js + * + * // Target Chrome locally; the chromedriver must be on your PATH + * SELENIUM_BROWSER=chrome node selenium-webdriver/example/google_search.js + * + * // Use a local copy of the standalone Selenium server + * SELENIUM_SERVER_JAR=/path/to/selenium-server-standalone.jar \ + * node selenium-webdriver/example/google_search.js + * + * // Target a remove Selenium server + * SELENIUM_REMOTE_URL=http://www.example.com:4444/wd/hub \ + * node selenium-webdriver/example/google_search.js + */ + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until; + +var driver = new webdriver.Builder() + .forBrowser('firefox') + .build(); + +driver.get('http://www.google.com/ncr'); +driver.findElement(By.name('q')).sendKeys('webdriver'); +driver.findElement(By.name('btnG')).click(); +driver.wait(until.titleIs('webdriver - Google Search'), 1000); +driver.quit(); \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/example/google_search_generator.js b/www/node_modules/selenium-webdriver/example/google_search_generator.js new file mode 100644 index 0000000..983c8d8 --- /dev/null +++ b/www/node_modules/selenium-webdriver/example/google_search_generator.js @@ -0,0 +1,45 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview An example WebDriver script using generator functions. + * + * Usage: node selenium-webdriver/example/google_search_generator.js + */ + +var webdriver = require('..'), + By = webdriver.By; + +var driver = new webdriver.Builder() + .forBrowser('firefox') + .build(); + +driver.get('http://www.google.com/ncr'); +driver.call(function* () { + var query = yield driver.findElement(By.name('q')); + query.sendKeys('webdriver'); + + var submit = yield driver.findElement(By.name('btnG')); + submit.click(); +}); + +driver.wait(function* () { + var title = yield driver.getTitle(); + return 'webdriver - Google Search' === title; +}, 1000); + +driver.quit(); diff --git a/www/node_modules/selenium-webdriver/example/google_search_test.js b/www/node_modules/selenium-webdriver/example/google_search_test.js new file mode 100644 index 0000000..823e2c5 --- /dev/null +++ b/www/node_modules/selenium-webdriver/example/google_search_test.js @@ -0,0 +1,47 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview An example test that may be run using Mocha. + * Usage: mocha -t 10000 selenium-webdriver/example/google_search_test.js + */ + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until, + test = require('../testing'); + +test.describe('Google Search', function() { + var driver; + + test.before(function() { + driver = new webdriver.Builder() + .forBrowser('firefox') + .build(); + }); + + test.it('should append query to title', function() { + driver.get('http://www.google.com'); + driver.findElement(By.name('q')).sendKeys('webdriver'); + driver.findElement(By.name('btnG')).click(); + driver.wait(until.titleIs('webdriver - Google Search'), 1000); + }); + + test.after(function() { + driver.quit(); + }); +}); diff --git a/www/node_modules/selenium-webdriver/example/logging.js b/www/node_modules/selenium-webdriver/example/logging.js new file mode 100644 index 0000000..ae1d4cc --- /dev/null +++ b/www/node_modules/selenium-webdriver/example/logging.js @@ -0,0 +1,43 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Demonstrates how to use WebDriver's logging sysem. + */ + +'use strict'; + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until; + +webdriver.logging.installConsoleHandler(); +webdriver.logging.getLogger('webdriver.http') + .setLevel(webdriver.logging.Level.ALL); + +var driver = new webdriver.Builder() + .forBrowser('firefox') + .build(); + +driver.get('http://www.google.com/ncr'); + +var searchBox = driver.wait(until.elementLocated(By.name('q')), 3000); +searchBox.sendKeys('webdriver'); + +driver.findElement(By.name('btnG')).click(); +driver.wait(until.titleIs('webdriver - Google Search'), 1000); +driver.quit(); diff --git a/www/node_modules/selenium-webdriver/example/parallel_flows.js b/www/node_modules/selenium-webdriver/example/parallel_flows.js new file mode 100644 index 0000000..f416922 --- /dev/null +++ b/www/node_modules/selenium-webdriver/example/parallel_flows.js @@ -0,0 +1,51 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview An example of starting multiple WebDriver clients that run + * in parallel in separate control flows. + */ + +var webdriver = require('..'), + By = webdriver.By, + until = webdriver.until; + +for (var i = 0; i < 3; i++) { + (function(n) { + var flow = new webdriver.promise.ControlFlow() + .on('uncaughtException', function(e) { + console.log('uncaughtException in flow %d: %s', n, e); + }); + + var driver = new webdriver.Builder(). + forBrowser('firefox'). + setControlFlow(flow). // Comment out this line to see the difference. + build(); + + // Position and resize window so it's easy to see them running together. + driver.manage().window().setSize(600, 400); + driver.manage().window().setPosition(300 * i, 400 * i); + + driver.get('http://www.google.com'); + driver.findElement(By.name('q')).sendKeys('webdriver'); + driver.findElement(By.name('btnG')).click(); + driver.wait(until.titleIs('webdriver - Google Search'), 1000); + + driver.quit(); + })(i); +} + diff --git a/www/node_modules/selenium-webdriver/executors.js b/www/node_modules/selenium-webdriver/executors.js new file mode 100644 index 0000000..17f222a --- /dev/null +++ b/www/node_modules/selenium-webdriver/executors.js @@ -0,0 +1,50 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Various utilities for working with {@link ./command.Executor} + * implementations. + */ + + 'use strict'; + +const HttpClient = require('./http').HttpClient, + HttpExecutor = require('./http').Executor, + DeferredExecutor = require('./lib/command').DeferredExecutor, + promise = require('./lib/promise'); + + +// PUBLIC API + + +/** @deprecated Use {@link ./lib/command.DeferredExecutor} instead. */ +exports.DeferredExecutor = DeferredExecutor; + +/** + * Creates a command executor that uses WebDriver's JSON wire protocol. + * @param {(string|!promise.Promise)} url The server's URL, + * or a promise that will resolve to that URL. + * @param {?string=} opt_proxy (optional) The URL of the HTTP proxy for the + * client to use. + * @returns {!./lib/command.Executor} The new command executor. + */ +exports.createExecutor = function(url, opt_proxy) { + return new DeferredExecutor(promise.when(url, function(url) { + var client = new HttpClient(url, null, opt_proxy); + return new HttpExecutor(client); + })); +}; diff --git a/www/node_modules/selenium-webdriver/firefox/binary.js b/www/node_modules/selenium-webdriver/firefox/binary.js new file mode 100644 index 0000000..48a4a0b --- /dev/null +++ b/www/node_modules/selenium-webdriver/firefox/binary.js @@ -0,0 +1,221 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Manages Firefox binaries. This module is considered internal; + * users should use {@link ./firefox selenium-webdriver/firefox}. + */ + +'use strict'; + +const child = require('child_process'), + fs = require('fs'), + path = require('path'), + util = require('util'); + +const isDevMode = require('../lib/devmode'), + promise = require('../lib/promise'), + Symbols = require('../lib/symbols'), + io = require('../io'), + exec = require('../io/exec'); + + + +/** @const */ +const NO_FOCUS_LIB_X86 = isDevMode ? + path.join(__dirname, '../../../../cpp/prebuilt/i386/libnoblur.so') : + path.join(__dirname, '../lib/firefox/i386/libnoblur.so') ; + +/** @const */ +const NO_FOCUS_LIB_AMD64 = isDevMode ? + path.join(__dirname, '../../../../cpp/prebuilt/amd64/libnoblur64.so') : + path.join(__dirname, '../lib/firefox/amd64/libnoblur64.so') ; + +const X_IGNORE_NO_FOCUS_LIB = 'x_ignore_nofocus.so'; + +var foundBinary = null; + + +/** + * Checks the default Windows Firefox locations in Program Files. + * @return {!Promise} A promise for the located executable. + * The promise will resolve to {@code null} if Firefox was not found. + */ +function defaultWindowsLocation() { + var files = [ + process.env['PROGRAMFILES'] || 'C:\\Program Files', + process.env['PROGRAMFILES(X86)'] || 'C:\\Program Files (x86)' + ].map(function(prefix) { + return path.join(prefix, 'Mozilla Firefox\\firefox.exe'); + }); + return io.exists(files[0]).then(function(exists) { + return exists ? files[0] : io.exists(files[1]).then(function(exists) { + return exists ? files[1] : null; + }); + }); +} + + +/** + * Locates the Firefox binary for the current system. + * @return {!promise.Promise.} A promise for the located binary. The + * promise will be rejected if Firefox cannot be located. + */ +function findFirefox() { + if (foundBinary) { + return foundBinary; + } + + if (process.platform === 'darwin') { + var osxExe = '/Applications/Firefox.app/Contents/MacOS/firefox-bin'; + foundBinary = io.exists(osxExe).then(function(exists) { + return exists ? osxExe : null; + }); + } else if (process.platform === 'win32') { + foundBinary = defaultWindowsLocation(); + } else { + foundBinary = promise.fulfilled(io.findInPath('firefox')); + } + + return foundBinary = foundBinary.then(function(found) { + if (found) { + return found; + } + throw Error('Could not locate Firefox on the current system'); + }); +} + + +/** + * Copies the no focus libs into the given profile directory. + * @param {string} profileDir Path to the profile directory to install into. + * @return {!promise.Promise.} The LD_LIBRARY_PATH prefix string to use + * for the installed libs. + */ +function installNoFocusLibs(profileDir) { + var x86 = path.join(profileDir, 'x86'); + var amd64 = path.join(profileDir, 'amd64'); + + return mkdir(x86) + .then(copyLib.bind(null, NO_FOCUS_LIB_X86, x86)) + .then(mkdir.bind(null, amd64)) + .then(copyLib.bind(null, NO_FOCUS_LIB_AMD64, amd64)) + .then(function() { + return x86 + ':' + amd64; + }); + + function mkdir(dir) { + return io.exists(dir).then(function(exists) { + if (!exists) { + return promise.checkedNodeCall(fs.mkdir, dir); + } + }); + } + + function copyLib(src, dir) { + return io.copy(src, path.join(dir, X_IGNORE_NO_FOCUS_LIB)); + } +} + + +/** + * Provides a mechanism to configure and launch Firefox in a subprocess for + * use with WebDriver. + * + * @final + */ +class Binary { + /** + * @param {string=} opt_exe Path to the Firefox binary to use. If not + * specified, will attempt to locate Firefox on the current system. + */ + constructor(opt_exe) { + /** @private {(string|undefined)} */ + this.exe_ = opt_exe; + + /** @private {!Array.} */ + this.args_ = []; + + /** @private {!Object} */ + this.env_ = {}; + Object.assign(this.env_, process.env, { + MOZ_CRASHREPORTER_DISABLE: '1', + MOZ_NO_REMOTE: '1', + NO_EM_RESTART: '1' + }); + } + + /** + * Add arguments to the command line used to start Firefox. + * @param {...(string|!Array.)} var_args Either the arguments to add + * as varargs, or the arguments as an array. + */ + addArguments(var_args) { + for (var i = 0; i < arguments.length; i++) { + if (Array.isArray(arguments[i])) { + this.args_ = this.args_.concat(arguments[i]); + } else { + this.args_.push(arguments[i]); + } + } + } + + /** + * Launches Firefox and returns a promise that will be fulfilled when the + * process terminates. + * @param {string} profile Path to the profile directory to use. + * @return {!promise.Promise} A promise for the handle to the + * started subprocess. + */ + launch(profile) { + let env = {}; + Object.assign(env, this.env_, {XRE_PROFILE_PATH: profile}); + + let args = ['-foreground'].concat(this.args_); + + return promise.when(this.exe_ || findFirefox(), function(firefox) { + if (process.platform === 'win32' || process.platform === 'darwin') { + return exec(firefox, {args: args, env: env}); + } + return installNoFocusLibs(profile).then(function(ldLibraryPath) { + env['LD_LIBRARY_PATH'] = ldLibraryPath + ':' + env['LD_LIBRARY_PATH']; + env['LD_PRELOAD'] = X_IGNORE_NO_FOCUS_LIB; + return exec(firefox, {args: args, env: env}); + }); + }); + } + + /** + * Returns a promise for the wire representation of this binary. Note: the + * FirefoxDriver only supports passing the path to the binary executable over + * the wire; all command line arguments and environment variables will be + * discarded. + * + * @return {!promise.Promise} A promise for this binary's wire + * representation. + */ + [Symbols.serialize]() { + return promise.fulfilled(this.exe_ || findFirefox()); + } +} + + +// PUBLIC API + + +exports.Binary = Binary; + diff --git a/www/node_modules/selenium-webdriver/firefox/extension.js b/www/node_modules/selenium-webdriver/firefox/extension.js new file mode 100644 index 0000000..990481c --- /dev/null +++ b/www/node_modules/selenium-webdriver/firefox/extension.js @@ -0,0 +1,177 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** @fileoverview Utilities for working with Firefox extensions. */ + +'use strict'; + +const AdmZip = require('adm-zip'), + fs = require('fs'), + path = require('path'), + xml = require('xml2js'); + +const promise = require('../lib/promise'), + checkedCall = promise.checkedNodeCall, + io = require('../io'); + + +/** + * Thrown when there an add-on is malformed. + */ +class AddonFormatError extends Error { + /** @param {string} msg The error message. */ + constructor(msg) { + super(msg); + /** @override */ + this.name = this.constructor.name; + } +} + + + +/** + * Installs an extension to the given directory. + * @param {string} extension Path to the extension to install, as either a xpi + * file or a directory. + * @param {string} dir Path to the directory to install the extension in. + * @return {!promise.Promise.} A promise for the add-on ID once + * installed. + */ +function install(extension, dir) { + return getDetails(extension).then(function(details) { + function returnId() { return details.id; } + + var dst = path.join(dir, details.id); + if (extension.slice(-4) === '.xpi') { + if (!details.unpack) { + return io.copy(extension, dst + '.xpi').then(returnId); + } else { + return checkedCall(fs.readFile, extension).then(function(buff) { + // TODO: find an async library for inflating a zip archive. + new AdmZip(buff).extractAllTo(dst, true); + }).then(returnId); + } + } else { + return io.copyDir(extension, dst).then(returnId); + } + }); +} + + +/** + * Describes a Firefox add-on. + * @typedef {{id: string, name: string, version: string, unpack: boolean}} + */ +var AddonDetails; + + +/** + * Extracts the details needed to install an add-on. + * @param {string} addonPath Path to the extension directory. + * @return {!promise.Promise.} A promise for the add-on details. + */ +function getDetails(addonPath) { + return readManifest(addonPath).then(function(doc) { + var em = getNamespaceId(doc, 'http://www.mozilla.org/2004/em-rdf#'); + var rdf = getNamespaceId( + doc, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); + + var description = doc[rdf + 'RDF'][rdf + 'Description'][0]; + var details = { + id: getNodeText(description, em + 'id'), + name: getNodeText(description, em + 'name'), + version: getNodeText(description, em + 'version'), + unpack: getNodeText(description, em + 'unpack') || false + }; + + if (typeof details.unpack === 'string') { + details.unpack = details.unpack.toLowerCase() === 'true'; + } + + if (!details.id) { + throw new AddonFormatError('Could not find add-on ID for ' + addonPath); + } + + return details; + }); + + function getNodeText(node, name) { + return node[name] && node[name][0] || ''; + } + + function getNamespaceId(doc, url) { + var keys = Object.keys(doc); + if (keys.length !== 1) { + throw new AddonFormatError('Malformed manifest for add-on ' + addonPath); + } + + var namespaces = doc[keys[0]].$; + var id = ''; + Object.keys(namespaces).some(function(ns) { + if (namespaces[ns] !== url) { + return false; + } + + if (ns.indexOf(':') != -1) { + id = ns.split(':')[1] + ':'; + } + return true; + }); + return id; + } +} + + +/** + * Reads the manifest for a Firefox add-on. + * @param {string} addonPath Path to a Firefox add-on as a xpi or an extension. + * @return {!promise.Promise} A promise for the parsed manifest. + */ +function readManifest(addonPath) { + var manifest; + + if (addonPath.slice(-4) === '.xpi') { + manifest = checkedCall(fs.readFile, addonPath).then(function(buff) { + var zip = new AdmZip(buff); + if (!zip.getEntry('install.rdf')) { + throw new AddonFormatError( + 'Could not find install.rdf in ' + addonPath); + } + var done = promise.defer(); + zip.readAsTextAsync('install.rdf', done.fulfill); + return done.promise; + }); + } else { + manifest = checkedCall(fs.stat, addonPath).then(function(stats) { + if (!stats.isDirectory()) { + throw Error( + 'Add-on path is niether a xpi nor a directory: ' + addonPath); + } + return checkedCall(fs.readFile, path.join(addonPath, 'install.rdf')); + }); + } + + return manifest.then(function(content) { + return checkedCall(xml.parseString, content); + }); +} + + +// PUBLIC API + + +exports.install = install; diff --git a/www/node_modules/selenium-webdriver/firefox/index.js b/www/node_modules/selenium-webdriver/firefox/index.js new file mode 100644 index 0000000..8d726ee --- /dev/null +++ b/www/node_modules/selenium-webdriver/firefox/index.js @@ -0,0 +1,320 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines the {@linkplain Driver WebDriver} client for Firefox. + * Each FirefoxDriver instance will be created with an anonymous profile, + * ensuring browser historys do not share session data (cookies, history, cache, + * offline storage, etc.) + * + * __Customizing the Firefox Profile__ + * + * The {@link Profile} class may be used to configure the browser profile used + * with WebDriver, with functions to install additional + * {@linkplain Profile#addExtension extensions}, configure browser + * {@linkplain Profile#setPreference preferences}, and more. For example, you + * may wish to include Firebug: + * + * var firefox = require('selenium-webdriver/firefox'); + * + * var profile = new firefox.Profile(); + * profile.addExtension('/path/to/firebug.xpi'); + * profile.setPreference('extensions.firebug.showChromeErrors', true); + * + * var options = new firefox.Options().setProfile(profile); + * var driver = new firefox.Driver(options); + * + * The {@link Profile} class may also be used to configure WebDriver based on a + * pre-existing browser profile: + * + * var profile = new firefox.Profile( + * '/usr/local/home/bob/.mozilla/firefox/3fgog75h.testing'); + * var options = new firefox.Options().setProfile(profile); + * var driver = new firefox.Driver(options); + * + * The FirefoxDriver will _never_ modify a pre-existing profile; instead it will + * create a copy for it to modify. By extension, there are certain browser + * preferences that are required for WebDriver to function properly and they + * will always be overwritten. + * + * __Using a Custom Firefox Binary__ + * + * On Windows and OSX, the FirefoxDriver will search for Firefox in its + * default installation location: + * + * * Windows: C:\Program Files and C:\Program Files (x86). + * * Mac OS X: /Applications/Firefox.app + * + * For Linux, Firefox will be located on the PATH: `$(where firefox)`. + * + * You can configure WebDriver to start use a custom Firefox installation with + * the {@link Binary} class: + * + * var firefox = require('selenium-webdriver/firefox'); + * var binary = new firefox.Binary('/my/firefox/install/dir/firefox-bin'); + * var options = new firefox.Options().setBinary(binary); + * var driver = new firefox.Driver(options); + * + * __Remote Testing__ + * + * You may customize the Firefox binary and profile when running against a + * remote Selenium server. Your custom profile will be packaged as a zip and + * transfered to the remote host for use. The profile will be transferred + * _once for each new session_. The performance impact should be minimal if + * you've only configured a few extra browser preferences. If you have a large + * profile with several extensions, you should consider installing it on the + * remote host and defining its path via the {@link Options} class. Custom + * binaries are never copied to remote machines and must be referenced by + * installation path. + * + * var options = new firefox.Options() + * .setProfile('/profile/path/on/remote/host') + * .setBinary('/install/dir/on/remote/host/firefox-bin'); + * + * var driver = new (require('selenium-webdriver')).Builder() + * .forBrowser('firefox') + * .usingServer('http://127.0.0.1:4444/wd/hub') + * .setFirefoxOptions(options) + * .build(); + */ + +'use strict'; + +const url = require('url'); + +const Binary = require('./binary').Binary, + Profile = require('./profile').Profile, + decodeProfile = require('./profile').decode, + executors = require('../executors'), + httpUtil = require('../http/util'), + io = require('../io'), + capabilities = require('../lib/capabilities'), + logging = require('../lib/logging'), + promise = require('../lib/promise'), + webdriver = require('../lib/webdriver'), + net = require('../net'), + portprober = require('../net/portprober'); + + +/** + * Configuration options for the FirefoxDriver. + */ +class Options { + constructor() { + /** @private {Profile} */ + this.profile_ = null; + + /** @private {Binary} */ + this.binary_ = null; + + /** @private {logging.Preferences} */ + this.logPrefs_ = null; + + /** @private {?capabilities.ProxyConfig} */ + this.proxy_ = null; + } + + /** + * Sets the profile to use. The profile may be specified as a + * {@link Profile} object or as the path to an existing Firefox profile to use + * as a template. + * + * @param {(string|!Profile)} profile The profile to use. + * @return {!Options} A self reference. + */ + setProfile(profile) { + if (typeof profile === 'string') { + profile = new Profile(profile); + } + this.profile_ = profile; + return this; + } + + /** + * Sets the binary to use. The binary may be specified as the path to a Firefox + * executable, or as a {@link Binary} object. + * + * @param {(string|!Binary)} binary The binary to use. + * @return {!Options} A self reference. + */ + setBinary(binary) { + if (typeof binary === 'string') { + binary = new Binary(binary); + } + this.binary_ = binary; + return this; + } + + /** + * Sets the logging preferences for the new session. + * @param {logging.Preferences} prefs The logging preferences. + * @return {!Options} A self reference. + */ + setLoggingPreferences(prefs) { + this.logPrefs_ = prefs; + return this; + } + + /** + * Sets the proxy to use. + * + * @param {capabilities.ProxyConfig} proxy The proxy configuration to use. + * @return {!Options} A self reference. + */ + setProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * Converts these options to a {@link capabilities.Capabilities} instance. + * + * @return {!capabilities.Capabilities} A new capabilities object. + */ + toCapabilities() { + var caps = capabilities.Capabilities.firefox(); + if (this.logPrefs_) { + caps.set(capabilities.Capability.LOGGING_PREFS, this.logPrefs_); + } + if (this.proxy_) { + caps.set(capabilities.Capability.PROXY, this.proxy_); + } + if (this.binary_) { + caps.set('firefox_binary', this.binary_); + } + if (this.profile_) { + caps.set('firefox_profile', this.profile_); + } + return caps; + } +} + + +/** + * A WebDriver client for Firefox. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(Options|capabilities.Capabilities|Object)=} opt_config The + * configuration options for this driver, specified as either an + * {@link Options} or {@link capabilities.Capabilities}, or as a raw hash + * object. + * @param {promise.ControlFlow=} opt_flow The flow to + * schedule commands through. Defaults to the active flow object. + */ + constructor(opt_config, opt_flow) { + let caps; + if (opt_config instanceof Options) { + caps = opt_config.toCapabilities(); + } else { + caps = new capabilities.Capabilities(opt_config); + } + + let binary = caps.get('firefox_binary') || new Binary(); + if (typeof binary === 'string') { + binary = new Binary(binary); + } + + let profile = caps.get('firefox_profile') || new Profile(); + + caps.set('firefox_binary', null); + caps.set('firefox_profile', null); + + let self; // Cannot assign to 'this' until after we call super. + let freePort = portprober.findFreePort(); + let command = freePort.then(function(port) { + if (typeof profile === 'string') { + return decodeProfile(profile).then(function(dir) { + var profile = new Profile(dir); + profile.setPreference('webdriver_firefox_port', port); + return profile.writeToDisk(); + }); + } else { + profile.setPreference('webdriver_firefox_port', port); + return profile.writeToDisk(); + } + }).then(function(profileDir) { + self.profilePath_ = profileDir; + return binary.launch(profileDir); + }); + + let serverUrl = command + .then(function() { return freePort; }) + .then(function(/** number */port) { + var serverUrl = url.format({ + protocol: 'http', + hostname: net.getLoopbackAddress(), + port: port + '', + pathname: '/hub' + }); + + return httpUtil.waitForServer(serverUrl, 45 * 1000).then(function() { + return serverUrl; + }); + }); + + var executor = executors.createExecutor(serverUrl); + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + + super(driver.getSession(), executor, opt_flow); + self = this; + + /** @private {?string} */ + this.profilePath_ = null; + + /** @private */ + this.command_ = command; + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() { + } + + /** @override */ + quit() { + // TODO: use super.quit when closure compiler knows how to transpile it. + // let superQuit = super.quit; + return this.call(function() { + let self = this; + return webdriver.WebDriver.prototype.quit.call(this) + .thenFinally(function() { + return self.command_.then(function(command) { + command.kill(); + return command.result(); + }); + }) + .thenFinally(function() { + if (self.profilePath_) { + return io.rmDir(self.profilePath_); + } + }); + }, this); + } +} + + +// PUBLIC API + + +exports.Binary = Binary; +exports.Driver = Driver; +exports.Options = Options; +exports.Profile = Profile; diff --git a/www/node_modules/selenium-webdriver/firefox/profile.js b/www/node_modules/selenium-webdriver/firefox/profile.js new file mode 100644 index 0000000..13f1250 --- /dev/null +++ b/www/node_modules/selenium-webdriver/firefox/profile.js @@ -0,0 +1,413 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Profile management module. This module is considered internal; + * users should use {@link selenium-webdriver/firefox}. + */ + +'use strict'; + +const AdmZip = require('adm-zip'), + AdmConstants = require('adm-zip/util/constants'), + fs = require('fs'), + path = require('path'), + vm = require('vm'); + +const isDevMode = require('../lib/devmode'), + promise = require('../lib/promise'), + Symbols = require('../lib/symbols'), + io = require('../io'), + extension = require('./extension'); + + +/** @const */ +const WEBDRIVER_PREFERENCES_PATH = isDevMode + ? path.join(__dirname, '../../../firefox-driver/webdriver.json') + : path.join(__dirname, '../lib/firefox/webdriver.json'); + +/** @const */ +const WEBDRIVER_EXTENSION_PATH = isDevMode + ? path.join(__dirname, + '../../../../build/javascript/firefox-driver/webdriver.xpi') + : path.join(__dirname, '../lib/firefox/webdriver.xpi'); + +/** @const */ +const WEBDRIVER_EXTENSION_NAME = 'fxdriver@googlecode.com'; + + + +/** @type {Object} */ +var defaultPreferences = null; + +/** + * Synchronously loads the default preferences used for the FirefoxDriver. + * @return {!Object} The default preferences JSON object. + */ +function getDefaultPreferences() { + if (!defaultPreferences) { + var contents = /** @type {string} */( + fs.readFileSync(WEBDRIVER_PREFERENCES_PATH, 'utf8')); + defaultPreferences = /** @type {!Object} */(JSON.parse(contents)); + } + return defaultPreferences; +} + + +/** + * Parses a user.js file in a Firefox profile directory. + * @param {string} f Path to the file to parse. + * @return {!promise.Promise} A promise for the parsed preferences as + * a JSON object. If the file does not exist, an empty object will be + * returned. + */ +function loadUserPrefs(f) { + var done = promise.defer(); + fs.readFile(f, function(err, contents) { + if (err && err.code === 'ENOENT') { + done.fulfill({}); + return; + } + + if (err) { + done.reject(err); + return; + } + + var prefs = {}; + var context = vm.createContext({ + 'user_pref': function(key, value) { + prefs[key] = value; + } + }); + + vm.runInContext(/** @type {string} */(contents), context, f); + done.fulfill(prefs); + }); + return done.promise; +} + + + +/** + * @param {!Object} prefs The default preferences to write. Will be + * overridden by user.js preferences in the template directory and the + * frozen preferences required by WebDriver. + * @param {string} dir Path to the directory write the file to. + * @return {!promise.Promise} A promise for the profile directory, + * to be fulfilled when user preferences have been written. + */ +function writeUserPrefs(prefs, dir) { + var userPrefs = path.join(dir, 'user.js'); + return loadUserPrefs(userPrefs).then(function(overrides) { + Object.assign(prefs, overrides); + Object.assign(prefs, getDefaultPreferences()['frozen']); + + var contents = Object.keys(prefs).map(function(key) { + return 'user_pref(' + JSON.stringify(key) + ', ' + + JSON.stringify(prefs[key]) + ');'; + }).join('\n'); + + var done = promise.defer(); + fs.writeFile(userPrefs, contents, function(err) { + err && done.reject(err) || done.fulfill(dir); + }); + return done.promise; + }); +}; + + +/** + * Installs a group of extensions in the given profile directory. If the + * WebDriver extension is not included in this set, the default version + * bundled with this package will be installed. + * @param {!Array.} extensions The extensions to install, as a + * path to an unpacked extension directory or a path to a xpi file. + * @param {string} dir The profile directory to install to. + * @param {boolean=} opt_excludeWebDriverExt Whether to skip installation of + * the default WebDriver extension. + * @return {!Promise} A promise for the main profile directory + * once all extensions have been installed. + */ +function installExtensions(extensions, dir, opt_excludeWebDriverExt) { + var hasWebDriver = !!opt_excludeWebDriverExt; + var next = 0; + var extensionDir = path.join(dir, 'extensions'); + + return new Promise(function(fulfill, reject) { + io.exists(extensionDir).then(function(exists) { + if (!exists) { + return promise.checkedNodeCall(fs.mkdir, extensionDir); + } + }).then(installNext); + + function installNext() { + if (next >= extensions.length) { + if (hasWebDriver) { + fulfill(dir); + } else { + install(WEBDRIVER_EXTENSION_PATH); + } + } else { + install(extensions[next++]); + } + } + + function install(ext) { + extension.install(ext, extensionDir).then(function(id) { + hasWebDriver = hasWebDriver || (id === WEBDRIVER_EXTENSION_NAME); + installNext(); + }, reject); + } + }); +} + + +/** + * Decodes a base64 encoded profile. + * @param {string} data The base64 encoded string. + * @return {!Promise} A promise for the path to the decoded profile + * directory. + */ +function decode(data) { + return io.tmpFile().then(function(file) { + var buf = new Buffer(data, 'base64'); + return promise.checkedNodeCall(fs.writeFile, file, buf).then(function() { + return io.tmpDir(); + }).then(function(dir) { + var zip = new AdmZip(file); + zip.extractAllTo(dir); // Sync only? Why?? :-( + return dir; + }); + }); +} + + + +/** + * Models a Firefox proifle directory for use with the FirefoxDriver. The + * {@code Proifle} directory uses an in-memory model until {@link #writeToDisk} + * is called. + */ +class Profile { + /** + * @param {string=} opt_dir Path to an existing Firefox profile directory to + * use a template for this profile. If not specified, a blank profile will + * be used. + */ + constructor(opt_dir) { + /** @private {!Object} */ + this.preferences_ = {}; + + Object.assign(this.preferences_, getDefaultPreferences()['mutable']); + Object.assign(this.preferences_, getDefaultPreferences()['frozen']); + + /** @private {boolean} */ + this.nativeEventsEnabled_ = true; + + /** @private {(string|undefined)} */ + this.template_ = opt_dir; + + /** @private {number} */ + this.port_ = 0; + + /** @private {!Array} */ + this.extensions_ = []; + } + + /** + * Registers an extension to be included with this profile. + * @param {string} extension Path to the extension to include, as either an + * unpacked extension directory or the path to a xpi file. + */ + addExtension(extension) { + this.extensions_.push(extension); + } + + /** + * Sets a desired preference for this profile. + * @param {string} key The preference key. + * @param {(string|number|boolean)} value The preference value. + * @throws {Error} If attempting to set a frozen preference. + */ + setPreference(key, value) { + var frozen = getDefaultPreferences()['frozen']; + if (frozen.hasOwnProperty(key) && frozen[key] !== value) { + throw Error('You may not set ' + key + '=' + JSON.stringify(value) + + '; value is frozen for proper WebDriver functionality (' + + key + '=' + JSON.stringify(frozen[key]) + ')'); + } + this.preferences_[key] = value; + } + + /** + * Returns the currently configured value of a profile preference. This does + * not include any defaults defined in the profile's template directory user.js + * file (if a template were specified on construction). + * @param {string} key The desired preference. + * @return {(string|number|boolean|undefined)} The current value of the + * requested preference. + */ + getPreference(key) { + return this.preferences_[key]; + } + + /** + * Specifies which host the driver should listen for commands on. If not + * specified, the driver will default to "localhost". This option should be + * specified when "localhost" is not mapped to the loopback address + * (127.0.0.1) in `/etc/hosts`. + * + * @param {string} host the host the driver should listen for commands on + */ + setHost(host) { + this.preferences_['webdriver_firefox_allowed_hosts'] = host; + } + + /** + * @return {number} The port this profile is currently configured to use, or + * 0 if the port will be selected at random when the profile is written + * to disk. + */ + getPort() { + return this.port_; + } + + /** + * Sets the port to use for the WebDriver extension loaded by this profile. + * @param {number} port The desired port, or 0 to use any free port. + */ + setPort(port) { + this.port_ = port; + } + + /** + * @return {boolean} Whether the FirefoxDriver is configured to automatically + * accept untrusted SSL certificates. + */ + acceptUntrustedCerts() { + return !!this.preferences_['webdriver_accept_untrusted_certs']; + } + + /** + * Sets whether the FirefoxDriver should automatically accept untrusted SSL + * certificates. + * @param {boolean} value . + */ + setAcceptUntrustedCerts(value) { + this.preferences_['webdriver_accept_untrusted_certs'] = !!value; + } + + /** + * Sets whether to assume untrusted certificates come from untrusted issuers. + * @param {boolean} value . + */ + setAssumeUntrustedCertIssuer(value) { + this.preferences_['webdriver_assume_untrusted_issuer'] = !!value; + } + + /** + * @return {boolean} Whether to assume untrusted certs come from untrusted + * issuers. + */ + assumeUntrustedCertIssuer() { + return !!this.preferences_['webdriver_assume_untrusted_issuer']; + } + + /** + * Sets whether to use native events with this profile. + * @param {boolean} enabled . + */ + setNativeEventsEnabled(enabled) { + this.nativeEventsEnabled_ = enabled; + } + + /** + * Returns whether native events are enabled in this profile. + * @return {boolean} . + */ + nativeEventsEnabled() { + return this.nativeEventsEnabled_; + } + + /** + * Writes this profile to disk. + * @param {boolean=} opt_excludeWebDriverExt Whether to exclude the WebDriver + * extension from the generated profile. Used to reduce the size of an + * {@link #encode() encoded profile} since the server will always install + * the extension itself. + * @return {!Promise} A promise for the path to the new profile + * directory. + */ + writeToDisk(opt_excludeWebDriverExt) { + var profileDir = io.tmpDir(); + if (this.template_) { + profileDir = profileDir.then(function(dir) { + return io.copyDir( + /** @type {string} */(this.template_), + dir, /(parent\.lock|lock|\.parentlock)/); + }.bind(this)); + } + + // Freeze preferences for async operations. + var prefs = {}; + Object.assign(prefs, this.preferences_); + + // Freeze extensions for async operations. + var extensions = this.extensions_.concat(); + + return profileDir.then(function(dir) { + return writeUserPrefs(prefs, dir); + }).then(function(dir) { + return installExtensions(extensions, dir, !!opt_excludeWebDriverExt); + }); + } + + /** + * Encodes this profile as a zipped, base64 encoded directory. + * @return {!Promise} A promise for the encoded profile. + */ + encode() { + return this.writeToDisk(true).then(function(dir) { + var zip = new AdmZip(); + zip.addLocalFolder(dir, ''); + zip.getEntries()[0].header.method = AdmConstants.STORED; + return io.tmpFile().then(function(file) { + zip.writeZip(file); // Sync! Why oh why :-( + return promise.checkedNodeCall(fs.readFile, file); + }); + }).then(function(data) { + return new Buffer(data).toString('base64'); + }); + } + + /** + * Encodes this profile as a zipped, base64 encoded directory. + * @return {!Promise} A promise for the encoded profile. + */ + [Symbols.serialize]() { + return this.encode(); + } +} + + +// PUBLIC API + + +exports.Profile = Profile; +exports.decode = decode; +exports.loadUserPrefs = loadUserPrefs; diff --git a/www/node_modules/selenium-webdriver/http/index.js b/www/node_modules/selenium-webdriver/http/index.js new file mode 100644 index 0000000..2ffbfb9 --- /dev/null +++ b/www/node_modules/selenium-webdriver/http/index.js @@ -0,0 +1,514 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines an {@linkplain cmd.Executor command executor} that + * communicates with a remote end using HTTP + JSON. + */ + +'use strict'; + +const http = require('http'); +const url = require('url'); + +const error = require('../error'); +const cmd = require('../lib/command'); +const logging = require('../lib/logging'); +const promise = require('../lib/promise'); + + + +/** + * Converts a headers map to a HTTP header block string. + * @param {!Map} headers The map to convert. + * @return {string} The headers as a string. + */ +function headersToString(headers) { + let ret = []; + headers.forEach(function(value, name) { + ret.push(`${name.toLowerCase()}: ${value}`); + }); + return ret.join('\n'); +} + + +/** + * Represents a HTTP request message. This class is a "partial" request and only + * defines the path on the server to send a request to. It is each client's + * responsibility to build the full URL for the final request. + * @final + */ +class HttpRequest { + /** + * @param {string} method The HTTP method to use for the request. + * @param {string} path The path on the server to send the request to. + * @param {Object=} opt_data This request's non-serialized JSON payload data. + */ + constructor(method, path, opt_data) { + this.method = /** string */method; + this.path = /** string */path; + this.data = /** Object */opt_data; + this.headers = /** !Map */new Map( + [['Accept', 'application/json; charset=utf-8']]); + } + + /** @override */ + toString() { + let ret = `${this.method} ${this.path} HTTP/1.1\n`; + ret += headersToString(this.headers) + '\n\n'; + if (this.data) { + ret += JSON.stringify(this.data); + } + return ret; + } +} + + +/** + * Represents a HTTP response message. + * @final + */ +class HttpResponse { + /** + * @param {number} status The response code. + * @param {!Object} headers The response headers. All header names + * will be converted to lowercase strings for consistent lookups. + * @param {string} body The response body. + */ + constructor(status, headers, body) { + this.status = /** number */status; + this.body = /** string */body; + this.headers = /** !Map*/new Map; + for (let header in headers) { + this.headers.set(header.toLowerCase(), headers[header]); + } + } + + /** @override */ + toString() { + let ret = `HTTP/1.1 ${this.status}\n${headersToString(this.headers)}\n\n`; + if (this.body) { + ret += this.body; + } + return ret; + } +} + + +function post(path) { return resource('POST', path); } +function del(path) { return resource('DELETE', path); } +function get(path) { return resource('GET', path); } +function resource(method, path) { return {method: method, path: path}; } + + +/** @const {!Map} */ +const COMMAND_MAP = new Map([ + [cmd.Name.GET_SERVER_STATUS, get('/status')], + [cmd.Name.NEW_SESSION, post('/session')], + [cmd.Name.GET_SESSIONS, get('/sessions')], + [cmd.Name.DESCRIBE_SESSION, get('/session/:sessionId')], + [cmd.Name.QUIT, del('/session/:sessionId')], + [cmd.Name.CLOSE, del('/session/:sessionId/window')], + [cmd.Name.GET_CURRENT_WINDOW_HANDLE, get('/session/:sessionId/window_handle')], + [cmd.Name.GET_WINDOW_HANDLES, get('/session/:sessionId/window_handles')], + [cmd.Name.GET_CURRENT_URL, get('/session/:sessionId/url')], + [cmd.Name.GET, post('/session/:sessionId/url')], + [cmd.Name.GO_BACK, post('/session/:sessionId/back')], + [cmd.Name.GO_FORWARD, post('/session/:sessionId/forward')], + [cmd.Name.REFRESH, post('/session/:sessionId/refresh')], + [cmd.Name.ADD_COOKIE, post('/session/:sessionId/cookie')], + [cmd.Name.GET_ALL_COOKIES, get('/session/:sessionId/cookie')], + [cmd.Name.DELETE_ALL_COOKIES, del('/session/:sessionId/cookie')], + [cmd.Name.DELETE_COOKIE, del('/session/:sessionId/cookie/:name')], + [cmd.Name.FIND_ELEMENT, post('/session/:sessionId/element')], + [cmd.Name.FIND_ELEMENTS, post('/session/:sessionId/elements')], + [cmd.Name.GET_ACTIVE_ELEMENT, post('/session/:sessionId/element/active')], + [cmd.Name.FIND_CHILD_ELEMENT, post('/session/:sessionId/element/:id/element')], + [cmd.Name.FIND_CHILD_ELEMENTS, post('/session/:sessionId/element/:id/elements')], + [cmd.Name.CLEAR_ELEMENT, post('/session/:sessionId/element/:id/clear')], + [cmd.Name.CLICK_ELEMENT, post('/session/:sessionId/element/:id/click')], + [cmd.Name.SEND_KEYS_TO_ELEMENT, post('/session/:sessionId/element/:id/value')], + [cmd.Name.SUBMIT_ELEMENT, post('/session/:sessionId/element/:id/submit')], + [cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')], + [cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')], + [cmd.Name.IS_ELEMENT_SELECTED, get('/session/:sessionId/element/:id/selected')], + [cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')], + [cmd.Name.IS_ELEMENT_DISPLAYED, get('/session/:sessionId/element/:id/displayed')], + [cmd.Name.GET_ELEMENT_LOCATION, get('/session/:sessionId/element/:id/location')], + [cmd.Name.GET_ELEMENT_SIZE, get('/session/:sessionId/element/:id/size')], + [cmd.Name.GET_ELEMENT_ATTRIBUTE, get('/session/:sessionId/element/:id/attribute/:name')], + [cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY, get('/session/:sessionId/element/:id/css/:propertyName')], + [cmd.Name.ELEMENT_EQUALS, get('/session/:sessionId/element/:id/equals/:other')], + [cmd.Name.TAKE_ELEMENT_SCREENSHOT, get('/session/:sessionId/element/:id/screenshot')], + [cmd.Name.SWITCH_TO_WINDOW, post('/session/:sessionId/window')], + [cmd.Name.MAXIMIZE_WINDOW, post('/session/:sessionId/window/:windowHandle/maximize')], + [cmd.Name.GET_WINDOW_POSITION, get('/session/:sessionId/window/:windowHandle/position')], + [cmd.Name.SET_WINDOW_POSITION, post('/session/:sessionId/window/:windowHandle/position')], + [cmd.Name.GET_WINDOW_SIZE, get('/session/:sessionId/window/:windowHandle/size')], + [cmd.Name.SET_WINDOW_SIZE, post('/session/:sessionId/window/:windowHandle/size')], + [cmd.Name.SWITCH_TO_FRAME, post('/session/:sessionId/frame')], + [cmd.Name.GET_PAGE_SOURCE, get('/session/:sessionId/source')], + [cmd.Name.GET_TITLE, get('/session/:sessionId/title')], + [cmd.Name.EXECUTE_SCRIPT, post('/session/:sessionId/execute')], + [cmd.Name.EXECUTE_ASYNC_SCRIPT, post('/session/:sessionId/execute_async')], + [cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')], + [cmd.Name.SET_TIMEOUT, post('/session/:sessionId/timeouts')], + [cmd.Name.SET_SCRIPT_TIMEOUT, post('/session/:sessionId/timeouts/async_script')], + [cmd.Name.IMPLICITLY_WAIT, post('/session/:sessionId/timeouts/implicit_wait')], + [cmd.Name.MOVE_TO, post('/session/:sessionId/moveto')], + [cmd.Name.CLICK, post('/session/:sessionId/click')], + [cmd.Name.DOUBLE_CLICK, post('/session/:sessionId/doubleclick')], + [cmd.Name.MOUSE_DOWN, post('/session/:sessionId/buttondown')], + [cmd.Name.MOUSE_UP, post('/session/:sessionId/buttonup')], + [cmd.Name.MOVE_TO, post('/session/:sessionId/moveto')], + [cmd.Name.SEND_KEYS_TO_ACTIVE_ELEMENT, post('/session/:sessionId/keys')], + [cmd.Name.TOUCH_SINGLE_TAP, post('/session/:sessionId/touch/click')], + [cmd.Name.TOUCH_DOUBLE_TAP, post('/session/:sessionId/touch/doubleclick')], + [cmd.Name.TOUCH_DOWN, post('/session/:sessionId/touch/down')], + [cmd.Name.TOUCH_UP, post('/session/:sessionId/touch/up')], + [cmd.Name.TOUCH_MOVE, post('/session/:sessionId/touch/move')], + [cmd.Name.TOUCH_SCROLL, post('/session/:sessionId/touch/scroll')], + [cmd.Name.TOUCH_LONG_PRESS, post('/session/:sessionId/touch/longclick')], + [cmd.Name.TOUCH_FLICK, post('/session/:sessionId/touch/flick')], + [cmd.Name.ACCEPT_ALERT, post('/session/:sessionId/accept_alert')], + [cmd.Name.DISMISS_ALERT, post('/session/:sessionId/dismiss_alert')], + [cmd.Name.GET_ALERT_TEXT, get('/session/:sessionId/alert_text')], + [cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert_text')], + [cmd.Name.GET_LOG, post('/session/:sessionId/log')], + [cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/log/types')], + [cmd.Name.GET_SESSION_LOGS, post('/logs')], + [cmd.Name.UPLOAD_FILE, post('/session/:sessionId/file')], +]); + + +/** + * A basic HTTP client used to send messages to a remote end. + */ +class HttpClient { + /** + * @param {string} serverUrl URL for the WebDriver server to send commands to. + * @param {http.Agent=} opt_agent The agent to use for each request. + * Defaults to `http.globalAgent`. + * @param {?string=} opt_proxy The proxy to use for the connection to the + * server. Default is to use no proxy. + */ + constructor(serverUrl, opt_agent, opt_proxy) { + let parsedUrl = url.parse(serverUrl); + if (!parsedUrl.hostname) { + throw new Error('Invalid server URL: ' + serverUrl); + } + + /** @private {http.Agent} */ + this.agent_ = opt_agent || null; + + /** @private {?string} */ + this.proxy_ = opt_proxy || null; + + /** + * Base options for each request. + * @private {{auth: (?string|undefined), + * host: string, + * path: (?string|undefined), + * port: (?string|undefined)}} + */ + this.options_ = { + auth: parsedUrl.auth, + host: parsedUrl.hostname, + path: parsedUrl.pathname, + port: parsedUrl.port + }; + } + + /** + * Sends a request to the server. The client will automatically follow any + * redirects returned by the server, fulfilling the returned promise with the + * final response. + * + * @param {!HttpRequest} httpRequest The request to send. + * @return {!promise.Promise} A promise that will be fulfilled + * with the server's response. + */ + send(httpRequest) { + var data; + + let headers = {}; + httpRequest.headers.forEach(function(value, name) { + headers[name] = value; + }); + + headers['Content-Length'] = 0; + if (httpRequest.method == 'POST' || httpRequest.method == 'PUT') { + data = JSON.stringify(httpRequest.data); + headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); + headers['Content-Type'] = 'application/json;charset=UTF-8'; + } + + var path = this.options_.path; + if (path[path.length - 1] === '/' && httpRequest.path[0] === '/') { + path += httpRequest.path.substring(1); + } else { + path += httpRequest.path; + } + + var options = { + method: httpRequest.method, + auth: this.options_.auth, + host: this.options_.host, + port: this.options_.port, + path: path, + headers: headers + }; + + if (this.agent_) { + options.agent = this.agent_; + } + + var proxy = this.proxy_; + return new promise.Promise(function(fulfill, reject) { + sendRequest(options, fulfill, reject, data, proxy); + }); + } +} + + +/** + * Sends a single HTTP request. + * @param {!Object} options The request options. + * @param {function(!HttpResponse)} onOk The function to call if the + * request succeeds. + * @param {function(!Error)} onError The function to call if the request fails. + * @param {?string=} opt_data The data to send with the request. + * @param {?string=} opt_proxy The proxy server to use for the request. + */ +function sendRequest(options, onOk, onError, opt_data, opt_proxy) { + var host = options.host; + var port = options.port; + + if (opt_proxy) { + var proxy = url.parse(opt_proxy); + + options.headers['Host'] = options.host; + options.host = proxy.hostname; + options.port = proxy.port; + + if (proxy.auth) { + options.headers['Proxy-Authorization'] = + 'Basic ' + new Buffer(proxy.auth).toString('base64'); + } + } + + var request = http.request(options, function(response) { + if (response.statusCode == 302 || response.statusCode == 303) { + try { + var location = url.parse(response.headers['location']); + } catch (ex) { + onError(Error( + 'Failed to parse "Location" header for server redirect: ' + + ex.message + '\nResponse was: \n' + + new HttpResponse(response.statusCode, response.headers, ''))); + return; + } + + if (!location.hostname) { + location.hostname = host; + location.port = port; + } + + request.abort(); + sendRequest({ + method: 'GET', + host: location.hostname, + path: location.pathname + (location.search || ''), + port: location.port, + headers: { + 'Accept': 'application/json; charset=utf-8' + } + }, onOk, onError, undefined, opt_proxy); + return; + } + + var body = []; + response.on('data', body.push.bind(body)); + response.on('end', function() { + var resp = new HttpResponse( + /** @type {number} */(response.statusCode), + /** @type {!Object} */(response.headers), + body.join('').replace(/\0/g, '')); + onOk(resp); + }); + }); + + request.on('error', function(e) { + if (e.code === 'ECONNRESET') { + setTimeout(function() { + sendRequest(options, onOk, onError, opt_data, opt_proxy); + }, 15); + } else { + var message = e.message; + if (e.code) { + message = e.code + ' ' + message; + } + onError(new Error(message)); + } + }); + + if (opt_data) { + request.write(opt_data); + } + + request.end(); +} + + +/** + * A command executor that communicates with the server using HTTP + JSON. + * @implements {cmd.Executor} + */ +class Executor { + /** + * @param {!HttpClient} client The client to use for sending requests to the + * server. + */ + constructor(client) { + /** @private {!HttpClient} */ + this.client_ = client; + + /** @private {Map} */ + this.customCommands_ = null; + + /** @private {!logging.Logger} */ + this.log_ = logging.getLogger('webdriver.http.Executor'); + } + + /** + * Defines a new command for use with this executor. When a command is sent, + * the {@code path} will be preprocessed using the command's parameters; any + * path segments prefixed with ":" will be replaced by the parameter of the + * same name. For example, given "/person/:name" and the parameters + * "{name: 'Bob'}", the final command path will be "/person/Bob". + * + * @param {string} name The command name. + * @param {string} method The HTTP method to use when sending this command. + * @param {string} path The path to send the command to, relative to + * the WebDriver server's command root and of the form + * "/path/:variable/segment". + */ + defineCommand(name, method, path) { + if (!this.customCommands_) { + this.customCommands_ = new Map; + } + this.customCommands_.set(name, {method, path}); + } + + /** @override */ + execute(command) { + let resource = + (this.customCommands_ && this.customCommands_.get(command.getName())) + || COMMAND_MAP.get(command.getName()); + if (!resource) { + throw new error.UnknownCommandError( + 'Unrecognized command: ' + command.getName()); + } + + let parameters = command.getParameters(); + let path = buildPath(resource.path, parameters); + let request = new HttpRequest(resource.method, path, parameters); + + let log = this.log_; + log.finer(() => '>>>\n' + request); + return this.client_.send(request).then(function(response) { + log.finer(() => '<<<\n' + response); + return parseHttpResponse(/** @type {!HttpResponse} */ (response)); + }); + } +} + + +/** + * Callback used to parse {@link HttpResponse} objects from a + * {@link HttpClient}. + * @param {!HttpResponse} httpResponse The HTTP response to parse. + * @return {!Object} The parsed response. + */ +function parseHttpResponse(httpResponse) { + try { + return /** @type {!Object} */ (JSON.parse(httpResponse.body)); + } catch (ignored) { + // Whoops, looks like the server sent us a malformed response. We'll need + // to manually build a response object based on the response code. + } + + let response = { + 'status': error.ErrorCode.SUCCESS, + 'value': httpResponse.body.replace(/\r\n/g, '\n') + }; + + if (httpResponse.status >= 400) { + // 404 represents an unknown command; anything else is a generic unknown + // error. + response['status'] = httpResponse.status == 404 ? + error.ErrorCode.UNKNOWN_COMMAND : + error.ErrorCode.UNKNOWN_ERROR; + } + + return response; +} + + +/** + * Builds a fully qualified path using the given set of command parameters. Each + * path segment prefixed with ':' will be replaced by the value of the + * corresponding parameter. All parameters spliced into the path will be + * removed from the parameter map. + * @param {string} path The original resource path. + * @param {!Object<*>} parameters The parameters object to splice into the path. + * @return {string} The modified path. + */ +function buildPath(path, parameters) { + let pathParameters = path.match(/\/:(\w+)\b/g); + if (pathParameters) { + for (let i = 0; i < pathParameters.length; ++i) { + let key = pathParameters[i].substring(2); // Trim the /: + if (key in parameters) { + let value = parameters[key]; + // TODO: move webdriver.WebElement.ELEMENT definition to a + // common file so we can reference it here without pulling in all of + // webdriver.WebElement's dependencies. + if (value && value['ELEMENT']) { + // When inserting a WebElement into the URL, only use its ID value, + // not the full JSON. + value = value['ELEMENT']; + } + path = path.replace(pathParameters[i], '/' + value); + delete parameters[key]; + } else { + throw new error.InvalidArgumentError( + 'Missing required parameter: ' + key); + } + } + } + return path; +} + + +// PUBLIC API + +exports.Executor = Executor; +exports.HttpClient = HttpClient; +exports.Request = HttpRequest; +exports.Response = HttpResponse; +exports.buildPath = buildPath; // Exported for testing. diff --git a/www/node_modules/selenium-webdriver/http/util.js b/www/node_modules/selenium-webdriver/http/util.js new file mode 100644 index 0000000..88a06d6 --- /dev/null +++ b/www/node_modules/selenium-webdriver/http/util.js @@ -0,0 +1,135 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Various HTTP utilities. + */ + +'use strict'; + +const error = require('../error'), + Executor = require('./index').Executor, + HttpClient = require('./index').HttpClient, + HttpRequest = require('./index').Request, + Command = require('../lib/command').Command, + CommandName = require('../lib/command').Name, + promise = require('../lib/promise'); + + + +/** + * Queries a WebDriver server for its current status. + * @param {string} url Base URL of the server to query. + * @return {!promise.Promise.} A promise that resolves with + * a hash of the server status. + */ +function getStatus(url) { + var client = new HttpClient(url); + var executor = new Executor(client); + var command = new Command(CommandName.GET_SERVER_STATUS); + return executor.execute(command).then(function(responseObj) { + error.checkLegacyResponse(responseObj); + return responseObj['value']; + }); +} + + +// PUBLIC API + + +/** + * Queries a WebDriver server for its current status. + * @param {string} url Base URL of the server to query. + * @return {!promise.Promise.} A promise that resolves with + * a hash of the server status. + */ +exports.getStatus = getStatus; + + +/** + * Waits for a WebDriver server to be healthy and accepting requests. + * @param {string} url Base URL of the server to query. + * @param {number} timeout How long to wait for the server. + * @return {!promise.Promise} A promise that will resolve when the + * server is ready. + */ +exports.waitForServer = function(url, timeout) { + var ready = promise.defer(), + start = Date.now(); + checkServerStatus(); + return ready.promise; + + function checkServerStatus() { + return getStatus(url).then(ready.fulfill, onError); + } + + function onError() { + if (Date.now() - start > timeout) { + ready.reject( + Error('Timed out waiting for the WebDriver server at ' + url)); + } else { + setTimeout(function() { + if (ready.isPending()) { + checkServerStatus(); + } + }, 50); + } + } +}; + + +/** + * Polls a URL with GET requests until it returns a 2xx response or the + * timeout expires. + * @param {string} url The URL to poll. + * @param {number} timeout How long to wait, in milliseconds. + * @return {!promise.Promise} A promise that will resolve when the + * URL responds with 2xx. + */ +exports.waitForUrl = function(url, timeout) { + var client = new HttpClient(url), + request = new HttpRequest('GET', ''), + ready = promise.defer(), + start = Date.now(); + testUrl(); + return ready.promise; + + function testUrl() { + client.send(request).then(onResponse, onError); + } + + function onError() { + if (Date.now() - start > timeout) { + ready.reject(Error( + 'Timed out waiting for the URL to return 2xx: ' + url)); + } else { + setTimeout(function() { + if (ready.isPending()) { + testUrl(); + } + }, 50); + } + } + + function onResponse(response) { + if (!ready.isPending()) return; + if (response.status > 199 && response.status < 300) { + return ready.fulfill(); + } + onError(); + } +}; diff --git a/www/node_modules/selenium-webdriver/ie.js b/www/node_modules/selenium-webdriver/ie.js new file mode 100644 index 0000000..a892094 --- /dev/null +++ b/www/node_modules/selenium-webdriver/ie.js @@ -0,0 +1,444 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a {@linkplain Driver WebDriver} client for Microsoft's + * Internet Explorer. Before using the IEDriver, you must download the latest + * [IEDriverServer](http://selenium-release.storage.googleapis.com/index.html) + * and place it on your + * [PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). You must also apply + * the system configuration outlined on the Selenium project + * [wiki](https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver) + */ + +'use strict'; + +const fs = require('fs'), + util = require('util'); + +const executors = require('./executors'), + io = require('./io'), + capabilities = require('./lib/capabilities'), + promise = require('./lib/promise'), + webdriver = require('./lib/webdriver'), + portprober = require('./net/portprober'), + remote = require('./remote'); + + +const IEDRIVER_EXE = 'IEDriverServer.exe'; + + + +/** + * IEDriverServer logging levels. + * @enum {string} + */ +const Level = { + FATAL: 'FATAL', + ERROR: 'ERROR', + WARN: 'WARN', + INFO: 'INFO', + DEBUG: 'DEBUG', + TRACE: 'TRACE' +}; + + + +/** + * Option keys: + * https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities#ie-specific + * @enum {string} + */ +const Key = { + IGNORE_PROTECTED_MODE_SETTINGS: 'ignoreProtectedModeSettings', + IGNORE_ZOOM_SETTING: 'ignoreZoomSetting', + INITIAL_BROWSER_URL: 'initialBrowserUrl', + ENABLE_PERSISTENT_HOVER: 'enablePersistentHover', + ENABLE_ELEMENT_CACHE_CLEANUP: 'enableElementCacheCleanup', + REQUIRE_WINDOW_FOCUS: 'requireWindowFocus', + BROWSER_ATTACH_TIMEOUT: 'browserAttachTimeout', + FORCE_CREATE_PROCESS: 'ie.forceCreateProcessApi', + BROWSER_COMMAND_LINE_SWITCHES: 'ie.browserCommandLineSwitches', + USE_PER_PROCESS_PROXY: 'ie.usePerProcessProxy', + ENSURE_CLEAN_SESSION: 'ie.ensureCleanSession', + LOG_FILE: 'logFile', + LOG_LEVEL: 'logLevel', + HOST: 'host', + EXTRACT_PATH: 'extractPath', + SILENT: 'silent' +}; + + +/** + * Class for managing IEDriver specific options. + */ +class Options { + constructor() { + /** @private {!Object<(boolean|number|string|!Array)>} */ + this.options_ = {}; + + /** @private {(capabilities.ProxyConfig|null)} */ + this.proxy_ = null; + } + + /** + * Extracts the IEDriver specific options from the given capabilities + * object. + * @param {!capabilities.Capabilities} caps The capabilities object. + * @return {!Options} The IEDriver options. + */ + static fromCapabilities(caps) { + var options = new Options(); + var map = options.options_; + + Object.keys(Key).forEach(function(key) { + key = Key[key]; + if (caps.has(key)) { + map[key] = caps.get(key); + } + }); + + if (caps.has(capabilities.Capability.PROXY)) { + options.setProxy(caps.get(capabilities.Capability.PROXY)); + } + + return options; + } + + /** + * Whether to disable the protected mode settings check when the session is + * created. Disbling this setting may lead to significant instability as the + * browser may become unresponsive/hang. Only "best effort" support is provided + * when using this capability. + * + * For more information, refer to the IEDriver's + * [required system configuration](http://goo.gl/eH0Yi3). + * + * @param {boolean} ignoreSettings Whether to ignore protected mode settings. + * @return {!Options} A self reference. + */ + introduceFlakinessByIgnoringProtectedModeSettings(ignoreSettings) { + this.options_[Key.IGNORE_PROTECTED_MODE_SETTINGS] = !!ignoreSettings; + return this; + } + + /** + * Indicates whether to skip the check that the browser's zoom level is set to + * 100%. + * + * @param {boolean} ignore Whether to ignore the browser's zoom level settings. + * @return {!Options} A self reference. + */ + ignoreZoomSetting(ignore) { + this.options_[Key.IGNORE_ZOOM_SETTING] = !!ignore; + return this; + } + + /** + * Sets the initial URL loaded when IE starts. This is intended to be used with + * {@link #ignoreProtectedModeSettings} to allow the user to initialize IE in + * the proper Protected Mode zone. Setting this option may cause browser + * instability or flaky and unresponsive code. Only "best effort" support is + * provided when using this option. + * + * @param {string} url The initial browser URL. + * @return {!Options} A self reference. + */ + initialBrowserUrl(url) { + this.options_[Key.INITIAL_BROWSER_URL] = url; + return this; + } + + /** + * Configures whether to enable persistent mouse hovering (true by default). + * Persistent hovering is achieved by continuously firing mouse over events at + * the last location the mouse cursor has been moved to. + * + * @param {boolean} enable Whether to enable persistent hovering. + * @return {!Options} A self reference. + */ + enablePersistentHover(enable) { + this.options_[Key.ENABLE_PERSISTENT_HOVER] = !!enable; + return this; + } + + /** + * Configures whether the driver should attempt to remove obsolete + * {@linkplain webdriver.WebElement WebElements} from its internal cache on + * page navigation (true by default). Disabling this option will cause the + * driver to run with a larger memory footprint. + * + * @param {boolean} enable Whether to enable element reference cleanup. + * @return {!Options} A self reference. + */ + enableElementCacheCleanup(enable) { + this.options_[Key.ENABLE_ELEMENT_CACHE_CLEANUP] = !!enable; + return this; + } + + /** + * Configures whether to require the IE window to have input focus before + * performing any user interactions (i.e. mouse or keyboard events). This + * option is disabled by default, but delivers much more accurate interaction + * events when enabled. + * + * @param {boolean} require Whether to require window focus. + * @return {!Options} A self reference. + */ + requireWindowFocus(require) { + this.options_[Key.REQUIRE_WINDOW_FOCUS] = !!require; + return this; + } + + /** + * Configures the timeout, in milliseconds, that the driver will attempt to + * located and attach to a newly opened instance of Internet Explorer. The + * default is zero, which indicates waiting indefinitely. + * + * @param {number} timeout How long to wait for IE. + * @return {!Options} A self reference. + */ + browserAttachTimeout(timeout) { + this.options_[Key.BROWSER_ATTACH_TIMEOUT] = Math.max(timeout, 0); + return this; + } + + /** + * Configures whether to launch Internet Explorer using the CreateProcess API. + * If this option is not specified, IE is launched using IELaunchURL, if + * available. For IE 8 and above, this option requires the TabProcGrowth + * registry value to be set to 0. + * + * @param {boolean} force Whether to use the CreateProcess API. + * @return {!Options} A self reference. + */ + forceCreateProcessApi(force) { + this.options_[Key.FORCE_CREATE_PROCESS] = !!force; + return this; + } + + /** + * Specifies command-line switches to use when launching Internet Explorer. + * This is only valid when used with {@link #forceCreateProcessApi}. + * + * @param {...(string|!Array.)} var_args The arguments to add. + * @return {!Options} A self reference. + */ + addArguments(var_args) { + var args = this.options_[Key.BROWSER_COMMAND_LINE_SWITCHES] || []; + args = args.concat.apply(args, arguments); + this.options_[Key.BROWSER_COMMAND_LINE_SWITCHES] = args; + return this; + } + + /** + * Configures whether proxies should be configured on a per-process basis. If + * not set, setting a {@linkplain #setProxy proxy} will configure the system + * proxy. The default behavior is to use the system proxy. + * + * @param {boolean} enable Whether to enable per-process proxy settings. + * @return {!Options} A self reference. + */ + usePerProcessProxy(enable) { + this.options_[Key.USE_PER_PROCESS_PROXY] = !!enable; + return this; + } + + /** + * Configures whether to clear the cache, cookies, history, and saved form data + * before starting the browser. _Using this capability will clear session data + * for all running instances of Internet Explorer, including those started + * manually._ + * + * @param {boolean} cleanSession Whether to clear all session data on startup. + * @return {!Options} A self reference. + */ + ensureCleanSession(cleanSession) { + this.options_[Key.ENSURE_CLEAN_SESSION] = !!cleanSession; + return this; + } + + /** + * Sets the path to the log file the driver should log to. + * @param {string} file The log file path. + * @return {!Options} A self reference. + */ + setLogFile(file) { + this.options_[Key.LOG_FILE] = file; + return this; + } + + /** + * Sets the IEDriverServer's logging {@linkplain Level level}. + * @param {Level} level The logging level. + * @return {!Options} A self reference. + */ + setLogLevel(level) { + this.options_[Key.LOG_LEVEL] = level; + return this; + } + + /** + * Sets the IP address of the driver's host adapter. + * @param {string} host The IP address to use. + * @return {!Options} A self reference. + */ + setHost(host) { + this.options_[Key.HOST] = host; + return this; + } + + /** + * Sets the path of the temporary data directory to use. + * @param {string} path The log file path. + * @return {!Options} A self reference. + */ + setExtractPath(path) { + this.options_[Key.EXTRACT_PATH] = path; + return this; + } + + /** + * Sets whether the driver should start in silent mode. + * @param {boolean} silent Whether to run in silent mode. + * @return {!Options} A self reference. + */ + silent(silent) { + this.options_[Key.SILENT] = silent; + return this; + } + + /** + * Sets the proxy settings for the new session. + * @param {capabilities.ProxyConfig} proxy The proxy configuration to use. + * @return {!Options} A self reference. + */ + setProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * Converts this options instance to a {@link capabilities.Capabilities} + * object. + * @param {capabilities.Capabilities=} opt_capabilities The capabilities to + * merge these options into, if any. + * @return {!capabilities.Capabilities} The capabilities. + */ + toCapabilities(opt_capabilities) { + var caps = opt_capabilities || capabilities.Capabilities.ie(); + if (this.proxy_) { + caps.set(capabilities.Capability.PROXY, this.proxy_); + } + Object.keys(this.options_).forEach(function(key) { + caps.set(key, this.options_[key]); + }, this); + return caps; + } +} + + +function createServiceFromCapabilities(capabilities) { + if (process.platform !== 'win32') { + throw Error( + 'The IEDriver may only be used on Windows, but you appear to be on ' + + process.platform + '. Did you mean to run against a remote ' + + 'WebDriver server?'); + } + + let exe = io.findInPath(IEDRIVER_EXE, true); + if (!exe || !fs.existsSync(exe)) { + throw Error( + `${IEDRIVER_EXE} could not be found on the current PATH. Please ` + + `download the latest version of ${IEDRIVER_EXE} from ` + + 'http://selenium-release.storage.googleapis.com/index.html and ' + + 'ensure it can be found on your system PATH.'); + } + + var args = []; + if (capabilities.has(Key.HOST)) { + args.push('--host=' + capabilities.get(Key.HOST)); + } + if (capabilities.has(Key.LOG_FILE)) { + args.push('--log-file=' + capabilities.get(Key.LOG_FILE)); + } + if (capabilities.has(Key.LOG_LEVEL)) { + args.push('--log-level=' + capabilities.get(Key.LOG_LEVEL)); + } + if (capabilities.has(Key.EXTRACT_PATH)) { + args.push('--extract-path=' + capabilities.get(Key.EXTRACT_PATH)); + } + if (capabilities.get(Key.SILENT)) { + args.push('--silent'); + } + + var port = portprober.findFreePort(); + return new remote.DriverService(exe, { + loopback: true, + port: port, + args: port.then(function(port) { + return args.concat('--port=' + port); + }), + stdio: 'ignore' + }); +} + + +/** + * A WebDriver client for Microsoft's Internet Explorer. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(capabilities.Capabilities|Options)=} opt_config The configuration + * options. + * @param {promise.ControlFlow=} opt_flow The control flow to use, + * or {@code null} to use the currently active flow. + */ + constructor(opt_config, opt_flow) { + var caps = opt_config instanceof Options ? + opt_config.toCapabilities() : + (opt_config || capabilities.Capabilities.ie()); + + var service = createServiceFromCapabilities(caps); + var executor = executors.createExecutor(service.start()); + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + + super(driver.getSession(), executor, driver.controlFlow()); + + let boundQuit = this.quit.bind(this); + + /** @override */ + this.quit = function() { + return boundQuit().thenFinally(service.kill.bind(service)); + }; + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() {} +} + + +// PUBLIC API + + +exports.Driver = Driver; +exports.Options = Options; +exports.Level = Level; diff --git a/www/node_modules/selenium-webdriver/index.js b/www/node_modules/selenium-webdriver/index.js new file mode 100644 index 0000000..38dfa6f --- /dev/null +++ b/www/node_modules/selenium-webdriver/index.js @@ -0,0 +1,57 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview The main user facing module. Exports WebDriver's primary + * public API and provides convenience assessors to certain sub-modules. + */ + +'use strict'; + +const builder = require('./builder'); +const error = require('./error'); +const actions = require('./lib/actions'); +const by = require('./lib/by'); +const capabilities = require('./lib/capabilities'); +const command = require('./lib/command'); +const events = require('./lib/events'); +const input = require('./lib/input'); +const logging = require('./lib/logging'); +const promise = require('./lib/promise'); +const session = require('./lib/session'); +const until = require('./lib/until'); +const webdriver = require('./lib/webdriver'); + + +exports.ActionSequence = actions.ActionSequence; +exports.Browser = capabilities.Browser; +exports.Builder = builder.Builder; +exports.Button = input.Button; +exports.By = by.By; +exports.Capabilities = capabilities.Capabilities; +exports.Capability = capabilities.Capability; +exports.EventEmitter = events.EventEmitter; +exports.FileDetector = input.FileDetector; +exports.Key = input.Key; +exports.Session = session.Session; +exports.WebDriver = webdriver.WebDriver; +exports.WebElement = webdriver.WebElement; +exports.WebElementPromise = webdriver.WebElementPromise; +exports.error = error; +exports.logging = logging; +exports.promise = promise; +exports.until = until; diff --git a/www/node_modules/selenium-webdriver/io/exec.js b/www/node_modules/selenium-webdriver/io/exec.js new file mode 100644 index 0000000..90d4232 --- /dev/null +++ b/www/node_modules/selenium-webdriver/io/exec.js @@ -0,0 +1,159 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const childProcess = require('child_process'); +const promise = require('../lib/promise'); + + +/** + * A hash with configuration options for an executed command. + * + * - `args` - Command line arguments. + * - `env` - Command environment; will inherit from the current process if + * missing. + * - `stdio` - IO configuration for the spawned server process. For more + * information, refer to the documentation of `child_process.spawn`. + * + * @typedef {{ + * args: (!Array|undefined), + * env: (!Object|undefined), + * stdio: (string|!Array| + * undefined) + * }} + */ +var Options; + + +/** + * Describes a command's termination conditions. + */ +class Result { + /** + * @param {?number} code The exit code, or {@code null} if the command did not + * exit normally. + * @param {?string} signal The signal used to kill the command, or + * {@code null}. + */ + constructor(code, signal) { + /** @type {?number} */ + this.code = code; + + /** @type {?string} */ + this.signal = signal; + } + + /** @override */ + toString() { + return `Result(code=${this.code}, signal=${this.signal})`; + } +} + + +const COMMAND_RESULT = + /** !WeakMap> */new WeakMap; +const KILL_HOOK = /** !WeakMap */new WeakMap; + +/** + * Represents a command running in a sub-process. + */ +class Command { + /** + * @param {!promise.Promise} result The command result. + * @param {function(string)} onKill The function to call when {@link #kill()} + * is called. + */ + constructor(result, onKill) { + COMMAND_RESULT.set(this, result); + KILL_HOOK.set(this, onKill); + } + + /** @return {boolean} Whether this command is still running. */ + isRunning() { + return COMMAND_RESULT.get(this).isPending(); + } + + /** + * @return {!promise.Promise} A promise for the result of this + * command. + */ + result() { + return /** @type {!promise.Promise} */(COMMAND_RESULT.get(this)); + } + + /** + * Sends a signal to the underlying process. + * @param {string=} opt_signal The signal to send; defaults to `SIGTERM`. + */ + kill(opt_signal) { + KILL_HOOK.get(this)(opt_signal || 'SIGTERM'); + } +} + + +// PUBLIC API + + +/** + * Spawns a child process. The returned {@link Command} may be used to wait + * for the process result or to send signals to the process. + * + * @param {string} command The executable to spawn. + * @param {Options=} opt_options The command options. + * @return {!Command} The launched command. + */ +module.exports = function exec(command, opt_options) { + var options = opt_options || {}; + + var proc = childProcess.spawn(command, options.args || [], { + env: options.env || process.env, + stdio: options.stdio || 'ignore' + }).once('exit', onExit); + + // This process should not wait on the spawned child, however, we do + // want to ensure the child is killed when this process exits. + proc.unref(); + process.once('exit', killCommand); + + var result = promise.defer(); + var cmd = new Command(result.promise, function(signal) { + if (!result.isPending() || !proc) { + return; // No longer running. + } + proc.kill(signal); + }); + return cmd; + + function onExit(code, signal) { + proc = null; + process.removeListener('exit', killCommand); + result.fulfill(new Result(code, signal)); + } + + function killCommand() { + process.removeListener('exit', killCommand); + proc && proc.kill('SIGTERM'); + } +}; + +// Exported to improve generated API documentation. + +module.exports.Command = Command; +/** @typedef {!Options} */ +module.exports.Options = Options; +module.exports.Result = Result; diff --git a/www/node_modules/selenium-webdriver/io/index.js b/www/node_modules/selenium-webdriver/io/index.js new file mode 100644 index 0000000..2da0670 --- /dev/null +++ b/www/node_modules/selenium-webdriver/io/index.js @@ -0,0 +1,227 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fs = require('fs'), + path = require('path'), + rimraf = require('rimraf'), + tmp = require('tmp'); + + + +// PUBLIC API + + + +/** + * Recursively removes a directory and all of its contents. This is equivalent + * to {@code rm -rf} on a POSIX system. + * @param {string} dirPath Path to the directory to remove. + * @return {!Promise} A promise to be resolved when the operation has + * completed. + */ +exports.rmDir = function(dirPath) { + return new Promise(function(fulfill, reject) { + var numAttempts = 0; + attemptRm(); + function attemptRm() { + numAttempts += 1; + rimraf(dirPath, function(err) { + if (err) { + if (err.code === 'ENOTEMPTY' && numAttempts < 2) { + attemptRm(); + return; + } + reject(err); + } else { + fulfill(); + } + }); + } + }); +}; + + +/** + * Copies one file to another. + * @param {string} src The source file. + * @param {string} dst The destination file. + * @return {!Promise} A promise for the copied file's path. + */ +exports.copy = function(src, dst) { + return new Promise(function(fulfill, reject) { + var rs = fs.createReadStream(src); + rs.on('error', reject); + rs.on('end', () => fulfill(dst)); + + var ws = fs.createWriteStream(dst); + ws.on('error', reject); + + rs.pipe(ws); + }); +}; + + +/** + * Recursively copies the contents of one directory to another. + * @param {string} src The source directory to copy. + * @param {string} dst The directory to copy into. + * @param {(RegExp|function(string): boolean)=} opt_exclude An exclusion filter + * as either a regex or predicate function. All files matching this filter + * will not be copied. + * @return {!Promise} A promise for the destination + * directory's path once all files have been copied. + */ +exports.copyDir = function(src, dst, opt_exclude) { + var predicate = opt_exclude; + if (opt_exclude && typeof opt_exclude !== 'function') { + predicate = function(p) { + return !opt_exclude.test(p); + }; + } + + // TODO(jleyba): Make this function completely async. + if (!fs.existsSync(dst)) { + fs.mkdirSync(dst); + } + + var files = fs.readdirSync(src); + files = files.map(function(file) { + return path.join(src, file); + }); + + if (predicate) { + files = files.filter(/** @type {function(string): boolean} */(predicate)); + } + + var results = []; + files.forEach(function(file) { + var stats = fs.statSync(file); + var target = path.join(dst, path.basename(file)); + + if (stats.isDirectory()) { + if (!fs.existsSync(target)) { + fs.mkdirSync(target, stats.mode); + } + results.push(exports.copyDir(file, target, predicate)); + } else { + results.push(exports.copy(file, target)); + } + }); + + return Promise.all(results).then(() => dst); +}; + + +/** + * Tests if a file path exists. + * @param {string} aPath The path to test. + * @return {!Promise} A promise for whether the file exists. + */ +exports.exists = function(aPath) { + return new Promise(function(fulfill) { + fs.exists(aPath, fulfill); + }); +}; + + +/** + * Deletes a name from the filesystem and possibly the file it refers to. Has + * no effect if the file does not exist. + * @param {string} aPath The path to remove. + * @return {!Promise} A promise for when the file has been removed. + */ +exports.unlink = function(aPath) { + return new Promise(function(fulfill, reject) { + fs.exists(aPath, function(exists) { + if (exists) { + fs.unlink(aPath, function(err) { + err && reject(err) || fulfill(); + }); + } else { + fulfill(); + } + }); + }); +}; + + +/** + * @return {!Promise} A promise for the path to a temporary directory. + * @see https://www.npmjs.org/package/tmp + */ +exports.tmpDir = function() { + return new Promise(function(fulfill, reject) { + tmp.dir(function(error, value) { + error ? reject(error) : fulfill(value); + }); + }); +}; + + +/** + * @param {{postfix: string}=} opt_options Temporary file options. + * @return {!Promise} A promise for the path to a temporary file. + * @see https://www.npmjs.org/package/tmp + */ +exports.tmpFile = function(opt_options) { + return new Promise(function(fulfill, reject) { + let callback = function( + /** Error */err, + /** (string|undefined) */value) { + err ? reject(err) : fulfill(value); + }; + + // |tmp.file| checks arguments length to detect options rather than doing a + // truthy check, so we must only pass options if there are some to pass. + if (opt_options) { + tmp.file(opt_options, callback); + } else { + tmp.file(callback); + } + }); +}; + + +/** + * Searches the {@code PATH} environment variable for the given file. + * @param {string} file The file to locate on the PATH. + * @param {boolean=} opt_checkCwd Whether to always start with the search with + * the current working directory, regardless of whether it is explicitly + * listed on the PATH. + * @return {?string} Path to the located file, or {@code null} if it could + * not be found. + */ +exports.findInPath = function(file, opt_checkCwd) { + if (opt_checkCwd) { + var tmp = path.join(process.cwd(), file); + if (fs.existsSync(tmp)) { + return tmp; + } + } + + var dirs = process.env['PATH'].split(path.delimiter); + var found = null; + dirs.forEach(function(dir) { + var tmp = path.join(dir, file); + if (!found && fs.existsSync(tmp)) { + found = tmp; + } + }); + return found; +}; diff --git a/www/node_modules/selenium-webdriver/lib/README b/www/node_modules/selenium-webdriver/lib/README new file mode 100644 index 0000000..bdf25b0 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/README @@ -0,0 +1,2 @@ +This directory contains modules internal to selenium-webdriver that are not +intended for general consumption. They may change at any time. diff --git a/www/node_modules/selenium-webdriver/lib/actions.js b/www/node_modules/selenium-webdriver/lib/actions.js new file mode 100644 index 0000000..bb94c5e --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/actions.js @@ -0,0 +1,594 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const command = require('./command'); +const input = require('./input'); +const error = require('../error'); + + +/** + * @param {!IArrayLike} args . + * @return {!Array} . + */ +function flatten(args) { + let result = []; + for (let i = 0; i < args.length; i++) { + let element = args[i]; + if (Array.isArray(element)) { + result.push.apply(result, flatten(element)); + } else { + result.push(element); + } + } + return result; +} + + +const MODIFIER_KEYS = new Set([ + input.Key.ALT, + input.Key.CONTROL, + input.Key.SHIFT, + input.Key.COMMAND +]); + + +/** + * Checks that a key is a modifier key. + * @param {!input.Key} key The key to check. + * @throws {error.InvalidArgumentError} If the key is not a modifier key. + * @private + */ +function checkModifierKey(key) { + if (!MODIFIER_KEYS.has(key)) { + throw new error.InvalidArgumentError('Not a modifier key'); + } +} + + +/** + * Class for defining sequences of complex user interactions. Each sequence + * will not be executed until {@link #perform} is called. + * + * Example: + * + * new ActionSequence(driver). + * keyDown(Key.SHIFT). + * click(element1). + * click(element2). + * dragAndDrop(element3, element4). + * keyUp(Key.SHIFT). + * perform(); + * + */ +class ActionSequence { + /** + * @param {!./webdriver.WebDriver} driver The driver that should be used to + * perform this action sequence. + */ + constructor(driver) { + /** @private {!./webdriver.WebDriver} */ + this.driver_ = driver; + + /** @private {!Array<{description: string, command: !command.Command}>} */ + this.actions_ = []; + } + + /** + * Schedules an action to be executed each time {@link #perform} is called on + * this instance. + * + * @param {string} description A description of the command. + * @param {!command.Command} command The command. + * @private + */ + schedule_(description, command) { + this.actions_.push({ + description: description, + command: command + }); + } + + /** + * Executes this action sequence. + * + * @return {!./promise.Promise} A promise that will be resolved once + * this sequence has completed. + */ + perform() { + // Make a protected copy of the scheduled actions. This will protect against + // users defining additional commands before this sequence is actually + // executed. + let actions = this.actions_.concat(); + let driver = this.driver_; + return driver.controlFlow().execute(function() { + actions.forEach(function(action) { + driver.schedule(action.command, action.description); + }); + }, 'ActionSequence.perform'); + } + + /** + * Moves the mouse. The location to move to may be specified in terms of the + * mouse's current location, an offset relative to the top-left corner of an + * element, or an element (in which case the middle of the element is used). + * + * @param {(!./webdriver.WebElement|{x: number, y: number})} location The + * location to drag to, as either another WebElement or an offset in + * pixels. + * @param {{x: number, y: number}=} opt_offset If the target {@code location} + * is defined as a {@link ./webdriver.WebElement}, this parameter defines + * an offset within that element. The offset should be specified in pixels + * relative to the top-left corner of the element's bounding box. If + * omitted, the element's center will be used as the target offset. + * @return {!ActionSequence} A self reference. + */ + mouseMove(location, opt_offset) { + let cmd = new command.Command(command.Name.MOVE_TO); + + if (typeof location.x === 'number') { + setOffset(/** @type {{x: number, y: number}} */(location)); + } else { + cmd.setParameter('element', location.getRawId()); + if (opt_offset) { + setOffset(opt_offset); + } + } + + this.schedule_('mouseMove', cmd); + return this; + + /** @param {{x: number, y: number}} offset The offset to use. */ + function setOffset(offset) { + cmd.setParameter('xoffset', offset.x || 0); + cmd.setParameter('yoffset', offset.y || 0); + } + } + + /** + * Schedules a mouse action. + * @param {string} description A simple descriptive label for the scheduled + * action. + * @param {!command.Name} commandName The name of the command. + * @param {(./webdriver.WebElement|input.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link input.Button.LEFT} if neither an element nor + * button is specified. + * @param {input.Button=} opt_button The button to use. Defaults to + * {@link input.Button.LEFT}. Ignored if the previous argument is + * provided as a button. + * @return {!ActionSequence} A self reference. + * @private + */ + scheduleMouseAction_( + description, commandName, opt_elementOrButton, opt_button) { + let button; + if (typeof opt_elementOrButton === 'number') { + button = opt_elementOrButton; + } else { + if (opt_elementOrButton) { + this.mouseMove( + /** @type {!./webdriver.WebElement} */ (opt_elementOrButton)); + } + button = opt_button !== void(0) ? opt_button : input.Button.LEFT; + } + + let cmd = new command.Command(commandName). + setParameter('button', button); + this.schedule_(description, cmd); + return this; + } + + /** + * Presses a mouse button. The mouse button will not be released until + * {@link #mouseUp} is called, regardless of whether that call is made in this + * sequence or another. The behavior for out-of-order events (e.g. mouseDown, + * click) is undefined. + * + * If an element is provided, the mouse will first be moved to the center + * of that element. This is equivalent to: + * + * sequence.mouseMove(element).mouseDown() + * + * Warning: this method currently only supports the left mouse button. See + * [issue 4047](http://code.google.com/p/selenium/issues/detail?id=4047). + * + * @param {(./webdriver.WebElement|input.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link input.Button.LEFT} if neither an element nor + * button is specified. + * @param {input.Button=} opt_button The button to use. Defaults to + * {@link input.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!ActionSequence} A self reference. + */ + mouseDown(opt_elementOrButton, opt_button) { + return this.scheduleMouseAction_('mouseDown', + command.Name.MOUSE_DOWN, opt_elementOrButton, opt_button); + } + + /** + * Releases a mouse button. Behavior is undefined for calling this function + * without a previous call to {@link #mouseDown}. + * + * If an element is provided, the mouse will first be moved to the center + * of that element. This is equivalent to: + * + * sequence.mouseMove(element).mouseUp() + * + * Warning: this method currently only supports the left mouse button. See + * [issue 4047](http://code.google.com/p/selenium/issues/detail?id=4047). + * + * @param {(./webdriver.WebElement|input.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link input.Button.LEFT} if neither an element nor + * button is specified. + * @param {input.Button=} opt_button The button to use. Defaults to + * {@link input.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!ActionSequence} A self reference. + */ + mouseUp(opt_elementOrButton, opt_button) { + return this.scheduleMouseAction_('mouseUp', + command.Name.MOUSE_UP, opt_elementOrButton, opt_button); + } + + /** + * Convenience function for performing a "drag and drop" manuever. The target + * element may be moved to the location of another element, or by an offset (in + * pixels). + * + * @param {!./webdriver.WebElement} element The element to drag. + * @param {(!./webdriver.WebElement|{x: number, y: number})} location The + * location to drag to, either as another WebElement or an offset in + * pixels. + * @return {!ActionSequence} A self reference. + */ + dragAndDrop(element, location) { + return this.mouseDown(element).mouseMove(location).mouseUp(); + } + + /** + * Clicks a mouse button. + * + * If an element is provided, the mouse will first be moved to the center + * of that element. This is equivalent to: + * + * sequence.mouseMove(element).click() + * + * @param {(./webdriver.WebElement|input.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link input.Button.LEFT} if neither an element nor + * button is specified. + * @param {input.Button=} opt_button The button to use. Defaults to + * {@link input.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!ActionSequence} A self reference. + */ + click(opt_elementOrButton, opt_button) { + return this.scheduleMouseAction_('click', + command.Name.CLICK, opt_elementOrButton, opt_button); + } + + /** + * Double-clicks a mouse button. + * + * If an element is provided, the mouse will first be moved to the center of + * that element. This is equivalent to: + * + * sequence.mouseMove(element).doubleClick() + * + * Warning: this method currently only supports the left mouse button. See + * [issue 4047](http://code.google.com/p/selenium/issues/detail?id=4047). + * + * @param {(./webdriver.WebElement|input.Button)=} opt_elementOrButton Either + * the element to interact with or the button to click with. + * Defaults to {@link input.Button.LEFT} if neither an element nor + * button is specified. + * @param {input.Button=} opt_button The button to use. Defaults to + * {@link input.Button.LEFT}. Ignored if a button is provided as the + * first argument. + * @return {!ActionSequence} A self reference. + */ + doubleClick(opt_elementOrButton, opt_button) { + return this.scheduleMouseAction_('doubleClick', + command.Name.DOUBLE_CLICK, opt_elementOrButton, opt_button); + } + + /** + * Schedules a keyboard action. + * + * @param {string} description A simple descriptive label for the scheduled + * action. + * @param {!Array<(string|!input.Key)>} keys The keys to send. + * @return {!ActionSequence} A self reference. + * @private + */ + scheduleKeyboardAction_(description, keys) { + let cmd = new command.Command(command.Name.SEND_KEYS_TO_ACTIVE_ELEMENT) + .setParameter('value', keys); + this.schedule_(description, cmd); + return this; + } + + /** + * Performs a modifier key press. The modifier key is not released + * until {@link #keyUp} or {@link #sendKeys} is called. The key press will be + * targetted at the currently focused element. + * + * @param {!input.Key} key The modifier key to push. Must be one of + * {ALT, CONTROL, SHIFT, COMMAND, META}. + * @return {!ActionSequence} A self reference. + * @throws {error.InvalidArgumentError} If the key is not a valid modifier + * key. + */ + keyDown(key) { + checkModifierKey(key); + return this.scheduleKeyboardAction_('keyDown', [key]); + } + + /** + * Performs a modifier key release. The release is targetted at the currently + * focused element. + * @param {!input.Key} key The modifier key to release. Must be one of + * {ALT, CONTROL, SHIFT, COMMAND, META}. + * @return {!ActionSequence} A self reference. + * @throws {error.InvalidArgumentError} If the key is not a valid modifier + * key. + */ + keyUp(key) { + checkModifierKey(key); + return this.scheduleKeyboardAction_('keyUp', [key]); + } + + /** + * Simulates typing multiple keys. Each modifier key encountered in the + * sequence will not be released until it is encountered again. All key events + * will be targetted at the currently focused element. + * + * @param {...(string|!input.Key|!Array<(string|!input.Key)>)} var_args + * The keys to type. + * @return {!ActionSequence} A self reference. + * @throws {Error} If the key is not a valid modifier key. + */ + sendKeys(var_args) { + let keys = flatten(arguments); + return this.scheduleKeyboardAction_('sendKeys', keys); + } +} + + +/** + * Class for defining sequences of user touch interactions. Each sequence + * will not be executed until {@link #perform} is called. + * + * Example: + * + * new TouchSequence(driver). + * tapAndHold({x: 0, y: 0}). + * move({x: 3, y: 4}). + * release({x: 10, y: 10}). + * perform(); + * + */ +class TouchSequence { + /** + * @param {!./webdriver.WebDriver} driver The driver that should be used to + * perform this action sequence. + */ + constructor(driver) { + /** @private {!./webdriver.WebDriver} */ + this.driver_ = driver; + + /** @private {!Array<{description: string, command: !command.Command}>} */ + this.actions_ = []; + } + + /** + * Schedules an action to be executed each time {@link #perform} is called on + * this instance. + * @param {string} description A description of the command. + * @param {!command.Command} command The command. + * @private + */ + schedule_(description, command) { + this.actions_.push({ + description: description, + command: command + }); + } + + /** + * Executes this action sequence. + * @return {!./promise.Promise} A promise that will be resolved once + * this sequence has completed. + */ + perform() { + // Make a protected copy of the scheduled actions. This will protect against + // users defining additional commands before this sequence is actually + // executed. + let actions = this.actions_.concat(); + let driver = this.driver_; + return driver.controlFlow().execute(function() { + actions.forEach(function(action) { + driver.schedule(action.command, action.description); + }); + }, 'TouchSequence.perform'); + } + + /** + * Taps an element. + * + * @param {!./webdriver.WebElement} elem The element to tap. + * @return {!TouchSequence} A self reference. + */ + tap(elem) { + let cmd = new command.Command(command.Name.TOUCH_SINGLE_TAP). + setParameter('element', elem.getId()); + + this.schedule_('tap', cmd); + return this; + } + + /** + * Double taps an element. + * + * @param {!./webdriver.WebElement} elem The element to double tap. + * @return {!TouchSequence} A self reference. + */ + doubleTap(elem) { + let cmd = new command.Command(command.Name.TOUCH_DOUBLE_TAP). + setParameter('element', elem.getId()); + + this.schedule_('doubleTap', cmd); + return this; + } + + /** + * Long press on an element. + * + * @param {!./webdriver.WebElement} elem The element to long press. + * @return {!TouchSequence} A self reference. + */ + longPress(elem) { + let cmd = new command.Command(command.Name.TOUCH_LONG_PRESS). + setParameter('element', elem.getId()); + + this.schedule_('longPress', cmd); + return this; + } + + /** + * Touch down at the given location. + * + * @param {{x: number, y: number}} location The location to touch down at. + * @return {!TouchSequence} A self reference. + */ + tapAndHold(location) { + let cmd = new command.Command(command.Name.TOUCH_DOWN). + setParameter('x', location.x). + setParameter('y', location.y); + + this.schedule_('tapAndHold', cmd); + return this; + } + + /** + * Move a held {@linkplain #tapAndHold touch} to the specified location. + * + * @param {{x: number, y: number}} location The location to move to. + * @return {!TouchSequence} A self reference. + */ + move(location) { + let cmd = new command.Command(command.Name.TOUCH_MOVE). + setParameter('x', location.x). + setParameter('y', location.y); + + this.schedule_('move', cmd); + return this; + } + + /** + * Release a held {@linkplain #tapAndHold touch} at the specified location. + * + * @param {{x: number, y: number}} location The location to release at. + * @return {!TouchSequence} A self reference. + */ + release(location) { + let cmd = new command.Command(command.Name.TOUCH_UP). + setParameter('x', location.x). + setParameter('y', location.y); + + this.schedule_('release', cmd); + return this; + } + + /** + * Scrolls the touch screen by the given offset. + * + * @param {{x: number, y: number}} offset The offset to scroll to. + * @return {!TouchSequence} A self reference. + */ + scroll(offset) { + let cmd = new command.Command(command.Name.TOUCH_SCROLL). + setParameter('xoffset', offset.x). + setParameter('yoffset', offset.y); + + this.schedule_('scroll', cmd); + return this; + } + + /** + * Scrolls the touch screen, starting on `elem` and moving by the specified + * offset. + * + * @param {!./webdriver.WebElement} elem The element where scroll starts. + * @param {{x: number, y: number}} offset The offset to scroll to. + * @return {!TouchSequence} A self reference. + */ + scrollFromElement(elem, offset) { + let cmd = new command.Command(command.Name.TOUCH_SCROLL). + setParameter('element', elem.getId()). + setParameter('xoffset', offset.x). + setParameter('yoffset', offset.y); + + this.schedule_('scrollFromElement', cmd); + return this; + } + + /** + * Flick, starting anywhere on the screen, at speed xspeed and yspeed. + * + * @param {{xspeed: number, yspeed: number}} speed The speed to flick in each + direction, in pixels per second. + * @return {!TouchSequence} A self reference. + */ + flick(speed) { + let cmd = new command.Command(command.Name.TOUCH_FLICK). + setParameter('xspeed', speed.xspeed). + setParameter('yspeed', speed.yspeed); + + this.schedule_('flick', cmd); + return this; + } + + /** + * Flick starting at elem and moving by x and y at specified speed. + * + * @param {!./webdriver.WebElement} elem The element where flick starts. + * @param {{x: number, y: number}} offset The offset to flick to. + * @param {number} speed The speed to flick at in pixels per second. + * @return {!TouchSequence} A self reference. + */ + flickElement(elem, offset, speed) { + let cmd = new command.Command(command.Name.TOUCH_FLICK). + setParameter('element', elem.getId()). + setParameter('xoffset', offset.x). + setParameter('yoffset', offset.y). + setParameter('speed', speed); + + this.schedule_('flickElement', cmd); + return this; + } +} + + +// PUBLIC API + +exports.ActionSequence = ActionSequence; +exports.TouchSequence = TouchSequence; diff --git a/www/node_modules/selenium-webdriver/lib/by.js b/www/node_modules/selenium-webdriver/lib/by.js new file mode 100644 index 0000000..4d77b99 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/by.js @@ -0,0 +1,276 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * @fileoverview Factory methods for the supported locator strategies. + */ + +/** + * Short-hand expressions for the primary element locator strategies. + * For example the following two statements are equivalent: + * + * var e1 = driver.findElement(By.id('foo')); + * var e2 = driver.findElement({id: 'foo'}); + * + * Care should be taken when using JavaScript minifiers (such as the + * Closure compiler), as locator hashes will always be parsed using + * the un-obfuscated properties listed. + * + * @typedef {( + * {className: string}| + * {css: string}| + * {id: string}| + * {js: string}| + * {linkText: string}| + * {name: string}| + * {partialLinkText: string}| + * {tagName: string}| + * {xpath: string})} + */ +var ByHash; + + +/** + * Error thrown if an invalid character is encountered while escaping a CSS + * identifier. + * @see https://drafts.csswg.org/cssom/#serialize-an-identifier + */ +class InvalidCharacterError extends Error { + constructor() { + super(); + this.name = this.constructor.name; + } +} + + +/** + * Escapes a CSS string. + * @param {string} css the string to escape. + * @return {string} the escaped string. + * @throws {TypeError} if the input value is not a string. + * @throws {InvalidCharacterError} if the string contains an invalid character. + * @see https://drafts.csswg.org/cssom/#serialize-an-identifier + */ +function escapeCss(css) { + if (typeof css !== 'string') { + throw new TypeError('input must be a string'); + } + let ret = ''; + const n = css.length; + for (let i = 0; i < n; i++) { + const c = css.charCodeAt(i); + if (c == 0x0) { + throw new InvalidCharacterError(); + } + + if ((c >= 0x0001 && c <= 0x001F) + || c == 0x007F + || (i == 0 && c >= 0x0030 && c <= 0x0039) + || (i == 1 && c >= 0x0030 && c <= 0x0039 + && css.charCodeAt(0) == 0x002D)) { + ret += '\\' + c.toString(16); + continue; + } + + if (i == 0 && c == 0x002D && n == 1) { + ret += '\\' + css.charAt(i); + continue; + } + + if (c >= 0x0080 + || c == 0x002D // - + || c == 0x005F // _ + || (c >= 0x0030 && c <= 0x0039) // [0-9] + || (c >= 0x0041 && c <= 0x005A) // [A-Z] + || (c >= 0x0061 && c <= 0x007A)) { // [a-z] + ret += css.charAt(i); + continue; + } + + ret += '\\' + css.charAt(i); + } + return ret; +} + + +/** + * Describes a mechanism for locating an element on the page. + * @final + */ +class By { + /** + * @param {string} using the name of the location strategy to use. + * @param {string} value the value to search for. + */ + constructor(using, value) { + /** @type {string} */ + this.using = using; + + /** @type {string} */ + this.value = value; + } + + /** + * Locates elements that have a specific class name. + * + * @param {string} name The class name to search for. + * @return {!By} The new locator. + * @see http://www.w3.org/TR/2011/WD-html5-20110525/elements.html#classes + * @see http://www.w3.org/TR/CSS2/selector.html#class-html + */ + static className(name) { + let names = name.split(/\s+/g) + .filter(s => s.length > 0) + .map(s => escapeCss(s)); + return By.css('.' + names.join('.')); + } + + /** + * Locates elements using a CSS selector. + * + * @param {string} selector The CSS selector to use. + * @return {!By} The new locator. + * @see http://www.w3.org/TR/CSS2/selector.html + */ + static css(selector) { + return new By('css selector', selector); + } + + /** + * Locates eleemnts by the ID attribute. This locator uses the CSS selector + * `*[id="$ID"]`, _not_ `document.getElementById`. + * + * @param {string} id The ID to search for. + * @return {!By} The new locator. + */ + static id(id) { + return By.css('*[id="' + escapeCss(id) + '"]'); + } + + /** + * Locates link elements whose + * {@linkplain webdriver.WebElement#getText visible text} matches the given + * string. + * + * @param {string} text The link text to search for. + * @return {!By} The new locator. + */ + static linkText(text) { + return new By('link text', text); + } + + /** + * Locates an elements by evaluating a + * {@linkplain webdriver.WebDriver#executeScript JavaScript expression}. + * The result of this expression must be an element or list of elements. + * + * @param {!(string|Function)} script The script to execute. + * @param {...*} var_args The arguments to pass to the script. + * @return {function(!./webdriver.WebDriver): !./promise.Promise} + * A new JavaScript-based locator function. + */ + static js(script, var_args) { + let args = Array.prototype.slice.call(arguments, 0); + return function(driver) { + return driver.executeScript.apply(driver, args); + }; + } + + /** + * Locates elements whose `name` attribute has the given value. + * + * @param {string} name The name attribute to search for. + * @return {!By} The new locator. + */ + static name(name) { + return By.css('*[name="' + escapeCss(name) + '"]'); + } + + /** + * Locates link elements whose + * {@linkplain webdriver.WebElement#getText visible text} contains the given + * substring. + * + * @param {string} text The substring to check for in a link's visible text. + * @return {!By} The new locator. + */ + static partialLinkText(text) { + return new By('partial link text', text); + } + + /** + * Locates elements with a given tag name. + * + * @param {string} name The tag name to search for. + * @return {!By} The new locator. + * @deprecated Use {@link By.css() By.css(tagName)} instead. + */ + static tagName(name) { + return By.css(name); + } + + /** + * Locates elements matching a XPath selector. Care should be taken when + * using an XPath selector with a {@link webdriver.WebElement} as WebDriver + * will respect the context in the specified in the selector. For example, + * given the selector `//div`, WebDriver will search from the document root + * regardless of whether the locator was used with a WebElement. + * + * @param {string} xpath The XPath selector to use. + * @return {!By} The new locator. + * @see http://www.w3.org/TR/xpath/ + */ + static xpath(xpath) { + return new By('xpath', xpath); + } + + /** @override */ + toString() { + // The static By.name() overrides this.constructor.name. Shame... + return `By(${this.using}, ${this.value})`; + } +} + + +/** + * Checks if a value is a valid locator. + * @param {!(By|Function|ByHash)} locator The value to check. + * @return {!(By|Function)} The valid locator. + * @throws {TypeError} If the given value does not define a valid locator + * strategy. + */ +function check(locator) { + if (locator instanceof By || typeof locator === 'function') { + return locator; + } + for (let key in locator) { + if (locator.hasOwnProperty(key) && By.hasOwnProperty(key)) { + return By[key](locator[key]); + } + } + throw new TypeError('Invalid locator'); +} + + + +// PUBLIC API + + +exports.By = By; +exports.checkedLocator = check; diff --git a/www/node_modules/selenium-webdriver/lib/capabilities.js b/www/node_modules/selenium-webdriver/lib/capabilities.js new file mode 100644 index 0000000..d5333fe --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/capabilities.js @@ -0,0 +1,404 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * @fileoverview Defines types related to describing the capabilities of a + * WebDriver session. + */ + +const Symbols = require('./symbols'); + + +/** + * Recognized browser names. + * @enum {string} + */ +const Browser = { + ANDROID: 'android', + CHROME: 'chrome', + EDGE: 'MicrosoftEdge', + FIREFOX: 'firefox', + IE: 'internet explorer', + INTERNET_EXPLORER: 'internet explorer', + IPAD: 'iPad', + IPHONE: 'iPhone', + OPERA: 'opera', + PHANTOM_JS: 'phantomjs', + SAFARI: 'safari', + HTMLUNIT: 'htmlunit' +}; + + +/** + * Common Capability keys. + * @enum {string} + */ +const Capability = { + + /** + * Indicates whether a driver should accept all SSL certs by default. This + * capability only applies when requesting a new session. To query whether + * a driver can handle insecure SSL certs, see {@link #SECURE_SSL}. + */ + ACCEPT_SSL_CERTS: 'acceptSslCerts', + + + /** + * The browser name. Common browser names are defined in the {@link Browser} + * enum. + */ + BROWSER_NAME: 'browserName', + + /** + * Defines how elements should be scrolled into the viewport for interaction. + * This capability will be set to zero (0) if elements are aligned with the + * top of the viewport, or one (1) if aligned with the bottom. The default + * behavior is to align with the top of the viewport. + */ + ELEMENT_SCROLL_BEHAVIOR: 'elementScrollBehavior', + + /** + * Whether the driver is capable of handling modal alerts (e.g. alert, + * confirm, prompt). To define how a driver should handle alerts, + * use {@link #UNEXPECTED_ALERT_BEHAVIOR}. + */ + HANDLES_ALERTS: 'handlesAlerts', + + /** + * Key for the logging driver logging preferences. + */ + LOGGING_PREFS: 'loggingPrefs', + + /** + * Whether this session generates native events when simulating user input. + */ + NATIVE_EVENTS: 'nativeEvents', + + /** + * Describes the platform the browser is running on. Will be one of + * ANDROID, IOS, LINUX, MAC, UNIX, or WINDOWS. When requesting a + * session, ANY may be used to indicate no platform preference (this is + * semantically equivalent to omitting the platform capability). + */ + PLATFORM: 'platform', + + /** + * Describes the proxy configuration to use for a new WebDriver session. + */ + PROXY: 'proxy', + + /** Whether the driver supports changing the brower's orientation. */ + ROTATABLE: 'rotatable', + + /** + * Whether a driver is only capable of handling secure SSL certs. To request + * that a driver accept insecure SSL certs by default, use + * {@link #ACCEPT_SSL_CERTS}. + */ + SECURE_SSL: 'secureSsl', + + /** Whether the driver supports manipulating the app cache. */ + SUPPORTS_APPLICATION_CACHE: 'applicationCacheEnabled', + + /** Whether the driver supports locating elements with CSS selectors. */ + SUPPORTS_CSS_SELECTORS: 'cssSelectorsEnabled', + + /** Whether the browser supports JavaScript. */ + SUPPORTS_JAVASCRIPT: 'javascriptEnabled', + + /** Whether the driver supports controlling the browser's location info. */ + SUPPORTS_LOCATION_CONTEXT: 'locationContextEnabled', + + /** Whether the driver supports taking screenshots. */ + TAKES_SCREENSHOT: 'takesScreenshot', + + /** + * Defines how the driver should handle unexpected alerts. The value should + * be one of "accept", "dismiss", or "ignore. + */ + UNEXPECTED_ALERT_BEHAVIOR: 'unexpectedAlertBehavior', + + /** Defines the browser version. */ + VERSION: 'version' +}; + + +/** + * Describes how a proxy should be configured for a WebDriver session. + * Proxy configuration object, as defined by the WebDriver wire protocol. + * @typedef {( + * {proxyType: string}| + * {proxyType: string, + * proxyAutoconfigUrl: string}| + * {proxyType: string, + * ftpProxy: string, + * httpProxy: string, + * sslProxy: string, + * noProxy: string})} + */ +var ProxyConfig; + + +/** + * Converts a generic hash object to a map. + * @param {!Object} hash The hash object. + * @return {!Map} The converted map. + */ +function toMap(hash) { + let m = new Map; + for (let key in hash) { + if (hash.hasOwnProperty(key)) { + m.set(key, hash[key]); + } + } + return m; +} + + +/** + * Describes a set of capabilities for a WebDriver session. + */ +class Capabilities extends Map { + /** + * @param {(Capabilities|Map|Object)=} opt_other Another set of + * capabilities to initialize this instance from. + */ + constructor(opt_other) { + if (opt_other && !(opt_other instanceof Map)) { + opt_other = toMap(opt_other); + } + super(opt_other); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Android. + */ + static android() { + return new Capabilities() + .set(Capability.BROWSER_NAME, Browser.ANDROID) + .set(Capability.PLATFORM, 'ANDROID'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Chrome. + */ + static chrome() { + return new Capabilities().set(Capability.BROWSER_NAME, Browser.CHROME); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Microsoft Edge. + */ + static edge() { + return new Capabilities() + .set(Capability.BROWSER_NAME, Browser.EDGE) + .set(Capability.PLATFORM, 'WINDOWS'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Firefox. + */ + static firefox() { + return new Capabilities().set(Capability.BROWSER_NAME, Browser.FIREFOX); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Internet Explorer. + */ + static ie() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.INTERNET_EXPLORER). + set(Capability.PLATFORM, 'WINDOWS'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for iPad. + */ + static ipad() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.IPAD). + set(Capability.PLATFORM, 'MAC'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for iPhone. + */ + static iphone() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.IPHONE). + set(Capability.PLATFORM, 'MAC'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Opera. + */ + static opera() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.OPERA); + } + + /** + * @return {!Capabilities} A basic set of capabilities for PhantomJS. + */ + static phantomjs() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.PHANTOM_JS); + } + + /** + * @return {!Capabilities} A basic set of capabilities for Safari. + */ + static safari() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.SAFARI). + set(Capability.PLATFORM, 'MAC'); + } + + /** + * @return {!Capabilities} A basic set of capabilities for HTMLUnit. + */ + static htmlunit() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.HTMLUNIT); + } + + /** + * @return {!Capabilities} A basic set of capabilities for HTMLUnit + * with enabled Javascript. + */ + static htmlunitwithjs() { + return new Capabilities(). + set(Capability.BROWSER_NAME, Browser.HTMLUNIT). + set(Capability.SUPPORTS_JAVASCRIPT, true); + } + + /** + * @return {!Object} The JSON representation of this instance. + * Note, the returned object may contain nested promised values. + */ + [Symbols.serialize]() { + let ret = {}; + for (let key of this.keys()) { + let cap = this.get(key); + if (cap) { + ret[key] = cap; + } + } + return ret; + } + + /** + * Merges another set of capabilities into this instance. + * @param {!(Capabilities|Map|Object)} other The other + * set of capabilities to merge. + * @return {!Capabilities} A self reference. + */ + merge(other) { + if (!other) { + throw new TypeError('no capabilities provided for merge'); + } + + if (!(other instanceof Map)) { + other = toMap(other); + } + + for (let key of other.keys()) { + this.set(key, other.get(key)); + } + + return this; + } + + /** + * @param {string} key The capability key. + * @param {*} value The capability value. + * @return {!Capabilities} A self reference. + * @throws {TypeError} If the `key` is not a string. + * @override + */ + set(key, value) { + if (typeof key !== 'string') { + throw new TypeError('Capability keys must be strings: ' + typeof key); + } + super.set(key, value); + return this; + } + + /** + * Sets the logging preferences. Preferences may be specified as a + * {@link ./logging.Preferences} instance, or a as a map of log-type to + * log-level. + * @param {!(./logging.Preferences|Object)} prefs The logging + * preferences. + * @return {!Capabilities} A self reference. + */ + setLoggingPrefs(prefs) { + return this.set(Capability.LOGGING_PREFS, prefs); + } + + /** + * Sets the proxy configuration for this instance. + * @param {ProxyConfig} proxy The desired proxy configuration. + * @return {!Capabilities} A self reference. + */ + setProxy(proxy) { + return this.set(Capability.PROXY, proxy); + } + + /** + * Sets whether native events should be used. + * @param {boolean} enabled Whether to enable native events. + * @return {!Capabilities} A self reference. + */ + setEnableNativeEvents(enabled) { + return this.set(Capability.NATIVE_EVENTS, enabled); + } + + /** + * Sets how elements should be scrolled into view for interaction. + * @param {number} behavior The desired scroll behavior: either 0 to align + * with the top of the viewport or 1 to align with the bottom. + * @return {!Capabilities} A self reference. + */ + setScrollBehavior(behavior) { + return this.set(Capability.ELEMENT_SCROLL_BEHAVIOR, behavior); + } + + /** + * Sets the default action to take with an unexpected alert before returning + * an error. + * @param {string} behavior The desired behavior; should be "accept", + * "dismiss", or "ignore". Defaults to "dismiss". + * @return {!Capabilities} A self reference. + */ + setAlertBehavior(behavior) { + return this.set(Capability.UNEXPECTED_ALERT_BEHAVIOR, behavior); + } +} + + +// PUBLIC API + + +exports.Browser = Browser; +exports.Capabilities = Capabilities; +exports.Capability = Capability; + +/** @typedef {ProxyConfig} */ +exports.ProxyConfig = ProxyConfig; diff --git a/www/node_modules/selenium-webdriver/lib/command.js b/www/node_modules/selenium-webdriver/lib/command.js new file mode 100644 index 0000000..188167f --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/command.js @@ -0,0 +1,263 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Contains several classes for handling commands. + */ + +'use strict'; + +const promise = require('./promise'); + + +/** + * Describes a command to execute. + * @final + */ +class Command { + /** @param {string} name The name of this command. */ + constructor(name) { + /** @private {string} */ + this.name_ = name; + + /** @private {!Object<*>} */ + this.parameters_ = {}; + } + + /** @return {string} This command's name. */ + getName() { + return this.name_; + } + + /** + * Sets a parameter to send with this command. + * @param {string} name The parameter name. + * @param {*} value The parameter value. + * @return {!Command} A self reference. + */ + setParameter(name, value) { + this.parameters_[name] = value; + return this; + } + + /** + * Sets the parameters for this command. + * @param {!Object<*>} parameters The command parameters. + * @return {!Command} A self reference. + */ + setParameters(parameters) { + this.parameters_ = parameters; + return this; + } + + /** + * Returns a named command parameter. + * @param {string} key The parameter key to look up. + * @return {*} The parameter value, or undefined if it has not been set. + */ + getParameter(key) { + return this.parameters_[key]; + } + + /** + * @return {!Object<*>} The parameters to send with this command. + */ + getParameters() { + return this.parameters_; + } +} + + +/** + * Enumeration of predefined names command names that all command processors + * will support. + * @enum {string} + */ +// TODO: Delete obsolete command names. +const Name = { + GET_SERVER_STATUS: 'getStatus', + + NEW_SESSION: 'newSession', + GET_SESSIONS: 'getSessions', + DESCRIBE_SESSION: 'getSessionCapabilities', + + CLOSE: 'close', + QUIT: 'quit', + + GET_CURRENT_URL: 'getCurrentUrl', + GET: 'get', + GO_BACK: 'goBack', + GO_FORWARD: 'goForward', + REFRESH: 'refresh', + + ADD_COOKIE: 'addCookie', + GET_COOKIE: 'getCookie', + GET_ALL_COOKIES: 'getCookies', + DELETE_COOKIE: 'deleteCookie', + DELETE_ALL_COOKIES: 'deleteAllCookies', + + GET_ACTIVE_ELEMENT: 'getActiveElement', + FIND_ELEMENT: 'findElement', + FIND_ELEMENTS: 'findElements', + FIND_CHILD_ELEMENT: 'findChildElement', + FIND_CHILD_ELEMENTS: 'findChildElements', + + CLEAR_ELEMENT: 'clearElement', + CLICK_ELEMENT: 'clickElement', + SEND_KEYS_TO_ELEMENT: 'sendKeysToElement', + SUBMIT_ELEMENT: 'submitElement', + + GET_CURRENT_WINDOW_HANDLE: 'getCurrentWindowHandle', + GET_WINDOW_HANDLES: 'getWindowHandles', + GET_WINDOW_POSITION: 'getWindowPosition', + SET_WINDOW_POSITION: 'setWindowPosition', + GET_WINDOW_SIZE: 'getWindowSize', + SET_WINDOW_SIZE: 'setWindowSize', + MAXIMIZE_WINDOW: 'maximizeWindow', + + SWITCH_TO_WINDOW: 'switchToWindow', + SWITCH_TO_FRAME: 'switchToFrame', + GET_PAGE_SOURCE: 'getPageSource', + GET_TITLE: 'getTitle', + + EXECUTE_SCRIPT: 'executeScript', + EXECUTE_ASYNC_SCRIPT: 'executeAsyncScript', + + GET_ELEMENT_TEXT: 'getElementText', + GET_ELEMENT_TAG_NAME: 'getElementTagName', + IS_ELEMENT_SELECTED: 'isElementSelected', + IS_ELEMENT_ENABLED: 'isElementEnabled', + IS_ELEMENT_DISPLAYED: 'isElementDisplayed', + GET_ELEMENT_LOCATION: 'getElementLocation', + GET_ELEMENT_LOCATION_IN_VIEW: 'getElementLocationOnceScrolledIntoView', + GET_ELEMENT_SIZE: 'getElementSize', + GET_ELEMENT_ATTRIBUTE: 'getElementAttribute', + GET_ELEMENT_VALUE_OF_CSS_PROPERTY: 'getElementValueOfCssProperty', + ELEMENT_EQUALS: 'elementEquals', + + SCREENSHOT: 'screenshot', + TAKE_ELEMENT_SCREENSHOT: 'takeElementScreenshot', + IMPLICITLY_WAIT: 'implicitlyWait', + SET_SCRIPT_TIMEOUT: 'setScriptTimeout', + SET_TIMEOUT: 'setTimeout', + + ACCEPT_ALERT: 'acceptAlert', + DISMISS_ALERT: 'dismissAlert', + GET_ALERT_TEXT: 'getAlertText', + SET_ALERT_TEXT: 'setAlertValue', + + EXECUTE_SQL: 'executeSQL', + GET_LOCATION: 'getLocation', + SET_LOCATION: 'setLocation', + GET_APP_CACHE: 'getAppCache', + GET_APP_CACHE_STATUS: 'getStatus', + CLEAR_APP_CACHE: 'clearAppCache', + IS_BROWSER_ONLINE: 'isBrowserOnline', + SET_BROWSER_ONLINE: 'setBrowserOnline', + + GET_LOCAL_STORAGE_ITEM: 'getLocalStorageItem', + GET_LOCAL_STORAGE_KEYS: 'getLocalStorageKeys', + SET_LOCAL_STORAGE_ITEM: 'setLocalStorageItem', + REMOVE_LOCAL_STORAGE_ITEM: 'removeLocalStorageItem', + CLEAR_LOCAL_STORAGE: 'clearLocalStorage', + GET_LOCAL_STORAGE_SIZE: 'getLocalStorageSize', + + GET_SESSION_STORAGE_ITEM: 'getSessionStorageItem', + GET_SESSION_STORAGE_KEYS: 'getSessionStorageKey', + SET_SESSION_STORAGE_ITEM: 'setSessionStorageItem', + REMOVE_SESSION_STORAGE_ITEM: 'removeSessionStorageItem', + CLEAR_SESSION_STORAGE: 'clearSessionStorage', + GET_SESSION_STORAGE_SIZE: 'getSessionStorageSize', + + SET_SCREEN_ORIENTATION: 'setScreenOrientation', + GET_SCREEN_ORIENTATION: 'getScreenOrientation', + + // These belong to the Advanced user interactions - an element is + // optional for these commands. + CLICK: 'mouseClick', + DOUBLE_CLICK: 'mouseDoubleClick', + MOUSE_DOWN: 'mouseButtonDown', + MOUSE_UP: 'mouseButtonUp', + MOVE_TO: 'mouseMoveTo', + SEND_KEYS_TO_ACTIVE_ELEMENT: 'sendKeysToActiveElement', + + // These belong to the Advanced Touch API + TOUCH_SINGLE_TAP: 'touchSingleTap', + TOUCH_DOWN: 'touchDown', + TOUCH_UP: 'touchUp', + TOUCH_MOVE: 'touchMove', + TOUCH_SCROLL: 'touchScroll', + TOUCH_DOUBLE_TAP: 'touchDoubleTap', + TOUCH_LONG_PRESS: 'touchLongPress', + TOUCH_FLICK: 'touchFlick', + + GET_AVAILABLE_LOG_TYPES: 'getAvailableLogTypes', + GET_LOG: 'getLog', + GET_SESSION_LOGS: 'getSessionLogs', + + // Non-standard commands used by the standalone Selenium server. + UPLOAD_FILE: 'uploadFile' +}; + + + +/** + * Handles the execution of WebDriver {@link Command commands}. + * @interface + */ +class Executor { + /** + * Executes the given {@code command}. If there is an error executing the + * command, the provided callback will be invoked with the offending error. + * Otherwise, the callback will be invoked with a null Error and non-null + * response object. + * + * @param {!Command} command The command to execute. + * @return {!promise.Promise} A promise that will be fulfilled with + * the command result. + */ + execute(command) {} +} + + +/** + * Wraps a promised {@link Executor}, ensuring no commands are executed until + * the wrapped executor has been fully resolved. + * @implements {Executor} + */ +class DeferredExecutor { + /** + * @param {!promise.Promise} delegate The promised delegate, which + * may be provided by any promise-like thenable object. + */ + constructor(delegate) { + /** @override */ + this.execute = function(command) { + return delegate.then(executor => executor.execute(command)); + }; + } +} + + + +// PUBLIC API + + +exports.Command = Command; +exports.Name = Name; +exports.Executor = Executor; +exports.DeferredExecutor = DeferredExecutor; diff --git a/www/node_modules/selenium-webdriver/lib/devmode.js b/www/node_modules/selenium-webdriver/lib/devmode.js new file mode 100644 index 0000000..4862c6a --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/devmode.js @@ -0,0 +1,34 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Module used to detect if scripts are loaded from the Selenium + * project repo instead of from a deployed package. + */ + +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +/** + * @const {boolean} + */ +module.exports = (function() { + let buildDescFile = path.join(__dirname, '..', '..', 'build.desc'); + return fs.existsSync(buildDescFile); +})(); diff --git a/www/node_modules/selenium-webdriver/lib/events.js b/www/node_modules/selenium-webdriver/lib/events.js new file mode 100644 index 0000000..fc5cfa6 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/events.js @@ -0,0 +1,210 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * Describes an event listener registered on an {@linkplain EventEmitter}. + */ +class Listener { + /** + * @param {!Function} fn The acutal listener function. + * @param {(Object|undefined)} scope The object in whose scope to invoke the + * listener. + * @param {boolean} oneshot Whether this listener should only be used once. + */ + constructor(fn, scope, oneshot) { + Object.defineProperties(this, { + fn: {value: fn}, + scope: {value: scope}, + oneshot: {value: oneshot} + }); + } +} + + +/** @type {!WeakMap>>} */ +const EVENTS = new WeakMap; + + +/** + * Object that can emit events for others to listen for. + */ +class EventEmitter { + /** + * Fires an event and calls all listeners. + * @param {string} type The type of event to emit. + * @param {...*} var_args Any arguments to pass to each listener. + */ + emit(type, var_args) { + let events = EVENTS.get(this); + if (!events) { + return; + } + + let args = Array.prototype.slice.call(arguments, 1); + + let listeners = events.get(type); + if (listeners) { + for (let listener of listeners) { + listener.fn.apply(listener.scope, args); + if (listener.oneshot) { + listeners.delete(listener); + } + } + } + } + + /** + * Returns a mutable list of listeners for a specific type of event. + * @param {string} type The type of event to retrieve the listeners for. + * @return {!Set} The registered listeners for the given event + * type. + */ + listeners(type) { + let events = EVENTS.get(this); + if (!events) { + events = new Map; + EVENTS.set(this, events); + } + + let listeners = events.get(type); + if (!listeners) { + listeners = new Set; + events.set(type, listeners); + } + return listeners; + } + + /** + * Registers a listener. + * @param {string} type The type of event to listen for. + * @param {!Function} fn The function to invoke when the event is fired. + * @param {Object=} opt_self The object in whose scope to invoke the listener. + * @param {boolean=} opt_oneshot Whether the listener should b (e removed after + * the first event is fired. + * @return {!EventEmitter} A self reference. + * @private + */ + addListener_(type, fn, opt_self, opt_oneshot) { + let listeners = this.listeners(type); + for (let listener of listeners) { + if (listener.fn === fn) { + return this; + } + } + listeners.add(new Listener(fn, opt_self || undefined, !!opt_oneshot)); + return this; + } + + /** + * Registers a listener. + * @param {string} type The type of event to listen for. + * @param {!Function} fn The function to invoke when the event is fired. + * @param {Object=} opt_self The object in whose scope to invoke the listener. + * @return {!EventEmitter} A self reference. + */ + addListener(type, fn, opt_self) { + return this.addListener_(type, fn, opt_self, false); + } + + /** + * Registers a one-time listener which will be called only the first time an + * event is emitted, after which it will be removed. + * @param {string} type The type of event to listen for. + * @param {!Function} fn The function to invoke when the event is fired. + * @param {Object=} opt_self The object in whose scope to invoke the listener. + * @return {!EventEmitter} A self reference. + */ + once(type, fn, opt_self) { + return this.addListener_(type, fn, opt_self, true); + } + + /** + * An alias for {@link #addListener() addListener()}. + * @param {string} type The type of event to listen for. + * @param {!Function} fn The function to invoke when the event is fired. + * @param {Object=} opt_self The object in whose scope to invoke the listener. + * @return {!EventEmitter} A self reference. + */ + on(type, fn, opt_self) { + return this.addListener(type, fn, opt_self); + } + + /** + * Removes a previously registered event listener. + * @param {string} type The type of event to unregister. + * @param {!Function} listenerFn The handler function to remove. + * @return {!EventEmitter} A self reference. + */ + removeListener(type, listenerFn) { + if (typeof type !== 'string' || typeof listenerFn !== 'function') { + throw TypeError('invalid args: expected (string, function), got (' + + (typeof type) + ', ' + (typeof listenerFn) + ')'); + } + + let events = EVENTS.get(this); + if (!events) { + return this; + } + + let listeners = events.get(type); + if (!listeners) { + return this; + } + + let match; + for (let listener of listeners) { + if (listener.fn === listenerFn) { + match = listener; + break; + } + } + if (match) { + listeners.delete(match); + if (!listeners.size) { + events.delete(type); + } + } + return this; + } + + /** + * Removes all listeners for a specific type of event. If no event is + * specified, all listeners across all types will be removed. + * @param {string=} opt_type The type of event to remove listeners from. + * @return {!EventEmitter} A self reference. + */ + removeAllListeners(opt_type) { + let events = EVENTS.get(this); + if (events) { + if (typeof opt_type === 'string') { + events.delete(opt_type); + } else { + EVENTS.delete(this); + } + } + return this; + } +} + + +// PUBLIC API + + +exports.EventEmitter = EventEmitter; +exports.Listener = Listener; diff --git a/www/node_modules/selenium-webdriver/lib/firefox/amd64/libnoblur64.so b/www/node_modules/selenium-webdriver/lib/firefox/amd64/libnoblur64.so new file mode 100644 index 0000000..916e530 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/firefox/amd64/libnoblur64.so differ diff --git a/www/node_modules/selenium-webdriver/lib/firefox/i386/libnoblur.so b/www/node_modules/selenium-webdriver/lib/firefox/i386/libnoblur.so new file mode 100644 index 0000000..8e7db8d Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/firefox/i386/libnoblur.so differ diff --git a/www/node_modules/selenium-webdriver/lib/firefox/webdriver.json b/www/node_modules/selenium-webdriver/lib/firefox/webdriver.json new file mode 100644 index 0000000..4a30492 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/firefox/webdriver.json @@ -0,0 +1,78 @@ +{ + "frozen": { + "app.update.auto": false, + "app.update.enabled": false, + "browser.displayedE10SNotice": 4, + "browser.download.manager.showWhenStarting": false, + "browser.EULA.override": true, + "browser.EULA.3.accepted": true, + "browser.link.open_external": 2, + "browser.link.open_newwindow": 2, + "browser.offline": false, + "browser.reader.detectedFirstArticle": true, + "browser.safebrowsing.enabled": false, + "browser.safebrowsing.malware.enabled": false, + "browser.search.update": false, + "browser.selfsupport.url" : "", + "browser.sessionstore.resume_from_crash": false, + "browser.shell.checkDefaultBrowser": false, + "browser.tabs.warnOnClose": false, + "browser.tabs.warnOnOpen": false, + "datareporting.healthreport.service.enabled": false, + "datareporting.healthreport.uploadEnabled": false, + "datareporting.healthreport.service.firstRun": false, + "datareporting.healthreport.logging.consoleEnabled": false, + "datareporting.policy.dataSubmissionEnabled": false, + "datareporting.policy.dataSubmissionPolicyAccepted": false, + "devtools.errorconsole.enabled": true, + "dom.disable_open_during_load": false, + "extensions.autoDisableScopes": 10, + "extensions.blocklist.enabled": false, + "extensions.checkCompatibility.nightly": false, + "extensions.logging.enabled": true, + "extensions.update.enabled": false, + "extensions.update.notifyUser": false, + "javascript.enabled": true, + "network.manage-offline-status": false, + "network.http.phishy-userpass-length": 255, + "offline-apps.allow_by_default": true, + "prompts.tab_modal.enabled": false, + "security.csp.enable": false, + "security.fileuri.origin_policy": 3, + "security.fileuri.strict_origin_policy": false, + "security.warn_entering_secure": false, + "security.warn_entering_secure.show_once": false, + "security.warn_entering_weak": false, + "security.warn_entering_weak.show_once": false, + "security.warn_leaving_secure": false, + "security.warn_leaving_secure.show_once": false, + "security.warn_submit_insecure": false, + "security.warn_viewing_mixed": false, + "security.warn_viewing_mixed.show_once": false, + "signon.rememberSignons": false, + "toolkit.networkmanager.disable": true, + "toolkit.telemetry.prompted": 2, + "toolkit.telemetry.enabled": false, + "toolkit.telemetry.rejected": true, + "xpinstall.signatures.required": false, + "xpinstall.whitelist.required": false + }, + "mutable": { + "browser.dom.window.dump.enabled": true, + "browser.laterrun.enabled": false, + "browser.newtab.url": "about:blank", + "browser.newtabpage.enabled": false, + "browser.startup.page": 0, + "browser.startup.homepage": "about:blank", + "browser.usedOnWindows10.introURL": "about:blank", + "dom.max_chrome_script_run_time": 30, + "dom.max_script_run_time": 30, + "dom.report_all_js_exceptions": true, + "javascript.options.showInConsole": true, + "network.http.max-connections-per-server": 10, + "startup.homepage_welcome_url": "about:blank", + "startup.homepage_welcome_url.additional": "about:blank", + "webdriver_accept_untrusted_certs": true, + "webdriver_assume_untrusted_issuer": true + } +} diff --git a/www/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi b/www/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi new file mode 100644 index 0000000..74182e9 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/firefox/webdriver.xpi differ diff --git a/www/node_modules/selenium-webdriver/lib/input.js b/www/node_modules/selenium-webdriver/lib/input.js new file mode 100644 index 0000000..e6f598c --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/input.js @@ -0,0 +1,172 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * @fileoverview Defines types related to user input with the WebDriver API. + */ + +const promise = require('./promise'); + + +/** + * Enumeration of the buttons used in the advanced interactions API. + * @enum {number} + */ +const Button = { + LEFT: 0, + MIDDLE: 1, + RIGHT: 2 +}; + + + +/** + * Representations of pressable keys that aren't text. These are stored in + * the Unicode PUA (Private Use Area) code points, 0xE000-0xF8FF. Refer to + * http://www.google.com.au/search?&q=unicode+pua&btnG=Search + * + * @enum {string} + */ +const Key = { + NULL: '\uE000', + CANCEL: '\uE001', // ^break + HELP: '\uE002', + BACK_SPACE: '\uE003', + TAB: '\uE004', + CLEAR: '\uE005', + RETURN: '\uE006', + ENTER: '\uE007', + SHIFT: '\uE008', + CONTROL: '\uE009', + ALT: '\uE00A', + PAUSE: '\uE00B', + ESCAPE: '\uE00C', + SPACE: '\uE00D', + PAGE_UP: '\uE00E', + PAGE_DOWN: '\uE00F', + END: '\uE010', + HOME: '\uE011', + ARROW_LEFT: '\uE012', + LEFT: '\uE012', + ARROW_UP: '\uE013', + UP: '\uE013', + ARROW_RIGHT: '\uE014', + RIGHT: '\uE014', + ARROW_DOWN: '\uE015', + DOWN: '\uE015', + INSERT: '\uE016', + DELETE: '\uE017', + SEMICOLON: '\uE018', + EQUALS: '\uE019', + + NUMPAD0: '\uE01A', // number pad keys + NUMPAD1: '\uE01B', + NUMPAD2: '\uE01C', + NUMPAD3: '\uE01D', + NUMPAD4: '\uE01E', + NUMPAD5: '\uE01F', + NUMPAD6: '\uE020', + NUMPAD7: '\uE021', + NUMPAD8: '\uE022', + NUMPAD9: '\uE023', + MULTIPLY: '\uE024', + ADD: '\uE025', + SEPARATOR: '\uE026', + SUBTRACT: '\uE027', + DECIMAL: '\uE028', + DIVIDE: '\uE029', + + F1: '\uE031', // function keys + F2: '\uE032', + F3: '\uE033', + F4: '\uE034', + F5: '\uE035', + F6: '\uE036', + F7: '\uE037', + F8: '\uE038', + F9: '\uE039', + F10: '\uE03A', + F11: '\uE03B', + F12: '\uE03C', + + COMMAND: '\uE03D', // Apple command key + META: '\uE03D' // alias for Windows key +}; + + +/** + * Simulate pressing many keys at once in a "chord". Takes a sequence of + * {@linkplain Key keys} or strings, appends each of the values to a string, + * adds the chord termination key ({@link Key.NULL}) and returns the resulting + * string. + * + * Note: when the low-level webdriver key handlers see Keys.NULL, active + * modifier keys (CTRL/ALT/SHIFT/etc) release via a keyup event. + * + * @param {...string} var_args The key sequence to concatenate. + * @return {string} The null-terminated key sequence. + */ +Key.chord = function(var_args) { + return Array.prototype.slice.call(arguments, 0).join('') + Key.NULL; +}; + + +/** + * Used with {@link ./webelement.WebElement#sendKeys WebElement#sendKeys} on + * file input elements (``) to detect when the entered key + * sequence defines the path to a file. + * + * By default, {@linkplain ./webelement.WebElement WebElement's} will enter all + * key sequences exactly as entered. You may set a + * {@linkplain ./webdriver.WebDriver#setFileDetector file detector} on the + * parent WebDriver instance to define custom behavior for handling file + * elements. Of particular note is the + * {@link selenium-webdriver/remote.FileDetector}, which should be used when + * running against a remote + * [Selenium Server](http://docs.seleniumhq.org/download/). + */ +class FileDetector { + + /** + * Handles the file specified by the given path, preparing it for use with + * the current browser. If the path does not refer to a valid file, it will + * be returned unchanged, otherwisee a path suitable for use with the current + * browser will be returned. + * + * This default implementation is a no-op. Subtypes may override this function + * for custom tailored file handling. + * + * @param {!./webdriver.WebDriver} driver The driver for the current browser. + * @param {string} path The path to process. + * @return {!./promise.Promise} A promise for the processed file + * path. + * @package + */ + handleFile(driver, path) { + return promise.fulfilled(path); + } +} + + +// PUBLIC API + + +exports.Button = Button; +exports.Key = Key; +exports.FileDetector = FileDetector; diff --git a/www/node_modules/selenium-webdriver/lib/logging.js b/www/node_modules/selenium-webdriver/lib/logging.js new file mode 100644 index 0000000..6bdee3e --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/logging.js @@ -0,0 +1,668 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +/** + * @fileoverview Defines WebDriver's logging system. The logging system is + * broken into major components: local and remote logging. + * + * The local logging API, which is anchored by the {@linkplain Logger} class is + * similar to Java's logging API. Loggers, retrieved by + * {@linkplain #getLogger getLogger(name)}, use hierarchical, dot-delimited + * namespaces (e.g. "" > "webdriver" > "webdriver.logging"). Recorded log + * messages are represented by the {@linkplain Entry} class. You can capture log + * records by {@linkplain Logger#addHandler attaching} a handler function to the + * desired logger. For convenience, you can quickly enable logging to the + * console by simply calling {@linkplain #installConsoleHandler + * installConsoleHandler}. + * + * The [remote logging API](https://github.com/SeleniumHQ/selenium/wiki/Logging) + * allows you to retrieve logs from a remote WebDriver server. This API uses the + * {@link Preferences} class to define desired log levels prior to creating + * a WebDriver session: + * + * var prefs = new logging.Preferences(); + * prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG); + * + * var caps = Capabilities.chrome(); + * caps.setLoggingPrefs(prefs); + * // ... + * + * Remote log entries, also represented by the {@link Entry} class, may be + * retrieved via {@link webdriver.WebDriver.Logs}: + * + * driver.manage().logs().get(logging.Type.BROWSER) + * .then(function(entries) { + * entries.forEach(function(entry) { + * console.log('[%s] %s', entry.level.name, entry.message); + * }); + * }); + * + * **NOTE:** Only a few browsers support the remote logging API (notably + * Firefox and Chrome). Firefox supports basic logging functionality, while + * Chrome exposes robust + * [performance logging](https://sites.google.com/a/chromium.org/chromedriver/logging) + * options. Remote logging is still considered a non-standard feature, and the + * APIs exposed by this module for it are non-frozen. This module will be + * updated, possibly breaking backwards-compatibility, once logging is + * officially defined by the + * [W3C WebDriver spec](http://www.w3.org/TR/webdriver/). + */ + +/** + * Defines a message level that may be used to control logging output. + * + * @final + */ +class Level { + /** + * @param {string} name the level's name. + * @param {number} level the level's numeric value. + */ + constructor(name, level) { + if (level < 0) { + throw new TypeError('Level must be >= 0'); + } + + /** @private {string} */ + this.name_ = name; + + /** @private {number} */ + this.value_ = level; + } + + /** This logger's name. */ + get name() { + return this.name_; + } + + /** The numeric log level. */ + get value() { + return this.value_; + } + + /** @override */ + toString() { + return this.name; + } +} + +/** + * Indicates no log messages should be recorded. + * @const + */ +Level.OFF = new Level('OFF', Infinity); + + +/** + * Log messages with a level of `1000` or higher. + * @const + */ +Level.SEVERE = new Level('SEVERE', 1000); + + +/** + * Log messages with a level of `900` or higher. + * @const + */ +Level.WARNING = new Level('WARNING', 900); + + +/** + * Log messages with a level of `800` or higher. + * @const + */ +Level.INFO = new Level('INFO', 800); + + +/** + * Log messages with a level of `700` or higher. + * @const + */ +Level.DEBUG = new Level('DEBUG', 700); + + +/** + * Log messages with a level of `500` or higher. + * @const + */ +Level.FINE = new Level('FINE', 500); + + +/** + * Log messages with a level of `400` or higher. + * @const + */ +Level.FINER = new Level('FINER', 400); + + +/** + * Log messages with a level of `300` or higher. + * @const + */ +Level.FINEST = new Level('FINEST', 300); + + +/** + * Indicates all log messages should be recorded. + * @const + */ +Level.ALL = new Level('ALL', 0); + + +const ALL_LEVELS = /** !Set */new Set([ + Level.OFF, + Level.SEVERE, + Level.WARNING, + Level.INFO, + Level.DEBUG, + Level.FINE, + Level.FINER, + Level.FINEST, + Level.ALL +]); + + +const LEVELS_BY_NAME = /** !Map */ new Map([ + [Level.OFF.name, Level.OFF], + [Level.SEVERE.name, Level.SEVERE], + [Level.WARNING.name, Level.WARNING], + [Level.INFO.name, Level.INFO], + [Level.DEBUG.name, Level.DEBUG], + [Level.FINE.name, Level.FINE], + [Level.FINER.name, Level.FINER], + [Level.FINEST.name, Level.FINEST], + [Level.ALL.name, Level.ALL] +]); + + +/** + * Converts a level name or value to a {@link Level} value. If the name/value + * is not recognized, {@link Level.ALL} will be returned. + * + * @param {(number|string)} nameOrValue The log level name, or value, to + * convert. + * @return {!Level} The converted level. + */ +function getLevel(nameOrValue) { + if (typeof nameOrValue === 'string') { + return LEVELS_BY_NAME.get(nameOrValue) || Level.ALL; + } + if (typeof nameOrValue !== 'number') { + throw new TypeError('not a string or number'); + } + for (let level of ALL_LEVELS) { + if (nameOrValue >= level.value) { + return level; + } + } + return Level.ALL; +} + + +/** + * Describes a single log entry. + * + * @final + */ +class Entry { + /** + * @param {(!Level|string|number)} level The entry level. + * @param {string} message The log message. + * @param {number=} opt_timestamp The time this entry was generated, in + * milliseconds since 0:00:00, January 1, 1970 UTC. If omitted, the + * current time will be used. + * @param {string=} opt_type The log type, if known. + */ + constructor(level, message, opt_timestamp, opt_type) { + this.level = level instanceof Level ? level : getLevel(level); + this.message = message; + this.timestamp = + typeof opt_timestamp === 'number' ? opt_timestamp : Date.now(); + this.type = opt_type || ''; + } + + /** + * @return {{level: string, message: string, timestamp: number, + * type: string}} The JSON representation of this entry. + */ + toJSON() { + return { + 'level': this.level.name, + 'message': this.message, + 'timestamp': this.timestamp, + 'type': this.type + }; + } +} + + +/** @typedef {(string|function(): string)} */ +let Loggable; + + +/** + * An object used to log debugging messages. Loggers use a hierarchical, + * dot-separated naming scheme. For instance, "foo" is considered the parent of + * the "foo.bar" and an ancestor of "foo.bar.baz". + * + * Each logger may be assigned a {@linkplain #setLevel log level}, which + * controls which level of messages will be reported to the + * {@linkplain #addHandler handlers} attached to this instance. If a log level + * is not explicitly set on a logger, it will inherit its parent. + * + * This class should never be directly instantiated. Instead, users should + * obtain logger references using the {@linkplain ./logging.getLogger() + * getLogger()} function. + * + * @final + */ +class Logger { + /** + * @param {string} name the name of this logger. + * @param {Level=} opt_level the initial level for this logger. + */ + constructor(name, opt_level) { + /** @private {string} */ + this.name_ = name; + + /** @private {Level} */ + this.level_ = opt_level || null; + + /** @private {Logger} */ + this.parent_ = null; + + /** @private {Set} */ + this.handlers_ = null; + } + + /** @return {string} the name of this logger. */ + getName() { + return this.name_; + } + + /** + * @param {Level} level the new level for this logger, or `null` if the logger + * should inherit its level from its parent logger. + */ + setLevel(level) { + this.level_ = level; + } + + /** @return {Level} the log level for this logger. */ + getLevel() { + return this.level_; + } + + /** + * @return {!Level} the effective level for this logger. + */ + getEffectiveLevel() { + let logger = this; + let level; + do { + level = logger.level_; + logger = logger.parent_; + } while (logger && !level); + return level || Level.OFF; + } + + /** + * @param {!Level} level the level to check. + * @return {boolean} whether messages recorded at the given level are loggable + * by this instance. + */ + isLoggable(level) { + return level.value !== Level.OFF.value + && level.value >= this.getEffectiveLevel().value; + } + + /** + * Adds a handler to this logger. The handler will be invoked for each message + * logged with this instance, or any of its descendants. + * + * @param {function(!Entry)} handler the handler to add. + */ + addHandler(handler) { + if (!this.handlers_) { + this.handlers_ = new Set; + } + this.handlers_.add(handler); + } + + /** + * Removes a handler from this logger. + * + * @param {function(!Entry)} handler the handler to remove. + * @return {boolean} whether a handler was successfully removed. + */ + removeHandler(handler) { + if (!this.handlers_) { + return false; + } + return this.handlers_.delete(handler); + } + + /** + * Logs a message at the given level. The message may be defined as a string + * or as a function that will return the message. If a function is provided, + * it will only be invoked if this logger's + * {@linkplain #getEffectiveLevel() effective log level} includes the given + * `level`. + * + * @param {!Level} level the level at which to log the message. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + log(level, loggable) { + if (!this.isLoggable(level)) { + return; + } + let message = '[' + this.name_ + '] ' + + (typeof loggable === 'function' ? loggable() : loggable); + let entry = new Entry(level, message, Date.now()); + for (let logger = this; !!logger; logger = logger.parent_) { + if (logger.handlers_) { + for (let handler of logger.handlers_) { + handler(entry); + } + } + } + } + + /** + * Logs a message at the {@link Level.SEVERE} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + severe(loggable) { + this.log(Level.SEVERE, loggable); + } + + /** + * Logs a message at the {@link Level.WARNING} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + warning(loggable) { + this.log(Level.WARNING, loggable); + } + + /** + * Logs a message at the {@link Level.INFO} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + info(loggable) { + this.log(Level.INFO, loggable); + } + + /** + * Logs a message at the {@link Level.DEBUG} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + debug(loggable) { + this.log(Level.DEBUG, loggable); + } + + /** + * Logs a message at the {@link Level.FINE} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + fine(loggable) { + this.log(Level.FINE, loggable); + } + + /** + * Logs a message at the {@link Level.FINER} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + finer(loggable) { + this.log(Level.FINER, loggable); + } + + /** + * Logs a message at the {@link Level.FINEST} log level. + * @param {(string|function(): string)} loggable the message to log, or a + * function that will return the message. + */ + finest(loggable) { + this.log(Level.FINEST, loggable); + } +} + + +/** + * Maintains a collection of loggers. + * + * @final + */ +class LogManager { + constructor() { + /** @private {!Map} */ + this.loggers_ = new Map; + this.root_ = new Logger('', Level.OFF); + } + + /** + * Retrieves a named logger, creating it in the process. This function will + * implicitly create the requested logger, and any of its parents, if they + * do not yet exist. + * + * @param {string} name the logger's name. + * @return {!Logger} the requested logger. + */ + getLogger(name) { + if (!name) { + return this.root_; + } + let parent = this.root_; + for (let i = name.indexOf('.'); i != -1; i = name.indexOf('.', i + 1)) { + let parentName = name.substr(0, i); + parent = this.createLogger_(parentName, parent); + } + return this.createLogger_(name, parent); + } + + /** + * Creates a new logger. + * + * @param {string} name the logger's name. + * @param {!Logger} parent the logger's parent. + * @return {!Logger} the new logger. + * @private + */ + createLogger_(name, parent) { + if (this.loggers_.has(name)) { + return /** @type {!Logger} */(this.loggers_.get(name)); + } + let logger = new Logger(name, null); + logger.parent_ = parent; + this.loggers_.set(name, logger); + return logger; + } +} + + +const logManager = new LogManager; + + +/** + * Retrieves a named logger, creating it in the process. This function will + * implicitly create the requested logger, and any of its parents, if they + * do not yet exist. + * + * The log level will be unspecified for newly created loggers. Use + * {@link Logger#setLevel(level)} to explicitly set a level. + * + * @param {string} name the logger's name. + * @return {!Logger} the requested logger. + */ +function getLogger(name) { + return logManager.getLogger(name); +} + + +function pad(n) { + if (n > 10) { + return '' + n; + } else { + return '0' + n; + } +} + + +/** + * Logs all messages to the Console API. + * @param {!Entry} entry the entry to log. + */ +function consoleHandler(entry) { + if (typeof console === 'undefined' || !console) { + return; + } + + var timestamp = new Date(entry.timestamp); + var msg = + '[' + timestamp.getUTCFullYear() + '-' + + pad(timestamp.getUTCMonth() + 1) + '-' + + pad(timestamp.getUTCDate()) + 'T' + + pad(timestamp.getUTCHours()) + ':' + + pad(timestamp.getUTCMinutes()) + ':' + + pad(timestamp.getUTCSeconds()) + 'Z] ' + + '[' + entry.level.name + '] ' + + entry.message; + + var level = entry.level.value; + if (level >= Level.SEVERE.value) { + console.error(msg); + } else if (level >= Level.WARNING.value) { + console.warn(msg); + } else { + console.log(msg); + } +} + + +/** + * Adds the console handler to the given logger. The console handler will log + * all messages using the JavaScript Console API. + * + * @param {Logger=} opt_logger The logger to add the handler to; defaults + * to the root logger. + */ +function addConsoleHandler(opt_logger) { + let logger = opt_logger || logManager.root_; + logger.addHandler(consoleHandler); +} + + +/** + * Removes the console log handler from the given logger. + * + * @param {Logger=} opt_logger The logger to remove the handler from; defaults + * to the root logger. + * @see exports.addConsoleHandler + */ +function removeConsoleHandler(opt_logger) { + let logger = opt_logger || logManager.root_; + logger.removeHandler(consoleHandler); +} + + +/** + * Installs the console log handler on the root logger. + */ +function installConsoleHandler() { + addConsoleHandler(logManager.root_); +} + + +/** + * Common log types. + * @enum {string} + */ +const Type = { + /** Logs originating from the browser. */ + BROWSER: 'browser', + /** Logs from a WebDriver client. */ + CLIENT: 'client', + /** Logs from a WebDriver implementation. */ + DRIVER: 'driver', + /** Logs related to performance. */ + PERFORMANCE: 'performance', + /** Logs from the remote server. */ + SERVER: 'server' +}; + + +/** + * Describes the log preferences for a WebDriver session. + * + * @final + */ +class Preferences { + constructor() { + /** @private {!Map} */ + this.prefs_ = new Map; + } + + /** + * Sets the desired logging level for a particular log type. + * @param {(string|Type)} type The log type. + * @param {(!Level|string|number)} level The desired log level. + * @throws {TypeError} if `type` is not a `string`. + */ + setLevel(type, level) { + if (typeof type !== 'string') { + throw TypeError('specified log type is not a string: ' + typeof type); + } + this.prefs_.set(type, level instanceof Level ? level : getLevel(level)); + } + + /** + * Converts this instance to its JSON representation. + * @return {!Object} The JSON representation of this set of + * preferences. + */ + toJSON() { + let json = {}; + for (let key of this.prefs_.keys()) { + json[key] = this.prefs_.get(key).name; + } + return json; + } +} + + +// PUBLIC API + + +exports.Entry = Entry; +exports.Level = Level; +exports.LogManager = LogManager; +exports.Logger = Logger; +exports.Preferences = Preferences; +exports.Type = Type; +exports.addConsoleHandler = addConsoleHandler; +exports.getLevel = getLevel; +exports.getLogger = getLogger; +exports.installConsoleHandler = installConsoleHandler; +exports.removeConsoleHandler = removeConsoleHandler; diff --git a/www/node_modules/selenium-webdriver/lib/promise.js b/www/node_modules/selenium-webdriver/lib/promise.js new file mode 100644 index 0000000..905ec50 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/promise.js @@ -0,0 +1,3093 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview + * The promise module is centered around the {@linkplain ControlFlow}, a class + * that coordinates the execution of asynchronous tasks. The ControlFlow allows + * users to focus on the imperative commands for their script without worrying + * about chaining together every single asynchronous action, which can be + * tedious and verbose. APIs may be layered on top of the control flow to read + * as if they were synchronous. For instance, the core + * {@linkplain ./webdriver.WebDriver WebDriver} API is built on top of the + * control flow, allowing users to write + * + * driver.get('http://www.google.com/ncr'); + * driver.findElement({name: 'q'}).sendKeys('webdriver'); + * driver.findElement({name: 'btnGn'}).click(); + * + * instead of + * + * driver.get('http://www.google.com/ncr') + * .then(function() { + * return driver.findElement({name: 'q'}); + * }) + * .then(function(q) { + * return q.sendKeys('webdriver'); + * }) + * .then(function() { + * return driver.findElement({name: 'btnG'}); + * }) + * .then(function(btnG) { + * return btnG.click(); + * }); + * + * ## Tasks and Task Queues + * + * The control flow is based on the concept of tasks and task queues. Tasks are + * functions that define the basic unit of work for the control flow to execute. + * Each task is scheduled via {@link ControlFlow#execute()}, which will return + * a {@link ManagedPromise ManagedPromise} that will be resolved with the task's + * result. + * + * A task queue contains all of the tasks scheduled within a single turn of the + * [JavaScript event loop][JSEL]. The control flow will create a new task queue + * the first time a task is scheduled within an event loop. + * + * var flow = promise.controlFlow(); + * flow.execute(foo); // Creates a new task queue and inserts foo. + * flow.execute(bar); // Inserts bar into the same queue as foo. + * setTimeout(function() { + * flow.execute(baz); // Creates a new task queue and inserts baz. + * }, 0); + * + * Whenever the control flow creates a new task queue, it will automatically + * begin executing tasks in the next available turn of the event loop. This + * execution is scheduled using a "micro-task" timer, such as a (native) + * `ManagedPromise.then()` callback. + * + * setTimeout(() => console.log('a')); + * ManagedPromise.resolve().then(() => console.log('b')); // A native promise. + * flow.execute(() => console.log('c')); + * ManagedPromise.resolve().then(() => console.log('d')); + * setTimeout(() => console.log('fin')); + * // b + * // c + * // d + * // a + * // fin + * + * In the example above, b/c/d is logged before a/fin because native promises + * and this module use "micro-task" timers, which have a higher priority than + * "macro-tasks" like `setTimeout`. + * + * ## Task Execution + * + * Upon creating a task queue, and whenever an exisiting queue completes a task, + * the control flow will schedule a micro-task timer to process any scheduled + * tasks. This ensures no task is ever started within the same turn of the + * JavaScript event loop in which it was scheduled, nor is a task ever started + * within the same turn that another finishes. + * + * When the execution timer fires, a single task will be dequeued and executed. + * There are several important events that may occur while executing a task + * function: + * + * 1. A new task queue is created by a call to {@link ControlFlow#execute()}. + * Any tasks scheduled within this task queue are considered subtasks of the + * current task. + * 2. The task function throws an error. Any scheduled tasks are immediately + * discarded and the task's promised result (previously returned by + * {@link ControlFlow#execute()}) is immediately rejected with the thrown + * error. + * 3. The task function returns sucessfully. + * + * If a task function created a new task queue, the control flow will wait for + * that queue to complete before processing the task result. If the queue + * completes without error, the flow will settle the task's promise with the + * value originaly returned by the task function. On the other hand, if the task + * queue termintes with an error, the task's promise will be rejected with that + * error. + * + * flow.execute(function() { + * flow.execute(() => console.log('a')); + * flow.execute(() => console.log('b')); + * }); + * flow.execute(() => console.log('c')); + * // a + * // b + * // c + * + * ## ManagedPromise Integration + * + * In addition to the {@link ControlFlow} class, the promise module also exports + * a [ManagedPromise/A+] {@linkplain ManagedPromise implementation} that is deeply + * integrated with the ControlFlow. First and foremost, each promise + * {@linkplain ManagedPromise#then() callback} is scheduled with the + * control flow as a task. As a result, each callback is invoked in its own turn + * of the JavaScript event loop with its own task queue. If any tasks are + * scheduled within a callback, the callback's promised result will not be + * settled until the task queue has completed. + * + * promise.fulfilled().then(function() { + * flow.execute(function() { + * console.log('b'); + * }); + * }).then(() => console.log('a')); + * // b + * // a + * + * ### Scheduling ManagedPromise Callbacks + * + * How callbacks are scheduled in the control flow depends on when they are + * attached to the promise. Callbacks attached to a _previously_ resolved + * promise are immediately enqueued as subtasks of the currently running task. + * + * var p = promise.fulfilled(); + * flow.execute(function() { + * flow.execute(() => console.log('A')); + * p.then( () => console.log('B')); + * flow.execute(() => console.log('C')); + * p.then( () => console.log('D')); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // B + * // C + * // D + * // fin + * + * When a promise is resolved while a task function is on the call stack, any + * callbacks also registered in that stack frame are scheduled as if the promise + * were already resolved: + * + * var d = promise.defer(); + * flow.execute(function() { + * flow.execute( () => console.log('A')); + * d.promise.then(() => console.log('B')); + * flow.execute( () => console.log('C')); + * d.promise.then(() => console.log('D')); + * + * d.fulfill(); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // B + * // C + * // D + * // fin + * + * Callbacks attached to an _unresolved_ promise within a task function are + * only weakly scheduled as subtasks and will be dropped if they reach the + * front of the queue before the promise is resolved. In the example below, the + * callbacks for `B` & `D` are dropped as sub-tasks since they are attached to + * an unresolved promise when they reach the front of the task queue. + * + * var d = promise.defer(); + * flow.execute(function() { + * flow.execute( () => console.log('A')); + * d.promise.then(() => console.log('B')); + * flow.execute( () => console.log('C')); + * d.promise.then(() => console.log('D')); + * + * setTimeout(d.fulfill, 20); + * }).then(function() { + * console.log('fin') + * }); + * // A + * // C + * // fin + * // B + * // D + * + * If a promise is resolved while a task function is on the call stack, any + * previously registered and unqueued callbacks (i.e. either attached while no + * task was on the call stack, or previously dropped as described above) act as + * _interrupts_ and are inserted at the front of the task queue. If multiple + * promises are fulfilled, their interrupts are enqueued in the order the + * promises are resolved. + * + * var d1 = promise.defer(); + * d1.promise.then(() => console.log('A')); + * + * var d2 = promise.defer(); + * d2.promise.then(() => console.log('B')); + * + * flow.execute(function() { + * d1.promise.then(() => console.log('C')); + * flow.execute(() => console.log('D')); + * }); + * flow.execute(function() { + * flow.execute(() => console.log('E')); + * flow.execute(() => console.log('F')); + * d1.fulfill(); + * d2.fulfill(); + * }).then(function() { + * console.log('fin'); + * }); + * // D + * // A + * // C + * // B + * // E + * // F + * // fin + * + * Within a task function (or callback), each step of a promise chain acts as + * an interrupt on the task queue: + * + * var d = promise.defer(); + * flow.execute(function() { + * d.promise. + * then(() => console.log('A')). + * then(() => console.log('B')). + * then(() => console.log('C')). + * then(() => console.log('D')); + * + * flow.execute(() => console.log('E')); + * d.fulfill(); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // B + * // C + * // D + * // E + * // fin + * + * If there are multiple promise chains derived from a single promise, they are + * processed in the order created: + * + * var d = promise.defer(); + * flow.execute(function() { + * var chain = d.promise.then(() => console.log('A')); + * + * chain.then(() => console.log('B')). + * then(() => console.log('C')); + * + * chain.then(() => console.log('D')). + * then(() => console.log('E')); + * + * flow.execute(() => console.log('F')); + * + * d.fulfill(); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // B + * // C + * // D + * // E + * // F + * // fin + * + * Even though a subtask's promised result will never resolve while the task + * function is on the stack, it will be treated as a promise resolved within the + * task. In all other scenarios, a task's promise behaves just like a normal + * promise. In the sample below, `C/D` is loggged before `B` because the + * resolution of `subtask1` interrupts the flow of the enclosing task. Within + * the final subtask, `E/F` is logged in order because `subtask1` is a resolved + * promise when that task runs. + * + * flow.execute(function() { + * var subtask1 = flow.execute(() => console.log('A')); + * var subtask2 = flow.execute(() => console.log('B')); + * + * subtask1.then(() => console.log('C')); + * subtask1.then(() => console.log('D')); + * + * flow.execute(function() { + * flow.execute(() => console.log('E')); + * subtask1.then(() => console.log('F')); + * }); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // C + * // D + * // B + * // E + * // F + * // fin + * + * Finally, consider the following: + * + * var d = promise.defer(); + * d.promise.then(() => console.log('A')); + * d.promise.then(() => console.log('B')); + * + * flow.execute(function() { + * flow.execute( () => console.log('C')); + * d.promise.then(() => console.log('D')); + * + * flow.execute( () => console.log('E')); + * d.promise.then(() => console.log('F')); + * + * d.fulfill(); + * + * flow.execute( () => console.log('G')); + * d.promise.then(() => console.log('H')); + * }).then(function() { + * console.log('fin'); + * }); + * // A + * // B + * // C + * // D + * // E + * // F + * // G + * // H + * // fin + * + * In this example, callbacks are registered on `d.promise` both before and + * during the invocation of the task function. When `d.fulfill()` is called, + * the callbacks registered before the task (`A` & `B`) are registered as + * interrupts. The remaining callbacks were all attached within the task and + * are scheduled in the flow as standard tasks. + * + * ## Generator Support + * + * [Generators][GF] may be scheduled as tasks within a control flow or attached + * as callbacks to a promise. Each time the generator yields a promise, the + * control flow will wait for that promise to settle before executing the next + * iteration of the generator. The yielded promise's fulfilled value will be + * passed back into the generator: + * + * flow.execute(function* () { + * var d = promise.defer(); + * + * setTimeout(() => console.log('...waiting...'), 25); + * setTimeout(() => d.fulfill(123), 50); + * + * console.log('start: ' + Date.now()); + * + * var value = yield d.promise; + * console.log('mid: %d; value = %d', Date.now(), value); + * + * yield promise.delayed(10); + * console.log('end: ' + Date.now()); + * }).then(function() { + * console.log('fin'); + * }); + * // start: 0 + * // ...waiting... + * // mid: 50; value = 123 + * // end: 60 + * // fin + * + * Yielding the result of a promise chain will wait for the entire chain to + * complete: + * + * promise.fulfilled().then(function* () { + * console.log('start: ' + Date.now()); + * + * var value = yield flow. + * execute(() => console.log('A')). + * then( () => console.log('B')). + * then( () => 123); + * + * console.log('mid: %s; value = %d', Date.now(), value); + * + * yield flow.execute(() => console.log('C')); + * }).then(function() { + * console.log('fin'); + * }); + * // start: 0 + * // A + * // B + * // mid: 2; value = 123 + * // C + * // fin + * + * Yielding a _rejected_ promise will cause the rejected value to be thrown + * within the generator function: + * + * flow.execute(function* () { + * console.log('start: ' + Date.now()); + * try { + * yield promise.delayed(10).then(function() { + * throw Error('boom'); + * }); + * } catch (ex) { + * console.log('caught time: ' + Date.now()); + * console.log(ex.message); + * } + * }); + * // start: 0 + * // caught time: 10 + * // boom + * + * # Error Handling + * + * ES6 promises do not require users to handle a promise rejections. This can + * result in subtle bugs as the rejections are silently "swallowed" by the + * ManagedPromise class. + * + * ManagedPromise.reject(Error('boom')); + * // ... *crickets* ... + * + * Selenium's promise module, on the other hand, requires that every rejection + * be explicitly handled. When a {@linkplain ManagedPromise ManagedPromise} is + * rejected and no callbacks are defined on that promise, it is considered an + * _unhandled rejection_ and reproted to the active task queue. If the rejection + * remains unhandled after a single turn of the [event loop][JSEL] (scheduled + * with a micro-task), it will propagate up the stack. + * + * ## Error Propagation + * + * If an unhandled rejection occurs within a task function, that task's promised + * result is rejected and all remaining subtasks are discarded: + * + * flow.execute(function() { + * // No callbacks registered on promise -> unhandled rejection + * promise.rejected(Error('boom')); + * flow.execute(function() { console.log('this will never run'); }); + * }).catch(function(e) { + * console.log(e.message); + * }); + * // boom + * + * The promised results for discarded tasks are silently rejected with a + * cancellation error and existing callback chains will never fire. + * + * flow.execute(function() { + * promise.rejected(Error('boom')); + * flow.execute(function() { console.log('a'); }). + * then(function() { console.log('b'); }); + * }).catch(function(e) { + * console.log(e.message); + * }); + * // boom + * + * An unhandled rejection takes precedence over a task function's returned + * result, even if that value is another promise: + * + * flow.execute(function() { + * promise.rejected(Error('boom')); + * return flow.execute(someOtherTask); + * }).catch(function(e) { + * console.log(e.message); + * }); + * // boom + * + * If there are multiple unhandled rejections within a task, they are packaged + * in a {@link MultipleUnhandledRejectionError}, which has an `errors` property + * that is a `Set` of the recorded unhandled rejections: + * + * flow.execute(function() { + * promise.rejected(Error('boom1')); + * promise.rejected(Error('boom2')); + * }).catch(function(ex) { + * console.log(ex instanceof MultipleUnhandledRejectionError); + * for (var e of ex.errors) { + * console.log(e.message); + * } + * }); + * // boom1 + * // boom2 + * + * When a subtask is discarded due to an unreported rejection in its parent + * frame, the existing callbacks on that task will never settle and the + * callbacks will not be invoked. If a new callback is attached ot the subtask + * _after_ it has been discarded, it is handled the same as adding a callback + * to a cancelled promise: the error-callback path is invoked. This behavior is + * intended to handle cases where the user saves a reference to a task promise, + * as illustrated below. + * + * var subTask; + * flow.execute(function() { + * promise.rejected(Error('boom')); + * subTask = flow.execute(function() {}); + * }).catch(function(e) { + * console.log(e.message); + * }).then(function() { + * return subTask.then( + * () => console.log('subtask success!'), + * (e) => console.log('subtask failed:\n' + e)); + * }); + * // boom + * // subtask failed: + * // DiscardedTaskError: Task was discarded due to a previous failure: boom + * + * When a subtask fails, its promised result is treated the same as any other + * promise: it must be handled within one turn of the rejection or the unhandled + * rejection is propagated to the parent task. This means users can catch errors + * from complex flows from the top level task: + * + * flow.execute(function() { + * flow.execute(function() { + * flow.execute(function() { + * throw Error('fail!'); + * }); + * }); + * }).catch(function(e) { + * console.log(e.message); + * }); + * // fail! + * + * ## Unhandled Rejection Events + * + * When an unhandled rejection propagates to the root of the control flow, the + * flow will emit an __uncaughtException__ event. If no listeners are registered + * on the flow, the error will be rethrown to the global error handler: an + * __uncaughtException__ event from the + * [`process`](https://nodejs.org/api/process.html) object in node, or + * `window.onerror` when running in a browser. + * + * Bottom line: you __*must*__ handle rejected promises. + * + * # ManagedPromise/A+ Compatibility + * + * This `promise` module is compliant with the [ManagedPromise/A+][] specification + * except for sections `2.2.6.1` and `2.2.6.2`: + * + * > + * > - `then` may be called multiple times on the same promise. + * > - If/when `promise` is fulfilled, all respective `onFulfilled` callbacks + * > must execute in the order of their originating calls to `then`. + * > - If/when `promise` is rejected, all respective `onRejected` callbacks + * > must execute in the order of their originating calls to `then`. + * > + * + * Specifically, the conformance tests contains the following scenario (for + * brevity, only the fulfillment version is shown): + * + * var p1 = ManagedPromise.resolve(); + * p1.then(function() { + * console.log('A'); + * p1.then(() => console.log('B')); + * }); + * p1.then(() => console.log('C')); + * // A + * // C + * // B + * + * Since the [ControlFlow](#scheduling_callbacks) executes promise callbacks as + * tasks, with this module, the result would be + * + * var p2 = promise.fulfilled(); + * p2.then(function() { + * console.log('A'); + * p2.then(() => console.log('B'); + * }); + * p2.then(() => console.log('C')); + * // A + * // B + * // C + * + * [JSEL]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop + * [GF]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function* + * [ManagedPromise/A+]: https://promisesaplus.com/ + */ + +'use strict'; + +const events = require('./events'); +const logging = require('./logging'); + + +/** + * Alias to help with readability and differentiate types. + * @const + */ +const NativePromise = Promise; + + +/** + * Whether to append traces of `then` to rejection errors. + * @type {boolean} + */ +exports.LONG_STACK_TRACES = false; // TODO: this should not be CONSTANT_CASE + + +/** @const */ +const LOG = logging.getLogger('promise'); + + +const UNIQUE_IDS = new WeakMap; +let nextId = 1; + + +function getUid(obj) { + let id = UNIQUE_IDS.get(obj); + if (!id) { + id = nextId; + nextId += 1; + UNIQUE_IDS.set(obj, id); + } + return id; +} + + +/** + * Runs the given function after a micro-task yield. + * @param {function()} fn The function to run. + */ +function asyncRun(fn) { + NativePromise.resolve().then(function() { + try { + fn(); + } catch (ignored) { + // Do nothing. + } + }); +} + + +/** + * Throws an error asynchronously so it is reported to the global error handler. + * + * @param {!Error} error The error to throw. + */ +function asyncThrow(error) { + setTimeout(function() { + throw error; + }, 0); +} + + +/** + * @param {number} level What level of verbosity to log with. + * @param {(string|function(this: T): string)} loggable The message to log. + * @param {T=} opt_self The object in whose context to run the loggable + * function. + * @template T + */ +function vlog(level, loggable, opt_self) { + var logLevel = logging.Level.FINE; + if (level > 1) { + logLevel = logging.Level.FINEST; + } else if (level > 0) { + logLevel = logging.Level.FINER; + } + + if (typeof loggable === 'function') { + loggable = loggable.bind(opt_self); + } + + LOG.log(logLevel, loggable); +} + + +/** + * Generates an error to capture the current stack trace. + * @param {string} name Error name for this stack trace. + * @param {string} msg Message to record. + * @param {Function=} opt_topFn The function that should appear at the top of + * the stack; only applicable in V8. + * @return {!Error} The generated error. + */ +function captureStackTrace(name, msg, opt_topFn) { + var e = Error(msg); + e.name = name; + if (Error.captureStackTrace) { + Error.captureStackTrace(e, opt_topFn); + } else { + var stack = Error().stack; + if (stack) { + e.stack = e.toString(); + e.stack += '\n' + stack; + } + } + return e; +} + + +/** + * Error used when the computation of a promise is cancelled. + */ +class CancellationError extends Error { + /** + * @param {string=} opt_msg The cancellation message. + */ + constructor(opt_msg) { + super(opt_msg); + + /** @override */ + this.name = this.constructor.name; + + /** @private {boolean} */ + this.silent_ = false; + } + + /** + * Wraps the given error in a CancellationError. + * + * @param {*} error The error to wrap. + * @param {string=} opt_msg The prefix message to use. + * @return {!CancellationError} A cancellation error. + */ + static wrap(error, opt_msg) { + var message; + if (error instanceof CancellationError) { + return new CancellationError( + opt_msg ? (opt_msg + ': ' + error.message) : error.message); + } else if (opt_msg) { + message = opt_msg; + if (error) { + message += ': ' + error; + } + return new CancellationError(message); + } + if (error) { + message = error + ''; + } + return new CancellationError(message); + } +} + + +/** + * Error used to cancel tasks when a control flow is reset. + * @final + */ +class FlowResetError extends CancellationError { + constructor() { + super('ControlFlow was reset'); + this.silent_ = true; + } +} + + +/** + * Error used to cancel tasks that have been discarded due to an uncaught error + * reported earlier in the control flow. + * @final + */ +class DiscardedTaskError extends CancellationError { + /** @param {*} error The original error. */ + constructor(error) { + if (error instanceof DiscardedTaskError) { + return /** @type {!DiscardedTaskError} */(error); + } + + var msg = ''; + if (error) { + msg = ': ' + ( + typeof error.message === 'string' ? error.message : error); + } + + super('Task was discarded due to a previous failure' + msg); + this.silent_ = true; + } +} + + +/** + * Error used when there are multiple unhandled promise rejections detected + * within a task or callback. + * + * @final + */ +class MultipleUnhandledRejectionError extends Error { + /** + * @param {!(Set<*>)} errors The errors to report. + */ + constructor(errors) { + super('Multiple unhandled promise rejections reported'); + + /** @override */ + this.name = this.constructor.name; + + /** @type {!Set<*>} */ + this.errors = errors; + } +} + + +/** + * Property used to flag constructor's as implementing the Thenable interface + * for runtime type checking. + * @const + */ +const IMPLEMENTED_BY_SYMBOL = Symbol('promise.Thenable'); + + +/** + * Thenable is a promise-like object with a {@code then} method which may be + * used to schedule callbacks on a promised value. + * + * @interface + * @extends {IThenable} + * @template T + */ +class Thenable { + /** + * Adds a property to a class prototype to allow runtime checks of whether + * instances of that class implement the Thenable interface. This function + * will also ensure the prototype's {@code then} function is exported from + * compiled code. + * @param {function(new: Thenable, ...?)} ctor The + * constructor whose prototype to modify. + */ + static addImplementation(ctor) { + ctor.prototype['then'] = ctor.prototype.then; + try { + ctor.prototype[IMPLEMENTED_BY_SYMBOL] = true; + } catch (ignored) { + // Property access denied? + } + } + + /** + * Checks if an object has been tagged for implementing the Thenable + * interface as defined by {@link Thenable.addImplementation}. + * @param {*} object The object to test. + * @return {boolean} Whether the object is an implementation of the Thenable + * interface. + */ + static isImplementation(object) { + if (!object) { + return false; + } + try { + return !!object[IMPLEMENTED_BY_SYMBOL]; + } catch (e) { + return false; // Property access seems to be forbidden. + } + } + + /** + * Cancels the computation of this promise's value, rejecting the promise in + * the process. This method is a no-op if the promise has already been + * resolved. + * + * @param {(string|Error)=} opt_reason The reason this promise is being + * cancelled. This value will be wrapped in a {@link CancellationError}. + */ + cancel(opt_reason) {} + + /** @return {boolean} Whether this promise's value is still being computed. */ + isPending() {} + + /** + * Registers listeners for when this instance is resolved. + * + * @param {?(function(T): (R|IThenable))=} opt_callback The + * function to call if this promise is successfully resolved. The function + * should expect a single argument: the promise's resolved value. + * @param {?(function(*): (R|IThenable))=} opt_errback + * The function to call if this promise is rejected. The function should + * expect a single argument: the rejection reason. + * @return {!ManagedPromise} A new promise which will be + * resolved with the result of the invoked callback. + * @template R + */ + then(opt_callback, opt_errback) {} + + /** + * Registers a listener for when this promise is rejected. This is synonymous + * with the {@code catch} clause in a synchronous API: + * + * // Synchronous API: + * try { + * doSynchronousWork(); + * } catch (ex) { + * console.error(ex); + * } + * + * // Asynchronous promise API: + * doAsynchronousWork().catch(function(ex) { + * console.error(ex); + * }); + * + * @param {function(*): (R|IThenable)} errback The + * function to call if this promise is rejected. The function should + * expect a single argument: the rejection reason. + * @return {!ManagedPromise} A new promise which will be + * resolved with the result of the invoked callback. + * @template R + */ + catch(errback) {} + + /** + * An alias for {@link #catch()} + * + * @param {function(*): (R|IThenable)} errback The + * function to call if this promise is rejected. The function should + * expect a single argument: the rejection reason. + * @return {!ManagedPromise} A new promise which will be + * resolved wdith the result of the invoked callback. + * @template R + */ + thenCatch(errback) {} + + /** + * Registers a listener to invoke when this promise is resolved, regardless + * of whether the promise's value was successfully computed. This function + * is synonymous with the {@code finally} clause in a synchronous API: + * + * // Synchronous API: + * try { + * doSynchronousWork(); + * } finally { + * cleanUp(); + * } + * + * // Asynchronous promise API: + * doAsynchronousWork().thenFinally(cleanUp); + * + * __Note:__ similar to the {@code finally} clause, if the registered + * callback returns a rejected promise or throws an error, it will silently + * replace the rejection error (if any) from this promise: + * + * try { + * throw Error('one'); + * } finally { + * throw Error('two'); // Hides Error: one + * } + * + * promise.rejected(Error('one')) + * .thenFinally(function() { + * throw Error('two'); // Hides Error: one + * }); + * + * @param {function(): (R|IThenable)} callback The function + * to call when this promise is resolved. + * @return {!ManagedPromise} A promise that will be fulfilled + * with the callback result. + * @template R + */ + thenFinally(callback) {} +} + + +/** + * @enum {string} + */ +const PromiseState = { + PENDING: 'pending', + BLOCKED: 'blocked', + REJECTED: 'rejected', + FULFILLED: 'fulfilled' +}; + + +/** + * Internal symbol used to store a cancellation handler for + * {@link ManagedPromise} objects. This is an internal implementation detail + * used by the {@link TaskQueue} class to monitor for when a promise is + * cancelled without generating an extra promise via then(). + */ +const CANCEL_HANDLER_SYMBOL = Symbol('on cancel'); + + +/** + * Represents the eventual value of a completed operation. Each promise may be + * in one of three states: pending, fulfilled, or rejected. Each promise starts + * in the pending state and may make a single transition to either a + * fulfilled or rejected state, at which point the promise is considered + * resolved. + * + * @implements {Thenable} + * @unrestricted + * @template T + * @see http://promises-aplus.github.io/promises-spec/ + */ +const ManagedPromise = class Promise { + /** + * @param {function( + * function((T|IThenable|Thenable)=), + * function(*=))} resolver + * Function that is invoked immediately to begin computation of this + * promise's value. The function should accept a pair of callback + * functions, one for fulfilling the promise and another for rejecting it. + * @param {ControlFlow=} opt_flow The control flow + * this instance was created under. Defaults to the currently active flow. + */ + constructor(resolver, opt_flow) { + getUid(this); + + /** @private {!ControlFlow} */ + this.flow_ = opt_flow || controlFlow(); + + /** @private {Error} */ + this.stack_ = null; + if (exports.LONG_STACK_TRACES) { + this.stack_ = captureStackTrace('Promise', 'new', this.constructor); + } + + /** @private {ManagedPromise} */ + this.parent_ = null; + + /** @private {Array} */ + this.callbacks_ = null; + + /** @private {PromiseState} */ + this.state_ = PromiseState.PENDING; + + /** @private {boolean} */ + this.handled_ = false; + + /** @private {*} */ + this.value_ = undefined; + + /** @private {TaskQueue} */ + this.queue_ = null; + + /** @private {(function(CancellationError)|null)} */ + this[CANCEL_HANDLER_SYMBOL] = null; + + try { + var self = this; + resolver(function(value) { + self.resolve_(PromiseState.FULFILLED, value); + }, function(reason) { + self.resolve_(PromiseState.REJECTED, reason); + }); + } catch (ex) { + this.resolve_(PromiseState.REJECTED, ex); + } + } + + /** @override */ + toString() { + return 'ManagedPromise::' + getUid(this) + + ' {[[PromiseStatus]]: "' + this.state_ + '"}'; + } + + /** + * Resolves this promise. If the new value is itself a promise, this function + * will wait for it to be resolved before notifying the registered listeners. + * @param {PromiseState} newState The promise's new state. + * @param {*} newValue The promise's new value. + * @throws {TypeError} If {@code newValue === this}. + * @private + */ + resolve_(newState, newValue) { + if (PromiseState.PENDING !== this.state_) { + return; + } + + if (newValue === this) { + // See promise a+, 2.3.1 + // http://promises-aplus.github.io/promises-spec/#point-48 + newValue = new TypeError('A promise may not resolve to itself'); + newState = PromiseState.REJECTED; + } + + this.parent_ = null; + this.state_ = PromiseState.BLOCKED; + + if (newState !== PromiseState.REJECTED) { + if (Thenable.isImplementation(newValue)) { + // 2.3.2 + newValue = /** @type {!Thenable} */(newValue); + newValue.then( + this.unblockAndResolve_.bind(this, PromiseState.FULFILLED), + this.unblockAndResolve_.bind(this, PromiseState.REJECTED)); + return; + + } else if (newValue + && (typeof newValue === 'object' || typeof newValue === 'function')) { + // 2.3.3 + + try { + // 2.3.3.1 + var then = newValue['then']; + } catch (e) { + // 2.3.3.2 + this.state_ = PromiseState.REJECTED; + this.value_ = e; + this.scheduleNotifications_(); + return; + } + + if (typeof then === 'function') { + // 2.3.3.3 + this.invokeThen_(/** @type {!Object} */(newValue), then); + return; + } + } + } + + if (newState === PromiseState.REJECTED && + isError(newValue) && newValue.stack && this.stack_) { + newValue.stack += '\nFrom: ' + (this.stack_.stack || this.stack_); + } + + // 2.3.3.4 and 2.3.4 + this.state_ = newState; + this.value_ = newValue; + this.scheduleNotifications_(); + } + + /** + * Invokes a thenable's "then" method according to 2.3.3.3 of the promise + * A+ spec. + * @param {!Object} x The thenable object. + * @param {!Function} then The "then" function to invoke. + * @private + */ + invokeThen_(x, then) { + var called = false; + var self = this; + + var resolvePromise = function(value) { + if (!called) { // 2.3.3.3.3 + called = true; + // 2.3.3.3.1 + self.unblockAndResolve_(PromiseState.FULFILLED, value); + } + }; + + var rejectPromise = function(reason) { + if (!called) { // 2.3.3.3.3 + called = true; + // 2.3.3.3.2 + self.unblockAndResolve_(PromiseState.REJECTED, reason); + } + }; + + try { + // 2.3.3.3 + then.call(x, resolvePromise, rejectPromise); + } catch (e) { + // 2.3.3.3.4.2 + rejectPromise(e); + } + } + + /** + * @param {PromiseState} newState The promise's new state. + * @param {*} newValue The promise's new value. + * @private + */ + unblockAndResolve_(newState, newValue) { + if (this.state_ === PromiseState.BLOCKED) { + this.state_ = PromiseState.PENDING; + this.resolve_(newState, newValue); + } + } + + /** + * @private + */ + scheduleNotifications_() { + vlog(2, () => this + ' scheduling notifications', this); + + this[CANCEL_HANDLER_SYMBOL] = null; + if (this.value_ instanceof CancellationError + && this.value_.silent_) { + this.callbacks_ = null; + } + + if (!this.queue_) { + this.queue_ = this.flow_.getActiveQueue_(); + } + + if (!this.handled_ && + this.state_ === PromiseState.REJECTED && + !(this.value_ instanceof CancellationError)) { + this.queue_.addUnhandledRejection(this); + } + this.queue_.scheduleCallbacks(this); + } + + /** @override */ + cancel(opt_reason) { + if (!canCancel(this)) { + return; + } + + if (this.parent_ && canCancel(this.parent_)) { + this.parent_.cancel(opt_reason); + } else { + var reason = CancellationError.wrap(opt_reason); + if (this[CANCEL_HANDLER_SYMBOL]) { + this[CANCEL_HANDLER_SYMBOL](reason); + this[CANCEL_HANDLER_SYMBOL] = null; + } + + if (this.state_ === PromiseState.BLOCKED) { + this.unblockAndResolve_(PromiseState.REJECTED, reason); + } else { + this.resolve_(PromiseState.REJECTED, reason); + } + } + + function canCancel(promise) { + return promise.state_ === PromiseState.PENDING + || promise.state_ === PromiseState.BLOCKED; + } + } + + /** @override */ + isPending() { + return this.state_ === PromiseState.PENDING; + } + + /** @override */ + then(opt_callback, opt_errback) { + return this.addCallback_( + opt_callback, opt_errback, 'then', ManagedPromise.prototype.then); + } + + /** @override */ + catch(errback) { + return this.addCallback_( + null, errback, 'catch', ManagedPromise.prototype.catch); + } + + /** @override */ + thenCatch(errback) { + return this.catch(errback); + } + + /** @override */ + thenFinally(callback) { + var error; + var mustThrow = false; + return this.then(function() { + return callback(); + }, function(err) { + error = err; + mustThrow = true; + return callback(); + }).then(function() { + if (mustThrow) { + throw error; + } + }); + } + + /** + * Registers a new callback with this promise + * @param {(function(T): (R|IThenable)|null|undefined)} callback The + * fulfillment callback. + * @param {(function(*): (R|IThenable)|null|undefined)} errback The + * rejection callback. + * @param {string} name The callback name. + * @param {!Function} fn The function to use as the top of the stack when + * recording the callback's creation point. + * @return {!ManagedPromise} A new promise which will be resolved with the + * esult of the invoked callback. + * @template R + * @private + */ + addCallback_(callback, errback, name, fn) { + if (typeof callback !== 'function' && typeof errback !== 'function') { + return this; + } + + this.handled_ = true; + if (this.queue_) { + this.queue_.clearUnhandledRejection(this); + } + + var cb = new Task( + this.flow_, + this.invokeCallback_.bind(this, callback, errback), + name, + exports.LONG_STACK_TRACES ? {name: 'Promise', top: fn} : undefined); + cb.promise.parent_ = this; + + if (this.state_ !== PromiseState.PENDING && + this.state_ !== PromiseState.BLOCKED) { + this.flow_.getActiveQueue_().enqueue(cb); + } else { + if (!this.callbacks_) { + this.callbacks_ = []; + } + this.callbacks_.push(cb); + cb.blocked = true; + this.flow_.getActiveQueue_().enqueue(cb); + } + + return cb.promise; + } + + /** + * Invokes a callback function attached to this promise. + * @param {(function(T): (R|IThenable)|null|undefined)} callback The + * fulfillment callback. + * @param {(function(*): (R|IThenable)|null|undefined)} errback The + * rejection callback. + * @template R + * @private + */ + invokeCallback_(callback, errback) { + var callbackFn = callback; + if (this.state_ === PromiseState.REJECTED) { + callbackFn = errback; + } + + if (typeof callbackFn === 'function') { + if (isGenerator(callbackFn)) { + return consume(callbackFn, null, this.value_); + } + return callbackFn(this.value_); + } else if (this.state_ === PromiseState.REJECTED) { + throw this.value_; + } else { + return this.value_; + } + } +} +Thenable.addImplementation(ManagedPromise); + + +/** + * Represents a value that will be resolved at some point in the future. This + * class represents the protected "producer" half of a ManagedPromise - each Deferred + * has a {@code promise} property that may be returned to consumers for + * registering callbacks, reserving the ability to resolve the deferred to the + * producer. + * + * If this Deferred is rejected and there are no listeners registered before + * the next turn of the event loop, the rejection will be passed to the + * {@link ControlFlow} as an unhandled failure. + * + * @implements {Thenable} + * @template T + */ +class Deferred { + /** + * @param {ControlFlow=} opt_flow The control flow this instance was + * created under. This should only be provided during unit tests. + */ + constructor(opt_flow) { + var fulfill, reject; + + /** @type {!ManagedPromise} */ + this.promise = new ManagedPromise(function(f, r) { + fulfill = f; + reject = r; + }, opt_flow); + + var self = this; + var checkNotSelf = function(value) { + if (value === self) { + throw new TypeError('May not resolve a Deferred with itself'); + } + }; + + /** + * Resolves this deferred with the given value. It is safe to call this as a + * normal function (with no bound "this"). + * @param {(T|IThenable|Thenable)=} opt_value The fulfilled value. + */ + this.fulfill = function(opt_value) { + checkNotSelf(opt_value); + fulfill(opt_value); + }; + + /** + * Rejects this promise with the given reason. It is safe to call this as a + * normal function (with no bound "this"). + * @param {*=} opt_reason The rejection reason. + */ + this.reject = function(opt_reason) { + checkNotSelf(opt_reason); + reject(opt_reason); + }; + } + + /** @override */ + isPending() { + return this.promise.isPending(); + } + + /** @override */ + cancel(opt_reason) { + this.promise.cancel(opt_reason); + } + + /** + * @override + * @deprecated Use {@code then} from the promise property directly. + */ + then(opt_cb, opt_eb) { + return this.promise.then(opt_cb, opt_eb); + } + + /** + * @override + * @deprecated Use {@lcode catch} from the promise property directly. + */ + catch(opt_eb) { + return this.promise.catch(opt_eb); + } + + /** + * @override + * @deprecated Use {@code thenCatch} from the promise property directly. + */ + thenCatch(opt_eb) { + return this.promise.thenCatch(opt_eb); + } + + /** + * @override + * @deprecated Use {@code thenFinally} from the promise property directly. + */ + thenFinally(opt_cb) { + return this.promise.thenFinally(opt_cb); + } +} +Thenable.addImplementation(Deferred); + + +/** + * Tests if a value is an Error-like object. This is more than an straight + * instanceof check since the value may originate from another context. + * @param {*} value The value to test. + * @return {boolean} Whether the value is an error. + */ +function isError(value) { + return value instanceof Error || + (!!value && typeof value === 'object' + && typeof value.message === 'string'); +} + + +/** + * Determines whether a {@code value} should be treated as a promise. + * Any object whose "then" property is a function will be considered a promise. + * + * @param {?} value The value to test. + * @return {boolean} Whether the value is a promise. + */ +function isPromise(value) { + try { + // Use array notation so the Closure compiler does not obfuscate away our + // contract. + return value + && (typeof value === 'object' || typeof value === 'function') + && typeof value['then'] === 'function'; + } catch (ex) { + return false; + } +} + + +/** + * Creates a promise that will be resolved at a set time in the future. + * @param {number} ms The amount of time, in milliseconds, to wait before + * resolving the promise. + * @return {!ManagedPromise} The promise. + */ +function delayed(ms) { + var key; + return new ManagedPromise(function(fulfill) { + key = setTimeout(function() { + key = null; + fulfill(); + }, ms); + }).catch(function(e) { + clearTimeout(key); + key = null; + throw e; + }); +} + + +/** + * Creates a new deferred object. + * @return {!Deferred} The new deferred object. + * @template T + */ +function defer() { + return new Deferred(); +} + + +/** + * Creates a promise that has been resolved with the given value. + * @param {T=} opt_value The resolved value. + * @return {!ManagedPromise} The resolved promise. + * @template T + */ +function fulfilled(opt_value) { + if (opt_value instanceof ManagedPromise) { + return opt_value; + } + return new ManagedPromise(function(fulfill) { + fulfill(opt_value); + }); +} + + +/** + * Creates a promise that has been rejected with the given reason. + * @param {*=} opt_reason The rejection reason; may be any value, but is + * usually an Error or a string. + * @return {!ManagedPromise} The rejected promise. + * @template T + */ +function rejected(opt_reason) { + if (opt_reason instanceof ManagedPromise) { + return opt_reason; + } + return new ManagedPromise(function(_, reject) { + reject(opt_reason); + }); +} + + +/** + * Wraps a function that expects a node-style callback as its final + * argument. This callback expects two arguments: an error value (which will be + * null if the call succeeded), and the success value as the second argument. + * The callback will the resolve or reject the returned promise, based on its + * arguments. + * @param {!Function} fn The function to wrap. + * @param {...?} var_args The arguments to apply to the function, excluding the + * final callback. + * @return {!ManagedPromise} A promise that will be resolved with the + * result of the provided function's callback. + */ +function checkedNodeCall(fn, var_args) { + let args = Array.prototype.slice.call(arguments, 1); + return new ManagedPromise(function(fulfill, reject) { + try { + args.push(function(error, value) { + error ? reject(error) : fulfill(value); + }); + fn.apply(undefined, args); + } catch (ex) { + reject(ex); + } + }); +} + + +/** + * Registers an observer on a promised {@code value}, returning a new promise + * that will be resolved when the value is. If {@code value} is not a promise, + * then the return promise will be immediately resolved. + * @param {*} value The value to observe. + * @param {Function=} opt_callback The function to call when the value is + * resolved successfully. + * @param {Function=} opt_errback The function to call when the value is + * rejected. + * @return {!ManagedPromise} A new promise. + */ +function when(value, opt_callback, opt_errback) { + if (Thenable.isImplementation(value)) { + return value.then(opt_callback, opt_errback); + } + + return new ManagedPromise(function(fulfill) { + fulfill(value); + }).then(opt_callback, opt_errback); +} + + +/** + * Invokes the appropriate callback function as soon as a promised `value` is + * resolved. This function is similar to `when()`, except it does not return + * a new promise. + * @param {*} value The value to observe. + * @param {Function} callback The function to call when the value is + * resolved successfully. + * @param {Function=} opt_errback The function to call when the value is + * rejected. + */ +function asap(value, callback, opt_errback) { + if (isPromise(value)) { + value.then(callback, opt_errback); + + } else if (callback) { + callback(value); + } +} + + +/** + * Given an array of promises, will return a promise that will be fulfilled + * with the fulfillment values of the input array's values. If any of the + * input array's promises are rejected, the returned promise will be rejected + * with the same reason. + * + * @param {!Array<(T|!ManagedPromise)>} arr An array of + * promises to wait on. + * @return {!ManagedPromise>} A promise that is + * fulfilled with an array containing the fulfilled values of the + * input array, or rejected with the same reason as the first + * rejected value. + * @template T + */ +function all(arr) { + return new ManagedPromise(function(fulfill, reject) { + var n = arr.length; + var values = []; + + if (!n) { + fulfill(values); + return; + } + + var toFulfill = n; + var onFulfilled = function(index, value) { + values[index] = value; + toFulfill--; + if (toFulfill == 0) { + fulfill(values); + } + }; + + function processPromise(index) { + asap(arr[index], function(value) { + onFulfilled(index, value); + }, reject); + } + + for (var i = 0; i < n; ++i) { + processPromise(i); + } + }); +} + + +/** + * Calls a function for each element in an array and inserts the result into a + * new array, which is used as the fulfillment value of the promise returned + * by this function. + * + * If the return value of the mapping function is a promise, this function + * will wait for it to be fulfilled before inserting it into the new array. + * + * If the mapping function throws or returns a rejected promise, the + * promise returned by this function will be rejected with the same reason. + * Only the first failure will be reported; all subsequent errors will be + * silently ignored. + * + * @param {!(Array|ManagedPromise>)} arr The + * array to iterator over, or a promise that will resolve to said array. + * @param {function(this: SELF, TYPE, number, !Array): ?} fn The + * function to call for each element in the array. This function should + * expect three arguments (the element, the index, and the array itself. + * @param {SELF=} opt_self The object to be used as the value of 'this' within + * {@code fn}. + * @template TYPE, SELF + */ +function map(arr, fn, opt_self) { + return fulfilled(arr).then(function(v) { + if (!Array.isArray(v)) { + throw TypeError('not an array'); + } + var arr = /** @type {!Array} */(v); + return new ManagedPromise(function(fulfill, reject) { + var n = arr.length; + var values = new Array(n); + (function processNext(i) { + for (; i < n; i++) { + if (i in arr) { + break; + } + } + if (i >= n) { + fulfill(values); + return; + } + try { + asap( + fn.call(opt_self, arr[i], i, /** @type {!Array} */(arr)), + function(value) { + values[i] = value; + processNext(i + 1); + }, + reject); + } catch (ex) { + reject(ex); + } + })(0); + }); + }); +} + + +/** + * Calls a function for each element in an array, and if the function returns + * true adds the element to a new array. + * + * If the return value of the filter function is a promise, this function + * will wait for it to be fulfilled before determining whether to insert the + * element into the new array. + * + * If the filter function throws or returns a rejected promise, the promise + * returned by this function will be rejected with the same reason. Only the + * first failure will be reported; all subsequent errors will be silently + * ignored. + * + * @param {!(Array|ManagedPromise>)} arr The + * array to iterator over, or a promise that will resolve to said array. + * @param {function(this: SELF, TYPE, number, !Array): ( + * boolean|ManagedPromise)} fn The function + * to call for each element in the array. + * @param {SELF=} opt_self The object to be used as the value of 'this' within + * {@code fn}. + * @template TYPE, SELF + */ +function filter(arr, fn, opt_self) { + return fulfilled(arr).then(function(v) { + if (!Array.isArray(v)) { + throw TypeError('not an array'); + } + var arr = /** @type {!Array} */(v); + return new ManagedPromise(function(fulfill, reject) { + var n = arr.length; + var values = []; + var valuesLength = 0; + (function processNext(i) { + for (; i < n; i++) { + if (i in arr) { + break; + } + } + if (i >= n) { + fulfill(values); + return; + } + try { + var value = arr[i]; + var include = fn.call(opt_self, value, i, /** @type {!Array} */(arr)); + asap(include, function(include) { + if (include) { + values[valuesLength++] = value; + } + processNext(i + 1); + }, reject); + } catch (ex) { + reject(ex); + } + })(0); + }); + }); +} + + +/** + * Returns a promise that will be resolved with the input value in a + * fully-resolved state. If the value is an array, each element will be fully + * resolved. Likewise, if the value is an object, all keys will be fully + * resolved. In both cases, all nested arrays and objects will also be + * fully resolved. All fields are resolved in place; the returned promise will + * resolve on {@code value} and not a copy. + * + * Warning: This function makes no checks against objects that contain + * cyclical references: + * + * var value = {}; + * value['self'] = value; + * promise.fullyResolved(value); // Stack overflow. + * + * @param {*} value The value to fully resolve. + * @return {!ManagedPromise} A promise for a fully resolved version + * of the input value. + */ +function fullyResolved(value) { + if (isPromise(value)) { + return when(value, fullyResolveValue); + } + return fullyResolveValue(value); +} + + +/** + * @param {*} value The value to fully resolve. If a promise, assumed to + * already be resolved. + * @return {!ManagedPromise} A promise for a fully resolved version + * of the input value. + */ +function fullyResolveValue(value) { + if (Array.isArray(value)) { + return fullyResolveKeys(/** @type {!Array} */ (value)); + } + + if (isPromise(value)) { + if (isPromise(value)) { + // We get here when the original input value is a promise that + // resolves to itself. When the user provides us with such a promise, + // trust that it counts as a "fully resolved" value and return it. + // Of course, since it's already a promise, we can just return it + // to the user instead of wrapping it in another promise. + return /** @type {!ManagedPromise} */ (value); + } + } + + if (value && typeof value === 'object') { + return fullyResolveKeys(/** @type {!Object} */ (value)); + } + + if (typeof value === 'function') { + return fullyResolveKeys(/** @type {!Object} */ (value)); + } + + return fulfilled(value); +} + + +/** + * @param {!(Array|Object)} obj the object to resolve. + * @return {!ManagedPromise} A promise that will be resolved with the + * input object once all of its values have been fully resolved. + */ +function fullyResolveKeys(obj) { + var isArray = Array.isArray(obj); + var numKeys = isArray ? obj.length : (function() { + let n = 0; + for (let key in obj) { + n += 1; + } + return n; + })(); + if (!numKeys) { + return fulfilled(obj); + } + + function forEachProperty(obj, fn) { + for (let key in obj) { + fn.call(null, obj[key], key, obj); + } + } + + function forEachElement(arr, fn) { + arr.forEach(fn); + } + + var numResolved = 0; + return new ManagedPromise(function(fulfill, reject) { + var forEachKey = isArray ? forEachElement: forEachProperty; + + forEachKey(obj, function(partialValue, key) { + if (!Array.isArray(partialValue) + && (!partialValue || typeof partialValue !== 'object')) { + maybeResolveValue(); + return; + } + + fullyResolved(partialValue).then( + function(resolvedValue) { + obj[key] = resolvedValue; + maybeResolveValue(); + }, + reject); + }); + + function maybeResolveValue() { + if (++numResolved == numKeys) { + fulfill(obj); + } + } + }); +} + + +////////////////////////////////////////////////////////////////////////////// +// +// ControlFlow +// +////////////////////////////////////////////////////////////////////////////// + + + +/** + * Handles the execution of scheduled tasks, each of which may be an + * asynchronous operation. The control flow will ensure tasks are executed in + * the ordered scheduled, starting each task only once those before it have + * completed. + * + * Each task scheduled within this flow may return a {@link ManagedPromise} to + * indicate it is an asynchronous operation. The ControlFlow will wait for such + * promises to be resolved before marking the task as completed. + * + * Tasks and each callback registered on a {@link ManagedPromise} will be run + * in their own ControlFlow frame. Any tasks scheduled within a frame will take + * priority over previously scheduled tasks. Furthermore, if any of the tasks in + * the frame fail, the remainder of the tasks in that frame will be discarded + * and the failure will be propagated to the user through the callback/task's + * promised result. + * + * Each time a ControlFlow empties its task queue, it will fire an + * {@link ControlFlow.EventType.IDLE IDLE} event. Conversely, + * whenever the flow terminates due to an unhandled error, it will remove all + * remaining tasks in its queue and fire an + * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION UNCAUGHT_EXCEPTION} event. + * If there are no listeners registered with the flow, the error will be + * rethrown to the global error handler. + * + * Refer to the {@link ./promise} module documentation fora detailed + * explanation of how the ControlFlow coordinates task execution. + * + * @final + */ +class ControlFlow extends events.EventEmitter { + constructor() { + super(); + + /** @private {boolean} */ + this.propagateUnhandledRejections_ = true; + + /** @private {TaskQueue} */ + this.activeQueue_ = null; + + /** @private {Set} */ + this.taskQueues_ = null; + + /** + * Micro task that controls shutting down the control flow. Upon shut down, + * the flow will emit an + * {@link ControlFlow.EventType.IDLE} event. Idle events + * always follow a brief timeout in order to catch latent errors from the + * last completed task. If this task had a callback registered, but no + * errback, and the task fails, the unhandled failure would not be reported + * by the promise system until the next turn of the event loop: + * + * // Schedule 1 task that fails. + * var result = promise.controlFlow().schedule('example', + * function() { return promise.rejected('failed'); }); + * // Set a callback on the result. This delays reporting the unhandled + * // failure for 1 turn of the event loop. + * result.then(function() {}); + * + * @private {MicroTask} + */ + this.shutdownTask_ = null; + + /** + * ID for a long running interval used to keep a Node.js process running + * while a control flow's event loop is still working. This is a cheap hack + * required since JS events are only scheduled to run when there is + * _actually_ something to run. When a control flow is waiting on a task, + * there will be nothing in the JS event loop and the process would + * terminate without this. + * @private + */ + this.hold_ = null; + } + + /** + * Returns a string representation of this control flow, which is its current + * {@linkplain #getSchedule() schedule}, sans task stack traces. + * @return {string} The string representation of this contorl flow. + * @override + */ + toString() { + return this.getSchedule(); + } + + /** + * Sets whether any unhandled rejections should propagate up through the + * control flow stack and cause rejections within parent tasks. If error + * propagation is disabled, tasks will not be aborted when an unhandled + * promise rejection is detected, but the rejection _will_ trigger an + * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION} + * event. + * + * The default behavior is to propagate all unhandled rejections. _The use + * of this option is highly discouraged._ + * + * @param {boolean} propagate whether to propagate errors. + */ + setPropagateUnhandledRejections(propagate) { + this.propagateUnhandledRejections_ = propagate; + } + + /** + * @return {boolean} Whether this flow is currently idle. + */ + isIdle() { + return !this.shutdownTask_ && (!this.taskQueues_ || !this.taskQueues_.size); + } + + /** + * Resets this instance, clearing its queue and removing all event listeners. + */ + reset() { + this.cancelQueues_(new FlowResetError); + this.emit(ControlFlow.EventType.RESET); + this.removeAllListeners(); + this.cancelShutdown_(); + } + + /** + * Generates an annotated string describing the internal state of this control + * flow, including the currently executing as well as pending tasks. If + * {@code opt_includeStackTraces === true}, the string will include the + * stack trace from when each task was scheduled. + * @param {string=} opt_includeStackTraces Whether to include the stack traces + * from when each task was scheduled. Defaults to false. + * @return {string} String representation of this flow's internal state. + */ + getSchedule(opt_includeStackTraces) { + var ret = 'ControlFlow::' + getUid(this); + var activeQueue = this.activeQueue_; + if (!this.taskQueues_ || !this.taskQueues_.size) { + return ret; + } + var childIndent = '| '; + for (var q of this.taskQueues_) { + ret += '\n' + printQ(q, childIndent); + } + return ret; + + function printQ(q, indent) { + var ret = q.toString(); + if (q === activeQueue) { + ret = '(active) ' + ret; + } + var prefix = indent + childIndent; + if (q.pending_) { + if (q.pending_.q.state_ !== TaskQueueState.FINISHED) { + ret += '\n' + prefix + '(pending) ' + q.pending_.task; + ret += '\n' + printQ(q.pending_.q, prefix + childIndent); + } else { + ret += '\n' + prefix + '(blocked) ' + q.pending_.task; + } + } + if (q.interrupts_) { + q.interrupts_.forEach((task) => { + ret += '\n' + prefix + task; + }); + } + if (q.tasks_) { + q.tasks_.forEach((task) => ret += printTask(task, '\n' + prefix)); + } + return indent + ret; + } + + function printTask(task, prefix) { + var ret = prefix + task; + if (opt_includeStackTraces && task.promise.stack_) { + ret += prefix + childIndent + + (task.promise.stack_.stack || task.promise.stack_) + .replace(/\n/g, prefix); + } + return ret; + } + } + + /** + * Returns the currently actively task queue for this flow. If there is no + * active queue, one will be created. + * @return {!TaskQueue} the currently active task queue for this flow. + * @private + */ + getActiveQueue_() { + if (this.activeQueue_) { + return this.activeQueue_; + } + + this.activeQueue_ = new TaskQueue(this); + if (!this.taskQueues_) { + this.taskQueues_ = new Set(); + } + this.taskQueues_.add(this.activeQueue_); + this.activeQueue_ + .once('end', this.onQueueEnd_, this) + .once('error', this.onQueueError_, this); + + asyncRun(() => this.activeQueue_ = null); + this.activeQueue_.start(); + return this.activeQueue_; + } + + /** + * Schedules a task for execution. If there is nothing currently in the + * queue, the task will be executed in the next turn of the event loop. If + * the task function is a generator, the task will be executed using + * {@link ./promise.consume consume()}. + * + * @param {function(): (T|ManagedPromise)} fn The function to + * call to start the task. If the function returns a + * {@link ManagedPromise}, this instance will wait for it to be + * resolved before starting the next task. + * @param {string=} opt_description A description of the task. + * @return {!ManagedPromise} A promise that will be resolved + * with the result of the action. + * @template T + */ + execute(fn, opt_description) { + if (isGenerator(fn)) { + let original = fn; + fn = () => consume(original); + } + + if (!this.hold_) { + var holdIntervalMs = 2147483647; // 2^31-1; max timer length for Node.js + this.hold_ = setInterval(function() {}, holdIntervalMs); + } + + var task = new Task( + this, fn, opt_description || '', + {name: 'Task', top: ControlFlow.prototype.execute}); + + var q = this.getActiveQueue_(); + q.enqueue(task); + this.emit(ControlFlow.EventType.SCHEDULE_TASK, task.description); + return task.promise; + } + + /** + * Inserts a {@code setTimeout} into the command queue. This is equivalent to + * a thread sleep in a synchronous programming language. + * + * @param {number} ms The timeout delay, in milliseconds. + * @param {string=} opt_description A description to accompany the timeout. + * @return {!ManagedPromise} A promise that will be resolved with + * the result of the action. + */ + timeout(ms, opt_description) { + return this.execute(function() { + return delayed(ms); + }, opt_description); + } + + /** + * Schedules a task that shall wait for a condition to hold. Each condition + * function may return any value, but it will always be evaluated as a + * boolean. + * + * Condition functions may schedule sub-tasks with this instance, however, + * their execution time will be factored into whether a wait has timed out. + * + * In the event a condition returns a ManagedPromise, the polling loop will wait for + * it to be resolved before evaluating whether the condition has been + * satisfied. The resolution time for a promise is factored into whether a + * wait has timed out. + * + * If the condition function throws, or returns a rejected promise, the + * wait task will fail. + * + * If the condition is defined as a promise, the flow will wait for it to + * settle. If the timeout expires before the promise settles, the promise + * returned by this function will be rejected. + * + * If this function is invoked with `timeout === 0`, or the timeout is + * omitted, the flow will wait indefinitely for the condition to be satisfied. + * + * @param {(!ManagedPromise|function())} condition The condition to poll, + * or a promise to wait on. + * @param {number=} opt_timeout How long to wait, in milliseconds, for the + * condition to hold before timing out. If omitted, the flow will wait + * indefinitely. + * @param {string=} opt_message An optional error message to include if the + * wait times out; defaults to the empty string. + * @return {!ManagedPromise} A promise that will be fulfilled + * when the condition has been satisified. The promise shall be rejected + * if the wait times out waiting for the condition. + * @throws {TypeError} If condition is not a function or promise or if timeout + * is not a number >= 0. + * @template T + */ + wait(condition, opt_timeout, opt_message) { + var timeout = opt_timeout || 0; + if (typeof timeout !== 'number' || timeout < 0) { + throw TypeError('timeout must be a number >= 0: ' + timeout); + } + + if (isPromise(condition)) { + return this.execute(function() { + if (!timeout) { + return condition; + } + return new ManagedPromise(function(fulfill, reject) { + var start = Date.now(); + var timer = setTimeout(function() { + timer = null; + reject(Error((opt_message ? opt_message + '\n' : '') + + 'Timed out waiting for promise to resolve after ' + + (Date.now() - start) + 'ms')); + }, timeout); + + /** @type {Thenable} */(condition).then( + function(value) { + timer && clearTimeout(timer); + fulfill(value); + }, + function(error) { + timer && clearTimeout(timer); + reject(error); + }); + }); + }, opt_message || ''); + } + + if (typeof condition !== 'function') { + throw TypeError('Invalid condition; must be a function or promise: ' + + typeof condition); + } + + if (isGenerator(condition)) { + let original = condition; + condition = () => consume(original); + } + + var self = this; + return this.execute(function() { + var startTime = Date.now(); + return new ManagedPromise(function(fulfill, reject) { + pollCondition(); + + function pollCondition() { + var conditionFn = /** @type {function()} */(condition); + self.execute(conditionFn).then(function(value) { + var elapsed = Date.now() - startTime; + if (!!value) { + fulfill(value); + } else if (timeout && elapsed >= timeout) { + reject(new Error((opt_message ? opt_message + '\n' : '') + + 'Wait timed out after ' + elapsed + 'ms')); + } else { + // Do not use asyncRun here because we need a non-micro yield + // here so the UI thread is given a chance when running in a + // browser. + setTimeout(pollCondition, 0); + } + }, reject); + } + }); + }, opt_message || ''); + } + + /** + * Executes a function in the next available turn of the JavaScript event + * loop. This ensures the function runs with its own task queue and any + * scheduled tasks will run in "parallel" to those scheduled in the current + * function. + * + * flow.execute(() => console.log('a')); + * flow.execute(() => console.log('b')); + * flow.execute(() => console.log('c')); + * flow.async(() => { + * flow.execute(() => console.log('d')); + * flow.execute(() => console.log('e')); + * }); + * flow.async(() => { + * flow.execute(() => console.log('f')); + * flow.execute(() => console.log('g')); + * }); + * flow.once('idle', () => console.log('fin')); + * // a + * // d + * // f + * // b + * // e + * // g + * // c + * // fin + * + * If the function itself throws, the error will be treated the same as an + * unhandled rejection within the control flow. + * + * __NOTE__: This function is considered _unstable_. + * + * @param {!Function} fn The function to execute. + * @param {Object=} opt_self The object in whose context to run the function. + * @param {...*} var_args Any arguments to pass to the function. + */ + async(fn, opt_self, var_args) { + asyncRun(() => { + // Clear any lingering queues, forces getActiveQueue_ to create a new one. + this.activeQueue_ = null; + var q = this.getActiveQueue_(); + try { + q.execute_(fn.bind(opt_self, var_args)); + } catch (ex) { + var cancellationError = CancellationError.wrap(ex, + 'Function passed to ControlFlow.async() threw'); + cancellationError.silent_ = true; + q.abort_(cancellationError); + } finally { + this.activeQueue_ = null; + } + }); + } + + /** + * Event handler for when a task queue is exhausted. This starts the shutdown + * sequence for this instance if there are no remaining task queues: after + * one turn of the event loop, this object will emit the + * {@link ControlFlow.EventType.IDLE IDLE} event to signal + * listeners that it has completed. During this wait, if another task is + * scheduled, the shutdown will be aborted. + * + * @param {!TaskQueue} q the completed task queue. + * @private + */ + onQueueEnd_(q) { + if (!this.taskQueues_) { + return; + } + this.taskQueues_.delete(q); + + vlog(1, () => q + ' has finished'); + vlog(1, () => this.taskQueues_.size + ' queues remain\n' + this, this); + + if (!this.taskQueues_.size) { + if (this.shutdownTask_) { + throw Error('Already have a shutdown task??'); + } + vlog(1, () => 'Scheduling shutdown\n' + this); + this.shutdownTask_ = new MicroTask(() => this.shutdown_()); + } + } + + /** + * Event handler for when a task queue terminates with an error. This triggers + * the cancellation of all other task queues and a + * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION} event. + * If there are no error event listeners registered with this instance, the + * error will be rethrown to the global error handler. + * + * @param {*} error the error that caused the task queue to terminate. + * @param {!TaskQueue} q the task queue. + * @private + */ + onQueueError_(error, q) { + if (this.taskQueues_) { + this.taskQueues_.delete(q); + } + this.cancelQueues_(CancellationError.wrap( + error, 'There was an uncaught error in the control flow')); + this.cancelShutdown_(); + this.cancelHold_(); + + var listeners = this.listeners( + ControlFlow.EventType.UNCAUGHT_EXCEPTION); + if (!listeners.size) { + asyncThrow(/** @type {!Error} */(error)); + } else { + this.reportUncaughtException_(error); + } + } + + /** + * Cancels all remaining task queues. + * @param {!CancellationError} reason The cancellation reason. + * @private + */ + cancelQueues_(reason) { + reason.silent_ = true; + if (this.taskQueues_) { + for (var q of this.taskQueues_) { + q.removeAllListeners(); + q.abort_(reason); + } + this.taskQueues_.clear(); + this.taskQueues_ = null; + } + } + + /** + * Reports an uncaught exception using a + * {@link ControlFlow.EventType.UNCAUGHT_EXCEPTION} event. + * + * @param {*} e the error to report. + * @private + */ + reportUncaughtException_(e) { + this.emit(ControlFlow.EventType.UNCAUGHT_EXCEPTION, e); + } + + /** @private */ + cancelHold_() { + if (this.hold_) { + clearInterval(this.hold_); + this.hold_ = null; + } + } + + /** @private */ + shutdown_() { + vlog(1, () => 'Going idle: ' + this); + this.cancelHold_(); + this.shutdownTask_ = null; + this.emit(ControlFlow.EventType.IDLE); + } + + /** + * Cancels the shutdown sequence if it is currently scheduled. + * @private + */ + cancelShutdown_() { + if (this.shutdownTask_) { + this.shutdownTask_.cancel(); + this.shutdownTask_ = null; + } + } +} + + +/** + * Events that may be emitted by an {@link ControlFlow}. + * @enum {string} + */ +ControlFlow.EventType = { + + /** Emitted when all tasks have been successfully executed. */ + IDLE: 'idle', + + /** Emitted when a ControlFlow has been reset. */ + RESET: 'reset', + + /** Emitted whenever a new task has been scheduled. */ + SCHEDULE_TASK: 'scheduleTask', + + /** + * Emitted whenever a control flow aborts due to an unhandled promise + * rejection. This event will be emitted along with the offending rejection + * reason. Upon emitting this event, the control flow will empty its task + * queue and revert to its initial state. + */ + UNCAUGHT_EXCEPTION: 'uncaughtException' +}; + + +/** + * Wraps a function to execute as a cancellable micro task. + * @final + */ +class MicroTask { + /** + * @param {function()} fn The function to run as a micro task. + */ + constructor(fn) { + /** @private {boolean} */ + this.cancelled_ = false; + asyncRun(() => { + if (!this.cancelled_) { + fn(); + } + }); + } + + /** + * Runs the given function after a micro-task yield. + * @param {function()} fn The function to run. + */ + static run(fn) { + NativePromise.resolve().then(function() { + try { + fn(); + } catch (ignored) { + // Do nothing. + } + }); + } + + /** + * Cancels the execution of this task. Note: this will not prevent the task + * timer from firing, just the invocation of the wrapped function. + */ + cancel() { + this.cancelled_ = true; + } +} + + +/** + * A task to be executed by a {@link ControlFlow}. + * + * @template T + * @final + */ +class Task extends Deferred { + /** + * @param {!ControlFlow} flow The flow this instances belongs + * to. + * @param {function(): (T|!ManagedPromise)} fn The function to + * call when the task executes. If it returns a + * {@link ManagedPromise}, the flow will wait for it to be + * resolved before starting the next task. + * @param {string} description A description of the task for debugging. + * @param {{name: string, top: !Function}=} opt_stackOptions Options to use + * when capturing the stacktrace for when this task was created. + */ + constructor(flow, fn, description, opt_stackOptions) { + super(flow); + getUid(this); + + /** @type {function(): (T|!ManagedPromise)} */ + this.execute = fn; + + /** @type {string} */ + this.description = description; + + /** @type {TaskQueue} */ + this.queue = null; + + /** + * Whether this task is considered block. A blocked task may be registered + * in a task queue, but will be dropped if it is still blocked when it + * reaches the front of the queue. A dropped task may always be rescheduled. + * + * Blocked tasks are used when a callback is attached to an unsettled + * promise to reserve a spot in line (in a manner of speaking). If the + * promise is not settled before the callback reaches the front of the + * of the queue, it will be dropped. Once the promise is settled, the + * dropped task will be rescheduled as an interrupt on the currently task + * queue. + * + * @type {boolean} + */ + this.blocked = false; + + if (opt_stackOptions) { + this.promise.stack_ = captureStackTrace( + opt_stackOptions.name, this.description, opt_stackOptions.top); + } + } + + /** @override */ + toString() { + return 'Task::' + getUid(this) + '<' + this.description + '>'; + } +} + + +/** @enum {string} */ +const TaskQueueState = { + NEW: 'new', + STARTED: 'started', + FINISHED: 'finished' +}; + + +/** + * @final + */ +class TaskQueue extends events.EventEmitter { + /** @param {!ControlFlow} flow . */ + constructor(flow) { + super(); + + /** @private {string} */ + this.name_ = 'TaskQueue::' + getUid(this); + + /** @private {!ControlFlow} */ + this.flow_ = flow; + + /** @private {!Array} */ + this.tasks_ = []; + + /** @private {Array} */ + this.interrupts_ = null; + + /** @private {({task: !Task, q: !TaskQueue}|null)} */ + this.pending_ = null; + + /** @private {TaskQueueState} */ + this.state_ = TaskQueueState.NEW; + + /** @private {!Set} */ + this.unhandledRejections_ = new Set(); + } + + /** @override */ + toString() { + return 'TaskQueue::' + getUid(this); + } + + /** + * @param {!ManagedPromise} promise . + */ + addUnhandledRejection(promise) { + // TODO: node 4.0.0+ + vlog(2, () => this + ' registering unhandled rejection: ' + promise, this); + this.unhandledRejections_.add(promise); + } + + /** + * @param {!ManagedPromise} promise . + */ + clearUnhandledRejection(promise) { + var deleted = this.unhandledRejections_.delete(promise); + if (deleted) { + // TODO: node 4.0.0+ + vlog(2, () => this + ' clearing unhandled rejection: ' + promise, this); + } + } + + /** + * Enqueues a new task for execution. + * @param {!Task} task The task to enqueue. + * @throws {Error} If this instance has already started execution. + */ + enqueue(task) { + if (this.state_ !== TaskQueueState.NEW) { + throw Error('TaskQueue has started: ' + this); + } + + if (task.queue) { + throw Error('Task is already scheduled in another queue'); + } + + this.tasks_.push(task); + task.queue = this; + task.promise[CANCEL_HANDLER_SYMBOL] = + this.onTaskCancelled_.bind(this, task); + + vlog(1, () => this + '.enqueue(' + task + ')', this); + vlog(2, () => this.flow_.toString(), this); + } + + /** + * Schedules the callbacks registered on the given promise in this queue. + * + * @param {!ManagedPromise} promise the promise whose callbacks should be + * registered as interrupts in this task queue. + * @throws {Error} if this queue has already finished. + */ + scheduleCallbacks(promise) { + if (this.state_ === TaskQueueState.FINISHED) { + throw new Error('cannot interrupt a finished q(' + this + ')'); + } + + if (this.pending_ && this.pending_.task.promise === promise) { + this.pending_.task.promise.queue_ = null; + this.pending_ = null; + asyncRun(() => this.executeNext_()); + } + + if (!promise.callbacks_) { + return; + } + promise.callbacks_.forEach(function(cb) { + cb.blocked = false; + if (cb.queue) { + return; + } + + cb.promise[CANCEL_HANDLER_SYMBOL] = this.onTaskCancelled_.bind(this, cb); + + if (cb.queue === this && this.tasks_.indexOf(cb) !== -1) { + return; + } + + if (cb.queue) { + cb.queue.dropTask_(cb); + } + + cb.queue = this; + if (!this.interrupts_) { + this.interrupts_ = []; + } + this.interrupts_.push(cb); + }, this); + promise.callbacks_ = null; + vlog(2, () => this + ' interrupted\n' + this.flow_, this); + } + + /** + * Starts executing tasks in this queue. Once called, no further tasks may + * be {@linkplain #enqueue() enqueued} with this instance. + * + * @throws {Error} if this queue has already been started. + */ + start() { + if (this.state_ !== TaskQueueState.NEW) { + throw new Error('TaskQueue has already started'); + } + // Always asynchronously execute next, even if there doesn't look like + // there is anything in the queue. This will catch pending unhandled + // rejections that were registered before start was called. + asyncRun(() => this.executeNext_()); + } + + /** + * Aborts this task queue. If there are any scheduled tasks, they are silently + * cancelled and discarded (their callbacks will never fire). If this queue + * has a _pending_ task, the abortion error is used to cancel that task. + * Otherwise, this queue will emit an error event. + * + * @param {*} error The abortion reason. + * @private + */ + abort_(error) { + var cancellation; + + if (error instanceof FlowResetError) { + cancellation = error; + } else { + cancellation = new DiscardedTaskError(error); + } + + if (this.interrupts_ && this.interrupts_.length) { + this.interrupts_.forEach((t) => t.reject(cancellation)); + this.interrupts_ = []; + } + + if (this.tasks_ && this.tasks_.length) { + this.tasks_.forEach((t) => t.reject(cancellation)); + this.tasks_ = []; + } + + if (this.pending_) { + vlog(2, () => this + '.abort(); cancelling pending task', this); + this.pending_.task.cancel(/** @type {!CancellationError} */(error)); + + } else { + vlog(2, () => this + '.abort(); emitting error event', this); + this.emit('error', error, this); + } + } + + /** @private */ + executeNext_() { + if (this.state_ === TaskQueueState.FINISHED) { + return; + } + this.state_ = TaskQueueState.STARTED; + + if (this.pending_ != null || this.processUnhandledRejections_()) { + return; + } + + var task; + do { + task = this.getNextTask_(); + } while (task && !task.promise.isPending()); + + if (!task) { + this.state_ = TaskQueueState.FINISHED; + this.tasks_ = []; + this.interrupts_ = null; + vlog(2, () => this + '.emit(end)', this); + this.emit('end', this); + return; + } + + var self = this; + var subQ = new TaskQueue(this.flow_); + subQ.once('end', () => self.onTaskComplete_(result)) + .once('error', (e) => self.onTaskFailure_(result, e)); + vlog(2, () => self + ' created ' + subQ + ' for ' + task); + + var result = undefined; + try { + this.pending_ = {task: task, q: subQ}; + task.promise.queue_ = this; + result = subQ.execute_(task.execute); + subQ.start(); + } catch (ex) { + subQ.abort_(ex); + } + } + + /** + * @param {!Function} fn . + * @return {T} . + * @template T + * @private + */ + execute_(fn) { + try { + activeFlows.push(this.flow_); + this.flow_.activeQueue_ = this; + return fn(); + } finally { + this.flow_.activeQueue_ = null; + activeFlows.pop(); + } + } + + /** + * Process any unhandled rejections registered with this task queue. If there + * is a rejection, this queue will be aborted with the rejection error. If + * there are multiple rejections registered, this queue will be aborted with + * a {@link MultipleUnhandledRejectionError}. + * @return {boolean} whether there was an unhandled rejection. + * @private + */ + processUnhandledRejections_() { + if (!this.unhandledRejections_.size) { + return false; + } + + var errors = new Set(); + for (var rejection of this.unhandledRejections_) { + errors.add(rejection.value_); + } + this.unhandledRejections_.clear(); + + var errorToReport = errors.size === 1 + ? errors.values().next().value + : new MultipleUnhandledRejectionError(errors); + + vlog(1, () => this + ' aborting due to unhandled rejections', this); + if (this.flow_.propagateUnhandledRejections_) { + this.abort_(errorToReport); + return true; + } else { + vlog(1, 'error propagation disabled; reporting to control flow'); + this.flow_.reportUncaughtException_(errorToReport); + return false; + } + } + + /** + * @param {!Task} task The task to drop. + * @private + */ + dropTask_(task) { + var index; + if (this.interrupts_) { + index = this.interrupts_.indexOf(task); + if (index != -1) { + task.queue = null; + this.interrupts_.splice(index, 1); + return; + } + } + + index = this.tasks_.indexOf(task); + if (index != -1) { + task.queue = null; + this.tasks_.splice(index, 1); + } + } + + /** + * @param {!Task} task The task that was cancelled. + * @param {!CancellationError} reason The cancellation reason. + * @private + */ + onTaskCancelled_(task, reason) { + if (this.pending_ && this.pending_.task === task) { + this.pending_.q.abort_(reason); + } else { + this.dropTask_(task); + } + } + + /** + * @param {*} value the value originally returned by the task function. + * @private + */ + onTaskComplete_(value) { + if (this.pending_) { + this.pending_.task.fulfill(value); + } + } + + /** + * @param {*} taskFnResult the value originally returned by the task function. + * @param {*} error the error that caused the task function to terminate. + * @private + */ + onTaskFailure_(taskFnResult, error) { + if (Thenable.isImplementation(taskFnResult)) { + taskFnResult.cancel(CancellationError.wrap(error)); + } + this.pending_.task.reject(error); + } + + /** + * @return {(Task|undefined)} the next task scheduled within this queue, + * if any. + * @private + */ + getNextTask_() { + var task = undefined; + while (true) { + if (this.interrupts_) { + task = this.interrupts_.shift(); + } + if (!task && this.tasks_) { + task = this.tasks_.shift(); + } + if (task && task.blocked) { + vlog(2, () => this + ' skipping blocked task ' + task, this); + task.queue = null; + task = null; + // TODO: recurse when tail-call optimization is available in node. + } else { + break; + } + } + return task; + } +}; + + + +/** + * The default flow to use if no others are active. + * @type {!ControlFlow} + */ +var defaultFlow = new ControlFlow(); + + +/** + * A stack of active control flows, with the top of the stack used to schedule + * commands. When there are multiple flows on the stack, the flow at index N + * represents a callback triggered within a task owned by the flow at index + * N-1. + * @type {!Array} + */ +var activeFlows = []; + + +/** + * Changes the default flow to use when no others are active. + * @param {!ControlFlow} flow The new default flow. + * @throws {Error} If the default flow is not currently active. + */ +function setDefaultFlow(flow) { + if (activeFlows.length) { + throw Error('You may only change the default flow while it is active'); + } + defaultFlow = flow; +} + + +/** + * @return {!ControlFlow} The currently active control flow. + */ +function controlFlow() { + return /** @type {!ControlFlow} */ ( + activeFlows.length ? activeFlows[activeFlows.length - 1] : defaultFlow); +} + + +/** + * Creates a new control flow. The provided callback will be invoked as the + * first task within the new flow, with the flow as its sole argument. Returns + * a promise that resolves to the callback result. + * @param {function(!ControlFlow)} callback The entry point + * to the newly created flow. + * @return {!ManagedPromise} A promise that resolves to the callback + * result. + */ +function createFlow(callback) { + var flow = new ControlFlow; + return flow.execute(function() { + return callback(flow); + }); +} + + +/** + * Tests is a function is a generator. + * @param {!Function} fn The function to test. + * @return {boolean} Whether the function is a generator. + */ +function isGenerator(fn) { + return fn.constructor.name === 'GeneratorFunction'; +} + + +/** + * Consumes a {@code GeneratorFunction}. Each time the generator yields a + * promise, this function will wait for it to be fulfilled before feeding the + * fulfilled value back into {@code next}. Likewise, if a yielded promise is + * rejected, the rejection error will be passed to {@code throw}. + * + * __Example 1:__ the Fibonacci Sequence. + * + * promise.consume(function* fibonacci() { + * var n1 = 1, n2 = 1; + * for (var i = 0; i < 4; ++i) { + * var tmp = yield n1 + n2; + * n1 = n2; + * n2 = tmp; + * } + * return n1 + n2; + * }).then(function(result) { + * console.log(result); // 13 + * }); + * + * __Example 2:__ a generator that throws. + * + * promise.consume(function* () { + * yield promise.delayed(250).then(function() { + * throw Error('boom'); + * }); + * }).catch(function(e) { + * console.log(e.toString()); // Error: boom + * }); + * + * @param {!Function} generatorFn The generator function to execute. + * @param {Object=} opt_self The object to use as "this" when invoking the + * initial generator. + * @param {...*} var_args Any arguments to pass to the initial generator. + * @return {!ManagedPromise} A promise that will resolve to the + * generator's final result. + * @throws {TypeError} If the given function is not a generator. + */ +function consume(generatorFn, opt_self, var_args) { + if (!isGenerator(generatorFn)) { + throw new TypeError('Input is not a GeneratorFunction: ' + + generatorFn.constructor.name); + } + + var deferred = defer(); + var generator = generatorFn.apply( + opt_self, Array.prototype.slice.call(arguments, 2)); + callNext(); + return deferred.promise; + + /** @param {*=} opt_value . */ + function callNext(opt_value) { + pump(generator.next, opt_value); + } + + /** @param {*=} opt_error . */ + function callThrow(opt_error) { + // Dictionary lookup required because Closure compiler's built-in + // externs does not include GeneratorFunction.prototype.throw. + pump(generator['throw'], opt_error); + } + + function pump(fn, opt_arg) { + if (!deferred.isPending()) { + return; // Defererd was cancelled; silently abort. + } + + try { + var result = fn.call(generator, opt_arg); + } catch (ex) { + deferred.reject(ex); + return; + } + + if (result.done) { + deferred.fulfill(result.value); + return; + } + + asap(result.value, callNext, callThrow); + } +} + + +// PUBLIC API + + +exports.CancellationError = CancellationError; +exports.ControlFlow = ControlFlow; +exports.Deferred = Deferred; +exports.MultipleUnhandledRejectionError = MultipleUnhandledRejectionError; +exports.Thenable = Thenable; +exports.Promise = ManagedPromise; +exports.all = all; +exports.asap = asap; +exports.captureStackTrace = captureStackTrace; +exports.checkedNodeCall = checkedNodeCall; +exports.consume = consume; +exports.controlFlow = controlFlow; +exports.createFlow = createFlow; +exports.defer = defer; +exports.delayed = delayed; +exports.filter = filter; +exports.fulfilled = fulfilled; +exports.fullyResolved = fullyResolved; +exports.isGenerator = isGenerator; +exports.isPromise = isPromise; +exports.map = map; +exports.rejected = rejected; +exports.setDefaultFlow = setDefaultFlow; +exports.when = when; diff --git a/www/node_modules/selenium-webdriver/lib/safari/client.js b/www/node_modules/selenium-webdriver/lib/safari/client.js new file mode 100644 index 0000000..b15dbd6 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/safari/client.js @@ -0,0 +1,7203 @@ +'use strict';var COMPILED = !0, goog = goog || {}; +goog.global = this; +goog.isDef = function(a) { + return void 0 !== a; +}; +goog.exportPath_ = function(a, b, c) { + a = a.split("."); + c = c || goog.global; + a[0] in c || !c.execScript || c.execScript("var " + a[0]); + for (var d;a.length && (d = a.shift());) { + !a.length && goog.isDef(b) ? c[d] = b : c = c[d] ? c[d] : c[d] = {}; + } +}; +goog.define = function(a, b) { + var c = b; + COMPILED || (goog.global.CLOSURE_UNCOMPILED_DEFINES && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_UNCOMPILED_DEFINES, a) ? c = goog.global.CLOSURE_UNCOMPILED_DEFINES[a] : goog.global.CLOSURE_DEFINES && Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES, a) && (c = goog.global.CLOSURE_DEFINES[a])); + goog.exportPath_(a, c); +}; +goog.DEBUG = !0; +goog.LOCALE = "en"; +goog.TRUSTED_SITE = !0; +goog.STRICT_MODE_COMPATIBLE = !1; +goog.DISALLOW_TEST_ONLY_CODE = COMPILED && !goog.DEBUG; +goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING = !1; +goog.provide = function(a) { + if (!COMPILED && goog.isProvided_(a)) { + throw Error('Namespace "' + a + '" already declared.'); + } + goog.constructNamespace_(a); +}; +goog.constructNamespace_ = function(a, b) { + if (!COMPILED) { + delete goog.implicitNamespaces_[a]; + for (var c = a;(c = c.substring(0, c.lastIndexOf("."))) && !goog.getObjectByName(c);) { + goog.implicitNamespaces_[c] = !0; + } + } + goog.exportPath_(a, b); +}; +goog.VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/; +goog.module = function(a) { + if (!goog.isString(a) || !a || -1 == a.search(goog.VALID_MODULE_RE_)) { + throw Error("Invalid module identifier"); + } + if (!goog.isInModuleLoader_()) { + throw Error("Module " + a + " has been loaded incorrectly."); + } + if (goog.moduleLoaderState_.moduleName) { + throw Error("goog.module may only be called once per module."); + } + goog.moduleLoaderState_.moduleName = a; + if (!COMPILED) { + if (goog.isProvided_(a)) { + throw Error('Namespace "' + a + '" already declared.'); + } + delete goog.implicitNamespaces_[a]; + } +}; +goog.module.get = function(a) { + return goog.module.getInternal_(a); +}; +goog.module.getInternal_ = function(a) { + if (!COMPILED) { + return goog.isProvided_(a) ? a in goog.loadedModules_ ? goog.loadedModules_[a] : goog.getObjectByName(a) : null; + } +}; +goog.moduleLoaderState_ = null; +goog.isInModuleLoader_ = function() { + return null != goog.moduleLoaderState_; +}; +goog.module.declareLegacyNamespace = function() { + if (!COMPILED && !goog.isInModuleLoader_()) { + throw Error("goog.module.declareLegacyNamespace must be called from within a goog.module"); + } + if (!COMPILED && !goog.moduleLoaderState_.moduleName) { + throw Error("goog.module must be called prior to goog.module.declareLegacyNamespace."); + } + goog.moduleLoaderState_.declareLegacyNamespace = !0; +}; +goog.setTestOnly = function(a) { + if (goog.DISALLOW_TEST_ONLY_CODE) { + throw a = a || "", Error("Importing test-only code into non-debug environment" + (a ? ": " + a : ".")); + } +}; +goog.forwardDeclare = function(a) { +}; +COMPILED || (goog.isProvided_ = function(a) { + return a in goog.loadedModules_ || !goog.implicitNamespaces_[a] && goog.isDefAndNotNull(goog.getObjectByName(a)); +}, goog.implicitNamespaces_ = {"goog.module":!0}); +goog.getObjectByName = function(a, b) { + for (var c = a.split("."), d = b || goog.global, e;e = c.shift();) { + if (goog.isDefAndNotNull(d[e])) { + d = d[e]; + } else { + return null; + } + } + return d; +}; +goog.globalize = function(a, b) { + var c = b || goog.global, d; + for (d in a) { + c[d] = a[d]; + } +}; +goog.addDependency = function(a, b, c, d) { + if (goog.DEPENDENCIES_ENABLED) { + var e; + a = a.replace(/\\/g, "/"); + for (var f = goog.dependencies_, g = 0;e = b[g];g++) { + f.nameToPath[e] = a, f.pathIsModule[a] = !!d; + } + for (d = 0;b = c[d];d++) { + a in f.requires || (f.requires[a] = {}), f.requires[a][b] = !0; + } + } +}; +goog.ENABLE_DEBUG_LOADER = !0; +goog.logToConsole_ = function(a) { + goog.global.console && goog.global.console.error(a); +}; +goog.require = function(a) { + if (!COMPILED) { + goog.ENABLE_DEBUG_LOADER && goog.IS_OLD_IE_ && goog.maybeProcessDeferredDep_(a); + if (goog.isProvided_(a)) { + return goog.isInModuleLoader_() ? goog.module.getInternal_(a) : null; + } + if (goog.ENABLE_DEBUG_LOADER) { + var b = goog.getPathFromDeps_(a); + if (b) { + return goog.writeScripts_(b), null; + } + } + a = "goog.require could not find: " + a; + goog.logToConsole_(a); + throw Error(a); + } +}; +goog.basePath = ""; +goog.nullFunction = function() { +}; +goog.abstractMethod = function() { + throw Error("unimplemented abstract method"); +}; +goog.addSingletonGetter = function(a) { + a.getInstance = function() { + if (a.instance_) { + return a.instance_; + } + goog.DEBUG && (goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = a); + return a.instance_ = new a; + }; +}; +goog.instantiatedSingletons_ = []; +goog.LOAD_MODULE_USING_EVAL = !0; +goog.SEAL_MODULE_EXPORTS = goog.DEBUG; +goog.loadedModules_ = {}; +goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER; +goog.DEPENDENCIES_ENABLED && (goog.dependencies_ = {pathIsModule:{}, nameToPath:{}, requires:{}, visited:{}, written:{}, deferred:{}}, goog.inHtmlDocument_ = function() { + var a = goog.global.document; + return null != a && "write" in a; +}, goog.findBasePath_ = function() { + if (goog.isDef(goog.global.CLOSURE_BASE_PATH)) { + goog.basePath = goog.global.CLOSURE_BASE_PATH; + } else { + if (goog.inHtmlDocument_()) { + for (var a = goog.global.document.getElementsByTagName("SCRIPT"), b = a.length - 1;0 <= b;--b) { + var c = a[b].src, d = c.lastIndexOf("?"), d = -1 == d ? c.length : d; + if ("base.js" == c.substr(d - 7, 7)) { + goog.basePath = c.substr(0, d - 7); + break; + } + } + } + } +}, goog.importScript_ = function(a, b) { + (goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_)(a, b) && (goog.dependencies_.written[a] = !0); +}, goog.IS_OLD_IE_ = !(goog.global.atob || !goog.global.document || !goog.global.document.all), goog.importModule_ = function(a) { + goog.importScript_("", 'goog.retrieveAndExecModule_("' + a + '");') && (goog.dependencies_.written[a] = !0); +}, goog.queuedModules_ = [], goog.wrapModule_ = function(a, b) { + return goog.LOAD_MODULE_USING_EVAL && goog.isDef(goog.global.JSON) ? "goog.loadModule(" + goog.global.JSON.stringify(b + "\n//# sourceURL=" + a + "\n") + ");" : 'goog.loadModule(function(exports) {"use strict";' + b + "\n;return exports});\n//# sourceURL=" + a + "\n"; +}, goog.loadQueuedModules_ = function() { + var a = goog.queuedModules_.length; + if (0 < a) { + var b = goog.queuedModules_; + goog.queuedModules_ = []; + for (var c = 0;c < a;c++) { + goog.maybeProcessDeferredPath_(b[c]); + } + } +}, goog.maybeProcessDeferredDep_ = function(a) { + goog.isDeferredModule_(a) && goog.allDepsAreAvailable_(a) && (a = goog.getPathFromDeps_(a), goog.maybeProcessDeferredPath_(goog.basePath + a)); +}, goog.isDeferredModule_ = function(a) { + return (a = goog.getPathFromDeps_(a)) && goog.dependencies_.pathIsModule[a] ? goog.basePath + a in goog.dependencies_.deferred : !1; +}, goog.allDepsAreAvailable_ = function(a) { + if ((a = goog.getPathFromDeps_(a)) && a in goog.dependencies_.requires) { + for (var b in goog.dependencies_.requires[a]) { + if (!goog.isProvided_(b) && !goog.isDeferredModule_(b)) { + return !1; + } + } + } + return !0; +}, goog.maybeProcessDeferredPath_ = function(a) { + if (a in goog.dependencies_.deferred) { + var b = goog.dependencies_.deferred[a]; + delete goog.dependencies_.deferred[a]; + goog.globalEval(b); + } +}, goog.loadModuleFromUrl = function(a) { + goog.retrieveAndExecModule_(a); +}, goog.loadModule = function(a) { + var b = goog.moduleLoaderState_; + try { + goog.moduleLoaderState_ = {moduleName:void 0, declareLegacyNamespace:!1}; + var c; + if (goog.isFunction(a)) { + c = a.call(goog.global, {}); + } else { + if (goog.isString(a)) { + c = goog.loadModuleFromSource_.call(goog.global, a); + } else { + throw Error("Invalid module definition"); + } + } + var d = goog.moduleLoaderState_.moduleName; + if (!goog.isString(d) || !d) { + throw Error('Invalid module name "' + d + '"'); + } + goog.moduleLoaderState_.declareLegacyNamespace ? goog.constructNamespace_(d, c) : goog.SEAL_MODULE_EXPORTS && Object.seal && Object.seal(c); + goog.loadedModules_[d] = c; + } finally { + goog.moduleLoaderState_ = b; + } +}, goog.loadModuleFromSource_ = function(a) { + eval(a); + return {}; +}, goog.writeScriptSrcNode_ = function(a) { + goog.global.document.write('")' + Response.Output.Write(""); + } +} diff --git a/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx b/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx new file mode 100644 index 0000000..52d2e67 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx @@ -0,0 +1,11 @@ +<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Redirect.aspx.cs" Inherits="Redirect" %> + + + + + + Untitled Page + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx.cs b/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx.cs new file mode 100644 index 0000000..9e0650b --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/Redirect.aspx.cs @@ -0,0 +1,9 @@ +using System; + +public partial class Redirect : Page +{ + protected new void Page_Load(object sender, EventArgs e) + { + Response.Redirect("resultPage.html"); + } +} diff --git a/www/node_modules/selenium-webdriver/lib/test/data/Settings.StyleCop b/www/node_modules/selenium-webdriver/lib/test/data/Settings.StyleCop new file mode 100644 index 0000000..fc955f8 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/Settings.StyleCop @@ -0,0 +1,759 @@ + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/Web.Config b/www/node_modules/selenium-webdriver/lib/test/data/Web.Config new file mode 100644 index 0000000..68b648f --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/Web.Config @@ -0,0 +1,59 @@ + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/actualXhtmlPage.xhtml b/www/node_modules/selenium-webdriver/lib/test/data/actualXhtmlPage.xhtml new file mode 100644 index 0000000..a0f5470 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/actualXhtmlPage.xhtml @@ -0,0 +1,14 @@ + + + + + + Title + + + +

    + Foo +

    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/ajaxy_page.html b/www/node_modules/selenium-webdriver/lib/test/data/ajaxy_page.html new file mode 100644 index 0000000..4b34031 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/ajaxy_page.html @@ -0,0 +1,81 @@ + + + +
    + + +
    + + Red + Green +
    + +
    + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/alerts.html b/www/node_modules/selenium-webdriver/lib/test/data/alerts.html new file mode 100644 index 0000000..1add0db --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/alerts.html @@ -0,0 +1,85 @@ + + + + + Testing Alerts + + + + + +

    Testing Alerts and Stuff

    + +

    This tests alerts: click me

    + +

    This tests alerts: click me

    + +

    Let's make the prompt happen

    + +

    Let's make the prompt with default happen

    + +

    Let's make TWO prompts happen

    + +

    A SLOW alert

    + +

    This is a test of a confirm: + test confirm

    + +

    This is a test of showModalDialog: test dialog

    + +

    This is a test of an alert in an iframe: + +

    + +

    This is a test of an alert in a nested iframe: + +

    + +

    This is a test of an alert open from onload event handler: open new page

    + +

    This is a test of an alert open from onload event handler: open new window

    + +

    This is a test of an alert open from onunload event handler: open new page

    + +

    This is a test of an alert open from onclose event handler: open new window

    + +

    This is a test of an alert open from onclose event handler: open new window

    + +
    +
    +
    + +

    +

    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/banner.gif b/www/node_modules/selenium-webdriver/lib/test/data/banner.gif new file mode 100644 index 0000000..3f34354 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/banner.gif differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/beach.jpg b/www/node_modules/selenium-webdriver/lib/test/data/beach.jpg new file mode 100644 index 0000000..402237c Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/beach.jpg differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/blank.html b/www/node_modules/selenium-webdriver/lib/test/data/blank.html new file mode 100644 index 0000000..c3f376e --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/blank.html @@ -0,0 +1 @@ +blank diff --git a/www/node_modules/selenium-webdriver/lib/test/data/bodyTypingTest.html b/www/node_modules/selenium-webdriver/lib/test/data/bodyTypingTest.html new file mode 100644 index 0000000..f2b1939 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/bodyTypingTest.html @@ -0,0 +1,41 @@ + + + + Testing Typing into body + + + + +

    Type Stuff

    + +
    +   +
    + +
    +   +
    + + + + +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/booleanAttributes.html b/www/node_modules/selenium-webdriver/lib/test/data/booleanAttributes.html new file mode 100644 index 0000000..16fbbe9 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/booleanAttributes.html @@ -0,0 +1,19 @@ + + + Elements with boolean attributes + + +
    + + + + + +
    + + +
    + +
    Unwrappable text
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/child/childPage.html b/www/node_modules/selenium-webdriver/lib/test/data/child/childPage.html new file mode 100644 index 0000000..9192b54 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/child/childPage.html @@ -0,0 +1,8 @@ + + + Depth one child page + + +

    I'm a page in a child directory

    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/child/grandchild/grandchildPage.html b/www/node_modules/selenium-webdriver/lib/test/data/child/grandchild/grandchildPage.html new file mode 100644 index 0000000..f52685e --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/child/grandchild/grandchildPage.html @@ -0,0 +1,8 @@ + + + Depth two child page + + +

    I'm a page in a grandchild directory! How cute!

    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/clickEventPage.html b/www/node_modules/selenium-webdriver/lib/test/data/clickEventPage.html new file mode 100644 index 0000000..8e0355d --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/clickEventPage.html @@ -0,0 +1,26 @@ + + + + Testing click events + + + +
    + Click me to view my coordinates +
    + +
    +

     

    +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_frames.html b/www/node_modules/selenium-webdriver/lib/test/data/click_frames.html new file mode 100644 index 0000000..bd055c7 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_frames.html @@ -0,0 +1,10 @@ + + + click frames + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_jacker.html b/www/node_modules/selenium-webdriver/lib/test/data/click_jacker.html new file mode 100644 index 0000000..0ff3900 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_jacker.html @@ -0,0 +1,38 @@ + + + + click-jacking + + + +
    +
    Click jacked!
    +
    Click Me
    + +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds.html b/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds.html new file mode 100644 index 0000000..8a51659 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds.html @@ -0,0 +1,23 @@ + + + + + + + + + + + +
    +
    +
    +
    +
    + +
    +
    +
    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds_overflow.html b/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds_overflow.html new file mode 100644 index 0000000..15ac17f --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_out_of_bounds_overflow.html @@ -0,0 +1,85 @@ + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    data
    click me
    +
    + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_rtl.html b/www/node_modules/selenium-webdriver/lib/test/data/click_rtl.html new file mode 100644 index 0000000..e84fffa --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_rtl.html @@ -0,0 +1,19 @@ + + +RTL test + + + +
    + +
    Ù…ÙØªØ§Ø­ معايير الويب
    + +
    פעילות הבינ×ו×
    + +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_source.html b/www/node_modules/selenium-webdriver/lib/test/data/click_source.html new file mode 100644 index 0000000..22e9319 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_source.html @@ -0,0 +1,18 @@ + + + Click Source + + + I go to a target + + + + + + Click Source + + + I go to a target + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_iframe.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_iframe.html new file mode 100644 index 0000000..7b749bc --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_iframe.html @@ -0,0 +1,6 @@ + + + click iframe + +Click me + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_in_iframe.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_in_iframe.html new file mode 100644 index 0000000..60b1cca --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/click_in_iframe.html @@ -0,0 +1,8 @@ + + + click in iframe + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_frame.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_frame.html new file mode 100644 index 0000000..d6f4caf --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_frame.html @@ -0,0 +1 @@ +Continue \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_target.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_target.html new file mode 100644 index 0000000..cbc16e8 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/issue5237_target.html @@ -0,0 +1,10 @@ + + + + Target page for issue 5237 + + +

    Test passed

    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/link_that_wraps.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/link_that_wraps.html new file mode 100644 index 0000000..0443436 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/link_that_wraps.html @@ -0,0 +1,11 @@ + + + + Link that continues on next line + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page1.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page1.html new file mode 100644 index 0000000..245f038 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page1.html @@ -0,0 +1,9 @@ + + + + Target Page 1 + + +
    Target Page 1
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page2.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page2.html new file mode 100644 index 0000000..6f9636c --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page2.html @@ -0,0 +1,9 @@ + + + + Target Page 2 + + +
    Target Page 2
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page3.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page3.html new file mode 100644 index 0000000..87a35f3 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/mapped_page3.html @@ -0,0 +1,9 @@ + + + + Target Page 3 + + +
    Target Page 3
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/overlapping_elements.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/overlapping_elements.html new file mode 100644 index 0000000..6cfa56a --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/overlapping_elements.html @@ -0,0 +1,70 @@ + + + + An element that disappears on click + + + +

    Hello

    +

    Hello

    +
    +
    +

    Log:

    +

    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/partially_overlapping_elements.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/partially_overlapping_elements.html new file mode 100644 index 0000000..2af6252 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/partially_overlapping_elements.html @@ -0,0 +1,124 @@ + + + + An element that disappears on click + + + +

    Hello

    +

    Hello

    +
    +
    +
    +
    +
    +
    +

    Log:

    +

    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/span_that_wraps.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/span_that_wraps.html new file mode 100644 index 0000000..77a9d6d --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/span_that_wraps.html @@ -0,0 +1,11 @@ + + + + Link that continues on next line + + +
    +
    placeholder
    Span that continues on next line +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/submitted_page.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/submitted_page.html new file mode 100644 index 0000000..0ed2cba --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/submitted_page.html @@ -0,0 +1,9 @@ + + + +Submitted Successfully! + + +

    Submitted Successfully!

    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_tests/wrapped_overlapping_elements.html b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/wrapped_overlapping_elements.html new file mode 100644 index 0000000..1c0c3d0 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_tests/wrapped_overlapping_elements.html @@ -0,0 +1,13 @@ + + + + A wrapped element with overlapped first part + + +
    +
    placeholder
    +
    Over
    + Link that continues on next line +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_too_big.html b/www/node_modules/selenium-webdriver/lib/test/data/click_too_big.html new file mode 100644 index 0000000..568ee77 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_too_big.html @@ -0,0 +1,10 @@ + + + + +
    +       +
    +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/click_too_big_in_frame.html b/www/node_modules/selenium-webdriver/lib/test/data/click_too_big_in_frame.html new file mode 100644 index 0000000..cda990e --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/click_too_big_in_frame.html @@ -0,0 +1,11 @@ + + + This page has iframes + + +

    This is the heading

    + + + + +
    +I'm a normal link +
    +I go to an anchor +
    +I open a window with javascript +
    +Click me +
    + +
    +I'm a green link +

    looooooooooong short looooooooooong +

    + +333333 +

    I have a span

    And another span

    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/closeable_window.html b/www/node_modules/selenium-webdriver/lib/test/data/closeable_window.html new file mode 100644 index 0000000..e64c599 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/closeable_window.html @@ -0,0 +1,8 @@ + + +closeable window + + +This window can be closed by clicking on this. + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/cn-test.html b/www/node_modules/selenium-webdriver/lib/test/data/cn-test.html new file mode 100644 index 0000000..df846ad --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/cn-test.html @@ -0,0 +1,156 @@ + + + + + + + + + + +
    +
    + + +

    Õ¹Íû2008ÊÀ½ç´óÊÆ£º·çÆðÔÆÓ¿ ¼¤µ´ÈËÐÄ


    +
    + 8ÔÂ8ÈÕÍí£¬±±¾©2008Äê°ÂÔ˻ᵹ¼ÆÊ±Ò»ÖÜÄêÇì×£»î¶¯ÔÚÌì°²ÃŹ㳡¾ÙÐС£Í¼ÎªÇì×£»î¶¯ÖеÄÎÄÒÕÑݳö¡£ лªÉç¼ÇÕßÁõÎÀ±øÉã + + £²£°£°£¸ÄêÊÀ½ç·çÆðÔÆÓ¿£¬¼¤µ´ÈËÐÄ¡£µ«Òª×÷³öÒ»¸öÔ¤²â£¬Ê×ÏÈÒª¶Ô½ñÌìËù´¦µÄÊÀ½çÓÐÒ»¸ö»ù±¾¹²Ê¶¡£
    +
    +ÖйúÖ®Éù
    +
    +
    + +
    + +
    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/colorPage.html b/www/node_modules/selenium-webdriver/lib/test/data/colorPage.html new file mode 100644 index 0000000..0d1bfc0 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/colorPage.html @@ -0,0 +1,20 @@ + + + + Color Page + + +
    namedColor
    +
    rgb
    +
    rgbpct
    +
    hex
    +
    hex
    +
    hsl
    +
    rgba
    +
    rgba
    +
    hsla
    + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/cookies.html b/www/node_modules/selenium-webdriver/lib/test/data/cookies.html new file mode 100644 index 0000000..7db5b49 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/cookies.html @@ -0,0 +1,30 @@ + + + Testing cookies + + + + +

    Cookie Mashing

    + .com Click
    + . Click
    + google.com Click
    + .google.com Click
    + 127.0.0.1 Click
    + localhost:3001 Click
    + .google:3001 Click
    + 172.16.12.225 Click
    + 172.16.12.225:port Click
    + Set on a different path + +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_frame.html b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_frame.html new file mode 100644 index 0000000..7714a48 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_frame.html @@ -0,0 +1,9 @@ + + + + Welcome Page + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_nested_frame.html b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_nested_frame.html new file mode 100644 index 0000000..b3143b0 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/element_in_nested_frame.html @@ -0,0 +1,9 @@ + + + + Welcome Page + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_element_out_of_view.html b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_element_out_of_view.html new file mode 100644 index 0000000..6f2bcd4 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_element_out_of_view.html @@ -0,0 +1,11 @@ + + + + Page With Element Out Of View + + +
    Placeholder
    +
    Red box
    +
    Tex after box
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_empty_element.html b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_empty_element.html new file mode 100644 index 0000000..b07972a --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_empty_element.html @@ -0,0 +1,10 @@ + + + + Page With Empty Element + + +
    +
    Tex after box
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_fixed_element.html b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_fixed_element.html new file mode 100644 index 0000000..6cbb273 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_fixed_element.html @@ -0,0 +1,12 @@ + + + + Page With Fixed Element + + +
    fixed red box
    +
    Placeholder
    +
    Element at the bottom
    +
    Tex after box
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_hidden_element.html b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_hidden_element.html new file mode 100644 index 0000000..286b04b --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_hidden_element.html @@ -0,0 +1,10 @@ + + + + Page With Hidden Element + + + +
    Tex after box
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_invisible_element.html b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_invisible_element.html new file mode 100644 index 0000000..dc33c71 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_invisible_element.html @@ -0,0 +1,10 @@ + + + + Page With Invisible Element + + + +
    Tex after box
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_transparent_element.html b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_transparent_element.html new file mode 100644 index 0000000..d0090d9 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/page_with_transparent_element.html @@ -0,0 +1,10 @@ + + + + Page With Transparent Element + + +
    Hidden box
    +
    Tex after box
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/simple_page.html b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/simple_page.html new file mode 100644 index 0000000..7b857b9 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/coordinates_tests/simple_page.html @@ -0,0 +1,10 @@ + + + + Simple Page + + +
    Red box
    +
    Tex after box
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png new file mode 100644 index 0000000..954e22d Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png new file mode 100644 index 0000000..64ece57 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png new file mode 100644 index 0000000..abdc010 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png new file mode 100644 index 0000000..9b383f4 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png new file mode 100644 index 0000000..a23baad Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 0000000..42ccba2 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png new file mode 100644 index 0000000..39d5824 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png new file mode 100644 index 0000000..f127367 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png new file mode 100644 index 0000000..359397a Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_222222_256x240.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000..b273ff1 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_222222_256x240.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_228ef1_256x240.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_228ef1_256x240.png new file mode 100644 index 0000000..a641a37 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_228ef1_256x240.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ef8c08_256x240.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ef8c08_256x240.png new file mode 100644 index 0000000..85e63e9 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ef8c08_256x240.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffd27a_256x240.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffd27a_256x240.png new file mode 100644 index 0000000..e117eff Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffd27a_256x240.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffffff_256x240.png b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffffff_256x240.png new file mode 100644 index 0000000..42f8f99 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/images/ui-icons_ffffff_256x240.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/jquery-ui-1.8.10.custom.css b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/jquery-ui-1.8.10.custom.css new file mode 100644 index 0000000..1706e22 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/css/ui-lightness/jquery-ui-1.8.10.custom.css @@ -0,0 +1,573 @@ +/* + * jQuery UI CSS Framework 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; } +.ui-widget-content a { color: #333333; } +.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; } +.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); } +.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/* + * jQuery UI Resizable 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * jQuery UI Selectable 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * jQuery UI Accordion 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/* + * jQuery UI Autocomplete 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.10 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * jQuery UI Button 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Dialog 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* + * jQuery UI Slider 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * jQuery UI Tabs 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/* + * jQuery UI Datepicker 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* + * jQuery UI Progressbar 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/cssTransform.html b/www/node_modules/selenium-webdriver/lib/test/data/cssTransform.html new file mode 100644 index 0000000..c3b9964 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/cssTransform.html @@ -0,0 +1,61 @@ + + +
    +You shouldn't see anything other than this sentence on the page +
    +
    + I have a hidden child +
    + I am a hidden child +
    +
    +
    + I have a hidden child +
    + I am a hidden child +
    +
    +
    I am a hidden element
    +
    I am a hidden element
    diff --git a/www/node_modules/selenium-webdriver/lib/test/data/cssTransform2.html b/www/node_modules/selenium-webdriver/lib/test/data/cssTransform2.html new file mode 100644 index 0000000..602924b --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/cssTransform2.html @@ -0,0 +1,20 @@ + + +
    +
    +
    +
    +
    +
    +
    I am not a hidden element
    diff --git a/www/node_modules/selenium-webdriver/lib/test/data/document_write_in_onload.html b/www/node_modules/selenium-webdriver/lib/test/data/document_write_in_onload.html new file mode 100644 index 0000000..a15fc47 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/document_write_in_onload.html @@ -0,0 +1,13 @@ + + + Document Write In Onload + + + +

    hello world

    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropInsideScrolledDiv.html b/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropInsideScrolledDiv.html new file mode 100644 index 0000000..0b2ee9a --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropInsideScrolledDiv.html @@ -0,0 +1,67 @@ + + + + + + + +
    +
    +
    +
    +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropTest.html b/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropTest.html new file mode 100644 index 0000000..fdee16b --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/dragAndDropTest.html @@ -0,0 +1,102 @@ + + + + + + + + +
    +
    +"Hi there +
    +
    +
    +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/dragDropOverflow.html b/www/node_modules/selenium-webdriver/lib/test/data/dragDropOverflow.html new file mode 100644 index 0000000..ecb2562 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/dragDropOverflow.html @@ -0,0 +1,104 @@ + + + + + + +
    +
    +
    +
    +
    12am
    +
    1am
    +
    2am
    +
    3am
    +
    4am
    +
    5am
    +
    6am
    +
    7am
    +
    8am
    +
    9am
    +
    10am
    +
    11am
    +
    12pm
    +
    1pm
    +
    2pm
    +
    3pm
    +
    4pm
    +
    5pm
    +
    6pm
    +
    7pm
    +
    8pm
    +
    9pm
    +
    10pm
    +
    11pm
    +
    +
    +
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/draggableLists.html b/www/node_modules/selenium-webdriver/lib/test/data/draggableLists.html new file mode 100644 index 0000000..f7e0dca --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/draggableLists.html @@ -0,0 +1,67 @@ + + + + + jQuery UI Sortable - Connect lists + + + + + + + + + +
    +
      +
    • LeftItem 1
    • +
    • LeftItem 2
    • +
    • LeftItem 3
    • +
    • LeftItem 4
    • +
    • LeftItem 5
    • +
    + +
      +
    • RightItem 1
    • +
    • RightItem 2
    • +
    • RightItem 3
    • +
    • RightItem 4
    • +
    • RightItem 5
    • +
    + +
    + +
    +
    +

    Nothing happened.

    +
    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/droppableItems.html b/www/node_modules/selenium-webdriver/lib/test/data/droppableItems.html new file mode 100644 index 0000000..fc850ac --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/droppableItems.html @@ -0,0 +1,65 @@ + + + + + jQuery UI Droppable - Default Demo + + + + + + + +
    + +
    +

    Drag me to my target

    +
    + +
    +

    Drop here

    +
    + +
    +

    start

    +
    + +
    + +
    + +

    Taken from the JQuery demo.

    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/dynamic.html b/www/node_modules/selenium-webdriver/lib/test/data/dynamic.html new file mode 100644 index 0000000..b9e6067 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/dynamic.html @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/dynamicallyModifiedPage.html b/www/node_modules/selenium-webdriver/lib/test/data/dynamicallyModifiedPage.html new file mode 100644 index 0000000..ed7c7ed --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/dynamicallyModifiedPage.html @@ -0,0 +1,42 @@ + + + + Delayed remove of an element + + + + + +
    + +
    +

    element

    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/errors.html b/www/node_modules/selenium-webdriver/lib/test/data/errors.html new file mode 100644 index 0000000..78fb902 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/errors.html @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/firefox/jetpack-sample.xpi b/www/node_modules/selenium-webdriver/lib/test/data/firefox/jetpack-sample.xpi new file mode 100644 index 0000000..84d6493 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/firefox/jetpack-sample.xpi differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/firefox/sample.xpi b/www/node_modules/selenium-webdriver/lib/test/data/firefox/sample.xpi new file mode 100644 index 0000000..062f9a1 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/firefox/sample.xpi differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScroll.html b/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScroll.html new file mode 100644 index 0000000..ca65d1f --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScroll.html @@ -0,0 +1,13 @@ + + + + Fixed footer with no scrollbar + + +
    +
    + Click me +
    +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScrollQuirksMode.html b/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScrollQuirksMode.html new file mode 100644 index 0000000..2593bf3 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/fixedFooterNoScrollQuirksMode.html @@ -0,0 +1,12 @@ + + + Fixed footer with no scrollbar + + +
    +
    + Click me +
    +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/formPage.html b/www/node_modules/selenium-webdriver/lib/test/data/formPage.html new file mode 100644 index 0000000..7bcfea0 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/formPage.html @@ -0,0 +1,174 @@ + + + We Leave From Here + + + + +There should be a form here: + +
    + + + +
    + +
    + +
    + +
    + Here's a checkbox: + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + Cheese
    + Peas
    + Cheese and peas
    + Not a sausage
    + Not another sausage + + + +

    I like cheese

    + + + Cumberland sausage +
    + +
    + + + + + + + + +
    + +
    + + + + + + + +
    + +
    + + + + + + + +
    + + +
    +
    + +
    + +
    + + +
    +

    + + + +

    +
    + +
    + + + +
    +

    + +

    +
    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/formSelectionPage.html b/www/node_modules/selenium-webdriver/lib/test/data/formSelectionPage.html new file mode 100644 index 0000000..4890c08 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/formSelectionPage.html @@ -0,0 +1,46 @@ + + + + Testing Typing into body + + + + +

    Type Stuff

    + +
    +   +
    + +
    + +
    + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/form_handling_js_submit.html b/www/node_modules/selenium-webdriver/lib/test/data/form_handling_js_submit.html new file mode 100644 index 0000000..3023143 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/form_handling_js_submit.html @@ -0,0 +1,30 @@ + + + + + + Form with JS action + + +
    + +
    + +

    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/framePage3.html b/www/node_modules/selenium-webdriver/lib/test/data/framePage3.html new file mode 100644 index 0000000..3e62e45 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/framePage3.html @@ -0,0 +1,7 @@ + + + inner + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/frameScrollChild.html b/www/node_modules/selenium-webdriver/lib/test/data/frameScrollChild.html new file mode 100644 index 0000000..3eb3bf4 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/frameScrollChild.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

    This is a scrolling frame test

    +
    + + + + + + + + + + + + + +
    First row
    Second row
    Third row
    Fourth row
    +
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/frameScrollPage.html b/www/node_modules/selenium-webdriver/lib/test/data/frameScrollPage.html new file mode 100644 index 0000000..b7fb8f2 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/frameScrollPage.html @@ -0,0 +1,14 @@ + + + + Welcome Page + + +
    + +
    +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/frameScrollParent.html b/www/node_modules/selenium-webdriver/lib/test/data/frameScrollParent.html new file mode 100644 index 0000000..8fccb6d --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/frameScrollParent.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/frameWithAnimals.html b/www/node_modules/selenium-webdriver/lib/test/data/frameWithAnimals.html new file mode 100644 index 0000000..1e0dc87 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/frameWithAnimals.html @@ -0,0 +1,11 @@ + + + This page has iframes + + +

    This is the heading

    + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876_iframe.html b/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876_iframe.html new file mode 100644 index 0000000..57d47d8 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/bug4876_iframe.html @@ -0,0 +1,9 @@ + + + +
    + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame.html b/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame.html new file mode 100644 index 0000000..9c27e04 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame.html @@ -0,0 +1,29 @@ + + + Deleting frame: main page + + + + +
    + + +
    +
    + +
    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe.html b/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe.html new file mode 100644 index 0000000..e4b9723 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe.html @@ -0,0 +1,8 @@ + + + Deleting frame: iframe + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe2.html b/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe2.html new file mode 100644 index 0000000..47764eb --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/frame_switching_tests/deletingFrame_iframe2.html @@ -0,0 +1,7 @@ + + + Deleting frame: iframe 2 + + +
    Added back
    + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/frameset.html b/www/node_modules/selenium-webdriver/lib/test/data/frameset.html new file mode 100644 index 0000000..039c5f2 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/frameset.html @@ -0,0 +1,14 @@ + + + Unique title + + + + + + + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/framesetPage2.html b/www/node_modules/selenium-webdriver/lib/test/data/framesetPage2.html new file mode 100644 index 0000000..4ea35ff --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/framesetPage2.html @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/framesetPage3.html b/www/node_modules/selenium-webdriver/lib/test/data/framesetPage3.html new file mode 100644 index 0000000..42a9300 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/framesetPage3.html @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/globalscope.html b/www/node_modules/selenium-webdriver/lib/test/data/globalscope.html new file mode 100644 index 0000000..e4ca97a --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/globalscope.html @@ -0,0 +1,15 @@ + + + + Global scope + + + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/hidden.html b/www/node_modules/selenium-webdriver/lib/test/data/hidden.html new file mode 100644 index 0000000..0e8097e --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/hidden.html @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/html5/blue.jpg b/www/node_modules/selenium-webdriver/lib/test/data/html5/blue.jpg new file mode 100644 index 0000000..8ea27c4 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/html5/blue.jpg differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/html5/database.js b/www/node_modules/selenium-webdriver/lib/test/data/html5/database.js new file mode 100644 index 0000000..c6333be --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/html5/database.js @@ -0,0 +1,84 @@ +var database={}; +database.db={}; + +database.onError = function(tx, e) { + var log = document.createElement('div'); + log.setAttribute('name','error'); + log.setAttribute('style','background-color:red'); + log.innerText = e.message; + document.getElementById('logs').appendChild(log); +} + +database.onSuccess = function(tx, r) { + if (r.rows.length) { + var ol; + for (var i = 0; i < r.rows.length; i++) { + ol = document.createElement('ol'); + ol.innerHTML = r.rows.item(i).ID + ": " + r.rows.item(i).docname + " (" + r.rows.item(i).created + ")"; + document.getElementById('logs').appendChild(ol); + } + + } +} + +database.open=function(){ + database.db=openDatabase('HTML5', '1.0', 'Offline document storage', 100*1024); +} + +database.create=function(){ + database.db.transaction(function(tx) { + tx.executeSql("CREATE TABLE IF NOT EXISTS docs(ID INTEGER PRIMARY KEY ASC, docname TEXT, created TIMESTAMP DEFAULT CURRENT_TIMESTAMP)", + [], + database.onSuccess, + database.onError); + });} + +database.add = function(message) { + database.db.transaction(function(tx){ + tx.executeSql("INSERT INTO docs(docname) VALUES (?)", + [message], database.onSuccess, database.onError); + }); +} + +database.selectAll = function() { + database.db.transaction(function(tx) { + tx.executeSql("SELECT * FROM docs", [], database.onSuccess, + database.onError); + }); +} + +database.onDeleteAllSuccess = function(tx, r) { + var doc = document.documentElement; + var db_completed = document.createElement("div"); + db_completed.setAttribute("id", "db_completed"); + db_completed.innerText = "db operation completed"; + doc.appendChild(db_completed); +} + +database.deleteAll = function() { + database.db.transaction(function(tx) { + tx.executeSql("delete from docs", [], database.onDeleteAllSuccess, + database.onError); + }); +} + +var log = document.createElement('div'); +log.setAttribute('name','notice'); +log.setAttribute('style','background-color:yellow'); +log.innerText = typeof window.openDatabase == "function" ? "Web Database is supported." : "Web Database is not supported."; +document.getElementById('logs').appendChild(log); + +try { + database.open(); + database.create(); + database.add('Doc 1'); + database.add('Doc 2'); + database.selectAll(); + database.deleteAll(); +} catch(error) { + var log = document.createElement('div'); + log.setAttribute('name','critical'); + log.setAttribute('style','background-color:pink'); + log.innerText = error; + document.getElementById('logs').appendChild(log); +} diff --git a/www/node_modules/selenium-webdriver/lib/test/data/html5/geolocation.js b/www/node_modules/selenium-webdriver/lib/test/data/html5/geolocation.js new file mode 100644 index 0000000..f07af14 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/html5/geolocation.js @@ -0,0 +1,18 @@ +function success(position) { + var message = document.getElementById("status"); + message.innerHTML =""; + message.innerHTML += "

    Longitude: " + position.coords.longitude + "

    "; + message.innerHTML += "

    Latitude: " + position.coords.latitude + "

    "; + message.innerHTML += "

    Altitude: " + position.coords.altitude + "

    "; +} + +function error(msg) { + var message = document.getElementById("status"); + message.innerHTML = "Failed to get geolocation."; +} + +if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(success, error); +} else { + error('Geolocation is not supported.'); +} \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/html5/green.jpg b/www/node_modules/selenium-webdriver/lib/test/data/html5/green.jpg new file mode 100644 index 0000000..6a0d3be Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/html5/green.jpg differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/html5/red.jpg b/www/node_modules/selenium-webdriver/lib/test/data/html5/red.jpg new file mode 100644 index 0000000..f296e27 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/html5/red.jpg differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/html5/status.html b/www/node_modules/selenium-webdriver/lib/test/data/html5/status.html new file mode 100644 index 0000000..394116a --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/html5/status.html @@ -0,0 +1 @@ +Online diff --git a/www/node_modules/selenium-webdriver/lib/test/data/html5/test.appcache b/www/node_modules/selenium-webdriver/lib/test/data/html5/test.appcache new file mode 100644 index 0000000..3bc4e00 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/html5/test.appcache @@ -0,0 +1,11 @@ +CACHE MANIFEST + +CACHE: +# Additional items to cache. +yellow.jpg +red.jpg +blue.jpg +green.jpg + +FALLBACK: +status.html offline.html diff --git a/www/node_modules/selenium-webdriver/lib/test/data/html5/yellow.jpg b/www/node_modules/selenium-webdriver/lib/test/data/html5/yellow.jpg new file mode 100644 index 0000000..7c609b3 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/html5/yellow.jpg differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/html5Page.html b/www/node_modules/selenium-webdriver/lib/test/data/html5Page.html new file mode 100644 index 0000000..355ddc3 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/html5Page.html @@ -0,0 +1,32 @@ + + +HTML5 + + + +

    Geolocation Test

    +
    Location unknown
    + + +

    Web SQL Database Test

    +
    + + +

    Application Cache Test

    +
    +

    Current network status:

    + + + + + +
    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/icon.gif b/www/node_modules/selenium-webdriver/lib/test/data/icon.gif new file mode 100644 index 0000000..bb99461 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/icon.gif differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/iframeAtBottom.html b/www/node_modules/selenium-webdriver/lib/test/data/iframeAtBottom.html new file mode 100644 index 0000000..a686ba3 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/iframeAtBottom.html @@ -0,0 +1,15 @@ + + + This page has iframes + + +

    This is the heading

    + +
    + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/iframes.html b/www/node_modules/selenium-webdriver/lib/test/data/iframes.html new file mode 100644 index 0000000..e00b482 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/iframes.html @@ -0,0 +1,11 @@ + + + This page has iframes + + +

    This is the heading

    + +':"");a._keyEvent=false;return I},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='
    ', +o="";if(h||!j)o+=''+i[b]+"";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='"}u||(k+=o+(h||!(j&& +l)?" ":""));a.yearshtml="";if(h||!l)k+=''+c+"";else{g=this._get(a,"yearRange").split(":");var r=(new Date).getFullYear();i=function(s){s=s.match(/c[+-].*/)?c+parseInt(s.substring(1),10):s.match(/[+-].*/)?r+parseInt(s,10):parseInt(s,10);return isNaN(s)?r:s};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b,e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='";if(d.browser.mozilla)k+='";else{k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="
    ";return k},_adjustInstDate:function(a,b,c){var e= +a.drawYear+(c=="Y"?b:0),f=a.drawMonth+(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&ba?a:b},_notifyChange:function(a){var b=this._get(a, +"onChangeMonthYear");if(b)b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a); +c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a, +"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker= +function(a){if(!this.length)return this;if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker, +[this[0]].concat(b));return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new K;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.10";window["DP_jQuery_"+y]=d})(jQuery); +;/* + * jQuery UI Progressbar 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("
    ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); +this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* +this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.10"})})(jQuery); +;/* + * jQuery UI Effects 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/ + */ +jQuery.effects||function(f,j){function n(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], +16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return o.transparent;return o[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return n(b)}function p(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle, +a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function q(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d= +a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function m(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor", +"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=n(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var o={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0, +0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211, +211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},r=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b, +d){if(f.isFunction(b)){d=b;b=null}return this.queue("fx",function(){var e=f(this),g=e.attr("style")||" ",h=q(p.call(this)),l,v=e.attr("className");f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});l=q(p.call(this));e.attr("className",v);e.animate(u(h,l),a,b,function(){f.each(r,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments)});h=f.queue(this);l=h.splice(h.length-1,1)[0]; +h.splice(1,0,l);f.dequeue(this)})};f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c, +a):f.effects.animateClass.apply(this,[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.10",save:function(c,a){for(var b=0;b
    ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent", +border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c); +return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)});return d.call(this,b)},_show:f.fn.show,show:function(c){if(m(c))return this._show.apply(this,arguments); +else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(m(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(m(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c), +b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c, +a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c, +a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a== +e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h
    ").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ +e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); +;/* + * jQuery UI Effects Fade 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fade + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Fold 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fold + * + * Depends: + * jquery.effects.core.js + */ +(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1], +10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); +;/* + * jQuery UI Effects Highlight 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Highlight + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& +this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Pulsate 1.8.10 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Pulsate + * + * Depends: + * jquery.effects.core.js + */ +(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c
    ').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); +b.dequeue()})})}})(jQuery); +; \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.inline.min.css b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.inline.min.css new file mode 100644 index 0000000..9f194f6 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.inline.min.css @@ -0,0 +1 @@ +.mce-object{border:1px dotted #3A3A3A;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0px}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp{background:#AAA}hr{cursor:default}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333} \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.min.css b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.min.css new file mode 100644 index 0000000..ea08c68 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/content.min.css @@ -0,0 +1 @@ +body{background-color:#FFFFFF;color:#000000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDDDDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px}.mce-object{border:1px dotted #3A3A3A;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0px}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp{background:#AAA}hr{cursor:default}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333} \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/readme.md b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/readme.md new file mode 100644 index 0000000..fa5d639 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/readme.md @@ -0,0 +1 @@ +Icons are generated and provided by the http://icomoon.io service. diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.dev.svg b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.dev.svg new file mode 100644 index 0000000..578b869 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.dev.svg @@ -0,0 +1,175 @@ + + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.eot b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.eot new file mode 100644 index 0000000..60e2d2e Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.eot differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.svg b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.svg new file mode 100644 index 0000000..930c48d --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.svg @@ -0,0 +1,62 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.ttf b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.ttf new file mode 100644 index 0000000..afc6ec4 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.ttf differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.woff b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.woff new file mode 100644 index 0000000..fa72c74 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce-small.woff differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.dev.svg b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.dev.svg new file mode 100644 index 0000000..c87b8cd --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.dev.svg @@ -0,0 +1,153 @@ + + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.eot b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.eot new file mode 100644 index 0000000..c1085bf Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.eot differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.svg b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.svg new file mode 100644 index 0000000..feb9ba3 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.svg @@ -0,0 +1,63 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.ttf b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.ttf new file mode 100644 index 0000000..58103c2 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.ttf differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.woff b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.woff new file mode 100644 index 0000000..ad1ae39 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/fonts/tinymce.woff differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/anchor.gif b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/anchor.gif new file mode 100644 index 0000000..606348c Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/anchor.gif differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/loader.gif b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/loader.gif new file mode 100644 index 0000000..c69e937 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/loader.gif differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/object.gif b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/object.gif new file mode 100644 index 0000000..cccd7f0 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/object.gif differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/trans.gif b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/trans.gif new file mode 100644 index 0000000..3884865 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/img/trans.gif differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.ie7.min.css b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.ie7.min.css new file mode 100644 index 0000000..cd2bbdf --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.ie7.min.css @@ -0,0 +1 @@ +.mce-container,.mce-container *,.mce-widget,.mce-widget *,.mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:normal;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible !important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.mce-wordcount{position:absolute;top:0;right:0;padding:8px}div.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #9e9e9e;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:#d9d9d9}.mce-grid td div{border:1px solid #d6d6d6;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:focus{border-color:#a1a1a1}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover,.mce-grid a:focus{border-color:#a1a1a1}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#d6d6d6;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#a1a1a1;background:#c8def4}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-toolbar-grp{padding-bottom:2px}.mce-toolbar-grp .mce-flow-layout-item{margin-bottom:0}.mce-rtl .mce-wordcount{left:0;right:auto}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-panel{border:0 solid #9e9e9e;background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fdfdfd, #ddd);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fdfdfd), to(#ddd));background-image:-webkit-linear-gradient(top, #fdfdfd, #ddd);background-image:-o-linear-gradient(top, #fdfdfd, #ddd);background-image:linear-gradient(to bottom, #fdfdfd, #ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd', endColorstr='#ffdddddd', GradientType=0);zoom:1}.mce-floatpanel{position:absolute;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2)}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);top:0;left:0;background:#fff;border:1px solid #9e9e9e;border:1px solid rgba(0,0,0,0.25)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px;*margin-top:0}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#9e9e9e;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#fff;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#fff;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #c5c5c5;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#858585;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#adadad}.mce-window-head .mce-title{line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#fff;border-top:1px solid #c5c5c5;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-rtl .mce-window-head .mce-close{position:absolute;right:auto;left:15px}.mce-rtl .mce-window-head .mce-dragh{left:auto;right:0}.mce-rtl .mce-window-head .mce-title{direction:rtl;text-align:right}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000000;-moz-box-shadow:0 0 5px #000000;box-shadow:0 0 5px #000000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0px;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);position:relative;text-shadow:0 1px 1px rgba(255,255,255,0.75);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1}.mce-btn:hover,.mce-btn:focus{color:#333;background-color:#e3e3e3;background-image:-moz-linear-gradient(top, #f2f2f2, #ccc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#ccc));background-image:-webkit-linear-gradient(top, #f2f2f2, #ccc);background-image:-o-linear-gradient(top, #f2f2f2, #ccc);background-image:linear-gradient(to bottom, #f2f2f2, #ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffcccccc', GradientType=0);zoom:1}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn:not(.mce-disabled):active{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{min-width:50px;color:#fff;border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #08c, #04c);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));background-image:-webkit-linear-gradient(top, #08c, #04c);background-image:-o-linear-gradient(top, #08c, #04c);background-image:linear-gradient(to bottom, #08c, #04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);zoom:1}.mce-primary:hover,.mce-primary:focus{background-color:#005fb3;background-image:-moz-linear-gradient(top, #0077b3, #003cb3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0077b3), to(#003cb3));background-image:-webkit-linear-gradient(top, #0077b3, #003cb3);background-image:-o-linear-gradient(top, #0077b3, #003cb3);background-image:linear-gradient(to bottom, #0077b3, #003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3', endColorstr='#ff003cb3', GradientType=0);zoom:1}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{background-color:#005299;background-image:-moz-linear-gradient(top, #069, #039);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#069), to(#039));background-image:-webkit-linear-gradient(top, #069, #039);background-image:-o-linear-gradient(top, #069, #039);background-image:linear-gradient(to bottom, #069, #039);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff006699', endColorstr='#ff003399', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-primary button,.mce-primary button i{color:#fff;text-shadow:1px 1px #333}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:1px 5px;font-size:12px;*padding-bottom:2px}.mce-btn-small i{line-height:20px;vertical-align:top;*line-height:18px}.mce-btn .mce-caret{margin-top:8px;margin-left:0}.mce-btn-small .mce-caret{margin-top:8px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #333;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #333;border-top:0}.mce-rtl .mce-btn button{direction:rtl}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-first{border-left:1px solid #b1b1b1;border-left:1px solid rgba(0,0,0,0.25);-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #b1b1b1;border-right:1px solid rgba(0,0,0,0.1);-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#333;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#acacac}.mce-rtl .mce-checkbox{direction:rtl;text-align:right}.mce-rtl i.mce-i-checkbox{margin:0 0 0 3px}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-14px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-16px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;border-left:1px solid transparent;border-right:1px solid transparent}.mce-colorbutton:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-colorbutton.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-colorbutton{direction:rtl}.mce-rtl .mce-colorbutton .mce-preview{margin-left:0;padding-right:0;padding-left:4px;margin-right:-14px}.mce-rtl .mce-colorbutton.mce-btn-small .mce-preview{margin-left:0;padding-right:0;margin-right:-17px;padding-left:0}.mce-rtl .mce-colorbutton button{padding-right:10px;padding-left:10px}.mce-rtl .mce-colorbutton .mce-open{padding-left:4px;padding-right:4px}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);*height:32px}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#adadad}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#333}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:#666;color:#fff}.mce-path .mce-divider{display:inline}.mce-disabled .mce-path-item{color:#aaa}.mce-rtl .mce-path{direction:rtl}.mce-fieldset{border:0 solid #9E9E9E;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-rtl .mce-flow-layout{text-align:right;direction:rtl}.mce-rtl .mce-flow-layout-item{margin:2px 2px 2px 0}.mce-rtl .mce-flow-layout-item.mce-last{margin-left:2px}.mce-iframe{border:0 solid #9e9e9e;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label.mce-disabled{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-label.mce-error{color:#a00}.mce-rtl .mce-label{text-align:right;direction:rtl}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #c4c4c4}.mce-menubar .mce-menubtn button span{color:#333}.mce-menubar .mce-caret{border-top-color:#333}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:transparent;background:#e6e6e6;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-menubtn span{color:#333;margin-right:2px;line-height:20px;*line-height:16px}.mce-menubtn.mce-btn-small span{font-size:12px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-menubtn .mce-caret{*margin-top:6px}.mce-rtl .mce-menubtn button{direction:rtl;text-align:right}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-rtl .mce-listbox .mce-caret{right:auto;left:8px}.mce-rtl .mce-listbox button{padding-right:10px;padding-left:20px}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-ico,.mce-menu-item .mce-text{color:#333}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled .mce-ico{color:#adadad}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text,.mce-menu-item:focus .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:#fff}.mce-menu-item.mce-disabled:hover{background:#ccc}.mce-menu-shortcut{display:inline-block;color:#adadad}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 15px 0 20px}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item.mce-selected .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:#fff}.mce-menu-item .mce-caret{margin-top:4px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #333}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret,.mce-menu-item:hover .mce-caret{border-left-color:#fff}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item-normal.mce-active{background-color:#c8def4}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa}.mce-menu-item-normal.mce-active .mce-text{color:#333}.mce-menu-item-normal.mce-active:hover .mce-text,.mce-menu-item-normal.mce-active:hover .mce-ico{color:#fff}.mce-menu-item-normal.mce-active:focus .mce-text,.mce-menu-item-normal.mce-active:focus .mce-ico{color:#fff}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #08c, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);zoom:1}div.mce-menu .mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#cbcbcb;border-bottom:1px solid #fff;cursor:default;filter:none}.mce-menu.mce-rtl{direction:rtl}.mce-rtl .mce-menu-item{text-align:right;direction:rtl;padding:6px 12px 6px 15px}.mce-menu-align.mce-rtl .mce-menu-shortcut,.mce-menu-align.mce-rtl .mce-caret{right:auto;left:0}.mce-rtl .mce-menu-item .mce-caret{margin-left:6px;margin-right:0;border-right:4px solid #333;border-left:0}.mce-rtl .mce-menu-item.mce-selected .mce-caret,.mce-rtl .mce-menu-item:focus .mce-caret,.mce-rtl .mce-menu-item:hover .mce-caret{border-left-color:transparent;border-right-color:#fff}.mce-menu{position:absolute;left:0;top:0;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#fff;border:1px solid #989898;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#333}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-splitbtn.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-splitbtn{direction:rtl;text-align:right}.mce-rtl .mce-splitbtn button{padding-right:10px;padding-left:10px}.mce-rtl .mce-splitbtn .mce-open{padding-left:4px;padding-right:4px}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-rtl .mce-tabs{text-align:right;direction:rtl}.mce-rtl .mce-tab{border-width:0 0 0 1px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);display:inline-block;-webkit-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#333}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-textbox.mce-disabled{color:#adadad}.mce-rtl .mce-textbox{text-align:right;direction:rtl}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}.mce-throbber-inline{position:static;height:50px}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce';font-style:normal;font-weight:normal;font-size:16px;line-height:16px;vertical-align:text-top;-webkit-font-smoothing:antialiased;display:inline-block;background:transparent center center;width:16px;height:16px;color:#333;-ie7-icon:' '}.mce-btn-small .mce-ico{font-family:'tinymce-small'}.mce-ico,i.mce-i-checkbox{zoom:expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = this.currentStyle['-ie7-icon'].substr(1, 1) + ' ')}.mce-i-save{-ie7-icon:"\e000"}.mce-i-newdocument{-ie7-icon:"\e001"}.mce-i-fullpage{-ie7-icon:"\e002"}.mce-i-alignleft{-ie7-icon:"\e003"}.mce-i-aligncenter{-ie7-icon:"\e004"}.mce-i-alignright{-ie7-icon:"\e005"}.mce-i-alignjustify{-ie7-icon:"\e006"}.mce-i-cut{-ie7-icon:"\e007"}.mce-i-paste{-ie7-icon:"\e008"}.mce-i-searchreplace{-ie7-icon:"\e009"}.mce-i-bullist{-ie7-icon:"\e00a"}.mce-i-numlist{-ie7-icon:"\e00b"}.mce-i-indent{-ie7-icon:"\e00c"}.mce-i-outdent{-ie7-icon:"\e00d"}.mce-i-blockquote{-ie7-icon:"\e00e"}.mce-i-undo{-ie7-icon:"\e00f"}.mce-i-redo{-ie7-icon:"\e010"}.mce-i-link{-ie7-icon:"\e011"}.mce-i-unlink{-ie7-icon:"\e012"}.mce-i-anchor{-ie7-icon:"\e013"}.mce-i-image{-ie7-icon:"\e014"}.mce-i-media{-ie7-icon:"\e015"}.mce-i-help{-ie7-icon:"\e016"}.mce-i-code{-ie7-icon:"\e017"}.mce-i-insertdatetime{-ie7-icon:"\e018"}.mce-i-preview{-ie7-icon:"\e019"}.mce-i-forecolor{-ie7-icon:"\e01a"}.mce-i-backcolor{-ie7-icon:"\e01a"}.mce-i-table{-ie7-icon:"\e01b"}.mce-i-hr{-ie7-icon:"\e01c"}.mce-i-removeformat{-ie7-icon:"\e01d"}.mce-i-subscript{-ie7-icon:"\e01e"}.mce-i-superscript{-ie7-icon:"\e01f"}.mce-i-charmap{-ie7-icon:"\e020"}.mce-i-emoticons{-ie7-icon:"\e021"}.mce-i-print{-ie7-icon:"\e022"}.mce-i-fullscreen{-ie7-icon:"\e023"}.mce-i-spellchecker{-ie7-icon:"\e024"}.mce-i-nonbreaking{-ie7-icon:"\e025"}.mce-i-template{-ie7-icon:"\e026"}.mce-i-pagebreak{-ie7-icon:"\e027"}.mce-i-restoredraft{-ie7-icon:"\e028"}.mce-i-untitled{-ie7-icon:"\e029"}.mce-i-bold{-ie7-icon:"\e02a"}.mce-i-italic{-ie7-icon:"\e02b"}.mce-i-underline{-ie7-icon:"\e02c"}.mce-i-strikethrough{-ie7-icon:"\e02d"}.mce-i-visualchars{-ie7-icon:"\e02e"}.mce-i-ltr{-ie7-icon:"\e02f"}.mce-i-rtl{-ie7-icon:"\e030"}.mce-i-copy{-ie7-icon:"\e031"}.mce-i-resize{-ie7-icon:"\e032"}.mce-i-browse{-ie7-icon:"\e034"}.mce-i-pastetext{-ie7-icon:"\e035"}.mce-i-checkbox,.mce-i-selected{-ie7-icon:"\e033"}.mce-i-selected{visibility:hidden}.mce-i-backcolor{background:#BBB} \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.min.css b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.min.css new file mode 100644 index 0000000..284ac1d --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/js/skins/lightgray/skin.min.css @@ -0,0 +1 @@ +.mce-container,.mce-container *,.mce-widget,.mce-widget *,.mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:normal;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible !important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.mce-wordcount{position:absolute;top:0;right:0;padding:8px}div.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #9e9e9e;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:#d9d9d9}.mce-grid td div{border:1px solid #d6d6d6;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid td div:focus{border-color:#a1a1a1}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover,.mce-grid a:focus{border-color:#a1a1a1}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#d6d6d6;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#a1a1a1;background:#c8def4}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-toolbar-grp{padding-bottom:2px}.mce-toolbar-grp .mce-flow-layout-item{margin-bottom:0}.mce-rtl .mce-wordcount{left:0;right:auto}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-panel{border:0 solid #9e9e9e;background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fdfdfd, #ddd);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fdfdfd), to(#ddd));background-image:-webkit-linear-gradient(top, #fdfdfd, #ddd);background-image:-o-linear-gradient(top, #fdfdfd, #ddd);background-image:linear-gradient(to bottom, #fdfdfd, #ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffdfdfd', endColorstr='#ffdddddd', GradientType=0);zoom:1}.mce-floatpanel{position:absolute;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2)}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);top:0;left:0;background:#fff;border:1px solid #9e9e9e;border:1px solid rgba(0,0,0,0.25)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px;*margin-top:0}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#9e9e9e;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#fff;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#fff;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #c5c5c5;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#858585;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#adadad}.mce-window-head .mce-title{line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#fff;border-top:1px solid #c5c5c5;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-rtl .mce-window-head .mce-close{position:absolute;right:auto;left:15px}.mce-rtl .mce-window-head .mce-dragh{left:auto;right:0}.mce-rtl .mce-window-head .mce-title{direction:rtl;text-align:right}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-inner{-webkit-box-shadow:0 0 5px #000000;-moz-box-shadow:0 0 5px #000000;box-shadow:0 0 5px #000000}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0px;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);position:relative;text-shadow:0 1px 1px rgba(255,255,255,0.75);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1}.mce-btn:hover,.mce-btn:focus{color:#333;background-color:#e3e3e3;background-image:-moz-linear-gradient(top, #f2f2f2, #ccc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#ccc));background-image:-webkit-linear-gradient(top, #f2f2f2, #ccc);background-image:-o-linear-gradient(top, #f2f2f2, #ccc);background-image:linear-gradient(to bottom, #f2f2f2, #ccc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffcccccc', GradientType=0);zoom:1}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn:not(.mce-disabled):active{background-color:#d6d6d6;background-image:-moz-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#e6e6e6), to(#c0c0c0));background-image:-webkit-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:-o-linear-gradient(top, #e6e6e6, #c0c0c0);background-image:linear-gradient(to bottom, #e6e6e6, #c0c0c0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6', endColorstr='#ffc0c0c0', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{min-width:50px;color:#fff;border:1px solid #b1b1b1;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25) rgba(0,0,0,0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #08c, #04c);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#04c));background-image:-webkit-linear-gradient(top, #08c, #04c);background-image:-o-linear-gradient(top, #08c, #04c);background-image:linear-gradient(to bottom, #08c, #04c);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);zoom:1}.mce-primary:hover,.mce-primary:focus{background-color:#005fb3;background-image:-moz-linear-gradient(top, #0077b3, #003cb3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0077b3), to(#003cb3));background-image:-webkit-linear-gradient(top, #0077b3, #003cb3);background-image:-o-linear-gradient(top, #0077b3, #003cb3);background-image:linear-gradient(to bottom, #0077b3, #003cb3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0077b3', endColorstr='#ff003cb3', GradientType=0);zoom:1}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{background-color:#005299;background-image:-moz-linear-gradient(top, #069, #039);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#069), to(#039));background-image:-webkit-linear-gradient(top, #069, #039);background-image:-o-linear-gradient(top, #069, #039);background-image:linear-gradient(to bottom, #069, #039);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff006699', endColorstr='#ff003399', GradientType=0);zoom:1;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-primary button,.mce-primary button i{color:#fff;text-shadow:1px 1px #333}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:1px 5px;font-size:12px;*padding-bottom:2px}.mce-btn-small i{line-height:20px;vertical-align:top;*line-height:18px}.mce-btn .mce-caret{margin-top:8px;margin-left:0}.mce-btn-small .mce-caret{margin-top:8px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #333;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #333;border-top:0}.mce-rtl .mce-btn button{direction:rtl}.mce-btn-group .mce-btn{border-width:1px 0 1px 0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-first{border-left:1px solid #b1b1b1;border-left:1px solid rgba(0,0,0,0.25);-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #b1b1b1;border-right:1px solid rgba(0,0,0,0.1);-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f0f0f0;background-image:-moz-linear-gradient(top, #fff, #d9d9d9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9d9d9));background-image:-webkit-linear-gradient(top, #fff, #d9d9d9);background-image:-o-linear-gradient(top, #fff, #d9d9d9);background-image:linear-gradient(to bottom, #fff, #d9d9d9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9d9d9', GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#333;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#acacac}.mce-rtl .mce-checkbox{direction:rtl;text-align:right}.mce-rtl i.mce-i-checkbox{margin:0 0 0 3px}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-14px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-16px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;border-left:1px solid transparent;border-right:1px solid transparent}.mce-colorbutton:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-colorbutton.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-colorbutton{direction:rtl}.mce-rtl .mce-colorbutton .mce-preview{margin-left:0;padding-right:0;padding-left:4px;margin-right:-14px}.mce-rtl .mce-colorbutton.mce-btn-small .mce-preview{margin-left:0;padding-right:0;margin-right:-17px;padding-left:0}.mce-rtl .mce-colorbutton button{padding-right:10px;padding-left:10px}.mce-rtl .mce-colorbutton .mce-open{padding-left:4px;padding-right:4px}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);*height:32px}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#adadad}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#333}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:#666;color:#fff}.mce-path .mce-divider{display:inline}.mce-disabled .mce-path-item{color:#aaa}.mce-rtl .mce-path{direction:rtl}.mce-fieldset{border:0 solid #9E9E9E;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-rtl .mce-flow-layout{text-align:right;direction:rtl}.mce-rtl .mce-flow-layout-item{margin:2px 2px 2px 0}.mce-rtl .mce-flow-layout-item.mce-last{margin-left:2px}.mce-iframe{border:0 solid #9e9e9e;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label.mce-disabled{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-label.mce-error{color:#a00}.mce-rtl .mce-label{text-align:right;direction:rtl}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #c4c4c4}.mce-menubar .mce-menubtn button span{color:#333}.mce-menubar .mce-caret{border-top-color:#333}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:transparent;background:#e6e6e6;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-menubtn span{color:#333;margin-right:2px;line-height:20px;*line-height:16px}.mce-menubtn.mce-btn-small span{font-size:12px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-menubtn .mce-caret{*margin-top:6px}.mce-rtl .mce-menubtn button{direction:rtl;text-align:right}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-rtl .mce-listbox .mce-caret{right:auto;left:8px}.mce-rtl .mce-listbox button{padding-right:10px;padding-left:20px}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-ico,.mce-menu-item .mce-text{color:#333}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled .mce-ico{color:#adadad}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text,.mce-menu-item:focus .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:#fff}.mce-menu-item.mce-disabled:hover{background:#ccc}.mce-menu-shortcut{display:inline-block;color:#adadad}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 15px 0 20px}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item.mce-selected .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:#fff}.mce-menu-item .mce-caret{margin-top:4px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #333}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret,.mce-menu-item:hover .mce-caret{border-left-color:#fff}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item-normal.mce-active{background-color:#c8def4}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa}.mce-menu-item-normal.mce-active .mce-text{color:#333}.mce-menu-item-normal.mce-active:hover .mce-text,.mce-menu-item-normal.mce-active:hover .mce-ico{color:#fff}.mce-menu-item-normal.mce-active:focus .mce-text,.mce-menu-item-normal.mce-active:focus .mce-ico{color:#fff}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #08c, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);zoom:1}div.mce-menu .mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#cbcbcb;border-bottom:1px solid #fff;cursor:default;filter:none}.mce-menu.mce-rtl{direction:rtl}.mce-rtl .mce-menu-item{text-align:right;direction:rtl;padding:6px 12px 6px 15px}.mce-menu-align.mce-rtl .mce-menu-shortcut,.mce-menu-align.mce-rtl .mce-caret{right:auto;left:0}.mce-rtl .mce-menu-item .mce-caret{margin-left:6px;margin-right:0;border-right:4px solid #333;border-left:0}.mce-rtl .mce-menu-item.mce-selected .mce-caret,.mce-rtl .mce-menu-item:focus .mce-caret,.mce-rtl .mce-menu-item:hover .mce-caret{border-left-color:transparent;border-right-color:#fff}.mce-menu{position:absolute;left:0;top:0;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#fff;border:1px solid #989898;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#333}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-splitbtn.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-splitbtn{direction:rtl;text-align:right}.mce-rtl .mce-splitbtn button{padding-right:10px;padding-left:10px}.mce-rtl .mce-splitbtn .mce-open{padding-left:4px;padding-right:4px}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-rtl .mce-tabs{text-align:right;direction:rtl}.mce-rtl .mce-tab{border-width:0 0 0 1px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);display:inline-block;-webkit-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#333}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-textbox.mce-disabled{color:#adadad}.mce-rtl .mce-textbox{text-align:right;direction:rtl}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}.mce-throbber-inline{position:static;height:50px}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce',Arial;font-style:normal;font-weight:normal;font-variant:normal;font-size:16px;line-height:16px;speak:none;vertical-align:text-top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;background:transparent center center;background-size:cover;width:16px;height:16px;color:#333}.mce-btn-small .mce-ico{font-family:'tinymce-small',Arial}.mce-i-save:before{content:"\e000"}.mce-i-newdocument:before{content:"\e001"}.mce-i-fullpage:before{content:"\e002"}.mce-i-alignleft:before{content:"\e003"}.mce-i-aligncenter:before{content:"\e004"}.mce-i-alignright:before{content:"\e005"}.mce-i-alignjustify:before{content:"\e006"}.mce-i-cut:before{content:"\e007"}.mce-i-paste:before{content:"\e008"}.mce-i-searchreplace:before{content:"\e009"}.mce-i-bullist:before{content:"\e00a"}.mce-i-numlist:before{content:"\e00b"}.mce-i-indent:before{content:"\e00c"}.mce-i-outdent:before{content:"\e00d"}.mce-i-blockquote:before{content:"\e00e"}.mce-i-undo:before{content:"\e00f"}.mce-i-redo:before{content:"\e010"}.mce-i-link:before{content:"\e011"}.mce-i-unlink:before{content:"\e012"}.mce-i-anchor:before{content:"\e013"}.mce-i-image:before{content:"\e014"}.mce-i-media:before{content:"\e015"}.mce-i-help:before{content:"\e016"}.mce-i-code:before{content:"\e017"}.mce-i-insertdatetime:before{content:"\e018"}.mce-i-preview:before{content:"\e019"}.mce-i-forecolor:before{content:"\e01a"}.mce-i-backcolor:before{content:"\e01a"}.mce-i-table:before{content:"\e01b"}.mce-i-hr:before{content:"\e01c"}.mce-i-removeformat:before{content:"\e01d"}.mce-i-subscript:before{content:"\e01e"}.mce-i-superscript:before{content:"\e01f"}.mce-i-charmap:before{content:"\e020"}.mce-i-emoticons:before{content:"\e021"}.mce-i-print:before{content:"\e022"}.mce-i-fullscreen:before{content:"\e023"}.mce-i-spellchecker:before{content:"\e024"}.mce-i-nonbreaking:before{content:"\e025"}.mce-i-template:before{content:"\e026"}.mce-i-pagebreak:before{content:"\e027"}.mce-i-restoredraft:before{content:"\e028"}.mce-i-untitled:before{content:"\e029"}.mce-i-bold:before{content:"\e02a"}.mce-i-italic:before{content:"\e02b"}.mce-i-underline:before{content:"\e02c"}.mce-i-strikethrough:before{content:"\e02d"}.mce-i-visualchars:before{content:"\e02e"}.mce-i-visualblocks:before{content:"\e02e"}.mce-i-ltr:before{content:"\e02f"}.mce-i-rtl:before{content:"\e030"}.mce-i-copy:before{content:"\e031"}.mce-i-resize:before{content:"\e032"}.mce-i-browse:before{content:"\e034"}.mce-i-pastetext:before{content:"\e035"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#bbb} \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/js/themes/modern/theme.min.js b/www/node_modules/selenium-webdriver/lib/test/data/js/themes/modern/theme.min.js new file mode 100644 index 0000000..e25849d --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/js/themes/modern/theme.min.js @@ -0,0 +1 @@ +tinymce.ThemeManager.add("modern",function(e){function t(){function t(t){var n,o=[];if(t)return d(t.split(/[ ,]/),function(t){function i(){var i=e.selection;"bullist"==r&&i.selectorChanged("ul > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"UL"==n)}),"numlist"==r&&i.selectorChanged("ol > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"OL"==n)}),t.settings.stateSelector&&i.selectorChanged(t.settings.stateSelector,function(e){t.active(e)},!0),t.settings.disabledStateSelector&&i.selectorChanged(t.settings.disabledStateSelector,function(e){t.disabled(e)})}var r;"|"==t?n=null:c.has(t)?(t={type:t},u.toolbar_items_size&&(t.size=u.toolbar_items_size),o.push(t),n=null):(n||(n={type:"buttongroup",items:[]},o.push(n)),e.buttons[t]&&(r=t,t=e.buttons[r],"function"==typeof t&&(t=t()),t.type=t.type||"button",u.toolbar_items_size&&(t.size=u.toolbar_items_size),t=c.create(t),n.items.push(t),e.initialized?i():e.on("init",i)))}),i.push({type:"toolbar",layout:"flow",items:o}),!0}var i=[];if(tinymce.isArray(u.toolbar)){if(0===u.toolbar.length)return;tinymce.each(u.toolbar,function(e,t){u["toolbar"+(t+1)]=e}),delete u.toolbar}for(var n=1;10>n&&t(u["toolbar"+n]);n++);return i.length||u.toolbar===!1||t(u.toolbar||f),i.length?{type:"panel",layout:"stack",classes:"toolbar-grp",ariaRoot:!0,ariaRemember:!0,items:i}:void 0}function i(){function t(t){var i;return"|"==t?{text:"|"}:i=e.menuItems[t]}function i(i){var n,o,r,a,s;if(s=tinymce.makeMap((u.removed_menuitems||"").split(/[ ,]/)),u.menu?(o=u.menu[i],a=!0):o=h[i],o){n={text:o.title},r=[],d((o.items||"").split(/[ ,]/),function(e){var i=t(e);i&&!s[e]&&r.push(t(e))}),a||d(e.menuItems,function(e){e.context==i&&("before"==e.separator&&r.push({text:"|"}),e.prependToContext?r.unshift(e):r.push(e),"after"==e.separator&&r.push({text:"|"}))});for(var l=0;lr;r++)if(o=n[r],o&&o.func.call(o.scope,e)===!1&&e.preventDefault(),e.isImmediatePropagationStopped())return}var a=this,s={},l,c,u,d,f;c=o+(+new Date).toString(32),d="onmouseenter"in document.documentElement,u="onfocusin"in document.documentElement,f={mouseenter:"mouseover",mouseleave:"mouseout"},l=1,a.domLoaded=!1,a.events=s,a.bind=function(t,o,p,h){function m(e){i(n(e||_.event),g)}var g,v,y,b,C,x,w,_=window;if(t&&3!==t.nodeType&&8!==t.nodeType){for(t[c]?g=t[c]:(g=l++,t[c]=g,s[g]={}),h=h||t,o=o.split(" "),y=o.length;y--;)b=o[y],x=m,C=w=!1,"DOMContentLoaded"===b&&(b="ready"),a.domLoaded&&"ready"===b&&"complete"==t.readyState?p.call(h,n({type:b})):(d||(C=f[b],C&&(x=function(e){var t,r;if(t=e.currentTarget,r=e.relatedTarget,r&&t.contains)r=t.contains(r);else for(;r&&r!==t;)r=r.parentNode;r||(e=n(e||_.event),e.type="mouseout"===e.type?"mouseleave":"mouseenter",e.target=t,i(e,g))})),u||"focusin"!==b&&"focusout"!==b||(w=!0,C="focusin"===b?"focus":"blur",x=function(e){e=n(e||_.event),e.type="focus"===e.type?"focusin":"focusout",i(e,g)}),v=s[g][b],v?"ready"===b&&a.domLoaded?p({type:b}):v.push({func:p,scope:h}):(s[g][b]=v=[{func:p,scope:h}],v.fakeName=C,v.capture=w,v.nativeHandler=x,"ready"===b?r(t,x,a):e(t,C||b,x,w)));return t=v=0,p}},a.unbind=function(e,n,r){var i,o,l,u,d,f;if(!e||3===e.nodeType||8===e.nodeType)return a;if(i=e[c]){if(f=s[i],n){for(n=n.split(" "),l=n.length;l--;)if(d=n[l],o=f[d]){if(r)for(u=o.length;u--;)if(o[u].func===r){var p=o.nativeHandler,h=o.fakeName,m=o.capture;o=o.slice(0,u).concat(o.slice(u+1)),o.nativeHandler=p,o.fakeName=h,o.capture=m,f[d]=o}r&&0!==o.length||(delete f[d],t(e,o.fakeName||d,o.nativeHandler,o.capture))}}else{for(d in f)o=f[d],t(e,o.fakeName||d,o.nativeHandler,o.capture);f={}}for(d in f)return a;delete s[i];try{delete e[c]}catch(g){e[c]=null}}return a},a.fire=function(e,t,r){var o;if(!e||3===e.nodeType||8===e.nodeType)return a;r=n(null,r),r.type=t,r.target=e;do o=e[c],o&&i(r,o),e=e.parentNode||e.ownerDocument||e.defaultView||e.parentWindow;while(e&&!r.isPropagationStopped());return a},a.clean=function(e){var t,n,r=a.unbind;if(!e||3===e.nodeType||8===e.nodeType)return a;if(e[c]&&r(e),e.getElementsByTagName||(e=e.document),e&&e.getElementsByTagName)for(r(e),n=e.getElementsByTagName("*"),t=n.length;t--;)e=n[t],e[c]&&r(e);return a},a.destroy=function(){s={}},a.cancel=function(e){return e&&(e.preventDefault(),e.stopImmediatePropagation()),!1}}var o="mce-data-",a=/^(?:mouse|contextmenu)|click/,s={keyLocation:1,layerX:1,layerY:1,returnValue:1};return i.Event=new i,i.Event.bind(window,"ready",function(){}),i}),r(c,[],function(){function e(e){return mt.test(e+"")}function n(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>_.cacheLength&&delete e[t.shift()],e[n]=r,r}}function r(e){return e[I]=!0,e}function i(e){var t=B.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t=null}}function o(e,t,n,r){var i,o,a,s,l,c,f,p,h,m;if((t?t.ownerDocument||t:F)!==B&&A(t),t=t||B,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(L&&!r){if(i=gt.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&O(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return Z.apply(n,t.getElementsByTagName(e)),n;if((a=i[3])&&z.getElementsByClassName&&t.getElementsByClassName)return Z.apply(n,t.getElementsByClassName(a)),n}if(z.qsa&&!M.test(e)){if(f=!0,p=I,h=t,m=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){for(c=u(e),(f=t.getAttribute("id"))?p=f.replace(bt,"\\$&"):t.setAttribute("id",p),p="[id='"+p+"'] ",l=c.length;l--;)c[l]=p+d(c[l]);h=ht.test(e)&&t.parentNode||t,m=c.join(",")}if(m)try{return Z.apply(n,h.querySelectorAll(m)),n}catch(g){}finally{f||t.removeAttribute("id")}}}return b(e.replace(lt,"$1"),t,n,r)}function a(e,t){var n=t&&e,r=n&&(~t.sourceIndex||Y)-(~e.sourceIndex||Y);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function l(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function c(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function u(e,t){var n,r,i,a,s,l,c,u=q[e+" "];if(u)return t?0:u.slice(0);for(s=e,l=[],c=_.preFilter;s;){(!n||(r=ct.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=ut.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(lt," ")}),s=s.slice(n.length));for(a in _.filter)!(r=pt[a].exec(s))||c[a]&&!(r=c[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?o.error(e):q(e,l).slice(0)}function d(e){for(var t=0,n=e.length,r="";n>t;t++)r+=e[t].value;return r}function f(e,t,n){var r=t.dir,i=n&&"parentNode"===r,o=V++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,l,c,u=W+" "+o;if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i)if(c=t[I]||(t[I]={}),(l=c[r])&&l[0]===u){if((s=l[1])===!0||s===w)return s===!0}else if(l=c[r]=[u],l[1]=e(t,n,a)||w,l[1]===!0)return!0}}function p(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function h(e,t,n,r,i){for(var o,a=[],s=0,l=e.length,c=null!=t;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),c&&t.push(s));return a}function m(e,t,n,i,o,a){return i&&!i[I]&&(i=m(i)),o&&!o[I]&&(o=m(o,a)),r(function(r,a,s,l){var c,u,d,f=[],p=[],m=a.length,g=r||y(t||"*",s.nodeType?[s]:s,[]),v=!e||!r&&t?g:h(g,f,e,s,l),b=n?o||(r?e:m||i)?[]:a:v;if(n&&n(v,b,s,l),i)for(c=h(b,p),i(c,[],s,l),u=c.length;u--;)(d=c[u])&&(b[p[u]]=!(v[p[u]]=d));if(r){if(o||e){if(o){for(c=[],u=b.length;u--;)(d=b[u])&&c.push(v[u]=d);o(null,b=[],c,l)}for(u=b.length;u--;)(d=b[u])&&(c=o?tt.call(r,d):f[u])>-1&&(r[c]=!(a[c]=d))}}else b=h(b===a?b.splice(m,b.length):b),o?o(null,a,b,l):Z.apply(a,b)})}function g(e){for(var t,n,r,i=e.length,o=_.relative[e[0].type],a=o||_.relative[" "],s=o?1:0,l=f(function(e){return e===t},a,!0),c=f(function(e){return tt.call(t,e)>-1},a,!0),u=[function(e,n,r){return!o&&(r||n!==k)||((t=n).nodeType?l(e,n,r):c(e,n,r))}];i>s;s++)if(n=_.relative[e[s].type])u=[f(p(u),n)];else{if(n=_.filter[e[s].type].apply(null,e[s].matches),n[I]){for(r=++s;i>r&&!_.relative[e[r].type];r++);return m(s>1&&p(u),s>1&&d(e.slice(0,s-1)).replace(lt,"$1"),n,r>s&&g(e.slice(s,r)),i>r&&g(e=e.slice(r)),i>r&&d(e))}u.push(n)}return p(u)}function v(e,t){var n=0,i=t.length>0,a=e.length>0,s=function(r,s,l,c,u){var d,f,p,m=[],g=0,v="0",y=r&&[],b=null!=u,C=k,x=r||a&&_.find.TAG("*",u&&s.parentNode||s),N=W+=null==C?1:Math.random()||.1;for(b&&(k=s!==B&&s,w=n);null!=(d=x[v]);v++){if(a&&d){for(f=0;p=e[f++];)if(p(d,s,l)){c.push(d);break}b&&(W=N,w=++n)}i&&((d=!p&&d)&&g--,r&&y.push(d))}if(g+=v,i&&v!==g){for(f=0;p=t[f++];)p(y,m,s,l);if(r){if(g>0)for(;v--;)y[v]||m[v]||(m[v]=J.call(c));m=h(m)}Z.apply(c,m),b&&!r&&m.length>0&&g+t.length>1&&o.uniqueSort(c)}return b&&(W=N,k=C),y};return i?r(s):s}function y(e,t,n){for(var r=0,i=t.length;i>r;r++)o(e,t[r],n);return n}function b(e,t,n,r){var i,o,a,s,l,c=u(e);if(!r&&1===c.length){if(o=c[0]=c[0].slice(0),o.length>2&&"ID"===(a=o[0]).type&&9===t.nodeType&&L&&_.relative[o[1].type]){if(t=(_.find.ID(a.matches[0].replace(xt,wt),t)||[])[0],!t)return n;e=e.slice(o.shift().value.length)}for(i=pt.needsContext.test(e)?0:o.length;i--&&(a=o[i],!_.relative[s=a.type]);)if((l=_.find[s])&&(r=l(a.matches[0].replace(xt,wt),ht.test(o[0].type)&&t.parentNode||t))){if(o.splice(i,1),e=r.length&&d(o),!e)return Z.apply(n,r),n;break}}return S(e,c)(r,t,!L,n,ht.test(e)),n}function C(){}var x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I="sizzle"+-new Date,F=window.document,z={},W=0,V=0,U=n(),q=n(),$=n(),j=!1,K=function(){return 0},G=typeof t,Y=1<<31,X=[],J=X.pop,Q=X.push,Z=X.push,et=X.slice,tt=X.indexOf||function(e){for(var t=0,n=this.length;n>t;t++)if(this[t]===e)return t;return-1},nt="[\\x20\\t\\r\\n\\f]",rt="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",it=rt.replace("w","w#"),ot="([*^$|!~]?=)",at="\\["+nt+"*("+rt+")"+nt+"*(?:"+ot+nt+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+it+")|)|)"+nt+"*\\]",st=":("+rt+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+at.replace(3,8)+")*)|.*)\\)|)",lt=new RegExp("^"+nt+"+|((?:^|[^\\\\])(?:\\\\.)*)"+nt+"+$","g"),ct=new RegExp("^"+nt+"*,"+nt+"*"),ut=new RegExp("^"+nt+"*([\\x20\\t\\r\\n\\f>+~])"+nt+"*"),dt=new RegExp(st),ft=new RegExp("^"+it+"$"),pt={ID:new RegExp("^#("+rt+")"),CLASS:new RegExp("^\\.("+rt+")"),NAME:new RegExp("^\\[name=['\"]?("+rt+")['\"]?\\]"),TAG:new RegExp("^("+rt.replace("w","w*")+")"),ATTR:new RegExp("^"+at),PSEUDO:new RegExp("^"+st),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+nt+"*(even|odd|(([+-]|)(\\d*)n|)"+nt+"*(?:([+-]|)"+nt+"*(\\d+)|))"+nt+"*\\)|)","i"),needsContext:new RegExp("^"+nt+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+nt+"*((?:-\\d)?\\d*)"+nt+"*\\)|)(?=[^-]|$)","i")},ht=/[\x20\t\r\n\f]*[+~]/,mt=/^[^{]+\{\s*\[native code/,gt=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,vt=/^(?:input|select|textarea|button)$/i,yt=/^h\d$/i,bt=/'|\\/g,Ct=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,xt=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,wt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320)};try{Z.apply(X=et.call(F.childNodes),F.childNodes),X[F.childNodes.length].nodeType}catch(_t){Z={apply:X.length?function(e,t){Q.apply(e,et.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}E=o.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},A=o.setDocument=function(n){var r=n?n.ownerDocument||n:F;return r!==B&&9===r.nodeType&&r.documentElement?(B=r,D=r.documentElement,L=!E(r),z.getElementsByTagName=i(function(e){return e.appendChild(r.createComment("")),!e.getElementsByTagName("*").length}),z.attributes=i(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),z.getElementsByClassName=i(function(e){return e.innerHTML="",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),z.getByName=i(function(e){e.id=I+0,e.appendChild(B.createElement("a")).setAttribute("name",I),e.appendChild(B.createElement("i")).setAttribute("name",I),D.appendChild(e);var t=r.getElementsByName&&r.getElementsByName(I).length===2+r.getElementsByName(I+0).length;return D.removeChild(e),t}),z.sortDetached=i(function(e){return e.compareDocumentPosition&&1&e.compareDocumentPosition(B.createElement("div"))}),_.attrHandle=i(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==G&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},z.getByName?(_.find.ID=function(e,t){if(typeof t.getElementById!==G&&L){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},_.filter.ID=function(e){var t=e.replace(xt,wt);return function(e){return e.getAttribute("id")===t}}):(_.find.ID=function(e,n){if(typeof n.getElementById!==G&&L){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==G&&r.getAttributeNode("id").value===e?[r]:t:[]}},_.filter.ID=function(e){var t=e.replace(xt,wt);return function(e){var n=typeof e.getAttributeNode!==G&&e.getAttributeNode("id");return n&&n.value===t}}),_.find.TAG=z.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==G?t.getElementsByTagName(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},_.find.NAME=z.getByName&&function(e,t){return typeof t.getElementsByName!==G?t.getElementsByName(name):void 0},_.find.CLASS=z.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==G&&L?t.getElementsByClassName(e):void 0},H=[],M=[":focus"],(z.qsa=e(r.querySelectorAll))&&(i(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||M.push("\\["+nt+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||M.push(":checked")}),i(function(e){e.innerHTML="",e.querySelectorAll("[i^='']").length&&M.push("[*^$]="+nt+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||M.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),M.push(",.*:")})),(z.matchesSelector=e(P=D.matchesSelector||D.mozMatchesSelector||D.webkitMatchesSelector||D.oMatchesSelector||D.msMatchesSelector))&&i(function(e){z.disconnectedMatch=P.call(e,"div"),P.call(e,"[s!='']:x"),H.push("!=",st)}),M=new RegExp(M.join("|")),H=H.length&&new RegExp(H.join("|")),O=e(D.contains)||D.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},K=D.compareDocumentPosition?function(e,t){if(e===t)return j=!0,0;var n=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return n?1&n||T&&t.compareDocumentPosition(e)===n?e===r||O(F,e)?-1:t===r||O(F,t)?1:R?tt.call(R,e)-tt.call(R,t):0:4&n?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var n,i=0,o=e.parentNode,s=t.parentNode,l=[e],c=[t];if(e===t)return j=!0,0;if(!o||!s)return e===r?-1:t===r?1:o?-1:s?1:0;if(o===s)return a(e,t);for(n=e;n=n.parentNode;)l.unshift(n);for(n=t;n=n.parentNode;)c.unshift(n);for(;l[i]===c[i];)i++;return i?a(l[i],c[i]):l[i]===F?-1:c[i]===F?1:0},B):B},o.matches=function(e,t){return o(e,null,null,t)},o.matchesSelector=function(e,t){if((e.ownerDocument||e)!==B&&A(e),t=t.replace(Ct,"='$1']"),z.matchesSelector&&L&&(!H||!H.test(t))&&!M.test(t))try{var n=P.call(e,t);if(n||z.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return o(t,B,null,[e]).length>0},o.contains=function(e,t){return(e.ownerDocument||e)!==B&&A(e),O(e,t)},o.attr=function(e,t){var n;return(e.ownerDocument||e)!==B&&A(e),L&&(t=t.toLowerCase()),(n=_.attrHandle[t])?n(e):!L||z.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},o.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},o.uniqueSort=function(e){var t,n=[],r=0,i=0;if(j=!z.detectDuplicates,T=!z.sortDetached,R=!z.sortStable&&e.slice(0),e.sort(K),j){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return e},N=o.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=N(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=N(t);return n},_=o.selectors={cacheLength:50,createPseudo:r,match:pt,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(xt,wt),e[3]=(e[4]||e[5]||"").replace(xt,wt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||o.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&o.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return pt.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&dt.test(n)&&(t=u(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(xt,wt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=U[e+" "];return t||(t=new RegExp("(^|"+nt+")"+e+"("+nt+"|$)"))&&U(e,function(e){return t.test(e.className||typeof e.getAttribute!==G&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=o.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var c,u,d,f,p,h,m=o!==a?"nextSibling":"previousSibling",g=t.parentNode,v=s&&t.nodeName.toLowerCase(),y=!l&&!s;if(g){if(o){for(;m;){for(d=t;d=d[m];)if(s?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;h=m="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?g.firstChild:g.lastChild],a&&y){for(u=g[I]||(g[I]={}),c=u[e]||[],p=c[0]===W&&c[1],f=c[0]===W&&c[2],d=p&&g.childNodes[p];d=++p&&d&&d[m]||(f=p=0)||h.pop();)if(1===d.nodeType&&++f&&d===t){u[e]=[W,p,f];break}}else if(y&&(c=(t[I]||(t[I]={}))[e])&&c[0]===W)f=c[1];else for(;(d=++p&&d&&d[m]||(f=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==v:1!==d.nodeType)||!++f||(y&&((d[I]||(d[I]={}))[e]=[W,f]),d!==t)););return f-=i,f===r||f%r===0&&f/r>=0}}},PSEUDO:function(e,t){var n,i=_.pseudos[e]||_.setFilters[e.toLowerCase()]||o.error("unsupported pseudo: "+e);return i[I]?i(t):i.length>1?(n=[e,e,"",t],_.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,n){for(var r,o=i(e,t),a=o.length;a--;)r=tt.call(e,o[a]),e[r]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:r(function(e){var t=[],n=[],i=S(e.replace(lt,"$1"));return i[I]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),!n.pop()}}),has:r(function(e){return function(t){return o(e,t).length>0}}),contains:r(function(e){return function(t){return(t.textContent||t.innerText||N(t)).indexOf(e)>-1}}),lang:r(function(e){return ft.test(e||"")||o.error("unsupported lang: "+e),e=e.replace(xt,wt).toLowerCase(),function(t){var n;do if(n=L?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(e){var t=window.location&&window.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===D},focus:function(e){return e===B.activeElement&&(!B.hasFocus||B.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!_.pseudos.empty(e)},header:function(e){return yt.test(e.nodeName)},input:function(e){return vt.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:c(function(){return[0]}),last:c(function(e,t){return[t-1]}),eq:c(function(e,t,n){return[0>n?n+t:n]}),even:c(function(e,t){for(var n=0;t>n;n+=2)e.push(n);return e}),odd:c(function(e,t){for(var n=1;t>n;n+=2)e.push(n);return e}),lt:c(function(e,t,n){for(var r=0>n?n+t:n;--r>=0;)e.push(r);return e}),gt:c(function(e,t,n){for(var r=0>n?n+t:n;++rn;n++)t[n]=e[n];return t}function f(e,t){var n;if(t.indexOf)return t.indexOf(e);for(n=t.length;n--;)if(t[n]===e)return n;return-1}function p(e){return null===e||e===t?"":(""+e).replace(N,"")}function h(e,t){var n,r,i,o,a;if(e)if(n=e.length,n===o){for(r in e)if(e.hasOwnProperty(r)&&(a=e[r],t.call(a,a,r)===!1))break}else for(i=0;n>i&&(a=e[i],t.call(a,a,r)!==!1);i++);return e}function m(e,n,r){for(var i=[],o=e[n];o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!c(o).is(r));)1===o.nodeType&&i.push(o),o=o[n];return i}function g(e,t,n,r){for(var i=[];e;e=e[n])r&&e.nodeType!==r||e===t||i.push(e);return i}var v=document,y=Array.prototype.push,b=Array.prototype.slice,C=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,x=e.Event,w=l("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom"),_=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)},N=/^\s*|\s*$/g;return c.fn=c.prototype={constructor:c,selector:"",length:0,init:function(e,t){var n=this,r,a;if(!e)return n;if(e.nodeType)return n.context=n[0]=e,n.length=1,n;if(i(e)){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:C.exec(e),!r)return c(t||document).find(e);if(r[1])for(a=o(e).firstChild;a;)this.add(a),a=a.nextSibling;else{if(a=v.getElementById(r[2]),a.id!==r[2])return n.find(e);n.length=1,n[0]=a}}else this.add(e);return n},toArray:function(){return d(this)},add:function(e){var t=this;return _(e)?y.apply(t,e):e instanceof c?t.add(e.toArray()):y.call(t,e),t},attr:function(e,n){var i=this;if("object"==typeof e)h(e,function(e,t){i.attr(t,e)});else{if(!r(n))return i[0]&&1===i[0].nodeType?i[0].getAttribute(e):t;this.each(function(){1===this.nodeType&&this.setAttribute(e,n)})}return i},css:function(e,n){var i=this;if("object"==typeof e)h(e,function(e,t){i.css(t,e)});else{if(e=e.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),!r(n))return i[0]?i[0].style[e]:t;"number"!=typeof n||w[e]||(n+="px"),i.each(function(){var t=this.style;"opacity"===e&&this.runtimeStyle&&"undefined"==typeof this.runtimeStyle.opacity&&(t.filter=""===n?"":"alpha(opacity="+100*n+")");try{t[e]=n}catch(r){}})}return i},remove:function(){for(var e=this,t,n=this.length;n--;)t=e[n],x.clean(t),t.parentNode&&t.parentNode.removeChild(t);return this},empty:function(){for(var e=this,t,n=this.length;n--;)for(t=e[n];t.firstChild;)t.removeChild(t.firstChild);return this},html:function(e){var t=this,n;if(r(e)){for(n=t.length;n--;)t[n].innerHTML=e;return t}return t[0]?t[0].innerHTML:""},text:function(e){var t=this,n;if(r(e)){for(n=t.length;n--;)t[n].innerText=t[0].textContent=e;return t}return t[0]?t[0].innerText||t[0].textContent:""},append:function(){return a(this,arguments,function(e){1===this.nodeType&&this.appendChild(e)})},prepend:function(){return a(this,arguments,function(e){1===this.nodeType&&this.insertBefore(e,this.firstChild)})},before:function(){var e=this;return e[0]&&e[0].parentNode?a(e,arguments,function(e){this.parentNode.insertBefore(e,this.nextSibling)}):e},after:function(){var e=this;return e[0]&&e[0].parentNode?a(e,arguments,function(e){this.parentNode.insertBefore(e,this)}):e},appendTo:function(e){return c(e).append(this),this},addClass:function(e){return this.toggleClass(e,!0)},removeClass:function(e){return this.toggleClass(e,!1)},toggleClass:function(e,t){var n=this;return-1!==e.indexOf(" ")?h(e.split(" "),function(){n.toggleClass(this,t)}):n.each(function(n){var r;s(n,e)!==t&&(r=n.className,t?n.className+=r?" "+e:e:n.className=p((" "+r+" ").replace(" "+e+" "," ")))}),n},hasClass:function(e){return s(this[0],e)},each:function(e){return h(this,e)},on:function(e,t){return this.each(function(){x.bind(this,e,t)})},off:function(e,t){return this.each(function(){x.unbind(this,e,t)})},show:function(){return this.css("display","")},hide:function(){return this.css("display","none")},slice:function(){return new c(b.apply(this,arguments))},eq:function(e){return-1===e?this.slice(e):this.slice(e,+e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},replaceWith:function(e){var t=this;return t[0]&&t[0].parentNode.replaceChild(c(e)[0],t[0]),t},wrap:function(e){return e=c(e)[0],this.each(function(){var t=this,n=e.cloneNode(!1);t.parentNode.insertBefore(n,t),n.appendChild(t)})},unwrap:function(){return this.each(function(){for(var e=this,t=e.firstChild,n;t;)n=t,t=t.nextSibling,e.parentNode.insertBefore(n,e)})},clone:function(){var e=[];return this.each(function(){e.push(this.cloneNode(!0))}),c(e)},find:function(e){var t,n,r=[];for(t=0,n=this.length;n>t;t++)c.find(e,this[t],r);return c(r)},push:y,sort:[].sort,splice:[].splice},u(c,{extend:u,toArray:d,inArray:f,isArray:_,each:h,trim:p,makeMap:l,find:n,expr:n.selectors,unique:n.uniqueSort,text:n.getText,isXMLDoc:n.isXML,contains:n.contains,filter:function(e,t,n){return n&&(e=":not("+e+")"),t=1===t.length?c.find.matchesSelector(t[0],e)?[t[0]]:[]:c.find.matches(e,t)}}),h({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return m(e,"parentNode")},parentsUntil:function(e,t){return m(e,"parentNode",t)},next:function(e){return g(e,"nextSibling",1)},prev:function(e){return g(e,"previousSibling",1)},nextNodes:function(e){return g(e,"nextSibling")},prevNodes:function(e){return g(e,"previousSibling")},children:function(e){return g(e.firstChild,"nextSibling",1)},contents:function(e){return d(("iframe"===e.nodeName?e.contentDocument||e.contentWindow.document:e).childNodes)}},function(e,t){c.fn[e]=function(n){var r=this,i;if(r.length>1)throw new Error("DomQuery only supports traverse functions on a single node.");return r[0]&&(i=t(r[0],n)),i=c(i),n&&"parentsUntil"!==e?i.filter(n):i}}),c.fn.filter=function(e){return c.filter(e)},c.fn.is=function(e){return!!e&&this.filter(e).length>0},c.fn.init.prototype=c.fn,c}),r(d,[],function(){return function(e,t){function n(e,t,n,r){function i(e){return e=parseInt(e,10).toString(16),e.length>1?e:"0"+e +}return"#"+i(t)+i(n)+i(r)}var r=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,i=/(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,o=/\s*([^:]+):\s*([^;]+);?/g,a=/\s+$/,s,l,c={},u,d="\ufeff";for(e=e||{},u=("\\\" \\' \\; \\: ; : "+d).split(" "),l=0;l-1&&n||(m[e+t]=-1==l?s[0]:s.join(" "),delete m[e+"-top"+t],delete m[e+"-right"+t],delete m[e+"-bottom"+t],delete m[e+"-left"+t])}}function u(e){var t=m[e],n;if(t){for(t=t.split(" "),n=t.length;n--;)if(t[n]!==t[0])return!1;return m[e]=t[0],!0}}function d(e,t,n,r){u(t)&&u(n)&&u(r)&&(m[e]=m[t]+" "+m[n]+" "+m[r],delete m[t],delete m[n],delete m[r])}function f(e){return b=!0,c[e]}function p(e,t){return b&&(e=e.replace(/\uFEFF[0-9]/g,function(e){return c[e]})),t||(e=e.replace(/\\([\'\";:])/g,"$1")),e}function h(t,n,r,i,o,a){if(o=o||a)return o=p(o),"'"+o.replace(/\'/g,"\\'")+"'";if(n=p(n||r||i),!e.allow_script_urls){var s=n.replace(/[\s\r\n]+/,"");if(/(java|vb)script:/i.test(s))return"";if(!e.allow_svg_data_urls&&/^data:image\/svg/i.test(s))return""}return C&&(n=C.call(x,n,"style")),"url('"+n.replace(/\'/g,"\\'")+"')"}var m={},g,v,y,b,C=e.url_converter,x=e.url_converter_scope||this;if(t){for(t=t.replace(/[\u0000-\u001F]/g,""),t=t.replace(/\\[\"\';:\uFEFF]/g,f).replace(/\"[^\"]+\"|\'[^\']+\'/g,function(e){return e.replace(/[;:]/g,f)});g=o.exec(t);){if(v=g[1].replace(a,"").toLowerCase(),y=g[2].replace(a,""),y=y.replace(/\\[0-9a-f]+/g,function(e){return String.fromCharCode(parseInt(e.substr(1),16))}),v&&y.length>0){if(!e.allow_script_urls&&("behavior"==v||/expression\s*\(|\/\*|\*\//.test(y)))continue;"font-weight"===v&&"700"===y?y="bold":("color"===v||"background-color"===v)&&(y=y.toLowerCase()),y=y.replace(r,n),y=y.replace(i,h),m[v]=b?p(y,!0):y}o.lastIndex=g.index+g[0].length}s("border","",!0),s("border","-width"),s("border","-color"),s("border","-style"),s("padding",""),s("margin",""),d("border","border-width","border-style","border-color"),"medium none"===m.border&&delete m.border,"none"===m["border-image"]&&delete m["border-image"]}return m},serialize:function(e,n){function r(n){var r,o,a,l;if(r=t.styles[n])for(o=0,a=r.length;a>o;o++)n=r[o],l=e[n],l!==s&&l.length>0&&(i+=(i.length>0?" ":"")+n+": "+l+";")}var i="",o,a;if(n&&t&&t.styles)r("*"),r(n);else for(o in e)a=e[o],a!==s&&a.length>0&&(i+=(i.length>0?" ":"")+o+": "+a+";");return i}}}}),r(f,[],function(){return function(e,t){function n(e,n,r,i){var o,a;if(e){if(!i&&e[n])return e[n];if(e!=t){if(o=e[r])return o;for(a=e.parentNode;a&&a!=t;a=a.parentNode)if(o=a[r])return o}}}var r=e;this.current=function(){return r},this.next=function(e){return r=n(r,"firstChild","nextSibling",e)},this.prev=function(e){return r=n(r,"lastChild","previousSibling",e)}}}),r(p,[],function(){function e(e){return null===e||e===t?"":(""+e).replace(m,"")}function n(e,n){return n?"array"==n&&g(e)?!0:typeof e==n:e!==t}function r(e){var t=[],n,r;for(n=0,r=e.length;r>n;n++)t[n]=e[n];return t}function i(e,t,n){var r;for(e=e||[],t=t||",","string"==typeof e&&(e=e.split(t)),n=n||{},r=e.length;r--;)n[e[r]]={};return n}function o(e,n,r){var i,o;if(!e)return 0;if(r=r||e,e.length!==t){for(i=0,o=e.length;o>i;i++)if(n.call(r,e[i],i,e)===!1)return 0}else for(i in e)if(e.hasOwnProperty(i)&&n.call(r,e[i],i,e)===!1)return 0;return 1}function a(e,t){var n=[];return o(e,function(e){n.push(t(e))}),n}function s(e,t){var n=[];return o(e,function(e){(!t||t(e))&&n.push(e)}),n}function l(e,t,n){var r=this,i,o,a,s,l,c=0;if(e=/^((static) )?([\w.]+)(:([\w.]+))?/.exec(e),a=e[3].match(/(^|\.)(\w+)$/i)[2],o=r.createNS(e[3].replace(/\.\w+$/,""),n),!o[a]){if("static"==e[2])return o[a]=t,void(this.onCreate&&this.onCreate(e[2],e[3],o[a]));t[a]||(t[a]=function(){},c=1),o[a]=t[a],r.extend(o[a].prototype,t),e[5]&&(i=r.resolve(e[5]).prototype,s=e[5].match(/\.(\w+)$/i)[1],l=o[a],o[a]=c?function(){return i[s].apply(this,arguments)}:function(){return this.parent=i[s],l.apply(this,arguments)},o[a].prototype[a]=o[a],r.each(i,function(e,t){o[a].prototype[t]=i[t]}),r.each(t,function(e,t){i[t]?o[a].prototype[t]=function(){return this.parent=i[t],e.apply(this,arguments)}:t!=a&&(o[a].prototype[t]=e)})),r.each(t["static"],function(e,t){o[a][t]=e})}}function c(e,t){var n,r;if(e)for(n=0,r=e.length;r>n;n++)if(e[n]===t)return n;return-1}function u(e,n){var r,i,o,a=arguments,s;for(r=1,i=a.length;i>r;r++){n=a[r];for(o in n)n.hasOwnProperty(o)&&(s=n[o],s!==t&&(e[o]=s))}return e}function d(e,t,n,r){r=r||this,e&&(n&&(e=e[n]),o(e,function(e,i){return t.call(r,e,i,n)===!1?!1:void d(e,t,n,r)}))}function f(e,t){var n,r;for(t=t||window,e=e.split("."),n=0;nn&&(t=t[e[n]],t);n++);return t}function h(t,r){return!t||n(t,"array")?t:a(t.split(r||","),e)}var m=/^\s*|\s*$/g,g=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)};return{trim:e,isArray:g,is:n,toArray:r,makeMap:i,each:o,map:a,grep:s,inArray:c,extend:u,create:l,walk:d,createNS:f,resolve:p,explode:h}}),r(h,[p],function(e){function t(n){function r(){return H.createDocumentFragment()}function i(e,t){_(F,e,t)}function o(e,t){_(z,e,t)}function a(e){i(e.parentNode,j(e))}function s(e){i(e.parentNode,j(e)+1)}function l(e){o(e.parentNode,j(e))}function c(e){o(e.parentNode,j(e)+1)}function u(e){e?(M[U]=M[V],M[q]=M[W]):(M[V]=M[U],M[W]=M[q]),M.collapsed=F}function d(e){a(e),c(e)}function f(e){i(e,0),o(e,1===e.nodeType?e.childNodes.length:e.nodeValue.length)}function p(e,t){var n=M[V],r=M[W],i=M[U],o=M[q],a=t.startContainer,s=t.startOffset,l=t.endContainer,c=t.endOffset;return 0===e?w(n,r,a,s):1===e?w(i,o,a,s):2===e?w(i,o,l,c):3===e?w(n,r,l,c):void 0}function h(){N(I)}function m(){return N(P)}function g(){return N(O)}function v(e){var t=this[V],r=this[W],i,o;3!==t.nodeType&&4!==t.nodeType||!t.nodeValue?(t.childNodes.length>0&&(o=t.childNodes[r]),o?t.insertBefore(e,o):3==t.nodeType?n.insertAfter(e,t):t.appendChild(e)):r?r>=t.nodeValue.length?n.insertAfter(e,t):(i=t.splitText(r),t.parentNode.insertBefore(e,i)):t.parentNode.insertBefore(e,t)}function y(e){var t=M.extractContents();M.insertNode(e),e.appendChild(t),M.selectNode(e)}function b(){return $(new t(n),{startContainer:M[V],startOffset:M[W],endContainer:M[U],endOffset:M[q],collapsed:M.collapsed,commonAncestorContainer:M.commonAncestorContainer})}function C(e,t){var n;if(3==e.nodeType)return e;if(0>t)return e;for(n=e.firstChild;n&&t>0;)--t,n=n.nextSibling;return n?n:e}function x(){return M[V]==M[U]&&M[W]==M[q]}function w(e,t,r,i){var o,a,s,l,c,u;if(e==r)return t==i?0:i>t?-1:1;for(o=r;o&&o.parentNode!=e;)o=o.parentNode;if(o){for(a=0,s=e.firstChild;s!=o&&t>a;)a++,s=s.nextSibling;return a>=t?-1:1}for(o=e;o&&o.parentNode!=r;)o=o.parentNode;if(o){for(a=0,s=r.firstChild;s!=o&&i>a;)a++,s=s.nextSibling;return i>a?-1:1}for(l=n.findCommonAncestor(e,r),c=e;c&&c.parentNode!=l;)c=c.parentNode;for(c||(c=l),u=r;u&&u.parentNode!=l;)u=u.parentNode;if(u||(u=l),c==u)return 0;for(s=l.firstChild;s;){if(s==c)return-1;if(s==u)return 1;s=s.nextSibling}}function _(e,t,r){var i,o;for(e?(M[V]=t,M[W]=r):(M[U]=t,M[q]=r),i=M[U];i.parentNode;)i=i.parentNode;for(o=M[V];o.parentNode;)o=o.parentNode;o==i?w(M[V],M[W],M[U],M[q])>0&&M.collapse(e):M.collapse(e),M.collapsed=x(),M.commonAncestorContainer=n.findCommonAncestor(M[V],M[U])}function N(e){var t,n=0,r=0,i,o,a,s,l,c;if(M[V]==M[U])return E(e);for(t=M[U],i=t.parentNode;i;t=i,i=i.parentNode){if(i==M[V])return S(t,e);++n}for(t=M[V],i=t.parentNode;i;t=i,i=i.parentNode){if(i==M[U])return k(t,e);++r}for(o=r-n,a=M[V];o>0;)a=a.parentNode,o--;for(s=M[U];0>o;)s=s.parentNode,o++;for(l=a.parentNode,c=s.parentNode;l!=c;l=l.parentNode,c=c.parentNode)a=l,s=c;return T(a,s,e)}function E(e){var t,n,i,o,a,s,l,c,u;if(e!=I&&(t=r()),M[W]==M[q])return t;if(3==M[V].nodeType){if(n=M[V].nodeValue,i=n.substring(M[W],M[q]),e!=O&&(o=M[V],c=M[W],u=M[q]-M[W],0===c&&u>=o.nodeValue.length-1?o.parentNode.removeChild(o):o.deleteData(c,u),M.collapse(F)),e==I)return;return i.length>0&&t.appendChild(H.createTextNode(i)),t}for(o=C(M[V],M[W]),a=M[q]-M[W];o&&a>0;)s=o.nextSibling,l=D(o,e),t&&t.appendChild(l),--a,o=s;return e!=O&&M.collapse(F),t}function S(e,t){var n,i,o,a,s,l;if(t!=I&&(n=r()),i=R(e,t),n&&n.appendChild(i),o=j(e),a=o-M[W],0>=a)return t!=O&&(M.setEndBefore(e),M.collapse(z)),n;for(i=e.previousSibling;a>0;)s=i.previousSibling,l=D(i,t),n&&n.insertBefore(l,n.firstChild),--a,i=s;return t!=O&&(M.setEndBefore(e),M.collapse(z)),n}function k(e,t){var n,i,o,a,s,l;for(t!=I&&(n=r()),o=A(e,t),n&&n.appendChild(o),i=j(e),++i,a=M[q]-i,o=e.nextSibling;o&&a>0;)s=o.nextSibling,l=D(o,t),n&&n.appendChild(l),--a,o=s;return t!=O&&(M.setStartAfter(e),M.collapse(F)),n}function T(e,t,n){var i,o,a,s,l,c,u;for(n!=I&&(o=r()),i=A(e,n),o&&o.appendChild(i),a=j(e),s=j(t),++a,l=s-a,c=e.nextSibling;l>0;)u=c.nextSibling,i=D(c,n),o&&o.appendChild(i),c=u,--l;return i=R(t,n),o&&o.appendChild(i),n!=O&&(M.setStartAfter(e),M.collapse(F)),o}function R(e,t){var n=C(M[U],M[q]-1),r,i,o,a,s,l=n!=M[U];if(n==e)return B(n,l,z,t);for(r=n.parentNode,i=B(r,z,z,t);r;){for(;n;)o=n.previousSibling,a=B(n,l,z,t),t!=I&&i.insertBefore(a,i.firstChild),l=F,n=o;if(r==e)return i;n=r.previousSibling,r=r.parentNode,s=B(r,z,z,t),t!=I&&s.appendChild(i),i=s}}function A(e,t){var n=C(M[V],M[W]),r=n!=M[V],i,o,a,s,l;if(n==e)return B(n,r,F,t);for(i=n.parentNode,o=B(i,z,F,t);i;){for(;n;)a=n.nextSibling,s=B(n,r,F,t),t!=I&&o.appendChild(s),r=F,n=a;if(i==e)return o;n=i.nextSibling,i=i.parentNode,l=B(i,z,F,t),t!=I&&l.appendChild(o),o=l}}function B(e,t,r,i){var o,a,s,l,c;if(t)return D(e,i);if(3==e.nodeType){if(o=e.nodeValue,r?(l=M[W],a=o.substring(l),s=o.substring(0,l)):(l=M[q],a=o.substring(0,l),s=o.substring(l)),i!=O&&(e.nodeValue=s),i==I)return;return c=n.clone(e,z),c.nodeValue=a,c}if(i!=I)return n.clone(e,z)}function D(e,t){return t!=I?t==O?n.clone(e,F):e:void e.parentNode.removeChild(e)}function L(){return n.create("body",null,g()).outerText}var M=this,H=n.doc,P=0,O=1,I=2,F=!0,z=!1,W="startOffset",V="startContainer",U="endContainer",q="endOffset",$=e.extend,j=n.nodeIndex;return $(M,{startContainer:H,startOffset:0,endContainer:H,endOffset:0,collapsed:F,commonAncestorContainer:H,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:i,setEnd:o,setStartBefore:a,setStartAfter:s,setEndBefore:l,setEndAfter:c,collapse:u,selectNode:d,selectNodeContents:f,compareBoundaryPoints:p,deleteContents:h,extractContents:m,cloneContents:g,insertNode:v,surroundContents:y,cloneRange:b,toStringIE:L}),M}return t.prototype.toString=function(){return this.toStringIE()},t}),r(m,[p],function(e){function t(e){var t;return t=document.createElement("div"),t.innerHTML=e,t.textContent||t.innerText||e}function n(e,t){var n,r,i,a={};if(e){for(e=e.split(","),t=t||10,n=0;n\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,l=/[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,c=/[<>&\"\']/g,u=/&(#x|#)?([\w]+);/g,d={128:"\u20ac",130:"\u201a",131:"\u0192",132:"\u201e",133:"\u2026",134:"\u2020",135:"\u2021",136:"\u02c6",137:"\u2030",138:"\u0160",139:"\u2039",140:"\u0152",142:"\u017d",145:"\u2018",146:"\u2019",147:"\u201c",148:"\u201d",149:"\u2022",150:"\u2013",151:"\u2014",152:"\u02dc",153:"\u2122",154:"\u0161",155:"\u203a",156:"\u0153",158:"\u017e",159:"\u0178"};o={'"':""","'":"'","<":"<",">":">","&":"&","`":"`"},a={"<":"<",">":">","&":"&",""":'"',"'":"'"},i=n("50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro",32);var f={encodeRaw:function(e,t){return e.replace(t?s:l,function(e){return o[e]||e})},encodeAllRaw:function(e){return(""+e).replace(c,function(e){return o[e]||e})},encodeNumeric:function(e,t){return e.replace(t?s:l,function(e){return e.length>1?"&#"+(1024*(e.charCodeAt(0)-55296)+(e.charCodeAt(1)-56320)+65536)+";":o[e]||"&#"+e.charCodeAt(0)+";"})},encodeNamed:function(e,t,n){return n=n||i,e.replace(t?s:l,function(e){return o[e]||n[e]||e})},getEncodeFunc:function(e,t){function a(e,n){return e.replace(n?s:l,function(e){return o[e]||t[e]||"&#"+e.charCodeAt(0)+";"||e})}function c(e,n){return f.encodeNamed(e,n,t)}return t=n(t)||i,e=r(e.replace(/\+/g,",")),e.named&&e.numeric?a:e.named?t?c:f.encodeNamed:e.numeric?f.encodeNumeric:f.encodeRaw},decode:function(e){return e.replace(u,function(e,n,r){return n?(r=parseInt(r,2===n.length?16:10),r>65535?(r-=65536,String.fromCharCode(55296+(r>>10),56320+(1023&r))):d[r]||String.fromCharCode(r)):a[e]||i[e]||t(e)})}};return f}),r(g,[],function(){var e=navigator,t=e.userAgent,n,r,i,o,a,s,l;n=window.opera&&window.opera.buildNumber,r=/WebKit/.test(t),i=!r&&!n&&/MSIE/gi.test(t)&&/Explorer/gi.test(e.appName),i=i&&/MSIE (\w+)\./.exec(t)[1],o=-1==t.indexOf("Trident/")||-1==t.indexOf("rv:")&&-1==e.appName.indexOf("Netscape")?!1:11,i=i||o,a=!r&&!o&&/Gecko/.test(t),s=-1!=t.indexOf("Mac"),l=/(iPad|iPhone)/.test(t);var c=!l||t.match(/AppleWebKit\/(\d*)/)[1]>=534;return{opera:n,webkit:r,ie:i,gecko:a,mac:s,iOS:l,contentEditable:c,transparentSrc:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",caretAfter:8!=i,range:window.getSelection&&"Range"in window,documentMode:i?document.documentMode||7:10}}),r(v,[],function(){return function(e,t){function n(t){e.getElementsByTagName("head")[0].appendChild(t)}function r(t,r,s){function l(){for(var e=v.passed,t=e.length;t--;)e[t]();v.status=2,v.passed=[],v.failed=[]}function c(){for(var e=v.failed,t=e.length;t--;)e[t]();v.status=3,v.passed=[],v.failed=[]}function u(){var e=navigator.userAgent.match(/WebKit\/(\d*)/);return!!(e&&e[1]<536)}function d(e,t){e()||((new Date).getTime()-g0)return m=e.createElement("style"),m.textContent='@import "'+t+'"',p(),void n(m);f()}n(h),h.href=t}}var i=0,o={},a;t=t||{},a=t.maxLoadTime||5e3,this.load=r}}),r(y,[c,d,l,f,h,m,g,p,v],function(e,n,r,i,o,a,s,l,c){function u(e,t){var i=this,o;i.doc=e,i.win=window,i.files={},i.counter=0,i.stdMode=!v||e.documentMode>=8,i.boxModel=!v||"CSS1Compat"==e.compatMode||i.stdMode,i.hasOuterHTML="outerHTML"in e.createElement("a"),i.styleSheetLoader=new c(e),this.boundEvents=[],i.settings=t=m({keep_values:!1,hex_colors:1},t),i.schema=t.schema,i.styles=new n({url_converter:t.url_converter,url_converter_scope:t.url_converter_scope},t.schema),i.fixDoc(e),i.events=t.ownEvents?new r(t.proxy):r.Event,o=t.schema?t.schema.getBlockElements():{},i.isBlock=function(e){if(!e)return!1;var t=e.nodeType;return t?!(1!==t||!o[e.nodeName]):!!o[e]}}var d=l.each,f=l.is,p=l.grep,h=l.trim,m=l.extend,g=s.webkit,v=s.ie,y=/^([a-z0-9],?)+$/i,b=/^[ \t\r\n]*$/,C=l.makeMap("fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom"," ");return u.prototype={root:null,props:{"for":"htmlFor","class":"className",className:"className",checked:"checked",disabled:"disabled",maxlength:"maxLength",readonly:"readOnly",selected:"selected",value:"value",id:"id",name:"name",type:"type"},fixDoc:function(e){var t=this.settings,n;if(v&&t.schema){"abbr article aside audio canvas details figcaption figure footer header hgroup mark menu meter nav output progress section summary time video".replace(/\w+/g,function(t){e.createElement(t)});for(n in t.schema.getCustomElements())e.createElement(n)}},clone:function(e,t){var n=this,r,i;return!v||1!==e.nodeType||t?e.cloneNode(t):(i=n.doc,t?r.firstChild:(r=i.createElement(e.nodeName),d(n.getAttribs(e),function(t){n.setAttrib(r,t.nodeName,n.getAttrib(e,t.nodeName))}),r))},getRoot:function(){var e=this;return e.get(e.settings.root_element)||e.doc.body},getViewPort:function(e){var t,n;return e=e?e:this.win,t=e.document,n=this.boxModel?t.documentElement:t.body,{x:e.pageXOffset||n.scrollLeft,y:e.pageYOffset||n.scrollTop,w:e.innerWidth||n.clientWidth,h:e.innerHeight||n.clientHeight}},getRect:function(e){var t=this,n,r;return e=t.get(e),n=t.getPos(e),r=t.getSize(e),{x:n.x,y:n.y,w:r.w,h:r.h}},getSize:function(e){var t=this,n,r;return e=t.get(e),n=t.getStyle(e,"width"),r=t.getStyle(e,"height"),-1===n.indexOf("px")&&(n=0),-1===r.indexOf("px")&&(r=0),{w:parseInt(n,10)||e.offsetWidth||e.clientWidth,h:parseInt(r,10)||e.offsetHeight||e.clientHeight}},getParent:function(e,t,n){return this.getParents(e,t,n,!1)},getParents:function(e,n,r,i){var o=this,a,s=[];for(e=o.get(e),i=i===t,r=r||("BODY"!=o.getRoot().nodeName?o.getRoot().parentNode:null),f(n,"string")&&(a=n,n="*"===n?function(e){return 1==e.nodeType}:function(e){return o.is(e,a)});e&&e!=r&&e.nodeType&&9!==e.nodeType;){if(!n||n(e)){if(!i)return e;s.push(e)}e=e.parentNode}return i?s:null},get:function(e){var t;return e&&this.doc&&"string"==typeof e&&(t=e,e=this.doc.getElementById(e),e&&e.id!==t)?this.doc.getElementsByName(t)[1]:e},getNext:function(e,t){return this._findSib(e,t,"nextSibling")},getPrev:function(e,t){return this._findSib(e,t,"previousSibling")},select:function(t,n){var r=this;return e(t,r.get(n)||r.get(r.settings.root_element)||r.doc,[])},is:function(n,r){var i;if(n.length===t){if("*"===r)return 1==n.nodeType;if(y.test(r)){for(r=r.toLowerCase().split(/,/),n=n.nodeName.toLowerCase(),i=r.length-1;i>=0;i--)if(r[i]==n)return!0;return!1}}if(n.nodeType&&1!=n.nodeType)return!1;var o=n.nodeType?[n]:n;return e(r,o[0].ownerDocument||o[0],null,o).length>0},add:function(e,t,n,r,i){var o=this;return this.run(e,function(e){var a;return a=f(t,"string")?o.doc.createElement(t):t,o.setAttribs(a,n),r&&(r.nodeType?a.appendChild(r):o.setHTML(a,r)),i?a:e.appendChild(a)})},create:function(e,t,n){return this.add(this.doc.createElement(e),e,t,n,1)},createHTML:function(e,t,n){var r="",i;r+="<"+e;for(i in t)t.hasOwnProperty(i)&&null!==t[i]&&(r+=" "+i+'="'+this.encode(t[i])+'"');return"undefined"!=typeof n?r+">"+n+"":r+" />"},createFragment:function(e){var t,n,r=this.doc,i;for(i=r.createElement("div"),t=r.createDocumentFragment(),e&&(i.innerHTML=e);n=i.firstChild;)t.appendChild(n);return t},remove:function(e,t){return this.run(e,function(e){var n,r=e.parentNode;if(!r)return null;if(t)for(;n=e.firstChild;)!v||3!==n.nodeType||n.nodeValue?r.insertBefore(n,e):e.removeChild(n);return r.removeChild(e)})},setStyle:function(e,t,n){return this.run(e,function(e){var r=this,i,o;if(t)if("string"==typeof t){i=e.style,t=t.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),"number"!=typeof n||C[t]||(n+="px"),"opacity"===t&&e.runtimeStyle&&"undefined"==typeof e.runtimeStyle.opacity&&(i.filter=""===n?"":"alpha(opacity="+100*n+")"),"float"==t&&(t="cssFloat"in e.style?"cssFloat":"styleFloat");try{i[t]=n}catch(a){}r.settings.update_styles&&e.removeAttribute("data-mce-style")}else for(o in t)r.setStyle(e,o,t[o])})},getStyle:function(e,n,r){if(e=this.get(e)){if(this.doc.defaultView&&r){n=n.replace(/[A-Z]/g,function(e){return"-"+e});try{return this.doc.defaultView.getComputedStyle(e,null).getPropertyValue(n)}catch(i){return null}}return n=n.replace(/-(\D)/g,function(e,t){return t.toUpperCase()}),"float"==n&&(n=v?"styleFloat":"cssFloat"),e.currentStyle&&r?e.currentStyle[n]:e.style?e.style[n]:t}},setStyles:function(e,t){this.setStyle(e,t)},css:function(e,t,n){this.setStyle(e,t,n)},removeAllAttribs:function(e){return this.run(e,function(e){var t,n=e.attributes;for(t=n.length-1;t>=0;t--)e.removeAttributeNode(n.item(t))})},setAttrib:function(e,t,n){var r=this;if(e&&t)return this.run(e,function(e){var i=r.settings,o=e.getAttribute(t);if(null!==n)switch(t){case"style":if(!f(n,"string"))return void d(n,function(t,n){r.setStyle(e,n,t)});i.keep_values&&(n?e.setAttribute("data-mce-style",n,2):e.removeAttribute("data-mce-style",2)),e.style.cssText=n;break;case"class":e.className=n||"";break;case"src":case"href":i.keep_values&&(i.url_converter&&(n=i.url_converter.call(i.url_converter_scope||r,n,t,e)),r.setAttrib(e,"data-mce-"+t,n,2));break;case"shape":e.setAttribute("data-mce-style",n)}f(n)&&null!==n&&0!==n.length?e.setAttribute(t,""+n,2):e.removeAttribute(t,2),o!=n&&i.onSetAttrib&&i.onSetAttrib({attrElm:e,attrName:t,attrValue:n})})},setAttribs:function(e,t){var n=this;return this.run(e,function(e){d(t,function(t,r){n.setAttrib(e,r,t)})})},getAttrib:function(e,t,n){var r,i=this,o;if(e=i.get(e),!e||1!==e.nodeType)return n===o?!1:n;if(f(n)||(n=""),/^(src|href|style|coords|shape)$/.test(t)&&(r=e.getAttribute("data-mce-"+t)))return r;if(v&&i.props[t]&&(r=e[i.props[t]],r=r&&r.nodeValue?r.nodeValue:r),r||(r=e.getAttribute(t,2)),/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(t))return e[i.props[t]]===!0&&""===r?t:r?t:"";if("FORM"===e.nodeName&&e.getAttributeNode(t))return e.getAttributeNode(t).nodeValue;if("style"===t&&(r=r||e.style.cssText,r&&(r=i.serializeStyle(i.parseStyle(r),e.nodeName),i.settings.keep_values&&e.setAttribute("data-mce-style",r))),g&&"class"===t&&r&&(r=r.replace(/(apple|webkit)\-[a-z\-]+/gi,"")),v)switch(t){case"rowspan":case"colspan":1===r&&(r="");break;case"size":("+0"===r||20===r||0===r)&&(r="");break;case"width":case"height":case"vspace":case"checked":case"disabled":case"readonly":0===r&&(r="");break;case"hspace":-1===r&&(r="");break;case"maxlength":case"tabindex":(32768===r||2147483647===r||"32768"===r)&&(r="");break;case"multiple":case"compact":case"noshade":case"nowrap":return 65535===r?t:n;case"shape":r=r.toLowerCase();break;default:0===t.indexOf("on")&&r&&(r=(""+r).replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/,"$1"))}return r!==o&&null!==r&&""!==r?""+r:n},getPos:function(e,t){var n=this,r=0,i=0,o,a=n.doc,s;if(e=n.get(e),t=t||a.body,e){if(t===a.body&&e.getBoundingClientRect)return s=e.getBoundingClientRect(),t=n.boxModel?a.documentElement:a.body,r=s.left+(a.documentElement.scrollLeft||a.body.scrollLeft)-t.clientLeft,i=s.top+(a.documentElement.scrollTop||a.body.scrollTop)-t.clientTop,{x:r,y:i};for(o=e;o&&o!=t&&o.nodeType;)r+=o.offsetLeft||0,i+=o.offsetTop||0,o=o.offsetParent;for(o=e.parentNode;o&&o!=t&&o.nodeType;)r-=o.scrollLeft||0,i-=o.scrollTop||0,o=o.parentNode}return{x:r,y:i}},parseStyle:function(e){return this.styles.parse(e)},serializeStyle:function(e,t){return this.styles.serialize(e,t)},addStyle:function(e){var t=this,n=t.doc,r,i;if(t!==u.DOM&&n===document){var o=u.DOM.addedStyles;if(o=o||[],o[e])return;o[e]=!0,u.DOM.addedStyles=o}i=n.getElementById("mceDefaultStyles"),i||(i=n.createElement("style"),i.id="mceDefaultStyles",i.type="text/css",r=n.getElementsByTagName("head")[0],r.firstChild?r.insertBefore(i,r.firstChild):r.appendChild(i)),i.styleSheet?i.styleSheet.cssText+=e:i.appendChild(n.createTextNode(e))},loadCSS:function(e){var t=this,n=t.doc,r;return t!==u.DOM&&n===document?void u.DOM.loadCSS(e):(e||(e=""),r=n.getElementsByTagName("head")[0],void d(e.split(","),function(e){var i;t.files[e]||(t.files[e]=!0,i=t.create("link",{rel:"stylesheet",href:e}),v&&n.documentMode&&n.recalc&&(i.onload=function(){n.recalc&&n.recalc(),i.onload=null}),r.appendChild(i))}))},addClass:function(e,t){return this.run(e,function(e){var n;return t?this.hasClass(e,t)?e.className:(n=this.removeClass(e,t),e.className=n=(""!==n?n+" ":"")+t,n):0})},removeClass:function(e,t){var n=this,r;return n.run(e,function(e){var i;return n.hasClass(e,t)?(r||(r=new RegExp("(^|\\s+)"+t+"(\\s+|$)","g")),i=e.className.replace(r," "),i=h(" "!=i?i:""),e.className=i,i||(e.removeAttribute("class"),e.removeAttribute("className")),i):e.className})},hasClass:function(e,t){return e=this.get(e),e&&t?-1!==(" "+e.className+" ").indexOf(" "+t+" "):!1},toggleClass:function(e,n,r){r=r===t?!this.hasClass(e,n):r,this.hasClass(e,n)!==r&&(r?this.addClass(e,n):this.removeClass(e,n))},show:function(e){return this.setStyle(e,"display","block")},hide:function(e){return this.setStyle(e,"display","none")},isHidden:function(e){return e=this.get(e),!e||"none"==e.style.display||"none"==this.getStyle(e,"display")},uniqueId:function(e){return(e?e:"mce_")+this.counter++},setHTML:function(e,t){var n=this;return n.run(e,function(e){if(v){for(;e.firstChild;)e.removeChild(e.firstChild);try{e.innerHTML="
    "+t,e.removeChild(e.firstChild)}catch(r){var i=n.create("div");i.innerHTML="
    "+t,d(p(i.childNodes),function(t,n){n&&e.canHaveHTML&&e.appendChild(t)})}}else e.innerHTML=t;return t})},getOuterHTML:function(e){var t,n=this;return(e=n.get(e))?1===e.nodeType&&n.hasOuterHTML?e.outerHTML:(t=(e.ownerDocument||n.doc).createElement("body"),t.appendChild(e.cloneNode(!0)),t.innerHTML):null},setOuterHTML:function(e,t,n){var r=this;return r.run(e,function(e){function i(){var i,o;for(o=n.createElement("body"),o.innerHTML=t,i=o.lastChild;i;)r.insertAfter(i.cloneNode(!0),e),i=i.previousSibling;r.remove(e)}if(1==e.nodeType)if(n=n||e.ownerDocument||r.doc,v)try{1==e.nodeType&&r.hasOuterHTML?e.outerHTML=t:i()}catch(o){i()}else i()})},decode:a.decode,encode:a.encodeAllRaw,insertAfter:function(e,t){return t=this.get(t),this.run(e,function(e){var n,r;return n=t.parentNode,r=t.nextSibling,r?n.insertBefore(e,r):n.appendChild(e),e})},replace:function(e,t,n){var r=this;return r.run(t,function(t){return f(t,"array")&&(e=e.cloneNode(!0)),n&&d(p(t.childNodes),function(t){e.appendChild(t)}),t.parentNode.replaceChild(e,t)})},rename:function(e,t){var n=this,r;return e.nodeName!=t.toUpperCase()&&(r=n.create(t),d(n.getAttribs(e),function(t){n.setAttrib(r,t.nodeName,n.getAttrib(e,t.nodeName))}),n.replace(r,e,1)),r||e},findCommonAncestor:function(e,t){for(var n=e,r;n;){for(r=t;r&&n!=r;)r=r.parentNode;if(n==r)break;n=n.parentNode}return!n&&e.ownerDocument?e.ownerDocument.documentElement:n},toHex:function(e){return this.styles.toHex(l.trim(e))},run:function(e,t,n){var r=this,i;return"string"==typeof e&&(e=r.get(e)),e?(n=n||this,e.nodeType||!e.length&&0!==e.length?t.call(n,e):(i=[],d(e,function(e,o){e&&("string"==typeof e&&(e=r.get(e)),i.push(t.call(n,e,o)))}),i)):!1},getAttribs:function(e){var t;if(e=this.get(e),!e)return[];if(v){if(t=[],"OBJECT"==e.nodeName)return e.attributes;"OPTION"===e.nodeName&&this.getAttrib(e,"selected")&&t.push({specified:1,nodeName:"selected"});var n=/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi;return e.cloneNode(!1).outerHTML.replace(n,"").replace(/[\w:\-]+/gi,function(e){t.push({specified:1,nodeName:e})}),t}return e.attributes},isEmpty:function(e,t){var n=this,r,o,a,s,l,c=0;if(e=e.firstChild){s=new i(e,e.parentNode),t=t||n.schema?n.schema.getNonEmptyElements():null;do{if(a=e.nodeType,1===a){if(e.getAttribute("data-mce-bogus"))continue;if(l=e.nodeName.toLowerCase(),t&&t[l]){if("br"===l){c++;continue}return!1}for(o=n.getAttribs(e),r=o.length;r--;)if(l=o[r].nodeName,"name"===l||"data-mce-bookmark"===l)return!1}if(8==a)return!1;if(3===a&&!b.test(e.nodeValue))return!1}while(e=s.next())}return 1>=c},createRng:function(){var e=this.doc;return e.createRange?e.createRange():new o(this)},nodeIndex:function(e,t){var n=0,r,i;if(e)for(r=e.nodeType,e=e.previousSibling;e;e=e.previousSibling)i=e.nodeType,(!t||3!=i||i!=r&&e.nodeValue.length)&&(n++,r=i);return n},split:function(e,t,n){function r(e){function t(e){var t=e.previousSibling&&"SPAN"==e.previousSibling.nodeName,n=e.nextSibling&&"SPAN"==e.nextSibling.nodeName;return t&&n}var n,o=e.childNodes,a=e.nodeType;if(1!=a||"bookmark"!=e.getAttribute("data-mce-type")){for(n=o.length-1;n>=0;n--)r(o[n]);if(9!=a){if(3==a&&e.nodeValue.length>0){var s=h(e.nodeValue).length;if(!i.isBlock(e.parentNode)||s>0||0===s&&t(e))return}else if(1==a&&(o=e.childNodes,1==o.length&&o[0]&&1==o[0].nodeType&&"bookmark"==o[0].getAttribute("data-mce-type")&&e.parentNode.insertBefore(o[0],e),o.length||/^(br|hr|input|img)$/i.test(e.nodeName)))return;i.remove(e)}return e}}var i=this,o=i.createRng(),a,s,l;return e&&t?(o.setStart(e.parentNode,i.nodeIndex(e)),o.setEnd(t.parentNode,i.nodeIndex(t)),a=o.extractContents(),o=i.createRng(),o.setStart(t.parentNode,i.nodeIndex(t)+1),o.setEnd(e.parentNode,i.nodeIndex(e)+1),s=o.extractContents(),l=e.parentNode,l.insertBefore(r(a),e),n?l.replaceChild(n,t):l.insertBefore(t,e),l.insertBefore(r(s),e),i.remove(e),n||t):void 0},bind:function(e,t,n,r){var i=this;if(l.isArray(e)){for(var o=e.length;o--;)e[o]=i.bind(e[o],t,n,r);return e}return!i.settings.collect||e!==i.doc&&e!==i.win||i.boundEvents.push([e,t,n,r]),i.events.bind(e,t,n,r||i)},unbind:function(e,t,n){var r=this,i;if(l.isArray(e)){for(i=e.length;i--;)e[i]=r.unbind(e[i],t,n);return e}if(r.boundEvents&&(e===r.doc||e===r.win))for(i=r.boundEvents.length;i--;){var o=r.boundEvents[i];e!=o[0]||t&&t!=o[1]||n&&n!=o[2]||this.events.unbind(o[0],o[1],o[2])}return this.events.unbind(e,t,n)},fire:function(e,t,n){return this.events.fire(e,t,n)},getContentEditable:function(e){var t;return e&&1==e.nodeType?(t=e.getAttribute("data-mce-contenteditable"),t&&"inherit"!==t?t:"inherit"!==e.contentEditable?e.contentEditable:null):null},getContentEditableParent:function(e){for(var t=this.getRoot(),n=null;e&&e!==t&&(n=this.getContentEditable(e),null===n);e=e.parentNode);return n},destroy:function(){var t=this;if(t.boundEvents){for(var n=t.boundEvents.length;n--;){var r=t.boundEvents[n]; +this.events.unbind(r[0],r[1],r[2])}t.boundEvents=null}e.setDocument&&e.setDocument(),t.win=t.doc=t.root=t.events=t.frag=null},isChildOf:function(e,t){for(;e;){if(t===e)return!0;e=e.parentNode}return!1},dumpRng:function(e){return"startContainer: "+e.startContainer.nodeName+", startOffset: "+e.startOffset+", endContainer: "+e.endContainer.nodeName+", endOffset: "+e.endOffset},_findSib:function(e,t,n){var r=this,i=t;if(e)for("string"==typeof i&&(i=function(e){return r.is(e,t)}),e=e[n];e;e=e[n])if(i(e))return e;return null}},u.DOM=new u(document),u}),r(b,[y,p],function(e,t){function n(){function e(e,t){function n(){o.remove(s),a&&(a.onreadystatechange=a.onload=a=null),t()}function i(){"undefined"!=typeof console&&console.log&&console.log("Failed to load: "+e)}var o=r,a,s;s=o.uniqueId(),a=document.createElement("script"),a.id=s,a.type="text/javascript",a.src=e,"onreadystatechange"in a?a.onreadystatechange=function(){/loaded|complete/.test(a.readyState)&&n()}:a.onload=n,a.onerror=i,(document.getElementsByTagName("head")[0]||document.body).appendChild(a)}var t=0,n=1,a=2,s={},l=[],c={},u=[],d=0,f;this.isDone=function(e){return s[e]==a},this.markDone=function(e){s[e]=a},this.add=this.load=function(e,n,r){var i=s[e];i==f&&(l.push(e),s[e]=t),n&&(c[e]||(c[e]=[]),c[e].push({func:n,scope:r||this}))},this.loadQueue=function(e,t){this.loadScripts(l,e,t)},this.loadScripts=function(t,r,l){function p(e){i(c[e],function(e){e.func.call(e.scope)}),c[e]=f}var h;u.push({func:r,scope:l||this}),(h=function(){var r=o(t);t.length=0,i(r,function(t){return s[t]==a?void p(t):void(s[t]!=n&&(s[t]=n,d++,e(t,function(){s[t]=a,d--,p(t),h()})))}),d||(i(u,function(e){e.func.call(e.scope)}),u.length=0)})()}}var r=e.DOM,i=t.each,o=t.grep;return n.ScriptLoader=new n,n}),r(C,[b,p],function(e,n){function r(){var e=this;e.items=[],e.urls={},e.lookup={}}var i=n.each;return r.prototype={get:function(e){return this.lookup[e]?this.lookup[e].instance:t},dependencies:function(e){var t;return this.lookup[e]&&(t=this.lookup[e].dependencies),t||[]},requireLangPack:function(t,n){var i=r.language;if(i&&r.languageLoad!==!1){if(n)if(n=","+n+",",-1!=n.indexOf(","+i.substr(0,2)+","))i=i.substr(0,2);else if(-1==n.indexOf(","+i+","))return;e.ScriptLoader.add(this.urls[t]+"/langs/"+i+".js")}},add:function(e,t,n){return this.items.push(t),this.lookup[e]={instance:t,dependencies:n},t},createUrl:function(e,t){return"object"==typeof t?t:{prefix:e.prefix,resource:t,suffix:e.suffix}},addComponents:function(t,n){var r=this.urls[t];i(n,function(t){e.ScriptLoader.add(r+"/"+t)})},load:function(n,o,a,s){function l(){var r=c.dependencies(n);i(r,function(e){var n=c.createUrl(o,e);c.load(n.resource,n,t,t)}),a&&a.call(s?s:e)}var c=this,u=o;c.urls[n]||("object"==typeof o&&(u=o.prefix+o.resource+o.suffix),0!==u.indexOf("/")&&-1==u.indexOf("://")&&(u=r.baseURL+"/"+u),c.urls[n]=u.substring(0,u.lastIndexOf("/")),c.lookup[n]?l():e.ScriptLoader.add(u,l,s))}},r.PluginManager=new r,r.ThemeManager=new r,r}),r(x,[],function(){function e(e,t,n){var r,i,o=n?"lastChild":"firstChild",a=n?"prev":"next";if(e[o])return e[o];if(e!==t){if(r=e[a])return r;for(i=e.parent;i&&i!==t;i=i.parent)if(r=i[a])return r}}function t(e,t){this.name=e,this.type=t,1===t&&(this.attributes=[],this.attributes.map={})}var n=/^[ \t\r\n]*$/,r={"#text":3,"#comment":8,"#cdata":4,"#pi":7,"#doctype":10,"#document-fragment":11};return t.prototype={replace:function(e){var t=this;return e.parent&&e.remove(),t.insert(e,t),t.remove(),t},attr:function(e,t){var n=this,r,i,o;if("string"!=typeof e){for(i in e)n.attr(i,e[i]);return n}if(r=n.attributes){if(t!==o){if(null===t){if(e in r.map)for(delete r.map[e],i=r.length;i--;)if(r[i].name===e)return r=r.splice(i,1),n;return n}if(e in r.map){for(i=r.length;i--;)if(r[i].name===e){r[i].value=t;break}}else r.push({name:e,value:t});return r.map[e]=t,n}return r.map[e]}},clone:function(){var e=this,n=new t(e.name,e.type),r,i,o,a,s;if(o=e.attributes){for(s=[],s.map={},r=0,i=o.length;i>r;r++)a=o[r],"id"!==a.name&&(s[s.length]={name:a.name,value:a.value},s.map[a.name]=a.value);n.attributes=s}return n.value=e.value,n.shortEnded=e.shortEnded,n},wrap:function(e){var t=this;return t.parent.insert(e,t),e.append(t),t},unwrap:function(){var e=this,t,n;for(t=e.firstChild;t;)n=t.next,e.insert(t,e,!0),t=n;e.remove()},remove:function(){var e=this,t=e.parent,n=e.next,r=e.prev;return t&&(t.firstChild===e?(t.firstChild=n,n&&(n.prev=null)):r.next=n,t.lastChild===e?(t.lastChild=r,r&&(r.next=null)):n.prev=r,e.parent=e.next=e.prev=null),e},append:function(e){var t=this,n;return e.parent&&e.remove(),n=t.lastChild,n?(n.next=e,e.prev=n,t.lastChild=e):t.lastChild=t.firstChild=e,e.parent=t,e},insert:function(e,t,n){var r;return e.parent&&e.remove(),r=t.parent||this,n?(t===r.firstChild?r.firstChild=e:t.prev.next=e,e.prev=t.prev,e.next=t,t.prev=e):(t===r.lastChild?r.lastChild=e:t.next.prev=e,e.next=t.next,e.prev=t,t.next=e),e.parent=r,e},getAll:function(t){var n=this,r,i=[];for(r=n.firstChild;r;r=e(r,n))r.name===t&&i.push(r);return i},empty:function(){var t=this,n,r,i;if(t.firstChild){for(n=[],i=t.firstChild;i;i=e(i,t))n.push(i);for(r=n.length;r--;)i=n[r],i.parent=i.firstChild=i.lastChild=i.next=i.prev=null}return t.firstChild=t.lastChild=null,t},isEmpty:function(t){var r=this,i=r.firstChild,o,a;if(i)do{if(1===i.type){if(i.attributes.map["data-mce-bogus"])continue;if(t[i.name])return!1;for(o=i.attributes.length;o--;)if(a=i.attributes[o].name,"name"===a||0===a.indexOf("data-mce-"))return!1}if(8===i.type)return!1;if(3===i.type&&!n.test(i.value))return!1}while(i=e(i,r));return!0},walk:function(t){return e(this,null,t)}},t.create=function(e,n){var i,o;if(i=new t(e,r[e]||1),n)for(o in n)i.attr(o,n[o]);return i},t}),r(w,[p],function(e){function t(e,t){return e?e.split(t||" "):[]}function n(e){function n(e,n,r){function i(e){var t={},n,r;for(n=0,r=e.length;r>n;n++)t[e[n]]={};return t}var o,l,c,u=arguments;for(r=r||[],n=n||"","string"==typeof r&&(r=t(r)),l=3;lo;o++)i.attributes[n[o]]={},i.attributesOrder.push(n[o])}var a={},s,l,c,u,d,f;return r[e]?r[e]:(s=t("id accesskey class dir lang style tabindex title"),l=t("address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul"),c=t("a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd label map noscript object q s samp script select small span strong sub sup textarea u var #text #comment"),"html4"!=e&&(s.push.apply(s,t("contenteditable contextmenu draggable dropzone hidden spellcheck translate")),l.push.apply(l,t("article aside details dialog figure header footer hgroup section nav")),c.push.apply(c,t("audio canvas command datalist mark meter output progress time wbr video ruby bdi keygen"))),"html5-strict"!=e&&(s.push("xml:lang"),f=t("acronym applet basefont big font strike tt"),c.push.apply(c,f),o(f,function(e){n(e,"",c)}),d=t("center dir isindex noframes"),l.push.apply(l,d),u=[].concat(l,c),o(d,function(e){n(e,"",u)})),u=u||[].concat(l,c),n("html","manifest","head body"),n("head","","base command link meta noscript script style title"),n("title hr noscript br"),n("base","href target"),n("link","href rel media hreflang type sizes hreflang"),n("meta","name http-equiv content charset"),n("style","media type scoped"),n("script","src async defer type charset"),n("body","onafterprint onbeforeprint onbeforeunload onblur onerror onfocus onhashchange onload onmessage onoffline ononline onpagehide onpageshow onpopstate onresize onscroll onstorage onunload",u),n("address dt dd div caption","",u),n("h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn","",c),n("blockquote","cite",u),n("ol","reversed start type","li"),n("ul","","li"),n("li","value",u),n("dl","","dt dd"),n("a","href target rel media hreflang type",c),n("q","cite",c),n("ins del","cite datetime",u),n("img","src alt usemap ismap width height"),n("iframe","src name width height",u),n("embed","src type width height"),n("object","data type typemustmatch name usemap form width height",u,"param"),n("param","name value"),n("map","name",u,"area"),n("area","alt coords shape href target rel media hreflang type"),n("table","border","caption colgroup thead tfoot tbody tr"+("html4"==e?" col":"")),n("colgroup","span","col"),n("col","span"),n("tbody thead tfoot","","tr"),n("tr","","td th"),n("td","colspan rowspan headers",u),n("th","colspan rowspan headers scope abbr",u),n("form","accept-charset action autocomplete enctype method name novalidate target",u),n("fieldset","disabled form name",u,"legend"),n("label","form for",c),n("input","accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate formtarget height list max maxlength min multiple name pattern readonly required size src step type value width"),n("button","disabled form formaction formenctype formmethod formnovalidate formtarget name type value","html4"==e?u:c),n("select","disabled form multiple name required size","option optgroup"),n("optgroup","disabled label","option"),n("option","disabled label selected value"),n("textarea","cols dirname disabled form maxlength name readonly required rows wrap"),n("menu","type label",u,"li"),n("noscript","",u),"html4"!=e&&(n("wbr"),n("ruby","",c,"rt rp"),n("figcaption","",u),n("mark rt rp summary bdi","",c),n("canvas","width height",u),n("video","src crossorigin poster preload autoplay mediagroup loop muted controls width height buffered",u,"track source"),n("audio","src crossorigin preload autoplay mediagroup loop muted controls buffered volume",u,"track source"),n("source","src type media"),n("track","kind src srclang label default"),n("datalist","",c,"option"),n("article section nav aside header footer","",u),n("hgroup","","h1 h2 h3 h4 h5 h6"),n("figure","",u,"figcaption"),n("time","datetime",c),n("dialog","open",u),n("command","type label icon disabled checked radiogroup command"),n("output","for form name",c),n("progress","value max",c),n("meter","value min max low high optimum",c),n("details","open",u,"summary"),n("keygen","autofocus challenge disabled form keytype name")),"html5-strict"!=e&&(i("script","language xml:space"),i("style","xml:space"),i("object","declare classid codebase codetype archive standby align border hspace vspace"),i("param","valuetype type"),i("a","charset name rev shape coords"),i("br","clear"),i("applet","codebase archive code object alt name width height align hspace vspace"),i("img","name longdesc align border hspace vspace"),i("iframe","longdesc frameborder marginwidth marginheight scrolling align"),i("font basefont","size color face"),i("input","usemap align"),i("select","onchange"),i("textarea"),i("h1 h2 h3 h4 h5 h6 div p legend caption","align"),i("ul","type compact"),i("li","type"),i("ol dl menu dir","compact"),i("pre","width xml:space"),i("hr","align noshade size width"),i("isindex","prompt"),i("table","summary width frame rules cellspacing cellpadding align bgcolor"),i("col","width align char charoff valign"),i("colgroup","width align char charoff valign"),i("thead","align char charoff valign"),i("tr","align char charoff valign bgcolor"),i("th","axis align char charoff valign nowrap bgcolor width height"),i("form","accept"),i("td","abbr axis scope align char charoff valign nowrap bgcolor width height"),i("tfoot","align char charoff valign"),i("tbody","align char charoff valign"),i("area","nohref"),i("body","background bgcolor text link vlink alink")),"html4"!=e&&(i("input button select textarea","autofocus"),i("input textarea","placeholder"),i("a","download"),i("link script img","crossorigin"),i("iframe","sandbox seamless allowfullscreen")),o(t("a form meter progress dfn"),function(e){a[e]&&delete a[e].children[e]}),delete a.caption.children.table,r[e]=a,a)}var r={},i=e.makeMap,o=e.each,a=e.extend,s=e.explode,l=e.inArray;return function(e){function c(t,n,o){var s=e[t];return s?s=i(s,/[, ]/,i(s.toUpperCase(),/[, ]/)):(s=r[t],s||(s=i(n," ",i(n.toUpperCase()," ")),s=a(s,o),r[t]=s)),s}function u(e){return new RegExp("^"+e.replace(/([?+*])/g,".$1")+"$")}function d(e){var n,r,o,a,s,c,d,f,p,h,m,g,y,C,x,w,_,N,E,S=/^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)\])?$/,k=/^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,T=/[*?+]/;if(e)for(e=t(e,","),v["@"]&&(w=v["@"].attributes,_=v["@"].attributesOrder),n=0,r=e.length;r>n;n++)if(s=S.exec(e[n])){if(C=s[1],p=s[2],x=s[3],f=s[5],g={},y=[],c={attributes:g,attributesOrder:y},"#"===C&&(c.paddEmpty=!0),"-"===C&&(c.removeEmpty=!0),"!"===s[4]&&(c.removeEmptyAttrs=!0),w){for(N in w)g[N]=w[N];y.push.apply(y,_)}if(f)for(f=t(f,"|"),o=0,a=f.length;a>o;o++)if(s=k.exec(f[o])){if(d={},m=s[1],h=s[2].replace(/::/g,":"),C=s[3],E=s[4],"!"===m&&(c.attributesRequired=c.attributesRequired||[],c.attributesRequired.push(h),d.required=!0),"-"===m){delete g[h],y.splice(l(y,h),1);continue}C&&("="===C&&(c.attributesDefault=c.attributesDefault||[],c.attributesDefault.push({name:h,value:E}),d.defaultValue=E),":"===C&&(c.attributesForced=c.attributesForced||[],c.attributesForced.push({name:h,value:E}),d.forcedValue=E),"<"===C&&(d.validValues=i(E,"?"))),T.test(h)?(c.attributePatterns=c.attributePatterns||[],d.pattern=u(h),c.attributePatterns.push(d)):(g[h]||y.push(h),g[h]=d)}w||"@"!=p||(w=g,_=y),x&&(c.outputName=p,v[x]=c),T.test(p)?(c.pattern=u(p),b.push(c)):v[p]=c}}function f(e){v={},b=[],d(e),o(x,function(e,t){y[t]=e.children})}function p(e){var n=/^(~)?(.+)$/;e&&(r.text_block_elements=r.block_elements=null,o(t(e,","),function(e){var t=n.exec(e),r="~"===t[1],i=r?"span":"div",s=t[2];if(y[s]=y[i],R[s]=i,r||(S[s.toUpperCase()]={},S[s]={}),!v[s]){var l=v[i];l=a({},l),delete l.removeEmptyAttrs,delete l.removeEmpty,v[s]=l}o(y,function(e,t){e[i]&&(y[t]=e=a({},y[t]),e[s]=e[i])})}))}function h(e){var n=/^([+\-]?)(\w+)\[([^\]]+)\]$/;e&&o(t(e,","),function(e){var r=n.exec(e),i,s;r&&(s=r[1],i=s?y[r[2]]:y[r[2]]={"#comment":{}},i=y[r[2]],o(t(r[3],"|"),function(e){"-"===s?(y[r[2]]=i=a({},y[r[2]]),delete i[e]):i[e]={}}))})}function m(e){var t=v[e],n;if(t)return t;for(n=b.length;n--;)if(t=b[n],t.pattern.test(e))return t}var g=this,v={},y={},b=[],C,x,w,_,N,E,S,k,T,R={},A={};e=e||{},x=n(e.schema),e.verify_html===!1&&(e.valid_elements="*[*]"),e.valid_styles&&(C={},o(e.valid_styles,function(e,t){C[t]=s(e)})),w=c("whitespace_elements","pre script noscript style textarea video audio iframe object"),_=c("self_closing_elements","colgroup dd dt li option p td tfoot th thead tr"),N=c("short_ended_elements","area base basefont br col frame hr img input isindex link meta param embed source wbr track"),E=c("boolean_attributes","checked compact declare defer disabled ismap multiple nohref noresize noshade nowrap readonly selected autoplay loop controls"),k=c("non_empty_elements","td th iframe video audio object script",N),T=c("text_block_elements","h1 h2 h3 h4 h5 h6 p div address pre form blockquote center dir fieldset header footer article section hgroup aside nav figure"),S=c("block_elements","hr table tbody thead tfoot th tr td li ol ul caption dl dt dd noscript menu isindex option datalist select optgroup",T),o((e.special||"script noscript style textarea").split(" "),function(e){A[e]=new RegExp("]*>","gi")}),e.valid_elements?f(e.valid_elements):(o(x,function(e,t){v[t]={attributes:e.attributes,attributesOrder:e.attributesOrder},y[t]=e.children}),"html5"!=e.schema&&o(t("strong/b em/i"),function(e){e=t(e,"/"),v[e[1]].outputName=e[0]}),v.img.attributesDefault=[{name:"alt",value:""}],o(t("ol ul sub sup blockquote span font a table tbody tr strong em b i"),function(e){v[e]&&(v[e].removeEmpty=!0)}),o(t("p h1 h2 h3 h4 h5 h6 th td pre div address caption"),function(e){v[e].paddEmpty=!0}),o(t("span"),function(e){v[e].removeEmptyAttrs=!0})),p(e.custom_elements),h(e.valid_children),d(e.extended_valid_elements),h("+ol[ul|ol],+ul[ul|ol]"),e.invalid_elements&&o(s(e.invalid_elements),function(e){v[e]&&delete v[e]}),m("span")||d("span[!data-mce-type|*]"),g.children=y,g.styles=C,g.getBoolAttrs=function(){return E},g.getBlockElements=function(){return S},g.getTextBlockElements=function(){return T},g.getShortEndedElements=function(){return N},g.getSelfClosingElements=function(){return _},g.getNonEmptyElements=function(){return k},g.getWhiteSpaceElements=function(){return w},g.getSpecialElements=function(){return A},g.isValidChild=function(e,t){var n=y[e];return!(!n||!n[t])},g.isValid=function(e,t){var n,r,i=m(e);if(i){if(!t)return!0;if(i.attributes[t])return!0;if(n=i.attributePatterns)for(r=n.length;r--;)if(n[r].pattern.test(e))return!0}return!1},g.getElementRule=m,g.getCustomElements=function(){return R},g.addValidElements=d,g.setValidElements=f,g.addCustomElements=p,g.addValidChildren=h,g.elements=v}}),r(_,[w,m,p],function(e,t,n){var r=n.each;return function(i,o){function a(){}var s=this;i=i||{},s.schema=o=o||new e,i.fix_self_closing!==!1&&(i.fix_self_closing=!0),r("comment cdata text start end pi doctype".split(" "),function(e){e&&(s[e]=i[e]||a)}),s.parse=function(e){function r(e){var t,n;for(t=f.length;t--&&f[t].name!==e;);if(t>=0){for(n=f.length-1;n>=t;n--)e=f[n],e.valid&&s.end(e.name);f.length=t}}function a(e,t,n,r,o){var a,s,l=/[\s\u0000-\u001F]+/g;if(t=t.toLowerCase(),n=t in C?t:F(n||r||o||""),w&&!v&&0!==t.indexOf("data-")){if(a=k[t],!a&&T){for(s=T.length;s--&&(a=T[s],!a.pattern.test(t)););-1===s&&(a=null)}if(!a)return;if(a.validValues&&!(n in a.validValues))return}if(W[t]&&!i.allow_script_urls){var c=n.replace(l,"");try{c=decodeURIComponent(c)}catch(u){c=unescape(c)}if(V.test(c))return;if(!i.allow_html_data_urls&&U.test(c)&&!/^data:image\//i.test(c))return}p.map[t]=n,p.push({name:t,value:n})}var s=this,l,c=0,u,d,f=[],p,h,m,g,v,y,b,C,x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I=0,F=t.decode,z,W=n.makeMap("src,href,data,background,formaction,poster"),V=/((java|vb)script|mhtml):/i,U=/^data:/i;for(M=new RegExp("<(?:(?:!--([\\w\\W]*?)-->)|(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|(?:!DOCTYPE([\\w\\W]*?)>)|(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|(?:\\/([^>]+)>)|(?:([A-Za-z0-9\\-\\:\\.]+)((?:\\s+[^\"'>]+(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>]*))*|\\/|\\s+)>))","g"),H=/([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g,b=o.getShortEndedElements(),L=i.self_closing_elements||o.getSelfClosingElements(),C=o.getBoolAttrs(),w=i.validate,y=i.remove_internals,z=i.fix_self_closing,P=o.getSpecialElements();l=M.exec(e);){if(c0&&f[f.length-1].name===u&&r(u),!w||(_=o.getElementRule(u))){if(N=!0,w&&(k=_.attributes,T=_.attributePatterns),(S=l[8])?(v=-1!==S.indexOf("data-mce-type"),v&&y&&(N=!1),p=[],p.map={},S.replace(H,a)):(p=[],p.map={}),w&&!v){if(R=_.attributesRequired,A=_.attributesDefault,B=_.attributesForced,D=_.removeEmptyAttrs,D&&!p.length&&(N=!1),B)for(h=B.length;h--;)E=B[h],g=E.name,O=E.value,"{$uid}"===O&&(O="mce_"+I++),p.map[g]=O,p.push({name:g,value:O});if(A)for(h=A.length;h--;)E=A[h],g=E.name,g in p.map||(O=E.value,"{$uid}"===O&&(O="mce_"+I++),p.map[g]=O,p.push({name:g,value:O}));if(R){for(h=R.length;h--&&!(R[h]in p.map););-1===h&&(N=!1)}p.map["data-mce-bogus"]&&(N=!1)}N&&s.start(u,p,x)}else N=!1;if(d=P[u]){d.lastIndex=c=l.index+l[0].length,(l=d.exec(e))?(N&&(m=e.substr(c,l.index-c)),c=l.index+l[0].length):(m=e.substr(c),c=e.length),N&&(m.length>0&&s.text(m,!0),s.end(u)),M.lastIndex=c;continue}x||(S&&S.indexOf("/")==S.length-1?N&&s.end(u):f.push({name:u,valid:N}))}else(u=l[1])?(">"===u.charAt(0)&&(u=" "+u),i.allow_conditional_comments||"[if"!==u.substr(0,3)||(u=" "+u),s.comment(u)):(u=l[2])?s.cdata(u):(u=l[3])?s.doctype(u):(u=l[4])&&s.pi(u,l[5]);c=l.index+l[0].length}for(c=0;h--)u=f[h],u.valid&&s.end(u.name)}}}),r(N,[x,w,_,p],function(e,t,n,r){var i=r.makeMap,o=r.each,a=r.explode,s=r.extend;return function(r,l){function c(t){var n,r,o,a,s,c,d,f,p,h,m,g,v,y;for(m=i("tr,td,th,tbody,thead,tfoot,table"),h=l.getNonEmptyElements(),g=l.getTextBlockElements(),n=0;n1){for(a.reverse(),s=c=u.filterNode(a[0].clone()),p=0;p0?(t.value=n,t=t.prev):(r=t.prev,t.remove(),t=r)}function g(e){var t,n={};for(t in e)"li"!==t&&"p"!=t&&(n[t]=e[t]);return n}var v,y,b,C,x,w,_,N,E,S,k,T,R,A=[],B,D,L,M,H,P,O,I;if(o=o||{},p={},h={},T=s(i("script,style,head,html,body,title,meta,param"),l.getBlockElements()),O=l.getNonEmptyElements(),P=l.children,k=r.validate,I="forced_root_block"in o?o.forced_root_block:r.forced_root_block,H=l.getWhiteSpaceElements(),R=/^[ \t\r\n]+/,D=/[ \t\r\n]+$/,L=/[ \t\r\n]+/g,M=/^[ \t\r\n]+$/,v=new n({validate:k,allow_script_urls:r.allow_script_urls,allow_conditional_comments:r.allow_conditional_comments,self_closing_elements:g(l.getSelfClosingElements()),cdata:function(e){b.append(u("#cdata",4)).value=e},text:function(e,t){var n;B||(e=e.replace(L," "),b.lastChild&&T[b.lastChild.name]&&(e=e.replace(R,""))),0!==e.length&&(n=u("#text",3),n.raw=!!t,b.append(n).value=e)},comment:function(e){b.append(u("#comment",8)).value=e},pi:function(e,t){b.append(u(e,7)).value=t,m(b)},doctype:function(e){var t;t=b.append(u("#doctype",10)),t.value=e,m(b)},start:function(e,t,n){var r,i,o,a,s;if(o=k?l.getElementRule(e):{}){for(r=u(o.outputName||e,1),r.attributes=t,r.shortEnded=n,b.append(r),s=P[b.name],s&&P[r.name]&&!s[r.name]&&A.push(r),i=f.length;i--;)a=f[i].name,a in t.map&&(E=h[a],E?E.push(r):h[a]=[r]);T[e]&&m(r),n||(b=r),!B&&H[e]&&(B=!0)}},end:function(t){var n,r,i,o,a;if(r=k?l.getElementRule(t):{}){if(T[t]&&!B){if(n=b.firstChild,n&&3===n.type)if(i=n.value.replace(R,""),i.length>0)n.value=i,n=n.next;else for(o=n.next,n.remove(),n=o;n&&3===n.type;)i=n.value,o=n.next,(0===i.length||M.test(i))&&(n.remove(),n=o),n=o;if(n=b.lastChild,n&&3===n.type)if(i=n.value.replace(D,""),i.length>0)n.value=i,n=n.prev;else for(o=n.prev,n.remove(),n=o;n&&3===n.type;)i=n.value,o=n.prev,(0===i.length||M.test(i))&&(n.remove(),n=o),n=o}if(B&&H[t]&&(B=!1),(r.removeEmpty||r.paddEmpty)&&b.isEmpty(O))if(r.paddEmpty)b.empty().append(new e("#text","3")).value="\xa0";else if(!b.attributes.map.name&&!b.attributes.map.id)return a=b.parent,b.empty().remove(),void(b=a);b=b.parent}}},l),y=b=new e(o.context||r.root_name,11),v.parse(t),k&&A.length&&(o.context?o.invalid=!0:c(A)),I&&("body"==y.name||o.isRootContent)&&a(),!o.invalid){for(S in p){for(E=d[S],C=p[S],_=C.length;_--;)C[_].parent||C.splice(_,1);for(x=0,w=E.length;w>x;x++)E[x](C,S,o)}for(x=0,w=f.length;w>x;x++)if(E=f[x],E.name in h){for(C=h[E.name],_=C.length;_--;)C[_].parent||C.splice(_,1);for(_=0,N=E.callbacks.length;N>_;_++)E.callbacks[_](C,E.name,o)}}return y},r.remove_trailing_brs&&u.addNodeFilter("br",function(t){var n,r=t.length,i,o=s({},l.getBlockElements()),a=l.getNonEmptyElements(),c,u,d,f,p,h;for(o.body=1,n=0;r>n;n++)if(i=t[n],c=i.parent,o[i.parent.name]&&i===c.lastChild){for(d=i.prev;d;){if(f=d.name,"span"!==f||"bookmark"!==d.attr("data-mce-type")){if("br"!==f)break;if("br"===f){i=null;break}}d=d.prev}i&&(i.remove(),c.isEmpty(a)&&(p=l.getElementRule(c.name),p&&(p.removeEmpty?c.remove():p.paddEmpty&&(c.empty().append(new e("#text",3)).value="\xa0"))))}else{for(u=i;c&&c.firstChild===u&&c.lastChild===u&&(u=c,!o[c.name]);)c=c.parent;u===c&&(h=new e("#text",3),h.value="\xa0",i.replace(h))}}),r.allow_html_in_named_anchor||u.addAttributeFilter("id,name",function(e){for(var t=e.length,n,r,i,o;t--;)if(o=e[t],"a"===o.name&&o.firstChild&&!o.attr("href")){i=o.parent,n=o.lastChild;do r=n.prev,i.insert(n,o),n=r;while(n)}})}}),r(E,[m,p],function(e,t){var n=t.makeMap;return function(t){var r=[],i,o,a,s,l;return t=t||{},i=t.indent,o=n(t.indent_before||""),a=n(t.indent_after||""),s=e.getEncodeFunc(t.entity_encoding||"raw",t.entities),l="html"==t.element_format,{start:function(e,t,n){var c,u,d,f;if(i&&o[e]&&r.length>0&&(f=r[r.length-1],f.length>0&&"\n"!==f&&r.push("\n")),r.push("<",e),t)for(c=0,u=t.length;u>c;c++)d=t[c],r.push(" ",d.name,'="',s(d.value,!0),'"');r[r.length]=!n||l?">":" />",n&&i&&a[e]&&r.length>0&&(f=r[r.length-1],f.length>0&&"\n"!==f&&r.push("\n"))},end:function(e){var t;r.push(""),i&&a[e]&&r.length>0&&(t=r[r.length-1],t.length>0&&"\n"!==t&&r.push("\n"))},text:function(e,t){e.length>0&&(r[r.length]=t?e:s(e))},cdata:function(e){r.push("")},comment:function(e){r.push("")},pi:function(e,t){t?r.push(""):r.push(""),i&&r.push("\n")},doctype:function(e){r.push("",i?"\n":"")},reset:function(){r.length=0},getContent:function(){return r.join("").replace(/\n$/,"")}}}}),r(S,[E,w],function(e,t){return function(n,r){var i=this,o=new e(n);n=n||{},n.validate="validate"in n?n.validate:!0,i.schema=r=r||new t,i.writer=o,i.serialize=function(e){function t(e){var n=i[e.type],s,l,c,u,d,f,p,h,m;if(n)n(e);else{if(s=e.name,l=e.shortEnded,c=e.attributes,a&&c&&c.length>1){for(f=[],f.map={},m=r.getElementRule(e.name),p=0,h=m.attributesOrder.length;h>p;p++)u=m.attributesOrder[p],u in c.map&&(d=c.map[u],f.map[u]=d,f.push({name:u,value:d}));for(p=0,h=c.length;h>p;p++)u=c[p].name,u in f.map||(d=c.map[u],f.map[u]=d,f.push({name:u,value:d}));c=f}if(o.start(e.name,c,l),!l){if(e=e.firstChild)do t(e);while(e=e.next);o.end(s)}}}var i,a;return a=n.validate,i={3:function(e){o.text(e.value,e.raw)},8:function(e){o.comment(e.value)},7:function(e){o.pi(e.name,e.value)},10:function(e){o.doctype(e.value)},4:function(e){o.cdata(e.value)},11:function(e){if(e=e.firstChild)do t(e);while(e=e.next)}},o.reset(),1!=e.type||n.inner?i[11](e):t(e),o.getContent()}}}),r(k,[y,N,m,S,x,w,g,p],function(e,t,n,r,i,o,a,s){var l=s.each,c=s.trim,u=e.DOM;return function(e,i){var s,d,f;return i&&(s=i.dom,d=i.schema),s=s||u,d=d||new o(e),e.entity_encoding=e.entity_encoding||"named",e.remove_trailing_brs="remove_trailing_brs"in e?e.remove_trailing_brs:!0,f=new t(e,d),f.addAttributeFilter("data-mce-tabindex",function(e,t){for(var n=e.length,r;n--;)r=e[n],r.attr("tabindex",r.attributes.map["data-mce-tabindex"]),r.attr(t,null)}),f.addAttributeFilter("src,href,style",function(t,n){for(var r=t.length,i,o,a="data-mce-"+n,l=e.url_converter,c=e.url_converter_scope,u;r--;)i=t[r],o=i.attributes.map[a],o!==u?(i.attr(n,o.length>0?o:null),i.attr(a,null)):(o=i.attributes.map[n],"style"===n?o=s.serializeStyle(s.parseStyle(o),i.name):l&&(o=l.call(c,o,n,i.name)),i.attr(n,o.length>0?o:null))}),f.addAttributeFilter("class",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.attr("class").replace(/(?:^|\s)mce-item-\w+(?!\S)/g,""),n.attr("class",r.length>0?r:null)}),f.addAttributeFilter("data-mce-type",function(e,t,n){for(var r=e.length,i;r--;)i=e[r],"bookmark"!==i.attributes.map["data-mce-type"]||n.cleanup||i.remove()}),f.addAttributeFilter("data-mce-expando",function(e,t){for(var n=e.length;n--;)e[n].attr(t,null)}),f.addNodeFilter("noscript",function(e){for(var t=e.length,r;t--;)r=e[t].firstChild,r&&(r.value=n.decode(r.value))}),f.addNodeFilter("script,style",function(e,t){function n(e){return e.replace(/()/g,"\n").replace(/^[\r\n]*|[\r\n]*$/g,"").replace(/^\s*(()?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g,"")}for(var r=e.length,i,o;r--;)if(i=e[r],o=i.firstChild?i.firstChild.value:"","script"===t){var a=(i.attr("type")||"text/javascript").replace(/^mce\-/,"");i.attr("type","text/javascript"===a?null:a),o.length>0&&(i.firstChild.value="// ")}else o.length>0&&(i.firstChild.value="")}),f.addNodeFilter("#comment",function(e){for(var t=e.length,n;t--;)n=e[t],0===n.value.indexOf("[CDATA[")?(n.name="#cdata",n.type=4,n.value=n.value.replace(/^\[CDATA\[|\]\]$/g,"")):0===n.value.indexOf("mce:protected ")&&(n.name="#text",n.type=3,n.raw=!0,n.value=unescape(n.value).substr(14))}),f.addNodeFilter("xml:namespace,input",function(e,t){for(var n=e.length,r;n--;)r=e[n],7===r.type?r.remove():1===r.type&&("input"!==t||"type"in r.attributes.map||r.attr("type","text"))}),e.fix_list_elements&&f.addNodeFilter("ul,ol",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.parent,("ul"===r.name||"ol"===r.name)&&n.prev&&"li"===n.prev.name&&n.prev.append(n)}),f.addAttributeFilter("data-mce-src,data-mce-href,data-mce-style,data-mce-selected",function(e,t){for(var n=e.length;n--;)e[n].attr(t,null)}),{schema:d,addNodeFilter:f.addNodeFilter,addAttributeFilter:f.addAttributeFilter,serialize:function(t,n){var i=this,o,u,p,h,m;return a.ie&&s.select("script,style,select,map").length>0?(m=t.innerHTML,t=t.cloneNode(!1),s.setHTML(t,m)):t=t.cloneNode(!0),o=t.ownerDocument.implementation,o.createHTMLDocument&&(u=o.createHTMLDocument(""),l("BODY"==t.nodeName?t.childNodes:[t],function(e){u.body.appendChild(u.importNode(e,!0))}),t="BODY"!=t.nodeName?u.body.firstChild:u.body,p=s.doc,s.doc=u),n=n||{},n.format=n.format||"html",n.selection&&(n.forced_root_block=""),n.no_events||(n.node=t,i.onPreProcess(n)),h=new r(e,d),n.content=h.serialize(f.parse(c(n.getInner?t.innerHTML:s.getOuterHTML(t)),n)),n.cleanup||(n.content=n.content.replace(/\uFEFF/g,"")),n.no_events||i.onPostProcess(n),p&&(s.doc=p),n.node=null,n.content},addRules:function(e){d.addValidElements(e)},setRules:function(e){d.setValidElements(e)},onPreProcess:function(e){i&&i.fire("PreProcess",e)},onPostProcess:function(e){i&&i.fire("PostProcess",e)}}}}),r(T,[],function(){function e(e){function t(t,n){var r,i=0,o,a,s,l,c,u,d=-1,f;if(r=t.duplicate(),r.collapse(n),f=r.parentElement(),f.ownerDocument===e.dom.doc){for(;"false"===f.contentEditable;)f=f.parentNode; +if(!f.hasChildNodes())return{node:f,inside:1};for(s=f.children,o=s.length-1;o>=i;)if(u=Math.floor((i+o)/2),l=s[u],r.moveToElementText(l),d=r.compareEndPoints(n?"StartToStart":"EndToEnd",t),d>0)o=u-1;else{if(!(0>d))return{node:l};i=u+1}if(0>d)for(l?r.collapse(!1):(r.moveToElementText(f),r.collapse(!0),l=f,a=!0),c=0;0!==r.compareEndPoints(n?"StartToStart":"StartToEnd",t)&&0!==r.move("character",1)&&f==r.parentElement();)c++;else for(r.collapse(!0),c=0;0!==r.compareEndPoints(n?"StartToStart":"StartToEnd",t)&&0!==r.move("character",-1)&&f==r.parentElement();)c++;return{node:l,position:d,offset:c,inside:a}}}function n(){function n(e){var n=t(o,e),r,i,s=0,l,c,u;if(r=n.node,i=n.offset,n.inside&&!r.hasChildNodes())return void a[e?"setStart":"setEnd"](r,0);if(i===c)return void a[e?"setStartBefore":"setEndAfter"](r);if(n.position<0){if(l=n.inside?r.firstChild:r.nextSibling,!l)return void a[e?"setStartAfter":"setEndAfter"](r);if(!i)return void(3==l.nodeType?a[e?"setStart":"setEnd"](l,0):a[e?"setStartBefore":"setEndBefore"](l));for(;l;){if(u=l.nodeValue,s+=u.length,s>=i){r=l,s-=i,s=u.length-s;break}l=l.nextSibling}}else{if(l=r.previousSibling,!l)return a[e?"setStartBefore":"setEndBefore"](r);if(!i)return void(3==r.nodeType?a[e?"setStart":"setEnd"](l,r.nodeValue.length):a[e?"setStartAfter":"setEndAfter"](l));for(;l;){if(s+=l.nodeValue.length,s>=i){r=l,s-=i;break}l=l.previousSibling}}a[e?"setStart":"setEnd"](r,s)}var o=e.getRng(),a=i.createRng(),s,l,c,u,d;if(s=o.item?o.item(0):o.parentElement(),s.ownerDocument!=i.doc)return a;if(l=e.isCollapsed(),o.item)return a.setStart(s.parentNode,i.nodeIndex(s)),a.setEnd(a.startContainer,a.startOffset+1),a;try{n(!0),l||n()}catch(f){if(-2147024809!=f.number)throw f;d=r.getBookmark(2),c=o.duplicate(),c.collapse(!0),s=c.parentElement(),l||(c=o.duplicate(),c.collapse(!1),u=c.parentElement(),u.innerHTML=u.innerHTML),s.innerHTML=s.innerHTML,r.moveToBookmark(d),o=e.getRng(),n(!0),l||n()}return a}var r=this,i=e.dom,o=!1;this.getBookmark=function(n){function r(e){var t,n,r,o,a=[];for(t=e.parentNode,n=i.getRoot().parentNode;t!=n&&9!==t.nodeType;){for(r=t.children,o=r.length;o--;)if(e===r[o]){a.push(o);break}e=t,t=t.parentNode}return a}function o(e){var n;return n=t(a,e),n?{position:n.position,offset:n.offset,indexes:r(n.node),inside:n.inside}:void 0}var a=e.getRng(),s={};return 2===n&&(a.item?s.start={ctrl:!0,indexes:r(a.item(0))}:(s.start=o(!0),e.isCollapsed()||(s.end=o()))),s},this.moveToBookmark=function(e){function t(e){var t,n,r,o;for(t=i.getRoot(),n=e.length-1;n>=0;n--)o=t.children,r=e[n],r<=o.length-1&&(t=o[r]);return t}function n(n){var i=e[n?"start":"end"],a,s,l,c;i&&(a=i.position>0,s=o.createTextRange(),s.moveToElementText(t(i.indexes)),c=i.offset,c!==l?(s.collapse(i.inside||a),s.moveStart("character",a?-c:c)):s.collapse(n),r.setEndPoint(n?"StartToStart":"EndToStart",s),n&&r.collapse(!0))}var r,o=i.doc.body;e.start&&(e.start.ctrl?(r=o.createControlRange(),r.addElement(t(e.start.indexes)),r.select()):(r=o.createTextRange(),n(!0),n(),r.select()))},this.addRange=function(t){function n(e){var t,n,a,d,h;a=i.create("a"),t=e?s:c,n=e?l:u,d=r.duplicate(),(t==f||t==f.documentElement)&&(t=p,n=0),3==t.nodeType?(t.parentNode.insertBefore(a,t),d.moveToElementText(a),d.moveStart("character",n),i.remove(a),r.setEndPoint(e?"StartToStart":"EndToEnd",d)):(h=t.childNodes,h.length?(n>=h.length?i.insertAfter(a,h[h.length-1]):t.insertBefore(a,h[n]),d.moveToElementText(a)):t.canHaveHTML&&(t.innerHTML="",a=t.firstChild,d.moveToElementText(a),d.collapse(o)),r.setEndPoint(e?"StartToStart":"EndToEnd",d),i.remove(a))}var r,a,s,l,c,u,d,f=e.dom.doc,p=f.body,h,m;if(s=t.startContainer,l=t.startOffset,c=t.endContainer,u=t.endOffset,r=p.createTextRange(),s==c&&1==s.nodeType){if(l==u&&!s.hasChildNodes()){if(s.canHaveHTML)return d=s.previousSibling,d&&!d.hasChildNodes()&&i.isBlock(d)?d.innerHTML="":d=null,s.innerHTML="",r.moveToElementText(s.lastChild),r.select(),i.doc.selection.clear(),s.innerHTML="",void(d&&(d.innerHTML=""));l=i.nodeIndex(s),s=s.parentNode}if(l==u-1)try{if(m=s.childNodes[l],a=p.createControlRange(),a.addElement(m),a.select(),h=e.getRng(),h.item&&m===h.item(0))return}catch(g){}}n(!0),n(),r.select()},this.getRangeAt=n}return e}),r(R,[g],function(e){return{BACKSPACE:8,DELETE:46,DOWN:40,ENTER:13,LEFT:37,RIGHT:39,SPACEBAR:32,TAB:9,UP:38,modifierPressed:function(e){return e.shiftKey||e.ctrlKey||e.altKey},metaKeyPressed:function(t){return(e.mac?t.metaKey:t.ctrlKey)&&!t.altKey}}}),r(A,[R,p,g],function(e,t,n){return function(r,i){function o(e){var t=i.settings.object_resizing;return t===!1||n.iOS?!1:("string"!=typeof t&&(t="table,img,div"),"false"===e.getAttribute("data-mce-resize")?!1:i.dom.is(e,t))}function a(t){var n,r;n=t.screenX-k,r=t.screenY-T,H=n*E[2]+B,P=r*E[3]+D,H=5>H?5:H,P=5>P?5:P,(e.modifierPressed(t)||"IMG"==w.nodeName&&E[2]*E[3]!==0)&&(H=Math.round(P/L),P=Math.round(H*L)),C.setStyles(_,{width:H,height:P}),E[2]<0&&_.clientWidth<=H&&C.setStyle(_,"left",R+(B-H)),E[3]<0&&_.clientHeight<=P&&C.setStyle(_,"top",A+(D-P)),M||(i.fire("ObjectResizeStart",{target:w,width:B,height:D}),M=!0)}function s(){function e(e,t){t&&(w.style[e]||!i.schema.isValid(w.nodeName.toLowerCase(),e)?C.setStyle(w,e,t):C.setAttrib(w,e,t))}M=!1,e("width",H),e("height",P),C.unbind(O,"mousemove",a),C.unbind(O,"mouseup",s),I!=O&&(C.unbind(I,"mousemove",a),C.unbind(I,"mouseup",s)),C.remove(_),F&&"TABLE"!=w.nodeName||l(w),i.fire("ObjectResized",{target:w,width:H,height:P}),i.nodeChanged()}function l(e,t,r){var l,u,d,f,p,h=i.getBody();g(),l=C.getPos(e,h),R=l.x,A=l.y,p=e.getBoundingClientRect(),u=p.width||p.right-p.left,d=p.height||p.bottom-p.top,w!=e&&(m(),w=e,H=P=0),f=i.fire("ObjectSelected",{target:e}),o(e)&&!f.isDefaultPrevented()?x(N,function(e,o){function l(t){k=t.screenX,T=t.screenY,B=w.clientWidth,D=w.clientHeight,L=D/B,E=e,_=w.cloneNode(!0),C.addClass(_,"mce-clonedresizable"),_.contentEditable=!1,_.unSelectabe=!0,C.setStyles(_,{left:R,top:A,margin:0}),_.removeAttribute("data-mce-selected"),i.getBody().appendChild(_),C.bind(O,"mousemove",a),C.bind(O,"mouseup",s),I!=O&&(C.bind(I,"mousemove",a),C.bind(I,"mouseup",s))}var c,f;return t?void(o==t&&l(r)):(c=C.get("mceResizeHandle"+o),c?C.show(c):(f=i.getBody(),c=C.add(f,"div",{id:"mceResizeHandle"+o,"data-mce-bogus":!0,"class":"mce-resizehandle",unselectable:!0,style:"cursor:"+o+"-resize; margin:0; padding:0"}),n.ie&&(c.contentEditable=!1)),e.elm||(C.bind(c,"mousedown",function(e){e.stopImmediatePropagation(),e.preventDefault(),l(e)}),e.elm=c),void C.setStyles(c,{left:u*e[0]+R-c.offsetWidth/2,top:d*e[1]+A-c.offsetHeight/2}))}):c(),w.setAttribute("data-mce-selected","1")}function c(){var e,t;g(),w&&w.removeAttribute("data-mce-selected");for(e in N)t=C.get("mceResizeHandle"+e),t&&(C.unbind(t),C.remove(t))}function u(e){function t(e,t){if(e)do if(e===t)return!0;while(e=e.parentNode)}var n;return x(C.select("img[data-mce-selected],hr[data-mce-selected]"),function(e){e.removeAttribute("data-mce-selected")}),n="mousedown"==e.type?e.target:r.getNode(),n=C.getParent(n,F?"table":"table,img,hr"),t(n,i.getBody())&&(v(),t(r.getStart(),n)&&t(r.getEnd(),n)&&(!F||n!=r.getStart()&&"IMG"!==r.getStart().nodeName))?void l(n):void c()}function d(e,t,n){e&&e.attachEvent&&e.attachEvent("on"+t,n)}function f(e,t,n){e&&e.detachEvent&&e.detachEvent("on"+t,n)}function p(e){var t=e.srcElement,n,r,o,a,s,c,u;n=t.getBoundingClientRect(),c=S.clientX-n.left,u=S.clientY-n.top;for(r in N)if(o=N[r],a=t.offsetWidth*o[0],s=t.offsetHeight*o[1],Math.abs(a-c)<8&&Math.abs(s-u)<8){E=o;break}M=!0,i.getDoc().selection.empty(),l(t,r,S)}function h(e){var t=e.srcElement;if(t!=w){if(m(),0===t.id.indexOf("mceResizeHandle"))return void(e.returnValue=!1);("IMG"==t.nodeName||"TABLE"==t.nodeName)&&(c(),w=t,d(t,"resizestart",p))}}function m(){f(w,"resizestart",p)}function g(){for(var e in N){var t=N[e];t.elm&&(C.unbind(t.elm),delete t.elm)}}function v(){try{i.getDoc().execCommand("enableObjectResizing",!1,!1)}catch(e){}}function y(e){var t;if(F){t=O.body.createControlRange();try{return t.addElement(e),t.select(),!0}catch(n){}}}function b(){w=_=null,F&&(m(),f(i.getBody(),"controlselect",h))}var C=i.dom,x=t.each,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O=i.getDoc(),I=document,F=n.ie&&n.ie<11;N={n:[.5,0,0,-1],e:[1,.5,1,0],s:[.5,1,0,1],w:[0,.5,-1,0],nw:[0,0,-1,-1],ne:[1,0,1,-1],se:[1,1,1,1],sw:[0,1,-1,1]};var z=".mce-content-body";return i.contentStyles.push(z+" div.mce-resizehandle {position: absolute;border: 1px solid black;background: #FFF;width: 5px;height: 5px;z-index: 10000}"+z+" .mce-resizehandle:hover {background: #000}"+z+" img[data-mce-selected], hr[data-mce-selected] {outline: 1px solid black;resize: none}"+z+" .mce-clonedresizable {position: absolute;"+(n.gecko?"":"outline: 1px dashed black;")+"opacity: .5;filter: alpha(opacity=50);z-index: 10000}"),i.on("init",function(){F?(i.on("ObjectResized",function(e){"TABLE"!=e.target.nodeName&&(c(),y(e.target))}),d(i.getBody(),"controlselect",h),i.on("mousedown",function(e){S=e})):(v(),n.ie>=11&&(i.on("mouseup",function(e){var t=e.target.nodeName;/^(TABLE|IMG|HR)$/.test(t)&&(i.selection.select(e.target,"TABLE"==t),i.nodeChanged())}),i.dom.bind(i.getBody(),"mscontrolselect",function(e){/^(TABLE|IMG|HR)$/.test(e.target.nodeName)&&(e.preventDefault(),"IMG"==e.target.tagName&&window.setTimeout(function(){i.selection.select(e.target)},0))}))),i.on("nodechange mousedown mouseup ResizeEditor",u),i.on("keydown keyup",function(e){w&&"TABLE"==w.nodeName&&u(e)}),i.on("hide",c)}),i.on("remove",g),{isResizable:o,showResizeRect:l,hideResizeRect:c,updateResizeRect:u,controlSelect:y,destroy:b}}}),r(B,[p,f],function(e,t){function n(e){this.walk=function(t,n){function i(e){var t;return t=e[0],3===t.nodeType&&t===l&&c>=t.nodeValue.length&&e.splice(0,1),t=e[e.length-1],0===d&&e.length>0&&t===u&&3===t.nodeType&&e.splice(e.length-1,1),e}function o(e,t,n){for(var r=[];e&&e!=n;e=e[t])r.push(e);return r}function a(e,t){do{if(e.parentNode==t)return e;e=e.parentNode}while(e)}function s(e,t,r){var a=r?"nextSibling":"previousSibling";for(m=e,g=m.parentNode;m&&m!=t;m=g)g=m.parentNode,v=o(m==e?m:m[a],a),v.length&&(r||v.reverse(),n(i(v)))}var l=t.startContainer,c=t.startOffset,u=t.endContainer,d=t.endOffset,f,p,h,m,g,v,y;if(y=e.select("td.mce-item-selected,th.mce-item-selected"),y.length>0)return void r(y,function(e){n([e])});if(1==l.nodeType&&l.hasChildNodes()&&(l=l.childNodes[c]),1==u.nodeType&&u.hasChildNodes()&&(u=u.childNodes[Math.min(d-1,u.childNodes.length-1)]),l==u)return n(i([l]));for(f=e.findCommonAncestor(l,u),m=l;m;m=m.parentNode){if(m===u)return s(l,f,!0);if(m===f)break}for(m=u;m;m=m.parentNode){if(m===l)return s(u,f);if(m===f)break}p=a(l,f)||l,h=a(u,f)||u,s(l,p,!0),v=o(p==l?p:p.nextSibling,"nextSibling",h==u?h.nextSibling:h),v.length&&n(i(v)),s(u,h)},this.split=function(e){function t(e,t){return e.splitText(t)}var n=e.startContainer,r=e.startOffset,i=e.endContainer,o=e.endOffset;return n==i&&3==n.nodeType?r>0&&rr?(o-=r,n=i=t(i,o).previousSibling,o=i.nodeValue.length,r=0):o=0):(3==n.nodeType&&r>0&&r0&&o0)return c=p,u=n?p.nodeValue.length:0,void(i=!0);if(e.isBlock(p)||h[p.nodeName.toLowerCase()])return;s=p}o&&s&&(c=s,i=!0,u=0)}var c,u,d,f=e.getRoot(),p,h,m,g;if(c=n[(r?"start":"end")+"Container"],u=n[(r?"start":"end")+"Offset"],g=1==c.nodeType&&u===c.childNodes.length,h=e.schema.getNonEmptyElements(),m=r,1==c.nodeType&&u>c.childNodes.length-1&&(m=!1),9===c.nodeType&&(c=e.getRoot(),u=0),c===f){if(m&&(p=c.childNodes[u>0?u-1:0],p&&(h[p.nodeName]||"TABLE"==p.nodeName)))return;if(c.hasChildNodes()&&(u=Math.min(!m&&u>0?u-1:u,c.childNodes.length-1),c=c.childNodes[u],u=0,c.hasChildNodes()&&!/TABLE/.test(c.nodeName))){p=c,d=new t(c,f);do{if(3===p.nodeType&&p.nodeValue.length>0){u=m?0:p.nodeValue.length,c=p,i=!0;break}if(h[p.nodeName.toLowerCase()]){u=e.nodeIndex(p),c=p.parentNode,"IMG"!=p.nodeName||m||u++,i=!0;break}}while(p=m?d.next():d.prev())}}o&&(3===c.nodeType&&0===u&&l(!0),1===c.nodeType&&(p=c.childNodes[u],p||(p=c.childNodes[u-1]),!p||"BR"!==p.nodeName||s(p,"A")||a(p)||a(p,!0)||l(!0,p))),m&&!o&&3===c.nodeType&&u===c.nodeValue.length&&l(!1),i&&n["set"+(r?"Start":"End")](c,u)}var i,o;return o=n.collapsed,r(!0),o||r(),i&&o&&n.collapse(!0),i}}var r=e.each;return n.compareRanges=function(e,t){if(e&&t){if(!e.item&&!e.duplicate)return e.startContainer==t.startContainer&&e.startOffset==t.startOffset;if(e.item&&t.item&&e.item(0)===t.item(0))return!0;if(e.isEqual&&t.isEqual&&t.isEqual(e))return!0}return!1},n}),r(D,[f,T,A,B,g,p],function(e,n,r,i,o,a){function s(e,t,i,o){var a=this;a.dom=e,a.win=t,a.serializer=i,a.editor=o,a.controlSelection=new r(a,o),a.win.getSelection||(a.tridentSel=new n(a))}var l=a.each,c=a.grep,u=a.trim,d=o.ie,f=o.opera;return s.prototype={setCursorLocation:function(e,t){var n=this,r=n.dom.createRng();e?(r.setStart(e,t),r.setEnd(e,t),n.setRng(r),n.collapse(!1)):(n._moveEndPoint(r,n.editor.getBody(),!0),n.setRng(r))},getContent:function(e){var n=this,r=n.getRng(),i=n.dom.create("body"),o=n.getSel(),a,s,l;return e=e||{},a=s="",e.get=!0,e.format=e.format||"html",e.selection=!0,n.editor.fire("BeforeGetContent",e),"text"==e.format?n.isCollapsed()?"":r.text||(o.toString?o.toString():""):(r.cloneContents?(l=r.cloneContents(),l&&i.appendChild(l)):r.item!==t||r.htmlText!==t?(i.innerHTML="
    "+(r.item?r.item(0).outerHTML:r.htmlText),i.removeChild(i.firstChild)):i.innerHTML=r.toString(),/^\s/.test(i.innerHTML)&&(a=" "),/\s+$/.test(i.innerHTML)&&(s=" "),e.getInner=!0,e.content=n.isCollapsed()?"":a+n.serializer.serialize(i,e)+s,n.editor.fire("GetContent",e),e.content)},setContent:function(e,t){var n=this,r=n.getRng(),i,o=n.win.document,a,s;if(t=t||{format:"html"},t.set=!0,t.selection=!0,e=t.content=e,t.no_events||n.editor.fire("BeforeSetContent",t),e=t.content,r.insertNode){e+='_',r.startContainer==o&&r.endContainer==o?o.body.innerHTML=e:(r.deleteContents(),0===o.body.childNodes.length?o.body.innerHTML=e:r.createContextualFragment?r.insertNode(r.createContextualFragment(e)):(a=o.createDocumentFragment(),s=o.createElement("div"),a.appendChild(s),s.outerHTML=e,r.insertNode(a))),i=n.dom.get("__caret"),r=o.createRange(),r.setStartBefore(i),r.setEndBefore(i),n.setRng(r),n.dom.remove("__caret");try{n.setRng(r)}catch(l){}}else r.item&&(o.execCommand("Delete",!1,null),r=n.getRng()),/^\s+/.test(e)?(r.pasteHTML('_'+e),n.dom.remove("__mce_tmp")):r.pasteHTML(e);t.no_events||n.editor.fire("SetContent",t)},getStart:function(){var e=this,t=e.getRng(),n,r,i,o;if(t.duplicate||t.item){if(t.item)return t.item(0);for(i=t.duplicate(),i.collapse(1),n=i.parentElement(),n.ownerDocument!==e.dom.doc&&(n=e.dom.getRoot()),r=o=t.parentElement();o=o.parentNode;)if(o==n){n=r;break}return n}return n=t.startContainer,1==n.nodeType&&n.hasChildNodes()&&(n=n.childNodes[Math.min(n.childNodes.length-1,t.startOffset)]),n&&3==n.nodeType?n.parentNode:n},getEnd:function(){var e=this,t=e.getRng(),n,r;return t.duplicate||t.item?t.item?t.item(0):(t=t.duplicate(),t.collapse(0),n=t.parentElement(),n.ownerDocument!==e.dom.doc&&(n=e.dom.getRoot()),n&&"BODY"==n.nodeName?n.lastChild||n:n):(n=t.endContainer,r=t.endOffset,1==n.nodeType&&n.hasChildNodes()&&(n=n.childNodes[r>0?r-1:r]),n&&3==n.nodeType?n.parentNode:n)},getBookmark:function(e,t){function n(e,t){var n=0;return l(a.select(e),function(e,r){e==t&&(n=r)}),n}function r(e){function t(t){var n,r,i,o=t?"start":"end";n=e[o+"Container"],r=e[o+"Offset"],1==n.nodeType&&"TR"==n.nodeName&&(i=n.childNodes,n=i[Math.min(t?r:r-1,i.length-1)],n&&(r=t?0:n.childNodes.length,e["set"+(t?"Start":"End")](n,r)))}return t(!0),t(),e}function i(){function e(e,n){var i=e[n?"startContainer":"endContainer"],a=e[n?"startOffset":"endOffset"],s=[],l,c,u=0;if(3==i.nodeType){if(t)for(l=i.previousSibling;l&&3==l.nodeType;l=l.previousSibling)a+=l.nodeValue.length;s.push(a)}else c=i.childNodes,a>=c.length&&c.length&&(u=1,a=Math.max(0,c.length-1)),s.push(o.dom.nodeIndex(c[a],t)+u);for(;i&&i!=r;i=i.parentNode)s.push(o.dom.nodeIndex(i,t));return s}var n=o.getRng(!0),r=a.getRoot(),i={};return i.start=e(n,!0),o.isCollapsed()||(i.end=e(n)),i}var o=this,a=o.dom,s,c,u,d,f,p,h="",m;if(2==e)return p=o.getNode(),f=p?p.nodeName:null,"IMG"==f?{name:f,index:n(f,p)}:o.tridentSel?o.tridentSel.getBookmark(e):i();if(e)return{rng:o.getRng()};if(s=o.getRng(),u=a.uniqueId(),d=o.isCollapsed(),m="overflow:hidden;line-height:0px",s.duplicate||s.item){if(s.item)return p=s.item(0),f=p.nodeName,{name:f,index:n(f,p)};c=s.duplicate();try{s.collapse(),s.pasteHTML(''+h+""),d||(c.collapse(!1),s.moveToElementText(c.parentElement()),0===s.compareEndPoints("StartToEnd",c)&&c.move("character",-1),c.pasteHTML(''+h+""))}catch(g){return null}}else{if(p=o.getNode(),f=p.nodeName,"IMG"==f)return{name:f,index:n(f,p)};c=r(s.cloneRange()),d||(c.collapse(!1),c.insertNode(a.create("span",{"data-mce-type":"bookmark",id:u+"_end",style:m},h))),s=r(s),s.collapse(!0),s.insertNode(a.create("span",{"data-mce-type":"bookmark",id:u+"_start",style:m},h))}return o.moveToBookmark({id:u,keep:1}),{id:u}},moveToBookmark:function(e){function t(t){var n=e[t?"start":"end"],r,i,o,l;if(n){for(o=n[0],i=s,r=n.length-1;r>=1;r--){if(l=i.childNodes,n[r]>l.length-1)return;i=l[n[r]]}3===i.nodeType&&(o=Math.min(n[0],i.nodeValue.length)),1===i.nodeType&&(o=Math.min(n[0],i.childNodes.length)),t?a.setStart(i,o):a.setEnd(i,o)}return!0}function n(t){var n=o.get(e.id+"_"+t),r,i,a,s,d=e.keep;if(n&&(r=n.parentNode,"start"==t?(d?(r=n.firstChild,i=1):i=o.nodeIndex(n),u=p=r,h=m=i):(d?(r=n.firstChild,i=1):i=o.nodeIndex(n),p=r,m=i),!d)){for(s=n.previousSibling,a=n.nextSibling,l(c(n.childNodes),function(e){3==e.nodeType&&(e.nodeValue=e.nodeValue.replace(/\uFEFF/g,""))});n=o.get(e.id+"_"+t);)o.remove(n,1);s&&a&&s.nodeType==a.nodeType&&3==s.nodeType&&!f&&(i=s.nodeValue.length,s.appendData(a.nodeValue),o.remove(a),"start"==t?(u=p=s,h=m=i):(p=s,m=i))}}function r(e){return!o.isBlock(e)||e.innerHTML||d||(e.innerHTML='
    '),e}var i=this,o=i.dom,a,s,u,p,h,m;if(e)if(e.start){if(a=o.createRng(),s=o.getRoot(),i.tridentSel)return i.tridentSel.moveToBookmark(e);t(!0)&&t()&&i.setRng(a)}else e.id?(n("start"),n("end"),u&&(a=o.createRng(),a.setStart(r(u),h),a.setEnd(r(p),m),i.setRng(a))):e.name?i.select(o.select(e.name)[e.index]):e.rng&&i.setRng(e.rng)},select:function(e,t){var n=this,r=n.dom,i=r.createRng(),o;if(n.lastFocusBookmark=null,e){if(!t&&n.controlSelection.controlSelect(e))return;o=r.nodeIndex(e),i.setStart(e.parentNode,o),i.setEnd(e.parentNode,o+1),t&&(n._moveEndPoint(i,e,!0),n._moveEndPoint(i,e)),n.setRng(i)}return e},isCollapsed:function(){var e=this,t=e.getRng(),n=e.getSel();return!t||t.item?!1:t.compareEndPoints?0===t.compareEndPoints("StartToEnd",t):!n||t.collapsed},collapse:function(e){var t=this,n=t.getRng(),r;n.item&&(r=n.item(0),n=t.win.document.body.createTextRange(),n.moveToElementText(r)),n.collapse(!!e),t.setRng(n)},getSel:function(){var e=this.win;return e.getSelection?e.getSelection():e.document.selection},getRng:function(e){function t(e,t,n){try{return t.compareBoundaryPoints(e,n)}catch(r){return-1}}var n=this,r,i,o,a=n.win.document,s;if(!e&&n.lastFocusBookmark){var l=n.lastFocusBookmark;return l.startContainer?(i=a.createRange(),i.setStart(l.startContainer,l.startOffset),i.setEnd(l.endContainer,l.endOffset)):i=l,i}if(e&&n.tridentSel)return n.tridentSel.getRangeAt(0);try{(r=n.getSel())&&(i=r.rangeCount>0?r.getRangeAt(0):r.createRange?r.createRange():a.createRange())}catch(c){}if(d&&i&&i.setStart&&a.selection){try{s=a.selection.createRange()}catch(c){}s&&s.item&&(o=s.item(0),i=a.createRange(),i.setStartBefore(o),i.setEndAfter(o))}return i||(i=a.createRange?a.createRange():a.body.createTextRange()),i.setStart&&9===i.startContainer.nodeType&&i.collapsed&&(o=n.dom.getRoot(),i.setStart(o,0),i.setEnd(o,0)),n.selectedRange&&n.explicitRange&&(0===t(i.START_TO_START,i,n.selectedRange)&&0===t(i.END_TO_END,i,n.selectedRange)?i=n.explicitRange:(n.selectedRange=null,n.explicitRange=null)),i},setRng:function(e,t){var n=this,r;if(e.select)try{e.select()}catch(i){}else if(n.tridentSel){if(e.cloneRange)try{return void n.tridentSel.addRange(e)}catch(i){}}else if(r=n.getSel()){n.explicitRange=e;try{r.removeAllRanges(),r.addRange(e)}catch(i){}t===!1&&r.extend&&(r.collapse(e.endContainer,e.endOffset),r.extend(e.startContainer,e.startOffset)),n.selectedRange=r.rangeCount>0?r.getRangeAt(0):null}},setNode:function(e){var t=this;return t.setContent(t.dom.getOuterHTML(e)),e},getNode:function(){function e(e,t){for(var n=e;e&&3===e.nodeType&&0===e.length;)e=t?e.nextSibling:e.previousSibling;return e||n}var t=this,n=t.getRng(),r,i=n.startContainer,o=n.endContainer,a=n.startOffset,s=n.endOffset,l=t.dom.getRoot();return n?n.setStart?(r=n.commonAncestorContainer,!n.collapsed&&(i==o&&2>s-a&&i.hasChildNodes()&&(r=i.childNodes[a]),3===i.nodeType&&3===o.nodeType&&(i=i.length===a?e(i.nextSibling,!0):i.parentNode,o=0===s?e(o.previousSibling,!1):o.parentNode,i&&i===o))?i:r&&3==r.nodeType?r.parentNode:r):(r=n.item?n.item(0):n.parentElement(),r.ownerDocument!==t.win.document&&(r=l),r):l},getSelectedBlocks:function(t,n){var r=this,i=r.dom,o,a,s=[];if(a=i.getRoot(),t=i.getParent(t||r.getStart(),i.isBlock),n=i.getParent(n||r.getEnd(),i.isBlock),t&&t!=a&&s.push(t),t&&n&&t!=n){o=t;for(var l=new e(t,a);(o=l.next())&&o!=n;)i.isBlock(o)&&s.push(o)}return n&&t!=n&&n!=a&&s.push(n),s},isForward:function(){var e=this.dom,t=this.getSel(),n,r;return t&&t.anchorNode&&t.focusNode?(n=e.createRng(),n.setStart(t.anchorNode,t.anchorOffset),n.collapse(!0),r=e.createRng(),r.setStart(t.focusNode,t.focusOffset),r.collapse(!0),n.compareBoundaryPoints(n.START_TO_START,r)<=0):!0},normalize:function(){var e=this,t=e.getRng();return!d&&new i(e.dom).normalize(t)&&e.setRng(t,e.isForward()),t},selectorChanged:function(e,t){var n=this,r;return n.selectorChangedData||(n.selectorChangedData={},r={},n.editor.on("NodeChange",function(e){var t=e.element,i=n.dom,o=i.getParents(t,null,i.getRoot()),a={};l(n.selectorChangedData,function(e,t){l(o,function(n){return i.is(n,t)?(r[t]||(l(e,function(e){e(!0,{node:n,selector:t,parents:o})}),r[t]=e),a[t]=e,!1):void 0})}),l(r,function(e,n){a[n]||(delete r[n],l(e,function(e){e(!1,{node:t,selector:n,parents:o})}))})})),n.selectorChangedData[e]||(n.selectorChangedData[e]=[]),n.selectorChangedData[e].push(t),n},getScrollContainer:function(){for(var e,t=this.dom.getRoot();t&&"BODY"!=t.nodeName;){if(t.scrollHeight>t.clientHeight){e=t;break}t=t.parentNode}return e},scrollIntoView:function(e){function t(e){for(var t=0,n=0,r=e;r&&r.nodeType;)t+=r.offsetLeft||0,n+=r.offsetTop||0,r=r.offsetParent;return{x:t,y:n}}var n,r,i=this,o=i.dom,a=o.getRoot(),s,l;if("BODY"!=a.nodeName){var c=i.getScrollContainer();if(c)return n=t(e).y-t(c).y,l=c.clientHeight,s=c.scrollTop,void((s>n||n+25>s+l)&&(c.scrollTop=s>n?n:n-l+25))}r=o.getViewPort(i.editor.getWin()),n=o.getPos(e).y,s=r.y,l=r.h,(ns+l)&&i.editor.getWin().scrollTo(0,s>n?n:n-l+25)},_moveEndPoint:function(t,n,r){var i=n,a=new e(n,i),s=this.dom.schema.getNonEmptyElements();do{if(3==n.nodeType&&0!==u(n.nodeValue).length)return void(r?t.setStart(n,0):t.setEnd(n,n.nodeValue.length));if(s[n.nodeName])return void(r?t.setStartBefore(n):"BR"==n.nodeName?t.setEndBefore(n):t.setEndAfter(n));if(o.ie&&o.ie<11&&this.dom.isBlock(n)&&this.dom.isEmpty(n))return void(r?t.setStart(n,0):t.setEnd(n,0))}while(n=r?a.next():a.prev());"BODY"==i.nodeName&&(r?t.setStart(i,0):t.setEnd(i,i.childNodes.length))},destroy:function(){this.win=null,this.controlSelection.destroy()}},s}),r(L,[p],function(e){function t(e,t){function r(e){return e.replace(/%(\w+)/g,"")}var i,o,a=e.dom,s="",l,c;if(c=e.settings.preview_styles,c===!1)return"";if(c||(c="font-family font-size font-weight font-style text-decoration text-transform color background-color border border-radius outline text-shadow"),"string"==typeof t){if(t=e.formatter.get(t),!t)return;t=t[0]}return i=t.block||t.inline||"span",o=a.create(i),n(t.styles,function(e,t){e=r(e),e&&a.setStyle(o,t,e)}),n(t.attributes,function(e,t){e=r(e),e&&a.setAttrib(o,t,e)}),n(t.classes,function(e){e=r(e),a.hasClass(o,e)||a.addClass(o,e)}),e.fire("PreviewFormats"),a.setStyles(o,{position:"absolute",left:-65535}),e.getBody().appendChild(o),l=a.getStyle(e.getBody(),"fontSize",!0),l=/px$/.test(l)?parseInt(l,10):0,n(c.split(" "),function(t){var n=a.getStyle(o,t,!0);if(!("background-color"==t&&/transparent|rgba\s*\([^)]+,\s*0\)/.test(n)&&(n=a.getStyle(e.getBody(),t,!0),"#ffffff"==a.toHex(n).toLowerCase())||"color"==t&&"#000000"==a.toHex(n).toLowerCase())){if("font-size"==t&&/em|%$/.test(n)){if(0===l)return;n=parseFloat(n,10)/(/%$/.test(n)?100:1),n=n*l+"px"}"border"==t&&n&&(s+="padding:0 2px;"),s+=t+":"+n+";"}}),e.fire("AfterPreviewFormats"),a.remove(o),s}var n=e.each;return{getCssText:t}}),r(M,[f,B,p,L],function(e,t,n,r){return function(i){function o(e){return e.nodeType&&(e=e.nodeName),!!i.schema.getTextBlockElements()[e.toLowerCase()]}function a(e,t){return z.getParents(e,t,z.getRoot())}function s(e){return 1===e.nodeType&&"_mce_caret"===e.id}function l(){d({valigntop:[{selector:"td,th",styles:{verticalAlign:"top"}}],valignmiddle:[{selector:"td,th",styles:{verticalAlign:"middle"}}],valignbottom:[{selector:"td,th",styles:{verticalAlign:"bottom"}}],alignleft:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"left"},defaultBlock:"div"},{selector:"img,table",collapsed:!1,styles:{"float":"left"}}],aligncenter:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"center"},defaultBlock:"div"},{selector:"img",collapsed:!1,styles:{display:"block",marginLeft:"auto",marginRight:"auto"}},{selector:"table",collapsed:!1,styles:{marginLeft:"auto",marginRight:"auto"}}],alignright:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"right"},defaultBlock:"div"},{selector:"img,table",collapsed:!1,styles:{"float":"right"}}],alignjustify:[{selector:"figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li",styles:{textAlign:"justify"},defaultBlock:"div"}],bold:[{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}},{inline:"b",remove:"all"}],italic:[{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}},{inline:"i",remove:"all"}],underline:[{inline:"span",styles:{textDecoration:"underline"},exact:!0},{inline:"u",remove:"all"}],strikethrough:[{inline:"span",styles:{textDecoration:"line-through"},exact:!0},{inline:"strike",remove:"all"}],forecolor:{inline:"span",styles:{color:"%value"},wrap_links:!1},hilitecolor:{inline:"span",styles:{backgroundColor:"%value"},wrap_links:!1},fontname:{inline:"span",styles:{fontFamily:"%value"}},fontsize:{inline:"span",styles:{fontSize:"%value"}},fontsize_class:{inline:"span",attributes:{"class":"%value"}},blockquote:{block:"blockquote",wrapper:1,remove:"all"},subscript:{inline:"sub"},superscript:{inline:"sup"},code:{inline:"code"},link:{inline:"a",selector:"a",remove:"all",split:!0,deep:!0,onmatch:function(){return!0},onformat:function(e,t,n){nt(n,function(t,n){z.setAttrib(e,n,t)})}},removeformat:[{selector:"b,strong,em,i,font,u,strike,sub,sup,dfn,code,samp,kbd,var,cite,mark,q",remove:"all",split:!0,expand:!1,block_expand:!0,deep:!0},{selector:"span",attributes:["style","class"],remove:"empty",split:!0,expand:!1,deep:!0},{selector:"*",attributes:["style","class"],split:!1,expand:!1,deep:!0}]}),nt("p h1 h2 h3 h4 h5 h6 div address pre div dt dd samp".split(/\s/),function(e){d(e,{block:e,remove:"all"})}),d(i.settings.formats)}function c(){i.addShortcut("ctrl+b","bold_desc","Bold"),i.addShortcut("ctrl+i","italic_desc","Italic"),i.addShortcut("ctrl+u","underline_desc","Underline");for(var e=1;6>=e;e++)i.addShortcut("ctrl+"+e,"",["FormatBlock",!1,"h"+e]);i.addShortcut("ctrl+7","",["FormatBlock",!1,"p"]),i.addShortcut("ctrl+8","",["FormatBlock",!1,"div"]),i.addShortcut("ctrl+9","",["FormatBlock",!1,"address"])}function u(e){return e?F[e]:F}function d(e,t){e&&("string"!=typeof e?nt(e,function(e,t){d(t,e)}):(t=t.length?t:[t],nt(t,function(e){e.deep===Q&&(e.deep=!e.selector),e.split===Q&&(e.split=!e.selector||e.inline),e.remove===Q&&e.selector&&!e.inline&&(e.remove="none"),e.selector&&e.inline&&(e.mixed=!0,e.block_expand=!0),"string"==typeof e.classes&&(e.classes=e.classes.split(/\s+/))}),F[e]=t))}function f(e){var t;return i.dom.getParent(e,function(e){return t=i.dom.getStyle(e,"text-decoration"),t&&"none"!==t}),t}function p(e){var t;1===e.nodeType&&e.parentNode&&1===e.parentNode.nodeType&&(t=f(e.parentNode),i.dom.getStyle(e,"color")&&t?i.dom.setStyle(e,"text-decoration",t):i.dom.getStyle(e,"textdecoration")===t&&i.dom.setStyle(e,"text-decoration",null))}function h(t,n,r){function a(e,t){if(t=t||m,e){if(t.onformat&&t.onformat(e,t,n,r),nt(t.styles,function(t,r){z.setStyle(e,r,k(t,n))}),t.styles){var i=z.getAttrib(e,"style");i&&e.setAttribute("data-mce-style",i)}nt(t.attributes,function(t,r){z.setAttrib(e,r,k(t,n))}),nt(t.classes,function(t){t=k(t,n),z.hasClass(e,t)||z.addClass(e,t)})}}function l(){function t(t,n){var i=new e(n);for(r=i.current();r;r=i.prev())if(r.childNodes.length>1||r==t||"BR"==r.tagName)return r}var n=i.selection.getRng(),o=n.startContainer,a=n.endContainer;if(o!=a&&0===n.endOffset){var s=t(o,a),l=3==s.nodeType?s.length:s.childNodes.length;n.setEnd(s,l)}return n}function c(e,t,n,r,i){var o=[],a=-1,s,l=-1,c=-1,u;return nt(e.childNodes,function(e,t){return"UL"===e.nodeName||"OL"===e.nodeName?(a=t,s=e,!1):void 0}),nt(e.childNodes,function(e,n){"SPAN"===e.nodeName&&"bookmark"==z.getAttrib(e,"data-mce-type")&&(e.id==t.id+"_start"?l=n:e.id==t.id+"_end"&&(c=n))}),0>=a||a>l&&c>a?(nt(rt(e.childNodes),i),0):(u=z.clone(n,Y),nt(rt(e.childNodes),function(e,t){(a>l&&a>t||l>a&&t>a)&&(o.push(e),e.parentNode.removeChild(e))}),a>l?e.insertBefore(u,s):l>a&&e.insertBefore(u,s.nextSibling),r.push(u),nt(o,function(e){u.appendChild(e)}),u)}function d(e,r,i){var l=[],u,d,p=!0;u=m.inline||m.block,d=z.create(u),a(d),V.walk(e,function(e){function h(e){var y,C,x,w,_;return _=p,y=e.nodeName.toLowerCase(),C=e.parentNode.nodeName.toLowerCase(),1===e.nodeType&&Z(e)&&(_=p,p="true"===Z(e),w=!0),N(y,"br")?(g=0,void(m.block&&z.remove(e))):m.wrapper&&v(e,t,n)?void(g=0):p&&!w&&m.block&&!m.wrapper&&o(y)&&U(C,u)?(e=z.rename(e,u),a(e),l.push(e),void(g=0)):m.selector&&(nt(f,function(t){"collapsed"in t&&t.collapsed!==b||z.is(e,t.selector)&&!s(e)&&(a(e,t),x=!0)}),!m.inline||x)?void(g=0):void(!p||w||!U(u,y)||!U(C,u)||!i&&3===e.nodeType&&1===e.nodeValue.length&&65279===e.nodeValue.charCodeAt(0)||s(e)||m.inline&&q(e)?"li"==y&&r?g=c(e,r,d,l,h):(g=0,nt(rt(e.childNodes),h),w&&(p=_),g=0):(g||(g=z.clone(d,Y),e.parentNode.insertBefore(g,e),l.push(g)),g.appendChild(e)))}var g;nt(e,h)}),m.wrap_links===!1&&nt(l,function(e){function t(e){var n,r,i;if("A"===e.nodeName){for(r=z.clone(d,Y),l.push(r),i=rt(e.childNodes),n=0;n1||!q(e))&&0===o)return void z.remove(e,1);if(m.inline||m.wrapper){if(m.exact||1!==o||(e=i(e)),nt(f,function(t){nt(z.select(t.inline,e),function(e){var r;if(!M(e)){if(t.wrap_links===!1){r=e.parentNode;do if("A"===r.nodeName)return;while(r=r.parentNode)}B(t,n,e,t.exact?e:null)}})}),v(e.parentNode,t,n))return z.remove(e,1),e=0,X;m.merge_with_parents&&z.getParent(e.parentNode,function(r){return v(r,t,n)?(z.remove(e,1),e=0,X):void 0}),e&&m.merge_siblings!==!1&&(e=H(L(e),e),e=H(e,L(e,X)))}})}var f=u(t),m=f[0],g,y,b=!r&&W.isCollapsed();if(m)if(r)r.nodeType?(y=z.createRng(),y.setStartBefore(r),y.setEndAfter(r),d(A(y,f),null,!0)):d(r,null,!0);else if(b&&m.inline&&!z.select("td.mce-item-selected,th.mce-item-selected").length)O("apply",t,n);else{var C=i.selection.getNode();$||!f[0].defaultBlock||z.getParent(C,z.isBlock)||h(f[0].defaultBlock),i.selection.setRng(l()),g=W.getBookmark(),d(A(W.getRng(X),f),g),m.styles&&(m.styles.color||m.styles.textDecoration)&&(it(C,p,"childNodes"),p(C)),W.moveToBookmark(g),I(W.getRng(X)),i.nodeChanged()}}function m(e,t,n){function r(e){var n,i,o,a,s;if(1===e.nodeType&&Z(e)&&(a=b,b="true"===Z(e),s=!0),n=rt(e.childNodes),b&&!s)for(i=0,o=p.length;o>i&&!B(p[i],t,e,e);i++);if(h.deep&&n.length){for(i=0,o=n.length;o>i;i++)r(n[i]);s&&(b=a)}}function o(n){var r;return nt(a(n.parentNode).reverse(),function(n){var i;r||"_start"==n.id||"_end"==n.id||(i=v(n,e,t),i&&i.split!==!1&&(r=n))}),r}function s(e,n,r,i){var o,a,s,l,c,u;if(e){for(u=e.parentNode,o=n.parentNode;o&&o!=u;o=o.parentNode){for(a=z.clone(o,Y),c=0;c=0;o--){if(s=t[o].selector,!s||t[o].defaultBlock)return X;for(i=r.length-1;i>=0;i--)if(z.is(r[i],s))return X}return Y}function x(e,t,n){var r;return J||(J={},r={},i.on("NodeChange",function(e){var t=a(e.element),n={};nt(J,function(e,i){nt(t,function(o){return v(o,i,{},e.similar)?(r[i]||(nt(e,function(e){e(!0,{node:o,format:i,parents:t})}),r[i]=e),n[i]=e,!1):void 0})}),nt(r,function(i,o){n[o]||(delete r[o],nt(i,function(n){n(!1,{node:e.element,format:o,parents:t})}))})})),nt(e.split(","),function(e){J[e]||(J[e]=[],J[e].similar=n),J[e].push(t)}),this}function w(e){return r.getCssText(i,e)}function _(e,t){return N(e,t.inline)?X:N(e,t.block)?X:t.selector?1==e.nodeType&&z.is(e,t.selector):void 0}function N(e,t){return e=e||"",t=t||"",e=""+(e.nodeName||e),t=""+(t.nodeName||t),e.toLowerCase()==t.toLowerCase()}function E(e,t){return S(z.getStyle(e,t),t)}function S(e,t){return("color"==t||"backgroundColor"==t)&&(e=z.toHex(e)),"fontWeight"==t&&700==e&&(e="bold"),"fontFamily"==t&&(e=e.replace(/[\'\"]/g,"").replace(/,\s+/g,",")),""+e}function k(e,t){return"string"!=typeof e?e=e(t):t&&(e=e.replace(/%(\w+)/g,function(e,n){return t[n]||e})),e}function T(e){return e&&3===e.nodeType&&/^([\t \r\n]+|)$/.test(e.nodeValue)}function R(e,t,n){var r=z.create(t,n);return e.parentNode.insertBefore(r,e),r.appendChild(e),r}function A(t,n,r){function s(e){function t(e){return"BR"==e.nodeName&&e.getAttribute("data-mce-bogus")&&!e.nextSibling}var r,i,o,a,s;if(r=i=e?g:y,a=e?"previousSibling":"nextSibling",s=z.getRoot(),3==r.nodeType&&!T(r)&&(e?v>0:bi?n:i,-1===n||r||n++):(n=a.indexOf(" ",t),i=a.indexOf("\xa0",t),n=-1!==n&&(-1===i||i>n)?n:i),n}var s,l,c,u;if(3===t.nodeType){if(c=a(t,n),-1!==c)return{container:t,offset:c};u=t}for(s=new e(t,z.getParent(t,q)||i.getBody());l=s[o?"prev":"next"]();)if(3===l.nodeType){if(u=l,c=a(l),-1!==c)return{container:l,offset:c}}else if(q(l))break;return u?(n=o?0:u.length,{container:u,offset:n}):void 0}function d(e,r){var i,o,s,l;for(3==e.nodeType&&0===e.nodeValue.length&&e[r]&&(e=e[r]),i=a(e),o=0;op?p:v],3==g.nodeType&&(v=0)),1==y.nodeType&&y.hasChildNodes()&&(p=y.childNodes.length-1,y=y.childNodes[b>p?p:b-1],3==y.nodeType&&(b=y.nodeValue.length)),g=c(g),y=c(y),(M(g.parentNode)||M(g))&&(g=M(g)?g:g.parentNode,g=g.nextSibling||g,3==g.nodeType&&(v=0)),(M(y.parentNode)||M(y))&&(y=M(y)?y:y.parentNode,y=y.previousSibling||y,3==y.nodeType&&(b=y.length)),n[0].inline&&(t.collapsed&&(m=u(g,v,!0),m&&(g=m.container,v=m.offset),m=u(y,b),m&&(y=m.container,b=m.offset)),h=l(y,b),h.node)){for(;h.node&&0===h.offset&&h.node.previousSibling;)h=l(h.node.previousSibling);h.node&&h.offset>0&&3===h.node.nodeType&&" "===h.node.nodeValue.charAt(h.offset-1)&&h.offset>1&&(y=h.node,y.splitText(h.offset-1))}return(n[0].inline||n[0].block_expand)&&(n[0].inline&&3==g.nodeType&&0!==v||(g=s(!0)),n[0].inline&&3==y.nodeType&&b!==y.nodeValue.length||(y=s())),n[0].selector&&n[0].expand!==Y&&!n[0].inline&&(g=d(g,"previousSibling"),y=d(y,"nextSibling")),(n[0].block||n[0].selector)&&(g=f(g,"previousSibling"),y=f(y,"nextSibling"),n[0].block&&(q(g)||(g=s(!0)),q(y)||(y=s()))),1==g.nodeType&&(v=j(g),g=g.parentNode),1==y.nodeType&&(b=j(y)+1,y=y.parentNode),{startContainer:g,startOffset:v,endContainer:y,endOffset:b}}function B(e,t,n,r){var i,o,a;if(!_(n,e))return Y;if("all"!=e.remove)for(nt(e.styles,function(e,i){e=S(k(e,t),i),"number"==typeof i&&(i=e,r=0),(!r||N(E(r,i),e))&&z.setStyle(n,i,""),a=1}),a&&""===z.getAttrib(n,"style")&&(n.removeAttribute("style"),n.removeAttribute("data-mce-style")),nt(e.attributes,function(e,i){var o;if(e=k(e,t),"number"==typeof i&&(i=e,r=0),!r||N(z.getAttrib(r,i),e)){if("class"==i&&(e=z.getAttrib(n,i),e&&(o="",nt(e.split(/\s+/),function(e){/mce\w+/.test(e)&&(o+=(o?" ":"")+e)}),o)))return void z.setAttrib(n,i,o);"class"==i&&n.removeAttribute("className"),G.test(i)&&n.removeAttribute("data-mce-"+i),n.removeAttribute(i)}}),nt(e.classes,function(e){e=k(e,t),(!r||z.hasClass(r,e))&&z.removeClass(n,e)}),o=z.getAttribs(n),i=0;ia?a:o]),3===r.nodeType&&n&&o>=r.nodeValue.length&&(r=new e(r,i.getBody()).next()||r),3!==r.nodeType||n||0!==o||(r=new e(r,i.getBody()).prev()||r),r}function O(t,n,r){function a(e){var t=z.create("span",{id:y,"data-mce-bogus":!0,style:b?"color:red":""});return e&&t.appendChild(i.getDoc().createTextNode(K)),t}function s(e,t){for(;e;){if(3===e.nodeType&&e.nodeValue!==K||e.childNodes.length>1)return!1;t&&1===e.nodeType&&t.push(e),e=e.firstChild}return!0}function l(e){for(;e;){if(e.id===y)return e;e=e.parentNode}}function c(t){var n;if(t)for(n=new e(t,t),t=n.current();t;t=n.next())if(3===t.nodeType)return t}function d(e,t){var n,r;if(e)r=W.getRng(!0),s(e)?(t!==!1&&(r.setStartBefore(e),r.setEndBefore(e)),z.remove(e)):(n=c(e),n.nodeValue.charAt(0)===K&&(n=n.deleteData(0,1)),z.remove(e,1)),W.setRng(r);else if(e=l(W.getStart()),!e)for(;e=z.get(y);)d(e,!1)}function f(){var e,t,i,o,s,d,f;e=W.getRng(!0),o=e.startOffset,d=e.startContainer,f=d.nodeValue,t=l(W.getStart()),t&&(i=c(t)),f&&o>0&&o=0;p--)c.appendChild(z.clone(f[p],!1)),c=c.firstChild;c.appendChild(z.doc.createTextNode(K)),c=c.firstChild;var g=z.getParent(d,o);g&&z.isEmpty(g)?d.parentNode.replaceChild(h,d):z.insertAfter(h,d),W.setCursorLocation(c,1),z.isEmpty(d)&&z.remove(d)}}function g(){var e;e=l(W.getStart()),e&&!z.isEmpty(e)&&it(e,function(e){1!=e.nodeType||e.id===y||z.isEmpty(e)||z.setAttrib(e,"data-mce-bogus",null)},"childNodes")}var y="_mce_caret",b=i.settings.caret_debug;i._hasCaretEvents||(tt=function(){var e=[],t;if(s(l(W.getStart()),e))for(t=e.length;t--;)z.setAttrib(e[t],"data-mce-bogus","1")},et=function(e){var t=e.keyCode;d(),(8==t||37==t||39==t)&&d(l(W.getStart())),g()},i.on("SetContent",function(e){e.selection&&g()}),i._hasCaretEvents=!0),"apply"==t?f():p()}function I(t){var n=t.startContainer,r=t.startOffset,i,o,a,s,l;if(3==n.nodeType&&r>=n.nodeValue.length&&(r=j(n),n=n.parentNode,i=!0),1==n.nodeType)for(s=n.childNodes,n=s[Math.min(r,s.length-1)],o=new e(n,z.getParent(n,z.isBlock)),(r>s.length-1||i)&&o.next(),a=o.current();a;a=o.next())if(3==a.nodeType&&!T(a))return l=z.create("a",null,K),a.parentNode.insertBefore(l,a),t.setStart(a,0),W.setRng(t),void z.remove(l)}var F={},z=i.dom,W=i.selection,V=new t(z),U=i.schema.isValidChild,q=z.isBlock,$=i.settings.forced_root_block,j=z.nodeIndex,K="\ufeff",G=/^(src|href|style)$/,Y=!1,X=!0,J,Q,Z=z.getContentEditable,et,tt,nt=n.each,rt=n.grep,it=n.walk,ot=n.extend;ot(this,{get:u,register:d,apply:h,remove:m,toggle:g,match:y,matchAll:b,matchNode:v,canApply:C,formatChanged:x,getCssText:w}),l(),c(),i.on("BeforeGetContent",function(){tt&&tt()}),i.on("mouseup keydown",function(e){et&&et(e)})}}),r(H,[g,p],function(e,t){var n=t.trim,r;return r=new RegExp(["]+data-mce-bogus[^>]+>[\u200b\ufeff]+<\\/span>","]+data-mce-bogus[^>]+><\\/div>",'\\s?data-mce-selected="[^"]+"'].join("|"),"gi"),function(t){function i(){return n(t.getContent({format:"raw",no_events:1}).replace(r,""))}function o(e){a.typing=!1,a.add({},e)}var a=this,s=0,l=[],c,u,d=0;return t.on("init",function(){a.add()}),t.on("BeforeExecCommand",function(e){var t=e.command;"Undo"!=t&&"Redo"!=t&&"mceRepaint"!=t&&a.beforeChange()}),t.on("ExecCommand",function(e){var t=e.command;"Undo"!=t&&"Redo"!=t&&"mceRepaint"!=t&&o(e)}),t.on("ObjectResizeStart",function(){a.beforeChange()}),t.on("SaveContent ObjectResized blur",o),t.on("DragEnd",o),t.on("KeyUp",function(n){var r=n.keyCode;(r>=33&&36>=r||r>=37&&40>=r||45==r||13==r||n.ctrlKey)&&(o(),t.nodeChanged()),(46==r||8==r||e.mac&&(91==r||93==r))&&t.nodeChanged(),u&&a.typing&&(t.isDirty()||(t.isNotDirty=!l[0]||i()==l[0].content,t.isNotDirty||t.fire("change",{level:l[0],lastLevel:null})),t.fire("TypingUndo"),u=!1,t.nodeChanged())}),t.on("KeyDown",function(e){var t=e.keyCode;return t>=33&&36>=t||t>=37&&40>=t||45==t?void(a.typing&&o(e)):void((16>t||t>20)&&224!=t&&91!=t&&!a.typing&&(a.beforeChange(),a.typing=!0,a.add({},e),u=!0))}),t.on("MouseDown",function(e){a.typing&&o(e)}),t.addShortcut("ctrl+z","","Undo"),t.addShortcut("ctrl+y,ctrl+shift+z","","Redo"),t.on("AddUndo Undo Redo ClearUndos MouseUp",function(e){e.isDefaultPrevented()||t.nodeChanged()}),a={data:l,typing:!1,beforeChange:function(){d||(c=t.selection.getBookmark(2,!0))},add:function(e,n){var r,o=t.settings,a;if(e=e||{},e.content=i(),d||t.removed)return null;if(a=l[s],t.fire("BeforeAddUndo",{level:e,lastLevel:a,originalEvent:n}).isDefaultPrevented())return null;if(a&&a.content==e.content)return null;if(l[s]&&(l[s].beforeBookmark=c),o.custom_undo_redo_levels&&l.length>o.custom_undo_redo_levels){for(r=0;r0&&(t.isNotDirty=!1,t.fire("change",u)),e},undo:function(){var e;return a.typing&&(a.add(),a.typing=!1),s>0&&(e=l[--s],0===s&&(t.isNotDirty=!0),t.setContent(e.content,{format:"raw"}),t.selection.moveToBookmark(e.beforeBookmark),t.fire("undo",{level:e})),e},redo:function(){var e;return s0||a.typing&&l[0]&&i()!=l[0].content},hasRedo:function(){return sD)&&(u=a.create("br"),t.parentNode.insertBefore(u,t)),l.setStartBefore(t),l.setEndBefore(t)):(l.setStartAfter(t),l.setEndAfter(t)):(l.setStart(t,0),l.setEnd(t,0));s.setRng(l),a.remove(u),s.scrollIntoView(t)}function g(e){var t=l.forced_root_block;t&&t.toLowerCase()===e.tagName.toLowerCase()&&a.setAttribs(e,l.forced_root_block_attrs)}function v(e){var t=R,n,i,o;if(e||"TABLE"==O?(n=a.create(e||F),g(n)):n=B.cloneNode(!1),o=n,l.keep_styles!==!1)do if(/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U|VAR|CITE|DFN|CODE|MARK|Q|SUP|SUB|SAMP)$/.test(t.nodeName)){if("_mce_caret"==t.id)continue;i=t.cloneNode(!1),a.setAttrib(i,"id",""),n.hasChildNodes()?(i.appendChild(n.firstChild),n.appendChild(i)):(o=i,n.appendChild(i))}while(t=t.parentNode);return r||(o.innerHTML='
    '),n}function y(t){var n,r,i;if(3==R.nodeType&&(t?A>0:A0)return!0}function w(){var e,t,n;R&&3==R.nodeType&&A>=R.nodeValue.length&&(r||x()||(e=a.create("br"),S.insertNode(e),S.setStartAfter(e),S.setEndAfter(e),t=!0)),e=a.create("br"),S.insertNode(e),r&&"PRE"==O&&(!D||8>D)&&e.parentNode.insertBefore(a.doc.createTextNode("\r"),e),n=a.create("span",{}," "),e.parentNode.insertBefore(n,e),s.scrollIntoView(n),a.remove(n),t?(S.setStartBefore(e),S.setEndBefore(e)):(S.setStartAfter(e),S.setEndAfter(e)),s.setRng(S),c.add()}function _(e){do 3===e.nodeType&&(e.nodeValue=e.nodeValue.replace(/^[\r\n]+/,"")),e=e.firstChild;while(e)}function N(e){var t=a.getRoot(),n,r;for(n=e;n!==t&&"false"!==a.getContentEditable(n);)"true"===a.getContentEditable(n)&&(r=n),n=n.parentNode;return n!==t?r:t}function E(e){var t;r||(e.normalize(),t=e.lastChild,(!t||/^(left|right)$/gi.test(a.getStyle(t,"float",!0)))&&a.add(e,"br"))}var S,k,T,R,A,B,D,L,M,H,P,O,I,F,z;if(S=s.getRng(!0),!o.isDefaultPrevented()){if(!S.collapsed)return void i.execCommand("Delete");if(new t(a).normalize(S),R=S.startContainer,A=S.startOffset,F=(l.force_p_newlines?"p":"")||l.forced_root_block,F=F?F.toUpperCase():"",D=a.doc.documentMode,L=o.shiftKey,1==R.nodeType&&R.hasChildNodes()&&(z=A>R.childNodes.length-1,R=R.childNodes[Math.min(A,R.childNodes.length-1)]||R,A=z&&3==R.nodeType?R.nodeValue.length:0),T=N(R)){if(c.beforeChange(),!a.isBlock(T)&&T!=a.getRoot())return void((!F||L)&&w());if((F&&!L||!F&&L)&&(R=b(R,A)),B=a.getParent(R,a.isBlock),P=B?a.getParent(B.parentNode,a.isBlock):null,O=B?B.nodeName.toUpperCase():"",I=P?P.nodeName.toUpperCase():"","LI"!=I||o.ctrlKey||(B=P,O=I),"LI"==O){if(!F&&L)return void w();if(a.isEmpty(B))return void C()}if("PRE"==O&&l.br_in_pre!==!1){if(!L)return void w()}else if(!F&&!L&&"LI"!=O||F&&L)return void w();F&&B===i.getBody()||(F=F||"P",y()?(M=/^(H[1-6]|PRE|FIGURE)$/.test(O)&&"HGROUP"!=I?v(F):v(),l.end_container_on_empty_block&&f(P)&&a.isEmpty(B)?M=a.split(P,B):a.insertAfter(M,B),m(M)):y(!0)?(M=B.parentNode.insertBefore(v(),B),p(M),m(B)):(k=S.cloneRange(),k.setEndAfter(B),H=k.extractContents(),_(H),M=H.firstChild,a.insertAfter(H,B),h(M),E(B),m(M)),a.setAttrib(M,"id",""),i.fire("NewBlock",{newBlock:M}),c.add())}}}var a=i.dom,s=i.selection,l=i.settings,c=i.undoManager,u=i.schema,d=u.getNonEmptyElements();i.on("keydown",function(e){13==e.keyCode&&o(e)!==!1&&e.preventDefault()})}}),r(O,[],function(){return function(e){function t(){var t=i.getStart(),s=e.getBody(),l,c,u,d,f,p,h,m=-16777215,g,v,y,b,C;if(C=n.forced_root_block,t&&1===t.nodeType&&C){for(;t&&t!=s;){if(a[t.nodeName])return;t=t.parentNode}if(l=i.getRng(),l.setStart){c=l.startContainer,u=l.startOffset,d=l.endContainer,f=l.endOffset;try{v=e.getDoc().activeElement===s}catch(x){}}else l.item&&(t=l.item(0),l=e.getDoc().body.createTextRange(),l.moveToElementText(t)),v=l.parentElement().ownerDocument===e.getDoc(),y=l.duplicate(),y.collapse(!0),u=-1*y.move("character",m),y.collapsed||(y=l.duplicate(),y.collapse(!1),f=-1*y.move("character",m)-u);for(t=s.firstChild,b=s.nodeName.toLowerCase();t;)if((3===t.nodeType||1==t.nodeType&&!a[t.nodeName])&&o.isValidChild(b,C.toLowerCase())){if(3===t.nodeType&&0===t.nodeValue.length){h=t,t=t.nextSibling,r.remove(h);continue}p||(p=r.create(C,e.settings.forced_root_block_attrs),t.parentNode.insertBefore(p,t),g=!0),h=t,t=t.nextSibling,p.appendChild(h)}else p=null,t=t.nextSibling;if(g&&v){if(l.setStart)l.setStart(c,u),l.setEnd(d,f),i.setRng(l);else try{l=e.getDoc().body.createTextRange(),l.moveToElementText(s),l.collapse(!0),l.moveStart("character",u),f>0&&l.moveEnd("character",f),l.select()}catch(x){}e.nodeChanged()}}}var n=e.settings,r=e.dom,i=e.selection,o=e.schema,a=o.getBlockElements();n.forced_root_block&&e.on("NodeChange",t)}}),r(I,[S,g,p],function(e,n,r){var i=r.each,o=r.extend,a=r.map,s=r.inArray,l=r.explode,c=n.gecko,u=n.ie,d=!0,f=!1;return function(r){function p(e,t,n){var r;return e=e.toLowerCase(),(r=N.exec[e])?(r(e,t,n),d):f}function h(e){var t;return e=e.toLowerCase(),(t=N.state[e])?t(e):-1}function m(e){var t;return e=e.toLowerCase(),(t=N.value[e])?t(e):f}function g(e,t){t=t||"exec",i(e,function(e,n){i(n.toLowerCase().split(","),function(n){N[t][n]=e})})}function v(e,n,i){return n===t&&(n=f),i===t&&(i=null),r.getDoc().execCommand(e,n,i)}function y(e){return S.match(e)}function b(e,n){S.toggle(e,n?{value:n}:t),r.nodeChanged()}function C(e){k=_.getBookmark(e)}function x(){_.moveToBookmark(k)}var w=r.dom,_=r.selection,N={state:{},exec:{},value:{}},E=r.settings,S=r.formatter,k;o(this,{execCommand:p,queryCommandState:h,queryCommandValue:m,addCommands:g}),g({"mceResetDesignMode,mceBeginUndoLevel":function(){},"mceEndUndoLevel,mceAddUndoLevel":function(){r.undoManager.add()},"Cut,Copy,Paste":function(e){var t=r.getDoc(),i;try{v(e)}catch(o){i=d}if(i||!t.queryCommandSupported(e)){var a=r.translate("Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.");n.mac&&(a=a.replace(/Ctrl\+/g,"\u2318+")),r.windowManager.alert(a)}},unlink:function(){if(_.isCollapsed()){var e=_.getNode();return void("A"==e.tagName&&r.dom.remove(e,!0))}S.remove("link")},"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(e){var t=e.substring(7);"full"==t&&(t="justify"),i("left,center,right,justify".split(","),function(e){t!=e&&S.remove("align"+e)}),b("align"+t),p("mceRepaint")},"InsertUnorderedList,InsertOrderedList":function(e){var t,n;v(e),t=w.getParent(_.getNode(),"ol,ul"),t&&(n=t.parentNode,/^(H[1-6]|P|ADDRESS|PRE)$/.test(n.nodeName)&&(C(),w.split(n,t),x()))},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(e){b(e)},"ForeColor,HiliteColor,FontName":function(e,t,n){b(e,n)},FontSize:function(e,t,n){var r,i;n>=1&&7>=n&&(i=l(E.font_size_style_values),r=l(E.font_size_classes),n=r?r[n-1]||n:i[n-1]||n),b(e,n)},RemoveFormat:function(e){S.remove(e)},mceBlockQuote:function(){b("blockquote")},FormatBlock:function(e,t,n){return b(n||"p")},mceCleanup:function(){var e=_.getBookmark();r.setContent(r.getContent({cleanup:d}),{cleanup:d}),_.moveToBookmark(e)},mceRemoveNode:function(e,t,n){var i=n||_.getNode();i!=r.getBody()&&(C(),r.dom.remove(i,d),x())},mceSelectNodeDepth:function(e,t,n){var i=0;w.getParent(_.getNode(),function(e){return 1==e.nodeType&&i++==n?(_.select(e),f):void 0},r.getBody())},mceSelectNode:function(e,t,n){_.select(n)},mceInsertContent:function(t,n,i){function o(e){function t(e){return r[e]&&3==r[e].nodeType}var n,r,i;return n=_.getRng(!0),r=n.startContainer,i=n.startOffset,3==r.nodeType&&(i>0?e=e.replace(/^ /," "):t("previousSibling")||(e=e.replace(/^ /," ")),i|)$/," "):t("nextSibling")||(e=e.replace(/( | )(
    |)$/," "))),e}var a,s,l,c,d,f,p,h,m,g,v;/^ | $/.test(i)&&(i=o(i)),a=r.parser,s=new e({},r.schema),v='ÈB;',f={content:i,format:"html",selection:!0},r.fire("BeforeSetContent",f),i=f.content,-1==i.indexOf("{$caret}")&&(i+="{$caret}"),i=i.replace(/\{\$caret\}/,v),h=_.getRng();var y=h.startContainer||(h.parentElement?h.parentElement():null),b=r.getBody();y===b&&_.isCollapsed()&&w.isBlock(b.firstChild)&&w.isEmpty(b.firstChild)&&(h=w.createRng(),h.setStart(b.firstChild,0),h.setEnd(b.firstChild,0),_.setRng(h)),_.isCollapsed()||r.getDoc().execCommand("Delete",!1,null),l=_.getNode();var C={context:l.nodeName.toLowerCase()};if(d=a.parse(i,C),m=d.lastChild,"mce_marker"==m.attr("id"))for(p=m,m=m.prev;m;m=m.walk(!0))if(3==m.type||!w.isBlock(m.name)){m.parent.insert(p,m,"br"===m.name);break}if(C.invalid){for(_.setContent(v),l=_.getNode(),c=r.getBody(),9==l.nodeType?l=m=c:m=l;m!==c;)l=m,m=m.parentNode;i=l==c?c.innerHTML:w.getOuterHTML(l),i=s.serialize(a.parse(i.replace(//i,function(){return s.serialize(d)}))),l==c?w.setHTML(c,i):w.setOuterHTML(l,i)}else i=s.serialize(d),m=l.firstChild,g=l.lastChild,!m||m===g&&"BR"===m.nodeName?w.setHTML(l,i):_.setContent(i);p=w.get("mce_marker"),_.scrollIntoView(p),h=w.createRng(),m=p.previousSibling,m&&3==m.nodeType?(h.setStart(m,m.nodeValue.length),u||(g=p.nextSibling,g&&3==g.nodeType&&(m.appendData(g.data),g.parentNode.removeChild(g)))):(h.setStartBefore(p),h.setEndBefore(p)),w.remove(p),_.setRng(h),r.fire("SetContent",f),r.addVisual()},mceInsertRawHTML:function(e,t,n){_.setContent("tiny_mce_marker"),r.setContent(r.getContent().replace(/tiny_mce_marker/g,function(){return n}))},mceToggleFormat:function(e,t,n){b(n)},mceSetContent:function(e,t,n){r.setContent(n)},"Indent,Outdent":function(e){var t,n,o;t=E.indentation,n=/[a-z%]+$/i.exec(t),t=parseInt(t,10),h("InsertUnorderedList")||h("InsertOrderedList")?v(e):(E.forced_root_block||w.getParent(_.getNode(),w.isBlock)||S.apply("div"),i(_.getSelectedBlocks(),function(i){if("LI"!=i.nodeName){var a=r.getParam("indent_use_margin",!1)?"margin":"padding";a+="rtl"==w.getStyle(i,"direction",!0)?"Right":"Left","outdent"==e?(o=Math.max(0,parseInt(i.style[a]||0,10)-t),w.setStyle(i,a,o?o+n:"")):(o=parseInt(i.style[a]||0,10)+t+n,w.setStyle(i,a,o))}}))},mceRepaint:function(){if(c)try{C(d),_.getSel()&&_.getSel().selectAllChildren(r.getBody()),_.collapse(d),x()}catch(e){}},InsertHorizontalRule:function(){r.execCommand("mceInsertContent",!1,"
    ")},mceToggleVisualAid:function(){r.hasVisual=!r.hasVisual,r.addVisual()},mceReplaceContent:function(e,t,n){r.execCommand("mceInsertContent",!1,n.replace(/\{\$selection\}/g,_.getContent({format:"text"})))},mceInsertLink:function(e,t,n){var r;"string"==typeof n&&(n={href:n}),r=w.getParent(_.getNode(),"a"),n.href=n.href.replace(" ","%20"),r&&n.href||S.remove("link"),n.href&&S.apply("link",n,r)},selectAll:function(){var e=w.getRoot(),t;_.getRng().setStart?(t=w.createRng(),t.setStart(e,0),t.setEnd(e,e.childNodes.length),_.setRng(t)):(t=_.getRng(),t.item||(t.moveToElementText(e),t.select()))},"delete":function(){v("Delete");var e=r.getBody();w.isEmpty(e)&&(r.setContent(""),e.firstChild&&w.isBlock(e.firstChild)?r.selection.setCursorLocation(e.firstChild,0):r.selection.setCursorLocation(e,0))},mceNewDocument:function(){r.setContent("")}}),g({"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(e){var t="align"+e.substring(7),n=_.isCollapsed()?[w.getParent(_.getNode(),w.isBlock)]:_.getSelectedBlocks(),r=a(n,function(e){return!!S.matchNode(e,t)});return-1!==s(r,d)},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(e){return y(e)},mceBlockQuote:function(){return y("blockquote")},Outdent:function(){var e;if(E.inline_styles){if((e=w.getParent(_.getStart(),w.isBlock))&&parseInt(e.style.paddingLeft,10)>0)return d;if((e=w.getParent(_.getEnd(),w.isBlock))&&parseInt(e.style.paddingLeft,10)>0)return d +}return h("InsertUnorderedList")||h("InsertOrderedList")||!E.inline_styles&&!!w.getParent(_.getNode(),"BLOCKQUOTE")},"InsertUnorderedList,InsertOrderedList":function(e){var t=w.getParent(_.getNode(),"ul,ol");return t&&("insertunorderedlist"===e&&"UL"===t.tagName||"insertorderedlist"===e&&"OL"===t.tagName)}},"state"),g({"FontSize,FontName":function(e){var t=0,n;return(n=w.getParent(_.getNode(),"span"))&&(t="fontsize"==e?n.style.fontSize:n.style.fontFamily.replace(/, /g,",").replace(/[\'\"]/g,"").toLowerCase()),t}},"value"),g({Undo:function(){r.undoManager.undo()},Redo:function(){r.undoManager.redo()}})}}),r(F,[p],function(e){function t(e,i){var o=this,a,s;if(e=r(e),i=o.settings=i||{},/^([\w\-]+):([^\/]{2})/i.test(e)||/^\s*#/.test(e))return void(o.source=e);var l=0===e.indexOf("//");0!==e.indexOf("/")||l||(e=(i.base_uri?i.base_uri.protocol||"http":"http")+"://mce_host"+e),/^[\w\-]*:?\/\//.test(e)||(s=i.base_uri?i.base_uri.path:new t(location.href).directory,e=""===i.base_uri.protocol?"//mce_host"+o.toAbsPath(s,e):(i.base_uri&&i.base_uri.protocol||"http")+"://mce_host"+o.toAbsPath(s,e)),e=e.replace(/@@/g,"(mce_at)"),e=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(e),n(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],function(t,n){var r=e[n];r&&(r=r.replace(/\(mce_at\)/g,"@@")),o[t]=r}),a=i.base_uri,a&&(o.protocol||(o.protocol=a.protocol),o.userInfo||(o.userInfo=a.userInfo),o.port||"mce_host"!==o.host||(o.port=a.port),o.host&&"mce_host"!==o.host||(o.host=a.host),o.source=""),l&&(o.protocol="")}var n=e.each,r=e.trim,i={ftp:21,http:80,https:443,mailto:25};return t.prototype={setPath:function(e){var t=this;e=/^(.*?)\/?(\w+)?$/.exec(e),t.path=e[0],t.directory=e[1],t.file=e[2],t.source="",t.getURI()},toRelative:function(e){var n=this,r;if("./"===e)return e;if(e=new t(e,{base_uri:n}),"mce_host"!=e.host&&n.host!=e.host&&e.host||n.port!=e.port||n.protocol!=e.protocol&&""!==e.protocol)return e.getURI();var i=n.getURI(),o=e.getURI();return i==o||"/"==i.charAt(i.length-1)&&i.substr(0,i.length-1)==o?i:(r=n.toRelPath(n.path,e.path),e.query&&(r+="?"+e.query),e.anchor&&(r+="#"+e.anchor),r)},toAbsolute:function(e,n){return e=new t(e,{base_uri:this}),e.getURI(n&&this.isSameOrigin(e))},isSameOrigin:function(e){if(this.host==e.host&&this.protocol==e.protocol){if(this.port==e.port)return!0;var t=i[this.protocol];if(t&&(this.port||t)==(e.port||t))return!0}return!1},toRelPath:function(e,t){var n,r=0,i="",o,a;if(e=e.substring(0,e.lastIndexOf("/")),e=e.split("/"),n=t.split("/"),e.length>=n.length)for(o=0,a=e.length;a>o;o++)if(o>=n.length||e[o]!=n[o]){r=o+1;break}if(e.lengtho;o++)if(o>=e.length||e[o]!=n[o]){r=o+1;break}if(1===r)return t;for(o=0,a=e.length-(r-1);a>o;o++)i+="../";for(o=r-1,a=n.length;a>o;o++)i+=o!=r-1?"/"+n[o]:n[o];return i},toAbsPath:function(e,t){var r,i=0,o=[],a,s;for(a=/\/$/.test(t)?"/":"",e=e.split("/"),t=t.split("/"),n(e,function(e){e&&o.push(e)}),e=o,r=t.length-1,o=[];r>=0;r--)0!==t[r].length&&"."!==t[r]&&(".."!==t[r]?i>0?i--:o.push(t[r]):i++);return r=e.length-i,s=0>=r?o.reverse().join("/"):e.slice(0,r).join("/")+"/"+o.reverse().join("/"),0!==s.indexOf("/")&&(s="/"+s),a&&s.lastIndexOf("/")!==s.length-1&&(s+=a),s},getURI:function(e){var t,n=this;return(!n.source||e)&&(t="",e||(t+=n.protocol?n.protocol+"://":"//",n.userInfo&&(t+=n.userInfo+"@"),n.host&&(t+=n.host),n.port&&(t+=":"+n.port)),n.path&&(t+=n.path),n.query&&(t+="?"+n.query),n.anchor&&(t+="#"+n.anchor),n.source=t),n.source}},t}),r(z,[p],function(e){function t(){}var n=e.each,r=e.extend,i,o;return t.extend=i=function(e){function t(){var e,t,n,r=this;if(!o&&(r.init&&r.init.apply(r,arguments),t=r.Mixins))for(e=t.length;e--;)n=t[e],n.init&&n.init.apply(r,arguments)}function a(){return this}function s(e,t){return function(){var n=this,r=n._super,i;return n._super=c[e],i=t.apply(n,arguments),n._super=r,i}}var l=this,c=l.prototype,u,d,f;o=!0,u=new l,o=!1,e.Mixins&&(n(e.Mixins,function(t){t=t;for(var n in t)"init"!==n&&(e[n]=t[n])}),c.Mixins&&(e.Mixins=c.Mixins.concat(e.Mixins))),e.Methods&&n(e.Methods.split(","),function(t){e[t]=a}),e.Properties&&n(e.Properties.split(","),function(t){var n="_"+t;e[t]=function(e){var t=this,r;return e!==r?(t[n]=e,t):t[n]}}),e.Statics&&n(e.Statics,function(e,n){t[n]=e}),e.Defaults&&c.Defaults&&(e.Defaults=r({},c.Defaults,e.Defaults));for(d in e)f=e[d],u[d]="function"==typeof f&&c[d]?s(d,f):f;return t.prototype=u,t.constructor=t,t.extend=i,t},t}),r(W,[p],function(e){function t(e){function t(){return!1}function n(){return!0}function r(r,i){var o,a,s,u;if(r=r.toLowerCase(),i=i||{},i.type=r,i.target||(i.target=l),i.preventDefault||(i.preventDefault=function(){i.isDefaultPrevented=n},i.stopPropagation=function(){i.isPropagationStopped=n},i.stopImmediatePropagation=function(){i.isImmediatePropagationStopped=n},i.isDefaultPrevented=t,i.isPropagationStopped=t,i.isImmediatePropagationStopped=t),e.beforeFire&&e.beforeFire(i),o=c[r])for(a=0,s=o.length;s>a;a++){if(o[a]=u=o[a],i.isImmediatePropagationStopped())return i.stopPropagation(),i;if(u.call(l,i)===!1)return i.preventDefault(),i}return i}function i(e,n,r){var i,o,a;if(n===!1&&(n=t),n)for(o=e.toLowerCase().split(" "),a=o.length;a--;)e=o[a],i=c[e],i||(i=c[e]=[],u(e,!0)),r?i.unshift(n):i.push(n);return s}function o(e,t){var n,r,i,o,a;if(e)for(o=e.toLowerCase().split(" "),n=o.length;n--;){if(e=o[n],r=c[e],!e){for(i in c)u(i,!1),delete c[i];return s}if(r){if(t)for(a=r.length;a--;)r[a]===t&&r.splice(a,1);else r.length=0;r.length||(u(e,!1),delete c[e])}}else{for(e in c)u(e,!1);c={}}return s}function a(e){return e=e.toLowerCase(),!(!c[e]||0===c[e].length)}var s=this,l,c={},u;e=e||{},l=e.scope||s,u=e.toggleEvent||t,s.fire=r,s.on=i,s.off=o,s.has=a}var n=e.makeMap("focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange mouseout mouseenter mouseleave wheel keydown keypress keyup input contextmenu dragstart dragend dragover draggesture dragdrop drop drag submit"," ");return t.isNative=function(e){return!!n[e.toLowerCase()]},t}),r(V,[z],function(e){function t(e){for(var t=[],n=e.length,r;n--;)r=e[n],r.__checked||(t.push(r),r.__checked=1);for(n=t.length;n--;)delete t[n].__checked;return t}var n=/^([\w\\*]+)?(?:#([\w\\]+))?(?:\.([\w\\\.]+))?(?:\[\@?([\w\\]+)([\^\$\*!~]?=)([\w\\]+)\])?(?:\:(.+))?/i,r=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,i=/^\s*|\s*$/g,o,a=e.extend({init:function(e){function t(e){return e?(e=e.toLowerCase(),function(t){return"*"===e||t.type===e}):void 0}function o(e){return e?function(t){return t._name===e}:void 0}function a(e){return e?(e=e.split("."),function(t){for(var n=e.length;n--;)if(!t.hasClass(e[n]))return!1;return!0}):void 0}function s(e,t,n){return e?function(r){var i=r[e]?r[e]():"";return t?"="===t?i===n:"*="===t?i.indexOf(n)>=0:"~="===t?(" "+i+" ").indexOf(" "+n+" ")>=0:"!="===t?i!=n:"^="===t?0===i.indexOf(n):"$="===t?i.substr(i.length-n.length)===n:!1:!!n}:void 0}function l(e){var t;return e?(e=/(?:not\((.+)\))|(.+)/i.exec(e),e[1]?(t=u(e[1],[]),function(e){return!d(e,t)}):(e=e[2],function(t,n,r){return"first"===e?0===n:"last"===e?n===r-1:"even"===e?n%2===0:"odd"===e?n%2===1:t[e]?t[e]():!1})):void 0}function c(e,r,c){function u(e){e&&r.push(e)}var d;return d=n.exec(e.replace(i,"")),u(t(d[1])),u(o(d[2])),u(a(d[3])),u(s(d[4],d[5],d[6])),u(l(d[7])),r.psuedo=!!d[7],r.direct=c,r}function u(e,t){var n=[],i,o,a;do if(r.exec(""),o=r.exec(e),o&&(e=o[3],n.push(o[1]),o[2])){i=o[3];break}while(o);for(i&&u(i,t),e=[],a=0;a"!=n[a]&&e.push(c(n[a],[],">"===n[a-1]));return t.push(e),t}var d=this.match;this._selectors=u(e,[])},match:function(e,t){var n,r,i,o,a,s,l,c,u,d,f,p,h;for(t=t||this._selectors,n=0,r=t.length;r>n;n++){for(a=t[n],o=a.length,h=e,p=0,i=o-1;i>=0;i--)for(c=a[i];h;){if(c.psuedo)for(f=h.parent().items(),u=d=f.length;u--&&f[u]!==h;);for(s=0,l=c.length;l>s;s++)if(!c[s](h,u,d)){s=l+1;break}if(s===l){p++;break}if(i===o-1)break;h=h.parent()}if(p===o)return!0}return!1},find:function(e){function n(e,t,i){var o,a,s,l,c,u=t[i];for(o=0,a=e.length;a>o;o++){for(c=e[o],s=0,l=u.length;l>s;s++)if(!u[s](c,o,a)){s=l+1;break}if(s===l)i==t.length-1?r.push(c):c.items&&n(c.items(),t,i+1);else if(u.direct)return;c.items&&n(c.items(),t,i)}}var r=[],i,s,l=this._selectors;if(e.items){for(i=0,s=l.length;s>i;i++)n(e.items(),l[i],0);s>1&&(r=t(r))}return o||(o=a.Collection),new o(r)}});return a}),r(U,[p,V,z],function(e,t,n){var r,i,o=Array.prototype.push,a=Array.prototype.slice;return i={length:0,init:function(e){e&&this.add(e)},add:function(t){var n=this;return e.isArray(t)?o.apply(n,t):t instanceof r?n.add(t.toArray()):o.call(n,t),n},set:function(e){var t=this,n=t.length,r;for(t.length=0,t.add(e),r=t.length;n>r;r++)delete t[r];return t},filter:function(e){var n=this,i,o,a=[],s,l;for("string"==typeof e?(e=new t(e),l=function(t){return e.match(t)}):l=e,i=0,o=n.length;o>i;i++)s=n[i],l(s)&&a.push(s);return new r(a)},slice:function(){return new r(a.apply(this,arguments))},eq:function(e){return-1===e?this.slice(e):this.slice(e,+e+1)},each:function(t){return e.each(this,t),this},toArray:function(){return e.toArray(this)},indexOf:function(e){for(var t=this,n=t.length;n--&&t[n]!==e;);return n},reverse:function(){return new r(e.toArray(this).reverse())},hasClass:function(e){return this[0]?this[0].hasClass(e):!1},prop:function(e,t){var n=this,r,i;return t!==r?(n.each(function(n){n[e]&&n[e](t)}),n):(i=n[0],i&&i[e]?i[e]():void 0)},exec:function(t){var n=this,r=e.toArray(arguments).slice(1);return n.each(function(e){e[t]&&e[t].apply(e,r)}),n},remove:function(){for(var e=this.length;e--;)this[e].remove();return this}},e.each("fire on off show hide addClass removeClass append prepend before after reflow".split(" "),function(t){i[t]=function(){var n=e.toArray(arguments);return this.each(function(e){t in e&&e[t].apply(e,n)}),this}}),e.each("text name disabled active selected checked visible parent value data".split(" "),function(e){i[e]=function(t){return this.prop(e,t)}}),r=n.extend(i),t.Collection=r,r}),r(q,[p,y],function(e,t){return{id:function(){return t.DOM.uniqueId()},createFragment:function(e){return t.DOM.createFragment(e)},getWindowSize:function(){return t.DOM.getViewPort()},getSize:function(e){var t,n;if(e.getBoundingClientRect){var r=e.getBoundingClientRect();t=Math.max(r.width||r.right-r.left,e.offsetWidth),n=Math.max(r.height||r.bottom-r.bottom,e.offsetHeight)}else t=e.offsetWidth,n=e.offsetHeight;return{width:t,height:n}},getPos:function(e,n){return t.DOM.getPos(e,n)},getViewPort:function(e){return t.DOM.getViewPort(e)},get:function(e){return document.getElementById(e)},addClass:function(e,n){return t.DOM.addClass(e,n)},removeClass:function(e,n){return t.DOM.removeClass(e,n)},hasClass:function(e,n){return t.DOM.hasClass(e,n)},toggleClass:function(e,n,r){return t.DOM.toggleClass(e,n,r)},css:function(e,n,r){return t.DOM.setStyle(e,n,r)},on:function(e,n,r,i){return t.DOM.bind(e,n,r,i)},off:function(e,n,r){return t.DOM.unbind(e,n,r)},fire:function(e,n,r){return t.DOM.fire(e,n,r)},innerHtml:function(e,n){t.DOM.setHTML(e,n)}}}),r($,[z,p,W,U,q],function(e,t,n,r,i){function o(e){return e._eventDispatcher||(e._eventDispatcher=new n({scope:e,toggleEvent:function(t,r){r&&n.isNative(t)&&(e._nativeEvents||(e._nativeEvents={}),e._nativeEvents[t]=!0,e._rendered&&e.bindPendingEvents())}})),e._eventDispatcher}var a={},s="onmousewheel"in document,l=!1,c="mce-",u=e.extend({Statics:{elementIdCache:a,classPrefix:c},isRtl:function(){return u.rtl},classPrefix:c,init:function(e){var n=this,r,o;if(n.settings=e=t.extend({},n.Defaults,e),n._id=e.id||i.id(),n._text=n._name="",n._width=n._height=0,n._aria={role:e.role},r=e.classes)for(r=r.split(" "),r.map={},o=r.length;o--;)r.map[r[o]]=!0;n._classes=r||[],n.visible(!0),t.each("title text width height name classes visible disabled active value".split(" "),function(t){var r=e[t],i;r!==i?n[t](r):n["_"+t]===i&&(n["_"+t]=!1)}),n.on("click",function(){return n.disabled()?!1:void 0}),e.classes&&t.each(e.classes.split(" "),function(e){n.addClass(e)}),n.settings=e,n._borderBox=n.parseBox(e.border),n._paddingBox=n.parseBox(e.padding),n._marginBox=n.parseBox(e.margin),e.hidden&&n.hide()},Properties:"parent,title,text,width,height,disabled,active,name,value",Methods:"renderHtml",getContainerElm:function(){return document.body},getParentCtrl:function(e){for(var t,n=this.getRoot().controlIdLookup;e&&n&&!(t=n[e.id]);)e=e.parentNode;return t},parseBox:function(e){var t,n=10;if(e)return"number"==typeof e?(e=e||0,{top:e,left:e,bottom:e,right:e}):(e=e.split(" "),t=e.length,1===t?e[1]=e[2]=e[3]=e[0]:2===t?(e[2]=e[0],e[3]=e[1]):3===t&&(e[3]=e[1]),{top:parseInt(e[0],n)||0,right:parseInt(e[1],n)||0,bottom:parseInt(e[2],n)||0,left:parseInt(e[3],n)||0})},borderBox:function(){return this._borderBox},paddingBox:function(){return this._paddingBox},marginBox:function(){return this._marginBox},measureBox:function(e,t){function n(t){var n=document.defaultView;return n?(t=t.replace(/[A-Z]/g,function(e){return"-"+e}),n.getComputedStyle(e,null).getPropertyValue(t)):e.currentStyle[t]}function r(e){var t=parseFloat(n(e),10);return isNaN(t)?0:t}return{top:r(t+"TopWidth"),right:r(t+"RightWidth"),bottom:r(t+"BottomWidth"),left:r(t+"LeftWidth")}},initLayoutRect:function(){var e=this,t=e.settings,n,r,o=e.getEl(),a,s,l,c,u,d,f,p;n=e._borderBox=e._borderBox||e.measureBox(o,"border"),e._paddingBox=e._paddingBox||e.measureBox(o,"padding"),e._marginBox=e._marginBox||e.measureBox(o,"margin"),p=i.getSize(o),d=t.minWidth,f=t.minHeight,l=d||p.width,c=f||p.height,a=t.width,s=t.height,u=t.autoResize,u="undefined"!=typeof u?u:!a&&!s,a=a||l,s=s||c;var h=n.left+n.right,m=n.top+n.bottom,g=t.maxWidth||65535,v=t.maxHeight||65535;return e._layoutRect=r={x:t.x||0,y:t.y||0,w:a,h:s,deltaW:h,deltaH:m,contentW:a-h,contentH:s-m,innerW:a-h,innerH:s-m,startMinWidth:d||0,startMinHeight:f||0,minW:Math.min(l,g),minH:Math.min(c,v),maxW:g,maxH:v,autoResize:u,scrollW:0},e._lastLayoutRect={},r},layoutRect:function(e){var t=this,n=t._layoutRect,r,i,o,a,s,l;return n||(n=t.initLayoutRect()),e?(o=n.deltaW,a=n.deltaH,e.x!==s&&(n.x=e.x),e.y!==s&&(n.y=e.y),e.minW!==s&&(n.minW=e.minW),e.minH!==s&&(n.minH=e.minH),i=e.w,i!==s&&(i=in.maxW?n.maxW:i,n.w=i,n.innerW=i-o),i=e.h,i!==s&&(i=in.maxH?n.maxH:i,n.h=i,n.innerH=i-a),i=e.innerW,i!==s&&(i=in.maxW-o?n.maxW-o:i,n.innerW=i,n.w=i+o),i=e.innerH,i!==s&&(i=in.maxH-a?n.maxH-a:i,n.innerH=i,n.h=i+a),e.contentW!==s&&(n.contentW=e.contentW),e.contentH!==s&&(n.contentH=e.contentH),r=t._lastLayoutRect,(r.x!==n.x||r.y!==n.y||r.w!==n.w||r.h!==n.h)&&(l=u.repaintControls,l&&l.map&&!l.map[t._id]&&(l.push(t),l.map[t._id]=!0),r.x=n.x,r.y=n.y,r.w=n.w,r.h=n.h),t):n},repaint:function(){var e=this,t,n,r,i,o=0,a=0,s,l;l=document.createRange?function(e){return e}:Math.round,t=e.getEl().style,r=e._layoutRect,s=e._lastRepaintRect||{},i=e._borderBox,o=i.left+i.right,a=i.top+i.bottom,r.x!==s.x&&(t.left=l(r.x)+"px",s.x=r.x),r.y!==s.y&&(t.top=l(r.y)+"px",s.y=r.y),r.w!==s.w&&(t.width=l(r.w-o)+"px",s.w=r.w),r.h!==s.h&&(t.height=l(r.h-a)+"px",s.h=r.h),e._hasBody&&r.innerW!==s.innerW&&(n=e.getEl("body").style,n.width=l(r.innerW)+"px",s.innerW=r.innerW),e._hasBody&&r.innerH!==s.innerH&&(n=n||e.getEl("body").style,n.height=l(r.innerH)+"px",s.innerH=r.innerH),e._lastRepaintRect=s,e.fire("repaint",{},!1)},on:function(e,t){function n(e){var t,n;return"string"!=typeof e?e:function(i){return t||r.parentsAndSelf().each(function(r){var i=r.settings.callbacks;return i&&(t=i[e])?(n=r,!1):void 0}),t.call(n,i)}}var r=this;return o(r).on(e,n(t)),r},off:function(e,t){return o(this).off(e,t),this},fire:function(e,t,n){var r=this;if(t=t||{},t.control||(t.control=r),t=o(r).fire(e,t),n!==!1&&r.parent)for(var i=r.parent();i&&!t.isPropagationStopped();)i.fire(e,t,!1),i=i.parent();return t},hasEventListeners:function(e){return o(this).has(e)},parents:function(e){var t=this,n,i=new r;for(n=t.parent();n;n=n.parent())i.add(n);return e&&(i=i.filter(e)),i},parentsAndSelf:function(e){return new r(this).add(this.parents(e))},next:function(){var e=this.parent().items();return e[e.indexOf(this)+1]},prev:function(){var e=this.parent().items();return e[e.indexOf(this)-1]},findCommonAncestor:function(e,t){for(var n;e;){for(n=t;n&&e!=n;)n=n.parent();if(e==n)break;e=e.parent()}return e},hasClass:function(e,t){var n=this._classes[t||"control"];return e=this.classPrefix+e,n&&!!n.map[e]},addClass:function(e,t){var n=this,r,i;return e=this.classPrefix+e,r=n._classes[t||"control"],r||(r=[],r.map={},n._classes[t||"control"]=r),r.map[e]||(r.map[e]=e,r.push(e),n._rendered&&(i=n.getEl(t),i&&(i.className=r.join(" ")))),n},removeClass:function(e,t){var n=this,r,i,o;if(e=this.classPrefix+e,r=n._classes[t||"control"],r&&r.map[e])for(delete r.map[e],i=r.length;i--;)r[i]===e&&r.splice(i,1);return n._rendered&&(o=n.getEl(t),o&&(o.className=r.join(" "))),n},toggleClass:function(e,t,n){var r=this;return t?r.addClass(e,n):r.removeClass(e,n),r},classes:function(e){var t=this._classes[e||"control"];return t?t.join(" "):""},innerHtml:function(e){return i.innerHtml(this.getEl(),e),this},getEl:function(e,t){var n,r=e?this._id+"-"+e:this._id;return n=a[r]=(t===!0?null:a[r])||i.get(r)},visible:function(e){var t=this,n;return"undefined"!=typeof e?(t._visible!==e&&(t._rendered&&(t.getEl().style.display=e?"":"none"),t._visible=e,n=t.parent(),n&&(n._lastRect=null),t.fire(e?"show":"hide")),t):t._visible},show:function(){return this.visible(!0)},hide:function(){return this.visible(!1)},focus:function(){try{this.getEl().focus()}catch(e){}return this},blur:function(){return this.getEl().blur(),this},aria:function(e,t){var n=this,r=n.getEl(n.ariaTarget);return"undefined"==typeof t?n._aria[e]:(n._aria[e]=t,n._rendered&&r.setAttribute("role"==e?e:"aria-"+e,t),n)},encode:function(e,t){return t!==!1&&(e=this.translate(e)),(e||"").replace(/[&<>"]/g,function(e){return"&#"+e.charCodeAt(0)+";"})},translate:function(e){return u.translate?u.translate(e):e},before:function(e){var t=this,n=t.parent();return n&&n.insert(e,n.items().indexOf(t),!0),t},after:function(e){var t=this,n=t.parent();return n&&n.insert(e,n.items().indexOf(t)),t},remove:function(){var e=this,t=e.getEl(),n=e.parent(),r,o;if(e.items){var s=e.items().toArray();for(o=s.length;o--;)s[o].remove()}n&&n.items&&(r=[],n.items().each(function(t){t!==e&&r.push(t)}),n.items().set(r),n._lastRect=null),e._eventsRoot&&e._eventsRoot==e&&i.off(t);var l=e.getRoot().controlIdLookup;if(l&&delete l[e._id],delete a[e._id],t&&t.parentNode){var c=t.getElementsByTagName("*");for(o=c.length;o--;)delete a[c[o].id];t.parentNode.removeChild(t)}return e._rendered=!1,e},renderBefore:function(e){var t=this;return e.parentNode.insertBefore(i.createFragment(t.renderHtml()),e),t.postRender(),t},renderTo:function(e){var t=this;return e=e||t.getContainerElm(),e.appendChild(i.createFragment(t.renderHtml())),t.postRender(),t},postRender:function(){var e=this,t=e.settings,n,r,o,a,s;for(a in t)0===a.indexOf("on")&&e.on(a.substr(2),t[a]);if(e._eventsRoot){for(o=e.parent();!s&&o;o=o.parent())s=o._eventsRoot;if(s)for(a in s._nativeEvents)e._nativeEvents[a]=!0}e.bindPendingEvents(),t.style&&(n=e.getEl(),n&&(n.setAttribute("style",t.style),n.style.cssText=t.style)),e._visible||i.css(e.getEl(),"display","none"),e.settings.border&&(r=e.borderBox(),i.css(e.getEl(),{"border-top-width":r.top,"border-right-width":r.right,"border-bottom-width":r.bottom,"border-left-width":r.left}));var l=e.getRoot();l.controlIdLookup||(l.controlIdLookup={}),l.controlIdLookup[e._id]=e;for(var c in e._aria)e.aria(c,e._aria[c]);e.fire("postrender",{},!1)},scrollIntoView:function(e){function t(e,t){var n,r,i=e;for(n=r=0;i&&i!=t&&i.nodeType;)n+=i.offsetLeft||0,r+=i.offsetTop||0,i=i.offsetParent;return{x:n,y:r}}var n=this.getEl(),r=n.parentNode,i,o,a,s,l,c,u=t(n,r);return i=u.x,o=u.y,a=n.offsetWidth,s=n.offsetHeight,l=r.clientWidth,c=r.clientHeight,"end"==e?(i-=l-a,o-=c-s):"center"==e&&(i-=l/2-a/2,o-=c/2-s/2),r.scrollLeft=i,r.scrollTop=o,this},bindPendingEvents:function(){function e(e){var t=o.getParentCtrl(e.target);t&&t.fire(e.type,e)}function t(){var e=d._lastHoverCtrl;e&&(e.fire("mouseleave",{target:e.getEl()}),e.parents().each(function(e){e.fire("mouseleave",{target:e.getEl()})}),d._lastHoverCtrl=null)}function n(e){var t=o.getParentCtrl(e.target),n=d._lastHoverCtrl,r=0,i,a,s;if(t!==n){if(d._lastHoverCtrl=t,a=t.parents().toArray().reverse(),a.push(t),n){for(s=n.parents().toArray().reverse(),s.push(n),r=0;r=r;i--)n=s[i],n.fire("mouseleave",{target:n.getEl()})}for(i=r;ia;a++)d=u[a]._eventsRoot;for(d||(d=u[u.length-1]||o),o._eventsRoot=d,c=a,a=0;c>a;a++)u[a]._eventsRoot=d;var h=d._delegates;h||(h=d._delegates={});for(p in f){if(!f)return!1;"wheel"!==p||l?("mouseenter"===p||"mouseleave"===p?d._hasMouseEnter||(i.on(d.getEl(),"mouseleave",t),i.on(d.getEl(),"mouseover",n),d._hasMouseEnter=1):h[p]||(i.on(d.getEl(),p,e),h[p]=!0),f[p]=!1):s?i.on(o.getEl(),"mousewheel",r):i.on(o.getEl(),"DOMMouseScroll",r)}}},getRoot:function(){for(var e=this,t,n=[];e;){if(e.rootControl){t=e.rootControl;break}n.push(e),t=e,e=e.parent()}t||(t=this);for(var r=n.length;r--;)n[r].rootControl=t;return t},reflow:function(){return this.repaint(),this}});return u}),r(j,[],function(){var e={},t;return{add:function(t,n){e[t.toLowerCase()]=n},has:function(t){return!!e[t.toLowerCase()]},create:function(n,r){var i,o,a;if(!t){a=tinymce.ui;for(o in a)e[o.toLowerCase()]=a[o];t=!0}if("string"==typeof n?(r=r||{},r.type=n):(r=n,n=r.type),n=n.toLowerCase(),i=e[n],!i)throw new Error("Could not find control by type: "+n);return i=new i(r),i.type=n,i}}}),r(K,[],function(){return function(e){function t(e){return e=e||b,e&&e.getAttribute("role")}function n(e){for(var n,r=e||b;r=r.parentNode;)if(n=t(r))return n}function r(e){var t=b;return t?t.getAttribute("aria-"+e):void 0}function i(e){var t=e.tagName.toUpperCase();return"INPUT"==t||"TEXTAREA"==t}function o(e){return i(e)&&!e.hidden?!0:/^(button|menuitem|checkbox|tab|menuitemcheckbox|option|gridcell)$/.test(t(e))?!0:!1}function a(e){function t(e){if(1==e.nodeType&&"none"!=e.style.display){o(e)&&n.push(e);for(var r=0;re?e=t.length-1:e>=t.length&&(e=0),t[e]&&t[e].focus(),e}function u(e,t){var n=-1,r=s();t=t||a(r.getEl());for(var i=0;i=0&&(n=t.getEl(),n&&n.parentNode.removeChild(n),n=e.getEl(),n&&n.parentNode.removeChild(n)),t.parent(this)},create:function(t){var n=this,i,a=[];return o.isArray(t)||(t=[t]),o.each(t,function(t){t&&(t instanceof e||("string"==typeof t&&(t={type:t}),i=o.extend({},n.settings.defaults,t),t.type=i.type=i.type||t.type||n.settings.defaultType||(i.defaults?i.defaults.type:null),t=r.create(i)),a.push(t))}),a},renderNew:function(){var e=this;return e.items().each(function(t,n){var r,i;t.parent(e),t._rendered||(r=e.getEl("body"),i=a.createFragment(t.renderHtml()),r.hasChildNodes()&&n<=r.childNodes.length-1?r.insertBefore(i,r.childNodes[n]):r.appendChild(i),t.postRender())}),e._layout.applyClasses(e),e._lastRect=null,e},append:function(e){return this.add(e).renderNew()},prepend:function(e){var t=this;return t.items().set(t.create(e).concat(t.items().toArray())),t.renderNew()},insert:function(e,t,n){var r=this,i,o,a;return e=r.create(e),i=r.items(),!n&&t=0&&t
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "},postRender:function(){var e=this,t;return e.items().exec("postRender"),e._super(),e._layout.postRender(e),e._rendered=!0,e.settings.style&&a.css(e.getEl(),e.settings.style),e.settings.border&&(t=e.borderBox(),a.css(e.getEl(),{"border-top-width":t.top,"border-right-width":t.right,"border-bottom-width":t.bottom,"border-left-width":t.left})),e.parent()||(e.keyboardNav=new i({root:e})),e},initLayoutRect:function(){var e=this,t=e._super();return e._layout.recalc(e),t},recalc:function(){var e=this,t=e._layoutRect,n=e._lastRect;return n&&n.w==t.w&&n.h==t.h?void 0:(e._layout.recalc(e),t=e.layoutRect(),e._lastRect={x:t.x,y:t.y,w:t.w,h:t.h},!0)},reflow:function(){var t;if(this.visible()){for(e.repaintControls=[],e.repaintControls.map={},this.recalc(),t=e.repaintControls.length;t--;)e.repaintControls[t].repaint();"flow"!==this.settings.layout&&"stack"!==this.settings.layout&&this.repaint(),e.repaintControls=[]}return this}})}),r(Y,[q],function(e){function t(){var e=document,t,n,r,i,o,a,s,l,c=Math.max;return t=e.documentElement,n=e.body,r=c(t.scrollWidth,n.scrollWidth),i=c(t.clientWidth,n.clientWidth),o=c(t.offsetWidth,n.offsetWidth),a=c(t.scrollHeight,n.scrollHeight),s=c(t.clientHeight,n.clientHeight),l=c(t.offsetHeight,n.offsetHeight),{width:o>r?i:r,height:l>a?s:a}}return function(n,r){function i(){return a.getElementById(r.handle||n)}var o,a=document,s,l,c,u,d,f;r=r||{},l=function(n){var l=t(),p,h;n.preventDefault(),s=n.button,p=i(),d=n.screenX,f=n.screenY,h=window.getComputedStyle?window.getComputedStyle(p,null).getPropertyValue("cursor"):p.runtimeStyle.cursor,o=a.createElement("div"),e.css(o,{position:"absolute",top:0,left:0,width:l.width,height:l.height,zIndex:2147483647,opacity:1e-4,background:"red",cursor:h}),a.body.appendChild(o),e.on(a,"mousemove",u),e.on(a,"mouseup",c),r.start(n)},u=function(e){return e.button!==s?c(e):(e.deltaX=e.screenX-d,e.deltaY=e.screenY-f,e.preventDefault(),void r.drag(e))},c=function(t){e.off(a,"mousemove",u),e.off(a,"mouseup",c),o.parentNode.removeChild(o),r.stop&&r.stop(t)},this.destroy=function(){e.off(i())},e.on(i(),"mousedown",l)}}),r(X,[q,Y],function(e,t){return{init:function(){var e=this;e.on("repaint",e.renderScroll)},renderScroll:function(){function n(){function t(t,a,s,l,c,u){var d,f,p,h,m,g,v,y,b;if(f=i.getEl("scroll"+t)){if(y=a.toLowerCase(),b=s.toLowerCase(),i.getEl("absend")&&e.css(i.getEl("absend"),y,i.layoutRect()[l]-1),!c)return void e.css(f,"display","none");e.css(f,"display","block"),d=i.getEl("body"),p=i.getEl("scroll"+t+"t"),h=d["client"+s]-2*o,h-=n&&r?f["client"+u]:0,m=d["scroll"+s],g=h/m,v={},v[y]=d["offset"+a]+o,v[b]=h,e.css(f,v),v={},v[y]=d["scroll"+a]*g,v[b]=h*g,e.css(p,v)}}var n,r,a;a=i.getEl("body"),n=a.scrollWidth>a.clientWidth,r=a.scrollHeight>a.clientHeight,t("h","Left","Width","contentW",n,"Height"),t("v","Top","Height","contentH",r,"Width")}function r(){function n(n,r,a,s,l){var c,u=i._id+"-scroll"+n,d=i.classPrefix;i.getEl().appendChild(e.createFragment('
    ')),i.draghelper=new t(u+"t",{start:function(){c=i.getEl("body")["scroll"+r],e.addClass(e.get(u),d+"active")},drag:function(e){var t,u,d,f,p=i.layoutRect();u=p.contentW>p.innerW,d=p.contentH>p.innerH,f=i.getEl("body")["client"+a]-2*o,f-=u&&d?i.getEl("scroll"+n)["client"+l]:0,t=f/i.getEl("body")["scroll"+a],i.getEl("body")["scroll"+r]=c+e["delta"+s]/t},stop:function(){e.removeClass(e.get(u),d+"active")}})}i.addClass("scroll"),n("v","Top","Height","Y","Width"),n("h","Left","Width","X","Height")}var i=this,o=2;i.settings.autoScroll&&(i._hasScroll||(i._hasScroll=!0,r(),i.on("wheel",function(e){var t=i.getEl("body");t.scrollLeft+=10*(e.deltaX||0),t.scrollTop+=10*e.deltaY,n()}),e.on(i.getEl("body"),"scroll",n)),n())}}}),r(J,[G,X],function(e,t){return e.extend({Defaults:{layout:"fit",containerCls:"panel"},Mixins:[t],renderHtml:function(){var e=this,t=e._layout,n=e.settings.html;return e.preRender(),t.preRender(e),"undefined"==typeof n?n='
    '+t.renderHtml(e)+"
    ":("function"==typeof n&&(n=n.call(e)),e._hasBody=!1),'
    '+(e._preBodyHtml||"")+n+"
    "}})}),r(Q,[q],function(e){function t(t,n,r){var i,o,a,s,l,c,u,d,f,p;return f=e.getViewPort(),o=e.getPos(n),a=o.x,s=o.y,t._fixed&&(a-=f.x,s-=f.y),i=t.getEl(),p=e.getSize(i),l=p.width,c=p.height,p=e.getSize(n),u=p.width,d=p.height,r=(r||"").split(""),"b"===r[0]&&(s+=d),"r"===r[1]&&(a+=u),"c"===r[0]&&(s+=Math.round(d/2)),"c"===r[1]&&(a+=Math.round(u/2)),"b"===r[3]&&(s-=c),"r"===r[4]&&(a-=l),"c"===r[3]&&(s-=Math.round(c/2)),"c"===r[4]&&(a-=Math.round(l/2)),{x:a,y:s,w:l,h:c}}return{testMoveRel:function(n,r){for(var i=e.getViewPort(),o=0;o0&&a.x+a.w0&&a.y+a.hi.x&&a.x+a.wi.y&&a.y+a.he?0:e+n>t?(e=t-n,0>e?0:e):e}var i=this;if(i.settings.constrainToViewport){var o=e.getViewPort(window),a=i.layoutRect();t=r(t,o.w+o.x,a.w),n=r(n,o.h+o.y,a.h)}return i._rendered?i.layoutRect({x:t,y:n}).repaint():(i.settings.x=t,i.settings.y=n),i.fire("move",{x:t,y:n}),i}}}),r(Z,[q],function(e){return{resizeToContent:function(){this._layoutRect.autoResize=!0,this._lastRect=null,this.reflow()},resizeTo:function(t,n){if(1>=t||1>=n){var r=e.getWindowSize();t=1>=t?t*r.w:t,n=1>=n?n*r.h:n}return this._layoutRect.autoResize=!1,this.layoutRect({minW:t,minH:n,w:t,h:n}).reflow()},resizeBy:function(e,t){var n=this,r=n.layoutRect();return n.resizeTo(r.w+e,r.h+t)}}}),r(et,[J,Q,Z,q],function(e,t,n,r){function i(e){var t;for(t=s.length;t--;)s[t]===e&&s.splice(t,1);for(t=l.length;t--;)l[t]===e&&l.splice(t,1)}var o,a,s=[],l=[],c,u=e.extend({Mixins:[t,n],init:function(e){function t(){var e,t=u.zIndex||65535,n;if(l.length)for(e=0;en&&(e.fixed(!1).layoutRect({y:e._autoFixY}).repaint(),t(!1,e._autoFixY-n)):(e._autoFixY=e.layoutRect().y,e._autoFixY'),n=n.firstChild,d.getContainerElm().appendChild(n),setTimeout(function(){r.addClass(n,i+"in"),r.addClass(d.getEl(),i+"in")},0),c=!0),l.push(d),t()}}),d.on("close hide",function(e){if(e.control==d){for(var n=l.length;n--;)l[n]===d&&l.splice(n,1);t()}}),d.on("show",function(){d.parents().each(function(e){return e._fixed?(d.fixed(!0),!1):void 0})}),e.popover&&(d._preBodyHtml='
    ',d.addClass("popover").addClass("bottom").addClass(d.isRtl()?"end":"start"))},fixed:function(e){var t=this;if(t._fixed!=e){if(t._rendered){var n=r.getViewPort();e?t.layoutRect().y-=n.y:t.layoutRect().y+=n.y}t.toggleClass("fixed",e),t._fixed=e}return t},show:function(){var e=this,t,n=e._super();for(t=s.length;t--&&s[t]!==e;);return-1===t&&s.push(e),n},hide:function(){return i(this),this._super()},hideAll:function(){u.hideAll()},close:function(){var e=this;return e.fire("close"),e.remove()},remove:function(){i(this),this._super()},postRender:function(){var e=this;return e.settings.bodyRole&&this.getEl("body").setAttribute("role",e.settings.bodyRole),e._super()}});return u.hideAll=function(){for(var e=s.length;e--;){var t=s[e];t&&t.settings.autohide&&(t.hide(),s.splice(e,1))}},u}),r(tt,[et,J,q,Y],function(e,t,n,r){var i=e.extend({modal:!0,Defaults:{border:1,layout:"flex",containerCls:"panel",role:"dialog",callbacks:{submit:function(){this.fire("submit",{data:this.toJSON()})},close:function(){this.close()}}},init:function(e){var n=this;n._super(e),n.isRtl()&&n.addClass("rtl"),n.addClass("window"),n._fixed=!0,e.buttons&&(n.statusbar=new t({layout:"flex",border:"1 0 0 0",spacing:3,padding:10,align:"center",pack:n.isRtl()?"start":"end",defaults:{type:"button"},items:e.buttons}),n.statusbar.addClass("foot"),n.statusbar.parent(n)),n.on("click",function(e){-1!=e.target.className.indexOf(n.classPrefix+"close")&&n.close()}),n.on("cancel",function(){n.close()}),n.aria("describedby",n.describedBy||n._id+"-none"),n.aria("label",e.title),n._fullscreen=!1},recalc:function(){var e=this,t=e.statusbar,r,i,o,a;e._fullscreen&&(e.layoutRect(n.getWindowSize()),e.layoutRect().contentH=e.layoutRect().innerH),e._super(),r=e.layoutRect(),e.settings.title&&!e._fullscreen&&(i=r.headerW,i>r.w&&(o=r.x-Math.max(0,i/2),e.layoutRect({w:i,x:o}),a=!0)),t&&(t.layoutRect({w:e.layoutRect().innerW}).recalc(),i=t.layoutRect().minW+r.deltaW,i>r.w&&(o=r.x-Math.max(0,i-r.w),e.layoutRect({w:i,x:o}),a=!0)),a&&e.recalc()},initLayoutRect:function(){var e=this,t=e._super(),r=0,i;if(e.settings.title&&!e._fullscreen){i=e.getEl("head");var o=n.getSize(i);t.headerW=o.width,t.headerH=o.height,r+=t.headerH}e.statusbar&&(r+=e.statusbar.layoutRect().h),t.deltaH+=r,t.minH+=r,t.h+=r;var a=n.getWindowSize();return t.x=Math.max(0,a.w/2-t.w/2),t.y=Math.max(0,a.h/2-t.h/2),t},renderHtml:function(){var e=this,t=e._layout,n=e._id,r=e.classPrefix,i=e.settings,o="",a="",s=i.html;return e.preRender(),t.preRender(e),i.title&&(o='
    '+e.encode(i.title)+'
    '),i.url&&(s=''),"undefined"==typeof s&&(s=t.renderHtml(e)),e.statusbar&&(a=e.statusbar.renderHtml()),'
    '+o+'
    '+s+"
    "+a+"
    "},fullscreen:function(e){var t=this,r=document.documentElement,i,o=t.classPrefix,a;if(e!=t._fullscreen)if(n.on(window,"resize",function(){var e;if(t._fullscreen)if(i)t._timer||(t._timer=setTimeout(function(){var e=n.getWindowSize();t.moveTo(0,0).resizeTo(e.w,e.h),t._timer=0},50));else{e=(new Date).getTime();var r=n.getWindowSize();t.moveTo(0,0).resizeTo(r.w,r.h),(new Date).getTime()-e>50&&(i=!0)}}),a=t.layoutRect(),t._fullscreen=e,e){t._initial={x:a.x,y:a.y,w:a.w,h:a.h},t._borderBox=t.parseBox("0"),t.getEl("head").style.display="none",a.deltaH-=a.headerH+2,n.addClass(r,o+"fullscreen"),n.addClass(document.body,o+"fullscreen"),t.addClass("fullscreen");var s=n.getWindowSize();t.moveTo(0,0).resizeTo(s.w,s.h)}else t._borderBox=t.parseBox(t.settings.border),t.getEl("head").style.display="",a.deltaH+=a.headerH,n.removeClass(r,o+"fullscreen"),n.removeClass(document.body,o+"fullscreen"),t.removeClass("fullscreen"),t.moveTo(t._initial.x,t._initial.y).resizeTo(t._initial.w,t._initial.h);return t.reflow()},postRender:function(){var e=this,t;setTimeout(function(){e.addClass("in")},0),e._super(),e.statusbar&&e.statusbar.postRender(),e.focus(),this.dragHelper=new r(e._id+"-dragh",{start:function(){t={x:e.layoutRect().x,y:e.layoutRect().y}},drag:function(n){e.moveTo(t.x+n.deltaX,t.y+n.deltaY)}}),e.on("submit",function(t){t.isDefaultPrevented()||e.close()})},submit:function(){return this.fire("submit",{data:this.toJSON()})},remove:function(){var e=this,t=e.classPrefix;e.dragHelper.destroy(),e._super(),e.statusbar&&this.statusbar.remove(),e._fullscreen&&(n.removeClass(document.documentElement,t+"fullscreen"),n.removeClass(document.body,t+"fullscreen"))},getContentWindow:function(){var e=this.getEl().getElementsByTagName("iframe")[0];return e?e.contentWindow:null}});return i}),r(nt,[tt],function(e){var t=e.extend({init:function(e){e={border:1,padding:20,layout:"flex",pack:"center",align:"center",containerCls:"panel",autoScroll:!0,buttons:{type:"button",text:"Ok",action:"ok"},items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200}},this._super(e)},Statics:{OK:1,OK_CANCEL:2,YES_NO:3,YES_NO_CANCEL:4,msgBox:function(n){var r,i=n.callback||function(){};switch(n.buttons){case t.OK_CANCEL:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close(),i(!0)}},{type:"button",text:"Cancel",onClick:function(e){e.control.parents()[1].close(),i(!1)}}];break;case t.YES_NO:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close(),i(!0)}}];break;case t.YES_NO_CANCEL:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close()}}];break;default:r=[{type:"button",text:"Ok",subtype:"primary",onClick:function(e){e.control.parents()[1].close(),i(!0)}}]}return new e({padding:20,x:n.x,y:n.y,minWidth:300,minHeight:100,layout:"flex",pack:"center",align:"center",buttons:r,title:n.title,role:"alertdialog",items:{type:"label",multiline:!0,maxWidth:500,maxHeight:200,text:n.text},onPostRender:function(){this.aria("describedby",this.items()[0]._id)},onClose:n.onClose,onCancel:function(){i(!1)}}).renderTo(document.body).reflow()},alert:function(e,n){return"string"==typeof e&&(e={text:e}),e.callback=n,t.msgBox(e)},confirm:function(e,n){return"string"==typeof e&&(e={text:e}),e.callback=n,e.buttons=t.OK_CANCEL,t.msgBox(e)}}});return t}),r(rt,[tt,nt],function(e,t){return function(n){function r(){return o.length?o[o.length-1]:void 0}var i=this,o=[];i.windows=o,i.open=function(t,r){var i;return n.editorManager.activeEditor=n,t.title=t.title||" ",t.url=t.url||t.file,t.url&&(t.width=parseInt(t.width||320,10),t.height=parseInt(t.height||240,10)),t.body&&(t.items={defaults:t.defaults,type:t.bodyType||"form",items:t.body}),t.url||t.buttons||(t.buttons=[{text:"Ok",subtype:"primary",onclick:function(){i.find("form")[0].submit()}},{text:"Cancel",onclick:function(){i.close()}}]),i=new e(t),o.push(i),i.on("close",function(){for(var e=o.length;e--;)o[e]===i&&o.splice(e,1);n.focus()}),t.data&&i.on("postRender",function(){this.find("*").each(function(e){var n=e.name();n in t.data&&e.value(t.data[n])})}),i.features=t||{},i.params=r||{},n.nodeChanged(),i.renderTo().reflow()},i.alert=function(e,r,i){t.alert(e,function(){r?r.call(i||this):n.focus()})},i.confirm=function(e,n,r){t.confirm(e,function(e){n.call(r||this,e)})},i.close=function(){r()&&r().close()},i.getParams=function(){return r()?r().params:null},i.setParams=function(e){r()&&(r().params=e)},i.getWindows=function(){return o}}}),r(it,[R,B,x,m,g,p],function(e,t,n,r,i,o){return function(a){function s(e,t){try{a.getDoc().execCommand(e,!1,t)}catch(n){}}function l(){var e=a.getDoc().documentMode;return e?e:6}function c(e){return e.isDefaultPrevented()}function u(){function t(e){var t=new i(function(){});o.each(a.getBody().getElementsByTagName("*"),function(e){"SPAN"==e.tagName&&e.setAttribute("mce-data-marked",1),!e.hasAttribute("data-mce-style")&&e.hasAttribute("style")&&a.dom.setAttrib(e,"style",e.getAttribute("style"))}),t.observe(a.getDoc(),{childList:!0,attributes:!0,subtree:!0,attributeFilter:["style"]}),a.getDoc().execCommand(e?"ForwardDelete":"Delete",!1,null);var n=a.selection.getRng(),r=n.startContainer.parentNode;o.each(t.takeRecords(),function(e){if(q.isChildOf(e.target,a.getBody())){if("style"==e.attributeName){var t=e.target.getAttribute("data-mce-style");t?e.target.setAttribute("style",t):e.target.removeAttribute("style")}o.each(e.addedNodes,function(e){if("SPAN"==e.nodeName&&!e.getAttribute("mce-data-marked")){var t,i;e==r&&(t=n.startOffset,i=e.firstChild),q.remove(e,!0),i&&(n.setStart(i,t),n.setEnd(i,t),a.selection.setRng(n))}})}}),t.disconnect(),o.each(a.dom.select("span[mce-data-marked]"),function(e){e.removeAttribute("mce-data-marked")})}var n=a.getDoc(),r="data:text/mce-internal,",i=window.MutationObserver,s,l;i||(s=!0,i=function(){function e(e){var t=e.relatedNode||e.target;n.push({target:t,addedNodes:[t]})}function t(e){var t=e.relatedNode||e.target;n.push({target:t,attributeName:e.attrName})}var n=[],r;this.observe=function(n){r=n,r.addEventListener("DOMSubtreeModified",e,!1),r.addEventListener("DOMNodeInsertedIntoDocument",e,!1),r.addEventListener("DOMNodeInserted",e,!1),r.addEventListener("DOMAttrModified",t,!1)},this.disconnect=function(){r.removeEventListener("DOMSubtreeModified",e,!1),r.removeEventListener("DOMNodeInsertedIntoDocument",e,!1),r.removeEventListener("DOMNodeInserted",e,!1),r.removeEventListener("DOMAttrModified",t,!1)},this.takeRecords=function(){return n}}),a.on("keydown",function(n){var r=n.keyCode==U,i=e.metaKeyPressed(n);if(!c(n)&&(r||n.keyCode==V)){var o=a.selection.getRng(),s=o.startContainer,l=o.startOffset;if(!i&&o.collapsed&&3==s.nodeType&&(r?l0))return;n.preventDefault(),i&&a.selection.getSel().modify("extend",r?"forward":"backward","word"),t(r)}}),a.on("keypress",function(n){c(n)||$.isCollapsed()||!n.charCode||e.metaKeyPressed(n)||(n.preventDefault(),t(!0),a.selection.setContent(String.fromCharCode(n.charCode)))}),a.addCommand("Delete",function(){t()}),a.addCommand("ForwardDelete",function(){t(!0)}),s||(a.on("dragstart",function(e){var t;a.selection.isCollapsed()&&"IMG"==e.target.tagName&&$.select(e.target),l=$.getRng(),t=a.selection.getContent(),t.length>0&&e.dataTransfer.setData("URL","data:text/mce-internal,"+escape(t))}),a.on("drop",function(e){if(!c(e)){var i=e.dataTransfer.getData("URL");if(!i||-1==i.indexOf(r)||!n.caretRangeFromPoint)return;i=unescape(i.substr(r.length)),n.caretRangeFromPoint&&(e.preventDefault(),window.setTimeout(function(){var r=n.caretRangeFromPoint(e.x,e.y);l&&($.setRng(l),l=null),t(),$.setRng(r),a.insertContent(i)},0))}}),a.on("cut",function(e){!c(e)&&e.clipboardData&&(e.preventDefault(),e.clipboardData.clearData(),e.clipboardData.setData("text/html",a.selection.getContent()),e.clipboardData.setData("text/plain",a.selection.getContent({format:"text"})),t(!0))}))}function d(){function e(e){var t=q.create("body"),n=e.cloneContents();return t.appendChild(n),$.serializer.serialize(t,{format:"html"})}function n(n){if(!n.setStart){if(n.item)return!1;var r=n.duplicate();return r.moveToElementText(a.getBody()),t.compareRanges(n,r)}var i=e(n),o=q.createRng();o.selectNode(a.getBody());var s=e(o);return i===s}a.on("keydown",function(e){var t=e.keyCode,r,i;if(!c(e)&&(t==U||t==V)){if(r=a.selection.isCollapsed(),i=a.getBody(),r&&!q.isEmpty(i))return;if(!r&&!n(a.selection.getRng()))return;e.preventDefault(),a.setContent(""),i.firstChild&&q.isBlock(i.firstChild)?a.selection.setCursorLocation(i.firstChild,0):a.selection.setCursorLocation(i,0),a.nodeChanged()}})}function f(){a.on("keydown",function(t){!c(t)&&65==t.keyCode&&e.metaKeyPressed(t)&&(t.preventDefault(),a.execCommand("SelectAll"))})}function p(){a.settings.content_editable||(q.bind(a.getDoc(),"focusin",function(){$.setRng($.getRng())}),q.bind(a.getDoc(),"mousedown",function(e){e.target==a.getDoc().documentElement&&(a.getBody().focus(),$.setRng($.getRng()))}))}function h(){a.on("keydown",function(e){if(!c(e)&&e.keyCode===V&&$.isCollapsed()&&0===$.getRng(!0).startOffset){var t=$.getNode(),n=t.previousSibling;if("HR"==t.nodeName)return q.remove(t),void e.preventDefault();n&&n.nodeName&&"hr"===n.nodeName.toLowerCase()&&(q.remove(n),e.preventDefault())}})}function m(){window.Range.prototype.getClientRects||a.on("mousedown",function(e){if(!c(e)&&"HTML"===e.target.nodeName){var t=a.getBody();t.blur(),setTimeout(function(){t.focus()},0)}})}function g(){a.on("click",function(e){e=e.target,/^(IMG|HR)$/.test(e.nodeName)&&$.getSel().setBaseAndExtent(e,0,e,1),"A"==e.nodeName&&q.hasClass(e,"mce-item-anchor")&&$.select(e),a.nodeChanged()})}function v(){function e(){var e=q.getAttribs($.getStart().cloneNode(!1));return function(){var t=$.getStart();t!==a.getBody()&&(q.setAttrib(t,"style",null),W(e,function(e){t.setAttributeNode(e.cloneNode(!0))}))}}function t(){return!$.isCollapsed()&&q.getParent($.getStart(),q.isBlock)!=q.getParent($.getEnd(),q.isBlock)}a.on("keypress",function(n){var r;return c(n)||8!=n.keyCode&&46!=n.keyCode||!t()?void 0:(r=e(),a.getDoc().execCommand("delete",!1,null),r(),n.preventDefault(),!1)}),q.bind(a.getDoc(),"cut",function(n){var r;!c(n)&&t()&&(r=e(),setTimeout(function(){r()},0))})}function y(){var e,n;a.on("selectionchange",function(){n&&(clearTimeout(n),n=0),n=window.setTimeout(function(){if(!a.removed){var n=$.getRng();e&&t.compareRanges(n,e)||(a.nodeChanged(),e=n)}},50)})}function b(){document.body.setAttribute("role","application")}function C(){a.on("keydown",function(e){if(!c(e)&&e.keyCode===V&&$.isCollapsed()&&0===$.getRng(!0).startOffset){var t=$.getNode().previousSibling;if(t&&t.nodeName&&"table"===t.nodeName.toLowerCase())return e.preventDefault(),!1}})}function x(){l()>7||(s("RespectVisibilityInDesign",!0),a.contentStyles.push(".mceHideBrInPre pre br {display: none}"),q.addClass(a.getBody(),"mceHideBrInPre"),K.addNodeFilter("pre",function(e){for(var t=e.length,r,i,o,a;t--;)for(r=e[t].getAll("br"),i=r.length;i--;)o=r[i],a=o.prev,a&&3===a.type&&"\n"!=a.value.charAt(a.value-1)?a.value+="\n":o.parent.insert(new n("#text",3),o,!0).value="\n"}),G.addNodeFilter("pre",function(e){for(var t=e.length,n,r,i,o;t--;)for(n=e[t].getAll("br"),r=n.length;r--;)i=n[r],o=i.prev,o&&3==o.type&&(o.value=o.value.replace(/\r?\n$/,""))}))}function w(){q.bind(a.getBody(),"mouseup",function(){var e,t=$.getNode();"IMG"==t.nodeName&&((e=q.getStyle(t,"width"))&&(q.setAttrib(t,"width",e.replace(/[^0-9%]+/g,"")),q.setStyle(t,"width","")),(e=q.getStyle(t,"height"))&&(q.setAttrib(t,"height",e.replace(/[^0-9%]+/g,"")),q.setStyle(t,"height","")))})}function _(){a.on("keydown",function(t){var n,r,i,o,s;if(!c(t)&&t.keyCode==e.BACKSPACE&&(n=$.getRng(),r=n.startContainer,i=n.startOffset,o=q.getRoot(),s=r,n.collapsed&&0===i)){for(;s&&s.parentNode&&s.parentNode.firstChild==s&&s.parentNode!=o;)s=s.parentNode;"BLOCKQUOTE"===s.tagName&&(a.formatter.toggle("blockquote",null,s),n=q.createRng(),n.setStart(r,0),n.setEnd(r,0),$.setRng(n))}})}function N(){function e(){a._refreshContentEditable(),s("StyleWithCSS",!1),s("enableInlineTableEditing",!1),j.object_resizing||s("enableObjectResizing",!1)}j.readonly||a.on("BeforeExecCommand MouseDown",e)}function E(){function e(){W(q.select("a"),function(e){var t=e.parentNode,n=q.getRoot();if(t.lastChild===e){for(;t&&!q.isBlock(t);){if(t.parentNode.lastChild!==t||t===n)return;t=t.parentNode}q.add(t,"br",{"data-mce-bogus":1})}})}a.on("SetContent ExecCommand",function(t){("setcontent"==t.type||"mceInsertLink"===t.command)&&e()})}function S(){j.forced_root_block&&a.on("init",function(){s("DefaultParagraphSeparator",j.forced_root_block)})}function k(){a.on("Undo Redo SetContent",function(e){e.initial||a.execCommand("mceRepaint")})}function T(){a.on("keydown",function(e){var t;c(e)||e.keyCode!=V||(t=a.getDoc().selection.createRange(),t&&t.item&&(e.preventDefault(),a.undoManager.beforeChange(),q.remove(t.item(0)),a.undoManager.add()))})}function R(){var e;l()>=10&&(e="",W("p div h1 h2 h3 h4 h5 h6".split(" "),function(t,n){e+=(n>0?",":"")+t+":empty"}),a.contentStyles.push(e+"{padding-right: 1px !important}"))}function A(){l()<9&&(K.addNodeFilter("noscript",function(e){for(var t=e.length,n,r;t--;)n=e[t],r=n.firstChild,r&&n.attr("data-mce-innertext",r.value)}),G.addNodeFilter("noscript",function(e){for(var t=e.length,i,o,a;t--;)i=e[t],o=e[t].firstChild,o?o.value=r.decode(o.value):(a=i.attributes.map["data-mce-innertext"],a&&(i.attr("data-mce-innertext",null),o=new n("#text",3),o.value=a,o.raw=!0,i.append(o)))}))}function B(){function e(e,t){var n=i.createTextRange();try{n.moveToPoint(e,t)}catch(r){n=null}return n}function t(t){var r;t.button?(r=e(t.x,t.y),r&&(r.compareEndPoints("StartToStart",a)>0?r.setEndPoint("StartToStart",a):r.setEndPoint("EndToEnd",a),r.select())):n()}function n(){var e=r.selection.createRange();a&&!e.item&&0===e.compareEndPoints("StartToEnd",e)&&a.select(),q.unbind(r,"mouseup",n),q.unbind(r,"mousemove",t),a=o=0}var r=q.doc,i=r.body,o,a,s;r.documentElement.unselectable=!0,q.bind(r,"mousedown contextmenu",function(i){if("HTML"===i.target.nodeName){if(o&&n(),s=r.documentElement,s.scrollHeight>s.clientHeight)return;o=1,a=e(i.x,i.y),a&&(q.bind(r,"mouseup",n),q.bind(r,"mousemove",t),q.getRoot().focus(),a.select())}})}function D(){a.on("keyup focusin mouseup",function(t){65==t.keyCode&&e.metaKeyPressed(t)||$.normalize()},!0)}function L(){a.contentStyles.push("img:-moz-broken {-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}")}function M(){a.inline||a.on("keydown",function(){document.activeElement==document.body&&a.getWin().focus()})}function H(){a.inline||(a.contentStyles.push("body {min-height: 150px}"),a.on("click",function(e){"HTML"==e.target.nodeName&&(a.getBody().focus(),a.selection.normalize(),a.nodeChanged())}))}function P(){i.mac&&a.on("keydown",function(t){!e.metaKeyPressed(t)||37!=t.keyCode&&39!=t.keyCode||(t.preventDefault(),a.selection.getSel().modify("move",37==t.keyCode?"backward":"forward","word"))})}function O(){s("AutoUrlDetect",!1)}function I(){a.inline||a.on("focus blur beforegetcontent",function(){var e=a.dom.create("br");a.getBody().appendChild(e),e.parentNode.removeChild(e)},!0)}function F(){a.on("click",function(e){var t=e.target;do if("A"===t.tagName)return void e.preventDefault();while(t=t.parentNode)}),a.contentStyles.push(".mce-content-body {-webkit-touch-callout: none}")}function z(){a.on("init",function(){a.dom.bind(a.getBody(),"submit",function(e){e.preventDefault()})})}var W=o.each,V=e.BACKSPACE,U=e.DELETE,q=a.dom,$=a.selection,j=a.settings,K=a.parser,G=a.serializer,Y=i.gecko,X=i.ie,J=i.webkit;C(),_(),d(),D(),J&&(u(),p(),g(),S(),z(),i.iOS?(y(),M(),H(),F()):f()),X&&i.ie<11&&(h(),b(),x(),w(),T(),R(),A(),B()),i.ie>=11&&(H(),I()),i.ie&&(f(),O()),Y&&(h(),m(),v(),N(),E(),k(),L(),P())}}),r(ot,[W],function(e){function t(t){return t._eventDispatcher||(t._eventDispatcher=new e({scope:t,toggleEvent:function(n,r){e.isNative(n)&&t.toggleNativeEvent&&t.toggleNativeEvent(n,r)}})),t._eventDispatcher}return{fire:function(e,n,r){var i=this;if(i.removed&&"remove"!==e)return n;if(n=t(i).fire(e,n,r),r!==!1&&i.parent)for(var o=i.parent();o&&!n.isPropagationStopped();)o.fire(e,n,!1),o=o.parent();return n},on:function(e,n,r){return t(this).on(e,n,r)},off:function(e,n){return t(this).off(e,n)},hasEventListeners:function(e){return t(this).has(e)}}}),r(at,[ot,y,p],function(e,t,n){function r(e,t){return"selectionchange"==t?e.getDoc():!e.inline&&/^mouse|click|contextmenu|drop/.test(t)?e.getDoc():e.getBody()}function i(e,t){var n=e.settings.event_root,i=e.editorManager,a=i.eventRootElm||r(e,t);if(n){if(i.rootEvents||(i.rootEvents={},i.on("RemoveEditor",function(){i.activeEditor||(o.unbind(a),delete i.rootEvents)})),i.rootEvents[t])return;a==e.getBody()&&(a=o.select(n)[0],i.eventRootElm=a),i.rootEvents[t]=!0,o.bind(a,t,function(e){for(var n=e.target,r=i.editors,a=r.length;a--;){var s=r[a].getBody();(s===n||o.isChildOf(n,s))&&(r[a].hidden||r[a].fire(t,e))}})}else e.dom.bind(a,t,function(n){e.hidden||e.fire(t,n)})}var o=t.DOM,a={bindPendingEventDelegates:function(){var e=this;n.each(e._pendingNativeEvents,function(t){i(e,t)})},toggleNativeEvent:function(e,t){var n=this;n.settings.readonly||"focus"!=e&&"blur"!=e&&(t?n.initialized?i(n,e):n._pendingNativeEvents?n._pendingNativeEvents.push(e):n._pendingNativeEvents=[e]:n.initialized&&n.dom.unbind(r(n,e),e))}};return a=n.extend({},e,a)}),r(st,[p,g],function(e,t){var n=e.each,r=e.explode,i={f9:120,f10:121,f11:122};return function(o){var a=this,s={};o.on("keyup keypress keydown",function(e){(e.altKey||e.ctrlKey||e.metaKey)&&n(s,function(n){var r=t.mac?e.metaKey:e.ctrlKey;if(n.ctrl==r&&n.alt==e.altKey&&n.shift==e.shiftKey)return e.keyCode==n.keyCode||e.charCode&&e.charCode==n.charCode?(e.preventDefault(),"keydown"==e.type&&n.func.call(n.scope),!0):void 0})}),a.add=function(t,a,l,c){var u;return u=l,"string"==typeof l?l=function(){o.execCommand(u,!1,null)}:e.isArray(u)&&(l=function(){o.execCommand(u[0],u[1],u[2])}),n(r(t.toLowerCase()),function(e){var t={func:l,scope:c||o,desc:o.translate(a),alt:!1,ctrl:!1,shift:!1};n(r(e,"+"),function(e){switch(e){case"alt":case"ctrl":case"shift":t[e]=!0;break;default:t.charCode=e.charCodeAt(0),t.keyCode=i[e]||e.toUpperCase().charCodeAt(0)}}),s[(t.ctrl?"ctrl":"")+","+(t.alt?"alt":"")+","+(t.shift?"shift":"")+","+t.keyCode]=t}),!0}}}),r(lt,[y,C,x,k,S,D,M,H,P,O,I,F,b,l,rt,w,N,it,g,p,at,st],function(e,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v,y,b,C,x,w){function _(e,t,r){var i=this,o,a;o=i.documentBaseUrl=r.documentBaseURL,a=r.baseURI,i.settings=t=k({id:e,theme:"modern",delta_width:0,delta_height:0,popup_css:"",plugins:"",document_base_url:o,add_form_submit_trigger:!0,submit_patch:!0,add_unload_trigger:!0,convert_urls:!0,relative_urls:!0,remove_script_host:!0,object_resizing:!0,doctype:"",visual:!0,font_size_style_values:"xx-small,x-small,small,medium,large,x-large,xx-large",font_size_legacy_values:"xx-small,small,medium,large,x-large,xx-large,300%",forced_root_block:"p",hidden_input:!0,padd_empty_editor:!0,render_ui:!0,indentation:"30px",inline_styles:!0,convert_fonts_to_spans:!0,indent:"simple",indent_before:"p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist",indent_after:"p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure,option,optgroup,datalist",validate:!0,entity_encoding:"named",url_converter:i.convertURL,url_converter_scope:i,ie7_compat:!0},t),n.language=t.language||"en",n.languageLoad=t.language_load,n.baseURL=r.baseURL,i.id=t.id=e,i.isNotDirty=!0,i.plugins={},i.documentBaseURI=new f(t.document_base_url||o,{base_uri:a}),i.baseURI=a,i.contentCSS=[],i.contentStyles=[],i.shortcuts=new w(i),i.execCommands={},i.queryStateCommands={},i.queryValueCommands={},i.loadedCSS={},i.suffix=r.suffix,i.editorManager=r,i.inline=t.inline,r.fire("SetupEditor",i),i.execCallback("setup",i)}var N=e.DOM,E=n.ThemeManager,S=n.PluginManager,k=C.extend,T=C.each,R=C.explode,A=C.inArray,B=C.trim,D=C.resolve,L=h.Event,M=b.gecko,H=b.ie;return _.prototype={render:function(){function e(){N.unbind(window,"ready",e),n.render()}function t(){var e=p.ScriptLoader;if(r.language&&"en"!=r.language&&!r.language_url&&(r.language_url=n.editorManager.baseURL+"/langs/"+r.language+".js"),r.language_url&&e.add(r.language_url),r.theme&&"function"!=typeof r.theme&&"-"!=r.theme.charAt(0)&&!E.urls[r.theme]){var t=r.theme_url;t=t?n.documentBaseURI.toAbsolute(t):"themes/"+r.theme+"/theme"+o+".js",E.load(r.theme,t)}C.isArray(r.plugins)&&(r.plugins=r.plugins.join(" ")),T(r.external_plugins,function(e,t){S.load(t,e),r.plugins+=" "+t}),T(r.plugins.split(/[ ,]/),function(e){if(e=B(e),e&&!S.urls[e])if("-"==e.charAt(0)){e=e.substr(1,e.length);var t=S.dependencies(e);T(t,function(e){var t={prefix:"plugins/",resource:e,suffix:"/plugin"+o+".js"};e=S.createUrl(t,e),S.load(e.resource,e)})}else S.load(e,{prefix:"plugins/",resource:e,suffix:"/plugin"+o+".js"})}),e.loadQueue(function(){n.removed||n.init()})}var n=this,r=n.settings,i=n.id,o=n.suffix;if(!L.domLoaded)return void N.bind(window,"ready",e);if(n.getElement()&&b.contentEditable){r.inline?n.inline=!0:(n.orgVisibility=n.getElement().style.visibility,n.getElement().style.visibility="hidden");var a=n.getElement().form||N.getParent(i,"form");a&&(n.formElement=a,r.hidden_input&&!/TEXTAREA|INPUT/i.test(n.getElement().nodeName)&&(N.insertAfter(N.create("input",{type:"hidden",name:i}),i),n.hasHiddenInput=!0),n.formEventDelegate=function(e){n.fire(e.type,e)},N.bind(a,"submit reset",n.formEventDelegate),n.on("reset",function(){n.setContent(n.startContent,{format:"raw"})}),!r.submit_patch||a.submit.nodeType||a.submit.length||a._mceOldSubmit||(a._mceOldSubmit=a.submit,a.submit=function(){return n.editorManager.triggerSave(),n.isNotDirty=!0,a._mceOldSubmit(a)})),n.windowManager=new m(n),"xml"==r.encoding&&n.on("GetContent",function(e){e.save&&(e.content=N.encode(e.content))}),r.add_form_submit_trigger&&n.on("submit",function(){n.initialized&&n.save()}),r.add_unload_trigger&&(n._beforeUnload=function(){!n.initialized||n.destroyed||n.isHidden()||n.save({format:"raw",no_events:!0,set_dirty:!1})},n.editorManager.on("BeforeUnload",n._beforeUnload)),t()}},init:function(){function e(n){var r=S.get(n),i,o;i=S.urls[n]||t.documentBaseUrl.replace(/\/$/,""),n=B(n),r&&-1===A(m,n)&&(T(S.dependencies(n),function(t){e(t)}),o=new r(t,i),t.plugins[n]=o,o.init&&(o.init(t,i),m.push(n)))}var t=this,n=t.settings,r=t.getElement(),i,o,a,s,l,c,u,d,f,p,h,m=[];if(t.rtl=this.editorManager.i18n.rtl,t.editorManager.add(t),n.aria_label=n.aria_label||N.getAttrib(r,"aria-label",t.getLang("aria.rich_text_area")),n.theme&&("function"!=typeof n.theme?(n.theme=n.theme.replace(/-/,""),c=E.get(n.theme),t.theme=new c(t,E.urls[n.theme]),t.theme.init&&t.theme.init(t,E.urls[n.theme]||t.documentBaseUrl.replace(/\/$/,""))):t.theme=n.theme),T(n.plugins.replace(/\-/g,"").split(/[ ,]/),e),n.render_ui&&t.theme&&(t.orgDisplay=r.style.display,"function"!=typeof n.theme?(i=n.width||r.style.width||r.offsetWidth,o=n.height||r.style.height||r.offsetHeight,a=n.min_height||100,p=/^[0-9\.]+(|px)$/i,p.test(""+i)&&(i=Math.max(parseInt(i,10),100)),p.test(""+o)&&(o=Math.max(parseInt(o,10),a)),l=t.theme.renderUI({targetNode:r,width:i,height:o,deltaWidth:n.delta_width,deltaHeight:n.delta_height}),n.content_editable||(N.setStyles(l.sizeContainer||l.editorContainer,{wi2dth:i,h2eight:o}),o=(l.iframeHeight||o)+("number"==typeof o?l.deltaHeight||0:""),a>o&&(o=a))):(l=n.theme(t,r),l.editorContainer.nodeType&&(l.editorContainer=l.editorContainer.id=l.editorContainer.id||t.id+"_parent"),l.iframeContainer.nodeType&&(l.iframeContainer=l.iframeContainer.id=l.iframeContainer.id||t.id+"_iframecontainer"),o=l.iframeHeight||r.offsetHeight),t.editorContainer=l.editorContainer),n.content_css&&T(R(n.content_css),function(e){t.contentCSS.push(t.documentBaseURI.toAbsolute(e))}),n.content_style&&t.contentStyles.push(n.content_style),n.content_editable)return r=s=l=null,t.initContentBody();for(t.iframeHTML=n.doctype+"",n.document_base_url!=t.documentBaseUrl&&(t.iframeHTML+=''),!b.caretAfter&&n.ie7_compat&&(t.iframeHTML+=''),t.iframeHTML+='',h=0;h',t.loadedCSS[g]=!0}d=n.body_id||"tinymce",-1!=d.indexOf("=")&&(d=t.getParam("body_id","","hash"),d=d[t.id]||d),f=n.body_class||"",-1!=f.indexOf("=")&&(f=t.getParam("body_class","","hash"),f=f[t.id]||""),t.iframeHTML+='
    ";var v='javascript:(function(){document.open();document.domain="'+document.domain+'";var ed = window.parent.tinymce.get("'+t.id+'");document.write(ed.iframeHTML);document.close();ed.initContentBody(true);})()';if(document.domain!=location.hostname&&(u=v),s=N.add(l.iframeContainer,"iframe",{id:t.id+"_ifr",src:u||'javascript:""',frameBorder:"0",allowTransparency:"true",title:t.editorManager.translate("Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help"),style:{width:"100%",height:o,display:"block"}}),H)try{t.getDoc()}catch(y){s.src=u=v}t.contentAreaContainer=l.iframeContainer,l.editorContainer&&(N.get(l.editorContainer).style.display=t.orgDisplay),N.get(t.id).style.display="none",N.setAttrib(t.id,"aria-hidden",!0),u||t.initContentBody(),r=s=l=null},initContentBody:function(t){var n=this,o=n.settings,f=N.get(n.id),p=n.getDoc(),h,m;o.inline||(n.getElement().style.visibility=n.orgVisibility),t||o.content_editable||(p.open(),p.write(n.iframeHTML),p.close()),o.content_editable&&(n.on("remove",function(){var e=this.getBody();N.removeClass(e,"mce-content-body"),N.removeClass(e,"mce-edit-focus"),N.setAttrib(e,"contentEditable",null)}),N.addClass(f,"mce-content-body"),n.contentDocument=p=o.content_document||document,n.contentWindow=o.content_window||window,n.bodyElement=f,o.content_document=o.content_window=null,o.root_name=f.nodeName.toLowerCase()),h=n.getBody(),h.disabled=!0,o.readonly||(n.inline&&"static"==N.getStyle(h,"position",!0)&&(h.style.position="relative"),h.contentEditable=n.getParam("content_editable_state",!0)),h.disabled=!1,n.schema=new g(o),n.dom=new e(p,{keep_values:!0,url_converter:n.convertURL,url_converter_scope:n,hex_colors:o.force_hex_style_colors,class_filter:o.class_filter,update_styles:!0,root_element:o.content_editable?n.id:null,collect:o.content_editable,schema:n.schema,onSetAttrib:function(e){n.fire("SetAttrib",e) +}}),n.parser=new v(o,n.schema),n.parser.addAttributeFilter("src,href,style,tabindex",function(e,t){for(var r=e.length,i,o=n.dom,a,s;r--;)i=e[r],a=i.attr(t),s="data-mce-"+t,i.attributes.map[s]||("style"===t?i.attr(s,o.serializeStyle(o.parseStyle(a),i.name)):"tabindex"===t?(i.attr(s,a),i.attr(t,null)):i.attr(s,n.convertURL(a,t,i.name)))}),n.parser.addNodeFilter("script",function(e){for(var t=e.length,n;t--;)n=e[t],n.attr("type","mce-"+(n.attr("type")||"text/javascript"))}),n.parser.addNodeFilter("#cdata",function(e){for(var t=e.length,n;t--;)n=e[t],n.type=8,n.name="#comment",n.value="[CDATA["+n.value+"]]"}),n.parser.addNodeFilter("p,h1,h2,h3,h4,h5,h6,div",function(e){for(var t=e.length,i,o=n.schema.getNonEmptyElements();t--;)i=e[t],i.isEmpty(o)&&(i.empty().append(new r("br",1)).shortEnded=!0)}),n.serializer=new i(o,n),n.selection=new a(n.dom,n.getWin(),n.serializer,n),n.formatter=new s(n),n.undoManager=new l(n),n.forceBlocks=new u(n),n.enterKey=new c(n),n.editorCommands=new d(n),n.fire("PreInit"),o.browser_spellcheck||o.gecko_spellcheck||(p.body.spellcheck=!1,N.setAttrib(h,"spellcheck","false")),n.fire("PostRender"),n.quirks=y(n),o.directionality&&(h.dir=o.directionality),o.nowrap&&(h.style.whiteSpace="nowrap"),o.protect&&n.on("BeforeSetContent",function(e){T(o.protect,function(t){e.content=e.content.replace(t,function(e){return""})})}),n.on("SetContent",function(){n.addVisual(n.getBody())}),o.padd_empty_editor&&n.on("PostProcess",function(e){e.content=e.content.replace(/^(]*>( | |\s|\u00a0|)<\/p>[\r\n]*|
    [\r\n]*)$/,"")}),n.load({initial:!0,format:"html"}),n.startContent=n.getContent({format:"raw"}),n.initialized=!0,n.bindPendingEventDelegates(),n.fire("init"),n.focus(!0),n.nodeChanged({initial:!0}),n.execCallback("init_instance_callback",n),n.contentStyles.length>0&&(m="",T(n.contentStyles,function(e){m+=e+"\r\n"}),n.dom.addStyle(m)),T(n.contentCSS,function(e){n.loadedCSS[e]||(n.dom.loadCSS(e),n.loadedCSS[e]=!0)}),o.auto_focus&&setTimeout(function(){var e=n.editorManager.get(o.auto_focus);e.selection.select(e.getBody(),1),e.selection.collapse(1),e.getBody().focus(),e.getWin().focus()},100),f=p=h=null},focus:function(e){var t,n=this,r=n.selection,i=n.settings.content_editable,o,a,s=n.getDoc(),l;if(!e){if(o=r.getRng(),o.item&&(a=o.item(0)),n._refreshContentEditable(),i||(b.opera||n.getBody().focus(),n.getWin().focus()),M||i){if(l=n.getBody(),l.setActive)try{l.setActive()}catch(c){l.focus()}else l.focus();i&&r.normalize()}a&&a.ownerDocument==s&&(o=s.body.createControlRange(),o.addElement(a),o.select())}n.editorManager.activeEditor!=n&&((t=n.editorManager.activeEditor)&&t.fire("deactivate",{relatedTarget:n}),n.fire("activate",{relatedTarget:t})),n.editorManager.activeEditor=n},execCallback:function(e){var t=this,n=t.settings[e],r;if(n)return t.callbackLookup&&(r=t.callbackLookup[e])&&(n=r.func,r=r.scope),"string"==typeof n&&(r=n.replace(/\.\w+$/,""),r=r?D(r):0,n=D(n),t.callbackLookup=t.callbackLookup||{},t.callbackLookup[e]={func:n,scope:r}),n.apply(r||t,Array.prototype.slice.call(arguments,1))},translate:function(e){var t=this.settings.language||"en",n=this.editorManager.i18n;return e?n.data[t+"."+e]||e.replace(/\{\#([^\}]+)\}/g,function(e,r){return n.data[t+"."+r]||"{#"+r+"}"}):""},getLang:function(e,n){return this.editorManager.i18n.data[(this.settings.language||"en")+"."+e]||(n!==t?n:"{#"+e+"}")},getParam:function(e,t,n){var r=e in this.settings?this.settings[e]:t,i;return"hash"===n?(i={},"string"==typeof r?T(r.split(r.indexOf("=")>0?/[;,](?![^=;,]*(?:[;,]|$))/:","),function(e){e=e.split("="),i[B(e[0])]=B(e.length>1?e[1]:e)}):i=r,i):r},nodeChanged:function(){var e=this,t=e.selection,n,r,i;!e.initialized||e.settings.disable_nodechange||e.settings.readonly||(i=e.getBody(),n=t.getStart()||i,n=H&&n.ownerDocument!=e.getDoc()?e.getBody():n,"IMG"==n.nodeName&&t.isCollapsed()&&(n=n.parentNode),r=[],e.dom.getParent(n,function(e){return e===i?!0:void r.push(e)}),e.fire("NodeChange",{element:n,parents:r}))},addButton:function(e,t){var n=this;t.cmd&&(t.onclick=function(){n.execCommand(t.cmd)}),t.text||t.icon||(t.icon=e),n.buttons=n.buttons||{},t.tooltip=t.tooltip||t.title,n.buttons[e]=t},addMenuItem:function(e,t){var n=this;t.cmd&&(t.onclick=function(){n.execCommand(t.cmd)}),n.menuItems=n.menuItems||{},n.menuItems[e]=t},addCommand:function(e,t,n){this.execCommands[e]={func:t,scope:n||this}},addQueryStateHandler:function(e,t,n){this.queryStateCommands[e]={func:t,scope:n||this}},addQueryValueHandler:function(e,t,n){this.queryValueCommands[e]={func:t,scope:n||this}},addShortcut:function(e,t,n,r){this.shortcuts.add(e,t,n,r)},execCommand:function(e,t,n,r){var i=this,o=0,a;return/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(e)||r&&r.skip_focus||i.focus(),r=k({},r),r=i.fire("BeforeExecCommand",{command:e,ui:t,value:n}),r.isDefaultPrevented()?!1:(a=i.execCommands[e])&&a.func.call(a.scope,t,n)!==!0?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):(T(i.plugins,function(r){return r.execCommand&&r.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),o=!0,!1):void 0}),o?o:i.theme&&i.theme.execCommand&&i.theme.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):i.editorCommands.execCommand(e,t,n)?(i.fire("ExecCommand",{command:e,ui:t,value:n}),!0):(i.getDoc().execCommand(e,t,n),void i.fire("ExecCommand",{command:e,ui:t,value:n})))},queryCommandState:function(e){var t=this,n,r;if(!t._isHidden()){if((n=t.queryStateCommands[e])&&(r=n.func.call(n.scope),r!==!0))return r;if(r=t.editorCommands.queryCommandState(e),-1!==r)return r;try{return t.getDoc().queryCommandState(e)}catch(i){}}},queryCommandValue:function(e){var n=this,r,i;if(!n._isHidden()){if((r=n.queryValueCommands[e])&&(i=r.func.call(r.scope),i!==!0))return i;if(i=n.editorCommands.queryCommandValue(e),i!==t)return i;try{return n.getDoc().queryCommandValue(e)}catch(o){}}},show:function(){var e=this;e.hidden&&(e.hidden=!1,e.inline?e.getBody().contentEditable=!0:(N.show(e.getContainer()),N.hide(e.id)),e.load(),e.fire("show"))},hide:function(){var e=this,t=e.getDoc();e.hidden||(e.hidden=!0,H&&t&&!e.inline&&t.execCommand("SelectAll"),e.save(),e.inline?(e.getBody().contentEditable=!1,e==e.editorManager.focusedEditor&&(e.editorManager.focusedEditor=null)):(N.hide(e.getContainer()),N.setStyle(e.id,"display",e.orgDisplay)),e.fire("hide"))},isHidden:function(){return!!this.hidden},setProgressState:function(e,t){this.fire("ProgressState",{state:e,time:t})},load:function(e){var n=this,r=n.getElement(),i;return r?(e=e||{},e.load=!0,i=n.setContent(r.value!==t?r.value:r.innerHTML,e),e.element=r,e.no_events||n.fire("LoadContent",e),e.element=r=null,i):void 0},save:function(e){var t=this,n=t.getElement(),r,i;if(n&&t.initialized)return e=e||{},e.save=!0,e.element=n,r=e.content=t.getContent(e),e.no_events||t.fire("SaveContent",e),r=e.content,/TEXTAREA|INPUT/i.test(n.nodeName)?n.value=r:(t.inline||(n.innerHTML=r),(i=N.getParent(t.id,"form"))&&T(i.elements,function(e){return e.name==t.id?(e.value=r,!1):void 0})),e.element=n=null,e.set_dirty!==!1&&(t.isNotDirty=!0),r},setContent:function(e,t){var n=this,r=n.getBody(),i;return t=t||{},t.format=t.format||"html",t.set=!0,t.content=e,t.no_events||n.fire("BeforeSetContent",t),e=t.content,0===e.length||/^\s+$/.test(e)?(i=n.settings.forced_root_block,i&&n.schema.isValidChild(r.nodeName.toLowerCase(),i.toLowerCase())?(e=H&&11>H?"":'
    ',e=n.dom.createHTML(i,n.settings.forced_root_block_attrs,e)):H||(e='
    '),r.innerHTML=e,n.fire("SetContent",t)):("raw"!==t.format&&(e=new o({},n.schema).serialize(n.parser.parse(e,{isRootContent:!0}))),t.content=B(e),n.dom.setHTML(r,t.content),t.no_events||n.fire("SetContent",t)),t.content},getContent:function(e){var t=this,n,r=t.getBody();return e=e||{},e.format=e.format||"html",e.get=!0,e.getInner=!0,e.no_events||t.fire("BeforeGetContent",e),n="raw"==e.format?r.innerHTML:"text"==e.format?r.innerText||r.textContent:t.serializer.serialize(r,e),e.content="text"!=e.format?B(n):n,e.no_events||t.fire("GetContent",e),e.content},insertContent:function(e){this.execCommand("mceInsertContent",!1,e)},isDirty:function(){return!this.isNotDirty},getContainer:function(){var e=this;return e.container||(e.container=N.get(e.editorContainer||e.id+"_parent")),e.container},getContentAreaContainer:function(){return this.contentAreaContainer},getElement:function(){return N.get(this.settings.content_element||this.id)},getWin:function(){var e=this,t;return e.contentWindow||(t=N.get(e.id+"_ifr"),t&&(e.contentWindow=t.contentWindow)),e.contentWindow},getDoc:function(){var e=this,t;return e.contentDocument||(t=e.getWin(),t&&(e.contentDocument=t.document)),e.contentDocument},getBody:function(){return this.bodyElement||this.getDoc().body},convertURL:function(e,t,n){var r=this,i=r.settings;return i.urlconverter_callback?r.execCallback("urlconverter_callback",e,n,!0,t):!i.convert_urls||n&&"LINK"==n.nodeName||0===e.indexOf("file:")||0===e.length?e:i.relative_urls?r.documentBaseURI.toRelative(e):e=r.documentBaseURI.toAbsolute(e,i.remove_script_host)},addVisual:function(e){var n=this,r=n.settings,i=n.dom,o;e=e||n.getBody(),n.hasVisual===t&&(n.hasVisual=r.visual),T(i.select("table,a",e),function(e){var t;switch(e.nodeName){case"TABLE":return o=r.visual_table_class||"mce-item-table",t=i.getAttrib(e,"border"),void(t&&"0"!=t||(n.hasVisual?i.addClass(e,o):i.removeClass(e,o)));case"A":return void(i.getAttrib(e,"href",!1)||(t=i.getAttrib(e,"name")||e.id,o=r.visual_anchor_class||"mce-item-anchor",t&&(n.hasVisual?i.addClass(e,o):i.removeClass(e,o))))}}),n.fire("VisualAid",{element:e,hasVisual:n.hasVisual})},remove:function(){var e=this;if(!e.removed){e.removed=1,e.save(),e.hasHiddenInput&&N.remove(e.getElement().nextSibling),e.inline||(H&&10>H&&e.getDoc().execCommand("SelectAll",!1,null),N.setStyle(e.id,"display",e.orgDisplay),e.getBody().onload=null,L.unbind(e.getWin()),L.unbind(e.getDoc()));var t=e.getContainer();L.unbind(e.getBody()),L.unbind(t),e.fire("remove"),e.editorManager.remove(e),N.remove(t),e.destroy()}},destroy:function(e){var t=this,n;if(!t.destroyed){if(!e&&!t.removed)return void t.remove();e&&M&&(L.unbind(t.getDoc()),L.unbind(t.getWin()),L.unbind(t.getBody())),e||(t.editorManager.off("beforeunload",t._beforeUnload),t.theme&&t.theme.destroy&&t.theme.destroy(),t.selection.destroy(),t.dom.destroy()),n=t.formElement,n&&(n._mceOldSubmit&&(n.submit=n._mceOldSubmit,n._mceOldSubmit=null),N.unbind(n,"submit reset",t.formEventDelegate)),t.contentAreaContainer=t.formElement=t.container=t.editorContainer=null,t.settings.content_element=t.bodyElement=t.contentDocument=t.contentWindow=null,t.selection&&(t.selection=t.selection.win=t.selection.dom=t.selection.dom.doc=null),t.destroyed=1}},_refreshContentEditable:function(){var e=this,t,n;e._isHidden()&&(t=e.getBody(),n=t.parentNode,n.removeChild(t),n.appendChild(t),t.focus())},_isHidden:function(){var e;return M?(e=this.selection.getSel(),!e||!e.rangeCount||0===e.rangeCount):0}},k(_.prototype,x),_}),r(ct,[],function(){var e={};return{rtl:!1,add:function(t,n){for(var r in n)e[r]=n[r];this.rtl=this.rtl||"rtl"===e._dir},translate:function(t){if("undefined"==typeof t)return t;if("string"!=typeof t&&t.raw)return t.raw;if(t.push){var n=t.slice(1);t=(e[t[0]]||t[0]).replace(/\{([^\}]+)\}/g,function(e,t){return n[t]})}return e[t]||t},data:e}}),r(ut,[y,g],function(e,t){function n(e){function s(){try{return document.activeElement}catch(e){return document.body}}function l(e,t){if(t&&t.startContainer){if(!e.isChildOf(t.startContainer,e.getRoot())||!e.isChildOf(t.endContainer,e.getRoot()))return;return{startContainer:t.startContainer,startOffset:t.startOffset,endContainer:t.endContainer,endOffset:t.endOffset}}return t}function c(e,t){var n;return t.startContainer?(n=e.getDoc().createRange(),n.setStart(t.startContainer,t.startOffset),n.setEnd(t.endContainer,t.endOffset)):n=t,n}function u(e){return!!a.getParent(e,n.isEditorUIElement)}function d(n){var d=n.editor;d.on("init",function(){(d.inline||t.ie)&&(d.on("nodechange keyup",function(){var e=document.activeElement;e&&e.id==d.id+"_ifr"&&(e=d.getBody()),d.dom.isChildOf(e,d.getBody())&&(d.lastRng=d.selection.getRng())}),t.webkit&&!r&&(r=function(){var t=e.activeEditor;if(t&&t.selection){var n=t.selection.getRng();n&&!n.collapsed&&(d.lastRng=n)}},a.bind(document,"selectionchange",r)))}),d.on("setcontent",function(){d.lastRng=null}),d.on("mousedown",function(){d.selection.lastFocusBookmark=null}),d.on("focusin",function(){var t=e.focusedEditor;d.selection.lastFocusBookmark&&(d.selection.setRng(c(d,d.selection.lastFocusBookmark)),d.selection.lastFocusBookmark=null),t!=d&&(t&&t.fire("blur",{focusedEditor:d}),e.activeEditor=d,e.focusedEditor=d,d.fire("focus",{blurredEditor:t}),d.focus(!0)),d.lastRng=null}),d.on("focusout",function(){window.setTimeout(function(){var t=e.focusedEditor;u(s())||t!=d||(d.fire("blur",{focusedEditor:null}),e.focusedEditor=null,d.selection&&(d.selection.lastFocusBookmark=null))},0)}),i||(i=function(t){var n=e.activeEditor;n&&t.target.ownerDocument==document&&(n.selection&&(n.selection.lastFocusBookmark=l(n.dom,n.lastRng)),u(t.target)||e.focusedEditor!=n||(n.fire("blur",{focusedEditor:null}),e.focusedEditor=null))},a.bind(document,"focusin",i)),d.inline&&!o&&(o=function(t){var n=e.activeEditor;if(n.inline&&!n.dom.isChildOf(t.target,n.getBody())){var r=n.selection.getRng();r.collapsed||(n.lastRng=r)}},a.bind(document,"mouseup",o))}function f(t){e.focusedEditor==t.editor&&(e.focusedEditor=null),e.activeEditor||(a.unbind(document,"selectionchange",r),a.unbind(document,"focusin",i),a.unbind(document,"mouseup",o),r=i=o=null)}e.on("AddEditor",d),e.on("RemoveEditor",f)}var r,i,o,a=e.DOM;return n.isEditorUIElement=function(e){return-1!==e.className.toString().indexOf("mce-")},n}),r(dt,[lt,y,F,g,p,ot,ct,ut],function(e,t,n,r,i,o,a,s){function l(e){var t=g.editors,n;delete t[e.id];for(var r=0;r0&&f(d(c),function(n){u.get(n)?(m=new e(n,t,s),l.push(m),m.render()):f(document.forms,function(e){f(e.elements,function(e){e.name===n&&(n="mce_editor_"+h++,u.setAttrib(e,"id",n),r(n,t))})})});break;case"textareas":case"specific_textareas":f(u.select("textarea"),function(e){t.editor_deselector&&o(e,t.editor_deselector)||(!t.editor_selector||o(e,t.editor_selector))&&r(n(e),t)})}t.oninit&&(c=g=0,f(l,function(e){g++,e.initialized?c++:e.on("init",function(){c++,c==g&&i(t,"oninit")}),c==g&&i(t,"oninit")}))}var s=this,l=[],m;s.settings=t,u.bind(window,"ready",a)},get:function(e){return arguments.length?e in this.editors?this.editors[e]:null:this.editors},add:function(e){var t=this,n=t.editors;return n[e.id]=e,n.push(e),t.activeEditor=e,t.fire("AddEditor",{editor:e}),m||(m=function(){t.fire("BeforeUnload")},u.bind(window,"beforeunload",m)),e},createEditor:function(t,n){return this.add(new e(t,n,this))},remove:function(e){var t=this,n,r=t.editors,i;{if(e)return"string"==typeof e?(e=e.selector||e,void f(u.select(e),function(e){t.remove(r[e.id])})):(i=e,r[i.id]?(l(i)&&t.fire("RemoveEditor",{editor:i}),r.length||u.unbind(window,"beforeunload",m),i.remove(),i):null);for(n=r.length-1;n>=0;n--)t.remove(r[n])}},execCommand:function(t,n,r){var i=this,o=i.get(r);switch(t){case"mceAddEditor":return i.get(r)||new e(r,i.settings,i).render(),!0;case"mceRemoveEditor":return o&&o.remove(),!0;case"mceToggleEditor":return o?(o.isHidden()?o.show():o.hide(),!0):(i.execCommand("mceAddEditor",0,r),!0)}return i.activeEditor?i.activeEditor.execCommand(t,n,r):!1},triggerSave:function(){f(this.editors,function(e){e.save()})},addI18n:function(e,t){a.add(e,t)},translate:function(e){return a.translate(e)}},p(g,o),g.setup(),window.tinymce=window.tinyMCE=g,g}),r(ft,[dt,p],function(e,t){var n=t.each,r=t.explode;e.on("AddEditor",function(e){var t=e.editor;t.on("preInit",function(){function e(e,t){n(t,function(t,n){t&&s.setStyle(e,n,t)}),s.rename(e,"span")}function i(e){s=t.dom,l.convert_fonts_to_spans&&n(s.select("font,u,strike",e.node),function(e){o[e.nodeName.toLowerCase()](s,e)})}var o,a,s,l=t.settings;l.inline_styles&&(a=r(l.font_size_legacy_values),o={font:function(t,n){e(n,{backgroundColor:n.style.backgroundColor,color:n.color,fontFamily:n.face,fontSize:a[parseInt(n.size,10)-1]})},u:function(t,n){e(n,{textDecoration:"underline"})},strike:function(t,n){e(n,{textDecoration:"line-through"})}},t.on("PreProcess SetContent",i))})})}),r(pt,[],function(){return{send:function(e){function t(){!e.async||4==n.readyState||r++>1e4?(e.success&&1e4>r&&200==n.status?e.success.call(e.success_scope,""+n.responseText,n,e):e.error&&e.error.call(e.error_scope,r>1e4?"TIMED_OUT":"GENERAL",n,e),n=null):setTimeout(t,10)}var n,r=0;if(e.scope=e.scope||this,e.success_scope=e.success_scope||e.scope,e.error_scope=e.error_scope||e.scope,e.async=e.async===!1?!1:!0,e.data=e.data||"",n=new XMLHttpRequest){if(n.overrideMimeType&&n.overrideMimeType(e.content_type),n.open(e.type||(e.data?"POST":"GET"),e.url,e.async),e.content_type&&n.setRequestHeader("Content-Type",e.content_type),n.setRequestHeader("X-Requested-With","XMLHttpRequest"),n.send(e.data),!e.async)return t();setTimeout(t,10)}}}}),r(ht,[],function(){function e(t,n){var r,i,o,a;if(n=n||'"',null===t)return"null";if(o=typeof t,"string"==o)return i="\bb t\nn\ff\rr\"\"''\\\\",n+t.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g,function(e,t){return'"'===n&&"'"===e?e:(r=i.indexOf(t),r+1?"\\"+i.charAt(r+1):(e=t.charCodeAt().toString(16),"\\u"+"0000".substring(e.length)+e))})+n;if("object"==o){if(t.hasOwnProperty&&"[object Array]"===Object.prototype.toString.call(t)){for(r=0,i="[";r0?",":"")+e(t[r],n);return i+"]"}i="{";for(a in t)t.hasOwnProperty(a)&&(i+="function"!=typeof t[a]?(i.length>1?","+n:n)+a+n+":"+e(t[a],n):"");return i+"}"}return""+t}return{serialize:e,parse:function(e){try{return window[String.fromCharCode(101)+"val"]("("+e+")")}catch(t){}}}}),r(mt,[ht,pt,p],function(e,t,n){function r(e){this.settings=i({},e),this.count=0}var i=n.extend;return r.sendRPC=function(e){return(new r).send(e)},r.prototype={send:function(n){var r=n.error,o=n.success;n=i(this.settings,n),n.success=function(t,i){t=e.parse(t),"undefined"==typeof t&&(t={error:"JSON Parse error."}),t.error?r.call(n.error_scope||n.scope,t.error,i):o.call(n.success_scope||n.scope,t.result)},n.error=function(e,t){r&&r.call(n.error_scope||n.scope,e,t)},n.data=e.serialize({id:n.id||"c"+this.count++,method:n.method,params:n.params}),n.content_type="application/json",t.send(n)}},r}),r(gt,[y],function(e){return{callbacks:{},count:0,send:function(n){var r=this,i=e.DOM,o=n.count!==t?n.count:r.count,a="tinymce_jsonp_"+o;r.callbacks[o]=function(e){i.remove(a),delete r.callbacks[o],n.callback(e)},i.add(i.doc.body,"script",{id:a,src:n.url,type:"text/javascript"}),r.count++}}}),r(vt,[],function(){function e(){s=[];for(var e in a)s.push(e);i.length=s.length}function n(){function n(e){var n,r;return r=e!==t?u+e:i.indexOf(",",u),-1===r||r>i.length?null:(n=i.substring(u,r),u=r+1,n)}var r,i,s,u=0;if(a={},c){o.load(l),i=o.getAttribute(l)||"";do{var d=n();if(null===d)break;if(r=n(parseInt(d,32)||0),null!==r){if(d=n(),null===d)break;s=n(parseInt(d,32)||0),r&&(a[r]=s)}}while(null!==r);e()}}function r(){var t,n="";if(c){for(var r in a)t=a[r],n+=(n?",":"")+r.length.toString(32)+","+r+","+t.length.toString(32)+","+t;o.setAttribute(l,n);try{o.save(l)}catch(i){}e()}}var i,o,a,s,l,c;try{if(window.localStorage)return localStorage}catch(u){}return l="tinymce",o=document.documentElement,c=!!o.addBehavior,c&&o.addBehavior("#default#userData"),i={key:function(e){return s[e]},getItem:function(e){return e in a?a[e]:null},setItem:function(e,t){a[e]=""+t,r()},removeItem:function(e){delete a[e],r()},clear:function(){a={},r()}},n(),i}),r(yt,[y,l,b,C,p,g],function(e,t,n,r,i,o){var a=window.tinymce;return a.DOM=e.DOM,a.ScriptLoader=n.ScriptLoader,a.PluginManager=r.PluginManager,a.ThemeManager=r.ThemeManager,a.dom=a.dom||{},a.dom.Event=t.Event,i.each(i,function(e,t){a[t]=e}),i.each("isOpera isWebKit isIE isGecko isMac".split(" "),function(e){a[e]=o[e.substr(2).toLowerCase()]}),{}}),r(bt,[z,p],function(e,t){return e.extend({Defaults:{firstControlClass:"first",lastControlClass:"last"},init:function(e){this.settings=t.extend({},this.Defaults,e)},preRender:function(e){e.addClass(this.settings.containerClass,"body")},applyClasses:function(e){var t=this,n=t.settings,r,i,o;r=e.items().filter(":visible"),i=n.firstControlClass,o=n.lastControlClass,r.each(function(e){e.removeClass(i).removeClass(o),n.controlClass&&e.addClass(n.controlClass)}),r.eq(0).addClass(i),r.eq(-1).addClass(o)},renderHtml:function(e){var t=this,n=t.settings,r,i="";return r=e.items(),r.eq(0).addClass(n.firstControlClass),r.eq(-1).addClass(n.lastControlClass),r.each(function(e){n.controlClass&&e.addClass(n.controlClass),i+=e.renderHtml()}),i},recalc:function(){},postRender:function(){}})}),r(Ct,[bt],function(e){return e.extend({Defaults:{containerClass:"abs-layout",controlClass:"abs-layout-item"},recalc:function(e){e.items().filter(":visible").each(function(e){var t=e.settings;e.layoutRect({x:t.x,y:t.y,w:t.w,h:t.h}),e.recalc&&e.recalc()})},renderHtml:function(e){return'
    '+this._super(e)}})}),r(xt,[$,Q],function(e,t){return e.extend({Mixins:[t],Defaults:{classes:"widget tooltip tooltip-n"},text:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t._rendered&&(t.getEl().lastChild.innerHTML=t.encode(e)),t):t._value},renderHtml:function(){var e=this,t=e.classPrefix;return'"},repaint:function(){var e=this,t,n;t=e.getEl().style,n=e._layoutRect,t.left=n.x+"px",t.top=n.y+"px",t.zIndex=131070}})}),r(wt,[$,xt],function(e,t){var n,r=e.extend({init:function(e){var t=this;t._super(e),e=t.settings,t.canFocus=!0,e.tooltip&&r.tooltips!==!1&&(t.on("mouseenter",function(n){var r=t.tooltip().moveTo(-65535);if(n.control==t){var i=r.text(e.tooltip).show().testMoveRel(t.getEl(),["bc-tc","bc-tl","bc-tr"]);r.toggleClass("tooltip-n","bc-tc"==i),r.toggleClass("tooltip-nw","bc-tl"==i),r.toggleClass("tooltip-ne","bc-tr"==i),r.moveRel(t.getEl(),i)}else r.hide()}),t.on("mouseleave mousedown click",function(){t.tooltip().hide()})),t.aria("label",e.ariaLabel||e.tooltip)},tooltip:function(){return n||(n=new t({type:"tooltip"}),n.renderTo()),n},active:function(e){var t=this,n;return e!==n&&(t.aria("pressed",e),t.toggleClass("active",e)),t._super(e)},disabled:function(e){var t=this,n;return e!==n&&(t.aria("disabled",e),t.toggleClass("disabled",e)),t._super(e)},postRender:function(){var e=this,t=e.settings;e._rendered=!0,e._super(),e.parent()||!t.width&&!t.height||(e.initLayoutRect(),e.repaint()),t.autofocus&&e.focus()},remove:function(){this._super(),n&&(n.remove(),n=null)}});return r}),r(_t,[wt],function(e){return e.extend({Defaults:{classes:"widget btn",role:"button"},init:function(e){var t=this,n;t.on("click mousedown",function(e){e.preventDefault()}),t._super(e),n=e.size,e.subtype&&t.addClass(e.subtype),n&&t.addClass("btn-"+n)},icon:function(e){var t=this,n=t.classPrefix;if("undefined"==typeof e)return t.settings.icon;if(t.settings.icon=e,e=e?n+"ico "+n+"i-"+t.settings.icon:"",t._rendered){var r=t.getEl().firstChild,i=r.getElementsByTagName("i")[0];e?(i&&i==r.firstChild||(i=document.createElement("i"),r.insertBefore(i,r.firstChild)),i.className=e):i&&r.removeChild(i),t.text(t._text)}return t},repaint:function(){var e=this.getEl().firstChild.style;e.width=e.height="100%",this._super()},text:function(e){var t=this;if(t._rendered){var n=t.getEl().lastChild.lastChild;n&&(n.data=t.translate(e))}return t._super(e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon,i;return i=e.settings.image,i?(r="none","string"!=typeof i&&(i=window.getSelection?i[0]:i[1]),i=" style=\"background-image: url('"+i+"')\""):i="",r=e.settings.icon?n+"ico "+n+"i-"+r:"",'
    "}})}),r(Nt,[G],function(e){return e.extend({Defaults:{defaultType:"button",role:"group"},renderHtml:function(){var e=this,t=e._layout;return e.addClass("btn-group"),e.preRender(),t.preRender(e),'
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "}})}),r(Et,[wt],function(e){return e.extend({Defaults:{classes:"checkbox",role:"checkbox",checked:!1},init:function(e){var t=this;t._super(e),t.on("click mousedown",function(e){e.preventDefault()}),t.on("click",function(e){e.preventDefault(),t.disabled()||t.checked(!t.checked())}),t.checked(t.settings.checked)},checked:function(e){var t=this;return"undefined"!=typeof e?(e?t.addClass("checked"):t.removeClass("checked"),t._checked=e,t.aria("checked",e),t):t._checked},value:function(e){return this.checked(e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix;return'
    '+e.encode(e._text)+"
    "}})}),r(St,[_t,et],function(e,t){return e.extend({showPanel:function(){var e=this,n=e.settings;if(e.active(!0),e.panel)e.panel.show();else{var r=n.panel;r.type&&(r={layout:"grid",items:r}),r.role=r.role||"dialog",r.popover=!0,r.autohide=!0,r.ariaRoot=!0,e.panel=new t(r).on("hide",function(){e.active(!1)}).on("cancel",function(t){t.stopPropagation(),e.focus(),e.hidePanel()}).parent(e).renderTo(e.getContainerElm()),e.panel.fire("show"),e.panel.reflow()}e.panel.moveRel(e.getEl(),n.popoverAlign||(e.isRtl()?["bc-tr","bc-tc"]:["bc-tl","bc-tc"]))},hidePanel:function(){var e=this;e.panel&&e.panel.hide()},postRender:function(){var e=this;return e.aria("haspopup",!0),e.on("click",function(t){t.control===e&&(e.panel&&e.panel.visible()?e.hidePanel():(e.showPanel(),e.panel.focus(!!t.aria)))}),e._super()}})}),r(kt,[St,y],function(e,t){var n=t.DOM;return e.extend({init:function(e){this._super(e),this.addClass("colorbutton")},color:function(e){return e?(this._color=e,this.getEl("preview").style.backgroundColor=e,this):this._color},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon?n+"ico "+n+"i-"+e.settings.icon:"",i=e.settings.image?" style=\"background-image: url('"+e.settings.image+"')\"":"";return'
    '},postRender:function(){var e=this,t=e.settings.onclick;return e.on("click",function(r){r.aria&&"down"==r.aria.key||r.control!=e||n.getParent(r.target,"."+e.classPrefix+"open")||(r.stopImmediatePropagation(),t.call(e,r))}),delete e.settings.onclick,e._super()}})}),r(Tt,[wt,j,q],function(e,t,n){return e.extend({init:function(e){var t=this;t._super(e),t.addClass("combobox"),t.subinput=!0,t.ariaTarget="inp",e=t.settings,e.menu=e.menu||e.values,e.menu&&(e.icon="caret"),t.on("click",function(n){for(var r=n.target,i=t.getEl();r&&r!=i;)r.id&&-1!=r.id.indexOf("-open")&&(t.fire("action"),e.menu&&(t.showMenu(),n.aria&&t.menu.items()[0].focus())),r=r.parentNode}),t.on("keydown",function(e){"INPUT"==e.target.nodeName&&13==e.keyCode&&t.parents().reverse().each(function(n){return e.preventDefault(),t.fire("change"),n.hasEventListeners("submit")&&n.toJSON?(n.fire("submit",{data:n.toJSON()}),!1):void 0})}),e.placeholder&&(t.addClass("placeholder"),t.on("focusin",function(){t._hasOnChange||(n.on(t.getEl("inp"),"change",function(){t.fire("change")}),t._hasOnChange=!0),t.hasClass("placeholder")&&(t.getEl("inp").value="",t.removeClass("placeholder"))}),t.on("focusout",function(){0===t.value().length&&(t.getEl("inp").value=e.placeholder,t.addClass("placeholder"))}))},showMenu:function(){var e=this,n=e.settings,r;e.menu||(r=n.menu||[],r.length?r={type:"menu",items:r}:r.type=r.type||"menu",e.menu=t.create(r).parent(e).renderTo(e.getContainerElm()),e.fire("createmenu"),e.menu.reflow(),e.menu.on("cancel",function(t){t.control===e.menu&&e.focus()}),e.menu.on("show hide",function(t){t.control.items().each(function(t){t.active(t.value()==e.value())})}).fire("show"),e.menu.on("select",function(t){e.value(t.control.value())}),e.on("focusin",function(t){"INPUT"==t.target.tagName.toUpperCase()&&e.menu.hide()}),e.aria("expanded",!0)),e.menu.show(),e.menu.layoutRect({w:e.layoutRect().w}),e.menu.moveRel(e.getEl(),e.isRtl()?["br-tr","tr-br"]:["bl-tl","tl-bl"])},value:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t.removeClass("placeholder"),t._rendered&&(t.getEl("inp").value=e),t):t._rendered?(e=t.getEl("inp").value,e!=t.settings.placeholder?e:""):t._value},disabled:function(e){var t=this;return t._rendered&&"undefined"!=typeof e&&(t.getEl("inp").disabled=e),t._super(e)},focus:function(){this.getEl("inp").focus()},repaint:function(){var e=this,t=e.getEl(),r=e.getEl("open"),i=e.layoutRect(),o,a;o=r?i.w-n.getSize(r).width-10:i.w-10;var s=document;return s.all&&(!s.documentMode||s.documentMode<=8)&&(a=e.layoutRect().h-2+"px"),n.css(t.firstChild,{width:o,lineHeight:a}),e._super(),e},postRender:function(){var e=this;return n.on(this.getEl("inp"),"change",function(){e.fire("change")}),e._super()},remove:function(){n.off(this.getEl("inp")),this._super()},renderHtml:function(){var e=this,t=e._id,n=e.settings,r=e.classPrefix,i=n.value||n.placeholder||"",o,a,s="",l="";return"spellcheck"in n&&(l+=' spellcheck="'+n.spellcheck+'"'),n.maxLength&&(l+=' maxlength="'+n.maxLength+'"'),n.size&&(l+=' size="'+n.size+'"'),n.subtype&&(l+=' type="'+n.subtype+'"'),e.disabled()&&(l+=' disabled="disabled"'),o=n.icon,o&&"caret"!=o&&(o=r+"ico "+r+"i-"+n.icon),a=e._text,(o||a)&&(s='
    ",e.addClass("has-open")),'
    "+s+"
    " +}})}),r(Rt,[wt],function(e){return e.extend({init:function(e){var t=this;e.delimiter||(e.delimiter="\xbb"),t._super(e),t.addClass("path"),t.canFocus=!0,t.on("click",function(e){var n,r=e.target;(n=r.getAttribute("data-index"))&&t.fire("select",{value:t.data()[n],index:n})})},focus:function(){var e=this;return e.getEl().firstChild.focus(),e},data:function(e){var t=this;return"undefined"!=typeof e?(t._data=e,t.update(),t):t._data},update:function(){this.innerHtml(this._getPathHtml())},postRender:function(){var e=this;e._super(),e.data(e.settings.data)},renderHtml:function(){var e=this;return'
    '+e._getPathHtml()+"
    "},_getPathHtml:function(){var e=this,t=e._data||[],n,r,i="",o=e.classPrefix;for(n=0,r=t.length;r>n;n++)i+=(n>0?'":"")+'
    '+t[n].name+"
    ";return i||(i='
    \xa0
    '),i}})}),r(At,[Rt,dt],function(e,t){return e.extend({postRender:function(){function e(e){if(1===e.nodeType){if("BR"==e.nodeName||e.getAttribute("data-mce-bogus"))return!0;if("bookmark"===e.getAttribute("data-mce-type"))return!0}return!1}var n=this,r=t.activeEditor;return n.on("select",function(t){var n=[],i,o=r.getBody();for(r.focus(),i=r.selection.getStart();i&&i!=o;)e(i)||n.push(i),i=i.parentNode;r.selection.select(n[n.length-1-t.index]),r.nodeChanged()}),r.on("nodeChange",function(t){for(var i=[],o=t.parents,a=o.length;a--;)if(1==o[a].nodeType&&!e(o[a])){var s=r.fire("ResolveName",{name:o[a].nodeName.toLowerCase(),target:o[a]});i.push({name:s.name})}n.data(i)}),n._super()}})}),r(Bt,[G],function(e){return e.extend({Defaults:{layout:"flex",align:"center",defaults:{flex:1}},renderHtml:function(){var e=this,t=e._layout,n=e.classPrefix;return e.addClass("formitem"),t.preRender(e),'
    '+(e.settings.title?'
    '+e.settings.title+"
    ":"")+'
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "}})}),r(Dt,[G,Bt],function(e,t){return e.extend({Defaults:{containerCls:"form",layout:"flex",direction:"column",align:"stretch",flex:1,padding:20,labelGap:30,spacing:10,callbacks:{submit:function(){this.submit()}}},preRender:function(){var e=this,n=e.items();n.each(function(n){var r,i=n.settings.label;i&&(r=new t({layout:"flex",autoResize:"overflow",defaults:{flex:1},items:[{type:"label",id:n._id+"-l",text:i,flex:0,forId:n._id,disabled:n.disabled()}]}),r.type="formitem",n.aria("labelledby",n._id+"-l"),"undefined"==typeof n.settings.flex&&(n.settings.flex=1),e.replace(n,r),r.add(n))})},recalcLabels:function(){var e=this,t=0,n=[],r,i;if(e.settings.labelGapCalc!==!1)for(e.items().filter("formitem").each(function(e){var r=e.items()[0],i=r.getEl().clientWidth;t=i>t?i:t,n.push(r)}),i=e.settings.labelGap||0,r=n.length;r--;)n[r].settings.minWidth=t+i},visible:function(e){var t=this._super(e);return e===!0&&this._rendered&&this.recalcLabels(),t},submit:function(){return this.fire("submit",{data:this.toJSON()})},postRender:function(){var e=this;e._super(),e.recalcLabels(),e.fromJSON(e.settings.data)}})}),r(Lt,[Dt],function(e){return e.extend({Defaults:{containerCls:"fieldset",layout:"flex",direction:"column",align:"stretch",flex:1,padding:"25 15 5 15",labelGap:30,spacing:10,border:1},renderHtml:function(){var e=this,t=e._layout,n=e.classPrefix;return e.preRender(),t.preRender(e),'
    '+(e.settings.title?''+e.settings.title+"":"")+'
    '+(e.settings.html||"")+t.renderHtml(e)+"
    "}})}),r(Mt,[Tt],function(e){return e.extend({init:function(e){var t=this,n=tinymce.activeEditor,r;e.spellcheck=!1,r=n.settings.file_browser_callback,r&&(e.icon="browse",e.onaction=function(){r(t.getEl("inp").id,t.getEl("inp").value,e.filetype,window)}),t._super(e)}})}),r(Ht,[Ct],function(e){return e.extend({recalc:function(e){var t=e.layoutRect(),n=e.paddingBox();e.items().filter(":visible").each(function(e){e.layoutRect({x:n.left,y:n.top,w:t.innerW-n.right-n.left,h:t.innerH-n.top-n.bottom}),e.recalc&&e.recalc()})}})}),r(Pt,[Ct],function(e){return e.extend({recalc:function(e){var t,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v=[],y,b,C,x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I,F,z=Math.max,W=Math.min;for(r=e.items().filter(":visible"),i=e.layoutRect(),o=e._paddingBox,a=e.settings,f=e.isRtl()?a.direction||"row-reversed":a.direction,s=a.align,l=e.isRtl()?a.pack||"end":a.pack,c=a.spacing||0,("row-reversed"==f||"column-reverse"==f)&&(r=r.set(r.toArray().reverse()),f=f.split("-")[0]),"column"==f?(S="y",N="h",E="minH",k="maxH",R="innerH",T="top",A="deltaH",B="contentH",P="left",M="w",D="x",L="innerW",H="minW",O="right",I="deltaW",F="contentW"):(S="x",N="w",E="minW",k="maxW",R="innerW",T="left",A="deltaW",B="contentW",P="top",M="h",D="y",L="innerH",H="minH",O="bottom",I="deltaH",F="contentH"),d=i[R]-o[T]-o[T],_=u=0,t=0,n=r.length;n>t;t++)p=r[t],h=p.layoutRect(),m=p.settings,g=m.flex,d-=n-1>t?c:0,g>0&&(u+=g,h[k]&&v.push(p),h.flex=g),d-=h[E],y=o[P]+h[H]+o[O],y>_&&(_=y);if(x={},x[E]=0>d?i[E]-d+i[A]:i[R]-d+i[A],x[H]=_+i[I],x[B]=i[R]-d,x[F]=_,x.minW=W(x.minW,i.maxW),x.minH=W(x.minH,i.maxH),x.minW=z(x.minW,i.startMinWidth),x.minH=z(x.minH,i.startMinHeight),!i.autoResize||x.minW==i.minW&&x.minH==i.minH){for(C=d/u,t=0,n=v.length;n>t;t++)p=v[t],h=p.layoutRect(),b=h[k],y=h[E]+h.flex*C,y>b?(d-=h[k]-h[E],u-=h.flex,h.flex=0,h.maxFlexSize=b):h.maxFlexSize=0;for(C=d/u,w=o[T],x={},0===u&&("end"==l?w=d+o[T]:"center"==l?(w=Math.round(i[R]/2-(i[R]-d)/2)+o[T],0>w&&(w=o[T])):"justify"==l&&(w=o[T],c=Math.floor(d/(r.length-1)))),x[D]=o[P],t=0,n=r.length;n>t;t++)p=r[t],h=p.layoutRect(),y=h.maxFlexSize||h[E],"center"===s?x[D]=Math.round(i[L]/2-h[M]/2):"stretch"===s?(x[M]=z(h[H]||0,i[L]-o[P]-o[O]),x[D]=o[P]):"end"===s&&(x[D]=i[L]-h[M]-o.top),h.flex>0&&(y+=h.flex*C),x[N]=y,x[S]=w,p.layoutRect(x),p.recalc&&p.recalc(),w+=y+c}else if(x.w=x.minW,x.h=x.minH,e.layoutRect(x),this.recalc(e),null===e._lastRect){var V=e.parent();V&&(V._lastRect=null,V.recalc())}}})}),r(Ot,[bt],function(e){return e.extend({Defaults:{containerClass:"flow-layout",controlClass:"flow-layout-item",endClass:"break"},recalc:function(e){e.items().filter(":visible").each(function(e){e.recalc&&e.recalc()})}})}),r(It,[$,wt,et,p,dt,g],function(e,t,n,r,i,o){function a(e){function t(t,n){return function(){var r=this;e.on("nodeChange",function(i){var o=e.formatter,a=null;s(i.parents,function(e){return s(t,function(t){return n?o.matchNode(e,n,{value:t.value})&&(a=t.value):o.matchNode(e,t.value)&&(a=t.value),a?!1:void 0}),a?!1:void 0}),r.value(a)})}}function r(e){e=e.replace(/;$/,"").split(";");for(var t=e.length;t--;)e[t]=e[t].split("=");return e}function i(){function t(e){var n=[];if(e)return s(e,function(e){var o={text:e.title,icon:e.icon};if(e.items)o.menu=t(e.items);else{var a=e.format||"custom"+r++;e.format||(e.name=a,i.push(e)),o.format=a}n.push(o)}),n}function n(){var n;return n=t(e.settings.style_formats_merge?e.settings.style_formats?o.concat(e.settings.style_formats):o:e.settings.style_formats||o)}var r=0,i=[],o=[{title:"Headings",items:[{title:"Heading 1",format:"h1"},{title:"Heading 2",format:"h2"},{title:"Heading 3",format:"h3"},{title:"Heading 4",format:"h4"},{title:"Heading 5",format:"h5"},{title:"Heading 6",format:"h6"}]},{title:"Inline",items:[{title:"Bold",icon:"bold",format:"bold"},{title:"Italic",icon:"italic",format:"italic"},{title:"Underline",icon:"underline",format:"underline"},{title:"Strikethrough",icon:"strikethrough",format:"strikethrough"},{title:"Superscript",icon:"superscript",format:"superscript"},{title:"Subscript",icon:"subscript",format:"subscript"},{title:"Code",icon:"code",format:"code"}]},{title:"Blocks",items:[{title:"Paragraph",format:"p"},{title:"Blockquote",format:"blockquote"},{title:"Div",format:"div"},{title:"Pre",format:"pre"}]},{title:"Alignment",items:[{title:"Left",icon:"alignleft",format:"alignleft"},{title:"Center",icon:"aligncenter",format:"aligncenter"},{title:"Right",icon:"alignright",format:"alignright"},{title:"Justify",icon:"alignjustify",format:"alignjustify"}]}];return e.on("init",function(){s(i,function(t){e.formatter.register(t.name,t)})}),{type:"menu",items:n(),onPostRender:function(t){e.fire("renderFormatsMenu",{control:t.control})},itemDefaults:{preview:!0,textStyle:function(){return this.settings.format?e.formatter.getCssText(this.settings.format):void 0},onPostRender:function(){var t=this,n=this.settings.format;n&&t.parent().on("show",function(){t.disabled(!e.formatter.canApply(n)),t.active(e.formatter.match(n))})},onclick:function(){this.settings.format&&d(this.settings.format)}}}}function o(){return e.undoManager?e.undoManager.hasUndo():!1}function a(){return e.undoManager?e.undoManager.hasRedo():!1}function l(){var t=this;t.disabled(!o()),e.on("Undo Redo AddUndo TypingUndo",function(){t.disabled(!o())})}function c(){var t=this;t.disabled(!a()),e.on("Undo Redo AddUndo TypingUndo",function(){t.disabled(!a())})}function u(){var t=this;e.on("VisualAid",function(e){t.active(e.hasVisual)}),t.active(e.hasVisual)}function d(t){t.control&&(t=t.control.value()),t&&e.execCommand("mceToggleFormat",!1,t)}var f;f=i(),s({bold:"Bold",italic:"Italic",underline:"Underline",strikethrough:"Strikethrough",subscript:"Subscript",superscript:"Superscript"},function(t,n){e.addButton(n,{tooltip:t,onPostRender:function(){var t=this;e.formatter?e.formatter.formatChanged(n,function(e){t.active(e)}):e.on("init",function(){e.formatter.formatChanged(n,function(e){t.active(e)})})},onclick:function(){d(n)}})}),s({outdent:["Decrease indent","Outdent"],indent:["Increase indent","Indent"],cut:["Cut","Cut"],copy:["Copy","Copy"],paste:["Paste","Paste"],help:["Help","mceHelp"],selectall:["Select all","SelectAll"],hr:["Insert horizontal rule","InsertHorizontalRule"],removeformat:["Clear formatting","RemoveFormat"],visualaid:["Visual aids","mceToggleVisualAid"],newdocument:["New document","mceNewDocument"]},function(t,n){e.addButton(n,{tooltip:t[0],cmd:t[1]})}),s({blockquote:["Blockquote","mceBlockQuote"],numlist:["Numbered list","InsertOrderedList"],bullist:["Bullet list","InsertUnorderedList"],subscript:["Subscript","Subscript"],superscript:["Superscript","Superscript"],alignleft:["Align left","JustifyLeft"],aligncenter:["Align center","JustifyCenter"],alignright:["Align right","JustifyRight"],alignjustify:["Justify","JustifyFull"]},function(t,n){e.addButton(n,{tooltip:t[0],cmd:t[1],onPostRender:function(){var t=this;e.formatter?e.formatter.formatChanged(n,function(e){t.active(e)}):e.on("init",function(){e.formatter.formatChanged(n,function(e){t.active(e)})})}})}),e.addButton("undo",{tooltip:"Undo",onPostRender:l,cmd:"undo"}),e.addButton("redo",{tooltip:"Redo",onPostRender:c,cmd:"redo"}),e.addMenuItem("newdocument",{text:"New document",shortcut:"Ctrl+N",icon:"newdocument",cmd:"mceNewDocument"}),e.addMenuItem("undo",{text:"Undo",icon:"undo",shortcut:"Ctrl+Z",onPostRender:l,cmd:"undo"}),e.addMenuItem("redo",{text:"Redo",icon:"redo",shortcut:"Ctrl+Y",onPostRender:c,cmd:"redo"}),e.addMenuItem("visualaid",{text:"Visual aids",selectable:!0,onPostRender:u,cmd:"mceToggleVisualAid"}),s({cut:["Cut","Cut","Ctrl+X"],copy:["Copy","Copy","Ctrl+C"],paste:["Paste","Paste","Ctrl+V"],selectall:["Select all","SelectAll","Ctrl+A"],bold:["Bold","Bold","Ctrl+B"],italic:["Italic","Italic","Ctrl+I"],underline:["Underline","Underline"],strikethrough:["Strikethrough","Strikethrough"],subscript:["Subscript","Subscript"],superscript:["Superscript","Superscript"],removeformat:["Clear formatting","RemoveFormat"]},function(t,n){e.addMenuItem(n,{text:t[0],icon:n,shortcut:t[2],cmd:t[1]})}),e.on("mousedown",function(){n.hideAll()}),e.addButton("styleselect",{type:"menubutton",text:"Formats",menu:f}),e.addButton("formatselect",function(){var n=[],i=r(e.settings.block_formats||"Paragraph=p;Address=address;Pre=pre;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6");return s(i,function(t){n.push({text:t[0],value:t[1],textStyle:function(){return e.formatter.getCssText(t[1])}})}),{type:"listbox",text:i[0][0],values:n,fixedWidth:!0,onselect:d,onPostRender:t(n)}}),e.addButton("fontselect",function(){var n="Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",i=[],o=r(e.settings.font_formats||n);return s(o,function(e){i.push({text:{raw:e[0]},value:e[1],textStyle:-1==e[1].indexOf("dings")?"font-family:"+e[1]:""})}),{type:"listbox",text:"Font Family",tooltip:"Font Family",values:i,fixedWidth:!0,onPostRender:t(i,"fontname"),onselect:function(t){t.control.settings.value&&e.execCommand("FontName",!1,t.control.settings.value)}}}),e.addButton("fontsizeselect",function(){var n=[],r="8pt 10pt 12pt 14pt 18pt 24pt 36pt",i=e.settings.fontsize_formats||r;return s(i.split(" "),function(e){n.push({text:e,value:e})}),{type:"listbox",text:"Font Sizes",tooltip:"Font Sizes",values:n,fixedWidth:!0,onPostRender:t(n,"fontsize"),onclick:function(t){t.control.settings.value&&e.execCommand("FontSize",!1,t.control.settings.value)}}}),e.addMenuItem("formats",{text:"Formats",menu:f})}var s=r.each;i.on("AddEditor",function(t){t.editor.rtl&&(e.rtl=!0),a(t.editor)}),e.translate=function(e){return i.translate(e)},t.tooltips=!o.iOS}),r(Ft,[Ct],function(e){return e.extend({recalc:function(e){var t=e.settings,n,r,i,o,a,s,l,c,u,d,f,p,h,m,g,v,y,b,C,x,w,_,N=[],E=[],S,k,T,R;for(t=e.settings,i=e.items().filter(":visible"),o=e.layoutRect(),r=t.columns||Math.ceil(Math.sqrt(i.length)),n=Math.ceil(i.length/r),y=t.spacingH||t.spacing||0,b=t.spacingV||t.spacing||0,C=t.alignH||t.align,x=t.alignV||t.align,g=e._paddingBox,C&&"string"==typeof C&&(C=[C]),x&&"string"==typeof x&&(x=[x]),d=0;r>d;d++)N.push(0);for(f=0;n>f;f++)E.push(0);for(f=0;n>f;f++)for(d=0;r>d&&(u=i[f*r+d],u);d++)c=u.layoutRect(),S=c.minW,k=c.minH,N[d]=S>N[d]?S:N[d],E[f]=k>E[f]?k:E[f];for(T=o.innerW-g.left-g.right,w=0,d=0;r>d;d++)w+=N[d]+(d>0?y:0),T-=(d>0?y:0)+N[d];for(R=o.innerH-g.top-g.bottom,_=0,f=0;n>f;f++)_+=E[f]+(f>0?b:0),R-=(f>0?b:0)+E[f];if(w+=g.left+g.right,_+=g.top+g.bottom,l={},l.minW=w+(o.w-o.innerW),l.minH=_+(o.h-o.innerH),l.contentW=l.minW-o.deltaW,l.contentH=l.minH-o.deltaH,l.minW=Math.min(l.minW,o.maxW),l.minH=Math.min(l.minH,o.maxH),l.minW=Math.max(l.minW,o.startMinWidth),l.minH=Math.max(l.minH,o.startMinHeight),!o.autoResize||l.minW==o.minW&&l.minH==o.minH){o.autoResize&&(l=e.layoutRect(l),l.contentW=l.minW-o.deltaW,l.contentH=l.minH-o.deltaH);var A;A="start"==t.packV?0:R>0?Math.floor(R/n):0;var B=0,D=t.flexWidths;if(D)for(d=0;dd;d++)N[d]+=D?D[d]*L:L;for(h=g.top,f=0;n>f;f++){for(p=g.left,s=E[f]+A,d=0;r>d&&(u=i[f*r+d],u);d++)m=u.settings,c=u.layoutRect(),a=Math.max(N[d],c.startMinWidth),c.x=p,c.y=h,v=m.alignH||(C?C[d]||C[0]:null),"center"==v?c.x=p+a/2-c.w/2:"right"==v?c.x=p+a-c.w:"stretch"==v&&(c.w=a),v=m.alignV||(x?x[d]||x[0]:null),"center"==v?c.y=h+s/2-c.h/2:"bottom"==v?c.y=h+s-c.h:"stretch"==v&&(c.h=s),u.layoutRect(c),p+=a+y,u.recalc&&u.recalc();h+=s+b}}else if(l.w=l.minW,l.h=l.minH,e.layoutRect(l),this.recalc(e),null===e._lastRect){var M=e.parent();M&&(M._lastRect=null,M.recalc())}}})}),r(zt,[wt],function(e){return e.extend({renderHtml:function(){var e=this;return e.addClass("iframe"),e.canFocus=!1,''},src:function(e){this.getEl().src=e},html:function(e,t){var n=this,r=this.getEl().contentWindow.document.body;return r?(r.innerHTML=e,t&&t()):setTimeout(function(){n.html(e)},0),this}})}),r(Wt,[wt,q],function(e,t){return e.extend({init:function(e){var t=this;t._super(e),t.addClass("widget"),t.addClass("label"),t.canFocus=!1,e.multiline&&t.addClass("autoscroll"),e.strong&&t.addClass("strong")},initLayoutRect:function(){var e=this,n=e._super();if(e.settings.multiline){var r=t.getSize(e.getEl());r.width>n.maxW&&(n.minW=n.maxW,e.addClass("multiline")),e.getEl().style.width=n.minW+"px",n.startMinH=n.h=n.minH=Math.min(n.maxH,t.getSize(e.getEl()).height)}return n},repaint:function(){var e=this;return e.settings.multiline||(e.getEl().style.lineHeight=e.layoutRect().h+"px"),e._super()},text:function(e){var t=this;return t._rendered&&e&&this.innerHtml(t.encode(e)),t._super(e)},renderHtml:function(){var e=this,t=e.settings.forId;return'"}})}),r(Vt,[G],function(e){return e.extend({Defaults:{role:"toolbar",layout:"flow"},init:function(e){var t=this;t._super(e),t.addClass("toolbar")},postRender:function(){var e=this;return e.items().addClass("toolbar-item"),e._super()}})}),r(Ut,[Vt],function(e){return e.extend({Defaults:{role:"menubar",containerCls:"menubar",ariaRoot:!0,defaults:{type:"menubutton"}}})}),r(qt,[_t,j,Ut],function(e,t,n){function r(e,t){for(;e;){if(t===e)return!0;e=e.parentNode}return!1}var i=e.extend({init:function(e){var t=this;t._renderOpen=!0,t._super(e),t.addClass("menubtn"),e.fixedWidth&&t.addClass("fixed-width"),t.aria("haspopup",!0),t.hasPopup=!0},showMenu:function(){var e=this,n=e.settings,r;return e.menu&&e.menu.visible()?e.hideMenu():(e.menu||(r=n.menu||[],r.length?r={type:"menu",items:r}:r.type=r.type||"menu",e.menu=t.create(r).parent(e).renderTo(),e.fire("createmenu"),e.menu.reflow(),e.menu.on("cancel",function(t){t.control.parent()===e.menu&&(t.stopPropagation(),e.focus(),e.hideMenu())}),e.menu.on("select",function(){e.focus()}),e.menu.on("show hide",function(t){t.control==e.menu&&e.activeMenu("show"==t.type),e.aria("expanded","show"==t.type)}).fire("show")),e.menu.show(),e.menu.layoutRect({w:e.layoutRect().w}),void e.menu.moveRel(e.getEl(),e.isRtl()?["br-tr","tr-br"]:["bl-tl","tl-bl"]))},hideMenu:function(){var e=this;e.menu&&(e.menu.items().each(function(e){e.hideMenu&&e.hideMenu()}),e.menu.hide())},activeMenu:function(e){this.toggleClass("active",e)},renderHtml:function(){var e=this,t=e._id,r=e.classPrefix,i=e.settings.icon?r+"ico "+r+"i-"+e.settings.icon:"";return e.aria("role",e.parent()instanceof n?"menuitem":"button"),'
    '},postRender:function(){var e=this;return e.on("click",function(t){t.control===e&&r(t.target,e.getEl())&&(e.showMenu(),t.aria&&e.menu.items()[0].focus())}),e.on("mouseenter",function(t){var n=t.control,r=e.parent(),o;n&&r&&n instanceof i&&n.parent()==r&&(r.items().filter("MenuButton").each(function(e){e.hideMenu&&e!=n&&(e.menu&&e.menu.visible()&&(o=!0),e.hideMenu())}),o&&(n.focus(),n.showMenu()))}),e._super()},text:function(e){var t=this,n,r;if(t._rendered)for(r=t.getEl("open").getElementsByTagName("span"),n=0;n0&&(o=n[0].text,t._value=n[0].value),e.menu=n}e.text=e.text||o||n[0].text,t._super(e),t.addClass("listbox"),t.on("select",function(n){var r=n.control;a&&(n.lastControl=a),e.multiple?r.active(!r.active()):t.value(n.control.settings.value),a=r})},value:function(e){function t(e,n){e.items().each(function(e){r=e.value()===n,r&&(i=i||e.text()),e.active(r),e.menu&&t(e.menu,n)})}var n=this,r,i,o,a;if("undefined"!=typeof e){if(n.menu)t(n.menu,e);else for(o=n.settings.menu,a=0;a'+("-"!==o?'\xa0":"")+("-"!==o?''+o+"":"")+(l?'
    '+l+"
    ":"")+(r.menu?'
    ':"")+""},postRender:function(){var e=this,t=e.settings,n=t.textStyle;if("function"==typeof n&&(n=n.call(this)),n){var r=e.getEl("text");r&&r.setAttribute("style",n)}return e.on("mouseenter click",function(n){n.control===e&&(t.menu||"click"!==n.type?(e.showMenu(),n.aria&&e.menu.focus(!0)):(e.fire("select"),e.parent().hideAll()))}),e._super(),e},active:function(e){return"undefined"!=typeof e&&this.aria("checked",e),this._super(e)},remove:function(){this._super(),this.menu&&this.menu.remove()}})}),r(Kt,[et,jt,p],function(e,t,n){var r=e.extend({Defaults:{defaultType:"menuitem",border:1,layout:"stack",role:"application",bodyRole:"menu",ariaRoot:!0},init:function(e){var t=this;if(e.autohide=!0,e.constrainToViewport=!0,e.itemDefaults)for(var r=e.items,i=r.length;i--;)r[i]=n.extend({},e.itemDefaults,r[i]);t._super(e),t.addClass("menu")},repaint:function(){return this.toggleClass("menu-align",!0),this._super(),this.getEl().style.height="",this.getEl("body").style.height="",this},cancel:function(){var e=this;e.hideAll(),e.fire("select")},hideAll:function(){var e=this;return this.find("menuitem").exec("hideMenu"),e._super()},preRender:function(){var e=this;return e.items().each(function(t){var n=t.settings;return n.icon||n.selectable?(e._hasIcons=!0,!1):void 0}),e._super()}});return r}),r(Gt,[Et],function(e){return e.extend({Defaults:{classes:"radio",role:"radio"}})}),r(Yt,[wt,Y],function(e,t){return e.extend({renderHtml:function(){var e=this,t=e.classPrefix;return e.addClass("resizehandle"),"both"==e.settings.direction&&e.addClass("resizehandle-both"),e.canFocus=!1,'
    '},postRender:function(){var e=this;e._super(),e.resizeDragHelper=new t(this._id,{start:function(){e.fire("ResizeStart")},drag:function(t){"both"!=e.settings.direction&&(t.deltaX=0),e.fire("Resize",t)},stop:function(){e.fire("ResizeEnd")}})},remove:function(){return this.resizeDragHelper&&this.resizeDragHelper.destroy(),this._super()}})}),r(Xt,[wt],function(e){return e.extend({renderHtml:function(){var e=this;return e.addClass("spacer"),e.canFocus=!1,'
    '}})}),r(Jt,[qt,q],function(e,t){return e.extend({Defaults:{classes:"widget btn splitbtn",role:"button"},repaint:function(){var e=this,n=e.getEl(),r=e.layoutRect(),i,o;return e._super(),i=n.firstChild,o=n.lastChild,t.css(i,{width:r.w-t.getSize(o).width,height:r.h-2}),t.css(o,{height:r.h-2}),e},activeMenu:function(e){var n=this;t.toggleClass(n.getEl().lastChild,n.classPrefix+"active",e)},renderHtml:function(){var e=this,t=e._id,n=e.classPrefix,r=e.settings.icon?n+"ico "+n+"i-"+e.settings.icon:"";return'
    '},postRender:function(){var e=this,t=e.settings.onclick;return e.on("click",function(e){var n=e.target;if(e.control==this)for(;n;){if(e.aria&&"down"!=e.aria.key||"BUTTON"==n.nodeName&&-1==n.className.indexOf("open"))return e.stopImmediatePropagation(),void t.call(this,e);n=n.parentNode}}),delete e.settings.onclick,e._super()}})}),r(Qt,[Ot],function(e){return e.extend({Defaults:{containerClass:"stack-layout",controlClass:"stack-layout-item",endClass:"break"}})}),r(Zt,[J,q],function(e,t){return e.extend({lastIdx:0,Defaults:{layout:"absolute",defaults:{type:"panel"}},activateTab:function(e){var n;this.activeTabId&&(n=this.getEl(this.activeTabId),t.removeClass(n,this.classPrefix+"active"),n.setAttribute("aria-selected","false")),this.activeTabId="t"+e,n=this.getEl("t"+e),n.setAttribute("aria-selected","true"),t.addClass(n,this.classPrefix+"active"),e!=this.lastIdx&&(this.items()[this.lastIdx].hide(),this.lastIdx=e),this.items()[e].show().fire("showtab"),this.reflow()},renderHtml:function(){var e=this,t=e._layout,n="",r=e.classPrefix;return e.preRender(),t.preRender(e),e.items().each(function(t,i){var o=e._id+"-t"+i;t.aria("role","tabpanel"),t.aria("labelledby",o),n+='"}),'
    '+n+'
    '+t.renderHtml(e)+"
    "},postRender:function(){var e=this;e._super(),e.settings.activeTab=e.settings.activeTab||0,e.activateTab(e.settings.activeTab),this.on("click",function(t){var n=t.target.parentNode;if(t.target.parentNode.id==e._id+"-head")for(var r=n.childNodes.length;r--;)n.childNodes[r]==t.target&&e.activateTab(r)})},initLayoutRect:function(){var e=this,n,r,i;r=t.getSize(e.getEl("head")).width,r=0>r?0:r,i=0,e.items().each(function(t,n){r=Math.max(r,t.layoutRect().minW),i=Math.max(i,t.layoutRect().minH),e.settings.activeTab!=n&&t.hide()}),e.items().each(function(e){e.settings.x=0,e.settings.y=0,e.settings.w=r,e.settings.h=i,e.layoutRect({x:0,y:0,w:r,h:i})});var o=t.getSize(e.getEl("head")).height;return e.settings.minWidth=r,e.settings.minHeight=i+o,n=e._super(),n.deltaH+=o,n.innerH=n.h-n.deltaH,n}})}),r(en,[wt,q],function(e,t){return e.extend({init:function(e){var t=this;t._super(e),t._value=e.value||"",t.addClass("textbox"),e.multiline?t.addClass("multiline"):t.on("keydown",function(e){13==e.keyCode&&t.parents().reverse().each(function(t){return e.preventDefault(),t.hasEventListeners("submit")&&t.toJSON?(t.fire("submit",{data:t.toJSON()}),!1):void 0})})},disabled:function(e){var t=this;return t._rendered&&"undefined"!=typeof e&&(t.getEl().disabled=e),t._super(e)},value:function(e){var t=this;return"undefined"!=typeof e?(t._value=e,t._rendered&&(t.getEl().value=e),t):t._rendered?t.getEl().value:t._value},repaint:function(){var e=this,t,n,r,i=0,o=0,a;t=e.getEl().style,n=e._layoutRect,a=e._lastRepaintRect||{};var s=document;return!e.settings.multiline&&s.all&&(!s.documentMode||s.documentMode<=8)&&(t.lineHeight=n.h-o+"px"),r=e._borderBox,i=r.left+r.right+8,o=r.top+r.bottom+(e.settings.multiline?8:0),n.x!==a.x&&(t.left=n.x+"px",a.x=n.x),n.y!==a.y&&(t.top=n.y+"px",a.y=n.y),n.w!==a.w&&(t.width=n.w-i+"px",a.w=n.w),n.h!==a.h&&(t.height=n.h-o+"px",a.h=n.h),e._lastRepaintRect=a,e.fire("repaint",{},!1),e},renderHtml:function(){var e=this,t=e._id,n=e.settings,r=e.encode(e._value,!1),i="";return"spellcheck"in n&&(i+=' spellcheck="'+n.spellcheck+'"'),n.maxLength&&(i+=' maxlength="'+n.maxLength+'"'),n.size&&(i+=' size="'+n.size+'"'),n.subtype&&(i+=' type="'+n.subtype+'"'),e.disabled()&&(i+=' disabled="disabled"'),n.multiline?'":'"},postRender:function(){var e=this;return t.on(e.getEl(),"change",function(t){e.fire("change",t)}),e._super()},remove:function(){t.off(this.getEl()),this._super()}})}),r(tn,[q,$],function(e,t){return function(n,r){var i=this,o,a=t.classPrefix;i.show=function(t){return i.hide(),o=!0,window.setTimeout(function(){o&&n.appendChild(e.createFragment('
    '))},t||0),i},i.hide=function(){var e=n.lastChild;return e&&-1!=e.className.indexOf("throbber")&&e.parentNode.removeChild(e),o=!1,i}}}),a([l,c,u,d,f,p,h,m,g,v,y,b,C,x,w,_,N,E,S,k,T,R,A,B,D,L,M,H,P,O,I,F,z,W,V,U,q,$,j,K,G,Y,X,J,Q,Z,et,tt,nt,rt,it,ot,at,st,lt,ct,ut,dt,ft,pt,ht,mt,gt,vt,yt,bt,Ct,xt,wt,_t,Nt,Et,St,kt,Tt,Rt,At,Bt,Dt,Lt,Mt,Ht,Pt,Ot,It,Ft,zt,Wt,Vt,Ut,qt,$t,jt,Kt,Gt,Yt,Xt,Jt,Qt,Zt,en,tn])}(this);tinymce.PluginManager.add("advlist",function(t){function e(t,e){var n=[];return tinymce.each(e.split(/[ ,]/),function(t){n.push({text:t.replace(/\-/g," ").replace(/\b\w/g,function(t){return t.toUpperCase()}),data:"default"==t?"":t})}),n}function n(e,n){var o,l=t.dom,a=t.selection;o=l.getParent(a.getNode(),"ol,ul"),o&&o.nodeName==e&&n!==!1||t.execCommand("UL"==e?"InsertUnorderedList":"InsertOrderedList"),n=n===!1?i[e]:n,i[e]=n,o=l.getParent(a.getNode(),"ol,ul"),o&&(l.setStyle(o,"listStyleType",n),o.removeAttribute("data-mce-style")),t.focus()}function o(e){var n=t.dom.getStyle(t.dom.getParent(t.selection.getNode(),"ol,ul"),"listStyleType")||"";e.control.items().each(function(t){t.active(t.settings.data===n)})}var l,a,i={};l=e("OL",t.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman")),a=e("UL",t.getParam("advlist_bullet_styles","default,circle,disc,square")),t.addButton("numlist",{type:"splitbutton",tooltip:"Numbered list",menu:l,onshow:o,onselect:function(t){n("OL",t.control.settings.data)},onclick:function(){n("OL",!1)}}),t.addButton("bullist",{type:"splitbutton",tooltip:"Bullet list",menu:a,onshow:o,onselect:function(t){n("UL",t.control.settings.data)},onclick:function(){n("UL",!1)}})});tinymce.PluginManager.add("anchor",function(n){function e(){var e=n.selection.getNode();n.windowManager.open({title:"Anchor",body:{type:"textbox",name:"name",size:40,label:"Name",value:e.name||e.id},onsubmit:function(e){n.execCommand("mceInsertContent",!1,n.dom.createHTML("a",{id:e.data.name}))}})}n.addButton("anchor",{icon:"anchor",tooltip:"Anchor",onclick:e,stateSelector:"a:not([href])"}),n.addMenuItem("anchor",{icon:"anchor",text:"Anchor",context:"insert",onclick:e})});tinymce.PluginManager.add("autolink",function(t){function n(t){o(t,-1,"(",!0)}function e(t){o(t,0,"",!0)}function i(t){o(t,-1,"",!1)}function o(t,n,e){function i(t,n){if(0>n&&(n=0),3==t.nodeType){var e=t.data.length;n>e&&(n=e)}return n}function o(t,n){f.setStart(t,i(t,n))}function r(t,n){f.setEnd(t,i(t,n))}var f,d,a,s,c,l,u,g,h;if(f=t.selection.getRng(!0).cloneRange(),f.startOffset<5){if(g=f.endContainer.previousSibling,!g){if(!f.endContainer.firstChild||!f.endContainer.firstChild.nextSibling)return;g=f.endContainer.firstChild.nextSibling}if(h=g.length,o(g,h),r(g,h),f.endOffset<5)return;d=f.endOffset,s=g}else{if(s=f.endContainer,3!=s.nodeType&&s.firstChild){for(;3!=s.nodeType&&s.firstChild;)s=s.firstChild;3==s.nodeType&&(o(s,0),r(s,s.nodeValue.length))}d=1==f.endOffset?2:f.endOffset-1-n}a=d;do o(s,d>=2?d-2:0),r(s,d>=1?d-1:0),d-=1;while(" "!=f.toString()&&""!==f.toString()&&160!=f.toString().charCodeAt(0)&&d-2>=0&&f.toString()!=e);f.toString()==e||160==f.toString().charCodeAt(0)?(o(s,d),r(s,a),d+=1):0===f.startOffset?(o(s,0),r(s,a)):(o(s,d),r(s,a)),l=f.toString(),"."==l.charAt(l.length-1)&&r(s,a-1),l=f.toString(),u=l.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i),u&&("www."==u[1]?u[1]="http://www.":/@$/.test(u[1])&&!/^mailto:/.test(u[1])&&(u[1]="mailto:"+u[1]),c=t.selection.getBookmark(),t.selection.setRng(f),t.execCommand("createlink",!1,u[1]+u[2]),t.selection.moveToBookmark(c),t.nodeChanged())}var r;return t.on("keydown",function(n){return 13==n.keyCode?i(t):void 0}),tinymce.Env.ie?void t.on("focus",function(){if(!r){r=!0;try{t.execCommand("AutoUrlDetect",!1,!0)}catch(n){}}}):(t.on("keypress",function(e){return 41==e.keyCode?n(t):void 0}),void t.on("keyup",function(n){return 32==n.keyCode?e(t):void 0}))});tinymce.PluginManager.add("autoresize",function(e){function t(){return e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen()}function i(n){var s,r,g,u,l,m,h,d,f=tinymce.DOM;if(r=e.getDoc()){if(g=r.body,u=r.documentElement,l=o.autoresize_min_height,!g||n&&"setcontent"===n.type&&n.initial||t())return void(g&&u&&(g.style.overflowY="auto",u.style.overflowY="auto"));h=e.dom.getStyle(g,"margin-top",!0),d=e.dom.getStyle(g,"margin-bottom",!0),m=g.offsetHeight+parseInt(h,10)+parseInt(d,10),(isNaN(m)||0>=m)&&(m=tinymce.Env.ie?g.scrollHeight:tinymce.Env.webkit&&0===g.clientHeight?0:g.offsetHeight),m>o.autoresize_min_height&&(l=m),o.autoresize_max_height&&m>o.autoresize_max_height?(l=o.autoresize_max_height,g.style.overflowY="auto",u.style.overflowY="auto"):(g.style.overflowY="hidden",u.style.overflowY="hidden",g.scrollTop=0),l!==a&&(s=l-a,f.setStyle(f.get(e.id+"_ifr"),"height",l+"px"),a=l,tinymce.isWebKit&&0>s&&i(n))}}function n(e,t,o){setTimeout(function(){i({}),e--?n(e,t,o):o&&o()},t)}var o=e.settings,a=0;e.settings.inline||(o.autoresize_min_height=parseInt(e.getParam("autoresize_min_height",e.getElement().offsetHeight),10),o.autoresize_max_height=parseInt(e.getParam("autoresize_max_height",0),10),e.on("init",function(){var t=e.getParam("autoresize_overflow_padding",1);e.dom.setStyles(e.getBody(),{paddingBottom:e.getParam("autoresize_bottom_margin",50),paddingLeft:t,paddingRight:t})}),e.on("nodechange setcontent keyup FullscreenStateChanged",i),e.getParam("autoresize_on_init",!0)&&e.on("init",function(){n(20,100,function(){n(5,1e3)})}),e.addCommand("mceAutoResize",i))});tinymce.PluginManager.add("autosave",function(e){function t(e,t){var n={s:1e3,m:6e4};return e=/^(\d+)([ms]?)$/.exec(""+(e||t)),(e[2]?n[e[2]]:1)*parseInt(e,10)}function n(){var e=parseInt(l.getItem(d+"time"),10)||0;return(new Date).getTime()-e>v.autosave_retention?(a(!1),!1):!0}function a(t){l.removeItem(d+"draft"),l.removeItem(d+"time"),t!==!1&&e.fire("RemoveDraft")}function r(){!c()&&e.isDirty()&&(l.setItem(d+"draft",e.getContent({format:"raw",no_events:!0})),l.setItem(d+"time",(new Date).getTime()),e.fire("StoreDraft"))}function o(){n()&&(e.setContent(l.getItem(d+"draft"),{format:"raw"}),e.fire("RestoreDraft"))}function i(){m||(setInterval(function(){e.removed||r()},v.autosave_interval),m=!0)}function s(){var t=this;t.disabled(!n()),e.on("StoreDraft RestoreDraft RemoveDraft",function(){t.disabled(!n())}),i()}function u(){e.undoManager.beforeChange(),o(),a(),e.undoManager.add()}function f(){var e;return tinymce.each(tinymce.editors,function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&t.getParam("autosave_ask_before_unload",!0)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))}),e}function c(t){var n=e.settings.forced_root_block;return t=tinymce.trim("undefined"==typeof t?e.getBody().innerHTML:t),""===t||new RegExp("^<"+n+"[^>]*>(( | |[ ]|]*>)+?|)|
    $","i").test(t)}var d,m,v=e.settings,l=tinymce.util.LocalStorage;d=v.autosave_prefix||"tinymce-autosave-{path}{query}-{id}-",d=d.replace(/\{path\}/g,document.location.pathname),d=d.replace(/\{query\}/g,document.location.search),d=d.replace(/\{id\}/g,e.id),v.autosave_interval=t(v.autosave_interval,"30s"),v.autosave_retention=t(v.autosave_retention,"20m"),e.addButton("restoredraft",{title:"Restore last draft",onclick:u,onPostRender:s}),e.addMenuItem("restoredraft",{text:"Restore last draft",onclick:u,onPostRender:s,context:"file"}),e.settings.autosave_restore_when_empty!==!1&&(e.on("init",function(){n()&&c()&&o()}),e.on("saveContent",function(){a()})),window.onbeforeunload=f,this.hasDraft=n,this.storeDraft=r,this.restoreDraft=o,this.removeDraft=a,this.isEmpty=c});!function(){tinymce.create("tinymce.plugins.BBCodePlugin",{init:function(o){var e=this,t=o.getParam("bbcode_dialect","punbb").toLowerCase();o.on("beforeSetContent",function(o){o.content=e["_"+t+"_bbcode2html"](o.content)}),o.on("postProcess",function(o){o.set&&(o.content=e["_"+t+"_bbcode2html"](o.content)),o.get&&(o.content=e["_"+t+"_html2bbcode"](o.content))})},getInfo:function(){return{longname:"BBCode Plugin",author:"Moxiecode Systems AB",authorurl:"http://www.tinymce.com",infourl:"http://www.tinymce.com/wiki.php/Plugin:bbcode"}},_punbb_html2bbcode:function(o){function e(e,t){o=o.replace(e,t)}return o=tinymce.trim(o),e(/(.*?)<\/a>/gi,"[url=$1]$2[/url]"),e(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),e(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),e(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),e(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),e(/(.*?)<\/span>/gi,"[color=$1]$2[/color]"),e(/(.*?)<\/font>/gi,"[color=$1]$2[/color]"),e(/(.*?)<\/span>/gi,"[size=$1]$2[/size]"),e(/(.*?)<\/font>/gi,"$1"),e(//gi,"[img]$1[/img]"),e(/(.*?)<\/span>/gi,"[code]$1[/code]"),e(/(.*?)<\/span>/gi,"[quote]$1[/quote]"),e(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),e(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),e(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),e(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),e(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),e(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),e(/<\/(strong|b)>/gi,"[/b]"),e(/<(strong|b)>/gi,"[b]"),e(/<\/(em|i)>/gi,"[/i]"),e(/<(em|i)>/gi,"[i]"),e(/<\/u>/gi,"[/u]"),e(/(.*?)<\/span>/gi,"[u]$1[/u]"),e(//gi,"[u]"),e(/]*>/gi,"[quote]"),e(/<\/blockquote>/gi,"[/quote]"),e(/
    /gi,"\n"),e(//gi,"\n"),e(/
    /gi,"\n"),e(/

    /gi,""),e(/<\/p>/gi,"\n"),e(/ |\u00a0/gi," "),e(/"/gi,'"'),e(/</gi,"<"),e(/>/gi,">"),e(/&/gi,"&"),o},_punbb_bbcode2html:function(o){function e(e,t){o=o.replace(e,t)}return o=tinymce.trim(o),e(/\n/gi,"
    "),e(/\[b\]/gi,""),e(/\[\/b\]/gi,""),e(/\[i\]/gi,""),e(/\[\/i\]/gi,""),e(/\[u\]/gi,""),e(/\[\/u\]/gi,""),e(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'$2'),e(/\[url\](.*?)\[\/url\]/gi,'$1'),e(/\[img\](.*?)\[\/img\]/gi,''),e(/\[color=(.*?)\](.*?)\[\/color\]/gi,'$2'),e(/\[code\](.*?)\[\/code\]/gi,'$1 '),e(/\[quote.*?\](.*?)\[\/quote\]/gi,'$1 '),o}}),tinymce.PluginManager.add("bbcode",tinymce.plugins.BBCodePlugin)}();tinymce.PluginManager.add("charmap",function(e){function a(){function a(e){for(;e;){if("TD"==e.nodeName)return e;e=e.parentNode}}var t,r,o,n;t='';var l=25;for(o=0;10>o;o++){for(t+="",r=0;l>r;r++){var s=i[o*l+r];t+='"}t+=""}t+="";var c={type:"container",html:t,onclick:function(a){var i=a.target;"TD"==i.tagName&&(i=i.firstChild),"DIV"==i.tagName&&(e.execCommand("mceInsertContent",!1,i.firstChild.data),a.ctrlKey||n.close())},onmouseover:function(e){var i=a(e.target);i&&n.find("#preview").text(i.firstChild.firstChild.data)}};n=e.windowManager.open({title:"Special character",spacing:10,padding:10,items:[c,{type:"label",name:"preview",text:" ",style:"font-size: 40px; text-align: center",border:1,minWidth:100,minHeight:80}],buttons:[{text:"Close",onclick:function(){n.close()}}]})}var i=[["160","no-break space"],["38","ampersand"],["34","quotation mark"],["162","cent sign"],["8364","euro sign"],["163","pound sign"],["165","yen sign"],["169","copyright sign"],["174","registered sign"],["8482","trade mark sign"],["8240","per mille sign"],["181","micro sign"],["183","middle dot"],["8226","bullet"],["8230","three dot leader"],["8242","minutes / feet"],["8243","seconds / inches"],["167","section sign"],["182","paragraph sign"],["223","sharp s / ess-zed"],["8249","single left-pointing angle quotation mark"],["8250","single right-pointing angle quotation mark"],["171","left pointing guillemet"],["187","right pointing guillemet"],["8216","left single quotation mark"],["8217","right single quotation mark"],["8220","left double quotation mark"],["8221","right double quotation mark"],["8218","single low-9 quotation mark"],["8222","double low-9 quotation mark"],["60","less-than sign"],["62","greater-than sign"],["8804","less-than or equal to"],["8805","greater-than or equal to"],["8211","en dash"],["8212","em dash"],["175","macron"],["8254","overline"],["164","currency sign"],["166","broken bar"],["168","diaeresis"],["161","inverted exclamation mark"],["191","turned question mark"],["710","circumflex accent"],["732","small tilde"],["176","degree sign"],["8722","minus sign"],["177","plus-minus sign"],["247","division sign"],["8260","fraction slash"],["215","multiplication sign"],["185","superscript one"],["178","superscript two"],["179","superscript three"],["188","fraction one quarter"],["189","fraction one half"],["190","fraction three quarters"],["402","function / florin"],["8747","integral"],["8721","n-ary sumation"],["8734","infinity"],["8730","square root"],["8764","similar to"],["8773","approximately equal to"],["8776","almost equal to"],["8800","not equal to"],["8801","identical to"],["8712","element of"],["8713","not an element of"],["8715","contains as member"],["8719","n-ary product"],["8743","logical and"],["8744","logical or"],["172","not sign"],["8745","intersection"],["8746","union"],["8706","partial differential"],["8704","for all"],["8707","there exists"],["8709","diameter"],["8711","backward difference"],["8727","asterisk operator"],["8733","proportional to"],["8736","angle"],["180","acute accent"],["184","cedilla"],["170","feminine ordinal indicator"],["186","masculine ordinal indicator"],["8224","dagger"],["8225","double dagger"],["192","A - grave"],["193","A - acute"],["194","A - circumflex"],["195","A - tilde"],["196","A - diaeresis"],["197","A - ring above"],["198","ligature AE"],["199","C - cedilla"],["200","E - grave"],["201","E - acute"],["202","E - circumflex"],["203","E - diaeresis"],["204","I - grave"],["205","I - acute"],["206","I - circumflex"],["207","I - diaeresis"],["208","ETH"],["209","N - tilde"],["210","O - grave"],["211","O - acute"],["212","O - circumflex"],["213","O - tilde"],["214","O - diaeresis"],["216","O - slash"],["338","ligature OE"],["352","S - caron"],["217","U - grave"],["218","U - acute"],["219","U - circumflex"],["220","U - diaeresis"],["221","Y - acute"],["376","Y - diaeresis"],["222","THORN"],["224","a - grave"],["225","a - acute"],["226","a - circumflex"],["227","a - tilde"],["228","a - diaeresis"],["229","a - ring above"],["230","ligature ae"],["231","c - cedilla"],["232","e - grave"],["233","e - acute"],["234","e - circumflex"],["235","e - diaeresis"],["236","i - grave"],["237","i - acute"],["238","i - circumflex"],["239","i - diaeresis"],["240","eth"],["241","n - tilde"],["242","o - grave"],["243","o - acute"],["244","o - circumflex"],["245","o - tilde"],["246","o - diaeresis"],["248","o slash"],["339","ligature oe"],["353","s - caron"],["249","u - grave"],["250","u - acute"],["251","u - circumflex"],["252","u - diaeresis"],["253","y - acute"],["254","thorn"],["255","y - diaeresis"],["913","Alpha"],["914","Beta"],["915","Gamma"],["916","Delta"],["917","Epsilon"],["918","Zeta"],["919","Eta"],["920","Theta"],["921","Iota"],["922","Kappa"],["923","Lambda"],["924","Mu"],["925","Nu"],["926","Xi"],["927","Omicron"],["928","Pi"],["929","Rho"],["931","Sigma"],["932","Tau"],["933","Upsilon"],["934","Phi"],["935","Chi"],["936","Psi"],["937","Omega"],["945","alpha"],["946","beta"],["947","gamma"],["948","delta"],["949","epsilon"],["950","zeta"],["951","eta"],["952","theta"],["953","iota"],["954","kappa"],["955","lambda"],["956","mu"],["957","nu"],["958","xi"],["959","omicron"],["960","pi"],["961","rho"],["962","final sigma"],["963","sigma"],["964","tau"],["965","upsilon"],["966","phi"],["967","chi"],["968","psi"],["969","omega"],["8501","alef symbol"],["982","pi symbol"],["8476","real part symbol"],["978","upsilon - hook symbol"],["8472","Weierstrass p"],["8465","imaginary part"],["8592","leftwards arrow"],["8593","upwards arrow"],["8594","rightwards arrow"],["8595","downwards arrow"],["8596","left right arrow"],["8629","carriage return"],["8656","leftwards double arrow"],["8657","upwards double arrow"],["8658","rightwards double arrow"],["8659","downwards double arrow"],["8660","left right double arrow"],["8756","therefore"],["8834","subset of"],["8835","superset of"],["8836","not a subset of"],["8838","subset of or equal to"],["8839","superset of or equal to"],["8853","circled plus"],["8855","circled times"],["8869","perpendicular"],["8901","dot operator"],["8968","left ceiling"],["8969","right ceiling"],["8970","left floor"],["8971","right floor"],["9001","left-pointing angle bracket"],["9002","right-pointing angle bracket"],["9674","lozenge"],["9824","black spade suit"],["9827","black club suit"],["9829","black heart suit"],["9830","black diamond suit"],["8194","en space"],["8195","em space"],["8201","thin space"],["8204","zero width non-joiner"],["8205","zero width joiner"],["8206","left-to-right mark"],["8207","right-to-left mark"],["173","soft hyphen"]];e.addButton("charmap",{icon:"charmap",tooltip:"Special character",onclick:a}),e.addMenuItem("charmap",{icon:"charmap",text:"Special character",onclick:a,context:"insert"})});tinymce.PluginManager.add("code",function(e){function o(){e.windowManager.open({title:"Source code",body:{type:"textbox",name:"code",multiline:!0,minWidth:e.getParam("code_dialog_width",600),minHeight:e.getParam("code_dialog_height",Math.min(tinymce.DOM.getViewPort().h-200,500)),value:e.getContent({source_view:!0}),spellcheck:!1,style:"direction: ltr; text-align: left"},onSubmit:function(o){e.focus(),e.undoManager.transact(function(){e.setContent(o.data.code)}),e.selection.setCursorLocation(),e.nodeChanged()}})}e.addCommand("mceCodeEditor",o),e.addButton("code",{icon:"code",tooltip:"Source code",onclick:o}),e.addMenuItem("code",{icon:"code",text:"Source code",context:"tools",onclick:o})});tinymce.PluginManager.add("contextmenu",function(e){var n,t=e.settings.contextmenu_never_use_native;e.on("contextmenu",function(i){var o;if(!i.ctrlKey||t){if(i.preventDefault(),o=e.settings.contextmenu||"link image inserttable | cell row column deletetable",n)n.show();else{var c=[];tinymce.each(o.split(/[ ,]/),function(n){var t=e.menuItems[n];"|"==n&&(t={text:n}),t&&(t.shortcut="",c.push(t))});for(var a=0;a'}),t+=""}),t+=""}var i=[["cool","cry","embarassed","foot-in-mouth"],["frown","innocent","kiss","laughing"],["money-mouth","sealed","smile","surprised"],["tongue-out","undecided","wink","yell"]];t.addButton("emoticons",{type:"panelbutton",panel:{role:"application",autohide:!0,html:a,onclick:function(e){var a=t.dom.getParent(e.target,"a");a&&(t.insertContent(''+a.getAttribute('),this.hide())}},tooltip:"Emoticons"})});tinymce.PluginManager.add("fullpage",function(e){function t(){var t=n();e.windowManager.open({title:"Document properties",data:t,defaults:{type:"textbox",size:40},body:[{name:"title",label:"Title"},{name:"keywords",label:"Keywords"},{name:"description",label:"Description"},{name:"robots",label:"Robots"},{name:"author",label:"Author"},{name:"docencoding",label:"Encoding"}],onSubmit:function(e){l(tinymce.extend(t,e.data))}})}function n(){function t(e,t){var n=e.attr(t);return n||""}var n,l,a=i(),r={};return r.fontface=e.getParam("fullpage_default_fontface",""),r.fontsize=e.getParam("fullpage_default_fontsize",""),n=a.firstChild,7==n.type&&(r.xml_pi=!0,l=/encoding="([^"]+)"/.exec(n.value),l&&(r.docencoding=l[1])),n=a.getAll("#doctype")[0],n&&(r.doctype=""),n=a.getAll("title")[0],n&&n.firstChild&&(r.title=n.firstChild.value),s(a.getAll("meta"),function(e){var t,n=e.attr("name"),l=e.attr("http-equiv");n?r[n.toLowerCase()]=e.attr("content"):"Content-Type"==l&&(t=/charset\s*=\s*(.*)\s*/gi.exec(e.attr("content")),t&&(r.docencoding=t[1]))}),n=a.getAll("html")[0],n&&(r.langcode=t(n,"lang")||t(n,"xml:lang")),r.stylesheets=[],tinymce.each(a.getAll("link"),function(e){"stylesheet"==e.attr("rel")&&r.stylesheets.push(e.attr("href"))}),n=a.getAll("body")[0],n&&(r.langdir=t(n,"dir"),r.style=t(n,"style"),r.visited_color=t(n,"vlink"),r.link_color=t(n,"link"),r.active_color=t(n,"alink")),r}function l(t){function n(e,t,n){e.attr(t,n?n:void 0)}function l(e){r.firstChild?r.insert(e,r.firstChild):r.append(e)}var a,r,o,c,u,f=e.dom;a=i(),r=a.getAll("head")[0],r||(c=a.getAll("html")[0],r=new m("head",1),c.firstChild?c.insert(r,c.firstChild,!0):c.append(r)),c=a.firstChild,t.xml_pi?(u='version="1.0"',t.docencoding&&(u+=' encoding="'+t.docencoding+'"'),7!=c.type&&(c=new m("xml",7),a.insert(c,a.firstChild,!0)),c.value=u):c&&7==c.type&&c.remove(),c=a.getAll("#doctype")[0],t.doctype?(c||(c=new m("#doctype",10),t.xml_pi?a.insert(c,a.firstChild):l(c)),c.value=t.doctype.substring(9,t.doctype.length-1)):c&&c.remove(),c=null,s(a.getAll("meta"),function(e){"Content-Type"==e.attr("http-equiv")&&(c=e)}),t.docencoding?(c||(c=new m("meta",1),c.attr("http-equiv","Content-Type"),c.shortEnded=!0,l(c)),c.attr("content","text/html; charset="+t.docencoding)):c.remove(),c=a.getAll("title")[0],t.title?(c?c.empty():(c=new m("title",1),l(c)),c.append(new m("#text",3)).value=t.title):c&&c.remove(),s("keywords,description,author,copyright,robots".split(","),function(e){var n,i,r=a.getAll("meta"),o=t[e];for(n=0;n"))}function i(){return new tinymce.html.DomParser({validate:!1,root_name:"#document"}).parse(d)}function a(t){function n(e){return e.replace(/<\/?[A-Z]+/g,function(e){return e.toLowerCase()})}var l,a,o,m,u=t.content,f="",g=e.dom;if(!t.selection&&!("raw"==t.format&&d||t.source_view&&e.getParam("fullpage_hide_in_source_view"))){u=u.replace(/<(\/?)BODY/gi,"<$1body"),l=u.indexOf("",l),d=n(u.substring(0,l+1)),a=u.indexOf("\n"),o=i(),s(o.getAll("style"),function(e){e.firstChild&&(f+=e.firstChild.value)}),m=o.getAll("body")[0],m&&g.setAttribs(e.getBody(),{style:m.attr("style")||"",dir:m.attr("dir")||"",vLink:m.attr("vlink")||"",link:m.attr("link")||"",aLink:m.attr("alink")||""}),g.remove("fullpage_styles");var y=e.getDoc().getElementsByTagName("head")[0];f&&(g.add(y,"style",{id:"fullpage_styles"},f),m=g.get("fullpage_styles"),m.styleSheet&&(m.styleSheet.cssText=f));var h={};tinymce.each(y.getElementsByTagName("link"),function(e){"stylesheet"==e.rel&&e.getAttribute("data-mce-fullpage")&&(h[e.href]=e)}),tinymce.each(o.getAll("link"),function(e){var t=e.attr("href");h[t]||"stylesheet"!=e.attr("rel")||g.add(y,"link",{rel:"stylesheet",text:"text/css",href:t,"data-mce-fullpage":"1"}),delete h[t]}),tinymce.each(h,function(e){e.parentNode.removeChild(e)})}}function r(){var t,n="",l="";return e.getParam("fullpage_default_xml_pi")&&(n+='\n'),n+=e.getParam("fullpage_default_doctype",""),n+="\n\n\n",(t=e.getParam("fullpage_default_title"))&&(n+=""+t+"\n"),(t=e.getParam("fullpage_default_encoding"))&&(n+='\n'),(t=e.getParam("fullpage_default_font_family"))&&(l+="font-family: "+t+";"),(t=e.getParam("fullpage_default_font_size"))&&(l+="font-size: "+t+";"),(t=e.getParam("fullpage_default_text_color"))&&(l+="color: "+t+";"),n+="\n\n"}function o(t){t.selection||t.source_view&&e.getParam("fullpage_hide_in_source_view")||(t.content=tinymce.trim(d)+"\n"+tinymce.trim(t.content)+"\n"+tinymce.trim(c))}var d,c,s=tinymce.each,m=tinymce.html.Node;e.addCommand("mceFullPageProperties",t),e.addButton("fullpage",{title:"Document properties",cmd:"mceFullPageProperties"}),e.addMenuItem("fullpage",{text:"Document properties",cmd:"mceFullPageProperties",context:"file"}),e.on("BeforeSetContent",a),e.on("GetContent",o)});tinymce.PluginManager.add("fullscreen",function(e){function t(){var e,t,n=window,i=document,l=i.body;return l.offsetWidth&&(e=l.offsetWidth,t=l.offsetHeight),n.innerWidth&&n.innerHeight&&(e=n.innerWidth,t=n.innerHeight),{w:e,h:t}}function n(){function n(){d.setStyle(a,"height",t().h-(h.clientHeight-a.clientHeight))}var u,h,a,f,m=document.body,g=document.documentElement;s=!s,h=e.getContainer(),u=h.style,a=e.getContentAreaContainer().firstChild,f=a.style,s?(i=f.width,l=f.height,f.width=f.height="100%",c=u.width,o=u.height,u.width=u.height="",d.addClass(m,"mce-fullscreen"),d.addClass(g,"mce-fullscreen"),d.addClass(h,"mce-fullscreen"),d.bind(window,"resize",n),n(),r=n):(f.width=i,f.height=l,c&&(u.width=c),o&&(u.height=o),d.removeClass(m,"mce-fullscreen"),d.removeClass(g,"mce-fullscreen"),d.removeClass(h,"mce-fullscreen"),d.unbind(window,"resize",r)),e.fire("FullscreenStateChanged",{state:s})}var i,l,r,c,o,s=!1,d=tinymce.DOM;return e.settings.inline?void 0:(e.on("init",function(){e.addShortcut("Ctrl+Alt+F","",n)}),e.on("remove",function(){r&&d.unbind(window,"resize",r)}),e.addCommand("mceFullScreen",n),e.addMenuItem("fullscreen",{text:"Fullscreen",shortcut:"Ctrl+Alt+F",selectable:!0,onClick:n,onPostRender:function(){var t=this;e.on("FullscreenStateChanged",function(e){t.active(e.state)})},context:"view"}),e.addButton("fullscreen",{tooltip:"Fullscreen",shortcut:"Ctrl+Alt+F",onClick:n,onPostRender:function(){var t=this;e.on("FullscreenStateChanged",function(e){t.active(e.state)})}}),{isFullscreen:function(){return s}})});tinymce.PluginManager.add("hr",function(n){n.addCommand("InsertHorizontalRule",function(){n.execCommand("mceInsertContent",!1,"


    ")}),n.addButton("hr",{icon:"hr",tooltip:"Horizontal line",cmd:"InsertHorizontalRule"}),n.addMenuItem("hr",{icon:"hr",text:"Horizontal line",cmd:"InsertHorizontalRule",context:"insert"})});tinymce.PluginManager.add("image",function(e){function t(e,t){function i(e,i){n.parentNode&&n.parentNode.removeChild(n),t({width:e,height:i})}var n=document.createElement("img");n.onload=function(){i(n.clientWidth,n.clientHeight)},n.onerror=function(){i()};var a=n.style;a.visibility="hidden",a.position="fixed",a.bottom=a.left=0,a.width=a.height="auto",document.body.appendChild(n),n.src=e}function i(t){return tinymce.each(t,function(t){t.textStyle=function(){return e.formatter.getCssText({inline:"img",classes:[t.value]})}}),t}function n(t){return function(){var i=e.settings.image_list;"string"==typeof i?tinymce.util.XHR.send({url:i,success:function(e){t(tinymce.util.JSON.parse(e))}}):"function"==typeof i?i(t):t(i)}}function a(n){function a(t,i,n){var a,l=[];return tinymce.each(e.settings[t]||n,function(e){var t={text:e.text||e.title,value:e.value};l.push(t),(f[i]===e.value||!a&&e.selected)&&(a=t)}),a&&!f[i]&&(f[i]=a.value,a.selected=!0),l}function l(){var t=[{text:"None",value:""}];return tinymce.each(n,function(i){t.push({text:i.text||i.title,value:e.convertURL(i.value||i.url,"src"),menu:i.menu})}),t}function o(){var e,t,i,n;e=u.find("#width")[0],t=u.find("#height")[0],i=e.value(),n=t.value(),u.find("#constrain")[0].checked()&&g&&h&&i&&n&&(g!=i?(n=Math.round(i/g*n),t.value(n)):(i=Math.round(n/h*i),e.value(i))),g=i,h=n}function s(){function t(t){function i(){t.onload=t.onerror=null,e.selection.select(t),e.nodeChanged()}t.onload=function(){f.width||f.height||y.setAttribs(t,{width:t.clientWidth,height:t.clientHeight}),i()},t.onerror=i}d(),o(),f=tinymce.extend(f,u.toJSON()),f.alt||(f.alt=""),""===f.width&&(f.width=null),""===f.height&&(f.height=null),f.style||(f.style=null),f={src:f.src,alt:f.alt,width:f.width,height:f.height,style:f.style,"class":f["class"]},f["class"]||delete f["class"],e.undoManager.transact(function(){return f.src?(v?y.setAttribs(v,f):(f.id="__mcenew",e.focus(),e.selection.setContent(y.createHTML("img",f)),v=y.get("__mcenew"),y.setAttrib(v,"id",null)),void t(v)):void(v&&(y.remove(v),e.focus(),e.nodeChanged()))})}function r(e){return e&&(e=e.replace(/px$/,"")),e}function c(){m&&m.value(e.convertURL(this.value(),"src")),t(this.value(),function(e){e.width&&e.height&&(g=e.width,h=e.height,u.find("#width").value(g),u.find("#height").value(h))})}function d(){function t(e){return e.length>0&&/^[0-9]+$/.test(e)&&(e+="px"),e}if(e.settings.image_advtab){var i=u.toJSON(),n=y.parseStyle(i.style);delete n.margin,n["margin-top"]=n["margin-bottom"]=t(i.vspace),n["margin-left"]=n["margin-right"]=t(i.hspace),n["border-width"]=t(i.border),u.find("#style").value(y.serializeStyle(y.parseStyle(y.serializeStyle(n))))}}var u,g,h,m,p,f={},y=e.dom,v=e.selection.getNode();g=y.getAttrib(v,"width"),h=y.getAttrib(v,"height"),"IMG"!=v.nodeName||v.getAttribute("data-mce-object")||v.getAttribute("data-mce-placeholder")?v=null:f={src:y.getAttrib(v,"src"),alt:y.getAttrib(v,"alt"),"class":y.getAttrib(v,"class"),width:g,height:h},n&&(m={type:"listbox",label:"Image list",values:l(),value:f.src&&e.convertURL(f.src,"src"),onselect:function(e){var t=u.find("#alt");(!t.value()||e.lastControl&&t.value()==e.lastControl.text())&&t.value(e.control.text()),u.find("#src").value(e.control.value())},onPostRender:function(){m=this}}),e.settings.image_class_list&&(p={name:"class",type:"listbox",label:"Class",values:i(a("image_class_list","class"))});var b=[{name:"src",type:"filepicker",filetype:"image",label:"Source",autofocus:!0,onchange:c},m];e.settings.image_description!==!1&&b.push({name:"alt",type:"textbox",label:"Image description"}),e.settings.image_dimensions!==!1&&b.push({type:"container",label:"Dimensions",layout:"flex",direction:"row",align:"center",spacing:5,items:[{name:"width",type:"textbox",maxLength:5,size:3,onchange:o,ariaLabel:"Width"},{type:"label",text:"x"},{name:"height",type:"textbox",maxLength:5,size:3,onchange:o,ariaLabel:"Height"},{name:"constrain",type:"checkbox",checked:!0,text:"Constrain proportions"}]}),b.push(p),e.settings.image_advtab?(v&&(f.hspace=r(v.style.marginLeft||v.style.marginRight),f.vspace=r(v.style.marginTop||v.style.marginBottom),f.border=r(v.style.borderWidth),f.style=e.dom.serializeStyle(e.dom.parseStyle(e.dom.getAttrib(v,"style")))),u=e.windowManager.open({title:"Insert/edit image",data:f,bodyType:"tabpanel",body:[{title:"General",type:"form",items:b},{title:"Advanced",type:"form",pack:"start",items:[{label:"Style",name:"style",type:"textbox"},{type:"form",layout:"grid",packV:"start",columns:2,padding:0,alignH:["left","right"],defaults:{type:"textbox",maxWidth:50,onchange:d},items:[{label:"Vertical space",name:"vspace"},{label:"Horizontal space",name:"hspace"},{label:"Border",name:"border"}]}]}],onSubmit:s})):u=e.windowManager.open({title:"Insert/edit image",data:f,body:b,onSubmit:s})}e.addButton("image",{icon:"image",tooltip:"Insert/edit image",onclick:n(a),stateSelector:"img:not([data-mce-object],[data-mce-placeholder])"}),e.addMenuItem("image",{icon:"image",text:"Insert image",onclick:n(a),context:"insert",prependToContext:!0})});tinymce.PluginManager.add("importcss",function(t){function e(t){return"string"==typeof t?function(e){return-1!==e.indexOf(t)}:t instanceof RegExp?function(e){return t.test(e)}:t}function n(e,n){function i(t,e){var c,o=t.href;if(o&&n(o,e)){s(t.imports,function(t){i(t,!0)});try{c=t.cssRules||t.rules}catch(a){}s(c,function(t){t.styleSheet?i(t.styleSheet,!0):t.selectorText&&s(t.selectorText.split(","),function(t){r.push(tinymce.trim(t))})})}}var r=[],c={};s(t.contentCSS,function(t){c[t]=!0}),n||(n=function(t,e){return e||c[t]});try{s(e.styleSheets,function(t){i(t)})}catch(o){}return r}function i(e){var n,i=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(e);if(i){var r=i[1],s=i[2].substr(1).split(".").join(" "),c=tinymce.makeMap("a,img");return i[1]?(n={title:e},t.schema.getTextBlockElements()[r]?n.block=r:t.schema.getBlockElements()[r]||c[r.toLowerCase()]?n.selector=r:n.inline=r):i[2]&&(n={inline:"span",title:e.substr(1),classes:s}),t.settings.importcss_merge_classes!==!1?n.classes=s:n.attributes={"class":s},n}}var r=this,s=tinymce.each;t.on("renderFormatsMenu",function(c){var o=t.settings,a={},l=o.importcss_selector_converter||i,f=e(o.importcss_selector_filter),m=c.control;t.settings.importcss_append||m.items().remove();var u=[];tinymce.each(o.importcss_groups,function(t){t=tinymce.extend({},t),t.filter=e(t.filter),u.push(t)}),s(n(c.doc||t.getDoc(),e(o.importcss_file_filter)),function(e){if(-1===e.indexOf(".mce-")&&!a[e]&&(!f||f(e))){var n,i=l.call(r,e);if(i){var s=i.name||tinymce.DOM.uniqueId();if(u)for(var c=0;c'+n+"";var i=e.dom.getParent(e.selection.getStart(),"time");if(i)return void e.dom.setOuterHTML(i,n)}e.insertContent(n)}var n,r,i="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),d="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),c="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),u=[];e.addCommand("mceInsertDate",function(){a(e.getParam("insertdatetime_dateformat",e.translate("%Y-%m-%d")))}),e.addCommand("mceInsertTime",function(){a(e.getParam("insertdatetime_timeformat",e.translate("%H:%M:%S")))}),e.addButton("insertdatetime",{type:"splitbutton",title:"Insert date/time",onclick:function(){a(n||r)},menu:u}),tinymce.each(e.settings.insertdatetime_formats||["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"],function(e){r||(r=e),u.push({text:t(e),onclick:function(){n=e,a(e)}})}),e.addMenuItem("insertdatetime",{icon:"date",text:"Insert date/time",menu:u,context:"insert"})});!function(e){e.on("AddEditor",function(e){e.editor.settings.inline_styles=!1}),e.PluginManager.add("legacyoutput",function(t){t.on("init",function(){var i="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",n=e.explode(t.settings.font_size_style_values),l=t.schema;t.formatter.register({alignleft:{selector:i,attributes:{align:"left"}},aligncenter:{selector:i,attributes:{align:"center"}},alignright:{selector:i,attributes:{align:"right"}},alignjustify:{selector:i,attributes:{align:"justify"}},bold:[{inline:"b",remove:"all"},{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}}],italic:[{inline:"i",remove:"all"},{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}}],underline:[{inline:"u",remove:"all"},{inline:"span",styles:{textDecoration:"underline"},exact:!0}],strikethrough:[{inline:"strike",remove:"all"},{inline:"span",styles:{textDecoration:"line-through"},exact:!0}],fontname:{inline:"font",attributes:{face:"%value"}},fontsize:{inline:"font",attributes:{size:function(t){return e.inArray(n,t.value)+1}}},forecolor:{inline:"font",attributes:{color:"%value"}},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"}}}),e.each("b,i,u,strike".split(","),function(e){l.addValidElements(e+"[*]")}),l.getElementRule("font")||l.addValidElements("font[face|size|color|style]"),e.each(i.split(","),function(e){var t=l.getElementRule(e);t&&(t.attributes.align||(t.attributes.align={},t.attributesOrder.push("align")))})})})}(tinymce);tinymce.PluginManager.add("link",function(t){function e(e){return function(){var n=t.settings.link_list;"string"==typeof n?tinymce.util.XHR.send({url:n,success:function(t){e(tinymce.util.JSON.parse(t))}}):"function"==typeof n?n(e):e(n)}}function n(e){function n(t){var e=d.find("#text");(!e.value()||t.lastControl&&e.value()==t.lastControl.text())&&e.value(t.control.text()),d.find("#href").value(t.control.value())}function l(){var n=[{text:"None",value:""}];return tinymce.each(e,function(e){n.push({text:e.text||e.title,value:t.convertURL(e.value||e.url,"href"),menu:e.menu})}),n}function i(e){return tinymce.each(e,function(e){e.textStyle=function(){return t.formatter.getCssText({inline:"a",classes:[e.value]})}}),e}function a(e,n,l){var i,a=[];return tinymce.each(t.settings[e]||l,function(t){var e={text:t.text||t.title,value:t.value};a.push(e),(b[n]===t.value||!i&&t.selected)&&(i=e)}),i&&!b[n]&&(b[n]=i.value,i.selected=!0),a}function r(e){var l=[];return tinymce.each(t.dom.select("a:not([href])"),function(t){var n=t.name||t.id;n&&l.push({text:n,value:"#"+n,selected:-1!=e.indexOf("#"+n)})}),l.length?(l.unshift({text:"None",value:""}),{name:"anchor",type:"listbox",label:"Anchors",values:l,onselect:n}):void 0}function o(){h&&h.value(t.convertURL(this.value(),"href")),!f&&0===b.text.length&&x&&this.parent().parent().find("#text")[0].value(this.value())}function s(t){var e=k.getContent();if(/]+>[^<]+<\/a>$/.test(e)||-1==e.indexOf("href=")))return!1;if(t){var n,l=t.childNodes;if(0===l.length)return!1;for(n=l.length-1;n>=0;n--)if(3!=l[n].nodeType)return!1}return!0}var u,c,f,d,x,v,h,g,m,p,y,b={},k=t.selection,w=t.dom;u=k.getNode(),c=w.getParent(u,"a[href]"),x=s(),b.text=f=c?c.innerText||c.textContent:k.getContent({format:"text"}),b.href=c?w.getAttrib(c,"href"):"",b.target=c?w.getAttrib(c,"target"):t.settings.default_link_target||null,b.rel=c?w.getAttrib(c,"rel"):null,b["class"]=c?w.getAttrib(c,"class"):null,b.title=c?w.getAttrib(c,"title"):"",x&&(v={name:"text",type:"textbox",size:40,label:"Text to display",onchange:function(){b.text=this.value()}}),e&&(h={type:"listbox",label:"Link list",values:l(),onselect:n,value:t.convertURL(b.href,"href"),onPostRender:function(){h=this}}),t.settings.target_list!==!1&&(m={name:"target",type:"listbox",label:"Target",values:a("target_list","target",[{text:"None",value:""},{text:"New window",value:"_blank"}])}),t.settings.rel_list&&(g={name:"rel",type:"listbox",label:"Rel",values:a("rel_list","rel",[{text:"None",value:""}])}),t.settings.link_class_list&&(p={name:"class",type:"listbox",label:"Class",values:i(a("link_class_list","class"))}),t.settings.link_title!==!1&&(y={name:"title",type:"textbox",label:"Title",value:b.title}),d=t.windowManager.open({title:"Insert link",data:b,body:[{name:"href",type:"filepicker",filetype:"file",size:40,autofocus:!0,label:"Url",onchange:o,onkeyup:o},v,y,r(b.href),h,g,m,p],onSubmit:function(e){function n(e,n){var l=t.selection.getRng();window.setTimeout(function(){t.windowManager.confirm(e,function(e){t.selection.setRng(l),n(e)})},0)}function l(){var e={href:i,target:b.target?b.target:null,rel:b.rel?b.rel:null,"class":b["class"]?b["class"]:null,title:b.title?b.title:null};c?(t.focus(),x&&b.text!=f&&("innerText"in c?c.innerText=b.text:c.textContent=b.text),w.setAttribs(c,e),k.select(c),t.undoManager.add()):x?t.insertContent(w.createHTML("a",e,w.encode(b.text))):t.execCommand("mceInsertLink",!1,e)}var i;return b=tinymce.extend(b,e.data),(i=b.href)?i.indexOf("@")>0&&-1==i.indexOf("//")&&-1==i.indexOf("mailto:")?void n("The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",function(t){t&&(i="mailto:"+i),l()}):/^\s*www\./i.test(i)?void n("The URL you entered seems to be an external link. Do you want to add the required http:// prefix?",function(t){t&&(i="http://"+i),l()}):void l():void t.execCommand("unlink")}})}t.addButton("link",{icon:"link",tooltip:"Insert/edit link",shortcut:"Ctrl+K",onclick:e(n),stateSelector:"a[href]"}),t.addButton("unlink",{icon:"unlink",tooltip:"Remove link",cmd:"unlink",stateSelector:"a[href]"}),t.addShortcut("Ctrl+K","",e(n)),this.showDialog=n,t.addMenuItem("link",{icon:"link",text:"Insert link",shortcut:"Ctrl+K",onclick:e(n),stateSelector:"a[href]",context:"insert",prependToContext:!0})});tinymce.PluginManager.add("lists",function(e){function t(e){return e&&/^(OL|UL)$/.test(e.nodeName)}function n(e){return e.parentNode.firstChild==e}function r(e){return e.parentNode.lastChild==e}function o(t){return t&&!!e.schema.getTextBlockElements()[t.nodeName]}function i(e){return e&&"SPAN"===e.nodeName&&"bookmark"===e.getAttribute("data-mce-type")}var a=this;e.on("init",function(){function d(e){function t(t){var r,o,i;o=e[t?"startContainer":"endContainer"],i=e[t?"startOffset":"endOffset"],1==o.nodeType&&(r=b.create("span",{"data-mce-type":"bookmark"}),o.hasChildNodes()?(i=Math.min(i,o.childNodes.length-1),t?o.insertBefore(r,o.childNodes[i]):b.insertAfter(r,o.childNodes[i])):o.appendChild(r),o=r,i=0),n[t?"startContainer":"endContainer"]=o,n[t?"startOffset":"endOffset"]=i}var n={};return t(!0),e.collapsed||t(),n}function s(e){function t(t){function n(e){for(var t=e.parentNode.firstChild,n=0;t;){if(t==e)return n;(1!=t.nodeType||"bookmark"!=t.getAttribute("data-mce-type"))&&n++,t=t.nextSibling}return-1}var r,o,i;r=i=e[t?"startContainer":"endContainer"],o=e[t?"startOffset":"endOffset"],r&&(1==r.nodeType&&(o=n(r),r=r.parentNode,b.remove(i)),e[t?"startContainer":"endContainer"]=r,e[t?"startOffset":"endOffset"]=o)}t(!0),t();var n=b.createRng();n.setStart(e.startContainer,e.startOffset),e.endContainer&&n.setEnd(e.endContainer,e.endOffset),k.setRng(n)}function f(t,n){var r,o,i,a=b.createFragment(),d=e.schema.getBlockElements();if(e.settings.forced_root_block&&(n=n||e.settings.forced_root_block),n&&(o=b.create(n),o.tagName===e.settings.forced_root_block&&b.setAttribs(o,e.settings.forced_root_block_attrs),a.appendChild(o)),t)for(;r=t.firstChild;){var s=r.nodeName;i||"SPAN"==s&&"bookmark"==r.getAttribute("data-mce-type")||(i=!0),d[s]?(a.appendChild(r),o=null):n?(o||(o=b.create(n),a.appendChild(o)),o.appendChild(r)):a.appendChild(r)}return e.settings.forced_root_block?i||tinymce.Env.ie&&!(tinymce.Env.ie>10)||o.appendChild(b.create("br",{"data-mce-bogus":"1"})):a.appendChild(b.create("br")),a}function l(){return tinymce.grep(k.getSelectedBlocks(),function(e){return"LI"==e.nodeName})}function c(e,t,n){var r,o,i=b.select('span[data-mce-type="bookmark"]',e);n=n||f(t),r=b.createRng(),r.setStartAfter(t),r.setEndAfter(e),o=r.extractContents(),b.isEmpty(o)||b.insertAfter(o,e),b.insertAfter(n,e),b.isEmpty(t.parentNode)&&(tinymce.each(i,function(e){t.parentNode.parentNode.insertBefore(e,t.parentNode)}),b.remove(t.parentNode)),b.remove(t)}function p(e){var n,r;if(n=e.nextSibling,n&&t(n)&&n.nodeName==e.nodeName){for(;r=n.firstChild;)e.appendChild(r);b.remove(n)}if(n=e.previousSibling,n&&t(n)&&n.nodeName==e.nodeName){for(;r=n.firstChild;)e.insertBefore(r,e.firstChild);b.remove(n)}}function u(e){tinymce.each(tinymce.grep(b.select("ol,ul",e)),function(e){var n,r=e.parentNode;"LI"==r.nodeName&&r.firstChild==e&&(n=r.previousSibling,n&&"LI"==n.nodeName&&(n.appendChild(e),b.isEmpty(r)&&b.remove(r))),t(r)&&(n=r.previousSibling,n&&"LI"==n.nodeName&&n.appendChild(e))})}function m(e){function o(e){b.isEmpty(e)&&b.remove(e)}var i,a=e.parentNode,d=a.parentNode;return n(e)&&r(e)?("LI"==d.nodeName?(b.insertAfter(e,d),o(d),b.remove(a)):t(d)?b.remove(a,!0):(d.insertBefore(f(e),a),b.remove(a)),!0):n(e)?("LI"==d.nodeName?(b.insertAfter(e,d),e.appendChild(a),o(d)):t(d)?d.insertBefore(e,a):(d.insertBefore(f(e),a),b.remove(e)),!0):r(e)?("LI"==d.nodeName?b.insertAfter(e,d):t(d)?b.insertAfter(e,a):(b.insertAfter(f(e),a),b.remove(e)),!0):("LI"==d.nodeName?(a=d,i=f(e,"LI")):i=t(d)?f(e,"LI"):f(e),c(a,e,i),u(a.parentNode),!0)}function h(e){function n(n,r){var o;if(t(n)){for(;o=e.lastChild.firstChild;)r.appendChild(o);b.remove(n)}}var r,o;return r=e.previousSibling,r&&t(r)?(r.appendChild(e),!0):r&&"LI"==r.nodeName&&t(r.lastChild)?(r.lastChild.appendChild(e),n(e.lastChild,r.lastChild),!0):(r=e.nextSibling,r&&t(r)?(r.insertBefore(e,r.firstChild),!0):r&&"LI"==r.nodeName&&t(e.lastChild)?!1:(r=e.previousSibling,r&&"LI"==r.nodeName?(o=b.create(e.parentNode.nodeName),r.appendChild(o),o.appendChild(e),n(e.lastChild,o),!0):!1))}function v(){var t=l();if(t.length){for(var n=d(k.getRng(!0)),r=0;r0))return n;for(var o=new tinymce.dom.TreeWalker(e.startContainer);n=o[t?"next":"prev"]();)if(3==n.nodeType&&n.data.length>0)return n}function r(e,n){var r,o,i=e.parentNode;for(t(n.lastChild)&&(o=n.lastChild),r=n.lastChild,r&&"BR"==r.nodeName&&e.hasChildNodes()&&b.remove(r);r=e.firstChild;)n.appendChild(r);o&&n.appendChild(o),b.remove(e),b.isEmpty(i)&&b.remove(i)}if(k.isCollapsed()){var o=b.getParent(k.getStart(),"LI");if(o){var i=k.getRng(!0),a=b.getParent(n(i,e),"LI");if(a&&a!=o){var f=d(i);return e?r(a,o):r(o,a),s(f),!0}if(!a&&!e&&N(o.parentNode.nodeName))return!0}}},e.addCommand("Indent",function(){return v()?void 0:!0}),e.addCommand("Outdent",function(){return C()?void 0:!0}),e.addCommand("InsertUnorderedList",function(){y("UL")}),e.addCommand("InsertOrderedList",function(){y("OL")}),e.on("keydown",function(t){9==t.keyCode&&e.dom.getParent(e.selection.getStart(),"LI")&&(t.preventDefault(),t.shiftKey?C():v())})}),e.addButton("indent",{icon:"indent",title:"Increase indent",cmd:"Indent",onPostRender:function(){var t=this;e.on("nodechange",function(){for(var r=e.selection.getSelectedBlocks(),o=!1,i=0,a=r.length;!o&&a>i;i++){var d=r[i].nodeName;o="LI"==d&&n(r[i])||"UL"==d||"OL"==d}t.disabled(o)})}}),e.on("keydown",function(e){e.keyCode==tinymce.util.VK.BACKSPACE?a.backspaceDelete()&&e.preventDefault():e.keyCode==tinymce.util.VK.DELETE&&a.backspaceDelete(!0)&&e.preventDefault()})});tinymce.PluginManager.add("media",function(e,t){function i(e){return-1!=e.indexOf(".mp3")?"audio/mpeg":-1!=e.indexOf(".wav")?"audio/wav":-1!=e.indexOf(".mp4")?"video/mp4":-1!=e.indexOf(".webm")?"video/webm":-1!=e.indexOf(".ogg")?"video/ogg":-1!=e.indexOf(".swf")?"application/x-shockwave-flash":""}function r(t){var i=e.settings.media_scripts;if(i)for(var r=0;r':"application/x-shockwave-flash"==o.source1mime?(a+='',o.poster&&(a+=''),a+=""):-1!=o.source1mime.indexOf("audio")?e.settings.audio_template_callback?a=e.settings.audio_template_callback(o):a+='":"script"==o.type?a+='':a=e.settings.video_template_callback?e.settings.video_template_callback(o):'"}return a}function s(e){var t={};return new tinymce.html.SaxParser({validate:!1,allow_conditional_comments:!0,special:"script,noscript",start:function(e,i){if(t.source1||"param"!=e||(t.source1=i.map.movie),("iframe"==e||"object"==e||"embed"==e||"video"==e||"audio"==e)&&(t.type||(t.type=e),t=tinymce.extend(i.map,t)),"script"==e){var o=r(i.map.src);if(!o)return;t={type:"script",source1:i.map.src,width:o.width,height:o.height}}"source"==e&&(t.source1?t.source2||(t.source2=i.map.src):t.source1=i.map.src),"img"!=e||t.poster||(t.poster=i.map.src)}}).parse(e),t.source1=t.source1||t.src||t.data,t.source2=t.source2||"",t.poster=t.poster||"",t}function n(t){return t.getAttribute("data-mce-object")?s(e.serializer.serialize(t,{selection:!0})):{}}function m(e,t,i){function r(e,t){var i,r,o,a;for(i in t)if(o=""+t[i],e.map[i])for(r=e.length;r--;)a=e[r],a.name==i&&(o?(e.map[i]=o,a.value=o):(delete e.map[i],e.splice(r,1)));else o&&(e.push({name:i,value:o}),e.map[i]=o)}var o,a=new tinymce.html.Writer,c=0;return new tinymce.html.SaxParser({validate:!1,allow_conditional_comments:!0,special:"script,noscript",comment:function(e){a.comment(e)},cdata:function(e){a.cdata(e)},text:function(e,t){a.text(e,t)},start:function(e,s,n){switch(e){case"video":case"object":case"embed":case"img":case"iframe":r(s,{width:t.width,height:t.height})}if(i)switch(e){case"video":r(s,{poster:t.poster,src:""}),t.source2&&r(s,{src:""});break;case"iframe":r(s,{src:t.source1});break;case"source":if(c++,2>=c&&(r(s,{src:t["source"+c],type:t["source"+c+"mime"]}),!t["source"+c]))return;break;case"img":if(!t.poster)return;o=!0}a.start(e,s,n)},end:function(e){if("video"==e&&i)for(var s=1;2>=s;s++)if(t["source"+s]){var n=[];n.map={},s>c&&(r(n,{src:t["source"+s],type:t["source"+s+"mime"]}),a.start("source",n,!0))}if(t.poster&&"object"==e&&i&&!o){var m=[];m.map={},r(m,{src:t.poster,width:t.width,height:t.height}),a.start("img",m,!0)}a.end(e)}},new tinymce.html.Schema({})).parse(e),a.getContent()}var u=[{regex:/youtu\.be\/([\w\-.]+)/,type:"iframe",w:425,h:350,url:"//www.youtube.com/embed/$1"},{regex:/youtube\.com(.+)v=([^&]+)/,type:"iframe",w:425,h:350,url:"//www.youtube.com/embed/$2"},{regex:/vimeo\.com\/([0-9]+)/,type:"iframe",w:425,h:350,url:"//player.vimeo.com/video/$1?title=0&byline=0&portrait=0&color=8dc7dc"},{regex:/maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/,type:"iframe",w:425,h:350,url:'//maps.google.com/maps/ms?msid=$2&output=embed"'}];e.on("ResolveName",function(e){var t;1==e.target.nodeType&&(t=e.target.getAttribute("data-mce-object"))&&(e.name=t)}),e.on("preInit",function(){var t=e.schema.getSpecialElements();tinymce.each("video audio iframe object".split(" "),function(e){t[e]=new RegExp("]*>","gi")});var i=e.schema.getBoolAttrs();tinymce.each("webkitallowfullscreen mozallowfullscreen allowfullscreen".split(" "),function(e){i[e]={}}),e.parser.addNodeFilter("iframe,video,audio,object,embed,script",function(t,i){for(var o,a,c,s,n,m,u,d,l=t.length;l--;)if(a=t[l],a.parent&&("script"!=a.name||(d=r(a.attr("src"))))){for(c=new tinymce.html.Node("img",1),c.shortEnded=!0,d&&(d.width&&a.attr("width",d.width.toString()),d.height&&a.attr("height",d.height.toString())),m=a.attributes,o=m.length;o--;)s=m[o].name,n=m[o].value,"width"!==s&&"height"!==s&&"style"!==s&&(("data"==s||"src"==s)&&(n=e.convertURL(n,s)),c.attr("data-mce-p-"+s,n));u=a.firstChild&&a.firstChild.value,u&&(c.attr("data-mce-html",escape(u)),c.firstChild=null),c.attr({width:a.attr("width")||"300",height:a.attr("height")||("audio"==i?"30":"150"),style:a.attr("style"),src:tinymce.Env.transparentSrc,"data-mce-object":i,"class":"mce-object mce-object-"+i}),a.replace(c)}}),e.serializer.addAttributeFilter("data-mce-object",function(e,t){for(var i,r,o,a,c,s,n,m=e.length;m--;)if(i=e[m],i.parent){for(n=i.attr(t),r=new tinymce.html.Node(n,1),"audio"!=n&&"script"!=n&&r.attr({width:i.attr("width"),height:i.attr("height")}),r.attr({style:i.attr("style")}),a=i.attributes,o=a.length;o--;){var u=a[o].name;0===u.indexOf("data-mce-p-")&&r.attr(u.substr(11),a[o].value)}"script"==n&&r.attr("type","text/javascript"),c=i.attr("data-mce-html"),c&&(s=new tinymce.html.Node("#text",3),s.raw=!0,s.value=unescape(c),r.append(s)),i.replace(r)}})}),e.on("ObjectSelected",function(e){var t=e.target.getAttribute("data-mce-object");("audio"==t||"script"==t)&&e.preventDefault()}),e.on("objectResized",function(e){var t,i=e.target;i.getAttribute("data-mce-object")&&(t=i.getAttribute("data-mce-html"),t&&(t=unescape(t),i.setAttribute("data-mce-html",escape(m(t,{width:e.width,height:e.height})))))}),e.addButton("media",{tooltip:"Insert/edit video",onclick:o,stateSelector:["img[data-mce-object=video]","img[data-mce-object=iframe]"]}),e.addMenuItem("media",{icon:"media",text:"Insert video",onclick:o,context:"insert",prependToContext:!0})});tinymce.PluginManager.add("nonbreaking",function(n){var e=n.getParam("nonbreaking_force_tab");if(n.addCommand("mceNonBreaking",function(){n.insertContent(n.plugins.visualchars&&n.plugins.visualchars.state?' ':" "),n.dom.setAttrib(n.dom.select("span.mce-nbsp"),"data-mce-bogus","1")}),n.addButton("nonbreaking",{title:"Insert nonbreaking space",cmd:"mceNonBreaking"}),n.addMenuItem("nonbreaking",{text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"}),e){var a=+e>1?+e:3;n.on("keydown",function(e){if(9==e.keyCode){if(e.shiftKey)return;e.preventDefault();for(var t=0;a>t;t++)n.execCommand("mceNonBreaking")}})}});tinymce.PluginManager.add("noneditable",function(e){function t(e){var t;if(1===e.nodeType){if(t=e.getAttribute(u),t&&"inherit"!==t)return t;if(t=e.contentEditable,"inherit"!==t)return t}return null}function n(e){for(var n;e;){if(n=t(e))return"false"===n?e:null;e=e.parentNode}}function r(){function r(e){for(;e;){if(e.id===g)return e;e=e.parentNode}}function a(e){var t;if(e)for(t=new f(e,e),e=t.current();e;e=t.next())if(3===e.nodeType)return e}function i(n,r){var a,i;return"false"===t(n)&&u.isBlock(n)?void s.select(n):(i=u.createRng(),"true"===t(n)&&(n.firstChild||n.appendChild(e.getDoc().createTextNode(" ")),n=n.firstChild,r=!0),a=u.create("span",{id:g,"data-mce-bogus":!0},m),r?n.parentNode.insertBefore(a,n):u.insertAfter(a,n),i.setStart(a.firstChild,1),i.collapse(!0),s.setRng(i),a)}function o(e){var t,n,i,o;if(e)t=s.getRng(!0),t.setStartBefore(e),t.setEndBefore(e),n=a(e),n&&n.nodeValue.charAt(0)==m&&(n=n.deleteData(0,1)),u.remove(e,!0),s.setRng(t);else for(i=r(s.getStart());(e=u.get(g))&&e!==o;)i!==e&&(n=a(e),n&&n.nodeValue.charAt(0)==m&&(n=n.deleteData(0,1)),u.remove(e,!0)),o=e}function l(){function e(e,n){var r,a,i,o,l;if(r=d.startContainer,a=d.startOffset,3==r.nodeType){if(l=r.nodeValue.length,a>0&&l>a||(n?a==l:0===a))return}else{if(!(a0?a-1:a;r=r.childNodes[u],r.hasChildNodes()&&(r=r.firstChild)}for(i=new f(r,e);o=i[n?"prev":"next"]();){if(3===o.nodeType&&o.nodeValue.length>0)return;if("true"===t(o))return o}return e}var r,a,l,d,u;o(),l=s.isCollapsed(),r=n(s.getStart()),a=n(s.getEnd()),(r||a)&&(d=s.getRng(!0),l?(r=r||a,(u=e(r,!0))?i(u,!0):(u=e(r,!1))?i(u,!1):s.select(r)):(d=s.getRng(!0),r&&d.setStartBefore(r),a&&d.setEndAfter(a),s.setRng(d)))}function d(a){function i(e,t){for(;e=e[t?"previousSibling":"nextSibling"];)if(3!==e.nodeType||e.nodeValue.length>0)return e}function d(e,t){s.select(e),s.collapse(t)}function g(a){function i(e){for(var t=d;t;){if(t===e)return;t=t.parentNode}u.remove(e),l()}function o(){var r,o,l=e.schema.getNonEmptyElements();for(o=new tinymce.dom.TreeWalker(d,e.getBody());(r=a?o.prev():o.next())&&!l[r.nodeName.toLowerCase()]&&!(3===r.nodeType&&tinymce.trim(r.nodeValue).length>0);)if("false"===t(r))return i(r),!0;return n(r)?!0:!1}var f,d,c,g;if(s.isCollapsed()){if(f=s.getRng(!0),d=f.startContainer,c=f.startOffset,d=r(d)||d,g=n(d))return i(g),!1;if(3==d.nodeType&&(a?c>0:ch||h>124)&&h!=c.DELETE&&h!=c.BACKSPACE){if((tinymce.isMac?a.metaKey:a.ctrlKey)&&(67==h||88==h||86==h))return;if(a.preventDefault(),h==c.LEFT||h==c.RIGHT){var y=h==c.LEFT;if(e.dom.isBlock(m)){var T=y?m.previousSibling:m.nextSibling,C=new f(T,T),b=y?C.prev():C.next();d(b,!y)}else d(m,y)}}else if(h==c.LEFT||h==c.RIGHT||h==c.BACKSPACE||h==c.DELETE){if(p=r(v)){if(h==c.LEFT||h==c.BACKSPACE)if(m=i(p,!0),m&&"false"===t(m)){if(a.preventDefault(),h!=c.LEFT)return void u.remove(m);d(m,!0)}else o(p);if(h==c.RIGHT||h==c.DELETE)if(m=i(p),m&&"false"===t(m)){if(a.preventDefault(),h!=c.RIGHT)return void u.remove(m);d(m,!1)}else o(p)}if((h==c.BACKSPACE||h==c.DELETE)&&!g(h==c.BACKSPACE))return a.preventDefault(),!1}}var u=e.dom,s=e.selection,g="mce_noneditablecaret",m="";e.on("mousedown",function(n){var r=e.selection.getNode();"false"===t(r)&&r==n.target&&l()}),e.on("mouseup keyup",l),e.on("keydown",d)}function a(t){var n=l.length,r=t.content,a=tinymce.trim(o);if("raw"!=t.format){for(;n--;)r=r.replace(l[n],function(t){var n=arguments,i=n[n.length-2];return i>0&&'"'==r.charAt(i-1)?t:''+e.dom.encode("string"==typeof n[1]?n[1]:n[0])+""});t.content=r}}var i,o,l,f=tinymce.dom.TreeWalker,d="contenteditable",u="data-mce-"+d,c=tinymce.util.VK;i=" "+tinymce.trim(e.getParam("noneditable_editable_class","mceEditable"))+" ",o=" "+tinymce.trim(e.getParam("noneditable_noneditable_class","mceNonEditable"))+" ",l=e.getParam("noneditable_regexp"),l&&!l.length&&(l=[l]),e.on("PreInit",function(){r(),l&&e.on("BeforeSetContent",a),e.parser.addAttributeFilter("class",function(e){for(var t,n,r=e.length;r--;)n=e[r],t=" "+n.attr("class")+" ",-1!==t.indexOf(i)?n.attr(u,"true"):-1!==t.indexOf(o)&&n.attr(u,"false")}),e.serializer.addAttributeFilter(u,function(e){for(var t,n=e.length;n--;)t=e[n],l&&t.attr("data-mce-content")?(t.name="#text",t.type=3,t.raw=!0,t.value=t.attr("data-mce-content")):(t.attr(d,null),t.attr(u,null))}),e.parser.addAttributeFilter(d,function(e){for(var t,n=e.length;n--;)t=e[n],t.attr(u,t.attr(d)),t.attr(d,null)})}),e.on("drop",function(e){n(e.target)&&e.preventDefault()})});tinymce.PluginManager.add("pagebreak",function(e){var a="mce-pagebreak",t=e.getParam("pagebreak_separator",""),n=new RegExp(t.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(e){return"\\"+e}),"gi"),r='';e.addCommand("mcePageBreak",function(){e.insertContent(e.settings.pagebreak_split_block?"

    "+r+"

    ":r)}),e.addButton("pagebreak",{title:"Page break",cmd:"mcePageBreak"}),e.addMenuItem("pagebreak",{text:"Page break",icon:"pagebreak",cmd:"mcePageBreak",context:"insert"}),e.on("ResolveName",function(t){"IMG"==t.target.nodeName&&e.dom.hasClass(t.target,a)&&(t.name="pagebreak")}),e.on("click",function(t){t=t.target,"IMG"===t.nodeName&&e.dom.hasClass(t,a)&&e.selection.select(t)}),e.on("BeforeSetContent",function(e){e.content=e.content.replace(n,r)}),e.on("PreInit",function(){e.serializer.addNodeFilter("img",function(a){for(var n,r,c=a.length;c--;)if(n=a[c],r=n.attr("class"),r&&-1!==r.indexOf("mce-pagebreak")){var o=n.parent;if(e.schema.getBlockElements()[o.name]&&e.settings.pagebreak_split_block){o.type=3,o.value=t,o.raw=!0,n.remove();continue}n.type=3,n.value=t,n.raw=!0}})})});!function(e,t){"use strict";function n(e,t){for(var n,i=[],r=0;r"),t&&/^(PRE|DIV)$/.test(t.nodeName)||!o?e=n.filter(e,[[/\n/g,"
    "]]):(e=n.filter(e,[[/\n\n/g,"

    "+a],[/^(.*<\/p>)(

    )$/,a+"$1"],[/\n/g,"
    "]]),-1!=e.indexOf("

    ")&&(e=a+e)),r(e)}function a(){var t=i.dom,n=i.getBody(),r=i.dom.getViewPort(i.getWin()),o=r.y,a=20,s;if(v=i.selection.getRng(),i.inline&&(s=i.selection.getScrollContainer(),s&&s.scrollTop>0&&(o=s.scrollTop)),v.getClientRects){var l=v.getClientRects();if(l.length)a=o+(l[0].top-t.getPos(n).y);else{a=o;var c=v.startContainer;c&&(3==c.nodeType&&c.parentNode!=n&&(c=c.parentNode),1==c.nodeType&&(a=t.getPos(c,s||n).y))}}h=t.add(i.getBody(),"div",{id:"mcepastebin",contentEditable:!0,"data-mce-bogus":"1",style:"position: absolute; top: "+a+"px;width: 10px; height: 10px; overflow: hidden; opacity: 0"},y),(e.ie||e.gecko)&&t.setStyle(h,"left","rtl"==t.getStyle(n,"direction",!0)?65535:-65535),t.bind(h,"beforedeactivate focusin focusout",function(e){e.stopPropagation()}),h.focus(),i.selection.select(h,!0)}function s(){if(h){for(var e;e=i.dom.get("mcepastebin");)i.dom.remove(e),i.dom.unbind(e);v&&i.selection.setRng(v)}x=!1,h=v=null}function l(){var e=y,t,n;for(t=i.dom.select("div[id=mcepastebin]"),n=t.length;n--;){var r=t[n].innerHTML;e==y&&(e=""),r.length>e.length&&(e=r)}return e}function c(e){var t={};if(e&&e.types){var n=e.getData("Text");n&&n.length>0&&(t["text/plain"]=n);for(var i=0;i')},t.readAsDataURL(e.getAsFile()),!0}}if(!(!i.settings.paste_data_images||"text/html"in t||"text/plain"in t)&&e.clipboardData){var o=e.clipboardData.items;if(o)for(var a=0;a0}function p(){i.on("keydown",function(n){if(!n.isDefaultPrevented()&&(t.metaKeyPressed(n)&&86==n.keyCode||n.shiftKey&&45==n.keyCode)){if(x=n.shiftKey&&86==n.keyCode,n.stopImmediatePropagation(),b=(new Date).getTime(),e.ie&&x)return n.preventDefault(),void i.fire("paste",{ieFake:!0});s(),a()}}),i.on("paste",function(t){var c=d(t),f=(new Date).getTime()-b<1e3,p="text"==g.pasteFormat||x;return t.isDefaultPrevented()?void s():u(t,c)?void s():(f||t.preventDefault(),!e.ie||f&&!t.ieFake||(a(),i.dom.bind(h,"paste",function(e){e.stopPropagation()}),i.getDoc().execCommand("Paste",!1,null),c["text/html"]=l()),void setTimeout(function(){var e=l();return h&&h.firstChild&&"mcepastebin"===h.firstChild.id&&(p=!0),s(),!p&&f&&e&&e!=y&&(c["text/html"]=e),e!=y&&f||(e=c["text/html"]||c["text/plain"]||y,e!=y)?(!m(c,"text/html")&&m(c,"text/plain")&&(p=!0),void(p?o(c["text/plain"]||n.innerText(e)):r(e))):void(f||i.windowManager.alert("Please use Ctrl+V/Cmd+V keyboard shortcuts to paste contents."))},0))}),i.on("dragstart",function(e){if(e.dataTransfer.types)try{e.dataTransfer.setData("mce-internal",i.selection.getContent())}catch(t){}}),i.on("drop",function(e){var t=f(e);if(t&&!e.isDefaultPrevented()){var n=c(e.dataTransfer),a=n["mce-internal"]||n["text/html"]||n["text/plain"];a&&(e.preventDefault(),i.undoManager.transact(function(){n["mce-internal"]&&i.execCommand("Delete"),i.selection.setRng(t),n["text/html"]?r(a):o(a)}))}})}var g=this,h,v,b=0,y="%MCEPASTEBIN%",x;g.pasteHtml=r,g.pasteText=o,i.on("preInit",function(){p(),i.parser.addNodeFilter("img",function(t){if(!i.settings.paste_data_images)for(var n=t.length;n--;){var r=t[n].attributes.map.src;r&&0===r.indexOf("data:image")&&(t[n].attr("data-mce-object")||r===e.transparentSrc||t[n].remove())}})}),i.on("PreProcess",function(){i.dom.remove(i.dom.get("mcepastebin"))})}}),i(g,[c,d,u,h,v,l],function(e,t,n,i,r,o){function a(e){return/l?n&&(n=n.parent.parent):(i=n,n=null)),n&&n.name==a?n.append(e):(i=i||n,n=new r(a,1),s>1&&n.attr("start",""+s),e.wrap(n)),e.name="li",t.value="";var c=t.next;c&&3==c.type&&(c.value=c.value.replace(/^\u00a0+/,"")),l>o&&i&&i.lastChild.append(n),o=l}for(var n,i,o=1,a=e.getAll("p"),s=0;s/gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/ /gi,"\xa0"],[/([\s\u00a0]*)<\/span>/gi,function(e,t){return t.length>0?t.replace(/./," ").slice(Math.floor(t.length/2)).split("").join("\xa0"):""}]]);var g=l.paste_word_valid_elements;g||(g="-strong/b,-em/i,-span,-p,-ol,-ul,-li,-h1,-h2,-h3,-h4,-h5,-h6,-p/div,-table[width],-tr,-td[colspan|rowspan|width],-th,-thead,-tfoot,-tbody,-a[href|name],sub,sup,strike,br,del");var h=new n({valid_elements:g,valid_children:"-li[p]"});e.each(h.elements,function(e){e.attributes["class"]||(e.attributes["class"]={},e.attributesOrder.push("class")),e.attributes.style||(e.attributes.style={},e.attributesOrder.push("style"))});var v=new t({},h);v.addAttributeFilter("style",function(e){for(var t=e.length,n;t--;)n=e[t],n.attr("style",u(n,n.attr("style"))),"span"==n.name&&n.parent&&!n.attributes.length&&n.unwrap()}),v.addAttributeFilter("class",function(e){for(var t=e.length,n,i;t--;)n=e[t],i=n.attr("class"),/^(MsoCommentReference|MsoCommentText|msoDel)$/i.test(i)&&n.remove(),n.attr("class",null)}),v.addNodeFilter("del",function(e){for(var t=e.length;t--;)e[t].remove()}),v.addNodeFilter("a",function(e){for(var t=e.length,n,i,r;t--;)if(n=e[t],i=n.attr("href"),r=n.attr("name"),i&&-1!=i.indexOf("#_msocom_"))n.remove();else if(i&&0===i.indexOf("file://")&&(i=i.split("#")[1],i&&(i="#"+i)),i||r){if(r&&!/^_?(?:toc|edn|ftn)/i.test(r)){n.unwrap();continue}n.attr({href:i,name:r})}else n.unwrap()});var b=v.parse(f);d(b),c.content=new i({},h).serialize(b)}})}return s.isWordContent=a,s}),i(b,[m,c,g,l],function(e,t,n,i){return function(r){function o(e){r.on("BeforePastePreProcess",function(t){t.content=e(t.content)})}function a(e){return e=i.filter(e,[/^[\s\S]*]*>\s*|\s*<\/body[^>]*>[\s\S]*$/g,/|/g,[/\u00a0<\/span>/g,"\xa0"],/
    $/i])}function s(e){if(!n.isWordContent(e))return e;var o=[];t.each(r.schema.getBlockElements(),function(e,t){o.push(t)});var a=new RegExp("(?:
     [\\s\\r\\n]+|
    )*(<\\/?("+o.join("|")+")[^>]*>)(?:
     [\\s\\r\\n]+|
    )*","g");return e=i.filter(e,[[a,"$1"]]),e=i.filter(e,[[/

    /g,"

    "],[/
    /g," "],[/

    /g,"
    "]])}function l(e){if(n.isWordContent(e))return e;var t=r.settings.paste_webkit_styles;if(r.settings.paste_remove_styles_if_webkit===!1||"all"==t)return e;if(t&&(t=t.split(/[, ]/)),t){var i=r.dom,o=r.selection.getNode();e=e.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi,function(e,n,r,a){var s=i.parseStyle(r,"span"),l={};if("none"===t)return n+a;for(var c=0;c]+) style="([^"]*)"([^>]*>)/gi,"$1$3");return e=e.replace(/(<[^>]+) data-mce-style="([^"]+)"([^>]*>)/gi,function(e,t,n,i){return t+' style="'+n+'"'+i})}e.webkit&&(o(l),o(a)),e.ie&&o(s)}}),i(y,[x,f,g,b],function(e,t,n,i){var r;e.add("paste",function(e){function o(){"text"==s.pasteFormat?(this.active(!1),s.pasteFormat="html"):(s.pasteFormat="text",this.active(!0),r||(e.windowManager.alert("Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off."),r=!0))}var a=this,s,l=e.settings;a.clipboard=s=new t(e),a.quirks=new i(e),a.wordFilter=new n(e),e.settings.paste_as_text&&(a.clipboard.pasteFormat="text"),l.paste_preprocess&&e.on("PastePreProcess",function(e){l.paste_preprocess.call(a,a,e)}),l.paste_postprocess&&e.on("PastePostProcess",function(e){l.paste_postprocess.call(a,a,e)}),e.addCommand("mceInsertClipboardContent",function(e,t){t.content&&a.clipboard.pasteHtml(t.content),t.text&&a.clipboard.pasteText(t.text)}),e.paste_block_drop&&e.on("dragend dragover draggesture dragdrop drop drag",function(e){e.preventDefault(),e.stopPropagation()}),e.settings.paste_data_images||e.on("drop",function(e){var t=e.dataTransfer;t&&t.files&&t.files.length>0&&e.preventDefault()}),e.addButton("pastetext",{icon:"pastetext",tooltip:"Paste as text",onclick:o,active:"text"==a.clipboard.pasteFormat}),e.addMenuItem("pastetext",{text:"Paste as text",selectable:!0,active:s.pasteFormat,onclick:o})})}),a([l,f,g,b,y])}(this);tinymce.PluginManager.add("preview",function(e){var t=e.settings,i=!tinymce.Env.ie;e.addCommand("mcePreview",function(){e.windowManager.open({title:"Preview",width:parseInt(e.getParam("plugin_preview_width","650"),10),height:parseInt(e.getParam("plugin_preview_height","500"),10),html:'",buttons:{text:"Close",onclick:function(){this.parent().parent().close()}},onPostRender:function(){var n,a="";a+='',tinymce.each(e.contentCSS,function(t){a+=''});var r=t.body_id||"tinymce";-1!=r.indexOf("=")&&(r=e.getParam("body_id","","hash"),r=r[e.id]||r);var d=t.body_class||"";-1!=d.indexOf("=")&&(d=e.getParam("body_class","","hash"),d=d[e.id]||"");var o=e.settings.directionality?' dir="'+e.settings.directionality+'"':"";if(n=""+a+'"+e.getContent()+"",i)this.getEl("body").firstChild.src="data:text/html;charset=utf-8,"+encodeURIComponent(n);else{var s=this.getEl("body").firstChild.contentWindow.document;s.open(),s.write(n),s.close()}}})}),e.addButton("preview",{title:"Preview",cmd:"mcePreview"}),e.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})});tinymce.PluginManager.add("print",function(t){t.addCommand("mcePrint",function(){t.getWin().print()}),t.addButton("print",{title:"Print",cmd:"mcePrint"}),t.addShortcut("Ctrl+P","","mcePrint"),t.addMenuItem("print",{text:"Print",cmd:"mcePrint",icon:"print",shortcut:"Ctrl+P",context:"file"})});tinymce.PluginManager.add("save",function(e){function a(){var a;return a=tinymce.DOM.getParent(e.id,"form"),!e.getParam("save_enablewhendirty",!0)||e.isDirty()?(tinymce.triggerSave(),e.getParam("save_onsavecallback")?void(e.execCallback("save_onsavecallback",e)&&(e.startContent=tinymce.trim(e.getContent({format:"raw"})),e.nodeChanged())):void(a?(e.isNotDirty=!0,(!a.onsubmit||a.onsubmit())&&("function"==typeof a.submit?a.submit():e.windowManager.alert("Error: Form submit field collision.")),e.nodeChanged()):e.windowManager.alert("Error: No form element found."))):void 0}function n(){var a=tinymce.trim(e.startContent);return e.getParam("save_oncancelcallback")?void e.execCallback("save_oncancelcallback",e):(e.setContent(a),e.undoManager.clear(),void e.nodeChanged())}function t(){var a=this;e.on("nodeChange",function(){a.disabled(e.getParam("save_enablewhendirty",!0)&&!e.isDirty())})}e.addCommand("mceSave",a),e.addCommand("mceCancel",n),e.addButton("save",{icon:"save",text:"Save",cmd:"mceSave",disabled:!0,onPostRender:t}),e.addButton("cancel",{text:"Cancel",icon:!1,cmd:"mceCancel",disabled:!0,onPostRender:t}),e.addShortcut("ctrl+s","","mceSave")});!function(){function e(e,t,n,a,r){function i(e,t){if(t=t||0,!e[0])throw"findAndReplaceDOMText cannot handle zero-length matches";var n=e.index;if(t>0){var a=e[t];if(!a)throw"Invalid capture group";n+=e[0].indexOf(a),e[0]=a}return[n,n+e[0].length,[e[0]]]}function d(e){var t;if(3===e.nodeType)return e.data;if(h[e.nodeName]&&!u[e.nodeName])return"";if(t="",(u[e.nodeName]||m[e.nodeName])&&(t+="\n"),e=e.firstChild)do t+=d(e);while(e=e.nextSibling);return t}function o(e,t,n){var a,r,i,d,o=[],l=0,c=e,s=t.shift(),f=0;e:for(;;){if((u[c.nodeName]||m[c.nodeName])&&l++,3===c.nodeType&&(!r&&c.length+l>=s[1]?(r=c,d=s[1]-l):a&&o.push(c),!a&&c.length+l>s[0]&&(a=c,i=s[0]-l),l+=c.length),a&&r){if(c=n({startNode:a,startNodeIndex:i,endNode:r,endNodeIndex:d,innerNodes:o,match:s[2],matchIndex:f}),l-=r.length-d,a=null,r=null,o=[],s=t.shift(),f++,!s)break}else{if((!h[c.nodeName]||u[c.nodeName])&&c.firstChild){c=c.firstChild;continue}if(c.nextSibling){c=c.nextSibling;continue}}for(;;){if(c.nextSibling){c=c.nextSibling;break}if(c.parentNode===e)break e;c=c.parentNode}}}function l(e){var t;if("function"!=typeof e){var n=e.nodeType?e:f.createElement(e);t=function(e,t){var a=n.cloneNode(!1);return a.setAttribute("data-mce-index",t),e&&a.appendChild(f.createTextNode(e)),a}}else t=e;return function(e){var n,a,r,i=e.startNode,d=e.endNode,o=e.matchIndex;if(i===d){var l=i;r=l.parentNode,e.startNodeIndex>0&&(n=f.createTextNode(l.data.substring(0,e.startNodeIndex)),r.insertBefore(n,l));var c=t(e.match[0],o);return r.insertBefore(c,l),e.endNodeIndexh;++h){var g=e.innerNodes[h],p=t(g.data,o);g.parentNode.replaceChild(p,g),u.push(p)}var x=t(d.data.substring(0,e.endNodeIndex),o);return r=i.parentNode,r.insertBefore(n,i),r.insertBefore(s,i),r.removeChild(i),r=d.parentNode,r.insertBefore(x,d),r.insertBefore(a,d),r.removeChild(d),x}}var c,s,f,u,h,m,g=[],p=0;if(f=t.ownerDocument,u=r.getBlockElements(),h=r.getWhiteSpaceElements(),m=r.getShortEndedElements(),s=d(t)){if(e.global)for(;c=e.exec(s);)g.push(i(c,a));else c=s.match(e),g.push(i(c,a));return g.length&&(p=g.length,o(t,g,l(n))),p}}function t(t){function n(){function e(){r.statusbar.find("#next").disabled(!d(s+1).length),r.statusbar.find("#prev").disabled(!d(s-1).length)}function n(){tinymce.ui.MessageBox.alert("Could not find the specified string.",function(){r.find("#find")[0].focus()})}var a={},r=tinymce.ui.Factory.create({type:"window",layout:"flex",pack:"center",align:"center",onClose:function(){t.focus(),c.done()},onSubmit:function(t){var i,o,l,f;return t.preventDefault(),o=r.find("#case").checked(),f=r.find("#words").checked(),l=r.find("#find").value(),l.length?a.text==l&&a.caseState==o&&a.wholeWord==f?0===d(s+1).length?void n():(c.next(),void e()):(i=c.find(l,o,f),i||n(),r.statusbar.items().slice(1).disabled(0===i),e(),void(a={text:l,caseState:o,wholeWord:f})):(c.done(!1),void r.statusbar.items().slice(1).disabled(!0))},buttons:[{text:"Find",onclick:function(){r.submit()}},{text:"Replace",disabled:!0,onclick:function(){c.replace(r.find("#replace").value())||(r.statusbar.items().slice(1).disabled(!0),s=-1,a={})}},{text:"Replace all",disabled:!0,onclick:function(){c.replace(r.find("#replace").value(),!0,!0),r.statusbar.items().slice(1).disabled(!0),a={}}},{type:"spacer",flex:1},{text:"Prev",name:"prev",disabled:!0,onclick:function(){c.prev(),e()}},{text:"Next",name:"next",disabled:!0,onclick:function(){c.next(),e()}}],title:"Find and replace",items:{type:"form",padding:20,labelGap:30,spacing:10,items:[{type:"textbox",name:"find",size:40,label:"Find",value:t.selection.getNode().src},{type:"textbox",name:"replace",size:40,label:"Replace with"},{type:"checkbox",name:"case",text:"Match case",label:" "},{type:"checkbox",name:"words",text:"Whole words",label:" "}]}}).renderTo().reflow()}function a(e){var t=e.getAttribute("data-mce-index");return"number"==typeof t?""+t:t}function r(n){var a,r;return r=t.dom.create("span",{"data-mce-bogus":1}),r.className="mce-match-marker",a=t.getBody(),c.done(!1),e(n,a,r,!1,t.schema)}function i(e){var t=e.parentNode;e.firstChild&&t.insertBefore(e.firstChild,e),e.parentNode.removeChild(e)}function d(e){var n,r=[];if(n=tinymce.toArray(t.getBody().getElementsByTagName("span")),n.length)for(var i=0;is&&f[o].setAttribute("data-mce-index",m-1)}return t.undoManager.add(),s=p,n?(g=d(p+1).length>0,c.next()):(g=d(p-1).length>0,c.prev()),!r&&g},c.done=function(e){var n,r,d,o;for(r=tinymce.toArray(t.getBody().getElementsByTagName("span")),n=0;n=d.end?(r=c,a=d.end-s):o&&l.push(c),!o&&c.length+s>d.start&&(o=c,i=d.start-s),s+=c.length),o&&r){if(c=n({startNode:o,startNodeIndex:i,endNode:r,endNodeIndex:a,innerNodes:l,match:d.text,matchIndex:u}),s-=r.length-a,o=null,r=null,l=[],d=t.shift(),u++,!d)break}else{if((!P[c.nodeName]||S[c.nodeName])&&c.firstChild){c=c.firstChild;continue}if(c.nextSibling){c=c.nextSibling;continue}}for(;;){if(c.nextSibling){c=c.nextSibling;break}if(c.parentNode===e)break e;c=c.parentNode}}}function i(e){function t(t,n){var o=w[n];o.stencil||(o.stencil=e(o));var r=o.stencil.cloneNode(!1);return r.setAttribute("data-mce-index",n),t&&r.appendChild(k.doc.createTextNode(t)),r}return function(e){var n,o,r,i=e.startNode,a=e.endNode,l=e.matchIndex,s=k.doc;if(i===a){var c=i;r=c.parentNode,e.startNodeIndex>0&&(n=s.createTextNode(c.data.substring(0,e.startNodeIndex)),r.insertBefore(n,c));var d=t(e.match,l);return r.insertBefore(d,c),e.endNodeIndexm;++m){var g=e.innerNodes[m],h=t(g.data,l);g.parentNode.replaceChild(h,g),f.push(h)}var v=t(a.data.substring(0,e.endNodeIndex),l);return r=i.parentNode,r.insertBefore(n,i),r.insertBefore(u,i),r.removeChild(i),r=a.parentNode,r.insertBefore(v,a),r.insertBefore(o,a),r.removeChild(a),v}}function a(e){var t=e.parentNode;t.insertBefore(e.firstChild,e),e.parentNode.removeChild(e)}function l(t){var n=e.getElementsByTagName("*"),o=[];t="number"==typeof t?""+t:null;for(var r=0;rt&&e(w[t],t)!==!1;t++);return this}function u(t){return w.length&&r(e,w,i(t)),this}function f(e,t){if(C&&e.global)for(;x=e.exec(C);)w.push(n(x,t));return this}function m(e){var t,n=l(e?s(e):null);for(t=n.length;t--;)a(n[t]);return this}function p(e){return w[e.getAttribute("data-mce-index")]}function g(e){return l(s(e))[0]}function h(e,t,n){return w.push({start:e,end:e+t,text:C.substr(e,t),data:n}),this}function v(e){var n=l(s(e)),o=t.dom.createRng();return o.setStartBefore(n[0]),o.setEndAfter(n[n.length-1]),o}function b(e,n){var o=v(e);return o.deleteContents(),n.length>0&&o.insertNode(t.dom.doc.createTextNode(n)),o}function y(){return w.splice(0,w.length),m(),this}var x,w=[],C,k=t.dom,S,P,N;return S=t.schema.getBlockElements(),P=t.schema.getWhiteSpaceElements(),N=t.schema.getShortEndedElements(),C=o(e),{text:C,matches:w,each:d,filter:c,reset:y,matchFromElement:p,elementFromMatch:g,find:f,add:h,wrap:u,unwrap:m,replace:b,rangeFromMatch:v,indexOf:s}}}),o(c,[s,d,u,f,m,p,g,h],function(e,t,n,o,r,i,a,l){t.add("spellchecker",function(t,s){function c(){return C.textMatcher||(C.textMatcher=new e(t.getBody(),t)),C.textMatcher}function d(e,t){var o=[];return n.each(t,function(e){o.push({selectable:!0,text:e.name,data:e.value})}),o}function u(e){for(var t in e)return!1;return!0}function f(e,i){var a=[],l=k[e];n.each(l,function(e){a.push({text:e,onclick:function(){t.insertContent(t.dom.encode(e)),t.dom.remove(i),g()}})}),a.push.apply(a,[{text:"-"},{text:"Ignore",onclick:function(){h(e,i)}},{text:"Ignore all",onclick:function(){h(e,i,!0)}},{text:"Finish",onclick:v}]),P=new o({items:a,context:"contextmenu",onautohide:function(e){-1!=e.target.className.indexOf("spellchecker")&&e.preventDefault()},onhide:function(){P.remove(),P=null}}),P.renderTo(document.body);var s=r.DOM.getPos(t.getContentAreaContainer()),c=t.dom.getPos(i[0]),d=t.dom.getRoot();"BODY"==d.nodeName?(c.x-=d.ownerDocument.documentElement.scrollLeft||d.scrollLeft,c.y-=d.ownerDocument.documentElement.scrollTop||d.scrollTop):(c.x-=d.scrollLeft,c.y-=d.scrollTop),s.x+=c.x,s.y+=c.y,P.moveTo(s.x,s.y+i[0].offsetHeight)}function m(){return t.getParam("spellchecker_wordchar_pattern")||new RegExp('[^\\s!"#$%&()*+,-./:;<=>?@[\\]^_{|}`\xa7\xa9\xab\xae\xb1\xb6\xb7\xb8\xbb\xbc\xbd\xbe\xbf\xd7\xf7\xa4\u201d\u201c\u201e]+',"g")}function p(){function e(e){return t.setProgressState(!1),u(e)?(t.windowManager.alert("No misspellings found"),void(S=!1)):(k=e,c().find(m()).filter(function(t){return!!e[t.text]}).wrap(function(e){return t.dom.create("span",{"class":"mce-spellchecker-word","data-mce-bogus":1,"data-mce-word":e.text})}),void t.fire("SpellcheckStart"))}function n(e){t.windowManager.alert(e),t.setProgressState(!1),v()}function o(e,t,o){i.send({url:new a(s).toAbsolute(N.spellchecker_rpc_url),type:"post",content_type:"application/x-www-form-urlencoded",data:"text="+encodeURIComponent(t)+"&lang="+N.spellchecker_language,success:function(e){e=l.parse(e),e?e.error?n(e.error):o(e.words):n("Sever response wasn't proper JSON.")},error:function(e,t){n("Spellchecker request error: "+t.status)}})}if(S)return void v();v(),S=!0,t.setProgressState(!0);var r=N.spellchecker_callback||o;r.call(C,"spellcheck",c().text,e,n),t.focus()}function g(){t.dom.select("span.mce-spellchecker-word").length||v()}function h(e,o,r){t.selection.collapse(),r?n.each(t.dom.select("span.mce-spellchecker-word"),function(n){n.getAttribute("data-mce-word")==e&&t.dom.remove(n,!0)}):t.dom.remove(o,!0),g()}function v(){c().reset(),C.textMatcher=null,S&&(S=!1,t.fire("SpellcheckEnd"))}function b(e){var t=e.getAttribute("data-mce-index");return"number"==typeof t?""+t:t}function y(e){var o,r=[];if(o=n.toArray(t.getBody().getElementsByTagName("span")),o.length)for(var i=0;i0){var r=t.dom.createRng();r.setStartBefore(o[0]),r.setEndAfter(o[o.length-1]),t.selection.setRng(r),f(n.getAttribute("data-mce-word"),o)}}}),t.addMenuItem("spellchecker",{text:"Spellcheck",context:"tools",onclick:p,selectable:!0,onPostRender:function(){var e=this;t.on("SpellcheckStart SpellcheckEnd",function(){e.active(S)})}});var T={tooltip:"Spellcheck",onclick:p,onPostRender:function(){var e=this;t.on("SpellcheckStart SpellcheckEnd",function(){e.active(S)})}};w.length>1&&(T.type="splitbutton",T.menu=w,T.onshow=x,T.onselect=function(e){N.spellchecker_language=e.control.settings.data}),t.addButton("spellchecker",T),t.addCommand("mceSpellCheck",p),t.on("remove",function(){P&&(P.remove(),P=null)}),t.on("change",g),this.getTextMatcher=c,this.getWordCharPattern=m,this.getLanguage=function(){return N.spellchecker_language},N.spellchecker_language=N.spellchecker_language||N.language||"en"})}),a([s,c])}(this);tinymce.PluginManager.add("tabfocus",function(e){function n(e){9!==e.keyCode||e.ctrlKey||e.altKey||e.metaKey||e.preventDefault()}function t(n){function t(n){function t(e){return"BODY"===e.nodeName||"hidden"!=e.type&&"none"!=e.style.display&&"hidden"!=e.style.visibility&&t(e.parentNode)}function r(e){return e.tabIndex||"INPUT"==e.nodeName||"TEXTAREA"==e.nodeName}function c(e){return!r(e)&&"-1"!=e.getAttribute("tabindex")&&t(e)}if(u=i.select(":input:enabled,*[tabindex]:not(iframe)"),o(u,function(n,t){return n.id==e.id?(a=t,!1):void 0}),n>0){for(d=a+1;d=0;d--)if(c(u[d]))return u[d];return null}var a,u,c,d;if(!(9!==n.keyCode||n.ctrlKey||n.altKey||n.metaKey)&&(c=r(e.getParam("tab_focus",e.getParam("tabfocus_elements",":prev,:next"))),1==c.length&&(c[1]=c[0],c[0]=":prev"),u=n.shiftKey?":prev"==c[0]?t(-1):i.get(c[0]):":next"==c[1]?t(1):i.get(c[1]))){var y=tinymce.get(u.id||u.name);u.id&&y?y.focus():window.setTimeout(function(){tinymce.Env.webkit||window.focus(),u.focus()},10),n.preventDefault()}}var i=tinymce.DOM,o=tinymce.each,r=tinymce.explode;e.on("init",function(){e.inline&&tinymce.DOM.setAttrib(e.getBody(),"tabIndex",null)}),e.on("keyup",n),tinymce.Env.gecko?e.on("keypress keydown",t):e.on("keydown",t)});!function(e,t){"use strict";function n(e,t){for(var n,o=[],i=0;i "+t+" tr",a);i(n,function(n,r){r+=e,i(I.select("> td, > th",n),function(e,n){var i,a,l,s;if(A[r])for(;A[r][n];)n++;for(l=o(e,"rowspan"),s=o(e,"colspan"),a=r;r+l>a;a++)for(A[a]||(A[a]=[]),i=n;n+s>i;i++)A[a][i]={part:t,real:a==r&&i==n,elm:e,rowspan:l,colspan:s}})}),e+=n.length})}function s(e,t){return e=e.cloneNode(t),e.removeAttribute("id"),e}function c(e,t){var n;return n=A[t],n?n[e]:void 0}function d(e,t,n){e&&(n=parseInt(n,10),1===n?e.removeAttribute(t,1):e.setAttribute(t,n,1))}function u(e){return e&&(I.hasClass(e.elm,"mce-item-selected")||e==M)}function f(){var e=[];return i(a.rows,function(t){i(t.cells,function(n){return I.hasClass(n,"mce-item-selected")||M&&n==M.elm?(e.push(t),!1):void 0})}),e}function m(){var e=I.createRng();e.setStartAfter(a),e.setEndAfter(a),E.setRng(e),I.remove(a)}function p(t){var o,a={};return r.settings.table_clone_elements!==!1&&(a=e.makeMap((r.settings.table_clone_elements||"strong em b i span font h1 h2 h3 h4 h5 h6 p div").toUpperCase(),/[ ,]/)),e.walk(t,function(e){var r;return 3==e.nodeType?(i(I.getParents(e.parentNode,null,t).reverse(),function(e){a[e.nodeName]&&(e=s(e,!1),o?r&&r.appendChild(e):o=r=e,r=e)}),r&&(r.innerHTML=n.ie?" ":'
    '),!1):void 0},"childNodes"),t=s(t,!1),d(t,"rowSpan",1),d(t,"colSpan",1),o?t.appendChild(o):n.ie||(t.innerHTML='
    '),t}function g(){var e=I.createRng(),t;return i(I.select("tr",a),function(e){0===e.cells.length&&I.remove(e)}),0===I.select("tr",a).length?(e.setStartBefore(a),e.setEndBefore(a),E.setRng(e),void I.remove(a)):(i(I.select("thead,tbody,tfoot",a),function(e){0===e.rows.length&&I.remove(e)}),l(),void(B&&(t=A[Math.min(A.length-1,B.y)],t&&(E.select(t[Math.min(t.length-1,B.x)].elm,!0),E.collapse(!0)))))}function h(e,t,n,o){var i,r,a,l,s;for(i=A[t][e].elm.parentNode,a=1;n>=a;a++)if(i=I.getNext(i,"tr")){for(r=e;r>=0;r--)if(s=A[t+a][r].elm,s.parentNode==i){for(l=1;o>=l;l++)I.insertAfter(p(s),s);break}if(-1==r)for(l=1;o>=l;l++)i.insertBefore(p(i.cells[0]),i.cells[0])}}function v(){i(A,function(e,t){i(e,function(e,n){var i,r,a;if(u(e)&&(e=e.elm,i=o(e,"colspan"),r=o(e,"rowspan"),i>1||r>1)){for(d(e,"rowSpan",1),d(e,"colSpan",1),a=0;i-1>a;a++)I.insertAfter(p(e),e);h(n,t,r-1,i)}})})}function b(t,n,o){var r,a,s,f,m,p,h,b,y,w,x;if(t?(r=T(t),a=r.x,s=r.y,f=a+(n-1),m=s+(o-1)):(B=D=null,i(A,function(e,t){i(e,function(e,n){u(e)&&(B||(B={x:n,y:t}),D={x:n,y:t})})}),B&&(a=B.x,s=B.y,f=D.x,m=D.y)),b=c(a,s),y=c(f,m),b&&y&&b.part==y.part){for(v(),l(),b=c(a,s).elm,d(b,"colSpan",f-a+1),d(b,"rowSpan",m-s+1),h=s;m>=h;h++)for(p=a;f>=p;p++)A[h]&&A[h][p]&&(t=A[h][p].elm,t!=b&&(w=e.grep(t.childNodes),i(w,function(e){b.appendChild(e)}),w.length&&(w=e.grep(b.childNodes),x=0,i(w,function(e){"BR"==e.nodeName&&I.getAttrib(e,"data-mce-bogus")&&x++0&&A[n-1][l]&&(g=A[n-1][l].elm,h=o(g,"rowSpan"),h>1)){d(g,"rowSpan",h+1);continue}}else if(h=o(r,"rowspan"),h>1){d(r,"rowSpan",h+1);continue}m=p(r),d(m,"colSpan",r.colSpan),f.appendChild(m),a=r}f.hasChildNodes()&&(e?c.parentNode.insertBefore(f,c):I.insertAfter(f,c))}}function w(e){var t,n;i(A,function(n){return i(n,function(n,o){return u(n)&&(t=o,e)?!1:void 0}),e?!t:void 0}),i(A,function(i,r){var a,l,s;i[t]&&(a=i[t].elm,a!=n&&(s=o(a,"colspan"),l=o(a,"rowspan"),1==s?e?(a.parentNode.insertBefore(p(a),a),h(t,r,l-1,s)):(I.insertAfter(p(a),a),h(t,r,l-1,s)):d(a,"colSpan",a.colSpan+1),n=a))})}function x(){var t=[];i(A,function(n){i(n,function(n,r){u(n)&&-1===e.inArray(t,r)&&(i(A,function(e){var t=e[r].elm,n;n=o(t,"colSpan"),n>1?d(t,"colSpan",n-1):I.remove(t)}),t.push(r))})}),g()}function C(){function e(e){var t,n,r;t=I.getNext(e,"tr"),i(e.cells,function(e){var t=o(e,"rowSpan");t>1&&(d(e,"rowSpan",t-1),n=T(e),h(n.x,n.y,1,1))}),n=T(e.cells[0]),i(A[n.y],function(e){var t;e=e.elm,e!=r&&(t=o(e,"rowSpan"),1>=t?I.remove(e):d(e,"rowSpan",t-1),r=e)})}var t;t=f(),i(t.reverse(),function(t){e(t)}),g()}function P(){var e=f();return I.remove(e),g(),e}function S(){var e=f();return i(e,function(t,n){e[n]=s(t,!0)}),e}function R(e,t){var n=f(),o=n[t?0:n.length-1],r=o.cells.length;e&&(i(A,function(e){var t;return r=0,i(e,function(e){e.real&&(r+=e.colspan),e.elm.parentNode==o&&(t=1)}),t?!1:void 0}),t||e.reverse(),i(e,function(e){var n,i=e.cells.length,a;for(n=0;i>n;n++)a=e.cells[n],d(a,"colSpan",1),d(a,"rowSpan",1);for(n=i;r>n;n++)e.appendChild(p(e.cells[i-1]));for(n=r;i>n;n++)I.remove(e.cells[n]);t?o.parentNode.insertBefore(e,o):I.insertAfter(e,o)}),I.removeClass(I.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"))}function T(e){var t;return i(A,function(n,o){return i(n,function(n,i){return n.elm==e?(t={x:i,y:o},!1):void 0}),!t}),t}function k(e){B=T(e)}function N(){var e,t;return e=t=0,i(A,function(n,o){i(n,function(n,i){var r,a;u(n)&&(n=A[o][i],i>e&&(e=i),o>t&&(t=o),n.real&&(r=n.colspan-1,a=n.rowspan-1,r&&i+r>e&&(e=i+r),a&&o+a>t&&(t=o+a)))})}),{x:e,y:t}}function _(e){var t,n,o,i,r,a,l,s,c,d;if(D=T(e),B&&D){for(t=Math.min(B.x,D.x),n=Math.min(B.y,D.y),o=Math.max(B.x,D.x),i=Math.max(B.y,D.y),r=o,a=i,d=n;a>=d;d++)e=A[d][t],e.real||t-(e.colspan-1)=c;c++)e=A[n][c],e.real||n-(e.rowspan-1)=d;d++)for(c=t;o>=c;c++)e=A[d][c],e.real&&(l=e.colspan-1,s=e.rowspan-1,l&&c+l>r&&(r=c+l),s&&d+s>a&&(a=d+s));for(I.removeClass(I.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),d=n;a>=d;d++)for(c=t;r>=c;c++)A[d][c]&&I.addClass(A[d][c].elm,"mce-item-selected")}}var A,B,D,M,E=r.selection,I=E.dom;a=a||I.getParent(E.getStart(),"table"),l(),M=I.getParent(E.getStart(),"th,td"),M&&(B=T(M),D=N(),M=c(B.x,B.y)),e.extend(this,{deleteTable:m,split:v,merge:b,insertRow:y,insertCol:w,deleteCols:x,deleteRows:C,cutRows:P,copyRows:S,pasteRows:R,getPos:T,setStartCell:k,setEndCell:_})}}),o(u,[f,d,c],function(e,t,n){function o(e,t){return parseInt(e.getAttribute(t)||1,10)}var i=n.each;return function(n){function r(){function t(t){function r(e,o){var i=e?"previousSibling":"nextSibling",r=n.dom.getParent(o,"tr"),l=r[i];if(l)return h(n,o,l,e),t.preventDefault(),!0;var d=n.dom.getParent(r,"table"),u=r.parentNode,f=u.nodeName.toLowerCase();if("tbody"===f||f===(e?"tfoot":"thead")){var m=a(e,d,u,"tbody");if(null!==m)return s(e,m,o)}return c(e,r,i,d)}function a(e,t,o,i){var r=n.dom.select(">"+i,t),a=r.indexOf(o);if(e&&0===a||!e&&a===r.length-1)return l(e,t);if(-1===a){var s="thead"===o.tagName.toLowerCase()?0:r.length-1;return r[s]}return r[a+(e?-1:1)]}function l(e,t){var o=e?"thead":"tfoot",i=n.dom.select(">"+o,t);return 0!==i.length?i[0]:null}function s(e,o,i){var r=d(o,e);return r&&h(n,i,r,e),t.preventDefault(),!0}function c(e,o,i,a){var l=a[i];if(l)return u(l),!0;var s=n.dom.getParent(a,"td,th");if(s)return r(e,s,t);var c=d(o,!e);return u(c),t.preventDefault(),!1}function d(e,t){var o=e&&e[t?"lastChild":"firstChild"];return o&&"BR"===o.nodeName?n.dom.getParent(o,"td,th"):o}function u(e){n.selection.setCursorLocation(e,0)}function f(){return y==e.UP||y==e.DOWN}function m(e){var t=e.selection.getNode(),n=e.dom.getParent(t,"tr");return null!==n}function p(e){for(var t=0,n=e;n.previousSibling;)n=n.previousSibling,t+=o(n,"colspan");return t}function g(e,t){var n=0,r=0;return i(e.children,function(e,i){return n+=o(e,"colspan"),r=i,n>t?!1:void 0}),r}function h(e,t,o,i){var r=p(n.dom.getParent(t,"td,th")),a=g(o,r),l=o.childNodes[a],s=d(l,i);u(s||l)}function v(e){var t=n.selection.getNode(),o=n.dom.getParent(t,"td,th"),i=n.dom.getParent(e,"td,th");return o&&o!==i&&b(o,i)}function b(e,t){return n.dom.getParent(e,"TABLE")===n.dom.getParent(t,"TABLE")}var y=t.keyCode;if(f()&&m(n)){var w=n.selection.getNode();setTimeout(function(){v(w)&&r(!t.shiftKey&&y===e.UP,w,t)},0)}}n.on("KeyDown",function(e){t(e)})}function a(){function e(e,t){var n=t.ownerDocument,o=n.createRange(),i;return o.setStartBefore(t),o.setEnd(e.endContainer,e.endOffset),i=n.createElement("body"),i.appendChild(o.cloneContents()),0===i.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi,"-").replace(/<[^>]+>/g,"").length}n.on("KeyDown",function(t){var o,i,r=n.dom;(37==t.keyCode||38==t.keyCode)&&(o=n.selection.getRng(),i=r.getParent(o.startContainer,"table"),i&&n.getBody().firstChild==i&&e(o,i)&&(o=r.createRng(),o.setStartBefore(i),o.setEndBefore(i),n.selection.setRng(o),t.preventDefault()))})}function l(){n.on("KeyDown SetContent VisualAid",function(){var e;for(e=n.getBody().lastChild;e;e=e.previousSibling)if(3==e.nodeType){if(e.nodeValue.length>0)break}else if(1==e.nodeType&&!e.getAttribute("data-mce-bogus"))break;e&&"TABLE"==e.nodeName&&(n.settings.forced_root_block?n.dom.add(n.getBody(),n.settings.forced_root_block,n.settings.forced_root_block_attrs,t.ie&&t.ie<11?" ":'
    '):n.dom.add(n.getBody(),"br",{"data-mce-bogus":"1"}))}),n.on("PreProcess",function(e){var t=e.node.lastChild;t&&("BR"==t.nodeName||1==t.childNodes.length&&("BR"==t.firstChild.nodeName||"\xa0"==t.firstChild.nodeValue))&&t.previousSibling&&"TABLE"==t.previousSibling.nodeName&&n.dom.remove(t)})}function s(){function e(e,t,n,o){var i=3,r=e.dom.getParent(t.startContainer,"TABLE"),a,l,s;return r&&(a=r.parentNode),l=t.startContainer.nodeType==i&&0===t.startOffset&&0===t.endOffset&&o&&("TR"==n.nodeName||n==a),s=("TD"==n.nodeName||"TH"==n.nodeName)&&!o,l||s}function t(){var t=n.selection.getRng(),o=n.selection.getNode(),i=n.dom.getParent(t.startContainer,"TD,TH");if(e(n,t,o,i)){i||(i=o);for(var r=i.lastChild;r.lastChild;)r=r.lastChild;t.setEnd(r,r.nodeValue.length),n.selection.setRng(t)}}n.on("KeyDown",function(){t()}),n.on("MouseDown",function(e){2!=e.button&&t()})}function c(){n.on("keydown",function(t){if((t.keyCode==e.DELETE||t.keyCode==e.BACKSPACE)&&!t.isDefaultPrevented()){var o=n.dom.getParent(n.selection.getStart(),"table");if(o){for(var i=n.dom.select("td,th",o),r=i.length;r--;)if(!n.dom.hasClass(i[r],"mce-item-selected"))return;t.preventDefault(),n.execCommand("mceTableDelete")}}})}c(),t.webkit&&(r(),s()),t.gecko&&(a(),l()),t.ie>10&&(a(),l())}}),o(m,[s,p,c],function(e,t,n){return function(o){function i(){o.getBody().style.webkitUserSelect="",d&&(o.dom.removeClass(o.dom.select("td.mce-item-selected,th.mce-item-selected"),"mce-item-selected"),d=!1)}function r(t){var n,i,r=t.target;if(s&&(l||r!=s)&&("TD"==r.nodeName||"TH"==r.nodeName)){i=a.getParent(r,"table"),i==c&&(l||(l=new e(o,i),l.setStartCell(s),o.getBody().style.webkitUserSelect="none"),l.setEndCell(r),d=!0),n=o.selection.getSel();try{n.removeAllRanges?n.removeAllRanges():n.empty()}catch(u){}t.preventDefault()}}var a=o.dom,l,s,c,d=!0;return o.on("MouseDown",function(e){2!=e.button&&(i(),s=a.getParent(e.target,"td,th"),c=a.getParent(s,"table"))}),o.on("mouseover",r),o.on("remove",function(){a.unbind(o.getDoc(),"mouseover",r)}),o.on("MouseUp",function(){function e(e,o){var r=new t(e,e);do{if(3==e.nodeType&&0!==n.trim(e.nodeValue).length)return void(o?i.setStart(e,0):i.setEnd(e,e.nodeValue.length));if("BR"==e.nodeName)return void(o?i.setStartBefore(e):i.setEndBefore(e))}while(e=o?r.next():r.prev())}var i,r=o.selection,d,u,f,m,p;if(s){if(l&&(o.getBody().style.webkitUserSelect=""),d=a.select("td.mce-item-selected,th.mce-item-selected"),d.length>0){i=a.createRng(),f=d[0],p=d[d.length-1],i.setStartBefore(f),i.setEndAfter(f),e(f,1),u=new t(f,a.getParent(d[0],"table"));do if("TD"==f.nodeName||"TH"==f.nodeName){if(!a.hasClass(f,"mce-item-selected"))break;m=f}while(f=u.next());e(m),r.setRng(i)}o.nodeChanged(),s=l=c=null}}),o.on("KeyUp Drop",function(){i(),s=l=c=null}),{clear:i}}}),o(g,[s,u,m,c,p,d,h],function(e,t,n,o,i,r,a){function l(o){function i(e){return e?e.replace(/px$/,""):""}function a(e){return/^[0-9]+$/.test(e)&&(e+="px"),e}function l(e){s("left center right".split(" "),function(t){o.formatter.remove("align"+t,{},e)})}function c(e){s("top middle bottom".split(" "),function(t){o.formatter.remove("valign"+t,{},e)})}function d(){var e=o.dom,t,n,c,d;t=e.getParent(o.selection.getStart(),"table"),d={width:i(e.getStyle(t,"width")||e.getAttrib(t,"width")),height:i(e.getStyle(t,"height")||e.getAttrib(t,"height")),cellspacing:t?e.getAttrib(t,"cellspacing"):"",cellpadding:t?e.getAttrib(t,"cellpadding"):"",border:t?e.getAttrib(t,"border"):"",caption:!!e.select("caption",t)[0]},s("left center right".split(" "),function(e){o.formatter.matchNode(t,"align"+e)&&(d.align=e)}),t||(n={label:"Cols",name:"cols"},c={label:"Rows",name:"rows"}),o.windowManager.open({title:"Table properties",items:{type:"form",layout:"grid",columns:2,data:d,defaults:{type:"textbox",maxWidth:50},items:[n,c,{label:"Width",name:"width"},{label:"Height",name:"height"},{label:"Cell spacing",name:"cellspacing"},{label:"Cell padding",name:"cellpadding"},{label:"Border",name:"border"},{label:"Caption",name:"caption",type:"checkbox"},{label:"Alignment",minWidth:90,name:"align",type:"listbox",text:"None",maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]}]},onsubmit:function(){var n=this.toJSON(),i;o.undoManager.transact(function(){t||(t=g(n.cols||1,n.rows||1)),o.dom.setAttribs(t,{cellspacing:n.cellspacing,cellpadding:n.cellpadding,border:n.border}),o.dom.setStyles(t,{width:a(n.width),height:a(n.height)}),i=e.select("caption",t)[0],i&&!n.caption&&e.remove(i),!i&&n.caption&&(i=e.create("caption"),i.innerHTML=r.ie?"\xa0":'
    ',t.insertBefore(i,t.firstChild)),l(t),n.align&&o.formatter.apply("align"+n.align,{},t),o.focus(),o.addVisual()})}})}function u(e,t){o.windowManager.open({title:"Merge cells",body:[{label:"Cols",name:"cols",type:"textbox",size:10},{label:"Rows",name:"rows",type:"textbox",size:10}],onsubmit:function(){var n=this.toJSON();o.undoManager.transact(function(){e.merge(t,n.cols,n.rows)})}})}function f(){var e=o.dom,t,n,r=[];r=o.dom.select("td.mce-item-selected,th.mce-item-selected"),t=o.dom.getParent(o.selection.getStart(),"td,th"),!r.length&&t&&r.push(t),t=t||r[0],t&&(n={width:i(e.getStyle(t,"width")||e.getAttrib(t,"width")),height:i(e.getStyle(t,"height")||e.getAttrib(t,"height")),scope:e.getAttrib(t,"scope")},n.type=t.nodeName.toLowerCase(),s("left center right".split(" "),function(e){o.formatter.matchNode(t,"align"+e)&&(n.align=e)}),s("top middle bottom".split(" "),function(e){o.formatter.matchNode(t,"valign"+e)&&(n.valign=e)}),o.windowManager.open({title:"Cell properties",items:{type:"form",data:n,layout:"grid",columns:2,defaults:{type:"textbox",maxWidth:50},items:[{label:"Width",name:"width"},{label:"Height",name:"height"},{label:"Cell type",name:"type",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"Cell",value:"td"},{text:"Header cell",value:"th"}]},{label:"Scope",name:"scope",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Row",value:"row"},{text:"Column",value:"col"},{text:"Row group",value:"rowgroup"},{text:"Column group",value:"colgroup"}]},{label:"H Align",name:"align",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]},{label:"V Align",name:"valign",type:"listbox",text:"None",minWidth:90,maxWidth:null,values:[{text:"None",value:""},{text:"Top",value:"top"},{text:"Middle",value:"middle"},{text:"Bottom",value:"bottom"}]}]},onsubmit:function(){var t=this.toJSON();o.undoManager.transact(function(){s(r,function(n){o.dom.setAttrib(n,"scope",t.scope),o.dom.setStyles(n,{width:a(t.width),height:a(t.height)}),t.type&&n.nodeName.toLowerCase()!=t.type&&(n=e.rename(n,t.type)),l(n),t.align&&o.formatter.apply("align"+t.align,{},n),c(n),t.valign&&o.formatter.apply("valign"+t.valign,{},n)}),o.focus()})}}))}function m(){var e=o.dom,t,n,r,c,d=[];t=o.dom.getParent(o.selection.getStart(),"table"),n=o.dom.getParent(o.selection.getStart(),"td,th"),s(t.rows,function(t){s(t.cells,function(o){return e.hasClass(o,"mce-item-selected")||o==n?(d.push(t),!1):void 0})}),r=d[0],r&&(c={height:i(e.getStyle(r,"height")||e.getAttrib(r,"height")),scope:e.getAttrib(r,"scope")},c.type=r.parentNode.nodeName.toLowerCase(),s("left center right".split(" "),function(e){o.formatter.matchNode(r,"align"+e)&&(c.align=e)}),o.windowManager.open({title:"Row properties",items:{type:"form",data:c,columns:2,defaults:{type:"textbox"},items:[{type:"listbox",name:"type",label:"Row type",text:"None",maxWidth:null,values:[{text:"Header",value:"thead"},{text:"Body",value:"tbody"},{text:"Footer",value:"tfoot"}]},{type:"listbox",name:"align",label:"Alignment",text:"None",maxWidth:null,values:[{text:"None",value:""},{text:"Left",value:"left"},{text:"Center",value:"center"},{text:"Right",value:"right"}]},{label:"Height",name:"height"}]},onsubmit:function(){var t=this.toJSON(),n,i,r;o.undoManager.transact(function(){var c=t.type;s(d,function(s){o.dom.setAttrib(s,"scope",t.scope),o.dom.setStyles(s,{height:a(t.height)}),c!=s.parentNode.nodeName.toLowerCase()&&(n=e.getParent(s,"table"),i=s.parentNode,r=e.select(c,n)[0],r||(r=e.create(c),n.firstChild?n.insertBefore(r,n.firstChild):n.appendChild(r)),r.appendChild(s),i.hasChildNodes()||e.remove(i)),l(s),t.align&&o.formatter.apply("align"+t.align,{},s)}),o.focus()})}}))}function p(e){return function(){o.execCommand(e)}}function g(e,t){var n,i,a;for(a='',n=0;t>n;n++){for(a+="",i=0;e>i;i++)a+="";a+=""}a+="
    "+(r.ie?" ":"
    ")+"
    ",o.insertContent(a);var l=o.dom.get("__mce");return o.dom.setAttrib(l,"id",null),l}function h(e,t){function n(){e.disabled(!o.dom.getParent(o.selection.getStart(),t)),o.selection.selectorChanged(t,function(t){e.disabled(!t)})}o.initialized?n():o.on("init",n)}function v(){h(this,"table")}function b(){h(this,"td,th")}function y(){var e="";e='';for(var t=0;10>t;t++){e+="";for(var n=0;10>n;n++)e+='';e+=""}return e+="
    ",e+='

    '}function w(e,t,n){var i=n.getEl().getElementsByTagName("table")[0],r,a,l,s,c,d=n.isRtl()||"tl-tr"==n.parent().rel;for(i.nextSibling.innerHTML=e+1+" x "+(t+1),d&&(e=9-e),a=0;10>a;a++)for(r=0;10>r;r++)s=i.rows[a].childNodes[r].firstChild,c=(d?r>=e:e>=r)&&t>=a,o.dom.toggleClass(s,"mce-active",c),c&&(l=s);return l.parentNode}var x,C,P=this;o.settings.table_grid===!1?o.addMenuItem("inserttable",{text:"Insert table",icon:"table",context:"table",onclick:d}):o.addMenuItem("inserttable",{text:"Insert table",icon:"table",context:"table",ariaHideMenu:!0,onclick:function(e){e.aria&&(this.parent().hideAll(),e.stopImmediatePropagation(),d())},onshow:function(){w(0,0,this.menu.items()[0])},onhide:function(){var e=this.menu.items()[0].getEl().getElementsByTagName("a");o.dom.removeClass(e,"mce-active"),o.dom.addClass(e[0],"mce-active")},menu:[{type:"container",html:y(),onPostRender:function(){this.lastX=this.lastY=0},onmousemove:function(e){var t=e.target,n,o;"A"==t.tagName.toUpperCase()&&(n=parseInt(t.getAttribute("data-mce-x"),10),o=parseInt(t.getAttribute("data-mce-y"),10),(this.isRtl()||"tl-tr"==this.parent().rel)&&(n=9-n),(n!==this.lastX||o!==this.lastY)&&(w(n,o,e.control),this.lastX=n,this.lastY=o))},onkeydown:function(e){var t=this.lastX,n=this.lastY,o;switch(e.keyCode){case 37:t>0&&(t--,o=!0);break;case 39:o=!0,9>t&&t++;break;case 38:o=!0,n>0&&n--;break;case 40:o=!0,9>n&&n++}o&&(e.preventDefault(),e.stopPropagation(),w(t,n,e.control).focus(),this.lastX=t,this.lastY=n)},onclick:function(e){"A"==e.target.tagName.toUpperCase()&&(e.preventDefault(),e.stopPropagation(),this.parent().cancel(),g(this.lastX+1,this.lastY+1))}}]}),o.addMenuItem("tableprops",{text:"Table properties",context:"table",onPostRender:v,onclick:d}),o.addMenuItem("deletetable",{text:"Delete table",context:"table",onPostRender:v,cmd:"mceTableDelete"}),o.addMenuItem("cell",{separator:"before",text:"Cell",context:"table",menu:[{text:"Cell properties",onclick:p("mceTableCellProps"),onPostRender:b},{text:"Merge cells",onclick:p("mceTableMergeCells"),onPostRender:b},{text:"Split cell",onclick:p("mceTableSplitCells"),onPostRender:b}]}),o.addMenuItem("row",{text:"Row",context:"table",menu:[{text:"Insert row before",onclick:p("mceTableInsertRowBefore"),onPostRender:b},{text:"Insert row after",onclick:p("mceTableInsertRowAfter"),onPostRender:b},{text:"Delete row",onclick:p("mceTableDeleteRow"),onPostRender:b},{text:"Row properties",onclick:p("mceTableRowProps"),onPostRender:b},{text:"-"},{text:"Cut row",onclick:p("mceTableCutRow"),onPostRender:b},{text:"Copy row",onclick:p("mceTableCopyRow"),onPostRender:b},{text:"Paste row before",onclick:p("mceTablePasteRowBefore"),onPostRender:b},{text:"Paste row after",onclick:p("mceTablePasteRowAfter"),onPostRender:b}]}),o.addMenuItem("column",{text:"Column",context:"table",menu:[{text:"Insert column before",onclick:p("mceTableInsertColBefore"),onPostRender:b},{text:"Insert column after",onclick:p("mceTableInsertColAfter"),onPostRender:b},{text:"Delete column",onclick:p("mceTableDeleteCol"),onPostRender:b}]});var S=[];s("inserttable tableprops deletetable | cell row column".split(" "),function(e){S.push("|"==e?{text:"-"}:o.menuItems[e])}),o.addButton("table",{type:"menubutton",title:"Table",menu:S}),r.isIE||o.on("click",function(e){e=e.target,"TABLE"===e.nodeName&&(o.selection.select(e),o.nodeChanged())}),P.quirks=new t(o),o.on("Init",function(){x=o.windowManager,P.cellSelection=new n(o)}),s({mceTableSplitCells:function(e){e.split()},mceTableMergeCells:function(e){var t,n,i;i=o.dom.getParent(o.selection.getStart(),"th,td"),i&&(t=i.rowSpan,n=i.colSpan),o.dom.select("td.mce-item-selected,th.mce-item-selected").length?e.merge():u(e,i)},mceTableInsertRowBefore:function(e){e.insertRow(!0)},mceTableInsertRowAfter:function(e){e.insertRow()},mceTableInsertColBefore:function(e){e.insertCol(!0)},mceTableInsertColAfter:function(e){e.insertCol()},mceTableDeleteCol:function(e){e.deleteCols()},mceTableDeleteRow:function(e){e.deleteRows()},mceTableCutRow:function(e){C=e.cutRows()},mceTableCopyRow:function(e){C=e.copyRows()},mceTablePasteRowBefore:function(e){e.pasteRows(C,!0)},mceTablePasteRowAfter:function(e){e.pasteRows(C)},mceTableDelete:function(e){e.deleteTable()}},function(t,n){o.addCommand(n,function(){var n=new e(o);n&&(t(n),o.execCommand("mceRepaint"),P.cellSelection.clear())})}),s({mceInsertTable:function(){d()},mceTableRowProps:m,mceTableCellProps:f},function(e,t){o.addCommand(t,function(t,n){e(n)})})}var s=o.each;a.add("table",l)}),a([s,u,m,g])}(this);tinymce.PluginManager.add("template",function(e){function t(t){return function(){var a=e.settings.templates;"string"==typeof a?tinymce.util.XHR.send({url:a,success:function(e){t(tinymce.util.JSON.parse(e))}}):t(a)}}function a(t){function a(t){function a(t){if(-1==t.indexOf("")){var a="";tinymce.each(e.contentCSS,function(t){a+=''}),t=""+a+""+t+""}t=r(t,"template_preview_replace_values");var l=n.find("iframe")[0].getEl().contentWindow.document;l.open(),l.write(t),l.close()}var c=t.control.value();c.url?tinymce.util.XHR.send({url:c.url,success:function(e){l=e,a(l)}}):(l=c.content,a(l)),n.find("#description")[0].text(t.control.value().description)}var n,l,i=[];return t&&0!==t.length?(tinymce.each(t,function(e){i.push({selected:!i.length,text:e.title,value:{url:e.url,content:e.content,description:e.description}})}),n=e.windowManager.open({title:"Insert template",layout:"flex",direction:"column",align:"stretch",padding:15,spacing:10,items:[{type:"form",flex:0,padding:0,items:[{type:"container",label:"Templates",items:{type:"listbox",label:"Templates",name:"template",values:i,onselect:a}}]},{type:"label",name:"description",label:"Description",text:" "},{type:"iframe",flex:1,border:1}],onsubmit:function(){c(!1,l)},width:e.getParam("template_popup_width",600),height:e.getParam("template_popup_height",500)}),void n.find("listbox")[0].fire("select")):void e.windowManager.alert("No templates defined")}function n(t,a){function n(e,t){if(e=""+e,e.length0&&(o=p.create("div",null),o.appendChild(s[0].cloneNode(!0))),i(p.select("*",o),function(t){c(t,e.getParam("template_cdate_classes","cdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_cdate_format",e.getLang("template.cdate_format")))),c(t,e.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_mdate_format",e.getLang("template.mdate_format")))),c(t,e.getParam("template_selected_content_classes","selcontent").replace(/\s+/g,"|"))&&(t.innerHTML=m)}),l(o),e.execCommand("mceInsertContent",!1,o.innerHTML),e.addVisual()}var i=tinymce.each;e.addCommand("mceInsertTemplate",c),e.addButton("template",{title:"Insert template",onclick:t(a)}),e.addMenuItem("template",{text:"Insert template",onclick:t(a),context:"insert"}),e.on("PreProcess",function(t){var a=e.dom;i(a.select("div",t.node),function(t){a.hasClass(t,"mceTmpl")&&(i(a.select("*",t),function(t){a.hasClass(t,e.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_mdate_format",e.getLang("template.mdate_format"))))}),l(t))})})});tinymce.PluginManager.add("textcolor",function(e){function t(){var t,o,l=[];for(o=e.settings.textcolor_map||["000000","Black","993300","Burnt orange","333300","Dark olive","003300","Dark green","003366","Dark azure","000080","Navy Blue","333399","Indigo","333333","Very dark gray","800000","Maroon","FF6600","Orange","808000","Olive","008000","Green","008080","Teal","0000FF","Blue","666699","Grayish blue","808080","Gray","FF0000","Red","FF9900","Amber","99CC00","Yellow green","339966","Sea green","33CCCC","Turquoise","3366FF","Royal blue","800080","Purple","999999","Medium gray","FF00FF","Magenta","FFCC00","Gold","FFFF00","Yellow","00FF00","Lime","00FFFF","Aqua","00CCFF","Sky blue","993366","Red violet","C0C0C0","Silver","FF99CC","Pink","FFCC99","Peach","FFFF99","Light yellow","CCFFCC","Pale green","CCFFFF","Pale cyan","99CCFF","Light sky blue","CC99FF","Plum","FFFFFF","White"],t=0;t',a=o.length-1,c=e.settings.textcolor_rows||5,i=e.settings.textcolor_cols||8,F=0;c>F;F++){for(r+="",n=0;i>n;n++)d=F*i+n,d>a?r+="":(l=o[d],r+='
    ');r+=""}return r+=""}function l(t){var o,l=this.parent();(o=t.target.getAttribute("data-mce-color"))&&(this.lastId&&document.getElementById(this.lastId).setAttribute("aria-selected",!1),t.target.setAttribute("aria-selected",!0),this.lastId=t.target.id,l.hidePanel(),o="#"+o,l.color(o),e.execCommand(l.settings.selectcmd,!1,o))}function r(){var t=this;t._color&&e.execCommand(t.settings.selectcmd,!1,t._color)}e.addButton("forecolor",{type:"colorbutton",tooltip:"Text color",selectcmd:"ForeColor",panel:{role:"application",ariaRemember:!0,html:o,onclick:l},onclick:r}),e.addButton("backcolor",{type:"colorbutton",tooltip:"Background color",selectcmd:"HiliteColor",panel:{role:"application",ariaRemember:!0,html:o,onclick:l},onclick:r})});tinymce.PluginManager.add("visualblocks",function(e,s){function o(){var s=this;s.active(a),e.on("VisualBlocks",function(){s.active(e.dom.hasClass(e.getBody(),"mce-visualblocks"))})}var l,t,a;window.NodeList&&(e.addCommand("mceVisualBlocks",function(){var o,c=e.dom;l||(l=c.uniqueId(),o=c.create("link",{id:l,rel:"stylesheet",href:s+"/css/visualblocks.css"}),e.getDoc().getElementsByTagName("head")[0].appendChild(o)),e.on("PreviewFormats AfterPreviewFormats",function(s){a&&c.toggleClass(e.getBody(),"mce-visualblocks","afterpreviewformats"==s.type)}),c.toggleClass(e.getBody(),"mce-visualblocks"),a=e.dom.hasClass(e.getBody(),"mce-visualblocks"),t&&t.active(c.hasClass(e.getBody(),"mce-visualblocks")),e.fire("VisualBlocks")}),e.addButton("visualblocks",{title:"Show blocks",cmd:"mceVisualBlocks",onPostRender:o}),e.addMenuItem("visualblocks",{text:"Show blocks",cmd:"mceVisualBlocks",onPostRender:o,selectable:!0,context:"view",prependToContext:!0}),e.on("init",function(){e.settings.visualblocks_default_state&&e.execCommand("mceVisualBlocks",!1,null,{skip_focus:!0})}),e.on("remove",function(){e.dom.removeClass(e.getBody(),"mce-visualblocks")}))});tinymce.PluginManager.add("visualchars",function(e){function a(a){var t,s,i,r,c,d,l=e.getBody(),m=e.selection;if(n=!n,o.state=n,e.fire("VisualChars",{state:n}),a&&(d=m.getBookmark()),n)for(s=[],tinymce.walk(l,function(e){3==e.nodeType&&e.nodeValue&&-1!=e.nodeValue.indexOf(" ")&&s.push(e)},"childNodes"),i=0;i$1
    '),c=e.dom.create("div",null,r);t=c.lastChild;)e.dom.insertAfter(t,s[i]);e.dom.remove(s[i])}else for(s=e.dom.select("span.mce-nbsp",l),i=s.length-1;i>=0;i--)e.dom.remove(s[i],1);m.moveToBookmark(d)}function t(){var a=this;e.on("VisualChars",function(e){a.active(e.state)})}var n,o=this;e.addCommand("mceVisualChars",a),e.addButton("visualchars",{title:"Show invisible characters",cmd:"mceVisualChars",onPostRender:t}),e.addMenuItem("visualchars",{text:"Show invisible characters",cmd:"mceVisualChars",onPostRender:t,selectable:!0,context:"view",prependToContext:!0}),e.on("beforegetcontent",function(e){n&&"raw"!=e.format&&!e.draft&&(n=!0,a(!1))})});tinymce.PluginManager.add("wordcount",function(e){function t(){e.theme.panel.find("#wordcount").text(["Words: {0}",a.getCount()])}var n,o,a=this;n=e.getParam("wordcount_countregex",/[\w\u2019\x27\-\u00C0-\u1FFF]+/g),o=e.getParam("wordcount_cleanregex",/[0-9.(),;:!?%#$?\x27\x22_+=\\\/\-]*/g),e.on("init",function(){var n=e.theme.panel&&e.theme.panel.find("#statusbar")[0];n&&window.setTimeout(function(){n.insert({type:"label",name:"wordcount",text:["Words: {0}",a.getCount()],classes:"wordcount",disabled:e.settings.readonly},0),e.on("setcontent beforeaddundo",t),e.on("keyup",function(e){32==e.keyCode&&t()})},0)}),a.getCount=function(){var t=e.getContent({format:"raw"}),a=0;if(t){t=t.replace(/\.\.\./g," "),t=t.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," "),t=t.replace(/(\w+)(&#?[a-z0-9]+;)+(\w+)/i,"$1$3").replace(/&.+?;/g," "),t=t.replace(o,"");var r=t.match(n);r&&(a=r.length)}return a}});tinymce.ThemeManager.add("modern",function(e){function t(){function t(t){var n,o=[];if(t)return d(t.split(/[ ,]/),function(t){function i(){var i=e.selection;"bullist"==r&&i.selectorChanged("ul > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"UL"==n)}),"numlist"==r&&i.selectorChanged("ol > li",function(e,i){for(var n,o=i.parents.length;o--&&(n=i.parents[o].nodeName,"OL"!=n&&"UL"!=n););t.active(e&&"OL"==n)}),t.settings.stateSelector&&i.selectorChanged(t.settings.stateSelector,function(e){t.active(e)},!0),t.settings.disabledStateSelector&&i.selectorChanged(t.settings.disabledStateSelector,function(e){t.disabled(e)})}var r;"|"==t?n=null:c.has(t)?(t={type:t},u.toolbar_items_size&&(t.size=u.toolbar_items_size),o.push(t),n=null):(n||(n={type:"buttongroup",items:[]},o.push(n)),e.buttons[t]&&(r=t,t=e.buttons[r],"function"==typeof t&&(t=t()),t.type=t.type||"button",u.toolbar_items_size&&(t.size=u.toolbar_items_size),t=c.create(t),n.items.push(t),e.initialized?i():e.on("init",i)))}),i.push({type:"toolbar",layout:"flow",items:o}),!0}var i=[];if(tinymce.isArray(u.toolbar)){if(0===u.toolbar.length)return;tinymce.each(u.toolbar,function(e,t){u["toolbar"+(t+1)]=e}),delete u.toolbar}for(var n=1;10>n&&t(u["toolbar"+n]);n++);return i.length||u.toolbar===!1||t(u.toolbar||f),i.length?{type:"panel",layout:"stack",classes:"toolbar-grp",ariaRoot:!0,ariaRemember:!0,items:i}:void 0}function i(){function t(t){var i;return"|"==t?{text:"|"}:i=e.menuItems[t]}function i(i){var n,o,r,a,s;if(s=tinymce.makeMap((u.removed_menuitems||"").split(/[ ,]/)),u.menu?(o=u.menu[i],a=!0):o=h[i],o){n={text:o.title},r=[],d((o.items||"").split(/[ ,]/),function(e){var i=t(e);i&&!s[e]&&r.push(t(e))}),a||d(e.menuItems,function(e){e.context==i&&("before"==e.separator&&r.push({text:"|"}),e.prependToContext?r.unshift(e):r.push(e),"after"==e.separator&&r.push({text:"|"}))});for(var l=0;l +
    Pressing "a" while this checkbox is + focused will remove it from the DOM.
    +
    +
    + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/keyboard_shortcut.html b/www/node_modules/selenium-webdriver/lib/test/data/keyboard_shortcut.html new file mode 100644 index 0000000..741d7f4 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/keyboard_shortcut.html @@ -0,0 +1,36 @@ + + +
    CTRL + 1: red
    +
    SHIFT + 1: green
    +
    CTRL + SHIFT + 1: yellow
    +
    ALT + 1: lightblue
    +
    CTRL + ALT + 1: lightgreen
    +
    SHIFT + ALT + 1: silver
    +
    CTRL + SHIFT + ALT + 1: magenta
    + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/linked_image.html b/www/node_modules/selenium-webdriver/lib/test/data/linked_image.html new file mode 100644 index 0000000..7c8df00 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/linked_image.html @@ -0,0 +1,16 @@ + + + + +Linking with an image + + +banner
    +Click here for next page
    +
    +link to other link
    +Just another link.
    +

    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected.html b/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected.html new file mode 100644 index 0000000..42b0442 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected.html @@ -0,0 +1,13 @@ + + + Boolean Attribute Selected + + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected_html4.html b/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected_html4.html new file mode 100644 index 0000000..60cd033 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/locators_tests/boolean_attribute_selected_html4.html @@ -0,0 +1,13 @@ + + + Boolean Attribute Selected + + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/longContentPage.html b/www/node_modules/selenium-webdriver/lib/test/data/longContentPage.html new file mode 100644 index 0000000..99a45e7 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/longContentPage.html @@ -0,0 +1,55 @@ + + + TouchLongContent + + + +

    Touch API

    +

    Page with long content

    +
                       



    +

    Long text:                                                                                                                          This is a very long text to make the screen horizontally movable, to test the flick gesture at a long horizontal distance Normal link                                                                                                                                           at normal and fast speeds to see results of it Normal link end

    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    + Middle of the screen Normal link +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    +










    + Bottom of the screen Normal link


    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/macbeth.html b/www/node_modules/selenium-webdriver/lib/test/data/macbeth.html new file mode 100644 index 0000000..9fa39d5 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/macbeth.html @@ -0,0 +1,5255 @@ + + + + Macbeth: Entire Play + + + + + + + +Quick link to last speech + +

    ACT I

    +

    SCENE I. A desert place.

    +

    +Thunder and lightning. Enter three Witches +
    + +First Witch +
    +When shall we three meet again
    +In thunder, lightning, or in rain?
    +
    + +Second Witch +
    +When the hurlyburly's done,
    +When the battle's lost and won.
    +
    + +Third Witch +
    +That will be ere the set of sun.
    +
    + +First Witch +
    +Where the place?
    +
    + +Second Witch +
    + Upon the heath.
    +
    + +Third Witch +
    +There to meet with Macbeth.
    +
    + +First Witch +
    +I come, Graymalkin!
    +
    + +Second Witch +
    +Paddock calls.
    +
    + +Third Witch +
    +Anon.
    +
    + +ALL +
    +Fair is foul, and foul is fair:
    +Hover through the fog and filthy air.
    +

    Exeunt

    +
    +

    SCENE II. A camp near Forres.

    +

    +Alarum within. Enter DUNCAN, MALCOLM, DONALBAIN, LENNOX, with Attendants, meeting a bleeding Sergeant +
    + +DUNCAN +
    +What bloody man is that? He can report,
    +As seemeth by his plight, of the revolt
    +The newest state.
    +
    + +MALCOLM +
    + This is the sergeant
    +Who like a good and hardy soldier fought
    +'Gainst my captivity. Hail, brave friend!
    +Say to the king the knowledge of the broil
    +As thou didst leave it.
    +
    + +Sergeant +
    +Doubtful it stood;
    +As two spent swimmers, that do cling together
    +And choke their art. The merciless Macdonwald--
    +Worthy to be a rebel, for to that
    +The multiplying villanies of nature
    +Do swarm upon him--from the western isles
    +Of kerns and gallowglasses is supplied;
    +And fortune, on his damned quarrel smiling,
    +Show'd like a rebel's whore: but all's too weak:
    +For brave Macbeth--well he deserves that name--
    +Disdaining fortune, with his brandish'd steel,
    +Which smoked with bloody execution,
    +Like valour's minion carved out his passage
    +Till he faced the slave;
    +Which ne'er shook hands, nor bade farewell to him,
    +Till he unseam'd him from the nave to the chaps,
    +And fix'd his head upon our battlements.
    +
    + +DUNCAN +
    +O valiant cousin! worthy gentleman!
    +
    + +Sergeant +
    +As whence the sun 'gins his reflection
    +Shipwrecking storms and direful thunders break,
    +So from that spring whence comfort seem'd to come
    +Discomfort swells. Mark, king of Scotland, mark:
    +No sooner justice had with valour arm'd
    +Compell'd these skipping kerns to trust their heels,
    +But the Norweyan lord surveying vantage,
    +With furbish'd arms and new supplies of men
    +Began a fresh assault.
    +
    + +DUNCAN +
    +Dismay'd not this
    +Our captains, Macbeth and Banquo?
    +
    + +Sergeant +
    +Yes;
    +As sparrows eagles, or the hare the lion.
    +If I say sooth, I must report they were
    +As cannons overcharged with double cracks, so they
    +Doubly redoubled strokes upon the foe:
    +Except they meant to bathe in reeking wounds,
    +Or memorise another Golgotha,
    +I cannot tell.
    +But I am faint, my gashes cry for help.
    +
    + +DUNCAN +
    +So well thy words become thee as thy wounds;
    +They smack of honour both. Go get him surgeons.
    +

    Exit Sergeant, attended

    +Who comes here?
    +

    Enter ROSS

    +
    + +MALCOLM +
    + The worthy thane of Ross.
    +
    + +LENNOX +
    +What a haste looks through his eyes! So should he look
    +That seems to speak things strange.
    +
    + +ROSS +
    +God save the king!
    +
    + +DUNCAN +
    +Whence camest thou, worthy thane?
    +
    + +ROSS +
    +From Fife, great king;
    +Where the Norweyan banners flout the sky
    +And fan our people cold. Norway himself,
    +With terrible numbers,
    +Assisted by that most disloyal traitor
    +The thane of Cawdor, began a dismal conflict;
    +Till that Bellona's bridegroom, lapp'd in proof,
    +Confronted him with self-comparisons,
    +Point against point rebellious, arm 'gainst arm.
    +Curbing his lavish spirit: and, to conclude,
    +The victory fell on us.
    +
    + +DUNCAN +
    +Great happiness!
    +
    + +ROSS +
    +That now
    +Sweno, the Norways' king, craves composition:
    +Nor would we deign him burial of his men
    +Till he disbursed at Saint Colme's inch
    +Ten thousand dollars to our general use.
    +
    + +DUNCAN +
    +No more that thane of Cawdor shall deceive
    +Our bosom interest: go pronounce his present death,
    +And with his former title greet Macbeth.
    +
    + +ROSS +
    +I'll see it done.
    +
    + +DUNCAN +
    +What he hath lost noble Macbeth hath won.
    +

    Exeunt

    +
    +

    SCENE III. A heath near Forres.

    +

    +Thunder. Enter the three Witches +
    + +First Witch +
    +Where hast thou been, sister?
    +
    + +Second Witch +
    +Killing swine.
    +
    + +Third Witch +
    +Sister, where thou?
    +
    + +First Witch +
    +A sailor's wife had chestnuts in her lap,
    +And munch'd, and munch'd, and munch'd:--
    +'Give me,' quoth I:
    +'Aroint thee, witch!' the rump-fed ronyon cries.
    +Her husband's to Aleppo gone, master o' the Tiger:
    +But in a sieve I'll thither sail,
    +And, like a rat without a tail,
    +I'll do, I'll do, and I'll do.
    +
    + +Second Witch +
    +I'll give thee a wind.
    +
    + +First Witch +
    +Thou'rt kind.
    +
    + +Third Witch +
    +And I another.
    +
    + +First Witch +
    +I myself have all the other,
    +And the very ports they blow,
    +All the quarters that they know
    +I' the shipman's card.
    +I will drain him dry as hay:
    +Sleep shall neither night nor day
    +Hang upon his pent-house lid;
    +He shall live a man forbid:
    +Weary se'nnights nine times nine
    +Shall he dwindle, peak and pine:
    +Though his bark cannot be lost,
    +Yet it shall be tempest-tost.
    +Look what I have.
    +
    + +Second Witch +
    +Show me, show me.
    +
    + +First Witch +
    +Here I have a pilot's thumb,
    +Wreck'd as homeward he did come.
    +

    Drum within

    +
    + +Third Witch +
    +A drum, a drum!
    +Macbeth doth come.
    +
    + +ALL +
    +The weird sisters, hand in hand,
    +Posters of the sea and land,
    +Thus do go about, about:
    +Thrice to thine and thrice to mine
    +And thrice again, to make up nine.
    +Peace! the charm's wound up.
    +

    Enter MACBETH and BANQUO

    +
    + +MACBETH +
    +So foul and fair a day I have not seen.
    +
    + +BANQUO +
    +How far is't call'd to Forres? What are these
    +So wither'd and so wild in their attire,
    +That look not like the inhabitants o' the earth,
    +And yet are on't? Live you? or are you aught
    +That man may question? You seem to understand me,
    +By each at once her chappy finger laying
    +Upon her skinny lips: you should be women,
    +And yet your beards forbid me to interpret
    +That you are so.
    +
    + +MACBETH +
    + Speak, if you can: what are you?
    +
    + +First Witch +
    +All hail, Macbeth! hail to thee, thane of Glamis!
    +
    + +Second Witch +
    +All hail, Macbeth, hail to thee, thane of Cawdor!
    +
    + +Third Witch +
    +All hail, Macbeth, thou shalt be king hereafter!
    +
    + +BANQUO +
    +Good sir, why do you start; and seem to fear
    +Things that do sound so fair? I' the name of truth,
    +Are ye fantastical, or that indeed
    +Which outwardly ye show? My noble partner
    +You greet with present grace and great prediction
    +Of noble having and of royal hope,
    +That he seems rapt withal: to me you speak not.
    +If you can look into the seeds of time,
    +And say which grain will grow and which will not,
    +Speak then to me, who neither beg nor fear
    +Your favours nor your hate.
    +
    + +First Witch +
    +Hail!
    +
    + +Second Witch +
    +Hail!
    +
    + +Third Witch +
    +Hail!
    +
    + +First Witch +
    +Lesser than Macbeth, and greater.
    +
    + +Second Witch +
    +Not so happy, yet much happier.
    +
    + +Third Witch +
    +Thou shalt get kings, though thou be none:
    +So all hail, Macbeth and Banquo!
    +
    + +First Witch +
    +Banquo and Macbeth, all hail!
    +
    + +MACBETH +
    +Stay, you imperfect speakers, tell me more:
    +By Sinel's death I know I am thane of Glamis;
    +But how of Cawdor? the thane of Cawdor lives,
    +A prosperous gentleman; and to be king
    +Stands not within the prospect of belief,
    +No more than to be Cawdor. Say from whence
    +You owe this strange intelligence? or why
    +Upon this blasted heath you stop our way
    +With such prophetic greeting? Speak, I charge you.
    +

    Witches vanish

    +
    + +BANQUO +
    +The earth hath bubbles, as the water has,
    +And these are of them. Whither are they vanish'd?
    +
    + +MACBETH +
    +Into the air; and what seem'd corporal melted
    +As breath into the wind. Would they had stay'd!
    +
    + +BANQUO +
    +Were such things here as we do speak about?
    +Or have we eaten on the insane root
    +That takes the reason prisoner?
    +
    + +MACBETH +
    +Your children shall be kings.
    +
    + +BANQUO +
    +You shall be king.
    +
    + +MACBETH +
    +And thane of Cawdor too: went it not so?
    +
    + +BANQUO +
    +To the selfsame tune and words. Who's here?
    +

    Enter ROSS and ANGUS

    +
    + +ROSS +
    +The king hath happily received, Macbeth,
    +The news of thy success; and when he reads
    +Thy personal venture in the rebels' fight,
    +His wonders and his praises do contend
    +Which should be thine or his: silenced with that,
    +In viewing o'er the rest o' the selfsame day,
    +He finds thee in the stout Norweyan ranks,
    +Nothing afeard of what thyself didst make,
    +Strange images of death. As thick as hail
    +Came post with post; and every one did bear
    +Thy praises in his kingdom's great defence,
    +And pour'd them down before him.
    +
    + +ANGUS +
    +We are sent
    +To give thee from our royal master thanks;
    +Only to herald thee into his sight,
    +Not pay thee.
    +
    + +ROSS +
    +And, for an earnest of a greater honour,
    +He bade me, from him, call thee thane of Cawdor:
    +In which addition, hail, most worthy thane!
    +For it is thine.
    +
    + +BANQUO +
    + What, can the devil speak true?
    +
    + +MACBETH +
    +The thane of Cawdor lives: why do you dress me
    +In borrow'd robes?
    +
    + +ANGUS +
    + Who was the thane lives yet;
    +But under heavy judgment bears that life
    +Which he deserves to lose. Whether he was combined
    +With those of Norway, or did line the rebel
    +With hidden help and vantage, or that with both
    +He labour'd in his country's wreck, I know not;
    +But treasons capital, confess'd and proved,
    +Have overthrown him.
    +
    + +MACBETH +
    +[Aside] Glamis, and thane of Cawdor!
    +The greatest is behind.
    +

    To ROSS and ANGUS

    +Thanks for your pains.
    +

    To BANQUO

    +Do you not hope your children shall be kings,
    +When those that gave the thane of Cawdor to me
    +Promised no less to them?
    +
    + +BANQUO +
    +That trusted home
    +Might yet enkindle you unto the crown,
    +Besides the thane of Cawdor. But 'tis strange:
    +And oftentimes, to win us to our harm,
    +The instruments of darkness tell us truths,
    +Win us with honest trifles, to betray's
    +In deepest consequence.
    +Cousins, a word, I pray you.
    +
    + +MACBETH +
    +[Aside] Two truths are told,
    +As happy prologues to the swelling act
    +Of the imperial theme.--I thank you, gentlemen.
    +

    Aside

    +Cannot be ill, cannot be good: if ill,
    +Why hath it given me earnest of success,
    +Commencing in a truth? I am thane of Cawdor:
    +If good, why do I yield to that suggestion
    +Whose horrid image doth unfix my hair
    +And make my seated heart knock at my ribs,
    +Against the use of nature? Present fears
    +Are less than horrible imaginings:
    +My thought, whose murder yet is but fantastical,
    +Shakes so my single state of man that function
    +Is smother'd in surmise, and nothing is
    +But what is not.
    +
    + +BANQUO +
    + Look, how our partner's rapt.
    +
    + +MACBETH +
    +[Aside] If chance will have me king, why, chance may crown me,
    +Without my stir.
    +
    + +BANQUO +
    + New horrors come upon him,
    +Like our strange garments, cleave not to their mould
    +But with the aid of use.
    +
    + +MACBETH +
    +[Aside] Come what come may,
    +Time and the hour runs through the roughest day.
    +
    + +BANQUO +
    +Worthy Macbeth, we stay upon your leisure.
    +
    + +MACBETH +
    +Give me your favour: my dull brain was wrought
    +With things forgotten. Kind gentlemen, your pains
    +Are register'd where every day I turn
    +The leaf to read them. Let us toward the king.
    +Think upon what hath chanced, and, at more time,
    +The interim having weigh'd it, let us speak
    +Our free hearts each to other.
    +
    + +BANQUO +
    +Very gladly.
    +
    + +MACBETH +
    +Till then, enough. Come, friends.
    +

    Exeunt

    +
    +

    SCENE IV. Forres. The palace.

    +

    +Flourish. Enter DUNCAN, MALCOLM, DONALBAIN, LENNOX, and Attendants +
    + +DUNCAN +
    +Is execution done on Cawdor? Are not
    +Those in commission yet return'd?
    +
    + +MALCOLM +
    +My liege,
    +They are not yet come back. But I have spoke
    +With one that saw him die: who did report
    +That very frankly he confess'd his treasons,
    +Implored your highness' pardon and set forth
    +A deep repentance: nothing in his life
    +Became him like the leaving it; he died
    +As one that had been studied in his death
    +To throw away the dearest thing he owed,
    +As 'twere a careless trifle.
    +
    + +DUNCAN +
    +There's no art
    +To find the mind's construction in the face:
    +He was a gentleman on whom I built
    +An absolute trust.
    +

    Enter MACBETH, BANQUO, ROSS, and ANGUS

    +O worthiest cousin!
    +The sin of my ingratitude even now
    +Was heavy on me: thou art so far before
    +That swiftest wing of recompense is slow
    +To overtake thee. Would thou hadst less deserved,
    +That the proportion both of thanks and payment
    +Might have been mine! only I have left to say,
    +More is thy due than more than all can pay.
    +
    + +MACBETH +
    +The service and the loyalty I owe,
    +In doing it, pays itself. Your highness' part
    +Is to receive our duties; and our duties
    +Are to your throne and state children and servants,
    +Which do but what they should, by doing every thing
    +Safe toward your love and honour.
    +
    + +DUNCAN +
    +Welcome hither:
    +I have begun to plant thee, and will labour
    +To make thee full of growing. Noble Banquo,
    +That hast no less deserved, nor must be known
    +No less to have done so, let me enfold thee
    +And hold thee to my heart.
    +
    + +BANQUO +
    +There if I grow,
    +The harvest is your own.
    +
    + +DUNCAN +
    +My plenteous joys,
    +Wanton in fulness, seek to hide themselves
    +In drops of sorrow. Sons, kinsmen, thanes,
    +And you whose places are the nearest, know
    +We will establish our estate upon
    +Our eldest, Malcolm, whom we name hereafter
    +The Prince of Cumberland; which honour must
    +Not unaccompanied invest him only,
    +But signs of nobleness, like stars, shall shine
    +On all deservers. From hence to Inverness,
    +And bind us further to you.
    +
    + +MACBETH +
    +The rest is labour, which is not used for you:
    +I'll be myself the harbinger and make joyful
    +The hearing of my wife with your approach;
    +So humbly take my leave.
    +
    + +DUNCAN +
    +My worthy Cawdor!
    +
    + +MACBETH +
    +[Aside] The Prince of Cumberland! that is a step
    +On which I must fall down, or else o'erleap,
    +For in my way it lies. Stars, hide your fires;
    +Let not light see my black and deep desires:
    +The eye wink at the hand; yet let that be,
    +Which the eye fears, when it is done, to see.
    +

    Exit

    +
    + +DUNCAN +
    +True, worthy Banquo; he is full so valiant,
    +And in his commendations I am fed;
    +It is a banquet to me. Let's after him,
    +Whose care is gone before to bid us welcome:
    +It is a peerless kinsman.
    +

    Flourish. Exeunt

    +
    +

    SCENE V. Inverness. Macbeth's castle.

    +

    +Enter LADY MACBETH, reading a letter +
    + +LADY MACBETH +
    +'They met me in the day of success: and I have
    +learned by the perfectest report, they have more in
    +them than mortal knowledge. When I burned in desire
    +to question them further, they made themselves air,
    +into which they vanished. Whiles I stood rapt in
    +the wonder of it, came missives from the king, who
    +all-hailed me 'Thane of Cawdor;' by which title,
    +before, these weird sisters saluted me, and referred
    +me to the coming on of time, with 'Hail, king that
    +shalt be!' This have I thought good to deliver
    +thee, my dearest partner of greatness, that thou
    +mightst not lose the dues of rejoicing, by being
    +ignorant of what greatness is promised thee. Lay it
    +to thy heart, and farewell.'
    +Glamis thou art, and Cawdor; and shalt be
    +What thou art promised: yet do I fear thy nature;
    +It is too full o' the milk of human kindness
    +To catch the nearest way: thou wouldst be great;
    +Art not without ambition, but without
    +The illness should attend it: what thou wouldst highly,
    +That wouldst thou holily; wouldst not play false,
    +And yet wouldst wrongly win: thou'ldst have, great Glamis,
    +That which cries 'Thus thou must do, if thou have it;
    +And that which rather thou dost fear to do
    +Than wishest should be undone.' Hie thee hither,
    +That I may pour my spirits in thine ear;
    +And chastise with the valour of my tongue
    +All that impedes thee from the golden round,
    +Which fate and metaphysical aid doth seem
    +To have thee crown'd withal.
    +

    Enter a Messenger

    +What is your tidings?
    +
    + +Messenger +
    +The king comes here to-night.
    +
    + +LADY MACBETH +
    +Thou'rt mad to say it:
    +Is not thy master with him? who, were't so,
    +Would have inform'd for preparation.
    +
    + +Messenger +
    +So please you, it is true: our thane is coming:
    +One of my fellows had the speed of him,
    +Who, almost dead for breath, had scarcely more
    +Than would make up his message.
    +
    + +LADY MACBETH +
    +Give him tending;
    +He brings great news.
    +

    Exit Messenger

    +The raven himself is hoarse
    +That croaks the fatal entrance of Duncan
    +Under my battlements. Come, you spirits
    +That tend on mortal thoughts, unsex me here,
    +And fill me from the crown to the toe top-full
    +Of direst cruelty! make thick my blood;
    +Stop up the access and passage to remorse,
    +That no compunctious visitings of nature
    +Shake my fell purpose, nor keep peace between
    +The effect and it! Come to my woman's breasts,
    +And take my milk for gall, you murdering ministers,
    +Wherever in your sightless substances
    +You wait on nature's mischief! Come, thick night,
    +And pall thee in the dunnest smoke of hell,
    +That my keen knife see not the wound it makes,
    +Nor heaven peep through the blanket of the dark,
    +To cry 'Hold, hold!'
    +

    Enter MACBETH

    +Great Glamis! worthy Cawdor!
    +Greater than both, by the all-hail hereafter!
    +Thy letters have transported me beyond
    +This ignorant present, and I feel now
    +The future in the instant.
    +
    + +MACBETH +
    +My dearest love,
    +Duncan comes here to-night.
    +
    + +LADY MACBETH +
    +And when goes hence?
    +
    + +MACBETH +
    +To-morrow, as he purposes.
    +
    + +LADY MACBETH +
    +O, never
    +Shall sun that morrow see!
    +Your face, my thane, is as a book where men
    +May read strange matters. To beguile the time,
    +Look like the time; bear welcome in your eye,
    +Your hand, your tongue: look like the innocent flower,
    +But be the serpent under't. He that's coming
    +Must be provided for: and you shall put
    +This night's great business into my dispatch;
    +Which shall to all our nights and days to come
    +Give solely sovereign sway and masterdom.
    +
    + +MACBETH +
    +We will speak further.
    +
    + +LADY MACBETH +
    +Only look up clear;
    +To alter favour ever is to fear:
    +Leave all the rest to me.
    +

    Exeunt

    +
    +

    SCENE VI. Before Macbeth's castle.

    +

    +Hautboys and torches. Enter DUNCAN, MALCOLM, DONALBAIN, BANQUO, LENNOX, MACDUFF, ROSS, ANGUS, and Attendants +
    + +DUNCAN +
    +This castle hath a pleasant seat; the air
    +Nimbly and sweetly recommends itself
    +Unto our gentle senses.
    +
    + +BANQUO +
    +This guest of summer,
    +The temple-haunting martlet, does approve,
    +By his loved mansionry, that the heaven's breath
    +Smells wooingly here: no jutty, frieze,
    +Buttress, nor coign of vantage, but this bird
    +Hath made his pendent bed and procreant cradle:
    +Where they most breed and haunt, I have observed,
    +The air is delicate.
    +

    Enter LADY MACBETH

    +
    + +DUNCAN +
    +See, see, our honour'd hostess!
    +The love that follows us sometime is our trouble,
    +Which still we thank as love. Herein I teach you
    +How you shall bid God 'ild us for your pains,
    +And thank us for your trouble.
    +
    + +LADY MACBETH +
    +All our service
    +In every point twice done and then done double
    +Were poor and single business to contend
    +Against those honours deep and broad wherewith
    +Your majesty loads our house: for those of old,
    +And the late dignities heap'd up to them,
    +We rest your hermits.
    +
    + +DUNCAN +
    +Where's the thane of Cawdor?
    +We coursed him at the heels, and had a purpose
    +To be his purveyor: but he rides well;
    +And his great love, sharp as his spur, hath holp him
    +To his home before us. Fair and noble hostess,
    +We are your guest to-night.
    +
    + +LADY MACBETH +
    +Your servants ever
    +Have theirs, themselves and what is theirs, in compt,
    +To make their audit at your highness' pleasure,
    +Still to return your own.
    +
    + +DUNCAN +
    +Give me your hand;
    +Conduct me to mine host: we love him highly,
    +And shall continue our graces towards him.
    +By your leave, hostess.
    +

    Exeunt

    +
    +

    SCENE VII. Macbeth's castle.

    +

    +Hautboys and torches. Enter a Sewer, and divers Servants with dishes and service, and pass over the stage. Then enter MACBETH +
    + +MACBETH +
    +If it were done when 'tis done, then 'twere well
    +It were done quickly: if the assassination
    +Could trammel up the consequence, and catch
    +With his surcease success; that but this blow
    +Might be the be-all and the end-all here,
    +But here, upon this bank and shoal of time,
    +We'ld jump the life to come. But in these cases
    +We still have judgment here; that we but teach
    +Bloody instructions, which, being taught, return
    +To plague the inventor: this even-handed justice
    +Commends the ingredients of our poison'd chalice
    +To our own lips. He's here in double trust;
    +First, as I am his kinsman and his subject,
    +Strong both against the deed; then, as his host,
    +Who should against his murderer shut the door,
    +Not bear the knife myself. Besides, this Duncan
    +Hath borne his faculties so meek, hath been
    +So clear in his great office, that his virtues
    +Will plead like angels, trumpet-tongued, against
    +The deep damnation of his taking-off;
    +And pity, like a naked new-born babe,
    +Striding the blast, or heaven's cherubim, horsed
    +Upon the sightless couriers of the air,
    +Shall blow the horrid deed in every eye,
    +That tears shall drown the wind. I have no spur
    +To prick the sides of my intent, but only
    +Vaulting ambition, which o'erleaps itself
    +And falls on the other.
    +

    Enter LADY MACBETH

    +How now! what news?
    +
    + +LADY MACBETH +
    +He has almost supp'd: why have you left the chamber?
    +
    + +MACBETH +
    +Hath he ask'd for me?
    +
    + +LADY MACBETH +
    +Know you not he has?
    +
    + +MACBETH +
    +We will proceed no further in this business:
    +He hath honour'd me of late; and I have bought
    +Golden opinions from all sorts of people,
    +Which would be worn now in their newest gloss,
    +Not cast aside so soon.
    +
    + +LADY MACBETH +
    +Was the hope drunk
    +Wherein you dress'd yourself? hath it slept since?
    +And wakes it now, to look so green and pale
    +At what it did so freely? From this time
    +Such I account thy love. Art thou afeard
    +To be the same in thine own act and valour
    +As thou art in desire? Wouldst thou have that
    +Which thou esteem'st the ornament of life,
    +And live a coward in thine own esteem,
    +Letting 'I dare not' wait upon 'I would,'
    +Like the poor cat i' the adage?
    +
    + +MACBETH +
    +Prithee, peace:
    +I dare do all that may become a man;
    +Who dares do more is none.
    +
    + +LADY MACBETH +
    +What beast was't, then,
    +That made you break this enterprise to me?
    +When you durst do it, then you were a man;
    +And, to be more than what you were, you would
    +Be so much more the man. Nor time nor place
    +Did then adhere, and yet you would make both:
    +They have made themselves, and that their fitness now
    +Does unmake you. I have given suck, and know
    +How tender 'tis to love the babe that milks me:
    +I would, while it was smiling in my face,
    +Have pluck'd my nipple from his boneless gums,
    +And dash'd the brains out, had I so sworn as you
    +Have done to this.
    +
    + +MACBETH +
    + If we should fail?
    +
    + +LADY MACBETH +
    +We fail!
    +But screw your courage to the sticking-place,
    +And we'll not fail. When Duncan is asleep--
    +Whereto the rather shall his day's hard journey
    +Soundly invite him--his two chamberlains
    +Will I with wine and wassail so convince
    +That memory, the warder of the brain,
    +Shall be a fume, and the receipt of reason
    +A limbeck only: when in swinish sleep
    +Their drenched natures lie as in a death,
    +What cannot you and I perform upon
    +The unguarded Duncan? what not put upon
    +His spongy officers, who shall bear the guilt
    +Of our great quell?
    +
    + +MACBETH +
    +Bring forth men-children only;
    +For thy undaunted mettle should compose
    +Nothing but males. Will it not be received,
    +When we have mark'd with blood those sleepy two
    +Of his own chamber and used their very daggers,
    +That they have done't?
    +
    + +LADY MACBETH +
    +Who dares receive it other,
    +As we shall make our griefs and clamour roar
    +Upon his death?
    +
    + +MACBETH +
    + I am settled, and bend up
    +Each corporal agent to this terrible feat.
    +Away, and mock the time with fairest show:
    +False face must hide what the false heart doth know.
    +

    Exeunt

    +

    +

    ACT II

    +

    SCENE I. Court of Macbeth's castle.

    +

    +Enter BANQUO, and FLEANCE bearing a torch before him +
    + +BANQUO +
    +How goes the night, boy?
    +
    + +FLEANCE +
    +The moon is down; I have not heard the clock.
    +
    + +BANQUO +
    +And she goes down at twelve.
    +
    + +FLEANCE +
    +I take't, 'tis later, sir.
    +
    + +BANQUO +
    +Hold, take my sword. There's husbandry in heaven;
    +Their candles are all out. Take thee that too.
    +A heavy summons lies like lead upon me,
    +And yet I would not sleep: merciful powers,
    +Restrain in me the cursed thoughts that nature
    +Gives way to in repose!
    +

    Enter MACBETH, and a Servant with a torch

    +Give me my sword.
    +Who's there?
    +
    + +MACBETH +
    +A friend.
    +
    + +BANQUO +
    +What, sir, not yet at rest? The king's a-bed:
    +He hath been in unusual pleasure, and
    +Sent forth great largess to your offices.
    +This diamond he greets your wife withal,
    +By the name of most kind hostess; and shut up
    +In measureless content.
    +
    + +MACBETH +
    +Being unprepared,
    +Our will became the servant to defect;
    +Which else should free have wrought.
    +
    + +BANQUO +
    +All's well.
    +I dreamt last night of the three weird sisters:
    +To you they have show'd some truth.
    +
    + +MACBETH +
    +I think not of them:
    +Yet, when we can entreat an hour to serve,
    +We would spend it in some words upon that business,
    +If you would grant the time.
    +
    + +BANQUO +
    +At your kind'st leisure.
    +
    + +MACBETH +
    +If you shall cleave to my consent, when 'tis,
    +It shall make honour for you.
    +
    + +BANQUO +
    +So I lose none
    +In seeking to augment it, but still keep
    +My bosom franchised and allegiance clear,
    +I shall be counsell'd.
    +
    + +MACBETH +
    +Good repose the while!
    +
    + +BANQUO +
    +Thanks, sir: the like to you!
    +

    Exeunt BANQUO and FLEANCE

    +
    + +MACBETH +
    +Go bid thy mistress, when my drink is ready,
    +She strike upon the bell. Get thee to bed.
    +

    Exit Servant

    +Is this a dagger which I see before me,
    +The handle toward my hand? Come, let me clutch thee.
    +I have thee not, and yet I see thee still.
    +Art thou not, fatal vision, sensible
    +To feeling as to sight? or art thou but
    +A dagger of the mind, a false creation,
    +Proceeding from the heat-oppressed brain?
    +I see thee yet, in form as palpable
    +As this which now I draw.
    +Thou marshall'st me the way that I was going;
    +And such an instrument I was to use.
    +Mine eyes are made the fools o' the other senses,
    +Or else worth all the rest; I see thee still,
    +And on thy blade and dudgeon gouts of blood,
    +Which was not so before. There's no such thing:
    +It is the bloody business which informs
    +Thus to mine eyes. Now o'er the one halfworld
    +Nature seems dead, and wicked dreams abuse
    +The curtain'd sleep; witchcraft celebrates
    +Pale Hecate's offerings, and wither'd murder,
    +Alarum'd by his sentinel, the wolf,
    +Whose howl's his watch, thus with his stealthy pace.
    +With Tarquin's ravishing strides, towards his design
    +Moves like a ghost. Thou sure and firm-set earth,
    +Hear not my steps, which way they walk, for fear
    +Thy very stones prate of my whereabout,
    +And take the present horror from the time,
    +Which now suits with it. Whiles I threat, he lives:
    +Words to the heat of deeds too cold breath gives.
    +

    A bell rings

    +I go, and it is done; the bell invites me.
    +Hear it not, Duncan; for it is a knell
    +That summons thee to heaven or to hell.
    +

    Exit

    +
    +

    SCENE II. The same.

    +

    +Enter LADY MACBETH +
    + +LADY MACBETH +
    +That which hath made them drunk hath made me bold;
    +What hath quench'd them hath given me fire.
    +Hark! Peace!
    +It was the owl that shriek'd, the fatal bellman,
    +Which gives the stern'st good-night. He is about it:
    +The doors are open; and the surfeited grooms
    +Do mock their charge with snores: I have drugg'd
    +their possets,
    +That death and nature do contend about them,
    +Whether they live or die.
    +
    + +MACBETH +
    +[Within] Who's there? what, ho!
    +
    + +LADY MACBETH +
    +Alack, I am afraid they have awaked,
    +And 'tis not done. The attempt and not the deed
    +Confounds us. Hark! I laid their daggers ready;
    +He could not miss 'em. Had he not resembled
    +My father as he slept, I had done't.
    +

    Enter MACBETH

    +My husband!
    +
    + +MACBETH +
    +I have done the deed. Didst thou not hear a noise?
    +
    + +LADY MACBETH +
    +I heard the owl scream and the crickets cry.
    +Did not you speak?
    +
    + +MACBETH +
    + When?
    +
    + +LADY MACBETH +
    +Now.
    +
    + +MACBETH +
    +As I descended?
    +
    + +LADY MACBETH +
    +Ay.
    +
    + +MACBETH +
    +Hark!
    +Who lies i' the second chamber?
    +
    + +LADY MACBETH +
    +Donalbain.
    +
    + +MACBETH +
    +This is a sorry sight.
    +

    Looking on his hands

    +
    + +LADY MACBETH +
    +A foolish thought, to say a sorry sight.
    +
    + +MACBETH +
    +There's one did laugh in's sleep, and one cried
    +'Murder!'
    +That they did wake each other: I stood and heard them:
    +But they did say their prayers, and address'd them
    +Again to sleep.
    +
    + +LADY MACBETH +
    + There are two lodged together.
    +
    + +MACBETH +
    +One cried 'God bless us!' and 'Amen' the other;
    +As they had seen me with these hangman's hands.
    +Listening their fear, I could not say 'Amen,'
    +When they did say 'God bless us!'
    +
    + +LADY MACBETH +
    +Consider it not so deeply.
    +
    + +MACBETH +
    +But wherefore could not I pronounce 'Amen'?
    +I had most need of blessing, and 'Amen'
    +Stuck in my throat.
    +
    + +LADY MACBETH +
    +These deeds must not be thought
    +After these ways; so, it will make us mad.
    +
    + +MACBETH +
    +Methought I heard a voice cry 'Sleep no more!
    +Macbeth does murder sleep', the innocent sleep,
    +Sleep that knits up the ravell'd sleeve of care,
    +The death of each day's life, sore labour's bath,
    +Balm of hurt minds, great nature's second course,
    +Chief nourisher in life's feast,--
    +
    + +LADY MACBETH +
    +What do you mean?
    +
    + +MACBETH +
    +Still it cried 'Sleep no more!' to all the house:
    +'Glamis hath murder'd sleep, and therefore Cawdor
    +Shall sleep no more; Macbeth shall sleep no more.'
    +
    + +LADY MACBETH +
    +Who was it that thus cried? Why, worthy thane,
    +You do unbend your noble strength, to think
    +So brainsickly of things. Go get some water,
    +And wash this filthy witness from your hand.
    +Why did you bring these daggers from the place?
    +They must lie there: go carry them; and smear
    +The sleepy grooms with blood.
    +
    + +MACBETH +
    +I'll go no more:
    +I am afraid to think what I have done;
    +Look on't again I dare not.
    +
    + +LADY MACBETH +
    +Infirm of purpose!
    +Give me the daggers: the sleeping and the dead
    +Are but as pictures: 'tis the eye of childhood
    +That fears a painted devil. If he do bleed,
    +I'll gild the faces of the grooms withal;
    +For it must seem their guilt.
    +

    Exit. Knocking within

    +
    + +MACBETH +
    +Whence is that knocking?
    +How is't with me, when every noise appals me?
    +What hands are here? ha! they pluck out mine eyes.
    +Will all great Neptune's ocean wash this blood
    +Clean from my hand? No, this my hand will rather
    +The multitudinous seas in incarnadine,
    +Making the green one red.
    +

    Re-enter LADY MACBETH

    +
    + +LADY MACBETH +
    +My hands are of your colour; but I shame
    +To wear a heart so white.
    +

    Knocking within

    +I hear a knocking
    +At the south entry: retire we to our chamber;
    +A little water clears us of this deed:
    +How easy is it, then! Your constancy
    +Hath left you unattended.
    +

    Knocking within

    +Hark! more knocking.
    +Get on your nightgown, lest occasion call us,
    +And show us to be watchers. Be not lost
    +So poorly in your thoughts.
    +
    + +MACBETH +
    +To know my deed, 'twere best not know myself.
    +

    Knocking within

    +Wake Duncan with thy knocking! I would thou couldst!
    +

    Exeunt

    +
    +

    SCENE III. The same.

    +

    +Knocking within. Enter a Porter +
    + +Porter +
    +Here's a knocking indeed! If a
    +man were porter of hell-gate, he should have
    +old turning the key.
    +

    Knocking within

    +Knock,
    +knock, knock! Who's there, i' the name of
    +Beelzebub? Here's a farmer, that hanged
    +himself on the expectation of plenty: come in
    +time; have napkins enow about you; here
    +you'll sweat for't.
    +

    Knocking within

    +Knock,
    +knock! Who's there, in the other devil's
    +name? Faith, here's an equivocator, that could
    +swear in both the scales against either scale;
    +who committed treason enough for God's sake,
    +yet could not equivocate to heaven: O, come
    +in, equivocator.
    +

    Knocking within

    +Knock,
    +knock, knock! Who's there? Faith, here's an
    +English tailor come hither, for stealing out of
    +a French hose: come in, tailor; here you may
    +roast your goose.
    +

    Knocking within

    +Knock,
    +knock; never at quiet! What are you? But
    +this place is too cold for hell. I'll devil-porter
    +it no further: I had thought to have let in
    +some of all professions that go the primrose
    +way to the everlasting bonfire.
    +

    Knocking within

    +Anon, anon! I pray you, remember the porter.
    +

    Opens the gate

    +

    Enter MACDUFF and LENNOX

    +
    + +MACDUFF +
    +Was it so late, friend, ere you went to bed,
    +That you do lie so late?
    +
    + +Porter +
    +'Faith sir, we were carousing till the
    +second cock: and drink, sir, is a great
    +provoker of three things.
    +
    + +MACDUFF +
    +What three things does drink especially provoke?
    +
    + +Porter +
    +Marry, sir, nose-painting, sleep, and
    +urine. Lechery, sir, it provokes, and unprovokes;
    +it provokes the desire, but it takes
    +away the performance: therefore, much drink
    +may be said to be an equivocator with lechery:
    +it makes him, and it mars him; it sets
    +him on, and it takes him off; it persuades him,
    +and disheartens him; makes him stand to, and
    +not stand to; in conclusion, equivocates him
    +in a sleep, and, giving him the lie, leaves him.
    +
    + +MACDUFF +
    +I believe drink gave thee the lie last night.
    +
    + +Porter +
    +That it did, sir, i' the very throat on
    +me: but I requited him for his lie; and, I
    +think, being too strong for him, though he took
    +up my legs sometime, yet I made a shift to cast
    +him.
    +
    + +MACDUFF +
    +Is thy master stirring?
    +

    Enter MACBETH

    +Our knocking has awaked him; here he comes.
    +
    + +LENNOX +
    +Good morrow, noble sir.
    +
    + +MACBETH +
    +Good morrow, both.
    +
    + +MACDUFF +
    +Is the king stirring, worthy thane?
    +
    + +MACBETH +
    +Not yet.
    +
    + +MACDUFF +
    +He did command me to call timely on him:
    +I have almost slipp'd the hour.
    +
    + +MACBETH +
    +I'll bring you to him.
    +
    + +MACDUFF +
    +I know this is a joyful trouble to you;
    +But yet 'tis one.
    +
    + +MACBETH +
    +The labour we delight in physics pain.
    +This is the door.
    +
    + +MACDUFF +
    + I'll make so bold to call,
    +For 'tis my limited service.
    +

    Exit

    +
    + +LENNOX +
    +Goes the king hence to-day?
    +
    + +MACBETH +
    +He does: he did appoint so.
    +
    + +LENNOX +
    +The night has been unruly: where we lay,
    +Our chimneys were blown down; and, as they say,
    +Lamentings heard i' the air; strange screams of death,
    +And prophesying with accents terrible
    +Of dire combustion and confused events
    +New hatch'd to the woeful time: the obscure bird
    +Clamour'd the livelong night: some say, the earth
    +Was feverous and did shake.
    +
    + +MACBETH +
    +'Twas a rough night.
    +
    + +LENNOX +
    +My young remembrance cannot parallel
    +A fellow to it.
    +

    Re-enter MACDUFF

    +
    + +MACDUFF +
    +O horror, horror, horror! Tongue nor heart
    +Cannot conceive nor name thee!
    +
    + +MACBETH + +LENNOX +
    +What's the matter.
    +
    + +MACDUFF +
    +Confusion now hath made his masterpiece!
    +Most sacrilegious murder hath broke ope
    +The Lord's anointed temple, and stole thence
    +The life o' the building!
    +
    + +MACBETH +
    +What is 't you say? the life?
    +
    + +LENNOX +
    +Mean you his majesty?
    +
    + +MACDUFF +
    +Approach the chamber, and destroy your sight
    +With a new Gorgon: do not bid me speak;
    +See, and then speak yourselves.
    +

    Exeunt MACBETH and LENNOX

    +Awake, awake!
    +Ring the alarum-bell. Murder and treason!
    +Banquo and Donalbain! Malcolm! awake!
    +Shake off this downy sleep, death's counterfeit,
    +And look on death itself! up, up, and see
    +The great doom's image! Malcolm! Banquo!
    +As from your graves rise up, and walk like sprites,
    +To countenance this horror! Ring the bell.
    +

    Bell rings

    +

    Enter LADY MACBETH

    +
    + +LADY MACBETH +
    +What's the business,
    +That such a hideous trumpet calls to parley
    +The sleepers of the house? speak, speak!
    +
    + +MACDUFF +
    +O gentle lady,
    +'Tis not for you to hear what I can speak:
    +The repetition, in a woman's ear,
    +Would murder as it fell.
    +

    Enter BANQUO

    +O Banquo, Banquo,
    +Our royal master 's murder'd!
    +
    + +LADY MACBETH +
    +Woe, alas!
    +What, in our house?
    +
    + +BANQUO +
    +Too cruel any where.
    +Dear Duff, I prithee, contradict thyself,
    +And say it is not so.
    +

    Re-enter MACBETH and LENNOX, with ROSS

    +
    + +MACBETH +
    +Had I but died an hour before this chance,
    +I had lived a blessed time; for, from this instant,
    +There 's nothing serious in mortality:
    +All is but toys: renown and grace is dead;
    +The wine of life is drawn, and the mere lees
    +Is left this vault to brag of.
    +

    Enter MALCOLM and DONALBAIN

    +
    + +DONALBAIN +
    +What is amiss?
    +
    + +MACBETH +
    + You are, and do not know't:
    +The spring, the head, the fountain of your blood
    +Is stopp'd; the very source of it is stopp'd.
    +
    + +MACDUFF +
    +Your royal father 's murder'd.
    +
    + +MALCOLM +
    +O, by whom?
    +
    + +LENNOX +
    +Those of his chamber, as it seem'd, had done 't:
    +Their hands and faces were an badged with blood;
    +So were their daggers, which unwiped we found
    +Upon their pillows:
    +They stared, and were distracted; no man's life
    +Was to be trusted with them.
    +
    + +MACBETH +
    +O, yet I do repent me of my fury,
    +That I did kill them.
    +
    + +MACDUFF +
    +Wherefore did you so?
    +
    + +MACBETH +
    +Who can be wise, amazed, temperate and furious,
    +Loyal and neutral, in a moment? No man:
    +The expedition my violent love
    +Outrun the pauser, reason. Here lay Duncan,
    +His silver skin laced with his golden blood;
    +And his gash'd stabs look'd like a breach in nature
    +For ruin's wasteful entrance: there, the murderers,
    +Steep'd in the colours of their trade, their daggers
    +Unmannerly breech'd with gore: who could refrain,
    +That had a heart to love, and in that heart
    +Courage to make 's love kno wn?
    +
    + +LADY MACBETH +
    +Help me hence, ho!
    +
    + +MACDUFF +
    +Look to the lady.
    +
    + +MALCOLM +
    +[Aside to DONALBAIN] Why do we hold our tongues,
    +That most may claim this argument for ours?
    +
    + +DONALBAIN +
    +[Aside to MALCOLM] What should be spoken here,
    +where our fate,
    +Hid in an auger-hole, may rush, and seize us?
    +Let 's away;
    +Our tears are not yet brew'd.
    +
    + +MALCOLM +
    +[Aside to DONALBAIN] Nor our strong sorrow
    +Upon the foot of motion.
    +
    + +BANQUO +
    +Look to the lady:
    +

    LADY MACBETH is carried out

    +And when we have our naked frailties hid,
    +That suffer in exposure, let us meet,
    +And question this most bloody piece of work,
    +To know it further. Fears and scruples shake us:
    +In the great hand of God I stand; and thence
    +Against the undivulged pretence I fight
    +Of treasonous malice.
    +
    + +MACDUFF +
    +And so do I.
    +
    + +ALL +
    +So all.
    +
    + +MACBETH +
    +Let's briefly put on manly readiness,
    +And meet i' the hall together.
    +
    + +ALL +
    +Well contented.
    +

    Exeunt all but Malcolm and Donalbain.

    +
    + +MALCOLM +
    +What will you do? Let's not consort with them:
    +To show an unfelt sorrow is an office
    +Which the false man does easy. I'll to England.
    +
    + +DONALBAIN +
    +To Ireland, I; our separated fortune
    +Shall keep us both the safer: where we are,
    +There's daggers in men's smiles: the near in blood,
    +The nearer bloody.
    +
    + +MALCOLM +
    + This murderous shaft that's shot
    +Hath not yet lighted, and our safest way
    +Is to avoid the aim. Therefore, to horse;
    +And let us not be dainty of leave-taking,
    +But shift away: there's warrant in that theft
    +Which steals itself, when there's no mercy left.
    +

    Exeunt

    +
    +

    SCENE IV. Outside Macbeth's castle.

    +

    +Enter ROSS and an old Man +
    + +Old Man +
    +Threescore and ten I can remember well:
    +Within the volume of which time I have seen
    +Hours dreadful and things strange; but this sore night
    +Hath trifled former knowings.
    +
    + +ROSS +
    +Ah, good father,
    +Thou seest, the heavens, as troubled with man's act,
    +Threaten his bloody stage: by the clock, 'tis day,
    +And yet dark night strangles the travelling lamp:
    +Is't night's predominance, or the day's shame,
    +That darkness does the face of earth entomb,
    +When living light should kiss it?
    +
    + +Old Man +
    +'Tis unnatural,
    +Even like the deed that's done. On Tuesday last,
    +A falcon, towering in her pride of place,
    +Was by a mousing owl hawk'd at and kill'd.
    +
    + +ROSS +
    +And Duncan's horses--a thing most strange and certain--
    +Beauteous and swift, the minions of their race,
    +Turn'd wild in nature, broke their stalls, flung out,
    +Contending 'gainst obedience, as they would make
    +War with mankind.
    +
    + +Old Man +
    +'Tis said they eat each other.
    +
    + +ROSS +
    +They did so, to the amazement of mine eyes
    +That look'd upon't. Here comes the good Macduff.
    +

    Enter MACDUFF

    +How goes the world, sir, now?
    +
    + +MACDUFF +
    +Why, see you not?
    +
    + +ROSS +
    +Is't known who did this more than bloody deed?
    +
    + +MACDUFF +
    +Those that Macbeth hath slain.
    +
    + +ROSS +
    +Alas, the day!
    +What good could they pretend?
    +
    + +MACDUFF +
    +They were suborn'd:
    +Malcolm and Donalbain, the king's two sons,
    +Are stol'n away and fled; which puts upon them
    +Suspicion of the deed.
    +
    + +ROSS +
    +'Gainst nature still!
    +Thriftless ambition, that wilt ravin up
    +Thine own life's means! Then 'tis most like
    +The sovereignty will fall upon Macbeth.
    +
    + +MACDUFF +
    +He is already named, and gone to Scone
    +To be invested.
    +
    + +ROSS +
    + Where is Duncan's body?
    +
    + +MACDUFF +
    +Carried to Colmekill,
    +The sacred storehouse of his predecessors,
    +And guardian of their bones.
    +
    + +ROSS +
    +Will you to Scone?
    +
    + +MACDUFF +
    +No, cousin, I'll to Fife.
    +
    + +ROSS +
    +Well, I will thither.
    +
    + +MACDUFF +
    +Well, may you see things well done there: adieu!
    +Lest our old robes sit easier than our new!
    +
    + +ROSS +
    +Farewell, father.
    +
    + +Old Man +
    +God's benison go with you; and with those
    +That would make good of bad, and friends of foes!
    +

    Exeunt

    +

    +

    ACT III

    +

    SCENE I. Forres. The palace.

    +

    +Enter BANQUO +
    + +BANQUO +
    +Thou hast it now: king, Cawdor, Glamis, all,
    +As the weird women promised, and, I fear,
    +Thou play'dst most foully for't: yet it was said
    +It should not stand in thy posterity,
    +But that myself should be the root and father
    +Of many kings. If there come truth from them--
    +As upon thee, Macbeth, their speeches shine--
    +Why, by the verities on thee made good,
    +May they not be my oracles as well,
    +And set me up in hope? But hush! no more.
    +

    Sennet sounded. Enter MACBETH, as king, LADY MACBETH, as queen, LENNOX, ROSS, Lords, Ladies, and Attendants

    +
    + +MACBETH +
    +Here's our chief guest.
    +
    + +LADY MACBETH +
    +If he had been forgotten,
    +It had been as a gap in our great feast,
    +And all-thing unbecoming.
    +
    + +MACBETH +
    +To-night we hold a solemn supper sir,
    +And I'll request your presence.
    +
    + +BANQUO +
    +Let your highness
    +Command upon me; to the which my duties
    +Are with a most indissoluble tie
    +For ever knit.
    +
    + +MACBETH +
    + Ride you this afternoon?
    +
    + +BANQUO +
    +Ay, my good lord.
    +
    + +MACBETH +
    +We should have else desired your good advice,
    +Which still hath been both grave and prosperous,
    +In this day's council; but we'll take to-morrow.
    +Is't far you ride?
    +
    + +BANQUO +
    +As far, my lord, as will fill up the time
    +'Twixt this and supper: go not my horse the better,
    +I must become a borrower of the night
    +For a dark hour or twain.
    +
    + +MACBETH +
    +Fail not our feast.
    +
    + +BANQUO +
    +My lord, I will not.
    +
    + +MACBETH +
    +We hear, our bloody cousins are bestow'd
    +In England and in Ireland, not confessing
    +Their cruel parricide, filling their hearers
    +With strange invention: but of that to-morrow,
    +When therewithal we shall have cause of state
    +Craving us jointly. Hie you to horse: adieu,
    +Till you return at night. Goes Fleance with you?
    +
    + +BANQUO +
    +Ay, my good lord: our time does call upon 's.
    +
    + +MACBETH +
    +I wish your horses swift and sure of foot;
    +And so I do commend you to their backs. Farewell.
    +

    Exit BANQUO

    +Let every man be master of his time
    +Till seven at night: to make society
    +The sweeter welcome, we will keep ourself
    +Till supper-time alone: while then, God be with you!
    +

    Exeunt all but MACBETH, and an attendant

    +Sirrah, a word with you: attend those men
    +Our pleasure?
    +
    + +ATTENDANT +
    +They are, my lord, without the palace gate.
    +
    + +MACBETH +
    +Bring them before us.
    +

    Exit Attendant

    +To be thus is nothing;
    +But to be safely thus.--Our fears in Banquo
    +Stick deep; and in his royalty of nature
    +Reigns that which would be fear'd: 'tis much he dares;
    +And, to that dauntless temper of his mind,
    +He hath a wisdom that doth guide his valour
    +To act in safety. There is none but he
    +Whose being I do fear: and, under him,
    +My Genius is rebuked; as, it is said,
    +Mark Antony's was by Caesar. He chid the sisters
    +When first they put the name of king upon me,
    +And bade them speak to him: then prophet-like
    +They hail'd him father to a line of kings:
    +Upon my head they placed a fruitless crown,
    +And put a barren sceptre in my gripe,
    +Thence to be wrench'd with an unlineal hand,
    +No son of mine succeeding. If 't be so,
    +For Banquo's issue have I filed my mind;
    +For them the gracious Duncan have I murder'd;
    +Put rancours in the vessel of my peace
    +Only for them; and mine eternal jewel
    +Given to the common enemy of man,
    +To make them kings, the seed of Banquo kings!
    +Rather than so, come fate into the list.
    +And champion me to the utterance! Who's there!
    +

    Re-enter Attendant, with two Murderers

    +Now go to the door, and stay there till we call.
    +

    Exit Attendant

    +Was it not yesterday we spoke together?
    +
    + +First Murderer +
    +It was, so please your highness.
    +
    + +MACBETH +
    +Well then, now
    +Have you consider'd of my speeches? Know
    +That it was he in the times past which held you
    +So under fortune, which you thought had been
    +Our innocent self: this I made good to you
    +In our last conference, pass'd in probation with you,
    +How you were borne in hand, how cross'd,
    +the instruments,
    +Who wrought with them, and all things else that might
    +To half a soul and to a notion crazed
    +Say 'Thus did Banquo.'
    +
    + +First Murderer +
    +You made it known to us.
    +
    + +MACBETH +
    +I did so, and went further, which is now
    +Our point of second meeting. Do you find
    +Your patience so predominant in your nature
    +That you can let this go? Are you so gospell'd
    +To pray for this good man and for his issue,
    +Whose heavy hand hath bow'd you to the grave
    +And beggar'd yours for ever?
    +
    + +First Murderer +
    +We are men, my liege.
    +
    + +MACBETH +
    +Ay, in the catalogue ye go for men;
    +As hounds and greyhounds, mongrels, spaniels, curs,
    +Shoughs, water-rugs and demi-wolves, are clept
    +All by the name of dogs: the valued file
    +Distinguishes the swift, the slow, the subtle,
    +The housekeeper, the hunter, every one
    +According to the gift which bounteous nature
    +Hath in him closed; whereby he does receive
    +Particular addition. from the bill
    +That writes them all alike: and so of men.
    +Now, if you have a station in the file,
    +Not i' the worst rank of manhood, say 't;
    +And I will put that business in your bosoms,
    +Whose execution takes your enemy off,
    +Grapples you to the heart and love of us,
    +Who wear our health but sickly in his life,
    +Which in his death were perfect.
    +
    + +Second Murderer +
    +I am one, my liege,
    +Whom the vile blows and buffets of the world
    +Have so incensed that I am reckless what
    +I do to spite the world.
    +
    + +First Murderer +
    +And I another
    +So weary with disasters, tugg'd with fortune,
    +That I would set my lie on any chance,
    +To mend it, or be rid on't.
    +
    + +MACBETH +
    +Both of you
    +Know Banquo was your enemy.
    +
    + +Both Murderers +
    +True, my lord.
    +
    + +MACBETH +
    +So is he mine; and in such bloody distance,
    +That every minute of his being thrusts
    +Against my near'st of life: and though I could
    +With barefaced power sweep him from my sight
    +And bid my will avouch it, yet I must not,
    +For certain friends that are both his and mine,
    +Whose loves I may not drop, but wail his fall
    +Who I myself struck down; and thence it is,
    +That I to your assistance do make love,
    +Masking the business from the common eye
    +For sundry weighty reasons.
    +
    + +Second Murderer +
    +We shall, my lord,
    +Perform what you command us.
    +
    + +First Murderer +
    +Though our lives--
    +
    + +MACBETH +
    +Your spirits shine through you. Within this hour at most
    +I will advise you where to plant yourselves;
    +Acquaint you with the perfect spy o' the time,
    +The moment on't; for't must be done to-night,
    +And something from the palace; always thought
    +That I require a clearness: and with him--
    +To leave no rubs nor botches in the work--
    +Fleance his son, that keeps him company,
    +Whose absence is no less material to me
    +Than is his father's, must embrace the fate
    +Of that dark hour. Resolve yourselves apart:
    +I'll come to you anon.
    +
    + +Both Murderers +
    +We are resolved, my lord.
    +
    + +MACBETH +
    +I'll call upon you straight: abide within.
    +

    Exeunt Murderers

    +It is concluded. Banquo, thy soul's flight,
    +If it find heaven, must find it out to-night.
    +

    Exit

    +
    +

    SCENE II. The palace.

    +

    +Enter LADY MACBETH and a Servant +
    + +LADY MACBETH +
    +Is Banquo gone from court?
    +
    + +Servant +
    +Ay, madam, but returns again to-night.
    +
    + +LADY MACBETH +
    +Say to the king, I would attend his leisure
    +For a few words.
    +
    + +Servant +
    + Madam, I will.
    +

    Exit

    +
    + +LADY MACBETH +
    +Nought's had, all's spent,
    +Where our desire is got without content:
    +'Tis safer to be that which we destroy
    +Than by destruction dwell in doubtful joy.
    +

    Enter MACBETH

    +How now, my lord! why do you keep alone,
    +Of sorriest fancies your companions making,
    +Using those thoughts which should indeed have died
    +With them they think on? Things without all remedy
    +Should be without regard: what's done is done.
    +
    + +MACBETH +
    +We have scotch'd the snake, not kill'd it:
    +She'll close and be herself, whilst our poor malice
    +Remains in danger of her former tooth.
    +But let the frame of things disjoint, both the
    +worlds suffer,
    +Ere we will eat our meal in fear and sleep
    +In the affliction of these terrible dreams
    +That shake us nightly: better be with the dead,
    +Whom we, to gain our peace, have sent to peace,
    +Than on the torture of the mind to lie
    +In restless ecstasy. Duncan is in his grave;
    +After life's fitful fever he sleeps well;
    +Treason has done his worst: nor steel, nor poison,
    +Malice domestic, foreign levy, nothing,
    +Can touch him further.
    +
    + +LADY MACBETH +
    +Come on;
    +Gentle my lord, sleek o'er your rugged looks;
    +Be bright and jovial among your guests to-night.
    +
    + +MACBETH +
    +So shall I, love; and so, I pray, be you:
    +Let your remembrance apply to Banquo;
    +Present him eminence, both with eye and tongue:
    +Unsafe the while, that we
    +Must lave our honours in these flattering streams,
    +And make our faces vizards to our hearts,
    +Disguising what they are.
    +
    + +LADY MACBETH +
    +You must leave this.
    +
    + +MACBETH +
    +O, full of scorpions is my mind, dear wife!
    +Thou know'st that Banquo, and his Fleance, lives.
    +
    + +LADY MACBETH +
    +But in them nature's copy's not eterne.
    +
    + +MACBETH +
    +There's comfort yet; they are assailable;
    +Then be thou jocund: ere the bat hath flown
    +His cloister'd flight, ere to black Hecate's summons
    +The shard-borne beetle with his drowsy hums
    +Hath rung night's yawning peal, there shall be done
    +A deed of dreadful note.
    +
    + +LADY MACBETH +
    +What's to be done?
    +
    + +MACBETH +
    +Be innocent of the knowledge, dearest chuck,
    +Till thou applaud the deed. Come, seeling night,
    +Scarf up the tender eye of pitiful day;
    +And with thy bloody and invisible hand
    +Cancel and tear to pieces that great bond
    +Which keeps me pale! Light thickens; and the crow
    +Makes wing to the rooky wood:
    +Good things of day begin to droop and drowse;
    +While night's black agents to their preys do rouse.
    +Thou marvell'st at my words: but hold thee still;
    +Things bad begun make strong themselves by ill.
    +So, prithee, go with me.
    +

    Exeunt

    +
    +

    SCENE III. A park near the palace.

    +

    +Enter three Murderers +
    + +First Murderer +
    +But who did bid thee join with us?
    +
    + +Third Murderer +
    +Macbeth.
    +
    + +Second Murderer +
    +He needs not our mistrust, since he delivers
    +Our offices and what we have to do
    +To the direction just.
    +
    + +First Murderer +
    +Then stand with us.
    +The west yet glimmers with some streaks of day:
    +Now spurs the lated traveller apace
    +To gain the timely inn; and near approaches
    +The subject of our watch.
    +
    + +Third Murderer +
    +Hark! I hear horses.
    +
    + +BANQUO +
    +[Within] Give us a light there, ho!
    +
    + +Second Murderer +
    +Then 'tis he: the rest
    +That are within the note of expectation
    +Already are i' the court.
    +
    + +First Murderer +
    +His horses go about.
    +
    + +Third Murderer +
    +Almost a mile: but he does usually,
    +So all men do, from hence to the palace gate
    +Make it their walk.
    +
    + +Second Murderer +
    +A light, a light!
    +

    Enter BANQUO, and FLEANCE with a torch

    +
    + +Third Murderer +
    +'Tis he.
    +
    + +First Murderer +
    +Stand to't.
    +
    + +BANQUO +
    +It will be rain to-night.
    +
    + +First Murderer +
    +Let it come down.
    +

    They set upon BANQUO

    +
    + +BANQUO +
    +O, treachery! Fly, good Fleance, fly, fly, fly!
    +Thou mayst revenge. O slave!
    +

    Dies. FLEANCE escapes

    +
    + +Third Murderer +
    +Who did strike out the light?
    +
    + +First Murderer +
    +Wast not the way?
    +
    + +Third Murderer +
    +There's but one down; the son is fled.
    +
    + +Second Murderer +
    +We have lost
    +Best half of our affair.
    +
    + +First Murderer +
    +Well, let's away, and say how much is done.
    +

    Exeunt

    +
    +

    SCENE IV. The same. Hall in the palace.

    +

    +A banquet prepared. Enter MACBETH, LADY MACBETH, ROSS, LENNOX, Lords, and Attendants +
    + +MACBETH +
    +You know your own degrees; sit down: at first
    +And last the hearty welcome.
    +
    + +Lords +
    +Thanks to your majesty.
    +
    + +MACBETH +
    +Ourself will mingle with society,
    +And play the humble host.
    +Our hostess keeps her state, but in best time
    +We will require her welcome.
    +
    + +LADY MACBETH +
    +Pronounce it for me, sir, to all our friends;
    +For my heart speaks they are welcome.
    +

    First Murderer appears at the door

    +
    + +MACBETH +
    +See, they encounter thee with their hearts' thanks.
    +Both sides are even: here I'll sit i' the midst:
    +Be large in mirth; anon we'll drink a measure
    +The table round.
    +

    Approaching the door

    +There's blood on thy face.
    +
    + +First Murderer +
    +'Tis Banquo's then.
    +
    + +MACBETH +
    +'Tis better thee without than he within.
    +Is he dispatch'd?
    +
    + +First Murderer +
    +My lord, his throat is cut; that I did for him.
    +
    + +MACBETH +
    +Thou art the best o' the cut-throats: yet he's good
    +That did the like for Fleance: if thou didst it,
    +Thou art the nonpareil.
    +
    + +First Murderer +
    +Most royal sir,
    +Fleance is 'scaped.
    +
    + +MACBETH +
    +Then comes my fit again: I had else been perfect,
    +Whole as the marble, founded as the rock,
    +As broad and general as the casing air:
    +But now I am cabin'd, cribb'd, confined, bound in
    +To saucy doubts and fears. But Banquo's safe?
    +
    + +First Murderer +
    +Ay, my good lord: safe in a ditch he bides,
    +With twenty trenched gashes on his head;
    +The least a death to nature.
    +
    + +MACBETH +
    +Thanks for that:
    +There the grown serpent lies; the worm that's fled
    +Hath nature that in time will venom breed,
    +No teeth for the present. Get thee gone: to-morrow
    +We'll hear, ourselves, again.
    +

    Exit Murderer

    +
    + +LADY MACBETH +
    +My royal lord,
    +You do not give the cheer: the feast is sold
    +That is not often vouch'd, while 'tis a-making,
    +'Tis given with welcome: to feed were best at home;
    +From thence the sauce to meat is ceremony;
    +Meeting were bare without it.
    +
    + +MACBETH +
    +Sweet remembrancer!
    +Now, good digestion wait on appetite,
    +And health on both!
    +
    + +LENNOX +
    +May't please your highness sit.
    +

    The GHOST OF BANQUO enters, and sits in MACBETH's place

    +
    + +MACBETH +
    +Here had we now our country's honour roof'd,
    +Were the graced person of our Banquo present;
    +Who may I rather challenge for unkindness
    +Than pity for mischance!
    +
    + +ROSS +
    +His absence, sir,
    +Lays blame upon his promise. Please't your highness
    +To grace us with your royal company.
    +
    + +MACBETH +
    +The table's full.
    +
    + +LENNOX +
    + Here is a place reserved, sir.
    +
    + +MACBETH +
    +Where?
    +
    + +LENNOX +
    +Here, my good lord. What is't that moves your highness?
    +
    + +MACBETH +
    +Which of you have done this?
    +
    + +Lords +
    +What, my good lord?
    +
    + +MACBETH +
    +Thou canst not say I did it: never shake
    +Thy gory locks at me.
    +
    + +ROSS +
    +Gentlemen, rise: his highness is not well.
    +
    + +LADY MACBETH +
    +Sit, worthy friends: my lord is often thus,
    +And hath been from his youth: pray you, keep seat;
    +The fit is momentary; upon a thought
    +He will again be well: if much you note him,
    +You shall offend him and extend his passion:
    +Feed, and regard him not. Are you a man?
    +
    + +MACBETH +
    +Ay, and a bold one, that dare look on that
    +Which might appal the devil.
    +
    + +LADY MACBETH +
    +O proper stuff!
    +This is the very painting of your fear:
    +This is the air-drawn dagger which, you said,
    +Led you to Duncan. O, these flaws and starts,
    +Impostors to true fear, would well become
    +A woman's story at a winter's fire,
    +Authorized by her grandam. Shame itself!
    +Why do you make such faces? When all's done,
    +You look but on a stool.
    +
    + +MACBETH +
    +Prithee, see there! behold! look! lo!
    +how say you?
    +Why, what care I? If thou canst nod, speak too.
    +If charnel-houses and our graves must send
    +Those that we bury back, our monuments
    +Shall be the maws of kites.
    +

    GHOST OF BANQUO vanishes

    +
    + +LADY MACBETH +
    +What, quite unmann'd in folly?
    +
    + +MACBETH +
    +If I stand here, I saw him.
    +
    + +LADY MACBETH +
    +Fie, for shame!
    +
    + +MACBETH +
    +Blood hath been shed ere now, i' the olden time,
    +Ere human statute purged the gentle weal;
    +Ay, and since too, murders have been perform'd
    +Too terrible for the ear: the times have been,
    +That, when the brains were out, the man would die,
    +And there an end; but now they rise again,
    +With twenty mortal murders on their crowns,
    +And push us from our stools: this is more strange
    +Than such a murder is.
    +
    + +LADY MACBETH +
    +My worthy lord,
    +Your noble friends do lack you.
    +
    + +MACBETH +
    +I do forget.
    +Do not muse at me, my most worthy friends,
    +I have a strange infirmity, which is nothing
    +To those that know me. Come, love and health to all;
    +Then I'll sit down. Give me some wine; fill full.
    +I drink to the general joy o' the whole table,
    +And to our dear friend Banquo, whom we miss;
    +Would he were here! to all, and him, we thirst,
    +And all to all.
    +
    + +Lords +
    + Our duties, and the pledge.
    +

    Re-enter GHOST OF BANQUO

    +
    + +MACBETH +
    +Avaunt! and quit my sight! let the earth hide thee!
    +Thy bones are marrowless, thy blood is cold;
    +Thou hast no speculation in those eyes
    +Which thou dost glare with!
    +
    + +LADY MACBETH +
    +Think of this, good peers,
    +But as a thing of custom: 'tis no other;
    +Only it spoils the pleasure of the time.
    +
    + +MACBETH +
    +What man dare, I dare:
    +Approach thou like the rugged Russian bear,
    +The arm'd rhinoceros, or the Hyrcan tiger;
    +Take any shape but that, and my firm nerves
    +Shall never tremble: or be alive again,
    +And dare me to the desert with thy sword;
    +If trembling I inhabit then, protest me
    +The baby of a girl. Hence, horrible shadow!
    +Unreal mockery, hence!
    +

    GHOST OF BANQUO vanishes

    +Why, so: being gone,
    +I am a man again. Pray you, sit still.
    +
    + +LADY MACBETH +
    +You have displaced the mirth, broke the good meeting,
    +With most admired disorder.
    +
    + +MACBETH +
    +Can such things be,
    +And overcome us like a summer's cloud,
    +Without our special wonder? You make me strange
    +Even to the disposition that I owe,
    +When now I think you can behold such sights,
    +And keep the natural ruby of your cheeks,
    +When mine is blanched with fear.
    +
    + +ROSS +
    +What sights, my lord?
    +
    + +LADY MACBETH +
    +I pray you, speak not; he grows worse and worse;
    +Question enrages him. At once, good night:
    +Stand not upon the order of your going,
    +But go at once.
    +
    + +LENNOX +
    + Good night; and better health
    +Attend his majesty!
    +
    + +LADY MACBETH +
    +A kind good night to all!
    +

    Exeunt all but MACBETH and LADY MACBETH

    +
    + +MACBETH +
    +It will have blood; they say, blood will have blood:
    +Stones have been known to move and trees to speak;
    +Augurs and understood relations have
    +By magot-pies and choughs and rooks brought forth
    +The secret'st man of blood. What is the night?
    +
    + +LADY MACBETH +
    +Almost at odds with morning, which is which.
    +
    + +MACBETH +
    +How say'st thou, that Macduff denies his person
    +At our great bidding?
    +
    + +LADY MACBETH +
    +Did you send to him, sir?
    +
    + +MACBETH +
    +I hear it by the way; but I will send:
    +There's not a one of them but in his house
    +I keep a servant fee'd. I will to-morrow,
    +And betimes I will, to the weird sisters:
    +More shall they speak; for now I am bent to know,
    +By the worst means, the worst. For mine own good,
    +All causes shall give way: I am in blood
    +Stepp'd in so far that, should I wade no more,
    +Returning were as tedious as go o'er:
    +Strange things I have in head, that will to hand;
    +Which must be acted ere they may be scann'd.
    +
    + +LADY MACBETH +
    +You lack the season of all natures, sleep.
    +
    + +MACBETH +
    +Come, we'll to sleep. My strange and self-abuse
    +Is the initiate fear that wants hard use:
    +We are yet but young in deed.
    +

    Exeunt

    +
    +

    SCENE V. A Heath.

    +

    +Thunder. Enter the three Witches meeting HECATE +
    + +First Witch +
    +Why, how now, Hecate! you look angerly.
    +
    + +HECATE +
    +Have I not reason, beldams as you are,
    +Saucy and overbold? How did you dare
    +To trade and traffic with Macbeth
    +In riddles and affairs of death;
    +And I, the mistress of your charms,
    +The close contriver of all harms,
    +Was never call'd to bear my part,
    +Or show the glory of our art?
    +And, which is worse, all you have done
    +Hath been but for a wayward son,
    +Spiteful and wrathful, who, as others do,
    +Loves for his own ends, not for you.
    +But make amends now: get you gone,
    +And at the pit of Acheron
    +Meet me i' the morning: thither he
    +Will come to know his destiny:
    +Your vessels and your spells provide,
    +Your charms and every thing beside.
    +I am for the air; this night I'll spend
    +Unto a dismal and a fatal end:
    +Great business must be wrought ere noon:
    +Upon the corner of the moon
    +There hangs a vaporous drop profound;
    +I'll catch it ere it come to ground:
    +And that distill'd by magic sleights
    +Shall raise such artificial sprites
    +As by the strength of their illusion
    +Shall draw him on to his confusion:
    +He shall spurn fate, scorn death, and bear
    +He hopes 'bove wisdom, grace and fear:
    +And you all know, security
    +Is mortals' chiefest enemy.
    +

    Music and a song within: 'Come away, come away,' & c

    +Hark! I am call'd; my little spirit, see,
    +Sits in a foggy cloud, and stays for me.
    +

    Exit

    +
    + +First Witch +
    +Come, let's make haste; she'll soon be back again.
    +

    Exeunt

    +
    +

    SCENE VI. Forres. The palace.

    +

    +Enter LENNOX and another Lord +
    + +LENNOX +
    +My former speeches have but hit your thoughts,
    +Which can interpret further: only, I say,
    +Things have been strangely borne. The
    +gracious Duncan
    +Was pitied of Macbeth: marry, he was dead:
    +And the right-valiant Banquo walk'd too late;
    +Whom, you may say, if't please you, Fleance kill'd,
    +For Fleance fled: men must not walk too late.
    +Who cannot want the thought how monstrous
    +It was for Malcolm and for Donalbain
    +To kill their gracious father? damned fact!
    +How it did grieve Macbeth! did he not straight
    +In pious rage the two delinquents tear,
    +That were the slaves of drink and thralls of sleep?
    +Was not that nobly done? Ay, and wisely too;
    +For 'twould have anger'd any heart alive
    +To hear the men deny't. So that, I say,
    +He has borne all things well: and I do think
    +That had he Duncan's sons under his key--
    +As, an't please heaven, he shall not--they
    +should find
    +What 'twere to kill a father; so should Fleance.
    +But, peace! for from broad words and 'cause he fail'd
    +His presence at the tyrant's feast, I hear
    +Macduff lives in disgrace: sir, can you tell
    +Where he bestows himself?
    +
    + +Lord +
    +The son of Duncan,
    +From whom this tyrant holds the due of birth
    +Lives in the English court, and is received
    +Of the most pious Edward with such grace
    +That the malevolence of fortune nothing
    +Takes from his high respect: thither Macduff
    +Is gone to pray the holy king, upon his aid
    +To wake Northumberland and warlike Siward:
    +That, by the help of these--with Him above
    +To ratify the work--we may again
    +Give to our tables meat, sleep to our nights,
    +Free from our feasts and banquets bloody knives,
    +Do faithful homage and receive free honours:
    +All which we pine for now: and this report
    +Hath so exasperate the king that he
    +Prepares for some attempt of war.
    +
    + +LENNOX +
    +Sent he to Macduff?
    +
    + +Lord +
    +He did: and with an absolute 'Sir, not I,'
    +The cloudy messenger turns me his back,
    +And hums, as who should say 'You'll rue the time
    +That clogs me with this answer.'
    +
    + +LENNOX +
    +And that well might
    +Advise him to a caution, to hold what distance
    +His wisdom can provide. Some holy angel
    +Fly to the court of England and unfold
    +His message ere he come, that a swift blessing
    +May soon return to this our suffering country
    +Under a hand accursed!
    +
    + +Lord +
    +I'll send my prayers with him.
    +

    Exeunt

    +

    +

    ACT IV

    +

    SCENE I. A cavern. In the middle, a boiling cauldron.

    +

    +Thunder. Enter the three Witches +
    + +First Witch +
    +Thrice the brinded cat hath mew'd.
    +
    + +Second Witch +
    +Thrice and once the hedge-pig whined.
    +
    + +Third Witch +
    +Harpier cries 'Tis time, 'tis time.
    +
    + +First Witch +
    +Round about the cauldron go;
    +In the poison'd entrails throw.
    +Toad, that under cold stone
    +Days and nights has thirty-one
    +Swelter'd venom sleeping got,
    +Boil thou first i' the charmed pot.
    +
    + +ALL +
    +Double, double toil and trouble;
    +Fire burn, and cauldron bubble.
    +
    + +Second Witch +
    +Fillet of a fenny snake,
    +In the cauldron boil and bake;
    +Eye of newt and toe of frog,
    +Wool of bat and tongue of dog,
    +Adder's fork and blind-worm's sting,
    +Lizard's leg and owlet's wing,
    +For a charm of powerful trouble,
    +Like a hell-broth boil and bubble.
    +
    + +ALL +
    +Double, double toil and trouble;
    +Fire burn and cauldron bubble.
    +
    + +Third Witch +
    +Scale of dragon, tooth of wolf,
    +Witches' mummy, maw and gulf
    +Of the ravin'd salt-sea shark,
    +Root of hemlock digg'd i' the dark,
    +Liver of blaspheming Jew,
    +Gall of goat, and slips of yew
    +Silver'd in the moon's eclipse,
    +Nose of Turk and Tartar's lips,
    +Finger of birth-strangled babe
    +Ditch-deliver'd by a drab,
    +Make the gruel thick and slab:
    +Add thereto a tiger's chaudron,
    +For the ingredients of our cauldron.
    +
    + +ALL +
    +Double, double toil and trouble;
    +Fire burn and cauldron bubble.
    +
    + +Second Witch +
    +Cool it with a baboon's blood,
    +Then the charm is firm and good.
    +

    Enter HECATE to the other three Witches

    +
    + +HECATE +
    +O well done! I commend your pains;
    +And every one shall share i' the gains;
    +And now about the cauldron sing,
    +Live elves and fairies in a ring,
    +Enchanting all that you put in.
    +

    Music and a song: 'Black spirits,' & c

    +

    HECATE retires

    +
    + +Second Witch +
    +By the pricking of my thumbs,
    +Something wicked this way comes.
    +Open, locks,
    +Whoever knocks!
    +

    Enter MACBETH

    +
    + +MACBETH +
    +How now, you secret, black, and midnight hags!
    +What is't you do?
    +
    + +ALL +
    + A deed without a name.
    +
    + +MACBETH +
    +I conjure you, by that which you profess,
    +Howe'er you come to know it, answer me:
    +Though you untie the winds and let them fight
    +Against the churches; though the yesty waves
    +Confound and swallow navigation up;
    +Though bladed corn be lodged and trees blown down;
    +Though castles topple on their warders' heads;
    +Though palaces and pyramids do slope
    +Their heads to their foundations; though the treasure
    +Of nature's germens tumble all together,
    +Even till destruction sicken; answer me
    +To what I ask you.
    +
    + +First Witch +
    + Speak.
    +
    + +Second Witch +
    +Demand.
    +
    + +Third Witch +
    +We'll answer.
    +
    + +First Witch +
    +Say, if thou'dst rather hear it from our mouths,
    +Or from our masters?
    +
    + +MACBETH +
    +Call 'em; let me see 'em.
    +
    + +First Witch +
    +Pour in sow's blood, that hath eaten
    +Her nine farrow; grease that's sweaten
    +From the murderer's gibbet throw
    +Into the flame.
    +
    + +ALL +
    + Come, high or low;
    +Thyself and office deftly show!
    +

    Thunder. First Apparition: an armed Head

    +
    + +MACBETH +
    +Tell me, thou unknown power,--
    +
    + +First Witch +
    +He knows thy thought:
    +Hear his speech, but say thou nought.
    +
    + +First Apparition +
    +Macbeth! Macbeth! Macbeth! beware Macduff;
    +Beware the thane of Fife. Dismiss me. Enough.
    +

    Descends

    +
    + +MACBETH +
    +Whate'er thou art, for thy good caution, thanks;
    +Thou hast harp'd my fear aright: but one
    +word more,--
    +
    + +First Witch +
    +He will not be commanded: here's another,
    +More potent than the first.
    +

    Thunder. Second Apparition: A bloody Child

    +
    + +Second Apparition +
    +Macbeth! Macbeth! Macbeth!
    +
    + +MACBETH +
    +Had I three ears, I'ld hear thee.
    +
    + +Second Apparition +
    +Be bloody, bold, and resolute; laugh to scorn
    +The power of man, for none of woman born
    +Shall harm Macbeth.
    +

    Descends

    +
    + +MACBETH +
    +Then live, Macduff: what need I fear of thee?
    +But yet I'll make assurance double sure,
    +And take a bond of fate: thou shalt not live;
    +That I may tell pale-hearted fear it lies,
    +And sleep in spite of thunder.
    +

    Thunder. Third Apparition: a Child crowned, with a tree in his hand

    +What is this
    +That rises like the issue of a king,
    +And wears upon his baby-brow the round
    +And top of sovereignty?
    +
    + +ALL +
    +Listen, but speak not to't.
    +
    + +Third Apparition +
    +Be lion-mettled, proud; and take no care
    +Who chafes, who frets, or where conspirers are:
    +Macbeth shall never vanquish'd be until
    +Great Birnam wood to high Dunsinane hill
    +Shall come against him.
    +

    Descends

    +
    + +MACBETH +
    +That will never be
    +Who can impress the forest, bid the tree
    +Unfix his earth-bound root? Sweet bodements! good!
    +Rebellion's head, rise never till the wood
    +Of Birnam rise, and our high-placed Macbeth
    +Shall live the lease of nature, pay his breath
    +To time and mortal custom. Yet my heart
    +Throbs to know one thing: tell me, if your art
    +Can tell so much: shall Banquo's issue ever
    +Reign in this kingdom?
    +
    + +ALL +
    +Seek to know no more.
    +
    + +MACBETH +
    +I will be satisfied: deny me this,
    +And an eternal curse fall on you! Let me know.
    +Why sinks that cauldron? and what noise is this?
    +

    Hautboys

    +
    + +First Witch +
    +Show!
    +
    + +Second Witch +
    +Show!
    +
    + +Third Witch +
    +Show!
    +
    + +ALL +
    +Show his eyes, and grieve his heart;
    +Come like shadows, so depart!
    +

    A show of Eight Kings, the last with a glass in his hand; GHOST OF BANQUO following

    +
    + +MACBETH +
    +Thou art too like the spirit of Banquo: down!
    +Thy crown does sear mine eye-balls. And thy hair,
    +Thou other gold-bound brow, is like the first.
    +A third is like the former. Filthy hags!
    +Why do you show me this? A fourth! Start, eyes!
    +What, will the line stretch out to the crack of doom?
    +Another yet! A seventh! I'll see no more:
    +And yet the eighth appears, who bears a glass
    +Which shows me many more; and some I see
    +That two-fold balls and treble scepters carry:
    +Horrible sight! Now, I see, 'tis true;
    +For the blood-bolter'd Banquo smiles upon me,
    +And points at them for his.
    +

    Apparitions vanish

    +What, is this so?
    +
    + +First Witch +
    +Ay, sir, all this is so: but why
    +Stands Macbeth thus amazedly?
    +Come, sisters, cheer we up his sprites,
    +And show the best of our delights:
    +I'll charm the air to give a sound,
    +While you perform your antic round:
    +That this great king may kindly say,
    +Our duties did his welcome pay.
    +

    Music. The witches dance and then vanish, with HECATE

    +
    + +MACBETH +
    +Where are they? Gone? Let this pernicious hour
    +Stand aye accursed in the calendar!
    +Come in, without there!
    +

    Enter LENNOX

    +
    + +LENNOX +
    +What's your grace's will?
    +
    + +MACBETH +
    +Saw you the weird sisters?
    +
    + +LENNOX +
    +No, my lord.
    +
    + +MACBETH +
    +Came they not by you?
    +
    + +LENNOX +
    +No, indeed, my lord.
    +
    + +MACBETH +
    +Infected be the air whereon they ride;
    +And damn'd all those that trust them! I did hear
    +The galloping of horse: who was't came by?
    +
    + +LENNOX +
    +'Tis two or three, my lord, that bring you word
    +Macduff is fled to England.
    +
    + +MACBETH +
    +Fled to England!
    +
    + +LENNOX +
    +Ay, my good lord.
    +
    + +MACBETH +
    +Time, thou anticipatest my dread exploits:
    +The flighty purpose never is o'ertook
    +Unless the deed go with it; from this moment
    +The very firstlings of my heart shall be
    +The firstlings of my hand. And even now,
    +To crown my thoughts with acts, be it thought and done:
    +The castle of Macduff I will surprise;
    +Seize upon Fife; give to the edge o' the sword
    +His wife, his babes, and all unfortunate souls
    +That trace him in his line. No boasting like a fool;
    +This deed I'll do before this purpose cool.
    +But no more sights!--Where are these gentlemen?
    +Come, bring me where they are.
    +

    Exeunt

    +
    +

    SCENE II. Fife. Macduff's castle.

    +

    +Enter LADY MACDUFF, her Son, and ROSS +
    + +LADY MACDUFF +
    +What had he done, to make him fly the land?
    +
    + +ROSS +
    +You must have patience, madam.
    +
    + +LADY MACDUFF +
    +He had none:
    +His flight was madness: when our actions do not,
    +Our fears do make us traitors.
    +
    + +ROSS +
    +You know not
    +Whether it was his wisdom or his fear.
    +
    + +LADY MACDUFF +
    +Wisdom! to leave his wife, to leave his babes,
    +His mansion and his titles in a place
    +From whence himself does fly? He loves us not;
    +He wants the natural touch: for the poor wren,
    +The most diminutive of birds, will fight,
    +Her young ones in her nest, against the owl.
    +All is the fear and nothing is the love;
    +As little is the wisdom, where the flight
    +So runs against all reason.
    +
    + +ROSS +
    +My dearest coz,
    +I pray you, school yourself: but for your husband,
    +He is noble, wise, judicious, and best knows
    +The fits o' the season. I dare not speak
    +much further;
    +But cruel are the times, when we are traitors
    +And do not know ourselves, when we hold rumour
    +From what we fear, yet know not what we fear,
    +But float upon a wild and violent sea
    +Each way and move. I take my leave of you:
    +Shall not be long but I'll be here again:
    +Things at the worst will cease, or else climb upward
    +To what they were before. My pretty cousin,
    +Blessing upon you!
    +
    + +LADY MACDUFF +
    +Father'd he is, and yet he's fatherless.
    +
    + +ROSS +
    +I am so much a fool, should I stay longer,
    +It would be my disgrace and your discomfort:
    +I take my leave at once.
    +

    Exit

    +
    + +LADY MACDUFF +
    +Sirrah, your father's dead;
    +And what will you do now? How will you live?
    +
    + +Son +
    +As birds do, mother.
    +
    + +LADY MACDUFF +
    +What, with worms and flies?
    +
    + +Son +
    +With what I get, I mean; and so do they.
    +
    + +LADY MACDUFF +
    +Poor bird! thou'ldst never fear the net nor lime,
    +The pitfall nor the gin.
    +
    + +Son +
    +Why should I, mother? Poor birds they are not set for.
    +My father is not dead, for all your saying.
    +
    + +LADY MACDUFF +
    +Yes, he is dead; how wilt thou do for a father?
    +
    + +Son +
    +Nay, how will you do for a husband?
    +
    + +LADY MACDUFF +
    +Why, I can buy me twenty at any market.
    +
    + +Son +
    +Then you'll buy 'em to sell again.
    +
    + +LADY MACDUFF +
    +Thou speak'st with all thy wit: and yet, i' faith,
    +With wit enough for thee.
    +
    + +Son +
    +Was my father a traitor, mother?
    +
    + +LADY MACDUFF +
    +Ay, that he was.
    +
    + +Son +
    +What is a traitor?
    +
    + +LADY MACDUFF +
    +Why, one that swears and lies.
    +
    + +Son +
    +And be all traitors that do so?
    +
    + +LADY MACDUFF +
    +Every one that does so is a traitor, and must be hanged.
    +
    + +Son +
    +And must they all be hanged that swear and lie?
    +
    + +LADY MACDUFF +
    +Every one.
    +
    + +Son +
    +Who must hang them?
    +
    + +LADY MACDUFF +
    +Why, the honest men.
    +
    + +Son +
    +Then the liars and swearers are fools,
    +for there are liars and swearers enow to beat
    +the honest men and hang up them.
    +
    + +LADY MACDUFF +
    +Now, God help thee, poor monkey!
    +But how wilt thou do for a father?
    +
    + +Son +
    +If he were dead, you'ld weep for
    +him: if you would not, it were a good sign
    +that I should quickly have a new father.
    +
    + +LADY MACDUFF +
    +Poor prattler, how thou talk'st!
    +

    Enter a Messenger

    +
    + +Messenger +
    +Bless you, fair dame! I am not to you known,
    +Though in your state of honour I am perfect.
    +I doubt some danger does approach you nearly:
    +If you will take a homely man's advice,
    +Be not found here; hence, with your little ones.
    +To fright you thus, methinks, I am too savage;
    +To do worse to you were fell cruelty,
    +Which is too nigh your person. Heaven preserve you!
    +I dare abide no longer.
    +

    Exit

    +
    + +LADY MACDUFF +
    +Whither should I fly?
    +I have done no harm. But I remember now
    +I am in this earthly world; where to do harm
    +Is often laudable, to do good sometime
    +Accounted dangerous folly: why then, alas,
    +Do I put up that womanly defence,
    +To say I have done no harm?
    +

    Enter Murderers

    +What are these faces?
    +
    + +First Murderer +
    +Where is your husband?
    +
    + +LADY MACDUFF +
    +I hope, in no place so unsanctified
    +Where such as thou mayst find him.
    +
    + +First Murderer +
    +He's a traitor.
    +
    + +Son +
    +Thou liest, thou shag-hair'd villain!
    +
    + +First Murderer +
    +What, you egg!
    +

    Stabbing him

    +Young fry of treachery!
    +
    + +Son +
    +He has kill'd me, mother:
    +Run away, I pray you!
    +

    Dies

    +

    Exit LADY MACDUFF, crying 'Murder!' Exeunt Murderers, following her

    +
    +

    SCENE III. England. Before the King's palace.

    +

    +Enter MALCOLM and MACDUFF +
    + +MALCOLM +
    +Let us seek out some desolate shade, and there
    +Weep our sad bosoms empty.
    +
    + +MACDUFF +
    +Let us rather
    +Hold fast the mortal sword, and like good men
    +Bestride our down-fall'n birthdom: each new morn
    +New widows howl, new orphans cry, new sorrows
    +Strike heaven on the face, that it resounds
    +As if it felt with Scotland and yell'd out
    +Like syllable of dolour.
    +
    + +MALCOLM +
    +What I believe I'll wail,
    +What know believe, and what I can redress,
    +As I shall find the time to friend, I will.
    +What you have spoke, it may be so perchance.
    +This tyrant, whose sole name blisters our tongues,
    +Was once thought honest: you have loved him well.
    +He hath not touch'd you yet. I am young;
    +but something
    +You may deserve of him through me, and wisdom
    +To offer up a weak poor innocent lamb
    +To appease an angry god.
    +
    + +MACDUFF +
    +I am not treacherous.
    +
    + +MALCOLM +
    +But Macbeth is.
    +A good and virtuous nature may recoil
    +In an imperial charge. But I shall crave
    +your pardon;
    +That which you are my thoughts cannot transpose:
    +Angels are bright still, though the brightest fell;
    +Though all things foul would wear the brows of grace,
    +Yet grace must still look so.
    +
    + +MACDUFF +
    +I have lost my hopes.
    +
    + +MALCOLM +
    +Perchance even there where I did find my doubts.
    +Why in that rawness left you wife and child,
    +Those precious motives, those strong knots of love,
    +Without leave-taking? I pray you,
    +Let not my jealousies be your dishonours,
    +But mine own safeties. You may be rightly just,
    +Whatever I shall think.
    +
    + +MACDUFF +
    +Bleed, bleed, poor country!
    +Great tyranny! lay thou thy basis sure,
    +For goodness dare not cheque thee: wear thou
    +thy wrongs;
    +The title is affeer'd! Fare thee well, lord:
    +I would not be the villain that thou think'st
    +For the whole space that's in the tyrant's grasp,
    +And the rich East to boot.
    +
    + +MALCOLM +
    +Be not offended:
    +I speak not as in absolute fear of you.
    +I think our country sinks beneath the yoke;
    +It weeps, it bleeds; and each new day a gash
    +Is added to her wounds: I think withal
    +There would be hands uplifted in my right;
    +And here from gracious England have I offer
    +Of goodly thousands: but, for all this,
    +When I shall tread upon the tyrant's head,
    +Or wear it on my sword, yet my poor country
    +Shall have more vices than it had before,
    +More suffer and more sundry ways than ever,
    +By him that shall succeed.
    +
    + +MACDUFF +
    +What should he be?
    +
    + +MALCOLM +
    +It is myself I mean: in whom I know
    +All the particulars of vice so grafted
    +That, when they shall be open'd, black Macbeth
    +Will seem as pure as snow, and the poor state
    +Esteem him as a lamb, being compared
    +With my confineless harms.
    +
    + +MACDUFF +
    +Not in the legions
    +Of horrid hell can come a devil more damn'd
    +In evils to top Macbeth.
    +
    + +MALCOLM +
    +I grant him bloody,
    +Luxurious, avaricious, false, deceitful,
    +Sudden, malicious, smacking of every sin
    +That has a name: but there's no bottom, none,
    +In my voluptuousness: your wives, your daughters,
    +Your matrons and your maids, could not fill up
    +The cistern of my lust, and my desire
    +All continent impediments would o'erbear
    +That did oppose my will: better Macbeth
    +Than such an one to reign.
    +
    + +MACDUFF +
    +Boundless intemperance
    +In nature is a tyranny; it hath been
    +The untimely emptying of the happy throne
    +And fall of many kings. But fear not yet
    +To take upon you what is yours: you may
    +Convey your pleasures in a spacious plenty,
    +And yet seem cold, the time you may so hoodwink.
    +We have willing dames enough: there cannot be
    +That vulture in you, to devour so many
    +As will to greatness dedicate themselves,
    +Finding it so inclined.
    +
    + +MALCOLM +
    +With this there grows
    +In my most ill-composed affection such
    +A stanchless avarice that, were I king,
    +I should cut off the nobles for their lands,
    +Desire his jewels and this other's house:
    +And my more-having would be as a sauce
    +To make me hunger more; that I should forge
    +Quarrels unjust against the good and loyal,
    +Destroying them for wealth.
    +
    + +MACDUFF +
    +This avarice
    +Sticks deeper, grows with more pernicious root
    +Than summer-seeming lust, and it hath been
    +The sword of our slain kings: yet do not fear;
    +Scotland hath foisons to fill up your will.
    +Of your mere own: all these are portable,
    +With other graces weigh'd.
    +
    + +MALCOLM +
    +But I have none: the king-becoming graces,
    +As justice, verity, temperance, stableness,
    +Bounty, perseverance, mercy, lowliness,
    +Devotion, patience, courage, fortitude,
    +I have no relish of them, but abound
    +In the division of each several crime,
    +Acting it many ways. Nay, had I power, I should
    +Pour the sweet milk of concord into hell,
    +Uproar the universal peace, confound
    +All unity on earth.
    +
    + +MACDUFF +
    +O Scotland, Scotland!
    +
    + +MALCOLM +
    +If such a one be fit to govern, speak:
    +I am as I have spoken.
    +
    + +MACDUFF +
    +Fit to govern!
    +No, not to live. O nation miserable,
    +With an untitled tyrant bloody-scepter'd,
    +When shalt thou see thy wholesome days again,
    +Since that the truest issue of thy throne
    +By his own interdiction stands accursed,
    +And does blaspheme his breed? Thy royal father
    +Was a most sainted king: the queen that bore thee,
    +Oftener upon her knees than on her feet,
    +Died every day she lived. Fare thee well!
    +These evils thou repeat'st upon thyself
    +Have banish'd me from Scotland. O my breast,
    +Thy hope ends here!
    +
    + +MALCOLM +
    +Macduff, this noble passion,
    +Child of integrity, hath from my soul
    +Wiped the black scruples, reconciled my thoughts
    +To thy good truth and honour. Devilish Macbeth
    +By many of these trains hath sought to win me
    +Into his power, and modest wisdom plucks me
    +From over-credulous haste: but God above
    +Deal between thee and me! for even now
    +I put myself to thy direction, and
    +Unspeak mine own detraction, here abjure
    +The taints and blames I laid upon myself,
    +For strangers to my nature. I am yet
    +Unknown to woman, never was forsworn,
    +Scarcely have coveted what was mine own,
    +At no time broke my faith, would not betray
    +The devil to his fellow and delight
    +No less in truth than life: my first false speaking
    +Was this upon myself: what I am truly,
    +Is thine and my poor country's to command:
    +Whither indeed, before thy here-approach,
    +Old Siward, with ten thousand warlike men,
    +Already at a point, was setting forth.
    +Now we'll together; and the chance of goodness
    +Be like our warranted quarrel! Why are you silent?
    +
    + +MACDUFF +
    +Such welcome and unwelcome things at once
    +'Tis hard to reconcile.
    +

    Enter a Doctor

    +
    + +MALCOLM +
    +Well; more anon.--Comes the king forth, I pray you?
    +
    + +Doctor +
    +Ay, sir; there are a crew of wretched souls
    +That stay his cure: their malady convinces
    +The great assay of art; but at his touch--
    +Such sanctity hath heaven given his hand--
    +They presently amend.
    +
    + +MALCOLM +
    +I thank you, doctor.
    +

    Exit Doctor

    +
    + +MACDUFF +
    +What's the disease he means?
    +
    + +MALCOLM +
    +'Tis call'd the evil:
    +A most miraculous work in this good king;
    +Which often, since my here-remain in England,
    +I have seen him do. How he solicits heaven,
    +Himself best knows: but strangely-visited people,
    +All swoln and ulcerous, pitiful to the eye,
    +The mere despair of surgery, he cures,
    +Hanging a golden stamp about their necks,
    +Put on with holy prayers: and 'tis spoken,
    +To the succeeding royalty he leaves
    +The healing benediction. With this strange virtue,
    +He hath a heavenly gift of prophecy,
    +And sundry blessings hang about his throne,
    +That speak him full of grace.
    +

    Enter ROSS

    +
    + +MACDUFF +
    +See, who comes here?
    +
    + +MALCOLM +
    +My countryman; but yet I know him not.
    +
    + +MACDUFF +
    +My ever-gentle cousin, welcome hither.
    +
    + +MALCOLM +
    +I know him now. Good God, betimes remove
    +The means that makes us strangers!
    +
    + +ROSS +
    +Sir, amen.
    +
    + +MACDUFF +
    +Stands Scotland where it did?
    +
    + +ROSS +
    +Alas, poor country!
    +Almost afraid to know itself. It cannot
    +Be call'd our mother, but our grave; where nothing,
    +But who knows nothing, is once seen to smile;
    +Where sighs and groans and shrieks that rend the air
    +Are made, not mark'd; where violent sorrow seems
    +A modern ecstasy; the dead man's knell
    +Is there scarce ask'd for who; and good men's lives
    +Expire before the flowers in their caps,
    +Dying or ere they sicken.
    +
    + +MACDUFF +
    +O, relation
    +Too nice, and yet too true!
    +
    + +MALCOLM +
    +What's the newest grief?
    +
    + +ROSS +
    +That of an hour's age doth hiss the speaker:
    +Each minute teems a new one.
    +
    + +MACDUFF +
    +How does my wife?
    +
    + +ROSS +
    +Why, well.
    +
    + +MACDUFF +
    + And all my children?
    +
    + +ROSS +
    +Well too.
    +
    + +MACDUFF +
    +The tyrant has not batter'd at their peace?
    +
    + +ROSS +
    +No; they were well at peace when I did leave 'em.
    +
    + +MACDUFF +
    +But not a niggard of your speech: how goes't?
    +
    + +ROSS +
    +When I came hither to transport the tidings,
    +Which I have heavily borne, there ran a rumour
    +Of many worthy fellows that were out;
    +Which was to my belief witness'd the rather,
    +For that I saw the tyrant's power a-foot:
    +Now is the time of help; your eye in Scotland
    +Would create soldiers, make our women fight,
    +To doff their dire distresses.
    +
    + +MALCOLM +
    +Be't their comfort
    +We are coming thither: gracious England hath
    +Lent us good Siward and ten thousand men;
    +An older and a better soldier none
    +That Christendom gives out.
    +
    + +ROSS +
    +Would I could answer
    +This comfort with the like! But I have words
    +That would be howl'd out in the desert air,
    +Where hearing should not latch them.
    +
    + +MACDUFF +
    +What concern they?
    +The general cause? or is it a fee-grief
    +Due to some single breast?
    +
    + +ROSS +
    +No mind that's honest
    +But in it shares some woe; though the main part
    +Pertains to you alone.
    +
    + +MACDUFF +
    +If it be mine,
    +Keep it not from me, quickly let me have it.
    +
    + +ROSS +
    +Let not your ears despise my tongue for ever,
    +Which shall possess them with the heaviest sound
    +That ever yet they heard.
    +
    + +MACDUFF +
    +Hum! I guess at it.
    +
    + +ROSS +
    +Your castle is surprised; your wife and babes
    +Savagely slaughter'd: to relate the manner,
    +Were, on the quarry of these murder'd deer,
    +To add the death of you.
    +
    + +MALCOLM +
    +Merciful heaven!
    +What, man! ne'er pull your hat upon your brows;
    +Give sorrow words: the grief that does not speak
    +Whispers the o'er-fraught heart and bids it break.
    +
    + +MACDUFF +
    +My children too?
    +
    + +ROSS +
    + Wife, children, servants, all
    +That could be found.
    +
    + +MACDUFF +
    +And I must be from thence!
    +My wife kill'd too?
    +
    + +ROSS +
    +I have said.
    +
    + +MALCOLM +
    +Be comforted:
    +Let's make us medicines of our great revenge,
    +To cure this deadly grief.
    +
    + +MACDUFF +
    +He has no children. All my pretty ones?
    +Did you say all? O hell-kite! All?
    +What, all my pretty chickens and their dam
    +At one fell swoop?
    +
    + +MALCOLM +
    +Dispute it like a man.
    +
    + +MACDUFF +
    +I shall do so;
    +But I must also feel it as a man:
    +I cannot but remember such things were,
    +That were most precious to me. Did heaven look on,
    +And would not take their part? Sinful Macduff,
    +They were all struck for thee! naught that I am,
    +Not for their own demerits, but for mine,
    +Fell slaughter on their souls. Heaven rest them now!
    +
    + +MALCOLM +
    +Be this the whetstone of your sword: let grief
    +Convert to anger; blunt not the heart, enrage it.
    +
    + +MACDUFF +
    +O, I could play the woman with mine eyes
    +And braggart with my tongue! But, gentle heavens,
    +Cut short all intermission; front to front
    +Bring thou this fiend of Scotland and myself;
    +Within my sword's length set him; if he 'scape,
    +Heaven forgive him too!
    +
    + +MALCOLM +
    +This tune goes manly.
    +Come, go we to the king; our power is ready;
    +Our lack is nothing but our leave; Macbeth
    +Is ripe for shaking, and the powers above
    +Put on their instruments. Receive what cheer you may:
    +The night is long that never finds the day.
    +

    Exeunt

    +

    +

    ACT V

    +

    SCENE I. Dunsinane. Ante-room in the castle.

    +

    +Enter a Doctor of Physic and a Waiting-Gentlewoman +
    + +Doctor +
    +I have two nights watched with you, but can perceive
    +no truth in your report. When was it she last walked?
    +
    + +Gentlewoman +
    +Since his majesty went into the field, I have seen
    +her rise from her bed, throw her night-gown upon
    +her, unlock her closet, take forth paper, fold it,
    +write upon't, read it, afterwards seal it, and again
    +return to bed; yet all this while in a most fast sleep.
    +
    + +Doctor +
    +A great perturbation in nature, to receive at once
    +the benefit of sleep, and do the effects of
    +watching! In this slumbery agitation, besides her
    +walking and other actual performances, what, at any
    +time, have you heard her say?
    +
    + +Gentlewoman +
    +That, sir, which I will not report after her.
    +
    + +Doctor +
    +You may to me: and 'tis most meet you should.
    +
    + +Gentlewoman +
    +Neither to you nor any one; having no witness to
    +confirm my speech.
    +

    Enter LADY MACBETH, with a taper

    +Lo you, here she comes! This is her very guise;
    +and, upon my life, fast asleep. Observe her; stand close.
    +
    + +Doctor +
    +How came she by that light?
    +
    + +Gentlewoman +
    +Why, it stood by her: she has light by her
    +continually; 'tis her command.
    +
    + +Doctor +
    +You see, her eyes are open.
    +
    + +Gentlewoman +
    +Ay, but their sense is shut.
    +
    + +Doctor +
    +What is it she does now? Look, how she rubs her hands.
    +
    + +Gentlewoman +
    +It is an accustomed action with her, to seem thus
    +washing her hands: I have known her continue in
    +this a quarter of an hour.
    +
    + +LADY MACBETH +
    +Yet here's a spot.
    +
    + +Doctor +
    +Hark! she speaks: I will set down what comes from
    +her, to satisfy my remembrance the more strongly.
    +
    + +LADY MACBETH +
    +Out, damned spot! out, I say!--One: two: why,
    +then, 'tis time to do't.--Hell is murky!--Fie, my
    +lord, fie! a soldier, and afeard? What need we
    +fear who knows it, when none can call our power to
    +account?--Yet who would have thought the old man
    +to have had so much blood in him.
    +
    + +Doctor +
    +Do you mark that?
    +
    + +LADY MACBETH +
    +The thane of Fife had a wife: where is she now?--
    +What, will these hands ne'er be clean?--No more o'
    +that, my lord, no more o' that: you mar all with
    +this starting.
    +
    + +Doctor +
    +Go to, go to; you have known what you should not.
    +
    + +Gentlewoman +
    +She has spoke what she should not, I am sure of
    +that: heaven knows what she has known.
    +
    + +LADY MACBETH +
    +Here's the smell of the blood still: all the
    +perfumes of Arabia will not sweeten this little
    +hand. Oh, oh, oh!
    +
    + +Doctor +
    +What a sigh is there! The heart is sorely charged.
    +
    + +Gentlewoman +
    +I would not have such a heart in my bosom for the
    +dignity of the whole body.
    +
    + +Doctor +
    +Well, well, well,--
    +
    + +Gentlewoman +
    +Pray God it be, sir.
    +
    + +Doctor +
    +This disease is beyond my practise: yet I have known
    +those which have walked in their sleep who have died
    +holily in their beds.
    +
    + +LADY MACBETH +
    +Wash your hands, put on your nightgown; look not so
    +pale.--I tell you yet again, Banquo's buried; he
    +cannot come out on's grave.
    +
    + +Doctor +
    +Even so?
    +
    + +LADY MACBETH +
    +To bed, to bed! there's knocking at the gate:
    +come, come, come, come, give me your hand. What's
    +done cannot be undone.--To bed, to bed, to bed!
    +

    Exit

    +
    + +Doctor +
    +Will she go now to bed?
    +
    + +Gentlewoman +
    +Directly.
    +
    + +Doctor +
    +Foul whisperings are abroad: unnatural deeds
    +Do breed unnatural troubles: infected minds
    +To their deaf pillows will discharge their secrets:
    +More needs she the divine than the physician.
    +God, God forgive us all! Look after her;
    +Remove from her the means of all annoyance,
    +And still keep eyes upon her. So, good night:
    +My mind she has mated, and amazed my sight.
    +I think, but dare not speak.
    +
    + +Gentlewoman +
    +Good night, good doctor.
    +

    Exeunt

    +
    +

    SCENE II. The country near Dunsinane.

    +

    +Drum and colours. Enter MENTEITH, CAITHNESS, ANGUS, LENNOX, and Soldiers +
    + +MENTEITH +
    +The English power is near, led on by Malcolm,
    +His uncle Siward and the good Macduff:
    +Revenges burn in them; for their dear causes
    +Would to the bleeding and the grim alarm
    +Excite the mortified man.
    +
    + +ANGUS +
    +Near Birnam wood
    +Shall we well meet them; that way are they coming.
    +
    + +CAITHNESS +
    +Who knows if Donalbain be with his brother?
    +
    + +LENNOX +
    +For certain, sir, he is not: I have a file
    +Of all the gentry: there is Siward's son,
    +And many unrough youths that even now
    +Protest their first of manhood.
    +
    + +MENTEITH +
    +What does the tyrant?
    +
    + +CAITHNESS +
    +Great Dunsinane he strongly fortifies:
    +Some say he's mad; others that lesser hate him
    +Do call it valiant fury: but, for certain,
    +He cannot buckle his distemper'd cause
    +Within the belt of rule.
    +
    + +ANGUS +
    +Now does he feel
    +His secret murders sticking on his hands;
    +Now minutely revolts upbraid his faith-breach;
    +Those he commands move only in command,
    +Nothing in love: now does he feel his title
    +Hang loose about him, like a giant's robe
    +Upon a dwarfish thief.
    +
    + +MENTEITH +
    +Who then shall blame
    +His pester'd senses to recoil and start,
    +When all that is within him does condemn
    +Itself for being there?
    +
    + +CAITHNESS +
    +Well, march we on,
    +To give obedience where 'tis truly owed:
    +Meet we the medicine of the sickly weal,
    +And with him pour we in our country's purge
    +Each drop of us.
    +
    + +LENNOX +
    + Or so much as it needs,
    +To dew the sovereign flower and drown the weeds.
    +Make we our march towards Birnam.
    +

    Exeunt, marching

    +
    +

    SCENE III. Dunsinane. A room in the castle.

    +

    +Enter MACBETH, Doctor, and Attendants +
    + +MACBETH +
    +Bring me no more reports; let them fly all:
    +Till Birnam wood remove to Dunsinane,
    +I cannot taint with fear. What's the boy Malcolm?
    +Was he not born of woman? The spirits that know
    +All mortal consequences have pronounced me thus:
    +'Fear not, Macbeth; no man that's born of woman
    +Shall e'er have power upon thee.' Then fly,
    +false thanes,
    +And mingle with the English epicures:
    +The mind I sway by and the heart I bear
    +Shall never sag with doubt nor shake with fear.
    +

    Enter a Servant

    +The devil damn thee black, thou cream-faced loon!
    +Where got'st thou that goose look?
    +
    + +Servant +
    +There is ten thousand--
    +
    + +MACBETH +
    +Geese, villain!
    +
    + +Servant +
    +Soldiers, sir.
    +
    + +MACBETH +
    +Go prick thy face, and over-red thy fear,
    +Thou lily-liver'd boy. What soldiers, patch?
    +Death of thy soul! those linen cheeks of thine
    +Are counsellors to fear. What soldiers, whey-face?
    +
    + +Servant +
    +The English force, so please you.
    +
    + +MACBETH +
    +Take thy face hence.
    +

    Exit Servant

    +Seyton!--I am sick at heart,
    +When I behold--Seyton, I say!--This push
    +Will cheer me ever, or disseat me now.
    +I have lived long enough: my way of life
    +Is fall'n into the sear, the yellow leaf;
    +And that which should accompany old age,
    +As honour, love, obedience, troops of friends,
    +I must not look to have; but, in their stead,
    +Curses, not loud but deep, mouth-honour, breath,
    +Which the poor heart would fain deny, and dare not. Seyton!
    +

    Enter SEYTON

    +
    + +SEYTON +
    +What is your gracious pleasure?
    +
    + +MACBETH +
    +What news more?
    +
    + +SEYTON +
    +All is confirm'd, my lord, which was reported.
    +
    + +MACBETH +
    +I'll fight till from my bones my flesh be hack'd.
    +Give me my armour.
    +
    + +SEYTON +
    +'Tis not needed yet.
    +
    + +MACBETH +
    +I'll put it on.
    +Send out more horses; skirr the country round;
    +Hang those that talk of fear. Give me mine armour.
    +How does your patient, doctor?
    +
    + +Doctor +
    +Not so sick, my lord,
    +As she is troubled with thick coming fancies,
    +That keep her from her rest.
    +
    + +MACBETH +
    +Cure her of that.
    +Canst thou not minister to a mind diseased,
    +Pluck from the memory a rooted sorrow,
    +Raze out the written troubles of the brain
    +And with some sweet oblivious antidote
    +Cleanse the stuff'd bosom of that perilous stuff
    +Which weighs upon the heart?
    +
    + +Doctor +
    +Therein the patient
    +Must minister to himself.
    +
    + +MACBETH +
    +Throw physic to the dogs; I'll none of it.
    +Come, put mine armour on; give me my staff.
    +Seyton, send out. Doctor, the thanes fly from me.
    +Come, sir, dispatch. If thou couldst, doctor, cast
    +The water of my land, find her disease,
    +And purge it to a sound and pristine health,
    +I would applaud thee to the very echo,
    +That should applaud again.--Pull't off, I say.--
    +What rhubarb, cyme, or what purgative drug,
    +Would scour these English hence? Hear'st thou of them?
    +
    + +Doctor +
    +Ay, my good lord; your royal preparation
    +Makes us hear something.
    +
    + +MACBETH +
    +Bring it after me.
    +I will not be afraid of death and bane,
    +Till Birnam forest come to Dunsinane.
    +
    + +Doctor +
    +[Aside] Were I from Dunsinane away and clear,
    +Profit again should hardly draw me here.
    +

    Exeunt

    +
    +

    SCENE IV. Country near Birnam wood.

    +

    +Drum and colours. Enter MALCOLM, SIWARD and YOUNG SIWARD, MACDUFF, MENTEITH, CAITHNESS, ANGUS, LENNOX, ROSS, and Soldiers, marching +
    + +MALCOLM +
    +Cousins, I hope the days are near at hand
    +That chambers will be safe.
    +
    + +MENTEITH +
    +We doubt it nothing.
    +
    + +SIWARD +
    +What wood is this before us?
    +
    + +MENTEITH +
    +The wood of Birnam.
    +
    + +MALCOLM +
    +Let every soldier hew him down a bough
    +And bear't before him: thereby shall we shadow
    +The numbers of our host and make discovery
    +Err in report of us.
    +
    + +Soldiers +
    +It shall be done.
    +
    + +SIWARD +
    +We learn no other but the confident tyrant
    +Keeps still in Dunsinane, and will endure
    +Our setting down before 't.
    +
    + +MALCOLM +
    +'Tis his main hope:
    +For where there is advantage to be given,
    +Both more and less have given him the revolt,
    +And none serve with him but constrained things
    +Whose hearts are absent too.
    +
    + +MACDUFF +
    +Let our just censures
    +Attend the true event, and put we on
    +Industrious soldiership.
    +
    + +SIWARD +
    +The time approaches
    +That will with due decision make us know
    +What we shall say we have and what we owe.
    +Thoughts speculative their unsure hopes relate,
    +But certain issue strokes must arbitrate:
    +Towards which advance the war.
    +

    Exeunt, marching

    +
    +

    SCENE V. Dunsinane. Within the castle.

    +

    +Enter MACBETH, SEYTON, and Soldiers, with drum and colours +
    + +MACBETH +
    +Hang out our banners on the outward walls;
    +The cry is still 'They come:' our castle's strength
    +Will laugh a siege to scorn: here let them lie
    +Till famine and the ague eat them up:
    +Were they not forced with those that should be ours,
    +We might have met them dareful, beard to beard,
    +And beat them backward home.
    +

    A cry of women within

    +What is that noise?
    +
    + +SEYTON +
    +It is the cry of women, my good lord.
    +

    Exit

    +
    + +MACBETH +
    +I have almost forgot the taste of fears;
    +The time has been, my senses would have cool'd
    +To hear a night-shriek; and my fell of hair
    +Would at a dismal treatise rouse and stir
    +As life were in't: I have supp'd full with horrors;
    +Direness, familiar to my slaughterous thoughts
    +Cannot once start me.
    +

    Re-enter SEYTON

    +Wherefore was that cry?
    +
    + +SEYTON +
    +The queen, my lord, is dead.
    +
    + +MACBETH +
    +She should have died hereafter;
    +There would have been a time for such a word.
    +To-morrow, and to-morrow, and to-morrow,
    +Creeps in this petty pace from day to day
    +To the last syllable of recorded time,
    +And all our yesterdays have lighted fools
    +The way to dusty death. Out, out, brief candle!
    +Life's but a walking shadow, a poor player
    +That struts and frets his hour upon the stage
    +And then is heard no more: it is a tale
    +Told by an idiot, full of sound and fury,
    +Signifying nothing.
    +

    Enter a Messenger

    +Thou comest to use thy tongue; thy story quickly.
    +
    + +Messenger +
    +Gracious my lord,
    +I should report that which I say I saw,
    +But know not how to do it.
    +
    + +MACBETH +
    +Well, say, sir.
    +
    + +Messenger +
    +As I did stand my watch upon the hill,
    +I look'd toward Birnam, and anon, methought,
    +The wood began to move.
    +
    + +MACBETH +
    +Liar and slave!
    +
    + +Messenger +
    +Let me endure your wrath, if't be not so:
    +Within this three mile may you see it coming;
    +I say, a moving grove.
    +
    + +MACBETH +
    +If thou speak'st false,
    +Upon the next tree shalt thou hang alive,
    +Till famine cling thee: if thy speech be sooth,
    +I care not if thou dost for me as much.
    +I pull in resolution, and begin
    +To doubt the equivocation of the fiend
    +That lies like truth: 'Fear not, till Birnam wood
    +Do come to Dunsinane:' and now a wood
    +Comes toward Dunsinane. Arm, arm, and out!
    +If this which he avouches does appear,
    +There is nor flying hence nor tarrying here.
    +I gin to be aweary of the sun,
    +And wish the estate o' the world were now undone.
    +Ring the alarum-bell! Blow, wind! come, wrack!
    +At least we'll die with harness on our back.
    +

    Exeunt

    +
    +

    SCENE VI. Dunsinane. Before the castle.

    +

    +Drum and colours. Enter MALCOLM, SIWARD, MACDUFF, and their Army, with boughs +
    + +MALCOLM +
    +Now near enough: your leafy screens throw down.
    +And show like those you are. You, worthy uncle,
    +Shall, with my cousin, your right-noble son,
    +Lead our first battle: worthy Macduff and we
    +Shall take upon 's what else remains to do,
    +According to our order.
    +
    + +SIWARD +
    +Fare you well.
    +Do we but find the tyrant's power to-night,
    +Let us be beaten, if we cannot fight.
    +
    + +MACDUFF +
    +Make all our trumpets speak; give them all breath,
    +Those clamorous harbingers of blood and death.
    +

    Exeunt

    +
    +

    SCENE VII. Another part of the field.

    +

    +Alarums. Enter MACBETH +
    + +MACBETH +
    +They have tied me to a stake; I cannot fly,
    +But, bear-like, I must fight the course. What's he
    +That was not born of woman? Such a one
    +Am I to fear, or none.
    +

    Enter YOUNG SIWARD

    +
    + +YOUNG SIWARD +
    +What is thy name?
    +
    + +MACBETH +
    + Thou'lt be afraid to hear it.
    +
    + +YOUNG SIWARD +
    +No; though thou call'st thyself a hotter name
    +Than any is in hell.
    +
    + +MACBETH +
    +My name's Macbeth.
    +
    + +YOUNG SIWARD +
    +The devil himself could not pronounce a title
    +More hateful to mine ear.
    +
    + +MACBETH +
    +No, nor more fearful.
    +
    + +YOUNG SIWARD +
    +Thou liest, abhorred tyrant; with my sword
    +I'll prove the lie thou speak'st.
    +

    They fight and YOUNG SIWARD is slain

    +
    + +MACBETH +
    +Thou wast born of woman
    +But swords I smile at, weapons laugh to scorn,
    +Brandish'd by man that's of a woman born.
    +

    Exit

    +

    Alarums. Enter MACDUFF

    +
    + +MACDUFF +
    +That way the noise is. Tyrant, show thy face!
    +If thou be'st slain and with no stroke of mine,
    +My wife and children's ghosts will haunt me still.
    +I cannot strike at wretched kerns, whose arms
    +Are hired to bear their staves: either thou, Macbeth,
    +Or else my sword with an unbatter'd edge
    +I sheathe again undeeded. There thou shouldst be;
    +By this great clatter, one of greatest note
    +Seems bruited. Let me find him, fortune!
    +And more I beg not.
    +

    Exit. Alarums

    +

    Enter MALCOLM and SIWARD

    +
    + +SIWARD +
    +This way, my lord; the castle's gently render'd:
    +The tyrant's people on both sides do fight;
    +The noble thanes do bravely in the war;
    +The day almost itself professes yours,
    +And little is to do.
    +
    + +MALCOLM +
    +We have met with foes
    +That strike beside us.
    +
    + +SIWARD +
    +Enter, sir, the castle.
    +

    Exeunt. Alarums

    +
    +

    SCENE VIII. Another part of the field.

    +

    +Enter MACBETH +
    + +MACBETH +
    +Why should I play the Roman fool, and die
    +On mine own sword? whiles I see lives, the gashes
    +Do better upon them.
    +

    Enter MACDUFF

    +
    + +MACDUFF +
    +Turn, hell-hound, turn!
    +
    + +MACBETH +
    +Of all men else I have avoided thee:
    +But get thee back; my soul is too much charged
    +With blood of thine already.
    +
    + +MACDUFF +
    +I have no words:
    +My voice is in my sword: thou bloodier villain
    +Than terms can give thee out!
    +

    They fight

    +
    + +MACBETH +
    +Thou losest labour:
    +As easy mayst thou the intrenchant air
    +With thy keen sword impress as make me bleed:
    +Let fall thy blade on vulnerable crests;
    +I bear a charmed life, which must not yield,
    +To one of woman born.
    +
    + +MACDUFF +
    +Despair thy charm;
    +And let the angel whom thou still hast served
    +Tell thee, Macduff was from his mother's womb
    +Untimely ripp'd.
    +
    + +MACBETH +
    +Accursed be that tongue that tells me so,
    +For it hath cow'd my better part of man!
    +And be these juggling fiends no more believed,
    +That palter with us in a double sense;
    +That keep the word of promise to our ear,
    +And break it to our hope. I'll not fight with thee.
    +
    + +MACDUFF +
    +Then yield thee, coward,
    +And live to be the show and gaze o' the time:
    +We'll have thee, as our rarer monsters are,
    +Painted on a pole, and underwrit,
    +'Here may you see the tyrant.'
    +
    + +MACBETH +
    +I will not yield,
    +To kiss the ground before young Malcolm's feet,
    +And to be baited with the rabble's curse.
    +Though Birnam wood be come to Dunsinane,
    +And thou opposed, being of no woman born,
    +Yet I will try the last. Before my body
    +I throw my warlike shield. Lay on, Macduff,
    +And damn'd be him that first cries, 'Hold, enough!'
    +

    Exeunt, fighting. Alarums

    +

    Retreat. Flourish. Enter, with drum and colours, MALCOLM, SIWARD, ROSS, the other Thanes, and Soldiers

    +
    + +MALCOLM +
    +I would the friends we miss were safe arrived.
    +
    + +SIWARD +
    +Some must go off: and yet, by these I see,
    +So great a day as this is cheaply bought.
    +
    + +MALCOLM +
    +Macduff is missing, and your noble son.
    +
    + +ROSS +
    +Your son, my lord, has paid a soldier's debt:
    +He only lived but till he was a man;
    +The which no sooner had his prowess confirm'd
    +In the unshrinking station where he fought,
    +But like a man he died.
    +
    + +SIWARD +
    +Then he is dead?
    +
    + +ROSS +
    +Ay, and brought off the field: your cause of sorrow
    +Must not be measured by his worth, for then
    +It hath no end.
    +
    + +SIWARD +
    + Had he his hurts before?
    +
    + +ROSS +
    +Ay, on the front.
    +
    + +SIWARD +
    + Why then, God's soldier be he!
    +Had I as many sons as I have hairs,
    +I would not wish them to a fairer death:
    +And so, his knell is knoll'd.
    +
    + +MALCOLM +
    +He's worth more sorrow,
    +And that I'll spend for him.
    +
    + +SIWARD +
    +He's worth no more
    +They say he parted well, and paid his score:
    +And so, God be with him! Here comes newer comfort.
    +

    Re-enter MACDUFF, with MACBETH's head

    +
    + +MACDUFF +
    +Hail, king! for so thou art: behold, where stands
    +The usurper's cursed head: the time is free:
    +I see thee compass'd with thy kingdom's pearl,
    +That speak my salutation in their minds;
    +Whose voices I desire aloud with mine:
    +Hail, King of Scotland!
    +
    + +ALL +
    +Hail, King of Scotland!
    +

    Flourish

    +
    + +MALCOLM +
    +We shall not spend a large expense of time
    +Before we reckon with your several loves,
    +And make us even with you. My thanes and kinsmen,
    +Henceforth be earls, the first that ever Scotland
    +In such an honour named. What's more to do,
    +Which would be planted newly with the time,
    +As calling home our exiled friends abroad
    +That fled the snares of watchful tyranny;
    +Producing forth the cruel ministers
    +Of this dead butcher and his fiend-like queen,
    +Who, as 'tis thought, by self and violent hands
    +Took off her life; this, and what needful else
    +That calls upon us, by the grace of Grace,
    +We will perform in measure, time and place:
    +So, thanks to all at once and to each one,
    +Whom we invite to see us crown'd at Scone.
    +

    Flourish. Exeunt

    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/map.png b/www/node_modules/selenium-webdriver/lib/test/data/map.png new file mode 100644 index 0000000..763f562 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/map.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/map_visibility.html b/www/node_modules/selenium-webdriver/lib/test/data/map_visibility.html new file mode 100644 index 0000000..6cf5f76 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/map_visibility.html @@ -0,0 +1,8 @@ + + + Map test page + + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/markerTransparent.png b/www/node_modules/selenium-webdriver/lib/test/data/markerTransparent.png new file mode 100644 index 0000000..ed4e5e7 Binary files /dev/null and b/www/node_modules/selenium-webdriver/lib/test/data/markerTransparent.png differ diff --git a/www/node_modules/selenium-webdriver/lib/test/data/messages.html b/www/node_modules/selenium-webdriver/lib/test/data/messages.html new file mode 100644 index 0000000..74f1a37 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/messages.html @@ -0,0 +1,15 @@ + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/meta-redirect.html b/www/node_modules/selenium-webdriver/lib/test/data/meta-redirect.html new file mode 100644 index 0000000..9d9c2f0 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/meta-redirect.html @@ -0,0 +1,11 @@ + + + Some test page + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/missedJsReference.html b/www/node_modules/selenium-webdriver/lib/test/data/missedJsReference.html new file mode 100644 index 0000000..6167752 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/missedJsReference.html @@ -0,0 +1,11 @@ + + + + Example page + + +

    This page contains a nested iframe. Execute some JS to locate a reference to an element in this + frame and return it. You should need to switch to that frame in order to use that element.

    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_1.html b/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_1.html new file mode 100644 index 0000000..4eff01a --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_1.html @@ -0,0 +1,21 @@ + + +First Modal + + + + +

    Modal dialog sample

    + + + +lnk2 +
    + +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_2.html b/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_2.html new file mode 100644 index 0000000..cec3f3f --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_2.html @@ -0,0 +1,21 @@ + + +Second Modal + + + + +

    Modal dialog sample

    + + + +lnk3 +
    + +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_3.html b/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_3.html new file mode 100644 index 0000000..6c5eb72 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modal_3.html @@ -0,0 +1,15 @@ + + +Third Modal + + + + +

    Modal dialog sample

    + + +
    + +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modalindex.html b/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modalindex.html new file mode 100644 index 0000000..0a1c4c9 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/modal_dialogs/modalindex.html @@ -0,0 +1,21 @@ + + +Main window + + + + +

    Modal dialog sample

    + + + +lnk1 +
    + +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/mouseOver.html b/www/node_modules/selenium-webdriver/lib/test/data/mouseOver.html new file mode 100644 index 0000000..d4751bf --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/mouseOver.html @@ -0,0 +1,17 @@ + + +
    +
    +
    + +
    diff --git a/www/node_modules/selenium-webdriver/lib/test/data/mousePositionTracker.html b/www/node_modules/selenium-webdriver/lib/test/data/mousePositionTracker.html new file mode 100644 index 0000000..39a31cd --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/mousePositionTracker.html @@ -0,0 +1,33 @@ + + + + + + + + + Div tracking mouse position. +
    +
    + Move mouse here. +
    +

    +0, 0 +

    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/nestedElements.html b/www/node_modules/selenium-webdriver/lib/test/data/nestedElements.html new file mode 100644 index 0000000..cf00083 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/nestedElements.html @@ -0,0 +1,155 @@ + + +

    outside

    +

    outside

    +
    +

    inside

    +
    + + Here's a checkbox:
    + + + +
    + Here's a checkbox:
    + + +
    + +hello world + + + + + + +
    + Here's a checkbox:
    + +
    + +
    + Here's a checkbox:
    + + +
    + +hello world + + + + + + +
    + Here's a checkbox:
    + +
    + +
    + Here's a checkbox:
    + + +
    + +hello world + + + + + + +
    + Here's a checkbox:
    + +
    + +
    + Here's a checkbox:
    + + +
    + +hello world + + +Span with class of one +
    + Find me + Also me + But not me +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/overflow-body.html b/www/node_modules/selenium-webdriver/lib/test/data/overflow-body.html new file mode 100644 index 0000000..2d2264c --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/overflow-body.html @@ -0,0 +1,15 @@ + + + + The Visibility of Everyday Things + + + +

    This image is copyright Simon Stewart and donated to the Selenium project for use in its test suites. +

    +a nice beach + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_auto.html b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_auto.html new file mode 100644 index 0000000..cf8a647 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_hidden.html b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_hidden.html new file mode 100644 index 0000000..96fd750 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_scroll.html b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_scroll.html new file mode 100644 index 0000000..6f1d90b --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_auto_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_auto.html b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_auto.html new file mode 100644 index 0000000..24dd192 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_hidden.html b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_hidden.html new file mode 100644 index 0000000..cae5665 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_scroll.html b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_scroll.html new file mode 100644 index 0000000..d4ffa39 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_hidden_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_auto.html b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_auto.html new file mode 100644 index 0000000..d425a2a --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_auto.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_hidden.html b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_hidden.html new file mode 100644 index 0000000..4a6ff59 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_hidden.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_scroll.html b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_scroll.html new file mode 100644 index 0000000..efa8074 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/overflow/x_scroll_y_scroll.html @@ -0,0 +1,30 @@ + + + + Page with overflow + + + +
    + +
    + Right clicked:
    + Bottom clicked:
    + Bottom-right clicked:
    +
    + + Click bottom +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnBeforeUnloadMessage.html b/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnBeforeUnloadMessage.html new file mode 100644 index 0000000..cb59707 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnBeforeUnloadMessage.html @@ -0,0 +1,20 @@ + + + + + + Page with OnBeforeUnload handler + + +

    Page with onbeforeunload event handler. Click here to navigate to another page.

    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnLoad.html b/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnLoad.html new file mode 100644 index 0000000..2c644ff --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnLoad.html @@ -0,0 +1,6 @@ + + + +

    Page with onload event handler

    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnUnload.html b/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnUnload.html new file mode 100644 index 0000000..6070341 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/pageWithOnUnload.html @@ -0,0 +1,6 @@ + + + +

    Page with onunload event handler

    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/page_with_link_to_slow_loading_page.html b/www/node_modules/selenium-webdriver/lib/test/data/page_with_link_to_slow_loading_page.html new file mode 100644 index 0000000..ea94f8e --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/page_with_link_to_slow_loading_page.html @@ -0,0 +1,6 @@ + + + +load a slow page + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/plain.txt b/www/node_modules/selenium-webdriver/lib/test/data/plain.txt new file mode 100644 index 0000000..8318c86 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/plain.txt @@ -0,0 +1 @@ +Test \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/proxy/page1.html b/www/node_modules/selenium-webdriver/lib/test/data/proxy/page1.html new file mode 100644 index 0000000..1810f1c --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/proxy/page1.html @@ -0,0 +1,20 @@ + + + +Page 1 +

    The next query param must be the URL for the next page to +link to. + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/proxy/page2.html b/www/node_modules/selenium-webdriver/lib/test/data/proxy/page2.html new file mode 100644 index 0000000..d826f17 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/proxy/page2.html @@ -0,0 +1,24 @@ + + + +Page 2 +This page is a middle man for referrer tests. +This page will include a link to a "next" page if the next query +parameter, or the document.referrer is set. +

    + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/proxy/page3.html b/www/node_modules/selenium-webdriver/lib/test/data/proxy/page3.html new file mode 100644 index 0000000..27048f7 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/proxy/page3.html @@ -0,0 +1,5 @@ + + + +Page 3 +

    diff --git a/www/node_modules/selenium-webdriver/lib/test/data/readOnlyPage.html b/www/node_modules/selenium-webdriver/lib/test/data/readOnlyPage.html new file mode 100644 index 0000000..8f257fd --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/readOnlyPage.html @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + +

    This

    is a

    contentEditable area

    + +
    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/rectangles.html b/www/node_modules/selenium-webdriver/lib/test/data/rectangles.html new file mode 100644 index 0000000..8ba2339 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/rectangles.html @@ -0,0 +1,40 @@ + + + + Rectangles + + + +
    r1
    +
    r2
    +
    r3
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/resultPage.html b/www/node_modules/selenium-webdriver/lib/test/data/resultPage.html new file mode 100644 index 0000000..94f3e24 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/resultPage.html @@ -0,0 +1,25 @@ + + + We Arrive Here + + + +

    Success!

    + +
    +

    List of stuff

    +
      +
    1. Item 1
    2. +
    3. Item 2
    4. +
    +
    +
    +

    Almost empty

    +
    + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/rich_text.html b/www/node_modules/selenium-webdriver/lib/test/data/rich_text.html new file mode 100644 index 0000000..a42e43a --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/rich_text.html @@ -0,0 +1,161 @@ + + + + + + +
    +
    +
    + + + + + +
    +
    IFRAME
    + +
    +
    frame.contentWindow.document.designMode: on
    frame.contentWindow.document.body.contentEditable: false
    +
    +
    DIV
    +
    +
    +
    +
    div.ownerDocument.designMode: off
    div.ownerDocument.body.contentEditable: false
    div.contentEditable: true
    +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + + +
    type:[]
    tagName:[]
    id:[]
    keyIdentifier:[]
    keyLocation:[]
    keyCode:[]
    charCode:[]
    which:[]
    isTrusted:[]
    ---------------------
    Modifiers
    alt:[]
    ctrl:[]
    shift:[]
    meta:[]
    +
    + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/safari/frames_benchmark.html b/www/node_modules/selenium-webdriver/lib/test/data/safari/frames_benchmark.html new file mode 100644 index 0000000..8a05925 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/safari/frames_benchmark.html @@ -0,0 +1,31 @@ + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.css b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.css new file mode 100644 index 0000000..8152618 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.css @@ -0,0 +1,19 @@ +* { + margin: 0; +} +html, body, #output { + width: 100%; + height: 100%; +} +table { + border: 0px; + border-collapse: collapse; + border-spacing: 0px; + display: table; +} +table td { + padding: 0px; +} +.cell { + color: black; +} diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.html b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.html new file mode 100644 index 0000000..166665d --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.js b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.js new file mode 100644 index 0000000..1d16859 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen.js @@ -0,0 +1,7 @@ +function toColor(num) { + num >>>= 0; + var b = num & 0xFF, + g = (num & 0xFF00) >>> 8, + r = (num & 0xFF0000) >>> 16; + return "rgb(" + [r, g, b].join(",") + ")"; +} \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame1.html b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame1.html new file mode 100644 index 0000000..35b03ae --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame1.html @@ -0,0 +1,72 @@ + + +screen frame1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame2.html b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame2.html new file mode 100644 index 0000000..e6e17e6 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frame2.html @@ -0,0 +1,72 @@ + + +screen frame2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frames.html b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frames.html new file mode 100644 index 0000000..46852dc --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_frames.html @@ -0,0 +1,11 @@ + + + screen test + + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_iframes.html b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_iframes.html new file mode 100644 index 0000000..ae3ea1e --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_iframes.html @@ -0,0 +1,12 @@ + + +Screen test + + +
    + + + +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_too_long.html b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_too_long.html new file mode 100644 index 0000000..4d00f02 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_too_long.html @@ -0,0 +1,68 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_long.html b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_long.html new file mode 100644 index 0000000..1a6a100 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_too_long.html b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_too_long.html new file mode 100644 index 0000000..3fee005 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_x_too_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_long.html b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_long.html new file mode 100644 index 0000000..31733e0 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_too_long.html b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_too_long.html new file mode 100644 index 0000000..dbef936 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/screen/screen_y_too_long.html @@ -0,0 +1,72 @@ + + +screen test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
         
         
         
         
         
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scroll.html b/www/node_modules/selenium-webdriver/lib/test/data/scroll.html new file mode 100644 index 0000000..cd5214f --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scroll.html @@ -0,0 +1,27 @@ + + + + + +
    +
      +
    • line1
    • +
    • line2
    • +
    • line3
    • +
    • line4
    • +
    • line5
    • +
    • line6
    • +
    • line7
    • +
    • line8
    • +
    • line9
    • +
    +
    +Clicked: +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scroll2.html b/www/node_modules/selenium-webdriver/lib/test/data/scroll2.html new file mode 100644 index 0000000..0ea66d3 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scroll2.html @@ -0,0 +1,21 @@ + + + + +
      +
    • +
    • +
    • Text
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scroll3.html b/www/node_modules/selenium-webdriver/lib/test/data/scroll3.html new file mode 100644 index 0000000..1aa1709 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scroll3.html @@ -0,0 +1,8 @@ + + +



























































































































































    + +



    + +                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 +
























































































































































    \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scroll4.html b/www/node_modules/selenium-webdriver/lib/test/data/scroll4.html new file mode 100644 index 0000000..652a778 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scroll4.html @@ -0,0 +1,7 @@ + + +


































































































    + +


































































































    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scroll5.html b/www/node_modules/selenium-webdriver/lib/test/data/scroll5.html new file mode 100644 index 0000000..b345a8c --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scroll5.html @@ -0,0 +1,18 @@ + + + + + +
    +
    +
    +
    +
    +Clicked: +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_200.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_200.html new file mode 100644 index 0000000..3eb3bf4 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_200.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

    This is a scrolling frame test

    +
    + + + + + + + + + + + + + +
    First row
    Second row
    Third row
    Fourth row
    +
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_2000.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_2000.html new file mode 100644 index 0000000..61ffe85 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_height_above_2000.html @@ -0,0 +1,26 @@ + + + + Child frame + + +

    This is a tall frame test

    +
    + + + + + + + + + + + + + +
    First row
    Second row
    Third row
    Fourth row
    +
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame.html new file mode 100644 index 0000000..1530138 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html new file mode 100644 index 0000000..5781aeb --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
    Placeholder
    +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_small_height.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_small_height.html new file mode 100644 index 0000000..047de0f --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/frame_with_small_height.html @@ -0,0 +1,10 @@ + + + + Child frame + + +

    This is a non-scrolling frame test

    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_double_overflow_auto.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_double_overflow_auto.html new file mode 100644 index 0000000..01b7c30 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_double_overflow_auto.html @@ -0,0 +1,19 @@ + + + + Page with overflow: auto + + + +
    Placeholder
    +
    + Click me! +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_frame_out_of_view.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_frame_out_of_view.html new file mode 100644 index 0000000..c536e41 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
    Placeholder
    +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames.html new file mode 100644 index 0000000..e5b7602 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html new file mode 100644 index 0000000..f79f7c8 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_nested_scrolling_frames_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
    Placeholder
    +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_non_scrolling_frame.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_non_scrolling_frame.html new file mode 100644 index 0000000..0a493fa --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_non_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame.html new file mode 100644 index 0000000..cb5d53a --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame_out_of_view.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame_out_of_view.html new file mode 100644 index 0000000..5df1115 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_scrolling_frame_out_of_view.html @@ -0,0 +1,12 @@ + + + + Welcome Page + + +
    Placeholder
    +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_tall_frame.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_tall_frame.html new file mode 100644 index 0000000..b7cfaf5 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_tall_frame.html @@ -0,0 +1,11 @@ + + + + Welcome Page + + +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_y_overflow_auto.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_y_overflow_auto.html new file mode 100644 index 0000000..b5716e7 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/page_with_y_overflow_auto.html @@ -0,0 +1,14 @@ + + + + Page with overflow: auto + + +
    +
    Placeholder
    +
    + Click me! +
    +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/target_page.html b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/target_page.html new file mode 100644 index 0000000..0457a82 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/scrolling_tests/target_page.html @@ -0,0 +1,9 @@ + + + +Clicked Successfully! + + +

    Clicked Successfully!

    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/selectPage.html b/www/node_modules/selenium-webdriver/lib/test/data/selectPage.html new file mode 100644 index 0000000..4028414 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/selectPage.html @@ -0,0 +1,58 @@ + + + + +Multiple Selection test page + + + + + + + + + + + + + + + + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/selectableItems.html b/www/node_modules/selenium-webdriver/lib/test/data/selectableItems.html new file mode 100644 index 0000000..190b2ad --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/selectableItems.html @@ -0,0 +1,65 @@ + + + + + jQuery UI Selectable - Default functionality + + + + + + + + +
    + +
      +
    1. Item 1
    2. +
    3. Item 2
    4. +
    5. Item 3
    6. +
    7. Item 4
    8. +
    9. Item 5
    10. +
    11. Item 6
    12. +
    13. Item 7
    14. +
    + +
    + +
    + +

    Enable a DOM element (or group of elements) to be selectable. Draw a box with your cursor to select items. Hold down the Ctrl key to make multiple non-adjacent selections.

    + + + +
    +

    no info

    +
    + + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/sessionCookie.html b/www/node_modules/selenium-webdriver/lib/test/data/sessionCookie.html new file mode 100644 index 0000000..0ada24e --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/sessionCookie.html @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/sessionCookieDest.html b/www/node_modules/selenium-webdriver/lib/test/data/sessionCookieDest.html new file mode 100644 index 0000000..f5e2ef2 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/sessionCookieDest.html @@ -0,0 +1,34 @@ + + + + + Session cookie destination + + + +This is the cookie destination page. + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/simple.xml b/www/node_modules/selenium-webdriver/lib/test/data/simple.xml new file mode 100644 index 0000000..01f4c87 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/simple.xml @@ -0,0 +1,5 @@ + + + baz + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/simpleTest.html b/www/node_modules/selenium-webdriver/lib/test/data/simpleTest.html new file mode 100644 index 0000000..38210b9 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/simpleTest.html @@ -0,0 +1,98 @@ + + + Hello WebDriver + + +

    Heading

    + +

    A single line of text

    + + +
    +

    A div containing

    + More than one line of text
    + +
    and block level elements
    +
    + +An inline element + +

    This line has lots + + of spaces. +

    + +

    This line has a non-breaking space

    + +

    This line has a   non-breaking space and spaces

    + +

    These lines  
      have leading and trailing NBSPs  

    + +

    This line has text within elements that are meant to be displayed + inline

    + +
    +

    before pre

    +
       This section has a preformatted
    +    text block    
    +  split in four lines
    +         
    +

    after pre

    +
    + +

    Some text

    Some more text

    + +
    Cheese

    Some text

    Some more text

    and also

    Brie
    + +
    Hello, world
    + +
    + +
    + +
    +

    + + +

    +
    + + + + + +
    Top level
    +
    +
    Nested
    +
    + + + + + +
    beforeSpace afterSpace
    + + + + + +a link to an icon + +{a="b", c=1, d=true} +{a="\\b\\\"'\'"} + +  â€â€‚        ​‌â€â€¯âŸâ ã€€test  â€â€‚        ​‌â€â€¯âŸâ ã€€ + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingAlert.html b/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingAlert.html new file mode 100644 index 0000000..a6216e3 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingAlert.html @@ -0,0 +1,10 @@ + + + +slowLoadingAlert + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingResourcePage.html b/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingResourcePage.html new file mode 100644 index 0000000..02796c3 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/slowLoadingResourcePage.html @@ -0,0 +1,12 @@ + + + This page loads something slowly + + +

    Simulate the situation where a web-bug or analytics script takes waaay + too long to respond. Normally these things are loaded in an iframe, which is + what we're doing here.

    + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/slow_loading_iframes.html b/www/node_modules/selenium-webdriver/lib/test/data/slow_loading_iframes.html new file mode 100644 index 0000000..d007248 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/slow_loading_iframes.html @@ -0,0 +1,14 @@ + + + + Page with slow loading iFrames + + + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/styledPage.html b/www/node_modules/selenium-webdriver/lib/test/data/styledPage.html new file mode 100644 index 0000000..30810f0 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/styledPage.html @@ -0,0 +1,28 @@ + + + + Styled Page + + + + +
    + +
    + + +
    + +
    + +
    Content
    + + + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/svgPiechart.xhtml b/www/node_modules/selenium-webdriver/lib/test/data/svgPiechart.xhtml new file mode 100644 index 0000000..bf060fd --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/svgPiechart.xhtml @@ -0,0 +1,81 @@ + + + + + Pie Chart Test + + + +
    + Some text for the chart. +
    +
    Nothing.
    +
    + + + + + Test Chart + + + Apple + + Orange + + Banana + + Orange + + + + + + + + Example RotateScale - Rotate and scale transforms + + + + + + + + + + + + + + ABC (rotate) + + + + + + + + + + + + ABC (scale) + + + + +
    WOrange
    +
    +
    WOrange
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/svgTest.svg b/www/node_modules/selenium-webdriver/lib/test/data/svgTest.svg new file mode 100644 index 0000000..c6cc283 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/svgTest.svg @@ -0,0 +1,4 @@ + + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/tables.html b/www/node_modules/selenium-webdriver/lib/test/data/tables.html new file mode 100644 index 0000000..a2bc957 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/tables.html @@ -0,0 +1,36 @@ + + + + Here be tables + + + + + + + + + +
    HelloWorld(Cheese!)
    + + + + + +
    some text +
    some more text
    +
    + + + + + + + + + +
    Heading
    Data 1Data 2
    + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/tinymce.html b/www/node_modules/selenium-webdriver/lib/test/data/tinymce.html new file mode 100644 index 0000000..067b66c --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/tinymce.html @@ -0,0 +1,10 @@ + + + + TinyMCE + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/transformable.xml b/www/node_modules/selenium-webdriver/lib/test/data/transformable.xml new file mode 100644 index 0000000..0b7e7fd --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/transformable.xml @@ -0,0 +1,11 @@ + + + ]> + + +

    Click the button.

    + + Go to another page + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/transformable.xsl b/www/node_modules/selenium-webdriver/lib/test/data/transformable.xsl new file mode 100644 index 0000000..53db9fd --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/transformable.xsl @@ -0,0 +1,37 @@ + + + + + + + +
    + + + + + +
    + + + + + + + + + + + + + + + +
    \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/transparentUpload.html b/www/node_modules/selenium-webdriver/lib/test/data/transparentUpload.html new file mode 100644 index 0000000..87b02bf --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/transparentUpload.html @@ -0,0 +1,70 @@ + + + + Upload Form + + + + +
    +
    +
    + Upload + +
    +
    +
    + + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/underscore.html b/www/node_modules/selenium-webdriver/lib/test/data/underscore.html new file mode 100644 index 0000000..904a444 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/underscore.html @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/unicode_ltr.html b/www/node_modules/selenium-webdriver/lib/test/data/unicode_ltr.html new file mode 100644 index 0000000..245acc7 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/unicode_ltr.html @@ -0,0 +1,8 @@ + + + + + +
    ‎Some notes‎
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/upload.html b/www/node_modules/selenium-webdriver/lib/test/data/upload.html new file mode 100644 index 0000000..aca398a --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/upload.html @@ -0,0 +1,45 @@ + + + + Upload Form + + + +
    +
    + Enter a file to upload: +
    +
    +
    + + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/userDefinedProperty.html b/www/node_modules/selenium-webdriver/lib/test/data/userDefinedProperty.html new file mode 100644 index 0000000..2453e69 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/userDefinedProperty.html @@ -0,0 +1,8 @@ + + +
    + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/veryLargeCanvas.html b/www/node_modules/selenium-webdriver/lib/test/data/veryLargeCanvas.html new file mode 100644 index 0000000..54a2aba --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/veryLargeCanvas.html @@ -0,0 +1,81 @@ + + + + Rectangles + + + + +
    +
    First Target
    +
    Second Target
    +
    Third Target
    +
    Fourth Target
    +
    Not a Target
    +
    Not a Target
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/visibility-css.html b/www/node_modules/selenium-webdriver/lib/test/data/visibility-css.html new file mode 100644 index 0000000..80cc649 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/visibility-css.html @@ -0,0 +1,21 @@ + + + + +Visibility test via CSS + +
    +

    Hello world. I like cheese.

    +
    + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/win32frameset.html b/www/node_modules/selenium-webdriver/lib/test/data/win32frameset.html new file mode 100644 index 0000000..108b80f --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/win32frameset.html @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/page_with_frame.html b/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/page_with_frame.html new file mode 100644 index 0000000..b94733b --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/page_with_frame.html @@ -0,0 +1,12 @@ + + + + Test page for WindowSwitchingTest.testShouldFocusOnTheTopMostFrameAfterSwitchingToAWindow + + +

    Open new window

    +
    + +
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/simple_page.html b/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/simple_page.html new file mode 100644 index 0000000..52c163c --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/window_switching_tests/simple_page.html @@ -0,0 +1,9 @@ + + + + Simple Page + + +
    Simple page with simple test.
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/xhtmlFormPage.xhtml b/www/node_modules/selenium-webdriver/lib/test/data/xhtmlFormPage.xhtml new file mode 100644 index 0000000..aca53d3 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/xhtmlFormPage.xhtml @@ -0,0 +1,17 @@ + + + + XHTML + + + +
    + + +
    + +

    Here is some content that should not be in the previous p tag + + + diff --git a/www/node_modules/selenium-webdriver/lib/test/data/xhtmlTest.html b/www/node_modules/selenium-webdriver/lib/test/data/xhtmlTest.html new file mode 100644 index 0000000..d2f3a5d --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/data/xhtmlTest.html @@ -0,0 +1,76 @@ + + + + XHTML Test Page + + +

    + + + +
    +

    XHTML Might Be The Future

    + +

    If you'd like to go elsewhere then click me.

    + +

    Alternatively, this goes to the same place.

    + +
    + +
    + + This link has the same text as another link: click me. +
    + +
    Another div starts here.

    +

    An H2 title

    +

    Some more text

    +
    + +
    + Foo +
      + +
    + +
    +
    +
    + + +
    +
    +
    + + I have width +
    +
    +
    +
    + + +

    +

    +
    Link=equalssign + +

    Spaced out

    + + +
    first_div
    +
    second_div
    + first_span + second_span +
    + +
    I'm a parent +
    I'm a child
    +
    + +
    Woo woo
    + + diff --git a/www/node_modules/selenium-webdriver/lib/test/fileserver.js b/www/node_modules/selenium-webdriver/lib/test/fileserver.js new file mode 100644 index 0000000..448b0c9 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/fileserver.js @@ -0,0 +1,319 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fs = require('fs'), + http = require('http'), + path = require('path'), + url = require('url'); + +var express = require('express'); +var multer = require('multer'); +var serveIndex = require('serve-index'); + +var Server = require('./httpserver').Server, + resources = require('./resources'), + isDevMode = require('../devmode'), + promise = require('../promise'); + +var WEB_ROOT = '/common'; +var JS_ROOT = '/javascript'; + +var baseDirectory = resources.locate(isDevMode ? 'common/src/web' : '.'); +var jsDirectory = resources.locate(isDevMode ? 'javascript' : '..'); + +var Pages = (function() { + var pages = {}; + function addPage(page, path) { + pages.__defineGetter__(page, function() { + return exports.whereIs(path); + }); + } + + addPage('ajaxyPage', 'ajaxy_page.html'); + addPage('alertsPage', 'alerts.html'); + addPage('bodyTypingPage', 'bodyTypingTest.html'); + addPage('booleanAttributes', 'booleanAttributes.html'); + addPage('childPage', 'child/childPage.html'); + addPage('chinesePage', 'cn-test.html'); + addPage('clickJacker', 'click_jacker.html'); + addPage('clickEventPage', 'clickEventPage.html'); + addPage('clicksPage', 'clicks.html'); + addPage('colorPage', 'colorPage.html'); + addPage('deletingFrame', 'deletingFrame.htm'); + addPage('draggableLists', 'draggableLists.html'); + addPage('dragAndDropPage', 'dragAndDropTest.html'); + addPage('droppableItems', 'droppableItems.html'); + addPage('documentWrite', 'document_write_in_onload.html'); + addPage('dynamicallyModifiedPage', 'dynamicallyModifiedPage.html'); + addPage('dynamicPage', 'dynamic.html'); + addPage('echoPage', 'echo'); + addPage('errorsPage', 'errors.html'); + addPage('xhtmlFormPage', 'xhtmlFormPage.xhtml'); + addPage('formPage', 'formPage.html'); + addPage('formSelectionPage', 'formSelectionPage.html'); + addPage('framesetPage', 'frameset.html'); + addPage('grandchildPage', 'child/grandchild/grandchildPage.html'); + addPage('html5Page', 'html5Page.html'); + addPage('html5OfflinePage', 'html5/offline.html'); + addPage('iframePage', 'iframes.html'); + addPage('javascriptEnhancedForm', 'javascriptEnhancedForm.html'); + addPage('javascriptPage', 'javascriptPage.html'); + addPage('linkedImage', 'linked_image.html'); + addPage('longContentPage', 'longContentPage.html'); + addPage('macbethPage', 'macbeth.html'); + addPage('mapVisibilityPage', 'map_visibility.html'); + addPage('metaRedirectPage', 'meta-redirect.html'); + addPage('missedJsReferencePage', 'missedJsReference.html'); + addPage('mouseTrackerPage', 'mousePositionTracker.html'); + addPage('nestedPage', 'nestedElements.html'); + addPage('readOnlyPage', 'readOnlyPage.html'); + addPage('rectanglesPage', 'rectangles.html'); + addPage('redirectPage', 'redirect'); + addPage('resultPage', 'resultPage.html'); + addPage('richTextPage', 'rich_text.html'); + addPage('selectableItemsPage', 'selectableItems.html'); + addPage('selectPage', 'selectPage.html'); + addPage('simpleTestPage', 'simpleTest.html'); + addPage('simpleXmlDocument', 'simple.xml'); + addPage('sleepingPage', 'sleep'); + addPage('slowIframes', 'slow_loading_iframes.html'); + addPage('slowLoadingAlertPage', 'slowLoadingAlert.html'); + addPage('svgPage', 'svgPiechart.xhtml'); + addPage('tables', 'tables.html'); + addPage('underscorePage', 'underscore.html'); + addPage('unicodeLtrPage', 'utf8/unicode_ltr.html'); + addPage('uploadPage', 'upload.html'); + addPage('veryLargeCanvas', 'veryLargeCanvas.html'); + addPage('xhtmlTestPage', 'xhtmlTest.html'); + + return pages; +})(); + + +var Path = { + BASIC_AUTH: WEB_ROOT + '/basicAuth', + ECHO: WEB_ROOT + '/echo', + GENERATED: WEB_ROOT + '/generated', + MANIFEST: WEB_ROOT + '/manifest', + REDIRECT: WEB_ROOT + '/redirect', + PAGE: WEB_ROOT + '/page', + SLEEP: WEB_ROOT + '/sleep', + UPLOAD: WEB_ROOT + '/upload' +}; + +var app = express(); + +app.get('/', sendIndex) +.get('/favicon.ico', function(req, res) { + res.writeHead(204); + res.end(); +}) +.use(JS_ROOT, serveIndex(jsDirectory), express.static(jsDirectory)) +.post(Path.UPLOAD, handleUpload) +.use(WEB_ROOT, serveIndex(baseDirectory), express.static(baseDirectory)) +.get(Path.ECHO, sendEcho) +.get(Path.PAGE, sendInifinitePage) +.get(Path.PAGE + '/*', sendInifinitePage) +.get(Path.REDIRECT, redirectToResultPage) +.get(Path.SLEEP, sendDelayedResponse) + +if (isDevMode) { + var closureDir = resources.locate('third_party/closure/goog'); + app.use('/third_party/closure/goog', + serveIndex(closureDir), express.static(closureDir)); +} +var server = new Server(app); + + +function redirectToResultPage(_, response) { + response.writeHead(303, { + Location: Pages.resultPage + }); + return response.end(); +} + + +function sendInifinitePage(request, response) { + var pathname = url.parse(request.url).pathname; + var lastIndex = pathname.lastIndexOf('/'); + var pageNumber = + (lastIndex == -1 ? 'Unknown' : pathname.substring(lastIndex + 1)); + var body = [ + '', + 'Page', pageNumber, '', + 'Page number ', pageNumber, '', + '

    top' + ].join(''); + response.writeHead(200, { + 'Content-Length': Buffer.byteLength(body, 'utf8'), + 'Content-Type': 'text/html; charset=utf-8' + }); + response.end(body); +} + + +function sendDelayedResponse(request, response) { + var duration = 0; + var query = url.parse(request.url).query || ''; + var match = query.match(/\btime=(\d+)/); + if (match) { + duration = parseInt(match[1], 10); + } + + setTimeout(function() { + var body = [ + '', + 'Done', + 'Slept for ', duration, 's' + ].join(''); + response.writeHead(200, { + 'Content-Length': Buffer.byteLength(body, 'utf8'), + 'Content-Type': 'text/html; charset=utf-8', + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache', + 'Expires': 0 + }); + response.end(body); + }, duration * 1000); +} + + +function handleUpload(request, response, next) { + multer({ + inMemory: true, + onFileUploadComplete: function(file) { + response.writeHead(200); + response.write(file.buffer); + response.end(''); + } + })(request, response, function() {}); +} + + +function sendEcho(request, response) { + var body = [ + '', + 'Echo', + '

    ', + request.method, ' ', request.url, ' ', 'HTTP/', request.httpVersion, + '
    ' + ]; + for (var name in request.headers) { + body.push('
    ', + name, ': ', request.headers[name], '
    '); + } + body = body.join(''); + response.writeHead(200, { + 'Content-Length': Buffer.byteLength(body, 'utf8'), + 'Content-Type': 'text/html; charset=utf-8' + }); + response.end(body); +} + + +/** + * Responds to a request for the file server's main index. + * @param {!http.ServerRequest} request The request object. + * @param {!http.ServerResponse} response The response object. + */ +function sendIndex(request, response) { + var pathname = url.parse(request.url).pathname; + + var host = request.headers.host; + if (!host) { + host = server.host(); + } + + var requestUrl = ['http://' + host + pathname].join(''); + + function createListEntry(path) { + var url = requestUrl + path; + return ['
  • ', path, ''].join(''); + } + + var data = ['

    /


      ', + createListEntry('common')]; + if (isDevMode) { + data.push(createListEntry('javascript')); + } + data.push('
    '); + data = data.join(''); + + response.writeHead(200, { + 'Content-Type': 'text/html; charset=UTF-8', + 'Content-Length': Buffer.byteLength(data, 'utf8') + }); + response.end(data); +} + + +// PUBLIC application + + +/** + * Starts the server on the specified port. + * @param {number=} opt_port The port to use, or 0 for any free port. + * @return {!webdriver.promise.Promise.} A promise that will resolve + * with the server host when it has fully started. + */ +exports.start = server.start.bind(server); + + +/** + * Stops the server. + * @return {!webdriver.promise.Promise} A promise that will resolve when the + * server has closed all connections. + */ +exports.stop = server.stop.bind(server); + + +/** + * Formats a URL for this server. + * @param {string=} opt_pathname The desired pathname on the server. + * @return {string} The formatted URL. + * @throws {Error} If the server is not running. + */ +exports.url = server.url.bind(server); + + +/** + * Builds the URL for a file in the //common/src/web directory of the + * Selenium client. + * @param {string} filePath A path relative to //common/src/web to compute a + * URL for. + * @return {string} The formatted URL. + * @throws {Error} If the server is not running. + */ +exports.whereIs = function(filePath) { + filePath = filePath.replace(/\\/g, '/'); + if (!filePath.startsWith('/')) { + filePath = '/' + filePath; + } + return server.url(WEB_ROOT + filePath); +}; + + +exports.Pages = Pages; + + +if (require.main === module) { + server.start(2310).then(function() { + console.log('Server running at ' + server.url()); + }); +} diff --git a/www/node_modules/selenium-webdriver/lib/test/httpserver.js b/www/node_modules/selenium-webdriver/lib/test/httpserver.js new file mode 100644 index 0000000..55b1255 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/httpserver.js @@ -0,0 +1,122 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'), + http = require('http'), + url = require('url'); + +var net = require('../../net'), + portprober = require('../../net/portprober'), + promise = require('../..').promise; + + + +/** + * Encapsulates a simple HTTP server for testing. The {@code onrequest} + * function should be overridden to define request handling behavior. + * @param {function(!http.ServerRequest, !http.ServerResponse)} requestHandler + * The request handler for the server. + * @constructor + */ +var Server = function(requestHandler) { + var server = http.createServer(function(req, res) { + requestHandler(req, res); + }); + + server.on('connection', function(stream) { + stream.setTimeout(4000); + }); + + /** @typedef {{port: number, address: string, family: string}} */ + var Host; + + /** + * Starts the server on the given port. If no port, or 0, is provided, + * the server will be started on a random port. + * @param {number=} opt_port The port to start on. + * @return {!webdriver.promise.Promise.} A promise that will resolve + * with the server host when it has fully started. + */ + this.start = function(opt_port) { + assert(typeof opt_port !== 'function', + "start invoked with function, not port (mocha callback)?"); + var port = opt_port || portprober.findFreePort('localhost'); + return promise.when(port, function(port) { + return promise.checkedNodeCall( + server.listen.bind(server, port, 'localhost')); + }).then(function() { + return server.address(); + }); + }; + + /** + * Stops the server. + * @return {!webdriver.promise.Promise} A promise that will resolve when the + * server has closed all connections. + */ + this.stop = function() { + var d = promise.defer(); + server.close(d.fulfill); + return d.promise; + }; + + /** + * @return {Host} This server's host info. + * @throws {Error} If the server is not running. + */ + this.address = function() { + var addr = server.address(); + if (!addr) { + throw Error('There server is not running!'); + } + return addr; + }; + + /** + * return {string} The host:port of this server. + * @throws {Error} If the server is not running. + */ + this.host = function() { + return net.getLoopbackAddress() + ':' + + this.address().port; + }; + + /** + * Formats a URL for this server. + * @param {string=} opt_pathname The desired pathname on the server. + * @return {string} The formatted URL. + * @throws {Error} If the server is not running. + */ + this.url = function(opt_pathname) { + var addr = this.address(); + var pathname = opt_pathname || ''; + return url.format({ + protocol: 'http', + hostname: net.getLoopbackAddress(), + port: addr.port, + pathname: pathname + }); + }; +}; + + +// PUBLIC API + + +exports.Server = Server; diff --git a/www/node_modules/selenium-webdriver/lib/test/index.js b/www/node_modules/selenium-webdriver/lib/test/index.js new file mode 100644 index 0000000..8f576a8 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/index.js @@ -0,0 +1,262 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'); + +var build = require('./build'), + isDevMode = require('../devmode'), + webdriver = require('../../'), + flow = webdriver.promise.controlFlow(), + remote = require('../../remote'), + testing = require('../../testing'), + fileserver = require('./fileserver'); + + +/** + * Browsers with native support. + * @type {!Array.} + */ +var NATIVE_BROWSERS = [ + webdriver.Browser.CHROME, + webdriver.Browser.EDGE, + webdriver.Browser.FIREFOX, + webdriver.Browser.IE, + webdriver.Browser.OPERA, + webdriver.Browser.PHANTOM_JS, + webdriver.Browser.SAFARI +]; + + +var serverJar = process.env['SELENIUM_SERVER_JAR']; +var remoteUrl = process.env['SELENIUM_REMOTE_URL']; +var useLoopback = process.env['SELENIUM_USE_LOOP_BACK'] == '1'; +var startServer = !!serverJar && !remoteUrl; +var nativeRun = !serverJar && !remoteUrl; + + +var browsersToTest = (function() { + var permitRemoteBrowsers = !!remoteUrl || !!serverJar; + var permitUnknownBrowsers = !nativeRun; + var browsers = process.env['SELENIUM_BROWSER'] || webdriver.Browser.FIREFOX; + + browsers = browsers.split(',').map(function(browser) { + var parts = browser.split(/:/); + if (parts[0] === 'ie') { + parts[0] = webdriver.Browser.IE; + } + if (parts[0] === 'edge') { + parts[0] = webdriver.Browser.EDGE; + } + return parts.join(':'); + }); + browsers.forEach(function(browser) { + var parts = browser.split(/:/, 3); + if (parts[0] === 'ie') { + parts[0] = webdriver.Browser.IE; + } + + if (NATIVE_BROWSERS.indexOf(parts[0]) == -1 && !permitRemoteBrowsers) { + throw Error('Browser ' + parts[0] + ' requires a WebDriver server and ' + + 'neither the SELENIUM_REMOTE_URL nor the SELENIUM_SERVER_JAR ' + + 'environment variables have been set.'); + } + + var recognized = false; + for (var prop in webdriver.Browser) { + if (webdriver.Browser.hasOwnProperty(prop) && + webdriver.Browser[prop] === parts[0]) { + recognized = true; + break; + } + } + + if (!recognized && !permitUnknownBrowsers) { + throw Error('Unrecognized browser: ' + browser); + } + }); + + console.log('Running tests against [' + browsers.join(',') + ']'); + if (remoteUrl) { + console.log('Using remote server ' + remoteUrl); + } else if (serverJar) { + console.log('Using standalone Selenium server ' + serverJar); + if (useLoopback) { + console.log('Running tests using loopback address') + } + } + + return browsers; +})(); + + +/** + * Creates a predicate function that ignores tests for specific browsers. + * @param {string} currentBrowser The name of the current browser. + * @param {!Array.} browsersToIgnore The browsers to ignore. + * @return {function(): boolean} The predicate function. + */ +function browsers(currentBrowser, browsersToIgnore) { + return function() { + return browsersToIgnore.indexOf(currentBrowser) != -1; + }; +} + + +/** + * @param {string} browserName The name to use. + * @param {remote.DriverService} server The server to use, if any. + * @constructor + */ +function TestEnvironment(browserName, server) { + var name = browserName; + + this.currentBrowser = function() { + return browserName; + }; + + this.isRemote = function() { + return server || remoteUrl; + }; + + this.browsers = function(var_args) { + var browsersToIgnore = Array.prototype.slice.apply(arguments, [0]); + return browsers(browserName, browsersToIgnore); + }; + + this.builder = function() { + var builder = new webdriver.Builder(); + var realBuild = builder.build; + + builder.build = function() { + var parts = browserName.split(/:/, 3); + builder.forBrowser(parts[0], parts[1], parts[2]); + if (server) { + builder.usingServer(server.address()); + } else if (remoteUrl) { + builder.usingServer(remoteUrl); + } + builder.disableEnvironmentOverrides(); + return realBuild.call(builder); + }; + + return builder; + }; +} + + +var seleniumServer; +var inSuite = false; + + +/** + * Expands a function to cover each of the target browsers. + * @param {function(!TestEnvironment)} fn The top level suite + * function. + * @param {{browsers: !Array.}=} opt_options Suite specific options. + */ +function suite(fn, opt_options) { + assert.ok(!inSuite, 'You may not nest suite calls'); + inSuite = true; + + var suiteOptions = opt_options || {}; + var browsers = suiteOptions.browsers; + if (browsers) { + // Filter out browser specific tests when that browser is not currently + // selected for testing. + browsers = browsers.filter(function(browser) { + return browsersToTest.indexOf(browser) != -1; + }); + } else { + browsers = browsersToTest; + } + + try { + + // Server is only started if required for a specific config. + testing.after(function() { + if (seleniumServer) { + return seleniumServer.stop(); + } + }); + + browsers.forEach(function(browser) { + testing.describe('[' + browser + ']', function() { + + if (isDevMode && nativeRun) { + if (browser === webdriver.Browser.FIREFOX) { + testing.before(function() { + return build.of('//javascript/firefox-driver:webdriver') + .onlyOnce().go(); + }); + } else if (browser === webdriver.Browser.SAFARI) { + testing.before(function() { + return build.of('//javascript/safari-driver:client') + .onlyOnce().go(); + }); + } + } + + var serverToUse = null; + + if (!!serverJar && !remoteUrl) { + if (!(serverToUse = seleniumServer)) { + serverToUse = seleniumServer = new remote.SeleniumServer( + serverJar, {loopback: useLoopback}); + } + + testing.before(function() { + this.timeout(0); + return seleniumServer.start(60 * 1000); + }); + } + fn(new TestEnvironment(browser, serverToUse)); + }); + }); + } finally { + inSuite = false; + } +} + + +// GLOBAL TEST SETUP + +testing.before(function() { + // Do not pass register fileserver.start directly with testing.before, + // as start takes an optional port, which before assumes is an async + // callback. + return fileserver.start(); +}); + +testing.after(function() { + return fileserver.stop(); +}); + +// PUBLIC API + + +exports.suite = suite; +exports.after = testing.after; +exports.afterEach = testing.afterEach; +exports.before = testing.before; +exports.beforeEach = testing.beforeEach; +exports.it = testing.it; +exports.ignore = testing.ignore; + +exports.Pages = fileserver.Pages; +exports.whereIs = fileserver.whereIs; diff --git a/www/node_modules/selenium-webdriver/lib/test/resources.js b/www/node_modules/selenium-webdriver/lib/test/resources.js new file mode 100644 index 0000000..8e9cceb --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/test/resources.js @@ -0,0 +1,44 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fs = require('fs'), + path = require('path'); + +var resourceRoot = require('../devmode') ? + require('./build').projectRoot() : + path.join(__dirname, 'data'); + + +// PUBLIC API + + +/** + * Locates a test resource. + * @param {string} resourcePath Path of the resource to locate. + * @param {string} filePath The file to locate from the root of the project. + * @return {string} The full path for the file, if it exists. + * @throws {Error} If the file does not exist. + */ +exports.locate = function(filePath) { + var fullPath = path.normalize(path.join(resourceRoot, filePath)); + if (!fs.existsSync(fullPath)) { + throw Error('File does not exist: ' + filePath); + } + return fullPath; +}; diff --git a/www/node_modules/selenium-webdriver/lib/until.js b/www/node_modules/selenium-webdriver/lib/until.js new file mode 100644 index 0000000..8b6e83d --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/until.js @@ -0,0 +1,428 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines common conditions for use with + * {@link webdriver.WebDriver#wait WebDriver wait}. + * + * Sample usage: + * + * driver.get('http://www.google.com/ncr'); + * + * var query = driver.wait(until.elementLocated(By.name('q'))); + * query.sendKeys('webdriver\n'); + * + * driver.wait(until.titleIs('webdriver - Google Search')); + * + * To define a custom condition, simply call WebDriver.wait with a function + * that will eventually return a truthy-value (neither null, undefined, false, + * 0, or the empty string): + * + * driver.wait(function() { + * return driver.getTitle().then(function(title) { + * return title === 'webdriver - Google Search'; + * }); + * }, 1000); + */ + +'use strict'; + +const by = require('./by'); +const By = require('./by').By; +const error = require('../error'); + + +/** + * Defines a condition for use with WebDriver's + * {@linkplain ./webdriver.WebDriver#wait wait command}. + * + * @template OUT + */ +class Condition { + /** + * @param {string} message A descriptive error message. Should complete the + * sentence "Waiting [...]" + * @param {function(!./webdriver.WebDriver): OUT} fn The condition function to + * evaluate on each iteration of the wait loop. + */ + constructor(message, fn) { + /** @private {string} */ + this.description_ = 'Waiting ' + message; + + /** @type {function(!./webdriver.WebDriver): OUT} */ + this.fn = fn; + } + + /** @return {string} A description of this condition. */ + description() { + return this.description_; + } +} + +/** + * @typedef {!(./webdriver.WebElement| + * ./promise.Promise)} + */ +var ElementConditionResult; + + +/** + * Defines a condition that will result in a + * {@link ./webdriver.WebElement WebElement}. + * + * @extends {Condition} + */ +class WebElementCondition extends Condition { + /** + * @param {string} message A descriptive error message. Should complete the + * sentence "Waiting [...]" + * @param {function(!./webdriver.WebDriver): ElementConditionResult} fn The + * condition function to evaluate on each iteration of the wait loop. + */ + constructor(message, fn) { + super(message, fn); + } +} + + +// PUBLIC API + + +exports.Condition = Condition; +exports.WebElementCondition = WebElementCondition; + + +/** + * Creates a condition that will wait until the input driver is able to switch + * to the designated frame. The target frame may be specified as + * + * 1. a numeric index into + * [window.frames](https://developer.mozilla.org/en-US/docs/Web/API/Window.frames) + * for the currently selected frame. + * 2. a {@link ./webdriver.WebElement}, which must reference a FRAME or IFRAME + * element on the current page. + * 3. a locator which may be used to first locate a FRAME or IFRAME on the + * current page before attempting to switch to it. + * + * Upon successful resolution of this condition, the driver will be left + * focused on the new frame. + * + * @param {!(number|./webdriver.WebElement|By| + * function(!./webdriver.WebDriver): !./webdriver.WebElement)} frame + * The frame identifier. + * @return {!Condition} A new condition. + */ +exports.ableToSwitchToFrame = function ableToSwitchToFrame(frame) { + // Not at top-level to avoid circular dependency. + const webdriver = require('./webdriver'); + + var condition; + if (typeof frame === 'number' || frame instanceof webdriver.WebElement) { + condition = attemptToSwitchFrames; + } else { + condition = function(driver) { + let locator = /** @type {!(By|Function)} */(frame); + return driver.findElements(locator).then(function(els) { + if (els.length) { + return attemptToSwitchFrames(driver, els[0]); + } + }); + }; + } + + return new Condition('to be able to switch to frame', condition); + + function attemptToSwitchFrames(driver, frame) { + return driver.switchTo().frame(frame).then( + function() { return true; }, + function(e) { + if (!(e instanceof error.NoSuchFrameError)) { + throw e; + } + }); + } +}; + + +/** + * Creates a condition that waits for an alert to be opened. Upon success, the + * returned promise will be fulfilled with the handle for the opened alert. + * + * @return {!Condition} The new condition. + */ +exports.alertIsPresent = function alertIsPresent() { + return new Condition('for alert to be present', function(driver) { + return driver.switchTo().alert().thenCatch(function(e) { + if (!(e instanceof error.NoSuchAlertError)) { + throw e; + } + }); + }); +}; + + +/** + * Creates a condition that will wait for the current page's title to match the + * given value. + * + * @param {string} title The expected page title. + * @return {!Condition} The new condition. + */ +exports.titleIs = function titleIs(title) { + return new Condition( + 'for title to be ' + JSON.stringify(title), + function(driver) { + return driver.getTitle().then(function(t) { + return t === title; + }); + }); +}; + + +/** + * Creates a condition that will wait for the current page's title to contain + * the given substring. + * + * @param {string} substr The substring that should be present in the page + * title. + * @return {!Condition} The new condition. + */ +exports.titleContains = function titleContains(substr) { + return new Condition( + 'for title to contain ' + JSON.stringify(substr), + function(driver) { + return driver.getTitle().then(function(title) { + return title.indexOf(substr) !== -1; + }); + }); +}; + + +/** + * Creates a condition that will wait for the current page's title to match the + * given regular expression. + * + * @param {!RegExp} regex The regular expression to test against. + * @return {!Condition} The new condition. + */ +exports.titleMatches = function titleMatches(regex) { + return new Condition('for title to match ' + regex, function(driver) { + return driver.getTitle().then(function(title) { + return regex.test(title); + }); + }); +}; + + +/** + * Creates a condition that will loop until an element is + * {@link ./webdriver.WebDriver#findElement found} with the given locator. + * + * @param {!(By|Function)} locator The locator to use. + * @return {!WebElementCondition} The new condition. + */ +exports.elementLocated = function elementLocated(locator) { + locator = by.checkedLocator(locator); + let locatorStr = + typeof locator === 'function' ? 'by function()' : locator + ''; + return new WebElementCondition('for element to be located ' + locatorStr, + function(driver) { + return driver.findElements(locator).then(function(elements) { + return elements[0]; + }); + }); +}; + + +/** + * Creates a condition that will loop until at least one element is + * {@link ./webdriver.WebDriver#findElement found} with the given locator. + * + * @param {!(By|Function)} locator The locator to use. + * @return {!Condition>} The new + * condition. + */ +exports.elementsLocated = function elementsLocated(locator) { + locator = by.checkedLocator(locator); + let locatorStr = + typeof locator === 'function' ? 'by function()' : locator + ''; + return new Condition( + 'for at least one element to be located ' + locatorStr, + function(driver) { + return driver.findElements(locator).then(function(elements) { + return elements.length > 0 ? elements : null; + }); + }); +}; + + +/** + * Creates a condition that will wait for the given element to become stale. An + * element is considered stale once it is removed from the DOM, or a new page + * has loaded. + * + * @param {!./webdriver.WebElement} element The element that should become stale. + * @return {!Condition} The new condition. + */ +exports.stalenessOf = function stalenessOf(element) { + return new Condition('element to become stale', function() { + return element.getTagName().then( + function() { return false; }, + function(e) { + if (e instanceof error.StaleElementReferenceError) { + return true; + } + throw e; + }); + }); +}; + + +/** + * Creates a condition that will wait for the given element to become visible. + * + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see ./webdriver.WebDriver#isDisplayed + */ +exports.elementIsVisible = function elementIsVisible(element) { + return new WebElementCondition('until element is visible', function() { + return element.isDisplayed().then(v => v ? element : null); + }); +}; + + +/** + * Creates a condition that will wait for the given element to be in the DOM, + * yet not visible to the user. + * + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see ./webdriver.WebDriver#isDisplayed + */ +exports.elementIsNotVisible = function elementIsNotVisible(element) { + return new WebElementCondition('until element is not visible', function() { + return element.isDisplayed().then(v => v ? null : element); + }); +}; + + +/** + * Creates a condition that will wait for the given element to be enabled. + * + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#isEnabled + */ +exports.elementIsEnabled = function elementIsEnabled(element) { + return new WebElementCondition('until element is enabled', function() { + return element.isEnabled().then(v => v ? element : null); + }); +}; + + +/** + * Creates a condition that will wait for the given element to be disabled. + * + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#isEnabled + */ +exports.elementIsDisabled = function elementIsDisabled(element) { + return new WebElementCondition('until element is disabled', function() { + return element.isEnabled().then(v => v ? null : element); + }); +}; + + +/** + * Creates a condition that will wait for the given element to be selected. + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#isSelected + */ +exports.elementIsSelected = function elementIsSelected(element) { + return new WebElementCondition('until element is selected', function() { + return element.isSelected().then(v => v ? element : null); + }); +}; + + +/** + * Creates a condition that will wait for the given element to be deselected. + * + * @param {!./webdriver.WebElement} element The element to test. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#isSelected + */ +exports.elementIsNotSelected = function elementIsNotSelected(element) { + return new WebElementCondition('until element is not selected', function() { + return element.isSelected().then(v => v ? null : element); + }); +}; + + +/** + * Creates a condition that will wait for the given element's + * {@link webdriver.WebDriver#getText visible text} to match the given + * {@code text} exactly. + * + * @param {!./webdriver.WebElement} element The element to test. + * @param {string} text The expected text. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#getText + */ +exports.elementTextIs = function elementTextIs(element, text) { + return new WebElementCondition('until element text is', function() { + return element.getText().then(t => t === text ? element : null); + }); +}; + + +/** + * Creates a condition that will wait for the given element's + * {@link webdriver.WebDriver#getText visible text} to contain the given + * substring. + * + * @param {!./webdriver.WebElement} element The element to test. + * @param {string} substr The substring to search for. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#getText + */ +exports.elementTextContains = function elementTextContains(element, substr) { + return new WebElementCondition('until element text contains', function() { + return element.getText() + .then(t => t.indexOf(substr) != -1 ? element : null); + }); +}; + + +/** + * Creates a condition that will wait for the given element's + * {@link webdriver.WebDriver#getText visible text} to match a regular + * expression. + * + * @param {!./webdriver.WebElement} element The element to test. + * @param {!RegExp} regex The regular expression to test against. + * @return {!WebElementCondition} The new condition. + * @see webdriver.WebDriver#getText + */ +exports.elementTextMatches = function elementTextMatches(element, regex) { + return new WebElementCondition('until element text matches', function() { + return element.getText().then(t => regex.test(t) ? element : null); + }); +}; diff --git a/www/node_modules/selenium-webdriver/lib/webdriver.js b/www/node_modules/selenium-webdriver/lib/webdriver.js new file mode 100644 index 0000000..0adcbb0 --- /dev/null +++ b/www/node_modules/selenium-webdriver/lib/webdriver.js @@ -0,0 +1,2351 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview The heart of the WebDriver JavaScript API. + */ + +'use strict'; + +const error = require('../error'); +const actions = require('./actions'); +const by = require('./by'); +const Capabilities = require('./capabilities').Capabilities; +const command = require('./command'); +const input = require('./input'); +const logging = require('./logging'); +const Session = require('./session').Session; +const Symbols = require('./symbols'); +const promise = require('./promise'); +const until = require('./until'); + + + +////////////////////////////////////////////////////////////////////////////// +// +// WebDriver +// +////////////////////////////////////////////////////////////////////////////// + + +/** + * Sends a command to the server that is expected to return the details for a + * {@link Session}. This may either be an existing session, or a newly created + * one. + * + * @param {!command.Executor} executor Command executor to use when + * querying for session details. + * @param {!command.Command} command The command to send to fetch the session + * details. + * @param {string} description A descriptive debug label for this action. + * @param {promise.ControlFlow=} opt_flow The control flow all driver + * commands should execute under. Defaults to the + * {@link promise.controlFlow() currently active} control flow. + * @return {!WebDriver} A new WebDriver client for the session. + */ +function acquireSession(executor, command, description, opt_flow) { + let flow = opt_flow || promise.controlFlow(); + let session = flow.execute(function() { + return executeCommand(executor, command).then(function(response) { + error.checkLegacyResponse(response); + return new Session(response['sessionId'], response['value']); + }); + }, description); + return new WebDriver(session, executor, flow); +} + + +/** + * Translates a command to its wire-protocol representation before passing it + * to the given `executor` for execution. + * @param {!command.Executor} executor The executor to use. + * @param {!command.Command} command The command to execute. + * @return {!promise.Promise} A promise that will resolve with the + * command response. + */ +function executeCommand(executor, command) { + return toWireValue(command.getParameters()). + then(function(parameters) { + command.setParameters(parameters); + return executor.execute(command); + }); +} + + +/** + * Converts an object to its JSON representation in the WebDriver wire protocol. + * When converting values of type object, the following steps will be taken: + *
      + *
    1. if the object is a WebElement, the return value will be the element's + * server ID + *
    2. if the object defines a {@link Symbols.serialize} method, this algorithm + * will be recursively applied to the object's serialized representation + *
    3. if the object provides a "toJSON" function, this algorithm will + * recursively be applied to the result of that function + *
    4. otherwise, the value of each key will be recursively converted according + * to the rules above. + *
    + * + * @param {*} obj The object to convert. + * @return {!promise.Promise} A promise that will resolve to the + * input value's JSON representation. + */ +function toWireValue(obj) { + if (promise.isPromise(obj)) { + return obj.then(toWireValue); + } + return promise.fulfilled(convertValue(obj)); +} + + +function convertValue(value) { + if (value === void 0 || value === null) { + return value; + } + + if (typeof value === 'boolean' + || typeof value === 'number' + || typeof value === 'string') { + return value; + } + + if (Array.isArray(value)) { + return convertKeys(value); + } + + if (typeof value === 'function') { + return '' + value; + } + + if (typeof value[Symbols.serialize] === 'function') { + return toWireValue(value[Symbols.serialize]()); + } else if (typeof value.toJSON === 'function') { + return toWireValue(value.toJSON()); + } + return convertKeys(value); +} + + +function convertKeys(obj) { + const isArray = Array.isArray(obj); + const numKeys = isArray ? obj.length : Object.keys(obj).length; + const ret = isArray ? new Array(numKeys) : {}; + if (!numKeys) { + return promise.fulfilled(ret); + } + + let numResolved = 0; + + function forEachKey(obj, fn) { + if (Array.isArray(obj)) { + for (let i = 0, n = obj.length; i < n; i++) { + fn(obj[i], i); + } + } else { + for (let key in obj) { + fn(obj[key], key); + } + } + } + + return new promise.Promise(function(done, reject) { + forEachKey(obj, function(value, key) { + if (promise.isPromise(value)) { + value.then(toWireValue).then(setValue, reject); + } else { + value = convertValue(value); + if (promise.isPromise(value)) { + value.then(toWireValue).then(setValue, reject); + } else { + setValue(value); + } + } + + function setValue(value) { + ret[key] = value; + maybeFulfill(); + } + }); + + function maybeFulfill() { + if (++numResolved === numKeys) { + done(ret); + } + } + }); +} + + +/** + * Converts a value from its JSON representation according to the WebDriver wire + * protocol. Any JSON object that defines a WebElement ID will be decoded to a + * {@link WebElement} object. All other values will be passed through as is. + * + * @param {!WebDriver} driver The driver to use as the parent of any unwrapped + * {@link WebElement} values. + * @param {*} value The value to convert. + * @return {*} The converted value. + */ +function fromWireValue(driver, value) { + if (Array.isArray(value)) { + value = value.map(v => fromWireValue(driver, v)); + } else if (WebElement.isId(value)) { + let id = WebElement.extractId(value); + value = new WebElement(driver, id); + } else if (value && typeof value === 'object') { + let result = {}; + for (let key in value) { + if (value.hasOwnProperty(key)) { + result[key] = fromWireValue(driver, value[key]); + } + } + value = result; + } + return value; +} + + +/** + * Creates a new WebDriver client, which provides control over a browser. + * + * Every command.Command returns a {@link promise.Promise} that + * represents the result of that command. Callbacks may be registered on this + * object to manipulate the command result or catch an expected error. Any + * commands scheduled with a callback are considered sub-commands and will + * execute before the next command in the current frame. For example: + * + * var message = []; + * driver.call(message.push, message, 'a').then(function() { + * driver.call(message.push, message, 'b'); + * }); + * driver.call(message.push, message, 'c'); + * driver.call(function() { + * alert('message is abc? ' + (message.join('') == 'abc')); + * }); + * + */ +class WebDriver { + /** + * @param {!(Session|promise.Promise)} session Either a + * known session or a promise that will be resolved to a session. + * @param {!command.Executor} executor The executor to use when sending + * commands to the browser. + * @param {promise.ControlFlow=} opt_flow The flow to + * schedule commands through. Defaults to the active flow object. + */ + constructor(session, executor, opt_flow) { + /** @private {!promise.Promise} */ + this.session_ = promise.fulfilled(session);; + + /** @private {!command.Executor} */ + this.executor_ = executor; + + /** @private {!promise.ControlFlow} */ + this.flow_ = opt_flow || promise.controlFlow(); + + /** @private {input.FileDetector} */ + this.fileDetector_ = null; + } + + /** + * Creates a new WebDriver client for an existing session. + * @param {!command.Executor} executor Command executor to use when querying + * for session details. + * @param {string} sessionId ID of the session to attach to. + * @param {promise.ControlFlow=} opt_flow The control flow all + * driver commands should execute under. Defaults to the + * {@link promise.controlFlow() currently active} control flow. + * @return {!WebDriver} A new client for the specified session. + */ + static attachToSession(executor, sessionId, opt_flow) { + return acquireSession(executor, + new command.Command(command.Name.DESCRIBE_SESSION). + setParameter('sessionId', sessionId), + 'WebDriver.attachToSession()', + opt_flow); + } + + /** + * Creates a new WebDriver session. + * @param {!command.Executor} executor The executor to create the new session + * with. + * @param {!./capabilities.Capabilities} desiredCapabilities The desired + * capabilities for the new session. + * @param {promise.ControlFlow=} opt_flow The control flow all driver + * commands should execute under, including the initial session creation. + * Defaults to the {@link promise.controlFlow() currently active} + * control flow. + * @return {!WebDriver} The driver for the newly created session. + */ + static createSession(executor, desiredCapabilities, opt_flow) { + return acquireSession(executor, + new command.Command(command.Name.NEW_SESSION). + setParameter('desiredCapabilities', desiredCapabilities), + 'WebDriver.createSession()', + opt_flow); + } + + /** + * @return {!promise.ControlFlow} The control flow used by this + * instance. + */ + controlFlow() { + return this.flow_; + } + + /** + * Schedules a {@link command.Command} to be executed by this driver's + * {@link command.Executor}. + * + * @param {!command.Command} command The command to schedule. + * @param {string} description A description of the command for debugging. + * @return {!promise.Promise} A promise that will be resolved + * with the command result. + * @template T + */ + schedule(command, description) { + var self = this; + + checkHasNotQuit(); + command.setParameter('sessionId', this.session_); + + // If any of the command parameters are rejected promises, those + // rejections may be reported as unhandled before the control flow + // attempts to execute the command. To ensure parameters errors + // propagate through the command itself, we resolve all of the + // command parameters now, but suppress any errors until the ControlFlow + // actually executes the command. This addresses scenarios like catching + // an element not found error in: + // + // driver.findElement(By.id('foo')).click().thenCatch(function(e) { + // if (e instanceof NoSuchElementError) { + // // Do something. + // } + // }); + var prepCommand = toWireValue(command.getParameters()); + prepCommand.thenCatch(function() {}); + + var flow = this.flow_; + var executor = this.executor_; + return flow.execute(function() { + // A call to WebDriver.quit() may have been scheduled in the same event + // loop as this |command|, which would prevent us from detecting that the + // driver has quit above. Therefore, we need to make another quick check. + // We still check above so we can fail as early as possible. + checkHasNotQuit(); + + // Retrieve resolved command parameters; any previously suppressed errors + // will now propagate up through the control flow as part of the command + // execution. + return prepCommand.then(function(parameters) { + command.setParameters(parameters); + return executor.execute(command); + }); + }, description).then(function(response) { + try { + error.checkLegacyResponse(response); + } catch (ex) { + if (ex instanceof error.UnexpectedAlertOpenError) { + let text = ''; + if (response['value'] + && response['value']['alert'] + && typeof response['value']['alert']['text'] === 'string') { + text = response['value']['alert']['text']; + } + throw new error.UnexpectedAlertOpenError(ex.message, text); + } + throw ex; + } + return fromWireValue(self, response['value']); + }); + + function checkHasNotQuit() { + if (!self.session_) { + throw new error.UnsupportedOperationError( + 'This driver instance does not have a valid session ID ' + + '(did you call WebDriver.quit()?) and may no longer be ' + + 'used.'); + } + } + } + + /** + * Sets the {@linkplain input.FileDetector file detector} that should be + * used with this instance. + * @param {input.FileDetector} detector The detector to use or {@code null}. + */ + setFileDetector(detector) { + this.fileDetector_ = detector; + } + + /** + * @return {!promise.Promise} A promise for this client's + * session. + */ + getSession() { + return this.session_; + } + + /** + * @return {!promise.Promise} A promise + * that will resolve with the this instance's capabilities. + */ + getCapabilities() { + return this.session_.then(session => session.getCapabilities()); + } + + /** + * Schedules a command to quit the current session. After calling quit, this + * instance will be invalidated and may no longer be used to issue commands + * against the browser. + * @return {!promise.Promise} A promise that will be resolved + * when the command has completed. + */ + quit() { + var result = this.schedule( + new command.Command(command.Name.QUIT), + 'WebDriver.quit()'); + // Delete our session ID when the quit command finishes; this will allow us to + // throw an error when attemnpting to use a driver post-quit. + return result.thenFinally(() => delete this.session_); + } + + /** + * Creates a new action sequence using this driver. The sequence will not be + * scheduled for execution until {@link actions.ActionSequence#perform} is + * called. Example: + * + * driver.actions(). + * mouseDown(element1). + * mouseMove(element2). + * mouseUp(). + * perform(); + * + * @return {!actions.ActionSequence} A new action sequence for this instance. + */ + actions() { + return new actions.ActionSequence(this); + } + + /** + * Creates a new touch sequence using this driver. The sequence will not be + * scheduled for execution until {@link actions.TouchSequence#perform} is + * called. Example: + * + * driver.touchActions(). + * tap(element1). + * doubleTap(element2). + * perform(); + * + * @return {!actions.TouchSequence} A new touch sequence for this instance. + */ + touchActions() { + return new actions.TouchSequence(this); + } + + /** + * Schedules a command to execute JavaScript in the context of the currently + * selected frame or window. The script fragment will be executed as the body + * of an anonymous function. If the script is provided as a function object, + * that function will be converted to a string for injection into the target + * window. + * + * Any arguments provided in addition to the script will be included as script + * arguments and may be referenced using the {@code arguments} object. + * Arguments may be a boolean, number, string, or {@linkplain WebElement}. + * Arrays and objects may also be used as script arguments as long as each item + * adheres to the types previously mentioned. + * + * The script may refer to any variables accessible from the current window. + * Furthermore, the script will execute in the window's context, thus + * {@code document} may be used to refer to the current document. Any local + * variables will not be available once the script has finished executing, + * though global variables will persist. + * + * If the script has a return value (i.e. if the script contains a return + * statement), then the following steps will be taken for resolving this + * functions return value: + * + * - For a HTML element, the value will resolve to a {@linkplain WebElement} + * - Null and undefined return values will resolve to null
  • + * - Booleans, numbers, and strings will resolve as is + * - Functions will resolve to their string representation + * - For arrays and objects, each member item will be converted according to + * the rules above + * + * @param {!(string|Function)} script The script to execute. + * @param {...*} var_args The arguments to pass to the script. + * @return {!promise.Promise} A promise that will resolve to the + * scripts return value. + * @template T + */ + executeScript(script, var_args) { + if (typeof script === 'function') { + script = 'return (' + script + ').apply(null, arguments);'; + } + let args = + arguments.length > 1 ? Array.prototype.slice.call(arguments, 1) : []; + return this.schedule( + new command.Command(command.Name.EXECUTE_SCRIPT). + setParameter('script', script). + setParameter('args', args), + 'WebDriver.executeScript()'); + } + + /** + * Schedules a command to execute asynchronous JavaScript in the context of the + * currently selected frame or window. The script fragment will be executed as + * the body of an anonymous function. If the script is provided as a function + * object, that function will be converted to a string for injection into the + * target window. + * + * Any arguments provided in addition to the script will be included as script + * arguments and may be referenced using the {@code arguments} object. + * Arguments may be a boolean, number, string, or {@code WebElement}. + * Arrays and objects may also be used as script arguments as long as each item + * adheres to the types previously mentioned. + * + * Unlike executing synchronous JavaScript with {@link #executeScript}, + * scripts executed with this function must explicitly signal they are finished + * by invoking the provided callback. This callback will always be injected + * into the executed function as the last argument, and thus may be referenced + * with {@code arguments[arguments.length - 1]}. The following steps will be + * taken for resolving this functions return value against the first argument + * to the script's callback function: + * + * - For a HTML element, the value will resolve to a + * {@link WebElement} + * - Null and undefined return values will resolve to null + * - Booleans, numbers, and strings will resolve as is + * - Functions will resolve to their string representation + * - For arrays and objects, each member item will be converted according to + * the rules above + * + * __Example #1:__ Performing a sleep that is synchronized with the currently + * selected window: + * + * var start = new Date().getTime(); + * driver.executeAsyncScript( + * 'window.setTimeout(arguments[arguments.length - 1], 500);'). + * then(function() { + * console.log( + * 'Elapsed time: ' + (new Date().getTime() - start) + ' ms'); + * }); + * + * __Example #2:__ Synchronizing a test with an AJAX application: + * + * var button = driver.findElement(By.id('compose-button')); + * button.click(); + * driver.executeAsyncScript( + * 'var callback = arguments[arguments.length - 1];' + + * 'mailClient.getComposeWindowWidget().onload(callback);'); + * driver.switchTo().frame('composeWidget'); + * driver.findElement(By.id('to')).sendKeys('dog@example.com'); + * + * __Example #3:__ Injecting a XMLHttpRequest and waiting for the result. In + * this example, the inject script is specified with a function literal. When + * using this format, the function is converted to a string for injection, so it + * should not reference any symbols not defined in the scope of the page under + * test. + * + * driver.executeAsyncScript(function() { + * var callback = arguments[arguments.length - 1]; + * var xhr = new XMLHttpRequest(); + * xhr.open("GET", "/resource/data.json", true); + * xhr.onreadystatechange = function() { + * if (xhr.readyState == 4) { + * callback(xhr.responseText); + * } + * }; + * xhr.send(''); + * }).then(function(str) { + * console.log(JSON.parse(str)['food']); + * }); + * + * @param {!(string|Function)} script The script to execute. + * @param {...*} var_args The arguments to pass to the script. + * @return {!promise.Promise} A promise that will resolve to the + * scripts return value. + * @template T + */ + executeAsyncScript(script, var_args) { + if (typeof script === 'function') { + script = 'return (' + script + ').apply(null, arguments);'; + } + let args = Array.prototype.slice.call(arguments, 1); + return this.schedule( + new command.Command(command.Name.EXECUTE_ASYNC_SCRIPT). + setParameter('script', script). + setParameter('args', args), + 'WebDriver.executeScript()'); + } + + /** + * Schedules a command to execute a custom function. + * @param {function(...): (T|promise.Promise)} fn The function to + * execute. + * @param {Object=} opt_scope The object in whose scope to execute the function. + * @param {...*} var_args Any arguments to pass to the function. + * @return {!promise.Promise} A promise that will be resolved' + * with the function's result. + * @template T + */ + call(fn, opt_scope, var_args) { + let args = Array.prototype.slice.call(arguments, 2); + let flow = this.flow_; + return flow.execute(function() { + return promise.fullyResolved(args).then(function(args) { + if (promise.isGenerator(fn)) { + args.unshift(fn, opt_scope); + return promise.consume.apply(null, args); + } + return fn.apply(opt_scope, args); + }); + }, 'WebDriver.call(' + (fn.name || 'function') + ')'); + } + + /** + * Schedules a command to wait for a condition to hold. The condition may be + * specified by a {@link until.Condition}, as a custom function, or as any + * promise-like thenable. + * + * For a {@link until.Condition} or function, the wait will repeatedly + * evaluate the condition until it returns a truthy value. If any errors occur + * while evaluating the condition, they will be allowed to propagate. In the + * event a condition returns a {@link promise.Promise promise}, the polling + * loop will wait for it to be resolved and use the resolved value for whether + * the condition has been satisified. Note the resolution time for a promise + * is factored into whether a wait has timed out. + * + * Note, if the provided condition is a {@link until.WebElementCondition}, then + * the wait will return a {@link WebElementPromise} that will resolve to the + * element that satisified the condition. + * + * *Example:* waiting up to 10 seconds for an element to be present on the + * page. + * + * var button = driver.wait(until.elementLocated(By.id('foo')), 10000); + * button.click(); + * + * This function may also be used to block the command flow on the resolution + * of any thenable promise object. When given a promise, the command will + * simply wait for its resolution before completing. A timeout may be provided + * to fail the command if the promise does not resolve before the timeout + * expires. + * + * *Example:* Suppose you have a function, `startTestServer`, that returns a + * promise for when a server is ready for requests. You can block a WebDriver + * client on this promise with: + * + * var started = startTestServer(); + * driver.wait(started, 5 * 1000, 'Server should start within 5 seconds'); + * driver.get(getServerUrl()); + * + * @param {!(promise.Promise| + * until.Condition| + * function(!WebDriver): T)} condition The condition to + * wait on, defined as a promise, condition object, or a function to + * evaluate as a condition. + * @param {number=} opt_timeout How long to wait for the condition to be true. + * @param {string=} opt_message An optional message to use if the wait times + * out. + * @return {!(promise.Promise|WebElementPromise)} A promise that will be + * resolved with the first truthy value returned by the condition + * function, or rejected if the condition times out. If the input + * input condition is an instance of a {@link until.WebElementCondition}, + * the returned value will be a {@link WebElementPromise}. + * @template T + */ + wait(condition, opt_timeout, opt_message) { + if (promise.isPromise(condition)) { + return this.flow_.wait( + /** @type {!promise.Promise} */(condition), + opt_timeout, opt_message); + } + + var message = opt_message; + var fn = /** @type {!Function} */(condition); + if (condition instanceof until.Condition) { + message = message || condition.description(); + fn = condition.fn; + } + + var driver = this; + var result = this.flow_.wait(function() { + if (promise.isGenerator(fn)) { + return promise.consume(fn, null, [driver]); + } + return fn(driver); + }, opt_timeout, message); + + if (condition instanceof until.WebElementCondition) { + result = new WebElementPromise(this, result.then(function(value) { + if (!(value instanceof WebElement)) { + throw TypeError( + 'WebElementCondition did not resolve to a WebElement: ' + + Object.prototype.toString.call(value)); + } + return value; + })); + } + return result; + } + + /** + * Schedules a command to make the driver sleep for the given amount of time. + * @param {number} ms The amount of time, in milliseconds, to sleep. + * @return {!promise.Promise} A promise that will be resolved + * when the sleep has finished. + */ + sleep(ms) { + return this.flow_.timeout(ms, 'WebDriver.sleep(' + ms + ')'); + } + + /** + * Schedules a command to retrieve they current window handle. + * @return {!promise.Promise} A promise that will be + * resolved with the current window handle. + */ + getWindowHandle() { + return this.schedule( + new command.Command(command.Name.GET_CURRENT_WINDOW_HANDLE), + 'WebDriver.getWindowHandle()'); + } + + /** + * Schedules a command to retrieve the current list of available window handles. + * @return {!promise.Promise.>} A promise that will + * be resolved with an array of window handles. + */ + getAllWindowHandles() { + return this.schedule( + new command.Command(command.Name.GET_WINDOW_HANDLES), + 'WebDriver.getAllWindowHandles()'); + } + + /** + * Schedules a command to retrieve the current page's source. The page source + * returned is a representation of the underlying DOM: do not expect it to be + * formatted or escaped in the same way as the response sent from the web + * server. + * @return {!promise.Promise} A promise that will be + * resolved with the current page source. + */ + getPageSource() { + return this.schedule( + new command.Command(command.Name.GET_PAGE_SOURCE), + 'WebDriver.getPageSource()'); + } + + /** + * Schedules a command to close the current window. + * @return {!promise.Promise} A promise that will be resolved + * when this command has completed. + */ + close() { + return this.schedule(new command.Command(command.Name.CLOSE), + 'WebDriver.close()'); + } + + /** + * Schedules a command to navigate to the given URL. + * @param {string} url The fully qualified URL to open. + * @return {!promise.Promise} A promise that will be resolved + * when the document has finished loading. + */ + get(url) { + return this.navigate().to(url); + } + + /** + * Schedules a command to retrieve the URL of the current page. + * @return {!promise.Promise} A promise that will be + * resolved with the current URL. + */ + getCurrentUrl() { + return this.schedule( + new command.Command(command.Name.GET_CURRENT_URL), + 'WebDriver.getCurrentUrl()'); + } + + /** + * Schedules a command to retrieve the current page's title. + * @return {!promise.Promise} A promise that will be + * resolved with the current page's title. + */ + getTitle() { + return this.schedule(new command.Command(command.Name.GET_TITLE), + 'WebDriver.getTitle()'); + } + + /** + * Schedule a command to find an element on the page. If the element cannot be + * found, a {@link bot.ErrorCode.NO_SUCH_ELEMENT} result will be returned + * by the driver. Unlike other commands, this error cannot be suppressed. In + * other words, scheduling a command to find an element doubles as an assert + * that the element is present on the page. To test whether an element is + * present on the page, use {@link #isElementPresent} instead. + * + * The search criteria for an element may be defined using one of the + * factories in the {@link webdriver.By} namespace, or as a short-hand + * {@link webdriver.By.Hash} object. For example, the following two statements + * are equivalent: + * + * var e1 = driver.findElement(By.id('foo')); + * var e2 = driver.findElement({id:'foo'}); + * + * You may also provide a custom locator function, which takes as input this + * instance and returns a {@link WebElement}, or a promise that will resolve + * to a WebElement. If the returned promise resolves to an array of + * WebElements, WebDriver will use the first element. For example, to find the + * first visible link on a page, you could write: + * + * var link = driver.findElement(firstVisibleLink); + * + * function firstVisibleLink(driver) { + * var links = driver.findElements(By.tagName('a')); + * return promise.filter(links, function(link) { + * return link.isDisplayed(); + * }); + * } + * + * @param {!(by.By|Function)} locator The locator to use. + * @return {!WebElementPromise} A WebElement that can be used to issue + * commands against the located element. If the element is not found, the + * element will be invalidated and all scheduled commands aborted. + */ + findElement(locator) { + let id; + locator = by.checkedLocator(locator); + if (typeof locator === 'function') { + id = this.findElementInternal_(locator, this); + } else { + let cmd = new command.Command(command.Name.FIND_ELEMENT). + setParameter('using', locator.using). + setParameter('value', locator.value); + id = this.schedule(cmd, 'WebDriver.findElement(' + locator + ')'); + } + return new WebElementPromise(this, id); + } + + /** + * @param {!Function} locatorFn The locator function to use. + * @param {!(WebDriver|WebElement)} context The search + * context. + * @return {!promise.Promise.} A + * promise that will resolve to a list of WebElements. + * @private + */ + findElementInternal_(locatorFn, context) { + return this.call(() => locatorFn(context)).then(function(result) { + if (Array.isArray(result)) { + result = result[0]; + } + if (!(result instanceof WebElement)) { + throw new TypeError('Custom locator did not return a WebElement'); + } + return result; + }); + } + + /** + * Schedules a command to test if an element is present on the page. + * + * If given a DOM element, this function will check if it belongs to the + * document the driver is currently focused on. Otherwise, the function will + * test if at least one element can be found with the given search criteria. + * + * @param {!(by.By|Function)} locator The locator to use. + * @return {!promise.Promise} A promise that will resolve + * with whether the element is present on the page. + */ + isElementPresent(locator) { + return this.findElements.apply(this, arguments).then(function(result) { + return !!result.length; + }); + } + + /** + * Schedule a command to search for multiple elements on the page. + * + * @param {!(by.By|Function)} locator The locator to use. + * @return {!promise.Promise.>} A + * promise that will resolve to an array of WebElements. + */ + findElements(locator) { + locator = by.checkedLocator(locator); + if (typeof locator === 'function') { + return this.findElementsInternal_(locator, this); + } else { + let cmd = new command.Command(command.Name.FIND_ELEMENTS). + setParameter('using', locator.using). + setParameter('value', locator.value); + let res = this.schedule(cmd, 'WebDriver.findElements(' + locator + ')'); + return res.thenCatch(function(e) { + if (e instanceof error.NoSuchElementError) { + return []; + } + throw e; + }); + } + } + + /** + * @param {!Function} locatorFn The locator function to use. + * @param {!(WebDriver|WebElement)} context The search context. + * @return {!promise.Promise>} A promise that + * will resolve to an array of WebElements. + * @private + */ + findElementsInternal_(locatorFn, context) { + return this.call(() => locatorFn(context)).then(function(result) { + if (result instanceof WebElement) { + return [result]; + } + + if (!Array.isArray(result)) { + return []; + } + + return result.filter(function(item) { + return item instanceof WebElement; + }); + }); + } + + /** + * Schedule a command to take a screenshot. The driver makes a best effort to + * return a screenshot of the following, in order of preference: + * + * 1. Entire page + * 2. Current window + * 3. Visible portion of the current frame + * 4. The entire display containing the browser + * + * @return {!promise.Promise} A promise that will be + * resolved to the screenshot as a base-64 encoded PNG. + */ + takeScreenshot() { + return this.schedule(new command.Command(command.Name.SCREENSHOT), + 'WebDriver.takeScreenshot()'); + } + + /** + * @return {!Options} The options interface for this instance. + */ + manage() { + return new Options(this); + } + + /** + * @return {!Navigation} The navigation interface for this instance. + */ + navigate() { + return new Navigation(this); + } + + /** + * @return {!TargetLocator} The target locator interface for this + * instance. + */ + switchTo() { + return new TargetLocator(this); + } +} + + +/** + * Interface for navigating back and forth in the browser history. + * + * This class should never be instantiated directly. Insead, obtain an instance + * with + * + * webdriver.navigate() + * + * @see WebDriver#navigate() + */ +class Navigation { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Schedules a command to navigate to a new URL. + * @param {string} url The URL to navigate to. + * @return {!promise.Promise} A promise that will be resolved + * when the URL has been loaded. + */ + to(url) { + return this.driver_.schedule( + new command.Command(command.Name.GET). + setParameter('url', url), + 'WebDriver.navigate().to(' + url + ')'); + } + + /** + * Schedules a command to move backwards in the browser history. + * @return {!promise.Promise} A promise that will be resolved + * when the navigation event has completed. + */ + back() { + return this.driver_.schedule( + new command.Command(command.Name.GO_BACK), + 'WebDriver.navigate().back()'); + } + + /** + * Schedules a command to move forwards in the browser history. + * @return {!promise.Promise} A promise that will be resolved + * when the navigation event has completed. + */ + forward() { + return this.driver_.schedule( + new command.Command(command.Name.GO_FORWARD), + 'WebDriver.navigate().forward()'); + } + + /** + * Schedules a command to refresh the current page. + * @return {!promise.Promise} A promise that will be resolved + * when the navigation event has completed. + */ + refresh() { + return this.driver_.schedule( + new command.Command(command.Name.REFRESH), + 'WebDriver.navigate().refresh()'); + } +} + + +/** + * Provides methods for managing browser and driver state. + * + * This class should never be instantiated directly. Insead, obtain an instance + * with + * + * webdriver.manage() + * + * @see WebDriver#manage() + */ +class Options { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Schedules a command to add a cookie. + * @param {string} name The cookie name. + * @param {string} value The cookie value. + * @param {string=} opt_path The cookie path. + * @param {string=} opt_domain The cookie domain. + * @param {boolean=} opt_isSecure Whether the cookie is secure. + * @param {(number|!Date)=} opt_expiry When the cookie expires. If specified + * as a number, should be in milliseconds since midnight, + * January 1, 1970 UTC. + * @return {!promise.Promise} A promise that will be resolved + * when the cookie has been added to the page. + */ + addCookie(name, value, opt_path, opt_domain, opt_isSecure, opt_expiry) { + // We do not allow '=' or ';' in the name. + if (/[;=]/.test(name)) { + throw new error.InvalidArgumentError( + 'Invalid cookie name "' + name + '"'); + } + + // We do not allow ';' in value. + if (/;/.test(value)) { + throw new error.InvalidArgumentError( + 'Invalid cookie value "' + value + '"'); + } + + var cookieString = name + '=' + value + + (opt_domain ? ';domain=' + opt_domain : '') + + (opt_path ? ';path=' + opt_path : '') + + (opt_isSecure ? ';secure' : ''); + + var expiry; + if (opt_expiry !== void(0)) { + var expiryDate; + if (typeof opt_expiry === 'number') { + expiryDate = new Date(opt_expiry); + } else { + expiryDate = /** @type {!Date} */ (opt_expiry); + opt_expiry = expiryDate.getTime(); + } + cookieString += ';expires=' + expiryDate.toUTCString(); + // Convert from milliseconds to seconds. + expiry = Math.floor(/** @type {number} */ (opt_expiry) / 1000); + } + + return this.driver_.schedule( + new command.Command(command.Name.ADD_COOKIE). + setParameter('cookie', { + 'name': name, + 'value': value, + 'path': opt_path, + 'domain': opt_domain, + 'secure': !!opt_isSecure, + 'expiry': expiry + }), + 'WebDriver.manage().addCookie(' + cookieString + ')'); + } + + /** + * Schedules a command to delete all cookies visible to the current page. + * @return {!promise.Promise} A promise that will be resolved + * when all cookies have been deleted. + */ + deleteAllCookies() { + return this.driver_.schedule( + new command.Command(command.Name.DELETE_ALL_COOKIES), + 'WebDriver.manage().deleteAllCookies()'); + } + + /** + * Schedules a command to delete the cookie with the given name. This command is + * a no-op if there is no cookie with the given name visible to the current + * page. + * @param {string} name The name of the cookie to delete. + * @return {!promise.Promise} A promise that will be resolved + * when the cookie has been deleted. + */ + deleteCookie(name) { + return this.driver_.schedule( + new command.Command(command.Name.DELETE_COOKIE). + setParameter('name', name), + 'WebDriver.manage().deleteCookie(' + name + ')'); + } + + /** + * Schedules a command to retrieve all cookies visible to the current page. + * Each cookie will be returned as a JSON object as described by the WebDriver + * wire protocol. + * @return {!promise.Promise>} A + * promise that will be resolved with the cookies visible to the current page. + */ + getCookies() { + return this.driver_.schedule( + new command.Command(command.Name.GET_ALL_COOKIES), + 'WebDriver.manage().getCookies()'); + } + + /** + * Schedules a command to retrieve the cookie with the given name. Returns null + * if there is no such cookie. The cookie will be returned as a JSON object as + * described by the WebDriver wire protocol. + * + * @param {string} name The name of the cookie to retrieve. + * @return {!promise.Promise} A promise + * that will be resolved with the named cookie, or `null` if there is no + * such cookie. + */ + getCookie(name) { + return this.getCookies().then(function(cookies) { + for (let cookie of cookies) { + if (cookie && cookie['name'] === name) { + return cookie; + } + } + return null; + }); + } + + /** + * @return {!Logs} The interface for managing driver + * logs. + */ + logs() { + return new Logs(this.driver_); + } + + /** + * @return {!Timeouts} The interface for managing driver timeouts. + */ + timeouts() { + return new Timeouts(this.driver_); + } + + /** + * @return {!Window} The interface for managing the current window. + */ + window() { + return new Window(this.driver_); + } +} + + +/** + * A JSON description of a browser cookie. + * @typedef {{ + * name: string, + * value: string, + * path: (string|undefined), + * domain: (string|undefined), + * secure: (boolean|undefined), + * expiry: (number|undefined) + * }} + */ +Options.Cookie; + + +/** + * An interface for managing timeout behavior for WebDriver instances. + * + * This class should never be instantiated directly. Insead, obtain an instance + * with + * + * webdriver.manage().timeouts() + * + * @see WebDriver#manage() + * @see Options#timeouts() + */ +class Timeouts { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Specifies the amount of time the driver should wait when searching for an + * element if it is not immediately present. + * + * When searching for a single element, the driver should poll the page + * until the element has been found, or this timeout expires before failing + * with a {@link bot.ErrorCode.NO_SUCH_ELEMENT} error. When searching + * for multiple elements, the driver should poll the page until at least one + * element has been found or this timeout has expired. + * + * Setting the wait timeout to 0 (its default value), disables implicit + * waiting. + * + * Increasing the implicit wait timeout should be used judiciously as it + * will have an adverse effect on test run time, especially when used with + * slower location strategies like XPath. + * + * @param {number} ms The amount of time to wait, in milliseconds. + * @return {!promise.Promise} A promise that will be resolved + * when the implicit wait timeout has been set. + */ + implicitlyWait(ms) { + return this.driver_.schedule( + new command.Command(command.Name.IMPLICITLY_WAIT). + setParameter('ms', ms < 0 ? 0 : ms), + 'WebDriver.manage().timeouts().implicitlyWait(' + ms + ')'); + } + + /** + * Sets the amount of time to wait, in milliseconds, for an asynchronous + * script to finish execution before returning an error. If the timeout is + * less than or equal to 0, the script will be allowed to run indefinitely. + * + * @param {number} ms The amount of time to wait, in milliseconds. + * @return {!promise.Promise} A promise that will be resolved + * when the script timeout has been set. + */ + setScriptTimeout(ms) { + return this.driver_.schedule( + new command.Command(command.Name.SET_SCRIPT_TIMEOUT). + setParameter('ms', ms < 0 ? 0 : ms), + 'WebDriver.manage().timeouts().setScriptTimeout(' + ms + ')'); + } + + /** + * Sets the amount of time to wait for a page load to complete before + * returning an error. If the timeout is negative, page loads may be + * indefinite. + * + * @param {number} ms The amount of time to wait, in milliseconds. + * @return {!promise.Promise} A promise that will be resolved + * when the timeout has been set. + */ + pageLoadTimeout(ms) { + return this.driver_.schedule( + new command.Command(command.Name.SET_TIMEOUT). + setParameter('type', 'page load'). + setParameter('ms', ms), + 'WebDriver.manage().timeouts().pageLoadTimeout(' + ms + ')'); + } +} + + +/** + * An interface for managing the current window. + * + * This class should never be instantiated directly. Insead, obtain an instance + * with + * + * webdriver.manage().window() + * + * @see WebDriver#manage() + * @see Options#window() + */ +class Window { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Retrieves the window's current position, relative to the top left corner of + * the screen. + * @return {!promise.Promise.<{x: number, y: number}>} A promise + * that will be resolved with the window's position in the form of a + * {x:number, y:number} object literal. + */ + getPosition() { + return this.driver_.schedule( + new command.Command(command.Name.GET_WINDOW_POSITION). + setParameter('windowHandle', 'current'), + 'WebDriver.manage().window().getPosition()'); + } + + /** + * Repositions the current window. + * @param {number} x The desired horizontal position, relative to the left + * side of the screen. + * @param {number} y The desired vertical position, relative to the top of the + * of the screen. + * @return {!promise.Promise} A promise that will be resolved + * when the command has completed. + */ + setPosition(x, y) { + return this.driver_.schedule( + new command.Command(command.Name.SET_WINDOW_POSITION). + setParameter('windowHandle', 'current'). + setParameter('x', x). + setParameter('y', y), + 'WebDriver.manage().window().setPosition(' + x + ', ' + y + ')'); + } + + /** + * Retrieves the window's current size. + * @return {!promise.Promise<{width: number, height: number}>} A + * promise that will be resolved with the window's size in the form of a + * {width:number, height:number} object literal. + */ + getSize() { + return this.driver_.schedule( + new command.Command(command.Name.GET_WINDOW_SIZE). + setParameter('windowHandle', 'current'), + 'WebDriver.manage().window().getSize()'); + } + + /** + * Resizes the current window. + * @param {number} width The desired window width. + * @param {number} height The desired window height. + * @return {!promise.Promise} A promise that will be resolved + * when the command has completed. + */ + setSize(width, height) { + return this.driver_.schedule( + new command.Command(command.Name.SET_WINDOW_SIZE). + setParameter('windowHandle', 'current'). + setParameter('width', width). + setParameter('height', height), + 'WebDriver.manage().window().setSize(' + width + ', ' + height + ')'); + } + + /** + * Maximizes the current window. + * @return {!promise.Promise} A promise that will be resolved + * when the command has completed. + */ + maximize() { + return this.driver_.schedule( + new command.Command(command.Name.MAXIMIZE_WINDOW). + setParameter('windowHandle', 'current'), + 'WebDriver.manage().window().maximize()'); + } +} + + +/** + * Interface for managing WebDriver log records. + * + * This class should never be instantiated directly. Instead, obtain an + * instance with + * + * webdriver.manage().logs() + * + * @see WebDriver#manage() + * @see Options#logs() + */ +class Logs { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Fetches available log entries for the given type. + * + * Note that log buffers are reset after each call, meaning that available + * log entries correspond to those entries not yet returned for a given log + * type. In practice, this means that this call will return the available log + * entries since the last call, or from the start of the session. + * + * @param {!logging.Type} type The desired log type. + * @return {!promise.Promise.>} A + * promise that will resolve to a list of log entries for the specified + * type. + */ + get(type) { + let cmd = new command.Command(command.Name.GET_LOG). + setParameter('type', type); + return this.driver_.schedule( + cmd, 'WebDriver.manage().logs().get(' + type + ')'). + then(function(entries) { + return entries.map(function(entry) { + if (!(entry instanceof logging.Entry)) { + return new logging.Entry( + entry['level'], entry['message'], entry['timestamp'], + entry['type']); + } + return entry; + }); + }); + } + + /** + * Retrieves the log types available to this driver. + * @return {!promise.Promise>} A + * promise that will resolve to a list of available log types. + */ + getAvailableLogTypes() { + return this.driver_.schedule( + new command.Command(command.Name.GET_AVAILABLE_LOG_TYPES), + 'WebDriver.manage().logs().getAvailableLogTypes()'); + } +} + + +/** + * An interface for changing the focus of the driver to another frame or window. + * + * This class should never be instantiated directly. Instead, obtain an + * instance with + * + * webdriver.switchTo() + * + * @see WebDriver#switchTo() + */ +class TargetLocator { + /** + * @param {!WebDriver} driver The parent driver. + * @private + */ + constructor(driver) { + /** @private {!WebDriver} */ + this.driver_ = driver; + } + + /** + * Schedules a command retrieve the {@code document.activeElement} element on + * the current document, or {@code document.body} if activeElement is not + * available. + * @return {!WebElementPromise} The active element. + */ + activeElement() { + var id = this.driver_.schedule( + new command.Command(command.Name.GET_ACTIVE_ELEMENT), + 'WebDriver.switchTo().activeElement()'); + return new WebElementPromise(this.driver_, id); + } + + /** + * Schedules a command to switch focus of all future commands to the topmost + * frame on the page. + * @return {!promise.Promise} A promise that will be resolved + * when the driver has changed focus to the default content. + */ + defaultContent() { + return this.driver_.schedule( + new command.Command(command.Name.SWITCH_TO_FRAME). + setParameter('id', null), + 'WebDriver.switchTo().defaultContent()'); + } + + /** + * Schedules a command to switch the focus of all future commands to another + * frame on the page. The target frame may be specified as one of the + * following: + * + * - A number that specifies a (zero-based) index into [window.frames]( + * https://developer.mozilla.org/en-US/docs/Web/API/Window.frames). + * - A {@link WebElement} reference, which correspond to a `frame` or `iframe` + * DOM element. + * - The `null` value, to select the topmost frame on the page. Passing `null` + * is the same as calling {@link #defaultContent defaultContent()}. + * + * If the specified frame can not be found, the returned promise will be + * rejected with a {@linkplain error.NoSuchFrameError}. + * + * @param {(number|WebElement|null)} id The frame locator. + * @return {!promise.Promise} A promise that will be resolved + * when the driver has changed focus to the specified frame. + */ + frame(id) { + return this.driver_.schedule( + new command.Command(command.Name.SWITCH_TO_FRAME). + setParameter('id', id), + 'WebDriver.switchTo().frame(' + id + ')'); + } + + /** + * Schedules a command to switch the focus of all future commands to another + * window. Windows may be specified by their {@code window.name} attribute or + * by its handle (as returned by {@link WebDriver#getWindowHandles}). + * + * If the specified window cannot be found, the returned promise will be + * rejected with a {@linkplain error.NoSuchWindowError}. + * + * @param {string} nameOrHandle The name or window handle of the window to + * switch focus to. + * @return {!promise.Promise} A promise that will be resolved + * when the driver has changed focus to the specified window. + */ + window(nameOrHandle) { + return this.driver_.schedule( + new command.Command(command.Name.SWITCH_TO_WINDOW). + setParameter('name', nameOrHandle), + 'WebDriver.switchTo().window(' + nameOrHandle + ')'); + } + + /** + * Schedules a command to change focus to the active modal dialog, such as + * those opened by `window.alert()`, `window.confirm()`, and + * `window.prompt()`. The returned promise will be rejected with a + * {@linkplain error.NoSuchAlertError} if there are no open alerts. + * + * @return {!AlertPromise} The open alert. + */ + alert() { + var text = this.driver_.schedule( + new command.Command(command.Name.GET_ALERT_TEXT), + 'WebDriver.switchTo().alert()'); + var driver = this.driver_; + return new AlertPromise(driver, text.then(function(text) { + return new Alert(driver, text); + })); + } +} + + +////////////////////////////////////////////////////////////////////////////// +// +// WebElement +// +////////////////////////////////////////////////////////////////////////////// + + +const LEGACY_ELEMENT_ID_KEY = 'ELEMENT'; +const ELEMENT_ID_KEY = 'element-6066-11e4-a52e-4f735466cecf'; + + +/** + * Represents a DOM element. WebElements can be found by searching from the + * document root using a {@link WebDriver} instance, or by searching + * under another WebElement: + * + * driver.get('http://www.google.com'); + * var searchForm = driver.findElement(By.tagName('form')); + * var searchBox = searchForm.findElement(By.name('q')); + * searchBox.sendKeys('webdriver'); + */ +class WebElement { + /** + * @param {!WebDriver} driver the parent WebDriver instance for this element. + * @param {(!IThenable|string)} id The server-assigned opaque ID for + * the underlying DOM element. + */ + constructor(driver, id) { + /** @private {!WebDriver} */ + this.driver_ = driver; + + /** @private {!promise.Promise} */ + this.id_ = promise.fulfilled(id); + } + + /** + * @param {string} id The raw ID. + * @return {!Object} The element ID for use with WebDriver's wire protocol. + */ + static buildId(id) { + return {[ELEMENT_ID_KEY]: id, [LEGACY_ELEMENT_ID_KEY]: id}; + } + + /** + * Extracts the encoded WebElement ID from the object. + * + * @param {?} obj The object to extract the ID from. + * @return {string} the extracted ID. + * @throws {TypeError} if the object is not a valid encoded ID. + */ + static extractId(obj) { + if (obj && typeof obj === 'object') { + if (typeof obj[ELEMENT_ID_KEY] === 'string') { + return obj[ELEMENT_ID_KEY]; + } else if (typeof obj[LEGACY_ELEMENT_ID_KEY] === 'string') { + return obj[LEGACY_ELEMENT_ID_KEY]; + } + } + throw new TypeError('object is not a WebElement ID'); + } + + /** + * @param {?} obj the object to test. + * @return {boolean} whether the object is a valid encoded WebElement ID. + */ + static isId(obj) { + return obj && typeof obj === 'object' + && (typeof obj[ELEMENT_ID_KEY] === 'string' + || typeof obj[LEGACY_ELEMENT_ID_KEY] === 'string'); + } + + /** + * Compares two WebElements for equality. + * + * @param {!WebElement} a A WebElement. + * @param {!WebElement} b A WebElement. + * @return {!promise.Promise} A promise that will be + * resolved to whether the two WebElements are equal. + */ + static equals(a, b) { + if (a === b) { + return promise.fulfilled(true); + } + let ids = [a.getId(), b.getId()]; + return promise.all(ids).then(function(ids) { + // If the two element's have the same ID, they should be considered + // equal. Otherwise, they may still be equivalent, but we'll need to + // ask the server to check for us. + if (ids[0] === ids[1]) { + return true; + } + + let cmd = new command.Command(command.Name.ELEMENT_EQUALS); + cmd.setParameter('id', ids[0]); + cmd.setParameter('other', ids[1]); + return a.driver_.schedule(cmd, 'WebElement.equals()'); + }); + } + + /** @return {!WebDriver} The parent driver for this instance. */ + getDriver() { + return this.driver_; + } + + /** + * @return {!promise.Promise} A promise that resolves to + * the server-assigned opaque ID assigned to this element. + */ + getId() { + return this.id_; + } + + /** + * @deprecated Use {@link #getId()} instead. + */ + getRawId() { + return this.getId(); + } + + /** + * @return {!Object} Returns the serialized representation of this WebElement. + */ + [Symbols.serialize]() { + return this.getId().then(WebElement.buildId); + } + + /** + * Schedules a command that targets this element with the parent WebDriver + * instance. Will ensure this element's ID is included in the command + * parameters under the "id" key. + * + * @param {!command.Command} command The command to schedule. + * @param {string} description A description of the command for debugging. + * @return {!promise.Promise} A promise that will be resolved + * with the command result. + * @template T + * @see WebDriver#schedule + * @private + */ + schedule_(command, description) { + command.setParameter('id', this.getId()); + return this.driver_.schedule(command, description); + } + + /** + * Schedule a command to find a descendant of this element. If the element + * cannot be found, the returned promise will be rejected with a + * {@linkplain error.NoSuchElementError NoSuchElementError}. + * + * The search criteria for an element may be defined using one of the static + * factories on the {@link by.By} class, or as a short-hand + * {@link ./by.ByHash} object. For example, the following two statements + * are equivalent: + * + * var e1 = element.findElement(By.id('foo')); + * var e2 = element.findElement({id:'foo'}); + * + * You may also provide a custom locator function, which takes as input this + * instance and returns a {@link WebElement}, or a promise that will resolve + * to a WebElement. If the returned promise resolves to an array of + * WebElements, WebDriver will use the first element. For example, to find the + * first visible link on a page, you could write: + * + * var link = element.findElement(firstVisibleLink); + * + * function firstVisibleLink(element) { + * var links = element.findElements(By.tagName('a')); + * return promise.filter(links, function(link) { + * return link.isDisplayed(); + * }); + * } + * + * @param {!(by.By|Function)} locator The locator strategy to use when + * searching for the element. + * @return {!WebElementPromise} A WebElement that can be used to issue + * commands against the located element. If the element is not found, the + * element will be invalidated and all scheduled commands aborted. + */ + findElement(locator) { + locator = by.checkedLocator(locator); + let id; + if (typeof locator === 'function') { + id = this.driver_.findElementInternal_(locator, this); + } else { + let cmd = new command.Command( + command.Name.FIND_CHILD_ELEMENT). + setParameter('using', locator.using). + setParameter('value', locator.value); + id = this.schedule_(cmd, 'WebElement.findElement(' + locator + ')'); + } + return new WebElementPromise(this.driver_, id); + } + + /** + * Schedules a command to test if there is at least one descendant of this + * element that matches the given search criteria. + * + * @param {!(by.By|Function)} locator The locator strategy to use when + * searching for the element. + * @return {!promise.Promise} A promise that will be + * resolved with whether an element could be located on the page. + */ + isElementPresent(locator) { + return this.findElements(locator).then(function(result) { + return !!result.length; + }); + } + + /** + * Schedules a command to find all of the descendants of this element that + * match the given search criteria. + * + * @param {!(by.By|Function)} locator The locator strategy to use when + * searching for the element. + * @return {!promise.Promise>} A + * promise that will resolve to an array of WebElements. + */ + findElements(locator) { + locator = by.checkedLocator(locator); + let id; + if (typeof locator === 'function') { + return this.driver_.findElementsInternal_(locator, this); + } else { + var cmd = new command.Command( + command.Name.FIND_CHILD_ELEMENTS). + setParameter('using', locator.using). + setParameter('value', locator.value); + return this.schedule_(cmd, 'WebElement.findElements(' + locator + ')'); + } + } + + /** + * Schedules a command to click on this element. + * @return {!promise.Promise} A promise that will be resolved + * when the click command has completed. + */ + click() { + return this.schedule_( + new command.Command(command.Name.CLICK_ELEMENT), + 'WebElement.click()'); + } + + /** + * Schedules a command to type a sequence on the DOM element represented by + * this instance. + * + * Modifier keys (SHIFT, CONTROL, ALT, META) are stateful; once a modifier is + * processed in the keysequence, that key state is toggled until one of the + * following occurs: + * + * - The modifier key is encountered again in the sequence. At this point the + * state of the key is toggled (along with the appropriate keyup/down + * events). + * - The {@link input.Key.NULL} key is encountered in the sequence. When + * this key is encountered, all modifier keys current in the down state are + * released (with accompanying keyup events). The NULL key can be used to + * simulate common keyboard shortcuts: + * + * element.sendKeys("text was", + * Key.CONTROL, "a", Key.NULL, + * "now text is"); + * // Alternatively: + * element.sendKeys("text was", + * Key.chord(Key.CONTROL, "a"), + * "now text is"); + * + * - The end of the keysequence is encountered. When there are no more keys + * to type, all depressed modifier keys are released (with accompanying + * keyup events). + * + * If this element is a file input ({@code }), the + * specified key sequence should specify the path to the file to attach to + * the element. This is analgous to the user clicking "Browse..." and entering + * the path into the file select dialog. + * + * var form = driver.findElement(By.css('form')); + * var element = form.findElement(By.css('input[type=file]')); + * element.sendKeys('/path/to/file.txt'); + * form.submit(); + * + * For uploads to function correctly, the entered path must reference a file + * on the _browser's_ machine, not the local machine running this script. When + * running against a remote Selenium server, a {@link input.FileDetector} + * may be used to transparently copy files to the remote machine before + * attempting to upload them in the browser. + * + * __Note:__ On browsers where native keyboard events are not supported + * (e.g. Firefox on OS X), key events will be synthesized. Special + * punctionation keys will be synthesized according to a standard QWERTY en-us + * keyboard layout. + * + * @param {...(string|!promise.Promise)} var_args The + * sequence of keys to type. All arguments will be joined into a single + * sequence. + * @return {!promise.Promise} A promise that will be resolved + * when all keys have been typed. + */ + sendKeys(var_args) { + // Coerce every argument to a string. This protects us from users that + // ignore the jsdoc and give us a number (which ends up causing problems on + // the server, which requires strings). + let keys = promise.all(Array.prototype.slice.call(arguments, 0)). + then(keys => keys.map(String)); + if (!this.driver_.fileDetector_) { + return this.schedule_( + new command.Command(command.Name.SEND_KEYS_TO_ELEMENT). + setParameter('value', keys), + 'WebElement.sendKeys()'); + } + + // Suppress unhandled rejection errors until the flow executes the command. + keys.thenCatch(function() {}); + + var element = this; + return this.driver_.flow_.execute(function() { + return keys.then(function(keys) { + return element.driver_.fileDetector_ + .handleFile(element.driver_, keys.join('')); + }).then(function(keys) { + return element.schedule_( + new command.Command(command.Name.SEND_KEYS_TO_ELEMENT). + setParameter('value', [keys]), + 'WebElement.sendKeys()'); + }); + }, 'WebElement.sendKeys()'); + } + + /** + * Schedules a command to query for the tag/node name of this element. + * @return {!promise.Promise} A promise that will be + * resolved with the element's tag name. + */ + getTagName() { + return this.schedule_( + new command.Command(command.Name.GET_ELEMENT_TAG_NAME), + 'WebElement.getTagName()'); + } + + /** + * Schedules a command to query for the computed style of the element + * represented by this instance. If the element inherits the named style from + * its parent, the parent will be queried for its value. Where possible, color + * values will be converted to their hex representation (e.g. #00ff00 instead of + * rgb(0, 255, 0)). + * + * _Warning:_ the value returned will be as the browser interprets it, so + * it may be tricky to form a proper assertion. + * + * @param {string} cssStyleProperty The name of the CSS style property to look + * up. + * @return {!promise.Promise} A promise that will be + * resolved with the requested CSS value. + */ + getCssValue(cssStyleProperty) { + var name = command.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY; + return this.schedule_( + new command.Command(name). + setParameter('propertyName', cssStyleProperty), + 'WebElement.getCssValue(' + cssStyleProperty + ')'); + } + + /** + * Schedules a command to query for the value of the given attribute of the + * element. Will return the current value, even if it has been modified after + * the page has been loaded. More exactly, this method will return the value of + * the given attribute, unless that attribute is not present, in which case the + * value of the property with the same name is returned. If neither value is + * set, null is returned (for example, the "value" property of a textarea + * element). The "style" attribute is converted as best can be to a + * text representation with a trailing semi-colon. The following are deemed to + * be "boolean" attributes and will return either "true" or null: + * + * async, autofocus, autoplay, checked, compact, complete, controls, declare, + * defaultchecked, defaultselected, defer, disabled, draggable, ended, + * formnovalidate, hidden, indeterminate, iscontenteditable, ismap, itemscope, + * loop, multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open, + * paused, pubdate, readonly, required, reversed, scoped, seamless, seeking, + * selected, spellcheck, truespeed, willvalidate + * + * Finally, the following commonly mis-capitalized attribute/property names + * are evaluated as expected: + * + * - "class" + * - "readonly" + * + * @param {string} attributeName The name of the attribute to query. + * @return {!promise.Promise} A promise that will be + * resolved with the attribute's value. The returned value will always be + * either a string or null. + */ + getAttribute(attributeName) { + return this.schedule_( + new command.Command(command.Name.GET_ELEMENT_ATTRIBUTE). + setParameter('name', attributeName), + 'WebElement.getAttribute(' + attributeName + ')'); + } + + /** + * Get the visible (i.e. not hidden by CSS) innerText of this element, including + * sub-elements, without any leading or trailing whitespace. + * @return {!promise.Promise} A promise that will be + * resolved with the element's visible text. + */ + getText() { + return this.schedule_( + new command.Command(command.Name.GET_ELEMENT_TEXT), + 'WebElement.getText()'); + } + + /** + * Schedules a command to compute the size of this element's bounding box, in + * pixels. + * @return {!promise.Promise.<{width: number, height: number}>} A + * promise that will be resolved with the element's size as a + * {@code {width:number, height:number}} object. + */ + getSize() { + return this.schedule_( + new command.Command(command.Name.GET_ELEMENT_SIZE), + 'WebElement.getSize()'); + } + + /** + * Schedules a command to compute the location of this element in page space. + * @return {!promise.Promise.<{x: number, y: number}>} A promise that + * will be resolved to the element's location as a + * {@code {x:number, y:number}} object. + */ + getLocation() { + return this.schedule_( + new command.Command(command.Name.GET_ELEMENT_LOCATION), + 'WebElement.getLocation()'); + } + + /** + * Schedules a command to query whether the DOM element represented by this + * instance is enabled, as dicted by the {@code disabled} attribute. + * @return {!promise.Promise} A promise that will be + * resolved with whether this element is currently enabled. + */ + isEnabled() { + return this.schedule_( + new command.Command(command.Name.IS_ELEMENT_ENABLED), + 'WebElement.isEnabled()'); + } + + /** + * Schedules a command to query whether this element is selected. + * @return {!promise.Promise} A promise that will be + * resolved with whether this element is currently selected. + */ + isSelected() { + return this.schedule_( + new command.Command(command.Name.IS_ELEMENT_SELECTED), + 'WebElement.isSelected()'); + } + + /** + * Schedules a command to submit the form containing this element (or this + * element if it is a FORM element). This command is a no-op if the element is + * not contained in a form. + * @return {!promise.Promise} A promise that will be resolved + * when the form has been submitted. + */ + submit() { + return this.schedule_( + new command.Command(command.Name.SUBMIT_ELEMENT), + 'WebElement.submit()'); + } + + /** + * Schedules a command to clear the `value` of this element. This command has + * no effect if the underlying DOM element is neither a text INPUT element + * nor a TEXTAREA element. + * @return {!promise.Promise} A promise that will be resolved + * when the element has been cleared. + */ + clear() { + return this.schedule_( + new command.Command(command.Name.CLEAR_ELEMENT), + 'WebElement.clear()'); + } + + /** + * Schedules a command to test whether this element is currently displayed. + * @return {!promise.Promise} A promise that will be + * resolved with whether this element is currently visible on the page. + */ + isDisplayed() { + return this.schedule_( + new command.Command(command.Name.IS_ELEMENT_DISPLAYED), + 'WebElement.isDisplayed()'); + } + + /** + * Take a screenshot of the visible region encompassed by this element's + * bounding rectangle. + * + * @param {boolean=} opt_scroll Optional argument that indicates whether the + * element should be scrolled into view before taking a screenshot. + * Defaults to false. + * @return {!promise.Promise} A promise that will be + * resolved to the screenshot as a base-64 encoded PNG. + */ + takeScreenshot(opt_scroll) { + var scroll = !!opt_scroll; + return this.schedule_( + new command.Command(command.Name.TAKE_ELEMENT_SCREENSHOT) + .setParameter('scroll', scroll), + 'WebElement.takeScreenshot(' + scroll + ')'); + } + + /** + * Schedules a command to retrieve the outer HTML of this element. + * @return {!promise.Promise} A promise that will be + * resolved with the element's outer HTML. + */ + getOuterHtml() { + return this.driver_.executeScript(function() { + var element = arguments[0]; + if ('outerHTML' in element) { + return element.outerHTML; + } else { + var div = element.ownerDocument.createElement('div'); + div.appendChild(element.cloneNode(true)); + return div.innerHTML; + } + }, this); + } + + /** + * Schedules a command to retrieve the inner HTML of this element. + * @return {!promise.Promise} A promise that will be + * resolved with the element's inner HTML. + */ + getInnerHtml() { + return this.driver_.executeScript('return arguments[0].innerHTML', this); + } +} + + +/** + * WebElementPromise is a promise that will be fulfilled with a WebElement. + * This serves as a forward proxy on WebElement, allowing calls to be + * scheduled without directly on this instance before the underlying + * WebElement has been fulfilled. In other words, the following two statements + * are equivalent: + * + * driver.findElement({id: 'my-button'}).click(); + * driver.findElement({id: 'my-button'}).then(function(el) { + * return el.click(); + * }); + * + * @implements {promise.Thenable} + * @final + */ +class WebElementPromise extends WebElement { + /** + * @param {!WebDriver} driver The parent WebDriver instance for this + * element. + * @param {!promise.Promise} el A promise + * that will resolve to the promised element. + */ + constructor(driver, el) { + super(driver, 'unused'); + + /** @override */ + this.cancel = el.cancel.bind(el); + + /** @override */ + this.isPending = el.isPending.bind(el); + + /** @override */ + this.then = el.then.bind(el); + + /** @override */ + this.catch = el.catch.bind(el); + + /** @override */ + this.thenCatch = el.thenCatch.bind(el); + + /** @override */ + this.thenFinally = el.thenFinally.bind(el); + + /** + * Defers returning the element ID until the wrapped WebElement has been + * resolved. + * @override + */ + this.getId = function() { + return el.then(function(el) { + return el.getId(); + }); + }; + } +} +promise.Thenable.addImplementation(WebElementPromise); + + +////////////////////////////////////////////////////////////////////////////// +// +// Alert +// +////////////////////////////////////////////////////////////////////////////// + + +/** + * Represents a modal dialog such as {@code alert}, {@code confirm}, or + * {@code prompt}. Provides functions to retrieve the message displayed with + * the alert, accept or dismiss the alert, and set the response text (in the + * case of {@code prompt}). + */ +class Alert { + /** + * @param {!WebDriver} driver The driver controlling the browser this alert + * is attached to. + * @param {string} text The message text displayed with this alert. + */ + constructor(driver, text) { + /** @private {!WebDriver} */ + this.driver_ = driver; + + /** @private {!promise.Promise} */ + this.text_ = promise.fulfilled(text); + } + + /** + * Retrieves the message text displayed with this alert. For instance, if the + * alert were opened with alert("hello"), then this would return "hello". + * + * @return {!promise.Promise} A promise that will be + * resolved to the text displayed with this alert. + */ + getText() { + return this.text_; + } + + /** + * Accepts this alert. + * + * @return {!promise.Promise} A promise that will be resolved + * when this command has completed. + */ + accept() { + return this.driver_.schedule( + new command.Command(command.Name.ACCEPT_ALERT), + 'WebDriver.switchTo().alert().accept()'); + } + + /** + * Dismisses this alert. + * + * @return {!promise.Promise} A promise that will be resolved + * when this command has completed. + */ + dismiss() { + return this.driver_.schedule( + new command.Command(command.Name.DISMISS_ALERT), + 'WebDriver.switchTo().alert().dismiss()'); + } + + /** + * Sets the response text on this alert. This command will return an error if + * the underlying alert does not support response text (e.g. window.alert and + * window.confirm). + * + * @param {string} text The text to set. + * @return {!promise.Promise} A promise that will be resolved + * when this command has completed. + */ + sendKeys(text) { + return this.driver_.schedule( + new command.Command(command.Name.SET_ALERT_TEXT). + setParameter('text', text), + 'WebDriver.switchTo().alert().sendKeys(' + text + ')'); + } +} + + +/** + * AlertPromise is a promise that will be fulfilled with an Alert. This promise + * serves as a forward proxy on an Alert, allowing calls to be scheduled + * directly on this instance before the underlying Alert has been fulfilled. In + * other words, the following two statements are equivalent: + * + * driver.switchTo().alert().dismiss(); + * driver.switchTo().alert().then(function(alert) { + * return alert.dismiss(); + * }); + * + * @implements {promise.Thenable.} + * @final + */ +class AlertPromise extends Alert { + /** + * @param {!WebDriver} driver The driver controlling the browser this + * alert is attached to. + * @param {!promise.Thenable} alert A thenable + * that will be fulfilled with the promised alert. + */ + constructor(driver, alert) { + super(driver, 'unused'); + + /** @override */ + this.cancel = alert.cancel.bind(alert); + + /** @override */ + this.isPending = alert.isPending.bind(alert); + + /** @override */ + this.then = alert.then.bind(alert); + + /** @override */ + this.catch = alert.catch.bind(alert); + + /** @override */ + this.thenCatch = alert.thenCatch.bind(alert); + + /** @override */ + this.thenFinally = alert.thenFinally.bind(alert); + + /** + * Defer returning text until the promised alert has been resolved. + * @override + */ + this.getText = function() { + return alert.then(function(alert) { + return alert.getText(); + }); + }; + + /** + * Defers action until the alert has been located. + * @override + */ + this.accept = function() { + return alert.then(function(alert) { + return alert.accept(); + }); + }; + + /** + * Defers action until the alert has been located. + * @override + */ + this.dismiss = function() { + return alert.then(function(alert) { + return alert.dismiss(); + }); + }; + + /** + * Defers action until the alert has been located. + * @override + */ + this.sendKeys = function(text) { + return alert.then(function(alert) { + return alert.sendKeys(text); + }); + }; + } +} +promise.Thenable.addImplementation(AlertPromise); + + +// PUBLIC API + + +exports.Alert = Alert; +exports.AlertPromise = AlertPromise; +exports.Logs = Logs; +exports.Navigation = Navigation; +exports.Options = Options; +exports.TargetLocator = TargetLocator; +exports.Timeouts = Timeouts; +/** @deprecated Use {@link error.UnexpectedAlertOpenError} instead. */ +exports.UnhandledAlertError = error.UnexpectedAlertOpenError; +exports.WebDriver = WebDriver; +exports.WebElement = WebElement; +exports.WebElementPromise = WebElementPromise; +exports.Window = Window; diff --git a/www/node_modules/selenium-webdriver/net/index.js b/www/node_modules/selenium-webdriver/net/index.js new file mode 100644 index 0000000..4142ebc --- /dev/null +++ b/www/node_modules/selenium-webdriver/net/index.js @@ -0,0 +1,82 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var os = require('os'); + + +function getLoInterface() { + var name; + if (process.platform === 'darwin') { + name = 'lo0'; + } else if (process.platform === 'linux') { + name = 'lo'; + } + return name ? os.networkInterfaces()[name] : null; +} + + +/** + * Queries the system network interfaces for an IP address. + * @param {boolean} loopback Whether to find a loopback address. + * @param {string=} opt_family The IP family (IPv4 or IPv6). Defaults to IPv4. + * @return {string} The located IP address or undefined. + */ +function getAddress(loopback, opt_family) { + var family = opt_family || 'IPv4'; + var addresses = []; + + var interfaces; + if (loopback) { + var lo = getLoInterface(); + interfaces = lo ? [lo] : null; + } + interfaces = interfaces || os.networkInterfaces(); + for (var key in interfaces) { + interfaces[key].forEach(function(ipAddress) { + if (ipAddress.family === family && + ipAddress.internal === loopback) { + addresses.push(ipAddress.address); + } + }); + } + return addresses[0]; +} + + +// PUBLIC API + + +/** + * Retrieves the external IP address for this host. + * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4". + * @return {string} The IP address or undefined if not available. + */ +exports.getAddress = function(opt_family) { + return getAddress(false, opt_family); +}; + + +/** + * Retrieves a loopback address for this machine. + * @param {string=} opt_family The IP family to retrieve. Defaults to "IPv4". + * @return {string} The IP address or undefined if not available. + */ +exports.getLoopbackAddress = function(opt_family) { + return getAddress(true, opt_family); +}; diff --git a/www/node_modules/selenium-webdriver/net/portprober.js b/www/node_modules/selenium-webdriver/net/portprober.js new file mode 100644 index 0000000..f455ede --- /dev/null +++ b/www/node_modules/selenium-webdriver/net/portprober.js @@ -0,0 +1,219 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var exec = require('child_process').exec, + fs = require('fs'), + net = require('net'); + +var promise = require('../lib/promise'); + + +/** + * The IANA suggested ephemeral port range. + * @type {{min: number, max: number}} + * @const + * @see http://en.wikipedia.org/wiki/Ephemeral_ports + */ +var DEFAULT_IANA_RANGE = {min: 49152, max: 65535}; + + +/** + * The epheremal port range for the current system. Lazily computed on first + * access. + * @type {promise.Promise.<{min: number, max: number}>} + */ +var systemRange = null; + + +/** + * Computes the ephemeral port range for the current system. This is based on + * http://stackoverflow.com/a/924337. + * @return {promise.Promise.<{min: number, max: number}>} A promise + * that will resolve to the ephemeral port range of the current system. + */ +function findSystemPortRange() { + if (systemRange) { + return systemRange; + } + var range = process.platform === 'win32' ? + findWindowsPortRange() : findUnixPortRange(); + return systemRange = range.thenCatch(function() { + return DEFAULT_IANA_RANGE; + }); +} + + +/** + * Executes a command and returns its output if it succeeds. + * @param {string} cmd The command to execute. + * @return {!promise.Promise.} A promise that will resolve + * with the command's stdout data. + */ +function execute(cmd) { + var result = promise.defer(); + exec(cmd, function(err, stdout) { + if (err) { + result.reject(err); + } else { + result.fulfill(stdout); + } + }); + return result.promise; +} + + +/** + * Computes the ephemeral port range for a Unix-like system. + * @return {!promise.Promise.<{min: number, max: number}>} A promise + * that will resolve with the ephemeral port range on the current system. + */ +function findUnixPortRange() { + var cmd; + if (process.platform === 'sunos') { + cmd = + '/usr/sbin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port'; + } else if (fs.existsSync('/proc/sys/net/ipv4/ip_local_port_range')) { + // Linux + cmd = 'cat /proc/sys/net/ipv4/ip_local_port_range'; + } else { + cmd = 'sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last' + + ' | sed -e "s/.*:\\s*//"'; + } + + return execute(cmd).then(function(stdout) { + if (!stdout || !stdout.length) return DEFAULT_IANA_RANGE; + var range = stdout.trim().split(/\s+/).map(Number); + if (range.some(isNaN)) return DEFAULT_IANA_RANGE; + return {min: range[0], max: range[1]}; + }); +} + + +/** + * Computes the ephemeral port range for a Windows system. + * @return {!promise.Promise.<{min: number, max: number}>} A promise + * that will resolve with the ephemeral port range on the current system. + */ +function findWindowsPortRange() { + var deferredRange = promise.defer(); + // First, check if we're running on XP. If this initial command fails, + // we just fallback on the default IANA range. + return execute('cmd.exe /c ver').then(function(stdout) { + if (/Windows XP/.test(stdout)) { + // TODO: Try to read these values from the registry. + return {min: 1025, max: 5000}; + } else { + return execute('netsh int ipv4 show dynamicport tcp'). + then(function(stdout) { + /* > netsh int ipv4 show dynamicport tcp + Protocol tcp Dynamic Port Range + --------------------------------- + Start Port : 49152 + Number of Ports : 16384 + */ + var range = stdout.split(/\n/).filter(function(line) { + return /.*:\s*\d+/.test(line); + }).map(function(line) { + return Number(line.split(/:\s*/)[1]); + }); + + return { + min: range[0], + max: range[0] + range[1] + }; + }); + } + }); +} + + +/** + * Tests if a port is free. + * @param {number} port The port to test. + * @param {string=} opt_host The bound host to test the {@code port} against. + * Defaults to {@code INADDR_ANY}. + * @return {!promise.Promise.} A promise that will resolve + * with whether the port is free. + */ +function isFree(port, opt_host) { + var result = promise.defer(); + + result.promise.thenCatch(function(e) { + if (e instanceof promise.CancellationError) { + server.close(); + } + }); + + var server = net.createServer().on('error', function(e) { + if (e.code === 'EADDRINUSE') { + result.fulfill(false); + } else { + result.reject(e); + } + }); + + server.listen(port, opt_host, function() { + server.close(function() { + result.fulfill(true); + }); + }); + + return result.promise; +} + + +/** + * @param {string=} opt_host The bound host to test the {@code port} against. + * Defaults to {@code INADDR_ANY}. + * @return {!promise.Promise.} A promise that will resolve + * to a free port. If a port cannot be found, the promise will be + * rejected. + */ +function findFreePort(opt_host) { + return findSystemPortRange().then(function(range) { + var attempts = 0; + var deferredPort = promise.defer(); + findPort(); + return deferredPort.promise; + + function findPort() { + attempts += 1; + if (attempts > 10) { + deferredPort.reject(Error('Unable to find a free port')); + } + + var port = Math.floor( + Math.random() * (range.max - range.min) + range.min); + isFree(port, opt_host).then(function(isFree) { + if (isFree) { + deferredPort.fulfill(port); + } else { + findPort(); + } + }); + } + }); +} + + +// PUBLIC API + + +exports.findFreePort = findFreePort; +exports.isFree = isFree; diff --git a/www/node_modules/selenium-webdriver/opera.js b/www/node_modules/selenium-webdriver/opera.js new file mode 100644 index 0000000..33f1e5b --- /dev/null +++ b/www/node_modules/selenium-webdriver/opera.js @@ -0,0 +1,480 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a {@linkplain Driver WebDriver} client for the + * Opera web browser (v26+). Before using this module, you must download the + * latest OperaDriver + * [release](https://github.com/operasoftware/operachromiumdriver/releases) and + * ensure it can be found on your system + * [PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). + * + * There are three primary classes exported by this module: + * + * 1. {@linkplain ServiceBuilder}: configures the + * {@link selenium-webdriver/remote.DriverService remote.DriverService} + * that manages the + * [OperaDriver](https://github.com/operasoftware/operachromiumdriver) + * child process. + * + * 2. {@linkplain Options}: defines configuration options for each new Opera + * session, such as which {@linkplain Options#setProxy proxy} to use, + * what {@linkplain Options#addExtensions extensions} to install, or + * what {@linkplain Options#addArguments command-line switches} to use when + * starting the browser. + * + * 3. {@linkplain Driver}: the WebDriver client; each new instance will control + * a unique browser session with a clean user profile (unless otherwise + * configured through the {@link Options} class). + * + * By default, every Opera session will use a single driver service, which is + * started the first time a {@link Driver} instance is created and terminated + * when this process exits. The default service will inherit its environment + * from the current process and direct all output to /dev/null. You may obtain + * a handle to this default service using + * {@link #getDefaultService getDefaultService()} and change its configuration + * with {@link #setDefaultService setDefaultService()}. + * + * You may also create a {@link Driver} with its own driver service. This is + * useful if you need to capture the server's log output for a specific session: + * + * var opera = require('selenium-webdriver/opera'); + * + * var service = new opera.ServiceBuilder() + * .loggingTo('/my/log/file.txt') + * .enableVerboseLogging() + * .build(); + * + * var options = new opera.Options(); + * // configure browser options ... + * + * var driver = new opera.Driver(options, service); + * + * Users should only instantiate the {@link Driver} class directly when they + * need a custom driver service configuration (as shown above). For normal + * operation, users should start Opera using the + * {@link selenium-webdriver.Builder}. + */ + +'use strict'; + +const fs = require('fs'); + +const executors = require('./executors'), + io = require('./io'), + capabilities = require('./lib/capabilities'), + promise = require('./lib/promise'), + Symbols = require('./lib/symbols'), + webdriver = require('./lib/webdriver'), + portprober = require('./net/portprober'), + remote = require('./remote'); + + +/** + * Name of the OperaDriver executable. + * @type {string} + * @const + */ +const OPERADRIVER_EXE = + process.platform === 'win32' ? 'operadriver.exe' : 'operadriver'; + + +/** + * Creates {@link remote.DriverService} instances that manages an + * [OperaDriver](https://github.com/operasoftware/operachromiumdriver) + * server in a child process. + */ +class ServiceBuilder { + /** + * @param {string=} opt_exe Path to the server executable to use. If omitted, + * the builder will attempt to locate the operadriver on the current + * PATH. + * @throws {Error} If provided executable does not exist, or the operadriver + * cannot be found on the PATH. + */ + constructor(opt_exe) { + let exe = opt_exe || io.findInPath(OPERADRIVER_EXE, true); + if (!exe) { + throw Error( + 'The OperaDriver could not be found on the current PATH. Please ' + + 'download the latest version of the OperaDriver from ' + + 'https://github.com/operasoftware/operachromiumdriver/releases and ' + + 'ensure it can be found on your PATH.'); + } + + /** @private {string} */ + this.exe_ = /** @type {string} */(exe); + if (!fs.existsSync(this.exe_)) { + throw Error('File does not exist: ' + this.exe_); + } + + /** @private {!Array.} */ + this.args_ = []; + + /** @private {number} */ + this.port_ = 0; + + /** + * @private {(string|!Array)} + */ + this.stdio_ = 'ignore'; + + /** @private {Object.} */ + this.env_ = null; + } + + /** + * Sets the port to start the OperaDriver on. + * @param {number} port The port to use, or 0 for any free port. + * @return {!ServiceBuilder} A self reference. + * @throws {Error} If the port is invalid. + */ + usingPort(port) { + if (port < 0) { + throw Error('port must be >= 0: ' + port); + } + this.port_ = port; + return this; + } + + /** + * Sets the path of the log file the driver should log to. If a log file is + * not specified, the driver will log to stderr. + * @param {string} path Path of the log file to use. + * @return {!ServiceBuilder} A self reference. + */ + loggingTo(path) { + this.args_.push('--log-path=' + path); + return this; + } + + /** + * Enables verbose logging. + * @return {!ServiceBuilder} A self reference. + */ + enableVerboseLogging() { + this.args_.push('--verbose'); + return this; + } + + /** + * Silence sthe drivers output. + * @return {!ServiceBuilder} A self reference. + */ + silent() { + this.args_.push('--silent'); + return this; + } + + /** + * Defines the stdio configuration for the driver service. See + * {@code child_process.spawn} for more information. + * @param {(string|!Array)} + * config The configuration to use. + * @return {!ServiceBuilder} A self reference. + */ + setStdio(config) { + this.stdio_ = config; + return this; + } + + /** + * Defines the environment to start the server under. This settings will be + * inherited by every browser session started by the server. + * @param {!Object.} env The environment to use. + * @return {!ServiceBuilder} A self reference. + */ + withEnvironment(env) { + this.env_ = env; + return this; + } + + /** + * Creates a new DriverService using this instance's current configuration. + * @return {!remote.DriverService} A new driver service using this instance's + * current configuration. + * @throws {Error} If the driver exectuable was not specified and a default + * could not be found on the current PATH. + */ + build() { + var port = this.port_ || portprober.findFreePort(); + var args = this.args_.concat(); // Defensive copy. + + return new remote.DriverService(this.exe_, { + loopback: true, + port: port, + args: promise.when(port, function(port) { + return args.concat('--port=' + port); + }), + env: this.env_, + stdio: this.stdio_ + }); + }; +} + + + +/** @type {remote.DriverService} */ +var defaultService = null; + + +/** + * Sets the default service to use for new OperaDriver instances. + * @param {!remote.DriverService} service The service to use. + * @throws {Error} If the default service is currently running. + */ +function setDefaultService(service) { + if (defaultService && defaultService.isRunning()) { + throw Error( + 'The previously configured OperaDriver service is still running. ' + + 'You must shut it down before you may adjust its configuration.'); + } + defaultService = service; +} + + +/** + * Returns the default OperaDriver service. If such a service has not been + * configured, one will be constructed using the default configuration for + * a OperaDriver executable found on the system PATH. + * @return {!remote.DriverService} The default OperaDriver service. + */ +function getDefaultService() { + if (!defaultService) { + defaultService = new ServiceBuilder().build(); + } + return defaultService; +} + + +/** + * @type {string} + * @const + */ +var OPTIONS_CAPABILITY_KEY = 'chromeOptions'; + + +/** + * Class for managing {@linkplain Driver OperaDriver} specific options. + */ +class Options { + constructor() { + /** @private {!Array.} */ + this.args_ = []; + + /** @private {?string} */ + this.binary_ = null; + + /** @private {!Array.<(string|!Buffer)>} */ + this.extensions_ = []; + + /** @private {./lib/logging.Preferences} */ + this.logPrefs_ = null; + + /** @private {?capabilities.ProxyConfig} */ + this.proxy_ = null; + } + + /** + * Extracts the OperaDriver specific options from the given capabilities + * object. + * @param {!capabilities.Capabilities} caps The capabilities object. + * @return {!Options} The OperaDriver options. + */ + static fromCapabilities(caps) { + var options; + var o = caps.get(OPTIONS_CAPABILITY_KEY); + if (o instanceof Options) { + options = o; + } else if (o) { + options = new Options() + .addArguments(o.args || []) + .addExtensions(o.extensions || []) + .setOperaBinaryPath(o.binary); + } else { + options = new Options; + } + + if (caps.has(capabilities.Capability.PROXY)) { + options.setProxy(caps.get(capabilities.Capability.PROXY)); + } + + if (caps.has(capabilities.Capability.LOGGING_PREFS)) { + options.setLoggingPrefs( + caps.get(capabilities.Capability.LOGGING_PREFS)); + } + + return options; + } + + /** + * Add additional command line arguments to use when launching the Opera + * browser. Each argument may be specified with or without the "--" prefix + * (e.g. "--foo" and "foo"). Arguments with an associated value should be + * delimited by an "=": "foo=bar". + * @param {...(string|!Array.)} var_args The arguments to add. + * @return {!Options} A self reference. + */ + addArguments(var_args) { + this.args_ = this.args_.concat.apply(this.args_, arguments); + return this; + } + + /** + * Add additional extensions to install when launching Opera. Each extension + * should be specified as the path to the packed CRX file, or a Buffer for an + * extension. + * @param {...(string|!Buffer|!Array.<(string|!Buffer)>)} var_args The + * extensions to add. + * @return {!Options} A self reference. + */ + addExtensions(var_args) { + this.extensions_ = this.extensions_.concat.apply( + this.extensions_, arguments); + return this; + } + + /** + * Sets the path to the Opera binary to use. On Mac OS X, this path should + * reference the actual Opera executable, not just the application binary. The + * binary path be absolute or relative to the operadriver server executable, but + * it must exist on the machine that will launch Opera. + * + * @param {string} path The path to the Opera binary to use. + * @return {!Options} A self reference. + */ + setOperaBinaryPath(path) { + this.binary_ = path; + return this; + } + + /** + * Sets the logging preferences for the new session. + * @param {!./lib/logging.Preferences} prefs The logging preferences. + * @return {!Options} A self reference. + */ + setLoggingPrefs(prefs) { + this.logPrefs_ = prefs; + return this; + } + + /** + * Sets the proxy settings for the new session. + * @param {capabilities.ProxyConfig} proxy The proxy configuration to use. + * @return {!Options} A self reference. + */ + setProxy(proxy) { + this.proxy_ = proxy; + return this; + } + + /** + * Converts this options instance to a {@link capabilities.Capabilities} + * object. + * @param {capabilities.Capabilities=} opt_capabilities The capabilities to + * merge these options into, if any. + * @return {!capabilities.Capabilities} The capabilities. + */ + toCapabilities(opt_capabilities) { + var caps = opt_capabilities || capabilities.Capabilities.opera(); + caps. + set(capabilities.Capability.PROXY, this.proxy_). + set(capabilities.Capability.LOGGING_PREFS, this.logPrefs_). + set(OPTIONS_CAPABILITY_KEY, this); + return caps; + } + + /** + * Converts this instance to its JSON wire protocol representation. Note this + * function is an implementation not intended for general use. + * @return {!Object} The JSON wire protocol representation of this instance. + */ + [Symbols.serialize]() { + var json = { + args: this.args_, + extensions: this.extensions_.map(function(extension) { + if (Buffer.isBuffer(extension)) { + return extension.toString('base64'); + } + return promise.checkedNodeCall( + fs.readFile, extension, 'base64'); + }) + }; + if (this.binary_) { + json.binary = this.binary_; + } + return json; + } +} + + +/** + * Creates a new WebDriver client for Opera. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(capabilities.Capabilities|Options)=} opt_config The configuration + * options. + * @param {remote.DriverService=} opt_service The session to use; will use + * the {@link getDefaultService default service} by default. + * @param {promise.ControlFlow=} opt_flow The control flow to use, + * or {@code null} to use the currently active flow. + */ + constructor(opt_config, opt_service, opt_flow) { + var service = opt_service || getDefaultService(); + var executor = executors.createExecutor(service.start()); + + var caps = + opt_config instanceof Options ? opt_config.toCapabilities() : + (opt_config || capabilities.Capabilities.opera()); + + // On Linux, the OperaDriver does not look for Opera on the PATH, so we + // must explicitly find it. See: operachromiumdriver #9. + if (process.platform === 'linux') { + var options = Options.fromCapabilities(caps); + if (!options.binary_) { + let exe = io.findInPath('opera', true); + if (!exe) { + throw Error( + 'The opera executable could not be found on the current PATH'); + } + options.setOperaBinaryPath(exe); + } + caps = options.toCapabilities(caps); + } + + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + super(driver.getSession(), executor, driver.controlFlow()); + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() {} +} + + +// PUBLIC API + + +exports.Driver = Driver; +exports.Options = Options; +exports.ServiceBuilder = ServiceBuilder; +exports.getDefaultService = getDefaultService; +exports.setDefaultService = setDefaultService; diff --git a/www/node_modules/selenium-webdriver/package.json b/www/node_modules/selenium-webdriver/package.json new file mode 100644 index 0000000..6c227ff --- /dev/null +++ b/www/node_modules/selenium-webdriver/package.json @@ -0,0 +1,94 @@ +{ + "_args": [ + [ + "selenium-webdriver", + "/Users/adamdon/Desktop/studywell/studywell/sw/www" + ] + ], + "_from": "selenium-webdriver@latest", + "_id": "selenium-webdriver@2.52.0", + "_inCache": true, + "_installable": true, + "_location": "/selenium-webdriver", + "_nodeVersion": "0.12.0", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/selenium-webdriver-2.52.0.tgz_1455259913894_0.6562679694034159" + }, + "_npmUser": { + "email": "jmleyba@gmail.com", + "name": "jmleyba" + }, + "_npmVersion": "2.5.1", + "_phantomChildren": {}, + "_requested": { + "name": "selenium-webdriver", + "raw": "selenium-webdriver", + "rawSpec": "", + "scope": null, + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.52.0.tgz", + "_shasum": "d2dcb2f51b48733d6c42829e52767ecee2bf4b6b", + "_shrinkwrap": null, + "_spec": "selenium-webdriver", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www", + "bugs": { + "url": "https://github.com/SeleniumHQ/selenium/issues" + }, + "dependencies": { + "adm-zip": "0.4.4", + "rimraf": "^2.2.8", + "tmp": "0.0.24", + "ws": "^1.0.1", + "xml2js": "0.4.4" + }, + "description": "The official WebDriver JavaScript bindings from the Selenium project", + "devDependencies": { + "express": "^4.11.2", + "mocha": ">= 1.21.x", + "multer": "^0.1.7", + "promises-aplus-tests": "^2.1.0", + "serve-index": "^1.6.1", + "sinon": "^1.17.2" + }, + "directories": {}, + "dist": { + "shasum": "d2dcb2f51b48733d6c42829e52767ecee2bf4b6b", + "tarball": "http://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.52.0.tgz" + }, + "engines": { + "node": ">= 4.2.x" + }, + "homepage": "https://github.com/SeleniumHQ/selenium", + "keywords": [ + "automation", + "selenium", + "testing", + "webdriver", + "webdriverjs" + ], + "license": "Apache-2.0", + "main": "./index", + "maintainers": [ + { + "email": "jmleyba@gmail.com", + "name": "jmleyba" + } + ], + "name": "selenium-webdriver", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/SeleniumHQ/selenium.git" + }, + "scripts": { + "test": "mocha --harmony -t 600000 --recursive test" + }, + "version": "2.52.0" +} diff --git a/www/node_modules/selenium-webdriver/phantomjs.js b/www/node_modules/selenium-webdriver/phantomjs.js new file mode 100644 index 0000000..7853149 --- /dev/null +++ b/www/node_modules/selenium-webdriver/phantomjs.js @@ -0,0 +1,260 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const fs = require('fs'); + +const executors = require('./executors'), + http = require('./http'), + io = require('./io'), + capabilities = require('./lib/capabilities'), + command = require('./lib/command'), + logging = require('./lib/logging'), + promise = require('./lib/promise'), + webdriver = require('./lib/webdriver'), + portprober = require('./net/portprober'), + remote = require('./remote'); + + +/** + * Name of the PhantomJS executable. + * @type {string} + * @const + */ +const PHANTOMJS_EXE = + process.platform === 'win32' ? 'phantomjs.exe' : 'phantomjs'; + + +/** + * Capability that designates the location of the PhantomJS executable to use. + * @type {string} + * @const + */ +const BINARY_PATH_CAPABILITY = 'phantomjs.binary.path'; + + +/** + * Capability that designates the CLI arguments to pass to PhantomJS. + * @type {string} + * @const + */ +const CLI_ARGS_CAPABILITY = 'phantomjs.cli.args'; + + +/** + * Default log file to use if one is not specified through CLI args. + * @type {string} + * @const + */ +const DEFAULT_LOG_FILE = 'phantomjsdriver.log'; + + +/** + * Custom command names supported by PhantomJS. + * @enum {string} + */ +const Command = { + EXECUTE_PHANTOM_SCRIPT: 'executePhantomScript' +}; + + +/** + * Finds the PhantomJS executable. + * @param {string=} opt_exe Path to the executable to use. + * @return {string} The located executable. + * @throws {Error} If the executable cannot be found on the PATH, or if the + * provided executable path does not exist. + */ +function findExecutable(opt_exe) { + var exe = opt_exe || io.findInPath(PHANTOMJS_EXE, true); + if (!exe) { + throw Error( + 'The PhantomJS executable could not be found on the current PATH. ' + + 'Please download the latest version from ' + + 'http://phantomjs.org/download.html and ensure it can be found on ' + + 'your PATH. For more information, see ' + + 'https://github.com/ariya/phantomjs/wiki'); + } + if (!fs.existsSync(exe)) { + throw Error('File does not exist: ' + exe); + } + return exe; +} + + +/** + * Maps WebDriver logging level name to those recognised by PhantomJS. + * @const {!Map} + */ +const WEBDRIVER_TO_PHANTOMJS_LEVEL = new Map([ + [logging.Level.ALL.name, 'DEBUG'], + [logging.Level.DEBUG.name, 'DEBUG'], + [logging.Level.INFO.name, 'INFO'], + [logging.Level.WARNING.name, 'WARN'], + [logging.Level.SEVERE.name, 'ERROR']]); + + +/** + * Creates a command executor with support for PhantomJS' custom commands. + * @param {!promise.Promise} url The server's URL. + * @return {!command.Executor} The new command executor. + */ +function createExecutor(url) { + return new executors.DeferredExecutor(url.then(function(url) { + var client = new http.HttpClient(url); + var executor = new http.Executor(client); + + executor.defineCommand( + Command.EXECUTE_PHANTOM_SCRIPT, + 'POST', '/session/:sessionId/phantom/execute'); + + return executor; + })); +} + +/** + * Creates a new WebDriver client for PhantomJS. + */ +class Driver extends webdriver.WebDriver { + /** + * @param {capabilities.Capabilities=} opt_capabilities The desired + * capabilities. + * @param {promise.ControlFlow=} opt_flow The control flow to use, + * or {@code null} to use the currently active flow. + */ + constructor(opt_capabilities, opt_flow) { + var caps = opt_capabilities || capabilities.Capabilities.phantomjs(); + var exe = findExecutable(caps.get(BINARY_PATH_CAPABILITY)); + var args = ['--webdriver-logfile=' + DEFAULT_LOG_FILE]; + + var logPrefs = caps.get(capabilities.Capability.LOGGING_PREFS); + if (logPrefs instanceof logging.Preferences) { + logPrefs = logPrefs.toJSON(); + } + + if (logPrefs && logPrefs[logging.Type.DRIVER]) { + let level = WEBDRIVER_TO_PHANTOMJS_LEVEL.get( + logPrefs[logging.Type.DRIVER]); + if (level) { + args.push('--webdriver-loglevel=' + level); + } + } + + var proxy = caps.get(capabilities.Capability.PROXY); + if (proxy) { + switch (proxy.proxyType) { + case 'manual': + if (proxy.httpProxy) { + args.push( + '--proxy-type=http', + '--proxy=http://' + proxy.httpProxy); + } + break; + case 'pac': + throw Error('PhantomJS does not support Proxy PAC files'); + case 'system': + args.push('--proxy-type=system'); + break; + case 'direct': + args.push('--proxy-type=none'); + break; + } + } + args = args.concat(caps.get(CLI_ARGS_CAPABILITY) || []); + + var port = portprober.findFreePort(); + var service = new remote.DriverService(exe, { + port: port, + args: promise.when(port, function(port) { + args.push('--webdriver=' + port); + return args; + }) + }); + + var executor = createExecutor(service.start()); + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + + super(driver.getSession(), executor, driver.controlFlow()); + + var boundQuit = this.quit.bind(this); + + /** @override */ + this.quit = function() { + return boundQuit().thenFinally(service.kill.bind(service)); + }; + } + + /** + * This function is a no-op as file detectors are not supported by this + * implementation. + * @override + */ + setFileDetector() {} + + /** + * Executes a PhantomJS fragment. This method is similar to + * {@link #executeScript}, except it exposes the + * PhantomJS API to the injected + * script. + * + *

    The injected script will execute in the context of PhantomJS's + * {@code page} variable. If a page has not been loaded before calling this + * method, one will be created.

    + * + *

    Be sure to wrap callback definitions in a try/catch block, as failures + * may cause future WebDriver calls to fail.

    + * + *

    Certain callbacks are used by GhostDriver (the PhantomJS WebDriver + * implementation) and overriding these may cause the script to fail. It is + * recommended that you check for existing callbacks before defining your own. + *

    + * + * As with {@link #executeScript}, the injected script may be defined as + * a string for an anonymous function body (e.g. "return 123;"), or as a + * function. If a function is provided, it will be decompiled to its original + * source. Note that injecting functions is provided as a convenience to + * simplify defining complex scripts. Care must be taken that the function + * only references variables that will be defined in the page's scope and + * that the function does not override {@code Function.prototype.toString} + * (overriding toString() will interfere with how the function is + * decompiled. + * + * @param {(string|!Function)} script The script to execute. + * @param {...*} var_args The arguments to pass to the script. + * @return {!promise.Promise} A promise that resolve to the + * script's return value. + * @template T + */ + executePhantomJS(script, var_args) { + if (typeof script === 'function') { + script = 'return (' + script + ').apply(this, arguments);'; + } + var args = arguments.length > 1 + ? Array.prototype.slice.call(arguments, 1) : []; + return this.schedule( + new command.Command(Command.EXECUTE_PHANTOM_SCRIPT) + .setParameter('script', script) + .setParameter('args', args), + 'Driver.executePhantomJS()'); + } +} + + +// PUBLIC API + +exports.Driver = Driver; diff --git a/www/node_modules/selenium-webdriver/proxy.js b/www/node_modules/selenium-webdriver/proxy.js new file mode 100644 index 0000000..e238cb1 --- /dev/null +++ b/www/node_modules/selenium-webdriver/proxy.js @@ -0,0 +1,103 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines functions for configuring a webdriver proxy: + * + * var webdriver = require('selenium-webdriver'), + * proxy = require('selenium-webdriver/proxy'); + * + * var driver = new webdriver.Builder() + * .withCapabilities(webdriver.Capabilities.chrome()) + * .setProxy(proxy.manual({http: 'host:1234'})) + * .build(); + */ + +'use strict'; + +var util = require('util'); + +var ProxyConfig = require('./lib/capabilities').ProxyConfig; + + + +// PUBLIC API + + +/** + * Configures WebDriver to bypass all browser proxies. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.direct = function() { + return {proxyType: 'direct'}; +}; + + +/** + * Manually configures the browser proxy. The following options are + * supported: + * + * - `ftp`: Proxy host to use for FTP requests + * - `http`: Proxy host to use for HTTP requests + * - `https`: Proxy host to use for HTTPS requests + * - `bypass`: A list of hosts requests should directly connect to, + * bypassing any other proxies for that request. May be specified as a + * comma separated string, or a list of strings. + * + * Behavior is undefined for FTP, HTTP, and HTTPS requests if the + * corresponding key is omitted from the configuration options. + * + * @param {{ftp: (string|undefined), + * http: (string|undefined), + * https: (string|undefined), + * bypass: (string|!Array.|undefined)}} options Proxy + * configuration options. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.manual = function(options) { + return { + proxyType: 'manual', + ftpProxy: options.ftp, + httpProxy: options.http, + sslProxy: options.https, + noProxy: util.isArray(options.bypass) ? + options.bypass.join(',') : options.bypass + }; +}; + + +/** + * Configures WebDriver to configure the browser proxy using the PAC file at + * the given URL. + * @param {string} url URL for the PAC proxy to use. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.pac = function(url) { + return { + proxyType: 'pac', + proxyAutoconfigUrl: url + }; +}; + + +/** + * Configures WebDriver to use the current system's proxy. + * @return {!ProxyConfig} A new proxy configuration object. + */ +exports.system = function() { + return {proxyType: 'system'}; +}; diff --git a/www/node_modules/selenium-webdriver/remote/index.js b/www/node_modules/selenium-webdriver/remote/index.js new file mode 100644 index 0000000..7b5eeeb --- /dev/null +++ b/www/node_modules/selenium-webdriver/remote/index.js @@ -0,0 +1,381 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const AdmZip = require('adm-zip'), + AdmConstants = require('adm-zip/util/constants'), + fs = require('fs'), + path = require('path'), + url = require('url'), + util = require('util'); + +const httpUtil = require('../http/util'), + exec = require('../io/exec'), + cmd = require('../lib/command'), + input = require('../lib/input'), + promise = require('../lib/promise'), + webdriver = require('../lib/webdriver'), + net = require('../net'), + portprober = require('../net/portprober'); + + + +/** + * Configuration options for a DriverService instance. + * + * - `loopback` - Whether the service should only be accessed on this host's + * loopback address. + * - `hostname` - The host name to access the server on. If this option is + * specified, the `loopback` option will be ignored. + * - `port` - The port to start the server on (must be > 0). If the port is + * provided as a promise, the service will wait for the promise to resolve + * before starting. + * - `args` - The arguments to pass to the service. If a promise is provided, + * the service will wait for it to resolve before starting. + * - `path` - The base path on the server for the WebDriver wire protocol + * (e.g. '/wd/hub'). Defaults to '/'. + * - `env` - The environment variables that should be visible to the server + * process. Defaults to inheriting the current process's environment. + * - `stdio` - IO configuration for the spawned server process. For more + * information, refer to the documentation of `child_process.spawn`. + * + * @typedef {{ + * loopback: (boolean|undefined), + * hostname: (string|undefined), + * port: (number|!promise.Promise), + * args: !(Array|promise.Promise>), + * path: (string|undefined|null), + * env: (Object|undefined), + * stdio: (string|!Array| + * undefined) + * }} + */ +var ServiceOptions; + + +/** + * Manages the life and death of a native executable WebDriver server. + * + * It is expected that the driver server implements the + * https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol. + * Furthermore, the managed server should support multiple concurrent sessions, + * so that this class may be reused for multiple clients. + */ +class DriverService { + /** + * @param {string} executable Path to the executable to run. + * @param {!ServiceOptions} options Configuration options for the service. + */ + constructor(executable, options) { + /** @private {string} */ + this.executable_ = executable; + + /** @private {boolean} */ + this.loopbackOnly_ = !!options.loopback; + + /** @private {(string|undefined)} */ + this.hostname_ = options.hostname; + + /** @private {(number|!promise.Promise)} */ + this.port_ = options.port; + + /** + * @private {!(Array|promise.Promise>)} + */ + this.args_ = options.args; + + /** @private {string} */ + this.path_ = options.path || '/'; + + /** @private {!Object} */ + this.env_ = options.env || process.env; + + /** + * @private {(string|!Array)} + */ + this.stdio_ = options.stdio || 'ignore'; + + /** + * A promise for the managed subprocess, or null if the server has not been + * started yet. This promise will never be rejected. + * @private {promise.Deferred} + */ + this.command_ = null; + + /** + * Promise that resolves to the server's address or null if the server has + * not been started. This promise will be rejected if the server terminates + * before it starts accepting WebDriver requests. + * @private {promise.Deferred} + */ + this.address_ = null; + } + + /** + * @return {!promise.Promise} A promise that resolves to + * the server's address. + * @throws {Error} If the server has not been started. + */ + address() { + if (this.address_) { + return this.address_.promise; + } + throw Error('Server has not been started.'); + } + + /** + * Returns whether the underlying process is still running. This does not take + * into account whether the process is in the process of shutting down. + * @return {boolean} Whether the underlying service process is running. + */ + isRunning() { + return !!this.address_; + } + + /** + * Starts the server if it is not already running. + * @param {number=} opt_timeoutMs How long to wait, in milliseconds, for the + * server to start accepting requests. Defaults to 30 seconds. + * @return {!promise.Promise} A promise that will resolve + * to the server's base URL when it has started accepting requests. If the + * timeout expires before the server has started, the promise will be + * rejected. + */ + start(opt_timeoutMs) { + if (this.address_) { + return this.address_.promise; + } + + var timeout = opt_timeoutMs || DriverService.DEFAULT_START_TIMEOUT_MS; + + var self = this; + this.command_ = promise.defer(); + this.address_ = promise.defer(); + this.address_.fulfill(promise.when(this.port_, function(port) { + if (port <= 0) { + throw Error('Port must be > 0: ' + port); + } + return promise.when(self.args_, function(args) { + var command = exec(self.executable_, { + args: args, + env: self.env_, + stdio: self.stdio_ + }); + + self.command_.fulfill(command); + + var earlyTermination = command.result().then(function(result) { + var error = result.code == null ? + Error('Server was killed with ' + result.signal) : + Error('Server terminated early with status ' + result.code); + self.address_.reject(error); + self.address_ = null; + self.command_ = null; + throw error; + }); + + var hostname = self.hostname_; + if (!hostname) { + hostname = !self.loopbackOnly_ && net.getAddress() + || net.getLoopbackAddress(); + } + + var serverUrl = url.format({ + protocol: 'http', + hostname: hostname, + port: port, + pathname: self.path_ + }); + + return new promise.Promise(function(fulfill, reject) { + var ready = httpUtil.waitForServer(serverUrl, timeout) + .then(fulfill, reject); + earlyTermination.thenCatch(function(e) { + ready.cancel(/** @type {Error} */(e)); + reject(Error(e.message)); + }); + }).then(function() { + return serverUrl; + }); + }); + })); + + return this.address_.promise; + } + + /** + * Stops the service if it is not currently running. This function will kill + * the server immediately. To synchronize with the active control flow, use + * {@link #stop()}. + * @return {!promise.Promise} A promise that will be resolved when + * the server has been stopped. + */ + kill() { + if (!this.address_ || !this.command_) { + return promise.fulfilled(); // Not currently running. + } + return this.command_.promise.then(function(command) { + command.kill('SIGTERM'); + }); + } + + /** + * Schedules a task in the current control flow to stop the server if it is + * currently running. + * @return {!promise.Promise} A promise that will be resolved when + * the server has been stopped. + */ + stop() { + return promise.controlFlow().execute(this.kill.bind(this)); + } +} + + +/** + * The default amount of time, in milliseconds, to wait for the server to + * start. + * @const {number} + */ +DriverService.DEFAULT_START_TIMEOUT_MS = 30 * 1000; + + +/** + * Manages the life and death of the + * + * standalone Selenium server. + */ +class SeleniumServer extends DriverService { + /** + * @param {string} jar Path to the Selenium server jar. + * @param {SeleniumServer.Options=} opt_options Configuration options for the + * server. + * @throws {Error} If the path to the Selenium jar is not specified or if an + * invalid port is specified. + */ + constructor(jar, opt_options) { + if (!jar) { + throw Error('Path to the Selenium jar not specified'); + } + + var options = opt_options || {}; + + if (options.port < 0) { + throw Error('Port must be >= 0: ' + options.port); + } + + var port = options.port || portprober.findFreePort(); + var args = promise.when(options.jvmArgs || [], function(jvmArgs) { + return promise.when(options.args || [], function(args) { + return promise.when(port, function(port) { + return jvmArgs.concat(['-jar', jar, '-port', port]).concat(args); + }); + }); + }); + + super('java', { + loopback: options.loopback, + port: port, + args: args, + path: '/wd/hub', + env: options.env, + stdio: options.stdio + }); + } +} + + +/** + * Options for the Selenium server: + * + * - `loopback` - Whether the server should only be accessed on this host's + * loopback address. + * - `port` - The port to start the server on (must be > 0). If the port is + * provided as a promise, the service will wait for the promise to resolve + * before starting. + * - `args` - The arguments to pass to the service. If a promise is provided, + * the service will wait for it to resolve before starting. + * - `jvmArgs` - The arguments to pass to the JVM. If a promise is provided, + * the service will wait for it to resolve before starting. + * - `env` - The environment variables that should be visible to the server + * process. Defaults to inheriting the current process's environment. + * - `stdio` - IO configuration for the spawned server process. For more + * information, refer to the documentation of `child_process.spawn`. + * + * @typedef {{ + * loopback: (boolean|undefined), + * port: (number|!promise.Promise), + * args: !(Array|promise.Promise>), + * jvmArgs: (!Array| + * !promise.Promise>| + * undefined), + * env: (!Object|undefined), + * stdio: (string|!Array| + * undefined) + * }} + */ +SeleniumServer.Options; + + + +/** + * A {@link webdriver.FileDetector} that may be used when running + * against a remote + * [Selenium server](http://selenium-release.storage.googleapis.com/index.html). + * + * When a file path on the local machine running this script is entered with + * {@link webdriver.WebElement#sendKeys WebElement#sendKeys}, this file detector + * will transfer the specified file to the Selenium server's host; the sendKeys + * command will be updated to use the transfered file's path. + * + * __Note:__ This class depends on a non-standard command supported on the + * Java Selenium server. The file detector will fail if used with a server that + * only supports standard WebDriver commands (such as the ChromeDriver). + * + * @final + */ +class FileDetector extends input.FileDetector { + /** @override */ + handleFile(driver, filePath) { + return promise.checkedNodeCall(fs.stat, filePath).then(function(stats) { + if (stats.isDirectory()) { + throw TypeError('Uploading directories is not supported: ' + filePath); + } + + var zip = new AdmZip(); + zip.addLocalFile(filePath); + zip.getEntries()[0].header.method = AdmConstants.STORED; + + var command = new cmd.Command(cmd.Name.UPLOAD_FILE) + .setParameter('file', zip.toBuffer().toString('base64')); + return driver.schedule(command, + 'remote.FileDetector.handleFile(' + filePath + ')'); + }, function(err) { + if (err.code === 'ENOENT') { + return filePath; // Not a file; return original input. + } + throw err; + }); + } +} + + +// PUBLIC API + +exports.DriverService = DriverService; +exports.FileDetector = FileDetector; +exports.SeleniumServer = SeleniumServer; diff --git a/www/node_modules/selenium-webdriver/safari.js b/www/node_modules/selenium-webdriver/safari.js new file mode 100644 index 0000000..e4b56d6 --- /dev/null +++ b/www/node_modules/selenium-webdriver/safari.js @@ -0,0 +1,547 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a WebDriver client for Safari. Before using this + * module, you must install the + * [latest version](http://selenium-release.storage.googleapis.com/index.html) + * of the SafariDriver browser extension; using Safari for normal browsing is + * not recommended once the extension has been installed. You can, and should, + * disable the extension when the browser is not being used with WebDriver. + */ + +'use strict'; + +const events = require('events'); +const fs = require('fs'); +const http = require('http'); +const path = require('path'); +const url = require('url'); +const util = require('util'); +const ws = require('ws'); + +const io = require('./io'); +const exec = require('./io/exec'); +const isDevMode = require('./lib/devmode'); +const Capabilities = require('./lib/capabilities').Capabilities; +const Capability = require('./lib/capabilities').Capability; +const command = require('./lib/command'); +const promise = require('./lib/promise'); +const Symbols = require('./lib/symbols'); +const webdriver = require('./lib/webdriver'); +const portprober = require('./net/portprober'); + + +/** @const */ +const CLIENT_PATH = isDevMode + ? path.join(__dirname, + '../../../build/javascript/safari-driver/client.js') + : path.join(__dirname, 'lib/safari/client.js'); + + +/** @const */ +const LIBRARY_DIR = (function() { + if (process.platform === 'darwin') { + return path.join('/Users', process.env['USER'], 'Library/Safari'); + } else if (process.platform === 'win32') { + return path.join(process.env['APPDATA'], 'Apple Computer', 'Safari'); + } else { + return '/dev/null'; + } +})(); + + +/** @const */ +const SESSION_DATA_FILES = (function() { + if (process.platform === 'darwin') { + var libraryDir = path.join('/Users', process.env['USER'], 'Library'); + return [ + path.join(libraryDir, 'Caches/com.apple.Safari/Cache.db'), + path.join(libraryDir, 'Cookies/Cookies.binarycookies'), + path.join(libraryDir, 'Cookies/Cookies.plist'), + path.join(libraryDir, 'Safari/History.plist'), + path.join(libraryDir, 'Safari/LastSession.plist'), + path.join(libraryDir, 'Safari/LocalStorage'), + path.join(libraryDir, 'Safari/Databases') + ]; + } else if (process.platform === 'win32') { + var appDataDir = path.join(process.env['APPDATA'], + 'Apple Computer', 'Safari'); + var localDataDir = path.join(process.env['LOCALAPPDATA'], + 'Apple Computer', 'Safari'); + return [ + path.join(appDataDir, 'History.plist'), + path.join(appDataDir, 'LastSession.plist'), + path.join(appDataDir, 'Cookies/Cookies.plist'), + path.join(appDataDir, 'Cookies/Cookies.binarycookies'), + path.join(localDataDir, 'Cache.db'), + path.join(localDataDir, 'Databases'), + path.join(localDataDir, 'LocalStorage') + ]; + } else { + return []; + } +})(); + + +/** @typedef {{port: number, address: string, family: string}} */ +var Host; + + +/** + * A basic HTTP/WebSocket server used to communicate with the SafariDriver + * browser extension. + */ +class Server extends events.EventEmitter { + constructor() { + super(); + var server = http.createServer(function(req, res) { + if (req.url === '/favicon.ico') { + res.writeHead(204); + res.end(); + return; + } + + var query = url.parse(/** @type {string} */(req.url)).query || ''; + if (query.indexOf('url=') == -1) { + var address = server.address() + var host = address.address + ':' + address.port; + res.writeHead( + 302, {'Location': 'http://' + host + '?url=ws://' + host}); + res.end(); + } + + fs.readFile(CLIENT_PATH, 'utf8', function(err, data) { + if (err) { + res.writeHead(500, {'Content-Type': 'text/plain'}); + res.end(err.stack); + return; + } + var content = ''; + res.writeHead(200, { + 'Content-Type': 'text/html; charset=utf-8', + 'Content-Length': Buffer.byteLength(content, 'utf8'), + }); + res.end(content); + }); + }); + + var wss = new ws.Server({server: server}); + wss.on('connection', this.emit.bind(this, 'connection')); + + /** + * Starts the server on a random port. + * @return {!promise.Promise} A promise that will resolve + * with the server host when it has fully started. + */ + this.start = function() { + if (server.address()) { + return promise.fulfilled(server.address()); + } + return portprober.findFreePort('localhost').then(function(port) { + return promise.checkedNodeCall( + server.listen.bind(server, port, 'localhost')); + }).then(function() { + return server.address(); + }); + }; + + /** + * Stops the server. + * @return {!promise.Promise} A promise that will resolve when + * the server has closed all connections. + */ + this.stop = function() { + return new promise.Promise(function(fulfill) { + server.close(fulfill); + }); + }; + + /** + * @return {Host} This server's host info. + * @throws {Error} If the server is not running. + */ + this.address = function() { + var addr = server.address(); + if (!addr) { + throw Error('There server is not running!'); + } + return addr; + }; + } +} + + +/** + * @return {!Promise} A promise that will resolve with the path + * to Safari on the current system. + */ +function findSafariExecutable() { + switch (process.platform) { + case 'darwin': + return Promise.resolve('/Applications/Safari.app/Contents/MacOS/Safari'); + + case 'win32': + var files = [ + process.env['PROGRAMFILES'] || '\\Program Files', + process.env['PROGRAMFILES(X86)'] || '\\Program Files (x86)' + ].map(function(prefix) { + return path.join(prefix, 'Safari\\Safari.exe'); + }); + return io.exists(files[0]).then(function(exists) { + return exists ? files[0] : io.exists(files[1]).then(function(exists) { + if (exists) { + return files[1]; + } + throw Error('Unable to find Safari on the current system'); + }); + }); + + default: + return Promise.reject( + Error('Safari is not supported on the current platform: ' + + process.platform)); + } +} + + +/** + * @param {string} serverUrl The URL to connect to. + * @return {!Promise} A promise for the path to a file that Safari can + * open on start-up to trigger a new connection to the WebSocket server. + */ +function createConnectFile(serverUrl) { + return io.tmpFile({postfix: '.html'}).then(function(f) { + var writeFile = promise.checkedNodeCall(fs.writeFile, + f, + '', + {encoding: 'utf8'}); + return writeFile.then(function() { + return f; + }); + }); +} + + +/** + * Deletes all session data files if so desired. + * @param {!Object} desiredCapabilities . + * @return {!Array} A list of promises for the deleted files. + */ +function cleanSession(desiredCapabilities) { + if (!desiredCapabilities) { + return []; + } + var options = desiredCapabilities[OPTIONS_CAPABILITY_KEY]; + if (!options) { + return []; + } + if (!options['cleanSession']) { + return []; + } + return SESSION_DATA_FILES.map(function(file) { + return io.unlink(file); + }); +} + + +/** @return {string} . */ +function getRandomString() { + let seed = Date.now(); + return Math.floor(Math.random() * seed).toString(36) + + Math.abs(Math.floor(Math.random() * seed) ^ Date.now()).toString(36); +} + + +/** + * @implements {command.Executor} + */ +class CommandExecutor { + constructor() { + this.server_ = null; + + /** @private {ws.WebSocket} */ + this.socket_ = null; + + /** @private {promise.Promise.} */ + this.safari_ = null; + } + + /** @override */ + execute(cmd) { + var self = this; + return new promise.Promise(function(fulfill, reject) { + var safariCommand = JSON.stringify({ + 'origin': 'webdriver', + 'type': 'command', + 'command': { + 'id': getRandomString(), + 'name': cmd.getName(), + 'parameters': cmd.getParameters() + } + }); + + switch (cmd.getName()) { + case command.Name.NEW_SESSION: + self.startSafari_(cmd) + .then(() => self.sendCommand_(safariCommand)) + .then(fulfill, reject); + break; + + case command.Name.QUIT: + self.destroySession_() + .then(() => fulfill({status: 0, value: null}), reject); + break; + + default: + self.sendCommand_(safariCommand).then(fulfill, reject); + break; + } + }); + } + + /** + * @param {string} data . + * @return {!promise.Promise} . + * @private + */ + sendCommand_(data) { + let self = this; + return new promise.Promise(function(fulfill, reject) { + // TODO: support reconnecting with the extension. + if (!self.socket_) { + self.destroySession_().thenFinally(function() { + reject(Error('The connection to the SafariDriver was closed')); + }); + return; + } + + self.socket_.send(data, function(err) { + if (err) { + reject(err); + return; + } + }); + + self.socket_.once('message', function(data) { + try { + data = JSON.parse(data); + } catch (ex) { + reject(Error('Failed to parse driver message: ' + data)); + return; + } + fulfill(data['response']); + }); + }); + } + + /** + * @param {!command.Command} command . + * @private + */ + startSafari_(command) { + this.server_ = new Server(); + + this.safari_ = this.server_.start().then(function(address) { + var tasks = cleanSession( + /** @type {!Object} */( + command.getParameters()['desiredCapabilities'])); + tasks.push( + findSafariExecutable(), + createConnectFile( + 'http://' + address.address + ':' + address.port)); + return promise.all(tasks).then(function(tasks) { + var exe = tasks[tasks.length - 2]; + var html = tasks[tasks.length - 1]; + return exec(exe, {args: [html]}); + }); + }); + + var connected = promise.defer(); + var self = this; + var start = Date.now(); + var timer = setTimeout(function() { + connected.reject(Error( + 'Failed to connect to the SafariDriver after ' + (Date.now() - start) + + ' ms; Have you installed the latest extension from ' + + 'http://selenium-release.storage.googleapis.com/index.html?')); + }, 10 * 1000); + this.server_.once('connection', function(socket) { + clearTimeout(timer); + self.socket_ = socket; + socket.once('close', function() { + self.socket_ = null; + }); + connected.fulfill(); + }); + return connected.promise; + } + + /** + * Destroys the active session by stopping the WebSocket server and killing the + * Safari subprocess. + * @private + */ + destroySession_() { + var tasks = []; + if (this.server_) { + tasks.push(this.server_.stop()); + } + if (this.safari_) { + tasks.push(this.safari_.then(function(safari) { + safari.kill(); + return safari.result(); + })); + } + var self = this; + return promise.all(tasks).thenFinally(function() { + self.server_ = null; + self.socket_ = null; + self.safari_ = null; + }); + } +} + + + +/** @const */ +const OPTIONS_CAPABILITY_KEY = 'safari.options'; + + + +/** + * Configuration options specific to the {@link Driver SafariDriver}. + */ +class Options { + constructor() { + /** @private {Object} */ + this.options_ = null; + + /** @private {./lib/logging.Preferences} */ + this.logPrefs_ = null; + } + + /** + * Extracts the SafariDriver specific options from the given capabilities + * object. + * @param {!Capabilities} capabilities The capabilities object. + * @return {!Options} The ChromeDriver options. + */ + static fromCapabilities(capabilities) { + var options = new Options(); + + var o = capabilities.get(OPTIONS_CAPABILITY_KEY); + if (o instanceof Options) { + options = o; + } else if (o) { + options.setCleanSession(o.cleanSession); + } + + if (capabilities.has(Capability.LOGGING_PREFS)) { + options.setLoggingPrefs(capabilities.get(Capability.LOGGING_PREFS)); + } + + return options; + } + + /** + * Sets whether to force Safari to start with a clean session. Enabling this + * option will cause all global browser data to be deleted. + * @param {boolean} clean Whether to make sure the session has no cookies, + * cache entries, local storage, or databases. + * @return {!Options} A self reference. + */ + setCleanSession(clean) { + if (!this.options_) { + this.options_ = {}; + } + this.options_['cleanSession'] = clean; + return this; + } + + /** + * Sets the logging preferences for the new session. + * @param {!./lib/logging.Preferences} prefs The logging preferences. + * @return {!Options} A self reference. + */ + setLoggingPrefs(prefs) { + this.logPrefs_ = prefs; + return this; + } + + /** + * Converts this options instance to a {@link Capabilities} object. + * @param {Capabilities=} opt_capabilities The capabilities to + * merge these options into, if any. + * @return {!Capabilities} The capabilities. + */ + toCapabilities(opt_capabilities) { + var caps = opt_capabilities || Capabilities.safari(); + if (this.logPrefs_) { + caps.set(Capability.LOGGING_PREFS, this.logPrefs_); + } + if (this.options_) { + caps.set(OPTIONS_CAPABILITY_KEY, this); + } + return caps; + } + + /** + * Converts this instance to its JSON wire protocol representation. Note this + * function is an implementation detail not intended for general use. + * @return {!Object} The JSON wire protocol representation of this + * instance. + */ + [Symbols.serialize]() { + return this.options_ || {}; + } +} + + +/** + * A WebDriver client for Safari. This class should never be instantiated + * directly; instead, use the {@linkplain ./builder.Builder Builder}: + * + * var driver = new Builder() + * .forBrowser('safari') + * .build(); + * + */ +class Driver extends webdriver.WebDriver { + /** + * @param {(Options|Capabilities)=} opt_config The configuration + * options for the new session. + * @param {promise.ControlFlow=} opt_flow The control flow to create + * the driver under. + */ + constructor(opt_config, opt_flow) { + var executor = new CommandExecutor(); + var caps = + opt_config instanceof Options ? opt_config.toCapabilities() : + (opt_config || Capabilities.safari()); + + var driver = webdriver.WebDriver.createSession(executor, caps, opt_flow); + super(driver.getSession(), executor, driver.controlFlow()); + } +} + + +// Public API + + +exports.Driver = Driver; +exports.Options = Options; diff --git a/www/node_modules/selenium-webdriver/test/actions_test.js b/www/node_modules/selenium-webdriver/test/actions_test.js new file mode 100644 index 0000000..8d6794a --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/actions_test.js @@ -0,0 +1,53 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var Browser = require('..').Browser, + By = require('..').By, + until = require('..').until, + test = require('../lib/test'), + fileServer = require('../lib/test/fileserver'); + + +test.suite(function(env) { + var driver; + test.beforeEach(function() { driver = env.builder().build(); }); + test.afterEach(function() { driver.quit(); }); + + test.ignore(env.browsers(Browser.PHANTOM_JS, Browser.SAFARI)). + describe('WebDriver.actions()', function() { + + test.it('can move to and click element in an iframe', function() { + driver.get(fileServer.whereIs('click_tests/click_in_iframe.html')); + + driver.wait(until.elementLocated(By.id('ifr')), 5000) + .then(function(frame) { + driver.switchTo().frame(frame); + }); + + var link = driver.findElement(By.id('link')); + driver.actions() + .mouseMove(link) + .click() + .perform(); + + driver.wait(until.titleIs('Submitted Successfully!'), 5000); + }); + + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/chrome/options_test.js b/www/node_modules/selenium-webdriver/test/chrome/options_test.js new file mode 100644 index 0000000..28c4faa --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/chrome/options_test.js @@ -0,0 +1,227 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fs = require('fs'); + +var webdriver = require('../..'), + chrome = require('../../chrome'), + symbols = require('../../lib/symbols'), + proxy = require('../../proxy'), + assert = require('../../testing/assert'); + +var test = require('../../lib/test'); + + +describe('chrome.Options', function() { + describe('fromCapabilities', function() { + + it('should return a new Options instance if none were defined', + function() { + var options = chrome.Options.fromCapabilities( + new webdriver.Capabilities()); + assert(options).instanceOf(chrome.Options); + }); + + it('should return options instance if present', function() { + var options = new chrome.Options(); + var caps = options.toCapabilities(); + assert(caps).instanceOf(webdriver.Capabilities); + assert(chrome.Options.fromCapabilities(caps)).equalTo(options); + }); + + it('should rebuild options from wire representation', function() { + var expectedExtension = fs.readFileSync(__filename, 'base64'); + var caps = webdriver.Capabilities.chrome().set('chromeOptions', { + args: ['a', 'b'], + extensions: [__filename], + binary: 'binaryPath', + logPath: 'logFilePath', + detach: true, + localState: 'localStateValue', + prefs: 'prefsValue' + }); + + var options = chrome.Options.fromCapabilities(caps); + var json = options[symbols.serialize](); + + assert(json.args.length).equalTo(2); + assert(json.args[0]).equalTo('a'); + assert(json.args[1]).equalTo('b'); + assert(json.extensions.length).equalTo(1); + assert(json.extensions[0]).equalTo(expectedExtension); + assert(json.binary).equalTo('binaryPath'); + assert(json.logPath).equalTo('logFilePath'); + assert(json.detach).equalTo(true); + assert(json.localState).equalTo('localStateValue'); + assert(json.prefs).equalTo('prefsValue'); + }); + + it('should rebuild options from incomplete wire representation', + function() { + var caps = webdriver.Capabilities.chrome().set('chromeOptions', { + logPath: 'logFilePath' + }); + + var options = chrome.Options.fromCapabilities(caps); + var json = options[symbols.serialize](); + assert(json.args).isUndefined(); + assert(json.binary).isUndefined(); + assert(json.detach).isUndefined(); + assert(json.excludeSwitches).isUndefined(); + assert(json.extensions).isUndefined(); + assert(json.localState).isUndefined(); + assert(json.logPath).equalTo('logFilePath'); + assert(json.prefs).isUndefined(); + assert(json.minidumpPath).isUndefined(); + assert(json.mobileEmulation).isUndefined(); + assert(json.perfLoggingPrefs).isUndefined(); + }); + + it('should extract supported WebDriver capabilities', function() { + var proxyPrefs = proxy.direct(); + var logPrefs = {}; + var caps = webdriver.Capabilities.chrome(). + set(webdriver.Capability.PROXY, proxyPrefs). + set(webdriver.Capability.LOGGING_PREFS, logPrefs); + + var options = chrome.Options.fromCapabilities(caps); + assert(options.proxy_).equalTo(proxyPrefs); + assert(options.logPrefs_).equalTo(logPrefs); + }); + }); + + describe('addArguments', function() { + it('takes var_args', function() { + var options = new chrome.Options(); + assert(options[symbols.serialize]().args).isUndefined(); + + options.addArguments('a', 'b'); + var json = options[symbols.serialize](); + assert(json.args.length).equalTo(2); + assert(json.args[0]).equalTo('a'); + assert(json.args[1]).equalTo('b'); + }); + + it('flattens input arrays', function() { + var options = new chrome.Options(); + assert(options[symbols.serialize]().args).isUndefined(); + + options.addArguments(['a', 'b'], 'c', [1, 2], 3); + var json = options[symbols.serialize](); + assert(json.args.length).equalTo(6); + assert(json.args[0]).equalTo('a'); + assert(json.args[1]).equalTo('b'); + assert(json.args[2]).equalTo('c'); + assert(json.args[3]).equalTo(1); + assert(json.args[4]).equalTo(2); + assert(json.args[5]).equalTo(3); + }); + }); + + describe('addExtensions', function() { + it('takes var_args', function() { + var options = new chrome.Options(); + assert(options.extensions_.length).equalTo(0); + + options.addExtensions('a', 'b'); + assert(options.extensions_.length).equalTo(2); + assert(options.extensions_[0]).equalTo('a'); + assert(options.extensions_[1]).equalTo('b'); + }); + + it('flattens input arrays', function() { + var options = new chrome.Options(); + assert(options.extensions_.length).equalTo(0); + + options.addExtensions(['a', 'b'], 'c', [1, 2], 3); + assert(options.extensions_.length).equalTo(6); + assert(options.extensions_[0]).equalTo('a'); + assert(options.extensions_[1]).equalTo('b'); + assert(options.extensions_[2]).equalTo('c'); + assert(options.extensions_[3]).equalTo(1); + assert(options.extensions_[4]).equalTo(2); + assert(options.extensions_[5]).equalTo(3); + }); + }); + + describe('serialize', function() { + it('base64 encodes extensions', function() { + var expected = fs.readFileSync(__filename, 'base64'); + var wire = new chrome.Options() + .addExtensions(__filename) + [symbols.serialize](); + assert(wire.extensions.length).equalTo(1); + assert(wire.extensions[0]).equalTo(expected); + }); + }); + + describe('toCapabilities', function() { + it('returns a new capabilities object if one is not provided', function() { + var options = new chrome.Options(); + var caps = options.toCapabilities(); + assert(caps.get('browserName')).equalTo('chrome'); + assert(caps.get('chromeOptions')).equalTo(options); + }); + + it('adds to input capabilities object', function() { + var caps = webdriver.Capabilities.firefox(); + var options = new chrome.Options(); + assert(options.toCapabilities(caps)).equalTo(caps); + assert(caps.get('browserName')).equalTo('firefox'); + assert(caps.get('chromeOptions')).equalTo(options); + }); + + it('sets generic driver capabilities', function() { + var proxyPrefs = {}; + var loggingPrefs = {}; + var options = new chrome.Options(). + setLoggingPrefs(loggingPrefs). + setProxy(proxyPrefs); + + var caps = options.toCapabilities(); + assert(caps.get('proxy')).equalTo(proxyPrefs); + assert(caps.get('loggingPrefs')).equalTo(loggingPrefs); + }); + }); +}); + +test.suite(function(env) { + var driver; + + test.afterEach(function() { + driver.quit(); + }); + + describe('Chrome options', function() { + test.it('can start Chrome with custom args', function() { + var options = new chrome.Options(). + addArguments('user-agent=foo;bar'); + + driver = env.builder(). + setChromeOptions(options). + build(); + + driver.get(test.Pages.ajaxyPage); + + var userAgent = driver.executeScript( + 'return window.navigator.userAgent'); + assert(userAgent).equalTo('foo;bar'); + }); + }); +}, {browsers: ['chrome']}); diff --git a/www/node_modules/selenium-webdriver/test/chrome/service_test.js b/www/node_modules/selenium-webdriver/test/chrome/service_test.js new file mode 100644 index 0000000..0e0209e --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/chrome/service_test.js @@ -0,0 +1,45 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var webdriver = require('../..'), + chrome = require('../../chrome'), + assert = require('../../testing/assert'); + +var test = require('../../lib/test'); + + +test.suite(function(env) { + describe('chromedriver', function() { + var service; + test.afterEach(function() { + if (service) { + return service.kill(); + } + }); + + test.it('can be started on a custom path', function() { + service = new chrome.ServiceBuilder() + .setUrlBasePath('/foo/bar/baz') + .build(); + return service.start().then(function(url) { + assert(url).endsWith('/foo/bar/baz'); + }); + }); + }); +}, {browsers: ['chrome']}); \ No newline at end of file diff --git a/www/node_modules/selenium-webdriver/test/cookie_test.js b/www/node_modules/selenium-webdriver/test/cookie_test.js new file mode 100644 index 0000000..fe4c839 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/cookie_test.js @@ -0,0 +1,206 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'), + url = require('url'); + +var test = require('../lib/test'), + fileserver = require('../lib/test/fileserver'), + Browser = require('..').Browser, + Pages = test.Pages; + + +test.suite(function(env) { + var driver; + + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + test.ignore(env.browsers(Browser.SAFARI)). // Cookie handling is broken. + describe('Cookie Management;', function() { + + test.beforeEach(function() { + driver.get(fileserver.Pages.ajaxyPage); + driver.manage().deleteAllCookies(); + assertHasCookies(); + }); + + test.it('can add new cookies', function() { + var cookie = createCookieSpec(); + + driver.manage().addCookie(cookie.name, cookie.value); + driver.manage().getCookie(cookie.name).then(function(actual) { + assert.equal(actual.value, cookie.value); + }); + }); + + test.it('can get all cookies', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.manage().addCookie(cookie1.name, cookie1.value); + driver.manage().addCookie(cookie2.name, cookie2.value); + + assertHasCookies(cookie1, cookie2); + }); + + test.ignore(env.browsers(Browser.IE)). + it('only returns cookies visible to the current page', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.manage().addCookie(cookie1.name, cookie1.value); + + var pageUrl = fileserver.whereIs('page/1'); + driver.get(pageUrl); + driver.manage().addCookie( + cookie2.name, cookie2.value, url.parse(pageUrl).pathname); + assertHasCookies(cookie1, cookie2); + + driver.get(fileserver.Pages.ajaxyPage); + assertHasCookies(cookie1); + + driver.get(pageUrl); + assertHasCookies(cookie1, cookie2); + }); + + test.it('can delete all cookies', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.executeScript( + 'document.cookie = arguments[0] + "=" + arguments[1];' + + 'document.cookie = arguments[2] + "=" + arguments[3];', + cookie1.name, cookie1.value, cookie2.name, cookie2.value); + assertHasCookies(cookie1, cookie2); + + driver.manage().deleteAllCookies(); + assertHasCookies(); + }); + + test.it('can delete cookies by name', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + + driver.executeScript( + 'document.cookie = arguments[0] + "=" + arguments[1];' + + 'document.cookie = arguments[2] + "=" + arguments[3];', + cookie1.name, cookie1.value, cookie2.name, cookie2.value); + assertHasCookies(cookie1, cookie2); + + driver.manage().deleteCookie(cookie1.name); + assertHasCookies(cookie2); + }); + + test.it('should only delete cookie with exact name', function() { + var cookie1 = createCookieSpec(); + var cookie2 = createCookieSpec(); + var cookie3 = {name: cookie1.name + 'xx', value: cookie1.value}; + + driver.executeScript( + 'document.cookie = arguments[0] + "=" + arguments[1];' + + 'document.cookie = arguments[2] + "=" + arguments[3];' + + 'document.cookie = arguments[4] + "=" + arguments[5];', + cookie1.name, cookie1.value, cookie2.name, cookie2.value, + cookie3.name, cookie3.value); + assertHasCookies(cookie1, cookie2, cookie3); + + driver.manage().deleteCookie(cookie1.name); + assertHasCookies(cookie2, cookie3); + }); + + test.it('can delete cookies set higher in the path', function() { + var cookie = createCookieSpec(); + var childUrl = fileserver.whereIs('child/childPage.html'); + var grandchildUrl = fileserver.whereIs( + 'child/grandchild/grandchildPage.html'); + + driver.get(childUrl); + driver.manage().addCookie(cookie.name, cookie.value); + assertHasCookies(cookie); + + driver.get(grandchildUrl); + assertHasCookies(cookie); + + driver.manage().deleteCookie(cookie.name); + assertHasCookies(); + + driver.get(childUrl); + assertHasCookies(); + }); + + test.ignore(env.browsers(Browser.ANDROID, Browser.FIREFOX, Browser.IE)). + it('should retain cookie expiry', function() { + var cookie = createCookieSpec(); + var expirationDelay = 5 * 1000; + var futureTime = Date.now() + expirationDelay; + + driver.manage().addCookie( + cookie.name, cookie.value, null, null, false, futureTime); + driver.manage().getCookie(cookie.name).then(function(actual) { + assert.equal(actual.value, cookie.value); + // expiry times are exchanged in seconds since January 1, 1970 UTC. + assert.equal(actual.expiry, Math.floor(futureTime / 1000)); + }); + + driver.sleep(expirationDelay); + assertHasCookies(); + }); + }); + + function createCookieSpec() { + return { + name: getRandomString(), + value: getRandomString() + }; + } + + function buildCookieMap(cookies) { + var map = {}; + cookies.forEach(function(cookie) { + map[cookie.name] = cookie; + }); + return map; + } + + function assertHasCookies(var_args) { + var expected = Array.prototype.slice.call(arguments, 0); + driver.manage().getCookies().then(function(cookies) { + assert.equal(cookies.length, expected.length, + 'Wrong # of cookies.' + + '\n Expected: ' + JSON.stringify(expected) + + '\n Was : ' + JSON.stringify(cookies)); + + var map = buildCookieMap(cookies); + for (var i = 0; i < expected.length; ++i) { + assert.equal(expected[i].value, map[expected[i].name].value); + } + }); + } + + function getRandomString() { + var x = 1234567890; + return Math.floor(Math.random() * x).toString(36); + } +}); diff --git a/www/node_modules/selenium-webdriver/test/element_finding_test.js b/www/node_modules/selenium-webdriver/test/element_finding_test.js new file mode 100644 index 0000000..3d56b54 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/element_finding_test.js @@ -0,0 +1,392 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fail = require('assert').fail; + +var Browser = require('..').Browser, + By = require('..').By, + error = require('..').error, + until = require('..').until, + promise = require('../lib/promise'), + test = require('../lib/test'), + assert = require('../testing/assert'), + Pages = test.Pages; + + +test.suite(function(env) { + var browsers = env.browsers; + + var driver; + + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + describe('finding elements', function() { + test.it( + 'should work after loading multiple pages in a row', + function() { + driver.get(Pages.formPage); + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.linkText('click me')).click(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + }); + + describe('By.id()', function() { + test.it('should work', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.id('linkId')).click(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + }); + + test.it('should fail if ID not present on page', function() { + driver.get(Pages.formPage); + driver.findElement(By.id('nonExistantButton')). + then(fail, function(e) { + assert(e).instanceOf(error.NoSuchElementError); + }); + }); + + test.it( + 'should find multiple elements by ID even though that is ' + + 'malformed HTML', + function() { + driver.get(Pages.nestedPage); + driver.findElements(By.id('2')).then(function(elements) { + assert(elements.length).equalTo(8); + }); + }); + }); + + describe('By.linkText()', function() { + test.it('should be able to click on link identified by text', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.linkText('click me')).click(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + }); + + test.it( + 'should be able to find elements by partial link text', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.partialLinkText('ick me')).click(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + }); + + test.it('should work when link text contains equals sign', function() { + driver.get(Pages.xhtmlTestPage); + var id = driver.findElement(By.linkText('Link=equalssign')). + getAttribute('id'); + assert(id).equalTo('linkWithEqualsSign'); + }); + + test.it('matches by partial text when containing equals sign', + function() { + driver.get(Pages.xhtmlTestPage); + var id = driver.findElement(By.partialLinkText('Link=')). + getAttribute('id'); + assert(id).equalTo('linkWithEqualsSign'); + }); + + test.it('works when searching for multiple and text contains =', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.linkText('Link=equalssign')). + then(function(elements) { + assert(elements.length).equalTo(1); + return elements[0].getAttribute('id'); + }). + then(function(id) { + assert(id).equalTo('linkWithEqualsSign'); + }); + }); + + test.it( + 'works when searching for multiple with partial text containing =', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.partialLinkText('Link=')). + then(function(elements) { + assert(elements.length).equalTo(1); + return elements[0].getAttribute('id'); + }). + then(function(id) { + assert(id).equalTo('linkWithEqualsSign'); + }); + }); + + test.it('should be able to find multiple exact matches', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.linkText('click me')). + then(function(elements) { + assert(elements.length).equalTo(2); + }); + }); + + test.it('should be able to find multiple partial matches', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.partialLinkText('ick me')). + then(function(elements) { + assert(elements.length).equalTo(2); + }); + }); + + test.it('works on XHTML pages', function() { + driver.get(test.whereIs('actualXhtmlPage.xhtml')); + + var el = driver.findElement(By.linkText('Foo')); + assert(el.getText()).equalTo('Foo'); + }); + }); + + describe('By.name()', function() { + test.it('should work', function() { + driver.get(Pages.formPage); + + var el = driver.findElement(By.name('checky')); + assert(el.getAttribute('value')).equalTo('furrfu'); + }); + + test.it('should find multiple elements with same name', function() { + driver.get(Pages.nestedPage); + driver.findElements(By.name('checky')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + + test.it( + 'should be able to find elements that do not support name property', + function() { + driver.get(Pages.nestedPage); + driver.findElement(By.name('div1')); + // Pass if this does not return an error. + }); + + test.it('shoudl be able to find hidden elements by name', function() { + driver.get(Pages.formPage); + driver.findElement(By.name('hidden')); + // Pass if this does not return an error. + }); + }); + + describe('By.className()', function() { + test.it('should work', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('extraDiv')); + assert(el.getText()).startsWith('Another div starts here.'); + }); + + test.it('should work when name is first name among many', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('nameA')); + assert(el.getText()).equalTo('An H2 title'); + }); + + test.it('should work when name is last name among many', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('nameC')); + assert(el.getText()).equalTo('An H2 title'); + }); + + test.it('should work when name is middle of many', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('nameBnoise')); + assert(el.getText()).equalTo('An H2 title'); + }); + + test.it('should work when name surrounded by whitespace', function() { + driver.get(Pages.xhtmlTestPage); + + var el = driver.findElement(By.className('spaceAround')); + assert(el.getText()).equalTo('Spaced out'); + }); + + test.it('should fail if queried name only partially matches', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.className('nameB')). + then(fail, function(e) { + assert(e).instanceOf(error.NoSuchElementError); + }); + }); + + test.it('should be able to find multiple matches', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.className('nameC')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + + test.it('permits compound class names', function() { + return driver.get(Pages.xhtmlTestPage) + .then(() => driver.findElement(By.className('nameA nameC'))) + .then(el => el.getText()) + .then(text => assert(text).equalTo('An H2 title')); + }); + }); + + describe('By.xpath()', function() { + test.it('should work with multiple matches', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.xpath('//div')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + + test.it('should work for selectors using contains keyword', function() { + driver.get(Pages.nestedPage); + driver.findElement(By.xpath('//a[contains(., "hello world")]')); + // Pass if no error. + }); + }); + + describe('By.tagName()', function() { + test.it('works', function() { + driver.get(Pages.formPage); + + var el = driver.findElement(By.tagName('input')); + assert(el.getTagName()).equalTo('input'); + }); + + test.it('can find multiple elements', function() { + driver.get(Pages.formPage); + driver.findElements(By.tagName('input')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + }); + }); + + describe('By.css()', function() { + test.it('works', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElement(By.css('div.content')); + // Pass if no error. + }); + + test.it('can find multiple elements', function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.css('p')).then(function(elements) { + assert(elements.length).greaterThan(1); + }); + // Pass if no error. + }); + + test.it( + 'should find first matching element when searching by ' + + 'compound CSS selector', + function() { + driver.get(Pages.xhtmlTestPage); + var el = driver.findElement(By.css('div.extraDiv, div.content')); + assert(el.getAttribute('class')).equalTo('content'); + }); + + test.it('should be able to find multiple elements by compound selector', + function() { + driver.get(Pages.xhtmlTestPage); + driver.findElements(By.css('div.extraDiv, div.content')). + then(function(elements) { + assertClassIs(elements[0], 'content'); + assertClassIs(elements[1], 'extraDiv'); + + function assertClassIs(el, expected) { + assert(el.getAttribute('class')).equalTo(expected); + } + }); + }); + + // IE only supports short version option[selected]. + test.ignore(browsers(Browser.IE)). + it('should be able to find element by boolean attribute', function() { + driver.get(test.whereIs( + 'locators_tests/boolean_attribute_selected.html')); + + var el = driver.findElement(By.css('option[selected="selected"]')); + assert(el.getAttribute('value')).equalTo('two'); + }); + + test.it( + 'should be able to find element with short ' + + 'boolean attribute selector', + function() { + driver.get(test.whereIs( + 'locators_tests/boolean_attribute_selected.html')); + + var el = driver.findElement(By.css('option[selected]')); + assert(el.getAttribute('value')).equalTo('two'); + }); + + test.it( + 'should be able to find element with short boolean attribute ' + + 'selector on HTML4 page', + function() { + driver.get(test.whereIs( + 'locators_tests/boolean_attribute_selected_html4.html')); + + var el = driver.findElement(By.css('option[selected]')); + assert(el.getAttribute('value')).equalTo('two'); + }); + }); + + describe('by custom locator', function() { + test.it('handles single element result', function() { + driver.get(Pages.javascriptPage); + + let link = driver.findElement(function(driver) { + let links = driver.findElements(By.tagName('a')); + return promise.filter(links, function(link) { + return link.getAttribute('id').then(id => id === 'updatediv'); + }).then(links => links[0]); + }); + + assert(link.getText()).isEqualTo('Update a div'); + }); + + test.it('uses first element if locator resolves to list', function() { + driver.get(Pages.javascriptPage); + + let link = driver.findElement(function() { + return driver.findElements(By.tagName('a')); + }); + + assert(link.getText()).isEqualTo('Change the page title!'); + }); + + test.it('fails if locator returns non-webelement value', function() { + driver.get(Pages.javascriptPage); + + let link = driver.findElement(function() { + return driver.getTitle(); + }); + + return link.then( + () => fail('Should have failed'), + (e) => assert(e).instanceOf(TypeError)); + }); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/error_test.js b/www/node_modules/selenium-webdriver/test/error_test.js new file mode 100644 index 0000000..c80423e --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/error_test.js @@ -0,0 +1,163 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +describe('error', function() { + let assert = require('assert'); + let error = require('../error'); + + describe('checkResponse', function() { + it('defaults to WebDriverError if type is unrecognized', function() { + assert.throws( + () => error.checkResponse({error: 'foo', message: 'hi there'}), + (e) => { + assert.equal(e.constructor, error.WebDriverError); + assert.equal(e.code, error.ErrorCode.UNKNOWN_ERROR); + return true; + }); + }); + + it('does not throw if error property is not a string', function() { + let resp = {error: 123, message: 'abc123'}; + let out = error.checkResponse(resp); + assert.strictEqual(out, resp); + }); + + test('unknown error', error.WebDriverError); + test('element not selectable', error.ElementNotSelectableError); + test('element not visible', error.ElementNotVisibleError); + test('invalid argument', error.InvalidArgumentError); + test('invalid cookie domain', error.InvalidCookieDomainError); + test('invalid element coordinates', error.InvalidElementCoordinatesError); + test('invalid element state', error.InvalidElementStateError); + test('invalid selector', error.InvalidSelectorError); + test('invalid session id', error.InvalidSessionIdError); + test('javascript error', error.JavascriptError); + test('move target out of bounds', error.MoveTargetOutOfBoundsError); + test('no such alert', error.NoSuchAlertError); + test('no such element', error.NoSuchElementError); + test('no such frame', error.NoSuchFrameError); + test('no such window', error.NoSuchWindowError); + test('script timeout', error.ScriptTimeoutError); + test('session not created', error.SessionNotCreatedError); + test('stale element reference', error.StaleElementReferenceError); + test('timeout', error.TimeoutError); + test('unable to set cookie', error.UnableToSetCookieError); + test('unable to capture screen', error.UnableToCaptureScreenError); + test('unexpected alert open', error.UnexpectedAlertOpenError); + test('unknown command', error.UnknownCommandError); + test('unknown method', error.UnknownMethodError); + test('unsupported operation', error.UnsupportedOperationError); + + function test(status, expectedType) { + it(`"${status}" => ${expectedType.name}`, function() { + assert.throws( + () => error.checkResponse({error: status, message: 'oops'}), + (e) => { + assert.equal(expectedType, e.constructor); + assert.equal(e.message, 'oops'); + return true; + }); + }); + } + }); + + describe('checkLegacyResponse', function() { + it('does not throw for success', function() { + let resp = {status: error.ErrorCode.SUCCESS}; + assert.strictEqual(resp, error.checkLegacyResponse(resp)); + }); + + test('NO_SUCH_ELEMENT', error.NoSuchElementError); + test('NO_SUCH_FRAME', error.NoSuchFrameError); + test('UNKNOWN_COMMAND', error.UnsupportedOperationError); + test('UNSUPPORTED_OPERATION', error.UnsupportedOperationError); + test('STALE_ELEMENT_REFERENCE', error.StaleElementReferenceError); + test('ELEMENT_NOT_VISIBLE', error.ElementNotVisibleError); + test('INVALID_ELEMENT_STATE', error.InvalidElementStateError); + test('UNKNOWN_ERROR', error.WebDriverError); + test('ELEMENT_NOT_SELECTABLE', error.ElementNotSelectableError); + test('JAVASCRIPT_ERROR', error.JavascriptError); + test('XPATH_LOOKUP_ERROR', error.InvalidSelectorError); + test('TIMEOUT', error.TimeoutError); + test('NO_SUCH_WINDOW', error.NoSuchWindowError); + test('INVALID_COOKIE_DOMAIN', error.InvalidCookieDomainError); + test('UNABLE_TO_SET_COOKIE', error.UnableToSetCookieError); + test('UNEXPECTED_ALERT_OPEN', error.UnexpectedAlertOpenError); + test('NO_SUCH_ALERT', error.NoSuchAlertError); + test('SCRIPT_TIMEOUT', error.ScriptTimeoutError); + test('INVALID_ELEMENT_COORDINATES', error.InvalidElementCoordinatesError); + test('INVALID_SELECTOR_ERROR', error.InvalidSelectorError); + test('SESSION_NOT_CREATED', error.SessionNotCreatedError); + test('MOVE_TARGET_OUT_OF_BOUNDS', error.MoveTargetOutOfBoundsError); + test('INVALID_XPATH_SELECTOR', error.InvalidSelectorError); + test('INVALID_XPATH_SELECTOR_RETURN_TYPE', error.InvalidSelectorError); + test('METHOD_NOT_ALLOWED', error.UnsupportedOperationError); + + function test(codeKey, expectedType) { + it(`${codeKey} => ${expectedType.name}`, function() { + let code = error.ErrorCode[codeKey]; + let resp = {status: code, value: {message: 'hi'}}; + assert.throws( + () => error.checkLegacyResponse(resp), + (e) => { + assert.equal(expectedType, e.constructor); + assert.equal(e.message, 'hi'); + return true; + }); + }); + } + }); + + describe('WebDriverError types provide a legacy error code', function() { + check(error.WebDriverError, 'UNKNOWN_ERROR'); + check(error.ElementNotSelectableError, 'ELEMENT_NOT_SELECTABLE'); + check(error.ElementNotVisibleError, 'ELEMENT_NOT_VISIBLE'); + check(error.InvalidArgumentError, 'UNKNOWN_ERROR'); + check(error.InvalidCookieDomainError, 'INVALID_COOKIE_DOMAIN'); + check(error.InvalidElementCoordinatesError, 'INVALID_ELEMENT_COORDINATES'); + check(error.InvalidElementStateError, 'INVALID_ELEMENT_STATE'); + check(error.InvalidSelectorError, 'INVALID_SELECTOR_ERROR'); + check(error.InvalidSessionIdError, 'UNKNOWN_ERROR'); + check(error.JavascriptError, 'JAVASCRIPT_ERROR'); + check(error.MoveTargetOutOfBoundsError, 'MOVE_TARGET_OUT_OF_BOUNDS'); + check(error.NoSuchAlertError, 'NO_SUCH_ALERT'); + check(error.NoSuchElementError, 'NO_SUCH_ELEMENT'); + check(error.NoSuchFrameError, 'NO_SUCH_FRAME'); + check(error.NoSuchWindowError, 'NO_SUCH_WINDOW'); + check(error.ScriptTimeoutError, 'SCRIPT_TIMEOUT'); + check(error.SessionNotCreatedError, 'SESSION_NOT_CREATED'); + check(error.StaleElementReferenceError, 'STALE_ELEMENT_REFERENCE'); + check(error.TimeoutError, 'TIMEOUT'); + check(error.UnableToSetCookieError, 'UNABLE_TO_SET_COOKIE'); + check(error.UnableToCaptureScreenError, 'UNKNOWN_ERROR'); + check(error.UnexpectedAlertOpenError, 'UNEXPECTED_ALERT_OPEN'); + check(error.UnknownCommandError, 'UNKNOWN_COMMAND'); + check(error.UnknownMethodError, 'UNSUPPORTED_OPERATION'); + check(error.UnsupportedOperationError, 'UNSUPPORTED_OPERATION'); + + function check(ctor, codeKey) { + it(`${ctor.name} => ${codeKey}`, function() { + let code = error.ErrorCode[codeKey]; + let e = new ctor(); + assert.equal(typeof e.code, 'number'); + assert.equal(e.code, code); + }); + } + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/execute_script_test.js b/www/node_modules/selenium-webdriver/test/execute_script_test.js new file mode 100644 index 0000000..8d3b099 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/execute_script_test.js @@ -0,0 +1,322 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var path = require('path'); + +var webdriver = require('..'), + Browser = webdriver.Browser, + By = webdriver.By, + assert = require('../testing/assert'), + test = require('../lib/test'); + + +test.suite(function(env) { + var driver; + + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + test.beforeEach(function() { + driver.get(test.Pages.echoPage); + }); + + describe('executeScript;', function() { + var shouldHaveFailed = new Error('Should have failed'); + + test.it('fails if script throws', function() { + execute('throw new Error("boom")') + .then(function() { throw shoudlHaveFailed; }) + .thenCatch(function(e) { + // The java WebDriver server adds a bunch of crap to error messages. + // Error message will just be "JavaScript error" for IE. + assert(e.message).matches(/.*(JavaScript error|boom).*/); + }); + }); + + test.it('fails if script does not parse', function() { + execute('throw function\\*') + .then(function() { throw shoudlHaveFailed; }) + .thenCatch(function(e) { + assert(e).notEqualTo(shouldHaveFailed); + }); + }); + + describe('scripts;', function() { + test.it('do not pollute the global scope', function() { + execute('var x = 1;'); + assert(execute('return typeof x;')).equalTo('undefined'); + }); + + test.it('can set global variables', function() { + execute('window.x = 1234;'); + assert(execute('return x;')).equalTo(1234); + }); + + test.it('may be defined as a function expression', function() { + assert(execute(function() { + return 1234 + 'abc'; + })).equalTo('1234abc'); + }); + }); + + describe('return values;', function() { + + test.it('returns undefined as null', function() { + assert(execute('var x; return x;')).isNull(); + }); + + test.it('can return null', function() { + assert(execute('return null;')).isNull(); + }); + + test.it('can return numbers', function() { + assert(execute('return 1234')).equalTo(1234); + assert(execute('return 3.1456')).equalTo(3.1456); + }); + + test.it('can return strings', function() { + assert(execute('return "hello"')).equalTo('hello'); + }); + + test.it('can return booleans', function() { + assert(execute('return true')).equalTo(true); + assert(execute('return false')).equalTo(false); + }); + + test.it('can return an array of primitives', function() { + execute('var x; return [1, false, null, 3.14, x]') + .then(verifyJson([1, false, null, 3.14, null])); + }); + + test.it('can return nested arrays', function() { + execute('return [[1, 2, [3]]]') + .then(verifyJson([[1, 2, [3]]])); + }); + + test.ignore(env.browsers(Browser.IE, Browser.SAFARI)). + it('can return empty object literal', function() { + execute('return {}').then(verifyJson({})); + }); + + test.it('can return object literals', function() { + execute('return {a: 1, b: false, c: null}').then(function(result) { + verifyJson(['a', 'b', 'c'])(Object.keys(result).sort()); + assert(result.a).equalTo(1); + assert(result.b).equalTo(false); + assert(result.c).isNull(); + }); + }); + + test.it('can return complex object literals', function() { + execute('return {a:{b: "hello"}}').then(verifyJson({a:{b: 'hello'}})); + }); + + test.it('can return dom elements as web elements', function() { + execute('return document.querySelector(".header.host")') + .then(function(result) { + assert(result).instanceOf(webdriver.WebElement); + assert(result.getText()).startsWith('host: '); + }); + }); + + test.it('can return array of dom elements', function() { + execute('var nodes = document.querySelectorAll(".request,.host");' + + 'return [nodes[0], nodes[1]];') + .then(function(result) { + assert(result.length).equalTo(2); + + assert(result[0]).instanceOf(webdriver.WebElement); + assert(result[0].getText()).startsWith('GET '); + + assert(result[1]).instanceOf(webdriver.WebElement); + assert(result[1].getText()).startsWith('host: '); + }); + }); + + test.it('can return a NodeList as an array of web elements', function() { + execute('return document.querySelectorAll(".request,.host");') + .then(function(result) { + assert(result.length).equalTo(2); + + assert(result[0]).instanceOf(webdriver.WebElement); + assert(result[0].getText()).startsWith('GET '); + + assert(result[1]).instanceOf(webdriver.WebElement); + assert(result[1].getText()).startsWith('host: '); + }); + }); + + test.it('can return object literal with element property', function() { + execute('return {a: document.body}').then(function(result) { + assert(result.a).instanceOf(webdriver.WebElement); + assert(result.a.getTagName()).equalTo('body'); + }); + }); + }); + + describe('parameters;', function() { + test.it('can pass numeric arguments', function() { + assert(execute('return arguments[0]', 12)).equalTo(12); + assert(execute('return arguments[0]', 3.14)).equalTo(3.14); + }); + + test.it('can pass boolean arguments', function() { + assert(execute('return arguments[0]', true)).equalTo(true); + assert(execute('return arguments[0]', false)).equalTo(false); + }); + + test.it('can pass string arguments', function() { + assert(execute('return arguments[0]', 'hi')).equalTo('hi'); + }); + + test.it('can pass null arguments', function() { + assert(execute('return arguments[0] === null', null)).equalTo(true); + assert(execute('return arguments[0]', null)).equalTo(null); + }); + + test.it('passes undefined as a null argument', function() { + var x; + assert(execute('return arguments[0] === null', x)).equalTo(true); + assert(execute('return arguments[0]', x)).equalTo(null); + }); + + test.it('can pass multiple arguments', function() { + assert(execute('return arguments.length')).equalTo(0); + assert(execute('return arguments.length', 1, 'a', false)).equalTo(3); + }); + + test.it('can return arguments object as array', function() { + execute('return arguments', 1, 'a', false).then(function(val) { + assert(val.length).equalTo(3); + assert(val[0]).equalTo(1); + assert(val[1]).equalTo('a'); + assert(val[2]).equalTo(false); + }); + }); + + test.it('can pass object literal', function() { + execute( + 'return [typeof arguments[0], arguments[0].a]', {a: 'hello'}) + .then(function(result) { + assert(result[0]).equalTo('object'); + assert(result[1]).equalTo('hello'); + }); + }); + + test.it('WebElement arguments are passed as DOM elements', function() { + var el = driver.findElement(By.tagName('div')); + assert(execute('return arguments[0].tagName.toLowerCase();', el)) + .equalTo('div'); + }); + + test.it('can pass array containing object literals', function() { + execute('return arguments[0]', [{color: "red"}]).then(function(result) { + assert(result.length).equalTo(1); + assert(result[0].color).equalTo('red'); + }); + }); + + test.it('does not modify object literal parameters', function() { + var input = {color: 'red'}; + execute('return arguments[0];', input).then(verifyJson(input)); + }); + }); + + // See https://code.google.com/p/selenium/issues/detail?id=8223. + describe('issue 8223;', function() { + describe('using for..in loops;', function() { + test.it('can return array built from for-loop index', function() { + execute(function() { + var ret = []; + for (var i = 0; i < 3; i++) { + ret.push(i); + } + return ret; + }).then(verifyJson[0, 1, 2]); + }); + + test.it('can copy input array contents', function() { + execute(function(input) { + var ret = []; + for (var i in input) { + ret.push(input[i]); + } + return ret; + }, ['fa', 'fe', 'fi']).then(verifyJson(['fa', 'fe', 'fi'])); + }); + + test.it('can iterate over input object keys', function() { + execute(function(thing) { + var ret = []; + for (var w in thing.words) { + ret.push(thing.words[w].word); + } + return ret; + }, {words: [{word: 'fa'}, {word: 'fe'}, {word: 'fi'}]}) + .then(verifyJson(['fa', 'fe', 'fi'])); + }); + + describe('recursive functions;', function() { + test.it('can build array from input', function() { + var input = ['fa', 'fe', 'fi']; + execute(function(thearray) { + var ret = []; + function build_response(thearray, ret) { + ret.push(thearray.shift()); + return (!thearray.length && ret + || build_response(thearray, ret)); + } + return build_response(thearray, ret); + }, input).then(verifyJson(input)); + }); + + test.it('can build array from elements in object', function() { + var input = {words: [{word: 'fa'}, {word: 'fe'}, {word: 'fi'}]}; + execute(function(thing) { + var ret = []; + function build_response(thing, ret) { + var item = thing.words.shift(); + ret.push(item.word); + return (!thing.words.length && ret + || build_response(thing, ret)); + } + return build_response(thing, ret); + }, input).then(verifyJson(['fa', 'fe', 'fi'])); + }); + }); + }); + }); + + }); + + function verifyJson(expected) { + return function(actual) { + assert(JSON.stringify(actual)).equalTo(JSON.stringify(expected)); + }; + } + + function execute() { + return driver.executeScript.apply(driver, arguments); + } +}); diff --git a/www/node_modules/selenium-webdriver/test/fingerprint_test.js b/www/node_modules/selenium-webdriver/test/fingerprint_test.js new file mode 100644 index 0000000..5a64494 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/fingerprint_test.js @@ -0,0 +1,57 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('../testing/assert'), + test = require('../lib/test'), + Pages = test.Pages; + + +test.suite(function(env) { + var browsers = env.browsers; + + var driver; + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + describe('fingerprinting', function() { + test.it('it should fingerprint the navigator object', function() { + driver.get(Pages.simpleTestPage); + assert(driver.executeScript('return navigator.webdriver')).equalTo(true); + }); + + test.it('fingerprint must not be writable', function() { + driver.get(Pages.simpleTestPage); + assert(driver.executeScript( + 'navigator.webdriver = "ohai"; return navigator.webdriver')) + .equalTo(true); + }); + + test.it('leaves fingerprint on svg pages', function() { + driver.get(Pages.svgPage); + assert(driver.executeScript('return navigator.webdriver')).equalTo(true); + }); + }); + +// Currently only implemented in firefox. +}, {browsers: ['firefox']}); diff --git a/www/node_modules/selenium-webdriver/test/firefox/extension_test.js b/www/node_modules/selenium-webdriver/test/firefox/extension_test.js new file mode 100644 index 0000000..50936f7 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/firefox/extension_test.js @@ -0,0 +1,96 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var AdmZip = require('adm-zip'), + assert = require('assert'), + crypto = require('crypto'), + fs = require('fs'), + path = require('path'); + +var extension = require('../../firefox/extension'), + io = require('../../io'), + it = require('../../testing').it; + + +var JETPACK_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/jetpack-sample.xpi'); +var NORMAL_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/sample.xpi'); + +var JETPACK_EXTENSION_ID = 'jid1-EaXX7k0wwiZR7w@jetpack'; +var NORMAL_EXTENSION_ID = 'sample@seleniumhq.org'; + + +describe('extension', function() { + it('can install a jetpack xpi file', function() { + return io.tmpDir().then(function(dir) { + return extension.install(JETPACK_EXTENSION, dir).then(function(id) { + assert.equal(JETPACK_EXTENSION_ID, id); + var file = path.join(dir, id + '.xpi'); + assert.ok(fs.existsSync(file), 'no such file: ' + file); + assert.ok(!fs.statSync(file).isDirectory()); + + var copiedSha1 = crypto.createHash('sha1') + .update(fs.readFileSync(file)) + .digest('hex'); + + var goldenSha1 = crypto.createHash('sha1') + .update(fs.readFileSync(JETPACK_EXTENSION)) + .digest('hex'); + + assert.equal(copiedSha1, goldenSha1); + }); + }); + }); + + it('can install a normal xpi file', function() { + return io.tmpDir().then(function(dir) { + return extension.install(NORMAL_EXTENSION, dir).then(function(id) { + assert.equal(NORMAL_EXTENSION_ID, id); + + var file = path.join(dir, NORMAL_EXTENSION_ID); + assert.ok(fs.statSync(file).isDirectory()); + + assert.ok(fs.existsSync(path.join(file, 'chrome.manifest'))); + assert.ok(fs.existsSync(path.join(file, 'content/overlay.xul'))); + assert.ok(fs.existsSync(path.join(file, 'content/overlay.js'))); + assert.ok(fs.existsSync(path.join(file, 'install.rdf'))); + }); + }); + }); + + it('can install an extension from a directory', function() { + return io.tmpDir().then(function(srcDir) { + var buf = fs.readFileSync(NORMAL_EXTENSION); + new AdmZip(buf).extractAllTo(srcDir, true); + return io.tmpDir().then(function(dstDir) { + return extension.install(srcDir, dstDir).then(function(id) { + assert.equal(NORMAL_EXTENSION_ID, id); + + var dir = path.join(dstDir, NORMAL_EXTENSION_ID); + + assert.ok(fs.existsSync(path.join(dir, 'chrome.manifest'))); + assert.ok(fs.existsSync(path.join(dir, 'content/overlay.xul'))); + assert.ok(fs.existsSync(path.join(dir, 'content/overlay.js'))); + assert.ok(fs.existsSync(path.join(dir, 'install.rdf'))); + }); + }); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/firefox/firefox_test.js b/www/node_modules/selenium-webdriver/test/firefox/firefox_test.js new file mode 100644 index 0000000..0a32940 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/firefox/firefox_test.js @@ -0,0 +1,183 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var path = require('path'); + +var firefox = require('../../firefox'), + io = require('../../io'), + test = require('../../lib/test'), + assert = require('../../testing/assert'); + + +var JETPACK_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/jetpack-sample.xpi'); +var NORMAL_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/sample.xpi'); + + +test.suite(function(env) { + describe('firefox', function() { + describe('Options', function() { + var driver; + + test.beforeEach(function() { + driver = null; + }); + + test.afterEach(function() { + if (driver) { + driver.quit(); + } + }); + + test.it('can start Firefox with custom preferences', function() { + var profile = new firefox.Profile(); + profile.setPreference('general.useragent.override', 'foo;bar'); + + var options = new firefox.Options().setProfile(profile); + + driver = env.builder(). + setFirefoxOptions(options). + build(); + + driver.get('data:text/html,
    content
    '); + + var userAgent = driver.executeScript( + 'return window.navigator.userAgent'); + assert(userAgent).equalTo('foo;bar'); + }); + + test.it('can start Firefox with a jetpack extension', function() { + var profile = new firefox.Profile(); + profile.addExtension(JETPACK_EXTENSION); + + var options = new firefox.Options().setProfile(profile); + + driver = env.builder(). + setFirefoxOptions(options). + build(); + + loadJetpackPage(driver, + 'data:text/html;charset=UTF-8,
    content
    '); + assert(driver.findElement({id: 'jetpack-sample-banner'}).getText()) + .equalTo('Hello, world!'); + }); + + test.it('can start Firefox with a normal extension', function() { + var profile = new firefox.Profile(); + profile.addExtension(NORMAL_EXTENSION); + + var options = new firefox.Options().setProfile(profile); + + driver = env.builder(). + setFirefoxOptions(options). + build(); + + driver.get('data:text/html,
    content
    '); + assert(driver.findElement({id: 'sample-extension-footer'}).getText()) + .equalTo('Goodbye'); + }); + + test.it('can start Firefox with multiple extensions', function() { + var profile = new firefox.Profile(); + profile.addExtension(JETPACK_EXTENSION); + profile.addExtension(NORMAL_EXTENSION); + + var options = new firefox.Options().setProfile(profile); + + driver = env.builder(). + setFirefoxOptions(options). + build(); + + loadJetpackPage(driver, + 'data:text/html;charset=UTF-8,
    content
    '); + assert(driver.findElement({id: 'jetpack-sample-banner'}).getText()) + .equalTo('Hello, world!'); + assert(driver.findElement({id: 'sample-extension-footer'}).getText()) + .equalTo('Goodbye'); + }); + + function loadJetpackPage(driver, url) { + // On linux the jetpack extension does not always run the first time + // we load a page. If this happens, just reload the page (a simple + // refresh doesn't appear to work). + driver.wait(function() { + driver.get(url); + return driver.isElementPresent({id: 'jetpack-sample-banner'}); + }, 3000); + } + }); + + describe('profile management', function() { + var driver; + + test.beforeEach(function() { + driver = null; + }); + + test.afterEach(function() { + if (driver) { + driver.quit(); + } + }); + + test.ignore(env.isRemote). + it('deletes the temp profile on quit', function() { + driver = env.builder().build(); + + var profilePath = driver.call(function() { + var path = driver.profilePath_; + assert(io.exists(path)).isTrue(); + return path; + }); + + return driver.quit().then(function() { + driver = null; + return profilePath; + }).then(function(path) { + assert(io.exists(path)).isFalse(); + }); + }); + }); + + describe('binary management', function() { + var driver1, driver2; + + test.ignore(env.isRemote). + it('can start multiple sessions with single binary instance', function() { + var options = new firefox.Options().setBinary(new firefox.Binary); + env.builder().setFirefoxOptions(options); + driver1 = env.builder().build(); + driver2 = env.builder().build(); + // Ok if this doesn't fail. + }); + + test.afterEach(function() { + if (driver1) { + driver1.quit(); + } + + if (driver2) { + driver2.quit(); + } + }); + }); + + }); +}, {browsers: ['firefox']}); diff --git a/www/node_modules/selenium-webdriver/test/firefox/profile_test.js b/www/node_modules/selenium-webdriver/test/firefox/profile_test.js new file mode 100644 index 0000000..feaa42f --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/firefox/profile_test.js @@ -0,0 +1,187 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var AdmZip = require('adm-zip'), + assert = require('assert'), + fs = require('fs'), + path = require('path'); + +var promise = require('../..').promise, + Profile = require('../../firefox/profile').Profile, + decode = require('../../firefox/profile').decode, + loadUserPrefs = require('../../firefox/profile').loadUserPrefs, + io = require('../../io'), + it = require('../../testing').it; + + +var JETPACK_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/jetpack-sample.xpi'); +var NORMAL_EXTENSION = path.join(__dirname, + '../../lib/test/data/firefox/sample.xpi'); + +var JETPACK_EXTENSION_ID = 'jid1-EaXX7k0wwiZR7w@jetpack.xpi'; +var NORMAL_EXTENSION_ID = 'sample@seleniumhq.org'; +var WEBDRIVER_EXTENSION_ID = 'fxdriver@googlecode.com'; + + + +describe('Profile', function() { + describe('setPreference', function() { + it('allows setting custom properties', function() { + var profile = new Profile(); + assert.equal(undefined, profile.getPreference('foo')); + + profile.setPreference('foo', 'bar'); + assert.equal('bar', profile.getPreference('foo')); + }); + + it('allows overriding mutable properties', function() { + var profile = new Profile(); + assert.equal('about:blank', profile.getPreference('browser.newtab.url')); + + profile.setPreference('browser.newtab.url', 'http://www.example.com'); + assert.equal('http://www.example.com', + profile.getPreference('browser.newtab.url')); + }); + + it('throws if setting a frozen preference', function() { + var profile = new Profile(); + assert.throws(function() { + profile.setPreference('app.update.auto', true); + }); + }); + }); + + describe('writeToDisk', function() { + it('copies template directory recursively', function() { + var templateDir; + return io.tmpDir().then(function(td) { + templateDir = td; + var foo = path.join(templateDir, 'foo'); + fs.writeFileSync(foo, 'Hello, world'); + + var bar = path.join(templateDir, 'subfolder/bar'); + fs.mkdirSync(path.dirname(bar)); + fs.writeFileSync(bar, 'Goodbye, world!'); + + return new Profile(templateDir).writeToDisk(); + }).then(function(profileDir) { + assert.notEqual(profileDir, templateDir); + + assert.equal('Hello, world', + fs.readFileSync(path.join(profileDir, 'foo'))); + assert.equal('Goodbye, world!', + fs.readFileSync(path.join(profileDir, 'subfolder/bar'))); + }); + }); + + it('does not copy lock files', function() { + return io.tmpDir().then(function(dir) { + fs.writeFileSync(path.join(dir, 'parent.lock'), 'lock'); + fs.writeFileSync(path.join(dir, 'lock'), 'lock'); + fs.writeFileSync(path.join(dir, '.parentlock'), 'lock'); + return new Profile(dir).writeToDisk(); + }).then(function(dir) { + assert.ok(fs.existsSync(dir)); + assert.ok(!fs.existsSync(path.join(dir, 'parent.lock'))); + assert.ok(!fs.existsSync(path.join(dir, 'lock'))); + assert.ok(!fs.existsSync(path.join(dir, '.parentlock'))); + }); + }); + + describe('user.js', function() { + + it('writes defaults', function() { + return new Profile().writeToDisk().then(function(dir) { + return loadUserPrefs(path.join(dir, 'user.js')); + }).then(function(prefs) { + // Just check a few. + assert.equal(false, prefs['app.update.auto']); + assert.equal(true, prefs['browser.EULA.override']); + assert.equal(false, prefs['extensions.update.enabled']); + assert.equal('about:blank', prefs['browser.newtab.url']); + assert.equal(30, prefs['dom.max_script_run_time']); + }); + }); + + it('merges template user.js into preferences', function() { + return io.tmpDir().then(function(dir) { + fs.writeFileSync(path.join(dir, 'user.js'), [ + 'user_pref("browser.newtab.url", "http://www.example.com")', + 'user_pref("dom.max_script_run_time", 1234)' + ].join('\n')); + + return new Profile(dir).writeToDisk(); + }).then(function(profile) { + return loadUserPrefs(path.join(profile, 'user.js')); + }).then(function(prefs) { + assert.equal('http://www.example.com', prefs['browser.newtab.url']); + assert.equal(1234, prefs['dom.max_script_run_time']); + }); + }); + + it('ignores frozen preferences when merging template user.js', + function() { + return io.tmpDir().then(function(dir) { + fs.writeFileSync(path.join(dir, 'user.js'), + 'user_pref("app.update.auto", true)'); + return new Profile(dir).writeToDisk(); + }).then(function(profile) { + return loadUserPrefs(path.join(profile, 'user.js')); + }).then(function(prefs) { + assert.equal(false, prefs['app.update.auto']); + }); + }); + }); + + describe('extensions', function() { + it('are copied into new profile directory', function() { + var profile = new Profile(); + profile.addExtension(JETPACK_EXTENSION); + profile.addExtension(NORMAL_EXTENSION); + + return profile.writeToDisk().then(function(dir) { + dir = path.join(dir, 'extensions'); + assert.ok(fs.existsSync(path.join(dir, JETPACK_EXTENSION_ID))); + assert.ok(fs.existsSync(path.join(dir, NORMAL_EXTENSION_ID))); + assert.ok(fs.existsSync(path.join(dir, WEBDRIVER_EXTENSION_ID))); + }); + }); + }); + }); + + describe('encode', function() { + it('excludes the bundled WebDriver extension', function() { + return new Profile().encode().then(function(data) { + return decode(data); + }).then(function(dir) { + assert.ok(fs.existsSync(path.join(dir, 'user.js'))); + assert.ok(fs.existsSync(path.join(dir, 'extensions'))); + return loadUserPrefs(path.join(dir, 'user.js')); + }).then(function(prefs) { + // Just check a few. + assert.equal(false, prefs['app.update.auto']); + assert.equal(true, prefs['browser.EULA.override']); + assert.equal(false, prefs['extensions.update.enabled']); + assert.equal('about:blank', prefs['browser.newtab.url']); + assert.equal(30, prefs['dom.max_script_run_time']); + }); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/http/http_test.js b/www/node_modules/selenium-webdriver/test/http/http_test.js new file mode 100644 index 0000000..b121f85 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/http/http_test.js @@ -0,0 +1,443 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'); +var http = require('http'); +var sinon = require('sinon'); +var url = require('url'); + +var error = require('../../error'); +var Executor = require('../../http').Executor; +var HttpClient = require('../../http').HttpClient; +var HttpRequest = require('../../http').Request; +var HttpResponse = require('../../http').Response; +var buildPath = require('../../http').buildPath; +var Command = require('../../lib/command').Command; +var CommandName = require('../../lib/command').Name; +var Server = require('../../lib/test/httpserver').Server; +var promise = require('../..').promise; + +describe('buildPath', function() { + it('properly replaces path segments with command parameters', function() { + var parameters = {'sessionId':'foo', 'url':'http://www.google.com'}; + var finalPath = buildPath('/session/:sessionId/url', parameters); + assert.equal(finalPath, '/session/foo/url'); + assert.deepEqual(parameters, {'url':'http://www.google.com'}); + }); + + it('handles web element references', function() { + var parameters = {'sessionId':'foo', 'id': {}}; + parameters['id']['ELEMENT'] = 'bar'; + + var finalPath = buildPath( + '/session/:sessionId/element/:id/click', parameters); + assert.equal(finalPath, '/session/foo/element/bar/click'); + assert.deepEqual(parameters, {}); + }); + + it('throws if missing a parameter', function() { + assert.throws( + () => buildPath('/session/:sessionId', {}), + function(err) { + return err instanceof error.InvalidArgumentError + && 'Missing required parameter: sessionId' === err.message; + }); + + assert.throws( + () => buildPath('/session/:sessionId/element/:id', {'sessionId': 'foo'}), + function(err) { + return err instanceof error.InvalidArgumentError + && 'Missing required parameter: id' === err.message; + }); + }); + + it('does not match on segments that do not start with a colon', function() { + assert.equal(buildPath('/session/foo:bar/baz', {}), '/session/foo:bar/baz'); + }); +}); + +describe('Executor', function() { + let executor; + let send; + + beforeEach(function setUp() { + let client = new HttpClient('http://www.example.com'); + send = sinon.stub(client, 'send'); + executor = new Executor(client); + }); + + it('rejects unrecognized commands', function() { + assert.throws( + () => executor.execute(new Command('fake-name')), + function (err) { + return err instanceof error.UnknownCommandError + && 'Unrecognized command: fake-name' === err.message; + }); + }); + + it('rejects promise if client fails to send request', function() { + let error = new Error('boom'); + send.returns(Promise.reject(error)); + return assertFailsToSend(new Command(CommandName.NEW_SESSION)) + .then(function(e) { + assert.strictEqual(error, e); + assertSent( + 'POST', '/session', {}, + [['Accept', 'application/json; charset=utf-8']]); + }); + }); + + it('can execute commands with no URL parameters', function() { + send.returns(Promise.resolve(new HttpResponse(200, {}, ''))); + + let command = new Command(CommandName.NEW_SESSION); + return assertSendsSuccessfully(command).then(function(response) { + assertSent( + 'POST', '/session', {}, + [['Accept', 'application/json; charset=utf-8']]); + }); + }); + + it('rejects commands missing URL parameters', function() { + let command = + new Command(CommandName.FIND_CHILD_ELEMENT). + setParameter('sessionId', 's123'). + // Let this be missing: setParameter('id', {'ELEMENT': 'e456'}). + setParameter('using', 'id'). + setParameter('value', 'foo'); + + assert.throws( + () => executor.execute(command), + function(err) { + return err instanceof error.InvalidArgumentError + && 'Missing required parameter: id' === err.message; + }); + assert.ok(!send.called); + }); + + it('replaces URL parameters with command parameters', function() { + var command = new Command(CommandName.GET). + setParameter('sessionId', 's123'). + setParameter('url', 'http://www.google.com'); + + send.returns(Promise.resolve(new HttpResponse(200, {}, ''))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent( + 'POST', '/session/s123/url', {'url': 'http://www.google.com'}, + [['Accept', 'application/json; charset=utf-8']]); + }); + }); + + it('returns parsed JSON response', function() { + var responseObj = { + 'status': error.ErrorCode.SUCCESS, + 'value': 'http://www.google.com' + }; + + var command = new Command(CommandName.GET_CURRENT_URL). + setParameter('sessionId', 's123'); + + + send.returns(Promise.resolve( + new HttpResponse(200, {}, JSON.stringify(responseObj)))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('GET', '/session/s123/url', {}, + [['Accept', 'application/json; charset=utf-8']]); + assert.deepEqual(response, responseObj); + }); + }); + + it('returns success for 2xx with body as value when not json', function() { + var command = new Command(CommandName.GET_CURRENT_URL). + setParameter('sessionId', 's123'); + + send.returns(Promise.resolve( + new HttpResponse(200, {}, 'hello, world\r\ngoodbye, world!'))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('GET', '/session/s123/url', {}, + [['Accept', 'application/json; charset=utf-8']]); + assert.deepEqual(response, { + 'status': error.ErrorCode.SUCCESS, + 'value': 'hello, world\ngoodbye, world!' + }); + }); + }); + + it('returns success for 2xx with invalid JSON body', function() { + var command = new Command(CommandName.GET_CURRENT_URL). + setParameter('sessionId', 's123'); + + send.returns(Promise.resolve( + new HttpResponse(200, {}, '['))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('GET', '/session/s123/url', {}, + [['Accept', 'application/json; charset=utf-8']]); + assert.deepEqual(response, { + 'status': error.ErrorCode.SUCCESS, + 'value': '[' + }); + }); + }); + + it('returns unknown command for 404 with body as value when not json', + function() { + var command = new Command(CommandName.GET_CURRENT_URL). + setParameter('sessionId', 's123'); + + send.returns(Promise.resolve( + new HttpResponse(404, {}, 'hello, world\r\ngoodbye, world!'))); + + return assertSendsSuccessfully(command, function(response) { + assertSent('GET', '/session/s123/url', {}, + [['Accept', 'application/json; charset=utf-8']]); + assert.deepEqual(response, { + 'status': error.ErrorCode.UNKNOWN_COMMAND, + 'value': 'hello, world\ngoodbye, world!' + }); + }); + }); + + it('returnsUnknownErrorForGenericErrorCodeWithBodyAsValueWhenNotJSON', + function() { + var command = new Command(CommandName.GET_CURRENT_URL). + setParameter('sessionId', 's123'); + + send.returns(Promise.resolve( + new HttpResponse(500, {}, 'hello, world\r\ngoodbye, world!'))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('GET', '/session/s123/url', {}, + [['Accept', 'application/json; charset=utf-8']]); + assert.deepEqual(response, { + 'status': error.ErrorCode.UNKNOWN_ERROR, + 'value': 'hello, world\ngoodbye, world!' + }); + }); + }); + + it('canDefineNewCommands', function() { + executor.defineCommand('greet', 'GET', '/person/:name'); + + var command = new Command('greet'). + setParameter('name', 'Bob'); + + send.returns(Promise.resolve(new HttpResponse(200, {}, ''))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('GET', '/person/Bob', {}, + [['Accept', 'application/json; charset=utf-8']]); + }); + }); + + it('canRedefineStandardCommands', function() { + executor.defineCommand(CommandName.GO_BACK, 'POST', '/custom/back'); + + var command = new Command(CommandName.GO_BACK). + setParameter('times', 3); + + send.returns(Promise.resolve(new HttpResponse(200, {}, ''))); + + return assertSendsSuccessfully(command).then(function(response) { + assertSent('POST', '/custom/back', {'times': 3}, + [['Accept', 'application/json; charset=utf-8']]); + }); + }); + + function entries(map) { + let entries = []; + for (let e of map.entries()) { + entries.push(e); + } + return entries; + } + + function assertSent(method, path, data, headers) { + assert.ok(send.calledWith(sinon.match(function(value) { + assert.equal(value.method, method); + assert.equal(value.path, path); + assert.deepEqual(value.data, data); + assert.deepEqual(entries(value.headers), headers); + return true; + }))); + } + + function assertSendsSuccessfully(command) { + return executor.execute(command).then(function(response) { + return response; + }); + } + + function assertFailsToSend(command, opt_onError) { + return executor.execute(command).then( + () => {throw Error('should have failed')}, + (e) => {return e}); + } +}); + +describe('HttpClient', function() { + this.timeout(4 * 1000); + + var server = new Server(function(req, res) { + if (req.method == 'GET' && req.url == '/echo') { + res.writeHead(200, req.headers); + res.end(); + + } else if (req.method == 'GET' && req.url == '/redirect') { + res.writeHead(303, {'Location': server.url('/hello')}); + res.end(); + + } else if (req.method == 'GET' && req.url == '/hello') { + res.writeHead(200, {'content-type': 'text/plain'}); + res.end('hello, world!'); + + } else if (req.method == 'GET' && req.url == '/badredirect') { + res.writeHead(303, {}); + res.end(); + + } else if (req.method == 'GET' && req.url == '/protected') { + var denyAccess = function() { + res.writeHead(401, {'WWW-Authenticate': 'Basic realm="test"'}); + res.end('Access denied'); + }; + + var basicAuthRegExp = /^\s*basic\s+([a-z0-9\-\._~\+\/]+)=*\s*$/i + var auth = req.headers.authorization; + var match = basicAuthRegExp.exec(auth || ''); + if (!match) { + denyAccess(); + return; + } + + var userNameAndPass = new Buffer(match[1], 'base64').toString(); + var parts = userNameAndPass.split(':', 2); + if (parts[0] !== 'genie' && parts[1] !== 'bottle') { + denyAccess(); + return; + } + + res.writeHead(200, {'content-type': 'text/plain'}); + res.end('Access granted!'); + + } else if (req.method == 'GET' && req.url == '/proxy') { + res.writeHead(200, req.headers); + res.end(); + + } else if (req.method == 'GET' && req.url == '/proxy/redirect') { + res.writeHead(303, {'Location': '/proxy'}); + res.end(); + + } else { + res.writeHead(404, {}); + res.end(); + } + }); + + before(function() { + return server.start(); + }); + + after(function() { + return server.stop(); + }); + + it('can send a basic HTTP request', function() { + var request = new HttpRequest('GET', '/echo'); + request.headers.set('Foo', 'Bar'); + + var agent = new http.Agent(); + agent.maxSockets = 1; // Only making 1 request. + + var client = new HttpClient(server.url(), agent); + return client.send(request).then(function(response) { + assert.equal(200, response.status); + assert.equal(response.headers.get('content-length'), '0'); + assert.equal(response.headers.get('connection'), 'keep-alive'); + assert.equal(response.headers.get('host'), server.host()); + + assert.equal(request.headers.get('Foo'), 'Bar'); + assert.equal( + request.headers.get('Accept'), 'application/json; charset=utf-8'); + }); + }); + + it('can use basic auth', function() { + var parsed = url.parse(server.url()); + parsed.auth = 'genie:bottle'; + + var client = new HttpClient(url.format(parsed)); + var request = new HttpRequest('GET', '/protected'); + return client.send(request).then(function(response) { + assert.equal(200, response.status); + assert.equal(response.headers.get('content-type'), 'text/plain'); + assert.equal(response.body, 'Access granted!'); + }); + }); + + it('fails requests missing required basic auth', function() { + var client = new HttpClient(server.url()); + var request = new HttpRequest('GET', '/protected'); + return client.send(request).then(function(response) { + assert.equal(401, response.status); + assert.equal(response.body, 'Access denied'); + }); + }); + + it('automatically follows redirects', function() { + var request = new HttpRequest('GET', '/redirect'); + var client = new HttpClient(server.url()); + return client.send(request).then(function(response) { + assert.equal(200, response.status); + assert.equal(response.headers.get('content-type'), 'text/plain'); + assert.equal(response.body, 'hello, world!'); + }); + }); + + it('handles malformed redirect responses', function() { + var request = new HttpRequest('GET', '/badredirect'); + var client = new HttpClient(server.url()); + return client.send(request).then(assert.fail, function(err) { + assert.ok(/Failed to parse "Location"/.test(err.message), + 'Not the expected error: ' + err.message); + }); + }); + + it('proxies requests through the webdriver proxy', function() { + var request = new HttpRequest('GET', '/proxy'); + var client = new HttpClient( + 'http://another.server.com', undefined, server.url()); + return client.send(request).then(function(response) { + assert.equal(200, response.status); + assert.equal(response.headers.get('host'), 'another.server.com'); + }); + }); + + it('proxies requests through the webdriver proxy on redirect', function() { + var request = new HttpRequest('GET', '/proxy/redirect'); + var client = new HttpClient( + 'http://another.server.com', undefined, server.url()); + return client.send(request).then(function(response) { + assert.equal(200, response.status); + assert.equal(response.headers.get('host'), 'another.server.com'); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/http/util_test.js b/www/node_modules/selenium-webdriver/test/http/util_test.js new file mode 100644 index 0000000..ca250c6 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/http/util_test.js @@ -0,0 +1,184 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'), + http = require('http'); + +var error = require('../../error'); +var util = require('../../http/util'); + +describe('selenium-webdriver/http/util', function() { + + var server, baseUrl; + + var status, value, responseCode; + + function startServer(done) { + if (server) return done(); + + server = http.createServer(function(req, res) { + var data = JSON.stringify({status: status, value: value}); + res.writeHead(responseCode, { + 'Content-Type': 'application/json; charset=utf-8', + 'Content-Length': Buffer.byteLength(data, 'utf8') + }); + res.end(data); + }); + + server.listen(0, '127.0.0.1', function(e) { + if (e) return done(e); + + var addr = server.address(); + baseUrl = 'http://' + addr.address + ':' + addr.port; + done(); + }); + } + + function killServer(done) { + if (!server) return done(); + server.close(done); + server = null; + } + + after(killServer); + + beforeEach(function(done) { + status = 0; + value = 'abc123'; + responseCode = 200; + startServer(done); + }); + + describe('#getStatus', function() { + it('should return value field on success', function() { + return util.getStatus(baseUrl).then(function(response) { + assert.equal('abc123', response); + }); + }); + + it('should fail if response object is not success', function() { + status = 1; + return util.getStatus(baseUrl).then(function() { + throw Error('expected a failure'); + }, function(err) { + assert.ok(err instanceof error.WebDriverError); + assert.equal(err.code, error.WebDriverError.code); + assert.equal(err.message, value); + }); + }); + + it('should fail if the server is not listening', function(done) { + killServer(function(e) { + if(e) return done(e); + + util.getStatus(baseUrl).then(function() { + done(Error('expected a failure')); + }, function() { + // Expected. + done(); + }); + }); + }); + + it('should fail if HTTP status is not 200', function() { + status = 1; + responseCode = 404; + return util.getStatus(baseUrl).then(function() { + throw Error('expected a failure'); + }, function(err) { + assert.ok(err instanceof error.WebDriverError); + assert.equal(err.code, error.WebDriverError.code); + assert.equal(err.message, value); + }); + }); + }); + + describe('#waitForServer', function() { + it('resolves when server is ready', function() { + status = 1; + setTimeout(function() { status = 0; }, 50); + return util.waitForServer(baseUrl, 100); + }); + + it('should fail if server does not become ready', function() { + status = 1; + return util.waitForServer(baseUrl, 50). + then(function() {throw Error('Expected to time out')}, + function() {}); + }); + + it('can cancel wait', function(done) { + status = 1; + var err = Error('cancelled!'); + var isReady = util.waitForServer(baseUrl, 200). + then(function() { done('Did not expect to succeed'); }). + then(null, function(e) { + assert.equal('cancelled!', e.message); + }). + then(function() { done(); }, done); + + setTimeout(function() { + isReady.cancel('cancelled!'); + }, 50); + }); + }); + + describe('#waitForUrl', function() { + it('succeeds when URL returns 2xx', function(done) { + responseCode = 404; + setTimeout(function() { responseCode = 200; }, 50); + + util.waitForUrl(baseUrl, 200). + then(function() {}). // done needs no argument to pass. + thenFinally(done); + }); + + it('fails if URL always returns 4xx', function(done) { + responseCode = 404; + + util.waitForUrl(baseUrl, 50). + then(function() { done('Expected to time out'); }, + function() { done(); }); + }); + + it('fails if cannot connect to server', function(done) { + killServer(function(e) { + if (e) return done(e); + + util.waitForUrl(baseUrl, 50). + then(function() { done('Expected to time out'); }, + function() { done(); }); + }); + }); + + it('can cancel wait', function(done) { + responseCode = 404; + var isReady = util.waitForUrl(baseUrl, 200). + then(function() { done('Did not expect to succeed'); }). + then(null, function(e) { + assert.equal('cancelled!', e.message); + }). + then(function() { done(); }, done); + + setTimeout(function() { + isReady.cancel('cancelled!'); + }, 50); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/io_test.js b/www/node_modules/selenium-webdriver/test/io_test.js new file mode 100644 index 0000000..bc2b457 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/io_test.js @@ -0,0 +1,232 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'), + fs = require('fs'), + path = require('path'), + tmp = require('tmp'); + +var io = require('../io'), + before = require('../testing').before, + beforeEach = require('../testing').beforeEach, + it = require('../testing').it; + + +describe('io', function() { + describe('copy', function() { + var tmpDir; + + before(function() { + return io.tmpDir().then(function(d) { + tmpDir = d; + + fs.writeFileSync(path.join(d, 'foo'), 'Hello, world'); + }); + }); + + it('can copy one file to another', function() { + return io.tmpFile().then(function(f) { + return io.copy(path.join(tmpDir, 'foo'), f).then(function(p) { + assert.equal(p, f); + assert.equal('Hello, world', fs.readFileSync(p)); + }); + }); + }); + + it('can copy symlink to destination', function() { + if (process.platform === 'win32') { + return; // No symlinks on windows. + } + fs.symlinkSync( + path.join(tmpDir, 'foo'), + path.join(tmpDir, 'symlinked-foo')); + return io.tmpFile().then(function(f) { + return io.copy(path.join(tmpDir, 'symlinked-foo'), f).then(function(p) { + assert.equal(p, f); + assert.equal('Hello, world', fs.readFileSync(p)); + }); + }); + }); + + it('fails if given a directory as a source', function() { + return io.tmpFile().then(function(f) { + return io.copy(tmpDir, f); + }).then(function() { + throw Error('Should have failed with a type error'); + }, function() { + // Do nothing; expected. + }); + }); + }); + + describe('copyDir', function() { + it('copies recursively', function() { + return io.tmpDir().then(function(dir) { + fs.writeFileSync(path.join(dir, 'file1'), 'hello'); + fs.mkdirSync(path.join(dir, 'sub')); + fs.mkdirSync(path.join(dir, 'sub/folder')); + fs.writeFileSync(path.join(dir, 'sub/folder/file2'), 'goodbye'); + + return io.tmpDir().then(function(dst) { + return io.copyDir(dir, dst).then(function(ret) { + assert.equal(dst, ret); + + assert.equal('hello', + fs.readFileSync(path.join(dst, 'file1'))); + assert.equal('goodbye', + fs.readFileSync(path.join(dst, 'sub/folder/file2'))); + }); + }); + }); + }); + + it('creates destination dir if necessary', function() { + return io.tmpDir().then(function(srcDir) { + fs.writeFileSync(path.join(srcDir, 'foo'), 'hi'); + return io.tmpDir().then(function(dstDir) { + return io.copyDir(srcDir, path.join(dstDir, 'sub')); + }); + }).then(function(p) { + assert.equal('sub', path.basename(p)); + assert.equal('hi', fs.readFileSync(path.join(p, 'foo'))); + }); + }); + + it('supports regex exclusion filter', function() { + return io.tmpDir().then(function(src) { + fs.writeFileSync(path.join(src, 'foo'), 'a'); + fs.writeFileSync(path.join(src, 'bar'), 'b'); + fs.writeFileSync(path.join(src, 'baz'), 'c'); + fs.mkdirSync(path.join(src, 'sub')); + fs.writeFileSync(path.join(src, 'sub/quux'), 'd'); + fs.writeFileSync(path.join(src, 'sub/quot'), 'e'); + + return io.tmpDir().then(function(dst) { + return io.copyDir(src, dst, /(bar|quux)/); + }); + }).then(function(dir) { + assert.equal('a', fs.readFileSync(path.join(dir, 'foo'))); + assert.equal('c', fs.readFileSync(path.join(dir, 'baz'))); + assert.equal('e', fs.readFileSync(path.join(dir, 'sub/quot'))); + + assert.ok(!fs.existsSync(path.join(dir, 'bar'))); + assert.ok(!fs.existsSync(path.join(dir, 'sub/quux'))); + }); + }); + + it('supports exclusion filter function', function() { + return io.tmpDir().then(function(src) { + fs.writeFileSync(path.join(src, 'foo'), 'a'); + fs.writeFileSync(path.join(src, 'bar'), 'b'); + fs.writeFileSync(path.join(src, 'baz'), 'c'); + fs.mkdirSync(path.join(src, 'sub')); + fs.writeFileSync(path.join(src, 'sub/quux'), 'd'); + fs.writeFileSync(path.join(src, 'sub/quot'), 'e'); + + return io.tmpDir().then(function(dst) { + return io.copyDir(src, dst, function(f) { + return f !== path.join(src, 'foo') + && f !== path.join(src, 'sub/quot'); + }); + }); + }).then(function(dir) { + assert.equal('b', fs.readFileSync(path.join(dir, 'bar'))); + assert.equal('c', fs.readFileSync(path.join(dir, 'baz'))); + assert.equal('d', fs.readFileSync(path.join(dir, 'sub/quux'))); + + assert.ok(!fs.existsSync(path.join(dir, 'foo'))); + assert.ok(!fs.existsSync(path.join(dir, 'sub/quot'))); + }); + }); + }); + + describe('exists', function() { + var dir; + + before(function() { + return io.tmpDir().then(function(d) { + dir = d; + }); + }); + + it('works for directories', function() { + return io.exists(dir).then(assert.ok); + }); + + it('works for files', function() { + var file = path.join(dir, 'foo'); + fs.writeFileSync(file, ''); + return io.exists(file).then(assert.ok); + }); + + it('does not return a rejected promise if file does not exist', function() { + return io.exists(path.join(dir, 'not-there')).then(function(exists) { + assert.ok(!exists); + }); + }); + }); + + describe('unlink', function() { + var dir; + + before(function() { + return io.tmpDir().then(function(d) { + dir = d; + }); + }); + + it('silently succeeds if the path does not exist', function() { + return io.unlink(path.join(dir, 'not-there')); + }); + + it('deletes files', function() { + var file = path.join(dir, 'foo'); + fs.writeFileSync(file, ''); + return io.exists(file).then(assert.ok).then(function() { + return io.unlink(file); + }).then(function() { + return io.exists(file); + }).then(function(exists) { + return assert.ok(!exists); + }); + }); + }); + + describe('rmDir', function() { + it('succeeds if the designated directory does not exist', function() { + return io.tmpDir().then(function(d) { + return io.rmDir(path.join(d, 'i/do/not/exist')); + }); + }); + + it('deletes recursively', function() { + return io.tmpDir().then(function(dir) { + fs.writeFileSync(path.join(dir, 'file1'), 'hello'); + fs.mkdirSync(path.join(dir, 'sub')); + fs.mkdirSync(path.join(dir, 'sub/folder')); + fs.writeFileSync(path.join(dir, 'sub/folder/file2'), 'goodbye'); + + return io.rmDir(dir).then(function() { + assert.ok(!fs.existsSync(dir)); + assert.ok(!fs.existsSync(path.join(dir, 'sub/folder/file2'))); + }); + }); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/lib/by_test.js b/www/node_modules/selenium-webdriver/test/lib/by_test.js new file mode 100644 index 0000000..c4bd2f4 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/by_test.js @@ -0,0 +1,127 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'); +var by = require('../../lib/by'); + +describe('by', function() { + describe('By', function() { + describe('className', function() { + it('delegates to By.css', function() { + let locator = by.By.className('foo'); + assert.equal('css selector', locator.using); + assert.equal('.foo', locator.value); + }); + + it('escapes class name', function() { + let locator = by.By.className('foo#bar'); + assert.equal('css selector', locator.using); + assert.equal('.foo\\#bar', locator.value); + }); + + it('translates compound class names', function() { + let locator = by.By.className('a b'); + assert.equal('css selector', locator.using); + assert.equal('.a.b', locator.value); + + locator = by.By.className(' x y z-1 "g" '); + assert.equal('css selector', locator.using); + assert.equal('.x.y.z-1.\\"g\\"', locator.value); + }); + }); + + describe('id', function() { + it('delegates to By.css', function() { + let locator = by.By.id('foo'); + assert.equal('css selector', locator.using); + assert.equal('*[id="foo"]', locator.value); + }); + + it('escapes the ID', function() { + let locator = by.By.id('foo#bar'); + assert.equal('css selector', locator.using); + assert.equal('*[id="foo\\#bar"]', locator.value); + }); + }); + + describe('name', function() { + it('delegates to By.css', function() { + let locator = by.By.name('foo') + assert.equal('css selector', locator.using); + assert.equal('*[name="foo"]', locator.value); + }); + + it('escapes the name', function() { + let locator = by.By.name('foo"bar"') + assert.equal('css selector', locator.using); + assert.equal('*[name="foo\\"bar\\""]', locator.value); + }); + }); + }); + + describe('checkedLocator', function() { + it('accepts class name', function() { + let locator = by.checkedLocator({className: 'foo'}); + assert.equal('css selector', locator.using); + assert.equal('.foo', locator.value); + }); + + it('accepts css', function() { + let locator = by.checkedLocator({css: 'a > b'}); + assert.equal('css selector', locator.using); + assert.equal('a > b', locator.value); + }); + + it('accepts id', function() { + let locator = by.checkedLocator({id: 'foobar'}); + assert.equal('css selector', locator.using); + assert.equal('*[id="foobar"]', locator.value); + }); + + it('accepts linkText', function() { + let locator = by.checkedLocator({linkText: 'hello'}); + assert.equal('link text', locator.using); + assert.equal('hello', locator.value); + }); + + it('accepts name', function() { + let locator = by.checkedLocator({name: 'foobar'}); + assert.equal('css selector', locator.using); + assert.equal('*[name="foobar"]', locator.value); + }); + + it('accepts partialLinkText', function() { + let locator = by.checkedLocator({partialLinkText: 'hello'}); + assert.equal('partial link text', locator.using); + assert.equal('hello', locator.value); + }); + + it('accepts tagName', function() { + let locator = by.checkedLocator({tagName: 'div'}); + assert.equal('css selector', locator.using); + assert.equal('div', locator.value); + }); + + it('accepts xpath', function() { + let locator = by.checkedLocator({xpath: '//div[1]'}); + assert.equal('xpath', locator.using); + assert.equal('//div[1]', locator.value); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/lib/capabilities_test.js b/www/node_modules/selenium-webdriver/test/lib/capabilities_test.js new file mode 100644 index 0000000..78823d7 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/capabilities_test.js @@ -0,0 +1,84 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const Capabilities = require('../../lib/capabilities').Capabilities; +const Symbols = require('../../lib/symbols'); + +const assert = require('assert'); + +describe('Capabilities', function() { + it('can set and unset a capability', function() { + let caps = new Capabilities(); + assert.equal(undefined, caps.get('foo')); + assert.ok(!caps.has('foo')); + + caps.set('foo', 'bar'); + assert.equal('bar', caps.get('foo')); + assert.ok(caps.has('foo')); + + caps.set('foo', null); + assert.equal(null, caps.get('foo')); + assert.ok(caps.has('foo')); + }); + + it('requires string capability keys', function() { + let caps = new Capabilities(); + assert.throws(() => caps.set({}, 'hi')); + }); + + it('can merge capabilities', function() { + let caps1 = new Capabilities() + .set('foo', 'bar') + .set('color', 'red'); + + let caps2 = new Capabilities() + .set('color', 'green'); + + assert.equal('bar', caps1.get('foo')); + assert.equal('red', caps1.get('color')); + assert.equal('green', caps2.get('color')); + assert.equal(undefined, caps2.get('foo')); + + caps2.merge(caps1); + assert.equal('bar', caps1.get('foo')); + assert.equal('red', caps1.get('color')); + assert.equal('red', caps2.get('color')); + assert.equal('bar', caps2.get('foo')); + }); + + it('can be initialized from a hash object', function() { + let caps = new Capabilities({'one': 123, 'abc': 'def'}); + assert.equal(123, caps.get('one')); + assert.equal('def', caps.get('abc')); + }); + + it('can be initialized from a map', function() { + let m = new Map([['one', 123], ['abc', 'def']]); + + let caps = new Capabilities(m); + assert.equal(123, caps.get('one')); + assert.equal('def', caps.get('abc')); + }); + + it('can be serialized', function() { + let m = new Map([['one', 123], ['abc', 'def']]); + let caps = new Capabilities(m); + assert.deepEqual({one: 123, abc: 'def'}, caps[Symbols.serialize]()); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/lib/events_test.js b/www/node_modules/selenium-webdriver/test/lib/events_test.js new file mode 100644 index 0000000..a02da97 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/events_test.js @@ -0,0 +1,177 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const EventEmitter = require('../../lib/events').EventEmitter; + +const assert = require('assert'); +const sinon = require('sinon'); + +describe('EventEmitter', function() { + describe('#emit()', function() { + it('can emit events when nothing is registered', function() { + let emitter = new EventEmitter; + emitter.emit('foo'); + // Ok if no errors are thrown. + }); + + it('can pass args to listeners on emit', function() { + let emitter = new EventEmitter; + let now = Date.now(); + + let messages = []; + emitter.on('foo', (arg) => messages.push(arg)); + + emitter.emit('foo', now); + assert.deepEqual([now], messages); + + emitter.emit('foo', now + 15); + assert.deepEqual([now, now + 15], messages); + }); + }); + + describe('#addListener()', function() { + it('can add multiple listeners for one event', function() { + let emitter = new EventEmitter; + let count = 0; + emitter.addListener('foo', () => count++); + emitter.addListener('foo', () => count++); + emitter.addListener('foo', () => count++); + emitter.emit('foo'); + assert.equal(3, count); + }); + + it('only registers each listener function once', function() { + let emitter = new EventEmitter; + let count = 0; + let onFoo = () => count++; + emitter.addListener('foo', onFoo); + emitter.addListener('foo', onFoo); + emitter.addListener('foo', onFoo); + + emitter.emit('foo'); + assert.equal(1, count); + + emitter.emit('foo'); + assert.equal(2, count); + }); + + it('allows users to specify a custom scope', function() { + let obj = { + count: 0, + inc: function() { + this.count++; + } + }; + let emitter = new EventEmitter; + emitter.addListener('foo', obj.inc, obj); + + emitter.emit('foo'); + assert.equal(1, obj.count); + + emitter.emit('foo'); + assert.equal(2, obj.count); + }); + }); + + describe('#once()', function() { + it('only calls registered callback once', function() { + let emitter = new EventEmitter; + let count = 0; + emitter.once('foo', () => count++); + emitter.once('foo', () => count++); + emitter.once('foo', () => count++); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.emit('foo'); + assert.equal(3, count); + }); + }); + + describe('#removeListeners()', function() { + it('only removes the given listener function', function() { + let emitter = new EventEmitter; + let count = 0; + emitter.addListener('foo', () => count++); + emitter.addListener('foo', () => count++); + + let toRemove = () => count++; + emitter.addListener('foo', toRemove); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.removeListener('foo', toRemove); + emitter.emit('foo'); + assert.equal(5, count); + }); + }); + + describe('#removeAllListeners()', function() { + it('only removes listeners for type if specified', function() { + let emitter = new EventEmitter; + let count = 0; + emitter.addListener('foo', () => count++); + emitter.addListener('foo', () => count++); + emitter.addListener('foo', () => count++); + emitter.addListener('bar', () => count++); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.removeAllListeners('foo'); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.emit('bar'); + assert.equal(4, count); + }); + + it('removes absolutely all listeners if no type specified', function() { + let emitter = new EventEmitter; + let count = 0; + emitter.addListener('foo', () => count++); + emitter.addListener('bar', () => count++); + emitter.addListener('baz', () => count++); + emitter.addListener('baz', () => count++); + + emitter.emit('foo'); + assert.equal(1, count); + + emitter.emit('baz'); + assert.equal(3, count); + + emitter.removeAllListeners(); + + emitter.emit('foo'); + assert.equal(3, count); + + emitter.emit('bar'); + assert.equal(3, count); + + emitter.emit('baz'); + assert.equal(3, count); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/lib/logging_test.js b/www/node_modules/selenium-webdriver/test/lib/logging_test.js new file mode 100644 index 0000000..29d2af4 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/logging_test.js @@ -0,0 +1,272 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); +const sinon = require('sinon'); +const logging = require('../../lib/logging'); + +describe('logging', function() { + let mgr, root, clock; + + beforeEach(function setUp() { + mgr = new logging.LogManager; + root = mgr.getLogger(''); + + clock = sinon.useFakeTimers(); + }); + + afterEach(function tearDown() { + clock.restore(); + }); + + describe('LogManager', function() { + describe('getLogger()', function() { + it('handles falsey input', function() { + assert.strictEqual(root, mgr.getLogger()); + assert.strictEqual(root, mgr.getLogger('')); + assert.strictEqual(root, mgr.getLogger(null)); + assert.strictEqual(root, mgr.getLogger(0)); + }); + + it('creates parent loggers', function() { + let logger = mgr.getLogger('foo.bar.baz'); + assert.strictEqual(logger.parent_, mgr.getLogger('foo.bar')); + + logger = logger.parent_; + assert.strictEqual(logger.parent_, mgr.getLogger('foo')); + + logger = logger.parent_; + assert.strictEqual(logger.parent_, mgr.getLogger('')); + + assert.strictEqual(logger.parent_.parent_, null); + }); + }); + }); + + describe('Logger', function() { + describe('getEffectiveLevel()', function() { + it('defaults to OFF', function() { + assert.strictEqual(root.getLevel(), logging.Level.OFF); + assert.strictEqual(root.getEffectiveLevel(), logging.Level.OFF); + + root.setLevel(null); + assert.strictEqual(root.getLevel(), null); + assert.strictEqual(root.getEffectiveLevel(), logging.Level.OFF); + }); + + it('uses own level if set', function() { + let logger = mgr.getLogger('foo.bar.baz'); + assert.strictEqual(logger.getLevel(), null); + assert.strictEqual(logger.getEffectiveLevel(), logging.Level.OFF); + + logger.setLevel(logging.Level.INFO); + assert.strictEqual(logger.getLevel(), logging.Level.INFO); + assert.strictEqual(logger.getEffectiveLevel(), logging.Level.INFO); + }); + + it('uses level from set on nearest parent', function() { + let ancestor = mgr.getLogger('foo'); + ancestor.setLevel(logging.Level.SEVERE); + + let logger = mgr.getLogger('foo.bar.baz'); + assert.strictEqual(logger.getLevel(), null); + assert.strictEqual(logger.getEffectiveLevel(), logging.Level.SEVERE); + }); + }); + + describe('isLoggable()', function() { + it('compares level against logger\'s effective level', function() { + const log1 = mgr.getLogger('foo'); + log1.setLevel(logging.Level.WARNING); + + const log2 = mgr.getLogger('foo.bar.baz'); + + assert(!log2.isLoggable(logging.Level.FINEST)); + assert(!log2.isLoggable(logging.Level.INFO)); + assert(log2.isLoggable(logging.Level.WARNING)); + assert(log2.isLoggable(logging.Level.SEVERE)); + + log2.setLevel(logging.Level.INFO); + + assert(!log2.isLoggable(logging.Level.FINEST)); + assert(log2.isLoggable(logging.Level.INFO)); + assert(log2.isLoggable(logging.Level.WARNING)); + assert(log2.isLoggable(logging.Level.SEVERE)); + + log2.setLevel(logging.Level.ALL); + + assert(log2.isLoggable(logging.Level.FINEST)); + assert(log2.isLoggable(logging.Level.INFO)); + assert(log2.isLoggable(logging.Level.WARNING)); + assert(log2.isLoggable(logging.Level.SEVERE)); + }); + + it('Level.OFF is never loggable', function() { + function test(level) { + root.setLevel(level); + assert(!root.isLoggable(logging.Level.OFF), + 'OFF should not be loggable at ' + level); + } + + test(logging.Level.ALL); + test(logging.Level.INFO); + test(logging.Level.OFF); + }); + }); + + describe('log()', function() { + it('does not invoke loggable if message is not loggable', function() { + const log = mgr.getLogger('foo'); + log.setLevel(logging.Level.OFF); + + let callback = sinon.spy(); + log.addHandler(callback); + root.addHandler(callback); + + assert(!callback.called); + }); + + it('invokes handlers for each parent logger', function() { + const cb1 = sinon.spy(); + const cb2 = sinon.spy(); + const cb3 = sinon.spy(); + const cb4 = sinon.spy(); + + const log1 = mgr.getLogger('foo'); + const log2 = mgr.getLogger('foo.bar'); + const log3 = mgr.getLogger('foo.bar.baz'); + const log4 = mgr.getLogger('foo.bar.baz.quot'); + + log1.addHandler(cb1); + log1.setLevel(logging.Level.INFO); + + log2.addHandler(cb2); + log2.setLevel(logging.Level.WARNING); + + log3.addHandler(cb3); + log3.setLevel(logging.Level.FINER); + + clock.tick(123456); + + log4.finest('this is the finest message'); + log4.finer('this is a finer message'); + log4.info('this is an info message'); + log4.warning('this is a warning message'); + log4.severe('this is a severe message'); + + assert.equal(4, cb1.callCount); + assert.equal(4, cb2.callCount); + assert.equal(4, cb3.callCount); + + const entry1 = new logging.Entry( + logging.Level.FINER, + '[foo.bar.baz.quot] this is a finer message', + 123456); + const entry2 = new logging.Entry( + logging.Level.INFO, + '[foo.bar.baz.quot] this is an info message', + 123456); + const entry3 = new logging.Entry( + logging.Level.WARNING, + '[foo.bar.baz.quot] this is a warning message', + 123456); + const entry4 = new logging.Entry( + logging.Level.SEVERE, + '[foo.bar.baz.quot] this is a severe message', + 123456); + + check(cb1.getCall(0).args[0], entry1); + check(cb1.getCall(1).args[0], entry2); + check(cb1.getCall(2).args[0], entry3); + check(cb1.getCall(3).args[0], entry4); + + check(cb2.getCall(0).args[0], entry1); + check(cb2.getCall(1).args[0], entry2); + check(cb2.getCall(2).args[0], entry3); + check(cb2.getCall(3).args[0], entry4); + + check(cb3.getCall(0).args[0], entry1); + check(cb3.getCall(1).args[0], entry2); + check(cb3.getCall(2).args[0], entry3); + check(cb3.getCall(3).args[0], entry4); + + function check(entry, expected) { + assert.equal(entry.level, expected.level, 'wrong level'); + assert.equal(entry.message, expected.message, 'wrong message'); + assert.equal(entry.timestamp, expected.timestamp, 'wrong time'); + } + }); + + it('does not invoke removed handler', function() { + root.setLevel(logging.Level.INFO); + const cb = sinon.spy(); + + root.addHandler(cb); + root.info('hi'); + assert.equal(1, cb.callCount); + + assert(root.removeHandler(cb)); + root.info('bye'); + assert.equal(1, cb.callCount); + + assert(!root.removeHandler(cb)); + }); + }); + }); + + describe('getLevel()', function() { + it('converts named levels', function() { + assert.strictEqual(logging.Level.DEBUG, logging.getLevel('DEBUG')); + assert.strictEqual(logging.Level.ALL, logging.getLevel('FAKE')); + }); + + it('converts numeric levels', function() { + assert.strictEqual( + logging.Level.DEBUG, + logging.getLevel(logging.Level.DEBUG.value)); + }); + + it('normalizes numeric levels', function() { + assert.strictEqual( + logging.Level.OFF, + logging.getLevel(logging.Level.OFF.value * 2)); + + let diff = logging.Level.SEVERE.value - logging.Level.WARNING.value; + assert.strictEqual( + logging.Level.WARNING, + logging.getLevel(logging.Level.WARNING.value + (diff * .5))); + + assert.strictEqual(logging.Level.ALL, logging.getLevel(0)); + assert.strictEqual(logging.Level.ALL, logging.getLevel(-1)); + }); + }); + + describe('Preferences', function() { + it('can be converted to JSON', function() { + let prefs = new logging.Preferences; + assert.equal('{}', JSON.stringify(prefs)); + + prefs.setLevel('foo', logging.Level.DEBUG); + assert.equal('{"foo":"DEBUG"}', JSON.stringify(prefs)); + + prefs.setLevel(logging.Type.BROWSER, logging.Level.FINE); + assert.equal('{"foo":"DEBUG","browser":"FINE"}', JSON.stringify(prefs)); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/lib/promise_aplus_test.js b/www/node_modules/selenium-webdriver/test/lib/promise_aplus_test.js new file mode 100644 index 0000000..a893915 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/promise_aplus_test.js @@ -0,0 +1,74 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const promise = require('../../lib/promise'); + +describe('Promises/A+ Compliance Tests', function() { + // The promise spec does not define behavior for unhandled rejections and + // assumes they are effectively swallowed. This is not the case with our + // implementation, so we have to disable error propagation to test that the + // rest of our behavior is compliant. + // We run the tests with a separate instance of the control flow to ensure + // disablign error propagation does not impact other tests. + var flow = new promise.ControlFlow(); + flow.setPropagateUnhandledRejections(false); + + // Skip the tests in 2.2.6.1/2. We are not compliant in these scenarios. + var realDescribe = global.describe; + global.describe = function(name, fn) { + realDescribe(name, function() { + var prefix = 'Promises/A+ Compliance Tests 2.2.6: ' + + '`then` may be called multiple times on the same promise.'; + var suffix = 'even when one handler is added inside another handler'; + if (this.fullTitle().startsWith(prefix) + && this.fullTitle().endsWith(suffix)) { + var realSpecify = global.specify; + try { + global.specify = function(name) { + realSpecify(name); + }; + fn(); + } finally { + global.specify = realSpecify; + } + } else { + fn(); + } + }); + }; + + require('promises-aplus-tests').mocha({ + resolved: function(value) { + return new promise.Promise((fulfill) => fulfill(value), flow); + }, + rejected: function(error) { + return new promise.Promise((_, reject) => reject(error), flow); + }, + deferred: function() { + var d = new promise.Deferred(flow); + return { + resolve: d.fulfill, + reject: d.reject, + promise: d.promise + }; + } + }); + + global.describe = realDescribe; +}); diff --git a/www/node_modules/selenium-webdriver/test/lib/promise_error_test.js b/www/node_modules/selenium-webdriver/test/lib/promise_error_test.js new file mode 100644 index 0000000..114189c --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/promise_error_test.js @@ -0,0 +1,808 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Contains tests against promise error handling. Many tests use + * NativePromise to control test termination independent of promise + * (and notably promise.ControlFlow). + */ + +'use strict'; + +const testutil = require('./testutil'); + +const assert = require('assert'); +const promise = require('../../lib/promise'); + +const NativePromise = Promise; +const StubError = testutil.StubError; +const throwStubError = testutil.throwStubError; +const assertIsStubError = testutil.assertIsStubError; + +describe('promise error handling', function() { + var flow, uncaughtExceptions; + + beforeEach(function setUp() { + flow = promise.controlFlow(); + uncaughtExceptions = []; + flow.on('uncaughtException', onUncaughtException); + }); + + afterEach(function tearDown() { + return waitForIdle(flow).then(function() { + assert.deepEqual( + [], uncaughtExceptions, 'There were uncaught exceptions'); + flow.reset(); + }); + }); + + function onUncaughtException(e) { + uncaughtExceptions.push(e); + } + + function waitForAbort(opt_flow, opt_n) { + var n = opt_n || 1; + var theFlow = opt_flow || flow; + theFlow.removeAllListeners( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION); + return new NativePromise(function(fulfill, reject) { + theFlow.once('idle', function() { + reject(Error('expected flow to report an unhandled error')); + }); + + var errors = []; + theFlow.on('uncaughtException', onError); + function onError(e) { + errors.push(e); + if (errors.length === n) { + theFlow.removeListener('uncaughtException', onError); + fulfill(n === 1 ? errors[0] : errors); + } + } + }); + } + + function waitForIdle(opt_flow) { + var theFlow = opt_flow || flow; + return new NativePromise(function(fulfill, reject) { + if (theFlow.isIdle()) { + fulfill(); + return; + } + theFlow.once('idle', fulfill); + theFlow.once('uncaughtException', reject); + }); + } + + it('testRejectedPromiseTriggersErrorCallback', function() { + return promise.rejected(new StubError). + then(assert.fail, assertIsStubError); + }); + + describe('callback throws trigger subsequent error callback', function() { + it('fulfilled promise', function() { + return promise.fulfilled(). + then(throwStubError). + then(assert.fail, assertIsStubError); + }); + + it('rejected promise', function() { + var e = Error('not the droids you are looking for'); + return promise.rejected(e). + then(assert.fail, throwStubError). + then(assert.fail, assertIsStubError); + }); + }); + + describe('callback returns rejected promise triggers subsequent errback', function() { + it('from fulfilled callback', function() { + return promise.fulfilled().then(function() { + return promise.rejected(new StubError); + }).then(assert.fail, assertIsStubError); + }); + + it('from rejected callback', function() { + var e = Error('not the droids you are looking for'); + return promise.rejected(e). + then(assert.fail, function() { + return promise.rejected(new StubError); + }). + then(assert.fail, assertIsStubError); + }); + }); + + it('testReportsUnhandledRejectionsThroughTheControlFlow', function() { + promise.rejected(new StubError); + return waitForAbort().then(assertIsStubError); + }); + + describe('multiple unhandled rejections outside a task', function() { + it('are reported in order they occurred', function() { + var e1 = Error('error 1'); + var e2 = Error('error 2'); + + promise.rejected(e1); + promise.rejected(e2); + + return waitForAbort(flow).then(function(error) { + assert.ok( + error instanceof promise.MultipleUnhandledRejectionError); + // TODO: switch to Array.from when we drop node 0.12.x + var errors = []; + for (var e of error.errors) { + errors.push(e); + } + assert.deepEqual([e1, e2], errors); + }); + }); + }); + + describe('does not report unhandled rejection when', function() { + it('handler added before next tick', function() { + promise.rejected(new StubError).then(assert.fail, assertIsStubError); + return waitForIdle(); + }); + + it('added async but before next tick', function() { + var called = false; + return new NativePromise(function(fulfill, reject) { + var aPromise; + NativePromise.resolve().then(function() { + aPromise.then(assert.fail, function(e) { + called = true; + assertIsStubError(e); + }); + waitForIdle().then(fulfill, reject); + }); + aPromise = promise.rejected(new StubError); + }).then(function() { + assert.ok(called); + }) + }); + }); + + it('testTaskThrows', function() { + return flow.execute(throwStubError).then(assert.fail, assertIsStubError); + }); + + it('testTaskReturnsRejectedPromise', function() { + return flow.execute(function() { + return promise.rejected(new StubError) + }).then(assert.fail, assertIsStubError); + }); + + it('testTaskHasUnhandledRejection', function() { + return flow.execute(function() { + promise.rejected(new StubError) + }).then(assert.fail, assertIsStubError); + }); + + it('testTaskfails_returnedPromiseIsUnhandled', function() { + flow.execute(throwStubError); + return waitForAbort().then(assertIsStubError); + }); + + it('testTaskHasUnhandledRejection_cancelsRemainingSubTasks', function() { + var seen = []; + flow.execute(function() { + promise.rejected(new StubError); + + flow.execute(() => seen.push('a')) + .then(() => seen.push('b'), (e) => seen.push(e)); + flow.execute(() => seen.push('c')) + .then(() => seen.push('b'), (e) => seen.push(e)); + }); + + return waitForAbort() + .then(assertIsStubError) + .then(() => assert.deepEqual([], seen)); + }); + + describe('nested task failures', function() { + it('returns up to paren', function() { + return flow.execute(function() { + return flow.execute(function() { + return flow.execute(throwStubError); + }); + }).then(assert.fail, assertIsStubError); + }); + + it('task throws; uncaught error bubbles up', function() { + flow.execute(function() { + flow.execute(function() { + flow.execute(throwStubError); + }); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('task throws; uncaught error bubbles up; is caught at root', function() { + flow.execute(function() { + flow.execute(function() { + flow.execute(throwStubError); + }); + }).then(assert.fail, assertIsStubError); + return waitForIdle(); + }); + + it('unhandled rejection bubbles up', function() { + flow.execute(function() { + flow.execute(function() { + flow.execute(function() { + promise.rejected(new StubError); + }); + }); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('unhandled rejection bubbles up; caught at root', function() { + flow.execute(function() { + flow.execute(function() { + promise.rejected(new StubError); + }); + }).then(assert.fail, assertIsStubError); + return waitForIdle(); + }); + + it('mixtureof hanging and free subtasks', function() { + flow.execute(function() { + return flow.execute(function() { + flow.execute(throwStubError); + }); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('cancels remaining tasks', function() { + var seen = []; + flow.execute(function() { + flow.execute(() => promise.rejected(new StubError)); + flow.execute(() => seen.push('a')) + .then(() => seen.push('b'), (e) => seen.push(e)); + flow.execute(() => seen.push('c')) + .then(() => seen.push('b'), (e) => seen.push(e)); + }); + + return waitForAbort() + .then(assertIsStubError) + .then(() => assert.deepEqual([], seen)); + }); + }); + + it('testTaskReturnsPromiseLikeObjectThatInvokesErrback', function() { + return flow.execute(function() { + return { + 'then': function(_, errback) { + errback('abc123'); + } + }; + }).then(assert.fail, function(value) { + assert.equal('abc123', value); + }); + }); + + describe('ControlFlow#wait();', function() { + describe('condition throws;', function() { + it('failure is caught', function() { + return flow.wait(throwStubError, 50).then(assert.fail, assertIsStubError); + }); + + it('failure is not caught', function() { + flow.wait(throwStubError, 50); + return waitForAbort().then(assertIsStubError); + }); + }); + + describe('condition returns promise', function() { + it('failure is caught', function() { + return flow.wait(function() { + return promise.rejected(new StubError); + }, 50).then(assert.fail, assertIsStubError); + }); + + it('failure is not caught', function() { + flow.wait(function() { + return promise.rejected(new StubError); + }, 50); + return waitForAbort().then(assertIsStubError); + }); + }); + + describe('condition has unhandled promise rejection', function() { + it('failure is caught', function() { + return flow.wait(function() { + promise.rejected(new StubError); + }, 50).then(assert.fail, assertIsStubError); + }); + + it('failure is not caught', function() { + flow.wait(function() { + promise.rejected(new StubError); + }, 50); + return waitForAbort().then(assertIsStubError); + }); + }); + + describe('condition has subtask failure', function() { + it('failure is caught', function() { + return flow.wait(function() { + flow.execute(function() { + flow.execute(throwStubError); + }); + }, 50).then(assert.fail, assertIsStubError); + }); + + it('failure is not caught', function() { + flow.wait(function() { + flow.execute(function() { + flow.execute(throwStubError); + }); + }, 50); + return waitForAbort().then(assertIsStubError); + }); + }); + }); + + describe('errback throws a new error', function() { + it('start with normal promise', function() { + var error = Error('an error'); + return promise.rejected(error). + thenCatch(function(e) { + assert.equal(e, error); + throw new StubError; + }). + thenCatch(assertIsStubError); + }); + + it('start with task result', function() { + var error = Error('an error'); + return flow.execute(function() { + throw error; + }). + thenCatch(function(e) { + assert.equal(e, error); + throw new StubError; + }). + thenCatch(assertIsStubError); + }); + + it('start with normal promise; uncaught error', function() { + var error = Error('an error'); + promise.rejected(error). + thenCatch(function(e) { + assert.equal(e, error); + throw new StubError; + }); + return waitForAbort().then(assertIsStubError); + }); + + it('start with task result; uncaught error', function() { + var error = Error('an error'); + flow.execute(function() { + throw error; + }). + thenCatch(function(e) { + assert.equal(e, error); + throw new StubError; + }); + return waitForAbort().then(assertIsStubError); + }); + }); + + it('thrownPromiseCausesCallbackRejection', function() { + let p = promise.fulfilled(1234); + return promise.fulfilled().then(function() { + throw p; + }).then(assert.fail, function(value) { + assert.strictEqual(p, value); + }); + }); + + describe('task throws promise', function() { + it('promise was fulfilled', function() { + var toThrow = promise.fulfilled(1234); + flow.execute(function() { + throw toThrow; + }).then(assert.fail, function(value) { + assert.equal(toThrow, value); + return toThrow; + }).then(function(value) { + assert.equal(1234, value); + }); + return waitForIdle(); + }); + + it('promise was rejected', function() { + var toThrow = promise.rejected(new StubError); + toThrow.thenCatch(function() {}); // For tearDown. + flow.execute(function() { + throw toThrow; + }).then(assert.fail, function(e) { + assert.equal(toThrow, e); + return e; + }).then(assert.fail, assertIsStubError); + return waitForIdle(); + }); + }); + + it('testFailsTaskIfThereIsAnUnhandledErrorWhileWaitingOnTaskResult', function() { + var d = promise.defer(); + flow.execute(function() { + promise.rejected(new StubError); + return d.promise; + }).then(assert.fail, assertIsStubError); + + return waitForIdle().then(function() { + return d.promise; + }).then(assert.fail, function(e) { + assert.equal('CancellationError: StubError', e.toString()); + }); + }); + + it('testFailsParentTaskIfAsyncScheduledTaskFails', function() { + var d = promise.defer(); + flow.execute(function() { + flow.execute(throwStubError); + return d.promise; + }).then(assert.fail, assertIsStubError); + + return waitForIdle().then(function() { + return d.promise; + }).then(assert.fail, function(e) { + assert.equal('CancellationError: StubError', e.toString()); + }); + }); + + describe('long stack traces', function() { + afterEach(() => promise.LONG_STACK_TRACES = false); + + it('always includes task stacks in failures', function() { + promise.LONG_STACK_TRACES = false; + flow.execute(function() { + flow.execute(function() { + flow.execute(throwStubError, 'throw error'); + }, 'two'); + }, 'three'). + then(assert.fail, function(e) { + assertIsStubError(e); + if (typeof e.stack !== 'string') { + return; + } + var messages = e.stack.split(/\n/).filter(function(line, index) { + return /^From: /.test(line); + }); + assert.deepEqual([ + 'From: Task: throw error', + 'From: Task: two', + 'From: Task: three' + ], messages); + }); + return waitForIdle(); + }); + + it('does not include completed tasks', function () { + flow.execute(function() {}, 'succeeds'); + flow.execute(throwStubError, 'kaboom').then(assert.fail, function(e) { + assertIsStubError(e); + if (typeof e.stack !== 'string') { + return; + } + var messages = e.stack.split(/\n/).filter(function(line, index) { + return /^From: /.test(line); + }); + assert.deepEqual(['From: Task: kaboom'], messages); + }); + return waitForIdle(); + }); + + it('does not include promise chain when disabled', function() { + promise.LONG_STACK_TRACES = false; + flow.execute(function() { + flow.execute(function() { + return promise.fulfilled(). + then(function() {}). + then(function() {}). + then(throwStubError); + }, 'eventually assert.fails'); + }, 'start'). + then(assert.fail, function(e) { + assertIsStubError(e); + if (typeof e.stack !== 'string') { + return; + } + var messages = e.stack.split(/\n/).filter(function(line, index) { + return /^From: /.test(line); + }); + assert.deepEqual([ + 'From: Task: eventually assert.fails', + 'From: Task: start' + ], messages); + }); + return waitForIdle(); + }); + + it('includes promise chain when enabled', function() { + promise.LONG_STACK_TRACES = true; + flow.execute(function() { + flow.execute(function() { + return promise.fulfilled(). + then(function() {}). + then(function() {}). + then(throwStubError); + }, 'eventually assert.fails'); + }, 'start'). + then(assert.fail, function(e) { + assertIsStubError(e); + if (typeof e.stack !== 'string') { + return; + } + var messages = e.stack.split(/\n/).filter(function(line, index) { + return /^From: /.test(line); + }); + assert.deepEqual([ + 'From: Promise: then', + 'From: Task: eventually assert.fails', + 'From: Task: start' + ], messages); + }); + return waitForIdle(); + }); + }); + + it('testFrameCancelsRemainingTasks_onUnhandledTaskFailure', function() { + var run = false; + return flow.execute(function() { + flow.execute(throwStubError); + flow.execute(function() { run = true; }); + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.ok(!run); + }); + }); + + it('testFrameCancelsRemainingTasks_onUnhandledPromiseRejection', function() { + var run = false; + return flow.execute(function() { + promise.rejected(new StubError); + flow.execute(function() { run = true; }); + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.ok(!run); + }); + }); + + it('testRegisteredTaskCallbacksAreDroppedWhenTaskIsCancelled_return', function() { + var seen = []; + return flow.execute(function() { + flow.execute(throwStubError); + + flow.execute(function() { + seen.push(1); + }).then(function() { + seen.push(2); + }, function() { + seen.push(3); + }); + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.deepEqual([], seen); + }); + }); + + it('testRegisteredTaskCallbacksAreDroppedWhenTaskIsCancelled_withReturn', function() { + var seen = []; + return flow.execute(function() { + flow.execute(throwStubError); + + return flow.execute(function() { + seen.push(1); + }).then(function() { + seen.push(2); + }, function() { + seen.push(3); + }); + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.deepEqual([], seen); + }); + }); + + it('testTasksWithinACallbackAreDroppedIfContainingTaskIsAborted', function() { + var seen = []; + return flow.execute(function() { + flow.execute(throwStubError); + + // None of the callbacks on this promise should execute because the + // task assert.failure above is never handled, causing the containing task to + // abort. + promise.fulfilled().then(function() { + seen.push(1); + return flow.execute(function() { + seen.push(2); + }); + }).thenFinally(function() { + seen.push(3); + }); + + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.deepEqual([], seen); + }); + }); + + it('testTaskIsCancelledAfterWaitTimeout', function() { + var seen = []; + return flow.execute(function() { + flow.wait(function() { + return promise.delayed(50); + }, 5); + + return flow.execute(function() { + seen.push(1); + }).then(function() { + seen.push(2); + }, function() { + seen.push(3); + }); + }).then(assert.fail, function() { + assert.deepEqual([], seen); + }); + }); + + describe('task callbacks get cancellation error if registered after task was cancelled', function() { + it('(a)', function() { + var task; + flow.execute(function() { + flow.execute(throwStubError); + task = flow.execute(function() {}); + }).then(assert.fail, assertIsStubError); + return waitForIdle().then(function() { + return task.then(assert.fail, function(e) { + assert.ok(e instanceof promise.CancellationError); + }); + }); + }); + + it('(b)', function() { + var seen = []; + + var task; + flow.execute(function() { + flow.execute(throwStubError); + task = flow.execute(function() {}); + + task.then(() => seen.push(1)) + .then(() => seen.push(2)); + task.then(() => seen.push(3)) + .then(() => seen.push(4)); + + }).then(assert.fail, assertIsStubError); + + return waitForIdle().then(function() { + return task.then(assert.fail, function(e) { + seen.push(5); + assert.ok(e instanceof promise.CancellationError); + }); + }).then(() => assert.deepEqual([5], seen)); + }); + }); + + it('unhandledRejectionInParallelTaskQueue', function() { + var seen = []; + function schedule(name) { + return flow.execute(() => seen.push(name), name); + } + + flow.async(function() { + schedule('a.1'); + flow.execute(throwStubError, 'a.2 (throws)'); + }); + + var b3; + flow.async(function() { + schedule('b.1'); + schedule('b.2'); + b3 = schedule('b.3'); + }); + + var c3; + flow.async(function() { + schedule('c.1'); + schedule('c.2'); + c3 = schedule('c.3'); + }); + + function assertWasCancelled(p) { + return p.then(assert.fail, function(e) { + assert.ok(e instanceof promise.CancellationError); + }); + } + + return waitForAbort() + .then(function() { + assert.deepEqual(['a.1', 'b.1', 'c.1', 'b.2', 'c.2'], seen); + assert.ok(!b3.isPending()); + assert.ok(!c3.isPending()); + }) + .then(() => assertWasCancelled(b3)) + .then(() => assertWasCancelled(c3)); + }); + + it('errorsInAsyncFunctionsAreReportedAsUnhandledRejection', function() { + flow.removeAllListeners(); // For tearDown. + + var task; + return new Promise(function(fulfill) { + flow.once('uncaughtException', fulfill); + flow.async(function() { + task = flow.execute(function() {}); + throw Error('boom'); + }); + }).then(function(error) { + assert.ok(error instanceof promise.CancellationError); + assert.ok(!task.isPending()); + return task.thenCatch(function(error) { + assert.ok(error instanceof promise.CancellationError); + }); + }); + }); + + describe('does not wait for values thrown from callbacks to be resolved', function() { + it('(a)', function() { + var p1 = promise.fulfilled(); + var reason = promise.fulfilled('should not see me'); + return p1.then(function() { + throw reason; + }).then(assert.fail, function(e) { + assert.equal(reason, e); + }); + }); + + it('(b)', function() { + var p1 = promise.fulfilled(); + var reason = promise.rejected('should not see me'); + reason.thenCatch(function() {}); // For tearDown. + return p1.then(function() { + throw reason; + }).then(assert.fail, function(e) { + assert.equal(reason, e); + }); + }); + + it('(c)', function() { + var p1 = promise.fulfilled(); + var reason = promise.defer(); + setTimeout(() => reason.fulfill('should not see me'), 100); + return p1.then(function() { + throw reason.promise; + }).then(assert.fail, function(e) { + assert.equal(reason.promise, e); + }); + }); + + it('(d)', function() { + var p1 = promise.fulfilled(); + var reason = {then: function() {}}; // A thenable like object. + return p1.then(function() { + throw reason; + }).then(assert.fail, function(e) { + assert.equal(reason, e); + }); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/lib/promise_flow_test.js b/www/node_modules/selenium-webdriver/test/lib/promise_flow_test.js new file mode 100644 index 0000000..fd4469d --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/promise_flow_test.js @@ -0,0 +1,2282 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); +const fail = assert.fail; +const sinon = require('sinon'); + +const testutil = require('./testutil'); +const promise = require('../../lib/promise'); + +const NativePromise = Promise; + +// Aliases for readability. +const StubError = testutil.StubError; +const assertIsStubError = testutil.assertIsStubError; +const callbackPair = testutil.callbackPair; +const throwStubError = testutil.throwStubError; + +describe('promise control flow', function() { + let flow, flowHistory, messages, uncaughtExceptions; + + beforeEach(function setUp() { + promise.LONG_STACK_TRACES = false; + flow = new promise.ControlFlow(); + promise.setDefaultFlow(flow); + messages = []; + flowHistory = []; + + uncaughtExceptions = []; + flow.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, + onUncaughtException); + }); + + afterEach(function tearDown() { + flow.removeAllListeners( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION); + assert.deepEqual([], uncaughtExceptions, + 'There were uncaught exceptions'); + flow.reset(); + promise.LONG_STACK_TRACES = false; + }); + + function onUncaughtException(e) { + uncaughtExceptions.push(e); + } + + function waitForAbort(opt_flow) { + var theFlow = opt_flow || flow; + theFlow.removeAllListeners( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION); + return new NativePromise(function(fulfill, reject) { + theFlow.once(promise.ControlFlow.EventType.IDLE, function() { + reject(Error('expected flow to report an unhandled error')); + }); + theFlow.once( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, + fulfill); + }); + } + + function waitForIdle(opt_flow) { + var theFlow = opt_flow || flow; + return new NativePromise(function(fulfill, reject) { + theFlow.once(promise.ControlFlow.EventType.IDLE, fulfill); + theFlow.once( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, reject); + }); + } + + function timeout(ms) { + return new NativePromise(function(fulfill) { + setTimeout(fulfill, ms); + }); + } + + + function schedule(msg, opt_return) { + return scheduleAction(msg, function() { + return opt_return; + }); + } + + /** + * @param {string} value The value to push. + * @param {promise.Promise=} opt_taskPromise Promise to return from + * the task. + * @return {!promise.Promise} The result. + */ + function schedulePush(value, opt_taskPromise) { + return scheduleAction(value, function() { + messages.push(value); + return opt_taskPromise; + }); + } + + /** + * @param {string} msg Debug message. + * @param {!Function} actionFn The function. + * @return {!promise.Promise} The function result. + */ + function scheduleAction(msg, actionFn) { + return promise.controlFlow().execute(function() { + flowHistory.push(msg); + return actionFn(); + }, msg); + } + + /** + * @param {!Function} condition The condition function. + * @param {number=} opt_timeout The timeout. + * @param {string=} opt_message Optional message. + * @return {!promise.Promise} The wait result. + */ + function scheduleWait(condition, opt_timeout, opt_message) { + var msg = opt_message || ''; + // It's not possible to hook into when the wait itself is scheduled, so + // we record each iteration of the wait loop. + var count = 0; + return promise.controlFlow().wait(function() { + flowHistory.push((count++) + ': ' + msg); + return condition(); + }, opt_timeout, msg); + } + + function asyncRun(fn, opt_self) { + NativePromise.resolve().then(() => fn.call(opt_self)); + } + + function assertFlowHistory(var_args) { + var expected = Array.prototype.slice.call(arguments, 0); + assert.deepEqual(expected, flowHistory); + } + + function assertMessages(var_args) { + var expected = Array.prototype.slice.call(arguments, 0); + assert.deepEqual(expected, messages); + } + + function assertingMessages(var_args) { + var args = Array.prototype.slice.call(arguments, 0); + return () => assertMessages.apply(null, args); + } + + function assertFlowIs(flow) { + assert.equal(flow, promise.controlFlow()); + } + + describe('testScheduling', function() { + it('aSimpleFunction', function() { + schedule('go'); + return waitForIdle().then(function() { + assertFlowHistory('go'); + }); + }); + + it('aSimpleFunctionWithANonPromiseReturnValue', function() { + schedule('go', 123).then(function(value) { + assert.equal(123, value); + }); + return waitForIdle().then(function() { + assertFlowHistory('go'); + }); + }); + + it('aSimpleSequence', function() { + schedule('a'); + schedule('b'); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('invokesCallbacksWhenTaskIsDone', function() { + var d = new promise.Deferred(); + var called = false; + var done = schedule('a', d.promise).then(function(value) { + called = true; + assert.equal(123, value); + }); + return timeout(5).then(function() { + assert.ok(!called); + d.fulfill(123); + return done; + }). + then(function() { + assertFlowHistory('a'); + }); + }); + + it('blocksUntilPromiseReturnedByTaskIsResolved', function() { + var done = promise.defer(); + schedulePush('a', done.promise); + schedulePush('b'); + setTimeout(function() { + done.fulfill(); + messages.push('c'); + }, 25); + return waitForIdle().then(assertingMessages('a', 'c', 'b')); + }); + + it('waitsForReturnedPromisesToResolve', function() { + var d1 = new promise.Deferred(); + var d2 = new promise.Deferred(); + + var callback = sinon.spy(); + schedule('a', d1.promise).then(callback); + + return timeout(5).then(function() { + assert(!callback.called); + d1.fulfill(d2); + return timeout(5); + }).then(function() { + assert(!callback.called); + d2.fulfill('fluffy bunny'); + return waitForIdle(); + }).then(function() { + assert(callback.called); + assert.equal('fluffy bunny', callback.getCall(0).args[0]); + assertFlowHistory('a'); + }); + }); + + it('executesTasksInAFutureTurnAfterTheyAreScheduled', function() { + var count = 0; + function incr() { count++; } + + scheduleAction('', incr); + assert.equal(0, count); + return waitForIdle().then(function() { + assert.equal(1, count); + }); + }); + + it('executesOneTaskPerTurnOfTheEventLoop', function() { + var order = []; + function go() { + order.push(order.length / 2); + asyncRun(function() { + order.push('-'); + }); + } + + scheduleAction('', go); + scheduleAction('', go); + return waitForIdle().then(function() { + assert.deepEqual([0, '-', 1, '-'], order); + }) + }); + + it('firstScheduledTaskIsWithinACallback', function() { + promise.fulfilled().then(function() { + schedule('a'); + schedule('b'); + schedule('c'); + }).then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + return waitForIdle(); + }); + + it('newTasksAddedWhileWaitingOnTaskReturnedPromise1', function() { + scheduleAction('a', function() { + var d = promise.defer(); + setTimeout(function() { + schedule('c'); + d.fulfill(); + }, 10); + return d.promise; + }); + schedule('b'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('newTasksAddedWhileWaitingOnTaskReturnedPromise2', function() { + scheduleAction('a', function() { + var d = promise.defer(); + setTimeout(function() { + schedule('c'); + asyncRun(d.fulfill); + }, 10); + return d.promise; + }); + schedule('b'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'b'); + }); + }); + }); + + describe('testFraming', function() { + it('callbacksRunInANewFrame', function() { + schedule('a').then(function() { + schedule('c'); + }); + schedule('b'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'b'); + }); + }); + + it('lotsOfNesting', function() { + schedule('a').then(function() { + schedule('c').then(function() { + schedule('e').then(function() { + schedule('g'); + }); + schedule('f'); + }); + schedule('d'); + }); + schedule('b'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'e', 'g', 'f', 'd', 'b'); + }); + }); + + it('callbackReturnsPromiseThatDependsOnATask_1', function() { + schedule('a').then(function() { + schedule('b'); + return promise.delayed(5).then(function() { + return schedule('c'); + }); + }); + schedule('d'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd'); + }); + }); + + it('callbackReturnsPromiseThatDependsOnATask_2', function() { + schedule('a').then(function() { + schedule('b'); + return promise.delayed(5). + then(function() { return promise.delayed(5) }). + then(function() { return promise.delayed(5) }). + then(function() { return promise.delayed(5) }). + then(function() { return schedule('c'); }); + }); + schedule('d'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd'); + }); + }); + + it('eachCallbackWaitsForAllScheduledTasksToComplete', function() { + schedule('a'). + then(function() { + schedule('b'); + schedule('c'); + }). + then(function() { + schedule('d'); + }); + schedule('e'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('eachCallbackWaitsForReturnTasksToComplete', function() { + schedule('a'). + then(function() { + schedule('b'); + return schedule('c'); + }). + then(function() { + schedule('d'); + }); + schedule('e'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('callbacksOnAResolvedPromiseInsertIntoTheCurrentFlow', function() { + promise.fulfilled().then(function() { + schedule('b'); + }); + schedule('a'); + + return waitForIdle().then(function() { + assertFlowHistory('b', 'a'); + }); + }); + + it('callbacksInterruptTheFlowWhenPromiseIsResolved', function() { + schedule('a').then(function() { + schedule('c'); + }); + schedule('b'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'b'); + }); + }); + + it('allCallbacksInAFrameAreScheduledWhenPromiseIsResolved', function() { + var a = schedule('a'); + a.then(function() { schedule('b'); }); + schedule('c'); + a.then(function() { schedule('d'); }); + schedule('e'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('tasksScheduledInInActiveFrameDoNotGetPrecedence', function() { + var d = promise.fulfilled(); + schedule('a'); + schedule('b'); + d.then(function() { schedule('c'); }); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('tasksScheduledInAFrameGetPrecedence_1', function() { + var a = schedule('a'); + schedule('b').then(function() { + a.then(function() { + schedule('c'); + schedule('d'); + }); + var e = schedule('e'); + a.then(function() { + schedule('f'); + e.then(function() { + schedule('g'); + }); + schedule('h'); + }); + schedule('i'); + }); + schedule('j'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'); + }); + }); + }); + + describe('testErrorHandling', function() { + it('thrownErrorsArePassedToTaskErrback', function() { + scheduleAction('function that throws', throwStubError). + then(fail, assertIsStubError); + return waitForIdle(); + }); + + it('thrownErrorsPropagateThroughPromiseChain', function() { + scheduleAction('function that throws', throwStubError). + then(fail). + then(fail, assertIsStubError); + return waitForIdle(); + }); + + it('catchesErrorsFromFailedTasksInAFrame', function() { + schedule('a').then(function() { + schedule('b'); + scheduleAction('function that throws', throwStubError); + }). + then(fail, assertIsStubError); + return waitForIdle(); + }); + + it('abortsIfOnlyTaskReturnsAnUnhandledRejection', function() { + scheduleAction('function that returns rejected promise', function() { + return promise.rejected(new StubError); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('abortsIfThereIsAnUnhandledRejection', function() { + promise.rejected(new StubError); + schedule('this should not run'); + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory(/* none */); + }); + }); + + it('abortsSequenceIfATaskFails', function() { + schedule('a'); + schedule('b'); + scheduleAction('c', throwStubError); + schedule('d'); // Should never execute. + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('abortsFromUnhandledFramedTaskFailures_1', function() { + schedule('outer task').then(function() { + scheduleAction('inner task', throwStubError); + }); + schedule('this should not run'); + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('outer task', 'inner task'); + }); + }); + + it('abortsFromUnhandledFramedTaskFailures_2', function() { + schedule('a').then(function() { + schedule('b').then(function() { + scheduleAction('c', throwStubError); + // This should not execute. + schedule('d'); + }); + }); + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject', function() { + var callback = sinon.spy(); + + scheduleAction('', function() { + var obj = {'foo': promise.rejected(new StubError)}; + return promise.fullyResolved(obj).then(callback); + }); + + return waitForAbort(). + then(assertIsStubError). + then(() => assert(!callback.called)); + }); + + it('abortsWhenErrorBubblesUpFromFullyResolvingAnObject_withCallback', function() { + var callback1 = sinon.spy(); + var callback2 = sinon.spy(); + + scheduleAction('', function() { + var obj = {'foo': promise.rejected(new StubError)}; + return promise.fullyResolved(obj).then(callback1); + }).then(callback2); + + return waitForAbort(). + then(assertIsStubError). + then(() => assert(!callback1.called)). + then(() => assert(!callback2.called)); + }); + + it('canCatchErrorsFromNestedTasks', function() { + var errback = sinon.spy(); + schedule('a'). + then(function() { + return scheduleAction('b', throwStubError); + }). + thenCatch(errback); + return waitForIdle().then(function() { + assert(errback.called); + assertIsStubError(errback.getCall(0).args[0]); + }); + }); + + it('nestedCommandFailuresCanBeCaughtAndSuppressed', function() { + var errback = sinon.spy(); + schedule('a').then(function() { + return schedule('b').then(function() { + return schedule('c').then(function() { + throw new StubError; + }); + }); + }).thenCatch(errback); + schedule('d'); + return waitForIdle(). + then(function() { + assert(errback.called); + assertIsStubError(errback.getCall(0).args[0]); + assertFlowHistory('a', 'b', 'c', 'd'); + }); + }); + + it('aTaskWithAnUnhandledPromiseRejection', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + promise.rejected(new StubError); + }); + schedule('should never run'); + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'sub-tasks'); + }); + }); + + it('aTaskThatReutrnsARejectedPromise', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + return promise.rejected(new StubError); + }); + schedule('should never run'); + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'sub-tasks'); + }); + }); + + it('discardsSubtasksIfTaskThrows', function() { + var pair = callbackPair(null, assertIsStubError); + scheduleAction('a', function() { + schedule('b'); + schedule('c'); + throwStubError(); + }).then(pair.callback, pair.errback); + schedule('d'); + + return waitForIdle(). + then(pair.assertErrback). + then(function() { + assertFlowHistory('a', 'd'); + }); + }); + + it('discardsRemainingSubtasksIfASubtaskFails', function() { + var pair = callbackPair(null, assertIsStubError); + scheduleAction('a', function() { + schedule('b'); + scheduleAction('c', throwStubError); + schedule('d'); + }).then(pair.callback, pair.errback); + schedule('e'); + + return waitForIdle(). + then(pair.assertErrback). + then(function() { + assertFlowHistory('a', 'b', 'c', 'e'); + }); + }); + }); + + describe('testTryModelingFinally', function() { + it('happyPath', function() { + /* Model: + try { + doFoo(); + doBar(); + } finally { + doBaz(); + } + */ + schedulePush('foo'). + then(() => schedulePush('bar')). + thenFinally(() => schedulePush('baz')); + return waitForIdle().then(assertingMessages('foo', 'bar', 'baz')); + }); + + it('firstTryFails', function() { + /* Model: + try { + doFoo(); + doBar(); + } finally { + doBaz(); + } + */ + + scheduleAction('doFoo and throw', function() { + messages.push('foo'); + throw new StubError; + }). + then(function() { schedulePush('bar'); }). + thenFinally(function() { schedulePush('baz'); }); + + return waitForAbort(). + then(assertIsStubError). + then(assertingMessages('foo', 'baz')); + }); + + it('secondTryFails', function() { + /* Model: + try { + doFoo(); + doBar(); + } finally { + doBaz(); + } + */ + + schedulePush('foo'). + then(function() { + return scheduleAction('doBar and throw', function() { + messages.push('bar'); + throw new StubError; + }); + }). + thenFinally(function() { + return schedulePush('baz'); + }); + return waitForAbort(). + then(assertIsStubError). + then(assertingMessages('foo', 'bar', 'baz')); + }); + }); + + describe('testTaskCallbacksInterruptFlow', function() { + it('(base case)', function() { + schedule('a').then(function() { + schedule('b'); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskDependsOnImmediatelyFulfilledPromise', function() { + scheduleAction('a', function() { + return promise.fulfilled(); + }).then(function() { + schedule('b'); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskDependsOnPreviouslyFulfilledPromise', function() { + var aPromise = promise.fulfilled(123); + scheduleAction('a', function() { + return aPromise; + }).then(function(value) { + assert.equal(123, value); + schedule('b'); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskDependsOnAsyncPromise', function() { + scheduleAction('a', function() { + return promise.delayed(25); + }).then(function() { + schedule('b'); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('promiseChainedToTaskInterruptFlow', function() { + schedule('a').then(function() { + return promise.fulfilled(); + }).then(function() { + return promise.fulfilled(); + }).then(function() { + schedule('b'); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('nestedTaskCallbacksInterruptFlowWhenResolved', function() { + schedule('a').then(function() { + schedule('b').then(function() { + schedule('c'); + }); + }); + schedule('d'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd'); + }); + }); + }); + + describe('testDelayedNesting', function() { + + it('1', function() { + var a = schedule('a'); + schedule('b').then(function() { + a.then(function() { schedule('c'); }); + schedule('d'); + }); + schedule('e'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('2', function() { + var a = schedule('a'); + schedule('b').then(function() { + a.then(function() { schedule('c'); }); + schedule('d'); + a.then(function() { schedule('e'); }); + }); + schedule('f'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f'); + }); + }); + + it('3', function() { + var a = schedule('a'); + schedule('b').then(function() { + a.then(function() { schedule('c'); }); + a.then(function() { schedule('d'); }); + }); + schedule('e'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('4', function() { + var a = schedule('a'); + schedule('b').then(function() { + a.then(function() { schedule('c'); }).then(function() { + schedule('d'); + }); + a.then(function() { schedule('e'); }); + }); + schedule('f'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f'); + }); + }); + + it('5', function() { + var a = schedule('a'); + schedule('b').then(function() { + var c; + a.then(function() { c = schedule('c'); }).then(function() { + schedule('d'); + a.then(function() { schedule('e'); }); + c.then(function() { schedule('f'); }); + schedule('g'); + }); + a.then(function() { schedule('h'); }); + }); + schedule('i'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'); + }); + }); + }); + + describe('testWaiting', function() { + it('onAConditionThatIsAlwaysTrue', function() { + scheduleWait(function() { return true;}, 0, 'waiting on true'); + return waitForIdle().then(function() { + assertFlowHistory('0: waiting on true'); + }); + }); + + it('aSimpleCountingCondition', function() { + var count = 0; + scheduleWait(function() { + return ++count == 3; + }, 100, 'counting to 3'); + + return waitForIdle().then(function() { + assert.equal(3, count); + }); + }); + + it('aConditionThatReturnsAPromise', function() { + var d = new promise.Deferred(); + var count = 0; + + scheduleWait(function() { + count += 1; + return d.promise; + }, 0, 'waiting for promise'); + + return timeout(50).then(function() { + assert.equal(1, count); + d.fulfill(123); + return waitForIdle(); + }); + }); + + it('aConditionThatReturnsAPromise_2', function() { + var count = 0; + scheduleWait(function() { + return promise.fulfilled(++count == 3); + }, 100, 'waiting for promise'); + + return waitForIdle().then(function() { + assert.equal(3, count); + }); + }); + + it('aConditionThatReturnsATaskResult', function() { + var count = 0; + scheduleWait(function() { + return scheduleAction('increment count', function() { + return ++count == 3; + }); + }, 100, 'counting to 3'); + schedule('post wait'); + + return waitForIdle().then(function() { + assert.equal(3, count); + assertFlowHistory( + '0: counting to 3', 'increment count', + '1: counting to 3', 'increment count', + '2: counting to 3', 'increment count', + 'post wait'); + }); + }); + + it('conditionContainsASubtask', function() { + var count = 0; + scheduleWait(function() { + schedule('sub task'); + return ++count == 3; + }, 100, 'counting to 3'); + schedule('post wait'); + + return waitForIdle().then(function() { + assert.equal(3, count); + assertFlowHistory( + '0: counting to 3', 'sub task', + '1: counting to 3', 'sub task', + '2: counting to 3', 'sub task', + 'post wait'); + }); + }); + + it('cancelsWaitIfScheduledTaskFails', function() { + var pair = callbackPair(null, assertIsStubError); + scheduleWait(function() { + scheduleAction('boom', throwStubError); + schedule('this should not run'); + return true; + }, 100, 'waiting to go boom').then(pair.callback, pair.errback); + schedule('post wait'); + + return waitForIdle(). + then(pair.assertErrback). + then(function() { + assertFlowHistory( + '0: waiting to go boom', 'boom', + 'post wait'); + }); + }); + + it('failsIfConditionThrows', function() { + var callbacks = callbackPair(null, assertIsStubError); + scheduleWait(throwStubError, 0, 'goes boom'). + then(callbacks.callback, callbacks.errback); + schedule('post wait'); + + return waitForIdle(). + then(callbacks.assertErrback). + then(function() { + assertFlowHistory('0: goes boom', 'post wait'); + }); + }); + + it('failsIfConditionReturnsARejectedPromise', function() { + var callbacks = callbackPair(null, assertIsStubError); + scheduleWait(function() { + return promise.rejected(new StubError); + }, 0, 'goes boom').then(callbacks.callback, callbacks.errback); + schedule('post wait'); + + return waitForIdle(). + then(callbacks.assertErrback). + then(function() { + assertFlowHistory('0: goes boom', 'post wait'); + }); + }); + + it('failsIfConditionHasUnhandledRejection', function() { + var callbacks = callbackPair(null, assertIsStubError); + scheduleWait(function() { + promise.controlFlow().execute(throwStubError); + }, 0, 'goes boom').then(callbacks.callback, callbacks.errback); + schedule('post wait'); + + return waitForIdle(). + then(callbacks.assertErrback). + then(function() { + assertFlowHistory('0: goes boom', 'post wait'); + }); + }); + + it('failsIfConditionHasAFailedSubtask', function() { + var callbacks = callbackPair(null, assertIsStubError); + var count = 0; + scheduleWait(function() { + scheduleAction('maybe throw', function() { + if (++count == 2) { + throw new StubError; + } + }); + }, 100, 'waiting').then(callbacks.callback, callbacks.errback); + schedule('post wait'); + + return waitForIdle().then(function() { + assert.equal(2, count); + assertFlowHistory( + '0: waiting', 'maybe throw', + '1: waiting', 'maybe throw', + 'post wait'); + }); + }); + + it('pollingLoopWaitsForAllScheduledTasksInCondition', function() { + var count = 0; + scheduleWait(function() { + scheduleAction('increment count', function() { ++count; }); + return count >= 3; + }, 100, 'counting to 3'); + schedule('post wait'); + + return waitForIdle().then(function() { + assert.equal(4, count); + assertFlowHistory( + '0: counting to 3', 'increment count', + '1: counting to 3', 'increment count', + '2: counting to 3', 'increment count', + '3: counting to 3', 'increment count', + 'post wait'); + }); + }); + + it('waitsForeverOnAZeroTimeout', function() { + var done = false; + setTimeout(function() { + done = true; + }, 150); + var waitResult = scheduleWait(function() { + return done; + }, 0); + + return timeout(75).then(function() { + assert.ok(!done); + return timeout(100); + }).then(function() { + assert.ok(done); + return waitResult; + }); + }); + + it('waitsForeverIfTimeoutOmitted', function() { + var done = false; + setTimeout(function() { + done = true; + }, 150); + var waitResult = scheduleWait(function() { + return done; + }); + + return timeout(75).then(function() { + assert.ok(!done); + return timeout(100); + }).then(function() { + assert.ok(done); + return waitResult; + }); + }); + + it('timesOut_nonZeroTimeout', function() { + var count = 0; + scheduleWait(function() { + count += 1; + var ms = count === 2 ? 65 : 5; + return promise.delayed(ms).then(function() { + return false; + }); + }, 60, 'counting to 3'); + return waitForAbort().then(function(e) { + switch (count) { + case 1: + assertFlowHistory('0: counting to 3'); + break; + case 2: + assertFlowHistory('0: counting to 3', '1: counting to 3'); + break; + default: + fail('unexpected polling count: ' + count); + } + assert.ok( + /^counting to 3\nWait timed out after \d+ms$/.test(e.message)); + }); + }); + + it('shouldFailIfConditionReturnsARejectedPromise', function() { + scheduleWait(function() { + return promise.rejected(new StubError); + }, 100, 'returns rejected promise on first pass'); + return waitForAbort().then(assertIsStubError); + }); + + it('scheduleWithIntermittentWaits', function() { + schedule('a'); + scheduleWait(function() { return true; }, 0, 'wait 1'); + schedule('b'); + scheduleWait(function() { return true; }, 0, 'wait 2'); + schedule('c'); + scheduleWait(function() { return true; }, 0, 'wait 3'); + + return waitForIdle().then(function() { + assertFlowHistory('a', '0: wait 1', 'b', '0: wait 2', 'c', '0: wait 3'); + }); + }); + + it('scheduleWithIntermittentAndNestedWaits', function() { + schedule('a'); + scheduleWait(function() { return true; }, 0, 'wait 1'). + then(function() { + schedule('d'); + scheduleWait(function() { return true; }, 0, 'wait 2'); + schedule('e'); + }); + schedule('b'); + scheduleWait(function() { return true; }, 0, 'wait 3'); + schedule('c'); + scheduleWait(function() { return true; }, 0, 'wait 4'); + + return waitForIdle().then(function() { + assertFlowHistory( + 'a', '0: wait 1', 'd', '0: wait 2', 'e', 'b', '0: wait 3', 'c', + '0: wait 4'); + }); + }); + + it('requiresConditionToBeAPromiseOrFunction', function() { + assert.throws(function() { + flow.wait(1234, 0); + }); + flow.wait(function() { return true;}, 0); + flow.wait(promise.fulfilled(), 0); + return waitForIdle(); + }); + + it('promiseThatDoesNotResolveBeforeTimeout', function() { + var d = promise.defer(); + flow.wait(d.promise, 5).then(fail, function(e) { + assert.ok( + /Timed out waiting for promise to resolve after \d+ms/ + .test(e.message), + 'unexpected error message: ' + e.message); + }); + return waitForIdle().then(function() { + assert.ok('Promise should not be cancelled', d.promise.isPending()); + }); + }); + + it('unboundedWaitOnPromiseResolution', function() { + var messages = []; + var d = promise.defer(); + var waitResult = flow.wait(d.promise).then(function(value) { + messages.push('b'); + assert.equal(1234, value); + }); + setTimeout(function() { + messages.push('a'); + }, 5); + + timeout(10).then(function() { + assert.deepEqual(['a'], messages); + assert.ok(waitResult.isPending()); + d.fulfill(1234); + return waitResult; + }).then(function() { + assert.deepEqual(['a', 'b'], messages); + }); + + return waitForIdle(); + }); + }); + + describe('testSubtasks', function() { + it('(base case)', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + schedule('c'); + schedule('d'); + }); + schedule('b'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'sub-tasks', 'c', 'd', 'b'); + }); + }); + + it('nesting', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + schedule('b'); + scheduleAction('sub-sub-tasks', function() { + schedule('c'); + schedule('d'); + }); + schedule('e'); + }); + schedule('f'); + + return waitForIdle().then(function() { + assertFlowHistory( + 'a', 'sub-tasks', 'b', 'sub-sub-tasks', 'c', 'd', 'e', 'f'); + }); + }); + + it('taskReturnsSubTaskResult_1', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + return schedule('c'); + }); + schedule('b'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'sub-tasks', 'c', 'b'); + }); + }); + + it('taskReturnsSubTaskResult_2', function() { + let pair = callbackPair((value) => assert.equal(123, value)); + schedule('a'); + schedule('sub-tasks', promise.fulfilled(123)).then(pair.callback); + schedule('b'); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'sub-tasks','b'); + pair.assertCallback(); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_1', function() { + scheduleAction('a', function() { + return promise.delayed(10).then(function() { + schedule('b'); + }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_2', function() { + scheduleAction('a', function() { + return promise.fulfilled().then(function() { + schedule('b'); + }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_3', function() { + scheduleAction('a', function() { + return promise.delayed(10).then(function() { + return schedule('b'); + }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_4', function() { + scheduleAction('a', function() { + return promise.delayed(5).then(function() { + return promise.delayed(5).then(function() { + return schedule('b'); + }); + }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_5', function() { + scheduleAction('a', function() { + return promise.delayed(5).then(function() { + return promise.delayed(5).then(function() { + return promise.delayed(5).then(function() { + return promise.delayed(5).then(function() { + return schedule('b'); + }); + }); + }); + }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('taskReturnsPromiseThatDependsOnSubtask_6', function() { + scheduleAction('a', function() { + return promise.delayed(5). + then(function() { return promise.delayed(5) }). + then(function() { return promise.delayed(5) }). + then(function() { return promise.delayed(5) }). + then(function() { return schedule('b'); }); + }); + schedule('c'); + return waitForIdle().then(function() { + assertFlowHistory('a', 'b', 'c'); + }); + }); + + it('subTaskFails_1', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + scheduleAction('sub-task that fails', throwStubError); + }); + schedule('should never execute'); + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'sub-tasks', 'sub-task that fails'); + }); + }); + + it('subTaskFails_2', function() { + schedule('a'); + scheduleAction('sub-tasks', function() { + return promise.rejected(new StubError); + }); + schedule('should never execute'); + + return waitForAbort(). + then(assertIsStubError). + then(function() { + assertFlowHistory('a', 'sub-tasks'); + }); + }); + + it('subTaskFails_3', function() { + var callbacks = callbackPair(null, assertIsStubError); + + schedule('a'); + scheduleAction('sub-tasks', function() { + return promise.rejected(new StubError); + }).then(callbacks.callback, callbacks.errback); + schedule('b'); + + return waitForIdle(). + then(function() { + assertFlowHistory('a', 'sub-tasks', 'b'); + callbacks.assertErrback(); + }); + }); + }); + + describe('testEventLoopWaitsOnPendingPromiseRejections', function() { + it('oneRejection', function() { + var d = new promise.Deferred; + scheduleAction('one', function() { + return d.promise; + }); + scheduleAction('two', function() {}); + + return timeout(50).then(function() { + assertFlowHistory('one'); + d.reject(new StubError); + return waitForAbort(); + }). + then(assertIsStubError). + then(function() { + assertFlowHistory('one'); + }); + }); + + it('multipleRejections', function() { + var once = Error('once'); + var twice = Error('twice'); + + scheduleAction('one', function() { + promise.rejected(once); + promise.rejected(twice); + }); + var twoResult = scheduleAction('two', function() {}); + + flow.removeAllListeners( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION); + return new NativePromise(function(fulfill, reject) { + setTimeout(function() { + reject(Error('Should have reported the two errors by now')); + }, 50); + flow.on( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, + fulfill); + }).then(function(e) { + assert.ok(e instanceof promise.MultipleUnhandledRejectionError, + 'Not a MultipleUnhandledRejectionError'); + let errors = Array.from(e.errors); + assert.deepEqual([once, twice], errors); + assertFlowHistory('one'); + assert.ok(!twoResult.isPending(), 'Did not cancel the second task'); + }); + }); + }); + + describe('testCancelsPromiseReturnedByCallbackIfFrameFails', function() { + it('promiseCallback', function() { + var chainPair = callbackPair(null, assertIsStubError); + var deferredPair = callbackPair(null, function(e) { + assert.equal('CancellationError: StubError', e.toString(), + 'callback result should be cancelled'); + }); + + var d = new promise.Deferred(); + d.then(deferredPair.callback, deferredPair.errback); + + promise.fulfilled(). + then(function() { + scheduleAction('boom', throwStubError); + schedule('this should not run'); + return d.promise; + }). + then(chainPair.callback, chainPair.errback); + + return waitForIdle().then(function() { + assertFlowHistory('boom'); + chainPair.assertErrback('chain errback not invoked'); + deferredPair.assertErrback('deferred errback not invoked'); + }); + }); + + it('taskCallback', function() { + var chainPair = callbackPair(null, assertIsStubError); + var deferredPair = callbackPair(null, function(e) { + assert.equal('CancellationError: StubError', e.toString(), + 'callback result should be cancelled'); + }); + + var d = new promise.Deferred(); + d.then(deferredPair.callback, deferredPair.errback); + + schedule('a'). + then(function() { + scheduleAction('boom', throwStubError); + schedule('this should not run'); + return d.promise; + }). + then(chainPair.callback, chainPair.errback); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'boom'); + chainPair.assertErrback('chain errback not invoked'); + deferredPair.assertErrback('deferred errback not invoked'); + }); + }); + }); + + it('testMaintainsOrderInCallbacksWhenATaskReturnsAPromise', function() { + schedule('__start__', promise.fulfilled()). + then(function() { + messages.push('a'); + schedulePush('b'); + messages.push('c'); + }). + then(function() { + messages.push('d'); + }); + schedulePush('e'); + + return waitForIdle().then(function() { + assertFlowHistory('__start__', 'b', 'e'); + assertMessages('a', 'c', 'b', 'd', 'e'); + }); + }); + + it('testOwningFlowIsActivatedForExecutingTasks', function() { + var defaultFlow = promise.controlFlow(); + var order = []; + + promise.createFlow(function(flow) { + assertFlowIs(flow); + order.push(0); + + defaultFlow.execute(function() { + assertFlowIs(defaultFlow); + order.push(1); + }); + }); + + return waitForIdle().then(function() { + assertFlowIs(defaultFlow); + assert.deepEqual([0, 1], order); + }); + }); + + it('testCreateFlowReturnsPromisePairedWithCreatedFlow', function() { + return new NativePromise(function(fulfill, reject) { + var newFlow; + promise.createFlow(function(flow) { + newFlow = flow; + assertFlowIs(newFlow); + }).then(function() { + assertFlowIs(newFlow); + waitForIdle(newFlow).then(fulfill, reject); + }); + }); + }); + + it('testDeferredFactoriesCreateForActiveFlow_defaultFlow', function() { + var e = Error(); + var defaultFlow = promise.controlFlow(); + promise.fulfilled().then(function() { + assertFlowIs(defaultFlow); + }); + promise.rejected(e).then(null, function(err) { + assert.equal(e, err); + assertFlowIs(defaultFlow); + }); + promise.defer().then(function() { + assertFlowIs(defaultFlow); + }); + + return waitForIdle(); + }); + + it('testDeferredFactoriesCreateForActiveFlow_newFlow', function() { + var e = Error(); + var newFlow = new promise.ControlFlow; + newFlow.execute(function() { + promise.fulfilled().then(function() { + assertFlowIs(newFlow); + }); + + promise.rejected(e).then(null, function(err) { + assert.equal(e, err); + assertFlowIs(newFlow); + }); + + promise.defer().then(function() { + assertFlowIs(newFlow); + }); + }).then(function() { + assertFlowIs(newFlow); + }); + + return waitForIdle(newFlow); + }); + + it('testFlowsSynchronizeWithThemselvesNotEachOther', function() { + var defaultFlow = promise.controlFlow(); + schedulePush('a', 'a'); + promise.controlFlow().timeout(250); + schedulePush('b', 'b'); + + promise.createFlow(function() { + schedulePush('c', 'c'); + schedulePush('d', 'd'); + }); + + return waitForIdle().then(function() { + assertMessages('a', 'c', 'd', 'b'); + }); + }); + + it('testUnhandledErrorsAreReportedToTheOwningFlow', function() { + var error1 = Error('e1'); + var error2 = Error('e2'); + + var defaultFlow = promise.controlFlow(); + defaultFlow.removeAllListeners('uncaughtException'); + + var flow1Error = NativePromise.defer(); + flow1Error.promise.then(function(value) { + assert.equal(error2, value); + }); + + var flow2Error = NativePromise.defer(); + flow2Error.promise.then(function(value) { + assert.equal(error1, value); + }); + + promise.createFlow(function(flow) { + flow.once('uncaughtException', flow2Error.resolve); + promise.rejected(error1); + + defaultFlow.once('uncaughtException', flow1Error.resolve); + defaultFlow.execute(function() { + promise.rejected(error2); + }); + }); + + return NativePromise.all([flow1Error.promise, flow2Error.promise]); + }); + + it('testCanSynchronizeFlowsByReturningPromiseFromOneToAnother', function() { + var flow1 = new promise.ControlFlow; + var flow1Done = NativePromise.defer(); + flow1.once('idle', flow1Done.resolve); + flow1.once('uncaughtException', flow1Done.reject); + + var flow2 = new promise.ControlFlow; + var flow2Done = NativePromise.defer(); + flow2.once('idle', flow2Done.resolve); + flow2.once('uncaughtException', flow2Done.reject); + + flow1.execute(function() { + schedulePush('a', 'a'); + return promise.delayed(25); + }, 'start flow 1'); + + flow2.execute(function() { + schedulePush('b', 'b'); + schedulePush('c', 'c'); + flow2.execute(function() { + return flow1.execute(function() { + schedulePush('d', 'd'); + }, 'flow 1 task'); + }, 'inject flow1 result into flow2'); + schedulePush('e', 'e'); + }, 'start flow 2'); + + return NativePromise.all([flow1Done.promise, flow2Done.promise]). + then(function() { + assertMessages('a', 'b', 'c', 'd', 'e'); + }); + }); + + it('testFramesWaitToCompleteForPendingRejections', function() { + return new NativePromise(function(fulfill, reject) { + + promise.controlFlow().execute(function() { + promise.rejected(new StubError); + }).then(fulfill, reject); + + }). + then(() => fail('expected to fail'), assertIsStubError); + }); + + it('testSynchronizeErrorsPropagateToOuterFlow', function() { + var outerFlow = new promise.ControlFlow; + var innerFlow = new promise.ControlFlow; + + var block = NativePromise.defer(); + innerFlow.execute(function() { + return block.promise; + }, 'block inner flow'); + + outerFlow.execute(function() { + block.resolve(); + return innerFlow.execute(function() { + promise.rejected(new StubError); + }, 'trigger unhandled rejection error'); + }, 'run test'); + + return NativePromise.all([ + waitForIdle(innerFlow), + waitForAbort(outerFlow).then(assertIsStubError) + ]); + }); + + it('testFailsIfErrbackThrows', function() { + promise.rejected('').then(null, throwStubError); + return waitForAbort().then(assertIsStubError); + }); + + it('testFailsIfCallbackReturnsRejectedPromise', function() { + promise.fulfilled().then(function() { + return promise.rejected(new StubError); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('testAbortsFrameIfTaskFails', function() { + promise.fulfilled().then(function() { + promise.controlFlow().execute(throwStubError); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('testAbortsFramePromisedChainedFromTaskIsNotHandled', function() { + promise.fulfilled().then(function() { + promise.controlFlow().execute(function() {}). + then(throwStubError); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('testTrapsChainedUnhandledRejectionsWithinAFrame', function() { + var pair = callbackPair(null, assertIsStubError); + promise.fulfilled().then(function() { + promise.controlFlow().execute(function() {}). + then(throwStubError); + }).then(pair.callback, pair.errback); + + return waitForIdle().then(pair.assertErrback); + }); + + it('testCancelsRemainingTasksIfFrameThrowsDuringScheduling', function() { + var task1, task2; + var pair = callbackPair(null, assertIsStubError); + var flow = promise.controlFlow(); + flow.execute(function() { + task1 = flow.execute(function() {}); + task2 = flow.execute(function() {}); + throw new StubError; + }).then(pair.callback, pair.errback); + + return waitForIdle(). + then(pair.assertErrback). + then(function() { + assert.ok(!task1.isPending()); + pair = callbackPair(); + return task1.then(pair.callback, pair.errback); + }). + then(function() { + pair.assertErrback(); + assert.ok(!task2.isPending()); + pair = callbackPair(); + return task2.then(pair.callback, pair.errback); + }). + then(function() { + pair.assertErrback(); + }); + }); + + it('testCancelsRemainingTasksInFrameIfATaskFails', function() { + var task; + var pair = callbackPair(null, assertIsStubError); + var flow = promise.controlFlow(); + flow.execute(function() { + flow.execute(throwStubError); + task = flow.execute(function() {}); + }).then(pair.callback, pair.errback); + + return waitForIdle().then(pair.assertErrback).then(function() { + assert.ok(!task.isPending()); + pair = callbackPair(); + task.then(pair.callback, pair.errback); + }).then(function() { + pair.assertErrback(); + }); + }); + + it('testDoesNotModifyRejectionErrorIfPromiseNotInsideAFlow', function() { + var error = Error('original message'); + var originalStack = error.stack; + var originalStr = error.toString(); + + var pair = callbackPair(null, function(e) { + assert.equal(error, e); + assert.equal('original message', e.message); + assert.equal(originalStack, e.stack); + assert.equal(originalStr, e.toString()); + }); + + promise.rejected(error).then(pair.callback, pair.errback); + return waitForIdle().then(pair.assertErrback); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/444 */ + it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_1', function() { + var messages = []; + flow.execute(function() { + return promise.fulfilled(['a', 'b', 'c', 'd']); + }, 'start').then(function(steps) { + steps.forEach(function(step) { + promise.fulfilled(step) + .then(function() { + messages.push(step + '.1'); + }).then(function() { + messages.push(step + '.2'); + }); + }) + }); + return waitForIdle().then(function() { + assert.deepEqual( + ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'], + messages); + }); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/444 */ + it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_2', function() { + var messages = []; + flow.execute(function() { + return promise.fulfilled(['a', 'b', 'c', 'd']); + }, 'start').then(function(steps) { + steps.forEach(function(step) { + promise.fulfilled(step) + .then(function() { + messages.push(step + '.1'); + }).then(function() { + flow.execute(function() {}, step + '.2').then(function() { + messages.push(step + '.2'); + }); + }); + }) + }); + return waitForIdle().then(function() { + assert.deepEqual( + ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'], + messages); + }); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/444 */ + it('testMaintainsOrderWithPromiseChainsCreatedWithinAForeach_3', function() { + var messages = []; + flow.execute(function() { + return promise.fulfilled(['a', 'b', 'c', 'd']); + }, 'start').then(function(steps) { + steps.forEach(function(step) { + promise.fulfilled(step) + .then(function(){}) + .then(function() { + messages.push(step + '.1'); + return flow.execute(function() {}, step + '.1'); + }).then(function() { + flow.execute(function() {}, step + '.2').then(function(text) { + messages.push(step + '.2'); + }); + }); + }) + }); + return waitForIdle().then(function() { + assert.deepEqual( + ['a.1', 'a.2', 'b.1', 'b.2', 'c.1', 'c.2', 'd.1', 'd.2'], + messages); + }); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/363 */ + it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() { + scheduleAction('a', () => promise.delayed(10)); + schedule('b'); + setTimeout(() => schedule('c'), 0); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'b'); + }); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/363 */ + it('testTasksScheduledInASeparateTurnOfTheEventLoopGetASeparateTaskQueue_2', function() { + scheduleAction('a', () => promise.delayed(10)); + schedule('b'); + schedule('c'); + setTimeout(function() { + schedule('d'); + scheduleAction('e', () => promise.delayed(10)); + schedule('f'); + }, 0); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'd', 'e', 'b', 'c', 'f'); + }); + }); + + /** See https://github.com/SeleniumHQ/selenium/issues/363 */ + it('testCanSynchronizeTasksFromAdjacentTaskQueues', function() { + var task1 = scheduleAction('a', () => promise.delayed(10)); + schedule('b'); + setTimeout(function() { + scheduleAction('c', () => task1); + schedule('d'); + }, 0); + + return waitForIdle().then(function() { + assertFlowHistory('a', 'c', 'd', 'b'); + }); + }); + + describe('testCancellingAScheduledTask', function() { + it('1', function() { + var called = false; + var task1 = scheduleAction('a', () => called = true); + task1.cancel('no soup for you'); + + return waitForIdle().then(function() { + assert.ok(!called); + assertFlowHistory(); + return task1.thenCatch(function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('no soup for you', e.message); + }); + }); + }); + + it('2', function() { + schedule('a'); + var called = false; + var task2 = scheduleAction('b', () => called = true); + schedule('c'); + + task2.cancel('no soup for you'); + + return waitForIdle().then(function() { + assert.ok(!called); + assertFlowHistory('a', 'c'); + return task2.thenCatch(function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('no soup for you', e.message); + }); + }); + }); + + it('3', function() { + var called = false; + var task = scheduleAction('a', () => called = true); + task.cancel(new StubError); + + return waitForIdle().then(function() { + assert.ok(!called); + assertFlowHistory(); + return task.thenCatch(function(e) { + assert.ok(e instanceof promise.CancellationError); + }); + }); + }); + + it('4', function() { + var seen = []; + var task = scheduleAction('a', () => seen.push(1)) + .then(() => seen.push(2)) + .then(() => seen.push(3)) + .then(() => seen.push(4)) + .then(() => seen.push(5)); + task.cancel(new StubError); + + return waitForIdle().then(function() { + assert.deepEqual([], seen); + assertFlowHistory(); + return task.thenCatch(function(e) { + assert.ok(e instanceof promise.CancellationError); + }); + }); + }); + + it('fromWithinAnExecutingTask', function() { + var called = false; + var task; + scheduleAction('a', function() { + task.cancel('no soup for you'); + }); + task = scheduleAction('b', () => called = true); + schedule('c'); + + return waitForIdle().then(function() { + assert.ok(!called); + assertFlowHistory('a', 'c'); + return task.thenCatch(function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('no soup for you', e.message); + }); + }); + }); + }); + + it('testCancellingAPendingTask', function() { + var order = []; + var unresolved = promise.defer(); + + var innerTask; + var outerTask = scheduleAction('a', function() { + order.push(1); + + // Schedule a task that will never finish. + innerTask = scheduleAction('a.1', function() { + return unresolved.promise; + }); + + // Since the outerTask is cancelled below, innerTask should be cancelled + // with a DiscardedTaskError, which means its callbacks are silently + // dropped - so this should never execute. + innerTask.thenCatch(function(e) { + order.push(2); + }); + }); + schedule('b'); + + outerTask.thenCatch(function(e) { + order.push(3); + assert.ok(e instanceof promise.CancellationError); + assert.equal('no soup for you', e.message); + }); + + unresolved.promise.thenCatch(function(e) { + order.push(4); + assert.ok(e instanceof promise.CancellationError); + }); + + return timeout(10).then(function() { + assert.deepEqual([1], order); + assert.ok(unresolved.promise.isPending()); + + outerTask.cancel('no soup for you'); + return waitForIdle(); + }).then(function() { + assertFlowHistory('a', 'a.1', 'b'); + assert.deepEqual([1, 3, 4], order); + }); + }); + + it('testCancellingAPendingPromiseCallback', function() { + var called = false; + + var root = promise.fulfilled(); + root.then(function() { + cb2.cancel('no soup for you'); + }); + + var cb2 = root.then(fail, fail); // These callbacks should never be called. + cb2.then(fail, function(e) { + called = true; + assert.ok(e instanceof promise.CancellationError); + assert.equal('no soup for you', e.message); + }); + + return waitForIdle().then(function() { + assert.ok(called); + }); + }); + + describe('testResetFlow', function() { + it('1', function() { + var called = 0; + var task = flow.execute(() => called++); + task.thenFinally(() => called++); + + return new Promise(function(fulfill) { + flow.once('reset', fulfill); + flow.reset(); + + }).then(function() { + assert.equal(0, called); + assert.ok(!task.isPending()); + return task; + + }).then(fail, function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('ControlFlow was reset', e.message); + }); + }); + + it('2', function() { + var called = 0; + var task1 = flow.execute(() => called++); + task1.thenFinally(() => called++); + + var task2 = flow.execute(() => called++); + task2.thenFinally(() => called++); + + var task3 = flow.execute(() => called++); + task3.thenFinally(() => called++); + + return new Promise(function(fulfill) { + flow.once('reset', fulfill); + flow.reset(); + + }).then(function() { + assert.equal(0, called); + assert.ok(!task1.isPending()); + assert.ok(!task2.isPending()); + assert.ok(!task3.isPending()); + }); + }); + }); + + describe('testPromiseFulfilledInsideTask', function() { + it('1', function() { + var order = []; + + flow.execute(function() { + var d = promise.defer(); + + d.promise.then(() => order.push('a')); + d.promise.then(() => order.push('b')); + d.promise.then(() => order.push('c')); + d.fulfill(); + + flow.execute(() => order.push('d')); + + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order); + }); + }); + + it('2', function() { + var order = []; + + flow.execute(function() { + flow.execute(() => order.push('a')); + flow.execute(() => order.push('b')); + + var d = promise.defer(); + d.promise.then(() => order.push('c')); + d.promise.then(() => order.push('d')); + d.fulfill(); + + flow.execute(() => order.push('e')); + + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'fin'], order); + }); + }); + + it('3', function() { + var order = []; + var d = promise.defer(); + d.promise.then(() => order.push('c')); + d.promise.then(() => order.push('d')); + + flow.execute(function() { + flow.execute(() => order.push('a')); + flow.execute(() => order.push('b')); + + d.promise.then(() => order.push('e')); + d.fulfill(); + + flow.execute(() => order.push('f')); + + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['c', 'd', 'a', 'b', 'e', 'f', 'fin'], order); + }); + }); + + it('4', function() { + var order = []; + var d = promise.defer(); + d.promise.then(() => order.push('a')); + d.promise.then(() => order.push('b')); + + flow.execute(function() { + flow.execute(function() { + order.push('c'); + flow.execute(() => order.push('d')); + d.promise.then(() => order.push('e')); + }); + flow.execute(() => order.push('f')); + + d.promise.then(() => order.push('g')); + d.fulfill(); + + flow.execute(() => order.push('h')); + + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'fin'], order); + }); + }); + }); + + describe('testSettledPromiseCallbacksInsideATask', function() { + it('1', function() { + var order = []; + var p = promise.fulfilled(); + + flow.execute(function() { + flow.execute(() => order.push('a')); + p.then(() => order.push('b')); + flow.execute(() => order.push('c')); + p.then(() => order.push('d')); + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order); + }); + }); + + it('2', function() { + var order = []; + + flow.execute(function() { + flow.execute(() => order.push('a')) + .then( () => order.push('c')); + flow.execute(() => order.push('b')); + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'c', 'b', 'fin'], order); + }); + }); + }); + + it('testTasksDoNotWaitForNewlyCreatedPromises', function() { + var order = []; + + flow.execute(function() { + var d = promise.defer(); + + // This is a normal promise, not a task, so the task for this callback is + // considered volatile. Volatile tasks should be skipped when they reach + // the front of the task queue. + d.promise.then(() => order.push('a')); + + flow.execute(() => order.push('b')); + flow.execute(function() { + flow.execute(() => order.push('c')); + d.promise.then(() => order.push('d')); + d.fulfill(); + }); + flow.execute(() => order.push('e')); + + }).then(() => order.push('fin')); + + return waitForIdle().then(function() { + assert.deepEqual(['b', 'a', 'c', 'd', 'e', 'fin'], order); + }); + }); + + it('testCallbackDependenciesDoNotDeadlock', function() { + var order = []; + var root = promise.defer(); + var dep = promise.fulfilled().then(function() { + order.push('a'); + return root.promise.then(function() { + order.push('b'); + }); + }); + // This callback depends on |dep|, which depends on another callback + // attached to |root| via a chain. + root.promise.then(function() { + order.push('c'); + return dep.then(() => order.push('d')); + }).then(() => order.push('fin')); + + setTimeout(() => root.fulfill(), 20); + + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c', 'd', 'fin'], order); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/lib/promise_generator_test.js b/www/node_modules/selenium-webdriver/test/lib/promise_generator_test.js new file mode 100644 index 0000000..44568c9 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/promise_generator_test.js @@ -0,0 +1,308 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); +const promise = require('../../lib/promise'); + +describe('promise.consume()', function() { + it('requires inputs to be generator functions', function() { + assert.throws(function() { + promise.consume(function() {}); + }); + }); + + it('handles a basic generator with no yielded promises', function() { + var values = []; + return promise.consume(function* () { + var i = 0; + while (i < 4) { + i = yield i + 1; + values.push(i); + } + }).then(function() { + assert.deepEqual([1, 2, 3, 4], values); + }); + }); + + it('handles a promise yielding generator', function() { + var values = []; + return promise.consume(function* () { + var i = 0; + while (i < 4) { + // Test that things are actually async here. + setTimeout(function() { + values.push(i * 2); + }, 10); + + yield promise.delayed(10).then(function() { + values.push(i++); + }); + } + }).then(function() { + assert.deepEqual([0, 0, 2, 1, 4, 2, 6, 3], values); + }); + }); + + it('assignemnts to yielded promises get fulfilled value', function() { + return promise.consume(function* () { + var p = promise.fulfilled(2); + var x = yield p; + assert.equal(2, x); + }); + }); + + it('is possible to cancel promise generators', function() { + var values = []; + var p = promise.consume(function* () { + var i = 0; + while (i < 3) { + yield promise.delayed(100).then(function() { + values.push(i++); + }); + } + }); + return promise.delayed(75).then(function() { + p.cancel(); + return p.thenCatch(function() { + return promise.delayed(300); + }); + }).then(function() { + assert.deepEqual([0], values); + }); + }); + + it('uses final return value as fulfillment value', function() { + return promise.consume(function* () { + yield 1; + yield 2; + return 3; + }).then(function(value) { + assert.equal(3, value); + }); + }); + + it('throws rejected promise errors within the generator', function() { + var values = []; + return promise.consume(function* () { + values.push('a'); + var e = Error('stub error'); + try { + yield promise.rejected(e); + values.push('b'); + } catch (ex) { + assert.equal(e, ex); + values.push('c'); + } + values.push('d'); + }).then(function() { + assert.deepEqual(['a', 'c', 'd'], values); + }); + }); + + it('aborts the generator if there is an unhandled rejection', function() { + var values = []; + var e = Error('stub error'); + return promise.consume(function* () { + values.push(1); + yield promise.rejected(e); + values.push(2); + }).thenCatch(function() { + assert.deepEqual([1], values); + }); + }); + + it('yield waits for promises', function() { + var values = []; + var d = promise.defer(); + + setTimeout(function() { + assert.deepEqual([1], values); + d.fulfill(2); + }, 100); + + return promise.consume(function* () { + values.push(1); + values.push((yield d.promise), 3); + }).then(function() { + assert.deepEqual([1, 2, 3], values); + }); + }); + + it('accepts custom scopes', function() { + return promise.consume(function* () { + return this.name; + }, {name: 'Bob'}).then(function(value) { + assert.equal('Bob', value); + }); + }); + + it('accepts initial generator arguments', function() { + return promise.consume(function* (a, b) { + assert.equal('red', a); + assert.equal('apples', b); + }, null, 'red', 'apples'); + }); + + it('executes generator within the control flow', function() { + var promises = [ + promise.defer(), + promise.defer() + ]; + var values = []; + + setTimeout(function() { + assert.deepEqual([], values); + promises[0].fulfill(1); + }, 100); + + setTimeout(function() { + assert.deepEqual([1], values); + promises[1].fulfill(2); + }, 200); + + return promise.controlFlow().execute(function* () { + values.push(yield promises[0].promise); + values.push(yield promises[1].promise); + values.push('fin'); + }).then(function() { + assert.deepEqual([1, 2, 'fin'], values); + }); + }); + + it('handles tasks scheduled in generator', function() { + var flow = promise.controlFlow(); + return flow.execute(function* () { + var x = yield flow.execute(function() { + return promise.delayed(10).then(function() { + return 1; + }); + }); + + var y = yield flow.execute(function() { + return 2; + }); + + return x + y; + }).then(function(value) { + assert.equal(3, value); + }); + }); + + it('blocks the control flow while processing generator', function() { + var values = []; + return promise.controlFlow().wait(function* () { + yield values.push(1); + values.push(yield promise.delayed(10).then(function() { + return 2; + })); + yield values.push(3); + return values.length === 6; + }, 250).then(function() { + assert.deepEqual([1, 2, 3, 1, 2, 3], values); + }); + }); + + it('ControlFlow.wait() will timeout on long generator', function() { + var values = []; + return promise.controlFlow().wait(function* () { + var i = 0; + while (i < 3) { + yield promise.delayed(100).then(function() { + values.push(i++); + }); + } + }, 75).thenCatch(function() { + assert.deepEqual( + [0, 1, 2], values, 'Should complete one loop of wait condition'); + }); + }); + + describe('generators in promise callbacks', function() { + it('works with no initial value', function() { + var promises = [ + promise.defer(), + promise.defer() + ]; + var values = []; + + setTimeout(function() { + promises[0].fulfill(1); + }, 50); + + setTimeout(function() { + promises[1].fulfill(2); + }, 100); + + return promise.fulfilled().then(function*() { + values.push(yield promises[0].promise); + values.push(yield promises[1].promise); + values.push('fin'); + }).then(function() { + assert.deepEqual([1, 2, 'fin'], values); + }); + }); + + it('starts the generator with promised value', function() { + var promises = [ + promise.defer(), + promise.defer() + ]; + var values = []; + + setTimeout(function() { + promises[0].fulfill(1); + }, 50); + + setTimeout(function() { + promises[1].fulfill(2); + }, 100); + + return promise.fulfilled(3).then(function*(value) { + var p1 = yield promises[0].promise; + var p2 = yield promises[1].promise; + values.push(value + p1); + values.push(value + p2); + values.push('fin'); + }).then(function() { + assert.deepEqual([4, 5, 'fin'], values); + }); + }); + + it('throws yielded rejections within the generator callback', function() { + var d = promise.defer(); + var e = Error('stub'); + + setTimeout(function() { + d.reject(e); + }, 50); + + return promise.fulfilled().then(function*() { + var threw = false; + try { + yield d.promise; + } catch (ex) { + threw = true; + assert.equal(e, ex); + } + assert.ok(threw); + }); + }); + }); +}); + diff --git a/www/node_modules/selenium-webdriver/test/lib/promise_test.js b/www/node_modules/selenium-webdriver/test/lib/promise_test.js new file mode 100644 index 0000000..ed6d965 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/promise_test.js @@ -0,0 +1,996 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); + +const testutil = require('./testutil'); +const promise = require('../../lib/promise'); + +// Aliases for readability. +const NativePromise = Promise; +const StubError = testutil.StubError; +const assertIsStubError = testutil.assertIsStubError; +const callbackHelper = testutil.callbackHelper; +const callbackPair = testutil.callbackPair; +const throwStubError = testutil.throwStubError; +const fail = () => assert.fail(); + +// Refer to promise_aplus_test for promise compliance with standard behavior. +describe('promise', function() { + var app, uncaughtExceptions; + + beforeEach(function setUp() { + promise.LONG_STACK_TRACES = false; + uncaughtExceptions = []; + + app = promise.controlFlow(); + app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, + (e) => uncaughtExceptions.push(e)); + }); + + afterEach(function tearDown() { + app.reset(); + promise.setDefaultFlow(new promise.ControlFlow); + assert.deepEqual([], uncaughtExceptions, + 'Did not expect any uncaught exceptions'); + promise.LONG_STACK_TRACES = false; + }); + + const assertIsPromise = (p) => assert.ok(promise.isPromise(p)); + const assertNotPromise = (v) => assert.ok(!promise.isPromise(v)); + + function createRejectedPromise(reason) { + var p = promise.rejected(reason); + p.thenCatch(function() {}); + return p; + } + + it('testCanDetectPromiseLikeObjects', function() { + assertIsPromise(new promise.Promise(function(fulfill) { + fulfill(); + })); + assertIsPromise(new promise.Deferred()); + assertIsPromise(new promise.Deferred().promise); + assertIsPromise({then:function() {}}); + + assertNotPromise(undefined); + assertNotPromise(null); + assertNotPromise(''); + assertNotPromise(true); + assertNotPromise(false); + assertNotPromise(1); + assertNotPromise({}); + assertNotPromise({then:1}); + assertNotPromise({then:true}); + assertNotPromise({then:''}); + }); + + describe('then', function() { + it('returnsOwnPromiseIfNoCallbacksWereGiven', function() { + var deferred = new promise.Deferred(); + assert.equal(deferred.promise, deferred.promise.then()); + assert.equal(deferred.promise, deferred.promise.thenCatch()); + assert.equal(deferred.promise, promise.when(deferred.promise)); + }); + + it('stillConsideredUnHandledIfNoCallbacksWereGivenOnCallsToThen', function() { + promise.rejected(new StubError).then(); + var handler = callbackHelper(assertIsStubError); + + // so tearDown() doesn't throw + app.removeAllListeners(); + app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler); + return NativePromise.resolve().then(() => handler.assertCalled()); + }); + }); + + describe('thenFinally', function() { + it('nonFailingCallbackDoesNotSuppressOriginalError', function() { + var done = callbackHelper(assertIsStubError); + return promise.rejected(new StubError). + thenFinally(function() {}). + thenCatch(done). + thenFinally(done.assertCalled); + }); + + it('failingCallbackSuppressesOriginalError', function() { + var done = callbackHelper(assertIsStubError); + return promise.rejected(new Error('original')). + thenFinally(throwStubError). + thenCatch(done). + thenFinally(done.assertCalled); + }); + + it('callbackThrowsAfterFulfilledPromise', function() { + var done = callbackHelper(assertIsStubError); + return promise.fulfilled(). + thenFinally(throwStubError). + thenCatch(done). + thenFinally(done.assertCalled); + }); + + it('callbackReturnsRejectedPromise', function() { + var done = callbackHelper(assertIsStubError); + return promise.fulfilled(). + thenFinally(function() { + return promise.rejected(new StubError); + }). + thenCatch(done). + thenFinally(done.assertCalled); + }); + }); + + describe('cancel', function() { + it('passesTheCancellationReasonToReject', function() { + var d = new promise.Deferred(); + var res = d.then(assert.fail, function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('because i said so', e.message); + }); + d.cancel('because i said so'); + return res; + }); + + it('canCancelADeferredFromAChainedPromise', function() { + var d = new promise.Deferred(); + var p = d.then(assert.fail, function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('because i said so', e.message); + }); + var p2 = p.then(function() {}, assert.fail); + + p.cancel('because i said so'); + return p2; + }); + + it('canCancelATimeout', function() { + var p = promise.delayed(25) + .then(assert.fail, (e) => e instanceof promise.CancellationError); + setTimeout(() => p.cancel(), 20); + p.cancel(); + return p; + }); + + it('cancelIsANoopOnceAPromiseHasBeenFulfilled', function() { + var p = promise.fulfilled(123); + p.cancel(); + return p.then((v) => assert.equal(123, v)); + }); + + it('cancelIsANoopOnceAPromiseHasBeenRejected', function() { + var p = promise.rejected(new StubError); + p.cancel(); + + var pair = callbackPair(null, assertIsStubError); + return p.then(assert.fail, assertIsStubError); + }); + + it('noopCancelTriggeredOnCallbackOfResolvedPromise', function() { + var d = promise.defer(); + var p = d.promise.then(); + + d.fulfill(); + p.cancel(); // This should not throw. + return p; // This should not trigger a failure. + }); + }); + + describe('when', function() { + it('ReturnsAResolvedPromiseIfGivenANonPromiseValue', function() { + var ret = promise.when('abc'); + assertIsPromise(ret); + return ret.then((value) => assert.equal('abc', value)); + }); + + it('PassesRawErrorsToCallbacks', function() { + var error = new Error('boo!'); + return promise.when(error, function(value) { + assert.equal(error, value); + }); + }); + + it('WaitsForValueToBeResolvedBeforeInvokingCallback', function() { + var d = new promise.Deferred(), callback; + let result = promise.when(d, callback = callbackHelper(function(value) { + assert.equal('hi', value); + })); + callback.assertNotCalled(); + d.fulfill('hi'); + return result.then(callback.assertCalled); + }); + + it('canCancelReturnedPromise', function() { + var callbacks = callbackPair(null, function(e) { + assert.ok(e instanceof promise.CancellationError); + assert.equal('just because', e.message); + }); + + var promiseLike = { + then: function(cb, eb) { + this.callback = cb; + this.errback = eb; + } + }; + + var aPromise = promise.when(promiseLike, + callbacks.callback, callbacks.errback); + + assert.ok(aPromise.isPending()); + aPromise.cancel('just because'); + + return aPromise.thenFinally(callbacks.assertErrback); + }); + }); + + it('firesUncaughtExceptionEventIfRejectionNeverHandled', function() { + promise.rejected(new StubError); + var handler = callbackHelper(assertIsStubError); + + // so tearDown() doesn't throw + app.removeAllListeners(); + app.on(promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION, handler); + + return NativePromise.resolve().then(handler.assertCalled); + }); + + it('cannotResolveADeferredWithItself', function() { + var deferred = new promise.Deferred(); + assert.throws(() => deferred.fulfill(deferred)); + assert.throws(() => deferred.reject(deferred)); + }); + + describe('fullyResolved', function() { + it('primitives', function() { + function runTest(value) { + var callback, errback; + return promise.fullyResolved(value) + .then((resolved) => assert.equal(value, resolved)); + } + return runTest(true) + .then(() => runTest(function() {})) + .then(() => runTest(null)) + .then(() => runTest(123)) + .then(() => runTest('foo bar')) + .then(() => runTest(undefined)); + }); + + it('arrayOfPrimitives', function() { + var fn = function() {}; + var array = [true, fn, null, 123, '', undefined, 1]; + return promise.fullyResolved(array).then(function(resolved) { + assert.equal(array, resolved); + assert.deepEqual([true, fn, null, 123, '', undefined, 1], + resolved); + }); + }); + + it('nestedArrayOfPrimitives', function() { + var fn = function() {}; + var array = [true, [fn, null, 123], '', undefined]; + return promise.fullyResolved(array) + .then(function(resolved) { + assert.equal(array, resolved); + assert.deepEqual([true, [fn, null, 123], '', undefined], resolved); + assert.deepEqual([fn, null, 123], resolved[1]); + }); + }); + + it('arrayWithPromisedPrimitive', function() { + return promise.fullyResolved([promise.fulfilled(123)]) + .then(function(resolved) { + assert.deepEqual([123], resolved); + }); + }); + + it('promiseResolvesToPrimitive', function() { + return promise.fullyResolved(promise.fulfilled(123)) + .then((resolved) => assert.equal(123, resolved)); + }); + + it('promiseResolvesToArray', function() { + var fn = function() {}; + var array = [true, [fn, null, 123], '', undefined]; + var aPromise = promise.fulfilled(array); + + var result = promise.fullyResolved(aPromise); + return result.then(function(resolved) { + assert.equal(array, resolved); + assert.deepEqual([true, [fn, null, 123], '', undefined], + resolved); + assert.deepEqual([fn, null, 123], resolved[1]); + }); + }); + + it('promiseResolvesToArrayWithPromises', function() { + var nestedPromise = promise.fulfilled(123); + var aPromise = promise.fulfilled([true, nestedPromise]); + return promise.fullyResolved(aPromise) + .then(function(resolved) { + assert.deepEqual([true, 123], resolved); + }); + }); + + it('rejectsIfArrayPromiseRejects', function() { + var nestedPromise = createRejectedPromise(new StubError); + var aPromise = promise.fulfilled([true, nestedPromise]); + + var pair = callbackPair(null, assertIsStubError); + return promise.fullyResolved(aPromise) + .then(assert.fail, assertIsStubError); + }); + + it('rejectsOnFirstArrayRejection', function() { + var e1 = new Error('foo'); + var e2 = new Error('bar'); + var aPromise = promise.fulfilled([ + createRejectedPromise(e1), + createRejectedPromise(e2) + ]); + + return promise.fullyResolved(aPromise) + .then(assert.fail, function(error) { + assert.strictEqual(e1, error); + }); + }); + + it('rejectsIfNestedArrayPromiseRejects', function() { + var aPromise = promise.fulfilled([ + promise.fulfilled([ + createRejectedPromise(new StubError) + ]) + ]); + + return promise.fullyResolved(aPromise) + .then(assert.fail, assertIsStubError); + }); + + it('simpleHash', function() { + var hash = {'a': 123}; + return promise.fullyResolved(hash) + .then(function(resolved) { + assert.strictEqual(hash, resolved); + assert.deepEqual(hash, {'a': 123}); + }); + }); + + it('nestedHash', function() { + var nestedHash = {'foo':'bar'}; + var hash = {'a': 123, 'b': nestedHash}; + + return promise.fullyResolved(hash) + .then(function(resolved) { + assert.strictEqual(hash, resolved); + assert.deepEqual({'a': 123, 'b': {'foo': 'bar'}}, resolved); + assert.strictEqual(nestedHash, resolved['b']); + }); + }); + + it('promiseResolvesToSimpleHash', function() { + var hash = {'a': 123}; + var aPromise = promise.fulfilled(hash); + + return promise.fullyResolved(aPromise) + .then((resolved) => assert.strictEqual(hash, resolved)); + }); + + it('promiseResolvesToNestedHash', function() { + var nestedHash = {'foo':'bar'}; + var hash = {'a': 123, 'b': nestedHash}; + var aPromise = promise.fulfilled(hash); + + return promise.fullyResolved(aPromise) + .then(function(resolved) { + assert.strictEqual(hash, resolved); + assert.strictEqual(nestedHash, resolved['b']); + assert.deepEqual(hash, {'a': 123, 'b': {'foo': 'bar'}}); + }); + }); + + it('promiseResolvesToHashWithPromises', function() { + var aPromise = promise.fulfilled({ + 'a': promise.fulfilled(123) + }); + + return promise.fullyResolved(aPromise) + .then(function(resolved) { + assert.deepEqual({'a': 123}, resolved); + }); + }); + + it('rejectsIfHashPromiseRejects', function() { + var aPromise = promise.fulfilled({ + 'a': createRejectedPromise(new StubError) + }); + + return promise.fullyResolved(aPromise) + .then(assert.fail, assertIsStubError); + }); + + it('rejectsIfNestedHashPromiseRejects', function() { + var aPromise = promise.fulfilled({ + 'a': {'b': createRejectedPromise(new StubError)} + }); + + return promise.fullyResolved(aPromise) + .then(assert.fail, assertIsStubError); + }); + + it('instantiatedObject', function() { + function Foo() { + this.bar = 'baz'; + } + var foo = new Foo; + + return promise.fullyResolved(foo).then(function(resolvedFoo) { + assert.equal(foo, resolvedFoo); + assert.ok(resolvedFoo instanceof Foo); + assert.deepEqual(new Foo, resolvedFoo); + }); + }); + + it('withEmptyArray', function() { + return promise.fullyResolved([]).then(function(resolved) { + assert.deepEqual([], resolved); + }); + }); + + it('withEmptyHash', function() { + return promise.fullyResolved({}).then(function(resolved) { + assert.deepEqual({}, resolved); + }); + }); + + it('arrayWithPromisedHash', function() { + var obj = {'foo': 'bar'}; + var array = [promise.fulfilled(obj)]; + + return promise.fullyResolved(array).then(function(resolved) { + assert.deepEqual(resolved, [obj]); + }); + }); + }); + + describe('checkedNodeCall', function() { + it('functionThrows', function() { + return promise.checkedNodeCall(throwStubError) + .then(assert.fail, assertIsStubError); + }); + + it('functionReturnsAnError', function() { + return promise.checkedNodeCall(function(callback) { + callback(new StubError); + }).then(assert.fail, assertIsStubError); + }); + + it('functionReturnsSuccess', function() { + var success = 'success!'; + return promise.checkedNodeCall(function(callback) { + callback(null, success); + }).then((value) => assert.equal(success, value)); + }); + + it('functionReturnsAndThrows', function() { + var error = new Error('boom'); + var error2 = new Error('boom again'); + return promise.checkedNodeCall(function(callback) { + callback(error); + throw error2; + }).then(assert.fail, (e) => assert.equal(error, e)); + }); + + it('functionThrowsAndReturns', function() { + var error = new Error('boom'); + var error2 = new Error('boom again'); + return promise.checkedNodeCall(function(callback) { + setTimeout(() => callback(error), 10); + throw error2; + }).then(assert.fail, (e) => assert.equal(error2, e)); + }); + }); + + describe('all', function() { + it('(base case)', function() { + var a = [ + 0, 1, + promise.defer(), + promise.defer(), + 4, 5, 6 + ]; + delete a[5]; + + var pair = callbackPair(function(value) { + assert.deepEqual([0, 1, 2, 3, 4, undefined, 6], value); + }); + + var result = promise.all(a).then(pair.callback, pair.errback); + pair.assertNeither(); + + a[2].fulfill(2); + pair.assertNeither(); + + a[3].fulfill(3); + return result.then(() => pair.assertCallback()); + }); + + it('empty array', function() { + return promise.all([]).then((a) => assert.deepEqual([], a)); + }); + + it('usesFirstRejection', function() { + var a = [ + promise.defer(), + promise.defer() + ]; + + var result = promise.all(a).then(assert.fail, assertIsStubError); + a[1].reject(new StubError); + setTimeout(() => a[0].reject(Error('ignored')), 0); + return result; + }); + }); + + describe('map', function() { + it('(base case)', function() { + var a = [1, 2, 3]; + return promise.map(a, function(value, index, a2) { + assert.equal(a, a2); + assert.equal('number', typeof index, 'not a number'); + return value + 1; + }).then(function(value) { + assert.deepEqual([2, 3, 4], value); + }); + }); + + it('omitsDeleted', function() { + var a = [0, 1, 2, 3, 4, 5, 6]; + delete a[1]; + delete a[3]; + delete a[4]; + delete a[6]; + + var expected = [0, 1, 4, 9, 16, 25, 36]; + delete expected[1]; + delete expected[3]; + delete expected[4]; + delete expected[6]; + + return promise.map(a, function(value) { + return value * value; + }).then(function(value) { + assert.deepEqual(expected, value); + }); + }); + + it('emptyArray', function() { + return promise.map([], function(value) { + return value + 1; + }).then(function(value) { + assert.deepEqual([], value); + }); + }); + + it('inputIsPromise', function() { + var input = promise.defer(); + var result = promise.map(input, function(value) { + return value + 1; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual([2, 3, 4], value); + }); + result = result.then(pair.callback, pair.errback); + + setTimeout(function() { + pair.assertNeither(); + input.fulfill([1, 2, 3]); + }, 10); + + return result; + }); + + it('waitsForFunctionResultToResolve', function() { + var innerResults = [ + promise.defer(), + promise.defer() + ]; + + var result = promise.map([1, 2], function(value, index) { + return innerResults[index].promise; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual(['a', 'b'], value); + }); + result = result.then(pair.callback, pair.errback); + + return NativePromise.resolve() + .then(function() { + pair.assertNeither(); + innerResults[0].fulfill('a'); + }) + .then(function() { + pair.assertNeither(); + innerResults[1].fulfill('b'); + return result; + }) + .then(pair.assertCallback); + }); + + it('rejectsPromiseIfFunctionThrows', function() { + return promise.map([1], throwStubError) + .then(assert.fail, assertIsStubError); + }); + + it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() { + return promise.map([1], function() { + return promise.rejected(new StubError); + }).then(assert.fail, assertIsStubError); + }); + + it('stopsCallingFunctionIfPreviousIterationFailed', function() { + var count = 0; + return promise.map([1, 2, 3, 4], function() { + count++; + if (count == 3) { + throw new StubError; + } + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.equal(3, count); + }); + }); + + it('rejectsWithFirstRejectedPromise', function() { + var innerResult = [ + promise.fulfilled(), + createRejectedPromise(new StubError), + createRejectedPromise(Error('should be ignored')) + ]; + var count = 0; + return promise.map([1, 2, 3, 4], function(value, index) { + count += 1; + return innerResult[index]; + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.equal(2, count); + }); + }); + + it('preservesOrderWhenMapReturnsPromise', function() { + var deferreds = [ + promise.defer(), + promise.defer(), + promise.defer(), + promise.defer() + ]; + var result = promise.map(deferreds, function(value) { + return value.promise; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual([0, 1, 2, 3], value); + }); + result = result.then(pair.callback, pair.errback); + + return NativePromise.resolve() + .then(function() { + pair.assertNeither(); + for (let i = deferreds.length; i > 0; i -= 1) { + deferreds[i - 1].fulfill(i - 1); + } + return result; + }).then(pair.assertCallback); + }); + }); + + describe('filter', function() { + it('basicFiltering', function() { + var a = [0, 1, 2, 3]; + return promise.filter(a, function(val, index, a2) { + assert.equal(a, a2); + assert.equal('number', typeof index, 'not a number'); + return val > 1; + }).then(function(val) { + assert.deepEqual([2, 3], val); + }); + }); + + it('omitsDeleted', function() { + var a = [0, 1, 2, 3, 4, 5, 6]; + delete a[3]; + delete a[4]; + + return promise.filter(a, function(value) { + return value > 1 && value < 6; + }).then(function(val) { + assert.deepEqual([2, 5], val); + }); + }); + + it('preservesInputs', function() { + var a = [0, 1, 2, 3]; + + return promise.filter(a, function(value, i, a2) { + assert.equal(a, a2); + // Even if a function modifies the input array, the original value + // should be inserted into the new array. + a2[i] = a2[i] - 1; + return a2[i] >= 1; + }).then(function(val) { + assert.deepEqual([2, 3], val); + }); + }); + + it('inputIsPromise', function() { + var input = promise.defer(); + var result = promise.filter(input, function(value) { + return value > 1 && value < 3; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual([2], value); + }); + result = result.then(pair.callback, pair.errback); + return NativePromise.resolve() + .then(function() { + pair.assertNeither(); + input.fulfill([1, 2, 3]); + return result; + }) + .then(pair.assertCallback); + }); + + it('waitsForFunctionResultToResolve', function() { + var innerResults = [ + promise.defer(), + promise.defer() + ]; + + var result = promise.filter([1, 2], function(value, index) { + return innerResults[index].promise; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual([2], value); + }); + result = result.then(pair.callback, pair.errback); + return NativePromise.resolve() + .then(function() { + pair.assertNeither(); + innerResults[0].fulfill(false); + }) + .then(function() { + pair.assertNeither(); + innerResults[1].fulfill(true); + return result; + }) + .then(pair.assertCallback); + }); + + it('rejectsPromiseIfFunctionReturnsRejectedPromise', function() { + return promise.filter([1], function() { + return promise.rejected(new StubError); + }).then(assert.fail, assertIsStubError); + }); + + it('stopsCallingFunctionIfPreviousIterationFailed', function() { + var count = 0; + return promise.filter([1, 2, 3, 4], function() { + count++; + if (count == 3) { + throw new StubError; + } + }).then(assert.fail, function(e) { + assertIsStubError(e); + assert.equal(3, count); + }); + }); + + it('rejectsWithFirstRejectedPromise', function() { + var innerResult = [ + promise.fulfilled(), + createRejectedPromise(new StubError), + createRejectedPromise(Error('should be ignored')) + ]; + + return promise.filter([1, 2, 3, 4], function(value, index) { + assert.ok(index < innerResult.length); + return innerResult[index]; + }).then(assert.fail, assertIsStubError); + }); + + it('preservesOrderWhenFilterReturnsPromise', function() { + var deferreds = [ + promise.defer(), + promise.defer(), + promise.defer(), + promise.defer() + ]; + var result = promise.filter([0, 1, 2, 3], function(value, index) { + return deferreds[index].promise; + }); + + var pair = callbackPair(function(value) { + assert.deepEqual([1, 2], value); + }); + result = result.then(pair.callback, pair.errback); + + return NativePromise.resolve() + .then(function() { + pair.assertNeither(); + for (let i = deferreds.length - 1; i >= 0; i -= 1) { + deferreds[i].fulfill(i > 0 && i < 3); + } + return result; + }).then(pair.assertCallback); + }); + }); + + it('testAddThenableImplementation', function() { + function tmp() {} + assert.ok(!promise.Thenable.isImplementation(new tmp())); + promise.Thenable.addImplementation(tmp); + assert.ok(promise.Thenable.isImplementation(new tmp())); + + class tmpClass {} + assert.ok(!promise.Thenable.isImplementation(new tmpClass())); + promise.Thenable.addImplementation(tmpClass); + assert.ok(promise.Thenable.isImplementation(new tmpClass())); + }); + + describe('testLongStackTraces', function() { + beforeEach(() => promise.LONG_STACK_TRACES = false); + afterEach(() => promise.LONG_STACK_TRACES = false); + + it('doesNotAppendStackIfFeatureDisabled', function() { + promise.LONG_STACK_TRACES = false; + + var error = Error('hello'); + var originalStack = error.stack; + return promise.rejected(error). + then(fail). + then(fail). + then(fail). + then(fail, function(e) { + assert.equal(error, e); + assert.equal(originalStack, e.stack); + }); + }); + + function getStackMessages(error) { + return error.stack.split(/\n/).filter(function(line) { + return /^From: /.test(line); + }); + } + + it('appendsInitialPromiseCreation_resolverThrows', function() { + promise.LONG_STACK_TRACES = true; + + var error = Error('hello'); + var originalStack = '(placeholder; will be overwritten later)'; + + return new promise.Promise(function() { + try { + throw error; + } catch (e) { + originalStack = e.stack; + throw e; + } + }).then(fail, function(e) { + assert.strictEqual(error, e); + if (typeof originalStack !== 'string') { + return; + } + assert.notEqual(originalStack, e.stack); + assert.equal(e.stack.indexOf(originalStack), 0, + 'should start with original stack'); + assert.deepEqual(['From: Promise: new'], getStackMessages(e)); + }); + }); + + it('appendsInitialPromiseCreation_rejectCalled', function() { + promise.LONG_STACK_TRACES = true; + + var error = Error('hello'); + var originalStack = error.stack; + + return new promise.Promise(function(_, reject) { + reject(error); + }).then(fail, function(e) { + assert.equal(error, e); + if (typeof originalStack !== 'string') { + return; + } + assert.notEqual(originalStack, e.stack); + assert.equal(e.stack.indexOf(originalStack), 0, + 'should start with original stack'); + assert.deepEqual(['From: Promise: new'], getStackMessages(e)); + }); + }); + + it('appendsEachStepToRejectionError', function() { + promise.LONG_STACK_TRACES = true; + + var error = Error('hello'); + var originalStack = '(placeholder; will be overwritten later)'; + + return new promise.Promise(function() { + try { + throw error; + } catch (e) { + originalStack = e.stack; + throw e; + } + }). + then(fail). + thenCatch(function(e) { throw e; }). + then(fail). + thenCatch(function(e) { throw e; }). + then(fail, function(e) { + assert.equal(error, e); + if (typeof originalStack !== 'string') { + return; + } + assert.notEqual(originalStack, e.stack); + assert.equal(e.stack.indexOf(originalStack), 0, + 'should start with original stack'); + assert.deepEqual([ + 'From: Promise: new', + 'From: Promise: then', + 'From: Promise: catch', + 'From: Promise: then', + 'From: Promise: catch', + ], getStackMessages(e)); + }); + }); + + it('errorOccursInCallbackChain', function() { + promise.LONG_STACK_TRACES = true; + + var error = Error('hello'); + var originalStack = '(placeholder; will be overwritten later)'; + + return promise.fulfilled(). + then(function() {}). + then(function() {}). + then(function() { + try { + throw error; + } catch (e) { + originalStack = e.stack; + throw e; + } + }). + thenCatch(function(e) { throw e; }). + then(fail, function(e) { + assert.equal(error, e); + if (typeof originalStack !== 'string') { + return; + } + assert.notEqual(originalStack, e.stack); + assert.equal(e.stack.indexOf(originalStack), 0, + 'should start with original stack'); + assert.deepEqual([ + 'From: Promise: then', + 'From: Promise: catch', + ], getStackMessages(e)); + }); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/lib/testutil.js b/www/node_modules/selenium-webdriver/test/lib/testutil.js new file mode 100644 index 0000000..e68ca28 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/testutil.js @@ -0,0 +1,90 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); +const sinon = require('sinon'); + + +class StubError extends Error { + constructor(opt_msg) { + super(opt_msg); + this.name = this.constructor.name; + } +} +exports.StubError = StubError; + +exports.throwStubError = function() { + throw new StubError; +}; + +exports.assertIsStubError = function(value) { + assert.ok(value instanceof StubError, value + ' is not a ' + StubError.name); +}; + +exports.assertIsInstance = function(ctor, value) { + assert.ok(value instanceof ctor, 'Not a ' + ctor.name + ': ' + value); +}; + +function callbackPair(cb, eb) { + if (cb && eb) { + throw new TypeError('can only specify one of callback or errback'); + } + + let callback = cb ? sinon.spy(cb) : sinon.spy(); + let errback = eb ? sinon.spy(eb) : sinon.spy(); + + function assertCallback() { + assert.ok(callback.called, 'callback not called'); + assert.ok(!errback.called, 'errback called'); + if (callback.threw()) { + throw callback.exceptions[0]; + } + } + + function assertErrback() { + assert.ok(!callback.called, 'callback called'); + assert.ok(errback.called, 'errback not called'); + if (errback.threw()) { + throw errback.exceptions[0]; + } + } + + function assertNeither() { + assert.ok(!callback.called, 'callback called'); + assert.ok(!errback.called, 'errback called'); + } + + return { + callback, + errback, + assertCallback, + assertErrback, + assertNeither + }; +} +exports.callbackPair = callbackPair; + + +exports.callbackHelper = function(cb) { + let pair = callbackPair(cb); + let wrapped = pair.callback.bind(null); + wrapped.assertCalled = () => pair.assertCallback(); + wrapped.assertNotCalled = () => pair.assertNeither(); + return wrapped; +}; diff --git a/www/node_modules/selenium-webdriver/test/lib/until_test.js b/www/node_modules/selenium-webdriver/test/lib/until_test.js new file mode 100644 index 0000000..3a25b76 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/until_test.js @@ -0,0 +1,436 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('assert'); + +const error = require('../../error'); +const By = require('../../lib/by').By; +const CommandName = require('../../lib/command').Name; +const promise = require('../../lib/promise'); +const until = require('../../lib/until'); +const webdriver = require('../../lib/webdriver'); + +describe('until', function() { + let driver, executor; + + function createResponse(value) { + return {status: 0, value}; + } + + class TestExecutor { + constructor() { + this.handlers_ = {}; + } + + on(cmd, handler) { + this.handlers_[cmd] = handler; + return this; + } + + execute(cmd) { + let self = this; + return new Promise(function(fulfill) { + if (!self.handlers_[cmd.getName()]) { + throw new error.UnknownCommandError(cmd.getName()); + } + fulfill(self.handlers_[cmd.getName()](cmd)); + }); + } + } + + function fail(opt_msg) { + throw new assert.AssertionError({message: opt_msg}); + } + + beforeEach(function setUp() { + executor = new TestExecutor(); + driver = new webdriver.WebDriver('session-id', executor); + }); + + describe('ableToSwitchToFrame', function() { + it('failsFastForNonSwitchErrors', function() { + let e = Error('boom'); + executor.on(CommandName.SWITCH_TO_FRAME, function() { + throw e; + }); + return driver.wait(until.ableToSwitchToFrame(0), 100) + .then(fail, (e2) => assert.strictEqual(e2, e)); + }); + + it('byIndex', function() { + executor.on(CommandName.SWITCH_TO_FRAME, function() { + return {status: error.ErrorCode.SUCCESS}; + }); + return driver.wait(until.ableToSwitchToFrame(0), 100); + }); + + it('byWebElement', function() { + executor.on(CommandName.SWITCH_TO_FRAME, function(cmd, callback) { + return {status: error.ErrorCode.SUCCESS}; + }); + var el = new webdriver.WebElement(driver, {ELEMENT: 1234}); + return driver.wait(until.ableToSwitchToFrame(el), 100); + }); + + it('byWebElementPromise', function() { + executor.on(CommandName.SWITCH_TO_FRAME, function(cmd, callback) { + return {status: error.ErrorCode.SUCCESS}; + }); + var el = new webdriver.WebElementPromise(driver, + promise.fulfilled(new webdriver.WebElement(driver, {ELEMENT: 1234}))); + return driver.wait(until.ableToSwitchToFrame(el), 100); + }); + + it('byLocator', function() { + executor.on(CommandName.FIND_ELEMENTS, function() { + return { + status: error.ErrorCode.SUCCESS, + value: [{ELEMENT: 1234}] + }; + }).on(CommandName.SWITCH_TO_FRAME, function() { + return {status: error.ErrorCode.SUCCESS}; + }); + + return driver.wait(until.ableToSwitchToFrame(By.id('foo')), 100); + }); + + it('byLocator_elementNotInitiallyFound', function() { + var foundResponses = [[], [], [{ELEMENT: 1234}]]; + executor.on(CommandName.FIND_ELEMENTS, function() { + return { + status: error.ErrorCode.SUCCESS, + value: foundResponses.shift() + }; + }).on(CommandName.SWITCH_TO_FRAME, function(cmd, callback) { + return {status: error.ErrorCode.SUCCESS}; + }); + + return driver.wait(until.ableToSwitchToFrame(By.id('foo')), 2000) + .then(function() { + assert.equal(foundResponses.length, 0); + }); + }); + + it('timesOutIfNeverAbletoSwitchFrames', function() { + var count = 0; + executor.on(CommandName.SWITCH_TO_FRAME, function() { + count += 1; + return {status: error.ErrorCode.NO_SUCH_FRAME}; + }); + + return driver.wait(until.ableToSwitchToFrame(0), 100) + .then(fail, function(e) { + assert.ok(count > 0); + assert.ok( + e.message.startsWith('Waiting to be able to switch to frame'), + 'Wrong message: ' + e.message); + }); + }); + }); + + describe('alertIsPresent', function() { + it('failsFastForNonAlertSwitchErrors', function() { + return driver.wait(until.alertIsPresent(), 100).then(fail, function(e) { + assert.ok(e instanceof error.UnknownCommandError); + assert.equal(e.message, CommandName.GET_ALERT_TEXT); + }); + }); + + it('waitsForAlert', function() { + var count = 0; + executor.on(CommandName.GET_ALERT_TEXT, function() { + if (count++ < 3) { + return {status: error.ErrorCode.NO_SUCH_ALERT}; + } else { + return {status: error.ErrorCode.SUCCESS}; + } + }).on(CommandName.DISMISS_ALERT, function(cmd, callback) { + return {status: error.ErrorCode.SUCCESS}; + }); + + return driver.wait(until.alertIsPresent(), 1000).then(function(alert) { + assert.equal(count, 4); + return alert.dismiss(); + }); + }); + }); + + it('testUntilTitleIs', function() { + var titles = ['foo', 'bar', 'baz']; + executor.on(CommandName.GET_TITLE, function() { + return createResponse(titles.shift()); + }); + + return driver.wait(until.titleIs('bar'), 3000).then(function() { + assert.deepStrictEqual(titles, ['baz']); + }); + }); + + it('testUntilTitleContains', function() { + var titles = ['foo', 'froogle', 'google']; + executor.on(CommandName.GET_TITLE, function() { + return createResponse(titles.shift()); + }); + + return driver.wait(until.titleContains('oogle'), 3000).then(function() { + assert.deepStrictEqual(titles, ['google']); + }); + }); + + it('testUntilTitleMatches', function() { + var titles = ['foo', 'froogle', 'aaaabc', 'aabbbc', 'google']; + executor.on(CommandName.GET_TITLE, function() { + return createResponse(titles.shift()); + }); + + return driver.wait(until.titleMatches(/^a{2,3}b+c$/), 3000) + .then(function() { + assert.deepStrictEqual(titles, ['google']); + }); + }); + + it('testUntilElementLocated', function() { + var responses = [[], [{ELEMENT: 'abc123'}, {ELEMENT: 'foo'}], ['end']]; + executor.on(CommandName.FIND_ELEMENTS, function(cmd, callback) { + return createResponse(responses.shift()); + }); + + let element = driver.wait(until.elementLocated(By.id('quux')), 2000); + assert.ok(element instanceof webdriver.WebElementPromise); + return element.getId().then(function(id) { + assert.deepStrictEqual(responses, [['end']]); + assert.equal(id, 'abc123'); + }); + }); + + describe('untilElementLocated, elementNeverFound', function() { + function runNoElementFoundTest(locator, locatorStr) { + executor.on(CommandName.FIND_ELEMENTS, function() { + return createResponse([]); + }); + + function expectedFailure() { + fail('expected condition to timeout'); + } + + return driver.wait(until.elementLocated(locator), 100) + .then(expectedFailure, function(error) { + var expected = 'Waiting for element to be located ' + locatorStr; + var lines = error.message.split(/\n/, 2); + assert.equal(lines[0], expected); + + let regex = /^Wait timed out after \d+ms$/; + assert.ok(regex.test(lines[1]), + `Lines <${lines[1]}> does not match ${regex}`); + }); + } + + it('byLocator', function() { + return runNoElementFoundTest( + By.id('quux'), 'By(css selector, *[id="quux"])'); + }); + + it('byHash', function() { + return runNoElementFoundTest( + {id: 'quux'}, 'By(css selector, *[id="quux"])'); + }); + + it('byFunction', function() { + return runNoElementFoundTest(function() {}, 'by function()'); + }); + }); + + it('testUntilElementsLocated', function() { + var responses = [[], [{ELEMENT: 'abc123'}, {ELEMENT: 'foo'}], ['end']]; + executor.on(CommandName.FIND_ELEMENTS, function() { + return createResponse(responses.shift()); + }); + + return driver.wait(until.elementsLocated(By.id('quux')), 2000) + .then(function(els) { + return Promise.all(els.map(e => e.getId())); + }).then(function(ids) { + assert.deepStrictEqual(responses, [['end']]); + assert.equal(ids.length, 2); + assert.equal(ids[0], 'abc123'); + assert.equal(ids[1], 'foo'); + }); + }); + + describe('untilElementsLocated, noElementsFound', function() { + function runNoElementsFoundTest(locator, locatorStr) { + executor.on(CommandName.FIND_ELEMENTS, function() { + return createResponse([]); + }); + + function expectedFailure() { + fail('expected condition to timeout'); + } + + return driver.wait(until.elementsLocated(locator), 100) + .then(expectedFailure, function(error) { + var expected = + 'Waiting for at least one element to be located ' + locatorStr; + var lines = error.message.split(/\n/, 2); + assert.equal(lines[0], expected); + + let regex = /^Wait timed out after \d+ms$/; + assert.ok(regex.test(lines[1]), + `Lines <${lines[1]}> does not match ${regex}`); + }); + } + + it('byLocator', function() { + return runNoElementsFoundTest( + By.id('quux'), 'By(css selector, *[id="quux"])'); + }); + + it('byHash', function() { + return runNoElementsFoundTest( + {id: 'quux'}, 'By(css selector, *[id="quux"])'); + }); + + it('byFunction', function() { + return runNoElementsFoundTest(function() {}, 'by function()'); + }); + }); + + it('testUntilStalenessOf', function() { + var responses = [ + createResponse('body'), + createResponse('body'), + createResponse('body'), + {status: error.ErrorCode.STALE_ELEMENT_REFERENCE, + value: {message: 'now stale'}}, + ['end'] + ]; + executor.on(CommandName.GET_ELEMENT_TAG_NAME, function() { + return responses.shift(); + }); + + var el = new webdriver.WebElement(driver, {ELEMENT: 'foo'}); + return driver.wait(until.stalenessOf(el), 2000).then(function() { + assert.deepStrictEqual(responses, [['end']]); + }); + }); + + describe('element state conditions', function() { + function runElementStateTest(predicate, command, responses, var_args) { + let original = new webdriver.WebElement(driver, 'foo'); + let predicateArgs = [original]; + if (arguments.length > 3) { + predicateArgs = predicateArgs.concat(arguments[1]); + command = arguments[2]; + responses = arguments[3]; + } + + assert.ok(responses.length > 1); + + responses = responses.concat(['end']); + executor.on(command, function() { + return createResponse(responses.shift()); + }); + + let result = driver.wait(predicate.apply(null, predicateArgs), 2000); + assert.ok(result instanceof webdriver.WebElementPromise); + return result.then(function(value) { + assert.ok(value instanceof webdriver.WebElement); + assert.ok(!(value instanceof webdriver.WebElementPromise)); + return value.getId(); + }).then(function(id) { + assert.equal('foo', id); + assert.deepStrictEqual(responses, ['end']); + }); + } + + it('elementIsVisible', function() { + return runElementStateTest( + until.elementIsVisible, + CommandName.IS_ELEMENT_DISPLAYED, [false, false, true]); + }); + + it('elementIsNotVisible', function() { + return runElementStateTest( + until.elementIsNotVisible, + CommandName.IS_ELEMENT_DISPLAYED, [true, true, false]); + }); + + it('elementIsEnabled', function() { + return runElementStateTest( + until.elementIsEnabled, + CommandName.IS_ELEMENT_ENABLED, [false, false, true]); + }); + + it('elementIsDisabled', function() { + return runElementStateTest( + until.elementIsDisabled, + CommandName.IS_ELEMENT_ENABLED, [true, true, false]); + }); + + it('elementIsSelected', function() { + return runElementStateTest( + until.elementIsSelected, + CommandName.IS_ELEMENT_SELECTED, [false, false, true]); + }); + + it('elementIsNotSelected', function() { + return runElementStateTest( + until.elementIsNotSelected, + CommandName.IS_ELEMENT_SELECTED, [true, true, false]); + }); + + it('elementTextIs', function() { + return runElementStateTest( + until.elementTextIs, 'foobar', + CommandName.GET_ELEMENT_TEXT, + ['foo', 'fooba', 'foobar']); + }); + + it('elementTextContains', function() { + return runElementStateTest( + until.elementTextContains, 'bar', + CommandName.GET_ELEMENT_TEXT, + ['foo', 'foobaz', 'foobarbaz']); + }); + + it('elementTextMatches', function() { + return runElementStateTest( + until.elementTextMatches, /fo+bar{3}/, + CommandName.GET_ELEMENT_TEXT, + ['foo', 'foobar', 'fooobarrr']); + }); + }); + + describe('WebElementCondition', function() { + it('fails if wait completes with a non-WebElement value', function() { + let result = driver.wait( + new until.WebElementCondition('testing', () => 123), 1000); + + return result.then( + () => assert.fail('expected to fail'), + function(e) { + assert.ok(e instanceof TypeError); + assert.equal( + 'WebElementCondition did not resolve to a WebElement: ' + + '[object Number]', + e.message); + }); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/lib/webdriver_test.js b/www/node_modules/selenium-webdriver/test/lib/webdriver_test.js new file mode 100644 index 0000000..eb68625 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/lib/webdriver_test.js @@ -0,0 +1,2207 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const testutil = require('./testutil'); + +const error = require('../../error'); + +const By = require('../../lib/by').By; +const Capabilities = require('../../lib/capabilities').Capabilities; +const Executor = require('../../lib/command').Executor; +const CName = require('../../lib/command').Name; +const Button = require('../../lib/input').Button; +const Key = require('../../lib/input').Key; +const logging = require('../../lib/logging'); +const Session = require('../../lib/session').Session; +const promise = require('../../lib/promise'); +const Alert = require('../../lib/webdriver').Alert; +const AlertPromise = require('../../lib/webdriver').AlertPromise; +const UnhandledAlertError = require('../../lib/webdriver').UnhandledAlertError; +const WebDriver = require('../../lib/webdriver').WebDriver; +const WebElement = require('../../lib/webdriver').WebElement; +const WebElementPromise = require('../../lib/webdriver').WebElementPromise; + +const assert = require('assert'); +const sinon = require('sinon'); + +const SESSION_ID = 'test_session_id'; + +// Aliases for readability. +const NativePromise = Promise; +const ECode = error.ErrorCode; +const StubError = testutil.StubError; +const assertIsInstance = testutil.assertIsInstance; +const assertIsStubError = testutil.assertIsStubError; +const throwStubError = testutil.throwStubError; +const fail = (msg) => assert.fail(msg); + +describe('WebDriver', function() { + const LOG = logging.getLogger('webdriver.test'); + + // before(function() { + // logging.getLogger('webdriver').setLevel(logging.Level.ALL); + // logging.installConsoleHandler(); + // }); + + // after(function() { + // logging.getLogger('webdriver').setLevel(null); + // logging.removeConsoleHandler(); + // }); + + var driver; + var flow; + var uncaughtExceptions; + + beforeEach(function setUp() { + flow = promise.controlFlow(); + uncaughtExceptions = []; + flow.on('uncaughtException', onUncaughtException); + }); + + afterEach(function tearDown() { + return waitForIdle(flow).then(function() { + assert.deepEqual([], uncaughtExceptions); + flow.reset(); + }); + }); + + function onUncaughtException(e) { + uncaughtExceptions.push(e); + } + + function waitForIdle(opt_flow) { + var theFlow = opt_flow || flow; + return new Promise(function(fulfill, reject) { + if (theFlow.isIdle()) { + fulfill(); + return; + } + theFlow.once('idle', fulfill); + theFlow.once('uncaughtException', reject); + }); + } + + function waitForAbort(opt_flow, opt_n) { + var n = opt_n || 1; + var theFlow = opt_flow || flow; + theFlow.removeAllListeners( + promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION); + return new Promise(function(fulfill, reject) { + theFlow.once('idle', function() { + reject(Error('expected flow to report an unhandled error')); + }); + + var errors = []; + theFlow.on('uncaughtException', onError); + function onError(e) { + errors.push(e); + if (errors.length === n) { + theFlow.removeListener('uncaughtException', onError); + fulfill(n === 1 ? errors[0] : errors); + } + } + }); + } + + function expectedError(ctor, message) { + return function(e) { + assertIsInstance(ctor, e); + assert.equal(message, e.message); + }; + } + + class Expectation { + constructor(executor, name, opt_parameters) { + this.executor_ = executor; + this.name_ = name; + this.times_ = 1; + this.sessionId_ = SESSION_ID; + this.check_ = null; + this.toDo_ = null; + this.withParameters(opt_parameters || {}); + } + + anyTimes() { + this.times_ = Infinity; + return this; + } + + times(n) { + this.times_ = n; + return this; + } + + withParameters(parameters) { + this.parameters_ = parameters; + if (this.name_ !== CName.NEW_SESSION) { + this.parameters_['sessionId'] = this.sessionId_; + } + return this; + } + + andReturn(code, opt_value) { + this.toDo_ = function(command) { + LOG.info('executing ' + command.getName() + '; returning ' + code); + return Promise.resolve({ + 'status': code, + 'sessionId': { + 'value': SESSION_ID + }, + 'value': opt_value !== void(0) ? opt_value : null + }); + }; + return this; + } + + andReturnSuccess(opt_value) { + return this.andReturn(0, opt_value); + } + + andReturnError(code, opt_value) { + return this.andReturn(code, opt_value); + } + + expect(name, opt_parameters) { + this.end(); + return this.executor_.expect(name, opt_parameters); + } + + end() { + if (!this.toDo_) { + this.andReturnSuccess(null); + } + return this.executor_; + } + + execute(command) { + assert.deepEqual(this.parameters_, command.getParameters()); + return this.toDo_(command); + } + } + + class FakeExecutor { + constructor() { + this.commands_ = new Map; + } + + execute(command) { + let expectations = this.commands_.get(command.getName()); + if (!expectations || !expectations.length) { + assert.fail('unexpected command: ' + command.getName()); + return; + } + + let next = expectations[0]; + let result = next.execute(command); + if (next.times_ != Infinity) { + next.times_ -= 1; + if (!next.times_) { + expectations.shift(); + } + } + return result; + } + + expect(commandName, opt_parameters) { + if (!this.commands_.has(commandName)) { + this.commands_.set(commandName, []); + } + let e = new Expectation(this, commandName, opt_parameters); + this.commands_.get(commandName).push(e); + return e; + } + + createDriver(opt_session) { + let session = opt_session || new Session(SESSION_ID, {}); + return new WebDriver(session, this); + } + } + + + ///////////////////////////////////////////////////////////////////////////// + // + // Tests + // + ///////////////////////////////////////////////////////////////////////////// + + + describe('testAttachToSession', function() { + it('sessionIsAvailable', function() { + let executor = new FakeExecutor(). + expect(CName.DESCRIBE_SESSION). + withParameters({'sessionId': SESSION_ID}). + andReturnSuccess({'browserName': 'firefox'}). + end(); + + let driver = WebDriver.attachToSession(executor, SESSION_ID); + return driver.getSession().then(function(session) { + assert.deepEqual({'value': 'test_session_id'}, session.getId()); + assert.equal('firefox', session.getCapability('browserName')); + }); + }); + + it('failsToGetSessionInfo', function() { + let executor = new FakeExecutor(). + expect(CName.DESCRIBE_SESSION). + withParameters({'sessionId': SESSION_ID}). + andReturnError(ECode.UNKNOWN_ERROR, {'message': 'boom'}). + end(); + + let driver = WebDriver.attachToSession(executor, SESSION_ID); + return driver.getSession() + .then(() => assert.fail('should have failed!'), function(e) { + assertIsInstance(error.WebDriverError, e); + assert.equal('boom', e.message); + }); + }); + + it('usesActiveFlowByDefault', function() { + let executor = new FakeExecutor(). + expect(CName.DESCRIBE_SESSION). + withParameters({'sessionId': SESSION_ID}). + andReturnSuccess({}). + end(); + + var driver = WebDriver.attachToSession(executor, SESSION_ID); + assert.equal(driver.controlFlow(), promise.controlFlow()); + + return waitForIdle(driver.controlFlow()); + }); + + it('canAttachInCustomFlow', function() { + let executor = new FakeExecutor(). + expect(CName.DESCRIBE_SESSION). + withParameters({'sessionId': SESSION_ID}). + andReturnSuccess({}). + end(); + + var otherFlow = new promise.ControlFlow(); + var driver = WebDriver.attachToSession(executor, SESSION_ID, otherFlow); + assert.equal(otherFlow, driver.controlFlow()); + assert.notEqual(otherFlow, promise.controlFlow()); + + return waitForIdle(otherFlow); + }); + }); + + describe('testCreateSession', function() { + it('happyPathWithCapabilitiesHashObject', function() { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({ + 'desiredCapabilities': {'browserName': 'firefox'} + }). + andReturnSuccess({'browserName': 'firefox'}). + end(); + + var driver = WebDriver.createSession(executor, { + 'browserName': 'firefox' + }); + return driver.getSession().then(function(session) { + assert.deepEqual({ + 'value':'test_session_id' + }, session.getId()); + assert.equal('firefox', session.getCapability('browserName')); + }); + }); + + it('happyPathWithCapabilitiesInstance', function() { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({'desiredCapabilities': {'browserName': 'firefox'}}). + andReturnSuccess({'browserName': 'firefox'}). + end(); + + var driver = WebDriver.createSession(executor, Capabilities.firefox()); + return driver.getSession().then(function(session) { + assert.deepEqual({'value':'test_session_id' }, session.getId()); + assert.equal('firefox', session.getCapability('browserName')); + }); + }); + + it('failsToCreateSession', function() { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({'desiredCapabilities': {'browserName': 'firefox'}}). + andReturnError(ECode.UNKNOWN_ERROR, {'message': 'boom'}). + end(); + + var driver = + WebDriver.createSession(executor, {'browserName': 'firefox'}); + return driver.getSession().then(fail, function(e) { + assertIsInstance(error.WebDriverError, e); + assert.equal('boom', e.message); + }); + }); + + it('usesActiveFlowByDefault', function() { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({'desiredCapabilities': {}}). + andReturnSuccess({}). + end(); + + var driver = WebDriver.createSession(executor, {}); + assert.equal(promise.controlFlow(), driver.controlFlow()); + + return waitForIdle(driver.controlFlow()); + }); + + it('canCreateInCustomFlow', function() { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({'desiredCapabilities': {}}). + andReturnSuccess({}). + end(); + + var otherFlow = new promise.ControlFlow(); + var driver = WebDriver.createSession(executor, {}, otherFlow); + assert.equal(otherFlow, driver.controlFlow()); + assert.notEqual(otherFlow, promise.controlFlow()); + + return waitForIdle(otherFlow); + }); + }); + + it('testDoesNotExecuteCommandIfSessionDoesNotResolve', function() { + var session = Promise.reject(new StubError); + new FakeExecutor().createDriver(session).getTitle(); + return waitForAbort().then(assertIsStubError); + }); + + it('testCommandReturnValuesArePassedToFirstCallback', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE).andReturnSuccess('Google Search'). + end(); + + var driver = executor.createDriver(); + return driver.getTitle().then(function(title) { + assert.equal('Google Search', title); + }); + }); + + it('testStopsCommandExecutionWhenAnErrorOccurs', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW). + withParameters({'name': 'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message': 'window not found'}). + end(); + + var driver = executor.createDriver(); + driver.switchTo().window('foo'); + driver.getTitle(); // mock should blow if this gets executed + + return waitForAbort(). + then(expectedError(error.NoSuchWindowError, 'window not found')); + }); + + it('testCanSuppressCommandFailures', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW). + withParameters({'name': 'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message': 'window not found'}). + expect(CName.GET_TITLE). + andReturnSuccess('Google Search'). + end(); + + var driver = executor.createDriver(); + driver.switchTo().window('foo') + .thenCatch(expectedError(error.NoSuchWindowError, 'window not found')); + driver.getTitle(); + return waitForIdle(); + }); + + it('testErrorsPropagateUpToTheRunningApplication', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW). + withParameters({'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message': 'window not found'}). + end(); + + executor.createDriver().switchTo().window('foo'); + return waitForAbort(). + then(expectedError(error.NoSuchWindowError, 'window not found')); + }); + + it('testErrbacksThatReturnErrorsStillSwitchToCallbackChain', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW). + withParameters({'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + end(); + + var driver = executor.createDriver(); + return driver.switchTo().window('foo'). + thenCatch(function() { return new StubError; }); + then(assertIsStubError); + }); + + it('testErrbacksThrownCanOverrideOriginalError', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + end(); + + var driver = executor.createDriver(); + driver.switchTo().window('foo').thenCatch(throwStubError); + + return waitForAbort().then(assertIsStubError); + }); + + it('testCannotScheduleCommandsIfTheSessionIdHasBeenDeleted', function() { + var driver = new FakeExecutor().createDriver(); + delete driver.session_; + assert.throws(() => driver.get('http://www.google.com')); + }); + + it('testDeletesSessionIdAfterQuitting', function() { + var driver; + let executor = new FakeExecutor(). + expect(CName.QUIT). + end(); + + driver = executor.createDriver(); + return driver.quit().then(function() { + assert.equal(void 0, driver.session_); + }); + }); + + it('testReportsErrorWhenExecutingCommandsAfterExecutingAQuit', function() { + let executor = new FakeExecutor(). + expect(CName.QUIT). + end(); + + var driver = executor.createDriver(); + driver.quit(); + driver.get('http://www.google.com'); + return waitForAbort(). + then(expectedError( + error.UnsupportedOperationError, + 'This driver instance does not have a valid session ID ' + + '(did you call WebDriver.quit()?) and may no longer be used.')); + }); + + it('testCallbackCommandsExecuteBeforeNextCommand', function() { + let executor = new FakeExecutor(). + expect(CName.GET_CURRENT_URL). + expect(CName.GET, {'url': 'http://www.google.com'}). + expect(CName.CLOSE). + expect(CName.GET_TITLE). + end(); + + var driver = executor.createDriver(); + driver.getCurrentUrl().then(function() { + driver.get('http://www.google.com').then(function() { + driver.close(); + }); + }); + driver.getTitle(); + + return waitForIdle(); + }); + + it('testEachCallbackFrameRunsToCompletionBeforeTheNext', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.GET_CURRENT_URL). + expect(CName.GET_CURRENT_WINDOW_HANDLE). + expect(CName.CLOSE). + expect(CName.QUIT). + end(); + + var driver = executor.createDriver(); + driver.getTitle(). + // Everything in this callback... + then(function() { + driver.getCurrentUrl(); + driver.getWindowHandle(); + }). + // ...should execute before everything in this callback. + then(function() { + driver.close(); + }); + // This should execute after everything above + driver.quit(); + + return waitForIdle(); + }); + + describe('nestedCommandFailures', function() { + it('bubbleUpToGlobalHandlerIfUnsuppressed', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + end(); + + var driver = executor.createDriver(); + driver.getTitle().then(function() { + driver.switchTo().window('foo'); + }); + + return waitForAbort(). + then(expectedError(error.NoSuchWindowError, 'window not found')); + }); + + it('canBeSuppressWhenTheyOccur', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + expect(CName.CLOSE). + end(); + + var driver = executor.createDriver(); + driver.getTitle().then(function() { + driver.switchTo().window('foo').thenCatch(function() {}); + }); + driver.close(); + + return waitForIdle(); + }); + + it('bubbleUpThroughTheFrameStack', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + end(); + + var driver = executor.createDriver(); + driver.getTitle(). + then(function() { + return driver.switchTo().window('foo'); + }). + thenCatch(function(e) { + assertIsInstance(error.NoSuchWindowError, e); + assert.equal('window not found', e.message); + }); + + return waitForIdle(); + }); + + it('canBeCaughtAndSuppressed', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.GET_CURRENT_URL). + expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + expect(CName.CLOSE). + end(); + + var driver = executor.createDriver(); + driver.getTitle().then(function() { + driver.getCurrentUrl(). + then(function() { + return driver.switchTo().window('foo'); + }). + thenCatch(function() {}); + driver.close(); + }); + + return waitForIdle(); + }); + }); + + describe('returningAPromise', function() { + it('fromACallback', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.GET_CURRENT_URL). + andReturnSuccess('http://www.google.com'). + end(); + + var driver = executor.createDriver(); + driver.getTitle(). + then(function() { + return driver.getCurrentUrl(); + }). + then(function(value) { + assert.equal('http://www.google.com', value); + }); + return waitForIdle(); + }); + + it('fromAnErrbackSuppressesTheError', function() { + var count = 0; + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + expect(CName.GET_CURRENT_URL). + andReturnSuccess('http://www.google.com'). + end(); + + var driver = executor.createDriver(); + driver.switchTo().window('foo'). + thenCatch(function(e) { + assertIsInstance(error.NoSuchWindowError, e); + assert.equal('window not found', e.message); + count += 1; + return driver.getCurrentUrl(); + }). + then(function(url) { + count += 1; + assert.equal('http://www.google.com', url); + }); + return waitForIdle().then(function() { + assert.equal(2, count); + }); + }); + }); + + describe('customFunctions', function() { + it('returnsANonPromiseValue', function() { + var driver = new FakeExecutor().createDriver(); + return driver.call(() => 'abc123').then(function(value) { + assert.equal('abc123', value); + }); + }); + + it('executionOrderWithCustomFunctions', function() { + var msg = []; + let executor = new FakeExecutor(). + expect(CName.GET_TITLE).andReturnSuccess('cheese '). + expect(CName.GET_CURRENT_URL).andReturnSuccess('tasty'). + end(); + + var driver = executor.createDriver(); + + var pushMsg = msg.push.bind(msg); + driver.getTitle().then(pushMsg); + driver.call(() => 'is ').then(pushMsg); + driver.getCurrentUrl().then(pushMsg); + driver.call(() => '!').then(pushMsg); + + return waitForIdle().then(function() { + assert.equal('cheese is tasty!', msg.join('')); + }); + }); + + it('passingArgumentsToACustomFunction', function() { + var add = function(a, b) { + return a + b; + }; + var driver = new FakeExecutor().createDriver(); + return driver.call(add, null, 1, 2).then(function(value) { + assert.equal(3, value); + }); + }); + + it('passingPromisedArgumentsToACustomFunction', function() { + var promisedArg = promise.fulfilled(2); + var add = function(a, b) { + return a + b; + }; + var driver = new FakeExecutor().createDriver(); + return driver.call(add, null, 1, promisedArg).then(function(value) { + assert.equal(3, value); + }); + }); + + it('passingArgumentsAndScopeToACustomFunction', function() { + function Foo(name) { + this.name = name; + } + Foo.prototype.getName = function() { + return this.name; + }; + var foo = new Foo('foo'); + + var driver = new FakeExecutor().createDriver(); + return driver.call(foo.getName, foo).then(function(value) { + assert.equal('foo', value); + }); + }); + + it('customFunctionThrowsAnError', function() { + var driver = new FakeExecutor().createDriver(); + return driver.call(throwStubError).then(fail, assertIsStubError); + }); + + it('customFunctionSchedulesCommands', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.CLOSE). + expect(CName.QUIT). + end(); + + var driver = executor.createDriver(); + driver.call(function() { + driver.getTitle(); + driver.close(); + }); + driver.quit(); + return waitForIdle(); + }); + + it('returnsATaskResultAfterSchedulingAnother', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + andReturnSuccess('Google Search'). + expect(CName.CLOSE). + end(); + + var driver = executor.createDriver(); + return driver.call(function() { + var title = driver.getTitle(); + driver.close(); + return title; + }).then(function(title) { + assert.equal('Google Search', title); + }); + }); + + it('hasANestedCommandThatFails', function() { + let executor = new FakeExecutor(). + expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}). + andReturnError(ECode.NO_SUCH_WINDOW, {'message':'window not found'}). + end(); + + var driver = executor.createDriver(); + return driver.call(function() { + return driver.switchTo().window('foo'); + }).then(fail, function(e) { + assertIsInstance(error.NoSuchWindowError, e); + assert.equal('window not found', e.message); + }); + }); + + it('doesNotCompleteUntilReturnedPromiseIsResolved', function() { + var order = []; + var driver = new FakeExecutor().createDriver(); + + var d = promise.defer(); + d.promise.then(function() { + order.push('b'); + }); + + driver.call(function() { + order.push('a'); + return d.promise; + }); + driver.call(function() { + order.push('c'); + }); + + // timeout to ensure the first function starts its execution before we + // trigger d's callbacks. + return new Promise(f => setTimeout(f, 0)).then(function() { + assert.deepEqual(['a'], order); + d.fulfill(); + return waitForIdle().then(function() { + assert.deepEqual(['a', 'b', 'c'], order); + }); + }); + }); + + it('returnsADeferredAction', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE).andReturnSuccess('Google'). + end(); + + var driver = executor.createDriver(); + driver.call(function() { + return driver.getTitle(); + }).then(function(title) { + assert.equal('Google', title); + }); + return waitForIdle(); + }); + }); + + describe('nestedCommands', function() { + it('commandExecutionOrder', function() { + var msg = []; + var driver = new FakeExecutor().createDriver(); + driver.call(msg.push, msg, 'a'); + driver.call(function() { + driver.call(msg.push, msg, 'c'); + driver.call(function() { + driver.call(msg.push, msg, 'e'); + driver.call(msg.push, msg, 'f'); + }); + driver.call(msg.push, msg, 'd'); + }); + driver.call(msg.push, msg, 'b'); + return waitForIdle().then(function() { + assert.equal('acefdb', msg.join('')); + }); + }); + + it('basicUsage', function() { + var msg = []; + var driver = new FakeExecutor().createDriver(); + var pushMsg = msg.push.bind(msg); + driver.call(() => 'cheese ').then(pushMsg); + driver.call(function() { + driver.call(() => 'is ').then(pushMsg); + driver.call(() => 'tasty').then(pushMsg); + }); + driver.call(() => '!').then(pushMsg); + return waitForIdle().then(function() { + assert.equal('cheese is tasty!', msg.join('')); + }); + }); + + it('canReturnValueFromNestedFunction', function() { + var driver = new FakeExecutor().createDriver(); + return driver.call(function() { + return driver.call(function() { + return driver.call(() => 'foobar'); + }); + }).then(function(value) { + assert.equal('foobar', value); + }); + }); + + it('normalCommandAfterNestedCommandThatReturnsAnAction', function() { + var msg = []; + let executor = new FakeExecutor(). + expect(CName.CLOSE). + end(); + var driver = executor.createDriver(); + driver.call(function() { + return driver.call(function() { + msg.push('a'); + return driver.call(() => 'foobar'); + }); + }); + driver.close().then(function() { + msg.push('b'); + }); + return waitForIdle().then(function() { + assert.equal('ab', msg.join('')); + }); + }); + + it('errorsBubbleUp_caught', function() { + var driver = new FakeExecutor().createDriver(); + var result = driver.call(function() { + return driver.call(function() { + return driver.call(throwStubError); + }); + }).then(fail, assertIsStubError); + return Promise.all([waitForIdle(), result]); + }); + + it('errorsBubbleUp_uncaught', function() { + var driver = new FakeExecutor().createDriver(); + driver.call(function() { + return driver.call(function() { + return driver.call(throwStubError); + }); + }); + return waitForAbort().then(assertIsStubError); + }); + + it('canScheduleCommands', function() { + let executor = new FakeExecutor(). + expect(CName.GET_TITLE). + expect(CName.CLOSE). + end(); + + var driver = executor.createDriver(); + driver.call(function() { + driver.call(function() { + driver.getTitle(); + }); + driver.close(); + }); + return waitForIdle(); + }); + }); + + describe('WebElementPromise', function() { + it('resolvesWhenUnderlyingElementDoes', function() { + var el = new WebElement({}, {'ELEMENT': 'foo'}); + return new WebElementPromise({}, promise.fulfilled(el)).then(function(e) { + assert.strictEqual(e, el); + }); + }); + + it('resolvesBeforeCallbacksOnWireValueTrigger', function() { + var el = new promise.Deferred(); + + var element = new WebElementPromise({}, el.promise); + var messages = []; + + element.then(function() { + messages.push('element resolved'); + }); + element.getId().then(function() { + messages.push('wire value resolved'); + }); + + assert.deepEqual([], messages); + el.fulfill(new WebElement({}, {'ELEMENT': 'foo'})); + return waitForIdle().then(function() { + assert.deepEqual([ + 'element resolved', + 'wire value resolved' + ], messages); + }); + }); + + it('isRejectedIfUnderlyingIdIsRejected', function() { + var element = new WebElementPromise({}, promise.rejected(new StubError)); + return element.then(fail, assertIsStubError); + }); + }); + + describe('executeScript', function() { + it('nullReturnValue', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return document.body;', + 'args': [] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + return driver.executeScript('return document.body;') + .then((result) => assert.equal(null, result)); + }); + + it('primitiveReturnValue', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return document.body;', + 'args': [] + }). + andReturnSuccess(123). + end(); + + var driver = executor.createDriver(); + return driver.executeScript('return document.body;') + .then((result) => assert.equal(123, result)); + }); + + it('webElementReturnValue', function() { + var json = WebElement.buildId('foo'); + + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return document.body;', + 'args': [] + }). + andReturnSuccess(json). + end(); + + var driver = executor.createDriver(); + return driver.executeScript('return document.body;') + .then((element) => element.getId()) + .then((id) => assert.equal(id, 'foo')); + }); + + it('arrayReturnValue', function() { + var json = [WebElement.buildId('foo')]; + + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return document.body;', + 'args': [] + }). + andReturnSuccess(json). + end(); + + var driver = executor.createDriver(); + return driver.executeScript('return document.body;') + .then(function(array) { + assert.equal(1, array.length); + return array[0].getId(); + }) + .then((id) => assert.equal('foo', id)); + }); + + it('objectReturnValue', function() { + var json = {'foo': WebElement.buildId('foo')}; + + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return document.body;', + 'args': [] + }). + andReturnSuccess(json). + end(); + + var driver = executor.createDriver(); + var callback; + return driver.executeScript('return document.body;') + .then((obj) => obj['foo'].getId()) + .then((id) => assert.equal(id, 'foo')); + }); + + it('scriptAsFunction', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return (' + function() {} + + ').apply(null, arguments);', + 'args': [] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + return driver.executeScript(function() {}); + }); + + it('simpleArgumentConversion', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return 1;', + 'args': ['abc', 123, true, [123, {'foo': 'bar'}]] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + return driver.executeScript( + 'return 1;', 'abc', 123, true, [123, {'foo': 'bar'}]); + }); + + it('webElementArgumentConversion', function() { + var elementJson = WebElement.buildId('fefifofum'); + + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return 1;', + 'args': [elementJson] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + return driver.executeScript('return 1;', + new WebElement(driver, 'fefifofum')); + }); + + it('webElementPromiseArgumentConversion', function() { + var elementJson = WebElement.buildId('bar'); + + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {'using': 'css selector', 'value': '*[id="foo"]'}). + andReturnSuccess(elementJson). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return 1;', + 'args': [elementJson] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.id('foo')); + return driver.executeScript('return 1;', element); + }); + + it('argumentConversion', function() { + var elementJson = WebElement.buildId('fefifofum'); + + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'return 1;', + 'args': ['abc', 123, true, elementJson, [123, {'foo': 'bar'}]] + }). + andReturnSuccess(null). + end(); + + var driver = executor.createDriver(); + var element = new WebElement(driver, 'fefifofum'); + return driver.executeScript('return 1;', + 'abc', 123, true, element, [123, {'foo': 'bar'}]); + }); + + it('scriptReturnsAnError', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT). + withParameters({ + 'script': 'throw Error(arguments[0]);', + 'args': ['bam'] + }). + andReturnError(ECode.UNKNOWN_ERROR, {'message':'bam'}). + end(); + var driver = executor.createDriver(); + return driver.executeScript('throw Error(arguments[0]);', 'bam'). + then(fail, function(e) { + assertIsInstance(error.WebDriverError, e); + assert.equal('bam', e.message); + }); + }); + + it('failsIfArgumentIsARejectedPromise', function() { + let executor = new FakeExecutor(); + + var arg = promise.rejected(new StubError); + arg.thenCatch(function() {}); // Suppress default handler. + + var driver = executor.createDriver(); + return driver.executeScript(function() {}, arg). + then(fail, assertIsStubError); + }); + }); + + describe('executeAsyncScript', function() { + it('failsIfArgumentIsARejectedPromise', function() { + var arg = promise.rejected(new StubError); + arg.thenCatch(function() {}); // Suppress default handler. + + var driver = new FakeExecutor().createDriver(); + return driver.executeAsyncScript(function() {}, arg). + then(fail, assertIsStubError); + }); + }); + + describe('findElement', function() { + it('elementNotFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.NO_SUCH_ELEMENT, { + 'message':'Unable to find element' + }). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.id('foo')); + element.click(); // This should never execute. + return waitForAbort().then(function(e) { + assertIsInstance(error.NoSuchElementError, e); + assert.equal('Unable to find element', e.message); + }); + }); + + it('elementNotFoundInACallback', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError( + ECode.NO_SUCH_ELEMENT, {'message':'Unable to find element'}). + end(); + + var driver = executor.createDriver(); + promise.fulfilled().then(function() { + var element = driver.findElement(By.id('foo')); + return element.click(); // Should not execute. + }); + return waitForAbort().then(function(e) { + assertIsInstance(error.NoSuchElementError, e); + assert.equal('Unable to find element', e.message); + }); + }); + + it('elementFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess(WebElement.buildId('bar')). + expect(CName.CLICK_ELEMENT, {'id': 'bar'}). + andReturnSuccess(). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.id('foo')); + element.click(); + return waitForIdle(); + }); + + it('canUseElementInCallback', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess(WebElement.buildId('bar')). + expect(CName.CLICK_ELEMENT, {'id': 'bar'}). + andReturnSuccess(). + end(); + + var driver = executor.createDriver(); + driver.findElement(By.id('foo')).then(function(element) { + element.click(); + }); + return waitForIdle(); + }); + + it('byJs', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': 'return document.body', + 'args': [] + }). + andReturnSuccess(WebElement.buildId('bar')). + expect(CName.CLICK_ELEMENT, {'id': 'bar'}). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.js('return document.body')); + element.click(); // just to make sure + return waitForIdle(); + }); + + it('byJs_returnsNonWebElementValue', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, {'script': 'return 123', 'args': []}). + andReturnSuccess(123). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.js('return 123')); + element.click(); // Should not execute. + return waitForAbort().then(function(e) { + assertIsInstance(TypeError, e); + assert.equal('Custom locator did not return a WebElement', e.message); + }); + }); + + it('byJs_canPassArguments', function() { + var script = 'return document.getElementsByTagName(arguments[0]);'; + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': script, + 'args': ['div'] + }). + andReturnSuccess({'ELEMENT':'one'}). + end(); + var driver = executor.createDriver(); + driver.findElement(By.js(script, 'div')); + return waitForIdle(); + }); + + it('customLocator', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, {'using': 'css selector', 'value': 'a'}). + andReturnSuccess([ + WebElement.buildId('foo'), + WebElement.buildId('bar')]). + expect(CName.CLICK_ELEMENT, {'id': 'foo'}). + andReturnSuccess(). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(function(d) { + assert.equal(driver, d); + return d.findElements(By.tagName('a')); + }); + element.click(); + return waitForIdle(); + }); + + it('customLocatorThrowsIfresultIsNotAWebElement', function() { + var driver = new FakeExecutor().createDriver(); + driver.findElement(function() { + return 1; + }); + return waitForAbort().then(function(e) { + assertIsInstance(TypeError, e); + assert.equal('Custom locator did not return a WebElement', e.message); + }); + }); + }); + + describe('isElementPresent', function() { + it('elementNotFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([]). + end(); + + var driver = executor.createDriver(); + return driver.isElementPresent(By.id('foo')) + .then((found) => assert.ok(!found)); + }); + + it('elementFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([WebElement.buildId('bar')]). + end(); + + var driver = executor.createDriver(); + return driver.isElementPresent(By.id('foo')).then(assert.ok); + }); + + it('letsErrorsPropagate', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.UNKNOWN_ERROR, {'message':'There is no spoon'}). + end(); + + var driver = executor.createDriver(); + driver.isElementPresent(By.id('foo')); + return waitForAbort().then(function(e) { + assertIsInstance(error.WebDriverError, e); + assert.equal(e.message, 'There is no spoon'); + }); + }); + + it('byJs', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, {'script': 'return 123', 'args': []}). + andReturnSuccess([WebElement.buildId('bar')]). + end(); + + var driver = executor.createDriver(); + return driver.isElementPresent(By.js('return 123')).then(assert.ok); + }); + + it('byJs_canPassScriptArguments', function() { + var script = 'return document.getElementsByTagName(arguments[0]);'; + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': script, + 'args': ['div'] + }). + andReturnSuccess([WebElement.buildId('one')]). + end(); + + var driver = executor.createDriver(); + driver.isElementPresent(By.js(script, 'div')).then(assert.ok); + return waitForIdle(); + }); + }); + + describe('findElements', function() { + it('returnsMultipleElements', function() { + var ids = ['foo', 'bar', 'baz']; + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, {'using':'css selector', 'value':'a'}). + andReturnSuccess(ids.map(WebElement.buildId)). + end(); + + var driver = executor.createDriver(); + return driver.findElements(By.tagName('a')) + .then(function(elements) { + return promise.all(elements.map(function(e) { + assert.ok(e instanceof WebElement); + return e.getId(); + })); + }) + .then((actual) => assert.deepEqual(ids, actual)); + }); + + it('byJs', function() { + var ids = ['foo', 'bar', 'baz']; + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': 'return document.getElementsByTagName("div");', + 'args': [] + }). + andReturnSuccess(ids.map(WebElement.buildId)). + end(); + + var driver = executor.createDriver(); + + return driver. + findElements(By.js('return document.getElementsByTagName("div");')). + then(function(elements) { + return promise.all(elements.map(function(e) { + assert.ok(e instanceof WebElement); + return e.getId(); + })); + }). + then((actual) => assert.deepEqual(ids, actual)); + }); + + it('byJs_filtersOutNonWebElementResponses', function() { + var ids = ['foo', 'bar', 'baz']; + var json = [ + WebElement.buildId(ids[0]), + 123, + 'a', + false, + WebElement.buildId(ids[1]), + {'not a web element': 1}, + WebElement.buildId(ids[2]) + ]; + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': 'return document.getElementsByTagName("div");', + 'args': [] + }). + andReturnSuccess(json). + end(); + + var driver = executor.createDriver(); + driver.findElements(By.js('return document.getElementsByTagName("div");')). + then(function(elements) { + return promise.all(elements.map(function(e) { + assert.ok(e instanceof WebElement); + return e.getId(); + })); + }). + then((actual) => assert.deepEqual(ids, actual)); + return waitForIdle(); + }); + + it('byJs_convertsSingleWebElementResponseToArray', function() { + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': 'return document.getElementsByTagName("div");', + 'args': [] + }). + andReturnSuccess(WebElement.buildId('foo')). + end(); + + var driver = executor.createDriver(); + return driver. + findElements(By.js('return document.getElementsByTagName("div");')). + then(function(elements) { + return promise.all(elements.map(function(e) { + assert.ok(e instanceof WebElement); + return e.getId(); + })); + }). + then((actual) => assert.deepEqual(['foo'], actual)); + }); + + it('byJs_canPassScriptArguments', function() { + var script = 'return document.getElementsByTagName(arguments[0]);'; + let executor = new FakeExecutor(). + expect(CName.EXECUTE_SCRIPT, { + 'script': script, + 'args': ['div'] + }). + andReturnSuccess([ + WebElement.buildId('one'), + WebElement.buildId('two') + ]). + end(); + + var driver = executor.createDriver(); + return driver.findElements(By.js(script, 'div')) + then(function(elements) { + return promise.all(elements.map(function(e) { + assert.ok(e instanceof WebElement); + return e.getId(); + })); + }). + then((actual) => assert.deepEqual(['one', 'two'], actual)); + }); + }); + + describe('sendKeys', function() { + it('convertsVarArgsIntoStrings_simpleArgs', function() { + let executor = new FakeExecutor(). + expect(CName.SEND_KEYS_TO_ELEMENT, {'id': 'one', + 'value':['1','2','abc','3']}). + andReturnSuccess(). + end(); + + var driver = executor.createDriver(); + var element = new WebElement(driver, 'one'); + element.sendKeys(1, 2, 'abc', 3); + return waitForIdle(); + }); + + it('convertsVarArgsIntoStrings_promisedArgs', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {'using':'css selector', 'value':'*[id="foo"]'}). + andReturnSuccess(WebElement.buildId('one')). + expect(CName.SEND_KEYS_TO_ELEMENT, {'id':'one', + 'value':['abc', '123', 'def']}). + andReturnSuccess(). + end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.id('foo')); + element.sendKeys( + promise.fulfilled('abc'), 123, + promise.fulfilled('def')); + return waitForIdle(); + }); + + it('sendKeysWithAFileDetector', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {'using':'css selector', 'value':'*[id="foo"]'}). + andReturnSuccess(WebElement.buildId('one')). + expect(CName.SEND_KEYS_TO_ELEMENT, {'id': 'one', + 'value':['modified/path']}). + andReturnSuccess(). + end(); + + let driver = executor.createDriver(); + let handleFile = function(d, path) { + assert.strictEqual(driver, d); + assert.equal(path, 'original/path'); + return promise.fulfilled('modified/path'); + }; + driver.setFileDetector({handleFile}); + + var element = driver.findElement(By.id('foo')); + element.sendKeys('original/', 'path'); + return waitForIdle(); + }); + }); + + describe('elementEquality', function() { + it('isReflexive', function() { + var a = new WebElement({}, 'foo'); + return WebElement.equals(a, a).then(assert.ok); + }); + + it('failsIfAnInputElementCouldNotBeFound', function() { + var id = promise.rejected(new StubError); + id.thenCatch(function() {}); // Suppress default handler. + + var driver = new FakeExecutor().createDriver(); + var a = new WebElement(driver, 'foo'); + var b = new WebElementPromise(driver, id); + + return WebElement.equals(a, b).then(fail, assertIsStubError); + }); + }); + + describe('waiting', function() { + it('waitSucceeds', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([]). + times(2). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([WebElement.buildId('bar')]). + end(); + + var driver = executor.createDriver(); + driver.wait(function() { + return driver.isElementPresent(By.id('foo')); + }, 200); + return waitForIdle(); + }); + + it('waitTimesout_timeoutCaught', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([]). + anyTimes(). + end(); + + var driver = executor.createDriver(); + return driver.wait(function() { + return driver.isElementPresent(By.id('foo')); + }, 25).then(fail, function(e) { + assert.equal('Wait timed out after ', + e.message.substring(0, 'Wait timed out after '.length)); + }); + }); + + it('waitTimesout_timeoutNotCaught', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENTS, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnSuccess([]). + anyTimes(). + end(); + + var driver = executor.createDriver(); + driver.wait(function() { + return driver.isElementPresent(By.id('foo')); + }, 25); + return waitForAbort().then(function(e) { + assert.equal('Wait timed out after ', + e.message.substring(0, 'Wait timed out after '.length)); + }); + }); + }); + + describe('alert handling', function() { + it('interceptsAndTransformsUnhandledAlertErrors', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.UNEXPECTED_ALERT_OPEN, { + 'message': 'boom', + 'alert': {'text': 'hello'} + }). + end(); + + var driver = executor.createDriver(); + return driver.findElement(By.id('foo')).then(fail, function(e) { + assertIsInstance(UnhandledAlertError, e); + assert.equal('hello', e.getAlertText()); + }); + }); + + it('usesEmptyStringIfAlertTextOmittedFromResponse', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.UNEXPECTED_ALERT_OPEN, {'message': 'boom'}). + end(); + + var driver = executor.createDriver(); + return driver.findElement(By.id('foo')).then(fail, function(e) { + assertIsInstance(UnhandledAlertError, e); + assert.equal('', e.getAlertText()); + }); + }); + + it('alertResolvesWhenPromisedTextResolves', function() { + var textPromise = new promise.Deferred(); + + var alert = new AlertPromise({}, textPromise); + assert.ok(alert.isPending()); + + textPromise.fulfill(new Alert({}, 'foo')); + return alert.getText().then(function(text) { + assert.equal('foo', text); + }); + }); + + it('cannotSwitchToAlertThatIsNotPresent', function() { + let executor = new FakeExecutor() + .expect(CName.GET_ALERT_TEXT) + .andReturnError(ECode.NO_SUCH_ALERT, {'message': 'no alert'}) + .end(); + + var driver = executor.createDriver(); + var alert = driver.switchTo().alert(); + alert.dismiss(); // Should never execute. + return waitForAbort().then(function(e) { + assertIsInstance(error.NoSuchAlertError, e); + assert.equal('no alert', e.message); + }); + }); + + it('alertsBelongToSameFlowAsParentDriver', function() { + let executor = new FakeExecutor() + .expect(CName.GET_ALERT_TEXT).andReturnSuccess('hello') + .end(); + + var driver = executor.createDriver(); + var otherFlow = new promise.ControlFlow(); + otherFlow.execute(function() { + driver.switchTo().alert().then(function() { + assert.strictEqual( + driver.controlFlow(), promise.controlFlow(), + 'Alert should belong to the same flow as its parent driver'); + }); + }); + + assert.notEqual(otherFlow, driver.controlFlow); + return Promise.all([ + waitForIdle(otherFlow), + waitForIdle(driver.controlFlow()) + ]); + }); + + it('commandsFailIfAlertNotPresent', function() { + let executor = new FakeExecutor() + .expect(CName.GET_ALERT_TEXT) + .andReturnError(ECode.NO_SUCH_ALERT, {'message': 'no alert'}) + .end(); + + var driver = executor.createDriver(); + var alert = driver.switchTo().alert(); + + var expectError = expectedError(error.NoSuchAlertError, 'no alert'); + + return alert.getText() + .then(fail, expectedError) + .then(() => alert.accept()) + .then(fail, expectedError) + .then(() => alert.dismiss()) + .then(fail, expectError) + .then(() => alert.sendKeys('hi')) + .then(fail, expectError); + }); + }); + + it('testWebElementsBelongToSameFlowAsParentDriver', function() { + let executor = new FakeExecutor() + .expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}) + .andReturnSuccess(WebElement.buildId('abc123')) + .end(); + + var driver = executor.createDriver(); + var otherFlow = new promise.ControlFlow(); + otherFlow.execute(function() { + driver.findElement({id: 'foo'}).then(function() { + assert.equal(driver.controlFlow(), promise.controlFlow()); + }); + }); + + assert.notEqual(otherFlow, driver.controlFlow); + return Promise.all([ + waitForIdle(otherFlow), + waitForIdle(driver.controlFlow()) + ]); + }); + + it('testFetchingLogs', function() { + let executor = new FakeExecutor(). + expect(CName.GET_LOG, {'type': 'browser'}). + andReturnSuccess([ + {'level': 'INFO', 'message': 'hello', 'timestamp': 1234}, + {'level': 'DEBUG', 'message': 'abc123', 'timestamp': 5678} + ]). + end(); + + var driver = executor.createDriver(); + return driver.manage().logs().get('browser').then(function(entries) { + assert.equal(2, entries.length); + + assert.ok(entries[0] instanceof logging.Entry); + assert.equal(logging.Level.INFO.value, entries[0].level.value); + assert.equal('hello', entries[0].message); + assert.equal(1234, entries[0].timestamp); + + assert.ok(entries[1] instanceof logging.Entry); + assert.equal(logging.Level.DEBUG.value, entries[1].level.value); + assert.equal('abc123', entries[1].message); + assert.equal(5678, entries[1].timestamp); + }); + }); + + it('testCommandsFailIfInitialSessionCreationFailed', function() { + var session = promise.rejected(new StubError); + + var driver = new FakeExecutor().createDriver(session); + var navigateResult = driver.get('some-url').then(fail, assertIsStubError); + var quitResult = driver.quit().then(fail, assertIsStubError); + + return waitForIdle().then(function() { + return promise.all(navigateResult, quitResult); + }); + }); + + it('testWebElementCommandsFailIfInitialDriverCreationFailed', function() { + var session = Promise.reject(new StubError); + var driver = new FakeExecutor().createDriver(session); + return driver.findElement(By.id('foo')).click(). + then(fail, assertIsStubError); + }); + + it('testWebElementCommansFailIfElementCouldNotBeFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.NO_SUCH_ELEMENT, + {'message':'Unable to find element'}). + end(); + + var driver = executor.createDriver(); + return driver.findElement(By.id('foo')).click() + .then(fail, function(e) { + assertIsInstance(error.NoSuchElementError, e); + assert.equal('Unable to find element', e.message); + }); + }); + + it('testCannotFindChildElementsIfParentCouldNotBeFound', function() { + let executor = new FakeExecutor(). + expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}). + andReturnError(ECode.NO_SUCH_ELEMENT, + {'message':'Unable to find element'}). + end(); + + var driver = executor.createDriver(); + return driver.findElement(By.id('foo')) + .findElement(By.id('bar')) + .findElement(By.id('baz')) + .then(fail, function(e) { + assertIsInstance(error.NoSuchElementError, e); + assert.equal('Unable to find element', e.message); + }); + }); + + describe('actions()', function() { + it('failsIfInitialDriverCreationFailed', function() { + let session = promise.rejected(new StubError); + session.catch(function() {}); + return new FakeExecutor(). + createDriver(session). + actions(). + mouseDown(). + mouseUp(). + perform(). + thenCatch(assertIsStubError); + }); + + describe('mouseMove', function() { + it('noElement', function() { + let executor = new FakeExecutor() + .expect(CName.MOVE_TO, {'xoffset': 0, 'yoffset': 125}) + .andReturnSuccess() + .end(); + + return executor.createDriver(). + actions(). + mouseMove({x: 0, y: 125}). + perform(); + }); + + it('element', function() { + let executor = new FakeExecutor() + .expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="foo"]'}) + .andReturnSuccess(WebElement.buildId('abc123')) + .expect(CName.MOVE_TO, + {'element': 'abc123', 'xoffset': 0, 'yoffset': 125}) + .andReturnSuccess() + .end(); + + var driver = executor.createDriver(); + var element = driver.findElement(By.id('foo')); + return driver.actions() + .mouseMove(element, {x: 0, y: 125}) + .perform(); + }); + }); + + it('supportsMouseDown', function() { + let executor = new FakeExecutor() + .expect(CName.MOUSE_DOWN, {'button': Button.LEFT}) + .andReturnSuccess() + .end(); + + return executor.createDriver(). + actions(). + mouseDown(). + perform(); + }); + + it('testActionSequence', function() { + let executor = new FakeExecutor() + .expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="a"]'}) + .andReturnSuccess(WebElement.buildId('id1')) + .expect(CName.FIND_ELEMENT, + {using: 'css selector', value: '*[id="b"]'}) + .andReturnSuccess(WebElement.buildId('id2')) + .expect(CName.SEND_KEYS_TO_ACTIVE_ELEMENT, + {'value': [Key.SHIFT]}) + .andReturnSuccess() + .expect(CName.MOVE_TO, {'element': 'id1'}) + .andReturnSuccess() + .expect(CName.CLICK, {'button': Button.LEFT}) + .andReturnSuccess() + .expect(CName.MOVE_TO, {'element': 'id2'}) + .andReturnSuccess() + .expect(CName.CLICK, {'button': Button.LEFT}) + .andReturnSuccess() + .end(); + + var driver = executor.createDriver(); + var element1 = driver.findElement(By.id('a')); + var element2 = driver.findElement(By.id('b')); + + return driver.actions() + .keyDown(Key.SHIFT) + .click(element1) + .click(element2) + .perform(); + }); + }); + + describe('touchActions()', function() { + it('failsIfInitialDriverCreationFailed', function() { + let session = promise.rejected(new StubError); + session.catch(function() {}); + return new FakeExecutor(). + createDriver(session). + touchActions(). + scroll({x: 3, y: 4}). + perform(). + thenCatch(assertIsStubError); + }); + + it('testTouchActionSequence', function() { + let executor = new FakeExecutor() + .expect(CName.TOUCH_DOWN, {x: 1, y: 2}).andReturnSuccess() + .expect(CName.TOUCH_MOVE, {x: 3, y: 4}).andReturnSuccess() + .expect(CName.TOUCH_UP, {x: 5, y: 6}).andReturnSuccess() + .end(); + + var driver = executor.createDriver(); + return driver.touchActions() + .tapAndHold({x: 1, y: 2}) + .move({x: 3, y: 4}) + .release({x: 5, y: 6}) + .perform(); + }); + }); + + describe('generator support', function() { + var driver; + + beforeEach(function() { + driver = new WebDriver( + new Session('test-session', {}), + new ExplodingExecutor()); + }); + + it('canUseGeneratorsWithWebDriverCall', function() { + return driver.call(function* () { + var x = yield promise.fulfilled(1); + var y = yield promise.fulfilled(2); + return x + y; + }).then(function(value) { + assert.deepEqual(3, value); + }); + }); + + it('canDefineScopeOnGeneratorCall', function() { + return driver.call(function* () { + var x = yield promise.fulfilled(1); + return this.name + x; + }, {name: 'Bob'}).then(function(value) { + assert.deepEqual('Bob1', value); + }); + }); + + it('canSpecifyArgsOnGeneratorCall', function() { + return driver.call(function* (a, b) { + var x = yield promise.fulfilled(1); + var y = yield promise.fulfilled(2); + return [x + y, a, b]; + }, null, 'abc', 123).then(function(value) { + assert.deepEqual([3, 'abc', 123], value); + }); + }); + + it('canUseGeneratorWithWebDriverWait', function() { + var values = []; + return driver.wait(function* () { + yield values.push(1); + values.push(yield promise.delayed(10).then(function() { + return 2; + })); + yield values.push(3); + return values.length === 6; + }, 250).then(function() { + assert.deepEqual([1, 2, 3, 1, 2, 3], values); + }); + }); + + /** + * @constructor + * @implements {CommandExecutor} + */ + function ExplodingExecutor() {} + + + /** @override */ + ExplodingExecutor.prototype.execute = function(command, cb) { + cb(Error('Unsupported operation')); + }; + }); + + describe('wire format', function() { + describe('can serialize', function() { + function runSerializeTest(input, want) { + let executor = new FakeExecutor(). + expect(CName.NEW_SESSION). + withParameters({'desiredCapabilities': want}). + andReturnSuccess({'browserName': 'firefox'}). + end(); + return WebDriver.createSession(executor, input) + .getSession(); + } + + it('function as a string', function() { + function foo() { return 'foo'; } + return runSerializeTest(foo, '' + foo); + }); + + it('object with toJSON()', function() { + return runSerializeTest( + new Date(605728511546), + '1989-03-12T17:55:11.546Z'); + }); + + it('Session', function() { + return runSerializeTest(new Session('foo', {}), 'foo'); + }); + + it('Capabilities', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG); + + var caps = Capabilities.chrome(); + caps.setLoggingPrefs(prefs); + + return runSerializeTest( + caps, + { + 'browserName': 'chrome', + 'loggingPrefs': {'browser': 'DEBUG'} + }); + }); + + it('WebElement', function() { + return runSerializeTest( + new WebElement({}, 'fefifofum'), + WebElement.buildId('fefifofum')); + }); + + it('WebElementPromise', function() { + return runSerializeTest( + new WebElementPromise( + {}, promise.fulfilled(new WebElement({}, 'fefifofum'))), + WebElement.buildId('fefifofum')); + }); + + describe('an array', function() { + it('with Serializable', function() { + return runSerializeTest([new Session('foo', {})], ['foo']); + }); + + it('with WebElement', function() { + return runSerializeTest( + [new WebElement({}, 'fefifofum')], + [WebElement.buildId('fefifofum')]); + }); + + it('with WebElementPromise', function() { + return runSerializeTest( + [new WebElementPromise( + {}, promise.fulfilled(new WebElement({}, 'fefifofum')))], + [WebElement.buildId('fefifofum')]); + }); + + it('complex array', function() { + var expected = [ + 'abc', 123, true, WebElement.buildId('fefifofum'), + [123, {'foo': 'bar'}] + ]; + + var element = new WebElement({}, 'fefifofum'); + var input = ['abc', 123, true, element, [123, {'foo': 'bar'}]]; + return runSerializeTest(input, expected); + }); + + it('nested promises', function() { + return runSerializeTest( + ['abc', Promise.resolve([123, Promise.resolve(true)])], + ['abc', [123, true]]); + }); + }); + + describe('an object', function() { + it('literal', function() { + var expected = {sessionId: 'foo'}; + return runSerializeTest({sessionId: 'foo'}, expected); + }); + + it('with sub-objects', function() { + var expected = {sessionId: {value: 'foo'}}; + return runSerializeTest( + {sessionId: {value: 'foo'}}, expected); + }); + + it('with values that have toJSON', function() { + return runSerializeTest( + {a: {b: new Date(605728511546)}}, + {a: {b: '1989-03-12T17:55:11.546Z'}}); + }); + + it('with a Session', function() { + return runSerializeTest( + {a: new Session('foo', {})}, + {a: 'foo'}); + }); + + it('nested', function() { + var elementJson = WebElement.buildId('fefifofum'); + var expected = { + 'script': 'return 1', + 'args': ['abc', 123, true, elementJson, [123, {'foo': 'bar'}]], + 'sessionId': 'foo' + }; + + var element = new WebElement({}, 'fefifofum'); + var parameters = { + 'script': 'return 1', + 'args':['abc', 123, true, element, [123, {'foo': 'bar'}]], + 'sessionId': new Session('foo', {}) + }; + + return runSerializeTest(parameters, expected); + }); + }); + }); + + describe('can deserialize', function() { + function runDeserializeTest(original, want) { + let executor = new FakeExecutor() + .expect(CName.GET_CURRENT_URL) + .andReturnSuccess(original) + .end(); + let driver = executor.createDriver(); + return driver.getCurrentUrl().then(function(got) { + assert.deepEqual(got, want); + }); + } + + it('primitives', function() { + return Promise.all([ + runDeserializeTest(1, 1), + runDeserializeTest('', ''), + runDeserializeTest(true, true), + runDeserializeTest(undefined, undefined), + runDeserializeTest(null, null) + ]); + }); + + it('simple object', function() { + return runDeserializeTest( + {sessionId: 'foo'}, + {sessionId: 'foo'}); + }); + + it('nested object', function() { + return runDeserializeTest( + {'foo': {'bar': 123}}, + {'foo': {'bar': 123}}); + }); + + it('array', function() { + return runDeserializeTest( + [{'foo': {'bar': 123}}], + [{'foo': {'bar': 123}}]); + }); + + it('passes through function properties', function() { + function bar() {} + return runDeserializeTest( + [{foo: {'bar': 123}, func: bar}], + [{foo: {'bar': 123}, func: bar}]); + }); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/logging_test.js b/www/node_modules/selenium-webdriver/test/logging_test.js new file mode 100644 index 0000000..fb8cdb2 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/logging_test.js @@ -0,0 +1,167 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var Browser = require('..').Browser, + By = require('..').By, + logging = require('..').logging, + assert = require('../testing/assert'), + test = require('../lib/test'); + +test.suite(function(env) { + // Logging API has numerous issues with PhantomJS: + // - does not support adjusting log levels for type "browser". + // - does not return proper log level for "browser" messages. + // - does not delete logs after retrieval + // Logging API is not supported in IE. + // Tests depend on opening data URLs, which is broken in Safari (issue 7586) + test.ignore(env.browsers(Browser.PHANTOM_JS, Browser.IE, Browser.SAFARI)). + describe('logging', function() { + var driver; + + test.beforeEach(function() { + driver = null; + }); + + test.afterEach(function() { + if (driver) { + driver.quit(); + } + }); + + test.it('can be disabled', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.OFF); + + driver = env.builder() + .setLoggingPrefs(prefs) + .build(); + + driver.get(dataUrl( + '')); + driver.manage().logs().get(logging.Type.BROWSER).then(function(entries) { + assert(entries.length).equalTo(0); + }); + }); + + // Firefox does not capture JS error console log messages. + test.ignore(env.browsers(Browser.FIREFOX)). + it('can be turned down', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.SEVERE); + + driver = env.builder() + .setLoggingPrefs(prefs) + .build(); + + driver.get(dataUrl( + '')); + driver.manage().logs().get(logging.Type.BROWSER).then(function(entries) { + assert(entries.length).equalTo(1); + assert(entries[0].level.name).equalTo('SEVERE'); + assert(entries[0].message).endsWith('and this is an error'); + }); + }); + + // Firefox does not capture JS error console log messages. + test.ignore(env.browsers(Browser.FIREFOX)). + it('can be made verbose', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG); + + driver = env.builder() + .setLoggingPrefs(prefs) + .build(); + + driver.get(dataUrl( + '')); + driver.manage().logs().get(logging.Type.BROWSER).then(function(entries) { + assert(entries.length).equalTo(3); + assert(entries[0].level.name).equalTo('DEBUG'); + assert(entries[0].message).endsWith('hello'); + + assert(entries[1].level.name).equalTo('WARNING'); + assert(entries[1].message).endsWith('this is a warning'); + + assert(entries[2].level.name).equalTo('SEVERE'); + assert(entries[2].message).endsWith('and this is an error'); + }); + }); + + // Firefox does not capture JS error console log messages. + test.ignore(env.browsers(Browser.FIREFOX)). + it('clears records after retrieval', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG); + + driver = env.builder() + .setLoggingPrefs(prefs) + .build(); + + driver.get(dataUrl( + '')); + driver.manage().logs().get(logging.Type.BROWSER).then(function(entries) { + assert(entries.length).equalTo(3); + }); + driver.manage().logs().get(logging.Type.BROWSER).then(function(entries) { + assert(entries.length).equalTo(0); + }); + }); + + test.it('does not mix log types', function() { + var prefs = new logging.Preferences(); + prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG); + prefs.setLevel(logging.Type.DRIVER, logging.Level.SEVERE); + + driver = env.builder() + .setLoggingPrefs(prefs) + .build(); + + driver.get(dataUrl( + '')); + driver.manage().logs().get(logging.Type.DRIVER).then(function(entries) { + assert(entries.length).equalTo(0); + }); + }); + }); + + function dataUrl(var_args) { + return 'data:text/html,' + + Array.prototype.slice.call(arguments, 0).join(''); + } +}); diff --git a/www/node_modules/selenium-webdriver/test/net/portprober_test.js b/www/node_modules/selenium-webdriver/test/net/portprober_test.js new file mode 100644 index 0000000..03a2f7a --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/net/portprober_test.js @@ -0,0 +1,129 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'), + net = require('net'); + +var promise = require('../..').promise, + portprober = require('../../net/portprober'); + +describe('isFree', function() { + + var server; + + beforeEach(function() { + server = net.createServer(function(){}); + }) + + afterEach(function(done) { + if (!server) return done(); + server.close(function() { + done(); + }); + }); + + it('should work for INADDR_ANY', function(done) { + server.listen(0, function() { + var port = server.address().port; + assertPortNotfree(port).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); + + it('should work for a specific host', function(done) { + var host = '127.0.0.1'; + server.listen(0, host, function() { + var port = server.address().port; + assertPortNotfree(port, host).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port, host)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); +}); + +describe('findFreePort', function() { + var server; + + beforeEach(function() { + server = net.createServer(function(){}); + }) + + afterEach(function(done) { + if (!server) return done(); + server.close(function() { + done(); + }); + }); + + it('should work for INADDR_ANY', function(done) { + portprober.findFreePort().then(function(port) { + server.listen(port, function() { + assertPortNotfree(port).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); + }); + + it('should work for a specific host', function(done) { + var host = '127.0.0.1'; + portprober.findFreePort(host).then(function(port) { + server.listen(port, host, function() { + assertPortNotfree(port, host).then(function() { + var done = promise.defer(); + server.close(function() { + server = null; + done.fulfill(assertPortIsFree(port, host)); + }); + return done.promise; + }).then(function() { done(); }, done); + }); + }); + }); +}); + + +function assertPortIsFree(port, opt_host) { + return portprober.isFree(port, opt_host).then(function(free) { + assert.ok(free, 'port should be free'); + }); +} + + +function assertPortNotfree(port, opt_host) { + return portprober.isFree(port, opt_host).then(function(free) { + assert.ok(!free, 'port should is not free'); + }); +} diff --git a/www/node_modules/selenium-webdriver/test/page_loading_test.js b/www/node_modules/selenium-webdriver/test/page_loading_test.js new file mode 100644 index 0000000..d59ca36 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/page_loading_test.js @@ -0,0 +1,164 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var Browser = require('..').Browser, + By = require('..').By, + error = require('../error'), + until = require('..').until, + assert = require('../testing/assert'), + test = require('../lib/test'), + Pages = test.Pages; + + +test.suite(function(env) { + var browsers = env.browsers; + + var driver; + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + test.it('should wait for document to be loaded', function() { + driver.get(Pages.simpleTestPage); + assert(driver.getTitle()).equalTo('Hello WebDriver'); + }); + + test.it('should follow redirects sent in the http response headers', + function() { + driver.get(Pages.redirectPage); + assert(driver.getTitle()).equalTo('We Arrive Here'); + }); + + test.it('should follow meta redirects', function() { + driver.get(Pages.metaRedirectPage); + assert(driver.getTitle()).equalTo('We Arrive Here'); + }); + + test.it('should be able to get a fragment on the current page', function() { + driver.get(Pages.xhtmlTestPage); + driver.get(Pages.xhtmlTestPage + '#text'); + driver.findElement(By.id('id1')); + }); + + test.ignore(browsers(Browser.IPAD, Browser.IPHONE)). + it('should wait for all frames to load in a frameset', function() { + driver.get(Pages.framesetPage); + driver.switchTo().frame(0); + + driver.findElement(By.css('span#pageNumber')).getText().then(function(txt) { + assert(txt.trim()).equalTo('1'); + }); + + driver.switchTo().defaultContent(); + driver.switchTo().frame(1); + driver.findElement(By.css('span#pageNumber')).getText().then(function(txt) { + assert(txt.trim()).equalTo('2'); + }); + }); + + test.ignore(browsers(Browser.SAFARI)). + it('should be able to navigate back in browser history', function() { + driver.get(Pages.formPage); + + driver.findElement(By.id('imageButton')).click(); + driver.wait(until.titleIs('We Arrive Here'), 2500); + + driver.navigate().back(); + driver.wait(until.titleIs('We Leave From Here'), 2500); + }); + + test.ignore(browsers(Browser.SAFARI)). + it('should be able to navigate back in presence of iframes', function() { + driver.get(Pages.xhtmlTestPage); + + driver.findElement(By.name('sameWindow')).click(); + driver.wait(until.titleIs('This page has iframes'), 2500); + + driver.navigate().back(); + driver.wait(until.titleIs('XHTML Test Page'), 2500); + }); + + test.ignore(browsers(Browser.SAFARI)). + it('should be able to navigate forwards in browser history', function() { + driver.get(Pages.formPage); + + driver.findElement(By.id('imageButton')).click(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + + driver.navigate().back(); + driver.wait(until.titleIs('We Leave From Here'), 5000); + + driver.navigate().forward(); + driver.wait(until.titleIs('We Arrive Here'), 5000); + }); + + // PhantomJS 2.0 does not properly reload pages on refresh. + test.ignore(browsers(Browser.PHANTOM_JS)). + it('should be able to refresh a page', function() { + driver.get(Pages.xhtmlTestPage); + + driver.navigate().refresh(); + + assert(driver.getTitle()).equalTo('XHTML Test Page'); + }); + + test.it('should return title of page if set', function() { + driver.get(Pages.xhtmlTestPage); + assert(driver.getTitle()).equalTo('XHTML Test Page'); + + driver.get(Pages.simpleTestPage); + assert(driver.getTitle()).equalTo('Hello WebDriver'); + }); + + // Only implemented in Firefox. + test.ignore(browsers( + Browser.CHROME, + Browser.IE, + Browser.IPAD, + Browser.IPHONE, + Browser.OPERA, + Browser.PHANTOM_JS, + Browser.SAFARI)). + it('should timeout if page load timeout is set', function() { + driver.call(function() { + driver.manage().timeouts().pageLoadTimeout(1); + driver.get(Pages.sleepingPage + '?time=3'). + then(function() { + throw Error('Should have timed out on page load'); + }, function(e) { + if (!(e instanceof error.ScriptTimeoutError) + && !(e instanceof error.TimeoutError)) { + throw Error('Unexpected error response: ' + e); + } + }); + }).then(resetPageLoad, function(err) { + resetPageLoad().thenFinally(function() { + throw err; + }); + }); + + function resetPageLoad() { + return driver.manage().timeouts().pageLoadTimeout(-1); + } + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/phantomjs/execute_phantomjs_test.js b/www/node_modules/selenium-webdriver/test/phantomjs/execute_phantomjs_test.js new file mode 100644 index 0000000..22a9a22 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/phantomjs/execute_phantomjs_test.js @@ -0,0 +1,73 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'); +var path = require('path'); +var test = require('../../lib/test'); + +test.suite(function(env) { + var driver; + + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + driver.quit(); + }); + + var testPageUrl = + 'data:text/html,

    ' + path.basename(__filename) + '

    '; + + test.beforeEach(function() { + driver.get(testPageUrl); + }); + + describe('phantomjs.Driver', function() { + describe('#executePhantomJS()', function() { + + test.it('can execute scripts using PhantomJS API', function() { + return driver.executePhantomJS('return this.url;').then(function(url) { + assert.equal(testPageUrl, decodeURIComponent(url)); + }); + }); + + test.it('can execute scripts as functions', function() { + driver.executePhantomJS(function(a, b) { + return a + b; + }, 1, 2).then(function(result) { + assert.equal(3, result); + }); + }); + + test.it('can manipulate the current page', function() { + driver.manage().addCookie('foo', 'bar'); + driver.manage().getCookie('foo').then(function(cookie) { + assert.equal('bar', cookie.value); + }); + driver.executePhantomJS(function() { + this.clearCookies(); + }); + driver.manage().getCookie('foo').then(function(cookie) { + assert.equal(null, cookie); + }); + }); + }); + }); +}, {browsers: ['phantomjs']}); diff --git a/www/node_modules/selenium-webdriver/test/proxy_test.js b/www/node_modules/selenium-webdriver/test/proxy_test.js new file mode 100644 index 0000000..b7a894f --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/proxy_test.js @@ -0,0 +1,170 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var http = require('http'), + url = require('url'); + +var Browser = require('..').Browser, + promise = require('..').promise, + proxy = require('../proxy'), + assert = require('../testing/assert'), + test = require('../lib/test'), + Server = require('../lib/test/httpserver').Server, + Pages = test.Pages; + + +test.suite(function(env) { + function writeResponse(res, body, encoding, contentType) { + res.writeHead(200, { + 'Content-Length': Buffer.byteLength(body, encoding), + 'Content-Type': contentType + }); + res.end(body); + } + + function writePacFile(res) { + writeResponse(res, [ + 'function FindProxyForURL(url, host) {', + ' if (shExpMatch(url, "' + goodbyeServer.url('*') + '")) {', + ' return "DIRECT";', + ' }', + ' return "PROXY ' + proxyServer.host() + '";', + '}' + ].join('\n'), 'ascii', 'application/x-javascript-config'); + } + + var proxyServer = new Server(function(req, res) { + var pathname = url.parse(req.url).pathname; + if (pathname === '/proxy.pac') { + return writePacFile(res); + } + + writeResponse(res, [ + '', + 'Proxy page', + '

    This is the proxy landing page

    ' + ].join(''), 'utf8', 'text/html; charset=UTF-8'); + }); + + var helloServer = new Server(function(req, res) { + writeResponse(res, [ + '', + 'Hello', + '

    Hello, world!

    ' + ].join(''), 'utf8', 'text/html; charset=UTF-8'); + }); + + var goodbyeServer = new Server(function(req, res) { + writeResponse(res, [ + '', + 'Goodbye', + '

    Goodbye, world!

    ' + ].join(''), 'utf8', 'text/html; charset=UTF-8'); + }); + + // Cannot pass start directly to mocha's before, as mocha will interpret the optional + // port parameter as an async callback parameter. + function mkStartFunc(server) { + return function() { + return server.start(); + }; + } + + + test.before(mkStartFunc(proxyServer)); + test.before(mkStartFunc(helloServer)); + test.before(mkStartFunc(goodbyeServer)); + + test.after(proxyServer.stop.bind(proxyServer)); + test.after(helloServer.stop.bind(helloServer)); + test.after(goodbyeServer.stop.bind(goodbyeServer)); + + var driver; + test.beforeEach(function() { driver = null; }); + test.afterEach(function() { driver && driver.quit(); }); + + // Proxy support not implemented. + test.ignore(env.browsers(Browser.IE, Browser.OPERA, Browser.SAFARI)). + describe('manual proxy settings', function() { + // phantomjs 1.9.1 in webdriver mode does not appear to respect proxy + // settings. + test.ignore(env.browsers(Browser.PHANTOM_JS)). + it('can configure HTTP proxy host', function() { + driver = env.builder(). + setProxy(proxy.manual({ + http: proxyServer.host() + })). + build(); + + driver.get(helloServer.url()); + assert(driver.getTitle()).equalTo('Proxy page'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('This is the proxy landing page'); + }); + + // PhantomJS does not support bypassing the proxy for individual hosts. + test.ignore(env.browsers(Browser.PHANTOM_JS)). + it('can bypass proxy for specific hosts', function() { + driver = env.builder(). + setProxy(proxy.manual({ + http: proxyServer.host(), + bypass: helloServer.host() + })). + build(); + + driver.get(helloServer.url()); + assert(driver.getTitle()).equalTo('Hello'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('Hello, world!'); + + driver.get(goodbyeServer.url()); + assert(driver.getTitle()).equalTo('Proxy page'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('This is the proxy landing page'); + }); + + // TODO: test ftp and https proxies. + }); + + // PhantomJS does not support PAC file proxy configuration. + // Safari does not support proxies. + test.ignore(env.browsers( + Browser.IE, Browser.OPERA, Browser.PHANTOM_JS, Browser.SAFARI)). + describe('pac proxy settings', function() { + test.it('can configure proxy through PAC file', function() { + driver = env.builder(). + setProxy(proxy.pac(proxyServer.url('/proxy.pac'))). + build(); + + driver.get(helloServer.url()); + assert(driver.getTitle()).equalTo('Proxy page'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('This is the proxy landing page'); + + driver.get(goodbyeServer.url()); + assert(driver.getTitle()).equalTo('Goodbye'); + assert(driver.findElement({tagName: 'h3'}).getText()). + equalTo('Goodbye, world!'); + }); + }); + + // TODO: figure out how to test direct and system proxy settings. + describe.skip('direct proxy settings', function() {}); + describe.skip('system proxy settings', function() {}); +}); diff --git a/www/node_modules/selenium-webdriver/test/remote_test.js b/www/node_modules/selenium-webdriver/test/remote_test.js new file mode 100644 index 0000000..c103d81 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/remote_test.js @@ -0,0 +1,72 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +var assert = require('assert'); + +var promise = require('../').promise; +var remote = require('../remote'); + +describe('DriverService', function() { + describe('start()', function() { + var service; + + beforeEach(function() { + service = new remote.DriverService(process.execPath, { + port: 1234, + args: ['-e', 'process.exit(1)'] + }); + }); + + afterEach(function(done) { + service.kill().thenFinally(function() { + done(); + }); + }); + + it('fails if child-process dies', function(done) { + this.timeout(1000); + service.start(500) + .then(expectFailure.bind(null, done), verifyFailure.bind(null, done)); + }); + + it('failures propagate through control flow if child-process dies', + function(done) { + this.timeout(1000); + + promise.controlFlow().execute(function() { + promise.controlFlow().execute(function() { + return service.start(500); + }); + }) + .then(expectFailure.bind(null, done), verifyFailure.bind(null, done)); + }); + + function verifyFailure(done, e) { + try { + assert.ok(!(e instanceof promise.CancellationError)); + assert.equal('Server terminated early with status 1', e.message); + done(); + } catch (ex) { + done(ex); + } + } + + function expectFailure(done) { + done(Error('expected to fail')); + } + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/stale_element_test.js b/www/node_modules/selenium-webdriver/test/stale_element_test.js new file mode 100644 index 0000000..72833d8 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/stale_element_test.js @@ -0,0 +1,58 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fail = require('assert').fail; + +var Browser = require('..').Browser, + By = require('..').By, + error = require('..').error, + until = require('..').until, + assert = require('../testing/assert'), + test = require('../lib/test'), + Pages = test.Pages; + + +test.suite(function(env) { + var driver; + test.before(function() { driver = env.builder().build(); }); + test.after(function() { driver.quit(); }); + + test.it( + 'dynamically removing elements from the DOM trigger a ' + + 'StaleElementReferenceError', + function() { + driver.get(Pages.javascriptPage); + + var toBeDeleted = driver.findElement(By.id('deleted')); + assert(toBeDeleted.isDisplayed()).isTrue(); + + driver.findElement(By.id('delete')).click(); + driver.wait(until.stalenessOf(toBeDeleted), 5000); + }); + + test.it('an element found in a different frame is stale', function() { + driver.get(Pages.missedJsReferencePage); + driver.switchTo().frame('inner'); + var el = driver.findElement(By.id('oneline')); + driver.switchTo().defaultContent(); + el.getText().then(fail, function(e) { + assert(e).instanceOf(error.StaleElementReferenceError); + }); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/tag_name_test.js b/www/node_modules/selenium-webdriver/test/tag_name_test.js new file mode 100644 index 0000000..d5e18a9 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/tag_name_test.js @@ -0,0 +1,34 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var By = require('..').By, + assert = require('../testing/assert'), + test = require('../lib/test'); + + +test.suite(function(env) { + var driver; + test.after(function() { driver.quit(); }); + + test.it('should return lower case tag name', function() { + driver = env.builder().build(); + driver.get(test.Pages.formPage); + assert(driver.findElement(By.id('cheese')).getTagName()).equalTo('input'); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/testing/assert_test.js b/www/node_modules/selenium-webdriver/test/testing/assert_test.js new file mode 100644 index 0000000..8c88482 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/testing/assert_test.js @@ -0,0 +1,374 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +const assert = require('../../testing/assert'); + +const AssertionError = require('assert').AssertionError; +const assertTrue = require('assert').ok; +const assertEqual = require('assert').equal; +const assertThrows = require('assert').throws; +const fail = require('assert').fail; + + +describe('assert', function() { + describe('atLeast', function() { + it('compares subject >= value', function() { + assert(1).atLeast(0); + assert(1).atLeast(1); + assertThrows(() => assert(1).atLeast(2)); + }); + + it('accepts failure message', function() { + assertThrows( + () => assert(1).atLeast(2, 'hi there!'), + (error) => error.message.indexOf('hi there') != -1); + }); + + it('fails if given a non-numeric subject', function() { + assertThrows(() => assert('a').atLeast(1)); + }); + + it('fails if given a non-numeric bound', function() { + assertThrows(() => assert(1).atLeast('a')); + }); + + it('waits for promised subject', function() { + return assert(Promise.resolve(123)).atLeast(100); + }); + + it('waits for promised subject (with failure)', function() { + return assert(Promise.resolve(100)) + .atLeast(123) + .then(() => fail('should have failed'), function(e) { + assertInstanceOf(AssertionError, e); + assertEqual('100 >= 123', e.message); + }); + }); + }); + + describe('atMost', function() { + it('compares subject <= value', function() { + assertThrows(() => assert(1).atMost(0)); + assert(1).atMost(1); + assert(1).atMost(2); + }); + + it('accepts failure message', function() { + assertThrows( + () => assert(1).atMost(0, 'hi there!'), + (error) => error.message.indexOf('hi there!') != -1); + }); + + it('fails if given a non-numeric subject', function() { + assertThrows(() => assert(1).atMost('a')); + }); + + it('fails if given a non-numeric bound', function() { + assertThrows(() => assert('a').atMost(1)); + }); + + it('waits for promised subject', function() { + return assert(Promise.resolve(100)).atMost(123); + }); + + it('waits for promised subject (with failure)', function() { + return assert(Promise.resolve(123)) + .atMost(100) + .then(() => fail('should have failed'), function(e) { + assertInstanceOf(AssertionError, e); + assertEqual('123 <= 100', e.message); + }); + }); + }); + + describe('greaterThan', function() { + it('compares subject > value', function() { + assertThrows(() => assert(1).greaterThan(1)); + assertThrows(() => assert(1).greaterThan(2)); + assert(2).greaterThan(1); + }); + + it('accepts failure message', function() { + assertThrows( + () => assert(0).greaterThan(1, 'hi there!'), + (error) => error.message.indexOf('hi there!') != -1); + }); + + it('fails if given a non-numeric subject', function() { + assertThrows(() => assert('a').atMost(1)); + }); + + it('fails if given a non-numeric bound', function() { + assertThrows(() => assert(1).atMost('a')); + }); + + it('waits for promised subject', function() { + return assert(Promise.resolve(123)).greaterThan(100); + }); + + it('waits for promised subject (with failure)', function() { + return assert(Promise.resolve(100)) + .greaterThan(123) + .then(() => fail('should have failed'), function(e) { + assertInstanceOf(AssertionError, e); + assertEqual('100 > 123', e.message); + }); + }); + }); + + describe('lessThan', function() { + it('compares subject < value', function() { + assertThrows(() => assert(1).lessThan(0)); + assertThrows(() => assert(1).lessThan(1)); + assert(1).lessThan(2); + }); + + it('accepts failure message', function() { + assertThrows( + () => assert(1).lessThan(0, 'hi there!'), + (error) => error.message.indexOf('hi there!') != -1); + }); + + it('fails if given a non-numeric subject', function() { + assertThrows(() => assert('a').lessThan(1)); + }); + + it('fails if given a non-numeric bound', function() { + assertThrows(() => assert(1).lessThan('a')); + }); + + it('waits for promised subject', function() { + return assert(Promise.resolve(100)).lessThan(123); + }); + + it('waits for promised subject (with failure)', function() { + return assert(Promise.resolve(123)) + .lessThan(100) + .then(() => fail('should have failed'), function(e) { + assertInstanceOf(AssertionError, e); + assertEqual('123 < 100', e.message); + }); + }); + }); + + describe('closeTo', function() { + it('accepts values within epislon of target', function() { + assert(123).closeTo(123, 0); + assert(123).closeTo(124, 1); + assert(125).closeTo(124, 1); + + assertThrows(() => assert(123).closeTo(125, .1)); + assertThrows(() => assert(1./3).closeTo(.8, .01)); + }); + + it('waits for promised values', function() { + let d = Promise.defer(); + setTimeout(() => d.resolve(123), 10); + return assert(d.promise).closeTo(124, 1); + }); + }); + + describe('instanceOf', function() { + it('works with direct instances', function() { + assert(Error('foo')).instanceOf(Error); + }); + + it('works with sub-types', function() { + assert(TypeError('foo')).instanceOf(Error); + }); + + it('parent types are not instances of sub-types', function() { + assertThrows(() => assert(Error('foo')).instanceOf(TypeError)); + }); + }); + + describe('isNull', function() { + it('normal case', function() { + assert(null).isNull(); + assertThrows(() => assert(1).isNull()); + }); + + it('handles promised values', function() { + let p = new Promise(function(f) { + setTimeout(() => f(null), 10); + }); + return assert(p).isNull(); + }); + + it('does not match on undefined', function() { + assertThrows(() => assert(void(0)).isNull()); + }) + }); + + describe('isUndefined', function() { + it('normal case', function() { + assert(void(0)).isUndefined(); + assertThrows(() => assert(1).isUndefined()); + }); + + it('handles promised values', function() { + let p = new Promise(function(f) { + setTimeout(() => f(void(0)), 10); + }); + return assert(p).isUndefined(); + }); + + it('does not match on null', function() { + assertThrows(() => assert(null).isUndefined()); + }) + }); + + describe('contains', function() { + it('works with strings', function() { + assert('abc').contains('a'); + assert('abc').contains('ab'); + assert('abc').contains('abc'); + assert('abc').contains('bc'); + assert('abc').contains('c'); + assertThrows(() => assert('abc').contains('d')); + }); + + it('works with arrays', function() { + assert([1, 2, 3]).contains(1); + assert([1, 2, 3]).contains(2); + assert([1, 2, 3]).contains(3); + assertThrows(() => assert([1, 2]).contains(3)); + }); + + it('works with maps', function() { + let m = new Map; + m.set(1, 2); + assert(m).contains(1); + assertThrows(() => assert(m).contains(2)); + }); + + it('works with sets', function() { + let s = new Set; + s.add(1); + assert(s).contains(1); + assertThrows(() => assert(s).contains(2)); + }); + + it('requires an array, string, map, or set subject', function() { + assertThrows(() => assert(123).contains('a')); + }); + }); + + describe('endsWith', function() { + it('works', function() { + assert('abc').endsWith('abc'); + assert('abc').endsWith('bc'); + assert('abc').endsWith('c'); + assertThrows(() => assert('abc').endsWith('d')); + }) + }); + + describe('startsWith', function() { + it('works', function() { + assert('abc').startsWith('abc'); + assert('abc').startsWith('ab'); + assert('abc').startsWith('a'); + assertThrows(() => assert('abc').startsWith('d')); + }) + }); + + describe('matches', function() { + it('requires a regex value', function() { + assertThrows(() => assert('abc').matches(1234)); + }); + + it('requires a string value', function() { + assertThrows(() => assert(1234).matches(/abc/)); + }); + + it('requires a string value (promise case)', function() { + return assert(Promise.resolve(1234)) + .matches(/abc/) + .then(fail, function(error) { + assertEqual( + 'Expected a string matching /abc/, got <1234> (number)', + error.message); + }); + }); + + it('applies regex', function() { + assert('abc').matches(/abc/); + assertThrows(() => assert('def').matches(/abc/)); + }); + }); + + describe('isTrue', function() { + it('only accepts booleans', function() { + assertThrows(() => assert(123).isTrue()); + }); + + it('accepts true values', function() { + assert(true).isTrue(); + assert(Boolean('abc')).isTrue(); + return assert(Promise.resolve(true)).isTrue(); + }); + + it('rejects false values', function() { + assertThrows(() => assert(false).isTrue()); + assertThrows(() => assert(Boolean(0)).isTrue()); + return assert(Promise.resolve(false)).isTrue() + .then(fail, function() {/*no-op, ok*/}); + }); + }); + + describe('isFalse', function() { + it('only accepts booleans', function() { + assertThrows(() => assert(123).isFalse()); + }) + + it('accepts false values', function() { + assert(false).isFalse(); + assert(Boolean('')).isFalse(); + return assert(Promise.resolve(false)).isFalse(); + }); + + it('rejects true values', function() { + assertThrows(() => assert(true).isFalse()); + assertThrows(() => assert(Boolean(1)).isFalse()); + return assert(Promise.resolve(true)).isFalse() + .then(fail, function() {/*no-op, ok*/}); + }); + }); + + describe('isEqualTo', function() { + it('is strict equality', function() { + assert('abc').isEqualTo('abc'); + assert('abc').equals('abc'); + assert('abc').equalTo('abc'); + assertThrows(() => assert('1').isEqualTo(1)); + }); + }); + + describe('notEqualTo', function() { + it('tests strict equality', function() { + assert('1').notEqualTo(1); + assert(1).notEqualTo('1'); + assertThrows(() => assert('abc').notEqualTo('abc')); + }); + }); + + function assertInstanceOf(ctor, value) { + assertTrue(value instanceof ctor); + } +}); diff --git a/www/node_modules/selenium-webdriver/test/testing/index_test.js b/www/node_modules/selenium-webdriver/test/testing/index_test.js new file mode 100644 index 0000000..31acff2 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/testing/index_test.js @@ -0,0 +1,178 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var assert = require('assert'); +var promise = require('../..').promise; + +var test = require('../../testing'); + +describe('Mocha Integration', function() { + + describe('beforeEach properly binds "this"', function() { + beforeEach(function() { this.x = 1; }); + test.beforeEach(function() { this.x = 2; }); + it('', function() { assert.equal(this.x, 2); }); + }); + + describe('afterEach properly binds "this"', function() { + it('', function() { this.x = 1; }); + test.afterEach(function() { this.x = 2; }); + afterEach(function() { assert.equal(this.x, 2); }); + }); + + describe('it properly binds "this"', function() { + beforeEach(function() { this.x = 1; }); + test.it('', function() { this.x = 2; }); + afterEach(function() { assert.equal(this.x, 2); }); + }); + + describe('timeout handling', function() { + describe('it does not reset the control flow on a non-timeout', function() { + var flowReset = false; + + beforeEach(function() { + flowReset = false; + test.controlFlow().once(promise.ControlFlow.EventType.RESET, onreset); + }); + + test.it('', function() { + this.timeout(100); + return promise.delayed(50); + }); + + afterEach(function() { + assert.ok(!flowReset); + test.controlFlow().removeListener( + promise.ControlFlow.EventType.RESET, onreset); + }); + + function onreset() { + flowReset = true; + } + }); + + describe('it resets the control flow after a timeout' ,function() { + var timeoutErr, flowReset; + + beforeEach(function() { + flowReset = false; + test.controlFlow().once(promise.ControlFlow.EventType.RESET, onreset); + }); + + test.it('', function() { + var callback = this.runnable().callback; + var test = this; + this.runnable().callback = function(err) { + timeoutErr = err; + // Reset our timeout to 0 so Mocha does not fail the test. + test.timeout(0); + // When we invoke the real callback, do not pass along the error so + // Mocha does not fail the test. + return callback.call(this); + }; + + test.timeout(50); + return promise.defer().promise; + }); + + afterEach(function() { + return Promise.resolve().then(function() { + test.controlFlow().removeListener( + promise.ControlFlow.EventType.RESET, onreset); + assert.ok(flowReset, 'control flow was not reset after a timeout'); + }); + }); + + function onreset() { + flowReset = true; + } + }); + }); +}); + +describe('Mocha async "done" support', function() { + this.timeout(2*1000); + + var waited = false; + var DELAY = 100; // ms enough to notice + + // Each test asynchronously sets waited to true, so clear/check waited + // before/after: + beforeEach(function() { + waited = false; + }); + + afterEach(function() { + assert.strictEqual(waited, true); + }); + + // --- First, vanilla mocha "it" should support the "done" callback correctly. + + // This 'it' should block until 'done' is invoked + it('vanilla delayed', function(done) { + setTimeout(function delayedVanillaTimeout() { + waited = true; + done(); + }, DELAY); + }); + + // --- Now with the webdriver wrappers for 'it' should support the "done" callback: + + test.it('delayed', function(done) { + assert(done); + assert.strictEqual(typeof done, 'function'); + setTimeout(function delayedTimeoutCallback() { + waited = true; + done(); + }, DELAY); + }); + + // --- And test that the webdriver wrapper for 'it' works with a returned promise, too: + + test.it('delayed by promise', function() { + var defer = promise.defer(); + setTimeout(function delayedPromiseCallback() { + waited = true; + defer.fulfill('ignored'); + }); + return defer.promise; + }); + +}); + +describe('ControlFlow and "done" work together', function() { + var flow, order; + before(function() { + order = []; + flow = test.controlFlow(); + flow.execute(function() { order.push(1); }); + }); + + test.it('control flow updates and async done', function(done) { + flow.execute(function() { order.push(2); }); + flow.execute(function() { order.push(3); }).then(function() { + order.push(4); + }); + done(); + }) + + after(function() { + assert.deepEqual([1, 2, 3, 4], order); + }) +}); diff --git a/www/node_modules/selenium-webdriver/test/upload_test.js b/www/node_modules/selenium-webdriver/test/upload_test.js new file mode 100644 index 0000000..f7fd907 --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/upload_test.js @@ -0,0 +1,85 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var fs = require('fs'); + +var Browser = require('..').Browser, + By = require('..').By, + until = require('..').until, + io = require('../io'), + remote = require('../remote'), + assert = require('../testing/assert'), + test = require('../lib/test'), + Pages = test.Pages; + +test.suite(function(env) { + var LOREM_IPSUM_TEXT = 'lorem ipsum dolor sit amet'; + var FILE_HTML = '
    ' + LOREM_IPSUM_TEXT + '
    '; + + var fp; + test.before(function() { + return fp = io.tmpFile().then(function(fp) { + fs.writeFileSync(fp, FILE_HTML); + return fp; + }); + }) + + var driver; + test.before(function() { + driver = env.builder().build(); + }); + + test.after(function() { + if (driver) { + driver.quit(); + } + }); + + test.ignore(env.browsers( + Browser.IPAD, + Browser.IPHONE, + // Uploads broken in PhantomJS 2.0. + // See https://github.com/ariya/phantomjs/issues/12506 + Browser.PHANTOM_JS, + Browser.SAFARI)). + it('can upload files', function() { + driver.setFileDetector(new remote.FileDetector); + + driver.get(Pages.uploadPage); + + var fp = driver.call(function() { + return io.tmpFile().then(function(fp) { + fs.writeFileSync(fp, FILE_HTML); + return fp; + }); + }); + + driver.findElement(By.id('upload')).sendKeys(fp); + driver.findElement(By.id('go')).submit(); + + // Uploading files across a network may take a while, even if they're small. + var label = driver.findElement(By.id('upload_label')); + driver.wait(until.elementIsNotVisible(label), + 10 * 1000, 'File took longer than 10 seconds to upload!'); + + driver.switchTo().frame('upload_target'); + assert(driver.findElement(By.css('body')).getText()) + .equalTo(LOREM_IPSUM_TEXT); + }); +}); diff --git a/www/node_modules/selenium-webdriver/test/window_test.js b/www/node_modules/selenium-webdriver/test/window_test.js new file mode 100644 index 0000000..959c9dc --- /dev/null +++ b/www/node_modules/selenium-webdriver/test/window_test.js @@ -0,0 +1,128 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict'; + +var Browser = require('..').Browser, + assert = require('../testing/assert'), + test = require('../lib/test'); + + +test.suite(function(env) { + var driver; + + test.before(function() { driver = env.builder().build(); }); + test.after(function() { driver.quit(); }); + + test.beforeEach(function() { + driver.switchTo().defaultContent(); + }); + + test.it('can set size of the current window', function() { + changeSizeBy(-20, -20); + }); + + test.it('can set size of the current window from frame', function() { + driver.get(test.Pages.framesetPage); + driver.switchTo().frame('fourth'); + changeSizeBy(-20, -20); + }); + + test.it('can set size of the current window from iframe', function() { + driver.get(test.Pages.iframePage); + driver.switchTo().frame('iframe1-name'); + changeSizeBy(-20, -20); + }); + + test.it('can set the window position of the current window', function() { + driver.manage().window().getPosition().then(function(position) { + driver.manage().window().setSize(640, 480); + driver.manage().window().setPosition(position.x + 10, position.y + 10); + + // For phantomjs, setPosition is a no-op and the "window" stays at (0, 0) + if (env.currentBrowser() === Browser.PHANTOM_JS) { + driver.manage().window().getPosition().then(function(position) { + assert(position.x).equalTo(0); + assert(position.y).equalTo(0); + }); + } else { + var dx = position.x + 10; + var dy = position.y + 10; + // On OSX, Safari position's the window relative to below the menubar + // at the top of the screen, which is 23 pixels tall. + if (env.currentBrowser() === Browser.SAFARI && + process.platform === 'darwin') { + dy += 23; + } + } + }); + }); + + test.it('can set the window position from a frame', function() { + driver.get(test.Pages.iframePage); + driver.switchTo().frame('iframe1-name'); + driver.manage().window().getPosition().then(function(position) { + driver.manage().window().setSize(640, 480); + driver.manage().window().setPosition(position.x + 10, position.y + 10); + + // For phantomjs, setPosition is a no-op and the "window" stays at (0, 0) + if (env.currentBrowser() === Browser.PHANTOM_JS) { + driver.manage().window().getPosition().then(function(position) { + assert(position.x).equalTo(0); + assert(position.y).equalTo(0); + }); + } else { + var dx = position.x + 10; + var dy = position.y + 10; + // On OSX, Safari position's the window relative to below the menubar + // at the top of the screen, which is 23 pixels tall. + if (env.currentBrowser() === Browser.SAFARI && + process.platform === 'darwin') { + dy += 23; + } + driver.wait(forPositionToBe(dx, dy), 1000); + } + }); + }); + + function changeSizeBy(dx, dy) { + driver.manage().window().getSize().then(function(size) { + driver.manage().window().setSize(size.width + dx, size.height + dy); + driver.wait(forSizeToBe(size.width + dx, size.height + dy), 1000); + }); + } + + function forSizeToBe(w, h) { + return function() { + return driver.manage().window().getSize().then(function(size) { + return size.width === w && size.height === h; + }); + }; + } + + function forPositionToBe(x, y) { + return function() { + return driver.manage().window().getPosition().then(function(position) { + return position.x === x && + // On OSX, the window height may be bumped down 22px for the top + // status bar. + // On Linux, Opera's window position will be off by 28px. + (position.y >= y && position.y <= (y + 28)); + }); + }; + } +}); diff --git a/www/node_modules/selenium-webdriver/testing/assert.js b/www/node_modules/selenium-webdriver/testing/assert.js new file mode 100644 index 0000000..0d8eb62 --- /dev/null +++ b/www/node_modules/selenium-webdriver/testing/assert.js @@ -0,0 +1,378 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Defines a library that simplifies writing assertions against + * promised values. + * + * >
    + * > __NOTE:__ This module is considered experimental and is subject to + * > change, or removal, at any time! + * >
    + * + * Sample usage: + * + * var driver = new webdriver.Builder().build(); + * driver.get('http://www.google.com'); + * + * assert(driver.getTitle()).equalTo('Google'); + */ + +'use strict'; + +const assert = require('assert'); + +function trueType(v) { + if (v === null) { + return 'null'; + } + + let type = typeof v; + if (type === 'object') { + if (Array.isArray(v)) { + type = 'array'; + } + } + return type; +} + + +function checkType(v, want) { + let got = trueType(v); + if (got !== want) { + throw new TypeError('require ' + want + ', but got ' + got); + } + return v; +} + +const checkNumber = v => checkType(v, 'number'); +const checkFunction = v => checkType(v, 'function'); +const checkString = v => checkType(v, 'string'); + +const isFunction = v => trueType(v) === 'function'; +const isNumber = v => trueType(v) === 'number'; +const isObject = v => trueType(v) === 'object'; +const isString = v => trueType(v) === 'string'; + + +function describe(value) { + let ret; + try { + ret = `<${String(value)}>`; + } catch (e) { + ret = ``; + } + + if (null !== value && void(0) !== value) { + ret += ` (${trueType(value)})`; + } + + return ret; +} + + +function evaluate(value, predicate) { + if (isObject(value) && isFunction(value.then)) { + return value.then(predicate); + } + predicate(value); +} + + +/** + * @private + */ +class Assertion { + /** + * @param {?} subject The subject of this assertion. + * @param {boolean=} opt_invert Whether to invert any assertions performed by + * this instance. + */ + constructor(subject, opt_invert) { + /** @private {?} */ + this.subject_ = subject; + /** @private {boolean} */ + this.invert_ = !!opt_invert; + } + + /** + * @param {number} expected The minimum permissible value (inclusive). + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + atLeast(expected, opt_message) { + checkNumber(expected); + return evaluate(this.subject_, function(actual) { + if (!isNumber(actual) || actual < expected) { + assert.fail(actual, expected, opt_message, '>='); + } + }); + } + + /** + * @param {number} expected The maximum permissible value (inclusive). + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + atMost(expected, opt_message) { + checkNumber(expected); + return evaluate(this.subject_, function (actual) { + if (!isNumber(actual) || actual > expected) { + assert.fail(actual, expected, opt_message, '<='); + } + }); + } + + /** + * @param {number} expected The maximum permissible value (exclusive). + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + greaterThan(expected, opt_message) { + checkNumber(expected); + return evaluate(this.subject_, function(actual) { + if (!isNumber(actual) || actual <= expected) { + assert.fail(actual, expected, opt_message, '>'); + } + }); + } + + /** + * @param {number} expected The minimum permissible value (exclusive). + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + lessThan(expected, opt_message) { + checkNumber(expected); + return evaluate(this.subject_, function (actual) { + if (!isNumber(actual) || actual >= expected) { + assert.fail(actual, expected, opt_message, '<'); + } + }); + } + + /** + * @param {number} expected The desired value. + * @param {number} epsilon The maximum distance from the desired value. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + closeTo(expected, episolon, opt_message) { + checkNumber(expected); + checkNumber(episolon); + return evaluate(this.subject_, function(actual) { + checkNumber(actual); + if (Math.abs(expected - actual) > episolon) { + assert.fail(opt_message || `${actual} === ${expected} (± ${episolon})`); + } + }); + } + + /** + * @param {function(new: ?)} ctor The exptected type's constructor. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + instanceOf(ctor, opt_message) { + checkFunction(ctor); + return evaluate(this.subject_, function(actual) { + if (!(actual instanceof ctor)) { + assert.fail( + opt_message + || `${describe(actual)} instanceof ${ctor.name || ctor}`); + } + }); + } + + /** + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + isNull(opt_message) { + return this.isEqualTo(null); + } + + /** + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + isUndefined(opt_message) { + return this.isEqualTo(void(0)); + } + + /** + * Ensures the subject of this assertion is either a string or array + * containing the given `value`. + * + * @param {?} value The value expected to be contained within the subject. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + contains(value, opt_message) { + return evaluate(this.subject_, function(actual) { + if (actual instanceof Map || actual instanceof Set) { + assert.ok(actual.has(value), opt_message || `${actual}.has(${value})`); + } else if (Array.isArray(actual) || isString(actual)) { + assert.ok( + actual.indexOf(value) !== -1, + opt_message || `${actual}.indexOf(${value}) !== -1`); + } else { + assert.fail( + `Expected an array, map, set, or string: got ${describe(actual)}`); + } + }); + } + + /** + * @param {string} str The expected suffix. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + endsWith(str, opt_message) { + checkString(str); + return evaluate(this.subject_, function(actual) { + if (!isString(actual) || !actual.endsWith(str)) { + assert.fail(actual, str, 'ends with'); + } + }); + } + + /** + * @param {string} str The expected prefix. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + startsWith(str, opt_message) { + checkString(str); + return evaluate(this.subject_, function(actual) { + if (!isString(actual) || !actual.startsWith(str)) { + assert.fail(actual, str, 'starts with'); + } + }); + } + + /** + * @param {!RegExp} regex The regex the subject is expected to match. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + matches(regex, opt_message) { + if (!(regex instanceof RegExp)) { + throw TypeError(`Not a RegExp: ${describe(regex)}`); + } + return evaluate(this.subject_, function(actual) { + if (!isString(actual) || !regex.test(actual)) { + let message = opt_message + || `Expected a string matching ${regex}, got ${describe(actual)}`; + assert.fail(actual, regex, message); + } + }); + } + + /** + * @param {?} value The unexpected value. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + notEqualTo(value, opt_message) { + return evaluate(this.subject_, function(actual) { + assert.notStrictEqual(actual, value, opt_message); + }); + } + + /** An alias for {@link #isEqualTo}. */ + equalTo(value, opt_message) { + return this.isEqualTo(value, opt_message); + } + + /** An alias for {@link #isEqualTo}. */ + equals(value, opt_message) { + return this.isEqualTo(value, opt_message); + } + + /** + * @param {?} value The expected value. + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + isEqualTo(value, opt_message) { + return evaluate(this.subject_, function(actual) { + assert.strictEqual(actual, value, opt_message); + }); + } + + /** + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + isTrue(opt_message) { + return this.isEqualTo(true, opt_message); + } + + /** + * @param {string=} opt_message An optional failure message. + * @return {(Promise|undefined)} The result of this assertion, if the subject + * is a promised-value. Otherwise, the assertion is performed immediately + * and nothing is returned. + */ + isFalse(opt_message) { + return this.isEqualTo(false, opt_message); + } +} + + +// PUBLIC API + + +/** + * Creates an assertion about the given `value`. + * @return {!Assertion} the new assertion. + */ +module.exports = function assertThat(value) { + return new Assertion(value); +}; +module.exports.Assertion = Assertion; // Exported to help generated docs diff --git a/www/node_modules/selenium-webdriver/testing/index.js b/www/node_modules/selenium-webdriver/testing/index.js new file mode 100644 index 0000000..1ad1f8b --- /dev/null +++ b/www/node_modules/selenium-webdriver/testing/index.js @@ -0,0 +1,268 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +/** + * @fileoverview Provides wrappers around the following global functions from + * [Mocha's BDD interface](https://github.com/mochajs/mocha): + * + * - after + * - afterEach + * - before + * - beforeEach + * - it + * - it.only + * - it.skip + * - xit + * + * The provided wrappers leverage the {@link webdriver.promise.ControlFlow} + * to simplify writing asynchronous tests: + * + * var By = require('selenium-webdriver').By, + * until = require('selenium-webdriver').until, + * firefox = require('selenium-webdriver/firefox'), + * test = require('selenium-webdriver/testing'); + * + * test.describe('Google Search', function() { + * var driver; + * + * test.before(function() { + * driver = new firefox.Driver(); + * }); + * + * test.after(function() { + * driver.quit(); + * }); + * + * test.it('should append query to title', function() { + * driver.get('http://www.google.com/ncr'); + * driver.findElement(By.name('q')).sendKeys('webdriver'); + * driver.findElement(By.name('btnG')).click(); + * driver.wait(until.titleIs('webdriver - Google Search'), 1000); + * }); + * }); + * + * You may conditionally suppress a test function using the exported + * "ignore" function. If the provided predicate returns true, the attached + * test case will be skipped: + * + * test.ignore(maybe()).it('is flaky', function() { + * if (Math.random() < 0.5) throw Error(); + * }); + * + * function maybe() { return Math.random() < 0.5; } + */ + +var promise = require('..').promise; +var flow = promise.controlFlow(); + + +/** + * Wraps a function so that all passed arguments are ignored. + * @param {!Function} fn The function to wrap. + * @return {!Function} The wrapped function. + */ +function seal(fn) { + return function() { + fn(); + }; +} + + +/** + * Wraps a function on Mocha's BDD interface so it runs inside a + * webdriver.promise.ControlFlow and waits for the flow to complete before + * continuing. + * @param {!Function} globalFn The function to wrap. + * @return {!Function} The new function. + */ +function wrapped(globalFn) { + return function() { + if (arguments.length === 1) { + return globalFn(makeAsyncTestFn(arguments[0])); + } + else if (arguments.length === 2) { + return globalFn(arguments[0], makeAsyncTestFn(arguments[1])); + } + else { + throw Error('Invalid # arguments: ' + arguments.length); + } + }; +} + +/** + * Make a wrapper to invoke caller's test function, fn. Run the test function + * within a ControlFlow. + * + * Should preserve the semantics of Mocha's Runnable.prototype.run (See + * https://github.com/mochajs/mocha/blob/master/lib/runnable.js#L192) + * + * @param {Function} fn + * @return {Function} + */ +function makeAsyncTestFn(fn) { + var async = fn.length > 0; // if test function expects a callback, its "async" + + var ret = function(done) { + var runnable = this.runnable(); + var mochaCallback = runnable.callback; + runnable.callback = function() { + flow.reset(); + return mochaCallback.apply(this, arguments); + }; + + var testFn = fn.bind(this); + flow.execute(function controlFlowExecute() { + return new promise.Promise(function(fulfill, reject) { + if (async) { + // If testFn is async (it expects a done callback), resolve the promise of this + // test whenever that callback says to. Any promises returned from testFn are + // ignored. + testFn(function testFnDoneCallback(err) { + if (err) { + reject(err); + } else { + fulfill(); + } + }); + } else { + // Without a callback, testFn can return a promise, or it will + // be assumed to have completed synchronously + fulfill(testFn()); + } + }, flow); + }, runnable.fullTitle()).then(seal(done), done); + }; + + ret.toString = function() { + return fn.toString(); + }; + + return ret; +} + + +/** + * Ignores the test chained to this function if the provided predicate returns + * true. + * @param {function(): boolean} predicateFn A predicate to call to determine + * if the test should be suppressed. This function MUST be synchronous. + * @return {!Object} An object with wrapped versions of {@link #it()} and + * {@link #describe()} that ignore tests as indicated by the predicate. + */ +function ignore(predicateFn) { + var describe = wrap(exports.xdescribe, exports.describe); + describe.only = wrap(exports.xdescribe, exports.describe.only); + + var it = wrap(exports.xit, exports.it); + it.only = wrap(exports.xit, exports.it.only); + + return { + describe: describe, + it: it + }; + + function wrap(onSkip, onRun) { + return function(title, fn) { + if (predicateFn()) { + onSkip(title, fn); + } else { + onRun(title, fn); + } + }; + } +} + + +// PUBLIC API + + +/** + * @return {!promise.ControlFlow} the control flow instance used by this module + * to coordinate test actions. + */ +exports.controlFlow = function(){ + return flow; +}; + + +/** + * Registers a new test suite. + * @param {string} name The suite name. + * @param {function()=} fn The suite function, or {@code undefined} to define + * a pending test suite. + */ +exports.describe = global.describe; + +/** + * Defines a suppressed test suite. + * @param {string} name The suite name. + * @param {function()=} fn The suite function, or {@code undefined} to define + * a pending test suite. + */ +exports.xdescribe = global.xdescribe; +exports.describe.skip = global.describe.skip; + +/** + * Register a function to call after the current suite finishes. + * @param {function()} fn . + */ +exports.after = wrapped(global.after); + +/** + * Register a function to call after each test in a suite. + * @param {function()} fn . + */ +exports.afterEach = wrapped(global.afterEach); + +/** + * Register a function to call before the current suite starts. + * @param {function()} fn . + */ +exports.before = wrapped(global.before); + +/** + * Register a function to call before each test in a suite. + * @param {function()} fn . + */ +exports.beforeEach = wrapped(global.beforeEach); + +/** + * Add a test to the current suite. + * @param {string} name The test name. + * @param {function()=} fn The test function, or {@code undefined} to define + * a pending test case. + */ +exports.it = wrapped(global.it); + +/** + * An alias for {@link #it()} that flags the test as the only one that should + * be run within the current suite. + * @param {string} name The test name. + * @param {function()=} fn The test function, or {@code undefined} to define + * a pending test case. + */ +exports.iit = exports.it.only = wrapped(global.it.only); + +/** + * Adds a test to the current suite while suppressing it so it is not run. + * @param {string} name The test name. + * @param {function()=} fn The test function, or {@code undefined} to define + * a pending test case. + */ +exports.xit = exports.it.skip = wrapped(global.xit); + +exports.ignore = ignore; diff --git a/www/node_modules/sigmund/LICENSE b/www/node_modules/sigmund/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/www/node_modules/sigmund/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/www/node_modules/sigmund/README.md b/www/node_modules/sigmund/README.md new file mode 100644 index 0000000..25a38a5 --- /dev/null +++ b/www/node_modules/sigmund/README.md @@ -0,0 +1,53 @@ +# sigmund + +Quick and dirty signatures for Objects. + +This is like a much faster `deepEquals` comparison, which returns a +string key suitable for caches and the like. + +## Usage + +```javascript +function doSomething (someObj) { + var key = sigmund(someObj, maxDepth) // max depth defaults to 10 + var cached = cache.get(key) + if (cached) return cached + + var result = expensiveCalculation(someObj) + cache.set(key, result) + return result +} +``` + +The resulting key will be as unique and reproducible as calling +`JSON.stringify` or `util.inspect` on the object, but is much faster. +In order to achieve this speed, some differences are glossed over. +For example, the object `{0:'foo'}` will be treated identically to the +array `['foo']`. + +Also, just as there is no way to summon the soul from the scribblings +of a cocaine-addled psychoanalyst, there is no way to revive the object +from the signature string that sigmund gives you. In fact, it's +barely even readable. + +As with `util.inspect` and `JSON.stringify`, larger objects will +produce larger signature strings. + +Because sigmund is a bit less strict than the more thorough +alternatives, the strings will be shorter, and also there is a +slightly higher chance for collisions. For example, these objects +have the same signature: + + var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} + var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} + +Like a good Freudian, sigmund is most effective when you already have +some understanding of what you're looking for. It can help you help +yourself, but you must be willing to do some work as well. + +Cycles are handled, and cyclical objects are silently omitted (though +the key is included in the signature output.) + +The second argument is the maximum depth, which defaults to 10, +because that is the maximum object traversal depth covered by most +insurance carriers. diff --git a/www/node_modules/sigmund/bench.js b/www/node_modules/sigmund/bench.js new file mode 100644 index 0000000..5acfd6d --- /dev/null +++ b/www/node_modules/sigmund/bench.js @@ -0,0 +1,283 @@ +// different ways to id objects +// use a req/res pair, since it's crazy deep and cyclical + +// sparseFE10 and sigmund are usually pretty close, which is to be expected, +// since they are essentially the same algorithm, except that sigmund handles +// regular expression objects properly. + + +var http = require('http') +var util = require('util') +var sigmund = require('./sigmund.js') +var sreq, sres, creq, cres, test + +http.createServer(function (q, s) { + sreq = q + sres = s + sres.end('ok') + this.close(function () { setTimeout(function () { + start() + }, 200) }) +}).listen(1337, function () { + creq = http.get({ port: 1337 }) + creq.on('response', function (s) { cres = s }) +}) + +function start () { + test = [sreq, sres, creq, cres] + // test = sreq + // sreq.sres = sres + // sreq.creq = creq + // sreq.cres = cres + + for (var i in exports.compare) { + console.log(i) + var hash = exports.compare[i]() + console.log(hash) + console.log(hash.length) + console.log('') + } + + require('bench').runMain() +} + +function customWs (obj, md, d) { + d = d || 0 + var to = typeof obj + if (to === 'undefined' || to === 'function' || to === null) return '' + if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '') + + if (Array.isArray(obj)) { + return obj.map(function (i, _, __) { + return customWs(i, md, d + 1) + }).reduce(function (a, b) { return a + b }, '') + } + + var keys = Object.keys(obj) + return keys.map(function (k, _, __) { + return k + ':' + customWs(obj[k], md, d + 1) + }).reduce(function (a, b) { return a + b }, '') +} + +function custom (obj, md, d) { + d = d || 0 + var to = typeof obj + if (to === 'undefined' || to === 'function' || to === null) return '' + if (d > md || !obj || to !== 'object') return '' + obj + + if (Array.isArray(obj)) { + return obj.map(function (i, _, __) { + return custom(i, md, d + 1) + }).reduce(function (a, b) { return a + b }, '') + } + + var keys = Object.keys(obj) + return keys.map(function (k, _, __) { + return k + ':' + custom(obj[k], md, d + 1) + }).reduce(function (a, b) { return a + b }, '') +} + +function sparseFE2 (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + Object.keys(v).forEach(function (k, _, __) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') return + var to = typeof v[k] + if (to === 'function' || to === 'undefined') return + soFar += k + ':' + ch(v[k], depth + 1) + }) + soFar += '}' + } + ch(obj, 0) + return soFar +} + +function sparseFE (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + Object.keys(v).forEach(function (k, _, __) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') return + var to = typeof v[k] + if (to === 'function' || to === 'undefined') return + soFar += k + ch(v[k], depth + 1) + }) + } + ch(obj, 0) + return soFar +} + +function sparse (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + for (var k in v) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') continue + var to = typeof v[k] + if (to === 'function' || to === 'undefined') continue + soFar += k + ch(v[k], depth + 1) + } + } + ch(obj, 0) + return soFar +} + +function noCommas (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + for (var k in v) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') continue + var to = typeof v[k] + if (to === 'function' || to === 'undefined') continue + soFar += k + ':' + ch(v[k], depth + 1) + } + soFar += '}' + } + ch(obj, 0) + return soFar +} + + +function flatten (obj, maxDepth) { + var seen = [] + var soFar = '' + function ch (v, depth) { + if (depth > maxDepth) return + if (typeof v === 'function' || typeof v === 'undefined') return + if (typeof v !== 'object' || !v) { + soFar += v + return + } + if (seen.indexOf(v) !== -1 || depth === maxDepth) return + seen.push(v) + soFar += '{' + for (var k in v) { + // pseudo-private values. skip those. + if (k.charAt(0) === '_') continue + var to = typeof v[k] + if (to === 'function' || to === 'undefined') continue + soFar += k + ':' + ch(v[k], depth + 1) + soFar += ',' + } + soFar += '}' + } + ch(obj, 0) + return soFar +} + +exports.compare = +{ + // 'custom 2': function () { + // return custom(test, 2, 0) + // }, + // 'customWs 2': function () { + // return customWs(test, 2, 0) + // }, + 'JSON.stringify (guarded)': function () { + var seen = [] + return JSON.stringify(test, function (k, v) { + if (typeof v !== 'object' || !v) return v + if (seen.indexOf(v) !== -1) return undefined + seen.push(v) + return v + }) + }, + + 'flatten 10': function () { + return flatten(test, 10) + }, + + // 'flattenFE 10': function () { + // return flattenFE(test, 10) + // }, + + 'noCommas 10': function () { + return noCommas(test, 10) + }, + + 'sparse 10': function () { + return sparse(test, 10) + }, + + 'sparseFE 10': function () { + return sparseFE(test, 10) + }, + + 'sparseFE2 10': function () { + return sparseFE2(test, 10) + }, + + sigmund: function() { + return sigmund(test, 10) + }, + + + // 'util.inspect 1': function () { + // return util.inspect(test, false, 1, false) + // }, + // 'util.inspect undefined': function () { + // util.inspect(test) + // }, + // 'util.inspect 2': function () { + // util.inspect(test, false, 2, false) + // }, + // 'util.inspect 3': function () { + // util.inspect(test, false, 3, false) + // }, + // 'util.inspect 4': function () { + // util.inspect(test, false, 4, false) + // }, + // 'util.inspect Infinity': function () { + // util.inspect(test, false, Infinity, false) + // } +} + +/** results +**/ diff --git a/www/node_modules/sigmund/package.json b/www/node_modules/sigmund/package.json new file mode 100644 index 0000000..f4862fc --- /dev/null +++ b/www/node_modules/sigmund/package.json @@ -0,0 +1,85 @@ +{ + "_args": [ + [ + "sigmund@~1.0.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine/node_modules/minimatch" + ] + ], + "_from": "sigmund@>=1.0.0 <1.1.0", + "_id": "sigmund@1.0.1", + "_inCache": true, + "_installable": true, + "_location": "/sigmund", + "_nodeVersion": "2.0.1", + "_npmUser": { + "email": "isaacs@npmjs.com", + "name": "isaacs" + }, + "_npmVersion": "2.10.0", + "_phantomChildren": {}, + "_requested": { + "name": "sigmund", + "raw": "sigmund@~1.0.0", + "rawSpec": "~1.0.0", + "scope": null, + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/jasmine/minimatch" + ], + "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "_shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590", + "_shrinkwrap": null, + "_spec": "sigmund@~1.0.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/jasmine/node_modules/minimatch", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/sigmund/issues" + }, + "dependencies": {}, + "description": "Quick and dirty signatures for Objects.", + "devDependencies": { + "tap": "~0.3.0" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590", + "tarball": "http://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz" + }, + "gitHead": "527f97aa5bb253d927348698c0cd3bb267d098c6", + "homepage": "https://github.com/isaacs/sigmund#readme", + "keywords": [ + "object", + "signature", + "key", + "data", + "psychoanalysis" + ], + "license": "ISC", + "main": "sigmund.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "sigmund", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/sigmund.git" + }, + "scripts": { + "bench": "node bench.js", + "test": "tap test/*.js" + }, + "version": "1.0.1" +} diff --git a/www/node_modules/sigmund/sigmund.js b/www/node_modules/sigmund/sigmund.js new file mode 100644 index 0000000..82c7ab8 --- /dev/null +++ b/www/node_modules/sigmund/sigmund.js @@ -0,0 +1,39 @@ +module.exports = sigmund +function sigmund (subject, maxSessions) { + maxSessions = maxSessions || 10; + var notes = []; + var analysis = ''; + var RE = RegExp; + + function psychoAnalyze (subject, session) { + if (session > maxSessions) return; + + if (typeof subject === 'function' || + typeof subject === 'undefined') { + return; + } + + if (typeof subject !== 'object' || !subject || + (subject instanceof RE)) { + analysis += subject; + return; + } + + if (notes.indexOf(subject) !== -1 || session === maxSessions) return; + + notes.push(subject); + analysis += '{'; + Object.keys(subject).forEach(function (issue, _, __) { + // pseudo-private values. skip those. + if (issue.charAt(0) === '_') return; + var to = typeof subject[issue]; + if (to === 'function' || to === 'undefined') return; + analysis += issue; + psychoAnalyze(subject[issue], session + 1); + }); + } + psychoAnalyze(subject, 0); + return analysis; +} + +// vim: set softtabstop=4 shiftwidth=4: diff --git a/www/node_modules/sigmund/test/basic.js b/www/node_modules/sigmund/test/basic.js new file mode 100644 index 0000000..50c53a1 --- /dev/null +++ b/www/node_modules/sigmund/test/basic.js @@ -0,0 +1,24 @@ +var test = require('tap').test +var sigmund = require('../sigmund.js') + + +// occasionally there are duplicates +// that's an acceptable edge-case. JSON.stringify and util.inspect +// have some collision potential as well, though less, and collision +// detection is expensive. +var hash = '{abc/def/g{0h1i2{jkl' +var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]} +var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']} + +var obj3 = JSON.parse(JSON.stringify(obj1)) +obj3.c = /def/ +obj3.g[2].cycle = obj3 +var cycleHash = '{abc/def/g{0h1i2{jklcycle' + +test('basic', function (t) { + t.equal(sigmund(obj1), hash) + t.equal(sigmund(obj2), hash) + t.equal(sigmund(obj3), cycleHash) + t.end() +}) + diff --git a/www/node_modules/tmp/.npmignore b/www/node_modules/tmp/.npmignore new file mode 100644 index 0000000..78f2710 --- /dev/null +++ b/www/node_modules/tmp/.npmignore @@ -0,0 +1,2 @@ +node_modules/ +.idea/ diff --git a/www/node_modules/tmp/.travis.yml b/www/node_modules/tmp/.travis.yml new file mode 100644 index 0000000..0175d82 --- /dev/null +++ b/www/node_modules/tmp/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "0.6" + - "0.8" + - "0.10" diff --git a/www/node_modules/tmp/README.md b/www/node_modules/tmp/README.md new file mode 100644 index 0000000..3a1a509 --- /dev/null +++ b/www/node_modules/tmp/README.md @@ -0,0 +1,162 @@ +# Tmp + +A simple temporary file and directory creator for [node.js.][1] + +[![Build Status](https://secure.travis-ci.org/raszi/node-tmp.png?branch=master)](http://travis-ci.org/raszi/node-tmp) + +## About + +The main difference between bruce's [node-temp][2] is that mine more +aggressively checks for the existence of the newly created temporary file and +creates the new file with `O_EXCL` instead of simple `O_CREAT | O_RDRW`, so it +is safer. + +The API is slightly different as well, Tmp does not yet provide synchronous +calls and all the parameters are optional. + +You can set whether you want to remove the temporary file on process exit or +not, and the destination directory can also be set. + +## How to install + +```bash +npm install tmp +``` + +## Usage + +### File creation + +Simple temporary file creation, the file will be unlinked on process exit. + +```javascript +var tmp = require('tmp'); + +tmp.file(function _tempFileCreated(err, path, fd) { + if (err) throw err; + + console.log("File: ", path); + console.log("Filedescriptor: ", fd); +}); +``` + +### Directory creation + +Simple temporary directory creation, it will be removed on process exit. + +If the directory still contains items on process exit, then it won't be removed. + +```javascript +var tmp = require('tmp'); + +tmp.dir(function _tempDirCreated(err, path) { + if (err) throw err; + + console.log("Dir: ", path); +}); +``` + +If you want to cleanup the directory even when there are entries in it, then +you can pass the `unsafeCleanup` option when creating it. + +### Filename generation + +It is possible with this library to generate a unique filename in the specified +directory. + +```javascript +var tmp = require('tmp'); + +tmp.tmpName(function _tempNameGenerated(err, path) { + if (err) throw err; + + console.log("Created temporary filename: ", path); +}); +``` + +## Advanced usage + +### File creation + +Creates a file with mode `0644`, prefix will be `prefix-` and postfix will be `.txt`. + +```javascript +var tmp = require('tmp'); + +tmp.file({ mode: 0644, prefix: 'prefix-', postfix: '.txt' }, function _tempFileCreated(err, path, fd) { + if (err) throw err; + + console.log("File: ", path); + console.log("Filedescriptor: ", fd); +}); +``` + +### Directory creation + +Creates a directory with mode `0755`, prefix will be `myTmpDir_`. + +```javascript +var tmp = require('tmp'); + +tmp.dir({ mode: 0750, prefix: 'myTmpDir_' }, function _tempDirCreated(err, path) { + if (err) throw err; + + console.log("Dir: ", path); +}); +``` + +### mkstemps like + +Creates a new temporary directory with mode `0700` and filename like `/tmp/tmp-nk2J1u`. + +```javascript +var tmp = require('tmp'); + +tmp.dir({ template: '/tmp/tmp-XXXXXX' }, function _tempDirCreated(err, path) { + if (err) throw err; + + console.log("Dir: ", path); +}); +``` + +### Filename generation + +The `tmpName()` function accepts the `prefix`, `postfix`, `dir`, etc. parameters also: + +```javascript +var tmp = require('tmp'); + +tmp.tmpName({ template: '/tmp/tmp-XXXXXX' }, function _tempNameGenerated(err, path) { + if (err) throw err; + + console.log("Created temporary filename: ", path); +}); +``` + +## Graceful cleanup + +One may want to cleanup the temporary files even when an uncaught exception +occurs. To enforce this, you can call the `setGracefulCleanup()` method: + +```javascript +var tmp = require('tmp'); + +tmp.setGracefulCleanup(); +``` + +## Options + +All options are optional :) + + * `mode`: the file mode to create with, it fallbacks to `0600` on file creation and `0700` on directory creation + * `prefix`: the optional prefix, fallbacks to `tmp-` if not provided + * `postfix`: the optional postfix, fallbacks to `.tmp` on file creation + * `template`: [`mkstemps`][3] like filename template, no default + * `dir`: the optional temporary directory, fallbacks to system default (guesses from environment) + * `tries`: how many times should the function try to get a unique filename before giving up, default `3` + * `keep`: signals that the temporary file or directory should not be deleted on exit, default is `false`, means delete + * `unsafeCleanup`: recursively removes the created temporary directory, even when it's not empty. default is `false` + +[1]: http://nodejs.org/ +[2]: https://github.com/bruce/node-temp +[3]: http://www.kernel.org/doc/man-pages/online/pages/man3/mkstemp.3.html diff --git a/www/node_modules/tmp/domain-test.js b/www/node_modules/tmp/domain-test.js new file mode 100644 index 0000000..47221bc --- /dev/null +++ b/www/node_modules/tmp/domain-test.js @@ -0,0 +1,13 @@ +var domain = require('domain'); + +//throw new Error('bazz'); + +var d = domain.create(); +d.on('error', function ( e ) { + console.log('error!!!', e); +}); + +d.run(function () { + console.log('hey'); + throw new Error('bazz'); +}); diff --git a/www/node_modules/tmp/lib/tmp.js b/www/node_modules/tmp/lib/tmp.js new file mode 100644 index 0000000..ea84faa --- /dev/null +++ b/www/node_modules/tmp/lib/tmp.js @@ -0,0 +1,307 @@ +/*! + * Tmp + * + * Copyright (c) 2011-2013 KARASZI Istvan + * + * MIT Licensed + */ + +/** + * Module dependencies. + */ +var + fs = require('fs'), + path = require('path'), + os = require('os'), + exists = fs.exists || path.exists, + tmpDir = os.tmpDir || _getTMPDir, + _c = require('constants'); + +/** + * The working inner variables. + */ +var + // store the actual TMP directory + _TMP = tmpDir(), + + // the random characters to choose from + randomChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz", + randomCharsLength = randomChars.length, + + // this will hold the objects need to be removed on exit + _removeObjects = [], + + _gracefulCleanup = false, + _uncaughtException = false; + +/** + * Gets the temp directory. + * + * @return {String} + * @api private + */ +function _getTMPDir() { + var tmpNames = [ 'TMPDIR', 'TMP', 'TEMP' ]; + + for (var i = 0, length = tmpNames.length; i < length; i++) { + if (_isUndefined(process.env[tmpNames[i]])) continue; + + return process.env[tmpNames[i]]; + } + + // fallback to the default + return '/tmp'; +} + +/** + * Checks whether the `obj` parameter is defined or not. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ +function _isUndefined(obj) { + return typeof obj === 'undefined'; +} + +/** + * Parses the function arguments. + * + * This function helps to have optional arguments. + * + * @param {Object} options + * @param {Function} callback + * @api private + */ +function _parseArguments(options, callback) { + if (!callback || typeof callback != "function") { + callback = options; + options = {}; + } + + return [ options, callback ]; +} + +/** + * Gets a temporary file name. + * + * @param {Object} opts + * @param {Function} cb + * @api private + */ +function _getTmpName(options, callback) { + var + args = _parseArguments(options, callback), + opts = args[0], + cb = args[1], + template = opts.template, + templateDefined = !_isUndefined(template), + tries = opts.tries || 3; + + if (isNaN(tries) || tries < 0) + return cb(new Error('Invalid tries')); + + if (templateDefined && !template.match(/XXXXXX/)) + return cb(new Error('Invalid template provided')); + + function _getName() { + + // prefix and postfix + if (!templateDefined) { + var name = [ + (_isUndefined(opts.prefix)) ? 'tmp-' : opts.prefix, + process.pid, + (Math.random() * 0x1000000000).toString(36), + opts.postfix + ].join(''); + + return path.join(opts.dir || _TMP, name); + } + + // mkstemps like template + var chars = []; + + for (var i = 0; i < 6; i++) { + chars.push(randomChars.substr(Math.floor(Math.random() * randomCharsLength), 1)); + } + + return template.replace(/XXXXXX/, chars.join('')); + } + + (function _getUniqueName() { + var name = _getName(); + + // check whether the path exists then retry if needed + exists(name, function _pathExists(pathExists) { + if (pathExists) { + if (tries-- > 0) return _getUniqueName(); + + return cb(new Error('Could not get a unique tmp filename, max tries reached')); + } + + cb(null, name); + }); + }()); +} + +/** + * Creates and opens a temporary file. + * + * @param {Object} options + * @param {Function} callback + * @api public + */ +function _createTmpFile(options, callback) { + var + args = _parseArguments(options, callback), + opts = args[0], + cb = args[1]; + + opts.postfix = (_isUndefined(opts.postfix)) ? '.tmp' : opts.postfix; + + // gets a temporary filename + _getTmpName(opts, function _tmpNameCreated(err, name) { + if (err) return cb(err); + + // create and open the file + fs.open(name, _c.O_CREAT | _c.O_EXCL | _c.O_RDWR, opts.mode || 0600, function _fileCreated(err, fd) { + if (err) return cb(err); + + var removeCallback = _prepareRemoveCallback(fs.unlinkSync.bind(fs), name); + + if (!opts.keep) { + _removeObjects.unshift(removeCallback); + } + + cb(null, name, fd, removeCallback); + }); + }); +} + +/** + * Removes files and folders in a directory recursively. + * + * @param {String} dir + */ +function _rmdirRecursiveSync(dir) { + var files = fs.readdirSync(dir); + + for (var i = 0, length = files.length; i < length; i++) { + var file = path.join(dir, files[i]); + // lstat so we don't recurse into symlinked directories. + var stat = fs.lstatSync(file); + + if (stat.isDirectory()) { + _rmdirRecursiveSync(file); + } else { + fs.unlinkSync(file); + } + } + + fs.rmdirSync(dir); +} + +/** + * + * @param {Function} removeFunction + * @param {String} path + * @returns {Function} + * @private + */ +function _prepareRemoveCallback(removeFunction, path) { + var called = false; + return function() { + if (called) { + return; + } + + removeFunction(path); + + called = true; + }; +} + +/** + * Creates a temporary directory. + * + * @param {Object} options + * @param {Function} callback + * @api public + */ +function _createTmpDir(options, callback) { + var + args = _parseArguments(options, callback), + opts = args[0], + cb = args[1]; + + // gets a temporary filename + _getTmpName(opts, function _tmpNameCreated(err, name) { + if (err) return cb(err); + + // create the directory + fs.mkdir(name, opts.mode || 0700, function _dirCreated(err) { + if (err) return cb(err); + + var removeCallback = _prepareRemoveCallback( + opts.unsafeCleanup + ? _rmdirRecursiveSync + : fs.rmdirSync.bind(fs), + name + ); + + if (!opts.keep) { + _removeObjects.unshift(removeCallback); + } + + cb(null, name, removeCallback); + }); + }); +} + +/** + * The garbage collector. + * + * @api private + */ +function _garbageCollector() { + if (_uncaughtException && !_gracefulCleanup) { + return; + } + + for (var i = 0, length = _removeObjects.length; i < length; i++) { + try { + _removeObjects[i].call(null); + } catch (e) { + // already removed? + } + } +} + +function _setGracefulCleanup() { + _gracefulCleanup = true; +} + +var version = process.versions.node.split('.').map(function (value) { + return parseInt(value, 10); +}); + +if (version[0] === 0 && (version[1] < 9 || version[1] === 9 && version[2] < 5)) { + process.addListener('uncaughtException', function _uncaughtExceptionThrown( err ) { + _uncaughtException = true; + _garbageCollector(); + + throw err; + }); +} + +process.addListener('exit', function _exit(code) { + if (code) _uncaughtException = true; + _garbageCollector(); +}); + +// exporting all the needed methods +module.exports.tmpdir = _TMP; +module.exports.dir = _createTmpDir; +module.exports.file = _createTmpFile; +module.exports.tmpName = _getTmpName; +module.exports.setGracefulCleanup = _setGracefulCleanup; diff --git a/www/node_modules/tmp/package.json b/www/node_modules/tmp/package.json new file mode 100644 index 0000000..ede4cfa --- /dev/null +++ b/www/node_modules/tmp/package.json @@ -0,0 +1,91 @@ +{ + "_args": [ + [ + "tmp@0.0.24", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver" + ] + ], + "_from": "tmp@0.0.24", + "_id": "tmp@0.0.24", + "_inCache": true, + "_installable": true, + "_location": "/tmp", + "_npmUser": { + "email": "npm@spam.raszi.hu", + "name": "raszi" + }, + "_npmVersion": "1.4.16", + "_phantomChildren": {}, + "_requested": { + "name": "tmp", + "raw": "tmp@0.0.24", + "rawSpec": "0.0.24", + "scope": null, + "spec": "0.0.24", + "type": "version" + }, + "_requiredBy": [ + "/selenium-webdriver" + ], + "_resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz", + "_shasum": "d6a5e198d14a9835cc6f2d7c3d9e302428c8cf12", + "_shrinkwrap": null, + "_spec": "tmp@0.0.24", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver", + "author": { + "email": "github@spam.raszi.hu", + "name": "KARASZI István", + "url": "http://raszi.hu/" + }, + "bugs": { + "url": "http://github.com/raszi/node-tmp/issues" + }, + "dependencies": {}, + "description": "Temporary file and directory creator", + "devDependencies": { + "vows": "~0.7.0" + }, + "directories": {}, + "dist": { + "shasum": "d6a5e198d14a9835cc6f2d7c3d9e302428c8cf12", + "tarball": "http://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz" + }, + "engines": { + "node": ">=0.4.0" + }, + "gitHead": "6864655f13a11c6043c119a0cb60385f072bcecf", + "homepage": "http://github.com/raszi/node-tmp", + "keywords": [ + "temporary", + "tmp", + "temp", + "tempdir", + "tempfile", + "tmpdir", + "tmpfile" + ], + "licenses": [ + { + "type": "MIT", + "url": "http://opensource.org/licenses/MIT" + } + ], + "main": "lib/tmp.js", + "maintainers": [ + { + "email": "npm@spam.raszi.hu", + "name": "raszi" + } + ], + "name": "tmp", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/raszi/node-tmp.git" + }, + "scripts": { + "test": "vows test/*-test.js" + }, + "version": "0.0.24" +} diff --git a/www/node_modules/tmp/test-all.sh b/www/node_modules/tmp/test-all.sh new file mode 100755 index 0000000..4734d60 --- /dev/null +++ b/www/node_modules/tmp/test-all.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +#node06 +for node in node08 node; do + command -v ${node} > /dev/null 2>&1 || continue + + echo "Testing with $(${node} --version)..." + ${node} node_modules/vows/bin/vows test/*test.js +done diff --git a/www/node_modules/tmp/test.js b/www/node_modules/tmp/test.js new file mode 100644 index 0000000..8058221 --- /dev/null +++ b/www/node_modules/tmp/test.js @@ -0,0 +1,6 @@ +process.on('uncaughtException', function ( err ) { + console.log('blah'); + throw err; +}); + +throw "on purpose" diff --git a/www/node_modules/tmp/test/base.js b/www/node_modules/tmp/test/base.js new file mode 100644 index 0000000..498d8fb --- /dev/null +++ b/www/node_modules/tmp/test/base.js @@ -0,0 +1,74 @@ +var + assert = require('assert'), + path = require('path'), + exec = require('child_process').exec; + +function _spawnTestWithError(testFile, params, cb) { + _spawnTest(true, testFile, params, cb); +} + +function _spawnTestWithoutError(testFile, params, cb) { + _spawnTest(false, testFile, params, cb); +} + +function _spawnTest(passError, testFile, params, cb) { + var + filename, + node_path = process.argv[0], + command = [ node_path, path.join(__dirname, testFile) ].concat(params).join(' '); + + exec(command, function _execDone(err, stdout, stderr) { + if (passError) { + if (err) { + return cb(err); + } else if (stderr.length > 0) { + return cb(stderr.toString()); + } + } + + return cb(null, stdout.toString()); + }); +} + +function _testStat(stat, mode) { + assert.equal(stat.uid, process.getuid(), 'should have the same UID'); + assert.equal(stat.gid, process.getgid(), 'should have the same GUID'); + assert.equal(stat.mode, mode); +} + +function _testPrefix(prefix) { + return function _testPrefixGenerated(err, name, fd) { + assert.equal(path.basename(name).slice(0, prefix.length), prefix, 'should have the provided prefix'); + }; +} + +function _testPostfix(postfix) { + return function _testPostfixGenerated(err, name, fd) { + assert.equal(name.slice(name.length - postfix.length, name.length), postfix, 'should have the provided postfix'); + }; +} + +function _testKeep(type, keep, cb) { + _spawnTestWithError('keep.js', [ type, keep ], cb); +} + +function _testGraceful(type, graceful, cb) { + _spawnTestWithoutError('graceful.js', [ type, graceful ], cb); +} + +function _assertName(err, name) { + assert.isString(name); + assert.isNotZero(name.length); +} + +function _testUnsafeCleanup(unsafe, cb) { + _spawnTestWithoutError('unsafe.js', [ 'dir', unsafe ], cb); +} + +module.exports.testStat = _testStat; +module.exports.testPrefix = _testPrefix; +module.exports.testPostfix = _testPostfix; +module.exports.testKeep = _testKeep; +module.exports.testGraceful = _testGraceful; +module.exports.assertName = _assertName; +module.exports.testUnsafeCleanup = _testUnsafeCleanup; diff --git a/www/node_modules/tmp/test/dir-test.js b/www/node_modules/tmp/test/dir-test.js new file mode 100644 index 0000000..2e4e529 --- /dev/null +++ b/www/node_modules/tmp/test/dir-test.js @@ -0,0 +1,196 @@ +var + vows = require('vows'), + assert = require('assert'), + + path = require('path'), + fs = require('fs'), + existsSync = fs.existsSync || path.existsSync, + + tmp = require('../lib/tmp.js'), + Test = require('./base.js'); + + +function _testDir(mode) { + return function _testDirGenerated(err, name) { + assert.ok(existsSync(name), 'should exist'); + + var stat = fs.statSync(name); + assert.ok(stat.isDirectory(), 'should be a directory'); + + Test.testStat(stat, mode); + }; +} + +vows.describe('Directory creation').addBatch({ + 'when using without parameters': { + topic: function () { + tmp.dir(this.callback); + }, + + 'should be a directory': _testDir(040700), + 'should have the default prefix': Test.testPrefix('tmp-') + }, + + 'when using with prefix': { + topic: function () { + tmp.dir({ prefix: 'something' }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a directory': _testDir(040700), + 'should have the provided prefix': Test.testPrefix('something') + }, + + 'when using with postfix': { + topic: function () { + tmp.dir({ postfix: '.txt' }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a directory': _testDir(040700), + 'should have the provided postfix': Test.testPostfix('.txt') + }, + + 'when using template': { + topic: function () { + tmp.dir({ template: path.join(tmp.tmpdir, 'clike-XXXXXX-postfix') }, this.callback); + }, + + 'should not return with error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testDir(040700), + 'should have the provided prefix': Test.testPrefix('clike-'), + 'should have the provided postfix': Test.testPostfix('-postfix') + }, + + 'when using multiple options': { + topic: function () { + tmp.dir({ prefix: 'foo', postfix: 'bar', mode: 0750 }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a directory': _testDir(040750), + 'should have the provided prefix': Test.testPrefix('foo'), + 'should have the provided postfix': Test.testPostfix('bar') + }, + + 'when using multiple options and mode': { + topic: function () { + tmp.dir({ prefix: 'complicated', postfix: 'options', mode: 0755 }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a directory': _testDir(040755), + 'should have the provided prefix': Test.testPrefix('complicated'), + 'should have the provided postfix': Test.testPostfix('options') + }, + + 'no tries': { + topic: function () { + tmp.dir({ tries: -1 }, this.callback); + }, + + 'should return with an error': assert.isObject + }, + + 'keep testing': { + topic: function () { + Test.testKeep('dir', '1', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a dir': function (err, name) { + _testDir(040700)(err, name); + fs.rmdirSync(name); + } + }, + + 'unlink testing': { + topic: function () { + Test.testKeep('dir', '0', this.callback); + }, + + 'should not return with error': assert.isNull, + 'should return with a name': Test.assertName, + 'should not exist': function (err, name) { + assert.ok(!existsSync(name), "Directory should be removed"); + } + }, + + 'non graceful testing': { + topic: function () { + Test.testGraceful('dir', '0', this.callback); + }, + + 'should not return with error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a dir': function (err, name) { + _testDir(040700)(err, name); + fs.rmdirSync(name); + } + }, + + 'graceful testing': { + topic: function () { + Test.testGraceful('dir', '1', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should not exist': function (err, name) { + assert.ok(!existsSync(name), "Directory should be removed"); + } + }, + + 'unsafeCleanup === true': { + topic: function () { + Test.testUnsafeCleanup('1', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should not exist': function (err, name) { + assert.ok(!existsSync(name), "Directory should be removed"); + }, + 'should remove symlinked dir': function(err, name) { + assert.ok( + !existsSync(name + '/symlinkme-target'), + 'should remove target' + ); + }, + 'should not remove contents of symlink dir': function(err, name) { + assert.ok( + existsSync(__dirname + '/symlinkme/file.js'), + 'should not remove symlinked directory\'s content' + ); + } + }, + + 'unsafeCleanup === false': { + topic: function () { + Test.testUnsafeCleanup('0', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a directory': _testDir(040700) + }, + + 'remove callback': { + topic: function () { + tmp.dir(this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'removeCallback should remove directory': function (_err, name, removeCallback) { + removeCallback(); + assert.ok(!existsSync(name), "Directory should be removed"); + } + } +}).exportTo(module); diff --git a/www/node_modules/tmp/test/file-test.js b/www/node_modules/tmp/test/file-test.js new file mode 100644 index 0000000..d9605b3 --- /dev/null +++ b/www/node_modules/tmp/test/file-test.js @@ -0,0 +1,177 @@ +var + vows = require('vows'), + assert = require('assert'), + + path = require('path'), + fs = require('fs'), + existsSync = fs.existsSync || path.existsSync, + + tmp = require('../lib/tmp.js'), + Test = require('./base.js'); + + +function _testFile(mode, fdTest) { + return function _testFileGenerated(err, name, fd) { + assert.ok(existsSync(name), 'should exist'); + + var stat = fs.statSync(name); + assert.equal(stat.size, 0, 'should have zero size'); + assert.ok(stat.isFile(), 'should be a file'); + + Test.testStat(stat, mode); + + // check with fstat as well (fd checking) + if (fdTest) { + var fstat = fs.fstatSync(fd); + assert.deepEqual(fstat, stat, 'fstat results should be the same'); + + var data = new Buffer('something'); + assert.equal(fs.writeSync(fd, data, 0, data.length, 0), data.length, 'should be writable'); + assert.ok(!fs.closeSync(fd), 'should not return with error'); + } + }; +} + +vows.describe('File creation').addBatch({ + 'when using without parameters': { + topic: function () { + tmp.file(this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100600, true), + 'should have the default prefix': Test.testPrefix('tmp-'), + 'should have the default postfix': Test.testPostfix('.tmp') + }, + + 'when using with prefix': { + topic: function () { + tmp.file({ prefix: 'something' }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100600, true), + 'should have the provided prefix': Test.testPrefix('something') + }, + + 'when using with postfix': { + topic: function () { + tmp.file({ postfix: '.txt' }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100600, true), + 'should have the provided postfix': Test.testPostfix('.txt') + }, + + 'when using template': { + topic: function () { + tmp.file({ template: path.join(tmp.tmpdir, 'clike-XXXXXX-postfix') }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100600, true), + 'should have the provided prefix': Test.testPrefix('clike-'), + 'should have the provided postfix': Test.testPostfix('-postfix') + }, + + 'when using multiple options': { + topic: function () { + tmp.file({ prefix: 'foo', postfix: 'bar', mode: 0640 }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100640, true), + 'should have the provided prefix': Test.testPrefix('foo'), + 'should have the provided postfix': Test.testPostfix('bar') + }, + + 'when using multiple options and mode': { + topic: function () { + tmp.file({ prefix: 'complicated', postfix: 'options', mode: 0644 }, this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': _testFile(0100644, true), + 'should have the provided prefix': Test.testPrefix('complicated'), + 'should have the provided postfix': Test.testPostfix('options') + }, + + 'no tries': { + topic: function () { + tmp.file({ tries: -1 }, this.callback); + }, + + 'should not be created': assert.isObject + }, + + 'keep testing': { + topic: function () { + Test.testKeep('file', '1', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': function (err, name) { + _testFile(0100600, false)(err, name, null); + fs.unlinkSync(name); + } + }, + + 'unlink testing': { + topic: function () { + Test.testKeep('file', '0', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should not exist': function (err, name) { + assert.ok(!existsSync(name), "File should be removed"); + } + }, + + 'non graceful testing': { + topic: function () { + Test.testGraceful('file', '0', this.callback); + }, + + 'should not return with error': assert.isNull, + 'should return with a name': Test.assertName, + 'should be a file': function (err, name) { + _testFile(0100600, false)(err, name, null); + fs.unlinkSync(name); + } + }, + + 'graceful testing': { + topic: function () { + Test.testGraceful('file', '1', this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'should not exist': function (err, name) { + assert.ok(!existsSync(name), "File should be removed"); + } + }, + + 'remove callback': { + topic: function () { + tmp.file(this.callback); + }, + + 'should not return with an error': assert.isNull, + 'should return with a name': Test.assertName, + 'removeCallback should remove file': function (_err, name, _fd, removeCallback) { + removeCallback(); + assert.ok(!existsSync(name), "File should be removed"); + } + } + +}).exportTo(module); diff --git a/www/node_modules/tmp/test/graceful.js b/www/node_modules/tmp/test/graceful.js new file mode 100644 index 0000000..c898656 --- /dev/null +++ b/www/node_modules/tmp/test/graceful.js @@ -0,0 +1,15 @@ +var + tmp = require('../lib/tmp'), + spawn = require('./spawn'); + +var graceful = spawn.arg; + +if (graceful) { + tmp.setGracefulCleanup(); +} + +spawn.tmpFunction(function (err, name) { + spawn.out(name, function () { + throw new Error("Thrown on purpose"); + }); +}); diff --git a/www/node_modules/tmp/test/keep.js b/www/node_modules/tmp/test/keep.js new file mode 100644 index 0000000..9538605 --- /dev/null +++ b/www/node_modules/tmp/test/keep.js @@ -0,0 +1,11 @@ +var spawn = require('./spawn'); + +var keep = spawn.arg; + +spawn.tmpFunction({ keep: keep }, function (err, name) { + if (err) { + spawn.err(err, spawn.exit); + } else { + spawn.out(name, spawn.exit); + } +}); diff --git a/www/node_modules/tmp/test/name-test.js b/www/node_modules/tmp/test/name-test.js new file mode 100644 index 0000000..a242c21 --- /dev/null +++ b/www/node_modules/tmp/test/name-test.js @@ -0,0 +1,82 @@ +var + vows = require('vows'), + assert = require('assert'), + + path = require('path'), + + tmp = require('../lib/tmp.js'), + Test = require('./base.js'); + +vows.describe('Name creation').addBatch({ + 'when using without parameters': { + topic: function () { + tmp.tmpName(this.callback); + }, + + 'should not return with error': assert.isNull, + 'should have the default prefix': Test.testPrefix('tmp-') + }, + + 'when using with prefix': { + topic: function () { + tmp.tmpName({ prefix: 'something' }, this.callback); + }, + + 'should not return with error': assert.isNull, + 'should have the provided prefix': Test.testPrefix('something') + }, + + 'when using with postfix': { + topic: function () { + tmp.tmpName({ postfix: '.txt' }, this.callback); + }, + + 'should not return with error': assert.isNull, + 'should have the provided postfix': Test.testPostfix('.txt') + + }, + + 'when using template': { + topic: function () { + tmp.tmpName({ template: path.join(tmp.tmpdir, 'clike-XXXXXX-postfix') }, this.callback); + }, + + 'should not return with error': assert.isNull, + 'should have the provided prefix': Test.testPrefix('clike-'), + 'should have the provided postfix': Test.testPostfix('-postfix'), + 'should have template filled': function (err, name) { + assert.isTrue(/[a-zA-Z0-9]{6}/.test(name)); + } + }, + + 'when using multiple options': { + topic: function () { + tmp.tmpName({ prefix: 'foo', postfix: 'bar', tries: 5 }, this.callback); + }, + + 'should not return with error': assert.isNull, + 'should have the provided prefix': Test.testPrefix('foo'), + 'should have the provided postfix': Test.testPostfix('bar') + }, + + 'no tries': { + topic: function () { + tmp.tmpName({ tries: -1 }, this.callback); + }, + + 'should fail': function (err, name) { + assert.isObject(err); + } + }, + + 'tries not numeric': { + topic: function () { + tmp.tmpName({ tries: 'hello'}, this.callback); + }, + + 'should fail': function (err, name) { + assert.isObject(err); + } + } + +}).exportTo(module); diff --git a/www/node_modules/tmp/test/spawn.js b/www/node_modules/tmp/test/spawn.js new file mode 100644 index 0000000..6468eb3 --- /dev/null +++ b/www/node_modules/tmp/test/spawn.js @@ -0,0 +1,32 @@ +var + fs = require('fs'), + tmp = require('../lib/tmp'); + +function _writeSync(stream, str, cb) { + var flushed = stream.write(str); + if (flushed) { + return cb(null); + } + + stream.once('drain', function _flushed() { + cb(null); + }); +} + +module.exports.out = function (str, cb) { + _writeSync(process.stdout, str, cb); +}; + +module.exports.err = function (str, cb) { + _writeSync(process.stderr, str, cb); +}; + +module.exports.exit = function () { + process.exit(0); +}; + +var type = process.argv[2]; +module.exports.tmpFunction = (type == 'file') ? tmp.file : tmp.dir; + +var arg = (process.argv[3] && parseInt(process.argv[3], 10) === 1) ? true : false; +module.exports.arg = arg; diff --git a/www/node_modules/tmp/test/symlinkme/file.js b/www/node_modules/tmp/test/symlinkme/file.js new file mode 100644 index 0000000..e69de29 diff --git a/www/node_modules/tmp/test/unsafe.js b/www/node_modules/tmp/test/unsafe.js new file mode 100644 index 0000000..73e4fb3 --- /dev/null +++ b/www/node_modules/tmp/test/unsafe.js @@ -0,0 +1,30 @@ +var + fs = require('fs'), + join = require('path').join, + spawn = require('./spawn'); + +var unsafe = spawn.arg; +spawn.tmpFunction({ unsafeCleanup: unsafe }, function (err, name) { + if (err) { + spawn.err(err, spawn.exit); + return; + } + + try { + // file that should be removed + var fd = fs.openSync(join(name, 'should-be-removed.file'), 'w'); + fs.closeSync(fd); + + // in tree source + var symlinkSource = join(__dirname, 'symlinkme'); + // testing target + var symlinkTarget = join(name, 'symlinkme-target'); + + // symlink that should be removed but the contents should be preserved. + fs.symlinkSync(symlinkSource, symlinkTarget, 'dir'); + + spawn.out(name, spawn.exit); + } catch (e) { + spawn.err(e.toString(), spawn.exit); + } +}); diff --git a/www/node_modules/ultron/.npmignore b/www/node_modules/ultron/.npmignore new file mode 100644 index 0000000..66210a2 --- /dev/null +++ b/www/node_modules/ultron/.npmignore @@ -0,0 +1,3 @@ +node_modules +coverage +.tern-port diff --git a/www/node_modules/ultron/.travis.yml b/www/node_modules/ultron/.travis.yml new file mode 100644 index 0000000..a505004 --- /dev/null +++ b/www/node_modules/ultron/.travis.yml @@ -0,0 +1,21 @@ +sudo: false +language: node_js +node_js: + - "0.12" + - "0.10" + - "0.8" + - "iojs" +before_install: + - 'if [ "${TRAVIS_NODE_VERSION}" == "0.8" ]; then npm install -g npm@2.11.1; fi' +script: + - "npm run test-travis" +after_script: + - "npm install coveralls@2.11.x && cat coverage/lcov.info | coveralls" +matrix: + fast_finish: true +notifications: + irc: + channels: + - "irc.freenode.org#unshift" + on_success: change + on_failure: change diff --git a/www/node_modules/ultron/LICENSE b/www/node_modules/ultron/LICENSE new file mode 100644 index 0000000..6dc9316 --- /dev/null +++ b/www/node_modules/ultron/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Unshift.io, Arnout Kazemier, the Contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/www/node_modules/ultron/README.md b/www/node_modules/ultron/README.md new file mode 100644 index 0000000..84fa3f2 --- /dev/null +++ b/www/node_modules/ultron/README.md @@ -0,0 +1,97 @@ +# Ultron + +[![Made by unshift](https://img.shields.io/badge/made%20by-unshift-00ffcc.svg?style=flat-square)](http://unshift.io)[![Version npm](http://img.shields.io/npm/v/ultron.svg?style=flat-square)](http://browsenpm.org/package/ultron)[![Build Status](http://img.shields.io/travis/unshiftio/ultron/master.svg?style=flat-square)](https://travis-ci.org/unshiftio/ultron)[![Dependencies](https://img.shields.io/david/unshiftio/ultron.svg?style=flat-square)](https://david-dm.org/unshiftio/ultron)[![Coverage Status](http://img.shields.io/coveralls/unshiftio/ultron/master.svg?style=flat-square)](https://coveralls.io/r/unshiftio/ultron?branch=master)[![IRC channel](http://img.shields.io/badge/IRC-irc.freenode.net%23unshift-00a8ff.svg?style=flat-square)](http://webchat.freenode.net/?channels=unshift) + +Ultron is a high-intelligence robot. It gathers intelligence so it can start +improving upon his rudimentary design. It will learn your event emitting +patterns and find ways to exterminate them. Allowing you to remove only the +event emitters that **you** assigned and not the ones that your users or +developers assigned. This can prevent race conditions, memory leaks and even file +descriptor leaks from ever happening as you won't remove clean up processes. + +## Installation + +The module is designed to be used in browsers using browserify and in Node.js. +You can install the module through the public npm registry by running the +following command in CLI: + +``` +npm install --save ultron +``` + +## Usage + +In all examples we assume that you've required the library as following: + +```js +'use strict'; + +var Ultron = require('ultron'); +``` + +Now that we've required the library we can construct our first `Ultron` instance. +The constructor requires one argument which should be the `EventEmitter` +instance that we need to operate upon. This can be the `EventEmitter` module +that ships with Node.js or `EventEmitter3` or anything else as long as it +follow the same API and internal structure as these 2. So with that in mind we +can create the instance: + +```js +// +// For the sake of this example we're going to construct an empty EventEmitter +// +var EventEmitter = require('events').EventEmitter; // or require('eventmitter3'); +var events = new EventEmitter(); + +var ultron = new Ultron(events); +``` + +You can now use the following API's from the Ultron instance: + +### Ultron.on + +Register a new event listener for the given event. It follows the exact same API +as `EventEmitter.on` but it will return itself instead of returning the +EventEmitter instance. If you are using EventEmitter3 it also supports the +context param: + +```js +ultron.on('event-name', handler, { custom: 'function context' }); +``` + +### Ultron.once + +Exactly the same as the [Ultron.on](#ultronon) but it only allows the execution +once. + +### Ultron.remove + +This is where all the magic happens and the safe removal starts. This function +accepts different argument styles: + +- No arguments, assume that all events need to be removed so it will work as + `removeAllListeners()` API. +- 1 argument, when it's a string it will be split on ` ` and `,` to create a + list of events that need to be cleared. +- Multiple arguments, we assume that they are all names of events that need to + be cleared. + +```js +ultron.remove('foo, bar baz'); // Removes foo, bar and baz. +ultron.remove('foo', 'bar', 'baz'); // Removes foo, bar and baz. +ultron.remove(); // Removes everything. +``` + +If you just want to remove a single event listener using a function reference +you can still use the EventEmitter's `removeListener(event, fn)` API: + +```js +function foo() {} + +ulton.on('foo', foo); +events.removeListener('foo', foo); +``` + +## License + +MIT diff --git a/www/node_modules/ultron/index.js b/www/node_modules/ultron/index.js new file mode 100644 index 0000000..af17ab7 --- /dev/null +++ b/www/node_modules/ultron/index.js @@ -0,0 +1,129 @@ +'use strict'; + +var has = Object.prototype.hasOwnProperty; + +/** + * An auto incrementing id which we can use to create "unique" Ultron instances + * so we can track the event emitters that are added through the Ultron + * interface. + * + * @type {Number} + * @private + */ +var id = 0; + +/** + * Ultron is high-intelligence robot. It gathers intelligence so it can start improving + * upon his rudimentary design. It will learn from your EventEmitting patterns + * and exterminate them. + * + * @constructor + * @param {EventEmitter} ee EventEmitter instance we need to wrap. + * @api public + */ +function Ultron(ee) { + if (!(this instanceof Ultron)) return new Ultron(ee); + + this.id = id++; + this.ee = ee; +} + +/** + * Register a new EventListener for the given event. + * + * @param {String} event Name of the event. + * @param {Functon} fn Callback function. + * @param {Mixed} context The context of the function. + * @returns {Ultron} + * @api public + */ +Ultron.prototype.on = function on(event, fn, context) { + fn.__ultron = this.id; + this.ee.on(event, fn, context); + + return this; +}; +/** + * Add an EventListener that's only called once. + * + * @param {String} event Name of the event. + * @param {Function} fn Callback function. + * @param {Mixed} context The context of the function. + * @returns {Ultron} + * @api public + */ +Ultron.prototype.once = function once(event, fn, context) { + fn.__ultron = this.id; + this.ee.once(event, fn, context); + + return this; +}; + +/** + * Remove the listeners we assigned for the given event. + * + * @returns {Ultron} + * @api public + */ +Ultron.prototype.remove = function remove() { + var args = arguments + , event; + + // + // When no event names are provided we assume that we need to clear all the + // events that were assigned through us. + // + if (args.length === 1 && 'string' === typeof args[0]) { + args = args[0].split(/[, ]+/); + } else if (!args.length) { + args = []; + + for (event in this.ee._events) { + if (has.call(this.ee._events, event)) args.push(event); + } + } + + for (var i = 0; i < args.length; i++) { + var listeners = this.ee.listeners(args[i]); + + for (var j = 0; j < listeners.length; j++) { + event = listeners[j]; + + // + // Once listeners have a `listener` property that stores the real listener + // in the EventEmitter that ships with Node.js. + // + if (event.listener) { + if (event.listener.__ultron !== this.id) continue; + delete event.listener.__ultron; + } else { + if (event.__ultron !== this.id) continue; + delete event.__ultron; + } + + this.ee.removeListener(args[i], event); + } + } + + return this; +}; + +/** + * Destroy the Ultron instance, remove all listeners and release all references. + * + * @returns {Boolean} + * @api public + */ +Ultron.prototype.destroy = function destroy() { + if (!this.ee) return false; + + this.remove(); + this.ee = null; + + return true; +}; + +// +// Expose the module. +// +module.exports = Ultron; diff --git a/www/node_modules/ultron/package.json b/www/node_modules/ultron/package.json new file mode 100644 index 0000000..28ad834 --- /dev/null +++ b/www/node_modules/ultron/package.json @@ -0,0 +1,100 @@ +{ + "_args": [ + [ + "ultron@1.0.x", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/ws" + ] + ], + "_from": "ultron@>=1.0.0 <1.1.0", + "_id": "ultron@1.0.2", + "_inCache": true, + "_installable": true, + "_location": "/ultron", + "_nodeVersion": "0.12.3", + "_npmUser": { + "email": "npm@3rd-Eden.com", + "name": "3rdeden" + }, + "_npmVersion": "2.9.1", + "_phantomChildren": {}, + "_requested": { + "name": "ultron", + "raw": "ultron@1.0.x", + "rawSpec": "1.0.x", + "scope": null, + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/ws" + ], + "_resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "_shasum": "ace116ab557cd197386a4e88f4685378c8b2e4fa", + "_shrinkwrap": null, + "_spec": "ultron@1.0.x", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/ws", + "author": { + "name": "Arnout Kazemier" + }, + "bugs": { + "url": "https://github.com/unshiftio/ultron/issues" + }, + "dependencies": {}, + "description": "Ultron is high-intelligence robot. It gathers intel so it can start improving upon his rudimentary design", + "devDependencies": { + "assume": "1.2.x", + "eventemitter3": "1.1.x", + "istanbul": "0.3.x", + "mocha": "2.2.x", + "pre-commit": "1.0.x" + }, + "directories": {}, + "dist": { + "shasum": "ace116ab557cd197386a4e88f4685378c8b2e4fa", + "tarball": "http://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz" + }, + "gitHead": "a10482ae98a09120821545456c90c6d60d540f7c", + "homepage": "https://github.com/unshiftio/ultron", + "keywords": [ + "Ultron", + "robot", + "gather", + "intelligence", + "event", + "events", + "eventemitter", + "emitter", + "cleanup" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "email": "npm@unshift.io", + "name": "unshift" + }, + { + "email": "info@3rd-Eden.com", + "name": "v1" + }, + { + "email": "npm@3rd-Eden.com", + "name": "3rdeden" + } + ], + "name": "ultron", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/unshiftio/ultron.git" + }, + "scripts": { + "100%": "istanbul check-coverage --statements 100 --functions 100 --lines 100 --branches 100", + "coverage": "istanbul cover ./node_modules/.bin/_mocha -- test.js", + "test": "mocha test.js", + "test-travis": "istanbul cover node_modules/.bin/_mocha --report lcovonly -- test.js", + "watch": "mocha --watch test.js" + }, + "version": "1.0.2" +} diff --git a/www/node_modules/ultron/test.js b/www/node_modules/ultron/test.js new file mode 100644 index 0000000..1fd4f1b --- /dev/null +++ b/www/node_modules/ultron/test.js @@ -0,0 +1,327 @@ +/* istanbul ignore next */ +describe('Ultron', function () { + 'use strict'; + + var EventEmitter = require('eventemitter3') + , EE = require('events').EventEmitter + , assume = require('assume') + , Ultron = require('./') + , ultron + , ee; + + beforeEach(function () { + ee = new EventEmitter(); + ultron = new Ultron(ee); + }); + + afterEach(function () { + ultron.destroy(); + ee.removeAllListeners(); + }); + + it('is exposed as a function', function () { + assume(Ultron).is.a('function'); + }); + + it('can be initialized without the new keyword', function () { + assume(Ultron(ee)).is.instanceOf(Ultron); + }); + + it('assigns a unique id to every instance', function () { + for (var i = 0; i < 100; i++) { + assume(ultron.id).does.not.equal((new Ultron()).id); + } + }); + + it('allows removal through the event emitter', function () { + function foo() {} + function bar() {} + + ultron.on('foo', foo); + ultron.once('foo', bar); + + assume(foo.__ultron).equals(ultron.id); + assume(bar.__ultron).equals(ultron.id); + assume(ee.listeners('foo').length).equals(2); + + ee.removeListener('foo', foo); + assume(ee.listeners('foo').length).equals(1); + + ee.removeListener('foo', bar); + assume(ee.listeners('foo').length).equals(0); + }); + + describe('#on', function () { + it('assigns a listener', function () { + assume(ee.listeners('foo').length).equals(0); + + function foo() {} + + ultron.on('foo', foo); + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('foo')[0]).equals(foo); + }); + + it('tags the assigned function', function () { + assume(ee.listeners('foo').length).equals(0); + + ultron.on('foo', function () {}); + assume(ee.listeners('foo')[0].__ultron).equals(ultron.id); + }); + + it('also passes in the context', function (next) { + var context = 1313; + + ultron.on('foo', function (a, b, c) { + assume(a).equals('a'); + assume(b).equals('b'); + assume(c).equals('c'); + + assume(this).equals(context); + + next(); + }, context); + + ee.emit('foo', 'a', 'b', 'c'); + }); + + it('works with regular eventemitters as well', function (next) { + var ee = new EE() + , ultron = new Ultron(ee); + + ultron.on('foo', function (a, b, c) { + assume(a).equals('a'); + assume(b).equals('b'); + assume(c).equals('c'); + + next(); + }); + + ee.emit('foo', 'a', 'b', 'c'); + }); + }); + + describe('#once', function () { + it('assigns a listener', function () { + assume(ee.listeners('foo').length).equals(0); + + function foo() {} + ultron.once('foo', foo); + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('foo')[0]).equals(foo); + }); + + it('tags the assigned function', function () { + assume(ee.listeners('foo').length).equals(0); + + ultron.once('foo', function () {}); + assume(ee.listeners('foo')[0].__ultron).equals(ultron.id); + }); + + it('also passes in the context', function (next) { + var context = 1313; + + ultron.once('foo', function (a, b, c) { + assume(a).equals('a'); + assume(b).equals('b'); + assume(c).equals('c'); + + assume(this).equals(context); + + next(); + }, context); + + ee.emit('foo', 'a', 'b', 'c'); + ee.emit('foo', 'a', 'b', 'c'); // Ensure that we don't double execute + }); + + it('works with regular eventemitters as well', function (next) { + var ee = new EE() + , ultron = new Ultron(ee); + + ultron.once('foo', function (a, b, c) { + assume(a).equals('a'); + assume(b).equals('b'); + assume(c).equals('c'); + + next(); + }); + + ee.emit('foo', 'a', 'b', 'c'); + ee.emit('foo', 'a', 'b', 'c'); // Ensure that we don't double execute + }); + }); + + describe('#remove', function () { + it('removes only our assigned `on` listeners', function () { + function foo() {} + function bar() {} + + ee.on('foo', foo); + ultron.on('foo', bar); + assume(ee.listeners('foo').length).equals(2); + + ultron.remove('foo'); + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('foo')[0]).equals(foo); + }); + + it('removes our private __ultron references', function () { + function once() {} + function on() {} + + assume('__ultron' in once).is.false(); + assume('__ultron' in on).is.false(); + + ultron.on('foo', on); + ultron.once('bar', once); + + assume('__ultron' in once).is.true(); + assume('__ultron' in on).is.true(); + + ultron.remove('foo, bar'); + + assume('__ultron' in once).is.false(); + assume('__ultron' in on).is.false(); + + ultron.destroy(); + + ee = new EE(); + ultron = new Ultron(ee); + + assume('__ultron' in once).is.false(); + assume('__ultron' in on).is.false(); + + ultron.on('foo', on); + ultron.once('bar', once); + + assume('__ultron' in once).is.true(); + assume('__ultron' in on).is.true(); + + ultron.remove('foo, bar'); + + assume('__ultron' in once).is.false(); + assume('__ultron' in on).is.false(); + }); + + it('removes only our assigned `once` listeners', function () { + function foo() {} + function bar() {} + + ee.once('foo', foo); + ultron.once('foo', bar); + assume(ee.listeners('foo').length).equals(2); + + ultron.remove('foo'); + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('foo')[0]).equals(foo); + }); + + it('removes only our assigned `once` listeners from regular EE', function () { + var ee = new EE() + , ultron = new Ultron(ee); + + function foo() {} + function bar() {} + + ee.once('foo', foo); + ultron.once('foo', bar); + assume(ee.listeners('foo').length).equals(2); + + ultron.remove('foo'); + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('foo')[0].listener).equals(foo); + }); + + it('removes all assigned events if called without args', function () { + function foo() {} + function bar() {} + + ultron.on('foo', foo); + ultron.on('bar', bar); + + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('bar').length).equals(1); + + ultron.remove(); + + assume(ee.listeners('foo').length).equals(0); + assume(ee.listeners('bar').length).equals(0); + }); + + it('removes multiple listeners based on args', function () { + function foo() {} + function bar() {} + function baz() {} + + ultron.on('foo', foo); + ultron.on('bar', bar); + ultron.on('baz', baz); + + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('bar').length).equals(1); + assume(ee.listeners('baz').length).equals(1); + + ultron.remove('foo', 'bar'); + + assume(ee.listeners('foo').length).equals(0); + assume(ee.listeners('bar').length).equals(0); + assume(ee.listeners('baz').length).equals(1); + }); + + it('removes multiple listeners if first arg is seperated string', function () { + function foo() {} + function bar() {} + function baz() {} + + ultron.on('foo', foo); + ultron.on('bar', bar); + ultron.on('baz', baz); + + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('bar').length).equals(1); + assume(ee.listeners('baz').length).equals(1); + + ultron.remove('foo, bar'); + + assume(ee.listeners('foo').length).equals(0); + assume(ee.listeners('bar').length).equals(0); + assume(ee.listeners('baz').length).equals(1); + }); + }); + + describe('#destroy', function () { + it('removes all listeners', function () { + function foo() {} + function bar() {} + function baz() {} + + ultron.on('foo', foo); + ultron.on('bar', bar); + ultron.on('baz', baz); + + assume(ee.listeners('foo').length).equals(1); + assume(ee.listeners('bar').length).equals(1); + assume(ee.listeners('baz').length).equals(1); + + ultron.destroy(); + + assume(ee.listeners('foo').length).equals(0); + assume(ee.listeners('bar').length).equals(0); + assume(ee.listeners('baz').length).equals(0); + }); + + it('removes the .ee reference', function () { + assume(ultron.ee).equals(ee); + ultron.destroy(); + assume(ultron.ee).equals(null); + }); + + it('returns booleans for state indication', function () { + assume(ultron.destroy()).is.true(); + assume(ultron.destroy()).is.false(); + assume(ultron.destroy()).is.false(); + assume(ultron.destroy()).is.false(); + }); + }); +}); diff --git a/www/node_modules/wrappy/LICENSE b/www/node_modules/wrappy/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/www/node_modules/wrappy/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/www/node_modules/wrappy/README.md b/www/node_modules/wrappy/README.md new file mode 100644 index 0000000..98eab25 --- /dev/null +++ b/www/node_modules/wrappy/README.md @@ -0,0 +1,36 @@ +# wrappy + +Callback wrapping utility + +## USAGE + +```javascript +var wrappy = require("wrappy") + +// var wrapper = wrappy(wrapperFunction) + +// make sure a cb is called only once +// See also: http://npm.im/once for this specific use case +var once = wrappy(function (cb) { + var called = false + return function () { + if (called) return + called = true + return cb.apply(this, arguments) + } +}) + +function printBoo () { + console.log('boo') +} +// has some rando property +printBoo.iAmBooPrinter = true + +var onlyPrintOnce = once(printBoo) + +onlyPrintOnce() // prints 'boo' +onlyPrintOnce() // does nothing + +// random property is retained! +assert.equal(onlyPrintOnce.iAmBooPrinter, true) +``` diff --git a/www/node_modules/wrappy/package.json b/www/node_modules/wrappy/package.json new file mode 100644 index 0000000..7069c85 --- /dev/null +++ b/www/node_modules/wrappy/package.json @@ -0,0 +1,78 @@ +{ + "_args": [ + [ + "wrappy@1", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/inflight" + ] + ], + "_from": "wrappy@>=1.0.0 <2.0.0", + "_id": "wrappy@1.0.1", + "_inCache": true, + "_installable": true, + "_location": "/wrappy", + "_nodeVersion": "0.10.31", + "_npmUser": { + "email": "i@izs.me", + "name": "isaacs" + }, + "_npmVersion": "2.0.0", + "_phantomChildren": {}, + "_requested": { + "name": "wrappy", + "raw": "wrappy@1", + "rawSpec": "1", + "scope": null, + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/inflight", + "/once" + ], + "_resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", + "_shasum": "1e65969965ccbc2db4548c6b84a6f2c5aedd4739", + "_shrinkwrap": null, + "_spec": "wrappy@1", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/inflight", + "author": { + "email": "i@izs.me", + "name": "Isaac Z. Schlueter", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/npm/wrappy/issues" + }, + "dependencies": {}, + "description": "Callback wrapping utility", + "devDependencies": { + "tap": "^0.4.12" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "1e65969965ccbc2db4548c6b84a6f2c5aedd4739", + "tarball": "http://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + }, + "gitHead": "006a8cbac6b99988315834c207896eed71fd069a", + "homepage": "https://github.com/npm/wrappy", + "license": "ISC", + "main": "wrappy.js", + "maintainers": [ + { + "email": "i@izs.me", + "name": "isaacs" + } + ], + "name": "wrappy", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/wrappy.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "1.0.1" +} diff --git a/www/node_modules/wrappy/test/basic.js b/www/node_modules/wrappy/test/basic.js new file mode 100644 index 0000000..5ed0fcd --- /dev/null +++ b/www/node_modules/wrappy/test/basic.js @@ -0,0 +1,51 @@ +var test = require('tap').test +var wrappy = require('../wrappy.js') + +test('basic', function (t) { + function onceifier (cb) { + var called = false + return function () { + if (called) return + called = true + return cb.apply(this, arguments) + } + } + onceifier.iAmOnce = {} + var once = wrappy(onceifier) + t.equal(once.iAmOnce, onceifier.iAmOnce) + + var called = 0 + function boo () { + t.equal(called, 0) + called++ + } + // has some rando property + boo.iAmBoo = true + + var onlyPrintOnce = once(boo) + + onlyPrintOnce() // prints 'boo' + onlyPrintOnce() // does nothing + t.equal(called, 1) + + // random property is retained! + t.equal(onlyPrintOnce.iAmBoo, true) + + var logs = [] + var logwrap = wrappy(function (msg, cb) { + logs.push(msg + ' wrapping cb') + return function () { + logs.push(msg + ' before cb') + var ret = cb.apply(this, arguments) + logs.push(msg + ' after cb') + } + }) + + var c = logwrap('foo', function () { + t.same(logs, [ 'foo wrapping cb', 'foo before cb' ]) + }) + c() + t.same(logs, [ 'foo wrapping cb', 'foo before cb', 'foo after cb' ]) + + t.end() +}) diff --git a/www/node_modules/wrappy/wrappy.js b/www/node_modules/wrappy/wrappy.js new file mode 100644 index 0000000..bb7e7d6 --- /dev/null +++ b/www/node_modules/wrappy/wrappy.js @@ -0,0 +1,33 @@ +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} diff --git a/www/node_modules/ws/.npmignore b/www/node_modules/ws/.npmignore new file mode 100644 index 0000000..1eba800 --- /dev/null +++ b/www/node_modules/ws/.npmignore @@ -0,0 +1,11 @@ +npm-debug.log +node_modules +.*.swp +.lock-* +build + +bench +doc +examples +test + diff --git a/www/node_modules/ws/.travis.yml b/www/node_modules/ws/.travis.yml new file mode 100644 index 0000000..5002b49 --- /dev/null +++ b/www/node_modules/ws/.travis.yml @@ -0,0 +1,15 @@ +language: node_js +sudo: false +node_js: + - "5" + - "4" + - "0.12" +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - gcc-4.9 + - g++-4.9 +before_install: + - export CC="gcc-4.9" CXX="g++-4.9" diff --git a/www/node_modules/ws/Makefile b/www/node_modules/ws/Makefile new file mode 100644 index 0000000..00f19fa --- /dev/null +++ b/www/node_modules/ws/Makefile @@ -0,0 +1,40 @@ +ALL_TESTS = $(shell find test/ -name '*.test.js') +ALL_INTEGRATION = $(shell find test/ -name '*.integration.js') + +all: + node-gyp configure build + +clean: + node-gyp clean + +run-tests: + @./node_modules/.bin/mocha \ + -t 5000 \ + -s 2400 \ + $(TESTFLAGS) \ + $(TESTS) + +run-integrationtests: + @./node_modules/.bin/mocha \ + -t 5000 \ + -s 6000 \ + $(TESTFLAGS) \ + $(TESTS) + +test: + @$(MAKE) NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests + +integrationtest: + @$(MAKE) NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=lib TESTS="$(ALL_INTEGRATION)" run-integrationtests + +benchmark: + @node bench/sender.benchmark.js + @node bench/parser.benchmark.js + +autobahn: + @NODE_PATH=lib node test/autobahn.js + +autobahn-server: + @NODE_PATH=lib node test/autobahn-server.js + +.PHONY: test diff --git a/www/node_modules/ws/README.md b/www/node_modules/ws/README.md new file mode 100644 index 0000000..9be2e51 --- /dev/null +++ b/www/node_modules/ws/README.md @@ -0,0 +1,242 @@ +# ws: a node.js websocket library + +[![Build Status](https://travis-ci.org/websockets/ws.svg?branch=master)](https://travis-ci.org/websockets/ws) + +`ws` is a simple to use WebSocket implementation, up-to-date against RFC-6455, +and [probably the fastest WebSocket library for node.js][archive]. + +Passes the quite extensive Autobahn test suite. See http://websockets.github.com/ws +for the full reports. + +## Protocol support + +* **Hixie draft 76** (Old and deprecated, but still in use by Safari and Opera. + Added to ws version 0.4.2, but server only. Can be disabled by setting the + `disableHixie` option to true.) +* **HyBi drafts 07-12** (Use the option `protocolVersion: 8`) +* **HyBi drafts 13-17** (Current default, alternatively option `protocolVersion: 13`) + +### Installing + +``` +npm install --save ws +``` + +### Opt-in for performance + +There are 2 optional modules that can be installed along side with the `ws` +module. These modules are binary addons which improve certain operations, but as +they are binary addons they require compilation which can fail if no c++ +compiler is installed on the host system. + +- `npm install --save bufferutil`: Improves internal buffer operations which + allows for faster processing of masked WebSocket frames and general buffer + operations. +- `npm install --save utf-8-validate`: The specification requires validation of + invalid UTF-8 chars, some of these validations could not be done in JavaScript + hence the need for a binary addon. In most cases you will already be + validating the input that you receive for security purposes leading to double + validation. But if you want to be 100% spec conform and fast validation of UTF-8 + then this module is a must. + +### Sending and receiving text data + +```js +var WebSocket = require('ws'); +var ws = new WebSocket('ws://www.host.com/path'); + +ws.on('open', function open() { + ws.send('something'); +}); + +ws.on('message', function(data, flags) { + // flags.binary will be set if a binary data is received. + // flags.masked will be set if the data was masked. +}); +``` + +### Sending binary data + +```js +var WebSocket = require('ws'); +var ws = new WebSocket('ws://www.host.com/path'); + +ws.on('open', function open() { + var array = new Float32Array(5); + + for (var i = 0; i < array.length; ++i) { + array[i] = i / 2; + } + + ws.send(array, { binary: true, mask: true }); +}); +``` + +Setting `mask`, as done for the send options above, will cause the data to be +masked according to the WebSocket protocol. The same option applies for text +data. + +### Server example + +```js +var WebSocketServer = require('ws').Server + , wss = new WebSocketServer({ port: 8080 }); + +wss.on('connection', function connection(ws) { + ws.on('message', function incoming(message) { + console.log('received: %s', message); + }); + + ws.send('something'); +}); +``` + +### ExpressJS example + +```js +var server = require('http').createServer() + , url = require('url') + , WebSocketServer = require('ws').Server + , wss = new WebSocketServer({ server: server }) + , express = require('express') + , app = express() + , port = 4080; + +app.use(function (req, res) { + res.send({ msg: "hello" }); +}); + +wss.on('connection', function connection(ws) { + var location = url.parse(ws.upgradeReq.url, true); + // you might use location.query.access_token to authenticate or share sessions + // or ws.upgradeReq.headers.cookie (see http://stackoverflow.com/a/16395220/151312) + + ws.on('message', function incoming(message) { + console.log('received: %s', message); + }); + + ws.send('something'); +}); + +server.on('request', app); +server.listen(port, function () { console.log('Listening on ' + server.address().port) }); +``` + +### Server sending broadcast data + +```js +var WebSocketServer = require('ws').Server + , wss = new WebSocketServer({ port: 8080 }); + +wss.broadcast = function broadcast(data) { + wss.clients.forEach(function each(client) { + client.send(data); + }); +}; +``` + +### Error handling best practices + +```js +// If the WebSocket is closed before the following send is attempted +ws.send('something'); + +// Errors (both immediate and async write errors) can be detected in an optional +// callback. The callback is also the only way of being notified that data has +// actually been sent. +ws.send('something', function ack(error) { + // if error is not defined, the send has been completed, + // otherwise the error object will indicate what failed. +}); + +// Immediate errors can also be handled with try/catch-blocks, but **note** that +// since sends are inherently asynchronous, socket write failures will *not* be +// captured when this technique is used. +try { ws.send('something'); } +catch (e) { /* handle error */ } +``` + +### echo.websocket.org demo + +```js +var WebSocket = require('ws'); +var ws = new WebSocket('ws://echo.websocket.org/', { + protocolVersion: 8, + origin: 'http://websocket.org' +}); + +ws.on('open', function open() { + console.log('connected'); + ws.send(Date.now().toString(), {mask: true}); +}); + +ws.on('close', function close() { + console.log('disconnected'); +}); + +ws.on('message', function message(data, flags) { + console.log('Roundtrip time: ' + (Date.now() - parseInt(data)) + 'ms', flags); + + setTimeout(function timeout() { + ws.send(Date.now().toString(), {mask: true}); + }, 500); +}); +``` + +### Browserify users +When including ws via a browserify bundle, ws returns global.WebSocket which has slightly different API. +You should use the standard WebSockets API instead. + +https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_client_applications#Availability_of_WebSockets + + +### Other examples + +For a full example with a browser client communicating with a ws server, see the +examples folder. + +Note that the usage together with Express 3.0 is quite different from Express +2.x. The difference is expressed in the two different serverstats-examples. + +Otherwise, see the test cases. + +### Running the tests + +``` +make test +``` + +## API Docs + +See [`/doc/ws.md`](https://github.com/websockets/ws/blob/master/doc/ws.md) for Node.js-like docs for the ws classes. + +## Changelog + +We're using the GitHub [`releases`](https://github.com/websockets/ws/releases) for changelog entries. + +## License + +(The MIT License) + +Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +[archive]: http://web.archive.org/web/20130314230536/http://hobbycoding.posterous.com/the-fastest-websocket-module-for-nodejs diff --git a/www/node_modules/ws/index.js b/www/node_modules/ws/index.js new file mode 100644 index 0000000..a7e8644 --- /dev/null +++ b/www/node_modules/ws/index.js @@ -0,0 +1,49 @@ +'use strict'; + +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var WS = module.exports = require('./lib/WebSocket'); + +WS.Server = require('./lib/WebSocketServer'); +WS.Sender = require('./lib/Sender'); +WS.Receiver = require('./lib/Receiver'); + +/** + * Create a new WebSocket server. + * + * @param {Object} options Server options + * @param {Function} fn Optional connection listener. + * @returns {WS.Server} + * @api public + */ +WS.createServer = function createServer(options, fn) { + var server = new WS.Server(options); + + if (typeof fn === 'function') { + server.on('connection', fn); + } + + return server; +}; + +/** + * Create a new WebSocket connection. + * + * @param {String} address The URL/address we need to connect to. + * @param {Function} fn Open listener. + * @returns {WS} + * @api public + */ +WS.connect = WS.createConnection = function connect(address, fn) { + var client = new WS(address); + + if (typeof fn === 'function') { + client.on('open', fn); + } + + return client; +}; diff --git a/www/node_modules/ws/lib/BufferPool.js b/www/node_modules/ws/lib/BufferPool.js new file mode 100644 index 0000000..8ee5990 --- /dev/null +++ b/www/node_modules/ws/lib/BufferPool.js @@ -0,0 +1,63 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util'); + +function BufferPool(initialSize, growStrategy, shrinkStrategy) { + if (this instanceof BufferPool === false) { + throw new TypeError("Classes can't be function-called"); + } + + if (typeof initialSize === 'function') { + shrinkStrategy = growStrategy; + growStrategy = initialSize; + initialSize = 0; + } + else if (typeof initialSize === 'undefined') { + initialSize = 0; + } + this._growStrategy = (growStrategy || function(db, size) { + return db.used + size; + }).bind(null, this); + this._shrinkStrategy = (shrinkStrategy || function(db) { + return initialSize; + }).bind(null, this); + this._buffer = initialSize ? new Buffer(initialSize) : null; + this._offset = 0; + this._used = 0; + this._changeFactor = 0; + this.__defineGetter__('size', function(){ + return this._buffer == null ? 0 : this._buffer.length; + }); + this.__defineGetter__('used', function(){ + return this._used; + }); +} + +BufferPool.prototype.get = function(length) { + if (this._buffer == null || this._offset + length > this._buffer.length) { + var newBuf = new Buffer(this._growStrategy(length)); + this._buffer = newBuf; + this._offset = 0; + } + this._used += length; + var buf = this._buffer.slice(this._offset, this._offset + length); + this._offset += length; + return buf; +} + +BufferPool.prototype.reset = function(forceNewBuffer) { + var len = this._shrinkStrategy(); + if (len < this.size) this._changeFactor -= 1; + if (forceNewBuffer || this._changeFactor < -2) { + this._changeFactor = 0; + this._buffer = len ? new Buffer(len) : null; + } + this._offset = 0; + this._used = 0; +} + +module.exports = BufferPool; diff --git a/www/node_modules/ws/lib/BufferUtil.fallback.js b/www/node_modules/ws/lib/BufferUtil.fallback.js new file mode 100644 index 0000000..508542c --- /dev/null +++ b/www/node_modules/ws/lib/BufferUtil.fallback.js @@ -0,0 +1,47 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +module.exports.BufferUtil = { + merge: function(mergedBuffer, buffers) { + var offset = 0; + for (var i = 0, l = buffers.length; i < l; ++i) { + var buf = buffers[i]; + buf.copy(mergedBuffer, offset); + offset += buf.length; + } + }, + mask: function(source, mask, output, offset, length) { + var maskNum = mask.readUInt32LE(0, true); + var i = 0; + for (; i < length - 3; i += 4) { + var num = maskNum ^ source.readUInt32LE(i, true); + if (num < 0) num = 4294967296 + num; + output.writeUInt32LE(num, offset + i, true); + } + switch (length % 4) { + case 3: output[offset + i + 2] = source[i + 2] ^ mask[2]; + case 2: output[offset + i + 1] = source[i + 1] ^ mask[1]; + case 1: output[offset + i] = source[i] ^ mask[0]; + case 0:; + } + }, + unmask: function(data, mask) { + var maskNum = mask.readUInt32LE(0, true); + var length = data.length; + var i = 0; + for (; i < length - 3; i += 4) { + var num = maskNum ^ data.readUInt32LE(i, true); + if (num < 0) num = 4294967296 + num; + data.writeUInt32LE(num, i, true); + } + switch (length % 4) { + case 3: data[i + 2] = data[i + 2] ^ mask[2]; + case 2: data[i + 1] = data[i + 1] ^ mask[1]; + case 1: data[i] = data[i] ^ mask[0]; + case 0:; + } + } +} diff --git a/www/node_modules/ws/lib/BufferUtil.js b/www/node_modules/ws/lib/BufferUtil.js new file mode 100644 index 0000000..18c6998 --- /dev/null +++ b/www/node_modules/ws/lib/BufferUtil.js @@ -0,0 +1,13 @@ +'use strict'; + +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +try { + module.exports = require('bufferutil'); +} catch (e) { + module.exports = require('./BufferUtil.fallback'); +} diff --git a/www/node_modules/ws/lib/ErrorCodes.js b/www/node_modules/ws/lib/ErrorCodes.js new file mode 100644 index 0000000..55ebd52 --- /dev/null +++ b/www/node_modules/ws/lib/ErrorCodes.js @@ -0,0 +1,24 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +module.exports = { + isValidErrorCode: function(code) { + return (code >= 1000 && code <= 1011 && code != 1004 && code != 1005 && code != 1006) || + (code >= 3000 && code <= 4999); + }, + 1000: 'normal', + 1001: 'going away', + 1002: 'protocol error', + 1003: 'unsupported data', + 1004: 'reserved', + 1005: 'reserved for extensions', + 1006: 'reserved for extensions', + 1007: 'inconsistent or invalid data', + 1008: 'policy violation', + 1009: 'message too big', + 1010: 'extension handshake missing', + 1011: 'an unexpected condition prevented the request from being fulfilled', +}; \ No newline at end of file diff --git a/www/node_modules/ws/lib/Extensions.js b/www/node_modules/ws/lib/Extensions.js new file mode 100644 index 0000000..a465ace --- /dev/null +++ b/www/node_modules/ws/lib/Extensions.js @@ -0,0 +1,70 @@ + +var util = require('util'); + +/** + * Module exports. + */ + +exports.parse = parse; +exports.format = format; + +/** + * Parse extensions header value + */ + +function parse(value) { + value = value || ''; + + var extensions = {}; + + value.split(',').forEach(function(v) { + var params = v.split(';'); + var token = params.shift().trim(); + var paramsList = extensions[token] = extensions[token] || []; + var parsedParams = {}; + + params.forEach(function(param) { + var parts = param.trim().split('='); + var key = parts[0]; + var value = parts[1]; + if (typeof value === 'undefined') { + value = true; + } else { + // unquote value + if (value[0] === '"') { + value = value.slice(1); + } + if (value[value.length - 1] === '"') { + value = value.slice(0, value.length - 1); + } + } + (parsedParams[key] = parsedParams[key] || []).push(value); + }); + + paramsList.push(parsedParams); + }); + + return extensions; +} + +/** + * Format extensions header value + */ + +function format(value) { + return Object.keys(value).map(function(token) { + var paramsList = value[token]; + if (!util.isArray(paramsList)) { + paramsList = [paramsList]; + } + return paramsList.map(function(params) { + return [token].concat(Object.keys(params).map(function(k) { + var p = params[k]; + if (!util.isArray(p)) p = [p]; + return p.map(function(v) { + return v === true ? k : k + '=' + v; + }).join('; '); + })).join('; '); + }).join(', '); + }).join(', '); +} diff --git a/www/node_modules/ws/lib/PerMessageDeflate.js b/www/node_modules/ws/lib/PerMessageDeflate.js new file mode 100644 index 0000000..5324bd8 --- /dev/null +++ b/www/node_modules/ws/lib/PerMessageDeflate.js @@ -0,0 +1,325 @@ + +var zlib = require('zlib'); + +var AVAILABLE_WINDOW_BITS = [8, 9, 10, 11, 12, 13, 14, 15]; +var DEFAULT_WINDOW_BITS = 15; +var DEFAULT_MEM_LEVEL = 8; + +PerMessageDeflate.extensionName = 'permessage-deflate'; + +/** + * Per-message Compression Extensions implementation + */ + +function PerMessageDeflate(options, isServer) { + if (this instanceof PerMessageDeflate === false) { + throw new TypeError("Classes can't be function-called"); + } + + this._options = options || {}; + this._isServer = !!isServer; + this._inflate = null; + this._deflate = null; + this.params = null; +} + +/** + * Create extension parameters offer + * + * @api public + */ + +PerMessageDeflate.prototype.offer = function() { + var params = {}; + if (this._options.serverNoContextTakeover) { + params.server_no_context_takeover = true; + } + if (this._options.clientNoContextTakeover) { + params.client_no_context_takeover = true; + } + if (this._options.serverMaxWindowBits) { + params.server_max_window_bits = this._options.serverMaxWindowBits; + } + if (this._options.clientMaxWindowBits) { + params.client_max_window_bits = this._options.clientMaxWindowBits; + } else if (this._options.clientMaxWindowBits == null) { + params.client_max_window_bits = true; + } + return params; +}; + +/** + * Accept extension offer + * + * @api public + */ + +PerMessageDeflate.prototype.accept = function(paramsList) { + paramsList = this.normalizeParams(paramsList); + + var params; + if (this._isServer) { + params = this.acceptAsServer(paramsList); + } else { + params = this.acceptAsClient(paramsList); + } + + this.params = params; + return params; +}; + +/** + * Releases all resources used by the extension + * + * @api public + */ + +PerMessageDeflate.prototype.cleanup = function() { + if (this._inflate) { + if (this._inflate.writeInProgress) { + this._inflate.pendingClose = true; + } else { + if (this._inflate.close) this._inflate.close(); + this._inflate = null; + } + } + if (this._deflate) { + if (this._deflate.writeInProgress) { + this._deflate.pendingClose = true; + } else { + if (this._deflate.close) this._deflate.close(); + this._deflate = null; + } + } +}; + +/** + * Accept extension offer from client + * + * @api private + */ + +PerMessageDeflate.prototype.acceptAsServer = function(paramsList) { + var accepted = {}; + var result = paramsList.some(function(params) { + accepted = {}; + if (this._options.serverNoContextTakeover === false && params.server_no_context_takeover) { + return; + } + if (this._options.serverMaxWindowBits === false && params.server_max_window_bits) { + return; + } + if (typeof this._options.serverMaxWindowBits === 'number' && + typeof params.server_max_window_bits === 'number' && + this._options.serverMaxWindowBits > params.server_max_window_bits) { + return; + } + if (typeof this._options.clientMaxWindowBits === 'number' && !params.client_max_window_bits) { + return; + } + + if (this._options.serverNoContextTakeover || params.server_no_context_takeover) { + accepted.server_no_context_takeover = true; + } + if (this._options.clientNoContextTakeover) { + accepted.client_no_context_takeover = true; + } + if (this._options.clientNoContextTakeover !== false && params.client_no_context_takeover) { + accepted.client_no_context_takeover = true; + } + if (typeof this._options.serverMaxWindowBits === 'number') { + accepted.server_max_window_bits = this._options.serverMaxWindowBits; + } else if (typeof params.server_max_window_bits === 'number') { + accepted.server_max_window_bits = params.server_max_window_bits; + } + if (typeof this._options.clientMaxWindowBits === 'number') { + accepted.client_max_window_bits = this._options.clientMaxWindowBits; + } else if (this._options.clientMaxWindowBits !== false && typeof params.client_max_window_bits === 'number') { + accepted.client_max_window_bits = params.client_max_window_bits; + } + return true; + }, this); + + if (!result) { + throw new Error('Doesn\'t support the offered configuration'); + } + + return accepted; +}; + +/** + * Accept extension response from server + * + * @api privaye + */ + +PerMessageDeflate.prototype.acceptAsClient = function(paramsList) { + var params = paramsList[0]; + if (this._options.clientNoContextTakeover != null) { + if (this._options.clientNoContextTakeover === false && params.client_no_context_takeover) { + throw new Error('Invalid value for "client_no_context_takeover"'); + } + } + if (this._options.clientMaxWindowBits != null) { + if (this._options.clientMaxWindowBits === false && params.client_max_window_bits) { + throw new Error('Invalid value for "client_max_window_bits"'); + } + if (typeof this._options.clientMaxWindowBits === 'number' && + (!params.client_max_window_bits || params.client_max_window_bits > this._options.clientMaxWindowBits)) { + throw new Error('Invalid value for "client_max_window_bits"'); + } + } + return params; +}; + +/** + * Normalize extensions parameters + * + * @api private + */ + +PerMessageDeflate.prototype.normalizeParams = function(paramsList) { + return paramsList.map(function(params) { + Object.keys(params).forEach(function(key) { + var value = params[key]; + if (value.length > 1) { + throw new Error('Multiple extension parameters for ' + key); + } + + value = value[0]; + + switch (key) { + case 'server_no_context_takeover': + case 'client_no_context_takeover': + if (value !== true) { + throw new Error('invalid extension parameter value for ' + key + ' (' + value + ')'); + } + params[key] = true; + break; + case 'server_max_window_bits': + case 'client_max_window_bits': + if (typeof value === 'string') { + value = parseInt(value, 10); + if (!~AVAILABLE_WINDOW_BITS.indexOf(value)) { + throw new Error('invalid extension parameter value for ' + key + ' (' + value + ')'); + } + } + if (!this._isServer && value === true) { + throw new Error('Missing extension parameter value for ' + key); + } + params[key] = value; + break; + default: + throw new Error('Not defined extension parameter (' + key + ')'); + } + }, this); + return params; + }, this); +}; + +/** + * Decompress message + * + * @api public + */ + +PerMessageDeflate.prototype.decompress = function (data, fin, callback) { + var endpoint = this._isServer ? 'client' : 'server'; + + if (!this._inflate) { + var maxWindowBits = this.params[endpoint + '_max_window_bits']; + this._inflate = zlib.createInflateRaw({ + windowBits: 'number' === typeof maxWindowBits ? maxWindowBits : DEFAULT_WINDOW_BITS + }); + } + this._inflate.writeInProgress = true; + + var self = this; + var buffers = []; + + this._inflate.on('error', onError).on('data', onData); + this._inflate.write(data); + if (fin) { + this._inflate.write(new Buffer([0x00, 0x00, 0xff, 0xff])); + } + this._inflate.flush(function() { + cleanup(); + callback(null, Buffer.concat(buffers)); + }); + + function onError(err) { + cleanup(); + callback(err); + } + + function onData(data) { + buffers.push(data); + } + + function cleanup() { + if (!self._inflate) return; + self._inflate.removeListener('error', onError); + self._inflate.removeListener('data', onData); + self._inflate.writeInProgress = false; + if ((fin && self.params[endpoint + '_no_context_takeover']) || self._inflate.pendingClose) { + if (self._inflate.close) self._inflate.close(); + self._inflate = null; + } + } +}; + +/** + * Compress message + * + * @api public + */ + +PerMessageDeflate.prototype.compress = function (data, fin, callback) { + var endpoint = this._isServer ? 'server' : 'client'; + + if (!this._deflate) { + var maxWindowBits = this.params[endpoint + '_max_window_bits']; + this._deflate = zlib.createDeflateRaw({ + flush: zlib.Z_SYNC_FLUSH, + windowBits: 'number' === typeof maxWindowBits ? maxWindowBits : DEFAULT_WINDOW_BITS, + memLevel: this._options.memLevel || DEFAULT_MEM_LEVEL + }); + } + this._deflate.writeInProgress = true; + + var self = this; + var buffers = []; + + this._deflate.on('error', onError).on('data', onData); + this._deflate.write(data); + this._deflate.flush(function() { + cleanup(); + var data = Buffer.concat(buffers); + if (fin) { + data = data.slice(0, data.length - 4); + } + callback(null, data); + }); + + function onError(err) { + cleanup(); + callback(err); + } + + function onData(data) { + buffers.push(data); + } + + function cleanup() { + if (!self._deflate) return; + self._deflate.removeListener('error', onError); + self._deflate.removeListener('data', onData); + self._deflate.writeInProgress = false; + if ((fin && self.params[endpoint + '_no_context_takeover']) || self._deflate.pendingClose) { + if (self._deflate.close) self._deflate.close(); + self._deflate = null; + } + } +}; + +module.exports = PerMessageDeflate; diff --git a/www/node_modules/ws/lib/Receiver.hixie.js b/www/node_modules/ws/lib/Receiver.hixie.js new file mode 100644 index 0000000..66bc561 --- /dev/null +++ b/www/node_modules/ws/lib/Receiver.hixie.js @@ -0,0 +1,184 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util'); + +/** + * State constants + */ + +var EMPTY = 0 + , BODY = 1; +var BINARYLENGTH = 2 + , BINARYBODY = 3; + +/** + * Hixie Receiver implementation + */ + +function Receiver () { + if (this instanceof Receiver === false) { + throw new TypeError("Classes can't be function-called"); + } + + this.state = EMPTY; + this.buffers = []; + this.messageEnd = -1; + this.spanLength = 0; + this.dead = false; + + this.onerror = function() {}; + this.ontext = function() {}; + this.onbinary = function() {}; + this.onclose = function() {}; + this.onping = function() {}; + this.onpong = function() {}; +} + +module.exports = Receiver; + +/** + * Add new data to the parser. + * + * @api public + */ + +Receiver.prototype.add = function(data) { + var self = this; + function doAdd() { + if (self.state === EMPTY) { + if (data.length == 2 && data[0] == 0xFF && data[1] == 0x00) { + self.reset(); + self.onclose(); + return; + } + if (data[0] === 0x80) { + self.messageEnd = 0; + self.state = BINARYLENGTH; + data = data.slice(1); + } else { + + if (data[0] !== 0x00) { + self.error('payload must start with 0x00 byte', true); + return; + } + data = data.slice(1); + self.state = BODY; + + } + } + if (self.state === BINARYLENGTH) { + var i = 0; + while ((i < data.length) && (data[i] & 0x80)) { + self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f); + ++i; + } + if (i < data.length) { + self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f); + self.state = BINARYBODY; + ++i; + } + if (i > 0) + data = data.slice(i); + } + if (self.state === BINARYBODY) { + var dataleft = self.messageEnd - self.spanLength; + if (data.length >= dataleft) { + // consume the whole buffer to finish the frame + self.buffers.push(data); + self.spanLength += dataleft; + self.messageEnd = dataleft; + return self.parse(); + } + // frame's not done even if we consume it all + self.buffers.push(data); + self.spanLength += data.length; + return; + } + self.buffers.push(data); + if ((self.messageEnd = bufferIndex(data, 0xFF)) != -1) { + self.spanLength += self.messageEnd; + return self.parse(); + } + else self.spanLength += data.length; + } + while(data) data = doAdd(); +}; + +/** + * Releases all resources used by the receiver. + * + * @api public + */ + +Receiver.prototype.cleanup = function() { + this.dead = true; + this.state = EMPTY; + this.buffers = []; +}; + +/** + * Process buffered data. + * + * @api public + */ + +Receiver.prototype.parse = function() { + var output = new Buffer(this.spanLength); + var outputIndex = 0; + for (var bi = 0, bl = this.buffers.length; bi < bl - 1; ++bi) { + var buffer = this.buffers[bi]; + buffer.copy(output, outputIndex); + outputIndex += buffer.length; + } + var lastBuffer = this.buffers[this.buffers.length - 1]; + if (this.messageEnd > 0) lastBuffer.copy(output, outputIndex, 0, this.messageEnd); + if (this.state !== BODY) --this.messageEnd; + var tail = null; + if (this.messageEnd < lastBuffer.length - 1) { + tail = lastBuffer.slice(this.messageEnd + 1); + } + this.reset(); + this.ontext(output.toString('utf8')); + return tail; +}; + +/** + * Handles an error + * + * @api private + */ + +Receiver.prototype.error = function (reason, terminate) { + this.reset(); + this.onerror(reason, terminate); + return this; +}; + +/** + * Reset parser state + * + * @api private + */ + +Receiver.prototype.reset = function (reason) { + if (this.dead) return; + this.state = EMPTY; + this.buffers = []; + this.messageEnd = -1; + this.spanLength = 0; +}; + +/** + * Internal api + */ + +function bufferIndex(buffer, byte) { + for (var i = 0, l = buffer.length; i < l; ++i) { + if (buffer[i] === byte) return i; + } + return -1; +} diff --git a/www/node_modules/ws/lib/Receiver.js b/www/node_modules/ws/lib/Receiver.js new file mode 100644 index 0000000..b3183bf --- /dev/null +++ b/www/node_modules/ws/lib/Receiver.js @@ -0,0 +1,702 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util') + , Validation = require('./Validation').Validation + , ErrorCodes = require('./ErrorCodes') + , BufferPool = require('./BufferPool') + , bufferUtil = require('./BufferUtil').BufferUtil + , PerMessageDeflate = require('./PerMessageDeflate'); + +/** + * HyBi Receiver implementation + */ + +function Receiver (extensions) { + if (this instanceof Receiver === false) { + throw new TypeError("Classes can't be function-called"); + } + + // memory pool for fragmented messages + var fragmentedPoolPrevUsed = -1; + this.fragmentedBufferPool = new BufferPool(1024, function(db, length) { + return db.used + length; + }, function(db) { + return fragmentedPoolPrevUsed = fragmentedPoolPrevUsed >= 0 ? + Math.ceil((fragmentedPoolPrevUsed + db.used) / 2) : + db.used; + }); + + // memory pool for unfragmented messages + var unfragmentedPoolPrevUsed = -1; + this.unfragmentedBufferPool = new BufferPool(1024, function(db, length) { + return db.used + length; + }, function(db) { + return unfragmentedPoolPrevUsed = unfragmentedPoolPrevUsed >= 0 ? + Math.ceil((unfragmentedPoolPrevUsed + db.used) / 2) : + db.used; + }); + + this.extensions = extensions || {}; + this.state = { + activeFragmentedOperation: null, + lastFragment: false, + masked: false, + opcode: 0, + fragmentedOperation: false + }; + this.overflow = []; + this.headerBuffer = new Buffer(10); + this.expectOffset = 0; + this.expectBuffer = null; + this.expectHandler = null; + this.currentMessage = []; + this.messageHandlers = []; + this.expectHeader(2, this.processPacket); + this.dead = false; + this.processing = false; + + this.onerror = function() {}; + this.ontext = function() {}; + this.onbinary = function() {}; + this.onclose = function() {}; + this.onping = function() {}; + this.onpong = function() {}; +} + +module.exports = Receiver; + +/** + * Add new data to the parser. + * + * @api public + */ + +Receiver.prototype.add = function(data) { + var dataLength = data.length; + if (dataLength == 0) return; + if (this.expectBuffer == null) { + this.overflow.push(data); + return; + } + var toRead = Math.min(dataLength, this.expectBuffer.length - this.expectOffset); + fastCopy(toRead, data, this.expectBuffer, this.expectOffset); + this.expectOffset += toRead; + if (toRead < dataLength) { + this.overflow.push(data.slice(toRead)); + } + while (this.expectBuffer && this.expectOffset == this.expectBuffer.length) { + var bufferForHandler = this.expectBuffer; + this.expectBuffer = null; + this.expectOffset = 0; + this.expectHandler.call(this, bufferForHandler); + } +}; + +/** + * Releases all resources used by the receiver. + * + * @api public + */ + +Receiver.prototype.cleanup = function() { + this.dead = true; + this.overflow = null; + this.headerBuffer = null; + this.expectBuffer = null; + this.expectHandler = null; + this.unfragmentedBufferPool = null; + this.fragmentedBufferPool = null; + this.state = null; + this.currentMessage = null; + this.onerror = null; + this.ontext = null; + this.onbinary = null; + this.onclose = null; + this.onping = null; + this.onpong = null; +}; + +/** + * Waits for a certain amount of header bytes to be available, then fires a callback. + * + * @api private + */ + +Receiver.prototype.expectHeader = function(length, handler) { + if (length == 0) { + handler(null); + return; + } + this.expectBuffer = this.headerBuffer.slice(this.expectOffset, this.expectOffset + length); + this.expectHandler = handler; + var toRead = length; + while (toRead > 0 && this.overflow.length > 0) { + var fromOverflow = this.overflow.pop(); + if (toRead < fromOverflow.length) this.overflow.push(fromOverflow.slice(toRead)); + var read = Math.min(fromOverflow.length, toRead); + fastCopy(read, fromOverflow, this.expectBuffer, this.expectOffset); + this.expectOffset += read; + toRead -= read; + } +}; + +/** + * Waits for a certain amount of data bytes to be available, then fires a callback. + * + * @api private + */ + +Receiver.prototype.expectData = function(length, handler) { + if (length == 0) { + handler(null); + return; + } + this.expectBuffer = this.allocateFromPool(length, this.state.fragmentedOperation); + this.expectHandler = handler; + var toRead = length; + while (toRead > 0 && this.overflow.length > 0) { + var fromOverflow = this.overflow.pop(); + if (toRead < fromOverflow.length) this.overflow.push(fromOverflow.slice(toRead)); + var read = Math.min(fromOverflow.length, toRead); + fastCopy(read, fromOverflow, this.expectBuffer, this.expectOffset); + this.expectOffset += read; + toRead -= read; + } +}; + +/** + * Allocates memory from the buffer pool. + * + * @api private + */ + +Receiver.prototype.allocateFromPool = function(length, isFragmented) { + return (isFragmented ? this.fragmentedBufferPool : this.unfragmentedBufferPool).get(length); +}; + +/** + * Start processing a new packet. + * + * @api private + */ + +Receiver.prototype.processPacket = function (data) { + if (this.extensions[PerMessageDeflate.extensionName]) { + if ((data[0] & 0x30) != 0) { + this.error('reserved fields (2, 3) must be empty', 1002); + return; + } + } else { + if ((data[0] & 0x70) != 0) { + this.error('reserved fields must be empty', 1002); + return; + } + } + this.state.lastFragment = (data[0] & 0x80) == 0x80; + this.state.masked = (data[1] & 0x80) == 0x80; + var compressed = (data[0] & 0x40) == 0x40; + var opcode = data[0] & 0xf; + if (opcode === 0) { + if (compressed) { + this.error('continuation frame cannot have the Per-message Compressed bits', 1002); + return; + } + // continuation frame + this.state.fragmentedOperation = true; + this.state.opcode = this.state.activeFragmentedOperation; + if (!(this.state.opcode == 1 || this.state.opcode == 2)) { + this.error('continuation frame cannot follow current opcode', 1002); + return; + } + } + else { + if (opcode < 3 && this.state.activeFragmentedOperation != null) { + this.error('data frames after the initial data frame must have opcode 0', 1002); + return; + } + if (opcode >= 8 && compressed) { + this.error('control frames cannot have the Per-message Compressed bits', 1002); + return; + } + this.state.compressed = compressed; + this.state.opcode = opcode; + if (this.state.lastFragment === false) { + this.state.fragmentedOperation = true; + this.state.activeFragmentedOperation = opcode; + } + else this.state.fragmentedOperation = false; + } + var handler = opcodes[this.state.opcode]; + if (typeof handler == 'undefined') this.error('no handler for opcode ' + this.state.opcode, 1002); + else { + handler.start.call(this, data); + } +}; + +/** + * Endprocessing a packet. + * + * @api private + */ + +Receiver.prototype.endPacket = function() { + if (!this.state.fragmentedOperation) this.unfragmentedBufferPool.reset(true); + else if (this.state.lastFragment) this.fragmentedBufferPool.reset(true); + this.expectOffset = 0; + this.expectBuffer = null; + this.expectHandler = null; + if (this.state.lastFragment && this.state.opcode === this.state.activeFragmentedOperation) { + // end current fragmented operation + this.state.activeFragmentedOperation = null; + } + this.state.lastFragment = false; + this.state.opcode = this.state.activeFragmentedOperation != null ? this.state.activeFragmentedOperation : 0; + this.state.masked = false; + this.expectHeader(2, this.processPacket); +}; + +/** + * Reset the parser state. + * + * @api private + */ + +Receiver.prototype.reset = function() { + if (this.dead) return; + this.state = { + activeFragmentedOperation: null, + lastFragment: false, + masked: false, + opcode: 0, + fragmentedOperation: false + }; + this.fragmentedBufferPool.reset(true); + this.unfragmentedBufferPool.reset(true); + this.expectOffset = 0; + this.expectBuffer = null; + this.expectHandler = null; + this.overflow = []; + this.currentMessage = []; + this.messageHandlers = []; +}; + +/** + * Unmask received data. + * + * @api private + */ + +Receiver.prototype.unmask = function (mask, buf, binary) { + if (mask != null && buf != null) bufferUtil.unmask(buf, mask); + if (binary) return buf; + return buf != null ? buf.toString('utf8') : ''; +}; + +/** + * Concatenates a list of buffers. + * + * @api private + */ + +Receiver.prototype.concatBuffers = function(buffers) { + var length = 0; + for (var i = 0, l = buffers.length; i < l; ++i) length += buffers[i].length; + var mergedBuffer = new Buffer(length); + bufferUtil.merge(mergedBuffer, buffers); + return mergedBuffer; +}; + +/** + * Handles an error + * + * @api private + */ + +Receiver.prototype.error = function (reason, protocolErrorCode) { + this.reset(); + this.onerror(reason, protocolErrorCode); + return this; +}; + +/** + * Execute message handler buffers + * + * @api private + */ + +Receiver.prototype.flush = function() { + if (this.processing || this.dead) return; + + var handler = this.messageHandlers.shift(); + if (!handler) return; + + this.processing = true; + var self = this; + + handler(function() { + self.processing = false; + self.flush(); + }); +}; + +/** + * Apply extensions to message + * + * @api private + */ + +Receiver.prototype.applyExtensions = function(messageBuffer, fin, compressed, callback) { + var self = this; + if (compressed) { + this.extensions[PerMessageDeflate.extensionName].decompress(messageBuffer, fin, function(err, buffer) { + if (self.dead) return; + if (err) { + callback(new Error('invalid compressed data')); + return; + } + callback(null, buffer); + }); + } else { + callback(null, messageBuffer); + } +}; + +/** + * Buffer utilities + */ + +function readUInt16BE(start) { + return (this[start]<<8) + + this[start+1]; +} + +function readUInt32BE(start) { + return (this[start]<<24) + + (this[start+1]<<16) + + (this[start+2]<<8) + + this[start+3]; +} + +function fastCopy(length, srcBuffer, dstBuffer, dstOffset) { + switch (length) { + default: srcBuffer.copy(dstBuffer, dstOffset, 0, length); break; + case 16: dstBuffer[dstOffset+15] = srcBuffer[15]; + case 15: dstBuffer[dstOffset+14] = srcBuffer[14]; + case 14: dstBuffer[dstOffset+13] = srcBuffer[13]; + case 13: dstBuffer[dstOffset+12] = srcBuffer[12]; + case 12: dstBuffer[dstOffset+11] = srcBuffer[11]; + case 11: dstBuffer[dstOffset+10] = srcBuffer[10]; + case 10: dstBuffer[dstOffset+9] = srcBuffer[9]; + case 9: dstBuffer[dstOffset+8] = srcBuffer[8]; + case 8: dstBuffer[dstOffset+7] = srcBuffer[7]; + case 7: dstBuffer[dstOffset+6] = srcBuffer[6]; + case 6: dstBuffer[dstOffset+5] = srcBuffer[5]; + case 5: dstBuffer[dstOffset+4] = srcBuffer[4]; + case 4: dstBuffer[dstOffset+3] = srcBuffer[3]; + case 3: dstBuffer[dstOffset+2] = srcBuffer[2]; + case 2: dstBuffer[dstOffset+1] = srcBuffer[1]; + case 1: dstBuffer[dstOffset] = srcBuffer[0]; + } +} + +function clone(obj) { + var cloned = {}; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + cloned[k] = obj[k]; + } + } + return cloned; +} + +/** + * Opcode handlers + */ + +var opcodes = { + // text + '1': { + start: function(data) { + var self = this; + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['1'].getData.call(self, firstLength); + } + else if (firstLength == 126) { + self.expectHeader(2, function(data) { + opcodes['1'].getData.call(self, readUInt16BE.call(data, 0)); + }); + } + else if (firstLength == 127) { + self.expectHeader(8, function(data) { + if (readUInt32BE.call(data, 0) != 0) { + self.error('packets with length spanning more than 32 bit is currently not supported', 1008); + return; + } + opcodes['1'].getData.call(self, readUInt32BE.call(data, 4)); + }); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['1'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['1'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var self = this; + var packet = this.unmask(mask, data, true) || new Buffer(0); + var state = clone(this.state); + this.messageHandlers.push(function(callback) { + self.applyExtensions(packet, state.lastFragment, state.compressed, function(err, buffer) { + if (err) return self.error(err.message, 1007); + if (buffer != null) self.currentMessage.push(buffer); + + if (state.lastFragment) { + var messageBuffer = self.concatBuffers(self.currentMessage); + self.currentMessage = []; + if (!Validation.isValidUTF8(messageBuffer)) { + self.error('invalid utf8 sequence', 1007); + return; + } + self.ontext(messageBuffer.toString('utf8'), {masked: state.masked, buffer: messageBuffer}); + } + callback(); + }); + }); + this.flush(); + this.endPacket(); + } + }, + // binary + '2': { + start: function(data) { + var self = this; + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['2'].getData.call(self, firstLength); + } + else if (firstLength == 126) { + self.expectHeader(2, function(data) { + opcodes['2'].getData.call(self, readUInt16BE.call(data, 0)); + }); + } + else if (firstLength == 127) { + self.expectHeader(8, function(data) { + if (readUInt32BE.call(data, 0) != 0) { + self.error('packets with length spanning more than 32 bit is currently not supported', 1008); + return; + } + opcodes['2'].getData.call(self, readUInt32BE.call(data, 4, true)); + }); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['2'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['2'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var self = this; + var packet = this.unmask(mask, data, true) || new Buffer(0); + var state = clone(this.state); + this.messageHandlers.push(function(callback) { + self.applyExtensions(packet, state.lastFragment, state.compressed, function(err, buffer) { + if (err) return self.error(err.message, 1007); + if (buffer != null) self.currentMessage.push(buffer); + if (state.lastFragment) { + var messageBuffer = self.concatBuffers(self.currentMessage); + self.currentMessage = []; + self.onbinary(messageBuffer, {masked: state.masked, buffer: messageBuffer}); + } + callback(); + }); + }); + this.flush(); + this.endPacket(); + } + }, + // close + '8': { + start: function(data) { + var self = this; + if (self.state.lastFragment == false) { + self.error('fragmented close is not supported', 1002); + return; + } + + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['8'].getData.call(self, firstLength); + } + else { + self.error('control frames cannot have more than 125 bytes of data', 1002); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['8'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['8'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var self = this; + data = self.unmask(mask, data, true); + + var state = clone(this.state); + this.messageHandlers.push(function() { + if (data && data.length == 1) { + self.error('close packets with data must be at least two bytes long', 1002); + return; + } + var code = data && data.length > 1 ? readUInt16BE.call(data, 0) : 1000; + if (!ErrorCodes.isValidErrorCode(code)) { + self.error('invalid error code', 1002); + return; + } + var message = ''; + if (data && data.length > 2) { + var messageBuffer = data.slice(2); + if (!Validation.isValidUTF8(messageBuffer)) { + self.error('invalid utf8 sequence', 1007); + return; + } + message = messageBuffer.toString('utf8'); + } + self.onclose(code, message, {masked: state.masked}); + self.reset(); + }); + this.flush(); + }, + }, + // ping + '9': { + start: function(data) { + var self = this; + if (self.state.lastFragment == false) { + self.error('fragmented ping is not supported', 1002); + return; + } + + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['9'].getData.call(self, firstLength); + } + else { + self.error('control frames cannot have more than 125 bytes of data', 1002); + } + }, + getData: function(length) { + var self = this; + if (self.state.masked) { + self.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['9'].finish.call(self, mask, data); + }); + }); + } + else { + self.expectData(length, function(data) { + opcodes['9'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var self = this; + data = this.unmask(mask, data, true); + var state = clone(this.state); + this.messageHandlers.push(function(callback) { + self.onping(data, {masked: state.masked, binary: true}); + callback(); + }); + this.flush(); + this.endPacket(); + } + }, + // pong + '10': { + start: function(data) { + var self = this; + if (self.state.lastFragment == false) { + self.error('fragmented pong is not supported', 1002); + return; + } + + // decode length + var firstLength = data[1] & 0x7f; + if (firstLength < 126) { + opcodes['10'].getData.call(self, firstLength); + } + else { + self.error('control frames cannot have more than 125 bytes of data', 1002); + } + }, + getData: function(length) { + var self = this; + if (this.state.masked) { + this.expectHeader(4, function(data) { + var mask = data; + self.expectData(length, function(data) { + opcodes['10'].finish.call(self, mask, data); + }); + }); + } + else { + this.expectData(length, function(data) { + opcodes['10'].finish.call(self, null, data); + }); + } + }, + finish: function(mask, data) { + var self = this; + data = self.unmask(mask, data, true); + var state = clone(this.state); + this.messageHandlers.push(function(callback) { + self.onpong(data, {masked: state.masked, binary: true}); + callback(); + }); + this.flush(); + this.endPacket(); + } + } +} diff --git a/www/node_modules/ws/lib/Sender.hixie.js b/www/node_modules/ws/lib/Sender.hixie.js new file mode 100644 index 0000000..b87d9dd --- /dev/null +++ b/www/node_modules/ws/lib/Sender.hixie.js @@ -0,0 +1,124 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var events = require('events') + , util = require('util') + , EventEmitter = events.EventEmitter; + +/** + * Hixie Sender implementation + */ + +function Sender(socket) { + if (this instanceof Sender === false) { + throw new TypeError("Classes can't be function-called"); + } + + events.EventEmitter.call(this); + + this.socket = socket; + this.continuationFrame = false; + this.isClosed = false; +} + +module.exports = Sender; + +/** + * Inherits from EventEmitter. + */ + +util.inherits(Sender, events.EventEmitter); + +/** + * Frames and writes data. + * + * @api public + */ + +Sender.prototype.send = function(data, options, cb) { + if (this.isClosed) return; + + var isString = typeof data == 'string' + , length = isString ? Buffer.byteLength(data) : data.length + , lengthbytes = (length > 127) ? 2 : 1 // assume less than 2**14 bytes + , writeStartMarker = this.continuationFrame == false + , writeEndMarker = !options || !(typeof options.fin != 'undefined' && !options.fin) + , buffer = new Buffer((writeStartMarker ? ((options && options.binary) ? (1 + lengthbytes) : 1) : 0) + length + ((writeEndMarker && !(options && options.binary)) ? 1 : 0)) + , offset = writeStartMarker ? 1 : 0; + + if (writeStartMarker) { + if (options && options.binary) { + buffer.write('\x80', 'binary'); + // assume length less than 2**14 bytes + if (lengthbytes > 1) + buffer.write(String.fromCharCode(128+length/128), offset++, 'binary'); + buffer.write(String.fromCharCode(length&0x7f), offset++, 'binary'); + } else + buffer.write('\x00', 'binary'); + } + + if (isString) buffer.write(data, offset, 'utf8'); + else data.copy(buffer, offset, 0); + + if (writeEndMarker) { + if (options && options.binary) { + // sending binary, not writing end marker + } else + buffer.write('\xff', offset + length, 'binary'); + this.continuationFrame = false; + } + else this.continuationFrame = true; + + try { + this.socket.write(buffer, 'binary', cb); + } catch (e) { + this.error(e.toString()); + } +}; + +/** + * Sends a close instruction to the remote party. + * + * @api public + */ + +Sender.prototype.close = function(code, data, mask, cb) { + if (this.isClosed) return; + this.isClosed = true; + try { + if (this.continuationFrame) this.socket.write(new Buffer([0xff], 'binary')); + this.socket.write(new Buffer([0xff, 0x00]), 'binary', cb); + } catch (e) { + this.error(e.toString()); + } +}; + +/** + * Sends a ping message to the remote party. Not available for hixie. + * + * @api public + */ + +Sender.prototype.ping = function(data, options) {}; + +/** + * Sends a pong message to the remote party. Not available for hixie. + * + * @api public + */ + +Sender.prototype.pong = function(data, options) {}; + +/** + * Handles an error + * + * @api private + */ + +Sender.prototype.error = function (reason) { + this.emit('error', reason); + return this; +}; diff --git a/www/node_modules/ws/lib/Sender.js b/www/node_modules/ws/lib/Sender.js new file mode 100644 index 0000000..d34061e --- /dev/null +++ b/www/node_modules/ws/lib/Sender.js @@ -0,0 +1,324 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var events = require('events') + , util = require('util') + , EventEmitter = events.EventEmitter + , ErrorCodes = require('./ErrorCodes') + , bufferUtil = require('./BufferUtil').BufferUtil + , PerMessageDeflate = require('./PerMessageDeflate'); + +/** + * HyBi Sender implementation + */ + +function Sender(socket, extensions) { + if (this instanceof Sender === false) { + throw new TypeError("Classes can't be function-called"); + } + + events.EventEmitter.call(this); + + this._socket = socket; + this.extensions = extensions || {}; + this.firstFragment = true; + this.compress = false; + this.messageHandlers = []; + this.processing = false; +} + +/** + * Inherits from EventEmitter. + */ + +util.inherits(Sender, events.EventEmitter); + +/** + * Sends a close instruction to the remote party. + * + * @api public + */ + +Sender.prototype.close = function(code, data, mask, cb) { + if (typeof code !== 'undefined') { + if (typeof code !== 'number' || + !ErrorCodes.isValidErrorCode(code)) throw new Error('first argument must be a valid error code number'); + } + code = code || 1000; + var dataBuffer = new Buffer(2 + (data ? Buffer.byteLength(data) : 0)); + writeUInt16BE.call(dataBuffer, code, 0); + if (dataBuffer.length > 2) dataBuffer.write(data, 2); + + var self = this; + this.messageHandlers.push(function(callback) { + self.frameAndSend(0x8, dataBuffer, true, mask); + callback(); + if (typeof cb == 'function') cb(); + }); + this.flush(); +}; + +/** + * Sends a ping message to the remote party. + * + * @api public + */ + +Sender.prototype.ping = function(data, options) { + var mask = options && options.mask; + var self = this; + this.messageHandlers.push(function(callback) { + self.frameAndSend(0x9, data || '', true, mask); + callback(); + }); + this.flush(); +}; + +/** + * Sends a pong message to the remote party. + * + * @api public + */ + +Sender.prototype.pong = function(data, options) { + var mask = options && options.mask; + var self = this; + this.messageHandlers.push(function(callback) { + self.frameAndSend(0xa, data || '', true, mask); + callback(); + }); + this.flush(); +}; + +/** + * Sends text or binary data to the remote party. + * + * @api public + */ + +Sender.prototype.send = function(data, options, cb) { + var finalFragment = options && options.fin === false ? false : true; + var mask = options && options.mask; + var compress = options && options.compress; + var opcode = options && options.binary ? 2 : 1; + if (this.firstFragment === false) { + opcode = 0; + compress = false; + } else { + this.firstFragment = false; + this.compress = compress; + } + if (finalFragment) this.firstFragment = true + + var compressFragment = this.compress; + + var self = this; + this.messageHandlers.push(function(callback) { + self.applyExtensions(data, finalFragment, compressFragment, function(err, data) { + if (err) { + if (typeof cb == 'function') cb(err); + else self.emit('error', err); + return; + } + self.frameAndSend(opcode, data, finalFragment, mask, compress, cb); + callback(); + }); + }); + this.flush(); +}; + +/** + * Frames and sends a piece of data according to the HyBi WebSocket protocol. + * + * @api private + */ + +Sender.prototype.frameAndSend = function(opcode, data, finalFragment, maskData, compressed, cb) { + var canModifyData = false; + + if (!data) { + try { + this._socket.write(new Buffer([opcode | (finalFragment ? 0x80 : 0), 0 | (maskData ? 0x80 : 0)].concat(maskData ? [0, 0, 0, 0] : [])), 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + return; + } + + if (!Buffer.isBuffer(data)) { + canModifyData = true; + if (data && (typeof data.byteLength !== 'undefined' || typeof data.buffer !== 'undefined')) { + data = getArrayBuffer(data); + } else { + // + // If people want to send a number, this would allocate the number in + // bytes as memory size instead of storing the number as buffer value. So + // we need to transform it to string in order to prevent possible + // vulnerabilities / memory attacks. + // + if (typeof data === 'number') data = data.toString(); + + data = new Buffer(data); + } + } + + var dataLength = data.length + , dataOffset = maskData ? 6 : 2 + , secondByte = dataLength; + + if (dataLength >= 65536) { + dataOffset += 8; + secondByte = 127; + } + else if (dataLength > 125) { + dataOffset += 2; + secondByte = 126; + } + + var mergeBuffers = dataLength < 32768 || (maskData && !canModifyData); + var totalLength = mergeBuffers ? dataLength + dataOffset : dataOffset; + var outputBuffer = new Buffer(totalLength); + outputBuffer[0] = finalFragment ? opcode | 0x80 : opcode; + if (compressed) outputBuffer[0] |= 0x40; + + switch (secondByte) { + case 126: + writeUInt16BE.call(outputBuffer, dataLength, 2); + break; + case 127: + writeUInt32BE.call(outputBuffer, 0, 2); + writeUInt32BE.call(outputBuffer, dataLength, 6); + } + + if (maskData) { + outputBuffer[1] = secondByte | 0x80; + var mask = this._randomMask || (this._randomMask = getRandomMask()); + outputBuffer[dataOffset - 4] = mask[0]; + outputBuffer[dataOffset - 3] = mask[1]; + outputBuffer[dataOffset - 2] = mask[2]; + outputBuffer[dataOffset - 1] = mask[3]; + if (mergeBuffers) { + bufferUtil.mask(data, mask, outputBuffer, dataOffset, dataLength); + try { + this._socket.write(outputBuffer, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + else { + bufferUtil.mask(data, mask, data, 0, dataLength); + try { + this._socket.write(outputBuffer, 'binary'); + this._socket.write(data, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + } + else { + outputBuffer[1] = secondByte; + if (mergeBuffers) { + data.copy(outputBuffer, dataOffset); + try { + this._socket.write(outputBuffer, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + else { + try { + this._socket.write(outputBuffer, 'binary'); + this._socket.write(data, 'binary', cb); + } + catch (e) { + if (typeof cb == 'function') cb(e); + else this.emit('error', e); + } + } + } +}; + +/** + * Execute message handler buffers + * + * @api private + */ + +Sender.prototype.flush = function() { + if (this.processing) return; + + var handler = this.messageHandlers.shift(); + if (!handler) return; + + this.processing = true; + + var self = this; + + handler(function() { + self.processing = false; + self.flush(); + }); +}; + +/** + * Apply extensions to message + * + * @api private + */ + +Sender.prototype.applyExtensions = function(data, fin, compress, callback) { + if (compress && data) { + if ((data.buffer || data) instanceof ArrayBuffer) { + data = getArrayBuffer(data); + } + this.extensions[PerMessageDeflate.extensionName].compress(data, fin, callback); + } else { + callback(null, data); + } +}; + +module.exports = Sender; + +function writeUInt16BE(value, offset) { + this[offset] = (value & 0xff00)>>8; + this[offset+1] = value & 0xff; +} + +function writeUInt32BE(value, offset) { + this[offset] = (value & 0xff000000)>>24; + this[offset+1] = (value & 0xff0000)>>16; + this[offset+2] = (value & 0xff00)>>8; + this[offset+3] = value & 0xff; +} + +function getArrayBuffer(data) { + // data is either an ArrayBuffer or ArrayBufferView. + var array = new Uint8Array(data.buffer || data) + , l = data.byteLength || data.length + , o = data.byteOffset || 0 + , buffer = new Buffer(l); + for (var i = 0; i < l; ++i) { + buffer[i] = array[o+i]; + } + return buffer; +} + +function getRandomMask() { + return new Buffer([ + ~~(Math.random() * 255), + ~~(Math.random() * 255), + ~~(Math.random() * 255), + ~~(Math.random() * 255) + ]); +} diff --git a/www/node_modules/ws/lib/Validation.fallback.js b/www/node_modules/ws/lib/Validation.fallback.js new file mode 100644 index 0000000..2c7c4fd --- /dev/null +++ b/www/node_modules/ws/lib/Validation.fallback.js @@ -0,0 +1,12 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +module.exports.Validation = { + isValidUTF8: function(buffer) { + return true; + } +}; + diff --git a/www/node_modules/ws/lib/Validation.js b/www/node_modules/ws/lib/Validation.js new file mode 100644 index 0000000..0795fb7 --- /dev/null +++ b/www/node_modules/ws/lib/Validation.js @@ -0,0 +1,13 @@ +'use strict'; + +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +try { + module.exports = require('utf-8-validate'); +} catch (e) { + module.exports = require('./Validation.fallback'); +} diff --git a/www/node_modules/ws/lib/WebSocket.js b/www/node_modules/ws/lib/WebSocket.js new file mode 100644 index 0000000..4e06c80 --- /dev/null +++ b/www/node_modules/ws/lib/WebSocket.js @@ -0,0 +1,965 @@ +'use strict'; + +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var url = require('url') + , util = require('util') + , http = require('http') + , https = require('https') + , crypto = require('crypto') + , stream = require('stream') + , Ultron = require('ultron') + , Options = require('options') + , Sender = require('./Sender') + , Receiver = require('./Receiver') + , SenderHixie = require('./Sender.hixie') + , ReceiverHixie = require('./Receiver.hixie') + , Extensions = require('./Extensions') + , PerMessageDeflate = require('./PerMessageDeflate') + , EventEmitter = require('events').EventEmitter; + +/** + * Constants + */ + +// Default protocol version + +var protocolVersion = 13; + +// Close timeout + +var closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly + +/** + * WebSocket implementation + * + * @constructor + * @param {String} address Connection address. + * @param {String|Array} protocols WebSocket protocols. + * @param {Object} options Additional connection options. + * @api public + */ +function WebSocket(address, protocols, options) { + if (this instanceof WebSocket === false) { + return new WebSocket(address, protocols, options); + } + + EventEmitter.call(this); + + if (protocols && !Array.isArray(protocols) && 'object' === typeof protocols) { + // accept the "options" Object as the 2nd argument + options = protocols; + protocols = null; + } + + if ('string' === typeof protocols) { + protocols = [ protocols ]; + } + + if (!Array.isArray(protocols)) { + protocols = []; + } + + this._socket = null; + this._ultron = null; + this._closeReceived = false; + this.bytesReceived = 0; + this.readyState = null; + this.supports = {}; + this.extensions = {}; + + if (Array.isArray(address)) { + initAsServerClient.apply(this, address.concat(options)); + } else { + initAsClient.apply(this, [address, protocols, options]); + } +} + +/** + * Inherits from EventEmitter. + */ +util.inherits(WebSocket, EventEmitter); + +/** + * Ready States + */ +["CONNECTING", "OPEN", "CLOSING", "CLOSED"].forEach(function each(state, index) { + WebSocket.prototype[state] = WebSocket[state] = index; +}); + +/** + * Gracefully closes the connection, after sending a description message to the server + * + * @param {Object} data to be sent to the server + * @api public + */ +WebSocket.prototype.close = function close(code, data) { + if (this.readyState === WebSocket.CLOSED) return; + + if (this.readyState === WebSocket.CONNECTING) { + this.readyState = WebSocket.CLOSED; + return; + } + + if (this.readyState === WebSocket.CLOSING) { + if (this._closeReceived && this._isServer) { + this.terminate(); + } + return; + } + + var self = this; + try { + this.readyState = WebSocket.CLOSING; + this._closeCode = code; + this._closeMessage = data; + var mask = !this._isServer; + this._sender.close(code, data, mask, function(err) { + if (err) self.emit('error', err); + + if (self._closeReceived && self._isServer) { + self.terminate(); + } else { + // ensure that the connection is cleaned up even when no response of closing handshake. + clearTimeout(self._closeTimer); + self._closeTimer = setTimeout(cleanupWebsocketResources.bind(self, true), closeTimeout); + } + }); + } catch (e) { + this.emit('error', e); + } +}; + +/** + * Pause the client stream + * + * @api public + */ +WebSocket.prototype.pause = function pauser() { + if (this.readyState !== WebSocket.OPEN) throw new Error('not opened'); + + return this._socket.pause(); +}; + +/** + * Sends a ping + * + * @param {Object} data to be sent to the server + * @param {Object} Members - mask: boolean, binary: boolean + * @param {boolean} dontFailWhenClosed indicates whether or not to throw if the connection isnt open + * @api public + */ +WebSocket.prototype.ping = function ping(data, options, dontFailWhenClosed) { + if (this.readyState !== WebSocket.OPEN) { + if (dontFailWhenClosed === true) return; + throw new Error('not opened'); + } + + options = options || {}; + + if (typeof options.mask === 'undefined') options.mask = !this._isServer; + + this._sender.ping(data, options); +}; + +/** + * Sends a pong + * + * @param {Object} data to be sent to the server + * @param {Object} Members - mask: boolean, binary: boolean + * @param {boolean} dontFailWhenClosed indicates whether or not to throw if the connection isnt open + * @api public + */ +WebSocket.prototype.pong = function(data, options, dontFailWhenClosed) { + if (this.readyState !== WebSocket.OPEN) { + if (dontFailWhenClosed === true) return; + throw new Error('not opened'); + } + + options = options || {}; + + if (typeof options.mask === 'undefined') options.mask = !this._isServer; + + this._sender.pong(data, options); +}; + +/** + * Resume the client stream + * + * @api public + */ +WebSocket.prototype.resume = function resume() { + if (this.readyState !== WebSocket.OPEN) throw new Error('not opened'); + + return this._socket.resume(); +}; + +/** + * Sends a piece of data + * + * @param {Object} data to be sent to the server + * @param {Object} Members - mask: boolean, binary: boolean, compress: boolean + * @param {function} Optional callback which is executed after the send completes + * @api public + */ + +WebSocket.prototype.send = function send(data, options, cb) { + if (typeof options === 'function') { + cb = options; + options = {}; + } + + if (this.readyState !== WebSocket.OPEN) { + if (typeof cb === 'function') cb(new Error('not opened')); + else throw new Error('not opened'); + return; + } + + if (!data) data = ''; + if (this._queue) { + var self = this; + this._queue.push(function() { self.send(data, options, cb); }); + return; + } + + options = options || {}; + options.fin = true; + + if (typeof options.binary === 'undefined') { + options.binary = (data instanceof ArrayBuffer || data instanceof Buffer || + data instanceof Uint8Array || + data instanceof Uint16Array || + data instanceof Uint32Array || + data instanceof Int8Array || + data instanceof Int16Array || + data instanceof Int32Array || + data instanceof Float32Array || + data instanceof Float64Array); + } + + if (typeof options.mask === 'undefined') options.mask = !this._isServer; + if (typeof options.compress === 'undefined') options.compress = true; + if (!this.extensions[PerMessageDeflate.extensionName]) { + options.compress = false; + } + + var readable = typeof stream.Readable === 'function' + ? stream.Readable + : stream.Stream; + + if (data instanceof readable) { + startQueue(this); + var self = this; + + sendStream(this, data, options, function send(error) { + process.nextTick(function tock() { + executeQueueSends(self); + }); + + if (typeof cb === 'function') cb(error); + }); + } else { + this._sender.send(data, options, cb); + } +}; + +/** + * Streams data through calls to a user supplied function + * + * @param {Object} Members - mask: boolean, binary: boolean, compress: boolean + * @param {function} 'function (error, send)' which is executed on successive ticks of which send is 'function (data, final)'. + * @api public + */ +WebSocket.prototype.stream = function stream(options, cb) { + if (typeof options === 'function') { + cb = options; + options = {}; + } + + var self = this; + + if (typeof cb !== 'function') throw new Error('callback must be provided'); + + if (this.readyState !== WebSocket.OPEN) { + if (typeof cb === 'function') cb(new Error('not opened')); + else throw new Error('not opened'); + return; + } + + if (this._queue) { + this._queue.push(function () { self.stream(options, cb); }); + return; + } + + options = options || {}; + + if (typeof options.mask === 'undefined') options.mask = !this._isServer; + if (typeof options.compress === 'undefined') options.compress = true; + if (!this.extensions[PerMessageDeflate.extensionName]) { + options.compress = false; + } + + startQueue(this); + + function send(data, final) { + try { + if (self.readyState !== WebSocket.OPEN) throw new Error('not opened'); + options.fin = final === true; + self._sender.send(data, options); + if (!final) process.nextTick(cb.bind(null, null, send)); + else executeQueueSends(self); + } catch (e) { + if (typeof cb === 'function') cb(e); + else { + delete self._queue; + self.emit('error', e); + } + } + } + + process.nextTick(cb.bind(null, null, send)); +}; + +/** + * Immediately shuts down the connection + * + * @api public + */ +WebSocket.prototype.terminate = function terminate() { + if (this.readyState === WebSocket.CLOSED) return; + + if (this._socket) { + this.readyState = WebSocket.CLOSING; + + // End the connection + try { this._socket.end(); } + catch (e) { + // Socket error during end() call, so just destroy it right now + cleanupWebsocketResources.call(this, true); + return; + } + + // Add a timeout to ensure that the connection is completely + // cleaned up within 30 seconds, even if the clean close procedure + // fails for whatever reason + // First cleanup any pre-existing timeout from an earlier "terminate" call, + // if one exists. Otherwise terminate calls in quick succession will leak timeouts + // and hold the program open for `closeTimout` time. + if (this._closeTimer) { clearTimeout(this._closeTimer); } + this._closeTimer = setTimeout(cleanupWebsocketResources.bind(this, true), closeTimeout); + } else if (this.readyState === WebSocket.CONNECTING) { + cleanupWebsocketResources.call(this, true); + } +}; + +/** + * Expose bufferedAmount + * + * @api public + */ +Object.defineProperty(WebSocket.prototype, 'bufferedAmount', { + get: function get() { + var amount = 0; + if (this._socket) { + amount = this._socket.bufferSize || 0; + } + return amount; + } +}); + +/** + * Emulates the W3C Browser based WebSocket interface using function members. + * + * @see http://dev.w3.org/html5/websockets/#the-websocket-interface + * @api public + */ +['open', 'error', 'close', 'message'].forEach(function(method) { + Object.defineProperty(WebSocket.prototype, 'on' + method, { + /** + * Returns the current listener + * + * @returns {Mixed} the set function or undefined + * @api public + */ + get: function get() { + var listener = this.listeners(method)[0]; + return listener ? (listener._listener ? listener._listener : listener) : undefined; + }, + + /** + * Start listening for events + * + * @param {Function} listener the listener + * @returns {Mixed} the set function or undefined + * @api public + */ + set: function set(listener) { + this.removeAllListeners(method); + this.addEventListener(method, listener); + } + }); +}); + +/** + * Emulates the W3C Browser based WebSocket interface using addEventListener. + * + * @see https://developer.mozilla.org/en/DOM/element.addEventListener + * @see http://dev.w3.org/html5/websockets/#the-websocket-interface + * @api public + */ +WebSocket.prototype.addEventListener = function(method, listener) { + var target = this; + + function onMessage (data, flags) { + listener.call(target, new MessageEvent(data, !!flags.binary, target)); + } + + function onClose (code, message) { + listener.call(target, new CloseEvent(code, message, target)); + } + + function onError (event) { + event.type = 'error'; + event.target = target; + listener.call(target, event); + } + + function onOpen () { + listener.call(target, new OpenEvent(target)); + } + + if (typeof listener === 'function') { + if (method === 'message') { + // store a reference so we can return the original function from the + // addEventListener hook + onMessage._listener = listener; + this.on(method, onMessage); + } else if (method === 'close') { + // store a reference so we can return the original function from the + // addEventListener hook + onClose._listener = listener; + this.on(method, onClose); + } else if (method === 'error') { + // store a reference so we can return the original function from the + // addEventListener hook + onError._listener = listener; + this.on(method, onError); + } else if (method === 'open') { + // store a reference so we can return the original function from the + // addEventListener hook + onOpen._listener = listener; + this.on(method, onOpen); + } else { + this.on(method, listener); + } + } +}; + +module.exports = WebSocket; +module.exports.buildHostHeader = buildHostHeader + +/** + * W3C MessageEvent + * + * @see http://www.w3.org/TR/html5/comms.html + * @constructor + * @api private + */ +function MessageEvent(dataArg, isBinary, target) { + this.type = 'message'; + this.data = dataArg; + this.target = target; + this.binary = isBinary; // non-standard. +} + +/** + * W3C CloseEvent + * + * @see http://www.w3.org/TR/html5/comms.html + * @constructor + * @api private + */ +function CloseEvent(code, reason, target) { + this.type = 'close'; + this.wasClean = (typeof code === 'undefined' || code === 1000); + this.code = code; + this.reason = reason; + this.target = target; +} + +/** + * W3C OpenEvent + * + * @see http://www.w3.org/TR/html5/comms.html + * @constructor + * @api private + */ +function OpenEvent(target) { + this.type = 'open'; + this.target = target; +} + +// Append port number to Host header, only if specified in the url +// and non-default +function buildHostHeader(isSecure, hostname, port) { + var headerHost = hostname; + if (hostname) { + if ((isSecure && (port != 443)) || (!isSecure && (port != 80))){ + headerHost = headerHost + ':' + port; + } + } + return headerHost; +} + +/** + * Entirely private apis, + * which may or may not be bound to a sepcific WebSocket instance. + */ +function initAsServerClient(req, socket, upgradeHead, options) { + options = new Options({ + protocolVersion: protocolVersion, + protocol: null, + extensions: {} + }).merge(options); + + // expose state properties + this.protocol = options.value.protocol; + this.protocolVersion = options.value.protocolVersion; + this.extensions = options.value.extensions; + this.supports.binary = (this.protocolVersion !== 'hixie-76'); + this.upgradeReq = req; + this.readyState = WebSocket.CONNECTING; + this._isServer = true; + + // establish connection + if (options.value.protocolVersion === 'hixie-76') { + establishConnection.call(this, ReceiverHixie, SenderHixie, socket, upgradeHead); + } else { + establishConnection.call(this, Receiver, Sender, socket, upgradeHead); + } +} + +function initAsClient(address, protocols, options) { + options = new Options({ + origin: null, + protocolVersion: protocolVersion, + host: null, + headers: null, + protocol: protocols.join(','), + agent: null, + + // ssl-related options + pfx: null, + key: null, + passphrase: null, + cert: null, + ca: null, + ciphers: null, + rejectUnauthorized: null, + perMessageDeflate: true, + localAddress: null + }).merge(options); + + if (options.value.protocolVersion !== 8 && options.value.protocolVersion !== 13) { + throw new Error('unsupported protocol version'); + } + + // verify URL and establish http class + var serverUrl = url.parse(address); + var isUnixSocket = serverUrl.protocol === 'ws+unix:'; + if (!serverUrl.host && !isUnixSocket) throw new Error('invalid url'); + var isSecure = serverUrl.protocol === 'wss:' || serverUrl.protocol === 'https:'; + var httpObj = isSecure ? https : http; + var port = serverUrl.port || (isSecure ? 443 : 80); + var auth = serverUrl.auth; + + // prepare extensions + var extensionsOffer = {}; + var perMessageDeflate; + if (options.value.perMessageDeflate) { + perMessageDeflate = new PerMessageDeflate(typeof options.value.perMessageDeflate !== true ? options.value.perMessageDeflate : {}, false); + extensionsOffer[PerMessageDeflate.extensionName] = perMessageDeflate.offer(); + } + + // expose state properties + this._isServer = false; + this.url = address; + this.protocolVersion = options.value.protocolVersion; + this.supports.binary = (this.protocolVersion !== 'hixie-76'); + + // begin handshake + var key = new Buffer(options.value.protocolVersion + '-' + Date.now()).toString('base64'); + var shasum = crypto.createHash('sha1'); + shasum.update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'); + var expectedServerKey = shasum.digest('base64'); + + var agent = options.value.agent; + + var headerHost = buildHostHeader(isSecure, serverUrl.hostname, port) + + var requestOptions = { + port: port, + host: serverUrl.hostname, + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + 'Host': headerHost, + 'Sec-WebSocket-Version': options.value.protocolVersion, + 'Sec-WebSocket-Key': key + } + }; + + // If we have basic auth. + if (auth) { + requestOptions.headers.Authorization = 'Basic ' + new Buffer(auth).toString('base64'); + } + + if (options.value.protocol) { + requestOptions.headers['Sec-WebSocket-Protocol'] = options.value.protocol; + } + + if (options.value.host) { + requestOptions.headers.Host = options.value.host; + } + + if (options.value.headers) { + for (var header in options.value.headers) { + if (options.value.headers.hasOwnProperty(header)) { + requestOptions.headers[header] = options.value.headers[header]; + } + } + } + + if (Object.keys(extensionsOffer).length) { + requestOptions.headers['Sec-WebSocket-Extensions'] = Extensions.format(extensionsOffer); + } + + if (options.isDefinedAndNonNull('pfx') + || options.isDefinedAndNonNull('key') + || options.isDefinedAndNonNull('passphrase') + || options.isDefinedAndNonNull('cert') + || options.isDefinedAndNonNull('ca') + || options.isDefinedAndNonNull('ciphers') + || options.isDefinedAndNonNull('rejectUnauthorized')) { + + if (options.isDefinedAndNonNull('pfx')) requestOptions.pfx = options.value.pfx; + if (options.isDefinedAndNonNull('key')) requestOptions.key = options.value.key; + if (options.isDefinedAndNonNull('passphrase')) requestOptions.passphrase = options.value.passphrase; + if (options.isDefinedAndNonNull('cert')) requestOptions.cert = options.value.cert; + if (options.isDefinedAndNonNull('ca')) requestOptions.ca = options.value.ca; + if (options.isDefinedAndNonNull('ciphers')) requestOptions.ciphers = options.value.ciphers; + if (options.isDefinedAndNonNull('rejectUnauthorized')) requestOptions.rejectUnauthorized = options.value.rejectUnauthorized; + + if (!agent) { + // global agent ignores client side certificates + agent = new httpObj.Agent(requestOptions); + } + } + + requestOptions.path = serverUrl.path || '/'; + + if (agent) { + requestOptions.agent = agent; + } + + if (isUnixSocket) { + requestOptions.socketPath = serverUrl.pathname; + } + + if (options.value.localAddress) { + requestOptions.localAddress = options.value.localAddress; + } + + if (options.value.origin) { + if (options.value.protocolVersion < 13) requestOptions.headers['Sec-WebSocket-Origin'] = options.value.origin; + else requestOptions.headers.Origin = options.value.origin; + } + + var self = this; + var req = httpObj.request(requestOptions); + + req.on('error', function onerror(error) { + self.emit('error', error); + cleanupWebsocketResources.call(self, error); + }); + + req.once('response', function response(res) { + var error; + + if (!self.emit('unexpected-response', req, res)) { + error = new Error('unexpected server response (' + res.statusCode + ')'); + req.abort(); + self.emit('error', error); + } + + cleanupWebsocketResources.call(self, error); + }); + + req.once('upgrade', function upgrade(res, socket, upgradeHead) { + if (self.readyState === WebSocket.CLOSED) { + // client closed before server accepted connection + self.emit('close'); + self.removeAllListeners(); + socket.end(); + return; + } + + var serverKey = res.headers['sec-websocket-accept']; + if (typeof serverKey === 'undefined' || serverKey !== expectedServerKey) { + self.emit('error', 'invalid server key'); + self.removeAllListeners(); + socket.end(); + return; + } + + var serverProt = res.headers['sec-websocket-protocol']; + var protList = (options.value.protocol || "").split(/, */); + var protError = null; + + if (!options.value.protocol && serverProt) { + protError = 'server sent a subprotocol even though none requested'; + } else if (options.value.protocol && !serverProt) { + protError = 'server sent no subprotocol even though requested'; + } else if (serverProt && protList.indexOf(serverProt) === -1) { + protError = 'server responded with an invalid protocol'; + } + + if (protError) { + self.emit('error', protError); + self.removeAllListeners(); + socket.end(); + return; + } else if (serverProt) { + self.protocol = serverProt; + } + + var serverExtensions = Extensions.parse(res.headers['sec-websocket-extensions']); + if (perMessageDeflate && serverExtensions[PerMessageDeflate.extensionName]) { + try { + perMessageDeflate.accept(serverExtensions[PerMessageDeflate.extensionName]); + } catch (err) { + self.emit('error', 'invalid extension parameter'); + self.removeAllListeners(); + socket.end(); + return; + } + self.extensions[PerMessageDeflate.extensionName] = perMessageDeflate; + } + + establishConnection.call(self, Receiver, Sender, socket, upgradeHead); + + // perform cleanup on http resources + req.removeAllListeners(); + req = null; + agent = null; + }); + + req.end(); + this.readyState = WebSocket.CONNECTING; +} + +function establishConnection(ReceiverClass, SenderClass, socket, upgradeHead) { + var ultron = this._ultron = new Ultron(socket) + , called = false + , self = this; + + socket.setTimeout(0); + socket.setNoDelay(true); + + this._receiver = new ReceiverClass(this.extensions); + this._socket = socket; + + // socket cleanup handlers + ultron.on('end', cleanupWebsocketResources.bind(this)); + ultron.on('close', cleanupWebsocketResources.bind(this)); + ultron.on('error', cleanupWebsocketResources.bind(this)); + + // ensure that the upgradeHead is added to the receiver + function firstHandler(data) { + if (called || self.readyState === WebSocket.CLOSED) return; + + called = true; + socket.removeListener('data', firstHandler); + ultron.on('data', realHandler); + + if (upgradeHead && upgradeHead.length > 0) { + realHandler(upgradeHead); + upgradeHead = null; + } + + if (data) realHandler(data); + } + + // subsequent packets are pushed straight to the receiver + function realHandler(data) { + self.bytesReceived += data.length; + self._receiver.add(data); + } + + ultron.on('data', firstHandler); + + // if data was passed along with the http upgrade, + // this will schedule a push of that on to the receiver. + // this has to be done on next tick, since the caller + // hasn't had a chance to set event handlers on this client + // object yet. + process.nextTick(firstHandler); + + // receiver event handlers + self._receiver.ontext = function ontext(data, flags) { + flags = flags || {}; + + self.emit('message', data, flags); + }; + + self._receiver.onbinary = function onbinary(data, flags) { + flags = flags || {}; + + flags.binary = true; + self.emit('message', data, flags); + }; + + self._receiver.onping = function onping(data, flags) { + flags = flags || {}; + + self.pong(data, { + mask: !self._isServer, + binary: flags.binary === true + }, true); + + self.emit('ping', data, flags); + }; + + self._receiver.onpong = function onpong(data, flags) { + self.emit('pong', data, flags || {}); + }; + + self._receiver.onclose = function onclose(code, data, flags) { + flags = flags || {}; + + self._closeReceived = true; + self.close(code, data); + }; + + self._receiver.onerror = function onerror(reason, errorCode) { + // close the connection when the receiver reports a HyBi error code + self.close(typeof errorCode !== 'undefined' ? errorCode : 1002, ''); + self.emit('error', reason, errorCode); + }; + + // finalize the client + this._sender = new SenderClass(socket, this.extensions); + this._sender.on('error', function onerror(error) { + self.close(1002, ''); + self.emit('error', error); + }); + + this.readyState = WebSocket.OPEN; + this.emit('open'); +} + +function startQueue(instance) { + instance._queue = instance._queue || []; +} + +function executeQueueSends(instance) { + var queue = instance._queue; + if (typeof queue === 'undefined') return; + + delete instance._queue; + for (var i = 0, l = queue.length; i < l; ++i) { + queue[i](); + } +} + +function sendStream(instance, stream, options, cb) { + stream.on('data', function incoming(data) { + if (instance.readyState !== WebSocket.OPEN) { + if (typeof cb === 'function') cb(new Error('not opened')); + else { + delete instance._queue; + instance.emit('error', new Error('not opened')); + } + return; + } + + options.fin = false; + instance._sender.send(data, options); + }); + + stream.on('end', function end() { + if (instance.readyState !== WebSocket.OPEN) { + if (typeof cb === 'function') cb(new Error('not opened')); + else { + delete instance._queue; + instance.emit('error', new Error('not opened')); + } + return; + } + + options.fin = true; + instance._sender.send(null, options); + + if (typeof cb === 'function') cb(null); + }); +} + +function cleanupWebsocketResources(error) { + if (this.readyState === WebSocket.CLOSED) return; + + var emitClose = this.readyState !== WebSocket.CONNECTING; + this.readyState = WebSocket.CLOSED; + + clearTimeout(this._closeTimer); + this._closeTimer = null; + + if (emitClose) { + // If the connection was closed abnormally (with an error), or if + // the close control frame was not received then the close code + // must default to 1006. + if (error || !this._closeReceived) { + this._closeCode = 1006; + } + this.emit('close', this._closeCode || 1000, this._closeMessage || ''); + } + + if (this._socket) { + if (this._ultron) this._ultron.destroy(); + this._socket.on('error', function onerror() { + try { this.destroy(); } + catch (e) {} + }); + + try { + if (!error) this._socket.end(); + else this._socket.destroy(); + } catch (e) { /* Ignore termination errors */ } + + this._socket = null; + this._ultron = null; + } + + if (this._sender) { + this._sender.removeAllListeners(); + this._sender = null; + } + + if (this._receiver) { + this._receiver.cleanup(); + this._receiver = null; + } + + if (this.extensions[PerMessageDeflate.extensionName]) { + this.extensions[PerMessageDeflate.extensionName].cleanup(); + } + + this.extensions = null; + + this.removeAllListeners(); + this.on('error', function onerror() {}); // catch all errors after this + delete this._queue; +} diff --git a/www/node_modules/ws/lib/WebSocketServer.js b/www/node_modules/ws/lib/WebSocketServer.js new file mode 100644 index 0000000..ba0e4c0 --- /dev/null +++ b/www/node_modules/ws/lib/WebSocketServer.js @@ -0,0 +1,513 @@ +/*! + * ws: a node.js websocket client + * Copyright(c) 2011 Einar Otto Stangvik + * MIT Licensed + */ + +var util = require('util') + , events = require('events') + , http = require('http') + , crypto = require('crypto') + , Options = require('options') + , WebSocket = require('./WebSocket') + , Extensions = require('./Extensions') + , PerMessageDeflate = require('./PerMessageDeflate') + , tls = require('tls') + , url = require('url'); + +/** + * WebSocket Server implementation + */ + +function WebSocketServer(options, callback) { + if (this instanceof WebSocketServer === false) { + return new WebSocketServer(options, callback); + } + + events.EventEmitter.call(this); + + options = new Options({ + host: '0.0.0.0', + port: null, + server: null, + verifyClient: null, + handleProtocols: null, + path: null, + noServer: false, + disableHixie: false, + clientTracking: true, + perMessageDeflate: true + }).merge(options); + + if (!options.isDefinedAndNonNull('port') && !options.isDefinedAndNonNull('server') && !options.value.noServer) { + throw new TypeError('`port` or a `server` must be provided'); + } + + var self = this; + + if (options.isDefinedAndNonNull('port')) { + this._server = http.createServer(function (req, res) { + var body = http.STATUS_CODES[426]; + res.writeHead(426, { + 'Content-Length': body.length, + 'Content-Type': 'text/plain' + }); + res.end(body); + }); + this._server.allowHalfOpen = false; + this._server.listen(options.value.port, options.value.host, callback); + this._closeServer = function() { if (self._server) self._server.close(); }; + } + else if (options.value.server) { + this._server = options.value.server; + if (options.value.path) { + // take note of the path, to avoid collisions when multiple websocket servers are + // listening on the same http server + if (this._server._webSocketPaths && options.value.server._webSocketPaths[options.value.path]) { + throw new Error('two instances of WebSocketServer cannot listen on the same http server path'); + } + if (typeof this._server._webSocketPaths !== 'object') { + this._server._webSocketPaths = {}; + } + this._server._webSocketPaths[options.value.path] = 1; + } + } + if (this._server) this._server.once('listening', function() { self.emit('listening'); }); + + if (typeof this._server != 'undefined') { + this._server.on('error', function(error) { + self.emit('error', error) + }); + this._server.on('upgrade', function(req, socket, upgradeHead) { + //copy upgradeHead to avoid retention of large slab buffers used in node core + var head = new Buffer(upgradeHead.length); + upgradeHead.copy(head); + + self.handleUpgrade(req, socket, head, function(client) { + self.emit('connection'+req.url, client); + self.emit('connection', client); + }); + }); + } + + this.options = options.value; + this.path = options.value.path; + this.clients = []; +} + +/** + * Inherits from EventEmitter. + */ + +util.inherits(WebSocketServer, events.EventEmitter); + +/** + * Immediately shuts down the connection. + * + * @api public + */ + +WebSocketServer.prototype.close = function(callback) { + // terminate all associated clients + var error = null; + try { + for (var i = 0, l = this.clients.length; i < l; ++i) { + this.clients[i].terminate(); + } + } + catch (e) { + error = e; + } + + // remove path descriptor, if any + if (this.path && this._server._webSocketPaths) { + delete this._server._webSocketPaths[this.path]; + if (Object.keys(this._server._webSocketPaths).length == 0) { + delete this._server._webSocketPaths; + } + } + + // close the http server if it was internally created + try { + if (typeof this._closeServer !== 'undefined') { + this._closeServer(); + } + } + finally { + delete this._server; + } + if(callback) + callback(error); + else if(error) + throw error; +} + +/** + * Handle a HTTP Upgrade request. + * + * @api public + */ + +WebSocketServer.prototype.handleUpgrade = function(req, socket, upgradeHead, cb) { + // check for wrong path + if (this.options.path) { + var u = url.parse(req.url); + if (u && u.pathname !== this.options.path) return; + } + + if (typeof req.headers.upgrade === 'undefined' || req.headers.upgrade.toLowerCase() !== 'websocket') { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + if (req.headers['sec-websocket-key1']) handleHixieUpgrade.apply(this, arguments); + else handleHybiUpgrade.apply(this, arguments); +} + +module.exports = WebSocketServer; + +/** + * Entirely private apis, + * which may or may not be bound to a sepcific WebSocket instance. + */ + +function handleHybiUpgrade(req, socket, upgradeHead, cb) { + // handle premature socket errors + var errorHandler = function() { + try { socket.destroy(); } catch (e) {} + } + socket.on('error', errorHandler); + + // verify key presence + if (!req.headers['sec-websocket-key']) { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + // verify version + var version = parseInt(req.headers['sec-websocket-version']); + if ([8, 13].indexOf(version) === -1) { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + // verify protocol + var protocols = req.headers['sec-websocket-protocol']; + + // verify client + var origin = version < 13 ? + req.headers['sec-websocket-origin'] : + req.headers['origin']; + + // handle extensions offer + var extensionsOffer = Extensions.parse(req.headers['sec-websocket-extensions']); + + // handler to call when the connection sequence completes + var self = this; + var completeHybiUpgrade2 = function(protocol) { + + // calc key + var key = req.headers['sec-websocket-key']; + var shasum = crypto.createHash('sha1'); + shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); + key = shasum.digest('base64'); + + var headers = [ + 'HTTP/1.1 101 Switching Protocols' + , 'Upgrade: websocket' + , 'Connection: Upgrade' + , 'Sec-WebSocket-Accept: ' + key + ]; + + if (typeof protocol != 'undefined') { + headers.push('Sec-WebSocket-Protocol: ' + protocol); + } + + var extensions = {}; + try { + extensions = acceptExtensions.call(self, extensionsOffer); + } catch (err) { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + if (Object.keys(extensions).length) { + var serverExtensions = {}; + Object.keys(extensions).forEach(function(token) { + serverExtensions[token] = [extensions[token].params] + }); + headers.push('Sec-WebSocket-Extensions: ' + Extensions.format(serverExtensions)); + } + + // allows external modification/inspection of handshake headers + self.emit('headers', headers); + + socket.setTimeout(0); + socket.setNoDelay(true); + try { + socket.write(headers.concat('', '').join('\r\n')); + } + catch (e) { + // if the upgrade write fails, shut the connection down hard + try { socket.destroy(); } catch (e) {} + return; + } + + var client = new WebSocket([req, socket, upgradeHead], { + protocolVersion: version, + protocol: protocol, + extensions: extensions + }); + + if (self.options.clientTracking) { + self.clients.push(client); + client.on('close', function() { + var index = self.clients.indexOf(client); + if (index != -1) { + self.clients.splice(index, 1); + } + }); + } + + // signal upgrade complete + socket.removeListener('error', errorHandler); + cb(client); + } + + // optionally call external protocol selection handler before + // calling completeHybiUpgrade2 + var completeHybiUpgrade1 = function() { + // choose from the sub-protocols + if (typeof self.options.handleProtocols == 'function') { + var protList = (protocols || "").split(/, */); + var callbackCalled = false; + var res = self.options.handleProtocols(protList, function(result, protocol) { + callbackCalled = true; + if (!result) abortConnection(socket, 401, 'Unauthorized'); + else completeHybiUpgrade2(protocol); + }); + if (!callbackCalled) { + // the handleProtocols handler never called our callback + abortConnection(socket, 501, 'Could not process protocols'); + } + return; + } else { + if (typeof protocols !== 'undefined') { + completeHybiUpgrade2(protocols.split(/, */)[0]); + } + else { + completeHybiUpgrade2(); + } + } + } + + // optionally call external client verification handler + if (typeof this.options.verifyClient == 'function') { + var info = { + origin: origin, + secure: typeof req.connection.authorized !== 'undefined' || typeof req.connection.encrypted !== 'undefined', + req: req + }; + if (this.options.verifyClient.length == 2) { + this.options.verifyClient(info, function(result, code, name) { + if (typeof code === 'undefined') code = 401; + if (typeof name === 'undefined') name = http.STATUS_CODES[code]; + + if (!result) abortConnection(socket, code, name); + else completeHybiUpgrade1(); + }); + return; + } + else if (!this.options.verifyClient(info)) { + abortConnection(socket, 401, 'Unauthorized'); + return; + } + } + + completeHybiUpgrade1(); +} + +function handleHixieUpgrade(req, socket, upgradeHead, cb) { + // handle premature socket errors + var errorHandler = function() { + try { socket.destroy(); } catch (e) {} + } + socket.on('error', errorHandler); + + // bail if options prevent hixie + if (this.options.disableHixie) { + abortConnection(socket, 401, 'Hixie support disabled'); + return; + } + + // verify key presence + if (!req.headers['sec-websocket-key2']) { + abortConnection(socket, 400, 'Bad Request'); + return; + } + + var origin = req.headers['origin'] + , self = this; + + // setup handshake completion to run after client has been verified + var onClientVerified = function() { + var wshost; + if (!req.headers['x-forwarded-host']) + wshost = req.headers.host; + else + wshost = req.headers['x-forwarded-host']; + var location = ((req.headers['x-forwarded-proto'] === 'https' || socket.encrypted) ? 'wss' : 'ws') + '://' + wshost + req.url + , protocol = req.headers['sec-websocket-protocol']; + + // handshake completion code to run once nonce has been successfully retrieved + var completeHandshake = function(nonce, rest) { + // calculate key + var k1 = req.headers['sec-websocket-key1'] + , k2 = req.headers['sec-websocket-key2'] + , md5 = crypto.createHash('md5'); + + [k1, k2].forEach(function (k) { + var n = parseInt(k.replace(/[^\d]/g, '')) + , spaces = k.replace(/[^ ]/g, '').length; + if (spaces === 0 || n % spaces !== 0){ + abortConnection(socket, 400, 'Bad Request'); + return; + } + n /= spaces; + md5.update(String.fromCharCode( + n >> 24 & 0xFF, + n >> 16 & 0xFF, + n >> 8 & 0xFF, + n & 0xFF)); + }); + md5.update(nonce.toString('binary')); + + var headers = [ + 'HTTP/1.1 101 Switching Protocols' + , 'Upgrade: WebSocket' + , 'Connection: Upgrade' + , 'Sec-WebSocket-Location: ' + location + ]; + if (typeof protocol != 'undefined') headers.push('Sec-WebSocket-Protocol: ' + protocol); + if (typeof origin != 'undefined') headers.push('Sec-WebSocket-Origin: ' + origin); + + socket.setTimeout(0); + socket.setNoDelay(true); + try { + // merge header and hash buffer + var headerBuffer = new Buffer(headers.concat('', '').join('\r\n')); + var hashBuffer = new Buffer(md5.digest('binary'), 'binary'); + var handshakeBuffer = new Buffer(headerBuffer.length + hashBuffer.length); + headerBuffer.copy(handshakeBuffer, 0); + hashBuffer.copy(handshakeBuffer, headerBuffer.length); + + // do a single write, which - upon success - causes a new client websocket to be setup + socket.write(handshakeBuffer, 'binary', function(err) { + if (err) return; // do not create client if an error happens + var client = new WebSocket([req, socket, rest], { + protocolVersion: 'hixie-76', + protocol: protocol + }); + if (self.options.clientTracking) { + self.clients.push(client); + client.on('close', function() { + var index = self.clients.indexOf(client); + if (index != -1) { + self.clients.splice(index, 1); + } + }); + } + + // signal upgrade complete + socket.removeListener('error', errorHandler); + cb(client); + }); + } + catch (e) { + try { socket.destroy(); } catch (e) {} + return; + } + } + + // retrieve nonce + var nonceLength = 8; + if (upgradeHead && upgradeHead.length >= nonceLength) { + var nonce = upgradeHead.slice(0, nonceLength); + var rest = upgradeHead.length > nonceLength ? upgradeHead.slice(nonceLength) : null; + completeHandshake.call(self, nonce, rest); + } + else { + // nonce not present in upgradeHead, so we must wait for enough data + // data to arrive before continuing + var nonce = new Buffer(nonceLength); + upgradeHead.copy(nonce, 0); + var received = upgradeHead.length; + var rest = null; + var handler = function (data) { + var toRead = Math.min(data.length, nonceLength - received); + if (toRead === 0) return; + data.copy(nonce, received, 0, toRead); + received += toRead; + if (received == nonceLength) { + socket.removeListener('data', handler); + if (toRead < data.length) rest = data.slice(toRead); + completeHandshake.call(self, nonce, rest); + } + } + socket.on('data', handler); + } + } + + // verify client + if (typeof this.options.verifyClient == 'function') { + var info = { + origin: origin, + secure: typeof req.connection.authorized !== 'undefined' || typeof req.connection.encrypted !== 'undefined', + req: req + }; + if (this.options.verifyClient.length == 2) { + var self = this; + this.options.verifyClient(info, function(result, code, name) { + if (typeof code === 'undefined') code = 401; + if (typeof name === 'undefined') name = http.STATUS_CODES[code]; + + if (!result) abortConnection(socket, code, name); + else onClientVerified.apply(self); + }); + return; + } + else if (!this.options.verifyClient(info)) { + abortConnection(socket, 401, 'Unauthorized'); + return; + } + } + + // no client verification required + onClientVerified(); +} + +function acceptExtensions(offer) { + var extensions = {}; + var options = this.options.perMessageDeflate; + if (options && offer[PerMessageDeflate.extensionName]) { + var perMessageDeflate = new PerMessageDeflate(options !== true ? options : {}, true); + perMessageDeflate.accept(offer[PerMessageDeflate.extensionName]); + extensions[PerMessageDeflate.extensionName] = perMessageDeflate; + } + return extensions; +} + +function abortConnection(socket, code, name) { + try { + var response = [ + 'HTTP/1.1 ' + code + ' ' + name, + 'Content-type: text/html' + ]; + socket.write(response.concat('', '').join('\r\n')); + } + catch (e) { /* ignore errors - we've aborted this connection */ } + finally { + // ensure that an early aborted connection is shut down completely + try { socket.destroy(); } catch (e) {} + } +} diff --git a/www/node_modules/ws/package.json b/www/node_modules/ws/package.json new file mode 100644 index 0000000..b597874 --- /dev/null +++ b/www/node_modules/ws/package.json @@ -0,0 +1,102 @@ +{ + "_args": [ + [ + "ws@^1.0.1", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver" + ] + ], + "_from": "ws@>=1.0.1 <2.0.0", + "_id": "ws@1.0.1", + "_inCache": true, + "_installable": true, + "_location": "/ws", + "_nodeVersion": "4.2.3", + "_npmUser": { + "email": "npm@3rd-Eden.com", + "name": "3rdeden" + }, + "_npmVersion": "3.5.1", + "_phantomChildren": {}, + "_requested": { + "name": "ws", + "raw": "ws@^1.0.1", + "rawSpec": "^1.0.1", + "scope": null, + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/selenium-webdriver" + ], + "_resolved": "https://registry.npmjs.org/ws/-/ws-1.0.1.tgz", + "_shasum": "7d0b2a2e58cddd819039c29c9de65045e1b310e9", + "_shrinkwrap": null, + "_spec": "ws@^1.0.1", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver", + "author": { + "email": "einaros@gmail.com", + "name": "Einar Otto Stangvik", + "url": "http://2x.io" + }, + "bugs": { + "url": "https://github.com/websockets/ws/issues" + }, + "dependencies": { + "options": ">=0.0.5", + "ultron": "1.0.x" + }, + "description": "simple to use, blazing fast and thoroughly tested websocket client, server and console for node.js, up-to-date against RFC-6455", + "devDependencies": { + "ansi": "0.3.x", + "benchmark": "0.3.x", + "bufferutil": "1.2.x", + "expect.js": "0.3.x", + "mocha": "2.3.x", + "should": "8.0.x", + "tinycolor": "0.0.x", + "utf-8-validate": "1.2.x" + }, + "directories": {}, + "dist": { + "shasum": "7d0b2a2e58cddd819039c29c9de65045e1b310e9", + "tarball": "http://registry.npmjs.org/ws/-/ws-1.0.1.tgz" + }, + "gitHead": "40a9d686288b5d0be13f2bf2f3f5da07afc8cda2", + "gypfile": true, + "homepage": "https://github.com/websockets/ws#readme", + "keywords": [ + "Hixie", + "HyBi", + "Push", + "RFC-6455", + "WebSocket", + "WebSockets", + "real-time" + ], + "license": "MIT", + "maintainers": [ + { + "email": "einaros@gmail.com", + "name": "einaros" + }, + { + "email": "info@3rd-Eden.com", + "name": "v1" + }, + { + "email": "npm@3rd-Eden.com", + "name": "3rdeden" + } + ], + "name": "ws", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/websockets/ws.git" + }, + "scripts": { + "test": "make test" + }, + "version": "1.0.1" +} diff --git a/www/node_modules/xml2js/.npmignore b/www/node_modules/xml2js/.npmignore new file mode 100644 index 0000000..ef7b9b9 --- /dev/null +++ b/www/node_modules/xml2js/.npmignore @@ -0,0 +1,6 @@ +*.swp +.idea +node_modules +src +test +Cakefile \ No newline at end of file diff --git a/www/node_modules/xml2js/.travis.yml b/www/node_modules/xml2js/.travis.yml new file mode 100644 index 0000000..755a6b7 --- /dev/null +++ b/www/node_modules/xml2js/.travis.yml @@ -0,0 +1,5 @@ +language: node_js + +node_js: + - "0.8" + - "0.10" diff --git a/www/node_modules/xml2js/83.coffee b/www/node_modules/xml2js/83.coffee new file mode 100644 index 0000000..3443540 --- /dev/null +++ b/www/node_modules/xml2js/83.coffee @@ -0,0 +1,6 @@ +xml2js = require 'xml2js' +util = require 'util' + +body = 'Character data here!' +xml2js.parseString body, (err, result) -> + console.log util.inspect result, false, null diff --git a/www/node_modules/xml2js/CONTRIBUTING.md b/www/node_modules/xml2js/CONTRIBUTING.md new file mode 100644 index 0000000..2209adf --- /dev/null +++ b/www/node_modules/xml2js/CONTRIBUTING.md @@ -0,0 +1,19 @@ +# How to contribute + +We're always happy about useful new pull requests. Keep in mind that the better +your pull request is, the easier it can be added to `xml2js`. As such please +make sure your patch is ok: + + * `xml2js` is written in CoffeeScript. Please don't send patches to + the JavaScript source, as it get's overwritten by the CoffeeScript + compiler. The reason we have the JS code in the repository is for easier + use with eg. `git submodule` + * Make sure that the unit tests still all pass. Failing unit tests mean that + someone *will* run into a bug, if we accept your pull request. + * Please, add a unit test with your pull request, to show what was broken and + is now fixed or what was impossible and now works due to your new code. + * If you add a new feature, please add some documentation that it exists. + +If you like, you can add yourself in the `package.json` as contributor if you +deem your contribution significant enough. Otherwise, we will decide and maybe +add you. diff --git a/www/node_modules/xml2js/LICENSE b/www/node_modules/xml2js/LICENSE new file mode 100644 index 0000000..e3b4222 --- /dev/null +++ b/www/node_modules/xml2js/LICENSE @@ -0,0 +1,19 @@ +Copyright 2010, 2011, 2012, 2013. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/www/node_modules/xml2js/README.md b/www/node_modules/xml2js/README.md new file mode 100644 index 0000000..4e01478 --- /dev/null +++ b/www/node_modules/xml2js/README.md @@ -0,0 +1,343 @@ +node-xml2js +=========== + +Ever had the urge to parse XML? And wanted to access the data in some sane, +easy way? Don't want to compile a C parser, for whatever reason? Then xml2js is +what you're looking for! + +Description +=========== + +Simple XML to JavaScript object converter. It supports bi-directional conversion. +Uses [sax-js](https://github.com/isaacs/sax-js/) and +[xmlbuilder-js](https://github.com/oozcitak/xmlbuilder-js/). + +Note: If you're looking for a full DOM parser, you probably want +[JSDom](https://github.com/tmpvar/jsdom). + +Installation +============ + +Simplest way to install `xml2js` is to use [npm](http://npmjs.org), just `npm +install xml2js` which will download xml2js and all dependencies. + +Usage +===== + +No extensive tutorials required because you are a smart developer! The task of +parsing XML should be an easy one, so let's make it so! Here's some examples. + +Shoot-and-forget usage +---------------------- + +You want to parse XML as simple and easy as possible? It's dangerous to go +alone, take this: + +```javascript +var parseString = require('xml2js').parseString; +var xml = "Hello xml2js!" +parseString(xml, function (err, result) { + console.dir(result); +}); +``` + +Can't get easier than this, right? This works starting with `xml2js` 0.2.3. +With CoffeeScript it looks like this: + +```coffeescript +{parseString} = require 'xml2js' +xml = "Hello xml2js!" +parseString xml, (err, result) -> + console.dir result +``` + +If you need some special options, fear not, `xml2js` supports a number of +options (see below), you can specify these as second argument: + +```javascript +parseString(xml, {trim: true}, function (err, result) { +}); +``` + +Simple as pie usage +------------------- + +That's right, if you have been using xml-simple or a home-grown +wrapper, this was added in 0.1.11 just for you: + +```javascript +var fs = require('fs'), + xml2js = require('xml2js'); + +var parser = new xml2js.Parser(); +fs.readFile(__dirname + '/foo.xml', function(err, data) { + parser.parseString(data, function (err, result) { + console.dir(result); + console.log('Done'); + }); +}); +``` + +Look ma, no event listeners! + +You can also use `xml2js` from +[CoffeeScript](http://jashkenas.github.com/coffee-script/), further reducing +the clutter: + +```coffeescript +fs = require 'fs', +xml2js = require 'xml2js' + +parser = new xml2js.Parser() +fs.readFile __dirname + '/foo.xml', (err, data) -> + parser.parseString data, (err, result) -> + console.dir result + console.log 'Done.' +``` + +But what happens if you forget the `new` keyword to create a new `Parser`? In +the middle of a nightly coding session, it might get lost, after all. Worry +not, we got you covered! Starting with 0.2.8 you can also leave it out, in +which case `xml2js` will helpfully add it for you, no bad surprises and +inexplicable bugs! + +"Traditional" usage +------------------- + +Alternatively you can still use the traditional `addListener` variant that was +supported since forever: + +```javascript +var fs = require('fs'), + xml2js = require('xml2js'); + +var parser = new xml2js.Parser(); +parser.addListener('end', function(result) { + console.dir(result); + console.log('Done.'); +}); +fs.readFile(__dirname + '/foo.xml', function(err, data) { + parser.parseString(data); +}); +``` + +If you want to parse multiple files, you have multiple possibilites: + + * You can create one `xml2js.Parser` per file. That's the recommended one + and is promised to always *just work*. + * You can call `reset()` on your parser object. + * You can hope everything goes well anyway. This behaviour is not + guaranteed work always, if ever. Use option #1 if possible. Thanks! + +So you wanna some JSON? +----------------------- + +Just wrap the `result` object in a call to `JSON.stringify` like this +`JSON.stringify(result)`. You get a string containing the JSON representation +of the parsed object that you can feed to JSON-hungry consumers. + +Displaying results +------------------ + +You might wonder why, using `console.dir` or `console.log` the output at some +level is only `[Object]`. Don't worry, this is not because xml2js got lazy. +That's because Node uses `util.inspect` to convert the object into strings and +that function stops after `depth=2` which is a bit low for most XML. + +To display the whole deal, you can use `console.log(util.inspect(result, false, +null))`, which displays the whole result. + +So much for that, but what if you use +[eyes](https://github.com/cloudhead/eyes.js) for nice colored output and it +truncates the output with `…`? Don't fear, there's also a solution for that, +you just need to increase the `maxLength` limit by creating a custom inspector +`var inspect = require('eyes').inspector({maxLength: false})` and then you can +easily `inspect(result)`. + +XML builder usage +----------------- + +Since 0.4.0, objects can be also be used to build XML: + +```javascript +var fs = require('fs'), + xml2js = require('xml2js'); + +var obj = {name: "Super", Surname: "Man", age: 23}; + +var builder = new xml2js.Builder(); +var xml = builder.buildObject(obj); +``` + +At the moment, a one to one bi-directional conversion is guaranteed only for +default configuration, except for `attrkey`, `charkey` and `explicitArray` options +you can redefine to your taste. Writing CDATA is not currently supported. + +Processing attribute and tag names +---------------------------------- + +Since 0.4.1 you can optionally provide the parser with attribute and tag name processors: + +```javascript + +function nameToUpperCase(name){ + return name.toUpperCase(); +} + +//transform all attribute and tag names to uppercase +parseString(xml, {tagNameProcessors: [nameToUpperCase], attrNameProcessors: [nameToUpperCase]}, function (err, result) { +}); +``` + +The `tagNameProcessors` and `attrNameProcessors` options both accept an `Array` of functions with the following signature: +```javascript +function (name){ + //do something with `name` + return name +} +``` + +Some processors are provided out-of-the-box and can be found in `lib/processors.js`: + +- `normalize`: transforms the name to lowercase. +(Automatically used when `options.normalize` is set to `true`) + +- `firstCharLowerCase`: transforms the first character to lower case. +E.g. 'MyTagName' becomes 'myTagName' + +- `stripPrefix`: strips the xml namespace prefix. E.g `` will become 'Bar'. +(N.B.: the `xmlns` prefix is NOT stripped.) + +Options +======= + +Apart from the default settings, there are a number of options that can be +specified for the parser. Options are specified by ``new Parser({optionName: +value})``. Possible options are: + + * `attrkey` (default: `$`): Prefix that is used to access the attributes. + Version 0.1 default was `@`. + * `charkey` (default: `_`): Prefix that is used to access the character + content. Version 0.1 default was `#`. + * `explicitCharkey` (default: `false`) + * `trim` (default: `false`): Trim the whitespace at the beginning and end of + text nodes. + * `normalizeTags` (default: `false`): Normalize all tag names to lowercase. + * `normalize` (default: `false`): Trim whitespaces inside text nodes. + * `explicitRoot` (default: `true`): Set this if you want to get the root + node in the resulting object. + * `emptyTag` (default: `undefined`): what will the value of empty nodes be. + Default is `{}`. + * `explicitArray` (default: `true`): Always put child nodes in an array if + true; otherwise an array is created only if there is more than one. + * `ignoreAttrs` (default: `false`): Ignore all XML attributes and only create + text nodes. + * `mergeAttrs` (default: `false`): Merge attributes and child elements as + properties of the parent, instead of keying attributes off a child + attribute object. This option is ignored if `ignoreAttrs` is `false`. + * `validator` (default `null`): You can specify a callable that validates + the resulting structure somehow, however you want. See unit tests + for an example. + * `xmlns` (default `false`): Give each element a field usually called '$ns' + (the first character is the same as attrkey) that contains its local name + and namespace URI. + * `explicitChildren` (default `false`): Put child elements to separate + property. Doesn't work with `mergeAttrs = true`. If element has no children + then "children" won't be created. Added in 0.2.5. + * `childkey` (default `$$`): Prefix that is used to access child elements if + `explicitChildren` is set to `true`. Added in 0.2.5. + * `charsAsChildren` (default `false`): Determines whether chars should be + considered children if `explicitChildren` is on. Added in 0.2.5. + * `async` (default `false`): Should the callbacks be async? This *might* be + an incompatible change if your code depends on sync execution of callbacks. + xml2js 0.3 might change this default, so the recommendation is to not + depend on sync execution anyway. Added in 0.2.6. + * `strict` (default `true`): Set sax-js to strict or non-strict parsing mode. + Defaults to `true` which is *highly* recommended, since parsing HTML which + is not well-formed XML might yield just about anything. Added in 0.2.7. + * `attrNameProcessors` (default: `null`): Allows the addition of attribute name processing functions. + Accepts an `Array` of functions with following signature: + ```javascript + function (name){ + //do something with `name` + return name + } + ``` + Added in 0.4.1 + * `tagNameProcessors` (default: `null`):Allows the addition of tag name processing functions. + Accepts an `Array` of functions with following signature: + ```javascript + function (name){ + //do something with `name` + return name + } + ``` + Added in 0.4.1 + +Options for the `Builder` class +------------------------------- + + * `rootName` (default `root`): root element name to be used in case + `explicitRoot` is `false` or to override the root element name. + * `renderOpts` (default `{ 'pretty': true, 'indent': ' ', 'newline': '\n' }`): + Rendering options for xmlbuilder-js. + * pretty: prettify generated XML + * indent: whitespace for indentation (only when pretty) + * newline: newline char (only when pretty) + * `xmldec` (default `{ 'version': '1.0', 'encoding': 'UTF-8', 'standalone': true }`: + XML declaration attributes. + * `xmldec.version` A version number string, e.g. 1.0 + * `xmldec.encoding` Encoding declaration, e.g. UTF-8 + * `xmldec.standalone` standalone document declaration: true or false + * `doctype` (default `null`): optional DTD. Eg. `{'ext': 'hello.dtd'}` + * `headless` (default: `false`): omit the XML header. Added in 0.4.3. + +`renderOpts`, `xmldec`,`doctype` and `headless` pass through to +[xmlbuilder-js](https://github.com/oozcitak/xmlbuilder-js). + +Updating to new version +======================= + +Version 0.2 changed the default parsing settings, but version 0.1.14 introduced +the default settings for version 0.2, so these settings can be tried before the +migration. + +```javascript +var xml2js = require('xml2js'); +var parser = new xml2js.Parser(xml2js.defaults["0.2"]); +``` + +To get the 0.1 defaults in version 0.2 you can just use +`xml2js.defaults["0.1"]` in the same place. This provides you with enough time +to migrate to the saner way of parsing in xml2js 0.2. We try to make the +migration as simple and gentle as possible, but some breakage cannot be +avoided. + +So, what exactly did change and why? In 0.2 we changed some defaults to parse +the XML in a more universal and sane way. So we disabled `normalize` and `trim` +so xml2js does not cut out any text content. You can reenable this at will of +course. A more important change is that we return the root tag in the resulting +JavaScript structure via the `explicitRoot` setting, so you need to access the +first element. This is useful for anybody who wants to know what the root node +is and preserves more information. The last major change was to enable +`explicitArray`, so everytime it is possible that one might embed more than one +sub-tag into a tag, xml2js >= 0.2 returns an array even if the array just +includes one element. This is useful when dealing with APIs that return +variable amounts of subtags. + +Running tests, development +========================== + +[![Build Status](https://secure.travis-ci.org/Leonidas-from-XIV/node-xml2js.png?branch=master)](https://travis-ci.org/Leonidas-from-XIV/node-xml2js) +[![Dependency Status](https://david-dm.org/Leonidas-from-XIV/node-xml2js.png)](https://david-dm.org/Leonidas-from-XIV/node-xml2js) + +The development requirements are handled by npm, you just need to install them. +We also have a number of unit tests, they can be run using `npm test` directly +from the project root. This runs zap to discover all the tests and execute +them. + +If you like to contribute, keep in mind that xml2js is written in CoffeeScript, +so don't develop on the JavaScript files that are checked into the repository +for convenience reasons. Also, please write some unit test to check your +behaviour and if it is some user-facing thing, add some documentation to this +README, so people will know it exists. Thanks in advance! diff --git a/www/node_modules/xml2js/canon.xml b/www/node_modules/xml2js/canon.xml new file mode 100644 index 0000000..f24ddd1 --- /dev/null +++ b/www/node_modules/xml2js/canon.xml @@ -0,0 +1,482 @@ + + + AF485783 + 14758 + double + DNA + circular + SYN + 15-MAY-2003 + 21-MAR-2002 + Binary vector pBI121, complete sequence + AF485783 + AF485783.1 + + gb|AF485783.1| + gi|19569229 + + Binary vector pBI121 + Binary vector pBI121 + other sequences; artificial sequences; vectors + + + 1 + 1..14758 + + Chen,P.Y. + Wang,C.K. + Soong,S.C. + To,K.Y. + + Complete sequence of the binary vector pBI121 and its application in cloning T-DNA insertion from transgenic plants + Mol. Breed. 11, 287-293 (2003) + + + 2 + 1..14758 + + To,K.Y. + + Direct Submission + Submitted (20-FEB-2002) Institute of BioAgricultural Sciences, Academia Sinica, Taipei 11529, Taiwan + + + + + source + 1..14758 + + + 1 + 14758 + AF485783.1 + + + + + organism + Binary vector pBI121 + + + mol_type + genomic DNA + + + db_xref + taxon:189807 + + + note + constructed using pB221 from Clontech Laboratories and Bin19 described in GenBank Accession Number U09365 + + + + + misc_feature + complement(13..796) + + + 796 + 13 + + AF485783.1 + + + + + note + similar to traF in GenBank Accession Number X54459 + + + + + rep_origin + complement(790..1168) + + + 1168 + 790 + + AF485783.1 + + + + + note + ColE1 ori; similar to sequence in GenBank Accession Number V00268 + + + + + misc_feature + complement(1161..2344) + + + 2344 + 1161 + + AF485783.1 + + + + + note + similar to tetA in GenBank Accession Number X75761 + + + + + misc_feature + complement(2454..2478) + + + 2478 + 2454 + + AF485783.1 + + + + + note + T-DNA right border + + + + + promoter + 2519..2825 + + + 2519 + 2825 + AF485783.1 + + + + + note + NOS + + + + + gene + 2838..3632 + + + 2838 + 3632 + AF485783.1 + + + + + gene + nptII + + + + + CDS + 2838..3632 + + + 2838 + 3632 + AF485783.1 + + + + + gene + nptII + + + codon_start + 1 + + + transl_table + 1 + + + product + neomycin phosphotransferase II + + + protein_id + AAL92039.1 + + + db_xref + GI:19569230 + + + translation + MIEQDGLHAGSPAAWVERLFGYDWAQQTIGCSDAAVFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLLLGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAGLVDQDDLDEEHQGLAPAELFARLKARMPDGDDLVVTHGDACLPNIMVENGRFSGFIDCGRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF + + + + + terminator + 4022..4277 + + + 4022 + 4277 + AF485783.1 + + + + + note + NOS + + + + + promoter + 4974..5808 + + + 4974 + 5808 + AF485783.1 + + + + + note + CaMV 35S + + + + + gene + 5845..7656 + + + 5845 + 7656 + AF485783.1 + + + + + gene + gusA + + + + + CDS + 5845..7656 + + + 5845 + 7656 + AF485783.1 + + + + + gene + gusA + + + note + GUS + + + codon_start + 1 + + + transl_table + 1 + + + product + beta-glucuronidase + + + protein_id + AAL92040.1 + + + db_xref + GI:19569231 + + + translation + MLRPVETPTREIKKLDGLWAFSLDRENCGIDQRWWESALQESRAIAVPGSFNDQFADADIRNYAGNVWYQREVFIPKGWAGQRIVLRFDAVTHYGKVWVNNQEVMEHQGGYTPFEADVTPYVIAGKSVRITVCVNNELNWQTIPPGMVITDENGKKKQSYFHDFFNYAGIHRSVMLYTTPNTWVDDITVVTHVAQDCNHASVDWQVVANGDVSVELRDADQQVVATGQGTSGTLQVVNPHLWQPGEGYLYELCVTAKSQTECDIYPLRVGIRSVAVKGEQFLINHKPFYFTGFGRHEDADLRGKGFDNVLMVHDHALMDWIGANSYRTSHYPYAEEMLDWADEHGIVVIDETAAVGFNLSLGIGFEAGNKPKELYSEEAVNGETQQAHLQAIKELIARDKNHPSVVMWSIANEPDTRPQGAREYFAPLAEATRKLDPTRPITCVNVMFCDAHTDTISDLFDVLCLNRYYGWYVQSGDLETAEKVLEKELLAWQEKLHQPIIITEYGVDTLAGLHSMYTDMWSEEYQCAWLDMYHRVFDRVSAVVGEQVWNFADFATSQGILRVGGNKKGIFTRDRKPKSAAFLLQKRWTGMNFGEKPQQGGKQ + + + + + terminator + 7727..7979 + + + 7727 + 7979 + AF485783.1 + + + + + note + NOS + + + + + misc_feature + complement(8621..8646) + + + 8646 + 8621 + + AF485783.1 + + + + + note + T-DNA left border + + + + + misc_feature + complement(9156..10198) + + + 10198 + 9156 + + AF485783.1 + + + + + note + similar to tetA in GenBank Accession Number L13842 + + + + + misc_feature + complement(10199..11680) + + + 11680 + 10199 + + AF485783.1 + + + + + note + similar to trfA in GenBank Accession Number X00713 + + + + + misc_feature + complement(11681..12673) + + + 12673 + 11681 + + AF485783.1 + + + + + note + similar to NPTIII gene in GenBank Accession Number V01547 + + + + + misc_feature + complement(12674..13443) + + + 13443 + 12674 + + AF485783.1 + + + + + note + similar to transposable element IS1 in GenBank Accession Number X58999 + + + + + misc_feature + complement(13444..13794) + + + 13794 + 13444 + + AF485783.1 + + + + + note + similarity to NPT III gene in GenBank Accession Number V01547 + + + + + misc_feature + complement(13795..14066) + + + 14066 + 13795 + + AF485783.1 + + + + + note + similar to kilA in GenBank Accession Number M62846 + + + + + rep_origin + complement(14141..14758) + + + 14758 + 14141 + + AF485783.1 + + + + + note + ori V; similar to sequence in GenBank Accession Number M20134 + + + + + tgagcgtcgcaaaggcgctcggtcttgccttgctcgtcggtgatgtacttcaccagctccgcgaagtcgctcttcttgatggagcgcatggggacgtgcttggcaatcacgcgcaccccccggccgttttagcggctaaaaaagtcatggctctgccctcgggcggaccacgcccatcatgaccttgccaagctcgtcctgcttctcttcgatcttcgccagcagggcgaggatcgtggcatcaccgaaccgcgccgtgcgcgggtcgtcggtgagccagagtttcagcaggccgcccaggcggcccaggtcgccattgatgcgggccagctcgcggacgtgctcatagtccacgacgcccgtgattttgtagccctggccgacggccagcaggtaggccgacaggctcatgccggccgccgccgccttttcctcaatcgctcttcgttcgtctggaaggcagtacaccttgataggtgggctgcccttcctggttggcttggtttcatcagccatccgcttgccctcatctgttacgccggcggtagccggccagcctcgcagagcaggattcccgttgagcaccgccaggtgcgaataagggacagtgaagaaggaacacccgctcgcgggtgggcctacttcacctatcctgcccggctgacgccgttggatacaccaaggaaagtctacacgaaccctttggcaaaatcctgtatatcgtgcgaaaaaggatggatataccgaaaaaatcgctataatgaccccgaagcagggttatgcagcggaaaagcgccacgcttcccgaagggagaaaggcggacaggtatccggtaagcggcagggtcggaacaggagagcgcacgagggagcttccagggggaaacgcctggtatctttatagtcctgtcgggtttcgccacctctgacttgagcgtcgatttttgtgatgctcgtcaggggggcggagcctatggaaaaacgccagcaacgcggcctttttacggttcctggccttttgctggccttttgctcacatgttctttcctgcgttatcccctgattctgtggataaccgtattaccgcctttgagtgagctgataccgctcgccgcagccgaacgaccgagcgcagcgagtcagtgagcgaggaagcggaagagcgccagaaggccgccagagaggccgagcgcggccgtgaggcttggacgctagggcagggcatgaaaaagcccgtagcgggctgctacgggcgtctgacgcggtggaaagggggaggggatgttgtctacatggctctgctgtagtgagtgggttgcgctccggcagcggtcctgatcaatcgtcaccctttctcggtccttcaacgttcctgacaacgagcctccttttcgccaatccatcgacaatcaccgcgagtccctgctcgaacgctgcgtccggaccggcttcgtcgaaggcgtctatcgcggcccgcaacagcggcgagagcggagcctgttcaacggtgccgccgcgctcgccggcatcgctgtcgccggcctgctcctcaagcacggccccaacagtgaagtagctgattgtcatcagcgcattgacggcgtccccggccgaaaaacccgcctcgcagaggaagcgaagctgcgcgtcggccgtttccatctgcggtgcgcccggtcgcgtgccggcatggatgcgcgcgccatcgcggtaggcgagcagcgcctgcctgaagctgcgggcattcccgatcagaaatgagcgccagtcgtcgtcggctctcggcaccgaatgcgtatgattctccgccagcatggcttcggccagtgcgtcgagcagcgcccgcttgttcctgaagtgccagtaaagcgccggctgctgaacccccaaccgttccgccagtttgcgtgtcgtcagaccgtctacgccgacctcgttcaacaggtccagggcggcacggatcactgtattcggctgcaactttgtcatgcttgacactttatcactgataaacataatatgtccaccaacttatcagtgataaagaatccgcgcgttcaatcggaccagcggaggctggtccggaggccagacgtgaaacccaacatacccctgatcgtaattctgagcactgtcgcgctcgacgctgtcggcatcggcctgattatgccggtgctgccgggcctcctgcgcgatctggttcactcgaacgacgtcaccgcccactatggcattctgctggcgctgtatgcgttggtgcaatttgcctgcgcacctgtgctgggcgcgctgtcggatcgtttcgggcggcggccaatcttgctcgtctcgctggccggcgccagatctggggaaccctgtggttggcatgcacatacaaatggacgaacggataaaccttttcacgcccttttaaatatccgattattctaataaacgctcttttctcttaggtttacccgccaatatatcctgtcaaacactgatagtttaaactgaaggcgggaaacgacaatctgatcatgagcggagaattaagggagtcacgttatgacccccgccgatgacgcgggacaagccgttttacgtttggaactgacagaaccgcaacgttgaaggagccactcagccgcgggtttctggagtttaatgagctaagcacatacgtcagaaaccattattgcgcgttcaaaagtcgcctaaggtcactatcagctagcaaatatttcttgtcaaaaatgctccactgacgttccataaattcccctcggtatccaattagagtctcatattcactctcaatccaaataatctgcaccggatctggatcgtttcgcatgattgaacaagatggattgcacgcaggttctccggccgcttgggtggagaggctattcggctatgactgggcacaacagacaatcggctgctctgatgccgccgtgttccggctgtcagcgcaggggcgcccggttctttttgtcaagaccgacctgtccggtgccctgaatgaactgcaggacgaggcagcgcggctatcgtggctggccacgacgggcgttccttgcgcagctgtgctcgacgttgtcactgaagcgggaagggactggctgctattgggcgaagtgccggggcaggatctcctgtcatctcaccttgctcctgccgagaaagtatccatcatggctgatgcaatgcggcggctgcatacgcttgatccggctacctgcccattcgaccaccaagcgaaacatcgcatcgagcgagcacgtactcggatggaagccggtcttgtcgatcaggatgatctggacgaagagcatcaggggctcgcgccagccgaactgttcgccaggctcaaggcgcgcatgcccgacggcgatgatctcgtcgtgacccatggcgatgcctgcttgccgaatatcatggtggaaaatggccgcttttctggattcatcgactgtggccggctgggtgtggcggaccgctatcaggacatagcgttggctacccgtgatattgctgaagagcttggcggcgaatgggctgaccgcttcctcgtgctttacggtatcgccgctcccgattcgcagcgcatcgccttctatcgccttcttgacgagttcttctgagcgggactctggggttcgaaatgaccgaccaagcgacgcccaacctgccatcacgagatttcgattccaccgccgccttctatgaaaggttgggcttcggaatcgttttccgggacgccggctggatgatcctccagcgcggggatctcatgctggagttcttcgcccacgggatctctgcggaacaggcggtcgaaggtgccgatatcattacgacagcaacggccgacaagcacaacgccacgatcctgagcgacaatatgatcgggcccggcgtccacatcaacggcgtcggcggcgactgcccaggcaagaccgagatgcaccgcgatatcttgctgcgttcggatattttcgtggagttcccgccacagacccggatgatccccgatcgttcaaacatttggcaataaagtttcttaagattgaatcctgttgccggtcttgcgatgattatcatataatttctgttgaattacgttaagcatgtaataattaacatgtaatgcatgacgttatttatgagatgggtttttatgattagagtcccgcaattatacatttaatacgcgatagaaaacaaaatatagcgcgcaaactaggataaattatcgcgcgcggtgtcatctatgttactagatcgggcctcctgtcaatgctggcggcggctctggtggtggttctggtggcggctctgagggtggtggctctgagggtggcggttctgagggtggcggctctgagggaggcggttccggtggtggctctggttccggtgattttgattatgaaaagatggcaaacgctaataagggggctatgaccgaaaatgccgatgaaaacgcgctacagtctgacgctaaaggcaaacttgattctgtcgctactgattacggtgctgctatcgatggtttcattggtgacgtttccggccttgctaatggtaatggtgctactggtgattttgctggctctaattcccaaatggctcaagtcggtgacggtgataattcacctttaatgaataatttccgtcaatatttaccttccctccctcaatcggttgaatgtcgcccttttgtctttggcccaatacgcaaaccgcctctccccgcgcgttggccgattcattaatgcagctggcacgacaggtttcccgactggaaagcgggcagtgagcgcaacgcaattaatgtgagttagctcactcattaggcaccccaggctttacactttatgcttccggctcgtatgttgtgtggaattgtgagcggataacaatttcacacaggaaacagctatgaccatgattacgccaagcttgcatgcctgcaggtccccagattagccttttcaatttcagaaagaatgctaacccacagatggttagagaggcttacgcagcaggtctcatcaagacgatctacccgagcaataatctccaggaaatcaaataccttcccaagaaggttaaagatgcagtcaaaagattcaggactaactgcatcaagaacacagagaaagatatatttctcaagatcagaagtactattccagtatggacgattcaaggcttgcttcacaaaccaaggcaagtaatagagattggagtctctaaaaaggtagttcccactgaatcaaaggccatggagtcaaagattcaaatagaggacctaacagaactcgccgtaaagactggcgaacagttcatacagagtctcttacgactcaatgacaagaagaaaatcttcgtcaacatggtggagcacgacacacttgtctactccaaaaatatcaaagatacagtctcagaagaccaaagggcaattgagacttttcaacaaagggtaatatccggaaacctcctcggattccattgcccagctatctgtcactttattgtgaagatagtggaaaaggaaggtggctcctacaaatgccatcattgcgataaaggaaaggccatcgttgaagatgcctctgccgacagtggtcccaaagatggacccccacccacgaggagcatcgtggaaaaagaagacgttccaaccacgtcttcaaagcaagtggattgatgtgatatctccactgacgtaagggatgacgcacaatcccactatccttcgcaagacccttcctctatataaggaagttcatttcatttggagagaacacgggggactctagaggatccccgggtggtcagtcccttatgttacgtcctgtagaaaccccaacccgtgaaatcaaaaaactcgacggcctgtgggcattcagtctggatcgcgaaaactgtggaattgatcagcgttggtgggaaagcgcgttacaagaaagccgggcaattgctgtgccaggcagttttaacgatcagttcgccgatgcagatattcgtaattatgcgggcaacgtctggtatcagcgcgaagtctttataccgaaaggttgggcaggccagcgtatcgtgctgcgtttcgatgcggtcactcattacggcaaagtgtgggtcaataatcaggaagtgatggagcatcagggcggctatacgccatttgaagccgatgtcacgccgtatgttattgccgggaaaagtgtacgtatcaccgtttgtgtgaacaacgaactgaactggcagactatcccgccgggaatggtgattaccgacgaaaacggcaagaaaaagcagtcttacttccatgatttctttaactatgccggaatccatcgcagcgtaatgctctacaccacgccgaacacctgggtggacgatatcaccgtggtgacgcatgtcgcgcaagactgtaaccacgcgtctgttgactggcaggtggtggccaatggtgatgtcagcgttgaactgcgtgatgcggatcaacaggtggttgcaactggacaaggcactagcgggactttgcaagtggtgaatccgcacctctggcaaccgggtgaaggttatctctatgaactgtgcgtcacagccaaaagccagacagagtgtgatatctacccgcttcgcgtcggcatccggtcagtggcagtgaagggcgaacagttcctgattaaccacaaaccgttctactttactggctttggtcgtcatgaagatgcggacttgcgtggcaaaggattcgataacgtgctgatggtgcacgaccacgcattaatggactggattggggccaactcctaccgtacctcgcattacccttacgctgaagagatgctcgactgggcagatgaacatggcatcgtggtgattgatgaaactgctgctgtcggctttaacctctctttaggcattggtttcgaagcgggcaacaagccgaaagaactgtacagcgaagaggcagtcaacggggaaactcagcaagcgcacttacaggcgattaaagagctgatagcgcgtgacaaaaaccacccaagcgtggtgatgtggagtattgccaacgaaccggatacccgtccgcaaggtgcacgggaatatttcgcgccactggcggaagcaacgcgtaaactcgacccgacgcgtccgatcacctgcgtcaatgtaatgttctgcgacgctcacaccgataccatcagcgatctctttgatgtgctgtgcctgaaccgttattacggatggtatgtccaaagcggcgatttggaaacggcagagaaggtactggaaaaagaacttctggcctggcaggagaaactgcatcagccgattatcatcaccgaatacggcgtggatacgttagccgggctgcactcaatgtacaccgacatgtggagtgaagagtatcagtgtgcatggctggatatgtatcaccgcgtctttgatcgcgtcagcgccgtcgtcggtgaacaggtatggaatttcgccgattttgcgacctcgcaaggcatattgcgcgttggcggtaacaagaaagggatcttcactcgcgaccgcaaaccgaagtcggcggcttttctgctgcaaaaacgctggactggcatgaacttcggtgaaaaaccgcagcagggaggcaaacaatgaatcaacaactctcctggcgcaccatcgtcggctacagcctcgggaattgctaccgagctcgaatttccccgatcgttcaaacatttggcaataaagtttcttaagattgaatcctgttgccggtcttgcgatgattatcatataatttctgttgaattacgttaagcatgtaataattaacatgtaatgcatgacgttatttatgagatgggtttttatgattagagtcccgcaattatacatttaatacgcgatagaaaacaaaatatagcgcgcaaactaggataaattatcgcgcgcggtgtcatctatgttactagatcgggaattcactggccgtcgttttacaacgtcgtgactgggaaaaccctggcgttacccaacttaatcgccttgcagcacatccccctttcgccagctggcgtaatagcgaagaggcccgcaccgatcgcccttcccaacagttgcgcagcctgaatggcgcccgctcctttcgctttcttcccttcctttctcgccacgttcgccggctttccccgtcaagctctaaatcgggggctccctttagggttccgatttagtgctttacggcacctcgaccccaaaaaacttgatttgggtgatggttcacgtagtgggccatcgccctgatagacggtttttcgccctttgacgttggagtccacgttctttaatagtggactcttgttccaaactggaacaacactcaaccctatctcgggctattcttttgatttataagggattttgccgatttcggaaccaccatcaaacaggattttcgcctgctggggcaaaccagcgtggaccgcttgctgcaactctctcagggccaggcggtgaagggcaatcagctgttgcccgtctcactggtgaaaagaaaaaccaccccagtacattaaaaacgtccgcaatgtgttattaagttgtctaagcgtcaatttgtttacaccacaatatatcctgccaccagccagccaacagctccccgaccggcagctcggcacaaaatcaccactcgatacaggcagcccatcagtccgggacggcgtcagcgggagagccgttgtaaggcggcagactttgctcatgttaccgatgctattcggaagaacggcaactaagctgccgggtttgaaacacggatgatctcgcggagggtagcatgttgattgtaacgatgacagagcgttgctgcctgtgatcaaatatcatctccctcgcagagatccgaattatcagccttcttattcatttctcgcttaaccgtgacaggctgtcgatcttgagaactatgccgacataataggaaatcgctggataaagccgctgaggaagctgagtggcgctatttctttagaagtgaacgttgacgatatcaactcccctatccattgctcaccgaatggtacaggtcggggacccgaagttccgactgtcggcctgatgcatccccggctgatcgaccccagatctggggctgagaaagcccagtaaggaaacaactgtaggttcgagtcgcgagatcccccggaaccaaaggaagtaggttaaacccgctccgatcaggccgagccacgccaggccgagaacattggttcctgtaggcatcgggattggcggatcaaacactaaagctactggaacgagcagaagtcctccggccgccagttgccaggcggtaaaggtgagcagaggcacgggaggttgccacttgcgggtcagcacggttccgaacgccatggaaaccgcccccgccaggcccgctgcgacgccgacaggatctagcgctgcgtttggtgtcaacaccaacagcgccacgcccgcagttccgcaaatagcccccaggaccgccatcaatcgtatcgggctacctagcagagcggcagagatgaacacgaccatcagcggctgcacagcgcctaccgtcgccgcgaccccgcccggcaggcggtagaccgaaataaacaacaagctccagaatagcgaaatattaagtgcgccgaggatgaagatgcgcatccaccagattcccgttggaatctgtcggacgatcatcacgagcaataaacccgccggcaacgcccgcagcagcataccggcgacccctcggcctcgctgttcgggctccacgaaaacgccggacagatgcgccttgtgagcgtccttggggccgtcctcctgtttgaagaccgacagcccaatgatctcgccgtcgatgtaggcgccgaatgccacggcatctcgcaaccgttcagcgaacgcctccatgggctttttctcctcgtgctcgtaaacggacccgaacatctctggagctttcttcagggccgacaatcggatctcgcggaaatcctgcacgtcggccgctccaagccgtcgaatctgagccttaatcacaattgtcaattttaatcctctgtttatcggcagttcgtagagcgcgccgtgcgtcccgagcgatactgagcgaagcaagtgcgtcgagcagtgcccgcttgttcctgaaatgccagtaaagcgctggctgctgaacccccagccggaactgaccccacaaggccctagcgtttgcaatgcaccaggtcatcattgacccaggcgtgttccaccaggccgctgcctcgcaactcttcgcaggcttcgccgacctgctcgcgccacttcttcacgcgggtggaatccgatccgcacatgaggcggaaggtttccagcttgagcgggtacggctcccggtgcgagctgaaatagtcgaacatccgtcgggccgtcggcgacagcttgcggtacttctcccatatgaatttcgtgtagtggtcgccagcaaacagcacgacgatttcctcgtcgatcaggacctggcaacgggacgttttcttgccacggtccaggacgcggaagcggtgcagcagcgacaccgattccaggtgcccaacgcggtcggacgtgaagcccatcgccgtcgcctgtaggcgcgacaggcattcctcggccttcgtgtaataccggccattgatcgaccagcccaggtcctggcaaagctcgtagaacgtgaaggtgatcggctcgccgataggggtgcgcttcgcgtactccaacacctgctgccacaccagttcgtcatcgtcggcccgcagctcgacgccggtgtaggtgatcttcacgtccttgttgacgtggaaaatgaccttgttttgcagcgcctcgcgcgggattttcttgttgcgcgtggtgaacagggcagagcgggccgtgtcgtttggcatcgctcgcatcgtgtccggccacggcgcaatatcgaacaaggaaagctgcatttccttgatctgctgcttcgtgtgtttcagcaacgcggcctgcttggcctcgctgacctgttttgccaggtcctcgccggcggtttttcgcttcttggtcgtcatagttcctcgcgtgtcgatggtcatcgacttcgccaaacctgccgcctcctgttcgagacgacgcgaacgctccacggcggccgatggcgcgggcagggcagggggagccagttgcacgctgtcgcgctcgatcttggccgtagcttgctggaccatcgagccgacggactggaaggtttcgcggggcgcacgcatgacggtgcggcttgcgatggtttcggcatcctcggcggaaaaccccgcgtcgatcagttcttgcctgtatgccttccggtcaaacgtccgattcattcaccctccttgcgggattgccccgactcacgccggggcaatgtgcccttattcctgatttgacccgcctggtgccttggtgtccagataatccaccttatcggcaatgaagtcggtcccgtagaccgtctggccgtccttctcgtacttggtattccgaatcttgccctgcacgaataccagcgaccccttgcccaaatacttgccgtgggcctcggcctgagagccaaaacacttgatgcggaagaagtcggtgcgctcctgcttgtcgccggcatcgttgcgccacatctaggtactaaaacaattcatccagtaaaatataatattttattttctcccaatcaggcttgatccccagtaagtcaaaaaatagctcgacatactgttcttccccgatatcctccctgatcgaccggacgcagaaggcaatgtcataccacttgtccgccctgccgcttctcccaagatcaataaagccacttactttgccatctttcacaaagatgttgctgtctcccaggtcgccgtgggaaaagacaagttcctcttcgggcttttccgtctttaaaaaatcatacagctcgcgcggatctttaaatggagtgtcttcttcccagttttcgcaatccacatcggccagatcgttattcagtaagtaatccaattcggctaagcggctgtctaagctattcgtatagggacaatccgatatgtcgatggagtgaaagagcctgatgcactccgcatacagctcgataatcttttcagggctttgttcatcttcatactcttccgagcaaaggacgccatcggcctcactcatgagcagattgctccagccatcatgccgttcaaagtgcaggacctttggaacaggcagctttccttccagccatagcatcatgtccttttcccgttccacatcataggtggtccctttataccggctgtccgtcatttttaaatataggttttcattttctcccaccagcttatataccttagcaggagacattccttccgtatcttttacgcagcggtatttttcgatcagttttttcaattccggtgatattctcattttagccatttattatttccttcctcttttctacagtatttaaagataccccaagaagctaattataacaagacgaactccaattcactgttccttgcattctaaaaccttaaataccagaaaacagctttttcaaagttgttttcaaagttggcgtataacatagtatcgacggagccgattttgaaaccacaattatgggtgatgctgccaacttactgatttagtgtatgatggtgtttttgaggtgctccagtggcttctgtgtctatcagctgtccctcctgttcagctactgacggggtggtgcgtaacggcaaaagcaccgccggacatcagcgctatctctgctctcactgccgtaaaacatggcaactgcagttcacttacaccgcttctcaacccggtacgcaccagaaaatcattgatatggccatgaatggcgttggatgccgggcaacagcccgcattatgggcgttggcctcaacacgattttacgtcacttaaaaaactcaggccgcagtcggtaacctcgcgcatacagccgggcagtgacgtcatcgtctgcgcggaaatggacgaacagtggggctatgtcggggctaaatcgcgccagcgctggctgttttacgcgtatgacagtctccggaagacggttgttgcgcacgtattcggtgaacgcactatggcgacgctggggcgtcttatgagcctgctgtcaccctttgacgtggtgatatggatgacggatggctggccgctgtatgaatcccgcctgaagggaaagctgcacgtaatcagcaagcgatatacgcagcgaattgagcggcataacctgaatctgaggcagcacctggcacggctgggacggaagtcgctgtcgttctcaaaatcggtggagctgcatgacaaagtcatcgggcattatctgaacataaaacactatcaataagttggagtcattacccaattatgatagaatttacaagctataaggttattgtcctgggtttcaagcattagtccatgcaagtttttatgctttgcccattctatagatatattgataagcgcgctgcctatgccttgccccctgaaatccttacatacggcgatatcttctatataaaagatatattatcttatcagtattgtcaatatattcaaggcaatctgcctcctcatcctcttcatcctcttcgtcttggtagctttttaaatatggcgcttcatagagtaattctgtaaaggtccaattctcgttttcatacctcggtataatcttacctatcacctcaaatggttcgctgggtttatcgcacccccgaacacgagcacggcacccgcgaccactatgccaagaatgcccaaggtaaaaattgccggccccgccatgaagtccgtgaatgccccgacggccgaagtgaagggcaggccgccacccaggccgccgccctcactgcccggcacctggtcgctgaatgtcgatgccagcacctgcggcacgtcaatgcttccgggcgtcgcgctcgggctgatcgcccatcccgttactgccccgatcccggcaatggcaaggactgccagcgctgccatttttggggtgaggccgttcgcggccgaggggcgcagcccctggggggatgggaggcccgcgttagcgggccgggagggttcgagaagggggggcaccccccttcggcgtgcgcggtcacgcgcacagggcgcagccctggttaaaaacaaggtttataaatattggtttaaaagcaggttaaaagacaggttagcggtggccgaaaaacgggcggaaacccttgcaaatgctggattttctgcctgtggacagcccctcaaatgtcaataggtgcgcccctcatctgtcagcactctgcccctcaagtgtcaaggatcgcgcccctcatctgtcagtagtcgcgcccctcaagtgtcaataccgcagggcacttatccccaggcttgtccacatcatctgtgggaaactcgcgtaaaatcaggcgttttcgccgatttgcgaggctggccagctccacgtcgccggccgaaatcgagcctgcccctcatctgtcaacgccgcgccgggtgagtcggcccctcaagtgtcaacgtccgcccctcatctgtcagtgagggccaagttttccgcgaggtatccacaacgccggcggccgcggtgtctcgcacacggcttcgacggcgtttctggcgcgtttgcagggccatagacggccgccagcccagcggcgagggcaaccagcccgg + + + \ No newline at end of file diff --git a/www/node_modules/xml2js/incompat.coffee b/www/node_modules/xml2js/incompat.coffee new file mode 100644 index 0000000..5533965 --- /dev/null +++ b/www/node_modules/xml2js/incompat.coffee @@ -0,0 +1,5 @@ +{parseString} = require './lib/xml2js' +xml = '' +parseString xml, (err, result) -> + console.dir result + diff --git a/www/node_modules/xml2js/incompat2.js b/www/node_modules/xml2js/incompat2.js new file mode 100644 index 0000000..31cfbc8 --- /dev/null +++ b/www/node_modules/xml2js/incompat2.js @@ -0,0 +1,7 @@ +var xml2js = require('xml2js'); +var parser = new xml2js.Parser({ + mergeAttrs: true +}); +parser.parseString('', function (err, result) { + console.dir(result); +}); diff --git a/www/node_modules/xml2js/lib/bom.js b/www/node_modules/xml2js/lib/bom.js new file mode 100644 index 0000000..d7f226e --- /dev/null +++ b/www/node_modules/xml2js/lib/bom.js @@ -0,0 +1,15 @@ +// Generated by CoffeeScript 1.7.1 +(function() { + var xml2js; + + xml2js = require('../lib/xml2js'); + + exports.stripBOM = function(str) { + if (str[0] === '\uFEFF') { + return str.substring(1); + } else { + return str; + } + }; + +}).call(this); diff --git a/www/node_modules/xml2js/lib/processors.js b/www/node_modules/xml2js/lib/processors.js new file mode 100644 index 0000000..aeadaef --- /dev/null +++ b/www/node_modules/xml2js/lib/processors.js @@ -0,0 +1,19 @@ +// Generated by CoffeeScript 1.7.1 +(function() { + var prefixMatch; + + prefixMatch = new RegExp(/(?!xmlns)^.*:/); + + exports.normalize = function(str) { + return str.toLowerCase(); + }; + + exports.firstCharLowerCase = function(str) { + return str.charAt(0).toLowerCase() + str.slice(1); + }; + + exports.stripPrefix = function(str) { + return str.replace(prefixMatch, ''); + }; + +}).call(this); diff --git a/www/node_modules/xml2js/lib/xml2js.js b/www/node_modules/xml2js/lib/xml2js.js new file mode 100644 index 0000000..7c1cad3 --- /dev/null +++ b/www/node_modules/xml2js/lib/xml2js.js @@ -0,0 +1,436 @@ +// Generated by CoffeeScript 1.7.1 +(function() { + var bom, builder, events, isEmpty, processName, processors, sax, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + + sax = require('sax'); + + events = require('events'); + + builder = require('xmlbuilder'); + + bom = require('./bom'); + + processors = require('./processors'); + + isEmpty = function(thing) { + return typeof thing === "object" && (thing != null) && Object.keys(thing).length === 0; + }; + + processName = function(processors, processedName) { + var process, _i, _len; + for (_i = 0, _len = processors.length; _i < _len; _i++) { + process = processors[_i]; + processedName = process(processedName); + } + return processedName; + }; + + exports.processors = processors; + + exports.defaults = { + "0.1": { + explicitCharkey: false, + trim: true, + normalize: true, + normalizeTags: false, + attrkey: "@", + charkey: "#", + explicitArray: false, + ignoreAttrs: false, + mergeAttrs: false, + explicitRoot: false, + validator: null, + xmlns: false, + explicitChildren: false, + childkey: '@@', + charsAsChildren: false, + async: false, + strict: true, + attrNameProcessors: null, + tagNameProcessors: null + }, + "0.2": { + explicitCharkey: false, + trim: false, + normalize: false, + normalizeTags: false, + attrkey: "$", + charkey: "_", + explicitArray: true, + ignoreAttrs: false, + mergeAttrs: false, + explicitRoot: true, + validator: null, + xmlns: false, + explicitChildren: false, + childkey: '$$', + charsAsChildren: false, + async: false, + strict: true, + attrNameProcessors: null, + tagNameProcessors: null, + rootName: 'root', + xmldec: { + 'version': '1.0', + 'encoding': 'UTF-8', + 'standalone': true + }, + doctype: null, + renderOpts: { + 'pretty': true, + 'indent': ' ', + 'newline': '\n' + }, + headless: false + } + }; + + exports.ValidationError = (function(_super) { + __extends(ValidationError, _super); + + function ValidationError(message) { + this.message = message; + } + + return ValidationError; + + })(Error); + + exports.Builder = (function() { + function Builder(opts) { + var key, value, _ref; + this.options = {}; + _ref = exports.defaults["0.2"]; + for (key in _ref) { + if (!__hasProp.call(_ref, key)) continue; + value = _ref[key]; + this.options[key] = value; + } + for (key in opts) { + if (!__hasProp.call(opts, key)) continue; + value = opts[key]; + this.options[key] = value; + } + } + + Builder.prototype.buildObject = function(rootObj) { + var attrkey, charkey, render, rootElement, rootName; + attrkey = this.options.attrkey; + charkey = this.options.charkey; + if ((Object.keys(rootObj).length === 1) && (this.options.rootName === exports.defaults['0.2'].rootName)) { + rootName = Object.keys(rootObj)[0]; + rootObj = rootObj[rootName]; + } else { + rootName = this.options.rootName; + } + render = function(element, obj) { + var attr, child, entry, index, key, value, _ref, _ref1; + if (typeof obj !== 'object') { + element.txt(obj); + } else { + for (key in obj) { + if (!__hasProp.call(obj, key)) continue; + child = obj[key]; + if (key === attrkey) { + if (typeof child === "object") { + for (attr in child) { + value = child[attr]; + element = element.att(attr, value); + } + } + } else if (key === charkey) { + element = element.txt(child); + } else if (typeof child === 'object' && ((child != null ? child.constructor : void 0) != null) && ((child != null ? (_ref = child.constructor) != null ? _ref.name : void 0 : void 0) != null) && (child != null ? (_ref1 = child.constructor) != null ? _ref1.name : void 0 : void 0) === 'Array') { + for (index in child) { + if (!__hasProp.call(child, index)) continue; + entry = child[index]; + if (typeof entry === 'string') { + element = element.ele(key, entry).up(); + } else { + element = arguments.callee(element.ele(key), entry).up(); + } + } + } else if (typeof child === "object") { + element = arguments.callee(element.ele(key), child).up(); + } else { + element = element.ele(key, child.toString()).up(); + } + } + } + return element; + }; + rootElement = builder.create(rootName, this.options.xmldec, this.options.doctype, { + headless: this.options.headless + }); + return render(rootElement, rootObj).end(this.options.renderOpts); + }; + + return Builder; + + })(); + + exports.Parser = (function(_super) { + __extends(Parser, _super); + + function Parser(opts) { + this.parseString = __bind(this.parseString, this); + this.reset = __bind(this.reset, this); + this.assignOrPush = __bind(this.assignOrPush, this); + var key, value, _ref; + if (!(this instanceof exports.Parser)) { + return new exports.Parser(opts); + } + this.options = {}; + _ref = exports.defaults["0.2"]; + for (key in _ref) { + if (!__hasProp.call(_ref, key)) continue; + value = _ref[key]; + this.options[key] = value; + } + for (key in opts) { + if (!__hasProp.call(opts, key)) continue; + value = opts[key]; + this.options[key] = value; + } + if (this.options.xmlns) { + this.options.xmlnskey = this.options.attrkey + "ns"; + } + if (this.options.normalizeTags) { + if (!this.options.tagNameProcessors) { + this.options.tagNameProcessors = []; + } + this.options.tagNameProcessors.unshift(processors.normalize); + } + this.reset(); + } + + Parser.prototype.assignOrPush = function(obj, key, newValue) { + if (!(key in obj)) { + if (!this.options.explicitArray) { + return obj[key] = newValue; + } else { + return obj[key] = [newValue]; + } + } else { + if (!(obj[key] instanceof Array)) { + obj[key] = [obj[key]]; + } + return obj[key].push(newValue); + } + }; + + Parser.prototype.reset = function() { + var attrkey, charkey, ontext, stack; + this.removeAllListeners(); + this.saxParser = sax.parser(this.options.strict, { + trim: false, + normalize: false, + xmlns: this.options.xmlns + }); + this.saxParser.errThrown = false; + this.saxParser.onerror = (function(_this) { + return function(error) { + _this.saxParser.resume(); + if (!_this.saxParser.errThrown) { + _this.saxParser.errThrown = true; + return _this.emit("error", error); + } + }; + })(this); + this.saxParser.ended = false; + this.EXPLICIT_CHARKEY = this.options.explicitCharkey; + this.resultObject = null; + stack = []; + attrkey = this.options.attrkey; + charkey = this.options.charkey; + this.saxParser.onopentag = (function(_this) { + return function(node) { + var key, newValue, obj, processedKey, _ref; + obj = {}; + obj[charkey] = ""; + if (!_this.options.ignoreAttrs) { + _ref = node.attributes; + for (key in _ref) { + if (!__hasProp.call(_ref, key)) continue; + if (!(attrkey in obj) && !_this.options.mergeAttrs) { + obj[attrkey] = {}; + } + newValue = node.attributes[key]; + processedKey = _this.options.attrNameProcessors ? processName(_this.options.attrNameProcessors, key) : key; + if (_this.options.mergeAttrs) { + _this.assignOrPush(obj, processedKey, newValue); + } else { + obj[attrkey][processedKey] = newValue; + } + } + } + obj["#name"] = _this.options.tagNameProcessors ? processName(_this.options.tagNameProcessors, node.name) : node.name; + if (_this.options.xmlns) { + obj[_this.options.xmlnskey] = { + uri: node.uri, + local: node.local + }; + } + return stack.push(obj); + }; + })(this); + this.saxParser.onclosetag = (function(_this) { + return function() { + var cdata, emptyStr, err, node, nodeName, obj, old, s, xpath; + obj = stack.pop(); + nodeName = obj["#name"]; + delete obj["#name"]; + cdata = obj.cdata; + delete obj.cdata; + s = stack[stack.length - 1]; + if (obj[charkey].match(/^\s*$/) && !cdata) { + emptyStr = obj[charkey]; + delete obj[charkey]; + } else { + if (_this.options.trim) { + obj[charkey] = obj[charkey].trim(); + } + if (_this.options.normalize) { + obj[charkey] = obj[charkey].replace(/\s{2,}/g, " ").trim(); + } + if (Object.keys(obj).length === 1 && charkey in obj && !_this.EXPLICIT_CHARKEY) { + obj = obj[charkey]; + } + } + if (isEmpty(obj)) { + obj = _this.options.emptyTag !== void 0 ? _this.options.emptyTag : emptyStr; + } + if (_this.options.validator != null) { + xpath = "/" + ((function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = stack.length; _i < _len; _i++) { + node = stack[_i]; + _results.push(node["#name"]); + } + return _results; + })()).concat(nodeName).join("/"); + try { + obj = _this.options.validator(xpath, s && s[nodeName], obj); + } catch (_error) { + err = _error; + _this.emit("error", err); + } + } + if (_this.options.explicitChildren && !_this.options.mergeAttrs && typeof obj === 'object') { + node = {}; + if (_this.options.attrkey in obj) { + node[_this.options.attrkey] = obj[_this.options.attrkey]; + delete obj[_this.options.attrkey]; + } + if (!_this.options.charsAsChildren && _this.options.charkey in obj) { + node[_this.options.charkey] = obj[_this.options.charkey]; + delete obj[_this.options.charkey]; + } + if (Object.getOwnPropertyNames(obj).length > 0) { + node[_this.options.childkey] = obj; + } + obj = node; + } + if (stack.length > 0) { + return _this.assignOrPush(s, nodeName, obj); + } else { + if (_this.options.explicitRoot) { + old = obj; + obj = {}; + obj[nodeName] = old; + } + _this.resultObject = obj; + _this.saxParser.ended = true; + return _this.emit("end", _this.resultObject); + } + }; + })(this); + ontext = (function(_this) { + return function(text) { + var s; + s = stack[stack.length - 1]; + if (s) { + s[charkey] += text; + return s; + } + }; + })(this); + this.saxParser.ontext = ontext; + return this.saxParser.oncdata = (function(_this) { + return function(text) { + var s; + s = ontext(text); + if (s) { + return s.cdata = true; + } + }; + })(this); + }; + + Parser.prototype.parseString = function(str, cb) { + var err; + if ((cb != null) && typeof cb === "function") { + this.on("end", function(result) { + this.reset(); + if (this.options.async) { + return process.nextTick(function() { + return cb(null, result); + }); + } else { + return cb(null, result); + } + }); + this.on("error", function(err) { + this.reset(); + if (this.options.async) { + return process.nextTick(function() { + return cb(err); + }); + } else { + return cb(err); + } + }); + } + if (str.toString().trim() === '') { + this.emit("end", null); + return true; + } + try { + return this.saxParser.write(bom.stripBOM(str.toString())).close(); + } catch (_error) { + err = _error; + if (!(this.saxParser.errThrown || this.saxParser.ended)) { + this.emit('error', err); + return this.saxParser.errThrown = true; + } + } + }; + + return Parser; + + })(events.EventEmitter); + + exports.parseString = function(str, a, b) { + var cb, options, parser; + if (b != null) { + if (typeof b === 'function') { + cb = b; + } + if (typeof a === 'object') { + options = a; + } + } else { + if (typeof a === 'function') { + cb = a; + } + options = {}; + } + parser = new exports.Parser(options); + return parser.parseString(str, cb); + }; + +}).call(this); diff --git a/www/node_modules/xml2js/package.json b/www/node_modules/xml2js/package.json new file mode 100644 index 0000000..a4c768f --- /dev/null +++ b/www/node_modules/xml2js/package.json @@ -0,0 +1,211 @@ +{ + "_args": [ + [ + "xml2js@0.4.4", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver" + ] + ], + "_from": "xml2js@0.4.4", + "_id": "xml2js@0.4.4", + "_inCache": true, + "_installable": true, + "_location": "/xml2js", + "_npmUser": { + "email": "marek@xivilization.net", + "name": "leonidas" + }, + "_npmVersion": "1.4.9", + "_phantomChildren": {}, + "_requested": { + "name": "xml2js", + "raw": "xml2js@0.4.4", + "rawSpec": "0.4.4", + "scope": null, + "spec": "0.4.4", + "type": "version" + }, + "_requiredBy": [ + "/selenium-webdriver" + ], + "_resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz", + "_shasum": "3111010003008ae19240eba17497b57c729c555d", + "_shrinkwrap": null, + "_spec": "xml2js@0.4.4", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/selenium-webdriver", + "author": { + "email": "marek@xivilization.net", + "name": "Marek Kubica", + "url": "http://xivilization.net" + }, + "bugs": { + "url": "https://github.com/Leonidas-from-XIV/node-xml2js/issues" + }, + "contributors": [ + { + "email": "maqr.lollerskates@gmail.com", + "name": "maqr", + "url": "https://github.com/maqr" + }, + { + "name": "Ben Weaver", + "url": "http://benweaver.com/" + }, + { + "name": "Jae Kwon", + "url": "https://github.com/jaekwon" + }, + { + "name": "Jim Robert" + }, + { + "name": "Ștefan Rusu", + "url": "http://www.saltwaterc.eu/" + }, + { + "email": "carter.cole@cartercole.com", + "name": "Carter Cole", + "url": "http://cartercole.com/" + }, + { + "email": "kurt@kurtraschke.com", + "name": "Kurt Raschke", + "url": "http://www.kurtraschke.com/" + }, + { + "email": "contra@australia.edu", + "name": "Contra", + "url": "https://github.com/Contra" + }, + { + "email": "marudiniz@gmail.com", + "name": "Marcelo Diniz", + "url": "https://github.com/mdiniz" + }, + { + "name": "Michael Hart", + "url": "https://github.com/mhart" + }, + { + "email": "zachary@zacharyscott.net", + "name": "Zachary Scott", + "url": "http://zacharyscott.net/" + }, + { + "name": "Raoul Millais", + "url": "https://github.com/raoulmillais" + }, + { + "name": "Salsita Software", + "url": "http://www.salsitasoft.com/" + }, + { + "email": "mike@emotive.com", + "name": "Mike Schilling", + "url": "http://www.emotive.com/" + }, + { + "email": "shyvo1987@gmail.com", + "name": "Jackson Tian", + "url": "http://weibo.com/shyvo" + }, + { + "email": "mikhail.zyatin@gmail.com", + "name": "Mikhail Zyatin", + "url": "https://github.com/Sitin" + }, + { + "email": "ctavares@microsoft.com", + "name": "Chris Tavares", + "url": "https://github.com/christav" + }, + { + "email": "yyfrankyy@gmail.com", + "name": "Frank Xu", + "url": "http://f2e.us/" + }, + { + "email": "guido@bitstorm.it", + "name": "Guido D'Albore", + "url": "http://www.bitstorm.it/" + }, + { + "name": "Jack Senechal", + "url": "http://jacksenechal.com/" + }, + { + "email": "tc@xantira.com", + "name": "Matthias Hölzl", + "url": "https://github.com/hoelzl" + }, + { + "email": "info@creynders.be", + "name": "Camille Reynders", + "url": "http://www.creynders.be/" + }, + { + "name": "Taylor Gautier", + "url": "https://github.com/tsgautier" + }, + { + "name": "Todd Bryan", + "url": "https://github.com/toddrbryan" + }, + { + "email": "leore.avidar@gmail.com", + "name": "Leore Avidar", + "url": "http://leoreavidar.com/" + }, + { + "email": "dave.aitken@gmail.com", + "name": "Dave Aitken", + "url": "http://www.actionshrimp.com/" + } + ], + "dependencies": { + "sax": "0.6.x", + "xmlbuilder": ">=1.0.0" + }, + "description": "Simple XML to JavaScript object converter.", + "devDependencies": { + "coffee-script": ">=1.7.1", + "diff": ">=1.0.8", + "docco": ">=0.6.2", + "zap": ">=0.2.6" + }, + "directories": { + "lib": "./lib" + }, + "dist": { + "shasum": "3111010003008ae19240eba17497b57c729c555d", + "tarball": "http://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz" + }, + "homepage": "https://github.com/Leonidas-from-XIV/node-xml2js", + "keywords": [ + "xml", + "json" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://raw.github.com/Leonidas-from-XIV/node-xml2js/master/LICENSE" + } + ], + "main": "./lib/xml2js", + "maintainers": [ + { + "email": "marek@xivilization.net", + "name": "leonidas" + } + ], + "name": "xml2js", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/Leonidas-from-XIV/node-xml2js.git" + }, + "scripts": { + "test": "zap" + }, + "version": "0.4.4" +} diff --git a/www/node_modules/xml2js/text.coffee b/www/node_modules/xml2js/text.coffee new file mode 100644 index 0000000..c5d8c66 --- /dev/null +++ b/www/node_modules/xml2js/text.coffee @@ -0,0 +1,11 @@ +fs = require 'fs' +xml2js = require 'xml2js' + +parser = new xml2js.Parser + +fs.readFile 'canon.xml', (err, data) -> + console.log err + parser.parseString (err, result) -> + console.log err + console.dir result + diff --git a/www/node_modules/xml2js/text.xml b/www/node_modules/xml2js/text.xml new file mode 100644 index 0000000..bd3b482 --- /dev/null +++ b/www/node_modules/xml2js/text.xml @@ -0,0 +1,485 @@ + + + + + AF485783 + 14758 + double + DNA + circular + SYN + 15-MAY-2003 + 21-MAR-2002 + Binary vector pBI121, complete sequence + AF485783 + AF485783.1 + + gb|AF485783.1| + gi|19569229 + + Binary vector pBI121 + Binary vector pBI121 + other sequences; artificial sequences; vectors + + + 1 + 1..14758 + + Chen,P.Y. + Wang,C.K. + Soong,S.C. + To,K.Y. + + Complete sequence of the binary vector pBI121 and its application in cloning T-DNA insertion from transgenic plants + Mol. Breed. 11, 287-293 (2003) + + + 2 + 1..14758 + + To,K.Y. + + Direct Submission + Submitted (20-FEB-2002) Institute of BioAgricultural Sciences, Academia Sinica, Taipei 11529, Taiwan + + + + + source + 1..14758 + + + 1 + 14758 + AF485783.1 + + + + + organism + Binary vector pBI121 + + + mol_type + genomic DNA + + + db_xref + taxon:189807 + + + note + constructed using pB221 from Clontech Laboratories and Bin19 described in GenBank Accession Number U09365 + + + + + misc_feature + complement(13..796) + + + 796 + 13 + + AF485783.1 + + + + + note + similar to traF in GenBank Accession Number X54459 + + + + + rep_origin + complement(790..1168) + + + 1168 + 790 + + AF485783.1 + + + + + note + ColE1 ori; similar to sequence in GenBank Accession Number V00268 + + + + + misc_feature + complement(1161..2344) + + + 2344 + 1161 + + AF485783.1 + + + + + note + similar to tetA in GenBank Accession Number X75761 + + + + + misc_feature + complement(2454..2478) + + + 2478 + 2454 + + AF485783.1 + + + + + note + T-DNA right border + + + + + promoter + 2519..2825 + + + 2519 + 2825 + AF485783.1 + + + + + note + NOS + + + + + gene + 2838..3632 + + + 2838 + 3632 + AF485783.1 + + + + + gene + nptII + + + + + CDS + 2838..3632 + + + 2838 + 3632 + AF485783.1 + + + + + gene + nptII + + + codon_start + 1 + + + transl_table + 1 + + + product + neomycin phosphotransferase II + + + protein_id + AAL92039.1 + + + db_xref + GI:19569230 + + + translation + MIEQDGLHAGSPAAWVERLFGYDWAQQTIGCSDAAVFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLLLGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAGLVDQDDLDEEHQGLAPAELFARLKARMPDGDDLVVTHGDACLPNIMVENGRFSGFIDCGRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF + + + + + terminator + 4022..4277 + + + 4022 + 4277 + AF485783.1 + + + + + note + NOS + + + + + promoter + 4974..5808 + + + 4974 + 5808 + AF485783.1 + + + + + note + CaMV 35S + + + + + gene + 5845..7656 + + + 5845 + 7656 + AF485783.1 + + + + + gene + gusA + + + + + CDS + 5845..7656 + + + 5845 + 7656 + AF485783.1 + + + + + gene + gusA + + + note + GUS + + + codon_start + 1 + + + transl_table + 1 + + + product + beta-glucuronidase + + + protein_id + AAL92040.1 + + + db_xref + GI:19569231 + + + translation + MLRPVETPTREIKKLDGLWAFSLDRENCGIDQRWWESALQESRAIAVPGSFNDQFADADIRNYAGNVWYQREVFIPKGWAGQRIVLRFDAVTHYGKVWVNNQEVMEHQGGYTPFEADVTPYVIAGKSVRITVCVNNELNWQTIPPGMVITDENGKKKQSYFHDFFNYAGIHRSVMLYTTPNTWVDDITVVTHVAQDCNHASVDWQVVANGDVSVELRDADQQVVATGQGTSGTLQVVNPHLWQPGEGYLYELCVTAKSQTECDIYPLRVGIRSVAVKGEQFLINHKPFYFTGFGRHEDADLRGKGFDNVLMVHDHALMDWIGANSYRTSHYPYAEEMLDWADEHGIVVIDETAAVGFNLSLGIGFEAGNKPKELYSEEAVNGETQQAHLQAIKELIARDKNHPSVVMWSIANEPDTRPQGAREYFAPLAEATRKLDPTRPITCVNVMFCDAHTDTISDLFDVLCLNRYYGWYVQSGDLETAEKVLEKELLAWQEKLHQPIIITEYGVDTLAGLHSMYTDMWSEEYQCAWLDMYHRVFDRVSAVVGEQVWNFADFATSQGILRVGGNKKGIFTRDRKPKSAAFLLQKRWTGMNFGEKPQQGGKQ + + + + + terminator + 7727..7979 + + + 7727 + 7979 + AF485783.1 + + + + + note + NOS + + + + + misc_feature + complement(8621..8646) + + + 8646 + 8621 + + AF485783.1 + + + + + note + T-DNA left border + + + + + misc_feature + complement(9156..10198) + + + 10198 + 9156 + + AF485783.1 + + + + + note + similar to tetA in GenBank Accession Number L13842 + + + + + misc_feature + complement(10199..11680) + + + 11680 + 10199 + + AF485783.1 + + + + + note + similar to trfA in GenBank Accession Number X00713 + + + + + misc_feature + complement(11681..12673) + + + 12673 + 11681 + + AF485783.1 + + + + + note + similar to NPTIII gene in GenBank Accession Number V01547 + + + + + misc_feature + complement(12674..13443) + + + 13443 + 12674 + + AF485783.1 + + + + + note + similar to transposable element IS1 in GenBank Accession Number X58999 + + + + + misc_feature + complement(13444..13794) + + + 13794 + 13444 + + AF485783.1 + + + + + note + similarity to NPT III gene in GenBank Accession Number V01547 + + + + + misc_feature + complement(13795..14066) + + + 14066 + 13795 + + AF485783.1 + + + + + note + similar to kilA in GenBank Accession Number M62846 + + + + + rep_origin + complement(14141..14758) + + + 14758 + 14141 + + AF485783.1 + + + + + note + ori V; similar to sequence in GenBank Accession Number M20134 + + + + + tgagcgtcgcaaaggcgctcggtcttgccttgctcgtcggtgatgtacttcaccagctccgcgaagtcgctcttcttgatggagcgcatggggacgtgcttggcaatcacgcgcaccccccggccgttttagcggctaaaaaagtcatggctctgccctcgggcggaccacgcccatcatgaccttgccaagctcgtcctgcttctcttcgatcttcgccagcagggcgaggatcgtggcatcaccgaaccgcgccgtgcgcgggtcgtcggtgagccagagtttcagcaggccgcccaggcggcccaggtcgccattgatgcgggccagctcgcggacgtgctcatagtccacgacgcccgtgattttgtagccctggccgacggccagcaggtaggccgacaggctcatgccggccgccgccgccttttcctcaatcgctcttcgttcgtctggaaggcagtacaccttgataggtgggctgcccttcctggttggcttggtttcatcagccatccgcttgccctcatctgttacgccggcggtagccggccagcctcgcagagcaggattcccgttgagcaccgccaggtgcgaataagggacagtgaagaaggaacacccgctcgcgggtgggcctacttcacctatcctgcccggctgacgccgttggatacaccaaggaaagtctacacgaaccctttggcaaaatcctgtatatcgtgcgaaaaaggatggatataccgaaaaaatcgctataatgaccccgaagcagggttatgcagcggaaaagcgccacgcttcccgaagggagaaaggcggacaggtatccggtaagcggcagggtcggaacaggagagcgcacgagggagcttccagggggaaacgcctggtatctttatagtcctgtcgggtttcgccacctctgacttgagcgtcgatttttgtgatgctcgtcaggggggcggagcctatggaaaaacgccagcaacgcggcctttttacggttcctggccttttgctggccttttgctcacatgttctttcctgcgttatcccctgattctgtggataaccgtattaccgcctttgagtgagctgataccgctcgccgcagccgaacgaccgagcgcagcgagtcagtgagcgaggaagcggaagagcgccagaaggccgccagagaggccgagcgcggccgtgaggcttggacgctagggcagggcatgaaaaagcccgtagcgggctgctacgggcgtctgacgcggtggaaagggggaggggatgttgtctacatggctctgctgtagtgagtgggttgcgctccggcagcggtcctgatcaatcgtcaccctttctcggtccttcaacgttcctgacaacgagcctccttttcgccaatccatcgacaatcaccgcgagtccctgctcgaacgctgcgtccggaccggcttcgtcgaaggcgtctatcgcggcccgcaacagcggcgagagcggagcctgttcaacggtgccgccgcgctcgccggcatcgctgtcgccggcctgctcctcaagcacggccccaacagtgaagtagctgattgtcatcagcgcattgacggcgtccccggccgaaaaacccgcctcgcagaggaagcgaagctgcgcgtcggccgtttccatctgcggtgcgcccggtcgcgtgccggcatggatgcgcgcgccatcgcggtaggcgagcagcgcctgcctgaagctgcgggcattcccgatcagaaatgagcgccagtcgtcgtcggctctcggcaccgaatgcgtatgattctccgccagcatggcttcggccagtgcgtcgagcagcgcccgcttgttcctgaagtgccagtaaagcgccggctgctgaacccccaaccgttccgccagtttgcgtgtcgtcagaccgtctacgccgacctcgttcaacaggtccagggcggcacggatcactgtattcggctgcaactttgtcatgcttgacactttatcactgataaacataatatgtccaccaacttatcagtgataaagaatccgcgcgttcaatcggaccagcggaggctggtccggaggccagacgtgaaacccaacatacccctgatcgtaattctgagcactgtcgcgctcgacgctgtcggcatcggcctgattatgccggtgctgccgggcctcctgcgcgatctggttcactcgaacgacgtcaccgcccactatggcattctgctggcgctgtatgcgttggtgcaatttgcctgcgcacctgtgctgggcgcgctgtcggatcgtttcgggcggcggccaatcttgctcgtctcgctggccggcgccagatctggggaaccctgtggttggcatgcacatacaaatggacgaacggataaaccttttcacgcccttttaaatatccgattattctaataaacgctcttttctcttaggtttacccgccaatatatcctgtcaaacactgatagtttaaactgaaggcgggaaacgacaatctgatcatgagcggagaattaagggagtcacgttatgacccccgccgatgacgcgggacaagccgttttacgtttggaactgacagaaccgcaacgttgaaggagccactcagccgcgggtttctggagtttaatgagctaagcacatacgtcagaaaccattattgcgcgttcaaaagtcgcctaaggtcactatcagctagcaaatatttcttgtcaaaaatgctccactgacgttccataaattcccctcggtatccaattagagtctcatattcactctcaatccaaataatctgcaccggatctggatcgtttcgcatgattgaacaagatggattgcacgcaggttctccggccgcttgggtggagaggctattcggctatgactgggcacaacagacaatcggctgctctgatgccgccgtgttccggctgtcagcgcaggggcgcccggttctttttgtcaagaccgacctgtccggtgccctgaatgaactgcaggacgaggcagcgcggctatcgtggctggccacgacgggcgttccttgcgcagctgtgctcgacgttgtcactgaagcgggaagggactggctgctattgggcgaagtgccggggcaggatctcctgtcatctcaccttgctcctgccgagaaagtatccatcatggctgatgcaatgcggcggctgcatacgcttgatccggctacctgcccattcgaccaccaagcgaaacatcgcatcgagcgagcacgtactcggatggaagccggtcttgtcgatcaggatgatctggacgaagagcatcaggggctcgcgccagccgaactgttcgccaggctcaaggcgcgcatgcccgacggcgatgatctcgtcgtgacccatggcgatgcctgcttgccgaatatcatggtggaaaatggccgcttttctggattcatcgactgtggccggctgggtgtggcggaccgctatcaggacatagcgttggctacccgtgatattgctgaagagcttggcggcgaatgggctgaccgcttcctcgtgctttacggtatcgccgctcccgattcgcagcgcatcgccttctatcgccttcttgacgagttcttctgagcgggactctggggttcgaaatgaccgaccaagcgacgcccaacctgccatcacgagatttcgattccaccgccgccttctatgaaaggttgggcttcggaatcgttttccgggacgccggctggatgatcctccagcgcggggatctcatgctggagttcttcgcccacgggatctctgcggaacaggcggtcgaaggtgccgatatcattacgacagcaacggccgacaagcacaacgccacgatcctgagcgacaatatgatcgggcccggcgtccacatcaacggcgtcggcggcgactgcccaggcaagaccgagatgcaccgcgatatcttgctgcgttcggatattttcgtggagttcccgccacagacccggatgatccccgatcgttcaaacatttggcaataaagtttcttaagattgaatcctgttgccggtcttgcgatgattatcatataatttctgttgaattacgttaagcatgtaataattaacatgtaatgcatgacgttatttatgagatgggtttttatgattagagtcccgcaattatacatttaatacgcgatagaaaacaaaatatagcgcgcaaactaggataaattatcgcgcgcggtgtcatctatgttactagatcgggcctcctgtcaatgctggcggcggctctggtggtggttctggtggcggctctgagggtggtggctctgagggtggcggttctgagggtggcggctctgagggaggcggttccggtggtggctctggttccggtgattttgattatgaaaagatggcaaacgctaataagggggctatgaccgaaaatgccgatgaaaacgcgctacagtctgacgctaaaggcaaacttgattctgtcgctactgattacggtgctgctatcgatggtttcattggtgacgtttccggccttgctaatggtaatggtgctactggtgattttgctggctctaattcccaaatggctcaagtcggtgacggtgataattcacctttaatgaataatttccgtcaatatttaccttccctccctcaatcggttgaatgtcgcccttttgtctttggcccaatacgcaaaccgcctctccccgcgcgttggccgattcattaatgcagctggcacgacaggtttcccgactggaaagcgggcagtgagcgcaacgcaattaatgtgagttagctcactcattaggcaccccaggctttacactttatgcttccggctcgtatgttgtgtggaattgtgagcggataacaatttcacacaggaaacagctatgaccatgattacgccaagcttgcatgcctgcaggtccccagattagccttttcaatttcagaaagaatgctaacccacagatggttagagaggcttacgcagcaggtctcatcaagacgatctacccgagcaataatctccaggaaatcaaataccttcccaagaaggttaaagatgcagtcaaaagattcaggactaactgcatcaagaacacagagaaagatatatttctcaagatcagaagtactattccagtatggacgattcaaggcttgcttcacaaaccaaggcaagtaatagagattggagtctctaaaaaggtagttcccactgaatcaaaggccatggagtcaaagattcaaatagaggacctaacagaactcgccgtaaagactggcgaacagttcatacagagtctcttacgactcaatgacaagaagaaaatcttcgtcaacatggtggagcacgacacacttgtctactccaaaaatatcaaagatacagtctcagaagaccaaagggcaattgagacttttcaacaaagggtaatatccggaaacctcctcggattccattgcccagctatctgtcactttattgtgaagatagtggaaaaggaaggtggctcctacaaatgccatcattgcgataaaggaaaggccatcgttgaagatgcctctgccgacagtggtcccaaagatggacccccacccacgaggagcatcgtggaaaaagaagacgttccaaccacgtcttcaaagcaagtggattgatgtgatatctccactgacgtaagggatgacgcacaatcccactatccttcgcaagacccttcctctatataaggaagttcatttcatttggagagaacacgggggactctagaggatccccgggtggtcagtcccttatgttacgtcctgtagaaaccccaacccgtgaaatcaaaaaactcgacggcctgtgggcattcagtctggatcgcgaaaactgtggaattgatcagcgttggtgggaaagcgcgttacaagaaagccgggcaattgctgtgccaggcagttttaacgatcagttcgccgatgcagatattcgtaattatgcgggcaacgtctggtatcagcgcgaagtctttataccgaaaggttgggcaggccagcgtatcgtgctgcgtttcgatgcggtcactcattacggcaaagtgtgggtcaataatcaggaagtgatggagcatcagggcggctatacgccatttgaagccgatgtcacgccgtatgttattgccgggaaaagtgtacgtatcaccgtttgtgtgaacaacgaactgaactggcagactatcccgccgggaatggtgattaccgacgaaaacggcaagaaaaagcagtcttacttccatgatttctttaactatgccggaatccatcgcagcgtaatgctctacaccacgccgaacacctgggtggacgatatcaccgtggtgacgcatgtcgcgcaagactgtaaccacgcgtctgttgactggcaggtggtggccaatggtgatgtcagcgttgaactgcgtgatgcggatcaacaggtggttgcaactggacaaggcactagcgggactttgcaagtggtgaatccgcacctctggcaaccgggtgaaggttatctctatgaactgtgcgtcacagccaaaagccagacagagtgtgatatctacccgcttcgcgtcggcatccggtcagtggcagtgaagggcgaacagttcctgattaaccacaaaccgttctactttactggctttggtcgtcatgaagatgcggacttgcgtggcaaaggattcgataacgtgctgatggtgcacgaccacgcattaatggactggattggggccaactcctaccgtacctcgcattacccttacgctgaagagatgctcgactgggcagatgaacatggcatcgtggtgattgatgaaactgctgctgtcggctttaacctctctttaggcattggtttcgaagcgggcaacaagccgaaagaactgtacagcgaagaggcagtcaacggggaaactcagcaagcgcacttacaggcgattaaagagctgatagcgcgtgacaaaaaccacccaagcgtggtgatgtggagtattgccaacgaaccggatacccgtccgcaaggtgcacgggaatatttcgcgccactggcggaagcaacgcgtaaactcgacccgacgcgtccgatcacctgcgtcaatgtaatgttctgcgacgctcacaccgataccatcagcgatctctttgatgtgctgtgcctgaaccgttattacggatggtatgtccaaagcggcgatttggaaacggcagagaaggtactggaaaaagaacttctggcctggcaggagaaactgcatcagccgattatcatcaccgaatacggcgtggatacgttagccgggctgcactcaatgtacaccgacatgtggagtgaagagtatcagtgtgcatggctggatatgtatcaccgcgtctttgatcgcgtcagcgccgtcgtcggtgaacaggtatggaatttcgccgattttgcgacctcgcaaggcatattgcgcgttggcggtaacaagaaagggatcttcactcgcgaccgcaaaccgaagtcggcggcttttctgctgcaaaaacgctggactggcatgaacttcggtgaaaaaccgcagcagggaggcaaacaatgaatcaacaactctcctggcgcaccatcgtcggctacagcctcgggaattgctaccgagctcgaatttccccgatcgttcaaacatttggcaataaagtttcttaagattgaatcctgttgccggtcttgcgatgattatcatataatttctgttgaattacgttaagcatgtaataattaacatgtaatgcatgacgttatttatgagatgggtttttatgattagagtcccgcaattatacatttaatacgcgatagaaaacaaaatatagcgcgcaaactaggataaattatcgcgcgcggtgtcatctatgttactagatcgggaattcactggccgtcgttttacaacgtcgtgactgggaaaaccctggcgttacccaacttaatcgccttgcagcacatccccctttcgccagctggcgtaatagcgaagaggcccgcaccgatcgcccttcccaacagttgcgcagcctgaatggcgcccgctcctttcgctttcttcccttcctttctcgccacgttcgccggctttccccgtcaagctctaaatcgggggctccctttagggttccgatttagtgctttacggcacctcgaccccaaaaaacttgatttgggtgatggttcacgtagtgggccatcgccctgatagacggtttttcgccctttgacgttggagtccacgttctttaatagtggactcttgttccaaactggaacaacactcaaccctatctcgggctattcttttgatttataagggattttgccgatttcggaaccaccatcaaacaggattttcgcctgctggggcaaaccagcgtggaccgcttgctgcaactctctcagggccaggcggtgaagggcaatcagctgttgcccgtctcactggtgaaaagaaaaaccaccccagtacattaaaaacgtccgcaatgtgttattaagttgtctaagcgtcaatttgtttacaccacaatatatcctgccaccagccagccaacagctccccgaccggcagctcggcacaaaatcaccactcgatacaggcagcccatcagtccgggacggcgtcagcgggagagccgttgtaaggcggcagactttgctcatgttaccgatgctattcggaagaacggcaactaagctgccgggtttgaaacacggatgatctcgcggagggtagcatgttgattgtaacgatgacagagcgttgctgcctgtgatcaaatatcatctccctcgcagagatccgaattatcagccttcttattcatttctcgcttaaccgtgacaggctgtcgatcttgagaactatgccgacataataggaaatcgctggataaagccgctgaggaagctgagtggcgctatttctttagaagtgaacgttgacgatatcaactcccctatccattgctcaccgaatggtacaggtcggggacccgaagttccgactgtcggcctgatgcatccccggctgatcgaccccagatctggggctgagaaagcccagtaaggaaacaactgtaggttcgagtcgcgagatcccccggaaccaaaggaagtaggttaaacccgctccgatcaggccgagccacgccaggccgagaacattggttcctgtaggcatcgggattggcggatcaaacactaaagctactggaacgagcagaagtcctccggccgccagttgccaggcggtaaaggtgagcagaggcacgggaggttgccacttgcgggtcagcacggttccgaacgccatggaaaccgcccccgccaggcccgctgcgacgccgacaggatctagcgctgcgtttggtgtcaacaccaacagcgccacgcccgcagttccgcaaatagcccccaggaccgccatcaatcgtatcgggctacctagcagagcggcagagatgaacacgaccatcagcggctgcacagcgcctaccgtcgccgcgaccccgcccggcaggcggtagaccgaaataaacaacaagctccagaatagcgaaatattaagtgcgccgaggatgaagatgcgcatccaccagattcccgttggaatctgtcggacgatcatcacgagcaataaacccgccggcaacgcccgcagcagcataccggcgacccctcggcctcgctgttcgggctccacgaaaacgccggacagatgcgccttgtgagcgtccttggggccgtcctcctgtttgaagaccgacagcccaatgatctcgccgtcgatgtaggcgccgaatgccacggcatctcgcaaccgttcagcgaacgcctccatgggctttttctcctcgtgctcgtaaacggacccgaacatctctggagctttcttcagggccgacaatcggatctcgcggaaatcctgcacgtcggccgctccaagccgtcgaatctgagccttaatcacaattgtcaattttaatcctctgtttatcggcagttcgtagagcgcgccgtgcgtcccgagcgatactgagcgaagcaagtgcgtcgagcagtgcccgcttgttcctgaaatgccagtaaagcgctggctgctgaacccccagccggaactgaccccacaaggccctagcgtttgcaatgcaccaggtcatcattgacccaggcgtgttccaccaggccgctgcctcgcaactcttcgcaggcttcgccgacctgctcgcgccacttcttcacgcgggtggaatccgatccgcacatgaggcggaaggtttccagcttgagcgggtacggctcccggtgcgagctgaaatagtcgaacatccgtcgggccgtcggcgacagcttgcggtacttctcccatatgaatttcgtgtagtggtcgccagcaaacagcacgacgatttcctcgtcgatcaggacctggcaacgggacgttttcttgccacggtccaggacgcggaagcggtgcagcagcgacaccgattccaggtgcccaacgcggtcggacgtgaagcccatcgccgtcgcctgtaggcgcgacaggcattcctcggccttcgtgtaataccggccattgatcgaccagcccaggtcctggcaaagctcgtagaacgtgaaggtgatcggctcgccgataggggtgcgcttcgcgtactccaacacctgctgccacaccagttcgtcatcgtcggcccgcagctcgacgccggtgtaggtgatcttcacgtccttgttgacgtggaaaatgaccttgttttgcagcgcctcgcgcgggattttcttgttgcgcgtggtgaacagggcagagcgggccgtgtcgtttggcatcgctcgcatcgtgtccggccacggcgcaatatcgaacaaggaaagctgcatttccttgatctgctgcttcgtgtgtttcagcaacgcggcctgcttggcctcgctgacctgttttgccaggtcctcgccggcggtttttcgcttcttggtcgtcatagttcctcgcgtgtcgatggtcatcgacttcgccaaacctgccgcctcctgttcgagacgacgcgaacgctccacggcggccgatggcgcgggcagggcagggggagccagttgcacgctgtcgcgctcgatcttggccgtagcttgctggaccatcgagccgacggactggaaggtttcgcggggcgcacgcatgacggtgcggcttgcgatggtttcggcatcctcggcggaaaaccccgcgtcgatcagttcttgcctgtatgccttccggtcaaacgtccgattcattcaccctccttgcgggattgccccgactcacgccggggcaatgtgcccttattcctgatttgacccgcctggtgccttggtgtccagataatccaccttatcggcaatgaagtcggtcccgtagaccgtctggccgtccttctcgtacttggtattccgaatcttgccctgcacgaataccagcgaccccttgcccaaatacttgccgtgggcctcggcctgagagccaaaacacttgatgcggaagaagtcggtgcgctcctgcttgtcgccggcatcgttgcgccacatctaggtactaaaacaattcatccagtaaaatataatattttattttctcccaatcaggcttgatccccagtaagtcaaaaaatagctcgacatactgttcttccccgatatcctccctgatcgaccggacgcagaaggcaatgtcataccacttgtccgccctgccgcttctcccaagatcaataaagccacttactttgccatctttcacaaagatgttgctgtctcccaggtcgccgtgggaaaagacaagttcctcttcgggcttttccgtctttaaaaaatcatacagctcgcgcggatctttaaatggagtgtcttcttcccagttttcgcaatccacatcggccagatcgttattcagtaagtaatccaattcggctaagcggctgtctaagctattcgtatagggacaatccgatatgtcgatggagtgaaagagcctgatgcactccgcatacagctcgataatcttttcagggctttgttcatcttcatactcttccgagcaaaggacgccatcggcctcactcatgagcagattgctccagccatcatgccgttcaaagtgcaggacctttggaacaggcagctttccttccagccatagcatcatgtccttttcccgttccacatcataggtggtccctttataccggctgtccgtcatttttaaatataggttttcattttctcccaccagcttatataccttagcaggagacattccttccgtatcttttacgcagcggtatttttcgatcagttttttcaattccggtgatattctcattttagccatttattatttccttcctcttttctacagtatttaaagataccccaagaagctaattataacaagacgaactccaattcactgttccttgcattctaaaaccttaaataccagaaaacagctttttcaaagttgttttcaaagttggcgtataacatagtatcgacggagccgattttgaaaccacaattatgggtgatgctgccaacttactgatttagtgtatgatggtgtttttgaggtgctccagtggcttctgtgtctatcagctgtccctcctgttcagctactgacggggtggtgcgtaacggcaaaagcaccgccggacatcagcgctatctctgctctcactgccgtaaaacatggcaactgcagttcacttacaccgcttctcaacccggtacgcaccagaaaatcattgatatggccatgaatggcgttggatgccgggcaacagcccgcattatgggcgttggcctcaacacgattttacgtcacttaaaaaactcaggccgcagtcggtaacctcgcgcatacagccgggcagtgacgtcatcgtctgcgcggaaatggacgaacagtggggctatgtcggggctaaatcgcgccagcgctggctgttttacgcgtatgacagtctccggaagacggttgttgcgcacgtattcggtgaacgcactatggcgacgctggggcgtcttatgagcctgctgtcaccctttgacgtggtgatatggatgacggatggctggccgctgtatgaatcccgcctgaagggaaagctgcacgtaatcagcaagcgatatacgcagcgaattgagcggcataacctgaatctgaggcagcacctggcacggctgggacggaagtcgctgtcgttctcaaaatcggtggagctgcatgacaaagtcatcgggcattatctgaacataaaacactatcaataagttggagtcattacccaattatgatagaatttacaagctataaggttattgtcctgggtttcaagcattagtccatgcaagtttttatgctttgcccattctatagatatattgataagcgcgctgcctatgccttgccccctgaaatccttacatacggcgatatcttctatataaaagatatattatcttatcagtattgtcaatatattcaaggcaatctgcctcctcatcctcttcatcctcttcgtcttggtagctttttaaatatggcgcttcatagagtaattctgtaaaggtccaattctcgttttcatacctcggtataatcttacctatcacctcaaatggttcgctgggtttatcgcacccccgaacacgagcacggcacccgcgaccactatgccaagaatgcccaaggtaaaaattgccggccccgccatgaagtccgtgaatgccccgacggccgaagtgaagggcaggccgccacccaggccgccgccctcactgcccggcacctggtcgctgaatgtcgatgccagcacctgcggcacgtcaatgcttccgggcgtcgcgctcgggctgatcgcccatcccgttactgccccgatcccggcaatggcaaggactgccagcgctgccatttttggggtgaggccgttcgcggccgaggggcgcagcccctggggggatgggaggcccgcgttagcgggccgggagggttcgagaagggggggcaccccccttcggcgtgcgcggtcacgcgcacagggcgcagccctggttaaaaacaaggtttataaatattggtttaaaagcaggttaaaagacaggttagcggtggccgaaaaacgggcggaaacccttgcaaatgctggattttctgcctgtggacagcccctcaaatgtcaataggtgcgcccctcatctgtcagcactctgcccctcaagtgtcaaggatcgcgcccctcatctgtcagtagtcgcgcccctcaagtgtcaataccgcagggcacttatccccaggcttgtccacatcatctgtgggaaactcgcgtaaaatcaggcgttttcgccgatttgcgaggctggccagctccacgtcgccggccgaaatcgagcctgcccctcatctgtcaacgccgcgccgggtgagtcggcccctcaagtgtcaacgtccgcccctcatctgtcagtgagggccaagttttccgcgaggtatccacaacgccggcggccgcggtgtctcgcacacggcttcgacggcgtttctggcgcgtttgcagggccatagacggccgccagcccagcggcgagggcaaccagcccgg + + + + diff --git a/www/node_modules/xml2js/x.js b/www/node_modules/xml2js/x.js new file mode 100644 index 0000000..b51ce57 --- /dev/null +++ b/www/node_modules/xml2js/x.js @@ -0,0 +1,24 @@ +var util = require('util'); +var xml2js = require('xml2js'); + +var myxml = " \ + \ + \ + 1 \ + green \ + \ + \ + 2 \ + red \ + \ + \ + 3 \ + yellow \ + \ +" + +xml2js.parseString(myxml, function (e, r) { + console.log(util.inspect(r, false, null)); + console.log(new xml2js.Builder().buildObject(r)); +}); + diff --git a/www/node_modules/xmlbuilder/.npmignore b/www/node_modules/xmlbuilder/.npmignore new file mode 100644 index 0000000..b6ad1f6 --- /dev/null +++ b/www/node_modules/xmlbuilder/.npmignore @@ -0,0 +1,5 @@ +.travis.yml +src +test +perf +coverage diff --git a/www/node_modules/xmlbuilder/CHANGELOG.md b/www/node_modules/xmlbuilder/CHANGELOG.md new file mode 100644 index 0000000..86f1e94 --- /dev/null +++ b/www/node_modules/xmlbuilder/CHANGELOG.md @@ -0,0 +1,329 @@ +# Change Log + +## [5.0.0] - 2016-03-05 +- Added text case option for element names and attribute names. Valid cases are `lower`, `upper`, `camel`, `kebab` and `snake`. +- Attribute and element values are escaped according to the [Canonical XML 1.0 specification](http://www.w3.org/TR/2000/WD-xml-c14n-20000119.html#charescaping). See [#54](https://github.com/oozcitak/xmlbuilder-js/issues/54) and [#86](https://github.com/oozcitak/xmlbuilder-js/issues/86). +- Added the `allowEmpty` option to `end()`. When this option is set, empty elements are not self-closed. +- Added support for [nested CDATA](https://en.wikipedia.org/wiki/CDATA#Nesting). The triad `]]>` in CDATA is now automatically replaced with `]]]]>`. + +## [4.2.1] - 2016-01-15 +- Updated lodash dependency to 4.0.0. + +## [4.2.0] - 2015-12-16 +- Added the `noDoubleEncoding` option to `create()` to control whether existing html entities are encoded. + +## [4.1.0] - 2015-11-11 +- Added the `separateArrayItems` option to `create()` to control how arrays are handled when converting from objects. e.g. + +```js +root.ele({ number: [ "one", "two" ]}); +// with separateArrayItems: true + + + + +// with separateArrayItems: false +one +two +``` + +## [4.0.0] - 2015-11-01 +- Removed the `#list` decorator. Array items are now created as child nodes by default. +- Fixed a bug where the XML encoding string was checked partially. + +## [3.1.0] - 2015-09-19 +- `#list` decorator ignores empty arrays. + +## [3.0.0] - 2015-09-10 +- Allow `\r`, `\n` and `\t` in attribute values without escaping. See [#86](https://github.com/oozcitak/xmlbuilder-js/issues/86). + +## [2.6.5] - 2015-09-09 +- Use native `isArray` instead of lodash. +- Indentation of processing intructions are set to the parent element's. + +## [2.6.4] - 2015-05-27 +- Updated lodash dependency to 3.5.0. + +## [2.6.3] - 2015-05-27 +- Bumped version because previous release was not published on npm. + +## [2.6.2] - 2015-03-10 +- Updated lodash dependency to 3.5.0. + +## [2.6.1] - 2015-02-20 +- Updated lodash dependency to 3.3.0. + +## [2.6.0] - 2015-02-20 +- Fixed a bug where the `XMLNode` constructor overwrote the super class parent. +- Removed document property from cloned nodes. +- Switched to mocha.js for testing. + +## [2.5.2] - 2015-02-16 +- Updated lodash dependency to 3.2.0. + +## [2.5.1] - 2015-02-09 +- Updated lodash dependency to 3.1.0. +- Support all node >= 0.8. + +## [2.5.0] - 2015-00-03 +- Updated lodash dependency to 3.0.0. + +## [2.4.6] - 2015-01-26 +- Show more information from attribute creation with null values. +- Added iojs as an engine. +- Self close elements with empty text. + +## [2.4.5] - 2014-11-15 +- Fixed prepublish script to run on windows. +- Fixed bug in XMLStringifier where an undefined value was used while reporting an invalid encoding value. +- Moved require statements to the top of files to reduce CPU usage from lazy requires. See [#62](https://github.com/oozcitak/xmlbuilder-js/issues/62). + +## [2.4.4] - 2014-09-08 +- Added the `offset` option to `toSTring()` for use in XML fragments. + +## [2.4.3] - 2014-08-13 +- Corrected license in package description. + +## [2.4.2] - 2014-08-13 +- Dropped performance test and memwatch dependency. + +## [2.4.1] - 2014-08-12 +- Fixed a bug where empty indent string was omitted when pretty printing. See [#59](https://github.com/oozcitak/xmlbuilder-js/issues/59). + +## [2.4.0] - 2014-08-04 +- Correct cases of pubID and sysID. +- Use single lodash instead of seperate npm modules. See [#53](https://github.com/oozcitak/xmlbuilder-js/issues/53). +- Escape according to Canonical XML 1.0. See [#54](https://github.com/oozcitak/xmlbuilder-js/issues/54). + +## [2.3.0] - 2014-07-17 +- Convert objects to JS primitives while sanitizing user input. +- Object builder preserves items with null values. See [#44](https://github.com/oozcitak/xmlbuilder-js/issues/44). +- Use modularized lodash functions to cut down dependencies. +- Process empty objects when converting from objects so that we don't throw on empty child objects. + +## [2.2.1] - 2014-04-04 +- Bumped version because previous release was not published on npm. + +## [2.2.0] - 2014-04-04 +- Switch to lodash from underscore. +- Removed legacy `ext` option from `create()`. +- Drop old node versions: 0.4, 0.5, 0.6. 0.8 is the minimum requirement from now on. + +## [2.1.0] - 2013-12-30 +- Removed duplicate null checks from constructors. +- Fixed node count in performance test. +- Added option for skipping null attribute values. See [#26](https://github.com/oozcitak/xmlbuilder-js/issues/26). +- Allow multiple values in `att()` and `ins()`. +- Added ability to run individual performance tests. +- Added flag for ignoring decorator strings. + +## [2.0.1] - 2013-12-24 +- Removed performance tests from npm package. + +## [2.0.0] - 2013-12-24 +- Combined loops for speed up. +- Added support for the DTD and XML declaration. +- `clone` includes attributes. +- Added performance tests. +- Evaluate attribute value if function. +- Evaluate instruction value if function. + +## [1.1.2] - 2013-12-11 +- Changed processing instruction decorator to `?`. + +## [1.1.1] - 2013-12-11 +- Added processing instructions to JS object conversion. + +## [1.1.0] - 2013-12-10 +- Added license to package. +- `create()` and `element()` accept JS object to fully build the document. +- Added `nod()` and `n()` aliases for `node()`. +- Renamed `convertAttChar` decorator to `convertAttKey`. +- Ignore empty decorator strings when converting JS objects. + +## [1.0.2] - 2013-11-27 +- Removed temp file which was accidentally included in the package. + +## [1.0.1] - 2013-11-27 +- Custom stringify functions affect current instance only. + +## [1.0.0] - 2013-11-27 +- Added processing instructions. +- Added stringify functions to sanitize and convert input values. +- Added option for headless XML documents. +- Added vows tests. +- Removed Makefile. Using npm publish scripts instead. +- Removed the `begin()` function. `create()` begins the document by creating the root node. + +## [0.4.3] - 2013-11-08 +- Added option to include surrogate pairs in XML content. See [#29](https://github.com/oozcitak/xmlbuilder-js/issues/29). +- Fixed empty value string representation in pretty mode. +- Added pre and postpublish scripts to package.json. +- Filtered out prototype properties when appending attributes. See [#31](https://github.com/oozcitak/xmlbuilder-js/issues/31). + +## [0.4.2] - 2012-09-14 +- Removed README.md from `.npmignore`. + +## [0.4.1] - 2012-08-31 +- Removed `begin()` calls in favor of `XMLBuilder` constructor. +- Added the `end()` function. `end()` is a convenience over `doc().toString()`. + +## [0.4.0] - 2012-08-31 +- Added arguments to `XMLBuilder` constructor to allow the name of the root element and XML prolog to be defined in one line. +- Soft deprecated `begin()`. + +## [0.3.11] - 2012-08-13 +- Package keywords are fixed to be an array of values. + +## [0.3.10] - 2012-08-13 +- Brought back npm package contents which were lost due to incorrect configuration of `package.json` in previous releases. + +## [0.3.3] - 2012-07-27 +- Implemented `importXMLBuilder()`. + +## [0.3.2] - 2012-07-20 +- Fixed a duplicated escaping problem on `element()`. +- Fixed a problem with text node creation from empty string. +- Calling `root()` on the document element returns the root element. +- `XMLBuilder` no longer extends `XMLFragment`. + +## [0.3.1] - 2011-11-28 +- Added guards for document element so that nodes cannot be inserted at document level. + +## [0.3.0] - 2011-11-28 +- Added `doc()` to return the document element. + +## [0.2.2] - 2011-11-28 +- Prevent code relying on `up()`'s older behavior to break. + +## [0.2.1] - 2011-11-28 +- Added the `root()` function. + +## [0.2.0] - 2011-11-21 +- Added Travis-CI integration. +- Added coffee-script dependency. +- Added insert, traversal and delete functions. + +## [0.1.7] - 2011-10-25 +- No changes. Accidental release. + +## [0.1.6] - 2011-10-25 +- Corrected `package.json` bugs link to `url` from `web`. + +## [0.1.5] - 2011-08-08 +- Added missing npm package contents. + +## [0.1.4] - 2011-07-29 +- Text-only nodes are no longer indented. +- Added documentation for multiple instances. + +## [0.1.3] - 2011-07-27 +- Exported the `create()` function to return a new instance. This allows multiple builder instances to be constructed. +- Fixed `u()` function so that it now correctly calls `up()`. +- Fixed typo in `element()` so that `attributes` and `text` van be passes interchangeably. + +## [0.1.2] - 2011-06-03 +- `ele()` accepts element text. +- `attributes()` now overrides existing attributes if passed the same attribute name. + +## [0.1.1] - 2011-05-19 +- Added the raw output option. +- Removed most validity checks. + +## [0.1.0] - 2011-04-27 +- `text()` and `cdata()` now return parent element. +- Attribute values are escaped. + +## [0.0.7] - 2011-04-23 +- Coerced text values to string. + +## [0.0.6] - 2011-02-23 +- Added support for XML comments. +- Text nodes are checked against CharData. + +## [0.0.5] - 2010-12-31 +- Corrected the name of the main npm module in `package.json`. + +## [0.0.4] - 2010-12-28 +- Added `.npmignore`. + +## [0.0.3] - 2010-12-27 +- root element is now constructed in `begin()`. +- moved prolog to `begin()`. +- Added the ability to have CDATA in element text. +- Removed unused prolog aliases. +- Removed `builder()` function from main module. +- Added the name of the main npm module in `package.json`. + +## [0.0.2] - 2010-11-03 +- `element()` expands nested arrays. +- Added pretty printing. +- Added the `up()`, `build()` and `prolog()` functions. +- Added readme. + +## 0.0.1 - 2010-11-02 +- Initial release + +[5.0.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v4.2.1...v5.0.0 +[4.2.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v4.2.0...v4.2.1 +[4.2.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v4.1.0...v4.2.0 +[4.1.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v4.0.0...v4.1.0 +[4.0.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v3.1.0...v4.0.0 +[3.1.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v3.0.0...v3.1.0 +[3.0.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.5...v3.0.0 +[2.6.5]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.4...v2.6.5 +[2.6.4]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.3...v2.6.4 +[2.6.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.2...v2.6.3 +[2.6.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.1...v2.6.2 +[2.6.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.6.0...v2.6.1 +[2.6.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.5.2...v2.6.0 +[2.5.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.5.1...v2.5.2 +[2.5.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.5.0...v2.5.1 +[2.5.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.6...v2.5.0 +[2.4.6]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.5...v2.4.6 +[2.4.5]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.4...v2.4.5 +[2.4.4]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.3...v2.4.4 +[2.4.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.2...v2.4.3 +[2.4.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.1...v2.4.2 +[2.4.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.4.0...v2.4.1 +[2.4.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.3.0...v2.4.0 +[2.3.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.2.1...v2.3.0 +[2.2.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.2.0...v2.2.1 +[2.2.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.1.0...v2.2.0 +[2.1.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.0.1...v2.1.0 +[2.0.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v2.0.0...v2.0.1 +[2.0.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.1.2...v2.0.0 +[1.1.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.1.1...v1.1.2 +[1.1.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.1.0...v1.1.1 +[1.1.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.0.2...v1.1.0 +[1.0.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.0.1...v1.0.2 +[1.0.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v1.0.0...v1.0.1 +[1.0.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.4.3...v1.0.0 +[0.4.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.4.2...v0.4.3 +[0.4.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.4.1...v0.4.2 +[0.4.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.4.0...v0.4.1 +[0.4.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.11...v0.4.0 +[0.3.11]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.10...v0.3.11 +[0.3.10]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.3...v0.3.10 +[0.3.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.2...v0.3.3 +[0.3.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.1...v0.3.2 +[0.3.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.3.0...v0.3.1 +[0.3.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.2.2...v0.3.0 +[0.2.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.2.1...v0.2.2 +[0.2.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.2.0...v0.2.1 +[0.2.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.7...v0.2.0 +[0.1.7]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.6...v0.1.7 +[0.1.6]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.5...v0.1.6 +[0.1.5]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.4...v0.1.5 +[0.1.4]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.3...v0.1.4 +[0.1.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.2...v0.1.3 +[0.1.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.1...v0.1.2 +[0.1.1]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.1.0...v0.1.1 +[0.1.0]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.7...v0.1.0 +[0.0.7]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.6...v0.0.7 +[0.0.6]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.5...v0.0.6 +[0.0.5]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.4...v0.0.5 +[0.0.4]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.3...v0.0.4 +[0.0.3]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.2...v0.0.3 +[0.0.2]: https://github.com/oozcitak/xmlbuilder-js/compare/v0.0.1...v0.0.2 + diff --git a/www/node_modules/xmlbuilder/LICENSE b/www/node_modules/xmlbuilder/LICENSE new file mode 100644 index 0000000..e7cbac9 --- /dev/null +++ b/www/node_modules/xmlbuilder/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Ozgur Ozcitak + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/www/node_modules/xmlbuilder/README.md b/www/node_modules/xmlbuilder/README.md new file mode 100644 index 0000000..13a5b12 --- /dev/null +++ b/www/node_modules/xmlbuilder/README.md @@ -0,0 +1,86 @@ +# xmlbuilder-js + +An XML builder for [node.js](https://nodejs.org/) similar to +[java-xmlbuilder](https://github.com/jmurty/java-xmlbuilder). + +[![License](http://img.shields.io/npm/l/xmlbuilder.svg?style=flat-square)](http://opensource.org/licenses/MIT) +[![NPM Version](http://img.shields.io/npm/v/xmlbuilder.svg?style=flat-square)](https://npmjs.com/package/xmlbuilder) +[![NPM Downloads](https://img.shields.io/npm/dm/xmlbuilder.svg?style=flat-square)](https://npmjs.com/package/xmlbuilder) + +[![Build Status](http://img.shields.io/travis/oozcitak/xmlbuilder-js.svg?style=flat-square)](http://travis-ci.org/oozcitak/xmlbuilder-js) +[![Dependency Status](http://img.shields.io/david/oozcitak/xmlbuilder-js.svg?style=flat-square)](https://david-dm.org/oozcitak/xmlbuilder-js) +[![Dev Dependency Status](http://img.shields.io/david/dev/oozcitak/xmlbuilder-js.svg?style=flat-square)](https://david-dm.org/oozcitak/xmlbuilder-js) +[![Code Coverage](https://img.shields.io/coveralls/oozcitak/xmlbuilder-js.svg?style=flat-square)](https://coveralls.io/github/oozcitak/xmlbuilder-js) + +### Installation: + +``` sh +npm install xmlbuilder +``` + +### Usage: + +``` js +var builder = require('xmlbuilder'); +var xml = builder.create('root') + .ele('xmlbuilder') + .ele('repo', {'type': 'git'}, 'git://github.com/oozcitak/xmlbuilder-js.git') + .end({ pretty: true}); + +console.log(xml); +``` + +will result in: + +``` xml + + + + git://github.com/oozcitak/xmlbuilder-js.git + + +``` + +It is also possible to convert objects into nodes: + +``` js +builder.create({ + root: { + xmlbuilder: { + repo: { + '@type': 'git', // attributes start with @ + '#text': 'git://github.com/oozcitak/xmlbuilder-js.git' // text node + } + } + } +}); +``` + +If you need to do some processing: + +``` js +var root = builder.create('squares'); +root.com('f(x) = x^2'); +for(var i = 1; i <= 5; i++) +{ + var item = root.ele('data'); + item.att('x', i); + item.att('y', i * i); +} +``` + +This will result in: + +``` xml + + + + + + + + + +``` + +See the [wiki](https://github.com/oozcitak/xmlbuilder-js/wiki) for details. diff --git a/www/node_modules/xmlbuilder/lib/XMLAttribute.js b/www/node_modules/xmlbuilder/lib/XMLAttribute.js new file mode 100644 index 0000000..f6c6bd8 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLAttribute.js @@ -0,0 +1,32 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLAttribute, create; + + create = require('lodash/create'); + + module.exports = XMLAttribute = (function() { + function XMLAttribute(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing attribute name of element " + parent.name); + } + if (value == null) { + throw new Error("Missing attribute value for attribute " + name + " of element " + parent.name); + } + this.name = this.stringify.attName(name); + this.value = this.stringify.attValue(value); + } + + XMLAttribute.prototype.clone = function() { + return create(XMLAttribute.prototype, this); + }; + + XMLAttribute.prototype.toString = function(options, level) { + return ' ' + this.name + '="' + this.value + '"'; + }; + + return XMLAttribute; + + })(); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLBuilder.js b/www/node_modules/xmlbuilder/lib/XMLBuilder.js new file mode 100644 index 0000000..4282833 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLBuilder.js @@ -0,0 +1,69 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLBuilder, XMLDeclaration, XMLDocType, XMLElement, XMLStringifier; + + XMLStringifier = require('./XMLStringifier'); + + XMLDeclaration = require('./XMLDeclaration'); + + XMLDocType = require('./XMLDocType'); + + XMLElement = require('./XMLElement'); + + module.exports = XMLBuilder = (function() { + function XMLBuilder(name, options) { + var root, temp; + if (name == null) { + throw new Error("Root element needs a name"); + } + if (options == null) { + options = {}; + } + this.options = options; + this.stringify = new XMLStringifier(options); + temp = new XMLElement(this, 'doc'); + root = temp.element(name); + root.isRoot = true; + root.documentObject = this; + this.rootObject = root; + if (!options.headless) { + root.declaration(options); + if ((options.pubID != null) || (options.sysID != null)) { + root.doctype(options); + } + } + } + + XMLBuilder.prototype.root = function() { + return this.rootObject; + }; + + XMLBuilder.prototype.end = function(options) { + return this.toString(options); + }; + + XMLBuilder.prototype.toString = function(options) { + var indent, newline, offset, pretty, r, ref, ref1, ref2; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + r = ''; + if (this.xmldec != null) { + r += this.xmldec.toString(options); + } + if (this.doctype != null) { + r += this.doctype.toString(options); + } + r += this.rootObject.toString(options); + if (pretty && r.slice(-newline.length) === newline) { + r = r.slice(0, -newline.length); + } + return r; + }; + + return XMLBuilder; + + })(); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLCData.js b/www/node_modules/xmlbuilder/lib/XMLCData.js new file mode 100644 index 0000000..c171a28 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLCData.js @@ -0,0 +1,49 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLNode, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLCData = (function(superClass) { + extend(XMLCData, superClass); + + function XMLCData(parent, text) { + XMLCData.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing CDATA text"); + } + this.text = this.stringify.cdata(text); + } + + XMLCData.prototype.clone = function() { + return create(XMLCData.prototype, this); + }; + + XMLCData.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLCData; + + })(XMLNode); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLComment.js b/www/node_modules/xmlbuilder/lib/XMLComment.js new file mode 100644 index 0000000..ca801f6 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLComment.js @@ -0,0 +1,49 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLComment, XMLNode, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLComment = (function(superClass) { + extend(XMLComment, superClass); + + function XMLComment(parent, text) { + XMLComment.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing comment text"); + } + this.text = this.stringify.comment(text); + } + + XMLComment.prototype.clone = function() { + return create(XMLComment.prototype, this); + }; + + XMLComment.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLComment; + + })(XMLNode); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLDTDAttList.js b/www/node_modules/xmlbuilder/lib/XMLDTDAttList.js new file mode 100644 index 0000000..4a71866 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLDTDAttList.js @@ -0,0 +1,68 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDAttList, create; + + create = require('lodash/create'); + + module.exports = XMLDTDAttList = (function() { + function XMLDTDAttList(parent, elementName, attributeName, attributeType, defaultValueType, defaultValue) { + this.stringify = parent.stringify; + if (elementName == null) { + throw new Error("Missing DTD element name"); + } + if (attributeName == null) { + throw new Error("Missing DTD attribute name"); + } + if (!attributeType) { + throw new Error("Missing DTD attribute type"); + } + if (!defaultValueType) { + throw new Error("Missing DTD attribute default"); + } + if (defaultValueType.indexOf('#') !== 0) { + defaultValueType = '#' + defaultValueType; + } + if (!defaultValueType.match(/^(#REQUIRED|#IMPLIED|#FIXED|#DEFAULT)$/)) { + throw new Error("Invalid default value type; expected: #REQUIRED, #IMPLIED, #FIXED or #DEFAULT"); + } + if (defaultValue && !defaultValueType.match(/^(#FIXED|#DEFAULT)$/)) { + throw new Error("Default value only applies to #FIXED or #DEFAULT"); + } + this.elementName = this.stringify.eleName(elementName); + this.attributeName = this.stringify.attName(attributeName); + this.attributeType = this.stringify.dtdAttType(attributeType); + this.defaultValue = this.stringify.dtdAttDefault(defaultValue); + this.defaultValueType = defaultValueType; + } + + XMLDTDAttList.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDAttList; + + })(); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLDTDElement.js b/www/node_modules/xmlbuilder/lib/XMLDTDElement.js new file mode 100644 index 0000000..0002c1b --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLDTDElement.js @@ -0,0 +1,46 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDElement, create; + + create = require('lodash/create'); + + module.exports = XMLDTDElement = (function() { + function XMLDTDElement(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing DTD element name"); + } + if (!value) { + value = '(#PCDATA)'; + } + if (Array.isArray(value)) { + value = '(' + value.join(',') + ')'; + } + this.name = this.stringify.eleName(name); + this.value = this.stringify.dtdElementValue(value); + } + + XMLDTDElement.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDElement; + + })(); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLDTDEntity.js b/www/node_modules/xmlbuilder/lib/XMLDTDEntity.js new file mode 100644 index 0000000..f27d567 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLDTDEntity.js @@ -0,0 +1,84 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDEntity, create, isObject; + + create = require('lodash/create'); + + isObject = require('lodash/isObject'); + + module.exports = XMLDTDEntity = (function() { + function XMLDTDEntity(parent, pe, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing entity name"); + } + if (value == null) { + throw new Error("Missing entity value"); + } + this.pe = !!pe; + this.name = this.stringify.eleName(name); + if (!isObject(value)) { + this.value = this.stringify.dtdEntityValue(value); + } else { + if (!value.pubID && !value.sysID) { + throw new Error("Public and/or system identifiers are required for an external entity"); + } + if (value.pubID && !value.sysID) { + throw new Error("System identifier is required for a public external entity"); + } + if (value.pubID != null) { + this.pubID = this.stringify.dtdPubID(value.pubID); + } + if (value.sysID != null) { + this.sysID = this.stringify.dtdSysID(value.sysID); + } + if (value.nData != null) { + this.nData = this.stringify.dtdNData(value.nData); + } + if (this.pe && this.nData) { + throw new Error("Notation declaration is not allowed in a parameter entity"); + } + } + } + + XMLDTDEntity.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDEntity; + + })(); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLDTDNotation.js b/www/node_modules/xmlbuilder/lib/XMLDTDNotation.js new file mode 100644 index 0000000..edd3501 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLDTDNotation.js @@ -0,0 +1,56 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDTDNotation, create; + + create = require('lodash/create'); + + module.exports = XMLDTDNotation = (function() { + function XMLDTDNotation(parent, name, value) { + this.stringify = parent.stringify; + if (name == null) { + throw new Error("Missing notation name"); + } + if (!value.pubID && !value.sysID) { + throw new Error("Public or system identifiers are required for an external entity"); + } + this.name = this.stringify.eleName(name); + if (value.pubID != null) { + this.pubID = this.stringify.dtdPubID(value.pubID); + } + if (value.sysID != null) { + this.sysID = this.stringify.dtdSysID(value.sysID); + } + } + + XMLDTDNotation.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDTDNotation; + + })(); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLDeclaration.js b/www/node_modules/xmlbuilder/lib/XMLDeclaration.js new file mode 100644 index 0000000..b502892 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLDeclaration.js @@ -0,0 +1,65 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLDeclaration, XMLNode, create, isObject, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/create'); + + isObject = require('lodash/isObject'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLDeclaration = (function(superClass) { + extend(XMLDeclaration, superClass); + + function XMLDeclaration(parent, version, encoding, standalone) { + var ref; + XMLDeclaration.__super__.constructor.call(this, parent); + if (isObject(version)) { + ref = version, version = ref.version, encoding = ref.encoding, standalone = ref.standalone; + } + if (!version) { + version = '1.0'; + } + this.version = this.stringify.xmlVersion(version); + if (encoding != null) { + this.encoding = this.stringify.xmlEncoding(encoding); + } + if (standalone != null) { + this.standalone = this.stringify.xmlStandalone(standalone); + } + } + + XMLDeclaration.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLDeclaration; + + })(XMLNode); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLDocType.js b/www/node_modules/xmlbuilder/lib/XMLDocType.js new file mode 100644 index 0000000..cbc61b3 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLDocType.js @@ -0,0 +1,188 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLComment, XMLDTDAttList, XMLDTDElement, XMLDTDEntity, XMLDTDNotation, XMLDocType, XMLProcessingInstruction, create, isObject; + + create = require('lodash/create'); + + isObject = require('lodash/isObject'); + + XMLCData = require('./XMLCData'); + + XMLComment = require('./XMLComment'); + + XMLDTDAttList = require('./XMLDTDAttList'); + + XMLDTDEntity = require('./XMLDTDEntity'); + + XMLDTDElement = require('./XMLDTDElement'); + + XMLDTDNotation = require('./XMLDTDNotation'); + + XMLProcessingInstruction = require('./XMLProcessingInstruction'); + + module.exports = XMLDocType = (function() { + function XMLDocType(parent, pubID, sysID) { + var ref, ref1; + this.documentObject = parent; + this.stringify = this.documentObject.stringify; + this.children = []; + if (isObject(pubID)) { + ref = pubID, pubID = ref.pubID, sysID = ref.sysID; + } + if (sysID == null) { + ref1 = [pubID, sysID], sysID = ref1[0], pubID = ref1[1]; + } + if (pubID != null) { + this.pubID = this.stringify.dtdPubID(pubID); + } + if (sysID != null) { + this.sysID = this.stringify.dtdSysID(sysID); + } + } + + XMLDocType.prototype.element = function(name, value) { + var child; + child = new XMLDTDElement(this, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.attList = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) { + var child; + child = new XMLDTDAttList(this, elementName, attributeName, attributeType, defaultValueType, defaultValue); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.entity = function(name, value) { + var child; + child = new XMLDTDEntity(this, false, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.pEntity = function(name, value) { + var child; + child = new XMLDTDEntity(this, true, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.notation = function(name, value) { + var child; + child = new XMLDTDNotation(this, name, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.cdata = function(value) { + var child; + child = new XMLCData(this, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.comment = function(value) { + var child; + child = new XMLComment(this, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.instruction = function(target, value) { + var child; + child = new XMLProcessingInstruction(this, target, value); + this.children.push(child); + return this; + }; + + XMLDocType.prototype.root = function() { + return this.documentObject.root(); + }; + + XMLDocType.prototype.document = function() { + return this.documentObject; + }; + + XMLDocType.prototype.toString = function(options, level) { + var child, i, indent, len, newline, offset, pretty, r, ref, ref1, ref2, ref3, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ' 0) { + r += ' ['; + if (pretty) { + r += newline; + } + ref3 = this.children; + for (i = 0, len = ref3.length; i < len; i++) { + child = ref3[i]; + r += child.toString(options, level + 1); + } + r += ']'; + } + r += '>'; + if (pretty) { + r += newline; + } + return r; + }; + + XMLDocType.prototype.ele = function(name, value) { + return this.element(name, value); + }; + + XMLDocType.prototype.att = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) { + return this.attList(elementName, attributeName, attributeType, defaultValueType, defaultValue); + }; + + XMLDocType.prototype.ent = function(name, value) { + return this.entity(name, value); + }; + + XMLDocType.prototype.pent = function(name, value) { + return this.pEntity(name, value); + }; + + XMLDocType.prototype.not = function(name, value) { + return this.notation(name, value); + }; + + XMLDocType.prototype.dat = function(value) { + return this.cdata(value); + }; + + XMLDocType.prototype.com = function(value) { + return this.comment(value); + }; + + XMLDocType.prototype.ins = function(target, value) { + return this.instruction(target, value); + }; + + XMLDocType.prototype.up = function() { + return this.root(); + }; + + XMLDocType.prototype.doc = function() { + return this.document(); + }; + + return XMLDocType; + + })(); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLElement.js b/www/node_modules/xmlbuilder/lib/XMLElement.js new file mode 100644 index 0000000..3e5e1eb --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLElement.js @@ -0,0 +1,217 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLAttribute, XMLElement, XMLNode, XMLProcessingInstruction, create, every, isFunction, isObject, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/create'); + + isObject = require('lodash/isObject'); + + isFunction = require('lodash/isFunction'); + + every = require('lodash/every'); + + XMLNode = require('./XMLNode'); + + XMLAttribute = require('./XMLAttribute'); + + XMLProcessingInstruction = require('./XMLProcessingInstruction'); + + module.exports = XMLElement = (function(superClass) { + extend(XMLElement, superClass); + + function XMLElement(parent, name, attributes) { + XMLElement.__super__.constructor.call(this, parent); + if (name == null) { + throw new Error("Missing element name"); + } + this.name = this.stringify.eleName(name); + this.children = []; + this.instructions = []; + this.attributes = {}; + if (attributes != null) { + this.attribute(attributes); + } + } + + XMLElement.prototype.clone = function() { + var att, attName, clonedSelf, i, len, pi, ref, ref1; + clonedSelf = create(XMLElement.prototype, this); + if (clonedSelf.isRoot) { + clonedSelf.documentObject = null; + } + clonedSelf.attributes = {}; + ref = this.attributes; + for (attName in ref) { + if (!hasProp.call(ref, attName)) continue; + att = ref[attName]; + clonedSelf.attributes[attName] = att.clone(); + } + clonedSelf.instructions = []; + ref1 = this.instructions; + for (i = 0, len = ref1.length; i < len; i++) { + pi = ref1[i]; + clonedSelf.instructions.push(pi.clone()); + } + clonedSelf.children = []; + this.children.forEach(function(child) { + var clonedChild; + clonedChild = child.clone(); + clonedChild.parent = clonedSelf; + return clonedSelf.children.push(clonedChild); + }); + return clonedSelf; + }; + + XMLElement.prototype.attribute = function(name, value) { + var attName, attValue; + if (name != null) { + name = name.valueOf(); + } + if (isObject(name)) { + for (attName in name) { + if (!hasProp.call(name, attName)) continue; + attValue = name[attName]; + this.attribute(attName, attValue); + } + } else { + if (isFunction(value)) { + value = value.apply(); + } + if (!this.options.skipNullAttributes || (value != null)) { + this.attributes[name] = new XMLAttribute(this, name, value); + } + } + return this; + }; + + XMLElement.prototype.removeAttribute = function(name) { + var attName, i, len; + if (name == null) { + throw new Error("Missing attribute name"); + } + name = name.valueOf(); + if (Array.isArray(name)) { + for (i = 0, len = name.length; i < len; i++) { + attName = name[i]; + delete this.attributes[attName]; + } + } else { + delete this.attributes[name]; + } + return this; + }; + + XMLElement.prototype.instruction = function(target, value) { + var i, insTarget, insValue, instruction, len; + if (target != null) { + target = target.valueOf(); + } + if (value != null) { + value = value.valueOf(); + } + if (Array.isArray(target)) { + for (i = 0, len = target.length; i < len; i++) { + insTarget = target[i]; + this.instruction(insTarget); + } + } else if (isObject(target)) { + for (insTarget in target) { + if (!hasProp.call(target, insTarget)) continue; + insValue = target[insTarget]; + this.instruction(insTarget, insValue); + } + } else { + if (isFunction(value)) { + value = value.apply(); + } + instruction = new XMLProcessingInstruction(this, target, value); + this.instructions.push(instruction); + } + return this; + }; + + XMLElement.prototype.toString = function(options, level) { + var allowEmpty, att, child, i, indent, instruction, j, len, len1, name, newline, offset, pretty, r, ref, ref1, ref2, ref3, ref4, ref5, ref6, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + allowEmpty = (ref3 = options != null ? options.allowEmpty : void 0) != null ? ref3 : false; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + ref4 = this.instructions; + for (i = 0, len = ref4.length; i < len; i++) { + instruction = ref4[i]; + r += instruction.toString(options, level); + } + if (pretty) { + r += space; + } + r += '<' + this.name; + ref5 = this.attributes; + for (name in ref5) { + if (!hasProp.call(ref5, name)) continue; + att = ref5[name]; + r += att.toString(options); + } + if (this.children.length === 0 || every(this.children, function(e) { + return e.value === ''; + })) { + if (allowEmpty) { + r += '>'; + } else { + r += '/>'; + } + if (pretty) { + r += newline; + } + } else if (pretty && this.children.length === 1 && (this.children[0].value != null)) { + r += '>'; + r += this.children[0].value; + r += ''; + r += newline; + } else { + r += '>'; + if (pretty) { + r += newline; + } + ref6 = this.children; + for (j = 0, len1 = ref6.length; j < len1; j++) { + child = ref6[j]; + r += child.toString(options, level + 1); + } + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + } + return r; + }; + + XMLElement.prototype.att = function(name, value) { + return this.attribute(name, value); + }; + + XMLElement.prototype.ins = function(target, value) { + return this.instruction(target, value); + }; + + XMLElement.prototype.a = function(name, value) { + return this.attribute(name, value); + }; + + XMLElement.prototype.i = function(target, value) { + return this.instruction(target, value); + }; + + return XMLElement; + + })(XMLNode); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLNode.js b/www/node_modules/xmlbuilder/lib/XMLNode.js new file mode 100644 index 0000000..0a6340b --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLNode.js @@ -0,0 +1,331 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLCData, XMLComment, XMLDeclaration, XMLDocType, XMLElement, XMLNode, XMLRaw, XMLText, isEmpty, isFunction, isObject, + hasProp = {}.hasOwnProperty; + + isObject = require('lodash/isObject'); + + isFunction = require('lodash/isFunction'); + + isEmpty = require('lodash/isEmpty'); + + XMLElement = null; + + XMLCData = null; + + XMLComment = null; + + XMLDeclaration = null; + + XMLDocType = null; + + XMLRaw = null; + + XMLText = null; + + module.exports = XMLNode = (function() { + function XMLNode(parent) { + this.parent = parent; + this.options = this.parent.options; + this.stringify = this.parent.stringify; + if (XMLElement === null) { + XMLElement = require('./XMLElement'); + XMLCData = require('./XMLCData'); + XMLComment = require('./XMLComment'); + XMLDeclaration = require('./XMLDeclaration'); + XMLDocType = require('./XMLDocType'); + XMLRaw = require('./XMLRaw'); + XMLText = require('./XMLText'); + } + } + + XMLNode.prototype.element = function(name, attributes, text) { + var childNode, item, j, k, key, lastChild, len, len1, ref, val; + lastChild = null; + if (attributes == null) { + attributes = {}; + } + attributes = attributes.valueOf(); + if (!isObject(attributes)) { + ref = [attributes, text], text = ref[0], attributes = ref[1]; + } + if (name != null) { + name = name.valueOf(); + } + if (Array.isArray(name)) { + for (j = 0, len = name.length; j < len; j++) { + item = name[j]; + lastChild = this.element(item); + } + } else if (isFunction(name)) { + lastChild = this.element(name.apply()); + } else if (isObject(name)) { + for (key in name) { + if (!hasProp.call(name, key)) continue; + val = name[key]; + if (isFunction(val)) { + val = val.apply(); + } + if ((isObject(val)) && (isEmpty(val))) { + val = null; + } + if (!this.options.ignoreDecorators && this.stringify.convertAttKey && key.indexOf(this.stringify.convertAttKey) === 0) { + lastChild = this.attribute(key.substr(this.stringify.convertAttKey.length), val); + } else if (!this.options.ignoreDecorators && this.stringify.convertPIKey && key.indexOf(this.stringify.convertPIKey) === 0) { + lastChild = this.instruction(key.substr(this.stringify.convertPIKey.length), val); + } else if (!this.options.separateArrayItems && Array.isArray(val)) { + for (k = 0, len1 = val.length; k < len1; k++) { + item = val[k]; + childNode = {}; + childNode[key] = item; + lastChild = this.element(childNode); + } + } else if (isObject(val)) { + lastChild = this.element(key); + lastChild.element(val); + } else { + lastChild = this.element(key, val); + } + } + } else { + if (!this.options.ignoreDecorators && this.stringify.convertTextKey && name.indexOf(this.stringify.convertTextKey) === 0) { + lastChild = this.text(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertCDataKey && name.indexOf(this.stringify.convertCDataKey) === 0) { + lastChild = this.cdata(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertCommentKey && name.indexOf(this.stringify.convertCommentKey) === 0) { + lastChild = this.comment(text); + } else if (!this.options.ignoreDecorators && this.stringify.convertRawKey && name.indexOf(this.stringify.convertRawKey) === 0) { + lastChild = this.raw(text); + } else { + lastChild = this.node(name, attributes, text); + } + } + if (lastChild == null) { + throw new Error("Could not create any elements with: " + name); + } + return lastChild; + }; + + XMLNode.prototype.insertBefore = function(name, attributes, text) { + var child, i, removed; + if (this.isRoot) { + throw new Error("Cannot insert elements at root level"); + } + i = this.parent.children.indexOf(this); + removed = this.parent.children.splice(i); + child = this.parent.element(name, attributes, text); + Array.prototype.push.apply(this.parent.children, removed); + return child; + }; + + XMLNode.prototype.insertAfter = function(name, attributes, text) { + var child, i, removed; + if (this.isRoot) { + throw new Error("Cannot insert elements at root level"); + } + i = this.parent.children.indexOf(this); + removed = this.parent.children.splice(i + 1); + child = this.parent.element(name, attributes, text); + Array.prototype.push.apply(this.parent.children, removed); + return child; + }; + + XMLNode.prototype.remove = function() { + var i, ref; + if (this.isRoot) { + throw new Error("Cannot remove the root element"); + } + i = this.parent.children.indexOf(this); + [].splice.apply(this.parent.children, [i, i - i + 1].concat(ref = [])), ref; + return this.parent; + }; + + XMLNode.prototype.node = function(name, attributes, text) { + var child, ref; + if (name != null) { + name = name.valueOf(); + } + if (attributes == null) { + attributes = {}; + } + attributes = attributes.valueOf(); + if (!isObject(attributes)) { + ref = [attributes, text], text = ref[0], attributes = ref[1]; + } + child = new XMLElement(this, name, attributes); + if (text != null) { + child.text(text); + } + this.children.push(child); + return child; + }; + + XMLNode.prototype.text = function(value) { + var child; + child = new XMLText(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.cdata = function(value) { + var child; + child = new XMLCData(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.comment = function(value) { + var child; + child = new XMLComment(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.raw = function(value) { + var child; + child = new XMLRaw(this, value); + this.children.push(child); + return this; + }; + + XMLNode.prototype.declaration = function(version, encoding, standalone) { + var doc, xmldec; + doc = this.document(); + xmldec = new XMLDeclaration(doc, version, encoding, standalone); + doc.xmldec = xmldec; + return doc.root(); + }; + + XMLNode.prototype.doctype = function(pubID, sysID) { + var doc, doctype; + doc = this.document(); + doctype = new XMLDocType(doc, pubID, sysID); + doc.doctype = doctype; + return doctype; + }; + + XMLNode.prototype.up = function() { + if (this.isRoot) { + throw new Error("The root node has no parent. Use doc() if you need to get the document object."); + } + return this.parent; + }; + + XMLNode.prototype.root = function() { + var child; + if (this.isRoot) { + return this; + } + child = this.parent; + while (!child.isRoot) { + child = child.parent; + } + return child; + }; + + XMLNode.prototype.document = function() { + return this.root().documentObject; + }; + + XMLNode.prototype.end = function(options) { + return this.document().toString(options); + }; + + XMLNode.prototype.prev = function() { + var i; + if (this.isRoot) { + throw new Error("Root node has no siblings"); + } + i = this.parent.children.indexOf(this); + if (i < 1) { + throw new Error("Already at the first node"); + } + return this.parent.children[i - 1]; + }; + + XMLNode.prototype.next = function() { + var i; + if (this.isRoot) { + throw new Error("Root node has no siblings"); + } + i = this.parent.children.indexOf(this); + if (i === -1 || i === this.parent.children.length - 1) { + throw new Error("Already at the last node"); + } + return this.parent.children[i + 1]; + }; + + XMLNode.prototype.importXMLBuilder = function(xmlbuilder) { + var clonedRoot; + clonedRoot = xmlbuilder.root().clone(); + clonedRoot.parent = this; + clonedRoot.isRoot = false; + this.children.push(clonedRoot); + return this; + }; + + XMLNode.prototype.ele = function(name, attributes, text) { + return this.element(name, attributes, text); + }; + + XMLNode.prototype.nod = function(name, attributes, text) { + return this.node(name, attributes, text); + }; + + XMLNode.prototype.txt = function(value) { + return this.text(value); + }; + + XMLNode.prototype.dat = function(value) { + return this.cdata(value); + }; + + XMLNode.prototype.com = function(value) { + return this.comment(value); + }; + + XMLNode.prototype.doc = function() { + return this.document(); + }; + + XMLNode.prototype.dec = function(version, encoding, standalone) { + return this.declaration(version, encoding, standalone); + }; + + XMLNode.prototype.dtd = function(pubID, sysID) { + return this.doctype(pubID, sysID); + }; + + XMLNode.prototype.e = function(name, attributes, text) { + return this.element(name, attributes, text); + }; + + XMLNode.prototype.n = function(name, attributes, text) { + return this.node(name, attributes, text); + }; + + XMLNode.prototype.t = function(value) { + return this.text(value); + }; + + XMLNode.prototype.d = function(value) { + return this.cdata(value); + }; + + XMLNode.prototype.c = function(value) { + return this.comment(value); + }; + + XMLNode.prototype.r = function(value) { + return this.raw(value); + }; + + XMLNode.prototype.u = function() { + return this.up(); + }; + + return XMLNode; + + })(); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLProcessingInstruction.js b/www/node_modules/xmlbuilder/lib/XMLProcessingInstruction.js new file mode 100644 index 0000000..596f5a6 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLProcessingInstruction.js @@ -0,0 +1,51 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLProcessingInstruction, create; + + create = require('lodash/create'); + + module.exports = XMLProcessingInstruction = (function() { + function XMLProcessingInstruction(parent, target, value) { + this.stringify = parent.stringify; + if (target == null) { + throw new Error("Missing instruction target"); + } + this.target = this.stringify.insTarget(target); + if (value) { + this.value = this.stringify.insValue(value); + } + } + + XMLProcessingInstruction.prototype.clone = function() { + return create(XMLProcessingInstruction.prototype, this); + }; + + XMLProcessingInstruction.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += ''; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLProcessingInstruction; + + })(); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLRaw.js b/www/node_modules/xmlbuilder/lib/XMLRaw.js new file mode 100644 index 0000000..9f48962 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLRaw.js @@ -0,0 +1,49 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLNode, XMLRaw, create, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + create = require('lodash/create'); + + XMLNode = require('./XMLNode'); + + module.exports = XMLRaw = (function(superClass) { + extend(XMLRaw, superClass); + + function XMLRaw(parent, text) { + XMLRaw.__super__.constructor.call(this, parent); + if (text == null) { + throw new Error("Missing raw text"); + } + this.value = this.stringify.raw(text); + } + + XMLRaw.prototype.clone = function() { + return create(XMLRaw.prototype, this); + }; + + XMLRaw.prototype.toString = function(options, level) { + var indent, newline, offset, pretty, r, ref, ref1, ref2, space; + pretty = (options != null ? options.pretty : void 0) || false; + indent = (ref = options != null ? options.indent : void 0) != null ? ref : ' '; + offset = (ref1 = options != null ? options.offset : void 0) != null ? ref1 : 0; + newline = (ref2 = options != null ? options.newline : void 0) != null ? ref2 : '\n'; + level || (level = 0); + space = new Array(level + offset + 1).join(indent); + r = ''; + if (pretty) { + r += space; + } + r += this.value; + if (pretty) { + r += newline; + } + return r; + }; + + return XMLRaw; + + })(XMLNode); + +}).call(this); diff --git a/www/node_modules/xmlbuilder/lib/XMLStringifier.js b/www/node_modules/xmlbuilder/lib/XMLStringifier.js new file mode 100644 index 0000000..bee8587 --- /dev/null +++ b/www/node_modules/xmlbuilder/lib/XMLStringifier.js @@ -0,0 +1,193 @@ +// Generated by CoffeeScript 1.9.1 +(function() { + var XMLStringifier, camelCase, kebabCase, snakeCase, + bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + hasProp = {}.hasOwnProperty; + + camelCase = require('lodash/camelCase'); + + kebabCase = require('lodash/kebabCase'); + + snakeCase = require('lodash/snakeCase'); + + module.exports = XMLStringifier = (function() { + function XMLStringifier(options) { + this.assertLegalChar = bind(this.assertLegalChar, this); + var key, ref, value; + this.allowSurrogateChars = options != null ? options.allowSurrogateChars : void 0; + this.noDoubleEncoding = options != null ? options.noDoubleEncoding : void 0; + this.textCase = options != null ? options.textCase : void 0; + ref = (options != null ? options.stringify : void 0) || {}; + for (key in ref) { + if (!hasProp.call(ref, key)) continue; + value = ref[key]; + this[key] = value; + } + } + + XMLStringifier.prototype.eleName = function(val) { + val = '' + val || ''; + val = this.applyCase(val); + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.eleText = function(val) { + val = '' + val || ''; + return this.assertLegalChar(this.elEscape(val)); + }; + + XMLStringifier.prototype.cdata = function(val) { + val = '' + val || ''; + val = val.replace(']]>', ']]]]>'); + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.comment = function(val) { + val = '' + val || ''; + if (val.match(/--/)) { + throw new Error("Comment text cannot contain double-hypen: " + val); + } + return this.assertLegalChar(val); + }; + + XMLStringifier.prototype.raw = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.attName = function(val) { + val = '' + val || ''; + return val = this.applyCase(val); + }; + + XMLStringifier.prototype.attValue = function(val) { + val = '' + val || ''; + return this.attEscape(val); + }; + + XMLStringifier.prototype.insTarget = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.insValue = function(val) { + val = '' + val || ''; + if (val.match(/\?>/)) { + throw new Error("Invalid processing instruction value: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlVersion = function(val) { + val = '' + val || ''; + if (!val.match(/1\.[0-9]+/)) { + throw new Error("Invalid version number: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlEncoding = function(val) { + val = '' + val || ''; + if (!val.match(/^[A-Za-z](?:[A-Za-z0-9._-]|-)*$/)) { + throw new Error("Invalid encoding: " + val); + } + return val; + }; + + XMLStringifier.prototype.xmlStandalone = function(val) { + if (val) { + return "yes"; + } else { + return "no"; + } + }; + + XMLStringifier.prototype.dtdPubID = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdSysID = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdElementValue = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdAttType = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdAttDefault = function(val) { + if (val != null) { + return '' + val || ''; + } else { + return val; + } + }; + + XMLStringifier.prototype.dtdEntityValue = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.dtdNData = function(val) { + return '' + val || ''; + }; + + XMLStringifier.prototype.convertAttKey = '@'; + + XMLStringifier.prototype.convertPIKey = '?'; + + XMLStringifier.prototype.convertTextKey = '#text'; + + XMLStringifier.prototype.convertCDataKey = '#cdata'; + + XMLStringifier.prototype.convertCommentKey = '#comment'; + + XMLStringifier.prototype.convertRawKey = '#raw'; + + XMLStringifier.prototype.assertLegalChar = function(str) { + var chars, chr; + if (this.allowSurrogateChars) { + chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uFFFE-\uFFFF]/; + } else { + chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]/; + } + chr = str.match(chars); + if (chr) { + throw new Error("Invalid character (" + chr + ") in string: " + str + " at index " + chr.index); + } + return str; + }; + + XMLStringifier.prototype.applyCase = function(str) { + switch (this.textCase) { + case "camel": + return camelCase(str); + case "kebab": + case "lower": + return kebabCase(str); + case "snake": + return snakeCase(str); + case "upper": + return kebabCase(str).toUpperCase(); + default: + return str; + } + }; + + XMLStringifier.prototype.elEscape = function(str) { + var ampregex; + ampregex = this.noDoubleEncoding ? /(?!&\S+;)&/g : /&/g; + return str.replace(ampregex, '&').replace(//g, '>').replace(/\r/g, ' '); + }; + + XMLStringifier.prototype.attEscape = function(str) { + var ampregex; + ampregex = this.noDoubleEncoding ? /(?!&\S+;)&/g : /&/g; + return str.replace(ampregex, '&').replace(/=1.0.0", + "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/xml2js" + ] + ], + "_from": "xmlbuilder@>=1.0.0", + "_id": "xmlbuilder@5.0.1", + "_inCache": true, + "_installable": true, + "_location": "/xmlbuilder", + "_npmOperationalInternal": { + "host": "packages-13-west.internal.npmjs.com", + "tmp": "tmp/xmlbuilder-5.0.1.tgz_1457392734733_0.19968478404916823" + }, + "_npmUser": { + "email": "oozcitak@gmail.com", + "name": "oozcitak" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "name": "xmlbuilder", + "raw": "xmlbuilder@>=1.0.0", + "rawSpec": ">=1.0.0", + "scope": null, + "spec": ">=1.0.0", + "type": "range" + }, + "_requiredBy": [ + "/xml2js" + ], + "_resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-5.0.1.tgz", + "_shasum": "155f1fb6e860137047443db54a9b263761b1f5c3", + "_shrinkwrap": null, + "_spec": "xmlbuilder@>=1.0.0", + "_where": "/Users/adamdon/Desktop/studywell/studywell/sw/www/node_modules/xml2js", + "author": { + "email": "oozcitak@gmail.com", + "name": "Ozgur Ozcitak" + }, + "bugs": { + "url": "http://github.com/oozcitak/xmlbuilder-js/issues" + }, + "contributors": [], + "dependencies": { + "lodash": "^4.0.0" + }, + "description": "An XML builder for node.js", + "devDependencies": { + "coffee-coverage": "*", + "coffee-script": "*", + "coveralls": "*", + "istanbul": "*", + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "155f1fb6e860137047443db54a9b263761b1f5c3", + "tarball": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-5.0.1.tgz" + }, + "engines": { + "node": ">=0.10" + }, + "gitHead": "328bfb90488b9823361e329598c5b2c8b9d3c1a8", + "homepage": "http://github.com/oozcitak/xmlbuilder-js", + "keywords": [ + "xml", + "xmlbuilder" + ], + "license": "MIT", + "main": "./lib/index", + "maintainers": [ + { + "email": "oozcitak@gmail.com", + "name": "oozcitak" + } + ], + "name": "xmlbuilder", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/oozcitak/xmlbuilder-js.git" + }, + "scripts": { + "postpublish": "rm -rf lib", + "prepublish": "coffee -co lib src", + "test": "mocha && istanbul report text lcov" + }, + "version": "5.0.1" +} diff --git a/www/package.json b/www/package.json new file mode 100644 index 0000000..70a9554 --- /dev/null +++ b/www/package.json @@ -0,0 +1,15 @@ +{ + "name": "studywelltests", + "version": "1.0.0", + "description": "gui tests for studywell", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Adam Don", + "license": "ISC", + "dependencies": { + "jasmine": "^2.4.1", + "selenium-webdriver": "^2.52.0" + } +} diff --git a/www/reports.html b/www/reports.html index 3273dff..93f0fc1 100644 --- a/www/reports.html +++ b/www/reports.html @@ -6,7 +6,9 @@ Reports - + + + @@ -23,7 +25,7 @@ - +
    diff --git a/www/resources/css/index.css b/www/resources/css/index.css deleted file mode 100644 index 7db53e4..0000000 --- a/www/resources/css/index.css +++ /dev/null @@ -1,4 +0,0 @@ -/* Stop main content being scrollable - */.noScroll { - {overflow: hidden; - } \ No newline at end of file diff --git a/www/resources/js/alerts.js b/www/resources/js/alerts.js index c1e5b45..0475c84 100644 --- a/www/resources/js/alerts.js +++ b/www/resources/js/alerts.js @@ -1,3 +1,7 @@ +var breakAlertUp = false; +var breakReminderCount = 0; +var distractedReminderCount = 0; + //Alert the user they have successfully set a custom ambient noise level function customVolumeLevelSet() { navigator.notification.alert( @@ -43,16 +47,17 @@ function stillRecordingNoiseLevelWarning() { ); } +//for some reason this nicer looking prompt broke (text input colour became white on white) //Ask the user for notes on their session. ---------------------------------------------------------------- -function askUserNotes() { - navigator.notification.prompt( - 'This is an opportunity to enter any notes you wish to remember about this session', // message - onPrompt, // callback to invoke - 'User Notes', // title - ['Ok'], // buttonLabels - ' ' // defaultText - ); -} +// function askUserNotes() { +// navigator.notification.prompt( +// 'This is an opportunity to enter any notes you wish to remember about this session', // message +// onPrompt, // callback to invoke +// 'User Notes', // title +// ['Ok'] // buttonLabels + +// ); +// } function onPrompt(results) { userNotes = results.input1; @@ -103,7 +108,7 @@ function onConfirmStopMon(buttonIndex) { function pausedPrompt() { pauseMonitoring(); navigator.notification.alert( - 'Monitoring has been paused, click OK when you wish to resume!', // message + 'Monitoring has been paused, click OK when you wish to resume.', // message resumeMonitoring, // callback 'Monitoring Paused', // title 'OK' // buttonName @@ -120,6 +125,11 @@ function checkDistractedReminder() { if (localStorage.getItem("score") > score) { if ((localStorage.getItem("score") - score) > 15) { returnToStudyAlert(); + distractedReminderCount++; + if (cordova.plugins.backgroundMode.isActive()) { + returnToStudyNotif(); + } + } } } @@ -132,7 +142,7 @@ function returnToStudyAlert() { navigator.notification.beep(1); navigator.notification.confirm( - 'Seems like you may have become a little distracted. Have you finished your study session?', // message + 'We think you may have become a little distracted. Have you finished your study session?', // message onConfirmReturn, // callback 'Sorry to interrupt, but...', // title ['Take a Break', 'Yes', 'No'] // button labels @@ -153,6 +163,14 @@ function onConfirmReturn(buttonIndex) { //continue monitoring (do nothing) } } + +function returnToStudyNotif() { + cordova.plugins.notification.local.schedule({ + id: 20, + title: "Sorry to interrupt, but...", + text: "We think you may have become a little distracted. Have you finished your study session?" + }); +} //End of Alert the user that they've been distracted for a while------------------------------------------------- @@ -161,19 +179,23 @@ function onConfirmReturn(buttonIndex) { function takeABreakAlert() { navigator.notification.beep(1); - - navigator.notification.confirm( - 'Seems like you\'ve been studying well for quite some time now. We recommend a 10 minute break for optimum brain functionality!', // message - onConfirmBreak, // callback - 'Sorry to interrupt, but...', // title - ['Continue Studying', 'Take a Break'] // button labels - ); - + if (breakAlertUp != true) { + breakAlertUp = true; + navigator.notification.confirm( + 'Seems like you\'ve been studying well for ' +((getOptimalStudyPeriod()/1000)/60) +' minutes now. We recommend a 5 to 10 minute break for optimum brain functionality!', // message + onConfirmBreak, // callback + 'Sorry to interrupt, but...', // title + ['Continue Studying', 'Take a Break'] // button labels + ); + } } function onConfirmBreak(buttonIndex) { + breakAlertUp = false; if (buttonIndex == 1) { //continue monitoring (do nothing) + timeResumed = new Date(); + } if (buttonIndex == 2) { //pause monitoring @@ -193,14 +215,29 @@ function checkBreakReminder() { if ((localStorage.getItem("oldScore") - 5) <= score) { if (score > 60) { //prompt break + if (cordova.plugins.backgroundMode.isActive()) { + takeABreakNotif(); + } takeABreakAlert(); + console.log("break suggested at: " + currentT + "time since break: " +timeSinceBreak); + localStorage.setItem("breakSuggestedTime", currentT); + localStorage.setItem("timeSinceBreak", timeSinceBreak); timeResumed = new Date(); + breakReminderCount++; } } } } } +function takeABreakNotif() { + cordova.plugins.notification.local.schedule({ + id: 10, + title: "Sorry to interrupt, but...", + text: "Seems like you've been studying well for " +((getOptimalStudyPeriod()/1000)/60) + " minutes now. We recommend a 5 to 10 minute break for optimum brain functionality!" + }); +} + function checkScore() { var score = createStudyScore(micNotStudying, micIntervalCount, accelNotStudying, accelIntervalCount);; localStorage.setItem("oldScore", score); diff --git a/www/resources/js/backend.js b/www/resources/js/backend.js index de020bd..e73c071 100644 --- a/www/resources/js/backend.js +++ b/www/resources/js/backend.js @@ -1,3 +1,4 @@ + var swFireBase = new Firebase("https://vivid-heat-9475.firebaseIO.com/"); var users = swFireBase.child('users'); @@ -19,7 +20,10 @@ function pushData() { accelIntervalCount: accelIntervalCount, accelNotStudingCount: accelNotStudying, appMessage: appMessage, - userNotes: getUserNotes() + userNotes: getUserNotes(), + distractedReminder: getDistractedBool() +" Count: " +distractedReminderCount, + breakReminder: getBreakNotifBool() +" Count: " +breakReminderCount + } ); } diff --git a/www/resources/js/mic.js b/www/resources/js/mic.js index 7d684c3..5961b87 100644 --- a/www/resources/js/mic.js +++ b/www/resources/js/mic.js @@ -49,44 +49,57 @@ function readMic(reading) { micOn(); } - micCount++; - micVolume.read(function(reading) { - console.log(reading.volume); - vol = reading.volume; - totalVol = totalVol + vol; - }, errorCallback); + micPulseCount++; - averageVol = totalVol / micCount; - if (averageVol > (getAmbientNoiseLevel() + 10) && micCount > 29) { - noisyBackground(); - noiseLevel = "vhigh"; - } else if (averageVol > (getAmbientNoiseLevel() + 5) && micCount > 29) { - noisyBackground(); - noiseLevel = "high"; - } else if (averageVol > getAmbientNoiseLevel() && micCount > 29) { - noisyBackground(); - noiseLevel = "medium"; - } else if (micCount > 29) { - noiseLevel = "low"; - micIntervalNSBool = "false"; //look to sampling method for more information on what this is for + //check how fast the phone can pulse mic (some phones may be limited) + if (localStorage.getItem("micPulseCount") == null) { + localStorage.setItem("micPulseCount", micPulseCount); + } else if (micPulseCount > localStorage.getItem("micPulseCount")) { + localStorage.setItem("micPulseCount", micPulseCount); } - - //As long as this isn't the first time this method is running, check if the sample rate needs updated. - if (localStorage.getItem("oldMicIntervalNSBool") != null) { - //console.log('running updateSampleR'); - //updateSampleRate(micIntervalNSBool, micSampleRate, localStorage.getItem("oldMicIntervalNSBool"), "microphone"); + //safety precausion to make sure micPulseCount does not go above 30 + if (localStorage.getItem("accelPulseCount") > 30) { + localStorage.setItem("accelPulseCount", 30); } + if (firstRunMic != true) { + + micVolume.read(function(reading) { + // console.log("micPulseCount: " + micPulseCount + " vol: " + reading.volume); + vol = reading.volume; + totalVol = totalVol + vol; + }, errorCallback); + + averageVol = totalVol / micPulseCount; + if (averageVol > (getAmbientNoiseLevel() + 10) && micPulseCount > (localStorage.getItem("micPulseCount")-1)) { + noisyBackground(); + noiseLevel = "vhigh"; + } else if (averageVol > (getAmbientNoiseLevel() + 5) && micPulseCount > (localStorage.getItem("micPulseCount")-1)) { + noisyBackground(); + noiseLevel = "high"; + } else if (averageVol > getAmbientNoiseLevel() && micPulseCount > (localStorage.getItem("micPulseCount")-1)) { + noisyBackground(); + noiseLevel = "medium"; + } else if (micPulseCount > (localStorage.getItem("micPulseCount")-1)) { + noiseLevel = "low"; + micIntervalNSBool = "false"; //look to sampling method for more information on what this is for + } + + //As long as this isn't the first time this method is running, check if the sample rate needs updated. + if (localStorage.getItem("oldMicIntervalNSBool") != null) { + //console.log('running updateSampleR'); + //updateSampleRate(micIntervalNSBool, micSampleRate, localStorage.getItem("oldMicIntervalNSBool"), "microphone"); + } + + //This is so we can compare the values from this interval and the previous interval + if (typeof(Storage) !== "undefined") { + localStorage.setItem("oldMicIntervalNSBool", micIntervalNSBool); + + } else { + // Sorry! No Web Storage support.. + console.log("No web storage support - oh dear."); + } - //This is so we can compare the values from this interval and the previous interval - if (typeof(Storage) !== "undefined") { - localStorage.setItem("oldMicIntervalNSBool", micIntervalNSBool); - - } else { - // Sorry! No Web Storage support.. - console.log("No web storage support - oh dear."); } - - } //Loop the microphone sensor for 10 seconds (perform an interval) @@ -95,7 +108,7 @@ function micInterval() { micIntervalNSBool = false; //boolean to determine if the user is not studying during the current interval micIntervalCount++; - micCount = 0; //this is a count of how many pulses the microphones sensors has read (how many times readMic was called in this interval) + micPulseCount = 0; //this is a count of how many pulses the microphones sensors has read (how many times readMic was called in this interval) totalVol = 0; //for working out the average within readMic micSensor = setInterval(readMic, 333); //measure values every x milliseconds setTimeout(stopMicInterval, 10000); //stop reading after x milliseconds @@ -103,6 +116,7 @@ function micInterval() { //stop the mic sensing function stopMicInterval() { + firstRunMic = false; clearInterval(micSensor); clearTimeout(micSensor); clearTimeout(stopMicInterval); @@ -111,7 +125,7 @@ function stopMicInterval() { //If the surrounding noise level is above the threshold value, do these things. function noisyBackground() { - //console.log('It is noisy!'); + console.log('mic not studying count went up'); micIntervalNSBool = "true"; micNotStudying++; } @@ -124,14 +138,14 @@ function getAverageVolume() { //-------------------Recording ambient noise level within settings to set a custom threshold value----------- function recordAmbientNoiseLevel(reading) { - micCount++; + micPulseCount++; micVolume.read(function(reading) { console.log(reading.volume); vol = reading.volume; totalVol = totalVol + vol; }, errorCallback); - averageVol = totalVol / micCount; + averageVol = totalVol / micPulseCount; if (typeof(Storage) !== "undefined") { localStorage.setItem("ambientNoiseLevel", (averageVol + 1)); @@ -151,12 +165,13 @@ function startRecordingAmbientNoiseLevel(button) { micOff(); micOn(); button.disabled = true; //disable the button - micCount = 0; + micPulseCount = 0; totalVol = 0; recordLevel = setInterval(recordAmbientNoiseLevel, 200); setTimeout(killNoiseLevelRecording, 10000); setTimeout(function() { - button.disabled = false; } //enable the button again + button.disabled = false; + } //enable the button again , 10000) } diff --git a/www/resources/js/motion.js b/www/resources/js/motion.js index d74d32f..81dfdf7 100644 --- a/www/resources/js/motion.js +++ b/www/resources/js/motion.js @@ -1,9 +1,9 @@ // function onSuccessAcc(acceleration) { - console.log('Acceleration X: ' + acceleration.x + '\n' + - 'Acceleration Y: ' + acceleration.y + '\n' + - 'Acceleration Z: ' + acceleration.z + '\n' + - 'Timestamp: ' + acceleration.timestamp + '\n'); + // console.log('Acceleration X: ' + acceleration.x + '\n' + + // 'Acceleration Y: ' + acceleration.y + '\n' + + // 'Acceleration Z: ' + acceleration.z + '\n' + + // 'Timestamp: ' + acceleration.timestamp + '\n'); // var currentAccelValues = new accelValues(acceleration.x, acceleration.y, acceleration.z, acceleration.timestamp); //boolean for if the device is moving or not @@ -11,6 +11,11 @@ function onSuccessAcc(acceleration) { accelPulseCount++; //this is a count of how many pulses the accelerometer sensor has read (how many pulses within this interval) + + + + + //check how fast the phone can pulse accelerometer (some phones limited) if (localStorage.getItem("accelPulseCount") == null) { localStorage.setItem("accelPulseCount", accelPulseCount); @@ -20,30 +25,33 @@ function onSuccessAcc(acceleration) { //safety precausion to make sure accelPulseCount does not go above 9 if (localStorage.getItem("accelPulseCount") > 9) { localStorage.setItem("accelPulseCount", 9); -} + } //if this is the first interval run then skip (we want to count the number of pulses per interval first) - if (firstRun != true) { - - //check if phone is in motion - if (acceleration.x > 1 || acceleration.x < -1) { - moving = true; - } - if (acceleration.y > 1 || acceleration.y < -1) { - moving = true; - } - if (acceleration.z > 10.2 || acceleration.z < 8.2) { - moving = true; + if (firstRunAccel != true) { + + if (localStorage.getItem("accelX") != null) { + //check if phone was in motion + if (Math.abs(localStorage.getItem("accelX")) - Math.abs(acceleration.x) > 0.5 || Math.abs(localStorage.getItem("accelX")) - Math.abs(acceleration.x) < -0.5) { + hasMoved = true; + } + if (Math.abs(localStorage.getItem("accelY")) - Math.abs(acceleration.y) > 0.5 || Math.abs(localStorage.getItem("accelY")) - Math.abs(acceleration.y) < -0.5) { + hasMoved = true; + } + if (Math.abs(localStorage.getItem("accelZ")) - Math.abs(acceleration.z) > 0.5 || Math.abs(localStorage.getItem("accelZ")) - Math.abs(acceleration.z) < -0.5) { + hasMoved = true; + } else + hasMoved = false; + console.log("X difference: " + (Math.abs(localStorage.getItem("accelX")) - Math.abs(acceleration.x))); + console.log("Y difference: " + (Math.abs(localStorage.getItem("accelY")) - Math.abs(acceleration.y))); + console.log("Z difference: " + (Math.abs(localStorage.getItem("accelZ")) - Math.abs(acceleration.z))); } - if (moving) { - motionCount++; - } - //if total count of moving is greater than the total number of pulses per interval divided by 3 then device is said to be moving in this interval - if (motionCount > (localStorage.getItem("accelPulseCount") / 3)) { - accelNotStudying++; - accelIntervalNSBool = "true"; - //console.log("Hit the interval move loop"); + + if (hasMoved) { + console.log("accel not studying count went up"); + accelNotStudying++; + accelIntervalNSBool = "true"; stopAccelInterval(); } else if (accelPulseCount > (localStorage.getItem("accelPulseCount") - 1)) { //once the interval is nearly finished, device is not moving this interval @@ -51,12 +59,14 @@ function onSuccessAcc(acceleration) { //console.log("accelIntervalNSBool: " +accelIntervalNSBool ); accelPulseCount = 0; //console.log("Hit the interval not moving loop"); + console.log("accel not studying REMAINS the same"); + } //As long as this isn't the first time this method is running, check if the sample rate needs updated. if (localStorage.getItem("oldAccelIntervalNSBool") != null) { //console.log('running updateSampleR'); - //updateSampleRate(accelIntervalNSBool, accelSampleRate, localStorage.getItem("oldAccelIntervalNSBool"), "accelerometer"); + updateSampleRate(accelIntervalNSBool, accelSampleRate, localStorage.getItem("oldAccelIntervalNSBool"), "accelerometer"); } //This is so we can compare the values from this interval and the previous interval if (typeof(Storage) !== "undefined") { @@ -66,8 +76,15 @@ function onSuccessAcc(acceleration) { // Sorry! No Web Storage support.. console.log("No web storage support - oh dear."); } - console.log('Device moving: ' + moving); + // console.log('Device moving: ' + moving); + console.log('Device moving: ' + hasMoved); + } + + //Store the values to compare next interval + localStorage.setItem("accelX", acceleration.x); + localStorage.setItem("accelY", acceleration.y); + localStorage.setItem("accelZ", acceleration.z); } @@ -85,7 +102,7 @@ function readAccel() { function accelInterval() { //localStorage.setItem("oldAccelIntervalNotStudyingBool", "initial"); accelPulseCount = 0; //this is a count of how many pulses the accelerometer sensor has read (how many pulses within this interval) - + hasMoved = false; //console.log("Accelerometer sampling rate: " + accelSampleRate); accelIntervalNSBool = false; //boolean to determine if the user is not studying during the current interval @@ -97,7 +114,7 @@ function accelInterval() { //finish the interval function stopAccelInterval() { - firstRun = false; + firstRunAccel = false; clearInterval(accelSensor); clearTimeout(accelSensor); clearTimeout(stopAccelInterval); diff --git a/www/resources/js/motionOldAlgo.js b/www/resources/js/motionOldAlgo.js new file mode 100644 index 0000000..750ae00 --- /dev/null +++ b/www/resources/js/motionOldAlgo.js @@ -0,0 +1,104 @@ +// +function onSuccessAcc(acceleration) { + console.log('Acceleration X: ' + acceleration.x + '\n' + + 'Acceleration Y: ' + acceleration.y + '\n' + + 'Acceleration Z: ' + acceleration.z + '\n' + + 'Timestamp: ' + acceleration.timestamp + '\n'); + // var currentAccelValues = new accelValues(acceleration.x, acceleration.y, acceleration.z, acceleration.timestamp); + + //boolean for if the device is moving or not + var moving = false; + + accelPulseCount++; //this is a count of how many pulses the accelerometer sensor has read (how many pulses within this interval) + + //check how fast the phone can pulse accelerometer (some phones limited) + if (localStorage.getItem("accelPulseCount") == null) { + localStorage.setItem("accelPulseCount", accelPulseCount); + } else if (accelPulseCount > localStorage.getItem("accelPulseCount")) { + localStorage.setItem("accelPulseCount", accelPulseCount); + } + //safety precausion to make sure accelPulseCount does not go above 9 + if (localStorage.getItem("accelPulseCount") > 9) { + localStorage.setItem("accelPulseCount", 9); +} + //if this is the first interval run then skip (we want to count the number of pulses per interval first) + if (firstRunAccel != true) { + + //check if phone is in motion + if (acceleration.x > 1 || acceleration.x < -1) { + moving = true; + } + if (acceleration.y > 1 || acceleration.y < -1) { + moving = true; + } + if (acceleration.z > 10.2 || acceleration.z < 8.2) { + moving = true; + } + if (moving) { + motionCount++; + } + //if total count of moving is greater than the total number of pulses per interval divided by 3 then device is said to be moving in this interval + if (motionCount > (localStorage.getItem("accelPulseCount") / 3)) { + accelNotStudying++; + accelIntervalNSBool = "true"; + //console.log("Hit the interval move loop"); + + + stopAccelInterval(); + + } else if (accelPulseCount > (localStorage.getItem("accelPulseCount") - 1)) { //once the interval is nearly finished, device is not moving this interval + accelIntervalNSBool = "false"; + //console.log("accelIntervalNSBool: " +accelIntervalNSBool ); + accelPulseCount = 0; + //console.log("Hit the interval not moving loop"); + + } + //As long as this isn't the first time this method is running, check if the sample rate needs updated. + if (localStorage.getItem("oldAccelIntervalNSBool") != null) { + //console.log('running updateSampleR'); + //updateSampleRate(accelIntervalNSBool, accelSampleRate, localStorage.getItem("oldAccelIntervalNSBool"), "accelerometer"); + } + //This is so we can compare the values from this interval and the previous interval + if (typeof(Storage) !== "undefined") { + localStorage.setItem("oldAccelIntervalNSBool", accelIntervalNSBool); + + } else { + // Sorry! No Web Storage support.. + console.log("No web storage support - oh dear."); + } + console.log('Device moving: ' + moving); + } +} + + +function onErrorAcc() { + alert('Error: ' + error); +} + + +function readAccel() { + navigator.accelerometer.getCurrentAcceleration(onSuccessAcc, onErrorAcc); +} + + +//Loop the accelerometer sensor reading to pulse every one second for 10 seconds. +function accelInterval() { + //localStorage.setItem("oldAccelIntervalNotStudyingBool", "initial"); + accelPulseCount = 0; //this is a count of how many pulses the accelerometer sensor has read (how many pulses within this interval) + + //console.log("Accelerometer sampling rate: " + accelSampleRate); + accelIntervalNSBool = false; //boolean to determine if the user is not studying during the current interval + + accelIntervalCount++; //how many intervals the accelerometer has been monitored for during this session + motionCount = 0; //how many times the accelerometer has pulsed during this session + accelSensor = setInterval(readAccel, 1000); //measure values every x milliseconds + setTimeout(stopAccelInterval, 10000); //stop reading after x milliseconds +} + +//finish the interval +function stopAccelInterval() { + firstRunAccel = false; + clearInterval(accelSensor); + clearTimeout(accelSensor); + clearTimeout(stopAccelInterval); +} \ No newline at end of file diff --git a/www/resources/js/reports.js b/www/resources/js/reports.js index b79e3a2..9ebc1a0 100644 --- a/www/resources/js/reports.js +++ b/www/resources/js/reports.js @@ -34,7 +34,7 @@ function drawData(date, time, duration, score, appMessage, userNotes, sessionID) var sessionTable = "" sessionTable += "" sessionTable += "" - sessionTable += "" + sessionTable += "" sessionTable += "" sessionTable += "" sessionTable += "
    Date: " +date + "
    Start Time: " +time + "
    Duration: " +duration + "
    Score: " +score + "
    Score: " +score + " / 100
    App Notes: " +appMessage + "
    User Notes: " +userNotes + "
    Session ID: " +sessionID + "


    " diff --git a/www/resources/js/sampling.js b/www/resources/js/sampling.js index 9b40fe4..7f87c03 100644 --- a/www/resources/js/sampling.js +++ b/www/resources/js/sampling.js @@ -1,7 +1,7 @@ //class to control sampling rates of sensors function increaseSampleRate(currentRate) { - if (currentRate > 30000) { + if (currentRate > 30000) { //highest sampling rate is 30 seconds var newRate = currentRate - 30000; return newRate; } else { @@ -11,7 +11,7 @@ function increaseSampleRate(currentRate) { } function decreaseSampleRate(currentRate) { - if (currentRate < 1200000) { + if (currentRate < 300000) { //slowest sampling rate is 5 minutes var newRate = currentRate + 30000; return newRate; } else { diff --git a/www/resources/js/scoring.js b/www/resources/js/scoring.js index 51272f3..67f09cb 100644 --- a/www/resources/js/scoring.js +++ b/www/resources/js/scoring.js @@ -19,9 +19,9 @@ function createStudyScore(micNotStudying, micIntervalCount, accelNotStudying, ac } if (accelStudyScore > 75) { - appMessage += " There was also a lot of phone movement during this session."; + appMessage += " There was a lot of phone movement during this session."; } else if (accelStudyScore > 50) { - appMessage += " There also seemed to be quite a bit of phone movement - were you fiddling with your phone a lot?"; + appMessage += " There seemed to be quite a bit of phone movement - were you fiddling with your phone a lot?"; } else if (accelStudyScore > 25) { appMessage += " There seemed to be a moderate amount of phone movement, maybe you were fiddling with your phone every now and then?"; } else if (accelStudyScore < 25) { diff --git a/www/resources/js/study.js b/www/resources/js/study.js index 3830f52..3242b5b 100644 --- a/www/resources/js/study.js +++ b/www/resources/js/study.js @@ -49,6 +49,11 @@ var app = { } }); + cordova.plugins.backgroundMode.setDefaults({ + title: "Session In Progress", + text: "StudyWell is running in the background." + }) + @@ -77,13 +82,13 @@ function startMonitoringSensors() { updateScore = setInterval(scoreOnStudyPage, 60000); //Check if the user wants to be reminded if they are too distracted. - if (getDistractedBool) { + if (getDistractedBool() == "true") { setTimeout(checkDistractedReminder, 600000); //first check begins at 10 mins in (score would be 100 if we did it immediately and cause the next check to immeditately flag) studyCheck = setInterval(checkDistractedReminder, 1200000); //timer to check if the users score has dropped significantly in the last 20 mins } //Check if the user wants to be reminded of breaks - if (getBreakNotifBool()) { + if (getBreakNotifBool() == "true") { // setTimeout(checkBreakReminder, 600000); //first check begins at 10 mins in (score would be 100 if we did it immediately and cause the next check to immeditately flag) // breakCheck = setInterval(checkBreakReminder, 1200000); //timer to check if the users score has dropped significantly in the last 20 mins setTimeout(checkScore, 300000); //first check begins at 10 mins in (score would be 100 if we did it immediately and cause the next check to immeditately flag) @@ -125,10 +130,10 @@ function stopMonitoringSensors() { //timeStop = new Date(); //sessionDuration = (timeStop - timeBegin) - totalDurationPaused; - if (getDistractedBool()) { + if (getDistractedBool() == "true") { clearInterval(studyCheck); } - if (getBreakNotifBool()) { + if (getBreakNotifBool() == "true") { clearInterval(breakCheck); } clearInterval(accelMonSensor); @@ -173,7 +178,7 @@ function pauseMonitoring() { timePaused = new Date(); document.getElementById('myonoffswitch').checked = false; - if (getBreakNotifBool()) { + if (getBreakNotifBool() == "true") { clearInterval(breakCheck); } @@ -197,7 +202,7 @@ function resumeMonitoring() { durationPaused = timeResumed - timePaused; //keep track of duration of pausing totalDurationPaused += durationPaused; - if (getBreakNotifBool()) { + if (getBreakNotifBool() == "true") { breakCheck = setInterval(checkBreakReminder, 60000); //check if the user should consider having a break every minute } @@ -224,7 +229,9 @@ function getUserNotes() { function initialiseMonitoring() { document.getElementById("studyPageScore").innerHTML = ""; //clear the previous score from the page. - firstRun = true; //var to check if the phone has to indentify the speed at which accel can be checked + firstRunAccel = true; //var to check if the phone has to indentify the speed at which accel can be checked + firstRunMic = true; //var to check if the phone has to indentify the speed at which accel can be checked + timeResumed = new Date(); //for checking if user should have break (used to get duration since last break) localStorage.setItem("accelPulseCount", 0); @@ -232,12 +239,17 @@ function initialiseMonitoring() { micOff(); localStorage.removeItem("oldScore"); - + localStorage.removeItem("score"); + localStorage.removeItem("accelX"); + localStorage.removeItem("accelY"); + localStorage.removeItem("accelZ"); + breakReminderCount = 0; + distractedReminderCount = 0; totalDurationPaused = 0; - accelSampleRate = 30000; - micSampleRate = 30000; + accelSampleRate = 30000; //sampling rate for accelerometer + micSampleRate = 30000; //sampling rate for microphone micSteadyScoreCount = 0; micFluctuatingScoreCount = 0; accelSteadyScoreCount = 0; @@ -298,10 +310,14 @@ function disableWakeLock() { } -// function askUserNotes() { -// userNotes = prompt("This is an opportunity to enter any notes you wish to remember about this session. If you have nothing to add then just click OK."); -// localStorage.setItem("userNotes", userNotes); -// } + +//for some reason the nicer looking prompt broke (text input colour became white on white) +function askUserNotes() { + userNotes = prompt("This is an opportunity to enter any notes you wish to remember about this session. If you have nothing to add then just click OK."); + localStorage.setItem("userNotes", userNotes); + + pushData(); +} // function getUserNotes() { // if (localStorage.getItem("userNotes") != null) { diff --git a/www/schedule.html b/www/schedule.html index 02b456e..3acaa6c 100644 --- a/www/schedule.html +++ b/www/schedule.html @@ -14,7 +14,7 @@ - +
    diff --git a/www/settings.html b/www/settings.html index 53da3e7..99e7afa 100644 --- a/www/settings.html +++ b/www/settings.html @@ -11,7 +11,6 @@ - @@ -26,7 +25,7 @@ - +
    diff --git a/www/spec/UI-help-test.js b/www/spec/UI-help-test.js new file mode 100644 index 0000000..441e50c --- /dev/null +++ b/www/spec/UI-help-test.js @@ -0,0 +1,133 @@ +// + +var selenium = require('selenium-webdriver'); + +describe('StudyWell Help Page UI Tests', function() { + + // Open the web app in the browser before each test is run + beforeEach(function(done) { + this.driver = new selenium.Builder(). + withCapabilities(selenium.Capabilities.chrome()). + build(); + + this.driver.get('http://localhost:8000/help.html').then(done); + }); + + // Close the website after each test is run (so that it is opened fresh each time) + afterEach(function(done) { + this.driver.quit().then(done); + }); + + // Test to ensure we are on the home page by checking the tag id attribute + it('Should be on the home page', function(done) { + var element = this.driver.findElement(selenium.By.tagName('body')); + + element.getAttribute('id').then(function(id) { + expect(id).toBe('help'); + done(); + }); + }); + + // Test the navigation bar and home button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + + // Test the navigation bar and schedule button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('sched')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/schedule'); + done(); + }); + + }); + + // Test the navigation bar and reports button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('reps')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/reports'); + done(); + }); + + }); + + // Test the navigation bar and settings button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('set')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/settings'); + done(); + }); + + }); + + // Test the navigation bar and help button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('help')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/help'); + done(); + }); + + }); + + // Test the navigation bar and survey button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('survey')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/viewform'); + done(); + }); + + }); + + }); \ No newline at end of file diff --git a/www/spec/UI-home-test.js b/www/spec/UI-home-test.js new file mode 100644 index 0000000..b76e64f --- /dev/null +++ b/www/spec/UI-home-test.js @@ -0,0 +1,133 @@ +// + +var selenium = require('selenium-webdriver'); + +describe('StudyWell Home Page UI Tests', function() { + + // Open the web app in the browser before each test is run + beforeEach(function(done) { + this.driver = new selenium.Builder(). + withCapabilities(selenium.Capabilities.chrome()). + build(); + + this.driver.get('http://localhost:8000/index.html').then(done); + }); + + // Close the website after each test is run (so that it is opened fresh each time) + afterEach(function(done) { + this.driver.quit().then(done); + }); + + // Test to ensure we are on the home page by checking the tag id attribute + it('Should be on the home page', function(done) { + var element = this.driver.findElement(selenium.By.tagName('body')); + + element.getAttribute('id').then(function(id) { + expect(id).toBe('home'); + done(); + }); + }); + + // Test the navigation bar and home button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + + // Test the navigation bar and schedule button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('sched')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/schedule'); + done(); + }); + + }); + + // Test the navigation bar and reports button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('reps')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/reports'); + done(); + }); + + }); + + // Test the navigation bar and settings button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('set')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/settings'); + done(); + }); + + }); + + // Test the navigation bar and help button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('help')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/help'); + done(); + }); + + }); + + // Test the navigation bar and survey button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('survey')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/viewform'); + done(); + }); + + }); + + }); \ No newline at end of file diff --git a/www/spec/UI-reports-test.js b/www/spec/UI-reports-test.js new file mode 100644 index 0000000..d8643e9 --- /dev/null +++ b/www/spec/UI-reports-test.js @@ -0,0 +1,133 @@ +// + +var selenium = require('selenium-webdriver'); + +describe('StudyWell Report Page UI Tests', function() { + + // Open the web app in the browser before each test is run + beforeEach(function(done) { + this.driver = new selenium.Builder(). + withCapabilities(selenium.Capabilities.chrome()). + build(); + + this.driver.get('http://localhost:8000/reports.html').then(done); + }); + + // Close the website after each test is run (so that it is opened fresh each time) + afterEach(function(done) { + this.driver.quit().then(done); + }); + + // Test to ensure we are on the home page by checking the tag id attribute + it('Should be on the home page', function(done) { + var element = this.driver.findElement(selenium.By.tagName('body')); + + element.getAttribute('id').then(function(id) { + expect(id).toBe('reports'); + done(); + }); + }); + + // Test the navigation bar and home button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + + // Test the navigation bar and schedule button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('sched')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/schedule'); + done(); + }); + + }); + + // Test the navigation bar and reports button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('reps')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/reports'); + done(); + }); + + }); + + // Test the navigation bar and settings button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('set')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/settings'); + done(); + }); + + }); + + // Test the navigation bar and help button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('help')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/help'); + done(); + }); + + }); + + // Test the navigation bar and survey button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('survey')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/viewform'); + done(); + }); + + }); + + }); \ No newline at end of file diff --git a/www/spec/UI-schedule-test.js b/www/spec/UI-schedule-test.js new file mode 100644 index 0000000..19e0895 --- /dev/null +++ b/www/spec/UI-schedule-test.js @@ -0,0 +1,133 @@ +// + +var selenium = require('selenium-webdriver'); + +describe('StudyWell Schedule page UI Tests', function() { + + // Open the web app in the browser before each test is run + beforeEach(function(done) { + this.driver = new selenium.Builder(). + withCapabilities(selenium.Capabilities.chrome()). + build(); + + this.driver.get('http://localhost:8000/schedule.html').then(done); + }); + + // Close the website after each test is run (so that it is opened fresh each time) + afterEach(function(done) { + this.driver.quit().then(done); + }); + + // Test to ensure we are on the home page by checking the tag id attribute + it('Should be on the home page', function(done) { + var element = this.driver.findElement(selenium.By.tagName('body')); + + element.getAttribute('id').then(function(id) { + expect(id).toBe('schedule'); + done(); + }); + }); + + // Test the navigation bar and home button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + + // Test the navigation bar and schedule button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('sched')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/schedule'); + done(); + }); + + }); + + // Test the navigation bar and reports button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('reps')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/reports'); + done(); + }); + + }); + + // Test the navigation bar and settings button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('set')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/settings'); + done(); + }); + + }); + + // Test the navigation bar and help button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('help')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/help'); + done(); + }); + + }); + + // Test the navigation bar and survey button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('survey')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/viewform'); + done(); + }); + + }); + + }); \ No newline at end of file diff --git a/www/spec/UI-settings-test.js b/www/spec/UI-settings-test.js new file mode 100644 index 0000000..df8240b --- /dev/null +++ b/www/spec/UI-settings-test.js @@ -0,0 +1,133 @@ +// + +var selenium = require('selenium-webdriver'); + +describe('StudyWell Settings Page UI Tests', function() { + + // Open the web app in the browser before each test is run + beforeEach(function(done) { + this.driver = new selenium.Builder(). + withCapabilities(selenium.Capabilities.chrome()). + build(); + + this.driver.get('http://localhost:8000/settings.html').then(done); + }); + + // Close the website after each test is run (so that it is opened fresh each time) + afterEach(function(done) { + this.driver.quit().then(done); + }); + + // Test to ensure we are on the home page by checking the tag id attribute + it('Should be on the home page', function(done) { + var element = this.driver.findElement(selenium.By.tagName('body')); + + element.getAttribute('id').then(function(id) { + expect(id).toBe('settings'); + done(); + }); + }); + + // Test the navigation bar and home button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('ST')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/index'); + done(); + }); + + }); + + // Test the navigation bar and schedule button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('sched')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/schedule'); + done(); + }); + + }); + + // Test the navigation bar and reports button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('reps')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/reports'); + done(); + }); + + }); + + // Test the navigation bar and settings button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('set')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/settings'); + done(); + }); + + }); + + // Test the navigation bar and help button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('help')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/help'); + done(); + }); + + }); + + // Test the navigation bar and survey button page + it('Has a working nav', function(done) { + var element = this.driver.findElement(selenium.By.id('hamburger')); + + element.click(); + + var menuElement = this.driver.findElement(selenium.By.id('survey')); + + menuElement.click(); + + this.driver.getCurrentUrl().then(function(value) { + expect(value).toContain('/viewform'); + done(); + }); + + }); + + }); \ No newline at end of file diff --git a/www/spec/support/jasmine.json b/www/spec/support/jasmine.json new file mode 100644 index 0000000..3ea3166 --- /dev/null +++ b/www/spec/support/jasmine.json @@ -0,0 +1,11 @@ +{ + "spec_dir": "spec", + "spec_files": [ + "**/*[sS]pec.js" + ], + "helpers": [ + "helpers/**/*.js" + ], + "stopSpecOnExpectationFailure": false, + "random": false +} diff --git a/www/vendors/jquery/slidemenu.hamburger.scroll.css b/www/vendors/jquery/slidemenu.hamburger.scroll.css index 4b80ac7..6b27568 100644 --- a/www/vendors/jquery/slidemenu.hamburger.scroll.css +++ b/www/vendors/jquery/slidemenu.hamburger.scroll.css @@ -3,8 +3,6 @@ body { margin: 0; padding: 0; background: #eee; - overflow-x: auto; - overflow-y: auto; } a { text-decoration: none; } @@ -51,6 +49,8 @@ header { -webkit-box-shadow: -10px 0px 9px 0px rgba(0, 0, 0, 0.4); box-shadow: -10px 0px 9px 0px rgba(0, 0, 0, 0.4); overflow: auto; + overflow-x: auto; + overflow-y: auto; } nav { diff --git a/www/vendors/js/firebase2.4.js b/www/vendors/js/firebase2.4.js new file mode 100644 index 0000000..a4a0f92 --- /dev/null +++ b/www/vendors/js/firebase2.4.js @@ -0,0 +1,7148 @@ +/*! @license Firebase v2.4.0 + License: https://www.firebase.com/terms/terms-of-service.html */ +(function() { + var h, n = this; + + function p(a) { + return void 0 !== a + } + + function aa() {} + + function ba(a) { + a.yb = function() { + return a.zf ? a.zf : a.zf = new a + } + } + + function ca(a) { + var b = typeof a; + if ("object" == b) + if (a) { + if (a instanceof Array) return "array"; + if (a instanceof Object) return b; + var c = Object.prototype.toString.call(a); + if ("[object Window]" == c) return "object"; + if ("[object Array]" == c || "number" == typeof a.length && "undefined" != typeof a.splice && "undefined" != typeof a.propertyIsEnumerable && !a.propertyIsEnumerable("splice")) return "array"; + if ("[object Function]" == c || "undefined" != typeof a.call && "undefined" != typeof a.propertyIsEnumerable && !a.propertyIsEnumerable("call")) return "function" + } else return "null"; + else if ("function" == b && "undefined" == typeof a.call) return "object"; + return b + } + + function da(a) { + return "array" == ca(a) + } + + function ea(a) { + var b = ca(a); + return "array" == b || "object" == b && "number" == typeof a.length + } + + function q(a) { + return "string" == typeof a + } + + function fa(a) { + return "number" == typeof a + } + + function r(a) { + return "function" == ca(a) + } + + function ga(a) { + var b = typeof a; + return "object" == b && null != a || "function" == b + } + + function ha(a, b, c) { + return a.call.apply(a.bind, arguments) + } + + function ia(a, b, c) { + if (!a) throw Error(); + if (2 < arguments.length) { + var d = Array.prototype.slice.call(arguments, 2); + return function() { + var c = Array.prototype.slice.call(arguments); + Array.prototype.unshift.apply(c, d); + return a.apply(b, c) + } + } + return function() { + return a.apply(b, arguments) + } + } + + function u(a, b, c) { + u = Function.prototype.bind && -1 != Function.prototype.bind.toString().indexOf("native code") ? ha : ia; + return u.apply(null, arguments) + } + var ja = Date.now || function() { + return +new Date + }; + + function ka(a, b) { + function c() {} + c.prototype = b.prototype; + a.nh = b.prototype; + a.prototype = new c; + a.prototype.constructor = a; + a.jh = function(a, c, f) { + for (var g = Array(arguments.length - 2), k = 2; k < arguments.length; k++) g[k - 2] = arguments[k]; + return b.prototype[c].apply(a, g) + } + }; + + function la(a) { + if (Error.captureStackTrace) Error.captureStackTrace(this, la); + else { + var b = Error().stack; + b && (this.stack = b) + } + a && (this.message = String(a)) + } + ka(la, Error); + la.prototype.name = "CustomError"; + + function v(a, b) { + for (var c in a) b.call(void 0, a[c], c, a) + } + + function ma(a, b) { + var c = {}, + d; + for (d in a) c[d] = b.call(void 0, a[d], d, a); + return c + } + + function na(a, b) { + for (var c in a) + if (!b.call(void 0, a[c], c, a)) return !1; + return !0 + } + + function oa(a) { + var b = 0, + c; + for (c in a) b++; + return b + } + + function pa(a) { + for (var b in a) return b + } + + function qa(a) { + var b = [], + c = 0, + d; + for (d in a) b[c++] = a[d]; + return b + } + + function ra(a) { + var b = [], + c = 0, + d; + for (d in a) b[c++] = d; + return b + } + + function sa(a, b) { + for (var c in a) + if (a[c] == b) return !0; + return !1 + } + + function ta(a, b, c) { + for (var d in a) + if (b.call(c, a[d], d, a)) return d + } + + function ua(a, b) { + var c = ta(a, b, void 0); + return c && a[c] + } + + function va(a) { + for (var b in a) return !1; + return !0 + } + + function wa(a) { + var b = {}, + c; + for (c in a) b[c] = a[c]; + return b + } + var xa = "constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "); + + function ya(a, b) { + for (var c, d, e = 1; e < arguments.length; e++) { + d = arguments[e]; + for (c in d) a[c] = d[c]; + for (var f = 0; f < xa.length; f++) c = xa[f], Object.prototype.hasOwnProperty.call(d, c) && (a[c] = d[c]) + } + }; + + function za(a) { + a = String(a); + if (/^\s*$/.test(a) ? 0 : /^[\],:{}\s\u2028\u2029]*$/.test(a.replace(/\\["\\\/bfnrtu]/g, "@").replace(/"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g, ""))) try { + return eval("(" + a + ")") + } catch (b) {} + throw Error("Invalid JSON string: " + a); + } + + function Aa() { + this.Vd = void 0 + } + + function Ba(a, b, c) { + switch (typeof b) { + case "string": + Ca(b, c); + break; + case "number": + c.push(isFinite(b) && !isNaN(b) ? b : "null"); + break; + case "boolean": + c.push(b); + break; + case "undefined": + c.push("null"); + break; + case "object": + if (null == b) { + c.push("null"); + break + } + if (da(b)) { + var d = b.length; + c.push("["); + for (var e = "", f = 0; f < d; f++) c.push(e), e = b[f], Ba(a, a.Vd ? a.Vd.call(b, String(f), e) : e, c), e = ","; + c.push("]"); + break + } + c.push("{"); + d = ""; + for (f in b) Object.prototype.hasOwnProperty.call(b, f) && (e = b[f], "function" != typeof e && (c.push(d), Ca(f, c), + c.push(":"), Ba(a, a.Vd ? a.Vd.call(b, f, e) : e, c), d = ",")); + c.push("}"); + break; + case "function": + break; + default: + throw Error("Unknown type: " + typeof b); + } + } + var Da = { + '"': '\\"', + "\\": "\\\\", + "/": "\\/", + "\b": "\\b", + "\f": "\\f", + "\n": "\\n", + "\r": "\\r", + "\t": "\\t", + "\x0B": "\\u000b" + }, + Ea = /\uffff/.test("\uffff") ? /[\\\"\x00-\x1f\x7f-\uffff]/g : /[\\\"\x00-\x1f\x7f-\xff]/g; + + function Ca(a, b) { + b.push('"', a.replace(Ea, function(a) { + if (a in Da) return Da[a]; + var b = a.charCodeAt(0), + e = "\\u"; + 16 > b ? e += "000" : 256 > b ? e += "00" : 4096 > b && (e += "0"); + return Da[a] = e + b.toString(16) + }), '"') + }; + + function Fa() { + return Math.floor(2147483648 * Math.random()).toString(36) + Math.abs(Math.floor(2147483648 * Math.random()) ^ ja()).toString(36) + }; + var w; + a: { + var Ga = n.navigator; + if (Ga) { + var Ha = Ga.userAgent; + if (Ha) { + w = Ha; + break a + } + } + w = "" + }; + + function Ia() { + this.Ya = -1 + }; + + function Ja() { + this.Ya = -1; + this.Ya = 64; + this.P = []; + this.pe = []; + this.eg = []; + this.Od = []; + this.Od[0] = 128; + for (var a = 1; a < this.Ya; ++a) this.Od[a] = 0; + this.ge = this.ec = 0; + this.reset() + } + ka(Ja, Ia); + Ja.prototype.reset = function() { + this.P[0] = 1732584193; + this.P[1] = 4023233417; + this.P[2] = 2562383102; + this.P[3] = 271733878; + this.P[4] = 3285377520; + this.ge = this.ec = 0 + }; + + function Ka(a, b, c) { + c || (c = 0); + var d = a.eg; + if (q(b)) + for (var e = 0; 16 > e; e++) d[e] = b.charCodeAt(c) << 24 | b.charCodeAt(c + 1) << 16 | b.charCodeAt(c + 2) << 8 | b.charCodeAt(c + 3), c += 4; + else + for (e = 0; 16 > e; e++) d[e] = b[c] << 24 | b[c + 1] << 16 | b[c + 2] << 8 | b[c + 3], c += 4; + for (e = 16; 80 > e; e++) { + var f = d[e - 3] ^ d[e - 8] ^ d[e - 14] ^ d[e - 16]; + d[e] = (f << 1 | f >>> 31) & 4294967295 + } + b = a.P[0]; + c = a.P[1]; + for (var g = a.P[2], k = a.P[3], m = a.P[4], l, e = 0; 80 > e; e++) 40 > e ? 20 > e ? (f = k ^ c & (g ^ k), l = 1518500249) : (f = c ^ g ^ k, l = 1859775393) : 60 > e ? (f = c & g | k & (c | g), l = 2400959708) : (f = c ^ g ^ k, l = 3395469782), f = (b << + 5 | b >>> 27) + f + m + l + d[e] & 4294967295, m = k, k = g, g = (c << 30 | c >>> 2) & 4294967295, c = b, b = f; + a.P[0] = a.P[0] + b & 4294967295; + a.P[1] = a.P[1] + c & 4294967295; + a.P[2] = a.P[2] + g & 4294967295; + a.P[3] = a.P[3] + k & 4294967295; + a.P[4] = a.P[4] + m & 4294967295 + } + Ja.prototype.update = function(a, b) { + if (null != a) { + p(b) || (b = a.length); + for (var c = b - this.Ya, d = 0, e = this.pe, f = this.ec; d < b;) { + if (0 == f) + for (; d <= c;) Ka(this, a, d), d += this.Ya; + if (q(a)) + for (; d < b;) { + if (e[f] = a.charCodeAt(d), ++f, ++d, f == this.Ya) { + Ka(this, e); + f = 0; + break + } + } else + for (; d < b;) + if (e[f] = a[d], ++f, ++d, f == this.Ya) { + Ka(this, e); + f = 0; + break + } + } + this.ec = f; + this.ge += b + } + }; + var x = Array.prototype, + La = x.indexOf ? function(a, b, c) { + return x.indexOf.call(a, b, c) + } : function(a, b, c) { + c = null == c ? 0 : 0 > c ? Math.max(0, a.length + c) : c; + if (q(a)) return q(b) && 1 == b.length ? a.indexOf(b, c) : -1; + for (; c < a.length; c++) + if (c in a && a[c] === b) return c; + return -1 + }, + Ma = x.forEach ? function(a, b, c) { + x.forEach.call(a, b, c) + } : function(a, b, c) { + for (var d = a.length, e = q(a) ? a.split("") : a, f = 0; f < d; f++) f in e && b.call(c, e[f], f, a) + }, + Na = x.filter ? function(a, b, c) { + return x.filter.call(a, b, c) + } : function(a, b, c) { + for (var d = a.length, e = [], f = 0, g = q(a) ? + a.split("") : a, k = 0; k < d; k++) + if (k in g) { + var m = g[k]; + b.call(c, m, k, a) && (e[f++] = m) + } + return e + }, + Oa = x.map ? function(a, b, c) { + return x.map.call(a, b, c) + } : function(a, b, c) { + for (var d = a.length, e = Array(d), f = q(a) ? a.split("") : a, g = 0; g < d; g++) g in f && (e[g] = b.call(c, f[g], g, a)); + return e + }, + Pa = x.reduce ? function(a, b, c, d) { + for (var e = [], f = 1, g = arguments.length; f < g; f++) e.push(arguments[f]); + d && (e[0] = u(b, d)); + return x.reduce.apply(a, e) + } : function(a, b, c, d) { + var e = c; + Ma(a, function(c, g) { + e = b.call(d, e, c, g, a) + }); + return e + }, + Qa = x.every ? function(a, b, + c) { + return x.every.call(a, b, c) + } : function(a, b, c) { + for (var d = a.length, e = q(a) ? a.split("") : a, f = 0; f < d; f++) + if (f in e && !b.call(c, e[f], f, a)) return !1; + return !0 + }; + + function Ra(a, b) { + var c = Sa(a, b, void 0); + return 0 > c ? null : q(a) ? a.charAt(c) : a[c] + } + + function Sa(a, b, c) { + for (var d = a.length, e = q(a) ? a.split("") : a, f = 0; f < d; f++) + if (f in e && b.call(c, e[f], f, a)) return f; + return -1 + } + + function Ta(a, b) { + var c = La(a, b); + 0 <= c && x.splice.call(a, c, 1) + } + + function Ua(a, b, c) { + return 2 >= arguments.length ? x.slice.call(a, b) : x.slice.call(a, b, c) + } + + function Va(a, b) { + a.sort(b || Wa) + } + + function Wa(a, b) { + return a > b ? 1 : a < b ? -1 : 0 + }; + + function Xa(a) { + n.setTimeout(function() { + throw a; + }, 0) + } + var Ya; + + function Za() { + var a = n.MessageChannel; + "undefined" === typeof a && "undefined" !== typeof window && window.postMessage && window.addEventListener && -1 == w.indexOf("Presto") && (a = function() { + var a = document.createElement("iframe"); + a.style.display = "none"; + a.src = ""; + document.documentElement.appendChild(a); + var b = a.contentWindow, + a = b.document; + a.open(); + a.write(""); + a.close(); + var c = "callImmediate" + Math.random(), + d = "file:" == b.location.protocol ? "*" : b.location.protocol + "//" + b.location.host, + a = u(function(a) { + if (("*" == d || a.origin == + d) && a.data == c) this.port1.onmessage() + }, this); + b.addEventListener("message", a, !1); + this.port1 = {}; + this.port2 = { + postMessage: function() { + b.postMessage(c, d) + } + } + }); + if ("undefined" !== typeof a && -1 == w.indexOf("Trident") && -1 == w.indexOf("MSIE")) { + var b = new a, + c = {}, + d = c; + b.port1.onmessage = function() { + if (p(c.next)) { + c = c.next; + var a = c.hb; + c.hb = null; + a() + } + }; + return function(a) { + d.next = { + hb: a + }; + d = d.next; + b.port2.postMessage(0) + } + } + return "undefined" !== typeof document && "onreadystatechange" in document.createElement("script") ? function(a) { + var b = + document.createElement("script"); + b.onreadystatechange = function() { + b.onreadystatechange = null; + b.parentNode.removeChild(b); + b = null; + a(); + a = null + }; + document.documentElement.appendChild(b) + } : function(a) { + n.setTimeout(a, 0) + } + }; + + function $a(a, b) { + ab || bb(); + cb || (ab(), cb = !0); + db.push(new eb(a, b)) + } + var ab; + + function bb() { + if (n.Promise && n.Promise.resolve) { + var a = n.Promise.resolve(); + ab = function() { + a.then(fb) + } + } else ab = function() { + var a = fb; + !r(n.setImmediate) || n.Window && n.Window.prototype && n.Window.prototype.setImmediate == n.setImmediate ? (Ya || (Ya = Za()), Ya(a)) : n.setImmediate(a) + } + } + var cb = !1, + db = []; + [].push(function() { + cb = !1; + db = [] + }); + + function fb() { + for (; db.length;) { + var a = db; + db = []; + for (var b = 0; b < a.length; b++) { + var c = a[b]; + try { + c.yg.call(c.scope) + } catch (d) { + Xa(d) + } + } + } + cb = !1 + } + + function eb(a, b) { + this.yg = a; + this.scope = b + }; + var gb = -1 != w.indexOf("Opera") || -1 != w.indexOf("OPR"), + hb = -1 != w.indexOf("Trident") || -1 != w.indexOf("MSIE"), + ib = -1 != w.indexOf("Gecko") && -1 == w.toLowerCase().indexOf("webkit") && !(-1 != w.indexOf("Trident") || -1 != w.indexOf("MSIE")), + jb = -1 != w.toLowerCase().indexOf("webkit"); + (function() { + var a = "", + b; + if (gb && n.opera) return a = n.opera.version, r(a) ? a() : a; + ib ? b = /rv\:([^\);]+)(\)|;)/ : hb ? b = /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/ : jb && (b = /WebKit\/(\S+)/); + b && (a = (a = b.exec(w)) ? a[1] : ""); + return hb && (b = (b = n.document) ? b.documentMode : void 0, b > parseFloat(a)) ? String(b) : a + })(); + var kb = null, + lb = null, + mb = null; + + function nb(a, b) { + if (!ea(a)) throw Error("encodeByteArray takes an array as a parameter"); + ob(); + for (var c = b ? lb : kb, d = [], e = 0; e < a.length; e += 3) { + var f = a[e], + g = e + 1 < a.length, + k = g ? a[e + 1] : 0, + m = e + 2 < a.length, + l = m ? a[e + 2] : 0, + t = f >> 2, + f = (f & 3) << 4 | k >> 4, + k = (k & 15) << 2 | l >> 6, + l = l & 63; + m || (l = 64, g || (k = 64)); + d.push(c[t], c[f], c[k], c[l]) + } + return d.join("") + } + + function ob() { + if (!kb) { + kb = {}; + lb = {}; + mb = {}; + for (var a = 0; 65 > a; a++) kb[a] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a), lb[a] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.".charAt(a), mb[lb[a]] = a, 62 <= a && (mb["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(a)] = a) + } + }; + + function pb(a, b) { + this.N = qb; + this.Rf = void 0; + this.Ba = this.Ha = null; + this.yd = this.ye = !1; + if (a == rb) sb(this, tb, b); + else try { + var c = this; + a.call(b, function(a) { + sb(c, tb, a) + }, function(a) { + if (!(a instanceof ub)) try { + if (a instanceof Error) throw a; + throw Error("Promise rejected."); + } catch (b) {} + sb(c, vb, a) + }) + } catch (d) { + sb(this, vb, d) + } + } + var qb = 0, + tb = 2, + vb = 3; + + function rb() {} + pb.prototype.then = function(a, b, c) { + return wb(this, r(a) ? a : null, r(b) ? b : null, c) + }; + pb.prototype.then = pb.prototype.then; + pb.prototype.$goog_Thenable = !0; + pb.prototype.cancel = function(a) { + this.N == qb && $a(function() { + var b = new ub(a); + xb(this, b) + }, this) + }; + + function xb(a, b) { + if (a.N == qb) + if (a.Ha) { + var c = a.Ha; + if (c.Ba) { + for (var d = 0, e = -1, f = 0, g; g = c.Ba[f]; f++) + if (g = g.o) + if (d++, g == a && (e = f), 0 <= e && 1 < d) break; + 0 <= e && (c.N == qb && 1 == d ? xb(c, b) : (d = c.Ba.splice(e, 1)[0], yb(c, d, vb, b))) + } + a.Ha = null + } else sb(a, vb, b) + } + + function zb(a, b) { + a.Ba && a.Ba.length || a.N != tb && a.N != vb || Ab(a); + a.Ba || (a.Ba = []); + a.Ba.push(b) + } + + function wb(a, b, c, d) { + var e = { + o: null, + Hf: null, + Jf: null + }; + e.o = new pb(function(a, g) { + e.Hf = b ? function(c) { + try { + var e = b.call(d, c); + a(e) + } catch (l) { + g(l) + } + } : a; + e.Jf = c ? function(b) { + try { + var e = c.call(d, b); + !p(e) && b instanceof ub ? g(b) : a(e) + } catch (l) { + g(l) + } + } : g + }); + e.o.Ha = a; + zb(a, e); + return e.o + } + pb.prototype.Yf = function(a) { + this.N = qb; + sb(this, tb, a) + }; + pb.prototype.Zf = function(a) { + this.N = qb; + sb(this, vb, a) + }; + + function sb(a, b, c) { + if (a.N == qb) { + if (a == c) b = vb, c = new TypeError("Promise cannot resolve to itself"); + else { + var d; + if (c) try { + d = !!c.$goog_Thenable + } catch (e) { + d = !1 + } else d = !1; + if (d) { + a.N = 1; + c.then(a.Yf, a.Zf, a); + return + } + if (ga(c)) try { + var f = c.then; + if (r(f)) { + Bb(a, c, f); + return + } + } catch (g) { + b = vb, c = g + } + } + a.Rf = c; + a.N = b; + a.Ha = null; + Ab(a); + b != vb || c instanceof ub || Cb(a, c) + } + } + + function Bb(a, b, c) { + function d(b) { + f || (f = !0, a.Zf(b)) + } + + function e(b) { + f || (f = !0, a.Yf(b)) + } + a.N = 1; + var f = !1; + try { + c.call(b, e, d) + } catch (g) { + d(g) + } + } + + function Ab(a) { + a.ye || (a.ye = !0, $a(a.wg, a)) + } + pb.prototype.wg = function() { + for (; this.Ba && this.Ba.length;) { + var a = this.Ba; + this.Ba = null; + for (var b = 0; b < a.length; b++) yb(this, a[b], this.N, this.Rf) + } + this.ye = !1 + }; + + function yb(a, b, c, d) { + if (c == tb) b.Hf(d); + else { + if (b.o) + for (; a && a.yd; a = a.Ha) a.yd = !1; + b.Jf(d) + } + } + + function Cb(a, b) { + a.yd = !0; + $a(function() { + a.yd && Db.call(null, b) + }) + } + var Db = Xa; + + function ub(a) { + la.call(this, a) + } + ka(ub, la); + ub.prototype.name = "cancel"; + var Eb = Eb || "2.4.0"; + + function y(a, b) { + return Object.prototype.hasOwnProperty.call(a, b) + } + + function z(a, b) { + if (Object.prototype.hasOwnProperty.call(a, b)) return a[b] + } + + function Fb(a, b) { + for (var c in a) Object.prototype.hasOwnProperty.call(a, c) && b(c, a[c]) + } + + function Gb(a) { + var b = {}; + Fb(a, function(a, d) { + b[a] = d + }); + return b + } + + function Hb(a) { + return "object" === typeof a && null !== a + }; + + function Ib(a) { + var b = []; + Fb(a, function(a, d) { + da(d) ? Ma(d, function(d) { + b.push(encodeURIComponent(a) + "=" + encodeURIComponent(d)) + }) : b.push(encodeURIComponent(a) + "=" + encodeURIComponent(d)) + }); + return b.length ? "&" + b.join("&") : "" + } + + function Jb(a) { + var b = {}; + a = a.replace(/^\?/, "").split("&"); + Ma(a, function(a) { + a && (a = a.split("="), b[a[0]] = a[1]) + }); + return b + }; + + function Kb(a, b) { + if (!a) throw Lb(b); + } + + function Lb(a) { + return Error("Firebase (" + Eb + ") INTERNAL ASSERT FAILED: " + a) + }; + var Mb = n.Promise || pb; + + function B() { + var a = this; + this.reject = this.resolve = null; + this.D = new Mb(function(b, c) { + a.resolve = b; + a.reject = c + }) + } + + function C(a, b) { + return function(c, d) { + c ? a.reject(c) : a.resolve(d); + r(b) && (Nb(a.D), 1 === b.length ? b(c) : b(c, d)) + } + } + + function Nb(a) { + a.then(void 0, aa) + }; + + function Ob(a) { + for (var b = [], c = 0, d = 0; d < a.length; d++) { + var e = a.charCodeAt(d); + 55296 <= e && 56319 >= e && (e -= 55296, d++, Kb(d < a.length, "Surrogate pair missing trail surrogate."), e = 65536 + (e << 10) + (a.charCodeAt(d) - 56320)); + 128 > e ? b[c++] = e : (2048 > e ? b[c++] = e >> 6 | 192 : (65536 > e ? b[c++] = e >> 12 | 224 : (b[c++] = e >> 18 | 240, b[c++] = e >> 12 & 63 | 128), b[c++] = e >> 6 & 63 | 128), b[c++] = e & 63 | 128) + } + return b + } + + function Pb(a) { + for (var b = 0, c = 0; c < a.length; c++) { + var d = a.charCodeAt(c); + 128 > d ? b++ : 2048 > d ? b += 2 : 55296 <= d && 56319 >= d ? (b += 4, c++) : b += 3 + } + return b + }; + + function D(a, b, c, d) { + var e; + d < b ? e = "at least " + b : d > c && (e = 0 === c ? "none" : "no more than " + c); + if (e) throw Error(a + " failed: Was called with " + d + (1 === d ? " argument." : " arguments.") + " Expects " + e + "."); + } + + function E(a, b, c) { + var d = ""; + switch (b) { + case 1: + d = c ? "first" : "First"; + break; + case 2: + d = c ? "second" : "Second"; + break; + case 3: + d = c ? "third" : "Third"; + break; + case 4: + d = c ? "fourth" : "Fourth"; + break; + default: + throw Error("errorPrefix called with argumentNumber > 4. Need to update it?"); + } + return a = a + " failed: " + (d + " argument ") + } + + function F(a, b, c, d) { + if ((!d || p(c)) && !r(c)) throw Error(E(a, b, d) + "must be a valid function."); + } + + function Qb(a, b, c) { + if (p(c) && (!ga(c) || null === c)) throw Error(E(a, b, !0) + "must be a valid context object."); + }; + + function Rb(a) { + return "undefined" !== typeof JSON && p(JSON.parse) ? JSON.parse(a) : za(a) + } + + function G(a) { + if ("undefined" !== typeof JSON && p(JSON.stringify)) a = JSON.stringify(a); + else { + var b = []; + Ba(new Aa, a, b); + a = b.join("") + } + return a + }; + + function Sb() { + this.Zd = H + } + Sb.prototype.j = function(a) { + return this.Zd.S(a) + }; + Sb.prototype.toString = function() { + return this.Zd.toString() + }; + + function Tb() {} + Tb.prototype.uf = function() { + return null + }; + Tb.prototype.Ce = function() { + return null + }; + var Ub = new Tb; + + function Vb(a, b, c) { + this.bg = a; + this.Oa = b; + this.Nd = c + } + Vb.prototype.uf = function(a) { + var b = this.Oa.Q; + if (Wb(b, a)) return b.j().T(a); + b = null != this.Nd ? new Xb(this.Nd, !0, !1) : this.Oa.w(); + return this.bg.Bc(a, b) + }; + Vb.prototype.Ce = function(a, b, c) { + var d = null != this.Nd ? this.Nd : Yb(this.Oa); + a = this.bg.qe(d, b, 1, c, a); + return 0 === a.length ? null : a[0] + }; + + function Zb() { + this.xb = [] + } + + function $b(a, b) { + for (var c = null, d = 0; d < b.length; d++) { + var e = b[d], + f = e.cc(); + null === c || f.ea(c.cc()) || (a.xb.push(c), c = null); + null === c && (c = new ac(f)); + c.add(e) + } + c && a.xb.push(c) + } + + function bc(a, b, c) { + $b(a, c); + cc(a, function(a) { + return a.ea(b) + }) + } + + function dc(a, b, c) { + $b(a, c); + cc(a, function(a) { + return a.contains(b) || b.contains(a) + }) + } + + function cc(a, b) { + for (var c = !0, d = 0; d < a.xb.length; d++) { + var e = a.xb[d]; + if (e) + if (e = e.cc(), b(e)) { + for (var e = a.xb[d], f = 0; f < e.xd.length; f++) { + var g = e.xd[f]; + if (null !== g) { + e.xd[f] = null; + var k = g.Zb(); + ec && fc("event: " + g.toString()); + gc(k) + } + } + a.xb[d] = null + } else c = !1 + } + c && (a.xb = []) + } + + function ac(a) { + this.ta = a; + this.xd = [] + } + ac.prototype.add = function(a) { + this.xd.push(a) + }; + ac.prototype.cc = function() { + return this.ta + }; + + function J(a, b, c, d) { + this.type = a; + this.Na = b; + this.Za = c; + this.Oe = d; + this.Td = void 0 + } + + function hc(a) { + return new J(ic, a) + } + var ic = "value"; + + function jc(a, b, c, d) { + this.xe = b; + this.be = c; + this.Td = d; + this.wd = a + } + jc.prototype.cc = function() { + var a = this.be.Mb(); + return "value" === this.wd ? a.path : a.parent().path + }; + jc.prototype.De = function() { + return this.wd + }; + jc.prototype.Zb = function() { + return this.xe.Zb(this) + }; + jc.prototype.toString = function() { + return this.cc().toString() + ":" + this.wd + ":" + G(this.be.qf()) + }; + + function kc(a, b, c) { + this.xe = a; + this.error = b; + this.path = c + } + kc.prototype.cc = function() { + return this.path + }; + kc.prototype.De = function() { + return "cancel" + }; + kc.prototype.Zb = function() { + return this.xe.Zb(this) + }; + kc.prototype.toString = function() { + return this.path.toString() + ":cancel" + }; + + function Xb(a, b, c) { + this.A = a; + this.ga = b; + this.Yb = c + } + + function lc(a) { + return a.ga + } + + function mc(a) { + return a.Yb + } + + function nc(a, b) { + return b.e() ? a.ga && !a.Yb : Wb(a, K(b)) + } + + function Wb(a, b) { + return a.ga && !a.Yb || a.A.Fa(b) + } + Xb.prototype.j = function() { + return this.A + }; + + function oc(a) { + this.pg = a; + this.Gd = null + } + oc.prototype.get = function() { + var a = this.pg.get(), + b = wa(a); + if (this.Gd) + for (var c in this.Gd) b[c] -= this.Gd[c]; + this.Gd = a; + return b + }; + + function pc(a, b) { + this.Vf = {}; + this.hd = new oc(a); + this.da = b; + var c = 1E4 + 2E4 * Math.random(); + setTimeout(u(this.Of, this), Math.floor(c)) + } + pc.prototype.Of = function() { + var a = this.hd.get(), + b = {}, + c = !1, + d; + for (d in a) 0 < a[d] && y(this.Vf, d) && (b[d] = a[d], c = !0); + c && this.da.Ye(b); + setTimeout(u(this.Of, this), Math.floor(6E5 * Math.random())) + }; + + function qc() { + this.Hc = {} + } + + function rc(a, b, c) { + p(c) || (c = 1); + y(a.Hc, b) || (a.Hc[b] = 0); + a.Hc[b] += c + } + qc.prototype.get = function() { + return wa(this.Hc) + }; + var sc = {}, + tc = {}; + + function uc(a) { + a = a.toString(); + sc[a] || (sc[a] = new qc); + return sc[a] + } + + function vc(a, b) { + var c = a.toString(); + tc[c] || (tc[c] = b()); + return tc[c] + }; + + function L(a, b) { + this.name = a; + this.U = b + } + + function wc(a, b) { + return new L(a, b) + }; + + function xc(a, b) { + return yc(a.name, b.name) + } + + function zc(a, b) { + return yc(a, b) + }; + + function Ac(a, b, c) { + this.type = Bc; + this.source = a; + this.path = b; + this.Ja = c + } + Ac.prototype.$c = function(a) { + return this.path.e() ? new Ac(this.source, M, this.Ja.T(a)) : new Ac(this.source, N(this.path), this.Ja) + }; + Ac.prototype.toString = function() { + return "Operation(" + this.path + ": " + this.source.toString() + " overwrite: " + this.Ja.toString() + ")" + }; + + function Cc(a, b) { + this.type = Dc; + this.source = a; + this.path = b + } + Cc.prototype.$c = function() { + return this.path.e() ? new Cc(this.source, M) : new Cc(this.source, N(this.path)) + }; + Cc.prototype.toString = function() { + return "Operation(" + this.path + ": " + this.source.toString() + " listen_complete)" + }; + + function Ec(a, b) { + this.Pa = a; + this.xa = b ? b : Fc + } + h = Ec.prototype; + h.Sa = function(a, b) { + return new Ec(this.Pa, this.xa.Sa(a, b, this.Pa).$(null, null, !1, null, null)) + }; + h.remove = function(a) { + return new Ec(this.Pa, this.xa.remove(a, this.Pa).$(null, null, !1, null, null)) + }; + h.get = function(a) { + for (var b, c = this.xa; !c.e();) { + b = this.Pa(a, c.key); + if (0 === b) return c.value; + 0 > b ? c = c.left : 0 < b && (c = c.right) + } + return null + }; + + function Gc(a, b) { + for (var c, d = a.xa, e = null; !d.e();) { + c = a.Pa(b, d.key); + if (0 === c) { + if (d.left.e()) return e ? e.key : null; + for (d = d.left; !d.right.e();) d = d.right; + return d.key + } + 0 > c ? d = d.left : 0 < c && (e = d, d = d.right) + } + throw Error("Attempted to find predecessor key for a nonexistent key. What gives?"); + } + h.e = function() { + return this.xa.e() + }; + h.count = function() { + return this.xa.count() + }; + h.Vc = function() { + return this.xa.Vc() + }; + h.jc = function() { + return this.xa.jc() + }; + h.ka = function(a) { + return this.xa.ka(a) + }; + h.ac = function(a) { + return new Hc(this.xa, null, this.Pa, !1, a) + }; + h.bc = function(a, b) { + return new Hc(this.xa, a, this.Pa, !1, b) + }; + h.dc = function(a, b) { + return new Hc(this.xa, a, this.Pa, !0, b) + }; + h.xf = function(a) { + return new Hc(this.xa, null, this.Pa, !0, a) + }; + + function Hc(a, b, c, d, e) { + this.Xd = e || null; + this.Je = d; + this.Ta = []; + for (e = 1; !a.e();) + if (e = b ? c(a.key, b) : 1, d && (e *= -1), 0 > e) a = this.Je ? a.left : a.right; + else if (0 === e) { + this.Ta.push(a); + break + } else this.Ta.push(a), a = this.Je ? a.right : a.left + } + + function Ic(a) { + if (0 === a.Ta.length) return null; + var b = a.Ta.pop(), + c; + c = a.Xd ? a.Xd(b.key, b.value) : { + key: b.key, + value: b.value + }; + if (a.Je) + for (b = b.left; !b.e();) a.Ta.push(b), b = b.right; + else + for (b = b.right; !b.e();) a.Ta.push(b), b = b.left; + return c + } + + function Jc(a) { + if (0 === a.Ta.length) return null; + var b; + b = a.Ta; + b = b[b.length - 1]; + return a.Xd ? a.Xd(b.key, b.value) : { + key: b.key, + value: b.value + } + } + + function Kc(a, b, c, d, e) { + this.key = a; + this.value = b; + this.color = null != c ? c : !0; + this.left = null != d ? d : Fc; + this.right = null != e ? e : Fc + } + h = Kc.prototype; + h.$ = function(a, b, c, d, e) { + return new Kc(null != a ? a : this.key, null != b ? b : this.value, null != c ? c : this.color, null != d ? d : this.left, null != e ? e : this.right) + }; + h.count = function() { + return this.left.count() + 1 + this.right.count() + }; + h.e = function() { + return !1 + }; + h.ka = function(a) { + return this.left.ka(a) || a(this.key, this.value) || this.right.ka(a) + }; + + function Lc(a) { + return a.left.e() ? a : Lc(a.left) + } + h.Vc = function() { + return Lc(this).key + }; + h.jc = function() { + return this.right.e() ? this.key : this.right.jc() + }; + h.Sa = function(a, b, c) { + var d, e; + e = this; + d = c(a, e.key); + e = 0 > d ? e.$(null, null, null, e.left.Sa(a, b, c), null) : 0 === d ? e.$(null, b, null, null, null) : e.$(null, null, null, null, e.right.Sa(a, b, c)); + return Mc(e) + }; + + function Nc(a) { + if (a.left.e()) return Fc; + a.left.ha() || a.left.left.ha() || (a = Oc(a)); + a = a.$(null, null, null, Nc(a.left), null); + return Mc(a) + } + h.remove = function(a, b) { + var c, d; + c = this; + if (0 > b(a, c.key)) c.left.e() || c.left.ha() || c.left.left.ha() || (c = Oc(c)), c = c.$(null, null, null, c.left.remove(a, b), null); + else { + c.left.ha() && (c = Pc(c)); + c.right.e() || c.right.ha() || c.right.left.ha() || (c = Qc(c), c.left.left.ha() && (c = Pc(c), c = Qc(c))); + if (0 === b(a, c.key)) { + if (c.right.e()) return Fc; + d = Lc(c.right); + c = c.$(d.key, d.value, null, null, Nc(c.right)) + } + c = c.$(null, null, null, null, c.right.remove(a, b)) + } + return Mc(c) + }; + h.ha = function() { + return this.color + }; + + function Mc(a) { + a.right.ha() && !a.left.ha() && (a = Rc(a)); + a.left.ha() && a.left.left.ha() && (a = Pc(a)); + a.left.ha() && a.right.ha() && (a = Qc(a)); + return a + } + + function Oc(a) { + a = Qc(a); + a.right.left.ha() && (a = a.$(null, null, null, null, Pc(a.right)), a = Rc(a), a = Qc(a)); + return a + } + + function Rc(a) { + return a.right.$(null, null, a.color, a.$(null, null, !0, null, a.right.left), null) + } + + function Pc(a) { + return a.left.$(null, null, a.color, null, a.$(null, null, !0, a.left.right, null)) + } + + function Qc(a) { + return a.$(null, null, !a.color, a.left.$(null, null, !a.left.color, null, null), a.right.$(null, null, !a.right.color, null, null)) + } + + function Sc() {} + h = Sc.prototype; + h.$ = function() { + return this + }; + h.Sa = function(a, b) { + return new Kc(a, b, null) + }; + h.remove = function() { + return this + }; + h.count = function() { + return 0 + }; + h.e = function() { + return !0 + }; + h.ka = function() { + return !1 + }; + h.Vc = function() { + return null + }; + h.jc = function() { + return null + }; + h.ha = function() { + return !1 + }; + var Fc = new Sc; + + function Tc(a, b) { + return a && "object" === typeof a ? (O(".sv" in a, "Unexpected leaf node or priority contents"), b[a[".sv"]]) : a + } + + function Uc(a, b) { + var c = new Vc; + Wc(a, new P(""), function(a, e) { + c.rc(a, Xc(e, b)) + }); + return c + } + + function Xc(a, b) { + var c = a.C().J(), + c = Tc(c, b), + d; + if (a.L()) { + var e = Tc(a.Ea(), b); + return e !== a.Ea() || c !== a.C().J() ? new Yc(e, Q(c)) : a + } + d = a; + c !== a.C().J() && (d = d.ia(new Yc(c))); + a.R(R, function(a, c) { + var e = Xc(c, b); + e !== c && (d = d.W(a, e)) + }); + return d + }; + + function Zc() { + this.Ac = {} + } + Zc.prototype.set = function(a, b) { + null == b ? delete this.Ac[a] : this.Ac[a] = b + }; + Zc.prototype.get = function(a) { + return y(this.Ac, a) ? this.Ac[a] : null + }; + Zc.prototype.remove = function(a) { + delete this.Ac[a] + }; + Zc.prototype.Af = !0; + + function $c(a) { + this.Ic = a; + this.Sd = "firebase:" + } + h = $c.prototype; + h.set = function(a, b) { + null == b ? this.Ic.removeItem(this.Sd + a) : this.Ic.setItem(this.Sd + a, G(b)) + }; + h.get = function(a) { + a = this.Ic.getItem(this.Sd + a); + return null == a ? null : Rb(a) + }; + h.remove = function(a) { + this.Ic.removeItem(this.Sd + a) + }; + h.Af = !1; + h.toString = function() { + return this.Ic.toString() + }; + + function ad(a) { + try { + if ("undefined" !== typeof window && "undefined" !== typeof window[a]) { + var b = window[a]; + b.setItem("firebase:sentinel", "cache"); + b.removeItem("firebase:sentinel"); + return new $c(b) + } + } catch (c) {} + return new Zc + } + var bd = ad("localStorage"), + cd = ad("sessionStorage"); + + function dd(a, b, c, d, e) { + this.host = a.toLowerCase(); + this.domain = this.host.substr(this.host.indexOf(".") + 1); + this.ob = b; + this.lc = c; + this.hh = d; + this.Rd = e || ""; + this.ab = bd.get("host:" + a) || this.host + } + + function ed(a, b) { + b !== a.ab && (a.ab = b, "s-" === a.ab.substr(0, 2) && bd.set("host:" + a.host, a.ab)) + } + + function fd(a, b, c) { + O("string" === typeof b, "typeof type must == string"); + O("object" === typeof c, "typeof params must == object"); + if (b === gd) b = (a.ob ? "wss://" : "ws://") + a.ab + "/.ws?"; + else if (b === hd) b = (a.ob ? "https://" : "http://") + a.ab + "/.lp?"; + else throw Error("Unknown connection type: " + b); + a.host !== a.ab && (c.ns = a.lc); + var d = []; + v(c, function(a, b) { + d.push(b + "=" + a) + }); + return b + d.join("&") + } + dd.prototype.toString = function() { + var a = (this.ob ? "https://" : "http://") + this.host; + this.Rd && (a += "<" + this.Rd + ">"); + return a + }; + var id = function() { + var a = 1; + return function() { + return a++ + } + }(), + O = Kb, + jd = Lb; + + function kd(a) { + try { + var b; + if ("undefined" !== typeof atob) b = atob(a); + else { + ob(); + for (var c = mb, d = [], e = 0; e < a.length;) { + var f = c[a.charAt(e++)], + g = e < a.length ? c[a.charAt(e)] : 0; + ++e; + var k = e < a.length ? c[a.charAt(e)] : 64; + ++e; + var m = e < a.length ? c[a.charAt(e)] : 64; + ++e; + if (null == f || null == g || null == k || null == m) throw Error(); + d.push(f << 2 | g >> 4); + 64 != k && (d.push(g << 4 & 240 | k >> 2), 64 != m && d.push(k << 6 & 192 | m)) + } + if (8192 > d.length) b = String.fromCharCode.apply(null, d); + else { + a = ""; + for (c = 0; c < d.length; c += 8192) a += String.fromCharCode.apply(null, Ua(d, c, + c + 8192)); + b = a + } + } + return b + } catch (l) { + fc("base64Decode failed: ", l) + } + return null + } + + function ld(a) { + var b = Ob(a); + a = new Ja; + a.update(b); + var b = [], + c = 8 * a.ge; + 56 > a.ec ? a.update(a.Od, 56 - a.ec) : a.update(a.Od, a.Ya - (a.ec - 56)); + for (var d = a.Ya - 1; 56 <= d; d--) a.pe[d] = c & 255, c /= 256; + Ka(a, a.pe); + for (d = c = 0; 5 > d; d++) + for (var e = 24; 0 <= e; e -= 8) b[c] = a.P[d] >> e & 255, ++c; + return nb(b) + } + + function md(a) { + for (var b = "", c = 0; c < arguments.length; c++) b = ea(arguments[c]) ? b + md.apply(null, arguments[c]) : "object" === typeof arguments[c] ? b + G(arguments[c]) : b + arguments[c], b += " "; + return b + } + var ec = null, + nd = !0; + + function od(a, b) { + Kb(!b || !0 === a || !1 === a, "Can't turn on custom loggers persistently."); + !0 === a ? ("undefined" !== typeof console && ("function" === typeof console.log ? ec = u(console.log, console) : "object" === typeof console.log && (ec = function(a) { + console.log(a) + })), b && cd.set("logging_enabled", !0)) : r(a) ? ec = a : (ec = null, cd.remove("logging_enabled")) + } + + function fc(a) { + !0 === nd && (nd = !1, null === ec && !0 === cd.get("logging_enabled") && od(!0)); + if (ec) { + var b = md.apply(null, arguments); + ec(b) + } + } + + function pd(a) { + return function() { + fc(a, arguments) + } + } + + function qd(a) { + if ("undefined" !== typeof console) { + var b = "FIREBASE INTERNAL ERROR: " + md.apply(null, arguments); + "undefined" !== typeof console.error ? console.error(b) : console.log(b) + } + } + + function rd(a) { + var b = md.apply(null, arguments); + throw Error("FIREBASE FATAL ERROR: " + b); + } + + function S(a) { + if ("undefined" !== typeof console) { + var b = "FIREBASE WARNING: " + md.apply(null, arguments); + "undefined" !== typeof console.warn ? console.warn(b) : console.log(b) + } + } + + function sd(a) { + var b = "", + c = "", + d = "", + e = "", + f = !0, + g = "https", + k = 443; + if (q(a)) { + var m = a.indexOf("//"); + 0 <= m && (g = a.substring(0, m - 1), a = a.substring(m + 2)); + m = a.indexOf("/"); - 1 === m && (m = a.length); + b = a.substring(0, m); + e = ""; + a = a.substring(m).split("/"); + for (m = 0; m < a.length; m++) + if (0 < a[m].length) { + var l = a[m]; + try { + l = decodeURIComponent(l.replace(/\+/g, " ")) + } catch (t) {} + e += "/" + l + } + a = b.split("."); + 3 === a.length ? (c = a[1], d = a[0].toLowerCase()) : 2 === a.length && (c = a[0]); + m = b.indexOf(":"); + 0 <= m && (f = "https" === g || "wss" === g, k = b.substring(m + 1), isFinite(k) && + (k = String(k)), k = q(k) ? /^\s*-?0x/i.test(k) ? parseInt(k, 16) : parseInt(k, 10) : NaN) + } + return { + host: b, + port: k, + domain: c, + eh: d, + ob: f, + scheme: g, + bd: e + } + } + + function td(a) { + return fa(a) && (a != a || a == Number.POSITIVE_INFINITY || a == Number.NEGATIVE_INFINITY) + } + + function ud(a) { + if ("complete" === document.readyState) a(); + else { + var b = !1, + c = function() { + document.body ? b || (b = !0, a()) : setTimeout(c, Math.floor(10)) + }; + document.addEventListener ? (document.addEventListener("DOMContentLoaded", c, !1), window.addEventListener("load", c, !1)) : document.attachEvent && (document.attachEvent("onreadystatechange", function() { + "complete" === document.readyState && c() + }), window.attachEvent("onload", c)) + } + } + + function yc(a, b) { + if (a === b) return 0; + if ("[MIN_NAME]" === a || "[MAX_NAME]" === b) return -1; + if ("[MIN_NAME]" === b || "[MAX_NAME]" === a) return 1; + var c = vd(a), + d = vd(b); + return null !== c ? null !== d ? 0 == c - d ? a.length - b.length : c - d : -1 : null !== d ? 1 : a < b ? -1 : 1 + } + + function wd(a, b) { + if (b && a in b) return b[a]; + throw Error("Missing required key (" + a + ") in object: " + G(b)); + } + + function xd(a) { + if ("object" !== typeof a || null === a) return G(a); + var b = [], + c; + for (c in a) b.push(c); + b.sort(); + c = "{"; + for (var d = 0; d < b.length; d++) 0 !== d && (c += ","), c += G(b[d]), c += ":", c += xd(a[b[d]]); + return c + "}" + } + + function yd(a, b) { + if (a.length <= b) return [a]; + for (var c = [], d = 0; d < a.length; d += b) d + b > a ? c.push(a.substring(d, a.length)) : c.push(a.substring(d, d + b)); + return c + } + + function zd(a, b) { + if (da(a)) + for (var c = 0; c < a.length; ++c) b(c, a[c]); + else v(a, b) + } + + function Ad(a) { + O(!td(a), "Invalid JSON number"); + var b, c, d, e; + 0 === a ? (d = c = 0, b = -Infinity === 1 / a ? 1 : 0) : (b = 0 > a, a = Math.abs(a), a >= Math.pow(2, -1022) ? (d = Math.min(Math.floor(Math.log(a) / Math.LN2), 1023), c = d + 1023, d = Math.round(a * Math.pow(2, 52 - d) - Math.pow(2, 52))) : (c = 0, d = Math.round(a / Math.pow(2, -1074)))); + e = []; + for (a = 52; a; --a) e.push(d % 2 ? 1 : 0), d = Math.floor(d / 2); + for (a = 11; a; --a) e.push(c % 2 ? 1 : 0), c = Math.floor(c / 2); + e.push(b ? 1 : 0); + e.reverse(); + b = e.join(""); + c = ""; + for (a = 0; 64 > a; a += 8) d = parseInt(b.substr(a, 8), 2).toString(16), 1 === d.length && + (d = "0" + d), c += d; + return c.toLowerCase() + } + var Bd = /^-?\d{1,10}$/; + + function vd(a) { + return Bd.test(a) && (a = Number(a), -2147483648 <= a && 2147483647 >= a) ? a : null + } + + function gc(a) { + try { + a() + } catch (b) { + setTimeout(function() { + S("Exception was thrown by user callback.", b.stack || ""); + throw b; + }, Math.floor(0)) + } + } + + function T(a, b) { + if (r(a)) { + var c = Array.prototype.slice.call(arguments, 1).slice(); + gc(function() { + a.apply(null, c) + }) + } + }; + + function Cd(a) { + var b = {}, + c = {}, + d = {}, + e = ""; + try { + var f = a.split("."), + b = Rb(kd(f[0]) || ""), + c = Rb(kd(f[1]) || ""), + e = f[2], + d = c.d || {}; + delete c.d + } catch (g) {} + return { + kh: b, + Ec: c, + data: d, + ah: e + } + } + + function Dd(a) { + a = Cd(a).Ec; + return "object" === typeof a && a.hasOwnProperty("iat") ? z(a, "iat") : null + } + + function Ed(a) { + a = Cd(a); + var b = a.Ec; + return !!a.ah && !!b && "object" === typeof b && b.hasOwnProperty("iat") + }; + + function Fd(a) { + this.Y = a; + this.g = a.n.g + } + + function Gd(a, b, c, d) { + var e = [], + f = []; + Ma(b, function(b) { + "child_changed" === b.type && a.g.Dd(b.Oe, b.Na) && f.push(new J("child_moved", b.Na, b.Za)) + }); + Hd(a, e, "child_removed", b, d, c); + Hd(a, e, "child_added", b, d, c); + Hd(a, e, "child_moved", f, d, c); + Hd(a, e, "child_changed", b, d, c); + Hd(a, e, ic, b, d, c); + return e + } + + function Hd(a, b, c, d, e, f) { + d = Na(d, function(a) { + return a.type === c + }); + Va(d, u(a.qg, a)); + Ma(d, function(c) { + var d = Id(a, c, f); + Ma(e, function(e) { + e.Qf(c.type) && b.push(e.createEvent(d, a.Y)) + }) + }) + } + + function Id(a, b, c) { + "value" !== b.type && "child_removed" !== b.type && (b.Td = c.wf(b.Za, b.Na, a.g)); + return b + } + Fd.prototype.qg = function(a, b) { + if (null == a.Za || null == b.Za) throw jd("Should only compare child_ events."); + return this.g.compare(new L(a.Za, a.Na), new L(b.Za, b.Na)) + }; + + function Jd() { + this.ib = {} + } + + function Kd(a, b) { + var c = b.type, + d = b.Za; + O("child_added" == c || "child_changed" == c || "child_removed" == c, "Only child changes supported for tracking"); + O(".priority" !== d, "Only non-priority child changes can be tracked."); + var e = z(a.ib, d); + if (e) { + var f = e.type; + if ("child_added" == c && "child_removed" == f) a.ib[d] = new J("child_changed", b.Na, d, e.Na); + else if ("child_removed" == c && "child_added" == f) delete a.ib[d]; + else if ("child_removed" == c && "child_changed" == f) a.ib[d] = new J("child_removed", e.Oe, d); + else if ("child_changed" == c && + "child_added" == f) a.ib[d] = new J("child_added", b.Na, d); + else if ("child_changed" == c && "child_changed" == f) a.ib[d] = new J("child_changed", b.Na, d, e.Oe); + else throw jd("Illegal combination of changes: " + b + " occurred after " + e); + } else a.ib[d] = b + }; + + function Ld(a) { + this.g = a + } + h = Ld.prototype; + h.H = function(a, b, c, d, e, f) { + O(a.Mc(this.g), "A node must be indexed if only a child is updated"); + e = a.T(b); + if (e.S(d).ea(c.S(d)) && e.e() == c.e()) return a; + null != f && (c.e() ? a.Fa(b) ? Kd(f, new J("child_removed", e, b)) : O(a.L(), "A child remove without an old child only makes sense on a leaf node") : e.e() ? Kd(f, new J("child_added", c, b)) : Kd(f, new J("child_changed", c, b, e))); + return a.L() && c.e() ? a : a.W(b, c).pb(this.g) + }; + h.ya = function(a, b, c) { + null != c && (a.L() || a.R(R, function(a, e) { + b.Fa(a) || Kd(c, new J("child_removed", e, a)) + }), b.L() || b.R(R, function(b, e) { + if (a.Fa(b)) { + var f = a.T(b); + f.ea(e) || Kd(c, new J("child_changed", e, b, f)) + } else Kd(c, new J("child_added", e, b)) + })); + return b.pb(this.g) + }; + h.ia = function(a, b) { + return a.e() ? H : a.ia(b) + }; + h.Ra = function() { + return !1 + }; + h.$b = function() { + return this + }; + + function Md(a) { + this.Fe = new Ld(a.g); + this.g = a.g; + var b; + a.oa ? (b = Nd(a), b = a.g.Sc(Od(a), b)) : b = a.g.Wc(); + this.gd = b; + a.ra ? (b = Pd(a), a = a.g.Sc(Rd(a), b)) : a = a.g.Tc(); + this.Jc = a + } + h = Md.prototype; + h.matches = function(a) { + return 0 >= this.g.compare(this.gd, a) && 0 >= this.g.compare(a, this.Jc) + }; + h.H = function(a, b, c, d, e, f) { + this.matches(new L(b, c)) || (c = H); + return this.Fe.H(a, b, c, d, e, f) + }; + h.ya = function(a, b, c) { + b.L() && (b = H); + var d = b.pb(this.g), + d = d.ia(H), + e = this; + b.R(R, function(a, b) { + e.matches(new L(a, b)) || (d = d.W(a, H)) + }); + return this.Fe.ya(a, d, c) + }; + h.ia = function(a) { + return a + }; + h.Ra = function() { + return !0 + }; + h.$b = function() { + return this.Fe + }; + + function Sd(a) { + this.ua = new Md(a); + this.g = a.g; + O(a.la, "Only valid if limit has been set"); + this.ma = a.ma; + this.Nb = !Td(a) + } + h = Sd.prototype; + h.H = function(a, b, c, d, e, f) { + this.ua.matches(new L(b, c)) || (c = H); + return a.T(b).ea(c) ? a : a.Hb() < this.ma ? this.ua.$b().H(a, b, c, d, e, f) : Ud(this, a, b, c, e, f) + }; + h.ya = function(a, b, c) { + var d; + if (b.L() || b.e()) d = H.pb(this.g); + else if (2 * this.ma < b.Hb() && b.Mc(this.g)) { + d = H.pb(this.g); + b = this.Nb ? b.dc(this.ua.Jc, this.g) : b.bc(this.ua.gd, this.g); + for (var e = 0; 0 < b.Ta.length && e < this.ma;) { + var f = Ic(b), + g; + if (g = this.Nb ? 0 >= this.g.compare(this.ua.gd, f) : 0 >= this.g.compare(f, this.ua.Jc)) d = d.W(f.name, f.U), e++; + else break + } + } else { + d = b.pb(this.g); + d = d.ia(H); + var k, m, l; + if (this.Nb) { + b = d.xf(this.g); + k = this.ua.Jc; + m = this.ua.gd; + var t = Vd(this.g); + l = function(a, b) { + return t(b, a) + } + } else b = d.ac(this.g), k = this.ua.gd, + m = this.ua.Jc, l = Vd(this.g); + for (var e = 0, A = !1; 0 < b.Ta.length;) f = Ic(b), !A && 0 >= l(k, f) && (A = !0), (g = A && e < this.ma && 0 >= l(f, m)) ? e++ : d = d.W(f.name, H) + } + return this.ua.$b().ya(a, d, c) + }; + h.ia = function(a) { + return a + }; + h.Ra = function() { + return !0 + }; + h.$b = function() { + return this.ua.$b() + }; + + function Ud(a, b, c, d, e, f) { + var g; + if (a.Nb) { + var k = Vd(a.g); + g = function(a, b) { + return k(b, a) + } + } else g = Vd(a.g); + O(b.Hb() == a.ma, ""); + var m = new L(c, d), + l = a.Nb ? Wd(b, a.g) : Xd(b, a.g), + t = a.ua.matches(m); + if (b.Fa(c)) { + for (var A = b.T(c), l = e.Ce(a.g, l, a.Nb); null != l && (l.name == c || b.Fa(l.name));) l = e.Ce(a.g, l, a.Nb); + e = null == l ? 1 : g(l, m); + if (t && !d.e() && 0 <= e) return null != f && Kd(f, new J("child_changed", d, c, A)), b.W(c, d); + null != f && Kd(f, new J("child_removed", A, c)); + b = b.W(c, H); + return null != l && a.ua.matches(l) ? (null != f && Kd(f, new J("child_added", + l.U, l.name)), b.W(l.name, l.U)) : b + } + return d.e() ? b : t && 0 <= g(l, m) ? (null != f && (Kd(f, new J("child_removed", l.U, l.name)), Kd(f, new J("child_added", d, c))), b.W(c, d).W(l.name, H)) : b + }; + + function Yd(a, b) { + this.me = a; + this.og = b + } + + function Zd(a) { + this.X = a + } + Zd.prototype.gb = function(a, b, c, d) { + var e = new Jd, + f; + if (b.type === Bc) b.source.Ae ? c = $d(this, a, b.path, b.Ja, c, d, e) : (O(b.source.tf, "Unknown source."), f = b.source.ef || mc(a.w()) && !b.path.e(), c = ae(this, a, b.path, b.Ja, c, d, f, e)); + else if (b.type === be) b.source.Ae ? c = ce(this, a, b.path, b.children, c, d, e) : (O(b.source.tf, "Unknown source."), f = b.source.ef || mc(a.w()), c = de(this, a, b.path, b.children, c, d, f, e)); + else if (b.type === ee) + if (b.Yd) + if (b = b.path, null != c.xc(b)) c = a; + else { + f = new Vb(c, a, d); + d = a.Q.j(); + if (b.e() || ".priority" === K(b)) lc(a.w()) ? + b = c.Aa(Yb(a)) : (b = a.w().j(), O(b instanceof fe, "serverChildren would be complete if leaf node"), b = c.Cc(b)), b = this.X.ya(d, b, e); + else { + var g = K(b), + k = c.Bc(g, a.w()); + null == k && Wb(a.w(), g) && (k = d.T(g)); + b = null != k ? this.X.H(d, g, k, N(b), f, e) : a.Q.j().Fa(g) ? this.X.H(d, g, H, N(b), f, e) : d; + b.e() && lc(a.w()) && (d = c.Aa(Yb(a)), d.L() && (b = this.X.ya(b, d, e))) + } + d = lc(a.w()) || null != c.xc(M); + c = ge(a, b, d, this.X.Ra()) + } else c = he(this, a, b.path, b.Ub, c, d, e); + else if (b.type === Dc) d = b.path, b = a.w(), f = b.j(), g = b.ga || d.e(), c = ie(this, new je(a.Q, new Xb(f, + g, b.Yb)), d, c, Ub, e); + else throw jd("Unknown operation type: " + b.type); + e = qa(e.ib); + d = c; + b = d.Q; + b.ga && (f = b.j().L() || b.j().e(), g = ke(a), (0 < e.length || !a.Q.ga || f && !b.j().ea(g) || !b.j().C().ea(g.C())) && e.push(hc(ke(d)))); + return new Yd(c, e) + }; + + function ie(a, b, c, d, e, f) { + var g = b.Q; + if (null != d.xc(c)) return b; + var k; + if (c.e()) O(lc(b.w()), "If change path is empty, we must have complete server data"), mc(b.w()) ? (e = Yb(b), d = d.Cc(e instanceof fe ? e : H)) : d = d.Aa(Yb(b)), f = a.X.ya(b.Q.j(), d, f); + else { + var m = K(c); + if (".priority" == m) O(1 == le(c), "Can't have a priority with additional path components"), f = g.j(), k = b.w().j(), d = d.nd(c, f, k), f = null != d ? a.X.ia(f, d) : g.j(); + else { + var l = N(c); + Wb(g, m) ? (k = b.w().j(), d = d.nd(c, g.j(), k), d = null != d ? g.j().T(m).H(l, d) : g.j().T(m)) : d = d.Bc(m, + b.w()); + f = null != d ? a.X.H(g.j(), m, d, l, e, f) : g.j() + } + } + return ge(b, f, g.ga || c.e(), a.X.Ra()) + } + + function ae(a, b, c, d, e, f, g, k) { + var m = b.w(); + g = g ? a.X : a.X.$b(); + if (c.e()) d = g.ya(m.j(), d, null); + else if (g.Ra() && !m.Yb) d = m.j().H(c, d), d = g.ya(m.j(), d, null); + else { + var l = K(c); + if (!nc(m, c) && 1 < le(c)) return b; + var t = N(c); + d = m.j().T(l).H(t, d); + d = ".priority" == l ? g.ia(m.j(), d) : g.H(m.j(), l, d, t, Ub, null) + } + m = m.ga || c.e(); + b = new je(b.Q, new Xb(d, m, g.Ra())); + return ie(a, b, c, e, new Vb(e, b, f), k) + } + + function $d(a, b, c, d, e, f, g) { + var k = b.Q; + e = new Vb(e, b, f); + if (c.e()) g = a.X.ya(b.Q.j(), d, g), a = ge(b, g, !0, a.X.Ra()); + else if (f = K(c), ".priority" === f) g = a.X.ia(b.Q.j(), d), a = ge(b, g, k.ga, k.Yb); + else { + c = N(c); + var m = k.j().T(f); + if (!c.e()) { + var l = e.uf(f); + d = null != l ? ".priority" === me(c) && l.S(c.parent()).e() ? l : l.H(c, d) : H + } + m.ea(d) ? a = b : (g = a.X.H(k.j(), f, d, c, e, g), a = ge(b, g, k.ga, a.X.Ra())) + } + return a + } + + function ce(a, b, c, d, e, f, g) { + var k = b; + ne(d, function(d, l) { + var t = c.o(d); + Wb(b.Q, K(t)) && (k = $d(a, k, t, l, e, f, g)) + }); + ne(d, function(d, l) { + var t = c.o(d); + Wb(b.Q, K(t)) || (k = $d(a, k, t, l, e, f, g)) + }); + return k + } + + function oe(a, b) { + ne(b, function(b, d) { + a = a.H(b, d) + }); + return a + } + + function de(a, b, c, d, e, f, g, k) { + if (b.w().j().e() && !lc(b.w())) return b; + var m = b; + c = c.e() ? d : pe(qe, c, d); + var l = b.w().j(); + c.children.ka(function(c, d) { + if (l.Fa(c)) { + var I = b.w().j().T(c), + I = oe(I, d); + m = ae(a, m, new P(c), I, e, f, g, k) + } + }); + c.children.ka(function(c, d) { + var I = !Wb(b.w(), c) && null == d.value; + l.Fa(c) || I || (I = b.w().j().T(c), I = oe(I, d), m = ae(a, m, new P(c), I, e, f, g, k)) + }); + return m + } + + function he(a, b, c, d, e, f, g) { + if (null != e.xc(c)) return b; + var k = mc(b.w()), + m = b.w(); + if (null != d.value) { + if (c.e() && m.ga || nc(m, c)) return ae(a, b, c, m.j().S(c), e, f, k, g); + if (c.e()) { + var l = qe; + m.j().R(re, function(a, b) { + l = l.set(new P(a), b) + }); + return de(a, b, c, l, e, f, k, g) + } + return b + } + l = qe; + ne(d, function(a) { + var b = c.o(a); + nc(m, b) && (l = l.set(a, m.j().S(b))) + }); + return de(a, b, c, l, e, f, k, g) + }; + + function se() {} + var te = {}; + + function Vd(a) { + return u(a.compare, a) + } + se.prototype.Dd = function(a, b) { + return 0 !== this.compare(new L("[MIN_NAME]", a), new L("[MIN_NAME]", b)) + }; + se.prototype.Wc = function() { + return ue + }; + + function ve(a) { + O(!a.e() && ".priority" !== K(a), "Can't create PathIndex with empty path or .priority key"); + this.gc = a + } + ka(ve, se); + h = ve.prototype; + h.Lc = function(a) { + return !a.S(this.gc).e() + }; + h.compare = function(a, b) { + var c = a.U.S(this.gc), + d = b.U.S(this.gc), + c = c.Gc(d); + return 0 === c ? yc(a.name, b.name) : c + }; + h.Sc = function(a, b) { + var c = Q(a), + c = H.H(this.gc, c); + return new L(b, c) + }; + h.Tc = function() { + var a = H.H(this.gc, we); + return new L("[MAX_NAME]", a) + }; + h.toString = function() { + return this.gc.slice().join("/") + }; + + function xe() {} + ka(xe, se); + h = xe.prototype; + h.compare = function(a, b) { + var c = a.U.C(), + d = b.U.C(), + c = c.Gc(d); + return 0 === c ? yc(a.name, b.name) : c + }; + h.Lc = function(a) { + return !a.C().e() + }; + h.Dd = function(a, b) { + return !a.C().ea(b.C()) + }; + h.Wc = function() { + return ue + }; + h.Tc = function() { + return new L("[MAX_NAME]", new Yc("[PRIORITY-POST]", we)) + }; + h.Sc = function(a, b) { + var c = Q(a); + return new L(b, new Yc("[PRIORITY-POST]", c)) + }; + h.toString = function() { + return ".priority" + }; + var R = new xe; + + function ye() {} + ka(ye, se); + h = ye.prototype; + h.compare = function(a, b) { + return yc(a.name, b.name) + }; + h.Lc = function() { + throw jd("KeyIndex.isDefinedOn not expected to be called."); + }; + h.Dd = function() { + return !1 + }; + h.Wc = function() { + return ue + }; + h.Tc = function() { + return new L("[MAX_NAME]", H) + }; + h.Sc = function(a) { + O(q(a), "KeyIndex indexValue must always be a string."); + return new L(a, H) + }; + h.toString = function() { + return ".key" + }; + var re = new ye; + + function ze() {} + ka(ze, se); + h = ze.prototype; + h.compare = function(a, b) { + var c = a.U.Gc(b.U); + return 0 === c ? yc(a.name, b.name) : c + }; + h.Lc = function() { + return !0 + }; + h.Dd = function(a, b) { + return !a.ea(b) + }; + h.Wc = function() { + return ue + }; + h.Tc = function() { + return Ae + }; + h.Sc = function(a, b) { + var c = Q(a); + return new L(b, c) + }; + h.toString = function() { + return ".value" + }; + var Be = new ze; + + function Ce() { + this.Xb = this.ra = this.Pb = this.oa = this.la = !1; + this.ma = 0; + this.Rb = ""; + this.ic = null; + this.Bb = ""; + this.fc = null; + this.zb = ""; + this.g = R + } + var De = new Ce; + + function Td(a) { + return "" === a.Rb ? a.oa : "l" === a.Rb + } + + function Od(a) { + O(a.oa, "Only valid if start has been set"); + return a.ic + } + + function Nd(a) { + O(a.oa, "Only valid if start has been set"); + return a.Pb ? a.Bb : "[MIN_NAME]" + } + + function Rd(a) { + O(a.ra, "Only valid if end has been set"); + return a.fc + } + + function Pd(a) { + O(a.ra, "Only valid if end has been set"); + return a.Xb ? a.zb : "[MAX_NAME]" + } + + function Ee(a) { + var b = new Ce; + b.la = a.la; + b.ma = a.ma; + b.oa = a.oa; + b.ic = a.ic; + b.Pb = a.Pb; + b.Bb = a.Bb; + b.ra = a.ra; + b.fc = a.fc; + b.Xb = a.Xb; + b.zb = a.zb; + b.g = a.g; + return b + } + h = Ce.prototype; + h.Le = function(a) { + var b = Ee(this); + b.la = !0; + b.ma = a; + b.Rb = ""; + return b + }; + h.Me = function(a) { + var b = Ee(this); + b.la = !0; + b.ma = a; + b.Rb = "l"; + return b + }; + h.Ne = function(a) { + var b = Ee(this); + b.la = !0; + b.ma = a; + b.Rb = "r"; + return b + }; + h.ce = function(a, b) { + var c = Ee(this); + c.oa = !0; + p(a) || (a = null); + c.ic = a; + null != b ? (c.Pb = !0, c.Bb = b) : (c.Pb = !1, c.Bb = ""); + return c + }; + h.vd = function(a, b) { + var c = Ee(this); + c.ra = !0; + p(a) || (a = null); + c.fc = a; + p(b) ? (c.Xb = !0, c.zb = b) : (c.mh = !1, c.zb = ""); + return c + }; + + function Fe(a, b) { + var c = Ee(a); + c.g = b; + return c + } + + function Ge(a) { + var b = {}; + a.oa && (b.sp = a.ic, a.Pb && (b.sn = a.Bb)); + a.ra && (b.ep = a.fc, a.Xb && (b.en = a.zb)); + if (a.la) { + b.l = a.ma; + var c = a.Rb; + "" === c && (c = Td(a) ? "l" : "r"); + b.vf = c + } + a.g !== R && (b.i = a.g.toString()); + return b + } + + function He(a) { + return !(a.oa || a.ra || a.la) + } + + function Ie(a) { + return He(a) && a.g == R + } + + function Je(a) { + var b = {}; + if (Ie(a)) return b; + var c; + a.g === R ? c = "$priority" : a.g === Be ? c = "$value" : a.g === re ? c = "$key" : (O(a.g instanceof ve, "Unrecognized index type!"), c = a.g.toString()); + b.orderBy = G(c); + a.oa && (b.startAt = G(a.ic), a.Pb && (b.startAt += "," + G(a.Bb))); + a.ra && (b.endAt = G(a.fc), a.Xb && (b.endAt += "," + G(a.zb))); + a.la && (Td(a) ? b.limitToFirst = a.ma : b.limitToLast = a.ma); + return b + } + h.toString = function() { + return G(Ge(this)) + }; + + function Ke(a, b) { + this.Ed = a; + this.hc = b + } + Ke.prototype.get = function(a) { + var b = z(this.Ed, a); + if (!b) throw Error("No index defined for " + a); + return b === te ? null : b + }; + + function Le(a, b, c) { + var d = ma(a.Ed, function(d, f) { + var g = z(a.hc, f); + O(g, "Missing index implementation for " + f); + if (d === te) { + if (g.Lc(b.U)) { + for (var k = [], m = c.ac(wc), l = Ic(m); l;) l.name != b.name && k.push(l), l = Ic(m); + k.push(b); + return Me(k, Vd(g)) + } + return te + } + g = c.get(b.name); + k = d; + g && (k = k.remove(new L(b.name, g))); + return k.Sa(b, b.U) + }); + return new Ke(d, a.hc) + } + + function Ne(a, b, c) { + var d = ma(a.Ed, function(a) { + if (a === te) return a; + var d = c.get(b.name); + return d ? a.remove(new L(b.name, d)) : a + }); + return new Ke(d, a.hc) + } + var Oe = new Ke({ + ".priority": te + }, { + ".priority": R + }); + + function Yc(a, b) { + this.B = a; + O(p(this.B) && null !== this.B, "LeafNode shouldn't be created with null/undefined value."); + this.ca = b || H; + Pe(this.ca); + this.Gb = null + } + var Qe = ["object", "boolean", "number", "string"]; + h = Yc.prototype; + h.L = function() { + return !0 + }; + h.C = function() { + return this.ca + }; + h.ia = function(a) { + return new Yc(this.B, a) + }; + h.T = function(a) { + return ".priority" === a ? this.ca : H + }; + h.S = function(a) { + return a.e() ? this : ".priority" === K(a) ? this.ca : H + }; + h.Fa = function() { + return !1 + }; + h.wf = function() { + return null + }; + h.W = function(a, b) { + return ".priority" === a ? this.ia(b) : b.e() && ".priority" !== a ? this : H.W(a, b).ia(this.ca) + }; + h.H = function(a, b) { + var c = K(a); + if (null === c) return b; + if (b.e() && ".priority" !== c) return this; + O(".priority" !== c || 1 === le(a), ".priority must be the last token in a path"); + return this.W(c, H.H(N(a), b)) + }; + h.e = function() { + return !1 + }; + h.Hb = function() { + return 0 + }; + h.R = function() { + return !1 + }; + h.J = function(a) { + return a && !this.C().e() ? { + ".value": this.Ea(), + ".priority": this.C().J() + } : this.Ea() + }; + h.hash = function() { + if (null === this.Gb) { + var a = ""; + this.ca.e() || (a += "priority:" + Re(this.ca.J()) + ":"); + var b = typeof this.B, + a = a + (b + ":"), + a = "number" === b ? a + Ad(this.B) : a + this.B; + this.Gb = ld(a) + } + return this.Gb + }; + h.Ea = function() { + return this.B + }; + h.Gc = function(a) { + if (a === H) return 1; + if (a instanceof fe) return -1; + O(a.L(), "Unknown node type"); + var b = typeof a.B, + c = typeof this.B, + d = La(Qe, b), + e = La(Qe, c); + O(0 <= d, "Unknown leaf type: " + b); + O(0 <= e, "Unknown leaf type: " + c); + return d === e ? "object" === c ? 0 : this.B < a.B ? -1 : this.B === a.B ? 0 : 1 : e - d + }; + h.pb = function() { + return this + }; + h.Mc = function() { + return !0 + }; + h.ea = function(a) { + return a === this ? !0 : a.L() ? this.B === a.B && this.ca.ea(a.ca) : !1 + }; + h.toString = function() { + return G(this.J(!0)) + }; + + function fe(a, b, c) { + this.m = a; + (this.ca = b) && Pe(this.ca); + a.e() && O(!this.ca || this.ca.e(), "An empty node cannot have a priority"); + this.Ab = c; + this.Gb = null + } + h = fe.prototype; + h.L = function() { + return !1 + }; + h.C = function() { + return this.ca || H + }; + h.ia = function(a) { + return this.m.e() ? this : new fe(this.m, a, this.Ab) + }; + h.T = function(a) { + if (".priority" === a) return this.C(); + a = this.m.get(a); + return null === a ? H : a + }; + h.S = function(a) { + var b = K(a); + return null === b ? this : this.T(b).S(N(a)) + }; + h.Fa = function(a) { + return null !== this.m.get(a) + }; + h.W = function(a, b) { + O(b, "We should always be passing snapshot nodes"); + if (".priority" === a) return this.ia(b); + var c = new L(a, b), + d, e; + b.e() ? (d = this.m.remove(a), c = Ne(this.Ab, c, this.m)) : (d = this.m.Sa(a, b), c = Le(this.Ab, c, this.m)); + e = d.e() ? H : this.ca; + return new fe(d, e, c) + }; + h.H = function(a, b) { + var c = K(a); + if (null === c) return b; + O(".priority" !== K(a) || 1 === le(a), ".priority must be the last token in a path"); + var d = this.T(c).H(N(a), b); + return this.W(c, d) + }; + h.e = function() { + return this.m.e() + }; + h.Hb = function() { + return this.m.count() + }; + var Se = /^(0|[1-9]\d*)$/; + h = fe.prototype; + h.J = function(a) { + if (this.e()) return null; + var b = {}, + c = 0, + d = 0, + e = !0; + this.R(R, function(f, g) { + b[f] = g.J(a); + c++; + e && Se.test(f) ? d = Math.max(d, Number(f)) : e = !1 + }); + if (!a && e && d < 2 * c) { + var f = [], + g; + for (g in b) f[g] = b[g]; + return f + } + a && !this.C().e() && (b[".priority"] = this.C().J()); + return b + }; + h.hash = function() { + if (null === this.Gb) { + var a = ""; + this.C().e() || (a += "priority:" + Re(this.C().J()) + ":"); + this.R(R, function(b, c) { + var d = c.hash(); + "" !== d && (a += ":" + b + ":" + d) + }); + this.Gb = "" === a ? "" : ld(a) + } + return this.Gb + }; + h.wf = function(a, b, c) { + return (c = Te(this, c)) ? (a = Gc(c, new L(a, b))) ? a.name : null : Gc(this.m, a) + }; + + function Wd(a, b) { + var c; + c = (c = Te(a, b)) ? (c = c.Vc()) && c.name : a.m.Vc(); + return c ? new L(c, a.m.get(c)) : null + } + + function Xd(a, b) { + var c; + c = (c = Te(a, b)) ? (c = c.jc()) && c.name : a.m.jc(); + return c ? new L(c, a.m.get(c)) : null + } + h.R = function(a, b) { + var c = Te(this, a); + return c ? c.ka(function(a) { + return b(a.name, a.U) + }) : this.m.ka(b) + }; + h.ac = function(a) { + return this.bc(a.Wc(), a) + }; + h.bc = function(a, b) { + var c = Te(this, b); + if (c) return c.bc(a, function(a) { + return a + }); + for (var c = this.m.bc(a.name, wc), d = Jc(c); null != d && 0 > b.compare(d, a);) Ic(c), d = Jc(c); + return c + }; + h.xf = function(a) { + return this.dc(a.Tc(), a) + }; + h.dc = function(a, b) { + var c = Te(this, b); + if (c) return c.dc(a, function(a) { + return a + }); + for (var c = this.m.dc(a.name, wc), d = Jc(c); null != d && 0 < b.compare(d, a);) Ic(c), d = Jc(c); + return c + }; + h.Gc = function(a) { + return this.e() ? a.e() ? 0 : -1 : a.L() || a.e() ? 1 : a === we ? -1 : 0 + }; + h.pb = function(a) { + if (a === re || sa(this.Ab.hc, a.toString())) return this; + var b = this.Ab, + c = this.m; + O(a !== re, "KeyIndex always exists and isn't meant to be added to the IndexMap."); + for (var d = [], e = !1, c = c.ac(wc), f = Ic(c); f;) e = e || a.Lc(f.U), d.push(f), f = Ic(c); + d = e ? Me(d, Vd(a)) : te; + e = a.toString(); + c = wa(b.hc); + c[e] = a; + a = wa(b.Ed); + a[e] = d; + return new fe(this.m, this.ca, new Ke(a, c)) + }; + h.Mc = function(a) { + return a === re || sa(this.Ab.hc, a.toString()) + }; + h.ea = function(a) { + if (a === this) return !0; + if (a.L()) return !1; + if (this.C().ea(a.C()) && this.m.count() === a.m.count()) { + var b = this.ac(R); + a = a.ac(R); + for (var c = Ic(b), d = Ic(a); c && d;) { + if (c.name !== d.name || !c.U.ea(d.U)) return !1; + c = Ic(b); + d = Ic(a) + } + return null === c && null === d + } + return !1 + }; + + function Te(a, b) { + return b === re ? null : a.Ab.get(b.toString()) + } + h.toString = function() { + return G(this.J(!0)) + }; + + function Q(a, b) { + if (null === a) return H; + var c = null; + "object" === typeof a && ".priority" in a ? c = a[".priority"] : "undefined" !== typeof b && (c = b); + O(null === c || "string" === typeof c || "number" === typeof c || "object" === typeof c && ".sv" in c, "Invalid priority type found: " + typeof c); + "object" === typeof a && ".value" in a && null !== a[".value"] && (a = a[".value"]); + if ("object" !== typeof a || ".sv" in a) return new Yc(a, Q(c)); + if (a instanceof Array) { + var d = H, + e = a; + v(e, function(a, b) { + if (y(e, b) && "." !== b.substring(0, 1)) { + var c = Q(a); + if (c.L() || !c.e()) d = + d.W(b, c) + } + }); + return d.ia(Q(c)) + } + var f = [], + g = !1, + k = a; + Fb(k, function(a) { + if ("string" !== typeof a || "." !== a.substring(0, 1)) { + var b = Q(k[a]); + b.e() || (g = g || !b.C().e(), f.push(new L(a, b))) + } + }); + if (0 == f.length) return H; + var m = Me(f, xc, function(a) { + return a.name + }, zc); + if (g) { + var l = Me(f, Vd(R)); + return new fe(m, Q(c), new Ke({ + ".priority": l + }, { + ".priority": R + })) + } + return new fe(m, Q(c), Oe) + } + var Ue = Math.log(2); + + function Ve(a) { + this.count = parseInt(Math.log(a + 1) / Ue, 10); + this.nf = this.count - 1; + this.ng = a + 1 & parseInt(Array(this.count + 1).join("1"), 2) + } + + function We(a) { + var b = !(a.ng & 1 << a.nf); + a.nf--; + return b + } + + function Me(a, b, c, d) { + function e(b, d) { + var f = d - b; + if (0 == f) return null; + if (1 == f) { + var l = a[b], + t = c ? c(l) : l; + return new Kc(t, l.U, !1, null, null) + } + var l = parseInt(f / 2, 10) + b, + f = e(b, l), + A = e(l + 1, d), + l = a[l], + t = c ? c(l) : l; + return new Kc(t, l.U, !1, f, A) + } + a.sort(b); + var f = function(b) { + function d(b, g) { + var k = t - b, + A = t; + t -= b; + var A = e(k + 1, A), + k = a[k], + I = c ? c(k) : k, + A = new Kc(I, k.U, g, null, A); + f ? f.left = A : l = A; + f = A + } + for (var f = null, l = null, t = a.length, A = 0; A < b.count; ++A) { + var I = We(b), + Qd = Math.pow(2, b.count - (A + 1)); + I ? d(Qd, !1) : (d(Qd, !1), d(Qd, !0)) + } + return l + }(new Ve(a.length)); + return null !== f ? new Ec(d || b, f) : new Ec(d || b) + } + + function Re(a) { + return "number" === typeof a ? "number:" + Ad(a) : "string:" + a + } + + function Pe(a) { + if (a.L()) { + var b = a.J(); + O("string" === typeof b || "number" === typeof b || "object" === typeof b && y(b, ".sv"), "Priority must be a string or number.") + } else O(a === we || a.e(), "priority of unexpected type."); + O(a === we || a.C().e(), "Priority nodes can't have a priority of their own.") + } + var H = new fe(new Ec(zc), null, Oe); + + function Xe() { + fe.call(this, new Ec(zc), H, Oe) + } + ka(Xe, fe); + h = Xe.prototype; + h.Gc = function(a) { + return a === this ? 0 : 1 + }; + h.ea = function(a) { + return a === this + }; + h.C = function() { + return this + }; + h.T = function() { + return H + }; + h.e = function() { + return !1 + }; + var we = new Xe, + ue = new L("[MIN_NAME]", H), + Ae = new L("[MAX_NAME]", we); + + function je(a, b) { + this.Q = a; + this.ae = b + } + + function ge(a, b, c, d) { + return new je(new Xb(b, c, d), a.ae) + } + + function ke(a) { + return a.Q.ga ? a.Q.j() : null + } + je.prototype.w = function() { + return this.ae + }; + + function Yb(a) { + return a.ae.ga ? a.ae.j() : null + }; + + function Ye(a, b) { + this.Y = a; + var c = a.n, + d = new Ld(c.g), + c = He(c) ? new Ld(c.g) : c.la ? new Sd(c) : new Md(c); + this.Nf = new Zd(c); + var e = b.w(), + f = b.Q, + g = d.ya(H, e.j(), null), + k = c.ya(H, f.j(), null); + this.Oa = new je(new Xb(k, f.ga, c.Ra()), new Xb(g, e.ga, d.Ra())); + this.$a = []; + this.ug = new Fd(a) + } + + function Ze(a) { + return a.Y + } + h = Ye.prototype; + h.w = function() { + return this.Oa.w().j() + }; + h.kb = function(a) { + var b = Yb(this.Oa); + return b && (He(this.Y.n) || !a.e() && !b.T(K(a)).e()) ? b.S(a) : null + }; + h.e = function() { + return 0 === this.$a.length + }; + h.Tb = function(a) { + this.$a.push(a) + }; + h.nb = function(a, b) { + var c = []; + if (b) { + O(null == a, "A cancel should cancel all event registrations."); + var d = this.Y.path; + Ma(this.$a, function(a) { + (a = a.lf(b, d)) && c.push(a) + }) + } + if (a) { + for (var e = [], f = 0; f < this.$a.length; ++f) { + var g = this.$a[f]; + if (!g.matches(a)) e.push(g); + else if (a.yf()) { + e = e.concat(this.$a.slice(f + 1)); + break + } + } + this.$a = e + } else this.$a = []; + return c + }; + h.gb = function(a, b, c) { + a.type === be && null !== a.source.Lb && (O(Yb(this.Oa), "We should always have a full cache before handling merges"), O(ke(this.Oa), "Missing event cache, even though we have a server cache")); + var d = this.Oa; + a = this.Nf.gb(d, a, b, c); + b = this.Nf; + c = a.me; + O(c.Q.j().Mc(b.X.g), "Event snap not indexed"); + O(c.w().j().Mc(b.X.g), "Server snap not indexed"); + O(lc(a.me.w()) || !lc(d.w()), "Once a server snap is complete, it should never go back"); + this.Oa = a.me; + return $e(this, a.og, a.me.Q.j(), null) + }; + + function af(a, b) { + var c = a.Oa.Q, + d = []; + c.j().L() || c.j().R(R, function(a, b) { + d.push(new J("child_added", b, a)) + }); + c.ga && d.push(hc(c.j())); + return $e(a, d, c.j(), b) + } + + function $e(a, b, c, d) { + return Gd(a.ug, b, c, d ? [d] : a.$a) + }; + + function bf(a, b, c) { + this.type = be; + this.source = a; + this.path = b; + this.children = c + } + bf.prototype.$c = function(a) { + if (this.path.e()) return a = this.children.subtree(new P(a)), a.e() ? null : a.value ? new Ac(this.source, M, a.value) : new bf(this.source, M, a); + O(K(this.path) === a, "Can't get a merge for a child not on the path of the operation"); + return new bf(this.source, N(this.path), this.children) + }; + bf.prototype.toString = function() { + return "Operation(" + this.path + ": " + this.source.toString() + " merge: " + this.children.toString() + ")" + }; + + function cf(a, b) { + this.f = pd("p:rest:"); + this.G = a; + this.Kb = b; + this.Ca = null; + this.ba = {} + } + + function df(a, b) { + if (p(b)) return "tag$" + b; + O(Ie(a.n), "should have a tag if it's not a default query."); + return a.path.toString() + } + h = cf.prototype; + h.Cf = function(a, b, c, d) { + var e = a.path.toString(); + this.f("Listen called for " + e + " " + a.wa()); + var f = df(a, c), + g = {}; + this.ba[f] = g; + a = Je(a.n); + var k = this; + ef(this, e + ".json", a, function(a, b) { + var t = b; + 404 === a && (a = t = null); + null === a && k.Kb(e, t, !1, c); + z(k.ba, f) === g && d(a ? 401 == a ? "permission_denied" : "rest_error:" + a : "ok", null) + }) + }; + h.$f = function(a, b) { + var c = df(a, b); + delete this.ba[c] + }; + h.O = function(a, b) { + this.Ca = a; + var c = Cd(a), + d = c.data, + c = c.Ec && c.Ec.exp; + b && b("ok", { + auth: d, + expires: c + }) + }; + h.je = function(a) { + this.Ca = null; + a("ok", null) + }; + h.Qe = function() {}; + h.Gf = function() {}; + h.Md = function() {}; + h.put = function() {}; + h.Df = function() {}; + h.Ye = function() {}; + + function ef(a, b, c, d) { + c = c || {}; + c.format = "export"; + a.Ca && (c.auth = a.Ca); + var e = (a.G.ob ? "https://" : "http://") + a.G.host + b + "?" + Ib(c); + a.f("Sending REST request for " + e); + var f = new XMLHttpRequest; + f.onreadystatechange = function() { + if (d && 4 === f.readyState) { + a.f("REST Response for " + e + " received. status:", f.status, "response:", f.responseText); + var b = null; + if (200 <= f.status && 300 > f.status) { + try { + b = Rb(f.responseText) + } catch (c) { + S("Failed to parse JSON response for " + e + ": " + f.responseText) + } + d(null, b) + } else 401 !== f.status && 404 !== + f.status && S("Got unsuccessful REST response for " + e + " Status: " + f.status), d(f.status); + d = null + } + }; + f.open("GET", e, !0); + f.send() + }; + + function ff(a) { + O(da(a) && 0 < a.length, "Requires a non-empty array"); + this.fg = a; + this.Rc = {} + } + ff.prototype.ie = function(a, b) { + var c; + c = this.Rc[a] || []; + var d = c.length; + if (0 < d) { + for (var e = Array(d), f = 0; f < d; f++) e[f] = c[f]; + c = e + } else c = []; + for (d = 0; d < c.length; d++) c[d].Dc.apply(c[d].Qa, Array.prototype.slice.call(arguments, 1)) + }; + ff.prototype.Ib = function(a, b, c) { + gf(this, a); + this.Rc[a] = this.Rc[a] || []; + this.Rc[a].push({ + Dc: b, + Qa: c + }); + (a = this.Ee(a)) && b.apply(c, a) + }; + ff.prototype.mc = function(a, b, c) { + gf(this, a); + a = this.Rc[a] || []; + for (var d = 0; d < a.length; d++) + if (a[d].Dc === b && (!c || c === a[d].Qa)) { + a.splice(d, 1); + break + } + }; + + function gf(a, b) { + O(Ra(a.fg, function(a) { + return a === b + }), "Unknown event: " + b) + }; + var hf = function() { + var a = 0, + b = []; + return function(c) { + var d = c === a; + a = c; + for (var e = Array(8), f = 7; 0 <= f; f--) e[f] = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(c % 64), c = Math.floor(c / 64); + O(0 === c, "Cannot push at time == 0"); + c = e.join(""); + if (d) { + for (f = 11; 0 <= f && 63 === b[f]; f--) b[f] = 0; + b[f]++ + } else + for (f = 0; 12 > f; f++) b[f] = Math.floor(64 * Math.random()); + for (f = 0; 12 > f; f++) c += "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(b[f]); + O(20 === c.length, "nextPushId: Length should be 20."); + return c + } + }(); + + function jf() { + ff.call(this, ["online"]); + this.oc = !0; + if ("undefined" !== typeof window && "undefined" !== typeof window.addEventListener) { + var a = this; + window.addEventListener("online", function() { + a.oc || (a.oc = !0, a.ie("online", !0)) + }, !1); + window.addEventListener("offline", function() { + a.oc && (a.oc = !1, a.ie("online", !1)) + }, !1) + } + } + ka(jf, ff); + jf.prototype.Ee = function(a) { + O("online" === a, "Unknown event type: " + a); + return [this.oc] + }; + ba(jf); + + function kf() { + ff.call(this, ["visible"]); + var a, b; + "undefined" !== typeof document && "undefined" !== typeof document.addEventListener && ("undefined" !== typeof document.hidden ? (b = "visibilitychange", a = "hidden") : "undefined" !== typeof document.mozHidden ? (b = "mozvisibilitychange", a = "mozHidden") : "undefined" !== typeof document.msHidden ? (b = "msvisibilitychange", a = "msHidden") : "undefined" !== typeof document.webkitHidden && (b = "webkitvisibilitychange", a = "webkitHidden")); + this.Sb = !0; + if (b) { + var c = this; + document.addEventListener(b, + function() { + var b = !document[a]; + b !== c.Sb && (c.Sb = b, c.ie("visible", b)) + }, !1) + } + } + ka(kf, ff); + kf.prototype.Ee = function(a) { + O("visible" === a, "Unknown event type: " + a); + return [this.Sb] + }; + ba(kf); + + function P(a, b) { + if (1 == arguments.length) { + this.u = a.split("/"); + for (var c = 0, d = 0; d < this.u.length; d++) 0 < this.u[d].length && (this.u[c] = this.u[d], c++); + this.u.length = c; + this.aa = 0 + } else this.u = a, this.aa = b + } + + function lf(a, b) { + var c = K(a); + if (null === c) return b; + if (c === K(b)) return lf(N(a), N(b)); + throw Error("INTERNAL ERROR: innerPath (" + b + ") is not within outerPath (" + a + ")"); + } + + function mf(a, b) { + for (var c = a.slice(), d = b.slice(), e = 0; e < c.length && e < d.length; e++) { + var f = yc(c[e], d[e]); + if (0 !== f) return f + } + return c.length === d.length ? 0 : c.length < d.length ? -1 : 1 + } + + function K(a) { + return a.aa >= a.u.length ? null : a.u[a.aa] + } + + function le(a) { + return a.u.length - a.aa + } + + function N(a) { + var b = a.aa; + b < a.u.length && b++; + return new P(a.u, b) + } + + function me(a) { + return a.aa < a.u.length ? a.u[a.u.length - 1] : null + } + h = P.prototype; + h.toString = function() { + for (var a = "", b = this.aa; b < this.u.length; b++) "" !== this.u[b] && (a += "/" + this.u[b]); + return a || "/" + }; + h.slice = function(a) { + return this.u.slice(this.aa + (a || 0)) + }; + h.parent = function() { + if (this.aa >= this.u.length) return null; + for (var a = [], b = this.aa; b < this.u.length - 1; b++) a.push(this.u[b]); + return new P(a, 0) + }; + h.o = function(a) { + for (var b = [], c = this.aa; c < this.u.length; c++) b.push(this.u[c]); + if (a instanceof P) + for (c = a.aa; c < a.u.length; c++) b.push(a.u[c]); + else + for (a = a.split("/"), c = 0; c < a.length; c++) 0 < a[c].length && b.push(a[c]); + return new P(b, 0) + }; + h.e = function() { + return this.aa >= this.u.length + }; + h.ea = function(a) { + if (le(this) !== le(a)) return !1; + for (var b = this.aa, c = a.aa; b <= this.u.length; b++, c++) + if (this.u[b] !== a.u[c]) return !1; + return !0 + }; + h.contains = function(a) { + var b = this.aa, + c = a.aa; + if (le(this) > le(a)) return !1; + for (; b < this.u.length;) { + if (this.u[b] !== a.u[c]) return !1; + ++b; + ++c + } + return !0 + }; + var M = new P(""); + + function nf(a, b) { + this.Ua = a.slice(); + this.Ka = Math.max(1, this.Ua.length); + this.pf = b; + for (var c = 0; c < this.Ua.length; c++) this.Ka += Pb(this.Ua[c]); + of(this) + } + nf.prototype.push = function(a) { + 0 < this.Ua.length && (this.Ka += 1); + this.Ua.push(a); + this.Ka += Pb(a); + of(this) + }; + nf.prototype.pop = function() { + var a = this.Ua.pop(); + this.Ka -= Pb(a); + 0 < this.Ua.length && --this.Ka + }; + + function of(a) { + if (768 < a.Ka) throw Error(a.pf + "has a key path longer than 768 bytes (" + a.Ka + ")."); + if (32 < a.Ua.length) throw Error(a.pf + "path specified exceeds the maximum depth that can be written (32) or object contains a cycle " + pf(a)); + } + + function pf(a) { + return 0 == a.Ua.length ? "" : "in property '" + a.Ua.join(".") + "'" + }; + + function qf(a, b) { + this.value = a; + this.children = b || rf + } + var rf = new Ec(function(a, b) { + return a === b ? 0 : a < b ? -1 : 1 + }); + + function sf(a) { + var b = qe; + v(a, function(a, d) { + b = b.set(new P(d), a) + }); + return b + } + h = qf.prototype; + h.e = function() { + return null === this.value && this.children.e() + }; + + function tf(a, b, c) { + if (null != a.value && c(a.value)) return { + path: M, + value: a.value + }; + if (b.e()) return null; + var d = K(b); + a = a.children.get(d); + return null !== a ? (b = tf(a, N(b), c), null != b ? { + path: (new P(d)).o(b.path), + value: b.value + } : null) : null + } + + function uf(a, b) { + return tf(a, b, function() { + return !0 + }) + } + h.subtree = function(a) { + if (a.e()) return this; + var b = this.children.get(K(a)); + return null !== b ? b.subtree(N(a)) : qe + }; + h.set = function(a, b) { + if (a.e()) return new qf(b, this.children); + var c = K(a), + d = (this.children.get(c) || qe).set(N(a), b), + c = this.children.Sa(c, d); + return new qf(this.value, c) + }; + h.remove = function(a) { + if (a.e()) return this.children.e() ? qe : new qf(null, this.children); + var b = K(a), + c = this.children.get(b); + return c ? (a = c.remove(N(a)), b = a.e() ? this.children.remove(b) : this.children.Sa(b, a), null === this.value && b.e() ? qe : new qf(this.value, b)) : this + }; + h.get = function(a) { + if (a.e()) return this.value; + var b = this.children.get(K(a)); + return b ? b.get(N(a)) : null + }; + + function pe(a, b, c) { + if (b.e()) return c; + var d = K(b); + b = pe(a.children.get(d) || qe, N(b), c); + d = b.e() ? a.children.remove(d) : a.children.Sa(d, b); + return new qf(a.value, d) + } + + function vf(a, b) { + return wf(a, M, b) + } + + function wf(a, b, c) { + var d = {}; + a.children.ka(function(a, f) { + d[a] = wf(f, b.o(a), c) + }); + return c(b, a.value, d) + } + + function xf(a, b, c) { + return yf(a, b, M, c) + } + + function yf(a, b, c, d) { + var e = a.value ? d(c, a.value) : !1; + if (e) return e; + if (b.e()) return null; + e = K(b); + return (a = a.children.get(e)) ? yf(a, N(b), c.o(e), d) : null + } + + function zf(a, b, c) { + Af(a, b, M, c) + } + + function Af(a, b, c, d) { + if (b.e()) return a; + a.value && d(c, a.value); + var e = K(b); + return (a = a.children.get(e)) ? Af(a, N(b), c.o(e), d) : qe + } + + function ne(a, b) { + Bf(a, M, b) + } + + function Bf(a, b, c) { + a.children.ka(function(a, e) { + Bf(e, b.o(a), c) + }); + a.value && c(b, a.value) + } + + function Cf(a, b) { + a.children.ka(function(a, d) { + d.value && b(a, d.value) + }) + } + var qe = new qf(null); + qf.prototype.toString = function() { + var a = {}; + ne(this, function(b, c) { + a[b.toString()] = c.toString() + }); + return G(a) + }; + + function Df(a, b, c) { + this.type = ee; + this.source = Ef; + this.path = a; + this.Ub = b; + this.Yd = c + } + Df.prototype.$c = function(a) { + if (this.path.e()) { + if (null != this.Ub.value) return O(this.Ub.children.e(), "affectedTree should not have overlapping affected paths."), this; + a = this.Ub.subtree(new P(a)); + return new Df(M, a, this.Yd) + } + O(K(this.path) === a, "operationForChild called for unrelated child."); + return new Df(N(this.path), this.Ub, this.Yd) + }; + Df.prototype.toString = function() { + return "Operation(" + this.path + ": " + this.source.toString() + " ack write revert=" + this.Yd + " affectedTree=" + this.Ub + ")" + }; + var Bc = 0, + be = 1, + ee = 2, + Dc = 3; + + function Ff(a, b, c, d) { + this.Ae = a; + this.tf = b; + this.Lb = c; + this.ef = d; + O(!d || b, "Tagged queries must be from server.") + } + var Ef = new Ff(!0, !1, null, !1), + Gf = new Ff(!1, !0, null, !1); + Ff.prototype.toString = function() { + return this.Ae ? "user" : this.ef ? "server(queryID=" + this.Lb + ")" : "server" + }; + + function Hf(a) { + this.Z = a + } + var If = new Hf(new qf(null)); + + function Jf(a, b, c) { + if (b.e()) return new Hf(new qf(c)); + var d = uf(a.Z, b); + if (null != d) { + var e = d.path, + d = d.value; + b = lf(e, b); + d = d.H(b, c); + return new Hf(a.Z.set(e, d)) + } + a = pe(a.Z, b, new qf(c)); + return new Hf(a) + } + + function Kf(a, b, c) { + var d = a; + Fb(c, function(a, c) { + d = Jf(d, b.o(a), c) + }); + return d + } + Hf.prototype.Ud = function(a) { + if (a.e()) return If; + a = pe(this.Z, a, qe); + return new Hf(a) + }; + + function Lf(a, b) { + var c = uf(a.Z, b); + return null != c ? a.Z.get(c.path).S(lf(c.path, b)) : null + } + + function Mf(a) { + var b = [], + c = a.Z.value; + null != c ? c.L() || c.R(R, function(a, c) { + b.push(new L(a, c)) + }) : a.Z.children.ka(function(a, c) { + null != c.value && b.push(new L(a, c.value)) + }); + return b + } + + function Nf(a, b) { + if (b.e()) return a; + var c = Lf(a, b); + return null != c ? new Hf(new qf(c)) : new Hf(a.Z.subtree(b)) + } + Hf.prototype.e = function() { + return this.Z.e() + }; + Hf.prototype.apply = function(a) { + return Of(M, this.Z, a) + }; + + function Of(a, b, c) { + if (null != b.value) return c.H(a, b.value); + var d = null; + b.children.ka(function(b, f) { + ".priority" === b ? (O(null !== f.value, "Priority writes must always be leaf nodes"), d = f.value) : c = Of(a.o(b), f, c) + }); + c.S(a).e() || null === d || (c = c.H(a.o(".priority"), d)); + return c + }; + + function Pf() { + this.V = If; + this.pa = []; + this.Pc = -1 + } + + function Qf(a, b) { + for (var c = 0; c < a.pa.length; c++) { + var d = a.pa[c]; + if (d.md === b) return d + } + return null + } + h = Pf.prototype; + h.Ud = function(a) { + var b = Sa(this.pa, function(b) { + return b.md === a + }); + O(0 <= b, "removeWrite called with nonexistent writeId."); + var c = this.pa[b]; + this.pa.splice(b, 1); + for (var d = c.visible, e = !1, f = this.pa.length - 1; d && 0 <= f;) { + var g = this.pa[f]; + g.visible && (f >= b && Rf(g, c.path) ? d = !1 : c.path.contains(g.path) && (e = !0)); + f-- + } + if (d) { + if (e) this.V = Sf(this.pa, Tf, M), this.Pc = 0 < this.pa.length ? this.pa[this.pa.length - 1].md : -1; + else if (c.Ja) this.V = this.V.Ud(c.path); + else { + var k = this; + v(c.children, function(a, b) { + k.V = k.V.Ud(c.path.o(b)) + }) + } + return !0 + } + return !1 + }; + h.Aa = function(a, b, c, d) { + if (c || d) { + var e = Nf(this.V, a); + return !d && e.e() ? b : d || null != b || null != Lf(e, M) ? (e = Sf(this.pa, function(b) { + return (b.visible || d) && (!c || !(0 <= La(c, b.md))) && (b.path.contains(a) || a.contains(b.path)) + }, a), b = b || H, e.apply(b)) : null + } + e = Lf(this.V, a); + if (null != e) return e; + e = Nf(this.V, a); + return e.e() ? b : null != b || null != Lf(e, M) ? (b = b || H, e.apply(b)) : null + }; + h.Cc = function(a, b) { + var c = H, + d = Lf(this.V, a); + if (d) d.L() || d.R(R, function(a, b) { + c = c.W(a, b) + }); + else if (b) { + var e = Nf(this.V, a); + b.R(R, function(a, b) { + var d = Nf(e, new P(a)).apply(b); + c = c.W(a, d) + }); + Ma(Mf(e), function(a) { + c = c.W(a.name, a.U) + }) + } else e = Nf(this.V, a), Ma(Mf(e), function(a) { + c = c.W(a.name, a.U) + }); + return c + }; + h.nd = function(a, b, c, d) { + O(c || d, "Either existingEventSnap or existingServerSnap must exist"); + a = a.o(b); + if (null != Lf(this.V, a)) return null; + a = Nf(this.V, a); + return a.e() ? d.S(b) : a.apply(d.S(b)) + }; + h.Bc = function(a, b, c) { + a = a.o(b); + var d = Lf(this.V, a); + return null != d ? d : Wb(c, b) ? Nf(this.V, a).apply(c.j().T(b)) : null + }; + h.xc = function(a) { + return Lf(this.V, a) + }; + h.qe = function(a, b, c, d, e, f) { + var g; + a = Nf(this.V, a); + g = Lf(a, M); + if (null == g) + if (null != b) g = a.apply(b); + else return []; + g = g.pb(f); + if (g.e() || g.L()) return []; + b = []; + a = Vd(f); + e = e ? g.dc(c, f) : g.bc(c, f); + for (f = Ic(e); f && b.length < d;) 0 !== a(f, c) && b.push(f), f = Ic(e); + return b + }; + + function Rf(a, b) { + return a.Ja ? a.path.contains(b) : !!ta(a.children, function(c, d) { + return a.path.o(d).contains(b) + }) + } + + function Tf(a) { + return a.visible + } + + function Sf(a, b, c) { + for (var d = If, e = 0; e < a.length; ++e) { + var f = a[e]; + if (b(f)) { + var g = f.path; + if (f.Ja) c.contains(g) ? (g = lf(c, g), d = Jf(d, g, f.Ja)) : g.contains(c) && (g = lf(g, c), d = Jf(d, M, f.Ja.S(g))); + else if (f.children) + if (c.contains(g)) g = lf(c, g), d = Kf(d, g, f.children); + else { + if (g.contains(c)) + if (g = lf(g, c), g.e()) d = Kf(d, M, f.children); + else if (f = z(f.children, K(g))) f = f.S(N(g)), d = Jf(d, M, f) + } else throw jd("WriteRecord should have .snap or .children"); + } + } + return d + } + + function Uf(a, b) { + this.Qb = a; + this.Z = b + } + h = Uf.prototype; + h.Aa = function(a, b, c) { + return this.Z.Aa(this.Qb, a, b, c) + }; + h.Cc = function(a) { + return this.Z.Cc(this.Qb, a) + }; + h.nd = function(a, b, c) { + return this.Z.nd(this.Qb, a, b, c) + }; + h.xc = function(a) { + return this.Z.xc(this.Qb.o(a)) + }; + h.qe = function(a, b, c, d, e) { + return this.Z.qe(this.Qb, a, b, c, d, e) + }; + h.Bc = function(a, b) { + return this.Z.Bc(this.Qb, a, b) + }; + h.o = function(a) { + return new Uf(this.Qb.o(a), this.Z) + }; + + function Vf() { + this.children = {}; + this.pd = 0; + this.value = null + } + + function Wf(a, b, c) { + this.Jd = a ? a : ""; + this.Ha = b ? b : null; + this.A = c ? c : new Vf + } + + function Xf(a, b) { + for (var c = b instanceof P ? b : new P(b), d = a, e; null !== (e = K(c));) d = new Wf(e, d, z(d.A.children, e) || new Vf), c = N(c); + return d + } + h = Wf.prototype; + h.Ea = function() { + return this.A.value + }; + + function Yf(a, b) { + O("undefined" !== typeof b, "Cannot set value to undefined"); + a.A.value = b; + Zf(a) + } + h.clear = function() { + this.A.value = null; + this.A.children = {}; + this.A.pd = 0; + Zf(this) + }; + h.zd = function() { + return 0 < this.A.pd + }; + h.e = function() { + return null === this.Ea() && !this.zd() + }; + h.R = function(a) { + var b = this; + v(this.A.children, function(c, d) { + a(new Wf(d, b, c)) + }) + }; + + function $f(a, b, c, d) { + c && !d && b(a); + a.R(function(a) { + $f(a, b, !0, d) + }); + c && d && b(a) + } + + function ag(a, b) { + for (var c = a.parent(); null !== c && !b(c);) c = c.parent() + } + h.path = function() { + return new P(null === this.Ha ? this.Jd : this.Ha.path() + "/" + this.Jd) + }; + h.name = function() { + return this.Jd + }; + h.parent = function() { + return this.Ha + }; + + function Zf(a) { + if (null !== a.Ha) { + var b = a.Ha, + c = a.Jd, + d = a.e(), + e = y(b.A.children, c); + d && e ? (delete b.A.children[c], b.A.pd--, Zf(b)) : d || e || (b.A.children[c] = a.A, b.A.pd++, Zf(b)) + } + }; + var bg = /[\[\].#$\/\u0000-\u001F\u007F]/, + cg = /[\[\].#$\u0000-\u001F\u007F]/, + dg = /^[a-zA-Z][a-zA-Z._\-+]+$/; + + function eg(a) { + return q(a) && 0 !== a.length && !bg.test(a) + } + + function fg(a) { + return null === a || q(a) || fa(a) && !td(a) || ga(a) && y(a, ".sv") + } + + function gg(a, b, c, d) { + d && !p(b) || hg(E(a, 1, d), b, c) + } + + function hg(a, b, c) { + c instanceof P && (c = new nf(c, a)); + if (!p(b)) throw Error(a + "contains undefined " + pf(c)); + if (r(b)) throw Error(a + "contains a function " + pf(c) + " with contents: " + b.toString()); + if (td(b)) throw Error(a + "contains " + b.toString() + " " + pf(c)); + if (q(b) && b.length > 10485760 / 3 && 10485760 < Pb(b)) throw Error(a + "contains a string greater than 10485760 utf8 bytes " + pf(c) + " ('" + b.substring(0, 50) + "...')"); + if (ga(b)) { + var d = !1, + e = !1; + Fb(b, function(b, g) { + if (".value" === b) d = !0; + else if (".priority" !== b && ".sv" !== b && (e = !0, !eg(b))) throw Error(a + " contains an invalid key (" + b + ") " + pf(c) + '. Keys must be non-empty strings and can\'t contain ".", "#", "$", "/", "[", or "]"'); + c.push(b); + hg(a, g, c); + c.pop() + }); + if (d && e) throw Error(a + ' contains ".value" child ' + pf(c) + " in addition to actual children."); + } + } + + function ig(a, b) { + var c, d; + for (c = 0; c < b.length; c++) { + d = b[c]; + for (var e = d.slice(), f = 0; f < e.length; f++) + if ((".priority" !== e[f] || f !== e.length - 1) && !eg(e[f])) throw Error(a + "contains an invalid key (" + e[f] + ") in path " + d.toString() + '. Keys must be non-empty strings and can\'t contain ".", "#", "$", "/", "[", or "]"'); + } + b.sort(mf); + e = null; + for (c = 0; c < b.length; c++) { + d = b[c]; + if (null !== e && e.contains(d)) throw Error(a + "contains a path " + e.toString() + " that is ancestor of another path " + d.toString()); + e = d + } + } + + function jg(a, b, c) { + var d = E(a, 1, !1); + if (!ga(b) || da(b)) throw Error(d + " must be an object containing the children to replace."); + var e = []; + Fb(b, function(a, b) { + var k = new P(a); + hg(d, b, c.o(k)); + if (".priority" === me(k) && !fg(b)) throw Error(d + "contains an invalid value for '" + k.toString() + "', which must be a valid Firebase priority (a string, finite number, server value, or null)."); + e.push(k) + }); + ig(d, e) + } + + function kg(a, b, c) { + if (td(c)) throw Error(E(a, b, !1) + "is " + c.toString() + ", but must be a valid Firebase priority (a string, finite number, server value, or null)."); + if (!fg(c)) throw Error(E(a, b, !1) + "must be a valid Firebase priority (a string, finite number, server value, or null)."); + } + + function lg(a, b, c) { + if (!c || p(b)) switch (b) { + case "value": + case "child_added": + case "child_removed": + case "child_changed": + case "child_moved": + break; + default: + throw Error(E(a, 1, c) + 'must be a valid event type: "value", "child_added", "child_removed", "child_changed", or "child_moved".'); + } + } + + function mg(a, b) { + if (p(b) && !eg(b)) throw Error(E(a, 2, !0) + 'was an invalid key: "' + b + '". Firebase keys must be non-empty strings and can\'t contain ".", "#", "$", "/", "[", or "]").'); + } + + function ng(a, b) { + if (!q(b) || 0 === b.length || cg.test(b)) throw Error(E(a, 1, !1) + 'was an invalid path: "' + b + '". Paths must be non-empty strings and can\'t contain ".", "#", "$", "[", or "]"'); + } + + function og(a, b) { + if (".info" === K(b)) throw Error(a + " failed: Can't modify data under /.info/"); + } + + function pg(a, b) { + if (!q(b)) throw Error(E(a, 1, !1) + "must be a valid credential (a string)."); + } + + function qg(a, b, c) { + if (!q(c)) throw Error(E(a, b, !1) + "must be a valid string."); + } + + function rg(a, b) { + qg(a, 1, b); + if (!dg.test(b)) throw Error(E(a, 1, !1) + "'" + b + "' is not a valid authentication provider."); + } + + function sg(a, b, c, d) { + if (!d || p(c)) + if (!ga(c) || null === c) throw Error(E(a, b, d) + "must be a valid object."); + } + + function tg(a, b, c) { + if (!ga(b) || !y(b, c)) throw Error(E(a, 1, !1) + 'must contain the key "' + c + '"'); + if (!q(z(b, c))) throw Error(E(a, 1, !1) + 'must contain the key "' + c + '" with type "string"'); + }; + + function ug() { + this.set = {} + } + h = ug.prototype; + h.add = function(a, b) { + this.set[a] = null !== b ? b : !0 + }; + h.contains = function(a) { + return y(this.set, a) + }; + h.get = function(a) { + return this.contains(a) ? this.set[a] : void 0 + }; + h.remove = function(a) { + delete this.set[a] + }; + h.clear = function() { + this.set = {} + }; + h.e = function() { + return va(this.set) + }; + h.count = function() { + return oa(this.set) + }; + + function vg(a, b) { + v(a.set, function(a, d) { + b(d, a) + }) + } + h.keys = function() { + var a = []; + v(this.set, function(b, c) { + a.push(c) + }); + return a + }; + + function Vc() { + this.m = this.B = null + } + Vc.prototype.find = function(a) { + if (null != this.B) return this.B.S(a); + if (a.e() || null == this.m) return null; + var b = K(a); + a = N(a); + return this.m.contains(b) ? this.m.get(b).find(a) : null + }; + Vc.prototype.rc = function(a, b) { + if (a.e()) this.B = b, this.m = null; + else if (null !== this.B) this.B = this.B.H(a, b); + else { + null == this.m && (this.m = new ug); + var c = K(a); + this.m.contains(c) || this.m.add(c, new Vc); + c = this.m.get(c); + a = N(a); + c.rc(a, b) + } + }; + + function wg(a, b) { + if (b.e()) return a.B = null, a.m = null, !0; + if (null !== a.B) { + if (a.B.L()) return !1; + var c = a.B; + a.B = null; + c.R(R, function(b, c) { + a.rc(new P(b), c) + }); + return wg(a, b) + } + return null !== a.m ? (c = K(b), b = N(b), a.m.contains(c) && wg(a.m.get(c), b) && a.m.remove(c), a.m.e() ? (a.m = null, !0) : !1) : !0 + } + + function Wc(a, b, c) { + null !== a.B ? c(b, a.B) : a.R(function(a, e) { + var f = new P(b.toString() + "/" + a); + Wc(e, f, c) + }) + } + Vc.prototype.R = function(a) { + null !== this.m && vg(this.m, function(b, c) { + a(b, c) + }) + }; + var xg = "auth.firebase.com"; + + function yg(a, b, c) { + this.qd = a || {}; + this.he = b || {}; + this.fb = c || {}; + this.qd.remember || (this.qd.remember = "default") + } + var zg = ["remember", "redirectTo"]; + + function Ag(a) { + var b = {}, + c = {}; + Fb(a || {}, function(a, e) { + 0 <= La(zg, a) ? b[a] = e : c[a] = e + }); + return new yg(b, {}, c) + }; + + function Bg(a, b) { + this.Ue = ["session", a.Rd, a.lc].join(":"); + this.ee = b + } + Bg.prototype.set = function(a, b) { + if (!b) + if (this.ee.length) b = this.ee[0]; + else throw Error("fb.login.SessionManager : No storage options available!"); + b.set(this.Ue, a) + }; + Bg.prototype.get = function() { + var a = Oa(this.ee, u(this.Bg, this)), + a = Na(a, function(a) { + return null !== a + }); + Va(a, function(a, c) { + return Dd(c.token) - Dd(a.token) + }); + return 0 < a.length ? a.shift() : null + }; + Bg.prototype.Bg = function(a) { + try { + var b = a.get(this.Ue); + if (b && b.token) return b + } catch (c) {} + return null + }; + Bg.prototype.clear = function() { + var a = this; + Ma(this.ee, function(b) { + b.remove(a.Ue) + }) + }; + + function Cg() { + return "undefined" !== typeof navigator && "string" === typeof navigator.userAgent ? navigator.userAgent : "" + } + + function Dg() { + return "undefined" !== typeof window && !!(window.cordova || window.phonegap || window.PhoneGap) && /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(Cg()) + } + + function Eg() { + return "undefined" !== typeof location && /^file:\//.test(location.href) + } + + function Fg(a) { + var b = Cg(); + if ("" === b) return !1; + if ("Microsoft Internet Explorer" === navigator.appName) { + if ((b = b.match(/MSIE ([0-9]{1,}[\.0-9]{0,})/)) && 1 < b.length) return parseFloat(b[1]) >= a + } else if (-1 < b.indexOf("Trident") && (b = b.match(/rv:([0-9]{2,2}[\.0-9]{0,})/)) && 1 < b.length) return parseFloat(b[1]) >= a; + return !1 + }; + + function Gg() { + var a = window.opener.frames, + b; + for (b = a.length - 1; 0 <= b; b--) try { + if (a[b].location.protocol === window.location.protocol && a[b].location.host === window.location.host && "__winchan_relay_frame" === a[b].name) return a[b] + } catch (c) {} + return null + } + + function Hg(a, b, c) { + a.attachEvent ? a.attachEvent("on" + b, c) : a.addEventListener && a.addEventListener(b, c, !1) + } + + function Ig(a, b, c) { + a.detachEvent ? a.detachEvent("on" + b, c) : a.removeEventListener && a.removeEventListener(b, c, !1) + } + + function Jg(a) { + /^https?:\/\//.test(a) || (a = window.location.href); + var b = /^(https?:\/\/[\-_a-zA-Z\.0-9:]+)/.exec(a); + return b ? b[1] : a + } + + function Kg(a) { + var b = ""; + try { + a = a.replace(/.*\?/, ""); + var c = Jb(a); + c && y(c, "__firebase_request_key") && (b = z(c, "__firebase_request_key")) + } catch (d) {} + return b + } + + function Lg() { + var a = sd(xg); + return a.scheme + "://" + a.host + "/v2" + } + + function Mg(a) { + return Lg() + "/" + a + "/auth/channel" + }; + + function Ng(a) { + var b = this; + this.hb = a; + this.fe = "*"; + Fg(8) ? this.Uc = this.Cd = Gg() : (this.Uc = window.opener, this.Cd = window); + if (!b.Uc) throw "Unable to find relay frame"; + Hg(this.Cd, "message", u(this.nc, this)); + Hg(this.Cd, "message", u(this.Ff, this)); + try { + Og(this, { + a: "ready" + }) + } catch (c) { + Hg(this.Uc, "load", function() { + Og(b, { + a: "ready" + }) + }) + } + Hg(window, "unload", u(this.Mg, this)) + } + + function Og(a, b) { + b = G(b); + Fg(8) ? a.Uc.doPost(b, a.fe) : a.Uc.postMessage(b, a.fe) + } + Ng.prototype.nc = function(a) { + var b = this, + c; + try { + c = Rb(a.data) + } catch (d) {} + c && "request" === c.a && (Ig(window, "message", this.nc), this.fe = a.origin, this.hb && setTimeout(function() { + b.hb(b.fe, c.d, function(a, c) { + b.mg = !c; + b.hb = void 0; + Og(b, { + a: "response", + d: a, + forceKeepWindowOpen: c + }) + }) + }, 0)) + }; + Ng.prototype.Mg = function() { + try { + Ig(this.Cd, "message", this.Ff) + } catch (a) {} + this.hb && (Og(this, { + a: "error", + d: "unknown closed window" + }), this.hb = void 0); + try { + window.close() + } catch (b) {} + }; + Ng.prototype.Ff = function(a) { + if (this.mg && "die" === a.data) try { + window.close() + } catch (b) {} + }; + + function Pg(a) { + this.tc = Fa() + Fa() + Fa(); + this.Kf = a + } + Pg.prototype.open = function(a, b) { + cd.set("redirect_request_id", this.tc); + cd.set("redirect_request_id", this.tc); + b.requestId = this.tc; + b.redirectTo = b.redirectTo || window.location.href; + a += (/\?/.test(a) ? "" : "?") + Ib(b); + window.location = a + }; + Pg.isAvailable = function() { + return !Eg() && !Dg() + }; + Pg.prototype.Fc = function() { + return "redirect" + }; + var Qg = { + NETWORK_ERROR: "Unable to contact the Firebase server.", + SERVER_ERROR: "An unknown server error occurred.", + TRANSPORT_UNAVAILABLE: "There are no login transports available for the requested method.", + REQUEST_INTERRUPTED: "The browser redirected the page before the login request could complete.", + USER_CANCELLED: "The user cancelled authentication." + }; + + function Rg(a) { + var b = Error(z(Qg, a), a); + b.code = a; + return b + }; + + function Sg(a) { + var b; + (b = !a.window_features) || (b = Cg(), b = -1 !== b.indexOf("Fennec/") || -1 !== b.indexOf("Firefox/") && -1 !== b.indexOf("Android")); + b && (a.window_features = void 0); + a.window_name || (a.window_name = "_blank"); + this.options = a + } + Sg.prototype.open = function(a, b, c) { + function d(a) { + g && (document.body.removeChild(g), g = void 0); + t && (t = clearInterval(t)); + Ig(window, "message", e); + Ig(window, "unload", d); + if (l && !a) try { + l.close() + } catch (b) { + k.postMessage("die", m) + } + l = k = void 0 + } + + function e(a) { + if (a.origin === m) try { + var b = Rb(a.data); + "ready" === b.a ? k.postMessage(A, m) : "error" === b.a ? (d(!1), c && (c(b.d), c = null)) : "response" === b.a && (d(b.forceKeepWindowOpen), c && (c(null, b.d), c = null)) + } catch (e) {} + } + var f = Fg(8), + g, k; + if (!this.options.relay_url) return c(Error("invalid arguments: origin of url and relay_url must match")); + var m = Jg(a); + if (m !== Jg(this.options.relay_url)) c && setTimeout(function() { + c(Error("invalid arguments: origin of url and relay_url must match")) + }, 0); + else { + f && (g = document.createElement("iframe"), g.setAttribute("src", this.options.relay_url), g.style.display = "none", g.setAttribute("name", "__winchan_relay_frame"), document.body.appendChild(g), k = g.contentWindow); + a += (/\?/.test(a) ? "" : "?") + Ib(b); + var l = window.open(a, this.options.window_name, this.options.window_features); + k || (k = l); + var t = setInterval(function() { + l && l.closed && + (d(!1), c && (c(Rg("USER_CANCELLED")), c = null)) + }, 500), + A = G({ + a: "request", + d: b + }); + Hg(window, "unload", d); + Hg(window, "message", e) + } + }; + Sg.isAvailable = function() { + var a; + if (a = "postMessage" in window && !Eg())(a = Dg() || "undefined" !== typeof navigator && (!!Cg().match(/Windows Phone/) || !!window.Windows && /^ms-appx:/.test(location.href))) || (a = Cg(), a = "undefined" !== typeof navigator && "undefined" !== typeof window && !!(a.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i) || a.match(/CriOS/) || a.match(/Twitter for iPhone/) || a.match(/FBAN\/FBIOS/) || window.navigator.standalone)), a = !a; + return a && !Cg().match(/PhantomJS/) + }; + Sg.prototype.Fc = function() { + return "popup" + }; + + function Tg(a) { + a.method || (a.method = "GET"); + a.headers || (a.headers = {}); + a.headers.content_type || (a.headers.content_type = "application/json"); + a.headers.content_type = a.headers.content_type.toLowerCase(); + this.options = a + } + Tg.prototype.open = function(a, b, c) { + function d() { + c && (c(Rg("REQUEST_INTERRUPTED")), c = null) + } + var e = new XMLHttpRequest, + f = this.options.method.toUpperCase(), + g; + Hg(window, "beforeunload", d); + e.onreadystatechange = function() { + if (c && 4 === e.readyState) { + var a; + if (200 <= e.status && 300 > e.status) { + try { + a = Rb(e.responseText) + } catch (b) {} + c(null, a) + } else 500 <= e.status && 600 > e.status ? c(Rg("SERVER_ERROR")) : c(Rg("NETWORK_ERROR")); + c = null; + Ig(window, "beforeunload", d) + } + }; + if ("GET" === f) a += (/\?/.test(a) ? "" : "?") + Ib(b), g = null; + else { + var k = this.options.headers.content_type; + "application/json" === k && (g = G(b)); + "application/x-www-form-urlencoded" === k && (g = Ib(b)) + } + e.open(f, a, !0); + a = { + "X-Requested-With": "XMLHttpRequest", + Accept: "application/json;text/plain" + }; + ya(a, this.options.headers); + for (var m in a) e.setRequestHeader(m, a[m]); + e.send(g) + }; + Tg.isAvailable = function() { + var a; + if (a = !!window.XMLHttpRequest) a = Cg(), a = !(a.match(/MSIE/) || a.match(/Trident/)) || Fg(10); + return a + }; + Tg.prototype.Fc = function() { + return "json" + }; + + function Ug(a) { + this.tc = Fa() + Fa() + Fa(); + this.Kf = a + } + Ug.prototype.open = function(a, b, c) { + function d() { + c && (c(Rg("USER_CANCELLED")), c = null) + } + var e = this, + f = sd(xg), + g; + b.requestId = this.tc; + b.redirectTo = f.scheme + "://" + f.host + "/blank/page.html"; + a += /\?/.test(a) ? "" : "?"; + a += Ib(b); + (g = window.open(a, "_blank", "location=no")) && r(g.addEventListener) ? (g.addEventListener("loadstart", function(a) { + var b; + if (b = a && a.url) a: { + try { + var l = document.createElement("a"); + l.href = a.url; + b = l.host === f.host && "/blank/page.html" === l.pathname; + break a + } catch (t) {} + b = !1 + } + b && (a = Kg(a.url), g.removeEventListener("exit", + d), g.close(), a = new yg(null, null, { + requestId: e.tc, + requestKey: a + }), e.Kf.requestWithCredential("/auth/session", a, c), c = null) + }), g.addEventListener("exit", d)) : c(Rg("TRANSPORT_UNAVAILABLE")) + }; + Ug.isAvailable = function() { + return Dg() + }; + Ug.prototype.Fc = function() { + return "redirect" + }; + + function Vg(a) { + a.callback_parameter || (a.callback_parameter = "callback"); + this.options = a; + window.__firebase_auth_jsonp = window.__firebase_auth_jsonp || {} + } + Vg.prototype.open = function(a, b, c) { + function d() { + c && (c(Rg("REQUEST_INTERRUPTED")), c = null) + } + + function e() { + setTimeout(function() { + window.__firebase_auth_jsonp[f] = void 0; + va(window.__firebase_auth_jsonp) && (window.__firebase_auth_jsonp = void 0); + try { + var a = document.getElementById(f); + a && a.parentNode.removeChild(a) + } catch (b) {} + }, 1); + Ig(window, "beforeunload", d) + } + var f = "fn" + (new Date).getTime() + Math.floor(99999 * Math.random()); + b[this.options.callback_parameter] = "__firebase_auth_jsonp." + f; + a += (/\?/.test(a) ? "" : "?") + Ib(b); + Hg(window, "beforeunload", d); + window.__firebase_auth_jsonp[f] = function(a) { + c && (c(null, a), c = null); + e() + }; + Wg(f, a, c) + }; + + function Wg(a, b, c) { + setTimeout(function() { + try { + var d = document.createElement("script"); + d.type = "text/javascript"; + d.id = a; + d.async = !0; + d.src = b; + d.onerror = function() { + var b = document.getElementById(a); + null !== b && b.parentNode.removeChild(b); + c && c(Rg("NETWORK_ERROR")) + }; + var e = document.getElementsByTagName("head"); + (e && 0 != e.length ? e[0] : document.documentElement).appendChild(d) + } catch (f) { + c && c(Rg("NETWORK_ERROR")) + } + }, 0) + } + Vg.isAvailable = function() { + return "undefined" !== typeof document && null != document.createElement + }; + Vg.prototype.Fc = function() { + return "json" + }; + + function Xg(a, b, c, d) { + ff.call(this, ["auth_status"]); + this.G = a; + this.hf = b; + this.gh = c; + this.Pe = d; + this.wc = new Bg(a, [bd, cd]); + this.qb = null; + this.We = !1; + Yg(this) + } + ka(Xg, ff); + h = Xg.prototype; + h.Be = function() { + return this.qb || null + }; + + function Yg(a) { + cd.get("redirect_request_id") && Zg(a); + var b = a.wc.get(); + b && b.token ? ($g(a, b), a.hf(b.token, function(c, d) { + ah(a, c, d, !1, b.token, b) + }, function(b, d) { + bh(a, "resumeSession()", b, d) + })) : $g(a, null) + } + + function ch(a, b, c, d, e, f) { + "firebaseio-demo.com" === a.G.domain && S("Firebase authentication is not supported on demo Firebases (*.firebaseio-demo.com). To secure your Firebase, create a production Firebase at https://www.firebase.com."); + a.hf(b, function(f, k) { + ah(a, f, k, !0, b, c, d || {}, e) + }, function(b, c) { + bh(a, "auth()", b, c, f) + }) + } + + function dh(a, b) { + a.wc.clear(); + $g(a, null); + a.gh(function(a, d) { + if ("ok" === a) T(b, null); + else { + var e = (a || "error").toUpperCase(), + f = e; + d && (f += ": " + d); + f = Error(f); + f.code = e; + T(b, f) + } + }) + } + + function ah(a, b, c, d, e, f, g, k) { + "ok" === b ? (d && (b = c.auth, f.auth = b, f.expires = c.expires, f.token = Ed(e) ? e : "", c = null, b && y(b, "uid") ? c = z(b, "uid") : y(f, "uid") && (c = z(f, "uid")), f.uid = c, c = "custom", b && y(b, "provider") ? c = z(b, "provider") : y(f, "provider") && (c = z(f, "provider")), f.provider = c, a.wc.clear(), Ed(e) && (g = g || {}, c = bd, "sessionOnly" === g.remember && (c = cd), "none" !== g.remember && a.wc.set(f, c)), $g(a, f)), T(k, null, f)) : (a.wc.clear(), $g(a, null), f = a = (b || "error").toUpperCase(), c && (f += ": " + c), f = Error(f), f.code = a, T(k, f)) + } + + function bh(a, b, c, d, e) { + S(b + " was canceled: " + d); + a.wc.clear(); + $g(a, null); + a = Error(d); + a.code = c.toUpperCase(); + T(e, a) + } + + function eh(a, b, c, d, e) { + fh(a); + c = new yg(d || {}, {}, c || {}); + gh(a, [Tg, Vg], "/auth/" + b, c, e) + } + + function hh(a, b, c, d) { + fh(a); + var e = [Sg, Ug]; + c = Ag(c); + "anonymous" === b || "password" === b ? setTimeout(function() { + T(d, Rg("TRANSPORT_UNAVAILABLE")) + }, 0) : (c.he.window_features = "menubar=yes,modal=yes,alwaysRaised=yeslocation=yes,resizable=yes,scrollbars=yes,status=yes,height=625,width=625,top=" + ("object" === typeof screen ? .5 * (screen.height - 625) : 0) + ",left=" + ("object" === typeof screen ? .5 * (screen.width - 625) : 0), c.he.relay_url = Mg(a.G.lc), c.he.requestWithCredential = u(a.uc, a), gh(a, e, "/auth/" + b, c, d)) + } + + function Zg(a) { + var b = cd.get("redirect_request_id"); + if (b) { + var c = cd.get("redirect_client_options"); + cd.remove("redirect_request_id"); + cd.remove("redirect_client_options"); + var d = [Tg, Vg], + b = { + requestId: b, + requestKey: Kg(document.location.hash) + }, + c = new yg(c, {}, b); + a.We = !0; + try { + document.location.hash = document.location.hash.replace(/&__firebase_request_key=([a-zA-z0-9]*)/, "") + } catch (e) {} + gh(a, d, "/auth/session", c, function() { + this.We = !1 + }.bind(a)) + } + } + h.ve = function(a, b) { + fh(this); + var c = Ag(a); + c.fb._method = "POST"; + this.uc("/users", c, function(a, c) { + a ? T(b, a) : T(b, a, c) + }) + }; + h.Xe = function(a, b) { + var c = this; + fh(this); + var d = "/users/" + encodeURIComponent(a.email), + e = Ag(a); + e.fb._method = "DELETE"; + this.uc(d, e, function(a, d) { + !a && d && d.uid && c.qb && c.qb.uid && c.qb.uid === d.uid && dh(c); + T(b, a) + }) + }; + h.se = function(a, b) { + fh(this); + var c = "/users/" + encodeURIComponent(a.email) + "/password", + d = Ag(a); + d.fb._method = "PUT"; + d.fb.password = a.newPassword; + this.uc(c, d, function(a) { + T(b, a) + }) + }; + h.re = function(a, b) { + fh(this); + var c = "/users/" + encodeURIComponent(a.oldEmail) + "/email", + d = Ag(a); + d.fb._method = "PUT"; + d.fb.email = a.newEmail; + d.fb.password = a.password; + this.uc(c, d, function(a) { + T(b, a) + }) + }; + h.Ze = function(a, b) { + fh(this); + var c = "/users/" + encodeURIComponent(a.email) + "/password", + d = Ag(a); + d.fb._method = "POST"; + this.uc(c, d, function(a) { + T(b, a) + }) + }; + h.uc = function(a, b, c) { + ih(this, [Tg, Vg], a, b, c) + }; + + function gh(a, b, c, d, e) { + ih(a, b, c, d, function(b, c) { + !b && c && c.token && c.uid ? ch(a, c.token, c, d.qd, function(a, b) { + a ? T(e, a) : T(e, null, b) + }) : T(e, b || Rg("UNKNOWN_ERROR")) + }) + } + + function ih(a, b, c, d, e) { + b = Na(b, function(a) { + return "function" === typeof a.isAvailable && a.isAvailable() + }); + 0 === b.length ? setTimeout(function() { + T(e, Rg("TRANSPORT_UNAVAILABLE")) + }, 0) : (b = new(b.shift())(d.he), d = Gb(d.fb), d.v = "js-" + Eb, d.transport = b.Fc(), d.suppress_status_codes = !0, a = Lg() + "/" + a.G.lc + c, b.open(a, d, function(a, b) { + if (a) T(e, a); + else if (b && b.error) { + var c = Error(b.error.message); + c.code = b.error.code; + c.details = b.error.details; + T(e, c) + } else T(e, null, b) + })) + } + + function $g(a, b) { + var c = null !== a.qb || null !== b; + a.qb = b; + c && a.ie("auth_status", b); + a.Pe(null !== b) + } + h.Ee = function(a) { + O("auth_status" === a, 'initial event must be of type "auth_status"'); + return this.We ? null : [this.qb] + }; + + function fh(a) { + var b = a.G; + if ("firebaseio.com" !== b.domain && "firebaseio-demo.com" !== b.domain && "auth.firebase.com" === xg) throw Error("This custom Firebase server ('" + a.G.domain + "') does not support delegated login."); + }; + var gd = "websocket", + hd = "long_polling"; + + function jh(a) { + this.nc = a; + this.Qd = []; + this.Wb = 0; + this.te = -1; + this.Jb = null + } + + function kh(a, b, c) { + a.te = b; + a.Jb = c; + a.te < a.Wb && (a.Jb(), a.Jb = null) + } + + function lh(a, b, c) { + for (a.Qd[b] = c; a.Qd[a.Wb];) { + var d = a.Qd[a.Wb]; + delete a.Qd[a.Wb]; + for (var e = 0; e < d.length; ++e) + if (d[e]) { + var f = a; + gc(function() { + f.nc(d[e]) + }) + } + if (a.Wb === a.te) { + a.Jb && (clearTimeout(a.Jb), a.Jb(), a.Jb = null); + break + } + a.Wb++ + } + }; + + function mh(a, b, c, d) { + this.ue = a; + this.f = pd(a); + this.rb = this.sb = 0; + this.Xa = uc(b); + this.Xf = c; + this.Kc = !1; + this.Fb = d; + this.ld = function(a) { + return fd(b, hd, a) + } + } + var nh, oh; + mh.prototype.open = function(a, b) { + this.mf = 0; + this.na = b; + this.Ef = new jh(a); + this.Db = !1; + var c = this; + this.ub = setTimeout(function() { + c.f("Timed out trying to connect."); + c.bb(); + c.ub = null + }, Math.floor(3E4)); + ud(function() { + if (!c.Db) { + c.Wa = new ph(function(a, b, d, k, m) { + qh(c, arguments); + if (c.Wa) + if (c.ub && (clearTimeout(c.ub), c.ub = null), c.Kc = !0, "start" == a) c.id = b, c.Mf = d; + else if ("close" === a) b ? (c.Wa.$d = !1, kh(c.Ef, b, function() { + c.bb() + })) : c.bb(); + else throw Error("Unrecognized command received: " + a); + }, function(a, b) { + qh(c, arguments); + lh(c.Ef, a, b) + }, function() { + c.bb() + }, c.ld); + var a = { + start: "t" + }; + a.ser = Math.floor(1E8 * Math.random()); + c.Wa.ke && (a.cb = c.Wa.ke); + a.v = "5"; + c.Xf && (a.s = c.Xf); + c.Fb && (a.ls = c.Fb); + "undefined" !== typeof location && location.href && -1 !== location.href.indexOf("firebaseio.com") && (a.r = "f"); + a = c.ld(a); + c.f("Connecting via long-poll to " + a); + rh(c.Wa, a, function() {}) + } + }) + }; + mh.prototype.start = function() { + var a = this.Wa, + b = this.Mf; + a.Fg = this.id; + a.Gg = b; + for (a.oe = !0; sh(a);); + a = this.id; + b = this.Mf; + this.kc = document.createElement("iframe"); + var c = { + dframe: "t" + }; + c.id = a; + c.pw = b; + this.kc.src = this.ld(c); + this.kc.style.display = "none"; + document.body.appendChild(this.kc) + }; + mh.isAvailable = function() { + return nh || !oh && "undefined" !== typeof document && null != document.createElement && !("object" === typeof window && window.chrome && window.chrome.extension && !/^chrome/.test(window.location.href)) && !("object" === typeof Windows && "object" === typeof Windows.ih) && !0 + }; + h = mh.prototype; + h.Hd = function() {}; + h.fd = function() { + this.Db = !0; + this.Wa && (this.Wa.close(), this.Wa = null); + this.kc && (document.body.removeChild(this.kc), this.kc = null); + this.ub && (clearTimeout(this.ub), this.ub = null) + }; + h.bb = function() { + this.Db || (this.f("Longpoll is closing itself"), this.fd(), this.na && (this.na(this.Kc), this.na = null)) + }; + h.close = function() { + this.Db || (this.f("Longpoll is being closed."), this.fd()) + }; + h.send = function(a) { + a = G(a); + this.sb += a.length; + rc(this.Xa, "bytes_sent", a.length); + a = Ob(a); + a = nb(a, !0); + a = yd(a, 1840); + for (var b = 0; b < a.length; b++) { + var c = this.Wa; + c.cd.push({ + Xg: this.mf, + fh: a.length, + of: a[b] + }); + c.oe && sh(c); + this.mf++ + } + }; + + function qh(a, b) { + var c = G(b).length; + a.rb += c; + rc(a.Xa, "bytes_received", c) + } + + function ph(a, b, c, d) { + this.ld = d; + this.lb = c; + this.Te = new ug; + this.cd = []; + this.we = Math.floor(1E8 * Math.random()); + this.$d = !0; + this.ke = id(); + window["pLPCommand" + this.ke] = a; + window["pRTLPCB" + this.ke] = b; + a = document.createElement("iframe"); + a.style.display = "none"; + if (document.body) { + document.body.appendChild(a); + try { + a.contentWindow.document || fc("No IE domain setting required") + } catch (e) { + a.src = "javascript:void((function(){document.open();document.domain='" + document.domain + "';document.close();})())" + } + } else throw "Document body has not initialized. Wait to initialize Firebase until after the document is ready."; + a.contentDocument ? a.jb = a.contentDocument : a.contentWindow ? a.jb = a.contentWindow.document : a.document && (a.jb = a.document); + this.Ga = a; + a = ""; + this.Ga.src && "javascript:" === this.Ga.src.substr(0, 11) && (a = '